summaryrefslogtreecommitdiff
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-01-12 12:18:00 +0300
committerIlya Dryomov <idryomov@gmail.com>2017-02-20 14:16:06 +0300
commiteb65b919b914e65485fd8134912066f4fafc4f1e (patch)
tree85f61deab3e050c1003787b6a00146d2c97e1411 /fs/ceph/caps.c
parent7c94ba27903c3c46c5829e96efb7c2a8ab7510e9 (diff)
downloadlinux-eb65b919b914e65485fd8134912066f4fafc4f1e.tar.xz
ceph: avoid updating mds_wanted too frequently
user space may open/close single file frequently. It's not good to send a clientcaps message to mds for each open/close syscall. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index e3a2a3f32568..d941c48e8bff 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1184,6 +1184,13 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
delayed = 1;
}
ci->i_ceph_flags &= ~(CEPH_I_NODELAY | CEPH_I_FLUSH);
+ if (want & ~cap->mds_wanted) {
+ /* user space may open/close single file frequently.
+ * This avoids droping mds_wanted immediately after
+ * requesting new mds_wanted.
+ */
+ __cap_set_timeouts(mdsc, ci);
+ }
cap->issued &= retain; /* drop bits we don't want */
if (cap->implemented & ~cap->issued) {
@@ -2485,15 +2492,14 @@ again:
goto out_unlock;
}
mds_wanted = __ceph_caps_mds_wanted(ci);
- if ((mds_wanted & need) != need) {
+ if (need & ~(mds_wanted & need)) {
dout("get_cap_refs %p caps were dropped"
" (session killed?)\n", inode);
*err = -ESTALE;
ret = 1;
goto out_unlock;
}
- if ((mds_wanted & file_wanted) ==
- (file_wanted & (CEPH_CAP_FILE_RD|CEPH_CAP_FILE_WR)))
+ if (!(file_wanted & ~mds_wanted))
ci->i_ceph_flags &= ~CEPH_I_CAP_DROPPED;
}