diff options
author | vmallika <vmallika@redhat.com> | 2014-09-29 13:02:30 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-09-30 09:42:40 -0700 |
commit | 3dcb313572082edb07ed61145570b73a898c51e2 (patch) | |
tree | 8e41a54ccfa549d19b21583bc43ba5a9422e3487 | |
parent | 19b2923fd56f19dadf2d81a76a0008784a4f684f (diff) |
glusterd/quota: Heal pgfid xattr on existing data when the quota is enable
This is a backport of http://review.gluster.org/#/c/8878/
The pgfid extended attributes are used to construct the ancestry path
(from the file to the volume root) for nameless lookups on files.
As NFS relies on nameless lookups heavily, quota enforcement through NFS
would be inconsistent if quota were to be enabled on a volume with
existing data.
Solution is to heal the pgfid extended attributes as a part of lookup
perfomed by quota-crawl process. In a posix lookup check for pgfid xattr
and if it is missing set the xattr.
BUG: 1147953
Change-Id: I707d91a056e07452bfd1e070af5eddaa752a84ac
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/8890
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rwxr-xr-x | tests/basic/quota-anon-fd-nfs.t | 34 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 6 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-handle.h | 16 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 21 |
4 files changed, 74 insertions, 3 deletions
diff --git a/tests/basic/quota-anon-fd-nfs.t b/tests/basic/quota-anon-fd-nfs.t new file mode 100755 index 00000000000..c0af918beb4 --- /dev/null +++ b/tests/basic/quota-anon-fd-nfs.t @@ -0,0 +1,34 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume set $V0 network.inode-lru-limit 1 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST mount -t nfs localhost:/$V0 $N0 +sleep 10 +deep=/0/1/2/3/4/5/6/7/8/9 +TEST mkdir -p $N0/$deep + +TEST dd if=/dev/zero of=$N0/$deep/file bs=1K count=1M + +TEST $CLI volume quota $V0 enable +TEST $CLI volume quota $V0 limit-usage / 2GB +TEST $CLI volume quota $V0 soft-timeout 0 + +sleep 10 +TEST dd if=/dev/zero of=$N0/$deep/newfile_1 bs=500 count=1M +TEST ! dd if=/dev/zero of=$N0/$deep/newfile_2 bs=1000 count=1M + +cleanup; diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 857c4643e75..7338e826ca9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -225,9 +225,9 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, runinit (&runner); if (type == GF_QUOTA_OPTION_TYPE_ENABLE) - - runner_add_args (&runner, "/usr/bin/find", "find", ".", - NULL); + runner_add_args (&runner, "/usr/bin/find", ".", + "-exec", "/usr/bin/stat", + "{}", "\\", ";", NULL); else if (type == GF_QUOTA_OPTION_TYPE_DISABLE) { diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h index a30e0296140..a34b936229b 100644 --- a/xlators/storage/posix/src/posix-handle.h +++ b/xlators/storage/posix/src/posix-handle.h @@ -51,6 +51,22 @@ } \ } while (0) +#define SET_PGFID_XATTR_IF_ABSENT(path, key, value, flags, op_ret, this, label)\ + do { \ + op_ret = sys_lgetxattr (path, key, &value, sizeof (value)); \ + if (op_ret == -1) { \ + op_errno = errno; \ + if (op_errno == ENOATTR) { \ + value = 1; \ + SET_PGFID_XATTR (path, key, value, flags, \ + op_ret, this, label); \ + } else { \ + gf_log(this->name, GF_LOG_WARNING, "getting " \ + "xattr failed on %s: key = %s (%s)", \ + path, key, strerror (op_errno)); \ + } \ + } \ + } while (0) #define REMOVE_PGFID_XATTR(path, key, op_ret, this, label) do { \ op_ret = sys_lremovexattr (path, key); \ diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 0fc0e4e16df..549f1c4dc01 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -104,6 +104,8 @@ posix_lookup (call_frame_t *frame, xlator_t *this, char * par_path = NULL; struct iatt postparent = {0,}; int32_t gfidless = 0; + char *pgfid_xattr_key = NULL; + int32_t nlink_samepgfid = 0; struct posix_private *priv = NULL; VALIDATE_OR_GOTO (frame, out); @@ -157,6 +159,25 @@ posix_lookup (call_frame_t *frame, xlator_t *this, xdata, &buf); } + if (priv->update_pgfid_nlinks) { + if (!uuid_is_null (loc->pargfid) && !IA_ISDIR (buf.ia_type)) { + MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, + PGFID_XATTR_KEY_PREFIX, + loc->pargfid); + + LOCK (&loc->inode->lock); + { + SET_PGFID_XATTR_IF_ABSENT (real_path, + pgfid_xattr_key, + nlink_samepgfid, + XATTR_CREATE, op_ret, + this, unlock); + } +unlock: + UNLOCK (&loc->inode->lock); + } + } + parent: if (par_path) { op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); |