From f5220016c6525a6e166b83bcc24a036c5db0498b Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Wed, 8 Apr 2015 14:48:32 +0530 Subject: storage/posix: Introduce xattr-fill on fds ... with some of the code borrowed from http://review.gluster.org/#/c/3904/ Change-Id: I4901ef14d6f843d8d69f102d43d21b60ba298092 BUG: 1207603 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/10180 Tested-by: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/storage/posix/src/posix-handle.c | 4 +- xlators/storage/posix/src/posix-helpers.c | 168 ++++++++++++++++++++---------- xlators/storage/posix/src/posix.c | 54 ++++++---- xlators/storage/posix/src/posix.h | 7 +- 4 files changed, 148 insertions(+), 85 deletions(-) (limited to 'xlators/storage') diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 5aedfe3eb95..6182fd8a630 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -89,8 +89,8 @@ posix_make_ancestral_node (const char *priv_base_path, char *path, int pathsize, loc.inode = inode_ref (inode); gf_uuid_copy (loc.gfid, inode->gfid); - entry->dict = posix_lookup_xattr_fill (THIS, real_path, &loc, - xdata, iabuf); + entry->dict = posix_xattr_fill (THIS, real_path, &loc, NULL, -1, + xdata, iabuf); loc_wipe (&loc); } diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 1b7d9118072..f3d6d6c3da7 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -102,6 +102,9 @@ _is_in_array (char **str_array, char *str) { int i = 0; + if (!str) + return _gf_false; + for (i = 0; str_array[i]; i++) { if (strcmp (str, str_array[i]) == 0) return _gf_true; @@ -110,23 +113,9 @@ _is_in_array (char **str_array, char *str) } static gf_boolean_t -posix_xattr_ignorable (char *key, posix_xattr_filler_t *filler) +posix_xattr_ignorable (char *key) { - gf_boolean_t ignore = _gf_false; - - GF_ASSERT (key); - if (!key) - goto out; - - ignore = _is_in_array (posix_ignore_xattrs, key); - if (ignore) - goto out; - - if ((!strcmp (key, GF_CONTENT_KEY)) - && (!IA_ISREG (filler->stbuf->ia_type))) - ignore = _gf_true; -out: - return ignore; + return _is_in_array (posix_ignore_xattrs, key); } static int @@ -136,31 +125,48 @@ _posix_xattr_get_set_from_backend (posix_xattr_filler_t *filler, char *key) int ret = 0; char *value = NULL; - xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); + if (filler->real_path) + xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); + else + xattr_size = sys_fgetxattr (filler->fdnum, key, NULL, 0); if (xattr_size != -1) { - value = GF_CALLOC (1, xattr_size + 1, - gf_posix_mt_char); + value = GF_CALLOC (1, xattr_size + 1, gf_posix_mt_char); if (!value) goto out; - xattr_size = sys_lgetxattr (filler->real_path, key, value, - xattr_size); + if (filler->real_path) + xattr_size = sys_lgetxattr (filler->real_path, key, + value, xattr_size); + else + xattr_size = sys_fgetxattr (filler->fdnum, key, value, + xattr_size); if (xattr_size == -1) { - gf_log (filler->this->name, GF_LOG_WARNING, - "getxattr failed. path: %s, key: %s", - filler->real_path, key); + if (filler->real_path) + gf_log (filler->this->name, GF_LOG_WARNING, + "getxattr failed. path: %s, key: %s", + filler->real_path, key); + else + gf_log (filler->this->name, GF_LOG_WARNING, + "getxattr failed. gfid: %s, key: %s", + uuid_utoa (filler->fd->inode->gfid), + key); GF_FREE (value); goto out; } value[xattr_size] = '\0'; - ret = dict_set_bin (filler->xattr, key, - value, xattr_size); + ret = dict_set_bin (filler->xattr, key, value, xattr_size); if (ret < 0) { - gf_log (filler->this->name, GF_LOG_DEBUG, - "dict set failed. path: %s, key: %s", - filler->real_path, key); + if (filler->real_path) + gf_log (filler->this->name, GF_LOG_DEBUG, + "dict set failed. path: %s, key: %s", + filler->real_path, key); + else + gf_log (filler->this->name, GF_LOG_DEBUG, + "dict set failed. gfid: %s, key: %s", + uuid_utoa (filler->fd->inode->gfid), + key); GF_FREE (value); goto out; } @@ -179,7 +185,10 @@ _posix_get_marker_all_contributions (posix_xattr_filler_t *filler) int ret = -1; char *list = NULL, key[4096] = {0, }; - size = sys_llistxattr (filler->real_path, NULL, 0); + if (filler->real_path) + size = sys_llistxattr (filler->real_path, NULL, 0); + else + size = sys_flistxattr (filler->fdnum, NULL, 0); if (size == -1) { if ((errno == ENOTSUP) || (errno == ENOSYS)) { GF_LOG_OCCASIONALLY (gf_posix_xattr_enotsup_log, @@ -187,14 +196,17 @@ _posix_get_marker_all_contributions (posix_xattr_filler_t *filler) "Extended attributes not " "supported (try remounting brick" " with 'user_xattr' flag)"); - } else { - gf_log (THIS->name, GF_LOG_WARNING, - "listxattr failed on %s: %s", - filler->real_path, strerror (errno)); - + if (filler->real_path) + gf_log (THIS->name, GF_LOG_WARNING, + "listxattr failed on %s: %s", + filler->real_path, strerror (errno)); + else + gf_log (THIS->name, GF_LOG_WARNING, + "listxattr failed on %s: %s", + uuid_utoa (filler->fd->inode->gfid), + strerror (errno)); } - goto out; } @@ -208,7 +220,10 @@ _posix_get_marker_all_contributions (posix_xattr_filler_t *filler) goto out; } - size = sys_llistxattr (filler->real_path, list, size); + if (filler->real_path) + size = sys_llistxattr (filler->real_path, list, size); + else + size = sys_flistxattr (filler->fdnum, list, size); if (size <= 0) { ret = size; goto out; @@ -257,10 +272,39 @@ _posix_get_marker_quota_contributions (posix_xattr_filler_t *filler, char *key) return ret; } +static inode_t * +_get_filler_inode (posix_xattr_filler_t *filler) +{ + if (filler->fd) + return filler->fd->inode; + else if (filler->loc && filler->loc->inode) + return filler->loc->inode; + else + return NULL; +} + +static int +_posix_filler_get_openfd_count (posix_xattr_filler_t *filler, char *key) +{ + inode_t *inode = NULL; + int ret = -1; + + inode = _get_filler_inode (filler); + if (!inode || gf_uuid_is_null (inode->gfid)) + goto out; + + ret = dict_set_uint32 (filler->xattr, key, inode->fd_count); + if (ret < 0) { + gf_log (filler->this->name, GF_LOG_WARNING, + "Failed to set dictionary value for %s", key); + goto out; + } +out: + return ret; +} + static int -_posix_xattr_get_set (dict_t *xattr_req, - char *key, - data_t *data, +_posix_xattr_get_set (dict_t *xattr_req, char *key, data_t *data, void *xattrargs) { posix_xattr_filler_t *filler = xattrargs; @@ -271,11 +315,13 @@ _posix_xattr_get_set (dict_t *xattr_req, ssize_t req_size = 0; - if (posix_xattr_ignorable (key, filler)) + if (posix_xattr_ignorable (key)) goto out; /* should size be put into the data_t ? */ if (!strcmp (key, GF_CONTENT_KEY) && IA_ISREG (filler->stbuf->ia_type)) { + if (!filler->real_path) + goto out; /* file content request */ req_size = data_to_uint64 (data); @@ -338,16 +384,14 @@ _posix_xattr_get_set (dict_t *xattr_req, GF_FREE (databuf); } } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) { - loc = filler->loc; - if (loc) { - ret = dict_set_uint32 (filler->xattr, key, - loc->inode->fd_count); - if (ret < 0) - gf_log (filler->this->name, GF_LOG_WARNING, - "Failed to set dictionary value for %s", - key); - } + ret = _posix_filler_get_openfd_count (filler, key); } else if (!strcmp (key, GET_ANCESTRY_PATH_KEY)) { + /* As of now, the only consumers of POSIX_ANCESTRY_PATH attempt + * fetching it via path-based fops. Hence, leaving it as it is + * for now. + */ + if (!filler->real_path) + goto out; char *path = NULL; ret = posix_get_ancestry (filler->this, filler->loc->inode, NULL, &path, POSIX_ANCESTRY_PATH, @@ -588,7 +632,7 @@ out: } static void -_handle_list_xattr (dict_t *xattr_req, const char *real_path, +_handle_list_xattr (dict_t *xattr_req, const char *real_path, int fdnum, posix_xattr_filler_t *filler) { int ret = -1; @@ -598,10 +642,14 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, ssize_t remaining_size = 0; char *key = NULL; - if (!real_path) + if ((!real_path) && (fdnum < 0)) goto out; - size = sys_llistxattr (real_path, NULL, 0); + if (real_path) + size = sys_llistxattr (real_path, NULL, 0); + else + size = sys_flistxattr (fdnum, NULL, 0); + if (size <= 0) goto out; @@ -609,7 +657,11 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, if (!list) goto out; - remaining_size = sys_llistxattr (real_path, list, size); + if (real_path) + remaining_size = sys_llistxattr (real_path, list, size); + else + remaining_size = sys_flistxattr (fdnum, list, size); + if (remaining_size <= 0) goto out; @@ -637,8 +689,8 @@ out: } dict_t * -posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, - dict_t *xattr_req, struct iatt *buf) +posix_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, fd_t *fd, + int fdnum, dict_t *xattr_req, struct iatt *buf) { dict_t *xattr = NULL; posix_xattr_filler_t filler = {0, }; @@ -659,10 +711,12 @@ posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, filler.xattr = xattr; filler.stbuf = buf; filler.loc = loc; + filler.fd = fd; + filler.fdnum = fdnum; dict_foreach (xattr_req, _posix_xattr_get_set, &filler); if (list) - _handle_list_xattr (xattr_req, real_path, &filler); + _handle_list_xattr (xattr_req, real_path, fdnum, &filler); out: return xattr; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index da8e58efd8c..50dae5db18d 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -156,8 +156,8 @@ posix_lookup (call_frame_t *frame, xlator_t *this, } if (xdata && (op_ret == 0)) { - xattr = posix_lookup_xattr_fill (this, real_path, loc, - xdata, &buf); + xattr = posix_xattr_fill (this, real_path, loc, NULL, -1, xdata, + &buf); } if (priv->update_pgfid_nlinks) { @@ -248,8 +248,8 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) goto out; } if (xdata) - xattr_rsp = posix_lookup_xattr_fill (this, real_path, loc, - xdata, &buf); + xattr_rsp = posix_xattr_fill (this, real_path, loc, NULL, -1, + xdata, &buf); op_ret = 0; @@ -3433,10 +3433,8 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, gf_entry = gf_dirent_for_name (entry->d_name); gf_entry->inode = inode_ref (leaf_inode); gf_entry->dict - = posix_lookup_xattr_fill (this, - temppath, - &loc, xdata, - NULL); + = posix_xattr_fill (this, temppath, &loc, NULL, + -1, xdata, NULL); list_add_tail (&gf_entry->list, &head->list); loc_wipe (&loc); } @@ -4301,7 +4299,7 @@ _handle_fsetxattr_keyvalue_pair (dict_t *d, char *k, data_t *v, filler = tmp; - return posix_fhandle_pair (filler->this, filler->fd, k, v, + return posix_fhandle_pair (filler->this, filler->fdnum, k, v, filler->flags); } @@ -4337,7 +4335,7 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, dict_del (dict, GFID_XATTR_KEY); dict_del (dict, GF_XATTR_VOL_ID_KEY); - filler.fd = _fd; + filler.fdnum = _fd; filler.this = this; #ifdef GF_DARWIN_HOST_OS filler.flags = map_xattr_flags(flags); @@ -4653,7 +4651,7 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v, size = sys_lgetxattr (filler->real_path, k, (char *)array, v->len); } else { - size = sys_fgetxattr (filler->fd, k, (char *)array, + size = sys_fgetxattr (filler->fdnum, k, (char *)array, v->len); } @@ -4676,9 +4674,10 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v, k, strerror (op_errno)); else gf_log (this->name, GF_LOG_ERROR, - "fgetxattr failed on fd=%d while doing " - "xattrop: Key:%s (%s)", - filler->fd, + "fgetxattr failed on gfid=%s " + "while doing xattrop: " + "Key:%s (%s)", + uuid_utoa (filler->fd->inode->gfid), k, strerror (op_errno)); } @@ -4712,7 +4711,7 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v, size = sys_lsetxattr (filler->real_path, k, array, v->len, 0); } else { - size = sys_fsetxattr (filler->fd, k, (char *)array, + size = sys_fsetxattr (filler->fdnum, k, (char *)array, v->len, 0); } } @@ -4731,8 +4730,9 @@ unlock: k, strerror (op_errno)); else gf_log (this->name, GF_LOG_ERROR, - "fsetxattr failed on fd=%d while doing xattrop: " - "key=%s (%s)", filler->fd, + "fsetxattr failed on gfid=%s while doing xattrop: " + "key=%s (%s)", + uuid_utoa (filler->fd->inode->gfid), k, strerror (op_errno)); op_ret = -1; @@ -4748,8 +4748,9 @@ unlock: k, strerror (-size)); else gf_log (this->name, GF_LOG_DEBUG, - "dict_set_bin failed (fd=%d): " - "key=%s (%s)", filler->fd, + "dict_set_bin failed (gfid=%s): " + "key=%s (%s)", + uuid_utoa (filler->fd->inode->gfid), k, strerror (-size)); op_ret = -1; @@ -4812,7 +4813,7 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, } filler.this = this; - filler.fd = _fd; + filler.fdnum = _fd; filler.real_path = real_path; filler.flags = (int)optype; filler.inode = inode; @@ -4967,6 +4968,7 @@ posix_fstat (call_frame_t *frame, xlator_t *this, int32_t op_errno = 0; struct iatt buf = {0,}; struct posix_fd *pfd = NULL; + dict_t *xattr_rsp = NULL; int ret = -1; struct posix_private *priv = NULL; @@ -4998,12 +5000,18 @@ posix_fstat (call_frame_t *frame, xlator_t *this, goto out; } + if (xdata) + xattr_rsp = posix_xattr_fill (this, NULL, NULL, fd, _fd, xdata, + &buf); + op_ret = 0; out: SET_TO_OLD_FS_ID (); - STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, &buf, NULL); + STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, &buf, xattr_rsp); + if (xattr_rsp) + dict_unref (xattr_rsp); return 0; } @@ -5277,8 +5285,8 @@ posix_entry_xattr_fill (xlator_t *this, inode_t *inode, return NULL; } - return posix_lookup_xattr_fill (this, entry_path, - &tmp_loc, dict, stbuf); + return posix_xattr_fill (this, entry_path, &tmp_loc, NULL, -1, dict, + stbuf); } diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 9fdc6ee44db..d53a488ff6e 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -181,7 +181,8 @@ typedef struct { struct iatt *stbuf; loc_t *loc; inode_t *inode; /* for all do_xattrop() key handling */ - int fd; + fd_t *fd; + int fdnum; int flags; int32_t op_errno; } posix_xattr_filler_t; @@ -201,8 +202,8 @@ int posix_istat (xlator_t *this, uuid_t gfid, const char *basename, struct iatt *iatt); int posix_pstat (xlator_t *this, uuid_t gfid, const char *real_path, struct iatt *iatt); -dict_t *posix_lookup_xattr_fill (xlator_t *this, const char *path, - loc_t *loc, dict_t *xattr, struct iatt *buf); +dict_t *posix_xattr_fill (xlator_t *this, const char *path, loc_t *loc, + fd_t *fd, int fdnum, dict_t *xattr, struct iatt *buf); int posix_handle_pair (xlator_t *this, const char *real_path, char *key, data_t *value, int flags); int posix_fhandle_pair (xlator_t *this, int fd, char *key, data_t *value, -- cgit