Merge branch 'miklos.fileattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / fs / btrfs / inode.c
index 0e007da..b21d491 100644 (file)
@@ -3386,15 +3386,19 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                        int is_dead_root = 0;
 
                        /*
-                        * this is an orphan in the tree root. Currently these
+                        * This is an orphan in the tree root. Currently these
                         * could come from 2 sources:
-                        *  a) a snapshot deletion in progress
+                        *  a) a root (snapshot/subvolume) deletion in progress
                         *  b) a free space cache inode
-                        * We need to distinguish those two, as the snapshot
-                        * orphan must not get deleted.
-                        * find_dead_roots already ran before us, so if this
-                        * is a snapshot deletion, we should find the root
-                        * in the fs_roots radix tree.
+                        * We need to distinguish those two, as the orphan item
+                        * for a root must not get deleted before the deletion
+                        * of the snapshot/subvolume's tree completes.
+                        *
+                        * btrfs_find_orphan_roots() ran before us, which has
+                        * found all deleted roots and loaded them into
+                        * fs_info->fs_roots_radix. So here we can find if an
+                        * orphan item corresponds to a deleted root by looking
+                        * up the root from that radix tree.
                         */
 
                        spin_lock(&fs_info->fs_roots_radix_lock);
@@ -4325,7 +4329,11 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry)
                goto out_end_trans;
        }
 
-       btrfs_record_root_in_trans(trans, dest);
+       ret = btrfs_record_root_in_trans(trans, dest);
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto out_end_trans;
+       }
 
        memset(&dest->root_item.drop_progress, 0,
                sizeof(dest->root_item.drop_progress));
@@ -7019,7 +7027,7 @@ next:
                                if (ret)
                                        goto out;
                        } else {
-                               map = kmap(page);
+                               map = kmap_local_page(page);
                                read_extent_buffer(leaf, map + pg_offset, ptr,
                                                   copy_size);
                                if (pg_offset + copy_size < PAGE_SIZE) {
@@ -7027,7 +7035,7 @@ next:
                                               PAGE_SIZE - pg_offset -
                                               copy_size);
                                }
-                               kunmap(page);
+                               kunmap_local(map);
                        }
                        flush_dcache_page(page);
                }
@@ -8409,17 +8417,11 @@ again:
                 * for the finish_ordered_io
                 */
                if (TestClearPagePrivate2(page)) {
-                       struct btrfs_ordered_inode_tree *tree;
-                       u64 new_len;
-
-                       tree = &inode->ordered_tree;
-
-                       spin_lock_irq(&tree->lock);
+                       spin_lock_irq(&inode->ordered_tree.lock);
                        set_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags);
-                       new_len = start - ordered->file_offset;
-                       if (new_len < ordered->truncated_len)
-                               ordered->truncated_len = new_len;
-                       spin_unlock_irq(&tree->lock);
+                       ordered->truncated_len = min(ordered->truncated_len,
+                                                    start - ordered->file_offset);
+                       spin_unlock_irq(&inode->ordered_tree.lock);
 
                        if (btrfs_dec_test_ordered_pending(inode, &ordered,
                                                           start,
@@ -9110,8 +9112,11 @@ static int btrfs_rename_exchange(struct inode *old_dir,
                goto out_notrans;
        }
 
-       if (dest != root)
-               btrfs_record_root_in_trans(trans, dest);
+       if (dest != root) {
+               ret = btrfs_record_root_in_trans(trans, dest);
+               if (ret)
+                       goto out_fail;
+       }
 
        /*
         * We need to find a free sequence number both in the source and
@@ -9415,8 +9420,11 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                goto out_notrans;
        }
 
-       if (dest != root)
-               btrfs_record_root_in_trans(trans, dest);
+       if (dest != root) {
+               ret = btrfs_record_root_in_trans(trans, dest);
+               if (ret)
+                       goto out_fail;
+       }
 
        ret = btrfs_set_inode_index(BTRFS_I(new_dir), &index);
        if (ret)
@@ -10612,6 +10620,8 @@ static const struct inode_operations btrfs_dir_inode_operations = {
        .set_acl        = btrfs_set_acl,
        .update_time    = btrfs_update_time,
        .tmpfile        = btrfs_tmpfile,
+       .fileattr_get   = btrfs_fileattr_get,
+       .fileattr_set   = btrfs_fileattr_set,
 };
 
 static const struct file_operations btrfs_dir_file_operations = {
@@ -10665,6 +10675,8 @@ static const struct inode_operations btrfs_file_inode_operations = {
        .get_acl        = btrfs_get_acl,
        .set_acl        = btrfs_set_acl,
        .update_time    = btrfs_update_time,
+       .fileattr_get   = btrfs_fileattr_get,
+       .fileattr_set   = btrfs_fileattr_set,
 };
 static const struct inode_operations btrfs_special_inode_operations = {
        .getattr        = btrfs_getattr,