summaryrefslogtreecommitdiffstats
path: root/xlators/storage
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2015-10-21 21:05:46 +0530
committerJeff Darcy <jdarcy@redhat.com>2015-10-28 06:39:42 -0700
commit641b3a9164227db52df1aab05795c90d06b315f2 (patch)
treee2a55cb4aed7e6376f6a6da55c6493247d99c366 /xlators/storage
parent8e5a7632edd040031e4942134331172805bc8eff (diff)
afr: write zeros to sink for non-sparse files
Problem: If a file is created with zeroes ('dd', 'fallocate' etc.) when a brick is down, the self-heal does not write the zeroes to the sink after it comes up. Consequenty, there is a mismatch in disk-usage amongst the bricks of the replica. Fix: If we definitely know that the file is not sparse, then write the zeroes to the sink even if the checksums match. Change-Id: Ic739b3da5dbf47d99801c0e1743bb13aeb3af864 BUG: 1272460 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/12371 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/storage')
-rw-r--r--xlators/storage/posix/src/posix.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index bc4e4904b74..b544e3739c6 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -5895,9 +5895,13 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
int op_ret = -1;
int op_errno = 0;
int ret = 0;
+ ssize_t bytes_read = 0;
int32_t weak_checksum = 0;
+ int32_t zerofillcheck = 0;
unsigned char strong_checksum[MD5_DIGEST_LENGTH] = {0};
struct posix_private *priv = NULL;
+ dict_t *rsp_xdata = NULL;
+ gf_boolean_t buf_has_zeroes = _gf_false;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -5912,6 +5916,12 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
goto out;
}
+ rsp_xdata = dict_new();
+ if (!rsp_xdata) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_msg (this->name, GF_LOG_WARNING, -ret, P_MSG_PFD_NULL,
@@ -5927,12 +5937,12 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
if (priv->aio_capable && priv->aio_init_done)
__posix_fd_set_odirect (fd, pfd, 0, offset, len);
- ret = pread (_fd, buf, len, offset);
- if (ret < 0) {
+ bytes_read = pread (_fd, buf, len, offset);
+ if (bytes_read < 0) {
gf_msg (this->name, GF_LOG_WARNING, errno,
P_MSG_PREAD_FAILED,
- "pread of %d bytes returned %d ",
- len, ret);
+ "pread of %d bytes returned %ld ",
+ len, bytes_read);
op_errno = errno;
}
@@ -5940,17 +5950,34 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
}
UNLOCK (&fd->lock);
- if (ret < 0)
+ if (bytes_read < 0)
goto out;
+ if (xdata && dict_get_int32 (xdata, "check-zero-filled",
+ &zerofillcheck) == 0) {
+ buf_has_zeroes = (mem_0filled (buf, bytes_read)) ? _gf_false :
+ _gf_true;
+ ret = dict_set_uint32 (rsp_xdata, "buf-has-zeroes",
+ buf_has_zeroes);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, -ret,
+ P_MSG_DICT_SET_FAILED, "%s: Failed to set "
+ "dictionary value for key: %s",
+ uuid_utoa (fd->inode->gfid), "buf-has-zeroes");
+ op_errno = -ret;
+ goto out;
+ }
+ }
weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret);
- gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) ret, (unsigned char *) strong_checksum);
+ gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read,
+ (unsigned char *) strong_checksum);
op_ret = 0;
out:
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno,
- weak_checksum, strong_checksum, NULL);
-
+ weak_checksum, strong_checksum, rsp_xdata);
+ if (rsp_xdata)
+ dict_unref (rsp_xdata);
GF_FREE (alloc_buf);
return 0;