diff options
author | bharrosh@panasas.com <bharrosh@panasas.com> | 2010-10-07 14:28:18 -0400 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2011-03-15 09:02:50 -0400 |
commit | 66cd6cad4919f980dd21307d0150ff251762a264 (patch) | |
tree | 4f2d9dc0f9070ce829d03097542e7968e02df41a | |
parent | 97178b7b6c84bd14660b89474d27931a1ea65c66 (diff) |
exofs: Override read-ahead to align on stripe_size
* Set all inode->i_mapping->backing_dev_info to point to
the per super-block sb->s_bdi.
* Calculating a read_ahead that is:
- preferable 2 stripes long
(Future patch will add a mount option to override this)
- Minimum 128K aligned up to stripe-size
- Caped to maximum-IO-sizes round down to stripe_size.
(Max sizes are governed by max bio-size that fits in a page
times number-of-devices)
CC: Marc Dionne <marc.c.dionne@gmail.com>
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
-rw-r--r-- | fs/exofs/exofs.h | 2 | ||||
-rw-r--r-- | fs/exofs/inode.c | 19 | ||||
-rw-r--r-- | fs/exofs/super.c | 18 |
3 files changed, 35 insertions, 4 deletions
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 2dc925fa1010..99fcb9126a97 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -256,6 +256,8 @@ static inline int exofs_oi_read(struct exofs_i_info *oi, | |||
256 | } | 256 | } |
257 | 257 | ||
258 | /* inode.c */ | 258 | /* inode.c */ |
259 | unsigned exofs_max_io_pages(struct exofs_layout *layout, | ||
260 | unsigned expected_pages); | ||
259 | int exofs_setattr(struct dentry *, struct iattr *); | 261 | int exofs_setattr(struct dentry *, struct iattr *); |
260 | int exofs_write_begin(struct file *file, struct address_space *mapping, | 262 | int exofs_write_begin(struct file *file, struct address_space *mapping, |
261 | loff_t pos, unsigned len, unsigned flags, | 263 | loff_t pos, unsigned len, unsigned flags, |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index fb9d38056103..681b3cb9b4d8 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -43,6 +43,17 @@ enum { BIO_MAX_PAGES_KMALLOC = | |||
43 | PAGE_SIZE / sizeof(struct page *), | 43 | PAGE_SIZE / sizeof(struct page *), |
44 | }; | 44 | }; |
45 | 45 | ||
46 | unsigned exofs_max_io_pages(struct exofs_layout *layout, | ||
47 | unsigned expected_pages) | ||
48 | { | ||
49 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); | ||
50 | |||
51 | /* TODO: easily support bio chaining */ | ||
52 | pages = min_t(unsigned, pages, | ||
53 | layout->group_width * BIO_MAX_PAGES_KMALLOC); | ||
54 | return pages; | ||
55 | } | ||
56 | |||
46 | struct page_collect { | 57 | struct page_collect { |
47 | struct exofs_sb_info *sbi; | 58 | struct exofs_sb_info *sbi; |
48 | struct inode *inode; | 59 | struct inode *inode; |
@@ -97,8 +108,7 @@ static void _pcol_reset(struct page_collect *pcol) | |||
97 | 108 | ||
98 | static int pcol_try_alloc(struct page_collect *pcol) | 109 | static int pcol_try_alloc(struct page_collect *pcol) |
99 | { | 110 | { |
100 | unsigned pages = min_t(unsigned, pcol->expected_pages, | 111 | unsigned pages; |
101 | MAX_PAGES_KMALLOC); | ||
102 | 112 | ||
103 | if (!pcol->ios) { /* First time allocate io_state */ | 113 | if (!pcol->ios) { /* First time allocate io_state */ |
104 | int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); | 114 | int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); |
@@ -108,8 +118,7 @@ static int pcol_try_alloc(struct page_collect *pcol) | |||
108 | } | 118 | } |
109 | 119 | ||
110 | /* TODO: easily support bio chaining */ | 120 | /* TODO: easily support bio chaining */ |
111 | pages = min_t(unsigned, pages, | 121 | pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); |
112 | pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC); | ||
113 | 122 | ||
114 | for (; pages; pages >>= 1) { | 123 | for (; pages; pages >>= 1) { |
115 | pcol->pages = kmalloc(pages * sizeof(struct page *), | 124 | pcol->pages = kmalloc(pages * sizeof(struct page *), |
@@ -1049,6 +1058,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1049 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); | 1058 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); |
1050 | } | 1059 | } |
1051 | 1060 | ||
1061 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1052 | if (S_ISREG(inode->i_mode)) { | 1062 | if (S_ISREG(inode->i_mode)) { |
1053 | inode->i_op = &exofs_file_inode_operations; | 1063 | inode->i_op = &exofs_file_inode_operations; |
1054 | inode->i_fop = &exofs_file_operations; | 1064 | inode->i_fop = &exofs_file_operations; |
@@ -1149,6 +1159,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1149 | 1159 | ||
1150 | sbi = sb->s_fs_info; | 1160 | sbi = sb->s_fs_info; |
1151 | 1161 | ||
1162 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1152 | sb->s_dirt = 1; | 1163 | sb->s_dirt = 1; |
1153 | inode_init_owner(inode, dir, mode); | 1164 | inode_init_owner(inode, dir, mode); |
1154 | inode->i_ino = sbi->s_nextid++; | 1165 | inode->i_ino = sbi->s_nextid++; |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 78f5ad633d3b..e87510f4749e 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -390,6 +390,23 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, | |||
390 | return 0; | 390 | return 0; |
391 | } | 391 | } |
392 | 392 | ||
393 | static unsigned __ra_pages(struct exofs_layout *layout) | ||
394 | { | ||
395 | const unsigned _MIN_RA = 32; /* min 128K read-ahead */ | ||
396 | unsigned ra_pages = layout->group_width * layout->stripe_unit / | ||
397 | PAGE_SIZE; | ||
398 | unsigned max_io_pages = exofs_max_io_pages(layout, ~0); | ||
399 | |||
400 | ra_pages *= 2; /* two stripes */ | ||
401 | if (ra_pages < _MIN_RA) | ||
402 | ra_pages = roundup(_MIN_RA, ra_pages / 2); | ||
403 | |||
404 | if (ra_pages > max_io_pages) | ||
405 | ra_pages = max_io_pages; | ||
406 | |||
407 | return ra_pages; | ||
408 | } | ||
409 | |||
393 | /* @odi is valid only as long as @fscb_dev is valid */ | 410 | /* @odi is valid only as long as @fscb_dev is valid */ |
394 | static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev, | 411 | static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev, |
395 | struct osd_dev_info *odi) | 412 | struct osd_dev_info *odi) |
@@ -623,6 +640,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
623 | } | 640 | } |
624 | 641 | ||
625 | /* set up operation vectors */ | 642 | /* set up operation vectors */ |
643 | sbi->bdi.ra_pages = __ra_pages(&sbi->layout); | ||
626 | sb->s_bdi = &sbi->bdi; | 644 | sb->s_bdi = &sbi->bdi; |
627 | sb->s_fs_info = sbi; | 645 | sb->s_fs_info = sbi; |
628 | sb->s_op = &exofs_sops; | 646 | sb->s_op = &exofs_sops; |