}
}
-int Client::get_caps(Inode *in, int need, int want, int *phave, loff_t endoff)
+int Client::get_caps(Fh *fh, int need, int want, int *phave, loff_t endoff)
{
+ Inode *in = fh->inode.get();
+
int r = check_pool_perm(in, need);
if (r < 0)
return r;
return -EBADF;
}
+ if ((in->flags & I_ERROR_FILELOCK) && fh->has_any_filelocks())
+ return -EIO;
+
int implemented;
int have = in->caps_issued(&implemented);
if (cmode & CEPH_FILE_MODE_RD)
need |= CEPH_CAP_FILE_RD;
- result = get_caps(in, need, want, &have, -1);
+ Fh fh(in, flags, cmode, perms);
+ result = get_caps(&fh, need, want, &have, -1);
if (result < 0) {
ldout(cct, 8) << "Unable to get caps after open of inode " << *in <<
" . Denying open: " <<
want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
else
want = CEPH_CAP_FILE_CACHE;
- r = get_caps(in, CEPH_CAP_FILE_RD, want, &have, -1);
+ r = get_caps(f, CEPH_CAP_FILE_RD, want, &have, -1);
if (r < 0) {
goto done;
}
want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
else
want = CEPH_CAP_FILE_BUFFER;
- int r = get_caps(in, CEPH_CAP_FILE_WR|CEPH_CAP_AUTH_SHARED, want, &have, endoff);
+ int r = get_caps(f, CEPH_CAP_FILE_WR|CEPH_CAP_AUTH_SHARED, want, &have, endoff);
if (r < 0)
return r;
}
int have;
- int r = get_caps(in, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, &have, -1);
+ int r = get_caps(fh, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, &have, -1);
if (r < 0)
return r;
void kick_flushing_caps(Inode *in, MetaSession *session);
void kick_flushing_caps(MetaSession *session);
void early_kick_flushing_caps(MetaSession *session);
- int get_caps(Inode *in, int need, int want, int *have, loff_t endoff);
+ int get_caps(Fh *fh, int need, int want, int *have, loff_t endoff);
int get_caps_used(Inode *in);
void maybe_update_snaprealm(SnapRealm *realm, snapid_t snap_created, snapid_t snap_highwater,
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());
+ }
+
// IO error encountered by any writeback on this Inode while
// this Fh existed (i.e. an fsync on another Fh will still show
// up as an async_err here because it could have been the same