Whamcloud - gitweb
LU-540 quota: add compatibility for 1.8 userspace
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 27 Jul 2011 08:30:19 +0000 (02:30 -0600)
committerOleg Drokin <green@whamcloud.com>
Tue, 9 Aug 2011 14:42:14 +0000 (10:42 -0400)
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 <adilger@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/1152
Tested-by: Hudson
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre/lustre_user.h
lustre/include/lustre_lib.h
lustre/llite/dir.c
lustre/llite/llite_internal.h

index d0da8a8..3a7f330 100644 (file)
@@ -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)
index 456dee9..6283648 100644 (file)
@@ -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 <lustre/lustre_user.h> 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)
index 436e77e..b757927 100644 (file)
@@ -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;
 
index f14da0a..67c670d 100644 (file)
@@ -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 */