#ifndef lint
static const char rcsid[] =
- "$Id: traverse.c,v 1.65 2005/01/25 13:33:44 stelian Exp $";
+ "$Id: traverse.c,v 1.67 2009/06/18 10:00:38 stelian Exp $";
#endif /* not lint */
#include <config.h>
static int searchdir __P((dump_ino_t ino, daddr_t blkno, long size, long filesize));
#endif
static void mapfileino __P((dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped));
+static void dump_xattr __P((dump_ino_t ino, struct dinode *dp));
#ifdef HAVE_EXT2_JOURNAL_INUM
#define ext2_journal_ino(sb) (sb->s_journal_inum)
struct block_context *p;
e2_blkcnt_t i;
- if (blockcnt < NDADDR)
- return 0;
p = (struct block_context *)private;
for (i = p->next_block; i < blockcnt; i++) {
p->buf[p->cnt++] = 0;
}
#endif
+static void
+dump_xattr(dump_ino_t ino, struct dinode *dp) {
+
+ if (dp->di_extraisize != 0) {
+#ifdef HAVE_EXT2FS_READ_INODE_FULL
+ char inode[EXT2_INODE_SIZE(fs->super)];
+ errcode_t err;
+ u_int32_t *magic;
+
+ memset(inode, 0, EXT2_INODE_SIZE(fs->super));
+ err = ext2fs_read_inode_full(fs, (ext2_ino_t)ino,
+ (struct ext2_inode *) inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (err) {
+ com_err(disk, err, "while reading inode #%ld\n", (long)ino);
+ exit(X_ABORT);
+ }
+
+ magic = (void *)inode + EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize;
+ if (*magic == EXT2_XATTR_MAGIC) {
+ char xattr[EXT2_INODE_SIZE(fs->super)];
+ int i;
+ char *cp;
+
+ if (vflag)
+ msg("dumping EA (inode) in inode #%ld\n", (long)ino);
+ memset(xattr, 0, EXT2_INODE_SIZE(fs->super));
+ memcpy(xattr, (void *)magic,
+ EXT2_INODE_SIZE(fs->super) -
+ (EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize));
+ magic = (u_int32_t *)xattr;
+ *magic = EXT2_XATTR_MAGIC2;
+
+ spcl.c_type = TS_INODE;
+ spcl.c_dinode.di_size = EXT2_INODE_SIZE(fs->super);
+ spcl.c_flags |= DR_EXTATTRIBUTES;
+ spcl.c_extattributes = EXT_XATTR;
+ spcl.c_count = howmany(EXT2_INODE_SIZE(fs->super), TP_BSIZE);
+ writeheader(ino);
+ for (i = 0, cp = xattr; i < spcl.c_count; i++, cp += TP_BSIZE)
+ writerec(cp, 0);
+ spcl.c_flags &= ~DR_EXTATTRIBUTES;
+ spcl.c_extattributes = 0;
+ }
+#endif
+ }
+
+ if (dp->di_file_acl) {
+
+ if (vflag)
+ msg("dumping EA (block) in inode #%ld\n", (long)ino);
+
+ spcl.c_type = TS_INODE;
+ spcl.c_dinode.di_size = sblock->fs_bsize;
+ spcl.c_flags |= DR_EXTATTRIBUTES;
+ spcl.c_extattributes = EXT_XATTR;
+ blksout(&dp->di_file_acl, EXT2_FRAGS_PER_BLOCK(fs->super), ino);
+ spcl.c_flags &= ~DR_EXTATTRIBUTES;
+ spcl.c_extattributes = 0;
+ }
+}
+
/*
* Dump passes 3 and 4.
*
nbi.di_gen = dp->di_gen;
nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid;
nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid;
- if (dp->di_file_acl)
- msg("ACLs in inode #%ld won't be dumped\n", (long)ino);
memmove(&spcl.c_dinode, &nbi, sizeof(nbi));
#else /* __linux__ */
spcl.c_dinode = *dp;
spcl.c_count = 0;
writeheader(ino);
spcl.c_flags &= ~DR_METAONLY;
+ dump_xattr(ino, dp);
return;
}
memmove(buf, dp->di_db, (u_long)dp->di_size);
buf[dp->di_size] = '\0';
writerec(buf, 0);
+ dump_xattr(ino, dp);
return;
}
#endif /* __linux__ */
case S_IFCHR:
case S_IFBLK:
writeheader(ino);
+ dump_xattr(ino, dp);
return;
default:
msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT);
return;
}
- if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize)
-#ifdef __linux__
- cnt = NDADDR * EXT2_FRAGS_PER_BLOCK(fs->super);
-#else
- cnt = NDADDR * sblock->fs_frag;
-#endif
- else
- cnt = howmany(i_size, sblock->fs_fsize);
- blksout(&dp->di_db[0], cnt, ino);
- if ((quad_t) (size = i_size - NDADDR * sblock->fs_bsize) <= 0)
- return;
#ifdef __linux__
bc.max = NINDIR(sblock) * EXT2_FRAGS_PER_BLOCK(fs->super);
bc.buf = (int *)malloc (bc.max * sizeof (int));
bc.ino = ino;
bc.next_block = NDADDR;
- ext2fs_block_iterate2(fs, (ext2_ino_t)ino, 0, NULL, dumponeblock, (void *)&bc);
+ ext2fs_block_iterate2(fs, (ext2_ino_t)ino, BLOCK_FLAG_DATA_ONLY, NULL, dumponeblock, (void *)&bc);
/* deal with holes at the end of the inode */
if (i_size > ((u_quad_t)bc.next_block) * sblock->fs_fsize) {
remaining = i_size - ((u_quad_t)bc.next_block) * sblock->fs_fsize;
blksout (bc.buf, bc.cnt, bc.ino);
}
free(bc.buf);
+ dump_xattr(ino, dp);
#else
+ if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize)
+ cnt = NDADDR * sblock->fs_frag;
+ else
+ cnt = howmany(i_size, sblock->fs_fsize);
+ blksout(&dp->di_db[0], cnt, ino);
+ if ((quad_t) (size = i_size - NDADDR * sblock->fs_bsize) <= 0) {
+ dump_xattr(ino, dp);
+ return;
+ }
for (ind_level = 0; ind_level < NIADDR; ind_level++) {
dmpindir(ino, dp->di_ib[ind_level], ind_level, &size);
if (size <= 0)
nbi.di_gen = dp->di_gen;
nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid;
nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid;
- if (dp->di_file_acl)
- msg("ACLs in inode #%ld won't be dumped\n", (long)ino);
memmove(&spcl.c_dinode, &nbi, sizeof(nbi));
#else /* __linux__ */
spcl.c_dinode = *dp;
}
(void)free(cdc.buf);
+ dump_xattr(ino, dp);
}
#endif /* __linux__ */
errcode_t err;
curino = inum;
+#ifdef HAVE_EXT2FS_READ_INODE_FULL
+ err = ext2fs_read_inode_full(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode, sizeof(struct dinode));
+#else
err = ext2fs_read_inode(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode);
+#endif
if (err) {
com_err(disk, err, "while reading inode #%ld\n", (long)inum);
exit(X_ABORT);