From: wangdi Date: Mon, 6 Jan 2014 01:44:54 +0000 (-0800) Subject: LU-2995 osd: Delete the ref of remote parent in del .. X-Git-Tag: 2.3.64~67 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=809d6a120a238ec64830ab16969728c8433dbeba LU-2995 osd: Delete the ref of remote parent in del .. Try to delete remote dir from REMOTE PARENT during delete .., because the object might not be destroyed if it is being opened by someone else, instead it will be inserted to the ORPHAN dir, so if it does not delete the {.., REMOTE_PARENT}, it will be two parents for this remote dir. Add remote object FID into op_data->op_fid3, so the stale check will not fail during remote open. Signed-off-by: wang di Change-Id: I6bbac9174869ae02f385ac52740bb2046f0f1bab Reviewed-on: http://review.whamcloud.com/5791 Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index b5bd261..821931e 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -284,7 +284,7 @@ enum lma_incompat { LMAI_REMOTE_PARENT = 0x00000004, /* the parent of the object is on the remote MDT */ }; -#define LMA_INCOMPAT_SUPP 0x0 +#define LMA_INCOMPAT_SUPP (LMAI_AGENT | LMAI_REMOTE_PARENT) /** * Following struct for MDT attributes, that will be kept inode's EA. diff --git a/lustre/include/lustre_update.h b/lustre/include/lustre_update.h index 03a4b63..d7f8cab 100644 --- a/lustre/include/lustre_update.h +++ b/lustre/include/lustre_update.h @@ -31,7 +31,7 @@ #ifndef _LUSTRE_UPDATE_H #define _LUSTRE_UPDATE_H -#define UPDATE_BUFFER_SIZE 4096 +#define UPDATE_BUFFER_SIZE 8192 struct update_request { struct dt_device *ur_dt; cfs_list_t ur_list; /* attached itself to thandle */ diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 387dd9d..14f49d3 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -111,8 +111,16 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm, op_data->op_fid1 = body->fid1; /* Sent the parent FID to the remote MDT */ - if (parent_fid != NULL) + if (parent_fid != NULL) { + /* The parent fid is only for remote open to + * check whether the open is from OBF, + * see mdt_cross_open */ + LASSERT(it->it_op & IT_OPEN); op_data->op_fid2 = *parent_fid; + /* Add object FID to op_fid3, in case it needs to check stale + * (M_CHECK_STALE), see mdc_finish_intent_lock */ + op_data->op_fid3 = body->fid1; + } op_data->op_bias = MDS_CROSS_REF; CDEBUG(D_INODE, "REMOTE_INTENT with fid="DFID" -> mds #%d\n", diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 806fcc0..8965c31 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -255,6 +255,8 @@ int osd_add_to_remote_parent(const struct lu_env *env, struct osd_device *osd, mutex_lock(&parent->d_inode->i_mutex); rc = osd_ldiskfs_add_entry(oh->ot_handle, dentry, obj->oo_inode, NULL); + CDEBUG(D_INODE, "%s: add %s:%lu to remote parent %lu.\n", osd_name(osd), + name, obj->oo_inode->i_ino, parent->d_inode->i_ino); LASSERTF(parent->d_inode->i_nlink > 1, "%s: %lu nlink %d", osd_name(osd), parent->d_inode->i_ino, parent->d_inode->i_nlink); @@ -297,6 +299,8 @@ int osd_delete_from_remote_parent(const struct lu_env *env, mutex_unlock(&parent->d_inode->i_mutex); RETURN(-ENOENT); } + CDEBUG(D_INODE, "%s: el %s:%lu to remote parent %lu.\n", osd_name(osd), + name, obj->oo_inode->i_ino, parent->d_inode->i_ino); rc = ldiskfs_delete_entry(oh->ot_handle, parent->d_inode, de, bh); LASSERTF(parent->d_inode->i_nlink > 1, "%s: %lu nlink %d", osd_name(osd), parent->d_inode->i_ino, @@ -305,6 +309,12 @@ int osd_delete_from_remote_parent(const struct lu_env *env, mark_inode_dirty(parent->d_inode); mutex_unlock(&parent->d_inode->i_mutex); brelse(bh); + + /* Get rid of REMOTE_PARENT flag from incompat */ + lma->lma_incompat &= ~LMAI_REMOTE_PARENT; + lustre_lma_swab(lma); + rc = __osd_xattr_set(oti, obj->oo_inode, XATTR_NAME_LMA, lma, + sizeof(*lma), XATTR_REPLACE); RETURN(rc); } diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 2c4ec7f..040ff74 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -194,7 +194,7 @@ int osd_get_lma(struct osd_thread_info *info, struct inode *inode, /* Check LMA compatibility */ if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) { CWARN("%.16s: unsupported incompat LMA feature(s) " - "%lx/%#x\n", + "%lu/%#x\n", LDISKFS_SB(inode->i_sb)->s_es->s_volume_name, inode->i_ino, le32_to_cpu(lma->lma_incompat) & ~LMA_INCOMPAT_SUPP); @@ -3265,10 +3265,22 @@ static int osd_index_ea_delete(const struct lu_env *env, struct dt_object *dt, GOTO(out, rc); /* For inode on the remote MDT, .. will point to - * /Agent directory. So do not try to lookup/delete - * remote inode for .. */ - if (strcmp((char *)key, dotdot) == 0) - GOTO(out, rc = 0); + * /Agent directory. So + * 1. do not need to lookup/delete remote inode for .. + * 2. Check whether it needs to delete from agent directory */ + if (strcmp((char *)key, dotdot) == 0) { + rc = osd_delete_from_remote_parent(env, osd_obj2dev(obj), obj, + oh); + if (rc != 0 && rc != -ENOENT) { + CERROR("%s: delete agent inode "DFID": rc = %d\n", + osd_name(osd), PFID(fid), rc); + } + + if (rc == -ENOENT) + rc = 0; + + GOTO(out, rc); + } LASSERT(de != NULL); rc = osd_get_fid_from_dentry(de, (struct dt_rec *)fid);