xfsdump: save & restore 32-bit projids
PATCH 1/1 xfsdump: save & restore 32-bit projids
Current xfsdump/xfsrestore only recognize the lower 16 bits of the projid. With this patch, the full 32 bits are dumped & restored.
---
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
common/arch_xlate.c +2 -1
@@ -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);
common/content_inode.h +16 -2
@@ -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. */
common/global.c +1 -0
@@ -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 ;
common/global.h +4 -2
@@ -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
dump/content.c +2 -1
@@ -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; }
restore/content.c +2 -2
@@ -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 ) {
restore/dirattr.c +2 -2
@@ -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
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Eric Sandeen
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 <[email protected]>Cc Arkadiusz Miśkiewicz <[email protected]>Signed-off-by Eric Sandeen <[email protected]>---
This also adds a definition for
bs_forkoff, but I don't think that is something which should get saved & restored, correct?
Right - it's a kernel controlled field, only exported as a hint to help xfs_fsr build similarly formatted inodes.
Quoted 3 lines
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.
Looks ok, but I'm in the same boat as you on xfsdump. A QA test would be good to go along with this. ;)
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 1/1 xfstests: test dump/restore of 32-bit projids
In reply to Eric SandeenTest that xfsdump/xfsrestore properly restores more than the bottom 16 bits of a 32-bit projid.
---
285 new file +81 -0
@@ -0,0 +1,81 @@ +#! /bin/bash +# FS QA Test No. 285 +# +# Test projid32: persist 32 bit projids thorugh dump/restore +# +#----------------------------------------------------------------------- +# Copyright (c) 2012 Eric Sandeen. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# +# creator [email protected] + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.dump +. ./common.quota + +_require_scratch +_require_xfs_quota + +# real QA test starts here + +_supported_fs xfs +_supported_os IRIX Linux + +_scratch_mkfs_xfs -i projid32bit=1 >> $seq.full || _fail "mkfs failed" + +export MOUNT_OPTIONS="-opquota" +_qmount +_require_prjquota $SCRATCH_DEV + +# > 16 bit project ID +PROJID=2123456789 + +# Put a project quota on a dir +mkdir $SCRATCH_MNT/dir +xfs_quota -x -c "project -s -p $SCRATCH_MNT/dir $PROJID" $SCRATCH_MNT >> $seq.full || _fail "dir pquota failed" + +# Dump it then restore it to a fresh fs, and check the projid +rm -f $tmp.dumpfile +xfsdump -L label -M media -f $tmp.dumpfile $SCRATCH_MNT >> $seq.full || _fail "dump failed" +umount $SCRATCH_DEV + +_scratch_mkfs_xfs -i projid32bit=1 >> $seq.full || _fail "re-mkfs failed" +_qmount +xfsrestore -f $tmp.dumpfile $SCRATCH_MNT >> $seq.full || _fail "restore failed" + +# check (-c) that we got the correct project ID back post-restore +xfs_quota -x -c "project -s -c -p $SCRATCH_MNT/dir $PROJID" $SCRATCH_MNT + +# success, all done +status=0 +exit
285.out new file +3 -0
@@ -0,0 +1,3 @@ +QA output created by 285 +Checking project 2123456790 (path /mnt/scratch/dir)... +Processed 1 (/etc/projects and cmdline) paths for project 2123456790 with recursion depth infinite (-1).
group +1 -0
@@ -403,3 +403,4 @@ deprecated 282 dump ioctl auto quick 283 dump ioctl auto quick 284 auto +285 auto dump quota
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Hey Eric,
Quoted 6 lines · Eric Sandeen
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 <[email protected]>Cc Arkadiusz Miśkiewicz <[email protected]>Signed-off-by Eric Sandeen <[email protected]>
Quoted 8 lines
---
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.
I have two versioned dump files ~/dump-v3 and ~/dump-v4. v3 is prior to your patch and v4 was with this patch.
Here is a version 3 xfsrestore of a version 4 dump:
~/xfsdump # xfsrestore -f ~/dump-v4 /mnt/scratch
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.0 (dump format 3.0) - type ^C for status and control
^^^^^^^^^^^^^^^ version 3
xfsrestore: searching media for dump
xfsrestore: ERROR: unrecognized media file header version (4)
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /root/dump-v4 OK (success)
xfsrestore: Restore Status: SUCCESS <---- FAIL?
We should consider whether failure is the correct thing to do when trying to restore from an incompatible dump file. That is not a problem with this patch.
Now a version 4 xfsrestore with a version 3 dump:
~/xfsdump # xfsrestore -f ~/dump-v3 /mnt/scratch
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.0 (dump format 4.0) - type ^C for status and control
^^^^^^^^^^^^^^^ version 4, looks good
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: foo
xfsrestore: mount point: /mnt/scratch
xfsrestore: volume: /dev/sdb1
xfsrestore: session time: Tue Sep 18 14:45:36 2012
xfsrestore: level: 0
xfsrestore: session label: "k"
xfsrestore: media label: "k"
xfsrestore: file system id: 983f85f2-9a11-460d-a276-9aec42fbd8f7
xfsrestore: session id: 4fbfbd3d-6f4a-4ad5-909b-bdf4742e849d
xfsrestore: media id: 41f8e77c-7b93-49c5-a9ed-c66a391778e7
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 4 directories and 9 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /root/dump-v3 OK (success)
xfsrestore: Restore Status: SUCCESS
So the behavior with respect to versioning is: You can restore from dumps that have a smaller or equal dump version than your xfsrestore, but not from dumps with versions greater than your xfsrestore. Now I'd like to see the behavior with some project ids set and a version 3 dump with version 4 xfsrestore.
A version 4 xfsrestore with a version 3 dump:
~/xfsdump # xfsrestore -f ~/dump-v3-3 /mnt/scratch/restore/
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.0 (dump format 4.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: foo
xfsrestore: mount point: /mnt/scratch
xfsrestore: volume: /dev/sdb1
xfsrestore: session time: Tue Sep 18 15:18:16 2012
xfsrestore: level: 0
xfsrestore: session label: "l"
xfsrestore: media label: "l"
xfsrestore: file system id: 983f85f2-9a11-460d-a276-9aec42fbd8f7
xfsrestore: session id: 9ad2909c-3542-428b-9f73-0bf207b77888
xfsrestore: media id: 529e47bc-b6fa-427c-a0f5-dcd4c9707adc
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 4 directories and 8 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: project quota information written to '/mnt/scratch/restore//xfsdump_quotas_proj'
xfsrestore: use 'xfs_quota' to restore quotas
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /root/dump-v3-3 OK (success)
xfsrestore: Restore Status: SUCCESS
And a version 4 xfsrestore with a version 4 dump:
~/xfsdump # xfsrestore -f ~/dump-v4-3 /mnt/scratch/restore2
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.0 (dump format 4.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: foo
xfsrestore: mount point: /mnt/scratch
xfsrestore: volume: /dev/sdb1
xfsrestore: session time: Tue Sep 18 15:20:18 2012
xfsrestore: level: 0
xfsrestore: session label: "l"
xfsrestore: media label: "l"
xfsrestore: file system id: 983f85f2-9a11-460d-a276-9aec42fbd8f7
xfsrestore: session id: e5d07daf-3bfc-4ab8-b13c-ad48db813807
xfsrestore: media id: 9d043994-9abb-4fd0-8cc9-eda68c62641c
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 4 directories and 8 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: project quota information written to '/mnt/scratch/restore2/xfsdump_quotas_proj'
xfsrestore: use 'xfs_quota' to restore quotas
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /root/dump-v4-3 OK (success)
xfsrestore: Restore Status: SUCCESS
Here are the files with project quotas:
originals:
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/dumpme/16bit projid = 1234
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/dumpme/32bit projid = 2123456789
from the v3 dump:
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/restore/dumpme/16bit projid = 1234
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/restore/dumpme/32bit
projid = 24853 <--- note that it is munged just as in test 287
from the v4 dump:
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/restore2/dumpme/16bit projid = 1234
~/xfsdump # xfs_io -r -c "lsproj" /mnt/scratch/restore2/dumpme/32bit projid = 2123456789
The code looks good, the xfstest 287 looks good, and the above shows that we have the desired behavior with respect to dump versioning.
Committed to git://oss.sgi.com/xfs/cmds/xfsdump.git, master branch.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs