From 329a009ee2b2fb5e5a8ed76e6edb038730649737 Mon Sep 17 00:00:00 2001 From: bobijam Date: Wed, 19 Nov 2008 01:29:46 +0000 Subject: [PATCH] Branch b1_8_gate b=16992 o=johann i=oleg.drokin (green) i=zhenyu.xu (bobijam) During ll_intent_lock(), server looks up parent and child, lock them, between these events parent could be deleted, then vfs_create may_access() fails with -ENOENT. Then client intent disposition got DISP_OPEN_CREATE | DISP_LOOKUP_NEG | DISP_LOOKUP_EXECD | DISP_IT_EXECD, and the request got double free. Solution: Clear DISP_ENQ_COMPLETE when we are going to release the intent (request cannot be reused anyway) --- lustre/llite/dcache.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index fb7235a..3d02a83 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -477,6 +477,9 @@ do_lock: revalidate_finish: rc = revalidate_it_finish(req, DLM_REPLY_REC_OFF, it, de); if (rc != 0) { + /* we are going release the intent, so clear DISP_ENQ_COMPLETE + * to prevent a double free of the request */ + it_clear_disposition(it, DISP_ENQ_COMPLETE); ll_intent_release(it); GOTO(out, rc = 0); } @@ -561,6 +564,9 @@ do_lookup: /* see if we got same inode, if not - return error */ if(!memcmp(&fid, &mds_body->fid1, sizeof(struct ll_fid))) goto revalidate_finish; + /* we are going release the intent, so clear DISP_ENQ_COMPLETE + * to prevent a double free of the request */ + it_clear_disposition(it, DISP_ENQ_COMPLETE); ll_intent_release(it); } GOTO(out, rc = 0); -- 1.8.3.1