X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_dir.c;h=7e71f4cbb952403d93ad3cc9d4887b17d1055e96;hp=14d0264e88d359a352dc98c6eae4476e02abb2a2;hb=8d27c92a66d63aaf8b8fbe1fc73e49263b5bed1e;hpb=9a4a99b81a267a098b92ec10991af27b7f3cae7e diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 14d0264..7e71f4c 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mdd_internal.h" @@ -91,7 +92,7 @@ __mdd_lookup(const struct lu_env *env, struct md_object *pobj, } rc = mdd_permission_internal_locked(env, mdd_obj, pattr, mask, - MOR_TGT_PARENT); + DT_TGT_PARENT); if (rc) RETURN(rc); @@ -384,8 +385,12 @@ static int mdd_dir_is_empty(const struct lu_env *env, 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); } @@ -449,7 +454,7 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, if (check_perm) rc = mdd_permission_internal_locked(env, pobj, pattr, MAY_WRITE | MAY_EXEC, - MOR_TGT_PARENT); + DT_TGT_PARENT); RETURN(rc); } @@ -470,7 +475,7 @@ int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj, rc = mdd_permission_internal_locked(env, pobj, pattr, MAY_WRITE | MAY_EXEC, - MOR_TGT_PARENT); + DT_TGT_PARENT); if (rc != 0) RETURN(rc); @@ -524,7 +529,7 @@ static int mdd_may_delete_entry(const struct lu_env *env, int rc; rc = mdd_permission_internal_locked(env, pobj, pattr, MAY_WRITE | MAY_EXEC, - MOR_TGT_PARENT); + DT_TGT_PARENT); if (rc) RETURN(rc); } @@ -690,7 +695,7 @@ static int __mdd_index_insert(const struct lu_env *env, struct mdd_object *pobj, 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); } @@ -703,17 +708,17 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *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, @@ -1392,7 +1397,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, 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) @@ -1451,9 +1456,6 @@ static int mdd_mark_orphan_object(const struct lu_env *env, 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; @@ -1711,7 +1713,7 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, 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); @@ -2020,8 +2022,7 @@ static int mdd_create_sanity_check(const struct lu_env *env, 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, " @@ -2038,12 +2039,24 @@ static int mdd_create_sanity_check(const struct lu_env *env, 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; } } @@ -2093,6 +2106,7 @@ static int mdd_declare_create_object(const struct lu_env *env, 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; @@ -2139,6 +2153,14 @@ static int mdd_declare_create_object(const struct lu_env *env, 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)) { @@ -2175,12 +2197,13 @@ static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd, 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); @@ -2239,7 +2262,7 @@ static int mdd_acl_init(const struct lu_env *env, struct mdd_object *pobj, 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); @@ -2275,13 +2298,14 @@ static int mdd_create_object(const struct lu_env *env, struct mdd_object *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) @@ -2323,6 +2347,19 @@ static int mdd_create_object(const struct lu_env *env, struct mdd_object *pobj, GOTO(err_destroy, rc); } + 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_FS_POSIX_ACL if (def_acl_buf != NULL && def_acl_buf->lb_len > 0 && S_ISDIR(attr->la_mode)) { @@ -2471,7 +2508,7 @@ stop: * \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) { @@ -2485,6 +2522,7 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, 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; @@ -2509,7 +2547,7 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, 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); @@ -2546,9 +2584,18 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, 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); @@ -2557,12 +2604,12 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, 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); @@ -2596,7 +2643,7 @@ err_insert: 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. */ @@ -2648,6 +2695,9 @@ out_free: /* 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, @@ -3010,7 +3060,7 @@ static int mdd_rename(const struct lu_env *env, 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); @@ -3029,7 +3079,7 @@ static int mdd_rename(const struct lu_env *env, * 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 */ @@ -3200,7 +3250,7 @@ static int mdd_migrate_sanity_check(const struct lu_env *env, 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)), @@ -3284,7 +3334,7 @@ static int mdd_dir_delete_stripe(const struct lu_env *env, 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); @@ -3375,7 +3425,7 @@ static int mdd_dir_destroy_stripe(const struct lu_env *env, 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); @@ -3429,6 +3479,9 @@ static int mdd_dir_iterate_stripes(const struct lu_env *env, 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)); @@ -3629,7 +3682,7 @@ static int mdd_update_link(const struct lu_env *env, 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), @@ -3640,13 +3693,13 @@ static int mdd_update_link(const struct lu_env *env, 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); @@ -3828,7 +3881,7 @@ static int mdd_dir_layout_delete(const struct lu_env *env, 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); @@ -3886,7 +3939,7 @@ static int mdd_declare_migrate_create(const struct lu_env *env, 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; @@ -4034,7 +4087,7 @@ static int mdd_migrate_create(const struct lu_env *env, * 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) @@ -4045,12 +4098,12 @@ static int mdd_migrate_create(const struct lu_env *env, /* 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) @@ -4069,7 +4122,7 @@ static int mdd_migrate_create(const struct lu_env *env, 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) @@ -4198,7 +4251,7 @@ static int mdd_migrate_update(const struct lu_env *env, 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) @@ -4206,7 +4259,7 @@ static int mdd_migrate_update(const struct lu_env *env, 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) @@ -4231,7 +4284,7 @@ static int mdd_migrate_update(const struct lu_env *env, * 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); @@ -4482,7 +4535,7 @@ static int mdd_migrate(const struct lu_env *env, struct md_object *md_pobj, 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)) @@ -4676,7 +4729,7 @@ static int __mdd_dir_layout_shrink(const struct lu_env *env, 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) @@ -4684,7 +4737,7 @@ static int __mdd_dir_layout_shrink(const struct lu_env *env, } /* 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); @@ -4708,8 +4761,8 @@ static int __mdd_dir_layout_shrink(const struct lu_env *env, 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,