Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'hpfs' from Mikulas Patocka

Merge hpfs patches from Mikulas Patocka.

* emailed patches from Mikulas Patocka <mpatocka@artax.karlin.mff.cuni.cz>:
hpfs: implement prefetch to improve performance
hpfs: use mpage
hpfs: better test for errors

+109 -16
+33
fs/hpfs/buffer.c
··· 7 7 */ 8 8 #include <linux/sched.h> 9 9 #include <linux/slab.h> 10 + #include <linux/blkdev.h> 10 11 #include "hpfs_fn.h" 12 + 13 + void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n) 14 + { 15 + struct buffer_head *bh; 16 + struct blk_plug plug; 17 + 18 + if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size)) 19 + return; 20 + 21 + bh = sb_find_get_block(s, secno); 22 + if (bh) { 23 + if (buffer_uptodate(bh)) { 24 + brelse(bh); 25 + return; 26 + } 27 + brelse(bh); 28 + }; 29 + 30 + blk_start_plug(&plug); 31 + while (n > 0) { 32 + if (unlikely(secno >= hpfs_sb(s)->sb_fs_size)) 33 + break; 34 + sb_breadahead(s, secno); 35 + secno++; 36 + n--; 37 + } 38 + blk_finish_plug(&plug); 39 + } 11 40 12 41 /* Map a sector into a buffer and return pointers to it and to the buffer. */ 13 42 ··· 46 17 struct buffer_head *bh; 47 18 48 19 hpfs_lock_assert(s); 20 + 21 + hpfs_prefetch_sectors(s, secno, ahead); 49 22 50 23 cond_resched(); 51 24 ··· 97 66 printk("HPFS: hpfs_map_4sectors: unaligned read\n"); 98 67 return NULL; 99 68 } 69 + 70 + hpfs_prefetch_sectors(s, secno, 4 + ahead); 100 71 101 72 qbh->data = data = kmalloc(2048, GFP_NOFS); 102 73 if (!data) {
+37 -9
fs/hpfs/file.c
··· 7 7 */ 8 8 9 9 #include "hpfs_fn.h" 10 + #include <linux/mpage.h> 10 11 11 12 #define BLOCKS(size) (((size) + 511) >> 9) 12 13 ··· 35 34 * so we must ignore such errors. 36 35 */ 37 36 38 - static secno hpfs_bmap(struct inode *inode, unsigned file_secno) 37 + static secno hpfs_bmap(struct inode *inode, unsigned file_secno, unsigned *n_secs) 39 38 { 40 39 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); 41 40 unsigned n, disk_secno; ··· 43 42 struct buffer_head *bh; 44 43 if (BLOCKS(hpfs_i(inode)->mmu_private) <= file_secno) return 0; 45 44 n = file_secno - hpfs_inode->i_file_sec; 46 - if (n < hpfs_inode->i_n_secs) return hpfs_inode->i_disk_sec + n; 45 + if (n < hpfs_inode->i_n_secs) { 46 + *n_secs = hpfs_inode->i_n_secs - n; 47 + return hpfs_inode->i_disk_sec + n; 48 + } 47 49 if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0; 48 50 disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh); 49 51 if (disk_secno == -1) return 0; 50 52 if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0; 53 + n = file_secno - hpfs_inode->i_file_sec; 54 + if (n < hpfs_inode->i_n_secs) { 55 + *n_secs = hpfs_inode->i_n_secs - n; 56 + return hpfs_inode->i_disk_sec + n; 57 + } 58 + *n_secs = 1; 51 59 return disk_secno; 52 60 } 53 61 ··· 77 67 { 78 68 int r; 79 69 secno s; 70 + unsigned n_secs; 80 71 hpfs_lock(inode->i_sb); 81 - s = hpfs_bmap(inode, iblock); 72 + s = hpfs_bmap(inode, iblock, &n_secs); 82 73 if (s) { 74 + if (bh_result->b_size >> 9 < n_secs) 75 + n_secs = bh_result->b_size >> 9; 83 76 map_bh(bh_result, inode->i_sb, s); 77 + bh_result->b_size = n_secs << 9; 84 78 goto ret_0; 85 79 } 86 80 if (!create) goto ret_0; ··· 109 95 return r; 110 96 } 111 97 112 - static int hpfs_writepage(struct page *page, struct writeback_control *wbc) 113 - { 114 - return block_write_full_page(page,hpfs_get_block, wbc); 115 - } 116 - 117 98 static int hpfs_readpage(struct file *file, struct page *page) 118 99 { 119 - return block_read_full_page(page,hpfs_get_block); 100 + return mpage_readpage(page, hpfs_get_block); 101 + } 102 + 103 + static int hpfs_writepage(struct page *page, struct writeback_control *wbc) 104 + { 105 + return block_write_full_page(page, hpfs_get_block, wbc); 106 + } 107 + 108 + static int hpfs_readpages(struct file *file, struct address_space *mapping, 109 + struct list_head *pages, unsigned nr_pages) 110 + { 111 + return mpage_readpages(mapping, pages, nr_pages, hpfs_get_block); 112 + } 113 + 114 + static int hpfs_writepages(struct address_space *mapping, 115 + struct writeback_control *wbc) 116 + { 117 + return mpage_writepages(mapping, wbc, hpfs_get_block); 120 118 } 121 119 122 120 static void hpfs_write_failed(struct address_space *mapping, loff_t to) ··· 187 161 const struct address_space_operations hpfs_aops = { 188 162 .readpage = hpfs_readpage, 189 163 .writepage = hpfs_writepage, 164 + .readpages = hpfs_readpages, 165 + .writepages = hpfs_writepages, 190 166 .write_begin = hpfs_write_begin, 191 167 .write_end = hpfs_write_end, 192 168 .bmap = _hpfs_bmap
+5 -2
fs/hpfs/hpfs_fn.h
··· 27 27 #define ALLOC_FWD_MAX 128 28 28 #define ALLOC_M 1 29 29 #define FNODE_RD_AHEAD 16 30 - #define ANODE_RD_AHEAD 16 31 - #define DNODE_RD_AHEAD 4 30 + #define ANODE_RD_AHEAD 0 31 + #define DNODE_RD_AHEAD 72 32 + #define COUNT_RD_AHEAD 62 32 33 33 34 #define FREE_DNODES_ADD 58 34 35 #define FREE_DNODES_DEL 29 ··· 208 207 209 208 /* buffer.c */ 210 209 210 + void hpfs_prefetch_sectors(struct super_block *, unsigned, int); 211 211 void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int); 212 212 void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **); 213 213 void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int); ··· 273 271 274 272 __le32 *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *); 275 273 __le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *); 274 + void hpfs_prefetch_bitmap(struct super_block *, unsigned); 276 275 unsigned char *hpfs_load_code_page(struct super_block *, secno); 277 276 __le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp); 278 277 struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **);
+20 -2
fs/hpfs/map.c
··· 17 17 struct quad_buffer_head *qbh, char *id) 18 18 { 19 19 secno sec; 20 - if (hpfs_sb(s)->sb_chk) if (bmp_block * 16384 > hpfs_sb(s)->sb_fs_size) { 20 + __le32 *ret; 21 + unsigned n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; 22 + if (hpfs_sb(s)->sb_chk) if (bmp_block >= n_bands) { 21 23 hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id); 22 24 return NULL; 23 25 } ··· 28 26 hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id); 29 27 return NULL; 30 28 } 31 - return hpfs_map_4sectors(s, sec, qbh, 4); 29 + ret = hpfs_map_4sectors(s, sec, qbh, 4); 30 + if (ret) hpfs_prefetch_bitmap(s, bmp_block + 1); 31 + return ret; 32 + } 33 + 34 + void hpfs_prefetch_bitmap(struct super_block *s, unsigned bmp_block) 35 + { 36 + unsigned to_prefetch, next_prefetch; 37 + unsigned n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; 38 + if (unlikely(bmp_block >= n_bands)) 39 + return; 40 + to_prefetch = le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[bmp_block]); 41 + if (unlikely(bmp_block + 1 >= n_bands)) 42 + next_prefetch = 0; 43 + else 44 + next_prefetch = le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[bmp_block + 1]); 45 + hpfs_prefetch_sectors(s, to_prefetch, 4 + 4 * (to_prefetch + 4 == next_prefetch)); 32 46 } 33 47 34 48 /*
+14 -3
fs/hpfs/super.c
··· 121 121 unsigned long *bits; 122 122 unsigned count; 123 123 124 - bits = hpfs_map_4sectors(s, secno, &qbh, 4); 124 + bits = hpfs_map_4sectors(s, secno, &qbh, 0); 125 125 if (!bits) 126 126 return 0; 127 127 count = bitmap_weight(bits, 2048 * BITS_PER_BYTE); ··· 134 134 unsigned n, count, n_bands; 135 135 n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14; 136 136 count = 0; 137 - for (n = 0; n < n_bands; n++) 137 + for (n = 0; n < COUNT_RD_AHEAD; n++) { 138 + hpfs_prefetch_bitmap(s, n); 139 + } 140 + for (n = 0; n < n_bands; n++) { 141 + hpfs_prefetch_bitmap(s, n + COUNT_RD_AHEAD); 138 142 count += hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n])); 143 + } 139 144 return count; 140 145 } 141 146 ··· 563 558 sbi->sb_cp_table = NULL; 564 559 sbi->sb_c_bitmap = -1; 565 560 sbi->sb_max_fwd_alloc = 0xffffff; 566 - 561 + 562 + if (sbi->sb_fs_size >= 0x80000000) { 563 + hpfs_error(s, "invalid size in superblock: %08x", 564 + (unsigned)sbi->sb_fs_size); 565 + goto bail4; 566 + } 567 + 567 568 /* Load bitmap directory */ 568 569 if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, le32_to_cpu(superblock->bitmaps)))) 569 570 goto bail4;