diff options
author | Bill Kendall <wkendall@sgi.com> | 2012-03-02 08:36:27 +0000 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2012-03-02 08:36:27 +0000 |
commit | 398a01bc7d53d0fca84638566df35656ae67e62e (patch) | |
tree | 98d381810fc39c57ebb254fa18e0a1b61610f74d | |
parent | 965b1657147cedab23b9fbee10209ae6eed485ea (diff) | |
download | xfsdump-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.c | 13 | ||||
-rw-r--r-- | restore/content.c | 29 |
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: |