Whamcloud - gitweb
LU-9679 llite: annotate non-owner locking 34/39234/3
authorMr NeilBrown <neilb@suse.de>
Thu, 2 Jul 2020 01:02:02 +0000 (11:02 +1000)
committerOleg Drokin <green@whamcloud.com>
Fri, 10 Jul 2020 16:52:05 +0000 (16:52 +0000)
The lli_lsm_sem locks taken by ll_prep_md_op_data() are sometimes
released by a different thread.  This confuses lockdep unless we
explain the situation.

So use down_read_non_owner() and up_read_non_owner().

Test-Parameters: trivial
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: Ie6543706c658fc427461ef03448f3fcf90abaab7
Reviewed-on: https://review.whamcloud.com/39234
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/llite_lib.c

index 4b77a39..66b3d2b 100644 (file)
@@ -2873,12 +2873,12 @@ out_statfs:
 void ll_unlock_md_op_lsm(struct md_op_data *op_data)
 {
        if (op_data->op_mea2_sem) {
 void ll_unlock_md_op_lsm(struct md_op_data *op_data)
 {
        if (op_data->op_mea2_sem) {
-               up_read(op_data->op_mea2_sem);
+               up_read_non_owner(op_data->op_mea2_sem);
                op_data->op_mea2_sem = NULL;
        }
 
        if (op_data->op_mea1_sem) {
                op_data->op_mea2_sem = NULL;
        }
 
        if (op_data->op_mea1_sem) {
-               up_read(op_data->op_mea1_sem);
+               up_read_non_owner(op_data->op_mea1_sem);
                op_data->op_mea1_sem = NULL;
        }
 }
                op_data->op_mea1_sem = NULL;
        }
 }
@@ -2915,7 +2915,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
        op_data->op_code = opc;
 
        if (S_ISDIR(i1->i_mode)) {
        op_data->op_code = opc;
 
        if (S_ISDIR(i1->i_mode)) {
-               down_read(&ll_i2info(i1)->lli_lsm_sem);
+               down_read_non_owner(&ll_i2info(i1)->lli_lsm_sem);
                op_data->op_mea1_sem = &ll_i2info(i1)->lli_lsm_sem;
                op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md;
                op_data->op_default_mea1 = ll_i2info(i1)->lli_default_lsm_md;
                op_data->op_mea1_sem = &ll_i2info(i1)->lli_lsm_sem;
                op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md;
                op_data->op_default_mea1 = ll_i2info(i1)->lli_default_lsm_md;
@@ -2925,7 +2925,10 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
                op_data->op_fid2 = *ll_inode2fid(i2);
                if (S_ISDIR(i2->i_mode)) {
                        if (i2 != i1) {
                op_data->op_fid2 = *ll_inode2fid(i2);
                if (S_ISDIR(i2->i_mode)) {
                        if (i2 != i1) {
-                               down_read(&ll_i2info(i2)->lli_lsm_sem);
+                               /* i2 is typically a child of i1, and MUST be
+                                * further from the root to avoid deadlocks.
+                                */
+                               down_read_non_owner(&ll_i2info(i2)->lli_lsm_sem);
                                op_data->op_mea2_sem =
                                                &ll_i2info(i2)->lli_lsm_sem;
                        }
                                op_data->op_mea2_sem =
                                                &ll_i2info(i2)->lli_lsm_sem;
                        }