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)) {
}
run_test 83 "access striped directory while it is being created/unlinked"
+test_90() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local pid1
+ local pid2
+ local duration=180
+
+ [ "$SLOW" = "yes" ] && duration=600
+ # Open/Create under striped directory
+ (
+ cd $DIR1
+ while true; do
+ $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
+ touch $tdir/f{0..3} > /dev/null 2>&1
+ done
+ ) &
+ pid1=$!
+ echo "start pid $pid1 to open/create under striped directory"
+
+ # unlink the striped directory at the same time
+ (
+ cd $DIR2
+ while true; do
+ rm -rf $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid2=$!
+ echo "start pid $pid2 to unlink striped directory"
+
+ sleep $duration
+
+ kill $pid1 $pid2
+ wait $pid1 $pid2
+
+ return 0
+}
+run_test 90 "open/create and unlink striped directory"
+
+test_91() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local pid1
+ local pid2
+ local duration=180
+
+ [ "$SLOW" = "yes" ] && duration=600
+ # chmod striped directory
+ (
+ cd $DIR1
+ while true; do
+ $LFS mkdir -c$MDSCOUNT $tdir > /dev/null 2>&1
+ chmod go+w $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid1=$!
+ echo "start pid $pid1 to chmod striped directory"
+
+ # unlink the striped directory at the same time
+ (
+ cd $DIR2
+ while true; do
+ rm -rf $tdir > /dev/null 2>&1
+ done
+ ) &
+ pid2=$!
+ echo "start pid $pid2 to unlink striped directory"
+
+ sleep $duration
+
+ kill $pid1 $pid2
+ wait $pid1 $pid2
+
+ return 0
+}
+run_test 91 "chmod and unlink striped directory"
+
log "cleanup: ======================================================"
[ "$(mount | grep $MOUNT2)" ] && umount $MOUNT2