xfs
[Top] [All Lists]

[PATCH] xfsdump: save & restore 32-bit projids

To: xfs-oss <xfs@xxxxxxxxxxx>
Subject: [PATCH] xfsdump: save & restore 32-bit projids
From: Eric Sandeen <sandeen@xxxxxxxxxx>
Date: Sun, 26 Aug 2012 19:20:07 -0500
Cc: Boris Ranto <branto@xxxxxxxxxx>, Arkadiusz Miśkiewicz <arekm@xxxxxxxx>, Bill Kendall <wkendall@xxxxxxx>
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:14.0) Gecko/20120713 Thunderbird/14.0
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;


<Prev in Thread] Current Thread [Next in Thread>