xfs
[Top] [All Lists]

[RFC v6 PATCH 4/5] xfs: Add proper versioning support to fs_quota_stat

To: xfs@xxxxxxxxxxx
Subject: [RFC v6 PATCH 4/5] xfs: Add proper versioning support to fs_quota_stat
From: Chandra Seetharaman <sekharan@xxxxxxxxxx>
Date: Fri, 20 Jul 2012 18:02:47 -0500
Cc: Chandra Seetharaman <sekharan@xxxxxxxxxx>
In-reply-to: <20120720230202.20477.69766.sendpatchset@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
References: <20120720230202.20477.69766.sendpatchset@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Add proper versioning support for fs_quota_stat.

Leave the earlier version as version 1 and add version 2 to add a new
field "fs_qfilestat_t qs_pquota"

Callers of the system call have to just set the version of the data
structure being passed, and kernel will fill as much data as possible.

Signed-off-by: Chandra Seetharaman <sekharan@xxxxxxxxxx>
---
 fs/quota/quota.c          |    6 +++++-
 include/linux/dqblk_xfs.h |   28 +++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 9a39120..ee929ca 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -203,8 +203,12 @@ static int quota_getxstate(struct super_block *sb, void 
__user *addr)
 
        if (!sb->s_qcop->get_xstate)
                return -ENOSYS;
+       if (copy_from_user(&fqs, addr, 1)) /* just get the version */
+               return -EFAULT;
+       if (!valid_qstat_version(fqs.qs_version))
+               fqs.qs_version = FS_QSTAT_VERSION;
        ret = sb->s_qcop->get_xstate(sb, &fqs);
-       if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
+       if (!ret && copy_to_user(addr, &fqs, qstatsize(fqs.qs_version)))
                return -EFAULT;
        return ret;
 }
diff --git a/include/linux/dqblk_xfs.h b/include/linux/dqblk_xfs.h
index f17e3bb..5be63fb 100644
--- a/include/linux/dqblk_xfs.h
+++ b/include/linux/dqblk_xfs.h
@@ -18,6 +18,7 @@
 #define _LINUX_DQBLK_XFS_H
 
 #include <linux/types.h>
+#include <linux/stddef.h>
 
 /*
  * Disk quota - quotactl(2) commands for the XFS Quota Manager (XQM).
@@ -139,6 +140,7 @@ typedef struct fs_disk_quota {
  * incore.
  */
 #define FS_QSTAT_VERSION       1       /* fs_quota_stat.qs_version */
+#define FS_QSTAT_VERSION_2     2       /* new field qs_pquota */
 
 /*
  * Some basic information about 'quota files'.
@@ -155,13 +157,37 @@ typedef struct fs_quota_stat {
        __s8            qs_pad;         /* unused */
        fs_qfilestat_t  qs_uquota;      /* user quota storage information */
        fs_qfilestat_t  qs_gquota;      /* group quota storage information */
-#define qs_pquota      qs_gquota
        __u32           qs_incoredqs;   /* number of dquots incore */
        __s32           qs_btimelimit;  /* limit for blks timer */      
        __s32           qs_itimelimit;  /* limit for inodes timer */    
        __s32           qs_rtbtimelimit;/* limit for rt blks timer */   
        __u16           qs_bwarnlimit;  /* limit for num warnings */
        __u16           qs_iwarnlimit;  /* limit for num warnings */
+       fs_qfilestat_t  qs_pquota;      /* project quota storage information */
 } fs_quota_stat_t;
 
+#define FS_QSTAT_V1_SIZE       (offsetof(fs_quota_stat_t, qs_pquota))
+#define FS_QSTAT_V2_SIZE       (FS_QSTAT_V1_SIZE + sizeof (fs_qfilestat_t))
+
+static inline int valid_qstat_version(int version)
+{
+       switch (version) {
+       case FS_QSTAT_VERSION:
+       case FS_QSTAT_VERSION_2:
+               return 1;
+       default:
+               return 0;
+       }
+}
+static inline int qstatsize(int version)
+{
+       switch (version) {
+       case FS_QSTAT_VERSION_2:
+               return FS_QSTAT_V2_SIZE;
+       case FS_QSTAT_VERSION:
+       default:
+               return FS_QSTAT_V1_SIZE;
+       }
+}
+
 #endif /* _LINUX_DQBLK_XFS_H */
-- 
1.7.1

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