Btrfs: Add inode sequence number for NFS and reserved space in a few structs

This adds a sequence number to the btrfs inode that is increased on
every update.  NFS will be able to use that to detect when an inode has
changed, without relying on inaccurate time fields.

While we're here, this also:

Puts reserved space into the super block and inode

Adds a log root transid to the super so we can pick the newest super
based on the fsync log as well as the main transaction ID.  For now
the log root transid is always zero, but that'll get fixed.

Adds a starting offset to the dev_item.  This will let us do better
alignment calculations if we know the start of a partition on the disk.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
Chris Mason 2008-12-08 16:40:21 -05:00
parent 934d375bac
commit c3027eb552
5 changed files with 34 additions and 4 deletions

View File

@ -49,9 +49,6 @@ struct btrfs_inode {
*/ */
struct extent_io_tree io_failure_tree; struct extent_io_tree io_failure_tree;
/* held while inserting checksums to avoid races */
struct mutex csum_mutex;
/* held while inesrting or deleting extents from files */ /* held while inesrting or deleting extents from files */
struct mutex extent_mutex; struct mutex extent_mutex;
@ -79,6 +76,9 @@ struct btrfs_inode {
*/ */
u64 generation; u64 generation;
/* sequence number for NFS changes */
u64 sequence;
/* /*
* transid of the trans_handle that last modified this inode * transid of the trans_handle that last modified this inode
*/ */

View File

@ -196,6 +196,12 @@ struct btrfs_dev_item {
/* expected generation for this device */ /* expected generation for this device */
__le64 generation; __le64 generation;
/*
* starting byte of this partition on the device,
* to allowr for stripe alignment in the future
*/
__le64 start_offset;
/* grouping information for allocation decisions */ /* grouping information for allocation decisions */
__le32 dev_group; __le32 dev_group;
@ -311,6 +317,9 @@ struct btrfs_super_block {
__le64 root; __le64 root;
__le64 chunk_root; __le64 chunk_root;
__le64 log_root; __le64 log_root;
/* this will help find the new super based on the log root */
__le64 log_root_transid;
__le64 total_bytes; __le64 total_bytes;
__le64 bytes_used; __le64 bytes_used;
__le64 root_dir_objectid; __le64 root_dir_objectid;
@ -329,7 +338,11 @@ struct btrfs_super_block {
u8 chunk_root_level; u8 chunk_root_level;
u8 log_root_level; u8 log_root_level;
struct btrfs_dev_item dev_item; struct btrfs_dev_item dev_item;
char label[BTRFS_LABEL_SIZE]; char label[BTRFS_LABEL_SIZE];
/* future expansion */
__le64 reserved[32];
u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
@ -463,6 +476,14 @@ struct btrfs_inode_item {
__le64 rdev; __le64 rdev;
__le64 flags; __le64 flags;
/* modification sequence number for NFS */
__le64 sequence;
/*
* a little future expansion, for more than this we can
* just grow the inode item and version it
*/
__le64 reserved[4];
struct btrfs_timespec atime; struct btrfs_timespec atime;
struct btrfs_timespec ctime; struct btrfs_timespec ctime;
struct btrfs_timespec mtime; struct btrfs_timespec mtime;
@ -1001,6 +1022,8 @@ BTRFS_SETGET_FUNCS(device_total_bytes, struct btrfs_dev_item, total_bytes, 64);
BTRFS_SETGET_FUNCS(device_bytes_used, struct btrfs_dev_item, bytes_used, 64); BTRFS_SETGET_FUNCS(device_bytes_used, struct btrfs_dev_item, bytes_used, 64);
BTRFS_SETGET_FUNCS(device_io_align, struct btrfs_dev_item, io_align, 32); BTRFS_SETGET_FUNCS(device_io_align, struct btrfs_dev_item, io_align, 32);
BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32); BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32);
BTRFS_SETGET_FUNCS(device_start_offset, struct btrfs_dev_item,
start_offset, 64);
BTRFS_SETGET_FUNCS(device_sector_size, struct btrfs_dev_item, sector_size, 32); BTRFS_SETGET_FUNCS(device_sector_size, struct btrfs_dev_item, sector_size, 32);
BTRFS_SETGET_FUNCS(device_id, struct btrfs_dev_item, devid, 64); BTRFS_SETGET_FUNCS(device_id, struct btrfs_dev_item, devid, 64);
BTRFS_SETGET_FUNCS(device_group, struct btrfs_dev_item, dev_group, 32); BTRFS_SETGET_FUNCS(device_group, struct btrfs_dev_item, dev_group, 32);
@ -1135,6 +1158,7 @@ BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64);
/* struct btrfs_inode_item */ /* struct btrfs_inode_item */
BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64);
BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64);
BTRFS_SETGET_FUNCS(inode_transid, struct btrfs_inode_item, transid, 64); BTRFS_SETGET_FUNCS(inode_transid, struct btrfs_inode_item, transid, 64);
BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64); BTRFS_SETGET_FUNCS(inode_size, struct btrfs_inode_item, size, 64);
BTRFS_SETGET_FUNCS(inode_nbytes, struct btrfs_inode_item, nbytes, 64); BTRFS_SETGET_FUNCS(inode_nbytes, struct btrfs_inode_item, nbytes, 64);
@ -1519,6 +1543,8 @@ BTRFS_SETGET_STACK_FUNCS(super_chunk_root_level, struct btrfs_super_block,
chunk_root_level, 8); chunk_root_level, 8);
BTRFS_SETGET_STACK_FUNCS(super_log_root, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_log_root, struct btrfs_super_block,
log_root, 64); log_root, 64);
BTRFS_SETGET_STACK_FUNCS(super_log_root_transid, struct btrfs_super_block,
log_root_transid, 64);
BTRFS_SETGET_STACK_FUNCS(super_log_root_level, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_log_root_level, struct btrfs_super_block,
log_root_level, 8); log_root_level, 8);
BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_total_bytes, struct btrfs_super_block,

