btrfs-progs: report I/O errors when closing the filesystem
authorOmar Sandoval <osandov@fb.com>
Fri, 3 Mar 2017 17:02:14 +0000 (09:02 -0800)
committerDavid Sterba <dsterba@suse.com>
Wed, 8 Mar 2017 12:36:49 +0000 (13:36 +0100)
If the final fsync() on the Btrfs device fails, we just swallow the
error and don't alert the user in any way. This was uncovered by xfstest
generic/405, which checks that mkfs fails when it encounters EIO.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
disk-io.c
volumes.c

index be6e28a..985c4a9 100644 (file)
--- a/disk-io.c
+++ b/disk-io.c
@@ -1815,10 +1815,10 @@ int close_ctree_fs_info(struct btrfs_fs_info *fs_info)
        free_fs_roots_tree(&fs_info->fs_root_tree);
 
        btrfs_release_all_roots(fs_info);
-       btrfs_close_devices(fs_info->fs_devices);
+       ret = btrfs_close_devices(fs_info->fs_devices);
        btrfs_cleanup_all_caches(fs_info);
        btrfs_free_fs_info(fs_info);
-       return 0;
+       return ret;
 }
 
 int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
index 59670c0..b350e25 100644 (file)
--- a/volumes.c
+++ b/volumes.c
@@ -160,6 +160,7 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
        struct btrfs_fs_devices *seed_devices;
        struct btrfs_device *device;
+       int ret = 0;
 
 again:
        if (!fs_devices)
@@ -168,7 +169,11 @@ again:
                device = list_entry(fs_devices->devices.next,
                                    struct btrfs_device, dev_list);
                if (device->fd != -1) {
-                       fsync(device->fd);
+                       if (fsync(device->fd) == -1) {
+                               warning("fsync on device %llu failed: %s",
+                                       device->devid, strerror(errno));
+                               ret = -errno;
+                       }
                        if (posix_fadvise(device->fd, 0, 0, POSIX_FADV_DONTNEED))
                                fprintf(stderr, "Warning, could not drop caches\n");
                        close(device->fd);
@@ -197,7 +202,7 @@ again:
                free(fs_devices);
        }
 
-       return 0;
+       return ret;
 }
 
 void btrfs_close_all_devices(void)