Commit 2f111a6f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ceph-for-5.15-rc7' of git://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
 "Two important filesystem fixes, marked for stable.

  The blocklisted superblocks issue was particularly annoying because
  for unexperienced users it essentially exacted a reboot to establish a
  new functional mount in that scenario"

* tag 'ceph-for-5.15-rc7' of git://github.com/ceph/ceph-client:
  ceph: fix handling of "meta" errors
  ceph: skip existing superblocks that are blocklisted or shut down when mounting
parents 515dcc2e 1bd85aa6
...@@ -2330,7 +2330,6 @@ static int unsafe_request_wait(struct inode *inode) ...@@ -2330,7 +2330,6 @@ static int unsafe_request_wait(struct inode *inode)
int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{ {
struct ceph_file_info *fi = file->private_data;
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
u64 flush_tid; u64 flush_tid;
...@@ -2365,14 +2364,9 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -2365,14 +2364,9 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
if (err < 0) if (err < 0)
ret = err; ret = err;
if (errseq_check(&ci->i_meta_err, READ_ONCE(fi->meta_err))) { err = file_check_and_advance_wb_err(file);
spin_lock(&file->f_lock); if (err < 0)
err = errseq_check_and_advance(&ci->i_meta_err, ret = err;
&fi->meta_err);
spin_unlock(&file->f_lock);
if (err < 0)
ret = err;
}
out: out:
dout("fsync %p%s result=%d\n", inode, datasync ? " datasync" : "", ret); dout("fsync %p%s result=%d\n", inode, datasync ? " datasync" : "", ret);
return ret; return ret;
......
...@@ -233,7 +233,6 @@ static int ceph_init_file_info(struct inode *inode, struct file *file, ...@@ -233,7 +233,6 @@ 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->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen); fi->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen);
return 0; return 0;
......
...@@ -541,8 +541,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb) ...@@ -541,8 +541,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
ceph_fscache_inode_init(ci); ceph_fscache_inode_init(ci);
ci->i_meta_err = 0;
return &ci->vfs_inode; return &ci->vfs_inode;
} }
......
...@@ -1493,7 +1493,6 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc, ...@@ -1493,7 +1493,6 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
{ {
struct ceph_mds_request *req; struct ceph_mds_request *req;
struct rb_node *p; struct rb_node *p;
struct ceph_inode_info *ci;
dout("cleanup_session_requests mds%d\n", session->s_mds); dout("cleanup_session_requests mds%d\n", session->s_mds);
mutex_lock(&mdsc->mutex); mutex_lock(&mdsc->mutex);
...@@ -1502,16 +1501,10 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc, ...@@ -1502,16 +1501,10 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
struct ceph_mds_request, r_unsafe_item); struct ceph_mds_request, r_unsafe_item);
pr_warn_ratelimited(" dropping unsafe request %llu\n", pr_warn_ratelimited(" dropping unsafe request %llu\n",
req->r_tid); req->r_tid);
if (req->r_target_inode) { if (req->r_target_inode)
/* dropping unsafe change of inode's attributes */ mapping_set_error(req->r_target_inode->i_mapping, -EIO);
ci = ceph_inode(req->r_target_inode); if (req->r_unsafe_dir)
errseq_set(&ci->i_meta_err, -EIO); mapping_set_error(req->r_unsafe_dir->i_mapping, -EIO);
}
if (req->r_unsafe_dir) {
/* dropping unsafe directory operation */
ci = ceph_inode(req->r_unsafe_dir);
errseq_set(&ci->i_meta_err, -EIO);
}
__unregister_request(mdsc, req); __unregister_request(mdsc, req);
} }
/* zero r_attempts, so kick_requests() will re-send requests */ /* zero r_attempts, so kick_requests() will re-send requests */
...@@ -1678,7 +1671,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, ...@@ -1678,7 +1671,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
spin_unlock(&mdsc->cap_dirty_lock); spin_unlock(&mdsc->cap_dirty_lock);
if (dirty_dropped) { if (dirty_dropped) {
errseq_set(&ci->i_meta_err, -EIO); mapping_set_error(inode->i_mapping, -EIO);
if (ci->i_wrbuffer_ref_head == 0 && if (ci->i_wrbuffer_ref_head == 0 &&
ci->i_wr_ref == 0 && ci->i_wr_ref == 0 &&
......
...@@ -1002,16 +1002,16 @@ static int ceph_compare_super(struct super_block *sb, struct fs_context *fc) ...@@ -1002,16 +1002,16 @@ static int ceph_compare_super(struct super_block *sb, struct fs_context *fc)
struct ceph_fs_client *new = fc->s_fs_info; struct ceph_fs_client *new = fc->s_fs_info;
struct ceph_mount_options *fsopt = new->mount_options; struct ceph_mount_options *fsopt = new->mount_options;
struct ceph_options *opt = new->client->options; struct ceph_options *opt = new->client->options;
struct ceph_fs_client *other = ceph_sb_to_client(sb); struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
dout("ceph_compare_super %p\n", sb); dout("ceph_compare_super %p\n", sb);
if (compare_mount_options(fsopt, opt, other)) { if (compare_mount_options(fsopt, opt, fsc)) {
dout("monitor(s)/mount options don't match\n"); dout("monitor(s)/mount options don't match\n");
return 0; return 0;
} }
if ((opt->flags & CEPH_OPT_FSID) && if ((opt->flags & CEPH_OPT_FSID) &&
ceph_fsid_compare(&opt->fsid, &other->client->fsid)) { ceph_fsid_compare(&opt->fsid, &fsc->client->fsid)) {
dout("fsid doesn't match\n"); dout("fsid doesn't match\n");
return 0; return 0;
} }
...@@ -1019,6 +1019,17 @@ static int ceph_compare_super(struct super_block *sb, struct fs_context *fc) ...@@ -1019,6 +1019,17 @@ static int ceph_compare_super(struct super_block *sb, struct fs_context *fc)
dout("flags differ\n"); dout("flags differ\n");
return 0; return 0;
} }
if (fsc->blocklisted && !ceph_test_mount_opt(fsc, CLEANRECOVER)) {
dout("client is blocklisted (and CLEANRECOVER is not set)\n");
return 0;
}
if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
dout("client has been forcibly unmounted\n");
return 0;
}
return 1; return 1;
} }
......
...@@ -429,8 +429,6 @@ struct ceph_inode_info { ...@@ -429,8 +429,6 @@ struct ceph_inode_info {
#ifdef CONFIG_CEPH_FSCACHE #ifdef CONFIG_CEPH_FSCACHE
struct fscache_cookie *fscache; struct fscache_cookie *fscache;
#endif #endif
errseq_t i_meta_err;
struct inode vfs_inode; /* at end */ struct inode vfs_inode; /* at end */
}; };
...@@ -774,7 +772,6 @@ struct ceph_file_info { ...@@ -774,7 +772,6 @@ struct ceph_file_info {
spinlock_t rw_contexts_lock; spinlock_t rw_contexts_lock;
struct list_head rw_contexts; struct list_head rw_contexts;
errseq_t meta_err;
u32 filp_gen; 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