dirty_caps = in->dirty_caps | in->flushing_caps;
in->wanted_max_size = 0;
in->requested_max_size = 0;
+ if (in->has_any_filelocks())
+ in->flags |= I_ERROR_FILELOCK;
}
auto caps = cap->implemented;
if (cap->wanted | cap->issued)
<< " type " << fl->l_type << " owner " << owner
<< " " << fl->l_start << "~" << fl->l_len << dendl;
+ if (in->flags & I_ERROR_FILELOCK)
+ return -EIO;
+
int lock_cmd;
if (F_RDLCK == fl->l_type)
lock_cmd = CEPH_LOCK_SHARED;
Inode *in = fh->inode.get();
ldout(cct, 10) << __func__ << " " << fh << " ino " << in->ino << dendl;
+ list<ceph_filelock> activated_locks;
+
list<pair<int, ceph_filelock> > to_release;
if (fh->fcntl_locks) {
auto &lock_state = fh->fcntl_locks;
- for(multimap<uint64_t, ceph_filelock>::iterator p = lock_state->held_locks.begin();
- p != lock_state->held_locks.end();
- ++p)
- to_release.push_back(pair<int, ceph_filelock>(CEPH_LOCK_FCNTL, p->second));
+ for(auto p = lock_state->held_locks.begin(); p != lock_state->held_locks.end(); ) {
+ auto q = p++;
+ if (in->flags & I_ERROR_FILELOCK) {
+ lock_state->remove_lock(q->second, activated_locks);
+ } else {
+ to_release.push_back(pair<int, ceph_filelock>(CEPH_LOCK_FCNTL, q->second));
+ }
+ }
lock_state.reset();
}
if (fh->flock_locks) {
auto &lock_state = fh->flock_locks;
- for(multimap<uint64_t, ceph_filelock>::iterator p = lock_state->held_locks.begin();
- p != lock_state->held_locks.end();
- ++p)
- to_release.push_back(pair<int, ceph_filelock>(CEPH_LOCK_FLOCK, p->second));
+ for(auto p = lock_state->held_locks.begin(); p != lock_state->held_locks.end(); ) {
+ auto q = p++;
+ if (in->flags & I_ERROR_FILELOCK) {
+ lock_state->remove_lock(q->second, activated_locks);
+ } else {
+ to_release.push_back(pair<int, ceph_filelock>(CEPH_LOCK_FLOCK, q->second));
+ }
+ }
lock_state.reset();
}
- if (to_release.empty())
- return;
+ if ((in->flags & I_ERROR_FILELOCK) && !in->has_any_filelocks())
+ in->flags &= ~I_ERROR_FILELOCK;
- // mds has already released filelocks if session was closed.
- if (in->caps.empty())
+ if (to_release.empty())
return;
struct flock fl;
};
// inode flags
-#define I_COMPLETE 1
-#define I_DIR_ORDERED 2
-#define I_CAP_DROPPED 4
-#define I_SNAPDIR_OPEN 8
-#define I_KICK_FLUSH 16
+#define I_COMPLETE (1 << 0)
+#define I_DIR_ORDERED (1 << 1)
+#define I_SNAPDIR_OPEN (1 << 2)
+#define I_KICK_FLUSH (1 << 3)
+#define I_CAP_DROPPED (1 << 4)
+#define I_ERROR_FILELOCK (1 << 5)
struct Inode {
Client *client;
std::unique_ptr<ceph_lock_state_t> fcntl_locks;
std::unique_ptr<ceph_lock_state_t> flock_locks;
+ bool has_any_filelocks() {
+ return
+ (fcntl_locks && !fcntl_locks->empty()) ||
+ (flock_locks && !flock_locks->empty());
+ }
+
list<Delegation> delegations;
xlist<MetaRequest*> unsafe_ops;