From 0c051fd0e737e03ac6cadb7699c93bcde959b4fd Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Wed, 27 Jul 2011 02:30:19 -0600 Subject: [PATCH] LU-540 quota: add compatibility for 1.8 userspace The LL_IOC_QUOTACTL ioctl data structure if_quotactl changed size in 2.x by adding new fields in the middle of the structure. Add compatibility for the old 1.8 quotactl userspace ioctl so that it is possible for existing quotactl tools to run on both 1.x and 2.x. This requires renumbering the LL_IOC_QUOTACTL ioctl, since it had incorrectly used "struct if_quotactl *" as the "size" parameter, but the _pointer_ size did not change. ioctl() values should always take a struct as the size parameter, not a pointer to the struct, so that issues like this can be caught earlier. Change-Id: I0bce98327a276c0c9a49ce78efd3f45e00df7168 Signed-off-by: Andreas Dilger Reviewed-on: http://review.whamcloud.com/1152 Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/lustre/lustre_user.h | 2 +- lustre/include/lustre_lib.h | 2 +- lustre/llite/dir.c | 54 +++++++++++++++++++++++++++++++++++++ lustre/llite/llite_internal.h | 19 +++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index d0da8a8..3a7f330 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -137,7 +137,7 @@ struct obd_statfs { /* LL_IOC_POLL_QUOTACHECK: See also OBD_IOC_POLL_QUOTACHECK */ #define LL_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) /* LL_IOC_QUOTACTL: See also OBD_IOC_QUOTACTL */ -#define LL_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl *) +#define LL_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) #define IOC_OBD_STATFS _IOWR('f', 164, struct obd_statfs *) #define IOC_LOV_GETINFO _IOWR('f', 165, struct lov_user_mds_data *) #define LL_IOC_FLUSHCTX _IOW ('f', 166, long) diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index 456dee9..6283648 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -507,7 +507,7 @@ static inline void obd_ioctl_freedata(char *buf, int len) /* OBD_IOC_POLL_QUOTACHECK: See also LL_IOC_POLL_QUOTACHECK */ #define OBD_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) /* OBD_IOC_QUOTACTL: See also LL_IOC_QUOTACTL */ -#define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl *) +#define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) /* see also for ioctls 163-176 */ #define OBD_IOC_CHANGELOG_REG _IOW ('f', 177, struct obd_ioctl_data) #define OBD_IOC_CHANGELOG_DEREG _IOW ('f', 178, struct obd_ioctl_data) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 436e77e..b757927 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -1383,6 +1383,60 @@ out_free: OBD_FREE_PTR(check); RETURN(rc); } +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) + case LL_IOC_QUOTACTL_18: { + /* copy the old 1.x quota struct for internal use, then copy + * back into old format struct. For 1.8 compatibility. */ + struct if_quotactl_18 *qctl_18; + struct if_quotactl *qctl_20; + + OBD_ALLOC_PTR(qctl_18); + if (!qctl_18) + RETURN(-ENOMEM); + + OBD_ALLOC_PTR(qctl_20); + if (!qctl_20) + GOTO(out_quotactl_18, rc = -ENOMEM); + + if (cfs_copy_from_user(qctl_18, (void *)arg, sizeof(*qctl_18))) + GOTO(out_quotactl_20, rc = -ENOMEM); + + QCTL_COPY(qctl_20, qctl_18); + qctl_20->qc_idx = 0; + + /* XXX: dqb_valid was borrowed as a flag to mark that + * only mds quota is wanted */ + if (qctl_18->qc_cmd == Q_GETQUOTA && + qctl_18->qc_dqblk.dqb_valid) { + qctl_20->qc_valid = QC_MDTIDX; + qctl_20->qc_dqblk.dqb_valid = 0; + } else if (qctl_18->obd_uuid.uuid[0] != '\0') { + qctl_20->qc_valid = QC_UUID; + qctl_20->obd_uuid = qctl_18->obd_uuid; + } else { + qctl_20->qc_valid = QC_GENERAL; + } + + rc = quotactl_ioctl(sbi, qctl_20); + + if (rc == 0) { + QCTL_COPY(qctl_18, qctl_20); + qctl_18->obd_uuid = qctl_20->obd_uuid; + + if (cfs_copy_to_user((void *)arg, qctl_18, + sizeof(*qctl_18))) + rc = -EFAULT; + } + + out_quotactl_20: + OBD_FREE_PTR(qctl_20); + out_quotactl_18: + OBD_FREE_PTR(qctl_18); + RETURN(rc); + } +#else +#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" +#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) */ case LL_IOC_QUOTACTL: { struct if_quotactl *qctl; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index f14da0a..67c670d 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1336,4 +1336,23 @@ static inline int ll_file_nolock(const struct file *file) return ((fd->fd_flags & LL_FILE_IGNORE_LOCK) || (ll_i2sbi(inode)->ll_flags & LL_SBI_NOLCK)); } + +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) +/* Compatibility for old (1.8) compiled userspace quota code */ +struct if_quotactl_18 { + __u32 qc_cmd; + __u32 qc_type; + __u32 qc_id; + __u32 qc_stat; + struct obd_dqinfo qc_dqinfo; + struct obd_dqblk qc_dqblk; + char obd_type[16]; + struct obd_uuid obd_uuid; +}; +#define LL_IOC_QUOTACTL_18 _IOWR('f', 162, struct if_quotactl_18 *) +/* End compatibility for old (1.8) compiled userspace quota code */ +#else +#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" +#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) */ + #endif /* LLITE_INTERNAL_H */ -- 1.8.3.1