btrfs: remove stale newlines from log messages
[deliverable/linux.git] / fs / btrfs / inode.c
index 06e9a4152b1419c6e4afbd4fd3580615ffc4eadd..0b8ce3002cfe36c1190e224ab5731aec31d55fe9 100644 (file)
@@ -394,6 +394,14 @@ static noinline int compress_file_range(struct inode *inode,
            (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
                btrfs_add_inode_defrag(NULL, inode);
 
+       /*
+        * skip compression for a small file range(<=blocksize) that
+        * isn't an inline extent, since it dosen't save disk space at all.
+        */
+       if ((end - start + 1) <= blocksize &&
+           (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
+               goto cleanup_and_bail_uncompressed;
+
        actual_end = min_t(u64, isize, end + 1);
 again:
        will_compress = 0;
@@ -1270,6 +1278,15 @@ next_slot:
                        disk_bytenr += extent_offset;
                        disk_bytenr += cur_offset - found_key.offset;
                        num_bytes = min(end + 1, extent_end) - cur_offset;
+                       /*
+                        * if there are pending snapshots for this root,
+                        * we fall into common COW way.
+                        */
+                       if (!nolock) {
+                               err = btrfs_start_nocow_write(root);
+                               if (!err)
+                                       goto out_check;
+                       }
                        /*
                         * force cow if csum exists in the range.
                         * this ensure that csum for a given extent are
@@ -1289,6 +1306,8 @@ next_slot:
 out_check:
                if (extent_end <= start) {
                        path->slots[0]++;
+                       if (!nolock && nocow)
+                               btrfs_end_nocow_write(root);
                        goto next_slot;
                }
                if (!nocow) {
@@ -1306,8 +1325,11 @@ out_check:
                        ret = cow_file_range(inode, locked_page,
                                             cow_start, found_key.offset - 1,
                                             page_started, nr_written, 1);
-                       if (ret)
+                       if (ret) {
+                               if (!nolock && nocow)
+                                       btrfs_end_nocow_write(root);
                                goto error;
+                       }
                        cow_start = (u64)-1;
                }
 
@@ -1354,8 +1376,11 @@ out_check:
                    BTRFS_DATA_RELOC_TREE_OBJECTID) {
                        ret = btrfs_reloc_clone_csums(inode, cur_offset,
                                                      num_bytes);
-                       if (ret)
+                       if (ret) {
+                               if (!nolock && nocow)
+                                       btrfs_end_nocow_write(root);
                                goto error;
+                       }
                }
 
                extent_clear_unlock_delalloc(inode, cur_offset,
@@ -1363,6 +1388,8 @@ out_check:
                                             locked_page, EXTENT_LOCKED |
                                             EXTENT_DELALLOC, PAGE_UNLOCK |
                                             PAGE_SET_PRIVATE2);
+               if (!nolock && nocow)
+                       btrfs_end_nocow_write(root);
                cur_offset = extent_end;
                if (cur_offset > end)
                        break;
@@ -2920,14 +2947,15 @@ void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans,
        root->orphan_block_rsv = NULL;
        spin_unlock(&root->orphan_lock);
 
-       if (root->orphan_item_inserted &&
+       if (test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state) &&
            btrfs_root_refs(&root->root_item) > 0) {
                ret = btrfs_del_orphan_item(trans, root->fs_info->tree_root,
                                            root->root_key.objectid);
                if (ret)
                        btrfs_abort_transaction(trans, root, ret);
                else
-                       root->orphan_item_inserted = 0;
+                       clear_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
+                                 &root->state);
        }
 
        if (block_rsv) {
@@ -3244,7 +3272,8 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                btrfs_block_rsv_release(root, root->orphan_block_rsv,
                                        (u64)-1);
 
-       if (root->orphan_block_rsv || root->orphan_item_inserted) {
+       if (root->orphan_block_rsv ||
+           test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state)) {
                trans = btrfs_join_transaction(root);
                if (!IS_ERR(trans))
                        btrfs_end_transaction(trans, root);
@@ -3446,7 +3475,7 @@ cache_acl:
                ret = btrfs_load_inode_props(inode, path);
                if (ret)
                        btrfs_err(root->fs_info,
-                                 "error loading props for ino %llu (root %llu): %d\n",
+                                 "error loading props for ino %llu (root %llu): %d",
                                  btrfs_ino(inode),
                                  root->root_key.objectid, ret);
        }
@@ -3971,7 +4000,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
         * not block aligned since we will be keeping the last block of the
         * extent just the way it is.
         */
-       if (root->ref_cows || root == root->fs_info->tree_root)
+       if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
+           root == root->fs_info->tree_root)
                btrfs_drop_extent_cache(inode, ALIGN(new_size,
                                        root->sectorsize), (u64)-1, 0);
 
@@ -4064,7 +4094,9 @@ search_again:
                                                         extent_num_bytes);
                                num_dec = (orig_num_bytes -
                                           extent_num_bytes);
-                               if (root->ref_cows && extent_start != 0)
+                               if (test_bit(BTRFS_ROOT_REF_COWS,
+                                            &root->state) &&
+                                   extent_start != 0)
                                        inode_sub_bytes(inode, num_dec);
                                btrfs_mark_buffer_dirty(leaf);
                        } else {
@@ -4078,7 +4110,8 @@ search_again:
                                num_dec = btrfs_file_extent_num_bytes(leaf, fi);
                                if (extent_start != 0) {
                                        found_extent = 1;
-                                       if (root->ref_cows)
+                                       if (test_bit(BTRFS_ROOT_REF_COWS,
+                                                    &root->state))
                                                inode_sub_bytes(inode, num_dec);
                                }
                        }
@@ -4093,10 +4126,9 @@ search_again:
                            btrfs_file_extent_other_encoding(leaf, fi) == 0) {
                                u32 size = new_size - found_key.offset;
 
-                               if (root->ref_cows) {
+                               if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
                                        inode_sub_bytes(inode, item_end + 1 -
                                                        new_size);
-                               }
 
                                /*
                                 * update the ram bytes to properly reflect
@@ -4106,7 +4138,8 @@ search_again:
                                size =
                                    btrfs_file_extent_calc_inline_size(size);
                                btrfs_truncate_item(root, path, size, 1);
-                       } else if (root->ref_cows) {
+                       } else if (test_bit(BTRFS_ROOT_REF_COWS,
+                                           &root->state)) {
                                inode_sub_bytes(inode, item_end + 1 -
                                                found_key.offset);
                        }
@@ -4128,8 +4161,9 @@ delete:
                } else {
                        break;
                }
-               if (found_extent && (root->ref_cows ||
-                                    root == root->fs_info->tree_root)) {
+               if (found_extent &&
+                   (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
+                    root == root->fs_info->tree_root)) {
                        btrfs_set_path_blocking(path);
                        ret = btrfs_free_extent(trans, root, extent_start,
                                                extent_num_bytes, 0,
@@ -5141,8 +5175,7 @@ static int btrfs_dentry_delete(const struct dentry *dentry)
 
 static void btrfs_dentry_release(struct dentry *dentry)
 {
-       if (dentry->d_fsdata)
-               kfree(dentry->d_fsdata);
+       kfree(dentry->d_fsdata);
 }
 
 static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
@@ -5526,6 +5559,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        struct btrfs_inode_ref *ref;
        struct btrfs_key key[2];
        u32 sizes[2];
+       int nitems = name ? 2 : 1;
        unsigned long ptr;
        int ret;
 
@@ -5545,7 +5579,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
         */
        inode->i_ino = objectid;
 
-       if (dir) {
+       if (dir && name) {
                trace_btrfs_inode_request(dir);
 
                ret = btrfs_set_inode_index(dir, index);
@@ -5554,6 +5588,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                        iput(inode);
                        return ERR_PTR(ret);
                }
+       } else if (dir) {
+               *index = 0;
        }
        /*
         * index_cnt is ignored for everything but a dir,
@@ -5578,21 +5614,24 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
        key[0].offset = 0;
 
-       /*
-        * Start new inodes with an inode_ref. This is slightly more
-        * efficient for small numbers of hard links since they will
-        * be packed into one item. Extended refs will kick in if we
-        * add more hard links than can fit in the ref item.
-        */
-       key[1].objectid = objectid;
-       btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
-       key[1].offset = ref_objectid;
-
        sizes[0] = sizeof(struct btrfs_inode_item);
-       sizes[1] = name_len + sizeof(*ref);
+
+       if (name) {
+               /*
+                * Start new inodes with an inode_ref. This is slightly more
+                * efficient for small numbers of hard links since they will
+                * be packed into one item. Extended refs will kick in if we
+                * add more hard links than can fit in the ref item.
+                */
+               key[1].objectid = objectid;
+               btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
+               key[1].offset = ref_objectid;
+
+               sizes[1] = name_len + sizeof(*ref);
+       }
 
        path->leave_spinning = 1;
-       ret = btrfs_insert_empty_items(trans, root, path, key, sizes, 2);
+       ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems);
        if (ret != 0)
                goto fail;
 
