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 "ffs.h"
8 0c98da8b 2005-07-13 devnull
9 e060bc52 2005-08-11 devnull #define BADBNO ((u64int)~0ULL)
10 e060bc52 2005-08-11 devnull
11 0c98da8b 2005-07-13 devnull #define checkcg 0
12 0c98da8b 2005-07-13 devnull #define debug 0
13 0c98da8b 2005-07-13 devnull
14 0c98da8b 2005-07-13 devnull static int checkfsblk(Fsblk*);
15 0c98da8b 2005-07-13 devnull static int checkcgblk(Cgblk*);
16 0c98da8b 2005-07-13 devnull static Block *ffsblockread(Fsys*, u64int);
17 0c98da8b 2005-07-13 devnull static int ffssync(Fsys*);
18 0c98da8b 2005-07-13 devnull static void ffsclose(Fsys*);
19 0c98da8b 2005-07-13 devnull
20 9f4a65a0 2005-07-28 devnull static u64int ffsxfileblock(Fsys *fs, Nfs3Handle *h, u64int offset);
21 0c98da8b 2005-07-13 devnull static Nfs3Status ffsroot(Fsys*, Nfs3Handle*);
22 0c98da8b 2005-07-13 devnull static Nfs3Status ffsgetattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
23 0c98da8b 2005-07-13 devnull static Nfs3Status ffslookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
24 0c98da8b 2005-07-13 devnull static Nfs3Status ffsreadfile(Fsys*, SunAuthUnix *au, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
25 0c98da8b 2005-07-13 devnull static Nfs3Status ffsreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link);
26 0c98da8b 2005-07-13 devnull static Nfs3Status ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
27 0c98da8b 2005-07-13 devnull static Nfs3Status ffsaccess(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr);
28 0c98da8b 2005-07-13 devnull
29 0c98da8b 2005-07-13 devnull Fsys*
30 0c98da8b 2005-07-13 devnull fsysopenffs(Disk *disk)
31 0c98da8b 2005-07-13 devnull {
32 0c98da8b 2005-07-13 devnull Ffs *fs;
33 0c98da8b 2005-07-13 devnull Fsys *fsys;
34 0c98da8b 2005-07-13 devnull
35 0c98da8b 2005-07-13 devnull fsys = emalloc(sizeof(Fsys));
36 0c98da8b 2005-07-13 devnull fs = emalloc(sizeof(Ffs));
37 0c98da8b 2005-07-13 devnull fs->disk = disk;
38 0c98da8b 2005-07-13 devnull fsys->priv = fs;
39 0c98da8b 2005-07-13 devnull fsys->type = "ffs";
40 0c98da8b 2005-07-13 devnull fsys->_readblock = ffsblockread;
41 0c98da8b 2005-07-13 devnull fsys->_sync = ffssync;
42 0c98da8b 2005-07-13 devnull fsys->_root = ffsroot;
43 0c98da8b 2005-07-13 devnull fsys->_getattr = ffsgetattr;
44 0c98da8b 2005-07-13 devnull fsys->_access = ffsaccess;
45 0c98da8b 2005-07-13 devnull fsys->_lookup = ffslookup;
46 0c98da8b 2005-07-13 devnull fsys->_readfile = ffsreadfile;
47 0c98da8b 2005-07-13 devnull fsys->_readlink = ffsreadlink;
48 0c98da8b 2005-07-13 devnull fsys->_readdir = ffsreaddir;
49 6fc7da3c 2006-10-19 devnull fsys->_close = ffsclose;
50 9f4a65a0 2005-07-28 devnull fsys->fileblock = ffsxfileblock;
51 0c98da8b 2005-07-13 devnull
52 0c98da8b 2005-07-13 devnull if(ffssync(fsys) < 0)
53 0c98da8b 2005-07-13 devnull goto error;
54 0c98da8b 2005-07-13 devnull
55 0c98da8b 2005-07-13 devnull return fsys;
56 0c98da8b 2005-07-13 devnull
57 0c98da8b 2005-07-13 devnull error:
58 0c98da8b 2005-07-13 devnull ffsclose(fsys);
59 0c98da8b 2005-07-13 devnull return nil;
60 0c98da8b 2005-07-13 devnull }
61 0c98da8b 2005-07-13 devnull
62 0c98da8b 2005-07-13 devnull static Cgblk*
63 e060bc52 2005-08-11 devnull ffscylgrp(Ffs *fs, u32int i, Block **pb)
64 0c98da8b 2005-07-13 devnull {
65 0c98da8b 2005-07-13 devnull Block *b;
66 0c98da8b 2005-07-13 devnull Cgblk *cg;
67 0c98da8b 2005-07-13 devnull
68 0c98da8b 2005-07-13 devnull if(i >= fs->ncg)
69 0c98da8b 2005-07-13 devnull return nil;
70 0c98da8b 2005-07-13 devnull
71 0c98da8b 2005-07-13 devnull b = diskread(fs->disk, fs->blocksize, (u64int)fs->cg[i].cgblkno*fs->blocksize);
72 0c98da8b 2005-07-13 devnull if(b == nil)
73 0c98da8b 2005-07-13 devnull return nil;
74 0c98da8b 2005-07-13 devnull cg = (Cgblk*)b->data;
75 0c98da8b 2005-07-13 devnull if(checkcgblk(cg) < 0){
76 0c98da8b 2005-07-13 devnull fprint(2, "checkcgblk %d %lud: %r\n", i, (ulong)fs->cg[i].cgblkno);
77 0c98da8b 2005-07-13 devnull blockput(b);
78 0c98da8b 2005-07-13 devnull return nil;
79 0c98da8b 2005-07-13 devnull }
80 0c98da8b 2005-07-13 devnull *pb = b;
81 0c98da8b 2005-07-13 devnull return cg;
82 0c98da8b 2005-07-13 devnull }
83 0c98da8b 2005-07-13 devnull
84 0c98da8b 2005-07-13 devnull static int
85 0c98da8b 2005-07-13 devnull ffssync(Fsys *fsys)
86 0c98da8b 2005-07-13 devnull {
87 0c98da8b 2005-07-13 devnull int i;
88 e060bc52 2005-08-11 devnull int off[] = { SBOFF, SBOFF2, SBOFFPIGGY };
89 0c98da8b 2005-07-13 devnull Block *b, *cgb;
90 0c98da8b 2005-07-13 devnull Cgblk *cgblk;
91 0c98da8b 2005-07-13 devnull Cylgrp *cg;
92 0c98da8b 2005-07-13 devnull Disk *disk;
93 0c98da8b 2005-07-13 devnull Ffs *fs;
94 0c98da8b 2005-07-13 devnull Fsblk *fsblk;
95 0c98da8b 2005-07-13 devnull
96 0c98da8b 2005-07-13 devnull fs = fsys->priv;
97 0c98da8b 2005-07-13 devnull disk = fs->disk;
98 0c98da8b 2005-07-13 devnull
99 0c98da8b 2005-07-13 devnull /*
100 0c98da8b 2005-07-13 devnull * Read super block.
101 0c98da8b 2005-07-13 devnull */
102 9614b46f 2005-10-29 devnull b = nil;
103 e060bc52 2005-08-11 devnull for(i=0; i<nelem(off); i++){
104 e060bc52 2005-08-11 devnull if((b = diskread(disk, SBSIZE, off[i])) == nil)
105 e060bc52 2005-08-11 devnull goto error;
106 e060bc52 2005-08-11 devnull fsblk = (Fsblk*)b->data;
107 6802a899 2006-04-28 devnull // fprint(2, "offset of magic: %ld\n", offsetof(Fsblk, magic));
108 e060bc52 2005-08-11 devnull if((fs->ufs = checkfsblk(fsblk)) > 0)
109 e060bc52 2005-08-11 devnull goto okay;
110 e060bc52 2005-08-11 devnull blockput(b);
111 5e084a4a 2006-04-28 devnull b = nil;
112 e060bc52 2005-08-11 devnull }
113 e060bc52 2005-08-11 devnull goto error;
114 0c98da8b 2005-07-13 devnull
115 e060bc52 2005-08-11 devnull okay:
116 0c98da8b 2005-07-13 devnull fs->blocksize = fsblk->blocksize;
117 0c98da8b 2005-07-13 devnull fs->nblock = (fsblk->nfrag+fsblk->fragsperblock-1) / fsblk->fragsperblock;
118 0c98da8b 2005-07-13 devnull fs->fragsize = fsblk->fragsize;
119 0c98da8b 2005-07-13 devnull fs->fragspergroup = fsblk->fragspergroup;
120 0c98da8b 2005-07-13 devnull fs->fragsperblock = fsblk->fragsperblock;
121 0c98da8b 2005-07-13 devnull fs->inosperblock = fsblk->inosperblock;
122 0c98da8b 2005-07-13 devnull fs->inospergroup = fsblk->inospergroup;
123 0c98da8b 2005-07-13 devnull
124 0c98da8b 2005-07-13 devnull fs->nfrag = fsblk->nfrag;
125 0c98da8b 2005-07-13 devnull fs->ndfrag = fsblk->ndfrag;
126 e060bc52 2005-08-11 devnull /*
127 fa325e9b 2020-01-10 cross * used to use
128 fa325e9b 2020-01-10 cross * fs->blockspergroup = (u64int)fsblk->_cylspergroup *
129 e060bc52 2005-08-11 devnull * fsblk->secspercyl * BYTESPERSEC / fsblk->blocksize;
130 e060bc52 2005-08-11 devnull * for UFS1, but this should work for both UFS1 and UFS2
131 e060bc52 2005-08-11 devnull */
132 e060bc52 2005-08-11 devnull fs->blockspergroup = (u64int)fsblk->fragspergroup / fsblk->fragsperblock;
133 0c98da8b 2005-07-13 devnull fs->ncg = fsblk->ncg;
134 0c98da8b 2005-07-13 devnull
135 0c98da8b 2005-07-13 devnull fsys->blocksize = fs->blocksize;
136 0c98da8b 2005-07-13 devnull fsys->nblock = fs->nblock;
137 0c98da8b 2005-07-13 devnull
138 e060bc52 2005-08-11 devnull if(debug) fprint(2, "ffs %lld %d-byte blocks, %d cylinder groups\n",
139 0c98da8b 2005-07-13 devnull fs->nblock, fs->blocksize, fs->ncg);
140 e060bc52 2005-08-11 devnull if(debug) fprint(2, "\tinospergroup %d perblock %d blockspergroup %lld\n",
141 e060bc52 2005-08-11 devnull fs->inospergroup, fs->inosperblock, fs->blockspergroup);
142 0c98da8b 2005-07-13 devnull
143 0c98da8b 2005-07-13 devnull if(fs->cg == nil)
144 0c98da8b 2005-07-13 devnull fs->cg = emalloc(fs->ncg*sizeof(Cylgrp));
145 0c98da8b 2005-07-13 devnull for(i=0; i<fs->ncg; i++){
146 0c98da8b 2005-07-13 devnull cg = &fs->cg[i];
147 e060bc52 2005-08-11 devnull if(fs->ufs == 2)
148 e060bc52 2005-08-11 devnull cg->bno = (u64int)fs->blockspergroup*i;
149 e060bc52 2005-08-11 devnull else
150 e060bc52 2005-08-11 devnull cg->bno = fs->blockspergroup*i + fsblk->_cgoffset * (i & ~fsblk->_cgmask);
151 0c98da8b 2005-07-13 devnull cg->cgblkno = cg->bno + fsblk->cfragno/fs->fragsperblock;
152 0c98da8b 2005-07-13 devnull cg->ibno = cg->bno + fsblk->ifragno/fs->fragsperblock;
153 0c98da8b 2005-07-13 devnull cg->dbno = cg->bno + fsblk->dfragno/fs->fragsperblock;
154 0c98da8b 2005-07-13 devnull
155 0c98da8b 2005-07-13 devnull if(checkcg){
156 0c98da8b 2005-07-13 devnull if((cgb = diskread(disk, fs->blocksize, (u64int)cg->cgblkno*fs->blocksize)) == nil)
157 0c98da8b 2005-07-13 devnull goto error;
158 0c98da8b 2005-07-13 devnull
159 0c98da8b 2005-07-13 devnull cgblk = (Cgblk*)cgb->data;
160 0c98da8b 2005-07-13 devnull if(checkcgblk(cgblk) < 0){
161 0c98da8b 2005-07-13 devnull blockput(cgb);
162 0c98da8b 2005-07-13 devnull goto error;
163 0c98da8b 2005-07-13 devnull }
164 0c98da8b 2005-07-13 devnull if(cgblk->nfrag % fs->fragsperblock && i != fs->ncg-1){
165 0c98da8b 2005-07-13 devnull werrstr("fractional number of blocks in non-last cylinder group %d", cgblk->nfrag);
166 0c98da8b 2005-07-13 devnull blockput(cgb);
167 0c98da8b 2005-07-13 devnull goto error;
168 0c98da8b 2005-07-13 devnull }
169 cbeb0b26 2006-04-01 devnull /* cg->nfrag = cgblk->nfrag; */
170 cbeb0b26 2006-04-01 devnull /* cg->nblock = (cgblk->nfrag+fs->fragsperblock-1) / fs->fragsperblock; */
171 cbeb0b26 2006-04-01 devnull /* fprint(2, "cg #%d: cgblk %lud, %d blocks, %d inodes\n", cgblk->num, (ulong)cg->cgblkno, cg->nblock, cg->nino); */
172 0c98da8b 2005-07-13 devnull }
173 0c98da8b 2005-07-13 devnull }
174 0c98da8b 2005-07-13 devnull blockput(b);
175 0c98da8b 2005-07-13 devnull return 0;
176 0c98da8b 2005-07-13 devnull
177 0c98da8b 2005-07-13 devnull error:
178 0c98da8b 2005-07-13 devnull blockput(b);
179 0c98da8b 2005-07-13 devnull return -1;
180 0c98da8b 2005-07-13 devnull }
181 0c98da8b 2005-07-13 devnull
182 0c98da8b 2005-07-13 devnull static void
183 0c98da8b 2005-07-13 devnull ffsclose(Fsys *fsys)
184 0c98da8b 2005-07-13 devnull {
185 0c98da8b 2005-07-13 devnull Ffs *fs;
186 0c98da8b 2005-07-13 devnull
187 0c98da8b 2005-07-13 devnull fs = fsys->priv;
188 0c98da8b 2005-07-13 devnull if(fs->cg)
189 0c98da8b 2005-07-13 devnull free(fs->cg);
190 0c98da8b 2005-07-13 devnull free(fs);
191 0c98da8b 2005-07-13 devnull free(fsys);
192 0c98da8b 2005-07-13 devnull }
193 fa325e9b 2020-01-10 cross
194 0c98da8b 2005-07-13 devnull static int
195 0c98da8b 2005-07-13 devnull checkfsblk(Fsblk *super)
196 0c98da8b 2005-07-13 devnull {
197 6802a899 2006-04-28 devnull // fprint(2, "ffs magic 0x%ux\n", super->magic);
198 e060bc52 2005-08-11 devnull if(super->magic == FSMAGIC){
199 e060bc52 2005-08-11 devnull super->time = super->_time;
200 e060bc52 2005-08-11 devnull super->nfrag = super->_nfrag;
201 e060bc52 2005-08-11 devnull super->ndfrag = super->_ndfrag;
202 e060bc52 2005-08-11 devnull super->flags = super->_flags;
203 e060bc52 2005-08-11 devnull return 1;
204 0c98da8b 2005-07-13 devnull }
205 e060bc52 2005-08-11 devnull if(super->magic == FSMAGIC2){
206 e060bc52 2005-08-11 devnull return 2;
207 e060bc52 2005-08-11 devnull }
208 0c98da8b 2005-07-13 devnull
209 e060bc52 2005-08-11 devnull werrstr("bad super block");
210 e060bc52 2005-08-11 devnull return -1;
211 0c98da8b 2005-07-13 devnull }
212 0c98da8b 2005-07-13 devnull
213 0c98da8b 2005-07-13 devnull static int
214 0c98da8b 2005-07-13 devnull checkcgblk(Cgblk *cg)
215 0c98da8b 2005-07-13 devnull {
216 0c98da8b 2005-07-13 devnull if(cg->magic != CGMAGIC){
217 0c98da8b 2005-07-13 devnull werrstr("bad cylinder group block");
218 0c98da8b 2005-07-13 devnull return -1;
219 0c98da8b 2005-07-13 devnull }
220 0c98da8b 2005-07-13 devnull return 0;
221 0c98da8b 2005-07-13 devnull }
222 0c98da8b 2005-07-13 devnull
223 0c98da8b 2005-07-13 devnull /*
224 0c98da8b 2005-07-13 devnull * Read block #bno from the disk, zeroing unused data.
225 0c98da8b 2005-07-13 devnull * If there is no data whatsoever, it's okay to return nil.
226 0c98da8b 2005-07-13 devnull */
227 0c98da8b 2005-07-13 devnull int nskipx;
228 0c98da8b 2005-07-13 devnull static Block*
229 0c98da8b 2005-07-13 devnull ffsblockread(Fsys *fsys, u64int bno)
230 0c98da8b 2005-07-13 devnull {
231 e060bc52 2005-08-11 devnull int i, o;
232 0c98da8b 2005-07-13 devnull u8int *fmap;
233 0c98da8b 2005-07-13 devnull int frag, fsize, avail;
234 0c98da8b 2005-07-13 devnull Block *b;
235 0c98da8b 2005-07-13 devnull Cgblk *cgblk;
236 0c98da8b 2005-07-13 devnull Ffs *fs;
237 0c98da8b 2005-07-13 devnull
238 0c98da8b 2005-07-13 devnull fs = fsys->priv;
239 0c98da8b 2005-07-13 devnull i = bno / fs->blockspergroup;
240 0c98da8b 2005-07-13 devnull o = bno % fs->blockspergroup;
241 0c98da8b 2005-07-13 devnull if(i >= fs->ncg)
242 0c98da8b 2005-07-13 devnull return nil;
243 0c98da8b 2005-07-13 devnull
244 0c98da8b 2005-07-13 devnull if((cgblk = ffscylgrp(fs, i, &b)) == nil)
245 0c98da8b 2005-07-13 devnull return nil;
246 0c98da8b 2005-07-13 devnull
247 0c98da8b 2005-07-13 devnull fmap = (u8int*)cgblk+cgblk->fmapoff;
248 0c98da8b 2005-07-13 devnull frag = fs->fragsperblock;
249 0c98da8b 2005-07-13 devnull switch(frag){
250 0c98da8b 2005-07-13 devnull default:
251 0c98da8b 2005-07-13 devnull sysfatal("bad frag");
252 0c98da8b 2005-07-13 devnull case 8:
253 0c98da8b 2005-07-13 devnull avail = fmap[o];
254 0c98da8b 2005-07-13 devnull break;
255 0c98da8b 2005-07-13 devnull case 4:
256 0c98da8b 2005-07-13 devnull avail = (fmap[o>>1] >> ((o&1)*4)) & 0xF;
257 0c98da8b 2005-07-13 devnull break;
258 0c98da8b 2005-07-13 devnull case 2:
259 0c98da8b 2005-07-13 devnull avail = (fmap[o>>2] >> ((o&3)*2)) & 0x3;
260 0c98da8b 2005-07-13 devnull break;
261 0c98da8b 2005-07-13 devnull case 1:
262 0c98da8b 2005-07-13 devnull avail = (fmap[o>>3] >> (o&7)) & 0x1;
263 0c98da8b 2005-07-13 devnull break;
264 0c98da8b 2005-07-13 devnull }
265 0c98da8b 2005-07-13 devnull blockput(b);
266 0c98da8b 2005-07-13 devnull
267 0c98da8b 2005-07-13 devnull if(avail == ((1<<frag)-1))
268 0c98da8b 2005-07-13 devnull {
269 0c98da8b 2005-07-13 devnull nskipx++;
270 0c98da8b 2005-07-13 devnull return nil;
271 0c98da8b 2005-07-13 devnull }
272 0c98da8b 2005-07-13 devnull if((b = diskread(fs->disk, fs->blocksize, bno*fs->blocksize)) == nil){
273 0c98da8b 2005-07-13 devnull fprint(2, "diskread failed!!!\n");
274 0c98da8b 2005-07-13 devnull return nil;
275 0c98da8b 2005-07-13 devnull }
276 0c98da8b 2005-07-13 devnull
277 0c98da8b 2005-07-13 devnull fsize = fs->fragsize;
278 0c98da8b 2005-07-13 devnull for(i=0; i<frag; i++)
279 0c98da8b 2005-07-13 devnull if(avail & (1<<i))
280 0c98da8b 2005-07-13 devnull memset(b->data + fsize*i, 0, fsize);
281 0c98da8b 2005-07-13 devnull return b;
282 0c98da8b 2005-07-13 devnull }
283 0c98da8b 2005-07-13 devnull
284 0c98da8b 2005-07-13 devnull static Block*
285 e060bc52 2005-08-11 devnull ffsdatablock(Ffs *fs, u64int bno, int size)
286 0c98da8b 2005-07-13 devnull {
287 0c98da8b 2005-07-13 devnull int fsize;
288 0c98da8b 2005-07-13 devnull u64int diskaddr;
289 0c98da8b 2005-07-13 devnull Block *b;
290 0c98da8b 2005-07-13 devnull
291 0c98da8b 2005-07-13 devnull if(bno == 0)
292 0c98da8b 2005-07-13 devnull return nil;
293 0c98da8b 2005-07-13 devnull
294 0c98da8b 2005-07-13 devnull fsize = size;
295 0c98da8b 2005-07-13 devnull if(fsize < fs->fragsize)
296 0c98da8b 2005-07-13 devnull fsize = fs->fragsize;
297 0c98da8b 2005-07-13 devnull
298 0c98da8b 2005-07-13 devnull if(bno >= fs->nfrag){
299 9614b46f 2005-10-29 devnull fprint(2, "ffs: request for block %#lux; nfrag %#llux\n", (ulong)bno, fs->nfrag);
300 0c98da8b 2005-07-13 devnull return nil;
301 0c98da8b 2005-07-13 devnull }
302 0c98da8b 2005-07-13 devnull diskaddr = (u64int)bno*fs->fragsize;
303 0c98da8b 2005-07-13 devnull b = diskread(fs->disk, fsize, diskaddr);
304 0c98da8b 2005-07-13 devnull if(b == nil){
305 0c98da8b 2005-07-13 devnull fprint(2, "ffs: disk i/o at %#llux for %#ux: %r\n", diskaddr, fsize);
306 0c98da8b 2005-07-13 devnull return nil;
307 0c98da8b 2005-07-13 devnull }
308 0c98da8b 2005-07-13 devnull if(b->len < fsize){
309 0c98da8b 2005-07-13 devnull fprint(2, "ffs: disk i/o at %#llux for %#ux got %#ux\n", diskaddr, fsize,
310 0c98da8b 2005-07-13 devnull b->len);
311 0c98da8b 2005-07-13 devnull blockput(b);
312 0c98da8b 2005-07-13 devnull return nil;
313 0c98da8b 2005-07-13 devnull }
314 fa325e9b 2020-01-10 cross
315 0c98da8b 2005-07-13 devnull return b;
316 0c98da8b 2005-07-13 devnull }
317 0c98da8b 2005-07-13 devnull
318 e060bc52 2005-08-11 devnull static u64int
319 e060bc52 2005-08-11 devnull ifetch(Ffs *fs, u64int bno, u32int off)
320 9f4a65a0 2005-07-28 devnull {
321 9f4a65a0 2005-07-28 devnull Block *b;
322 fa325e9b 2020-01-10 cross
323 e060bc52 2005-08-11 devnull if(bno == BADBNO)
324 e060bc52 2005-08-11 devnull return BADBNO;
325 9f4a65a0 2005-07-28 devnull b = ffsdatablock(fs, bno, fs->blocksize);
326 9f4a65a0 2005-07-28 devnull if(b == nil)
327 e060bc52 2005-08-11 devnull return BADBNO;
328 e060bc52 2005-08-11 devnull if(fs->ufs == 2)
329 e060bc52 2005-08-11 devnull bno = ((u64int*)b->data)[off];
330 e060bc52 2005-08-11 devnull else
331 e060bc52 2005-08-11 devnull bno = ((u32int*)b->data)[off];
332 9f4a65a0 2005-07-28 devnull blockput(b);
333 9f4a65a0 2005-07-28 devnull return bno;
334 9f4a65a0 2005-07-28 devnull }
335 0c98da8b 2005-07-13 devnull
336 e060bc52 2005-08-11 devnull static u64int
337 e060bc52 2005-08-11 devnull ffsfileblockno(Ffs *fs, Inode *ino, u64int bno)
338 9f4a65a0 2005-07-28 devnull {
339 9f4a65a0 2005-07-28 devnull int ppb;
340 9f4a65a0 2005-07-28 devnull
341 0c98da8b 2005-07-13 devnull if(bno < NDADDR){
342 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "ffsfileblock %lud: direct %#lux\n", (ulong)bno, (ulong)ino->db[bno]);
343 9f4a65a0 2005-07-28 devnull return ino->db[bno];
344 0c98da8b 2005-07-13 devnull }
345 0c98da8b 2005-07-13 devnull bno -= NDADDR;
346 0c98da8b 2005-07-13 devnull ppb = fs->blocksize/4;
347 0c98da8b 2005-07-13 devnull
348 9f4a65a0 2005-07-28 devnull if(bno < ppb) /* single indirect */
349 9f4a65a0 2005-07-28 devnull return ifetch(fs, ino->ib[0], bno);
350 9f4a65a0 2005-07-28 devnull bno -= ppb;
351 0c98da8b 2005-07-13 devnull
352 9f4a65a0 2005-07-28 devnull if(bno < ppb*ppb)
353 9f4a65a0 2005-07-28 devnull return ifetch(fs, ifetch(fs, ino->ib[1], bno/ppb), bno%ppb);
354 9f4a65a0 2005-07-28 devnull bno -= ppb*ppb;
355 fa325e9b 2020-01-10 cross
356 9f4a65a0 2005-07-28 devnull if(bno/ppb/ppb/ppb == 0) /* bno < ppb*ppb*ppb w/o overflow */
357 9f4a65a0 2005-07-28 devnull return ifetch(fs, ifetch(fs, ifetch(fs, ino->ib[2], bno/ppb/ppb), (bno/ppb)%ppb), bno%ppb);
358 fa325e9b 2020-01-10 cross
359 e060bc52 2005-08-11 devnull fprint(2, "ffsfileblock %llud: way too big\n", bno+NDADDR+ppb+ppb*ppb);
360 e060bc52 2005-08-11 devnull return BADBNO;
361 9f4a65a0 2005-07-28 devnull }
362 9f4a65a0 2005-07-28 devnull
363 9f4a65a0 2005-07-28 devnull static Block*
364 e060bc52 2005-08-11 devnull ffsfileblock(Ffs *fs, Inode *ino, u64int bno, int size)
365 9f4a65a0 2005-07-28 devnull {
366 e060bc52 2005-08-11 devnull u64int b;
367 fa325e9b 2020-01-10 cross
368 9f4a65a0 2005-07-28 devnull b = ffsfileblockno(fs, ino, bno);
369 9f4a65a0 2005-07-28 devnull if(b == ~0)
370 9f4a65a0 2005-07-28 devnull return nil;
371 9f4a65a0 2005-07-28 devnull return ffsdatablock(fs, b, size);
372 0c98da8b 2005-07-13 devnull }
373 0c98da8b 2005-07-13 devnull
374 0c98da8b 2005-07-13 devnull /*
375 0c98da8b 2005-07-13 devnull * NFS handles are 4-byte inode number.
376 0c98da8b 2005-07-13 devnull */
377 0c98da8b 2005-07-13 devnull static void
378 0c98da8b 2005-07-13 devnull mkhandle(Nfs3Handle *h, u64int ino)
379 0c98da8b 2005-07-13 devnull {
380 0c98da8b 2005-07-13 devnull h->h[0] = ino >> 24;
381 0c98da8b 2005-07-13 devnull h->h[1] = ino >> 16;
382 0c98da8b 2005-07-13 devnull h->h[2] = ino >> 8;
383 0c98da8b 2005-07-13 devnull h->h[3] = ino;
384 0c98da8b 2005-07-13 devnull h->len = 4;
385 0c98da8b 2005-07-13 devnull }
386 0c98da8b 2005-07-13 devnull
387 0c98da8b 2005-07-13 devnull static u32int
388 0c98da8b 2005-07-13 devnull byte2u32(uchar *p)
389 0c98da8b 2005-07-13 devnull {
390 0c98da8b 2005-07-13 devnull return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
391 0c98da8b 2005-07-13 devnull }
392 0c98da8b 2005-07-13 devnull
393 e060bc52 2005-08-11 devnull static u64int lastiaddr; /* debugging */
394 9f4a65a0 2005-07-28 devnull
395 e060bc52 2005-08-11 devnull static void
396 e060bc52 2005-08-11 devnull inode1to2(Inode1 *i1, Inode *i2)
397 e060bc52 2005-08-11 devnull {
398 e060bc52 2005-08-11 devnull int i;
399 fa325e9b 2020-01-10 cross
400 e060bc52 2005-08-11 devnull memset(i2, 0, sizeof *i2);
401 e060bc52 2005-08-11 devnull i2->mode = i1->mode;
402 e060bc52 2005-08-11 devnull i2->nlink = i1->nlink;
403 e060bc52 2005-08-11 devnull i2->size = i1->size;
404 e060bc52 2005-08-11 devnull i2->atime = i1->atime;
405 e060bc52 2005-08-11 devnull i2->atimensec = i1->atimensec;
406 e060bc52 2005-08-11 devnull i2->mtime = i1->mtime;
407 e060bc52 2005-08-11 devnull i2->mtimensec = i1->mtimensec;
408 e060bc52 2005-08-11 devnull i2->ctime = i1->ctime;
409 e060bc52 2005-08-11 devnull i2->ctimensec = i1->ctimensec;
410 e060bc52 2005-08-11 devnull for(i=0; i<NDADDR; i++)
411 e060bc52 2005-08-11 devnull i2->db[i] = i1->db[i];
412 e060bc52 2005-08-11 devnull for(i=0; i<NIADDR; i++)
413 e060bc52 2005-08-11 devnull i2->ib[i] = i1->ib[i];
414 e060bc52 2005-08-11 devnull i2->flags = i1->flags;
415 e060bc52 2005-08-11 devnull i2->nblock = i1->nblock;
416 e060bc52 2005-08-11 devnull i2->gen = i1->gen;
417 e060bc52 2005-08-11 devnull i2->uid = i1->uid;
418 e060bc52 2005-08-11 devnull i2->gid = i1->gid;
419 e060bc52 2005-08-11 devnull }
420 e060bc52 2005-08-11 devnull
421 0c98da8b 2005-07-13 devnull static Nfs3Status
422 0c98da8b 2005-07-13 devnull handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
423 0c98da8b 2005-07-13 devnull {
424 0c98da8b 2005-07-13 devnull int i;
425 0c98da8b 2005-07-13 devnull u32int ioff;
426 0c98da8b 2005-07-13 devnull u32int inum;
427 e060bc52 2005-08-11 devnull u64int iaddr;
428 0c98da8b 2005-07-13 devnull Block *b;
429 0c98da8b 2005-07-13 devnull Cylgrp *cg;
430 e060bc52 2005-08-11 devnull Inode1 ino1;
431 0c98da8b 2005-07-13 devnull
432 0c98da8b 2005-07-13 devnull if(h->len != 4)
433 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
434 0c98da8b 2005-07-13 devnull inum = byte2u32(h->h);
435 0c98da8b 2005-07-13 devnull if(pinum)
436 0c98da8b 2005-07-13 devnull *pinum = inum;
437 0c98da8b 2005-07-13 devnull if(debug) print("inum %d...", (int)inum);
438 0c98da8b 2005-07-13 devnull
439 0c98da8b 2005-07-13 devnull /* fetch inode from disk */
440 0c98da8b 2005-07-13 devnull i = inum / fs->inospergroup;
441 0c98da8b 2005-07-13 devnull ioff = inum % fs->inospergroup;
442 0c98da8b 2005-07-13 devnull if(debug)print("cg %d off %d...", i, (int)ioff);
443 0c98da8b 2005-07-13 devnull if(i >= fs->ncg)
444 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
445 0c98da8b 2005-07-13 devnull cg = &fs->cg[i];
446 0c98da8b 2005-07-13 devnull
447 e060bc52 2005-08-11 devnull if(debug) print("cg->ibno %lld ufs %d...", cg->ibno, fs->ufs);
448 e060bc52 2005-08-11 devnull iaddr = (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize;
449 e060bc52 2005-08-11 devnull ioff = ioff%fs->inosperblock;
450 e060bc52 2005-08-11 devnull if((b = diskread(fs->disk, fs->blocksize, iaddr)) == nil)
451 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
452 e060bc52 2005-08-11 devnull if(fs->ufs == 2){
453 e060bc52 2005-08-11 devnull *ino = ((Inode*)b->data)[ioff];
454 e060bc52 2005-08-11 devnull lastiaddr = iaddr+ioff*sizeof(Inode);
455 e060bc52 2005-08-11 devnull }else{
456 e060bc52 2005-08-11 devnull ino1 = ((Inode1*)b->data)[ioff];
457 e060bc52 2005-08-11 devnull inode1to2(&ino1, ino);
458 e060bc52 2005-08-11 devnull lastiaddr = iaddr+ioff*sizeof(Inode1);
459 e060bc52 2005-08-11 devnull }
460 0c98da8b 2005-07-13 devnull blockput(b);
461 0c98da8b 2005-07-13 devnull return Nfs3Ok;
462 0c98da8b 2005-07-13 devnull }
463 0c98da8b 2005-07-13 devnull
464 0c98da8b 2005-07-13 devnull static Nfs3Status
465 0c98da8b 2005-07-13 devnull ffsroot(Fsys *fsys, Nfs3Handle *h)
466 0c98da8b 2005-07-13 devnull {
467 0c98da8b 2005-07-13 devnull USED(fsys);
468 0c98da8b 2005-07-13 devnull mkhandle(h, 2);
469 0c98da8b 2005-07-13 devnull return Nfs3Ok;
470 0c98da8b 2005-07-13 devnull }
471 0c98da8b 2005-07-13 devnull
472 0c98da8b 2005-07-13 devnull static Nfs3Status
473 0c98da8b 2005-07-13 devnull ino2attr(Ffs *fs, Inode *ino, u32int inum, Nfs3Attr *attr)
474 0c98da8b 2005-07-13 devnull {
475 0c98da8b 2005-07-13 devnull u32int rdev;
476 0c98da8b 2005-07-13 devnull
477 0c98da8b 2005-07-13 devnull attr->type = -1;
478 0c98da8b 2005-07-13 devnull switch(ino->mode&IFMT){
479 0c98da8b 2005-07-13 devnull case IFIFO:
480 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileFifo;
481 0c98da8b 2005-07-13 devnull break;
482 0c98da8b 2005-07-13 devnull case IFCHR:
483 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileChar;
484 0c98da8b 2005-07-13 devnull break;
485 0c98da8b 2005-07-13 devnull case IFDIR:
486 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileDir;
487 0c98da8b 2005-07-13 devnull break;
488 0c98da8b 2005-07-13 devnull case IFBLK:
489 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileBlock;
490 0c98da8b 2005-07-13 devnull break;
491 0c98da8b 2005-07-13 devnull case IFREG:
492 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileReg;
493 0c98da8b 2005-07-13 devnull break;
494 0c98da8b 2005-07-13 devnull case IFLNK:
495 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileSymlink;
496 0c98da8b 2005-07-13 devnull break;
497 0c98da8b 2005-07-13 devnull case IFSOCK:
498 0c98da8b 2005-07-13 devnull attr->type = Nfs3FileSocket;
499 0c98da8b 2005-07-13 devnull break;
500 0c98da8b 2005-07-13 devnull case IFWHT:
501 0c98da8b 2005-07-13 devnull default:
502 0c98da8b 2005-07-13 devnull return Nfs3ErrBadHandle;
503 0c98da8b 2005-07-13 devnull }
504 0c98da8b 2005-07-13 devnull
505 0c98da8b 2005-07-13 devnull attr->mode = ino->mode&07777;
506 0c98da8b 2005-07-13 devnull attr->nlink = ino->nlink;
507 0c98da8b 2005-07-13 devnull attr->uid = ino->uid;
508 0c98da8b 2005-07-13 devnull attr->gid = ino->gid;
509 0c98da8b 2005-07-13 devnull attr->size = ino->size;
510 0c98da8b 2005-07-13 devnull attr->used = ino->nblock*fs->blocksize;
511 0c98da8b 2005-07-13 devnull if(attr->type==Nfs3FileBlock || attr->type==Nfs3FileChar){
512 0c98da8b 2005-07-13 devnull rdev = ino->db[0];
513 0c98da8b 2005-07-13 devnull attr->major = (rdev>>8)&0xFF;
514 0c98da8b 2005-07-13 devnull attr->minor = rdev & 0xFFFF00FF;
515 0c98da8b 2005-07-13 devnull }else{
516 0c98da8b 2005-07-13 devnull attr->major = 0;
517 0c98da8b 2005-07-13 devnull attr->minor = 0;
518 0c98da8b 2005-07-13 devnull }
519 0c98da8b 2005-07-13 devnull attr->fsid = 0;
520 0c98da8b 2005-07-13 devnull attr->fileid = inum;
521 0c98da8b 2005-07-13 devnull attr->atime.sec = ino->atime;
522 0c98da8b 2005-07-13 devnull attr->atime.nsec = ino->atimensec;
523 0c98da8b 2005-07-13 devnull attr->mtime.sec = ino->mtime;
524 0c98da8b 2005-07-13 devnull attr->mtime.nsec = ino->mtimensec;
525 0c98da8b 2005-07-13 devnull attr->ctime.sec = ino->ctime;
526 0c98da8b 2005-07-13 devnull attr->ctime.nsec = ino->ctimensec;
527 0c98da8b 2005-07-13 devnull return Nfs3Ok;
528 0c98da8b 2005-07-13 devnull }
529 0c98da8b 2005-07-13 devnull
530 0c98da8b 2005-07-13 devnull static int
531 0c98da8b 2005-07-13 devnull ingroup(SunAuthUnix *au, uint gid)
532 0c98da8b 2005-07-13 devnull {
533 0c98da8b 2005-07-13 devnull int i;
534 0c98da8b 2005-07-13 devnull
535 0c98da8b 2005-07-13 devnull for(i=0; i<au->ng; i++)
536 0c98da8b 2005-07-13 devnull if(au->g[i] == gid)
537 0c98da8b 2005-07-13 devnull return 1;
538 0c98da8b 2005-07-13 devnull return 0;
539 0c98da8b 2005-07-13 devnull }
540 0c98da8b 2005-07-13 devnull
541 0c98da8b 2005-07-13 devnull static Nfs3Status
542 0c98da8b 2005-07-13 devnull inoperm(Inode *ino, SunAuthUnix *au, int need)
543 0c98da8b 2005-07-13 devnull {
544 0c98da8b 2005-07-13 devnull int have;
545 0c98da8b 2005-07-13 devnull
546 9f4a65a0 2005-07-28 devnull if(au == nil)
547 9f4a65a0 2005-07-28 devnull return Nfs3Ok;
548 9f4a65a0 2005-07-28 devnull
549 0c98da8b 2005-07-13 devnull have = ino->mode&0777;
550 0c98da8b 2005-07-13 devnull if(ino->uid == au->uid)
551 0c98da8b 2005-07-13 devnull have >>= 6;
552 0c98da8b 2005-07-13 devnull else if(ino->gid == au->gid || ingroup(au, ino->gid))
553 0c98da8b 2005-07-13 devnull have >>= 3;
554 0c98da8b 2005-07-13 devnull
555 0c98da8b 2005-07-13 devnull if((have&need) != need)
556 0c98da8b 2005-07-13 devnull return Nfs3ErrNotOwner; /* really EPERM */
557 0c98da8b 2005-07-13 devnull return Nfs3Ok;
558 0c98da8b 2005-07-13 devnull }
559 0c98da8b 2005-07-13 devnull
560 0c98da8b 2005-07-13 devnull static Nfs3Status
561 0c98da8b 2005-07-13 devnull ffsgetattr(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
562 0c98da8b 2005-07-13 devnull {
563 0c98da8b 2005-07-13 devnull Inode ino;
564 0c98da8b 2005-07-13 devnull u32int inum;
565 0c98da8b 2005-07-13 devnull Ffs *fs;
566 0c98da8b 2005-07-13 devnull Nfs3Status ok;
567 0c98da8b 2005-07-13 devnull
568 0c98da8b 2005-07-13 devnull fs = fsys->priv;
569 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
570 0c98da8b 2005-07-13 devnull return ok;
571 0c98da8b 2005-07-13 devnull
572 0c98da8b 2005-07-13 devnull USED(au); /* anyone can getattr */
573 0c98da8b 2005-07-13 devnull
574 0c98da8b 2005-07-13 devnull return ino2attr(fs, &ino, inum, attr);
575 0c98da8b 2005-07-13 devnull }
576 0c98da8b 2005-07-13 devnull
577 0c98da8b 2005-07-13 devnull static Nfs3Status
578 0c98da8b 2005-07-13 devnull ffsaccess(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
579 0c98da8b 2005-07-13 devnull {
580 0c98da8b 2005-07-13 devnull int have;
581 0c98da8b 2005-07-13 devnull Inode ino;
582 0c98da8b 2005-07-13 devnull u32int inum;
583 0c98da8b 2005-07-13 devnull Ffs *fs;
584 0c98da8b 2005-07-13 devnull Nfs3Status ok;
585 0c98da8b 2005-07-13 devnull
586 0c98da8b 2005-07-13 devnull fs = fsys->priv;
587 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
588 0c98da8b 2005-07-13 devnull return ok;
589 0c98da8b 2005-07-13 devnull
590 0c98da8b 2005-07-13 devnull have = ino.mode&0777;
591 0c98da8b 2005-07-13 devnull if(ino.uid == au->uid)
592 0c98da8b 2005-07-13 devnull have >>= 6;
593 0c98da8b 2005-07-13 devnull else if(ino.gid == au->gid || ingroup(au, ino.gid))
594 0c98da8b 2005-07-13 devnull have >>= 3;
595 0c98da8b 2005-07-13 devnull
596 0c98da8b 2005-07-13 devnull *got = 0;
597 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessRead) && (have&AREAD))
598 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessRead;
599 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessLookup) && (ino.mode&IFMT)==IFDIR && (have&AEXEC))
600 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessLookup;
601 0c98da8b 2005-07-13 devnull if((want&Nfs3AccessExecute) && (ino.mode&IFMT)!=IFDIR && (have&AEXEC))
602 0c98da8b 2005-07-13 devnull *got |= Nfs3AccessExecute;
603 0c98da8b 2005-07-13 devnull
604 0c98da8b 2005-07-13 devnull return ino2attr(fs, &ino, inum, attr);
605 0c98da8b 2005-07-13 devnull }
606 0c98da8b 2005-07-13 devnull
607 0c98da8b 2005-07-13 devnull static Nfs3Status
608 0c98da8b 2005-07-13 devnull ffslookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
609 0c98da8b 2005-07-13 devnull {
610 0c98da8b 2005-07-13 devnull u32int nblock;
611 0c98da8b 2005-07-13 devnull u32int i;
612 0c98da8b 2005-07-13 devnull uchar *p, *ep;
613 0c98da8b 2005-07-13 devnull Dirent *de;
614 0c98da8b 2005-07-13 devnull Inode ino;
615 0c98da8b 2005-07-13 devnull Block *b;
616 0c98da8b 2005-07-13 devnull Ffs *fs;
617 0c98da8b 2005-07-13 devnull Nfs3Status ok;
618 0c98da8b 2005-07-13 devnull int len, want;
619 0c98da8b 2005-07-13 devnull
620 0c98da8b 2005-07-13 devnull fs = fsys->priv;
621 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
622 0c98da8b 2005-07-13 devnull return ok;
623 0c98da8b 2005-07-13 devnull
624 0c98da8b 2005-07-13 devnull if((ino.mode&IFMT) != IFDIR)
625 0c98da8b 2005-07-13 devnull return Nfs3ErrNotDir;
626 0c98da8b 2005-07-13 devnull
627 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AEXEC)) != Nfs3Ok)
628 0c98da8b 2005-07-13 devnull return ok;
629 0c98da8b 2005-07-13 devnull
630 0c98da8b 2005-07-13 devnull len = strlen(name);
631 0c98da8b 2005-07-13 devnull nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
632 0c98da8b 2005-07-13 devnull for(i=0; i<nblock; i++){
633 0c98da8b 2005-07-13 devnull if(i==nblock-1)
634 0c98da8b 2005-07-13 devnull want = ino.size % fs->blocksize;
635 0c98da8b 2005-07-13 devnull else
636 0c98da8b 2005-07-13 devnull want = fs->blocksize;
637 0c98da8b 2005-07-13 devnull b = ffsfileblock(fs, &ino, i, want);
638 0c98da8b 2005-07-13 devnull if(b == nil)
639 0c98da8b 2005-07-13 devnull continue;
640 0c98da8b 2005-07-13 devnull p = b->data;
641 0c98da8b 2005-07-13 devnull ep = p+b->len;
642 0c98da8b 2005-07-13 devnull while(p < ep){
643 0c98da8b 2005-07-13 devnull de = (Dirent*)p;
644 0c98da8b 2005-07-13 devnull if(de->reclen == 0){
645 0c98da8b 2005-07-13 devnull if(debug)
646 0c98da8b 2005-07-13 devnull fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
647 0c98da8b 2005-07-13 devnull break;
648 0c98da8b 2005-07-13 devnull }
649 0c98da8b 2005-07-13 devnull p += de->reclen;
650 0c98da8b 2005-07-13 devnull if(p > ep){
651 0c98da8b 2005-07-13 devnull if(debug)
652 0c98da8b 2005-07-13 devnull fprint(2, "bad len %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
653 0c98da8b 2005-07-13 devnull break;
654 0c98da8b 2005-07-13 devnull }
655 0c98da8b 2005-07-13 devnull if(de->ino == 0)
656 0c98da8b 2005-07-13 devnull continue;
657 0c98da8b 2005-07-13 devnull if(4+2+2+de->namlen > de->reclen){
658 0c98da8b 2005-07-13 devnull if(debug)
659 0c98da8b 2005-07-13 devnull fprint(2, "bad namelen %d at offset %d of %d\n", de->namlen, (int)(p-b->data), b->len);
660 0c98da8b 2005-07-13 devnull break;
661 0c98da8b 2005-07-13 devnull }
662 0c98da8b 2005-07-13 devnull if(de->namlen == len && memcmp(de->name, name, len) == 0){
663 0c98da8b 2005-07-13 devnull mkhandle(nh, de->ino);
664 0c98da8b 2005-07-13 devnull blockput(b);
665 0c98da8b 2005-07-13 devnull return Nfs3Ok;
666 0c98da8b 2005-07-13 devnull }
667 0c98da8b 2005-07-13 devnull }
668 0c98da8b 2005-07-13 devnull blockput(b);
669 0c98da8b 2005-07-13 devnull }
670 0c98da8b 2005-07-13 devnull return Nfs3ErrNoEnt;
671 0c98da8b 2005-07-13 devnull }
672 0c98da8b 2005-07-13 devnull
673 0c98da8b 2005-07-13 devnull static Nfs3Status
674 0c98da8b 2005-07-13 devnull ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
675 0c98da8b 2005-07-13 devnull {
676 0c98da8b 2005-07-13 devnull u32int nblock;
677 0c98da8b 2005-07-13 devnull u32int i;
678 0c98da8b 2005-07-13 devnull int off, done;
679 0c98da8b 2005-07-13 devnull uchar *data, *dp, *dep, *p, *ep, *ndp;
680 0c98da8b 2005-07-13 devnull Dirent *de;
681 0c98da8b 2005-07-13 devnull Inode ino;
682 0c98da8b 2005-07-13 devnull Block *b;
683 0c98da8b 2005-07-13 devnull Ffs *fs;
684 0c98da8b 2005-07-13 devnull Nfs3Status ok;
685 0c98da8b 2005-07-13 devnull Nfs3Entry e;
686 0c98da8b 2005-07-13 devnull int want;
687 0c98da8b 2005-07-13 devnull
688 0c98da8b 2005-07-13 devnull fs = fsys->priv;
689 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
690 0c98da8b 2005-07-13 devnull return ok;
691 0c98da8b 2005-07-13 devnull
692 0c98da8b 2005-07-13 devnull if((ino.mode&IFMT) != IFDIR)
693 0c98da8b 2005-07-13 devnull return Nfs3ErrNotDir;
694 0c98da8b 2005-07-13 devnull
695 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
696 0c98da8b 2005-07-13 devnull return ok;
697 0c98da8b 2005-07-13 devnull
698 0c98da8b 2005-07-13 devnull if(cookie >= ino.size){
699 63408c39 2007-06-08 devnull *peof = 1;
700 0c98da8b 2005-07-13 devnull *pcount = 0;
701 0c98da8b 2005-07-13 devnull *pdata = 0;
702 0c98da8b 2005-07-13 devnull return Nfs3Ok;
703 0c98da8b 2005-07-13 devnull }
704 0c98da8b 2005-07-13 devnull
705 0c98da8b 2005-07-13 devnull dp = malloc(count);
706 0c98da8b 2005-07-13 devnull data = dp;
707 0c98da8b 2005-07-13 devnull if(dp == nil)
708 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
709 0c98da8b 2005-07-13 devnull dep = dp+count;
710 0c98da8b 2005-07-13 devnull *peof = 0;
711 0c98da8b 2005-07-13 devnull nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
712 0c98da8b 2005-07-13 devnull i = cookie/fs->blocksize;
713 0c98da8b 2005-07-13 devnull off = cookie%fs->blocksize;
714 0c98da8b 2005-07-13 devnull done = 0;
715 0c98da8b 2005-07-13 devnull for(; i<nblock && !done; i++){
716 0c98da8b 2005-07-13 devnull if(i==nblock-1)
717 0c98da8b 2005-07-13 devnull want = ino.size % fs->blocksize;
718 0c98da8b 2005-07-13 devnull else
719 0c98da8b 2005-07-13 devnull want = fs->blocksize;
720 0c98da8b 2005-07-13 devnull b = ffsfileblock(fs, &ino, i, want);
721 0c98da8b 2005-07-13 devnull if(b == nil)
722 0c98da8b 2005-07-13 devnull continue;
723 0c98da8b 2005-07-13 devnull p = b->data;
724 0c98da8b 2005-07-13 devnull ep = p+b->len;
725 0c98da8b 2005-07-13 devnull memset(&e, 0, sizeof e);
726 0c98da8b 2005-07-13 devnull while(p < ep){
727 0c98da8b 2005-07-13 devnull de = (Dirent*)p;
728 0c98da8b 2005-07-13 devnull if(de->reclen == 0){
729 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
730 0c98da8b 2005-07-13 devnull break;
731 0c98da8b 2005-07-13 devnull }
732 0c98da8b 2005-07-13 devnull p += de->reclen;
733 0c98da8b 2005-07-13 devnull if(p > ep){
734 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "reclen %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
735 0c98da8b 2005-07-13 devnull break;
736 0c98da8b 2005-07-13 devnull }
737 0c98da8b 2005-07-13 devnull if(de->ino == 0){
738 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "zero inode\n");
739 0c98da8b 2005-07-13 devnull continue;
740 0c98da8b 2005-07-13 devnull }
741 0c98da8b 2005-07-13 devnull if(4+2+2+de->namlen > de->reclen){
742 0c98da8b 2005-07-13 devnull 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);
743 0c98da8b 2005-07-13 devnull break;
744 0c98da8b 2005-07-13 devnull }
745 0c98da8b 2005-07-13 devnull if(de->name[de->namlen] != 0){
746 0c98da8b 2005-07-13 devnull if(debug) fprint(2, "bad name %d %.*s\n", de->namlen, de->namlen, de->name);
747 0c98da8b 2005-07-13 devnull continue;
748 0c98da8b 2005-07-13 devnull }
749 0c98da8b 2005-07-13 devnull if(debug) print("%s/%d ", de->name, (int)de->ino);
750 0c98da8b 2005-07-13 devnull if((uchar*)de - b->data < off)
751 0c98da8b 2005-07-13 devnull continue;
752 0c98da8b 2005-07-13 devnull e.fileid = de->ino;
753 0c98da8b 2005-07-13 devnull e.name = de->name;
754 4e81d4f6 2006-05-09 devnull e.namelen = de->namlen;
755 0c98da8b 2005-07-13 devnull e.cookie = (u64int)i*fs->blocksize + (p - b->data);
756 0c98da8b 2005-07-13 devnull if(nfs3entrypack(dp, dep, &ndp, &e) < 0){
757 0c98da8b 2005-07-13 devnull done = 1;
758 0c98da8b 2005-07-13 devnull break;
759 0c98da8b 2005-07-13 devnull }
760 0c98da8b 2005-07-13 devnull dp = ndp;
761 0c98da8b 2005-07-13 devnull }
762 0c98da8b 2005-07-13 devnull off = 0;
763 0c98da8b 2005-07-13 devnull blockput(b);
764 0c98da8b 2005-07-13 devnull }
765 0c98da8b 2005-07-13 devnull if(i==nblock)
766 0c98da8b 2005-07-13 devnull *peof = 1;
767 0c98da8b 2005-07-13 devnull
768 0c98da8b 2005-07-13 devnull *pcount = dp - data;
769 0c98da8b 2005-07-13 devnull *pdata = data;
770 0c98da8b 2005-07-13 devnull return Nfs3Ok;
771 9f4a65a0 2005-07-28 devnull }
772 9f4a65a0 2005-07-28 devnull
773 9f4a65a0 2005-07-28 devnull static u64int
774 9f4a65a0 2005-07-28 devnull ffsxfileblock(Fsys *fsys, Nfs3Handle *h, u64int offset)
775 9f4a65a0 2005-07-28 devnull {
776 e060bc52 2005-08-11 devnull u64int bno;
777 9f4a65a0 2005-07-28 devnull Inode ino;
778 9f4a65a0 2005-07-28 devnull Nfs3Status ok;
779 9f4a65a0 2005-07-28 devnull Ffs *fs;
780 fa325e9b 2020-01-10 cross
781 9f4a65a0 2005-07-28 devnull fs = fsys->priv;
782 9f4a65a0 2005-07-28 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok){
783 9f4a65a0 2005-07-28 devnull nfs3errstr(ok);
784 9f4a65a0 2005-07-28 devnull return 0;
785 9f4a65a0 2005-07-28 devnull }
786 e060bc52 2005-08-11 devnull if(offset == 1) /* clumsy hack for debugging */
787 e060bc52 2005-08-11 devnull return lastiaddr;
788 9f4a65a0 2005-07-28 devnull if(offset >= ino.size){
789 9f4a65a0 2005-07-28 devnull werrstr("beyond end of file");
790 9f4a65a0 2005-07-28 devnull return 0;
791 9f4a65a0 2005-07-28 devnull }
792 9f4a65a0 2005-07-28 devnull bno = offset/fs->blocksize;
793 9f4a65a0 2005-07-28 devnull bno = ffsfileblockno(fs, &ino, bno);
794 9f4a65a0 2005-07-28 devnull if(bno == ~0)
795 9f4a65a0 2005-07-28 devnull return 0;
796 9f4a65a0 2005-07-28 devnull return bno*(u64int)fs->fragsize;
797 0c98da8b 2005-07-13 devnull }
798 0c98da8b 2005-07-13 devnull
799 0c98da8b 2005-07-13 devnull static Nfs3Status
800 0c98da8b 2005-07-13 devnull ffsreadfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
801 0c98da8b 2005-07-13 devnull u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
802 0c98da8b 2005-07-13 devnull {
803 0c98da8b 2005-07-13 devnull uchar *data;
804 0c98da8b 2005-07-13 devnull Block *b;
805 0c98da8b 2005-07-13 devnull Ffs *fs;
806 0c98da8b 2005-07-13 devnull int off, want, fragcount;
807 0c98da8b 2005-07-13 devnull Inode ino;
808 0c98da8b 2005-07-13 devnull Nfs3Status ok;
809 0c98da8b 2005-07-13 devnull
810 0c98da8b 2005-07-13 devnull fs = fsys->priv;
811 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
812 0c98da8b 2005-07-13 devnull return ok;
813 0c98da8b 2005-07-13 devnull
814 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
815 0c98da8b 2005-07-13 devnull return ok;
816 0c98da8b 2005-07-13 devnull
817 0c98da8b 2005-07-13 devnull if(offset >= ino.size){
818 0c98da8b 2005-07-13 devnull *pdata = 0;
819 0c98da8b 2005-07-13 devnull *pcount = 0;
820 0c98da8b 2005-07-13 devnull *peof = 1;
821 0c98da8b 2005-07-13 devnull return Nfs3Ok;
822 0c98da8b 2005-07-13 devnull }
823 0c98da8b 2005-07-13 devnull if(offset+count > ino.size)
824 0c98da8b 2005-07-13 devnull count = ino.size-offset;
825 0c98da8b 2005-07-13 devnull if(offset/fs->blocksize != (offset+count-1)/fs->blocksize)
826 0c98da8b 2005-07-13 devnull count = fs->blocksize - offset%fs->blocksize;
827 0c98da8b 2005-07-13 devnull
828 0c98da8b 2005-07-13 devnull data = malloc(count);
829 0c98da8b 2005-07-13 devnull if(data == nil)
830 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
831 0c98da8b 2005-07-13 devnull
832 0c98da8b 2005-07-13 devnull want = offset%fs->blocksize+count;
833 0c98da8b 2005-07-13 devnull if(want%fs->fragsize)
834 0c98da8b 2005-07-13 devnull want += fs->fragsize - want%fs->fragsize;
835 0c98da8b 2005-07-13 devnull
836 0c98da8b 2005-07-13 devnull b = ffsfileblock(fs, &ino, offset/fs->blocksize, want);
837 0c98da8b 2005-07-13 devnull if(b == nil){
838 0c98da8b 2005-07-13 devnull /* BUG: distinguish sparse file from I/O error */
839 0c98da8b 2005-07-13 devnull memset(data, 0, count);
840 0c98da8b 2005-07-13 devnull }else{
841 0c98da8b 2005-07-13 devnull off = offset%fs->blocksize;
842 0c98da8b 2005-07-13 devnull fragcount = count; /* need signed variable */
843 0c98da8b 2005-07-13 devnull if(off+fragcount > b->len){
844 0c98da8b 2005-07-13 devnull fragcount = b->len - off;
845 0c98da8b 2005-07-13 devnull if(fragcount < 0)
846 0c98da8b 2005-07-13 devnull fragcount = 0;
847 0c98da8b 2005-07-13 devnull }
848 0c98da8b 2005-07-13 devnull if(fragcount > 0)
849 0c98da8b 2005-07-13 devnull memmove(data, b->data+off, fragcount);
850 0c98da8b 2005-07-13 devnull count = fragcount;
851 0c98da8b 2005-07-13 devnull blockput(b);
852 0c98da8b 2005-07-13 devnull }
853 0c98da8b 2005-07-13 devnull *peof = (offset+count == ino.size);
854 0c98da8b 2005-07-13 devnull *pcount = count;
855 0c98da8b 2005-07-13 devnull *pdata = data;
856 0c98da8b 2005-07-13 devnull return Nfs3Ok;
857 0c98da8b 2005-07-13 devnull }
858 0c98da8b 2005-07-13 devnull
859 0c98da8b 2005-07-13 devnull static Nfs3Status
860 0c98da8b 2005-07-13 devnull ffsreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
861 0c98da8b 2005-07-13 devnull {
862 0c98da8b 2005-07-13 devnull Ffs *fs;
863 0c98da8b 2005-07-13 devnull Nfs3Status ok;
864 0c98da8b 2005-07-13 devnull int len;
865 0c98da8b 2005-07-13 devnull Inode ino;
866 0c98da8b 2005-07-13 devnull Block *b;
867 0c98da8b 2005-07-13 devnull
868 0c98da8b 2005-07-13 devnull fs = fsys->priv;
869 0c98da8b 2005-07-13 devnull if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
870 0c98da8b 2005-07-13 devnull return ok;
871 0c98da8b 2005-07-13 devnull if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
872 0c98da8b 2005-07-13 devnull return ok;
873 0c98da8b 2005-07-13 devnull
874 0c98da8b 2005-07-13 devnull if(ino.size > 1024)
875 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
876 0c98da8b 2005-07-13 devnull len = ino.size;
877 0c98da8b 2005-07-13 devnull
878 0c98da8b 2005-07-13 devnull if(ino.nblock != 0){
879 e060bc52 2005-08-11 devnull /* assumes symlink fits in one block */
880 0c98da8b 2005-07-13 devnull b = ffsfileblock(fs, &ino, 0, len);
881 0c98da8b 2005-07-13 devnull if(b == nil)
882 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
883 0c98da8b 2005-07-13 devnull if(memchr(b->data, 0, len) != nil){
884 0c98da8b 2005-07-13 devnull blockput(b);
885 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
886 0c98da8b 2005-07-13 devnull }
887 0c98da8b 2005-07-13 devnull *link = malloc(len+1);
888 0c98da8b 2005-07-13 devnull if(*link == 0){
889 0c98da8b 2005-07-13 devnull blockput(b);
890 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
891 0c98da8b 2005-07-13 devnull }
892 0c98da8b 2005-07-13 devnull memmove(*link, b->data, len);
893 0c98da8b 2005-07-13 devnull (*link)[len] = 0;
894 0c98da8b 2005-07-13 devnull blockput(b);
895 0c98da8b 2005-07-13 devnull return Nfs3Ok;
896 0c98da8b 2005-07-13 devnull }
897 0c98da8b 2005-07-13 devnull
898 0c98da8b 2005-07-13 devnull if(len > sizeof ino.db + sizeof ino.ib)
899 0c98da8b 2005-07-13 devnull return Nfs3ErrIo;
900 0c98da8b 2005-07-13 devnull
901 0c98da8b 2005-07-13 devnull *link = malloc(len+1);
902 0c98da8b 2005-07-13 devnull if(*link == 0)
903 0c98da8b 2005-07-13 devnull return Nfs3ErrNoMem;
904 0c98da8b 2005-07-13 devnull memmove(*link, ino.db, ino.size);
905 0c98da8b 2005-07-13 devnull (*link)[len] = 0;
906 0c98da8b 2005-07-13 devnull return Nfs3Ok;
907 0c98da8b 2005-07-13 devnull }