X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_dir.c;h=f9d0c7f5bf88fa3b6a70a44a0755ef25e38d40e3;hp=6045cf3d1cd71687950a0b7b29342a29d7dd20ca;hb=a77212cd13627b2b9f1835c48599e91c82aeed9d;hpb=dc89b0a99c82f0e9da3a0dad91763d61e3a3a4a9 diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 6045cf3..f9d0c7f 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -82,7 +82,7 @@ static int mdd_links_add(const struct lu_env *env, struct mdd_object *mdd_obj, const struct lu_fid *pfid, const struct lu_name *lname, - struct thandle *handle); + struct thandle *handle, int first); static int mdd_links_rename(const struct lu_env *env, struct mdd_object *mdd_obj, const struct lu_fid *oldpfid, @@ -250,8 +250,8 @@ static int mdd_dir_is_empty(const struct lu_env *env, RETURN(-ENOTDIR); iops = &obj->do_index_ops->dio_it; - it = iops->init(env, obj, BYPASS_CAPA); - if (it != NULL) { + it = iops->init(env, obj, LUDA_64BITHASH, BYPASS_CAPA); + if (!IS_ERR(it)) { result = iops->get(env, it, (const void *)""); if (result > 0) { int i; @@ -270,7 +270,7 @@ static int mdd_dir_is_empty(const struct lu_env *env, iops->put(env, it); iops->fini(env, it); } else - result = -ENOMEM; + result = PTR_ERR(it); RETURN(result); } @@ -619,6 +619,7 @@ static int __mdd_index_delete(const struct lu_env *env, struct mdd_object *pobj, static int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd, enum changelog_rec_type type, + int flags, struct mdd_object *target, struct mdd_object *parent, const struct lu_fid *tf, @@ -633,8 +634,11 @@ static int mdd_changelog_ns_store(const struct lu_env *env, int rc; ENTRY; + /* Not recording */ if (!(mdd->mdd_cl.mc_flags & CLM_ON)) RETURN(0); + if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0) + RETURN(0); LASSERT(parent != NULL); LASSERT(tname != NULL); @@ -647,7 +651,7 @@ static int mdd_changelog_ns_store(const struct lu_env *env, RETURN(-ENOMEM); rec = (struct llog_changelog_rec *)buf->lb_buf; - rec->cr.cr_flags = CLF_VERSION; + rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; tfid = tf ? tf : mdo2fid(target); rec->cr.cr_tfid = *tfid; @@ -738,8 +742,10 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, la->la_valid = LA_CTIME; rc = mdd_attr_check_set_internal(env, mdd_sobj, la, handle, 0); - if (rc == 0) - mdd_links_add(env, mdd_sobj, mdo2fid(mdd_tobj), lname, handle); + if (rc == 0) { + mdd_links_add(env, mdd_sobj, + mdo2fid(mdd_tobj), lname, handle, 0); + } EXIT; out_unlock: @@ -747,7 +753,7 @@ out_unlock: mdd_pdo_write_unlock(env, mdd_tobj, dlh); out_trans: if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_HARDLINK, mdd_sobj, + rc = mdd_changelog_ns_store(env, mdd, CL_HARDLINK, 0, mdd_sobj, mdd_tobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); out_pending: @@ -775,7 +781,9 @@ int mdd_finish_unlink(const struct lu_env *env, LASSERT(mdd_write_locked(env, obj) != 0); - rc = mdd_iattr_get(env, obj, ma); + /* 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) { obj->mod_flags |= DEAD_OBJ; /* add new orphan and the object @@ -881,10 +889,14 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, if (rc) GOTO(cleanup, rc); - la->la_valid = LA_CTIME; - rc = mdd_attr_check_set_internal(env, mdd_cobj, la, handle, 0); - if (rc) - GOTO(cleanup, rc); + if (ma->ma_attr.la_nlink > 0 || mdd_cobj->mod_count > 0) { + /* update ctime of an unlinked file only if it is still + * opened or a link still exists */ + la->la_valid = LA_CTIME; + rc = mdd_attr_check_set_internal(env, mdd_cobj, la, handle, 0); + if (rc) + GOTO(cleanup, rc); + } rc = mdd_finish_unlink(env, mdd_cobj, ma, handle); #ifdef HAVE_QUOTA_SUPPORT @@ -914,11 +926,18 @@ cleanup: mdd_write_unlock(env, mdd_cobj); mdd_pdo_write_unlock(env, mdd_pobj, dlh); out_trans: - if (rc == 0) + if (rc == 0) { + int cl_flags; + + cl_flags = (ma->ma_attr.la_nlink == 0) ? CLF_UNLINK_LAST : 0; + if ((ma->ma_valid & MA_HSM) && + (ma->ma_hsm.mh_flags & HS_EXISTS)) + cl_flags |= CLF_UNLINK_HSM_EXISTS; + rc = mdd_changelog_ns_store(env, mdd, - is_dir ? CL_RMDIR : CL_UNLINK, - mdd_cobj, mdd_pobj, NULL, lname, - handle); + is_dir ? CL_RMDIR : CL_UNLINK, cl_flags, + mdd_cobj, mdd_pobj, NULL, lname, handle); + } mdd_trans_stop(env, mdd, rc, handle); #ifdef HAVE_QUOTA_SUPPORT @@ -1292,7 +1311,7 @@ out_trans: if (rc == 0) /* Bare EXT record with no RENAME in front of it signifies a partial slave op */ - rc = mdd_changelog_ns_store(env, mdd, CL_EXT, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_EXT, 0, mdd_tobj, mdd_tpobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -1476,7 +1495,7 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, __mdd_ref_del(env, child, handle, 1); } if (rc == 0) - mdd_links_add(env, child, pfid, lname, handle); + mdd_links_add(env, child, pfid, lname, handle, 1); RETURN(rc); } @@ -1843,10 +1862,10 @@ out_trans: S_ISDIR(attr->la_mode) ? CL_MKDIR : S_ISREG(attr->la_mode) ? CL_CREATE : S_ISLNK(attr->la_mode) ? CL_SOFTLINK : CL_MKNOD, - son, mdd_pobj, NULL, lname, handle); + 0, son, mdd_pobj, NULL, lname, handle); mdd_trans_stop(env, mdd, rc, handle); out_free: - /* finis lov_create stuff, free all temporary data */ + /* finish lov_create stuff, free all temporary data */ mdd_lov_create_finish(env, mdd, lmm, lmm_size, spec); out_pending: #ifdef HAVE_QUOTA_SUPPORT @@ -2160,7 +2179,7 @@ static int mdd_rename(const struct lu_env *env, if (rc == -ENOENT) /* Old files might not have EA entry */ mdd_links_add(env, mdd_sobj, mdo2fid(mdd_spobj), - lsname, handle); + lsname, handle, 0); mdd_write_unlock(env, mdd_sobj); /* We don't fail the transaction if the link ea can't be updated -- fid2path will use alternate lookup method. */ @@ -2217,10 +2236,10 @@ cleanup: mdd_pdo_write_unlock(env, mdd_spobj, sdlh); cleanup_unlocked: if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_RENAME, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_RENAME, 0, mdd_tobj, mdd_spobj, lf, lsname, handle); if (rc == 0) - rc = mdd_changelog_ns_store(env, mdd, CL_EXT, mdd_tobj, + rc = mdd_changelog_ns_store(env, mdd, CL_EXT, 0, mdd_tobj, mdd_tpobj, lf, ltname, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -2313,10 +2332,12 @@ struct lu_buf *mdd_links_get(const struct lu_env *env, static int mdd_lee_pack(struct link_ea_entry *lee, const struct lu_name *lname, const struct lu_fid *pfid) { - int reclen; + struct lu_fid tmpfid; + int reclen; - fid_cpu_to_be(&lee->lee_parent_fid, pfid); - strncpy(lee->lee_name, lname->ln_name, lname->ln_namelen); + fid_cpu_to_be(&tmpfid, pfid); + memcpy(&lee->lee_parent_fid, &tmpfid, sizeof(tmpfid)); + memcpy(lee->lee_name, lname->ln_name, lname->ln_namelen); reclen = sizeof(struct link_ea_entry) + lname->ln_namelen; lee->lee_reclen[0] = (reclen >> 8) & 0xff; @@ -2328,7 +2349,8 @@ void mdd_lee_unpack(const struct link_ea_entry *lee, int *reclen, struct lu_name *lname, struct lu_fid *pfid) { *reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1]; - fid_be_to_cpu(pfid, &lee->lee_parent_fid); + memcpy(pfid, &lee->lee_parent_fid, sizeof(*pfid)); + fid_be_to_cpu(pfid, pfid); lname->ln_name = lee->lee_name; lname->ln_namelen = *reclen - sizeof(struct link_ea_entry); } @@ -2371,7 +2393,7 @@ static int mdd_links_add(const struct lu_env *env, struct mdd_object *mdd_obj, const struct lu_fid *pfid, const struct lu_name *lname, - struct thandle *handle) + struct thandle *handle, int first) { struct lu_buf *buf; struct link_ea_header *leh; @@ -2381,7 +2403,7 @@ static int mdd_links_add(const struct lu_env *env, if (!mdd_linkea_enable) RETURN(0); - buf = mdd_links_get(env, mdd_obj); + buf = first ? ERR_PTR(-ENODATA) : mdd_links_get(env, mdd_obj); if (IS_ERR(buf)) { rc = PTR_ERR(buf); if (rc != -ENODATA) { @@ -2411,11 +2433,16 @@ static int mdd_links_add(const struct lu_env *env, rc = __mdd_xattr_set(env, mdd_obj, mdd_buf_get_const(env, buf->lb_buf, leh->leh_len), XATTR_NAME_LINK, 0, handle); - if (rc) - CERROR("link_ea add failed %d "DFID"\n", rc, - PFID(mdd_object_fid(mdd_obj))); + if (rc) { + if (rc == -ENOSPC) + CDEBUG(D_INODE, "link_ea add failed %d "DFID"\n", rc, + PFID(mdd_object_fid(mdd_obj))); + else + CERROR("link_ea add failed %d "DFID"\n", rc, + PFID(mdd_object_fid(mdd_obj))); + } - if (buf->lb_vmalloc) + if (buf->lb_len > OBD_ALLOC_BIG) /* if we vmalloced a large buffer drop it */ mdd_buf_put(buf); @@ -2450,8 +2477,12 @@ static int mdd_links_rename(const struct lu_env *env, buf = mdd_links_get(env, mdd_obj); if (IS_ERR(buf)) { rc = PTR_ERR(buf); - CERROR("link_ea read failed %d "DFID"\n", - rc, PFID(mdd_object_fid(mdd_obj))); + if (rc == -ENODATA) + CDEBUG(D_INODE, "link_ea read failed %d "DFID"\n", + rc, PFID(mdd_object_fid(mdd_obj))); + else + CERROR("link_ea read failed %d "DFID"\n", + rc, PFID(mdd_object_fid(mdd_obj))); RETURN(rc); } leh = buf->lb_buf; @@ -2498,7 +2529,7 @@ out: oldlname->ln_namelen, oldlname->ln_name, rc, PFID(mdd_object_fid(mdd_obj))); - if (buf->lb_vmalloc) + if (buf->lb_len > OBD_ALLOC_BIG) /* if we vmalloced a large buffer drop it */ mdd_buf_put(buf); @@ -2515,5 +2546,5 @@ const struct md_dir_operations mdd_dir_ops = { .mdo_name_insert = mdd_name_insert, .mdo_name_remove = mdd_name_remove, .mdo_rename_tgt = mdd_rename_tgt, - .mdo_create_data = mdd_create_data + .mdo_create_data = mdd_create_data, };