root/file.c

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

DEFINITIONS

This source file includes following definitions.
  1. fileinit
  2. filealloc
  3. filedup
  4. fileclose
  5. filestat
  6. fileread
  7. filewrite

   1 //
   2 // File descriptors
   3 //
   4 
   5 #include "types.h"
   6 #include "defs.h"
   7 #include "param.h"
   8 #include "fs.h"
   9 #include "spinlock.h"
  10 #include "sleeplock.h"
  11 #include "file.h"
  12 
  13 struct devsw devsw[NDEV];
  14 struct {
  15   struct spinlock lock;
  16   struct file file[NFILE];
  17 } ftable;
  18 
  19 void
  20 fileinit(void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  21 {
  22   initlock(&ftable.lock, "ftable");
  23 }
  24 
  25 // Allocate a file structure.
  26 struct file*
  27 filealloc(void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  28 {
  29   struct file *f;
  30 
  31   acquire(&ftable.lock);
  32   for(f = ftable.file; f < ftable.file + NFILE; f++){
  33     if(f->ref == 0){
  34       f->ref = 1;
  35       release(&ftable.lock);
  36       return f;
  37     }
  38   }
  39   release(&ftable.lock);
  40   return 0;
  41 }
  42 
  43 // Increment ref count for file f.
  44 struct file*
  45 filedup(struct file *f)
     /* [previous][next][first][last][top][bottom][index][help]  */
  46 {
  47   acquire(&ftable.lock);
  48   if(f->ref < 1)
  49     panic("filedup");
  50   f->ref++;
  51   release(&ftable.lock);
  52   return f;
  53 }
  54 
  55 // Close file f.  (Decrement ref count, close when reaches 0.)
  56 void
  57 fileclose(struct file *f)
     /* [previous][next][first][last][top][bottom][index][help]  */
  58 {
  59   struct file ff;
  60 
  61   acquire(&ftable.lock);
  62   if(f->ref < 1)
  63     panic("fileclose");
  64   if(--f->ref > 0){
  65     release(&ftable.lock);
  66     return;
  67   }
  68   ff = *f;
  69   f->ref = 0;
  70   f->type = FD_NONE;
  71   release(&ftable.lock);
  72 
  73   if(ff.type == FD_PIPE)
  74     pipeclose(ff.pipe, ff.writable);
  75   else if(ff.type == FD_INODE){
  76     begin_op();
  77     iput(ff.ip);
  78     end_op();
  79   }
  80 }
  81 
  82 // Get metadata about file f.
  83 int
  84 filestat(struct file *f, struct stat *st)
     /* [previous][next][first][last][top][bottom][index][help]  */
  85 {
  86   if(f->type == FD_INODE){
  87     ilock(f->ip);
  88     stati(f->ip, st);
  89     iunlock(f->ip);
  90     return 0;
  91   }
  92   return -1;
  93 }
  94 
  95 // Read from file f.
  96 int
  97 fileread(struct file *f, char *addr, int n)
     /* [previous][next][first][last][top][bottom][index][help]  */
  98 {
  99   int r;
 100 
 101   if(f->readable == 0)
 102     return -1;
 103   if(f->type == FD_PIPE)
 104     return piperead(f->pipe, addr, n);
 105   if(f->type == FD_INODE){
 106     ilock(f->ip);
 107     if((r = readi(f->ip, addr, f->off, n)) > 0)
 108       f->off += r;
 109     iunlock(f->ip);
 110     return r;
 111   }
 112   panic("fileread");
 113 }
 114 
 115 //PAGEBREAK!
 116 // Write to file f.
 117 int
 118 filewrite(struct file *f, char *addr, int n)
     /* [previous][next][first][last][top][bottom][index][help]  */
 119 {
 120   int r;
 121 
 122   if(f->writable == 0)
 123     return -1;
 124   if(f->type == FD_PIPE)
 125     return pipewrite(f->pipe, addr, n);
 126   if(f->type == FD_INODE){
 127     // write a few blocks at a time to avoid exceeding
 128     // the maximum log transaction size, including
 129     // i-node, indirect block, allocation blocks,
 130     // and 2 blocks of slop for non-aligned writes.
 131     // this really belongs lower down, since writei()
 132     // might be writing a device like the console.
 133     int max = ((MAXOPBLOCKS-1-1-2) / 2) * 512;
 134     int i = 0;
 135     while(i < n){
 136       int n1 = n - i;
 137       if(n1 > max)
 138         n1 = max;
 139 
 140       begin_op();
 141       ilock(f->ip);
 142       if ((r = writei(f->ip, addr + i, f->off, n1)) > 0)
 143         f->off += r;
 144       iunlock(f->ip);
 145       end_op();
 146 
 147       if(r < 0)
 148         break;
 149       if(r != n1)
 150         panic("short filewrite");
 151       i += r;
 152     }
 153     return i == n ? n : -1;
 154   }
 155   panic("filewrite");
 156 }
 157 

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