+ knfsd-add-a-callback-for-when-last-rpc-thread-finishes.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     knfsd: add a callback for when last rpc thread finishes

has been added to the -mm tree.  Its filename is

     knfsd-add-a-callback-for-when-last-rpc-thread-finishes.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: knfsd: add a callback for when last rpc thread finishes
From: NeilBrown <neilb@xxxxxxx>

nfsd has some cleanup that it wants to do when the last thread exits, and
there will shortly be some more.  So collect this all into one place and
define a callback for an rpc service to call when the service is about to be
destroyed.

Signed-off-by: Neil Brown <neilb@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 fs/lockd/svc.c             |    2 -
 fs/nfsd/nfssvc.c           |   40 +++++++++++++++--------------------
 include/linux/sunrpc/svc.h |    8 ++++++-
 net/sunrpc/svc.c           |    7 +++++-
 4 files changed, 32 insertions(+), 25 deletions(-)

diff -puN fs/lockd/svc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes fs/lockd/svc.c
--- a/fs/lockd/svc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes
+++ a/fs/lockd/svc.c
@@ -236,7 +236,7 @@ lockd_up(void)
 			"lockd_up: no pid, %d users??\n", nlmsvc_users);
 
 	error = -ENOMEM;
-	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
 	if (!serv) {
 		printk(KERN_WARNING "lockd_up: create service failed\n");
 		goto out;
diff -puN fs/nfsd/nfssvc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes
+++ a/fs/nfsd/nfssvc.c
@@ -130,11 +130,25 @@ int nfsd_nrthreads(void)
 		return nfsd_serv->sv_nrthreads;
 }
 
+static int killsig = 0; /* signal that was used to kill last nfsd */
+static void nfsd_last_thread(struct svc_serv *serv)
+{
+	/* When last nfsd thread exits we need to do some clean-up */
+	nfsd_serv = NULL;
+	nfsd_racache_shutdown();
+	nfs4_state_shutdown();
+
+	printk(KERN_WARNING "nfsd: last server has exited\n");
+	if (killsig != SIG_NOCLEAN) {
+		printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
+		nfsd_export_flush();
+	}
+}
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
 	int	error;
-	int	none_left, found_one, i;
+	int	found_one, i;
 	struct list_head *victim;
 	
 	lock_kernel();
@@ -197,7 +211,8 @@ nfsd_svc(unsigned short port, int nrserv
 
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;
-		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
+		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE,
+				       nfsd_last_thread);
 		if (nfsd_serv == NULL)
 			goto out;
 		error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
@@ -231,13 +246,7 @@ nfsd_svc(unsigned short port, int nrserv
 		nrservs++;
 	}
  failure:
-	none_left = (nfsd_serv->sv_nrthreads == 1);
 	svc_destroy(nfsd_serv);		/* Release server */
-	if (none_left) {
-		nfsd_serv = NULL;
-		nfsd_racache_shutdown();
-		nfs4_state_shutdown();
-	}
  out:
 	unlock_kernel();
 	return error;
@@ -353,7 +362,7 @@ nfsd(struct svc_rqst *rqstp)
 			if (sigismember(&current->pending.signal, signo) &&
 			    !sigismember(&current->blocked, signo))
 				break;
-		err = signo;
+		killsig = signo;
 	}
 	/* Clear signals before calling lockd_down() and svc_exit_thread() */
 	flush_signals(current);
@@ -362,19 +371,6 @@ nfsd(struct svc_rqst *rqstp)
 
 	/* Release lockd */
 	lockd_down();
-
-	/* Check if this is last thread */
-	if (serv->sv_nrthreads==1) {
-		
-		printk(KERN_WARNING "nfsd: last server has exited\n");
-		if (err != SIG_NOCLEAN) {
-			printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
-			nfsd_export_flush();
-		}
-		nfsd_serv = NULL;
-	        nfsd_racache_shutdown();	/* release read-ahead cache */
-		nfs4_state_shutdown();
-	}
 	list_del(&me.list);
 	nfsdstats.th_cnt --;
 
diff -puN include/linux/sunrpc/svc.h~knfsd-add-a-callback-for-when-last-rpc-thread-finishes include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h~knfsd-add-a-callback-for-when-last-rpc-thread-finishes
+++ a/include/linux/sunrpc/svc.h
@@ -42,6 +42,11 @@ struct svc_serv {
 	int			sv_tmpcnt;	/* count of temporary sockets */
 
 	char *			sv_name;	/* service name */
+
+	void			(*sv_shutdown)(struct svc_serv *serv);
+						/* Callback to use when last thread
+						 * exits.
+						 */
 };
 
 /*
@@ -311,7 +316,8 @@ typedef void		(*svc_thread_fn)(struct sv
 /*
  * Function prototypes.
  */
-struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+struct svc_serv *  svc_create(struct svc_program *, unsigned int,
+			      void (*shutdown)(struct svc_serv*));
 int		   svc_create_thread(svc_thread_fn, struct svc_serv *);
 void		   svc_exit_thread(struct svc_rqst *);
 void		   svc_destroy(struct svc_serv *);
diff -puN net/sunrpc/svc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes net/sunrpc/svc.c
--- a/net/sunrpc/svc.c~knfsd-add-a-callback-for-when-last-rpc-thread-finishes
+++ a/net/sunrpc/svc.c
@@ -26,7 +26,8 @@
  * Create an RPC service
  */
 struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+svc_create(struct svc_program *prog, unsigned int bufsize,
+	   void (*shutdown)(struct svc_serv *serv))
 {
 	struct svc_serv	*serv;
 	int vers;
@@ -39,6 +40,7 @@ svc_create(struct svc_program *prog, uns
 	serv->sv_nrthreads = 1;
 	serv->sv_stats     = prog->pg_stats;
 	serv->sv_bufsz	   = bufsize? bufsize : 4096;
+	serv->sv_shutdown  = shutdown;
 	xdrsize = 0;
 	while (prog) {
 		prog->pg_lovers = prog->pg_nvers-1;
@@ -91,6 +93,9 @@ svc_destroy(struct svc_serv *serv)
 				  sk_list);
 		svc_delete_socket(svsk);
 	}
+	if (serv->sv_shutdown)
+		serv->sv_shutdown(serv);
+
 	while (!list_empty(&serv->sv_permsocks)) {
 		svsk = list_entry(serv->sv_permsocks.next,
 				  struct svc_sock,
_

Patches currently in -mm which might be from neilb@xxxxxxx are

ext3-avoid-triggering-ext3_error-on-bad-nfs-file-handle.patch
ext3-avoid-triggering-ext3_error-on-bad-nfs-file-handle-fix.patch
git-klibc.patch
ext3-reject-filehandles-referring-to-special-files.patch
ext2-reject-file-handles-with-bad-inode-numbers-early.patch
knfsd-knfsd-add-some-missing-newlines-in-printks.patch
knfsd-knfsd-remove-an-unused-variable-from-e_show.patch
knfsd-knfsd-remove-an-unused-variable-from-auth_unix_lookup.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes-tidy.patch
knfsd-be-more-selective-in-which-sockets-lockd-listens-on.patch
knfsd-remove-nfsd_versbits-as-intermediate-storage-for-desired-versions.patch
knfsd-separate-out-some-parts-of-nfsd_svc-which-start-nfs-servers.patch
knfsd-separate-out-some-parts-of-nfsd_svc-which-start-nfs-servers-tweaks.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports-tidy.patch
knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist.patch
md-dm-reduce-stack-usage-with-stacked-block-devices.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux