]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.27pre5 2.3.27pre5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:28:31 +0000 (15:28 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:28:31 +0000 (15:28 -0500)
24 files changed:
arch/alpha/mm/extable.c
arch/arm/mm/extable.c
arch/i386/mm/extable.c
arch/m68k/mm/extable.c
arch/mips/mm/extable.c
arch/ppc/mm/extable.c
arch/sh/mm/extable.c
arch/sparc/mm/extable.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/mm/extable.c
drivers/char/ftape/lowlevel/ftape-proc.c
drivers/char/ip2main.c
drivers/net/pcmcia/ray_cs.c
drivers/pnp/isapnp_proc.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_syms.c
fs/minix/bitmap.c
fs/proc/array.c
fs/proc/kcore.c
include/linux/module.h
include/linux/proc_fs.h
kernel/module.c

index 12a1f4803fd1f47a175d60c00a896946ba7fbe83..ea1387f791d643677f806a2ee29025d8fcc61e56 100644 (file)
@@ -49,13 +49,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special. */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp ; mp = mp->next) {
                if (!mp->ex_table_start)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr - mp->gp);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index e603b6362041b228401380a1fcec7228555b52ff..c98ba5a9e0295f38ec4cf6619c024cfeba2adf90 100644 (file)
@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index ba34c0395812fdc712d3143fee0a22f29c09dd3b..398a62fa1a73c178241d82fd5b1d13e152fc0511 100644 (file)
@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index 1f8d9e8c3323997fd02f3a339d835bcd83cdfa37..7cd5d5c644da3a5e63e2db648452210a531f19dc 100644 (file)
@@ -42,13 +42,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end-1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index a92fdc482e9fb71cde6796825efdf8e0aa1231c3..8a0febc3813657befc4e7d29e22b9a1a67037469 100644 (file)
@@ -41,13 +41,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index afcf705e14a630314c4d86fa3f229809d9ecaf44..dc57bf86845b38e4bc94ba5062a3260fbf9b6f16 100644 (file)
@@ -43,13 +43,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index dc77f57fe2438317a9de8ab0776bee0e8d2dd711..7c677a970bfeafd238f2318d4a52b642309def62 100644 (file)
@@ -45,13 +45,18 @@ search_exception_table(unsigned long addr)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end - 1, addr);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index 7fe26ad96edda0f499518fd6db79f9e96528e582..e66e4c72a00304975b054e6f643384ee85c457ed 100644 (file)
@@ -56,13 +56,18 @@ search_exception_table(unsigned long addr, unsigned long *g2)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end-1, addr, g2);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index a1e0f26dd9a6b115f6ce3ebfd9437e823e3df435..c25879850a6e330c4e94f5a489ef63849a2b01a1 100644 (file)
@@ -2932,6 +2932,7 @@ put_mod_name(char *buf)
        free_page((unsigned long)buf);
 }
 
+/* caller must hold modlist_lock at least in read mode */
 static __inline__ struct module *find_module(const char *name)
 {
        struct module *mod;
@@ -3161,7 +3162,7 @@ asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kerne
        struct module *mod;
        int err;
 
-       lock_kernel();
+       read_lock(&modlist_lock);
        if (name_user == 0) {
                /* This finds "kernel_module" which is not exported. */
                for(mod = module_list; mod->next != NULL; mod = mod->next)
@@ -3211,7 +3212,7 @@ asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kerne
                break;
        }
 out:
-       unlock_kernel();
+       read_unlock(&modlist_lock);
        return err;
 }
 
index b2df0e169ac0763a96e4be2010eacab967cf644a..a8d4964df0b30f2cc2ba5ab54d378a131cb1d5ad 100644 (file)
@@ -56,13 +56,18 @@ search_exception_table(unsigned long addr, unsigned long *g2)
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
        struct module *mp;
+       read_lock(&modlist_lock);
        for (mp = module_list; mp != NULL; mp = mp->next) {
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
                                       mp->ex_table_end-1, addr, g2);
-               if (ret) return ret;
+               if (ret) {
+                       read_unlock(&modlist_lock);
+                       return ret;
+               }
        }
+       read_unlock(&modlist_lock);
 #endif
 
        return 0;
index edae52c3824678e44d7ce7db74203d03b097bb4e..cfea418c5599dcca52ced8ae0796f3de56e853eb 100644 (file)
  *
  *      This file contains the procfs interface for the
  *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
+
+ *     Old code removed, switched to dynamic proc entry.
  */
 
 #include <linux/config.h>
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
 
-/*  adding proc entries from inside a module is REALLY complicated 
- *  for pre-2.1.28 kernels. I don't want to care about it.
- */
-
 #include <linux/proc_fs.h>
 
 #include <linux/ftape.h>
-#if LINUX_VERSION_CODE <= KERNEL_VER(1,2,13) /* bail out */
-#error \
-Please disable CONFIG_FT_PROC_FS in "MCONFIG" or upgrade to a newer kernel!
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,16)
 #include <linux/init.h>
