diff options
author | ru <ru@FreeBSD.org> | 2001-05-26 11:57:45 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2001-05-26 11:57:45 +0000 |
commit | 05f3be90b2e785fbcbac9efe38dd8fb4bd6cdb7c (patch) | |
tree | bc6b0076c297f637980e63a3ebde03fd9302042a | |
parent | bb3012ea8ac3c3f242d03857752725e5a8e74119 (diff) | |
download | FreeBSD-src-05f3be90b2e785fbcbac9efe38dd8fb4bd6cdb7c.zip FreeBSD-src-05f3be90b2e785fbcbac9efe38dd8fb4bd6cdb7c.tar.gz |
- sys/n[tw]fs moved to sys/fs/n[tw]fs
- /usr/include/n[tw]fs moved to /usr/include/fs/n[tw]fs
47 files changed, 68 insertions, 8730 deletions
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 7028770..69ead05 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -26,8 +26,12 @@ .. msdosfs .. + ntfs + .. nullfs .. + nwfs + .. portalfs .. procfs @@ -77,10 +81,6 @@ .. nfs .. - ntfs - .. - nwfs - .. objc .. openssl diff --git a/include/Makefile b/include/Makefile index 4b68b53..ee9fbd5 100644 --- a/include/Makefile +++ b/include/Makefile @@ -40,13 +40,13 @@ LFILES= aio.h errno.h fcntl.h inttypes.h linker_set.h poll.h syslog.h \ termios.h ucontext.h LDIRS= cam net netatalk netatm netgraph netinet netinet6 \ - netipx netkey netnatm netncp netns netsmb nfs ntfs nwfs pccard posix4 \ + netipx netkey netnatm netncp netns netsmb nfs pccard posix4 \ sys vm LNOHEADERDIRS= fs isofs ufs dev LSUBDIRS= cam/scsi dev/ppbus dev/usb dev/wi \ - fs/fdescfs fs/fifofs fs/msdosfs fs/nullfs fs/portalfs \ + fs/fdescfs fs/fifofs fs/msdosfs fs/ntfs fs/nullfs fs/nwfs fs/portalfs \ fs/procfs fs/smbfs fs/umapfs fs/unionfs isofs/cd9660 \ ufs/ffs ufs/mfs ufs/ufs diff --git a/lib/libncp/ncpl_conn.c b/lib/libncp/ncpl_conn.c index 0a12cf8..b688186 100644 --- a/lib/libncp/ncpl_conn.c +++ b/lib/libncp/ncpl_conn.c @@ -64,7 +64,7 @@ #include <netncp/ncp_lib.h> #include <netncp/ncp_rcfile.h> -#include <nwfs/nwfs.h> +#include <fs/nwfs/nwfs.h> static char *server_name; /* need a better way ! */ diff --git a/lib/libncp/ncpl_file.c b/lib/libncp/ncpl_file.c index ab8bb76..dedd533 100644 --- a/lib/libncp/ncpl_file.c +++ b/lib/libncp/ncpl_file.c @@ -41,7 +41,7 @@ #include <netncp/ncp_lib.h> #include <netncp/ncp_file.h> -#include <nwfs/nwfs.h> +#include <fs/nwfs/nwfs.h> int ncp_read(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *target) { diff --git a/sbin/mount_ntfs/mount_ntfs.c b/sbin/mount_ntfs/mount_ntfs.c index 95b86c2..9dbd5fb 100644 --- a/sbin/mount_ntfs/mount_ntfs.c +++ b/sbin/mount_ntfs/mount_ntfs.c @@ -37,7 +37,7 @@ #define NTFS #include <sys/mount.h> #include <sys/stat.h> -#include <ntfs/ntfsmount.h> +#include <fs/ntfs/ntfsmount.h> #include <ctype.h> #include <err.h> #include <grp.h> diff --git a/sbin/mount_nwfs/mount_nwfs.c b/sbin/mount_nwfs/mount_nwfs.c index 02b45dd..8e37b09 100644 --- a/sbin/mount_nwfs/mount_nwfs.c +++ b/sbin/mount_nwfs/mount_nwfs.c @@ -51,7 +51,7 @@ #include <netncp/ncp_lib.h> #include <netncp/ncp_rcfile.h> -#include <nwfs/nwfs_mount.h> +#include <fs/nwfs/nwfs_mount.h> #include "mntopts.h" #define NWFS_VFSNAME "nwfs" diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c index 2d198e6..0c08f40 100644 --- a/sbin/mountd/mountd.c +++ b/sbin/mountd/mountd.c @@ -64,7 +64,7 @@ static const char rcsid[] = #include <nfs/nfs.h> #include <ufs/ufs/ufsmount.h> #include <fs/msdosfs/msdosfsmount.h> -#include <ntfs/ntfsmount.h> +#include <fs/ntfs/ntfsmount.h> #include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */ #include <arpa/inet.h> diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 8f723fe..859bdb9 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -246,7 +246,7 @@ struct linux_statfs_buf { }; #ifndef VT_NWFS -#define VT_NWFS VT_TFS /* XXX - bug compatibility with sys/nwfs/nwfs_node.h */ +#define VT_NWFS VT_TFS /* XXX - bug compatibility with sys/fs/nwfs/nwfs_node.h */ #endif #define LINUX_CODA_SUPER_MAGIC 0x73757245L diff --git a/sys/conf/files b/sys/conf/files index 22c2859..c11713b 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -604,9 +604,20 @@ fs/msdosfs/msdosfs_fat.c optional msdosfs fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs fs/msdosfs/msdosfs_vnops.c optional msdosfs +fs/ntfs/ntfs_compr.c optional ntfs +fs/ntfs/ntfs_ihash.c optional ntfs +fs/ntfs/ntfs_subr.c optional ntfs +fs/ntfs/ntfs_vfsops.c optional ntfs +fs/ntfs/ntfs_vnops.c optional ntfs fs/nullfs/null_subr.c optional nullfs fs/nullfs/null_vfsops.c optional nullfs fs/nullfs/null_vnops.c optional nullfs +fs/nwfs/nwfs_io.c optional nwfs +fs/nwfs/nwfs_ioctl.c optional nwfs +fs/nwfs/nwfs_node.c optional nwfs +fs/nwfs/nwfs_subr.c optional nwfs +fs/nwfs/nwfs_vfsops.c optional nwfs +fs/nwfs/nwfs_vnops.c optional nwfs fs/portalfs/portal_vfsops.c optional portalfs fs/portalfs/portal_vnops.c optional portalfs fs/procfs/procfs_ctl.c optional procfs @@ -1141,17 +1152,6 @@ nfs/nfs_subs.c optional nfs nfs/nfs_syscalls.c optional nfs nfs/nfs_vfsops.c optional nfs nfs/nfs_vnops.c optional nfs -ntfs/ntfs_compr.c optional ntfs -ntfs/ntfs_ihash.c optional ntfs -ntfs/ntfs_subr.c optional ntfs -ntfs/ntfs_vfsops.c optional ntfs -ntfs/ntfs_vnops.c optional ntfs -nwfs/nwfs_io.c optional nwfs -nwfs/nwfs_ioctl.c optional nwfs -nwfs/nwfs_node.c optional nwfs -nwfs/nwfs_subr.c optional nwfs -nwfs/nwfs_vfsops.c optional nwfs -nwfs/nwfs_vnops.c optional nwfs pccard/pccard.c count card pccard/pccard_beep.c optional card pccard/pccard_nbk.c optional card diff --git a/sys/fs/ntfs/ntfs_compr.c b/sys/fs/ntfs/ntfs_compr.c index 1d22b54..3ae675b 100644 --- a/sys/fs/ntfs/ntfs_compr.c +++ b/sys/fs/ntfs/ntfs_compr.c @@ -39,8 +39,8 @@ #include <miscfs/specfs/specdev.h> #endif -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_compr.h> +#include <fs/ntfs/ntfs.h> +#include <fs/ntfs/ntfs_compr.h> #define GET_UINT16(addr) (*((u_int16_t *)(addr))) diff --git a/sys/fs/ntfs/ntfs_ihash.c b/sys/fs/ntfs/ntfs_ihash.c index fea648c..8892741 100644 --- a/sys/fs/ntfs/ntfs_ihash.c +++ b/sys/fs/ntfs/ntfs_ihash.c @@ -45,9 +45,9 @@ #include <sys/mount.h> #include <sys/mutex.h> -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_ihash.h> +#include <fs/ntfs/ntfs.h> +#include <fs/ntfs/ntfs_inode.h> +#include <fs/ntfs/ntfs_ihash.h> MALLOC_DEFINE(M_NTFSNTHASH, "NTFS nthash", "NTFS ntnode hash tables"); diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c index c55cd0a..6158407 100644 --- a/sys/fs/ntfs/ntfs_subr.c +++ b/sys/fs/ntfs/ntfs_subr.c @@ -46,13 +46,13 @@ #endif /* #define NTFS_DEBUG 1 */ -#include <ntfs/ntfs.h> -#include <ntfs/ntfsmount.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_vfsops.h> -#include <ntfs/ntfs_subr.h> -#include <ntfs/ntfs_compr.h> -#include <ntfs/ntfs_ihash.h> +#include <fs/ntfs/ntfs.h> +#include <fs/ntfs/ntfsmount.h> +#include <fs/ntfs/ntfs_inode.h> +#include <fs/ntfs/ntfs_vfsops.h> +#include <fs/ntfs/ntfs_subr.h> +#include <fs/ntfs/ntfs_compr.h> +#include <fs/ntfs/ntfs_ihash.h> #if defined(__FreeBSD__) MALLOC_DEFINE(M_NTFSNTVATTR, "NTFS vattr", "NTFS file attribute information"); diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index 526decd..42a4fcb 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -60,12 +60,12 @@ #endif /*#define NTFS_DEBUG 1*/ -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_subr.h> -#include <ntfs/ntfs_vfsops.h> -#include <ntfs/ntfs_ihash.h> -#include <ntfs/ntfsmount.h> +#include <fs/ntfs/ntfs.h> +#include <fs/ntfs/ntfs_inode.h> +#include <fs/ntfs/ntfs_subr.h> +#include <fs/ntfs/ntfs_vfsops.h> +#include <fs/ntfs/ntfs_ihash.h> +#include <fs/ntfs/ntfsmount.h> #if defined(__FreeBSD__) MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure"); diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c index 072a512..44abb50 100644 --- a/sys/fs/ntfs/ntfs_vnops.c +++ b/sys/fs/ntfs/ntfs_vnops.c @@ -69,9 +69,9 @@ #include <sys/sysctl.h> /*#define NTFS_DEBUG 1*/ -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_subr.h> +#include <fs/ntfs/ntfs.h> +#include <fs/ntfs/ntfs_inode.h> +#include <fs/ntfs/ntfs_subr.h> #if defined(__NetBSD__) #include <miscfs/specfs/specdev.h> #include <miscfs/genfs/genfs.h> diff --git a/sys/fs/nwfs/nwfs.h b/sys/fs/nwfs/nwfs.h index e547869..41b25ae 100644 --- a/sys/fs/nwfs/nwfs.h +++ b/sys/fs/nwfs/nwfs.h @@ -36,7 +36,7 @@ #define _NWFS_H_ #include <netncp/ncp.h> -#include <nwfs/nwfs_mount.h> +#include <fs/nwfs/nwfs_mount.h> #define NR_OPEN 0 #define NW_NSB_DOS (1 << NW_NS_DOS) diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c index 4b105c6..8e73cf0 100644 --- a/sys/fs/nwfs/nwfs_io.c +++ b/sys/fs/nwfs/nwfs_io.c @@ -58,9 +58,9 @@ #include <netncp/ncp_subr.h> #include <netncp/ncp_ncp.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> +#include <fs/nwfs/nwfs.h> +#include <fs/nwfs/nwfs_node.h> +#include <fs/nwfs/nwfs_subr.h> static int nwfs_fastlookup = 1; diff --git a/sys/fs/nwfs/nwfs_ioctl.c b/sys/fs/nwfs/nwfs_ioctl.c index eb58389..41c956c 100644 --- a/sys/fs/nwfs/nwfs_ioctl.c +++ b/sys/fs/nwfs/nwfs_ioctl.c @@ -41,9 +41,9 @@ #include <netncp/ncp_conn.h> #include <netncp/ncp_subr.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> +#include <fs/nwfs/nwfs.h> +#include <fs/nwfs/nwfs_node.h> +#include <fs/nwfs/nwfs_subr.h> int nwfs_ioctl(ap) diff --git a/sys/fs/nwfs/nwfs_node.c b/sys/fs/nwfs/nwfs_node.c index 9c1f086..0700b76 100644 --- a/sys/fs/nwfs/nwfs_node.c +++ b/sys/fs/nwfs/nwfs_node.c @@ -53,10 +53,10 @@ #include <netncp/ncp_conn.h> #include <netncp/ncp_subr.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_mount.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_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]) diff --git a/sys/fs/nwfs/nwfs_subr.c b/sys/fs/nwfs/nwfs_subr.c index d3e212d..b83e89b 100644 --- a/sys/fs/nwfs/nwfs_subr.c +++ b/sys/fs/nwfs/nwfs_subr.c @@ -45,9 +45,9 @@ #include <netncp/ncp_rq.h> #include <netncp/nwerror.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.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) diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c index c978722..b37a856 100644 --- a/sys/fs/nwfs/nwfs_vfsops.c +++ b/sys/fs/nwfs/nwfs_vfsops.c @@ -54,9 +54,9 @@ #include <netncp/ncp_ncp.h> #include <netncp/ncp_nls.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> +#include <fs/nwfs/nwfs.h> +#include <fs/nwfs/nwfs_node.h> +#include <fs/nwfs/nwfs_subr.h> int nwfs_debuglevel = 0; diff --git a/sys/fs/nwfs/nwfs_vnops.c b/sys/fs/nwfs/nwfs_vnops.c index 1e5361f..dc83b3d 100644 --- a/sys/fs/nwfs/nwfs_vnops.c +++ b/sys/fs/nwfs/nwfs_vnops.c @@ -53,9 +53,9 @@ #include <netncp/nwerror.h> #include <netncp/ncp_nls.h> -#include <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> +#include <fs/nwfs/nwfs.h> +#include <fs/nwfs/nwfs_node.h> +#include <fs/nwfs/nwfs_subr.h> /* * Prototypes for NWFS vnode operations diff --git a/sys/modules/ntfs/Makefile b/sys/modules/ntfs/Makefile index 8f663e2..99d1a6e 100644 --- a/sys/modules/ntfs/Makefile +++ b/sys/modules/ntfs/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../ntfs +.PATH: ${.CURDIR}/../../fs/ntfs KMOD= ntfs SRCS= vnode_if.h \ diff --git a/sys/modules/nwfs/Makefile b/sys/modules/nwfs/Makefile index bc0e328..d272cb0 100644 --- a/sys/modules/nwfs/Makefile +++ b/sys/modules/nwfs/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../nwfs +.PATH: ${.CURDIR}/../../fs/nwfs KMOD= nwfs diff --git a/sys/ntfs/ntfs.h b/sys/ntfs/ntfs.h deleted file mode 100644 index d74fe6f..0000000 --- a/sys/ntfs/ntfs.h +++ /dev/null @@ -1,334 +0,0 @@ -/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -/*#define NTFS_DEBUG 1*/ -#if defined(__NetBSD__) && defined(_KERNEL) && !defined(_LKM) -#include "opt_ntfs.h" -#endif - -typedef u_int64_t cn_t; -typedef u_int16_t wchar; - -#pragma pack(1) -#define BBSIZE 1024 -#define BBOFF ((off_t)(0)) -#define BBLOCK ((daddr_t)(0)) -#define NTFS_MFTINO 0 -#define NTFS_VOLUMEINO 3 -#define NTFS_ATTRDEFINO 4 -#define NTFS_ROOTINO 5 -#define NTFS_BITMAPINO 6 -#define NTFS_BOOTINO 7 -#define NTFS_BADCLUSINO 8 -#define NTFS_UPCASEINO 10 -#define NTFS_MAXFILENAME 255 - -struct fixuphdr { - u_int32_t fh_magic; - u_int16_t fh_foff; - u_int16_t fh_fnum; -}; - -#define NTFS_AF_INRUN 0x00000001 -struct attrhdr { - u_int32_t a_type; - u_int32_t reclen; - u_int8_t a_flag; - u_int8_t a_namelen; - u_int8_t a_nameoff; - u_int8_t reserved1; - u_int8_t a_compression; - u_int8_t reserved2; - u_int16_t a_index; -}; -#define NTFS_A_STD 0x10 -#define NTFS_A_ATTRLIST 0x20 -#define NTFS_A_NAME 0x30 -#define NTFS_A_VOLUMENAME 0x60 -#define NTFS_A_DATA 0x80 -#define NTFS_A_INDXROOT 0x90 -#define NTFS_A_INDX 0xA0 -#define NTFS_A_INDXBITMAP 0xB0 - -#define NTFS_MAXATTRNAME 255 -struct attr { - struct attrhdr a_hdr; - union { - struct { - u_int16_t a_datalen; - u_int16_t reserved1; - u_int16_t a_dataoff; - u_int16_t a_indexed; - } a_S_r; - struct { - cn_t a_vcnstart; - cn_t a_vcnend; - u_int16_t a_dataoff; - u_int16_t a_compressalg; - u_int32_t reserved1; - u_int64_t a_allocated; - u_int64_t a_datalen; - u_int64_t a_initialized; - } a_S_nr; - } a_S; -}; -#define a_r a_S.a_S_r -#define a_nr a_S.a_S_nr - -typedef struct { - u_int64_t t_create; - u_int64_t t_write; - u_int64_t t_mftwrite; - u_int64_t t_access; -} ntfs_times_t; - -#define NTFS_FFLAG_RDONLY 0x01LL -#define NTFS_FFLAG_HIDDEN 0x02LL -#define NTFS_FFLAG_SYSTEM 0x04LL -#define NTFS_FFLAG_ARCHIVE 0x20LL -#define NTFS_FFLAG_COMPRESSED 0x0800LL -#define NTFS_FFLAG_DIR 0x10000000LL - -struct attr_name { - u_int32_t n_pnumber; /* Parent ntnode */ - u_int32_t reserved; - ntfs_times_t n_times; - u_int64_t n_size; - u_int64_t n_attrsz; - u_int64_t n_flag; - u_int8_t n_namelen; - u_int8_t n_nametype; - u_int16_t n_name[1]; -}; - -#define NTFS_IRFLAG_INDXALLOC 0x00000001 -struct attr_indexroot { - u_int32_t ir_unkn1; /* always 0x30 */ - u_int32_t ir_unkn2; /* always 0x1 */ - u_int32_t ir_size;/* ??? */ - u_int32_t ir_unkn3; /* number of cluster */ - u_int32_t ir_unkn4; /* always 0x10 */ - u_int32_t ir_datalen; /* sizeof simething */ - u_int32_t ir_allocated; /* same as above */ - u_int16_t ir_flag;/* ?? always 1 */ - u_int16_t ir_unkn7; -}; - -struct attr_attrlist { - u_int32_t al_type; /* Attribute type */ - u_int16_t reclen; /* length of this entry */ - u_int8_t al_namelen; /* Attribute name len */ - u_int8_t al_nameoff; /* Name offset from entry start */ - u_int64_t al_vcnstart; /* VCN number */ - u_int32_t al_inumber; /* Parent ntnode */ - u_int32_t reserved; - u_int16_t al_index; /* Attribute index in MFT record */ - u_int16_t al_name[1]; /* Name */ -}; - -#define NTFS_INDXMAGIC (u_int32_t)(0x58444E49) -struct attr_indexalloc { - struct fixuphdr ia_fixup; - u_int64_t unknown1; - cn_t ia_bufcn; - u_int16_t ia_hdrsize; - u_int16_t unknown2; - u_int32_t ia_inuse; - u_int32_t ia_allocated; -}; - -#define NTFS_IEFLAG_SUBNODE 0x00000001 -#define NTFS_IEFLAG_LAST 0x00000002 - -struct attr_indexentry { - u_int32_t ie_number; - u_int32_t unknown1; - u_int16_t reclen; - u_int16_t ie_size; - u_int32_t ie_flag;/* 1 - has subnodes, 2 - last */ - u_int32_t ie_fpnumber; - u_int32_t unknown2; - ntfs_times_t ie_ftimes; - u_int64_t ie_fallocated; - u_int64_t ie_fsize; - u_int64_t ie_fflag; - u_int8_t ie_fnamelen; - u_int8_t ie_fnametype; - wchar ie_fname[NTFS_MAXFILENAME]; - /* cn_t ie_bufcn; buffer with subnodes */ -}; - -#define NTFS_FILEMAGIC (u_int32_t)(0x454C4946) -#define NTFS_FRFLAG_DIR 0x0002 -struct filerec { - struct fixuphdr fr_fixup; - u_int8_t reserved[8]; - u_int16_t fr_seqnum; /* Sequence number */ - u_int16_t fr_nlink; - u_int16_t fr_attroff; /* offset to attributes */ - u_int16_t fr_flags; /* 1-nonresident attr, 2-directory */ - u_int32_t fr_size;/* hdr + attributes */ - u_int32_t fr_allocated; /* allocated length of record */ - u_int64_t fr_mainrec; /* main record */ - u_int16_t fr_attrnum; /* maximum attr number + 1 ??? */ -}; - -#define NTFS_ATTRNAME_MAXLEN 0x40 -#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */ -#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */ -struct attrdef { - wchar ad_name[NTFS_ATTRNAME_MAXLEN]; - u_int32_t ad_type; - u_int32_t reserved1[2]; - u_int32_t ad_flag; - u_int64_t ad_minlen; - u_int64_t ad_maxlen; /* -1 for nonlimited */ -}; - -struct ntvattrdef { - char ad_name[0x40]; - int ad_namelen; - u_int32_t ad_type; -}; - -#define NTFS_BBID "NTFS " -#define NTFS_BBIDLEN 8 -struct bootfile { - u_int8_t reserved1[3]; /* asm jmp near ... */ - u_int8_t bf_sysid[8]; /* 'NTFS ' */ - u_int16_t bf_bps; /* bytes per sector */ - u_int8_t bf_spc; /* sectors per cluster */ - u_int8_t reserved2[7]; /* unused (zeroed) */ - u_int8_t bf_media; /* media desc. (0xF8) */ - u_int8_t reserved3[2]; - u_int16_t bf_spt; /* sectors per track */ - u_int16_t bf_heads; /* number of heads */ - u_int8_t reserver4[12]; - u_int64_t bf_spv; /* sectors per volume */ - cn_t bf_mftcn; /* $MFT cluster number */ - cn_t bf_mftmirrcn; /* $MFTMirr cn */ - u_int8_t bf_mftrecsz; /* MFT record size (clust) */ - /* 0xF6 inducates 1/4 */ - u_int32_t bf_ibsz; /* index buffer size */ - u_int32_t bf_volsn; /* volume ser. num. */ -}; - -#define NTFS_SYSNODESNUM 0x0B -struct ntfsmount { - struct mount *ntm_mountp; /* filesystem vfs structure */ - struct bootfile ntm_bootfile; - dev_t ntm_dev; /* device mounted */ - struct vnode *ntm_devvp; /* block device mounted vnode */ - struct vnode *ntm_sysvn[NTFS_SYSNODESNUM]; - u_int32_t ntm_bpmftrec; - uid_t ntm_uid; - gid_t ntm_gid; - mode_t ntm_mode; - u_long ntm_flag; - cn_t ntm_cfree; - struct ntvattrdef *ntm_ad; - int ntm_adnum; -#if !defined(__FreeBSD__) - struct netexport ntm_export; /* export information */ -#endif -}; - -#define ntm_mftcn ntm_bootfile.bf_mftcn -#define ntm_mftmirrcn ntm_bootfile.bf_mftmirrcn -#define ntm_mftrecsz ntm_bootfile.bf_mftrecsz -#define ntm_spc ntm_bootfile.bf_spc -#define ntm_bps ntm_bootfile.bf_bps - -#pragma pack() - -#define NTFS_NEXTREC(s, type) ((type)(((caddr_t) s) + (s)->reclen)) - -/* Convert mount ptr to ntfsmount ptr. */ -#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data)) -#define VTONT(v) FTONT(VTOF(v)) -#define VTOF(v) ((struct fnode *)((v)->v_data)) -#define FTOV(f) ((f)->f_vp) -#define FTONT(f) ((f)->f_ip) -#define ntfs_cntobn(cn) (daddr_t)((cn) * (ntmp->ntm_spc)) -#define ntfs_cntob(cn) (off_t)((cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps) -#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) -#define ntfs_btocl(off) (cn_t)((off + ntfs_cntob(1) - 1) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) -#define ntfs_btocnoff(off) (off_t)((off) % ((ntmp)->ntm_spc * (ntmp)->ntm_bps)) -#define ntfs_bntob(bn) (daddr_t)((bn) * (ntmp)->ntm_bps) - -#define ntfs_bpbl (daddr_t)((ntmp)->ntm_bps) - -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_NTFSMNT); -MALLOC_DECLARE(M_NTFSNTNODE); -MALLOC_DECLARE(M_NTFSFNODE); -MALLOC_DECLARE(M_NTFSDIR); -MALLOC_DECLARE(M_NTFSNTHASH); -#endif - -#ifdef __NetBSD__ -#define MALLOC_DEFINE(a, b, c) -#define M_NTFSNTHASH M_NTFS -#define M_NTFSNTVATTR M_NTFS -#define M_NTFSRDATA M_NTFS -#define M_NTFSRUN M_NTFS -#define M_NTFSDECOMP M_NTFS -#define M_NTFSMNT M_NTFS -#define M_NTFSNTNODE M_NTFS -#define M_NTFSFNODE M_NTFS -#define M_NTFSDIR M_NTFS -typedef int (vop_t) __P((void *)); -#define HASHINIT(a, b, c, d) hashinit((a), (b), (c), (d)) -#define bqrelse(bp) brelse(bp) -#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), (b)) -#define VGET(a, b, c) vget((a), (b)) -#define VN_LOCK(a, b, c) vn_lock((a), (b)) -#define LOCKMGR(a, b, c) lockmgr((a), (b), (c)) -#else /* !NetBSD */ -#define HASHINIT(a, b, c, d) hashinit((a), (b), (d)) -#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), (b), (c)) -#define VGET(a, b, c) vget((a), (b), (c)) -#define VN_LOCK(a, b, c) vn_lock((a), (b), (c)) -#define LOCKMGR(a, b, c) lockmgr((a), (b), (c), NULL) -#endif /* NetBSD */ - -#if defined(NTFS_DEBUG) -#define dprintf(a) printf a -#if NTFS_DEBUG > 1 -#define ddprintf(a) printf a -#else -#define ddprintf(a) -#endif -#else -#define dprintf(a) -#define ddprintf(a) -#endif - -extern vop_t **ntfs_vnodeop_p; diff --git a/sys/ntfs/ntfs_compr.c b/sys/ntfs/ntfs_compr.c deleted file mode 100644 index 1d22b54..0000000 --- a/sys/ntfs/ntfs_compr.c +++ /dev/null @@ -1,115 +0,0 @@ -/* $NetBSD: ntfs_compr.c,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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/vnode.h> -#include <sys/mount.h> -#include <sys/file.h> - -#if defined(__NetBSD__) -#include <miscfs/specfs/specdev.h> -#endif - -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_compr.h> - -#define GET_UINT16(addr) (*((u_int16_t *)(addr))) - -int -ntfs_uncompblock( - u_int8_t * buf, - u_int8_t * cbuf) -{ - u_int32_t ctag; - int len, dshift, lmask; - int blen, boff; - int i, j; - int pos, cpos; - - len = GET_UINT16(cbuf) & 0xFFF; - dprintf(("ntfs_uncompblock: block length: %d + 3, 0x%x,0x%04x\n", - len, len, GET_UINT16(cbuf))); - - if (!(GET_UINT16(cbuf) & 0x8000)) { - if ((len + 1) != NTFS_COMPBLOCK_SIZE) { - dprintf(("ntfs_uncompblock: len: %x instead of %d\n", - len, 0xfff)); - } - memcpy(buf, cbuf + 2, len + 1); - bzero(buf + len + 1, NTFS_COMPBLOCK_SIZE - 1 - len); - return len + 3; - } - cpos = 2; - pos = 0; - while ((cpos < len + 3) && (pos < NTFS_COMPBLOCK_SIZE)) { - ctag = cbuf[cpos++]; - for (i = 0; (i < 8) && (pos < NTFS_COMPBLOCK_SIZE); i++) { - if (ctag & 1) { - for (j = pos - 1, lmask = 0xFFF, dshift = 12; - j >= 0x10; j >>= 1) { - dshift--; - lmask >>= 1; - } - boff = -1 - (GET_UINT16(cbuf + cpos) >> dshift); - blen = 3 + (GET_UINT16(cbuf + cpos) & lmask); - for (j = 0; (j < blen) && (pos < NTFS_COMPBLOCK_SIZE); j++) { - buf[pos] = buf[pos + boff]; - pos++; - } - cpos += 2; - } else { - buf[pos++] = cbuf[cpos++]; - } - ctag >>= 1; - } - } - return len + 3; -} - -int -ntfs_uncompunit( - struct ntfsmount * ntmp, - u_int8_t * uup, - u_int8_t * cup) -{ - int i; - int off = 0; - int new; - - for (i = 0; i * NTFS_COMPBLOCK_SIZE < ntfs_cntob(NTFS_COMPUNIT_CL); i++) { - new = ntfs_uncompblock(uup + i * NTFS_COMPBLOCK_SIZE, cup + off); - if (new == 0) - return (EINVAL); - off += new; - } - return (0); -} diff --git a/sys/ntfs/ntfs_compr.h b/sys/ntfs/ntfs_compr.h deleted file mode 100644 index e51bc09..0000000 --- a/sys/ntfs/ntfs_compr.h +++ /dev/null @@ -1,35 +0,0 @@ -/* $NetBSD: ntfs_compr.h,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -#define NTFS_COMPBLOCK_SIZE 0x1000 -#define NTFS_COMPUNIT_CL 16 - -int ntfs_uncompblock(u_int8_t *, u_int8_t *); -int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, u_int8_t *); diff --git a/sys/ntfs/ntfs_ihash.c b/sys/ntfs/ntfs_ihash.c deleted file mode 100644 index fea648c..0000000 --- a/sys/ntfs/ntfs_ihash.c +++ /dev/null @@ -1,134 +0,0 @@ -/* $NetBSD: ntfs_ihash.c,v 1.5 1999/09/30 16:56:40 jdolecek Exp $ */ - -/* - * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995 - * The Regents of the University of California. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95 - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/mutex.h> - -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_ihash.h> - -MALLOC_DEFINE(M_NTFSNTHASH, "NTFS nthash", "NTFS ntnode hash tables"); - -/* - * Structures associated with inode cacheing. - */ -static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl; -static u_long ntfs_nthash; /* size of hash table - 1 */ -#define NTNOHASH(device, inum) (&ntfs_nthashtbl[(minor(device) + (inum)) & ntfs_nthash]) -static struct mtx ntfs_nthash_mtx; -struct lock ntfs_hashlock; - -/* - * Initialize inode hash table. - */ -void -ntfs_nthashinit() -{ - lockinit(&ntfs_hashlock, PINOD, "ntfs_nthashlock", 0, 0); - ntfs_nthashtbl = HASHINIT(desiredvnodes, M_NTFSNTHASH, M_WAITOK, - &ntfs_nthash); - mtx_init(&ntfs_nthash_mtx, "ntfs nthash", MTX_DEF); -} - -/* - * Destroy inode hash table. - */ -void -ntfs_nthashdestroy(void) -{ - lockdestroy(&ntfs_hashlock); - mtx_destroy(&ntfs_nthash_mtx); -} - -/* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, return it, even if it is locked. - */ -struct ntnode * -ntfs_nthashlookup(dev, inum) - dev_t dev; - ino_t inum; -{ - struct ntnode *ip; - - mtx_lock(&ntfs_nthash_mtx); - LIST_FOREACH(ip, NTNOHASH(dev, inum), i_hash) - if (inum == ip->i_number && dev == ip->i_dev) - break; - mtx_unlock(&ntfs_nthash_mtx); - - return (ip); -} - -/* - * Insert the ntnode into the hash table. - */ -void -ntfs_nthashins(ip) - struct ntnode *ip; -{ - struct nthashhead *ipp; - - mtx_lock(&ntfs_nthash_mtx); - ipp = NTNOHASH(ip->i_dev, ip->i_number); - LIST_INSERT_HEAD(ipp, ip, i_hash); - ip->i_flag |= IN_HASHED; - mtx_unlock(&ntfs_nthash_mtx); -} - -/* - * Remove the inode from the hash table. - */ -void -ntfs_nthashrem(ip) - struct ntnode *ip; -{ - mtx_lock(&ntfs_nthash_mtx); - if (ip->i_flag & IN_HASHED) { - ip->i_flag &= ~IN_HASHED; - LIST_REMOVE(ip, i_hash); - } - mtx_unlock(&ntfs_nthash_mtx); -} diff --git a/sys/ntfs/ntfs_ihash.h b/sys/ntfs/ntfs_ihash.h deleted file mode 100644 index a3f166f..0000000 --- a/sys/ntfs/ntfs_ihash.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $NetBSD: ntfs_ihash.h,v 1.4 1999/09/30 16:56:40 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -extern struct lock ntfs_hashlock; -void ntfs_nthashinit __P((void)); -void ntfs_nthashdestroy __P((void)); -struct ntnode *ntfs_nthashlookup __P((dev_t, ino_t)); -struct ntnode *ntfs_nthashget __P((dev_t, ino_t)); -void ntfs_nthashins __P((struct ntnode *)); -void ntfs_nthashrem __P((register struct ntnode *)); diff --git a/sys/ntfs/ntfs_inode.h b/sys/ntfs/ntfs_inode.h deleted file mode 100644 index a865276..0000000 --- a/sys/ntfs/ntfs_inode.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $NetBSD: ntfs_inode.h,v 1.8 1999/10/31 19:45:26 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -/* These flags are kept in i_flag. */ -#if defined(__FreeBSD__) -#define IN_ACCESS 0x0001 /* Access time update request. */ -#define IN_CHANGE 0x0002 /* Inode change time update request. */ -#define IN_UPDATE 0x0004 /* Modification time update request. */ -#define IN_MODIFIED 0x0008 /* Inode has been modified. */ -#define IN_RENAME 0x0010 /* Inode is being renamed. */ -#define IN_SHLOCK 0x0020 /* File has shared lock. */ -#define IN_EXLOCK 0x0040 /* File has exclusive lock. */ -#define IN_LAZYMOD 0x0080 /* Modified, but don't write yet. */ -#else /* defined(__NetBSD__) */ -#define IN_ACCESS 0x0001 /* Access time update request. */ -#define IN_CHANGE 0x0002 /* Inode change time update request. */ -#define IN_EXLOCK 0x0004 /* File has exclusive lock. */ -#define IN_LOCKED 0x0008 /* Inode lock. */ -#define IN_LWAIT 0x0010 /* Process waiting on file lock. */ -#define IN_MODIFIED 0x0020 /* Inode has been modified. */ -#define IN_RENAME 0x0040 /* Inode is being renamed. */ -#define IN_SHLOCK 0x0080 /* File has shared lock. */ -#define IN_UPDATE 0x0100 /* Modification time update request. */ -#define IN_WANTED 0x0200 /* Inode is wanted by a process. */ -#define IN_RECURSE 0x0400 /* Recursion expected */ -#endif - -#define IN_HASHED 0x0800 /* Inode is on hash list */ -#define IN_LOADED 0x8000 /* ntvattrs loaded */ -#define IN_PRELOADED 0x4000 /* loaded from directory entry */ - -struct ntnode { - struct vnode *i_devvp; /* vnode of blk dev we live on */ - dev_t i_dev; /* Device associated with the inode. */ - - LIST_ENTRY(ntnode) i_hash; - struct ntnode *i_next; - struct ntnode **i_prev; - struct ntfsmount *i_mp; - ino_t i_number; - u_int32_t i_flag; - - /* locking */ - struct lock i_lock; - struct mtx i_interlock; - int i_usecount; - - LIST_HEAD(,fnode) i_fnlist; - LIST_HEAD(,ntvattr) i_valist; - - long i_nlink; /* MFR */ - ino_t i_mainrec; /* MFR */ - u_int32_t i_frflag; /* MFR */ -}; - -#define FN_PRELOADED 0x0001 -#define FN_VALID 0x0002 -#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */ -struct fnode { -#ifdef __FreeBSD__ - struct lock f_lock; /* fnode lock >Keep this first< */ -#endif - - LIST_ENTRY(fnode) f_fnlist; - struct vnode *f_vp; /* Associatied vnode */ - struct ntnode *f_ip; /* Associated ntnode */ - u_long f_flag; - - ntfs_times_t f_times; /* $NAME/dirinfo */ - ino_t f_pnumber; /* $NAME/dirinfo */ - u_int32_t f_fflag; /* $NAME/dirinfo */ - u_int64_t f_size; /* defattr/dirinfo: */ - u_int64_t f_allocated; /* defattr/dirinfo */ - - u_int32_t f_attrtype; - char *f_attrname; - - /* for ntreaddir */ - u_int32_t f_lastdattr; - u_int32_t f_lastdblnum; - u_int32_t f_lastdoff; - u_int32_t f_lastdnum; - caddr_t f_dirblbuf; - u_int32_t f_dirblsz; -}; - -/* This overlays the fid structure (see <sys/mount.h>) */ -struct ntfid { - u_int16_t ntfid_len; /* Length of structure. */ - u_int16_t ntfid_pad; /* Force 32-bit alignment. */ - ino_t ntfid_ino; /* File number (ino). */ - int32_t ntfid_gen; /* Generation number. */ -}; diff --git a/sys/ntfs/ntfs_subr.c b/sys/ntfs/ntfs_subr.c deleted file mode 100644 index c55cd0a..0000000 --- a/sys/ntfs/ntfs_subr.c +++ /dev/null @@ -1,2007 +0,0 @@ -/* $NetBSD: ntfs_subr.c,v 1.23 1999/10/31 19:45:26 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org) - * 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/types.h> -#include <sys/systm.h> -#include <sys/namei.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/file.h> -#include <sys/malloc.h> -#include <sys/lock.h> - -#if defined(__NetBSD__) -#include <miscfs/specfs/specdev.h> -#endif - -/* #define NTFS_DEBUG 1 */ -#include <ntfs/ntfs.h> -#include <ntfs/ntfsmount.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_vfsops.h> -#include <ntfs/ntfs_subr.h> -#include <ntfs/ntfs_compr.h> -#include <ntfs/ntfs_ihash.h> - -#if defined(__FreeBSD__) -MALLOC_DEFINE(M_NTFSNTVATTR, "NTFS vattr", "NTFS file attribute information"); -MALLOC_DEFINE(M_NTFSRDATA, "NTFS res data", "NTFS resident data"); -MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage"); -MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary"); -#endif - -static int ntfs_ntlookupattr __P((struct ntfsmount *, const char *, int, int *, char **)); -static int ntfs_findvattr __P((struct ntfsmount *, struct ntnode *, struct ntvattr **, struct ntvattr **, u_int32_t, const char *, size_t, cn_t)); -static int ntfs_uastricmp __P((const wchar *, size_t, const char *, size_t)); -static int ntfs_uastrcmp __P((const wchar *, size_t, const char *, size_t)); - -/* table for mapping Unicode chars into uppercase; it's filled upon first - * ntfs mount, freed upon last ntfs umount */ -static wchar *ntfs_toupper_tab; -#define NTFS_U28(ch) ((((ch) & 0xFF) == 0) ? '_' : (ch) & 0xFF) -#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(unsigned char)(ch)]) -static struct lock ntfs_toupper_lock; -static signed int ntfs_toupper_usecount; - -/* support macro for ntfs_ntvattrget() */ -#define NTFS_AALPCMP(aalp,type,name,namelen) ( \ - (aalp->al_type == type) && (aalp->al_namelen == namelen) && \ - !ntfs_uastrcmp(aalp->al_name,aalp->al_namelen,name,namelen) ) - -/* - * - */ -int -ntfs_ntvattrrele(vap) - struct ntvattr * vap; -{ - dprintf(("ntfs_ntvattrrele: ino: %d, type: 0x%x\n", - vap->va_ip->i_number, vap->va_type)); - - ntfs_ntrele(vap->va_ip); - - return (0); -} - -/* - * find the attribute in the ntnode - */ -static int -ntfs_findvattr(ntmp, ip, lvapp, vapp, type, name, namelen, vcn) - struct ntfsmount *ntmp; - struct ntnode *ip; - struct ntvattr **lvapp, **vapp; - u_int32_t type; - const char *name; - size_t namelen; - cn_t vcn; -{ - int error; - struct ntvattr *vap; - - if((ip->i_flag & IN_LOADED) == 0) { - dprintf(("ntfs_findvattr: node not loaded, ino: %d\n", - ip->i_number)); - error = ntfs_loadntnode(ntmp,ip); - if (error) { - printf("ntfs_findvattr: FAILED TO LOAD INO: %d\n", - ip->i_number); - return (error); - } - } - - *lvapp = NULL; - *vapp = NULL; - LIST_FOREACH(vap, &ip->i_valist, va_list) { - ddprintf(("ntfs_findvattr: type: 0x%x, vcn: %d - %d\n", \ - vap->va_type, (u_int32_t) vap->va_vcnstart, \ - (u_int32_t) vap->va_vcnend)); - if ((vap->va_type == type) && - (vap->va_vcnstart <= vcn) && (vap->va_vcnend >= vcn) && - (vap->va_namelen == namelen) && - (strncmp(name, vap->va_name, namelen) == 0)) { - *vapp = vap; - ntfs_ntref(vap->va_ip); - return (0); - } - if (vap->va_type == NTFS_A_ATTRLIST) - *lvapp = vap; - } - - return (-1); -} - -/* - * Search attribute specifed in ntnode (load ntnode if nessecary). - * If not found but ATTR_A_ATTRLIST present, read it in and search throught. - * VOP_VGET node needed, and lookup througth it's ntnode (load if nessesary). - * - * ntnode should be locked - */ -int -ntfs_ntvattrget( - struct ntfsmount * ntmp, - struct ntnode * ip, - u_int32_t type, - const char *name, - cn_t vcn, - struct ntvattr ** vapp) -{ - struct ntvattr *lvap = NULL; - struct attr_attrlist *aalp; - struct attr_attrlist *nextaalp; - struct vnode *newvp; - struct ntnode *newip; - caddr_t alpool; - size_t namelen, len; - int error; - - *vapp = NULL; - - if (name) { - dprintf(("ntfs_ntvattrget: " \ - "ino: %d, type: 0x%x, name: %s, vcn: %d\n", \ - ip->i_number, type, name, (u_int32_t) vcn)); - namelen = strlen(name); - } else { - dprintf(("ntfs_ntvattrget: " \ - "ino: %d, type: 0x%x, vcn: %d\n", \ - ip->i_number, type, (u_int32_t) vcn)); - name = ""; - namelen = 0; - } - - error = ntfs_findvattr(ntmp, ip, &lvap, vapp, type, name, namelen, vcn); - if (error >= 0) - return (error); - - if (!lvap) { - dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \ - "ino: %d, type: 0x%x, name: %s, vcn: %d\n", \ - ip->i_number, type, name, (u_int32_t) vcn)); - return (ENOENT); - } - /* Scan $ATTRIBUTE_LIST for requested attribute */ - len = lvap->va_datalen; - MALLOC(alpool, caddr_t, len, M_TEMP, M_WAITOK); - error = ntfs_readntvattr_plain(ntmp, ip, lvap, 0, len, alpool, &len, - NULL); - if (error) - goto out; - - aalp = (struct attr_attrlist *) alpool; - nextaalp = NULL; - - for(; len > 0; aalp = nextaalp) { - dprintf(("ntfs_ntvattrget: " \ - "attrlist: ino: %d, attr: 0x%x, vcn: %d\n", \ - aalp->al_inumber, aalp->al_type, \ - (u_int32_t) aalp->al_vcnstart)); - - if (len > aalp->reclen) { - nextaalp = NTFS_NEXTREC(aalp, struct attr_attrlist *); - } else { - nextaalp = NULL; - } - len -= aalp->reclen; - - if (!NTFS_AALPCMP(aalp, type, name, namelen) || - (nextaalp && (nextaalp->al_vcnstart <= vcn) && - NTFS_AALPCMP(nextaalp, type, name, namelen))) - continue; - - dprintf(("ntfs_ntvattrget: attribute in ino: %d\n", - aalp->al_inumber)); - - /* this is not a main record, so we can't use just plain - vget() */ - error = ntfs_vgetex(ntmp->ntm_mountp, aalp->al_inumber, - NTFS_A_DATA, NULL, LK_EXCLUSIVE, - VG_EXT, curproc, &newvp); - if (error) { - printf("ntfs_ntvattrget: CAN'T VGET INO: %d\n", - aalp->al_inumber); - goto out; - } - newip = VTONT(newvp); - /* XXX have to lock ntnode */ - error = ntfs_findvattr(ntmp, newip, &lvap, vapp, - type, name, namelen, vcn); - vput(newvp); - if (error == 0) - goto out; - printf("ntfs_ntvattrget: ATTRLIST ERROR.\n"); - break; - } - error = ENOENT; - - dprintf(("ntfs_ntvattrget: UNEXISTED ATTRIBUTE: " \ - "ino: %d, type: 0x%x, name: %.*s, vcn: %d\n", \ - ip->i_number, type, (int) namelen, name, (u_int32_t) vcn)); -out: - FREE(alpool, M_TEMP); - return (error); -} - -/* - * Read ntnode from disk, make ntvattr list. - * - * ntnode should be locked - */ -int -ntfs_loadntnode( - struct ntfsmount * ntmp, - struct ntnode * ip) -{ - struct filerec *mfrp; - daddr_t bn; - int error,off; - struct attr *ap; - struct ntvattr *nvap; - - dprintf(("ntfs_loadntnode: loading ino: %d\n",ip->i_number)); - - MALLOC(mfrp, struct filerec *, ntfs_bntob(ntmp->ntm_bpmftrec), - M_TEMP, M_WAITOK); - - if (ip->i_number < NTFS_SYSNODESNUM) { - struct buf *bp; - - dprintf(("ntfs_loadntnode: read system node\n")); - - bn = ntfs_cntobn(ntmp->ntm_mftcn) + - ntmp->ntm_bpmftrec * ip->i_number; - - error = bread(ntmp->ntm_devvp, - bn, ntfs_bntob(ntmp->ntm_bpmftrec), - NOCRED, &bp); - if (error) { - printf("ntfs_loadntnode: BREAD FAILED\n"); - brelse(bp); - goto out; - } - memcpy(mfrp, bp->b_data, ntfs_bntob(ntmp->ntm_bpmftrec)); - bqrelse(bp); - } else { - struct vnode *vp; - - vp = ntmp->ntm_sysvn[NTFS_MFTINO]; - error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, - ip->i_number * ntfs_bntob(ntmp->ntm_bpmftrec), - ntfs_bntob(ntmp->ntm_bpmftrec), mfrp, NULL); - if (error) { - printf("ntfs_loadntnode: ntfs_readattr failed\n"); - goto out; - } - } - - /* Check if magic and fixups are correct */ - error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp, - ntfs_bntob(ntmp->ntm_bpmftrec)); - if (error) { - printf("ntfs_loadntnode: BAD MFT RECORD %d\n", - (u_int32_t) ip->i_number); - goto out; - } - - dprintf(("ntfs_loadntnode: load attrs for ino: %d\n",ip->i_number)); - off = mfrp->fr_attroff; - ap = (struct attr *) ((caddr_t)mfrp + off); - - LIST_INIT(&ip->i_valist); - - while (ap->a_hdr.a_type != -1) { - error = ntfs_attrtontvattr(ntmp, &nvap, ap); - if (error) - break; - nvap->va_ip = ip; - - LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list); - - off += ap->a_hdr.reclen; - ap = (struct attr *) ((caddr_t)mfrp + off); - } - if (error) { - printf("ntfs_loadntnode: failed to load attr ino: %d\n", - ip->i_number); - goto out; - } - - ip->i_mainrec = mfrp->fr_mainrec; - ip->i_nlink = mfrp->fr_nlink; - ip->i_frflag = mfrp->fr_flags; - - ip->i_flag |= IN_LOADED; - -out: - FREE(mfrp, M_TEMP); - return (error); -} - -/* - * Routine locks ntnode and increase usecount, just opposite of - * ntfs_ntput(). - */ -int -ntfs_ntget(ip) - struct ntnode *ip; -{ - dprintf(("ntfs_ntget: get ntnode %d: %p, usecount: %d\n", - ip->i_number, ip, ip->i_usecount)); - - mtx_lock(&ip->i_interlock); - ip->i_usecount++; - LOCKMGR(&ip->i_lock, LK_EXCLUSIVE | LK_INTERLOCK, &ip->i_interlock); - - return 0; -} - -/* - * Routine search ntnode in hash, if found: lock, inc usecount and return. - * If not in hash allocate structure for ntnode, prefill it, lock, - * inc count and return. - * - * ntnode returned locked - */ -int -ntfs_ntlookup( - struct ntfsmount * ntmp, - ino_t ino, - struct ntnode ** ipp) -{ - struct ntnode *ip; - - dprintf(("ntfs_ntlookup: looking for ntnode %d\n", ino)); - - do { - if ((ip = ntfs_nthashlookup(ntmp->ntm_dev, ino)) != NULL) { - ntfs_ntget(ip); - dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n", - ino, ip, ip->i_usecount)); - *ipp = ip; - return (0); - } - } while (LOCKMGR(&ntfs_hashlock, LK_EXCLUSIVE | LK_SLEEPFAIL, NULL)); - - MALLOC(ip, struct ntnode *, sizeof(struct ntnode), M_NTFSNTNODE, - M_WAITOK | M_ZERO); - ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip)); - - /* Generic initialization */ - ip->i_devvp = ntmp->ntm_devvp; - ip->i_dev = ntmp->ntm_dev; - ip->i_number = ino; - ip->i_mp = ntmp; - - LIST_INIT(&ip->i_fnlist); - - /* init lock and lock the newborn ntnode */ - lockinit(&ip->i_lock, PINOD, "ntnode", 0, LK_EXCLUSIVE); - mtx_init(&ip->i_interlock, "ntnode interlock", MTX_DEF); - ntfs_ntget(ip); - - ntfs_nthashins(ip); - - LOCKMGR(&ntfs_hashlock, LK_RELEASE, NULL); - - *ipp = ip; - - dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n", - ino, ip, ip->i_usecount)); - - return (0); -} - -/* - * Decrement usecount of ntnode and unlock it, if usecount reach zero, - * deallocate ntnode. - * - * ntnode should be locked on entry, and unlocked on return. - */ -void -ntfs_ntput(ip) - struct ntnode *ip; -{ - struct ntvattr *vap; - - dprintf(("ntfs_ntput: rele ntnode %d: %p, usecount: %d\n", - ip->i_number, ip, ip->i_usecount)); - - mtx_lock(&ip->i_interlock); - ip->i_usecount--; - -#ifdef DIAGNOSTIC - if (ip->i_usecount < 0) { - panic("ntfs_ntput: ino: %d usecount: %d \n", - ip->i_number,ip->i_usecount); - } -#endif - - if (ip->i_usecount == 0) { - dprintf(("ntfs_ntput: deallocating ntnode: %d\n", - ip->i_number)); - - if (LIST_FIRST(&ip->i_fnlist)) - panic("ntfs_ntput: ntnode has fnodes\n"); - - ntfs_nthashrem(ip); - - while (LIST_FIRST(&ip->i_valist) != NULL) { - vap = LIST_FIRST(&ip->i_valist); - LIST_REMOVE(vap,va_list); - ntfs_freentvattr(vap); - } - mtx_unlock(&ip->i_interlock); - mtx_destroy(&ip->i_interlock); - lockdestroy(&ip->i_lock); - - FREE(ip, M_NTFSNTNODE); - } else { - LOCKMGR(&ip->i_lock, LK_RELEASE|LK_INTERLOCK, &ip->i_interlock); - } -} - -/* - * increment usecount of ntnode - */ -void -ntfs_ntref(ip) - struct ntnode *ip; -{ - mtx_lock(&ip->i_interlock); - ip->i_usecount++; - mtx_unlock(&ip->i_interlock); - - dprintf(("ntfs_ntref: ino %d, usecount: %d\n", - ip->i_number, ip->i_usecount)); - -} - -/* - * Decrement usecount of ntnode. - */ -void -ntfs_ntrele(ip) - struct ntnode *ip; -{ - dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n", - ip->i_number, ip, ip->i_usecount)); - - mtx_lock(&ip->i_interlock); - ip->i_usecount--; - - if (ip->i_usecount < 0) - panic("ntfs_ntrele: ino: %d usecount: %d \n", - ip->i_number,ip->i_usecount); - mtx_unlock(&ip->i_interlock); -} - -/* - * Deallocate all memory allocated for ntvattr - */ -void -ntfs_freentvattr(vap) - struct ntvattr * vap; -{ - if (vap->va_flag & NTFS_AF_INRUN) { - if (vap->va_vruncn) - FREE(vap->va_vruncn, M_NTFSRUN); - if (vap->va_vruncl) - FREE(vap->va_vruncl, M_NTFSRUN); - } else { - if (vap->va_datap) - FREE(vap->va_datap, M_NTFSRDATA); - } - FREE(vap, M_NTFSNTVATTR); -} - -/* - * Convert disk image of attribute into ntvattr structure, - * runs are expanded also. - */ -int -ntfs_attrtontvattr( - struct ntfsmount * ntmp, - struct ntvattr ** rvapp, - struct attr * rap) -{ - int error, i; - struct ntvattr *vap; - - error = 0; - *rvapp = NULL; - - MALLOC(vap, struct ntvattr *, sizeof(struct ntvattr), - M_NTFSNTVATTR, M_WAITOK | M_ZERO); - vap->va_ip = NULL; - vap->va_flag = rap->a_hdr.a_flag; - vap->va_type = rap->a_hdr.a_type; - vap->va_compression = rap->a_hdr.a_compression; - vap->va_index = rap->a_hdr.a_index; - - ddprintf(("type: 0x%x, index: %d", vap->va_type, vap->va_index)); - - vap->va_namelen = rap->a_hdr.a_namelen; - if (rap->a_hdr.a_namelen) { - wchar *unp = (wchar *) ((caddr_t) rap + rap->a_hdr.a_nameoff); - ddprintf((", name:[")); - for (i = 0; i < vap->va_namelen; i++) { - vap->va_name[i] = unp[i]; - ddprintf(("%c", vap->va_name[i])); - } - ddprintf(("]")); - } - if (vap->va_flag & NTFS_AF_INRUN) { - ddprintf((", nonres.")); - vap->va_datalen = rap->a_nr.a_datalen; - vap->va_allocated = rap->a_nr.a_allocated; - vap->va_vcnstart = rap->a_nr.a_vcnstart; - vap->va_vcnend = rap->a_nr.a_vcnend; - vap->va_compressalg = rap->a_nr.a_compressalg; - error = ntfs_runtovrun(&(vap->va_vruncn), &(vap->va_vruncl), - &(vap->va_vruncnt), - (caddr_t) rap + rap->a_nr.a_dataoff); - } else { - vap->va_compressalg = 0; - ddprintf((", res.")); - vap->va_datalen = rap->a_r.a_datalen; - vap->va_allocated = rap->a_r.a_datalen; - vap->va_vcnstart = 0; - vap->va_vcnend = ntfs_btocn(vap->va_allocated); - MALLOC(vap->va_datap, caddr_t, vap->va_datalen, - M_NTFSRDATA, M_WAITOK); - memcpy(vap->va_datap, (caddr_t) rap + rap->a_r.a_dataoff, - rap->a_r.a_datalen); - } - ddprintf((", len: %d", vap->va_datalen)); - - if (error) - FREE(vap, M_NTFSNTVATTR); - else - *rvapp = vap; - - ddprintf(("\n")); - - return (error); -} - -/* - * Expand run into more utilizable and more memory eating format. - */ -int -ntfs_runtovrun( - cn_t ** rcnp, - cn_t ** rclp, - u_long * rcntp, - u_int8_t * run) -{ - u_int32_t off; - u_int32_t sz, i; - cn_t *cn; - cn_t *cl; - u_long cnt; - cn_t prev; - cn_t tmp; - - off = 0; - cnt = 0; - i = 0; - while (run[off]) { - off += (run[off] & 0xF) + ((run[off] >> 4) & 0xF) + 1; - cnt++; - } - MALLOC(cn, cn_t *, cnt * sizeof(cn_t), M_NTFSRUN, M_WAITOK); - MALLOC(cl, cn_t *, cnt * sizeof(cn_t), M_NTFSRUN, M_WAITOK); - - off = 0; - cnt = 0; - prev = 0; - while (run[off]) { - - sz = run[off++]; - cl[cnt] = 0; - - for (i = 0; i < (sz & 0xF); i++) - cl[cnt] += (u_int32_t) run[off++] << (i << 3); - - sz >>= 4; - if (run[off + sz - 1] & 0x80) { - tmp = ((u_int64_t) - 1) << (sz << 3); - for (i = 0; i < sz; i++) - tmp |= (u_int64_t) run[off++] << (i << 3); - } else { - tmp = 0; - for (i = 0; i < sz; i++) - tmp |= (u_int64_t) run[off++] << (i << 3); - } - if (tmp) - prev = cn[cnt] = prev + tmp; - else - cn[cnt] = tmp; - - cnt++; - } - *rcnp = cn; - *rclp = cl; - *rcntp = cnt; - return (0); -} - -/* - * Compare unicode and ascii string case insens. - */ -static int -ntfs_uastricmp(ustr, ustrlen, astr, astrlen) - const wchar *ustr; - size_t ustrlen; - const char *astr; - size_t astrlen; -{ - size_t i; - int res; - - for (i = 0; i < ustrlen && i < astrlen; i++) { - res = ((int) NTFS_TOUPPER(NTFS_U28(ustr[i]))) - - ((int)NTFS_TOUPPER(astr[i])); - if (res) - return res; - } - return (ustrlen - astrlen); -} - -/* - * Compare unicode and ascii string case sens. - */ -static int -ntfs_uastrcmp(ustr, ustrlen, astr, astrlen) - const wchar *ustr; - size_t ustrlen; - const char *astr; - size_t astrlen; -{ - size_t i; - int res; - - for (i = 0; (i < ustrlen) && (i < astrlen); i++) { - res = (int) (((char)NTFS_U28(ustr[i])) - astr[i]); - if (res) - return res; - } - return (ustrlen - astrlen); -} - -/* - * Search fnode in ntnode, if not found allocate and preinitialize. - * - * ntnode should be locked on entry. - */ -int -ntfs_fget( - struct ntfsmount *ntmp, - struct ntnode *ip, - int attrtype, - char *attrname, - struct fnode **fpp) -{ - struct fnode *fp; - - dprintf(("ntfs_fget: ino: %d, attrtype: 0x%x, attrname: %s\n", - ip->i_number,attrtype, attrname?attrname:"")); - *fpp = NULL; - LIST_FOREACH(fp, &ip->i_fnlist, f_fnlist){ - dprintf(("ntfs_fget: fnode: attrtype: %d, attrname: %s\n", - fp->f_attrtype, fp->f_attrname?fp->f_attrname:"")); - - if ((attrtype == fp->f_attrtype) && - ((!attrname && !fp->f_attrname) || - (attrname && fp->f_attrname && - !strcmp(attrname,fp->f_attrname)))){ - dprintf(("ntfs_fget: found existed: %p\n",fp)); - *fpp = fp; - } - } - - if (*fpp) - return (0); - - MALLOC(fp, struct fnode *, sizeof(struct fnode), M_NTFSFNODE, - M_WAITOK | M_ZERO); - dprintf(("ntfs_fget: allocating fnode: %p\n",fp)); - - fp->f_ip = ip; - fp->f_attrname = attrname; - if (fp->f_attrname) fp->f_flag |= FN_AATTRNAME; - fp->f_attrtype = attrtype; - - ntfs_ntref(ip); - - LIST_INSERT_HEAD(&ip->i_fnlist, fp, f_fnlist); - - *fpp = fp; - - return (0); -} - -/* - * Deallocate fnode, remove it from ntnode's fnode list. - * - * ntnode should be locked. - */ -void -ntfs_frele( - struct fnode *fp) -{ - struct ntnode *ip = FTONT(fp); - - dprintf(("ntfs_frele: fnode: %p for %d: %p\n", fp, ip->i_number, ip)); - - dprintf(("ntfs_frele: deallocating fnode\n")); - LIST_REMOVE(fp,f_fnlist); - if (fp->f_flag & FN_AATTRNAME) - FREE(fp->f_attrname, M_TEMP); - if (fp->f_dirblbuf) - FREE(fp->f_dirblbuf, M_NTFSDIR); -#ifdef __FreeBSD__ - lockdestroy(&fp->f_lock); -#endif - FREE(fp, M_NTFSFNODE); - ntfs_ntrele(ip); -} - -/* - * Lookup attribute name in format: [[:$ATTR_TYPE]:$ATTR_NAME], - * $ATTR_TYPE is searched in attrdefs read from $AttrDefs. - * If $ATTR_TYPE nott specifed, ATTR_A_DATA assumed. - */ -static int -ntfs_ntlookupattr( - struct ntfsmount * ntmp, - const char * name, - int namelen, - int *attrtype, - char **attrname) -{ - const char *sys; - size_t syslen, i; - struct ntvattrdef *adp; - - if (namelen == 0) - return (0); - - if (name[0] == '$') { - sys = name; - for (syslen = 0; syslen < namelen; syslen++) { - if(sys[syslen] == ':') { - name++; - namelen--; - break; - } - } - name += syslen; - namelen -= syslen; - - adp = ntmp->ntm_ad; - for (i = 0; i < ntmp->ntm_adnum; i++, adp++){ - if (syslen != adp->ad_namelen || - strncmp(sys, adp->ad_name, syslen) != 0) - continue; - - *attrtype = adp->ad_type; - goto out; - } - return (ENOENT); - } - - out: - if (namelen) { - MALLOC((*attrname), char *, namelen, M_TEMP, M_WAITOK); - memcpy((*attrname), name, namelen); - (*attrname)[namelen] = '\0'; - *attrtype = NTFS_A_DATA; - } - - return (0); -} - -/* - * Lookup specifed node for filename, matching cnp, - * return fnode filled. - */ -int -ntfs_ntlookupfile( - struct ntfsmount * ntmp, - struct vnode * vp, - struct componentname * cnp, - struct vnode ** vpp) -{ - struct fnode *fp = VTOF(vp); - struct ntnode *ip = FTONT(fp); - struct ntvattr *vap; /* Root attribute */ - cn_t cn; /* VCN in current attribute */ - caddr_t rdbuf; /* Buffer to read directory's blocks */ - u_int32_t blsize; - u_int32_t rdsize; /* Length of data to read from current block */ - struct attr_indexentry *iep; - int error, res, anamelen, fnamelen; - const char *fname,*aname; - u_int32_t aoff; - int attrtype = NTFS_A_DATA; - char *attrname = NULL; - struct fnode *nfp; - struct vnode *nvp; - enum vtype f_type; - - error = ntfs_ntget(ip); - if (error) - return (error); - - error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap); - if (error || (vap->va_flag & NTFS_AF_INRUN)) - return (ENOTDIR); - - blsize = vap->va_a_iroot->ir_size; - rdsize = vap->va_datalen; - - /* - * Divide file name into: foofilefoofilefoofile[:attrspec] - * Store like this: fname:fnamelen [aname:anamelen] - */ - fname = cnp->cn_nameptr; - aname = NULL; - anamelen = 0; - for (fnamelen = 0; fnamelen < cnp->cn_namelen; fnamelen++) - if(fname[fnamelen] == ':') { - aname = fname + fnamelen + 1; - anamelen = cnp->cn_namelen - fnamelen - 1; - dprintf(("ntfs_ntlookupfile: %s (%d), attr: %s (%d)\n", - fname, fnamelen, aname, anamelen)); - break; - } - - dprintf(("ntfs_ntlookupfile: blksz: %d, rdsz: %d\n", blsize, rdsize)); - - MALLOC(rdbuf, caddr_t, blsize, M_TEMP, M_WAITOK); - - error = ntfs_readattr(ntmp, ip, NTFS_A_INDXROOT, "$I30", - 0, rdsize, rdbuf, NULL); - if (error) - goto fail; - - aoff = sizeof(struct attr_indexroot); - - do { - iep = (struct attr_indexentry *) (rdbuf + aoff); - - for (; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (rdsize > aoff); - aoff += iep->reclen, - iep = (struct attr_indexentry *) (rdbuf + aoff)) - { - ddprintf(("scan: %d, %d\n", - (u_int32_t) iep->ie_number, - (u_int32_t) iep->ie_fnametype)); - - /* check the name - the case-insensitible check - * has to come first, to break from this for loop - * if needed, so we can dive correctly */ - res = ntfs_uastricmp(iep->ie_fname, iep->ie_fnamelen, - fname, fnamelen); - if (res > 0) break; - if (res < 0) continue; - - if (iep->ie_fnametype == 0 || - !(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)) - { - res = ntfs_uastrcmp(iep->ie_fname, - iep->ie_fnamelen, fname, fnamelen); - if (res != 0) continue; - } - - if (aname) { - error = ntfs_ntlookupattr(ntmp, - aname, anamelen, - &attrtype, &attrname); - if (error) - goto fail; - } - - /* Check if we've found ourself */ - if ((iep->ie_number == ip->i_number) && - (attrtype == fp->f_attrtype) && - ((!attrname && !fp->f_attrname) || - (attrname && fp->f_attrname && - !strcmp(attrname, fp->f_attrname)))) - { - VREF(vp); - *vpp = vp; - error = 0; - goto fail; - } - - /* free the buffer returned by ntfs_ntlookupattr() */ - if (attrname) { - FREE(attrname, M_TEMP); - attrname = NULL; - } - - /* vget node, but don't load it */ - error = ntfs_vgetex(ntmp->ntm_mountp, - iep->ie_number, attrtype, attrname, - LK_EXCLUSIVE, VG_DONTLOADIN | VG_DONTVALIDFN, - curproc, &nvp); - if (error) - goto fail; - - nfp = VTOF(nvp); - - if (nfp->f_flag & FN_VALID) { - *vpp = nvp; - goto fail; - } - - nfp->f_fflag = iep->ie_fflag; - nfp->f_pnumber = iep->ie_fpnumber; - nfp->f_times = iep->ie_ftimes; - - if((nfp->f_fflag & NTFS_FFLAG_DIR) && - (nfp->f_attrtype == NTFS_A_DATA) && - (nfp->f_attrname == NULL)) - f_type = VDIR; - else - f_type = VREG; - - nvp->v_type = f_type; - - if ((nfp->f_attrtype == NTFS_A_DATA) && - (nfp->f_attrname == NULL)) - { - /* Opening default attribute */ - nfp->f_size = iep->ie_fsize; - nfp->f_allocated = iep->ie_fallocated; - nfp->f_flag |= FN_PRELOADED; - } else { - error = ntfs_filesize(ntmp, nfp, - &nfp->f_size, &nfp->f_allocated); - if (error) { - vput(nvp); - goto fail; - } - } - - nfp->f_flag &= ~FN_VALID; - *vpp = nvp; - goto fail; - } - - /* Dive if possible */ - if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) { - dprintf(("ntfs_ntlookupfile: diving\n")); - - cn = *(cn_t *) (rdbuf + aoff + - iep->reclen - sizeof(cn_t)); - rdsize = blsize; - - error = ntfs_readattr(ntmp, ip, NTFS_A_INDX, "$I30", - ntfs_cntob(cn), rdsize, rdbuf, NULL); - if (error) - goto fail; - - error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC, - rdbuf, rdsize); - if (error) - goto fail; - - aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize + - 0x18); - } else { - dprintf(("ntfs_ntlookupfile: nowhere to dive :-(\n")); - error = ENOENT; - break; - } - } while (1); - - dprintf(("finish\n")); - -fail: - if (attrname) FREE(attrname, M_TEMP); - ntfs_ntvattrrele(vap); - ntfs_ntput(ip); - FREE(rdbuf, M_TEMP); - return (error); -} - -/* - * Check if name type is permitted to show. - */ -int -ntfs_isnamepermitted( - struct ntfsmount * ntmp, - struct attr_indexentry * iep) -{ - if (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES) - return 1; - - switch (iep->ie_fnametype) { - case 2: - ddprintf(("ntfs_isnamepermitted: skiped DOS name\n")); - return 0; - case 0: case 1: case 3: - return 1; - default: - printf("ntfs_isnamepermitted: " \ - "WARNING! Unknown file name type: %d\n", - iep->ie_fnametype); - break; - } - return 0; -} - -/* - * Read ntfs dir like stream of attr_indexentry, not like btree of them. - * This is done by scaning $BITMAP:$I30 for busy clusters and reading them. - * Ofcouse $INDEX_ROOT:$I30 is read before. Last read values are stored in - * fnode, so we can skip toward record number num almost immediatly. - * Anyway this is rather slow routine. The problem is that we don't know - * how many records are there in $INDEX_ALLOCATION:$I30 block. - */ -int -ntfs_ntreaddir( - struct ntfsmount * ntmp, - struct fnode * fp, - u_int32_t num, - struct attr_indexentry ** riepp) -{ - struct ntnode *ip = FTONT(fp); - struct ntvattr *vap = NULL; /* IndexRoot attribute */ - struct ntvattr *bmvap = NULL; /* BitMap attribute */ - struct ntvattr *iavap = NULL; /* IndexAllocation attribute */ - caddr_t rdbuf; /* Buffer to read directory's blocks */ - u_char *bmp = NULL; /* Bitmap */ - u_int32_t blsize; /* Index allocation size (2048) */ - u_int32_t rdsize; /* Length of data to read */ - u_int32_t attrnum; /* Current attribute type */ - u_int32_t cpbl = 1; /* Clusters per directory block */ - u_int32_t blnum; - struct attr_indexentry *iep; - int error = ENOENT; - u_int32_t aoff, cnum; - - dprintf(("ntfs_ntreaddir: read ino: %d, num: %d\n", ip->i_number, num)); - error = ntfs_ntget(ip); - if (error) - return (error); - - error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap); - if (error) - return (ENOTDIR); - - if (fp->f_dirblbuf == NULL) { - fp->f_dirblsz = vap->va_a_iroot->ir_size; - MALLOC(fp->f_dirblbuf, caddr_t, - max(vap->va_datalen,fp->f_dirblsz), M_NTFSDIR, M_WAITOK); - } - - blsize = fp->f_dirblsz; - rdbuf = fp->f_dirblbuf; - - dprintf(("ntfs_ntreaddir: rdbuf: 0x%p, blsize: %d\n", rdbuf, blsize)); - - if (vap->va_a_iroot->ir_flag & NTFS_IRFLAG_INDXALLOC) { - error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXBITMAP, "$I30", - 0, &bmvap); - if (error) { - error = ENOTDIR; - goto fail; - } - MALLOC(bmp, u_char *, bmvap->va_datalen, M_TEMP, M_WAITOK); - error = ntfs_readattr(ntmp, ip, NTFS_A_INDXBITMAP, "$I30", 0, - bmvap->va_datalen, bmp, NULL); - if (error) - goto fail; - - error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDX, "$I30", - 0, &iavap); - if (error) { - error = ENOTDIR; - goto fail; - } - cpbl = ntfs_btocn(blsize + ntfs_cntob(1) - 1); - dprintf(("ntfs_ntreaddir: indexalloc: %d, cpbl: %d\n", - iavap->va_datalen, cpbl)); - } else { - dprintf(("ntfs_ntreadidir: w/o BitMap and IndexAllocation\n")); - iavap = bmvap = NULL; - bmp = NULL; - } - - /* Try use previous values */ - if ((fp->f_lastdnum < num) && (fp->f_lastdnum != 0)) { - attrnum = fp->f_lastdattr; - aoff = fp->f_lastdoff; - blnum = fp->f_lastdblnum; - cnum = fp->f_lastdnum; - } else { - attrnum = NTFS_A_INDXROOT; - aoff = sizeof(struct attr_indexroot); - blnum = 0; - cnum = 0; - } - - do { - dprintf(("ntfs_ntreaddir: scan: 0x%x, %d, %d, %d, %d\n", - attrnum, (u_int32_t) blnum, cnum, num, aoff)); - rdsize = (attrnum == NTFS_A_INDXROOT) ? vap->va_datalen : blsize; - error = ntfs_readattr(ntmp, ip, attrnum, "$I30", - ntfs_cntob(blnum * cpbl), rdsize, rdbuf, NULL); - if (error) - goto fail; - - if (attrnum == NTFS_A_INDX) { - error = ntfs_procfixups(ntmp, NTFS_INDXMAGIC, - rdbuf, rdsize); - if (error) - goto fail; - } - if (aoff == 0) - aoff = (attrnum == NTFS_A_INDX) ? - (0x18 + ((struct attr_indexalloc *) rdbuf)->ia_hdrsize) : - sizeof(struct attr_indexroot); - - iep = (struct attr_indexentry *) (rdbuf + aoff); - for (; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (rdsize > aoff); - aoff += iep->reclen, - iep = (struct attr_indexentry *) (rdbuf + aoff)) - { - if (!ntfs_isnamepermitted(ntmp, iep)) continue; - - if (cnum >= num) { - fp->f_lastdnum = cnum; - fp->f_lastdoff = aoff; - fp->f_lastdblnum = blnum; - fp->f_lastdattr = attrnum; - - *riepp = iep; - - error = 0; - goto fail; - } - cnum++; - } - - if (iavap) { - if (attrnum == NTFS_A_INDXROOT) - blnum = 0; - else - blnum++; - - while (ntfs_cntob(blnum * cpbl) < iavap->va_datalen) { - if (bmp[blnum >> 3] & (1 << (blnum & 3))) - break; - blnum++; - } - - attrnum = NTFS_A_INDX; - aoff = 0; - if (ntfs_cntob(blnum * cpbl) >= iavap->va_datalen) - break; - dprintf(("ntfs_ntreaddir: blnum: %d\n", (u_int32_t) blnum)); - } - } while (iavap); - - *riepp = NULL; - fp->f_lastdnum = 0; - -fail: - if (vap) - ntfs_ntvattrrele(vap); - if (bmvap) - ntfs_ntvattrrele(bmvap); - if (iavap) - ntfs_ntvattrrele(iavap); - if (bmp) - FREE(bmp, M_TEMP); - ntfs_ntput(ip); - return (error); -} - -/* - * Convert NTFS times that are in 100 ns units and begins from - * 1601 Jan 1 into unix times. - */ -struct timespec -ntfs_nttimetounix( - u_int64_t nt) -{ - struct timespec t; - - /* WindowNT times are in 100 ns and from 1601 Jan 1 */ - t.tv_nsec = (nt % (1000 * 1000 * 10)) * 100; - t.tv_sec = nt / (1000 * 1000 * 10) - - 369LL * 365LL * 24LL * 60LL * 60LL - - 89LL * 1LL * 24LL * 60LL * 60LL; - return (t); -} - -/* - * Get file times from NTFS_A_NAME attribute. - */ -int -ntfs_times( - struct ntfsmount * ntmp, - struct ntnode * ip, - ntfs_times_t * tm) -{ - struct ntvattr *vap; - int error; - - dprintf(("ntfs_times: ino: %d...\n", ip->i_number)); - - error = ntfs_ntget(ip); - if (error) - return (error); - - error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap); - if (error) { - ntfs_ntput(ip); - return (error); - } - *tm = vap->va_a_name->n_times; - ntfs_ntvattrrele(vap); - ntfs_ntput(ip); - - return (0); -} - -/* - * Get file sizes from corresponding attribute. - * - * ntnode under fnode should be locked. - */ -int -ntfs_filesize( - struct ntfsmount * ntmp, - struct fnode * fp, - u_int64_t * size, - u_int64_t * bytes) -{ - struct ntvattr *vap; - struct ntnode *ip = FTONT(fp); - u_int64_t sz, bn; - int error; - - dprintf(("ntfs_filesize: ino: %d\n", ip->i_number)); - - error = ntfs_ntvattrget(ntmp, ip, - fp->f_attrtype, fp->f_attrname, 0, &vap); - if (error) - return (error); - - bn = vap->va_allocated; - sz = vap->va_datalen; - - dprintf(("ntfs_filesize: %d bytes (%d bytes allocated)\n", - (u_int32_t) sz, (u_int32_t) bn)); - - if (size) - *size = sz; - if (bytes) - *bytes = bn; - - ntfs_ntvattrrele(vap); - - return (0); -} - -/* - * This is one of write routine. - */ -int -ntfs_writeattr_plain( - struct ntfsmount * ntmp, - struct ntnode * ip, - u_int32_t attrnum, - char *attrname, - off_t roff, - size_t rsize, - void *rdata, - size_t * initp, - struct uio *uio) -{ - size_t init; - int error = 0; - off_t off = roff, left = rsize, towrite; - caddr_t data = rdata; - struct ntvattr *vap; - *initp = 0; - - while (left) { - error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname, - ntfs_btocn(off), &vap); - if (error) - return (error); - towrite = min(left, ntfs_cntob(vap->va_vcnend + 1) - off); - ddprintf(("ntfs_writeattr_plain: o: %d, s: %d (%d - %d)\n", - (u_int32_t) off, (u_int32_t) towrite, - (u_int32_t) vap->va_vcnstart, - (u_int32_t) vap->va_vcnend)); - error = ntfs_writentvattr_plain(ntmp, ip, vap, - off - ntfs_cntob(vap->va_vcnstart), - towrite, data, &init, uio); - if (error) { - printf("ntfs_writeattr_plain: " \ - "ntfs_writentvattr_plain failed: o: %d, s: %d\n", - (u_int32_t) off, (u_int32_t) towrite); - printf("ntfs_writeattr_plain: attrib: %d - %d\n", - (u_int32_t) vap->va_vcnstart, - (u_int32_t) vap->va_vcnend); - ntfs_ntvattrrele(vap); - break; - } - ntfs_ntvattrrele(vap); - left -= towrite; - off += towrite; - data = data + towrite; - *initp += init; - } - - return (error); -} - -/* - * This is one of write routine. - * - * ntnode should be locked. - */ -int -ntfs_writentvattr_plain( - struct ntfsmount * ntmp, - struct ntnode * ip, - struct ntvattr * vap, - off_t roff, - size_t rsize, - void *rdata, - size_t * initp, - struct uio *uio) -{ - int error = 0; - int off; - int cnt; - cn_t ccn, ccl, cn, left, cl; - caddr_t data = rdata; - struct buf *bp; - size_t tocopy; - - *initp = 0; - - if ((vap->va_flag & NTFS_AF_INRUN) == 0) { - printf("ntfs_writevattr_plain: CAN'T WRITE RES. ATTRIBUTE\n"); - return ENOTTY; - } - - ddprintf(("ntfs_writentvattr_plain: data in run: %d chains\n", - vap->va_vruncnt)); - - off = roff; - left = rsize; - ccl = 0; - ccn = 0; - cnt = 0; - for (; left && (cnt < vap->va_vruncnt); cnt++) { - ccn = vap->va_vruncn[cnt]; - ccl = vap->va_vruncl[cnt]; - - ddprintf(("ntfs_writentvattr_plain: " \ - "left %d, cn: 0x%x, cl: %d, off: %d\n", \ - (u_int32_t) left, (u_int32_t) ccn, \ - (u_int32_t) ccl, (u_int32_t) off)); - - if (ntfs_cntob(ccl) < off) { - off -= ntfs_cntob(ccl); - cnt++; - continue; - } - if (!ccn && ip->i_number != NTFS_BOOTINO) - continue; /* XXX */ - - ccl -= ntfs_btocn(off); - cn = ccn + ntfs_btocn(off); - off = ntfs_btocnoff(off); - - while (left && ccl) { -#if defined(__FreeBSD__) - tocopy = min(left, - min(ntfs_cntob(ccl) - off, MAXBSIZE - off)); -#else - /* under NetBSD, bread() can read - * maximum one block worth of data */ - tocopy = min(left, ntmp->ntm_bps - off); -#endif - cl = ntfs_btocl(tocopy + off); - ddprintf(("ntfs_writentvattr_plain: write: " \ - "cn: 0x%x cl: %d, off: %d len: %d, left: %d\n", - (u_int32_t) cn, (u_int32_t) cl, - (u_int32_t) off, (u_int32_t) tocopy, - (u_int32_t) left)); - if ((off == 0) && (tocopy == ntfs_cntob(cl))) - { - bp = getblk(ntmp->ntm_devvp, ntfs_cntobn(cn), - ntfs_cntob(cl), 0, 0); - clrbuf(bp); - } else { - error = bread(ntmp->ntm_devvp, ntfs_cntobn(cn), - ntfs_cntob(cl), NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - } - if (uio) - uiomove(bp->b_data + off, tocopy, uio); - else - memcpy(bp->b_data + off, data, tocopy); - bawrite(bp); - data = data + tocopy; - *initp += tocopy; - off = 0; - left -= tocopy; - cn += cl; - ccl -= cl; - } - } - - if (left) { - printf("ntfs_writentvattr_plain: POSSIBLE RUN ERROR\n"); - error = EINVAL; - } - - return (error); -} - -/* - * This is one of read routines. - * - * ntnode should be locked. - */ -int -ntfs_readntvattr_plain( - struct ntfsmount * ntmp, - struct ntnode * ip, - struct ntvattr * vap, - off_t roff, - size_t rsize, - void *rdata, - size_t * initp, - struct uio *uio) -{ - int error = 0; - int off; - - *initp = 0; - if (vap->va_flag & NTFS_AF_INRUN) { - int cnt; - cn_t ccn, ccl, cn, left, cl; - caddr_t data = rdata; - struct buf *bp; - size_t tocopy; - - ddprintf(("ntfs_readntvattr_plain: data in run: %d chains\n", - vap->va_vruncnt)); - - off = roff; - left = rsize; - ccl = 0; - ccn = 0; - cnt = 0; - while (left && (cnt < vap->va_vruncnt)) { - ccn = vap->va_vruncn[cnt]; - ccl = vap->va_vruncl[cnt]; - - ddprintf(("ntfs_readntvattr_plain: " \ - "left %d, cn: 0x%x, cl: %d, off: %d\n", \ - (u_int32_t) left, (u_int32_t) ccn, \ - (u_int32_t) ccl, (u_int32_t) off)); - - if (ntfs_cntob(ccl) < off) { - off -= ntfs_cntob(ccl); - cnt++; - continue; - } - if (ccn || ip->i_number == NTFS_BOOTINO) { - ccl -= ntfs_btocn(off); - cn = ccn + ntfs_btocn(off); - off = ntfs_btocnoff(off); - - while (left && ccl) { -#if defined(__FreeBSD__) - tocopy = min(left, - min(ntfs_cntob(ccl) - off, - MAXBSIZE - off)); -#else - /* under NetBSD, bread() can read - * maximum one block worth of data */ - tocopy = min(left, - ntmp->ntm_bps - off); -#endif - cl = ntfs_btocl(tocopy + off); - ddprintf(("ntfs_readntvattr_plain: " \ - "read: cn: 0x%x cl: %d, " \ - "off: %d len: %d, left: %d\n", - (u_int32_t) cn, - (u_int32_t) cl, - (u_int32_t) off, - (u_int32_t) tocopy, - (u_int32_t) left)); - error = bread(ntmp->ntm_devvp, - ntfs_cntobn(cn), - ntfs_cntob(cl), - NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - if (uio) { - uiomove(bp->b_data + off, - tocopy, uio); - } else { - memcpy(data, bp->b_data + off, - tocopy); - } - brelse(bp); - data = data + tocopy; - *initp += tocopy; - off = 0; - left -= tocopy; - cn += cl; - ccl -= cl; - } - } else { - tocopy = min(left, ntfs_cntob(ccl) - off); - ddprintf(("ntfs_readntvattr_plain: " - "hole: ccn: 0x%x ccl: %d, off: %d, " \ - " len: %d, left: %d\n", - (u_int32_t) ccn, (u_int32_t) ccl, - (u_int32_t) off, (u_int32_t) tocopy, - (u_int32_t) left)); - left -= tocopy; - off = 0; - if (uio) { - size_t remains = tocopy; - for(; remains; remains++) - uiomove("", 1, uio); - } else - bzero(data, tocopy); - data = data + tocopy; - } - cnt++; - } - if (left) { - printf("ntfs_readntvattr_plain: POSSIBLE RUN ERROR\n"); - error = E2BIG; - } - } else { - ddprintf(("ntfs_readnvattr_plain: data is in mft record\n")); - if (uio) - uiomove(vap->va_datap + roff, rsize, uio); - else - memcpy(rdata, vap->va_datap + roff, rsize); - *initp += rsize; - } - - return (error); -} - -/* - * This is one of read routines. - */ -int -ntfs_readattr_plain( - struct ntfsmount * ntmp, - struct ntnode * ip, - u_int32_t attrnum, - char *attrname, - off_t roff, - size_t rsize, - void *rdata, - size_t * initp, - struct uio *uio) -{ - size_t init; - int error = 0; - off_t off = roff, left = rsize, toread; - caddr_t data = rdata; - struct ntvattr *vap; - *initp = 0; - - while (left) { - error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname, - ntfs_btocn(off), &vap); - if (error) - return (error); - toread = min(left, ntfs_cntob(vap->va_vcnend + 1) - off); - ddprintf(("ntfs_readattr_plain: o: %d, s: %d (%d - %d)\n", - (u_int32_t) off, (u_int32_t) toread, - (u_int32_t) vap->va_vcnstart, - (u_int32_t) vap->va_vcnend)); - error = ntfs_readntvattr_plain(ntmp, ip, vap, - off - ntfs_cntob(vap->va_vcnstart), - toread, data, &init, uio); - if (error) { - printf("ntfs_readattr_plain: " \ - "ntfs_readntvattr_plain failed: o: %d, s: %d\n", - (u_int32_t) off, (u_int32_t) toread); - printf("ntfs_readattr_plain: attrib: %d - %d\n", - (u_int32_t) vap->va_vcnstart, - (u_int32_t) vap->va_vcnend); - ntfs_ntvattrrele(vap); - break; - } - ntfs_ntvattrrele(vap); - left -= toread; - off += toread; - data = data + toread; - *initp += init; - } - - return (error); -} - -/* - * This is one of read routines. - */ -int -ntfs_readattr( - struct ntfsmount * ntmp, - struct ntnode * ip, - u_int32_t attrnum, - char *attrname, - off_t roff, - size_t rsize, - void *rdata, - struct uio *uio) -{ - int error = 0; - struct ntvattr *vap; - size_t init; - - ddprintf(("ntfs_readattr: reading %d: 0x%x, from %d size %d bytes\n", - ip->i_number, attrnum, (u_int32_t) roff, (u_int32_t) rsize)); - - error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname, 0, &vap); - if (error) - return (error); - - if ((roff > vap->va_datalen) || - (roff + rsize > vap->va_datalen)) { - ddprintf(("ntfs_readattr: offset too big\n")); - ntfs_ntvattrrele(vap); - return (E2BIG); - } - if (vap->va_compression && vap->va_compressalg) { - u_int8_t *cup; - u_int8_t *uup; - off_t off = roff, left = rsize, tocopy; - caddr_t data = rdata; - cn_t cn; - - ddprintf(("ntfs_ntreadattr: compression: %d\n", - vap->va_compressalg)); - - MALLOC(cup, u_int8_t *, ntfs_cntob(NTFS_COMPUNIT_CL), - M_NTFSDECOMP, M_WAITOK); - MALLOC(uup, u_int8_t *, ntfs_cntob(NTFS_COMPUNIT_CL), - M_NTFSDECOMP, M_WAITOK); - - cn = (ntfs_btocn(roff)) & (~(NTFS_COMPUNIT_CL - 1)); - off = roff - ntfs_cntob(cn); - - while (left) { - error = ntfs_readattr_plain(ntmp, ip, attrnum, - attrname, ntfs_cntob(cn), - ntfs_cntob(NTFS_COMPUNIT_CL), - cup, &init, NULL); - if (error) - break; - - tocopy = min(left, ntfs_cntob(NTFS_COMPUNIT_CL) - off); - - if (init == ntfs_cntob(NTFS_COMPUNIT_CL)) { - if (uio) - uiomove(cup + off, tocopy, uio); - else - memcpy(data, cup + off, tocopy); - } else if (init == 0) { - if (uio) { - size_t remains = tocopy; - for(; remains; remains--) - uiomove("", 1, uio); - } - else - bzero(data, tocopy); - } else { - error = ntfs_uncompunit(ntmp, uup, cup); - if (error) - break; - if (uio) - uiomove(uup + off, tocopy, uio); - else - memcpy(data, uup + off, tocopy); - } - - left -= tocopy; - data = data + tocopy; - off += tocopy - ntfs_cntob(NTFS_COMPUNIT_CL); - cn += NTFS_COMPUNIT_CL; - } - - FREE(uup, M_NTFSDECOMP); - FREE(cup, M_NTFSDECOMP); - } else - error = ntfs_readattr_plain(ntmp, ip, attrnum, attrname, - roff, rsize, rdata, &init, uio); - ntfs_ntvattrrele(vap); - return (error); -} - -#if UNUSED_CODE -int -ntfs_parserun( - cn_t * cn, - cn_t * cl, - u_int8_t * run, - u_long len, - u_long *off) -{ - u_int8_t sz; - int i; - - if (NULL == run) { - printf("ntfs_parsetun: run == NULL\n"); - return (EINVAL); - } - sz = run[(*off)++]; - if (0 == sz) { - printf("ntfs_parserun: trying to go out of run\n"); - return (E2BIG); - } - *cl = 0; - if ((sz & 0xF) > 8 || (*off) + (sz & 0xF) > len) { - printf("ntfs_parserun: " \ - "bad run: length too big: sz: 0x%02x (%ld < %ld + sz)\n", - sz, len, *off); - return (EINVAL); - } - for (i = 0; i < (sz & 0xF); i++) - *cl += (u_int32_t) run[(*off)++] << (i << 3); - - sz >>= 4; - if ((sz & 0xF) > 8 || (*off) + (sz & 0xF) > len) { - printf("ntfs_parserun: " \ - "bad run: length too big: sz: 0x%02x (%ld < %ld + sz)\n", - sz, len, *off); - return (EINVAL); - } - for (i = 0; i < (sz & 0xF); i++) - *cn += (u_int32_t) run[(*off)++] << (i << 3); - - return (0); -} -#endif - -/* - * Process fixup routine on given buffer. - */ -int -ntfs_procfixups( - struct ntfsmount * ntmp, - u_int32_t magic, - caddr_t buf, - size_t len) -{ - struct fixuphdr *fhp = (struct fixuphdr *) buf; - int i; - u_int16_t fixup; - u_int16_t *fxp; - u_int16_t *cfxp; - - if (fhp->fh_magic != magic) { - printf("ntfs_procfixups: magic doesn't match: %08x != %08x\n", - fhp->fh_magic, magic); - return (EINVAL); - } - if ((fhp->fh_fnum - 1) * ntmp->ntm_bps != len) { - printf("ntfs_procfixups: " \ - "bad fixups number: %d for %ld bytes block\n", - fhp->fh_fnum, (long)len); /* XXX printf kludge */ - return (EINVAL); - } - if (fhp->fh_foff >= ntmp->ntm_spc * ntmp->ntm_mftrecsz * ntmp->ntm_bps) { - printf("ntfs_procfixups: invalid offset: %x", fhp->fh_foff); - return (EINVAL); - } - fxp = (u_int16_t *) (buf + fhp->fh_foff); - cfxp = (u_int16_t *) (buf + ntmp->ntm_bps - 2); - fixup = *fxp++; - for (i = 1; i < fhp->fh_fnum; i++, fxp++) { - if (*cfxp != fixup) { - printf("ntfs_procfixups: fixup %d doesn't match\n", i); - return (EINVAL); - } - *cfxp = *fxp; - ((caddr_t) cfxp) += ntmp->ntm_bps; - } - return (0); -} - -#if UNUSED_CODE -int -ntfs_runtocn( - cn_t * cn, - struct ntfsmount * ntmp, - u_int8_t * run, - u_long len, - cn_t vcn) -{ - cn_t ccn = 0; - cn_t ccl = 0; - u_long off = 0; - int error = 0; - -#if NTFS_DEBUG - int i; - printf("ntfs_runtocn: run: 0x%p, %ld bytes, vcn:%ld\n", - run, len, (u_long) vcn); - printf("ntfs_runtocn: run: "); - for (i = 0; i < len; i++) - printf("0x%02x ", run[i]); - printf("\n"); -#endif - - if (NULL == run) { - printf("ntfs_runtocn: run == NULL\n"); - return (EINVAL); - } - do { - if (run[off] == 0) { - printf("ntfs_runtocn: vcn too big\n"); - return (E2BIG); - } - vcn -= ccl; - error = ntfs_parserun(&ccn, &ccl, run, len, &off); - if (error) { - printf("ntfs_runtocn: ntfs_parserun failed\n"); - return (error); - } - } while (ccl <= vcn); - *cn = ccn + vcn; - return (0); -} -#endif - -/* - * this initializes toupper table & dependant variables to be ready for - * later work - */ -void -ntfs_toupper_init() -{ - ntfs_toupper_tab = (wchar *) NULL; - lockinit(&ntfs_toupper_lock, PVFS, "ntfs_toupper", 0, 0); - ntfs_toupper_usecount = 0; -} - -void -ntfs_toupper_destroy(void) -{ - - lockdestroy(&ntfs_toupper_lock); -} - -/* - * if the ntfs_toupper_tab[] is filled already, just raise use count; - * otherwise read the data from the filesystem we are currently mounting - */ -int -ntfs_toupper_use(mp, ntmp) - struct mount *mp; - struct ntfsmount *ntmp; -{ - int error = 0; - struct vnode *vp; - - /* get exclusive access */ - LOCKMGR(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL); - - /* only read the translation data from a file if it hasn't been - * read already */ - if (ntfs_toupper_tab) - goto out; - - /* - * Read in Unicode lowercase -> uppercase translation file. - * XXX for now, just the first 256 entries are used anyway, - * so don't bother reading more - */ - MALLOC(ntfs_toupper_tab, wchar *, 256 * sizeof(wchar), - M_NTFSRDATA, M_WAITOK); - - if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp))) - goto out; - error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, - 0, 256*sizeof(wchar), (char *) ntfs_toupper_tab, NULL); - vput(vp); - - out: - ntfs_toupper_usecount++; - LOCKMGR(&ntfs_toupper_lock, LK_RELEASE, NULL); - return (error); -} - -/* - * lower the use count and if it reaches zero, free the memory - * tied by toupper table - */ -void -ntfs_toupper_unuse() -{ - /* get exclusive access */ - LOCKMGR(&ntfs_toupper_lock, LK_EXCLUSIVE, NULL); - - ntfs_toupper_usecount--; - if (ntfs_toupper_usecount == 0) { - FREE(ntfs_toupper_tab, M_NTFSRDATA); - ntfs_toupper_tab = NULL; - } -#ifdef DIAGNOSTIC - else if (ntfs_toupper_usecount < 0) { - panic("ntfs_toupper_unuse(): use count negative: %d\n", - ntfs_toupper_usecount); - } -#endif - - /* release the lock */ - LOCKMGR(&ntfs_toupper_lock, LK_RELEASE, NULL); -} - -/* - * maps the Unicode char to 8bit equivalent - * XXX currently only gets lower 8bit from the Unicode char - * and substitutes a '_' for it if the result would be '\0'; - * something better has to be definitely though out - */ -char -ntfs_u28(unichar) - wchar unichar; -{ - return (char) NTFS_U28(unichar); -} - diff --git a/sys/ntfs/ntfs_subr.h b/sys/ntfs/ntfs_subr.h deleted file mode 100644 index 8f1480a..0000000 --- a/sys/ntfs/ntfs_subr.h +++ /dev/null @@ -1,110 +0,0 @@ -/* $NetBSD: ntfs_subr.h,v 1.8 1999/10/10 14:48:37 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -#define VA_LOADED 0x0001 -#define VA_PRELOADED 0x0002 - -struct ntvattr { - LIST_ENTRY(ntvattr) va_list; - - u_int32_t va_vflag; - struct vnode *va_vp; - struct ntnode *va_ip; - - u_int32_t va_flag; - u_int32_t va_type; - u_int8_t va_namelen; - char va_name[NTFS_MAXATTRNAME]; - - u_int32_t va_compression; - u_int32_t va_compressalg; - u_int32_t va_datalen; - u_int32_t va_allocated; - cn_t va_vcnstart; - cn_t va_vcnend; - u_int16_t va_index; - union { - struct { - cn_t * cn; - cn_t * cl; - u_long cnt; - } vrun; - caddr_t datap; - struct attr_name *name; - struct attr_indexroot *iroot; - struct attr_indexalloc *ialloc; - } va_d; -}; -#define va_vruncn va_d.vrun.cn -#define va_vruncl va_d.vrun.cl -#define va_vruncnt va_d.vrun.cnt -#define va_datap va_d.datap -#define va_a_name va_d.name -#define va_a_iroot va_d.iroot -#define va_a_ialloc va_d.ialloc - -struct componentname; -struct fnode; -struct uio; - -int ntfs_procfixups __P(( struct ntfsmount *, u_int32_t, caddr_t, size_t )); -int ntfs_parserun __P(( cn_t *, cn_t *, u_int8_t *, u_long, u_long *)); -int ntfs_runtocn __P(( cn_t *, struct ntfsmount *, u_int8_t *, u_long, cn_t)); -int ntfs_readntvattr_plain __P(( struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *,size_t *, struct uio *)); -int ntfs_readattr_plain __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *, struct uio *)); -int ntfs_readattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, struct uio *)); -int ntfs_filesize __P(( struct ntfsmount *, struct fnode *, u_int64_t *, u_int64_t *)); -int ntfs_times __P(( struct ntfsmount *, struct ntnode *, ntfs_times_t *)); -struct timespec ntfs_nttimetounix __P(( u_int64_t )); -int ntfs_ntreaddir __P(( struct ntfsmount *, struct fnode *, u_int32_t, struct attr_indexentry **)); -char ntfs_u28 __P((wchar)); -int ntfs_runtovrun __P(( cn_t **, cn_t **, u_long *, u_int8_t *)); -int ntfs_attrtontvattr __P(( struct ntfsmount *, struct ntvattr **, struct attr * )); -void ntfs_freentvattr __P(( struct ntvattr * )); -int ntfs_loadntvattrs __P(( struct ntfsmount *, struct vnode *, caddr_t, struct ntvattr **)); -struct ntvattr * ntfs_findntvattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, cn_t )); -int ntfs_ntlookupfile __P((struct ntfsmount *, struct vnode *, struct componentname *, struct vnode **)); -int ntfs_isnamepermitted __P((struct ntfsmount *, struct attr_indexentry * )); -int ntfs_ntvattrrele __P((struct ntvattr * )); -int ntfs_ntvattrget __P((struct ntfsmount *, struct ntnode *, u_int32_t, const char *, cn_t , struct ntvattr **)); -int ntfs_ntlookup __P((struct ntfsmount *, ino_t, struct ntnode **)); -int ntfs_ntget __P((struct ntnode *)); -void ntfs_ntref __P((struct ntnode *)); -void ntfs_ntrele __P((struct ntnode *)); -void ntfs_ntput __P((struct ntnode *)); -int ntfs_loadntnode __P(( struct ntfsmount *, struct ntnode * )); -int ntfs_writentvattr_plain __P((struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *, struct uio *)); -int ntfs_writeattr_plain __P((struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, size_t *, struct uio *)); -void ntfs_toupper_init __P((void)); -void ntfs_toupper_destroy __P((void)); -int ntfs_toupper_use __P((struct mount *, struct ntfsmount *)); -void ntfs_toupper_unuse __P((void)); -int ntfs_fget __P((struct ntfsmount *, struct ntnode *, int, char *, struct fnode **)); -void ntfs_frele __P((struct fnode *)); diff --git a/sys/ntfs/ntfs_vfsops.c b/sys/ntfs/ntfs_vfsops.c deleted file mode 100644 index 526decd..0000000 --- a/sys/ntfs/ntfs_vfsops.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* $NetBSD: ntfs_vfsops.c,v 1.23 1999/11/15 19:38:14 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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/conf.h> -#include <sys/proc.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/fcntl.h> -#include <sys/malloc.h> -#include <sys/systm.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#endif - -#include <vm/vm.h> -#include <vm/vm_param.h> -#if defined(__NetBSD__) -#include <vm/vm_prot.h> -#endif -#include <vm/vm_page.h> -#include <vm/vm_object.h> -#include <vm/vm_extern.h> - -#if defined(__NetBSD__) -#include <miscfs/specfs/specdev.h> -#endif - -/*#define NTFS_DEBUG 1*/ -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_subr.h> -#include <ntfs/ntfs_vfsops.h> -#include <ntfs/ntfs_ihash.h> -#include <ntfs/ntfsmount.h> - -#if defined(__FreeBSD__) -MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure"); -MALLOC_DEFINE(M_NTFSNTNODE,"NTFS ntnode", "NTFS ntnode information"); -MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode", "NTFS fnode information"); -MALLOC_DEFINE(M_NTFSDIR,"NTFS dir", "NTFS dir buffer"); -#endif - -static int ntfs_root __P((struct mount *, struct vnode **)); -static int ntfs_statfs __P((struct mount *, struct statfs *, - struct proc *)); -static int ntfs_unmount __P((struct mount *, int, struct proc *)); -static int ntfs_vget __P((struct mount *mp, ino_t ino, - struct vnode **vpp)); -static int ntfs_mountfs __P((register struct vnode *, struct mount *, - struct ntfs_args *, struct proc *)); -static int ntfs_vptofh __P((struct vnode *, struct fid *)); -static int ntfs_fhtovp __P((struct mount *, struct fid *, - struct vnode **)); - -#if !defined (__FreeBSD__) -static int ntfs_quotactl __P((struct mount *, int, uid_t, caddr_t, - struct proc *)); -static int ntfs_start __P((struct mount *, int, struct proc *)); -static int ntfs_sync __P((struct mount *, int, struct ucred *, - struct proc *)); -#endif - -#if defined(__FreeBSD__) -struct sockaddr; -static int ntfs_mount __P((struct mount *, char *, caddr_t, - struct nameidata *, struct proc *)); -static int ntfs_init __P((struct vfsconf *)); -#elif defined(__NetBSD__) -static int ntfs_mount __P((struct mount *, const char *, void *, - struct nameidata *, struct proc *)); -static void ntfs_init __P((void)); -static int ntfs_mountroot __P((void)); -static int ntfs_sysctl __P((int *, u_int, void *, size_t *, void *, - size_t, struct proc *)); -static int ntfs_checkexp __P((struct mount *, struct mbuf *, - int *, struct ucred **)); -#endif - -/* - * Verify a remote client has export rights and return these rights via. - * exflagsp and credanonp. - */ -#if !defined(__FreeBSD__) -static int -ntfs_checkexp(mp, nam, exflagsp, credanonp) - register struct mount *mp; - struct mbuf *nam; - int *exflagsp; - struct ucred **credanonp; -{ - register struct netcred *np; - register struct ntfsmount *ntm = VFSTONTFS(mp); - - /* - * Get the export permission structure for this <mp, client> tuple. - */ - np = vfs_export_lookup(mp, &ntm->ntm_export, nam); - if (np == NULL) - return (EACCES); - *exflagsp = np->netc_exflags; - *credanonp = &np->netc_anon; - return (0); -} -#endif - -#if defined(__NetBSD__) -/*ARGSUSED*/ -static int -ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) - int *name; - u_int namelen; - void *oldp; - size_t *oldlenp; - void *newp; - size_t newlen; - struct proc *p; -{ - return (EINVAL); -} - -static int -ntfs_mountroot() -{ - struct mount *mp; - extern struct vnode *rootvp; - struct proc *p = curproc; /* XXX */ - int error; - struct ntfs_args args; - - if (root_device->dv_class != DV_DISK) - return (ENODEV); - - /* - * Get vnodes for rootdev. - */ - if (bdevvp(rootdev, &rootvp)) - panic("ntfs_mountroot: can't setup rootvp"); - - if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) { - vrele(rootvp); - return (error); - } - - args.flag = 0; - args.uid = 0; - args.gid = 0; - args.mode = 0777; - - if ((error = ntfs_mountfs(rootvp, mp, &args, p)) != 0) { - mp->mnt_op->vfs_refcount--; - vfs_unbusy(mp); - free(mp, M_MOUNT); - vrele(rootvp); - return (error); - } - - mtx_lock(&mountlist_mtx); - TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); - mtx_unlock(&mountlist_mtx); - (void)ntfs_statfs(mp, &mp->mnt_stat, p); - vfs_unbusy(mp); - return (0); -} - -static void -ntfs_init () -{ - ntfs_nthashinit(); - ntfs_toupper_init(); -} - -#elif defined(__FreeBSD__) - -static int -ntfs_init ( - struct vfsconf *vcp ) -{ - ntfs_nthashinit(); - ntfs_toupper_init(); - return 0; -} - -static int -ntfs_uninit ( - struct vfsconf *vcp ) -{ - ntfs_toupper_destroy(); - ntfs_nthashdestroy(); - return 0; -} - -#endif /* NetBSD */ - -static int -ntfs_mount ( - struct mount *mp, -#if defined(__FreeBSD__) - char *path, - caddr_t data, -#else - const char *path, - void *data, -#endif - struct nameidata *ndp, - struct proc *p ) -{ - size_t size; - int err = 0; - struct vnode *devvp; - struct ntfs_args args; - -#ifdef __FreeBSD__ - /* - * Use NULL path to flag a root mount - */ - if( path == NULL) { - /* - *** - * Mounting root file system - *** - */ - - /* Get vnode for root device*/ - if( bdevvp( rootdev, &rootvp)) - panic("ffs_mountroot: can't setup bdevvp for root"); - - /* - * FS specific handling - */ - mp->mnt_flag |= MNT_RDONLY; /* XXX globally applicable?*/ - - /* - * Attempt mount - */ - if( ( err = ntfs_mountfs(rootvp, mp, &args, p)) != 0) { - /* fs specific cleanup (if any)*/ - goto error_1; - } - - goto dostatfs; /* success*/ - - } -#endif /* FreeBSD */ - - /* - *** - * Mounting non-root file system or updating a file system - *** - */ - - /* copy in user arguments*/ - err = copyin(data, (caddr_t)&args, sizeof (struct ntfs_args)); - if (err) - goto error_1; /* can't get arguments*/ - - /* - * If updating, check whether changing from read-only to - * read/write; if there is no device name, that's all we do. - */ - if (mp->mnt_flag & MNT_UPDATE) { - /* if not updating name...*/ - if (args.fspec == 0) { - /* - * Process export requests. Jumping to "success" - * will return the vfs_export() error code. - */ -#if defined(__FreeBSD__) - err = vfs_export(mp, &args.export); -#else /* defined(__NetBSD__) */ - struct ntfsmount *ntm = VFSTONTFS(mp); - err = vfs_export(mp, &ntm->ntm_export, &args.export); -#endif - goto success; - } - - printf("ntfs_mount(): MNT_UPDATE not supported\n"); - err = EINVAL; - goto error_1; - } - - /* - * Not an update, or updating the name: look up the name - * and verify that it refers to a sensible block device. - */ - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - err = namei(ndp); - if (err) { - /* can't get devvp!*/ - goto error_1; - } - NDFREE(ndp, NDF_ONLY_PNBUF); - devvp = ndp->ni_vp; - -#if defined(__FreeBSD__) - if (!vn_isdisk(devvp, &err)) - goto error_2; -#else - if (devvp->v_type != VBLK) { - err = ENOTBLK; - goto error_2; - } - if (major(devvp->v_rdev) >= nblkdev) { - err = ENXIO; - goto error_2; - } -#endif - if (mp->mnt_flag & MNT_UPDATE) { -#if 0 - /* - ******************** - * UPDATE - ******************** - */ - - if (devvp != ntmp->um_devvp) - err = EINVAL; /* needs translation */ - else - vrele(devvp); - /* - * Update device name only on success - */ - if( !err) { - /* Save "mounted from" info for mount point (NULL pad)*/ - copyinstr( args.fspec, - mp->mnt_stat.f_mntfromname, - MNAMELEN - 1, - &size); - bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - } -#endif - } else { - /* - ******************** - * NEW MOUNT - ******************** - */ - - /* - * Since this is a new mount, we want the names for - * the device and the mount point copied in. If an - * error occurs, the mountpoint is discarded by the - * upper level code. Note that vfs_mount() handles - * copying the mountpoint f_mntonname for us, so we - * don't have to do it here unless we want to set it - * to something other than "path" for some rason. - */ - /* Save "mounted from" info for mount point (NULL pad)*/ - copyinstr( args.fspec, /* device name*/ - mp->mnt_stat.f_mntfromname, /* save area*/ - MNAMELEN - 1, /* max size*/ - &size); /* real size*/ - bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - - err = ntfs_mountfs(devvp, mp, &args, p); - } - if (err) { - goto error_2; - } - -#ifdef __FreeBSD__ -dostatfs: -#endif - /* - * Initialize FS stat information in mount struct; uses both - * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname - * - * This code is common to root and non-root mounts - */ - (void)VFS_STATFS(mp, &mp->mnt_stat, p); - - goto success; - - -error_2: /* error with devvp held*/ - - /* release devvp before failing*/ - vrele(devvp); - -error_1: /* no state to back out*/ - -success: - return(err); -} - -/* - * Common code for mount and mountroot - */ -int -ntfs_mountfs(devvp, mp, argsp, p) - register struct vnode *devvp; - struct mount *mp; - struct ntfs_args *argsp; - struct proc *p; -{ - struct buf *bp; - struct ntfsmount *ntmp; - dev_t dev = devvp->v_rdev; - int error, ronly, ncount, i; - struct vnode *vp; - - /* - * Disallow multiple mounts of the same device. - * Disallow mounting of a device that is currently in use - * (except for root, which might share swap device for miniroot). - * Flush out any old buffers remaining from a previous use. - */ - error = vfs_mountedon(devvp); - if (error) - return (error); - ncount = vcount(devvp); -#if defined(__FreeBSD__) - if (devvp->v_object) - ncount -= 1; -#endif - if (ncount > 1 && devvp != rootvp) - return (EBUSY); -#if defined(__FreeBSD__) - VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p); - error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0); - VOP__UNLOCK(devvp, 0, p); -#else - error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0); -#endif - if (error) - return (error); - - ronly = (mp->mnt_flag & MNT_RDONLY) != 0; - VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p); - error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); - VOP__UNLOCK(devvp, 0, p); - if (error) - return (error); - - bp = NULL; - - error = bread(devvp, BBLOCK, BBSIZE, NOCRED, &bp); - if (error) - goto out; - ntmp = malloc( sizeof *ntmp, M_NTFSMNT, M_WAITOK | M_ZERO); - bcopy( bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile) ); - brelse( bp ); - bp = NULL; - - if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) { - error = EINVAL; - dprintf(("ntfs_mountfs: invalid boot block\n")); - goto out; - } - - { - int8_t cpr = ntmp->ntm_mftrecsz; - if( cpr > 0 ) - ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr; - else - ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps; - } - dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n", - ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media, - ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec)); - dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n", - (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn)); - - ntmp->ntm_mountp = mp; - ntmp->ntm_dev = dev; - ntmp->ntm_devvp = devvp; - ntmp->ntm_uid = argsp->uid; - ntmp->ntm_gid = argsp->gid; - ntmp->ntm_mode = argsp->mode; - ntmp->ntm_flag = argsp->flag; - mp->mnt_data = (qaddr_t)ntmp; - - dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n", - (ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.", - (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"", - ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode)); - - /* - * We read in some system nodes to do not allow - * reclaim them and to have everytime access to them. - */ - { - int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO }; - for (i=0; i<3; i++) { - error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]])); - if(error) - goto out1; - ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM; - VREF(ntmp->ntm_sysvn[pi[i]]); - vput(ntmp->ntm_sysvn[pi[i]]); - } - } - - /* read the Unicode lowercase --> uppercase translation table, - * if necessary */ - if ((error = ntfs_toupper_use(mp, ntmp))) - goto out1; - - /* - * Scan $BitMap and count free clusters - */ - error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree); - if(error) - goto out1; - - /* - * Read and translate to internal format attribute - * definition file. - */ - { - int num,j; - struct attrdef ad; - - /* Open $AttrDef */ - error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp ); - if(error) - goto out1; - - /* Count valid entries */ - for(num=0;;num++) { - error = ntfs_readattr(ntmp, VTONT(vp), - NTFS_A_DATA, NULL, - num * sizeof(ad), sizeof(ad), - &ad, NULL); - if (error) - goto out1; - if (ad.ad_name[0] == 0) - break; - } - - /* Alloc memory for attribute definitions */ - MALLOC(ntmp->ntm_ad, struct ntvattrdef *, - num * sizeof(struct ntvattrdef), - M_NTFSMNT, M_WAITOK); - - ntmp->ntm_adnum = num; - - /* Read them and translate */ - for(i=0;i<num;i++){ - error = ntfs_readattr(ntmp, VTONT(vp), - NTFS_A_DATA, NULL, - i * sizeof(ad), sizeof(ad), - &ad, NULL); - if (error) - goto out1; - j = 0; - do { - ntmp->ntm_ad[i].ad_name[j] = ad.ad_name[j]; - } while(ad.ad_name[j++]); - ntmp->ntm_ad[i].ad_namelen = j - 1; - ntmp->ntm_ad[i].ad_type = ad.ad_type; - } - - vput(vp); - } - -#if defined(__FreeBSD__) - mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); - mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; -#else - mp->mnt_stat.f_fsid.val[0] = dev; - mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_NTFS); -#endif - mp->mnt_maxsymlinklen = 0; - mp->mnt_flag |= MNT_LOCAL; - devvp->v_rdev->si_mountpoint = mp; - return (0); - -out1: - for(i=0;i<NTFS_SYSNODESNUM;i++) - if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]); - - if (vflush(mp, 0, 0)) - dprintf(("ntfs_mountfs: vflush failed\n")); - -out: - devvp->v_rdev->si_mountpoint = NULL; - if (bp) - brelse(bp); - -#if defined __NetBSD__ - /* lock the device vnode before calling VOP_CLOSE() */ - VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p); - (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); - VOP__UNLOCK(devvp, 0, p); -#else - (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); -#endif - - return (error); -} - -#if !defined(__FreeBSD__) -static int -ntfs_start ( - struct mount *mp, - int flags, - struct proc *p ) -{ - return (0); -} -#endif - -static int -ntfs_unmount( - struct mount *mp, - int mntflags, - struct proc *p) -{ - register struct ntfsmount *ntmp; - int error, ronly = 0, flags, i; - - dprintf(("ntfs_unmount: unmounting...\n")); - ntmp = VFSTONTFS(mp); - - flags = 0; - if(mntflags & MNT_FORCE) - flags |= FORCECLOSE; - - dprintf(("ntfs_unmount: vflushing...\n")); - error = vflush(mp, 0, flags | SKIPSYSTEM); - if (error) { - printf("ntfs_unmount: vflush failed: %d\n",error); - return (error); - } - - /* Check if only system vnodes are rest */ - for(i=0;i<NTFS_SYSNODESNUM;i++) - if((ntmp->ntm_sysvn[i]) && - (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY); - - /* Dereference all system vnodes */ - for(i=0;i<NTFS_SYSNODESNUM;i++) - if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]); - - /* vflush system vnodes */ - error = vflush(mp, 0, flags); - if (error) - printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error); - - /* Check if the type of device node isn't VBAD before - * touching v_specinfo. If the device vnode is revoked, the - * field is NULL and touching it causes null pointer derefercence. - */ - if (ntmp->ntm_devvp->v_type != VBAD) - ntmp->ntm_devvp->v_rdev->si_mountpoint = NULL; - - vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0); - -#if defined(__NetBSD__) - /* lock the device vnode before calling VOP_CLOSE() */ - VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE, - NOCRED, p); - VOP__UNLOCK(ntmp->ntm_devvp, 0, p); -#else - error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE, - NOCRED, p); -#endif - - vrele(ntmp->ntm_devvp); - - /* free the toupper table, if this has been last mounted ntfs volume */ - ntfs_toupper_unuse(); - - dprintf(("ntfs_umount: freeing memory...\n")); - mp->mnt_data = (qaddr_t)0; - mp->mnt_flag &= ~MNT_LOCAL; - FREE(ntmp->ntm_ad, M_NTFSMNT); - FREE(ntmp, M_NTFSMNT); - return (error); -} - -static int -ntfs_root( - struct mount *mp, - struct vnode **vpp ) -{ - struct vnode *nvp; - int error = 0; - - dprintf(("ntfs_root(): sysvn: %p\n", - VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO])); - error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp); - if(error) { - printf("ntfs_root: VFS_VGET failed: %d\n",error); - return (error); - } - - *vpp = nvp; - return (0); -} - -#if !defined(__FreeBSD__) -static int -ntfs_quotactl ( - struct mount *mp, - int cmds, - uid_t uid, - caddr_t arg, - struct proc *p) -{ - printf("\nntfs_quotactl():\n"); - return EOPNOTSUPP; -} -#endif - -int -ntfs_calccfree( - struct ntfsmount *ntmp, - cn_t *cfreep) -{ - struct vnode *vp; - u_int8_t *tmp; - int j, error; - long cfree = 0; - size_t bmsize, i; - - vp = ntmp->ntm_sysvn[NTFS_BITMAPINO]; - - bmsize = VTOF(vp)->f_size; - - MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK); - - error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, - 0, bmsize, tmp, NULL); - if (error) - goto out; - - for(i=0;i<bmsize;i++) - for(j=0;j<8;j++) - if(~tmp[i] & (1 << j)) cfree++; - *cfreep = cfree; - - out: - FREE(tmp, M_TEMP); - return(error); -} - -static int -ntfs_statfs( - struct mount *mp, - struct statfs *sbp, - struct proc *p) -{ - struct ntfsmount *ntmp = VFSTONTFS(mp); - u_int64_t mftsize,mftallocated; - - dprintf(("ntfs_statfs():\n")); - - mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size; - mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated; - -#if defined(__FreeBSD__) - sbp->f_type = mp->mnt_vfc->vfc_typenum; -#elif defined(__NetBSD__) - sbp->f_type = 0; -#else - sbp->f_type = MOUNT_NTFS; -#endif - sbp->f_bsize = ntmp->ntm_bps; - sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc; - sbp->f_blocks = ntmp->ntm_bootfile.bf_spv; - sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree); - sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec; - sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) + - sbp->f_ffree; - if (sbp != &mp->mnt_stat) { - bcopy((caddr_t)mp->mnt_stat.f_mntonname, - (caddr_t)&sbp->f_mntonname[0], MNAMELEN); - bcopy((caddr_t)mp->mnt_stat.f_mntfromname, - (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); - } - sbp->f_flags = mp->mnt_flag; -#ifdef __NetBSD__ - strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); -#endif - - return (0); -} - -#if !defined(__FreeBSD__) -static int -ntfs_sync ( - struct mount *mp, - int waitfor, - struct ucred *cred, - struct proc *p) -{ - /*dprintf(("ntfs_sync():\n"));*/ - return (0); -} -#endif - -/*ARGSUSED*/ -static int -ntfs_fhtovp( - struct mount *mp, - struct fid *fhp, - struct vnode **vpp) -{ - struct vnode *nvp; - struct ntfid *ntfhp = (struct ntfid *)fhp; - int error; - - ddprintf(("ntfs_fhtovp(): %s: %d\n", mp->mnt_stat->f_mntonname, - ntfhp->ntfid_ino)); - - if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, &nvp)) != 0) { - *vpp = NULLVP; - return (error); - } - /* XXX as unlink/rmdir/mkdir/creat are not currently possible - * with NTFS, we don't need to check anything else for now */ - *vpp = nvp; - - return (0); -} - -static int -ntfs_vptofh( - struct vnode *vp, - struct fid *fhp) -{ - register struct ntnode *ntp; - register struct ntfid *ntfhp; - - ddprintf(("ntfs_fhtovp(): %s: %p\n", vp->v_mount->mnt_stat->f_mntonname, - vp)); - - ntp = VTONT(vp); - ntfhp = (struct ntfid *)fhp; - ntfhp->ntfid_len = sizeof(struct ntfid); - ntfhp->ntfid_ino = ntp->i_number; - /* ntfhp->ntfid_gen = ntp->i_gen; */ - return (0); -} - -int -ntfs_vgetex( - struct mount *mp, - ino_t ino, - u_int32_t attrtype, - char *attrname, - u_long lkflags, - u_long flags, - struct proc *p, - struct vnode **vpp) -{ - int error; - register struct ntfsmount *ntmp; - struct ntnode *ip; - struct fnode *fp; - struct vnode *vp; - enum vtype f_type; - - dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n", - ino, attrtype, attrname?attrname:"", (u_long)lkflags, - (u_long)flags )); - - ntmp = VFSTONTFS(mp); - *vpp = NULL; - - /* Get ntnode */ - error = ntfs_ntlookup(ntmp, ino, &ip); - if (error) { - printf("ntfs_vget: ntfs_ntget failed\n"); - return (error); - } - - /* It may be not initialized fully, so force load it */ - if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) { - error = ntfs_loadntnode(ntmp, ip); - if(error) { - printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n", - ip->i_number); - ntfs_ntput(ip); - return (error); - } - } - - error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp); - if (error) { - printf("ntfs_vget: ntfs_fget failed\n"); - ntfs_ntput(ip); - return (error); - } - - f_type = VNON; - if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) { - if ((ip->i_frflag & NTFS_FRFLAG_DIR) && - (fp->f_attrtype == NTFS_A_DATA && fp->f_attrname == NULL)) { - f_type = VDIR; - } else if (flags & VG_EXT) { - f_type = VNON; - fp->f_size = fp->f_allocated = 0; - } else { - f_type = VREG; - - error = ntfs_filesize(ntmp, fp, - &fp->f_size, &fp->f_allocated); - if (error) { - ntfs_ntput(ip); - return (error); - } - } - - fp->f_flag |= FN_VALID; - } - - if (FTOV(fp)) { - VGET(FTOV(fp), lkflags, p); - *vpp = FTOV(fp); - ntfs_ntput(ip); - return (0); - } - - error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp); - if(error) { - ntfs_frele(fp); - ntfs_ntput(ip); - return (error); - } - dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino)); - -#ifdef __FreeBSD__ - lockinit(&fp->f_lock, PINOD, "fnode", 0, 0); -#endif - fp->f_vp = vp; - vp->v_data = fp; - vp->v_type = f_type; - - if (ino == NTFS_ROOTINO) - vp->v_flag |= VROOT; - - ntfs_ntput(ip); - - if (lkflags & LK_TYPE_MASK) { - error = VN_LOCK(vp, lkflags, p); - if (error) { - vput(vp); - return (error); - } - } - - VREF(ip->i_devvp); - *vpp = vp; - return (0); - -} - -static int -ntfs_vget( - struct mount *mp, - ino_t ino, - struct vnode **vpp) -{ - return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, - LK_EXCLUSIVE | LK_RETRY, 0, curproc, vpp); -} - -#if defined(__FreeBSD__) -static struct vfsops ntfs_vfsops = { - ntfs_mount, - vfs_stdstart, - ntfs_unmount, - ntfs_root, - vfs_stdquotactl, - ntfs_statfs, - vfs_stdsync, - ntfs_vget, - ntfs_fhtovp, - vfs_stdcheckexp, - ntfs_vptofh, - ntfs_init, - ntfs_uninit, - vfs_stdextattrctl, -}; -VFS_SET(ntfs_vfsops, ntfs, 0); -#elif defined(__NetBSD__) -extern struct vnodeopv_desc ntfs_vnodeop_opv_desc; - -struct vnodeopv_desc *ntfs_vnodeopv_descs[] = { - &ntfs_vnodeop_opv_desc, - NULL, -}; - -struct vfsops ntfs_vfsops = { - MOUNT_NTFS, - ntfs_mount, - ntfs_start, - ntfs_unmount, - ntfs_root, - ntfs_quotactl, - ntfs_statfs, - ntfs_sync, - ntfs_vget, - ntfs_fhtovp, - ntfs_vptofh, - ntfs_init, - ntfs_sysctl, - ntfs_mountroot, - ntfs_checkexp, - ntfs_vnodeopv_descs, -}; -#else /* !NetBSD && !FreeBSD */ -static struct vfsops ntfs_vfsops = { - ntfs_mount, - ntfs_start, - ntfs_unmount, - ntfs_root, - ntfs_quotactl, - ntfs_statfs, - ntfs_sync, - ntfs_vget, - ntfs_fhtovp, - ntfs_vptofh, - ntfs_init, -}; -VFS_SET(ntfs_vfsops, ntfs, MOUNT_NTFS, 0); -#endif - - diff --git a/sys/ntfs/ntfs_vfsops.h b/sys/ntfs/ntfs_vfsops.h deleted file mode 100644 index c05686f..0000000 --- a/sys/ntfs/ntfs_vfsops.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $NetBSD: ntfs_vfsops.h,v 1.4 1999/10/10 14:20:33 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org) - * 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$ - */ -#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */ - /* ntfs_loadntnode() on ntnode, even if */ - /* ntnode not loaded */ -#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */ - /* fnode */ -#define VG_EXT 0x0004 /* This is not main record */ - -struct mount; -struct ntfsmount; -struct proc; -struct vnode; - -int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long, - struct proc *, struct vnode **); -int ntfs_calccfree(struct ntfsmount *, cn_t *); diff --git a/sys/ntfs/ntfs_vnops.c b/sys/ntfs/ntfs_vnops.c deleted file mode 100644 index 072a512..0000000 --- a/sys/ntfs/ntfs_vnops.c +++ /dev/null @@ -1,917 +0,0 @@ -/* $NetBSD: ntfs_vnops.c,v 1.23 1999/10/31 19:45:27 jdolecek Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * John Heidemann of the UCLA Ficus project. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/namei.h> -#include <sys/malloc.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/dirent.h> - -#include <vm/vm.h> -#include <vm/vm_param.h> -#if defined(__NetBSD__) -#include <vm/vm_prot.h> -#endif -#include <vm/vm_page.h> -#include <vm/vm_object.h> -#include <vm/vm_pager.h> -#if defined(__FreeBSD__) -#include <vm/vnode_pager.h> -#endif -#include <vm/vm_extern.h> - -#include <sys/sysctl.h> - -/*#define NTFS_DEBUG 1*/ -#include <ntfs/ntfs.h> -#include <ntfs/ntfs_inode.h> -#include <ntfs/ntfs_subr.h> -#if defined(__NetBSD__) -#include <miscfs/specfs/specdev.h> -#include <miscfs/genfs/genfs.h> -#endif - -#include <sys/unistd.h> /* for pathconf(2) constants */ - -static int ntfs_read __P((struct vop_read_args *)); -static int ntfs_write __P((struct vop_write_args *ap)); -static int ntfs_getattr __P((struct vop_getattr_args *ap)); -static int ntfs_inactive __P((struct vop_inactive_args *ap)); -static int ntfs_print __P((struct vop_print_args *ap)); -static int ntfs_reclaim __P((struct vop_reclaim_args *ap)); -static int ntfs_strategy __P((struct vop_strategy_args *ap)); -static int ntfs_access __P((struct vop_access_args *ap)); -static int ntfs_open __P((struct vop_open_args *ap)); -static int ntfs_close __P((struct vop_close_args *ap)); -static int ntfs_readdir __P((struct vop_readdir_args *ap)); -static int ntfs_lookup __P((struct vop_lookup_args *ap)); -static int ntfs_bmap __P((struct vop_bmap_args *ap)); -#if defined(__FreeBSD__) -static int ntfs_fsync __P((struct vop_fsync_args *ap)); -#else -static int ntfs_bypass __P((struct vop_generic_args *ap)); -#endif -static int ntfs_pathconf __P((void *)); - -int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */ - -#if defined(__NetBSD__) -/* - * This is a noop, simply returning what one has been given. - */ -int -ntfs_bmap(ap) - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - int *a_runb; - } */ *ap; -{ - dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn)); - if (ap->a_vpp != NULL) - *ap->a_vpp = ap->a_vp; - if (ap->a_bnp != NULL) - *ap->a_bnp = ap->a_bn; - if (ap->a_runp != NULL) - *ap->a_runp = 0; - return (0); -} -#endif - -static int -ntfs_read(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - struct uio *uio = ap->a_uio; - struct ntfsmount *ntmp = ip->i_mp; - u_int64_t toread; - int error; - - dprintf(("ntfs_read: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg)); - - dprintf(("ntfs_read: filesize: %d",(u_int32_t)fp->f_size)); - - /* don't allow reading after end of file */ - if (uio->uio_offset > fp->f_size) - toread = 0; - else - toread = min( uio->uio_resid, fp->f_size - uio->uio_offset ); - - dprintf((", toread: %d\n",(u_int32_t)toread)); - - if (toread == 0) - return (0); - - error = ntfs_readattr(ntmp, ip, fp->f_attrtype, - fp->f_attrname, uio->uio_offset, toread, NULL, uio); - if (error) { - printf("ntfs_read: ntfs_readattr failed: %d\n",error); - return (error); - } - - return (0); -} - -#if !defined(__FreeBSD__) - -static int -ntfs_bypass(ap) - struct vop_generic_args /* { - struct vnodeop_desc *a_desc; - <other random data follows, presumably> - } */ *ap; -{ - int error = ENOTTY; - dprintf(("ntfs_bypass: %s\n", ap->a_desc->vdesc_name)); - return (error); -} - -#endif - -static int -ntfs_getattr(ap) - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - register struct vattr *vap = ap->a_vap; - - dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag)); - -#if defined(__FreeBSD__) - vap->va_fsid = dev2udev(ip->i_dev); -#else /* NetBSD */ - vap->va_fsid = ip->i_dev; -#endif - vap->va_fileid = ip->i_number; - vap->va_mode = ip->i_mp->ntm_mode; - vap->va_nlink = ip->i_nlink; - vap->va_uid = ip->i_mp->ntm_uid; - vap->va_gid = ip->i_mp->ntm_gid; - vap->va_rdev = 0; /* XXX UNODEV ? */ - vap->va_size = fp->f_size; - vap->va_bytes = fp->f_allocated; - vap->va_atime = ntfs_nttimetounix(fp->f_times.t_access); - vap->va_mtime = ntfs_nttimetounix(fp->f_times.t_write); - vap->va_ctime = ntfs_nttimetounix(fp->f_times.t_create); - vap->va_flags = ip->i_flag; - vap->va_gen = 0; - vap->va_blocksize = ip->i_mp->ntm_spc * ip->i_mp->ntm_bps; - vap->va_type = vp->v_type; - vap->va_filerev = 0; - return (0); -} - - -/* - * Last reference to an ntnode. If necessary, write or delete it. - */ -int -ntfs_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; -#ifdef NTFS_DEBUG - register struct ntnode *ip = VTONT(vp); -#endif - - dprintf(("ntfs_inactive: vnode: %p, ntnode: %d\n", vp, ip->i_number)); - - if (ntfs_prtactive && vp->v_usecount != 0) - vprint("ntfs_inactive: pushing active", vp); - - VOP__UNLOCK(vp, 0, ap->a_p); - - /* XXX since we don't support any filesystem changes - * right now, nothing more needs to be done - */ - return (0); -} - -/* - * Reclaim an fnode/ntnode so that it can be used for other purposes. - */ -int -ntfs_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - int error; - - dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number)); - - if (ntfs_prtactive && vp->v_usecount != 0) - vprint("ntfs_reclaim: pushing active", vp); - - if ((error = ntfs_ntget(ip)) != 0) - return (error); - - /* Purge old data structures associated with the inode. */ - cache_purge(vp); - if (ip->i_devvp) { - vrele(ip->i_devvp); - ip->i_devvp = NULL; - } - - ntfs_frele(fp); - ntfs_ntput(ip); - vp->v_data = NULL; - - return (0); -} - -static int -ntfs_print(ap) - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap; -{ - return (0); -} - -/* - * Calculate the logical to physical mapping if not done already, - * then call the device strategy routine. - */ -int -ntfs_strategy(ap) - struct vop_strategy_args /* { - struct buf *a_bp; - } */ *ap; -{ - register struct buf *bp = ap->a_bp; - register struct vnode *vp = bp->b_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - struct ntfsmount *ntmp = ip->i_mp; - int error; - -#ifdef __FreeBSD__ - dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n", - (u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno, - (u_int32_t)bp->b_lblkno)); -#else - dprintf(("ntfs_strategy: blkno: %d, lblkno: %d\n", - (u_int32_t)bp->b_blkno, - (u_int32_t)bp->b_lblkno)); -#endif - - dprintf(("strategy: bcount: %d flags: 0x%lx\n", - (u_int32_t)bp->b_bcount,bp->b_flags)); - - if (bp->b_iocmd == BIO_READ) { - u_int32_t toread; - - if (ntfs_cntob(bp->b_blkno) >= fp->f_size) { - clrbuf(bp); - error = 0; - } else { - toread = min(bp->b_bcount, - fp->f_size-ntfs_cntob(bp->b_blkno)); - dprintf(("ntfs_strategy: toread: %d, fsize: %d\n", - toread,(u_int32_t)fp->f_size)); - - error = ntfs_readattr(ntmp, ip, fp->f_attrtype, - fp->f_attrname, ntfs_cntob(bp->b_blkno), - toread, bp->b_data, NULL); - - if (error) { - printf("ntfs_strategy: ntfs_readattr failed\n"); - bp->b_error = error; - bp->b_ioflags |= BIO_ERROR; - } - - bzero(bp->b_data + toread, bp->b_bcount - toread); - } - } else { - size_t tmp; - u_int32_t towrite; - - if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) { - printf("ntfs_strategy: CAN'T EXTEND FILE\n"); - bp->b_error = error = EFBIG; - bp->b_ioflags |= BIO_ERROR; - } else { - towrite = min(bp->b_bcount, - fp->f_size-ntfs_cntob(bp->b_blkno)); - dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n", - towrite,(u_int32_t)fp->f_size)); - - error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype, - fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite, - bp->b_data, &tmp, NULL); - - if (error) { - printf("ntfs_strategy: ntfs_writeattr fail\n"); - bp->b_error = error; - bp->b_ioflags |= BIO_ERROR; - } - } - } - bufdone(bp); - return (error); -} - -static int -ntfs_write(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - struct uio *uio = ap->a_uio; - struct ntfsmount *ntmp = ip->i_mp; - u_int64_t towrite; - size_t written; - int error; - - dprintf(("ntfs_write: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg)); - dprintf(("ntfs_write: filesize: %d",(u_int32_t)fp->f_size)); - - if (uio->uio_resid + uio->uio_offset > fp->f_size) { - printf("ntfs_write: CAN'T WRITE BEYOND END OF FILE\n"); - return (EFBIG); - } - - towrite = min(uio->uio_resid, fp->f_size - uio->uio_offset); - - dprintf((", towrite: %d\n",(u_int32_t)towrite)); - - error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype, - fp->f_attrname, uio->uio_offset, towrite, NULL, &written, uio); -#ifdef NTFS_DEBUG - if (error) - printf("ntfs_write: ntfs_writeattr failed: %d\n", error); -#endif - - return (error); -} - -int -ntfs_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct ntnode *ip = VTONT(vp); - mode_t mode = ap->a_mode; -#ifdef QUOTA - int error; -#endif - - dprintf(("ntfs_access: %d\n",ip->i_number)); - - /* - * Disallow write attempts on read-only file systems; - * unless the file is a socket, fifo, or a block or - * character device resident on the file system. - */ - if (mode & VWRITE) { - switch ((int)vp->v_type) { - case VDIR: - case VLNK: - case VREG: - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); -#ifdef QUOTA - if (error = getinoquota(ip)) - return (error); -#endif - break; - } - } - - return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid, - ip->i_mp->ntm_gid, ap->a_mode, ap->a_cred, NULL)); -} - -/* - * Open called. - * - * Nothing to do. - */ -/* ARGSUSED */ -static int -ntfs_open(ap) - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ -#if NTFS_DEBUG - register struct vnode *vp = ap->a_vp; - register struct ntnode *ip = VTONT(vp); - - printf("ntfs_open: %d\n",ip->i_number); -#endif - - /* - * Files marked append-only must be opened for appending. - */ - - return (0); -} - -/* - * Close called. - * - * Update the times on the inode. - */ -/* ARGSUSED */ -static int -ntfs_close(ap) - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ -#if NTFS_DEBUG - register struct vnode *vp = ap->a_vp; - register struct ntnode *ip = VTONT(vp); - - printf("ntfs_close: %d\n",ip->i_number); -#endif - - return (0); -} - -int -ntfs_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_ncookies; - u_int **cookies; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct fnode *fp = VTOF(vp); - register struct ntnode *ip = FTONT(fp); - struct uio *uio = ap->a_uio; - struct ntfsmount *ntmp = ip->i_mp; - int i, error = 0; - u_int32_t faked = 0, num; - int ncookies = 0; - struct dirent cde; - off_t off; - - dprintf(("ntfs_readdir %d off: %d resid: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid)); - - off = uio->uio_offset; - - /* Simulate . in every dir except ROOT */ - if( ip->i_number != NTFS_ROOTINO ) { - struct dirent dot = { NTFS_ROOTINO, - sizeof(struct dirent), DT_DIR, 1, "." }; - - if( uio->uio_offset < sizeof(struct dirent) ) { - dot.d_fileno = ip->i_number; - error = uiomove((char *)&dot,sizeof(struct dirent),uio); - if(error) - return (error); - - ncookies ++; - } - } - - /* Simulate .. in every dir including ROOT */ - if( uio->uio_offset < 2 * sizeof(struct dirent) ) { - struct dirent dotdot = { NTFS_ROOTINO, - sizeof(struct dirent), DT_DIR, 2, ".." }; - - error = uiomove((char *)&dotdot,sizeof(struct dirent),uio); - if(error) - return (error); - - ncookies ++; - } - - faked = (ip->i_number == NTFS_ROOTINO) ? 1 : 2; - num = uio->uio_offset / sizeof(struct dirent) - faked; - - while( uio->uio_resid >= sizeof(struct dirent) ) { - struct attr_indexentry *iep; - - error = ntfs_ntreaddir(ntmp, fp, num, &iep); - - if(error) - return (error); - - if( NULL == iep ) - break; - - for(; !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent)); - iep = NTFS_NEXTREC(iep, struct attr_indexentry *)) - { - if(!ntfs_isnamepermitted(ntmp,iep)) - continue; - - for(i=0; i<iep->ie_fnamelen; i++) { - cde.d_name[i] = ntfs_u28(iep->ie_fname[i]); - } - cde.d_name[i] = '\0'; - dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ", - num, cde.d_name, iep->ie_fnametype, - iep->ie_flag)); - cde.d_namlen = iep->ie_fnamelen; - cde.d_fileno = iep->ie_number; - cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG; - cde.d_reclen = sizeof(struct dirent); - dprintf(("%s\n", (cde.d_type == DT_DIR) ? "dir":"reg")); - - error = uiomove((char *)&cde, sizeof(struct dirent), uio); - if(error) - return (error); - - ncookies++; - num++; - } - } - - dprintf(("ntfs_readdir: %d entries (%d bytes) read\n", - ncookies,(u_int)(uio->uio_offset - off))); - dprintf(("ntfs_readdir: off: %d resid: %d\n", - (u_int32_t)uio->uio_offset,uio->uio_resid)); - - if (!error && ap->a_ncookies != NULL) { - struct dirent* dpStart; - struct dirent* dp; -#if defined(__FreeBSD__) - u_long *cookies; - u_long *cookiep; -#else /* defined(__NetBSD__) */ - off_t *cookies; - off_t *cookiep; -#endif - - ddprintf(("ntfs_readdir: %d cookies\n",ncookies)); - if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) - panic("ntfs_readdir: unexpected uio from NFS server"); - dpStart = (struct dirent *) - ((caddr_t)uio->uio_iov->iov_base - - (uio->uio_offset - off)); -#if defined(__FreeBSD__) - MALLOC(cookies, u_long *, ncookies * sizeof(u_long), - M_TEMP, M_WAITOK); -#else /* defined(__NetBSD__) */ - MALLOC(cookies, off_t *, ncookies * sizeof(off_t), - M_TEMP, M_WAITOK); -#endif - for (dp = dpStart, cookiep = cookies, i=0; - i < ncookies; - dp = (struct dirent *)((caddr_t) dp + dp->d_reclen), i++) { - off += dp->d_reclen; - *cookiep++ = (u_int) off; - } - *ap->a_ncookies = ncookies; - *ap->a_cookies = cookies; - } -/* - if (ap->a_eofflag) - *ap->a_eofflag = VTONT(ap->a_vp)->i_size <= uio->uio_offset; -*/ - return (error); -} - -int -ntfs_lookup(ap) - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; -{ - register struct vnode *dvp = ap->a_dvp; - register struct ntnode *dip = VTONT(dvp); - struct ntfsmount *ntmp = dip->i_mp; - struct componentname *cnp = ap->a_cnp; - struct ucred *cred = cnp->cn_cred; - int error; - int lockparent = cnp->cn_flags & LOCKPARENT; -#if NTFS_DEBUG - int wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); -#endif - dprintf(("ntfs_lookup: \"%.*s\" (%ld bytes) in %d, lp: %d, wp: %d \n", - (int)cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_namelen, - dip->i_number, lockparent, wantparent)); - - error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc); - if(error) - return (error); - - if ((cnp->cn_flags & ISLASTCN) && - (dvp->v_mount->mnt_flag & MNT_RDONLY) && - (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) - return (EROFS); - -#ifdef __NetBSD__ - /* - * We now have a segment name to search for, and a directory - * to search. - * - * Before tediously performing a linear scan of the directory, - * check the name cache to see if the directory/name pair - * we are looking for is known already. - */ - if ((error = cache_lookup(ap->a_dvp, ap->a_vpp, cnp)) >= 0) - return (error); -#endif - - if(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { - dprintf(("ntfs_lookup: faking . directory in %d\n", - dip->i_number)); - - VREF(dvp); - *ap->a_vpp = dvp; - error = 0; - } else if (cnp->cn_flags & ISDOTDOT) { - struct ntvattr *vap; - - dprintf(("ntfs_lookup: faking .. directory in %d\n", - dip->i_number)); - - error = ntfs_ntvattrget(ntmp, dip, NTFS_A_NAME, NULL, 0, &vap); - if(error) - return (error); - - VOP__UNLOCK(dvp,0,cnp->cn_proc); - cnp->cn_flags |= PDIRUNLOCK; - - dprintf(("ntfs_lookup: parentdir: %d\n", - vap->va_a_name->n_pnumber)); - error = VFS_VGET(ntmp->ntm_mountp, - vap->va_a_name->n_pnumber,ap->a_vpp); - ntfs_ntvattrrele(vap); - if (error) { - if (VN_LOCK(dvp,LK_EXCLUSIVE|LK_RETRY,cnp->cn_proc)==0) - cnp->cn_flags &= ~PDIRUNLOCK; - return (error); - } - - if (lockparent && (cnp->cn_flags & ISLASTCN)) { - error = VN_LOCK(dvp, LK_EXCLUSIVE, cnp->cn_proc); - if (error) { - vput( *(ap->a_vpp) ); - return (error); - } - cnp->cn_flags &= ~PDIRUNLOCK; - } - } else { - error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp); - if (error) { - dprintf(("ntfs_ntlookupfile: returned %d\n", error)); - return (error); - } - - dprintf(("ntfs_lookup: found ino: %d\n", - VTONT(*ap->a_vpp)->i_number)); - - if(!lockparent || !(cnp->cn_flags & ISLASTCN)) - VOP__UNLOCK(dvp, 0, cnp->cn_proc); - } - - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, *ap->a_vpp, cnp); - - return (error); -} - -#if defined(__FreeBSD__) -/* - * Flush the blocks of a file to disk. - * - * This function is worthless for vnodes that represent directories. Maybe we - * could just do a sync if they try an fsync on a directory file. - */ -static int -ntfs_fsync(ap) - struct vop_fsync_args /* { - struct vnode *a_vp; - struct ucred *a_cred; - int a_waitfor; - struct proc *a_p; - } */ *ap; -{ - return (0); -} -#endif - -/* - * Return POSIX pathconf information applicable to NTFS filesystem - */ -int -ntfs_pathconf(v) - void *v; -{ - struct vop_pathconf_args /* { - struct vnode *a_vp; - int a_name; - register_t *a_retval; - } */ *ap = v; - - switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = 1; - return (0); - case _PC_NAME_MAX: - *ap->a_retval = NTFS_MAXFILENAME; - return (0); - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - return (0); - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - return (0); - case _PC_NO_TRUNC: - *ap->a_retval = 0; - return (0); -#if defined(__NetBSD__) - case _PC_SYNC_IO: - *ap->a_retval = 1; - return (0); - case _PC_FILESIZEBITS: - *ap->a_retval = 64; - return (0); -#endif - default: - return (EINVAL); - } - /* NOTREACHED */ -} - -/* - * Global vfs data structures - */ -vop_t **ntfs_vnodeop_p; -#if defined(__FreeBSD__) -static -struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *)vop_defaultop }, - - { &vop_getattr_desc, (vop_t *)ntfs_getattr }, - { &vop_inactive_desc, (vop_t *)ntfs_inactive }, - { &vop_reclaim_desc, (vop_t *)ntfs_reclaim }, - { &vop_print_desc, (vop_t *)ntfs_print }, - { &vop_pathconf_desc, ntfs_pathconf }, - - { &vop_islocked_desc, (vop_t *)vop_stdislocked }, - { &vop_unlock_desc, (vop_t *)vop_stdunlock }, - { &vop_lock_desc, (vop_t *)vop_stdlock }, - { &vop_cachedlookup_desc, (vop_t *)ntfs_lookup }, - { &vop_lookup_desc, (vop_t *)vfs_cache_lookup }, - - { &vop_access_desc, (vop_t *)ntfs_access }, - { &vop_close_desc, (vop_t *)ntfs_close }, - { &vop_open_desc, (vop_t *)ntfs_open }, - { &vop_readdir_desc, (vop_t *)ntfs_readdir }, - { &vop_fsync_desc, (vop_t *)ntfs_fsync }, - - { &vop_strategy_desc, (vop_t *)ntfs_strategy }, - { &vop_read_desc, (vop_t *)ntfs_read }, - { &vop_write_desc, (vop_t *)ntfs_write }, - - { NULL, NULL } -}; - -static -struct vnodeopv_desc ntfs_vnodeop_opv_desc = - { &ntfs_vnodeop_p, ntfs_vnodeop_entries }; - -VNODEOP_SET(ntfs_vnodeop_opv_desc); - -#else /* !FreeBSD */ - -struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *) ntfs_bypass }, - { &vop_lookup_desc, (vop_t *) ntfs_lookup }, /* lookup */ - { &vop_create_desc, genfs_eopnotsupp }, /* create */ - { &vop_mknod_desc, genfs_eopnotsupp }, /* mknod */ - { &vop_open_desc, (vop_t *) ntfs_open }, /* open */ - { &vop_close_desc,(vop_t *) ntfs_close }, /* close */ - { &vop_access_desc, (vop_t *) ntfs_access }, /* access */ - { &vop_getattr_desc, (vop_t *) ntfs_getattr }, /* getattr */ - { &vop_setattr_desc, genfs_eopnotsupp }, /* setattr */ - { &vop_read_desc, (vop_t *) ntfs_read }, /* read */ - { &vop_write_desc, (vop_t *) ntfs_write }, /* write */ - { &vop_lease_desc, genfs_lease_check }, /* lease */ - { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ - { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ - { &vop_poll_desc, genfs_poll }, /* poll */ - { &vop_revoke_desc, genfs_revoke }, /* revoke */ - { &vop_fsync_desc, genfs_fsync }, /* fsync */ - { &vop_seek_desc, genfs_seek }, /* seek */ - { &vop_remove_desc, genfs_eopnotsupp }, /* remove */ - { &vop_link_desc, genfs_eopnotsupp }, /* link */ - { &vop_rename_desc, genfs_eopnotsupp }, /* rename */ - { &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */ - { &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */ - { &vop_symlink_desc, genfs_eopnotsupp }, /* symlink */ - { &vop_readdir_desc, (vop_t *) ntfs_readdir }, /* readdir */ - { &vop_readlink_desc, genfs_eopnotsupp }, /* readlink */ - { &vop_abortop_desc, genfs_abortop }, /* abortop */ - { &vop_inactive_desc, (vop_t *) ntfs_inactive }, /* inactive */ - { &vop_reclaim_desc, (vop_t *) ntfs_reclaim }, /* reclaim */ - { &vop_lock_desc, genfs_lock }, /* lock */ - { &vop_unlock_desc, genfs_unlock }, /* unlock */ - { &vop_bmap_desc, (vop_t *) ntfs_bmap }, /* bmap */ - { &vop_strategy_desc, (vop_t *) ntfs_strategy }, /* strategy */ - { &vop_print_desc, (vop_t *) ntfs_print }, /* print */ - { &vop_islocked_desc, genfs_islocked }, /* islocked */ - { &vop_pathconf_desc, ntfs_pathconf }, /* pathconf */ - { &vop_advlock_desc, genfs_nullop }, /* advlock */ - { &vop_blkatoff_desc, genfs_eopnotsupp }, /* blkatoff */ - { &vop_valloc_desc, genfs_eopnotsupp }, /* valloc */ - { &vop_reallocblks_desc, genfs_eopnotsupp }, /* reallocblks */ - { &vop_vfree_desc, genfs_eopnotsupp }, /* vfree */ - { &vop_truncate_desc, genfs_eopnotsupp }, /* truncate */ - { &vop_update_desc, genfs_eopnotsupp }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ - { (struct vnodeop_desc *)NULL, (int (*) __P((void *)))NULL } -}; -struct vnodeopv_desc ntfs_vnodeop_opv_desc = - { &ntfs_vnodeop_p, ntfs_vnodeop_entries }; - -#endif diff --git a/sys/ntfs/ntfsmount.h b/sys/ntfs/ntfsmount.h deleted file mode 100644 index f3a6d25..0000000 --- a/sys/ntfs/ntfsmount.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $NetBSD: ntfsmount.h,v 1.3 1999/07/26 14:02:32 jdolecek Exp $ */ - -/*- - * Copyright (c) 1998, 1999 Semen Ustimenko - * 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$ - */ - -#define NTFS_MFLAG_CASEINS 0x00000001 -#define NTFS_MFLAG_ALLNAMES 0x00000002 - -struct ntfs_args { - char *fspec; /* block special device to mount */ - struct export_args export; /* network export information */ - uid_t uid; /* uid that owns ntfs files */ - gid_t gid; /* gid that owns ntfs files */ - mode_t mode; /* mask to be applied for ntfs perms */ - u_long flag; /* additional flags */ -}; diff --git a/sys/nwfs/nwfs.h b/sys/nwfs/nwfs.h deleted file mode 100644 index e547869..0000000 --- a/sys/nwfs/nwfs.h +++ /dev/null @@ -1,83 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 <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 buf *bp, struct ucred *cr, struct proc *p); -int nwfs_vinvalbuf(struct vnode *vp, int flags, struct ucred *cred, - struct proc *p, int intrflg); -#endif /* _KERNEL */ - -#endif /* _NWFS_H_ */ diff --git a/sys/nwfs/nwfs_io.c b/sys/nwfs/nwfs_io.c deleted file mode 100644 index 4b105c6..0000000 --- a/sys/nwfs/nwfs_io.c +++ /dev/null @@ -1,635 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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/resourcevar.h> /* defines plimit structure in proc struct */ -#include <sys/kernel.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/namei.h> -#include <sys/vnode.h> -#include <sys/dirent.h> -#include <sys/signalvar.h> -#include <sys/sysctl.h> - -#include <vm/vm.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 <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> - -static int nwfs_fastlookup = 1; - -extern struct linker_set sysctl_vfs_nwfs; - -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_procp, 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_procp, 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((caddr_t)&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 proc *p; - 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",__FUNCTION__); - 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);*/ - p = uiop->uio_procp; - 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, p); - if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, cred, p); - if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - error = nwfs_vinvalbuf(vp, V_SAVE, cred, p, 1); - 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 proc *p; -/* struct vattr vattr;*/ - int error = 0; - - if (vp->v_type != VREG) { - printf("%s: vn types other than VREG unsupported !\n",__FUNCTION__); - 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);*/ - p = uiop->uio_procp; - if (ioflag & (IO_APPEND | IO_SYNC)) { - if (np->n_flag & NMODIFIED) { - nwfs_attr_cacheremove(vp); - error = nwfs_vinvalbuf(vp, V_SAVE, cred, p, 1); - 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. */ -#if notyet - nwfs_attr_cacheremove(vp); - error = VOP_GETATTR(vp, &vattr, cred, p); - if (error) return (error); -#endif - uiop->uio_offset = np->n_size; - } - } - if (uiop->uio_resid == 0) return 0; - if (p && uiop->uio_offset + uiop->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { - PROC_LOCK(p); - psignal(p, SIGXFSZ); - PROC_UNLOCK(p); - 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(bp, cr, p) - struct buf *bp; - struct ucred *cr; - struct proc *p; -{ - struct uio *uiop; - struct vnode *vp; - struct nwnode *np; - struct nwmount *nmp; - int error = 0; - struct uio uio; - struct iovec io; - - vp = bp->b_vp; - 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_procp = p; - 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; - bp->b_flags |= B_WRITEINPROG; - error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cr); - bp->b_flags &= ~B_WRITEINPROG; - - /* - * 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 proc *p; - struct ucred *cred; - struct nwmount *nmp; - struct nwnode *np; - vm_page_t *pages; - - vp = ap->a_vp; - p = curproc; /* XXX */ - cred = curproc->p_ucred; /* XXX */ - np = VTONW(vp); - nmp = VFSTONWFS(vp->v_mount); - pages = ap->a_m; - count = ap->a_count; - - if (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_procp = p; - - error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, &uio,cred); - pmap_qremove(kva, npages); - - relpbuf(bp, &nwfs_pbuf_freecnt); - - 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_free(pages[i]); - } - 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]; - - m->flags &= ~PG_ZERO; - - if (nextoff <= size) { - m->valid = VM_PAGE_BITS_ALL; - m->dirty = 0; - } else { - int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1); - vm_page_set_validclean(m, 0, nvalid); - } - - if (i != ap->a_reqpage) { - /* - * Whether or not to leave the page activated is up in - * the air, but we should put the page on a page queue - * somewhere (it already is in the object). Result: - * It appears that emperical results show that - * deactivating pages is best. - */ - - /* - * Just in case someone was asking for this page we - * now tell them that it is ok to use. - */ - if (!error) { - if (m->flags & PG_WANTED) - vm_page_activate(m); - else - vm_page_deactivate(m); - vm_page_wakeup(m); - } else { - vm_page_free(m); - } - } - } - 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 proc *p; - struct ucred *cred; - -#ifndef NWFS_RWCACHE - p = curproc; /* XXX */ - cred = p->p_ucred; /* XXX */ - VOP_OPEN(vp, FWRITE, cred, p); - error = vop_stdputpages(ap); - VOP_CLOSE(vp, FWRITE, cred, p); - 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; - - p = curproc; /* XXX */ - cred = p->p_ucred; /* XXX */ -/* VOP_OPEN(vp, FWRITE, cred, p);*/ - 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_AGAIN; - } - - 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_procp = p; - 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, p);*/ - NCPVNDEBUG("paged write done: %d\n", error); - - pmap_qremove(kva, npages); - relpbuf(bp, &nwfs_pbuf_freecnt); - - if (!error) { - int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; - for (i = 0; i < nwritten; i++) { - rtvals[i] = VM_PAGER_OK; - pages[i]->dirty = 0; - } - } - 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, flags, cred, p, intrflg) - struct vnode *vp; - int flags; - struct ucred *cred; - struct proc *p; - int intrflg; -{ - struct nwnode *np = VTONW(vp); -/* struct nwmount *nmp = VTONWFS(vp);*/ - int error = 0, slpflag, slptimeo; - - if (vp->v_flag & VXLOCK) { - return (0); - } - if (intrflg) { - slpflag = PCATCH; - slptimeo = 2 * hz; - } else { - slpflag = 0; - slptimeo = 0; - } - while (np->n_flag & NFLUSHINPROG) { - np->n_flag |= NFLUSHWANT; - error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "nwfsvinv", slptimeo); - error = ncp_chkintr(NWFSTOCONN(VTONWFS(vp)), p); - if (error == EINTR && intrflg) - return EINTR; - } - np->n_flag |= NFLUSHINPROG; - error = vinvalbuf(vp, flags, cred, p, slpflag, 0); - while (error) { - if (intrflg && (error == ERESTART || error == EINTR)) { - np->n_flag &= ~NFLUSHINPROG; - if (np->n_flag & NFLUSHWANT) { - np->n_flag &= ~NFLUSHWANT; - wakeup((caddr_t)&np->n_flag); - } - return EINTR; - } - error = vinvalbuf(vp, flags, cred, p, slpflag, 0); - } - np->n_flag &= ~(NMODIFIED | NFLUSHINPROG); - if (np->n_flag & NFLUSHWANT) { - np->n_flag &= ~NFLUSHWANT; - wakeup((caddr_t)&np->n_flag); - } - return (error); -} diff --git a/sys/nwfs/nwfs_ioctl.c b/sys/nwfs/nwfs_ioctl.c deleted file mode 100644 index eb58389..0000000 --- a/sys/nwfs/nwfs_ioctl.c +++ /dev/null @@ -1,95 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <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 proc *p; - } */ *ap; -{ - int error; - struct proc *p = ap->a_p; - 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, p, cred, NCPM_READ); - if (error) break; - error = ncp_conn_gethandle(conn, p, &hp); - ncp_conn_unlock(conn, p); - if (error) break; - *(int*)data = hp->nh_id; - break; - case NWFSIOC_GETEINFO: - if ((error = VOP_ACCESS(vp, VEXEC, cred, p))) break; - fap = data; - error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, fap, - ap->a_p,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, p))) break; - *(int*)data = nmp->name_space; - break; - default: - error = EINVAL; - } - return (error); -} diff --git a/sys/nwfs/nwfs_mount.h b/sys/nwfs/nwfs_mount.h deleted file mode 100644 index 23274a7..0000000 --- a/sys/nwfs/nwfs_mount.h +++ /dev/null @@ -1,81 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 file system. */ -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; -}; - -#ifdef _KERNEL - -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_NWFSMNT); -#endif - -#endif -#endif /* !_NWFS_MOUNT_H_ */ diff --git a/sys/nwfs/nwfs_node.c b/sys/nwfs/nwfs_node.c deleted file mode 100644 index 9c1f086..0000000 --- a/sys/nwfs/nwfs_node.c +++ /dev/null @@ -1,377 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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/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 <nwfs/nwfs.h> -#include <nwfs/nwfs_mount.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> - -#define NWNOHASH(fhsum) (&nwhashtbl[(fhsum.f_id) & nwnodehash]) - -extern vop_t **nwfs_vnodeop_p; - -static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl; -static u_long nwnodehash; -static struct lock nwhashlock; - -MALLOC_DEFINE(M_NWNODE, "NWFS node", "NWFS vnode private part"); -MALLOC_DEFINE(M_NWFSHASH, "NWFS hash", "NWFS has table"); - -static int nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS); - -extern struct linker_set sysctl_vfs_nwfs; - -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); - lockinit(&nwhashlock, PVFS, "nwfshl", 0, 0); -} - -void -nwfs_hash_free(void) { - lockdestroy(&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(NULL, vp); - printf("%s:%d:%d:%d:%d\n",np->n_name,vp->v_usecount,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; - - 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 proc *p = curproc; /* XXX */ - struct nwnode *np; - struct nwnode_hash_head *nhpp; - struct nwmount *nmp = VFSTONWFS(mp); - struct vnode *vp; - int error; - -loop: - lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p); -rescan: - if (nwfs_hashlookup(nmp, fid, &np) == 0) { - vp = NWTOV(np); - mtx_lock(&vp->v_interlock); - lockmgr(&nwhashlock, LK_RELEASE, NULL, p); - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) - goto loop; - if (fap) - np->n_attr = fap->attributes; - *vpp = vp; - return(0); - } - lockmgr(&nwhashlock, LK_RELEASE, NULL, p); - - 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. - */ - MALLOC(np, struct nwnode *, sizeof *np, M_NWNODE, M_WAITOK | M_ZERO); - error = getnewvnode(VT_NWFS, mp, nwfs_vnodeop_p, &vp); - if (error) { - *vpp = NULL; - FREE(np, M_NWNODE); - 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; - } - lockinit(&vp->v_lock, PINOD, "nwnode", 0, LK_CANRECURSE); - lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p); - /* - * 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, p); - lockmgr(&nwhashlock, LK_RELEASE, NULL, p); - - if (vp->v_type == VDIR && dvp && (dvp->v_flag & VROOT) == 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 proc *p, - struct nwnode **npp) -{ - int error; - - lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p); - error = nwfs_hashlookup(nmp, fid, npp); - lockmgr(&nwhashlock, LK_RELEASE, NULL, p); - return error; -} - -/* - * Free nwnode, and give vnode back to system - */ -int -nwfs_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - struct proc *a_p; - } */ *ap; -{ - struct vnode *dvp = NULL, *vp = ap->a_vp; - struct nwnode *dnp, *np = VTONW(vp); - struct nwmount *nmp = VTONWFS(vp); - struct proc *p = ap->a_p; - - NCPVNDEBUG("%s,%d\n", np->n_name, vp->v_usecount); - if (np->n_flag & NREFPARENT) { - np->n_flag &= ~NREFPARENT; - if (nwfs_lookupnp(nmp, np->n_parent, p, &dnp) == 0) { - dvp = dnp->n_vnode; - } else { - NCPVNDEBUG("%s: has no parent ?\n",np->n_name); - } - } - lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p); - LIST_REMOVE(np, n_hash); - lockmgr(&nwhashlock, LK_RELEASE, NULL, p); - cache_purge(vp); - 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 proc *a_p; - } */ *ap; -{ - struct proc *p = ap->a_p; - struct ucred *cred = p->p_ucred; - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - int error; - - NCPVNDEBUG("%s: %d\n", VTONW(vp)->n_name, vp->v_usecount); - if (np->opened) { - error = nwfs_vinvalbuf(vp, V_SAVE, cred, p, 1); - error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, p, cred); - np->opened = 0; - } - VOP_UNLOCK(vp, 0, p); - 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/nwfs/nwfs_node.h b/sys/nwfs/nwfs_node.h deleted file mode 100644 index 34c693d..0000000 --- a/sys/nwfs/nwfs_node.h +++ /dev/null @@ -1,102 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 proc *p, - 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/nwfs/nwfs_subr.c b/sys/nwfs/nwfs_subr.c deleted file mode 100644 index d3e212d..0000000 --- a/sys/nwfs/nwfs_subr.c +++ /dev/null @@ -1,711 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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/malloc.h> -#include <machine/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 <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <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 proc *p,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, p, 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 proc *p,struct ucred *cred) -{ - struct ncp_conn *conn = NWFSTOCONN(nmp); - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(87, conn, p, 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 proc *p,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, p, 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 proc *p,struct ucred *cred) -{ - struct nwmount *nmp; - struct nwnode *dnp = VTONW(dvp); - struct ncp_conn *conn; - int error; - - if (!dvp || dvp->v_type != VDIR) { - nwfs_printf("dvp is NULL or not a directory.\n"); - return (ENOENT); - } - nmp = VTONWFS(dvp); - conn = NWFSTOCONN(nmp); - - if (len == 1 && name[0] == '.') { - if (dnp->n_flag & NVOLUME) { - error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL, - fap, p, cred); - } else { - error = ncp_obtain_info(nmp, dnp->n_fid.f_parent, - dnp->n_nmlen, dnp->n_name, fap, p, cred); - } - return error; - } else if (len == 2 && name[0] == '.' && name[1] == '.') { - printf("%s: knows NOTHING about '..'\n", __FUNCTION__); - return EIO; - } else { - error = ncp_obtain_info(nmp, dnp->n_fid.f_id, - len, name, fap, p, 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 proc *p,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, p, 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 proc *p,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(66, conn, p, 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 proc *p,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - struct ncp_conn *conn=NWFSTOCONN(nmp); - - error = ncp_rq_alloc(87, conn, p, 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 proc *p, struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - - error = ncp_rq_alloc(87, conn, p, 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 proc *p,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, p, 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, procp) - struct vnode *vp; - struct vattr *vap; - struct ucred *cred; - struct proc *procp; -{ - 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,procp,cred); - if (error) - return error; - error = ncp_rq_alloc(73, conn, procp, cred, &rqp); - if (error) { - ncp_close_file(conn, &nwn.fh, procp, 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, procp, 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,procp,cred); - } - return (error); -} - -int -ncp_get_volume_info_with_number(struct ncp_conn *conn, - int n, struct ncp_volume_info *target, - struct proc *p,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, p, 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 proc *p,struct ucred *cred) -{ - struct ncp_rq *rqp; - int error; - u_int8_t ns; - u_int16_t nscnt; - - error = ncp_rq_alloc(87, conn, p, 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 proc *p,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, p, 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; -} - -/* - * Time & date conversion routines taken from msdosfs. Although leap - * year calculation is bogus, it's sufficient before 2100 :) - */ -/* - * This is the format of the contents of the deTime field in the direntry - * structure. - * We don't use bitfields because we don't know how compilers for - * arbitrary machines will lay them out. - */ -#define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */ -#define DT_2SECONDS_SHIFT 0 -#define DT_MINUTES_MASK 0x7E0 /* minutes */ -#define DT_MINUTES_SHIFT 5 -#define DT_HOURS_MASK 0xF800 /* hours */ -#define DT_HOURS_SHIFT 11 - -/* - * This is the format of the contents of the deDate field in the direntry - * structure. - */ -#define DD_DAY_MASK 0x1F /* day of month */ -#define DD_DAY_SHIFT 0 -#define DD_MONTH_MASK 0x1E0 /* month */ -#define DD_MONTH_SHIFT 5 -#define DD_YEAR_MASK 0xFE00 /* year - 1980 */ -#define DD_YEAR_SHIFT 9 -/* - * Total number of days that have passed for each month in a regular year. - */ -static u_short regyear[] = { - 31, 59, 90, 120, 151, 181, - 212, 243, 273, 304, 334, 365 -}; - -/* - * Total number of days that have passed for each month in a leap year. - */ -static u_short leapyear[] = { - 31, 60, 91, 121, 152, 182, - 213, 244, 274, 305, 335, 366 -}; - -/* - * Variables used to remember parts of the last time conversion. Maybe we - * can avoid a full conversion. - */ -static u_long lasttime; -static u_long lastday; -static u_short lastddate; -static u_short lastdtime; -/* - * Convert the unix version of time to dos's idea of time to be used in - * file timestamps. The passed in unix time is assumed to be in GMT. - */ -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; -{ - u_long t; - u_long days; - u_long inc; - u_long year; - u_long month; - u_short *months; - - /* - * If the time from the last conversion is the same as now, then - * skip the computations and use the saved result. - */ - t = tsp->tv_sec - tzoff * 60 - tz.tz_minuteswest * 60 - - (wall_cmos_clock ? adjkerntz : 0); - t &= ~1; - if (lasttime != t) { - lasttime = t; - lastdtime = (((t / 2) % 30) << DT_2SECONDS_SHIFT) - + (((t / 60) % 60) << DT_MINUTES_SHIFT) - + (((t / 3600) % 24) << DT_HOURS_SHIFT); - - /* - * If the number of days since 1970 is the same as the last - * time we did the computation then skip all this leap year - * and month stuff. - */ - days = t / (24 * 60 * 60); - if (days != lastday) { - lastday = days; - for (year = 1970;; year++) { - inc = year & 0x03 ? 365 : 366; - if (days < inc) - break; - days -= inc; - } - months = year & 0x03 ? regyear : leapyear; - for (month = 0; days >= months[month]; month++) - ; - if (month > 0) - days -= months[month - 1]; - lastddate = ((days + 1) << DD_DAY_SHIFT) - + ((month + 1) << DD_MONTH_SHIFT); - /* - * Remember dos's idea of time is relative to 1980. - * unix's is relative to 1970. If somehow we get a - * time before 1980 then don't give totally crazy - * results. - */ - if (year > 1980) - lastddate += (year - 1980) << DD_YEAR_SHIFT; - } - } - if (dtp) - *dtp = lastdtime; - if (dhp) - *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000; - - *ddp = lastddate; -} - -/* - * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that - * interval there were 8 regular years and 2 leap years. - */ -#define SECONDSTO1980 (((8 * 365) + (2 * 366)) * (24 * 60 * 60)) - -static u_short lastdosdate; -static u_long lastseconds; - -/* - * Convert from dos' idea of time to unix'. This will probably only be - * called from the stat(), and fstat() system calls and so probably need - * not be too efficient. - */ -void -ncp_dos2unixtime(dd, dt, dh, tzoff, tsp) - u_int dd; - u_int dt; - u_int dh; - int tzoff; - struct timespec *tsp; -{ - u_long seconds; - u_long month; - u_long year; - u_long days; - u_short *months; - - if (dd == 0) { - /* - * Uninitialized field, return the epoch. - */ - tsp->tv_sec = 0; - tsp->tv_nsec = 0; - return; - } - seconds = (((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) << 1) - + ((dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT) * 60 - + ((dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT) * 3600 - + dh / 100; - /* - * If the year, month, and day from the last conversion are the - * same then use the saved value. - */ - if (lastdosdate != dd) { - lastdosdate = dd; - days = 0; - year = (dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT; - days = year * 365; - days += year / 4 + 1; /* add in leap days */ - if ((year & 0x03) == 0) - days--; /* if year is a leap year */ - months = year & 0x03 ? regyear : leapyear; - month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT; - if (month < 1 || month > 12) { - month = 1; - } - if (month > 1) - days += months[month - 2]; - days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1; - lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980; - } - tsp->tv_sec = seconds + lastseconds + tz.tz_minuteswest * 60 + - tzoff * 60 + (wall_cmos_clock ? adjkerntz : 0); - tsp->tv_nsec = (dh % 100) * 10000000; -} diff --git a/sys/nwfs/nwfs_subr.h b/sys/nwfs/nwfs_subr.h deleted file mode 100644 index b603c76..0000000 --- a/sys/nwfs/nwfs_subr.h +++ /dev/null @@ -1,96 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 proc; -struct timespec; -struct ucred; -struct vattr; -struct vnode; - -int ncp_initsearch(struct vnode *dvp,struct proc *p,struct ucred *cred); -int ncp_search_for_file_or_subdir(struct nwmount *nmp,struct nw_search_seq *seq, - struct nw_entry_info *target, - struct proc *p,struct ucred *cred); -int ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap, - struct proc *p,struct ucred *cred); -int ncp_lookup_volume(struct ncp_conn *conn, char *volname, - u_char *volNum, u_int32_t *dirEnt, - struct proc *p,struct ucred *cred); -int ncp_close_file(struct ncp_conn *conn, ncp_fh *fh, - struct proc *p,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 proc *p,struct ucred *cred); -int ncp_DeleteNSEntry(struct nwmount *nmp, - u_int32_t dirent, int namelen, char *name, - struct proc *p,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 proc *p, struct ucred *cred); -int ncp_obtain_info(struct nwmount *nmp, u_int32_t dirent, - int namelen, char *path, struct nw_entry_info *target, - struct proc *p,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 proc *p,struct ucred *cred); -int ncp_setattr(struct vnode *,struct vattr *,struct ucred *,struct proc *); -int ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf, - struct proc *p,struct ucred *cred); -int ncp_get_volume_info_with_number(struct ncp_conn *conn, - int n, struct ncp_volume_info *target, - struct proc *p,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/nwfs/nwfs_vfsops.c b/sys/nwfs/nwfs_vfsops.c deleted file mode 100644 index c978722..0000000 --- a/sys/nwfs/nwfs_vfsops.c +++ /dev/null @@ -1,500 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 "opt_ncp.h" -#ifndef NCP -#error "NWFS requires NCP protocol" -#endif - -#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 <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <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 file system"); -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 int nwfs_mount(struct mount *, char *, caddr_t, - struct nameidata *, struct proc *); -static int nwfs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *); -static int nwfs_root(struct mount *, struct vnode **); -static int nwfs_start(struct mount *, int, struct proc *); -static int nwfs_statfs(struct mount *, struct statfs *, struct proc *); -static int nwfs_sync(struct mount *, int, struct ucred *, struct proc *); -static int nwfs_unmount(struct mount *, int, struct proc *); -static int nwfs_init(struct vfsconf *vfsp); -static int nwfs_uninit(struct vfsconf *vfsp); - -static struct vfsops nwfs_vfsops = { - nwfs_mount, - nwfs_start, - nwfs_unmount, - nwfs_root, - nwfs_quotactl, - nwfs_statfs, - nwfs_sync, - vfs_stdvget, - vfs_stdfhtovp, /* shouldn't happen */ - vfs_stdcheckexp, - vfs_stdvptofh, /* shouldn't happen */ - nwfs_init, - nwfs_uninit, - vfs_stdextattrctl, -}; - - -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; - } - MALLOC(pe, char *, 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; -} -/* - * 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, char *path, caddr_t data, - struct nameidata *ndp, struct proc *p) -{ - 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; - char *pc,*pe; - - if (data == NULL) { - nwfs_printf("missing data argument\n"); - return 1; - } - if (mp->mnt_flag & MNT_UPDATE) { - nwfs_printf("MNT_UPDATE not implemented"); - return (EOPNOTSUPP); - } - error = copyin(data, (caddr_t)&args, sizeof(struct nwfs_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,p,p->p_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,p); /* we keep the ref */ - mp->mnt_stat.f_iosize = conn->buffer_size; - /* We must malloc our own mount info */ - MALLOC(nmp,struct nwmount *,sizeof(struct nwmount),M_NWFSDATA,M_USE_RESERVE | M_ZERO); - if (nmp == NULL) { - nwfs_printf("could not alloc nwmount\n"); - error = ENOMEM; - goto bad; - } - mp->mnt_data = (qaddr_t)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 = index(strncpy(pc, conn->li.server, pe-pc-2),0); - if (pc < pe-1) { - *(pc++) = ':'; - pc=index(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, &vp); - if (error) - goto bad; - /* - * Lose the lock but keep the ref. - */ - VOP_UNLOCK(vp, 0, curproc); - NCPVODEBUG("rootvp.vrefcnt=%d\n",vp->v_usecount); - 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 proc *p) -{ - struct nwmount *nmp = VFSTONWFS(mp); - struct ncp_conn *conn; - int error, flags; - - NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags); - flags = 0; - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - /* There is 1 extra root vnode reference from nwfs_mount(). */ - error = vflush(mp, 1, flags); - if (error) - return (error); - conn = NWFSTOCONN(nmp); - ncp_conn_puthandle(nmp->connh,NULL,0); - if (ncp_conn_lock(conn,p,p->p_ucred,NCPM_WRITE | NCPM_EXECUTE) == 0) { - if(ncp_conn_free(conn)) - ncp_conn_unlock(conn,p); - } - mp->mnt_data = (qaddr_t)0; - if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS) - free(nmp->m.nls.to_lower, M_NWFSDATA); - free(nmp, M_NWFSDATA); - mp->mnt_flag &= ~MNT_LOCAL; - return (error); -} - -/* Return locked vnode to root of a filesystem */ -static int -nwfs_root(struct mount *mp, struct vnode **vpp) { - struct vnode *vp; - struct nwmount *nmp; - struct nwnode *np; - struct ncp_conn *conn; - struct nw_entry_info fattr; - struct proc *p = curproc; - struct ucred *cred = p->p_ucred; - int error, nsf, opt; - u_char vol; - - nmp = VFSTONWFS(mp); - conn = NWFSTOCONN(nmp); - if (nmp->n_root) { - *vpp = NWTOV(nmp->n_root); - while (vget(*vpp, LK_EXCLUSIVE, curproc) != 0) - ; - return 0; - } - error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol, - &nmp->n_rootent.f_id, p, cred); - if (error) - return ENOENT; - nmp->n_volume = vol; - error = ncp_get_namespaces(conn, vol, &nsf, p, 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, p, 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, p, 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, p, 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_flag |= VROOT; - np = VTONW(vp); - if (nmp->m.root_path[0] == 0) - np->n_flag |= NVOLUME; - nmp->n_root = np; -/* error = VOP_GETATTR(vp, &vattr, cred, p); - if (error) { - vput(vp); - NCPFATAL("Can't get root directory entry\n"); - return error; - }*/ - *vpp = vp; - return (0); -} - -/* - * Vfs start routine, a no-op. - */ -/* ARGSUSED */ -static int -nwfs_start(mp, flags, p) - struct mount *mp; - int flags; - struct proc *p; -{ - NCPVODEBUG("flags=%04x\n",flags); - return (0); -} - -/* - * Do operations associated with quotas, not supported - */ -/* ARGSUSED */ -static int -nwfs_quotactl(mp, cmd, uid, arg, p) - struct mount *mp; - int cmd; - uid_t uid; - caddr_t arg; - struct proc *p; -{ - NCPVODEBUG("return EOPNOTSUPP\n"); - return (EOPNOTSUPP); -} - -/*ARGSUSED*/ -int -nwfs_init(struct vfsconf *vfsp) -{ -#ifndef SMP - int name[2]; - int olen, ncpu, plen, error; - - name[0] = CTL_HW; - name[1] = HW_NCPU; - error = kernel_sysctl(curproc, name, 2, &ncpu, &olen, NULL, 0, &plen); - if (error == 0 && ncpu > 1) - printf("warning: nwfs module compiled without SMP support."); -#endif - 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, p) - struct mount *mp; - struct statfs *sbp; - struct proc *p; -{ - struct nwmount *nmp = VFSTONWFS(mp); - 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,p,p->p_ucred); - if (error) return error; - secsize = 512; /* XXX how to get real value ??? */ - sbp->f_spare2=0; /* placeholder */ - /* fundamental file system 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 file system */ - 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 file system */ - 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 */ - if (sbp != &mp->mnt_stat) { - sbp->f_fsid = mp->mnt_stat.f_fsid; /* file system id */ - sbp->f_owner = mp->mnt_stat.f_owner; /* user that mounted the filesystem */ - sbp->f_type = mp->mnt_vfc->vfc_typenum; /* type of filesystem */ - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - } - strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); - return 0; -} - -/* - * Flush out the buffer cache - */ -/* ARGSUSED */ -static int -nwfs_sync(mp, waitfor, cred, p) - struct mount *mp; - int waitfor; - struct ucred *cred; - struct proc *p; -{ - struct vnode *vp; - int error, allerror = 0; - /* - * Force stale buffer cache information to be flushed. - */ -loop: - for (vp = LIST_FIRST(&mp->mnt_vnodelist); - vp != NULL; - vp = LIST_NEXT(vp, v_mntvnodes)) { - /* - * If the vnode that we are about to sync is no longer - * associated with this mount point, start over. - */ - if (vp->v_mount != mp) - goto loop; - if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) || - waitfor == MNT_LAZY) - continue; - if (vget(vp, LK_EXCLUSIVE, p)) - goto loop; - error = VOP_FSYNC(vp, cred, waitfor, p); - if (error) - allerror = error; - vput(vp); - } - return (allerror); -} diff --git a/sys/nwfs/nwfs_vnops.c b/sys/nwfs/nwfs_vnops.c deleted file mode 100644 index 1e5361f..0000000 --- a/sys/nwfs/nwfs_vnops.c +++ /dev/null @@ -1,1032 +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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Boris Popov. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 <machine/mutex.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 <nwfs/nwfs.h> -#include <nwfs/nwfs_node.h> -#include <nwfs/nwfs_subr.h> - -/* - * Prototypes for NWFS vnode operations - */ -static int nwfs_create(struct vop_create_args *); -static int nwfs_mknod(struct vop_mknod_args *); -static int nwfs_open(struct vop_open_args *); -static int nwfs_close(struct vop_close_args *); -static int nwfs_access(struct vop_access_args *); -static int nwfs_getattr(struct vop_getattr_args *); -static int nwfs_setattr(struct vop_setattr_args *); -static int nwfs_read(struct vop_read_args *); -static int nwfs_write(struct vop_write_args *); -static int nwfs_fsync(struct vop_fsync_args *); -static int nwfs_remove(struct vop_remove_args *); -static int nwfs_link(struct vop_link_args *); -static int nwfs_lookup(struct vop_lookup_args *); -static int nwfs_rename(struct vop_rename_args *); -static int nwfs_mkdir(struct vop_mkdir_args *); -static int nwfs_rmdir(struct vop_rmdir_args *); -static int nwfs_symlink(struct vop_symlink_args *); -static int nwfs_readdir(struct vop_readdir_args *); -static int nwfs_strategy(struct vop_strategy_args *); -static int nwfs_print(struct vop_print_args *); -static int nwfs_pathconf(struct vop_pathconf_args *ap); - -/* Global vfs data structures for nwfs */ -vop_t **nwfs_vnodeop_p; -static struct vnodeopv_entry_desc nwfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *) vop_defaultop }, - { &vop_access_desc, (vop_t *) nwfs_access }, - { &vop_open_desc, (vop_t *) nwfs_open }, - { &vop_close_desc, (vop_t *) nwfs_close }, - { &vop_create_desc, (vop_t *) nwfs_create }, - { &vop_fsync_desc, (vop_t *) nwfs_fsync }, - { &vop_getattr_desc, (vop_t *) nwfs_getattr }, - { &vop_getpages_desc, (vop_t *) nwfs_getpages }, - { &vop_putpages_desc, (vop_t *) nwfs_putpages }, - { &vop_ioctl_desc, (vop_t *) nwfs_ioctl }, - { &vop_inactive_desc, (vop_t *) nwfs_inactive }, - { &vop_islocked_desc, (vop_t *) vop_stdislocked }, - { &vop_link_desc, (vop_t *) nwfs_link }, - { &vop_lock_desc, (vop_t *) vop_stdlock }, - { &vop_lookup_desc, (vop_t *) nwfs_lookup }, - { &vop_mkdir_desc, (vop_t *) nwfs_mkdir }, - { &vop_mknod_desc, (vop_t *) nwfs_mknod }, - { &vop_pathconf_desc, (vop_t *) nwfs_pathconf }, - { &vop_print_desc, (vop_t *) nwfs_print }, - { &vop_read_desc, (vop_t *) nwfs_read }, - { &vop_readdir_desc, (vop_t *) nwfs_readdir }, - { &vop_reclaim_desc, (vop_t *) nwfs_reclaim }, - { &vop_remove_desc, (vop_t *) nwfs_remove }, - { &vop_rename_desc, (vop_t *) nwfs_rename }, - { &vop_rmdir_desc, (vop_t *) nwfs_rmdir }, - { &vop_setattr_desc, (vop_t *) nwfs_setattr }, - { &vop_strategy_desc, (vop_t *) nwfs_strategy }, - { &vop_symlink_desc, (vop_t *) nwfs_symlink }, - { &vop_unlock_desc, (vop_t *) vop_stdunlock }, - { &vop_write_desc, (vop_t *) nwfs_write }, - { NULL, NULL } -}; -static struct vnodeopv_desc nwfs_vnodeop_opv_desc = - { &nwfs_vnodeop_p, nwfs_vnodeop_entries }; - -VNODEOP_SET(nwfs_vnodeop_opv_desc); - -/* - * nwfs_access vnode op - * for now just return ok - */ -static int -nwfs_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct ucred *cred = ap->a_cred; - u_int mode = ap->a_mode; - struct nwmount *nmp = VTONWFS(vp); - int error = 0; - - NCPVNDEBUG("\n"); - if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: case VDIR: case VLNK: - return (EROFS); - default: - break; - } - } - if (cred->cr_uid == 0) - return 0; - if (cred->cr_uid != nmp->m.uid) { - mode >>= 3; - if (!groupmember(nmp->m.gid, cred)) - mode >>= 3; - } - error = (((vp->v_type == VREG) ? nmp->m.file_mode : nmp->m.dir_mode) & mode) == mode ? 0 : EACCES; - return error; -} -/* - * 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 proc *a_p; - } */ *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, V_SAVE, ap->a_cred, ap->a_p, 1)) == EINTR) - return (error); - np->n_atime = 0; - error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); - if (error) return (error); - np->n_mtime = vattr.va_mtime.tv_sec; - } else { - error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); - if (error) return (error); - if (np->n_mtime != vattr.va_mtime.tv_sec) { - if ((error = nwfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1)) == 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_p, 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_p,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 proc *a_p; - } */ *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_p->p_pid,np->opened); - - if (vp->v_type == VDIR) return 0; /* nothing to do now */ - error = 0; - mtx_lock(&vp->v_interlock); - if (np->opened == 0) { - mtx_unlock(&vp->v_interlock); - return 0; - } - mtx_unlock(&vp->v_interlock); - error = nwfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1); - mtx_lock(&vp->v_interlock); - if (np->opened == 0) { - mtx_unlock(&vp->v_interlock); - return 0; - } - if (--np->opened == 0) { - mtx_unlock(&vp->v_interlock); - error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, - ap->a_p, ap->a_cred); - } else - mtx_unlock(&vp->v_interlock); - 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; - struct proc *a_p; - } */ *ap; -{ - struct vnode *vp = ap->a_vp; - struct nwnode *np = VTONW(vp); - struct vattr *va=ap->a_vap; - struct nwmount *nmp = VTONWFS(vp); - 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_flag & VROOT) != 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, - ap->a_p,ap->a_cred); - } else { - error = ncp_obtain_info(nmp, np->n_fid.f_parent, np->n_nmlen, - np->n_name, &fattr, ap->a_p, 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; - struct proc *a_p; - } */ *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, ap->a_p); - 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, ap->a_p); - 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, cnp->cn_proc))) { - 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_proc, cnp->cn_cred); - if (!error) { - error = ncp_close_file(NWFSTOCONN(nmp), &no.fh, cnp->cn_proc,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 || vp->v_usecount != 1) - return EPERM; - cache_purge(vp); - error = ncp_DeleteNSEntry(nmp, VTONW(dvp)->n_fid.f_id, - cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_proc,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 && tvp->v_usecount > 1) { - error = EBUSY; - goto out; - } - if (tvp && tvp != fvp) { - error = ncp_DeleteNSEntry(nmp, VTONW(tdvp)->n_fid.f_id, - tcnp->cn_namelen, tcnp->cn_nameptr, - tcnp->cn_proc, tcnp->cn_cred); - if (error == 0x899c) error = EACCES; - if (error) - goto out; - } - if (fvp->v_type == VDIR) { - oldtype |= NW_TYPE_SUBDIR; - } else if (fvp->v_type == VREG) { - oldtype |= NW_TYPE_FILE; - } else - return EINVAL; - 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_proc,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: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - nwfs_attr_cacheremove(fdvp); - nwfs_attr_cacheremove(tdvp); - nwfs_attr_cacheremove(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 nwnode *np; - 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, cnp->cn_proc))) { - 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_proc, 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) { - np = VTONW(newvp); - 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_proc,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 proc * a_p; - } */ *ap; -{ -/* return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p, 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("nwfs 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 proc *p; - int error = 0; - - NCPVNDEBUG("\n"); - if (bp->b_flags & B_PHYS) - panic("nwfs physio"); - if (bp->b_flags & B_ASYNC) - p = (struct proc *)0; - else - p = curproc; /* 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 ) - error = nwfs_doio(bp, cr, p); - return (error); -} - - -/* - * 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 lockparent, wantparent, error = 0, notfound; - struct proc *p = cnp->cn_proc; - 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_flag & VROOT)) { - 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, p))) - return (error); - lockparent = flags & LOCKPARENT; - wantparent = flags & (LOCKPARENT|WANTPARENT); - nmp = VFSTONWFS(mp); - dnp = VTONW(dvp); -/* -printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (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); - NCPVNDEBUG("cache_lookup returned %d\n",error); - if (error > 0) - return error; - if (error) { /* name was found */ - struct vattr vattr; - int vpid; - - vp = *vpp; - vpid = vp->v_id; - if (dvp == vp) { /* lookup on current */ - vref(vp); - error = 0; - NCPVNDEBUG("cached '.'"); - } else if (flags & ISDOTDOT) { - VOP_UNLOCK(dvp, 0, p); /* unlock parent */ - error = vget(vp, LK_EXCLUSIVE, p); - if (!error && lockparent && islastcn) - error = vn_lock(dvp, LK_EXCLUSIVE, p); - } else { - error = vget(vp, LK_EXCLUSIVE, p); - if (!lockparent || error || !islastcn) - VOP_UNLOCK(dvp, 0, p); - } - if (!error) { - if (vpid == vp->v_id) { - if (!VOP_GETATTR(vp, &vattr, cnp->cn_cred, p) - && 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); - } - vput(vp); - if (lockparent && dvp != vp && islastcn) - VOP_UNLOCK(dvp, 0, p); - } - error = vn_lock(dvp, LK_EXCLUSIVE, p); - *vpp = NULLVP; - if (error) - return (error); - } - /* 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, p, &npp); - if (error) { - return error; - } - fid = dnp->n_parent; - fap = &fattr; - /*np = *npp;*/ - notfound = ncp_obtain_info(nmp, npp->n_dosfid, - 0, NULL, fap, p, cnp->cn_cred); - } - } else { - fap = &fattr; - notfound = ncp_lookup(dvp, cnp->cn_namelen, cnp->cn_nameptr, - fap, p, 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) && wantparent && islastcn) { - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(dvp, 0, p); - 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_proc); - 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 */ - if (!lockparent) VOP_UNLOCK(dvp,0,p); - return (0); - } - if (nameiop == RENAME && islastcn && wantparent) { - error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, cnp->cn_proc); - 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; - if (!lockparent) - VOP_UNLOCK(dvp,0,p); - return (0); - } - if (flags & ISDOTDOT) { - VOP_UNLOCK(dvp, 0, p); /* race to get the inode */ - error = nwfs_nget(mp, fid, NULL, NULL, &vp); - if (error) { - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); - return (error); - } - if (lockparent && islastcn && - (error = vn_lock(dvp, LK_EXCLUSIVE, p))) { - vput(vp); - 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 (!lockparent || !islastcn) - VOP_UNLOCK(dvp, 0, p); - } - 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); -} diff --git a/usr.sbin/mount_nwfs/mount_nwfs.c b/usr.sbin/mount_nwfs/mount_nwfs.c index 02b45dd..8e37b09 100644 --- a/usr.sbin/mount_nwfs/mount_nwfs.c +++ b/usr.sbin/mount_nwfs/mount_nwfs.c @@ -51,7 +51,7 @@ #include <netncp/ncp_lib.h> #include <netncp/ncp_rcfile.h> -#include <nwfs/nwfs_mount.h> +#include <fs/nwfs/nwfs_mount.h> #include "mntopts.h" #define NWFS_VFSNAME "nwfs" diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 2d198e6..0c08f40 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -64,7 +64,7 @@ static const char rcsid[] = #include <nfs/nfs.h> #include <ufs/ufs/ufsmount.h> #include <fs/msdosfs/msdosfsmount.h> -#include <ntfs/ntfsmount.h> +#include <fs/ntfs/ntfsmount.h> #include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */ #include <arpa/inet.h> |