zero i_uid/i_gid on inode allocation
[safe/jmp/linux-2.6] / drivers / usb / core / inode.c
index f48c3db..2a129cb 100644 (file)
 #include <linux/usb.h>
 #include <linux/namei.h>
 #include <linux/usbdevice_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/parser.h>
 #include <linux/notifier.h>
+#include <linux/seq_file.h>
 #include <asm/byteorder.h>
 #include "usb.h"
 #include "hcd.h"
 
+#define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO)
+#define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
+#define USBFS_DEFAULT_LISTMODE S_IRUGO
+
 static struct super_operations usbfs_ops;
-static struct file_operations default_file_operations;
+static const struct file_operations default_file_operations;
 static struct vfsmount *usbfs_mount;
 static int usbfs_mount_count;  /* = 0 */
 static int ignore_mount = 0;
@@ -58,9 +62,33 @@ static uid_t listuid;        /* = 0 */
 static gid_t devgid;   /* = 0 */
 static gid_t busgid;   /* = 0 */
 static gid_t listgid;  /* = 0 */
-static umode_t devmode = S_IWUSR | S_IRUGO;
-static umode_t busmode = S_IXUGO | S_IRUGO;
-static umode_t listmode = S_IRUGO;
+static umode_t devmode = USBFS_DEFAULT_DEVMODE;
+static umode_t busmode = USBFS_DEFAULT_BUSMODE;
+static umode_t listmode = USBFS_DEFAULT_LISTMODE;
+
+static int usbfs_show_options(struct seq_file *seq, struct vfsmount *mnt)
+{
+       if (devuid != 0)
+               seq_printf(seq, ",devuid=%u", devuid);
+       if (devgid != 0)
+               seq_printf(seq, ",devgid=%u", devgid);
+       if (devmode != USBFS_DEFAULT_DEVMODE)
+               seq_printf(seq, ",devmode=%o", devmode);
+       if (busuid != 0)
+               seq_printf(seq, ",busuid=%u", busuid);
+       if (busgid != 0)
+               seq_printf(seq, ",busgid=%u", busgid);
+       if (busmode != USBFS_DEFAULT_BUSMODE)
+               seq_printf(seq, ",busmode=%o", busmode);
+       if (listuid != 0)
+               seq_printf(seq, ",listuid=%u", listuid);
+       if (listgid != 0)
+               seq_printf(seq, ",listgid=%u", listgid);
+       if (listmode != USBFS_DEFAULT_LISTMODE)
+               seq_printf(seq, ",listmode=%o", listmode);
+
+       return 0;
+}
 
 enum {
        Opt_devuid, Opt_devgid, Opt_devmode,
@@ -69,7 +97,7 @@ enum {
        Opt_err,
 };
 
-static match_table_t tokens = {
+static const match_table_t tokens = {
        {Opt_devuid, "devuid=%u"},
        {Opt_devgid, "devgid=%u"},
        {Opt_devmode, "devmode=%o"},
@@ -94,9 +122,9 @@ static int parse_options(struct super_block *s, char *data)
        devgid = 0;
        busgid = 0;
        listgid = 0;
-       devmode = S_IWUSR | S_IRUGO;
-       busmode = S_IXUGO | S_IRUGO;
-       listmode = S_IRUGO;
+       devmode = USBFS_DEFAULT_DEVMODE;
+       busmode = USBFS_DEFAULT_BUSMODE;
+       listmode = USBFS_DEFAULT_LISTMODE;
 
        while ((p = strsep(&data, ",")) != NULL) {
                substring_t args[MAX_OPT_ARGS];
@@ -152,8 +180,8 @@ static int parse_options(struct super_block *s, char *data)
                        listmode = option & S_IRWXUGO;
                        break;
                default:
-                       err("usbfs: unrecognised mount option \"%s\" "
-                           "or missing value\n", p);
+                       printk(KERN_ERR "usbfs: unrecognised mount option "
+                              "\"%s\" or missing value\n", p);
                        return -EINVAL;
                }
        }
@@ -212,7 +240,9 @@ static void update_sb(struct super_block *sb)
                                update_special(bus);
                                break;
                        default:
-                               warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode);
+                               printk(KERN_WARNING "usbfs: Unknown node %s "
+                                      "mode %x found on remount!\n",
+                                      bus->d_name.name, bus->d_inode->i_mode);
                                break;
                        }
                }
