X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fnamei.c;h=29e379e28d438c9d244f0ce55e7d40218d8c78bd;hp=d7c28c3a34a5e48ec906b87075d0742a0a50e353;hb=d06433141bbd83e523bc611f23cb1b42935830f4;hpb=7f67aa42f9123caef3cee714f1e2cee3c6848892 diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index d7c28c3..29e379e 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -288,8 +288,34 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, hash = cl_fid_build_ino(&lli->lli_pfid, ll_need_32bit_api(ll_i2sbi(inode))); - master_inode = ilookup5(inode->i_sb, hash, - ll_test_inode_by_fid, + /* Do not lookup the inode with ilookup5, + * otherwise it will cause dead lock, + * + * 1. Client1 send chmod req to the MDT0, then + * on MDT0, it enqueues master and all of its + * slaves lock, (mdt_attr_set() -> + * mdt_lock_slaves()), after gets master and + * stripe0 lock, it will send the enqueue req + * (for stripe1) to MDT1, then MDT1 finds the + * lock has been granted to client2. Then MDT1 + * sends blocking ast to client2. + * + * 2. At the same time, client2 tries to unlink + * the striped dir (rm -rf striped_dir), and + * during lookup, it will hold the master inode + * of the striped directory, whose inode state + * is NEW, then tries to revalidate all of its + * slaves, (ll_prep_inode()->ll_iget()-> + * ll_read_inode2()-> ll_update_inode().). And + * it will be blocked on the server side because + * of 1. + * + * 3. Then the client get the blocking_ast req, + * cancel the lock, but being blocked if using + * ->ilookup5()), because master inode state is + * NEW. */ + master_inode = ilookup5_nowait(inode->i_sb, + hash, ll_test_inode_by_fid, (void *)&lli->lli_pfid); if (master_inode != NULL && !IS_ERR(master_inode)) {