00001 #include "types.h"
00002 #include "defs.h"
00003 #include "param.h"
00004 #include "fs.h"
00005 #include "file.h"
00006 #include "spinlock.h"
00007
00008 struct devsw devsw[NDEV];
00009 struct {
00010 struct spinlock lock;
00011 struct file file[NFILE];
00012 } ftable;
00013
00014 void
00015 fileinit(void)
00016 {
00017 initlock(&ftable.lock, "ftable");
00018 }
00019
00020
00021 struct file*
00022 filealloc(void)
00023 {
00024 struct file *f;
00025
00026 acquire(&ftable.lock);
00027 for(f = ftable.file; f < ftable.file + NFILE; f++){
00028 if(f->ref == 0){
00029 f->ref = 1;
00030 release(&ftable.lock);
00031 return f;
00032 }
00033 }
00034 release(&ftable.lock);
00035 return 0;
00036 }
00037
00038
00039 struct file*
00040 filedup(struct file *f)
00041 {
00042 acquire(&ftable.lock);
00043 if(f->ref < 1)
00044 panic("filedup");
00045 f->ref++;
00046 release(&ftable.lock);
00047 return f;
00048 }
00049
00050
00051 void
00052 fileclose(struct file *f)
00053 {
00054 struct file ff;
00055
00056 acquire(&ftable.lock);
00057 if(f->ref < 1)
00058 panic("fileclose");
00059 if(--f->ref > 0){
00060 release(&ftable.lock);
00061 return;
00062 }
00063 ff = *f;
00064 f->ref = 0;
00065 f->type = FD_NONE;
00066 release(&ftable.lock);
00067
00068 if(ff.type == FD_PIPE)
00069 pipeclose(ff.pipe, ff.writable);
00070 else if(ff.type == FD_INODE)
00071 iput(ff.ip);
00072 }
00073
00074
00075 int
00076 filestat(struct file *f, struct stat *st)
00077 {
00078 if(f->type == FD_INODE){
00079 ilock(f->ip);
00080 stati(f->ip, st);
00081 iunlock(f->ip);
00082 return 0;
00083 }
00084 return -1;
00085 }
00086
00087
00088 int
00089 fileread(struct file *f, char *addr, int n)
00090 {
00091 int r;
00092
00093 if(f->readable == 0)
00094 return -1;
00095 if(f->type == FD_PIPE)
00096 return piperead(f->pipe, addr, n);
00097 if(f->type == FD_INODE){
00098 ilock(f->ip);
00099 if((r = readi(f->ip, addr, f->off, n)) > 0)
00100 f->off += r;
00101 iunlock(f->ip);
00102 return r;
00103 }
00104 panic("fileread");
00105 }
00106
00107
00108 int
00109 filewrite(struct file *f, char *addr, int n)
00110 {
00111 int r;
00112
00113 if(f->writable == 0)
00114 return -1;
00115 if(f->type == FD_PIPE)
00116 return pipewrite(f->pipe, addr, n);
00117 if(f->type == FD_INODE){
00118 ilock(f->ip);
00119 if((r = writei(f->ip, addr, f->off, n)) > 0)
00120 f->off += r;
00121 iunlock(f->ip);
00122 return r;
00123 }
00124 panic("filewrite");
00125 }
00126