public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 4/5] metadump: walk single fsb objects a block at a time
Date: Thu, 23 Jan 2014 21:23:54 +1100	[thread overview]
Message-ID: <1390472635-17225-5-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1390472635-17225-1-git-send-email-david@fromorbit.com>

From: Dave Chinner <dchinner@redhat.com>

To be able to support arbitrary discontiguous extents in multi-block
objects, we need to be able to process a single object at a time
presented as a single flat buffer. Right now we pass an arbitrary
extent and have the individal object processing functions break it
up and keep track of inter-call state.

This greatly complicates the processing of directory objects, such
that certain formats are simply not handled at all. Instead, for
single block objects loop over the extent a block at a time, feeding
a whole object to the processing function and hence making the
extent walking generic instead of per object.

At thsi point multi-block directory objects still need to use the
existing code, so duplicate the old single block object code into it
so we can fix it up properly. This means directory block processing
can't be fully cleaned up yet.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 db/metadump.c | 180 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 107 insertions(+), 73 deletions(-)

diff --git a/db/metadump.c b/db/metadump.c
index 9fc08ed..e973c5e 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -1257,12 +1257,11 @@ obfuscate_dir_data_blocks(
 }
 
 static void
-obfuscate_symlink_blocks(
-	char			*block,
-	xfs_dfilblks_t		count)
+obfuscate_symlink_block(
+	char			*block)
 {
-	count <<= mp->m_sb.sb_blocklog;
-	obfuscate_path_components(block, count);
+	/* XXX: need to handle CRC headers */
+	obfuscate_path_components(block, mp->m_sb.sb_blocksize);
 }
 
 #define MAX_REMOTE_VALS		4095
@@ -1283,80 +1282,79 @@ add_remote_vals(
 		blockidx++;
 		length -= XFS_LBSIZE(mp);
 	}
+
+	if (attr_data.remote_val_count >= MAX_REMOTE_VALS) {
+		print_warning(
+"Overflowed attr obfuscation array. No longer obfuscating remote attrs.");
+	}
 }
 
 static void
