aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@gmail.com>2014-04-27 15:40:45 -0400
committerChris Mason <clm@fb.com>2014-06-09 20:20:30 -0400
commitef3b9af50bfa6a1f02cd7b3f5124b712b1ba3e3c (patch)
tree8aeb9ff9803aa2060676c1817ca11f0015d1da1c /fs/btrfs/inode.c
parente4ef90ff6198ac58d4c7dbbeae8cc7b24867d1ca (diff)
Btrfs: implement inode_operations callback tmpfile
This implements the tmpfile callback of struct inode_operations, introduced in the linux kernel 3.11, and implemented already by some filesystems. This callback is invoked by the VFS when the flag O_TMPFILE is passed to the open system call. Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com> Signed-off-by: Chris Mason <clm@fb.com> Reviewed-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 24dfa27a4f76..5c0def8dd761 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5553,6 +5553,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5553 struct btrfs_inode_ref *ref; 5553 struct btrfs_inode_ref *ref;
5554 struct btrfs_key key[2]; 5554 struct btrfs_key key[2];
5555 u32 sizes[2]; 5555 u32 sizes[2];
5556 int nitems = name ? 2 : 1;
5556 unsigned long ptr; 5557 unsigned long ptr;
5557 int ret; 5558 int ret;
5558 5559
@@ -5572,7 +5573,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5572 */ 5573 */
5573 inode->i_ino = objectid; 5574 inode->i_ino = objectid;
5574 5575
5575 if (dir) { 5576 if (dir && name) {
5576 trace_btrfs_inode_request(dir); 5577 trace_btrfs_inode_request(dir);
5577 5578
5578 ret = btrfs_set_inode_index(dir, index); 5579 ret = btrfs_set_inode_index(dir, index);
@@ -5581,6 +5582,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5581 iput(inode); 5582 iput(inode);
5582 return ERR_PTR(ret); 5583 return ERR_PTR(ret);
5583 } 5584 }
5585 } else if (dir) {
5586 *index = 0;
5584 } 5587 }
5585 /* 5588 /*
5586 * index_cnt is ignored for everything but a dir, 5589 * index_cnt is ignored for everything but a dir,
@@ -5605,21 +5608,24 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5605 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 5608 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
5606 key[0].offset = 0; 5609 key[0].offset = 0;
5607 5610
5608 /*
5609 * Start new inodes with an inode_ref. This is slightly more
5610 * efficient for small numbers of hard links since they will
5611 * be packed into one item. Extended refs will kick in if we
5612 * add more hard links than can fit in the ref item.
5613 */
5614 key[1].objectid = objectid;
5615 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
5616 key[1].offset = ref_objectid;
5617
5618 sizes[0] = sizeof(struct btrfs_inode_item); 5611 sizes[0] = sizeof(struct btrfs_inode_item);
5619 sizes[1] = name_len + sizeof(*ref); 5612
5613 if (name) {
5614 /*
5615 * Start new inodes with an inode_ref. This is slightly more
5616 * efficient for small numbers of hard links since they will
5617 * be packed into one item. Extended refs will kick in if we
5618 * add more hard links than can fit in the ref item.
5619 */
5620 key[1].objectid = objectid;
5621 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
5622 key[1].offset = ref_objectid;
5623
5624 sizes[1] = name_len + sizeof(*ref);
5625 }
5620 5626
5621 path->leave_spinning = 1; 5627 path->leave_spinning = 1;
5622 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, 2); 5628 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems);
5623 if (ret != 0) 5629 if (ret != 0)
5624 goto fail; 5630 goto fail;
5625 5631
@@ -5632,12 +5638,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5632 sizeof(*inode_item)); 5638 sizeof(*inode_item));
5633 fill_inode_item(trans, path->nodes[0], inode_item, inode); 5639 fill_inode_item(trans, path->nodes[0], inode_item, inode);
5634 5640
5635 ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1, 5641 if (name) {
5636 struct btrfs_inode_ref); 5642 ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
5637 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); 5643 struct btrfs_inode_ref);
5638 btrfs_set_inode_ref_index(path->nodes[0], ref, *index); 5644 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
5639 ptr = (unsigned long)(ref + 1); 5645 btrfs_set_inode_ref_index(path->nodes[0], ref, *index);
5640 write_extent_buffer(path->nodes[0], name, ptr, name_len); 5646 ptr = (unsigned long)(ref + 1);
5647 write_extent_buffer(path->nodes[0], name, ptr, name_len);
5648 }
5641 5649
5642 btrfs_mark_buffer_dirty(path->nodes[0]); 5650 btrfs_mark_buffer_dirty(path->nodes[0]);
5643 btrfs_free_path(path); 5651 btrfs_free_path(path);
@@ -5673,7 +5681,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5673 5681
5674 return inode; 5682 return inode;
5675fail: 5683fail:
5676 if (dir) 5684 if (dir && name)
5677 BTRFS_I(dir)->index_cnt--; 5685 BTRFS_I(dir)->index_cnt--;
5678 btrfs_free_path(path); 5686 btrfs_free_path(path);
5679 iput(inode); 5687 iput(inode);
@@ -5958,6 +5966,15 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
5958 err = btrfs_update_inode(trans, root, inode); 5966 err = btrfs_update_inode(trans, root, inode);
5959 if (err) 5967 if (err)
5960 goto fail; 5968 goto fail;
5969 if (inode->i_nlink == 1) {
5970 /*
5971 * If new hard link count is 1, it's a file created
5972 * with open(2) O_TMPFILE flag.
5973 */
5974 err = btrfs_orphan_del(trans, inode);
5975 if (err)
5976 goto fail;
5977 }
5961 d_instantiate(dentry, inode); 5978 d_instantiate(dentry, inode);
5962 btrfs_log_new_name(trans, inode, NULL, parent); 5979 btrfs_log_new_name(trans, inode, NULL, parent);
5963 } 5980 }
@@ -8884,6 +8901,66 @@ static int btrfs_permission(struct inode *inode, int mask)
8884 return generic_permission(inode, mask); 8901 return generic_permission(inode, mask);
8885} 8902}
8886 8903
8904static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
8905{
8906 struct btrfs_trans_handle *trans;
8907 struct btrfs_root *root = BTRFS_I(dir)->root;
8908 struct inode *inode = NULL;
8909 u64 objectid;
8910 u64 index;
8911 int ret = 0;
8912
8913 /*
8914 * 5 units required for adding orphan entry
8915 */
8916 trans = btrfs_start_transaction(root, 5);
8917 if (IS_ERR(trans))
8918 return PTR_ERR(trans);
8919
8920 ret = btrfs_find_free_ino(root, &objectid);
8921 if (ret)
8922 goto out;
8923
8924 inode = btrfs_new_inode(trans, root, dir, NULL, 0,
8925 btrfs_ino(dir), objectid, mode, &index);
8926 if (IS_ERR(inode)) {
8927 ret = PTR_ERR(inode);
8928 inode = NULL;
8929 goto out;
8930 }
8931
8932 ret = btrfs_init_inode_security(trans, inode, dir, NULL);
8933 if (ret)
8934 goto out;
8935
8936 ret = btrfs_update_inode(trans, root, inode);
8937 if (ret)
8938 goto out;
8939
8940 inode->i_fop = &btrfs_file_operations;
8941 inode->i_op = &btrfs_file_inode_operations;
8942
8943 inode->i_mapping->a_ops = &btrfs_aops;
8944 inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
8945 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
8946
8947 ret = btrfs_orphan_add(trans, inode);
8948 if (ret)
8949 goto out;
8950
8951 d_tmpfile(dentry, inode);
8952 mark_inode_dirty(inode);
8953
8954out:
8955 btrfs_end_transaction(trans, root);
8956 if (ret)
8957 iput(inode);
8958 btrfs_balance_delayed_items(root);
8959 btrfs_btree_balance_dirty(root);
8960
8961 return ret;
8962}
8963
8887static const struct inode_operations btrfs_dir_inode_operations = { 8964static const struct inode_operations btrfs_dir_inode_operations = {
8888 .getattr = btrfs_getattr, 8965 .getattr = btrfs_getattr,
8889 .lookup = btrfs_lookup, 8966 .lookup = btrfs_lookup,
@@ -8904,6 +8981,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
8904 .get_acl = btrfs_get_acl, 8981 .get_acl = btrfs_get_acl,
8905 .set_acl = btrfs_set_acl, 8982 .set_acl = btrfs_set_acl,
8906 .update_time = btrfs_update_time, 8983 .update_time = btrfs_update_time,
8984 .tmpfile = btrfs_tmpfile,
8907}; 8985};
8908static const struct inode_operations btrfs_dir_ro_inode_operations = { 8986static const struct inode_operations btrfs_dir_ro_inode_operations = {
8909 .lookup = btrfs_lookup, 8987 .lookup = btrfs_lookup,