root/fs/fat/buffer.c

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

DEFINITIONS

This source file includes following definitions.
  1. fat_bread
  2. fat_getblk
  3. fat_brelse
  4. fat_mark_buffer_dirty
  5. fat_set_uptodate
  6. fat_is_uptodate
  7. fat_ll_rw_block

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

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