Linux NFS development
 help / color / mirror / Atom feed
* referrals
@ 2008-05-09  1:19 J. Bruce Fields
  2008-05-09  5:10 ` referrals Trond Myklebust
  0 siblings, 1 reply; 36+ messages in thread
From: J. Bruce Fields @ 2008-05-09  1:19 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-nfs, Manoj Naik

An attempt to follow an nfsv4 referral is leading to a hang.  I'm doing
an "ls" on the absent directory.  A network trace shows the server
returning with a sane-looking response to the getattr of fs_locations.
I've appended the part of the sysrq-t trace for "ls".  Any ideas?

--b.

May  8 19:33:02 piglet2 kernel: ls            D 00000046     0  3023   3006
May  8 19:33:02 piglet2 kernel:        ce527870 00000046 cf9181f0 00000046 00000000 00000000 cf9181f0 cf918450
May  8 19:33:02 piglet2 kernel:        cf918450 ce527850 c013976d c1201b88 00000246 ce527860 cf14a4c0 ce5278a8
May  8 19:33:02 piglet2 kernel:        c1201b88 ce527878 ce5278a0 00000000 ce5278a8 ce527878 c053b497 ce527894
May  8 19:33:02 piglet2 kernel: Call Trace:
May  8 19:33:02 piglet2 kernel:  [<c013976d>] ? trace_hardirqs_on+0x9d/0x110
May  8 19:33:02 piglet2 kernel:  [<c053b497>] rpc_wait_bit_killable+0x17/0x30
May  8 19:33:02 piglet2 kernel:  [<c058a045>] __wait_on_bit+0x55/0x80
May  8 19:33:02 piglet2 kernel:  [<c053b480>] ? rpc_wait_bit_killable+0x0/0x30
May  8 19:33:02 piglet2 kernel:  [<c053b480>] ? rpc_wait_bit_killable+0x0/0x30
May  8 19:33:02 piglet2 kernel:  [<c058a0b8>] out_of_line_wait_on_bit+0x48/0x50
May  8 19:33:02 piglet2 kernel:  [<c012f5b0>] ? wake_bit_function+0x0/0x50
May  8 19:33:02 piglet2 kernel:  [<c053be87>] __rpc_execute+0xa7/0x240
May  8 19:33:02 piglet2 kernel:  [<c053c047>] rpc_execute+0x17/0x20
May  8 19:33:02 piglet2 kernel:  [<c0534a25>] rpc_run_task+0x25/0x60
May  8 19:33:02 piglet2 kernel:  [<c0534b01>] rpc_call_sync+0x41/0x60
May  8 19:33:02 piglet2 kernel:  [<c0534b63>] rpc_ping+0x43/0x60
May  8 19:33:02 piglet2 kernel:  [<c053662c>] rpc_create+0x46c/0x510
May  8 19:33:02 piglet2 kernel:  [<c0139da2>] ? __lock_acquire+0x4b2/0xc30
May  8 19:33:02 piglet2 kernel:  [<c053cb61>] ? rpcauth_lookup_credcache+0xe1/0x220
May  8 19:33:02 piglet2 kernel:  [<c021ee18>] nfs_create_rpc_client+0xa8/0xe0
May  8 19:33:02 piglet2 kernel:  [<c058bbd7>] ? _spin_unlock+0x27/0x40
May  8 19:33:02 piglet2 kernel:  [<c021f547>] nfs4_set_client+0x67/0x170
May  8 19:33:02 piglet2 kernel:  [<c021fd6b>] nfs4_create_referral_server+0x7b/0x230
May  8 19:33:02 piglet2 kernel:  [<c0139da2>] ? __lock_acquire+0x4b2/0xc30
May  8 19:33:02 piglet2 last message repeated 2 times
May  8 19:33:02 piglet2 kernel:  [<c0165430>] ? poison_obj+0x20/0x40
May  8 19:33:02 piglet2 kernel:  [<c0228f91>] nfs4_referral_get_sb+0x31/0x190
May  8 19:33:02 piglet2 kernel:  [<c013976d>] ? trace_hardirqs_on+0x9d/0x110
May  8 19:33:02 piglet2 kernel:  [<c0165882>] ? check_poison_obj+0x22/0x1b0
May  8 19:33:02 piglet2 kernel:  [<c0165430>] ? poison_obj+0x20/0x40
May  8 19:33:02 piglet2 kernel:  [<c0165131>] ? dbg_redzone1+0x11/0x20
May  8 19:33:02 piglet2 kernel:  [<c0181375>] ? alloc_vfsmnt+0xd5/0x110
May  8 19:33:02 piglet2 kernel:  [<c0165a81>] ? cache_alloc_debugcheck_after+0x71/0x1a0
May  8 19:33:02 piglet2 kernel:  [<c01671b0>] ? __kmalloc+0x100/0x140
May  8 19:33:02 piglet2 kernel:  [<c016716e>] ? __kmalloc+0xbe/0x140
May  8 19:33:02 piglet2 kernel:  [<c0181375>] ? alloc_vfsmnt+0xd5/0x110
May  8 19:33:02 piglet2 kernel:  [<c0181375>] ? alloc_vfsmnt+0xd5/0x110
May  8 19:33:02 piglet2 kernel:  [<c016bc33>] vfs_kern_mount+0x53/0x120
May  8 19:33:02 piglet2 kernel:  [<c02464fd>] nfs_do_refmount+0x65d/0x680
May  8 19:33:02 piglet2 kernel:  [<c02317b2>] nfs_follow_mountpoint+0x232/0x410
May  8 19:33:02 piglet2 kernel:  [<c058bbd7>] ? _spin_unlock+0x27/0x40
May  8 19:33:02 piglet2 kernel:  [<c018017d>] ? mnt_drop_write+0x5d/0x120
May  8 19:33:02 piglet2 kernel:  [<c0174bb4>] do_follow_link+0x104/0x300
May  8 19:33:02 piglet2 kernel:  [<c017294c>] ? do_lookup+0x5c/0x170
May  8 19:33:02 piglet2 kernel:  [<c0172fd5>] __link_path_walk+0x575/0x7e0
May  8 19:33:02 piglet2 kernel:  [<c0173286>] path_walk+0x46/0xb0
May  8 19:33:02 piglet2 kernel:  [<c01734b8>] do_path_lookup+0x68/0x160
May  8 19:33:02 piglet2 kernel:  [<c017183d>] ? getname+0x9d/0xb0
May  8 19:33:02 piglet2 kernel:  [<c0173ec0>] __user_walk_fd+0x30/0x50
May  8 19:33:02 piglet2 kernel:  [<c016d8e9>] vfs_stat_fd+0x19/0x40
May  8 19:33:02 piglet2 kernel:  [<c0157eac>] ? handle_mm_fault+0xfc/0x5a0
May  8 19:33:02 piglet2 kernel:  [<c016d9e1>] vfs_stat+0x11/0x20
May  8 19:33:02 piglet2 kernel:  [<c016da04>] sys_stat64+0x14/0x30
May  8 19:33:02 piglet2 kernel:  [<c0132886>] ? up_read+0x16/0x30
May  8 19:33:02 piglet2 kernel:  [<c0103123>] ? restore_nocheck+0x12/0x15
May  8 19:33:02 piglet2 kernel:  [<c058d4c0>] ? do_page_fault+0x0/0x6c0
May  8 19:33:02 piglet2 kernel:  [<c013976d>] ? trace_hardirqs_on+0x9d/0x110
May  8 19:33:02 piglet2 kernel:  [<c0103123>] ? restore_nocheck+0x12/0x15
May  8 19:33:02 piglet2 kernel:  [<c01030c2>] syscall_call+0x7/0xb

^ permalink raw reply	[flat|nested] 36+ messages in thread
* [PATCH] nfs: Fix misparsing of nfsv4 fs_locations attribute
@ 2008-08-14 22:30 J. Bruce Fields
  2008-08-15 16:59 ` Chuck Lever
  0 siblings, 1 reply; 36+ messages in thread