-#else
-#define __initdata
-#define __initfunc(__arg) __arg
-#endif
 #include <linux/qic117.h>
 
-
 #include "../lowlevel/ftape-io.h"
 #include "../lowlevel/ftape-ctl.h"
 #include "../lowlevel/ftape-proc.h"
 #include "../lowlevel/ftape-tracing.h"
 
-static int ftape_read_proc(char *page, char **start, off_t off,
-                          int count, int *eof, void *data);
-
-#if LINUX_VERSION_CODE < KERNEL_VER(2,1,28)
-
-#include <asm/segment.h> /* for memcpy_tofs() */
-
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
-static long ftape_proc_read(struct inode* inode, struct file* file,
-                           char* buf, unsigned long count);
-#else
-static int ftape_proc_read(struct inode* inode, struct file* file,
-                          char* buf, int count);
-#endif
-
-#define FT_PROC_REGISTER(parent, child) proc_register_dynamic(parent, child)
-
-/*
- *     Structures for interfacing with the /proc filesystem.
- *     Router creates its own directory /proc/net/router with the folowing
- *     entries:
- *     config          device configuration
- *     status          global device statistics
- *     <device>        entry for each WAN device
- */
-
-/*
- *     Generic /proc/net/ftape/<file> file and inode operations
- */
-
-
-static struct file_operations ftape_proc_fops =
-{
-       NULL,                   /* lseek   */
-       ftape_proc_read,        /* read    */
-       NULL,                   /* write   */
-       NULL,                   /* readdir */
-       NULL,                   /* select  */
-       NULL,                   /* ioctl   */
-       NULL,                   /* mmap    */
-       NULL,                   /* no special open code    */
-       NULL,                   /* flush */
-       NULL,                   /* no special release code */
-       NULL,                   /* can't fsync */
-};
-
-static struct inode_operations ftape_proc_inode_operations =
-{
-       &ftape_proc_fops,
-       NULL,                   /* create */
-       NULL,                   /* lookup */
-       NULL,                   /* link */
-       NULL,                   /* unlink */
-       NULL,                   /* symlink */
-       NULL,                   /* mkdir */
-       NULL,                   /* rmdir */
-       NULL,                   /* mknod */
-       NULL,                   /* rename */
-       NULL,                   /* readlink */
-       NULL,                   /* follow_link */
-       NULL,                   /* get_block */
-       NULL,                   /* readpage */
-       NULL,                   /* writepage */
-       NULL,                   /* flushpage */
-       NULL,                   /* truncate */
-       NULL,                   /* permission */
-       NULL,                   /* smap */
-       NULL,                   /* revalidate */
-};
-
-/*
- * Proc filesystem directory entries.
- */
-
-static int ftape_get_info(char *page, char **start, off_t off,
-                         int count, int dummy)
-{
-       int dummy_eof;
-
-       return ftape_read_proc(page, start, off, count, &dummy_eof, NULL);
-}
-
-static struct proc_dir_entry proc_ftape = {
-       0,                            /* low_ino    */
-       sizeof("ftape")-1,            /* namelen    */
-       "ftape",                      /* name       */
-       S_IFREG | S_IRUGO,            /* mode       */
-       1,                            /* nlink      */
-       0,                            /* uid        */
-       0,                            /* gid        */
-       0,                            /* size       */
-       &ftape_proc_inode_operations, /* ops        */
-       ftape_get_info,               /* get_info   */
-       NULL,                         /* fill_inode */
-       NULL,                         /* next       */
-       NULL,                         /* parent     */
-       NULL,                         /* subdir     */
-       NULL                          /* data       */
-};
-
-/*  Read ftape proc directory entry.
- */
-
-#define PROC_BLOCK_SIZE        PAGE_SIZE
-
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
-static long ftape_proc_read(struct inode * inode, struct file * file,
-                           char * buf, unsigned long nbytes)
-#else
-static int ftape_proc_read(struct inode * inode, struct file * file,
-                          char * buf, int nbytes)
-#endif
-{
-       char    *page;
-       int     retval=0;
-       int     eof=0;
-       int     n, count;
-       char    *start;
-       struct proc_dir_entry * dp;
-
-       if (nbytes < 0)
-               return -EINVAL;
-       dp = (struct proc_dir_entry *) inode->u.generic_ip;
-       if (!(page = (char*) __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
-
-       while ((nbytes > 0) && !eof)
-       {
-               count = PROC_BLOCK_SIZE <= nbytes ? PROC_BLOCK_SIZE : nbytes;
-
-               start = NULL;
-               if (dp->get_info) {
-                       /*
-                        * Handle backwards compatibility with the old net
-                        * routines.
-                        * 
-                        * XXX What gives with the file->f_flags & O_ACCMODE
-                        * test?  Seems stupid to me....
-                        */
-                       n = dp->get_info(page, &start, file->f_pos, count,
-                                (file->f_flags & O_ACCMODE) == O_RDWR);
-                       if (n < count)
-                               eof = 1;
-               } else
-                       break;
-                       
-               if (!start) {
-                       /*
-                        * For proc files that are less than 4k
-                        */
-                       start = page + file->f_pos;
-                       n -= file->f_pos;
-                       if (n <= 0)
-                               break;
-                       if (n > count)
-                               n = count;
-               }
-               if (n == 0)
-                       break;  /* End of file */
-               if (n < 0) {
-                       if (retval == 0)
-                               retval = n;
-                       break;
-               }
-#if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
-               copy_to_user(buf, start, n);
-#else
-               memcpy_tofs(buf, start, n);
-#endif
-               file->f_pos += n;       /* Move down the file */
-               nbytes -= n;
-               buf += n;
-               retval += n;
-       }
-       free_page((unsigned long) page);
-       return retval;
-}
-
-#else /* LINUX_VERSION_CODE < KERNEL_VER(2,1,28) */
-
-#define FT_PROC_REGISTER(parent, child) proc_register(parent, child)
-
-/*
- * Proc filesystem directory entries.
- */
-
-static struct proc_dir_entry proc_ftape = {
-       0,                   /* low_ino    */
-       sizeof("ftape")-1,   /* namelen    */
-       "ftape",             /* name       */
-       S_IFREG | S_IRUGO,   /* mode       */
-       1,                   /* nlink      */
-       0,                   /* uid        */
-       0,                   /* gid        */
-       0,                   /* size       */
-       NULL,                /* ops        */
-       NULL,                /* get_info   */
-       NULL,                /* fill_inode */
-       NULL,                /* next       */
-       NULL,                /* parent     */
-       NULL,                /* subdir     */
-       NULL,                /* data       */
-       ftape_read_proc,     /* read_proc  */
-       NULL                 /* write_proc */
-};
-
-#endif
-
 static size_t get_driver_info(char *buf)
 {
        const char *debug_level[] = { "bugs"  ,
@@ -423,13 +203,14 @@ int ftape_read_proc(char *page, char **start, off_t off,
 
 int __init ftape_proc_init(void)
 {
-       return FT_PROC_REGISTER(&proc_root, &proc_ftape);
+       return create_proc_read_entry("ftape", 0, &proc_root,
+               ftape_read_proc, NULL) != NULL;
 }
 
 #ifdef MODULE
 void ftape_proc_destroy(void)
 {
-       proc_unregister(&proc_root, proc_ftape.low_ino);
+       remove_proc_entry("ftape", &proc_root);
 }
 #endif
 
index 8f0ef75ae7f43b1404828cb8b593001c8566022e..b31f10ac9fbe066b024273691be810a283321e8d 100644 (file)
 int ip2_read_procmem(char *, char **, off_t, int, int );
 int ip2_read_proc(char *, char **, off_t, int, int *, void * );
 
-struct proc_dir_entry ip2_proc_entry = {
-   0,
-   6,"ip2mem",
-   S_IFREG | S_IRUGO,
-   1, 0, 0,
-   0,
-   NULL,
-   ip2_read_procmem
-};
-
 /********************/
 /* Type Definitions */
 /********************/
@@ -429,9 +419,7 @@ cleanup_module(void)
        if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
                printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
        }
-       if ( ( err = proc_unregister( &proc_root, ip2_proc_entry.low_ino ) ) ) {
-               printk(KERN_ERR "IP2: failed to unregister read_procmem (%d)\n", err);
-       }
+       remove_proc_entry("ip2mem", &proc_root);
 
        // free memory
        for (i = 0; i < IP2_MAX_BOARDS; i++) {
@@ -673,8 +661,8 @@ old_ip2_init(void)
                printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
        } else
        /* Register the read_procmem thing */
-       if ( ( err = proc_register( &proc_root,  &ip2_proc_entry ) ) ) {
-               printk(KERN_ERR "IP2: failed to register read_procmem (%d)\n", err );
+       if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
+               printk(KERN_ERR "IP2: failed to register read_procmem\n");
        } else {
 
 #ifdef IP2DEBUG_TRACE
index 5594f51d1d54b4928ba399355c16126add188185..4467b8af60fd62e77b4bf4a040ea3577509d92c4 100644 (file)
@@ -147,7 +147,6 @@ static void join_net(u_long local);
 static void start_net(u_long local);
 /* void start_net(ray_dev_t *local); */
 
-static int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare);
 /* Create symbol table for registering with kernel in init_module */
 EXPORT_SYMBOL(ray_dev_ioctl);
 EXPORT_SYMBOL(ray_rx);
@@ -308,18 +307,6 @@ static char hop_pattern_length[] = { 1,
 
 static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
 
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry ray_cs_proc_entry = {
-    0,                         /* Dynamic inode # */
-    6,"ray_cs",                /* name length and name */
-    S_IFREG | S_IRUGO,         /* mode */
-    1, 0, 0,                   /* nlinks, owner, group */
-    0,                         /* size (unused) */
-    NULL,                      /* operations (default) */
-    &ray_cs_proc_read,         /* function to read data */
-    /* The end ?? */
-};
-#endif
 /*===========================================================================*/
 static void cs_error(client_handle_t handle, int func, int ret)
 {
@@ -2695,7 +2682,8 @@ static int __init init_ray_cs(void)
     rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
     DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
 #ifdef CONFIG_PROC_FS    
-    proc_register(&proc_root, &ray_cs_proc_entry);
+    /* [proc-namespace][fixme] It shouldn't be under root, damnit! */
+    create_proc_info_entry("ray_cs", 0, proc_root, ray_cs_proc_read);
 #endif    
     if (translate != 0) translate = 1;
     return 0;
@@ -2726,7 +2714,7 @@ static void __exit exit_ray_cs(void)
         ray_detach(dev_list);
     }
 #ifdef CONFIG_PROC_FS    
-    proc_unregister(&proc_root, ray_cs_proc_entry.low_ino);
+    remove_proc_entry("ray_cs", proc_root);
 #endif   
 } /* exit_ray_cs */
 
index 784d371434be8563a382b89130ce4ab27c48727f..32352c1e7113383fce0b9153ee8f171c9010006c 100644 (file)
@@ -247,7 +247,7 @@ static int __init isapnp_proc_init(void)
 static int isapnp_proc_done(void)
 {
        if (isapnp_proc_entry)
-               proc_unregister(&proc_root, isapnp_proc_entry->low_ino);
+               remove_proc_entry("isapnp",&proc_root);
        return 0;
 }
 #endif /* MODULE */
index e5fa93ed6b1ca94cc3beca01762758d053879d86..6b818225ef42b353c6d2985cf2b9d03ccedbc70d 100644 (file)
 #undef USE_STATIC_SCSI_MEMORY
 
 struct proc_dir_entry *proc_scsi = NULL;
+
+#ifdef CONFIG_PROC_FS
 static int scsi_proc_info(char *buffer, char **start, off_t offset,
                          int length, int inout);
+static void scsi_dump_status(int level);
+#endif
 
 /*
    static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
@@ -189,7 +193,6 @@ extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
                   || ((HOST)->host_blocked)                                       \
                   || ((DEVICE) != NULL && (DEVICE)->device_blocked) )
 
-static void scsi_dump_status(int level);
 
 
 struct dev_info {
@@ -1983,7 +1986,7 @@ int __init scsi_dev_init(void)
        /*
         * This makes /proc/scsi and /proc/scsi/scsi visible.
         */
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
        proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
        if (!proc_scsi) {
                printk (KERN_ERR "cannot init /proc/scsi\n");
@@ -2178,7 +2181,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset,
         * where token is one of [error,scan,mlqueue,mlcomplete,llqueue,
         * llcomplete,hlqueue,hlcomplete]
         */
-#if CONFIG_SCSI_LOGGING                /* { */
+#ifdef CONFIG_SCSI_LOGGING             /* { */
 
        if (!strncmp("log", buffer + 5, 3)) {
                char *token;
@@ -2614,7 +2617,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
                scsi_hosts = tpnt;
 
                /* Add the new driver to /proc/scsi */
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
                build_proc_dir_entries(tpnt);
 #endif
 
@@ -2884,7 +2887,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
                        if (shpnt->loaded_as_module) {
                                pcount = next_scsi_host;
                                /* Remove the /proc/scsi directory entry */
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
                                proc_scsi_unregister(tpnt->proc_dir,
                                        shpnt->host_no + PROC_SCSI_FILE);
 #endif
@@ -2946,7 +2949,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
                        break;
                }
        /* Rebuild the /proc/scsi directory entries */
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
        proc_scsi_unregister(tpnt->proc_dir, tpnt->proc_dir->low_ino);
 #endif
        MOD_DEC_USE_COUNT;
@@ -3133,6 +3136,7 @@ void scsi_unregister_module(int module_type, void *ptr)
 
 #endif                         /* CONFIG_MODULES */
 
+#ifdef CONFIG_PROC_FS
 /*
  * Function:    scsi_dump_status
  *
@@ -3153,8 +3157,7 @@ void scsi_unregister_module(int module_type, void *ptr)
  */
 static void scsi_dump_status(int level)
 {
-#if CONFIG_PROC_FS
-#if CONFIG_SCSI_LOGGING                /* { */
+#ifdef CONFIG_SCSI_LOGGING             /* { */
        int i;
        struct Scsi_Host *shpnt;
        Scsi_Cmnd *SCpnt;
@@ -3233,8 +3236,8 @@ static void scsi_dump_status(int level)
        }
        /* printk("wait_for_request = %p\n", &wait_for_request); */
 #endif /* CONFIG_SCSI_LOGGING */ /* } */
-#endif                         /* CONFIG_PROC_FS */
 }
+#endif                         /* CONFIG_PROC_FS */
 
 #ifdef MODULE
 
@@ -3246,7 +3249,7 @@ int init_module(void)
        /*
         * This makes /proc/scsi and /proc/scsi/scsi visible.
         */
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
        proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
        if (!proc_scsi) {
                printk (KERN_ERR "cannot init /proc/scsi\n");
@@ -3303,7 +3306,7 @@ void cleanup_module(void)
 {
        remove_bh(SCSI_BH);
 
-#if CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
        /* No, we're not here anymore. Don't show the /proc/scsi files. */
        remove_proc_entry ("scsi/scsi", 0);
        remove_proc_entry ("scsi", 0);
index f370c542a1eb48a76f8121b494fa41d6dc7ef030..0b42a14666f47ce5e5b26e3d8171e16769214d5f 100644 (file)
@@ -16,6 +16,7 @@
 #define _SCSI_H
 
 #include <linux/config.h>      /* for CONFIG_SCSI_LOGGING */
+#include <linux/proc_fs.h>
 
 /*
  * Some of the public constants are being moved to this file.
@@ -404,6 +405,50 @@ extern void scsi_release_command(Scsi_Cmnd *);
 extern int max_scsi_hosts;
 
 extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
+extern struct inode_operations proc_scsi_inode_operations;
+extern struct proc_dir_entry *proc_scsi;
+
+#ifdef CONFIG_PROC_FS
+
+extern inline int proc_scsi_register(struct proc_dir_entry *driver, 
+                                    struct proc_dir_entry *x)
+{
+    x->ops = &proc_scsi_inode_operations;
+    if(x->low_ino < PROC_SCSI_FILE){
+       return(proc_register(proc_scsi, x));
+    }else{
+       return(proc_register(driver, x));
+    }
+}
+
+extern inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
+{
+    extern void scsi_init_free(char *ptr, unsigned int size);
+
+    if(x < PROC_SCSI_FILE)
+       return(proc_unregister(proc_scsi, x));
+    else {
+       struct proc_dir_entry **p = &driver->subdir, *dp;
+       int ret;
+
+       while ((dp = *p) != NULL) {
+               if (dp->low_ino == x) 
+                   break;
+               p = &dp->next;
+       }
+       ret = proc_unregister(driver, x);
+       scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4);
+       return(ret);
+    }
+}
+
+#else
+
+extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
+extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
+
+#endif /* CONFIG_PROC_FS */
+
 
 extern void print_command(unsigned char *);
 extern void print_sense(const char *, Scsi_Cmnd *);
index 5a92ddbf93807764b7143d3433172f9435703f7c..d64b15f448f8b08962e752953000cbc334cb8e06 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/blk.h>
+
+#include <asm/uaccess.h>
+
 #include "scsi.h"
 #include "hosts.h"
 
@@ -77,7 +80,7 @@ int generic_proc_info(char *buffer, char **start, off_t offset,
 /* dispatch_scsi_info is the central dispatcher 
  * It is the interface between the proc-fs and the SCSI subsystem code
  */
-int dispatch_scsi_info(int ino, char *buffer, char **start,
+static int dispatch_scsi_info(int ino, char *buffer, char **start,
                              off_t offset, int length, int func)
 {
        struct Scsi_Host *hpnt = scsi_hostlist;
@@ -290,12 +293,6 @@ void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
        return;
 }
 
-#else
-
-void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
-{
-}
-
 /* forward references */
 static ssize_t proc_readscsi(struct file * file, char * buf,
                              size_t count, loff_t *ppos);
@@ -305,10 +302,6 @@ static long long proc_scsilseek(struct file *, long long, int);
 
 extern void build_proc_dir_hba_entries(uint);
 
-/* the *_get_info() functions are in the respective scsi driver code */
-int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
-                               off_t offset, int length, int inout) = 0;
-
 static struct file_operations proc_scsi_operations = {
     proc_scsilseek,    /* lseek   */
     proc_readscsi,     /* read    */
@@ -349,26 +342,6 @@ struct inode_operations proc_scsi_inode_operations = {
        NULL                    /* revalidate */
 };
 
-static int get_not_present_info(char *buffer, char **start, off_t offset, int length)
-{
-    int len, pos, begin;
-    
-    begin = 0;
-    pos = len = sprintf(buffer, 
-                       "No low-level scsi modules are currently present\n");
-    if(pos < offset) {
-       len = 0;
-       begin = pos;
-    }
-    
-    *start = buffer + (offset - begin);          /* Start of wanted data */
-    len -= (offset - begin);
-    if(len > length)
-       len = length;
-    
-    return(len);
-}
-
 #define PROC_BLOCK_SIZE (3*1024)     /* 4K page size, but our output routines 
                                      * use some slack for overruns 
                                      */
@@ -392,11 +365,8 @@ static ssize_t proc_readscsi(struct file * file, char * buf,
        if(bytes > PROC_BLOCK_SIZE)
            thistime = PROC_BLOCK_SIZE;
        
-       if(dispatch_scsi_info_ptr)
-           length = dispatch_scsi_info_ptr(inode->i_ino, page, &start, 
-                                           *ppos, thistime, 0);
-       else
-           length = get_not_present_info(page, &start, *ppos, thistime);
+       length = dispatch_scsi_info (inode->i_ino, page, &start, 
+                                    *ppos, thistime, 0);
        if(length < 0) {
            free_page((ulong) page);
            return(length);
@@ -438,13 +408,10 @@ static ssize_t proc_writescsi(struct file * file, const char * buf,
        return(-EOVERFLOW);
     }
 
-    if(dispatch_scsi_info_ptr != NULL) {
-        if (!(page = (char *) __get_free_page(GFP_KERNEL)))
-            return(-ENOMEM);
-       copy_from_user(page, buf, count);
-       ret = dispatch_scsi_info_ptr(inode->i_ino, page, 0, 0, count, 1);
-    } else 
-       return(-ENOPKG);          /* Nothing here */
+    if (!(page = (char *) __get_free_page(GFP_KERNEL)))
+       return(-ENOMEM);
+    copy_from_user(page, buf, count);
+    ret = dispatch_scsi_info (inode->i_ino, page, 0, 0, count, 1);
     
     free_page((ulong) page);
     return(ret);
@@ -467,6 +434,14 @@ static long long proc_scsilseek(struct file * file, long long offset, int orig)
     }
 }
 
+#else                          /* if !CONFIG_PROC_FS */
+
+void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len)
+{
+}
+
+struct inode_operations proc_scsi_inode_operations = { 0, };
+
 #endif                         /* CONFIG_PROC_FS */
 
 /*
index d3cb4a1031dcaabb8d64a3be2937aa5fa2f87e93..741b60710a2b57a9f521df6e7cc2a4049803f42f 100644 (file)
@@ -74,6 +74,7 @@ EXPORT_SYMBOL(scsi_sleep);
 
 EXPORT_SYMBOL(proc_print_scsidevice);
 EXPORT_SYMBOL(proc_scsi);
+EXPORT_SYMBOL(proc_scsi_inode_operations);
 
 /*
  * These are here only while I debug the rest of the scsi stuff.
index 060d5b26c5505ed4829f50cc65002c9b35a803de..21057e7dc8e2ba3852cdc2dc44b2b97b25b3e2bc 100644 (file)
@@ -251,13 +251,15 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
        struct buffer_head * bh;
        int i,j;
 
-       if (!dir || !(inode = get_empty_inode()))
+       inode = get_empty_inode();
+       if (!inode)
                return NULL;
        sb = dir->i_sb;
        inode->i_sb = sb;
        inode->i_flags = 0;
        j = 8192;
        bh = NULL;
+       lock_super(sb);
        for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
                bh = inode->i_sb->u.minix_sb.s_imap[i];
                if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
@@ -265,17 +267,20 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
        }
        if (!bh || j >= 8192) {
                iput(inode);
+               unlock_super(sb);
                return NULL;
        }
        if (minix_set_bit(j,bh->b_data)) {      /* shouldn't happen */
                printk("new_inode: bit already set");
                iput(inode);
+               unlock_super(sb);
                return NULL;
        }
        mark_buffer_dirty(bh, 1);
        j += i*8192;
        if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) {
                iput(inode);
+               unlock_super(sb);
                return NULL;
        }
        inode->i_nlink = 1;
index c707dd57221e5c14094a8015bceae85a9d70f7b8..181cc4e62fbfdcaf4267e1f4dbf864f4aedde104 100644 (file)
@@ -403,9 +403,9 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned
                ++*pages;
                if (pte_dirty(page))
                        ++*dirty;
-               if (MAP_NR(pte_page(page)) >= max_mapnr)
+               if (pte_pagenr(page) >= max_mapnr)
                        continue;
-               if (page_count(mem_map + MAP_NR(pte_page(page))) > 1)
+               if (page_count(pte_page(page)) > 1)
                        ++*shared;
        } while (address < end);
 }
index db052fc63004692a52c29941a3603fbb9eaf0604..1db720ca69570cf1e31cd1853e6c7c361da79cb9 100644 (file)
@@ -211,6 +211,7 @@ static void elf_kcore_store_hdr(char *bufp)
 #ifdef CONFIG_MODULES
        {
                struct module *m;
+               read_lock(&modlist_lock);
                for (m=module_list; m; m=m->next) {
                        dhdr = (struct elf_phdr *) bufp;
                        bufp += sizeof(struct elf_phdr);
@@ -226,6 +227,7 @@ static void elf_kcore_store_hdr(char *bufp)
                        dhdr->p_align   = 0;
                        elf->e_phnum++;
                }
+               read_unlock(&modlist_lock);
        }
 #endif
 
index 88c260f658b01022318a007ff98a34ecdaac1869..bb3a3de158dca940a86e009e31033dc0576d5a24 100644 (file)
@@ -8,6 +8,7 @@
 #define _LINUX_MODULE_H
 
 #include <linux/config.h>
+#include <linux/spinlock.h>
 
 #ifdef __GENKSYMS__
 #  define _set_ver(sym) sym
@@ -286,5 +287,6 @@ __attribute__((section("__ksymtab"))) =                     \
 #define EXPORT_NO_SYMBOLS
 #endif /* MODULE */
 
+extern rwlock_t modlist_lock;
 extern unsigned long get_kcore_size(void);
 #endif /* _LINUX_MODULE_H */
index 2c6b3874426cbd99d5e2ee9364dd2591056b529c..d3edb886b044cd1d8264935a45e5016e2e767f3d 100644 (file)
@@ -145,12 +145,6 @@ struct proc_dir_entry {
        int deleted;            /* delete flag */
 };
 
-#if 0 /* FIXME! /proc/scsi is broken right now */
-extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
-                               off_t offset, int length, int inout);
-extern struct inode_operations proc_scsi_inode_operations;
-#endif
-
 #define PROC_INODE_PROPER(inode) ((inode)->i_ino & ~0xffff)
 #define PROC_INODE_OPENPROM(inode) \
        ((inode->i_ino >= PROC_OPENPROM_FIRST) \
@@ -161,7 +155,6 @@ extern struct inode_operations proc_scsi_inode_operations;
 extern struct proc_dir_entry proc_root;
 extern struct proc_dir_entry *proc_root_fs;
 extern struct proc_dir_entry *proc_net;
-extern struct proc_dir_entry *proc_scsi;
 extern struct proc_dir_entry proc_sys;
 extern struct proc_dir_entry proc_openprom;
 extern struct proc_dir_entry *proc_mca;
@@ -184,41 +177,6 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
 
 
-extern inline int proc_scsi_register(struct proc_dir_entry *driver, 
-                                    struct proc_dir_entry *x)
-{
-#if 0 /* FIXME! */
-    x->ops = &proc_scsi_inode_operations;
-#endif
-    if(x->low_ino < PROC_SCSI_FILE){
-       return(proc_register(proc_scsi, x));
-    }else{
-       return(proc_register(driver, x));
-    }
-}
-
-extern inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
-{
-    extern void scsi_init_free(char *ptr, unsigned int size);
-
-    if(x < PROC_SCSI_FILE)
-       return(proc_unregister(proc_scsi, x));
-    else {
-       struct proc_dir_entry **p = &driver->subdir, *dp;
-       int ret;
-
-       while ((dp = *p) != NULL) {
-               if (dp->low_ino == x) 
-                   break;
-               p = &dp->next;
-       }
-       ret = proc_unregister(driver, x);
-       scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4);
-       return(ret);
-    }
-}
-
-
 /*
  * retrieve the proc_dir_entry associated with /proc/driver/$module_name
  */
@@ -362,8 +320,6 @@ extern inline int proc_unregister(struct proc_dir_entry *a, int b) { return 0; }
 extern inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode, 
        get_info_t *get_info) {return NULL;}
 extern inline void proc_net_remove(const char *name) {}
-extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
-extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
 
 extern inline struct proc_dir_entry *create_proc_entry(const char *name,
        mode_t mode, struct proc_dir_entry *parent) { return NULL; }
index 9b82e4e555b035537aa3b34fd1c728f66bfff6d9..a79fa619f22f81c37d3805f7787679f2d315a5a6 100644 (file)
@@ -13,6 +13,7 @@
  * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
  * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
  * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
+ * Use rw spinlock instead of global kernel lock for module_list, by TA <tigran@sco.com>
  *
  * This source is covered by the GNU GPL, the same as all kernel sources.
  */
@@ -52,6 +53,8 @@ static void put_mod_name(char *buf);
 static struct module *find_module(const char *name);
 static void free_module(struct module *, int tag_freed);
 
+rwlock_t modlist_lock = RW_LOCK_UNLOCKED;
+
 
 /* needed for /proc/kcore, here because kernel_module is static (TA) */
 unsigned long get_kcore_size(void)
@@ -62,14 +65,13 @@ unsigned long get_kcore_size(void)
        if (module_list == &kernel_module)
                return ((unsigned long)high_memory - PAGE_OFFSET + PAGE_SIZE);
 
-       /* shouldn't we have a rw spinlock for module_list? */
-       lock_kernel();
+       read_lock(&modlist_lock);
        for (m=module_list; m; m=m->next) {
                try = (unsigned long)m + m->size;
                if (try > size)
                        size = try;
        }
-       unlock_kernel();
+       read_unlock(&modlist_lock);
        return (size - PAGE_OFFSET + PAGE_SIZE);
 }
 
@@ -131,7 +133,7 @@ sys_create_module(const char *name_user, size_t size)
        long namelen, error;
        struct module *mod;
 
-       lock_kernel();
+       write_lock(&modlist_lock);
        if (!capable(CAP_SYS_MODULE)) {
                error = -EPERM;
                goto err0;
@@ -169,7 +171,7 @@ sys_create_module(const char *name_user, size_t size)
 err1:
        put_mod_name(name);
 err0:
-       unlock_kernel();
+       write_unlock(&modlist_lock);
        return error;
 }
 
@@ -186,7 +188,7 @@ sys_init_module(const char *name_user, struct module *mod_user)
        unsigned long mod_user_size;
        struct module_ref *dep;
 
-       lock_kernel();
+       write_lock(&modlist_lock);
        if (!capable(CAP_SYS_MODULE))
                goto err0;
        if ((namelen = get_mod_name(name_user, &name)) < 0) {
@@ -365,7 +367,7 @@ err2:
 err1:
        put_mod_name(name);
 err0:
-       unlock_kernel();
+       write_unlock(&modlist_lock);
        return error;
 }
 
@@ -377,7 +379,7 @@ sys_delete_module(const char *name_user)
        long error = -EPERM;
        int something_changed;
 
-       lock_kernel();
+       write_lock(&modlist_lock);
        if (!capable(CAP_SYS_MODULE))
                goto out;
 
@@ -430,7 +432,7 @@ restart:
                mod->flags &= ~MOD_JUST_FREED;
        error = 0;
 out:
-       unlock_kernel();
+       write_unlock(&modlist_lock);
        return error;
 }
 
