Whamcloud - gitweb
LU-12806 llapi: use name_to_handle_at in llapi_fd2fid 92/36292/19
authorQuentin Bouget <quentin.bouget@cea.fr>
Thu, 12 Dec 2019 08:47:23 +0000 (09:47 +0100)
committerOleg Drokin <green@whamcloud.com>
Thu, 23 Jan 2020 05:30:59 +0000 (05:30 +0000)
Reimplement llapi_fd2fid so as to use name_to_handle_at() rather than
using an ioctl() call.

This patch also updates llapi_fid2path as using file descriptor
obtained from a call to open() + O_PATH is valid with
name_to_handle_at(), is more efficient and also works for symlinks
out of the box.

Signed-off-by: Quentin Bouget <quentin.bouget@cea.fr>
Change-Id: Ic7e83c7fdf924363ed59a0681267d960e660db6d
Reviewed-on: https://review.whamcloud.com/36292
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/llite_nfs.c
lustre/utils/liblustreapi_fid.c

index fdcc379..f90725a 100644 (file)
@@ -61,6 +61,7 @@
 /* # include <sys/quota.h> - this causes complaints about caddr_t */
 # include <sys/stat.h>
 # include <linux/lustre/lustre_fiemap.h>
 /* # include <sys/quota.h> - this causes complaints about caddr_t */
 # include <sys/stat.h>
 # include <linux/lustre/lustre_fiemap.h>
+# define FILEID_LUSTRE 0x97 /* for name_to_handle_at() (and llapi_fd2fid()) */
 #endif /* __KERNEL__ */
 
 /* Handle older distros */
 #endif /* __KERNEL__ */
 
 /* Handle older distros */
@@ -331,6 +332,12 @@ static inline bool fid_is_zero(const struct lu_fid *fid)
        return fid->f_seq == 0 && fid->f_oid == 0;
 }
 
        return fid->f_seq == 0 && fid->f_oid == 0;
 }
 
+/* The data name_to_handle_at() places in a struct file_handle (at f_handle) */
+struct lustre_file_handle {
+       struct lu_fid lfh_child;
+       struct lu_fid lfh_parent;
+};
+
 /* Currently, the filter_fid::ff_parent::f_ver is not the real parent
  * MDT-object's FID::f_ver, instead it is the OST-object index in its
  * parent MDT-object's layout EA. */
 /* Currently, the filter_fid::ff_parent::f_ver is not the real parent
  * MDT-object's FID::f_ver, instead it is the OST-object index in its
  * parent MDT-object's layout EA. */
index d291cfa..6f0d511 100644 (file)
@@ -112,11 +112,6 @@ struct inode *search_inode_for_lustre(struct super_block *sb,
        RETURN(inode);
 }
 
        RETURN(inode);
 }
 
-struct lustre_nfs_fid {
-       struct lu_fid lnf_child;
-       struct lu_fid lnf_parent;
-};
-
 static struct dentry *
 ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *parent)
 {
 static struct dentry *
 ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *parent)
 {
@@ -193,8 +188,8 @@ static int ll_encode_fh(struct inode *inode, u32 *fh, int *plen,
                        struct inode *parent)
 {
 #endif
                        struct inode *parent)
 {
 #endif
-       int fileid_len = sizeof(struct lustre_nfs_fid) / 4;
-       struct lustre_nfs_fid *nfs_fid = (void *)fh;
+       int fileid_len = sizeof(struct lustre_file_handle) / 4;
+       struct lustre_file_handle *lfh = (void *)fh;
 
        ENTRY;
 
 
        ENTRY;
 
@@ -207,11 +202,11 @@ static int ll_encode_fh(struct inode *inode, u32 *fh, int *plen,
                RETURN(FILEID_INVALID);
        }
 
                RETURN(FILEID_INVALID);
        }
 
-       nfs_fid->lnf_child = *ll_inode2fid(inode);
+       lfh->lfh_child = *ll_inode2fid(inode);
        if (parent)
        if (parent)
-               nfs_fid->lnf_parent = *ll_inode2fid(parent);
+               lfh->lfh_parent = *ll_inode2fid(parent);
        else
        else
-               fid_zero(&nfs_fid->lnf_parent);
+               fid_zero(&lfh->lfh_parent);
        *plen = fileid_len;
 
        RETURN(FILEID_LUSTRE);
        *plen = fileid_len;
 
        RETURN(FILEID_LUSTRE);
@@ -293,23 +288,23 @@ out:
 static struct dentry *ll_fh_to_dentry(struct super_block *sb, struct fid *fid,
                                      int fh_len, int fh_type)
 {
 static struct dentry *ll_fh_to_dentry(struct super_block *sb, struct fid *fid,
                                      int fh_len, int fh_type)
 {
-       struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
+       struct lustre_file_handle *lfh = (struct lustre_file_handle *)fid;
 
        if (fh_type != FILEID_LUSTRE)
                RETURN(ERR_PTR(-EPROTO));
 
 
        if (fh_type != FILEID_LUSTRE)
                RETURN(ERR_PTR(-EPROTO));
 
-       RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_child, &nfs_fid->lnf_parent));
+       RETURN(ll_iget_for_nfs(sb, &lfh->lfh_child, &lfh->lfh_parent));
 }
 
 static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
                                      int fh_len, int fh_type)
 {
 }
 
 static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
                                      int fh_len, int fh_type)
 {
-       struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
+       struct lustre_file_handle *lfh = (struct lustre_file_handle *)fid;
 
        if (fh_type != FILEID_LUSTRE)
                RETURN(ERR_PTR(-EPROTO));
 
 
        if (fh_type != FILEID_LUSTRE)
                RETURN(ERR_PTR(-EPROTO));
 
-       RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL));
+       RETURN(ll_iget_for_nfs(sb, &lfh->lfh_parent, NULL));
 }
 
 int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
 }
 
 int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
