comparison src/file.c @ 0:83c23a36980d

Init
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Fri, 26 May 2017 23:11:05 +0900
parents
children 36bd61f5c847
comparison
equal deleted inserted replaced
-1:000000000000 0:83c23a36980d
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 fileinit (void)
19 {
20 initlock(&ftable.lock, "ftable");
21 }
22
23 // Allocate a file structure.
24 struct file* filealloc (void)
25 {
26 struct file *f;
27
28 acquire(&ftable.lock);
29
30 for (f = ftable.file; f < ftable.file + NFILE; f++) {
31 if (f->ref == 0) {
32 f->ref = 1;
33 release(&ftable.lock);
34 return f;
35 }
36 }
37
38 release(&ftable.lock);
39 return 0;
40 }
41
42 // Increment ref count for file f.
43 struct file* filedup (struct file *f)
44 {
45 acquire(&ftable.lock);
46
47 if (f->ref < 1) {
48 panic("filedup");
49 }
50
51 f->ref++;
52 release(&ftable.lock);
53 return f;
54 }
55
56 // Close file f. (Decrement ref count, close when reaches 0.)
57 void fileclose (struct file *f)
58 {
59 struct file ff;
60
61 acquire(&ftable.lock);
62
63 if (f->ref < 1) {
64 panic("fileclose");
65 }
66
67 if (--f->ref > 0) {
68 release(&ftable.lock);
69 return;
70 }
71
72 ff = *f;
73 f->ref = 0;
74 f->type = FD_NONE;
75 release(&ftable.lock);
76
77 if (ff.type == FD_PIPE) {
78 pipeclose(ff.pipe, ff.writable);
79
80 } else if (ff.type == FD_INODE) {
81 begin_trans();
82 iput(ff.ip);
83 commit_trans();
84 }
85 }
86
87 // Get metadata about file f.
88 int filestat (struct file *f, struct stat *st)
89 {
90 if (f->type == FD_INODE) {
91 ilock(f->ip);
92 stati(f->ip, st);
93 iunlock(f->ip);
94
95 return 0;
96 }
97
98 return -1;
99 }
100
101 // Read from file f.
102 int fileread (struct file *f, char *addr, int n)
103 {
104 int r;
105
106 if (f->readable == 0) {
107 return -1;
108 }
109
110 if (f->type == FD_PIPE) {
111 return piperead(f->pipe, addr, n);
112 }
113
114 if (f->type == FD_INODE) {
115 ilock(f->ip);
116
117 if ((r = readi(f->ip, addr, f->off, n)) > 0) {
118 f->off += r;
119 }
120
121 iunlock(f->ip);
122
123 return r;
124 }
125
126 panic("fileread");
127 }
128
129 //PAGEBREAK!
130 // Write to file f.
131 int filewrite (struct file *f, char *addr, int n)
132 {
133 int r;
134 int i;
135 int max;
136 int n1;
137
138 if (f->writable == 0) {
139 return -1;
140 }
141
142 if (f->type == FD_PIPE) {
143 return pipewrite(f->pipe, addr, n);
144 }
145
146 if (f->type == FD_INODE) {
147 // write a few blocks at a time to avoid exceeding
148 // the maximum log transaction size, including
149 // i-node, indirect block, allocation blocks,
150 // and 2 blocks of slop for non-aligned writes.
151 // this really belongs lower down, since writei()
152 // might be writing a device like the console.
153 max = ((LOGSIZE - 1 - 1 - 2) / 2) * 512;
154 i = 0;
155
156 while (i < n) {
157 n1 = n - i;
158
159 if (n1 > max) {
160 n1 = max;
161 }
162
163 begin_trans();
164 ilock(f->ip);
165
166 if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) {
167 f->off += r;
168 }
169
170 iunlock(f->ip);
171 commit_trans();
172
173 if (r < 0) {
174 break;
175 }
176
177 if (r != n1) {
178 panic("short filewrite");
179 }
180
181 i += r;
182 }
183
184 return i == n ? n : -1;
185 }
186
187 panic("filewrite");
188 }
189