Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/ext2srv/ext2fs.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <fcall.h>
4
#include <thread.h>
5
#include <9p.h>
6
#include "dat.h"
7
#include "fns.h"
8
 
9
#define thdr	r->ifcall
10
#define rhdr	r->ofcall
11
 
12
extern int	errno;
13
 
14
static void
15
response(Req *r)
16
{
17
	char *err;
18
 
19
	if (errno) {
20
		err = xerrstr(errno);
21
		chat("%s\n", err);
22
		respond(r, err);
23
	} else {
24
		chat("OK\n");
25
		respond(r, nil);
26
	}
27
}
28
 
29
static void
30
rattach(Req *r)
31
{
32
	Xfs *xf;
33
	Xfile *root;
34
 
35
	chat("attach(fid=%d,uname=\"%s\",aname=\"%s\",afid=\"%d\")...",
36
		thdr.fid, thdr.uname, thdr.aname, thdr.afid);
37
 
38
	errno = 0;
39
	root = xfile(r->fid, Clean);
40
	if(!root){
41
		errno = Enomem;
42
		goto error;
43
	}
44
	root->xf = xf = getxfs(thdr.aname);
45
	if(!xf)
46
		goto error;
47
 
48
	/* now attach root inode */
49
	if( get_inode(root, EXT2_ROOT_INODE) < 0 )
50
		goto error;
51
 
52
	r->fid->qid.type = QTDIR;
53
	r->fid->qid.vers = 0;
54
	root->xf->rootqid = r->fid->qid;
55
	root->pinbr = EXT2_ROOT_INODE;
56
	root->root = 1;
57
	rhdr.qid = r->fid->qid;
58
 
59
error:
60
	response(r);
61
}
62
static char *
63
rclone(Fid *fid, Fid *newfid)
64
{
65
	Xfile *of = xfile(fid, Asis);
66
	Xfile *nf = xfile(newfid, Clean);
67
 
68
	chat("clone(fid=%d,newfid=%d)...", fid->fid, newfid->fid);
69
	errno = 0;
70
	if(!of)
71
		errno = Eio;
72
	else if(!nf)
73
		errno = Enomem;
74
	else{
75
		Xfile *next = nf->next;
76
		*nf = *of;
77
		nf->next = next;
78
		nf->fid = newfid->fid;
79
		nf->root = 0;
80
	}
81
	chat("%s\n", errno? xerrstr(errno) : "OK");
82
	return errno ? xerrstr(errno) : 0;
83
}
84
static char *
85
rwalk1(Fid *fid, char *name, Qid *qid)
86
{
87
	Xfile *f=xfile(fid, Asis);
88
	int nr, sinbr = 0;
89
 
90
	chat("walk1(fid=%d,name=\"%s\")...", fid->fid, name);
91
	errno = 0;
92
	if( !f ){
93
		chat("no xfile...");
94
		goto error;
95
	}
96
	if( !(fid->qid.type & QTDIR) ){
97
		chat("qid.type=0x%x...", fid->qid.type);
98
		goto error;
99
	}
100
	sinbr = f->pinbr;
101
	if( name == 0 || name[0] == 0 || !strcmp(name, ".") ){
102
		*qid = fid->qid;
103
		goto ok;
104
	}else if( !strcmp(name, "..") ){
105
		if( fid->qid.path == f->xf->rootqid.path ){
106
			chat("walkup from root...");
107
			*qid = fid->qid;
108
			goto ok;
109
		}
110
		if( get_inode(f, f->pinbr) < 0 )
111
			goto error;
112
		if( f->pinbr == EXT2_ROOT_INODE ){
113
			*qid = f->xf->rootqid;
114
			f->pinbr = EXT2_ROOT_INODE;
115
		} else {
116
			*qid = (Qid){f->pinbr,0,QTDIR};
117
			f->inbr = f->pinbr;
118
			if( (nr = get_file(f, "..")) < 0 )
119
				goto error;
120
			f->pinbr = nr;
121
		}
122
	}else{
123
		f->pinbr = f->inbr;
124
		if( (nr = get_file(f, name)) < 0 )
125
			goto error;
126
		if( get_inode(f, nr) < 0 )
127
			goto error;
128
		*qid = (Qid){nr,0,0};
129
		if( nr == EXT2_ROOT_INODE )
130
			*qid = f->xf->rootqid;
131
		else if( S_ISDIR(getmode(f)) )
132
			 qid->type = QTDIR;
133
		/*strcpy(f->name, thdr.name);*/
134
	}
135
ok:
136
	chat("OK\n");
137
	return 0;
138
error:
139
	f->pinbr = sinbr;
140
	chat("%s\n", xerrstr(Enonexist));
141
	return xerrstr(Enonexist);
142
}
143
static void
144
rstat(Req *r)
145
{
146
	Xfile *f=xfile(r->fid, Asis);
147
 
148
	chat("stat(fid=%d)...", thdr.fid);
149
	errno = 0;
150
	if( !f )
151
		errno = Eio;
152
	else{
153
		dostat(r->fid->qid, f, &r->d);
154
	}
155
	response(r);
156
}
157
static void
158
rwstat(Req *r)
159
{
160
	Xfile *f=xfile(r->fid, Asis);
161
 
162
	chat("wstat(fid=%d)...", thdr.fid);
163
	errno = 0;
164
	if( !f )
165
		errno = Eio;
166
	else
167
		dowstat(f, &r->d);
168
	response(r);	
169
}
170
static void
171
rread(Req *r)
172
{
173
	Xfile *f; 
174
	int nr;
175
 
176
	chat("read(fid=%d,offset=%lld,count=%d)...",
177
		thdr.fid, thdr.offset, thdr.count);
178
	errno = 0;
179
	if ( !(f=xfile(r->fid, Asis)) )
180
		goto error;
181
	if( r->fid->qid.type & QTDIR ){
182
		nr = readdir(f, r->rbuf, thdr.offset, thdr.count);
183
	}else
184
		nr = readfile(f, r->rbuf, thdr.offset, thdr.count);
185
 
186
	if(nr >= 0){
187
		rhdr.count = nr;
188
		chat("rcnt=%d...OK\n", nr);
189
		respond(r, nil);
190
		return;
191
	}
192
error:
193
	errno = Eio;
194
	response(r);
195
}
196
static void
197
rwrite(Req *r)
198
{
199
	Xfile *f; int nr;
200
 
201
	chat("write(fid=%d,offset=%lld,count=%d)...",
202
		thdr.fid, thdr.offset, thdr.count);
203
 
204
	errno = 0;
205
	if (!(f=xfile(r->fid, Asis)) ){
206
		errno = Eio;
207
		goto error;
208
	}
209
	if( !S_ISREG(getmode(f)) ){
210
		errno = Elink;
211
		goto error;
212
	}
213
	nr = writefile(f, thdr.data, thdr.offset, thdr.count);
214
	if(nr >= 0){	
215
		rhdr.count = nr;
216
		chat("rcnt=%d...OK\n", nr);
217
		respond(r, nil);
218
		return;
219
	}
220
	errno = Eio;
221
error:
222
	response(r);
223
}
224
static void
225
destroyfid(Fid *fid)
226
{
227
	chat("destroy(fid=%d)\n", fid->fid);
228
	xfile(fid, Clunk);
229
	/*syncbuf(xf);*/
230
}
231
static void
232
ropen(Req *r)
233
{
234
	Xfile *f;
235
 
236
	chat("open(fid=%d,mode=%d)...", thdr.fid, thdr.mode);
237
 
238
	errno = 0;
239
	f = xfile(r->fid, Asis);
240
	if( !f ){
241
		errno = Eio;
242
		goto error;
243
	}
244
 
245
	if(thdr.mode & OTRUNC){
246
		if( !S_ISREG(getmode(f)) ){
247
			errno = Eperm;
248
			goto error;
249
		}
250
		if(truncfile(f) < 0){
251
			goto error;
252
		}
253
	}
254
	chat("f->qid=0x%8.8lux...", r->fid->qid.path);
255
	rhdr.qid = r->fid->qid;
256
error:
257
	response(r);
258
}
259
static void
260
rcreate(Req *r)
261
{
262
	Xfile *f;
263
	int inr, perm;
264
 
265
	chat("create(fid=%d,name=\"%s\",perm=%uo,mode=%d)...",
266
		thdr.fid, thdr.name, thdr.perm, thdr.mode);
267
 
268
	errno = 0;
269
	if(strcmp(thdr.name, ".") == 0 || strcmp(thdr.name, "..") == 0){
270
		errno = Eperm;
271
		goto error;
272
	}
273
	f = xfile(r->fid, Asis);
274
	if( !f ){
275
		errno = Eio;
276
		goto error;
277
	}
278
	if( strlen(thdr.name) > EXT2_NAME_LEN ){
279
		chat("name too long ...");
280
		errno = Elongname;
281
		goto error;
282
	}
283
 
284
	/* create */
285
	errno = 0;
286
	if( thdr.perm & DMDIR ){
287
		perm = (thdr.perm & ~0777) | 
288
				(getmode(f) & thdr.perm & 0777);
289
		perm |= S_IFDIR;
290
		inr = create_dir(f, thdr.name, perm);
291
	}else{
292
		perm = (thdr.perm & (~0777|0111)) |
293
				(getmode(f) & thdr.perm & 0666);
294
		perm |= S_IFREG;
295
		inr = create_file(f, thdr.name, perm);
296
 
297
	}
298
	if( inr < 0 )
299
		goto error;
300
 
301
	/* fill with new inode */
302
	f->pinbr = f->inbr;
303
	if( get_inode(f, inr) < 0 ){
304
		errno = Eio;
305
		goto error;
306
	}
307
	r->fid->qid = (Qid){inr, 0, 0};
308
	if( S_ISDIR(getmode(f)) )
309
		r->fid->qid.type |= QTDIR;
310
	chat("f->qid=0x%8.8lux...", r->fid->qid.path);
311
	rhdr.qid = r->fid->qid;
312
error:
313
	response(r);
314
}
315
static void
316
rremove(Req *r)
317
{
318
	Xfile *f=xfile(r->fid, Asis);
319
 
320
	chat("remove(fid=%d) ...", thdr.fid);
321
 
322
	errno = 0;
323
	if(!f){
324
		errno = Eio;
325
		goto error;
326
	}
327
 
328
	/* check permission here !!!!*/
329
 
330
	unlink(f);
331
 
332
error:
333
	response(r);
334
}
335
 
336
Srv ext2srv = {
337
	.destroyfid =	destroyfid,
338
	.attach =	rattach,
339
	.stat =		rstat,
340
	.wstat =	rwstat,
341
	.clone =	rclone,
342
	.walk1 =	rwalk1,
343
	.open =		ropen,
344
	.read =		rread,
345
	.write =	rwrite,
346
	.create =	rcreate,
347
	.remove =	rremove,
348
};