From a0cd85c307f3576291829beb825323d43aeca7f8 Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Tue, 5 May 2009 15:58:09 +0530 Subject: libglusterfsclient: Fix realpath operation This commit does two things: 1. Ensures we go on to traverse nested symlinks by calling realpath recursively on the symlink. 2. Makes glusterfs_realpath, a VMP-based operation, return a resolved /real path that actually has the VMP pre-fixed to the resolved path. If this is not done, we'll be returning a path that is valid only within the glusterfs context, i.e. the path will point to a real file/dir only if a glusterfs handle identifies which glusterfs context the file is in. Signed-off-by: Anand V. Avati --- libglusterfsclient/src/libglusterfsclient.c | 48 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'libglusterfsclient/src') diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c index b0b226e99ab..7130cfb4924 100755 --- a/libglusterfsclient/src/libglusterfsclient.c +++ b/libglusterfsclient/src/libglusterfsclient.c @@ -5617,7 +5617,7 @@ char * glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, char *resolved_path) { - char *buf = NULL, *extra_buf = NULL; + char *buf = NULL; char *rpath = NULL; char *start = NULL, *end = NULL; char *dest = NULL; @@ -5630,7 +5630,8 @@ glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, int dest_offset = 0; char *rpath_limit = 0; int ret = 0, num_links = 0; - size_t len = 0; + struct vmp_entry *entry = NULL; + char *vpath = NULL; GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out); GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); @@ -5727,8 +5728,7 @@ glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, dest += end - start; *dest = '\0'; - /* posix_stat is implemented using lstat */ - ret = glusterfs_glh_stat (handle, rpath, &stbuf); + ret = glusterfs_glh_lstat (handle, rpath, &stbuf); if (ret == -1) { gf_log ("libglusterfsclient", GF_LOG_ERROR, "glusterfs_glh_stat returned -1 for" @@ -5759,24 +5759,10 @@ glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, } buf[ret] = '\0'; - if (extra_buf == NULL) - extra_buf = alloca (path_max); - - len = strlen (end); - if ((long int) (ret + len) >= path_max) - { - errno = ENAMETOOLONG; - goto err; - } - - memmove (&extra_buf[ret], end, len + 1); - path = end = memcpy (extra_buf, buf, ret); - - if (buf[0] == '/') - dest = rpath + 1; - else - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); + entry = libgf_vmp_search_entry (buf); + vpath = libgf_vmp_virtual_path (entry, buf); + glusterfs_glh_realpath (handle, vpath, rpath); + goto out; } else if (!S_ISDIR (stbuf.st_mode) && *end != '\0') { errno = ENOTDIR; goto err; @@ -5788,9 +5774,13 @@ glusterfs_glh_realpath (glusterfs_handle_t handle, const char *path, *dest = '\0'; out: + if (vpath) + FREE (vpath); return rpath; err: + if (vpath) + FREE (vpath); if (resolved_path == NULL) { FREE (rpath); } @@ -5804,6 +5794,7 @@ glusterfs_realpath (const char *path, char *resolved_path) struct vmp_entry *entry = NULL; char *vpath = NULL; char *res = NULL; + char *realp = NULL; GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, path, out); @@ -5813,12 +5804,23 @@ glusterfs_realpath (const char *path, char *resolved_path) goto out; } + realp = CALLOC (PATH_MAX, sizeof (char)); + if (!realp) + goto out; + vpath = libgf_vmp_virtual_path (entry, path); res = glusterfs_glh_realpath (entry->handle, vpath, resolved_path); + if (!res) + goto out; + + strncpy (realp, entry->vmp, entry->vmplen-1); + strcat (realp, res); + strcpy (resolved_path, realp); out: if (vpath) free (vpath); - return res; + + return realp; } static struct xlator_fops libgf_client_fops = { -- cgit