Merge git://git.infradead.org/mtd-2.6
[firefly-linux-kernel-4.4.55.git] / fs / xfs / linux-2.6 / xfs_export.c
index 595751f783506540ab08ea88819682dc8a73c647..87b8cbd23d4bc5a9e287dbfbea056d11994612cf 100644 (file)
@@ -126,11 +126,26 @@ xfs_nfs_get_inode(
        if (ino == 0)
                return ERR_PTR(-ESTALE);
 
-       error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
-       if (error)
+       /*
+        * The XFS_IGET_BULKSTAT means that an invalid inode number is just
+        * fine and not an indication of a corrupted filesystem.  Because
+        * clients can send any kind of invalid file handle, e.g. after
+        * a restore on the server we have to deal with this case gracefully.
+        */
+       error = xfs_iget(mp, NULL, ino, XFS_IGET_BULKSTAT,
+                        XFS_ILOCK_SHARED, &ip, 0);
+       if (error) {
+               /*
+                * EINVAL means the inode cluster doesn't exist anymore.
+                * This implies the filehandle is stale, so we should
+                * translate it here.
+                * We don't use ESTALE directly down the chain to not
+                * confuse applications using bulkstat that expect EINVAL.
+                */
+               if (error == EINVAL)
+                       error = ESTALE;
                return ERR_PTR(-error);
-       if (!ip)
-               return ERR_PTR(-EIO);
+       }
 
        if (ip->i_d.di_gen != generation) {
                xfs_iput_new(ip, XFS_ILOCK_SHARED);