summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/client.c6
-rw-r--r--fs/nfs/direct.c2
-rw-r--r--fs/nfs/getroot.c11
-rw-r--r--fs/nfs/super.c2
4 files changed, 15 insertions, 6 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 70587f383f1..a6f62549761 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -410,9 +410,6 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
*/
static void nfs_destroy_server(struct nfs_server *server)
{
- if (!IS_ERR(server->client_acl))
- rpc_shutdown_client(server->client_acl);
-
if (!(server->flags & NFS_MOUNT_NONLM))
lockd_down(); /* release rpc.lockd */
}
@@ -755,6 +752,9 @@ void nfs_free_server(struct nfs_server *server)
if (server->destroy != NULL)
server->destroy(server);
+
+ if (!IS_ERR(server->client_acl))
+ rpc_shutdown_client(server->client_acl);
if (!IS_ERR(server->client))
rpc_shutdown_client(server->client);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 5e8d82f6666..3c9d16b4f80 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -894,8 +894,6 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
retval = generic_write_checks(file, &pos, &count, 0);
if (retval)
goto out;
- if (!count)
- goto out; /* return 0 */
retval = -EINVAL;
if ((ssize_t) count < 0)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 0ee43843f4e..e6242cdbaf9 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -57,6 +57,17 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
}
/* Circumvent igrab(): we know the inode is not being freed */
atomic_inc(&inode->i_count);
+ /*
+ * Ensure that this dentry is invisible to d_find_alias().
+ * Otherwise, it may be spliced into the tree by
+ * d_materialise_unique if a parent directory from the same
+ * filesystem gets mounted at a later time.
+ * This again causes shrink_dcache_for_umount_subtree() to
+ * Oops, since the test for IS_ROOT() will fail.
+ */
+ spin_lock(&dcache_lock);
+ list_del_init(&sb->s_root->d_alias);
+ spin_unlock(&dcache_lock);
}
return 0;
}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2426e713b77..ea929207f27 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1475,7 +1475,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
error = PTR_ERR(mntroot);
goto error_splat_super;
}
- if (mntroot->d_inode->i_op != &nfs_dir_inode_operations) {
+ if (mntroot->d_inode->i_op != server->nfs_client->rpc_ops->dir_inode_ops) {
dput(mntroot);
error = -ESTALE;
goto error_splat_super;