From 87fd65f1ef1c64b1e32a6da47865a4a28f1e508e Mon Sep 17 00:00:00 2001 From: Poornima G Date: Tue, 16 Jan 2018 14:24:28 +0530 Subject: Posix: Implement put fop Updates #353 Change-Id: I1410222529ff42a810d62825bd6eebe8913fad1e Signed-off-by: Poornima G --- xlators/storage/posix/src/posix-entry-ops.c | 99 +++++++++++++++++++++++++++++ xlators/storage/posix/src/posix.c | 1 + xlators/storage/posix/src/posix.h | 6 ++ 3 files changed, 106 insertions(+) (limited to 'xlators') 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 @@ -612,6 +612,12 @@ int32_t 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); -- cgit