On Mon, 2013-03-25 at 10:14 +1100, Dave Chinner wrote:
> On Fri, Mar 22, 2013 at 10:00:46AM -0500, Chandra Seetharaman wrote:
> > Sure. I will look at your CRC patchset and see what changes are needed
> > to mine.
> >
> > Meantime, you can answer my dilemma with the change in fs_quota_stat
> > (see patch 4).
> >
> > As per your suggestion, I changed the data structure, to include pads at
> > relevant places in the data structure, which also means that the new
> > modified structure is not compatible with older user space code.
> >
> > So, I created a copy of the older structure (fs_quota_stat_v1) and used
> > that if the user space request has older structure. So, now the new
> > kernel code is backward compatible with the old (already running) user
> > space code. All is well till now....
> >
> > Now, I make the changes to the user space code so as to use the new
> > fs_quota_stat. Since the data structure has changed, the new user space
> > code will not work with the old kernel code.
>
> The issue that the userspace code has to handle is that old kernels
> decide the version of the structure, not userspace. i.e. the
> version number is an output parameter, not an input parameter. Hence
> on old kernels we have to detect the version after the call rather
> than assume the kernel treated the version as an input...
>
> > This is where I have the dilemma.
> >
> > 1. Leave the user space code to work only with the newer version,
> > breaking the compatibility with the older kernel (with an error
> > message).
> > or
> > 2. Read the superblock, and if pquotino is _not_ present conclude older
> > version of fs_quota_stat would suffice for getting quota information
> > from kernel (note that this will work properly with newer kernel code
> > too), and use the older version of fs_quota_stat_v1 for quotactl.
> > or
> > 3. Any other clever way ? :)
>
> Because the version is only an output field for old kernels, the
> userspace code should be able to handle it like this:
>
> struct fs_quota_stat fqs;
>
> ASSERT(sizeof(struct fs_quota_stat) >= sizeof(struct fs_quota_stat_v1));
>
> memset(&fqs, 0, sizeof(fqs));
> fqs.version = FS_QSTAT_VERSION_2;
> error = quotactl(...., &fqs);
>
> if (fqs.version == FS_QSTAT_VERSION) {
> struct fs_quota_stat_v1 *fqsv1 = &fqs;
>
> /* process as version 1 */
> .....
> return error;
> }
>
> /* process as version 2 */
> .....
> return error;
>
> However, with the version field in the same place for both
> structures, userspace can read the version number after the call and
> determine the correct structure type for the information returned by
> the kernel...
Oh yeah. I didn't think about it.
Thanks.
>
> Cheers,
>
> Dave.
|