struct mutex lli_pcc_lock;
enum lu_pcc_state_flags lli_pcc_state;
atomic_t lli_pcc_mapcnt;
-
+ /*
+ * I/O for a file previously opened before attach into
+ * PCC or once opened while in ATTACHING state will
+ * fallback to Lustre OSTs.
+ * For a later mmap() on the file, the mmap I/O also
+ * needs to fallback and cannot read from PCC directly
+ * until all fallback file handles are closed as we
+ * replace the mmaping of the PCC copy with the one of
+ * Lustre file when mmaped a file.
+ */
+ atomic_t lli_pcc_mapneg;
/*
* @lli_pcc_generation saves the gobal PCC generation
* when the file was successfully attached into PCC.
lli->lli_pcc_dsflags = PCC_DATASET_INVALID;
lli->lli_pcc_generation = 0;
atomic_set(&lli->lli_pcc_mapcnt, 0);
+ atomic_set(&lli->lli_pcc_mapneg, 0);
mutex_init(&lli->lli_group_mutex);
lli->lli_group_users = 0;
lli->lli_group_gid = 0;
{
struct pcc_inode *pcci = ll_i2pcci(inode);
+ if (!pcci)
+ return;
+
+ pcc_inode_lock(inode);
+ pcci = ll_i2pcci(inode);
if (pcci) {
WARN_ON(atomic_read(&pcci->pcci_refcount) > 1);
pcc_inode_put(pcci);
}
+ pcc_inode_unlock(inode);
}
/*
if (list_empty(&super->pccs_datasets))
RETURN(0);
+ if (lli->lli_pcc_state & PCC_STATE_FL_ATTACHING)
+ RETURN(0);
+
+ /* Forbid to auto attach the file once mmapped into PCC. */
+ if (atomic_read(&lli->lli_pcc_mapcnt) > 0)
+ RETURN(0);
+
/*
* The file layout lock was cancelled. And this open does not
* obtain valid layout lock from MDT (i.e. the file is being
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);
}
rc = pcc_get_layout_info(inode, &clt);
RETURN(lli->lli_pcc_dsflags & PCC_DATASET_IO_ATTACH);
}
-static void __pcc_layout_invalidate(struct pcc_inode *pcci)
+static inline void pcc_wait_ios_finish(struct pcc_inode *pcci)
{
- pcci->pcci_type = LU_PCC_NONE;
- pcc_layout_gen_set(pcci, CL_LAYOUT_GEN_NONE);
if (atomic_read(&pcci->pcci_active_ios) == 0)
return;
struct address_space *mapping = inode->i_mapping;
int rc;
+ pcc_wait_ios_finish(pcci);
+
/* Did we mmap this file? */
if (pcc_inode->i_mapping == &pcc_inode->i_data)
return;
/* Call with inode lock held. */
static inline void pcc_inode_detach(struct inode *inode)
{
- __pcc_layout_invalidate(ll_i2pcci(inode));
+ struct pcc_inode *pcci = ll_i2pcci(inode);
+
+ pcci->pcci_type = LU_PCC_NONE;
+ pcc_layout_gen_set(pcci, CL_LAYOUT_GEN_NONE);
pcc_inode_mapping_reset(inode);
}
return true;
}
+static inline void
+pcc_file_fallback_set(struct ll_inode_info *lli, struct pcc_file *pccf)
+{
+ atomic_inc(&lli->lli_pcc_mapneg);
+ pccf->pccf_fallback = 1;
+}
+
+static inline void
+pcc_file_fallback_reset(struct ll_inode_info *lli, struct pcc_file *pccf)
+{
+ if (pccf->pccf_fallback) {
+ pccf->pccf_fallback = 0;
+ atomic_dec(&lli->lli_pcc_mapneg);
+ }
+}
+
+static inline void
+pcc_file_mapping_reset(struct inode *inode, struct file *file, bool cached)
+{
+ struct file *pcc_file = NULL;
+
+ if (file) {
+ struct pcc_file *pccf = ll_file2pccf(file);
+
+ pcc_file = pccf->pccf_file;
+ if (!cached && !pccf->pccf_fallback)
+ pcc_file_fallback_set(ll_i2info(inode), pccf);
+ }
+
+ if (pcc_file) {
+ struct inode *pcc_inode = file_inode(pcc_file);
+
+ if (pcc_inode->i_mapping == &pcc_inode->i_data)
+ pcc_file->f_mapping = pcc_inode->i_mapping;
+ }
+}
+
static void pcc_io_init(struct inode *inode, enum pcc_io_type iot,
- bool *cached)
+ struct file *file, bool *cached)
{
struct pcc_inode *pcci;
} else {
*cached = false;
/*
- * FIXME: Forbid auto PCC attach if the file has still been
- * mmapped in PCC.
+ * Forbid to auto PCC attach if the file has still been
+ * mapped in PCC.
*/
if (pcc_may_auto_attach(inode, iot)) {
(void) pcc_try_auto_attach(inode, cached, iot);
}
}
}
+ pcc_file_mapping_reset(inode, file, *cached);
pcc_inode_unlock(inode);
}
pcc_inode_lock(inode);
pcci = ll_i2pcci(inode);
- if (lli->lli_pcc_state & PCC_STATE_FL_ATTACHING)
+ if (lli->lli_pcc_state & PCC_STATE_FL_ATTACHING) {
+ pcc_file_fallback_set(lli, pccf);
GOTO(out_unlock, rc = 0);
+ }
if (!pcci || !pcc_inode_has_layout(pcci)) {
if (pcc_may_auto_attach(inode, PIT_OPEN))
if (rc == 0 && !cached)
rc = pcc_try_readonly_open_attach(inode, file, &cached);
- if (rc < 0 || !cached)
+ if (rc < 0)
GOTO(out_unlock, rc);
+ if (!cached) {
+ pcc_file_fallback_set(lli, pccf);
+ GOTO(out_unlock, rc);
+ }
+
pcci = ll_i2pcci(inode);
}
pccf = &fd->fd_pcc_file;
pcc_inode_lock(inode);
+ pcc_file_fallback_reset(ll_i2info(inode), pccf);
+
if (pccf->pccf_file == NULL)
goto out;
RETURN(0);
}
- pcc_io_init(inode, PIT_READ, cached);
+ pcc_io_init(inode, PIT_READ, file, cached);
if (!*cached)
RETURN(0);
RETURN(0);
}
- pcc_io_init(inode, PIT_WRITE, cached);
+ pcc_io_init(inode, PIT_WRITE, file, cached);
if (!*cached)
RETURN(0);
RETURN(0);
}
- pcc_io_init(inode, PIT_SETATTR, cached);
+ pcc_io_init(inode, PIT_SETATTR, NULL, cached);
if (!*cached)
RETURN(0);
RETURN(0);
}
- pcc_io_init(inode, PIT_GETATTR, cached);
+ pcc_io_init(inode, PIT_GETATTR, NULL, cached);
if (!*cached)
RETURN(0);
RETURN(default_file_splice_read(in_file, ppos, pipe,
count, flags));
- pcc_io_init(inode, PIT_SPLICE_READ, &cached);
+ pcc_io_init(inode, PIT_SPLICE_READ, in_file, &cached);
if (!cached)
RETURN(default_file_splice_read(in_file, ppos, pipe,
count, flags));
RETURN(0);
}
- pcc_io_init(inode, PIT_FSYNC, cached);
+ pcc_io_init(inode, PIT_FSYNC, file, cached);
if (!*cached)
RETURN(0);
LASSERT(pccv);
if (vma->vm_file != pccv->pccv_file) {
struct pcc_file *pccf = ll_file2pccf(pccv->pccv_file);
+ struct file *pcc_file = pccf->pccf_file;
+ struct inode *pcc_inode = file_inode(pcc_file);
- LASSERT(vma->vm_file == pccf->pccf_file);
+ LASSERT(vma->vm_file == pcc_file);
LASSERT(vma->vm_file->f_mapping == inode->i_mapping);
vma->vm_file = pccv->pccv_file;
get_file(vma->vm_file);
- fput(pccf->pccf_file);
+ if (pcc_file->f_mapping != pcc_inode->i_mapping)
+ pcc_file->f_mapping = pcc_inode->i_mapping;
+ fput(pcc_file);
CDEBUG(D_CACHE,
DFID" mapcnt %d vm_file %p:%ld lu_file %p:%ld vma %p\n",
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;
*cached = false;
pcc_vma_file_reset(inode, vma);
}
+
+ if (!*cached && !pccf->pccf_fallback)
+ pcc_file_fallback_set(lli, pccf);
+
pcc_inode_unlock(inode);
}
int pcc_file_mmap(struct file *file, struct vm_area_struct *vma,
bool *cached)
{
- struct file *pcc_file = ll_file2pccf(file)->pccf_file;
+ struct pcc_file *pccf = ll_file2pccf(file);
+ struct file *pcc_file = pccf->pccf_file;
struct inode *inode = file_inode(file);
struct pcc_inode *pcci;
int rc = 0;
pcc_inode_lock(inode);
pcci = ll_i2pcci(inode);
if (pcci && pcc_inode_has_layout(pcci)) {
+ struct ll_inode_info *lli = ll_i2info(inode);
struct inode *pcc_inode = file_inode(pcc_file);
struct pcc_vma *pccv;
+ if (pccf->pccf_fallback) {
+ LASSERT(atomic_read(&lli->lli_pcc_mapneg) > 0);
+ GOTO(out, rc);
+ }
+
+ if (atomic_read(&lli->lli_pcc_mapneg) > 0) {
+ pcc_file_fallback_set(lli, pccf);
+ GOTO(out, rc);
+ }
+
LASSERT(atomic_read(&pcci->pcci_refcount) > 1);
*cached = true;
RETURN(rc);
}
-static int pcc_layout_rdonly_set(struct inode *inode, __u32 *gen)
+static int pcc_layout_rdonly_set(struct inode *inode, __u32 *gen, bool *cached)
{
struct ll_inode_info *lli = ll_i2info(inode);
if (rc)
RETURN(rc);
} else { /* Readonly layout */
+ struct pcc_inode *pcci;
+
*gen = clt.cl_layout_gen;
+ /*
+ * The file is already in readonly state, give a chance to
+ * try auto attach.
+ */
+ pcc_inode_lock(inode);
+ pcci = ll_i2pcci(inode);
+ if (pcci && pcc_inode_has_layout(pcci))
+ *cached = true;
+ else
+ rc = pcc_try_datasets_attach(inode, PIT_OPEN, *gen,
+ LU_PCC_READONLY, cached);
+ pcc_inode_unlock(inode);
}
RETURN(rc);
struct ll_inode_info *lli = ll_i2info(inode);
const struct cred *old_cred;
struct pcc_dataset *dataset;
- struct pcc_inode *pcci;
+ struct pcc_inode *pcci = NULL;
struct dentry *dentry;
bool attached = false;
bool unlinked = false;
+ bool cached = false;
__u32 gen;
int rc;
ENTRY;
- rc = pcc_layout_rdonly_set(inode, &gen);
+ rc = pcc_layout_rdonly_set(inode, &gen, &cached);
+ if (cached)
+ RETURN(0);
if (rc)
RETURN(rc);
if (rc)
GOTO(out_dataset_put, rc);
- mutex_lock(&lli->lli_layout_mutex);
pcc_inode_lock(inode);
old_cred = override_creds(super->pccs_cred);
- lli->lli_pcc_state &= ~PCC_STATE_FL_ATTACHING;
if (gen != ll_layout_version_get(lli)) {
CDEBUG(D_CACHE, "L.Gen mismatch %u:%u\n",
gen, ll_layout_version_get(lli));
pcc_inode_attach_set(super, dataset, lli, pcci,
dentry, LU_PCC_READONLY);
+ } else if (pcc_inode_has_layout(pcci)) {
+ /*
+ * There may be a gap between auto attach and auto open cache:
+ * ->pcc_file_open()
+ * ->pcc_try_auto_attach()
+ * The file is re-attach into PCC by other thread.
+ * ->pcc_try_readonly_open_attach()
+ */
+ CWARN("%s: The file (fid@"DFID") is already attached.\n",
+ ll_i2sbi(inode)->ll_fsname, PFID(ll_inode2fid(inode)));
+ GOTO(out_put_unlock, rc = -EEXIST);
} else {
atomic_inc(&pcci->pcci_refcount);
path_put(&pcci->pcci_path);
}
revert_creds(old_cred);
pcc_inode_unlock(inode);
- mutex_unlock(&lli->lli_layout_mutex);
out_dataset_put:
pcc_dataset_put(dataset);
struct file *pccf_file;
/* Whether readonly or readwrite PCC */
enum lu_pcc_type pccf_type;
+ /* I/O especially mmap() I/O must fallback to Lustre OSTs. */
+ __u32 pccf_fallback:1;
};
struct pcc_vma {
copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
setup_pcc_mapping $SINGLEAGT \
- "projid\>{100}\ roid=5\ ropcc=1"
+ "projid\>{100}\ roid=5\ pccro=1"
do_facet $SINGLEAGT $LCTL pcc list $MOUNT
do_facet $SINGLEAGT "echo -n QQQQQ > $file" ||
error "failed to write $file"
cleanup_pcc_mapping
setup_pcc_mapping $SINGLEAGT \
- "projid\<{100}\ roid=5\ ropcc=1"
+ "projid\<{100}\ roid=5\ pccro=1"
do_facet $SINGLEAGT $LCTL pcc list $MOUNT
do_facet $SINGLEAGT $MULTIOP $file oc ||
error "failed to readonly open $file"
cleanup_pcc_mapping
setup_pcc_mapping $SINGLEAGT \
- "projid\<{120}\&projid\>{110}\ roid=5\ ropcc=1"
+ "projid\<{120}\&projid\>{110}\ roid=5\ pccro=1"
do_facet $SINGLEAGT $LCTL pcc list $MOUNT
do_facet $SINGLEAGT $MULTIOP $file oc ||
error "failed to readonly open $file"
}
run_test 41 "Test mtime rule for PCC-RO open attach with O_RDONLY mode"
+test_96() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file1=$DIR/$tfile
+ local file2=$DIR2/$tfile
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ 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\ pccro=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.$((RANDOM % 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.$((RANDOM % 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.$((RANDOM % 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.$((RANDOM % 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.$((RANDOM % 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.$((RANDOM % 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"
+ 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 $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\ pccro=1\ mmap_conv=0"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+ do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=1G
+
+ local mpid1
+ local mpid2
+ local lpid
+
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
+ error "Write $file failed"
+
+ (
+ while [ ! -e $DIR/sanity-pcc.97.lck ]; do
+ echo "T1. $MMAP_CAT $file ..."
+ do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null ||
+ error "$MMAP_CAT $file failed"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ mpid1=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.97.lck ]; do
+ echo "T2. $MMAP_CAT $file ..."
+ do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null ||
+ error "$MMAP_CAT $file failed"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ mpid2=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.97.lck ]; do
+ do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*mdc*.lru_size=clear ||
+ error "cancel_lru_locks mdc failed"
+ sleep 0.1
+ done
+ )&
+ lpid=$!
+
+ sleep 120
+ stack_trap "rm -f $DIR/sanity-pcc.97.lck"
+ touch $DIR/sanity-pcc.97.lck
+ wait $mpid1 || error "$?: mmap1 failed"
+ wait $mpid2 || error "$?: mmap2 failed"
+ wait $lpid || error "$?: cancel locks failed"
+
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ rm -f $DIR/sanity-pcc.97.lck
+}
+run_test 97 "two mmap I/O and layout lock cancel"
+
+test_98() {
+ 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 $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\ pccro=1\ mmap_conv=0"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+ do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=1G
+
+ 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"
+
+ (
+ 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.$((RANDOM % 4 + 1))
+ done
+ )&
+ 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.$((RANDOM % 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.$((RANDOM % 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 % 2 + 1))
+ done
+ )&
+ mpid1=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.98.lck ]; do
+ do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*mdc*.lru_size=clear ||
+ error "cancel_lru_locks mdc failed"
+ sleep 0.1
+ done
+ )&
+ 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
+ stack_trap "rm -f $DIR/sanity-pcc.98.lck"
+ touch $DIR/sanity-pcc.98.lck
+ 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
+}
+run_test 98 "racer between auto attach and mmap I/O"
+
+test_99() {
+ 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 $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\ pccro=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
+ error "Write $file failed"
+
+ local rpid
+ local rpid2
+ local wpid
+ local upid
+ local dpid
+ local lpcc_path
+
+ lpcc_path=$(lpcc_fid2path $hsm_root $file)
+ (
+ while [ ! -e $DIR/sanity-pcc.99.lck ]; do
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
+ error "failed to write $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ wpid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.99.lck ]; do
+ do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 ||
+ error "failed to write $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ rpid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.99.lck ]; do
+ do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null ||
+ error "failed to mmap_cat $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ rpid2=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.99.lck ]; do
+ echo "Unlink $lpcc_path"
+ do_facet $SINGLEAGT unlink $lpcc_path
+ sleep 1
+ done
+ true
+ )&
+ upid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.99.lck ]; do
+ echo "Detach $file ..."
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ sleep 0.$((RANDOM % 8 + 1))
+ done
+ )&
+ dpid=$!
+
+ sleep 60
+ stack_trap "rm -f $DIR/sanity-pcc.99.lck"
+ touch $DIR/sanity-pcc.99.lck
+ wait $wpid || error "$?: write failed"
+ wait $rpid || error "$?: read failed"
+ wait $rpid2 || error "$?: read2 failed"
+ wait $upid || error "$?: unlink failed"
+ wait $dpid || error "$?: detach failed"
+
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ rm -f $DIR/sanity-pcc.99.lck
+}
+run_test 99 "race among unlink | mmap read | write | detach for PCC-RO file"
+
+test_100() {
+ 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 $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\ pccro=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
+ error "Write $file failed"
+
+ local rpid
+ local rpid2
+ local wpid
+ local upid
+ local dpid
+ local lpcc_path
+
+ lpcc_path=$(lpcc_fid2path $hsm_root $file)
+ (
+ while [ ! -e $DIR/sanity-pcc.100.lck ]; do
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=50 ||
+ error "failed to write $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ wpid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.100.lck ]; do
+ do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 ||
+ error "failed to write $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ rpid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.100.lck ]; do
+ do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 ||
+ error "failed to write $file"
+ sleep 0.$((RANDOM % 4 + 1))
+ done
+ )&
+ rpid2=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.100.lck ]; do
+ echo "Unlink $lpcc_path"
+ do_facet $SINGLEAGT unlink $lpcc_path
+ sleep 1
+ done
+ true
+ )&
+ upid=$!
+
+ (
+ while [ ! -e $DIR/sanity-pcc.100.lck ]; do
+ echo "Detach $file ..."
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ sleep 0.$((RANDOM % 8 + 1))
+ done
+ )&
+ dpid=$!
+
+ sleep 60
+ stack_trap "rm -f $DIR/sanity-pcc.100.lck"
+ touch $DIR/sanity-pcc.100.lck
+ wait $wpid || error "$?: write failed"
+ wait $rpid || error "$?: read failed"
+ wait $rpid2 || error "$?: read2 failed"
+ wait $upid || error "$?: unlink failed"
+ wait $dpid || error "$?: detach failed"
+
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ rm -f $DIR/sanity-pcc.100.lck
+}
+run_test 100 "race among PCC unlink | read | write | detach for PCC-RO file"
+
#test 101: containers and PCC
#LU-15170: Test mount namespaces with PCC
#This tests the cases where the PCC mount is not present in the container by
};
rc = ioctl(dirfd, LL_IOC_PCC_DETACH_BY_FID, &detach);
- return rc;
+ return rc ? -errno : 0;
}
/**
rc = ioctl(hsc->hsc_mntfd, LL_IOC_PCC_DETACH_BY_FID, &detach);
if (rc) {
rc = -errno;
- llapi_printf(LLAPI_MSG_DEBUG,
- "failed to detach file '%s': rc = %d\n",
- fidname, rc);
+ llapi_error(LLAPI_MSG_ERROR, rc,
+ "failed to detach file '%s'\n", fidname);
return rc;
}