Whamcloud - gitweb
LU-15562 statahead: using try lock for batched RPCs 49/46549/16
authorQian Yingjin <qian@ddn.com>
Fri, 18 Feb 2022 08:07:54 +0000 (03:07 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 31 May 2023 19:04:18 +0000 (19:04 +0000)
To avoid the possible deadlock between the batched statahead RPC
and rename()/migrate() operation, we use trylock to obtain the DLM
PR ibits lock for file attributes in a batched statahead RPC.
A failed trylock means that other users maybe modify the directory
simultaneously as the server only grants read lock to a client in
current Lustre design which is compatible with the PR lock for
attributes in stat()-ahead.
When a trylock failed, the MDT reports the conflict with the error
code -EBUSY, and the client stops the statahead immediately.

In this patch, we set "statahead_batch_max" with 64 to enable
batched statahead by default.

Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: I38394b1547e18ad156f94e49cd81aaef2f6fafb5
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/46549
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Mikhail Pershin <mpershin@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_internal.h
lustre/mdt/mdt_handler.c

index c493fb5..dde54b2 100644 (file)
@@ -1552,7 +1552,7 @@ void ll_ra_stats_inc(struct inode *inode, enum ra_stat which);
 /* statahead.c */
 
 #define LL_SA_RPC_MIN           8
-#define LL_SA_RPC_DEF           32
+#define LL_SA_RPC_DEF           128
 #define LL_SA_RPC_MAX           2048
 
 /* XXX: If want to support more concurrent statahead instances,
@@ -1563,7 +1563,7 @@ void ll_ra_stats_inc(struct inode *inode, enum ra_stat which);
 #define LL_SA_RUNNING_DEF      16
 
 #define LL_SA_BATCH_MAX                1024
-#define LL_SA_BATCH_DEF                0
+#define LL_SA_BATCH_DEF                64
 
 #define LL_SA_CACHE_BIT         5
 #define LL_SA_CACHE_SIZE        (1 << LL_SA_CACHE_BIT)
index 782ddef..e31fee0 100644 (file)
@@ -2346,6 +2346,29 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                                try_bits |= MDS_INODELOCK_DOM;
                }
 
+               /*
+                * To avoid possible deadlock between batched statahead RPC
+                * and rename()/migrate() operation, it should use trylock to
+                * obtain the DLM PR ibits lock for file attributes in a
+                * batched statahead RPC. A failed trylock means that other
+                * users maybe modify the directory simultaneously as in current
+                * Lustre design the server only grants read lock to a client.
+                *
+                * When a trylock failed, the MDT reports the conflict with
+                * error code -EBUSY, and stops statahead immediately.
+                */
+               if (info->mti_batch_env) {
+                       /*
+                        * This is a sub stat-ahead request in a batched RPC.
+                        * However, the @child is a remote object, we just
+                        * return -EREMOTE here to forbid stat-ahead on it.
+                        */
+                       if (mdt_object_remote(child))
+                               GOTO(out_child, rc = -EREMOTE);
+                       try_bits |= child_bits;
+                       child_bits = 0;
+               }
+
                if (try_bits != 0) {
                        /* try layout lock, it may fail to be granted due to
                         * contention at LOOKUP or UPDATE */
@@ -2365,6 +2388,11 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info,
                }
                if (unlikely(rc != 0))
                        GOTO(out_child, rc);
+               if (info->mti_batch_env && child_bits == 0) {
+                       if (!is_resent)
+                               mdt_object_unlock(info, child, lhc, 1);
+                       GOTO(out_child, rc = -EBUSY);
+               }
        }
 
        if (fscrypt_md)