patch-2.4.5 linux/fs/fat/buffer.c
Next file: linux/fs/fat/cache.c
Previous file: linux/fs/ext2/super.c
Back to the patch index
Back to the overall index
- Lines: 194
- Date:
Thu May 24 15:36:33 2001
- Orig file:
v2.4.4/linux/fs/fat/buffer.c
- Orig date:
Fri Feb 9 11:29:44 2001
diff -u --recursive --new-file v2.4.4/linux/fs/fat/buffer.c linux/fs/fat/buffer.c
@@ -8,6 +8,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/blkdev.h>
#include <linux/msdos_fs.h>
#include <linux/fat_cvf.h>
@@ -58,22 +59,26 @@
struct buffer_head *default_fat_bread(struct super_block *sb, int block)
{
- return bread (sb->s_dev,block,512);
+ return bread (sb->s_dev, block, sb->s_blocksize);
}
+
struct buffer_head *default_fat_getblk(struct super_block *sb, int block)
{
- return getblk (sb->s_dev,block,512);
+ return getblk (sb->s_dev, block, sb->s_blocksize);
}
+
void default_fat_brelse(struct super_block *sb, struct buffer_head *bh)
{
brelse (bh);
}
+
void default_fat_mark_buffer_dirty (
struct super_block *sb,
struct buffer_head *bh)
{
mark_buffer_dirty (bh);
}
+
void default_fat_set_uptodate (
struct super_block *sb,
struct buffer_head *bh,
@@ -81,10 +86,12 @@
{
mark_buffer_uptodate(bh, val);
}
+
int default_fat_is_uptodate (struct super_block *sb, struct buffer_head *bh)
{
return buffer_uptodate(bh);
}
+
void default_fat_ll_rw_block (
struct super_block *sb,
int opr,
@@ -94,109 +101,61 @@
ll_rw_block(opr,nbreq,bh);
}
-struct buffer_head *bigblock_fat_bread (
- struct super_block *sb,
- int block)
+struct buffer_head *bigblock_fat_bread(struct super_block *sb, int block)
{
- struct buffer_head *ret = NULL;
- struct buffer_head *real;
- if (sb->s_blocksize == 1024){
- real = bread (sb->s_dev,block>>1,1024);
- } else {
- real = bread (sb->s_dev,block>>2,2048);
- }
-
+ unsigned int hardsect = get_hardsect_size(sb->s_dev);
+ int rblock, roffset;
+ struct buffer_head *real, *dummy;
+
+ if (hardsect <= sb->s_blocksize)
+ BUG();
+
+ dummy = NULL;
+ rblock = block / (hardsect / sb->s_blocksize);
+ roffset = (block % (hardsect / sb->s_blocksize)) * sb->s_blocksize;
+ real = bread(sb->s_dev, rblock, hardsect);
if (real != NULL) {
- ret = (struct buffer_head *)
- kmalloc (sizeof(struct buffer_head), GFP_KERNEL);
- if (ret != NULL) {
- /* #Specification: msdos / strategy / special device / dummy blocks
- * Many special device (Scsi optical disk for one) use
- * larger hardware sector size. This allows for higher
- * capacity.
-
- * Most of the time, the MS-DOS filesystem that sits
- * on this device is totally unaligned. It use logically
- * 512 bytes sector size, with logical sector starting
- * in the middle of a hardware block. The bad news is
- * that a hardware sector may hold data own by two
- * different files. This means that the hardware sector
- * must be read, patch and written almost all the time.
-
- * Needless to say that it kills write performance
- * on all OS.
-
- * Internally the linux msdos fs is using 512 bytes
- * logical sector. When accessing such a device, we
- * allocate dummy buffer cache blocks, that we stuff
- * with the information of a real one (1k large).
-
- * This strategy is used to hide this difference to
- * the core of the msdos fs. The slowdown is not
- * hidden though!
- */
- /*
- * The memset is there only to catch errors. The msdos
- * fs is only using b_data
- */
- memset (ret,0,sizeof(*ret));
- ret->b_data = real->b_data;
- if (sb->s_blocksize == 2048) {
- if (block & 3) ret->b_data += (block & 3) << 9;
- }else{
- if (block & 1) ret->b_data += 512;
- }
- ret->b_next = real;
- }else{
- brelse (real);
- }
+ dummy = kmalloc(sizeof(struct buffer_head), GFP_KERNEL);
+ if (dummy != NULL) {
+ memset(dummy, 0, sizeof(*dummy));
+ dummy->b_data = real->b_data + roffset;
+ dummy->b_next = real;
+ } else
+ brelse(real);
}
- return ret;
+
+ return dummy;
}
-void bigblock_fat_brelse (
- struct super_block *sb,
- struct buffer_head *bh)
+void bigblock_fat_brelse(struct super_block *sb, struct buffer_head *bh)
{
- brelse (bh->b_next);
- /*
- * We can free the dummy because a new one is allocated at
- * each fat_getblk() and fat_bread().
- */
- kfree (bh);
+ brelse(bh->b_next);
+ kfree(bh);
}
-void bigblock_fat_mark_buffer_dirty (
- struct super_block *sb,
- struct buffer_head *bh)
+void bigblock_fat_mark_buffer_dirty(struct super_block *sb, struct buffer_head *bh)
{
- mark_buffer_dirty (bh->b_next);
+ mark_buffer_dirty(bh->b_next);
}
-void bigblock_fat_set_uptodate (
- struct super_block *sb,
- struct buffer_head *bh,
- int val)
+void bigblock_fat_set_uptodate(struct super_block *sb, struct buffer_head *bh,
+ int val)
{
mark_buffer_uptodate(bh->b_next, val);
}
-int bigblock_fat_is_uptodate (
- struct super_block *sb,
- struct buffer_head *bh)
+int bigblock_fat_is_uptodate(struct super_block *sb, struct buffer_head *bh)
{
return buffer_uptodate(bh->b_next);
}
-void bigblock_fat_ll_rw_block (
- struct super_block *sb,
- int opr,
- int nbreq,
- struct buffer_head *bh[32])
+void bigblock_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
+ struct buffer_head *bh[32])
{
struct buffer_head *tmp[32];
int i;
- for (i=0; i<nbreq; i++)
+
+ for (i = 0; i < nbreq; i++)
tmp[i] = bh[i]->b_next;
- ll_rw_block(opr,nbreq,tmp);
+ ll_rw_block(opr, nbreq, tmp);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)