From: Vyacheslav Dubeyko <slava@dubeyko.com>
To: Linux FS devel list <linux-fsdevel@vger.kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
ChristophHellwig <hch@infradead.org>,
Hin-Tak Leung <htl10@users.sourceforge.net>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [PATCH 12/14] hfsplus: implement replay transaction's block functionality
Date: Thu, 26 Dec 2013 13:49:32 +0400 [thread overview]
Message-ID: <1388051372.4168.76.camel@slavad-ubuntu> (raw)
From: Vyacheslav Dubeyko <slava@dubeyko.com>
Subject: [PATCH 12/14] hfsplus: implement replay transaction's block functionality
A group of related changes is called a transaction. When all of the
changes of a transaction have been written to their normal locations
on disk, that transaction has been committed, and is removed from the
journal. The journal may contain several transactions. Copying changes
from all transactions to their normal locations on disk is called
replaying the journal.
A single transaction consists of several blocks, including both the data
to be written, and the location where that data is to be written. This is
represented on disk by a block list header, which describes the number
and sizes of the blocks, immediately followed by the contents of those
blocks.
This patch implements replaying of transaction's block in location
is described by binfo in block list.
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
CC: Al Viro <viro@zeniv.linux.org.uk>
CC: Christoph Hellwig <hch@infradead.org>
CC: Hin-Tak Leung <htl10@users.sourceforge.net>
---
fs/hfsplus/journal.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/fs/hfsplus/journal.c b/fs/hfsplus/journal.c
index d061c7f..fb44829 100644
--- a/fs/hfsplus/journal.c
+++ b/fs/hfsplus/journal.c
@@ -590,6 +590,93 @@ static int hfsplus_check_transaction_block(struct super_block *sb, int i,
return 0;
}
+static int hfsplus_replay_transaction_block(struct super_block *sb, int i,
+ struct hfsplus_blist_desc *desc)
+{
+ struct hfsplus_journal *jnl = HFSPLUS_SB(sb)->jnl;
+ struct hfsplus_journal_header *jh = jnl->jh;
+ struct hfsplus_block_info *binfo;
+ u64 bnum;
+ u32 bsize;
+ sector_t src_sec, dst_sec;
+
+ hfs_dbg(JREPLAY, "replay binfo[%u]\n", i);
+
+ binfo = hfsplus_get_binfo(sb, i, desc);
+ if (!binfo) {
+ pr_err("unable to get binfo[%u]\n", i);
+ return -EIO;
+ }
+
+ bnum = BNUM(binfo);
+ bsize = BSIZE(binfo);
+
+ hfs_dbg(JREPLAY, "bnum: %llu, bsize: %u\n", bnum, bsize);
+
+ if (bnum == ~(u64)0) {
+ hfs_dbg(JREPLAY, "don't add *killed* block %llu\n", bnum);
+ return 0; /* don't add "killed" blocks */
+ }
+
+ src_sec = JOURNAL_OFF_TO_SEC(sb);
+ dst_sec = HFSPLUS_SB(sb)->blockoffset + bnum;
+
+ hfs_dbg(JREPLAY, "dst_sec: %lu, bsize: %u\n",
+ dst_sec, bsize);
+
+ while (bsize > 0) {
+ size_t buf_size = hfsplus_min_io_size(sb);
+ size_t dst_off = 0;
+ size_t rest_bytes;
+ int err;
+
+ if (dst_sec >= HFSPLUS_SB(sb)->sect_count) {
+ pr_err("replay out of volume %lu\n", dst_sec);
+ return -EIO;
+ }
+
+ while (dst_off < buf_size) {
+ void *src_ptr;
+ size_t copy_size = HFSPLUS_SECTOR_SIZE;
+
+ if (need_to_wrap_journal(jh, TR_START(jh), copy_size)) {
+ hfsplus_wrap_journal(sb, TR_START(jh),
+ copy_size);
+ src_sec = JOURNAL_OFF_TO_SEC(sb);
+ }
+
+ err = hfsplus_submit_bio(sb, src_sec, desc->src_buf,
+ &src_ptr, READ, &rest_bytes);
+ if (err) {
+ pr_err("can't read sector %lu of block list\n",
+ src_sec);
+ return err;
+ }
+
+ BUG_ON(rest_bytes < HFSPLUS_SECTOR_SIZE);
+
+ memcpy((void *)((u8 *)desc->dst_buf + dst_off),
+ desc->src_buf, copy_size);
+
+ dst_off += copy_size;
+ bsize -= copy_size;
+ le64_add_cpu(&jh->start, copy_size);
+ src_sec = JOURNAL_OFF_TO_SEC(sb);
+ }
+
+ err = hfsplus_submit_bio(sb, dst_sec, desc->dst_buf, NULL,
+ WRITE_SYNC, NULL);
+ if (err) {
+ pr_err("can't replay sector %lu\n", dst_sec);
+ return err;
+ }
+
+ dst_sec += buf_size >> HFSPLUS_SECTOR_SHIFT;
+ }
+
+ return 0;
+}
+
static inline
bool hfsplus_journal_empty(struct hfsplus_journal_header *jh)
{
--
1.7.9.5
reply other threads:[~2013-12-26 9:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1388051372.4168.76.camel@slavad-ubuntu \
--to=slava@dubeyko.com \
--cc=akpm@linux-foundation.org \
--cc=hch@infradead.org \
--cc=htl10@users.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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;
as well as URLs for NNTP newsgroup(s).