diff options
Diffstat (limited to 'sys/fs/ntfs/ntfs_vnops.c')
-rw-r--r-- | sys/fs/ntfs/ntfs_vnops.c | 527 |
1 files changed, 238 insertions, 289 deletions
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c index 9d3f6e5..381cb8f 100644 --- a/sys/fs/ntfs/ntfs_vnops.c +++ b/sys/fs/ntfs/ntfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ntfs_vnops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */ +/* $NetBSD: ntfs_vnops.c,v 1.23 1999/10/31 19:45:27 jdolecek Exp $ */ /* * Copyright (c) 1992, 1993 @@ -42,7 +42,6 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/proc.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> @@ -55,6 +54,9 @@ #include <vm/vm.h> #include <vm/vm_param.h> +#if defined(__NetBSD__) +#include <vm/vm_prot.h> +#endif #include <vm/vm_page.h> #include <vm/vm_object.h> #include <vm/vm_pager.h> @@ -65,12 +67,16 @@ #include <sys/sysctl.h> - /*#define NTFS_DEBUG 1*/ #include <ntfs/ntfs.h> #include <ntfs/ntfs_inode.h> #include <ntfs/ntfs_subr.h> -#include <ntfs/ntfs_extern.h> +#if defined(__NetBSD__) +#include <miscfs/specfs/specdev.h> +#include <miscfs/genfs/genfs.h> +#endif + +#include <sys/unistd.h> /* for pathconf(2) constants */ static int ntfs_bypass __P((struct vop_generic_args *ap)); static int ntfs_read __P((struct vop_read_args *)); @@ -80,11 +86,6 @@ static int ntfs_inactive __P((struct vop_inactive_args *ap)); static int ntfs_print __P((struct vop_print_args *ap)); static int ntfs_reclaim __P((struct vop_reclaim_args *ap)); static int ntfs_strategy __P((struct vop_strategy_args *ap)); -#if defined(__NetBSD__) -static int ntfs_islocked __P((struct vop_islocked_args *ap)); -static int ntfs_unlock __P((struct vop_unlock_args *ap)); -static int ntfs_lock __P((struct vop_lock_args *ap)); -#endif static int ntfs_access __P((struct vop_access_args *ap)); static int ntfs_open __P((struct vop_open_args *ap)); static int ntfs_close __P((struct vop_close_args *ap)); @@ -94,8 +95,9 @@ static int ntfs_bmap __P((struct vop_bmap_args *ap)); #if defined(__FreeBSD__) static int ntfs_getpages __P((struct vop_getpages_args *ap)); static int ntfs_putpages __P((struct vop_putpages_args *)); -#endif static int ntfs_fsync __P((struct vop_fsync_args *ap)); +#endif +static int ntfs_pathconf __P((void *)); int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */ @@ -159,39 +161,31 @@ ntfs_read(ap) register struct ntnode *ip = FTONT(fp); struct uio *uio = ap->a_uio; struct ntfsmount *ntmp = ip->i_mp; - u_int8_t *data; u_int64_t toread; int error; dprintf(("ntfs_read: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg)); - toread = fp->f_size; - - dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread)); + dprintf(("ntfs_read: filesize: %d",(u_int32_t)fp->f_size)); - toread = min( uio->uio_resid, toread - uio->uio_offset ); + /* don't allow reading after end of file */ + if (uio->uio_offset > fp->f_size) + toread = 0; + else + toread = min( uio->uio_resid, fp->f_size - uio->uio_offset ); dprintf((", toread: %d\n",(u_int32_t)toread)); - MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK); + if (toread == 0) + return (0); error = ntfs_readattr(ntmp, ip, fp->f_attrtype, - fp->f_attrname, uio->uio_offset, toread, data); - if(error) { + fp->f_attrname, uio->uio_offset, toread, NULL, uio); + if (error) { printf("ntfs_read: ntfs_readattr failed: %d\n",error); - FREE(data, M_TEMP); - return (error); - } - - error = uiomove(data, (int) toread, uio); - if(error) { - printf("ntfs_read: uiomove failed: %d\n",error); - FREE(data, M_TEMP); return (error); } - FREE(data, M_TEMP); - return (0); } @@ -224,12 +218,16 @@ ntfs_getattr(ap) dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag)); - vap->va_fsid = dev2udev(fp->f_dev); +#if defined(__FreeBSD__) + vap->va_fsid = dev2udev(ip->i_dev); +#else /* NetBSD */ + vap->va_fsid = ip->i_dev; +#endif vap->va_fileid = ip->i_number; - vap->va_mode = ip->i_mode; + vap->va_mode = ip->i_mp->ntm_mode; vap->va_nlink = ip->i_nlink; - vap->va_uid = ip->i_uid; - vap->va_gid = ip->i_gid; + vap->va_uid = ip->i_mp->ntm_uid; + vap->va_gid = ip->i_mp->ntm_gid; vap->va_rdev = 0; /* XXX UNODEV ? */ vap->va_size = fp->f_size; vap->va_bytes = fp->f_allocated; @@ -239,7 +237,7 @@ ntfs_getattr(ap) vap->va_flags = ip->i_flag; vap->va_gen = 0; vap->va_blocksize = ip->i_mp->ntm_spc * ip->i_mp->ntm_bps; - vap->va_type = fp->f_type; + vap->va_type = vp->v_type; vap->va_filerev = 0; return (0); } @@ -255,33 +253,25 @@ ntfs_inactive(ap) } */ *ap; { register struct vnode *vp = ap->a_vp; +#ifdef NTFS_DEBUG register struct ntnode *ip = VTONT(vp); - int error; +#endif dprintf(("ntfs_inactive: vnode: %p, ntnode: %d\n", vp, ip->i_number)); if (ntfs_prtactive && vp->v_usecount != 0) vprint("ntfs_inactive: pushing active", vp); - error = 0; - - VOP__UNLOCK(vp,0,ap->a_p); + VOP__UNLOCK(vp, 0, ap->a_p); - /* - * If we are done with the ntnode, reclaim it - * so that it can be reused immediately. + /* XXX since we don't support any filesystem changes + * right now, nothing more needs to be done */ - if (vp->v_usecount == 0 && ip->i_mode == 0) -#if defined(__FreeBSD__) - vrecycle(vp, (struct simplelock *)0, ap->a_p); -#else /* defined(__NetBSD__) */ - vgone(vp); -#endif - return (error); + return (0); } /* - * Reclaim an inode so that it can be used for other purposes. + * Reclaim an fnode/ntnode so that it can be used for other purposes. */ int ntfs_reclaim(ap) @@ -296,26 +286,22 @@ ntfs_reclaim(ap) dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number)); - error = ntfs_ntget(ip); - if (error) - return (error); - -#if defined(__FreeBSD__) - VOP__UNLOCK(vp,0,ap->a_p); -#endif + if (ntfs_prtactive && vp->v_usecount != 0) + vprint("ntfs_reclaim: pushing active", vp); + if ((error = ntfs_ntget(ip)) != 0) + return (error); + /* Purge old data structures associated with the inode. */ cache_purge(vp); - if (fp->f_devvp) { - vrele(fp->f_devvp); - fp->f_devvp = NULL; + if (ip->i_devvp) { + vrele(ip->i_devvp); + ip->i_devvp = NULL; } ntfs_frele(fp); - - vp->v_data = NULL; - ntfs_ntput(ip); + vp->v_data = NULL; return (0); } @@ -326,8 +312,6 @@ ntfs_print(ap) struct vnode *a_vp; } */ *ap; { -/* printf("[ntfs_print]");*/ - return (0); } @@ -348,10 +332,17 @@ ntfs_strategy(ap) struct ntfsmount *ntmp = ip->i_mp; int error; +#ifdef __FreeBSD__ dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n", (u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno, (u_int32_t)bp->b_lblkno)); - dprintf(("strategy: bcount: %d flags: 0x%x\n", +#else + dprintf(("ntfs_strategy: blkno: %d, lblkno: %d\n", + (u_int32_t)bp->b_blkno, + (u_int32_t)bp->b_lblkno)); +#endif + + dprintf(("strategy: bcount: %d flags: 0x%lx\n", (u_int32_t)bp->b_bcount,bp->b_flags)); if (bp->b_flags & B_READ) { @@ -368,7 +359,7 @@ ntfs_strategy(ap) error = ntfs_readattr(ntmp, ip, fp->f_attrtype, fp->f_attrname, ntfs_cntob(bp->b_blkno), - toread, bp->b_data); + toread, bp->b_data, NULL); if (error) { printf("ntfs_strategy: ntfs_readattr failed\n"); @@ -394,7 +385,7 @@ ntfs_strategy(ap) error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype, fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite, - bp->b_data, &tmp); + bp->b_data, &tmp, NULL); if (error) { printf("ntfs_strategy: ntfs_writeattr fail\n"); @@ -421,172 +412,31 @@ ntfs_write(ap) register struct ntnode *ip = FTONT(fp); struct uio *uio = ap->a_uio; struct ntfsmount *ntmp = ip->i_mp; - u_int8_t *data; u_int64_t towrite; - off_t off; size_t written; int error; dprintf(("ntfs_write: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg)); + dprintf(("ntfs_write: filesize: %d",(u_int32_t)fp->f_size)); - towrite = fp->f_size; - - dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite)); - - if (uio->uio_resid + uio->uio_offset > towrite) { - printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n"); + if (uio->uio_resid + uio->uio_offset > fp->f_size) { + printf("ntfs_write: CAN'T WRITE BEYOND END OF FILE\n"); return (EFBIG); } - towrite = min(uio->uio_resid, towrite - uio->uio_offset); - off = uio->uio_offset; + towrite = min(uio->uio_resid, fp->f_size - uio->uio_offset); dprintf((", towrite: %d\n",(u_int32_t)towrite)); - MALLOC(data, u_int8_t *, towrite, M_TEMP,M_WAITOK); - - error = uiomove(data, (int) towrite, uio); - if(error) { - FREE(data, M_TEMP); - return (error); - } - error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype, - fp->f_attrname, off, towrite, data, &written); - if(error) { - printf("ntfs_write: ntfs_writeattr failed: %d\n",error); - FREE(data, M_TEMP); - return (error); - } - - FREE(data, M_TEMP); - - return (0); -} - -#if defined(__NetBSD__) -/* - * Check for a locked ntnode. - */ -int -ntfs_islocked(ap) - struct vop_islocked_args /* { - struct vnode *a_vp; - } */ *ap; -{ - register struct ntnode *ip = VTONT(ap->a_vp); - - dprintf(("ntfs_islocked %d\n",ip->i_number)); - - if (ip->i_flag & IN_LOCKED) - return (1); - return (0); -} - -/* - * Unlock an ntnode. If WANT bit is on, wakeup. - */ -int ntfs_lockcount = 90; -int -ntfs_unlock(ap) - struct vop_unlock_args /* { - struct vnode *a_vp; - } */ *ap; -{ - register struct ntnode *ip = VTONT(ap->a_vp); -#ifdef DIAGNOSTIC - struct proc *p = curproc; -#endif - - dprintf(("ntfs_unlock %d\n",ip->i_number)); - -#ifdef DIAGNOSTIC - - if ((ip->i_flag & IN_LOCKED) == 0) { - vprint("ntfs_unlock: unlocked ntnode", ap->a_vp); - panic("ntfs_unlock NOT LOCKED"); - } - if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 && - ip->i_lockholder > -1 && ntfs_lockcount++ < 100) - panic("unlocker (%d) != lock holder (%d)", - p->p_pid, ip->i_lockholder); -#endif - - if (--ip->i_lockcount > 0) { - if ((ip->i_flag & IN_RECURSE) == 0) - panic("ntfs_unlock: recursive lock prematurely released, pid=%d\n", ip->i_lockholder); - return (0); - } - ip->i_lockholder = 0; - ip->i_flag &= ~(IN_LOCKED|IN_RECURSE); - if (ip->i_flag & IN_WANTED) { - ip->i_flag &= ~IN_WANTED; - wakeup((caddr_t)ip); - } - return (0); -} - -/* - * Lock an ntnode. If its already locked, set the WANT bit and sleep. - */ -int -ntfs_lock(ap) - struct vop_lock_args /* { - struct vnode *a_vp; - } */ *ap; -{ - struct proc *p = curproc; - register struct vnode *vp = ap->a_vp; - register struct ntnode *ip = VTONT(vp); - - dprintf(("ntfs_lock %d (%d locks)\n",ip->i_number,ip->i_lockcount)); - -start: - while (vp->v_flag & VXLOCK) { - vp->v_flag |= VXWANT; - (void) tsleep((caddr_t)vp, PINOD, "ntflk1", 0); - } - if (vp->v_tag == VT_NON) - return (ENOENT); - ip = VTONT(vp); - if (ip->i_flag & IN_LOCKED) { - if (p->p_pid == ip->i_lockholder) { - if( (ip->i_flag & IN_RECURSE) == 0) - panic("ntfs_lock: recursive lock not expected, pid: %d\n", - ip->i_lockholder); - } else { - ip->i_flag |= IN_WANTED; -#ifdef DIAGNOSTIC - if (p) - ip->i_lockwaiter = p->p_pid; - else - ip->i_lockwaiter = -1; -#endif - (void) tsleep((caddr_t)ip, PINOD, "ntflk2", 0); - goto start; - } - } -#ifdef DIAGNOSTIC - ip->i_lockwaiter = 0; - if (((ip->i_flag & IN_RECURSE) == 0) && (ip->i_lockholder != 0)) - panic("lockholder (%d) != 0", ip->i_lockholder); - if (p && p->p_pid == 0) - printf("locking by process 0\n"); + fp->f_attrname, uio->uio_offset, towrite, NULL, &written, uio); +#ifdef NTFS_DEBUG + if (error) + printf("ntfs_write: ntfs_writeattr failed: %d\n", error); #endif - if ((ip->i_flag & IN_RECURSE) == 0) - ip->i_lockcount = 1; - else - ++ip->i_lockcount; - - if (p) - ip->i_lockholder = p->p_pid; - else - ip->i_lockholder = -1; - ip->i_flag |= IN_LOCKED; - return (0); + return (error); } -#endif int ntfs_access(ap) @@ -629,12 +479,6 @@ ntfs_access(ap) } } - /* If immutable bit set, nobody gets to write it. */ -/* - if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE)) - return (EPERM); -*/ - /* Otherwise, user id 0 always gets access. */ if (cred->cr_uid == 0) return (0); @@ -642,26 +486,26 @@ ntfs_access(ap) mask = 0; /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->i_uid) { + if (cred->cr_uid == ip->i_mp->ntm_uid) { if (mode & VEXEC) mask |= S_IXUSR; if (mode & VREAD) mask |= S_IRUSR; if (mode & VWRITE) mask |= S_IWUSR; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); + return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); } /* Otherwise, check the groups. */ for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->i_gid == *gp) { + if (ip->i_mp->ntm_gid == *gp) { if (mode & VEXEC) mask |= S_IXGRP; if (mode & VREAD) mask |= S_IRGRP; if (mode & VWRITE) mask |= S_IWGRP; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); + return ((ip->i_mp->ntm_mode&mask) == mask ? 0 : EACCES); } /* Otherwise, check everyone else. */ @@ -671,7 +515,7 @@ ntfs_access(ap) mask |= S_IROTH; if (mode & VWRITE) mask |= S_IWOTH; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); + return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); } /* @@ -794,31 +638,31 @@ ntfs_readdir(ap) if( NULL == iep ) break; - while( !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent)) ) { - - if( ntfs_isnamepermitted(ntmp,iep) ) { - dprintf(("ntfs_readdir: elem: %d, fname:[",num)); - for(i=0;i<iep->ie_fnamelen;i++) { - cde.d_name[i] = (char)iep->ie_fname[i]; - dprintf(("%c", cde.d_name[i])); - } - dprintf(("] type: %d, flag: %d, ",iep->ie_fnametype, iep->ie_flag)); - cde.d_name[i] = '\0'; - cde.d_namlen = iep->ie_fnamelen; - cde.d_fileno = iep->ie_number; - cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG; - cde.d_reclen = sizeof(struct dirent); - dprintf(("%s\n", (cde.d_type == DT_DIR) ? "dir":"reg")); - - error = uiomove((char *)&cde, sizeof(struct dirent), uio); - if(error) - return (error); - - ncookies++; - num++; + for(; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent)); + iep = NTFS_NEXTREC(iep, struct attr_indexentry *)) + { + if(!ntfs_isnamepermitted(ntmp,iep)) + continue; + + for(i=0; i<iep->ie_fnamelen; i++) { + cde.d_name[i] = ntfs_u28(iep->ie_fname[i]); } + cde.d_name[i] = '\0'; + dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ", + num, cde.d_name, iep->ie_fnametype, + iep->ie_flag)); + cde.d_namlen = iep->ie_fnamelen; + cde.d_fileno = iep->ie_number; + cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG; + cde.d_reclen = sizeof(struct dirent); + dprintf(("%s\n", (cde.d_type == DT_DIR) ? "dir":"reg")); + + error = uiomove((char *)&cde, sizeof(struct dirent), uio); + if(error) + return (error); - iep = NTFS_NEXTREC(iep,struct attr_indexentry *); + ncookies++; + num++; } } @@ -838,7 +682,7 @@ ntfs_readdir(ap) off_t *cookiep; #endif - printf("ntfs_readdir: %d cookies\n",ncookies); + ddprintf(("ntfs_readdir: %d cookies\n",ncookies)); if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) panic("ntfs_readdir: unexpected uio from NFS server"); dpStart = (struct dirent *) @@ -885,25 +729,40 @@ ntfs_lookup(ap) #if NTFS_DEBUG int wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); #endif - dprintf(("ntfs_lookup: %s (%ld bytes) in %d, lp: %d, wp: %d \n", - cnp->cn_nameptr, cnp->cn_namelen, - dip->i_number,lockparent, wantparent)); + dprintf(("ntfs_lookup: \"%.*s\" (%ld bytes) in %d, lp: %d, wp: %d \n", + (int)cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_namelen, + dip->i_number, lockparent, wantparent)); error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc); if(error) return (error); - if( (cnp->cn_namelen == 1) && - !strncmp(cnp->cn_nameptr,".",1) ) { + if ((cnp->cn_flags & ISLASTCN) && + (dvp->v_mount->mnt_flag & MNT_RDONLY) && + (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) + return (EROFS); + +#ifdef __NetBSD__ + /* + * We now have a segment name to search for, and a directory + * to search. + * + * Before tediously performing a linear scan of the directory, + * check the name cache to see if the directory/name pair + * we are looking for is known already. + */ + if ((error = cache_lookup(ap->a_dvp, ap->a_vpp, cnp)) >= 0) + return (error); +#endif + + if(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { dprintf(("ntfs_lookup: faking . directory in %d\n", dip->i_number)); VREF(dvp); *ap->a_vpp = dvp; - return (0); - } else if( (cnp->cn_namelen == 2) && - !strncmp(cnp->cn_nameptr,"..",2) && - (cnp->cn_flags & ISDOTDOT) ) { + error = 0; + } else if (cnp->cn_flags & ISDOTDOT) { struct ntvattr *vap; dprintf(("ntfs_lookup: faking .. directory in %d\n", @@ -914,40 +773,48 @@ ntfs_lookup(ap) return (error); VOP__UNLOCK(dvp,0,cnp->cn_proc); + cnp->cn_flags |= PDIRUNLOCK; dprintf(("ntfs_lookup: parentdir: %d\n", vap->va_a_name->n_pnumber)); error = VFS_VGET(ntmp->ntm_mountp, vap->va_a_name->n_pnumber,ap->a_vpp); ntfs_ntvattrrele(vap); - if(error) { - VOP__LOCK(dvp, 0, cnp->cn_proc); - return(error); + if (error) { + if (VN_LOCK(dvp,LK_EXCLUSIVE|LK_RETRY,cnp->cn_proc)==0) + cnp->cn_flags &= ~PDIRUNLOCK; + return (error); } - if( lockparent && (cnp->cn_flags & ISLASTCN) && - (error = VOP__LOCK(dvp, 0, cnp->cn_proc)) ) { - vput( *(ap->a_vpp) ); - return (error); + if (lockparent && (cnp->cn_flags & ISLASTCN)) { + error = VN_LOCK(dvp, LK_EXCLUSIVE, cnp->cn_proc); + if (error) { + vput( *(ap->a_vpp) ); + return (error); + } + cnp->cn_flags &= ~PDIRUNLOCK; } - return (error); } else { error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp); - if(error) + if (error) { + dprintf(("ntfs_ntlookupfile: returned %d\n", error)); return (error); + } dprintf(("ntfs_lookup: found ino: %d\n", VTONT(*ap->a_vpp)->i_number)); if(!lockparent || !(cnp->cn_flags & ISLASTCN)) VOP__UNLOCK(dvp, 0, cnp->cn_proc); - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, *ap->a_vpp, cnp); - } + + if (cnp->cn_flags & MAKEENTRY) + cache_enter(dvp, *ap->a_vpp, cnp); + return (error); } +#if defined(__FreeBSD__) /* * Flush the blocks of a file to disk. * @@ -965,6 +832,50 @@ ntfs_fsync(ap) { return (0); } +#endif + +/* + * Return POSIX pathconf information applicable to NTFS filesystem + */ +int +ntfs_pathconf(v) + void *v; +{ + struct vop_pathconf_args /* { + struct vnode *a_vp; + int a_name; + register_t *a_retval; + } */ *ap = v; + + switch (ap->a_name) { + case _PC_LINK_MAX: + *ap->a_retval = 1; + return (0); + case _PC_NAME_MAX: + *ap->a_retval = NTFS_MAXFILENAME; + return (0); + case _PC_PATH_MAX: + *ap->a_retval = PATH_MAX; + return (0); + case _PC_CHOWN_RESTRICTED: + *ap->a_retval = 1; + return (0); + case _PC_NO_TRUNC: + *ap->a_retval = 0; + return (0); +#if defined(__NetBSD__) + case _PC_SYNC_IO: + *ap->a_retval = 1; + return (0); + case _PC_FILESIZEBITS: + *ap->a_retval = 64; + return (0); +#endif + default: + return (EINVAL); + } + /* NOTREACHED */ +} /* * Global vfs data structures @@ -972,7 +883,6 @@ ntfs_fsync(ap) vop_t **ntfs_vnodeop_p; #if defined(__FreeBSD__) static -#endif struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { { &vop_default_desc, (vop_t *)ntfs_bypass }, @@ -980,19 +890,13 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { { &vop_inactive_desc, (vop_t *)ntfs_inactive }, { &vop_reclaim_desc, (vop_t *)ntfs_reclaim }, { &vop_print_desc, (vop_t *)ntfs_print }, + { &vop_pathconf_desc, ntfs_pathconf }, -#if defined(__FreeBSD__) { &vop_islocked_desc, (vop_t *)vop_stdislocked }, { &vop_unlock_desc, (vop_t *)vop_stdunlock }, { &vop_lock_desc, (vop_t *)vop_stdlock }, { &vop_cachedlookup_desc, (vop_t *)ntfs_lookup }, { &vop_lookup_desc, (vop_t *)vfs_cache_lookup }, -#else - { &vop_islocked_desc, (vop_t *)ntfs_islocked }, - { &vop_unlock_desc, (vop_t *)ntfs_unlock }, - { &vop_lock_desc, (vop_t *)ntfs_lock }, - { &vop_lookup_desc, (vop_t *)ntfs_lookup }, -#endif { &vop_access_desc, (vop_t *)ntfs_access }, { &vop_close_desc, (vop_t *)ntfs_close }, @@ -1001,28 +905,73 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { { &vop_fsync_desc, (vop_t *)ntfs_fsync }, { &vop_bmap_desc, (vop_t *)ntfs_bmap }, -#if defined(__FreeBSD__) { &vop_getpages_desc, (vop_t *) ntfs_getpages }, { &vop_putpages_desc, (vop_t *) ntfs_putpages }, -#endif { &vop_strategy_desc, (vop_t *)ntfs_strategy }, -#if defined(__FreeBSD__) { &vop_bwrite_desc, (vop_t *)vop_stdbwrite }, -#else /* defined(__NetBSD__) */ - { &vop_bwrite_desc, (vop_t *)vn_bwrite }, -#endif { &vop_read_desc, (vop_t *)ntfs_read }, { &vop_write_desc, (vop_t *)ntfs_write }, { NULL, NULL } }; -#if defined(__FreeBSD__) static -#endif struct vnodeopv_desc ntfs_vnodeop_opv_desc = { &ntfs_vnodeop_p, ntfs_vnodeop_entries }; -#if defined(__FreeBSD__) VNODEOP_SET(ntfs_vnodeop_opv_desc); + +#else /* !FreeBSD */ + +struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { + { &vop_default_desc, (vop_t *) ntfs_bypass }, + { &vop_lookup_desc, (vop_t *) ntfs_lookup }, /* lookup */ + { &vop_create_desc, genfs_eopnotsupp }, /* create */ + { &vop_mknod_desc, genfs_eopnotsupp }, /* mknod */ + { &vop_open_desc, (vop_t *) ntfs_open }, /* open */ + { &vop_close_desc,(vop_t *) ntfs_close }, /* close */ + { &vop_access_desc, (vop_t *) ntfs_access }, /* access */ + { &vop_getattr_desc, (vop_t *) ntfs_getattr }, /* getattr */ + { &vop_setattr_desc, genfs_eopnotsupp }, /* setattr */ + { &vop_read_desc, (vop_t *) ntfs_read }, /* read */ + { &vop_write_desc, (vop_t *) ntfs_write }, /* write */ + { &vop_lease_desc, genfs_lease_check }, /* lease */ + { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ + { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ + { &vop_poll_desc, genfs_poll }, /* poll */ + { &vop_revoke_desc, genfs_revoke }, /* revoke */ + { &vop_mmap_desc, genfs_eopnotsupp }, /* mmap */ + { &vop_fsync_desc, genfs_fsync }, /* fsync */ + { &vop_seek_desc, genfs_seek }, /* seek */ + { &vop_remove_desc, genfs_eopnotsupp }, /* remove */ + { &vop_link_desc, genfs_eopnotsupp }, /* link */ + { &vop_rename_desc, genfs_eopnotsupp }, /* rename */ + { &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */ + { &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */ + { &vop_symlink_desc, genfs_eopnotsupp }, /* symlink */ + { &vop_readdir_desc, (vop_t *) ntfs_readdir }, /* readdir */ + { &vop_readlink_desc, genfs_eopnotsupp }, /* readlink */ + { &vop_abortop_desc, genfs_abortop }, /* abortop */ + { &vop_inactive_desc, (vop_t *) ntfs_inactive }, /* inactive */ + { &vop_reclaim_desc, (vop_t *) ntfs_reclaim }, /* reclaim */ + { &vop_lock_desc, genfs_lock }, /* lock */ + { &vop_unlock_desc, genfs_unlock }, /* unlock */ + { &vop_bmap_desc, (vop_t *) ntfs_bmap }, /* bmap */ + { &vop_strategy_desc, (vop_t *) ntfs_strategy }, /* strategy */ + { &vop_print_desc, (vop_t *) ntfs_print }, /* print */ + { &vop_islocked_desc, genfs_islocked }, /* islocked */ + { &vop_pathconf_desc, ntfs_pathconf }, /* pathconf */ + { &vop_advlock_desc, genfs_nullop }, /* advlock */ + { &vop_blkatoff_desc, genfs_eopnotsupp }, /* blkatoff */ + { &vop_valloc_desc, genfs_eopnotsupp }, /* valloc */ + { &vop_reallocblks_desc, genfs_eopnotsupp }, /* reallocblks */ + { &vop_vfree_desc, genfs_eopnotsupp }, /* vfree */ + { &vop_truncate_desc, genfs_eopnotsupp }, /* truncate */ + { &vop_update_desc, genfs_eopnotsupp }, /* update */ + { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ + { (struct vnodeop_desc *)NULL, (int (*) __P((void *)))NULL } +}; +struct vnodeopv_desc ntfs_vnodeop_opv_desc = + { &ntfs_vnodeop_p, ntfs_vnodeop_entries }; + #endif |