Whamcloud - gitweb
LU-13903 uapi: fixup UAPI headers for native Linux client. 64/44664/5
authorJames Simmons <jsimmons@infradead.org>
Sat, 4 Sep 2021 12:33:53 +0000 (08:33 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 17 Sep 2021 14:07:41 +0000 (14:07 +0000)
This covers all the UAPI problems outside of the user land
wiretest utility. One set of problems is build and the second is
that UAPI header definitions are either user land only or never
used to valid data going to or from user land.

1) Use UAPI header definitions to validate data send to or from
   kernel space. We check lum_hash_type using LMV_HASH_TYPE_MASK.
   This avoids a round trip to the server which will report back
   an error. The other case is we check the values returned for
   LL_IOC_HSM_ACTION. We keep the original behavior of passing
   unknown data to the user land application but add debug
   logging if the data looks corrupt to help track down bug
   issues.

2) We can use QIF_DQBLKSIZE* instead of Lustre specific values
   for our quota handling. QIF_DQBLKSIZE* is a Linux UAPI quota
   value.

3) The NOTIFY_GRACE_* macros are used only by user land. Move
   to lustreapi.h

4) A few of the UAPI definitions are used by utility code
   present on the client and the Lustre kernel server code; which
   are not sent over the wire. Handle these special cases. This
   covers the missing LCM_USER_MIRROR_FLAGS, LCME_TEMPLATE_FLAGS,
   and LQUOTA_* values. Once server code merges upstream we can
   clean this up.

5) lcfg_cmd2data() is server specific so in case of a client build
   we can have get_llog_event_name() just always return NULL.

6) Don't package OpenSFS UAPI headers when building for native
   Linux client.

Change-Id: I258ee917b005e438eb7c15fa6e0c4b72e9ea9d56
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/44664
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
12 files changed:
config/lustre-build.m4
lustre.spec.in
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/dir.c
lustre/llite/file.c
lustre/ptlrpc/wiretest.c
lustre/tests/mirror_io.c
lustre/utils/lfs.c
lustre/utils/obd.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 9169a80..01fba20 100644 (file)
@@ -148,7 +148,7 @@ AC_MSG_CHECKING([whether to build Linux kernel modules])
 AC_ARG_ENABLE([modules],
        AC_HELP_STRING([--disable-modules],
                [disable building of Lustre kernel modules]),
-       [], [
+       [ AC_DEFINE(HAVE_NATIVE_LINUX_CLIENT, 1, [support native Linux client])], [
                LC_TARGET_SUPPORTED([enable_modules="yes"],
                                    [enable_modules="no"])
        ])
index 0609232..6a8ceb7 100644 (file)
@@ -333,9 +333,6 @@ This package contains the header files needed for building additional
 applications against the Lustre / LNet utilities libraries.
 
 :> lustre-devel.files
-%if %{with lustre_modules}
-find . -type f -name '*.h' | grep uapi | sed 's/.*uapi\//usr\/include\//' >> lustre-devel.files
-%endif
 
 %if %{with lustre_tests}
 %package tests
@@ -630,8 +627,13 @@ echo '%{_libdir}/lustre/tests/lutf/*' >>lustre-tests.files
 %{_libdir}/liblustreapi.so
 %endif
 %{_includedir}/lustre
+%if %{with lustre_modules}
 %{_includedir}/linux/lnet
 %{_includedir}/linux/lustre
+%else
+%exclude %{_includedir}/linux/lnet
+%exclude %{_includedir}/linux/lustre
+%endif
 
 %files -f lustre.files
 %defattr(-,root,root)
index f1e8652..7ea4f8b 100644 (file)
@@ -1472,18 +1472,6 @@ struct ost_lvb {
  *   lquota data structures
  */
 
-#ifndef QUOTABLOCK_BITS
-# define QUOTABLOCK_BITS LUSTRE_QUOTABLOCK_BITS
-#endif
-
-#ifndef QUOTABLOCK_SIZE
-# define QUOTABLOCK_SIZE LUSTRE_QUOTABLOCK_SIZE
-#endif
-
-#ifndef toqb
-# define toqb lustre_stoqb
-#endif
-
 /* The lquota_id structure is an union of all the possible identifier types that
  * can be used with quota, this includes:
  * - 64-bit user ID
index c5f5c91..bb5d3e6 100644 (file)
@@ -1253,12 +1253,10 @@ static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen)
 
 /********* Quotas **********/
 
-#define LUSTRE_QUOTABLOCK_BITS 10
-#define LUSTRE_QUOTABLOCK_SIZE (1 << LUSTRE_QUOTABLOCK_BITS)
-
-static inline __u64 lustre_stoqb(__kernel_size_t space)
+/* From linux/fs/quota/quota.c */
+static inline __u64 toqb(__kernel_size_t space)
 {
-       return (space + LUSTRE_QUOTABLOCK_SIZE - 1) >> LUSTRE_QUOTABLOCK_BITS;
+       return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
 }
 
 #define Q_QUOTACHECK   0x800100 /* deprecated as of 2.4 */
index c0ceecc..9d81d58 100644 (file)
@@ -453,9 +453,10 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump,
                },
        };
        bool encrypt = false;
+       int hash_flags;
        int err;
-       ENTRY;
 
+       ENTRY;
        if (unlikely(!lmv_user_magic_supported(lump->lum_magic)))
                RETURN(-EINVAL);
 
@@ -494,6 +495,10 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump,
                                              LMV_HASH_TYPE_FNV_1A_64;
        }
 
+       hash_flags = lump->lum_hash_type & ~LMV_HASH_TYPE_MASK;
+       if (hash_flags & ~LMV_HASH_FLAG_KNOWN)
+               RETURN(-EINVAL);
+
        if (unlikely(!lmv_user_magic_supported(cpu_to_le32(lump->lum_magic))))
                lustre_swab_lmv_user_md(lump);
 
index 8d0452b..75a01e4 100644 (file)
@@ -4058,9 +4058,10 @@ out:
                RETURN(rc);
        }
        case LL_IOC_HSM_ACTION: {
-               struct md_op_data               *op_data;
-               struct hsm_current_action       *hca;
-               int                              rc;
+               struct md_op_data *op_data;
+               struct hsm_current_action *hca;
+               const char *action;
+               int rc;
 
                OBD_ALLOC_PTR(hca);
                if (hca == NULL)
@@ -4075,10 +4076,26 @@ out:
 
                rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data),
                                   op_data, NULL);
+               if (rc < 0)
+                       GOTO(skip_copy, rc);
+
+               /* The hsm_current_action retreived from the server could
+                * contain corrupt information. If it is incorrect data collect
+                * debug information. We still send the data even if incorrect
+                * to user land to handle.
+                */
+               action = hsm_user_action2name(hca->hca_action);
+               if (strcmp(action, "UNKNOWN") == 0 ||
+                   hca->hca_state > HPS_DONE) {
+                       CDEBUG(D_HSM,
+                              "HSM current state %s action %s, offset = %llu, length %llu\n",
+                              hsm_progress_state2name(hca->hca_state), action,
+                              hca->hca_location.offset, hca->hca_location.length);
+               }
 
                if (copy_to_user((char __user *)arg, hca, sizeof(*hca)))
                        rc = -EFAULT;
-
+skip_copy:
                ll_finish_md_op_data(op_data);
                OBD_FREE_PTR(hca);
                RETURN(rc);
index bcd8a08..02352d6 100644 (file)
@@ -2049,10 +2049,10 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(union lquota_id) == 16, "found %lld\n",
                 (long long)(int)sizeof(union lquota_id));
 
-       LASSERTF(QUOTABLOCK_BITS == 10, "found %lld\n",
-                (long long)QUOTABLOCK_BITS);
-       LASSERTF(QUOTABLOCK_SIZE == 1024, "found %lld\n",
-                (long long)QUOTABLOCK_SIZE);
+       LASSERTF(QIF_DQBLKSIZE_BITS == 10, "found %lld\n",
+                (long long)QIF_DQBLKSIZE_BITS);
+       LASSERTF(QIF_DQBLKSIZE == 1024, "found %lld\n",
+                (long long)QIF_DQBLKSIZE);
 
        /* Checks for struct obd_quotactl */
        LASSERTF((int)sizeof(struct obd_quotactl) == 112, "found %lld\n",
index f4deaed..f7035c0 100644 (file)
@@ -45,7 +45,7 @@
 #include <sys/param.h>
 #include <err.h>
 
-#include <uapi/linux/lustre/lustre_idl.h>
+#include <linux/lustre/lustre_idl.h>
 #include <lustre/lustreapi.h>
 
 #define syserr(exp, str, args...)                                      \
index e8aea7b..a0f41b2 100644 (file)
@@ -3019,6 +3019,11 @@ static int build_prev_component(struct llapi_layout **layout,
        return 0;
 }
 
+#ifndef LCME_TEMPLATE_FLAGS
+#define LCME_TEMPLATE_FLAGS    (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
+                                LCME_FL_EXTENSION)
+#endif
+
 static int build_layout_from_yaml_node(struct cYAML *node,
                                       struct llapi_layout **layout,
                                       struct lfs_setstripe_args *lsa,
@@ -3454,6 +3459,11 @@ enum {
        LFS_FIND_PERM,
 };
 
+#ifndef LCME_USER_MIRROR_FLAGS
+/* The mirror flags can be set by users at creation time. */
+#define LCME_USER_MIRROR_FLAGS  (LCME_FL_PREF_RW)
+#endif
+
 /* functions */
 static int lfs_setstripe_internal(int argc, char **argv,
                                  enum setstripe_origin opc)
@@ -7544,6 +7554,21 @@ static inline int lfs_verify_poolarg(char *pool)
        return 0;
 }
 
+/* special grace time, only notify the user when its quota is over soft limit
+ * but doesn't block new writes until the hard limit is reached.
+ */
+#define NOTIFY_GRACE           "notify"
+#define NOTIFY_GRACE_TIME      LQUOTA_GRACE_MASK
+
+#ifndef toqb
+static inline __u64 lustre_stoqb(size_t space)
+{
+       return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
+}
+#else
+#define lustre_stoqb   toqb
+#endif
+
 int lfs_setquota_times(int argc, char **argv, struct if_quotactl *qctl)
 {
        int c, rc;
@@ -8044,6 +8069,19 @@ static void kbytes2str(__u64 num, char *buf, int buflen, bool h)
        }
 }
 
+#ifdef HAVE_NATIVE_CLIENT
+/* In the current Lustre implementation, the grace time is either the time
+ * or the timestamp to be used after some quota ID exceeds the soft limt,
+ * 48 bits should be enough, its high 16 bits can be used as quota flags.
+ */
+#define LQUOTA_GRACE_BITS      48
+#define LQUOTA_GRACE_MASK      ((1ULL << LQUOTA_GRACE_BITS) - 1)
+#define LQUOTA_GRACE_MAX       LQUOTA_GRACE_MASK
+#define LQUOTA_GRACE(t)                (t & LQUOTA_GRACE_MASK)
+#define LQUOTA_FLAG(t)         (t >> LQUOTA_GRACE_BITS)
+#define LQUOTA_GRACE_FLAG(t, f)        ((__u64)t | (__u64)f << LQUOTA_GRACE_BITS)
+#endif
+
 #define STRBUF_LEN     24
 static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                        int rc, bool h, bool show_default)
@@ -11274,6 +11312,10 @@ static inline int get_other_mirror_ids(int fd, __u16 *ids, __u16 exclude_id)
        return cid.cid_count;
 }
 
+#ifndef MIRROR_ID_NEG
+#define MIRROR_ID_NEG         0x8000
+#endif
+
 static inline int lfs_mirror_copy(int argc, char **argv)
 {
        int rc = CMD_HELP;
index 186b6b9..6775a41 100644 (file)
@@ -3331,11 +3331,13 @@ static long llog_last_index(char *logname)
 
 static char *get_llog_event_name(__u32 cmd)
 {
+#ifdef HAVE_SERVER_SUPPORT
        struct lcfg_type_data *data;
 
        data = lcfg_cmd2data(cmd);
        if (data)
                return data->ltd_name;
+#endif
        return NULL;
 }
 
index 511bdbf..342388b 100644 (file)
@@ -948,8 +948,8 @@ check_obd_quotactl(void)
        CHECK_UNION(lquota_id);
 
        BLANK_LINE();
-       CHECK_VALUE(QUOTABLOCK_BITS);
-       CHECK_VALUE(QUOTABLOCK_SIZE);
+       CHECK_VALUE(QIF_DQBLKSIZE_BITS);
+       CHECK_VALUE(QIF_DQBLKSIZE);
 
        BLANK_LINE();
        CHECK_STRUCT(obd_quotactl);
index a9b8ef3..d368124 100644 (file)
@@ -2073,10 +2073,10 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(union lquota_id) == 16, "found %lld\n",
                 (long long)(int)sizeof(union lquota_id));
 
-       LASSERTF(QUOTABLOCK_BITS == 10, "found %lld\n",
-                (long long)QUOTABLOCK_BITS);
-       LASSERTF(QUOTABLOCK_SIZE == 1024, "found %lld\n",
-                (long long)QUOTABLOCK_SIZE);
+       LASSERTF(QIF_DQBLKSIZE_BITS == 10, "found %lld\n",
+                (long long)QIF_DQBLKSIZE_BITS);
+       LASSERTF(QIF_DQBLKSIZE == 1024, "found %lld\n",
+                (long long)QIF_DQBLKSIZE_BITS);
 
        /* Checks for struct obd_quotactl */
        LASSERTF((int)sizeof(struct obd_quotactl) == 112, "found %lld\n",