Commit c3397e7e authored by wang di's avatar wang di Committed by Greg Kroah-Hartman

staging: lustre: llite: add error handler in inode prepare phase

Add error handler during inode inialization, so inode will
become bad inode if something bad happens during inode prepare
phase, otherwise the striped directory will not get its layout
and being mis-regarded as normal directory.
Signed-off-by: default avatarwang di <di.wang@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4930
Reviewed-on: http://review.whamcloud.com/10170Reviewed-by: default avatarLai Siyao <lai.siyao@intel.com>
Reviewed-by: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8877d3bf
......@@ -766,8 +766,8 @@ int ll_setattr(struct dentry *de, struct iattr *attr);
int ll_statfs(struct dentry *de, struct kstatfs *sfs);
int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
__u64 max_age, __u32 flags);
void ll_update_inode(struct inode *inode, struct lustre_md *md);
void ll_read_inode2(struct inode *inode, void *opaque);
int ll_update_inode(struct inode *inode, struct lustre_md *md);
int ll_read_inode2(struct inode *inode, void *opaque);
void ll_delete_inode(struct inode *inode);
int ll_iocontrol(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
......
......@@ -464,7 +464,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
md_free_lustre_md(sbi->ll_md_exp, &lmd);
ptlrpc_req_finished(request);
if (!(root)) {
if (IS_ERR(root)) {
if (lmd.lsm)
obd_free_memmd(sbi->ll_dt_exp, &lmd.lsm);
#ifdef CONFIG_FS_POSIX_ACL
......@@ -1109,11 +1109,11 @@ static inline int lli_lsm_md_eq(const struct lmv_stripe_md *lsm_md1,
lsm_md2->lsm_md_pool_name);
}
static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lmv_stripe_md *lsm = md->lmv;
int idx;
int idx, rc;
LASSERT(S_ISDIR(inode->i_mode));
CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md,
......@@ -1122,7 +1122,7 @@ static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
/* no striped information from request. */
if (!lsm) {
if (!lli->lli_lsm_md) {
return;
return 0;
} else if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_MIGRATE) {
/*
* migration is done, the temporay MIGRATE layout has
......@@ -1132,27 +1132,22 @@ static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
PFID(ll_inode2fid(inode)));
lmv_free_memmd(lli->lli_lsm_md);
lli->lli_lsm_md = NULL;
return;
return 0;
} else {
/*
* The lustre_md from req does not include stripeEA,
* see ll_md_setattr
*/
return;
return 0;
}
}
/* set the directory layout */
if (!lli->lli_lsm_md) {
int rc;
rc = ll_init_lsm_md(inode, md);
if (rc) {
CERROR("%s: init "DFID" failed: rc = %d\n",
ll_get_fsname(inode->i_sb, NULL, 0),
PFID(&lli->lli_fid), rc);
return;
}
if (rc)
return rc;
lli->lli_lsm_md = lsm;
/*
* set lsm_md to NULL, so the following free lustre_md
......@@ -1161,7 +1156,7 @@ static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
md->lmv = NULL;
CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
return;
return 0;
}
/* Compare the old and new stripe information */
......@@ -1185,7 +1180,7 @@ static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
lli->lli_lsm_md->lsm_md_layout_version,
lsm->lsm_md_pool_name,
lli->lli_lsm_md->lsm_md_pool_name);
return;
return -EIO;
}
for (idx = 0; idx < lli->lli_lsm_md->lsm_md_stripe_count; idx++) {
......@@ -1195,12 +1190,13 @@ static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
ll_get_fsname(inode->i_sb, NULL, 0), idx,
PFID(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid),
PFID(&lsm->lsm_md_oinfo[idx].lmo_fid));
return;
return -EIO;
}
}
md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
md->body, ll_md_blocking_ast);
rc = md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
md->body, ll_md_blocking_ast);
return rc;
}
void ll_clear_inode(struct inode *inode)
......@@ -1252,7 +1248,7 @@ void ll_clear_inode(struct inode *inode)
if (S_ISDIR(inode->i_mode))
ll_dir_clear_lsm_md(inode);
else
if (S_ISREG(inode->i_mode) && !is_bad_inode(inode))
LASSERT(list_empty(&lli->lli_agl_list));
/*
......@@ -1320,7 +1316,7 @@ static int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data,
op_data->op_handle = md.body->handle;
op_data->op_ioepoch = md.body->ioepoch;
ll_update_inode(inode, &md);
rc = ll_update_inode(inode, &md);
ptlrpc_req_finished(request);
return rc;
......@@ -1679,7 +1675,7 @@ void ll_inode_size_unlock(struct inode *inode)
mutex_unlock(&lli->lli_size_mutex);
}
void ll_update_inode(struct inode *inode, struct lustre_md *md)
int ll_update_inode(struct inode *inode, struct lustre_md *md)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct mdt_body *body = md->body;
......@@ -1697,8 +1693,13 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
lli->lli_maxbytes = MAX_LFS_FILESIZE;
}
if (S_ISDIR(inode->i_mode))
ll_update_lsm_md(inode, md);
if (S_ISDIR(inode->i_mode)) {
int rc;
rc = ll_update_lsm_md(inode, md);
if (rc)
return rc;
}
#ifdef CONFIG_FS_POSIX_ACL
if (body->valid & OBD_MD_FLACL) {
......@@ -1819,12 +1820,15 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
if (body->t_state & MS_RESTORE)
lli->lli_flags |= LLIF_FILE_RESTORING;
}
return 0;
}
void ll_read_inode2(struct inode *inode, void *opaque)
int ll_read_inode2(struct inode *inode, void *opaque)
{
struct lustre_md *md = opaque;
struct ll_inode_info *lli = ll_i2info(inode);
int rc;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
PFID(&lli->lli_fid), inode);
......@@ -1840,7 +1844,9 @@ void ll_read_inode2(struct inode *inode, void *opaque)
LTIME_S(inode->i_atime) = 0;
LTIME_S(inode->i_ctime) = 0;
inode->i_rdev = 0;
ll_update_inode(inode, md);
rc = ll_update_inode(inode, md);
if (rc)
return rc;
/* OIDEBUG(inode); */
......@@ -1861,6 +1867,8 @@ void ll_read_inode2(struct inode *inode, void *opaque)
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
}
return 0;
}
void ll_delete_inode(struct inode *inode)
......@@ -2127,7 +2135,9 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
goto cleanup;
if (*inode) {
ll_update_inode(*inode, &md);
rc = ll_update_inode(*inode, &md);
if (rc)
goto out;
} else {
LASSERT(sb);
......@@ -2146,7 +2156,7 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
*inode = ll_iget(sb, cl_fid_build_ino(&md.body->fid1,
sbi->ll_flags & LL_SBI_32BIT_API),
&md);
if (!*inode) {
if (IS_ERR(*inode)) {
#ifdef CONFIG_FS_POSIX_ACL
if (md.posix_acl) {
posix_acl_release(md.posix_acl);
......
......@@ -96,41 +96,46 @@ static int ll_set_inode(struct inode *inode, void *opaque)
return 0;
}
/*
* Get an inode by inode number (already instantiated by the intent lookup).
* Returns inode or NULL
/**
* Get an inode by inode number(@hash), which is already instantiated by
* the intent lookup).
*/
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *md)
{
struct inode *inode;
int rc = 0;
LASSERT(hash != 0);
inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
if (inode) {
if (inode->i_state & I_NEW) {
int rc = 0;
ll_read_inode2(inode, md);
if (S_ISREG(inode->i_mode) &&
!ll_i2info(inode)->lli_clob) {
CDEBUG(D_INODE,
"%s: apply lsm %p to inode " DFID ".\n",
ll_get_fsname(sb, NULL, 0), md->lsm,
PFID(ll_inode2fid(inode)));
rc = cl_file_inode_init(inode, md);
}
if (rc != 0) {
iget_failed(inode);
inode = NULL;
} else {
unlock_new_inode(inode);
}
} else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
ll_update_inode(inode, md);
CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p)\n",
PFID(&md->body->fid1), inode);
if (!inode)
return ERR_PTR(-ENOMEM);
if (inode->i_state & I_NEW) {
rc = ll_read_inode2(inode, md);
if (!rc && S_ISREG(inode->i_mode) &&
!ll_i2info(inode)->lli_clob) {
CDEBUG(D_INODE, "%s: apply lsm %p to inode "DFID"\n",
ll_get_fsname(sb, NULL, 0), md->lsm,
PFID(ll_inode2fid(inode)));
rc = cl_file_inode_init(inode, md);
}
if (rc) {
make_bad_inode(inode);
unlock_new_inode(inode);
iput(inode);
inode = ERR_PTR(rc);
} else {
unlock_new_inode(inode);
}
} else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
rc = ll_update_inode(inode, md);
CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p): rc = %d\n",
PFID(&md->body->fid1), inode, rc);
if (rc) {
make_bad_inode(inode);
iput(inode);
inode = ERR_PTR(rc);
}
}
return inode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment