Blame


1 0c98da8b 2005-07-13 devnull #include <u.h>
2 0c98da8b 2005-07-13 devnull #include <libc.h>
3 0c98da8b 2005-07-13 devnull #include <thread.h>
4 0c98da8b 2005-07-13 devnull #include <sunrpc.h>
5 0c98da8b 2005-07-13 devnull #include <nfs3.h>
6 0c98da8b 2005-07-13 devnull #include <diskfs.h>
7 0c98da8b 2005-07-13 devnull #include "ext2.h"
8 0c98da8b 2005-07-13 devnull
9 83ab7d88 2007-11-27 rsc static void parsedirent(Dirent*, uchar*);
10 83ab7d88 2007-11-27 rsc static void parseinode(Inode*, uchar*);
11 83ab7d88 2007-11-27 rsc static void parsegroup(Group*, uchar*);
12 83ab7d88 2007-11-27 rsc static void parsesuper(Super*, uchar*);
13 83ab7d88 2007-11-27 rsc
14 e77222a4 2006-05-04 devnull #define debug 0
15 0c98da8b 2005-07-13 devnull
16 0c98da8b 2005-07-13 devnull static int ext2sync(Fsys*);
17 0c98da8b 2005-07-13 devnull static void ext2close(Fsys*);
18 0c98da8b 2005-07-13 devnull static Block* ext2blockread(Fsys*, u64int);
19 0c98da8b 2005-07-13 devnull
20 0c98da8b 2005-07-13 devnull static Nfs3Status ext2root(Fsys*, Nfs3Handle*);
21 0c98da8b 2005-07-13 devnull static Nfs3Status ext2getattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
22 0c98da8b 2005-07-13 devnull static Nfs3Status ext2lookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
23 0c98da8b 2005-07-13 devnull static Nfs3Status ext2readfile(Fsys*, SunAuthUnix *au, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
24 0c98da8b 2005-07-13 devnull static Nfs3Status ext2readlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link);
25 0c98da8b 2005-07-13 devnull static Nfs3Status ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
26 0c98da8b 2005-07-13 devnull static Nfs3Status ext2access(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr);
27 0c98da8b 2005-07-13 devnull
28 0c98da8b 2005-07-13 devnull Fsys*
29 0c98da8b 2005-07-13 devnull fsysopenext2(Disk *disk)
30 0c98da8b 2005-07-13 devnull {
31 0c98da8b 2005-07-13 devnull Ext2 *fs;
32 0c98da8b 2005-07-13 devnull Fsys *fsys;
33 0c98da8b 2005-07-13 devnull
34 0c98da8b 2005-07-13 devnull fsys = emalloc(sizeof(Fsys));
35 0c98da8b 2005-07-13 devnull fs = emalloc(sizeof(Ext2));
36 0c98da8b 2005-07-13 devnull fs->disk = disk;
37 0c98da8b 2005-07-13 devnull fsys->priv = fs;
38 0c98da8b 2005-07-13 devnull fs->fsys = fsys;
39 0c98da8b 2005-07-13 devnull fsys->type = "ext2";
40 0c98da8b 2005-07-13 devnull fsys->_readblock = ext2blockread;
41 0c98da8b 2005-07-13 devnull fsys->_sync = ext2sync;
42 0c98da8b 2005-07-13 devnull fsys->_root = ext2root;
43 0c98da8b 2005-07-13 devnull fsys->_getattr = ext2getattr;
44 0c98da8b 2005-07-13 devnull fsys->_access = ext2access;
45 0c98da8b 2005-07-13 devnull fsys->_lookup = ext2lookup;
46 0c98da8b 2005-07-13 devnull fsys->_readfile = ext2readfile;
47 0c98da8b 2005-07-13 devnull fsys->_readlink = ext2readlink;
48 0c98da8b 2005-07-13 devnull fsys->_readdir = ext2readdir;
49 a51dffd3 2006-11-20 devnull fsys->_close = ext2close;
50 0c98da8b 2005-07-13 devnull
51 0c98da8b 2005-07-13 devnull if(ext2sync(fsys) < 0)
52 0c98da8b 2005-07-13 devnull goto error;
53 0c98da8b 2005-07-13 devnull
54 0c98da8b 2005-07-13 devnull return fsys;
55 0c98da8b 2005-07-13 devnull
56 0c98da8b 2005-07-13 devnull error:
57 0c98da8b 2005-07-13 devnull ext2close(fsys);
58 0c98da8b 2005-07-13 devnull return nil;
59 0c98da8b 2005-07-13 devnull }
60 0c98da8b 2005-07-13 devnull
61 0c98da8b 2005-07-13 devnull static void
62 0c98da8b 2005-07-13 devnull ext2close(Fsys *fsys)
63 0c98da8b 2005-07-13 devnull {
64 0c98da8b 2005-07-13 devnull Ext2 *fs;
65 0c98da8b 2005-07-13 devnull
66 0c98da8b 2005-07-13 devnull fs = fsys->priv;
67 0c98da8b 2005-07-13 devnull free(fs);
68 0c98da8b 2005-07-13 devnull free(fsys);
69 0c98da8b 2005-07-13 devnull }
70 0c98da8b 2005-07-13 devnull
71 83ab7d88 2007-11-27 rsc static int
72 83ab7d88 2007-11-27 rsc ext2group(Ext2 *fs, u32int i, Group *g)
73 0c98da8b 2005-07-13 devnull {
74 0c98da8b 2005-07-13 devnull Block *b;
75 0c98da8b 2005-07-13 devnull u64int addr;
76 0c98da8b 2005-07-13 devnull
77 0c98da8b 2005-07-13 devnull if(i >= fs->ngroup)
78 83ab7d88 2007-11-27 rsc return -1;
79 0c98da8b 2005-07-13 devnull
80 0c98da8b 2005-07-13 devnull addr = fs->groupaddr + i/fs->descperblock;
81 0c98da8b 2005-07-13 devnull b = diskread(fs->disk, fs->blocksize, addr*fs->blocksize);
82 0c98da8b 2005-07-13 devnull if(b == nil)
83 83ab7d88 2007-11-27 rsc return -1;
84 83ab7d88 2007-11-27 rsc parsegroup(g, b->data+i%fs->descperblock*GroupSize);
85 83ab7d88 2007-11-27 rsc blockput(b);
86 83ab7d88 2007-11-27 rsc return 0;
87 0c98da8b 2005-07-13 devnull }
88 0c98da8b 2005-07-13 devnull
89 0c98da8b 2005-07-13 devnull static Block*
90 0c98da8b 2005-07-13 devnull ext2blockread(Fsys *fsys, u64int vbno)
91 0c98da8b 2005-07-13 devnull {
92 0c98da8b 2005-07-13 devnull Block *bitb;
93 83ab7d88 2007-11-27 rsc Group g;
94 0c98da8b 2005-07-13 devnull uchar *bits;
95 c1a4592d 2006-06-15 devnull u32int bno, boff, bitblock;
96 c1a4592d 2006-06-15 devnull u64int bitpos;
97 0c98da8b 2005-07-13 devnull Ext2 *fs;
98 0c98da8b 2005-07-13 devnull
99 0c98da8b 2005-07-13 devnull fs = fsys->priv;
100 0c98da8b 2005-07-13 devnull if(vbno >= fs->nblock)
101 0c98da8b 2005-07-13 devnull return nil;
102 0c98da8b 2005-07-13 devnull bno = vbno;
103 0c98da8b 2005-07-13 devnull if(bno != vbno)
104 0c98da8b 2005-07-13 devnull return nil;
105 0c98da8b 2005-07-13 devnull
106 fa325e9b 2020-01-10 cross /*
107 0c98da8b 2005-07-13 devnull if(bno < fs->firstblock)
108 0c98da8b 2005-07-13 devnull return diskread(fs->disk, fs->blocksize, (u64int)bno*fs->blocksize);
109 0c98da8b 2005-07-13 devnull */
110 0c98da8b 2005-07-13 devnull if(bno < fs->firstblock)
111 0c98da8b 2005-07-13 devnull return nil;
112 0c98da8b 2005-07-13 devnull
113 0c98da8b 2005-07-13 devnull bno -= fs->firstblock;
114 83ab7d88 2007-11-27 rsc if(ext2group(fs, bno/fs->blockspergroup, &g) < 0){
115 0c98da8b 2005-07-13 devnull if(debug)
116 0c98da8b 2005-07-13 devnull fprint(2, "loading group: %r...");
117 0c98da8b 2005-07-13 devnull return nil;
118 0c98da8b 2005-07-13 devnull }
119 e77222a4 2006-05-04 devnull /*
120 c1a4592d 2006-06-15 devnull if(debug)
121 c1a4592d 2006-06-15 devnull fprint(2, "ext2 group %d: bitblock=%ud inodebitblock=%ud inodeaddr=%ud freeblocks=%ud freeinodes=%ud useddirs=%ud\n",
122 c1a4592d 2006-06-15 devnull (int)(bno/fs->blockspergroup),
123 83ab7d88 2007-11-27 rsc g.bitblock,
124 83ab7d88 2007-11-27 rsc g.inodebitblock,
125 83ab7d88 2007-11-27 rsc g.inodeaddr,
126 83ab7d88 2007-11-27 rsc g.freeblockscount,
127 83ab7d88 2007-11-27 rsc g.freeinodescount,
128 83ab7d88 2007-11-27 rsc g.useddirscount);
129 83ab7d88 2007-11-27 rsc if(debug)
130 83ab7d88 2007-11-27 rsc fprint(2, "group %d bitblock=%d...", bno/fs->blockspergroup, g.bitblock);
131 e77222a4 2006-05-04 devnull */
132 83ab7d88 2007-11-27 rsc bitblock = g.bitblock;
133 c1a4592d 2006-06-15 devnull bitpos = (u64int)bitblock*fs->blocksize;
134 0c98da8b 2005-07-13 devnull
135 9bbcb80d 2006-06-15 devnull if((bitb = diskread(fs->disk, fs->blocksize, bitpos)) == nil){
136 0c98da8b 2005-07-13 devnull if(debug)
137 0c98da8b 2005-07-13 devnull fprint(2, "loading bitblock: %r...");
138 0c98da8b 2005-07-13 devnull return nil;
139 0c98da8b 2005-07-13 devnull }
140 0c98da8b 2005-07-13 devnull bits = bitb->data;
141 0c98da8b 2005-07-13 devnull boff = bno%fs->blockspergroup;
142 0c98da8b 2005-07-13 devnull if((bits[boff>>3] & (1<<(boff&7))) == 0){
143 0c98da8b 2005-07-13 devnull if(debug)
144 c1a4592d 2006-06-15 devnull fprint(2, "block %d not allocated in group %d: bitblock %d/%lld bits[%d] = %#x\n",
145 fa325e9b 2020-01-10 cross boff, bno/fs->blockspergroup,
146 c1a4592d 2006-06-15 devnull (int)bitblock,
147 c1a4592d 2006-06-15 devnull bitpos,
148 c1a4592d 2006-06-15 devnull boff>>3,
149 c1a4592d 2006-06-15 devnull bits[boff>>3]);
150 0c98da8b 2005-07-13 devnull blockput(bitb);
151 0c98da8b 2005-07-13 devnull return nil;
152 0c98da8b 2005-07-13 devnull }
153 9bbcb80d 2006-06-15 devnull blockput(bitb);
154 0c98da8b 2005-07-13 devnull
155 0c98da8b 2005-07-13 devnull bno += fs->firstblock;
156 0c98da8b 2005-07-13 devnull return diskread(fs->disk, fs->blocksize, (u64int)bno*fs->blocksize);
157 0c98da8b 2005-07-13 devnull }
158 0c98da8b 2005-07-13 devnull
159 0c98da8b 2005-07-13 devnull static Block*
160 0c98da8b 2005-07-13 devnull ext2datablock(Ext2 *fs, u32int bno, int size)
161 0c98da8b 2005-07-13 devnull {
162 3330e5bf 2005-10-29 devnull USED(size);
163 e77222a4 2006-05-04 devnull return ext2blockread(fs->fsys, bno);
164 0c98da8b 2005-07-13 devnull }
165 0c98da8b 2005-07-13 devnull
166 0c98da8b 2005-07-13 devnull static Block*
167 0c98da8b 2005-07-13 devnull ext2fileblock(Ext2 *fs, Inode *ino, u32int bno, int size)
168 0c98da8b 2005-07-13 devnull {
169 0c98da8b 2005-07-13 devnull int ppb;
170 0c98da8b 2005-07-13 devnull Block *b;
171 0c98da8b 2005-07-13 devnull u32int *a;
172 b109049f 2007-03-25 devnull u32int obno, pbno;
173 0c98da8b 2005-07-13 devnull
174 0c98da8b 2005-07-13 devnull obno = bno;
175 0c98da8b 2005-07-13 devnull if(bno < NDIRBLOCKS){
176 0c98da8b 2005-07-13 devnull if(debug)
177 fa325e9b 2020-01-10 cross fprint(2, "fileblock %d -> %d...",
178 0c98da8b 2005-07-13 devnull bno, ino->block[bno]);
179 0c98da8b 2005-07-13 devnull return ext2datablock(fs, ino->block[bno], size);
180 0c98da8b 2005-07-13 devnull }
181 0c98da8b 2005-07-13 devnull bno -= NDIRBLOCKS;
182 0c98da8b 2005-07-13 devnull ppb = fs->blocksize/4;
183 0c98da8b 2005-07-13 devnull
184 0c98da8b 2005-07-13 devnull /* one indirect */
185 0c98da8b 2005-07-13 devnull if(bno < ppb){
186 0c98da8b 2005-07-13 devnull b = ext2datablock(fs, ino->block[INDBLOCK], fs->blocksize);
187 0c98da8b 2005-07-13 devnull if(b == nil)
188 0c98da8b 2005-07-13 devnull return nil;
189 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
190 b109049f 2007-03-25 devnull bno = a[bno];
191 0c98da8b 2005-07-13 devnull blockput(b);
192 0c98da8b 2005-07-13 devnull return ext2datablock(fs, bno, size);
193 0c98da8b 2005-07-13 devnull }
194 0c98da8b 2005-07-13 devnull bno -= ppb;
195 0c98da8b 2005-07-13 devnull
196 0c98da8b 2005-07-13 devnull /* one double indirect */
197 0c98da8b 2005-07-13 devnull if(bno < ppb*ppb){
198 0c98da8b 2005-07-13 devnull b = ext2datablock(fs, ino->block[DINDBLOCK], fs->blocksize);
199 0c98da8b 2005-07-13 devnull if(b == nil)
200 0c98da8b 2005-07-13 devnull return nil;
201 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
202 b109049f 2007-03-25 devnull pbno = a[bno/ppb];
203 b109049f 2007-03-25 devnull bno = bno%ppb;
204 0c98da8b 2005-07-13 devnull blockput(b);
205 b109049f 2007-03-25 devnull b = ext2datablock(fs, pbno, fs->blocksize);
206 0c98da8b 2005-07-13 devnull if(b == nil)
207 0c98da8b 2005-07-13 devnull return nil;
208 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
209 b109049f 2007-03-25 devnull bno = a[bno];
210 0c98da8b 2005-07-13 devnull blockput(b);
211 0c98da8b 2005-07-13 devnull return ext2datablock(fs, bno, size);
212 0c98da8b 2005-07-13 devnull }
213 0c98da8b 2005-07-13 devnull bno -= ppb*ppb;
214 0c98da8b 2005-07-13 devnull
215 0c98da8b 2005-07-13 devnull /* one triple indirect */
216 0c98da8b 2005-07-13 devnull if(bno < ppb*ppb*ppb){
217 0c98da8b 2005-07-13 devnull b = ext2datablock(fs, ino->block[TINDBLOCK], fs->blocksize);
218 0c98da8b 2005-07-13 devnull if(b == nil)
219 0c98da8b 2005-07-13 devnull return nil;
220 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
221 b109049f 2007-03-25 devnull pbno = a[bno/(ppb*ppb)];
222 b109049f 2007-03-25 devnull bno = bno%(ppb*ppb);
223 0c98da8b 2005-07-13 devnull blockput(b);
224 b109049f 2007-03-25 devnull b = ext2datablock(fs, pbno, fs->blocksize);
225 0c98da8b 2005-07-13 devnull if(b == nil)
226 0c98da8b 2005-07-13 devnull return nil;
227 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
228 b109049f 2007-03-25 devnull pbno = a[bno/ppb];
229 b109049f 2007-03-25 devnull bno = bno%ppb;
230 0c98da8b 2005-07-13 devnull blockput(b);
231 b109049f 2007-03-25 devnull b = ext2datablock(fs, pbno, fs->blocksize);
232 0c98da8b 2005-07-13 devnull if(b == nil)
233 0c98da8b 2005-07-13 devnull return nil;
234 0c98da8b 2005-07-13 devnull a = (u32int*)b->data;
235 b109049f 2007-03-25 devnull bno = a[bno];
236 0c98da8b 2005-07-13 devnull blockput(b);
237 0c98da8b 2005-07-13 devnull return ext2datablock(fs, bno, size);
238 0c98da8b 2005-07-13 devnull }
239 0c98da8b 2005-07-13 devnull
240 3330e5bf 2005-10-29 devnull fprint(2, "ext2fileblock %ud: too big\n", obno);
241 0c98da8b 2005-07-13 devnull return nil;
242 0c98da8b 2005-07-13 devnull }
243 0c98da8b 2005-07-13 devnull
244 0c98da8b 2005-07-13 devnull static int
245 0c98da8b 2005-07-13 devnull checksuper(Super *super)
246 0c98da8b 2005-07-13 devnull {
247 0c98da8b 2005-07-13 devnull if(super->magic != SUPERMAGIC){
248 0c98da8b 2005-07-13 devnull werrstr("bad magic 0x%ux wanted 0x%ux", super->magic, SUPERMAGIC);
249 0c98da8b 2005-07-13 devnull return -1;
250 0c98da8b 2005-07-13 devnull }
251 0c98da8b 2005-07-13 devnull return 0;
252 0c98da8b 2005-07-13 devnull }
253 0c98da8b 2005-07-13 devnull
254 0c98da8b 2005-07-13 devnull static int
255 0c98da8b 2005-07-13 devnull ext2sync(Fsys *fsys)
256 0c98da8b 2005-07-13 devnull {
257 0c98da8b 2005-07-13 devnull int i;
258 83ab7d88 2007-11-27 rsc Group g;
259 0c98da8b 2005-07-13 devnull Block *b;
260 83ab7d88 2007-11-27 rsc Super super;
261 0c98da8b 2005-07-13 devnull Ext2 *fs;
262 0c98da8b 2005-07-13 devnull Disk *disk;
263 0c98da8b 2005-07-13 devnull
264 0c98da8b 2005-07-13 devnull fs = fsys->priv;
265 0c98da8b 2005-07-13 devnull disk = fs->disk;
266 0c98da8b 2005-07-13 devnull if((b = diskread(disk, SBSIZE, SBOFF)) == nil)
267 83ab7d88 2007-11-27 rsc return -1;
268 83ab7d88 2007-11-27 rsc parsesuper(&super, b->data);
269 83ab7d88 2007-11-27 rsc blockput(b);
270 83ab7d88 2007-11-27 rsc if(checksuper(&super) < 0)
271 83ab7d88 2007-11-27 rsc return -1;
272 83ab7d88 2007-11-27 rsc fs->blocksize = MINBLOCKSIZE<<super.logblocksize;
273 83ab7d88 2007-11-27 rsc fs->nblock = super.nblock;
274 83ab7d88 2007-11-27 rsc fs->ngroup = (super.nblock+super.blockspergroup-1)
275 83ab7d88 2007-11-27 rsc / super.blockspergroup;
276 83ab7d88 2007-11-27 rsc fs->inospergroup = super.inospergroup;
277 83ab7d88 2007-11-27 rsc fs->blockspergroup = super.blockspergroup;
278 d29f5ece 2008-06-01 rsc if(super.revlevel >= 1)
279 d29f5ece 2008-06-01 rsc fs->inosize = super.inosize;
280 d29f5ece 2008-06-01 rsc else
281 d29f5ece 2008-06-01 rsc fs->inosize = 128;
282 d29f5ece 2008-06-01 rsc fs->inosperblock = fs->blocksize / fs->inosize;
283 0c98da8b 2005-07-13 devnull if(fs->blocksize == SBOFF)
284 0c98da8b 2005-07-13 devnull fs->groupaddr = 2;
285 0c98da8b 2005-07-13 devnull else
286 0c98da8b 2005-07-13 devnull fs->groupaddr = 1;
287 0c98da8b 2005-07-13 devnull fs->descperblock = fs->blocksize / GroupSize;
288 83ab7d88 2007-11-27 rsc fs->firstblock = super.firstdatablock;
289 0c98da8b 2005-07-13 devnull
290 0c98da8b 2005-07-13 devnull fsys->blocksize = fs->blocksize;
291 0c98da8b 2005-07-13 devnull fsys->nblock = fs->nblock;
292 27c1d3a4 2007-05-28 devnull if(debug) fprint(2, "ext2 %d %d-byte blocks, first data block %d, %d groups of %d\n",
293 0c98da8b 2005-07-13 devnull fs->nblock, fs->blocksize, fs->firstblock, fs->ngroup, fs->blockspergroup);
294 0c98da8b 2005-07-13 devnull
295 0c98da8b 2005-07-13 devnull if(0){
296 0c98da8b 2005-07-13 devnull for(i=0; i<fs->ngroup; i++)
297 83ab7d88 2007-11-27 rsc if(ext2group(fs, i, &g) >= 0)
298 83ab7d88 2007-11-27 rsc fprint(2, "grp %d: bitblock=%d\n", i, g.bitblock);
299 0c98da8b 2005-07-13 devnull }
300 0c98da8b 2005-07-13 devnull return 0;
301 0c98da8b 2005-07-13 devnull }
302 0c98da8b 2005-07-13 devnull
303 0c98da8b 2005-07-13 devnull static void
304 0c98da8b 2005-07-13 devnull mkhandle(Nfs3Handle *h, u64int ino)
305 0c98da8b 2005-07-13 devnull {
306 0c98da8b 2005-07-13 devnull h->h[0] = ino>>24;
307 0c98da8b 2005-07-13 devnull h->h[1] = ino>>16;
308 0c98da8b 2005-07-13 devnull h->h[2] = ino>>8;
309 0c98da8b 2005-07-13 devnull h->h[3] = ino;
310 0c98da8b 2005-07-13 devnull h->len = 4;
311 0c98da8b 2005-07-13 devnull }
312 0c98da8b 2005-07-13 devnull
313 0c98da8b 2005-07-13 devnull static u32int
314 0c98da8b 2005-07-13 devnull byte2u32(uchar *p)
315 0c98da8b 2005-07-13 devnull {
316 0c98da8b 2005-07-13 devnull return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
317 0c98da8b 2005-07-13 devnull }
318 0c98da8b 2005-07-13 devnull
319 0c98da8b 2005-07-13 devnull static Nfs3Status
320 0c98da8b 2005-07-13 devnull handle2ino(Ext2 *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
321 0c98da8b 2005-07-13 devnull {
322 0c98da8b 2005-07-13 devnull int i;
323 0c98da8b 2005-07-13 devnull uint ioff;
324 0c98da8b 2005-07-13 devnull u32int inum;
325 0c98da8b 2005-07-13 devnull u32int addr;
326 83ab7d88 2007-11-27 rsc Block *b;
327 83ab7d88 2007-11-27 rsc Group g;
328 0c98da8b 2005-07-13 devnull
329 0c98da8b 2005-07-13 devnull if(h->len != 4)
330 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
331 0c98da8b 2005-07-13 devnull inum = byte2u32(h->h);
332 0c98da8b 2005-07-13 devnull if(pinum)
333 0c98da8b 2005-07-13 devnull *pinum = inum;
334 0c98da8b 2005-07-13 devnull i = (inum-1) / fs->inospergroup;
335 0c98da8b 2005-07-13 devnull if(i >= fs->ngroup)
336 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
337 0c98da8b 2005-07-13 devnull ioff = (inum-1) % fs->inospergroup;
338 83ab7d88 2007-11-27 rsc if(ext2group(fs, i, &g) < 0)
339 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
340 83ab7d88 2007-11-27 rsc addr = g.inodeaddr + ioff/fs->inosperblock;
341 0c98da8b 2005-07-13 devnull if((b = diskread(fs->disk, fs->blocksize, (u64int)addr*fs->blocksize)) == nil)
342 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
343 d29f5ece 2008-06-01 rsc parseinode(ino, b->data+fs->inosize*(ioff%fs->inosperblock));
344 0c98da8b 2005-07-13 devnull blockput(b);
345 0c98da8b 2005-07-13 devnull return Nfs3Ok;
346 0c98da8b 2005-07-13 devnull }
347 0c98da8b 2005-07-13 devnull
348 0c98da8b 2005-07-13 devnull static Nfs3Status
349 0c98da8b 2005-07-13 devnull ext2root(Fsys *fsys, Nfs3Handle *h)
350 0c98da8b 2005-07-13 devnull {
351 3330e5bf 2005-10-29 devnull USED(fsys);
352 0c98da8b 2005-07-13 devnull mkhandle(h, ROOTINODE);
353 0c98da8b 2005-07-13 devnull return Nfs3Ok;
354 b109049f 2007-03-25 devnull }
355 b109049f 2007-03-25 devnull
356 b109049f 2007-03-25 devnull static u64int
357 b109049f 2007-03-25 devnull inosize(Inode* ino)
358 b109049f 2007-03-25 devnull {
359 b109049f 2007-03-25 devnull u64int size;
360 b109049f 2007-03-25 devnull
361 b109049f 2007-03-25 devnull size = ino->size;
362 b109049f 2007-03-25 devnull if((ino->mode&IFMT)==IFREG)
363 b109049f 2007-03-25 devnull size |= (u64int)ino->diracl << 32;
364 b109049f 2007-03-25 devnull return size;
365 0c98da8b 2005-07-13 devnull }
366 0c98da8b 2005-07-13 devnull
367 0c98da8b 2005-07-13 devnull static Nfs3Status
368 0c98da8b 2005-07-13 devnull ino2attr(Ext2 *fs, Inode *ino, u32int inum, Nfs3Attr *attr)
369 0c98da8b 2005-07-13 devnull {
370 0c98da8b 2005-07-13 devnull u32int rdev;
371 0c98da8b 2005-07-13 devnull
372 0c98da8b 2005-07-13 devnull attr->type = -1;
373 0c98da8b 2005-07-13 devnull switch(ino->mode&IFMT){
374 0c98da8b 2005-07-13 devnull case IFIFO:
375 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileFifo;
376 0c98da8b 2005-07-13 devnull break;
377 0c98da8b 2005-07-13 devnull case IFCHR:
378 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileChar;
379 0c98da8b 2005-07-13 devnull break;
380 0c98da8b 2005-07-13 devnull case IFDIR:
381 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileDir;
382 0c98da8b 2005-07-13 devnull break;
383 0c98da8b 2005-07-13 devnull case IFBLK:
384 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileBlock;
385 0c98da8b 2005-07-13 devnull break;
386 0c98da8b 2005-07-13 devnull case IFREG:
387 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileReg;
388 0c98da8b 2005-07-13 devnull break;
389 0c98da8b 2005-07-13 devnull case IFLNK:
390 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileSymlink;
391 0c98da8b 2005-07-13 devnull break;
392 0c98da8b 2005-07-13 devnull case IFSOCK:
393 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileSocket;
394 0c98da8b 2005-07-13 devnull break;
395 0c98da8b 2005-07-13 devnull case IFWHT:
396 0c98da8b 2005-07-13 devnull default:
397 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
398 0c98da8b 2005-07-13 devnull }
399 0c98da8b 2005-07-13 devnull
400 0c98da8b 2005-07-13 devnull attr->mode = ino->mode&07777;
401 0c98da8b 2005-07-13 devnull attr->nlink = ino->nlink;
402 0c98da8b 2005-07-13 devnull attr->uid = ino->uid;
403 0c98da8b 2005-07-13 devnull attr->gid = ino->gid;
404 b109049f 2007-03-25 devnull attr->size = inosize(ino);
405 b109049f 2007-03-25 devnull attr->used = (u64int)ino->nblock*fs->blocksize;
406 0c98da8b 2005-07-13 devnull if(attr->type==Nfs3FileBlock || attr->type==Nfs3FileChar){
407 0c98da8b 2005-07-13 devnull rdev = ino->block[0];
408 0c98da8b 2005-07-13 devnull attr->major = (rdev>>8)&0xFF;
409 0c98da8b 2005-07-13 devnull attr->minor = rdev & 0xFFFF00FF;
410 0c98da8b 2005-07-13 devnull }else{
411 0c98da8b 2005-07-13 devnull attr->major = 0;
412 0c98da8b 2005-07-13 devnull attr->minor = 0;
413 0c98da8b 2005-07-13 devnull }
414 0c98da8b 2005-07-13 devnull attr->fsid = 0;
415 0c98da8b 2005-07-13 devnull attr->fileid = inum;
416 0c98da8b 2005-07-13 devnull attr->atime.sec = ino->atime;
417 0c98da8b 2005-07-13 devnull attr->atime.nsec = 0;
418 0c98da8b 2005-07-13 devnull attr->mtime.sec = ino->mtime;
419 0c98da8b 2005-07-13 devnull attr->mtime.nsec = 0;
420 0c98da8b 2005-07-13 devnull attr->ctime.sec = ino->ctime;
421 0c98da8b 2005-07-13 devnull attr->ctime.nsec = 0;
422 0c98da8b 2005-07-13 devnull return Nfs3Ok;
423 0c98da8b 2005-07-13 devnull }
424 0c98da8b 2005-07-13 devnull
425 0c98da8b 2005-07-13 devnull static int
426 0c98da8b 2005-07-13 devnull ingroup(SunAuthUnix *au, uint gid)
427 0c98da8b 2005-07-13 devnull {
428 0c98da8b 2005-07-13 devnull int i;
429 0c98da8b 2005-07-13 devnull
430 0c98da8b 2005-07-13 devnull for(i=0; i<au->ng; i++)
431 0c98da8b 2005-07-13 devnull if(au->g[i] == gid)
432 0c98da8b 2005-07-13 devnull return 1;
433 0c98da8b 2005-07-13 devnull return 0;
434 0c98da8b 2005-07-13 devnull }
435 0c98da8b 2005-07-13 devnull
436 0c98da8b 2005-07-13 devnull static Nfs3Status
437 0c98da8b 2005-07-13 devnull inoperm(Inode *ino, SunAuthUnix *au, int need)
438 0c98da8b 2005-07-13 devnull {
439 0c98da8b 2005-07-13 devnull int have;
440 0c98da8b 2005-07-13 devnull
441 0c98da8b 2005-07-13 devnull if(allowall)
442 0c98da8b 2005-07-13 devnull return Nfs3Ok;
443 0c98da8b 2005-07-13 devnull
444 0c98da8b 2005-07-13 devnull have = ino->mode&0777;
445 0c98da8b 2005-07-13 devnull if(ino->uid == au->uid)
446 0c98da8b 2005-07-13 devnull have >>= 6;
447 0c98da8b 2005-07-13 devnull else if(ino->gid == au->gid || ingroup(au, ino->gid))
448 0c98da8b 2005-07-13 devnull have >>= 3;
449 0c98da8b 2005-07-13 devnull
450 0c98da8b 2005-07-13 devnull if((have&need) != need)
451 0c98da8b 2005-07-13 devnull return Nfs3ErrNotOwner; /* really EPERM */
452 0c98da8b 2005-07-13 devnull return Nfs3Ok;
453 0c98da8b 2005-07-13 devnull }
454 0c98da8b 2005-07-13 devnull
455 0c98da8b 2005-07-13 devnull static Nfs3Status
456 0c98da8b 2005-07-13 devnull ext2getattr(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
457 0c98da8b 2005-07-13 devnull {
458 0c98da8b 2005-07-13 devnull Inode ino;
459 0c98da8b 2005-07-13 devnull u32int inum;
460 0c98da8b 2005-07-13 devnull Ext2 *fs;
461 0c98da8b 2005-07-13 devnull Nfs3Status ok;
462 0c98da8b 2005-07-13 devnull
463 0c98da8b 2005-07-13 devnull fs = fsys->priv;
464 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
465 0c98da8b 2005-07-13 devnull return ok;
466 0c98da8b 2005-07-13 devnull
467 0c98da8b 2005-07-13 devnull USED(au); /* anyone can getattr */
468 0c98da8b 2005-07-13 devnull return ino2attr(fs, &ino, inum, attr);
469 0c98da8b 2005-07-13 devnull }
470 0c98da8b 2005-07-13 devnull
471 0c98da8b 2005-07-13 devnull static Nfs3Status
472 0c98da8b 2005-07-13 devnull ext2access(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
473 0c98da8b 2005-07-13 devnull {
474 0c98da8b 2005-07-13 devnull int have;
475 0c98da8b 2005-07-13 devnull Inode ino;
476 0c98da8b 2005-07-13 devnull u32int inum;
477 0c98da8b 2005-07-13 devnull Ext2 *fs;
478 0c98da8b 2005-07-13 devnull Nfs3Status ok;
479 0c98da8b 2005-07-13 devnull
480 0c98da8b 2005-07-13 devnull fs = fsys->priv;
481 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
482 0c98da8b 2005-07-13 devnull return ok;
483 0c98da8b 2005-07-13 devnull
484 0c98da8b 2005-07-13 devnull have = ino.mode&0777;
485 0c98da8b 2005-07-13 devnull if(ino.uid == au->uid)
486 0c98da8b 2005-07-13 devnull have >>= 6;
487 0c98da8b 2005-07-13 devnull else if(ino.gid == au->gid || ingroup(au, ino.gid))
488 0c98da8b 2005-07-13 devnull have >>= 3;
489 0c98da8b 2005-07-13 devnull
490 0c98da8b 2005-07-13 devnull *got = 0;
491 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessRead) && (have&AREAD))
492 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessRead;
493 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessLookup) && (ino.mode&IFMT)==IFDIR && (have&AEXEC))
494 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessLookup;
495 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessExecute) && (ino.mode&IFMT)!=IFDIR && (have&AEXEC))
496 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessExecute;
497 0c98da8b 2005-07-13 devnull
498 0c98da8b 2005-07-13 devnull return ino2attr(fs, &ino, inum, attr);
499 0c98da8b 2005-07-13 devnull }
500 0c98da8b 2005-07-13 devnull
501 0c98da8b 2005-07-13 devnull static Nfs3Status
502 0c98da8b 2005-07-13 devnull ext2lookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
503 0c98da8b 2005-07-13 devnull {
504 0c98da8b 2005-07-13 devnull u32int nblock;
505 0c98da8b 2005-07-13 devnull u32int i;
506 0c98da8b 2005-07-13 devnull uchar *p, *ep;
507 83ab7d88 2007-11-27 rsc Dirent de;
508 0c98da8b 2005-07-13 devnull Inode ino;
509 0c98da8b 2005-07-13 devnull Block *b;
510 0c98da8b 2005-07-13 devnull Ext2 *fs;
511 0c98da8b 2005-07-13 devnull Nfs3Status ok;
512 0c98da8b 2005-07-13 devnull int len, want;
513 0c98da8b 2005-07-13 devnull
514 0c98da8b 2005-07-13 devnull fs = fsys->priv;
515 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
516 0c98da8b 2005-07-13 devnull return ok;
517 0c98da8b 2005-07-13 devnull
518 0c98da8b 2005-07-13 devnull if((ino.mode&IFMT) != IFDIR)
519 0c98da8b 2005-07-13 devnull return Nfs3ErrNotDir;
520 0c98da8b 2005-07-13 devnull
521 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AEXEC)) != Nfs3Ok)
522 0c98da8b 2005-07-13 devnull return ok;
523 0c98da8b 2005-07-13 devnull
524 0c98da8b 2005-07-13 devnull len = strlen(name);
525 0c98da8b 2005-07-13 devnull nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
526 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "%d blocks in dir...", nblock);
527 0c98da8b 2005-07-13 devnull for(i=0; i<nblock; i++){
528 0c98da8b 2005-07-13 devnull if(i==nblock-1)
529 0c98da8b 2005-07-13 devnull want = ino.size % fs->blocksize;
530 0c98da8b 2005-07-13 devnull else
531 0c98da8b 2005-07-13 devnull want = fs->blocksize;
532 0c98da8b 2005-07-13 devnull b = ext2fileblock(fs, &ino, i, want);
533 0c98da8b 2005-07-13 devnull if(b == nil){
534 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "empty block...");
535 0c98da8b 2005-07-13 devnull continue;
536 0c98da8b 2005-07-13 devnull }
537 0c98da8b 2005-07-13 devnull p = b->data;
538 0c98da8b 2005-07-13 devnull ep = p+b->len;
539 0c98da8b 2005-07-13 devnull while(p < ep){
540 83ab7d88 2007-11-27 rsc parsedirent(&de, p);
541 83ab7d88 2007-11-27 rsc if(de.reclen == 0){
542 0c98da8b 2005-07-13 devnull if(debug)
543 0c98da8b 2005-07-13 devnull fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
544 0c98da8b 2005-07-13 devnull break;
545 0c98da8b 2005-07-13 devnull }
546 83ab7d88 2007-11-27 rsc p += de.reclen;
547 0c98da8b 2005-07-13 devnull if(p > ep){
548 0c98da8b 2005-07-13 devnull if(debug)
549 83ab7d88 2007-11-27 rsc fprint(2, "bad len %d at offset %d of %d\n", de.reclen, (int)(p-b->data), b->len);
550 0c98da8b 2005-07-13 devnull break;
551 0c98da8b 2005-07-13 devnull }
552 83ab7d88 2007-11-27 rsc if(de.ino == 0)
553 0c98da8b 2005-07-13 devnull continue;
554 83ab7d88 2007-11-27 rsc if(4+2+2+de.namlen > de.reclen){
555 0c98da8b 2005-07-13 devnull if(debug)
556 83ab7d88 2007-11-27 rsc fprint(2, "bad namelen %d at offset %d of %d\n", de.namlen, (int)(p-b->data), b->len);
557 0c98da8b 2005-07-13 devnull break;
558 0c98da8b 2005-07-13 devnull }
559 83ab7d88 2007-11-27 rsc if(de.namlen == len && memcmp(de.name, name, len) == 0){
560 83ab7d88 2007-11-27 rsc mkhandle(nh, de.ino);
561 0c98da8b 2005-07-13 devnull blockput(b);
562 0c98da8b 2005-07-13 devnull return Nfs3Ok;
563 0c98da8b 2005-07-13 devnull }
564 0c98da8b 2005-07-13 devnull }
565 0c98da8b 2005-07-13 devnull blockput(b);
566 0c98da8b 2005-07-13 devnull }
567 0c98da8b 2005-07-13 devnull return Nfs3ErrNoEnt;
568 0c98da8b 2005-07-13 devnull }
569 0c98da8b 2005-07-13 devnull
570 0c98da8b 2005-07-13 devnull static Nfs3Status
571 0c98da8b 2005-07-13 devnull ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
572 0c98da8b 2005-07-13 devnull {
573 0c98da8b 2005-07-13 devnull u32int nblock;
574 0c98da8b 2005-07-13 devnull u32int i;
575 52abe8e1 2008-01-12 rsc int off, outofspace;
576 0c98da8b 2005-07-13 devnull uchar *data, *dp, *dep, *p, *ep, *ndp;
577 83ab7d88 2007-11-27 rsc Dirent de;
578 0c98da8b 2005-07-13 devnull Inode ino;
579 0c98da8b 2005-07-13 devnull Block *b;
580 0c98da8b 2005-07-13 devnull Ext2 *fs;
581 0c98da8b 2005-07-13 devnull Nfs3Status ok;
582 0c98da8b 2005-07-13 devnull Nfs3Entry e;
583 0c98da8b 2005-07-13 devnull int want;
584 0c98da8b 2005-07-13 devnull
585 0c98da8b 2005-07-13 devnull fs = fsys->priv;
586 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
587 0c98da8b 2005-07-13 devnull return ok;
588 0c98da8b 2005-07-13 devnull
589 0c98da8b 2005-07-13 devnull if((ino.mode&IFMT) != IFDIR)
590 0c98da8b 2005-07-13 devnull return Nfs3ErrNotDir;
591 0c98da8b 2005-07-13 devnull
592 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
593 0c98da8b 2005-07-13 devnull return ok;
594 0c98da8b 2005-07-13 devnull
595 fa325e9b 2020-01-10 cross if(debug) print("readdir cookie %#llux ino.size %#llux\n",
596 52abe8e1 2008-01-12 rsc (u64int)cookie, (u64int)ino.size);
597 52abe8e1 2008-01-12 rsc
598 0c98da8b 2005-07-13 devnull if(cookie >= ino.size){
599 63408c39 2007-06-08 devnull *peof = 1;
600 0c98da8b 2005-07-13 devnull *pcount = 0;
601 0c98da8b 2005-07-13 devnull *pdata = 0;
602 0c98da8b 2005-07-13 devnull return Nfs3Ok;
603 0c98da8b 2005-07-13 devnull }
604 0c98da8b 2005-07-13 devnull
605 0c98da8b 2005-07-13 devnull dp = malloc(count);
606 0c98da8b 2005-07-13 devnull data = dp;
607 0c98da8b 2005-07-13 devnull if(dp == nil)
608 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
609 0c98da8b 2005-07-13 devnull dep = dp+count;
610 0c98da8b 2005-07-13 devnull *peof = 0;
611 0c98da8b 2005-07-13 devnull nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
612 0c98da8b 2005-07-13 devnull i = cookie/fs->blocksize;
613 0c98da8b 2005-07-13 devnull off = cookie%fs->blocksize;
614 52abe8e1 2008-01-12 rsc outofspace = 0;
615 52abe8e1 2008-01-12 rsc for(; i<nblock && !outofspace; i++, off=0){
616 0c98da8b 2005-07-13 devnull if(i==nblock-1)
617 0c98da8b 2005-07-13 devnull want = ino.size % fs->blocksize;
618 0c98da8b 2005-07-13 devnull else
619 0c98da8b 2005-07-13 devnull want = fs->blocksize;
620 0c98da8b 2005-07-13 devnull b = ext2fileblock(fs, &ino, i, want);
621 0c98da8b 2005-07-13 devnull if(b == nil)
622 0c98da8b 2005-07-13 devnull continue;
623 0c98da8b 2005-07-13 devnull p = b->data;
624 0c98da8b 2005-07-13 devnull ep = p+b->len;
625 0c98da8b 2005-07-13 devnull memset(&e, 0, sizeof e);
626 0c98da8b 2005-07-13 devnull while(p < ep){
627 83ab7d88 2007-11-27 rsc parsedirent(&de, p);
628 83ab7d88 2007-11-27 rsc if(de.reclen == 0){
629 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
630 0c98da8b 2005-07-13 devnull break;
631 0c98da8b 2005-07-13 devnull }
632 83ab7d88 2007-11-27 rsc p += de.reclen;
633 0c98da8b 2005-07-13 devnull if(p > ep){
634 83ab7d88 2007-11-27 rsc if(debug) fprint(2, "reclen %d at offset %d of %d\n", de.reclen, (int)(p-b->data), b->len);
635 0c98da8b 2005-07-13 devnull break;
636 0c98da8b 2005-07-13 devnull }
637 83ab7d88 2007-11-27 rsc if(de.ino == 0){
638 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "zero inode\n");
639 0c98da8b 2005-07-13 devnull continue;
640 0c98da8b 2005-07-13 devnull }
641 83ab7d88 2007-11-27 rsc if(4+2+2+de.namlen > de.reclen){
642 83ab7d88 2007-11-27 rsc if(debug) fprint(2, "bad namlen %d reclen %d at offset %d of %d\n", de.namlen, de.reclen, (int)(p-b->data), b->len);
643 0c98da8b 2005-07-13 devnull break;
644 0c98da8b 2005-07-13 devnull }
645 83ab7d88 2007-11-27 rsc if(debug) print("%.*s/%d ", de.namlen, de.name, (int)de.ino);
646 83ab7d88 2007-11-27 rsc if(p-de.reclen - b->data < off)
647 0c98da8b 2005-07-13 devnull continue;
648 83ab7d88 2007-11-27 rsc e.fileid = de.ino;
649 83ab7d88 2007-11-27 rsc e.name = de.name;
650 83ab7d88 2007-11-27 rsc e.namelen = de.namlen;
651 0c98da8b 2005-07-13 devnull e.cookie = (u64int)i*fs->blocksize + (p - b->data);
652 52abe8e1 2008-01-12 rsc if(debug) print("%.*s %#llux\n", utfnlen(e.name, e.namelen), e.name, (u64int)e.cookie);
653 0c98da8b 2005-07-13 devnull if(nfs3entrypack(dp, dep, &ndp, &e) < 0){
654 52abe8e1 2008-01-12 rsc outofspace = 1;
655 0c98da8b 2005-07-13 devnull break;
656 0c98da8b 2005-07-13 devnull }
657 0c98da8b 2005-07-13 devnull dp = ndp;
658 0c98da8b 2005-07-13 devnull }
659 0c98da8b 2005-07-13 devnull blockput(b);
660 0c98da8b 2005-07-13 devnull }
661 52abe8e1 2008-01-12 rsc if(i==nblock && !outofspace)
662 0c98da8b 2005-07-13 devnull *peof = 1;
663 0c98da8b 2005-07-13 devnull
664 0c98da8b 2005-07-13 devnull *pcount = dp - data;
665 0c98da8b 2005-07-13 devnull *pdata = data;
666 0c98da8b 2005-07-13 devnull return Nfs3Ok;
667 0c98da8b 2005-07-13 devnull }
668 0c98da8b 2005-07-13 devnull
669 0c98da8b 2005-07-13 devnull static Nfs3Status
670 0c98da8b 2005-07-13 devnull ext2readfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
671 0c98da8b 2005-07-13 devnull u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
672 0c98da8b 2005-07-13 devnull {
673 0c98da8b 2005-07-13 devnull uchar *data;
674 0c98da8b 2005-07-13 devnull Block *b;
675 0c98da8b 2005-07-13 devnull Ext2 *fs;
676 fa5af687 2006-06-15 devnull int skip1, tot, want, fragcount;
677 0c98da8b 2005-07-13 devnull Inode ino;
678 0c98da8b 2005-07-13 devnull Nfs3Status ok;
679 b109049f 2007-03-25 devnull u64int size;
680 0c98da8b 2005-07-13 devnull
681 0c98da8b 2005-07-13 devnull fs = fsys->priv;
682 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
683 0c98da8b 2005-07-13 devnull return ok;
684 0c98da8b 2005-07-13 devnull
685 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
686 0c98da8b 2005-07-13 devnull return ok;
687 0c98da8b 2005-07-13 devnull
688 b109049f 2007-03-25 devnull size = inosize(&ino);
689 b109049f 2007-03-25 devnull if(offset >= size){
690 0c98da8b 2005-07-13 devnull *pdata = 0;
691 0c98da8b 2005-07-13 devnull *pcount = 0;
692 0c98da8b 2005-07-13 devnull *peof = 1;
693 0c98da8b 2005-07-13 devnull return Nfs3Ok;
694 0c98da8b 2005-07-13 devnull }
695 b109049f 2007-03-25 devnull if(offset+count > size)
696 b109049f 2007-03-25 devnull count = size-offset;
697 0c98da8b 2005-07-13 devnull
698 0c98da8b 2005-07-13 devnull data = malloc(count);
699 0c98da8b 2005-07-13 devnull if(data == nil)
700 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
701 fa5af687 2006-06-15 devnull memset(data, 0, count);
702 0c98da8b 2005-07-13 devnull
703 fa5af687 2006-06-15 devnull skip1 = offset%fs->blocksize;
704 fa5af687 2006-06-15 devnull offset -= skip1;
705 fa5af687 2006-06-15 devnull want = skip1+count;
706 0c98da8b 2005-07-13 devnull
707 fa5af687 2006-06-15 devnull /*
708 fa5af687 2006-06-15 devnull * have to read multiple blocks if we get asked for a big read.
709 fa5af687 2006-06-15 devnull * Linux NFS client assumes that if you ask for 8k and only get 4k
710 fa5af687 2006-06-15 devnull * back, the remaining 4k is zeros.
711 fa5af687 2006-06-15 devnull */
712 fa5af687 2006-06-15 devnull for(tot=0; tot<want; tot+=fragcount){
713 fa5af687 2006-06-15 devnull b = ext2fileblock(fs, &ino, (offset+tot)/fs->blocksize, fs->blocksize);
714 fa5af687 2006-06-15 devnull fragcount = fs->blocksize;
715 fa5af687 2006-06-15 devnull if(b == nil)
716 fa5af687 2006-06-15 devnull continue;
717 fa5af687 2006-06-15 devnull if(tot+fragcount > want)
718 fa5af687 2006-06-15 devnull fragcount = want - tot;
719 fa5af687 2006-06-15 devnull if(tot == 0)
720 fa5af687 2006-06-15 devnull memmove(data, b->data+skip1, fragcount-skip1);
721 fa5af687 2006-06-15 devnull else
722 fa5af687 2006-06-15 devnull memmove(data+tot-skip1, b->data, fragcount);
723 0c98da8b 2005-07-13 devnull blockput(b);
724 0c98da8b 2005-07-13 devnull }
725 fa5af687 2006-06-15 devnull count = tot - skip1;
726 fa5af687 2006-06-15 devnull
727 b109049f 2007-03-25 devnull *peof = (offset+count == size);
728 0c98da8b 2005-07-13 devnull *pcount = count;
729 0c98da8b 2005-07-13 devnull *pdata = data;
730 0c98da8b 2005-07-13 devnull return Nfs3Ok;
731 0c98da8b 2005-07-13 devnull }
732 0c98da8b 2005-07-13 devnull
733 0c98da8b 2005-07-13 devnull static Nfs3Status
734 0c98da8b 2005-07-13 devnull ext2readlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
735 0c98da8b 2005-07-13 devnull {
736 0c98da8b 2005-07-13 devnull Ext2 *fs;
737 0c98da8b 2005-07-13 devnull Nfs3Status ok;
738 0c98da8b 2005-07-13 devnull int len;
739 0c98da8b 2005-07-13 devnull Inode ino;
740 0c98da8b 2005-07-13 devnull Block *b;
741 0c98da8b 2005-07-13 devnull
742 0c98da8b 2005-07-13 devnull fs = fsys->priv;
743 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
744 0c98da8b 2005-07-13 devnull return ok;
745 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
746 0c98da8b 2005-07-13 devnull return ok;
747 0c98da8b 2005-07-13 devnull
748 0c98da8b 2005-07-13 devnull if(ino.size > 1024)
749 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
750 0c98da8b 2005-07-13 devnull len = ino.size;
751 0c98da8b 2005-07-13 devnull
752 0c98da8b 2005-07-13 devnull if(ino.nblock != 0){
753 0c98da8b 2005-07-13 devnull /* BUG: assumes symlink fits in one block */
754 0c98da8b 2005-07-13 devnull b = ext2fileblock(fs, &ino, 0, len);
755 0c98da8b 2005-07-13 devnull if(b == nil)
756 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
757 0c98da8b 2005-07-13 devnull if(memchr(b->data, 0, len) != nil){
758 0c98da8b 2005-07-13 devnull blockput(b);
759 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
760 0c98da8b 2005-07-13 devnull }
761 0c98da8b 2005-07-13 devnull *link = malloc(len+1);
762 0c98da8b 2005-07-13 devnull if(*link == 0){
763 0c98da8b 2005-07-13 devnull blockput(b);
764 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
765 0c98da8b 2005-07-13 devnull }
766 0c98da8b 2005-07-13 devnull memmove(*link, b->data, len);
767 0c98da8b 2005-07-13 devnull (*link)[len] = 0;
768 0c98da8b 2005-07-13 devnull blockput(b);
769 0c98da8b 2005-07-13 devnull return Nfs3Ok;
770 0c98da8b 2005-07-13 devnull }
771 0c98da8b 2005-07-13 devnull
772 0c98da8b 2005-07-13 devnull if(len > sizeof ino.block)
773 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
774 0c98da8b 2005-07-13 devnull
775 0c98da8b 2005-07-13 devnull *link = malloc(len+1);
776 0c98da8b 2005-07-13 devnull if(*link == 0)
777 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
778 0c98da8b 2005-07-13 devnull memmove(*link, ino.block, ino.size);
779 0c98da8b 2005-07-13 devnull (*link)[len] = 0;
780 0c98da8b 2005-07-13 devnull return Nfs3Ok;
781 0c98da8b 2005-07-13 devnull }
782 0c98da8b 2005-07-13 devnull
783 83ab7d88 2007-11-27 rsc /*
784 83ab7d88 2007-11-27 rsc * Ext2 is always little-endian, even on big-endian machines.
785 83ab7d88 2007-11-27 rsc */
786 83ab7d88 2007-11-27 rsc
787 83ab7d88 2007-11-27 rsc static u32int
788 83ab7d88 2007-11-27 rsc l32(uchar *p)
789 83ab7d88 2007-11-27 rsc {
790 83ab7d88 2007-11-27 rsc return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
791 83ab7d88 2007-11-27 rsc }
792 83ab7d88 2007-11-27 rsc
793 83ab7d88 2007-11-27 rsc static u16int
794 83ab7d88 2007-11-27 rsc l16(uchar *p)
795 83ab7d88 2007-11-27 rsc {
796 83ab7d88 2007-11-27 rsc return p[0] | (p[1]<<8);
797 83ab7d88 2007-11-27 rsc }
798 83ab7d88 2007-11-27 rsc
799 83ab7d88 2007-11-27 rsc static u8int
800 83ab7d88 2007-11-27 rsc l8(uchar *p)
801 83ab7d88 2007-11-27 rsc {
802 83ab7d88 2007-11-27 rsc return p[0];
803 83ab7d88 2007-11-27 rsc }
804 83ab7d88 2007-11-27 rsc
805 83ab7d88 2007-11-27 rsc static void
806 83ab7d88 2007-11-27 rsc parsedirent(Dirent *de, uchar *p)
807 83ab7d88 2007-11-27 rsc {
808 83ab7d88 2007-11-27 rsc de->ino = l32(p);
809 83ab7d88 2007-11-27 rsc de->reclen = l16(p+4);
810 83ab7d88 2007-11-27 rsc de->namlen = l8(p+6);
811 83ab7d88 2007-11-27 rsc /* 1 byte pad */
812 83ab7d88 2007-11-27 rsc de->name = (char*)p+8;
813 83ab7d88 2007-11-27 rsc }
814 83ab7d88 2007-11-27 rsc
815 83ab7d88 2007-11-27 rsc static void
816 83ab7d88 2007-11-27 rsc parseinode(Inode *ino, uchar *p)
817 83ab7d88 2007-11-27 rsc {
818 83ab7d88 2007-11-27 rsc int i;
819 83ab7d88 2007-11-27 rsc
820 83ab7d88 2007-11-27 rsc ino->mode = l16(p);
821 83ab7d88 2007-11-27 rsc ino->uid = l16(p+2);
822 83ab7d88 2007-11-27 rsc ino->size = l32(p+4);
823 83ab7d88 2007-11-27 rsc ino->atime = l32(p+8);
824 83ab7d88 2007-11-27 rsc ino->ctime = l32(p+12);
825 83ab7d88 2007-11-27 rsc ino->mtime = l32(p+16);
826 83ab7d88 2007-11-27 rsc ino->dtime = l32(p+20);
827 83ab7d88 2007-11-27 rsc ino->gid = l16(p+24);
828 83ab7d88 2007-11-27 rsc ino->nlink = l16(p+26);
829 83ab7d88 2007-11-27 rsc ino->nblock = l32(p+28);
830 83ab7d88 2007-11-27 rsc ino->flags = l32(p+32);
831 83ab7d88 2007-11-27 rsc /* 4 byte osd1 */
832 83ab7d88 2007-11-27 rsc for(i=0; i<NBLOCKS; i++)
833 83ab7d88 2007-11-27 rsc ino->block[i] = l32(p+40+i*4);
834 83ab7d88 2007-11-27 rsc ino->version = l32(p+100);
835 83ab7d88 2007-11-27 rsc ino->fileacl = l32(p+104);
836 83ab7d88 2007-11-27 rsc ino->diracl = l32(p+108);
837 83ab7d88 2007-11-27 rsc ino->faddr = l32(p+112);
838 83ab7d88 2007-11-27 rsc /* 12 byte osd2 */
839 83ab7d88 2007-11-27 rsc }
840 83ab7d88 2007-11-27 rsc
841 83ab7d88 2007-11-27 rsc static void
842 83ab7d88 2007-11-27 rsc parsegroup(Group *g, uchar *p)
843 83ab7d88 2007-11-27 rsc {
844 83ab7d88 2007-11-27 rsc g->bitblock = l32(p);
845 83ab7d88 2007-11-27 rsc g->inodebitblock = l32(p+4);
846 83ab7d88 2007-11-27 rsc g->inodeaddr = l32(p+8);
847 83ab7d88 2007-11-27 rsc g->freeblockscount = l16(p+12);
848 83ab7d88 2007-11-27 rsc g->freeinodescount = l16(p+14);
849 83ab7d88 2007-11-27 rsc g->useddirscount = l16(p+16);
850 83ab7d88 2007-11-27 rsc /* 2 byte pad */
851 83ab7d88 2007-11-27 rsc /* 12 byte reserved */
852 83ab7d88 2007-11-27 rsc }
853 83ab7d88 2007-11-27 rsc
854 83ab7d88 2007-11-27 rsc static void
855 83ab7d88 2007-11-27 rsc parsesuper(Super *s, uchar *p)
856 83ab7d88 2007-11-27 rsc {
857 83ab7d88 2007-11-27 rsc s->ninode = l32(p);
858 83ab7d88 2007-11-27 rsc s->nblock = l32(p+4);
859 83ab7d88 2007-11-27 rsc s->rblockcount = l32(p+8);
860 83ab7d88 2007-11-27 rsc s->freeblockcount = l32(p+12);
861 83ab7d88 2007-11-27 rsc s->freeinodecount = l32(p+16);
862 83ab7d88 2007-11-27 rsc s->firstdatablock = l32(p+20);
863 83ab7d88 2007-11-27 rsc s->logblocksize = l32(p+24);
864 83ab7d88 2007-11-27 rsc s->logfragsize = l32(p+28);
865 83ab7d88 2007-11-27 rsc s->blockspergroup = l32(p+32);
866 83ab7d88 2007-11-27 rsc s->fragpergroup = l32(p+36);
867 83ab7d88 2007-11-27 rsc s->inospergroup = l32(p+40);
868 83ab7d88 2007-11-27 rsc s->mtime = l32(p+44);
869 83ab7d88 2007-11-27 rsc s->wtime = l32(p+48);
870 83ab7d88 2007-11-27 rsc s->mntcount = l16(p+52);
871 83ab7d88 2007-11-27 rsc s->maxmntcount = l16(p+54);
872 83ab7d88 2007-11-27 rsc s->magic = l16(p+56);
873 83ab7d88 2007-11-27 rsc s->state = l16(p+58);
874 83ab7d88 2007-11-27 rsc s->errors = l16(p+60);
875 83ab7d88 2007-11-27 rsc /* 2 byte pad */
876 83ab7d88 2007-11-27 rsc s->lastcheck = l32(p+64);
877 83ab7d88 2007-11-27 rsc s->checkinterval = l32(p+68);
878 83ab7d88 2007-11-27 rsc s->creatoros = l32(p+72);
879 83ab7d88 2007-11-27 rsc s->revlevel = l32(p+76);
880 83ab7d88 2007-11-27 rsc s->defresuid = l16(p+80);
881 83ab7d88 2007-11-27 rsc s->defresgid = l16(p+82);
882 d29f5ece 2008-06-01 rsc s->firstino = l32(p+84);
883 d29f5ece 2008-06-01 rsc s->inosize = l32(p+88);
884 d29f5ece 2008-06-01 rsc s->blockgroupnr = l16(p+60);
885 d29f5ece 2008-06-01 rsc /* 932 byte reserved */
886 83ab7d88 2007-11-27 rsc }