-obfuscate_attr_blocks(
+obfuscate_attr_block(
 	char			*block,
-	xfs_dfiloff_t		offset,
-	xfs_dfilblks_t		count)
+	xfs_dfiloff_t		offset)
 {
 	xfs_attr_leafblock_t	*leaf;
-	int			c;
 	int			i;
 	int			nentries;
 	xfs_attr_leaf_entry_t 	*entry;
 	xfs_attr_leaf_name_local_t *local;
 	xfs_attr_leaf_name_remote_t *remote;
 
-	for (c = 0; c < count; c++, offset++, block += XFS_LBSIZE(mp)) {
+	leaf = (xfs_attr_leafblock_t *)block;
 
-		leaf = (xfs_attr_leafblock_t *)block;
-
-		if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) {
-			for (i = 0; i < attr_data.remote_val_count; i++) {
-				if (attr_data.remote_vals[i] == offset)
-					memset(block, 0, XFS_LBSIZE(mp));
-			}
-			continue;
+	if (be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC) {
+		for (i = 0; i < attr_data.remote_val_count; i++) {
+			/* XXX: need to handle CRC headers */
+			if (attr_data.remote_vals[i] == offset)
+				memset(block, 0, XFS_LBSIZE(mp));
 		}
+		return;
+	}
+
+	nentries = be16_to_cpu(leaf->hdr.count);
+	if (nentries * sizeof(xfs_attr_leaf_entry_t) +
+			sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) {
+		if (show_warnings)
+			print_warning("invalid attr count in inode %llu",
+					(long long)cur_ino);
+		return;
+	}
 
-		nentries = be16_to_cpu(leaf->hdr.count);
-		if (nentries * sizeof(xfs_attr_leaf_entry_t) +
-				sizeof(xfs_attr_leaf_hdr_t) > XFS_LBSIZE(mp)) {
+	for (i = 0, entry = &leaf->entries[0]; i < nentries; i++, entry++) {
+		if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) {
 			if (show_warnings)
-				print_warning("invalid attr count in inode %llu",
+				print_warning(
+				"invalid attr nameidx in inode %llu",
 						(long long)cur_ino);
-			continue;
+			break;
 		}
-
-		for (i = 0, entry = &leaf->entries[0]; i < nentries;
-				i++, entry++) {
-			if (be16_to_cpu(entry->nameidx) > XFS_LBSIZE(mp)) {
+		if (entry->flags & XFS_ATTR_LOCAL) {
+			local = xfs_attr3_leaf_name_local(leaf, i);
+			if (local->namelen == 0) {
 				if (show_warnings)
-					print_warning("invalid attr nameidx "
-							"in inode %llu",
-							(long long)cur_ino);
+					print_warning(
+				"zero length for attr name in inode %llu",
+						(long long)cur_ino);
 				break;
 			}
-			if (entry->flags & XFS_ATTR_LOCAL) {
-				local = xfs_attr3_leaf_name_local(leaf, i);
-				if (local->namelen == 0) {
-					if (show_warnings)
-						print_warning("zero length for "
-							"attr name in inode %llu",
-							(long long)cur_ino);
-					break;
-				}
-				generate_obfuscated_name(0, local->namelen,
-					&local->nameval[0]);
-				memset(&local->nameval[local->namelen], 0,
-					be16_to_cpu(local->valuelen));
-			} else {
-				remote = xfs_attr3_leaf_name_remote(leaf, i);
-				if (remote->namelen == 0 ||
-						remote->valueblk == 0) {
-					if (show_warnings)
-						print_warning("invalid attr "
-							"entry in inode %llu",
-							(long long)cur_ino);
-					break;
-				}
-				generate_obfuscated_name(0, remote->namelen,
-					&remote->name[0]);
-				add_remote_vals(be32_to_cpu(remote->valueblk),
-					be32_to_cpu(remote->valuelen));
+			generate_obfuscated_name(0, local->namelen,
+				&local->nameval[0]);
+			memset(&local->nameval[local->namelen], 0,
+				be16_to_cpu(local->valuelen));
+		} else {
+			remote = xfs_attr3_leaf_name_remote(leaf, i);
+			if (remote->namelen == 0 || remote->valueblk == 0) {
+				if (show_warnings)
+					print_warning(
+				"invalid attr entry in inode %llu",
+						(long long)cur_ino);
+				break;
 			}
+			generate_obfuscated_name(0, remote->namelen,
+						 &remote->name[0]);
+			add_remote_vals(be32_to_cpu(remote->valueblk),
+					be32_to_cpu(remote->valuelen));
 		}
 	}
 }
@@ -1369,7 +1367,9 @@ process_single_fsb_objects(
 	typnm_t		btype,
 	xfs_dfiloff_t	last)
 {
+	char		*dp;
 	int		ret = 0;
+	int		i;
 
 	push_cur();
 	set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), c * blkbb,
@@ -1392,22 +1392,27 @@ process_single_fsb_objects(
 		goto out_pop;
 	}
 
-	switch (btype) {
-	case TYP_DIR2:
-		if (o >= mp->m_dirleafblk)
-			break;
+	dp = iocur_top->data;
+	for (i = 0; i < c; i++) {
+		switch (btype) {
+		case TYP_DIR2:
+			if (o >= mp->m_dirleafblk)
+				break;
 
-		obfuscate_dir_data_blocks(iocur_top->data, o, c,
-					 last == mp->m_dirblkfsbs);
-		break;
-	case TYP_SYMLINK:
-		obfuscate_symlink_blocks(iocur_top->data, c);
-		break;
-	case TYP_ATTR:
-		obfuscate_attr_blocks(iocur_top->data, o, c);
-		break;
-	default:
-		break;
+			obfuscate_dir_data_blocks(dp, o, 1,
+						  last == mp->m_dirblkfsbs);
+			break;
+		case TYP_SYMLINK:
+			obfuscate_symlink_block(dp);
+			break;
+		case TYP_ATTR:
+			obfuscate_attr_block(dp, o);
+			break;
+		default:
+			break;
+		}
+		o++;
+		dp += mp->m_sb.sb_blocksize;
 	}
 	ret = write_buf(iocur_top);
 
@@ -1424,12 +1429,41 @@ process_multi_fsb_objects(
 	typnm_t		btype,
 	xfs_dfiloff_t	last)
 {
+	int		ret = 0;
+
 	if (btype != TYP_DIR2) {
 		print_warning("bad type for multi-fsb object %d", btype);
 		return -EINVAL;
 	}
 
-	return process_single_fsb_objects(o, s, c, btype, last);
+	push_cur();
+	set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, s), c * blkbb,
+			DB_RING_IGN, NULL);
+
+	if (!iocur_top->data) {
+		xfs_agnumber_t	agno = XFS_FSB_TO_AGNO(mp, s);
+		xfs_agblock_t	agbno = XFS_FSB_TO_AGBNO(mp, s);
+
+		print_warning("cannot read %s block %u/%u (%llu)",
+				typtab[btype].name, agno, agbno, s);
+		if (stop_on_read_error)
+			ret = -EIO;
+		goto out_pop;
+
+	}
+
+	if (dont_obfuscate || o >= mp->m_dirleafblk) {
+		ret = write_buf(iocur_top);
+		goto out_pop;
+	}
+
+	obfuscate_dir_data_blocks(iocur_top->data, o, c,
+				 last == mp->m_dirblkfsbs);
+	ret = write_buf(iocur_top);
+
+out_pop:
+	pop_cur();
+	return ret;
 }
 
 /* inode copy routines */
-- 
1.8.4.rc3

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2014-01-23 10:24 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-23 10:23 [PATCH 0/5] metadump: discontiguous directory block support Dave Chinner
2014-01-23 10:23 ` [PATCH 1/5] metadump: sanitise write_buf/index return values Dave Chinner
2014-02-03 11:08   ` Christoph Hellwig
2014-02-13 19:30   ` Mark Tinguely
2014-02-14  2:20     ` Dave Chinner
2014-02-14 19:51       ` Mark Tinguely
2014-02-14 20:54         ` Mark Tinguely
2014-01-23 10:23 ` [PATCH 2/5] metadump: support writing discontiguous io cursors Dave Chinner
2014-02-03 15:06   ` Christoph Hellwig
2014-01-23 10:23 ` [PATCH 3/5] metadump: separate single block objects from multiblock objects Dave Chinner
2014-02-03 15:09   ` Christoph Hellwig
2014-02-03 22:19     ` Dave Chinner
2014-01-23 10:23 ` Dave Chinner [this message]
2014-02-03 15:43   ` [PATCH 4/5] metadump: walk single fsb objects a block at a time Christoph Hellwig
2014-01-23 10:23 ` [PATCH 5/5] metadump: fully support discontiguous directory blocks Dave Chinner
2014-02-03 21:15   ` Christoph Hellwig
2014-02-03  3:19 ` [PATCH 0/5] metadump: discontiguous directory block support Dave Chinner

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=1390472635-17225-5-git-send-email-david@fromorbit.com \
    --to=david@fromorbit.com \
    --cc=xfs@oss.sgi.com \
    /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