This source file includes following definitions.
- fileinit
- filealloc
- filedup
- fileclose
- filestat
- fileread
- filewrite
1
2
3
4
5 #include "types.h"
6 #include "riscv.h"
7 #include "defs.h"
8 #include "param.h"
9 #include "fs.h"
10 #include "spinlock.h"
11 #include "sleeplock.h"
12 #include "file.h"
13 #include "stat.h"
14 #include "proc.h"
15
16 struct devsw devsw[NDEV];
17 struct {
18 struct spinlock lock;
19 struct file file[NFILE];
20 } ftable;
21
22 void
23 fileinit(void)
24 {
25 initlock(&ftable.lock, "ftable");
26 }
27
28
29 struct file*
30 filealloc(void)
31 {
32 struct file *f;
33
34 acquire(&ftable.lock);
35 for(f = ftable.file; f < ftable.file + NFILE; f++){
36 if(f->ref == 0){
37 f->ref = 1;
38 release(&ftable.lock);
39 return f;
40 }
41 }
42 release(&ftable.lock);
43 return 0;
44 }
45
46
47 struct file*
48 filedup(struct file *f)
49 {
50 acquire(&ftable.lock);
51 if(f->ref < 1)
52 panic("filedup");
53 f->ref++;
54 release(&ftable.lock);
55 return f;
56 }
57
58
59 void
60 fileclose(struct file *f)
61 {
62 struct file ff;
63
64 acquire(&ftable.lock);
65 if(f->ref < 1)
66 panic("fileclose");
67 if(--f->ref > 0){
68 release(&ftable.lock);
69 return;
70 }
71 ff = *f;
72 f->ref = 0;
73 f->type = FD_NONE;
74 release(&ftable.lock);
75
76 if(ff.type == FD_PIPE){
77 pipeclose(ff.pipe, ff.writable);
78 } else if(ff.type == FD_INODE || ff.type == FD_DEVICE){
79 begin_op();
80 iput(ff.ip);
81 end_op();
82 }
83 }
84
85
86
87 int
88 filestat(struct file *f, uint64 addr)
89 {
90 struct proc *p = myproc();
91 struct stat st;
92
93 if(f->type == FD_INODE || f->type == FD_DEVICE){
94 ilock(f->ip);
95 stati(f->ip, &st);
96 iunlock(f->ip);
97 if(copyout(p->pagetable, addr, (char *)&st, sizeof(st)) < 0)
98 return -1;
99 return 0;
100 }
101 return -1;
102 }
103
104
105
106 int
107 fileread(struct file *f, uint64 addr, int n)
108 {
109 int r = 0;
110
111 if(f->readable == 0)
112 return -1;
113
114 if(f->type == FD_PIPE){
115 r = piperead(f->pipe, addr, n);
116 } else if(f->type == FD_DEVICE){
117 if(f->major < 0 || f->major >= NDEV || !devsw[f->major].read)
118 return -1;
119 r = devsw[f->major].read(1, addr, n);
120 } else if(f->type == FD_INODE){
121 ilock(f->ip);
122 if((r = readi(f->ip, 1, addr, f->off, n)) > 0)
123 f->off += r;
124 iunlock(f->ip);
125 } else {
126 panic("fileread");
127 }
128
129 return r;
130 }
131
132
133
134 int
135 filewrite(struct file *f, uint64 addr, int n)
136 {
137 int r, ret = 0;
138
139 if(f->writable == 0)
140 return -1;
141
142 if(f->type == FD_PIPE){
143 ret = pipewrite(f->pipe, addr, n);
144 } else if(f->type == FD_DEVICE){
145 if(f->major < 0 || f->major >= NDEV || !devsw[f->major].write)
146 return -1;
147 ret = devsw[f->major].write(1, addr, n);
148 } else if(f->type == FD_INODE){
149
150
151
152
153
154
155 int max = ((MAXOPBLOCKS-1-1-2) / 2) * BSIZE;
156 int i = 0;
157 while(i < n){
158 int n1 = n - i;
159 if(n1 > max)
160 n1 = max;
161
162 begin_op();
163 ilock(f->ip);
164 if ((r = writei(f->ip, 1, addr + i, f->off, n1)) > 0)
165 f->off += r;
166 iunlock(f->ip);
167 end_op();
168
169 if(r != n1){
170
171 break;
172 }
173 i += r;
174 }
175 ret = (i == n ? n : -1);
176 } else {
177 panic("filewrite");
178 }
179
180 return ret;
181 }
182