From: J. Bruce Fields @ 2008-08-14 22:30 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

I was looking back at this bug with the misparsing of
(non-mull-terminated) fs_locations attributes.  Thanks to the work on
nfs_parse_server_address, etc., we can now also more easily support ipv6
addresses here.  But I got lost in the usual maze of twisty struct
sockaddr_*'s, all alike.  Is this right?  Does any of it need to be
under CONFIG_IPV6?  Is there a simpler way?

--b.

    nfs: Fix misparsing of nfsv4 fs_locations attribute
    
    The code incorrectly assumes here that the server name (or ip address)
    is null-terminated.  This can cause referrals to fail in some cases.
    
    Also support ipv6 addresses.
    
    Compile-tested only.

    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>

diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index b112857..c0f5191 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -93,23 +93,6 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
 	return 0;
 }
 
-/*
- * Check if the string represents a "valid" IPv4 address
- */
-static inline int valid_ipaddr4(const char *buf)
-{
-	int rc, count, in[4];
-
-	rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
-	if (rc != 4)
-		return -EINVAL;
-	for (count = 0; count < 4; count++) {
-		if (in[count] > 255)
-			return -EINVAL;
-	}
-	return 0;
-}
-
 /**
  * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
  * @mnt_parent - mountpoint of parent directory
@@ -172,30 +155,44 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
 
 		s = 0;
 		while (s < location->nservers) {
-			struct sockaddr_in addr = {
-				.sin_family	= AF_INET,
-				.sin_port	= htons(NFS_PORT),
-			};
-
-			if (location->servers[s].len <= 0 ||
-			    valid_ipaddr4(location->servers[s].data) < 0) {
-				s++;
-				continue;
-			}
+			const struct nfs4_string *buf = &location->servers[s];
+			struct sockaddr_storage addr;
+
+			if (buf->len <= 0 || buf->len >= PAGE_SIZE)
+				goto next;
 
-			mountdata.hostname = location->servers[s].data;
-			addr.sin_addr.s_addr = in_aton(mountdata.hostname),
 			mountdata.addr = (struct sockaddr *)&addr;
-			mountdata.addrlen = sizeof(addr);
+
+			if (memchr(buf->data, '%', buf->len))
+				goto next;
+			nfs_parse_ip_address(buf->data, buf->len,
+					mountdata.addr, &mountdata.addrlen);
+			switch (mountdata.addr->sa_family) {
+			case AF_UNSPEC:
+				goto next;
+			case AF_INET:
+				((struct sockaddr_in *)&addr)->sin_port =
+							htons(NFS_PORT);
+				break;
+			case AF_INET6:
+				((struct sockaddr_in6 *)&addr)->sin6_port =
+							htons(NFS_PORT);
+				break;
+			}
+
+			mountdata.hostname = kmalloc(buf->len + 1, GFP_KERNEL);
+			mountdata.hostname[buf->len] = 0;
 
 			snprintf(page, PAGE_SIZE, "%s:%s",
 					mountdata.hostname,
 					mountdata.mnt_path);
 
 			mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, &mountdata);
+			kfree(mountdata.hostname);
 			if (!IS_ERR(mnt)) {
 				break;
 			}
+next:
 			s++;
 		}
 		loc++;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9abcd2b..1d10756 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -798,7 +798,7 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len,
  * If there is a problem constructing the new sockaddr, set the address
  * family to AF_UNSPEC.
  */
