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,
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;