This source file includes following definitions.
- block_write
 
- block_read
 
- block_fsync
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 #include <linux/errno.h>
   8 #include <linux/sched.h>
   9 #include <linux/kernel.h>
  10 #include <linux/locks.h>
  11 #include <asm/segment.h>
  12 #include <asm/system.h>
  13 
  14 extern int *blk_size[];
  15 extern int *blksize_size[];
  16 
  17 int block_write(struct inode * inode, struct file * filp, char * buf, int count)
     
  18 {
  19         int blocksize, blocksize_bits, i;
  20         int block;
  21         int offset;
  22         int chars;
  23         int written = 0;
  24         unsigned int size;
  25         unsigned int dev;
  26         struct buffer_head * bh;
  27         register char * p;
  28 
  29         dev = inode->i_rdev;
  30         blocksize = BLOCK_SIZE;
  31         if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
  32                 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
  33 
  34         i = blocksize;
  35         blocksize_bits = 0;
  36         while(i != 1) {
  37                 blocksize_bits++;
  38                 i >>= 1;
  39         }
  40 
  41         block = filp->f_pos >> blocksize_bits;
  42         offset = filp->f_pos & (blocksize-1);
  43 
  44         if (blk_size[MAJOR(dev)])
  45                 size = (blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
  46         else
  47                 size = INT_MAX;
  48         while (count>0) {
  49                 if (block >= size)
  50                         return written;
  51                 chars = blocksize - offset;
  52                 if (chars > count)
  53                         chars=count;
  54                 if (chars == blocksize)
  55                         bh = getblk(dev, block, blocksize);
  56                 else
  57                         bh = breada(dev,block,block+1,block+2,-1);
  58                 block++;
  59                 if (!bh)
  60                         return written?written:-EIO;
  61                 p = offset + bh->b_data;
  62                 offset = 0;
  63                 filp->f_pos += chars;
  64                 written += chars;
  65                 count -= chars;
  66                 memcpy_fromfs(p,buf,chars);
  67                 p += chars;
  68                 buf += chars;
  69                 bh->b_uptodate = 1;
  70                 bh->b_dirt = 1;
  71                 brelse(bh);
  72         }
  73         return written;
  74 }
  75 
  76 #define NBUF 32
  77 
  78 int block_read(struct inode * inode, struct file * filp, char * buf, int count)
     
  79 {
  80         unsigned int block;
  81         unsigned int offset;
  82         int blocksize;
  83         int blocksize_bits, i;
  84         unsigned int left;
  85         unsigned int blocks;
  86         int bhrequest, uptodate;
  87         struct buffer_head ** bhb, ** bhe;
  88         struct buffer_head * buflist[NBUF];
  89         struct buffer_head * bhreq[NBUF];
  90         unsigned int chars;
  91         unsigned int size;
  92         unsigned int dev;
  93         int read;
  94 
  95         dev = inode->i_rdev;
  96         blocksize = BLOCK_SIZE;
  97         if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
  98                 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
  99         i = blocksize;
 100         blocksize_bits = 0;
 101         while (i != 1) {
 102                 blocksize_bits++;
 103                 i >>= 1;
 104         }
 105 
 106         offset = filp->f_pos;
 107         if (blk_size[MAJOR(dev)])
 108                 size = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
 109         else
 110                 size = INT_MAX;
 111 
 112         if (offset > size)
 113                 left = 0;
 114         else
 115                 left = size - offset;
 116         if (left > count)
 117                 left = count;
 118         if (left <= 0)
 119                 return 0;
 120         read = 0;
 121         block = offset >> blocksize_bits;
 122         offset &= blocksize-1;
 123         size >>= blocksize_bits;
 124         blocks = (left + offset + blocksize - 1) >> blocksize_bits;
 125         bhb = bhe = buflist;
 126         if (filp->f_reada) {
 127                 blocks += read_ahead[MAJOR(dev)] / (blocksize >> 9);
 128                 if (block + blocks > size)
 129                         blocks = size - block;
 130         }
 131 
 132         
 133 
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 
 142         do {
 143                 bhrequest = 0;
 144                 uptodate = 1;
 145                 while (blocks) {
 146                         --blocks;
 147                         *bhb = getblk(dev, block++, blocksize);
 148                         if (*bhb && !(*bhb)->b_uptodate) {
 149                                 uptodate = 0;
 150                                 bhreq[bhrequest++] = *bhb;
 151                         }
 152 
 153                         if (++bhb == &buflist[NBUF])
 154                                 bhb = buflist;
 155 
 156                         
 157 
 158                         if (uptodate)
 159                                 break;
 160                         if (bhb == bhe)
 161                                 break;
 162                 }
 163 
 164                 
 165                 if (bhrequest)
 166                         ll_rw_block(READ, bhrequest, bhreq);
 167 
 168                 do { 
 169                         if (*bhe) {
 170                                 wait_on_buffer(*bhe);
 171                                 if (!(*bhe)->b_uptodate) {      
 172                                         brelse(*bhe);
 173                                         if (++bhe == &buflist[NBUF])
 174                                           bhe = buflist;
 175                                         left = 0;
 176                                         break;
 177                                 }
 178                         }                       
 179                         if (left < blocksize - offset)
 180                                 chars = left;
 181                         else
 182                                 chars = blocksize - offset;
 183                         filp->f_pos += chars;
 184                         left -= chars;
 185                         read += chars;
 186                         if (*bhe) {
 187                                 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
 188                                 brelse(*bhe);
 189                                 buf += chars;
 190                         } else {
 191                                 while (chars-->0)
 192                                         put_fs_byte(0,buf++);
 193                         }
 194                         offset = 0;
 195                         if (++bhe == &buflist[NBUF])
 196                                 bhe = buflist;
 197                 } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
 198         } while (left > 0);
 199 
 200 
 201         while (bhe != bhb) {
 202                 brelse(*bhe);
 203                 if (++bhe == &buflist[NBUF])
 204                         bhe = buflist;
 205         };
 206         if (!read)
 207                 return -EIO;
 208         filp->f_reada = 1;
 209         return read;
 210 }
 211 
 212 int block_fsync(struct inode *inode, struct file *filp)
     
 213 {
 214         return fsync_dev (inode->i_rdev);
 215 }