MDD forgets updating target LinkEA if target is not unlinked, and
this will cause LinkEA inconsistency.
Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Change-Id: I92b9019b9517513d0cf3f92cf09e7a546cee6027
Reviewed-on: http://review.whamcloud.com/9366
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Li Wei <wei.g.li@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Henri Doreau <henri.doreau@cea.fr>
/* caller should take a lock before calling */
int mdd_finish_unlink(const struct lu_env *env,
/* caller should take a lock before calling */
int mdd_finish_unlink(const struct lu_env *env,
- struct mdd_object *obj, struct md_attr *ma,
- struct thandle *th)
+ struct mdd_object *obj, struct md_attr *ma,
+ const struct mdd_object *pobj,
+ const struct lu_name *lname,
+ struct thandle *th)
{
int rc = 0;
int is_dir = S_ISDIR(ma->ma_attr.la_mode);
{
int rc = 0;
int is_dir = S_ISDIR(ma->ma_attr.la_mode);
} else {
rc = mdo_destroy(env, obj, th);
}
} else {
rc = mdo_destroy(env, obj, th);
}
+ } else if (!is_dir) {
+ /* old files may not have link ea; ignore errors */
+ mdd_links_del(env, obj, mdo2fid(pobj), lname, th);
+ }
/* XXX: this transfer to ma will be removed with LOD/OSP */
ma->ma_attr = *cattr;
ma->ma_valid |= MA_INODE;
/* XXX: this transfer to ma will be removed with LOD/OSP */
ma->ma_attr = *cattr;
ma->ma_valid |= MA_INODE;
- rc = mdd_finish_unlink(env, mdd_cobj, ma, handle);
+ rc = mdd_finish_unlink(env, mdd_cobj, ma, mdd_pobj, lname, handle);
/* fetch updated nlink */
if (rc == 0)
rc = mdd_la_get(env, mdd_cobj, cattr, BYPASS_CAPA);
/* fetch updated nlink */
if (rc == 0)
rc = mdd_la_get(env, mdd_cobj, cattr, BYPASS_CAPA);
- if (!is_dir)
- /* old files may not have link ea; ignore errors */
- mdd_links_del(env, mdd_cobj, mdo2fid(mdd_pobj), lname, handle);
-
/* if object is removed then we can't get its attrs, use last get */
if (cattr->la_nlink == 0) {
ma->ma_attr = *cattr;
/* if object is removed then we can't get its attrs, use last get */
if (cattr->la_nlink == 0) {
ma->ma_attr = *cattr;
/* XXX: this transfer to ma will be removed with LOD/OSP */
ma->ma_attr = *tattr;
ma->ma_valid |= MA_INODE;
/* XXX: this transfer to ma will be removed with LOD/OSP */
ma->ma_attr = *tattr;
ma->ma_valid |= MA_INODE;
- rc = mdd_finish_unlink(env, mdd_tobj, ma, handle);
+ rc = mdd_finish_unlink(env, mdd_tobj, ma, mdd_tpobj, ltname,
+ handle);
if (rc != 0) {
CERROR("%s: Failed to unlink tobj "
DFID": rc = %d\n",
if (rc != 0) {
CERROR("%s: Failed to unlink tobj "
DFID": rc = %d\n",
struct mdd_object *cobj,
const struct lu_attr *cattr);
int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj,
struct mdd_object *cobj,
const struct lu_attr *cattr);
int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj,
- struct md_attr *ma, struct thandle *th);
+ struct md_attr *ma, const struct mdd_object *pobj,
+ const struct lu_name *lname, struct thandle *th);
int mdd_is_root(struct mdd_device *mdd, const struct lu_fid *fid);
int mdd_lookup(const struct lu_env *env,
int mdd_is_root(struct mdd_device *mdd, const struct lu_fid *fid);
int mdd_lookup(const struct lu_env *env,
}
run_test 237 "Verify name_to_handle_at/open_by_handle_at syscalls"
}
run_test 237 "Verify name_to_handle_at/open_by_handle_at syscalls"
+# LU-4659 linkea consistency
+test_238() {
+ touch $DIR/$tfile
+ ln $DIR/$tfile $DIR/$tfile.lnk
+ touch $DIR/$tfile.new
+ mv $DIR/$tfile.new $DIR/$tfile
+ local fid1=$(lfs path2fid $DIR/$tfile)
+ local fid2=$(lfs path2fid $DIR/$tfile.lnk)
+ local path1=$(lfs fid2path $FSNAME $fid1)
+ [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
+ local path2=$(lfs fid2path $FSNAME $fid2)
+ [ $tfile.lnk == $path2 ] ||
+ error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
+ rm -f $DIR/$tfile*
+}
+run_test 238 "Verify linkea consistency"
+
test_striped_dir() {
local mdt_index=$1
local stripe_count
test_striped_dir() {
local mdt_index=$1
local stripe_count