Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 7 Feb 2011 22:06:18 +0000 (14:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 7 Feb 2011 22:06:18 +0000 (14:06 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (33 commits)
  Btrfs: Fix page count calculation
  btrfs: Drop __exit attribute on btrfs_exit_compress
  btrfs: cleanup error handling in btrfs_unlink_inode()
  Btrfs: exclude super blocks when we read in block groups
  Btrfs: make sure search_bitmap finds something in remove_from_bitmap
  btrfs: fix return value check of btrfs_start_transaction()
  btrfs: checking NULL or not in some functions
  Btrfs: avoid uninit variable warnings in ordered-data.c
  Btrfs: catch errors from btrfs_sync_log
  Btrfs: make shrink_delalloc a little friendlier
  Btrfs: handle no memory properly in prepare_pages
  Btrfs: do error checking in btrfs_del_csums
  Btrfs: use the global block reserve if we cannot reserve space
  Btrfs: do not release more reserved bytes to the global_block_rsv than we need
  Btrfs: fix check_path_shared so it returns the right value
  btrfs: check return value of btrfs_start_ioctl_transaction() properly
  btrfs: fix return value check of btrfs_join_transaction()
  fs/btrfs/inode.c: Add missing IS_ERR test
  btrfs: fix missing break in switch phrase
  btrfs: fix several uncheck memory allocations
  ...

1  2 
fs/btrfs/acl.c
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/super.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/acl.c
@@@ -37,6 -37,9 +37,9 @@@ static struct posix_acl *btrfs_get_acl(
        char *value = NULL;
        struct posix_acl *acl;
  
+       if (!IS_POSIXACL(inode))
+               return NULL;
        acl = get_cached_acl(inode, type);
        if (acl != ACL_NOT_CACHED)
                return acl;
@@@ -84,6 -87,9 +87,9 @@@ static int btrfs_xattr_acl_get(struct d
        struct posix_acl *acl;
        int ret = 0;
  
+       if (!IS_POSIXACL(dentry->d_inode))
+               return -EOPNOTSUPP;
        acl = btrfs_get_acl(dentry->d_inode, type);
  
        if (IS_ERR(acl))
@@@ -187,23 -193,18 +193,23 @@@ static int btrfs_xattr_acl_set(struct d
        return ret;
  }
  
 -int btrfs_check_acl(struct inode *inode, int mask)
 +int btrfs_check_acl(struct inode *inode, int mask, unsigned int flags)
  {
 -      struct posix_acl *acl;
        int error = -EAGAIN;
  
 -      acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
 +      if (flags & IPERM_FLAG_RCU) {
 +              if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
 +                      error = -ECHILD;
  
 -      if (IS_ERR(acl))
 -              return PTR_ERR(acl);
 -      if (acl) {
 -              error = posix_acl_permission(inode, acl, mask);
 -              posix_acl_release(acl);
 +      } else {
 +              struct posix_acl *acl;
 +              acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
 +              if (IS_ERR(acl))
 +                      return PTR_ERR(acl);
 +              if (acl) {
 +                      error = posix_acl_permission(inode, acl, mask);
 +                      posix_acl_release(acl);
 +              }
        }
  
        return error;
diff --combined fs/btrfs/disk-io.c
@@@ -1550,6 -1550,7 +1550,7 @@@ static int transaction_kthread(void *ar
                spin_unlock(&root->fs_info->new_trans_lock);
  
                trans = btrfs_join_transaction(root, 1);
+               BUG_ON(IS_ERR(trans));
                if (transid == trans->transid) {
                        ret = btrfs_commit_transaction(trans, root);
                        BUG_ON(ret);
@@@ -2126,7 -2127,7 +2127,7 @@@ static void btrfs_end_buffer_write_sync
        if (uptodate) {
                set_buffer_uptodate(bh);
        } else {
 -              if (!buffer_eopnotsupp(bh) && printk_ratelimit()) {
 +              if (printk_ratelimit()) {
                        printk(KERN_WARNING "lost page write due to "
                                        "I/O error on %s\n",
                                       bdevname(bh->b_bdev, b));
@@@ -2263,10 -2264,21 +2264,10 @@@ static int write_dev_supers(struct btrf
                        bh->b_end_io = btrfs_end_buffer_write_sync;
                }
  
 -              if (i == last_barrier && do_barriers && device->barriers) {
 -                      ret = submit_bh(WRITE_BARRIER, bh);
 -                      if (ret == -EOPNOTSUPP) {
 -                              printk("btrfs: disabling barriers on dev %s\n",
 -                                     device->name);
 -                              set_buffer_uptodate(bh);
 -                              device->barriers = 0;
 -                              /* one reference for submit_bh */
 -                              get_bh(bh);
 -                              lock_buffer(bh);
 -                              ret = submit_bh(WRITE_SYNC, bh);
 -                      }
 -              } else {
 +              if (i == last_barrier && do_barriers)
 +                      ret = submit_bh(WRITE_FLUSH_FUA, bh);
 +              else
                        ret = submit_bh(WRITE_SYNC, bh);
 -              }
  
                if (ret)
                        errors++;
@@@ -2453,10 -2465,14 +2454,14 @@@ int btrfs_commit_super(struct btrfs_roo
        up_write(&root->fs_info->cleanup_work_sem);
  
        trans = btrfs_join_transaction(root, 1);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
        ret = btrfs_commit_transaction(trans, root);
        BUG_ON(ret);
        /* run commit again to drop the original snapshot */
        trans = btrfs_join_transaction(root, 1);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
        btrfs_commit_transaction(trans, root);
        ret = btrfs_write_and_wait_transaction(NULL, root);
        BUG_ON(ret);
@@@ -2554,6 -2570,8 +2559,8 @@@ int close_ctree(struct btrfs_root *root
        kfree(fs_info->chunk_root);
        kfree(fs_info->dev_root);
        kfree(fs_info->csum_root);
+       kfree(fs_info);
        return 0;
  }
  
diff --combined fs/btrfs/export.c
@@@ -65,6 -65,7 +65,6 @@@ static struct dentry *btrfs_get_dentry(
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info;
        struct btrfs_root *root;
 -      struct dentry *dentry;
        struct inode *inode;
        struct btrfs_key key;
        int index;
                return ERR_PTR(-ESTALE);
        }
  
 -      dentry = d_obtain_alias(inode);
 -      if (!IS_ERR(dentry))
 -              dentry->d_op = &btrfs_dentry_operations;
 -      return dentry;
 +      return d_obtain_alias(inode);
  fail:
        srcu_read_unlock(&fs_info->subvol_srcu, index);
        return ERR_PTR(err);
@@@ -162,6 -166,7 +162,6 @@@ static struct dentry *btrfs_fh_to_dentr
  static struct dentry *btrfs_get_parent(struct dentry *child)
  {
        struct inode *dir = child->d_inode;
 -      static struct dentry *dentry;
        struct btrfs_root *root = BTRFS_I(dir)->root;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        int ret;
  
        path = btrfs_alloc_path();
+       if (!path)
+               return ERR_PTR(-ENOMEM);
  
        if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
                key.objectid = root->root_key.objectid;
  
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
 -      dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
 -      if (!IS_ERR(dentry))
 -              dentry->d_op = &btrfs_dentry_operations;
 -      return dentry;
 +      return d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
  fail:
        btrfs_free_path(path);
        return ERR_PTR(ret);
diff --combined fs/btrfs/extent-tree.c
@@@ -320,11 -320,6 +320,6 @@@ static int caching_kthread(void *data
        if (!path)
                return -ENOMEM;
  
-       exclude_super_stripes(extent_root, block_group);
-       spin_lock(&block_group->space_info->lock);
-       block_group->space_info->bytes_readonly += block_group->bytes_super;
-       spin_unlock(&block_group->space_info->lock);
        last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
  
        /*
@@@ -467,8 -462,10 +462,10 @@@ static int cache_block_group(struct btr
                        cache->cached = BTRFS_CACHE_NO;
                }
                spin_unlock(&cache->lock);
-               if (ret == 1)
+               if (ret == 1) {
+                       free_excluded_extents(fs_info->extent_root, cache);
                        return 0;
+               }
        }
  
        if (load_cache_only)
@@@ -1746,7 -1743,8 +1743,7 @@@ static int remove_extent_backref(struc
  static void btrfs_issue_discard(struct block_device *bdev,
                                u64 start, u64 len)
  {
 -      blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL,
 -                      BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
 +      blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, 0);
  }
  
  static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
@@@ -3344,8 -3342,10 +3341,10 @@@ static int shrink_delalloc(struct btrfs
        u64 reserved;
        u64 max_reclaim;
        u64 reclaimed = 0;
+       long time_left;
        int pause = 1;
        int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
+       int loops = 0;
  
        block_rsv = &root->fs_info->delalloc_block_rsv;
        space_info = block_rsv->space_info;
  
        max_reclaim = min(reserved, to_reclaim);
  
-       while (1) {
+       while (loops < 1024) {
                /* have the flusher threads jump in and do some IO */
                smp_mb();
                nr_pages = min_t(unsigned long, nr_pages,
                writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
  
                spin_lock(&space_info->lock);
-               if (reserved > space_info->bytes_reserved)
+               if (reserved > space_info->bytes_reserved) {
+                       loops = 0;
                        reclaimed += reserved - space_info->bytes_reserved;
+               } else {
+                       loops++;
+               }
                reserved = space_info->bytes_reserved;
                spin_unlock(&space_info->lock);
  
                        return -EAGAIN;
  
                __set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(pause);
+               time_left = schedule_timeout(pause);
+               /* We were interrupted, exit */
+               if (time_left)
+                       break;
                pause <<= 1;
                if (pause > HZ / 10)
                        pause = HZ / 10;
@@@ -3588,8 -3597,20 +3596,20 @@@ void block_rsv_release_bytes(struct btr
  
        if (num_bytes > 0) {
                if (dest) {
-                       block_rsv_add_bytes(dest, num_bytes, 0);
-               } else {
+                       spin_lock(&dest->lock);
+                       if (!dest->full) {
+                               u64 bytes_to_add;
+                               bytes_to_add = dest->size - dest->reserved;
+                               bytes_to_add = min(num_bytes, bytes_to_add);
+                               dest->reserved += bytes_to_add;
+                               if (dest->reserved >= dest->size)
+                                       dest->full = 1;
+                               num_bytes -= bytes_to_add;
+                       }
+                       spin_unlock(&dest->lock);
+               }
+               if (num_bytes) {
                        spin_lock(&space_info->lock);
                        space_info->bytes_reserved -= num_bytes;
                        spin_unlock(&space_info->lock);
@@@ -4012,6 -4033,7 +4032,7 @@@ void btrfs_delalloc_release_metadata(st
  
        num_bytes = ALIGN(num_bytes, root->sectorsize);
        atomic_dec(&BTRFS_I(inode)->outstanding_extents);
+       WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0);
  
        spin_lock(&BTRFS_I(inode)->accounting_lock);
        nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
@@@ -5633,6 -5655,7 +5654,7 @@@ use_block_rsv(struct btrfs_trans_handl
              struct btrfs_root *root, u32 blocksize)
  {
        struct btrfs_block_rsv *block_rsv;
+       struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
        int ret;
  
        block_rsv = get_block_rsv(trans, root);
        if (block_rsv->size == 0) {
                ret = reserve_metadata_bytes(trans, root, block_rsv,
                                             blocksize, 0);
-               if (ret)
+               /*
+                * If we couldn't reserve metadata bytes try and use some from
+                * the global reserve.
+                */
+               if (ret && block_rsv != global_rsv) {
+                       ret = block_rsv_use_bytes(global_rsv, blocksize);
+                       if (!ret)
+                               return global_rsv;
                        return ERR_PTR(ret);
+               } else if (ret) {
+                       return ERR_PTR(ret);
+               }
                return block_rsv;
        }
  
        ret = block_rsv_use_bytes(block_rsv, blocksize);
        if (!ret)
                return block_rsv;
+       if (ret) {
+               WARN_ON(1);
+               ret = reserve_metadata_bytes(trans, root, block_rsv, blocksize,
+                                            0);
+               if (!ret) {
+                       spin_lock(&block_rsv->lock);
+                       block_rsv->size += blocksize;
+                       spin_unlock(&block_rsv->lock);
+                       return block_rsv;
+               } else if (ret && block_rsv != global_rsv) {
+                       ret = block_rsv_use_bytes(global_rsv, blocksize);
+                       if (!ret)
+                               return global_rsv;
+               }
+       }
  
        return ERR_PTR(-ENOSPC);
  }
@@@ -6221,6 -6269,8 +6268,8 @@@ int btrfs_drop_snapshot(struct btrfs_ro
        BUG_ON(!wc);
  
        trans = btrfs_start_transaction(tree_root, 0);
+       BUG_ON(IS_ERR(trans));
        if (block_rsv)
                trans->block_rsv = block_rsv;
  
  
                        btrfs_end_transaction_throttle(trans, tree_root);
                        trans = btrfs_start_transaction(tree_root, 0);
+                       BUG_ON(IS_ERR(trans));
                        if (block_rsv)
                                trans->block_rsv = block_rsv;
                }
@@@ -6446,6 -6497,8 +6496,8 @@@ static noinline int relocate_inode_page
        int ret = 0;
  
        ra = kzalloc(sizeof(*ra), GFP_NOFS);
+       if (!ra)
+               return -ENOMEM;
  
        mutex_lock(&inode->i_mutex);
        first_index = start >> PAGE_CACHE_SHIFT;
@@@ -7477,7 -7530,7 +7529,7 @@@ int btrfs_drop_dead_reloc_roots(struct 
                BUG_ON(reloc_root->commit_root != NULL);
                while (1) {
                        trans = btrfs_join_transaction(root, 1);
-                       BUG_ON(!trans);
+                       BUG_ON(IS_ERR(trans));
  
                        mutex_lock(&root->fs_info->drop_mutex);
                        ret = btrfs_drop_snapshot(trans, reloc_root);
@@@ -7535,7 -7588,7 +7587,7 @@@ int btrfs_cleanup_reloc_trees(struct bt
  
        if (found) {
                trans = btrfs_start_transaction(root, 1);
-               BUG_ON(!trans);
+               BUG_ON(IS_ERR(trans));
                ret = btrfs_commit_transaction(trans, root);
                BUG_ON(ret);
        }
@@@ -7779,7 -7832,7 +7831,7 @@@ static noinline int relocate_one_extent
  
  
        trans = btrfs_start_transaction(extent_root, 1);
-       BUG_ON(!trans);
+       BUG_ON(IS_ERR(trans));
  
        if (extent_key->objectid == 0) {
                ret = del_extent_zero(trans, extent_root, path, extent_key);
@@@ -8270,6 -8323,13 +8322,13 @@@ int btrfs_free_block_groups(struct btrf
                if (block_group->cached == BTRFS_CACHE_STARTED)
                        wait_block_group_cache_done(block_group);
  
+               /*
+                * We haven't cached this block group, which means we could
+                * possibly have excluded extents on this block group.
+                */
+               if (block_group->cached == BTRFS_CACHE_NO)
+                       free_excluded_extents(info->extent_root, block_group);
                btrfs_remove_free_space_cache(block_group);
                btrfs_put_block_group(block_group);
  
@@@ -8384,6 -8444,13 +8443,13 @@@ int btrfs_read_block_groups(struct btrf
                cache->flags = btrfs_block_group_flags(&cache->item);
                cache->sectorsize = root->sectorsize;
  
+               /*
+                * We need to exclude the super stripes now so that the space
+                * info has super bytes accounted for, otherwise we'll think
+                * we have more space than we actually do.
+                */
+               exclude_super_stripes(root, cache);
                /*
                 * check for two cases, either we are full, and therefore
                 * don't need to bother with the caching work since we won't
                 * time, particularly in the full case.
                 */
                if (found_key.offset == btrfs_block_group_used(&cache->item)) {
-                       exclude_super_stripes(root, cache);
                        cache->last_byte_to_unpin = (u64)-1;
                        cache->cached = BTRFS_CACHE_FINISHED;
                        free_excluded_extents(root, cache);
                } else if (btrfs_block_group_used(&cache->item) == 0) {
-                       exclude_super_stripes(root, cache);
                        cache->last_byte_to_unpin = (u64)-1;
                        cache->cached = BTRFS_CACHE_FINISHED;
                        add_new_free_space(cache, root->fs_info,
diff --combined fs/btrfs/extent_io.c
@@@ -1865,7 -1865,7 +1865,7 @@@ static int submit_one_bio(int rw, struc
        bio_get(bio);
  
        if (tree->ops && tree->ops->submit_bio_hook)
-               tree->ops->submit_bio_hook(page->mapping->host, rw, bio,
+               ret = tree->ops->submit_bio_hook(page->mapping->host, rw, bio,
                                           mirror_num, bio_flags, start);
        else
                submit_bio(rw, bio);
@@@ -1920,6 -1920,8 +1920,8 @@@ static int submit_extent_page(int rw, s
                nr = bio_get_nr_vecs(bdev);
  
        bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
+       if (!bio)
+               return -ENOMEM;
  
        bio_add_page(bio, page, page_size, offset);
        bio->bi_end_io = end_io_func;
@@@ -2126,7 -2128,7 +2128,7 @@@ int extent_read_full_page(struct extent
        ret = __extent_read_full_page(tree, page, get_extent, &bio, 0,
                                      &bio_flags);
        if (bio)
-               submit_one_bio(READ, bio, 0, bio_flags);
+               ret = submit_one_bio(READ, bio, 0, bio_flags);
        return ret;
  }
  
@@@ -3081,6 -3083,7 +3083,6 @@@ static struct extent_buffer *__alloc_ex
        eb->len = len;
        spin_lock_init(&eb->lock);
        init_waitqueue_head(&eb->lock_wq);
 -      INIT_RCU_HEAD(&eb->rcu_head);
  
  #if LEAK_DEBUG
        spin_lock_irqsave(&leak_lock, flags);
diff --combined fs/btrfs/file.c
@@@ -24,7 -24,6 +24,7 @@@
  #include <linux/string.h>
  #include <linux/backing-dev.h>
  #include <linux/mpage.h>
 +#include <linux/falloc.h>
  #include <linux/swap.h>
  #include <linux/writeback.h>
  #include <linux/statfs.h>
@@@ -793,8 -792,12 +793,12 @@@ again
        for (i = 0; i < num_pages; i++) {
                pages[i] = grab_cache_page(inode->i_mapping, index + i);
                if (!pages[i]) {
-                       err = -ENOMEM;
-                       BUG_ON(1);
+                       int c;
+                       for (c = i - 1; c >= 0; c--) {
+                               unlock_page(pages[c]);
+                               page_cache_release(pages[c]);
+                       }
+                       return -ENOMEM;
                }
                wait_on_page_writeback(pages[i]);
        }
@@@ -946,6 -949,10 +950,10 @@@ static ssize_t btrfs_file_aio_write(str
                     PAGE_CACHE_SIZE, PAGE_CACHE_SIZE /
                     (sizeof(struct page *)));
        pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
+       if (!pages) {
+               ret = -ENOMEM;
+               goto out;
+       }
  
        /* generic_write_checks can change our pos */
        start_pos = pos;
                size_t write_bytes = min(iov_iter_count(&i),
                                         nrptrs * (size_t)PAGE_CACHE_SIZE -
                                         offset);
-               size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >>
-                                       PAGE_CACHE_SHIFT;
+               size_t num_pages = (write_bytes + offset +
+                                   PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  
                WARN_ON(num_pages > nrptrs);
                memset(pages, 0, sizeof(struct page *) * nrptrs);
  
                copied = btrfs_copy_from_user(pos, num_pages,
                                           write_bytes, pages, &i);
-               dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
-                                       PAGE_CACHE_SHIFT;
+               dirty_pages = (copied + offset + PAGE_CACHE_SIZE - 1) >>
+                               PAGE_CACHE_SHIFT;
  
                if (num_pages > dirty_pages) {
                        if (copied > 0)
@@@ -1251,117 -1258,6 +1259,117 @@@ static int btrfs_file_mmap(struct file      
        return 0;
  }
  
 +static long btrfs_fallocate(struct file *file, int mode,
 +                          loff_t offset, loff_t len)
 +{
 +      struct inode *inode = file->f_path.dentry->d_inode;
 +      struct extent_state *cached_state = NULL;
 +      u64 cur_offset;
 +      u64 last_byte;
 +      u64 alloc_start;
 +      u64 alloc_end;
 +      u64 alloc_hint = 0;
 +      u64 locked_end;
 +      u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
 +      struct extent_map *em;
 +      int ret;
 +
 +      alloc_start = offset & ~mask;
 +      alloc_end =  (offset + len + mask) & ~mask;
 +
 +      /* We only support the FALLOC_FL_KEEP_SIZE mode */
 +      if (mode & ~FALLOC_FL_KEEP_SIZE)
 +              return -EOPNOTSUPP;
 +
 +      /*
 +       * wait for ordered IO before we have any locks.  We'll loop again
 +       * below with the locks held.
 +       */
 +      btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start);
 +
 +      mutex_lock(&inode->i_mutex);
 +      ret = inode_newsize_ok(inode, alloc_end);
 +      if (ret)
 +              goto out;
 +
 +      if (alloc_start > inode->i_size) {
 +              ret = btrfs_cont_expand(inode, alloc_start);
 +              if (ret)
 +                      goto out;
 +      }
 +
 +      ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
 +      if (ret)
 +              goto out;
 +
 +      locked_end = alloc_end - 1;
 +      while (1) {
 +              struct btrfs_ordered_extent *ordered;
 +
 +              /* the extent lock is ordered inside the running
 +               * transaction
 +               */
 +              lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
 +                               locked_end, 0, &cached_state, GFP_NOFS);
 +              ordered = btrfs_lookup_first_ordered_extent(inode,
 +                                                          alloc_end - 1);
 +              if (ordered &&
 +                  ordered->file_offset + ordered->len > alloc_start &&
 +                  ordered->file_offset < alloc_end) {
 +                      btrfs_put_ordered_extent(ordered);
 +                      unlock_extent_cached(&BTRFS_I(inode)->io_tree,
 +                                           alloc_start, locked_end,
 +                                           &cached_state, GFP_NOFS);
 +                      /*
 +                       * we can't wait on the range with the transaction
 +                       * running or with the extent lock held
 +                       */
 +                      btrfs_wait_ordered_range(inode, alloc_start,
 +                                               alloc_end - alloc_start);
 +              } else {
 +                      if (ordered)
 +                              btrfs_put_ordered_extent(ordered);
 +                      break;
 +              }
 +      }
 +
 +      cur_offset = alloc_start;
 +      while (1) {
 +              em = btrfs_get_extent(inode, NULL, 0, cur_offset,
 +                                    alloc_end - cur_offset, 0);
 +              BUG_ON(IS_ERR(em) || !em);
 +              last_byte = min(extent_map_end(em), alloc_end);
 +              last_byte = (last_byte + mask) & ~mask;
 +              if (em->block_start == EXTENT_MAP_HOLE ||
 +                  (cur_offset >= inode->i_size &&
 +                   !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
 +                      ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
 +                                                      last_byte - cur_offset,
 +                                                      1 << inode->i_blkbits,
 +                                                      offset + len,
 +                                                      &alloc_hint);
 +                      if (ret < 0) {
 +                              free_extent_map(em);
 +                              break;
 +                      }
 +              }
 +              free_extent_map(em);
 +
 +              cur_offset = last_byte;
 +              if (cur_offset >= alloc_end) {
 +                      ret = 0;
 +                      break;
 +              }
 +      }
 +      unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
 +                           &cached_state, GFP_NOFS);
 +
 +      btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
 +out:
 +      mutex_unlock(&inode->i_mutex);
 +      return ret;
 +}
 +
  const struct file_operations btrfs_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
        .open           = generic_file_open,
        .release        = btrfs_release_file,
        .fsync          = btrfs_sync_file,
 +      .fallocate      = btrfs_fallocate,
        .unlocked_ioctl = btrfs_ioctl,
  #ifdef CONFIG_COMPAT
        .compat_ioctl   = btrfs_ioctl,
diff --combined fs/btrfs/inode.c
@@@ -416,7 -416,7 +416,7 @@@ again
        }
        if (start == 0) {
                trans = btrfs_join_transaction(root, 1);
-               BUG_ON(!trans);
+               BUG_ON(IS_ERR(trans));
                btrfs_set_trans_block_group(trans, inode);
                trans->block_rsv = &root->fs_info->delalloc_block_rsv;
  
@@@ -612,6 -612,7 +612,7 @@@ retry
                            GFP_NOFS);
  
                trans = btrfs_join_transaction(root, 1);
+               BUG_ON(IS_ERR(trans));
                ret = btrfs_reserve_extent(trans, root,
                                           async_extent->compressed_size,
                                           async_extent->compressed_size,
@@@ -771,7 -772,7 +772,7 @@@ static noinline int cow_file_range(stru
  
        BUG_ON(root == root->fs_info->tree_root);
        trans = btrfs_join_transaction(root, 1);
-       BUG_ON(!trans);
+       BUG_ON(IS_ERR(trans));
        btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
  
@@@ -1049,7 -1050,7 +1050,7 @@@ static noinline int run_delalloc_nocow(
        } else {
                trans = btrfs_join_transaction(root, 1);
        }
-       BUG_ON(!trans);
+       BUG_ON(IS_ERR(trans));
  
        cow_start = (u64)-1;
        cur_offset = start;
@@@ -1557,6 -1558,7 +1558,7 @@@ out
  out_page:
        unlock_page(page);
        page_cache_release(page);
+       kfree(fixup);
  }
  
  /*
@@@ -1703,7 -1705,7 +1705,7 @@@ static int btrfs_finish_ordered_io(stru
                                trans = btrfs_join_transaction_nolock(root, 1);
                        else
                                trans = btrfs_join_transaction(root, 1);
-                       BUG_ON(!trans);
+                       BUG_ON(IS_ERR(trans));
                        btrfs_set_trans_block_group(trans, inode);
                        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                        ret = btrfs_update_inode(trans, root, inode);
                trans = btrfs_join_transaction_nolock(root, 1);
        else
                trans = btrfs_join_transaction(root, 1);
+       BUG_ON(IS_ERR(trans));
        btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
  
@@@ -2354,6 -2357,7 +2357,7 @@@ void btrfs_orphan_cleanup(struct btrfs_
                 */
                if (is_bad_inode(inode)) {
                        trans = btrfs_start_transaction(root, 0);
+                       BUG_ON(IS_ERR(trans));
                        btrfs_orphan_del(trans, inode);
                        btrfs_end_transaction(trans, root);
                        iput(inode);
  
        if (root->orphan_block_rsv || root->orphan_item_inserted) {
                trans = btrfs_join_transaction(root, 1);
+               BUG_ON(IS_ERR(trans));
                btrfs_end_transaction(trans, root);
        }
  
@@@ -2641,7 -2646,7 +2646,7 @@@ int btrfs_unlink_inode(struct btrfs_tra
        path = btrfs_alloc_path();
        if (!path) {
                ret = -ENOMEM;
-               goto err;
+               goto out;
        }
  
        path->leave_spinning = 1;
@@@ -2714,9 -2719,10 +2719,10 @@@ static int check_path_shared(struct btr
        struct extent_buffer *eb;
        int level;
        u64 refs = 1;
-       int uninitialized_var(ret);
  
        for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
+               int ret;
                if (!path->nodes[level])
                        break;
                eb = path->nodes[level];
                if (refs > 1)
                        return 1;
        }
-       return ret; /* XXX callers? */
+       return 0;
  }
  
  /*
@@@ -3896,7 -3902,7 +3902,7 @@@ again
        p = &root->inode_tree.rb_node;
        parent = NULL;
  
 -      if (hlist_unhashed(&inode->i_hash))
 +      if (inode_unhashed(inode))
                return;
  
        spin_lock(&root->inode_lock);
@@@ -4103,6 -4109,8 +4109,6 @@@ struct inode *btrfs_lookup_dentry(struc
        int index;
        int ret;
  
 -      dentry->d_op = &btrfs_dentry_operations;
 -
        if (dentry->d_name.len > BTRFS_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
  
        }
        srcu_read_unlock(&root->fs_info->subvol_srcu, index);
  
-       if (root != sub_root) {
+       if (!IS_ERR(inode) && root != sub_root) {
                down_read(&root->fs_info->cleanup_work_sem);
                if (!(inode->i_sb->s_flags & MS_RDONLY))
                        btrfs_orphan_cleanup(sub_root);
        return inode;
  }
  
 -static int btrfs_dentry_delete(struct dentry *dentry)
 +static int btrfs_dentry_delete(const struct dentry *dentry)
  {
        struct btrfs_root *root;
  
@@@ -4347,6 -4355,8 +4353,8 @@@ int btrfs_write_inode(struct inode *ino
                        trans = btrfs_join_transaction_nolock(root, 1);
                else
                        trans = btrfs_join_transaction(root, 1);
+               if (IS_ERR(trans))
+                       return PTR_ERR(trans);
                btrfs_set_trans_block_group(trans, inode);
                if (nolock)
                        ret = btrfs_end_transaction_nolock(trans, root);
@@@ -4372,6 -4382,7 +4380,7 @@@ void btrfs_dirty_inode(struct inode *in
                return;
  
        trans = btrfs_join_transaction(root, 1);
+       BUG_ON(IS_ERR(trans));
        btrfs_set_trans_block_group(trans, inode);
  
        ret = btrfs_update_inode(trans, root, inode);
@@@ -4819,7 -4830,7 +4828,7 @@@ static int btrfs_link(struct dentry *ol
        }
  
        btrfs_set_trans_block_group(trans, dir);
 -      atomic_inc(&inode->i_count);
 +      ihold(inode);
  
        err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
  
@@@ -5176,6 -5187,8 +5185,8 @@@ again
                                em = NULL;
                                btrfs_release_path(root, path);
                                trans = btrfs_join_transaction(root, 1);
+                               if (IS_ERR(trans))
+                                       return ERR_CAST(trans);
                                goto again;
                        }
                        map = kmap(page);
@@@ -5280,8 -5293,8 +5291,8 @@@ static struct extent_map *btrfs_new_ext
        btrfs_drop_extent_cache(inode, start, start + len - 1, 0);
  
        trans = btrfs_join_transaction(root, 0);
-       if (!trans)
-               return ERR_PTR(-ENOMEM);
+       if (IS_ERR(trans))
+               return ERR_CAST(trans);
  
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
  
@@@ -5505,7 -5518,7 +5516,7 @@@ static int btrfs_get_blocks_direct(stru
                 * while we look for nocow cross refs
                 */
                trans = btrfs_join_transaction(root, 0);
-               if (!trans)
+               if (IS_ERR(trans))
                        goto must_cow;
  
                if (can_nocow_odirect(trans, inode, start, len) == 1) {
@@@ -5640,7 -5653,7 +5651,7 @@@ again
        BUG_ON(!ordered);
  
        trans = btrfs_join_transaction(root, 1);
-       if (!trans) {
+       if (IS_ERR(trans)) {
                err = -ENOMEM;
                goto out;
        }
@@@ -6517,13 -6530,6 +6528,13 @@@ struct inode *btrfs_alloc_inode(struct 
        return inode;
  }
  
 +static void btrfs_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(btrfs_inode_cachep, BTRFS_I(inode));
 +}
 +
  void btrfs_destroy_inode(struct inode *inode)
  {
        struct btrfs_ordered_extent *ordered;
        inode_tree_del(inode);
        btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
  free:
 -      kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
 +      call_rcu(&inode->i_rcu, btrfs_i_callback);
  }
  
  int btrfs_drop_inode(struct inode *inode)
@@@ -7122,12 -7128,118 +7133,12 @@@ int btrfs_prealloc_file_range_trans(str
                                           min_size, actual_len, alloc_hint, trans);
  }
  
 -static long btrfs_fallocate(struct inode *inode, int mode,
 -                          loff_t offset, loff_t len)
 -{
 -      struct extent_state *cached_state = NULL;
 -      u64 cur_offset;
 -      u64 last_byte;
 -      u64 alloc_start;
 -      u64 alloc_end;
 -      u64 alloc_hint = 0;
 -      u64 locked_end;
 -      u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
 -      struct extent_map *em;
 -      int ret;
 -
 -      alloc_start = offset & ~mask;
 -      alloc_end =  (offset + len + mask) & ~mask;
 -
 -      /*
 -       * wait for ordered IO before we have any locks.  We'll loop again
 -       * below with the locks held.
 -       */
 -      btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start);
 -
 -      mutex_lock(&inode->i_mutex);
 -      ret = inode_newsize_ok(inode, alloc_end);
 -      if (ret)
 -              goto out;
 -
 -      if (alloc_start > inode->i_size) {
 -              ret = btrfs_cont_expand(inode, alloc_start);
 -              if (ret)
 -                      goto out;
 -      }
 -
 -      ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
 -      if (ret)
 -              goto out;
 -
 -      locked_end = alloc_end - 1;
 -      while (1) {
 -              struct btrfs_ordered_extent *ordered;
 -
 -              /* the extent lock is ordered inside the running
 -               * transaction
 -               */
 -              lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
 -                               locked_end, 0, &cached_state, GFP_NOFS);
 -              ordered = btrfs_lookup_first_ordered_extent(inode,
 -                                                          alloc_end - 1);
 -              if (ordered &&
 -                  ordered->file_offset + ordered->len > alloc_start &&
 -                  ordered->file_offset < alloc_end) {
 -                      btrfs_put_ordered_extent(ordered);
 -                      unlock_extent_cached(&BTRFS_I(inode)->io_tree,
 -                                           alloc_start, locked_end,
 -                                           &cached_state, GFP_NOFS);
 -                      /*
 -                       * we can't wait on the range with the transaction
 -                       * running or with the extent lock held
 -                       */
 -                      btrfs_wait_ordered_range(inode, alloc_start,
 -                                               alloc_end - alloc_start);
 -              } else {
 -                      if (ordered)
 -                              btrfs_put_ordered_extent(ordered);
 -                      break;
 -              }
 -      }
 -
 -      cur_offset = alloc_start;
 -      while (1) {
 -              em = btrfs_get_extent(inode, NULL, 0, cur_offset,
 -                                    alloc_end - cur_offset, 0);
 -              BUG_ON(IS_ERR(em) || !em);
 -              last_byte = min(extent_map_end(em), alloc_end);
 -              last_byte = (last_byte + mask) & ~mask;
 -              if (em->block_start == EXTENT_MAP_HOLE ||
 -                  (cur_offset >= inode->i_size &&
 -                   !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
 -                      ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
 -                                                      last_byte - cur_offset,
 -                                                      1 << inode->i_blkbits,
 -                                                      offset + len,
 -                                                      &alloc_hint);
 -                      if (ret < 0) {
 -                              free_extent_map(em);
 -                              break;
 -                      }
 -              }
 -              free_extent_map(em);
 -
 -              cur_offset = last_byte;
 -              if (cur_offset >= alloc_end) {
 -                      ret = 0;
 -                      break;
 -              }
 -      }
 -      unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
 -                           &cached_state, GFP_NOFS);
 -
 -      btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
 -out:
 -      mutex_unlock(&inode->i_mutex);
 -      return ret;
 -}
 -
  static int btrfs_set_page_dirty(struct page *page)
  {
        return __set_page_dirty_nobuffers(page);
  }
  
 -static int btrfs_permission(struct inode *inode, int mask)
 +static int btrfs_permission(struct inode *inode, int mask, unsigned int flags)
  {
        struct btrfs_root *root = BTRFS_I(inode)->root;
  
                return -EROFS;
        if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE))
                return -EACCES;
 -      return generic_permission(inode, mask, btrfs_check_acl);
 +      return generic_permission(inode, mask, flags, btrfs_check_acl);
  }
  
  static const struct inode_operations btrfs_dir_inode_operations = {
@@@ -7228,6 -7340,7 +7239,6 @@@ static const struct inode_operations bt
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .permission     = btrfs_permission,
 -      .fallocate      = btrfs_fallocate,
        .fiemap         = btrfs_fiemap,
  };
  static const struct inode_operations btrfs_special_inode_operations = {
diff --combined fs/btrfs/super.c
@@@ -383,7 -383,7 +383,7 @@@ static int btrfs_parse_early_options(co
                struct btrfs_fs_devices **fs_devices)
  {
        substring_t args[MAX_OPT_ARGS];
-       char *opts, *p;
+       char *opts, *orig, *p;
        int error = 0;
        int intarg;
  
        opts = kstrdup(options, GFP_KERNEL);
        if (!opts)
                return -ENOMEM;
+       orig = opts;
  
        while ((p = strsep(&opts, ",")) != NULL) {
                int token;
        }
  
   out_free_opts:
-       kfree(opts);
+       kfree(orig);
   out:
        /*
         * If no subvolume name is specified we use the default one.  Allocate
@@@ -566,7 -567,6 +567,7 @@@ static int btrfs_fill_super(struct supe
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_magic = BTRFS_SUPER_MAGIC;
        sb->s_op = &btrfs_super_ops;
 +      sb->s_d_op = &btrfs_dentry_operations;
        sb->s_export_op = &btrfs_export_ops;
        sb->s_xattr = btrfs_xattr_handlers;
        sb->s_time_gran = 1;
@@@ -623,6 -623,8 +624,8 @@@ int btrfs_sync_fs(struct super_block *s
        btrfs_wait_ordered_extents(root, 0, 0);
  
        trans = btrfs_start_transaction(root, 0);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
        ret = btrfs_commit_transaction(trans, root);
        return ret;
  }
@@@ -696,8 -698,8 +699,8 @@@ static int btrfs_set_super(struct super
   * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
   *      for multiple device setup.  Make sure to keep it in sync.
   */
 -static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
 -              const char *dev_name, void *data, struct vfsmount *mnt)
 +static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
 +              const char *dev_name, void *data)
  {
        struct block_device *bdev = NULL;
        struct super_block *s;
                                          &subvol_name, &subvol_objectid,
                                          &fs_devices);
        if (error)
 -              return error;
 +              return ERR_PTR(error);
  
        error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
        if (error)
                }
  
                btrfs_close_devices(fs_devices);
+               kfree(fs_info);
+               kfree(tree_root);
        } else {
                char b[BDEVNAME_SIZE];
  
                root = new_root;
        }
  
 -      mnt->mnt_sb = s;
 -      mnt->mnt_root = root;
 -
        kfree(subvol_name);
 -      return 0;
 +      return root;
  
  error_s:
        error = PTR_ERR(s);
@@@ -819,7 -826,7 +824,7 @@@ error_close_devices
        kfree(tree_root);
  error_free_subvol_name:
        kfree(subvol_name);
 -      return error;
 +      return ERR_PTR(error);
  }
  
  static int btrfs_remount(struct super_block *sb, int *flags, char *data)
@@@ -1036,7 -1043,7 +1041,7 @@@ static int btrfs_statfs(struct dentry *
  static struct file_system_type btrfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "btrfs",
 -      .get_sb         = btrfs_get_sb,
 +      .mount          = btrfs_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_REQUIRES_DEV,
  };
@@@ -1105,7 -1112,6 +1110,7 @@@ static const struct file_operations btr
        .unlocked_ioctl  = btrfs_control_ioctl,
        .compat_ioctl = btrfs_control_ioctl,
        .owner   = THIS_MODULE,
 +      .llseek = noop_llseek,
  };
  
  static struct miscdevice btrfs_misc = {
diff --combined fs/btrfs/volumes.c
@@@ -399,6 -399,7 +399,6 @@@ static noinline int device_list_add(con
                device->work.func = pending_bios_fn;
                memcpy(device->uuid, disk_super->dev_item.uuid,
                       BTRFS_UUID_SIZE);
 -              device->barriers = 1;
                spin_lock_init(&device->io_lock);
                device->name = kstrdup(path, GFP_NOFS);
                if (!device->name) {
@@@ -466,6 -467,7 +466,6 @@@ static struct btrfs_fs_devices *clone_f
                device->devid = orig_dev->devid;
                device->work.func = pending_bios_fn;
                memcpy(device->uuid, orig_dev->uuid, sizeof(device->uuid));
 -              device->barriers = 1;
                spin_lock_init(&device->io_lock);
                INIT_LIST_HEAD(&device->dev_list);
                INIT_LIST_HEAD(&device->dev_alloc_list);
@@@ -494,7 -496,7 +494,7 @@@ again
                        continue;
  
                if (device->bdev) {
 -                      close_bdev_exclusive(device->bdev, device->mode);
 +                      blkdev_put(device->bdev, device->mode);
                        device->bdev = NULL;
                        fs_devices->open_devices--;
                }
@@@ -528,7 -530,7 +528,7 @@@ static int __btrfs_close_devices(struc
  
        list_for_each_entry(device, &fs_devices->devices, dev_list) {
                if (device->bdev) {
 -                      close_bdev_exclusive(device->bdev, device->mode);
 +                      blkdev_put(device->bdev, device->mode);
                        fs_devices->open_devices--;
                }
                if (device->writeable) {
@@@ -585,15 -587,13 +585,15 @@@ static int __btrfs_open_devices(struct 
        int seeding = 1;
        int ret = 0;
  
 +      flags |= FMODE_EXCL;
 +
        list_for_each_entry(device, head, dev_list) {
                if (device->bdev)
                        continue;
                if (!device->name)
                        continue;
  
 -              bdev = open_bdev_exclusive(device->name, flags, holder);
 +              bdev = blkdev_get_by_path(device->name, flags, holder);
                if (IS_ERR(bdev)) {
                        printk(KERN_INFO "open %s failed\n", device->name);
                        goto error;
  error_brelse:
                brelse(bh);
  error_close:
 -              close_bdev_exclusive(bdev, FMODE_READ);
 +              blkdev_put(bdev, flags);
  error:
                continue;
        }
@@@ -693,8 -693,7 +693,8 @@@ int btrfs_scan_one_device(const char *p
  
        mutex_lock(&uuid_mutex);
  
 -      bdev = open_bdev_exclusive(path, flags, holder);
 +      flags |= FMODE_EXCL;
 +      bdev = blkdev_get_by_path(path, flags, holder);
  
        if (IS_ERR(bdev)) {
                ret = PTR_ERR(bdev);
  
        brelse(bh);
  error_close:
 -      close_bdev_exclusive(bdev, flags);
 +      blkdev_put(bdev, flags);
  error:
        mutex_unlock(&uuid_mutex);
        return ret;
@@@ -1213,6 -1212,10 +1213,10 @@@ static int btrfs_rm_dev_item(struct btr
                return -ENOMEM;
  
        trans = btrfs_start_transaction(root, 0);
+       if (IS_ERR(trans)) {
+               btrfs_free_path(path);
+               return PTR_ERR(trans);
+       }
        key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
        key.type = BTRFS_DEV_ITEM_KEY;
        key.offset = device->devid;
@@@ -1296,8 -1299,8 +1300,8 @@@ int btrfs_rm_device(struct btrfs_root *
                        goto out;
                }
        } else {
 -              bdev = open_bdev_exclusive(device_path, FMODE_READ,
 -                                    root->fs_info->bdev_holder);
 +              bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL,
 +                                        root->fs_info->bdev_holder);
                if (IS_ERR(bdev)) {
                        ret = PTR_ERR(bdev);
                        goto out;
                root->fs_info->fs_devices->latest_bdev = next_device->bdev;
  
        if (device->bdev) {
 -              close_bdev_exclusive(device->bdev, device->mode);
 +              blkdev_put(device->bdev, device->mode);
                device->bdev = NULL;
                device->fs_devices->open_devices--;
        }
@@@ -1407,7 -1410,7 +1411,7 @@@ error_brelse
        brelse(bh);
  error_close:
        if (bdev)
 -              close_bdev_exclusive(bdev, FMODE_READ);
 +              blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
  out:
        mutex_unlock(&root->fs_info->volume_mutex);
        mutex_unlock(&uuid_mutex);
@@@ -1559,8 -1562,7 +1563,8 @@@ int btrfs_init_new_device(struct btrfs_
        if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding)
                return -EINVAL;
  
 -      bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder);
 +      bdev = blkdev_get_by_path(device_path, FMODE_EXCL,
 +                                root->fs_info->bdev_holder);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
  
        }
  
        trans = btrfs_start_transaction(root, 0);
+       if (IS_ERR(trans)) {
+               kfree(device);
+               ret = PTR_ERR(trans);
+               goto error;
+       }
        lock_chunks(root);
  
 -      device->barriers = 1;
        device->writeable = 1;
        device->work.func = pending_bios_fn;
        generate_random_uuid(device->uuid);
@@@ -1686,7 -1695,7 +1696,7 @@@ out
        mutex_unlock(&root->fs_info->volume_mutex);
        return ret;
  error:
 -      close_bdev_exclusive(bdev, 0);
 +      blkdev_put(bdev, FMODE_EXCL);
        if (seeding_dev) {
                mutex_unlock(&uuid_mutex);
                up_write(&sb->s_umount);
@@@ -1873,7 -1882,7 +1883,7 @@@ static int btrfs_relocate_chunk(struct 
                return ret;
  
        trans = btrfs_start_transaction(root, 0);
-       BUG_ON(!trans);
+       BUG_ON(IS_ERR(trans));
  
        lock_chunks(root);
  
@@@ -2047,7 -2056,7 +2057,7 @@@ int btrfs_balance(struct btrfs_root *de
                BUG_ON(ret);
  
                trans = btrfs_start_transaction(dev_root, 0);
-               BUG_ON(!trans);
+               BUG_ON(IS_ERR(trans));
  
                ret = btrfs_grow_device(trans, device, old_size);
                BUG_ON(ret);
@@@ -2213,6 -2222,11 +2223,11 @@@ again
  
        /* Shrinking succeeded, else we would be at "done". */
        trans = btrfs_start_transaction(root, 0);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               goto done;
+       }
        lock_chunks(root);
  
        device->disk_total_bytes = new_size;
@@@ -3379,6 -3393,7 +3394,6 @@@ static struct btrfs_device *add_missing
                return NULL;
        list_add(&device->dev_list,
                 &fs_devices->devices);
 -      device->barriers = 1;
        device->dev_root = root->fs_info->dev_root;
        device->devid = devid;
        device->work.func = pending_bios_fn;