Hello, Not really sure why but when you do a mkfs it creates a default directory and the root directory is read-only. The first patch makes the root directory writeable, and the second patch fixes mkfs so it sets the root directoryy's permission properly and doesn't create the default directory. I tested this on my box and ran iozone and it worked fine. Thank you, Josef
Josef Bacik
2007-Jun-28 20:36 UTC
[Btrfs-devel] [PATCH 1/2] set the root inode's operations properly
Hello, This patch sets the root inode's inode operations to the normal dir inode operations so you can write to it and such. Thank you, Josef diff -r 080c0640a527 inode.c --- a/inode.c Thu Jun 28 15:57:36 2007 -0400 +++ b/inode.c Thu Jun 28 17:13:00 2007 -0400 @@ -46,7 +46,6 @@ struct btrfs_iget_args { static struct inode_operations btrfs_dir_inode_operations; static struct inode_operations btrfs_symlink_inode_operations; -static struct inode_operations btrfs_dir_ro_inode_operations; static struct inode_operations btrfs_file_inode_operations; static struct address_space_operations btrfs_aops; static struct address_space_operations btrfs_symlink_aops; @@ -128,10 +127,7 @@ void btrfs_read_locked_inode(struct inod break; case S_IFDIR: inode->i_fop = &btrfs_dir_file_operations; - if (root == root->fs_info->tree_root) - inode->i_op = &btrfs_dir_ro_inode_operations; - else - inode->i_op = &btrfs_dir_inode_operations; + inode->i_op = &btrfs_dir_inode_operations; break; case S_IFLNK: inode->i_op = &btrfs_symlink_inode_operations; @@ -2529,10 +2525,6 @@ static struct inode_operations btrfs_dir .setattr = btrfs_setattr, }; -static struct inode_operations btrfs_dir_ro_inode_operations = { - .lookup = btrfs_lookup, -}; - static struct file_operations btrfs_dir_file_operations = { .llseek = generic_file_llseek, .read = generic_read_dir,
Josef Bacik
2007-Jun-28 20:38 UTC
[Btrfs-devel] [PATCH 2/2] fix mkfs so it sets the proper permissions on the root inode
Hello, This patch makes mkfs set the root inode's permissions to 755 and doesn't create the 'default' directory in the root of the filesystem. Thank you, Josef diff -r 85bf73175772 mkfs.c --- a/mkfs.c Thu Jun 28 16:20:29 2007 -0400 +++ b/mkfs.c Thu Jun 28 20:48:25 2007 -0400 @@ -61,7 +61,7 @@ static int __make_root_dir(struct btrfs_ btrfs_set_inode_size(&inode_item, 6); btrfs_set_inode_nlink(&inode_item, 1); btrfs_set_inode_nblocks(&inode_item, 1); - btrfs_set_inode_mode(&inode_item, S_IFDIR | 0555); + btrfs_set_inode_mode(&inode_item, S_IFDIR | 0755); if (root->fs_info->tree_root == root) btrfs_set_super_root_dir(root->fs_info->disk_super, objectid); @@ -146,7 +146,6 @@ static int make_root_dir(int fd) { struct btrfs_super_block super; struct btrfs_trans_handle *trans; int ret; - struct btrfs_key location; root = open_ctree_fd(fd, &super); @@ -161,14 +160,6 @@ static int make_root_dir(int fd) { if (ret) goto err; ret = __make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID); - if (ret) - goto err; - memcpy(&location, &root->fs_info->fs_root->root_key, sizeof(location)); - location.offset = (u64)-1; - ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, - "default", strlen("default"), - btrfs_super_root_dir(root->fs_info->disk_super), - &location, BTRFS_FT_DIR); if (ret) goto err; btrfs_commit_transaction(trans, root, root->fs_info->disk_super);
On Thu, Jun 28, 2007 at 11:36:59PM -0400, Josef Bacik wrote:> Hello, > > Not really sure why but when you do a mkfs it creates a default directory and > the root directory is read-only. The first patch makes the root directory > writeable, and the second patch fixes mkfs so it sets the root directoryy's > permission properly and doesn't create the default directory. I tested this on > my box and ran iozone and it worked fine. Thank you,Thanks for sending these along, but the top level directory is special. It is meant to only have snapshots and subvolumes. As we refine the way that subvolumes and snapshots are presented, the top level directory won't be needed anymore (at least won't need to be visible), but for right now, it does need to be read only. The 'default' directory is a subvolume, where all the tree blocks and file extents inside are reference counted. You can make more subvolumes appear in the root directory with the btrfsctl command: btrfsctl -s new_subvol mount_point The btree that makes up the root directory is written via copy-on-write, but it is not reference counted. It is a special index of the subvolumes and snapshots on the FS, so we don't want to create files there. Here are a few ideas of things that won't conflict too much with my current enospc work. But, if you have other ideas or bits you would like to improve, please feel free to suggest them, I'm happy to get all the help I can. 1) On fsync, ext3 and reiserfs have code to let more writers try and come into the current transaction before a commit is forced (this is called let_transaction_grow in reiserfs). btrfs needs something similar. It's fairly simple, you look at the count of procs currently in the transaction, and if it is non-zero you sleep for a bit before forcing the commit. It's important to sleep without any locks held and without being in the transaction. Once coded, you can benchmark with Ric Wheeler's fs_mark: http://developer.osdl.org/dev/doubt/fs_mark/index.html If you're comparing btrfs to ext3 on a sata or ide drive, make sure to mount ext3 with -o barrier=1 2) The in ram portion of the inode needs a field to indicate which transaction number last changed the inode. This field can be checked by fsync to decide if a commit is actually required. You would have to an index (use a radix tree) of the in memory transaction structs so that you can check to make sure a given transaction is actually done. 3) struct btrfs_root_item has fields for block use accounting, but they currently don't get updated. When blocks are allocated for a given root, we need to reflect that in struct btrfs_root_item and send it down to disk when the transaction commits. The in memory struct btrfs_root has a duplicate of the root item, so the updates can be stored in the in memory version and then put into the tree once right before commit. -chris