~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/fat/buffer.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/fs/fat/buffer.c
  3  *
  4  *
  5  */
  6 
  7 #include <linux/mm.h>
  8 #include <linux/malloc.h>
  9 #include <linux/string.h>
 10 #include <linux/fs.h>
 11 #include <linux/msdos_fs.h>
 12 #include <linux/fat_cvf.h>
 13 
 14 #if 0
 15 #  define PRINTK(x) printk x
 16 #else
 17 #  define PRINTK(x)
 18 #endif
 19 
 20 struct buffer_head *fat_bread(struct super_block *sb, int block)
 21 {
 22         return MSDOS_SB(sb)->cvf_format->cvf_bread(sb,block);
 23 }
 24 struct buffer_head *fat_getblk(struct super_block *sb, int block)
 25 {
 26         return MSDOS_SB(sb)->cvf_format->cvf_getblk(sb,block);
 27 }
 28 void fat_brelse (struct super_block *sb, struct buffer_head *bh)
 29 {
 30         if (bh) 
 31                 MSDOS_SB(sb)->cvf_format->cvf_brelse(sb,bh);
 32 }
 33 void fat_mark_buffer_dirty (
 34         struct super_block *sb,
 35         struct buffer_head *bh)
 36 {
 37         MSDOS_SB(sb)->cvf_format->cvf_mark_buffer_dirty(sb,bh);
 38 }
 39 void fat_set_uptodate (
 40         struct super_block *sb,
 41         struct buffer_head *bh,
 42         int val)
 43 {
 44         MSDOS_SB(sb)->cvf_format->cvf_set_uptodate(sb,bh,val);
 45 }
 46 int fat_is_uptodate(struct super_block *sb, struct buffer_head *bh)
 47 {
 48         return MSDOS_SB(sb)->cvf_format->cvf_is_uptodate(sb,bh);
 49 }
 50 void fat_ll_rw_block (
 51         struct super_block *sb,
 52         int opr,
 53         int nbreq,
 54         struct buffer_head *bh[32])
 55 {
 56         MSDOS_SB(sb)->cvf_format->cvf_ll_rw_block(sb,opr,nbreq,bh);
 57 }
 58 
 59 struct buffer_head *default_fat_bread(struct super_block *sb, int block)
 60 {
 61         return bread (sb->s_dev,block,512);
 62 }
 63 struct buffer_head *default_fat_getblk(struct super_block *sb, int block)
 64 {
 65         return getblk (sb->s_dev,block,512);
 66 }
 67 void default_fat_brelse(struct super_block *sb, struct buffer_head *bh)
 68 {
 69         brelse (bh);
 70 }
 71 void default_fat_mark_buffer_dirty (
 72         struct super_block *sb,
 73         struct buffer_head *bh)
 74 {
 75         mark_buffer_dirty (bh);
 76 }
 77 void default_fat_set_uptodate (
 78         struct super_block *sb,
 79         struct buffer_head *bh,
 80         int val)
 81 {
 82         mark_buffer_uptodate(bh, val);
 83 }
 84 int default_fat_is_uptodate (struct super_block *sb, struct buffer_head *bh)
 85 {
 86         return buffer_uptodate(bh);
 87 }
 88 void default_fat_ll_rw_block (
 89         struct super_block *sb,
 90         int opr,
 91         int nbreq,
 92         struct buffer_head *bh[32])
 93 {
 94         ll_rw_block(opr,nbreq,bh);
 95 }
 96 
 97 struct buffer_head *bigblock_fat_bread (
 98         struct super_block *sb,
 99         int block)
100 {
101         struct buffer_head *ret = NULL;
102         struct buffer_head *real;
103         if (sb->s_blocksize == 1024){
104                 real = bread (sb->s_dev,block>>1,1024);
105         } else {
106                 real = bread (sb->s_dev,block>>2,2048);
107         }
108 
109         if (real != NULL) {
110                 ret = (struct buffer_head *)
111                         kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
112                 if (ret != NULL) {
113                         /* #Specification: msdos / strategy / special device / dummy blocks
114                          * Many special device (Scsi optical disk for one) use
115                          * larger hardware sector size. This allows for higher
116                          * capacity.
117 
118                          * Most of the time, the MS-DOS filesystem that sits
119                          * on this device is totally unaligned. It use logically
120                          * 512 bytes sector size, with logical sector starting
121                          * in the middle of a hardware block. The bad news is
122                          * that a hardware sector may hold data own by two
123                          * different files. This means that the hardware sector
124                          * must be read, patch and written almost all the time.
125 
126                          * Needless to say that it kills write performance
127                          * on all OS.
128 
129                          * Internally the linux msdos fs is using 512 bytes
130                          * logical sector. When accessing such a device, we
131                          * allocate dummy buffer cache blocks, that we stuff
132                          * with the information of a real one (1k large).
133 
134                          * This strategy is used to hide this difference to
135                          * the core of the msdos fs. The slowdown is not
136                          * hidden though!
137                          */
138                         /*
139                          * The memset is there only to catch errors. The msdos
140                          * fs is only using b_data
141                          */
142                         memset (ret,0,sizeof(*ret));
143                         ret->b_data = real->b_data;
144                         if (sb->s_blocksize == 2048) {
145                                 if (block & 3) ret->b_data += (block & 3) << 9;
146                         }else{
147                                 if (block & 1) ret->b_data += 512;
148                         }
149                         ret->b_next = real;
150                 }else{
151                         brelse (real);
152                 }
153         }
154         return ret;
155 }
156 
157 void bigblock_fat_brelse (
158         struct super_block *sb,
159         struct buffer_head *bh)
160 {
161         brelse (bh->b_next);
162         /*
163          * We can free the dummy because a new one is allocated at
164          * each fat_getblk() and fat_bread().
165          */
166         kfree (bh);
167 }
168 
169 void bigblock_fat_mark_buffer_dirty (
170         struct super_block *sb,
171         struct buffer_head *bh)
172 {
173         mark_buffer_dirty (bh->b_next);
174 }
175 
176 void bigblock_fat_set_uptodate (
177         struct super_block *sb,
178         struct buffer_head *bh,
179         int val)
180 {
181         mark_buffer_uptodate(bh->b_next, val);
182 }
183 
184 int bigblock_fat_is_uptodate (
185         struct super_block *sb,
186         struct buffer_head *bh)
187 {
188         return buffer_uptodate(bh->b_next);
189 }
190 
191 void bigblock_fat_ll_rw_block (
192         struct super_block *sb,
193         int opr,
194         int nbreq,
195         struct buffer_head *bh[32])
196 {
197         struct buffer_head *tmp[32];
198         int i;
199         for (i=0; i<nbreq; i++)
200                 tmp[i] = bh[i]->b_next;
201         ll_rw_block(opr,nbreq,tmp);
202 }
203 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.