free(orig_name);
}
+static inline bool
+is_metadir_ino(
+ struct xfs_dinode *dip)
+{
+ if (!xfs_has_metadir(mp) || dip->di_version < 3)
+ return false;
+ return dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADIR);
+}
+
static inline bool
want_obfuscate_dirents(bool is_meta)
{
static void
process_sf_dir(
- struct xfs_dinode *dip,
- bool is_meta)
+ struct xfs_dinode *dip)
{
+ bool is_meta = is_metadir_ino(dip);
struct xfs_dir2_sf_hdr *sfp;
xfs_dir2_sf_entry_t *sfep;
uint64_t ino_dir_size;
return true;
}
+/*
+ * Obfuscate the attr names and fill the actual values with 'v' (to see a valid
+ * string length, as opposed to NULLs).
+ */
static void
process_sf_attr(
- struct xfs_dinode *dip,
- bool is_meta)
+ struct xfs_dinode *dip)
{
- /*
- * with extended attributes, obfuscate the names and fill the actual
- * values with 'v' (to see a valid string length, as opposed to NULLs)
- */
-
+ bool is_meta = is_metadir_ino(dip);
struct xfs_attr_sf_hdr *hdr = XFS_DFORK_APTR(dip);
struct xfs_attr_sf_entry *asfep = libxfs_attr_sf_firstentry(hdr);
int ino_attr_size;
return rval;
}
+static typnm_t
+ifork_data_type(
+ struct xfs_dinode *dip,
+ int whichfork)
+{
+ xfs_ino_t ino = be64_to_cpu(dip->di_ino);
+
+ if (whichfork == XFS_ATTR_FORK)
+ return TYP_ATTR;
+
+ switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
+ case S_IFDIR:
+ return TYP_DIR2;
+ case S_IFLNK:
+ return TYP_SYMLINK;
+ case S_IFREG:
+ if (ino == mp->m_sb.sb_rbmino)
+ return TYP_RTBITMAP;
+ if (ino == mp->m_sb.sb_rsumino)
+ return TYP_RTSUMMARY;
+ if (ino == mp->m_sb.sb_uquotino)
+ return TYP_DQBLK;
+ if (ino == mp->m_sb.sb_gquotino)
+ return TYP_DQBLK;
+ if (ino == mp->m_sb.sb_pquotino)
+ return TYP_DQBLK;
+ return TYP_DATA;
+ default:
+ return TYP_NONE;
+ }
+}
+
static bool
is_multi_fsb_object(
struct xfs_mount *mp,
/* inode copy routines */
static int
process_bmbt_reclist(
- xfs_bmbt_rec_t *rp,
- int numrecs,
- typnm_t btype,
- bool is_meta)
+ struct xfs_dinode *dip,
+ int whichfork,
+ struct xfs_bmbt_rec *rp,
+ int numrecs)
{
+ bool is_meta = is_metadir_ino(dip);
+ typnm_t btype = ifork_data_type(dip, whichfork);
int i;
xfs_fileoff_t o, op = NULLFILEOFF;
xfs_fsblock_t s;
xfs_fileoff_t last;
xfs_agnumber_t agno;
xfs_agblock_t agbno;
- bool is_multi_fsb = is_multi_fsb_object(mp, btype);
int rval = 1;
if (btype == TYP_DATA)
}
/* multi-extent blocks require special handling */
- if (is_multi_fsb)
+ if (is_multi_fsb_object(mp, btype))
rval = process_multi_fsb_objects(o, s, c, btype,
last, is_meta);
else
}
struct scan_bmap {
- enum typnm typ;
- bool is_meta;
+ struct xfs_dinode *dip;
+ int whichfork;
};
static int
xfs_agblock_t agbno,
int level,
typnm_t btype,
- void *arg) /* ptr to itype */
+ void *arg)
{
struct scan_bmap *sbm = arg;
int i;
typtab[btype].name, agno, agbno);
return 1;
}
- return process_bmbt_reclist(xfs_bmbt_rec_addr(mp, block, 1),
- nrecs, sbm->typ, sbm->is_meta);
+ return process_bmbt_reclist(sbm->dip, sbm->whichfork,
+ xfs_bmbt_rec_addr(mp, block, 1), nrecs);
}
if (nrecs > mp->m_bmap_dmxr[1]) {
return 1;
}
-static inline bool
-is_metadata_ino(
- struct xfs_dinode *dip)
-{
- return xfs_has_metadir(mp) &&
- dip->di_version >= 3 &&
- (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADIR));
-}
-
static int
process_btinode(
struct xfs_dinode *dip,
- typnm_t itype)
+ int whichfork)
{
- xfs_bmdr_block_t *dib;
- int i;
- xfs_bmbt_ptr_t *pp;
- int level;
- int nrecs;
+ struct xfs_bmdr_block *dib =
+ (struct xfs_bmdr_block *)XFS_DFORK_PTR(dip, whichfork);
+ int level = be16_to_cpu(dib->bb_level);
+ int nrecs = be16_to_cpu(dib->bb_numrecs);
int maxrecs;
- int whichfork;
- typnm_t btype;
- bool is_meta = is_metadata_ino(dip);
-
- whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
- btype = (itype == TYP_ATTR) ? TYP_BMAPBTA : TYP_BMAPBTD;
-
- dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
- level = be16_to_cpu(dib->bb_level);
- nrecs = be16_to_cpu(dib->bb_numrecs);
+ typnm_t btype = (whichfork == XFS_ATTR_FORK) ?
+ TYP_BMAPBTA : TYP_BMAPBTD;
+ xfs_bmbt_ptr_t *pp;
+ int i;
if (level > XFS_BM_MAXLEVELS(mp, whichfork)) {
if (metadump.show_warnings)
}
if (level == 0) {
- return process_bmbt_reclist(xfs_bmdr_rec_addr(dib, 1),
- nrecs, itype, is_meta);
+ return process_bmbt_reclist(dip, whichfork,
+ xfs_bmdr_rec_addr(dib, 1),
+ nrecs);
}
maxrecs = libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0);
for (i = 0; i < nrecs; i++) {
struct scan_bmap sbm = {
- .typ = itype,
- .is_meta = is_meta,
+ .dip = dip,
+ .whichfork = whichfork,
};
xfs_agnumber_t ag;
xfs_agblock_t bno;
static int
process_exinode(
struct xfs_dinode *dip,
- typnm_t itype)
+ int whichfork)
{
- int whichfork;
- int used;
- xfs_extnum_t nex, max_nex;
- bool is_meta = is_metadata_ino(dip);
-
- whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
+ xfs_extnum_t max_nex = xfs_iext_max_nextents(
+ xfs_dinode_has_large_extent_counts(dip), whichfork);
+ xfs_extnum_t nex = xfs_dfork_nextents(dip, whichfork);
+ int used = nex * sizeof(struct xfs_bmbt_rec);
- nex = xfs_dfork_nextents(dip, whichfork);
- max_nex = xfs_iext_max_nextents(
- xfs_dinode_has_large_extent_counts(dip),
- whichfork);
- used = nex * sizeof(xfs_bmbt_rec_t);
if (nex > max_nex || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
if (metadump.show_warnings)
print_warning("bad number of extents %llu in inode %lld",
XFS_DFORK_SIZE(dip, mp, whichfork) - used);
- return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip,
- whichfork), nex, itype, is_meta);
+ return process_bmbt_reclist(dip, whichfork,
+ (struct xfs_bmbt_rec *)XFS_DFORK_PTR(dip, whichfork),
+ nex);
}
static int
process_rtrmap(
- struct xfs_dinode *dip,
- typnm_t itype)
+ struct xfs_dinode *dip)
{
- struct xfs_rtrmap_root *dib;
- int i;
- xfs_rtrmap_ptr_t *pp;
- int level;
- int nrecs;
+ int whichfork = XFS_DATA_FORK;
+ struct xfs_rtrmap_root *dib =
+ (struct xfs_rtrmap_root *)XFS_DFORK_PTR(dip, whichfork);
+ int level = be16_to_cpu(dib->bb_level);
+ int nrecs = be16_to_cpu(dib->bb_numrecs);
+ typnm_t btype = TYP_RTRMAPBT;
int maxrecs;
- int whichfork;
- typnm_t btype;
-
- if (itype == TYP_ATTR && metadump.show_warnings) {
- print_warning("ignoring rtrmapbt root in inode %llu attr fork",
- (unsigned long long)metadump.cur_ino);
- return 1;
- }
-
- whichfork = XFS_DATA_FORK;
- btype = TYP_RTRMAPBT;
-
- dib = (struct xfs_rtrmap_root *)XFS_DFORK_PTR(dip, whichfork);
- level = be16_to_cpu(dib->bb_level);
- nrecs = be16_to_cpu(dib->bb_numrecs);
+ xfs_rtrmap_ptr_t *pp;
+ int i;
if (level > mp->m_rtrmap_maxlevels) {
if (metadump.show_warnings)
continue;
}
- if (!scan_btree(ag, bno, level, btype, &itype,
- scanfunc_rtrmapbt))
+ if (!scan_btree(ag, bno, level, btype, NULL, scanfunc_rtrmapbt))
return 0;
}
return 1;
static int
process_rtrefc(
- struct xfs_dinode *dip,
- typnm_t itype)
+ struct xfs_dinode *dip)
{
- struct xfs_rtrefcount_root *dib;
- int i;
- xfs_rtrefcount_ptr_t *pp;
- int level;
- int nrecs;
+ int whichfork = XFS_DATA_FORK;
+ struct xfs_rtrefcount_root *dib =
+ (struct xfs_rtrefcount_root *)XFS_DFORK_PTR(dip, whichfork);
+ int level = be16_to_cpu(dib->bb_level);
+ int nrecs = be16_to_cpu(dib->bb_numrecs);
+ typnm_t btype = TYP_RTREFCBT;
int maxrecs;
- int whichfork;
- typnm_t btype;
-
- if (itype == TYP_ATTR && metadump.show_warnings) {
- print_warning("ignoring rtrefcbt root in inode %llu attr fork",
- (unsigned long long)metadump.cur_ino);
- return 1;
- }
-
- whichfork = XFS_DATA_FORK;
- btype = TYP_RTREFCBT;
-
- dib = (struct xfs_rtrefcount_root *)XFS_DFORK_PTR(dip, whichfork);
- level = be16_to_cpu(dib->bb_level);
- nrecs = be16_to_cpu(dib->bb_numrecs);
+ xfs_rtrefcount_ptr_t *pp;
+ int i;
if (level > mp->m_rtrefc_maxlevels) {
if (metadump.show_warnings)
continue;
}
- if (!scan_btree(ag, bno, level, btype, &itype,
- scanfunc_rtrefcbt))
+ if (!scan_btree(ag, bno, level, btype, NULL, scanfunc_rtrefcbt))
return 0;
}
return 1;
static int
process_inode_data(
- struct xfs_dinode *dip,
- typnm_t itype)
+ struct xfs_dinode *dip)
{
- bool is_meta = is_metadata_ino(dip);
-
switch (dip->di_format) {
- case XFS_DINODE_FMT_LOCAL:
- if (!(metadump.obfuscate || metadump.zero_stale_data))
- break;
+ case XFS_DINODE_FMT_LOCAL:
+ if (!(metadump.obfuscate || metadump.zero_stale_data))
+ break;
- /*
- * If the fork size is invalid, we can't safely do
- * anything with this fork. Leave it alone to preserve
- * the information for diagnostic purposes.
- */
- if (XFS_DFORK_DSIZE(dip, mp) > XFS_LITINO(mp)) {
- print_warning(
+ /*
+ * If the fork size is invalid, we can't safely do
+ * anything with this fork. Leave it alone to preserve
+ * the information for diagnostic purposes.
+ */
+ if (XFS_DFORK_DSIZE(dip, mp) > XFS_LITINO(mp)) {
+ print_warning(
"Invalid data fork size (%d) in inode %llu, preserving contents!",
- XFS_DFORK_DSIZE(dip, mp),
- (long long)metadump.cur_ino);
- break;
- }
-
- switch (itype) {
- case TYP_DIR2:
- process_sf_dir(dip, is_meta);
- break;
-
- case TYP_SYMLINK:
- process_sf_symlink(dip);
- break;
-
- default:
- break;
- }
+ XFS_DFORK_DSIZE(dip, mp),
+ (long long)metadump.cur_ino);
break;
+ }
- case XFS_DINODE_FMT_EXTENTS:
- return process_exinode(dip, itype);
-
- case XFS_DINODE_FMT_BTREE:
- return process_btinode(dip, itype);
-
- case XFS_DINODE_FMT_RMAP:
- return process_rtrmap(dip, itype);
-
- case XFS_DINODE_FMT_REFCOUNT:
- return process_rtrefc(dip, itype);
+ switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
+ case S_IFDIR:
+ process_sf_dir(dip);
+ break;
+ case S_IFLNK:
+ process_sf_symlink(dip);
+ break;
+ default:
+ break;
+ }
+ break;
+ case XFS_DINODE_FMT_EXTENTS:
+ return process_exinode(dip, XFS_DATA_FORK);
+ case XFS_DINODE_FMT_BTREE:
+ return process_btinode(dip, XFS_DATA_FORK);
+ case XFS_DINODE_FMT_RMAP:
+ return process_rtrmap(dip);
+ case XFS_DINODE_FMT_REFCOUNT:
+ return process_rtrefc(dip);
}
return 1;
}
/* copy appropriate data fork metadata */
switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
- case S_IFDIR:
- rval = process_inode_data(dip, TYP_DIR2);
- if (dip->di_format == XFS_DINODE_FMT_LOCAL)
- need_new_crc = true;
- break;
- case S_IFLNK:
- rval = process_inode_data(dip, TYP_SYMLINK);
- if (dip->di_format == XFS_DINODE_FMT_LOCAL)
- need_new_crc = true;
- break;
- case S_IFREG:
- rval = process_inode_data(dip, TYP_DATA);
- break;
- case S_IFIFO:
- case S_IFCHR:
- case S_IFBLK:
- case S_IFSOCK:
- process_dev_inode(dip);
+ case S_IFDIR:
+ case S_IFLNK:
+ case S_IFREG:
+ rval = process_inode_data(dip);
+ if (dip->di_format == XFS_DINODE_FMT_LOCAL)
need_new_crc = true;
- break;
- default:
- break;
+ break;
+ case S_IFIFO:
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFSOCK:
+ process_dev_inode(dip);
+ need_new_crc = true;
+ break;
+ default:
+ break;
}
nametable_clear();
if (!rval)
/* copy extended attributes if they exist and forkoff is valid */
if (XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) {
- bool is_meta = is_metadata_ino(dip);
-
attr_data.remote_val_count = 0;
switch (dip->di_aformat) {
- case XFS_DINODE_FMT_LOCAL:
- need_new_crc = true;
- if (metadump.obfuscate ||
- metadump.zero_stale_data)
- process_sf_attr(dip, is_meta);
- break;
-
- case XFS_DINODE_FMT_EXTENTS:
- rval = process_exinode(dip, TYP_ATTR);
- break;
-
- case XFS_DINODE_FMT_BTREE:
- rval = process_btinode(dip, TYP_ATTR);
- break;
+ case XFS_DINODE_FMT_LOCAL:
+ need_new_crc = true;
+ if (metadump.obfuscate ||
+ metadump.zero_stale_data)
+ process_sf_attr(dip);
+ break;
+ case XFS_DINODE_FMT_EXTENTS:
+ rval = process_exinode(dip, XFS_ATTR_FORK);
+ break;
+ case XFS_DINODE_FMT_BTREE:
+ rval = process_btinode(dip, XFS_ATTR_FORK);
+ break;
}
nametable_clear();
}
return rval;
}
-static int
-copy_ino(
- xfs_ino_t ino,
- typnm_t itype)
-{
- xfs_agnumber_t agno;
- xfs_agblock_t agbno;
- xfs_agino_t agino;
- int offset;
- int rval = 1;
-
- if (ino == 0 || ino == NULLFSINO)
- return 1;
-
- agno = XFS_INO_TO_AGNO(mp, ino);
- agino = XFS_INO_TO_AGINO(mp, ino);
- agbno = XFS_AGINO_TO_AGBNO(mp, agino);
- offset = XFS_AGINO_TO_OFFSET(mp, agino);
-
- if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
- offset >= mp->m_sb.sb_inopblock) {
- if (metadump.show_warnings)
- print_warning("invalid %s inode number (%lld)",
- typtab[itype].name, (long long)ino);
- return 1;
- }
-
- push_cur();
- set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno),
- blkbb, DB_RING_IGN, NULL);
- if (iocur_top->data == NULL) {
- print_warning("cannot read %s inode %lld",
- typtab[itype].name, (long long)ino);
- rval = !metadump.stop_on_read_error;
- goto pop_out;
- }
- off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
-
- metadump.cur_ino = ino;
- rval = process_inode_data(iocur_top->data, itype);
-pop_out:
- pop_cur();
- return rval;
-}
-
-
-static int
-copy_sb_inodes(void)
-{
- if (!copy_ino(mp->m_sb.sb_rbmino, TYP_RTBITMAP))
- return 0;
-
- if (!copy_ino(mp->m_sb.sb_rsumino, TYP_RTSUMMARY))
- return 0;
-
- if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK))
- return 0;
-
- if (!copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK))
- return 0;
-
- return copy_ino(mp->m_sb.sb_pquotino, TYP_DQBLK);
-}
-
static int
copy_log(void)
{
}
}
- /* copy realtime and quota inode contents */
- if (!exitcode)
- exitcode = !copy_sb_inodes();
-
/* copy log */
if (!exitcode && !(metadump.version == 1 && metadump.external_log))
exitcode = !copy_log();