diff options
Diffstat (limited to 'xlators/storage/posix/src')
-rw-r--r-- | xlators/storage/posix/src/posix-handle.h | 18 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 249 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 1 |
3 files changed, 203 insertions, 65 deletions
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h index da48366e..5490d016 100644 --- a/xlators/storage/posix/src/posix-handle.h +++ b/xlators/storage/posix/src/posix-handle.h @@ -46,6 +46,22 @@ } \ } while (0) +#define SET_PGFID_XATTR_IF_ABSENT(path, key, value, flags, op_ret, this, label) \ + do { \ + op_ret = sys_lgetxattr (path, key, &value, sizeof (value)); \ + if (op_ret == -1) { \ + op_errno = errno; \ + if (op_errno == ENOATTR) { \ + SET_PGFID_XATTR (path, key, value, flags, \ + op_ret, this, label); \ + } else { \ + gf_log (this->name, GF_LOG_WARNING,"getting " \ + "xattr failed on %s: key = %s (%s)", \ + path, key, strerror (op_errno)); \ + } \ + } \ + } while (0) + #define REMOVE_PGFID_XATTR(path, key, op_ret, this, label) do { \ op_ret = sys_lremovexattr (path, key); \ if (op_ret == -1) { \ @@ -72,7 +88,6 @@ } else { \ value = ntoh32 (value); \ value++; \ - value = hton32 (value); \ } \ SET_PGFID_XATTR (path, key, value, flags, op_ret, this, label); \ } while (0) @@ -88,7 +103,6 @@ } else { \ value = ntoh32 (value); \ value--; \ - value = hton32 (value); \ if (value > 0) { \ SET_PGFID_XATTR (path, key, value, flags, op_ret, \ this, label); \ diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index e63ca8d4..635d5f01 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -102,11 +102,16 @@ posix_lookup (call_frame_t *frame, xlator_t *this, char * par_path = NULL; struct iatt postparent = {0,}; int32_t gfidless = 0; + char *pgfid_xattr_key = NULL; + struct posix_private *priv = NULL; + int32_t nlink_samepgfid = 0; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (loc, out); + priv = this->private; + /* The Hidden directory should be for housekeeping purpose and it should not get any gfid on it */ if (__is_root_gfid (loc->pargfid) && loc->name @@ -152,6 +157,29 @@ posix_lookup (call_frame_t *frame, xlator_t *this, xdata, &buf); } + if (priv->update_pgfid_nlinks && !uuid_is_null (loc->pargfid) && + !IA_ISDIR (buf.ia_type)) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, + PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + + LOCK (&loc->inode->lock); + { + nlink_samepgfid = 1; + /** + * This is in case where quota/update_nlinks enabled + * on a preexisting data. We're setting the the pgfid + * to '1' to continue with the normal pgfid xattr + * building as we don't know the exact no of hardlinks. + */ + SET_PGFID_XATTR_IF_ABSENT (real_path, pgfid_xattr_key, + nlink_samepgfid, + XATTR_CREATE, op_ret, + this, unlock); + } + unlock: + UNLOCK (&loc->inode->lock); + } parent: if (par_path) { op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); @@ -628,7 +656,7 @@ _posix_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_siz ret = posix_do_fallocate(frame, this, fd, flags, offset, len, &statpre, &statpost); - if (ret < 0) + if (ret < 0) goto err; STACK_UNWIND_STRICT(fallocate, frame, 0, 0, &statpre, &statpost, NULL); @@ -650,7 +678,7 @@ posix_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, ret = posix_do_fallocate(frame, this, fd, flags, offset, len, &statpre, &statpost); - if (ret < 0) + if (ret < 0) goto err; STACK_UNWIND_STRICT(discard, frame, 0, 0, &statpre, &statpost, NULL); @@ -844,6 +872,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, mode_t st_mode = 0; int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; + gf_boolean_t internal_fop = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -877,6 +906,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, internal call from distribute for creating 'linkfile', and that linkfile may be for a hardlinked file */ if (dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { + internal_fop = _gf_true; dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY); op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (op_ret) { @@ -959,12 +989,27 @@ post_op: strerror (errno)); } - MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, - loc->pargfid); - nlink_samepgfid = 1; - - SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, - XATTR_CREATE, op_ret, this, ignore); + /* If the mknod is due to distribute as an internal fop, then + the PGFID_XATTR is not needed, as the linkfile is used to + only get the actual subvolume of the file. Otherwise it is + difficult to keep the PGFID_XATTR of both the linkfile and + the original file in sync. Imagine this set of operations. + inode1: a, b are the links present in the same parent p1 + Now, for the inode of a and b (inode1), pgfid.<p1> will be + set to 2. Now when b gets renamed to c which gets hashed to + a different subvolume, then mknod is called on the subvolume2 + to create the linkfile. On that subvolume, posix_mknod will set + the PGFID_XATTR to 1 (which is not right). + */ + if (!internal_fop && priv->update_pgfid_nlinks) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, + PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + nlink_samepgfid = 1; + SET_PGFID_XATTR (real_path, pgfid_xattr_key, + nlink_samepgfid, XATTR_CREATE, op_ret, + this, ignore); + } ignore: op_ret = posix_entry_create_xattr_set (this, real_path, xdata); if (op_ret) { @@ -1147,17 +1192,19 @@ int32_t posix_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) { - int32_t op_ret = -1; - int32_t op_errno = 0; - char *real_path = NULL; - char *par_path = NULL; - int32_t fd = -1; - struct iatt stbuf = {0,}; - struct posix_private *priv = NULL; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; - char *pgfid_xattr_key = NULL; - int32_t nlink_samepgfid = 0; + int32_t op_ret = -1; + int32_t op_errno = 0; + char *real_path = NULL; + char *par_path = NULL; + int32_t fd = -1; + struct iatt stbuf = {0,}; + struct posix_private *priv = NULL; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + char *pgfid_xattr_key = NULL; + int32_t nlink_samepgfid = 0; + gf_boolean_t internal_fop = _gf_false; + gf_boolean_t update_pgfid_xattr = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1195,13 +1242,21 @@ posix_unlink (call_frame_t *frame, xlator_t *this, } } - if (stbuf.ia_nlink > 1) { - MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, + internal_fop = (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)); + update_pgfid_xattr = (priv->update_pgfid_nlinks && + stbuf.ia_nlink > 1 && + !internal_fop); + + if (update_pgfid_xattr) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, + PGFID_XATTR_KEY_PREFIX, loc->pargfid); LOCK (&loc->inode->lock); { - UNLINK_MODIFY_PGFID_XATTR (real_path, pgfid_xattr_key, - nlink_samepgfid, 0, op_ret, + UNLINK_MODIFY_PGFID_XATTR (real_path, + pgfid_xattr_key, + nlink_samepgfid, 0, + op_ret, this, unlock); } unlock: @@ -1221,6 +1276,30 @@ posix_unlink (call_frame_t *frame, xlator_t *this, gf_log (this->name, GF_LOG_ERROR, "unlink of %s failed: %s", real_path, strerror (op_errno)); + + if (update_pgfid_xattr) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, + PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + LOCK (&loc->inode->lock); + { + LINK_MODIFY_PGFID_XATTR (real_path, + pgfid_xattr_key, + nlink_samepgfid, + 0, op_ret, + this, nolock); + } + nolock: + UNLOCK (&loc->inode->lock); + + if (op_ret < 0) + gf_log (this->name, GF_LOG_WARNING, + "modification of parent gfid xattr " + "failed (path:%s gfid:%s)", + real_path, + uuid_utoa (loc->inode->gfid)); + } + goto out; } @@ -1435,11 +1514,13 @@ posix_symlink (call_frame_t *frame, xlator_t *this, strerror (errno)); } - MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, - loc->pargfid); - nlink_samepgfid = 1; - SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, - XATTR_CREATE, op_ret, this, ignore); + if (priv->update_pgfid_nlinks) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + nlink_samepgfid = 1; + SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, + XATTR_CREATE, op_ret, this, ignore); + } ignore: op_ret = posix_entry_create_xattr_set (this, real_path, xdata); if (op_ret) { @@ -1507,6 +1588,8 @@ posix_rename (call_frame_t *frame, xlator_t *this, int nlink = 0; char *pgfid_xattr_key = NULL; int32_t nlink_samepgfid = 0; + gf_boolean_t link_file = _gf_false; + gf_boolean_t update_pgfid_xattr = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1574,17 +1657,24 @@ posix_rename (call_frame_t *frame, xlator_t *this, if (IA_ISDIR (oldloc->inode->ia_type)) posix_handle_unset (this, oldloc->inode->gfid, NULL); + if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { + link_file = _gf_true; + dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY); + } + LOCK (&oldloc->inode->lock); { - if (!IA_ISDIR (oldloc->inode->ia_type)) { + update_pgfid_xattr = (priv->update_pgfid_nlinks && + !IA_ISDIR (oldloc->inode->ia_type) && + !link_file); + if (update_pgfid_xattr) { MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, oldloc->pargfid); UNLINK_MODIFY_PGFID_XATTR (real_oldpath, pgfid_xattr_key, nlink_samepgfid, 0, - op_ret, - this, unlock); + op_ret, this, unlock); } op_ret = sys_rename (real_oldpath, real_newpath); @@ -1597,22 +1687,22 @@ posix_rename (call_frame_t *frame, xlator_t *this, real_oldpath, real_newpath, strerror (op_errno)); - LINK_MODIFY_PGFID_XATTR (real_oldpath, - pgfid_xattr_key, - nlink_samepgfid, 0, - op_ret, - this, unlock); + if (update_pgfid_xattr) { + LINK_MODIFY_PGFID_XATTR (real_oldpath, + pgfid_xattr_key, + nlink_samepgfid, + 0, op_ret, this, + unlock); + } goto unlock; } - if (!IA_ISDIR (oldloc->inode->ia_type)) { + if (update_pgfid_xattr) { MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, newloc->pargfid); - LINK_MODIFY_PGFID_XATTR (real_newpath, - pgfid_xattr_key, - nlink_samepgfid, 0, - op_ret, + LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key, + nlink_samepgfid, 0, op_ret, this, unlock); } } @@ -1762,25 +1852,26 @@ posix_link (call_frame_t *frame, xlator_t *this, goto out; } - MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, - newloc->pargfid); + if (priv->update_pgfid_nlinks) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, + newloc->pargfid); - LOCK (&newloc->inode->lock); - { - LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key, - nlink_samepgfid, 0, op_ret, this, - unlock); - } -unlock: - UNLOCK (&newloc->inode->lock); + LOCK (&newloc->inode->lock); + { + LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key, + nlink_samepgfid, 0, op_ret, + this, unlock); + } + unlock: + UNLOCK (&newloc->inode->lock); - if (op_ret < 0) { - gf_log (this->name, GF_LOG_WARNING, "modification of " - "parent gfid xattr failed (path:%s gfid:%s)", - real_newpath, uuid_utoa (newloc->inode->gfid)); - goto out; + if (op_ret < 0) { + gf_log (this->name, GF_LOG_WARNING, "modification of " + "parent gfid xattr failed (path:%s gfid:%s)", + real_newpath, uuid_utoa (newloc->inode->gfid)); + goto out; + } } - op_ret = 0; out: @@ -1961,11 +2052,13 @@ posix_create (call_frame_t *frame, xlator_t *this, strerror (errno)); } - MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, - loc->pargfid); - nlink_samepgfid = 1; - SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, - XATTR_CREATE, op_ret, this, ignore); + if (priv->update_pgfid_nlinks) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + nlink_samepgfid = 1; + SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, + XATTR_CREATE, op_ret, this, ignore); + } ignore: op_ret = posix_entry_create_xattr_set (this, real_path, xdata); if (op_ret) { @@ -3113,7 +3206,10 @@ int posix_get_ancestry (xlator_t *this, const char *real_path, loc_t *loc, dict_t *dict, int type, int32_t *op_errno, dict_t *xdata) { - int ret = -1; + int ret = -1; + struct posix_private *priv = NULL; + + priv = this->private; if (IA_ISDIR (loc->inode->ia_type)) { ret = posix_get_ancestry_directory (this, real_path, loc, dict, @@ -3305,6 +3401,11 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, size = op_ret = posix_get_ancestry (this, real_path, loc, dict, type, &op_errno, xdata); + if (op_ret < 0) { + op_ret = -1; + op_errno = ENODATA; + goto out; + } goto done; } @@ -4908,6 +5009,9 @@ reconfigure (xlator_t *this, dict_t *options) else posix_aio_off (this); + GF_OPTION_RECONF ("update-pgfid-nlinks", priv->update_pgfid_nlinks, + options, bool, out); + GF_OPTION_RECONF ("node-uuid-pathinfo", priv->node_uuid_pathinfo, options, bool, out); @@ -5185,6 +5289,20 @@ init (xlator_t *this) "for every open)"); } + tmp_data = dict_get (this->options, "update-pgfid-nlinks"); + if (tmp_data) { + if (gf_string2boolean (tmp_data->data, + &_private->update_pgfid_nlinks) == -1) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "wrong value provided for " + "'update-pgfid-nlinks'"); + goto out; + } + gf_log (this->name, GF_LOG_DEBUG, "update-pgfid-nlinks is %s", + _private->update_pgfid_nlinks? "enabled": "disabled"); + } + ret = dict_get_str (this->options, "glusterd-uuid", &guuid); if (!ret) { if (uuid_parse (guuid, _private->glusterd_uuid)) @@ -5475,5 +5593,10 @@ struct volume_options options[] = { .description = "Num of usecs to wait for aggregating fsync" " requests", }, + { .key = {"update-pgfid-nlinks"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "false", + .description = "Enable placeholders for gfid to path conversion" + }, { .key = {NULL} } }; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 09e6d39c..ec69e952 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -149,6 +149,7 @@ struct posix_private { uint32_t health_check_interval; pthread_t health_check; gf_boolean_t health_check_active; + gf_boolean_t update_pgfid_nlinks; }; typedef struct { |