Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 92828
b: refs/heads/master
c: a277e33
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Layton authored and J. Bruce Fields committed Apr 23, 2008
1 parent 0ceba1e commit d5a589f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ba1514815817f93a4f09615726dd4bcd0ddbbc9
refs/heads/master: a277e33cbe3fdfb9a77b448ea3043be22f000dfd
73 changes: 35 additions & 38 deletions trunk/fs/nfs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/nfs_fs.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
#include <linux/kthread.h>

#include <net/inet_sock.h>

Expand All @@ -27,9 +28,7 @@
struct nfs_callback_data {
unsigned int users;
struct svc_serv *serv;
pid_t pid;
struct completion started;
struct completion stopped;
struct task_struct *task;
};

static struct nfs_callback_data nfs_callback_info;
Expand Down Expand Up @@ -57,27 +56,20 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
/*
* This is the callback kernel thread.
*/
static void nfs_callback_svc(struct svc_rqst *rqstp)
static int
nfs_callback_svc(void *vrqstp)
{
int err;
struct svc_rqst *rqstp = vrqstp;

__module_get(THIS_MODULE);
lock_kernel();

nfs_callback_info.pid = current->pid;
daemonize("nfsv4-svc");
/* Process request with signals blocked, but allow SIGKILL. */
allow_signal(SIGKILL);
set_freezable();

complete(&nfs_callback_info.started);

for(;;) {
if (signalled()) {
if (nfs_callback_info.users == 0)
break;
flush_signals(current);
}
/*
* FIXME: do we really need to run this under the BKL? If so, please
* add a comment about what it's intended to protect.
*/
lock_kernel();
while (!kthread_should_stop()) {
/*
* Listen for a request on the socket
*/
Expand All @@ -92,13 +84,10 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
}
svc_process(rqstp);
}

flush_signals(current);
svc_exit_thread(rqstp);
nfs_callback_info.pid = 0;
complete(&nfs_callback_info.stopped);
unlock_kernel();
module_put_and_exit(0);
nfs_callback_info.task = NULL;
svc_exit_thread(rqstp);
return 0;
}

/*
Expand All @@ -107,14 +96,13 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
int nfs_callback_up(void)
{
struct svc_serv *serv = NULL;
struct svc_rqst *rqstp;
int ret = 0;

lock_kernel();
mutex_lock(&nfs_callback_mutex);
if (nfs_callback_info.users++ || nfs_callback_info.pid != 0)
if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
goto out;
init_completion(&nfs_callback_info.started);
init_completion(&nfs_callback_info.stopped);
serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
ret = -ENOMEM;
if (!serv)
Expand All @@ -127,15 +115,28 @@ int nfs_callback_up(void)
nfs_callback_tcpport = ret;
dprintk("Callback port = 0x%x\n", nfs_callback_tcpport);

ret = svc_create_thread(nfs_callback_svc, serv);
if (ret < 0)
rqstp = svc_prepare_thread(serv, &serv->sv_pools[0]);
if (IS_ERR(rqstp)) {
ret = PTR_ERR(rqstp);
goto out_err;
}

svc_sock_update_bufs(serv);
nfs_callback_info.serv = serv;
wait_for_completion(&nfs_callback_info.started);

nfs_callback_info.task = kthread_run(nfs_callback_svc, rqstp,
"nfsv4-svc");
if (IS_ERR(nfs_callback_info.task)) {
ret = PTR_ERR(nfs_callback_info.task);
nfs_callback_info.serv = NULL;
nfs_callback_info.task = NULL;
svc_exit_thread(rqstp);
goto out_err;
}
out:
/*
* svc_create creates the svc_serv with sv_nrthreads == 1, and then
* svc_create_thread increments that. So we need to call svc_destroy
* svc_prepare_thread increments that. So we need to call svc_destroy
* on both success and failure so that the refcount is 1 when the
* thread exits.
*/
Expand All @@ -159,12 +160,8 @@ void nfs_callback_down(void)
lock_kernel();
mutex_lock(&nfs_callback_mutex);
nfs_callback_info.users--;
do {
if (nfs_callback_info.users != 0 || nfs_callback_info.pid == 0)
break;
if (kill_proc(nfs_callback_info.pid, SIGKILL, 1) < 0)
break;
} while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0);
if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL)
kthread_stop(nfs_callback_info.task);
mutex_unlock(&nfs_callback_mutex);
unlock_kernel();
}
Expand Down

0 comments on commit d5a589f

Please sign in to comment.