From b1769f43f577a768e056677204ba6ee018a42e54 Mon Sep 17 00:00:00 2001 From: yury Date: Mon, 7 Aug 2006 17:07:45 +0000 Subject: [PATCH] - in llite and liblustre ll_prepare_md_op_data() zeroes out passed @op_data to avoid garbage in it in caases caller did not zero it out. All fid allocations saved in op_data->fid2 are done after ll_prepare_md_op_data(); - in lmv replace all on stac allocations of struct md_op_data by memory allocated ones; - in lmv fixed few memory leaks, cleanups. --- lustre/liblustre/dir.c | 2 +- lustre/liblustre/file.c | 2 + lustre/liblustre/namei.c | 12 +-- lustre/liblustre/super.c | 31 +++--- lustre/llite/dcache.c | 6 +- lustre/llite/dir.c | 6 +- lustre/llite/file.c | 13 ++- lustre/llite/llite_internal.h | 8 -- lustre/llite/llite_lib.c | 7 +- lustre/llite/namei.c | 52 +++++----- lustre/lmv/lmv_intent.c | 220 ++++++++++++++++++++++++++---------------- lustre/lmv/lmv_obd.c | 70 ++++++++------ 12 files changed, 251 insertions(+), 178 deletions(-) diff --git a/lustre/liblustre/dir.c b/lustre/liblustre/dir.c index e48a29a..8368c68 100644 --- a/lustre/liblustre/dir.c +++ b/lustre/liblustre/dir.c @@ -73,7 +73,7 @@ static int llu_dir_do_readpage(struct inode *inode, struct page *page) struct lustre_handle lockh; struct mdt_body *body; struct lookup_intent it = { .it_op = IT_READDIR }; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct obd_device *obddev = class_exp2obd(sbi->ll_md_exp); struct ldlm_res_id res_id = { .name = {fid_seq(&lli->lli_fid), diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c index a5190f4..877dafc 100644 --- a/lustre/liblustre/file.c +++ b/lustre/liblustre/file.c @@ -78,7 +78,9 @@ void llu_prepare_md_op_data(struct md_op_data *op_data, int namelen, int mode) { + LASSERT(op_data); LASSERT(i1); + memset(op_data, 0, sizeof(*op_data)); ll_i2gids(op_data->suppgids, i1, i2); op_data->fid1 = *ll_inode2fid(i1); diff --git a/lustre/liblustre/namei.c b/lustre/liblustre/namei.c index 977ecbb..8a50dbe 100644 --- a/lustre/liblustre/namei.c +++ b/lustre/liblustre/namei.c @@ -273,7 +273,7 @@ static int llu_pb_revalidate(struct pnode *pnode, int flags, } llu_prepare_md_op_data(&op_data, pnode->p_parent->p_base->pb_ino, - pb->pb_ino, pb->pb_name.name,pb->pb_name.len,0); + pb->pb_ino, pb->pb_name.name, pb->pb_name.len,0); rc = md_intent_lock(exp, &op_data, NULL, 0, it, flags, &req, llu_mdc_blocking_ast, @@ -424,7 +424,7 @@ struct inode *llu_inode_from_lock(struct ldlm_lock *lock) static int llu_lookup_it(struct inode *parent, struct pnode *pnode, struct lookup_intent *it, int flags) { - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct it_cb_data icbd; struct ptlrpc_request *req = NULL; struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; @@ -442,6 +442,10 @@ static int llu_lookup_it(struct inode *parent, struct pnode *pnode, icbd.icbd_child = pnode; icbd.icbd_parent = parent; + llu_prepare_md_op_data(&op_data, parent, NULL, + pnode->p_base->pb_name.name, + pnode->p_base->pb_name.len, flags); + /* allocate new fid for child */ if (it->it_op & IT_CREAT || (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) { @@ -455,10 +459,6 @@ static int llu_lookup_it(struct inode *parent, struct pnode *pnode, LBUG(); } } - llu_prepare_md_op_data(&op_data, parent, NULL, - pnode->p_base->pb_name.name, - pnode->p_base->pb_name.len, flags); - rc = md_intent_lock(llu_i2mdcexp(parent), &op_data, NULL, 0, it, flags, &req, llu_mdc_blocking_ast, LDLM_FL_CANCEL_ON_BLOCK); diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index e14344c..4c2702b 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -623,8 +623,8 @@ int llu_setattr_raw(struct inode *inode, struct iattr *attr) struct llu_sb_info *sbi = llu_i2sbi(inode); struct intnl_stat *st = llu_i2stat(inode); struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; int ia_valid = attr->ia_valid; + struct md_op_data op_data; int rc = 0; ENTRY; @@ -667,6 +667,7 @@ int llu_setattr_raw(struct inode *inode, struct iattr *attr) * inode ourselves so we can call obdo_from_inode() always. */ if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) { struct lustre_md md; + llu_prepare_md_op_data(&op_data, inode, NULL, NULL, 0, 0); rc = md_setattr(sbi->ll_md_exp, &op_data, @@ -849,7 +850,7 @@ static int llu_iop_symlink_raw(struct pnode *pno, const char *tgt) int len = qstr->len; struct ptlrpc_request *request = NULL; struct llu_sb_info *sbi = llu_i2sbi(dir); - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct lu_placement_hint hint = { .ph_pname = NULL, .ph_cname = qstr, @@ -862,13 +863,14 @@ static int llu_iop_symlink_raw(struct pnode *pno, const char *tgt) if (llu_i2stat(dir)->st_nlink >= EXT2_LINK_MAX) RETURN(err); + llu_prepare_md_op_data(&op_data, dir, NULL, name, len, 0); + /* allocate new fid */ err = llu_fid_md_alloc(sbi, &op_data.fid2, &hint); if (err) { CERROR("can't allocate new fid, rc %d\n", err); RETURN(err); } - llu_prepare_md_op_data(&op_data, dir, NULL, name, len, 0); err = md_create(sbi->ll_md_exp, &op_data, tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO, current->fsuid, current->fsgid, current->cap_effective, @@ -971,7 +973,7 @@ static int llu_iop_mknod_raw(struct pnode *pno, struct ptlrpc_request *request = NULL; struct inode *dir = pno->p_parent->p_base->pb_ino; struct llu_sb_info *sbi = llu_i2sbi(dir); - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int err = -EMLINK; struct lu_placement_hint hint = { .ph_pname = NULL, @@ -996,6 +998,10 @@ static int llu_iop_mknod_raw(struct pnode *pno, case S_IFBLK: case S_IFIFO: case S_IFSOCK: + llu_prepare_md_op_data(&op_data, dir, NULL, + pno->p_base->pb_name.name, + pno->p_base->pb_name.len, + 0); /* allocate new fid */ err = llu_fid_md_alloc(sbi, &op_data.fid2, &hint); if (err) { @@ -1003,10 +1009,6 @@ static int llu_iop_mknod_raw(struct pnode *pno, RETURN(err); } - llu_prepare_md_op_data(&op_data, dir, NULL, - pno->p_base->pb_name.name, - pno->p_base->pb_name.len, - 0); err = md_create(sbi->ll_md_exp, &op_data, NULL, 0, mode, current->fsuid, current->fsgid, current->cap_effective, dev, &request); @@ -1029,7 +1031,7 @@ static int llu_iop_link_raw(struct pnode *old, struct pnode *new) const char *name = new->p_base->pb_name.name; int namelen = new->p_base->pb_name.len; struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int rc; ENTRY; @@ -1056,7 +1058,7 @@ static int llu_iop_unlink_raw(struct pnode *pno) int len = qstr->len; struct inode *target = pno->p_base->pb_ino; struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int rc; ENTRY; @@ -1082,7 +1084,7 @@ static int llu_iop_rename_raw(struct pnode *old, struct pnode *new) const char *newname = new->p_base->pb_name.name; int newnamelen = new->p_base->pb_name.len; struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int rc; ENTRY; @@ -1225,7 +1227,7 @@ static int llu_iop_mkdir_raw(struct pnode *pno, mode_t mode) int len = qstr->len; struct ptlrpc_request *request = NULL; struct intnl_stat *st = llu_i2stat(dir); - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct lu_placement_hint hint = { .ph_pname = NULL, .ph_cname = qstr, @@ -1242,13 +1244,14 @@ static int llu_iop_mkdir_raw(struct pnode *pno, mode_t mode) if (st->st_nlink >= EXT2_LINK_MAX) RETURN(err); + llu_prepare_md_op_data(&op_data, dir, NULL, name, len, 0); + /* allocate new fid */ err = llu_fid_md_alloc(llu_i2sbi(dir), &op_data.fid2, &hint); if (err) { CERROR("can't allocate new fid, rc %d\n", err); RETURN(err); } - llu_prepare_md_op_data(&op_data, dir, NULL, name, len, 0); err = md_create(llu_i2sbi(dir)->ll_md_exp, &op_data, NULL, 0, mode, current->fsuid, current->fsgid, current->cap_effective, 0, &request); @@ -1264,7 +1267,7 @@ static int llu_iop_rmdir_raw(struct pnode *pno) const char *name = qstr->name; int len = qstr->len; struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int rc; ENTRY; diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index d0e890c..06207a7 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -281,7 +281,7 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, { int rc; struct it_cb_data icbd; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct ptlrpc_request *req = NULL; struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; struct obd_export *exp; @@ -310,8 +310,8 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, parent = de->d_parent->d_inode; - ll_prepare_md_op_data(&op_data, parent, NULL, de->d_name.name, - de->d_name.len, 0); + ll_prepare_md_op_data(&op_data, parent, de->d_inode, + de->d_name.name, de->d_name.len, 0); rc = md_intent_lock(exp, &op_data, NULL, 0, it, lookup_flags, &req, ll_md_blocking_ast, 0); diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index fd40adb..854e575 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -279,8 +279,8 @@ static struct page *ll_get_dir_page(struct inode *dir, __u32 hash, int exact, ll_inode2fid(dir), LDLM_IBITS, &policy, LCK_CR, &lockh); if (!rc) { struct lookup_intent it = { .it_op = IT_READDIR }; - struct md_op_data op_data = { { 0 } }; struct ptlrpc_request *request; + struct md_op_data op_data; ll_prepare_md_op_data(&op_data, dir, NULL, NULL, 0, 0); @@ -607,10 +607,10 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, return rc; } case LL_IOC_LOV_SETSTRIPE: { + struct lov_user_md lum, *lump = (struct lov_user_md *)arg; struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct iattr attr = { 0 }; - struct lov_user_md lum, *lump = (struct lov_user_md *)arg; int rc = 0; ll_prepare_md_op_data(&op_data, inode, diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 655e667..cbd2ca5 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -180,11 +180,11 @@ static int ll_intent_file_open(struct file *file, void *lmm, int lmmsize, struct lookup_intent *itp) { struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode); - struct lustre_handle lockh; - struct md_op_data op_data = { { 0 } }; struct dentry *parent = file->f_dentry->d_parent; const char *name = file->f_dentry->d_name.name; const int len = file->f_dentry->d_name.len; + struct lustre_handle lockh; + struct md_op_data op_data; int rc; if (!parent) @@ -198,13 +198,12 @@ static int ll_intent_file_open(struct file *file, void *lmm, ll_md_blocking_ast, NULL, 0); if (rc < 0) { CERROR("lock enqueue: err: %d\n", rc); - GOTO(out, rc); + RETURN(rc); } rc = ll_prep_inode(&file->f_dentry->d_inode, - (struct ptlrpc_request *)itp->d.lustre.it_data, 1, - NULL); -out: + (struct ptlrpc_request *)itp->d.lustre.it_data, + 1, NULL); RETURN(rc); } @@ -1922,9 +1921,9 @@ int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock) int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it) { struct lookup_intent oit = { .it_op = IT_GETATTR }; - struct md_op_data op_data = { { 0 } }; struct inode *inode = dentry->d_inode; struct ptlrpc_request *req = NULL; + struct md_op_data op_data; struct ll_inode_info *lli; struct ll_sb_info *sbi; int rc; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 5da3837..c41502f 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -15,14 +15,6 @@ #include #include /* for s2sbi */ -/* -struct lustre_intent_data { - __u64 it_lock_handle[2]; - __u32 it_disposition; - __u32 it_status; - __u32 it_lock_mode; - }; */ - #define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0") #if (LUSTRE_KERNEL_VERSION < 46) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index e17ec1c..29cbd7b 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -901,8 +901,8 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) struct lov_stripe_md *lsm = lli->lli_smd; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; int ia_valid = attr->ia_valid; + struct md_op_data op_data; int rc = 0; ENTRY; @@ -955,6 +955,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) * inode ourselves so we can call obdo_from_inode() always. */ if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) { struct lustre_md md; + ll_prepare_md_op_data(&op_data, inode, NULL, NULL, 0, 0); rc = md_setattr(sbi->ll_md_exp, &op_data, @@ -1442,10 +1443,10 @@ int ll_iocontrol(struct inode *inode, struct file *file, RETURN(put_user(flags, (int *)arg)); } case EXT3_IOC_SETFLAGS: { - struct md_op_data op_data = { { 0 } }; + struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; struct ll_iattr_struct attr; + struct md_op_data op_data; struct obdo *oa; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; if (get_user(flags, (int *)arg)) RETURN(-EFAULT); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index cb95dfe..7d91ada 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -197,6 +197,12 @@ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2) } } +/* + * this function prepares md_op_data hint for passing ot down to MD stack. + * + * Note: it zeroes @op_data out before doing anything else, so all additional + * initializations of @op_data should be done after it. + */ void ll_prepare_md_op_data(struct md_op_data *op_data, struct inode *i1, struct inode *i2, const char *name, int namelen, int mode) @@ -204,6 +210,7 @@ void ll_prepare_md_op_data(struct md_op_data *op_data, struct inode *i1, LASSERT(i1 != NULL); LASSERT(op_data != NULL); + memset(op_data, 0, sizeof(*op_data)); ll_i2gids(op_data->suppgids, i1, i2); op_data->fid1 = ll_i2info(i1)->lli_fid; @@ -362,11 +369,11 @@ static int lookup_it_finish(struct ptlrpc_request *request, int offset, static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, struct lookup_intent *it, int lookup_flags) { + struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; struct dentry *save = dentry, *retval; - struct md_op_data op_data = { { 0 } }; - struct it_cb_data icbd; struct ptlrpc_request *req = NULL; - struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; + struct md_op_data op_data; + struct it_cb_data icbd; int rc; ENTRY; @@ -385,6 +392,10 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, icbd.icbd_childp = &dentry; icbd.icbd_parent = parent; + /* prepare operatoin hint first */ + ll_prepare_md_op_data(&op_data, parent, NULL, dentry->d_name.name, + dentry->d_name.len, lookup_flags); + /* allocate new fid for child */ if (it->it_op & IT_CREAT || (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) { @@ -399,9 +410,6 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, } } - ll_prepare_md_op_data(&op_data, parent, NULL, dentry->d_name.name, - dentry->d_name.len, lookup_flags); - it->it_create_mode &= ~current->fs->umask; rc = md_intent_lock(ll_i2mdexp(parent), &op_data, NULL, 0, it, @@ -546,7 +554,7 @@ static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode, struct ptlrpc_request *request = NULL; struct inode *inode = NULL; struct ll_sb_info *sbi = ll_i2sbi(dir); - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct lu_placement_hint hint = { .ph_pname = NULL, .ph_cname = name, @@ -569,11 +577,11 @@ static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode, case S_IFBLK: case S_IFIFO: case S_IFSOCK: + ll_prepare_md_op_data(&op_data, dir, NULL, name->name, + name->len, 0); err = ll_fid_md_alloc(sbi, &op_data.fid2, &hint); if (err) break; - ll_prepare_md_op_data(&op_data, dir, NULL, name->name, - name->len, 0); err = md_create(sbi->ll_md_exp, &op_data, NULL, 0, mode, current->fsuid, current->fsgid, current->cap_effective, rdev, &request); @@ -622,8 +630,8 @@ static int ll_symlink_generic(struct inode *dir, struct dentry *dchild, struct ptlrpc_request *request = NULL; struct ll_sb_info *sbi = ll_i2sbi(dir); - struct md_op_data op_data = { { 0 } }; struct inode *inode = NULL; + struct md_op_data op_data; int err; ENTRY; @@ -631,6 +639,9 @@ static int ll_symlink_generic(struct inode *dir, struct dentry *dchild, name->len, name->name, dir->i_ino, dir->i_generation, dir, tgt); + ll_prepare_md_op_data(&op_data, dir, NULL, + name->name, name->len, 0); + /* allocate new fid */ err = ll_fid_md_alloc(ll_i2sbi(dir), &op_data.fid2, &hint); if (err) { @@ -638,9 +649,6 @@ static int ll_symlink_generic(struct inode *dir, struct dentry *dchild, LBUG(); } - ll_prepare_md_op_data(&op_data, dir, NULL, - name->name, name->len, 0); - err = md_create(sbi->ll_md_exp, &op_data, tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO, current->fsuid, current->fsgid, current->cap_effective, @@ -663,10 +671,10 @@ static int ll_symlink_generic(struct inode *dir, struct dentry *dchild, static int ll_link_generic(struct inode *src, struct inode *dir, struct qstr *name) { + struct ll_sb_info *sbi = ll_i2sbi(dir); struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int err; - struct ll_sb_info *sbi = ll_i2sbi(dir); ENTRY; CDEBUG(D_VFSTRACE, @@ -694,8 +702,8 @@ static int ll_mkdir_generic(struct inode *dir, struct qstr *name, int mode, .ph_opc = LUSTRE_OPC_MKDIR }; struct ptlrpc_request *request = NULL; struct ll_sb_info *sbi = ll_i2sbi(dir); - struct md_op_data op_data = { { 0 } }; struct inode *inode = NULL; + struct md_op_data op_data; int err; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", @@ -703,6 +711,9 @@ static int ll_mkdir_generic(struct inode *dir, struct qstr *name, int mode, mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR; + ll_prepare_md_op_data(&op_data, dir, NULL, + name->name, name->len, 0); + /* allocate new fid */ err = ll_fid_md_alloc(ll_i2sbi(dir), &op_data.fid2, &hint); if (err) { @@ -710,9 +721,6 @@ static int ll_mkdir_generic(struct inode *dir, struct qstr *name, int mode, LBUG(); } - ll_prepare_md_op_data(&op_data, dir, NULL, - name->name, name->len, 0); - err = md_create(sbi->ll_md_exp, &op_data, NULL, 0, mode, current->fsuid, current->fsgid, current->cap_effective, 0, &request); @@ -734,7 +742,7 @@ static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent, struct qstr *name) { struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; struct dentry *dentry; int rc; ENTRY; @@ -839,7 +847,7 @@ int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir) static int ll_unlink_generic(struct inode * dir, struct qstr *name) { struct ptlrpc_request *request = NULL; - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int rc; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", @@ -865,7 +873,7 @@ static int ll_rename_generic(struct inode *src, struct qstr *src_name, { struct ptlrpc_request *request = NULL; struct ll_sb_info *sbi = ll_i2sbi(src); - struct md_op_data op_data = { { 0 } }; + struct md_op_data op_data; int err; ENTRY; CDEBUG(D_VFSTRACE,"VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s," diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 88ed709..e0a8cf2 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -59,12 +59,12 @@ int lmv_intent_remote(struct obd_export *exp, void *lmm, ldlm_blocking_callback cb_blocking, int extra_lock_flags) { - struct md_op_data op_data = { { 0 } }; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct ptlrpc_request *req = NULL; struct mdt_body *body = NULL; struct lustre_handle plock; + struct md_op_data *op_data; struct lu_fid nid; int pmode, i, rc = 0; ENTRY; @@ -100,29 +100,40 @@ int lmv_intent_remote(struct obd_export *exp, void *lmm, nid = body->fid1; it->d.lustre.it_disposition &= ~DISP_ENQ_COMPLETE; - op_data.fid1 = nid; + + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + GOTO(out, rc = -ENOMEM); + + op_data->fid1 = nid; i = lmv_fld_lookup(obd, &nid); if (i < 0) RETURN(i); - rc = md_intent_lock(lmv->tgts[i].ltd_exp, &op_data, + rc = md_intent_lock(lmv->tgts[i].ltd_exp, op_data, lmm, lmmsize, it, flags, &req, cb_blocking, extra_lock_flags); - /*llite needs LOOKUP lock to track dentry revocation in order to + /* + * llite needs LOOKUP lock to track dentry revocation in order to * maintain dcache consistency. Thus drop UPDATE lock here and put - * LOOKUP in request. */ + * LOOKUP in request. + */ if (rc == 0) { lmv_drop_intent_lock(it); memcpy(&it->d.lustre.it_lock_handle, &plock, sizeof(plock)); it->d.lustre.it_lock_mode = pmode; - } else if (pmode) { - ldlm_lock_decref(&plock, pmode); } + OBD_FREE_PTR(op_data); + EXIT; +out: + if (pmode) + ldlm_lock_decref(&plock, pmode); + ptlrpc_req_finished(*reqp); *reqp = req; - RETURN(rc); + return rc; } int lmv_intent_open(struct obd_export *exp, struct lu_fid *pid, @@ -132,16 +143,20 @@ int lmv_intent_open(struct obd_export *exp, struct lu_fid *pid, ldlm_blocking_callback cb_blocking, int extra_lock_flags) { - struct md_op_data op_data = { { 0 } }; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct mdt_body *body = NULL; + struct md_op_data *op_data; + struct lmv_stripe_md *mea; struct lu_fid rpid = *pid; int rc, mds, loop = 0; struct lmv_obj *obj; - struct lmv_stripe_md *mea; ENTRY; + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + RETURN(-ENOMEM); + /* IT_OPEN is intended to open (and create, possible) an object. Parent * (pid) may be splitted dir */ @@ -149,7 +164,7 @@ repeat: LASSERT(++loop <= 2); mds = lmv_fld_lookup(obd, &rpid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); obj = lmv_obj_grab(obd, &rpid); if (obj) { /* directory is already splitted, so we have to forward @@ -163,15 +178,15 @@ repeat: lmv_obj_put(obj); } - op_data.fid1 = rpid; + op_data->fid1 = rpid; if (cid) - op_data.fid2 = *cid; - op_data.name = name; - op_data.namelen = len; + op_data->fid2 = *cid; + op_data->name = name; + op_data->namelen = len; //mds = lmv_fld_lookup(obd, &rpid); - rc = md_intent_lock(lmv->tgts[mds].ltd_exp, &op_data, + rc = md_intent_lock(lmv->tgts[mds].ltd_exp, op_data, lmm, lmmsize, it, flags, reqp, cb_blocking, extra_lock_flags); if (rc == -ERESTART) { @@ -181,11 +196,12 @@ repeat: rc = lmv_handle_split(exp, &rpid); if (rc == 0) { ptlrpc_req_finished(*reqp); + memset(op_data, 0, sizeof(*op_data)); goto repeat; } } if (rc != 0) - RETURN(rc); + GOTO(out_free_op_data, rc); /* okay, MDS has returned success. Probably name has been resolved in * remote inode */ @@ -203,7 +219,7 @@ repeat: CDEBUG(D_OTHER, "can't handle remote %s: dir "DFID3"("DFID3"):" "%*s: %d\n", LL_IT2STR(it), PFID3(pid), PFID3(&rpid), len, name, rc); - RETURN(rc); + GOTO(out_free_op_data, rc); } /* @@ -213,7 +229,7 @@ repeat: if ((it->d.lustre.it_disposition & DISP_LOOKUP_NEG) && !(it->d.lustre.it_disposition & DISP_OPEN_CREATE) && !(it->d.lustre.it_disposition & DISP_OPEN_OPEN)) - RETURN(0); + GOTO(out_free_op_data, rc = 0); /* caller may use attrs MDS returns on IT_OPEN lock request so, we have * to update them for splitted dir */ @@ -222,7 +238,7 @@ repeat: /* could not find object, FID is not present in response. */ if (!(body->valid & OBD_MD_FLID)) - RETURN(0); + GOTO(out_free_op_data, rc = 0); cid = &body->fid1; obj = lmv_obj_grab(obd, cid); @@ -230,7 +246,7 @@ repeat: /* wow! this is splitted dir, we'd like to handle it */ obj = lmv_obj_create(exp, &body->fid1, mea); if (IS_ERR(obj)) - RETURN(PTR_ERR(obj)); + GOTO(out_free_op_data, rc = (int)PTR_ERR(obj)); } if (obj) { @@ -248,7 +264,10 @@ repeat: if (obj) lmv_obj_put(obj); - RETURN(rc); + EXIT; +out_free_op_data: + OBD_FREE_PTR(op_data); + return rc; } int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, @@ -259,22 +278,26 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, int extra_lock_flags) { struct lmv_obj *obj = NULL, *obj2 = NULL; - struct md_op_data op_data = { { 0 } }; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct mdt_body *body = NULL; + struct md_op_data *op_data; struct lu_fid rpid = *pid; struct lmv_stripe_md *mea; int rc = 0, mds; ENTRY; + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + RETURN(-ENOMEM); + if (cid) { /* caller wants to revalidate attrs of obj we have to revalidate * slaves if requested object is splitted directory */ CDEBUG(D_OTHER, "revalidate attrs for "DFID3"\n", PFID3(cid)); mds = lmv_fld_lookup(obd, cid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); #if 0 obj = lmv_obj_grab(obd, cid); if (obj) { @@ -284,18 +307,18 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, rpid = obj->lo_inodes[mds].li_fid; mds = lmv_fld_lookup(obd, &rpid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); } lmv_obj_put(obj); } #endif - op_data.fid2 = *cid; + op_data->fid2 = *cid; } else { CDEBUG(D_OTHER, "INTENT getattr for %*s on "DFID3"\n", len, name, PFID3(pid)); mds = lmv_fld_lookup(obd, pid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); obj = lmv_obj_grab(obd, pid); if (obj && len) { /* directory is already splitted. calculate mds */ @@ -310,24 +333,26 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, } } - op_data.fid1 = rpid; - op_data.name = name; - op_data.namelen = len; + op_data->fid1 = rpid; + op_data->name = name; + op_data->namelen = len; /* the same about fid returning. */ - rc = md_intent_lock(lmv->tgts[mds].ltd_exp, &op_data, lmm, + rc = md_intent_lock(lmv->tgts[mds].ltd_exp, op_data, lmm, lmmsize, it, flags, reqp, cb_blocking, extra_lock_flags); if (rc < 0) - RETURN(rc); + GOTO(out_free_op_data, rc); if (obj && rc > 0) { - /* this is splitted dir. In order to optimize things a - * bit, we consider obj valid updating missing parts. + /* + * this is splitted dir. In order to optimize things a bit, we + * consider obj valid updating missing parts. - * FIXME: do we need to return any lock here? It would - * be fine if we don't. this means that nobody should - * use UPDATE lock to notify about object * removal */ + * FIXME: do we need to return any lock here? It would be fine + * if we don't. this means that nobody should use UPDATE lock to + * notify about object * removal. + */ CDEBUG(D_OTHER, "revalidate slaves for "DFID3", rc %d\n", PFID3(cid), rc); @@ -335,32 +360,34 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, LASSERT(cid != 0); rc = lmv_revalidate_slaves(exp, reqp, cid, it, rc, cb_blocking, extra_lock_flags); - RETURN(rc); + GOTO(out_free_op_data, rc); } if (*reqp == NULL) - RETURN(rc); + GOTO(out_free_op_data, rc); - /* okay, MDS has returned success. probably name has been - * resolved in remote inode */ + /* + * okay, MDS has returned success. probably name has been resolved in + * remote inode. + */ rc = lmv_intent_remote(exp, lmm, lmmsize, it, flags, reqp, cb_blocking, extra_lock_flags); if (rc < 0) - RETURN(rc); + GOTO(out_free_op_data, rc); /* * nothing is found, do not access body->fid1 as it is zero and thus * pointless. */ if (it->d.lustre.it_disposition & DISP_LOOKUP_NEG) - RETURN(0); + GOTO(out_free_op_data, rc = 0); body = lustre_msg_buf((*reqp)->rq_repmsg, 1, sizeof(*body)); LASSERT(body != NULL); /* could not find object, FID is not present in response. */ if (!(body->valid & OBD_MD_FLID)) - RETURN(0); + GOTO(out_free_op_data, rc = 0); cid = &body->fid1; obj2 = lmv_obj_grab(obd, cid); @@ -372,7 +399,7 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, obj2 = lmv_obj_create(exp, &body->fid1, mea); if (IS_ERR(obj2)) - RETURN(PTR_ERR(obj2)); + GOTO(out_free_op_data, rc = (int)PTR_ERR(obj2)); } if (obj2) { @@ -384,7 +411,11 @@ int lmv_intent_getattr(struct obd_export *exp, struct lu_fid *pid, cb_blocking, extra_lock_flags); lmv_obj_put(obj2); } - RETURN(rc); + + EXIT; +out_free_op_data: + OBD_FREE_PTR(op_data); + return rc; } void lmv_update_body(struct mdt_body *body, struct lmv_inode *lino) @@ -400,6 +431,7 @@ int lmv_lookup_slaves(struct obd_export *exp, struct ptlrpc_request **reqp) struct lmv_obd *lmv = &obd->u.lmv; struct mdt_body *body = NULL; struct lustre_handle *lockh; + struct md_op_data *op_data; struct ldlm_lock *lock; struct mdt_body *body2; struct lmv_obj *obj; @@ -429,11 +461,14 @@ int lmv_lookup_slaves(struct obd_export *exp, struct ptlrpc_request **reqp) CDEBUG(D_OTHER, "lookup slaves for "DFID3"\n", PFID3(&body->fid1)); + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + RETURN(-ENOMEM); + lmv_obj_lock(obj); for (i = 0; i < obj->lo_objcount; i++) { struct lu_fid fid = obj->lo_inodes[i].li_fid; - struct md_op_data op_data = { { 0 } }; struct ptlrpc_request *req = NULL; struct lookup_intent it; int mds; @@ -448,13 +483,14 @@ int lmv_lookup_slaves(struct obd_export *exp, struct ptlrpc_request **reqp) memset(&it, 0, sizeof(it)); it.it_op = IT_GETATTR; - op_data.fid1 = fid; - op_data.fid2 = fid; + memset(op_data, 0, sizeof(*op_data)); + op_data->fid1 = fid; + op_data->fid2 = fid; mds = lmv_fld_lookup(obd, &fid); if (mds < 0) GOTO(cleanup, rc = mds); - rc = md_intent_lock(lmv->tgts[mds].ltd_exp, &op_data, + rc = md_intent_lock(lmv->tgts[mds].ltd_exp, op_data, NULL, 0, &it, 0, &req, lmv_blocking_ast, 0); @@ -496,6 +532,7 @@ release_lock: EXIT; cleanup: + OBD_FREE_PTR(op_data); lmv_obj_unlock(obj); lmv_obj_put(obj); return rc; @@ -508,16 +545,20 @@ int lmv_intent_lookup(struct obd_export *exp, struct lu_fid *pid, ldlm_blocking_callback cb_blocking, int extra_lock_flags) { - struct md_op_data op_data = { { 0 } }; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; struct mdt_body *body = NULL; struct lu_fid rpid = *pid; - struct lmv_obj *obj; + struct md_op_data *op_data; struct lmv_stripe_md *mea; int rc, mds, loop = 0; + struct lmv_obj *obj; ENTRY; + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + RETURN(-ENOMEM); + /* * IT_LOOKUP is intended to produce name -> fid resolving (let's call * this lookup below) or to confirm requested resolving is still valid @@ -539,23 +580,24 @@ int lmv_intent_lookup(struct obd_export *exp, struct lu_fid *pid, } mds = lmv_fld_lookup(obd, &rpid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); CDEBUG(D_OTHER, "revalidate lookup for "DFID3" to %d MDS\n", PFID3(cid), mds); - op_data.fid2 = *cid; + op_data->fid2 = *cid; } else { mds = lmv_fld_lookup(obd, pid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); repeat: LASSERT(++loop <= 2); - /* this is lookup. during lookup we have to update all the + /* + * this is lookup. during lookup we have to update all the * attributes, because returned values will be put in struct - * inode */ - + * inode. + */ obj = lmv_obj_grab(obd, pid); if (obj) { if (len) { @@ -565,37 +607,39 @@ repeat: rpid = obj->lo_inodes[mds].li_fid; mds = lmv_fld_lookup(obd, &rpid); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data, rc = mds); } lmv_obj_put(obj); } - memset(&op_data.fid2, 0, sizeof op_data.fid2); + memset(&op_data->fid2, 0, sizeof(op_data->fid2)); } - op_data.fid1 = rpid; - op_data.name = name; - op_data.namelen = len; + op_data->fid1 = rpid; + op_data->name = name; + op_data->namelen = len; - rc = md_intent_lock(lmv->tgts[mds].ltd_exp, &op_data, lmm, lmmsize, + rc = md_intent_lock(lmv->tgts[mds].ltd_exp, op_data, lmm, lmmsize, it, flags, reqp, cb_blocking, extra_lock_flags); if (rc > 0) { LASSERT(cid != 0); - RETURN(rc); + GOTO(out_free_op_data, rc); } if (rc > 0) { - /* very interesting. it seems object is still valid but for some - * reason llite calls lookup, not revalidate */ + /* + * very interesting. it seems object is still valid but for some + * reason llite calls lookup, not revalidate. + */ CDEBUG(D_OTHER, "lookup for "DFID3" and data should be uptodate\n", PFID3(&rpid)); LASSERT(*reqp == NULL); - RETURN(rc); + GOTO(out_free_op_data, rc); } if (rc == 0 && *reqp == NULL) { /* once again, we're asked for lookup, not revalidate */ CDEBUG(D_OTHER, "lookup for "DFID3" and data should be uptodate\n", PFID3(&rpid)); - RETURN(rc); + GOTO(out_free_op_data, rc); } if (rc == -ERESTART) { @@ -607,13 +651,14 @@ repeat: obj = lmv_obj_create(exp, &rpid, NULL); if (IS_ERR(obj)) - RETURN(PTR_ERR(obj)); + GOTO(out_free_op_data, rc = (int)PTR_ERR(obj)); lmv_obj_put(obj); + memset(op_data, 0, sizeof(*op_data)); goto repeat; } if (rc < 0) - RETURN(rc); + GOTO(out_free_op_data, rc); /* okay, MDS has returned success. Probably name has been resolved in * remote inode. */ @@ -630,12 +675,15 @@ repeat: if (!obj) { obj = lmv_obj_create(exp, &body->fid1, mea); if (IS_ERR(obj)) - RETURN(PTR_ERR(obj)); + GOTO(out_free_op_data, rc = (int)PTR_ERR(obj)); } lmv_obj_put(obj); } - RETURN(rc); + EXIT; +out_free_op_data: + OBD_FREE_PTR(op_data); + return rc; } int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data, @@ -692,6 +740,7 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct ptlrpc_request **reqp, struct ptlrpc_request *mreq = *reqp; struct lmv_obd *lmv = &obd->u.lmv; struct lustre_handle master_lockh; + struct md_op_data *op_data; struct ldlm_lock *lock; unsigned long size = 0; struct mdt_body *body; @@ -700,6 +749,10 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct ptlrpc_request **reqp, int i, mds, rc = 0; ENTRY; + OBD_ALLOC_PTR(op_data); + if (op_data == NULL) + RETURN(-ENOMEM); + /* we have to loop over the subobjects, check validity and update them * from MDSs if needed. it's very useful that we need not to update all * the fields. say, common fields (that are equal on all the subojects @@ -714,7 +767,6 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct ptlrpc_request **reqp, for (i = 0; i < obj->lo_objcount; i++) { struct lu_fid fid = obj->lo_inodes[i].li_fid; - struct md_op_data op_data = { { 0 } }; struct lustre_handle *lockh = NULL; struct ptlrpc_request *req = NULL; ldlm_blocking_callback cb; @@ -724,6 +776,7 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct ptlrpc_request **reqp, CDEBUG(D_OTHER, "revalidate subobj "DFID3"\n", PFID3(&fid)); + memset(op_data, 0, sizeof(*op_data)); memset(&it, 0, sizeof(it)); it.it_op = IT_GETATTR; @@ -750,14 +803,14 @@ int lmv_revalidate_slaves(struct obd_export *exp, struct ptlrpc_request **reqp, cb = cb_blocking; } - op_data.fid1 = fid; - op_data.fid2 = fid; + op_data->fid1 = fid; + op_data->fid2 = fid; /* is obj valid? */ mds = lmv_fld_lookup(obd, &fid); if (mds < 0) - RETURN(mds); - rc = md_intent_lock(lmv->tgts[mds].ltd_exp, &op_data, + GOTO(out_free_op_data, rc = mds); + rc = md_intent_lock(lmv->tgts[mds].ltd_exp, op_data, NULL, 0, &it, 0, &req, cb, extra_lock_flags); lockh = (struct lustre_handle *) &it.d.lustre.it_lock_handle; if (rc > 0 && req == NULL) { @@ -826,10 +879,11 @@ release_lock: body->size = size; if (mreq == NULL) { - /* very important to maintain mds num the - * same because of revalidation. mreq == NULL means that - * caller has no reply and the only attr we can return - * is size */ + /* + * very important to maintain mds num the same because + * of revalidation. mreq == NULL means that caller has + * no reply and the only attr we can return is size. + */ body->valid = OBD_MD_FLSIZE; // body->mds = lmv_fld_lookup(obd, &obj->lo_fid); } @@ -851,5 +905,7 @@ release_lock: cleanup: lmv_obj_unlock(obj); lmv_obj_put(obj); +out_free_op_data: + OBD_FREE_PTR(op_data); return rc; } diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 36855fc..81d55a5 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1086,7 +1086,8 @@ static int lmv_change_cbdata(struct obd_export *exp, RETURN(0); } -static int lmv_close(struct obd_export *exp, struct md_op_data *op_data, +static int lmv_close(struct obd_export *exp, + struct md_op_data *op_data, struct obd_client_handle *och, struct ptlrpc_request **request) { @@ -1255,10 +1256,10 @@ lmv_enqueue_slaves(struct obd_export *exp, int locktype, struct lmv_obd *lmv = &obd->u.lmv; struct lmv_stripe_md *mea = op_data->mea1; struct md_op_data *op_data2; - int i, rc, mds; + int i, rc = 0, mds; ENTRY; - OBD_ALLOC(op_data2, sizeof(*op_data2)); + OBD_ALLOC_PTR(op_data2); if (op_data2 == NULL) RETURN(-ENOMEM); @@ -1268,7 +1269,7 @@ lmv_enqueue_slaves(struct obd_export *exp, int locktype, op_data2->fid1 = mea->mea_ids[i]; mds = lmv_fld_lookup(obd, &op_data2->fid1); if (mds < 0) - RETURN(mds); + GOTO(cleanup, rc = mds); if (lmv->tgts[mds].ltd_exp == NULL) continue; @@ -1291,16 +1292,17 @@ lmv_enqueue_slaves(struct obd_export *exp, int locktype, GOTO(cleanup, rc = it->d.lustre.it_status); } - OBD_FREE(op_data2, sizeof(*op_data2)); - RETURN(0); + EXIT; cleanup: - OBD_FREE(op_data2, sizeof(*op_data2)); - - /* drop all taken locks */ - while (--i >= 0) { - if (lockh[i].cookie) - ldlm_lock_decref(lockh + i, lockmode); - lockh[i].cookie = 0; + OBD_FREE_PTR(op_data2); + + if (rc != 0) { + /* drop all taken locks */ + while (--i >= 0) { + if (lockh[i].cookie) + ldlm_lock_decref(lockh + i, lockmode); + lockh[i].cookie = 0; + } } return rc; } @@ -1316,9 +1318,9 @@ lmv_enqueue_remote(struct obd_export *exp, int lock_type, struct ptlrpc_request *req = it->d.lustre.it_data; struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; - struct lustre_handle plock; - struct md_op_data rdata; struct mdt_body *body = NULL; + struct lustre_handle plock; + struct md_op_data *rdata; int i, rc = 0, pmode; ENTRY; @@ -1338,23 +1340,29 @@ lmv_enqueue_remote(struct obd_export *exp, int lock_type, it->d.lustre.it_lock_mode = 0; it->d.lustre.it_data = NULL; - memcpy(&rdata, op_data, sizeof(rdata)); - rdata.fid1 = body->fid1; - rdata.name = NULL; - rdata.namelen = 0; + OBD_ALLOC_PTR(rdata); + if (rdata == NULL) + RETURN(-ENOMEM); + rdata->fid1 = body->fid1; + rdata->name = NULL; + rdata->namelen = 0; it->d.lustre.it_disposition &= ~DISP_ENQ_COMPLETE; ptlrpc_req_finished(req); - i = lmv_fld_lookup(obd, &rdata.fid1); + i = lmv_fld_lookup(obd, &rdata->fid1); if (i < 0) - RETURN(i); + GOTO(out_free_rdata, rc = i); rc = md_enqueue(lmv->tgts[i].ltd_exp, - lock_type, it, lock_mode, &rdata, lockh, lmm, + lock_type, it, lock_mode, rdata, lockh, lmm, lmmsize, cb_compl, cb_blocking, cb_data, extra_lock_flags); ldlm_lock_decref(&plock, pmode); - RETURN(rc); + + EXIT; +out_free_rdata: + OBD_FREE_PTR(rdata); + return rc; } static int @@ -1834,7 +1842,8 @@ static int lmv_readpage(struct obd_export *exp, struct lu_fid *fid, RETURN(rc); } -static int lmv_unlink_slaves(struct obd_export *exp, struct md_op_data *op_data, +static int lmv_unlink_slaves(struct obd_export *exp, + struct md_op_data *op_data, struct ptlrpc_request **req) { struct obd_device *obd = exp->exp_obd; @@ -1844,7 +1853,7 @@ static int lmv_unlink_slaves(struct obd_export *exp, struct md_op_data *op_data, int i, mds, rc = 0; ENTRY; - OBD_ALLOC(op_data2, sizeof(*op_data2)); + OBD_ALLOC_PTR(op_data2); if (op_data2 == NULL) RETURN(-ENOMEM); @@ -1856,7 +1865,7 @@ static int lmv_unlink_slaves(struct obd_export *exp, struct md_op_data *op_data, mds = lmv_fld_lookup(obd, &op_data2->fid1); if (mds < 0) - RETURN(mds); + GOTO(out_free_op_data2, rc = mds); if (lmv->tgts[mds].ltd_exp == NULL) continue; @@ -1871,10 +1880,13 @@ static int lmv_unlink_slaves(struct obd_export *exp, struct md_op_data *op_data, *req = NULL; } if (rc) - RETURN(rc); + GOTO(out_free_op_data2, rc); } - OBD_FREE(op_data2, sizeof(*op_data2)); - RETURN(rc); + + EXIT; +out_free_op_data2: + OBD_FREE_PTR(op_data2); + return rc; } static int lmv_unlink(struct obd_export *exp, struct md_op_data *op_data, -- 1.8.3.1