annotate src/file.c @ 51:ccd59cd9ee45

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