diff options
author | Venky Shankar <vshankar@redhat.com> | 2015-06-04 10:07:38 +0530 |
---|---|---|
committer | Raghavendra Bhat <raghavendra@redhat.com> | 2015-06-16 02:22:21 -0700 |
commit | 8e81dccfce17db2d388de95b0b009478cc7d0d4d (patch) | |
tree | b75b93bb4ae24e6fa6faac33fa8d9b416d8ef61e /xlators/features/bit-rot/src | |
parent | 1ac3d28d8dde6360550c80a10d8add572937be16 (diff) |
features/bitrot: fix fd leak in truncate (stub)
The need to perform object versioning in the truncate() code path
required an fd to reuse existing versioning infrastructure that's
used by fd based operations (such as writev(), ftruncate(), etc..).
This tempted the use of anonymous fd which was never ever unref()'d
after use resulting in fd and/or memory leak depending on the code
path taken. Versioning resulted in a dangling file descriptor left
open in the filesystem effecting the signing process of a given
object (no release() would be trigerred, hence no signing would be
performed). On the other hand, cases where the object need not be
versioned, the anonymous fd in still ref()'d resulting in memory
leak (NOTE: there's no "dangling" file descriptor in this case).
Change-Id: I29c3d2af9bbc5cd4b8ddf38954080e3c7a44ba61
BUG: 1227996
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Reviewed-on: http://review.gluster.org/11077
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Diffstat (limited to 'xlators/features/bit-rot/src')
-rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index 2f2e16df226..5238f4333bb 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -1548,6 +1548,9 @@ int32_t br_stub_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { + br_stub_local_t *local = frame->local; + + fd_unref (local->u.context.fd); STACK_WIND (frame, br_stub_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; @@ -1596,14 +1599,14 @@ br_stub_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, ret = br_stub_need_versioning (this, fd, &inc_version, &modified, &ctx); if (ret) - goto unwind; + goto cleanup_fd; if (!inc_version && modified) goto wind; ret = br_stub_versioning_prep (frame, this, fd, ctx); if (ret) - goto unwind; + goto cleanup_fd; local = frame->local; if (!inc_version) { @@ -1627,12 +1630,14 @@ br_stub_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, wind: STACK_WIND (frame, cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); + fd_unref (fd); return 0; cleanup_local: br_stub_cleanup_local (local); br_stub_dealloc_local (local); - + cleanup_fd: + fd_unref (fd); unwind: frame->local = NULL; STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, NULL, NULL, |