diff options
author | Shreyas Siravara <sshreyas@fb.com> | 2017-09-07 16:36:29 -0700 |
---|---|---|
committer | Krutika Dhananjay <kdhananj@redhat.com> | 2017-12-08 09:07:35 +0000 |
commit | 5a29779aceec59069511cec7eff9b314e819eacc (patch) | |
tree | f2641d7f453eb3e770942b2fda3a654c23f169d8 /xlators | |
parent | 97a97bab57873083d5b49f636fd0ccbe94a310e3 (diff) |
storage/posix: Add limit to number of hard links
Summary:
Too may hard links blow up btrfs by exceeding max xattr size (recordign
pgfid for each hardlink). Add a limit to prevent this explosion.
> Reviewed-on: https://review.gluster.org/18232
> Reviewed-by: Shreyas Siravara <sshreyas@fb.com>
Fixes gluster/glusterfs#370
Signed-off-by: ShyamsundarR <srangana@redhat.com>
Change-Id: I614a247834fb8f2b2743c0c67d11cefafff0dbaa
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 5 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-common.c | 16 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-entry-ops.c | 9 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 1 |
4 files changed, 31 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 7750914705e..eef95e8809d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -2843,6 +2843,11 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "storage/posix", .op_version = GD_OP_VERSION_4_0_0, }, + { .option = "max-hardlinks", + .key = "storage.max-hardlinks", + .voltype = "storage/posix", + .op_version = GD_OP_VERSION_4_0_0, + }, { .key = "storage.bd-aio", .voltype = "storage/bd", .op_version = 3 diff --git a/xlators/storage/posix/src/posix-common.c b/xlators/storage/posix/src/posix-common.c index 011bef8a720..1b2bb609fb0 100644 --- a/xlators/storage/posix/src/posix-common.c +++ b/xlators/storage/posix/src/posix-common.c @@ -398,6 +398,8 @@ posix_reconfigure (xlator_t *this, dict_t *options) options, int32, out); priv->create_directory_mask = create_directory_mask; + GF_OPTION_RECONF ("max-hardlinks", priv->max_hardlinks, + options, uint32, out); ret = 0; out: return ret; @@ -1075,6 +1077,8 @@ posix_init (xlator_t *this) GF_OPTION_INIT ("create-directory-mask", create_directory_mask, int32, out); _private->create_directory_mask = create_directory_mask; + + GF_OPTION_INIT ("max-hardlinks", _private->max_hardlinks, uint32, out); out: if (ret) { if (_private) { @@ -1322,5 +1326,17 @@ struct volume_options options[] = { .description = "Any bit not set here will be removed from the" "modes set on a directory when it is created" }, + { + .key = {"max-hardlinks"}, + .type = GF_OPTION_TYPE_INT, + .min = 0, + .default_value = "100", + .op_version = {GD_OP_VERSION_4_0_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"posix"}, + .validate = GF_OPT_VALIDATE_MIN, + .description = "max number of hardlinks allowed on any one inode.\n" + "0 is unlimited, 1 prevents any hardlinking at all." + }, { .key = {NULL} } }; diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index 7a83eb3dfba..e7658e46543 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -1814,6 +1814,15 @@ posix_link (call_frame_t *frame, xlator_t *this, goto out; } + if (priv->max_hardlinks && stbuf.ia_nlink >= priv->max_hardlinks) { + op_ret = -1; + op_errno = EMLINK; + gf_log (this->name, GF_LOG_ERROR, + "hardlink failed: %s exceeds max link count (%u/%u).", + real_oldpath, stbuf.ia_nlink, priv->max_hardlinks); + goto out; + } + MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf); if (!real_newpath || !par_newpath) { op_ret = -1; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 36348767870..afb4b4413f6 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -239,6 +239,7 @@ struct posix_private { mode_t force_directory_mode; mode_t create_mask; mode_t create_directory_mask; + uint32_t max_hardlinks; }; typedef struct { |