diff options
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/nwfs/nwfs.h | 79 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_io.c | 599 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_ioctl.c | 89 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_mount.h | 68 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_node.c | 379 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_node.h | 96 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_subr.c | 553 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_subr.h | 90 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_vfsops.c | 439 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_vnops.c | 967 |
10 files changed, 0 insertions, 3359 deletions
diff --git a/sys/fs/nwfs/nwfs.h b/sys/fs/nwfs/nwfs.h deleted file mode 100644 index af71724..0000000 --- a/sys/fs/nwfs/nwfs.h +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 1999 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _NWFS_H_ -#define _NWFS_H_ - -#include <netncp/ncp.h> -#include <fs/nwfs/nwfs_mount.h> - -#define NR_OPEN 0 -#define NW_NSB_DOS (1 << NW_NS_DOS) -#define NW_NSB_MAC (1 << NW_NS_MAC) -#define NW_NSB_NFS (1 << NW_NS_NFS) -#define NW_NSB_FTAM (1 << NW_NS_FTAM) -#define NW_NSB_OS2 (1 << NW_NS_OS2) - -#define NWFSIOC_GETCONN _IOR('n',1,int) -#define NWFSIOC_GETEINFO _IOR('n',2,struct nw_entry_info) -#define NWFSIOC_GETNS _IOR('n',3,int) - -#ifdef _KERNEL - -#include <sys/vnode.h> -#include <sys/mount.h> - -struct nwfsnode; - -struct nwmount { - struct nwfs_args m; - struct mount *mp; - struct ncp_handle *connh; - int name_space; - struct nwnode *n_root; - u_int32_t n_volume; - ncpfid n_rootent; - int n_id; -}; - -#define VFSTONWFS(mntp) ((struct nwmount *)((mntp)->mnt_data)) -#define NWFSTOVFS(mnp) ((struct mount *)((mnp)->mount)) -#define VTOVFS(vp) ((vp)->v_mount) -#define VTONWFS(vp) (VFSTONWFS(VTOVFS(vp))) -#define NWFSTOCONN(nmp) ((nmp)->connh->nh_conn) - -int ncp_conn_logged_in(struct nwmount *); -int nwfs_ioctl(struct vop_ioctl_args *ap); -int nwfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td); -int nwfs_vinvalbuf(struct vnode *vp, struct thread *td); - -extern struct vop_vector nwfs_vnodeops; - -#endif /* _KERNEL */ - -#endif /* _NWFS_H_ */ diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c deleted file mode 100644 index cd3c989..0000000 --- a/sys/fs/nwfs/nwfs_io.c +++ /dev/null @@ -1,599 +0,0 @@ -/*- - * Copyright (c) 1999 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/mount.h> -#include <sys/namei.h> -#include <sys/vnode.h> -#include <sys/dirent.h> -#include <sys/sysctl.h> - -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/vm_page.h> -#include <vm/vm_extern.h> -#include <vm/vm_object.h> -#include <vm/vm_pager.h> -#include <vm/vnode_pager.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_subr.h> -#include <netncp/ncp_ncp.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -static int nwfs_fastlookup = 1; - -SYSCTL_DECL(_vfs_nwfs); -SYSCTL_INT(_vfs_nwfs, OID_AUTO, fastlookup, CTLFLAG_RW, &nwfs_fastlookup, 0, ""); - - -extern int nwfs_pbuf_freecnt; - -#define DE_SIZE (sizeof(struct dirent)) -#define NWFS_RWCACHE - -static int -nwfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) { - struct nwmount *nmp = VTONWFS(vp); - int error, count, i; - struct dirent dp; - struct nwnode *np = VTONW(vp); - struct nw_entry_info fattr; - struct vnode *newvp; - struct componentname cn; - ncpfid fid; - - np = VTONW(vp); - NCPVNDEBUG("dirname='%s'\n",np->n_name); - if (uio->uio_resid < DE_SIZE || (uio->uio_offset < 0)) - return (EINVAL); - error = 0; - count = 0; - i = uio->uio_offset / DE_SIZE; /* offset in directory */ - if (i == 0) { - error = ncp_initsearch(vp, uio->uio_td, cred); - if (error) { - NCPVNDEBUG("cannot initialize search, error=%d",error); - return( error ); - } - } - - for (; uio->uio_resid >= DE_SIZE; i++) { - bzero((char *) &dp, DE_SIZE); - dp.d_reclen = DE_SIZE; - switch (i) { - case 0: /* `.' */ - case 1: /* `..' */ - dp.d_fileno = (i == 0) ? np->n_fid.f_id : np->n_parent.f_id; - if (!dp.d_fileno) dp.d_fileno = NWFS_ROOT_INO; - dp.d_namlen = i + 1; - dp.d_name[0] = '.'; - dp.d_name[1] = '.'; - dp.d_name[i + 1] = '\0'; - dp.d_type = DT_DIR; - break; - default: - error = ncp_search_for_file_or_subdir(nmp, &np->n_seq, &fattr, uio->uio_td, cred); - if (error && error < 0x80) break; - dp.d_fileno = fattr.dirEntNum; - dp.d_type = (fattr.attributes & aDIR) ? DT_DIR : DT_REG; - dp.d_namlen = fattr.nameLen; - bcopy(fattr.entryName, dp.d_name, dp.d_namlen); - dp.d_name[dp.d_namlen] = '\0'; -#if 0 - if (error && eofflag) { - /* *eofflag = 1;*/ - break; - } -#endif - break; - } - if (nwfs_fastlookup && !error && i > 1) { - fid.f_id = fattr.dirEntNum; - fid.f_parent = np->n_fid.f_id; - error = nwfs_nget(vp->v_mount, fid, &fattr, vp, &newvp); - if (!error) { - VTONW(newvp)->n_ctime = VTONW(newvp)->n_vattr.va_ctime.tv_sec; - cn.cn_nameptr = dp.d_name; - cn.cn_namelen = dp.d_namlen; - cache_enter(vp, newvp, &cn); - vput(newvp); - } else - error = 0; - } - if (error >= 0x80) { - error = 0; - break; - } - if ((error = uiomove(&dp, DE_SIZE, uio))) - break; - } - - uio->uio_offset = i * DE_SIZE; - return (error); -} - -int -nwfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred) { - struct nwmount *nmp = VFSTONWFS(vp->v_mount); - struct nwnode *np = VTONW(vp); - struct thread *td; - struct vattr vattr; - int error, biosize; - - if (vp->v_type != VREG && vp->v_type != VDIR) { - printf("%s: vn types other than VREG or VDIR are unsupported !\n",__func__); - return EIO; - } - if (uiop->uio_resid == 0) return 0; - if (uiop->uio_offset < 0) return EINVAL; -/* if (uiop->uio_offset + uiop->uio_resid > nmp->nm_maxfilesize) - return (EFBIG);*/ - td = uiop->uio_td; - if (vp->v_type == VDIR) { - error = nwfs_readvdir(vp, uiop, cred); - return error; - } - biosize = NWFSTOCONN(nmp)->buffer_size; - if (np->n_flag & NMODIFIED) { - nwfs_attr_cacheremove(vp); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, cred); - if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - error = nwfs_vinvalbuf(vp, td); - if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } - } - error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, uiop, cred); - return (error); -} - -int -nwfs_writevnode(vp, uiop, cred, ioflag) - struct vnode *vp; - struct uio *uiop; - struct ucred *cred; - int ioflag; -{ - struct nwmount *nmp = VTONWFS(vp); - struct nwnode *np = VTONW(vp); - struct thread *td; -/* struct vattr vattr;*/ - int error = 0; - - if (vp->v_type != VREG) { - printf("%s: vn types other than VREG unsupported !\n",__func__); - return EIO; - } - NCPVNDEBUG("ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid); - if (uiop->uio_offset < 0) return EINVAL; -/* if (uiop->uio_offset + uiop->uio_resid > nmp->nm_maxfilesize) - return (EFBIG);*/ - td = uiop->uio_td; - if (ioflag & (IO_APPEND | IO_SYNC)) { - if (np->n_flag & NMODIFIED) { - nwfs_attr_cacheremove(vp); - error = nwfs_vinvalbuf(vp, td); - if (error) return (error); - } - if (ioflag & IO_APPEND) { - /* We can relay only on local information about file size, - * because until file is closed NetWare will not return - * the correct size. */ -#ifdef notyet - nwfs_attr_cacheremove(vp); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) return (error); -#endif - uiop->uio_offset = np->n_size; - } - } - if (uiop->uio_resid == 0) return 0; - - if (vn_rlimit_fsize(vp, uiop, td)) - return (EFBIG); - - error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cred); - NCPVNDEBUG("after: ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid); - if (!error) { - if (uiop->uio_offset > np->n_size) { - np->n_vattr.va_size = np->n_size = uiop->uio_offset; - vnode_pager_setsize(vp, np->n_size); - } - } - return (error); -} - -/* - * Do an I/O operation to/from a cache block. - */ -int -nwfs_doio(vp, bp, cr, td) - struct vnode *vp; - struct buf *bp; - struct ucred *cr; - struct thread *td; -{ - struct uio *uiop; - struct nwnode *np; - struct nwmount *nmp; - int error = 0; - struct uio uio; - struct iovec io; - - np = VTONW(vp); - nmp = VFSTONWFS(vp->v_mount); - uiop = &uio; - uiop->uio_iov = &io; - uiop->uio_iovcnt = 1; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = td; - if (bp->b_iocmd == BIO_READ) { - io.iov_len = uiop->uio_resid = bp->b_bcount; - io.iov_base = bp->b_data; - uiop->uio_rw = UIO_READ; - switch (vp->v_type) { - case VREG: - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; - error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, uiop, cr); - if (error) - break; - if (uiop->uio_resid) { - int left = uiop->uio_resid; - int nread = bp->b_bcount - left; - if (left > 0) - bzero((char *)bp->b_data + nread, left); - } - break; -/* case VDIR: - nfsstats.readdir_bios++; - uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ; - if (nmp->nm_flag & NFSMNT_RDIRPLUS) { - error = nfs_readdirplusrpc(vp, uiop, cr); - if (error == NFSERR_NOTSUPP) - nmp->nm_flag &= ~NFSMNT_RDIRPLUS; - } - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0) - error = nfs_readdirrpc(vp, uiop, cr); - if (error == 0 && uiop->uio_resid == bp->b_bcount) - bp->b_flags |= B_INVAL; - break; -*/ - default: - printf("nwfs_doio: type %x unexpected\n",vp->v_type); - break; - }; - if (error) { - bp->b_ioflags |= BIO_ERROR; - bp->b_error = error; - } - } else { /* write */ - if (((bp->b_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) - bp->b_dirtyend = np->n_size - (bp->b_blkno * DEV_BSIZE); - - if (bp->b_dirtyend > bp->b_dirtyoff) { - io.iov_len = uiop->uio_resid = bp->b_dirtyend - bp->b_dirtyoff; - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; - io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; - uiop->uio_rw = UIO_WRITE; - error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cr); - - /* - * For an interrupted write, the buffer is still valid - * and the write hasn't been pushed to the server yet, - * so we can't set BIO_ERROR and report the interruption - * by setting B_EINTR. For the B_ASYNC case, B_EINTR - * is not relevant, so the rpc attempt is essentially - * a noop. For the case of a V3 write rpc not being - * committed to stable storage, the block is still - * dirty and requires either a commit rpc or another - * write rpc with iomode == NFSV3WRITE_FILESYNC before - * the block is reused. This is indicated by setting - * the B_DELWRI and B_NEEDCOMMIT flags. - */ - if (error == EINTR - || (!error && (bp->b_flags & B_NEEDCOMMIT))) { - int s; - - s = splbio(); - bp->b_flags &= ~(B_INVAL|B_NOCACHE); - if ((bp->b_flags & B_ASYNC) == 0) - bp->b_flags |= B_EINTR; - if ((bp->b_flags & B_PAGING) == 0) { - bdirty(bp); - bp->b_flags &= ~B_DONE; - } - if ((bp->b_flags & B_ASYNC) == 0) - bp->b_flags |= B_EINTR; - splx(s); - } else { - if (error) { - bp->b_ioflags |= BIO_ERROR; - bp->b_error /*= np->n_error */= error; -/* np->n_flag |= NWRITEERR;*/ - } - bp->b_dirtyoff = bp->b_dirtyend = 0; - } - } else { - bp->b_resid = 0; - bufdone(bp); - return (0); - } - } - bp->b_resid = uiop->uio_resid; - bufdone(bp); - return (error); -} - -/* - * Vnode op for VM getpages. - * Wish wish .... get rid from multiple IO routines - */ -int -nwfs_getpages(ap) - struct vop_getpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_reqpage; - vm_ooffset_t a_offset; - } */ *ap; -{ -#ifndef NWFS_RWCACHE - return vop_stdgetpages(ap);(ap->a_vp, ap->a_m, ap->a_count, -#else - int i, error, nextoff, size, toff, npages, count; - struct uio uio; - struct iovec iov; - vm_offset_t kva; - struct buf *bp; - struct vnode *vp; - struct thread *td; - struct ucred *cred; - struct nwmount *nmp; - struct nwnode *np; - vm_object_t object; - vm_page_t *pages; - - vp = ap->a_vp; - td = curthread; /* XXX */ - cred = td->td_ucred; /* XXX */ - np = VTONW(vp); - nmp = VFSTONWFS(vp->v_mount); - pages = ap->a_m; - count = ap->a_count; - - if ((object = vp->v_object) == NULL) { - printf("nwfs_getpages: called with non-merged cache vnode??\n"); - return VM_PAGER_ERROR; - } - - bp = getpbuf(&nwfs_pbuf_freecnt); - npages = btoc(count); - kva = (vm_offset_t) bp->b_data; - pmap_qenter(kva, pages, npages); - - iov.iov_base = (caddr_t) kva; - iov.iov_len = count; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); - uio.uio_resid = count; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_READ; - uio.uio_td = td; - - error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, &uio,cred); - pmap_qremove(kva, npages); - - relpbuf(bp, &nwfs_pbuf_freecnt); - - VM_OBJECT_LOCK(object); - if (error && (uio.uio_resid == count)) { - printf("nwfs_getpages: error %d\n",error); - for (i = 0; i < npages; i++) { - if (ap->a_reqpage != i) { - vm_page_lock(pages[i]); - vm_page_free(pages[i]); - vm_page_unlock(pages[i]); - } - } - VM_OBJECT_UNLOCK(object); - return VM_PAGER_ERROR; - } - - size = count - uio.uio_resid; - - for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { - vm_page_t m; - nextoff = toff + PAGE_SIZE; - m = pages[i]; - - if (nextoff <= size) { - m->valid = VM_PAGE_BITS_ALL; - KASSERT(m->dirty == 0, - ("nwfs_getpages: page %p is dirty", m)); - } else { - int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1); - vm_page_set_valid_range(m, 0, nvalid); - KASSERT((m->dirty & vm_page_bits(0, nvalid)) == 0, - ("nwfs_getpages: page %p is dirty", m)); - } - - if (i != ap->a_reqpage) - vm_page_readahead_finish(m); - } - VM_OBJECT_UNLOCK(object); - return 0; -#endif /* NWFS_RWCACHE */ -} - -/* - * Vnode op for VM putpages. - * possible bug: all IO done in sync mode - * Note that vop_close always invalidate pages before close, so it's - * not necessary to open vnode. - */ -int -nwfs_putpages(ap) - struct vop_putpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_sync; - int *a_rtvals; - vm_ooffset_t a_offset; - } */ *ap; -{ - int error; - struct vnode *vp = ap->a_vp; - struct thread *td; - struct ucred *cred; - -#ifndef NWFS_RWCACHE - td = curthread; /* XXX */ - cred = td->td_ucred; /* XXX */ - VOP_OPEN(vp, FWRITE, cred, td, NULL); - error = vop_stdputpages(ap); - VOP_CLOSE(vp, FWRITE, cred, td); - return error; -#else - struct uio uio; - struct iovec iov; - vm_offset_t kva; - struct buf *bp; - int i, npages, count; - int *rtvals; - struct nwmount *nmp; - struct nwnode *np; - vm_page_t *pages; - - td = curthread; /* XXX */ - cred = td->td_ucred; /* XXX */ -/* VOP_OPEN(vp, FWRITE, cred, td, NULL);*/ - np = VTONW(vp); - nmp = VFSTONWFS(vp->v_mount); - pages = ap->a_m; - count = ap->a_count; - rtvals = ap->a_rtvals; - npages = btoc(count); - - for (i = 0; i < npages; i++) { - rtvals[i] = VM_PAGER_ERROR; - } - - bp = getpbuf(&nwfs_pbuf_freecnt); - kva = (vm_offset_t) bp->b_data; - pmap_qenter(kva, pages, npages); - - iov.iov_base = (caddr_t) kva; - iov.iov_len = count; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); - uio.uio_resid = count; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_WRITE; - uio.uio_td = td; - NCPVNDEBUG("ofs=%d,resid=%d\n",(int)uio.uio_offset, uio.uio_resid); - - error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, &uio, cred); -/* VOP_CLOSE(vp, FWRITE, cred, td);*/ - NCPVNDEBUG("paged write done: %d\n", error); - - pmap_qremove(kva, npages); - relpbuf(bp, &nwfs_pbuf_freecnt); - - if (!error) - vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid); - return rtvals[0]; -#endif /* NWFS_RWCACHE */ -} -/* - * Flush and invalidate all dirty buffers. If another process is already - * doing the flush, just wait for completion. - */ -int -nwfs_vinvalbuf(vp, td) - struct vnode *vp; - struct thread *td; -{ - struct nwnode *np = VTONW(vp); -/* struct nwmount *nmp = VTONWFS(vp);*/ - int error = 0; - - if (vp->v_iflag & VI_DOOMED) - return (0); - - while (np->n_flag & NFLUSHINPROG) { - np->n_flag |= NFLUSHWANT; - error = tsleep(&np->n_flag, PRIBIO + 2, "nwfsvinv", 2 * hz); - error = ncp_chkintr(NWFSTOCONN(VTONWFS(vp)), td); - if (error == EINTR) - return EINTR; - } - np->n_flag |= NFLUSHINPROG; - - if (vp->v_bufobj.bo_object != NULL) { - VM_OBJECT_LOCK(vp->v_bufobj.bo_object); - vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); - } - - error = vinvalbuf(vp, V_SAVE, PCATCH, 0); - while (error) { - if (error == ERESTART || error == EINTR) { - np->n_flag &= ~NFLUSHINPROG; - if (np->n_flag & NFLUSHWANT) { - np->n_flag &= ~NFLUSHWANT; - wakeup(&np->n_flag); - } - return EINTR; - } - error = vinvalbuf(vp, V_SAVE, PCATCH, 0); - } - np->n_flag &= ~(NMODIFIED | NFLUSHINPROG); - if (np->n_flag & NFLUSHWANT) { - np->n_flag &= ~NFLUSHWANT; - wakeup(&np->n_flag); - } - return (error); -} diff --git a/sys/fs/nwfs/nwfs_ioctl.c b/sys/fs/nwfs/nwfs_ioctl.c deleted file mode 100644 index 35fe93e..0000000 --- a/sys/fs/nwfs/nwfs_ioctl.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 1999 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/ioccom.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_subr.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -int -nwfs_ioctl(ap) - struct vop_ioctl_args /* { - struct vnode *a_vp; - u_long a_command; - caddr_t a_data; - int fflag; - struct ucred *cred; - struct thread *td; - } */ *ap; -{ - int error; - struct thread *td = ap->a_td; - struct ucred *cred = ap->a_cred; - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - struct ncp_conn *conn = NWFSTOCONN(nmp); - struct ncp_handle *hp; - struct nw_entry_info *fap; - void *data = ap->a_data; - - switch (ap->a_command) { - case NWFSIOC_GETCONN: - error = ncp_conn_lock(conn, td, cred, NCPM_READ); - if (error) break; - error = ncp_conn_gethandle(conn, td, &hp); - ncp_conn_unlock(conn, td); - if (error) break; - *(int*)data = hp->nh_id; - break; - case NWFSIOC_GETEINFO: - if ((error = VOP_ACCESS(vp, VEXEC, cred, td))) break; - fap = data; - error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, fap, - ap->a_td,ap->a_cred); - strcpy(fap->entryName, np->n_name); - fap->nameLen = np->n_nmlen; - break; - case NWFSIOC_GETNS: - if ((error = VOP_ACCESS(vp, VEXEC, cred, td))) break; - *(int*)data = nmp->name_space; - break; - default: - error = ENOTTY; - } - return (error); -} diff --git a/sys/fs/nwfs/nwfs_mount.h b/sys/fs/nwfs/nwfs_mount.h deleted file mode 100644 index 92c11af..0000000 --- a/sys/fs/nwfs/nwfs_mount.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 1999 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _NWFS_MOUNT_H_ -#define _NWFS_MOUNT_H_ - -#ifndef _NCP_NCP_NLS_H_ -#include <netncp/ncp_nls.h> -#endif - -#define NWFS_VERMAJ 1 -#define NWFS_VERMIN 3400 -#define NWFS_VERSION (NWFS_VERMAJ*100000 + NWFS_VERMIN) - -/* Values for flags */ -#define NWFS_MOUNT_SOFT 0x0001 -#define WNFS_MOUNT_INTR 0x0002 -#define NWFS_MOUNT_STRONG 0x0004 -#define NWFS_MOUNT_NO_OS2 0x0008 -#define NWFS_MOUNT_NO_NFS 0x0010 -#define NWFS_MOUNT_NO_LONG 0x0020 -#define NWFS_MOUNT_GET_SYSENT 0x0040 /* special case, look to vfsops :) */ -#define NWFS_MOUNT_HAVE_NLS 0x0080 - -#define NWFS_VOLNAME_LEN 48 - - -/* Layout of the mount control block for a netware filesystem. */ -struct nwfs_args { - int connRef; /* connection reference */ - char mount_point[MAXPATHLEN]; - u_int flags; - u_char mounted_vol[NWFS_VOLNAME_LEN + 1]; - u_char root_path[512+1]; - int version; - uid_t uid; - gid_t gid; - mode_t file_mode; - mode_t dir_mode; - struct ncp_nlstables nls; - int tz; -}; - -#endif /* !_NWFS_MOUNT_H_ */ diff --git a/sys/fs/nwfs/nwfs_node.c b/sys/fs/nwfs/nwfs_node.c deleted file mode 100644 index cf6f6d9..0000000 --- a/sys/fs/nwfs/nwfs_node.c +++ /dev/null @@ -1,379 +0,0 @@ -/*- - * Copyright (c) 1999, 2000 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/queue.h> -#include <sys/sx.h> -#include <sys/sysctl.h> -#include <sys/time.h> -#include <sys/vnode.h> - -#include <vm/vm.h> -#include <vm/vm_extern.h> -#include <vm/vm_page.h> -#include <vm/vm_object.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_subr.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_mount.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -#define NWNOHASH(fhsum) (&nwhashtbl[(fhsum.f_id) & nwnodehash]) - -static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl; -static u_long nwnodehash; -static struct sx nwhashlock; - -static MALLOC_DEFINE(M_NWNODE, "nwfs_node", "NWFS vnode private part"); -static MALLOC_DEFINE(M_NWFSHASH, "nwfs_hash", "NWFS has table"); - -static int nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS); - -SYSCTL_DECL(_vfs_nwfs); - -SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE, - NULL, 0, nwfs_sysctl_vnprint, "S,vnlist", "vnode hash"); - -void -nwfs_hash_init(void) { - nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash); - sx_init(&nwhashlock, "nwfshl"); -} - -void -nwfs_hash_free(void) { - sx_destroy(&nwhashlock); - free(nwhashtbl, M_NWFSHASH); -} - -int -nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS) { - struct nwnode *np; - struct nwnode_hash_head *nhpp; - struct vnode *vp; - int i; - - if (nwfs_debuglevel == 0) - return 0; - printf("Name:uc:hc:fid:pfid\n"); - for(i = 0; i <= nwnodehash; i++) { - nhpp = &nwhashtbl[i]; - LIST_FOREACH(np, nhpp, n_hash) { - vp = NWTOV(np); - vprint("", vp); - printf("%s:%d:%d:%d:%d\n",np->n_name,vrefcnt(vp), - vp->v_holdcnt,np->n_fid.f_id, np->n_fid.f_parent); - } - } - return 0; -} - -/* - * Search nwnode with given fid. - * Hash list should be locked by caller. - */ -static int -nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp) -{ - struct nwnode *np; - struct nwnode_hash_head *nhpp; - - sx_assert(&nwhashlock, SA_XLOCKED); - - nhpp = NWNOHASH(fid); - LIST_FOREACH(np, nhpp, n_hash) { - if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid)) - continue; - if (npp) - *npp = np; - return 0; - } - return ENOENT; -} - -/* - * Allocate new nwfsnode/vnode from given nwnode. - * Vnode referenced and not locked. - */ -static int -nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap, - struct vnode *dvp, struct vnode **vpp) -{ - struct nwnode *np; - struct nwnode_hash_head *nhpp; - struct nwmount *nmp = VFSTONWFS(mp); - struct vnode *vp; - int error; - -loop: - sx_xlock(&nwhashlock); -rescan: - if (nwfs_hashlookup(nmp, fid, &np) == 0) { - vp = NWTOV(np); - VI_LOCK(vp); - sx_xunlock(&nwhashlock); - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread)) - goto loop; - if (fap) - np->n_attr = fap->attributes; - *vpp = vp; - return(0); - } - sx_xunlock(&nwhashlock); - - if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL)) - panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp); - /* - * Do the MALLOC before the getnewvnode since doing so afterward - * might cause a bogus v_data pointer to get dereferenced - * elsewhere if MALLOC should block. - */ - np = malloc(sizeof *np, M_NWNODE, M_WAITOK | M_ZERO); - error = getnewvnode("nwfs", mp, &nwfs_vnodeops, &vp); - if (error) { - *vpp = NULL; - free(np, M_NWNODE); - return (error); - } - error = insmntque(vp, mp); /* XXX: Too early for mpsafe fs */ - if (error != 0) { - free(np, M_NWNODE); - *vpp = NULL; - return (error); - } - vp->v_data = np; - np->n_vnode = vp; - np->n_mount = nmp; - np->n_attr = fap->attributes; - vp->v_type = np->n_attr & aDIR ? VDIR : VREG; - np->n_fid = fid; - if (dvp) { - np->n_parent = VTONW(dvp)->n_fid; - } - sx_xlock(&nwhashlock); - /* - * Another process can create vnode while we blocked in malloc() or - * getnewvnode(). Rescan list again. - */ - if (nwfs_hashlookup(nmp, fid, NULL) == 0) { - vp->v_data = NULL; - np->n_vnode = NULL; - vrele(vp); - free(np, M_NWNODE); - goto rescan; - } - *vpp = vp; - nhpp = NWNOHASH(fid); - LIST_INSERT_HEAD(nhpp, np, n_hash); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - VN_LOCK_AREC(vp); - sx_xunlock(&nwhashlock); - - ASSERT_VOP_LOCKED(dvp, "nwfs_allocvp"); - if (vp->v_type == VDIR && dvp && (dvp->v_vflag & VV_ROOT) == 0) { - np->n_flag |= NREFPARENT; - vref(dvp); - } - return 0; -} - -int -nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap, - struct vnode *dvp, struct vnode **vpp) -{ - struct vnode *vp; - int error; - - *vpp = NULL; - error = nwfs_allocvp(mp, fid, fap, dvp, &vp); - if (error) - return error; - if (fap) - nwfs_attr_cacheenter(vp, fap); - *vpp = vp; - return 0; -} - -int -nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct thread *td, - struct nwnode **npp) -{ - int error; - - sx_xlock(&nwhashlock); - error = nwfs_hashlookup(nmp, fid, npp); - sx_xunlock(&nwhashlock); - return error; -} - -/* - * Free nwnode, and give vnode back to system - */ -int -nwfs_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap; -{ - struct vnode *dvp = NULL, *vp = ap->a_vp; - struct nwnode *dnp, *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - struct thread *td = ap->a_td; - - NCPVNDEBUG("%s,%d\n", np->n_name, vrefcnt(vp)); - /* - * Destroy the vm object and flush associated pages. - */ - vnode_destroy_vobject(vp); - - if (np->n_flag & NREFPARENT) { - np->n_flag &= ~NREFPARENT; - if (nwfs_lookupnp(nmp, np->n_parent, td, &dnp) == 0) { - dvp = dnp->n_vnode; - } else { - NCPVNDEBUG("%s: has no parent ?\n",np->n_name); - } - } - sx_xlock(&nwhashlock); - LIST_REMOVE(np, n_hash); - sx_xunlock(&nwhashlock); - if (nmp->n_root == np) { - nmp->n_root = NULL; - } - vp->v_data = NULL; - free(np, M_NWNODE); - if (dvp) { - vrele(dvp); - } - return (0); -} - -int -nwfs_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap; -{ - struct thread *td = ap->a_td; - struct ucred *cred = td->td_ucred; - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - int error; - - NCPVNDEBUG("%s: %d\n", VTONW(vp)->n_name, vrefcnt(vp)); - if (np->opened) { - error = nwfs_vinvalbuf(vp, td); - error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, td, cred); - np->opened = 0; - } - if (np->n_flag & NSHOULDFREE) { - cache_purge(vp); - vgone(vp); - } - return (0); -} -/* - * routines to maintain vnode attributes cache - * nwfs_attr_cacheenter: unpack np.i to va structure - */ -void -nwfs_attr_cacheenter(struct vnode *vp, struct nw_entry_info *fi) -{ - struct nwnode *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - struct vattr *va = &np->n_vattr; - - va->va_type = vp->v_type; /* vnode type (for create) */ - np->n_nmlen = fi->nameLen; - bcopy(fi->entryName, np->n_name, np->n_nmlen); - np->n_name[fi->nameLen] = 0; - if (vp->v_type == VREG) { - if (va->va_size != fi->dataStreamSize) { - va->va_size = fi->dataStreamSize; - vnode_pager_setsize(vp, va->va_size); - } - va->va_mode = nmp->m.file_mode; /* files access mode and type */ - } else if (vp->v_type == VDIR) { - va->va_size = 16384; /* should be a better way ... */ - va->va_mode = nmp->m.dir_mode; /* files access mode and type */ - } else - return; - np->n_size = va->va_size; - va->va_nlink = 1; /* number of references to file */ - va->va_uid = nmp->m.uid; /* owner user id */ - va->va_gid = nmp->m.gid; /* owner group id */ - va->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; - va->va_fileid = np->n_fid.f_id; /* file id */ - if (va->va_fileid == 0) - va->va_fileid = NWFS_ROOT_INO; - va->va_blocksize=nmp->connh->nh_conn->buffer_size;/* blocksize preferred for i/o */ - /* time of last modification */ - ncp_dos2unixtime(fi->modifyDate, fi->modifyTime, 0, nmp->m.tz, &va->va_mtime); - /* time of last access */ - ncp_dos2unixtime(fi->lastAccessDate, 0, 0, nmp->m.tz, &va->va_atime); - va->va_ctime = va->va_mtime; /* time file changed */ - va->va_gen = VNOVAL; /* generation number of file */ - va->va_flags = 0; /* flags defined for file */ - va->va_rdev = VNOVAL; /* device the special file represents */ - va->va_bytes = va->va_size; /* bytes of disk space held by file */ - va->va_filerev = 0; /* file modification number */ - va->va_vaflags = 0; /* operations flags */ - np->n_vattr = *va; - if (np->n_mtime == 0) { - np->n_mtime = va->va_mtime.tv_sec; - } - np->n_atime = time_second; - np->n_dosfid = fi->DosDirNum; - return; -} - -int -nwfs_attr_cachelookup(struct vnode *vp, struct vattr *va) -{ - struct nwnode *np = VTONW(vp); - int diff; - - diff = time_second - np->n_atime; - if (diff > 2) { /* XXX should be configurable */ - return ENOENT; - } - *va = np->n_vattr; - return 0; -} diff --git a/sys/fs/nwfs/nwfs_node.h b/sys/fs/nwfs/nwfs_node.h deleted file mode 100644 index 89545eb..0000000 --- a/sys/fs/nwfs/nwfs_node.h +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _NWFS_NODE_H_ -#define _NWFS_NODE_H_ - -#define NWFS_ROOT_INO 0x7ffffffd - -/* Bits for nwnode.n_flag */ -#define NFLUSHINPROG 0x0001 -#define NFLUSHWANT 0x0002 /* they should gone ... */ -#define NMODIFIED 0x0004 /* bogus, until async IO implemented */ -#define NREFPARENT 0x0008 /* vnode holds reference to a parent vnode */ -#define NVOLUME 0x0010 /* vnode references a volume */ -#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */ - -struct nwnode { - LIST_ENTRY(nwnode) n_hash; - struct vnode *n_vnode; - struct vattr n_vattr; - struct nwmount *n_mount; - time_t n_atime; /* attributes cache time*/ - time_t n_ctime; - time_t n_mtime; - int n_flag; - ncpfid n_parent; - ncpfid n_fid; - u_long n_attr; /* LH */ - u_long n_size; - u_long n_dosfid; - int opened; -/* int access;*/ - u_long n_origfh; - ncp_fh n_fh; - struct nw_search_seq n_seq; - u_char n_nmlen; - u_char n_name[256]; -}; - -#define VTONW(vp) ((struct nwnode *)(vp)->v_data) -#define NWTOV(np) ((struct vnode *)(np)->n_vnode) -#define NWCMPF(f1,f2) ((f1)->f_parent == (f2)->f_parent && \ - (f1)->f_id == (f2)->f_id) -#define NWCMPN(np1,np2) NWCMPF(&(np1)->n_fid, &(np2)->n_fid) -#define NWCMPV(vp1,vp2) NWCMPN(VTONW(vp1),VTONW(vp2)) - -struct vop_getpages_args; -struct vop_inactive_args; -struct vop_putpages_args; -struct vop_reclaim_args; -struct ucred; -struct uio; - -void nwfs_hash_init(void); -void nwfs_hash_free(void); -int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct thread *td, - struct nwnode **npp); -int nwfs_inactive(struct vop_inactive_args *); -int nwfs_reclaim(struct vop_reclaim_args *); -int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap, - struct vnode *dvp, struct vnode **vpp); - -int nwfs_getpages(struct vop_getpages_args *); -int nwfs_putpages(struct vop_putpages_args *); -int nwfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred); -int nwfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int ioflag); -void nwfs_attr_cacheenter(struct vnode *vp, struct nw_entry_info *fi); -int nwfs_attr_cachelookup(struct vnode *vp,struct vattr *va); - -#define nwfs_attr_cacheremove(vp) VTONW(vp)->n_atime = 0 - -#endif /* _NWFS_NODE_H_ */ diff --git a/sys/fs/nwfs/nwfs_subr.c b/sys/fs/nwfs/nwfs_subr.c deleted file mode 100644 index cb85450..0000000 --- a/sys/fs/nwfs/nwfs_subr.c +++ /dev/null @@ -1,553 +0,0 @@ -/*- - * Copyright (c) 1999, 2001 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/lockmgr.h> -#include <sys/malloc.h> -#include <sys/clock.h> -#include <sys/time.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_ncp.h> -#include <netncp/ncp_subr.h> -#include <netncp/ncp_rq.h> -#include <netncp/nwerror.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -#define NCP_INFOSZ (sizeof(struct nw_entry_info) - 257) - -MALLOC_DEFINE(M_NWFSDATA, "nwfs_data", "NWFS private data"); - -static int -ncp_extract_file_info(struct nwmount *nmp, struct ncp_rq *rqp, - struct nw_entry_info *target, int withname) -{ - u_int8_t name_len; - - md_get_mem(&rqp->rp, (caddr_t)target, NCP_INFOSZ, MB_MSYSTEM); - if (!withname) - return 0; - md_get_uint8(&rqp->rp, &name_len); - target->nameLen = name_len; - md_get_mem(&rqp->rp, (caddr_t)target->entryName, name_len, MB_MSYSTEM); - target->entryName[name_len] = '\0'; - ncp_path2unix(target->entryName, target->entryName, name_len, &nmp->m.nls); - return 0; -} - -int -ncp_initsearch(struct vnode *dvp, struct thread *td, struct ucred *cred) -{ - struct nwmount *nmp = VTONWFS(dvp); - struct ncp_conn *conn = NWFSTOCONN(nmp); - struct nwnode *np = VTONW(dvp); - struct ncp_rq *rqp; - u_int8_t volnum = nmp->n_volume; - u_int32_t dirent = np->n_fid.f_id; - int error; - - NCPNDEBUG("vol=%d,dir=%d\n", volnum, dirent); - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 2); /* subfunction */ - mb_put_uint8(&rqp->rq, nmp->name_space); - mb_put_uint8(&rqp->rq, 0); /* reserved */ - ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL); - rqp->nr_minrplen = sizeof(np->n_seq); - error = ncp_request(rqp); - if (error) - return error; - md_get_mem(&rqp->rp, (caddr_t)&np->n_seq, sizeof(np->n_seq), MB_MSYSTEM); - ncp_rq_done(rqp); - return 0; -} - -int -ncp_search_for_file_or_subdir(struct nwmount *nmp, - struct nw_search_seq *seq, - struct nw_entry_info *target, - struct thread *td,struct ucred *cred) -{ - struct ncp_conn *conn = NWFSTOCONN(nmp); - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 3); /* subfunction */ - mb_put_uint8(&rqp->rq, nmp->name_space); - mb_put_uint8(&rqp->rq, 0); /* data stream */ - mb_put_uint16le(&rqp->rq, 0xffff); /* Search attribs */ - mb_put_uint32le(&rqp->rq, IM_ALL); /* return info mask */ - mb_put_mem(&rqp->rq, (caddr_t)seq, 9, MB_MSYSTEM); - mb_put_uint8(&rqp->rq, 2); /* 2 byte pattern */ - mb_put_uint8(&rqp->rq, 0xff); /* following is a wildcard */ - mb_put_uint8(&rqp->rq, '*'); - rqp->nr_minrplen = sizeof(*seq) + 1 + NCP_INFOSZ + 1; - error = ncp_request(rqp); - if (error) - return error; - md_get_mem(&rqp->rp, (caddr_t)seq, sizeof(*seq), MB_MSYSTEM); - md_get_uint8(&rqp->rp, NULL); /* skip */ - error = ncp_extract_file_info(nmp, rqp, target, 1); - ncp_rq_done(rqp); - return error; -} - -/* - * Returns information for a (one-component) name relative to the specified - * directory. - */ -int -ncp_obtain_info(struct nwmount *nmp, u_int32_t dirent, - int namelen, char *path, struct nw_entry_info *target, - struct thread *td,struct ucred *cred) -{ - struct ncp_conn *conn=NWFSTOCONN(nmp); - struct ncp_rq *rqp; - int error; - u_char volnum = nmp->n_volume, ns; - - if (target == NULL) { - NCPFATAL("target == NULL\n"); - return EINVAL; - } - ns = (path == NULL || path[0] == 0) ? NW_NS_DOS : nmp->name_space; - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 6); /* subfunction */ - mb_put_uint8(&rqp->rq, ns); - mb_put_uint8(&rqp->rq, ns); /* DestNameSpace */ - mb_put_uint16le(&rqp->rq, 0xff); /* get all */ - mb_put_uint32le(&rqp->rq, IM_ALL); - ncp_rq_dbase_path(rqp, volnum, dirent, namelen, path, &nmp->m.nls); - error = ncp_request(rqp); - if (error) - return error; - error = ncp_extract_file_info(nmp, rqp, target, path != NULL); - ncp_rq_done(rqp); - return error; -} -/* - * lookup name pointed by cnp in directory dvp and return file info in np. - * May be I should create a little cache, but another way is to minimize - * number of calls, on other hand, in multiprocess environment ... - */ -int -ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap, - struct thread *td,struct ucred *cred) -{ - struct nwmount *nmp; - struct nwnode *dnp; - int error; - - if (!dvp || dvp->v_type != VDIR) { - nwfs_printf("dvp is NULL or not a directory.\n"); - return (ENOENT); - } - dnp = VTONW(dvp); - nmp = VTONWFS(dvp); - - if (len == 1 && name[0] == '.') { - if (dnp->n_flag & NVOLUME) { - error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL, - fap, td, cred); - } else { - error = ncp_obtain_info(nmp, dnp->n_fid.f_parent, - dnp->n_nmlen, dnp->n_name, fap, td, cred); - } - return error; - } else if (len == 2 && name[0] == '.' && name[1] == '.') { - printf("%s: knows NOTHING about '..'\n", __func__); - return EIO; - } else { - error = ncp_obtain_info(nmp, dnp->n_fid.f_id, - len, name, fap, td, cred); - } - return error; -} - -static void ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh); -static void -ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh) { - fh->val1 = (fh->val.val32 = sfd); - return; -} - -/* - * If both dir and name are NULL, then in target there's already a looked-up - * entry that wants to be opened. - */ -int -ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp,int namelen, - char *name, int open_create_mode, u_int32_t create_attributes, - int desired_acc_rights, struct ncp_open_info *nop, - struct thread *td,struct ucred *cred) -{ - - struct ncp_conn *conn=NWFSTOCONN(nmp); - struct ncp_rq *rqp; - u_int16_t search_attribs = SA_ALL & (~SA_SUBDIR_FILES); - u_int8_t volnum; - u_int32_t dirent; - int error; - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - volnum = nmp->n_volume; - dirent = VTONW(dvp)->n_fid.f_id; - if ((create_attributes & aDIR) != 0) { - search_attribs |= SA_SUBDIR_FILES; - } - mb_put_uint8(&rqp->rq, 1);/* subfunction */ - mb_put_uint8(&rqp->rq, nmp->name_space); - mb_put_uint8(&rqp->rq, open_create_mode); - mb_put_uint16le(&rqp->rq, search_attribs); - mb_put_uint32le(&rqp->rq, IM_ALL); - mb_put_uint32le(&rqp->rq, create_attributes); - /* - * The desired acc rights seem to be the inherited rights mask for - * directories - */ - mb_put_uint16le(&rqp->rq, desired_acc_rights); - ncp_rq_dbase_path(rqp, volnum, dirent, namelen, name, &nmp->m.nls); - error = ncp_request(rqp); - if (error) { - if (error == NWE_FILE_NO_CREATE_PRIV) - error = EACCES; - return error; - } - md_get_uint32le(&rqp->rp, &nop->origfh); - md_get_uint8(&rqp->rp, &nop->action); - md_get_uint8(&rqp->rp, NULL); /* skip */ - error = ncp_extract_file_info(nmp, rqp, &nop->fattr, 1); - ncp_rq_done(rqp); - ConvertToNWfromDWORD(nop->origfh, &nop->fh); - return error; -} - -int -ncp_close_file(struct ncp_conn *conn, ncp_fh *fh,struct thread *td,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(66, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 0); - mb_put_mem(&rqp->rq, (caddr_t)fh, 6, MB_MSYSTEM); - error = ncp_request(rqp); - if (error) - return error; - ncp_rq_done(rqp); - return error; -} - -int -ncp_DeleteNSEntry(struct nwmount *nmp, u_int32_t dirent, - int namelen,char *name,struct thread *td,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - struct ncp_conn *conn=NWFSTOCONN(nmp); - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 8); /* subfunction */ - mb_put_uint8(&rqp->rq, nmp->name_space); - mb_put_uint8(&rqp->rq, 0); /* reserved */ - mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */ - ncp_rq_dbase_path(rqp, nmp->n_volume, dirent, namelen, name, &nmp->m.nls); - error = ncp_request(rqp); - if (!error) - ncp_rq_done(rqp); - return error; -} - -int -ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype, - struct ncp_nlstables *nt, - nwdirent fdir, char *old_name, int oldlen, - nwdirent tdir, char *new_name, int newlen, - struct thread *td, struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 4); - mb_put_uint8(&rqp->rq, ns); - mb_put_uint8(&rqp->rq, 1); /* RRenameToMySelf */ - mb_put_uint16le(&rqp->rq, oldtype); - /* source Handle Path */ - mb_put_uint8(&rqp->rq, volume); - mb_put_mem(&rqp->rq, (c_caddr_t)&fdir, sizeof(fdir), MB_MSYSTEM); - mb_put_uint8(&rqp->rq, 1); - mb_put_uint8(&rqp->rq, 1); /* 1 source component */ - /* dest Handle Path */ - mb_put_uint8(&rqp->rq, volume); - mb_put_mem(&rqp->rq, (c_caddr_t)&tdir, sizeof(tdir), MB_MSYSTEM); - mb_put_uint8(&rqp->rq, 1); - mb_put_uint8(&rqp->rq, 1); /* 1 destination component */ - ncp_rq_pathstring(rqp, oldlen, old_name, nt); - ncp_rq_pathstring(rqp, newlen, new_name, nt); - error = ncp_request(rqp); - if (!error) - ncp_rq_done(rqp); - return error; -} - -int -ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp, - u_int32_t info_mask, - struct nw_modify_dos_info *info, - struct thread *td,struct ucred *cred) -{ - struct nwnode *np=VTONW(vp); - struct ncp_rq *rqp; - u_int8_t volnum = nmp->n_volume; - u_int32_t dirent = np->n_fid.f_id; - struct ncp_conn *conn=NWFSTOCONN(nmp); - int error; - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 7); /* subfunction */ - mb_put_uint8(&rqp->rq, nmp->name_space); - mb_put_uint8(&rqp->rq, 0); /* reserved */ - mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */ - mb_put_uint32le(&rqp->rq, info_mask); - mb_put_mem(&rqp->rq, (caddr_t)info, sizeof(*info), MB_MSYSTEM); - ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL); - error = ncp_request(rqp); - if (!error) - ncp_rq_done(rqp); - return error; -} - -int -ncp_setattr(vp, vap, cred, td) - struct vnode *vp; - struct vattr *vap; - struct ucred *cred; - struct thread *td; -{ - struct nwmount *nmp=VTONWFS(vp); - struct nwnode *np=VTONW(vp); - struct ncp_open_info nwn; - struct ncp_conn *conn=NWFSTOCONN(nmp); - struct nw_modify_dos_info info; - struct ncp_rq *rqp; - int error = 0, info_mask; - - if (vap->va_size != VNOVAL) { - error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0, - AR_WRITE | AR_READ, &nwn,td,cred); - if (error) - return error; - error = ncp_rq_alloc(73, conn, td, cred, &rqp); - if (error) { - ncp_close_file(conn, &nwn.fh, td, cred); - return error; - } - mb_put_uint8(&rqp->rq, 0); - mb_put_mem(&rqp->rq, (caddr_t)&nwn.fh, 6, MB_MSYSTEM); - mb_put_uint32be(&rqp->rq, vap->va_size); - mb_put_uint16be(&rqp->rq, 0); - error = ncp_request(rqp); - np->n_vattr.va_size = np->n_size = vap->va_size; - if (!error) - ncp_rq_done(rqp); - ncp_close_file(conn, &nwn.fh, td, cred); - if (error) - return error; - } - info_mask = 0; - bzero(&info, sizeof(info)); - - if (vap->va_mtime.tv_sec != VNOVAL) { - info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE); - ncp_unix2dostime(&vap->va_mtime, nmp->m.tz, &info.modifyDate, &info.modifyTime, NULL); - } - if (vap->va_atime.tv_sec != VNOVAL) { - info_mask |= (DM_LAST_ACCESS_DATE); - ncp_unix2dostime(&vap->va_atime, nmp->m.tz, &info.lastAccessDate, NULL, NULL); - } - if (info_mask) { - error = ncp_modify_file_or_subdir_dos_info(nmp, vp, info_mask, &info,td,cred); - } - return (error); -} - -int -ncp_get_volume_info_with_number(struct ncp_conn *conn, - int n, struct ncp_volume_info *target, - struct thread *td,struct ucred *cred) -{ - struct ncp_rq *rqp; - u_int32_t tmp32; - u_int8_t len; - int error; - - error = ncp_rq_alloc_subfn(22, 44, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq,n); - error = ncp_request(rqp); - if (error) - return error; - md_get_uint32le(&rqp->rp, &target->total_blocks); - md_get_uint32le(&rqp->rp, &target->free_blocks); - md_get_uint32le(&rqp->rp, &target->purgeable_blocks); - md_get_uint32le(&rqp->rp, &target->not_yet_purgeable_blocks); - md_get_uint32le(&rqp->rp, &target->total_dir_entries); - md_get_uint32le(&rqp->rp, &target->available_dir_entries); - md_get_uint32le(&rqp->rp, &tmp32); - md_get_uint8(&rqp->rp, &target->sectors_per_block); - bzero(&target->volume_name, sizeof(target->volume_name)); - md_get_uint8(&rqp->rp, &len); - if (len > NCP_VOLNAME_LEN) { - error = ENAMETOOLONG; - } else { - md_get_mem(&rqp->rp, (caddr_t)&target->volume_name, len, MB_MSYSTEM); - } - ncp_rq_done(rqp); - return error; -} - -int -ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf, - struct thread *td,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - u_int8_t ns; - u_int16_t nscnt; - - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 24); /* Subfunction: Get Loaded Name Spaces */ - mb_put_uint16le(&rqp->rq, 0); /* reserved */ - mb_put_uint8(&rqp->rq, volume); - error = ncp_request(rqp); - if (error) - return error; - md_get_uint16le(&rqp->rp, &nscnt); - *nsf = 0; - while (nscnt-- > 0) { - md_get_uint8(&rqp->rp, &ns); - *nsf |= 1 << ns; - } - ncp_rq_done(rqp); - return error; -} - -int -ncp_lookup_volume(struct ncp_conn *conn, char *volname, - u_char *volNum, u_int32_t *dirEnt, - struct thread *td,struct ucred *cred) -{ - struct ncp_rq *rqp; - u_int32_t tmp32; - int error; - - NCPNDEBUG("looking up vol %s\n", volname); - error = ncp_rq_alloc(87, conn, td, cred, &rqp); - if (error) - return error; - mb_put_uint8(&rqp->rq, 22); /* Subfunction: Generate dir handle */ - mb_put_uint8(&rqp->rq, 0); /* src name space */ - mb_put_uint8(&rqp->rq, 0); /* dst name space, always zero */ - mb_put_uint16le(&rqp->rq, 0); /* dstNSIndicator (Jn) */ - - mb_put_uint8(&rqp->rq, 0); /* faked volume number */ - mb_put_uint32be(&rqp->rq, 0); /* faked dir_base */ - mb_put_uint8(&rqp->rq, 0xff); /* Don't have a dir_base */ - mb_put_uint8(&rqp->rq, 1); /* 1 path component */ - ncp_rq_pstring(rqp, volname); - error = ncp_request(rqp); - if (error) - return error; - md_get_uint32le(&rqp->rp, &tmp32); - md_get_uint32le(&rqp->rp, dirEnt); - md_get_uint8(&rqp->rp, volNum); - ncp_rq_done(rqp); - return error; -} - -/* - * XXX: I think the timezone in struct nwfs_args is truly bogus, especially - * XXX: considering that nwfs_mount(8) picks this up from the kernel in - * XXX: the first place. Since I can't test this, I won't attempt to fix it. - * XXX: /phk - */ - -void -ncp_unix2dostime(tsp, tzoff, ddp, dtp, dhp) - struct timespec *tsp; - int tzoff; - u_int16_t *ddp; - u_int16_t *dtp; - u_int8_t *dhp; -{ - struct timespec t; - - t = *tsp; - - t.tv_sec = - tzoff * 60 - utc_offset(); - timespec2fattime(&t, 1, ddp, dtp, dhp); -} - -void -ncp_dos2unixtime(dd, dt, dh, tzoff, tsp) - u_int dd; - u_int dt; - u_int dh; - int tzoff; - struct timespec *tsp; -{ - - fattime2timespec(dd, dt, dh, 1, tsp); - tsp->tv_sec += tzoff * 60 + utc_offset(); -} diff --git a/sys/fs/nwfs/nwfs_subr.h b/sys/fs/nwfs/nwfs_subr.h deleted file mode 100644 index e571349..0000000 --- a/sys/fs/nwfs/nwfs_subr.h +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * Copyright (c) 1999 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#ifndef _NWFS_SUBR_H_ -#define _NWFS_SUBR_H_ - -extern int nwfs_debuglevel; - -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_NWFSDATA); -#endif - -struct ncp_conn; -struct ncp_nlstables; -struct ncp_open_info; -struct nw_entry_info; -struct nw_search_info; -struct nwmount; -struct thread; -struct timespec; -struct ucred; -struct vattr; -struct vnode; - -int ncp_initsearch(struct vnode *dvp,struct thread *td, struct ucred *cred); -int ncp_search_for_file_or_subdir(struct nwmount *nmp,struct nw_search_seq *seq, - struct nw_entry_info *target, - struct thread *td, struct ucred *cred); -int ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap, - struct thread *td, struct ucred *cred); -int ncp_lookup_volume(struct ncp_conn *conn, char *volname, - u_char *volNum, u_int32_t *dirEnt, - struct thread *td, struct ucred *cred); -int ncp_close_file(struct ncp_conn *conn, ncp_fh *fh, - struct thread *td, struct ucred *cred); -int ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp, int namelen,char *name, - int open_create_mode, u_int32_t create_attributes, - int desired_acc_rights, struct ncp_open_info *nop, - struct thread *td, struct ucred *cred); -int ncp_DeleteNSEntry(struct nwmount *nmp, - u_int32_t dirent, int namelen, char *name, - struct thread *td, struct ucred *cred); -int ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype, - struct ncp_nlstables *nt, - nwdirent fdir, char *old_name, int oldlen, - nwdirent tdir, char *new_name, int newlen, - struct thread *td, struct ucred *cred); -int ncp_obtain_info(struct nwmount *nmp, u_int32_t dirent, - int namelen, char *path, struct nw_entry_info *target, - struct thread *td, struct ucred *cred); -int ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp, - u_int32_t info_mask, - struct nw_modify_dos_info *info, - struct thread *td, struct ucred *cred); -int ncp_setattr(struct vnode *,struct vattr *,struct ucred *,struct thread *td); -int ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf, - struct thread *td, struct ucred *cred); -int ncp_get_volume_info_with_number(struct ncp_conn *conn, - int n, struct ncp_volume_info *target, - struct thread *td, struct ucred *cred); - -void ncp_unix2dostime (struct timespec *tsp, int tz, u_int16_t *ddp, - u_int16_t *dtp, u_int8_t *dhp); -void ncp_dos2unixtime (u_int dd, u_int dt, u_int dh, int tz, struct timespec *tsp); - -#endif /* !_NWFS_SUBR_H_ */ diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c deleted file mode 100644 index f319fb5..0000000 --- a/sys/fs/nwfs/nwfs_vfsops.c +++ /dev/null @@ -1,439 +0,0 @@ -/*- - * Copyright (c) 1999, 2000 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/kernel.h> -#include <sys/sysctl.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/malloc.h> -#include <sys/bio.h> -#include <sys/buf.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_subr.h> -#include <netncp/ncp_ncp.h> -#include <netncp/ncp_nls.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -int nwfs_debuglevel = 0; - -static int nwfs_version = NWFS_VERSION; - -SYSCTL_DECL(_vfs_nwfs); -SYSCTL_NODE(_vfs, OID_AUTO, nwfs, CTLFLAG_RW, 0, "Netware filesystem"); -SYSCTL_INT(_vfs_nwfs, OID_AUTO, version, CTLFLAG_RD, &nwfs_version, 0, ""); -SYSCTL_INT(_vfs_nwfs, OID_AUTO, debuglevel, CTLFLAG_RW, &nwfs_debuglevel, 0, ""); - -MODULE_DEPEND(nwfs, ncp, 1, 1, 1); -MODULE_DEPEND(nwfs, libmchain, 1, 1, 1); - -static vfs_cmount_t nwfs_cmount; -static vfs_mount_t nwfs_mount; -static vfs_quotactl_t nwfs_quotactl; -static vfs_root_t nwfs_root; -static vfs_statfs_t nwfs_statfs; -static vfs_unmount_t nwfs_unmount; -static vfs_init_t nwfs_init; -static vfs_uninit_t nwfs_uninit; - -static struct vfsops nwfs_vfsops = { - .vfs_init = nwfs_init, - .vfs_mount = nwfs_mount, - .vfs_cmount = nwfs_cmount, - .vfs_quotactl = nwfs_quotactl, - .vfs_root = nwfs_root, - .vfs_statfs = nwfs_statfs, - .vfs_sync = vfs_stdsync, - .vfs_uninit = nwfs_uninit, - .vfs_unmount = nwfs_unmount, -}; - - -VFS_SET(nwfs_vfsops, nwfs, VFCF_NETWORK); - -int nwfs_pbuf_freecnt = -1; /* start out unlimited */ -static int nwfsid = 1; - -static int -nwfs_initnls(struct nwmount *nmp) { - char *pc, *pe; - int error = 0; -#define COPY_TABLE(t,d) { \ - if (t) { \ - error = copyin((t), pc, 256); \ - if (error) break; \ - } else \ - bcopy(d, pc, 256); \ - (t) = pc; pc += 256; \ - } - - nmp->m.nls.opt |= NWHP_NLS | NWHP_DOS; - if ((nmp->m.flags & NWFS_MOUNT_HAVE_NLS) == 0) { - nmp->m.nls.to_lower = ncp_defnls.to_lower; - nmp->m.nls.to_upper = ncp_defnls.to_upper; - nmp->m.nls.n2u = ncp_defnls.n2u; - nmp->m.nls.u2n = ncp_defnls.u2n; - return 0; - } - pe = malloc(256 * 4, M_NWFSDATA, M_WAITOK); - pc = pe; - do { - COPY_TABLE(nmp->m.nls.to_lower, ncp_defnls.to_lower); - COPY_TABLE(nmp->m.nls.to_upper, ncp_defnls.to_upper); - COPY_TABLE(nmp->m.nls.n2u, ncp_defnls.n2u); - COPY_TABLE(nmp->m.nls.u2n, ncp_defnls.u2n); - } while(0); - if (error) { - free(pe, M_NWFSDATA); - return error; - } - return 0; -} - -static int nwfs_cmount(struct mntarg *ma, void *data, uint64_t flags) -{ - struct nwfs_args args; /* will hold data from mount request */ - int error; - - error = copyin(data, &args, sizeof(struct nwfs_args)); - if (error) - return (error); - - /* - * XXX: cheap cop-out here, args contains a structure I don't - * XXX: know how we should handle, and I don't see any immediate - * XXX: prospect of avoiding a mount_nwfs(8) binary anyway. - */ - ma = mount_arg(ma, "nwfs_args", &args, sizeof args); - - error = kernel_mount(ma, flags); - - return (error); -} - -/* - * mp - path - addr in user space of mount point (ie /usr or whatever) - * data - addr in user space of mount params - */ -static int nwfs_mount(struct mount *mp) -{ - struct nwfs_args args; /* will hold data from mount request */ - int error; - struct nwmount *nmp = NULL; - struct ncp_conn *conn = NULL; - struct ncp_handle *handle = NULL; - struct vnode *vp; - struct thread *td; - char *pc,*pe; - - td = curthread; - if (mp->mnt_flag & MNT_ROOTFS) - return (EOPNOTSUPP); - if (mp->mnt_flag & MNT_UPDATE) { - nwfs_printf("MNT_UPDATE not implemented"); - return (EOPNOTSUPP); - } - error = vfs_copyopt(mp->mnt_optnew, "nwfs_args", &args, sizeof args); - if (error) - return (error); - if (args.version != NWFS_VERSION) { - nwfs_printf("mount version mismatch: kernel=%d, mount=%d\n",NWFS_VERSION,args.version); - return (1); - } - error = ncp_conn_getbyref(args.connRef, td , td->td_ucred,NCPM_EXECUTE,&conn); - if (error) { - nwfs_printf("invalid connection refernce %d\n",args.connRef); - return (error); - } - error = ncp_conn_gethandle(conn, NULL, &handle); - if (error) { - nwfs_printf("can't get connection handle\n"); - return (error); - } - ncp_conn_unlock(conn, td); /* we keep the ref */ - mp->mnt_stat.f_iosize = conn->buffer_size; - /* We must malloc our own mount info */ - nmp = malloc(sizeof(struct nwmount), M_NWFSDATA, M_WAITOK | M_ZERO); - if (nmp == NULL) { - nwfs_printf("could not alloc nwmount\n"); - error = ENOMEM; - goto bad; - } - mp->mnt_data = nmp; - nmp->connh = handle; - nmp->n_root = NULL; - nmp->n_id = nwfsid++; - nmp->m = args; - nmp->m.file_mode = (nmp->m.file_mode & - (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG; - nmp->m.dir_mode = (nmp->m.dir_mode & - (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR; - if ((error = nwfs_initnls(nmp)) != 0) goto bad; - pc = mp->mnt_stat.f_mntfromname; - pe = pc+sizeof(mp->mnt_stat.f_mntfromname); - bzero(pc, MNAMELEN); - *(pc++) = '/'; - pc = strchr(strncpy(pc, conn->li.server, pe - pc - 2), 0); - if (pc < pe-1) { - *(pc++) = ':'; - pc = strchr(strncpy(pc, conn->li.user, pe - pc - 2), 0); - if (pc < pe-1) { - *(pc++) = '/'; - strncpy(pc, nmp->m.mounted_vol, pe-pc-2); - } - } - /* protect against invalid mount points */ - nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0'; - vfs_getnewfsid(mp); - error = nwfs_root(mp, LK_EXCLUSIVE, &vp); - if (error) - goto bad; - /* - * Lose the lock but keep the ref. - */ - VOP_UNLOCK(vp, 0); - NCPVODEBUG("rootvp.vrefcnt=%d\n",vrefcnt(vp)); - return error; -bad: - if (nmp) - free(nmp, M_NWFSDATA); - if (handle) - ncp_conn_puthandle(handle, NULL, 0); - return error; -} - -/* Unmount the filesystem described by mp. */ -static int -nwfs_unmount(struct mount *mp, int mntflags) -{ - struct thread *td; - struct nwmount *nmp = VFSTONWFS(mp); - struct ncp_conn *conn; - int error, flags; - - NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags); - td = curthread; - flags = 0; - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - /* There is 1 extra root vnode reference from nwfs_mount(). */ - error = vflush(mp, 1, flags, td); - if (error) - return (error); - conn = NWFSTOCONN(nmp); - ncp_conn_puthandle(nmp->connh,NULL,0); - if (ncp_conn_lock(conn, td, td->td_ucred,NCPM_WRITE | NCPM_EXECUTE) == 0) { - if(ncp_conn_free(conn)) - ncp_conn_unlock(conn, td); - } - mp->mnt_data = NULL; - if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS) - free(nmp->m.nls.to_lower, M_NWFSDATA); - free(nmp, M_NWFSDATA); - MNT_ILOCK(mp); - mp->mnt_flag &= ~MNT_LOCAL; - MNT_IUNLOCK(mp); - return (error); -} - -/* Return locked vnode to root of a filesystem */ -static int -nwfs_root(struct mount *mp, int flags, struct vnode **vpp) { - struct vnode *vp; - struct nwmount *nmp; - struct nwnode *np; - struct ncp_conn *conn; - struct nw_entry_info fattr; - struct thread *td; - struct ucred *cred; - int error, nsf, opt; - u_char vol; - - td = curthread; - cred = td->td_ucred; - - nmp = VFSTONWFS(mp); - conn = NWFSTOCONN(nmp); - if (nmp->n_root) { - *vpp = NWTOV(nmp->n_root); - while (vget(*vpp, LK_EXCLUSIVE, curthread) != 0) - ; - return 0; - } - error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol, - &nmp->n_rootent.f_id, td, cred); - if (error) - return ENOENT; - nmp->n_volume = vol; - error = ncp_get_namespaces(conn, vol, &nsf, td, cred); - if (error) - return ENOENT; - if (nsf & NW_NSB_OS2) { - NCPVODEBUG("volume %s has os2 namespace\n",nmp->m.mounted_vol); - if ((nmp->m.flags & NWFS_MOUNT_NO_OS2) == 0) { - nmp->name_space = NW_NS_OS2; - nmp->m.nls.opt &= ~NWHP_DOS; - } - } - opt = nmp->m.nls.opt; - nsf = opt & (NWHP_UPPER | NWHP_LOWER); - if (opt & NWHP_DOS) { - if (nsf == (NWHP_UPPER | NWHP_LOWER)) { - nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); - } else if (nsf == 0) { - nmp->m.nls.opt |= NWHP_LOWER; - } - } else { - if (nsf == (NWHP_UPPER | NWHP_LOWER)) { - nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); - } - } - if (nmp->m.root_path[0]) { - nmp->m.root_path[0]--; - error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, - -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); - if (error) { - NCPFATAL("Invalid root path specified\n"); - return ENOENT; - } - nmp->n_rootent.f_parent = fattr.dirEntNum; - nmp->m.root_path[0]++; - error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, - -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); - if (error) { - NCPFATAL("Invalid root path specified\n"); - return ENOENT; - } - nmp->n_rootent.f_id = fattr.dirEntNum; - } else { - error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, - 0, NULL, &fattr, td, cred); - if (error) { - NCPFATAL("Can't obtain volume info\n"); - return ENOENT; - } - fattr.nameLen = strlen(strcpy(fattr.entryName, "#.ROOT")); - nmp->n_rootent.f_parent = nmp->n_rootent.f_id; - } - error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp); - if (error) - return (error); - vp->v_vflag |= VV_ROOT; - np = VTONW(vp); - if (nmp->m.root_path[0] == 0) - np->n_flag |= NVOLUME; - nmp->n_root = np; -/* error = VOP_GETATTR(vp, &vattr, cred, td); - if (error) { - vput(vp); - NCPFATAL("Can't get root directory entry\n"); - return error; - }*/ - *vpp = vp; - return (0); -} - -/* - * Do operations associated with quotas, not supported - */ -/* ARGSUSED */ -static int -nwfs_quotactl(mp, cmd, uid, arg) - struct mount *mp; - int cmd; - uid_t uid; - void *arg; -{ - NCPVODEBUG("return EOPNOTSUPP\n"); - return (EOPNOTSUPP); -} - -/*ARGSUSED*/ -int -nwfs_init(struct vfsconf *vfsp) -{ - nwfs_hash_init(); - nwfs_pbuf_freecnt = nswbuf / 2 + 1; - NCPVODEBUG("always happy to load!\n"); - return (0); -} - -/*ARGSUSED*/ -int -nwfs_uninit(struct vfsconf *vfsp) -{ - - nwfs_hash_free(); - NCPVODEBUG("unloaded\n"); - return (0); -} - -/* - * nwfs_statfs call - */ -int -nwfs_statfs(mp, sbp) - struct mount *mp; - struct statfs *sbp; -{ - struct nwmount *nmp = VFSTONWFS(mp); - struct thread *td = curthread; - int error = 0, secsize; - struct nwnode *np = nmp->n_root; - struct ncp_volume_info vi; - - if (np == NULL) return EINVAL; - error = ncp_get_volume_info_with_number(NWFSTOCONN(nmp), - nmp->n_volume, &vi, td, td->td_ucred); - if (error) return error; - secsize = 512; /* XXX how to get real value ??? */ - /* fundamental filesystem block size */ - sbp->f_bsize = vi.sectors_per_block*secsize; - /* optimal transfer block size */ - sbp->f_iosize = NWFSTOCONN(nmp)->buffer_size; - /* total data blocks in filesystem */ - sbp->f_blocks= vi.total_blocks; - /* free blocks in fs */ - sbp->f_bfree = vi.free_blocks + vi.purgeable_blocks; - /* free blocks avail to non-superuser */ - sbp->f_bavail= vi.free_blocks+vi.purgeable_blocks; - /* total file nodes in filesystem */ - sbp->f_files = vi.total_dir_entries; - /* free file nodes in fs */ - sbp->f_ffree = vi.available_dir_entries; - sbp->f_flags = 0; /* copy of mount exported flags */ - return 0; -} diff --git a/sys/fs/nwfs/nwfs_vnops.c b/sys/fs/nwfs/nwfs_vnops.c deleted file mode 100644 index b3f26e8..0000000 --- a/sys/fs/nwfs/nwfs_vnops.c +++ /dev/null @@ -1,967 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001 Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/namei.h> -#include <sys/kernel.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/fcntl.h> -#include <sys/mount.h> -#include <sys/unistd.h> -#include <sys/vnode.h> - -#include <vm/vm.h> -#include <vm/vm_extern.h> - -#include <netncp/ncp.h> -#include <netncp/ncp_conn.h> -#include <netncp/ncp_subr.h> -#include <netncp/nwerror.h> -#include <netncp/ncp_nls.h> - -#include <fs/nwfs/nwfs.h> -#include <fs/nwfs/nwfs_node.h> -#include <fs/nwfs/nwfs_subr.h> - -/* - * Prototypes for NWFS vnode operations - */ -static vop_create_t nwfs_create; -static vop_mknod_t nwfs_mknod; -static vop_open_t nwfs_open; -static vop_close_t nwfs_close; -static vop_access_t nwfs_access; -static vop_getattr_t nwfs_getattr; -static vop_setattr_t nwfs_setattr; -static vop_read_t nwfs_read; -static vop_write_t nwfs_write; -static vop_fsync_t nwfs_fsync; -static vop_remove_t nwfs_remove; -static vop_link_t nwfs_link; -static vop_lookup_t nwfs_lookup; -static vop_rename_t nwfs_rename; -static vop_mkdir_t nwfs_mkdir; -static vop_rmdir_t nwfs_rmdir; -static vop_symlink_t nwfs_symlink; -static vop_readdir_t nwfs_readdir; -static vop_strategy_t nwfs_strategy; -static vop_print_t nwfs_print; -static vop_pathconf_t nwfs_pathconf; - -/* Global vfs data structures for nwfs */ -struct vop_vector nwfs_vnodeops = { - .vop_default = &default_vnodeops, - - .vop_access = nwfs_access, - .vop_close = nwfs_close, - .vop_create = nwfs_create, - .vop_fsync = nwfs_fsync, - .vop_getattr = nwfs_getattr, - .vop_getpages = nwfs_getpages, - .vop_inactive = nwfs_inactive, - .vop_ioctl = nwfs_ioctl, - .vop_link = nwfs_link, - .vop_lookup = nwfs_lookup, - .vop_mkdir = nwfs_mkdir, - .vop_mknod = nwfs_mknod, - .vop_open = nwfs_open, - .vop_pathconf = nwfs_pathconf, - .vop_print = nwfs_print, - .vop_putpages = nwfs_putpages, - .vop_read = nwfs_read, - .vop_readdir = nwfs_readdir, - .vop_reclaim = nwfs_reclaim, - .vop_remove = nwfs_remove, - .vop_rename = nwfs_rename, - .vop_rmdir = nwfs_rmdir, - .vop_setattr = nwfs_setattr, - .vop_strategy = nwfs_strategy, - .vop_symlink = nwfs_symlink, - .vop_write = nwfs_write, -}; - -/* - * nwfs_access vnode op - */ -static int -nwfs_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - accmode_t a_accmode; - struct ucred *a_cred; - struct thread *td; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - mode_t mpmode; - struct nwmount *nmp = VTONWFS(vp); - - NCPVNDEBUG("\n"); - if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: case VDIR: case VLNK: - return (EROFS); - default: - break; - } - } - mpmode = vp->v_type == VREG ? nmp->m.file_mode : - nmp->m.dir_mode; - return (vaccess(vp->v_type, mpmode, nmp->m.uid, - nmp->m.gid, ap->a_accmode, ap->a_cred, NULL)); -} -/* - * nwfs_open vnode op - */ -/* ARGSUSED */ -static int -nwfs_open(ap) - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *td; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - int mode = ap->a_mode; - struct nwnode *np = VTONW(vp); - struct ncp_open_info no; - struct nwmount *nmp = VTONWFS(vp); - struct vattr vattr; - int error, nwm; - - NCPVNDEBUG("%s,%d\n", np->n_name, np->opened); - if (vp->v_type != VREG && vp->v_type != VDIR) { - NCPFATAL("open vtype = %d\n", vp->v_type); - return (EACCES); - } - if (vp->v_type == VDIR) return 0; /* nothing to do now */ - if (np->n_flag & NMODIFIED) { - if ((error = nwfs_vinvalbuf(vp, ap->a_td)) == EINTR) - return (error); - np->n_atime = 0; - error = VOP_GETATTR(vp, &vattr, ap->a_cred); - if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, ap->a_cred); - if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - if ((error = nwfs_vinvalbuf(vp, ap->a_td)) == EINTR) - return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } - } - if (np->opened) { - np->opened++; - return 0; - } - nwm = AR_READ; - if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) - nwm |= AR_WRITE; - error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, - 0, nwm, &no, ap->a_td, ap->a_cred); - if (error) { - if (mode & FWRITE) - return EACCES; - nwm = AR_READ; - error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0, - nwm, &no, ap->a_td, ap->a_cred); - } - if (!error) { - np->opened++; - np->n_fh = no.fh; - np->n_origfh = no.origfh; - } - np->n_atime = 0; - return (error); -} - -static int -nwfs_close(ap) - struct vop_close_args /* { - struct vnodeop_desc *a_desc; - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *td; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - int error; - - NCPVNDEBUG("name=%s,pid=%d,c=%d\n", np->n_name, ap->a_td->td_proc->p_pid, - np->opened); - - if (vp->v_type == VDIR) return 0; /* nothing to do now */ - error = 0; - VI_LOCK(vp); - if (np->opened == 0) { - VI_UNLOCK(vp); - return 0; - } - VI_UNLOCK(vp); - error = nwfs_vinvalbuf(vp, ap->a_td); - VI_LOCK(vp); - if (np->opened == 0) { - VI_UNLOCK(vp); - return 0; - } - if (--np->opened == 0) { - VI_UNLOCK(vp); - error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, - ap->a_td, ap->a_cred); - } else - VI_UNLOCK(vp); - np->n_atime = 0; - return (error); -} - -/* - * nwfs_getattr call from vfs. - */ -static int -nwfs_getattr(ap) - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - struct vattr *va=ap->a_vap; - struct nwmount *nmp = VTONWFS(vp); - struct thread *td = curthread; - struct nw_entry_info fattr; - int error; - u_int32_t oldsize; - - NCPVNDEBUG("%lx:%d: '%s' %d\n", (long)vp, nmp->n_volume, np->n_name, (vp->v_vflag & VV_ROOT) != 0); - error = nwfs_attr_cachelookup(vp, va); - if (!error) return 0; - NCPVNDEBUG("not in cache\n"); - oldsize = np->n_size; - if (np->n_flag & NVOLUME) { - error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, &fattr, - td, ap->a_cred); - } else { - error = ncp_obtain_info(nmp, np->n_fid.f_parent, np->n_nmlen, - np->n_name, &fattr, td, ap->a_cred); - } - if (error) { - NCPVNDEBUG("error %d\n", error); - return error; - } - nwfs_attr_cacheenter(vp, &fattr); - *va = np->n_vattr; - if (np->opened) - np->n_size = oldsize; - return (0); -} -/* - * nwfs_setattr call from vfs. - */ -static int -nwfs_setattr(ap) - struct vop_setattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - struct vattr *vap = ap->a_vap; - u_quad_t tsize=0; - int error = 0; - - NCPVNDEBUG("\n"); - if (vap->va_flags != VNOVAL) - return (EOPNOTSUPP); - /* - * Disallow write attempts if the filesystem is mounted read-only. - */ - if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL || - vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || - vap->va_mode != (mode_t)VNOVAL) &&(vp->v_mount->mnt_flag & MNT_RDONLY)) - return (EROFS); - if (vap->va_size != VNOVAL) { - switch (vp->v_type) { - case VDIR: - return (EISDIR); - case VREG: - /* - * Disallow write attempts if the filesystem is - * mounted read-only. - */ - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - vnode_pager_setsize(vp, (u_long)vap->va_size); - tsize = np->n_size; - np->n_size = vap->va_size; - break; - default: - return EINVAL; - }; - } - error = ncp_setattr(vp, vap, ap->a_cred, curthread); - if (error && vap->va_size != VNOVAL) { - np->n_size = tsize; - vnode_pager_setsize(vp, (u_long)tsize); - } - np->n_atime = 0; /* invalidate cache */ - VOP_GETATTR(vp, vap, ap->a_cred); - np->n_mtime = vap->va_mtime.tv_sec; - return (0); -} -/* - * nwfs_read call. - */ -static int -nwfs_read(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct uio *uio=ap->a_uio; - int error; - NCPVNDEBUG("nwfs_read:\n"); - - if (vp->v_type != VREG && vp->v_type != VDIR) - return (EPERM); - error = nwfs_readvnode(vp, uio, ap->a_cred); - return error; -} - -static int -nwfs_write(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct uio *uio = ap->a_uio; - int error; - - NCPVNDEBUG("%d,ofs=%d,sz=%d\n", vp->v_type, (int)uio->uio_offset, uio->uio_resid); - - if (vp->v_type != VREG) - return (EPERM); - error = nwfs_writevnode(vp, uio, ap->a_cred, ap->a_ioflag); - return(error); -} -/* - * nwfs_create call - * Create a regular file. On entry the directory to contain the file being - * created is locked. We must release before we return. We must also free - * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or - * only if the SAVESTART bit in cn_flags is clear on success. - */ -static int -nwfs_create(ap) - struct vop_create_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap; -{ - struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; - struct vnode **vpp=ap->a_vpp; - struct componentname *cnp = ap->a_cnp; - struct vnode *vp = (struct vnode *)0; - int error = 0, fmode; - struct vattr vattr; - struct nwnode *np; - struct ncp_open_info no; - struct nwmount *nmp=VTONWFS(dvp); - ncpfid fid; - - - NCPVNDEBUG("\n"); - *vpp = NULL; - if (vap->va_type == VSOCK) - return (EOPNOTSUPP); - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred))) - return (error); - fmode = AR_READ | AR_WRITE; -/* if (vap->va_vaflags & VA_EXCLUSIVE) - fmode |= AR_DENY_READ | AR_DENY_WRITE;*/ - - error = ncp_open_create_file_or_subdir(nmp, dvp, cnp->cn_namelen, cnp->cn_nameptr, - OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, - 0, fmode, &no, cnp->cn_thread, cnp->cn_cred); - if (!error) { - error = ncp_close_file(NWFSTOCONN(nmp), &no.fh, cnp->cn_thread, cnp->cn_cred); - fid.f_parent = VTONW(dvp)->n_fid.f_id; - fid.f_id = no.fattr.dirEntNum; - error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &vp); - if (!error) { - np = VTONW(vp); - np->opened = 0; - *vpp = vp; - } - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, vp, cnp); - } - return (error); -} - -/* - * nwfs_remove call. It isn't possible to emulate UFS behaivour because - * NetWare doesn't allow delete/rename operations on an opened file. - */ -static int -nwfs_remove(ap) - struct vop_remove_args /* { - struct vnodeop_desc *a_desc; - struct vnode * a_dvp; - struct vnode * a_vp; - struct componentname * a_cnp; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct nwnode *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - int error; - - if (vp->v_type == VDIR || np->opened || vrefcnt(vp) != 1) - return EPERM; - cache_purge(vp); - error = ncp_DeleteNSEntry(nmp, VTONW(dvp)->n_fid.f_id, - cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_thread, cnp->cn_cred); - if (error == 0) - np->n_flag |= NSHOULDFREE; - else if (error == 0x899c) - error = EACCES; - return (error); -} - -/* - * nwfs_file rename call - */ -static int -nwfs_rename(ap) - struct vop_rename_args /* { - struct vnode *a_fdvp; - struct vnode *a_fvp; - struct componentname *a_fcnp; - struct vnode *a_tdvp; - struct vnode *a_tvp; - struct componentname *a_tcnp; - } */ *ap; -{ - struct vnode *fvp = ap->a_fvp; - struct vnode *tvp = ap->a_tvp; - struct vnode *fdvp = ap->a_fdvp; - struct vnode *tdvp = ap->a_tdvp; - struct componentname *tcnp = ap->a_tcnp; - struct componentname *fcnp = ap->a_fcnp; - struct nwmount *nmp=VTONWFS(fvp); - u_int16_t oldtype = 6; - int error=0; - - /* Check for cross-device rename */ - if ((fvp->v_mount != tdvp->v_mount) || - (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; - goto out; - } - - if (tvp && vrefcnt(tvp) > 1) { - error = EBUSY; - goto out; - } - if (fvp->v_type == VDIR) { - oldtype |= NW_TYPE_SUBDIR; - } else if (fvp->v_type == VREG) { - oldtype |= NW_TYPE_FILE; - } else { - error = EINVAL; - goto out; - } - if (tvp && tvp != fvp) { - error = ncp_DeleteNSEntry(nmp, VTONW(tdvp)->n_fid.f_id, - tcnp->cn_namelen, tcnp->cn_nameptr, - tcnp->cn_thread, tcnp->cn_cred); - if (error == 0x899c) error = EACCES; - if (error) - goto out_cacherem; - } - error = ncp_nsrename(NWFSTOCONN(nmp), nmp->n_volume, nmp->name_space, - oldtype, &nmp->m.nls, - VTONW(fdvp)->n_fid.f_id, fcnp->cn_nameptr, fcnp->cn_namelen, - VTONW(tdvp)->n_fid.f_id, tcnp->cn_nameptr, tcnp->cn_namelen, - tcnp->cn_thread, tcnp->cn_cred); - - if (error == 0x8992) - error = EEXIST; - if (fvp->v_type == VDIR) { - if (tvp != NULL && tvp->v_type == VDIR) - cache_purge(tdvp); - cache_purge(fdvp); - } -out_cacherem: - nwfs_attr_cacheremove(fdvp); - nwfs_attr_cacheremove(tdvp); - nwfs_attr_cacheremove(fvp); -out: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - if (tvp) - nwfs_attr_cacheremove(tvp); - /* - * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. - */ - if (error == ENOENT) - error = 0; - return (error); -} - -/* - * nwfs hard link create call - * Netware filesystems don't know what links are. - */ -static int -nwfs_link(ap) - struct vop_link_args /* { - struct vnode *a_tdvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap; -{ - return EOPNOTSUPP; -} - -/* - * nwfs_symlink link create call - * Netware filesystems don't know what symlinks are. - */ -static int -nwfs_symlink(ap) - struct vop_symlink_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - char *a_target; - } */ *ap; -{ - return (EOPNOTSUPP); -} - -static int nwfs_mknod(ap) - struct vop_mknod_args /* { - } */ *ap; -{ - return (EOPNOTSUPP); -} - -/* - * nwfs_mkdir call - */ -static int -nwfs_mkdir(ap) - struct vop_mkdir_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap; -{ - struct vnode *dvp = ap->a_dvp; -/* struct vattr *vap = ap->a_vap;*/ - struct componentname *cnp = ap->a_cnp; - int len=cnp->cn_namelen; - struct ncp_open_info no; - struct vnode *newvp = (struct vnode *)0; - ncpfid fid; - int error = 0; - struct vattr vattr; - char *name=cnp->cn_nameptr; - - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred))) - return (error); - if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))) { - return EEXIST; - } - if (ncp_open_create_file_or_subdir(VTONWFS(dvp), dvp, cnp->cn_namelen, - cnp->cn_nameptr, OC_MODE_CREATE, aDIR, 0xffff, - &no, cnp->cn_thread, cnp->cn_cred) != 0) { - error = EACCES; - } else { - error = 0; - } - if (!error) { - fid.f_parent = VTONW(dvp)->n_fid.f_id; - fid.f_id = no.fattr.dirEntNum; - error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &newvp); - if (!error) { - newvp->v_type = VDIR; - *ap->a_vpp = newvp; - } - } - return (error); -} - -/* - * nwfs_remove directory call - */ -static int -nwfs_rmdir(ap) - struct vop_rmdir_args /* { - struct vnode *a_dvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct nwnode *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - struct nwnode *dnp = VTONW(dvp); - int error = EIO; - - if (dvp == vp) - return EINVAL; - - error = ncp_DeleteNSEntry(nmp, dnp->n_fid.f_id, - cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_thread, cnp->cn_cred); - if (error == 0) - np->n_flag |= NSHOULDFREE; - else if (error == NWE_DIR_NOT_EMPTY) - error = ENOTEMPTY; - dnp->n_flag |= NMODIFIED; - nwfs_attr_cacheremove(dvp); - cache_purge(dvp); - cache_purge(vp); - return (error); -} - -/* - * nwfs_readdir call - */ -static int -nwfs_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_eofflag; - u_long *a_cookies; - int a_ncookies; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct uio *uio = ap->a_uio; - int error; - - if (vp->v_type != VDIR) - return (EPERM); - if (ap->a_ncookies) { - printf("nwfs_readdir: no support for cookies now..."); - return (EOPNOTSUPP); - } - - error = nwfs_readvnode(vp, uio, ap->a_cred); - return error; -} -/* ARGSUSED */ -static int -nwfs_fsync(ap) - struct vop_fsync_args /* { - struct vnodeop_desc *a_desc; - struct vnode * a_vp; - struct ucred * a_cred; - int a_waitfor; - struct thread *a_td; - } */ *ap; -{ -/* return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_td, 1));*/ - return (0); -} - -/* ARGSUSED */ -static -int nwfs_print (ap) - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - - printf("\tnwfs node: name = '%s', fid = %d, pfid = %d\n", - np->n_name, np->n_fid.f_id, np->n_fid.f_parent); - return (0); -} - -static int nwfs_pathconf (ap) - struct vop_pathconf_args /* { - struct vnode *vp; - int name; - register_t *retval; - } */ *ap; -{ - int name=ap->a_name, error=0; - register_t *retval=ap->a_retval; - - switch(name){ - case _PC_LINK_MAX: - *retval=0; - break; - case _PC_NAME_MAX: - *retval=NCP_MAX_FILENAME; /* XXX from nwfsnode */ - break; - case _PC_PATH_MAX: - *retval=NCP_MAXPATHLEN; /* XXX from nwfsnode */ - break; - default: - error=EINVAL; - } - return(error); -} - -static int nwfs_strategy (ap) - struct vop_strategy_args /* { - struct buf *a_bp - } */ *ap; -{ - struct buf *bp=ap->a_bp; - struct ucred *cr; - struct thread *td; - - NCPVNDEBUG("\n"); - if (bp->b_flags & B_ASYNC) - td = (struct thread *)0; - else - td = curthread; /* XXX */ - if (bp->b_iocmd == BIO_READ) - cr = bp->b_rcred; - else - cr = bp->b_wcred; - /* - * If the op is asynchronous and an i/o daemon is waiting - * queue the request, wake it up and wait for completion - * otherwise just do it ourselves. - */ - if ((bp->b_flags & B_ASYNC) == 0 ) - (void)nwfs_doio(ap->a_vp, bp, cr, td); - return (0); -} - - -/* - * How to keep the brain busy ... - * Currently lookup routine can make two lookup for vnode. This can be - * avoided by reorg the code. - */ -int -nwfs_lookup(ap) - struct vop_lookup_args /* { - struct vnodeop_desc *a_desc; - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; -{ - struct componentname *cnp = ap->a_cnp; - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - int flags = cnp->cn_flags; - struct vnode *vp; - struct nwmount *nmp; - struct mount *mp = dvp->v_mount; - struct nwnode *dnp, *npp; - struct nw_entry_info fattr, *fap; - ncpfid fid; - int nameiop=cnp->cn_nameiop, islastcn; - int error = 0, notfound; - struct thread *td = cnp->cn_thread; - char _name[cnp->cn_namelen+1]; - bcopy(cnp->cn_nameptr, _name, cnp->cn_namelen); - _name[cnp->cn_namelen]=0; - - if (dvp->v_type != VDIR) - return (ENOTDIR); - if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT)) { - printf("nwfs_lookup: invalid '..'\n"); - return EIO; - } - - NCPVNDEBUG("%d '%s' in '%s' id=d\n", nameiop, _name, - VTONW(dvp)->n_name/*, VTONW(dvp)->n_name*/); - - islastcn = flags & ISLASTCN; - if (islastcn && (mp->mnt_flag & MNT_RDONLY) && (nameiop != LOOKUP)) - return (EROFS); - if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td))) - return (error); - nmp = VFSTONWFS(mp); - dnp = VTONW(dvp); -/* -printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_vflag & VV_ROOT, (int)flags & ISDOTDOT); -*/ - error = ncp_pathcheck(cnp->cn_nameptr, cnp->cn_namelen, &nmp->m.nls, - (nameiop == CREATE || nameiop == RENAME) && (nmp->m.nls.opt & NWHP_NOSTRICT) == 0); - if (error) - return ENOENT; - - error = cache_lookup(dvp, vpp, cnp, NULL, NULL); - NCPVNDEBUG("cache_lookup returned %d\n", error); - if (error > 0) - return error; - if (error) { /* name was found */ - struct vattr vattr; - - vp = *vpp; - if (!VOP_GETATTR(vp, &vattr, cnp->cn_cred) && - vattr.va_ctime.tv_sec == VTONW(vp)->n_ctime) { - if (nameiop != LOOKUP && islastcn) - cnp->cn_flags |= SAVENAME; - NCPVNDEBUG("use cached vnode"); - return (0); - } - cache_purge(vp); - if (vp != dvp) - vput(vp); - else - vrele(vp); - *vpp = NULLVP; - } - /* not in cache, so ... */ - error = 0; - *vpp = NULLVP; - fap = NULL; - if (flags & ISDOTDOT) { - if (NWCMPF(&dnp->n_parent, &nmp->n_rootent)) { - fid = nmp->n_rootent; - fap = NULL; - notfound = 0; - } else { - error = nwfs_lookupnp(nmp, dnp->n_parent, td, &npp); - if (error) { - return error; - } - fid = dnp->n_parent; - fap = &fattr; - /*np = *npp;*/ - notfound = ncp_obtain_info(nmp, npp->n_dosfid, - 0, NULL, fap, td, cnp->cn_cred); - } - } else { - fap = &fattr; - notfound = ncp_lookup(dvp, cnp->cn_namelen, cnp->cn_nameptr, - fap, td, cnp->cn_cred); - fid.f_id = fap->dirEntNum; - if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { - fid.f_parent = dnp->n_fid.f_parent; - } else - fid.f_parent = dnp->n_fid.f_id; - NCPVNDEBUG("call to ncp_lookup returned=%d\n", notfound); - } - if (notfound && notfound < 0x80 ) - return (notfound); /* hard error */ - if (notfound) { /* entry not found */ - /* Handle RENAME or CREATE case... */ - if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { - cnp->cn_flags |= SAVENAME; - return (EJUSTRETURN); - } - return ENOENT; - }/* else { - NCPVNDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum); - }*/ - /* handle DELETE case ... */ - if (nameiop == DELETE && islastcn) { /* delete last component */ - error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, cnp->cn_thread); - if (error) return (error); - if (NWCMPF(&dnp->n_fid, &fid)) { /* we found ourselfs */ - VREF(dvp); - *vpp = dvp; - return 0; - } - error = nwfs_nget(mp, fid, fap, dvp, &vp); - if (error) return (error); - *vpp = vp; - cnp->cn_flags |= SAVENAME; /* I free it later */ - return (0); - } - if (nameiop == RENAME && islastcn) { - error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, cnp->cn_thread); - if (error) return (error); - if (NWCMPF(&dnp->n_fid, &fid)) return EISDIR; - error = nwfs_nget(mp, fid, fap, dvp, &vp); - if (error) return (error); - *vpp = vp; - cnp->cn_flags |= SAVENAME; - return (0); - } - if (flags & ISDOTDOT) { - VOP_UNLOCK(dvp, 0); /* race to get the inode */ - error = nwfs_nget(mp, fid, NULL, NULL, &vp); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - if (error) - return (error); - *vpp = vp; - } else if (NWCMPF(&dnp->n_fid, &fid)) { - vref(dvp); - *vpp = dvp; - } else { - error = nwfs_nget(mp, fid, fap, dvp, &vp); - if (error) return (error); - *vpp = vp; - NCPVNDEBUG("lookup: getnewvp!\n"); - } - if ((cnp->cn_flags & MAKEENTRY)/* && !islastcn*/) { - VTONW(*vpp)->n_ctime = VTONW(*vpp)->n_vattr.va_ctime.tv_sec; - cache_enter(dvp, *vpp, cnp); - } - return (0); -} |