@@ -2783,6 +2783,10 @@ int ceph_get_caps(struct file *filp, int need, int want,
if (ret < 0)
return ret;
+ if ((fi->fmode & CEPH_FILE_MODE_WR) &&
+ fi->filp_gen != READ_ONCE(ceph_inode_to_client(inode)->filp_gen))
+ return -EBADF;
+
while (true) {
if (endoff > 0)
check_max_size(inode, endoff);
@@ -234,6 +234,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
spin_lock_init(&fi->rw_contexts_lock);
INIT_LIST_HEAD(&fi->rw_contexts);
fi->meta_err = errseq_sample(&ci->i_meta_err);
+ fi->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen);
return 0;
}
@@ -669,6 +669,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
fsc->sb = NULL;
fsc->mount_state = CEPH_MOUNT_MOUNTING;
+ fsc->filp_gen = 1;
atomic_long_set(&fsc->writeback_count, 0);
@@ -832,6 +833,7 @@ static void ceph_umount_begin(struct super_block *sb)
if (!fsc)
return;
fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
+ fsc->filp_gen++; // invalidate open files
ceph_osdc_abort_requests(&fsc->client->osdc, -EIO);
ceph_mdsc_force_umount(fsc->mdsc);
return;
@@ -102,6 +102,8 @@ struct ceph_fs_client {
struct ceph_client *client;
unsigned long mount_state;
+
+ u32 filp_gen;
loff_t max_file_size;
struct ceph_mds_client *mdsc;
@@ -708,6 +710,7 @@ struct ceph_file_info {
struct list_head rw_contexts;
errseq_t meta_err;
+ u32 filp_gen;
atomic_t num_locks;
};
Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/caps.c | 4 ++++ fs/ceph/file.c | 1 + fs/ceph/super.c | 2 ++ fs/ceph/super.h | 3 +++ 4 files changed, 10 insertions(+)