@@ -5605,12 +5644,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                             sizeof(*inode_item));
        fill_inode_item(trans, path->nodes[0], inode_item, inode);
 
-       ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
-                            struct btrfs_inode_ref);
-       btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
-       btrfs_set_inode_ref_index(path->nodes[0], ref, *index);
-       ptr = (unsigned long)(ref + 1);
-       write_extent_buffer(path->nodes[0], name, ptr, name_len);
+       if (name) {
+               ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
+                                    struct btrfs_inode_ref);
+               btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
+               btrfs_set_inode_ref_index(path->nodes[0], ref, *index);
+               ptr = (unsigned long)(ref + 1);
+               write_extent_buffer(path->nodes[0], name, ptr, name_len);
+       }
 
        btrfs_mark_buffer_dirty(path->nodes[0]);
        btrfs_free_path(path);
@@ -5646,7 +5687,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
 
        return inode;
 fail:
-       if (dir)
+       if (dir && name)
                BTRFS_I(dir)->index_cnt--;
        btrfs_free_path(path);
        iput(inode);
@@ -5931,6 +5972,15 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                err = btrfs_update_inode(trans, root, inode);
                if (err)
                        goto fail;
+               if (inode->i_nlink == 1) {
+                       /*
+                        * If new hard link count is 1, it's a file created
+                        * with open(2) O_TMPFILE flag.
+                        */
+                       err = btrfs_orphan_del(trans, inode);
+                       if (err)
+                               goto fail;
+               }
                d_instantiate(dentry, inode);
                btrfs_log_new_name(trans, inode, NULL, parent);
        }
