]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.infradead.org/mtd-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 5 Jun 2007 00:54:09 +0000 (17:54 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 5 Jun 2007 00:54:09 +0000 (17:54 -0700)
* git://git.infradead.org/mtd-2.6:
  [JFFS2] Fix obsoletion of metadata nodes in jffs2_add_tn_to_tree()
  [MTD] Fix error checking after get_mtd_device() in get_sb_mtd functions
  [JFFS2] Fix buffer length calculations in jffs2_get_inode_nodes()
  [JFFS2] Fix potential memory leak of dead xattrs on unmount.
  [JFFS2] Fix BUG() caused by failing to discard xattrs on deleted files.
  [MTD] generalise the handling of MTD-specific superblocks
  [MTD] [MAPS] don't force uclinux mtd map to be root dev

1  2 
fs/jffs2/super.c
include/linux/fs.h

diff --combined fs/jffs2/super.c
index 6488af43bc9b757e5de859184aacd987404d866f,e3c69e659efb100d5134adc579c08b731fbb5eab..e220d3bd610de5ae2bc3eb96441d0c9c3c1c8d28
@@@ -19,7 -19,7 +19,7 @@@
  #include <linux/mount.h>
  #include <linux/jffs2.h>
  #include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
+ #include <linux/mtd/super.h>
  #include <linux/ctype.h>
  #include <linux/namei.h>
  #include "compr.h"
@@@ -47,8 -47,11 +47,8 @@@ static void jffs2_i_init_once(void * fo
  {
        struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
  
 -      if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 -          SLAB_CTOR_CONSTRUCTOR) {
 -              init_MUTEX(&ei->sem);
 -              inode_init_once(&ei->vfs_inode);
 -      }
 +      init_MUTEX(&ei->sem);
 +      inode_init_once(&ei->vfs_inode);
  }
  
  static int jffs2_sync_fs(struct super_block *sb, int wait)
@@@ -75,69 -78,27 +75,27 @@@ static const struct super_operations jf
        .sync_fs =      jffs2_sync_fs,
  };
  
- static int jffs2_sb_compare(struct super_block *sb, void *data)
- {
-       struct jffs2_sb_info *p = data;
-       struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-       /* The superblocks are considered to be equivalent if the underlying MTD
-          device is the same one */
-       if (c->mtd == p->mtd) {
-               D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name));
-               return 1;
-       } else {
-               D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n",
-                         c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name));
-               return 0;
-       }
- }
- static int jffs2_sb_set(struct super_block *sb, void *data)
- {
-       struct jffs2_sb_info *p = data;
-       /* For persistence of NFS exports etc. we use the same s_dev
-          each time we mount the device, don't just use an anonymous
-          device */
-       sb->s_fs_info = p;
-       p->os_priv = sb;
-       sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
-       return 0;
- }
- static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
-                           int flags, const char *dev_name,
-                           void *data, struct mtd_info *mtd,
-                           struct vfsmount *mnt)
+ /*
+  * fill in the superblock
+  */
+ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
  {
-       struct super_block *sb;
        struct jffs2_sb_info *c;
-       int ret;
+       D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
+                 " New superblock for device %d (\"%s\")\n",
+                 sb->s_mtd->index, sb->s_mtd->name));
  
        c = kzalloc(sizeof(*c), GFP_KERNEL);
        if (!c)
                return -ENOMEM;
-       c->mtd = mtd;
-       sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
-       if (IS_ERR(sb))
-               goto out_error;
-       if (sb->s_root) {
-               /* New mountpoint for JFFS2 which is already mounted */
-               D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
-                         mtd->index, mtd->name));
-               ret = simple_set_mnt(mnt, sb);
-               goto out_put;
-       }
  
-       D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
-                 mtd->index, mtd->name));
+       c->mtd = sb->s_mtd;
+       c->os_priv = sb;
+       sb->s_fs_info = c;
  
-       /* Initialize JFFS2 superblock locks, the further initialization will be
-        * done later */
+       /* Initialize JFFS2 superblock locks, the further initialization will
+        * be done later */
        init_MUTEX(&c->alloc_sem);
        init_MUTEX(&c->erase_free_sem);
        init_waitqueue_head(&c->erase_wait);
        spin_lock_init(&c->inocache_lock);
  
        sb->s_op = &jffs2_super_operations;
