return 0;
}
+static void pcc_dataset_put(struct pcc_dataset *dataset);
+
/**
* pcc_dataset_add - Add a Cache policy to control which files need be
* cached and where it will be cached.
dataset->pccd_flags = cmd->u.pccc_add.pccc_flags;
dataset->pccd_hsmtool_type = cmd->u.pccc_add.pccc_hsmtool_type;
atomic_set(&dataset->pccd_refcount, 1);
+ atomic_set(&dataset->pccd_attach_nr, 0);
+ init_waitqueue_head(&dataset->pccd_attach_waitq);
rc = pcc_dataset_rule_init(&dataset->pccd_rule, cmd);
if (rc) {
return rc;
}
-struct pcc_dataset *
-pcc_dataset_get(struct pcc_super *super, enum lu_pcc_type type, __u32 id)
+static struct pcc_dataset *
+pcc_dataset_attach_get(struct pcc_super *super, enum lu_pcc_type type, __u32 id)
{
struct pcc_dataset *dataset;
struct pcc_dataset *selected = NULL;
!(dataset->pccd_flags & PCC_DATASET_ROPCC)))
continue;
atomic_inc(&dataset->pccd_refcount);
+ atomic_inc(&dataset->pccd_attach_nr);
selected = dataset;
break;
}
return selected;
}
-void
+static void
pcc_dataset_put(struct pcc_dataset *dataset)
{
if (atomic_dec_and_test(&dataset->pccd_refcount)) {
}
}
+static void
+pcc_dataset_attach_put(struct pcc_dataset *dataset)
+{
+ if (atomic_dec_and_test(&dataset->pccd_attach_nr))
+ wake_up(&dataset->pccd_attach_waitq);
+
+ pcc_dataset_put(dataset);
+}
+
static int
pcc_dataset_del(struct pcc_super *super, char *pathname)
{
dataset = list_entry(l, struct pcc_dataset, pccd_linkage);
if (strcmp(dataset->pccd_pathname, pathname) == 0) {
list_del_init(&dataset->pccd_linkage);
+ up_write(&super->pccs_rw_sem);
+ l_wait_event_abortable(dataset->pccd_attach_waitq,
+ atomic_read(&dataset->pccd_attach_nr) == 0);
pcc_dataset_put(dataset);
super->pccs_generation++;
- rc = 0;
- break;
+ return 0;
}
}
up_write(&super->pccs_rw_sem);
static void pcc_remove_datasets(struct pcc_super *super)
{
- struct pcc_dataset *dataset, *tmp;
+ struct pcc_dataset *dataset;
down_write(&super->pccs_rw_sem);
- list_for_each_entry_safe(dataset, tmp,
- &super->pccs_datasets, pccd_linkage) {
+ while ((dataset = list_first_entry_or_null(&super->pccs_datasets,
+ struct pcc_dataset,
+ pccd_linkage)) != NULL) {
list_del(&dataset->pccd_linkage);
+ up_write(&super->pccs_rw_sem);
+ l_wait_event_abortable(dataset->pccd_attach_waitq,
+ atomic_read(&dataset->pccd_attach_nr) == 0);
pcc_dataset_put(dataset);
+ down_write(&super->pccs_rw_sem);
}
super->pccs_generation++;
up_write(&super->pccs_rw_sem);
if (rc)
RETURN(rc);
- dataset = pcc_dataset_get(&ll_i2sbi(inode)->ll_pcc_super,
- LU_PCC_READWRITE, archive_id);
+ dataset = pcc_dataset_attach_get(&ll_i2sbi(inode)->ll_pcc_super,
+ LU_PCC_READWRITE, archive_id);
if (dataset == NULL)
RETURN(-ENOENT);
dput(dentry);
}
out_dataset_put:
- pcc_dataset_put(dataset);
+ pcc_dataset_attach_put(dataset);
RETURN(rc);
}
if (rc)
RETURN(rc);
- dataset = pcc_dataset_get(&ll_s2sbi(inode->i_sb)->ll_pcc_super,
- LU_PCC_READONLY, roid);
+ dataset = pcc_dataset_attach_get(&ll_s2sbi(inode->i_sb)->ll_pcc_super,
+ LU_PCC_READONLY, roid);
if (dataset == NULL)
RETURN(-ENOENT);
if (rc)
GOTO(out_dataset_put, rc);
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LLITE_PCC_ATTACH_PAUSE, cfs_fail_val);
+
pcc_inode_lock(inode);
old_cred = override_creds(super->pccs_cred);
if (gen != ll_layout_version_get(lli)) {
revert_creds(old_cred);
pcc_inode_unlock(inode);
out_dataset_put:
- pcc_dataset_put(dataset);
+ pcc_dataset_attach_put(dataset);
RETURN(rc);
}
}
run_test 105 "Return valid flag for PCC file that is still valid cached"
+test_106() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file=$DIR/$tfile
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ setup_loopdev client $loopfile $mntpt 600
+ mkdir $hsm_root || error "mkdir $hsm_root failed"
+ setup_pcc_mapping client \
+ "projid={100}\ roid=$HSM_ARCHIVE_NUMBER\ pccro=1"
+
+ local pid
+
+ echo "Test for PCC dataset clear (PCC_CLEAR_ALL)"
+ echo "QQQQQ" > $file || error "failed to write $file"
+ # define OBD_FAIL_LLITE_PCC_ATTACH_PAUSE 0x1414
+ $LCTL set_param fail_loc=0x1414 fail_val=5
+ $LFS pcc attach $file &
+ pid=$!
+ sleep 1
+ $LCTL set_param llite.*.pcc="clear"
+ wait $pid || error "PCC attach for $file failed"
+ $LFS pcc state $file
+ $LFS pcc detach $file || error "failed to detch $file"
+
+ echo "Test for PCC dataset del (PCC_DEL_DATASET)"
+ setup_pcc_mapping client \
+ "projid={100}\ roid=$HSM_ARCHIVE_NUMBER\ pccro=1"
+ $LFS pcc attach $file &
+ sleep 1
+ $LCTL pcc clear -v $MOUNT
+}
+run_test 106 "PCC backend cleanup shound wait for all attaching finished"
+
test_200() {
local loopfile="$TMP/$tfile"
local mntpt="/mnt/pcc.$tdir"