nilfs2: do not propagate ENOENT error from nilfs_sufile_mark_dirty()
authorRyusuke Konishi <konishi.ryusuke@gmail.com>
Wed, 21 Aug 2024 15:46:27 +0000 (00:46 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 2 Sep 2024 03:43:40 +0000 (20:43 -0700)
nilfs_sufile_mark_dirty(), which marks a block in the sufile metadata file
as dirty in preparation for log writing, returns -ENOENT to the caller if
the block containing the segment usage of the specified segment is
missing.

This internal code can propagate through the log writer to system calls
such as fsync.  To prevent this, treat this case as a filesystem error and
return -EIO instead.

Link: https://lkml.kernel.org/r/20240821154627.11848-6-konishi.ryusuke@gmail.com
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/nilfs2/sufile.c

index f071eba48163adc8265d8dc392656d0617760cfd..eea5a6a12f7bec078c6d3a812a5e4f5dfb75fc34 100644 (file)
@@ -513,8 +513,15 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
 
        down_write(&NILFS_MDT(sufile)->mi_sem);
        ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
-       if (ret)
+       if (unlikely(ret)) {
+               if (ret == -ENOENT) {
+                       nilfs_error(sufile->i_sb,
+                                   "segment usage for segment %llu is unreadable due to a hole block",
+                                   (unsigned long long)segnum);
+                       ret = -EIO;
+               }
                goto out_sem;
+       }
 
        kaddr = kmap_local_page(bh->b_page);
        su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);