Annotation of src/sys/fs/sysvbfs/sysvbfs_vnops.c, Revision 1.3.6.7
1.3.6.7 ! yamt 1: /* $NetBSD: sysvbfs_vnops.c,v 1.3.6.6 2007/12/07 17:32:10 yamt Exp $ */
1.3.6.2 yamt 2:
3: /*-
4: * Copyright (c) 2004 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by UCHIYAMA Yasushi.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: #include <sys/cdefs.h>
1.3.6.7 ! yamt 40: __KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.3.6.6 2007/12/07 17:32:10 yamt Exp $");
1.3.6.2 yamt 41:
42: #include <sys/param.h>
43: #include <sys/kernel.h>
44: #include <sys/resource.h>
45: #include <sys/vnode.h>
46: #include <sys/namei.h>
47: #include <sys/dirent.h>
48: #include <sys/malloc.h>
49: #include <sys/lockf.h>
50: #include <sys/unistd.h>
51: #include <sys/fcntl.h>
52: #include <sys/kauth.h>
53:
54: #include <fs/sysvbfs/sysvbfs.h>
55: #include <fs/sysvbfs/bfs.h>
56:
57: #ifdef SYSVBFS_VNOPS_DEBUG
58: #define DPRINTF(fmt, args...) printf(fmt, ##args)
59: #else
60: #define DPRINTF(arg...) ((void)0)
61: #endif
62: #define ROUND_SECTOR(x) (((x) + 511) & ~511)
63:
1.3.6.5 yamt 64: MALLOC_JUSTDEFINE(M_SYSVBFS_VNODE, "sysvbfs vnode", "sysvbfs vnode structures");
1.3.6.6 yamt 65: MALLOC_DECLARE(M_BFS);
1.3.6.2 yamt 66:
67: int
68: sysvbfs_lookup(void *arg)
69: {
70: struct vop_lookup_args /* {
71: struct vnode *a_dvp;
72: struct vnode **a_vpp;
73: struct componentname *a_cnp;
74: } */ *a = arg;
75: struct vnode *v = a->a_dvp;
76: struct sysvbfs_node *bnode = v->v_data;
77: struct bfs *bfs = bnode->bmp->bfs; /* my filesystem */
78: struct vnode *vpp = NULL;
79: struct bfs_dirent *dirent = NULL;
80: struct componentname *cnp = a->a_cnp;
81: int nameiop = cnp->cn_nameiop;
82: const char *name = cnp->cn_nameptr;
83: int namelen = cnp->cn_namelen;
84: int error;
1.3.6.4 yamt 85: bool islastcn = cnp->cn_flags & ISLASTCN;
1.3.6.2 yamt 86:
87: DPRINTF("%s: %s op=%d %ld\n", __FUNCTION__, name, nameiop,
88: cnp->cn_flags);
89:
1.3.6.3 yamt 90: KASSERT((cnp->cn_flags & ISDOTDOT) == 0);
1.3.6.7 ! yamt 91: if ((error = VOP_ACCESS(a->a_dvp, VEXEC, cnp->cn_cred)) != 0) {
1.3.6.2 yamt 92: return error; /* directory permittion. */
93: }
94:
95:
96: if (namelen == 1 && name[0] == '.') { /* "." */
97: VREF(v);
98: *a->a_vpp = v;
99: } else { /* Regular file */
100: if (!bfs_dirent_lookup_by_name(bfs, cnp->cn_nameptr,
101: &dirent)) {
102: if (nameiop != CREATE && nameiop != RENAME) {
103: DPRINTF("%s: no such a file. (1)\n",
104: __FUNCTION__);
105: return ENOENT;
106: }
1.3.6.7 ! yamt 107: if ((error = VOP_ACCESS(v, VWRITE, cnp->cn_cred)) != 0)
1.3.6.2 yamt 108: return error;
109: cnp->cn_flags |= SAVENAME;
110: return EJUSTRETURN;
111: }
112:
113: /* Allocate v-node */
1.3.6.3 yamt 114: if ((error = sysvbfs_vget(v->v_mount, dirent->inode, &vpp)) != 0) {
1.3.6.2 yamt 115: DPRINTF("%s: can't get vnode.\n", __FUNCTION__);
116: return error;
117: }
118: *a->a_vpp = vpp;
119: }
120:
121: if (cnp->cn_nameiop != LOOKUP && islastcn)
122: cnp->cn_flags |= SAVENAME;
123:
124: return 0;
125: }
126:
127: int
128: sysvbfs_create(void *arg)
129: {
130: struct vop_create_args /* {
131: struct vnode *a_dvp;
132: struct vnode **a_vpp;
133: struct componentname *a_cnp;
134: struct vattr *a_vap;
135: } */ *a = arg;
136: struct sysvbfs_node *bnode = a->a_dvp->v_data;
137: struct sysvbfs_mount *bmp = bnode->bmp;
138: struct bfs *bfs = bmp->bfs;
139: struct mount *mp = bmp->mountp;
140: struct bfs_dirent *dirent;
141: struct bfs_fileattr attr;
142: struct vattr *va = a->a_vap;
143: kauth_cred_t cr = a->a_cnp->cn_cred;
144: int err = 0;
145:
146: DPRINTF("%s: %s\n", __FUNCTION__, a->a_cnp->cn_nameptr);
147: KDASSERT(a->a_vap->va_type == VREG);
148: attr.uid = kauth_cred_geteuid(cr);
149: attr.gid = kauth_cred_getegid(cr);
150: attr.mode = va->va_mode;
151:
152: if ((err = bfs_file_create(bfs, a->a_cnp->cn_nameptr, 0, 0, &attr))
153: != 0) {
154: DPRINTF("%s: bfs_file_create failed.\n", __FUNCTION__);
155: goto unlock_exit;
156: }
157:
158: if (!bfs_dirent_lookup_by_name(bfs, a->a_cnp->cn_nameptr, &dirent))
159: panic("no dirent for created file.");
160:
161: if ((err = sysvbfs_vget(mp, dirent->inode, a->a_vpp)) != 0) {
162: DPRINTF("%s: sysvbfs_vget failed.\n", __FUNCTION__);
163: goto unlock_exit;
164: }
165: bnode = (*a->a_vpp)->v_data;
1.3.6.4 yamt 166: bnode->update_ctime = true;
167: bnode->update_mtime = true;
168: bnode->update_atime = true;
1.3.6.2 yamt 169:
170: unlock_exit:
171: /* unlock parent directory */
172: vput(a->a_dvp); /* locked at sysvbfs_lookup(); */
173:
174: return err;
175: }
176:
177: int
178: sysvbfs_open(void *arg)
179: {
180: struct vop_open_args /* {
181: struct vnode *a_vp;
182: int a_mode;
183: kauth_cred_t a_cred;
184: } */ *a = arg;
185: struct vnode *v = a->a_vp;
186: struct sysvbfs_node *bnode = v->v_data;
187: struct bfs_inode *inode = bnode->inode;
188: struct bfs *bfs = bnode->bmp->bfs;
189: struct bfs_dirent *dirent;
190:
191: DPRINTF("%s:\n", __FUNCTION__);
192: KDASSERT(v->v_type == VREG || v->v_type == VDIR);
193:
194: if (!bfs_dirent_lookup_by_inode(bfs, inode->number, &dirent))
195: return ENOENT;
1.3.6.4 yamt 196: bnode->update_atime = true;
1.3.6.2 yamt 197: if ((a->a_mode & FWRITE) && !(a->a_mode & O_APPEND)) {
198: bnode->size = 0;
199: } else {
200: bnode->size = bfs_file_size(inode);
201: }
202: bnode->data_block = inode->start_sector;
203:
204: return 0;
205: }
206:
207: int
208: sysvbfs_close(void *arg)
209: {
210: struct vop_close_args /* {
211: struct vnodeop_desc *a_desc;
212: struct vnode *a_vp;
213: int a_fflag;
214: kauth_cred_t a_cred;
215: } */ *a = arg;
216: struct vnode *v = a->a_vp;
217: struct sysvbfs_node *bnode = v->v_data;
218: struct bfs_fileattr attr;
219:
220: DPRINTF("%s:\n", __FUNCTION__);
221: uvm_vnp_setsize(v, bnode->size);
222:
223: memset(&attr, 0xff, sizeof attr); /* Set VNOVAL all */
224: if (bnode->update_atime)
1.3.6.3 yamt 225: attr.atime = time_second;
1.3.6.2 yamt 226: if (bnode->update_ctime)
1.3.6.3 yamt 227: attr.ctime = time_second;
1.3.6.2 yamt 228: if (bnode->update_mtime)
1.3.6.3 yamt 229: attr.mtime = time_second;
1.3.6.2 yamt 230: bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
231:
1.3.6.7 ! yamt 232: VOP_FSYNC(a->a_vp, a->a_cred, FSYNC_WAIT, 0, 0);
1.3.6.2 yamt 233:
234: return 0;
235: }
236:
237: int
238: sysvbfs_access(void *arg)
239: {
240: struct vop_access_args /* {
241: struct vnode *a_vp;
242: int a_mode;
243: kauth_cred_t a_cred;
244: } */ *ap = arg;
245: struct vnode *vp = ap->a_vp;
246: struct sysvbfs_node *bnode = vp->v_data;
247: struct bfs_fileattr *attr = &bnode->inode->attr;
248:
249: DPRINTF("%s:\n", __FUNCTION__);
250: if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
251: return EROFS;
252:
253: return vaccess(vp->v_type, attr->mode, attr->uid, attr->gid,
254: ap->a_mode, ap->a_cred);
255: }
256:
257: int
258: sysvbfs_getattr(void *v)
259: {
260: struct vop_getattr_args /* {
261: struct vnode *a_vp;
262: struct vattr *a_vap;
263: kauth_cred_t a_cred;
264: } */ *ap = v;
265: struct vnode *vp = ap->a_vp;
266: struct sysvbfs_node *bnode = vp->v_data;
267: struct bfs_inode *inode = bnode->inode;
268: struct bfs_fileattr *attr = &inode->attr;
269: struct sysvbfs_mount *bmp = bnode->bmp;
270: struct vattr *vap = ap->a_vap;
271:
272: DPRINTF("%s:\n", __FUNCTION__);
273:
274: vap->va_type = vp->v_type;
275: vap->va_mode = attr->mode;
276: vap->va_nlink = attr->nlink;
277: vap->va_uid = attr->uid;
278: vap->va_gid = attr->gid;
279: vap->va_fsid = bmp->devvp->v_rdev;
280: vap->va_fileid = inode->number;
281: vap->va_size = bfs_file_size(inode);
282: vap->va_blocksize = BFS_BSIZE;
283: vap->va_atime.tv_sec = attr->atime;
284: vap->va_mtime.tv_sec = attr->mtime;
285: vap->va_ctime.tv_sec = attr->ctime;
286: vap->va_birthtime.tv_sec = 0;
287: vap->va_gen = 1;
288: vap->va_flags = 0;
289: vap->va_rdev = 0; /* No device file */
290: vap->va_bytes = vap->va_size;
291: vap->va_filerev = 0;
292: vap->va_vaflags = 0;
293:
294: return 0;
295: }
296:
297: int
298: sysvbfs_setattr(void *arg)
299: {
300: struct vop_setattr_args /* {
301: struct vnode *a_vp;
302: struct vattr *a_vap;
303: kauth_cred_t a_cred;
304: struct proc *p;
305: } */ *ap = arg;
306: struct vnode *vp = ap->a_vp;
307: struct vattr *vap = ap->a_vap;
308: struct sysvbfs_node *bnode = vp->v_data;
309: struct bfs_inode *inode = bnode->inode;
310: struct bfs_fileattr *attr = &inode->attr;
311: struct bfs *bfs = bnode->bmp->bfs;
312:
313: DPRINTF("%s:\n", __FUNCTION__);
314: if (vp->v_mount->mnt_flag & MNT_RDONLY)
315: return EROFS;
316:
317: if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
318: (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
319: (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
320: ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL))
321: return EINVAL;
322:
323: if (vap->va_uid != (uid_t)VNOVAL)
324: attr->uid = vap->va_uid;
325: if (vap->va_gid != (uid_t)VNOVAL)
326: attr->gid = vap->va_gid;
327: if (vap->va_mode != (mode_t)VNOVAL)
328: attr->mode = vap->va_mode;
329: if (vap->va_atime.tv_sec != VNOVAL)
330: attr->atime = vap->va_atime.tv_sec;
331: if (vap->va_mtime.tv_sec != VNOVAL)
332: attr->mtime = vap->va_mtime.tv_sec;
333: if (vap->va_ctime.tv_sec != VNOVAL)
334: attr->ctime = vap->va_ctime.tv_sec;
335:
336: bfs_inode_set_attr(bfs, inode, attr);
337:
338: return 0;
339: }
340:
341: int
342: sysvbfs_read(void *arg)
343: {
344: struct vop_read_args /* {
345: struct vnode *a_vp;
346: struct uio *a_uio;
347: int a_ioflag;
348: kauth_cred_t a_cred;
349: } */ *a = arg;
350: struct vnode *v = a->a_vp;
351: struct uio *uio = a->a_uio;
352: struct sysvbfs_node *bnode = v->v_data;
353: struct bfs_inode *inode = bnode->inode;
354: vsize_t sz, filesz = bfs_file_size(inode);
355: int err;
356: void *win;
357: const int advice = IO_ADV_DECODE(a->a_ioflag);
358:
359: DPRINTF("%s: type=%d\n", __FUNCTION__, v->v_type);
360: if (v->v_type != VREG)
361: return EINVAL;
362:
363: while (uio->uio_resid > 0) {
364: if ((sz = MIN(filesz - uio->uio_offset, uio->uio_resid)) == 0)
365: break;
366:
367: win = ubc_alloc(&v->v_uobj, uio->uio_offset, &sz, advice,
368: UBC_READ);
369: err = uiomove(win, sz, uio);
370: ubc_release(win, 0);
371: if (err)
372: break;
373: DPRINTF("%s: read %ldbyte\n", __FUNCTION__, sz);
374: }
375:
376: return sysvbfs_update(v, NULL, NULL, UPDATE_WAIT);
377: }
378:
379: int
380: sysvbfs_write(void *arg)
381: {
382: struct vop_write_args /* {
383: struct vnode *a_vp;
384: struct uio *a_uio;
385: int a_ioflag;
386: kauth_cred_t a_cred;
387: } */ *a = arg;
388: struct vnode *v = a->a_vp;
389: struct uio *uio = a->a_uio;
390: struct sysvbfs_node *bnode = v->v_data;
391: struct bfs_inode *inode = bnode->inode;
1.3.6.4 yamt 392: bool extended = false;
1.3.6.2 yamt 393: vsize_t sz;
394: void *win;
395: int err = 0;
396:
397: if (a->a_vp->v_type != VREG)
398: return EISDIR;
399:
400: if (a->a_ioflag & IO_APPEND)
401: uio->uio_offset = bnode->size;
402:
403: if (uio->uio_resid == 0)
404: return 0;
405:
406: if (bnode->size < uio->uio_offset + uio->uio_resid) {
407: bnode->size = uio->uio_offset + uio->uio_resid;
408: uvm_vnp_setsize(v, bnode->size);
1.3.6.4 yamt 409: extended = true;
1.3.6.2 yamt 410: }
411:
412: while (uio->uio_resid > 0) {
413: sz = uio->uio_resid;
414: win = ubc_alloc(&v->v_uobj, uio->uio_offset, &sz,
415: UVM_ADV_NORMAL, UBC_WRITE);
416: err = uiomove(win, sz, uio);
417: ubc_release(win, 0);
418: if (err)
419: break;
420: DPRINTF("%s: write %ldbyte\n", __FUNCTION__, sz);
421: }
422: inode->end_sector = bnode->data_block +
423: (ROUND_SECTOR(bnode->size) >> DEV_BSHIFT) - 1;
424: inode->eof_offset_byte = bnode->data_block * DEV_BSIZE +
425: bnode->size - 1;
1.3.6.4 yamt 426: bnode->update_mtime = true;
1.3.6.2 yamt 427:
428: VN_KNOTE(v, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
429:
430: return err;
431: }
432:
433: int
434: sysvbfs_remove(void *arg)
435: {
436: struct vop_remove_args /* {
437: struct vnodeop_desc *a_desc;
438: struct vnode * a_dvp;
439: struct vnode * a_vp;
440: struct componentname * a_cnp;
441: } */ *ap = arg;
442: struct vnode *vp = ap->a_vp;
443: struct vnode *dvp = ap->a_dvp;
444: struct sysvbfs_node *bnode = vp->v_data;
445: struct sysvbfs_mount *bmp = bnode->bmp;
446: struct bfs *bfs = bmp->bfs;
447: int err;
448:
449: DPRINTF("%s: delete %s\n", __FUNCTION__, ap->a_cnp->cn_nameptr);
450:
451: if (vp->v_type == VDIR)
452: return EPERM;
453:
454: if ((err = bfs_file_delete(bfs, ap->a_cnp->cn_nameptr)) != 0)
455: DPRINTF("%s: bfs_file_delete failed.\n", __FUNCTION__);
456:
457: VN_KNOTE(ap->a_vp, NOTE_DELETE);
458: VN_KNOTE(ap->a_dvp, NOTE_WRITE);
459: if (dvp == vp)
460: vrele(vp);
461: else
462: vput(vp);
463: vput(dvp);
464:
465: return err;
466: }
467:
468: int
469: sysvbfs_rename(void *arg)
470: {
471: struct vop_rename_args /* {
472: struct vnode *a_fdvp; from parent-directory v-node
473: struct vnode *a_fvp; from file v-node
474: struct componentname *a_fcnp;
475: struct vnode *a_tdvp; to parent-directory
476: struct vnode *a_tvp; to file v-node
477: struct componentname *a_tcnp;
478: } */ *ap = arg;
479: struct vnode *fvp = ap->a_fvp;
480: struct vnode *tvp = ap->a_tvp;
481: struct sysvbfs_node *bnode = fvp->v_data;
482: struct bfs *bfs = bnode->bmp->bfs;
483: const char *from_name = ap->a_fcnp->cn_nameptr;
484: const char *to_name = ap->a_tcnp->cn_nameptr;
485: int error;
486:
487: DPRINTF("%s: %s->%s\n", __FUNCTION__, from_name, to_name);
488: if ((fvp->v_mount != ap->a_tdvp->v_mount) ||
489: (tvp && (fvp->v_mount != tvp->v_mount))) {
490: error = EXDEV;
491: printf("cross-device link\n");
492: goto out;
493: }
494:
495: KDASSERT(fvp->v_type == VREG);
1.3.6.4 yamt 496: KDASSERT(tvp == NULL ? true : tvp->v_type == VREG);
1.3.6.2 yamt 497:
498: error = bfs_file_rename(bfs, from_name, to_name);
499: out:
500: vput(ap->a_tdvp);
1.3.6.3 yamt 501: if (tvp)
502: vput(ap->a_tvp); /* locked on entry */
1.3.6.2 yamt 503: if (ap->a_tdvp != ap->a_fdvp)
504: vrele(ap->a_fdvp);
505: vrele(ap->a_fvp); /* unlocked and refcnt is incremented on entry. */
506:
507: return 0;
508: }
509:
510: int
511: sysvbfs_readdir(void *v)
512: {
513: struct vop_readdir_args /* {
514: struct vnode *a_vp;
515: struct uio *a_uio;
516: kauth_cred_t a_cred;
517: int *a_eofflag;
518: off_t **a_cookies;
519: int *a_ncookies;
520: } */ *ap = v;
521: struct uio *uio = ap->a_uio;
522: struct vnode *vp = ap->a_vp;
523: struct sysvbfs_node *bnode = vp->v_data;
524: struct bfs *bfs = bnode->bmp->bfs;
1.3.6.6 yamt 525: struct dirent *dp;
1.3.6.2 yamt 526: struct bfs_dirent *file;
527: int i, n, error;
528:
529: DPRINTF("%s: offset=%lld residue=%d\n", __FUNCTION__,
530: uio->uio_offset, uio->uio_resid);
531:
532: KDASSERT(vp->v_type == VDIR);
533: KDASSERT(uio->uio_offset >= 0);
534:
1.3.6.6 yamt 535: dp = malloc(sizeof(struct dirent), M_BFS, M_WAITOK | M_ZERO);
536:
1.3.6.2 yamt 537: i = uio->uio_offset / sizeof(struct dirent);
538: n = uio->uio_resid / sizeof(struct dirent);
539: if ((i + n) > bfs->n_dirent)
540: n = bfs->n_dirent - i;
541:
542: for (file = &bfs->dirent[i]; i < n; file++) {
543: if (file->inode == 0)
544: continue;
545: if (i == bfs->max_dirent) {
546: DPRINTF("%s: file system inconsistent.\n",
547: __FUNCTION__);
548: break;
549: }
550: i++;
1.3.6.6 yamt 551: memset(dp, 0, sizeof(struct dirent));
552: dp->d_fileno = file->inode;
553: dp->d_type = file->inode == BFS_ROOT_INODE ? DT_DIR : DT_REG;
554: dp->d_namlen = strlen(file->name);
555: strncpy(dp->d_name, file->name, BFS_FILENAME_MAXLEN);
556: dp->d_reclen = sizeof(struct dirent);
557: if ((error = uiomove(dp, dp->d_reclen, uio)) != 0) {
1.3.6.2 yamt 558: DPRINTF("%s: uiomove failed.\n", __FUNCTION__);
1.3.6.6 yamt 559: free(dp, M_BFS);
1.3.6.2 yamt 560: return error;
561: }
562: }
563: DPRINTF("%s: %d %d %d\n", __FUNCTION__, i, n, bfs->n_dirent);
1.3.6.6 yamt 564: *ap->a_eofflag = (i == bfs->n_dirent);
1.3.6.2 yamt 565:
1.3.6.6 yamt 566: free(dp, M_BFS);
1.3.6.2 yamt 567: return 0;
568: }
569:
570: int
571: sysvbfs_inactive(void *arg)
572: {
573: struct vop_inactive_args /* {
574: struct vnode *a_vp;
575: } */ *a = arg;
576: struct vnode *v = a->a_vp;
577:
578: DPRINTF("%s:\n", __FUNCTION__);
579: VOP_UNLOCK(v, 0);
1.3.6.7 ! yamt 580: vrecycle(v, NULL, curlwp);
1.3.6.2 yamt 581:
582: return 0;
583: }
584:
585: int
586: sysvbfs_reclaim(void *v)
587: {
588: extern struct pool sysvbfs_node_pool;
589: struct vop_reclaim_args /* {
590: struct vnode *a_vp;
591: } */ *ap = v;
592: struct vnode *vp = ap->a_vp;
593: struct sysvbfs_node *bnode = vp->v_data;
594:
595: DPRINTF("%s:\n", __FUNCTION__);
596: simple_lock(&mntvnode_slock);
597: LIST_REMOVE(bnode, link);
598: simple_unlock(&mntvnode_slock);
599: cache_purge(vp);
1.3.6.4 yamt 600: genfs_node_destroy(vp);
1.3.6.2 yamt 601: pool_put(&sysvbfs_node_pool, bnode);
602: vp->v_data = NULL;
603:
604: return 0;
605: }
606:
607: int
608: sysvbfs_bmap(void *arg)
609: {
610: struct vop_bmap_args /* {
611: struct vnode *a_vp;
612: daddr_t a_bn;
613: struct vnode **a_vpp;
614: daddr_t *a_bnp;
615: int *a_runp;
616: } */ *a = arg;
617: struct vnode *v = a->a_vp;
618: struct sysvbfs_node *bnode = v->v_data;
619: struct sysvbfs_mount *bmp = bnode->bmp;
620: struct bfs_inode *inode = bnode->inode;
621: daddr_t blk;
622:
623: DPRINTF("%s:\n", __FUNCTION__);
1.3.6.3 yamt 624: /* BFS algorithm is contiguous allocation */
1.3.6.2 yamt 625: blk = inode->start_sector + a->a_bn;
626:
627: if (blk * BFS_BSIZE > bmp->bfs->data_end)
628: return ENOSPC;
629:
630: *a->a_vpp = bmp->devvp;
631: *a->a_runp = 0;
632: DPRINTF("%s: %d + %lld\n", __FUNCTION__, inode->start_sector, a->a_bn);
633:
634: *a->a_bnp = blk;
635:
636:
637: return 0;
638: }
639:
640: int
641: sysvbfs_strategy(void *arg)
642: {
643: struct vop_strategy_args /* {
644: struct vnode *a_vp;
645: struct buf *a_bp;
646: } */ *a = arg;
647: struct buf *b = a->a_bp;
648: struct vnode *v = a->a_vp;
649: struct sysvbfs_node *bnode = v->v_data;
650: struct sysvbfs_mount *bmp = bnode->bmp;
651: int error;
652:
653: DPRINTF("%s:\n", __FUNCTION__);
654: KDASSERT(v->v_type == VREG);
655: if (b->b_blkno == b->b_lblkno) {
656: error = VOP_BMAP(v, b->b_lblkno, NULL, &b->b_blkno, NULL);
657: if (error) {
658: b->b_error = error;
659: biodone(b);
660: return error;
661: }
662: if ((long)b->b_blkno == -1)
663: clrbuf(b);
664: }
665: if ((long)b->b_blkno == -1) {
666: biodone(b);
667: return 0;
668: }
669:
670: return VOP_STRATEGY(bmp->devvp, b);
671: }
672:
673: int
674: sysvbfs_print(void *v)
675: {
676: struct vop_print_args /* {
677: struct vnode *a_vp;
678: } */ *ap = v;
679: struct sysvbfs_node *bnode = ap->a_vp->v_data;
680:
681: DPRINTF("%s:\n", __FUNCTION__);
682: bfs_dump(bnode->bmp->bfs);
683:
684: return 0;
685: }
686:
687: int
688: sysvbfs_advlock(void *v)
689: {
690: struct vop_advlock_args /* {
691: struct vnode *a_vp;
692: void *a_id;
693: int a_op;
694: struct flock *a_fl;
695: int a_flags;
696: } */ *ap = v;
697: struct sysvbfs_node *bnode = ap->a_vp->v_data;
698:
699: DPRINTF("%s: op=%d\n", __FUNCTION__, ap->a_op);
700:
701: return lf_advlock(ap, &bnode->lockf, bfs_file_size(bnode->inode));
702: }
703:
704: int
705: sysvbfs_pathconf(void *v)
706: {
707: struct vop_pathconf_args /* {
708: struct vnode *a_vp;
709: int a_name;
710: register_t *a_retval;
711: } */ *ap = v;
712: int err = 0;
713:
714: DPRINTF("%s:\n", __FUNCTION__);
715:
716: switch (ap->a_name) {
717: case _PC_LINK_MAX:
718: *ap->a_retval = 1;
719: break;;
720: case _PC_NAME_MAX:
721: *ap->a_retval = BFS_FILENAME_MAXLEN;
722: break;;
723: case _PC_PATH_MAX:
724: *ap->a_retval = BFS_FILENAME_MAXLEN;
725: break;;
726: case _PC_CHOWN_RESTRICTED:
727: *ap->a_retval = 1;
728: break;;
729: case _PC_NO_TRUNC:
730: *ap->a_retval = 0;
731: break;;
732: case _PC_SYNC_IO:
733: *ap->a_retval = 1;
734: break;;
735: case _PC_FILESIZEBITS:
736: *ap->a_retval = 32;
737: break;;
738: default:
739: err = EINVAL;
740: break;
741: }
742:
743: return err;
744: }
745:
746: int
747: sysvbfs_fsync(void *v)
748: {
749: struct vop_fsync_args /* {
750: struct vnode *a_vp;
751: kauth_cred_t a_cred;
752: int a_flags;
753: off_t offlo;
754: off_t offhi;
755: } */ *ap = v;
756: struct vnode *vp = ap->a_vp;
757: int error, wait;
758:
759: if (ap->a_flags & FSYNC_CACHE) {
760: return EOPNOTSUPP;
761: }
762:
763: wait = (ap->a_flags & FSYNC_WAIT) != 0;
764: vflushbuf(vp, wait);
765:
766: if ((ap->a_flags & FSYNC_DATAONLY) != 0)
767: error = 0;
768: else
769: error = sysvbfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
770:
771: return error;
772: }
773:
774: int
775: sysvbfs_update(struct vnode *vp, const struct timespec *acc,
776: const struct timespec *mod, int flags)
777: {
778: struct sysvbfs_node *bnode = vp->v_data;
779: struct bfs_fileattr attr;
780:
781: DPRINTF("%s:\n", __FUNCTION__);
782: memset(&attr, 0xff, sizeof attr); /* Set VNOVAL all */
783: if (bnode->update_atime) {
1.3.6.3 yamt 784: attr.atime = acc ? acc->tv_sec : time_second;
1.3.6.4 yamt 785: bnode->update_atime = false;
1.3.6.2 yamt 786: }
787: if (bnode->update_ctime) {
1.3.6.3 yamt 788: attr.ctime = time_second;
1.3.6.4 yamt 789: bnode->update_ctime = false;
1.3.6.2 yamt 790: }
791: if (bnode->update_mtime) {
1.3.6.3 yamt 792: attr.mtime = mod ? mod->tv_sec : time_second;
1.3.6.4 yamt 793: bnode->update_mtime = false;
1.3.6.2 yamt 794: }
795: bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
796:
797: return 0;
798: }
CVSweb <webmaster@jp.NetBSD.org>