index 0034714..3ef7ff9 100644 (file)
@@ -293,27 +293,6 @@ out:
        return rc;
 }
 
        return rc;
 }
 
-static int fid_from_lma(const char *path, int fd, struct lu_fid *fid)
-{
-       char buf[512];
-       struct lustre_mdt_attrs *lma;
-       int rc = -1;
-
-       if (fd >= 0)
-               rc = fgetxattr(fd, XATTR_NAME_LMA, buf, sizeof(buf));
-       else if (path)
-               rc = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf));
-       else
-               errno = EINVAL;
-       if (rc < 0)
-               return -errno;
-
-       lma = (struct lustre_mdt_attrs *)buf;
-       fid_le_to_cpu(fid, &lma->lma_self_fid);
-
-       return 0;
-}
-
 int llapi_get_mdt_index_by_fid(int fd, const struct lu_fid *fid,
                               int *mdt_index)
 {
 int llapi_get_mdt_index_by_fid(int fd, const struct lu_fid *fid,
                               int *mdt_index)
 {
@@ -329,38 +308,77 @@ int llapi_get_mdt_index_by_fid(int fd, const struct lu_fid *fid,
        return rc;
 }
 
        return rc;
 }
 
+static int fid_from_lma(const char *path, int fd, struct lu_fid *fid)
+{
+       struct lustre_mdt_attrs *lma;
+       char buf[512];
+       int rc = -1;
+
+       if (path == NULL)
+               rc = fgetxattr(fd, XATTR_NAME_LMA, buf, sizeof(buf));
+       else
+               rc = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf));
+       if (rc < 0)
+               return -errno;
+
+       lma = (struct lustre_mdt_attrs *)buf;
+       memcpy(fid, &lma->lma_self_fid, sizeof(lma->lma_self_fid));
+       return 0;
+}
+
 int llapi_fd2fid(int fd, struct lu_fid *fid)
 {
 int llapi_fd2fid(int fd, struct lu_fid *fid)
 {
-       int rc;
+       const struct lustre_file_handle *data;
+       struct file_handle *handle;
+       char buffer[sizeof(*handle) + MAX_HANDLE_SZ];
+       int mount_id;
 
        memset(fid, 0, sizeof(*fid));
 
 
        memset(fid, 0, sizeof(*fid));
 
-       rc = ioctl(fd, LL_IOC_PATH2FID, fid) < 0 ? -errno : 0;
-       /* Allow extracting the FID from an ldiskfs-mounted filesystem */
-       if (rc < 0) {
-               if (errno == EINVAL || errno == ENOTTY)
-                       rc = fid_from_lma(NULL, fd, fid);
-               else
-                       rc = -errno;
+       /* A lustre file handle should always fit in a 128 bytes long buffer
+        * (which is the value of MAX_HANDLE_SZ at the time this is written)
+        */
+       handle = (struct file_handle *)buffer;
+       handle->handle_bytes = MAX_HANDLE_SZ;
+
+       if (name_to_handle_at(fd, "", handle, &mount_id, AT_EMPTY_PATH)) {
+               if (errno == EOVERFLOW)
+                       /* A Lustre file_handle would have fit */
+                       return -ENOTTY;
+               return -errno;
        }
 
        }
 
-       return rc;
+       if (handle->handle_type != FILEID_LUSTRE)
+               /* Might be a locally mounted Lustre target */
+               return fid_from_lma(NULL, fd, fid);
+       if (handle->handle_bytes < sizeof(*fid))
+               /* Unexpected error try and recover */
+               return fid_from_lma(NULL, fd, fid);
+
+       /* Parse the FID out of the handle */
+       data = (const struct lustre_file_handle *)handle->f_handle;
+       memcpy(fid, &data->lfh_child, sizeof(data->lfh_child));
+
+       return 0;
 }
 
 int llapi_path2fid(const char *path, struct lu_fid *fid)
 {
        int fd, rc;
 
 }
 
 int llapi_path2fid(const char *path, struct lu_fid *fid)
 {
        int fd, rc;
 
-       fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW);
-       if (fd >= 0) {
-               rc = llapi_fd2fid(fd, fid);
-               close(fd);
-       } else {
-               memset(fid, 0, sizeof(*fid));
-               rc = -errno;
-       }
+       fd = open(path, O_RDONLY | O_PATH | O_CLOEXEC | O_NOFOLLOW);
+       if (fd < 0)
+               return -errno;
+
+       rc = llapi_fd2fid(fd, fid);
+       close(fd);
 
 
-       if (rc == -ELOOP || rc == -ENXIO || rc == -EINVAL || rc == -ENOTTY)
+       if (rc == -EBADF)
+               /* Might be a locally mounted Lustre target
+                *
+                * Cannot use `fd' as fgetxattr() does not work on file
+                * descriptor opened with O_PATH
+                */
                rc = fid_from_lma(path, -1, fid);
 
        return rc;
                rc = fid_from_lma(path, -1, fid);
 
        return rc;