Commit 8628764e authored by Arne Jansen's avatar Arne Jansen

btrfs: add readonly flag

setting the readonly flag prevents writes in case an error is detected
Signed-off-by: default avatarArne Jansen <sensille@gmx.net>
parent 96e36920
...@@ -2657,7 +2657,7 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, ...@@ -2657,7 +2657,7 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
/* scrub.c */ /* scrub.c */
int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
struct btrfs_scrub_progress *progress); struct btrfs_scrub_progress *progress, int readonly);
int btrfs_scrub_pause(struct btrfs_root *root); int btrfs_scrub_pause(struct btrfs_root *root);
int btrfs_scrub_pause_super(struct btrfs_root *root); int btrfs_scrub_pause_super(struct btrfs_root *root);
int btrfs_scrub_continue(struct btrfs_root *root); int btrfs_scrub_continue(struct btrfs_root *root);
......
...@@ -2547,7 +2547,7 @@ static long btrfs_ioctl_scrub(struct btrfs_root *root, void __user *arg) ...@@ -2547,7 +2547,7 @@ static long btrfs_ioctl_scrub(struct btrfs_root *root, void __user *arg)
return PTR_ERR(sa); return PTR_ERR(sa);
ret = btrfs_scrub_dev(root, sa->devid, sa->start, sa->end, ret = btrfs_scrub_dev(root, sa->devid, sa->start, sa->end,
&sa->progress); &sa->progress, sa->flags & BTRFS_SCRUB_READONLY);
if (copy_to_user(arg, sa, sizeof(*sa))) if (copy_to_user(arg, sa, sizeof(*sa)))
ret = -EFAULT; ret = -EFAULT;
......
...@@ -81,6 +81,7 @@ struct btrfs_scrub_progress { ...@@ -81,6 +81,7 @@ struct btrfs_scrub_progress {
* Intermittent error. */ * Intermittent error. */
}; };
#define BTRFS_SCRUB_READONLY 1
struct btrfs_ioctl_scrub_args { struct btrfs_ioctl_scrub_args {
__u64 devid; /* in */ __u64 devid; /* in */
__u64 start; /* in */ __u64 start; /* in */
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
* - In case of a read error on files with nodatasum, map the file and read * - In case of a read error on files with nodatasum, map the file and read
* the extent to trigger a writeback of the good copy * the extent to trigger a writeback of the good copy
* - track and record media errors, throw out bad devices * - track and record media errors, throw out bad devices
* - add a readonly mode
* - add a mode to also read unallocated space * - add a mode to also read unallocated space
* - make the prefetch cancellable * - make the prefetch cancellable
*/ */
...@@ -99,6 +98,7 @@ struct scrub_dev { ...@@ -99,6 +98,7 @@ struct scrub_dev {
u16 csum_size; u16 csum_size;
struct list_head csum_list; struct list_head csum_list;
atomic_t cancel_req; atomic_t cancel_req;
int readonly;
/* /*
* statistics * statistics
*/ */
...@@ -329,14 +329,16 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -329,14 +329,16 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
if (i == multi->num_stripes) if (i == multi->num_stripes)
goto uncorrectable; goto uncorrectable;
/* if (!sdev->readonly) {
* bi_io_vec[ix].bv_page now contains good data, write it back /*
*/ * bi_io_vec[ix].bv_page now contains good data, write it back
if (scrub_fixup_io(WRITE, sdev->dev->bdev, */
(sbio->physical + ix * PAGE_SIZE) >> 9, if (scrub_fixup_io(WRITE, sdev->dev->bdev,
sbio->bio->bi_io_vec[ix].bv_page)) { (sbio->physical + ix * PAGE_SIZE) >> 9,
/* I/O-error, writeback failed, give up */ sbio->bio->bi_io_vec[ix].bv_page)) {
goto uncorrectable; /* I/O-error, writeback failed, give up */
goto uncorrectable;
}
} }
kfree(multi); kfree(multi);
...@@ -1156,7 +1158,7 @@ static noinline_for_stack void scrub_workers_put(struct btrfs_root *root) ...@@ -1156,7 +1158,7 @@ static noinline_for_stack void scrub_workers_put(struct btrfs_root *root)
int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
struct btrfs_scrub_progress *progress) struct btrfs_scrub_progress *progress, int readonly)
{ {
struct scrub_dev *sdev; struct scrub_dev *sdev;
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
...@@ -1209,6 +1211,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, ...@@ -1209,6 +1211,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
scrub_workers_put(root); scrub_workers_put(root);
return PTR_ERR(sdev); return PTR_ERR(sdev);
} }
sdev->readonly = readonly;
dev->scrub_device = sdev; dev->scrub_device = sdev;
atomic_inc(&fs_info->scrubs_running); atomic_inc(&fs_info->scrubs_running);
......
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