diff options
-rw-r--r-- | fs/btrfs/ctree.h | 28 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 21 |
2 files changed, 42 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 166896dd44c2..b5af1fc77c5d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -305,6 +305,9 @@ struct btrfs_super_block { | |||
305 | __le32 stripesize; | 305 | __le32 stripesize; |
306 | __le32 sys_chunk_array_size; | 306 | __le32 sys_chunk_array_size; |
307 | __le64 chunk_root_generation; | 307 | __le64 chunk_root_generation; |
308 | __le64 compat_flags; | ||
309 | __le64 compat_ro_flags; | ||
310 | __le64 incompat_flags; | ||
308 | u8 root_level; | 311 | u8 root_level; |
309 | u8 chunk_root_level; | 312 | u8 chunk_root_level; |
310 | u8 log_root_level; | 313 | u8 log_root_level; |
@@ -314,6 +317,14 @@ struct btrfs_super_block { | |||
314 | } __attribute__ ((__packed__)); | 317 | } __attribute__ ((__packed__)); |
315 | 318 | ||
316 | /* | 319 | /* |
320 | * Compat flags that we support. If any incompat flags are set other than the | ||
321 | * ones specified below then we will fail to mount | ||
322 | */ | ||
323 | #define BTRFS_FEATURE_COMPAT_SUPP 0x0 | ||
324 | #define BTRFS_FEATURE_COMPAT_RO_SUPP 0x0 | ||
325 | #define BTRFS_FEATURE_INCOMPAT_SUPP 0x0 | ||
326 | |||
327 | /* | ||
317 | * A leaf is full of items. offset and size tell us where to find | 328 | * A leaf is full of items. offset and size tell us where to find |
318 | * the item in the leaf (relative to the start of the data area) | 329 | * the item in the leaf (relative to the start of the data area) |
319 | */ | 330 | */ |
@@ -433,8 +444,7 @@ struct btrfs_inode_item { | |||
433 | __le32 gid; | 444 | __le32 gid; |
434 | __le32 mode; | 445 | __le32 mode; |
435 | __le64 rdev; | 446 | __le64 rdev; |
436 | __le16 flags; | 447 | __le64 flags; |
437 | __le16 compat_flags; | ||
438 | 448 | ||
439 | struct btrfs_timespec atime; | 449 | struct btrfs_timespec atime; |
440 | struct btrfs_timespec ctime; | 450 | struct btrfs_timespec ctime; |
@@ -462,7 +472,7 @@ struct btrfs_root_item { | |||
462 | __le64 byte_limit; | 472 | __le64 byte_limit; |
463 | __le64 bytes_used; | 473 | __le64 bytes_used; |
464 | __le64 last_snapshot; | 474 | __le64 last_snapshot; |
465 | __le32 flags; | 475 | __le64 flags; |
466 | __le32 refs; | 476 | __le32 refs; |
467 | struct btrfs_disk_key drop_progress; | 477 | struct btrfs_disk_key drop_progress; |
468 | u8 drop_level; | 478 | u8 drop_level; |
@@ -1116,9 +1126,7 @@ BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32); | |||
1116 | BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32); | 1126 | BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32); |
1117 | BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32); | 1127 | BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32); |
1118 | BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64); | 1128 | BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64); |
1119 | BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 16); | 1129 | BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64); |
1120 | BTRFS_SETGET_FUNCS(inode_compat_flags, struct btrfs_inode_item, | ||
1121 | compat_flags, 16); | ||
1122 | 1130 | ||
1123 | static inline struct btrfs_timespec * | 1131 | static inline struct btrfs_timespec * |
1124 | btrfs_inode_atime(struct btrfs_inode_item *inode_item) | 1132 | btrfs_inode_atime(struct btrfs_inode_item *inode_item) |
@@ -1468,7 +1476,7 @@ BTRFS_SETGET_STACK_FUNCS(root_bytenr, struct btrfs_root_item, bytenr, 64); | |||
1468 | BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); | 1476 | BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); |
1469 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); | 1477 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); |
1470 | BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); | 1478 | BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32); |
1471 | BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32); | 1479 | BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 64); |
1472 | BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); | 1480 | BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); |
1473 | BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); | 1481 | BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); |
1474 | BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, | 1482 | BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, |
@@ -1510,6 +1518,12 @@ BTRFS_SETGET_STACK_FUNCS(super_root_dir, struct btrfs_super_block, | |||
1510 | root_dir_objectid, 64); | 1518 | root_dir_objectid, 64); |
1511 | BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block, | 1519 | BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block, |
1512 | num_devices, 64); | 1520 | num_devices, 64); |
1521 | BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block, | ||
1522 | compat_flags, 64); | ||
1523 | BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block, | ||
1524 | compat_flags, 64); | ||
1525 | BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, | ||
1526 | incompat_flags, 64); | ||
1513 | 1527 | ||
1514 | static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) | 1528 | static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) |
1515 | { | 1529 | { |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2464c099db57..6ae9bdf98b68 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1434,6 +1434,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1434 | u32 blocksize; | 1434 | u32 blocksize; |
1435 | u32 stripesize; | 1435 | u32 stripesize; |
1436 | u64 generation; | 1436 | u64 generation; |
1437 | u64 features; | ||
1437 | struct btrfs_key location; | 1438 | struct btrfs_key location; |
1438 | struct buffer_head *bh; | 1439 | struct buffer_head *bh; |
1439 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), | 1440 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), |
@@ -1586,6 +1587,26 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1586 | goto fail_sb_buffer; | 1587 | goto fail_sb_buffer; |
1587 | } | 1588 | } |
1588 | 1589 | ||
1590 | features = btrfs_super_incompat_flags(disk_super) & | ||
1591 | ~BTRFS_FEATURE_INCOMPAT_SUPP; | ||
1592 | if (features) { | ||
1593 | printk(KERN_ERR "BTRFS: couldn't mount because of " | ||
1594 | "unsupported optional features (%Lx).\n", | ||
1595 | features); | ||
1596 | err = -EINVAL; | ||
1597 | goto fail_sb_buffer; | ||
1598 | } | ||
1599 | |||
1600 | features = btrfs_super_compat_ro_flags(disk_super) & | ||
1601 | ~BTRFS_FEATURE_COMPAT_RO_SUPP; | ||
1602 | if (!(sb->s_flags & MS_RDONLY) && features) { | ||
1603 | printk(KERN_ERR "BTRFS: couldn't mount RDWR because of " | ||
1604 | "unsupported option features (%Lx).\n", | ||
1605 | features); | ||
1606 | err = -EINVAL; | ||
1607 | goto fail_sb_buffer; | ||
1608 | } | ||
1609 | |||
1589 | /* | 1610 | /* |
1590 | * we need to start all the end_io workers up front because the | 1611 | * we need to start all the end_io workers up front because the |
1591 | * queue work function gets called at interrupt time, and so it | 1612 | * queue work function gets called at interrupt time, and so it |