From: NeilBrown <neilb@suse.de>
To: Andrew Morton <akpm@osdl.org>
Cc: nfs@lists.sourceforge.net, linux-kernel@vger.kernel.org
Subject: [PATCH 004 of 9] knfsd: Add a callback for when last rpc thread finishes.
Date: Tue, 25 Jul 2006 11:54:42 +1000 [thread overview]
Message-ID: <1060725015442.21945@suse.de> (raw)
In-Reply-To: <20060725114207.21779.patches@notabene>
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@suse.de>
### Diffstat output
./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 .prev/fs/lockd/svc.c ./fs/lockd/svc.c
--- .prev/fs/lockd/svc.c 2006-07-24 14:55:00.000000000 +1000
+++ ./fs/lockd/svc.c 2006-07-24 15:13:40.000000000 +1000
@@ -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 .prev/fs/nfsd/nfssvc.c ./fs/nfsd/nfssvc.c
--- .prev/fs/nfsd/nfssvc.c 2006-07-24 14:50:53.000000000 +1000
+++ ./fs/nfsd/nfssvc.c 2006-07-24 15:14:31.000000000 +1000
@@ -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(¤t->pending.signal, signo) &&
!sigismember(¤t->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 .prev/include/linux/sunrpc/svc.h ./include/linux/sunrpc/svc.h
--- .prev/include/linux/sunrpc/svc.h 2006-07-24 14:42:06.000000000 +1000
+++ ./include/linux/sunrpc/svc.h 2006-07-24 15:13:40.000000000 +1000
@@ -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 .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c
--- .prev/net/sunrpc/svc.c 2006-07-24 14:40:46.000000000 +1000
+++ ./net/sunrpc/svc.c 2006-07-24 15:13:40.000000000 +1000
@@ -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;
@@ -40,6 +41,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;
@@ -92,6 +94,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,
next prev parent reply other threads:[~2006-07-25 1:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-25 1:54 [PATCH 000 of 9] knfsd: Introduction NeilBrown
2006-07-25 1:54 ` [PATCH 001 of 9] knfsd: knfsd: Add some missing newlines in printks NeilBrown
2006-07-25 1:54 ` [PATCH 002 of 9] knfsd: knfsd: Remove an unused variable from e_show() NeilBrown
2006-07-25 4:10 ` Josef Sipek
2006-07-25 4:20 ` Neil Brown
2006-07-25 4:24 ` [NFS] " Greg Banks
2006-07-25 4:32 ` Greg Banks
2006-07-25 4:36 ` Neil Brown
2006-07-25 5:53 ` Greg Banks
2006-07-25 1:54 ` [PATCH 003 of 9] knfsd: knfsd: Remove an unused variable from auth_unix_lookup() NeilBrown
2006-07-25 1:54 ` NeilBrown [this message]
2006-07-25 1:54 ` [PATCH 005 of 9] knfsd: Be more selective in which sockets lockd listens on NeilBrown
2006-07-26 19:17 ` [NFS] " J. Bruce Fields
2006-07-28 2:32 ` Neil Brown
2006-07-25 1:54 ` [PATCH 006 of 9] knfsd: Remove nfsd_versbits as intermediate storage for desired versions NeilBrown
2006-07-26 19:34 ` [NFS] " J. Bruce Fields
2006-07-25 1:54 ` [PATCH 007 of 9] knfsd: Separate out some parts of nfsd_svc, which start nfs servers NeilBrown
2006-07-26 6:42 ` Andrew Morton
2006-07-25 1:55 ` [PATCH 008 of 9] knfsd: Define new nfsdfs file: portlist - contains list of ports NeilBrown
2006-07-25 1:55 ` [PATCH 009 of 9] knfsd: Allow sockets to be passed to nfsd via 'portlist' NeilBrown
2006-07-26 6:53 ` Andrew Morton
2006-07-26 20:41 ` [NFS] " J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1060725015442.21945@suse.de \
--to=neilb@suse.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nfs@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome