public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: Chandra Seetharaman <sekharan@us.ibm.com>
Cc: xfs@oss.sgi.com
Subject: Re: [RFC v6 PATCH 4/5] xfs: Add proper versioning support to fs_quota_stat
Date: Wed, 15 Aug 2012 12:32:06 +1000	[thread overview]
Message-ID: <20120815023206.GT2877@dastard> (raw)
In-Reply-To: <20120720230247.20477.68011.sendpatchset@chandra-lucid.austin.ibm.com>

On Fri, Jul 20, 2012 at 06:02:47PM -0500, Chandra Seetharaman wrote:
> 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.

Userspace Interface Traps for the Unwary 101, below.

>  /*
>   * 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))

I don't expect that will work on all arches. pahole (everyone needs
to know about pahole!) tells me the original structure on x86_64
looks like:

struct fs_quota_stat {
        __s8                       qs_version;           /*     0     1 */

        /* XXX 1 byte hole, try to pack */

        __u16                      qs_flags;             /*     2     2 */
        __s8                       qs_pad;               /*     4     1 */

        /* XXX 3 bytes hole, try to pack */

        fs_qfilestat_t             qs_uquota;            /*     8    24 */
        fs_qfilestat_t             qs_gquota;            /*    32    24 */
        __u32                      qs_incoredqs;         /*    56     4 */
        __s32                      qs_btimelimit;        /*    60     4 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        __s32                      qs_itimelimit;        /*    64     4 */
        __s32                      qs_rtbtimelimit;      /*    68     4 */
        __u16                      qs_bwarnlimit;        /*    72     2 */
        __u16                      qs_iwarnlimit;        /*    74     2 */

        /* size: 80, cachelines: 2, members: 11 */
        /* sum members: 72, holes: 2, sum holes: 4 */
        /* padding: 4 */
        /* last cacheline: 16 bytes */
}

and that qs_iwarnlimit does not end on a 8 byte boundary. If we then
look at fs_qfilestat:

typedef struct fs_qfilestat {
        __u64           qfs_ino;        /* inode number */
        __u64           qfs_nblks;      /* number of BBs 512-byte-blks */
        __u32           qfs_nextents;   /* number of extents */
} fs_qfilestat_t;

it has an 8 byte alignment, so the above FS_QSTAT_V2_SIZE
calculation is wrong because it doesn't take into account holes in
the structure and there is 4 bytes of hole between qs_iwarnlimit and
qs_pquota. It's entirely possible that this might require a compat
handler as some platforms might pack the structure differently in 32
vs 64 bit binaries..

IOWs, you ned to explicitly add padding to thie structure, like
someone tried to do in the past a screwed it up completely.
Basically, the structure needs to be padded like this:

typedef struct fs_quota_stat {
	__s8            qs_version;     /* version number for future changes */
	__u8		qs_pad1;	/* unused */
	__u16           qs_flags;       /* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
	__u8            qs_pad2[3];     /* unused */
	fs_qfilestat_t  qs_uquota;      /* user quota storage information */
	fs_qfilestat_t  qs_gquota;      /* group quota storage information */
	__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 */
	__u8		qs_pad3[4];	/* unused */
	fs_qfilestat_t	qs_pquota;	/* project quota storage information */
} fs_quota_stat_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;
> +	}
> +}

I don't see much point in these helpers - just put them in line in
the quota_getxstate() code. i.e.

	switch (version) {
	case FS_QSTAT_VERSION_2:
		size = FS_QSTAT_V2_SIZE;
		break;
	default:
		version = FS_QSTAT_VERSION;
		/* fallthrough */
	case FS_QSTAT_VERSION:
		size = FS_QSTAT_V1_SIZE;
		break;
	}

Cheers,

Dave.

-- 
Dave Chinner
david@fromorbit.com

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

  reply	other threads:[~2012-08-15  2:32 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-20 23:02 [RFC v6 PATCH 0/5] xfs: Allow pquota and gquota to be used together Chandra Seetharaman
2012-07-20 23:02 ` [RFC v6 PATCH 1/5] xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD Chandra Seetharaman
2012-08-14 22:46   ` Dave Chinner
2012-08-22 22:53     ` Chandra Seetharaman
2012-09-13  7:56       ` Christoph Hellwig
2012-09-13 20:37         ` Chandra Seetharaman
2012-07-20 23:02 ` [RFC v6 PATCH 2/5] xfs: Add pquota fields where gquota is used Chandra Seetharaman
2012-08-15  1:15   ` Dave Chinner
2012-08-22 22:56     ` Chandra Seetharaman
2012-07-20 23:02 ` [RFC v6 PATCH 3/5] xfs: Add pquotaino to on-disk super block Chandra Seetharaman
2012-08-15  2:09   ` Dave Chinner
2012-08-22 23:30     ` Chandra Seetharaman
2012-08-23  0:25       ` Dave Chinner
2012-07-20 23:02 ` [RFC v6 PATCH 4/5] xfs: Add proper versioning support to fs_quota_stat Chandra Seetharaman
2012-08-15  2:32   ` Dave Chinner [this message]
2012-08-22 23:32     ` Chandra Seetharaman
2012-07-20 23:03 ` [RFC v6 PATCH 5/5] xfs: Add a new field to fs_quota_stat to get pquota information Chandra Seetharaman
2012-08-15  2:37   ` Dave Chinner
2012-08-22 23:40     ` Chandra Seetharaman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120815023206.GT2877@dastard \
    --to=david@fromorbit.com \
    --cc=sekharan@us.ibm.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox