d2787b
From 0e453ede1f248a004965d0d368e2c4beb83f2ce1 Mon Sep 17 00:00:00 2001
d2787b
From: Vinayakswami Hariharmath <vharihar@redhat.com>
d2787b
Date: Mon, 25 Jan 2021 17:32:14 +0530
d2787b
Subject: [PATCH 573/584] features/shard: unlink fails due to nospace to mknod
d2787b
 marker file
d2787b
d2787b
When we hit the max capacity of the storage space, shard_unlink()
d2787b
starts failing if there is no space left on the brick to create a
d2787b
marker file.
d2787b
d2787b
shard_unlink() happens in below steps:
d2787b
d2787b
1. create a marker file in the name of gfid of the base file under
d2787b
BRICK_PATH/.shard/.remove_me
d2787b
2. unlink the base file
d2787b
3. shard_delete_shards() deletes the shards in background by
d2787b
picking the entries in BRICK_PATH/.shard/.remove_me
d2787b
d2787b
If a marker file creation fails then we can't really delete the
d2787b
shards which eventually a problem for user who is looking to make
d2787b
space by deleting unwanted data.
d2787b
d2787b
Solution:
d2787b
Create the marker file by marking xdata = GLUSTERFS_INTERNAL_FOP_KEY
d2787b
which is considered to be internal op and allowed to create under
d2787b
reserved space.
d2787b
d2787b
Backport of:
d2787b
> Upstream-patch: https://github.com/gluster/glusterfs/pull/2057
d2787b
> Fixes: #2038
d2787b
> Change-Id: I7facebab940f9aeee81d489df429e00ef4fb7c5d
d2787b
> Signed-off-by: Vinayakswami Hariharmath <vharihar@redhat.com>
d2787b
d2787b
BUG: 1891403
d2787b
Change-Id: I7facebab940f9aeee81d489df429e00ef4fb7c5d
d2787b
Signed-off-by: Vinayakswami Hariharmath <vharihar@redhat.com>
d2787b
Reviewed-on: https://code.engineering.redhat.com/gerrit/c/rhs-glusterfs/+/244966
d2787b
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d2787b
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
d2787b
---
d2787b
 tests/bugs/shard/issue-2038.t      | 56 ++++++++++++++++++++++++++++++++++++++
d2787b
 xlators/features/shard/src/shard.c | 20 ++++++++++++++
d2787b
 2 files changed, 76 insertions(+)
d2787b
 create mode 100644 tests/bugs/shard/issue-2038.t
d2787b
d2787b
diff --git a/tests/bugs/shard/issue-2038.t b/tests/bugs/shard/issue-2038.t
d2787b
new file mode 100644
d2787b
index 0000000..fc3e7f9
d2787b
--- /dev/null
d2787b
+++ b/tests/bugs/shard/issue-2038.t
d2787b
@@ -0,0 +1,56 @@
d2787b
+#!/bin/bash
d2787b
+
d2787b
+. $(dirname $0)/../../include.rc
d2787b
+. $(dirname $0)/../../volume.rc
d2787b
+. $(dirname $0)/../../snapshot.rc
d2787b
+
d2787b
+cleanup
d2787b
+
d2787b
+FILE_COUNT_TIME=5
d2787b
+
d2787b
+function get_file_count {
d2787b
+    ls $1* | wc -l
d2787b
+}
d2787b
+
d2787b
+TEST verify_lvm_version
d2787b
+TEST glusterd
d2787b
+TEST pidof glusterd
d2787b
+TEST init_n_bricks 1
d2787b
+TEST setup_lvm 1
d2787b
+
d2787b
+TEST $CLI volume create $V0 $H0:$L1
d2787b
+TEST $CLI volume start $V0
d2787b
+
d2787b
+$CLI volume info
d2787b
+
d2787b
+TEST $CLI volume set $V0 features.shard on
d2787b
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0
d2787b
+
d2787b
+#Setting the size in percentage
d2787b
+TEST $CLI volume set $V0 storage.reserve 40
d2787b
+
d2787b
+#wait 5s to reset disk_space_full flag
d2787b
+sleep 5
d2787b
+
d2787b
+TEST touch $M0/test
d2787b
+TEST unlink $M0/test
d2787b
+
d2787b
+TEST dd if=/dev/zero of=$M0/a bs=80M count=1
d2787b
+TEST dd if=/dev/zero of=$M0/b bs=10M count=1
d2787b
+
d2787b
+gfid_new=$(get_gfid_string $M0/a)
d2787b
+
d2787b
+# Wait 5s to update disk_space_full flag because thread check disk space
d2787b
+# after every 5s
d2787b
+
d2787b
+sleep 5
d2787b
+# setup_lvm create lvm partition of 150M and 40M are reserve so after
d2787b
+# consuming more than 110M next unlink should not fail
d2787b
+# Delete the base shard and check shards get cleaned up
d2787b
+TEST unlink $M0/a
d2787b
+TEST ! stat $M0/a
d2787b
+
d2787b
+TEST $CLI volume stop $V0
d2787b
+TEST $CLI volume delete $V0
d2787b
+
d2787b
+cleanup
d2787b
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
d2787b
index d1d7d7a..8d4a970 100644
d2787b
--- a/xlators/features/shard/src/shard.c
d2787b
+++ b/xlators/features/shard/src/shard.c
d2787b
@@ -4078,6 +4078,16 @@ shard_create_marker_file_under_remove_me(call_frame_t *frame, xlator_t *this,
d2787b
     SHARD_INODE_CREATE_INIT(this, bs, xattr_req, &local->newloc,
d2787b
                             local->prebuf.ia_size, 0, err);
d2787b
 
d2787b
+    /* Mark this as an internal operation, so that in case of disk full,
d2787b
+     * the marker file will be created as part of reserve space */
d2787b
+    ret = dict_set_int32_sizen(xattr_req, GLUSTERFS_INTERNAL_FOP_KEY, 1);
d2787b
+    if (ret < 0) {
d2787b
+        gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED,
d2787b
+               "Failed to set key: %s on path %s", GLUSTERFS_INTERNAL_FOP_KEY,
d2787b
+               local->newloc.path);
d2787b
+        goto err;
d2787b
+    }
d2787b
+
d2787b
     STACK_WIND(frame, shard_create_marker_file_under_remove_me_cbk,
d2787b
                FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
d2787b
                &local->newloc, 0, 0, 0644, xattr_req);
d2787b
@@ -5843,6 +5853,16 @@ shard_mkdir_internal_dir(call_frame_t *frame, xlator_t *this,
d2787b
 
d2787b
     SHARD_SET_ROOT_FS_ID(frame, local);
d2787b
 
d2787b
+    /* Mark this as an internal operation, so that in case of disk full
d2787b
+     * the internal dir will be created as part of reserve space */
d2787b
+    ret = dict_set_int32_sizen(xattr_req, GLUSTERFS_INTERNAL_FOP_KEY, 1);
d2787b
+    if (ret < 0) {
d2787b
+        gf_msg(this->name, GF_LOG_WARNING, 0, SHARD_MSG_DICT_OP_FAILED,
d2787b
+               "Failed to set key: %s on path %s", GLUSTERFS_INTERNAL_FOP_KEY,
d2787b
+               loc->path);
d2787b
+        goto err;
d2787b
+    }
d2787b
+
d2787b
     STACK_WIND_COOKIE(frame, shard_mkdir_internal_dir_cbk, (void *)(long)type,
d2787b
                       FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc,
d2787b
                       0755, 0, xattr_req);
d2787b
-- 
d2787b
1.8.3.1
d2787b