Current xfsdump/xfsrestore only recognize the lower 16 bits of the projid. With this patch, the full 32 bits are dumped & restored. Reported-by: Boris Ranto <branto@xxxxxxxxxx> Cc: Arkadiusz Miśkiewicz <arekm@xxxxxxxx> Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx> --- This also adds a definition for bs_forkoff, but I don't think that is something which should get saved & restored, correct? TBH I've done very little hacking on xfsdump. I think this requires a new version, but not sure. This seems to work but may need sanity checks & fixups. And, of course, an xfstest. Thanks, -Eric diff --git a/common/arch_xlate.c b/common/arch_xlate.c index c156313..e42abd5 100644 --- a/common/arch_xlate.c +++ b/common/arch_xlate.c @@ -376,7 +376,8 @@ xlate_bstat(bstat_t *bs1, bstat_t *bs2, int dir) IXLATE(bs1, bs2, bs_extsize); IXLATE(bs1, bs2, bs_extents); IXLATE(bs1, bs2, bs_gen); - IXLATE(bs1, bs2, bs_projid); + IXLATE(bs1, bs2, bs_projid_lo); + IXLATE(bs1, bs2, bs_projid_hi); IXLATE(bs1, bs2, bs_dmevmask); IXLATE(bs1, bs2, bs_dmstate); diff --git a/common/content_inode.h b/common/content_inode.h index a25b66e..8f0390c 100644 --- a/common/content_inode.h +++ b/common/content_inode.h @@ -173,8 +173,10 @@ struct bstat { /* bytes accum */ int32_t bs_extsize; /* extent size 4 50 */ int32_t bs_extents; /* number of extents 4 54 */ u_int32_t bs_gen; /* generation count 4 58 */ - u_int16_t bs_projid; /* project id 2 5a */ - char bs_pad[ 14 ]; /* for expansion e 68 */ + u_int16_t bs_projid_lo; /* low 16 of project id 2 5a */ + u_int16_t bs_forkoff; /* inode fork offset 2 5c */ + u_int16_t bs_projid_hi; /* hi 16 of project id 2 5e */ + char bs_pad[ 10 ]; /* for expansion e 68 */ u_int32_t bs_dmevmask; /* DMI event mask 4 6c */ u_int16_t bs_dmstate; /* DMI state info 2 6e */ char bs_pad1[ 18 ]; /* for expansion 12 80 */ @@ -184,6 +186,18 @@ struct bstat { /* bytes accum */ typedef struct bstat bstat_t; +/* + * Project quota id helpers (previously projid was 16bit only + * and using two 16bit values to hold new 32bit projid was choosen + * to retain compatibility with "old" filesystems). + */ +static inline __uint32_t +bstat_projid(struct bstat *bs) +{ + return (__uint32_t)bs->bs_projid_hi << 16 | bs->bs_projid_lo; +} + + /* extended inode flags that can only be set after all data * has been restored to a file. */ diff --git a/common/global.c b/common/global.c index 8e49d8b..1793ff4 100644 --- a/common/global.c +++ b/common/global.c @@ -281,6 +281,7 @@ global_version_check( u_int32_t version ) case GLOBAL_HDR_VERSION_1: case GLOBAL_HDR_VERSION_2: case GLOBAL_HDR_VERSION_3: + case GLOBAL_HDR_VERSION_4: return BOOL_TRUE; default: return BOOL_FALSE; diff --git a/common/global.h b/common/global.h index 6556a68..5138ed8 100644 --- a/common/global.h +++ b/common/global.h @@ -28,13 +28,15 @@ #define GLOBAL_HDR_VERSION_1 1 #define GLOBAL_HDR_VERSION_2 2 #define GLOBAL_HDR_VERSION_3 3 - /* version 3 uses the full 32-bit inode generation number in direnthdr_t. +#define GLOBAL_HDR_VERSION_4 4 + /* version 4 adds 32-bit projid (projid_hi) + * version 3 uses the full 32-bit inode generation number in direnthdr_t. * version 2 adds encoding of holes and a change to on-tape inventory format. * version 1 adds extended file attribute dumping. * version 0 xfsrestore can't handle media produced * by version 1 xfsdump. */ -#define GLOBAL_HDR_VERSION GLOBAL_HDR_VERSION_3 +#define GLOBAL_HDR_VERSION GLOBAL_HDR_VERSION_4 #define GLOBAL_HDR_STRING_SZ 0x100 #define GLOBAL_HDR_TIME_SZ 4 diff --git a/dump/content.c b/dump/content.c index 481297a..ec5e954 100644 --- a/dump/content.c +++ b/dump/content.c @@ -4927,7 +4927,8 @@ copy_xfs_bstat(bstat_t *dst, xfs_bstat_t *src) dst->bs_extsize = src->bs_extsize; dst->bs_extents = src->bs_extents; dst->bs_gen = src->bs_gen; - dst->bs_projid = src->bs_projid; + dst->bs_projid_lo = src->bs_projid_lo; + dst->bs_projid_hi = src->bs_projid_hi; dst->bs_dmevmask = src->bs_dmevmask; dst->bs_dmstate = src->bs_dmstate; } diff --git a/restore/content.c b/restore/content.c index 3110cdf..edd00ed 100644 --- a/restore/content.c +++ b/restore/content.c @@ -7451,7 +7451,7 @@ restore_reg( drive_t *drivep, memset((void *)&fsxattr, 0, sizeof( fsxattr )); fsxattr.fsx_xflags = bstatp->bs_xflags & ~POST_DATA_XFLAGS; fsxattr.fsx_extsize = (u_int32_t) bstatp->bs_extsize; - fsxattr.fsx_projid = bstatp->bs_projid; + fsxattr.fsx_projid = bstat_projid(bstatp); rval = ioctl( *fdp, XFS_IOC_FSSETXATTR, (void *)&fsxattr); if ( rval < 0 ) { @@ -7702,7 +7702,7 @@ restore_complete_reg(stream_context_t *strcxtp) memset((void *)&fsxattr, 0, sizeof( fsxattr )); fsxattr.fsx_xflags = bstatp->bs_xflags; fsxattr.fsx_extsize = (u_int32_t)bstatp->bs_extsize; - fsxattr.fsx_projid = bstatp->bs_projid; + fsxattr.fsx_projid = bstat_projid(bstatp); rval = ioctl( fd, XFS_IOC_FSSETXATTR, (void *)&fsxattr ); if ( rval < 0 ) { diff --git a/restore/dirattr.c b/restore/dirattr.c index 68d1b49..8a1fb06 100644 --- a/restore/dirattr.c +++ b/restore/dirattr.c @@ -434,7 +434,7 @@ dirattr_add( filehdr_t *fhdrp ) dirattr.d_ctime = ( time32_t )fhdrp->fh_stat.bs_ctime.tv_sec; dirattr.d_xflags = fhdrp->fh_stat.bs_xflags; dirattr.d_extsize = ( u_int32_t )fhdrp->fh_stat.bs_extsize; - dirattr.d_projid = fhdrp->fh_stat.bs_projid; + dirattr.d_projid = bstat_projid(&(fhdrp->fh_stat)); dirattr.d_dmevmask = fhdrp->fh_stat.bs_dmevmask; dirattr.d_dmstate = ( u_int32_t )fhdrp->fh_stat.bs_dmstate; #ifdef DIRATTRCHK @@ -812,7 +812,7 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) dirattr.d_ctime = ( time32_t )fhdrp->fh_stat.bs_ctime.tv_sec; dirattr.d_xflags = fhdrp->fh_stat.bs_xflags; dirattr.d_extsize = ( u_int32_t )fhdrp->fh_stat.bs_extsize; - dirattr.d_projid = fhdrp->fh_stat.bs_projid; + dirattr.d_projid = bstat_projid(&(fhdrp->fh_stat)); dirattr.d_dmevmask = fhdrp->fh_stat.bs_dmevmask; dirattr.d_dmstate = ( u_int32_t )fhdrp->fh_stat.bs_dmstate; dirattr.d_extattroff = DIRATTR_EXTATTROFFNULL; _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs