- 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:
parent
882f2b2b40
commit
8a8402d3a5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=77223
@ -26,8 +26,12 @@
|
||||
..
|
||||
msdosfs
|
||||
..
|
||||
ntfs
|
||||
..
|
||||
nullfs
|
||||
..
|
||||
nwfs
|
||||
..
|
||||
portalfs
|
||||
..
|
||||
procfs
|
||||
@ -77,10 +81,6 @@
|
||||
..
|
||||
nfs
|
||||
..
|
||||
ntfs
|
||||
..
|
||||
nwfs
|
||||
..
|
||||
objc
|
||||
..
|
||||
openssl
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 ! */
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../ntfs
|
||||
.PATH: ${.CURDIR}/../../fs/ntfs
|
||||
|
||||
KMOD= ntfs
|
||||
SRCS= vnode_if.h \
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../nwfs
|
||||
.PATH: ${.CURDIR}/../../fs/nwfs
|
||||
|
||||
KMOD= nwfs
|
||||
|
||||
|
334
sys/ntfs/ntfs.h
334
sys/ntfs/ntfs.h
@ -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;
|
@ -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);
|
||||
}
|
@ -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 *);
|
@ -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);
|
||||
}
|
@ -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 *));
|
@ -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. */
|
||||
};
|
2007
sys/ntfs/ntfs_subr.c
2007
sys/ntfs/ntfs_subr.c
File diff suppressed because it is too large
Load Diff
@ -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
@ -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 *);
|
@ -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
|
@ -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 */
|
||||
};
|
@ -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_ */
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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
@ -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"
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user