]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Jan 2012 20:51:21 +0000 (12:51 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Jan 2012 20:51:21 +0000 (12:51 -0800)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2/3/4: delete unneeded includes of module.h
  ext{3,4}: Fix potential race when setversion ioctl updates inode
  udf: Mark LVID buffer as uptodate before marking it dirty
  ext3: Don't warn from writepage when readonly inode is spotted after error
  jbd: Remove j_barrier mutex
  reiserfs: Force inode evictions before umount to avoid crash
  reiserfs: Fix quota mount option parsing
  udf: Treat symlink component of type 2 as /
  udf: Fix deadlock when converting file from in-ICB one to normal one
  udf: Cleanup calling convention of inode_getblk()
  ext2: Fix error handling on inode bitmap corruption
  ext3: Fix error handling on inode bitmap corruption
  ext3: replace ll_rw_block with other functions
  ext3: NULL dereference in ext3_evict_inode()
  jbd: clear revoked flag on buffers before a new transaction started
  ext3: call ext3_mark_recovery_complete() when recovery is really needed

15 files changed:
1  2 
fs/ext2/ialloc.c
fs/ext2/super.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/ioctl.c
fs/ext3/namei.c
fs/ext3/super.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/page-io.c
fs/jbd/journal.c
fs/reiserfs/super.c
fs/udf/inode.c
fs/udf/super.c

diff --combined fs/ext2/ialloc.c
index cd7f5f424a757a9717ebf4f0a7e863ccd1d202b1,78502c166814f596c2fc5be589749d915c4e5076..8b15cf8cef37bfa29360444204eacfd5b722b952
@@@ -429,7 -429,7 +429,7 @@@ found
        return group;
  }
  
 -struct inode *ext2_new_inode(struct inode *dir, int mode,
 +struct inode *ext2_new_inode(struct inode *dir, umode_t mode,
                             const struct qstr *qstr)
  {
        struct super_block *sb;
@@@ -573,8 -573,11 +573,11 @@@ got
        inode->i_generation = sbi->s_next_generation++;
        spin_unlock(&sbi->s_next_gen_lock);
        if (insert_inode_locked(inode) < 0) {
-               err = -EINVAL;
-               goto fail_drop;
+               ext2_error(sb, "ext2_new_inode",
+                          "inode number already in use - inode=%lu",
+                          (unsigned long) ino);
+               err = -EIO;
+               goto fail;
        }
  
        dquot_initialize(inode);
diff --combined fs/ext2/super.c
index 9b403f064ce09304c56ed2b6d767ac7eb37798e1,9e7e203146b19b643fccd5108f677579657ed073..0090595beb28de8243cc6cfd2437dd007c6a7a69
@@@ -173,6 -173,7 +173,6 @@@ static struct inode *ext2_alloc_inode(s
  static void ext2_i_callback(struct rcu_head *head)
  {
        struct inode *inode = container_of(head, struct inode, i_rcu);
 -      INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(ext2_inode_cachep, EXT2_I(inode));
  }
  
@@@ -210,9 -211,9 +210,9 @@@ static void destroy_inodecache(void
        kmem_cache_destroy(ext2_inode_cachep);
  }
  
 -static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
 +static int ext2_show_options(struct seq_file *seq, struct dentry *root)
  {
 -      struct super_block *sb = vfs->mnt_sb;
 +      struct super_block *sb = root->d_sb;
        struct ext2_sb_info *sbi = EXT2_SB(sb);
        struct ext2_super_block *es = sbi->s_es;
        unsigned long def_mount_opts;
@@@ -1520,5 -1521,8 +1520,8 @@@ static void __exit exit_ext2_fs(void
        exit_ext2_xattr();
  }
  
+ MODULE_AUTHOR("Remy Card and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem");
+ MODULE_LICENSE("GPL");
  module_init(init_ext2_fs)
  module_exit(exit_ext2_fs)
diff --combined fs/ext3/ialloc.c
index 92cc86dfa23db90609115abfa37b0f4043a523a0,adae962ee9579b62fec146253404d8a10208927e..1cde28438014bfaccd9b1e2b27785044d9f26aec
@@@ -371,7 -371,7 +371,7 @@@ static int find_group_other(struct supe
   * group to find a free inode.
   */
  struct inode *ext3_new_inode(handle_t *handle, struct inode * dir,
 -                           const struct qstr *qstr, int mode)
 +                           const struct qstr *qstr, umode_t mode)
  {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@@ -525,8 -525,12 +525,12 @@@ got
        if (IS_DIRSYNC(inode))
                handle->h_sync = 1;
        if (insert_inode_locked(inode) < 0) {
-               err = -EINVAL;
-               goto fail_drop;
+               /*
+                * Likely a bitmap corruption causing inode to be allocated
+                * twice.
+                */
+               err = -EIO;
+               goto fail;
        }
        spin_lock(&sbi->s_next_gen_lock);
        inode->i_generation = sbi->s_next_generation++;
diff --combined fs/ext3/inode.c
index 15cb47088aac79083efa18203be0e35bea759292,261979feb4b5f195549e69a93282f983ca3ba231..2d0afeca0b479a9e5f3c80f6a98511a47643235a
@@@ -22,7 -22,6 +22,6 @@@
   *  Assorted race fixes, rewrite of ext3_get_block() by Al Viro, 2000
   */
  
- #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/time.h>
  #include <linux/ext3_jbd.h>
@@@ -223,8 -222,12 +222,12 @@@ void ext3_evict_inode (struct inode *in
         *
         * Note that directories do not have this problem because they don't
         * use page cache.
+        *
+        * The s_journal check handles the case when ext3_get_journal() fails
+        * and puts the journal inode.
         */
        if (inode->i_nlink && ext3_should_journal_data(inode) &&
+           EXT3_SB(inode->i_sb)->s_journal &&
            (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
                tid_t commit_tid = atomic_read(&ei->i_datasync_tid);
                journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
@@@ -1132,9 -1135,11 +1135,11 @@@ struct buffer_head *ext3_bread(handle_
        bh = ext3_getblk(handle, inode, block, create, err);
        if (!bh)
                return bh;
-       if (buffer_uptodate(bh))
+       if (bh_uptodate_or_lock(bh))
                return bh;
-       ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
+       get_bh(bh);
+       bh->b_end_io = end_buffer_read_sync;
+       submit_bh(READ | REQ_META | REQ_PRIO, bh);
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
                return bh;
@@@ -1617,7 -1622,13 +1622,13 @@@ static int ext3_ordered_writepage(struc
        int err;
  
        J_ASSERT(PageLocked(page));
-       WARN_ON_ONCE(IS_RDONLY(inode));
+       /*
+        * We don't want to warn for emergency remount. The condition is
+        * ordered to avoid dereferencing inode->i_sb in non-error case to
+        * avoid slow-downs.
+        */
+       WARN_ON_ONCE(IS_RDONLY(inode) &&
+                    !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
  
        /*
         * We give up here if we're reentered, because it might be for a
@@@ -1692,7 -1703,13 +1703,13 @@@ static int ext3_writeback_writepage(str
        int err;
  
        J_ASSERT(PageLocked(page));
-       WARN_ON_ONCE(IS_RDONLY(inode));
+       /*
+        * We don't want to warn for emergency remount. The condition is
+        * ordered to avoid dereferencing inode->i_sb in non-error case to
+        * avoid slow-downs.
+        */
+       WARN_ON_ONCE(IS_RDONLY(inode) &&
+                    !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
  
        if (ext3_journal_current_handle())
                goto out_fail;
@@@ -1735,7 -1752,13 +1752,13 @@@ static int ext3_journalled_writepage(st
        int err;
  
        J_ASSERT(PageLocked(page));
-       WARN_ON_ONCE(IS_RDONLY(inode));
+       /*
+        * We don't want to warn for emergency remount. The condition is
+        * ordered to avoid dereferencing inode->i_sb in non-error case to
+        * avoid slow-downs.
+        */
+       WARN_ON_ONCE(IS_RDONLY(inode) &&
+                    !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
  
        if (ext3_journal_current_handle())
                goto no_write;
@@@ -2064,12 -2087,10 +2087,10 @@@ static int ext3_block_truncate_page(str
        if (PageUptodate(page))
                set_buffer_uptodate(bh);
  
-       if (!buffer_uptodate(bh)) {
-               err = -EIO;
-               ll_rw_block(READ, 1, &bh);
-               wait_on_buffer(bh);
+       if (!bh_uptodate_or_lock(bh)) {
+               err = bh_submit_read(bh);
                /* Uhhuh. Read error. Complain and punt. */
-               if (!buffer_uptodate(bh))
+               if (err)
                        goto unlock;
        }
  
@@@ -2490,7 -2511,7 +2511,7 @@@ int ext3_can_truncate(struct inode *ino
   * transaction, and VFS/VM ensures that ext3_truncate() cannot run
   * simultaneously on behalf of the same inode.
   *
 - * As we work through the truncate and commmit bits of it to the journal there
 + * As we work through the truncate and commit bits of it to the journal there
   * is one core, guiding principle: the file's tree must always be consistent on
   * disk.  We must be able to restart the truncate after a crash.
   *
diff --combined fs/ext3/ioctl.c
index 8e37c41a071b31e90756f9b0762e37a2ac362065,e7b2ed9d36cc7cbc885ca35039fbe80146a047a8..4af574ce4a4638c651006ff8ce73ca61dbe7a14f
@@@ -44,7 -44,7 +44,7 @@@ long ext3_ioctl(struct file *filp, unsi
                if (get_user(flags, (int __user *) arg))
                        return -EFAULT;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
@@@ -110,7 -110,7 +110,7 @@@ flags_err
                        err = ext3_change_inode_journal_flag(inode, jflag);
  flags_out:
                mutex_unlock(&inode->i_mutex);
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT3_IOC_GETVERSION:
                if (!inode_owner_or_capable(inode))
                        return -EPERM;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
                if (get_user(generation, (int __user *) arg)) {
                        goto setversion_out;
                }
  
+               mutex_lock(&inode->i_mutex);
                handle = ext3_journal_start(inode, 1);
                if (IS_ERR(handle)) {
                        err = PTR_ERR(handle);
-                       goto setversion_out;
+                       goto unlock_out;
                }
                err = ext3_reserve_inode_write(handle, inode, &iloc);
                if (err == 0) {
                        err = ext3_mark_iloc_dirty(handle, inode, &iloc);
                }
                ext3_journal_stop(handle);
+ unlock_out:
+               mutex_unlock(&inode->i_mutex);
  setversion_out:
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT3_IOC_GETRSVSZ:
                if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
                        return -ENOTTY;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
                }
                mutex_unlock(&ei->truncate_mutex);
  setrsvsz_out:
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT3_IOC_GROUP_EXTEND: {
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
                if (err == 0)
                        err = err2;
  group_extend_out:
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT3_IOC_GROUP_ADD: {
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
                if (err == 0)
                        err = err2;
  group_add_out:
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case FITRIM: {
diff --combined fs/ext3/namei.c
index d269821203fda949f998c0310bad7c4afe12b32f,337c3f3375c45ed80df939db04673466fa2c1cb9..e8e211795e9f3cf13a34c12e1376efcde034fa54
@@@ -921,9 -921,12 +921,12 @@@ restart
                                num++;
                                bh = ext3_getblk(NULL, dir, b++, 0, &err);
                                bh_use[ra_max] = bh;
-                               if (bh)
-                                       ll_rw_block(READ | REQ_META | REQ_PRIO,
-                                                   1, &bh);
+                               if (bh && !bh_uptodate_or_lock(bh)) {
+                                       get_bh(bh);
+                                       bh->b_end_io = end_buffer_read_sync;
+                                       submit_bh(READ | REQ_META | REQ_PRIO,
+                                                 bh);
+                               }
                        }
                }
                if ((bh = bh_use[ra_ptr++]) == NULL)
@@@ -1698,7 -1701,7 +1701,7 @@@ static int ext3_add_nondir(handle_t *ha
   * If the create succeeds, we fill in the inode information
   * with d_instantiate().
   */
 -static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
 +static int ext3_create (struct inode * dir, struct dentry * dentry, umode_t mode,
                struct nameidata *nd)
  {
        handle_t *handle;
@@@ -1732,7 -1735,7 +1735,7 @@@ retry
  }
  
  static int ext3_mknod (struct inode * dir, struct dentry *dentry,
 -                      int mode, dev_t rdev)
 +                      umode_t mode, dev_t rdev)
  {
        handle_t *handle;
        struct inode *inode;
@@@ -1768,7 -1771,7 +1771,7 @@@ retry
        return err;
  }
  
 -static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 +static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
  {
        handle_t *handle;
        struct inode * inode;
@@@ -2272,7 -2275,7 +2275,7 @@@ retry
                        err = PTR_ERR(handle);
                        goto err_drop_inode;
                }
 -              inc_nlink(inode);
 +              set_nlink(inode, 1);
                err = ext3_orphan_del(handle, inode);
                if (err) {
                        ext3_journal_stop(handle);
diff --combined fs/ext3/super.c
index 3a10b884e1bebe881b53e79d8643a53c6e2efca9,662cef4569abbca708c43871c837b700552c91f9..726c7ef6cdf129df3bd4da58e791919be7e1aeca
@@@ -511,6 -511,7 +511,6 @@@ static int ext3_drop_inode(struct inod
  static void ext3_i_callback(struct rcu_head *head)
  {
        struct inode *inode = container_of(head, struct inode, i_rcu);
 -      INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
  }
  
@@@ -610,9 -611,9 +610,9 @@@ static char *data_mode_string(unsigned 
   *  - it's set to a non-default value OR
   *  - if the per-sb default is different from the global default
   */
 -static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
 +static int ext3_show_options(struct seq_file *seq, struct dentry *root)
  {
 -      struct super_block *sb = vfs->mnt_sb;
 +      struct super_block *sb = root->d_sb;
        struct ext3_sb_info *sbi = EXT3_SB(sb);
        struct ext3_super_block *es = sbi->s_es;
        unsigned long def_mount_opts;
@@@ -2059,9 -2060,10 +2059,10 @@@ static int ext3_fill_super (struct supe
        EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS;
        ext3_orphan_cleanup(sb, es);
        EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS;
-       if (needs_recovery)
+       if (needs_recovery) {
+               ext3_mark_recovery_complete(sb, es);
                ext3_msg(sb, KERN_INFO, "recovery complete");
-       ext3_mark_recovery_complete(sb, es);
+       }
        ext3_msg(sb, KERN_INFO, "mounted filesystem with %s data mode",
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
@@@ -2229,11 -2231,11 +2230,11 @@@ static journal_t *ext3_get_dev_journal(
                goto out_bdev;
        }
        journal->j_private = sb;
-       ll_rw_block(READ, 1, &journal->j_sb_buffer);
-       wait_on_buffer(journal->j_sb_buffer);
-       if (!buffer_uptodate(journal->j_sb_buffer)) {
-               ext3_msg(sb, KERN_ERR, "I/O error on journal device");
-               goto out_journal;
+       if (!bh_uptodate_or_lock(journal->j_sb_buffer)) {
+               if (bh_submit_read(journal->j_sb_buffer)) {
+                       ext3_msg(sb, KERN_ERR, "I/O error on journal device");
+                       goto out_journal;
+               }
        }
        if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) {
                ext3_msg(sb, KERN_ERR,
@@@ -2909,7 -2911,7 +2910,7 @@@ static int ext3_quota_on(struct super_b
                return -EINVAL;
  
        /* Quotafile not on the same filesystem? */
 -      if (path->mnt->mnt_sb != sb)
 +      if (path->dentry->d_sb != sb)
                return -EXDEV;
        /* Journaling quota? */
        if (EXT3_SB(sb)->s_qf_names[type]) {
diff --combined fs/ext4/extents.c
index 607b1557d292d1b24d5a605d28565de17f36bf13,130ffe4818fa746b4d42f8524cb4b84416fb7257..841faf5fb785058477ba59b205fe0e55dd1c0f0d
@@@ -29,7 -29,6 +29,6 @@@
   *   - smart tree reduction
   */
  
- #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/time.h>
  #include <linux/jbd2.h>
@@@ -1095,7 -1094,7 +1094,7 @@@ static int ext4_ext_grow_indepth(handle
                  le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block),
                  ext4_idx_pblock(EXT_FIRST_INDEX(neh)));
  
 -      neh->eh_depth = cpu_to_le16(neh->eh_depth + 1);
 +      neh->eh_depth = cpu_to_le16(le16_to_cpu(neh->eh_depth) + 1);
        ext4_mark_inode_dirty(handle, inode);
  out:
        brelse(bh);
@@@ -2955,6 -2954,7 +2954,6 @@@ static int ext4_ext_convert_to_initiali
        /* Pre-conditions */
        BUG_ON(!ext4_ext_is_uninitialized(ex));
        BUG_ON(!in_range(map->m_lblk, ee_block, ee_len));
 -      BUG_ON(map->m_lblk + map->m_len > ee_block + ee_len);
  
        /*
         * Attempt to transfer newly initialized blocks from the currently
diff --combined fs/ext4/inode.c
index 7dbcc3e8457046159b9187f095177ce51ff2b0d3,e53858033368e25137485b5b99617f2f5696ff60..aa8efa6572d6d835f5be2a4867d81441a71bb19f
@@@ -18,7 -18,6 +18,6 @@@
   *  Assorted race fixes, rewrite of ext4_get_block() by Al Viro, 2000
   */
  
- #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/time.h>
  #include <linux/jbd2.h>
@@@ -1339,11 -1338,8 +1338,11 @@@ static int mpage_da_submit_io(struct mp
                                        clear_buffer_unwritten(bh);
                                }
  
 -                              /* skip page if block allocation undone */
 -                              if (buffer_delay(bh) || buffer_unwritten(bh))
 +                              /*
 +                               * skip page if block allocation undone and
 +                               * block is dirty
 +                               */
 +                              if (ext4_bh_delay_or_unwritten(NULL, bh))
                                        skip_page = 1;
                                bh = bh->b_this_page;
                                block_start += bh->b_size;
@@@ -1881,7 -1877,7 +1880,7 @@@ static void ext4_end_io_buffer_write(st
   * a[0] = 'a';
   * truncate(f, 4096);
   * we have in the page first buffer_head mapped via page_mkwrite call back
 - * but other bufer_heads would be unmapped but dirty(dirty done via the
 + * but other buffer_heads would be unmapped but dirty (dirty done via the
   * do_wp_page). So writepage should write the first block. If we modify
   * the mmap area beyond 1024 we will again get a page_fault and the
   * page_mkwrite callback will do the block allocation and mark the
@@@ -2273,7 -2269,6 +2272,7 @@@ retry
                        ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: "
                               "%ld pages, ino %lu; err %d", __func__,
                                wbc->nr_to_write, inode->i_ino, ret);
 +                      blk_finish_plug(&plug);
                        goto out_writepages;
                }
  
@@@ -2390,6 -2385,7 +2389,6 @@@ static int ext4_da_write_begin(struct f
        pgoff_t index;
        struct inode *inode = mapping->host;
        handle_t *handle;
 -      loff_t page_len;
  
        index = pos >> PAGE_CACHE_SHIFT;
  
@@@ -2436,6 -2432,13 +2435,6 @@@ retry
                 */
                if (pos + len > inode->i_size)
                        ext4_truncate_failed_write(inode);
 -      } else {
 -              page_len = pos & (PAGE_CACHE_SIZE - 1);
 -              if (page_len > 0) {
 -                      ret = ext4_discard_partial_page_buffers_no_lock(handle,
 -                              inode, page, pos - page_len, page_len,
 -                              EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED);
 -              }
        }
  
        if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@@ -2478,6 -2481,7 +2477,6 @@@ static int ext4_da_write_end(struct fil
        loff_t new_i_size;
        unsigned long start, end;
        int write_mode = (int)(unsigned long)fsdata;
 -      loff_t page_len;
  
        if (write_mode == FALL_BACK_TO_NONDELALLOC) {
                if (ext4_should_order_data(inode)) {
         */
  
        new_i_size = pos + copied;
 -      if (new_i_size > EXT4_I(inode)->i_disksize) {
 +      if (copied && new_i_size > EXT4_I(inode)->i_disksize) {
                if (ext4_da_should_update_i_disksize(page, end)) {
                        down_write(&EXT4_I(inode)->i_data_sem);
                        if (new_i_size > EXT4_I(inode)->i_disksize) {
        }
        ret2 = generic_write_end(file, mapping, pos, len, copied,
                                                        page, fsdata);
 -
 -      page_len = PAGE_CACHE_SIZE -
 -                      ((pos + copied - 1) & (PAGE_CACHE_SIZE - 1));
 -
 -      if (page_len > 0) {
 -              ret = ext4_discard_partial_page_buffers_no_lock(handle,
 -                      inode, page, pos + copied - 1, page_len,
 -                      EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED);
 -      }
 -
        copied = ret2;
        if (ret2 < 0)
                ret = ret2;
@@@ -2765,11 -2779,10 +2764,11 @@@ static void ext4_end_io_dio(struct kioc
                  iocb->private, io_end->inode->i_ino, iocb, offset,
                  size);
  
 +      iocb->private = NULL;
 +
        /* if not aio dio with unwritten extents, just free io and return */
        if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
                ext4_free_io_end(io_end);
 -              iocb->private = NULL;
  out:
                if (is_async)
                        aio_complete(iocb, ret, 0);
  
        /* queue the work to convert unwritten extents to written */
        queue_work(wq, &io_end->work);
 -      iocb->private = NULL;
  
        /* XXX: probably should move into the real I/O completion handler */
        inode_dio_done(inode);
@@@ -3187,8 -3201,26 +3186,8 @@@ int ext4_discard_partial_page_buffers_n
  
        iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
  
 -      if (!page_has_buffers(page)) {
 -              /*
 -               * If the range to be discarded covers a partial block
 -               * we need to get the page buffers.  This is because
 -               * partial blocks cannot be released and the page needs
 -               * to be updated with the contents of the block before
 -               * we write the zeros on top of it.
 -               */
 -              if ((from & (blocksize - 1)) ||
 -                  ((from + length) & (blocksize - 1))) {
 -                      create_empty_buffers(page, blocksize, 0);
 -              } else {
 -                      /*
 -                       * If there are no partial blocks,
 -                       * there is nothing to update,
 -                       * so we can return now
 -                       */
 -                      return 0;
 -              }
 -      }
 +      if (!page_has_buffers(page))
 +              create_empty_buffers(page, blocksize, 0);
  
        /* Find the buffer that contains "offset" */
        bh = page_buffers(page);
@@@ -3469,7 -3501,7 +3468,7 @@@ int ext4_punch_hole(struct file *file, 
   * transaction, and VFS/VM ensures that ext4_truncate() cannot run
   * simultaneously on behalf of the same inode.
   *
 - * As we work through the truncate and commmit bits of it to the journal there
 + * As we work through the truncate and commit bits of it to the journal there
   * is one core, guiding principle: the file's tree must always be consistent on
   * disk.  We must be able to restart the truncate after a crash.
   *
diff --combined fs/ext4/ioctl.c
index d37b3bb2a3b8748b79f3c0e02ab4c17909c5f189,46a8de6f2089e521288fcdd05de022c4a7374810..e87a932b073bcf7db1916db8ef1ac469c676ca63
@@@ -45,7 -45,7 +45,7 @@@ long ext4_ioctl(struct file *filp, unsi
                if (get_user(flags, (int __user *) arg))
                        return -EFAULT;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
@@@ -134,7 -134,7 +134,7 @@@ flags_err
                        err = ext4_ext_migrate(inode);
  flags_out:
                mutex_unlock(&inode->i_mutex);
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT4_IOC_GETVERSION:
                if (!inode_owner_or_capable(inode))
                        return -EPERM;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
                if (get_user(generation, (int __user *) arg)) {
                        goto setversion_out;
                }
  
+               mutex_lock(&inode->i_mutex);
                handle = ext4_journal_start(inode, 1);
                if (IS_ERR(handle)) {
                        err = PTR_ERR(handle);
-                       goto setversion_out;
+                       goto unlock_out;
                }
                err = ext4_reserve_inode_write(handle, inode, &iloc);
                if (err == 0) {
                        err = ext4_mark_iloc_dirty(handle, inode, &iloc);
                }
                ext4_journal_stop(handle);
+ unlock_out:
+               mutex_unlock(&inode->i_mutex);
  setversion_out:
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
        case EXT4_IOC_GROUP_EXTEND: {
                        return -EOPNOTSUPP;
                }
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
                }
                if (err == 0)
                        err = err2;
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                ext4_resize_end(sb);
  
                return err;
                        return -EOPNOTSUPP;
                }
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        goto mext_out;
  
                err = ext4_move_extents(filp, donor_filp, me.orig_start,
                                        me.donor_start, me.len, &me.moved_len);
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                if (me.moved_len > 0)
                        file_remove_suid(donor_filp);
  
@@@ -277,7 -281,7 +281,7 @@@ mext_out
                        return -EOPNOTSUPP;
                }
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
  
                }
                if (err == 0)
                        err = err2;
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                ext4_resize_end(sb);
  
                return err;
                if (!inode_owner_or_capable(inode))
                        return -EACCES;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
                /*
                mutex_lock(&(inode->i_mutex));
                err = ext4_ext_migrate(inode);
                mutex_unlock(&(inode->i_mutex));
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
  
                if (!inode_owner_or_capable(inode))
                        return -EACCES;
  
 -              err = mnt_want_write(filp->f_path.mnt);
 +              err = mnt_want_write_file(filp);
                if (err)
                        return err;
                err = ext4_alloc_da_blocks(inode);
 -              mnt_drop_write(filp->f_path.mnt);
 +              mnt_drop_write_file(filp);
                return err;
        }
  
diff --combined fs/ext4/page-io.c
index 7e106c810c62bb18435d9a0fcb6d5066a3813fad,b1758538b3b5aa8593fc4fe356d233938ec913fc..4758518965187749815eb7b76736313faa5e95c5
@@@ -6,7 -6,6 +6,6 @@@
   * Written by Theodore Ts'o, 2010.
   */
  
- #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/time.h>
  #include <linux/jbd2.h>
@@@ -385,18 -384,6 +384,18 @@@ int ext4_bio_write_page(struct ext4_io_
  
                block_end = block_start + blocksize;
                if (block_start >= len) {
 +                      /*
 +                       * Comments copied from block_write_full_page_endio:
 +                       *
 +                       * The page straddles i_size.  It must be zeroed out on
 +                       * each and every writepage invocation because it may
 +                       * be mmapped.  "A file is mapped in multiples of the
 +                       * page size.  For a file that is not a multiple of
 +                       * the  page size, the remaining memory is zeroed when
 +                       * mapped, and writes to that region are not written
 +                       * out to the file."
 +                       */
 +                      zero_user_segment(page, block_start, block_end);
                        clear_buffer_dirty(bh);
                        set_buffer_uptodate(bh);
                        continue;
diff --combined fs/jbd/journal.c
index a96cff0c5f1d75c89b9275b0f5e0407e65443d08,1656dc2e6a089de8a64e52823fab9eff2ebde6c4..59c09f9541b5923c08ad1d227120dca764f8facf
@@@ -166,7 -166,7 +166,7 @@@ loop
                 */
                jbd_debug(1, "Now suspending kjournald\n");
                spin_unlock(&journal->j_state_lock);
 -              refrigerator();
 +              try_to_freeze();
                spin_lock(&journal->j_state_lock);
        } else {
                /*
@@@ -721,7 -721,6 +721,6 @@@ static journal_t * journal_init_common 
        init_waitqueue_head(&journal->j_wait_checkpoint);
        init_waitqueue_head(&journal->j_wait_commit);
        init_waitqueue_head(&journal->j_wait_updates);
-       mutex_init(&journal->j_barrier);
        mutex_init(&journal->j_checkpoint_mutex);
        spin_lock_init(&journal->j_revoke_lock);
        spin_lock_init(&journal->j_list_lock);
diff --combined fs/reiserfs/super.c
index 19c454e61b79dc259d20cc09b22751efb29609ca,5e3527be11468b9ea29cadc87ebba7a96e404310..1d42e707d5fadc0e604beecf42085c168e628274
@@@ -28,7 -28,6 +28,7 @@@
  #include <linux/mount.h>
  #include <linux/namei.h>
  #include <linux/crc32.h>
 +#include <linux/seq_file.h>
  
  struct file_system_type reiserfs_fs_type;
  
@@@ -62,7 -61,6 +62,7 @@@ static int is_any_reiserfs_magic_string
  
  static int reiserfs_remount(struct super_block *s, int *flags, char *data);
  static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf);
 +void show_alloc_options(struct seq_file *seq, struct super_block *s);
  
  static int reiserfs_sync_fs(struct super_block *s, int wait)
  {
@@@ -455,16 -453,20 +455,20 @@@ int remove_save_link(struct inode *inod
  static void reiserfs_kill_sb(struct super_block *s)
  {
        if (REISERFS_SB(s)) {
-               if (REISERFS_SB(s)->xattr_root) {
-                       d_invalidate(REISERFS_SB(s)->xattr_root);
-                       dput(REISERFS_SB(s)->xattr_root);
-                       REISERFS_SB(s)->xattr_root = NULL;
-               }
-               if (REISERFS_SB(s)->priv_root) {
-                       d_invalidate(REISERFS_SB(s)->priv_root);
-                       dput(REISERFS_SB(s)->priv_root);
-                       REISERFS_SB(s)->priv_root = NULL;
-               }
+               /*
+                * Force any pending inode evictions to occur now. Any
+                * inodes to be removed that have extended attributes
+                * associated with them need to clean them up before
+                * we can release the extended attribute root dentries.
+                * shrink_dcache_for_umount will BUG if we don't release
+                * those before it's called so ->put_super is too late.
+                */
+               shrink_dcache_sb(s);
+               dput(REISERFS_SB(s)->xattr_root);
+               REISERFS_SB(s)->xattr_root = NULL;
+               dput(REISERFS_SB(s)->priv_root);
+               REISERFS_SB(s)->priv_root = NULL;
        }
  
        kill_block_super(s);
@@@ -534,6 -536,7 +538,6 @@@ static struct inode *reiserfs_alloc_ino
  static void reiserfs_i_callback(struct rcu_head *head)
  {
        struct inode *inode = container_of(head, struct inode, i_rcu);
 -      INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
  }
  
@@@ -598,82 -601,6 +602,82 @@@ out
        reiserfs_write_unlock_once(inode->i_sb, lock_depth);
  }
  
 +static int reiserfs_show_options(struct seq_file *seq, struct dentry *root)
 +{
 +      struct super_block *s = root->d_sb;
 +      struct reiserfs_journal *journal = SB_JOURNAL(s);
 +      long opts = REISERFS_SB(s)->s_mount_opt;
 +
 +      if (opts & (1 << REISERFS_LARGETAIL))
 +              seq_puts(seq, ",tails=on");
 +      else if (!(opts & (1 << REISERFS_SMALLTAIL)))
 +              seq_puts(seq, ",notail");
 +      /* tails=small is default so we don't show it */
 +
 +      if (!(opts & (1 << REISERFS_BARRIER_FLUSH)))
 +              seq_puts(seq, ",barrier=none");
 +      /* barrier=flush is default so we don't show it */
 +
 +      if (opts & (1 << REISERFS_ERROR_CONTINUE))
 +              seq_puts(seq, ",errors=continue");
 +      else if (opts & (1 << REISERFS_ERROR_PANIC))
 +              seq_puts(seq, ",errors=panic");
 +      /* errors=ro is default so we don't show it */
 +
 +      if (opts & (1 << REISERFS_DATA_LOG))
 +              seq_puts(seq, ",data=journal");
 +      else if (opts & (1 << REISERFS_DATA_WRITEBACK))
 +              seq_puts(seq, ",data=writeback");
 +      /* data=ordered is default so we don't show it */
 +
 +      if (opts & (1 << REISERFS_ATTRS))
 +              seq_puts(seq, ",attrs");
 +
 +      if (opts & (1 << REISERFS_XATTRS_USER))
 +              seq_puts(seq, ",user_xattr");
 +
 +      if (opts & (1 << REISERFS_EXPOSE_PRIVROOT))
 +              seq_puts(seq, ",expose_privroot");
 +
 +      if (opts & (1 << REISERFS_POSIXACL))
 +              seq_puts(seq, ",acl");
 +
 +      if (REISERFS_SB(s)->s_jdev)
 +              seq_printf(seq, ",jdev=%s", REISERFS_SB(s)->s_jdev);
 +
 +      if (journal->j_max_commit_age != journal->j_default_max_commit_age)
 +              seq_printf(seq, ",commit=%d", journal->j_max_commit_age);
 +
 +#ifdef CONFIG_QUOTA
 +      if (REISERFS_SB(s)->s_qf_names[USRQUOTA])
 +              seq_printf(seq, ",usrjquota=%s", REISERFS_SB(s)->s_qf_names[USRQUOTA]);
 +      else if (opts & (1 << REISERFS_USRQUOTA))
 +              seq_puts(seq, ",usrquota");
 +      if (REISERFS_SB(s)->s_qf_names[GRPQUOTA])
 +              seq_printf(seq, ",grpjquota=%s", REISERFS_SB(s)->s_qf_names[GRPQUOTA]);
 +      else if (opts & (1 << REISERFS_GRPQUOTA))
 +              seq_puts(seq, ",grpquota");
 +      if (REISERFS_SB(s)->s_jquota_fmt) {
 +              if (REISERFS_SB(s)->s_jquota_fmt == QFMT_VFS_OLD)
 +                      seq_puts(seq, ",jqfmt=vfsold");
 +              else if (REISERFS_SB(s)->s_jquota_fmt == QFMT_VFS_V0)
 +                      seq_puts(seq, ",jqfmt=vfsv0");
 +      }
 +#endif
 +
 +      /* Block allocator options */
 +      if (opts & (1 << REISERFS_NO_BORDER))
 +              seq_puts(seq, ",block-allocator=noborder");
 +      if (opts & (1 << REISERFS_NO_UNHASHED_RELOCATION))
 +              seq_puts(seq, ",block-allocator=no_unhashed_relocation");
 +      if (opts & (1 << REISERFS_HASHED_RELOCATION))
 +              seq_puts(seq, ",block-allocator=hashed_relocation");
 +      if (opts & (1 << REISERFS_TEST4))
 +              seq_puts(seq, ",block-allocator=test4");
 +      show_alloc_options(seq, s);
 +      return 0;
 +}
 +
  #ifdef CONFIG_QUOTA
  static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
                                    size_t, loff_t);
@@@ -694,7 -621,7 +698,7 @@@ static const struct super_operations re
        .unfreeze_fs = reiserfs_unfreeze,
        .statfs = reiserfs_statfs,
        .remount_fs = reiserfs_remount,
 -      .show_options = generic_show_options,
 +      .show_options = reiserfs_show_options,
  #ifdef CONFIG_QUOTA
        .quota_read = reiserfs_quota_read,
        .quota_write = reiserfs_quota_write,
@@@ -992,9 -919,9 +996,9 @@@ static int reiserfs_parse_options(struc
                {"jdev",.arg_required = 'j',.values = NULL},
                {"nolargeio",.arg_required = 'w',.values = NULL},
                {"commit",.arg_required = 'c',.values = NULL},
 -              {"usrquota",.setmask = 1 << REISERFS_QUOTA},
 -              {"grpquota",.setmask = 1 << REISERFS_QUOTA},
 -              {"noquota",.clrmask = 1 << REISERFS_QUOTA},
 +              {"usrquota",.setmask = 1 << REISERFS_USRQUOTA},
 +              {"grpquota",.setmask = 1 << REISERFS_GRPQUOTA},
 +              {"noquota",.clrmask = 1 << REISERFS_USRQUOTA | 1 << REISERFS_GRPQUOTA},
                {"errors",.arg_required = 'e',.values = error_actions},
                {"usrjquota",.arg_required =
                 'u' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
                                        return 0;
                                }
                                strcpy(qf_names[qtype], arg);
 -                              *mount_options |= 1 << REISERFS_QUOTA;
 +                              if (qtype == USRQUOTA)
 +                                      *mount_options |= 1 << REISERFS_USRQUOTA;
 +                              else
 +                                      *mount_options |= 1 << REISERFS_GRPQUOTA;
                        } else {
                                if (qf_names[qtype] !=
                                    REISERFS_SB(s)->s_qf_names[qtype])
                                        kfree(qf_names[qtype]);
                                qf_names[qtype] = NULL;
 +                              if (qtype == USRQUOTA)
 +                                      *mount_options &= ~(1 << REISERFS_USRQUOTA);
 +                              else
 +                                      *mount_options &= ~(1 << REISERFS_GRPQUOTA);
                        }
                }
                if (c == 'f') {
                                 "journaled quota format not specified.");
                return 0;
        }
 -      /* This checking is not precise wrt the quota type but for our purposes it is sufficient */
 -      if (!(*mount_options & (1 << REISERFS_QUOTA))
 -          && sb_any_quota_loaded(s)) {
 +      if ((!(*mount_options & (1 << REISERFS_USRQUOTA)) &&
 +             sb_has_quota_loaded(s, USRQUOTA)) ||
 +          (!(*mount_options & (1 << REISERFS_GRPQUOTA)) &&
 +             sb_has_quota_loaded(s, GRPQUOTA))) {
                reiserfs_warning(s, "super-6516", "quota options must "
                                 "be present when quota is turned on.");
                return 0;
@@@ -1249,7 -1168,8 +1253,8 @@@ static void handle_quota_files(struct s
                        kfree(REISERFS_SB(s)->s_qf_names[i]);
                REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
        }
-       REISERFS_SB(s)->s_jquota_fmt = *qfmt;
+       if (*qfmt)
+               REISERFS_SB(s)->s_jquota_fmt = *qfmt;
  }
  #endif
  
@@@ -1310,8 -1230,7 +1315,8 @@@ static int reiserfs_remount(struct supe
        safe_mask |= 1 << REISERFS_ERROR_RO;
        safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
        safe_mask |= 1 << REISERFS_ERROR_PANIC;
 -      safe_mask |= 1 << REISERFS_QUOTA;
 +      safe_mask |= 1 << REISERFS_USRQUOTA;
 +      safe_mask |= 1 << REISERFS_GRPQUOTA;
  
        /* Update the bitmask, taking care to keep
         * the bits we're not allowed to change here */
@@@ -1758,14 -1677,6 +1763,14 @@@ static int reiserfs_fill_super(struct s
             &commit_max_age, qf_names, &qfmt) == 0) {
                goto error;
        }
 +      if (jdev_name && jdev_name[0]) {
 +              REISERFS_SB(s)->s_jdev = kstrdup(jdev_name, GFP_KERNEL);
 +              if (!REISERFS_SB(s)->s_jdev) {
 +                      SWARN(silent, s, "", "Cannot allocate memory for "
 +                              "journal device name");
 +                      goto error;
 +              }
 +      }
  #ifdef CONFIG_QUOTA
        handle_quota_files(s, qf_names, &qfmt);
  #endif
@@@ -2148,13 -2059,12 +2153,13 @@@ static int reiserfs_quota_on(struct sup
        int err;
        struct inode *inode;
        struct reiserfs_transaction_handle th;
 +      int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
  
 -      if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
 +      if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
                return -EINVAL;
  
        /* Quotafile not on the same filesystem? */
 -      if (path->mnt->mnt_sb != sb) {
 +      if (path->dentry->d_sb != sb) {
                err = -EXDEV;
                goto out;
        }
diff --combined fs/udf/inode.c
index 4598904be1bbfe00d2f37102bc2a8705967beb25,4f7b1ffd9e3733bd61ccc9a9c899fd0b83eb1058..7699df7b3198e40e02d84a1c444e1bf360140f06
@@@ -48,13 -48,12 +48,12 @@@ MODULE_LICENSE("GPL")
  
  #define EXTENT_MERGE_SIZE 5
  
 -static mode_t udf_convert_permissions(struct fileEntry *);
 +static umode_t udf_convert_permissions(struct fileEntry *);
  static int udf_update_inode(struct inode *, int);
  static void udf_fill_inode(struct inode *, struct buffer_head *);
  static int udf_sync_inode(struct inode *inode);
  static int udf_alloc_i_data(struct inode *inode, size_t size);
- static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
-                                       sector_t *, int *);
+ static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
  static int8_t udf_insert_aext(struct inode *, struct extent_position,
                              struct kernel_lb_addr, uint32_t);
  static void udf_split_extents(struct inode *, int *, int, int,
@@@ -151,6 -150,12 +150,12 @@@ const struct address_space_operations u
        .bmap           = udf_bmap,
  };
  
+ /*
+  * Expand file stored in ICB to a normal one-block-file
+  *
+  * This function requires i_data_sem for writing and releases it.
+  * This function requires i_mutex held
+  */
  int udf_expand_file_adinicb(struct inode *inode)
  {
        struct page *page;
                        iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
                /* from now on we have normal address_space methods */
                inode->i_data.a_ops = &udf_aops;
+               up_write(&iinfo->i_data_sem);
                mark_inode_dirty(inode);
                return 0;
        }
+       /*
+        * Release i_data_sem so that we can lock a page - page lock ranks
+        * above i_data_sem. i_mutex still protects us against file changes.
+        */
+       up_write(&iinfo->i_data_sem);
  
        page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
        if (!page)
                SetPageUptodate(page);
                kunmap(page);
        }
+       down_write(&iinfo->i_data_sem);
        memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
               iinfo->i_lenAlloc);
        iinfo->i_lenAlloc = 0;
                iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
        /* from now on we have normal address_space methods */
        inode->i_data.a_ops = &udf_aops;
+       up_write(&iinfo->i_data_sem);
        err = inode->i_data.a_ops->writepage(page, &udf_wbc);
        if (err) {
                /* Restore everything back so that we don't lose data... */
                lock_page(page);
                kaddr = kmap(page);
+               down_write(&iinfo->i_data_sem);
                memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
                       inode->i_size);
                kunmap(page);
                unlock_page(page);
                iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
                inode->i_data.a_ops = &udf_adinicb_aops;
+               up_write(&iinfo->i_data_sem);
        }
        page_cache_release(page);
        mark_inode_dirty(inode);
@@@ -310,7 -325,6 +325,6 @@@ static int udf_get_block(struct inode *
                         struct buffer_head *bh_result, int create)
  {
        int err, new;
-       struct buffer_head *bh;
        sector_t phys = 0;
        struct udf_inode_info *iinfo;
  
  
        err = -EIO;
        new = 0;
-       bh = NULL;
        iinfo = UDF_I(inode);
  
        down_write(&iinfo->i_data_sem);
                iinfo->i_next_alloc_goal++;
        }
  
-       err = 0;
  
-       bh = inode_getblk(inode, block, &err, &phys, &new);
-       BUG_ON(bh);
-       if (err)
+       phys = inode_getblk(inode, block, &err, &new);
+       if (!phys)
                goto abort;
-       BUG_ON(!phys);
  
        if (new)
                set_buffer_new(bh_result);
@@@ -547,11 -557,10 +557,10 @@@ out
        return err;
  }
  
- static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
-                                       int *err, sector_t *phys, int *new)
+ static sector_t inode_getblk(struct inode *inode, sector_t block,
+                            int *err, int *new)
  {
        static sector_t last_block;
-       struct buffer_head *result = NULL;
        struct kernel_long_ad laarr[EXTENT_MERGE_SIZE];
        struct extent_position prev_epos, cur_epos, next_epos;
        int count = 0, startnum = 0, endnum = 0;
        int goal = 0, pgoal = iinfo->i_location.logicalBlockNum;
        int lastblock = 0;
  
+       *err = 0;
+       *new = 0;
        prev_epos.offset = udf_file_entry_alloc_offset(inode);
        prev_epos.block = iinfo->i_location;
        prev_epos.bh = NULL;
                brelse(cur_epos.bh);
                brelse(next_epos.bh);
                newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
-               *phys = newblock;
-               return NULL;
+               return newblock;
        }
  
        last_block = block;
                        brelse(cur_epos.bh);
                        brelse(next_epos.bh);
                        *err = ret;
-                       return NULL;
+                       return 0;
                }
                c = 0;
                offset = 0;
                if (!newblocknum) {
                        brelse(prev_epos.bh);
                        *err = -ENOSPC;
-                       return NULL;
+                       return 0;
                }
                iinfo->i_lenExtents += inode->i_sb->s_blocksize;
        }
  
        newblock = udf_get_pblock(inode->i_sb, newblocknum,
                                iinfo->i_location.partitionReferenceNum, 0);
-       if (!newblock)
-               return NULL;
-       *phys = newblock;
-       *err = 0;
+       if (!newblock) {
+               *err = -EIO;
+               return 0;
+       }
        *new = 1;
        iinfo->i_next_alloc_block = block;
        iinfo->i_next_alloc_goal = newblocknum;
        else
                mark_inode_dirty(inode);
  
-       return result;
+       return newblock;
  }
  
  static void udf_split_extents(struct inode *inode, int *c, int offset,
@@@ -1111,10 -1121,9 +1121,9 @@@ int udf_setsize(struct inode *inode, lo
                        if (bsize <
                            (udf_file_entry_alloc_offset(inode) + newsize)) {
                                err = udf_expand_file_adinicb(inode);
-                               if (err) {
-                                       up_write(&iinfo->i_data_sem);
+                               if (err)
                                        return err;
-                               }
+                               down_write(&iinfo->i_data_sem);
                        } else
                                iinfo->i_lenAlloc = newsize;
                }
@@@ -1452,9 -1461,9 +1461,9 @@@ static int udf_alloc_i_data(struct inod
        return 0;
  }
  
 -static mode_t udf_convert_permissions(struct fileEntry *fe)
 +static umode_t udf_convert_permissions(struct fileEntry *fe)
  {
 -      mode_t mode;
 +      umode_t mode;
        uint32_t permissions;
        uint32_t flags;
  
diff --combined fs/udf/super.c
index 0c33225647a010ffcf77e5b0056063b5c98ddb5c,87cb24a0ee7b3fc40c3174096407bbe9b0c2b8bc..c09a84daaf50ce5ae6ae2f1fccbd96fbd2d74653
@@@ -89,7 -89,7 +89,7 @@@ static void udf_open_lvid(struct super_
  static void udf_close_lvid(struct super_block *);
  static unsigned int udf_count_free(struct super_block *);
  static int udf_statfs(struct dentry *, struct kstatfs *);
 -static int udf_show_options(struct seq_file *, struct vfsmount *);
 +static int udf_show_options(struct seq_file *, struct dentry *);
  
  struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi)
  {
@@@ -138,6 -138,7 +138,6 @@@ static struct inode *udf_alloc_inode(st
  static void udf_i_callback(struct rcu_head *head)
  {
        struct inode *inode = container_of(head, struct inode, i_rcu);
 -      INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(udf_inode_cachep, UDF_I(inode));
  }
  
@@@ -195,11 -196,11 +195,11 @@@ struct udf_options 
        unsigned int fileset;
        unsigned int rootdir;
        unsigned int flags;
 -      mode_t umask;
 +      umode_t umask;
        gid_t gid;
        uid_t uid;
 -      mode_t fmode;
 -      mode_t dmode;
 +      umode_t fmode;
 +      umode_t dmode;
        struct nls_table *nls_map;
  };
  
@@@ -249,9 -250,9 +249,9 @@@ static int udf_sb_alloc_partition_maps(
        return 0;
  }
  
 -static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
 +static int udf_show_options(struct seq_file *seq, struct dentry *root)
  {
 -      struct super_block *sb = mnt->mnt_sb;
 +      struct super_block *sb = root->d_sb;
        struct udf_sb_info *sbi = UDF_SB(sb);
  
        if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
                seq_printf(seq, ",gid=%u", sbi->s_gid);
        if (sbi->s_umask != 0)
 -              seq_printf(seq, ",umask=%o", sbi->s_umask);
 +              seq_printf(seq, ",umask=%ho", sbi->s_umask);
        if (sbi->s_fmode != UDF_INVALID_MODE)
 -              seq_printf(seq, ",mode=%o", sbi->s_fmode);
 +              seq_printf(seq, ",mode=%ho", sbi->s_fmode);
        if (sbi->s_dmode != UDF_INVALID_MODE)
 -              seq_printf(seq, ",dmode=%o", sbi->s_dmode);
 +              seq_printf(seq, ",dmode=%ho", sbi->s_dmode);
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
                seq_printf(seq, ",session=%u", sbi->s_session);
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
@@@ -1798,6 -1799,12 +1798,12 @@@ static void udf_close_lvid(struct super
                                le16_to_cpu(lvid->descTag.descCRCLength)));
  
        lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
+       /*
+        * We set buffer uptodate unconditionally here to avoid spurious
+        * warnings from mark_buffer_dirty() when previous EIO has marked
+        * the buffer as !uptodate
+        */
+       set_buffer_uptodate(bh);
        mark_buffer_dirty(bh);
        sbi->s_lvid_dirty = 0;
        mutex_unlock(&sbi->s_alloc_mutex);