summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/storage/posix/src/posix-entry-ops.c99
-rw-r--r--xlators/storage/posix/src/posix.c1
-rw-r--r--xlators/storage/posix/src/posix.h6
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 41d8c873b4..8f3be6c491 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 d8d908f83c..9ac60ae81d 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 720c3011f5..5a623aa657 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 */