From: James Simmons Date: Sat, 8 Apr 2017 19:44:32 +0000 (-0400) Subject: LU-6401 uapi: turn lustre_ioctl.h into a proper UAPI header X-Git-Tag: 2.9.57~30 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b8afd0dcd3834a88b0ceead18c71d37052a00a8d LU-6401 uapi: turn lustre_ioctl.h into a proper UAPI header Remove all the complex inline functions. Move all the user land specific functions into the userland library. Unwind the kernel specific functions and move obd_ioctl_is_valid() into the kernel source file linux-module.c. Change-Id: I91e69a21231f3effd23b191b6df9b5515a2ccc64 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/24568 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Ben Evans Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/Makefile.am b/lustre/include/Makefile.am index 32f6680..44ff84d 100644 --- a/lustre/include/Makefile.am +++ b/lustre/include/Makefile.am @@ -61,7 +61,6 @@ EXTRA_DIST = \ lustre_idmap.h \ lustre_import.h \ lustre_intent.h \ - lustre_ioctl.h \ lustre_lfsck.h \ lustre_lib.h \ lustre_linkea.h \ diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 6b13669..a79c321 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -128,7 +128,6 @@ extern int llapi_get_poollist(const char *name, char **poollist, int list_size, extern int llapi_get_poolmembers(const char *poolname, char **members, int list_size, char *buffer, int buffer_size); extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum); -#define HAVE_LLAPI_FILE_LOOKUP extern int llapi_file_lookup(int dirfd, const char *name); #define VERBOSE_COUNT 0x1 diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 38c2c49..991586a 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1710,6 +1710,7 @@ int server_name2index(const char *svname, __u32 *idx, const char **endptr); /* linux-module.c */ extern struct miscdevice obd_psdev; +int obd_ioctl_getdata(char **buf, int *len, void __user *arg); int class_procfs_init(void); int class_procfs_clean(void); diff --git a/lustre/include/uapi/linux/Makefile.am b/lustre/include/uapi/linux/Makefile.am index a5ae04a..09d3349 100644 --- a/lustre/include/uapi/linux/Makefile.am +++ b/lustre/include/uapi/linux/Makefile.am @@ -30,4 +30,5 @@ # EXTRA_DIST = \ - lustre_disk.h + lustre_disk.h \ + lustre_ioctl.h diff --git a/lustre/include/lustre_ioctl.h b/lustre/include/uapi/linux/lustre_ioctl.h similarity index 52% rename from lustre/include/lustre_ioctl.h rename to lustre/include/uapi/linux/lustre_ioctl.h index fa63359..2e8ee29 100644 --- a/lustre/include/lustre_ioctl.h +++ b/lustre/include/uapi/linux/lustre_ioctl.h @@ -25,27 +25,24 @@ * * Copyright (c) 2014, 2016, Intel Corporation. */ -#ifndef LUSTRE_IOCTL_H_ -#define LUSTRE_IOCTL_H_ +#ifndef _UAPI_LUSTRE_IOCTL_H +#define _UAPI_LUSTRE_IOCTL_H +#include +#include #include -#include #include -#ifdef __KERNEL__ -# include -# include -# include -#else /* __KERNEL__ */ -# include -# include -#include -#endif /* !__KERNEL__ */ - #if !defined(__KERNEL__) && !defined(LUSTRE_UTILS) # error This file is for Lustre internal use only. #endif +/* Handle older distros */ +#ifndef __ALIGN_KERNEL +# define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +# define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#endif + enum md_echo_cmd { ECHO_MD_CREATE = 1, /* Open/Create file on MDT */ ECHO_MD_MKDIR = 2, /* Mkdir on MDT */ @@ -122,212 +119,23 @@ struct obd_ioctl_hdr { static inline __u32 obd_ioctl_packlen(struct obd_ioctl_data *data) { - __u32 len = cfs_size_round(sizeof(*data)); + __u32 len = __ALIGN_KERNEL(sizeof(*data), 8); - len += cfs_size_round(data->ioc_inllen1); - len += cfs_size_round(data->ioc_inllen2); - len += cfs_size_round(data->ioc_inllen3); - len += cfs_size_round(data->ioc_inllen4); + len += __ALIGN_KERNEL(data->ioc_inllen1, 8); + len += __ALIGN_KERNEL(data->ioc_inllen2, 8); + len += __ALIGN_KERNEL(data->ioc_inllen3, 8); + len += __ALIGN_KERNEL(data->ioc_inllen4, 8); return len; } -static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) -{ - if (data->ioc_len > (1 << 30)) { - CERROR("OBD ioctl: ioc_len larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inllen1 > (1 << 30)) { - CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inllen2 > (1 << 30)) { - CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inllen3 > (1 << 30)) { - CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inllen4 > (1 << 30)) { - CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n"); - return 1; - } - - if (data->ioc_inlbuf1 != NULL && data->ioc_inllen1 == 0) { - CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_inlbuf2 != NULL && data->ioc_inllen2 == 0) { - CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_inlbuf3 != NULL && data->ioc_inllen3 == 0) { - CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_inlbuf4 != NULL && data->ioc_inllen4 == 0) { - CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_pbuf1 != NULL && data->ioc_plen1 == 0) { - CERROR("OBD ioctl: pbuf1 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_pbuf2 != NULL && data->ioc_plen2 == 0) { - CERROR("OBD ioctl: pbuf2 pointer but 0 length\n"); - return 1; - } - - if (data->ioc_pbuf1 == NULL && data->ioc_plen1 != 0) { - CERROR("OBD ioctl: plen1 set but NULL pointer\n"); - return 1; - } - - if (data->ioc_pbuf2 == NULL && data->ioc_plen2 != 0) { - CERROR("OBD ioctl: plen2 set but NULL pointer\n"); - return 1; - } - - if (obd_ioctl_packlen(data) > data->ioc_len) { - CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n", - obd_ioctl_packlen(data), data->ioc_len); - return 1; - } - - return 0; -} - -#ifdef __KERNEL__ - -int obd_ioctl_getdata(char **buf, int *len, void __user *arg); -int obd_ioctl_popdata(void __user *arg, void *data, int len); - -static inline void obd_ioctl_freedata(char *buf, size_t len) -{ - ENTRY; - - OBD_FREE_LARGE(buf, len); - EXIT; -} - -#else /* __KERNEL__ */ - -static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, - int max_len) -{ - char *ptr; - struct obd_ioctl_data *overlay; - - data->ioc_len = obd_ioctl_packlen(data); - data->ioc_version = OBD_IOCTL_VERSION; - - if (*pbuf != NULL && data->ioc_len > max_len) { - fprintf(stderr, "pbuf = %p, ioc_len = %u, max_len = %d\n", - *pbuf, data->ioc_len, max_len); - return -EINVAL; - } - - if (*pbuf == NULL) - *pbuf = malloc(data->ioc_len); - - if (*pbuf == NULL) - return -ENOMEM; - - overlay = (struct obd_ioctl_data *)*pbuf; - memcpy(*pbuf, data, sizeof(*data)); - - ptr = overlay->ioc_bulk; - if (data->ioc_inlbuf1) { - memcpy(ptr, data->ioc_inlbuf1, data->ioc_inllen1); - ptr += cfs_size_round(data->ioc_inllen1); - } - - if (data->ioc_inlbuf2) { - memcpy(ptr, data->ioc_inlbuf2, data->ioc_inllen2); - ptr += cfs_size_round(data->ioc_inllen2); - } - - if (data->ioc_inlbuf3) { - memcpy(ptr, data->ioc_inlbuf3, data->ioc_inllen3); - ptr += cfs_size_round(data->ioc_inllen3); - } - - if (data->ioc_inlbuf4) { - memcpy(ptr, data->ioc_inlbuf4, data->ioc_inllen4); - ptr += cfs_size_round(data->ioc_inllen4); - } - - if (obd_ioctl_is_invalid(overlay)) { - fprintf(stderr, "invalid ioctl data: ioc_len = %u, " - "max_len = %d\n", - data->ioc_len, max_len); - return -EINVAL; - } - - return 0; -} - -static inline int -obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) -{ - char *ptr; - struct obd_ioctl_data *overlay; - - if (pbuf == NULL) - return 1; - - overlay = (struct obd_ioctl_data *)pbuf; - - /* Preserve the caller's buffer pointers */ - overlay->ioc_inlbuf1 = data->ioc_inlbuf1; - overlay->ioc_inlbuf2 = data->ioc_inlbuf2; - overlay->ioc_inlbuf3 = data->ioc_inlbuf3; - overlay->ioc_inlbuf4 = data->ioc_inlbuf4; - - memcpy(data, pbuf, sizeof(*data)); - - ptr = overlay->ioc_bulk; - if (data->ioc_inlbuf1) { - memcpy(data->ioc_inlbuf1, ptr, data->ioc_inllen1); - ptr += cfs_size_round(data->ioc_inllen1); - } - - if (data->ioc_inlbuf2) { - memcpy(data->ioc_inlbuf2, ptr, data->ioc_inllen2); - ptr += cfs_size_round(data->ioc_inllen2); - } - - if (data->ioc_inlbuf3) { - memcpy(data->ioc_inlbuf3, ptr, data->ioc_inllen3); - ptr += cfs_size_round(data->ioc_inllen3); - } - - if (data->ioc_inlbuf4) { - memcpy(data->ioc_inlbuf4, ptr, data->ioc_inllen4); - ptr += cfs_size_round(data->ioc_inllen4); - } - - return 0; -} - -#endif /* !__KERNEL__ */ - -/* OBD_IOC_DATA_TYPE is only for compatibility reasons with older +/* + * OBD_IOC_DATA_TYPE is only for compatibility reasons with older * Linux Lustre user tools. New ioctls should NOT use this macro as * the ioctl "size". Instead the ioctl should get a "size" argument * which is the actual data type used by the ioctl, to ensure the - * ioctl interface is versioned correctly. */ + * ioctl interface is versioned correctly. + */ #define OBD_IOC_DATA_TYPE long /* IOC_LDLM_TEST _IOWR('f', 40, long) */ @@ -336,16 +144,16 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) /* IOC_LDLM_REGRESS_STOP _IOWR('f', 43, long) */ #define OBD_IOC_CREATE _IOWR('f', 101, OBD_IOC_DATA_TYPE) -#define OBD_IOC_DESTROY _IOW ('f', 104, OBD_IOC_DATA_TYPE) +#define OBD_IOC_DESTROY _IOW('f', 104, OBD_IOC_DATA_TYPE) /* OBD_IOC_PREALLOCATE _IOWR('f', 105, OBD_IOC_DATA_TYPE) */ -#define OBD_IOC_SETATTR _IOW ('f', 107, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SETATTR _IOW('f', 107, OBD_IOC_DATA_TYPE) #define OBD_IOC_GETATTR _IOWR('f', 108, OBD_IOC_DATA_TYPE) #define OBD_IOC_READ _IOWR('f', 109, OBD_IOC_DATA_TYPE) #define OBD_IOC_WRITE _IOWR('f', 110, OBD_IOC_DATA_TYPE) #define OBD_IOC_STATFS _IOWR('f', 113, OBD_IOC_DATA_TYPE) -#define OBD_IOC_SYNC _IOW ('f', 114, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SYNC _IOW('f', 114, OBD_IOC_DATA_TYPE) /* OBD_IOC_READ2 _IOWR('f', 115, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_FORMAT _IOWR('f', 116, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_PARTITION _IOWR('f', 117, OBD_IOC_DATA_TYPE) */ @@ -359,21 +167,21 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) #define OBD_IOC_NAME2DEV _IOWR('f', 127, OBD_IOC_DATA_TYPE) #define OBD_IOC_UUID2DEV _IOWR('f', 130, OBD_IOC_DATA_TYPE) #define OBD_IOC_GETNAME _IOWR('f', 131, OBD_IOC_DATA_TYPE) -#define OBD_IOC_GETMDNAME _IOR ('f', 131, char[MAX_OBD_NAME]) +#define OBD_IOC_GETMDNAME _IOR('f', 131, char[MAX_OBD_NAME]) #define OBD_IOC_GETDTNAME OBD_IOC_GETNAME #define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE) -#define OBD_IOC_CLIENT_RECOVER _IOW ('f', 133, OBD_IOC_DATA_TYPE) -#define OBD_IOC_PING_TARGET _IOW ('f', 136, OBD_IOC_DATA_TYPE) +#define OBD_IOC_CLIENT_RECOVER _IOW('f', 133, OBD_IOC_DATA_TYPE) +#define OBD_IOC_PING_TARGET _IOW('f', 136, OBD_IOC_DATA_TYPE) /* OBD_IOC_DEC_FS_USE_COUNT _IO('f', 139) */ -#define OBD_IOC_NO_TRANSNO _IOW ('f', 140, OBD_IOC_DATA_TYPE) -#define OBD_IOC_SET_READONLY _IOW ('f', 141, OBD_IOC_DATA_TYPE) -#define OBD_IOC_ABORT_RECOVERY _IOR ('f', 142, OBD_IOC_DATA_TYPE) +#define OBD_IOC_NO_TRANSNO _IOW('f', 140, OBD_IOC_DATA_TYPE) +#define OBD_IOC_SET_READONLY _IOW('f', 141, OBD_IOC_DATA_TYPE) +#define OBD_IOC_ABORT_RECOVERY _IOR('f', 142, OBD_IOC_DATA_TYPE) /* OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE) */ #define OBD_GET_VERSION _IOWR('f', 144, OBD_IOC_DATA_TYPE) /* OBD_IOC_GSS_SUPPORT _IOWR('f', 145, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_CLOSE_UUID _IOWR('f', 147, OBD_IOC_DATA_TYPE) */ -/* OBD_IOC_CHANGELOG_SEND _IOW ('f', 148, OBD_IOC_DATA_TYPE) */ +/* OBD_IOC_CHANGELOG_SEND _IOW('f', 148, OBD_IOC_DATA_TYPE) */ #define OBD_IOC_GETDEVICE _IOWR('f', 149, OBD_IOC_DATA_TYPE) #define OBD_IOC_FID2PATH _IOWR('f', 150, OBD_IOC_DATA_TYPE) /* lustre/lustre_user.h 151-153 */ @@ -381,13 +189,13 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) /* OBD_IOC_LOV_GETSTRIPE 155 LL_IOC_LOV_GETSTRIPE */ /* OBD_IOC_LOV_SETEA 156 LL_IOC_LOV_SETEA */ /* lustre/lustre_user.h 157-159 */ -/* OBD_IOC_QUOTACHECK _IOW ('f', 160, int) */ -/* OBD_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) */ +/* OBD_IOC_QUOTACHECK _IOW('f', 160, int) */ +/* OBD_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *) */ #define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) /* lustre/lustre_user.h 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) -#define OBD_IOC_CHANGELOG_CLEAR _IOW ('f', 179, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_REG _IOW('f', 177, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_DEREG _IOW('f', 178, struct obd_ioctl_data) +#define OBD_IOC_CHANGELOG_CLEAR _IOW('f', 179, struct obd_ioctl_data) /* OBD_IOC_RECORD _IOWR('f', 180, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_ENDRECORD _IOWR('f', 181, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_PARSE _IOWR('f', 182, OBD_IOC_DATA_TYPE) */ @@ -395,7 +203,7 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) #define OBD_IOC_PROCESS_CFG _IOWR('f', 184, OBD_IOC_DATA_TYPE) /* OBD_IOC_DUMP_LOG _IOWR('f', 185, OBD_IOC_DATA_TYPE) */ /* OBD_IOC_CLEAR_LOG _IOWR('f', 186, OBD_IOC_DATA_TYPE) */ -#define OBD_IOC_PARAM _IOW ('f', 187, OBD_IOC_DATA_TYPE) +#define OBD_IOC_PARAM _IOW('f', 187, OBD_IOC_DATA_TYPE) #define OBD_IOC_POOL _IOWR('f', 188, OBD_IOC_DATA_TYPE) #define OBD_IOC_REPLACE_NIDS _IOWR('f', 189, OBD_IOC_DATA_TYPE) @@ -415,14 +223,14 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) #define OBD_IOC_LCFG_FORK _IOWR('f', 208, OBD_IOC_DATA_TYPE) #define OBD_IOC_LCFG_ERASE _IOWR('f', 209, OBD_IOC_DATA_TYPE) -#define OBD_IOC_GET_OBJ_VERSION _IOR ('f', 210, OBD_IOC_DATA_TYPE) +#define OBD_IOC_GET_OBJ_VERSION _IOR('f', 210, OBD_IOC_DATA_TYPE) /* lustre/lustre_user.h 212-217 */ -#define OBD_IOC_GET_MNTOPT _IOW ('f', 220, mntopt_t) -#define OBD_IOC_ECHO_MD _IOR ('f', 221, struct obd_ioctl_data) +#define OBD_IOC_GET_MNTOPT _IOW('f', 220, mntopt_t) +#define OBD_IOC_ECHO_MD _IOR('f', 221, struct obd_ioctl_data) #define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data) #define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE) -#define OBD_IOC_STOP_LFSCK _IOW ('f', 231, OBD_IOC_DATA_TYPE) +#define OBD_IOC_STOP_LFSCK _IOW('f', 231, OBD_IOC_DATA_TYPE) #define OBD_IOC_QUERY_LFSCK _IOR('f', 232, struct obd_ioctl_data) /* lustre/lustre_user.h 240-249 */ /* LIBCFS_IOC_DEBUG_MASK 250 */ @@ -431,4 +239,4 @@ obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) #define IOC_OSC_SET_ACTIVE _IOWR('h', 21, void *) -#endif /* LUSTRE_IOCTL_H_ */ +#endif /* _UAPI_LUSTRE_IOCTL_H */ diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index ec86fa0..67c52fe 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -52,7 +52,7 @@ #include #include -#include +#include #include #include #include @@ -1219,7 +1219,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) GOTO(out_free, rc); } out_free: - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); return rc; } case LL_IOC_LMV_SETSTRIPE: { @@ -1265,7 +1265,7 @@ out_free: #endif rc = ll_dir_setdirstripe(dentry, lum, filename, mode); lmv_out_free: - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); RETURN(rc); } @@ -1754,7 +1754,7 @@ out_hur: rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1); migrate_free: - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); RETURN(rc); } diff --git a/lustre/llite/file.c b/lustre/llite/file.c index bf8e826..e829c83 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -47,7 +47,7 @@ #endif #include -#include +#include #include #include "cl_object.h" diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index bbf5c3e..3307d2c 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -48,7 +48,7 @@ #endif #include -#include +#include #include #include #include @@ -2343,9 +2343,8 @@ int ll_obd_statfs(struct inode *inode, void __user *arg) if (rc) GOTO(out_statfs, rc); out_statfs: - if (buf) - obd_ioctl_freedata(buf, len); - return rc; + OBD_FREE_LARGE(buf, len); + return rc; } int ll_process_config(struct lustre_cfg *lcfg) diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 5be99ee..78160ad 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include "lmv_internal.h" diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 985b720..d5a9f7a 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include #include #include @@ -1101,17 +1101,17 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data = (struct obd_ioctl_data *)buf; if (sizeof(*desc) > data->ioc_inllen1) { - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); RETURN(-EINVAL); } if (sizeof(uuidp->uuid) * count > data->ioc_inllen2) { - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); RETURN(-EINVAL); } if (sizeof(__u32) * count > data->ioc_inllen3) { - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); RETURN(-EINVAL); } @@ -1130,7 +1130,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (copy_to_user(uarg, buf, len)) rc = -EFAULT; - obd_ioctl_freedata(buf, len); + OBD_FREE_LARGE(buf, len); break; } case OBD_IOC_QUOTACTL: { diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 418453a..95add74 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 45141822..cbe8756 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index e96a17b..c0d1b72 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lustre/mgs/mgs_barrier.c b/lustre/mgs/mgs_barrier.c index db406a9..13841b1 100644 --- a/lustre/mgs/mgs_barrier.c +++ b/lustre/mgs/mgs_barrier.c @@ -30,7 +30,7 @@ #define DEBUG_SUBSYSTEM S_MGS #define D_MGS D_CONFIG -#include +#include #include #include diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 8c398a2..1c73276 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 400a3ce..895a1e2 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -42,7 +42,7 @@ #define D_MGS D_CONFIG #include -#include +#include #include #include #include diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index f644a3f..75c5dab 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -50,7 +50,7 @@ # include # include #endif /* HAVE_SERVER_SUPPORT */ -#include +#include #include "llog_internal.h" #ifdef CONFIG_PROC_FS @@ -270,8 +270,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) memcpy(data->ioc_bulk, LUSTRE_VERSION_STRING, strlen(LUSTRE_VERSION_STRING) + 1); - err = obd_ioctl_popdata((void __user *)arg, data, len); - if (err) + if (copy_to_user((void __user *)arg, data, len)) err = -EFAULT; GOTO(out, err); @@ -287,9 +286,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) if (dev < 0) GOTO(out, err = -EINVAL); - err = obd_ioctl_popdata((void __user *)arg, data, - sizeof(*data)); - if (err) + if (copy_to_user((void __user *)arg, data, sizeof(*data))) err = -EFAULT; GOTO(out, err); } @@ -322,9 +319,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, dev); - err = obd_ioctl_popdata((void __user *)arg, data, - sizeof(*data)); - if (err) + if (copy_to_user((void __user *)arg, data, sizeof(*data))) err = -EFAULT; GOTO(out, err); } @@ -359,9 +354,11 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) (int)index, status, obd->obd_type->typ_name, obd->obd_name, obd->obd_uuid.uuid, atomic_read(&obd->obd_refcount)); - err = obd_ioctl_popdata((void __user *)arg, data, len); - GOTO(out, err = 0); + if (copy_to_user((void __user *)arg, data, len)) + err = -EFAULT; + + GOTO(out, err); } } @@ -407,17 +404,15 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) if (err) GOTO(out, err); - err = obd_ioctl_popdata((void __user *)arg, data, len); - if (err) + if (copy_to_user((void __user *)arg, data, len)) err = -EFAULT; GOTO(out, err); } } - out: - if (buf) - obd_ioctl_freedata(buf, len); - RETURN(err); +out: + OBD_FREE_LARGE(buf, len); + RETURN(err); } /* class_handle_ioctl */ #define OBD_INIT_CHECK diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index 72beddc..6cee4d7 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -68,9 +68,85 @@ #include #include #include -#include +#include #include +static int obd_ioctl_is_invalid(struct obd_ioctl_data *data) +{ + if (data->ioc_len > BIT(30)) { + CERROR("OBD ioctl: ioc_len larger than 1<<30\n"); + return 1; + } + + if (data->ioc_inllen1 > BIT(30)) { + CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n"); + return 1; + } + + if (data->ioc_inllen2 > BIT(30)) { + CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n"); + return 1; + } + + if (data->ioc_inllen3 > BIT(30)) { + CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n"); + return 1; + } + + if (data->ioc_inllen4 > BIT(30)) { + CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n"); + return 1; + } + + if (data->ioc_inlbuf1 && data->ioc_inllen1 == 0) { + CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n"); + return 1; + } + + if (data->ioc_inlbuf2 && data->ioc_inllen2 == 0) { + CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n"); + return 1; + } + + if (data->ioc_inlbuf3 && data->ioc_inllen3 == 0) { + CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n"); + return 1; + } + + if (data->ioc_inlbuf4 && data->ioc_inllen4 == 0) { + CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n"); + return 1; + } + + if (data->ioc_pbuf1 && data->ioc_plen1 == 0) { + CERROR("OBD ioctl: pbuf1 pointer but 0 length\n"); + return 1; + } + + if (data->ioc_pbuf2 && data->ioc_plen2 == 0) { + CERROR("OBD ioctl: pbuf2 pointer but 0 length\n"); + return 1; + } + + if (!data->ioc_pbuf1 && data->ioc_plen1 != 0) { + CERROR("OBD ioctl: plen1 set but NULL pointer\n"); + return 1; + } + + if (!data->ioc_pbuf2 && data->ioc_plen2 != 0) { + CERROR("OBD ioctl: plen2 set but NULL pointer\n"); + return 1; + } + + if (obd_ioctl_packlen(data) > data->ioc_len) { + CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n", + obd_ioctl_packlen(data), data->ioc_len); + return 1; + } + + return 0; +} + /* buffer MUST be at least the size of obd_ioctl_hdr */ int obd_ioctl_getdata(char **buf, int *len, void __user *arg) { @@ -145,15 +221,6 @@ int obd_ioctl_getdata(char **buf, int *len, void __user *arg) } EXPORT_SYMBOL(obd_ioctl_getdata); -int obd_ioctl_popdata(void __user *arg, void *data, int len) -{ - int err; - ENTRY; - - err = copy_to_user(arg, data, len) ? -EFAULT : 0; - RETURN(err); -} - /* opening /dev/obd */ static int obd_class_open(struct inode * inode, struct file * file) { diff --git a/lustre/obdclass/llog_ioctl.c b/lustre/obdclass/llog_ioctl.c index ad53938..09934e7 100644 --- a/lustre/obdclass/llog_ioctl.c +++ b/lustre/obdclass/llog_ioctl.c @@ -33,7 +33,7 @@ #define DEBUG_SUBSYSTEM S_LOG #include -#include +#include #include #include "llog_internal.h" diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 4def961..07b3ab0 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lustre/obdclass/obd_mount_server.c b/lustre/obdclass/obd_mount_server.c index 3c645c9..e3e675e 100644 --- a/lustre/obdclass/obd_mount_server.c +++ b/lustre/obdclass/obd_mount_server.c @@ -55,7 +55,7 @@ #include #include -#include +#include #include #include #include diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 1c585d6..9f383f8 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_SERVER_SUPPORT # include diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index cd9f673..5e35d8a 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -46,7 +46,7 @@ #include #include "ofd_internal.h" #include -#include +#include #include #include #include diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 3c4150a..fa08096 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lustre/osp/osp_dev.c b/lustre/osp/osp_dev.c index 108c385..a94d533 100644 --- a/lustre/osp/osp_dev.c +++ b/lustre/osp/osp_dev.c @@ -72,7 +72,7 @@ #include -#include +#include #include #include #include diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index fcd9ae0..0b6a874 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -97,6 +97,8 @@ group_lock_test_LDADD=$(LIBLUSTREAPI) llapi_fid_test_LDADD=$(LIBLUSTREAPI) sendfile_grouplock_LDADD=$(LIBLUSTREAPI) swap_lock_test_LDADD=$(LIBLUSTREAPI) +statmany_LDADD=$(LIBLUSTREAPI) +statone_LDADD=$(LIBLUSTREAPI) it_test_LDADD=$(LIBCFS) rwv_LDADD=$(LIBCFS) diff --git a/lustre/tests/mpi/mdsrate.c b/lustre/tests/mpi/mdsrate.c index 9040656..cdfab50 100644 --- a/lustre/tests/mpi/mdsrate.c +++ b/lustre/tests/mpi/mdsrate.c @@ -227,42 +227,6 @@ sigalrm_handler(int signum) alarm_caught++; } -/* HAVE_LLAPI_FILE_LOOKUP is defined by liblustreapi.h if this function is - * defined therein. Otherwise we can do the equivalent operation via ioctl - * if we have access to a complete lustre build tree to get the various - * definitions - then compile with USE_MDC_LOOKUP defined. */ -#if defined(HAVE_LLAPI_FILE_LOOKUP) -#define HAVE_MDC_LOOKUP -#elif defined(USE_MDC_LOOKUP) -#include -#include - -int llapi_file_lookup(int dirfd, const char *name) -{ - struct obd_ioctl_data data = { 0 }; - char rawbuf[8192]; - char *buf = rawbuf; - int rc; - - if (dirfd < 0 || name == NULL) - return -EINVAL; - - data.ioc_version = OBD_IOCTL_VERSION; - data.ioc_len = sizeof(data); - data.ioc_inlbuf1 = name; - data.ioc_inllen1 = strlen(name) + 1; - - rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); - if (rc) { - fatal(myrank, "ioctl_pack failed: rc = %d\n", rc); - return rc; - } - - return ioctl(fd, IOC_MDC_LOOKUP, buf); -} -#define HAVE_MDC_LOOKUP -#endif - static void process_args(int argc, char *argv[]) { @@ -290,9 +254,7 @@ process_args(int argc, char *argv[]) case OPEN: openflags &= ~(O_CREAT|O_EXCL); case CREATE: -#ifdef HAVE_MDC_LOOKUP case LOOKUP: -#endif case MKNOD: case STAT: case UNLINK: @@ -532,9 +494,7 @@ process_args(int argc, char *argv[]) (order == RANDOM) ? "random_order" : "readdir_order"); } else { usage(stderr, "one --create, --mknod, --open, --stat," -#ifdef HAVE_MDC_LOOKUP " --lookup," -#endif " --unlink or --setxattr must be specifed."); } @@ -782,7 +742,6 @@ main(int argc, char *argv[]) dmesg("%d: created %d files, last file '%s'.\n", myrank, nops, filename); break; -#ifdef HAVE_MDC_LOOKUP case LOOKUP: fd = open(dir, O_RDONLY); if (fd < 0) { @@ -804,7 +763,6 @@ main(int argc, char *argv[]) DISPLAY_PROGRESS(); } break; -#endif case MKNOD: for (; begin <= end && !alarm_caught; begin += dirthreads) { snprintf(filename, sizeof(filename), filefmt, begin); diff --git a/lustre/tests/statmany.c b/lustre/tests/statmany.c index 4f83434..8a4f82a 100644 --- a/lustre/tests/statmany.c +++ b/lustre/tests/statmany.c @@ -41,9 +41,8 @@ #include #include #include -#include -#include +#include struct option longopts[] = { { .name = "lookup", .has_arg = no_argument, .val = 'l' }, @@ -179,29 +178,15 @@ int main(int argc, char ** argv) break; } } else if (mode == 'l') { - struct obd_ioctl_data data; - char rawbuf[8192]; - char *buf = rawbuf; - int max = sizeof(rawbuf); - - memset(&data, 0, sizeof(data)); - data.ioc_version = OBD_IOCTL_VERSION; - data.ioc_len = sizeof(data); - if (offset >= 0) - data.ioc_inlbuf1 = filename + offset; - else - data.ioc_inlbuf1 = filename; - data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1; - - if (obd_ioctl_pack(&data, &buf, max)) { - printf("ioctl_pack failed.\n"); - break; - } + char *name = filename; - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); + if (offset >= 0) + name += offset; + + rc = llapi_file_lookup(fd, name); if (rc < 0) { - printf("ioctl(%s) error: %s\n", filename, - strerror(errno)); + printf("llapi_file_lookup for (%s) error: %s\n", + filename, strerror(errno)); break; } } diff --git a/lustre/tests/statone.c b/lustre/tests/statone.c index 1c223b7..0f11d5d 100644 --- a/lustre/tests/statone.c +++ b/lustre/tests/statone.c @@ -35,18 +35,16 @@ #include #include #include -#include #include #include #include -#include +#include int main(int argc, char **argv) { - struct obd_ioctl_data data = { 0 }; - char rawbuf[8192], parent[4096], *buf = rawbuf, *base, *t; - int max = sizeof(rawbuf), fd, offset, rc; + char parent[4096], *base, *name, *t; + int fd, offset, rc; if (argc != 2) { printf("usage: %s filename\n", argv[0]); @@ -69,23 +67,14 @@ int main(int argc, char **argv) exit(errno); } - data.ioc_version = OBD_IOCTL_VERSION; - data.ioc_len = sizeof(data); + name = base; if (offset >= 0) - data.ioc_inlbuf1 = base + offset + 2; - else - data.ioc_inlbuf1 = base; - data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1; - - if (obd_ioctl_pack(&data, &buf, max)) { - printf("ioctl_pack failed.\n"); - exit(1); - } - - rc = ioctl(fd, IOC_MDC_LOOKUP, buf); + name += offset + 2; + + rc = llapi_file_lookup(fd, name); if (rc < 0) { - printf("ioctl(%s/%s) error: %s\n", parent, - data.ioc_inlbuf1, strerror(errno)); + printf("llapi_file_lookup (%s/%s) error: %s\n", parent, + name, strerror(errno)); exit(errno); } diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 2b2bae8..6764367 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -68,12 +68,13 @@ #endif #include +#include #include #include #include #include #include -#include +#include #include "lustreapi_internal.h" static int llapi_msg_level = LLAPI_MSG_MAX; @@ -253,6 +254,95 @@ int llapi_parse_size(const char *optarg, unsigned long long *size, return 0; } +int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, int max_len) +{ + struct obd_ioctl_data *overlay; + char *ptr; + + data->ioc_len = obd_ioctl_packlen(data); + data->ioc_version = OBD_IOCTL_VERSION; + + if (*pbuf != NULL && data->ioc_len > max_len) { + fprintf(stderr, "pbuf = %p, ioc_len = %u, max_len = %d\n", + *pbuf, data->ioc_len, max_len); + return -EINVAL; + } + + if (*pbuf == NULL) + *pbuf = malloc(data->ioc_len); + + if (*pbuf == NULL) + return -ENOMEM; + + overlay = (struct obd_ioctl_data *)*pbuf; + memcpy(*pbuf, data, sizeof(*data)); + + ptr = overlay->ioc_bulk; + if (data->ioc_inlbuf1) { + memcpy(ptr, data->ioc_inlbuf1, data->ioc_inllen1); + ptr += cfs_size_round(data->ioc_inllen1); + } + + if (data->ioc_inlbuf2) { + memcpy(ptr, data->ioc_inlbuf2, data->ioc_inllen2); + ptr += cfs_size_round(data->ioc_inllen2); + } + + if (data->ioc_inlbuf3) { + memcpy(ptr, data->ioc_inlbuf3, data->ioc_inllen3); + ptr += cfs_size_round(data->ioc_inllen3); + } + + if (data->ioc_inlbuf4) { + memcpy(ptr, data->ioc_inlbuf4, data->ioc_inllen4); + ptr += cfs_size_round(data->ioc_inllen4); + } + + return 0; +} + +int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len) +{ + struct obd_ioctl_data *overlay; + char *ptr; + + if (pbuf == NULL) + return 1; + + overlay = (struct obd_ioctl_data *)pbuf; + + /* Preserve the caller's buffer pointers */ + overlay->ioc_inlbuf1 = data->ioc_inlbuf1; + overlay->ioc_inlbuf2 = data->ioc_inlbuf2; + overlay->ioc_inlbuf3 = data->ioc_inlbuf3; + overlay->ioc_inlbuf4 = data->ioc_inlbuf4; + + memcpy(data, pbuf, sizeof(*data)); + + ptr = overlay->ioc_bulk; + if (data->ioc_inlbuf1) { + memcpy(data->ioc_inlbuf1, ptr, data->ioc_inllen1); + ptr += cfs_size_round(data->ioc_inllen1); + } + + if (data->ioc_inlbuf2) { + memcpy(data->ioc_inlbuf2, ptr, data->ioc_inllen2); + ptr += cfs_size_round(data->ioc_inllen2); + } + + if (data->ioc_inlbuf3) { + memcpy(data->ioc_inlbuf3, ptr, data->ioc_inllen3); + ptr += cfs_size_round(data->ioc_inllen3); + } + + if (data->ioc_inlbuf4) { + memcpy(data->ioc_inlbuf4, ptr, data->ioc_inllen4); + ptr += cfs_size_round(data->ioc_inllen4); + } + + return 0; +} + /* XXX: llapi_xxx() functions return negative values upon failure */ int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset, diff --git a/lustre/utils/lsnapshot.c b/lustre/utils/lsnapshot.c index cf4f8f5..4fef5c0 100644 --- a/lustre/utils/lsnapshot.c +++ b/lustre/utils/lsnapshot.c @@ -43,7 +43,8 @@ #include #include -#include +#include +#include #include #include "obdctl.h" diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index 2e0b2bd..9c4ef3f 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -50,12 +50,13 @@ #include #include +#include #include #include #include #include #include -#include +#include #include #include diff --git a/lustre/utils/lustre_lfsck.c b/lustre/utils/lustre_lfsck.c index f399a32..94f0b2b 100644 --- a/lustre/utils/lustre_lfsck.c +++ b/lustre/utils/lustre_lfsck.c @@ -40,10 +40,11 @@ #include #include "obdctl.h" +#include "lustreapi_internal.h" #include #include -#include +#include /* Needs to be last to avoid clashes */ #include #include diff --git a/lustre/utils/lustreapi_internal.h b/lustre/utils/lustreapi_internal.h index e1deeb9..ba2a847 100644 --- a/lustre/utils/lustreapi_internal.h +++ b/lustre/utils/lustreapi_internal.h @@ -36,7 +36,13 @@ #ifndef _LUSTREAPI_INTERNAL_H_ #define _LUSTREAPI_INTERNAL_H_ +#include +#include + +#include #include + +#include #include #define WANT_PATH 0x1 @@ -53,6 +59,8 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index); int root_ioctl(const char *mdtname, int opc, void *data, int *mdtidxp, int want_error); +int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, int max_len); +int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len); int sattr_cache_get_defaults(const char *const fsname, const char *const pathname, unsigned int *scount, unsigned int *ssize, unsigned int *soffset); diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 0fdec22..b3b6a14 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -60,6 +60,7 @@ #include #include "obdctl.h" +#include "lustreapi_internal.h" #include #include #include @@ -69,7 +70,7 @@ #include #include #include -#include +#include #include #include