#include <lprocfs_status.h>
/* fid_be_cpu(), fid_cpu_to_be(). */
#include <lustre_fid.h>
-#include <obd_lov.h>
#include <lustre_idmap.h>
#include <lustre_param.h>
#include <lustre_mds.h>
return mdo_attr_get(env, obj, la, capa);
}
-static void mdd_flags_xlate(struct mdd_object *obj, __u32 flags)
+void mdd_flags_xlate(struct mdd_object *obj, __u32 flags)
{
obj->mod_flags &= ~(APPEND_OBJ|IMMUTE_OBJ);
}
struct lu_object *mdd_object_alloc(const struct lu_env *env,
- const struct lu_object_header *hdr,
- struct lu_device *d)
+ const struct lu_object_header *hdr,
+ struct lu_device *d)
{
- struct mdd_object *mdd_obj;
-
- OBD_SLAB_ALLOC_PTR_GFP(mdd_obj, mdd_object_kmem, __GFP_IO);
- if (mdd_obj != NULL) {
- struct lu_object *o;
-
- o = mdd2lu_obj(mdd_obj);
- lu_object_init(o, NULL, d);
- mdd_obj->mod_obj.mo_ops = &mdd_obj_ops;
- mdd_obj->mod_obj.mo_dir_ops = &mdd_dir_ops;
- mdd_obj->mod_count = 0;
- o->lo_ops = &mdd_lu_obj_ops;
- return o;
- } else {
- return NULL;
- }
+ struct mdd_object *mdd_obj;
+
+ OBD_SLAB_ALLOC_PTR_GFP(mdd_obj, mdd_object_kmem, GFP_NOFS);
+ if (mdd_obj != NULL) {
+ struct lu_object *o;
+
+ o = mdd2lu_obj(mdd_obj);
+ lu_object_init(o, NULL, d);
+ mdd_obj->mod_obj.mo_ops = &mdd_obj_ops;
+ mdd_obj->mod_obj.mo_dir_ops = &mdd_dir_ops;
+ mdd_obj->mod_count = 0;
+ o->lo_ops = &mdd_lu_obj_ops;
+ return o;
+ } else {
+ return NULL;
+ }
}
static int mdd_object_init(const struct lu_env *env, struct lu_object *o,
if (lu_object_exists(o)) {
struct mdd_object *mdd_obj = lu2mdd_obj(o);
- struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
+ struct lu_attr *attr = MDD_ENV_VAR(env, la_for_start);
rc = mdd_la_get(env, mdd_obj, attr, BYPASS_CAPA);
if (rc == 0)
* Permission check is done when open,
* no need check again.
*/
-static int mdd_readlink(const struct lu_env *env, struct md_object *obj,
- struct lu_buf *buf)
+int mdd_readlink(const struct lu_env *env, struct md_object *obj,
+ struct lu_buf *buf)
{
struct mdd_object *mdd_obj = md2mdd_obj(obj);
struct dt_object *next;
}
next = mdd_object_child(mdd_obj);
- mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
+ LASSERT(next != NULL);
+ LASSERT(next->do_body_ops != NULL);
+ LASSERT(next->do_body_ops->dbo_read != NULL);
+ mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
rc = next->do_body_ops->dbo_read(env, next, buf, &pos,
mdd_object_capa(env, mdd_obj));
mdd_read_unlock(env, mdd_obj);
struct mdd_object *c,
struct lu_attr *attr,
struct thandle *handle,
- const struct md_op_spec *spec)
+ const struct md_op_spec *spec,
+ struct dt_allocation_hint *hint)
{
struct dt_object_format *dof = &mdd_env_info(env)->mti_dof;
- struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
const struct dt_index_features *feat = spec->sp_feat;
int rc;
ENTRY;
int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p,
struct mdd_object *c, struct lu_attr *attr,
- struct thandle *handle,
- const struct md_op_spec *spec)
+ struct thandle *handle,
+ const struct md_op_spec *spec,
+ struct dt_allocation_hint *hint)
{
- struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
struct dt_object_format *dof = &mdd_env_info(env)->mti_dof;
int rc;
ENTRY;
CDEBUG(D_INODE, "setting mtime "LPU64", ctime "LPU64"\n",
la->la_mtime, la->la_ctime);
- if (la_copy->la_valid & LA_FLAGS) {
+ mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
+ if (la_copy->la_valid & LA_FLAGS) {
rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 1);
- if (rc == 0)
- mdd_flags_xlate(mdd_obj, la_copy->la_flags);
- } else if (la_copy->la_valid) { /* setattr */
+ if (rc == 0)
+ mdd_flags_xlate(mdd_obj, la_copy->la_flags);
+ } else if (la_copy->la_valid) { /* setattr */
rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 1);
- }
+ }
+ mdd_write_unlock(env, mdd_obj);
+
+ if (rc == 0)
+ rc = mdd_attr_set_changelog(env, obj, handle, la->la_valid);
+
+ GOTO(stop, rc);
- if (rc == 0)
- rc = mdd_attr_set_changelog(env, obj, handle,
- la->la_valid);
stop:
- mdd_trans_stop(env, mdd, rc, handle);
- RETURN(rc);
+ mdd_trans_stop(env, mdd, rc, handle);
+ return rc;
}
static int mdd_xattr_sanity_check(const struct lu_env *env,
/* Only record user and layout xattr changes */
if (strncmp(XATTR_USER_PREFIX, name,
sizeof(XATTR_USER_PREFIX) - 1) == 0 ||
- strncmp(XATTR_NAME_LOV, name,
- sizeof(XATTR_NAME_LOV) - 1) == 0) {
+ strcmp(XATTR_NAME_LOV, name) == 0) {
rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
if (rc)
return rc;
}
/* If HSM data is modified, this could add a changelog */
- if (strncmp(XATTR_NAME_HSM, name, sizeof(XATTR_NAME_HSM) - 1) == 0) {
+ if (strcmp(XATTR_NAME_HSM, name) == 0) {
rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
if (rc)
return rc;
if (rc)
RETURN(rc);
+ rc = mdd_xattr_sanity_check(env, mdd_obj, attr);
+ if (rc)
+ RETURN(rc);
+
if (!strcmp(name, XATTR_NAME_ACL_ACCESS)) {
rc = mdd_acl_set(env, mdd_obj, attr, buf, fl);
RETURN(rc);
}
- rc = mdd_xattr_sanity_check(env, mdd_obj, attr);
- if (rc)
- RETURN(rc);
-
handle = mdd_trans_create(env, mdd);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
- if (strncmp(XATTR_NAME_HSM, name, sizeof(XATTR_NAME_HSM) - 1) == 0) {
+ if (strcmp(XATTR_NAME_HSM, name) == 0) {
rc = mdd_hsm_update_locked(env, obj, buf, handle);
if (rc) {
mdd_write_unlock(env, mdd_obj);
if (rc)
GOTO(stop, rc);
- if (strncmp(XATTR_NAME_LOV, name, sizeof(XATTR_NAME_LOV) - 1) == 0)
+ if (strcmp(XATTR_NAME_LOV, name) == 0)
rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, mdd_obj,
handle);
else if (strncmp(XATTR_USER_PREFIX, name,
const char *name,
struct thandle *handle)
{
- int rc;
+ int rc;
- rc = mdo_declare_xattr_del(env, obj, name, handle);
- if (rc)
- return rc;
+ rc = mdo_declare_xattr_del(env, obj, name, handle);
+ if (rc)
+ return rc;
- /* Only record user xattr changes */
- if ((strncmp("user.", name, 5) == 0))
- rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
+ /* Only record user xattr changes */
+ if ((strncmp(XATTR_USER_PREFIX, name,
+ sizeof(XATTR_USER_PREFIX) - 1) == 0))
+ rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
- return rc;
+ return rc;
}
/**
* read lov EA of an object
* return the lov EA in an allocated lu_buf
*/
-static int mdd_get_lov_ea(const struct lu_env *env,
- struct mdd_object *obj,
- struct lu_buf *lmm_buf)
+int mdd_get_lov_ea(const struct lu_env *env, struct mdd_object *obj,
+ struct lu_buf *lmm_buf)
{
struct lu_buf *buf = &mdd_env_info(env)->mti_big_buf;
- int rc, sz;
+ int rc, bufsize;
ENTRY;
repeat:
}
if (rc < 0)
- GOTO(out, rc);
+ RETURN(rc);
if (rc == 0)
- GOTO(out, rc = -ENODATA);
+ RETURN(-ENODATA);
- sz = rc;
+ bufsize = rc;
if (memcmp(buf, &LU_BUF_NULL, sizeof(*buf)) == 0) {
/* mti_big_buf was not allocated, so we have to
* allocate it based on the ea size */
buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf,
- sz);
+ bufsize);
if (buf->lb_buf == NULL)
GOTO(out, rc = -ENOMEM);
goto repeat;
}
- lu_buf_alloc(lmm_buf, sz);
+ lu_buf_alloc(lmm_buf, bufsize);
if (lmm_buf->lb_buf == NULL)
GOTO(out, rc = -ENOMEM);
- memcpy(lmm_buf->lb_buf, buf->lb_buf, sz);
+ memcpy(lmm_buf->lb_buf, buf->lb_buf, bufsize);
rc = 0;
EXIT;
/*
* check if layout swapping between 2 objects is allowed
* the rules are:
+ * - only normal FIDs or non-system IGIFs
* - same type of objects
* - same owner/group (so quotas are still valid)
*/
fid1 = mdo2fid(o1);
fid2 = mdo2fid(o2);
- if (!fid_is_norm(fid1) || !fid_is_norm(fid2) ||
- (mdd_object_type(o1) != mdd_object_type(o2)))
- RETURN(-EPERM);
+ if (!fid_is_norm(fid1) &&
+ (!fid_is_igif(fid1) || IS_ERR(mdd_links_get(env, o1))))
+ RETURN(-EBADF);
+
+ if (!fid_is_norm(fid2) &&
+ (!fid_is_igif(fid2) || IS_ERR(mdd_links_get(env, o2))))
+ RETURN(-EBADF);
+
+ if (mdd_object_type(o1) != mdd_object_type(o2)) {
+ if (S_ISDIR(mdd_object_type(o1)))
+ RETURN(-ENOTDIR);
+ if (S_ISREG(mdd_object_type(o1)))
+ RETURN(-EISDIR);
+ RETURN(-EBADF);
+ }
if ((attr1->la_uid != attr2->la_uid) ||
(attr1->la_gid != attr2->la_gid))
}
void mdd_object_make_hint(const struct lu_env *env, struct mdd_object *parent,
- struct mdd_object *child, struct lu_attr *attr)
+ struct mdd_object *child, const struct lu_attr *attr,
+ const struct md_op_spec *spec,
+ struct dt_allocation_hint *hint)
{
- struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint;
- struct dt_object *np = parent ? mdd_object_child(parent) : NULL;
+ struct dt_object *np = parent ? mdd_object_child(parent) : NULL;
struct dt_object *nc = mdd_object_child(child);
+ memset(hint, 0, sizeof(*hint));
+
+ /* For striped directory, give striping EA to lod_ah_init, which will
+ * decide the stripe_offset and stripe count by it. */
+ if (S_ISDIR(attr->la_mode) &&
+ unlikely(spec != NULL && spec->sp_cr_flags & MDS_OPEN_HAS_EA)) {
+ hint->dah_eadata = spec->u.sp_ea.eadata;
+ hint->dah_eadata_len = spec->u.sp_ea.eadatalen;
+ } else {
+ hint->dah_eadata = NULL;
+ hint->dah_eadata_len = 0;
+ }
+
+ CDEBUG(D_INFO, DFID" eadata %p len %d\n", PFID(mdd_object_fid(child)),
+ hint->dah_eadata, hint->dah_eadata_len);
/* @hint will be initialized by underlying device. */
nc->do_ops->do_ah_init(env, hint, np, nc, attr->la_mode & S_IFMT);
}
struct md_object *obj,
struct lustre_handle *lh,
struct ldlm_enqueue_info *einfo,
- void *policy)
+ ldlm_policy_data_t *policy)
{
struct mdd_object *mdd_obj = md2mdd_obj(obj);
return dt_object_lock(env, mdd_object_child(mdd_obj), lh,
einfo, policy);
}
+static int mdd_object_unlock(const struct lu_env *env,
+ struct md_object *obj,
+ struct ldlm_enqueue_info *einfo,
+ ldlm_policy_data_t *policy)
+{
+ struct mdd_object *mdd_obj = md2mdd_obj(obj);
+ return dt_object_unlock(env, mdd_object_child(mdd_obj), einfo, policy);
+}
+
const struct md_object_operations mdd_obj_ops = {
.moo_permission = mdd_permission,
.moo_attr_get = mdd_attr_get,
.moo_capa_get = mdd_capa_get,
.moo_object_sync = mdd_object_sync,
.moo_object_lock = mdd_object_lock,
+ .moo_object_unlock = mdd_object_unlock,
};