diff options
author | Poornima G <pgurusid@redhat.com> | 2018-01-16 14:24:28 +0530 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2018-02-12 21:35:15 +0000 |
commit | 87fd65f1ef1c64b1e32a6da47865a4a28f1e508e (patch) | |
tree | 51c62a994cb8241e5e77e226b3c6d6a46a46e036 /xlators/storage | |
parent | 384562b294e9a7847403961e878a4daa0fff33eb (diff) |
Posix: Implement put fop
Updates #353
Change-Id: I1410222529ff42a810d62825bd6eebe8913fad1e
Signed-off-by: Poornima G <pgurusid@redhat.com>
Diffstat (limited to 'xlators/storage')
-rw-r--r-- | xlators/storage/posix/src/posix-entry-ops.c | 99 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 1 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 6 |
3 files changed, 106 insertions, 0 deletions
diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index 41d8c873b4c..8f3be6c4914 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -60,6 +60,7 @@ #include "events.h" #include "posix-gfid-path.h" #include "compat-uuid.h" +#include "syncop.h" extern char *marker_xattrs[]; #define ALIGN_SIZE 4096 @@ -2160,3 +2161,101 @@ out: return 0; } + +/* TODO: Ensure atomocity of put, and rollback in case of failure + * One of the ways, is to perform put in the hidden directory + * and rename it to the specified location, if the put was successful + */ +int32_t +posix_put (call_frame_t *frame, xlator_t *this, loc_t *loc, + mode_t mode, mode_t umask, uint32_t flags, + struct iovec *vector, int32_t count, off_t offset, + struct iobref *iobref, dict_t *xattr, dict_t *xdata) +{ + int32_t op_ret = -1; + int32_t op_errno = 0; + fd_t *fd = NULL; + char *real_path = NULL; + char *par_path = NULL; + struct iatt stbuf = {0, }; + struct iatt preparent = {0,}; + struct iatt postparent = {0,}; + + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); + + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED, + "pre-operation lstat on parent %s failed", + par_path); + goto out; + } + fd = fd_create (loc->inode, getpid()); + if (!fd) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + fd->flags = flags; + + /* No xlators are expected below posix, but we cannot still call sys_create() + * directly here, as posix_create does many other things like chmod, setxattr + * etc. along with sys_create(). But we cannot also directly call posix_create() + * as it calls STACK_UNWIND. Hence using syncop() + */ + op_ret = syncop_create (this, loc, flags, mode, fd, &stbuf, xdata, NULL); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_CREATE_FAILED, + "create of %s failed", loc->path); + goto out; + } + + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED, + "post-operation lstat on parent %s failed", + par_path); + goto out; + } + + op_ret = syncop_writev (this, fd, vector, count, offset, iobref, + flags, xdata, NULL); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_WRITE_FAILED, + "write on file %s failed", loc->path); + goto out; + } + + op_ret = syncop_fsetxattr (this, fd, xattr, flags, xdata, NULL); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED, + "setxattr on file %s failed", loc->path); + goto out; + } + + op_ret = syncop_flush (this, fd, xdata, NULL); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_CLOSE_FAILED, + "setxattr on file %s failed", loc->path); + goto out; + } + + op_ret = posix_pstat (this, loc->gfid, real_path, &stbuf); + if (op_ret < 0) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED, + "post-operation lstat on %s failed", real_path); + goto out; + } +out: + STACK_UNWIND_STRICT (put, frame, op_ret, op_errno, loc->inode, &stbuf, + &preparent, &postparent, NULL); + + return 0; +} diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index d8d908f83cd..9ac60ae81d3 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -79,6 +79,7 @@ struct xlator_fops fops = { .seek = posix_seek, #endif .lease = posix_lease, + .put = posix_put, }; struct xlator_cbks cbks = { diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 720c3011f5a..5a623aa657a 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -613,6 +613,12 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t len, dict_t *xdata); int32_t +posix_put (call_frame_t *frame, xlator_t *this, loc_t *loc, + mode_t mode, mode_t umask, uint32_t flags, + struct iovec *vector, int32_t count, off_t offset, + struct iobref *iobref, dict_t *xattr, dict_t *xdata); + +int32_t posix_set_mode_in_dict (dict_t *in_dict, dict_t *out_dict, struct iatt *in_stbuf); #endif /* _POSIX_H */ |