-       sb->s_flags = flags | MS_NOATIME;
+       sb->s_flags = sb->s_flags | MS_NOATIME;
        sb->s_xattr = jffs2_xattr_handlers;
  #ifdef CONFIG_JFFS2_FS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
  #endif
-       ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
-       if (ret) {
-               /* Failure case... */
-               up_write(&sb->s_umount);
-               deactivate_super(sb);
-               return ret;
-       }
-       sb->s_flags |= MS_ACTIVE;
-       return simple_set_mnt(mnt, sb);
- out_error:
-       ret = PTR_ERR(sb);
-  out_put:
-       kfree(c);
-       put_mtd_device(mtd);
-       return ret;
- }
- static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
-                             int flags, const char *dev_name,
-                             void *data, int mtdnr,
-                             struct vfsmount *mnt)
- {
-       struct mtd_info *mtd;
-       mtd = get_mtd_device(NULL, mtdnr);
-       if (IS_ERR(mtd)) {
-               D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
-               return PTR_ERR(mtd);
-       }
-       return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
+       return jffs2_do_fill_super(sb, data, silent);
  }
  
  static int jffs2_get_sb(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
                        void *data, struct vfsmount *mnt)
  {
-       int err;
-       struct nameidata nd;
-       int mtdnr;
-       if (!dev_name)
-               return -EINVAL;
-       D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
-       /* The preferred way of mounting in future; especially when
-          CONFIG_BLK_DEV is implemented - we specify the underlying
-          MTD device by number or by name, so that we don't require
-          block device support to be present in the kernel. */
-       /* FIXME: How to do the root fs this way? */
-       if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
-               /* Probably mounting without the blkdev crap */
-               if (dev_name[3] == ':') {
-                       struct mtd_info *mtd;
-                       /* Mount by MTD device name */
-                       D1(printk(KERN_DEBUG "jffs2_get_sb(): 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 jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
-                                       put_mtd_device(mtd);
-                               }
-                       }
-                       printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4);
-               } else if (isdigit(dev_name[3])) {
-                       /* Mount by MTD device number name */
-                       char *endptr;
-                       mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
-                       if (!*endptr) {
-                               /* It was a valid number */
-                               D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
-                               return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
-                       }
-               }
-       }
-       /* Try the old way - the hack where we allowed users to mount
-          /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
-       err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-       D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n",
-                 err, nd.dentry->d_inode));
-       if (err)
-               return err;
-       err = -EINVAL;
-       if (!S_ISBLK(nd.dentry->d_inode->i_mode))
-               goto out;
-       if (nd.mnt->mnt_flags & MNT_NODEV) {
-               err = -EACCES;
-               goto out;
-       }
-       if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
-               if (!(flags & MS_SILENT))
-                       printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
-                              dev_name);
-               goto out;
-       }
-       mtdnr = iminor(nd.dentry->d_inode);
-       path_release(&nd);
-       return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
- out:
-       path_release(&nd);
-       return err;
+       return get_sb_mtd(fs_type, flags, dev_name, data, jffs2_fill_super,
+                         mnt);
  }
  
  static void jffs2_put_super (struct super_block *sb)
@@@ -307,8 -155,7 +152,7 @@@ static void jffs2_kill_sb(struct super_
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
        if (!(sb->s_flags & MS_RDONLY))
                jffs2_stop_garbage_collect_thread(c);
-       generic_shutdown_super(sb);
-       put_mtd_device(c->mtd);
+       kill_mtd_super(sb);
        kfree(c);
  }
  
diff --combined include/linux/fs.h
index 7cf0c54a46a7fff64365b3184ea492d572dac9b0,151739a55eaff67d9360b94ff4856d071ed4b2e3..b3ae77cccbb6723499e094ec01cd4660607fcee7
@@@ -30,7 -30,6 +30,7 @@@
  #define SEEK_SET      0       /* seek relative to beginning of file */
  #define SEEK_CUR      1       /* seek relative to current file position */
  #define SEEK_END      2       /* seek relative to end of file */
 +#define SEEK_MAX      SEEK_END
  
  /* And dynamically-tunable limits and defaults: */
  struct files_stat_struct {
@@@ -92,7 -91,6 +92,7 @@@ extern int dir_notify_enable
  /* public flags for file_system_type */
  #define FS_REQUIRES_DEV 1 
  #define FS_BINARY_MOUNTDATA 2
 +#define FS_HAS_SUBTYPE 4
  #define FS_REVAL_DOT  16384   /* Check the paths ".", ".." for staleness */
  #define FS_RENAME_DOES_D_MOVE 32768   /* FS will handle d_move()
                                         * during rename() internally.
@@@ -698,13 -696,12 +698,13 @@@ struct file_ra_state 
        unsigned long size;
        unsigned long flags;            /* ra flags RA_FLAG_xxx*/
        unsigned long cache_hit;        /* cache hit count*/
 -      unsigned long prev_page;        /* Cache last read() position */
 +      unsigned long prev_index;       /* Cache last read() position */
        unsigned long ahead_start;      /* Ahead window */
        unsigned long ahead_size;
        unsigned long ra_pages;         /* Maximum readahead window */
        unsigned long mmap_hit;         /* Cache hit stat for mmap accesses */
        unsigned long mmap_miss;        /* Cache miss stat for mmap accesses */
 +      unsigned int prev_offset;       /* Offset where last read() ended in a page */
  };
  #define RA_FLAG_MISS 0x01     /* a cache miss occured against this file */
  #define RA_FLAG_INCACHE 0x02  /* file is already in cache */
