struct dentry *result;
ENTRY;
- CDEBUG(D_INFO, "Get dentry for fid: "DFID"\n", PFID(fid));
- if (!fid_is_sane(fid))
- RETURN(ERR_PTR(-ESTALE));
+ if (!fid_is_sane(fid))
+ RETURN(ERR_PTR(-ESTALE));
+
+ CDEBUG(D_INFO, "Get dentry for fid: "DFID"\n", PFID(fid));
inode = search_inode_for_lustre(sb, fid);
if (IS_ERR(inode))
* We have to find the parent to tell MDS how to init lov objects.
*/
if (S_ISREG(inode->i_mode) && !ll_i2info(inode)->lli_has_smd &&
- parent != NULL) {
+ parent != NULL && !fid_is_zero(parent)) {
struct ll_inode_info *lli = ll_i2info(inode);
spin_lock(&lli->lli_lock);
RETURN(result);
}
-#define LUSTRE_NFS_FID 0x97
+#ifndef FILEID_INVALID
+#define FILEID_INVALID 0xff
+#endif
+#ifndef FILEID_LUSTRE
+#define FILEID_LUSTRE 0x97
+#endif
/**
* \a connectable - is nfsd will connect himself or this should be done
struct inode *parent)
{
#endif
+ int fileid_len = sizeof(struct lustre_nfs_fid) / 4;
struct lustre_nfs_fid *nfs_fid = (void *)fh;
ENTRY;
- CDEBUG(D_INFO, "encoding for (%lu,"DFID") maxlen=%d minlen=%d\n",
- inode->i_ino, PFID(ll_inode2fid(inode)), *plen,
- (int)sizeof(struct lustre_nfs_fid));
+ CDEBUG(D_INFO, "%s: encoding for ("DFID") maxlen=%d minlen=%d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0),
+ PFID(ll_inode2fid(inode)), *plen, fileid_len);
- if (*plen < sizeof(struct lustre_nfs_fid) / 4)
- RETURN(255);
+ if (*plen < fileid_len) {
+ *plen = fileid_len;
+ RETURN(FILEID_INVALID);
+ }
nfs_fid->lnf_child = *ll_inode2fid(inode);
- nfs_fid->lnf_parent = *ll_inode2fid(parent);
- *plen = sizeof(struct lustre_nfs_fid) / 4;
+ if (parent != NULL)
+ nfs_fid->lnf_parent = *ll_inode2fid(parent);
+ else
+ fid_zero(&nfs_fid->lnf_parent);
+ *plen = fileid_len;
- RETURN(LUSTRE_NFS_FID);
+ RETURN(FILEID_LUSTRE);
}
static int ll_nfs_get_name_filldir(void *cookie, const char *name, int namelen,
{
struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
- if (fh_type != LUSTRE_NFS_FID)
- RETURN(ERR_PTR(-EPROTO));
+ if (fh_type != FILEID_LUSTRE)
+ RETURN(ERR_PTR(-EPROTO));
RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_child, &nfs_fid->lnf_parent));
}
{
struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
- if (fh_type != LUSTRE_NFS_FID)
- RETURN(ERR_PTR(-EPROTO));
+ if (fh_type != FILEID_LUSTRE)
+ RETURN(ERR_PTR(-EPROTO));
RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL));
}
+
static struct dentry *ll_get_parent(struct dentry *dchild)
{
struct ptlrpc_request *req = NULL;
sbi = ll_s2sbi(dir->i_sb);
- CDEBUG(D_INFO, "getting parent for (%lu,"DFID")\n",
- dir->i_ino, PFID(ll_inode2fid(dir)));
+ CDEBUG(D_INFO, "%s: getting parent for ("DFID")\n",
+ ll_get_fsname(dir->i_sb, NULL, 0),
+ PFID(ll_inode2fid(dir)));
rc = ll_get_max_mdsize(sbi, &lmmsize);
if (rc != 0)
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);
-
- rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
- ll_finish_md_op_data(op_data);
- if (rc) {
- CERROR("failure %d inode %lu get parent\n", rc, dir->i_ino);
- RETURN(ERR_PTR(rc));
- }
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- LASSERT(body->valid & OBD_MD_FLID);
-
- CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n",
- PFID(ll_inode2fid(dir)), PFID(&body->fid1));
-
- result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL);
+ LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ RETURN((void *)op_data);
+
+ rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
+ ll_finish_md_op_data(op_data);
+ if (rc) {
+ 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));
+ }
+ 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) {
+ CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n",
+ PFID(ll_inode2fid(dir)), PFID(&body->fid1));
+ }
+ result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL);
- ptlrpc_req_finished(req);
- RETURN(result);
+ ptlrpc_req_finished(req);
+ RETURN(result);
}
struct export_operations lustre_export_operations = {