diff options
author | Venkatesh Somyajulu <vsomyaju@redhat.com> | 2014-07-15 18:17:19 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-07-18 03:11:06 -0700 |
commit | 74d92e322e3c9f4f70ddfbf9b0e2140922009658 (patch) | |
tree | b569c431d68676188a2df87711d4a975887b4ba9 /xlators/storage/posix | |
parent | 52da727e7564963a8a244fc5cb7028315e458529 (diff) |
cluster/dht: Fix races to avoid deletion of linkto file
Explanation of Race between rebalance processes:
https://bugzilla.redhat.com/show_bug.cgi?id=1110694#c4
STATE 1: BRICK-1
only one brick Cached File
in the system
STATE 2:
Add brick-2 BRICK-1 BRICK-2
STATE 3: Lookup of File on brick-2
by this node's rebalance
will fail because hashed
file is not created yet.
So dht_lookup_everywhere is
about to get called.
STATE 4: As part of lookup
link file at brick-2
will be created.
STATE 5: getxattr to check that
cached file belongs to
this node is done
STATE 6:
dht_lookup_everywhere_cbk detects
the link created by rebalance-1.
It will unlink it.
STATE 7: getxattr at the link
file with "pathinfo" key
will be called will fail
as the link file is deleted
by rebalance on node-2
Fix:
So in the STATE 6, we should avoid the deletion of link file. Every time
dht_lookup_everywhere gets called, lookup will be performed on all the nodes.
So to avoid STATE 6, if linkto file is found, it is not deleted until valid
case is found in dht_lookup_everywhere_done.
Case 1: if linkto file points to cached node, and cached file exists,
uwind with success.
Case 2: if linkto does not point to current cached node, and cached file
exists:
a) Unlink stale link file
b) Create new link file
Case 3: Only linkto file exists:
Delete linkto file
Case 4: Only cached file
Create link file (Handled event without patch)
Case 5: Neither cached nor hashed file is present
Return with ENOENT (handled even without patch)
Change-Id: Ibf53671410d8d613b8e2e7e5d0ec30fc7dcc0298
BUG: 1116150
Signed-off-by: Venkatesh Somyajulu <vsomyaju@redhat.com>
Reviewed-on: http://review.gluster.org/8231
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Tested-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/storage/posix')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 76 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 2 |
2 files changed, 67 insertions, 11 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index eb0bac66d06..63b65edcda5 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -1343,17 +1343,22 @@ 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; + int32_t unlink_if_linkto = 0; + int32_t check_open_fd = 0; + int32_t skip_unlink = 0; + ssize_t xattr_size = -1; + int32_t is_dht_linkto_file = 0; DECLARE_OLD_FS_ID_VAR; @@ -1377,6 +1382,55 @@ posix_unlink (call_frame_t *frame, xlator_t *this, posix_handle_unset (this, stbuf.ia_gfid, NULL); priv = this->private; + + op_ret = dict_get_int32 (xdata, "dont-unlink-for-open-fd", + &check_open_fd); + + if (!op_ret && check_open_fd) { + + LOCK (&loc->inode->lock); + + if (loc->inode->fd_count) { + skip_unlink = 1; + } + + UNLOCK (&loc->inode->lock); + + if (skip_unlink) { + op_ret = -1; + op_errno = EBUSY; + goto out; + } + } + + + op_ret = dict_get_int32 (xdata, "unlink-only-if-dht-linkto-file", + &unlink_if_linkto); + + if (!op_ret && unlink_if_linkto) { + + LOCK (&loc->inode->lock); + + xattr_size = sys_lgetxattr (real_path, LINKTO, NULL, 0); + + if (xattr_size <= 0) { + skip_unlink = 1; + } else { + is_dht_linkto_file = IS_DHT_LINKFILE_MODE (&stbuf); + if (!is_dht_linkto_file) + skip_unlink = 1; + } + + UNLOCK (&loc->inode->lock); + + if (skip_unlink) { + op_ret = -1; + op_errno = EBUSY; + goto out; + } + } + + if (priv->background_unlink) { if (IA_ISREG (loc->inode->ia_type)) { fd = open (real_path, O_RDONLY); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index c9bfc984da5..aa4a66c3051 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -53,6 +53,8 @@ #define VECTOR_SIZE 64 * 1024 /* vector size 64KB*/ #define MAX_NO_VECT 1024 +#define LINKTO "trusted.glusterfs.dht.linkto" + #define POSIX_GFID_HANDLE_SIZE(base_path_len) (base_path_len + SLEN("/") \ + SLEN(GF_HIDDEN_PATH) + SLEN("/") \ + SLEN("00/") \ |