}
LUSTRE_RW_ATTR(pcc_async_affinity);
+static ssize_t pcc_mode_show(struct kobject *kobj, struct attribute *attr,
+ char *buffer)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ struct pcc_super *super = &sbi->ll_pcc_super;
+
+ return sprintf(buffer, "0%o\n", super->pccs_mode);
+
+}
+
+static ssize_t pcc_mode_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ struct pcc_super *super = &sbi->ll_pcc_super;
+ __u32 mode;
+ int rc;
+
+ rc = kstrtouint(buffer, 8, &mode);
+ if (rc)
+ return rc;
+
+ if (mode & ~S_IRWXUGO)
+ return -EINVAL;
+
+ super->pccs_mode = mode;
+ return count;
+}
+LUSTRE_RW_ATTR(pcc_mode);
+
static ssize_t checksums_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
&lustre_attr_filename_enc_use_old_base64.attr,
#endif
&lustre_attr_pcc_async_threshold.attr,
+ &lustre_attr_pcc_mode.attr,
&lustre_attr_pcc_async_affinity.attr,
NULL,
};
INIT_LIST_HEAD(&super->pccs_datasets);
super->pccs_generation = 1;
super->pccs_async_threshold = PCC_DEFAULT_ASYNC_THRESHOLD;
+ super->pccs_mode = S_IRUSR;
return 0;
}
wake_up_all(&pcci->pcci_waitq);
}
+bool pcc_inode_permission(struct inode *inode)
+{
+ umode_t mask = inode->i_mode & ll_i2pccs(inode)->pccs_mode;
+
+ return (mask & (S_IRUSR | S_IXUSR) &&
+ inode_owner_or_capable(&nop_mnt_idmap, inode)) ||
+ (mask & (S_IRGRP | S_IXGRP) && in_group_p(inode->i_gid)) ||
+ (mask & (S_IROTH | S_IXOTH));
+}
+
int pcc_file_open(struct inode *inode, struct file *file)
{
struct pcc_inode *pcci;
if (pcc_may_auto_attach(inode, PIT_OPEN))
rc = pcc_try_auto_attach(inode, &cached, PIT_OPEN);
- if (rc == 0 && !cached)
+ if (rc == 0 && !cached && pcc_inode_permission(inode))
rc = pcc_try_readonly_open_attach(inode, file, &cached);
if (rc < 0)
CDEBUG(D_CACHE,
"PCC-RO caching for "DFID" not allowed, rc = %d\n",
PFID(ll_inode2fid(inode)), rc);
+ /* Ignore EEXIST error if the file has already attached. */
+ if (rc == -EEXIST)
+ rc = 0;
RETURN(rc);
}
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 \
}
run_test 42 "PCC attach without attach ID specified"
+test_43() {
+ 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 \
+ "size\<{100M}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ echo "attach_root_user_data" > $file || error "echo $file failed"
+
+ do_facet $SINGLEAGT $LFS pcc state $file
+ # Attach by non-root user should fail.
+ do_facet $SINGLEAGT $RUNAS $LFS pcc attach -r $file &&
+ error "PCC attach -r $file should fail for non-root user"
+ do_facet $SINGLEAGT $RUNAS $LFS pcc state $file
+ check_lpcc_state $file "none"
+}
+run_test 43 "Auto attach at open() should add capacity owner check"
+
test_44() {
local loopfile="$TMP/$tfile"
local mntpt="/mnt/pcc.$tdir"
}
run_test 45 "Concurrent read access from two mount points"
+test_46() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file=$DIR/$tfile
+ local fsuuid=$($LFS getname $MOUNT | awk '{print $1}')
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ setup_loopdev client $loopfile $mntpt 60
+ mkdir $hsm_root || error "mkdir $hsm_root failed"
+ setup_pcc_mapping client \
+ "projid={0}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1\ mmap_conv=0"
+ $LCTL pcc list $MOUNT
+
+ local mode=$($LCTL get_param -n llite.$fsuuid.pcc_mode)
+ $RUNAS id
+
+ echo "Mode: $mode"
+ echo "QQQQQ" > $file || error "write $file failed"
+ chmod 664 $file || error "chomd $file failed"
+
+ $LCTL set_param llite.$fsuuid.pcc_mode="0" ||
+ error "Set PCC mode failed"
+ stack_trap "$LCTL set_param llite.$fsuuid.pcc_mode=$mode" EXIT
+ $RUNAS $LFS pcc attach -r $file &&
+ error "User should not attach $file"
+ $RUNAS cat $file || error "cat $file failed"
+ check_lpcc_state $file "none" client
+
+ $LCTL set_param llite.$fsuuid.pcc_mode="0400" ||
+ error "Set PCC mode failed"
+ stack_trap "$LCTL set_param llite.$fsuuid.pcc_mode=$mode" EXIT
+ $RUNAS $LFS pcc attach -r $file &&
+ error "User should not attach $file"
+ $RUNAS cat $file || error "cat $file failed"
+ check_lpcc_state $file "none" client
+
+ $LCTL set_param llite.$fsuuid.pcc_mode="0004" ||
+ error "Set PCC mode failed"
+ $RUNAS cat $file || error "cat $file failed"
+ $LFS pcc state $file
+ check_lpcc_state $file "readonly" client
+ $RUNAS $LFS pcc detach $file || error "Detach $file failed"
+
+ $RUNAS stat $file || error "stat $file failed"
+ $LFS pcc attach -r $file || error "failed to attach $file"
+ check_lpcc_state $file "readonly" client
+ $RUNAS $LFS pcc detach $file || error "failed to detach $file"
+
+ $LCTL set_param llite.$fsuuid.pcc_mode="0040" ||
+ error "Set PCC mode failed"
+ chmod 660 $file || error "chmod $file failed"
+ $RUNAS cat $file || error "cat $file failed"
+ $LFS pcc state $file
+ check_lpcc_state $file "readonly" client
+ $RUNAS $LFS pcc detach $file || error "failed to detach $file"
+
+ $RUNAS $LFS pcc attach -r $file || error "attach $file failed"
+ stat $file || error "stat $file failed"
+ $LFS pcc state $file
+ check_lpcc_state $file "readonly" client
+ $RUNAS $LFS pcc detach $file || error "Detach $file failed"
+}
+run_test 46 "Verify PCC mode setting works correctly"
+
test_96() {
local loopfile="$TMP/$tfile"
local mntpt="/mnt/pcc.$tdir"