diff options
| author | Anand Avati <avati@redhat.com> | 2012-08-28 23:23:52 -0700 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-09-17 19:25:01 -0700 | 
| commit | 8f9e94c65516662ff49926203a73b3a0166c087e (patch) | |
| tree | e9fba03e9a97a97dd0411a5009ac8147bb2bcd2f /api/src/glfs-resolve.c | |
| parent | 0d3bec589748b4cc8295d9ed109d21c94e3d8854 (diff) | |
gfapi: add symlink (auto resolution) support in resolver
- new internal API glfs_lresolve() for usage with APIs
  like glfs_lXXXX() (e.g. glfs_lstat())
Change-Id: I61c60af6bda3072f189684ad8ac9815d59f455fc
BUG: 839950
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/3866
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Diffstat (limited to 'api/src/glfs-resolve.c')
| -rw-r--r-- | api/src/glfs-resolve.c | 96 | 
1 files changed, 93 insertions, 3 deletions
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index c03c4154db0..83667378e2c 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -80,6 +80,35 @@ out:  } +int +glfs_resolve_symlink (struct glfs *fs, xlator_t *subvol, inode_t *inode, +		      char **lpath) +{ +	loc_t  loc = {0, }; +	char  *path = NULL; +	char  *rpath = NULL; +	int    ret = -1; + +	loc.inode = inode_ref (inode); +	uuid_copy (loc.gfid, inode->gfid); +	ret = inode_path (inode, NULL, &rpath); +	if (ret < 0) +		goto out; +	loc.path = rpath; + +	ret = syncop_readlink (subvol, &loc, &path, 4096); + +	if (ret) +		goto out; + +	if (lpath) +		*lpath = path; +out: +	loc_wipe (&loc); +	return ret; +} + +  inode_t *  glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,  			const char *component, struct iatt *iatt) @@ -159,8 +188,9 @@ out:  int -glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath, -	      loc_t *loc, struct iatt *iatt) +glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, +		 const char *origpath, loc_t *loc, struct iatt *iatt, +		 int follow)  {  	inode_t    *inode = NULL;  	inode_t    *parent = NULL; @@ -178,7 +208,13 @@ glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,  	}  	parent = NULL; -	inode = inode_ref (subvol->itable->root); +	if (at && path[0] != '/') +		/* A relative resolution of a path which starts with '/' +		   is equal to an absolute path resolution. +		*/ +		inode = inode_ref (at); +	else +		inode = inode_ref (subvol->itable->root);  	for (component = strtok_r (path, "/", &saveptr);  	     component; component = next_component) { @@ -195,6 +231,36 @@ glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,  		if (!inode)  			break; +		if (!IA_ISLNK (ciatt.ia_type) && (next_component || follow)) { +			/* If the component is not the last piece, +			   then following it is necessary even if +			   not requested by the caller +			*/ +			char *lpath = NULL; +			loc_t sym_loc = {0,}; + +			ret = glfs_resolve_symlink (fs, subvol, inode, &lpath); +			inode_unref (inode); +			inode = NULL; +			if (ret < 0) +				break; + +			ret = glfs_resolve_at (fs, subvol, parent, lpath, +					       &sym_loc, +					       /* followed iatt becomes the +						  component iatt +					       */ +					       &ciatt, +					       /* always recurisvely follow while +						  following symlink +					       */ +					       1); +			if (ret == 0) +				inode = inode_ref (sym_loc.inode); +			loc_wipe (&sym_loc); +			GF_FREE (lpath); +		} +  		if (!next_component)  			break; @@ -242,3 +308,27 @@ out:  	return ret;  } + +int +glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath, +	      loc_t *loc, struct iatt *iatt) +{ +	int ret = -1; + +	ret = glfs_resolve_at (fs, subvol, NULL, origpath, loc, iatt, 1); + +	return ret; +} + + +int +glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *origpath, +	       loc_t *loc, struct iatt *iatt) +{ +	int ret = -1; + +	ret = glfs_resolve_at (fs, subvol, NULL, origpath, loc, iatt, 0); + +	return ret; +} +  | 
