[PATCH] xfsprogs: projid32bit handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add projid32bit handling to userspace. Userspace xfs_get/set_projid
helpers operate on struct xfs_icdinode instead of struct xfs_inode as it
fits better for userspace.

Signed-off-by: Arkadiusz Miśkiewicz <arekm@xxxxxxxx>
---
 db/check.c               |    2 +-
 db/inode.c               |    6 ++++--
 db/sb.c                  |    6 ++++++
 include/xfs_dinode.h     |    5 +++--
 include/xfs_fs.h         |    5 +++--
 include/xfs_inode.h      |   23 ++++++++++++++++++++---
 include/xfs_sb.h         |   16 +++++++++++++++-
 include/xfs_types.h      |    2 --
 libxfs/util.c            |   13 ++++++++-----
 libxfs/xfs_ialloc.c      |    3 ++-
 libxfs/xfs_inode.c       |    6 ++++--
 logprint/log_print_all.c |    6 ++++--
 man/man3/xfsctl.3        |    6 ++++--
 man/man8/xfs_db.8        |    6 ++++--
 mkfs/xfs_mkfs.c          |   18 +++++++++++++++---
 mkfs/xfs_mkfs.h          |    3 ++-
 quota/quot.c             |    3 ++-
 repair/README            |    2 +-
 18 files changed, 98 insertions(+), 33 deletions(-)

diff --git a/db/check.c b/db/check.c
index 4f8a62a..a8939a4 100644
--- a/db/check.c
+++ b/db/check.c
@@ -2840,7 +2840,7 @@ process_inode(
 			break;
 		}
 		if (ic) {
-			dqprid = idic.di_projid;	/* dquot ID is u32 */
+			dqprid = xfs_get_projid(idic);	/* dquot ID is u32 */
 			quota_add(&dqprid, &idic.di_gid, &idic.di_uid,
 				  0, bc, ic, rc);
 		}
diff --git a/db/inode.c b/db/inode.c
index 4aa4e1a..6f8592a 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -81,8 +81,10 @@ const field_t	inode_core_flds[] = {
 	  FLD_COUNT, TYP_NONE },
 	{ "onlink", FLDT_UINT16D, OI(COFF(onlink)), inode_core_onlink_count,
 	  FLD_COUNT, TYP_NONE },
