summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/scrub.c
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-03-23 16:34:19 +0100
committerArne Jansen <sensille@gmx.net>2011-05-12 14:48:31 +0200
commit8628764e1a5e1998a42b9713e9edea7753653d01 (patch)
tree19c88f4d4eb806f7d5de83a1fc36996658ace17d /fs/btrfs/scrub.c
parent96e369208e65a7d017a52361fd572df41fde8472 (diff)
btrfs: add readonly flag
setting the readonly flag prevents writes in case an error is detected Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs/scrub.c')
-rw-r--r--fs/btrfs/scrub.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 6a50801ecfa..a31f2a9bd2e 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -42,7 +42,6 @@
* - 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
* - track and record media errors, throw out bad devices
- * - add a readonly mode
* - add a mode to also read unallocated space
* - make the prefetch cancellable
*/
@@ -99,6 +98,7 @@ struct scrub_dev {
u16 csum_size;
struct list_head csum_list;
atomic_t cancel_req;
+ int readonly;
/*
* statistics
*/
@@ -329,14 +329,16 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
if (i == multi->num_stripes)
goto uncorrectable;
- /*
- * 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,
- sbio->bio->bi_io_vec[ix].bv_page)) {
- /* I/O-error, writeback failed, give up */
- goto uncorrectable;
+ if (!sdev->readonly) {
+ /*
+ * 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,
+ sbio->bio->bi_io_vec[ix].bv_page)) {
+ /* I/O-error, writeback failed, give up */
+ goto uncorrectable;
+ }
}
kfree(multi);
@@ -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,
- struct btrfs_scrub_progress *progress)
+ struct btrfs_scrub_progress *progress, int readonly)
{
struct scrub_dev *sdev;
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,
scrub_workers_put(root);
return PTR_ERR(sdev);
}
+ sdev->readonly = readonly;
dev->scrub_device = sdev;
atomic_inc(&fs_info->scrubs_running);