[PATCH] fix race in inotify_release
[pandora-kernel.git] / fs / char_dev.c
index 4e1b849..f3418f7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/seq_file.h>
 
 #include <linux/kobject.h>
 #include <linux/kobj_map.h>
@@ -27,8 +28,6 @@
 
 static struct kobj_map *cdev_map;
 
-#define MAX_PROBE_HASH 255     /* random */
-
 static DEFINE_MUTEX(chrdevs_lock);
 
 static struct char_device_struct {
@@ -39,93 +38,29 @@ static struct char_device_struct {
        char name[64];
        struct file_operations *fops;
        struct cdev *cdev;              /* will die */
-} *chrdevs[MAX_PROBE_HASH];
+} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
 
 /* index in the above */
 static inline int major_to_index(int major)
 {
-       return major % MAX_PROBE_HASH;
-}
-
-struct chrdev_info {
-       int index;
-       struct char_device_struct *cd;
-};
-
-void *get_next_chrdev(void *dev)
-{
-       struct chrdev_info *info;
-
-       if (dev == NULL) {
-               info = kmalloc(sizeof(*info), GFP_KERNEL);
-               if (!info)
-                       goto out;
-               info->index=0;
-               info->cd = chrdevs[info->index];
-               if (info->cd)
-                       goto out;
-       } else {
-               info = dev;
-       }
-
-       while (info->index < ARRAY_SIZE(chrdevs)) {
-               if (info->cd)
-                       info->cd = info->cd->next;
-               if (info->cd)
-                       goto out;
-               /*
-                * No devices on this chain, move to the next
-                */
-               info->index++;
-               info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
-                       chrdevs[info->index] : NULL;
-               if (info->cd)
-                       goto out;
-       }
-
-out:
-       return info;
-}
-
-void *acquire_chrdev_list(void)
-{
-       mutex_lock(&chrdevs_lock);
-       return get_next_chrdev(NULL);
-}
-
-void release_chrdev_list(void *dev)
-{
-       mutex_unlock(&chrdevs_lock);
-       kfree(dev);
+       return major % CHRDEV_MAJOR_HASH_SIZE;
 }
 
+#ifdef CONFIG_PROC_FS
 
-int count_chrdev_list(void)
+void chrdev_show(struct seq_file *f, off_t offset)
 {
        struct char_device_struct *cd;
-       int i, count;
-
-       count = 0;
 
-       for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
-               for (cd = chrdevs[i]; cd; cd = cd->next)
-                       count++;
+       if (offset < CHRDEV_MAJOR_HASH_SIZE) {
+               mutex_lock(&chrdevs_lock);
+               for (cd = chrdevs[offset]; cd; cd = cd->next)
+                       seq_printf(f, "%3d %s\n", cd->major, cd->name);
+               mutex_unlock(&chrdevs_lock);
        }
-
-       return count;
 }
 
-int get_chrdev_info(void *dev, int *major, char **name)
-{
-       struct chrdev_info *info = dev;
-
-       if (info->cd == NULL)
-               return 1;
-
-       *major = info->cd->major;
-       *name = info->cd->name;
-       return 0;
-}
+#endif /* CONFIG_PROC_FS */
 
 /*
  * Register a single major with a specified minor range.