-	{ "projid", FLDT_UINT16D, OI(COFF(projid)), inode_core_projid_count,
-	  FLD_COUNT, TYP_NONE },
+	{ "projid_lo", FLDT_UINT16D, OI(COFF(projid_lo)),
+	  inode_core_projid_count, FLD_COUNT, TYP_NONE },
+	{ "projid_hi", FLDT_UINT16D, OI(COFF(projid_hi)),
+	  inode_core_projid_count, FLD_COUNT, TYP_NONE },
 	{ "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
 	{ "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
 	{ "flushiter", FLDT_UINT16D, OI(COFF(flushiter)), C1, 0, TYP_NONE },
diff --git a/db/sb.c b/db/sb.c
index 961a939..21f38c5 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -620,6 +620,8 @@ version_string(
 		strcat(s, ",ATTR2");
 	if (xfs_sb_version_haslazysbcount(sbp))
 		strcat(s, ",LAZYSBCOUNT");
+	if (xfs_sb_version_hasprojid32bit(sbp))
+		strcat(s, ",PROJID32BIT");
 	return s;
 }
 
@@ -696,6 +698,10 @@ version_f(
 			xfs_sb_version_addattr2(&mp->m_sb);
 			version = mp->m_sb.sb_versionnum;
 			features = mp->m_sb.sb_features2;
+		} else if (!strcasecmp(argv[1], "projid32bit")) {
+			xfs_sb_version_addprojid32bit(&mp->m_sb);
+			version = mp->m_sb.sb_versionnum;
+			features = mp->m_sb.sb_features2;
 		} else {
 			dbprintf(_("%s: invalid version change command \"%s\"\n"),
 				progname, argv[1]);
diff --git a/include/xfs_dinode.h b/include/xfs_dinode.h
index d7cf392..f28c088 100644
--- a/include/xfs_dinode.h
+++ b/include/xfs_dinode.h
@@ -52,8 +52,9 @@ typedef struct xfs_dinode_core {
 	__be32		di_uid;		/* owner's user id */
 	__be32		di_gid;		/* owner's group id */
 	__be32		di_nlink;	/* number of links to file */
-	__be16		di_projid;	/* owner's project id */
-	__u8		di_pad[8];	/* unused, zeroed space */
+	__be16		di_projid_lo;	/* lower part of owner's project id */
+	__be16		di_projid_hi;	/* higher part owner's project id */
+	__u8		di_pad[6];	/* unused, zeroed space */
 	__be16		di_flushiter;	/* incremented on flush */
 	xfs_timestamp_t	di_atime;	/* time last accessed */
 	xfs_timestamp_t	di_mtime;	/* time last modified */
diff --git a/include/xfs_fs.h b/include/xfs_fs.h
index 74e7274..e36a5f1 100644
--- a/include/xfs_fs.h
+++ b/include/xfs_fs.h
@@ -299,9 +299,10 @@ typedef struct xfs_bstat {
 	__s32		bs_extsize;	/* extent size			*/
 	__s32		bs_extents;	/* number of extents		*/
 	__u32		bs_gen;		/* generation count		*/
-	__u16		bs_projid;	/* project id			*/
+	__u16		bs_projid_lo;	/* lower part of project id	*/
 	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
-	unsigned char	bs_pad[12];	/* pad space, unused		*/
+	__u16		bs_projid_hi;	/* higher part of project id	*/
+	unsigned char	bs_pad[10];	/* pad space, unused		*/
 	__u32		bs_dmevmask;	/* DMIG event mask		*/
 	__u16		bs_dmstate;	/* DMIG state info		*/
 	__u16		bs_aextents;	/* attribute number of extents	*/
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index b19b467..49f2524 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -124,8 +124,9 @@ typedef struct xfs_icdinode {
 	__uint32_t	di_uid;		/* owner's user id */
 	__uint32_t	di_gid;		/* owner's group id */
 	__uint32_t	di_nlink;	/* number of links to file */
-	__uint16_t	di_projid;	/* owner's project id */
-	__uint8_t	di_pad[8];	/* unused, zeroed space */
+	__uint16_t	di_projid_lo;	/* lower part of owner's project id */
+	__uint16_t	di_projid_hi;	/* higher part of owner's project id */
+	__uint8_t	di_pad[6];	/* unused, zeroed space */
 	__uint16_t	di_flushiter;	/* incremented on flush */
 	xfs_ictimestamp_t di_atime;	/* time last accessed */
 	xfs_ictimestamp_t di_mtime;	/* time last modified */
@@ -204,6 +205,22 @@ typedef struct xfs_icdinode {
 		((ip)->i_d.di_anextents = (n)))
 
 
+/*
+ * Project quota id helpers (userspace)
+ */
+static inline __uint32_t
+xfs_get_projid(xfs_icdinode_t i_d)
+{
+	return (__uint32_t)(i_d.di_projid_hi) << 16 | i_d.di_projid_lo;
+}
+
+static inline void
+xfs_set_projid(xfs_icdinode_t *i_d,
+		__uint32_t projid)
+{
+	i_d->di_projid_hi = (__uint16_t) (projid >> 16);
+	i_d->di_projid_lo = (__uint16_t) (projid & 0xffff);
+}
 
 #ifdef __KERNEL__
 
@@ -510,7 +527,7 @@ int		xfs_finish_reclaim_all(struct xfs_mount *, int);
 int		xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
 			  xfs_inode_t **, xfs_daddr_t, uint);
 int		xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
-			   xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
+			   xfs_nlink_t, xfs_dev_t, struct cred *, prid_t,
 			   int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
 
 uint		xfs_ip2xflags(struct xfs_inode *);
diff --git a/include/xfs_sb.h b/include/xfs_sb.h
index 1e86489..a0126dd 100644
--- a/include/xfs_sb.h
+++ b/include/xfs_sb.h
@@ -80,10 +80,12 @@ struct xfs_mount;
 #define XFS_SB_VERSION2_RESERVED4BIT	0x00000004
 #define XFS_SB_VERSION2_ATTR2BIT	0x00000008	/* Inline attr rework */
 #define XFS_SB_VERSION2_PARENTBIT	0x00000010	/* parent pointers */
+#define XFS_SB_VERSION2_PROJID32BIT	0x00000020	/* 32 bit project id */
 
 #define	XFS_SB_VERSION2_OKREALFBITS	\
 	(XFS_SB_VERSION2_LAZYSBCOUNTBIT	| \
-	 XFS_SB_VERSION2_ATTR2BIT)
+	 XFS_SB_VERSION2_ATTR2BIT	| \
+	 XFS_SB_VERSION2_PROJID32BIT)
 #define	XFS_SB_VERSION2_OKSASHFBITS	\
 	(0)
 #define XFS_SB_VERSION2_OKREALBITS	\
@@ -489,6 +491,18 @@ static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp)
 		sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
 }
 
+static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp)
+{
+	return xfs_sb_version_hasmorebits(sbp) &&
+		(sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT);
+}
+
+static inline void xfs_sb_version_addprojid32bit(xfs_sb_t *sbp)
+{
+	sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
+	sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
+}
+
 /*
  * end of superblock version macros
  */
diff --git a/include/xfs_types.h b/include/xfs_types.h
index 0f51916..228b948 100644
--- a/include/xfs_types.h
+++ b/include/xfs_types.h
@@ -81,8 +81,6 @@ typedef	__int32_t	xfs_tid_t;	/* transaction identifier */
 typedef	__uint32_t	xfs_dablk_t;	/* dir/attr block number (in file) */
 typedef	__uint32_t	xfs_dahash_t;	/* dir/attr hash value */
 
-typedef __uint16_t	xfs_prid_t;	/* prid_t truncated to 16bits in XFS */
-
 /*
  * These types are 64 bits on disk but are either 32 or 64 bits in memory.
  * Disk based types:
diff --git a/libxfs/util.c b/libxfs/util.c
index 409fb92..077d2a2 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -134,7 +134,7 @@ libxfs_iread(
 	 * made it 32 bits long.  If this is an old format inode,
 	 * convert it in memory to look like a new one.  If it gets
 	 * flushed to disk we will convert back before flushing or
-	 * logging it.  We zero out the new projid field and the old link
+	 * logging it.  We zero out the new projid_lo/hi field and the old link
 	 * count field.  We'll handle clearing the pad field (the remains
 	 * of the old uuid field) when we actually convert the inode to
 	 * the new format. We don't change the version number so that we
@@ -143,7 +143,7 @@ libxfs_iread(
 	if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
 		ip->i_d.di_nlink = ip->i_d.di_onlink;
 		ip->i_d.di_onlink = 0;
-		ip->i_d.di_projid = 0;
+		xfs_set_projid(&ip->i_d, 0);
 	}
 
 	ip->i_delayed_blks = 0;
@@ -219,7 +219,7 @@ libxfs_ialloc(
 	ASSERT(ip->i_d.di_nlink == nlink);
 	ip->i_d.di_uid = cr->cr_uid;
 	ip->i_d.di_gid = cr->cr_gid;
-	ip->i_d.di_projid = pip ? 0 : fsx->fsx_projid;
+	xfs_set_projid(&ip->i_d, pip ? 0 : fsx->fsx_projid);
 	memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 
 	/*
@@ -231,7 +231,10 @@ libxfs_ialloc(
 	if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) &&
 	    ip->i_d.di_version == XFS_DINODE_VERSION_1) {
 		ip->i_d.di_version = XFS_DINODE_VERSION_2;
-		/* old link count, projid field, pad field already zeroed */
+		/*
+		 * old link count, projid_lo/hi field, pad field
+		 * already zeroed
+		 */
 	}
 
 	if (pip && (pip->i_d.di_mode & S_ISGID)) {
@@ -446,7 +449,7 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp)
 			memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 			memset(&(dip->di_core.di_pad[0]), 0,
 			      sizeof(dip->di_core.di_pad));
