summaryrefslogtreecommitdiffstats
path: root/xlators/features/changelog/src/changelog-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/changelog/src/changelog-helpers.c')
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
index a72ad25e4bc..0a29969194e 100644
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ b/xlators/features/changelog/src/changelog-helpers.c
@@ -1735,3 +1735,88 @@ err:
inode_unref (parent);
return -1;
}
+
+/*
+ * resolve_pargfid_to_path:
+ * It converts given pargfid to path by doing recursive readlinks at the
+ * backend. If bname is given, it suffixes bname to pargfid to form the
+ * complete path else it doesn't. It allocates memory for the path and is
+ * caller's responsibility to free the same. If bname is NULL and pargfid
+ * is ROOT, then it returns "."
+ */
+
+int
+resolve_pargfid_to_path (xlator_t *this, uuid_t pargfid,
+ char **path, char *bname)
+{
+ char *linkname = NULL;
+ char *dir_handle = NULL;
+ char *pgfidstr = NULL;
+ char *saveptr = NULL;
+ ssize_t len = 0;
+ int ret = 0;
+ uuid_t tmp_gfid = {0, };
+ changelog_priv_t *priv = NULL;
+ char gpath[PATH_MAX] = {0,};
+ char result[PATH_MAX] = {0,};
+ char *dir_name = NULL;
+ char pre_dir_name[PATH_MAX] = {0,};
+
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (!path || gf_uuid_is_null (pargfid)) {
+ ret = -1;
+ goto out;
+ }
+
+ if (__is_root_gfid (pargfid)) {
+ if (bname)
+ *path = gf_strdup (bname);
+ else
+ *path = gf_strdup (".");
+ return ret;
+ }
+
+ dir_handle = alloca (PATH_MAX);
+ linkname = alloca (PATH_MAX);
+ (void) snprintf (gpath, PATH_MAX, "%s/.glusterfs/",
+ priv->changelog_brick);
+
+ while (!(__is_root_gfid (pargfid))) {
+ snprintf (dir_handle, PATH_MAX, "%s/%02x/%02x/%s", gpath,
+ pargfid[0], pargfid[1], uuid_utoa (pargfid));
+
+ len = readlink (dir_handle, linkname, PATH_MAX);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "could not read the "
+ "link from the gfid handle %s (%s)", dir_handle,
+ strerror (errno));
+ ret = -1;
+ goto out;
+ }
+
+ linkname[len] = '\0';
+
+ pgfidstr = strtok_r (linkname + strlen("../../00/00/"), "/",
+ &saveptr);
+ dir_name = strtok_r (NULL, "/", &saveptr);
+
+ strncpy (result, dir_name, PATH_MAX);
+ strncat (result, "/", 1);
+ strncat (result, pre_dir_name, PATH_MAX);
+ strncpy (pre_dir_name, result, PATH_MAX);
+
+ gf_uuid_parse (pgfidstr, tmp_gfid);
+ gf_uuid_copy (pargfid, tmp_gfid);
+ }
+
+ if (bname)
+ strncat (result, bname, PATH_MAX);
+
+ *path = gf_strdup (result);
+
+out:
+ return ret;
+}