@@ -444,17 +446,21 @@ qm_modules(char *buf, size_t bufsize, size_t *ret)
 
        nmod = space = 0;
 
+       read_lock(&modlist_lock);
        for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
                len = strlen(mod->name)+1;
                if (len > bufsize)
                        goto calc_space_needed;
-               if (copy_to_user(buf, mod->name, len))
+               if (copy_to_user(buf, mod->name, len)) {
+                       read_unlock(&modlist_lock);
                        return -EFAULT;
+               }
                buf += len;
                bufsize -= len;
                space += len;
        }
 
+       read_unlock(&modlist_lock);
        if (put_user(nmod, ret))
                return -EFAULT;
        else
@@ -465,6 +471,7 @@ calc_space_needed:
        while ((mod = mod->next) != &kernel_module)
                space += strlen(mod->name)+1;
 
+       read_unlock(&modlist_lock);
        if (put_user(space, ret))
                return -EFAULT;
        else
@@ -651,7 +658,7 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
        struct module *mod;
        int err;
 
-       lock_kernel();
+       read_lock(&modlist_lock);
        if (name_user == NULL)
                mod = &kernel_module;
        else {
@@ -697,7 +704,7 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
                break;
        }
 out:
-       unlock_kernel();
+       read_unlock(&modlist_lock);
        return err;
 }
 
