diff options
Diffstat (limited to '0389-posix-Avoid-diskpace-error-in-case-of-overwriting-th.patch')
-rw-r--r-- | 0389-posix-Avoid-diskpace-error-in-case-of-overwriting-th.patch | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/0389-posix-Avoid-diskpace-error-in-case-of-overwriting-th.patch b/0389-posix-Avoid-diskpace-error-in-case-of-overwriting-th.patch new file mode 100644 index 0000000..7f20fb2 --- /dev/null +++ b/0389-posix-Avoid-diskpace-error-in-case-of-overwriting-th.patch @@ -0,0 +1,297 @@ +From 50318713486e79d9258cf22e656caff402256dde Mon Sep 17 00:00:00 2001 +From: Mohit Agrawal <moagrawal@redhat.com> +Date: Sun, 20 Oct 2019 22:01:01 +0530 +Subject: [PATCH 389/449] posix: Avoid diskpace error in case of overwriting + the data + +Problem: Sometime fops like posix_writev, posix_fallocate, posix_zerofile + failed and throw error ENOSPC if storage.reserve threshold limit + has reached even fops is overwriting the data + +Solution: Retry the fops in case of overwrite if diskspace check + is failed + +> Credits: kinsu <vpolakis@gmail.com> +> Change-Id: I987d73bcf47ed1bb27878df40c39751296e95fe8 +> Updates: #745 +> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com> +> (Cherry pick from commit ca3e5905ac02fb9c373ac3de10b44f061d04cd6f) +> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/23572/) + +Change-Id: I987d73bcf47ed1bb27878df40c39751296e95fe8 +BUG: 1787331 +Signed-off-by: Mohit Agrawal <moagrawa@redhat.com> +Reviewed-on: https://code.engineering.redhat.com/gerrit/202307 +Tested-by: RHGS Build Bot <nigelb@redhat.com> +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com> +--- + tests/bugs/posix/bug-1651445.t | 1 + + xlators/storage/posix/src/posix-entry-ops.c | 1 - + xlators/storage/posix/src/posix-inode-fd-ops.c | 141 ++++++++++++++++++++++--- + 3 files changed, 126 insertions(+), 17 deletions(-) + +diff --git a/tests/bugs/posix/bug-1651445.t b/tests/bugs/posix/bug-1651445.t +index 5248d47..4d08b69 100644 +--- a/tests/bugs/posix/bug-1651445.t ++++ b/tests/bugs/posix/bug-1651445.t +@@ -33,6 +33,7 @@ sleep 5 + # setup_lvm create lvm partition of 150M and 40M are reserve so after + # consuming more than 110M next dd should fail + TEST ! dd if=/dev/zero of=$M0/c bs=5M count=1 ++TEST dd if=/dev/urandom of=$M0/a bs=1022 count=1 oflag=seek_bytes,sync seek=102 conv=notrunc + + rm -rf $M0/* + +diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c +index 283b305..bea0bbf 100644 +--- a/xlators/storage/posix/src/posix-entry-ops.c ++++ b/xlators/storage/posix/src/posix-entry-ops.c +@@ -1634,7 +1634,6 @@ posix_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + + priv = this->private; + VALIDATE_OR_GOTO(priv, out); +- DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out); + + SET_FS_ID(frame->root->uid, frame->root->gid); + MAKE_ENTRY_HANDLE(real_oldpath, par_oldpath, this, oldloc, NULL); +diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c +index a2a518f..bcce06e 100644 +--- a/xlators/storage/posix/src/posix-inode-fd-ops.c ++++ b/xlators/storage/posix/src/posix-inode-fd-ops.c +@@ -692,6 +692,10 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + gf_boolean_t locked = _gf_false; + posix_inode_ctx_t *ctx = NULL; + struct posix_private *priv = NULL; ++ gf_boolean_t check_space_error = _gf_false; ++ struct stat statbuf = { ++ 0, ++ }; + + DECLARE_OLD_FS_ID_VAR; + +@@ -711,7 +715,10 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + if (priv->disk_reserve) + posix_disk_space_check(this); + +- DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, ret, ret, out); ++ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, ret, ret, unlock); ++ ++overwrite: ++ check_space_error = _gf_true; + + ret = posix_fd_ctx_get(fd, this, &pfd, &op_errno); + if (ret < 0) { +@@ -735,7 +742,7 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + ret = -errno; + gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED, + "fallocate (fstat) failed on fd=%p", fd); +- goto out; ++ goto unlock; + } + + if (xdata) { +@@ -745,7 +752,7 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + gf_msg(this->name, GF_LOG_ERROR, 0, 0, + "file state check failed, fd %p", fd); + ret = -EIO; +- goto out; ++ goto unlock; + } + } + +@@ -756,7 +763,7 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + "fallocate failed on %s offset: %jd, " + "len:%zu, flags: %d", + uuid_utoa(fd->inode->gfid), offset, len, flags); +- goto out; ++ goto unlock; + } + + ret = posix_fdstat(this, fd->inode, pfd->fd, statpost); +@@ -764,16 +771,47 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + ret = -errno; + gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED, + "fallocate (fstat) failed on fd=%p", fd); +- goto out; ++ goto unlock; + } + + posix_set_ctime(frame, this, NULL, pfd->fd, fd->inode, statpost); + +-out: ++unlock: + if (locked) { + pthread_mutex_unlock(&ctx->write_atomic_lock); + locked = _gf_false; + } ++ ++ if (op_errno == ENOSPC && priv->disk_space_full && !check_space_error) { ++#ifdef FALLOC_FL_KEEP_SIZE ++ if (flags & FALLOC_FL_KEEP_SIZE) { ++ goto overwrite; ++ } ++#endif ++ ret = posix_fd_ctx_get(fd, this, &pfd, &op_errno); ++ if (ret < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, ret, P_MSG_PFD_NULL, ++ "pfd is NULL from fd=%p", fd); ++ goto out; ++ } ++ ++ if (sys_fstat(pfd->fd, &statbuf) < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, op_errno, P_MSG_FILE_OP_FAILED, ++ "%d", pfd->fd); ++ goto out; ++ } ++ ++ if (offset + len <= statbuf.st_size) { ++ gf_msg_debug(this->name, 0, ++ "io vector size will not" ++ " change disk size so allow overwrite for" ++ " fd %d", ++ pfd->fd); ++ goto overwrite; ++ } ++ } ++ ++out: + SET_TO_OLD_FS_ID(); + if (ret == ENOSPC) + ret = -ENOSPC; +@@ -1083,25 +1121,57 @@ posix_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + int op_ret = -1; + int op_errno = EINVAL; + dict_t *rsp_xdata = NULL; ++ gf_boolean_t check_space_error = _gf_false; ++ struct posix_fd *pfd = NULL; ++ struct stat statbuf = { ++ 0, ++ }; + +- VALIDATE_OR_GOTO(frame, out); +- VALIDATE_OR_GOTO(this, out); ++ VALIDATE_OR_GOTO(frame, unwind); ++ VALIDATE_OR_GOTO(this, unwind); + + priv = this->private; + DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out); + ++overwrite: ++ check_space_error = _gf_true; + ret = posix_do_zerofill(frame, this, fd, offset, len, &statpre, &statpost, + xdata, &rsp_xdata); + if (ret < 0) { + op_ret = -1; + op_errno = -ret; +- goto out; ++ goto unwind; + } + + STACK_UNWIND_STRICT(zerofill, frame, 0, 0, &statpre, &statpost, rsp_xdata); + return 0; + + out: ++ if (op_errno == ENOSPC && priv->disk_space_full && !check_space_error) { ++ ret = posix_fd_ctx_get(fd, this, &pfd, &op_errno); ++ if (ret < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, ret, P_MSG_PFD_NULL, ++ "pfd is NULL from fd=%p", fd); ++ goto out; ++ } ++ ++ if (sys_fstat(pfd->fd, &statbuf) < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, op_errno, P_MSG_FILE_OP_FAILED, ++ "%d", pfd->fd); ++ goto out; ++ } ++ ++ if (offset + len <= statbuf.st_size) { ++ gf_msg_debug(this->name, 0, ++ "io vector size will not" ++ " change disk size so allow overwrite for" ++ " fd %d", ++ pfd->fd); ++ goto overwrite; ++ } ++ } ++ ++unwind: + STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, NULL, NULL, + rsp_xdata); + return 0; +@@ -1857,19 +1927,28 @@ posix_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_boolean_t write_append = _gf_false; + gf_boolean_t update_atomic = _gf_false; + posix_inode_ctx_t *ctx = NULL; ++ gf_boolean_t check_space_error = _gf_false; ++ struct stat statbuf = { ++ 0, ++ }; ++ int totlen = 0; ++ int idx = 0; + +- VALIDATE_OR_GOTO(frame, out); +- VALIDATE_OR_GOTO(this, out); +- VALIDATE_OR_GOTO(fd, out); +- VALIDATE_OR_GOTO(fd->inode, out); +- VALIDATE_OR_GOTO(vector, out); +- VALIDATE_OR_GOTO(this->private, out); ++ VALIDATE_OR_GOTO(frame, unwind); ++ VALIDATE_OR_GOTO(this, unwind); ++ VALIDATE_OR_GOTO(fd, unwind); ++ VALIDATE_OR_GOTO(fd->inode, unwind); ++ VALIDATE_OR_GOTO(vector, unwind); ++ VALIDATE_OR_GOTO(this->private, unwind); + + priv = this->private; + +- VALIDATE_OR_GOTO(priv, out); ++ VALIDATE_OR_GOTO(priv, unwind); + DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out); + ++overwrite: ++ ++ check_space_error = _gf_true; + if ((fd->inode->ia_type == IA_IFBLK) || (fd->inode->ia_type == IA_IFCHR)) { + gf_msg(this->name, GF_LOG_ERROR, EINVAL, P_MSG_INVALID_ARGUMENT, + "writev received on a block/char file (%s)", +@@ -2011,6 +2090,36 @@ out: + locked = _gf_false; + } + ++ if (op_errno == ENOSPC && priv->disk_space_full && !check_space_error) { ++ ret = posix_fd_ctx_get(fd, this, &pfd, &op_errno); ++ if (ret < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, ret, P_MSG_PFD_NULL, ++ "pfd is NULL from fd=%p", fd); ++ goto unwind; ++ } ++ ++ if (sys_fstat(pfd->fd, &statbuf) < 0) { ++ gf_msg(this->name, GF_LOG_WARNING, op_errno, P_MSG_FILE_OP_FAILED, ++ "%d", pfd->fd); ++ goto unwind; ++ } ++ ++ for (idx = 0; idx < count; idx++) { ++ totlen = vector[idx].iov_len; ++ } ++ ++ if ((offset + totlen <= statbuf.st_size) && ++ !(statbuf.st_blocks * statbuf.st_blksize < statbuf.st_size)) { ++ gf_msg_debug(this->name, 0, ++ "io vector size will not" ++ " change disk size so allow overwrite for" ++ " fd %d", ++ pfd->fd); ++ goto overwrite; ++ } ++ } ++ ++unwind: + STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, &preop, &postop, + rsp_xdata); + +-- +1.8.3.1 + |