Skip to content

Commit 1bd85aa

Browse files
jtlaytonidryomov
authored andcommitted
ceph: fix handling of "meta" errors
Currently, we check the wb_err too early for directories, before all of the unsafe child requests have been waited on. In order to fix that we need to check the mapping->wb_err later nearer to the end of ceph_fsync. We also have an overly-complex method for tracking errors after blocklisting. The errors recorded in cleanup_session_requests go to a completely separate field in the inode, but we end up reporting them the same way we would for any other error (in fsync). There's no real benefit to tracking these errors in two different places, since the only reporting mechanism for them is in fsync, and we'd need to advance them both every time. Given that, we can just remove i_meta_err, and convert the places that used it to instead just use mapping->wb_err instead. That also fixes the original problem by ensuring that we do a check_and_advance of the wb_err at the end of the fsync op. Cc: [email protected] URL: https://tracker.ceph.com/issues/52864 Reported-by: Patrick Donnelly <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Reviewed-by: Xiubo Li <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 98d0a6f commit 1bd85aa

File tree

5 files changed

+8
-27
lines changed

5 files changed

+8
-27
lines changed

fs/ceph/caps.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2330,7 +2330,6 @@ static int unsafe_request_wait(struct inode *inode)
23302330

23312331
int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
23322332
{
2333-
struct ceph_file_info *fi = file->private_data;
23342333
struct inode *inode = file->f_mapping->host;
23352334
struct ceph_inode_info *ci = ceph_inode(inode);
23362335
u64 flush_tid;
@@ -2365,14 +2364,9 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
23652364
if (err < 0)
23662365
ret = err;
23672366

2368-
if (errseq_check(&ci->i_meta_err, READ_ONCE(fi->meta_err))) {
2369-
spin_lock(&file->f_lock);
2370-
err = errseq_check_and_advance(&ci->i_meta_err,
2371-
&fi->meta_err);
2372-
spin_unlock(&file->f_lock);
2373-
if (err < 0)
2374-
ret = err;
2375-
}
2367+
err = file_check_and_advance_wb_err(file);
2368+
if (err < 0)
2369+
ret = err;
23762370
out:
23772371
dout("fsync %p%s result=%d\n", inode, datasync ? " datasync" : "", ret);
23782372
return ret;

fs/ceph/file.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
233233

234234
spin_lock_init(&fi->rw_contexts_lock);
235235
INIT_LIST_HEAD(&fi->rw_contexts);
236-
fi->meta_err = errseq_sample(&ci->i_meta_err);
237236
fi->filp_gen = READ_ONCE(ceph_inode_to_client(inode)->filp_gen);
238237

239238
return 0;

fs/ceph/inode.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
541541

542542
ceph_fscache_inode_init(ci);
543543

544-
ci->i_meta_err = 0;
545-
546544
return &ci->vfs_inode;
547545
}
548546

fs/ceph/mds_client.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,6 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
14931493
{
14941494
struct ceph_mds_request *req;
14951495
struct rb_node *p;
1496-
struct ceph_inode_info *ci;
14971496

14981497
dout("cleanup_session_requests mds%d\n", session->s_mds);
14991498
mutex_lock(&mdsc->mutex);
@@ -1502,16 +1501,10 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
15021501
struct ceph_mds_request, r_unsafe_item);
15031502
pr_warn_ratelimited(" dropping unsafe request %llu\n",
15041503
req->r_tid);
1505-
if (req->r_target_inode) {
1506-
/* dropping unsafe change of inode's attributes */
1507-
ci = ceph_inode(req->r_target_inode);
1508-
errseq_set(&ci->i_meta_err, -EIO);
1509-
}
1510-
if (req->r_unsafe_dir) {
1511-
/* dropping unsafe directory operation */
1512-
ci = ceph_inode(req->r_unsafe_dir);
1513-
errseq_set(&ci->i_meta_err, -EIO);
1514-
}
1504+
if (req->r_target_inode)
1505+
mapping_set_error(req->r_target_inode->i_mapping, -EIO);
1506+
if (req->r_unsafe_dir)
1507+
mapping_set_error(req->r_unsafe_dir->i_mapping, -EIO);
15151508
__unregister_request(mdsc, req);
15161509
}
15171510
/* 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,
16781671
spin_unlock(&mdsc->cap_dirty_lock);
16791672

16801673
if (dirty_dropped) {
1681-
errseq_set(&ci->i_meta_err, -EIO);
1674+
mapping_set_error(inode->i_mapping, -EIO);
16821675

16831676
if (ci->i_wrbuffer_ref_head == 0 &&
16841677
ci->i_wr_ref == 0 &&

fs/ceph/super.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,6 @@ struct ceph_inode_info {
429429
#ifdef CONFIG_CEPH_FSCACHE
430430
struct fscache_cookie *fscache;
431431
#endif
432-
errseq_t i_meta_err;
433-
434432
struct inode vfs_inode; /* at end */
435433
};
436434

@@ -774,7 +772,6 @@ struct ceph_file_info {
774772
spinlock_t rw_contexts_lock;
775773
struct list_head rw_contexts;
776774

777-
errseq_t meta_err;
778775
u32 filp_gen;
779776
atomic_t num_locks;
780777
};

0 commit comments

Comments
 (0)