@@ -716,7 +723,7 @@ sys_get_kernel_syms(struct kernel_sym *table)
        int i;
        struct kernel_sym ksym;
 
-       lock_kernel();
+       read_lock(&modlist_lock);
        for (mod = module_list, i = 0; mod; mod = mod->next) {
                /* include the count for the module name! */
                i += mod->nsyms + 1;
@@ -759,12 +766,13 @@ sys_get_kernel_syms(struct kernel_sym *table)
                }
        }
 out:
-       unlock_kernel();
+       read_unlock(&modlist_lock);
        return i;
 }
 
 /*
  * Look for a module by name, ignoring modules marked for deletion.
+ * Callers must hold modlist_lock at least in read mode.
  */
 
 static struct module *
@@ -784,6 +792,7 @@ find_module(const char *name)
 
 /*
  * Free the given module.
+ * Callers must hold modlist_lock in exclusive (write) mode.
  */
 
 static void
@@ -840,6 +849,7 @@ int get_module_list(char *p)
        char tmpstr[64];
        struct module_ref *ref;
 
+       read_lock(&modlist_lock);
        for (mod = module_list; mod != &kernel_module; mod = mod->next) {
                long len;
                const char *q;
@@ -905,6 +915,7 @@ int get_module_list(char *p)
        }
 
 fini:
+       read_unlock(&modlist_lock);
        return PAGE_SIZE - left;
 }
 
@@ -921,6 +932,7 @@ get_ksyms_list(char *buf, char **start, off_t offset, int length)
        off_t pos   = 0;
        off_t begin = 0;
 
+       read_lock(&modlist_lock);
        for (mod = module_list; mod; mod = mod->next) {
                unsigned i;
                struct module_symbol *sym;
@@ -955,6 +967,7 @@ leave_the_loop:
        len -= (offset - begin);
        if (len > length)
                len = length;
+       read_unlock(&modlist_lock);
        return len;
 }
 
@@ -971,6 +984,7 @@ get_module_symbol(char *modname, char *symname)
        struct module_symbol *sym;
        int i;
 
+       read_lock(&modlist_lock);
        for (mp = module_list; mp; mp = mp->next) {
                if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
                        (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
@@ -979,11 +993,13 @@ get_module_symbol(char *modname, char *symname)
                                i > 0; --i, ++sym) {
 
                                if (strcmp(sym->name, symname) == 0) {
+                                       read_unlock(&modlist_lock);
                                        return sym->value;
                                }
                        }
                }
        }
+       read_unlock(&modlist_lock);
        return 0;
 }