- sys/n[tw]fs moved to sys/fs/n[tw]fs

- /usr/include/n[tw]fs moved to /usr/include/fs/n[tw]fs
This commit is contained in:
Ruslan Ermilov 2001-05-26 11:57:45 +00:00
parent 882f2b2b40
commit 8a8402d3a5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=77223
47 changed files with 68 additions and 8730 deletions

View File

@ -26,8 +26,12 @@
..
msdosfs
..
ntfs
..
nullfs
..
nwfs
..
portalfs
..
procfs
@ -77,10 +81,6 @@
..
nfs
..
ntfs
..
nwfs
..
objc
..
openssl

View File

@ -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

View File

@ -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 ! */

View File

@ -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) {

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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>

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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])

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../ntfs
.PATH: ${.CURDIR}/../../fs/ntfs
KMOD= ntfs
SRCS= vnode_if.h \

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../nwfs
.PATH: ${.CURDIR}/../../fs/nwfs
KMOD= nwfs

View File

@ -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;

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 *));

View File

@ -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. */
};

File diff suppressed because it is too large Load Diff

View File

@ -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 *));

File diff suppressed because it is too large Load Diff

View File

@ -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 *);

View File

@ -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

View File

@ -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 */
};

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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>