@@ -231,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
                return 0;
 
        if (parse_options(sb, data)) {
-               warn("usbfs: mount parameter error:");
+               printk(KERN_WARNING "usbfs: mount parameter error.\n");
                return -EINVAL;
        }
 
@@ -247,10 +277,8 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
 
        if (inode) {
                inode->i_mode = mode;
-               inode->i_uid = current->fsuid;
-               inode->i_gid = current->fsgid;
-               inode->i_blksize = PAGE_CACHE_SIZE;
-               inode->i_blocks = 0;
+               inode->i_uid = current_fsuid();
+               inode->i_gid = current_fsgid();
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                switch (mode & S_IFMT) {
                default:
@@ -264,7 +292,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
                        inode->i_fop = &simple_dir_operations;
 
                        /* directory inodes start off with i_nlink == 2 (for "." entry) */
-                       inode->i_nlink++;
+                       inc_nlink(inode);
                        break;
                }
        }
@@ -296,7 +324,7 @@ static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
        mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
        res = usbfs_mknod (dir, dentry, mode, 0);
        if (!res)
-               dir->i_nlink++;
+               inc_nlink(dir);
        return res;
 }
 
@@ -333,7 +361,7 @@ static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
 {
        struct inode *inode = dentry->d_inode;
        mutex_lock(&inode->i_mutex);
-       dentry->d_inode->i_nlink--;
+       drop_nlink(dentry->d_inode);
        dput(dentry);
        mutex_unlock(&inode->i_mutex);
        d_delete(dentry);
@@ -348,10 +376,11 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
        mutex_lock(&inode->i_mutex);
        dentry_unhash(dentry);
        if (usbfs_empty(dentry)) {
-               dentry->d_inode->i_nlink -= 2;
+               drop_nlink(dentry->d_inode);
+               drop_nlink(dentry->d_inode);
                dput(dentry);
                inode->i_flags |= S_DEAD;
-               dir->i_nlink--;
+               drop_nlink(dir);
                error = 0;
        }
        mutex_unlock(&inode->i_mutex);
@@ -379,7 +408,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
 {
        loff_t retval = -EINVAL;
 
-       mutex_lock(&file->f_dentry->d_inode->i_mutex);
+       mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
        switch(orig) {
        case 0:
                if (offset > 0) {
@@ -396,19 +425,19 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
        default:
                break;
        }
-       mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+       mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
        return retval;
 }
 
 static int default_open (struct inode *inode, struct file *file)
 {
-       if (inode->u.generic_ip)
-               file->private_data = inode->u.generic_ip;
+       if (inode->i_private)
+               file->private_data = inode->i_private;
 
        return 0;
 }
 
-static struct file_operations default_file_operations = {
+static const struct file_operations default_file_operations = {
        .read =         default_read_file,
        .write =        default_write_file,
        .open =         default_open,
@@ -419,6 +448,7 @@ static struct super_operations usbfs_ops = {
        .statfs =       simple_statfs,
        .drop_inode =   generic_delete_inode,
        .remount_fs =   remount,
+       .show_options = usbfs_show_options,
 };
 
 static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -434,13 +464,13 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
        inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
 
        if (!inode) {
-               dbg("%s: could not get inode!",__FUNCTION__);
+               dbg("%s: could not get inode!",__func__);
                return -ENOMEM;
        }
 
        root = d_alloc_root(inode);
        if (!root) {
-               dbg("%s: could not get root dentry!",__FUNCTION__);
+               dbg("%s: could not get root dentry!",__func__);
                iput(inode);
                return -ENOMEM;
        }
@@ -495,7 +525,7 @@ static int fs_create_by_name (const char *name, mode_t mode,
 
 static struct dentry *fs_create_file (const char *name, mode_t mode,
                                      struct dentry *parent, void *data,
-                                     struct file_operations *fops,
+                                     const struct file_operations *fops,
                                      uid_t uid, gid_t gid)
 {
        struct dentry *dentry;
@@ -509,7 +539,7 @@ static struct dentry *fs_create_file (const char *name, mode_t mode,
        } else {
                if (dentry->d_inode) {
                        if (data)
-                               dentry->d_inode->u.generic_ip = data;
+                               dentry->d_inode->i_private = data;
                        if (fops)
                                dentry->d_inode->i_fop = fops;
                        dentry->d_inode->i_uid = uid;
@@ -570,7 +600,7 @@ static int create_special_files (void)
        /* create the devices special file */
        retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
        if (retval) {
-               err ("Unable to get usbfs mount");
+               printk(KERN_ERR "Unable to get usbfs mount\n");
                goto exit;
        }
 
@@ -582,7 +612,7 @@ static int create_special_files (void)
                                               NULL, &usbfs_devices_fops,
                                               listuid, listgid);
        if (devices_usbfs_dentry == NULL) {
-               err ("Unable to create devices usbfs file");
+               printk(KERN_ERR "Unable to create devices usbfs file\n");
                retval = -ENODEV;
                goto error_clean_mounts;
        }
@@ -634,7 +664,7 @@ static void usbfs_add_bus(struct usb_bus *bus)
        bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
                                            bus, NULL, busuid, busgid);
        if (bus->usbfs_dentry == NULL) {
-               err ("error creating usbfs bus entry");
+               printk(KERN_ERR "Error creating usbfs bus entry\n");
                return;
        }
 }
@@ -662,10 +692,10 @@ static void usbfs_add_device(struct usb_device *dev)
        sprintf (name, "%03d", dev->devnum);
        dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
                                            dev->bus->usbfs_dentry, dev,
-                                           &usbfs_device_file_operations,
+                                           &usbdev_file_operations,
                                            devuid, devgid);
        if (dev->usbfs_dentry == NULL) {
-               err ("error creating usbfs device entry");
+               printk(KERN_ERR "Error creating usbfs device entry\n");
                return;
        }
 
@@ -683,25 +713,11 @@ static void usbfs_add_device(struct usb_device *dev)
 
 static void usbfs_remove_device(struct usb_device *dev)
 {
-       struct dev_state *ds;
-       struct siginfo sinfo;
-
        if (dev->usbfs_dentry) {
                fs_remove_file (dev->usbfs_dentry);
                dev->usbfs_dentry = NULL;
        }
-       while (!list_empty(&dev->filelist)) {
-               ds = list_entry(dev->filelist.next, struct dev_state, list);
-               wake_up_all(&ds->wait);
-               list_del_init(&ds->list);
-               if (ds->discsignr) {
-                       sinfo.si_signo = SIGPIPE;
-                       sinfo.si_errno = EPIPE;
-                       sinfo.si_code = SI_ASYNCIO;
-                       sinfo.si_addr = ds->disccontext;
-                       kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
-               }
-       }
+       usb_fs_classdev_common_remove(dev);
 }
 
 static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
@@ -744,7 +760,7 @@ int __init usbfs_init(void)
        usb_register_notify(&usbfs_nb);
 
        /* create mount point for usbfs */
-       usbdir = proc_mkdir("usb", proc_bus);
+       usbdir = proc_mkdir("bus/usb", NULL);
 
        return 0;
 }
@@ -754,6 +770,6 @@ void usbfs_cleanup(void)
        usb_unregister_notify(&usbfs_nb);
        unregister_filesystem(&usb_fs_type);
        if (usbdir)
-               remove_proc_entry("usb", proc_bus);
+               remove_proc_entry("bus/usb", NULL);
 }