diff options
author | Kotresh HR <khiremat@redhat.com> | 2017-07-16 15:16:56 -0400 |
---|---|---|
committer | Krutika Dhananjay <kdhananj@redhat.com> | 2017-07-28 05:21:46 +0000 |
commit | ab2558a3e7a1b2de2d63a3812ab4ed58d10d8619 (patch) | |
tree | 8f0baa0697c37abd5a113334e6452138d8a7a5c0 /xlators/storage/posix/src/posix-helpers.c | |
parent | 1477fa442a733d7b1a5ea74884cac8f29fbe7e6a (diff) |
storage/posix: Add virtual xattr to fetch path from gfid
The gfid2path infra stores the "pargfid/bname" as on xattr
value for each non directory entry. Hardlinks would have a
separate xattr. This xattr key is internal and is not
exposed to applications. A virtual xattr is exposed for
the applications to fetch the path from gfid.
Internal xattr:
trusted.gfid2path.<xxhash>
Virtual xattr:
glusterfs.gfidtopath
getfattr -h -n glusterfs.gfidtopath /<aux-mnt>/.gfid/<gfid>
If there are hardlinks, it returns all the paths separated
by ':'.
A volume set option is introduced to change the delimiter
to required string of max length 7.
gluster vol set gfid2path-separator ":::"
Updates: #139
Change-Id: Ie3b0c3fd8bd5333c4a27410011e608333918c02a
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://review.gluster.org/17785
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 1530b1192c5..1a05d65161a 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2379,6 +2379,102 @@ posix_fdget_objectsignature (int fd, dict_t *xattr) return -EINVAL; } +/* + * posix_resolve_dirgfid_to_path: + * It converts given dirgfid to path by doing recursive readlinks at the + * backend. If bname is given, it suffixes bname to dir path 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 "/" + **/ + +int32_t +posix_resolve_dirgfid_to_path (const uuid_t dirgfid, const char *brick_path, + const char *bname, char **path) +{ + 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, }; + uuid_t pargfid = {0, }; + char gpath[PATH_MAX] = {0,}; + char result[PATH_MAX] = {0,}; + char result1[PATH_MAX] = {0,}; + char *dir_name = NULL; + char pre_dir_name[PATH_MAX] = {0,}; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + gf_uuid_copy (pargfid, dirgfid); + if (!path || gf_uuid_is_null (pargfid)) { + ret = -1; + goto out; + } + + if (__is_root_gfid (pargfid)) { + if (bname) { + snprintf (result, PATH_MAX, "/%s", bname); + *path = gf_strdup (result); + } else { + *path = gf_strdup ("/"); + } + return ret; + } + + dir_handle = alloca (PATH_MAX); + linkname = alloca (PATH_MAX); + (void) snprintf (gpath, PATH_MAX, "%s/.glusterfs/", brick_path); + + while (!(__is_root_gfid (pargfid))) { + snprintf (dir_handle, PATH_MAX, "%s/%02x/%02x/%s", gpath, + pargfid[0], pargfid[1], uuid_utoa (pargfid)); + + len = sys_readlink (dir_handle, linkname, PATH_MAX); + if (len < 0) { + gf_msg (this->name, GF_LOG_ERROR, errno, + P_MSG_READLINK_FAILED, + "could not read the " + "link from the gfid handle %s", dir_handle); + ret = -1; + goto out; + } + + linkname[len] = '\0'; + + pgfidstr = strtok_r (linkname + strlen("../../00/00/"), "/", + &saveptr); + dir_name = strtok_r (NULL, "/", &saveptr); + + if (strlen(pre_dir_name) != 0) { /* Remove '/' at the end */ + snprintf (result, PATH_MAX, "%s/%s", dir_name, + pre_dir_name); + } else { + snprintf (result, PATH_MAX, "%s", dir_name); + } + + strncpy (pre_dir_name, result, sizeof(pre_dir_name)); + + gf_uuid_parse (pgfidstr, tmp_gfid); + gf_uuid_copy (pargfid, tmp_gfid); + } + + if (bname) { + snprintf (result1, PATH_MAX, "/%s/%s", result, bname); + } else { + snprintf (result1, PATH_MAX, "/%s", result); + } + + *path = gf_strdup (result1); + +out: + return ret; +} + posix_inode_ctx_t * __posix_inode_ctx_get (inode_t *inode, xlator_t *this) { |