root/file.c

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

/* [<][>][^][v][top][bottom][index][help] */