@@@ -788,7 -785,6 +788,7 @@@ struct file_lock_operations 
  struct lock_manager_operations {
        int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
        void (*fl_notify)(struct file_lock *);  /* unblock callback */
 +      int (*fl_grant)(struct file_lock *, struct file_lock *, int);
        void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
        void (*fl_release_private)(struct file_lock *);
        void (*fl_break)(struct file_lock *);
@@@ -849,19 -845,22 +849,19 @@@ extern int fcntl_getlease(struct file *
  /* fs/sync.c */
  extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
                        loff_t endbyte, unsigned int flags);
 -static inline int do_sync_file_range(struct file *file, loff_t offset,
 -                      loff_t endbyte, unsigned int flags)
 -{
 -      return do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
 -}
  
  /* fs/locks.c */
  extern void locks_init_lock(struct file_lock *);
  extern void locks_copy_lock(struct file_lock *, struct file_lock *);
  extern void locks_remove_posix(struct file *, fl_owner_t);
  extern void locks_remove_flock(struct file *);
 -extern int posix_test_lock(struct file *, struct file_lock *, struct file_lock *);
 -extern int posix_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
 -extern int posix_lock_file(struct file *, struct file_lock *);
 +extern int posix_test_lock(struct file *, struct file_lock *);
 +extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
  extern int posix_lock_file_wait(struct file *, struct file_lock *);
  extern int posix_unblock_lock(struct file *, struct file_lock *);
 +extern int vfs_test_lock(struct file *, struct file_lock *);
 +extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
 +extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
  extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
  extern int __break_lease(struct inode *inode, unsigned int flags);
  extern void lease_get_mtime(struct inode *, struct timespec *time);
@@@ -938,6 -937,7 +938,7 @@@ struct super_block 
        struct list_head        s_files;
  
        struct block_device     *s_bdev;
+       struct mtd_info         *s_mtd;
        struct list_head        s_instances;
        struct quota_info       s_dquot;        /* Diskquota specific options */
  
        /* Granularity of c/m/atime in ns.
           Cannot be worse than a second */
        u32                s_time_gran;
 +
 +      /*
 +       * Filesystem subtype.  If non-empty the filesystem type field
 +       * in /proc/mounts will be "type.subtype"
 +       */
 +      char *s_subtype;
  };
  
  extern struct timespec current_fs_time(struct super_block *sb);
@@@ -1423,7 -1417,7 +1424,7 @@@ extern void mnt_set_mountpoint(struct v
  extern int vfs_statfs(struct dentry *, struct kstatfs *);
  
  /* /sys/fs */
 -extern struct subsystem fs_subsys;
 +extern struct kset fs_subsys;
  
  #define FLOCK_VERIFY_READ  1
  #define FLOCK_VERIFY_WRITE 2
@@@ -1738,8 -1732,6 +1739,8 @@@ extern ssize_t generic_file_sendfile(st
  extern void do_generic_mapping_read(struct address_space *mapping,
                                    struct file_ra_state *, struct file *,
                                    loff_t *, read_descriptor_t *, read_actor_t);
 +extern int generic_segment_checks(const struct iovec *iov,
 +              unsigned long *nr_segs, size_t *count, int access_flags);
  
  /* fs/splice.c */
  extern ssize_t generic_file_splice_read(struct file *, loff_t *,