* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011 Whamcloud, Inc.
- *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
RETURN(rc);
}
-/**
- * If subdir count is up to ddp_max_nlink, then enable MNLINK_OBJ flag and
- * assign i_nlink to 1 which means the i_nlink for subdir count is incredible
- * (maybe too large to be represented). It is a trick to break through the
- * "i_nlink" limitation for subdir count.
- */
-void __mdd_ref_add(const struct lu_env *env, struct mdd_object *obj,
- struct thandle *handle)
-{
- struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
- struct mdd_device *m = mdd_obj2mdd_dev(obj);
-
- if (!mdd_is_mnlink(obj)) {
- if (S_ISDIR(mdd_object_type(obj))) {
- if (mdd_la_get(env, obj, tmp_la, BYPASS_CAPA))
- return;
-
- if (tmp_la->la_nlink >= m->mdd_dt_conf.ddp_max_nlink) {
- obj->mod_flags |= MNLINK_OBJ;
- tmp_la->la_nlink = 1;
- tmp_la->la_valid = LA_NLINK;
- mdd_attr_set_internal(env, obj, tmp_la, handle,
- 0);
- return;
- }
- }
- mdo_ref_add(env, obj, handle);
- }
-}
-
-void __mdd_ref_del(const struct lu_env *env, struct mdd_object *obj,
- struct thandle *handle, int is_dot)
-{
- if (!mdd_is_mnlink(obj) || is_dot)
- mdo_ref_del(env, obj, handle);
-}
-
static int __mdd_index_delete_only(const struct lu_env *env, struct mdd_object *pobj,
const char *name, struct thandle *handle,
struct lustre_capa *capa)
rc = __mdd_index_insert_only(env, pobj, lf, name, handle, capa);
if (rc == 0 && is_dir) {
mdd_write_lock(env, pobj, MOR_TGT_PARENT);
- __mdd_ref_add(env, pobj, handle);
+ mdo_ref_add(env, pobj, handle);
mdd_write_unlock(env, pobj);
}
RETURN(rc);
rc = __mdd_index_delete_only(env, pobj, name, handle, capa);
if (rc == 0 && is_dir) {
- int is_dot = 0;
-
- if (name != NULL && name[0] == '.' && name[1] == 0)
- is_dot = 1;
mdd_write_lock(env, pobj, MOR_TGT_PARENT);
- __mdd_ref_del(env, pobj, handle, is_dot);
+ mdo_ref_del(env, pobj, handle);
mdd_write_unlock(env, pobj);
}
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, reclen, 0, handle);
+ 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, LLOG_CHUNK_SIZE,
- 0, handle);
+ rc = dt_declare_record_write(env, mdd->mdd_capa,
+ DECLARE_LLOG_WRITE, 0, handle);
if (rc)
return rc;
/* new record referencing new plain llog */
rc = dt_declare_record_write(env, mdd->mdd_capa,
- sizeof(struct llog_logid_rec), 0, handle);
+ 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, LLOG_CHUNK_SIZE,
- 0, handle);
+ rc = dt_declare_record_write(env, mdd->mdd_capa,
+ DECLARE_LLOG_REWRITE, 0, handle);
return rc;
}
if (rc)
GOTO(out_unlock, rc);
- __mdd_ref_add(env, mdd_sobj, handle);
+ mdo_ref_add(env, mdd_sobj, handle);
LASSERT(ma->ma_attr.la_valid & LA_CTIME);
la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
{
int rc;
int reset = 1;
+ int is_dir = S_ISDIR(ma->ma_attr.la_mode);
ENTRY;
LASSERT(mdd_write_locked(env, obj) != 0);
/* read HSM flags, needed to set changelogs flags */
ma->ma_need = MA_HSM | MA_INODE;
rc = mdd_attr_get_internal(env, obj, ma);
- if (rc == 0 && ma->ma_attr.la_nlink == 0) {
+ if (rc == 0 && (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() */
reset = 0;
}
+ /* get the i_nlink */
+ ma->ma_need = MA_INODE;
+ rc = mdd_attr_get_internal(env, obj, ma);
}
if (reset)
ma->ma_valid &= ~(MA_LOV | MA_COOKIE);
if (rc)
GOTO(cleanup, rc);
- __mdd_ref_del(env, mdd_cobj, handle, 0);
+ mdo_ref_del(env, mdd_cobj, handle);
if (is_dir)
/* unlink dot */
- __mdd_ref_del(env, mdd_cobj, handle, 1);
+ mdo_ref_del(env, mdd_cobj, handle);
LASSERT(ma->ma_attr.la_valid & LA_CTIME);
la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime;
* it must be local one.
*/
if (tobj && mdd_object_exists(mdd_tobj)) {
- __mdd_ref_del(env, mdd_tobj, handle, 0);
+ mdo_ref_del(env, mdd_tobj, handle);
/* Remove dot reference. */
if (S_ISDIR(ma->ma_attr.la_mode))
- __mdd_ref_del(env, mdd_tobj, handle, 1);
+ mdo_ref_del(env, mdd_tobj, handle);
la->la_valid = LA_CTIME;
rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0);
struct mdd_device *mdd = mdo2mdd(cobj);
struct mdd_object *mdd_pobj = md2mdd_obj(pobj);
struct mdd_object *son = md2mdd_obj(cobj);
- struct lu_attr *attr = &ma->ma_attr;
struct lov_mds_md *lmm = NULL;
int lmm_size = 0;
struct thandle *handle;
if (!md_should_create(spec->sp_cr_flags))
RETURN(0);
lmm_size = ma->ma_lmm_size;
- rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size,
- spec, attr);
+
+ rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size, spec, ma);
if (rc)
RETURN(rc);
mdd_trans_stop(env, mdd, rc, handle);
out_free:
/* Finish mdd_lov_create() stuff. */
+ /* if no_create == 0 (not replay), we free lmm allocated by
+ * mdd_lov_create() */
mdd_lov_create_finish(env, mdd, lmm, lmm_size, spec);
RETURN(rc);
}
if (S_ISDIR(ma->ma_attr.la_mode)) {
/* Add "." and ".." for newly created dir */
- __mdd_ref_add(env, child, handle);
+ mdo_ref_add(env, child, handle);
rc = __mdd_index_insert_only(env, child, mdo2fid(child),
dot, handle, BYPASS_CAPA);
if (rc == 0)
dotdot, handle,
BYPASS_CAPA);
if (rc != 0)
- __mdd_ref_del(env, child, handle, 1);
+ mdo_ref_del(env, child, handle);
}
if (rc == 0)
mdd_links_add(env, child, pfid, lname, handle, 1);
if (S_ISREG(attr->la_mode)) {
lmm_size = ma->ma_lmm_size;
rc = mdd_lov_create(env, mdd, mdd_pobj, son, &lmm, &lmm_size,
- spec, attr);
+ spec, ma);
if (rc)
GOTO(out_pending, rc);
}
if (rc2 == 0) {
mdd_write_lock(env, son, MOR_TGT_CHILD);
- __mdd_ref_del(env, son, handle, 0);
+ mdo_ref_del(env, son, handle);
if (initialized && S_ISDIR(attr->la_mode))
- __mdd_ref_del(env, son, handle, 1);
+ mdo_ref_del(env, son, handle);
mdd_write_unlock(env, son);
}
}
rc = -EINVAL;
goto cleanup;
}
- __mdd_ref_del(env, mdd_tobj, handle, 0);
+ mdo_ref_del(env, mdd_tobj, handle);
/* Remove dot reference. */
if (is_dir)
- __mdd_ref_del(env, mdd_tobj, handle, 1);
+ mdo_ref_del(env, mdd_tobj, handle);
la->la_valid = LA_CTIME;
rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0);
.mdo_rename = mdd_rename,
.mdo_link = mdd_link,
.mdo_unlink = mdd_unlink,
+ .mdo_lum_lmm_cmp = mdd_lum_lmm_cmp,
.mdo_name_insert = mdd_name_insert,
.mdo_name_remove = mdd_name_remove,
.mdo_rename_tgt = mdd_rename_tgt,