root/fs/msdos/buffer.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. msdos_bread
  2. msdos_getblk
  3. msdos_brelse
  4. msdos_mark_buffer_dirty
  5. msdos_set_uptodate
  6. msdos_is_uptodate
  7. msdos_ll_rw_block

   1 #ifdef MODULE
   2 #include <linux/module.h>
   3 #endif
   4 
   5 #include <linux/mm.h>
   6 #include <linux/malloc.h>
   7 #include <linux/string.h>
   8 #include <linux/fs.h>
   9 #include <linux/msdos_fs.h>
  10 
  11 struct buffer_head *msdos_bread (
     /* [previous][next][first][last][top][bottom][index][help] */
  12         struct super_block *sb,
  13         int block)
  14 {
  15         struct buffer_head *ret = NULL;
  16         if (sb->s_blocksize == 512){
  17                 ret = bread (sb->s_dev,block,512);
  18         }else{
  19                 struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
  20                 if (real != NULL){
  21                         ret = (struct buffer_head *)kmalloc (sizeof(struct buffer_head)
  22                                 ,GFP_KERNEL);
  23                         if (ret != NULL){
  24                                 /* #Specification: msdos / strategy / special device / dummy blocks
  25                                         Many special device (Scsi optical disk for one) use
  26                                         larger hardware sector size. This allows for higher
  27                                         capacity.
  28 
  29                                         Most of the time, the MsDOS file system that sit
  30                                         on this device is totally unaligned. It use logically
  31                                         512 bytes sector size, with logical sector starting
  32                                         in the middle of a hardware block. The bad news is
  33                                         that a hardware sector may hold data own by two
  34                                         different files. This means that the hardware sector
  35                                         must be read, patch and written almost all the time.
  36 
  37                                         Needless to say that it kills write performance
  38                                         on all OS.
  39 
  40                                         Internally the linux msdos fs is using 512 bytes
  41                                         logical sector. When accessing such a device, we
  42                                         allocate dummy buffer cache blocks, that we stuff
  43                                         with the information of a real one (1k large).
  44 
  45                                         This strategy is used to hide this difference to
  46                                         the core of the msdos fs. The slowdown is not
  47                                         hidden though!
  48                                 */
  49                                 /*
  50                                         The memset is there only to catch errors. The msdos
  51                                         fs is only using b_data
  52                                 */
  53                                 memset (ret,0,sizeof(*ret));
  54                                 ret->b_data = real->b_data;
  55                                 if (block & 1) ret->b_data += 512;
  56                                 ret->b_next = real;
  57                         }else{
  58                                 brelse (real);
  59                         }
  60                 }
  61         }
  62         return ret;
  63 }
  64 struct buffer_head *msdos_getblk (
     /* [previous][next][first][last][top][bottom][index][help] */
  65         struct super_block *sb,
  66         int block)
  67 {
  68         struct buffer_head *ret = NULL;
  69         if (sb->s_blocksize == 512){
  70                 ret = getblk (sb->s_dev,block,512);
  71         }else{
  72                 /* #Specification: msdos / special device / writing
  73                         A write is always preceded by a read of the complete block
  74                         (large hardware sector size). This defeat write performance.
  75                         There is a possibility to optimize this when writing large
  76                         chunk by making sure we are filling large block. Volunteer ?
  77                 */
  78                 ret = msdos_bread (sb,block);
  79         }
  80         return ret;
  81 }
  82 
  83 void msdos_brelse (
     /* [previous][next][first][last][top][bottom][index][help] */
  84         struct super_block *sb,
  85         struct buffer_head *bh)
  86 {
  87         if (bh != NULL){
  88                 if (sb->s_blocksize == 512){
  89                         brelse (bh);
  90                 }else{
  91                         brelse (bh->b_next);
  92                         /* We can free the dummy because a new one is allocated at
  93                                 each msdos_getblk() and msdos_bread().
  94                         */
  95                         kfree (bh);
  96                 }
  97         }
  98 }
  99         
 100 void msdos_mark_buffer_dirty (
     /* [previous][next][first][last][top][bottom][index][help] */
 101         struct super_block *sb,
 102         struct buffer_head *bh,
 103         int dirty_val)
 104 {
 105         if (sb->s_blocksize != 512){
 106                 bh = bh->b_next;
 107         }
 108         mark_buffer_dirty (bh,dirty_val);
 109 }
 110 
 111 void msdos_set_uptodate (
     /* [previous][next][first][last][top][bottom][index][help] */
 112         struct super_block *sb,
 113         struct buffer_head *bh,
 114         int val)
 115 {
 116         if (sb->s_blocksize != 512){
 117                 bh = bh->b_next;
 118         }
 119         bh->b_uptodate = val;
 120 }
 121 int msdos_is_uptodate (
     /* [previous][next][first][last][top][bottom][index][help] */
 122         struct super_block *sb,
 123         struct buffer_head *bh)
 124 {
 125         if (sb->s_blocksize != 512){
 126                 bh = bh->b_next;
 127         }
 128         return bh->b_uptodate;
 129 }
 130 
 131 void msdos_ll_rw_block (
     /* [previous][next][first][last][top][bottom][index][help] */
 132         struct super_block *sb,
 133         int opr,
 134         int nbreq,
 135         struct buffer_head *bh[32])
 136 {
 137         if (sb->s_blocksize == 512){
 138                 ll_rw_block(opr,nbreq,bh);
 139         }else{
 140                 struct buffer_head *tmp[32];
 141                 int i;
 142                 for (i=0; i<nbreq; i++){
 143                         tmp[i] = bh[i]->b_next;
 144                 }
 145                 ll_rw_block(opr,nbreq,tmp);
 146         }
 147 }
 148 

/* [previous][next][first][last][top][bottom][index][help] */