* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
RETURN(rc);
}
-int mdd_declare_llog_record(const struct lu_env *env, struct mdd_device *mdd,
- int reclen, struct thandle *handle)
-{
- int rc;
-
- /* XXX: this is a temporary solution to declare llog changes
- * will be fixed in 2.3 with new llog implementation */
-
- LASSERT(mdd->mdd_capa);
-
- /* XXX: Since we use the 'mdd_capa' as fake llog object here, we
- * have to set the parameter 'size' as INT_MAX or 0 to inform
- * OSD that this record write is for a llog write or catalog
- * header update, and osd declare function will reserve less
- * credits for optimization purpose.
- *
- * Reserve 6 blocks for a llog write, since the llog file is
- * usually small, reserve 2 blocks for catalog header update,
- * because we know for sure that catalog header is already
- * allocated.
- *
- * This hack should be removed in 2.3.
- */
-
- /* record itself */
- rc = dt_declare_record_write(env, mdd->mdd_capa,
- DECLARE_LLOG_WRITE, 0, handle);
- if (rc)
- return rc;
-
- /* header will be updated as well */
- rc = dt_declare_record_write(env, mdd->mdd_capa,
- DECLARE_LLOG_WRITE, 0, handle);
- if (rc)
- return rc;
-
- /* also we should be able to create new plain log */
- rc = dt_declare_create(env, mdd->mdd_capa, NULL, NULL, NULL, handle);
- if (rc)
- return rc;
-
- /* new record referencing new plain llog */
- rc = dt_declare_record_write(env, mdd->mdd_capa,
- DECLARE_LLOG_WRITE, 0, handle);
- if (rc)
- return rc;
-
- /* catalog's header will be updated as well */
- rc = dt_declare_record_write(env, mdd->mdd_capa,
- DECLARE_LLOG_REWRITE, 0, handle);
-
- return rc;
-}
-
int mdd_declare_changelog_store(const struct lu_env *env,
struct mdd_device *mdd,
const struct lu_name *fname,
linkea_add_buf(ldata, lname, tfid);
}
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LINKEA_MORE2))
+ linkea_add_buf(ldata, lname, pfid);
+
return linkea_add_buf(ldata, lname, pfid);
}
LASSERT(oldpfid != NULL || newpfid != NULL);
- if (mdd_obj->mod_flags & DEAD_OBJ)
+ if (mdd_obj->mod_flags & DEAD_OBJ) {
+ /* Prevent linkea to be updated which is NOT necessary. */
+ ldata->ld_reclen = 0;
/* No more links, don't bother */
RETURN(0);
+ }
if (oldpfid != NULL) {
rc = __mdd_links_del(env, mdd_obj, ldata, oldlname, oldpfid);
GOTO(out, rc);
}
- if (ldata->ld_lee != NULL)
+ if (ldata->ld_reclen != 0)
rc = mdd_links_write(env, mdd_obj, ldata, handle);
EXIT;
out:
rc = rc2;
if (rc) {
int error = 1;
- if (rc == -EOVERFLOW || rc == -ENOENT)
+ if (rc == -EOVERFLOW || rc == -ENOENT || rc == -ENOSPC)
error = 0;
if (oldpfid == NULL)
CDEBUG(error ? D_ERROR : D_OTHER,
ea_len = ldata->ld_leh->leh_len;
linkea = ldata->ld_buf->lb_buf;
} else {
- ea_len = 4096;
+ ea_len = DEFAULT_LINKEA_SIZE;
linkea = NULL;
}
struct mdd_object *c,
const struct lu_name *name,
struct thandle *handle,
+ struct lu_attr *la,
struct linkea_data *data)
{
int rc;
if (rc)
return rc;
- rc = mdo_declare_attr_set(env, p, NULL, handle);
- if (rc)
- return rc;
+ la->la_valid = LA_CTIME | LA_MTIME;
+ rc = mdo_declare_attr_set(env, p, la, handle);
+ if (rc != 0)
+ return rc;
- rc = mdo_declare_attr_set(env, c, NULL, handle);
+ la->la_valid = LA_CTIME;
+ rc = mdo_declare_attr_set(env, c, la, handle);
if (rc)
return rc;
memset(ldata, 0, sizeof(*ldata));
+ LASSERT(ma->ma_attr.la_valid & LA_CTIME);
+ la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
+
rc = mdd_declare_link(env, mdd, mdd_tobj, mdd_sobj, lname, handle,
- ldata);
+ la, ldata);
if (rc)
GOTO(stop, rc);
GOTO(out_unlock, rc);
}
- LASSERT(ma->ma_attr.la_valid & LA_CTIME);
- la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
-
la->la_valid = LA_CTIME | LA_MTIME;
rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0);
if (rc)
LASSERT(mdd_write_locked(env, obj) != 0);
- if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_dir)) {
+ if (ma->ma_attr.la_nlink == 0 || is_dir) {
obj->mod_flags |= DEAD_OBJ;
+
/* add new orphan and the object
* will be deleted during mdd_close() */
if (obj->mod_count) {
if (rc)
return rc;
- rc = mdo_declare_attr_set(env, c, NULL, handle);
+ la->la_valid = LA_CTIME;
+ rc = mdo_declare_attr_set(env, c, la, handle);
if (rc)
return rc;
int rc;
ENTRY;
- /* do not let users to create stripes via .lustre/
- * mdd_obf_setup() sets IMMUTE_OBJ on this directory */
- if (pobj && mdd_pobj->mod_flags & IMMUTE_OBJ)
- RETURN(-ENOENT);
-
rc = mdd_cd_sanity_check(env, son);
if (rc)
RETURN(rc);
if (rc)
GOTO(stop, rc);
+ rc = mdd_declare_changelog_store(env, mdd, NULL, handle);
+ if (rc)
+ GOTO(stop, rc);
+
rc = mdd_trans_start(env, mdd, handle);
if (rc)
GOTO(stop, rc);
rc = dt_xattr_set(env, mdd_object_child(son), buf, XATTR_NAME_LOV,
0, handle, mdd_object_capa(env, son));
+
+ if (rc)
+ GOTO(stop, rc);
+
+ rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, son, handle);
+
stop:
mdd_trans_stop(env, mdd, rc, handle);
out_free:
dotdot, handle);
}
- if (rc == 0 && (fid_is_norm(mdo2fid(child)) ||
- fid_is_dot_lustre(mdo2fid(child)) ||
- fid_is_root(mdo2fid(child))))
+ if (rc == 0)
mdd_declare_links_add(env, child, handle, ldata);
RETURN(rc);
mdo_ref_del(env, child, handle);
}
- if (rc == 0 && (fid_is_norm(mdo2fid(child)) ||
- fid_is_dot_lustre(mdo2fid(child)) ||
- fid_is_root(mdo2fid(child))))
+ if (rc == 0)
mdd_links_add(env, child, pfid, lname, handle, ldata, 1);
RETURN(rc);
} else if (rc == -ENODATA || rc == -EOPNOTSUPP) {
/* If there are no default ACL, fix mode by mask */
struct lu_ucred *uc = lu_ucred(env);
- la->la_mode &= ~uc->uc_umask;
+
+ /* The create triggered by MDT internal events, such as
+ * LFSCK reset, will not contain valid "uc". */
+ if (unlikely(uc != NULL))
+ la->la_mode &= ~uc->uc_umask;
rc = 0;
}
mdd_pdo_write_unlock(env, mdd_pobj, dlh);
out_trans:
- if (rc == 0 && fid_is_client_mdt_visible(mdo2fid(son)))
+ if (rc == 0 && fid_is_namespace_visible(mdo2fid(son)))
rc = mdd_changelog_ns_store(env, mdd,
S_ISDIR(attr->la_mode) ? CL_MKDIR :
S_ISREG(attr->la_mode) ? CL_CREATE :
}
static int mdd_declare_rename(const struct lu_env *env,
- struct mdd_device *mdd,
- struct mdd_object *mdd_spobj,
- struct mdd_object *mdd_tpobj,
- struct mdd_object *mdd_sobj,
- struct mdd_object *mdd_tobj,
- const struct lu_name *tname,
+ struct mdd_device *mdd,
+ struct mdd_object *mdd_spobj,
+ struct mdd_object *mdd_tpobj,
+ struct mdd_object *mdd_sobj,
+ struct mdd_object *mdd_tobj,
+ const struct lu_name *tname,
const struct lu_name *sname,
- struct md_attr *ma,
- struct thandle *handle)
+ struct md_attr *ma,
+ struct linkea_data *ldata,
+ struct thandle *handle)
{
- int rc;
+ struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix;
+ int rc;
+
+ LASSERT(ma->ma_attr.la_valid & LA_CTIME);
+ la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
LASSERT(mdd_spobj);
LASSERT(mdd_tpobj);
rc = mdo_declare_ref_del(env, mdd_spobj, handle);
if (rc)
return rc;
+ if (mdd_spobj != mdd_tpobj) {
+ rc = mdo_declare_index_delete(env, mdd_sobj, dotdot,
+ handle);
+ if (rc)
+ return rc;
- rc = mdo_declare_index_delete(env, mdd_sobj, dotdot, handle);
- if (rc)
- return rc;
-
- rc = mdo_declare_index_insert(env, mdd_sobj, mdo2fid(mdd_tpobj),
- dotdot, handle);
- if (rc)
- return rc;
-
+ rc = mdo_declare_index_insert(env, mdd_sobj,
+ mdo2fid(mdd_tpobj),
+ dotdot, handle);
+ if (rc)
+ return rc;
+ }
/* new target child can be directory,
* counted by target dir's nlink */
rc = mdo_declare_ref_add(env, mdd_tpobj, handle);
}
- rc = mdo_declare_attr_set(env, mdd_spobj, NULL, handle);
- if (rc)
- return rc;
+ la->la_valid = LA_CTIME | LA_MTIME;
+ rc = mdo_declare_attr_set(env, mdd_spobj, la, handle);
+ if (rc != 0)
+ return rc;
- rc = mdo_declare_attr_set(env, mdd_sobj, NULL, handle);
- if (rc)
- return rc;
- mdd_declare_links_add(env, mdd_sobj, handle, NULL);
- if (rc)
- return rc;
+ rc = mdo_declare_attr_set(env, mdd_tpobj, la, handle);
+ if (rc != 0)
+ return rc;
- rc = mdo_declare_attr_set(env, mdd_tpobj, NULL, handle);
- if (rc)
- return rc;
+ la->la_valid = LA_CTIME;
+ rc = mdo_declare_attr_set(env, mdd_sobj, la, handle);
+ if (rc)
+ return rc;
+
+ rc = mdd_declare_links_add(env, mdd_sobj, handle, ldata);
+ if (rc)
+ return rc;
/* new name */
rc = mdo_declare_index_insert(env, mdd_tpobj, mdo2fid(mdd_sobj),
return rc;
}
- rc = mdo_declare_attr_set(env, mdd_tobj, NULL, handle);
+ la->la_valid = LA_CTIME;
+ rc = mdo_declare_attr_set(env, mdd_tobj, la, handle);
if (rc)
return rc;
struct md_object *tobj, const struct lu_name *ltname,
struct md_attr *ma)
{
- const char *sname = lsname->ln_name;
- const char *tname = ltname->ln_name;
- struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix;
+ const char *sname = lsname->ln_name;
+ const char *tname = ltname->ln_name;
+ struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix;
struct lu_attr *so_attr = &mdd_env_info(env)->mti_cattr;
struct lu_attr *tg_attr = &mdd_env_info(env)->mti_pattr;
- struct mdd_object *mdd_spobj = md2mdd_obj(src_pobj); /* source parent */
- struct mdd_object *mdd_tpobj = md2mdd_obj(tgt_pobj);
- struct mdd_device *mdd = mdo2mdd(src_pobj);
- struct mdd_object *mdd_sobj = NULL; /* source object */
- struct mdd_object *mdd_tobj = NULL;
- struct dynlock_handle *sdlh, *tdlh;
- struct thandle *handle;
- const struct lu_fid *tpobj_fid = mdo2fid(mdd_tpobj);
- const struct lu_fid *spobj_fid = mdo2fid(mdd_spobj);
- bool is_dir;
+ struct mdd_object *mdd_spobj = md2mdd_obj(src_pobj); /* source parent */
+ struct mdd_object *mdd_tpobj = md2mdd_obj(tgt_pobj);
+ struct mdd_device *mdd = mdo2mdd(src_pobj);
+ struct mdd_object *mdd_sobj = NULL; /* source object */
+ struct mdd_object *mdd_tobj = NULL;
+ struct dynlock_handle *sdlh = NULL, *tdlh = NULL;
+ struct thandle *handle;
+ struct linkea_data *ldata = &mdd_env_info(env)->mti_link_data;
+ const struct lu_fid *tpobj_fid = mdo2fid(mdd_tpobj);
+ const struct lu_fid *spobj_fid = mdo2fid(mdd_spobj);
+ bool is_dir;
bool tobj_ref = 0;
bool tobj_locked = 0;
unsigned cl_flags = 0;
- int rc, rc2;
- ENTRY;
+ int rc, rc2;
+ ENTRY;
if (tobj)
mdd_tobj = md2mdd_obj(tobj);
mdd_sobj = mdd_object_find(env, mdd, lf);
+ rc = mdd_la_get(env, mdd_sobj, so_attr,
+ mdd_object_capa(env, mdd_sobj));
+ if (rc)
+ GOTO(out_pending, rc);
+
+ if (mdd_tobj) {
+ rc = mdd_la_get(env, mdd_tobj, tg_attr,
+ mdd_object_capa(env, mdd_tobj));
+ if (rc)
+ GOTO(out_pending, rc);
+ }
+
+ rc = mdd_rename_sanity_check(env, mdd_spobj, mdd_tpobj, mdd_sobj,
+ mdd_tobj, so_attr, tg_attr);
+ if (rc)
+ GOTO(out_pending, rc);
+
handle = mdd_trans_create(env, mdd);
if (IS_ERR(handle))
GOTO(out_pending, rc = PTR_ERR(handle));
- rc = mdd_declare_rename(env, mdd, mdd_spobj, mdd_tpobj, mdd_sobj,
- mdd_tobj, lsname, ltname, ma, handle);
- if (rc)
- GOTO(stop, rc);
+ memset(ldata, 0, sizeof(*ldata));
+ mdd_linkea_prepare(env, mdd_sobj, NULL, NULL, mdd_object_fid(mdd_tpobj),
+ ltname, 1, 0, ldata);
+ rc = mdd_declare_rename(env, mdd, mdd_spobj, mdd_tpobj, mdd_sobj,
+ mdd_tobj, lsname, ltname, ma, ldata, handle);
+ if (rc)
+ GOTO(stop, rc);
rc = mdd_trans_start(env, mdd, handle);
if (rc)
if (sdlh == NULL || tdlh == NULL)
GOTO(cleanup, rc = -ENOMEM);
- rc = mdd_la_get(env, mdd_sobj, so_attr,
- mdd_object_capa(env, mdd_sobj));
- if (rc)
- GOTO(cleanup, rc);
-
- if (mdd_tobj) {
- rc = mdd_la_get(env, mdd_tobj, tg_attr,
- mdd_object_capa(env, mdd_tobj));
- if (rc)
- GOTO(cleanup, rc);
- }
-
- rc = mdd_rename_sanity_check(env, mdd_spobj, mdd_tpobj, mdd_sobj,
- mdd_tobj, so_attr, tg_attr);
- if (rc)
- GOTO(cleanup, rc);
-
is_dir = S_ISDIR(so_attr->la_mode);
/* Remove source name from source directory */
handle, 0);
}
- if (rc == 0 && mdd_sobj) {
- mdd_write_lock(env, mdd_sobj, MOR_SRC_CHILD);
+ if (rc == 0 && mdd_sobj) {
+ mdd_write_lock(env, mdd_sobj, MOR_SRC_CHILD);
rc = mdd_links_rename(env, mdd_sobj, mdo2fid(mdd_spobj), lsname,
mdo2fid(mdd_tpobj), ltname, handle, NULL,
0, 0);
}
fixup_spobj:
- if (rc && is_dir && mdd_sobj) {
- rc2 = __mdd_index_delete_only(env, mdd_sobj, dotdot, handle,
- BYPASS_CAPA);
+ if (rc && is_dir && mdd_sobj && mdd_spobj != mdd_tpobj) {
+ rc2 = __mdd_index_delete_only(env, mdd_sobj, dotdot, handle,
+ BYPASS_CAPA);
- if (rc2)
- CWARN("sp obj dotdot delete error %d\n",rc2);
+ if (rc2)
+ CWARN("%s: sp obj dotdot delete error: rc = %d\n",
+ mdd2obd_dev(mdd)->obd_name, rc2);
- rc2 = __mdd_index_insert_only(env, mdd_sobj, spobj_fid,
- dotdot, handle, BYPASS_CAPA);
- if (rc2)
- CWARN("sp obj dotdot insert error %d\n",rc2);
- }
+ rc2 = __mdd_index_insert_only(env, mdd_sobj, spobj_fid,
+ dotdot, handle, BYPASS_CAPA);
+ if (rc2)
+ CWARN("%s: sp obj dotdot insert error: rc = %d\n",
+ mdd2obd_dev(mdd)->obd_name, rc2);
+ }
fixup_spobj2:
if (rc) {