@@ -6059,16 +6109,8 @@ static noinline int uncompress_inline(struct btrfs_path *path,
        max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size);
        ret = btrfs_decompress(compress_type, tmp, page,
                               extent_offset, inline_size, max_size);
-       if (ret) {
-               char *kaddr = kmap_atomic(page);
-               unsigned long copy_size = min_t(u64,
-                                 PAGE_CACHE_SIZE - pg_offset,
-                                 max_size - extent_offset);
-               memset(kaddr + pg_offset, 0, copy_size);
-               kunmap_atomic(kaddr);
-       }
        kfree(tmp);
-       return 0;
+       return ret;
 }
 
 /*
@@ -6269,7 +6311,10 @@ next:
                                ret = uncompress_inline(path, inode, page,
                                                        pg_offset,
                                                        extent_offset, item);
-                               BUG_ON(ret); /* -ENOMEM */
+                               if (ret) {
+                                       err = ret;
+                                       goto out;
+                               }
                        } else {
                                map = kmap(page);
                                read_extent_buffer(leaf, map + pg_offset, ptr,
@@ -7965,7 +8010,7 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
        err = btrfs_subvol_inherit_props(trans, new_root, parent_root);
        if (err)
                btrfs_err(new_root->fs_info,
-                         "error inheriting subvolume %llu properties: %d\n",
+                         "error inheriting subvolume %llu properties: %d",
                          new_root->root_key.objectid, err);
 
        err = btrfs_update_inode(trans, new_root, inode);
@@ -8284,7 +8329,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        BTRFS_I(old_inode)->dir_index = 0ULL;
        if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) {
                /* force full log commit if subvolume involved. */
-               root->fs_info->last_trans_log_full_commit = trans->transid;
+               btrfs_set_log_full_commit(root->fs_info, trans);
        } else {
                ret = btrfs_insert_inode_ref(trans, dest,
                                             new_dentry->d_name.name,
@@ -8476,19 +8521,20 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput,
                        else
                                iput(inode);
                        ret = -ENOMEM;
-                       break;
+                       goto out;
                }
                list_add_tail(&work->list, &works);
                btrfs_queue_work(root->fs_info->flush_workers,
                                 &work->work);
                ret++;
                if (nr != -1 && ret >= nr)
-                       break;
+                       goto out;
                cond_resched();
                spin_lock(&root->delalloc_lock);
        }
        spin_unlock(&root->delalloc_lock);
 
+out:
        list_for_each_entry_safe(work, next, &works, list) {
                list_del_init(&work->list);
                btrfs_wait_and_free_delalloc_work(work);
@@ -8861,6 +8907,66 @@ static int btrfs_permission(struct inode *inode, int mask)
        return generic_permission(inode, mask);
 }
 
+static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+       struct btrfs_trans_handle *trans;
+       struct btrfs_root *root = BTRFS_I(dir)->root;
+       struct inode *inode = NULL;
+       u64 objectid;
+       u64 index;
+       int ret = 0;
+
+       /*
+        * 5 units required for adding orphan entry
+        */
+       trans = btrfs_start_transaction(root, 5);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
+
+       ret = btrfs_find_free_ino(root, &objectid);
+       if (ret)
+               goto out;
+
+       inode = btrfs_new_inode(trans, root, dir, NULL, 0,
+                               btrfs_ino(dir), objectid, mode, &index);
+       if (IS_ERR(inode)) {
+               ret = PTR_ERR(inode);
+               inode = NULL;
+               goto out;
+       }
+
+       ret = btrfs_init_inode_security(trans, inode, dir, NULL);
+       if (ret)
+               goto out;
+
+       ret = btrfs_update_inode(trans, root, inode);
+       if (ret)
+               goto out;
+
+       inode->i_fop = &btrfs_file_operations;
+       inode->i_op = &btrfs_file_inode_operations;
+
+       inode->i_mapping->a_ops = &btrfs_aops;
+       inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
+       BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
+
+       ret = btrfs_orphan_add(trans, inode);
+       if (ret)
+               goto out;
+
+       d_tmpfile(dentry, inode);
+       mark_inode_dirty(inode);
+
+out:
+       btrfs_end_transaction(trans, root);
+       if (ret)
+               iput(inode);
+       btrfs_balance_delayed_items(root);
+       btrfs_btree_balance_dirty(root);
+
+       return ret;
+}
+
 static const struct inode_operations btrfs_dir_inode_operations = {
        .getattr        = btrfs_getattr,
        .lookup         = btrfs_lookup,
@@ -8881,6 +8987,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
        .get_acl        = btrfs_get_acl,
        .set_acl        = btrfs_set_acl,
        .update_time    = btrfs_update_time,
+       .tmpfile        = btrfs_tmpfile,
 };
 static const struct inode_operations btrfs_dir_ro_inode_operations = {
        .lookup         = btrfs_lookup,
This page took 0.031949 seconds and 5 git commands to generate.