diff options
Diffstat (limited to 'xlators/storage/posix/src/posix-inode-fd-ops.c')
-rw-r--r-- | xlators/storage/posix/src/posix-inode-fd-ops.c | 266 |
1 files changed, 252 insertions, 14 deletions
diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c index dafac59fe5b..c6779356f66 100644 --- a/xlators/storage/posix/src/posix-inode-fd-ops.c +++ b/xlators/storage/posix/src/posix-inode-fd-ops.c @@ -146,10 +146,14 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) } goto out; } - if (xdata) + if (xdata) { xattr_rsp = posix_xattr_fill (this, real_path, loc, NULL, -1, xdata, &buf); + posix_cs_maintenance (this, NULL, loc, NULL, &buf, real_path, + xdata, &xattr_rsp, _gf_true); + } + op_ret = 0; out: @@ -579,7 +583,8 @@ out: static int32_t posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, off_t offset, size_t len, - struct iatt *statpre, struct iatt *statpost, dict_t *xdata) + struct iatt *statpre, struct iatt *statpost, dict_t *xdata, + dict_t **rsp_xdata) { int32_t ret = -1; int32_t op_errno = 0; @@ -624,6 +629,17 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, goto out; } + if (xdata) { + ret = posix_cs_maintenance (this, fd, NULL, &pfd->fd, statpre, + NULL, xdata, rsp_xdata, _gf_false); + if (ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + ret = -EIO; + goto out; + } + } + ret = sys_fallocate (pfd->fd, flags, offset, len); if (ret == -1) { ret = -errno; @@ -753,7 +769,7 @@ err: static int32_t posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, struct iatt *statpre, struct iatt *statpost, - dict_t *xdata) + dict_t *xdata, dict_t **rsp_xdata) { int32_t ret = -1; int32_t op_errno = 0; @@ -795,6 +811,17 @@ posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto out; } + if (xdata) { + ret = posix_cs_maintenance (this, fd, NULL, &pfd->fd, statpre, + NULL, xdata, rsp_xdata, _gf_false); + if (ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, "file state " + "check failed, fd %p", fd); + ret = -EIO; + goto out; + } + } + /* See if we can use FALLOC_FL_ZERO_RANGE to perform the zero fill. * If it fails, fall back to _posix_do_zerofill() and an optional fsync. */ @@ -857,7 +884,7 @@ posix_glfallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_si #endif /* FALLOC_FL_KEEP_SIZE */ ret = posix_do_fallocate (frame, this, fd, flags, offset, len, - &statpre, &statpost, xdata); + &statpre, &statpost, xdata, NULL); if (ret < 0) goto err; @@ -874,6 +901,7 @@ posix_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { int32_t ret; + dict_t *rsp_xdata = NULL; #ifndef FALLOC_FL_KEEP_SIZE ret = EOPNOTSUPP; @@ -883,16 +911,17 @@ posix_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, struct iatt statpost = {0,}; ret = posix_do_fallocate (frame, this, fd, flags, offset, len, - &statpre, &statpost, xdata); + &statpre, &statpost, xdata, &rsp_xdata); if (ret < 0) goto err; - STACK_UNWIND_STRICT(discard, frame, 0, 0, &statpre, &statpost, NULL); + STACK_UNWIND_STRICT(discard, frame, 0, 0, &statpre, &statpost, + rsp_xdata); return 0; err: #endif /* FALLOC_FL_KEEP_SIZE */ - STACK_UNWIND_STRICT(discard, frame, -1, -ret, NULL, NULL, NULL); + STACK_UNWIND_STRICT(discard, frame, -1, -ret, NULL, NULL, rsp_xdata); return 0; } @@ -906,6 +935,7 @@ posix_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, struct posix_private *priv = NULL; int op_ret = -1; int op_errno = -EINVAL; + dict_t *rsp_xdata = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -914,18 +944,20 @@ posix_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out); ret = posix_do_zerofill (frame, this, fd, offset, len, - &statpre, &statpost, xdata); + &statpre, &statpost, xdata, &rsp_xdata); if (ret < 0) { op_ret = -1; op_errno = -ret; goto out; } - STACK_UNWIND_STRICT(zerofill, frame, 0, 0, &statpre, &statpost, NULL); + STACK_UNWIND_STRICT(zerofill, frame, 0, 0, &statpre, &statpost, + rsp_xdata); return 0; out: - STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, NULL, NULL, NULL); + STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, NULL, NULL, + rsp_xdata); return 0; } @@ -953,6 +985,8 @@ posix_seek (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t ret = -1; int err = 0; int whence = 0; + struct iatt preop = {0,}; + dict_t *rsp_xdata = NULL; DECLARE_OLD_FS_ID_VAR; @@ -982,6 +1016,25 @@ posix_seek (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto out; } + if (xdata) { + ret = posix_fdstat (this, pfd->fd, &preop); + if (ret == -1) { + ret = -errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED, + "pre-operation fstat failed on fd=%p", fd); + goto out; + } + + ret = posix_cs_maintenance (this, fd, NULL, &pfd->fd, &preop, NULL, + xdata, &rsp_xdata, _gf_false); + if (ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + ret = -EIO; + goto out; + } + } + ret = sys_lseek (pfd->fd, offset, whence); if (ret == -1) { err = errno; @@ -995,7 +1048,7 @@ out: SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (seek, frame, (ret == -1 ? -1 : 0), err, - (ret == -1 ? -1 : ret), xdata); + (ret == -1 ? -1 : ret), rsp_xdata); return 0; } #endif @@ -1174,6 +1227,7 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, struct posix_private *priv = NULL; struct iatt prebuf = {0,}; struct iatt postbuf = {0,}; + dict_t *rsp_xdata = NULL; DECLARE_OLD_FS_ID_VAR; @@ -1195,6 +1249,18 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, goto out; } + if (xdata) { + op_ret = posix_cs_maintenance (this, NULL, loc, NULL, &prebuf, + real_path, xdata, &rsp_xdata, + _gf_false); + if (op_ret == -1) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, path %s", loc->path); + op_errno = EIO; + goto out; + } + } + op_ret = sys_truncate (real_path, offset); if (op_ret == -1) { op_errno = errno; @@ -1326,7 +1392,9 @@ posix_readv (call_frame_t *frame, xlator_t *this, struct iovec vec = {0,}; struct posix_fd * pfd = NULL; struct iatt stbuf = {0,}; + struct iatt preop = {0,}; int ret = -1; + dict_t *rsp_xdata = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -1358,6 +1426,25 @@ posix_readv (call_frame_t *frame, xlator_t *this, } _fd = pfd->fd; + + if (xdata) { + op_ret = posix_fdstat (this, _fd, &preop); + if (op_ret == -1) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED, + "pre-operation fstat failed on fd=%p", fd); + goto out; + } + op_ret = posix_cs_maintenance (this, fd, NULL, &_fd, &preop, NULL, + xdata, &rsp_xdata, _gf_false); + if (op_ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + op_errno = EIO; + goto out; + } + } + op_ret = sys_pread (_fd, iobuf->ptr, size, offset); if (op_ret == -1) { op_errno = errno; @@ -1400,10 +1487,11 @@ posix_readv (call_frame_t *frame, xlator_t *this, op_errno = ENOENT; op_ret = vec.iov_len; + out: STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, - &vec, 1, &stbuf, iobref, NULL); + &vec, 1, &stbuf, iobref, rsp_xdata); if (iobref) iobref_unref (iobref); @@ -1413,7 +1501,6 @@ out: return 0; } - int32_t __posix_pwritev (int fd, struct iovec *vector, int count, off_t offset) { @@ -1643,6 +1730,17 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, goto out; } + if (xdata) { + op_ret = posix_cs_maintenance (this, fd, NULL, &_fd, &preop, NULL, + xdata, &rsp_xdata, _gf_false); + if (op_ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + op_errno = EIO; + goto out; + } + } + if (locked && write_append) { if (preop.ia_size == offset || (fd->flags & O_APPEND)) is_append = 1; @@ -2035,6 +2133,13 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, dict_t *xattr = NULL; posix_xattr_filler_t filler = {0,}; struct posix_private *priv = NULL; + struct iatt tmp_stbuf = {0,}; + data_t *tdata = NULL; + char stime[4096]; + char sxattr[4096]; + gf_cs_obj_state state = -1; + char remotepath[4096] = {0}; + int i = 0; DECLARE_OLD_FS_ID_VAR; SET_FS_ID (frame->root->uid, frame->root->gid); @@ -2064,6 +2169,99 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, /* the io-stats-dump key should not reach disk */ dict_del (dict, GF_XATTR_IOSTATS_DUMP_KEY); + tdata = dict_get (dict, GF_CS_OBJECT_UPLOAD_COMPLETE); + if (tdata) { + /*TODO: move the following to a different function */ + LOCK (&loc->inode->lock); + { + state = posix_cs_check_status (this, real_path, NULL, &stbuf); + if (state != GF_CS_LOCAL) { + op_errno = EINVAL; + ret = posix_cs_set_state (this, &xattr, state, real_path, + NULL); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "set state failed"); + } + goto unlock; + } + + ret = posix_pstat (this, NULL, real_path, &tmp_stbuf); + if (ret) { + op_errno = EINVAL; + goto unlock; + } + + sprintf (stime, "%lu", tmp_stbuf.ia_mtime); + + /*TODO: may be should consider nano-second also */ + if (strncmp (stime, tdata->data, tdata->len) != 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, "mtime " + "passed is different from seen by file now." + " Will skip truncating the file"); + ret = -1; + op_errno = EINVAL; + goto unlock; + } + + sprintf (sxattr, "%lu", tmp_stbuf.ia_size); + + ret = sys_lsetxattr (real_path, GF_CS_OBJECT_SIZE, + sxattr, strlen (sxattr), flags); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "setxattr failed. key %s err %d", + GF_CS_OBJECT_SIZE, ret); + op_errno = errno; + goto unlock; + } + + if (loc->path[0] == '/') { + for (i = 1; i < strlen(loc->path); i++) { + remotepath[i-1] = loc->path[i]; + } + + remotepath[i] = '\0'; + gf_msg_debug (this->name, GF_LOG_ERROR, "remotepath %s", + remotepath); + } + + + ret = sys_lsetxattr (real_path, GF_CS_OBJECT_REMOTE, + remotepath, strlen (loc->path), flags); + if (ret) { + gf_log ("POSIX", GF_LOG_ERROR, "setxattr failed - %s" + " %d", GF_CS_OBJECT_SIZE, ret); + goto unlock; + } + + ret = sys_truncate (real_path, 0); + if (ret) { + gf_log ("POSIX", GF_LOG_ERROR, "truncate failed - %s" + " %d", GF_CS_OBJECT_SIZE, ret); + op_errno = errno; + ret = sys_lremovexattr (real_path, GF_CS_OBJECT_REMOTE); + if (ret) { + gf_log ("POSIX", GF_LOG_ERROR, "removexattr " + "failed post processing- %s" + " %d", GF_CS_OBJECT_SIZE, ret); + } + goto unlock; + } else { + state = GF_CS_REMOTE; + ret = posix_cs_set_state (this, &xattr, state, real_path, + NULL); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "set state failed"); + } + } + } +unlock: + UNLOCK (&loc->inode->lock); + goto out; + } + filler.real_path = real_path; filler.this = this; filler.stbuf = &stbuf; @@ -2184,6 +2382,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, goto out; } } + out: SET_TO_OLD_FS_ID (); @@ -4265,6 +4464,7 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, struct posix_fd *pfd = NULL; int ret = -1; struct posix_private *priv = NULL; + dict_t *rsp_xdata = NULL; DECLARE_OLD_FS_ID_VAR; SET_FS_ID (frame->root->uid, frame->root->gid); @@ -4293,6 +4493,17 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, goto out; } + if (xdata) { + op_ret = posix_cs_maintenance (this, fd, NULL, &_fd, &preop, NULL, + xdata, &rsp_xdata, _gf_false); + if (op_ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + op_errno = EIO; + goto out; + } + } + op_ret = sys_ftruncate (_fd, offset); if (op_ret == -1) { @@ -4345,6 +4556,9 @@ posix_fstat (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); + if (!xdata) + gf_msg_trace (this->name, 0, "null xdata passed, fd %p", fd); + ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno); if (ret < 0) { gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL, @@ -4362,10 +4576,14 @@ posix_fstat (call_frame_t *frame, xlator_t *this, goto out; } - if (xdata) + if (xdata) { xattr_rsp = posix_xattr_fill (this, NULL, NULL, fd, _fd, xdata, &buf); + posix_cs_maintenance (this, fd, NULL, &_fd, &buf, NULL, xdata, + &xattr_rsp, _gf_false); + } + op_ret = 0; out: @@ -4898,6 +5116,7 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, struct posix_private *priv = NULL; dict_t *rsp_xdata = NULL; gf_boolean_t buf_has_zeroes = _gf_false; + struct iatt preop = {0,}; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -4926,6 +5145,25 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, _fd = pfd->fd; + if (xdata) { + op_ret = posix_fdstat (this, _fd, &preop); + if (op_ret == -1) { + op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED, + "pre-operation fstat failed on fd=%p", fd); + goto out; + } + + op_ret = posix_cs_maintenance (this, fd, NULL, &_fd, &preop, NULL, + xdata, &rsp_xdata, _gf_false); + if (op_ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + op_errno = EIO; + goto out; + } + } + LOCK (&fd->lock); { if (priv->aio_capable && priv->aio_init_done) |