* [PATCH 01/24] NFS: Use NFSDBG_FILE for all fops
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-04-14 16:26 ` Chuck Lever
2008-04-14 16:26 ` [PATCH 02/24] NFS: Fix trace debugging nits in write.c Chuck Lever
` (23 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:26 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: some fops use NFSDBG_FILE, some use NFSDBG_VFS. Let's use
NFSDBG_FILE for all fops, and consistently report file names instead
of inode numbers.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/dir.c | 10 +++++----
fs/nfs/direct.c | 4 ++--
fs/nfs/file.c | 60 +++++++++++++++++++++++++++++++++++--------------------
3 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index b9f1a72..9f52a8c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -134,7 +134,7 @@ nfs_opendir(struct inode *inode, struct file *filp)
struct dentry *dentry = filp->f_path.dentry;
int res;
- dfprintk(VFS, "NFS: open dir(%s/%s)\n",
+ dfprintk(FILE, "NFS: open dir(%s/%s)\n",
dentry->d_parent->d_name.name,
dentry->d_name.name);
@@ -532,7 +532,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct nfs_fattr fattr;
long res;
- dfprintk(VFS, "NFS: readdir(%s/%s) starting at cookie %Lu\n",
+ dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %Lu\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
(long long)filp->f_pos);
nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);
@@ -599,7 +599,7 @@ out:
unlock_kernel();
if (res > 0)
res = 0;
- dfprintk(VFS, "NFS: readdir(%s/%s) returns %ld\n",
+ dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
res);
return res;
@@ -610,7 +610,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = filp->f_path.dentry->d_inode;
- dfprintk(VFS, "NFS: llseek dir(%s/%s, %Ld, %d)\n",
+ dfprintk(FILE, "NFS: llseek dir(%s/%s, %Ld, %d)\n",
dentry->d_parent->d_name.name,
dentry->d_name.name,
offset, origin);
@@ -641,7 +641,7 @@ out:
*/
static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
{
- dfprintk(VFS, "NFS: fsync dir(%s/%s) datasync %d\n",
+ dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
datasync);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 16844f9..2724d19 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -870,7 +870,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
count = iov_length(iov, nr_segs);
nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
- dprintk("nfs: direct read(%s/%s, %zd@%Ld)\n",
+ dfprintk(FILE, "NFS: direct read(%s/%s, %zd@%Ld)\n",
file->f_path.dentry->d_parent->d_name.name,
file->f_path.dentry->d_name.name,
count, (long long) pos);
@@ -927,7 +927,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
count = iov_length(iov, nr_segs);
nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
- dfprintk(VFS, "nfs: direct write(%s/%s, %zd@%Ld)\n",
+ dfprintk(FILE, "NFS: direct write(%s/%s, %zd@%Ld)\n",
file->f_path.dentry->d_parent->d_name.name,
file->f_path.dentry->d_name.name,
count, (long long) pos);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 03f00bd..a635457 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -120,7 +120,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
struct dentry *dentry = filp->f_path.dentry;
int res;
- dfprintk(VFS, "NFS: open file(%s/%s)\n",
+ dprintk("NFS: open file(%s/%s)\n",
dentry->d_parent->d_name.name,
dentry->d_name.name);
@@ -138,6 +138,12 @@ nfs_file_open(struct inode *inode, struct file *filp)
static int
nfs_file_release(struct inode *inode, struct file *filp)
{
+ struct dentry *dentry = filp->f_path.dentry;
+
+ dprintk("NFS: release(%s/%s)\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name);
+
/* Ensure that dirty pages are flushed out with the right creds */
if (filp->f_mode & FMODE_WRITE)
nfs_wb_all(filp->f_path.dentry->d_inode);
@@ -177,7 +183,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
{
struct dentry *dentry = filp->f_path.dentry;
- dfprintk(VFS, "NFS: llseek file(%s/%s, %Ld, %d)\n",
+ dprintk("NFS: llseek file(%s/%s, %Ld, %d)\n",
dentry->d_parent->d_name.name,
dentry->d_name.name,
offset, origin);
@@ -219,16 +225,18 @@ static int nfs_do_fsync(struct nfs_open_context *ctx, struct inode *inode)
/*
* Flush all dirty pages, and check for write errors.
- *
*/
static int
nfs_file_flush(struct file *file, fl_owner_t id)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
- struct inode *inode = file->f_path.dentry->d_inode;
+ struct dentry *dentry = file->f_path.dentry;
+ struct inode *inode = dentry->d_inode;
int status;
- dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
+ dprintk("NFS: flush(%s/%s)\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name);
if ((file->f_mode & FMODE_WRITE) == 0)
return 0;
@@ -253,7 +261,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
if (iocb->ki_filp->f_flags & O_DIRECT)
return nfs_file_direct_read(iocb, iov, nr_segs, pos);
- dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n",
+ dprintk("NFS: read(%s/%s, %lu@%lu)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long) pos);
@@ -273,7 +281,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
struct inode *inode = dentry->d_inode;
ssize_t res;
- dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n",
+ dprintk("NFS: splice_read(%s/%s, %lu@%Lu)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long long) *ppos);
@@ -290,7 +298,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
struct inode *inode = dentry->d_inode;
int status;
- dfprintk(VFS, "nfs: mmap(%s/%s)\n",
+ dprintk("NFS: mmap(%s/%s)\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
status = nfs_revalidate_mapping(inode, file->f_mapping);
@@ -313,7 +321,7 @@ nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = dentry->d_inode;
- dfprintk(VFS, "NFS: fsync file(%s/%s) datasync %d\n",
+ dprintk("NFS: fsync file(%s/%s) datasync %d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
datasync);
@@ -487,9 +495,9 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
if (iocb->ki_filp->f_flags & O_DIRECT)
return nfs_file_direct_write(iocb, iov, nr_segs, pos);
- dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
+ dprintk("NFS: write(%s/%s, %lu@%Ld)\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
- inode->i_ino, (unsigned long) count, (long long) pos);
+ (unsigned long) count, (long long) pos);
result = -EBUSY;
if (IS_SWAPFILE(inode))
@@ -640,12 +648,14 @@ out:
*/
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
{
- struct inode * inode = filp->f_mapping->host;
+ struct dentry *dentry = filp->f_path.dentry;
+ struct inode *inode = filp->f_mapping->host;
- dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n",
- inode->i_sb->s_id, inode->i_ino,
+ dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%Ld:%Ld)\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,
fl->fl_type, fl->fl_flags,
(long long)fl->fl_start, (long long)fl->fl_end);
+
nfs_inc_stats(inode, NFSIOS_VFSLOCK);
/* No mandatory locks over NFS */
@@ -664,9 +674,10 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
*/
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
{
- dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n",
- filp->f_path.dentry->d_inode->i_sb->s_id,
- filp->f_path.dentry->d_inode->i_ino,
+ struct dentry *dentry = filp->f_path.dentry;
+
+ dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name,
fl->fl_type, fl->fl_flags);
/*
@@ -689,12 +700,17 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
return do_setlk(filp, cmd, fl);
}
+/*
+ * There is no protocol support for leases, so we have no way to implement
+ * them correctly in the face of opens by other clients.
+ */
static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
{
- /*
- * There is no protocol support for leases, so we have no way
- * to implement them correctly in the face of opens by other
- * clients.
- */
+ struct dentry *dentry = file->f_path.dentry;
+
+ dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name, arg);
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 02/24] NFS: Fix trace debugging nits in write.c
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:26 ` [PATCH 01/24] NFS: Use NFSDBG_FILE for all fops Chuck Lever
@ 2008-04-14 16:26 ` Chuck Lever
2008-04-14 16:27 ` [PATCH 03/24] SUNRPC: RPC server still uses 2.4 method for disabling TCP Nagle Chuck Lever
` (22 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:26 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/write.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index bed6341..969658b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -728,10 +728,10 @@ int nfs_updatepage(struct file *file, struct page *page,
nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
- dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n",
+ dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n",
file->f_path.dentry->d_parent->d_name.name,
file->f_path.dentry->d_name.name, count,
- (long long)(page_offset(page) +offset));
+ (long long)(page_offset(page) + offset));
/* If we're not using byte range locks, and we know the page
* is up to date, it may be more efficient to extend the write
@@ -748,7 +748,7 @@ int nfs_updatepage(struct file *file, struct page *page,
status = nfs_writepage_setup(ctx, page, offset, count);
__set_page_dirty_nobuffers(page);
- dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
+ dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
status, (long long)i_size_read(inode));
if (status < 0)
nfs_set_pageerror(page);
@@ -974,7 +974,8 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
struct nfs_page *req = data->req;
struct page *page = req->wb_page;
- dprintk("NFS: write (%s/%Ld %d@%Ld)",
+ dprintk("NFS: %5u write(%s/%Ld %d@%Ld)",
+ task->tk_pid,
req->wb_context->path.dentry->d_inode->i_sb->s_id,
(long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
req->wb_bytes,
@@ -1040,7 +1041,8 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
nfs_list_remove_request(req);
page = req->wb_page;
- dprintk("NFS: write (%s/%Ld %d@%Ld)",
+ dprintk("NFS: %5u write (%s/%Ld %d@%Ld)",
+ task->tk_pid,
req->wb_context->path.dentry->d_inode->i_sb->s_id,
(long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
req->wb_bytes,
@@ -1114,7 +1116,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
static unsigned long complain;
if (time_before(complain, jiffies)) {
- dprintk("NFS: faulty NFS server %s:"
+ dprintk("NFS: faulty NFS server %s:"
" (committed = %d) != (stable = %d)\n",
NFS_SERVER(data->inode)->nfs_client->cl_hostname,
resp->verf->committed, argp->stable);
@@ -1272,7 +1274,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
BDI_RECLAIMABLE);
- dprintk("NFS: commit (%s/%Ld %d@%Ld)",
+ dprintk("NFS: commit (%s/%Ld %d@%Ld)",
req->wb_context->path.dentry->d_inode->i_sb->s_id,
(long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
req->wb_bytes,
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 03/24] SUNRPC: RPC server still uses 2.4 method for disabling TCP Nagle
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:26 ` [PATCH 01/24] NFS: Use NFSDBG_FILE for all fops Chuck Lever
2008-04-14 16:26 ` [PATCH 02/24] NFS: Fix trace debugging nits in write.c Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162701.12741.10868.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:27 ` [PATCH 04/24] SUNRPC: Address potential buffer length overflow in svc_sendto Chuck Lever
` (21 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Use the 2.6 method for disabling TCP Nagle in the kernel's RPC server.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svcsock.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index c475977..6d4162b 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -38,6 +38,7 @@
#include <net/checksum.h>
#include <net/ip.h>
#include <net/ipv6.h>
+#include <net/tcp.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -1045,7 +1046,6 @@ void svc_cleanup_xprt_sock(void)
static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
{
struct sock *sk = svsk->sk_sk;
- struct tcp_sock *tp = tcp_sk(sk);
svc_xprt_init(&svc_tcp_class, &svsk->sk_xprt, serv);
set_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
@@ -1063,7 +1063,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
svsk->sk_reclen = 0;
svsk->sk_tcplen = 0;
- tp->nonagle = 1; /* disable Nagle's algorithm */
+ tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
/* initialise setting must have enough space to
* receive and respond to one request.
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 04/24] SUNRPC: Address potential buffer length overflow in svc_sendto
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (2 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 03/24] SUNRPC: RPC server still uses 2.4 method for disabling TCP Nagle Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162708.12741.71691.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:27 ` [PATCH 05/24] SUNRPC: Address potential buffer length overflow in svc_tcp_sendto Chuck Lever
` (20 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Paranoia: Ensure a negative error value return from kernel_sendpage never
matches a large buffer length.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svcsock.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 6d4162b..a8ae279 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -200,7 +200,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
flags = 0;
len = kernel_sendpage(sock, rqstp->rq_respages[0], 0,
xdr->head[0].iov_len, flags);
- if (len != xdr->head[0].iov_len)
+ if (len < 0 || len != xdr->head[0].iov_len)
goto out;
slen -= xdr->head[0].iov_len;
if (slen == 0)
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 05/24] SUNRPC: Address potential buffer length overflow in svc_tcp_sendto
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (3 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 04/24] SUNRPC: Address potential buffer length overflow in svc_sendto Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
2008-04-14 16:27 ` [PATCH 06/24] SUNRPC: Sanity check incoming UDP datagram lengths properly Chuck Lever
` (19 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Paranoia: Ensure a negative error value returned from svc_sendto()
doesn't match a large buffer length.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svcsock.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index a8ae279..d077071 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -956,18 +956,18 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
return -ENOTCONN;
sent = svc_sendto(rqstp, &rqstp->rq_res);
- if (sent != xbufp->len) {
- printk(KERN_NOTICE
- "rpc-srv/tcp: %s: %s %d when sending %d bytes "
- "- shutting down socket\n",
- rqstp->rq_xprt->xpt_server->sv_name,
- (sent<0)?"got error":"sent only",
- sent, xbufp->len);
- set_bit(XPT_CLOSE, &rqstp->rq_xprt->xpt_flags);
- svc_xprt_enqueue(rqstp->rq_xprt);
- sent = -EAGAIN;
- }
- return sent;
+ if (sent > 0 && sent == xbufp->len)
+ return sent;
+
+ printk(KERN_NOTICE "%s: %s %d when sending %u bytes "
+ "- shutting down TCP socket\n",
+ rqstp->rq_xprt->xpt_server->sv_name,
+ (sent < 0) ? "got error" : "sent only",
+ sent, xbufp->len);
+
+ set_bit(XPT_CLOSE, &rqstp->rq_xprt->xpt_flags);
+ svc_xprt_enqueue(rqstp->rq_xprt);
+ return -EAGAIN;
}
/*
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 06/24] SUNRPC: Sanity check incoming UDP datagram lengths properly
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (4 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 05/24] SUNRPC: Address potential buffer length overflow in svc_tcp_sendto Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162723.12741.35500.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:27 ` [PATCH 07/24] SUNRPC: Update RPC server's TCP record marker decoder Chuck Lever
` (18 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: ensure svc_udp_recvfrom() is getting at least a full UDP header
to avoid potential negative intermediate values.
A similar sanity check is already used in the RPC client.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svcsock.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d077071..de29e7f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -431,6 +431,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
} buffer;
struct cmsghdr *cmh = &buffer.hdr;
int err, len;
+ unsigned int bytes;
struct msghdr msg = {
.msg_name = svc_addr(rqstp),
.msg_control = cmh,
@@ -484,8 +485,13 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
*/
svc_xprt_received(&svsk->sk_xprt);
- len = skb->len - sizeof(struct udphdr);
- rqstp->rq_arg.len = len;
+ if (skb->len < sizeof(struct udphdr)) {
+ dprintk("svc: bad UDP datagram length: %u\n", skb->len);
+ skb_free_datagram(svsk->sk_sk, skb);
+ return 0;
+ }
+ bytes = skb->len - sizeof(struct udphdr);
+ rqstp->rq_arg.len = bytes;
rqstp->rq_prot = IPPROTO_UDP;
@@ -515,7 +521,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
/* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data +
sizeof(struct udphdr);
- rqstp->rq_arg.head[0].iov_len = len;
+ rqstp->rq_arg.head[0].iov_len = bytes;
if (skb_checksum_complete(skb)) {
skb_free_datagram(svsk->sk_sk, skb);
return 0;
@@ -524,12 +530,12 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
}
rqstp->rq_arg.page_base = 0;
- if (len <= rqstp->rq_arg.head[0].iov_len) {
- rqstp->rq_arg.head[0].iov_len = len;
+ if (bytes <= rqstp->rq_arg.head[0].iov_len) {
+ rqstp->rq_arg.head[0].iov_len = bytes;
rqstp->rq_arg.page_len = 0;
rqstp->rq_respages = rqstp->rq_pages+1;
} else {
- rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len;
+ rqstp->rq_arg.page_len = bytes - rqstp->rq_arg.head[0].iov_len;
rqstp->rq_respages = rqstp->rq_pages + 1 +
DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE);
}
@@ -537,7 +543,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
if (serv->sv_stats)
serv->sv_stats->netudpcnt++;
- return len;
+ return bytes;
}
static int
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 07/24] SUNRPC: Update RPC server's TCP record marker decoder
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (5 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 06/24] SUNRPC: Sanity check incoming UDP datagram lengths properly Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162730.12741.97124.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:27 ` [PATCH 08/24] SUNRPC: Use unsigned index when looping over arrays Chuck Lever
` (17 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Update the RPC server's TCP record marker decoder to match the
constructs used by the RPC client's TCP socket transport.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/svcsock.h | 4 ++--
net/sunrpc/svcsock.c | 24 ++++++++++++------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 206f092..8cff696 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -26,8 +26,8 @@ struct svc_sock {
void (*sk_owspace)(struct sock *);
/* private TCP part */
- int sk_reclen; /* length of record */
- int sk_tcplen; /* current read length */
+ u32 sk_reclen; /* length of record */
+ u32 sk_tcplen; /* current read length */
};
/*
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index de29e7f..51357a3 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -46,6 +46,7 @@
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/svcsock.h>
#include <linux/sunrpc/stats.h>
@@ -829,8 +830,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
* the next four bytes. Otherwise try to gobble up as much as
* possible up to the complete record length.
*/
- if (svsk->sk_tcplen < 4) {
- unsigned long want = 4 - svsk->sk_tcplen;
+ if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) {
+ int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
struct kvec iov;
iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
@@ -840,32 +841,31 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
svsk->sk_tcplen += len;
if (len < want) {
- dprintk("svc: short recvfrom while reading record length (%d of %lu)\n",
- len, want);
+ dprintk("svc: short recvfrom while reading record "
+ "length (%d of %d)\n", len, want);
svc_xprt_received(&svsk->sk_xprt);
return -EAGAIN; /* record header not complete */
}
svsk->sk_reclen = ntohl(svsk->sk_reclen);
- if (!(svsk->sk_reclen & 0x80000000)) {
+ if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) {
/* FIXME: technically, a record can be fragmented,
* and non-terminal fragments will not have the top
* bit set in the fragment length header.
* But apparently no known nfs clients send fragmented
* records. */
if (net_ratelimit())
- printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx"
- " (non-terminal)\n",
- (unsigned long) svsk->sk_reclen);
+ printk(KERN_NOTICE "RPC: multiple fragments "
+ "per record not supported\n");
goto err_delete;
}
- svsk->sk_reclen &= 0x7fffffff;
+ svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
if (svsk->sk_reclen > serv->sv_max_mesg) {
if (net_ratelimit())
- printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx"
- " (large)\n",
- (unsigned long) svsk->sk_reclen);
+ printk(KERN_NOTICE "RPC: "
+ "fragment too large: 0x%08lx\n",
+ (unsigned long)svsk->sk_reclen);
goto err_delete;
}
}
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 08/24] SUNRPC: Use unsigned index when looping over arrays
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (6 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 07/24] SUNRPC: Update RPC server's TCP record marker decoder Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
2008-04-14 16:27 ` [PATCH 09/24] " Chuck Lever
` (16 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Suppress a handful of harmless compiler warnings in the RPC
client related to array indices.
ARRAY_SIZE() returns a size_t, so use unsigned type for a loop index when
looping over arrays.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpc_pipe.c | 2 +-
net/sunrpc/sched.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 1b395a4..5209444 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -529,7 +529,7 @@ static void rpc_depopulate(struct dentry *parent,
struct inode *dir = parent->d_inode;
struct list_head *pos, *next;
struct dentry *dentry, *dvec[10];
- int n = 0;
+ unsigned int n = 0;
mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD);
repeat:
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 63fe132..01fc7b8 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -222,7 +222,7 @@ static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue)
static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, unsigned char nr_queues)
{
- int i;
+ unsigned int i;
spin_lock_init(&queue->lock);
for (i = 0; i < ARRAY_SIZE(queue->tasks); i++)
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 09/24] SUNRPC: Use unsigned index when looping over arrays
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (7 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 08/24] SUNRPC: Use unsigned index when looping over arrays Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162745.12741.37176.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:27 ` [PATCH 10/24] SUNRPC: Use unsigned loop and array index in svc_init_buffer() Chuck Lever
` (15 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Suppress a harmless compiler warning in the RPC server related
to array indices.
ARRAY_SIZE() returns a size_t, so use unsigned type for a loop index when
looping over arrays.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svc.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index a290e15..c1e763b 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -528,8 +528,9 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
static void
svc_release_buffer(struct svc_rqst *rqstp)
{
- int i;
- for (i=0; i<ARRAY_SIZE(rqstp->rq_pages); i++)
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(rqstp->rq_pages); i++)
if (rqstp->rq_pages[i])
put_page(rqstp->rq_pages[i]);
}
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 10/24] SUNRPC: Use unsigned loop and array index in svc_init_buffer()
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (8 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 09/24] " Chuck Lever
@ 2008-04-14 16:27 ` Chuck Lever
[not found] ` <20080414162752.12741.15628.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-04-14 16:28 ` [PATCH 11/24] SUNRPC: Remove obsolete messages during transport connect Chuck Lever
` (14 subsequent siblings)
24 siblings, 1 reply; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:27 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Suppress a harmless compiler warning.
Index rq_pages[] with an unsigned type. Make "pages" unsigned as well,
as it never represents a value less than zero.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svc.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index c1e763b..86a5b56 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -504,8 +504,7 @@ EXPORT_SYMBOL(svc_destroy);
static int
svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
{
- int pages;
- int arghi;
+ unsigned int pages, arghi;
pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply.
* We assume one is at most one page
@@ -519,7 +518,7 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
rqstp->rq_pages[arghi++] = p;
pages--;
}
- return ! pages;
+ return pages == 0;
}
/*
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 11/24] SUNRPC: Remove obsolete messages during transport connect
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (9 preceding siblings ...)
2008-04-14 16:27 ` [PATCH 10/24] SUNRPC: Use unsigned loop and array index in svc_init_buffer() Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 12/24] SUNRPC: More useful debugging output for rpcb client Chuck Lever
` (13 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Recent changes to the RPC client's transport connect logic make connect
status values ECONNREFUSED and ECONNRESET impossible.
Clean up xprt_connect_status() to account for these changes.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/xprt.c | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d5553b8..4b1dca0 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -664,7 +664,7 @@ static void xprt_connect_status(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
- if (task->tk_status >= 0) {
+ if (task->tk_status == 0) {
xprt->stat.connect_count++;
xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start;
dprintk("RPC: %5u xprt_connect_status: connection established\n",
@@ -673,12 +673,6 @@ static void xprt_connect_status(struct rpc_task *task)
}
switch (task->tk_status) {
- case -ECONNREFUSED:
- case -ECONNRESET:
- dprintk("RPC: %5u xprt_connect_status: server %s refused "
- "connection\n", task->tk_pid,
- task->tk_client->cl_server);
- break;
case -ENOTCONN:
dprintk("RPC: %5u xprt_connect_status: connection broken\n",
task->tk_pid);
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 12/24] SUNRPC: More useful debugging output for rpcb client
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (10 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 11/24] SUNRPC: Remove obsolete messages during transport connect Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 13/24] SUNRPC: Document some naked integers in rpcbind client Chuck Lever
` (12 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up dprintk's in rpcb client's XDR decoder functions.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 3164a08..904b1f5 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -439,7 +439,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
unsigned short *portp)
{
*portp = (unsigned short) ntohl(*p++);
- dprintk("RPC: rpcb_decode_getport result %u\n",
+ dprintk("RPC: rpcb_decode_getport result %u\n",
*portp);
return 0;
}
@@ -448,8 +448,8 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
unsigned int *boolp)
{
*boolp = (unsigned int) ntohl(*p++);
- dprintk("RPC: rpcb_decode_set result %u\n",
- *boolp);
+ dprintk("RPC: rpcb_decode_set: call %s\n",
+ (*boolp ? "succeeded" : "failed"));
return 0;
}
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 13/24] SUNRPC: Document some naked integers in rpcbind client
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (11 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 12/24] SUNRPC: More useful debugging output for rpcb client Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 14/24] SUNRPC: Use correct XDR encoding procedure for rpcbind SET/UNSET Chuck Lever
` (11 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Replace naked integers that represent rpcbind protocol versions.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 49 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 904b1f5..d852b2e 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -32,6 +32,10 @@
#define RPCBIND_PROGRAM (100000u)
#define RPCBIND_PORT (111u)
+#define RPCBVERS_2 (2u)
+#define RPCBVERS_3 (3u)
+#define RPCBVERS_4 (4u)
+
enum {
RPCBPROC_NULL,
RPCBPROC_SET,
@@ -82,7 +86,7 @@ static struct rpc_procinfo rpcb_procedures2[];
static struct rpc_procinfo rpcb_procedures3[];
struct rpcb_info {
- int rpc_vers;
+ u32 rpc_vers;
struct rpc_procinfo * rpc_proc;
};
@@ -177,7 +181,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
prog, vers, prot, port);
rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
- sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1);
+ sizeof(sin), XPRT_TRANSPORT_UDP, RPCBVERS_2, 1);
if (IS_ERR(rpcb_clnt))
return PTR_ERR(rpcb_clnt);
@@ -227,7 +231,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
__FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
- sizeof(*sin), prot, 2, 0);
+ sizeof(*sin), prot, RPCBVERS_2, 0);
if (IS_ERR(rpcb_clnt))
return PTR_ERR(rpcb_clnt);
@@ -589,35 +593,54 @@ static struct rpc_procinfo rpcb_procedures4[] = {
static struct rpcb_info rpcb_next_version[] = {
#ifdef CONFIG_SUNRPC_BIND34
- { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
- { 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
+ {
+ .rpc_vers = RPCBVERS_4,
+ .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR],
+ },
+ {
+ .rpc_vers = RPCBVERS_3,
+ .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
+ },
#endif
- { 2, &rpcb_procedures2[RPCBPROC_GETPORT] },
- { 0, NULL },
+ {
+ .rpc_vers = RPCBVERS_2,
+ .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
+ },
+ {
+ .rpc_proc = NULL,
+ },
};
static struct rpcb_info rpcb_next_version6[] = {
#ifdef CONFIG_SUNRPC_BIND34
- { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
- { 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
+ {
+ .rpc_vers = RPCBVERS_4,
+ .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR],
+ },
+ {
+ .rpc_vers = RPCBVERS_3,
+ .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
+ },
#endif
- { 0, NULL },
+ {
+ .rpc_proc = NULL,
+ },
};
static struct rpc_version rpcb_version2 = {
- .number = 2,
+ .number = RPCBVERS_2,
.nrprocs = RPCB_HIGHPROC_2,
.procs = rpcb_procedures2
};
static struct rpc_version rpcb_version3 = {
- .number = 3,
+ .number = RPCBVERS_3,
.nrprocs = RPCB_HIGHPROC_3,
.procs = rpcb_procedures3
};
static struct rpc_version rpcb_version4 = {
- .number = 4,
+ .number = RPCBVERS_4,
.nrprocs = RPCB_HIGHPROC_4,
.procs = rpcb_procedures4
};
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 14/24] SUNRPC: Use correct XDR encoding procedure for rpcbind SET/UNSET
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (12 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 13/24] SUNRPC: Document some naked integers in rpcbind client Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 15/24] SUNRPC: Introduce a specific rpcb_create for contacting localhost Chuck Lever
` (10 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
The rpcbind versions 3 and 4 SET and UNSET procedures use the same
arguments as the GETADDR procedure.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index d852b2e..18e677c 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -425,6 +425,10 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
rpcb_wake_rpcbind_waiters(xprt, status);
}
+/*
+ * XDR functions for rpcbind
+ */
+
static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
struct rpcbind_args *rpcb)
{
@@ -580,14 +584,14 @@ static struct rpc_procinfo rpcb_procedures2[] = {
};
static struct rpc_procinfo rpcb_procedures3[] = {
- PROC(SET, mapping, set),
- PROC(UNSET, mapping, set),
+ PROC(SET, getaddr, set),
+ PROC(UNSET, getaddr, set),
PROC(GETADDR, getaddr, getaddr),
};
static struct rpc_procinfo rpcb_procedures4[] = {
- PROC(SET, mapping, set),
- PROC(UNSET, mapping, set),
+ PROC(SET, getaddr, set),
+ PROC(UNSET, getaddr, set),
PROC(GETVERSADDR, getaddr, getaddr),
};
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 15/24] SUNRPC: Introduce a specific rpcb_create for contacting localhost
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (13 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 14/24] SUNRPC: Use correct XDR encoding procedure for rpcbind SET/UNSET Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 16/24] SUNRPC: None of rpcb_create's callers wants a privileged ephemeral port Chuck Lever
` (9 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Add rpcb_create_local() for use by rpcb_register() and upcoming IPv6
registration functions. Ensure any errors encountered by
rpcb_create_local() are properly reported.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 42 +++++++++++++++++++++++++++++++-----------
1 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 18e677c..9a92baa 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -112,6 +112,29 @@ static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
rpc_wake_up_status(&xprt->binding, status);
}
+static const struct sockaddr_in rpcb_inaddr_loopback = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+ .sin_port = htons(RPCBIND_PORT),
+};
+
+static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
+ size_t addrlen, u32 version)
+{
+ struct rpc_create_args args = {
+ .protocol = XPRT_TRANSPORT_UDP,
+ .address = addr,
+ .addrsize = addrlen,
+ .servername = "localhost",
+ .program = &rpcb_program,
+ .version = version,
+ .authflavor = RPC_AUTH_UNIX,
+ .flags = RPC_CLNT_CREATE_NOPING,
+ };
+
+ return rpc_create(&args);
+}
+
static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
size_t salen, int proto, u32 version,
int privileged)
@@ -157,10 +180,6 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
*/
int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
{
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
- };
struct rpcbind_args map = {
.r_prog = prog,
.r_vers = vers,
@@ -180,14 +199,15 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
"rpcbind\n", (port ? "" : "un"),
prog, vers, prot, port);
- rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
- sizeof(sin), XPRT_TRANSPORT_UDP, RPCBVERS_2, 1);
- if (IS_ERR(rpcb_clnt))
- return PTR_ERR(rpcb_clnt);
+ rpcb_clnt = rpcb_create_local((struct sockaddr *)&rpcb_inaddr_loopback,
+ sizeof(rpcb_inaddr_loopback),
+ RPCBVERS_2);
+ if (!IS_ERR(rpcb_clnt)) {
+ error = rpc_call_sync(rpcb_clnt, &msg, 0);
+ rpc_shutdown_client(rpcb_clnt);
+ } else
+ error = PTR_ERR(rpcb_clnt);
- error = rpc_call_sync(rpcb_clnt, &msg, 0);
-
- rpc_shutdown_client(rpcb_clnt);
if (error < 0)
printk(KERN_WARNING "RPC: failed to contact local rpcbind "
"server (errno %d).\n", -error);
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 16/24] SUNRPC: None of rpcb_create's callers wants a privileged ephemeral port
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (14 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 15/24] SUNRPC: Introduce a specific rpcb_create for contacting localhost Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 17/24] SUNRPC: Refactor rpcb_register to make rpcbindv4 support easier Chuck Lever
` (8 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Clean up: Now that rpcb_register has it's own rpcb_create routine, none
of rpcb_create's current callers needs a privileged ephemeral port.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 9a92baa..8590f4a 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -136,8 +136,7 @@ static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
}
static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
- size_t salen, int proto, u32 version,
- int privileged)
+ size_t salen, int proto, u32 version)
{
struct rpc_create_args args = {
.protocol = proto,
@@ -147,7 +146,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
.program = &rpcb_program,
.version = version,
.authflavor = RPC_AUTH_UNIX,
- .flags = RPC_CLNT_CREATE_NOPING,
+ .flags = (RPC_CLNT_CREATE_NOPING |
+ RPC_CLNT_CREATE_NONPRIVPORT),
};
switch (srvaddr->sa_family) {
@@ -161,8 +161,6 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
return NULL;
}
- if (!privileged)
- args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
return rpc_create(&args);
}
@@ -251,7 +249,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
__FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
- sizeof(*sin), prot, RPCBVERS_2, 0);
+ sizeof(*sin), prot, RPCBVERS_2);
if (IS_ERR(rpcb_clnt))
return PTR_ERR(rpcb_clnt);
@@ -361,7 +359,7 @@ void rpcb_getport_async(struct rpc_task *task)
task->tk_pid, __FUNCTION__, bind_version);
rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
- bind_version, 0);
+ bind_version);
if (IS_ERR(rpcb_clnt)) {
status = PTR_ERR(rpcb_clnt);
dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 17/24] SUNRPC: Refactor rpcb_register to make rpcbindv4 support easier
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (15 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 16/24] SUNRPC: None of rpcb_create's callers wants a privileged ephemeral port Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 18/24] SUNRPC: introduce new task flag that fails requests on xprt disconnect Chuck Lever
` (7 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
rpcbindv4 registration will reuse part of rpcb_register, so just split it out
into a separate function now.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 48 ++++++++++++++++++++++++++++++------------------
1 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 8590f4a..eb2bffe 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -164,6 +164,30 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
return rpc_create(&args);
}
+static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
+ u32 version, struct rpc_message *msg,
+ int *result)
+{
+ struct rpc_clnt *rpcb_clnt;
+ int error = 0;
+
+ *result = 0;
+
+ rpcb_clnt = rpcb_create_local(addr, addrlen, version);
+ if (!IS_ERR(rpcb_clnt)) {
+ error = rpc_call_sync(rpcb_clnt, msg, 0);
+ rpc_shutdown_client(rpcb_clnt);
+ } else
+ error = PTR_ERR(rpcb_clnt);
+
+ if (error < 0)
+ printk(KERN_WARNING "RPC: failed to contact local rpcbind "
+ "server (errno %d).\n", -error);
+ dprintk("RPC: registration status %d/%d\n", error, *result);
+
+ return error;
+}
+
/**
* rpcb_register - set or unset a port registration with the local rpcbind svc
* @prog: RPC program number to bind
@@ -185,33 +209,21 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
.r_port = port,
};
struct rpc_message msg = {
- .rpc_proc = &rpcb_procedures2[port ?
- RPCBPROC_SET : RPCBPROC_UNSET],
.rpc_argp = &map,
.rpc_resp = okay,
};
- struct rpc_clnt *rpcb_clnt;
- int error = 0;
dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
"rpcbind\n", (port ? "" : "un"),
prog, vers, prot, port);
- rpcb_clnt = rpcb_create_local((struct sockaddr *)&rpcb_inaddr_loopback,
- sizeof(rpcb_inaddr_loopback),
- RPCBVERS_2);
- if (!IS_ERR(rpcb_clnt)) {
- error = rpc_call_sync(rpcb_clnt, &msg, 0);
- rpc_shutdown_client(rpcb_clnt);
- } else
- error = PTR_ERR(rpcb_clnt);
+ msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
+ if (port)
+ msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
- if (error < 0)
- printk(KERN_WARNING "RPC: failed to contact local rpcbind "
- "server (errno %d).\n", -error);
- dprintk("RPC: registration status %d/%d\n", error, *okay);
-
- return error;
+ return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
+ sizeof(rpcb_inaddr_loopback),
+ RPCBVERS_2, &msg, okay);
}
/**
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 18/24] SUNRPC: introduce new task flag that fails requests on xprt disconnect
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (16 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 17/24] SUNRPC: Refactor rpcb_register to make rpcbindv4 support easier Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:28 ` [PATCH 19/24] SUNRPC: Quickly detect missing portmapper during RPC service registration Chuck Lever
` (6 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Introduce a new RPC client capability that allows RPC consumers to specify
that if a connection cannot be established to the remote RPC service, a
submitted request should fail immediately.
Useful for in-kernel RPC applications that want to connect and do just one
or a handful of idempotent requests, but don't want any long waits if the
remote service is not available.
No, Tom, I'm not going to call it "squishy." :-)
Note that because the UDP transport uses an unconnected socket, this new
flag is a no-op.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/sched.h | 2 ++
net/sunrpc/clnt.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 7190d7a..54d0f3e 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -137,6 +137,7 @@ struct rpc_task_setup {
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
#define RPC_TASK_KILLED 0x0100 /* task was killed */
#define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */
+#define RPC_TASK_ONESHOT 0x0400 /* fail if can't connect */
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
@@ -144,6 +145,7 @@ struct rpc_task_setup {
#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL)
#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
+#define RPC_IS_ONESHOT(t) ((t)->tk_flags & RPC_TASK_ONESHOT)
#define RPC_TASK_RUNNING 0
#define RPC_TASK_QUEUED 1
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index dd39a39..a8bb701 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1016,6 +1016,8 @@ call_connect_status(struct rpc_task *task)
switch (status) {
case -ENOTCONN:
+ if (RPC_IS_ONESHOT(task))
+ break;
case -EAGAIN:
task->tk_action = call_bind;
if (!RPC_IS_SOFT(task))
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 19/24] SUNRPC: Quickly detect missing portmapper during RPC service registration
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (17 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 18/24] SUNRPC: introduce new task flag that fails requests on xprt disconnect Chuck Lever
@ 2008-04-14 16:28 ` Chuck Lever
2008-04-14 16:29 ` [PATCH 20/24] SUNRPC: Support registering IPv6 interfaces with local rpcbind daemon Chuck Lever
` (5 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:28 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Currently the in-kernel RPC server uses an unconnected UDP socket to
contact the local user-space portmapper daemon because UDP is less
overhead than TCP. However, attempting to register or unregister a
local RPC service with a portmapper that isn't listening for requests
results in a long timeout wait (35 seconds per request, by my
calculations).
Using TCP, the absence of a listener results in an immediate ECONNREFUSED.
Setting the ONESHOT flag causes the RPC client to fail RPC requests as soon
as this occurs.
Therefore, this patch changes rpcb_register() to use TCP to contact the
local portmapper. Starting up in-kernel RPC services should no longer
hang if there is no local portmapper listening for requests.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 22 ++++++++++++++++++++--
1 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index eb2bffe..4a85bf5 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -67,6 +67,12 @@ enum {
#define RPCB_OWNER_STRING "rpcb"
#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
+/*
+ * Number of seconds before timing out a registration request
+ * to our local user space rpcbind daemon.
+ */
+#define RPCB_REGISTER_TO_SECS (10UL)
+
static void rpcb_getport_done(struct rpc_task *, void *);
static struct rpc_program rpcb_program;
@@ -118,14 +124,26 @@ static const struct sockaddr_in rpcb_inaddr_loopback = {
.sin_port = htons(RPCBIND_PORT),
};
+/*
+ * TCP is always used to contact the local rpcbind daemon because we
+ * get an immediate indication of whether there is a remote listener
+ * when a connection is attempted.
+ */
+static const struct rpc_timeout rpcb_local_tcp_timeout = {
+ .to_initval = RPCB_REGISTER_TO_SECS * HZ,
+ .to_maxval = RPCB_REGISTER_TO_SECS * HZ,
+ .to_retries = 0,
+};
+
static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
size_t addrlen, u32 version)
{
struct rpc_create_args args = {
- .protocol = XPRT_TRANSPORT_UDP,
+ .protocol = XPRT_TRANSPORT_TCP,
.address = addr,
.addrsize = addrlen,
.servername = "localhost",
+ .timeout = &rpcb_local_tcp_timeout,
.program = &rpcb_program,
.version = version,
.authflavor = RPC_AUTH_UNIX,
@@ -175,7 +193,7 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
rpcb_clnt = rpcb_create_local(addr, addrlen, version);
if (!IS_ERR(rpcb_clnt)) {
- error = rpc_call_sync(rpcb_clnt, msg, 0);
+ error = rpc_call_sync(rpcb_clnt, msg, RPC_TASK_ONESHOT);
rpc_shutdown_client(rpcb_clnt);
} else
error = PTR_ERR(rpcb_clnt);
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 20/24] SUNRPC: Support registering IPv6 interfaces with local rpcbind daemon
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (18 preceding siblings ...)
2008-04-14 16:28 ` [PATCH 19/24] SUNRPC: Quickly detect missing portmapper during RPC service registration Chuck Lever
@ 2008-04-14 16:29 ` Chuck Lever
2008-04-14 16:29 ` [PATCH 21/24] SUNRPC: Split portmap unregister API into separate function Chuck Lever
` (4 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:29 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Introduce a new API to register RPC services on IPv6 interfaces to allow
the NFS server and lockd to advertise on IPv6 networks.
Unlike rpcb_register(), the new rpcb_v4_register() function uses rpcbind
protocol version 4 to contact the local rpcbind daemon. The version 4
SET/UNSET procedures allow services to register address families besides
AF_INET, register at specific network interfaces, and register transport
protocols besides UDP and TCP. All of this functionality is exposed via
the new rpcb_v4_register() kernel API.
A user-space rpcbind daemon implementation that supports version 4 of the
rpcbind protocol is required in order to make use of this new API.
Note that rpcbind version 3 is sufficient to support the new rpcbind
facilities listed above, but most extant implementations use version 4.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/clnt.h | 3 +
net/sunrpc/rpcb_clnt.c | 136 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 139 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 129a86e..919b1ea 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -123,6 +123,9 @@ void rpc_shutdown_client(struct rpc_clnt *);
void rpc_release_client(struct rpc_clnt *);
int rpcb_register(u32, u32, int, unsigned short, int *);
+int rpcb_v4_register(const u32 program, const u32 version,
+ const struct sockaddr *address,
+ const char *netid, int *result);
int rpcb_getport_sync(struct sockaddr_in *, u32, u32, int);
void rpcb_getport_async(struct rpc_task *);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 4a85bf5..849b4f7 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -90,6 +90,7 @@ struct rpcbind_args {
static struct rpc_procinfo rpcb_procedures2[];
static struct rpc_procinfo rpcb_procedures3[];
+static struct rpc_procinfo rpcb_procedures4[];
struct rpcb_info {
u32 rpc_vers;
@@ -124,6 +125,12 @@ static const struct sockaddr_in rpcb_inaddr_loopback = {
.sin_port = htons(RPCBIND_PORT),
};
+static const struct sockaddr_in6 rpcb_in6addr_loopback = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = IN6ADDR_LOOPBACK_INIT,
+ .sin6_port = htons(RPCBIND_PORT),
+};
+
/*
* TCP is always used to contact the local rpcbind daemon because we
* get an immediate indication of whether there is a remote listener
@@ -244,6 +251,135 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
RPCBVERS_2, &msg, okay);
}
+/*
+ * Fill in AF_INET family-specific arguments to register
+ */
+static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
+ struct rpc_message *msg)
+{
+ struct rpcbind_args *map = msg->rpc_argp;
+ unsigned short port = ntohs(address_to_register->sin_port);
+ char buf[32];
+
+ /* Construct AF_INET universal address */
+ snprintf(buf, sizeof(buf),
+ NIPQUAD_FMT".%u.%u",
+ NIPQUAD(address_to_register->sin_addr.s_addr),
+ port >> 8, port & 0xff);
+ map->r_addr = buf;
+
+ dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
+ "local rpcbind\n", (port ? "" : "un"),
+ map->r_prog, map->r_vers,
+ map->r_addr, map->r_netid);
+
+ msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
+ if (port)
+ msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
+
+ return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
+ sizeof(rpcb_inaddr_loopback),
+ RPCBVERS_4, msg, msg->rpc_resp);
+}
+
+/*
+ * Fill in AF_INET6 family-specific arguments to register
+ */
+static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
+ struct rpc_message *msg)
+{
+ struct rpcbind_args *map = msg->rpc_argp;
+ unsigned short port = ntohs(address_to_register->sin6_port);
+ char buf[64];
+
+ /* Construct AF_INET6 universal address */
+ snprintf(buf, sizeof(buf),
+ NIP6_FMT".%u.%u",
+ NIP6(address_to_register->sin6_addr),
+ port >> 8, port & 0xff);
+ map->r_addr = buf;
+
+ dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
+ "local rpcbind\n", (port ? "" : "un"),
+ map->r_prog, map->r_vers,
+ map->r_addr, map->r_netid);
+
+ msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
+ if (port)
+ msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
+
+ return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
+ sizeof(rpcb_in6addr_loopback),
+ RPCBVERS_4, msg, msg->rpc_resp);
+}
+
+/**
+ * rpcb_v4_register - set or unset a port registration with the local rpcbind
+ * @program: RPC program number of service to (un)register
+ * @version: RPC version number of service to (un)register
+ * @address: family, IP address, and port to (un)register
+ * @netid: netid of transport protocol to (un)register
+ * @result: result code from rpcbind RPC call
+ *
+ * Called by server-side RPC consumers to advertise an RPC-based service
+ * via the system's rpcbind daemon. Callers must call this routine once for
+ * each [program, version, address, netid] tuple they wish to advertise.
+ * A unique address family counts as a separate address, thus a service must
+ * register AF_INET and AF_INET6 service addresses separately.
+ *
+ * Callers may also unregister their RPC services by setting the port
+ * number in the passed-in address to zero. Callers can pass "" for
+ * @netid to unregister all transport netids associated with [program,
+ * version, address].
+ *
+ * Returns zero if the registration request was dispatched successfully.
+ * The rpcbind daemon's result code is stored in *result.
+ *
+ * Returns an errno value and sets *result to zero if there was some
+ * problem that prevented the rpcbind request from being dispatched.
+ *
+ * This function uses rpcbind protocol version 4 to contact the local
+ * rpcbind daemon. The local rpcbind daemon must support version 4 of the
+ * rpcbind protocol in order for these functions to return success.
+ *
+ * Version 4 SET/UNSET procedures allow services to register address
+ * families besides AF_INET, register at specific network interfaces, and
+ * register transport protocols besides UDP and TCP.
+ *
+ * The contents of @address determine the address family and the port to be
+ * registered. The usual practice is to pass in INADDR_ANY as the raw
+ * address, but specifying a non-zero address is supported by this API if
+ * the caller wishes to advertise a service on a specific network interface.
+ */
+int rpcb_v4_register(const u32 program, const u32 version,
+ const struct sockaddr *address, const char *netid,
+ int *result)
+{
+ struct rpcbind_args map = {
+ .r_prog = program,
+ .r_vers = version,
+ .r_netid = netid,
+ .r_owner = RPCB_OWNER_STRING,
+ };
+ struct rpc_message msg = {
+ .rpc_argp = &map,
+ .rpc_resp = result,
+ };
+
+ *result = 0;
+
+ switch (address->sa_family) {
+ case AF_INET:
+ return rpcb_register_netid4((struct sockaddr_in *)address,
+ &msg);
+ case AF_INET6:
+ return rpcb_register_netid6((struct sockaddr_in6 *)address,
+ &msg);
+ }
+
+ return -EAFNOSUPPORT;
+}
+
/**
* rpcb_getport_sync - obtain the port for an RPC service on a given host
* @sin: address of remote peer
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 21/24] SUNRPC: Split portmap unregister API into separate function
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (19 preceding siblings ...)
2008-04-14 16:29 ` [PATCH 20/24] SUNRPC: Support registering IPv6 interfaces with local rpcbind daemon Chuck Lever
@ 2008-04-14 16:29 ` Chuck Lever
2008-04-14 16:29 ` [PATCH 22/24] SUNRPC: Use the new rpcb_v4_register() API in svc_unregister() Chuck Lever
` (3 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:29 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Registering RPC services with the local portmapper is sufficiently
different from unregistering them that providing a separate API for each
makes sense.
The mechanics of and API for registering and unregistering RPC services
will diverge further as support for IPv6 is added.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/svc.h | 1 +
net/sunrpc/svc.c | 66 +++++++++++++++++++++++++++++++++-----------
2 files changed, 51 insertions(+), 16 deletions(-)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 64c9755..48ad59c 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -395,6 +395,7 @@ int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
void svc_destroy(struct svc_serv *);
int svc_process(struct svc_rqst *);
int svc_register(struct svc_serv *, int, unsigned short);
+void svc_unregister(const struct svc_serv *serv);
void svc_wake_up(struct svc_serv *);
void svc_reserve(struct svc_rqst *rqstp, int space);
struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 86a5b56..576efa7 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -420,9 +420,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
spin_lock_init(&pool->sp_lock);
}
-
/* Remove any stale portmap registrations */
- svc_register(serv, 0, 0);
+ svc_unregister(serv);
return serv;
}
@@ -490,8 +489,7 @@ svc_destroy(struct svc_serv *serv)
if (svc_serv_is_pooled(serv))
svc_pool_map_put();
- /* Unregister service with the portmapper */
- svc_register(serv, 0, 0);
+ svc_unregister(serv);
kfree(serv->sv_pools);
kfree(serv);
}
@@ -753,21 +751,21 @@ svc_exit_thread(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL(svc_exit_thread);
-/*
- * Register an RPC service with the local portmapper.
- * To unregister a service, call this routine with
- * proto and port == 0.
+/**
+ * svc_register - register an RPC service with the local portmapper
+ * @serv: svc_serv struct for the service to register
+ * @protocol: transport protocol number to advertise
+ * @port: port to advertise
+ *
*/
int
svc_register(struct svc_serv *serv, int proto, unsigned short port)
{
struct svc_program *progp;
- unsigned long flags;
unsigned int i;
int error = 0, dummy;
- if (!port)
- clear_thread_flag(TIF_SIGPENDING);
+ BUG_ON(proto == 0 && port == 0);
for (progp = serv->sv_program; progp; progp = progp->pg_next) {
for (i = 0; i < progp->pg_nvers; i++) {
@@ -795,13 +793,49 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
}
}
- if (!port) {
- spin_lock_irqsave(¤t->sighand->siglock, flags);
- recalc_sigpending();
- spin_unlock_irqrestore(¤t->sighand->siglock, flags);
+ return error;
+}
+
+static void __svc_unregister(struct svc_program *program, u32 version)
+{
+ int error, boolean = 0;
+
+ error = rpcb_register(program->pg_prog, version, 0, 0, &boolean);
+ dprintk("svc: svc_unregister(%sv%u), error %d, %s\n",
+ program->pg_name, version, error,
+ (boolean ? "succeeded" : "failed"));
+}
+
+/**
+ * svc_unregister - remove an RPC server from the local rpcbind database
+ * @serv: svc_serv struct for the service to register
+ *
+ * All transport protocols and ports for this service are removed from
+ * the local rpcbind database. The result of unregistration is reported
+ * via dprintk for those who want verification of the result, but is
+ * otherwise not important.
+ */
+void svc_unregister(const struct svc_serv *serv)
+{
+ struct svc_program *program;
+ unsigned long flags;
+ u32 version;
+
+ clear_thread_flag(TIF_SIGPENDING);
+
+ for (program = serv->sv_program; program; program = program->pg_next) {
+ for (version = 0; version < program->pg_nvers; version++) {
+ if (program->pg_vers[version] == NULL)
+ continue;
+ if (program->pg_vers[version]->vs_hidden)
+ continue;
+ __svc_unregister(program, version);
+ }
}
- return error;
+ spin_lock_irqsave(¤t->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(¤t->sighand->siglock, flags);
}
/*
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 22/24] SUNRPC: Use the new rpcb_v4_register() API in svc_unregister()
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (20 preceding siblings ...)
2008-04-14 16:29 ` [PATCH 21/24] SUNRPC: Split portmap unregister API into separate function Chuck Lever
@ 2008-04-14 16:29 ` Chuck Lever
2008-04-14 16:29 ` [PATCH 23/24] SUNRPC: Use new rpcb_v4_register() interface in svc_register() Chuck Lever
` (2 subsequent siblings)
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:29 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Unregister both AF_INET and AF_INET6 capabilities for a service advertised
in the local rpcbind database.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/svc.c | 37 +++++++++++++++++++++++++++++++++----
1 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 576efa7..42f83b4 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -28,6 +28,18 @@
#define RPCDBG_FACILITY RPCDBG_SVCDSP
+#ifdef CONFIG_SUNRPC_REGISTER_V4
+static const struct sockaddr_in svc_inaddr_any = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = htonl(INADDR_ANY),
+};
+
+static const struct sockaddr_in6 svc_in6addr_any = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = IN6ADDR_ANY_INIT,
+};
+#endif
+
#define svc_serv_is_pooled(serv) ((serv)->sv_function)
/*
@@ -800,20 +812,37 @@ static void __svc_unregister(struct svc_program *program, u32 version)
{
int error, boolean = 0;
+#ifdef CONFIG_SUNRPC_REGISTER_V4
+ error = rpcb_v4_register(program->pg_prog, version,
+ (struct sockaddr *)&svc_inaddr_any,
+ "", &boolean);
+ dprintk("svc: svc_unregister(%sv%u, AF_INET), error %d, %s\n",
+ program->pg_name, version, error,
+ (boolean ? "succeeded" : "failed"));
+
+ boolean = 0;
+ error = rpcb_v4_register(program->pg_prog, version,
+ (struct sockaddr *)&svc_in6addr_any,
+ "", &boolean);
+ dprintk("svc: svc_unregister(%sv%u, AF_INET6), error %d, %s\n",
+ program->pg_name, version, error,
+ (boolean ? "succeeded" : "failed"));
+#else
error = rpcb_register(program->pg_prog, version, 0, 0, &boolean);
dprintk("svc: svc_unregister(%sv%u), error %d, %s\n",
program->pg_name, version, error,
(boolean ? "succeeded" : "failed"));
+#endif
}
/**
* svc_unregister - remove an RPC server from the local rpcbind database
* @serv: svc_serv struct for the service to register
*
- * All transport protocols and ports for this service are removed from
- * the local rpcbind database. The result of unregistration is reported
- * via dprintk for those who want verification of the result, but is
- * otherwise not important.
+ * All address families, transport protocols, and ports for this service
+ * are removed from the local rpcbind database. The result of unregis-
+ * tration is reported via dprintk for those who want verification of the
+ * result, but is otherwise not important.
*/
void svc_unregister(const struct svc_serv *serv)
{
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 23/24] SUNRPC: Use new rpcb_v4_register() interface in svc_register()
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (21 preceding siblings ...)
2008-04-14 16:29 ` [PATCH 22/24] SUNRPC: Use the new rpcb_v4_register() API in svc_unregister() Chuck Lever
@ 2008-04-14 16:29 ` Chuck Lever
2008-04-14 16:29 ` [PATCH 24/24] SUNRPC: Add kernel build option to disable server-side use of rpcbind v3/v4 Chuck Lever
2008-04-14 19:14 ` [PATCH 00/24] RPC server support rpcbind v4 plus additional clean ups J. Bruce Fields
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:29 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
In order to advertise NFS-related services on IPv6 interfaces via
rpcbind, the Linux RPC server implementation must use
rpcb_v4_register() instead of rpcb_register().
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/sunrpc/svc.h | 5 ++-
net/sunrpc/svc.c | 86 +++++++++++++++++++++++++++++++++++---------
net/sunrpc/svcsock.c | 3 +-
3 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 48ad59c..9cf11ea 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -394,7 +394,10 @@ struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
void svc_destroy(struct svc_serv *);
int svc_process(struct svc_rqst *);
-int svc_register(struct svc_serv *, int, unsigned short);
+int svc_register(const struct svc_serv *serv,
+ const unsigned short family,
+ const unsigned short protocol,
+ const unsigned short port);
void svc_unregister(const struct svc_serv *serv);
void svc_wake_up(struct svc_serv *);
void svc_reserve(struct svc_rqst *rqstp, int space);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 42f83b4..d31f0ff 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -763,45 +763,95 @@ svc_exit_thread(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL(svc_exit_thread);
+static int __svc_register(const u32 program, const u32 version,
+ const unsigned short family,
+ const unsigned short protocol,
+ const unsigned short port)
+{
+ int error, result;
+
+#ifdef CONFIG_SUNRPC_REGISTER_V4
+ struct sockaddr_storage any_addr;
+ char *netid;
+
+ switch (family) {
+ case AF_INET: {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&any_addr;
+ memcpy(sin, &svc_inaddr_any, sizeof(svc_inaddr_any));
+ sin->sin_port = htons(port);
+
+ if (protocol == IPPROTO_UDP)
+ netid = RPCBIND_NETID_UDP;
+ else
+ netid = RPCBIND_NETID_TCP;
+ break;
+ }
+ case AF_INET6: {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&any_addr;
+ memcpy(sin6, &svc_in6addr_any, sizeof(svc_in6addr_any));
+ sin6->sin6_port = htons(port);
+
+ if (protocol == IPPROTO_UDP)
+ netid = RPCBIND_NETID_UDP6;
+ else
+ netid = RPCBIND_NETID_TCP6;
+ break;
+ }
+ default:
+ return -EAFNOSUPPORT;
+ }
+
+ error = rpcb_v4_register(program, version,
+ (struct sockaddr *)&any_addr,
+ netid, &result);
+#else
+ error = rpcb_register(program, version, protocol, port, &result);
+#endif
+
+ if (!result)
+ error = -EACCES;
+
+ return error;
+}
+
/**
* svc_register - register an RPC service with the local portmapper
* @serv: svc_serv struct for the service to register
+ * @family: address family to register
* @protocol: transport protocol number to advertise
* @port: port to advertise
*
+ * Service is registered for any address in given address family
*/
-int
-svc_register(struct svc_serv *serv, int proto, unsigned short port)
+int svc_register(const struct svc_serv *serv, const unsigned short family,
+ const unsigned short protocol, const unsigned short port)
{
- struct svc_program *progp;
- unsigned int i;
- int error = 0, dummy;
+ struct svc_program *progp;
+ u32 version;
+ int error = 0;
- BUG_ON(proto == 0 && port == 0);
+ BUG_ON(protocol == 0 && port == 0);
for (progp = serv->sv_program; progp; progp = progp->pg_next) {
- for (i = 0; i < progp->pg_nvers; i++) {
- if (progp->pg_vers[i] == NULL)
+ for (version = 0; version < progp->pg_nvers; version++) {
+ if (progp->pg_vers[version] == NULL)
continue;
- dprintk("svc: svc_register(%s, %s, %d, %d)%s\n",
+ dprintk("svc: svc_register(%s, %u, %s, %u)%s\n",
progp->pg_name,
- proto == IPPROTO_UDP? "udp" : "tcp",
+ version,
+ protocol == IPPROTO_UDP? "udp" : "tcp",
port,
- i,
- progp->pg_vers[i]->vs_hidden?
+ progp->pg_vers[version]->vs_hidden?
" (but not telling portmap)" : "");
- if (progp->pg_vers[i]->vs_hidden)
+ if (progp->pg_vers[version]->vs_hidden)
continue;
- error = rpcb_register(progp->pg_prog, i, proto, port, &dummy);
+ error = __svc_register(progp->pg_prog, version,
+ family, protocol, port);
if (error < 0)
break;
- if (port && !dummy) {
- error = -EACCES;
- break;
- }
}
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 51357a3..54a829a 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1128,9 +1128,8 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
inet = sock->sk;
- /* Register socket with portmapper */
if (*errp >= 0 && pmap_register)
- *errp = svc_register(serv, inet->sk_protocol,
+ *errp = svc_register(serv, inet->sk_family, inet->sk_protocol,
ntohs(inet_sk(inet)->sport));
if (*errp < 0) {
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 24/24] SUNRPC: Add kernel build option to disable server-side use of rpcbind v3/v4
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (22 preceding siblings ...)
2008-04-14 16:29 ` [PATCH 23/24] SUNRPC: Use new rpcb_v4_register() interface in svc_register() Chuck Lever
@ 2008-04-14 16:29 ` Chuck Lever
2008-04-14 19:14 ` [PATCH 00/24] RPC server support rpcbind v4 plus additional clean ups J. Bruce Fields
24 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 16:29 UTC (permalink / raw)
To: bfields, trond.myklebust; +Cc: linux-nfs
Allow distributions to use the legacy behavior until they integrate an
appropriate user-space rpcbind daemon that can support IPv6 RPC services.
I tried adding some logic to fall back if (un)registering with a v4
protocol request failed, but there are too many corner cases. So I just
made it a compile-time switch that distributions can throw when they've
replaced portmapper with rpcbind.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/Kconfig | 30 ++++++++++++++++++++++++++++--
1 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/fs/Kconfig b/fs/Kconfig
index f1bc33f..56e6fa5 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1772,7 +1772,7 @@ config SUNRPC_XPRT_RDMA
If unsure, say N.
config SUNRPC_BIND34
- bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)"
+ bool "Support for rpcbind v3 & v4 queries (EXPERIMENTAL)"
depends on SUNRPC && EXPERIMENTAL
default n
help
@@ -1785,13 +1785,39 @@ config SUNRPC_BIND34
querying rpcbind servers via versions 3 and 4 of the rpcbind
protocol. The kernel automatically falls back to version 2
if a remote rpcbind service does not support versions 3 or 4.
+
By themselves, these new versions do not provide support for
RPC over IPv6, but the new protocol versions are necessary to
- support it.
+ support it. Enabling this option is required to support
+ mounting NFS servers over IPv6 networks.
If unsure, say N to get traditional behavior (version 2 rpcbind
requests only).
+config SUNRPC_REGISTER_V4
+ bool "Register local RPC services via rpcbind v4 (EXPERIMENTAL)"
+ depends on SUNRPC && EXPERIMENTAL
+ default n
+ help
+ RPC requests over IPv6 networks require support for larger
+ addresses when performing an RPC bind. Sun added support for
+ registering RPC services at an IPv6 address by creating two
+ new versions of the rpcbind protocol (RFC 1833).
+
+ This option enables support in the kernel RPC server for
+ registering local RPC services via version 4 of the rpcbind
+ protocol. If you enable this option, you must run a user
+ space portmapper daemon capable of understanding rpcbind
+ protocol version 4.
+
+ If unsure, say N to get traditional behavior (register local
+ services using only rpcbind version 2).
+
+ Enabling this option and using a portmapper capable of
+ responding to rpcbind version 4 requests is required to support
+ serving NFS requests over IPv6 networks. Distributions using
+ the legacy Linux portmapper daemon must say N here.
+
config RPCSEC_GSS_KRB5
tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
depends on SUNRPC && EXPERIMENTAL
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 00/24] RPC server support rpcbind v4 plus additional clean ups
[not found] ` <20080414162108.12741.73233.stgit-meopP2rzCrTwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (23 preceding siblings ...)
2008-04-14 16:29 ` [PATCH 24/24] SUNRPC: Add kernel build option to disable server-side use of rpcbind v3/v4 Chuck Lever
@ 2008-04-14 19:14 ` J. Bruce Fields
2008-04-14 20:05 ` Chuck Lever
24 siblings, 1 reply; 38+ messages in thread
From: J. Bruce Fields @ 2008-04-14 19:14 UTC (permalink / raw)
To: Chuck Lever; +Cc: trond.myklebust, linux-nfs
On Mon, Apr 14, 2008 at 12:26:38PM -0400, Chuck Lever wrote:
> Hi Bruce, Trond -
>
> This patch series provides some minor clean ups, and finishes with an
> implementation of support for rpcbind version 4 registration. Version 4
> support can be entirely disabled in favor of legacy behavior with a kernel
> build option, and the default is to use rpcbind version 2 when registering
> kernel RPC services.
>
> There are 24 patches in this series, but only a few are more than trivial and
> hopefully fewer yet are controversial. I've tried to split these so that
> server side and client side changes are in separate patches.
>
> It would be helpful for me if they could be considered for 2.6.26.
Thanks. I've applied 3, 7, 9, and 10, and I'm mostly assuming the
others are Somebody Else's Problem for now. Please feel free to correct
that idea.
--b.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 00/24] RPC server support rpcbind v4 plus additional clean ups
2008-04-14 19:14 ` [PATCH 00/24] RPC server support rpcbind v4 plus additional clean ups J. Bruce Fields
@ 2008-04-14 20:05 ` Chuck Lever
0 siblings, 0 replies; 38+ messages in thread
From: Chuck Lever @ 2008-04-14 20:05 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: trond.myklebust, linux-nfs
On Apr 14, 2008, at 3:14 PM, J. Bruce Fields wrote:
> On Mon, Apr 14, 2008 at 12:26:38PM -0400, Chuck Lever wrote:
>> Hi Bruce, Trond -
>>
>> This patch series provides some minor clean ups, and finishes with an
>> implementation of support for rpcbind version 4 registration.
>> Version 4
>> support can be entirely disabled in favor of legacy behavior with a
>> kernel
>> build option, and the default is to use rpcbind version 2 when
>> registering
>> kernel RPC services.
>>
>> There are 24 patches in this series, but only a few are more than
>> trivial and
>> hopefully fewer yet are controversial. I've tried to split these
>> so that
>> server side and client side changes are in separate patches.
>>
>> It would be helpful for me if they could be considered for 2.6.26.
>
> Thanks. I've applied 3, 7, 9, and 10, and I'm mostly assuming the
> others are Somebody Else's Problem for now. Please feel free to
> correct
> that idea.
At least for now, review of the last 4 patches in the series would be
useful. Those go against net/sunrpc/svc.c, which I assume is your
bailiwick.
Naturally they don't make any sense to apply if the preceding patches
against net/sunrpc/rpcb_clnt.c aren't accepted.
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
^ permalink raw reply [flat|nested] 38+ messages in thread