View File

@ -1055,6 +1055,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
BTRFS_I(inode)->sequence++;
first_index = pos >> PAGE_CACHE_SHIFT; first_index = pos >> PAGE_CACHE_SHIFT;
last_index = (pos + count) >> PAGE_CACHE_SHIFT; last_index = (pos + count) >> PAGE_CACHE_SHIFT;

View File

@ -1963,6 +1963,7 @@ void btrfs_read_locked_inode(struct inode *inode)
inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item)); inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item); BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
BTRFS_I(inode)->sequence = btrfs_inode_sequence(leaf, inode_item);
inode->i_generation = BTRFS_I(inode)->generation; inode->i_generation = BTRFS_I(inode)->generation;
inode->i_rdev = 0; inode->i_rdev = 0;
rdev = btrfs_inode_rdev(leaf, inode_item); rdev = btrfs_inode_rdev(leaf, inode_item);
@ -2043,6 +2044,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode)); btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation); btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation);
btrfs_set_inode_sequence(leaf, item, BTRFS_I(inode)->sequence);
btrfs_set_inode_transid(leaf, item, trans->transid); btrfs_set_inode_transid(leaf, item, trans->transid);
btrfs_set_inode_rdev(leaf, item, inode->i_rdev); btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
@ -2945,6 +2947,7 @@ static noinline void init_btrfs_i(struct inode *inode)
bi->i_default_acl = NULL; bi->i_default_acl = NULL;
bi->generation = 0; bi->generation = 0;
bi->sequence = 0;
bi->last_trans = 0; bi->last_trans = 0;
bi->logged_trans = 0; bi->logged_trans = 0;
bi->delalloc_bytes = 0; bi->delalloc_bytes = 0;
@ -2959,7 +2962,6 @@ static noinline void init_btrfs_i(struct inode *inode)
inode->i_mapping, GFP_NOFS); inode->i_mapping, GFP_NOFS);
INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes);
btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree);
mutex_init(&BTRFS_I(inode)->csum_mutex);
mutex_init(&BTRFS_I(inode)->extent_mutex); mutex_init(&BTRFS_I(inode)->extent_mutex);
mutex_init(&BTRFS_I(inode)->log_mutex); mutex_init(&BTRFS_I(inode)->log_mutex);
} }

View File

@ -890,6 +890,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
btrfs_set_device_group(leaf, dev_item, 0); btrfs_set_device_group(leaf, dev_item, 0);
btrfs_set_device_seek_speed(leaf, dev_item, 0); btrfs_set_device_seek_speed(leaf, dev_item, 0);
btrfs_set_device_bandwidth(leaf, dev_item, 0); btrfs_set_device_bandwidth(leaf, dev_item, 0);
btrfs_set_device_start_offset(leaf, dev_item, 0);
ptr = (unsigned long)btrfs_device_uuid(dev_item); ptr = (unsigned long)btrfs_device_uuid(dev_item);
write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE);