}
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
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)) {
+ 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;
+ }
+
+ 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));
}
}
}
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,
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);
typnm_t btype,
xfs_dfiloff_t last)
{
+ int ret = 0;
+
switch (btype) {
case TYP_DIR2:
break;
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 */