Whamcloud - gitweb
EX-3663 pcc: auto attach should skip if already attached
authorQian Yingjin <qian@ddn.com>
Wed, 18 Aug 2021 02:03:23 +0000 (10:03 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Sat, 28 Aug 2021 01:26:36 +0000 (01:26 +0000)
When try to auto attach a file into PCC, if found that the file
had already attached into PCC, it should skip the auto attach
processing. Otherwise, it will result in wrong PCC inode refcount
when multiple threads try to auto attach a file at the same time.

For a file once mmapped into PCC and detached due to layout lock
shrinking or manual detach command, If found that file is still
valid cached (attach into PCC again by another thread), in the
@pcc_mmap_io_init(), it should set the mapping of PCC copy with
the one of Lustre file again.

Test-Parameters: testlist=sanity-pcc,sanity-pcc,sanity-pcc
Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: I5f049ca7d6db8708712e79e9ad459fc60b80f2be
Reviewed-on: https://review.whamcloud.com/44697
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/llite/pcc.c
lustre/tests/sanity-pcc.sh

index 47501c8..4ff9de9 100644 (file)
@@ -1939,12 +1939,20 @@ static int pcc_try_auto_attach(struct inode *inode, bool *cached,
                if (ll_layout_version_get(lli) == CL_LAYOUT_GEN_NONE)
                        RETURN(0);
        } else {
+               struct pcc_inode *pcci;
+
                pcc_inode_unlock(inode);
                rc = ll_layout_refresh(inode, &gen);
                pcc_inode_lock(inode);
                if (rc)
                        RETURN(rc);
 
+               pcci = ll_i2pcci(inode);
+               if (pcci && pcc_inode_has_layout(pcci)) {
+                       *cached = true;
+                       RETURN(0);
+               }
+
                if (atomic_read(&lli->lli_pcc_mapcnt) > 0)
                        RETURN(0);
        }
@@ -2668,23 +2676,49 @@ static void pcc_mmap_vma_reset(struct inode *inode, struct vm_area_struct *vma)
        pcc_inode_unlock(inode);
 }
 
+static int pcc_mmap_mapping_set(struct inode *inode, struct inode *pcc_inode);
+
 static void pcc_mmap_io_init(struct inode *inode, enum pcc_io_type iot,
                             struct vm_area_struct *vma, bool *cached)
 {
        struct pcc_vma *pccv = (struct pcc_vma *)vma->vm_private_data;
+       struct ll_inode_info *lli = ll_i2info(inode);
        struct pcc_inode *pcci;
+       struct pcc_file *pccf;
 
        LASSERT(pccv);
 
        pcc_inode_lock(inode);
        pcci = ll_i2pcci(inode);
+       pccf = ll_file2pccf(pccv->pccv_file);
        if (pcci && pcc_inode_has_layout(pcci)) {
+               struct inode *pcc_inode = pcci->pcci_path.dentry->d_inode;
+
                LASSERT(atomic_read(&pcci->pcci_refcount) > 0);
+
                if (pcci->pcci_type == LU_PCC_READONLY &&
                    iot == PIT_PAGE_MKWRITE) {
                        pcc_inode_detach_put(inode);
                        pcc_vma_file_reset(inode, vma);
                        *cached = false;
+               } else if (pcc_inode->i_mapping == &pcc_inode->i_data) {
+                       if (atomic_read(&lli->lli_pcc_mapneg) > 0) {
+                               pcc_inode_detach_put(inode);
+                               pcc_vma_file_reset(inode, vma);
+                               *cached = false;
+                       } else {
+                               int rc;
+
+                               rc = pcc_mmap_mapping_set(inode, pcc_inode);
+                               if (rc) {
+                                       pcc_inode_detach_put(inode);
+                                       pcc_vma_file_reset(inode, vma);
+                                       *cached = false;
+                               } else {
+                                       atomic_inc(&pcci->pcci_active_ios);
+                                       *cached = true;
+                               }
+                       }
                } else {
                        atomic_inc(&pcci->pcci_active_ios);
                        *cached = true;
@@ -2693,6 +2727,10 @@ static void pcc_mmap_io_init(struct inode *inode, enum pcc_io_type iot,
                *cached = false;
                pcc_vma_file_reset(inode, vma);
        }
+
+       if (!*cached && !pccf->pccf_fallback)
+               pcc_file_fallback_set(lli, pccf);
+
        pcc_inode_unlock(inode);
 }
 
index 4507b2f..a1d73b7 100644 (file)
@@ -3346,6 +3346,114 @@ test_43() {
 }
 run_test 43 "Auto attach at open() should add capacity owner check"
 
+test_96() {
+       local loopfile="$TMP/$tfile"
+       local mntpt="/mnt/pcc.$tdir"
+       local hsm_root="$mntpt/$tdir"
+       local file1=$DIR/$tfile
+       local file2=$DIR2/$tfile
+
+       setup_loopdev $SINGLEAGT $loopfile $mntpt 60
+       do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed"
+       setup_pcc_mapping $SINGLEAGT \
+               "projid={0}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1\ mmap_conv=0"
+       do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+       do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=1G
+
+       local rpid11
+       local rpid12
+       local rpid13
+       local rpid21
+       local rpid22
+       local rpid23
+       local lpid
+
+       local bs="1M"
+       local count=50
+
+       do_facet $SINGLEAGT dd if=/dev/zero of=$file1 bs=$bs count=$count ||
+               error "Write $file failed"
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file1 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid11=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file1 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid12=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file1 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid13=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file2 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid21=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file2 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid22=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file2 of=/dev/null bs=$bs count=$count ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid23=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.96.lck ]; do
+                       do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*mdc*.lru_size=clear ||
+                               error "cancel_lru_locks mdc failed"
+                       sleep 0.5
+               done
+       )&
+       lpid=$!
+
+       sleep 60
+       touch $DIR/sanity-pcc.96.lck
+
+       echo "Finish ========"
+       wait $rpid11 || error "$?: read failed"
+       wait $rpid12 || error "$?: read failed"
+       wait $rpid13 || error "$?: read failed"
+       wait $rpid21 || error "$?: read failed"
+       wait $rpid22 || error "$?: read failed"
+       wait $rpid23 || error "$?: read failed"
+       wait $lpid || error "$?: lock cancel failed"
+
+       do_facet $SINGLEAGT $LFS pcc detach $file
+       rm -f $DIR/sanity-pcc.96.lck
+}
+run_test 96 "Auto attach from multiple read process on a node"
+
 test_97() {
        local loopfile="$TMP/$tfile"
        local mntpt="/mnt/pcc.$tdir"
@@ -3417,11 +3525,16 @@ test_98() {
        setup_pcc_mapping $SINGLEAGT \
                "projid={0}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1\ mmap_conv=0"
        do_facet $SINGLEAGT $LCTL pcc list $MOUNT
-       do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=0
+       do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=1G
 
-       local rpid
-       local mpid
-       local lpid
+       local rpid1
+       local rpid2
+       local rpid3
+       local mpid1
+       local mpid2
+       local mpid3
+       local lpid1
+       local lpid2
 
        do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
                error "Write $file failed"
@@ -3433,16 +3546,34 @@ test_98() {
                        sleep 0.$((RANDON % 4 + 1))
                done
        )&
-       rpid=$!
+       rpid1=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.98.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid2=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.98.lck ]; do
+                       do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 ||
+                               error "Read $file failed"
+                       sleep 0.$((RANDON % 4 + 1))
+               done
+       )&
+       rpid3=$!
 
        (
                while [ ! -e $DIR/sanity-pcc.98.lck ]; do
                        do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null ||
                                error "$MMAP_CAT $file failed"
-                       sleep 0.$((RANDOM % 4 + 1))
+                       sleep 0.$((RANDOM % 2 + 1))
                done
        )&
-       mpid=$!
+       mpid1=$!
 
        (
                while [ ! -e $DIR/sanity-pcc.98.lck ]; do
@@ -3451,13 +3582,25 @@ test_98() {
                        sleep 0.1
                done
        )&
-       lpid=$!
+       lpid1=$!
+
+       (
+               while [ ! -e $DIR/sanity-pcc.98.lck ]; do
+                       do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*osc*.lru_size=clear ||
+                               error "cancel_lru_locks mdc failed"
+                       sleep 0.1
+               done
+       )&
+       lpid2=$!
 
        sleep 60
        touch $DIR/sanity-pcc.98.lck
-       wait $rpid || error "$?: read failed"
-       wait $mpid || error "$?: mmap failed"
-       wait $lpid || error "$?: cancel locks failed"
+       wait $rpid1 || error "$?: read failed"
+       wait $rpid2 || error "$?: read failed"
+       wait $rpid3 || error "$?: read failed"
+       wait $mpid1 || error "$?: mmap failed"
+       wait $lpid1 || error "$?: cancel locks failed"
+       wait $lpid2 || error "$?: cancel locks failed"
 
        do_facet $SINGLEAGT $LFS pcc detach $file
        rm -f $DIR/sanity-pcc.98.lck