aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Kendall <wkendall@sgi.com>2012-03-02 08:36:27 +0000
committerChristoph Hellwig <hch@lst.de>2012-03-02 08:36:27 +0000
commit398a01bc7d53d0fca84638566df35656ae67e62e (patch)
tree98d381810fc39c57ebb254fa18e0a1b61610f74d
parent965b1657147cedab23b9fbee10209ae6eed485ea (diff)
downloadxfsdump-dev-398a01bc7d53d0fca84638566df35656ae67e62e.tar.gz
xfsdump: handle files with no extent headers
Normally the first file header for a given file in xfsdump is followed by one or more extent headers along with the file data. If there is a problem opening the file, the file header will not be dumped and the file will not be created during a restore. This is working as designed. However if the inode indicates the file has extended attributes, a file header will be dumped followed by an extended attribute header. Since this is the first file header xfsrestore sees for the file, it expects to see an extent header and bails out complaining about an extent header checksum error. This patch changes xfsrestore to look for the extended attribute flag on the file header even if it's the first file header seen for the file. The result is a zero-length file will be restored along with the extended attributes, if they were successfully backed up. More importantly, xfsrestore will continue on to restore the rest of the backup. This patch also changes xfsdump so that if it fails to open a file, it does not try to dump the extended attributes. This prevents xfsrestore from creating zero-length files in the situation described above. Signed-off-by: Bill Kendall <wkendall@sgi.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--dump/content.c13
-rw-r--r--restore/content.c29
2 files changed, 32 insertions, 10 deletions
diff --git a/dump/content.c b/dump/content.c
index 78b303f0..481297a4 100644
--- a/dump/content.c
+++ b/dump/content.c
@@ -270,7 +270,8 @@ static rv_t dump_file_reg( drive_t *drivep,
context_t *contextp,
content_inode_hdr_t *scwhdrp,
jdm_fshandle_t *,
- xfs_bstat_t * );
+ xfs_bstat_t *,
+ bool_t *);
static rv_t dump_file_spec( drive_t *drivep,
context_t *contextp,
jdm_fshandle_t *,
@@ -3698,6 +3699,7 @@ dump_file( void *arg1,
cwhdrp->ch_specific;
startpt_t *startptp = &scwhdrp->cih_startpt;
startpt_t *endptp = &scwhdrp->cih_endpt;
+ bool_t file_skipped = BOOL_FALSE;
intgen_t state;
rv_t rv;
@@ -3843,7 +3845,8 @@ dump_file( void *arg1,
contextp,
scwhdrp,
fshandlep,
- statp );
+ statp,
+ &file_skipped );
if ( statp->bs_ino > contextp->cc_stat_lastino ) {
lock( );
sc_stat_nondirdone++;
@@ -3891,6 +3894,8 @@ dump_file( void *arg1,
if ( rv == RV_OK
&&
+ file_skipped == BOOL_FALSE
+ &&
sc_dumpextattrpr
&&
( statp->bs_xflags & XFS_XFLAG_HASATTR )) {
@@ -3911,7 +3916,8 @@ dump_file_reg( drive_t *drivep,
context_t *contextp,
content_inode_hdr_t *scwhdrp,
jdm_fshandle_t *fshandlep,
- xfs_bstat_t *statp )
+ xfs_bstat_t *statp,
+ bool_t *file_skippedp )
{
startpt_t *startptp = &scwhdrp->cih_startpt;
startpt_t *endptp = &scwhdrp->cih_endpt;
@@ -4004,6 +4010,7 @@ dump_file_reg( drive_t *drivep,
statp->bs_ino,
statp->bs_mode,
strerror( errno ));
+ *file_skippedp = BOOL_TRUE;
return RV_OK;
}
diff --git a/restore/content.c b/restore/content.c
index 9aa85818..3110cdf7 100644
--- a/restore/content.c
+++ b/restore/content.c
@@ -768,6 +768,7 @@ static rv_t read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t fhcs );
static rv_t restore_file( drive_t *drivep,
filehdr_t *fhdrp,
bool_t ehcs,
+ bool_t ahcs,
char *path1,
char *path2 );
static bool_t restore_reg( drive_t *drivep,
@@ -3455,7 +3456,7 @@ applynondirdump( drive_t *drivep,
strctxp->sc_path[0] = '\0';
strctxp->sc_fd = -1;
- rv = restore_file( drivep, fhdrp, ehcs, path1, path2 );
+ rv = restore_file( drivep, fhdrp, ehcs, ahcs, path1, path2 );
} else if ( fhdrp->fh_flags & FILEHDR_FLAGS_EXTATTR ) {
rv = restore_extattr( drivep,
@@ -7183,6 +7184,7 @@ struct cb_context {
filehdr_t *cb_fhdrp;
rv_t cb_rv;
bool_t cb_ehcs;
+ bool_t cb_ahcs;
char *cb_path1;
char *cb_path2;
};
@@ -7195,6 +7197,7 @@ static rv_t
restore_file( drive_t *drivep,
filehdr_t *fhdrp,
bool_t ehcs,
+ bool_t ahcs,
char *path1,
char *path2 )
{
@@ -7210,6 +7213,7 @@ restore_file( drive_t *drivep,
context.cb_fhdrp = fhdrp;
context.cb_rv = RV_OK;
context.cb_ehcs = ehcs;
+ context.cb_ahcs = ahcs;
context.cb_path1 = path1;
context.cb_path2 = path2;
rv = tree_cb_links( bstatp->bs_ino,
@@ -7242,6 +7246,7 @@ restore_file_cb( void *cp, bool_t linkpr, char *path1, char *path2 )
bstat_t *bstatp = &fhdrp->fh_stat;
rv_t *rvp = &contextp->cb_rv;
bool_t ehcs = contextp->cb_ehcs;
+ bool_t ahcs = contextp->cb_ahcs;
stream_context_t *strctxp = (stream_context_t *)drivep->d_strmcontextp;
int rval;
@@ -7267,12 +7272,22 @@ restore_file_cb( void *cp, bool_t linkpr, char *path1, char *path2 )
ok = restore_reg( drivep, fhdrp, rvp, path1 );
if (!ok)
return ok;
- ok = restore_extent_group( drivep,
- fhdrp,
- path1,
- strctxp->sc_fd,
- ehcs,
- rvp );
+ if ( fhdrp->fh_flags & FILEHDR_FLAGS_EXTATTR ) {
+ *rvp = restore_extattr( drivep,
+ fhdrp,
+ path1,
+ ahcs,
+ BOOL_FALSE, /* isdirpr */
+ BOOL_FALSE, /* onlydoreadpr */
+ DAH_NULL );
+ } else {
+ ok = restore_extent_group( drivep,
+ fhdrp,
+ path1,
+ strctxp->sc_fd,
+ ehcs,
+ rvp );
+ }
return ok;
case S_IFBLK:
case S_IFCHR: