either both data and tag or none of them are written. The
journaled mode degrades write throughput twice because the
data have to be written twice.
+ R - recovery mode - in this mode, journal is not replayed,
+ checksums are not checked and writes to the device are not
+ allowed. This mode is useful for data recovery if the
+ device cannot be activated in any of the other standard
+ modes.
5. the number of additional arguments
unsigned sectors_to_process = dio->range.n_sectors;
sector_t sector = dio->range.logical_sector;
+ if (unlikely(ic->mode == 'R'))
+ goto skip_io;
+
checksums = kmalloc((PAGE_SIZE >> SECTOR_SHIFT) * ic->tag_size + extra_space,
GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN);
if (!checksums)
}
}
}
+skip_io:
dec_in_flight(dio);
return;
error:
return -EIO;
}
+ if (unlikely(ic->mode == 'R') && unlikely(dio->write))
+ return -EIO;
+
get_area_and_offset(ic, dio->range.logical_sector, &area, &offset);
dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset, &dio->metadata_offset);
bio->bi_iter.bi_sector = get_data_sector(ic, area, offset);
bool journal_empty;
unsigned char unused, last_used, want_commit_seq;
+ if (ic->mode == 'R')
+ return;
+
if (ic->journal_uptodate)
return;
}
}
- if (!strcmp(argv[3], "J") || !strcmp(argv[3], "D"))
+ if (!strcmp(argv[3], "J") || !strcmp(argv[3], "D") || !strcmp(argv[3], "R"))
ic->mode = argv[3][0];
else {
ti->error = "Invalid mode (expecting J or D)";
ti->error = "Error reading superblock";
goto bad;
}
- if (!memcmp(ic->sb->magic, SB_MAGIC, 8)) {
- should_write_sb = false;
- } else {
- for (i = 0; i < 512; i += 8) {
- if (*(__u64 *)((__u8 *)ic->sb + i)) {
- r = -EINVAL;
- ti->error = "The device is not initialized";
- goto bad;
+ should_write_sb = false;
+ if (memcmp(ic->sb->magic, SB_MAGIC, 8)) {
+ if (ic->mode != 'R') {
+ for (i = 0; i < 512; i += 8) {
+ if (*(__u64 *)((__u8 *)ic->sb + i)) {
+ r = -EINVAL;
+ ti->error = "The device is not initialized";
+ goto bad;
+ }
}
}
ti->error = "Could not initialize superblock";
goto bad;
}
- should_write_sb = true;
+ if (ic->mode != 'R')
+ should_write_sb = true;
}
if (ic->sb->version != SB_VERSION) {
}
dm_bufio_set_sector_offset(ic->bufio, ic->start + ic->initial_sectors);
- r = create_journal(ic, &ti->error);
- if (r)
- goto bad;
+ if (ic->mode != 'R') {
+ r = create_journal(ic, &ti->error);
+ if (r)
+ goto bad;
+ }
if (should_write_sb) {
int r;