aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs
diff options
context:
space:
mode:
authorbharrosh@panasas.com <bharrosh@panasas.com>2010-10-07 14:28:18 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-03-15 09:02:50 -0400
commit66cd6cad4919f980dd21307d0150ff251762a264 (patch)
tree4f2d9dc0f9070ce829d03097542e7968e02df41a /fs/exofs
parent97178b7b6c84bd14660b89474d27931a1ea65c66 (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>
Diffstat (limited to 'fs/exofs')
-rw-r--r--fs/exofs/exofs.h2
-rw-r--r--fs/exofs/inode.c19
-rw-r--r--fs/exofs/super.c18
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 */
259unsigned exofs_max_io_pages(struct exofs_layout *layout,
260 unsigned expected_pages);
259int exofs_setattr(struct dentry *, struct iattr *); 261int exofs_setattr(struct dentry *, struct iattr *);
260int exofs_write_begin(struct file *file, struct address_space *mapping, 262int 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
46unsigned 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
46struct page_collect { 57struct 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
98static int pcol_try_alloc(struct page_collect *pcol) 109static 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
393static 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 */
394static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev, 411static 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;