This source file includes following definitions.
- xfs_handle_stale
- xfs_open_valid
- xfs_attr_valid
- xfs_data_valid
- xfs_open_common
- do_fsync
- xfs_fsync_common
- xfs_close_common
- xfs_uio_end_length
- xfs_read_common
- xfs_write_common
- xfs_getattr_common
- xfs_setattr_common
- check_rights
- xfs_access_common
- xfs_lookup_common
- xfs_create_common
- xfs_remove_common
- xfs_rename_common
- xfs_mkdir_common
- xfs_rmdir_common
- xfs_readdir_common
- xfs_link_common
- xfs_symlink_common
- xfs_readlink_common
- xfs_inactive_common
- xfs_reclaim_common
- xfs_advlock_common
- xfs_printnode_common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include <xfs/xfs_locl.h>
39 #include <xfs/xfs_message.h>
40 #include <xfs/xfs_common.h>
41 #include <xfs/xfs_fs.h>
42 #include <xfs/xfs_dev.h>
43 #include <xfs/xfs_deb.h>
44 #include <xfs/xfs_syscalls.h>
45 #include <xfs/xfs_vnodeops.h>
46
47 RCSID("$arla: xfs_vnodeops-common.c,v 1.94 2003/01/27 11:58:50 lha Exp $");
48
49 static void
50 xfs_handle_stale(struct xfs_node *xn)
51 {
52 #if __APPLE__
53 struct vnode *vp = XNODE_TO_VNODE(xn);
54 #endif
55
56 if ((xn->flags & NNPFS_STALE) == 0)
57 return;
58
59 #if __APPLE__
60 if (UBCISVALID(vp) && !ubc_isinuse(vp, 1)) {
61 xn->flags &= ~NNPFS_STALE;
62 ubc_setsize(vp, 0);
63 NNPFS_TOKEN_CLEAR(xn, ~0,
64 NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
65 NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
66 }
67 #endif
68 }
69
70 int
71 xfs_open_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
72 u_int tok)
73 {
74 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
75 struct xfs_node *xn = VNODE_TO_XNODE(vp);
76 int error = 0;
77
78 NNPFSDEB(XDEBVFOPS, ("xfs_open_valid\n"));
79
80 xfs_handle_stale(xn);
81
82 do {
83 if (!NNPFS_TOKEN_GOT(xn, tok)) {
84 struct xfs_message_open msg;
85
86 msg.header.opcode = NNPFS_MSG_OPEN;
87 msg.cred.uid = cred->cr_uid;
88 msg.cred.pag = xfs_get_pag(cred);
89 msg.handle = xn->handle;
90 msg.tokens = tok;
91
92 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
93
94 if (error == 0)
95 error = ((struct xfs_message_wakeup *) & msg)->error;
96 } else {
97 goto done;
98 }
99 } while (error == 0);
100
101 done:
102 NNPFSDEB(XDEBVFOPS, ("xfs_open_valid: error = %d\n", error));
103
104 return error;
105 }
106
107 int
108 xfs_attr_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
109 u_int tok)
110 {
111 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
112 struct xfs_node *xn = VNODE_TO_XNODE(vp);
113 int error = 0;
114 xfs_pag_t pag = xfs_get_pag(cred);
115
116 do {
117 if (!NNPFS_TOKEN_GOT(xn, tok) || !xfs_has_pag(xn, pag)) {
118 struct xfs_message_getattr msg;
119
120 msg.header.opcode = NNPFS_MSG_GETATTR;
121 msg.cred.uid = cred->cr_uid;
122 msg.cred.pag = pag;
123 msg.handle = xn->handle;
124 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
125 if (error == 0)
126 error = ((struct xfs_message_wakeup *) & msg)->error;
127 } else {
128 goto done;
129 }
130 } while (error == 0);
131
132 done:
133 return error;
134 }
135
136 int
137 xfs_data_valid(struct vnode *vp, struct ucred *cred, d_thread_t *p,
138 u_int tok, uint32_t want_offset)
139 {
140 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
141 struct xfs_node *xn = VNODE_TO_XNODE(vp);
142 int error = 0;
143 uint32_t offset;
144 struct xfs_message_getdata msg;
145
146 do {
147 offset = want_offset;
148 if (NNPFS_TOKEN_GOT(xn, tok|NNPFS_ATTR_R) && offset > xn->attr.va_size) {
149 offset = xn->attr.va_size;
150 }
151
152 NNPFSDEB(XDEBVNOPS, ("xfs_data_valid: offset: want %ld has %ld, "
153 "tokens: want %lx has %lx length: %ld\n",
154 (long) offset, (long) xn->offset,
155 (long) tok, (long) xn->tokens,
156 (long) xn->attr.va_size));
157
158 if (NNPFS_TOKEN_GOT(xn, tok)) {
159 if (offset <= xn->offset || xn->attr.va_type == VDIR) {
160 break;
161 }
162 }
163
164 msg.header.opcode = NNPFS_MSG_GETDATA;
165 msg.cred.uid = cred->cr_uid;
166 msg.cred.pag = xfs_get_pag(cred);
167 msg.handle = xn->handle;
168 msg.tokens = tok;
169 msg.offset = offset;
170
171 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
172
173 if (error == 0)
174 error = ((struct xfs_message_wakeup *) & msg)->error;
175
176 } while (error == 0);
177
178 return error;
179 }
180
181 int
182 xfs_open_common(struct vnode *vp,
183 int mode,
184 struct ucred *cred,
185 d_thread_t *p)
186 {
187 struct xfs_node *xn = VNODE_TO_XNODE(vp);
188 int ret;
189
190 NNPFSDEB(XDEBVNOPS, ("xfs_open\n"));
191
192 if (mode & FWRITE) {
193 ret = xfs_open_valid(vp, cred, p, NNPFS_OPEN_NW);
194 } else {
195 ret = xfs_open_valid(vp, cred, p, NNPFS_OPEN_NR);
196 }
197
198
199
200 if (mode & FWRITE)
201 xfs_update_write_cred(xn, cred);
202 xfs_update_read_cred(xn, cred);
203
204 return ret;
205 }
206
207 static int
208 do_fsync(struct xfs *xfsp,
209 struct xfs_node *xn,
210 struct ucred *cred,
211 d_thread_t *p,
212 u_int flag)
213 {
214 int error;
215 struct xfs_message_putdata msg;
216
217 msg.header.opcode = NNPFS_MSG_PUTDATA;
218 if (cred != NOCRED) {
219 msg.cred.uid = cred->cr_uid;
220 msg.cred.pag = xfs_get_pag(cred);
221 } else {
222 msg.cred.uid = 0;
223 msg.cred.pag = NNPFS_ANONYMOUSID;
224 }
225 msg.handle = xn->handle;
226 vattr2xfs_attr(&xn->attr, &msg.attr);
227 msg.flag = flag;
228
229 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
230
231 if (error == 0)
232 error = ((struct xfs_message_wakeup *) & msg)->error;
233
234 if (error == 0)
235 xn->flags &= ~NNPFS_DATA_DIRTY;
236
237 return error;
238 }
239
240 int
241 xfs_fsync_common(struct vnode *vp, struct ucred *cred,
242 int waitfor, d_thread_t *proc)
243 {
244 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
245 struct xfs_node *xn = VNODE_TO_XNODE(vp);
246 int error = 0;
247
248 NNPFSDEB(XDEBVNOPS, ("xfs_fsync: %lx\n", (unsigned long)vp));
249
250
251
252
253
254
255 if (xn == NULL) {
256 printf("NNPFS PANIC WARNING! xfs_fsync called after reclaiming!\n");
257 return 0;
258 }
259
260 xfs_pushdirty(vp, cred, proc);
261
262 if (xn->flags & NNPFS_DATA_DIRTY) {
263 #ifdef FSYNC_RECLAIM
264
265 if (waitfor & FSYNC_RECLAIM) {
266 printf("xfs_fsync: data lost, failed to write back\n");
267 xn->flags &= ~NNPFS_DATA_DIRTY;
268 return 0;
269 }
270 #endif
271 error = do_fsync(xfsp, xn, cred, proc, NNPFS_WRITE | NNPFS_FSYNC);
272 }
273
274 return error;
275 }
276
277 int
278 xfs_close_common(struct vnode *vp, int fflag,
279 d_thread_t *proc, struct ucred *cred)
280 {
281 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
282 struct xfs_node *xn = VNODE_TO_XNODE(vp);
283 int error = 0;
284
285 NNPFSDEB(XDEBVNOPS,
286 ("xfs_close cred = %lx, fflag = %x, xn->flags = %x\n",
287 (unsigned long)cred, fflag, xn->flags));
288
289 if (vp->v_type == VREG)
290 xfs_pushdirty(vp, cred, proc);
291
292 if (fflag & FWRITE && xn->flags & NNPFS_DATA_DIRTY)
293 error = do_fsync(xfsp, xn, cred, proc, NNPFS_WRITE);
294
295 return error;
296 }
297
298 size_t
299 xfs_uio_end_length (struct uio *uio)
300 {
301 #ifdef DIAGNOSTIC
302 size_t sz = 0;
303 int i;
304
305 for (i = 0; i < uio->uio_iovcnt; i++)
306 sz += uio->uio_iov[i].iov_len;
307 if (sz != uio->uio_resid)
308 panic("xfs_uio_end_length");
309 #endif
310 return uio->uio_offset + uio->uio_resid;
311 }
312
313
314 int
315 xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag,
316 struct ucred *cred)
317 {
318 int error = 0;
319 int i;
320
321 NNPFSDEB(XDEBVNOPS, ("xfs_read\n"));
322
323 xfs_update_read_cred(VNODE_TO_XNODE(vp), cred);
324
325 #ifdef HAVE_FREEBSD_THREAD
326 error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uio), NNPFS_DATA_R,
327 xfs_uio_end_length(uio));
328 #else
329 error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uio), NNPFS_DATA_R,
330 xfs_uio_end_length(uio));
331 #endif
332
333 NNPFSDEB(XDEBVNOPS, ("xfs_read: iovcnt: %d\n", uio->uio_iovcnt));
334 for (i = 0; i < uio->uio_iovcnt; i++)
335 NNPFSDEB(XDEBVNOPS, (" base: %lx len: %lu\n",
336 (unsigned long)uio->uio_iov[i].iov_base,
337 (unsigned long)uio->uio_iov[i].iov_len));
338
339 if (error == 0) {
340 struct vnode *t = DATA_FROM_VNODE(vp);
341
342 #ifdef HAVE_FREEBSD_THREAD
343 xfs_vfs_readlock(t, xfs_uio_to_thread(uio));
344 xfs_vop_read(t, uio, ioflag, cred, error);
345 xfs_vfs_unlock(t, xfs_uio_to_thread(uio));
346 #else
347 xfs_vfs_readlock(t, xfs_uio_to_proc(uio));
348 xfs_vop_read(t, uio, ioflag, cred, error);
349 xfs_vfs_unlock(t, xfs_uio_to_proc(uio));
350 #endif
351 }
352
353 NNPFSDEB(XDEBVNOPS, ("xfs_read offset: %lu resid: %lu\n",
354 (unsigned long)uio->uio_offset,
355 (unsigned long)uio->uio_resid));
356 NNPFSDEB(XDEBVNOPS, ("xfs_read error: %d\n", error));
357
358 return error;
359 }
360
361 int
362 xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag,
363 struct ucred *cred)
364 {
365 struct xfs_node *xn = VNODE_TO_XNODE(vp);
366 int error = 0;
367
368 NNPFSDEB(XDEBVNOPS, ("xfs_write\n"));
369
370 xfs_update_write_cred(xn, cred);
371
372 #ifdef HAVE_FREEBSD_THREAD
373 error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_W,
374 VNODE_TO_XNODE(vp)->attr.va_size);
375 #else
376 error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_W,
377 VNODE_TO_XNODE(vp)->attr.va_size);
378 #endif
379
380 if (error == 0) {
381 struct vnode *t = DATA_FROM_XNODE(xn);
382 struct vattr sub_attr;
383 int error2 = 0;
384
385 #ifdef HAVE_FREEBSD_THREAD
386 xfs_vfs_writelock(t, xfs_uio_to_thread(uiop));
387 xfs_vop_write(t, uiop, ioflag, cred, error);
388 VNODE_TO_XNODE(vp)->flags |= NNPFS_DATA_DIRTY;
389 xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_thread(uiop), error2);
390 #else
391 xfs_vfs_writelock(t, xfs_uio_to_proc(uiop));
392 xfs_vop_write(t, uiop, ioflag, cred, error);
393 VNODE_TO_XNODE(vp)->flags |= NNPFS_DATA_DIRTY;
394 xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_proc(uiop), error2);
395 #endif
396
397 if (error2 == 0) {
398 xn->attr.va_size = sub_attr.va_size;
399 xn->attr.va_bytes = sub_attr.va_size;
400 xn->attr.va_mtime = sub_attr.va_mtime;
401 xfs_set_vp_size(vp, sub_attr.va_size);
402 xn->offset = sub_attr.va_size;
403 }
404 #ifdef HAVE_FREEBSD_THREAD
405 xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
406 #else
407 xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
408 #endif
409 }
410
411 return error;
412 }
413
414 int
415 xfs_getattr_common(struct vnode *vp, struct vattr *vap,
416 struct ucred *cred, d_thread_t *p)
417 {
418 int error = 0;
419
420 struct xfs_node *xn = VNODE_TO_XNODE(vp);
421
422 NNPFSDEB(XDEBVNOPS, ("xfs_getattr\n"));
423
424 error = xfs_attr_valid(vp, cred, p, NNPFS_ATTR_R);
425 if (error == 0)
426 *vap = xn->attr;
427 return error;
428 }
429
430 int
431 xfs_setattr_common(struct vnode *vp, struct vattr *vap,
432 struct ucred *cred, d_thread_t *p)
433 {
434 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
435 struct xfs_node *xn = VNODE_TO_XNODE(vp);
436 int error = 0;
437
438 NNPFSDEB(XDEBVNOPS, ("xfs_setattr\n"));
439
440 #define CHECK_NNPFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A)
441 if (CHECK_NNPFSATTR(va_mode,(mode_t)) &&
442 CHECK_NNPFSATTR(va_nlink,(short)) &&
443 CHECK_NNPFSATTR(va_size,(va_size_t)) &&
444 CHECK_NNPFSATTR(va_uid,(uid_t)) &&
445 CHECK_NNPFSATTR(va_gid,(gid_t)) &&
446 CHECK_NNPFSATTR(va_mtime.tv_sec,(unsigned int)) &&
447 CHECK_NNPFSATTR(va_fileid,(long)) &&
448 CHECK_NNPFSATTR(va_type,(enum vtype)))
449 return 0;
450 #undef CHECK_NNPFSATTR
451
452 if (NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_W)) {
453
454 VNODE_TO_XNODE(vp)->flags |= NNPFS_ATTR_DIRTY;
455 error = EINVAL;
456 goto done;
457 } else {
458 struct xfs_message_putattr msg;
459
460 msg.header.opcode = NNPFS_MSG_PUTATTR;
461 if (cred != NOCRED) {
462 msg.cred.uid = cred->cr_uid;
463 msg.cred.pag = xfs_get_pag(cred);
464 } else {
465 msg.cred.uid = 0;
466 msg.cred.pag = NNPFS_ANONYMOUSID;
467 }
468 msg.handle = xn->handle;
469 vattr2xfs_attr(vap, &msg.attr);
470 if (NNPFS_TOKEN_GOT(xn, NNPFS_DATA_R)) {
471 if (vp->v_type == VREG) {
472 if (vap->va_size != (va_size_t)VNOVAL)
473 XA_SET_SIZE(&msg.attr, vap->va_size);
474 else
475 XA_SET_SIZE(&msg.attr, xn->attr.va_size);
476 #ifdef __APPLE__
477
478 if (UBCINFOEXISTS(vp))
479 ubc_setsize(vp, msg.attr.xa_size);
480 #endif
481 }
482 if (vap->va_mtime.tv_sec != (unsigned int)VNOVAL)
483 XA_SET_MTIME(&msg.attr, vap->va_mtime.tv_sec);
484 else
485 XA_SET_MTIME(&msg.attr, xn->attr.va_mtime.tv_sec);
486 }
487
488 NNPFS_TOKEN_CLEAR(xn, NNPFS_ATTR_VALID, NNPFS_ATTR_MASK);
489 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
490 if (error == 0)
491 error = ((struct xfs_message_wakeup *) & msg)->error;
492 }
493
494 done:
495 return error;
496 }
497
498 static int
499 check_rights (u_char rights, int mode)
500 {
501 int error = 0;
502
503 if (mode & VREAD)
504 if ((rights & NNPFS_RIGHT_R) == 0)
505 error = EACCES;
506 if (mode & VWRITE)
507 if ((rights & NNPFS_RIGHT_W) == 0)
508 error = EACCES;
509 if (mode & VEXEC)
510 if ((rights & NNPFS_RIGHT_X) == 0)
511 error = EACCES;
512 return error;
513 }
514
515 int
516 xfs_access_common(struct vnode *vp, int mode, struct ucred *cred,
517 d_thread_t *p)
518 {
519 int error = 0;
520 xfs_pag_t pag = xfs_get_pag(cred);
521
522 NNPFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode));
523
524 error = xfs_attr_valid(vp, cred, p, NNPFS_ATTR_R);
525 if (error == 0) {
526 struct xfs_node *xn = VNODE_TO_XNODE(vp);
527 int i;
528
529 error = check_rights (xn->anonrights, mode);
530
531 if (error == 0)
532 goto done;
533
534 NNPFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n"));
535
536 error = EACCES;
537
538 for (i = 0; i < MAXRIGHTS; i++)
539 if (xn->id[i] == pag) {
540 error = check_rights (xn->rights[i], mode);
541 break;
542 }
543 }
544
545 done:
546 NNPFSDEB(XDEBVNOPS, ("xfs_access(0%o) = %d\n", mode, error));
547
548 return error;
549 }
550
551 int
552 xfs_lookup_common(struct vnode *dvp,
553 xfs_componentname *cnp,
554 struct vnode **vpp)
555 {
556 struct xfs_message_getnode msg;
557 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
558 struct xfs_node *d = VNODE_TO_XNODE(dvp);
559 int error = 0;
560 #ifdef HAVE_FREEBSD_THREAD
561 d_thread_t *proc = xfs_cnp_to_thread(cnp);
562 struct ucred *cred = xfs_thread_to_cred(proc);
563 #else
564 d_thread_t *proc = xfs_cnp_to_proc(cnp);
565 struct ucred *cred = xfs_proc_to_cred(proc);
566 #endif
567
568 NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: enter\n"));
569
570 *vpp = NULL;
571
572 if (cnp->cn_namelen >= NNPFS_MAX_NAME)
573 return ENAMETOOLONG;
574
575 if (dvp->v_type != VDIR)
576 return ENOTDIR;
577
578 if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
579 *vpp = dvp;
580 VREF(*vpp);
581 return 0;
582 }
583
584 do {
585 xfs_vop_access(dvp, VEXEC, cred, proc, error);
586 if (error != 0)
587 goto done;
588
589 NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: dvp = %lx\n",
590 (unsigned long) dvp));
591 NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: cnp = %lx, "
592 "cnp->cn_nameiop = %d\n",
593 (unsigned long) cnp, (int)cnp->cn_nameiop));
594
595
596 error = xfs_dnlc_lookup(dvp, cnp, vpp);
597 if (error == 0) {
598
599
600
601
602
603 #if 0
604 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
605 && (cnp->cn_flags & ISLASTCN)) {
606 error = EJUSTRETURN;
607 goto done;
608 }
609 #endif
610
611 msg.header.opcode = NNPFS_MSG_GETNODE;
612 if (cnp->cn_cred != NOCRED) {
613 msg.cred.uid = cnp->cn_cred->cr_uid;
614 msg.cred.pag = xfs_get_pag(cnp->cn_cred);
615 } else {
616 msg.cred.uid = 0;
617 msg.cred.pag = NNPFS_ANONYMOUSID;
618 }
619 msg.parent_handle = d->handle;
620 memcpy(msg.name, cnp->cn_nameptr, cnp->cn_namelen);
621 msg.name[cnp->cn_namelen] = '\0';
622 error = xfs_message_rpc(xfsp->fd, &msg.header,
623 sizeof(msg), proc);
624 if (error == 0)
625 error = ((struct xfs_message_wakeup *) & msg)->error;
626 if(error == ENOENT && cnp->cn_nameiop != CREATE) {
627 NNPFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %lx (%s, %ld)\n",
628 (unsigned long)dvp,
629 cnp->cn_nameptr, cnp->cn_namelen));
630 xfs_dnlc_enter (dvp, cnp, NULL);
631 }
632 } else if (error == -1) {
633 error = 0;
634 goto done;
635 }
636 } while (error == 0);
637
638 done:
639 NNPFSDEB(XDEBVNOPS, ("xfs_lookup_common: return error = %d\n", error));
640 return error;
641 }
642
643 int
644 xfs_create_common(struct vnode *dvp,
645 const char *name,
646 struct vattr *vap,
647 struct ucred *cred,
648 d_thread_t *p)
649 {
650 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
651 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
652 int error = 0;
653
654 NNPFSDEB(XDEBVNOPS, ("xfs_create: (%lx, %s)\n",
655 (unsigned long)dvp, name));
656 {
657 struct xfs_message_create msg;
658
659 msg.header.opcode = NNPFS_MSG_CREATE;
660 msg.parent_handle = xn->handle;
661 if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
662 return ENAMETOOLONG;
663 vattr2xfs_attr(vap, &msg.attr);
664
665 msg.mode = 0;
666 if (cred != NOCRED) {
667 msg.cred.uid = cred->cr_uid;
668 msg.cred.pag = xfs_get_pag(cred);
669 } else {
670 msg.cred.uid = 0;
671 msg.cred.pag = NNPFS_ANONYMOUSID;
672 }
673
674
675 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
676
677 if (error == 0)
678 error = ((struct xfs_message_wakeup *) & msg)->error;
679 }
680
681 #if 0
682 if (error == EEXIST)
683 error = 0;
684 #endif
685
686 return error;
687 }
688
689 int
690 xfs_remove_common(struct vnode *dvp,
691 struct vnode *vp,
692 const char *name,
693 struct ucred *cred,
694 d_thread_t *p)
695 {
696 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
697 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
698 struct xfs_message_remove msg;
699 int error;
700
701 NNPFSDEB(XDEBVNOPS, ("xfs_remove: %s\n", name));
702
703 msg.header.opcode = NNPFS_MSG_REMOVE;
704 msg.parent_handle = xn->handle;
705 msg.cred.uid = cred->cr_uid;
706 msg.cred.pag = xfs_get_pag(cred);
707
708 if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
709 error = ENAMETOOLONG;
710 else
711 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
712 if (error == 0)
713 error = ((struct xfs_message_wakeup *) &msg)->error;
714
715 if (error == 0)
716 xfs_dnlc_purge (vp);
717
718 return error;
719 }
720
721 int
722 xfs_rename_common(struct vnode *fdvp,
723 struct vnode *fvp,
724 const char *fname,
725 struct vnode *tdvp,
726 struct vnode *tvp,
727 const char *tname,
728 struct ucred *cred,
729 d_thread_t *p)
730 {
731 struct xfs *xfsp = NNPFS_FROM_VNODE(fdvp);
732 int error;
733
734 NNPFSDEB(XDEBVNOPS, ("xfs_rename: %s %s\n", fname, tname));
735
736 if ((fvp->v_mount != tdvp->v_mount)
737 || (tvp && (fvp->v_mount != tvp->v_mount))) {
738 return EXDEV;
739 }
740
741 {
742 struct xfs_message_rename msg;
743
744 msg.header.opcode = NNPFS_MSG_RENAME;
745 msg.old_parent_handle = VNODE_TO_XNODE(fdvp)->handle;
746 if (strlcpy(msg.old_name, fname, sizeof(msg.old_name)) >= NNPFS_MAX_NAME)
747 return ENAMETOOLONG;
748 msg.new_parent_handle = VNODE_TO_XNODE(tdvp)->handle;
749 if (strlcpy(msg.new_name, tname, sizeof(msg.new_name)) >= NNPFS_MAX_NAME)
750 return ENAMETOOLONG;
751 msg.cred.uid = cred->cr_uid;
752 msg.cred.pag = xfs_get_pag(cred);
753 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
754 if (error == 0)
755 error = ((struct xfs_message_wakeup *) &msg)->error;
756
757 }
758
759 NNPFSDEB(XDEBVNOPS, ("xfs_rename: error = %d\n", error));
760
761 return error;
762 }
763
764 int
765 xfs_mkdir_common(struct vnode *dvp,
766 const char *name,
767 struct vattr *vap,
768 struct ucred *cred,
769 d_thread_t *p)
770 {
771 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
772 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
773 int error = 0;
774
775 NNPFSDEB(XDEBVNOPS, ("xfs_mkdir: %s\n", name));
776 {
777 struct xfs_message_mkdir msg;
778
779 msg.header.opcode = NNPFS_MSG_MKDIR;
780 msg.parent_handle = xn->handle;
781 if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
782 return ENAMETOOLONG;
783 vattr2xfs_attr(vap, &msg.attr);
784 if (cred != NOCRED) {
785 msg.cred.uid = cred->cr_uid;
786 msg.cred.pag = xfs_get_pag(cred);
787 } else {
788 msg.cred.uid = 0;
789 msg.cred.pag = NNPFS_ANONYMOUSID;
790 }
791 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
792 if (error == 0)
793 error = ((struct xfs_message_wakeup *) & msg)->error;
794 }
795
796 return error;
797 }
798
799 int
800 xfs_rmdir_common(struct vnode *dvp,
801 struct vnode *vp,
802 const char *name,
803 struct ucred *cred,
804 d_thread_t *p)
805 {
806 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
807 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
808 struct xfs_message_rmdir msg;
809 int error;
810
811 NNPFSDEB(XDEBVNOPS, ("xfs_rmdir: %s\n", name));
812
813 msg.header.opcode = NNPFS_MSG_RMDIR;
814 msg.parent_handle = xn->handle;
815 msg.cred.uid = cred->cr_uid;
816 msg.cred.pag = xfs_get_pag(cred);
817 if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
818 error = ENAMETOOLONG;
819 else
820 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
821 if (error == 0)
822 error = ((struct xfs_message_wakeup *) &msg)->error;
823
824 if (error == 0)
825 xfs_dnlc_purge (vp);
826
827 NNPFSDEB(XDEBVNOPS, ("xfs_rmdir error: %d\n", error));
828
829 return error;
830 }
831
832 int
833 xfs_readdir_common(struct vnode *vp,
834 struct uio *uiop,
835 struct ucred *cred,
836 d_thread_t *p,
837 int *eofflag)
838 {
839 int error = 0;
840
841 NNPFSDEB(XDEBVNOPS, ("xfs_readdir\n"));
842
843 if(eofflag)
844 *eofflag = 0;
845 #ifdef HAVE_FREEBSD_THREAD
846 error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_R,
847 xfs_uio_end_length(uiop));
848 #else
849 error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_R,
850 xfs_uio_end_length(uiop));
851 #endif
852 if (error == 0) {
853 struct vnode *t = DATA_FROM_VNODE(vp);
854
855 #ifdef HAVE_FREEBSD_THREAD
856 xfs_vfs_readlock(t, xfs_uio_to_thread(uiop));
857 #else
858 xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
859 #endif
860 xfs_vop_read(t, uiop, 0, cred, error);
861 if (eofflag) {
862 struct vattr t_attr;
863 int error2;
864
865 #ifdef HAVE_FREEBSD_THREAD
866 xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_thread(uiop), error2);
867 #else
868 xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_proc(uiop), error2);
869 #endif
870 if (error2 == 0)
871 *eofflag = t_attr.va_size <= uiop->uio_offset;
872 }
873 #ifdef HAVE_FREEBSD_THREAD
874 xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
875 #else
876 xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
877 #endif
878 }
879 return error;
880 }
881
882 int
883 xfs_link_common(struct vnode *dvp,
884 struct vnode *vp,
885 const char *name,
886 struct ucred *cred,
887 d_thread_t *p)
888 {
889 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
890 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
891 struct xfs_node *xn2 = VNODE_TO_XNODE(vp);
892 struct xfs_message_link msg;
893 int error = 0;
894
895 NNPFSDEB(XDEBVNOPS, ("xfs_link: %s\n", name));
896
897 msg.header.opcode = NNPFS_MSG_LINK;
898 msg.parent_handle = xn->handle;
899 msg.from_handle = xn2->handle;
900 if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME)
901 return ENAMETOOLONG;
902 msg.cred.uid = cred->cr_uid;
903 msg.cred.pag = xfs_get_pag(cred);
904
905 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
906 if (error == 0)
907 error = ((struct xfs_message_wakeup *) & msg)->error;
908
909 return error;
910 }
911
912 int
913 xfs_symlink_common(struct vnode *dvp,
914 struct vnode **vpp,
915 xfs_componentname *cnp,
916 struct vattr *vap,
917 char *target)
918 {
919 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
920 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
921 #ifdef HAVE_FREEBSD_THREAD
922 d_thread_t *proc = xfs_cnp_to_thread(cnp);
923 struct ucred *cred = xfs_thread_to_cred(proc);
924 #else
925 d_thread_t *proc = xfs_cnp_to_proc(cnp);
926 struct ucred *cred = xfs_proc_to_cred(proc);
927 #endif
928 struct xfs_message_symlink *msg = NULL;
929 const char *name = cnp->cn_nameptr;
930 int error = 0;
931
932 NNPFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name));
933
934 msg = malloc(sizeof(struct xfs_message_symlink), M_TEMP, M_WAITOK);
935 if (msg == NULL) {
936 error = ENOMEM;
937 goto done;
938 }
939 memset(msg, 0, sizeof(*msg));
940
941 msg->header.opcode = NNPFS_MSG_SYMLINK;
942 msg->parent_handle = xn->handle;
943 vattr2xfs_attr(vap, &msg->attr);
944 msg->cred.uid = cred->cr_uid;
945 msg->cred.pag = xfs_get_pag(cred);
946 if (strlcpy (msg->contents, target, sizeof(msg->contents)) >= NNPFS_MAX_SYMLINK_CONTENT) {
947 error = ENAMETOOLONG;
948 goto done;
949 }
950 if (strlcpy(msg->name, name, sizeof(msg->name)) >= NNPFS_MAX_NAME) {
951 error = ENAMETOOLONG;
952 goto done;
953 }
954 error = xfs_message_rpc(xfsp->fd, &msg->header, sizeof(*msg), proc);
955 if (error == 0)
956 error = ((struct xfs_message_wakeup *) msg)->error;
957
958 done:
959 free(msg, M_TEMP);
960 return error;
961 }
962
963 int
964 xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred)
965 {
966 int error = 0;
967
968 NNPFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
969
970 #ifdef HAVE_FREEBSD_THREAD
971 error = xfs_data_valid(vp, cred, xfs_uio_to_thread(uiop), NNPFS_DATA_R,
972 xfs_uio_end_length(uiop));
973 #else
974 error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), NNPFS_DATA_R,
975 xfs_uio_end_length(uiop));
976 #endif
977 if (error == 0) {
978 struct vnode *t = DATA_FROM_VNODE(vp);
979
980 #ifdef HAVE_FREEBSD_THREAD
981 xfs_vfs_readlock(t, xfs_uio_to_thread(uiop));
982 xfs_vop_read(t, uiop, 0, cred, error);
983 xfs_vfs_unlock(t, xfs_uio_to_thread(uiop));
984 #else
985 xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
986 xfs_vop_read(t, uiop, 0, cred, error);
987 xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
988 #endif
989 }
990 return error;
991 }
992
993 int
994 xfs_inactive_common(struct vnode *vp, d_thread_t *p)
995 {
996 int error;
997 struct xfs_node *xn = VNODE_TO_XNODE(vp);
998
999 NNPFSDEB(XDEBVNOPS, ("xfs_inactive, %lx\n",
1000 (unsigned long)vp));
1001
1002
1003
1004
1005
1006
1007 if (xn == NULL) {
1008 NNPFSDEB(XDEBVNOPS, ("xfs_inactive: clean node\n"));
1009 return 0;
1010 }
1011
1012
1013
1014 if (vp->v_type == VREG)
1015 xfs_pushdirty(vp, xn->wr_cred, p);
1016
1017 error = xfs_fsync_common(vp, xn->wr_cred, 0, p);
1018 if (error) {
1019 printf ("xfs_inactive: failed writing back data: %d\n", error);
1020 xn->flags &= ~NNPFS_DATA_DIRTY;
1021 }
1022
1023
1024 if (!NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_R | NNPFS_ATTR_W)
1025 || (xn->flags & NNPFS_STALE) == NNPFS_STALE)
1026 {
1027 #ifndef __osf__
1028 xfs_vfs_unlock(vp, p);
1029 NNPFSDEB(XDEBVNOPS, ("xfs_inactive: vrecycle\n"));
1030 vrecycle(vp, p);
1031 #else
1032 NNPFSDEB(XDEBVNOPS, ("xfs_inactive: vp = %lx vp->v_usecount= %d\n",
1033 (unsigned long)vp, vp?vp->v_usecount:0));
1034 #endif
1035 } else {
1036 #ifndef __osf__
1037 xfs_vfs_unlock(vp, p);
1038 #endif
1039 xn->flags &= ~NNPFS_STALE;
1040 }
1041
1042 NNPFSDEB(XDEBVNOPS, ("return: xfs_inactive\n"));
1043
1044 return 0;
1045 }
1046
1047 int
1048 xfs_reclaim_common(struct vnode *vp)
1049 {
1050 struct xfs_message_inactivenode msg;
1051 struct xfs *xfsp = NNPFS_FROM_VNODE(vp);
1052 struct xfs_node *xn = VNODE_TO_XNODE(vp);
1053
1054 NNPFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx\n",
1055 (unsigned long)vp));
1056
1057 NNPFS_TOKEN_CLEAR(xn,
1058 ~0,
1059 NNPFS_OPEN_MASK | NNPFS_ATTR_MASK |
1060 NNPFS_DATA_MASK | NNPFS_LOCK_MASK);
1061
1062 if (DATA_FROM_XNODE(xn) != 0) {
1063 vrele(DATA_FROM_XNODE(xn));
1064 DATA_FROM_XNODE(xn) = 0;
1065 }
1066
1067 xfs_remove_node(&xfsp->nodehead, xn);
1068
1069 msg.header.opcode = NNPFS_MSG_INACTIVENODE;
1070 msg.handle = xn->handle;
1071 msg.flag = NNPFS_NOREFS | NNPFS_DELETE;
1072 xfs_message_send(xfsp->fd, &msg.header, sizeof(msg));
1073
1074 xfs_dnlc_purge(vp);
1075 free_xfs_node(xn);
1076 return 0;
1077 }
1078
1079
1080
1081
1082
1083 #if 0
1084
1085 int
1086 xfs_advlock_common(struct vnode *dvp,
1087 int locktype,
1088 unsigned long lockid,
1089 struct ucred *cred)
1090 {
1091 struct xfs *xfsp = NNPFS_FROM_VNODE(dvp);
1092 struct xfs_node *xn = VNODE_TO_XNODE(dvp);
1093 int error = 0;
1094
1095 NNPFSDEB(XDEBVNOPS, ("xfs_advlock\n"));
1096 {
1097 struct xfs_message_advlock msg;
1098
1099 msg.header.opcode = NNPFS_MSG_ADVLOCK;
1100 msg.handle = xn->handle;
1101 msg.locktype = locktype;
1102 msg.lockid = lockid;
1103
1104 if (cred != NOCRED) {
1105 msg.cred.uid = cred->cr_uid;
1106 msg.cred.pag = xfs_get_pag(cred);
1107 } else {
1108 msg.cred.uid = 0;
1109 msg.cred.pag = NNPFS_ANONYMOUSID;
1110 }
1111 error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), p);
1112 if (error == 0)
1113 error = ((struct xfs_message_wakeup *) & msg)->error;
1114 }
1115
1116 if (error == 0) {
1117
1118
1119
1120 } else {
1121
1122
1123 }
1124
1125 return error;
1126 }
1127
1128 #endif
1129
1130
1131
1132
1133
1134 void
1135 xfs_printnode_common (struct vnode *vp)
1136 {
1137 struct xfs_node *xn = VNODE_TO_XNODE(vp);
1138
1139 printf ("xnode: fid: %d.%d.%d.%d\n",
1140 xn->handle.a, xn->handle.b, xn->handle.c, xn->handle.d);
1141 printf ("\tattr: %svalid\n",
1142 NNPFS_TOKEN_GOT(xn, NNPFS_ATTR_VALID) ? "": "in");
1143 printf ("\tdata: %svalid\n",
1144 NNPFS_TOKEN_GOT(xn, NNPFS_DATA_VALID) ? "": "in");
1145 printf ("\tflags: 0x%x\n", xn->flags);
1146 printf ("\toffset: %d\n", xn->offset);
1147 }