ceph: always renew caps if mds_wanted is insufficient
authorYan, Zheng <zyan@redhat.com>
Thu, 5 Mar 2020 12:20:59 +0000 (20:20 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 30 Mar 2020 10:42:42 +0000 (12:42 +0200)
Original code only renews caps for inodes with CEPH_I_CAP_DROPPED flag,
which indicates that mds has closed the session and caps were dropped.
Remove this flag in preparation for not requesting caps for idle open
files.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/caps.c
fs/ceph/mds_client.c
fs/ceph/super.h

index be85225b962c802a211cbced702c2858740dd818..a75e5eb3740ea0e3735cc5699694e15793225ba1 100644 (file)
@@ -2686,6 +2686,7 @@ again:
                }
        } else {
                int session_readonly = false;
+               int mds_wanted;
                if (ci->i_auth_cap &&
                    (need & (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_EXCL))) {
                        struct ceph_mds_session *s = ci->i_auth_cap->session;
@@ -2694,32 +2695,27 @@ again:
                        spin_unlock(&s->s_cap_lock);
                }
                if (session_readonly) {
-                       dout("get_cap_refs %p needed %s but mds%d readonly\n",
+                       dout("get_cap_refs %p need %s but mds%d readonly\n",
                             inode, ceph_cap_string(need), ci->i_auth_cap->mds);
                        ret = -EROFS;
                        goto out_unlock;
                }
 
-               if (ci->i_ceph_flags & CEPH_I_CAP_DROPPED) {
-                       int mds_wanted;
-                       if (READ_ONCE(mdsc->fsc->mount_state) ==
-                           CEPH_MOUNT_SHUTDOWN) {
-                               dout("get_cap_refs %p forced umount\n", inode);
-                               ret = -EIO;
-                               goto out_unlock;
-                       }
-                       mds_wanted = __ceph_caps_mds_wanted(ci, false);
-                       if (need & ~(mds_wanted & need)) {
-                               dout("get_cap_refs %p caps were dropped"
-                                    " (session killed?)\n", inode);
-                               ret = -ESTALE;
-                               goto out_unlock;
-                       }
-                       if (!(file_wanted & ~mds_wanted))
-                               ci->i_ceph_flags &= ~CEPH_I_CAP_DROPPED;
+               if (READ_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
+                       dout("get_cap_refs %p forced umount\n", inode);
+                       ret = -EIO;
+                       goto out_unlock;
+               }
+               mds_wanted = __ceph_caps_mds_wanted(ci, false);
+               if (need & ~mds_wanted) {
+                       dout("get_cap_refs %p need %s > mds_wanted %s\n",
+                            inode, ceph_cap_string(need),
+                            ceph_cap_string(mds_wanted));
+                       ret = -ESTALE;
+                       goto out_unlock;
                }
 
-               dout("get_cap_refs %p have %s needed %s\n", inode,
+               dout("get_cap_refs %p have %s need %s\n", inode,
                     ceph_cap_string(have), ceph_cap_string(need));
        }
 out_unlock:
@@ -3678,8 +3674,6 @@ retry:
                goto out_unlock;
 
        if (target < 0) {
-               if (cap->mds_wanted | cap->issued)
-                       ci->i_ceph_flags |= CEPH_I_CAP_DROPPED;
                __ceph_remove_cap(cap, false);
                goto out_unlock;
        }
index 177acb9f456b6e0f0f16bb18b803ae54e8390af8..68b8afded466265637de7458efb421963b480d12 100644 (file)
@@ -1514,8 +1514,6 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
        dout("removing cap %p, ci is %p, inode is %p\n",
             cap, ci, &ci->vfs_inode);
        spin_lock(&ci->i_ceph_lock);
-       if (cap->mds_wanted | cap->issued)
-               ci->i_ceph_flags |= CEPH_I_CAP_DROPPED;
        __ceph_remove_cap(cap, false);
        if (!ci->i_auth_cap) {
                struct ceph_cap_flush *cf;
@@ -1681,9 +1679,6 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
                        /* mds did not re-issue stale cap */
                        spin_lock(&ci->i_ceph_lock);
                        cap->issued = cap->implemented = CEPH_CAP_PIN;
-                       /* make sure mds knows what we want */
-                       if (__ceph_caps_file_wanted(ci) & ~cap->mds_wanted)
-                               ci->i_ceph_flags |= CEPH_I_CAP_DROPPED;
                        spin_unlock(&ci->i_ceph_lock);
                }
        } else if (ev == FORCE_RO) {
index 22b89eaeaad44b82163e4e05266780c7d31aa36d..356ad7b46b856bc921ac0f9b222ee181c8ef2f10 100644 (file)
@@ -522,13 +522,12 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
 #define CEPH_I_POOL_RD         (1 << 4)  /* can read from pool */
 #define CEPH_I_POOL_WR         (1 << 5)  /* can write to pool */
 #define CEPH_I_SEC_INITED      (1 << 6)  /* security initialized */
-#define CEPH_I_CAP_DROPPED     (1 << 7)  /* caps were forcibly dropped */
-#define CEPH_I_KICK_FLUSH      (1 << 8)  /* kick flushing caps */
-#define CEPH_I_FLUSH_SNAPS     (1 << 9)  /* need flush snapss */
-#define CEPH_I_ERROR_WRITE     (1 << 10) /* have seen write errors */
-#define CEPH_I_ERROR_FILELOCK  (1 << 11) /* have seen file lock errors */
-#define CEPH_I_ODIRECT         (1 << 12) /* inode in direct I/O mode */
-#define CEPH_ASYNC_CREATE_BIT  (13)      /* async create in flight for this */
+#define CEPH_I_KICK_FLUSH      (1 << 7)  /* kick flushing caps */
+#define CEPH_I_FLUSH_SNAPS     (1 << 8)  /* need flush snapss */
+#define CEPH_I_ERROR_WRITE     (1 << 9) /* have seen write errors */
+#define CEPH_I_ERROR_FILELOCK  (1 << 10) /* have seen file lock errors */
+#define CEPH_I_ODIRECT         (1 << 11) /* inode in direct I/O mode */
+#define CEPH_ASYNC_CREATE_BIT  (12)      /* async create in flight for this */
 #define CEPH_I_ASYNC_CREATE    (1 << CEPH_ASYNC_CREATE_BIT)
 
 /*