From: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
To: linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
Subject: [PATCH 1/1] nilfs2: add mount option that reduces super block writes
Date: Thu, 30 Jan 2014 03:47:00 +0100 [thread overview]
Message-ID: <75ceb45c464097ab556baacf2d15d6ae4b792bb2.1391048231.git.andreas.rohner@gmx.net> (raw)
In-Reply-To: <cover.1391048231.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
In-Reply-To: <cover.1391048231.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
This patch introduces a mount option bad_ftl that disables the
periodic overwrites of the super block to make the file system better
suitable for bad flash memory with a bad FTL. The super block is only
written at umount time. So if there is a power outage the file system
needs to be recovered by a linear scan of all segment summary blocks.
The linear scan is only necessary if the file system wasn't umounted
properly. So the normal mount time is not affected.
Signed-off-by: Andreas Rohner <andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
---
fs/nilfs2/segbuf.c | 3 ++-
fs/nilfs2/segment.c | 3 ++-
fs/nilfs2/super.c | 10 +++++++--
fs/nilfs2/the_nilfs.c | 54 ++++++++++++++++++++++++++++++++++++++++++++---
include/linux/nilfs2_fs.h | 4 +++-
5 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 2d8be51..4ea9dd6 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -158,6 +158,7 @@ void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
{
struct nilfs_segment_summary *raw_sum;
struct buffer_head *bh_sum;
+ struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info;
bh_sum = list_entry(segbuf->sb_segsum_buffers.next,
struct buffer_head, b_assoc_buffers);
@@ -172,7 +173,7 @@ void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
raw_sum->ss_nblocks = cpu_to_le32(segbuf->sb_sum.nblocks);
raw_sum->ss_nfinfo = cpu_to_le32(segbuf->sb_sum.nfinfo);
raw_sum->ss_sumbytes = cpu_to_le32(segbuf->sb_sum.sumbytes);
- raw_sum->ss_pad = 0;
+ raw_sum->ss_crc_seed = cpu_to_le32(nilfs->ns_crc_seed);
raw_sum->ss_cno = cpu_to_le64(segbuf->sb_sum.cno);
}
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index a1a1916..e8e38a9 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2288,7 +2288,8 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
if (mode != SC_FLUSH_DAT)
atomic_set(&nilfs->ns_ndirtyblks, 0);
if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
- nilfs_discontinued(nilfs)) {
+ nilfs_discontinued(nilfs) &&
+ !nilfs_test_opt(nilfs, BAD_FTL)) {
down_write(&nilfs->ns_sem);
err = -EIO;
sbp = nilfs_prepare_super(sci->sc_super,
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 7ac2a12..c3374ed 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -505,7 +505,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
err = nilfs_construct_segment(sb);
down_write(&nilfs->ns_sem);
- if (nilfs_sb_dirty(nilfs)) {
+ if (nilfs_sb_dirty(nilfs) && !nilfs_test_opt(nilfs, BAD_FTL)) {
sbp = nilfs_prepare_super(sb, nilfs_sb_will_flip(nilfs));
if (likely(sbp)) {
nilfs_set_log_cursor(sbp[0], nilfs);
@@ -691,6 +691,8 @@ static int nilfs_show_options(struct seq_file *seq, struct dentry *dentry)
seq_puts(seq, ",norecovery");
if (nilfs_test_opt(nilfs, DISCARD))
seq_puts(seq, ",discard");
+ if (nilfs_test_opt(nilfs, BAD_FTL))
+ seq_puts(seq, ",bad_ftl");
return 0;
}
@@ -712,7 +714,7 @@ static const struct super_operations nilfs_sops = {
enum {
Opt_err_cont, Opt_err_panic, Opt_err_ro,
Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
- Opt_discard, Opt_nodiscard, Opt_err,
+ Opt_discard, Opt_nodiscard, Opt_err, Opt_bad_ftl,
};
static match_table_t tokens = {
@@ -726,6 +728,7 @@ static match_table_t tokens = {
{Opt_norecovery, "norecovery"},
{Opt_discard, "discard"},
{Opt_nodiscard, "nodiscard"},
+ {Opt_bad_ftl, "bad_ftl"},
{Opt_err, NULL}
};
@@ -787,6 +790,9 @@ static int parse_options(char *options, struct super_block *sb, int is_remount)
case Opt_nodiscard:
nilfs_clear_opt(nilfs, DISCARD);
break;
+ case Opt_bad_ftl:
+ nilfs_set_opt(nilfs, BAD_FTL);
+ break;
default:
printk(KERN_ERR
"NILFS: Unrecognized mount option \"%s\"\n", p);
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 94c451c..d29b2f0 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -168,6 +168,50 @@ static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
nilfs_dispose_segment_list(&ri->ri_used_segments);
}
+static int nilfs_search_log_cursor(struct the_nilfs *nilfs)
+{
+ u64 segnum;
+ struct buffer_head *bh_sum = NULL;
+ struct nilfs_segment_summary *sum;
+ sector_t seg_start, seg_end; /* range of full segment (block number) */
+
+ for (segnum = 0; segnum < nilfs->ns_nsegments; ++segnum) {
+ brelse(bh_sum);
+
+ /* Calculate range of segment */
+ nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
+
+ bh_sum = __bread(nilfs->ns_bdev, seg_start,
+ nilfs->ns_blocksize);
+ if (!bh_sum) {
+ printk(KERN_ERR "NILFS error searching for cursor.\n");
+ return -EINVAL;
+ }
+
+ sum = (struct nilfs_segment_summary *)bh_sum->b_data;
+
+ /*
+ * use ss_crc_seed to distinguish the segments from previous
+ * nilfs2 file systems on the same volume
+ */
+ if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC
+ || le32_to_cpu(sum->ss_nblocks) == 0
+ || le32_to_cpu(sum->ss_nblocks) >
+ nilfs->ns_blocks_per_segment
+ || le32_to_cpu(sum->ss_crc_seed) != nilfs->ns_crc_seed)
+ continue;
+
+ if (le64_to_cpu(sum->ss_seq) > nilfs->ns_last_seq) {
+ nilfs->ns_last_pseg = seg_start;
+ nilfs->ns_last_cno = le64_to_cpu(sum->ss_cno);
+ nilfs->ns_last_seq = le64_to_cpu(sum->ss_seq);
+ }
+ }
+ brelse(bh_sum);
+
+ return 0;
+}
+
/**
* nilfs_store_log_cursor - load log cursor from a super block
* @nilfs: nilfs object
@@ -179,7 +223,7 @@ static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
* scanning and recovery.
*/
static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
- struct nilfs_super_block *sbp)
+ struct nilfs_super_block *sbp, int valid_fs)
{
int ret = 0;
@@ -187,6 +231,9 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
+ if (!valid_fs && nilfs_test_opt(nilfs, BAD_FTL))
+ ret = nilfs_search_log_cursor(nilfs);
+
nilfs->ns_prev_seq = nilfs->ns_last_seq;
nilfs->ns_seg_seq = nilfs->ns_last_seq;
nilfs->ns_segnum =
@@ -263,7 +310,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
goto scan_error;
}
- err = nilfs_store_log_cursor(nilfs, sbp[0]);
+ err = nilfs_store_log_cursor(nilfs, sbp[0], 1);
if (err)
goto scan_error;
@@ -626,7 +673,8 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
- err = nilfs_store_log_cursor(nilfs, sbp);
+ err = nilfs_store_log_cursor(nilfs, sbp,
+ nilfs->ns_mount_state & NILFS_VALID_FS);
if (err)
goto failed_sbh;
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index 4140f7f..6a8f5f8 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -135,6 +135,8 @@ struct nilfs_super_root {
#define NILFS_MOUNT_NORECOVERY 0x4000 /* Disable write access during
mount-time recovery */
#define NILFS_MOUNT_DISCARD 0x8000 /* Issue DISCARD requests */
+#define NILFS_MOUNT_BAD_FTL 0x10000 /* Only write super block
+ at umount time */
/**
@@ -422,7 +424,7 @@ struct nilfs_segment_summary {
__le32 ss_nblocks;
__le32 ss_nfinfo;
__le32 ss_sumbytes;
- __le32 ss_pad;
+ __le32 ss_crc_seed;
__le64 ss_cno;
/* array of finfo structures */
};
--
1.8.5.3
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2014-01-30 2:47 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-15 10:44 Does nilfs2 do any in-place writes? Clemens Eisserer
[not found] ` <CAFvQSYSzpX_WpUi9KpGj0pZvzhw2mfzzOqcgdj9ripXAjipmtw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-15 10:52 ` Vyacheslav Dubeyko
2014-01-15 11:44 ` Clemens Eisserer
[not found] ` <CAFvQSYTG6HBVc9iodYyvCejwf889jiwOPsVb1Hi8cDrR9pOGeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-15 12:01 ` Vyacheslav Dubeyko
2014-01-15 15:23 ` Ryusuke Konishi
[not found] ` <20140116.002353.94325733.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-16 10:08 ` Vyacheslav Dubeyko
2014-01-17 22:55 ` Ryusuke Konishi
[not found] ` <20140118.075519.43661574.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-20 11:54 ` [writable snapshots discussion] " Vyacheslav Dubeyko
2014-01-18 0:00 ` Ryusuke Konishi
[not found] ` <20140118.090008.194171715.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-28 9:25 ` [static superblock discussion] " Vyacheslav Dubeyko
[not found] ` <1390901114.2942.11.camel-dzAnj6fV1RxGeWtTaGDT1UEK6ufn8VP3@public.gmane.org>
2014-01-29 12:44 ` Andreas Rohner
[not found] ` <52E8F7A7.8010505-hi6Y0CQ0nG0@public.gmane.org>
2014-01-29 13:19 ` Vyacheslav Dubeyko
2014-01-29 18:18 ` Clemens Eisserer
[not found] ` <CAFvQSYSu5CGxs+K6bZUCtq17PrS_paX3bXBuLBRTba_XWYGgAg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-30 2:46 ` [PATCH 0/1] nilfs2: add mount option that reduces super block writes Andreas Rohner
[not found] ` <cover.1391048231.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 2:47 ` Andreas Rohner [this message]
[not found] ` <75ceb45c464097ab556baacf2d15d6ae4b792bb2.1391048231.git.andreas.rohner-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 6:36 ` [PATCH 1/1] " Vyacheslav Dubeyko
[not found] ` <127C78C3-9D47-439C-9639-263BC453D98D-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-01-30 6:02 ` Andreas Rohner
[not found] ` <52E9EB06.1000504-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 7:44 ` Vyacheslav Dubeyko
[not found] ` <8DBE8E18-F678-44B0-A6A6-5AFEC227AA86-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-01-30 6:52 ` Andreas Rohner
2014-01-30 9:48 ` Andreas Rohner
[not found] ` <52EA2002.1030809-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 11:27 ` Vyacheslav Dubeyko
[not found] ` <A6830DB2-DC73-4ACC-BE73-7A6EC1AC7C18-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-01-30 11:33 ` Andreas Rohner
[not found] ` <52EA38A3.8060107-hi6Y0CQ0nG0@public.gmane.org>
2014-02-01 19:05 ` Clemens Eisserer
2014-01-30 3:27 ` [PATCH 0/1] " Andreas Rohner
2014-01-30 5:29 ` Ryusuke Konishi
[not found] ` <20140130.142941.55837481.konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2014-01-30 5:59 ` Andreas Rohner
2014-01-30 6:29 ` Andreas Rohner
[not found] ` <52E9F13A.5050805-hi6Y0CQ0nG0@public.gmane.org>
2014-01-30 8:46 ` Ryusuke Konishi
2014-01-30 8:35 ` [static superblock discussion] Does nilfs2 do any in-place writes? Vyacheslav Dubeyko
[not found] ` <71B2806D-7CF2-4992-A588-EB73EADFFF9F-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-01-30 10:09 ` Clemens Eisserer
[not found] ` <CAFvQSYQ84_BsqVC_ZM77P92jkP+1dh7NexvZWg4mFE7B3wSK0A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-30 12:42 ` Vyacheslav Dubeyko
[not found] ` <AE0F313D-5934-452B-80AB-5D691AF8A4BE-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-01-30 13:09 ` Clemens Eisserer
[not found] ` <CAFvQSYQGDXmUit1zFZ9_LAjdLjxM-i_yR2L6pwFDX_BEdjdXxQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-30 13:32 ` Vyacheslav Dubeyko
2014-01-30 14:03 ` Clemens Eisserer
[not found] ` <CAFvQSYQ-qkXz677-obgHVN5fLQiF10-A=T2yNNAHKRcOGm_Pqw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-30 15:27 ` Vyacheslav Dubeyko
[not found] ` <720AFF13-6203-4A28-9850-3C2CAFF3B7BF-yeENwD64cLxBDgjK7y7TUQ@public.gmane.org>
2014-02-05 20:47 ` Clemens Eisserer
[not found] ` <CAFvQSYStT4uwxqtxATLbPOvHYjww=sw=C=f3vBi_qdu6MXAn5A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-02-07 6:43 ` Vyacheslav Dubeyko
2014-01-16 10:03 ` Clemens Eisserer
[not found] ` <CAFvQSYSC7+dd93pRH-uok9N+A_s=1VKrfGEppu3qRTg3q=CuXQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-01-16 10:10 ` Vyacheslav Dubeyko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=75ceb45c464097ab556baacf2d15d6ae4b792bb2.1391048231.git.andreas.rohner@gmx.net \
--to=andreas.rohner-hi6y0cq0ng0@public.gmane.org \
--cc=linux-nilfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox