]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: -EIO on read/write if file hander has lost filelocks
authorYan, Zheng <zyan@redhat.com>
Tue, 5 Nov 2019 09:15:20 +0000 (17:15 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 30 Mar 2020 02:24:47 +0000 (10:24 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/Fh.h

index 5294759ef99c550be5039ed94f61145691724706..6db2effdadd1b58117dd241be4bf91629b0cc6b6 100644 (file)
@@ -3202,8 +3202,10 @@ void Client::put_cap_ref(Inode *in, int cap)
   }
 }
 
-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;
@@ -3217,6 +3219,9 @@ int Client::get_caps(Inode *in, int need, int want, int *phave, loff_t endoff)
       return -EBADF;
     }
 
+    if ((in->flags & I_ERROR_FILELOCK) && fh->has_any_filelocks())
+      return -EIO;
+
     int implemented;
     int have = in->caps_issued(&implemented);
 
@@ -8813,7 +8818,8 @@ int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp,
       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: " <<
@@ -9144,7 +9150,7 @@ retry:
     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;
   }
@@ -9574,7 +9580,7 @@ int64_t Client::_write(Fh *f, int64_t offset, uint64_t size, const char *buf,
     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;
 
@@ -13517,7 +13523,7 @@ int Client::_fallocate(Fh *fh, int mode, int64_t offset, int64_t length)
   }
 
   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;
 
index ea6ea86c95aa9392488c5d79d8240cc5f6c2927f..2dabfad00355e1b2375e7c9f3e098f78f63e38c6 100644 (file)
@@ -655,7 +655,7 @@ public:
   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,
index eae96037e74325d5af7db2f5d6f5ca79de4e8891..5511585c1141793ba1cd0f8308c239cf74468f64 100644 (file)
@@ -30,6 +30,12 @@ struct Fh {
   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