path: root/xlators
diff options
authorVenky Shankar <>2015-06-04 10:07:38 +0530
committerRaghavendra Bhat <>2015-06-19 01:37:54 -0700
commitc79977c23f6108128043986995fe2eacf35dc6ac (patch)
treeb70eea13da244881b2fa4d427d9339f9ec01ee8c /xlators
parent2f027e49f4105289eb7455964eec29349bbdbf34 (diff)
features/bitrot: fix fd leak in truncate (stub)
Backport of 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: 1232179 Signed-off-by: Venky Shankar <> Reviewed-on: Tested-by: Gluster Build System <> Tested-by: NetBSD Build System <> Reviewed-by: Raghavendra Bhat <>
Diffstat (limited to 'xlators')
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 69e326b17e1..4f0605da0c4 100644
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
@@ -1434,6 +1434,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;
@@ -1482,14 +1485,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) {
@@ -1513,12 +1516,14 @@ br_stub_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
+ fd_unref (fd);
return 0;
br_stub_cleanup_local (local);
br_stub_dealloc_local (local);
+ cleanup_fd:
+ fd_unref (fd);
frame->local = NULL;
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, NULL, NULL,