diff options
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 73 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 66 | 
3 files changed, 140 insertions, 0 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 74e6847a0..8ee55c706 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -83,6 +83,7 @@  #define GF_XATTR_NODE_UUID_KEY  "trusted.glusterfs.node-uuid"  #define GF_XATTR_VOL_ID_KEY   "trusted.glusterfs.volume-id"  #define GF_XATTR_LOCKINFO_KEY   "trusted.glusterfs.lockinfo" +#define GF_XATTR_GET_REAL_FILENAME_KEY "user.glusterfs.get_real_filename:"  #define GF_READDIR_SKIP_DIRS       "readdir-filter-directories" diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 1d394910a..8cbae676e 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2027,6 +2027,71 @@ dht_getxattr_unwind (call_frame_t *frame,  int +dht_getxattr_get_real_filename_cbk (call_frame_t *frame, void *cookie, +				    xlator_t *this, int op_ret, int op_errno, +				    dict_t *xattr, dict_t *xdata) +{ +        int             this_call_cnt = 0; +        dht_local_t     *local = NULL; +        dht_conf_t      *conf = NULL; + + +        conf = this->private; +        local = frame->local; + +	if (op_ret != -1) { +		if (local->xattr) +			dict_unref (local->xattr); +		local->xattr = dict_ref (xattr); + +		if (local->xattr_req) +			dict_unref (local->xattr_req); +		local->xattr_req = dict_ref (xdata); +	} + +	this_call_cnt = dht_frame_return (frame); +	if (is_last_call (this_call_cnt)) { +		DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, +				  local->xattr, local->xattr_req); +	} + +	return 0; +} + + +int +dht_getxattr_get_real_filename (call_frame_t *frame, xlator_t *this, +				loc_t *loc, const char *key, dict_t *xdata) +{ +	dht_conf_t      *conf = NULL; +	dht_local_t     *local = NULL; +	int              i = 0; +	dht_layout_t    *layout = NULL; +	int              cnt = 0; +	xlator_t        *subvol = NULL; + + +        conf   = this->private; +	local = frame->local; +	layout = local->layout; + +	cnt = local->call_cnt = layout->cnt; + +	local->op_ret = -1; +	local->op_errno = ENODATA; + +	for (i = 0; i < cnt; i++) { +		subvol = layout->list[i].xlator; +		STACK_WIND (frame, dht_getxattr_get_real_filename_cbk, +			    subvol, subvol->fops->getxattr, +			    loc, key, xdata); +	} + +	return 0; +} + + +int  dht_getxattr (call_frame_t *frame, xlator_t *this,                loc_t *loc, const char *key, dict_t *xdata)  #define DHT_IS_DIR(layout)  (layout->cnt > 1) @@ -2075,6 +2140,14 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,                  }          } +	if (key && +	    (strncmp (key, GF_XATTR_GET_REAL_FILENAME_KEY, +		      strlen (GF_XATTR_GET_REAL_FILENAME_KEY)) == 0) +	    && DHT_IS_DIR(layout)) { +		dht_getxattr_get_real_filename (frame, this, loc, key, xdata); +		return 0; +	} +          /* for file use cached subvolume (obviously!): see if {}           * below           * for directory: diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 5e014f8e9..93577cf54 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -2439,6 +2439,53 @@ out:          return 0;  } + +int +posix_xattr_get_real_filename (call_frame_t *frame, xlator_t *this, loc_t *loc, +			       const char *key, dict_t *dict, dict_t *xdata) +{ +	char *real_path = NULL; +	struct dirent *dirent = NULL; +	DIR *fd = NULL; +	const char *fname = NULL; +	char *found = NULL; +	int ret = -1; +	int op_ret = -1; + +        MAKE_INODE_HANDLE (real_path, this, loc, NULL); + +	fd = opendir (real_path); +	if (!fd) +		return -errno; + +	fname = key + strlen (GF_XATTR_GET_REAL_FILENAME_KEY); + +	while ((dirent = readdir (fd))) { +		if (strcasecmp (dirent->d_name, fname) == 0) { +			found = gf_strdup (dirent->d_name); +			if (!found) { +				closedir (fd); +				return -ENOMEM; +			} +			break; +		} +	} + +	closedir (fd); + +	if (!found) +		return -ENOENT; + +	ret = dict_set_dynstr (dict, (char *)key, found); +	if (ret) { +		GF_FREE (found); +		return -ENOMEM; +	} +	ret = strlen (found) + 1; + +	return ret; +} +  /**   * posix_getxattr - this function returns a dictionary with all the   *                  key:value pair present as xattr. used for @@ -2493,9 +2540,28 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,          dict = dict_new ();          if (!dict) { +		op_errno = ENOMEM;                  goto out;          } +	if (loc->inode && name && +	    (strncmp (name, GF_XATTR_GET_REAL_FILENAME_KEY, +		      strlen (GF_XATTR_GET_REAL_FILENAME_KEY)) == 0)) { +		ret = posix_xattr_get_real_filename (frame, this, loc, +						     name, dict, xdata); +		if (ret < 0) { +			op_ret = -1; +			op_errno = -ret; +			gf_log (this->name, GF_LOG_WARNING, +				"Failed to get rea filename (%s, %s): %s", +				loc->path, name, strerror (op_errno)); +			goto out; +		} + +		size = ret; +		goto done; +	} +          if (loc->inode && name && !strcmp (name, GLUSTERFS_OPEN_FD_COUNT)) {                  if (!list_empty (&loc->inode->fd_list)) {                          ret = dict_set_uint32 (dict, (char *)name, 1);  | 
