Whamcloud - gitweb
LU-6401 uapi: turn lustre_ioctl.h into a proper UAPI header
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 2b2bae8..6764367 100644 (file)
 #endif
 #include <poll.h>
 
+#include <libcfs/util/ioctl.h>
 #include <libcfs/util/param.h>
 #include <libcfs/util/string.h>
 #include <lnet/lnetctl.h>
 #include <lustre/lustreapi.h>
 #include <lustre/lustre_ostid.h>
-#include <lustre_ioctl.h>
+#include <linux/lustre_ioctl.h>
 #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,