Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128598
b: refs/heads/master
c: dc17ff8
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent c791881 commit a661744
Show file tree
Hide file tree
Showing 14 changed files with 388 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e4204dedbbaa3a614605cb83cc0ac5161af6b4e6
refs/heads/master: dc17ff8f11d129db9e83ab7244769e4eae05e14d
2 changes: 1 addition & 1 deletion trunk/fs/btrfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ obj-m := btrfs.o
btrfs-y := super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
hash.o file-item.o inode-item.o inode-map.o disk-io.o \
transaction.o bit-radix.o inode.o file.o tree-defrag.o \
extent_map.o sysfs.o struct-funcs.o xattr.o acl.o
extent_map.o sysfs.o struct-funcs.o xattr.o acl.o ordered-data.o

#btrfs-y := ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
# root-tree.o dir-item.o hash.o file-item.o inode-item.o \
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/btrfs/btrfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct btrfs_inode {
struct extent_map_tree extent_tree;
struct inode vfs_inode;

u64 ordered_trans;
/*
* transid of the trans_handle that last modified this inode
*/
Expand Down
6 changes: 5 additions & 1 deletion trunk/fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
struct extent_buffer **cow_ret)
{
u64 search_start;
u64 header_trans;
int ret;

if (trans->transaction != root->fs_info->running_transaction) {
printk(KERN_CRIT "trans %Lu running %Lu\n", trans->transid,
root->fs_info->running_transaction->transid);
Expand All @@ -232,7 +234,9 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
root->fs_info->generation);
WARN_ON(1);
}
if (btrfs_header_generation(buf) == trans->transid) {

header_trans = btrfs_header_generation(buf);
if (header_trans == trans->transid) {
*cow_ret = buf;
return 0;
}
Expand Down
7 changes: 4 additions & 3 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
* Boston, MA 021110-1307, USA.
*/

#ifndef __BTRFS__
#define __BTRFS__
#ifndef __BTRFS_CTREE__
#define __BTRFS_CTREE__

#include <linux/version.h>
#include <linux/mm.h>
Expand Down Expand Up @@ -363,7 +363,6 @@ struct btrfs_root {
struct inode *inode;
struct kobject root_kobj;
struct completion kobj_unregister;
struct rw_semaphore snap_sem;
u64 objectid;
u64 last_trans;

Expand Down Expand Up @@ -1142,6 +1141,8 @@ void btrfs_destroy_cachep(void);
long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid,
struct btrfs_root *root);
struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
u64 root_objectid);
int btrfs_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to);
struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
Expand Down
16 changes: 15 additions & 1 deletion trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
memset(&root->root_kobj, 0, sizeof(root->root_kobj));
init_completion(&root->kobj_unregister);
init_rwsem(&root->snap_sem);
root->defrag_running = 0;
root->defrag_level = 0;
root->root_key.objectid = objectid;
Expand Down Expand Up @@ -498,6 +497,21 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
return root;
}

struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
u64 root_objectid)
{
struct btrfs_root *root;

if (root_objectid == BTRFS_ROOT_TREE_OBJECTID)
return fs_info->tree_root;
if (root_objectid == BTRFS_EXTENT_TREE_OBJECTID)
return fs_info->extent_root;

root = radix_tree_lookup(&fs_info->fs_roots_radix,
(unsigned long)root_objectid);
return root;
}

struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
struct btrfs_key *location)
{
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/disk-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
u64 bytenr, u32 blocksize);
struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
u64 root_objectid);
struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
struct btrfs_key *location,
const char *name, int namelen);
Expand Down
4 changes: 3 additions & 1 deletion trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,9 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
if (btrfs_buffer_uptodate(buf)) {
u64 transid =
root->fs_info->running_transaction->transid;
if (btrfs_header_generation(buf) == transid) {
u64 header_transid =
btrfs_header_generation(buf);
if (header_transid == transid) {
free_extent_buffer(buf);
return 1;
}
Expand Down
5 changes: 2 additions & 3 deletions trunk/fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "disk-io.h"
#include "transaction.h"
#include "btrfs_inode.h"
#include "ordered-data.h"
#include "ioctl.h"
#include "print-tree.h"

Expand Down Expand Up @@ -329,6 +330,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
root->fs_info->delalloc_bytes += (end_of_last_block + 1 -
start_pos) - existing_delalloc;
spin_unlock(&root->fs_info->delalloc_lock);
btrfs_add_ordered_inode(inode);
} else {
u64 aligned_end;
/* step one, delete the existing extents in this range */
Expand Down Expand Up @@ -724,8 +726,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,

pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);

down_read(&BTRFS_I(inode)->root->snap_sem);

mutex_lock(&inode->i_mutex);
first_index = pos >> PAGE_CACHE_SHIFT;
last_index = (pos + count) >> PAGE_CACHE_SHIFT;
Expand Down Expand Up @@ -804,7 +804,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
}
out:
mutex_unlock(&inode->i_mutex);
up_read(&BTRFS_I(inode)->root->snap_sem);

