diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/llite/statahead.c')
-rw-r--r-- | drivers/staging/lustre/lustre/llite/statahead.c | 94 |
1 files changed, 36 insertions, 58 deletions
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index f1ee17f9ec0d..fb7c315b33cb 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -79,6 +79,8 @@ struct sa_entry { struct inode *se_inode; /* entry name */ struct qstr se_qstr; + /* entry fid */ + struct lu_fid se_fid; }; static unsigned int sai_generation; @@ -169,7 +171,7 @@ static inline int is_omitted_entry(struct ll_statahead_info *sai, __u64 index) /* allocate sa_entry and hash it to allow scanner process to find it */ static struct sa_entry * sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index, - const char *name, int len) + const char *name, int len, const struct lu_fid *fid) { struct ll_inode_info *lli; struct sa_entry *entry; @@ -194,6 +196,7 @@ sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index, entry->se_qstr.hash = full_name_hash(parent, name, len); entry->se_qstr.len = len; entry->se_qstr.name = dname; + entry->se_fid = *fid; lli = ll_i2info(sai->sai_dentry->d_inode); spin_lock(&lli->lli_sa_lock); @@ -566,24 +569,8 @@ static void sa_instantiate(struct ll_statahead_info *sai, } child = entry->se_inode; - if (!child) { - /* - * lookup. - */ - LASSERT(fid_is_zero(&minfo->mi_data.op_fid2)); - - /* XXX: No fid in reply, this is probably cross-ref case. - * SA can't handle it yet. - */ - if (body->mbo_valid & OBD_MD_MDS) { - rc = -EAGAIN; - goto out; - } - } else { - /* - * revalidate. - */ - /* unlinked and re-created with the same name */ + if (child) { + /* revalidate; unlinked and re-created with the same name */ if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->mbo_fid1))) { entry->se_inode = NULL; iput(child); @@ -720,50 +707,42 @@ static int ll_statahead_interpret(struct ptlrpc_request *req, } /* finish async stat RPC arguments */ -static void sa_fini_data(struct md_enqueue_info *minfo, - struct ldlm_enqueue_info *einfo) +static void sa_fini_data(struct md_enqueue_info *minfo) { - LASSERT(minfo && einfo); iput(minfo->mi_dir); kfree(minfo); - kfree(einfo); } /** * prepare arguments for async stat RPC. */ -static int sa_prep_data(struct inode *dir, struct inode *child, - struct sa_entry *entry, struct md_enqueue_info **pmi, - struct ldlm_enqueue_info **pei) +static struct md_enqueue_info * +sa_prep_data(struct inode *dir, struct inode *child, struct sa_entry *entry) { - const struct qstr *qstr = &entry->se_qstr; struct md_enqueue_info *minfo; struct ldlm_enqueue_info *einfo; struct md_op_data *op_data; - einfo = kzalloc(sizeof(*einfo), GFP_NOFS); - if (!einfo) - return -ENOMEM; - minfo = kzalloc(sizeof(*minfo), GFP_NOFS); - if (!minfo) { - kfree(einfo); - return -ENOMEM; - } + if (!minfo) + return ERR_PTR(-ENOMEM); - op_data = ll_prep_md_op_data(&minfo->mi_data, dir, child, qstr->name, - qstr->len, 0, LUSTRE_OPC_ANY, NULL); + op_data = ll_prep_md_op_data(&minfo->mi_data, dir, child, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) { - kfree(einfo); kfree(minfo); - return PTR_ERR(op_data); + return (struct md_enqueue_info *)op_data; } + if (!child) + op_data->op_fid2 = entry->se_fid; + minfo->mi_it.it_op = IT_GETATTR; minfo->mi_dir = igrab(dir); minfo->mi_cb = ll_statahead_interpret; minfo->mi_cbdata = entry; + einfo = &minfo->mi_einfo; einfo->ei_type = LDLM_IBITS; einfo->ei_mode = it_to_lock_mode(&minfo->mi_it); einfo->ei_cb_bl = ll_md_blocking_ast; @@ -771,26 +750,22 @@ static int sa_prep_data(struct inode *dir, struct inode *child, einfo->ei_cb_gl = NULL; einfo->ei_cbdata = NULL; - *pmi = minfo; - *pei = einfo; - - return 0; + return minfo; } /* async stat for file not found in dcache */ static int sa_lookup(struct inode *dir, struct sa_entry *entry) { struct md_enqueue_info *minfo; - struct ldlm_enqueue_info *einfo; int rc; - rc = sa_prep_data(dir, NULL, entry, &minfo, &einfo); - if (rc) - return rc; + minfo = sa_prep_data(dir, NULL, entry); + if (IS_ERR(minfo)) + return PTR_ERR(minfo); - rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo); + rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo); if (rc) - sa_fini_data(minfo, einfo); + sa_fini_data(minfo); return rc; } @@ -809,7 +784,6 @@ static int sa_revalidate(struct inode *dir, struct sa_entry *entry, struct lookup_intent it = { .it_op = IT_GETATTR, .it_lock_handle = 0 }; struct md_enqueue_info *minfo; - struct ldlm_enqueue_info *einfo; int rc; if (unlikely(!inode)) @@ -827,25 +801,26 @@ static int sa_revalidate(struct inode *dir, struct sa_entry *entry, return 1; } - rc = sa_prep_data(dir, inode, entry, &minfo, &einfo); - if (rc) { + minfo = sa_prep_data(dir, inode, entry); + if (IS_ERR(minfo)) { entry->se_inode = NULL; iput(inode); - return rc; + return PTR_ERR(minfo); } - rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo); + rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo); if (rc) { entry->se_inode = NULL; iput(inode); - sa_fini_data(minfo, einfo); + sa_fini_data(minfo); } return rc; } /* async stat for file with @name */ -static void sa_statahead(struct dentry *parent, const char *name, int len) +static void sa_statahead(struct dentry *parent, const char *name, int len, + const struct lu_fid *fid) { struct inode *dir = d_inode(parent); struct ll_inode_info *lli = ll_i2info(dir); @@ -854,7 +829,7 @@ static void sa_statahead(struct dentry *parent, const char *name, int len) struct sa_entry *entry; int rc; - entry = sa_alloc(parent, sai, sai->sai_index, name, len); + entry = sa_alloc(parent, sai, sai->sai_index, name, len, fid); if (IS_ERR(entry)) return; @@ -1043,6 +1018,7 @@ static int ll_statahead_thread(void *arg) for (ent = lu_dirent_start(dp); ent && thread_is_running(sa_thread) && !sa_low_hit(sai); ent = lu_dirent_next(ent)) { + struct lu_fid fid; __u64 hash; int namelen; char *name; @@ -1088,6 +1064,8 @@ static int ll_statahead_thread(void *arg) if (unlikely(++first == 1)) continue; + fid_le_to_cpu(&fid, &ent->lde_fid); + /* wait for spare statahead window */ do { l_wait_event(sa_thread->t_ctl_waitq, @@ -1117,7 +1095,7 @@ static int ll_statahead_thread(void *arg) } while (sa_sent_full(sai) && thread_is_running(sa_thread)); - sa_statahead(parent, name, namelen); + sa_statahead(parent, name, namelen, &fid); } pos = le64_to_cpu(dp->ldp_hash_end); |