-/* 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)
-{
- char suffix[]="-MDT0000";
- int len = strlen(name);
-
- if ((len > 5) && (strncmp(name + len - 5, "_UUID", 5) == 0)) {
- name[len - 5] = '\0';
- len -= 5;
- }
-
- 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;
- }
- }
-
- return sprintf(buf, format, name, suffix);
-}
-
-/** 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;
-
- /* Take path, fsname, or MDTname. Assume MDT0000 in the 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;
- }
-
- if (mdtidxp)
- *mdtidxp = index;
-
- 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 *buf,
- int buflen, long long *recno, int *linkno)
-{
- const char *fidstr_orig = fidstr;
- struct lu_fid fid;
- struct getinfo_fid2path *gf;
- char *a;
- char *b;
- int rc;
-
- while (*fidstr == '[')
- fidstr++;
-
- sscanf(fidstr, SFID, RFID(&fid));
- if (!fid_is_sane(&fid)) {
- llapi_err_noerrno(LLAPI_MSG_ERROR,
- "bad FID format '%s', should be [seq:oid:ver]"
- " (e.g. "DFID")\n", fidstr_orig,
- (unsigned long long)FID_SEQ_NORMAL, 2, 0);
- return -EINVAL;
- }
-
- gf = malloc(sizeof(*gf) + buflen);
- if (gf == NULL)
- return -ENOMEM;
-
- gf->gf_fid = fid;
- gf->gf_recno = *recno;
- gf->gf_linkno = *linkno;
- gf->gf_pathlen = buflen;
-
- /* Take path or fsname */
- rc = root_ioctl(device, OBD_IOC_FID2PATH, gf, NULL, 0);
- if (rc)
- goto out_free;
-
- b = buf;
- /* strip out instances of // */
- for (a = gf->gf_u.gf_path; *a != '\0'; a++) {
- if ((*a == '/') && (*(a + 1) == '/'))
- continue;
- *b = *a;
- b++;
- }
- *b = '\0';
-
- if (buf[0] == '\0') { /* ROOT path */
- buf[0] = '/';
- buf[1] = '\0';
- }
-
- *recno = gf->gf_recno;
- *linkno = gf->gf_linkno;
-
-out_free:
- free(gf);
- 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;
-
- 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;
- 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 rc;
-
- rc = ioctl(fd, LL_IOC_FID2MDTIDX, fid);
- if (rc < 0)
- return -errno;
-
- *mdt_index = rc;
-
- return rc;
-}
-
-int llapi_fd2fid(int fd, struct lu_fid *fid)
-{
- int rc;
-
- memset(fid, 0, sizeof(*fid));
-
- rc = ioctl(fd, LL_IOC_PATH2FID, fid) < 0 ? -errno : 0;
- if (rc == -EINVAL || rc == -ENOTTY)
- rc = fid_from_lma(NULL, fd, fid);
-
- return rc;
-}
-
-int llapi_path2fid(const char *path, struct lu_fid *fid)
-{
- int fd, rc;
-
- memset(fid, 0, sizeof(*fid));
- fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW);
- if (fd < 0) {
- if (errno == ELOOP || errno == ENXIO)
- return fid_from_lma(path, -1, fid);
- return -errno;
- }
-
- rc = llapi_fd2fid(fd, fid);
- if (rc == -EINVAL || rc == -ENOTTY)
- rc = fid_from_lma(path, -1, fid);
-
- close(fd);
- return rc;
-}
-
-int llapi_fd2parent(int fd, unsigned int linkno, struct lu_fid *parent_fid,
- char *name, size_t name_size)
-{
- struct getparent *gp;
- int rc;
-
- gp = malloc(sizeof(*gp) + name_size);
- if (gp == NULL)
- return -ENOMEM;
-
- gp->gp_linkno = linkno;
- gp->gp_name_size = name_size;
-
- rc = ioctl(fd, LL_IOC_GETPARENT, gp);
- if (rc < 0) {
- rc = -errno;
- goto err_free;
- }
-
- *parent_fid = gp->gp_fid;
-
- strncpy(name, gp->gp_name, name_size);
- name[name_size - 1] = '\0';
-
-err_free:
- free(gp);
- return rc;
-}
-
-int llapi_path2parent(const char *path, unsigned int linkno,
- struct lu_fid *parent_fid, char *name, size_t name_size)
-{
- int fd;
- int rc;
-
- fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW);
- if (fd < 0)
- return -errno;
-
- rc = llapi_fd2parent(fd, linkno, parent_fid, name, name_size);
- close(fd);
- return rc;
-}
-