diff options
author | Raghavendra G <rgowdapp@redhat.com> | 2014-09-10 21:40:26 +0530 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2014-09-17 08:34:17 -0700 |
commit | c0cc62c144c560dcbfe9c89a139f51fd5274e33f (patch) | |
tree | 274b0b9d8c66dcbad3d83b32dc4e3ce6df303dff /xlators/storage | |
parent | 3f886a345d4cb0d4760cadd0ab5fd94c0b7209a6 (diff) |
storage/posix: removing deleting entries in case of creation failures
The code is not atomic enough to not to delete a dentry created by a
prallel dentry creation operation.
Change-Id: I9bd6d2aa9e7a1c0688c0a937b02a4b4f56d7aa3d
BUG: 1129527
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: http://review.gluster.org/8327
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
(cherry picked from commit 45fbf99cb669e891a84a8228cef27973f5e774bf)
Signed-off-by: Nithya Balachandran <nbalacha@redhat.com>
Reviewed-on: http://review.gluster.org/8716
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'xlators/storage')
-rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 2 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 18 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 108 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 4 |
4 files changed, 91 insertions, 41 deletions
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 991b991874e..bc5786359fd 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -807,7 +807,7 @@ posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc, } -static int +int posix_handle_unset_gfid (xlator_t *this, uuid_t gfid) { char *path = NULL; diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 65382b501e7..7474a609524 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -644,6 +644,24 @@ out: return xattr; } +void +posix_gfid_unset (xlator_t *this, dict_t *xdata) +{ + uuid_t uuid = {0, }; + int ret = 0; + + if (xdata == NULL) + goto out; + + ret = dict_get_ptr (xdata, "gfid-req", (void **)&uuid); + if (ret) { + goto out; + } + + posix_handle_unset (this, uuid, NULL); +out: + return; +} int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 6cfa2224d94..da96e6d56cf 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -1050,7 +1050,6 @@ posix_mknod (call_frame_t *frame, xlator_t *this, char *real_path = 0; char *par_path = 0; struct iatt stbuf = { 0, }; - char was_present = 1; struct posix_private *priv = NULL; gid_t gid = 0; struct iatt preparent = {0,}; @@ -1058,6 +1057,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, void * uuid_req = NULL; int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; + gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1135,10 +1135,14 @@ real_op: } } + entry_created = _gf_true; + op_ret = posix_gfid_set (this, real_path, loc, xdata); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, "setting gfid on %s failed", real_path); + } else { + gfid_set = _gf_true; } #ifndef HAVE_SET_FSID @@ -1204,28 +1208,35 @@ out: (loc)?loc->inode:NULL, &stbuf, &preparent, &postparent, NULL); - if ((op_ret == -1) && (!was_present)) { - unlink (real_path); + if (op_ret < 0) { + if (entry_created) { + if (S_ISREG (mode)) + sys_unlink (real_path); + else + sys_rmdir (real_path); + } + + if (gfid_set) + posix_gfid_unset (this, xdata); } return 0; } - int posix_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { - int32_t op_ret = -1; - int32_t op_errno = 0; - char *real_path = NULL; - char *par_path = NULL; - struct iatt stbuf = {0, }; - char was_present = 1; - struct posix_private *priv = NULL; - gid_t gid = 0; - struct iatt preparent = {0,}; - struct iatt postparent = {0,}; + int32_t op_ret = -1; + int32_t op_errno = 0; + char *real_path = NULL; + char *par_path = NULL; + struct iatt stbuf = {0, }; + struct posix_private *priv = NULL; + gid_t gid = 0; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1253,9 +1264,6 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, gid = frame->root->gid; op_ret = posix_pstat (this, NULL, real_path, &stbuf); - if ((op_ret == -1) && (errno == ENOENT)) { - was_present = 0; - } SET_FS_ID (frame->root->uid, gid); @@ -1282,10 +1290,14 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, goto out; } + entry_created = _gf_true; + op_ret = posix_gfid_set (this, real_path, loc, xdata); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, "setting gfid on %s failed", real_path); + } else { + gfid_set = _gf_true; } #ifndef HAVE_SET_FSID @@ -1339,8 +1351,12 @@ out: (loc)?loc->inode:NULL, &stbuf, &preparent, &postparent, NULL); - if ((op_ret == -1) && (!was_present)) { - unlink (real_path); + if (op_ret < 0) { + if (entry_created) + sys_rmdir (real_path); + + if (gfid_set) + posix_gfid_unset (this, xdata); } return 0; @@ -1567,11 +1583,11 @@ posix_symlink (call_frame_t *frame, xlator_t *this, struct iatt stbuf = { 0, }; struct posix_private *priv = NULL; gid_t gid = 0; - char was_present = 1; struct iatt preparent = {0,}; struct iatt postparent = {0,}; char *pgfid_xattr_key = NULL; int32_t nlink_samepgfid = 0; + gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1585,10 +1601,6 @@ posix_symlink (call_frame_t *frame, xlator_t *this, MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); - if ((op_ret == -1) && (errno == ENOENT)){ - was_present = 0; - } - SET_FS_ID (frame->root->uid, gid); gid = frame->root->gid; @@ -1616,10 +1628,14 @@ posix_symlink (call_frame_t *frame, xlator_t *this, goto out; } + entry_created = _gf_true; + op_ret = posix_gfid_set (this, real_path, loc, xdata); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, "setting gfid on %s failed", real_path); + } else { + gfid_set = _gf_true; } #ifndef HAVE_SET_FSID @@ -1681,8 +1697,12 @@ out: (loc)?loc->inode:NULL, &stbuf, &preparent, &postparent, NULL); - if ((op_ret == -1) && (!was_present)) { - unlink (real_path); + if (op_ret < 0) { + if (entry_created) + sys_unlink (real_path); + + if (gfid_set) + posix_gfid_unset (this, xdata); } return 0; @@ -1886,10 +1906,6 @@ out: &preoldparent, &postoldparent, &prenewparent, &postnewparent, NULL); - if ((op_ret == -1) && !was_present) { - unlink (real_newpath); - } - return 0; } @@ -1905,11 +1921,11 @@ posix_link (call_frame_t *frame, xlator_t *this, char *par_newpath = 0; struct iatt stbuf = {0, }; struct posix_private *priv = NULL; - char was_present = 1; struct iatt preparent = {0,}; struct iatt postparent = {0,}; int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; + gf_boolean_t entry_created = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -1925,9 +1941,6 @@ posix_link (call_frame_t *frame, xlator_t *this, MAKE_INODE_HANDLE (real_oldpath, this, oldloc, &stbuf); MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf); - if ((op_ret == -1) && (errno == ENOENT)) { - was_present = 0; - } op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &preparent); if (op_ret == -1) { @@ -1957,6 +1970,8 @@ posix_link (call_frame_t *frame, xlator_t *this, goto out; } + entry_created = _gf_true; + op_ret = posix_pstat (this, NULL, real_newpath, &stbuf); if (op_ret == -1) { op_errno = errno; @@ -2004,8 +2019,9 @@ out: (oldloc)?oldloc->inode:NULL, &stbuf, &preparent, &postparent, NULL); - if ((op_ret == -1) && (!was_present)) { - unlink (real_newpath); + if (op_ret < 0) { + if (entry_created) + sys_unlink (real_newpath); } return 0; @@ -2093,6 +2109,7 @@ posix_create (call_frame_t *frame, xlator_t *this, int nlink_samepgfid = 0; char * pgfid_xattr_key = NULL; + gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; DECLARE_OLD_FS_ID_VAR; @@ -2150,6 +2167,11 @@ posix_create (call_frame_t *frame, xlator_t *this, goto out; } + if ((_flags & O_CREAT) && (_flags & O_EXCL)) { + entry_created = _gf_true; + } + + if (was_present) goto fill_stat; @@ -2157,6 +2179,8 @@ posix_create (call_frame_t *frame, xlator_t *this, if (op_ret) { gf_log (this->name, GF_LOG_ERROR, "setting gfid on %s failed", real_path); + } else { + gfid_set = _gf_true; } #ifndef HAVE_SET_FSID @@ -2237,16 +2261,20 @@ out: if ((-1 == op_ret) && (_fd != -1)) { close (_fd); - - if (!was_present) { - unlink (real_path); - } } STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, (loc)?loc->inode:NULL, &stbuf, &preparent, &postparent, xdata); + if (op_ret < 0) { + if (entry_created) + sys_unlink (real_path); + + if (gfid_set) + posix_gfid_unset (this, xdata); + } + return 0; } diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index d579bf673db..f2e947c7670 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -216,4 +216,8 @@ int posix_get_ancestry (xlator_t *this, inode_t *leaf_inode, gf_dirent_t *head, char **path, int type, int32_t *op_errno, dict_t *xdata); + +void +posix_gfid_unset (xlator_t *this, dict_t *xdata); + #endif /* _POSIX_H */ |