Skip to content

Commit 0af3d00

Browse files
author
Josef Bacik
committed
Btrfs: create special free space cache inode
In order to save free space cache, we need an inode to hold the data, and we need a special item to point at the right inode for the right block group. So first, create a special item that will point to the right inode, and the number of extent entries we will have and the number of bitmaps we will have. We truncate and pre-allocate space everytime to make sure it's uptodate. This feature will be turned on as soon as you mount with -o space_cache, however it is safe to boot into old kernels, they will just generate the cache the old fashion way. When you boot back into a newer kernel we will notice that we modified and not the cache and automatically discard the cache. Signed-off-by: Josef Bacik <josef@redhat.com>
1 parent f6f94e2 commit 0af3d00

File tree

10 files changed

+668
-46
lines changed

10 files changed

+668
-46
lines changed

fs/btrfs/ctree.h

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ struct btrfs_ordered_sum;
9999
*/
100100
#define BTRFS_EXTENT_CSUM_OBJECTID -10ULL
101101

102+
/* For storing free space cache */
103+
#define BTRFS_FREE_SPACE_OBJECTID -11ULL
104+
102105
/* dummy objectid represents multiple objectids */
103106
#define BTRFS_MULTIPLE_OBJECTIDS -255ULL
104107

@@ -265,6 +268,22 @@ struct btrfs_chunk {
265268
/* additional stripes go here */
266269
} __attribute__ ((__packed__));
267270

271+
#define BTRFS_FREE_SPACE_EXTENT 1
272+
#define BTRFS_FREE_SPACE_BITMAP 2
273+
274+
struct btrfs_free_space_entry {
275+
__le64 offset;
276+
__le64 bytes;
277+
u8 type;
278+
} __attribute__ ((__packed__));
279+
280+
struct btrfs_free_space_header {
281+
struct btrfs_disk_key location;
282+
__le64 generation;
283+
__le64 num_entries;
284+
__le64 num_bitmaps;
285+
} __attribute__ ((__packed__));
286+
268287
static inline unsigned long btrfs_chunk_item_size(int num_stripes)
269288
{
270289
BUG_ON(num_stripes == 0);
@@ -365,8 +384,10 @@ struct btrfs_super_block {
365384

366385
char label[BTRFS_LABEL_SIZE];
367386

387+
__le64 cache_generation;
388+
368389
/* future expansion */
369-
__le64 reserved[32];
390+
__le64 reserved[31];
370391
u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
371392
} __attribute__ ((__packed__));
372393

@@ -375,12 +396,12 @@ struct btrfs_super_block {
375396
* ones specified below then we will fail to mount
376397
*/
377398
#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
378-
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0)
399+
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
379400

380401
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
381402
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
382-
#define BTRFS_FEATURE_INCOMPAT_SUPP \
383-
(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
403+
#define BTRFS_FEATURE_INCOMPAT_SUPP \
404+
(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
384405
BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
385406

386407
/*
@@ -750,6 +771,14 @@ enum btrfs_caching_type {
750771
BTRFS_CACHE_FINISHED = 2,
751772
};
752773

774+
enum btrfs_disk_cache_state {
775+
BTRFS_DC_WRITTEN = 0,
776+
BTRFS_DC_ERROR = 1,
777+
BTRFS_DC_CLEAR = 2,
778+
BTRFS_DC_SETUP = 3,
779+
BTRFS_DC_NEED_WRITE = 4,
780+
};
781+
753782
struct btrfs_caching_control {
754783
struct list_head list;
755784
struct mutex mutex;
@@ -763,6 +792,7 @@ struct btrfs_block_group_cache {
763792
struct btrfs_key key;
764793
struct btrfs_block_group_item item;
765794
struct btrfs_fs_info *fs_info;
795+
struct inode *inode;
766796
spinlock_t lock;
767797
u64 pinned;
768798
u64 reserved;
@@ -773,8 +803,11 @@ struct btrfs_block_group_cache {
773803
int extents_thresh;
774804
int free_extents;
775805
int total_bitmaps;
776-
int ro;
777-
int dirty;
806+
int ro:1;
807+
int dirty:1;
808+
int iref:1;
809+
810+
int disk_cache_state;
778811

779812
/* cache tracking stuff */
780813
int cached;
@@ -1192,6 +1225,7 @@ struct btrfs_root {
11921225
#define BTRFS_MOUNT_NOSSD (1 << 9)
11931226
#define BTRFS_MOUNT_DISCARD (1 << 10)
11941227
#define BTRFS_MOUNT_FORCE_COMPRESS (1 << 11)
1228+
#define BTRFS_MOUNT_SPACE_CACHE (1 << 12)
11951229

11961230
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
11971231
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -1665,6 +1699,27 @@ static inline void btrfs_set_dir_item_key(struct extent_buffer *eb,
16651699
write_eb_member(eb, item, struct btrfs_dir_item, location, key);
16661700
}
16671701

1702+
BTRFS_SETGET_FUNCS(free_space_entries, struct btrfs_free_space_header,
1703+
num_entries, 64);
1704+
BTRFS_SETGET_FUNCS(free_space_bitmaps, struct btrfs_free_space_header,
1705+
num_bitmaps, 64);
1706+
BTRFS_SETGET_FUNCS(free_space_generation, struct btrfs_free_space_header,
1707+
generation, 64);
1708+
1709+
static inline void btrfs_free_space_key(struct extent_buffer *eb,
1710+
struct btrfs_free_space_header *h,
1711+
struct btrfs_disk_key *key)
1712+
{
1713+
read_eb_member(eb, h, struct btrfs_free_space_header, location, key);
1714+
}
1715+
1716+
static inline void btrfs_set_free_space_key(struct extent_buffer *eb,
1717+
struct btrfs_free_space_header *h,
1718+
struct btrfs_disk_key *key)
1719+
{
1720+
write_eb_member(eb, h, struct btrfs_free_space_header, location, key);
1721+
}
1722+
16681723
/* struct btrfs_disk_key */
16691724
BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
16701725
objectid, 64);
@@ -1876,6 +1931,8 @@ BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
18761931
incompat_flags, 64);
18771932
BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
18781933
csum_type, 16);
1934+
BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
1935+
cache_generation, 64);
18791936

