]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/linux-2.6/xfs_export.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-2.6-omap-h63xx.git] / fs / xfs / linux-2.6 / xfs_export.c
index 15bd4948832ce7b1f789074b4ec77f53d0a9e25a..987fe84f7b1351d8204b18d182c4f49185f95218 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
+#include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_export.h"
@@ -30,8 +31,6 @@
 #include "xfs_inode.h"
 #include "xfs_vfsops.h"
 
-static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
-
 /*
  * Note that we only accept fileids which are long enough rather than allow
  * the parent generation number to default to zero.  XFS considers zero a
@@ -66,7 +65,7 @@ xfs_fs_encode_fh(
        int                     len;
 
        /* Directories don't need their parent encoded, they have ".." */
-       if (S_ISDIR(inode->i_mode))
+       if (S_ISDIR(inode->i_mode) || !connectable)
                fileid_type = FILEID_INO32_GEN;
        else
                fileid_type = FILEID_INO32_GEN_PARENT;
@@ -118,20 +117,29 @@ xfs_nfs_get_inode(
        u64                     ino,
        u32                     generation)
  {
-       xfs_fid_t               xfid;
-       bhv_vnode_t             *vp;
+       xfs_mount_t             *mp = XFS_M(sb);
+       xfs_inode_t             *ip;
        int                     error;
 
-       xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len);
-       xfid.fid_pad = 0;
-       xfid.fid_ino = ino;
-       xfid.fid_gen = generation;
+       /*
+        * NFS can sometimes send requests for ino 0.  Fail them gracefully.
+        */
+       if (ino == 0)
+               return ERR_PTR(-ESTALE);
 
-       error = xfs_vget(XFS_M(sb), &vp, &xfid);
+       error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
        if (error)
                return ERR_PTR(-error);
+       if (!ip)
+               return ERR_PTR(-EIO);
+
+       if (ip->i_d.di_gen != generation) {
+               xfs_iput_new(ip, XFS_ILOCK_SHARED);
+               return ERR_PTR(-ENOENT);
+       }
 
-       return vp ? vn_to_inode(vp) : NULL;
+       xfs_iunlock(ip, XFS_ILOCK_SHARED);
+       return ip->i_vnode;
 }
 
 STATIC struct dentry *
@@ -204,17 +212,16 @@ xfs_fs_get_parent(
        struct dentry           *child)
 {
        int                     error;
-       bhv_vnode_t             *cvp;
+       struct xfs_inode        *cip;
        struct dentry           *parent;
 
-       cvp = NULL;
-       error = xfs_lookup(XFS_I(child->d_inode), &dotdot, &cvp);
+       error = xfs_lookup(XFS_I(child->d_inode), &xfs_name_dotdot, &cip, NULL);
        if (unlikely(error))
                return ERR_PTR(-error);
 
-       parent = d_alloc_anon(vn_to_inode(cvp));
+       parent = d_alloc_anon(cip->i_vnode);
        if (unlikely(!parent)) {
-               VN_RELE(cvp);
+               iput(cip->i_vnode);
                return ERR_PTR(-ENOMEM);
        }
        return parent;