Fixups agains the nfs 'devel' branch
Subsystems (2)
cover Fixups agains the nfs 'devel' branch
The following series fixes a Connectathon testsuite regression, as well as updating a couple of old patches from Bruce and Chuck.
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
A message that is not in the archive (sent off-list or not yet received): 20081009190031.18388.95039.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
PATCH 1/4 NFS: Fix attribute updates
This fixes a regression seen when running the Connectathon testsuite against an ext3 filesystem. The reason was that the inode was constantly being marked as 'just updated' by the jiffy wraparound test. This again meant that newer GETATTR calls were failing to pass the nfs_inode_attrs_need_update() test unless the changes caused a ctime update on the server, since they were perceived as having been started before the latest inode update.
Given that nfs_inode_attrs_need_update() already checks for wraparound of nfsi->last_updated, we can drop the buggy "protection" in nfs_update_inode().
Also make a slight micro-optimisation of nfs_inode_attrs_need_update(): we are more often going to see time_after(fattr->time_start, nfsi->last_updated) be true, rather than seeing an update of ctime/size, so put that test first to ensure that we optimise away the ctime/size tests.
---
fs/nfs/inode.c | 13 ++++--------- 1 files changed, 4 insertions(+), 9 deletions(-)
fs/nfs/inode.c +4 -9
@@ -933,10 +933,10 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n {const struct nfs_inode *nfsi =NFS_I (inode); -return nfs_ctime_need_update (inode, fattr) || -nfs_size_need_update (inode, fattr) || -time_after (fattr->time_start, nfsi->last_updated) || -time_after (nfsi->last_updated, jiffies); +return time_after (fattr->time_start, nfsi->last_updated) || +nfs_ctime_need_update (inode, fattr) || +nfs_size_need_update (inode, fattr) || +time_after (nfsi->last_updated, jiffies); }static int nfs_refresh_inode_locked (struct inode *inode,struct nfs_fattr *fattr)
@@ -1167,11 +1167,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfsi->attrtimeo =NFS_MAXATTRTIMEO (inode); nfsi->attrtimeo_timestamp = now; } -/* -* Avoid jiffy wraparound issues with nfsi->last_updated -*/ -if (!time_in_range (nfsi->last_updated, nfsi->read_cache_jiffies, now)) - nfsi->last_updated = nfsi->read_cache_jiffies; } invalid &= ~NFS_INO_INVALID_ATTR ;/* Don't invalidate the data if we were to blame */
PATCH 2/4 NFS: Remove checks for scope id's in v6 addresses in the fs-locations code
In reply to a message not in the archiveFrom: J. Bruce Fields <[email protected]>
The concensus on the list is that servers should not be allowed to send anything other than ordinary IPv6 addresses, or DNS hostnames in the fs-locations attribute.
---
fs/nfs/internal.h | 2 -- fs/nfs/nfs4namespace.c | 2 -- fs/nfs/super.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-)
fs/nfs/internal.h +0 -2
@@ -277,8 +277,6 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len) PAGE_SIZE - 1) >> PAGE_SHIFT; } -#define IPV6_SCOPE_DELIMITER '%' -/* * Set the port number in an address. Be agnostic about the address * family.
fs/nfs/nfs4namespace.c +0 -2
@@ -118,8 +118,6 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, mountdata->addr = (struct sockaddr *)&addr; -if (memchr (buf->data,IPV6_SCOPE_DELIMITER , buf->len)) -continue ;nfs_parse_ip_address (buf->data, buf->len, mountdata->addr, &mountdata->addrlen);if (mountdata->addr->sa_family ==AF_UNSPEC )
fs/nfs/super.c +2 -0
@@ -716,6 +716,8 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len, *addr_len =0 ; } +#define IPV6_SCOPE_DELIMITER '%' +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len, const char *delim,
PATCH 3/4 NFS: Cleanup nfs_set_port
In reply to a message not in the archiveFrom: J. Bruce Fields <[email protected]>
---
fs/nfs/internal.h | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-)
fs/nfs/internal.h +9 -10
@@ -283,16 +283,15 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)*/ static inline void nfs_set_port (struct sockaddr *sap,unsigned short port) { +struct sockaddr_in *ap = (struct sockaddr_in *)sap; +struct sockaddr_in6 *ap6 = (struct sockaddr_in6 *)sap; +switch (sap->sa_family) { -case AF_INET : { -struct sockaddr_in *ap = (struct sockaddr_in *)sap; - ap->sin_port =htons (port); -break ; - } -case AF_INET6 : { -struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap; - ap->sin6_port =htons (port); -break ; - } +case AF_INET : + ap->sin_port =htons (port); +break ; +case AF_INET6 : + ap6->sin6_port =htons (port); +break ; } }
PATCH 4/4 NFS: fix nfs_parse_ip_address() corner case
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Bruce observed that nfs_parse_ip_address() will successfully parse an IPv6 address that looks like this:
"::1%"
A scope delimiter is present, but there is no scope ID following it. This is harmless, as it would simply set the scope ID to zero. However, in some cases we would like to flag this as an improperly formed address.
We are now also careful to reject addresses where garbage follows the address (up to the length of the string), instead of ignoring the non-address characters; and where the scope ID is nonsense (not a valid device name, but also not numeric). Before, both of these cases would result in a harmless zero scope ID.
---
fs/nfs/super.c | 34 +++++++++++++++++++++++----------- 1 files changed, 23 insertions(+), 11 deletions(-)
fs/nfs/super.c +23 -11
@@ -719,17 +719,21 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len,#define IPV6_SCOPE_DELIMITER '%'#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) -static void nfs_parse_ipv6_scope_id (const char *string,const size_t str_len, -const char *delim, -struct sockaddr_in6 *sin6) +static int nfs_parse_ipv6_scope_id (const char *string,const size_t str_len, +const char *delim, +struct sockaddr_in6 *sin6) {char *p;size_t len; -if (!(ipv6_addr_type (&sin6->sin6_addr) &IPV6_ADDR_LINKLOCAL )) -return ; +if ((string + str_len) == delim) +return 1 ; +if (*delim !=IPV6_SCOPE_DELIMITER ) -return ; +return 0 ; + +if (!(ipv6_addr_type (&sin6->sin6_addr) &IPV6_ADDR_LINKLOCAL )) +return 0 ; len = (string + str_len) - delim -1 ; p =kstrndup (delim +1 , len,GFP_KERNEL );
@@ -742,14 +746,20 @@ static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len, scope_id = dev->ifindex;dev_put (dev); }else { -/* scope_id is set to zero on error */ -strict_strtoul (p,10 , &scope_id); +if (strict_strtoul (p,10 , &scope_id) ==0 ) { +kfree (p); +return 0 ; + } }kfree (p); + sin6->sin6_scope_id = scope_id;dfprintk (MOUNT ,"NFS: IPv6 scope ID = %lu\n" , scope_id); +return 1 ; } + +return 0 ; } static void nfs_parse_ipv6_address(char *string, size_t str_len,
@@ -765,9 +775,11 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len, sin6->sin6_family =AF_INET6 ; *addr_len =sizeof (*sin6); -if (in6_pton (string, str_len, addr,IPV6_SCOPE_DELIMITER , &delim)) { -nfs_parse_ipv6_scope_id (string, str_len, delim, sin6); -return ; +if (in6_pton (string, str_len, addr, +IPV6_SCOPE_DELIMITER , &delim) !=0 ) { +if (nfs_parse_ipv6_scope_id (string, str_len, + delim, sin6) !=0 ) +return ; } }