root/fs/file_dev.c

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

DEFINITIONS

This source file includes following definitions.
  1. file_read
  2. file_write

   1 /*
   2  *  linux/fs/file_dev.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 #include <errno.h>
   8 #include <fcntl.h>
   9 
  10 #include <linux/sched.h>
  11 #include <linux/kernel.h>
  12 #include <asm/segment.h>
  13 
  14 #define MIN(a,b) (((a)<(b))?(a):(b))
  15 #define MAX(a,b) (((a)>(b))?(a):(b))
  16 
  17 int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  18 {
  19         int left,chars,nr;
  20         struct buffer_head * bh;
  21 
  22         if ((left=count)<=0)
  23                 return 0;
  24         while (left) {
  25                 if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) {
  26                         if (!(bh=bread(inode->i_dev,nr)))
  27                                 break;
  28                 } else
  29                         bh = NULL;
  30                 nr = filp->f_pos % BLOCK_SIZE;
  31                 chars = MIN( BLOCK_SIZE-nr , left );
  32                 filp->f_pos += chars;
  33                 left -= chars;
  34                 if (bh) {
  35                         char * p = nr + bh->b_data;
  36                         while (chars-->0)
  37                                 put_fs_byte(*(p++),buf++);
  38                         brelse(bh);
  39                 } else {
  40                         while (chars-->0)
  41                                 put_fs_byte(0,buf++);
  42                 }
  43         }
  44         inode->i_atime = CURRENT_TIME;
  45         return (count-left)?(count-left):-ERROR;
  46 }
  47 
  48 int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         off_t pos;
  51         int block,c;
  52         struct buffer_head * bh;
  53         char * p;
  54         int i=0;
  55 
  56 /*
  57  * ok, append may not work when many processes are writing at the same time
  58  * but so what. That way leads to madness anyway.
  59  */
  60         if (filp->f_flags & O_APPEND)
  61                 pos = inode->i_size;
  62         else
  63                 pos = filp->f_pos;
  64         while (i<count) {
  65                 if (!(block = create_block(inode,pos/BLOCK_SIZE)))
  66                         break;
  67                 if (!(bh=bread(inode->i_dev,block)))
  68                         break;
  69                 c = pos % BLOCK_SIZE;
  70                 p = c + bh->b_data;
  71                 bh->b_dirt = 1;
  72                 c = BLOCK_SIZE-c;
  73                 if (c > count-i) c = count-i;
  74                 pos += c;
  75                 if (pos > inode->i_size) {
  76                         inode->i_size = pos;
  77                         inode->i_dirt = 1;
  78                 }
  79                 i += c;
  80                 while (c-->0)
  81                         *(p++) = get_fs_byte(buf++);
  82                 brelse(bh);
  83         }
  84         inode->i_mtime = CURRENT_TIME;
  85         if (!(filp->f_flags & O_APPEND)) {
  86                 filp->f_pos = pos;
  87                 inode->i_ctime = CURRENT_TIME;
  88         }
  89         return (i?i:-1);
  90 }

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