diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/llite/llite_nfs.c')
-rw-r--r-- | drivers/staging/lustre/lustre/llite/llite_nfs.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c index 65972c8..7092305 100644 --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c @@ -38,7 +38,6 @@ */ #define DEBUG_SUBSYSTEM S_LLITE -#include "../include/lustre_lite.h" #include "llite_internal.h" #include <linux/exportfs.h> @@ -73,11 +72,6 @@ void get_uuid2fsid(const char *name, int len, __kernel_fsid_t *fsid) fsid->val[1] = key >> 32; } -static int ll_nfs_test_inode(struct inode *inode, void *opaque) -{ - return lu_fid_eq(&ll_i2info(inode)->lli_fid, opaque); -} - struct inode *search_inode_for_lustre(struct super_block *sb, const struct lu_fid *fid) { @@ -92,7 +86,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb, CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", hash, PFID(fid)); - inode = ilookup5(sb, hash, ll_nfs_test_inode, (void *)fid); + inode = ilookup5(sb, hash, ll_test_inode_by_fid, (void *)fid); if (inode) return inode; @@ -153,12 +147,18 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren return ERR_PTR(-ESTALE); } + result = d_obtain_alias(inode); + if (IS_ERR(result)) { + iput(inode); + return result; + } + /** - * It is an anonymous dentry without OST objects created yet. - * We have to find the parent to tell MDS how to init lov objects. + * In case d_obtain_alias() found a disconnected dentry, always update + * lli_pfid to allow later operation (normally open) have parent fid, + * which may be used by MDS to create data. */ - if (S_ISREG(inode->i_mode) && !ll_i2info(inode)->lli_has_smd && - parent && !fid_is_zero(parent)) { + if (parent) { struct ll_inode_info *lli = ll_i2info(inode); spin_lock(&lli->lli_lock); @@ -255,6 +255,8 @@ static int ll_get_name(struct dentry *dentry, char *name, .lgd_fid = ll_i2info(d_inode(child))->lli_fid, .ctx.actor = ll_nfs_get_name_filldir, }; + struct md_op_data *op_data; + __u64 pos = 0; if (!dir || !S_ISDIR(dir->i_mode)) { rc = -ENOTDIR; @@ -266,9 +268,18 @@ static int ll_get_name(struct dentry *dentry, char *name, goto out; } + op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0, + LUSTRE_OPC_ANY, dir); + if (IS_ERR(op_data)) { + rc = PTR_ERR(op_data); + goto out; + } + + op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; inode_lock(dir); - rc = ll_dir_read(dir, &lgd.ctx); + rc = ll_dir_read(dir, &pos, op_data, &lgd.ctx); inode_unlock(dir); + ll_finish_md_op_data(op_data); if (!rc && !lgd.lgd_found) rc = -ENOENT; out: @@ -297,14 +308,12 @@ static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid, return ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL); } -static struct dentry *ll_get_parent(struct dentry *dchild) +int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid) { struct ptlrpc_request *req = NULL; - struct inode *dir = d_inode(dchild); struct ll_sb_info *sbi; - struct dentry *result = NULL; struct mdt_body *body; - static char dotdot[] = ".."; + static const char dotdot[] = ".."; struct md_op_data *op_data; int rc; int lmmsize; @@ -319,13 +328,13 @@ static struct dentry *ll_get_parent(struct dentry *dchild) rc = ll_get_default_mdsize(sbi, &lmmsize); if (rc != 0) - return ERR_PTR(rc); + return rc; op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot, strlen(dotdot), lmmsize, LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) - return (void *)op_data; + return PTR_ERR(op_data); rc = md_getattr_name(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); @@ -333,21 +342,36 @@ static struct dentry *ll_get_parent(struct dentry *dchild) CERROR("%s: failure inode "DFID" get parent: rc = %d\n", ll_get_fsname(dir->i_sb, NULL, 0), PFID(ll_inode2fid(dir)), rc); - return ERR_PTR(rc); + return rc; } body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); /* * LU-3952: MDT may lost the FID of its parent, we should not crash * the NFS server, ll_iget_for_nfs() will handle the error. */ - if (body->valid & OBD_MD_FLID) { + if (body->mbo_valid & OBD_MD_FLID) { CDEBUG(D_INFO, "parent for " DFID " is " DFID "\n", - PFID(ll_inode2fid(dir)), PFID(&body->fid1)); + PFID(ll_inode2fid(dir)), PFID(&body->mbo_fid1)); + *parent_fid = body->mbo_fid1; } - result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL); ptlrpc_req_finished(req); - return result; + return 0; +} + +static struct dentry *ll_get_parent(struct dentry *dchild) +{ + struct lu_fid parent_fid = { 0 }; + struct dentry *dentry; + int rc; + + rc = ll_dir_get_parent_fid(dchild->d_inode, &parent_fid); + if (rc) + return ERR_PTR(rc); + + dentry = ll_iget_for_nfs(dchild->d_inode->i_sb, &parent_fid, NULL); + + return dentry; } const struct export_operations lustre_export_operations = { |