-			ASSERT(ip->i_d.di_projid == 0);
+			ASSERT(xfs_get_projid(ip->i_d) == 0);
 		}
 	}
 
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 39fdf96..32ae4b0 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -46,7 +46,8 @@ xfs_ialloc_log_di(
 		offsetof(xfs_dinode_core_t, di_uid),
 		offsetof(xfs_dinode_core_t, di_gid),
 		offsetof(xfs_dinode_core_t, di_nlink),
-		offsetof(xfs_dinode_core_t, di_projid),
+		offsetof(xfs_dinode_core_t, di_projid_lo),
+		offsetof(xfs_dinode_core_t, di_projid_hi),
 		offsetof(xfs_dinode_core_t, di_pad),
 		offsetof(xfs_dinode_core_t, di_atime),
 		offsetof(xfs_dinode_core_t, di_mtime),
diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c
index b0adabc..1c9ea3b 100644
--- a/libxfs/xfs_inode.c
+++ b/libxfs/xfs_inode.c
@@ -589,7 +589,8 @@ xfs_dinode_from_disk(
 	to->di_uid = be32_to_cpu(from->di_uid);
 	to->di_gid = be32_to_cpu(from->di_gid);
 	to->di_nlink = be32_to_cpu(from->di_nlink);
-	to->di_projid = be16_to_cpu(from->di_projid);
+	to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
+	to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
 	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
 	to->di_flushiter = be16_to_cpu(from->di_flushiter);
 	to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
@@ -624,7 +625,8 @@ xfs_dinode_to_disk(
 	to->di_uid = cpu_to_be32(from->di_uid);
 	to->di_gid = cpu_to_be32(from->di_gid);
 	to->di_nlink = cpu_to_be32(from->di_nlink);
-	to->di_projid = cpu_to_be16(from->di_projid);
+	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
+	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
 	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
 	to->di_flushiter = cpu_to_be16(from->di_flushiter);
 	to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index c21e05c..572dac8 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -238,8 +238,10 @@ xlog_recover_print_inode_core(
 	     "onlink:%d\n"),
 	       (di->di_magic>>8) & 0xff, di->di_magic & 0xff,
 	       di->di_mode, di->di_version, di->di_format, di->di_onlink);
-	printf(_("		uid:%d  gid:%d  nlink:%d projid:%d\n"),
-	       di->di_uid, di->di_gid, di->di_nlink, (uint)di->di_projid);
+	printf(_("		uid:%d  gid:%d  nlink:%d\n"),
+	       di->di_uid, di->di_gid, di->di_nlink);
+	printf(_("		projid_lo:%d projid_hi:%d\n"),
+	       (uint)di->di_projid_lo, (uint)di->di_projid_hi);
 	printf(_("		atime:%d  mtime:%d  ctime:%d\n"),
 	       di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec);
 	printf(_("		flushiter:%d\n"), di->di_flushiter);
diff --git a/man/man3/xfsctl.3 b/man/man3/xfsctl.3
index 784b3e0..7f3c2e8 100644
--- a/man/man3/xfsctl.3
+++ b/man/man3/xfsctl.3
@@ -564,8 +564,10 @@ The structure has the following elements:
 (number of extents),
 .B bs_gen
 (generation count),
-.B bs_projid
-(project id),
+.B bs_projid_lo
+(project id - low word),
+.B bs_projid_hi
+(project id - high word),
 .B bs_dmevmask
 (DMIG event mask),
 .B bs_dmstate
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index 629ae58..17ac601 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -1474,8 +1474,10 @@ number of links to the file in a version 1 inode.
 .B nlinkv2
 number of links to the file in a version 2 inode.
 .TP
-.B projid
-owner's project id (version 2 inode only).
+.B projid_lo
+owner's project id (low word; version 2 inode only).
+.B projid_hi
+owner's project id (high word; version 2 inode only).
 .TP
 .B uid
 owner's user id.
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 2d09e36..15edf67 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -106,6 +106,8 @@ char	*iopts[] = {
 	"size",
 #define	I_ATTR		5
 	"attr",
+#define	I_PROJID32BIT	6
+	"projid32bit",
 	NULL
 };
 
@@ -829,6 +831,7 @@ main(
 	__uint64_t		agsize;
 	xfs_alloc_rec_t		*arec;
 	int			attrversion;
+	int			projid32bit;
 	struct xfs_btree_block	*block;
 	int			blflag;
 	int			blocklog;
@@ -923,6 +926,7 @@ main(
 	textdomain(PACKAGE);
 
 	attrversion = 2;
+	projid32bit = 0;
 	blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
 	blocklog = blocksize = 0;
 	sectorlog = lsectorlog = XFS_MIN_SECTORSIZE_LOG;
@@ -1259,6 +1263,14 @@ main(
 						illegal(value, "i attr");
 					attrversion = c;
 					break;
+				case I_PROJID32BIT:
+					if (!value)
+						reqval('i', iopts, I_PROJID32BIT);
+					c = atoi(value);
+					if (c < 0 || c > 1)
+						illegal(value, "i projid32bit");
+					projid32bit = c;
+					break;
 				default:
 					unknown('i', value);
 				}
@@ -2261,7 +2273,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
 	if (!qflag || Nflag) {
 		printf(_(
 		   "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
-		   "         =%-22s sectsz=%-5u attr=%u\n"
+		   "         =%-22s sectsz=%-5u attr=%u projid32bit=%u\n"
 		   "data     =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
 		   "         =%-22s sunit=%-6u swidth=%u blks\n"
 		   "naming   =version %-14u bsize=%-6u ascii-ci=%d\n"
@@ -2269,7 +2281,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
 		   "         =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
 		   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
 			dfile, isize, (long long)agcount, (long long)agsize,
-			"", sectorsize, attrversion,
+			"", sectorsize, attrversion, projid32bit,
 			"", blocksize, (long long)dblocks, imaxpct,
 			"", dsunit, dswidth,
 			dirversion, dirblocksize, nci,
@@ -2336,7 +2348,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"),
 		sbp->sb_logsectsize = 0;
 	}
 	sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters,
-					attrversion == 2, 0);
+					attrversion == 2, projid32bit == 1, 0);
 	sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0,
 					logversion == 2, attrversion == 1,
 					(sectorsize != BBSIZE ||
diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h
index 49401d6..f25a7f3 100644
--- a/mkfs/xfs_mkfs.h
+++ b/mkfs/xfs_mkfs.h
@@ -36,9 +36,10 @@
 	        XFS_DFL_SB_VERSION_BITS |                               \
 	0 ) : XFS_SB_VERSION_1 )
 
-#define XFS_SB_VERSION2_MKFS(lazycount, attr2, parent) (\
+#define XFS_SB_VERSION2_MKFS(lazycount, attr2, projid32bit, parent) (\
 	((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) |		\
 	((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) |			\
+	((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) |		\
 	((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) |			\
 	0 )
 
diff --git a/quota/quot.c b/quota/quot.c
index 09d349f..98f9a04 100644
--- a/quota/quot.c
+++ b/quota/quot.c
@@ -102,7 +102,8 @@ quot_bulkstat_add(
 	}
 	for (i = 0; i < 3; i++) {
 		id = (i == 0) ? p->bs_uid : ((i == 1) ?
-				p->bs_gid : p->bs_projid);
+			p->bs_gid : ((prid_t)p->bs_projid_hi << 16
+					| p->bs_projid_lo));
 		hp = &duhash[i][id % DUHASH];
 		for (dp = *hp; dp; dp = dp->next)
 			if (dp->id == id)
diff --git a/repair/README b/repair/README
index 69cb0c5..7f168e6 100644
--- a/repair/README
+++ b/repair/README
@@ -130,7 +130,7 @@ D - 0)	rewrite directory leaf block holemap comparison code.
 	it does describe doesn't conflict with reality.
 
 D - 0)	rewrite setting nlinks handling -- for version 1
-	inodes, set both nlinks and onlinks (zero projid
+	inodes, set both nlinks and onlinks (zero projid_lo/hi
 	and pad) if we have to change anything.  For
 	version 2, I think we're ok.
 
-- 
1.7.2.2

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs



[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux