Whamcloud - gitweb
LU-8585 llite: add special fid handling for fhandle API 07/51707/11
authorJames Simmons <jsimmons@infradead.org>
Thu, 10 Aug 2023 01:59:28 +0000 (21:59 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 13 Sep 2023 04:01:28 +0000 (04:01 +0000)
Lustre has been moving its FIDs handling to the fhandle API. This
works well for normal files but Lustre has special FIDs that don't
map to normal files which are used by user land applications. Add
special handling to ll_iget_for_nfs() so the fhandle API can work
with these special FIDs. These FIDs should also work with filesets.

Change-Id: I4b55d96cc9eea0b1fb898f94c071c8b30c7b2bd5
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51707
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Etienne AUJAMES <eaujames@ddn.com>
Reviewed-by: Neil Brown <neilb@suse.de>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/fid/fid_lib.c
lustre/include/lustre_fid.h
lustre/include/uapi/linux/lustre/lustre_fid.h
lustre/llite/llite_nfs.c
lustre/tests/llapi_fid_test.c

index 4bd0552..c719d01 100644 (file)
@@ -73,18 +73,6 @@ const struct lu_fid LUSTRE_BFL_FID = { .f_seq = FID_SEQ_SPECIAL,
                                        .f_ver = 0x0000000000000000 };
 EXPORT_SYMBOL(LUSTRE_BFL_FID);
 
-/** Special fid for ".lustre" directory */
-const struct lu_fid LU_DOT_LUSTRE_FID = { .f_seq = FID_SEQ_DOT_LUSTRE,
-                                          .f_oid = FID_OID_DOT_LUSTRE,
-                                          .f_ver = 0x0000000000000000 };
-EXPORT_SYMBOL(LU_DOT_LUSTRE_FID);
-
-/** Special fid for "fid" special object in .lustre */
-const struct lu_fid LU_OBF_FID = { .f_seq = FID_SEQ_DOT_LUSTRE,
-                                   .f_oid = FID_OID_DOT_LUSTRE_OBF,
-                                   .f_ver = 0x0000000000000000 };
-EXPORT_SYMBOL(LU_OBF_FID);
-
 /** Special fid for "lost+found" special object in .lustre */
 const struct lu_fid LU_LPF_FID = { .f_seq = FID_SEQ_DOT_LUSTRE,
                                   .f_oid = FID_OID_DOT_LUSTRE_LPF,
index e6a88e7..213f463 100644 (file)
@@ -167,9 +167,7 @@ struct obd_export;
 extern const struct lu_seq_range LUSTRE_SEQ_SPACE_RANGE;
 extern const struct lu_seq_range LUSTRE_SEQ_ZERO_RANGE;
 extern const struct lu_fid LUSTRE_BFL_FID;
-extern const struct lu_fid LU_OBF_FID;
 extern const struct lu_fid LU_LPF_FID;
-extern const struct lu_fid LU_DOT_LUSTRE_FID;
 extern const struct lu_fid LU_BACKEND_LPF_FID;
 
 enum {
@@ -255,20 +253,17 @@ static inline void lu_local_name_obj_fid(struct lu_fid *fid, __u32 oid)
  * the root FID will still be IGIF */
 static inline int fid_is_root(const struct lu_fid *fid)
 {
-       return unlikely((fid_seq(fid) == FID_SEQ_ROOT &&
-                        fid_oid(fid) == FID_OID_ROOT));
+       return unlikely(lu_fid_eq(fid, &LU_ROOT_FID));
 }
 
 static inline int fid_is_dot_lustre(const struct lu_fid *fid)
 {
-       return unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE &&
-                       fid_oid(fid) == FID_OID_DOT_LUSTRE);
+       return unlikely(lu_fid_eq(fid, &LU_DOT_LUSTRE_FID));
 }
 
 static inline int fid_is_obf(const struct lu_fid *fid)
 {
-       return unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE &&
-                       fid_oid(fid) == FID_OID_DOT_LUSTRE_OBF);
+       return unlikely(lu_fid_eq(fid, &LU_OBF_FID));
 }
 
 static inline int fid_is_otable_it(const struct lu_fid *fid)
index 43787e3..a57cc0c 100644 (file)
 #include <linux/types.h>
 #include <linux/lustre/lustre_idl.h>
 
+/** Special fid for root directory */
+static const struct lu_fid LU_ROOT_FID = {
+       .f_seq = FID_SEQ_ROOT,
+       .f_oid = FID_OID_ROOT,
+       .f_ver = 0x0000000000000000
+};
+
+/** Special fid for ".lustre" directory */
+static const struct lu_fid LU_DOT_LUSTRE_FID = {
+       .f_seq = FID_SEQ_DOT_LUSTRE,
+       .f_oid = FID_OID_DOT_LUSTRE,
+       .f_ver = 0x0000000000000000
+};
+
+/** Special fid for "fid" special object in .lustre */
+static const struct lu_fid LU_OBF_FID = {
+       .f_seq = FID_SEQ_DOT_LUSTRE,
+       .f_oid = FID_OID_DOT_LUSTRE_OBF,
+       .f_ver = 0x0000000000000000
+};
+
 /** returns fid object sequence */
 static inline __u64 fid_seq(const struct lu_fid *fid)
 {
index 20d96a4..989143f 100644 (file)
  */
 
 #define DEBUG_SUBSYSTEM S_LLITE
-#include "llite_internal.h"
 #include <linux/exportfs.h>
 
+#include <lustre_fid.h>
+#include "llite_internal.h"
+
 u32 get_uuid2int(const char *name, int len)
 {
        u32 key0 = 0x12a3fe2d, key1 = 0x37abe8f9;
@@ -114,16 +116,19 @@ struct inode *search_inode_for_lustre(struct super_block *sb,
 static struct dentry *
 ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *parent)
 {
-       struct inode  *inode;
+       bool is_dot_lustre = fid_is_dot_lustre(fid);
        struct dentry *result;
+       struct inode *inode;
 
        ENTRY;
-
        if (!fid_is_sane(fid))
                RETURN(ERR_PTR(-ESTALE));
 
        CDEBUG(D_INFO, "Get dentry for fid: "DFID"\n", PFID(fid));
 
+       if (fid_is_root(fid))
+               RETURN(dget(sb->s_root));
+
        inode = search_inode_for_lustre(sb, fid);
        if (IS_ERR(inode))
                RETURN(ERR_CAST(inode));
@@ -134,6 +139,86 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren
                RETURN(ERR_PTR(-ESTALE));
        }
 
+       /* Both LU_DOT_LUSTRE_FID and LU_OBF_FID are special fids that
+        * don't match to a real searchable file, so they need special
+        * handling.
+        */
+       if (is_dot_lustre || fid_is_obf(fid)) {
+               struct qstr dot_name = QSTR_INIT(".lustre",
+                                                strlen(".lustre"));
+               struct dentry *dot, *obf;
+
+               inode_lock(d_inode(sb->s_root));
+               dot = d_lookup(sb->s_root, &dot_name);
+               if (!dot) {
+                       struct inode *tmp = inode;
+
+                       dot = d_alloc(sb->s_root, &dot_name);
+                       if (!dot) {
+                               inode_unlock(d_inode(sb->s_root));
+                               iput(inode);
+                               RETURN(ERR_PTR(-ENOMEM));
+                       }
+
+                       if (!ll_d_setup(dot, true)) {
+                               inode_unlock(d_inode(sb->s_root));
+                               obf = ERR_PTR(-ENOMEM);
+                               goto free_dot;
+                       }
+
+                       /* We are requesting OBF fid then locate inode of
+                        * .lustre FID
+                        */
+                       if (!is_dot_lustre) {
+                               tmp = search_inode_for_lustre(sb,
+                                                             &LU_DOT_LUSTRE_FID);
+                               if (IS_ERR(tmp)) {
+                                       inode_unlock(d_inode(sb->s_root));
+                                       obf = ERR_CAST(tmp);
+                                       goto free_dot;
+                               }
+                       }
+                       /* Successfully add .lustre dentry to dcache. For future
+                        * failures for the obf case we don't need to iput the
+                        * .lustre inode.
+                        */
+                       d_add(dot, tmp);
+               }
+               inode_unlock(d_inode(sb->s_root));
+
+               if (!is_dot_lustre) {
+                       struct qstr obf_name = QSTR_INIT("fid", strlen("fid"));
+
+                       inode_lock(d_inode(dot));
+                       obf = d_lookup(dot, &obf_name);
+                       if (!obf) {
+                               obf = d_alloc(dot, &obf_name);
+                               if (!obf) {
+                                       inode_unlock(d_inode(dot));
+                                       obf = ERR_PTR(-ENOMEM);
+                                       goto free_dot;
+                               }
+
+                               if (!ll_d_setup(obf, true)) {
+                                       dput(obf);
+                                       inode_unlock(d_inode(dot));
+                                       obf = ERR_PTR(-ENOMEM);
+                                       goto free_dot;
+                               }
+                               d_add(obf, inode);
+                       }
+                       inode_unlock(d_inode(dot));
+free_dot:
+                       if (IS_ERR(obf))
+                               iput(inode);
+                       dput(dot);
+                       result = obf;
+               } else {
+                       result = dot;
+               }
+               RETURN(result);
+       }
+
        /* N.B. d_obtain_alias() drops inode ref on error */
        result = d_obtain_alias(inode);
        if (IS_ERR(result))
index 3c17e0a..21122ac 100644 (file)
@@ -45,7 +45,7 @@
 #include <time.h>
 
 #include <lustre/lustreapi.h>
-#include <linux/lustre/lustre_idl.h>
+#include <linux/lustre/lustre_fid.h>
 
 #define ERROR(fmt, ...)                                                        \
        fprintf(stderr, "%s: %s:%d: %s: " fmt "\n",                     \
@@ -490,6 +490,24 @@ static void test30(void)
        }
 }
 
+/* Test special FIDs for lustre */
+static void test31(void)
+{
+       int fd;
+
+       fd = llapi_open_by_fid(mainpath, &LU_ROOT_FID, O_RDONLY);
+       ASSERTF(fd >= 0, "llapi_open_by_fid for " DFID_NOBRACE ": %s",
+               PFID(&LU_ROOT_FID), strerror(errno));
+
+       fd = llapi_open_by_fid(mainpath, &LU_DOT_LUSTRE_FID, O_RDONLY);
+       ASSERTF(fd >= 0, "llapi_open_by_fid for " DFID_NOBRACE ": %s",
+               PFID(&LU_DOT_LUSTRE_FID), strerror(errno));
+
+       fd = llapi_open_by_fid(mainpath, &LU_OBF_FID, O_RDONLY);
+       ASSERTF(fd >= 0, "llapi_open_by_fid for " DFID_NOBRACE ": %s",
+               PFID(&LU_OBF_FID), strerror(errno));
+}
+
 /* Test llapi_fd2parent/llapi_path2parent on mainpath (whatever its
  * type). mainpath must exist. */
 static void help_test40(void)
@@ -749,6 +767,7 @@ int main(int argc, char *argv[])
        PERFORM(test12);
        PERFORM(test20);
        PERFORM(test30);
+       PERFORM(test31);
        PERFORM(test40);
        PERFORM(test41);
        PERFORM(test42);