diff options
author | Mohammed Rafi KC <rkavunga@redhat.com> | 2019-01-21 17:01:33 +0530 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2019-01-23 13:59:54 +0000 |
commit | cf12a446f86169d0954e68dad36a7763cb178a0e (patch) | |
tree | 94aed72a17d9fa741ac4558f1b654fc96102dfbb /xlators | |
parent | d193ed84ae2886d89b899e02e9642e61bdab462a (diff) |
performance/readdir-ahead: Fix deadlock in readdir ahead.
This patch fixes a lock contention in reaadir-ahead xlator.
There are two issues, one is the processing of "." ".."
entry while holding an fd_ctx lock. The other one is destroying
the stack inside a fd_ctx lock.
Change-Id: Id0bf83a3d9fea6b40015b8d167525c59c6cfa25e
updates: bz#1659708
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/performance/readdir-ahead/src/readdir-ahead.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.c b/xlators/performance/readdir-ahead/src/readdir-ahead.c index 36835473f15..e7fe0f7c7f5 100644 --- a/xlators/performance/readdir-ahead/src/readdir-ahead.c +++ b/xlators/performance/readdir-ahead/src/readdir-ahead.c @@ -492,6 +492,7 @@ rda_fill_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, 0, }; uint64_t generation = 0; + call_frame_t *fill_frame = NULL; INIT_LIST_HEAD(&serve_entries.list); LOCK(&ctx->lock); @@ -510,6 +511,7 @@ rda_fill_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, list_for_each_entry_safe(dirent, tmp, &entries->list, list) { list_del_init(&dirent->list); + /* must preserve entry order */ list_add_tail(&dirent->list, &ctx->entries.list); if (dirent->inode) { @@ -519,6 +521,7 @@ rda_fill_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, * request was initiated. So, we pass 0 for * generation number */ + generation = -1; if (ctx->writes_during_prefetch) { memset(gfid, 0, sizeof(gfid)); @@ -527,8 +530,12 @@ rda_fill_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, generation = 0; } - rda_inode_ctx_update_iatts(dirent->inode, this, &dirent->d_stat, - &dirent->d_stat, generation); + if (!((strcmp(dirent->d_name, ".") == 0) || + (strcmp(dirent->d_name, "..") == 0))) { + rda_inode_ctx_update_iatts(dirent->inode, this, + &dirent->d_stat, &dirent->d_stat, + generation); + } } dirent_size = gf_dirent_size(dirent->d_name); @@ -596,8 +603,7 @@ out: ctx->xattrs = NULL; } - rda_local_wipe(ctx->fill_frame->local); - STACK_DESTROY(ctx->fill_frame->root); + fill_frame = ctx->fill_frame; ctx->fill_frame = NULL; } @@ -606,6 +612,10 @@ out: op_errno = 0; UNLOCK(&ctx->lock); + if (fill_frame) { + rda_local_wipe(fill_frame->local); + STACK_DESTROY(fill_frame->root); + } if (serve) { STACK_UNWIND_STRICT(readdirp, stub->frame, ret, op_errno, |