out_nolock:
kfree(pages);
Expand Down
46 changes: 30 additions & 16 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
alloc_hint = ins.objectid + ins.offset;
start += cur_alloc_size;
}
btrfs_add_ordered_inode(inode);
out:
btrfs_end_transaction(trans, root);
return ret;
Expand Down Expand Up @@ -367,8 +368,8 @@ void btrfs_read_locked_inode(struct inode *inode)
path = btrfs_alloc_path();
BUG_ON(!path);
mutex_lock(&root->fs_info->fs_mutex);

memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));

ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
if (ret)
goto make_bad;
Expand Down Expand Up @@ -898,7 +899,6 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
if ((offset & (blocksize - 1)) == 0)
goto out;

down_read(&root->snap_sem);
ret = -ENOMEM;
page = grab_cache_page(mapping, index);
if (!page)
Expand All @@ -917,7 +917,6 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)

unlock_page(page);
page_cache_release(page);
up_read(&BTRFS_I(inode)->root->snap_sem);
out:
return ret;
}
Expand Down Expand Up @@ -1146,6 +1145,19 @@ static int btrfs_find_actor(struct inode *inode, void *opaque)
args->root == BTRFS_I(inode)->root);
}

struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
u64 root_objectid)
{
struct btrfs_iget_args args;
args.ino = objectid;
args.root = btrfs_lookup_fs_root(btrfs_sb(s)->fs_info, root_objectid);

if (!args.root)
return NULL;

return ilookup5(s, objectid, btrfs_find_actor, (void *)&args);
}

struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid,
struct btrfs_root *root)
{
Expand Down Expand Up @@ -1336,7 +1348,6 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)

d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
btrfs_dir_item_key_to_cpu(leaf, di, &location);

over = filldir(dirent, name_ptr, name_len,
found_key.offset,
location.objectid,
Expand Down Expand Up @@ -2054,7 +2065,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page)

ret = -EINVAL;

down_read(&BTRFS_I(inode)->root->snap_sem);
lock_page(page);
wait_on_page_writeback(page);
size = i_size_read(inode);
Expand All @@ -2075,7 +2085,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
ret = btrfs_cow_one_page(inode, page, end);

out_unlock:
up_read(&BTRFS_I(inode)->root->snap_sem);
unlock_page(page);
out:
return ret;
Expand Down Expand Up @@ -2118,7 +2127,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name,
struct btrfs_root_item root_item;
struct btrfs_inode_item *inode_item;
struct extent_buffer *leaf;
struct btrfs_root *new_root;
struct btrfs_root *new_root = root;
struct inode *inode;
struct inode *dir;
int ret;
Expand Down Expand Up @@ -2230,7 +2239,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name,
goto fail;
fail:
nr = trans->blocks_used;
err = btrfs_commit_transaction(trans, root);
err = btrfs_commit_transaction(trans, new_root);
if (err && !ret)
ret = err;
fail_commit:
Expand All @@ -2253,17 +2262,16 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
if (!root->ref_cows)
return -EINVAL;

down_write(&root->snap_sem);
freeze_bdev(root->fs_info->sb->s_bdev);
thaw_bdev(root->fs_info->sb->s_bdev, root->fs_info->sb);

mutex_lock(&root->fs_info->fs_mutex);
ret = btrfs_check_free_space(root, 1, 0);
if (ret)
goto fail_unlock;

trans = btrfs_start_transaction(root, 1);
BUG_ON(!trans);
err = btrfs_commit_transaction(trans, root);

trans = btrfs_start_transaction(root, 1);

ret = btrfs_update_inode(trans, root, root->inode);
if (ret)
Expand All @@ -2272,9 +2280,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root,
0, &objectid);
if (ret)
goto fail;

memcpy(&new_root_item, &root->root_item,
goto fail; memcpy(&new_root_item, &root->root_item,
sizeof(new_root_item));

key.objectid = objectid;
Expand All @@ -2285,12 +2291,20 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
free_extent_buffer(tmp);

/* write the ordered inodes to force all delayed allocations to
* be filled. Once this is done, we can copy the root
*/
mutex_lock(&root->fs_info->trans_mutex);
btrfs_write_ordered_inodes(trans, root);
mutex_unlock(&root->fs_info->trans_mutex);

btrfs_copy_root(trans, root, root->node, &tmp, objectid);

btrfs_set_root_bytenr(&new_root_item, tmp->start);
btrfs_set_root_level(&new_root_item, btrfs_header_level(tmp));
ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
&new_root_item);
printk("new root %Lu node %Lu\n", objectid, tmp->start);
free_extent_buffer(tmp);
if (ret)
goto fail;
Expand Down Expand Up @@ -2321,7 +2335,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
ret = err;
fail_unlock:
mutex_unlock(&root->fs_info->fs_mutex);
up_write(&root->snap_sem);
btrfs_btree_balance_dirty(root, nr);
return ret;
}
Expand Down Expand Up @@ -2608,6 +2621,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
if (!ei)
return NULL;
ei->last_trans = 0;
ei->ordered_trans = 0;
return &ei->vfs_inode;
}

Expand Down
Loading

0 comments on commit a661744

Please sign in to comment.