18801937
static inline int btrfs_super_csum_size(struct btrfs_super_block *s)
18811938
{
@@ -2115,6 +2172,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
21152172
struct btrfs_block_group_cache *cache);
21162173
int btrfs_set_block_group_rw(struct btrfs_root *root,
21172174
struct btrfs_block_group_cache *cache);
2175+
void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
21182176
/* ctree.c */
21192177
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
21202178
int level, int *slot);
@@ -2426,6 +2484,10 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root);
24262484
int btrfs_prealloc_file_range(struct inode *inode, int mode,
24272485
u64 start, u64 num_bytes, u64 min_size,
24282486
loff_t actual_len, u64 *alloc_hint);
2487+
int btrfs_prealloc_file_range_trans(struct inode *inode,
2488+
struct btrfs_trans_handle *trans, int mode,
2489+
u64 start, u64 num_bytes, u64 min_size,
2490+
loff_t actual_len, u64 *alloc_hint);
24292491
extern const struct dentry_operations btrfs_dentry_operations;
24302492

24312493
/* ioctl.c */

fs/btrfs/disk-io.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1685,7 +1685,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
16851685
__setup_root(4096, 4096, 4096, 4096, tree_root,
16861686
fs_info, BTRFS_ROOT_TREE_OBJECTID);
16871687

1688-
16891688
bh = btrfs_read_dev_super(fs_devices->latest_bdev);
16901689
if (!bh)
16911690
goto fail_iput;
@@ -1993,6 +1992,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
19931992
if (!(sb->s_flags & MS_RDONLY)) {
19941993
down_read(&fs_info->cleanup_work_sem);
19951994
btrfs_orphan_cleanup(fs_info->fs_root);
1995+
btrfs_orphan_cleanup(fs_info->tree_root);
19961996
up_read(&fs_info->cleanup_work_sem);
19971997
}
19981998

@@ -2421,6 +2421,7 @@ int close_ctree(struct btrfs_root *root)
24212421
fs_info->closing = 1;
24222422
smp_mb();
24232423

2424+
btrfs_put_block_group_cache(fs_info);
24242425
if (!(fs_info->sb->s_flags & MS_RDONLY)) {
24252426
ret = btrfs_commit_super(root);
24262427
if (ret)

0 commit comments

Comments
 (0)