xfs
[Top] [All Lists]

[PATCH VER 4] Extend project quotas to support 32bit project identificat

To: xfs@xxxxxxxxxxx
Subject: [PATCH VER 4] Extend project quotas to support 32bit project identificators.
From: Arkadiusz Miśkiewicz <arekm@xxxxxxxx>
Date: Wed, 22 Sep 2010 19:42:23 +0200
Cc: Arkadiusz Miśkiewicz <arekm@xxxxxxxx>
This patch adds support for 32bit project quota identificators.

On disk format is backward compatible with 16bit projid numbers. projid
on disk is now keept in two 16bit values - di_projid_lo (which holds the
same position as old 16bit projid value) and new di_projid_hi (takes
existing padding) and convertes from/to 32bit value on the fly.

PROJID32BIT feature2 flag is set automaticly when trying to use 32bit
quota project identificator.

Signed-off-by: Arkadiusz Miśkiewicz <arekm@xxxxxxxx>
---

What has changed?
- sb_bad_features2 is also updated
- new helper - xfs_addprojid32bit
- drop 16bit projid protection in latest kernels

I think it's ready to merge but it lacks final Reviewed-by,
Tested-by (beside me) etc :-(

 fs/xfs/linux-2.6/xfs_ioctl.c   |   30 ++++++++++++++++--------------
 fs/xfs/linux-2.6/xfs_ioctl32.c |    6 ++++--
 fs/xfs/linux-2.6/xfs_ioctl32.h |    5 +++--
 fs/xfs/quota/xfs_qm.c          |   12 ++++++------
 fs/xfs/quota/xfs_qm_bhv.c      |    2 +-
 fs/xfs/quota/xfs_qm_syscalls.c |    2 +-
 fs/xfs/xfs_dinode.h            |    5 +++--
 fs/xfs/xfs_fs.h                |    5 +++--
 fs/xfs/xfs_inode.c             |   14 ++++++++------
 fs/xfs/xfs_inode.h             |   24 +++++++++++++++++++++---
 fs/xfs/xfs_itable.c            |    3 ++-
 fs/xfs/xfs_rename.c            |    2 +-
 fs/xfs/xfs_sb.h                |   17 ++++++++++++++++-
 fs/xfs/xfs_types.h             |    2 --
 fs/xfs/xfs_utils.c             |   21 +++++++++++++++++++++
 fs/xfs/xfs_utils.h             |    1 +
 fs/xfs/xfs_vnodeops.c          |   14 +++++++-------
 17 files changed, 114 insertions(+), 51 deletions(-)

diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4fec427..aa72465 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -788,7 +788,7 @@ xfs_ioc_fsgetxattr(
        xfs_ilock(ip, XFS_ILOCK_SHARED);
        fa.fsx_xflags = xfs_ip2xflags(ip);
        fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
-       fa.fsx_projid = ip->i_d.di_projid;
+       fa.fsx_projid = xfs_get_projid(ip);
 
        if (attr) {
                if (ip->i_afp) {
@@ -907,13 +907,6 @@ xfs_ioctl_setattr(
                return XFS_ERROR(EIO);
 
        /*
-        * Disallow 32bit project ids because on-disk structure
-        * is 16bit only.
-        */
-       if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1))
-               return XFS_ERROR(EINVAL);
-
-       /*
         * If disk quotas is on, we make sure that the dquots do exist on disk,
         * before we start any other transactions. Trying to do this later
         * is messy. We don't care to take a readlock to look at the ids
@@ -953,13 +946,22 @@ xfs_ioctl_setattr(
                goto error_return;
        }
 
-       /*
-        * Do a quota reservation only if projid is actually going to change.
-        */
        if (mask & FSX_PROJID) {
+               /*
+                * Switch on the PROJID32BIT superblock bit when needed
+                * (implies also FEATURES2)
+                */
+               if (!xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb) &&
+                               fa->fsx_projid > (__uint16_t)-1)
+                       xfs_addprojid32bit(tp, ip);
+
+               /*
+                * Do a quota reservation only if projid is actually
+                * going to change.
+                */
                if (XFS_IS_QUOTA_RUNNING(mp) &&
                    XFS_IS_PQUOTA_ON(mp) &&
-                   ip->i_d.di_projid != fa->fsx_projid) {
+                   xfs_get_projid(ip) != fa->fsx_projid) {
                        ASSERT(tp);
                        code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
                                                capable(CAP_FOWNER) ?
@@ -1061,12 +1063,12 @@ xfs_ioctl_setattr(
                 * Change the ownerships and register quota modifications
                 * in the transaction.
                 */
-               if (ip->i_d.di_projid != fa->fsx_projid) {
+               if (xfs_get_projid(ip) != fa->fsx_projid) {
                        if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
                                olddquot = xfs_qm_vop_chown(tp, ip,
                                                        &ip->i_gdquot, gdqp);
                        }
-                       ip->i_d.di_projid = fa->fsx_projid;
+                       xfs_set_projid(ip, fa->fsx_projid);
 
                        /*
                         * We may have to rev the inode as well as
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 6c83f7f..2146196 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -164,7 +164,8 @@ xfs_ioctl32_bstat_copyin(
            get_user(bstat->bs_extsize, &bstat32->bs_extsize)   ||
            get_user(bstat->bs_extents, &bstat32->bs_extents)   ||
            get_user(bstat->bs_gen,     &bstat32->bs_gen)       ||
-           get_user(bstat->bs_projid,  &bstat32->bs_projid)    ||
+           get_user(bstat->bs_projid_lo,       &bstat32->bs_projid_lo) ||
+           get_user(bstat->bs_projid_hi,       &bstat32->bs_projid_hi) ||
            get_user(bstat->bs_dmevmask, &bstat32->bs_dmevmask) ||
            get_user(bstat->bs_dmstate, &bstat32->bs_dmstate)   ||
            get_user(bstat->bs_aextents, &bstat32->bs_aextents))
@@ -217,7 +218,8 @@ xfs_bulkstat_one_fmt_compat(
            put_user(buffer->bs_extsize,  &p32->bs_extsize)     ||
            put_user(buffer->bs_extents,  &p32->bs_extents)     ||
            put_user(buffer->bs_gen,      &p32->bs_gen)         ||
-           put_user(buffer->bs_projid,   &p32->bs_projid)      ||
+           put_user(buffer->bs_projid_lo,      &p32->bs_projid_lo)     ||
+           put_user(buffer->bs_projid_hi,      &p32->bs_projid_hi)     ||
            put_user(buffer->bs_dmevmask, &p32->bs_dmevmask)    ||
            put_user(buffer->bs_dmstate,  &p32->bs_dmstate)     ||
            put_user(buffer->bs_aextents, &p32->bs_aextents))
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h
index 1024c4f..7a22385 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.h
@@ -65,8 +65,9 @@ typedef struct compat_xfs_bstat {
        __s32           bs_extsize;     /* extent size                  */
        __s32           bs_extents;     /* number of extents            */
        __u32           bs_gen;         /* generation count             */
-       __u16           bs_projid;      /* project id                   */
-       unsigned char   bs_pad[14];     /* pad space, unused            */
+       __u16           bs_projid_lo;   /* lower part of project id     */
+       __u16           bs_projid_hi;   /* high part of project id      */
+       unsigned char   bs_pad[12];     /* 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/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 9a92407..9a8885e 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -837,7 +837,7 @@ xfs_qm_dqattach_locked(
                        xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
                                                flags & XFS_QMOPT_DQALLOC,
                                                ip->i_udquot, &ip->i_gdquot) :
-                       xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
+                       xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
                                                flags & XFS_QMOPT_DQALLOC,
                                                ip->i_udquot, &ip->i_gdquot);
                /*
@@ -1248,7 +1248,7 @@ xfs_qm_dqget_noattach(
                                             XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
                                             &gdqp) :
                                xfs_qm_dqget(mp, ip,
-                                            ip->i_d.di_projid, XFS_DQ_PROJ,
+                                            xfs_get_projid(ip), XFS_DQ_PROJ,
                                             XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
                                             &gdqp);
                if (error) {
@@ -2332,9 +2332,9 @@ xfs_qm_vop_dqalloc(
                        xfs_dqunlock(gq);
                }
        } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
-               if (ip->i_d.di_projid != prid) {
+               if (xfs_get_projid(ip) != prid) {
                        xfs_iunlock(ip, lockflags);
-                       if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
+                       if ((error = xfs_qm_dqget(mp, NULL, prid,
                                                 XFS_DQ_PROJ,
                                                 XFS_QMOPT_DQALLOC |
                                                 XFS_QMOPT_DOWARN,
@@ -2454,7 +2454,7 @@ xfs_qm_vop_chown_reserve(
        }
        if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
                if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
-                    ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
+                    xfs_get_projid(ip) != be32_to_cpu(gdqp->q_core.d_id))
                        prjflags = XFS_QMOPT_ENOSPC;
 
                if (prjflags ||
@@ -2558,7 +2558,7 @@ xfs_qm_vop_create_dqattach(
                ip->i_gdquot = gdqp;
                ASSERT(XFS_IS_OQUOTA_ON(mp));
                ASSERT((XFS_IS_GQUOTA_ON(mp) ?
-                       ip->i_d.di_gid : ip->i_d.di_projid) ==
+                       ip->i_d.di_gid : xfs_get_projid(ip)) ==
                                be32_to_cpu(gdqp->q_core.d_id));
                xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
        }
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index bea02d7..45b5cb1 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -81,7 +81,7 @@ xfs_qm_statvfs(
        xfs_mount_t             *mp = ip->i_mount;
        xfs_dquot_t             *dqp;
 
-       if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
+       if (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
                xfs_fill_statvfs_from_dquot(statp, &dqp->q_core);
                xfs_qm_dqput(dqp);
        }
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 45e5849..a89065b 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -1175,7 +1175,7 @@ xfs_qm_internalqcheck_adjust(
        }
        xfs_qm_internalqcheck_get_dquots(mp,
                                        (xfs_dqid_t) ip->i_d.di_uid,
-                                       (xfs_dqid_t) ip->i_d.di_projid,
+                                       (xfs_dqid_t) xfs_get_projid(ip),
                                        (xfs_dqid_t) ip->i_d.di_gid,
                                        &ud, &gd);
        if (XFS_IS_UQUOTA_ON(mp)) {
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index e5b153b..dffba9b 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -49,8 +49,9 @@ typedef struct xfs_dinode {
        __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/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 87c2e9d..c03c752 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -293,9 +293,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/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 34798f3..2ab5959 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -660,7 +660,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);
@@ -695,7 +696,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);
@@ -874,7 +876,7 @@ xfs_iread(
        if (ip->i_d.di_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, 0);
        }
 
        ip->i_delayed_blks = 0;
@@ -983,7 +985,7 @@ xfs_ialloc(
        xfs_nlink_t     nlink,
        xfs_dev_t       rdev,
        cred_t          *cr,
-       xfs_prid_t      prid,
+       prid_t          prid,
        int             okalloc,
        xfs_buf_t       **ialloc_context,
        boolean_t       *call_again,
@@ -1027,7 +1029,7 @@ xfs_ialloc(
        ASSERT(ip->i_d.di_nlink == nlink);
        ip->i_d.di_uid = current_fsuid();
        ip->i_d.di_gid = current_fsgid();
-       ip->i_d.di_projid = prid;
+       xfs_set_projid(ip, prid);
        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
 
        /*
@@ -3008,7 +3010,7 @@ xfs_iflush_int(
                        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
                        memset(&(dip->di_pad[0]), 0,
                              sizeof(dip->di_pad));
-                       ASSERT(ip->i_d.di_projid == 0);
+                       ASSERT(xfs_get_projid(ip) == 0);
                }
        }
 
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 0898c54..5bbb100 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -134,8 +134,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 */
@@ -335,6 +336,23 @@ xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short 
flags)
 }
 
 /*
+ * Project quota id helpers
+ */
+static inline prid_t
+xfs_get_projid(xfs_inode_t *ip)
+{
+       return (prid_t)(ip->i_d.di_projid_hi) << 16 | ip->i_d.di_projid_lo;
+}
+
+static inline void
+xfs_set_projid(xfs_inode_t *ip,
+               prid_t projid)
+{
+       ip->i_d.di_projid_hi = (__uint16_t) (projid >> 16);
+       ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
+}
+
+/*
  * Manage the i_flush queue embedded in the inode.  This completion
  * queue synchronizes processes attempting to flush the in-core
  * inode back to disk.
@@ -456,7 +474,7 @@ void                xfs_inode_free(struct xfs_inode *ip);
  * xfs_inode.c prototypes.
  */
 int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
-                          xfs_nlink_t, xfs_dev_t, cred_t *, xfs_prid_t,
+                          xfs_nlink_t, xfs_dev_t, cred_t *, prid_t,
                           int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
 
 uint           xfs_ip2xflags(struct xfs_inode *);
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 7e3626e..dc1882a 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -92,7 +92,8 @@ xfs_bulkstat_one_int(
         * further change.
         */
        buf->bs_nlink = dic->di_nlink;
-       buf->bs_projid = dic->di_projid;
+       buf->bs_projid_lo = dic->di_projid_lo;
+       buf->bs_projid_hi = dic->di_projid_hi;
        buf->bs_ino = ino;
        buf->bs_mode = dic->di_mode;
        buf->bs_uid = dic->di_uid;
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 8fca957..494b5cd 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -183,7 +183,7 @@ xfs_rename(
         * tree quota mechanism would be circumvented.
         */
        if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
-                    (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) {
+                    (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) {
                error = XFS_ERROR(EXDEV);
                goto error_return;
        }
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index 1b017c6..f7674c4 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/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     \
@@ -495,6 +497,19 @@ 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;
+       sbp->sb_bad_features2 |= XFS_SB_VERSION2_PROJID32BIT;
+}
+
 /*
  * end of superblock version macros
  */
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 3207752..26d1867 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -73,8 +73,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 */
-
 typedef __uint32_t     xlog_tid_t;     /* transaction ID type */
 
 /*
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index b7d5769..962efbd 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -320,3 +320,24 @@ xfs_bumplink(
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
        return 0;
 }
+
+/*
+ * Switches on the PROJID32BIT superblock bit
+ * (implies also FEATURES2).
+ */
+
+int
+xfs_addprojid32bit(
+       xfs_trans_t *tp,
+       xfs_inode_t *ip)
+{
+       spin_lock(&ip->i_mount->m_sb_lock);
+       if (!xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb)) {
+               xfs_sb_version_addprojid32bit(&ip->i_mount->m_sb);
+               spin_unlock(&ip->i_mount->m_sb_lock);
+               xfs_mod_sb(tp,
+                               XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+       } else
+               spin_unlock(&ip->i_mount->m_sb_lock);
+       return 0;
+}
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index f55b967..5c40acd 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -24,5 +24,6 @@ extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, 
mode_t, xfs_nlink_t,
 extern int xfs_droplink(xfs_trans_t *, xfs_inode_t *);
 extern int xfs_bumplink(xfs_trans_t *, xfs_inode_t *);
 extern void xfs_bump_ino_vers2(xfs_trans_t *, xfs_inode_t *);
+extern int xfs_addprojid32bit(xfs_trans_t *, xfs_inode_t *);
 
 #endif /* __XFS_UTILS_H__ */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 4c7c7bf..72319a9 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -114,7 +114,7 @@ xfs_setattr(
                 */
                ASSERT(udqp == NULL);
                ASSERT(gdqp == NULL);
-               code = xfs_qm_vop_dqalloc(ip, uid, gid, ip->i_d.di_projid,
+               code = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip),
                                         qflags, &udqp, &gdqp);
                if (code)
                        return code;
@@ -1266,7 +1266,7 @@ xfs_create(
        boolean_t               unlock_dp_on_error = B_FALSE;
        uint                    cancel_flags;
        int                     committed;
-       xfs_prid_t              prid;
+       prid_t                  prid;
        struct xfs_dquot        *udqp = NULL;
        struct xfs_dquot        *gdqp = NULL;
        uint                    resblks;
@@ -1279,7 +1279,7 @@ xfs_create(
                return XFS_ERROR(EIO);
 
        if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
-               prid = dp->i_d.di_projid;
+               prid = xfs_get_projid(dp);
        else
                prid = dfltprid;
 
@@ -1880,7 +1880,7 @@ xfs_link(
         * the tree quota mechanism could be circumvented.
         */
        if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
-                    (tdp->i_d.di_projid != sip->i_d.di_projid))) {
+                    (xfs_get_projid(tdp) != xfs_get_projid(sip)))) {
                error = XFS_ERROR(EXDEV);
                goto error_return;
        }
@@ -1955,7 +1955,7 @@ xfs_symlink(
        int                     byte_cnt;
        int                     n;
        xfs_buf_t               *bp;
-       xfs_prid_t              prid;
+       prid_t                  prid;
        struct xfs_dquot        *udqp, *gdqp;
        uint                    resblks;
 
@@ -1978,9 +1978,9 @@ xfs_symlink(
 
        udqp = gdqp = NULL;
        if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
-               prid = dp->i_d.di_projid;
+               prid = xfs_get_projid(dp);
        else
-               prid = (xfs_prid_t)dfltprid;
+               prid = dfltprid;
 
        /*
         * Make sure that we have allocated dquot(s) on disk.
-- 
1.7.2.3

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