Btrfs: Fix uninitialized root flags for subvolumes
root_item->flags and root_item->byte_limit are not initialized when a subvolume is created. This bug is not revealed until we added readonly snapshot support - now you mount a btrfs filesystem and you may find the subvolumes in it are readonly. To work around this problem, we steal a bit from root_item->inode_item->flags, and use it to indicate if those fields have been properly initialized. When we read a tree root from disk, we check if the bit is set, and if not we'll set the flag and initialize the two fields of the root item. Reported-by: Andreas Philipp <philipp.andreas@gmail.com> Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Tested-by: Andreas Philipp <philipp.andreas@gmail.com> cc: stable@kernel.org Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
@@ -1284,6 +1284,8 @@ struct btrfs_root {
|
||||
#define BTRFS_INODE_DIRSYNC (1 << 10)
|
||||
#define BTRFS_INODE_COMPRESS (1 << 11)
|
||||
|
||||
#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31)
|
||||
|
||||
/* some macros to generate set/get funcs for the struct fields. This
|
||||
* assumes there is a lefoo_to_cpu for every type, so lets make a simple
|
||||
* one for u8:
|
||||
@@ -2359,6 +2361,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid);
|
||||
int btrfs_find_orphan_roots(struct btrfs_root *tree_root);
|
||||
int btrfs_set_root_node(struct btrfs_root_item *item,
|
||||
struct extent_buffer *node);
|
||||
void btrfs_check_and_init_root_item(struct btrfs_root_item *item);
|
||||
|
||||
/* dir-item.c */
|
||||
int btrfs_insert_dir_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, const char *name,
|
||||
|
||||
Reference in New Issue
Block a user