* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
if (rc != 0)
RETURN(rc);
- rc = __mdd_lookup(env, pobj, pattr, lname, fid, MAY_EXEC);
+ rc = __mdd_lookup(env, pobj, pattr, lname, fid,
+ (spec != NULL && spec->sp_permitted) ? 0 : MAY_EXEC);
RETURN(rc);
}
if (mdd_is_dead_obj(pobj))
RETURN(-ENOENT);
- if ((attr->la_valid & LA_FLAGS) &&
- (attr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL)))
+ if (attr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))
RETURN(-EPERM);
rc = mdd_permission_internal_locked(env, pobj, pattr,
MAY_WRITE | MAY_EXEC,
MOR_TGT_PARENT);
- if (rc)
+ if (rc != 0)
RETURN(rc);
- if (mdd_is_append(pobj))
+ if (pattr->la_flags & LUSTRE_APPEND_FL)
RETURN(-EPERM);
RETURN(rc);
RETURN(rc);
}
- if (mdd_is_append(pobj))
+ if (pattr->la_flags & LUSTRE_APPEND_FL)
RETURN(-EPERM);
RETURN(0);
if (mdd_is_sticky(env, tpobj, tpattr, tobj, tattr))
RETURN(-EPERM);
- if (mdd_is_immutable(tobj) || mdd_is_append(tobj))
- RETURN(-EPERM);
-
- if ((tattr->la_valid & LA_FLAGS) &&
- (tattr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL)))
+ if (tattr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))
RETURN(-EPERM);
/* additional check the rename case */
if (rc < 0)
RETURN(rc);
- if (mdd_is_immutable(src_obj) || mdd_is_append(src_obj))
- RETURN(-EPERM);
+ if (cattr->la_flags & (LUSTRE_IMMUTABLE_FL | LUSTRE_APPEND_FL))
+ RETURN(-EPERM);
- if (S_ISDIR(mdd_object_type(src_obj)))
- RETURN(-EPERM);
+ if (S_ISDIR(mdd_object_type(src_obj)))
+ RETURN(-EPERM);
LASSERT(src_obj != tgt_obj);
rc = mdd_may_create(env, tgt_obj, tattr, NULL, true);
struct lu_buf *mdd_links_get(const struct lu_env *env,
struct mdd_object *mdd_obj)
{
- struct linkea_data ldata = { 0 };
+ struct linkea_data ldata = { NULL };
int rc;
rc = mdd_links_read(env, mdd_obj, &ldata);
{
const struct lu_buf *buf = mdd_buf_get_const(env, ldata->ld_buf->lb_buf,
ldata->ld_leh->leh_len);
+ int rc;
if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_NO_LINKEA))
return 0;
- return mdo_xattr_set(env, mdd_obj, buf, XATTR_NAME_LINK, 0, handle,
- mdd_object_capa(env, mdd_obj));
+ rc = mdo_xattr_set(env, mdd_obj, buf, XATTR_NAME_LINK, 0, handle,
+ mdd_object_capa(env, mdd_obj));
+ if (unlikely(rc == -ENOSPC) && S_ISREG(mdd_object_type(mdd_obj)) &&
+ mdd_object_remote(mdd_obj) == 0) {
+ struct lfsck_request *lr = &mdd_env_info(env)->mti_lr;
+
+ /* XXX: If the linkEA is overflow, then we need to notify the
+ * namespace LFSCK to skip "nlink" attribute verification
+ * on this object to avoid the "nlink" to be shrinked by
+ * wrong. It may be not good an interaction with LFSCK
+ * like this. We will consider to replace it with other
+ * mechanism in future. LU-5802. */
+ lfsck_pack_rfa(lr, mdo2fid(mdd_obj), LE_SKIP_NLINK,
+ LFSCK_TYPE_NAMESPACE);
+ lfsck_in_notify(env, mdo2mdd(&mdd_obj->mod_obj)->mdd_bottom,
+ lr, handle);
+ }
+
+ return rc;
}
int mdd_declare_links_add(const struct lu_env *env, struct mdd_object *mdd_obj,
- struct thandle *handle, struct linkea_data *ldata)
+ struct thandle *handle, struct linkea_data *ldata,
+ enum mdd_links_add_overflow overflow)
{
int rc;
int ea_len;
rc = mdo_declare_xattr_set(env, mdd_obj,
mdd_buf_get_const(env, linkea, ea_len),
XATTR_NAME_LINK, 0, handle);
+ if (rc != 0)
+ return rc;
+
+ if (mdd_object_remote(mdd_obj) == 0 && overflow == MLAO_CHECK) {
+ struct lfsck_request *lr = &mdd_env_info(env)->mti_lr;
+
+ /* XXX: If the linkEA is overflow, then we need to notify the
+ * namespace LFSCK to skip "nlink" attribute verification
+ * on this object to avoid the "nlink" to be shrinked by
+ * wrong. It may be not good an interaction with LFSCK
+ * like this. We will consider to replace it with other
+ * mechanism in future. LU-5802. */
+ lfsck_pack_rfa(lr, mdo2fid(mdd_obj), LE_SKIP_NLINK_DECLARE,
+ LFSCK_TYPE_NAMESPACE);
+ rc = lfsck_in_notify(env,
+ mdo2mdd(&mdd_obj->mod_obj)->mdd_bottom,
+ lr, handle);
+ }
+
return rc;
}
/* For directory, the linkEA will be removed together
* with the object. */
if (!S_ISDIR(mdd_object_type(c)))
- rc = mdd_declare_links_add(env, c, handle, NULL);
+ rc = mdd_declare_links_add(env, c, handle, NULL, MLAO_IGNORE);
return rc;
}
return rc;
rc = mdo_declare_ref_add(env, c, handle);
- if (rc)
+ if (rc != 0)
return rc;
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_MORE_NLINK)) {
+ rc = mdo_declare_ref_add(env, c, handle);
+ if (rc != 0)
+ return rc;
+ }
+
la->la_valid = LA_CTIME | LA_MTIME;
rc = mdo_declare_attr_set(env, p, la, handle);
if (rc != 0)
la->la_valid = LA_CTIME;
rc = mdo_declare_attr_set(env, c, la, handle);
- if (rc)
+ if (rc != 0)
return rc;
- rc = mdd_declare_links_add(env, c, handle, data);
- if (rc)
+ rc = mdd_declare_links_add(env, c, handle, data,
+ S_ISREG(mdd_object_type(c)) ? MLAO_CHECK : MLAO_IGNORE);
+ if (rc != 0)
return rc;
rc = mdd_declare_changelog_store(env, mdd, name, NULL, handle);
if (rc)
GOTO(out_unlock, rc);
- rc = mdo_ref_add(env, mdd_sobj, handle);
- if (rc)
- GOTO(out_unlock, rc);
+ if (!OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LESS_NLINK)) {
+ rc = mdo_ref_add(env, mdd_sobj, handle);
+ if (rc != 0)
+ GOTO(out_unlock, rc);
+ }
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_MORE_NLINK)) {
+ rc = mdo_ref_add(env, mdd_sobj, handle);
+ if (rc != 0)
+ GOTO(out_unlock, rc);
+ }
if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DANGLING3)) {
struct lu_fid tfid = *mdo2fid(mdd_sobj);
struct lu_attr *attr, struct thandle *handle,
const struct md_op_spec *spec)
{
- int rc;
- ENTRY;
-
- /*
- * Update attributes for child.
- *
- * FIXME:
- * (1) the valid bits should be converted between Lustre and Linux;
- * (2) maybe, the child attributes should be set in OSD when creation.
- */
+ int rc = 0;
+ ENTRY;
- rc = mdd_attr_set_internal(env, child, attr, handle, 0);
- /* arguments are supposed to stay the same */
if (S_ISDIR(attr->la_mode)) {
/* Add "." and ".." for newly created dir */
mdo_ref_add(env, child, handle);
if (rc != 0)
return rc;
- rc = mdd_declare_links_add(env, c, handle, ldata);
+ rc = mdd_declare_links_add(env, c, handle, ldata, MLAO_IGNORE);
if (rc)
return rc;
/* During creation, there are only a few cases we need do xattr_set to
* create stripes.
* 1. regular file: see comments above.
- * 2. create striped directory with provided stripeEA.
- * 3. create striped directory because inherit default layout from the
- * parent. */
+ * 2. dir: inherit default striping or pool settings from parent.
+ * 3. create striped directory with provided stripeEA.
+ * 4. create striped directory because inherit default layout from the
+ * parent.
+ */
if (spec->no_create ||
(S_ISREG(attr->la_mode) && spec->sp_cr_flags & MDS_OPEN_HAS_EA) ||
S_ISDIR(attr->la_mode)) {
mdd_object_make_hint(env, mdd_pobj, son, attr, spec, hint);
memset(ldata, 0, sizeof(*ldata));
- if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT2)) {
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_PARENT)) {
struct lu_fid tfid = *mdd_object_fid(mdd_pobj);
tfid.f_oid--;
if (rc)
return rc;
- rc = mdd_declare_links_add(env, mdd_sobj, handle, ldata);
+ rc = mdd_declare_links_add(env, mdd_sobj, handle, ldata,
+ S_ISREG(mdd_object_type(mdd_sobj)) ? MLAO_CHECK : MLAO_IGNORE);
if (rc)
return rc;
bool declare)
{
struct mdd_thread_info *info = mdd_env_info(env);
- struct linkea_data ldata = {0};
+ struct linkea_data ldata = { NULL };
struct lu_buf *buf = &info->mti_link_buf;
int count;
int rc = 0;
linkea_entry_pack(ldata.ld_lee, &lname,
mdd_object_fid(parent));
if (declare)
- rc = mdd_declare_links_add(env, child, handle, &ldata);
+ rc = mdd_declare_links_add(env, child, handle, &ldata,
+ MLAO_IGNORE);
else
rc = mdd_links_write(env, child, &ldata, handle);
break;
}
if (declare)
- rc = mdd_declare_links_add(env, mdd_tobj, handle, ldata);
+ rc = mdd_declare_links_add(env, mdd_tobj, handle, ldata,
+ MLAO_IGNORE);
else
rc = mdd_links_write(env, mdd_tobj, ldata, handle);
la_flag->la_valid = LA_FLAGS;
la_flag->la_flags = la->la_flags | LUSTRE_IMMUTABLE_FL;
- mdd_flags_xlate(mdd_sobj, la_flag->la_flags);
rc = mdo_declare_attr_set(env, mdd_sobj, la_flag, handle);
return rc;
struct mdd_thread_info *info = mdd_env_info(env);
struct mdd_device *mdd = mdo2mdd(&mdd_sobj->mod_obj);
struct md_op_spec *spec = &info->mti_spec;
- struct lu_buf lmm_buf = { 0 };
- struct lu_buf link_buf = { 0 };
+ struct lu_buf lmm_buf = { NULL };
+ struct lu_buf link_buf = { NULL };
const struct lu_buf *buf;
struct thandle *handle;
struct lmv_mds_md_v1 *mgr_ea;
* flag and approve the migration */
la_flag->la_valid = LA_FLAGS;
la_flag->la_flags = la->la_flags | LUSTRE_IMMUTABLE_FL;
- mdd_flags_xlate(mdd_sobj, la_flag->la_flags);
rc = mdo_attr_set(env, mdd_sobj, la_flag, handle,
mdd_object_capa(env, mdd_sobj));
stop_trans:
/* Revert IMMUTABLE flag */
la_flag->la_valid = LA_FLAGS;
la_flag->la_flags = la->la_flags & ~LUSTRE_IMMUTABLE_FL;
- mdd_flags_xlate(mdd_sobj, la_flag->la_flags);
rc = mdo_declare_attr_set(env, mdd_sobj, la_flag, handle);
if (rc != 0)
return rc;
/* Revert IMMUTABLE flag */
la_flag->la_valid = LA_FLAGS;
la_flag->la_flags = so_attr->la_flags & ~LUSTRE_IMMUTABLE_FL;
- mdd_flags_xlate(mdd_sobj, la_flag->la_flags);
rc = mdo_attr_set(env, mdd_sobj, la_flag, handle,
mdd_object_capa(env, mdd_pobj));
if (rc != 0)
struct mdd_device *mdd = mdo2mdd(&sobj->mod_obj);
sattr->la_flags &= ~LUSTRE_IMMUTABLE_FL;
- sobj->mod_flags &= ~IMMUTE_OBJ;
CDEBUG(D_HA, "%s: "DFID" override IMMUTE FLAG\n",
mdd2obd_dev(mdd)->obd_name,
PFID(mdd_object_fid(sobj)));
if (unlikely(OBD_FAIL_CHECK_RESET(OBD_FAIL_MIGRATE_NET_REP,
OBD_FAIL_MDS_REINT_NET_REP)))
GOTO(put, rc = 0);
+ } else {
+ OBD_FAIL_TIMEOUT(OBD_FAIL_MIGRATE_DELAY, cfs_fail_val);
}
/* step 4: update name entry to the new object */