This source file includes following definitions.
- fileinit
- filealloc
- filedup
- fileclose
- filestat
- fileread
- filewrite
1
2
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)
21 {
22 initlock(&ftable.lock, "ftable");
23 }
24
25
26 struct file*
27 filealloc(void)
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
44 struct file*
45 filedup(struct file *f)
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
56 void
57 fileclose(struct file *f)
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
83 int
84 filestat(struct file *f, struct stat *st)
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
96 int
97 fileread(struct file *f, char *addr, int n)
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
116
117 int
118 filewrite(struct file *f, char *addr, int n)
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
128
129
130
131
132
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