Commit 81f148a9 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov

ceph: invalidate all write mode filp after reconnect

Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent ff5d913d
...@@ -2780,12 +2780,17 @@ int ceph_get_caps(struct file *filp, int need, int want, ...@@ -2780,12 +2780,17 @@ int ceph_get_caps(struct file *filp, int need, int want,
struct ceph_file_info *fi = filp->private_data; struct ceph_file_info *fi = filp->private_data;
struct inode *inode = file_inode(filp); struct inode *inode = file_inode(filp);
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
int ret, _got, flags; int ret, _got, flags;
ret = ceph_pool_perm_check(inode, need); ret = ceph_pool_perm_check(inode, need);
if (ret < 0) if (ret < 0)
return ret; return ret;
if ((fi->fmode & CEPH_FILE_MODE_WR) &&
fi->filp_gen != READ_ONCE(fsc->filp_gen))
return -EBADF;
while (true) { while (true) {
if (endoff > 0) if (endoff > 0)
check_max_size(inode, endoff); check_max_size(inode, endoff);
...@@ -2814,6 +2819,14 @@ int ceph_get_caps(struct file *filp, int need, int want, ...@@ -2814,6 +2819,14 @@ int ceph_get_caps(struct file *filp, int need, int want,
if (ret == -EAGAIN) if (ret == -EAGAIN)
continue; 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 < 0) {
if (ret == -ESTALE) { if (ret == -ESTALE) {
/* session was killed, try renew caps */ /* session was killed, try renew caps */
......
...@@ -234,6 +234,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file, ...@@ -234,6 +234,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
spin_lock_init(&fi->rw_contexts_lock); spin_lock_init(&fi->rw_contexts_lock);
INIT_LIST_HEAD(&fi->rw_contexts); INIT_LIST_HEAD(&fi->rw_contexts);
fi->meta_err = errseq_sample(&ci->i_meta_err); fi->meta_err = errseq_sample(&ci->i_meta_err);
fi->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen);
return 0; return 0;
} }
......
...@@ -664,6 +664,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, ...@@ -664,6 +664,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
fsc->sb = NULL; fsc->sb = NULL;
fsc->mount_state = CEPH_MOUNT_MOUNTING; fsc->mount_state = CEPH_MOUNT_MOUNTING;
fsc->filp_gen = 1;
atomic_long_set(&fsc->writeback_count, 0); atomic_long_set(&fsc->writeback_count, 0);
...@@ -829,6 +830,7 @@ static void ceph_umount_begin(struct super_block *sb) ...@@ -829,6 +830,7 @@ static void ceph_umount_begin(struct super_block *sb)
fsc->mount_state = CEPH_MOUNT_SHUTDOWN; fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
ceph_osdc_abort_requests(&fsc->client->osdc, -EIO); ceph_osdc_abort_requests(&fsc->client->osdc, -EIO);
ceph_mdsc_force_umount(fsc->mdsc); ceph_mdsc_force_umount(fsc->mdsc);
fsc->filp_gen++; // invalidate open files
} }
static int ceph_remount(struct super_block *sb, int *flags, char *data) static int ceph_remount(struct super_block *sb, int *flags, char *data)
......
...@@ -101,6 +101,8 @@ struct ceph_fs_client { ...@@ -101,6 +101,8 @@ struct ceph_fs_client {
struct ceph_client *client; struct ceph_client *client;
unsigned long mount_state; unsigned long mount_state;
u32 filp_gen;
loff_t max_file_size; loff_t max_file_size;
struct ceph_mds_client *mdsc; struct ceph_mds_client *mdsc;
...@@ -707,6 +709,7 @@ struct ceph_file_info { ...@@ -707,6 +709,7 @@ struct ceph_file_info {
struct list_head rw_contexts; struct list_head rw_contexts;
errseq_t meta_err; errseq_t meta_err;
u32 filp_gen;
atomic_t num_locks; atomic_t num_locks;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment