lkml.org 
[lkml]   [2002]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
From
SubjectRe: [PATCH] -- filesystems.c::sys_nfsservctl 2.5.5-pre1
Date
> What would remain to protect 'nfsd_linkage' if you removed the BKL?


ok here is a patch with that changed. inlined for commenting and attached for
patching. (kmail screws up my inlines occasionally)
All of this extra checking is only in place if nfsd is a module. rw_sems
shouldn't impost that much overhead in the normal case.

The while is there to catch extremely unlikely cases of the module unloading
during this loop, ie: the cleanup_module section of nfsd is waiting for the
semaphore.

===== fs/filesystems.c 1.4 vs edited =====
--- 1.4/fs/filesystems.c Fri Feb 8 22:10:55 2002
+++ edited/fs/filesystems.c Wed Feb 13 17:43:41 2002
@@ -16,19 +16,28 @@

#if defined(CONFIG_NFSD_MODULE)
struct nfsd_linkage *nfsd_linkage = NULL;
+DECLARE_RWSEM(nfsd_linkage_lock);

long
asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp)
{
int ret = -ENOSYS;

- lock_kernel();
-
- if (nfsd_linkage ||
- (request_module ("nfsd") == 0 && nfsd_linkage))
- ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
-
- unlock_kernel();
+ down_read(&nfsd_linkage_lock);
+ while(!nfsd_linkage) {
+ up_read(&nfsd_linkage_lock);
+ down_write(&nfsd_linkage_lock);
+ if (!nfsd_linkage)
+ if (request_module ("nfsd") != 0) {
+ up_write(&nfsd_linkage_lock);
+ goto out;
+ }
+ up_write(&nfsd_linkage_lock);
+ down_read(&nfsd_linkage_lock);
+ }
+ ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
+ up_read(&nfsd_linkage_lock);
+out:
return ret;
}
EXPORT_SYMBOL(nfsd_linkage);
===== fs/nfsd/nfsctl.c 1.10 vs edited =====
--- 1.10/fs/nfsd/nfsctl.c Fri Feb 8 22:10:55 2002
+++ edited/fs/nfsd/nfsctl.c Wed Feb 13 17:33:17 2002
@@ -290,6 +290,7 @@
do_nfsservctl: handle_sys_nfsservctl,
};

+extern struct nfsd_linkage_lock;
/*
* Initialize the module
*/
@@ -307,7 +308,9 @@
void
cleanup_module(void)
{
+ down_write(&nfsd_linkage_lock);
nfsd_linkage = NULL;
+ up_write(&nfsd_linkage_lock);
nfsd_export_shutdown();
nfsd_cache_shutdown();
remove_proc_entry("fs/nfs/exports", NULL);===== fs/filesystems.c 1.4 vs edited =====
--- 1.4/fs/filesystems.c Fri Feb 8 22:10:55 2002
+++ edited/fs/filesystems.c Wed Feb 13 17:43:41 2002
@@ -16,19 +16,28 @@

#if defined(CONFIG_NFSD_MODULE)
struct nfsd_linkage *nfsd_linkage = NULL;
+DECLARE_RWSEM(nfsd_linkage_lock);

long
asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp)
{
int ret = -ENOSYS;

- lock_kernel();
-
- if (nfsd_linkage ||
- (request_module ("nfsd") == 0 && nfsd_linkage))
- ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
-
- unlock_kernel();
+ down_read(&nfsd_linkage_lock);
+ while(!nfsd_linkage) {
+ up_read(&nfsd_linkage_lock);
+ down_write(&nfsd_linkage_lock);
+ if (!nfsd_linkage)
+ if (request_module ("nfsd") != 0) {
+ up_write(&nfsd_linkage_lock);
+ goto out;
+ }
+ up_write(&nfsd_linkage_lock);
+ down_read(&nfsd_linkage_lock);
+ }
+ ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
+ up_read(&nfsd_linkage_lock);
+out:
return ret;
}
EXPORT_SYMBOL(nfsd_linkage);
===== fs/nfsd/nfsctl.c 1.10 vs edited =====
--- 1.10/fs/nfsd/nfsctl.c Fri Feb 8 22:10:55 2002
+++ edited/fs/nfsd/nfsctl.c Wed Feb 13 17:33:17 2002
@@ -290,6 +290,7 @@
do_nfsservctl: handle_sys_nfsservctl,
};

+extern struct nfsd_linkage_lock;
/*
* Initialize the module
*/
@@ -307,7 +308,9 @@
void
cleanup_module(void)
{
+ down_write(&nfsd_linkage_lock);
nfsd_linkage = NULL;
+ up_write(&nfsd_linkage_lock);
nfsd_export_shutdown();
nfsd_cache_shutdown();
remove_proc_entry("fs/nfs/exports", NULL);
\
 
 \ /
  Last update: 2005-03-22 13:24    [W:0.054 / U:1.036 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site