Adjust some comments with reality.
[dragonfly.git] / sys / vfs / hpfs / hpfs_vnops.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $
b478fdce 27 * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.42 2007/08/08 00:12:51 swildner Exp $
984263bc
MD
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/proc.h>
34#include <sys/time.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <sys/vnode.h>
38#include <sys/mount.h>
39#include <sys/namei.h>
40#include <sys/malloc.h>
41#include <sys/buf.h>
42#include <sys/dirent.h>
43
0c50e491
JS
44#include <machine/limits.h>
45
984263bc
MD
46#include <vm/vm.h>
47#include <vm/vm_param.h>
08c23b99 48#if !defined(__DragonFly__)
984263bc
MD
49#include <vm/vm_prot.h>
50#endif
51#include <vm/vm_page.h>
52#include <vm/vm_object.h>
53#include <vm/vm_pager.h>
54#include <vm/vm_zone.h>
08c23b99 55#if defined(__DragonFly__)
984263bc
MD
56#include <vm/vnode_pager.h>
57#endif
58#include <vm/vm_extern.h>
7d1b9a3b 59#include <sys/buf2.h>
984263bc 60
08c23b99 61#if !defined(__DragonFly__)
984263bc
MD
62#include <miscfs/specfs/specdev.h>
63#include <miscfs/genfs/genfs.h>
64#endif
65
66#include <sys/unistd.h> /* for pathconf(2) constants */
67
1f2de5d4
MD
68#include "hpfs.h"
69#include "hpfsmount.h"
70#include "hpfs_subr.h"
71#include "hpfs_ioctl.h"
984263bc 72
957d9419
SS
73static int hpfs_de_uiomove (int *, struct hpfsmount *,
74 struct hpfsdirent *, struct uio *);
a6ee311a
RG
75static int hpfs_ioctl (struct vop_ioctl_args *ap);
76static int hpfs_read (struct vop_read_args *);
77static int hpfs_write (struct vop_write_args *ap);
78static int hpfs_getattr (struct vop_getattr_args *ap);
79static int hpfs_setattr (struct vop_setattr_args *ap);
80static int hpfs_inactive (struct vop_inactive_args *ap);
81static int hpfs_print (struct vop_print_args *ap);
82static int hpfs_reclaim (struct vop_reclaim_args *ap);
83static int hpfs_strategy (struct vop_strategy_args *ap);
84static int hpfs_access (struct vop_access_args *ap);
a6ee311a 85static int hpfs_readdir (struct vop_readdir_args *ap);
e62afb5f
MD
86static int hpfs_lookup (struct vop_old_lookup_args *ap);
87static int hpfs_create (struct vop_old_create_args *);
88static int hpfs_remove (struct vop_old_remove_args *);
a6ee311a 89static int hpfs_bmap (struct vop_bmap_args *ap);
08c23b99 90#if defined(__DragonFly__)
a6ee311a
RG
91static int hpfs_getpages (struct vop_getpages_args *ap);
92static int hpfs_putpages (struct vop_putpages_args *);
93static int hpfs_fsync (struct vop_fsync_args *ap);
984263bc 94#endif
a6ee311a 95static int hpfs_pathconf (struct vop_pathconf_args *ap);
984263bc 96
08c23b99 97#if defined(__DragonFly__)
984263bc 98int
dd3af26c 99hpfs_getpages(struct vop_getpages_args *ap)
984263bc
MD
100{
101 return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
102 ap->a_reqpage);
103}
104
105int
dd3af26c 106hpfs_putpages(struct vop_putpages_args *ap)
984263bc
MD
107{
108 return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
109 ap->a_sync, ap->a_rtvals);
110}
111
dd3af26c 112/*
b478fdce 113 * hpfs_fsync(struct vnode *a_vp, int a_waitfor)
dd3af26c 114 */
984263bc 115static int
dd3af26c 116hpfs_fsync(struct vop_fsync_args *ap)
984263bc
MD
117{
118 struct vnode *vp = ap->a_vp;
984263bc
MD
119
120 /*
121 * Flush all dirty buffers associated with a vnode.
122 */
6bae6177 123#ifdef DIAGNOSTIC
984263bc 124loop:
6bae6177 125#endif
4e0ecc94 126 vfsync(vp, ap->a_waitfor, 0, NULL, NULL);
984263bc 127#ifdef DIAGNOSTIC
6bae6177 128 if (ap->a_waitfor == MNT_WAIT && !RB_EMPTY(&vp->v_rbdirty_tree)) {
984263bc
MD
129 vprint("hpfs_fsync: dirty", vp);
130 goto loop;
131 }
132#endif
984263bc
MD
133
134 /*
135 * Write out the on-disc version of the vnode.
136 */
137 return hpfs_update(VTOHP(vp));
138}
139
140#endif
141
dd3af26c
CP
142/*
143 * hpfs_ioctl(struct vnode *a_vp, u_long a_command, caddr_t a_data,
b478fdce 144 * int a_fflag, struct ucred *a_cred)
dd3af26c 145 */
984263bc 146static int
dd3af26c 147hpfs_ioctl(struct vop_ioctl_args *ap)
984263bc 148{
f7aae92f
RG
149 struct vnode *vp = ap->a_vp;
150 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
151 int error;
152
086c1d7e 153 kprintf("hpfs_ioctl(0x%x, 0x%lx, 0x%p, 0x%x): ",
984263bc
MD
154 hp->h_no, ap->a_command, ap->a_data, ap->a_fflag);
155
156 switch (ap->a_command) {
157 case HPFSIOCGEANUM: {
158 u_long eanum;
159 u_long passed;
160 struct ea *eap;
161
162 eanum = 0;
163
164 if (hp->h_fn.fn_ealen > 0) {
165 eap = (struct ea *)&(hp->h_fn.fn_int);
166 passed = 0;
167
168 while (passed < hp->h_fn.fn_ealen) {
169
086c1d7e 170 kprintf("EAname: %s\n", EA_NAME(eap));
984263bc
MD
171
172 eanum++;
173 passed += sizeof(struct ea) +
174 eap->ea_namelen + 1 + eap->ea_vallen;
175 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
176 passed);
177 }
178 error = 0;
179 } else {
180 error = ENOENT;
181 }
182
086c1d7e 183 kprintf("%lu eas\n", eanum);
984263bc
MD
184
185 *(u_long *)ap->a_data = eanum;
186
187 break;
188 }
189 case HPFSIOCGEASZ: {
190 u_long eanum;
191 u_long passed;
192 struct ea *eap;
193
086c1d7e 194 kprintf("EA%ld\n", *(u_long *)ap->a_data);
984263bc
MD
195
196 eanum = 0;
197 if (hp->h_fn.fn_ealen > 0) {
198 eap = (struct ea *)&(hp->h_fn.fn_int);
199 passed = 0;
200
201 error = ENOENT;
202 while (passed < hp->h_fn.fn_ealen) {
086c1d7e 203 kprintf("EAname: %s\n", EA_NAME(eap));
984263bc
MD
204
205 if (eanum == *(u_long *)ap->a_data) {
206 *(u_long *)ap->a_data =
207 eap->ea_namelen + 1 +
208 eap->ea_vallen;
209
210 error = 0;
211 break;
212 }
213
214 eanum++;
215 passed += sizeof(struct ea) +
216 eap->ea_namelen + 1 + eap->ea_vallen;
217 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
218 passed);
219 }
220 } else {
221 error = ENOENT;
222 }
223
224 break;
225 }
226 case HPFSIOCRDEA: {
227 u_long eanum;
228 u_long passed;
229 struct hpfs_rdea *rdeap;
230 struct ea *eap;
231
232 rdeap = (struct hpfs_rdea *)ap->a_data;
086c1d7e 233 kprintf("EA%ld\n", rdeap->ea_no);
984263bc
MD
234
235 eanum = 0;
236 if (hp->h_fn.fn_ealen > 0) {
237 eap = (struct ea *)&(hp->h_fn.fn_int);
238 passed = 0;
239
240 error = ENOENT;
241 while (passed < hp->h_fn.fn_ealen) {
086c1d7e 242 kprintf("EAname: %s\n", EA_NAME(eap));
984263bc
MD
243
244 if (eanum == rdeap->ea_no) {
245 rdeap->ea_sz = eap->ea_namelen + 1 +
246 eap->ea_vallen;
247 copyout(EA_NAME(eap),rdeap->ea_data,
248 rdeap->ea_sz);
249 error = 0;
250 break;
251 }
252
253 eanum++;
254 passed += sizeof(struct ea) +
255 eap->ea_namelen + 1 + eap->ea_vallen;
256 eap = (struct ea *)((caddr_t)hp->h_fn.fn_int +
257 passed);
258 }
259 } else {
260 error = ENOENT;
261 }
262
263 break;
264 }
265 default:
266 error = EOPNOTSUPP;
267 break;
268 }
269 return (error);
270}
271
272/*
273 * Map file offset to disk offset.
dd3af26c 274 *
54078292
MD
275 * hpfs_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp,
276 * off_t *a_doffsetp, int *a_runp, int *a_runb)
984263bc
MD
277 */
278int
dd3af26c 279hpfs_bmap(struct vop_bmap_args *ap)
984263bc 280{
f7aae92f 281 struct hpfsnode *hp = VTOHP(ap->a_vp);
984263bc 282 int error;
54078292
MD
283 daddr_t lbn;
284 daddr_t dbn;
984263bc
MD
285
286 if (ap->a_vpp != NULL)
287 *ap->a_vpp = hp->h_devvp;
984263bc
MD
288 if (ap->a_runb != NULL)
289 *ap->a_runb = 0;
54078292 290 if (ap->a_doffsetp == NULL)
984263bc
MD
291 return (0);
292
293 dprintf(("hpfs_bmap(0x%x, 0x%x): ",hp->h_no, ap->a_bn));
294
54078292
MD
295 lbn = ap->a_loffset >> DEV_BSHIFT;
296 KKASSERT(((int)ap->a_loffset & DEV_BMASK) == 0);
984263bc 297
54078292
MD
298 error = hpfs_hpbmap (hp, lbn, &dbn, ap->a_runp);
299 if (error || dbn == (daddr_t)-1) {
300 *ap->a_doffsetp = NOOFFSET;
301 } else {
302 *ap->a_doffsetp = (off_t)dbn << DEV_BSHIFT;
303 }
984263bc
MD
304 return (error);
305}
306
dd3af26c
CP
307/*
308 * hpfs_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
309 * struct ucred *a_cred)
310 */
984263bc 311static int
dd3af26c 312hpfs_read(struct vop_read_args *ap)
984263bc 313{
f7aae92f
RG
314 struct vnode *vp = ap->a_vp;
315 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
316 struct uio *uio = ap->a_uio;
317 struct buf *bp;
318 u_int xfersz, toread;
319 u_int off;
320 daddr_t lbn, bn;
321 int resid;
322 int runl;
323 int error = 0;
324
325 resid = min (uio->uio_resid, hp->h_fn.fn_size - uio->uio_offset);
326
327 dprintf(("hpfs_read(0x%x, off: %d resid: %d, segflg: %d): [resid: 0x%x]\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg, resid));
328
329 while (resid) {
330 lbn = uio->uio_offset >> DEV_BSHIFT;
331 off = uio->uio_offset & (DEV_BSIZE - 1);
332 dprintf(("hpfs_read: resid: 0x%x lbn: 0x%x off: 0x%x\n",
333 uio->uio_resid, lbn, off));
334 error = hpfs_hpbmap(hp, lbn, &bn, &runl);
335 if (error)
336 return (error);
337
338 toread = min(off + resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
339 xfersz = (toread + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
340 dprintf(("hpfs_read: bn: 0x%x (0x%x) toread: 0x%x (0x%x)\n",
341 bn, runl, toread, xfersz));
342
343 if (toread == 0)
344 break;
345
54078292 346 error = bread(hp->h_devvp, dbtodoff(bn), xfersz, &bp);
984263bc
MD
347 if (error) {
348 brelse(bp);
349 break;
350 }
351
352 error = uiomove(bp->b_data + off, toread - off, uio);
353 if(error) {
354 brelse(bp);
355 break;
356 }
357 brelse(bp);
358 resid -= toread;
359 }
360 dprintf(("hpfs_read: successful\n"));
361 return (error);
362}
363
dd3af26c
CP
364/*
365 * hpfs_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
366 * struct ucred *a_cred)
367 */
984263bc 368static int
dd3af26c 369hpfs_write(struct vop_write_args *ap)
984263bc 370{
f7aae92f
RG
371 struct vnode *vp = ap->a_vp;
372 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
373 struct uio *uio = ap->a_uio;
374 struct buf *bp;
375 u_int xfersz, towrite;
376 u_int off;
377 daddr_t lbn, bn;
378 int runl;
379 int error = 0;
380
381 dprintf(("hpfs_write(0x%x, off: %d resid: %d, segflg: %d):\n",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg));
382
383 if (ap->a_ioflag & IO_APPEND) {
384 dprintf(("hpfs_write: APPEND mode\n"));
385 uio->uio_offset = hp->h_fn.fn_size;
386 }
387 if (uio->uio_offset + uio->uio_resid > hp->h_fn.fn_size) {
388 error = hpfs_extend (hp, uio->uio_offset + uio->uio_resid);
389 if (error) {
086c1d7e 390 kprintf("hpfs_write: hpfs_extend FAILED %d\n", error);
984263bc
MD
391 return (error);
392 }
393 }
394
395 while (uio->uio_resid) {
396 lbn = uio->uio_offset >> DEV_BSHIFT;
397 off = uio->uio_offset & (DEV_BSIZE - 1);
398 dprintf(("hpfs_write: resid: 0x%x lbn: 0x%x off: 0x%x\n",
399 uio->uio_resid, lbn, off));
400 error = hpfs_hpbmap(hp, lbn, &bn, &runl);
401 if (error)
402 return (error);
403
404 towrite = min(off + uio->uio_resid, min(DFLTPHYS, (runl+1)*DEV_BSIZE));
405 xfersz = (towrite + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
406 dprintf(("hpfs_write: bn: 0x%x (0x%x) towrite: 0x%x (0x%x)\n",
407 bn, runl, towrite, xfersz));
408
409 if ((off == 0) && (towrite == xfersz)) {
54078292 410 bp = getblk(hp->h_devvp, dbtodoff(bn), xfersz, 0, 0);
984263bc
MD
411 clrbuf(bp);
412 } else {
54078292 413 error = bread(hp->h_devvp, dbtodoff(bn), xfersz, &bp);
984263bc
MD
414 if (error) {
415 brelse(bp);
416 return (error);
417 }
418 }
419
420 error = uiomove(bp->b_data + off, towrite - off, uio);
421 if(error) {
422 brelse(bp);
423 return (error);
424 }
425
426 if (ap->a_ioflag & IO_SYNC)
427 bwrite(bp);
428 else
429 bawrite(bp);
430 }
431
432 dprintf(("hpfs_write: successful\n"));
433 return (0);
434}
435
436/*
437 * XXXXX do we need hpfsnode locking inside?
dd3af26c 438 *
b478fdce 439 * hpfs_getattr(struct vnode *a_vp, struct vattr *a_vap)
984263bc
MD
440 */
441static int
dd3af26c 442hpfs_getattr(struct vop_getattr_args *ap)
984263bc 443{
f7aae92f
RG
444 struct vnode *vp = ap->a_vp;
445 struct hpfsnode *hp = VTOHP(vp);
446 struct vattr *vap = ap->a_vap;
984263bc
MD
447 int error;
448
449 dprintf(("hpfs_getattr(0x%x):\n", hp->h_no));
450
08c23b99 451#if defined(__DragonFly__)
984263bc
MD
452 vap->va_fsid = dev2udev(hp->h_dev);
453#else /* defined(__NetBSD__) */
454 vap->va_fsid = ip->i_dev;
455#endif
456 vap->va_fileid = hp->h_no;
457 vap->va_mode = hp->h_mode;
458 vap->va_nlink = 1;
459 vap->va_uid = hp->h_uid;
460 vap->va_gid = hp->h_gid;
0e9b9130
MD
461 vap->va_rmajor = VNOVAL;
462 vap->va_rminor = VNOVAL;
984263bc
MD
463 vap->va_size = hp->h_fn.fn_size;
464 vap->va_bytes = ((hp->h_fn.fn_size + DEV_BSIZE-1) & ~(DEV_BSIZE-1)) +
465 DEV_BSIZE;
466
467 if (!(hp->h_flag & H_PARVALID)) {
468 error = hpfs_validateparent(hp);
469 if (error)
470 return (error);
471 }
472 vap->va_atime = hpfstimetounix(hp->h_atime);
473 vap->va_mtime = hpfstimetounix(hp->h_mtime);
474 vap->va_ctime = hpfstimetounix(hp->h_ctime);
475
476 vap->va_flags = 0;
477 vap->va_gen = 0;
478 vap->va_blocksize = DEV_BSIZE;
479 vap->va_type = vp->v_type;
480 vap->va_filerev = 0;
481
482 return (0);
483}
484
485/*
486 * XXXXX do we need hpfsnode locking inside?
dd3af26c 487 *
b478fdce 488 * hpfs_setattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred)
984263bc
MD
489 */
490static int
dd3af26c 491hpfs_setattr(struct vop_setattr_args *ap)
984263bc
MD
492{
493 struct vnode *vp = ap->a_vp;
494 struct hpfsnode *hp = VTOHP(vp);
495 struct vattr *vap = ap->a_vap;
496 struct ucred *cred = ap->a_cred;
984263bc
MD
497 int error;
498
499 dprintf(("hpfs_setattr(0x%x):\n", hp->h_no));
500
501 /*
502 * Check for unsettable attributes.
503 */
504 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
505 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
0e9b9130 506 (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
984263bc
MD
507 (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
508 dprintf(("hpfs_setattr: changing nonsettable attr\n"));
509 return (EINVAL);
510 }
511
512 /* Can't change flags XXX Could be implemented */
513 if (vap->va_flags != VNOVAL) {
086c1d7e 514 kprintf("hpfs_setattr: FLAGS CANNOT BE SET\n");
984263bc
MD
515 return (EINVAL);
516 }
517
518 /* Can't change uid/gid XXX Could be implemented */
519 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
086c1d7e 520 kprintf("hpfs_setattr: UID/GID CANNOT BE SET\n");
984263bc
MD
521 return (EINVAL);
522 }
523
524 /* Can't change mode XXX Could be implemented */
525 if (vap->va_mode != (mode_t)VNOVAL) {
086c1d7e 526 kprintf("hpfs_setattr: MODE CANNOT BE SET\n");
984263bc
MD
527 return (EINVAL);
528 }
529
530 /* Update times */
531 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
532 if (vp->v_mount->mnt_flag & MNT_RDONLY)
533 return (EROFS);
534 if (cred->cr_uid != hp->h_uid &&
dadab5e9 535 (error = suser_cred(cred, PRISON_ROOT)) &&
984263bc 536 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
87de5057 537 (error = VOP_ACCESS(vp, VWRITE, cred))))
984263bc
MD
538 return (error);
539 if (vap->va_atime.tv_sec != VNOVAL)
540 hp->h_atime = vap->va_atime.tv_sec;
541 if (vap->va_mtime.tv_sec != VNOVAL)
542 hp->h_mtime = vap->va_mtime.tv_sec;
543
544 hp->h_flag |= H_PARCHANGE;
545 }
546
547 if (vap->va_size != VNOVAL) {
548 switch (vp->v_type) {
549 case VDIR:
550 return (EISDIR);
551 case VREG:
552 if (vp->v_mount->mnt_flag & MNT_RDONLY)
553 return (EROFS);
554 break;
555 default:
086c1d7e 556 kprintf("hpfs_setattr: WRONG v_type\n");
984263bc
MD
557 return (EINVAL);
558 }
559
560 if (vap->va_size < hp->h_fn.fn_size) {
08c23b99 561#if defined(__DragonFly__)
87de5057 562 error = vtruncbuf(vp, vap->va_size, DEV_BSIZE);
984263bc
MD
563 if (error)
564 return (error);
565#else /* defined(__NetBSD__) */
566#error Need alternation for vtruncbuf()
567#endif
568 error = hpfs_truncate(hp, vap->va_size);
569 if (error)
570 return (error);
571
572 } else if (vap->va_size > hp->h_fn.fn_size) {
08c23b99 573#if defined(__DragonFly__)
984263bc
MD
574 vnode_pager_setsize(vp, vap->va_size);
575#endif
576 error = hpfs_extend(hp, vap->va_size);
577 if (error)
578 return (error);
579 }
580 }
581
582 return (0);
583}
584
585/*
586 * Last reference to an node. If necessary, write or delete it.
dd3af26c
CP
587 *
588 * hpfs_inactive(struct vnode *a_vp)
984263bc
MD
589 */
590int
dd3af26c 591hpfs_inactive(struct vop_inactive_args *ap)
984263bc 592{
f7aae92f
RG
593 struct vnode *vp = ap->a_vp;
594 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
595 int error;
596
597 dprintf(("hpfs_inactive(0x%x): \n", hp->h_no));
598
599 if (hp->h_flag & H_CHANGE) {
600 dprintf(("hpfs_inactive: node changed, update\n"));
601 error = hpfs_update (hp);
602 if (error)
603 return (error);
604 }
605
606 if (hp->h_flag & H_PARCHANGE) {
607 dprintf(("hpfs_inactive: parent node changed, update\n"));
608 error = hpfs_updateparent (hp);
609 if (error)
610 return (error);
611 }
612
3c37c940 613 if (prtactive && vp->v_sysref.refcnt > 1)
984263bc
MD
614 vprint("hpfs_inactive: pushing active", vp);
615
616 if (hp->h_flag & H_INVAL) {
08c23b99 617#if defined(__DragonFly__)
87de5057 618 vrecycle(vp);
984263bc
MD
619#else /* defined(__NetBSD__) */
620 vgone(vp);
621#endif
622 return (0);
623 }
984263bc
MD
624 return (0);
625}
626
627/*
628 * Reclaim an inode so that it can be used for other purposes.
dd3af26c
CP
629 *
630 * hpfs_reclaim(struct vnode *a_vp)
984263bc
MD
631 */
632int
dd3af26c 633hpfs_reclaim(struct vop_reclaim_args *ap)
984263bc 634{
f7aae92f
RG
635 struct vnode *vp = ap->a_vp;
636 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
637
638 dprintf(("hpfs_reclaim(0x%x0): \n", hp->h_no));
639
640 hpfs_hphashrem(hp);
641
642 /* Purge old data structures associated with the inode. */
984263bc
MD
643 if (hp->h_devvp) {
644 vrele(hp->h_devvp);
645 hp->h_devvp = NULL;
646 }
647
648 vp->v_data = NULL;
649
650 FREE(hp, M_HPFSNO);
651
652 return (0);
653}
654
dd3af26c
CP
655/*
656 * hpfs_print(struct vnode *a_vp)
657 */
984263bc 658static int
dd3af26c 659hpfs_print(struct vop_print_args *ap)
984263bc 660{
f7aae92f
RG
661 struct vnode *vp = ap->a_vp;
662 struct hpfsnode *hp = VTOHP(vp);
984263bc 663
086c1d7e 664 kprintf("tag VT_HPFS, ino 0x%x",hp->h_no);
3446c007 665 lockmgr_printinfo(&vp->v_lock);
086c1d7e 666 kprintf("\n");
984263bc
MD
667 return (0);
668}
669
670/*
671 * Calculate the logical to physical mapping if not done already,
672 * then call the device strategy routine.
673 *
674 * In order to be able to swap to a file, the VOP_BMAP operation may not
675 * deadlock on memory. See hpfs_bmap() for details. XXXXXXX (not impl)
dd3af26c 676 *
81b5c339 677 * hpfs_strategy(struct vnode *a_vp, struct bio *a_bio)
984263bc
MD
678 */
679int
dd3af26c 680hpfs_strategy(struct vop_strategy_args *ap)
984263bc 681{
81b5c339
MD
682 struct bio *bio = ap->a_bio;
683 struct bio *nbio;
684 struct buf *bp = bio->bio_buf;
f7aae92f 685 struct vnode *vp = ap->a_vp;
81b5c339 686 struct hpfsnode *hp;
984263bc
MD
687 int error;
688
689 dprintf(("hpfs_strategy(): \n"));
690
691 if (vp->v_type == VBLK || vp->v_type == VCHR)
692 panic("hpfs_strategy: spec");
81b5c339
MD
693
694 nbio = push_bio(bio);
54078292
MD
695 if (nbio->bio_offset == NOOFFSET) {
696 error = VOP_BMAP(vp, bio->bio_offset, NULL, &nbio->bio_offset,
81b5c339 697 NULL, NULL);
984263bc 698 if (error) {
086c1d7e 699 kprintf("hpfs_strategy: VOP_BMAP FAILED %d\n", error);
984263bc
MD
700 bp->b_error = error;
701 bp->b_flags |= B_ERROR;
81b5c339
MD
702 /* I/O was never started on nbio, must biodone(bio) */
703 biodone(bio);
984263bc
MD
704 return (error);
705 }
54078292 706 if (nbio->bio_offset == NOOFFSET)
984263bc
MD
707 vfs_bio_clrbuf(bp);
708 }
54078292 709 if (nbio->bio_offset == NOOFFSET) {
81b5c339
MD
710 /* I/O was never started on nbio, must biodone(bio) */
711 biodone(bio);
984263bc
MD
712 return (0);
713 }
81b5c339
MD
714 hp = VTOHP(ap->a_vp);
715 vn_strategy(hp->h_devvp, nbio);
984263bc
MD
716 return (0);
717}
718
719/*
720 * XXXXX do we need hpfsnode locking inside?
dd3af26c 721 *
b478fdce 722 * hpfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
984263bc
MD
723 */
724int
dd3af26c 725hpfs_access(struct vop_access_args *ap)
984263bc
MD
726{
727 struct vnode *vp = ap->a_vp;
728 struct hpfsnode *hp = VTOHP(vp);
729 struct ucred *cred = ap->a_cred;
730 mode_t mask, mode = ap->a_mode;
f7aae92f 731 gid_t *gp;
984263bc
MD
732 int i;
733
734 dprintf(("hpfs_access(0x%x):\n", hp->h_no));
735
736 /*
737 * Disallow write attempts on read-only file systems;
738 * unless the file is a socket, fifo, or a block or
739 * character device resident on the file system.
740 */
741 if (mode & VWRITE) {
742 switch ((int)vp->v_type) {
743 case VDIR:
744 case VLNK:
745 case VREG:
746 if (vp->v_mount->mnt_flag & MNT_RDONLY)
747 return (EROFS);
748 break;
749 }
750 }
751
752 /* Otherwise, user id 0 always gets access. */
753 if (cred->cr_uid == 0)
754 return (0);
755
756 mask = 0;
757
758 /* Otherwise, check the owner. */
759 if (cred->cr_uid == hp->h_uid) {
760 if (mode & VEXEC)
761 mask |= S_IXUSR;
762 if (mode & VREAD)
763 mask |= S_IRUSR;
764 if (mode & VWRITE)
765 mask |= S_IWUSR;
766 return ((hp->h_mode & mask) == mask ? 0 : EACCES);
767 }
768
769 /* Otherwise, check the groups. */
770 for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
771 if (hp->h_gid == *gp) {
772 if (mode & VEXEC)
773 mask |= S_IXGRP;
774 if (mode & VREAD)
775 mask |= S_IRGRP;
776 if (mode & VWRITE)
777 mask |= S_IWGRP;
778 return ((hp->h_mode & mask) == mask ? 0 : EACCES);
779 }
780
781 /* Otherwise, check everyone else. */
782 if (mode & VEXEC)
783 mask |= S_IXOTH;
784 if (mode & VREAD)
785 mask |= S_IROTH;
786 if (mode & VWRITE)
787 mask |= S_IWOTH;
788 return ((hp->h_mode & mask) == mask ? 0 : EACCES);
789}
790
984263bc 791static int
957d9419 792hpfs_de_uiomove(int *error, struct hpfsmount *hpmp, struct hpfsdirent *dep,
dd3af26c 793 struct uio *uio)
984263bc 794{
0c50e491 795 char convname[HPFS_MAXFILENAME + 1];
957d9419 796 int i, success;
984263bc
MD
797
798 dprintf(("[no: 0x%x, size: %d, name: %2d:%.*s, flag: 0x%x] ",
799 dep->de_fnode, dep->de_size, dep->de_namelen,
800 dep->de_namelen, dep->de_name, dep->de_flag));
801
802 /*strncpy(cde.d_name, dep->de_name, dep->de_namelen);*/
803 for (i=0; i<dep->de_namelen; i++)
957d9419
SS
804 convname[i] = hpfs_d2u(hpmp, dep->de_name[i]);
805 convname[dep->de_namelen] = '\0';
984263bc 806
957d9419
SS
807 success = vop_write_dirent(error, uio, dep->de_fnode,
808 (dep->de_flag & DE_DIR) ? DT_DIR : DT_REG,
809 dep->de_namelen, convname);
984263bc 810
984263bc 811 dprintf(("[0x%x] ", uio->uio_resid));
957d9419 812 return (success);
984263bc
MD
813}
814
815
dd3af26c
CP
816/*
817 * hpfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred,
818 * int *a_ncookies, u_int **cookies)
819 */
984263bc 820int
dd3af26c 821hpfs_readdir(struct vop_readdir_args *ap)
984263bc 822{
f7aae92f
RG
823 struct vnode *vp = ap->a_vp;
824 struct hpfsnode *hp = VTOHP(vp);
984263bc
MD
825 struct hpfsmount *hpmp = hp->h_hpmp;
826 struct uio *uio = ap->a_uio;
827 int ncookies = 0, i, num, cnum;
828 int error = 0;
984263bc
MD
829 struct buf *bp;
830 struct dirblk *dp;
831 struct hpfsdirent *dep;
832 lsn_t olsn;
833 lsn_t lsn;
834 int level;
835
836 dprintf(("hpfs_readdir(0x%x, 0x%x, 0x%x): ",hp->h_no,(u_int32_t)uio->uio_offset,uio->uio_resid));
837
957d9419 838 /*
ad079f69
SS
839 * As we need to fake up . and .., and the remaining directory structure
840 * can't be expressed in one off_t as well, we just increment uio_offset
841 * by 1 for each entry.
842 *
957d9419
SS
843 * num is the entry we need to start reporting
844 * cnum is the current entry
845 */
0c50e491
JS
846 if (uio->uio_offset < 0 || uio->uio_offset > INT_MAX)
847 return(EINVAL);
885ecb13
MD
848 if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
849 return (error);
850
957d9419
SS
851 num = uio->uio_offset;
852 cnum = 0;
853
957d9419 854 if( num <= cnum ) {
984263bc 855 dprintf((". faked, "));
957d9419 856 if (vop_write_dirent(&error, uio, hp->h_no, DT_DIR, 1, "."))
885ecb13
MD
857 goto done;
858 if (error)
859 goto done;
984263bc
MD
860 ncookies ++;
861 }
957d9419 862 cnum++;
984263bc 863
957d9419 864 if( num <= cnum ) {
984263bc 865 dprintf((".. faked, "));
957d9419
SS
866 if (vop_write_dirent(&error, uio, hp->h_fn.fn_parent, DT_DIR, 2, ".."))
867 goto readdone;
885ecb13
MD
868 if (error)
869 goto done;
984263bc
MD
870 ncookies ++;
871 }
957d9419 872 cnum++;
984263bc
MD
873
874 lsn = ((alleaf_t *)hp->h_fn.fn_abd)->al_lsn;
875
876 olsn = 0;
877 level = 1;
878
879dive:
880 dprintf(("[dive 0x%x] ", lsn));
54078292 881 error = bread(hp->h_devvp, dbtodoff(lsn), D_BSIZE, &bp);
984263bc
MD
882 if (error) {
883 brelse(bp);
885ecb13 884 goto done;
984263bc
MD
885 }
886
887 dp = (struct dirblk *) bp->b_data;
888 if (dp->d_magic != D_MAGIC) {
086c1d7e 889 kprintf("hpfs_readdir: MAGIC DOESN'T MATCH\n");
984263bc 890 brelse(bp);
885ecb13
MD
891 error = EINVAL;
892 goto done;
984263bc
MD
893 }
894
895 dep = D_DIRENT(dp);
896
897 if (olsn) {
898 dprintf(("[restore 0x%x] ", olsn));
899
900 while(!(dep->de_flag & DE_END) ) {
901 if((dep->de_flag & DE_DOWN) &&
902 (olsn == DE_DOWNLSN(dep)))
903 break;
904 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
905 }
906
907 if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
908 if (dep->de_flag & DE_END)
909 goto blockdone;
910
911 if (!(dep->de_flag & DE_SPECIAL)) {
912 if (num <= cnum) {
957d9419 913 if (hpfs_de_uiomove(&error, hpmp, dep, uio)) {
984263bc
MD
914 brelse(bp);
915 dprintf(("[resid] "));
916 goto readdone;
917 }
984263bc
MD
918 if (error) {
919 brelse (bp);
885ecb13 920 goto done;
984263bc
MD
921 }
922 ncookies++;
984263bc
MD
923 }
924 cnum++;
925 }
926
927 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
928 } else {
086c1d7e 929 kprintf("hpfs_readdir: ERROR! oLSN not found\n");
984263bc 930 brelse(bp);
885ecb13
MD
931 error = EINVAL;
932 goto done;
984263bc
MD
933 }
934 }
935
936 olsn = 0;
937
938 while(!(dep->de_flag & DE_END)) {
939 if(dep->de_flag & DE_DOWN) {
940 lsn = DE_DOWNLSN(dep);
941 brelse(bp);
942 level++;
943 goto dive;
944 }
945
946 if (!(dep->de_flag & DE_SPECIAL)) {
947 if (num <= cnum) {
957d9419 948 if (hpfs_de_uiomove(&error, hpmp, dep, uio)) {
984263bc
MD
949 brelse(bp);
950 dprintf(("[resid] "));
951 goto readdone;
952 }
984263bc
MD
953 if (error) {
954 brelse (bp);
885ecb13 955 goto done;
984263bc
MD
956 }
957 ncookies++;
984263bc
MD
958 }
959 cnum++;
960 }
961
962 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
963 }
964
965 if(dep->de_flag & DE_DOWN) {
966 dprintf(("[enddive] "));
967 lsn = DE_DOWNLSN(dep);
968 brelse(bp);
969 level++;
970 goto dive;
971 }
972
973blockdone:
974 dprintf(("[EOB] "));
975 olsn = lsn;
976 lsn = dp->d_parent;
977 brelse(bp);
978 level--;
979
980 dprintf(("[level %d] ", level));
981
982 if (level > 0)
983 goto dive; /* undive really */
984
985 if (ap->a_eofflag) {
986 dprintf(("[EOF] "));
987 *ap->a_eofflag = 1;
988 }
989
990readdone:
957d9419 991 uio->uio_offset = cnum;
984263bc
MD
992 dprintf(("[readdone]\n"));
993 if (!error && ap->a_ncookies != NULL) {
08c23b99 994#if defined(__DragonFly__)
984263bc
MD
995 u_long *cookies;
996 u_long *cookiep;
997#else /* defined(__NetBSD__) */
998 off_t *cookies;
999 off_t *cookiep;
1000#endif
1001
1002 dprintf(("%d cookies, ",ncookies));
1003 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1004 panic("hpfs_readdir: unexpected uio from NFS server");
08c23b99 1005#if defined(__DragonFly__)
984263bc
MD
1006 MALLOC(cookies, u_long *, ncookies * sizeof(u_long),
1007 M_TEMP, M_WAITOK);
1008#else /* defined(__NetBSD__) */
1009 MALLOC(cookies, off_t *, ncookies * sizeof(off_t),
1010 M_TEMP, M_WAITOK);
1011#endif
957d9419 1012 for (cookiep = cookies, i=0; i < ncookies; i++)
0c50e491 1013 *cookiep++ = (u_int)++num;
957d9419 1014
984263bc
MD
1015 *ap->a_ncookies = ncookies;
1016 *ap->a_cookies = cookies;
1017 }
1018
885ecb13
MD
1019done:
1020 vn_unlock(ap->a_vp);
1021 return (error);
984263bc
MD
1022}
1023
dd3af26c
CP
1024/*
1025 * hpfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
1026 * struct componentname *a_cnp)
1027 */
984263bc 1028int
e62afb5f 1029hpfs_lookup(struct vop_old_lookup_args *ap)
984263bc 1030{
f7aae92f
RG
1031 struct vnode *dvp = ap->a_dvp;
1032 struct hpfsnode *dhp = VTOHP(dvp);
984263bc
MD
1033 struct hpfsmount *hpmp = dhp->h_hpmp;
1034 struct componentname *cnp = ap->a_cnp;
1035 struct ucred *cred = cnp->cn_cred;
1036 int error;
1037 int nameiop = cnp->cn_nameiop;
1038 int flags = cnp->cn_flags;
2b69e610 1039 int lockparent = flags & CNP_LOCKPARENT;
984263bc 1040#if HPFS_DEBUG
2b69e610 1041 int wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT);
984263bc
MD
1042#endif
1043 dprintf(("hpfs_lookup(0x%x, %s, %ld, %d, %d): \n",
1044 dhp->h_no, cnp->cn_nameptr, cnp->cn_namelen,
1045 lockparent, wantparent));
1046
2b69e610 1047 if (nameiop != NAMEI_CREATE && nameiop != NAMEI_DELETE && nameiop != NAMEI_LOOKUP) {
086c1d7e 1048 kprintf("hpfs_lookup: LOOKUP, DELETE and CREATE are only supported\n");
984263bc
MD
1049 return (EOPNOTSUPP);
1050 }
1051
87de5057 1052 error = VOP_ACCESS(dvp, VEXEC, cred);
984263bc
MD
1053 if(error)
1054 return (error);
1055
1056 if( (cnp->cn_namelen == 1) &&
1057 !strncmp(cnp->cn_nameptr,".",1) ) {
1058 dprintf(("hpfs_lookup(0x%x,...): . faked\n",dhp->h_no));
1059
597aea93 1060 vref(dvp);
984263bc
MD
1061 *ap->a_vpp = dvp;
1062
1063 return (0);
1064 } else if( (cnp->cn_namelen == 2) &&
2b69e610 1065 !strncmp(cnp->cn_nameptr,"..",2) && (flags & CNP_ISDOTDOT) ) {
984263bc
MD
1066 dprintf(("hpfs_lookup(0x%x,...): .. faked (0x%x)\n",
1067 dhp->h_no, dhp->h_fn.fn_parent));
1068
acde96db 1069 VOP__UNLOCK(dvp, 0);
984263bc
MD
1070
1071 error = VFS_VGET(hpmp->hpm_mp,
1072 dhp->h_fn.fn_parent, ap->a_vpp);
fad57d0e 1073 if (error) {
acde96db 1074 VOP__LOCK(dvp, 0);
984263bc
MD
1075 return(error);
1076 }
1077
acde96db 1078 if (lockparent && (error = VOP__LOCK(dvp, 0))) {
984263bc
MD
1079 vput( *(ap->a_vpp) );
1080 return (error);
1081 }
1082 return (error);
1083 } else {
1084 struct buf *bp;
1085 struct hpfsdirent *dep;
1086 struct hpfsnode *hp;
1087
1088 error = hpfs_genlookupbyname(dhp,
1089 cnp->cn_nameptr, cnp->cn_namelen, &bp, &dep);
1090 if (error) {
fad57d0e 1091 if (error == ENOENT &&
2b69e610 1092 (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME)) {
984263bc 1093 if(!lockparent)
acde96db 1094 VOP__UNLOCK(dvp, 0);
984263bc
MD
1095 return (EJUSTRETURN);
1096 }
1097
1098 return (error);
1099 }
1100
1101 dprintf(("hpfs_lookup: fnode: 0x%x, CPID: 0x%x\n",
1102 dep->de_fnode, dep->de_cpid));
1103
fad57d0e 1104 if (nameiop == NAMEI_DELETE) {
87de5057 1105 error = VOP_ACCESS(dvp, VWRITE, cred);
984263bc
MD
1106 if (error) {
1107 brelse(bp);
1108 return (error);
1109 }
1110 }
1111
1112 if (dhp->h_no == dep->de_fnode) {
1113 brelse(bp);
597aea93 1114 vref(dvp);
984263bc
MD
1115 *ap->a_vpp = dvp;
1116 return (0);
1117 }
1118
1119 error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, ap->a_vpp);
1120 if (error) {
086c1d7e 1121 kprintf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
984263bc
MD
1122 brelse(bp);
1123 return(error);
1124 }
1125
1126 hp = VTOHP(*ap->a_vpp);
1127
1128 hp->h_mtime = dep->de_mtime;
1129 hp->h_ctime = dep->de_ctime;
1130 hp->h_atime = dep->de_atime;
1131 bcopy(dep->de_name, hp->h_name, dep->de_namelen);
1132 hp->h_name[dep->de_namelen] = '\0';
1133 hp->h_namelen = dep->de_namelen;
1134 hp->h_flag |= H_PARVALID;
1135
1136 brelse(bp);
1137
fad57d0e 1138 if(!lockparent)
acde96db 1139 VOP__UNLOCK(dvp, 0);
984263bc
MD
1140 }
1141 return (error);
1142}
1143
dd3af26c
CP
1144/*
1145 * hpfs_remove(struct vnode *a_dvp, struct vnode *a_vp,
1146 * struct componentname *a_cnp)
1147 */
984263bc 1148int
e62afb5f 1149hpfs_remove(struct vop_old_remove_args *ap)
984263bc
MD
1150{
1151 int error;
1152
1153 dprintf(("hpfs_remove(0x%x, %s, %ld): \n", VTOHP(ap->a_vp)->h_no,
1154 ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
1155
1156 if (ap->a_vp->v_type == VDIR)
1157 return (EPERM);
1158
1159 error = hpfs_removefnode (ap->a_dvp, ap->a_vp, ap->a_cnp);
1160 return (error);
1161}
1162
dd3af26c
CP
1163/*
1164 * hpfs_create(struct vnode *a_dvp, struct vnode **a_vpp,
1165 * struct componentname *a_cnp, struct vattr *a_vap)
1166 */
984263bc 1167int
e62afb5f 1168hpfs_create(struct vop_old_create_args *ap)
984263bc
MD
1169{
1170 int error;
1171
1172 dprintf(("hpfs_create(0x%x, %s, %ld): \n", VTOHP(ap->a_dvp)->h_no,
1173 ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen));
1174
984263bc
MD
1175 error = hpfs_makefnode (ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
1176
1177 return (error);
1178}
1179
1180/*
1181 * Return POSIX pathconf information applicable to NTFS filesystem
dd3af26c
CP
1182 *
1183 * hpfs_pathconf(struct vnode *a_vp, int a_name, t *a_retval)
984263bc
MD
1184 */
1185int
dd3af26c 1186hpfs_pathconf(struct vop_pathconf_args *ap)
984263bc
MD
1187{
1188 switch (ap->a_name) {
1189 case _PC_LINK_MAX:
1190 *ap->a_retval = 1;
1191 return (0);
1192 case _PC_NAME_MAX:
1193 *ap->a_retval = HPFS_MAXFILENAME;
1194 return (0);
1195 case _PC_PATH_MAX:
1196 *ap->a_retval = PATH_MAX;
1197 return (0);
1198 case _PC_CHOWN_RESTRICTED:
1199 *ap->a_retval = 1;
1200 return (0);
1201 case _PC_NO_TRUNC:
1202 *ap->a_retval = 0;
1203 return (0);
1204#if defined(__NetBSD__)
1205 case _PC_SYNC_IO:
1206 *ap->a_retval = 1;
1207 return (0);
1208 case _PC_FILESIZEBITS:
1209 *ap->a_retval = 32;
1210 return (0);
1211#endif
1212 default:
1213 return (EINVAL);
1214 }
1215 /* NOTREACHED */
1216}
1217
1218
1219/*
1220 * Global vfs data structures
1221 */
a11aaa81 1222
66a1ddf5
MD
1223struct vop_ops hpfs_vnode_vops = {
1224 .vop_default = vop_defaultop,
1225 .vop_getattr = hpfs_getattr,
1226 .vop_setattr = hpfs_setattr,
1227 .vop_inactive = hpfs_inactive,
1228 .vop_reclaim = hpfs_reclaim,
1229 .vop_print = hpfs_print,
1230 .vop_old_create = hpfs_create,
1231 .vop_old_remove = hpfs_remove,
66a1ddf5
MD
1232 .vop_old_lookup = hpfs_lookup,
1233 .vop_access = hpfs_access,
1234 .vop_readdir = hpfs_readdir,
1235 .vop_fsync = hpfs_fsync,
1236 .vop_bmap = hpfs_bmap,
1237 .vop_getpages = hpfs_getpages,
1238 .vop_putpages = hpfs_putpages,
1239 .vop_strategy = hpfs_strategy,
1240 .vop_read = hpfs_read,
1241 .vop_write = hpfs_write,
1242 .vop_ioctl = hpfs_ioctl,
1243 .vop_pathconf = hpfs_pathconf
984263bc
MD
1244};
1245