From 4584f520e1f773082ef44ff4f8969a5d992b16ec Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 11 Dec 2007 19:01:45 -0500 Subject: NFS: Fix NFS mountpoint crossing... The check that was added to nfs_xdev_get_sb() to work around broken servers, works fine for NFSv2, but causes mountpoint crossing on NFSv3 to always return ESTALE. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2426e71..ea92920 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; -- cgit v0.10.2 From 5cef338b30c110daf547fb13d99f0c77f2a79fbc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 11 Dec 2007 22:01:56 -0500 Subject: NFSv2/v3: Fix a memory leak when using -onolock Neil Brown said: > Hi Trond, > > We found that a machine which made moderately heavy use of > 'automount' was leaking some nfs data structures - particularly the > 4K allocated by rpc_alloc_iostats. > It turns out that this only happens with filesystems with -onolock > set. > The problem is that if NFS_MOUNT_NONLM is set, nfs_start_lockd doesn't > set server->destroy, so when the filesystem is unmounted, the > ->client_acl is not shutdown, and so several resources are still > held. Multiple mount/umount cycles will slowly eat away memory > several pages at a time. Signed-off-by: Trond Myklebust Acked-by: NeilBrown diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 70587f3..a6f6254 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); -- cgit v0.10.2 From 50e1092b3a119bb4660bb6bd2e1749dc2d8ac62e Mon Sep 17 00:00:00 2001 From: James Lentini Date: Mon, 10 Dec 2007 11:24:48 -0500 Subject: SUNRPC xprtrdma: fix XDR tail buf marshalling for all ops rpcrdma_convert_iovs is passed an xdr_buf representing either an RPC request or an RPC reply. In the case of a request, several calculations and tests involving pos are unnecessary. In the case of a reply, several calculations and tests involving pos are incorrect (the code tests pos against the reply xdr buf's len field, which is always 0 at the time rpcrdma_convert_iovs is executed). This change removes the incorrect/unnecessary calculations and tests involving pos. This fixes an observed problem when reading certain file sizes over NFS/RDMA. Signed-off-by: Tom Tucker Signed-off-by: Tom Talpey Signed-off-by: James Lentini Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 9e11ce7..ee8de7a 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -92,7 +92,6 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, seg[n].mr_page = NULL; seg[n].mr_offset = xdrbuf->head[0].iov_base; seg[n].mr_len = xdrbuf->head[0].iov_len; - pos += xdrbuf->head[0].iov_len; ++n; } @@ -104,7 +103,6 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, seg[n].mr_len = min_t(u32, PAGE_SIZE - xdrbuf->page_base, xdrbuf->page_len); len = xdrbuf->page_len - seg[n].mr_len; - pos += len; ++n; p = 1; while (len > 0) { @@ -119,20 +117,15 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, } } - if (pos < xdrbuf->len && xdrbuf->tail[0].iov_len) { + if (xdrbuf->tail[0].iov_len) { if (n == nsegs) return 0; seg[n].mr_page = NULL; seg[n].mr_offset = xdrbuf->tail[0].iov_base; seg[n].mr_len = xdrbuf->tail[0].iov_len; - pos += xdrbuf->tail[0].iov_len; ++n; } - if (pos < xdrbuf->len) - dprintk("RPC: %s: marshaled only %d of %d\n", - __func__, pos, xdrbuf->len); - return n; } -- cgit v0.10.2 From a5576cfa5cd8d8aa874bd4ee500dc8a2e7cbad18 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 12 Dec 2007 11:08:33 -0500 Subject: Revert "NFS: Ensure we return zero if applications attempt to write zero bytes" This reverts commit b9148c6b80d802dbc2a7530b29915a80432e50c7. On Wed, 12 Dec 2007 10:57:30 -0500, Chuck Lever wrote > commit b9148c6b should be reverted. It was recently forward-ported > from some years-old patches, and is clearly not needed now. > > On Dec 11, 2007, at 5:21 PM, Adrian Bunk wrote: > >> This code became dead after commit >> b9148c6b80d802dbc2a7530b29915a80432e50c7 >> (which BTW doesn't seem to have changed any behaviour) and can >> therefore >> be removed. >> >> Spotted by the Coverity checker. >> >> Signed-off-by: Adrian Bunk >> >> --- >> --- linux-2.6/fs/nfs/direct.c.old 2007-12-02 21:54:53.000000000 +0100 >> +++ linux-2.6/fs/nfs/direct.c 2007-12-02 21:55:10.000000000 +0100 >> @@ -897,15 +897,12 @@ ssize_t nfs_file_direct_write(struct kio >> if (!count) >> goto out; /* return 0 */ >> >> retval = -EINVAL; >> if ((ssize_t) count < 0) >> goto out; >> - retval = 0; >> - if (!count) >> - goto out; >> >> retval = nfs_sync_mapping(mapping); >> if (retval) >> goto out; >> >> retval = nfs_direct_write(iocb, iov, nr_segs, pos, count); >> Signed-off-by: Trond Myklebust diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 5e8d82f..3c9d16b 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) -- cgit v0.10.2 From a10db50a4ae813fcb2f431f2fb039933c109a925 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 12 Dec 2007 11:12:15 -0500 Subject: NFS: Fix an Oops in NFS unmount Ensure that the dummy 'root dentry' is invisible to d_find_alias(). If not, then it may be spliced into the tree if a parent directory from the same filesystem gets mounted at a later time. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 0ee4384..e6242cd 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; } -- cgit v0.10.2 From 78f5815368837ae7e3a0d3709c9f95f74e4d8537 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 12 Dec 2007 20:16:06 -0500 Subject: MAINTAINERS: update the NFS CLIENT entry Add in the new NFS mailing list on vger, website, and git tree info, and update my email address to reflect the fact that I've been working for netapp for the past 2 years. Signed-off-by: Trond Myklebust diff --git a/MAINTAINERS b/MAINTAINERS index 9507b42..94143d7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2751,8 +2751,10 @@ S: Maintained NFS CLIENT P: Trond Myklebust -M: trond.myklebust@fys.uio.no -L: linux-kernel@vger.kernel.org +M: Trond.Myklebust@netapp.com +L: linux-nfs@vger.kernel.org +W: http://client.linux-nfs.org +T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git S: Maintained NI5010 NETWORK DRIVER -- cgit v0.10.2