Whamcloud - gitweb
LU-14462 gss: fix support for namespace in lgss_keyring
[fs/lustre-release.git] / lustre / utils / liblustreapi_fid.c
index 0034714..578c6e6 100644 (file)
@@ -160,100 +160,71 @@ out:
        return rc;
 }
 
-/* Print mdtname 'name' into 'buf' using 'format'.  Add -MDT0000 if needed.
- * format must have %s%s, buf must be > 16
- * Eg: if name = "lustre-MDT0000", "lustre", or "lustre-MDT0000_UUID"
- *     then buf = "lustre-MDT0000"
- */
-static int get_mdtname(char *name, char *format, char *buf)
+int llapi_fid2path_at(int mnt_fd, const struct lu_fid *fid,
+                     char *path_buf, int path_buf_size,
+                     long long *recno, int *linkno)
 {
-       char suffix[] = "-MDT0000";
-       int len = strlen(name);
+       struct getinfo_fid2path *gf = NULL;
+       int rc;
 
-       if (len > 5 && strncmp(name + len - 5, "_UUID", 5) == 0) {
-               name[len - 5] = '\0';
-               len -= 5;
+       gf = calloc(1, sizeof(*gf) + path_buf_size);
+       if (gf == NULL) {
+               rc = -ENOMEM;
+               goto out;
        }
 
-       if (len > 8) {
-               if ((len <= 16) && strncmp(name + len - 8, "-MDT", 4) == 0) {
-                       suffix[0] = '\0';
-               } else {
-                       /* Not enough room to add suffix */
-                       llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                         "Invalid MDT name |%s|", name);
-                       return -EINVAL;
-               }
-       }
+       gf->gf_fid = *fid;
+       if (recno != NULL)
+               gf->gf_recno = *recno;
 
-       return sprintf(buf, format, name, suffix);
-}
+       if (linkno != NULL)
+               gf->gf_linkno = *linkno;
 
-/** ioctl on filsystem root, with mdtindex sent as data
- * \param mdtname path, fsname, or mdtname (lutre-MDT0004)
- * \param mdtidxp pointer to integer within data to be filled in with the
- *    mdt index (0 if no mdt is specified).  NULL won't be filled.
- */
-int root_ioctl(const char *mdtname, int opc, void *data, int *mdtidxp,
-              int want_error)
-{
-       char fsname[20];
-       char *ptr;
-       int fd, rc;
-       long index;
+       gf->gf_pathlen = path_buf_size;
 
-       /* Take path, fsname, or MDTname.  Assume MDT0000 in former cases.
-        * Open root and parse mdt index.
-        */
-       if (mdtname[0] == '/') {
-               index = 0;
-               rc = get_root_path(WANT_FD | want_error, NULL, &fd,
-                                  (char *)mdtname, -1);
-       } else {
-               if (get_mdtname((char *)mdtname, "%s%s", fsname) < 0)
-                       return -EINVAL;
-               ptr = fsname + strlen(fsname) - 8;
-               *ptr = '\0';
-               index = strtol(ptr + 4, NULL, 16);
-               rc = get_root_path(WANT_FD | want_error, fsname, &fd, NULL, -1);
-       }
-       if (rc < 0) {
-               if (want_error)
-                       llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                         "Can't open %s: %d\n", mdtname, rc);
-               return rc;
+       rc = ioctl(mnt_fd, OBD_IOC_FID2PATH, gf);
+       if (rc) {
+               rc = -errno;
+               goto out;
        }
 
-       if (mdtidxp)
-               *mdtidxp = index;
+       rc = copy_strip_dne_path(gf->gf_u.gf_path, path_buf, path_buf_size);
+
+       if (recno != NULL)
+               *recno = gf->gf_recno;
+
+       if (linkno != NULL)
+               *linkno = gf->gf_linkno;
+out:
+       free(gf);
 
-       rc = ioctl(fd, opc, data);
-       if (rc == -1)
-               rc = -errno;
-       else
-               rc = 0;
-       close(fd);
        return rc;
 }
 
-int llapi_fid2path(const char *device, const char *fidstr, char *path,
+int llapi_fid2path(const char *path_or_device, const char *fidstr, char *path,
                   int pathlen, long long *recno, int *linkno)
 {
        struct lu_fid fid;
-       struct getinfo_fid2path *gf;
+       int mnt_fd = -1;
        int rc;
 
-       if (!path || pathlen <= 1) {
+       if (path_or_device == NULL || *path_or_device == '\0') {
                rc = -EINVAL;
                goto out;
        }
 
-       rc = llapi_fid_parse(fidstr, &fid, NULL);
-       if (!rc && !fid_is_sane(&fid)) {
-               rc = -EINVAL;
+       if (*path_or_device == '/')
+               rc = get_root_path(WANT_FD, NULL, &mnt_fd,
+                                  (char *)path_or_device, -1);
+       else
+               rc = get_root_path(WANT_FD, (char *)path_or_device,
+                                  &mnt_fd, NULL, -1);
+
+       if (rc < 0)
                goto out;
-       }
-       if (rc) {
+
+       rc = llapi_fid_parse(fidstr, &fid, NULL);
+       if (rc < 0) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "bad FID format '%s', should be [seq:oid:ver] (e.g. "DFID")\n",
                                  fidstr,
@@ -261,106 +232,100 @@ int llapi_fid2path(const char *device, const char *fidstr, char *path,
                goto out;
        }
 
-       gf = malloc(sizeof(*gf) + pathlen);
-       if (gf == NULL) {
-               rc = -ENOMEM;
-               goto out;
-       }
+       rc = llapi_fid2path_at(mnt_fd, &fid, path, pathlen, recno, linkno);
+out:
+       if (!(mnt_fd < 0))
+               close(mnt_fd);
 
-       gf->gf_fid = fid;
-       if (recno)
-               gf->gf_recno = *recno;
-       if (linkno)
-               gf->gf_linkno = *linkno;
-       gf->gf_pathlen = pathlen;
+       return rc;
+}
 
-       /* Take path or fsname */
-       rc = root_ioctl(device, OBD_IOC_FID2PATH, gf, NULL, 0);
-       if (rc)
-               goto out_free;
+int llapi_get_mdt_index_by_fid(int fd, const struct lu_fid *fid,
+                              int *mdt_index)
+{
+       int rc;
 
-       rc = copy_strip_dne_path(gf->gf_u.gf_path, path, pathlen);
+       rc = ioctl(fd, LL_IOC_FID2MDTIDX, fid);
+       if (rc < 0)
+               return -errno;
 
-       if (recno)
-               *recno = gf->gf_recno;
-       if (linkno)
-               *linkno = gf->gf_linkno;
+       if (mdt_index)
+               *mdt_index = rc;
 
-out_free:
-       free(gf);
-out:
-       errno = -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;
+       char buf[512];
        int rc = -1;
 
-       if (fd >= 0)
+       if (path == NULL)
                rc = fgetxattr(fd, XATTR_NAME_LMA, buf, sizeof(buf));
-       else if (path)
-               rc = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf));
        else
-               errno = EINVAL;
+               rc = lgetxattr(path, XATTR_NAME_LMA, buf, sizeof(buf));
        if (rc < 0)
                return -errno;
 
        lma = (struct lustre_mdt_attrs *)buf;
-       fid_le_to_cpu(fid, &lma->lma_self_fid);
-
+       memcpy(fid, &lma->lma_self_fid, sizeof(lma->lma_self_fid));
        return 0;
 }
 
-int llapi_get_mdt_index_by_fid(int fd, const struct lu_fid *fid,
-                              int *mdt_index)
-{
-       int rc;
-
-       rc = ioctl(fd, LL_IOC_FID2MDTIDX, fid);
-       if (rc < 0)
-               return -errno;
-
-       if (mdt_index)
-               *mdt_index = rc;
-
-       return rc;
-}
-
 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));
 
-       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;
 
-       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;