#include <lustre_mds.h>
#include <lustre_fid.h>
#include <lustre_lmv.h>
+#include <lustre_idmap.h>
#include "mdd_internal.h"
}
rc = mdd_permission_internal_locked(env, mdd_obj, pattr, mask,
- MOR_TGT_PARENT);
+ DT_TGT_PARENT);
if (rc)
RETURN(rc);
ENTRY;
- LASSERT(S_ISDIR(mdd_object_type(obj)));
+ LASSERTF(S_ISDIR(mdd_object_type(obj)),
+ "%s: FID "DFID" is not a directory type = %o\n",
+ mdd_obj_dev_name(obj), PFID(mdd_object_fid(obj)),
+ mdd_object_type(obj));
buf = lu_buf_check_and_alloc(buf, PATH_MAX);
if (buf->lb_buf == NULL)
iops->put(env, it);
iops->fini(env, it);
- } else
+ } else {
result = PTR_ERR(it);
+ /* -ENODEV means no valid stripe */
+ if (result == -ENODEV)
+ RETURN(0);
+ }
RETURN(result);
}
if (check_perm)
rc = mdd_permission_internal_locked(env, pobj, pattr,
MAY_WRITE | MAY_EXEC,
- MOR_TGT_PARENT);
+ DT_TGT_PARENT);
RETURN(rc);
}
rc = mdd_permission_internal_locked(env, pobj, pattr,
MAY_WRITE | MAY_EXEC,
- MOR_TGT_PARENT);
+ DT_TGT_PARENT);
if (rc != 0)
RETURN(rc);
int rc;
rc = mdd_permission_internal_locked(env, pobj, pattr,
MAY_WRITE | MAY_EXEC,
- MOR_TGT_PARENT);
+ DT_TGT_PARENT);
if (rc)
RETURN(rc);
}
rc = __mdd_index_insert_only(env, pobj, lf, type, name, handle);
if (rc == 0 && S_ISDIR(type)) {
- mdd_write_lock(env, pobj, MOR_TGT_PARENT);
+ mdd_write_lock(env, pobj, DT_TGT_PARENT);
mdo_ref_add(env, pobj, handle);
mdd_write_unlock(env, pobj);
}
const char *name, int is_dir,
struct thandle *handle)
{
- int rc;
- ENTRY;
+ int rc;
+ ENTRY;
rc = __mdd_index_delete_only(env, pobj, name, handle);
- if (rc == 0 && is_dir) {
- mdd_write_lock(env, pobj, MOR_TGT_PARENT);
- mdo_ref_del(env, pobj, handle);
- mdd_write_unlock(env, pobj);
- }
+ if (rc == 0 && is_dir) {
+ mdd_write_lock(env, pobj, DT_TGT_PARENT);
+ mdo_ref_del(env, pobj, handle);
+ mdd_write_unlock(env, pobj);
+ }
- RETURN(rc);
+ RETURN(rc);
}
static int mdd_llog_record_calc_size(const struct lu_env *env,
const struct lu_name *sname)
{
const struct lu_ucred *uc = lu_ucred(env);
- enum changelog_rec_flags crf = CLF_EXTRA_FLAGS;
+ enum changelog_rec_flags clf_flags = CLF_EXTRA_FLAGS;
enum changelog_rec_extra_flags crfe = CLFE_UIDGID | CLFE_NID;
if (sname != NULL)
- crf |= CLF_RENAME;
+ clf_flags |= CLF_RENAME;
if (uc != NULL && uc->uc_jobid[0] != '\0')
- crf |= CLF_JOBID;
+ clf_flags |= CLF_JOBID;
return llog_data_len(LLOG_CHANGELOG_HDR_SZ +
- changelog_rec_offset(crf, crfe) +
+ changelog_rec_offset(clf_flags, crfe) +
(tname != NULL ? tname->ln_namelen : 0) +
(sname != NULL ? 1 + sname->ln_namelen : 0));
}
clnid->cr_nid = nid;
}
-void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags)
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, u32 flags)
{
struct changelog_ext_openmode *omd = changelog_rec_openmode(rec);
- omd->cr_openflags = (__u32)flags;
+ omd->cr_openflags = flags;
}
void mdd_changelog_rec_extra_xattr(struct changelog_rec *rec,
const char *xattr_name)
{
- struct changelog_ext_xattr *xattr = changelog_rec_xattr(rec);
+ struct changelog_ext_xattr *xattr = changelog_rec_xattr(rec);
strlcpy(xattr->cr_xattr, xattr_name, sizeof(xattr->cr_xattr));
}
int mdd_changelog_ns_store(const struct lu_env *env,
struct mdd_device *mdd,
enum changelog_rec_type type,
- enum changelog_rec_flags crf,
+ enum changelog_rec_flags clf_flags,
struct mdd_object *target,
const struct lu_fid *tpfid,
const struct lu_fid *sfid,
RETURN(-ENOMEM);
rec = buf->lb_buf;
- crf &= CLF_FLAGMASK;
- crf |= CLF_EXTRA_FLAGS;
+ clf_flags &= CLF_FLAGMASK;
+ clf_flags |= CLF_EXTRA_FLAGS;
if (uc) {
if (uc->uc_jobid[0] != '\0')
- crf |= CLF_JOBID;
+ clf_flags |= CLF_JOBID;
xflags |= CLFE_UIDGID;
xflags |= CLFE_NID;
}
if (sname != NULL)
- crf |= CLF_RENAME;
+ clf_flags |= CLF_RENAME;
else
- crf |= CLF_VERSION;
+ clf_flags |= CLF_VERSION;
- rec->cr.cr_flags = crf;
+ rec->cr.cr_flags = clf_flags;
- if (crf & CLF_EXTRA_FLAGS) {
+ if (clf_flags & CLF_EXTRA_FLAGS) {
mdd_changelog_rec_ext_extra_flags(&rec->cr, xflags);
if (xflags & CLFE_UIDGID)
mdd_changelog_rec_extra_uidgid(&rec->cr,
rec->cr.cr_namelen = tname->ln_namelen;
memcpy(changelog_rec_name(&rec->cr), tname->ln_name, tname->ln_namelen);
- if (crf & CLF_RENAME)
+ if (clf_flags & CLF_RENAME)
mdd_changelog_rec_ext_rename(&rec->cr, sfid, spfid, sname);
- if (crf & CLF_JOBID)
+ if (clf_flags & CLF_JOBID)
mdd_changelog_rec_ext_jobid(&rec->cr, uc->uc_jobid);
if (likely(target != NULL)) {
if (rc)
GOTO(stop, rc);
- mdd_write_lock(env, mdd_sobj, MOR_TGT_CHILD);
+ mdd_write_lock(env, mdd_sobj, DT_TGT_CHILD);
rc = mdd_link_sanity_check(env, mdd_tobj, tattr, lname, mdd_sobj,
cattr);
if (rc)
struct lu_attr *attr = MDD_ENV_VAR(env, la_for_start);
int rc;
- if (!S_ISDIR(mdd_object_type(obj)))
- return 0;
-
attr->la_valid = LA_FLAGS;
attr->la_flags = LUSTRE_ORPHAN_FL;
GOTO(stop, rc);
if (likely(mdd_cobj != NULL))
- mdd_write_lock(env, mdd_cobj, MOR_TGT_CHILD);
+ mdd_write_lock(env, mdd_cobj, DT_TGT_CHILD);
if (likely(no_name == 0) && !OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DANGLING2)) {
rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle);
spec->u.sp_ea.eadata != NULL && spec->u.sp_ea.eadatalen > 0) {
const struct lmv_user_md *lum = spec->u.sp_ea.eadata;
- if (le32_to_cpu(lum->lum_magic) != LMV_USER_MAGIC &&
- le32_to_cpu(lum->lum_magic) != LMV_USER_MAGIC_SPECIFIC &&
+ if (!lmv_magic_supported(le32_to_cpu(lum->lum_magic)) &&
le32_to_cpu(lum->lum_magic) != LMV_USER_MAGIC_V0) {
rc = -EINVAL;
CERROR("%s: invalid lmv_user_md: magic = %x, "
if (rc != 0)
RETURN(rc);
- /* sgid check */
+ /* sgid check */
if (pattr->la_mode & S_ISGID) {
+ struct lu_ucred *uc = lu_ucred(env);
+
cattr->la_gid = pattr->la_gid;
+
+ /* Directories are special, and always inherit S_ISGID */
if (S_ISDIR(cattr->la_mode)) {
cattr->la_mode |= S_ISGID;
cattr->la_valid |= LA_MODE;
+ } else if ((cattr->la_mode & (S_ISGID | S_IXGRP))
+ == (S_ISGID | S_IXGRP) &&
+ !lustre_in_group_p(uc,
+ (cattr->la_valid & LA_GID) ?
+ cattr->la_gid : pattr->la_gid) &&
+ !md_capable(uc, CFS_CAP_FSETID)) {
+ cattr->la_mode &= ~S_ISGID;
+ cattr->la_valid |= LA_MODE;
}
}
const struct md_op_spec *spec,
struct lu_buf *def_acl_buf,
struct lu_buf *acl_buf,
+ struct lu_buf *hsm_buf,
struct dt_allocation_hint *hint)
{
const struct lu_buf *buf;
if (rc)
GOTO(out, rc);
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
if (def_acl_buf && def_acl_buf->lb_len > 0 && S_ISDIR(attr->la_mode)) {
/* if dir, then can inherit default ACl */
rc = mdo_declare_xattr_set(env, c, def_acl_buf,
0, handle);
if (rc)
GOTO(out, rc);
+
+ if (spec->sp_cr_flags & MDS_OPEN_PCC) {
+ rc = mdo_declare_xattr_set(env, c, hsm_buf,
+ XATTR_NAME_HSM,
+ 0, handle);
+ if (rc)
+ GOTO(out, rc);
+ }
}
if (S_ISLNK(attr->la_mode)) {
struct linkea_data *ldata,
struct lu_buf *def_acl_buf,
struct lu_buf *acl_buf,
+ struct lu_buf *hsm_buf,
struct dt_allocation_hint *hint)
{
int rc;
rc = mdd_declare_create_object(env, mdd, p, c, attr, handle, spec,
- def_acl_buf, acl_buf, hint);
+ def_acl_buf, acl_buf, hsm_buf, hint);
if (rc)
GOTO(out, rc);
RETURN(0);
}
- mdd_read_lock(env, pobj, MOR_TGT_PARENT);
+ mdd_read_lock(env, pobj, DT_TGT_PARENT);
rc = mdo_xattr_get(env, pobj, def_acl_buf,
XATTR_NAME_ACL_DEFAULT);
mdd_read_unlock(env, pobj);
struct mdd_object *son, struct lu_attr *attr,
struct md_op_spec *spec, struct lu_buf *acl_buf,
struct lu_buf *def_acl_buf,
+ struct lu_buf *hsm_buf,
struct dt_allocation_hint *hint,
struct thandle *handle)
{
const struct lu_buf *buf;
int rc;
- mdd_write_lock(env, son, MOR_TGT_CHILD);
+ mdd_write_lock(env, son, DT_TGT_CHILD);
rc = mdd_create_object_internal(env, NULL, son, attr, handle, spec,
hint);
if (rc)
GOTO(err_destroy, rc);
}
-#ifdef CONFIG_FS_POSIX_ACL
+ if (S_ISREG(attr->la_mode) && spec->sp_cr_flags & MDS_OPEN_PCC) {
+ struct md_hsm mh;
+
+ memset(&mh, 0, sizeof(mh));
+ mh.mh_flags = HS_EXISTS | HS_ARCHIVED | HS_RELEASED;
+ mh.mh_arch_id = spec->sp_archive_id;
+ lustre_hsm2buf(hsm_buf->lb_buf, &mh);
+ rc = mdo_xattr_set(env, son, hsm_buf, XATTR_NAME_HSM,
+ 0, handle);
+ if (rc != 0)
+ GOTO(err_destroy, rc);
+ }
+
+#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
if (def_acl_buf != NULL && def_acl_buf->lb_len > 0 &&
S_ISDIR(attr->la_mode)) {
/* set default acl */
* \retval 0 on success
* \retval negative errno on failure
*/
-static int mdd_create(const struct lu_env *env, struct md_object *pobj,
+int mdd_create(const struct lu_env *env, struct md_object *pobj,
const struct lu_name *lname, struct md_object *child,
struct md_op_spec *spec, struct md_attr *ma)
{
struct lu_attr *pattr = &info->mti_pattr;
struct lu_buf acl_buf;
struct lu_buf def_acl_buf;
+ struct lu_buf hsm_buf;
struct linkea_data *ldata = &info->mti_link_data;
const char *name = lname->ln_name;
struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
GOTO(out_free, rc = PTR_ERR(handle));
lu_buf_check_and_alloc(&info->mti_xattr_buf,
- mdd->mdd_dt_conf.ddp_max_ea_size);
+ MIN(mdd->mdd_dt_conf.ddp_max_ea_size, XATTR_SIZE_MAX));
acl_buf = info->mti_xattr_buf;
def_acl_buf.lb_buf = info->mti_key;
def_acl_buf.lb_len = sizeof(info->mti_key);
lname, 1, 0, ldata);
}
+ if (spec->sp_cr_flags & MDS_OPEN_PCC) {
+ LASSERT(spec->sp_cr_flags & MDS_OPEN_HAS_EA);
+
+ memset(&hsm_buf, 0, sizeof(hsm_buf));
+ lu_buf_alloc(&hsm_buf, sizeof(struct hsm_attrs));
+ if (hsm_buf.lb_buf == NULL)
+ GOTO(out_stop, rc = -ENOMEM);
+ }
+
rc = mdd_declare_create(env, mdd, mdd_pobj, son, lname, attr,
handle, spec, ldata, &def_acl_buf, &acl_buf,
- hint);
+ &hsm_buf, hint);
if (rc)
GOTO(out_stop, rc);
GOTO(out_stop, rc);
rc = mdd_create_object(env, mdd_pobj, son, attr, spec, &acl_buf,
- &def_acl_buf, hint, handle);
+ &def_acl_buf, &hsm_buf, hint, handle);
if (rc != 0)
GOTO(out_stop, rc);
if (unlikely(spec->sp_cr_flags & MDS_OPEN_VOLATILE)) {
- mdd_write_lock(env, son, MOR_TGT_CHILD);
+ mdd_write_lock(env, son, DT_TGT_CHILD);
son->mod_flags |= VOLATILE_OBJ;
rc = mdd_orphan_insert(env, son, handle);
GOTO(out_volatile, rc);
goto out_stop;
err_created:
- mdd_write_lock(env, son, MOR_TGT_CHILD);
+ mdd_write_lock(env, son, DT_TGT_CHILD);
if (S_ISDIR(attr->la_mode)) {
/* Drop the reference, no need to delete "."/"..",
* because the object is to be destroyed directly. */
/* if we vmalloced a large buffer drop it */
lu_buf_free(ldata->ld_buf);
+ if (spec->sp_cr_flags & MDS_OPEN_PCC)
+ lu_buf_free(&hsm_buf);
+
/* The child object shouldn't be cached anymore */
if (rc)
set_bit(LU_OBJECT_HEARD_BANSHEE,
GOTO(fixup_tpobj, rc);
/* Update the linkEA for the source object */
- mdd_write_lock(env, mdd_sobj, MOR_SRC_CHILD);
+ mdd_write_lock(env, mdd_sobj, DT_SRC_CHILD);
rc = mdd_links_rename(env, mdd_sobj, mdo2fid(mdd_spobj), lsname,
mdo2fid(mdd_tpobj), ltname, handle, ldata,
0, 0);
* it must be local one.
*/
if (tobj && mdd_object_exists(mdd_tobj)) {
- mdd_write_lock(env, mdd_tobj, MOR_TGT_CHILD);
+ mdd_write_lock(env, mdd_tobj, DT_TGT_CHILD);
tobj_locked = 1;
if (mdd_is_dead_obj(mdd_tobj)) {
/* shld not be dead, something is wrong */
ENTRY;
if (!mdd_object_remote(sobj)) {
- mdd_read_lock(env, sobj, MOR_SRC_CHILD);
+ mdd_read_lock(env, sobj, DT_SRC_CHILD);
if (sobj->mod_count > 0) {
CDEBUG(D_INFO, "%s: "DFID" is opened, count %d\n",
mdd2obd_dev(mdd)->obd_name, PFID(mdo2fid(sobj)),
if (index < del_offset)
RETURN(0);
- mdd_write_lock(env, stripe, MOR_SRC_CHILD);
+ mdd_write_lock(env, stripe, DT_SRC_CHILD);
rc = __mdd_index_delete_only(env, stripe, dotdot, handle);
if (rc)
GOTO(out, rc);
RETURN(rc);
}
- mdd_write_lock(env, stripe, MOR_SRC_CHILD);
+ mdd_write_lock(env, stripe, DT_SRC_CHILD);
rc = mdo_ref_del(env, stripe, handle);
if (!rc)
rc = mdo_destroy(env, stripe, handle);
for (i = 0; i < le32_to_cpu(lmv->lmv_stripe_count); i++) {
fid_le_to_cpu(fid, &lmv->lmv_stripe_fids[i]);
+ if (!fid_is_sane(fid))
+ continue;
+
stripe = mdd_object_find(env, mdd, fid);
if (IS_ERR(stripe))
RETURN(PTR_ERR(stripe));
struct mdd_thread_info *info = mdd_env_info(env);
char *xname;
struct lu_buf list_xbuf;
+ struct lu_buf cbxbuf;
struct lu_buf xbuf = { NULL };
int list_xsize;
int xlen;
if (rc < 0)
GOTO(out, rc);
+ cbxbuf = xbuf;
repeat:
- rc = cb(env, tobj, &xbuf, xname, 0, handle);
+ rc = cb(env, tobj, &cbxbuf, xname, 0, handle);
if (unlikely(rc == -ENOSPC &&
strcmp(xname, XATTR_NAME_LINK) == 0)) {
rc = linkea_overflow_shrink(
- (struct linkea_data *)(xbuf.lb_buf));
+ (struct linkea_data *)(cbxbuf.lb_buf));
if (likely(rc > 0)) {
- xbuf.lb_len = rc;
+ cbxbuf.lb_len = rc;
goto repeat;
}
}
RETURN(-ENOENT);
}
- mdd_write_lock(env, pobj, MOR_TGT_PARENT);
+ mdd_write_lock(env, pobj, DT_TGT_PARENT);
rc = __mdd_index_delete_only(env, pobj, lname->ln_name, handle);
if (!rc)
rc = __mdd_index_insert_only(env, pobj, mdo2fid(tobj),
if (rc)
RETURN(rc);
- mdd_write_lock(env, tobj, MOR_TGT_CHILD);
+ mdd_write_lock(env, tobj, DT_TGT_CHILD);
rc = mdo_ref_add(env, tobj, handle);
mdd_write_unlock(env, tobj);
if (rc)
RETURN(rc);
- mdd_write_lock(env, sobj, MOR_SRC_CHILD);
+ mdd_write_lock(env, sobj, DT_SRC_CHILD);
rc = mdo_ref_del(env, sobj, handle);
mdd_write_unlock(env, sobj);
ENTRY;
- mdd_write_lock(env, obj, MOR_SRC_PARENT);
+ mdd_write_lock(env, obj, DT_SRC_PARENT);
if (!lmv_buf->lb_buf)
/* normal dir */
rc = __mdd_index_delete_only(env, obj, dotdot, handle);
rc = mdd_declare_create(env, mdo2mdd(&tpobj->mod_obj), tpobj, tobj,
lname, attr, handle, spec, ldata, NULL, NULL,
- hint);
+ NULL, hint);
if (rc)
return rc;
* stripes again.
*/
if (sbuf->lb_buf) {
- mdd_write_lock(env, sobj, MOR_SRC_CHILD);
+ mdd_write_lock(env, sobj, DT_SRC_CHILD);
rc = mdo_xattr_del(env, sobj, XATTR_NAME_LMV, handle);
mdd_write_unlock(env, sobj);
if (rc)
/* don't set nlink from sobj */
attr->la_valid &= ~LA_NLINK;
- rc = mdd_create_object(env, tpobj, tobj, attr, spec, NULL, NULL, hint,
- handle);
+ rc = mdd_create_object(env, tpobj, tobj, attr, spec, NULL, NULL, NULL,
+ hint, handle);
if (rc)
RETURN(rc);
- mdd_write_lock(env, tobj, MOR_TGT_CHILD);
+ mdd_write_lock(env, tobj, DT_TGT_CHILD);
rc = mdd_iterate_xattrs(env, sobj, tobj, true, handle, mdo_xattr_set);
mdd_write_unlock(env, tobj);
if (rc)
RETURN(rc);
/* delete LOV to avoid deleting OST objs when destroying sobj */
- mdd_write_lock(env, sobj, MOR_SRC_CHILD);
+ mdd_write_lock(env, sobj, DT_SRC_CHILD);
rc = mdo_xattr_del(env, sobj, XATTR_NAME_LOV, handle);
mdd_write_unlock(env, sobj);
if (rc)
la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
la->la_valid = LA_CTIME | LA_MTIME;
- mdd_write_lock(env, spobj, MOR_SRC_PARENT);
+ mdd_write_lock(env, spobj, DT_SRC_PARENT);
rc = mdd_update_time(env, spobj, spattr, la, handle);
mdd_write_unlock(env, spobj);
if (rc)
if (tpobj != spobj) {
la->la_valid = LA_CTIME | LA_MTIME;
- mdd_write_lock(env, tpobj, MOR_TGT_PARENT);
+ mdd_write_lock(env, tpobj, DT_TGT_PARENT);
rc = mdd_update_time(env, tpobj, tpattr, la, handle);
mdd_write_unlock(env, tpobj);
if (rc)
* message, this won't cause any inconsistency or trouble.
*/
if (do_create && do_destroy) {
- mdd_write_lock(env, sobj, MOR_SRC_CHILD);
+ mdd_write_lock(env, sobj, DT_SRC_CHILD);
mdo_ref_del(env, sobj, handle);
rc = mdo_destroy(env, sobj, handle);
mdd_write_unlock(env, sobj);
if (rc)
GOTO(out, rc);
- mdd_object_make_hint(env, NULL, tobj, attr, spec, hint);
+ mdd_object_make_hint(env, tpobj, tobj, attr, spec, hint);
handle = mdd_trans_create(env, mdd);
if (IS_ERR(handle))
lmu->lum_stripe_count = cpu_to_le32(1);
/* delete LMV to avoid deleting stripes again upon destroy */
- mdd_write_lock(env, obj, MOR_SRC_CHILD);
+ mdd_write_lock(env, obj, DT_SRC_CHILD);
rc = mdo_xattr_del(env, obj, XATTR_NAME_LMV, handle);
mdd_write_unlock(env, obj);
if (rc)
}
/* destroy stripes after lmu_stripe_count */
- mdd_write_lock(env, obj, MOR_SRC_PARENT);
+ mdd_write_lock(env, obj, DT_SRC_PARENT);
rc = mdd_dir_iterate_stripes(env, obj, lmv_buf, &shrink_buf, handle,
mdd_dir_destroy_stripe);
mdd_write_unlock(env, obj);
LASSERT(pobj);
LASSERT(stripe);
- mdd_write_lock(env, pobj, MOR_SRC_PARENT);
- mdd_write_lock(env, obj, MOR_SRC_CHILD);
+ mdd_write_lock(env, pobj, DT_SRC_PARENT);
+ mdd_write_lock(env, obj, DT_SRC_CHILD);
/* insert dotdot to stripe which points to parent */
rc = __mdd_index_insert_only(env, stripe, mdo2fid(pobj), S_IFDIR,