rec->cr.cr_namelen = tname->ln_namelen;
memcpy(rec->cr.cr_name, tname->ln_name, tname->ln_namelen);
if (sname) {
- LASSERT(sfid != NULL);
rec->cr.cr_name[tname->ln_namelen] = '\0';
memcpy(rec->cr.cr_name + tname->ln_namelen + 1, sname->ln_name,
sname->ln_namelen);
if (rc)
GOTO(out_unlock, rc);
- rc = __mdd_index_insert_only(env, mdd_tobj, mdo2fid(mdd_sobj),
- name, handle,
- mdd_object_capa(env, mdd_tobj));
- if (rc)
- GOTO(out_unlock, rc);
-
rc = mdo_ref_add(env, mdd_sobj, handle);
+ if (rc)
+ GOTO(out_unlock, rc);
+
+
+ rc = __mdd_index_insert_only(env, mdd_tobj, mdo2fid(mdd_sobj),
+ name, handle,
+ mdd_object_capa(env, mdd_tobj));
if (rc != 0) {
- __mdd_index_delete_only(env, mdd_tobj, name, handle,
- mdd_object_capa(env, mdd_tobj));
- GOTO(out_unlock, rc);
+ mdo_ref_del(env, mdd_sobj, handle);
+ GOTO(out_unlock, rc);
}
LASSERT(ma->ma_attr.la_valid & LA_CTIME);
}
int mdd_declare_finish_unlink(const struct lu_env *env,
- struct mdd_object *obj,
- struct md_attr *ma,
- struct thandle *handle)
+ struct mdd_object *obj,
+ struct md_attr *ma,
+ struct thandle *handle)
{
- int rc;
+ int rc;
- rc = orph_declare_index_insert(env, obj, handle);
- if (rc)
- return rc;
+ rc = orph_declare_index_insert(env, obj, mdd_object_type(obj), handle);
+ if (rc)
+ return rc;
return mdo_declare_destroy(env, obj, handle);
}
if (rc)
GOTO(cleanup, rc);
+ rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle,
+ mdd_object_capa(env, mdd_pobj));
+ if (rc)
+ GOTO(cleanup, rc);
+
rc = mdo_ref_del(env, mdd_cobj, handle);
if (rc != 0) {
__mdd_index_insert_only(env, mdd_pobj, mdo2fid(mdd_cobj),
GOTO(cleanup, rc);
}
- rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle,
- mdd_object_capa(env, mdd_pobj));
- if (rc)
- GOTO(cleanup, rc);
-
if (is_dir)
/* unlink dot */
mdo_ref_del(env, mdd_cobj, handle);
spec->u.sp_ea.eadata, spec->u.sp_ea.eadatalen,
spec->sp_cr_flags, spec->no_create);
- if (spec->no_create) {
- /* replay case */
+ if (spec->no_create || spec->sp_cr_flags & MDS_OPEN_HAS_EA) {
+ /* replay case or lfs setstripe */
buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
spec->u.sp_ea.eadatalen);
- } else if (!(spec->sp_cr_flags & MDS_OPEN_HAS_OBJS)) {
- if (spec->sp_cr_flags & MDS_OPEN_HAS_EA) {
- /* lfs setstripe */
- buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
- spec->u.sp_ea.eadatalen);
- } else {
- buf = &LU_BUF_NULL;
- }
} else {
- /* MDS_OPEN_HAS_OBJS is not used anymore ? */
- LBUG();
+ buf = &LU_BUF_NULL;
}
rc = dt_declare_xattr_set(env, mdd_object_child(son), buf,
{
int rc;
+ /*
+ * inode mode has been set in creation time, and it's based on umask,
+ * la_mode and acl, don't set here again! (which will go wrong
+ * because below function doesn't consider umask).
+ * I'd suggest set all object attributes in creation time, see above.
+ */
+ LASSERT(attr->la_valid & (LA_MODE | LA_TYPE));
+ attr->la_valid &= ~(LA_MODE | LA_TYPE);
rc = mdo_declare_attr_set(env, child, attr, handle);
+ attr->la_valid |= LA_MODE | LA_TYPE;
if (rc == 0 && S_ISDIR(attr->la_mode)) {
rc = mdo_declare_index_insert(env, child, mdo2fid(child),
dot, handle);
* because below function doesn't consider umask).
* I'd suggest set all object attributes in creation time, see above.
*/
- attr->la_valid &= ~LA_MODE;
+ LASSERT(attr->la_valid & (LA_MODE | LA_TYPE));
+ attr->la_valid &= ~(LA_MODE | LA_TYPE);
rc = mdd_attr_set_internal(env, child, attr, handle, 0);
- if (rc != 0)
- RETURN(rc);
+ /* arguments are supposed to stay the same */
+ attr->la_valid |= LA_MODE | LA_TYPE;
+ if (rc != 0)
+ RETURN(rc);
if (S_ISDIR(attr->la_mode)) {
/* Add "." and ".." for newly created dir */
if (mdd_is_dead_obj(obj))
RETURN(-ENOENT);
- /*
+ /*
* In some cases this lookup is not needed - we know before if name
* exists or not because MDT performs lookup for it.
* name length check is done in lookup.
struct thandle *handle,
const struct md_op_spec *spec)
{
- struct mdd_thread_info *info = mdd_env_info(env);
- int rc = 0;
+ int rc;
rc = mdd_declare_object_create_internal(env, p, c, attr, handle, spec);
if (rc)
GOTO(out, rc);
}
- rc = mdo_declare_attr_set(env, c, &info->mti_pattr, handle);
+ rc = mdo_declare_attr_set(env, c, attr, handle);
if (rc)
GOTO(out, rc);
}
rc = mdd_declare_object_initialize(env, c, attr, handle);
- if (rc)
- GOTO(out, rc);
+ if (rc)
+ GOTO(out, rc);
- rc = mdo_declare_index_insert(env, p, mdo2fid(c),
- name->ln_name, handle);
- if (rc)
- GOTO(out, rc);
+ if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+ rc = orph_declare_index_insert(env, c, attr->la_mode, handle);
+ else
+ rc = mdo_declare_index_insert(env, p, mdo2fid(c),
+ name->ln_name, handle);
+ if (rc)
+ GOTO(out, rc);
/* replay case, create LOV EA from client data */
if (spec->no_create || (spec->sp_cr_flags & MDS_OPEN_HAS_EA)) {
GOTO(out, rc);
}
- rc = mdo_declare_attr_set(env, p, attr, handle);
- if (rc)
- return rc;
+ if (!(spec->sp_cr_flags & MDS_OPEN_VOLATILE)) {
+ rc = mdo_declare_attr_set(env, p, attr, handle);
+ if (rc)
+ return rc;
+ }
rc = mdd_declare_changelog_store(env, mdd, name, handle);
if (rc)
const struct lu_name *lname, struct md_object *child,
struct md_op_spec *spec, struct md_attr* ma)
{
- struct mdd_thread_info *info = mdd_env_info(env);
- struct lu_attr *la = &info->mti_la_for_fix;
- struct mdd_object *mdd_pobj = md2mdd_obj(pobj);
- struct mdd_object *son = md2mdd_obj(child);
- struct mdd_device *mdd = mdo2mdd(pobj);
- struct lu_attr *attr = &ma->ma_attr;
- struct thandle *handle;
- struct lu_attr *pattr = &info->mti_pattr;
- struct dynlock_handle *dlh;
- const char *name = lname->ln_name;
- int rc, created = 0, initialized = 0, inserted = 0;
- int got_def_acl = 0;
- ENTRY;
+ struct mdd_thread_info *info = mdd_env_info(env);
+ struct lu_attr *la = &info->mti_la_for_fix;
+ struct mdd_object *mdd_pobj = md2mdd_obj(pobj);
+ struct mdd_object *son = md2mdd_obj(child);
+ struct mdd_device *mdd = mdo2mdd(pobj);
+ struct lu_attr *attr = &ma->ma_attr;
+ struct thandle *handle;
+ struct lu_attr *pattr = &info->mti_pattr;
+ struct dynlock_handle *dlh;
+ const char *name = lname->ln_name;
+ int rc, created = 0, initialized = 0, inserted = 0;
+ int got_def_acl = 0;
+ ENTRY;
/*
* Two operations have to be performed:
if (rc)
GOTO(out_stop, rc);
- dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
- if (dlh == NULL)
- GOTO(out_trans, rc = -ENOMEM);
+ dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT);
+ if (dlh == NULL)
+ GOTO(out_trans, rc = -ENOMEM);
- mdd_write_lock(env, son, MOR_TGT_CHILD);
- rc = mdd_object_create_internal(env, mdd_pobj, son, attr, handle, spec);
- if (rc) {
- mdd_write_unlock(env, son);
- GOTO(cleanup, rc);
- }
+ mdd_write_lock(env, son, MOR_TGT_CHILD);
+ rc = mdd_object_create_internal(env, NULL, son, attr, handle, spec);
+ if (rc) {
+ mdd_write_unlock(env, son);
+ GOTO(cleanup, rc);
+ }
- created = 1;
+ created = 1;
#ifdef CONFIG_FS_POSIX_ACL
- if (got_def_acl) {
+ if (got_def_acl) {
struct lu_buf *acl_buf;
acl_buf = mdd_buf_get(env, info->mti_xattr_buf, got_def_acl);
mdd_write_unlock(env, son);
GOTO(cleanup, rc);
}
- }
+ }
#endif
- rc = mdd_object_initialize(env, mdo2fid(mdd_pobj), lname,
+ rc = mdd_object_initialize(env, mdo2fid(mdd_pobj), lname,
son, attr, handle, spec);
/*
* MDT calls this xattr_set(LOV) in a different transaction.
* probably this way we code can be made better.
*/
- if (rc == 0 &&
- (spec->no_create || (spec->sp_cr_flags & MDS_OPEN_HAS_EA))) {
+ if (rc == 0 && (spec->no_create ||
+ (spec->sp_cr_flags & MDS_OPEN_HAS_EA))) {
const struct lu_buf *buf;
buf = mdd_buf_get_const(env, spec->u.sp_ea.eadata,
rc = mdo_xattr_set(env, son, buf, XATTR_NAME_LOV, 0, handle,
BYPASS_CAPA);
}
- mdd_write_unlock(env, son);
- if (rc)
- /*
- * Object has no links, so it will be destroyed when last
- * reference is released. (XXX not now.)
- */
- GOTO(cleanup, rc);
- initialized = 1;
+ if (rc == 0 && spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+ rc = __mdd_orphan_add(env, son, handle);
- rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son),
- name, S_ISDIR(attr->la_mode), handle,
- mdd_object_capa(env, mdd_pobj));
- if (rc)
- GOTO(cleanup, rc);
+ mdd_write_unlock(env, son);
- inserted = 1;
+ if (rc != 0)
+ /*
+ * Object has no links, so it will be destroyed when last
+ * reference is released. (XXX not now.)
+ */
+ GOTO(cleanup, rc);
+
+ initialized = 1;
+
+ if (!(spec->sp_cr_flags & MDS_OPEN_VOLATILE))
+ rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son),
+ name, S_ISDIR(attr->la_mode), handle,
+ mdd_object_capa(env, mdd_pobj));
+
+ if (rc != 0)
+ GOTO(cleanup, rc);
+
+ inserted = 1;
if (S_ISLNK(attr->la_mode)) {
struct lu_ucred *uc = lu_ucred_assert(env);
GOTO(cleanup, rc = -EFAULT);
}
+ /* volatile file creation does not update parent directory times */
+ if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+ GOTO(cleanup, rc = 0);
+
+ /* update parent directory mtime/ctime */
*la = *attr;
- la->la_valid = LA_CTIME | LA_MTIME;
+ la->la_valid = LA_CTIME | LA_MTIME;
rc = mdd_attr_check_set_internal(env, mdd_pobj, la, handle, 0);
- if (rc)
- GOTO(cleanup, rc);
+ if (rc)
+ GOTO(cleanup, rc);
EXIT;
cleanup:
int rc2;
if (inserted != 0) {
- rc2 = __mdd_index_delete(env, mdd_pobj, name,
- S_ISDIR(attr->la_mode),
- handle, BYPASS_CAPA);
+ if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+ rc2 = __mdd_orphan_del(env, son, handle);
+ else
+ rc2 = __mdd_index_delete(env, mdd_pobj, name,
+ S_ISDIR(attr->la_mode),
+ handle, BYPASS_CAPA);
if (rc2 != 0)
goto out_stop;
}