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);
{
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;
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;
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;
* 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)));