-static void nfs_parse_ip_address(char *string, size_t str_len,
+void nfs_parse_ip_address(char *string, size_t str_len,
 				 struct sockaddr *sap, size_t *addr_len)
 {
 	unsigned int i, colons;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 78a5922..62ca683 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -444,6 +444,8 @@ extern const struct inode_operations nfs_referral_inode_operations;
 extern int nfs_mountpoint_expiry_timeout;
 extern void nfs_release_automount_timer(void);
 
+void nfs_parse_ip_address(char *, size_t, struct sockaddr *, size_t *);
+
 /*
  * linux/fs/nfs/unlink.c
  */

^ permalink raw reply related	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2008-08-22 18:26 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-09  1:19 referrals J. Bruce Fields
2008-05-09  5:10 ` referrals Trond Myklebust
2008-05-09 15:27   ` referrals J. Bruce Fields
2008-05-09 16:52     ` referrals J. Bruce Fields
2008-05-09 17:12       ` referrals J. Bruce Fields
2008-05-09 23:59         ` [PATCH] nfs: Fix misparsing of nfsv4 fs_locations attribute J. Bruce Fields
2008-05-10  0:15           ` Benny Halevy
2008-05-10  1:06             ` J. Bruce Fields
2008-05-10  2:29           ` Chuck Lever
2008-05-10 17:32             ` Trond Myklebust
2008-05-10 23:50               ` Chuck Lever
2008-05-11  1:07                 ` david m. richter
     [not found]                   ` <1d07ca700805101807s7c034b08sc531993aa81010b2-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-05-16 19:53                     ` J. Bruce Fields
2008-05-17  2:25                       ` Chuck Lever
2008-05-18 15:22                       ` Chuck Lever
2008-05-20  2:47                         ` J. Bruce Fields
2008-05-20 16:54                           ` Chuck Lever
2008-05-20 19:32                             ` Trond Myklebust
2008-05-20 19:38                               ` Chuck Lever
2008-05-20 19:42                                 ` Trond Myklebust
  -- strict thread matches above, loose matches on Subject: below --
2008-08-14 22:30 J. Bruce Fields
2008-08-15 16:59 ` Chuck Lever
2008-08-15 22:00   ` Chuck Lever
2008-08-20 20:08   ` J. Bruce Fields
2008-08-20 20:19     ` Chuck Lever
     [not found]       ` <76bd70e30808201319j7b59de5gc912fcd01594e8-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-20 20:47         ` J. Bruce Fields
2008-08-20 21:19           ` Chuck Lever
     [not found]             ` <76bd70e30808201419g5171d7eob7e6b57dd735e07d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-20 21:29               ` J. Bruce Fields
2008-08-20 22:07                 ` Chuck Lever
     [not found]                   ` <76bd70e30808201507l44c85d08o3ec4e8eeb7edda5e-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-20 23:30                     ` J. Bruce Fields
2008-08-21  2:00                       ` Chuck Lever
     [not found]                         ` <76bd70e30808201900r699ca044o884584ecedc6a799-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-21 20:46                           ` J. Bruce Fields
2008-08-21 22:22                             ` Chuck Lever
     [not found]                               ` <76bd70e30808211522k7cb6846fs4e371c8003320fe7-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-21 22:54                                 ` J. Bruce Fields
2008-08-21 23:05                                   ` Chuck Lever
     [not found]                                     ` <76bd70e30808211605j3c32cc44v440c19e5fe81bdc9-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-08-22 18:25                                       ` Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox