Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 713404d6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-2.6.29' of git://linux-nfs.org/~bfields/linux

* 'for-2.6.29' of git://linux-nfs.org/~bfields/linux: (67 commits)
  nfsd: get rid of NFSD_VERSION
  nfsd: last_byte_offset
  nfsd: delete wrong file comment from nfsd/nfs4xdr.c
  nfsd: git rid of nfs4_cb_null_ops declaration
  nfsd: dprint each op status in nfsd4_proc_compound
  nfsd: add etoosmall to nfserrno
  NFSD: FIDs need to take precedence over UUIDs
  SUNRPC: The sunrpc server code should not be used by out-of-tree modules
  svc: Clean up deferred requests on transport destruction
  nfsd: fix double-locks of directory mutex
  svc: Move kfree of deferral record to common code
  CRED: Fix NFSD regression
  NLM: Clean up flow of control in make_socks() function
  NLM: Refactor make_socks() function
  nfsd: Ensure nfsv4 calls the underlying filesystem on LOCKT
  SUNRPC: Ensure the server closes sockets in a timely fashion
  NFSD: Add documenting comments for nfsctl interface
  NFSD: Replace open-coded integer with macro
  NFSD: Fix a handful of coding style issues in write_filehandle()
  NFSD: clean up failover sysctl function naming
  ...
parents d599edca db43910c
Loading
Loading
Loading
Loading
+2 −5
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/svc.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/sm_inter.h>


#define NLMDBG_FACILITY		NLMDBG_CLIENT
#define NLMDBG_FACILITY		NLMDBG_CLIENT
#define NLMCLNT_GRACE_WAIT	(5*HZ)
#define NLMCLNT_GRACE_WAIT	(5*HZ)
@@ -518,11 +517,9 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
	unsigned char fl_type;
	unsigned char fl_type;
	int status = -ENOLCK;
	int status = -ENOLCK;


	if (nsm_monitor(host) < 0) {
	if (nsm_monitor(host) < 0)
		printk(KERN_NOTICE "lockd: failed to monitor %s\n",
					host->h_name);
		goto out;
		goto out;
	}

	fl->fl_flags |= FL_ACCESS;
	fl->fl_flags |= FL_ACCESS;
	status = do_vfs_lock(fl);
	status = do_vfs_lock(fl);
	fl->fl_flags = fl_flags;
	fl->fl_flags = fl_flags;
+17 −153
Original line number Original line Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/svc.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/sm_inter.h>
#include <linux/mutex.h>
#include <linux/mutex.h>


#include <net/ipv6.h>
#include <net/ipv6.h>
@@ -32,11 +31,6 @@ static int nrhosts;
static DEFINE_MUTEX(nlm_host_mutex);
static DEFINE_MUTEX(nlm_host_mutex);


static void			nlm_gc_hosts(void);
static void			nlm_gc_hosts(void);
static struct nsm_handle	*nsm_find(const struct sockaddr *sap,
						const size_t salen,
						const char *hostname,
						const size_t hostname_len,
						const int create);


struct nlm_lookup_host_info {
struct nlm_lookup_host_info {
	const int		server;		/* search for server|client */
	const int		server;		/* search for server|client */
@@ -105,32 +99,6 @@ static void nlm_clear_port(struct sockaddr *sap)
	}
	}
}
}


static void nlm_display_address(const struct sockaddr *sap,
				char *buf, const size_t len)
{
	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;

	switch (sap->sa_family) {
	case AF_UNSPEC:
		snprintf(buf, len, "unspecified");
		break;
	case AF_INET:
		snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
		break;
	case AF_INET6:
		if (ipv6_addr_v4mapped(&sin6->sin6_addr))
			snprintf(buf, len, "%pI4",
				 &sin6->sin6_addr.s6_addr32[3]);
		else
			snprintf(buf, len, "%pI6", &sin6->sin6_addr);
		break;
	default:
		snprintf(buf, len, "unsupported address family");
		break;
	}
}

