}
/**
+ * Check whether object contains compression component
+ *
+ * \retval 0 if it does not has compression component
+ * \retval 1 if it has compressoin component
+ * \retval negative on error
+ */
+static int lod_lovea_contains_compression(const struct lu_env *env,
+ struct lod_object *lo)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct lov_comp_md_v1 *lcm;
+ __u32 magic;
+ int i;
+ int rc;
+
+ ENTRY;
+
+ rc = lod_get_lov_ea(env, lo);
+ if (rc <= 0)
+ RETURN(rc);
+
+ lcm = info->lti_ea_store;
+ magic = le32_to_cpu(lcm->lcm_magic);
+ if (magic != LOV_MAGIC_COMP_V1 && magic != LOV_MAGIC_SEL)
+ RETURN(0);
+
+ for (i = 0; i < le16_to_cpu(lcm->lcm_entry_count); i++) {
+ struct lov_comp_md_entry_v1 *lcme;
+
+ lcme = &lcm->lcm_entries[i];
+ if (lcme->lcme_compr_type != LL_COMPR_TYPE_NONE)
+ RETURN(1);
+ continue;
+ }
+
+ RETURN(0);
+}
+
+/**
* Implementation of dt_object_operations::do_declare_attr_set.
*
* If the object is striped, then apply the changes to all the stripes.
int rc, i;
ENTRY;
+ /* prohibit encrypting object with compression component */
+ if (attr->la_valid & LA_FLAGS && attr->la_flags & LUSTRE_ENCRYPT_FL) {
+ rc = lod_lovea_contains_compression(env, lo);
+ if (rc < 0)
+ RETURN(rc);
+
+ if (rc > 0) {
+ CERROR("%s: cannot encrypt file with compression layout\n",
+ dt->do_lu.lo_dev->ld_obd->obd_name);
+ RETURN(-EINVAL);
+ }
+
+ }
+
/*
* declare setattr on the local object
*/
*/
static int lod_dir_declare_xattr_set(const struct lu_env *env,
struct dt_object *dt,
+ struct lu_attr *attr,
const struct lu_buf *buf,
const char *name, int fl,
struct thandle *th)
if (rc != 0)
RETURN(rc);
} else if (strcmp(name, XATTR_NAME_LOV) == 0) {
- rc = lod_verify_striping(env, d, lo, buf, false);
+ rc = lod_verify_striping(env, d, lo, attr, buf, false);
if (rc != 0)
RETURN(rc);
}
*
* \param[in] env execution environment
* \param[in] dt dt_object to add components on
+ * \param[in] attr attributes of the object
* \param[in] buf buffer contains components to be added
* \parem[in] th thandle
*
*/
static int lod_declare_layout_add(const struct lu_env *env,
struct dt_object *dt,
+ struct lu_attr *attr,
const struct lu_buf *buf,
struct thandle *th)
{
if (lo->ldo_flr_state != LCM_FL_NONE)
RETURN(-EBUSY);
- rc = lod_verify_striping(env, d, lo, buf, false);
+ rc = lod_verify_striping(env, d, lo, attr, buf, false);
if (rc != 0)
RETURN(rc);
lod_comp->llc_compr_type =
comp_v1->lcm_entries[i].lcme_compr_type;
+
lod_comp->llc_compr_lvl =
comp_v1->lcm_entries[i].lcme_compr_lvl;
lod_comp->llc_compr_chunk_log_bits =
*
* \param[in] env execution environment
* \param[in] dt object
+ * \param[in] attr attributes of the object
* \param[in] name name of xattr
* \param[in] buf lu_buf contains xattr value
* \param[in] th transaction handle
*/
static int lod_declare_modify_layout(const struct lu_env *env,
struct dt_object *dt,
+ struct lu_attr *attr,
const char *name,
const struct lu_buf *buf,
struct thandle *th)
op = (char *)name + len;
if (strcmp(op, "add") == 0) {
- rc = lod_declare_layout_add(env, dt, buf, th);
+ rc = lod_declare_layout_add(env, dt, attr, buf, th);
} else if (strcmp(op, "del") == 0) {
rc = lod_declare_layout_del(env, dt, buf, th);
} else if (strncmp(op, "set", strlen("set")) == 0) {
*/
static int lod_declare_layout_merge(const struct lu_env *env,
struct dt_object *dt,
+ struct lu_attr *attr,
const struct lu_buf *mbuf,
struct thandle *th)
{
/* check if first entry in new layout is DOM */
lmm = (struct lov_mds_md_v1 *)((char *)merge_lcm +
- merge_lcm->lcm_entries[0].lcme_offset);
+ le32_to_cpu(merge_lcm->lcm_entries[0].lcme_offset));
merge_has_dom = lov_pattern(le32_to_cpu(lmm->lmm_pattern)) &
LOV_PATTERN_MDT;
lcme = &lcm->lcm_entries[cur_entry_count + i];
*lcme = *merge_lcme;
+
+ lmm = (struct lov_mds_md_v1 *)((char *)merge_lcm +
+ le32_to_cpu(merge_lcme->lcme_offset));
+ if (lov_pattern(le32_to_cpu(lmm->lmm_pattern)) &
+ LOV_PATTERN_COMPRESS ||
+ merge_lcme->lcme_compr_type != LL_COMPR_TYPE_NONE) {
+ bool encrypted = false;
+
+ if (attr->la_valid & LA_FLAGS &&
+ attr->la_flags & LUSTRE_ENCRYPT_FL) {
+ encrypted = true;
+ } else {
+ struct lustre_ost_attrs loa;
+ struct lu_buf loa_buf = {
+ .lb_buf = &loa,
+ .lb_len = sizeof(loa),
+ };
+
+ rc = dt_xattr_get(env,
+ dt_object_child(&lo->ldo_obj),
+ &loa_buf, XATTR_NAME_LMA);
+ if (!rc &&
+ loa.loa_lma.lma_incompat & LMAI_ENCRYPT)
+ encrypted = true;
+ }
+ if (encrypted) {
+ CERROR("%s: cannot merge compression layout in encrypted file.\n",
+ dt->do_lu.lo_dev->ld_obd->obd_name);
+ GOTO(out, rc = -EINVAL);
+ }
+ }
+
lcme->lcme_offset = cpu_to_le32(offset);
if (merge_has_dom && i == 0)
lcme->lcme_flags |= cpu_to_le32(LCME_FL_STALE);
int rc;
ENTRY;
+ if (dt_object_exists(dt)) {
+ rc = dt_attr_get(env, next, attr);
+ if (rc)
+ RETURN(rc);
+ } else {
+ memset(attr, 0, sizeof(*attr));
+ }
mode = dt->do_lu.lo_header->loh_attr & S_IFMT;
if ((S_ISREG(mode) || mode == 0) &&
!(fl & (LU_XATTR_REPLACE | LU_XATTR_MERGE | LU_XATTR_SPLIT)) &&
*
* LU_XATTR_REPLACE is set to indicate a layout swap
*/
- if (dt_object_exists(dt)) {
- rc = dt_attr_get(env, next, attr);
- if (rc)
- RETURN(rc);
- } else {
- memset(attr, 0, sizeof(*attr));
+ if (!dt_object_exists(dt)) {
attr->la_valid = LA_TYPE | LA_MODE;
attr->la_mode = S_IFREG;
}
} else if (fl & LU_XATTR_MERGE) {
LASSERT(strcmp(name, XATTR_NAME_LOV) == 0 ||
strcmp(name, XATTR_LUSTRE_LOV) == 0);
- rc = lod_declare_layout_merge(env, dt, buf, th);
+ rc = lod_declare_layout_merge(env, dt, attr, buf, th);
} else if (fl & LU_XATTR_SPLIT) {
LASSERT(strcmp(name, XATTR_NAME_LOV) == 0 ||
strcmp(name, XATTR_LUSTRE_LOV) == 0);
if (!dt_object_exists(dt))
RETURN(-ENOENT);
- rc = lod_declare_modify_layout(env, dt, name, buf, th);
+ rc = lod_declare_modify_layout(env, dt, attr, name, buf, th);
} else if (S_ISDIR(mode)) {
- rc = lod_dir_declare_xattr_set(env, dt, buf, name, fl, th);
+ rc = lod_dir_declare_xattr_set(env, dt, attr, buf, name, fl,th);
} else if (strcmp(name, XATTR_NAME_FID) == 0) {
rc = lod_replace_parent_fid(env, dt, buf, th, true);
} else {
info->lti_buf.lb_buf = v1;
info->lti_buf.lb_len = sizeof(*v1);
if (declare)
- rc = lod_dir_declare_xattr_set(env, dt, &info->lti_buf,
+ rc = lod_dir_declare_xattr_set(env, dt, attr,
+ &info->lti_buf,
XATTR_NAME_DEFAULT_LMV,
0, th);
else
info->lti_buf.lb_len = lmm_size;
if (declare)
- rc = lod_dir_declare_xattr_set(env, dt, &info->lti_buf,
+ rc = lod_dir_declare_xattr_set(env, dt, attr,
+ &info->lti_buf,
XATTR_NAME_LOV, 0, th);
else
rc = lod_xattr_set_lov_on_dir(env, dt, &info->lti_buf,
struct lod_thread_info *info = lod_env_info(env);
struct lod_device *d = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev);
- rc = lod_verify_striping(env, d, lo, &info->lti_buf, false);
+ rc = lod_verify_striping(env, d, lo, NULL, &info->lti_buf,
+ false);
if (rc)
lds->lds_def_striping_set = 0;
}
{
struct lod_device *d = lu2lod_dev(child->do_lu.lo_dev);
struct lod_thread_info *info = lod_env_info(env);
+ struct lu_buf *lbuf = &lod_env_info(env)->lti_buf;
struct lod_default_striping *lds = lod_lds_buf_get(env);
struct dt_object *nextp = NULL;
struct dt_object *nextc;
if (S_ISREG(child_mode))
lod_free_comp_entries(lc);
- if (!dt_object_exists(nextc))
+ if (!dt_object_exists(nextc)) {
nextc->do_ops->do_ah_init(env, ah, nextp, nextc, child_mode);
+ /**
+ * hint that the child object to be created would be encrypted
+ * if its parent directory has been encrypted.
+ */
+ if (parent && parent->do_ops && parent->do_ops->do_xattr_get) {
+ struct lustre_ost_attrs loa;
+
+ lbuf->lb_buf = &loa;
+ lbuf->lb_len = sizeof(loa);
+ rc = dt_xattr_get(env, nextp, lbuf, XATTR_NAME_LMA);
+ if (!rc && loa.loa_lma.lma_incompat & LMAI_ENCRYPT)
+ lc->ldo_parent_encrypted = 1;
+ }
+ }
+
if (S_ISDIR(child_mode)) {
const struct lmv_user_md_v1 *lum1 = ah->dah_eadata;
if (likely(lp != NULL)) {
rc = lod_get_default_lov_striping(env, lp, lds, ah);
if (rc == 0 && lds->lds_def_striping_set) {
- rc = lod_verify_striping(env, d, lp, &info->lti_buf,
- false);
+ rc = lod_verify_striping(env, d, lp, NULL,
+ &info->lti_buf, false);
if (rc == 0)
lod_striping_from_default(lc, lds, child_mode);
}
if (rc || !lds->lds_def_striping_set)
goto out;
- rc = lod_verify_striping(env, d, d->lod_md_root, &info->lti_buf,
- false);
+ rc = lod_verify_striping(env, d, d->lod_md_root, NULL,
+ &info->lti_buf, false);
if (rc)
goto out;
* \retval negative if failed
*/
int lod_declare_striped_create(const struct lu_env *env, struct dt_object *dt,
- struct lu_attr *attr,
- const struct lu_buf *lovea, struct thandle *th)
+ struct lu_attr *attr, const struct lu_buf *lovea,
+ struct thandle *th)
{
struct lod_thread_info *info = lod_env_info(env);
struct dt_object *next = dt_object_child(dt);