2 * linux/fs/fat/buffer.c
8 #include <linux/malloc.h>
9 #include <linux/string.h>
11 #include <linux/msdos_fs.h>
12 #include <linux/fat_cvf.h>
15 # define PRINTK(x) printk x
20 struct buffer_head
*fat_bread(struct super_block
*sb
, int block
)
22 return MSDOS_SB(sb
)->cvf_format
->cvf_bread(sb
,block
);
24 struct buffer_head
*fat_getblk(struct super_block
*sb
, int block
)
26 return MSDOS_SB(sb
)->cvf_format
->cvf_getblk(sb
,block
);
28 void fat_brelse (struct super_block
*sb
, struct buffer_head
*bh
)
31 MSDOS_SB(sb
)->cvf_format
->cvf_brelse(sb
,bh
);
33 void fat_mark_buffer_dirty (
34 struct super_block
*sb
,
35 struct buffer_head
*bh
,
38 MSDOS_SB(sb
)->cvf_format
->cvf_mark_buffer_dirty(sb
,bh
,dirty
);
40 void fat_set_uptodate (
41 struct super_block
*sb
,
42 struct buffer_head
*bh
,
45 MSDOS_SB(sb
)->cvf_format
->cvf_set_uptodate(sb
,bh
,val
);
47 int fat_is_uptodate(struct super_block
*sb
, struct buffer_head
*bh
)
49 return MSDOS_SB(sb
)->cvf_format
->cvf_is_uptodate(sb
,bh
);
51 void fat_ll_rw_block (
52 struct super_block
*sb
,
55 struct buffer_head
*bh
[32])
57 MSDOS_SB(sb
)->cvf_format
->cvf_ll_rw_block(sb
,opr
,nbreq
,bh
);
60 struct buffer_head
*default_fat_bread(struct super_block
*sb
, int block
)
62 return bread (sb
->s_dev
,block
,512);
64 struct buffer_head
*default_fat_getblk(struct super_block
*sb
, int block
)
66 return getblk (sb
->s_dev
,block
,512);
68 void default_fat_brelse(struct super_block
*sb
, struct buffer_head
*bh
)
72 void default_fat_mark_buffer_dirty (
73 struct super_block
*sb
,
74 struct buffer_head
*bh
,
77 mark_buffer_dirty (bh
,dirty
);
79 void default_fat_set_uptodate (
80 struct super_block
*sb
,
81 struct buffer_head
*bh
,
84 mark_buffer_uptodate(bh
, val
);
86 int default_fat_is_uptodate (struct super_block
*sb
, struct buffer_head
*bh
)
88 return buffer_uptodate(bh
);
90 void default_fat_ll_rw_block (
91 struct super_block
*sb
,
94 struct buffer_head
*bh
[32])
96 ll_rw_block(opr
,nbreq
,bh
);
99 struct buffer_head
*bigblock_fat_bread (
100 struct super_block
*sb
,
103 struct buffer_head
*ret
= NULL
;
104 struct buffer_head
*real
;
105 if (sb
->s_blocksize
== 1024){
106 real
= bread (sb
->s_dev
,block
>>1,1024);
108 real
= bread (sb
->s_dev
,block
>>2,2048);
112 ret
= (struct buffer_head
*)
113 kmalloc (sizeof(struct buffer_head
), GFP_KERNEL
);
115 /* #Specification: msdos / strategy / special device / dummy blocks
116 * Many special device (Scsi optical disk for one) use
117 * larger hardware sector size. This allows for higher
120 * Most of the time, the MS-DOS filesystem that sits
121 * on this device is totally unaligned. It use logically
122 * 512 bytes sector size, with logical sector starting
123 * in the middle of a hardware block. The bad news is
124 * that a hardware sector may hold data own by two
125 * different files. This means that the hardware sector
126 * must be read, patch and written almost all the time.
128 * Needless to say that it kills write performance
131 * Internally the linux msdos fs is using 512 bytes
132 * logical sector. When accessing such a device, we
133 * allocate dummy buffer cache blocks, that we stuff
134 * with the information of a real one (1k large).
136 * This strategy is used to hide this difference to
137 * the core of the msdos fs. The slowdown is not
141 * The memset is there only to catch errors. The msdos
142 * fs is only using b_data
144 memset (ret
,0,sizeof(*ret
));
145 ret
->b_data
= real
->b_data
;
146 if (sb
->s_blocksize
== 2048) {
147 if (block
& 3) ret
->b_data
+= (block
& 3) << 9;
149 if (block
& 1) ret
->b_data
+= 512;
159 void bigblock_fat_brelse (
160 struct super_block
*sb
,
161 struct buffer_head
*bh
)
165 * We can free the dummy because a new one is allocated at
166 * each fat_getblk() and fat_bread().
171 void bigblock_fat_mark_buffer_dirty (
172 struct super_block
*sb
,
173 struct buffer_head
*bh
,
176 mark_buffer_dirty (bh
->b_next
,dirty
);
179 void bigblock_fat_set_uptodate (
180 struct super_block
*sb
,
181 struct buffer_head
*bh
,
184 mark_buffer_uptodate(bh
->b_next
, val
);
187 int bigblock_fat_is_uptodate (
188 struct super_block
*sb
,
189 struct buffer_head
*bh
)
191 return buffer_uptodate(bh
->b_next
);
194 void bigblock_fat_ll_rw_block (
195 struct super_block
*sb
,
198 struct buffer_head
*bh
[32])
200 struct buffer_head
*tmp
[32];
202 for (i
=0; i
<nbreq
; i
++)
203 tmp
[i
] = bh
[i
]->b_next
;
204 ll_rw_block(opr
,nbreq
,tmp
);