/*
/*
 * Common host lookup routine for server & client
 * Common host lookup routine for server & client
 */
 */
@@ -190,8 +158,8 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
		atomic_inc(&nsm->sm_count);
		atomic_inc(&nsm->sm_count);
	else {
	else {
		host = NULL;
		host = NULL;
		nsm = nsm_find(ni->sap, ni->salen,
		nsm = nsm_get_handle(ni->sap, ni->salen,
				ni->hostname, ni->hostname_len, 1);
					ni->hostname, ni->hostname_len);
		if (!nsm) {
		if (!nsm) {
			dprintk("lockd: nlm_lookup_host failed; "
			dprintk("lockd: nlm_lookup_host failed; "
				"no nsm handle\n");
				"no nsm handle\n");
@@ -206,6 +174,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
		goto out;
		goto out;
	}
	}
	host->h_name	   = nsm->sm_name;
	host->h_name	   = nsm->sm_name;
	host->h_addrbuf    = nsm->sm_addrbuf;
	memcpy(nlm_addr(host), ni->sap, ni->salen);
	memcpy(nlm_addr(host), ni->sap, ni->salen);
	host->h_addrlen = ni->salen;
	host->h_addrlen = ni->salen;
	nlm_clear_port(nlm_addr(host));
	nlm_clear_port(nlm_addr(host));
@@ -232,11 +201,6 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)


	nrhosts++;
	nrhosts++;


	nlm_display_address((struct sockaddr *)&host->h_addr,
				host->h_addrbuf, sizeof(host->h_addrbuf));
	nlm_display_address((struct sockaddr *)&host->h_srcaddr,
				host->h_srcaddrbuf, sizeof(host->h_srcaddrbuf));

	dprintk("lockd: nlm_lookup_host created host %s\n",
	dprintk("lockd: nlm_lookup_host created host %s\n",
			host->h_name);
			host->h_name);


@@ -256,10 +220,8 @@ nlm_destroy_host(struct nlm_host *host)
	BUG_ON(!list_empty(&host->h_lockowners));
	BUG_ON(!list_empty(&host->h_lockowners));
	BUG_ON(atomic_read(&host->h_count));
	BUG_ON(atomic_read(&host->h_count));


	/*
	 * Release NSM handle and unmonitor host.
	 */
	nsm_unmonitor(host);
	nsm_unmonitor(host);
	nsm_release(host->h_nsmhandle);


	clnt = host->h_rpcclnt;
	clnt = host->h_rpcclnt;
	if (clnt != NULL)
	if (clnt != NULL)
@@ -378,8 +340,8 @@ nlm_bind_host(struct nlm_host *host)
{
{
	struct rpc_clnt	*clnt;
	struct rpc_clnt	*clnt;


	dprintk("lockd: nlm_bind_host %s (%s), my addr=%s\n",
	dprintk("lockd: nlm_bind_host %s (%s)\n",
			host->h_name, host->h_addrbuf, host->h_srcaddrbuf);
			host->h_name, host->h_addrbuf);


	/* Lock host handle */
	/* Lock host handle */
	mutex_lock(&host->h_mutex);
	mutex_lock(&host->h_mutex);
@@ -481,35 +443,23 @@ void nlm_release_host(struct nlm_host *host)
	}
	}
}
}


/*
/**
 * We were notified that the host indicated by address &sin
 * nlm_host_rebooted - Release all resources held by rebooted host
 * has rebooted.
 * @info: pointer to decoded results of NLM_SM_NOTIFY call
 * Release all resources held by that peer.
 *
 * We were notified that the specified host has rebooted.  Release
 * all resources held by that peer.
 */
 */
void nlm_host_rebooted(const struct sockaddr_in *sin,
void nlm_host_rebooted(const struct nlm_reboot *info)
				const char *hostname,
				unsigned int hostname_len,
				u32 new_state)
{
{
	struct hlist_head *chain;
	struct hlist_head *chain;
	struct hlist_node *pos;
	struct hlist_node *pos;
	struct nsm_handle *nsm;
	struct nsm_handle *nsm;
	struct nlm_host	*host;
	struct nlm_host	*host;


	nsm = nsm_find((struct sockaddr *)sin, sizeof(*sin),
	nsm = nsm_reboot_lookup(info);
			hostname, hostname_len, 0);
	if (unlikely(nsm == NULL))
	if (nsm == NULL) {
		dprintk("lockd: never saw rebooted peer '%.*s' before\n",
				hostname_len, hostname);
		return;
		return;
	}

	dprintk("lockd: nlm_host_rebooted(%.*s, %s)\n",
			hostname_len, hostname, nsm->sm_addrbuf);

	/* When reclaiming locks on this peer, make sure that
	 * we set up a new notification */
	nsm->sm_monitored = 0;


	/* Mark all hosts tied to this NSM state as having rebooted.
	/* Mark all hosts tied to this NSM state as having rebooted.
	 * We run the loop repeatedly, because we drop the host table
	 * We run the loop repeatedly, because we drop the host table
@@ -520,8 +470,8 @@ again: mutex_lock(&nlm_host_mutex);
	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
		hlist_for_each_entry(host, pos, chain, h_hash) {
		hlist_for_each_entry(host, pos, chain, h_hash) {
			if (host->h_nsmhandle == nsm
			if (host->h_nsmhandle == nsm
			 && host->h_nsmstate != new_state) {
			 && host->h_nsmstate != info->state) {
				host->h_nsmstate = new_state;
				host->h_nsmstate = info->state;
				host->h_state++;
				host->h_state++;


				nlm_get_host(host);
				nlm_get_host(host);
@@ -629,89 +579,3 @@ nlm_gc_hosts(void)


	next_gc = jiffies + NLM_HOST_COLLECT;
	next_gc = jiffies + NLM_HOST_COLLECT;
}
}


/*
 * Manage NSM handles
 */
static LIST_HEAD(nsm_handles);
static DEFINE_SPINLOCK(nsm_lock);

static struct nsm_handle *nsm_find(const struct sockaddr *sap,
				   const size_t salen,
				   const char *hostname,
				   const size_t hostname_len,
				   const int create)
{
	struct nsm_handle *nsm = NULL;
	struct nsm_handle *pos;

	if (!sap)
		return NULL;

	if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
		if (printk_ratelimit()) {
			printk(KERN_WARNING "Invalid hostname \"%.*s\" "
					    "in NFS lock request\n",
				(int)hostname_len, hostname);
		}
		return NULL;
	}

retry:
	spin_lock(&nsm_lock);
	list_for_each_entry(pos, &nsm_handles, sm_link) {

		if (hostname && nsm_use_hostnames) {
			if (strlen(pos->sm_name) != hostname_len
			 || memcmp(pos->sm_name, hostname, hostname_len))
				continue;
		} else if (!nlm_cmp_addr(nsm_addr(pos), sap))
			continue;
		atomic_inc(&pos->sm_count);
		kfree(nsm);
		nsm = pos;
		goto found;
	}
	if (nsm) {
		list_add(&nsm->sm_link, &nsm_handles);
		goto found;
	}
	spin_unlock(&nsm_lock);

	if (!create)
		return NULL;

	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
	if (nsm == NULL)
		return NULL;

	memcpy(nsm_addr(nsm), sap, salen);
	nsm->sm_addrlen = salen;
	nsm->sm_name = (char *) (nsm + 1);
	memcpy(nsm->sm_name, hostname, hostname_len);
	nsm->sm_name[hostname_len] = '\0';
	nlm_display_address((struct sockaddr *)&nsm->sm_addr,
				nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
	atomic_set(&nsm->sm_count, 1);
	goto retry;

found:
	spin_unlock(&nsm_lock);
	return nsm;
}

/*
 * Release an NSM handle
 */
void
nsm_release(struct nsm_handle *nsm)
{
	if (!nsm)
		return;
	if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
		list_del(&nsm->sm_link);
		spin_unlock(&nsm_lock);
		kfree(nsm);
	}
}
Loading