#define LOV_V1_INSANE_STRIPE_COUNT LOV_V1_INSANE_STRIPE_INDEX /* deprecated */
#define XATTR_LUSTRE_PREFIX "lustre."
+#define XATTR_LUSTRE_PIN XATTR_LUSTRE_PREFIX"pin"
#define XATTR_LUSTRE_LOV XATTR_LUSTRE_PREFIX"lov"
/* Please update if XATTR_LUSTRE_LOV".set" groks more flags in the future */
if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T &&
(type != XATTR_SECURITY_T || !ll_xattr_is_seclabel(name)) &&
- (type != XATTR_TRUSTED_T || strcmp(name, XATTR_NAME_SOM))) {
+ (type != XATTR_TRUSTED_T || strcmp(name, XATTR_NAME_SOM)) &&
+ (type != XATTR_LUSTRE_T || strcmp(name, XATTR_LUSTRE_PIN))) {
rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
if (rc == -EAGAIN)
goto getxattr_nocache;
m->mdt_enable_parallel_rename_crossdir = 1;
m->mdt_enable_remote_dir = 1;
m->mdt_enable_remote_dir_gid = 0;
+ m->mdt_enable_pin_gid = 0;
m->mdt_enable_remote_rename = 1;
m->mdt_enable_striped_dir = 1;
m->mdt_enable_dmv_implicit_inherit = 1;
/* user with this gid can change projid */
gid_t mdt_enable_chprojid_gid;
kernel_cap_t mdt_enable_cap_mask;
+ /* user with this gid can pin/unpin file */
+ gid_t mdt_enable_pin_gid;
/* lock for osfs and md_root */
spinlock_t mdt_lock;
MDT_BOOL_RW_ATTR(enable_dmv_implicit_inherit);
MDT_BOOL_RW_ATTR(enable_dmv_xattr);
+static ssize_t enable_pin_gid_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+ if (mdt->mdt_enable_pin_gid == ~0U)
+ return scnprintf(buf, PAGE_SIZE, "-1\n");
+ return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_pin_gid);
+}
+
+static ssize_t enable_pin_gid_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ int val;
+ int rc;
+
+ rc = kstrtoint(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ mdt->mdt_enable_pin_gid = val;
+ return count;
+}
+LUSTRE_RW_ATTR(enable_pin_gid);
+
/**
* Show if the MDT is in no create mode.
*
&lustre_attr_evict_tgt_nids.attr,
&lustre_attr_enable_cap_mask.attr,
&lustre_attr_enable_chprojid_gid.attr,
+ &lustre_attr_enable_pin_gid.attr,
&lustre_attr_enable_dir_migration.attr,
&lustre_attr_enable_dir_restripe.attr,
&lustre_attr_enable_dir_auto_split.attr,
!strncmp(xattr_name, user_string, sizeof(user_string) - 1))
RETURN(-EOPNOTSUPP);
+ if (strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)
+ xattr_name = XATTR_NAME_PIN;
+
size = mo_xattr_get(info->mti_env,
mdt_object_child(info->mti_object),
&LU_BUF_NULL, xattr_name);
if (valid == OBD_MD_FLXATTR) {
const char *xattr_name = req_capsule_client_get(info->mti_pill,
&RMF_NAME);
+
+ if (strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)
+ xattr_name = XATTR_NAME_PIN;
+
rc = mo_xattr_get(info->mti_env, next, buf, xattr_name);
if (rc < 0)
GOTO(out, rc);
}
lockpart |= MDS_INODELOCK_LAYOUT;
+ } else if ((strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)) {
+ struct mdt_device *mdt = info->mti_mdt;
+ struct lu_ucred *uc = mdt_ucred(info);
+
+ if (!cap_raised(uc->uc_cap, CAP_SYS_RESOURCE) &&
+ !lustre_in_group_p(uc, mdt->mdt_enable_pin_gid) &&
+ !(mdt->mdt_enable_pin_gid == -1))
+ GOTO(out, rc = -EPERM);
+
+ xattr_name = XATTR_NAME_PIN;
}
if (!strcmp(xattr_name, XATTR_NAME_ACL_ACCESS))
run_test 204a "pin/unpin pcc flag"
test_204b() {
+ local id="100"
+ local dir=$DIR/$tdir
+ local file=$dir/$tfile
+ local old
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ (( $MDS1_VERSION >= $(version_code 2.15.61) )) ||
+ skip "Need server version at least 2.15.61"
+
+ old=$(do_facet mds1 $LCTL get_param -n mdt.*.enable_pin_gid | head -1)
+ do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=0
+ stack_trap "do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=$old"
+
+ mkdir_on_mdt0 -p $dir || error "mkdir $dir failed"
+ chmod 777 $dir || error "chown $dir failed"
+ $RUNAS touch $file || error "touch $file failed"
+ $RUNAS $LFS pcc pin -i $id $file &&
+ error "normal user should not able to pin any file"
+ $LFS pcc pin -i $id $file || error "root should be able to pin any file"
+ getfattr -d -n trusted.pin $file
+ $RUNAS $LFS pcc unpin -i $id $file &&
+ error "nonroot user should fail to unpin file"
+ $LFS pcc unpin -i $id $file ||
+ error "root should be able to unpin any file"
+ $RUNAS $LFS pcc pin -i $id $file &&
+ error "nonroot user should fail to pin file"
+
+ do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=-1
+ $RUNAS $LFS pcc pin -i $id $file ||
+ error "failed to pin $file when enable_pin_gid=-1"
+ $RUNAS $LFS pcc unpin -i $id $file ||
+ error "failed to unpin $file when enable_pin_gid=-1"
+
+ do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=$RUNAS_GID
+ $RUNAS $LFS pcc pin -i $id $file ||
+ error "failed to pin $file when enable_pin_gid=$RUNAS_GID"
+ $RUNAS $LFS pcc unpin -i $id $file ||
+ error "failed to unpin $file when enable_pin_gid=$RUNAS_GID"
+ $LFS pcc pin -i $id $file ||
+ error "failed to pin $file when enable_pin_gid=$RUNAS_GID"
+ $LFS pcc unpin -i $id $file ||
+ error "failed to unpin $file when enable_pin_gid=$RUNAS_GID"
+}
+run_test 204b "Permission check for the pin/unpin operation"
+
+test_204c() {
local loopfile="$TMP/$tfile"
local mntpt="/mnt/pcc.$tdir"
local hsm_root="$mntpt/$tdir"
xattrvalue=$(do_facet $SINGLEAGT getfattr $file -n $xattrname --only-values)
[[ -z "$xattrvalue" ]] || error "incorrect xattr $xattrname=$xattrvalue"
}
-run_test 204b "PCC pin/unpin without attach ID specified"
+run_test 204c "PCC pin/unpin without attach ID specified"
complete_test $SECONDS
check_and_cleanup_lustre
struct cYAML *yaml = NULL;
char buff[XATTR_SIZE_MAX];
- rc = getxattr(path, XATTR_NAME_PIN, buff, sizeof(buff));
+ rc = getxattr(path, XATTR_LUSTRE_PIN, buff, sizeof(buff));
if (rc < 0)
goto out;
goto out;
set:
- rc = setxattr(path, XATTR_NAME_PIN, buff, strlen(buff), 0);
+ rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
if (rc < 0)
rc = -errno;
out:
goto out;
if (strlen(buff) == 0)
- rc = removexattr(path, XATTR_NAME_PIN);
+ rc = removexattr(path, XATTR_LUSTRE_PIN);
else
- rc = setxattr(path, XATTR_NAME_PIN, buff, strlen(buff), 0);
+ rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
if (rc < 0)
rc = -errno;