summaryrefslogtreecommitdiffstats
path: root/xlators/performance/readdir-ahead
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2019-01-21 17:01:33 +0530
committerAmar Tumballi <amarts@redhat.com>2019-01-23 13:59:54 +0000
commitcf12a446f86169d0954e68dad36a7763cb178a0e (patch)
tree94aed72a17d9fa741ac4558f1b654fc96102dfbb /xlators/performance/readdir-ahead
parentd193ed84ae2886d89b899e02e9642e61bdab462a (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/performance/readdir-ahead')
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.c18
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,