summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2019-07-25 20:16:46 +0800
committerIlya Dryomov <idryomov@gmail.com>2019-09-16 12:06:24 +0200
commit81f148a910045cd0a139f589a0b42764b172f8f5 (patch)
tree1f89ef39c6b7a440490aa2293f8ec70e8ecc74cd /fs/ceph/caps.c
parentff5d913dfc7142974eb1694d5fd6284658e46bc6 (diff)
downloadlinux-stable-81f148a910045cd0a139f589a0b42764b172f8f5.tar.gz
linux-stable-81f148a910045cd0a139f589a0b42764b172f8f5.tar.bz2
linux-stable-81f148a910045cd0a139f589a0b42764b172f8f5.zip
ceph: invalidate all write mode filp after reconnect
Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 102192c90edd..d17bde5d4f9a 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2780,12 +2780,17 @@ int ceph_get_caps(struct file *filp, int need, int want,
struct ceph_file_info *fi = filp->private_data;
struct inode *inode = file_inode(filp);
struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
int ret, _got, flags;
ret = ceph_pool_perm_check(inode, need);
if (ret < 0)
return ret;
+ if ((fi->fmode & CEPH_FILE_MODE_WR) &&
+ fi->filp_gen != READ_ONCE(fsc->filp_gen))
+ return -EBADF;
+
while (true) {
if (endoff > 0)
check_max_size(inode, endoff);
@@ -2814,6 +2819,14 @@ int ceph_get_caps(struct file *filp, int need, int want,
if (ret == -EAGAIN)
continue;
}
+
+ if ((fi->fmode & CEPH_FILE_MODE_WR) &&
+ fi->filp_gen != READ_ONCE(fsc->filp_gen)) {
+ if (ret >= 0 && _got)
+ ceph_put_cap_refs(ci, _got);
+ return -EBADF;
+ }
+
if (ret < 0) {
if (ret == -ESTALE) {
/* session was killed, try renew caps */