Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / mtd / mtdsuper.c
index 9b430f2..bd9a443 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mtd/super.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 /*
  * compare superblocks to see if they're equivalent
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
 
        sb->s_mtd = mtd;
        sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+       sb->s_bdi = mtd->backing_dev_info;
        return 0;
 }
 
@@ -74,20 +76,22 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
 
        ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
        if (ret < 0) {
-               up_write(&sb->s_umount);
-               deactivate_super(sb);
+               deactivate_locked_super(sb);
                return ret;
        }
 
        /* go */
        sb->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+
+       return 0;
 
        /* new mountpoint for an already mounted superblock */
 already_mounted:
        DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
              mtd->index, mtd->name);
-       ret = simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       ret = 0;
        goto out_put;
 
 out_error:
@@ -125,8 +129,11 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
               int (*fill_super)(struct super_block *, void *, int),
               struct vfsmount *mnt)
 {
-       struct nameidata nd;
-       int mtdnr, ret;
+#ifdef CONFIG_BLOCK
+       struct block_device *bdev;
+       int ret, major;
+#endif
+       int mtdnr;
 
        if (!dev_name)
                return -EINVAL;
@@ -145,18 +152,12 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
                        DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
                              dev_name + 4);
 
-                       for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
-                               mtd = get_mtd_device(NULL, mtdnr);
-                               if (!IS_ERR(mtd)) {
-                                       if (!strcmp(mtd->name, dev_name + 4))
-                                               return get_sb_mtd_aux(
-                                                       fs_type, flags,
-                                                       dev_name, data, mtd,
-                                                       fill_super, mnt);
-
-                                       put_mtd_device(mtd);
-                               }
-                       }
+                       mtd = get_mtd_device_nm(dev_name + 4);
+                       if (!IS_ERR(mtd))
+                               return get_sb_mtd_aux(
+                                       fs_type, flags,
+                                       dev_name, data, mtd,
+                                       fill_super, mnt);
 
                        printk(KERN_NOTICE "MTD:"
                               " MTD device with name \"%s\" not found.\n",
@@ -178,45 +179,38 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
                }
        }
 
+#ifdef CONFIG_BLOCK
        /* try the old way - the hack where we allowed users to mount
         * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
         */
-       ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-
-       DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
-             ret, nd.dentry ? nd.dentry->d_inode : NULL);
-
-       if (ret)
+       bdev = lookup_bdev(dev_name);
+       if (IS_ERR(bdev)) {
+               ret = PTR_ERR(bdev);
+               DEBUG(1, "MTDSB: lookup_bdev() returned %d\n", ret);
                return ret;
+       }
+       DEBUG(1, "MTDSB: lookup_bdev() returned 0\n");
 
        ret = -EINVAL;
 
-       if (!S_ISBLK(nd.dentry->d_inode->i_mode))
-               goto out;
+       major = MAJOR(bdev->bd_dev);
+       mtdnr = MINOR(bdev->bd_dev);
+       bdput(bdev);
 
-       if (nd.mnt->mnt_flags & MNT_NODEV) {
-               ret = -EACCES;
-               goto out;
-       }
-
-       if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
+       if (major != MTD_BLOCK_MAJOR)
                goto not_an_MTD_device;
 
-       mtdnr = iminor(nd.dentry->d_inode);
-       path_release(&nd);
-
        return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
                             mnt);
 
 not_an_MTD_device:
+#endif /* CONFIG_BLOCK */
+
        if (!(flags & MS_SILENT))
                printk(KERN_NOTICE
                       "MTD: Attempt to mount non-MTD device \"%s\"\n",
                       dev_name);
-out:
-       path_release(&nd);
-       return ret;
-
+       return -EINVAL;
 }
 
 EXPORT_SYMBOL_GPL(get_sb_mtd);