Garbage collect NTFS bits which are now completely disconnected from

the tree since few months.

This patch is not targeted for MFC.
This commit is contained in:
Attilio Rao 2013-03-02 18:40:04 +00:00
parent 0f90e981cb
commit 737a61a1ee
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=247665
20 changed files with 10 additions and 5023 deletions

View File

@ -38,6 +38,16 @@
# xargs -n1 | sort | uniq -d;
# done
# 20130302: NTFS support removed
OLD_FILES+=usr/include/fs/ntfs/ntfs.h
OLD_FILES+=usr/include/fs/ntfs/ntfs_compr.h
OLD_FILES+=usr/include/fs/ntfs/ntfs_ihash.h
OLD_FILES+=usr/include/fs/ntfs/ntfs_inode.h
OLD_FILES+=usr/include/fs/ntfs/ntfs_subr.h
OLD_FILES+=usr/include/fs/ntfs/ntfs_vfsops.h
OLD_FILES+=usr/include/fs/ntfs/ntfsmount.h
OLD_DIRS+=usr/include/fs/ntfs
OLD_FILES+=usr/share/man/man8/mount_ntfs.8.gz
# 20130302: PORTALFS support removed
OLD_FILES+=usr/include/fs/portalfs/portal.h
OLD_DIRS+=usr/include/fs/portalfs

View File

@ -1,71 +0,0 @@
/*-
* Copyright (c) 2005-2009 Stanislav Sedov <stas@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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <netinet/in.h>
#include <assert.h>
#include <err.h>
#include <kvm.h>
#include <stdlib.h>
#include <fs/ntfs/ntfs.h>
#include <fs/ntfs/ntfs_inode.h>
#include "libprocstat.h"
#include "common_kvm.h"
int
ntfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn)
{
struct fnode fnod;
struct ntnode node;
int error;
assert(kd);
assert(vn);
error = kvm_read_all(kd, (unsigned long)VTOF(vp), &fnod, sizeof(fnod));
if (error != 0) {
warnx("can't read ntfs fnode at %p", (void *)VTOF(vp));
return (1);
}
error = kvm_read_all(kd, (unsigned long)FTONT(&fnod), &node,
sizeof(node));
if (error != 0) {
warnx("can't read ntfs node at %p", (void *)FTONT(&fnod));
return (1);
}
vn->vn_fileid = node.i_number;
vn->vn_fsid = dev2udev(kd, node.i_dev);
return (0);
}

View File

@ -1,20 +0,0 @@
#
# $FreeBSD$
#
PROG= mount_ntfs
SRCS= mount_ntfs.c getmntopts.c
MAN= mount_ntfs.8
DPADD= ${LIBKICONV}
LDADD= -lkiconv
MOUNT= ${.CURDIR}/../mount
CFLAGS+= -I${MOUNT}
# Needs to be dynamically linked for optional dlopen() access to
# userland libiconv
NO_SHARED?= NO
.PATH: ${MOUNT}
.include <bsd.prog.mk>

View File

@ -1,173 +0,0 @@
.\"
.\" Copyright (c) 1993,1994 Christopher G. Demetriou
.\" Copyright (c) 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgment:
.\" This product includes software developed by Christopher G. Demetriou.
.\" 3. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$
.\"
.Dd November 17, 2007
.Dt MOUNT_NTFS 8
.Os
.Sh NAME
.Nm mount_ntfs
.Nd mount an NTFS file system
.Sh SYNOPSIS
.Nm
.Op Fl a
.Op Fl i
.Op Fl u Ar user
.Op Fl g Ar group
.Op Fl m Ar mask
.Op Fl C Ar charset
.Op Fl W Ar u2wtable
.Pa special
.Pa node
.Sh DESCRIPTION
The
.Nm
utility attaches the NTFS file system residing on the device
.Pa special
to the global file system namespace at the location
indicated by
.Pa node .
This command is normally executed by
.Xr mount 8
at boot time, but can be used by any user to mount an
NTFS file system on any directory that they own (provided,
of course, that they have appropriate access to the device that
contains the file system).
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a
Force behaviour to return MS-DOS 8.3 names also on
.Fn readdir .
.It Fl i
Make name lookup case insensitive for all names except POSIX names.
.It Fl u Ar user
Set the owner of the files in the file system to
.Ar user .
The default owner is the owner of the directory
on which the file system is being mounted.
.It Fl g Ar group
Set the group of the files in the file system to
.Ar group .
The default group is the group of the directory
on which the file system is being mounted.
.It Fl m Ar mask
Specify the maximum file permissions for files
in the file system.
Only the nine low-order bits of
.Ar mask
are used.
.It Fl C Ar charset
Specify local
.Ar charset
to convert Unicode file names.
Currently only reading is supported, thus the file system is to be
mounted read-only.
.It Fl W Ar u2wtable
Specify
.Ux
to
.Tn Unicode
translation table.
See
.Xr mount_msdosfs 8
for the description of this option.
.Bf Em
This option is preserved for backward compatibility purpose only,
and will be removed in the future.
Please do not use this option.
.Ef
.El
.Sh FEATURES
NTFS file attributes are accessed in following way:
.Bd -literal -offset indent
foo[[:ATTRTYPE]:ATTRNAME]
.Ed
.Pp
.Sq ATTRTYPE
is one of the identifiers listed in $AttrDef file of
volume.
Default is $DATA.
.Sq ATTRNAME
is an attribute name.
Default is none.
.Sh EXAMPLES
To mount an NTFS volume located in
.Pa /dev/ad1s1 :
.Pp
.Dl "mount_ntfs /dev/ad1s1 /mnt"
.Pp
To get the volume name (in Unicode):
.Pp
.Dl "cat /mnt/\e$Volume:\e$VOLUME_NAME"
.Pp
To read directory raw data:
.Pp
.Dl "cat /mnt/foodir:\e$INDEX_ROOT:\e$I30"
.Pp
To mount a Japanese NTFS volume located in
.Pa /dev/ad0s1 :
.Pp
.Dl "mount_ntfs -C eucJP /dev/ad0s1 /mnt"
.Sh WRITING
There is limited writing ability.
Limitations: file must be nonresident
and must not contain any sparces (uninitialized areas); compressed
files are also not supported.
The file name must not contain multibyte characters.
.Sh SEE ALSO
.Xr mount 2 ,
.Xr unmount 2 ,
.Xr fstab 5 ,
.Xr mount 8 ,
.Xr mount_msdosfs 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 3.0 .
.Pp
The Unicode conversion routine was added by
.An Ryuichiro Imura Aq imura@ryu16.org
in 2003.
.Sh AUTHORS
The NTFS kernel implementation,
.Nm
utility, and manual were written by
.An Semen Ustimenko Aq semenu@FreeBSD.org .
.Sh CAVEATS
This utility is primarily used for read access to an NTFS volume.
See the
.Sx WRITING
section for details about writing to an NTFS volume.
.Pp
For a full read-write NTFS support consider sysutils/fusefs-ntfs
port/package.

View File

@ -1,280 +0,0 @@
/*
* Copyright (c) 1994 Christopher G. Demetriou
* Copyright (c) 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/cdefs.h>
#include <sys/param.h>
#define NTFS
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/module.h>
#include <sys/iconv.h>
#include <sys/linker.h>
#include <fs/ntfs/ntfsmount.h>
#include <ctype.h>
#include <err.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <libutil.h>
#include "mntopts.h"
#define TRANSITION_PERIOD_HACK
static struct mntopt mopts[] = {
MOPT_STDOPTS,
MOPT_END
};
static gid_t a_gid(char *);
static uid_t a_uid(char *);
static mode_t a_mask(char *);
static void usage(void) __dead2;
static int set_charset(struct ntfs_args *);
int
main(int argc, char *argv[])
{
struct ntfs_args args;
struct stat sb;
int c, mntflags, set_gid, set_uid, set_mask;
char *dev, *dir, mntpath[MAXPATHLEN];
mntflags = set_gid = set_uid = set_mask = 0;
(void)memset(&args, '\0', sizeof(args));
args.cs_ntfs = NULL;
args.cs_local = NULL;
#ifdef TRANSITION_PERIOD_HACK
while ((c = getopt(argc, argv, "aiu:g:m:o:C:W:")) != -1) {
#else
while ((c = getopt(argc, argv, "aiu:g:m:o:C:")) != -1) {
#endif
switch (c) {
case 'u':
args.uid = a_uid(optarg);
set_uid = 1;
break;
case 'g':
args.gid = a_gid(optarg);
set_gid = 1;
break;
case 'm':
args.mode = a_mask(optarg);
set_mask = 1;
break;
case 'i':
args.flag |= NTFS_MFLAG_CASEINS;
break;
case 'a':
args.flag |= NTFS_MFLAG_ALLNAMES;
break;
case 'o':
getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'C':
args.cs_local = malloc(ICONV_CSNMAXLEN);
if (args.cs_local == NULL)
err(EX_OSERR, "malloc()");
strncpy(args.cs_local,
kiconv_quirkcs(optarg, KICONV_VENDOR_MICSFT),
ICONV_CSNMAXLEN);
break;
#ifdef TRANSITION_PERIOD_HACK
case 'W':
args.cs_local = malloc(ICONV_CSNMAXLEN);
if (args.cs_local == NULL)
err(EX_OSERR, "malloc()");
if (strcmp(optarg, "iso22dos") == 0) {
strcpy(args.cs_local, "ISO8859-2");
} else if (strcmp(optarg, "iso72dos") == 0) {
strcpy(args.cs_local, "ISO8859-7");
} else if (strcmp(optarg, "koi2dos") == 0) {
strcpy(args.cs_local, "KOI8-R");
} else if (strcmp(optarg, "koi8u2dos") == 0) {
strcpy(args.cs_local, "KOI8-U");
} else {
err(EX_NOINPUT, "%s", optarg);
}
break;
#endif /* TRANSITION_PERIOD_HACK */
case '?':
default:
usage();
break;
}
}
if (optind + 2 != argc)
usage();
dev = argv[optind];
dir = argv[optind + 1];
if (args.cs_local) {
if (set_charset(&args) == -1)
err(EX_OSERR, "ntfs_iconv");
args.flag |= NTFS_MFLAG_KICONV;
/*
* XXX
* Force to be MNT_RDONLY,
* since only reading is supported right now,
*/
mntflags |= MNT_RDONLY;
}
/*
* Resolve the mountpoint with realpath(3) and remove unnecessary
* slashes from the devicename if there are any.
*/
if (checkpath(dir, mntpath) != 0)
err(EX_USAGE, "%s", mntpath);
(void)rmslashes(dev, dev);
args.fspec = dev;
args.export.ex_root = 65534; /* unchecked anyway on DOS fs */
if (mntflags & MNT_RDONLY)
args.export.ex_flags = MNT_EXRDONLY;
else
args.export.ex_flags = 0;
if (!set_gid || !set_uid || !set_mask) {
if (stat(mntpath, &sb) == -1)
err(EX_OSERR, "stat %s", mntpath);
if (!set_uid)
args.uid = sb.st_uid;
if (!set_gid)
args.gid = sb.st_gid;
if (!set_mask)
args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
}
if (mount("ntfs", mntpath, mntflags, &args) < 0)
err(EX_OSERR, "%s", dev);
exit (0);
}
gid_t
a_gid(char *s)
{
struct group *gr;
char *gname;
gid_t gid;
if ((gr = getgrnam(s)) != NULL)
gid = gr->gr_gid;
else {
for (gname = s; *s && isdigit(*s); ++s);
if (!*s)
gid = atoi(gname);
else
errx(EX_NOUSER, "unknown group id: %s", gname);
}
return (gid);
}
uid_t
a_uid(char *s)
{
struct passwd *pw;
char *uname;
uid_t uid;
if ((pw = getpwnam(s)) != NULL)
uid = pw->pw_uid;
else {
for (uname = s; *s && isdigit(*s); ++s);
if (!*s)
uid = atoi(uname);
else
errx(EX_NOUSER, "unknown user id: %s", uname);
}
return (uid);
}
mode_t
a_mask(char *s)
{
int done, rv=0;
char *ep;
done = 0;
if (*s >= '0' && *s <= '7') {
done = 1;
rv = strtol(optarg, &ep, 8);
}
if (!done || rv < 0 || *ep)
errx(EX_USAGE, "invalid file mode: %s", s);
return (rv);
}
void
usage(void)
{
#ifdef TRANSITION_PERIOD_HACK
fprintf(stderr, "%s\n%s\n",
"usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask]",
" [-C charset] [-W u2wtable] special node");
#else
fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] [-C charset] special node\n");
#endif
exit(EX_USAGE);
}
int
set_charset(struct ntfs_args *pargs)
{
int error;
if (modfind("ntfs_iconv") < 0)
if (kldload("ntfs_iconv") < 0 || modfind("ntfs_iconv") < 0) {
warnx( "cannot find or load \"ntfs_iconv\" kernel module");
return (-1);
}
if ((pargs->cs_ntfs = malloc(ICONV_CSNMAXLEN)) == NULL)
return (-1);
strncpy(pargs->cs_ntfs, ENCODING_UNICODE, ICONV_CSNMAXLEN);
error = kiconv_add_xlat16_cspairs(pargs->cs_ntfs, pargs->cs_local);
if (error)
return (-1);
return (0);
}

View File

@ -1,308 +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*/
typedef uint64_t cn_t;
typedef uint16_t wchar;
#pragma pack(1)
#define BBSIZE 1024
#define BBOFF ((off_t)(0))
#define BBLOCK 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 {
uint32_t fh_magic;
uint16_t fh_foff;
uint16_t fh_fnum;
};
#define NTFS_AF_INRUN 0x00000001
struct attrhdr {
uint32_t a_type;
uint32_t reclen;
uint8_t a_flag;
uint8_t a_namelen;
uint8_t a_nameoff;
uint8_t reserved1;
uint8_t a_compression;
uint8_t reserved2;
uint16_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 {
uint16_t a_datalen;
uint16_t reserved1;
uint16_t a_dataoff;
uint16_t a_indexed;
} a_S_r;
struct {
cn_t a_vcnstart;
cn_t a_vcnend;
uint16_t a_dataoff;
uint16_t a_compressalg;
uint32_t reserved1;
uint64_t a_allocated;
uint64_t a_datalen;
uint64_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 {
uint64_t t_create;
uint64_t t_write;
uint64_t t_mftwrite;
uint64_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 {
uint32_t n_pnumber; /* Parent ntnode */
uint32_t reserved;
ntfs_times_t n_times;
uint64_t n_size;
uint64_t n_attrsz;
uint64_t n_flag;
uint8_t n_namelen;
uint8_t n_nametype;
uint16_t n_name[1];
};
#define NTFS_IRFLAG_INDXALLOC 0x00000001
struct attr_indexroot {
uint32_t ir_unkn1; /* always 0x30 */
uint32_t ir_unkn2; /* always 0x1 */
uint32_t ir_size;/* ??? */
uint32_t ir_unkn3; /* number of cluster */
uint32_t ir_unkn4; /* always 0x10 */
uint32_t ir_datalen; /* sizeof simething */
uint32_t ir_allocated; /* same as above */
uint16_t ir_flag;/* ?? always 1 */
uint16_t ir_unkn7;
};
struct attr_attrlist {
uint32_t al_type; /* Attribute type */
uint16_t reclen; /* length of this entry */
uint8_t al_namelen; /* Attribute name len */
uint8_t al_nameoff; /* Name offset from entry start */
uint64_t al_vcnstart; /* VCN number */
uint32_t al_inumber; /* Parent ntnode */
uint32_t reserved;
uint16_t al_index; /* Attribute index in MFT record */
uint16_t al_name[1]; /* Name */
};
#define NTFS_INDXMAGIC (uint32_t)(0x58444E49)
struct attr_indexalloc {
struct fixuphdr ia_fixup;
uint64_t unknown1;
cn_t ia_bufcn;
uint16_t ia_hdrsize;
uint16_t unknown2;
uint32_t ia_inuse;
uint32_t ia_allocated;
};
#define NTFS_IEFLAG_SUBNODE 0x00000001
#define NTFS_IEFLAG_LAST 0x00000002
struct attr_indexentry {
uint32_t ie_number;
uint32_t unknown1;
uint16_t reclen;
uint16_t ie_size;
uint32_t ie_flag; /* 1 - has subnodes, 2 - last */
uint32_t ie_fpnumber;
uint32_t unknown2;
ntfs_times_t ie_ftimes;
uint64_t ie_fallocated;
uint64_t ie_fsize;
uint64_t ie_fflag;
uint8_t ie_fnamelen;
uint8_t ie_fnametype;
wchar ie_fname[NTFS_MAXFILENAME];
/* cn_t ie_bufcn; buffer with subnodes */
};
#define NTFS_FILEMAGIC (uint32_t)(0x454C4946)
#define NTFS_BLOCK_SIZE 512
#define NTFS_FRFLAG_DIR 0x0002
struct filerec {
struct fixuphdr fr_fixup;
uint8_t reserved[8];
uint16_t fr_seqnum; /* Sequence number */
uint16_t fr_nlink;
uint16_t fr_attroff; /* offset to attributes */
uint16_t fr_flags; /* 1-nonresident attr, 2-directory */
uint32_t fr_size;/* hdr + attributes */
uint32_t fr_allocated; /* allocated length of record */
uint64_t fr_mainrec; /* main record */
uint16_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];
uint32_t ad_type;
uint32_t reserved1[2];
uint32_t ad_flag;
uint64_t ad_minlen;
uint64_t ad_maxlen; /* -1 for nonlimited */
};
struct ntvattrdef {
char ad_name[0x40];
int ad_namelen;
uint32_t ad_type;
};
#define NTFS_BBID "NTFS "
#define NTFS_BBIDLEN 8
struct bootfile {
uint8_t reserved1[3]; /* asm jmp near ... */
uint8_t bf_sysid[8]; /* 'NTFS ' */
uint16_t bf_bps; /* bytes per sector */
uint8_t bf_spc; /* sectors per cluster */
uint8_t reserved2[7]; /* unused (zeroed) */
uint8_t bf_media; /* media desc. (0xF8) */
uint8_t reserved3[2];
uint16_t bf_spt; /* sectors per track */
uint16_t bf_heads; /* number of heads */
uint8_t reserver4[12];
uint64_t bf_spv; /* sectors per volume */
cn_t bf_mftcn; /* $MFT cluster number */
cn_t bf_mftmirrcn; /* $MFTMirr cn */
uint8_t bf_mftrecsz; /* MFT record size (clust) */
/* 0xF6 inducates 1/4 */
uint32_t bf_ibsz; /* index buffer size */
uint32_t bf_volsn; /* volume ser. num. */
};
#define NTFS_SYSNODESNUM 0x0B
struct ntfsmount {
struct mount *ntm_mountp; /* filesystem vfs structure */
struct bootfile ntm_bootfile;
struct g_consumer *ntm_cp;
struct bufobj *ntm_bo;
struct vnode *ntm_devvp; /* block device mounted vnode */
struct vnode *ntm_sysvn[NTFS_SYSNODESNUM];
uint32_t ntm_bpmftrec;
uid_t ntm_uid;
gid_t ntm_gid;
mode_t ntm_mode;
uint64_t ntm_flag;
cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
int ntm_adnum;
wchar * ntm_82u; /* 8bit to Unicode */
char ** ntm_u28; /* Unicode to 8 bit */
void * ntm_ic_l2u; /* Local to Unicode (iconv) */
void * ntm_ic_u2l; /* Unicode to Local (iconv) */
uint8_t ntm_multiplier; /* NTFS blockno to DEV_BSIZE sectorno */
};
#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_NTFSNTNODE);
MALLOC_DECLARE(M_NTFSFNODE);
MALLOC_DECLARE(M_NTFSDIR);
MALLOC_DECLARE(M_NTFSNTHASH);
#endif
#if defined(NTFS_DEBUG)
#define dprintf(a) printf a
#if NTFS_DEBUG > 1
#define ddprintf(a) printf a
#else
#define ddprintf(a) (void)0
#endif
#else
#define dprintf(a) (void)0
#define ddprintf(a) (void)0
#endif
extern struct vop_vector ntfs_vnodeops;

View File

@ -1,111 +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>
#include <fs/ntfs/ntfs.h>
#include <fs/ntfs/ntfs_compr.h>
#define GET_UINT16(addr) (*((u_int16_t *)(addr)))
int
ntfs_uncompblock(
u_int8_t * dbuf,
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(dbuf, cbuf + 2, len + 1);
memset(dbuf + len + 1, 0, 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++) {
dbuf[pos] = dbuf[pos + boff];
pos++;
}
cpos += 2;
} else {
dbuf[pos++] = cbuf[cpos++];
}
ctag >>= 1;
}
}
return len + 3;
}
int
ntfs_uncompunit(
struct ntfsmount * ntmp,
u_int8_t * uup,
u_int8_t * cup)
{
int i;
int off = 0;
int new;
for (i = 0; i * NTFS_COMPBLOCK_SIZE < ntfs_cntob(NTFS_COMPUNIT_CL); i++) {
new = ntfs_uncompblock(uup + i * NTFS_COMPBLOCK_SIZE, cup + off);
if (new == 0)
return (EINVAL);
off += new;
}
return (0);
}

View File

@ -1,35 +0,0 @@
/* $NetBSD: ntfs_compr.h,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#define NTFS_COMPBLOCK_SIZE 0x1000
#define NTFS_COMPUNIT_CL 16
int ntfs_uncompblock(u_int8_t *, u_int8_t *);
int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, u_int8_t *);

View File

@ -1,36 +0,0 @@
/*-
* Copyright (c) 2003 Ryuichiro Imura
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/mount.h>
#include <sys/iconv.h>
VFS_DECLARE_ICONV(ntfs);

View File

@ -1,130 +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.
* 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 <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");
/*
* Structures associated with inode cacheing.
*/
static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
static u_long ntfs_nthash; /* size of hash table - 1 */
#define NTNOHASH(inum) (&ntfs_nthashtbl[(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, &ntfs_nthash);
mtx_init(&ntfs_nthash_mtx, "ntfs nthash", NULL, MTX_DEF);
}
/*
* Destroy inode hash table.
*/
void
ntfs_nthashdestroy(void)
{
hashdestroy(ntfs_nthashtbl, M_NTFSNTHASH, ntfs_nthash);
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)
struct cdev *dev;
ino_t inum;
{
struct ntnode *ip;
mtx_lock(&ntfs_nthash_mtx);
LIST_FOREACH(ip, NTNOHASH(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_number);
LIST_INSERT_HEAD(ipp, ip, i_hash);
ip->i_flag |= IN_HASHED;
mtx_unlock(&ntfs_nthash_mtx);
}
/*
* Remove the inode from the hash table.
*/
void
ntfs_nthashrem(ip)
struct ntnode *ip;
{
mtx_lock(&ntfs_nthash_mtx);
if (ip->i_flag & IN_HASHED) {
ip->i_flag &= ~IN_HASHED;
LIST_REMOVE(ip, i_hash);
}
mtx_unlock(&ntfs_nthash_mtx);
}

View File

@ -1,37 +0,0 @@
/* $NetBSD: ntfs_ihash.h,v 1.4 1999/09/30 16:56:40 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
extern struct lock ntfs_hashlock;
void ntfs_nthashinit(void);
void ntfs_nthashdestroy(void);
struct ntnode *ntfs_nthashlookup(struct cdev *, ino_t);
struct ntnode *ntfs_nthashget(struct cdev *, ino_t);
void ntfs_nthashins(struct ntnode *);
void ntfs_nthashrem(register struct ntnode *);

View File

@ -1,101 +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. */
#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. */
#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 */
struct cdev *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 {
LIST_ENTRY(fnode) f_fnlist;
struct vnode *f_vp; /* Associatied vnode */
struct ntnode *f_ip; /* Associated ntnode */
u_long f_flag;
ntfs_times_t f_times; /* $NAME/dirinfo */
ino_t f_pnumber; /* $NAME/dirinfo */
u_int32_t f_fflag; /* $NAME/dirinfo */
u_int64_t f_size; /* defattr/dirinfo: */
u_int64_t f_allocated; /* defattr/dirinfo */
u_int32_t f_attrtype;
char *f_attrname;
/* for ntreaddir */
u_int32_t f_lastdattr;
u_int32_t f_lastdblnum;
u_int32_t f_lastdoff;
u_int32_t f_lastdnum;
caddr_t f_dirblbuf;
u_int32_t f_dirblsz;
};
/* This overlays the fid structure (see <sys/mount.h>) */
struct ntfid {
u_int16_t ntfid_len; /* Length of structure. */
u_int16_t ntfid_pad; /* Force 32-bit alignment. */
ino_t ntfid_ino; /* File number (ino). */
int32_t ntfid_gen; /* Generation number. */
};

File diff suppressed because it is too large Load Diff

View File

@ -1,120 +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_int64_t va_datalen;
u_int64_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( struct ntfsmount *, u_int32_t, caddr_t, size_t );
int ntfs_parserun( cn_t *, cn_t *, u_int8_t *, u_long, u_long *);
int ntfs_runtocn( cn_t *, struct ntfsmount *, u_int8_t *, u_long, cn_t);
int ntfs_readntvattr_plain( struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *,size_t *, struct uio *);
int ntfs_readattr_plain( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *, struct uio *);
int ntfs_readattr( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, struct uio *);
int ntfs_filesize( struct ntfsmount *, struct fnode *, u_int64_t *, u_int64_t *);
int ntfs_times( struct ntfsmount *, struct ntnode *, ntfs_times_t *);
struct timespec ntfs_nttimetounix( u_int64_t );
int ntfs_ntreaddir( struct ntfsmount *, struct fnode *, u_int32_t, struct attr_indexentry **);
int ntfs_runtovrun( cn_t **, cn_t **, u_long *, u_int8_t *);
int ntfs_attrtontvattr( struct ntfsmount *, struct ntvattr **, struct attr * );
void ntfs_freentvattr( struct ntvattr * );
int ntfs_loadntvattrs( struct ntfsmount *, struct vnode *, caddr_t, struct ntvattr **);
struct ntvattr * ntfs_findntvattr( struct ntfsmount *, struct ntnode *, u_int32_t, cn_t );
int ntfs_ntlookupfile(struct ntfsmount *, struct vnode *, struct componentname *, struct vnode **);
int ntfs_isnamepermitted(struct ntfsmount *, struct attr_indexentry * );
int ntfs_ntvattrrele(struct ntvattr * );
int ntfs_ntvattrget(struct ntfsmount *, struct ntnode *, u_int32_t, const char *, cn_t , struct ntvattr **);
int ntfs_ntlookup(struct ntfsmount *, ino_t, struct ntnode **);
int ntfs_ntget(struct ntnode *);
void ntfs_ntref(struct ntnode *);
void ntfs_ntrele(struct ntnode *);
void ntfs_ntput(struct ntnode *);
int ntfs_loadntnode( struct ntfsmount *, struct ntnode * );
void ntfs_toupper_init(void);
void ntfs_toupper_destroy(void);
int ntfs_toupper_use(struct mount *, struct ntfsmount *);
void ntfs_toupper_unuse(void);
int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
void ntfs_frele(struct fnode *);
int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w, char *cs_local, char *cs_ntfs);
int ntfs_u28_uninit(struct ntfsmount *ntmp);
int ntfs_82u_init(struct ntfsmount *ntmp, char *cs_local, char *cs_ntfs);
int ntfs_82u_uninit(struct ntfsmount *ntmp);
char * ntfs_u28(char *outbuf, struct ntfsmount *ntmp, wchar wc);
wchar ntfs_82u(struct ntfsmount *ntmp, const char *c, int *len);
#define NTFS_U28(ch) ntfs_u28(tmpbuf, ntmp, (ch))
#define NTFS_82U(ch, len) ntfs_82u(ntmp, (ch), len)
#define NTFS_UASTRCMP(ustr, ustrlen, astr, astrlen) \
ntfs_uastrcmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
#define NTFS_UASTRICMP(ustr, ustrlen, astr, astrlen) \
ntfs_uastricmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))

View File

@ -1,780 +0,0 @@
/* $NetBSD: ntfs_vfsops.c,v 1.23 1999/11/15 19:38:14 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
#include <sys/conf.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/stat.h>
#include <sys/systm.h>
#include <geom/geom.h>
#include <geom/geom_vfs.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
/*#define NTFS_DEBUG 1*/
#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>
static MALLOC_DEFINE(M_NTFSMNT, "ntfs_mount", "NTFS mount structure");
MALLOC_DEFINE(M_NTFSNTNODE,"ntfs_ntnode", "NTFS ntnode information");
MALLOC_DEFINE(M_NTFSFNODE,"ntfs_fnode", "NTFS fnode information");
MALLOC_DEFINE(M_NTFSDIR,"ntfs_dir", "NTFS dir buffer");
static int ntfs_mountfs(register struct vnode *, struct mount *,
struct thread *);
static int ntfs_calccfree(struct ntfsmount *ntmp, cn_t *cfreep);
static vfs_init_t ntfs_init;
static vfs_uninit_t ntfs_uninit;
static vfs_vget_t ntfs_vget;
static vfs_fhtovp_t ntfs_fhtovp;
static vfs_cmount_t ntfs_cmount;
static vfs_mount_t ntfs_mount;
static vfs_root_t ntfs_root;
static vfs_statfs_t ntfs_statfs;
static vfs_unmount_t ntfs_unmount;
static b_strategy_t ntfs_bufstrategy;
/*
* Buffer operations for NTFS vnodes.
* We punt on VOP_BMAP, so we need to do
* strategy on the file's vnode rather
* than the underlying device's
*/
static struct buf_ops ntfs_vnbufops = {
.bop_name = "NTFS",
.bop_strategy = ntfs_bufstrategy,
};
static int
ntfs_init (
struct vfsconf *vcp )
{
ntfs_nthashinit();
ntfs_toupper_init();
return 0;
}
static int
ntfs_uninit (
struct vfsconf *vcp )
{
ntfs_toupper_destroy();
ntfs_nthashdestroy();
return 0;
}
static int
ntfs_cmount (
struct mntarg *ma,
void *data,
uint64_t flags)
{
struct ntfs_args args;
struct export_args exp;
int error;
error = copyin(data, &args, sizeof(args));
if (error)
return (error);
vfs_oexport_conv(&args.export, &exp);
ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
ma = mount_arg(ma, "export", &exp, sizeof(exp));
ma = mount_argf(ma, "uid", "%d", args.uid);
ma = mount_argf(ma, "gid", "%d", args.gid);
ma = mount_argf(ma, "mode", "%d", args.mode);
ma = mount_argb(ma, args.flag & NTFS_MFLAG_CASEINS, "nocaseins");
ma = mount_argb(ma, args.flag & NTFS_MFLAG_ALLNAMES, "noallnames");
if (args.flag & NTFS_MFLAG_KICONV) {
ma = mount_argsu(ma, "cs_ntfs", args.cs_ntfs, 64);
ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
}
error = kernel_mount(ma, flags);
return (error);
}
static const char *ntfs_opts[] = {
"from", "export", "uid", "gid", "mode", "caseins", "allnames",
"kiconv", "cs_ntfs", "cs_local", NULL
};
static int
ntfs_mount(struct mount *mp)
{
int err = 0, error;
struct vnode *devvp;
struct nameidata ndp;
struct thread *td;
char *from;
td = curthread;
if (vfs_filteropt(mp->mnt_optnew, ntfs_opts))
return (EINVAL);
/* Force mount as read-only. */
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_RDONLY;
MNT_IUNLOCK(mp);
from = vfs_getopts(mp->mnt_optnew, "from", &error);
if (error)
return (error);
/*
* If updating, check whether changing from read-only to
* read/write.
*/
if (mp->mnt_flag & MNT_UPDATE) {
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
/* Process export requests in vfs_mount.c */
return (0);
} else {
printf("ntfs_mount(): MNT_UPDATE not supported\n");
return (EINVAL);
}
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td);
err = namei(&ndp);
if (err)
return (err);
NDFREE(&ndp, NDF_ONLY_PNBUF);
devvp = ndp.ni_vp;
if (!vn_isdisk(devvp, &err)) {
vput(devvp);
return (err);
}
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
err = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
if (err)
err = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (err) {
vput(devvp);
return (err);
}
/*
* Since this is a new mount, we want the names for the device and
* the mount point copied in. If an error occurs, the mountpoint is
* discarded by the upper level code. Note that vfs_mount() handles
* copying the mountpoint f_mntonname for us, so we don't have to do
* it here unless we want to set it to something other than "path"
* for some rason.
*/
err = ntfs_mountfs(devvp, mp, td);
if (err == 0) {
/* Save "mounted from" info for mount point. */
vfs_mountedfrom(mp, from);
} else
vrele(devvp);
return (err);
}
/*
* Common code for mount and mountroot
*/
int
ntfs_mountfs(devvp, mp, td)
register struct vnode *devvp;
struct mount *mp;
struct thread *td;
{
struct buf *bp;
struct ntfsmount *ntmp;
struct cdev *dev = devvp->v_rdev;
int error, i, v;
struct vnode *vp;
struct g_consumer *cp;
struct g_provider *pp;
char *cs_ntfs, *cs_local;
DROP_GIANT();
g_topology_lock();
/*
* XXX: Do not allow more than one consumer to open a device
* associated with a particular GEOM provider.
* This disables multiple read-only mounts of a device,
* but it gets rid of panics in vget() when you try to
* mount the same device more than once.
*/
pp = g_dev_getprovider(devvp->v_rdev);
if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
error = EPERM;
else
error = g_vfs_open(devvp, &cp, "ntfs", 0);
g_topology_unlock();
PICKUP_GIANT();
VOP_UNLOCK(devvp, 0);
if (error)
return (error);
bp = NULL;
error = bread(devvp, BBLOCK, BBSIZE, NOCRED, &bp);
if (error)
goto out;
ntmp = malloc( sizeof *ntmp, M_NTFSMNT, M_WAITOK | M_ZERO);
bcopy( bp->b_data, &ntmp->ntm_bootfile, sizeof(struct bootfile) );
/*
* We must not cache the boot block if its size is not exactly
* one cluster in order to avoid confusing the buffer cache when
* the boot file is read later by ntfs_readntvattr_plain(), which
* reads a cluster at a time.
*/
if (ntfs_cntob(1) != BBSIZE)
bp->b_flags |= B_NOCACHE;
brelse( bp );
bp = NULL;
if (strncmp((const char *)ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
error = EINVAL;
dprintf(("ntfs_mountfs: invalid boot block\n"));
goto out;
}
{
int8_t cpr = ntmp->ntm_mftrecsz;
if( cpr > 0 )
ntmp->ntm_bpmftrec = ntmp->ntm_spc * cpr;
else
ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
}
ntmp->ntm_multiplier = ntmp->ntm_bps / DEV_BSIZE;
dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
(u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
ntmp->ntm_mountp = mp;
ntmp->ntm_devvp = devvp;
if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v) == 1)
ntmp->ntm_uid = v;
if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v) == 1)
ntmp->ntm_gid = v;
if (vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v) == 1)
ntmp->ntm_mode = v & ACCESSPERMS;
vfs_flagopt(mp->mnt_optnew,
"caseins", &ntmp->ntm_flag, NTFS_MFLAG_CASEINS);
vfs_flagopt(mp->mnt_optnew,
"allnames", &ntmp->ntm_flag, NTFS_MFLAG_ALLNAMES);
ntmp->ntm_cp = cp;
ntmp->ntm_bo = &devvp->v_bufobj;
cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error);
if (error && error != ENOENT)
goto out;
cs_ntfs = vfs_getopts(mp->mnt_optnew, "cs_ntfs", &error);
if (error && error != ENOENT)
goto out;
/* Copy in the 8-bit to Unicode conversion table */
/* Initialize Unicode to 8-bit table from 8toU table */
ntfs_82u_init(ntmp, cs_local, cs_ntfs);
if (cs_local != NULL && cs_ntfs != NULL)
ntfs_u28_init(ntmp, NULL, cs_local, cs_ntfs);
else
ntfs_u28_init(ntmp, ntmp->ntm_82u, cs_local, cs_ntfs);
mp->mnt_data = ntmp;
dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
(ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
/*
* We read in some system nodes to do not allow
* reclaim them and to have everytime access to them.
*/
{
int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
for (i=0; i<3; i++) {
error = VFS_VGET(mp, pi[i], LK_EXCLUSIVE,
&(ntmp->ntm_sysvn[pi[i]]));
if(error)
goto out1;
ntmp->ntm_sysvn[pi[i]]->v_vflag |= VV_SYSTEM;
VREF(ntmp->ntm_sysvn[pi[i]]);
vput(ntmp->ntm_sysvn[pi[i]]);
}
}
/* read the Unicode lowercase --> uppercase translation table,
* if necessary */
if ((error = ntfs_toupper_use(mp, ntmp)))
goto out1;
/*
* Scan $BitMap and count free clusters
*/
error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
if(error)
goto out1;
/*
* Read and translate to internal format attribute
* definition file.
*/
{
int num,j;
struct attrdef ad;
/* Open $AttrDef */
error = VFS_VGET(mp, NTFS_ATTRDEFINO, LK_EXCLUSIVE, &vp );
if(error)
goto out1;
/* Count valid entries */
for(num=0;;num++) {
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
num * sizeof(ad), sizeof(ad),
&ad, NULL);
if (error)
goto out1;
if (ad.ad_name[0] == 0)
break;
}
/* Alloc memory for attribute definitions */
ntmp->ntm_ad = malloc(num * sizeof(struct ntvattrdef),
M_NTFSMNT, M_WAITOK);
ntmp->ntm_adnum = num;
/* Read them and translate */
for(i=0;i<num;i++){
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
i * sizeof(ad), sizeof(ad),
&ad, NULL);
if (error)
goto out1;
j = 0;
do {
ntmp->ntm_ad[i].ad_name[j] = ad.ad_name[j];
} while(ad.ad_name[j++]);
ntmp->ntm_ad[i].ad_namelen = j - 1;
ntmp->ntm_ad[i].ad_type = ad.ad_type;
}
vput(vp);
}
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
mp->mnt_maxsymlinklen = 0;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
MNT_IUNLOCK(mp);
return (0);
out1:
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
if (vflush(mp, 0, 0, td))
dprintf(("ntfs_mountfs: vflush failed\n"));
out:
if (bp)
brelse(bp);
DROP_GIANT();
g_topology_lock();
g_vfs_close(cp);
g_topology_unlock();
PICKUP_GIANT();
return (error);
}
static int
ntfs_unmount(
struct mount *mp,
int mntflags)
{
struct thread *td;
struct ntfsmount *ntmp;
int error, flags, i;
dprintf(("ntfs_unmount: unmounting...\n"));
td = curthread;
ntmp = VFSTONTFS(mp);
flags = 0;
if(mntflags & MNT_FORCE)
flags |= FORCECLOSE;
dprintf(("ntfs_unmount: vflushing...\n"));
error = vflush(mp, 0, flags | SKIPSYSTEM, td);
if (error) {
printf("ntfs_unmount: vflush failed: %d\n",error);
return (error);
}
/* Check if only system vnodes are rest */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if((ntmp->ntm_sysvn[i]) &&
(vrefcnt(ntmp->ntm_sysvn[i]) > 1)) return (EBUSY);
/* Dereference all system vnodes */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
/* vflush system vnodes */
error = vflush(mp, 0, flags, td);
if (error)
printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
vinvalbuf(ntmp->ntm_devvp, V_SAVE, 0, 0);
DROP_GIANT();
g_topology_lock();
g_vfs_close(ntmp->ntm_cp);
g_topology_unlock();
PICKUP_GIANT();
vrele(ntmp->ntm_devvp);
/* free the toupper table, if this has been last mounted ntfs volume */
ntfs_toupper_unuse();
dprintf(("ntfs_umount: freeing memory...\n"));
ntfs_u28_uninit(ntmp);
ntfs_82u_uninit(ntmp);
mp->mnt_data = NULL;
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp);
free(ntmp->ntm_ad, M_NTFSMNT);
free(ntmp, M_NTFSMNT);
return (error);
}
static int
ntfs_root(
struct mount *mp,
int flags,
struct vnode **vpp)
{
struct vnode *nvp;
int error = 0;
dprintf(("ntfs_root(): sysvn: %p\n",
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, LK_EXCLUSIVE, &nvp);
if(error) {
printf("ntfs_root: VFS_VGET failed: %d\n",error);
return (error);
}
*vpp = nvp;
return (0);
}
static int
ntfs_calccfree(
struct ntfsmount *ntmp,
cn_t *cfreep)
{
struct vnode *vp;
u_int8_t *tmp;
int j, error;
long cfree = 0;
size_t bmsize, i;
vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
bmsize = VTOF(vp)->f_size;
tmp = malloc(bmsize, M_TEMP, M_WAITOK);
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, bmsize, tmp, NULL);
if (error)
goto out;
for(i=0;i<bmsize;i++)
for(j=0;j<8;j++)
if(~tmp[i] & (1 << j)) cfree++;
*cfreep = cfree;
out:
free(tmp, M_TEMP);
return(error);
}
static int
ntfs_statfs(
struct mount *mp,
struct statfs *sbp)
{
struct ntfsmount *ntmp = VFSTONTFS(mp);
u_int64_t mftsize,mftallocated;
dprintf(("ntfs_statfs():\n"));
mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size;
mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
sbp->f_type = mp->mnt_vfc->vfc_typenum;
sbp->f_bsize = ntmp->ntm_bps;
sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
sbp->f_ffree;
sbp->f_flags = mp->mnt_flag;
return (0);
}
/*ARGSUSED*/
static int
ntfs_fhtovp(
struct mount *mp,
struct fid *fhp,
int flags,
struct vnode **vpp)
{
struct vnode *nvp;
struct ntfid *ntfhp = (struct ntfid *)fhp;
int error;
ddprintf(("ntfs_fhtovp(): %d\n", ntfhp->ntfid_ino));
if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, LK_EXCLUSIVE, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
/* XXX as unlink/rmdir/mkdir/creat are not currently possible
* with NTFS, we don't need to check anything else for now */
*vpp = nvp;
vnode_create_vobject(nvp, VTOF(nvp)->f_size, curthread);
return (0);
}
int
ntfs_vgetex(
struct mount *mp,
ino_t ino,
u_int32_t attrtype,
char *attrname,
u_long lkflags,
u_long flags,
struct thread *td,
struct vnode **vpp)
{
int error;
register struct ntfsmount *ntmp;
struct ntnode *ip;
struct fnode *fp;
struct vnode *vp;
enum vtype f_type;
dprintf(("ntfs_vgetex: ino: %ju, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
(uintmax_t)ino, attrtype, attrname ? attrname : "", lkflags,
(u_long)flags));
ntmp = VFSTONTFS(mp);
*vpp = NULL;
/* Get ntnode */
error = ntfs_ntlookup(ntmp, ino, &ip);
if (error) {
printf("ntfs_vget: ntfs_ntget failed\n");
return (error);
}
/* It may be not initialized fully, so force load it */
if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
error = ntfs_loadntnode(ntmp, ip);
if(error) {
printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %ju\n",
(uintmax_t)ip->i_number);
ntfs_ntput(ip);
return (error);
}
}
error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
if (error) {
printf("ntfs_vget: ntfs_fget failed\n");
ntfs_ntput(ip);
return (error);
}
f_type = VNON;
if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
(fp->f_attrtype == NTFS_A_DATA && fp->f_attrname == NULL)) {
f_type = VDIR;
} else if (flags & VG_EXT) {
f_type = VNON;
fp->f_size = fp->f_allocated = 0;
} else {
f_type = VREG;
error = ntfs_filesize(ntmp, fp,
&fp->f_size, &fp->f_allocated);
if (error) {
ntfs_ntput(ip);
return (error);
}
}
fp->f_flag |= FN_VALID;
}
if (FTOV(fp)) {
vget(FTOV(fp), lkflags, td);
*vpp = FTOV(fp);
ntfs_ntput(ip);
return (0);
}
error = getnewvnode("ntfs", ntmp->ntm_mountp, &ntfs_vnodeops, &vp);
if(error) {
ntfs_frele(fp);
ntfs_ntput(ip);
return (error);
}
/* XXX: Too early for mpsafe fs, lacks vnode lock */
error = insmntque(vp, ntmp->ntm_mountp);
if (error) {
ntfs_frele(fp);
ntfs_ntput(ip);
return (error);
}
dprintf(("ntfs_vget: vnode: %p for ntnode: %ju\n", vp, (uintmax_t)ino));
fp->f_vp = vp;
vp->v_data = fp;
vp->v_type = f_type;
vp->v_bufobj.bo_ops = &ntfs_vnbufops;
vp->v_bufobj.bo_private = vp;
if (ino == NTFS_ROOTINO)
vp->v_vflag |= VV_ROOT;
ntfs_ntput(ip);
if (lkflags & LK_TYPE_MASK) {
error = vn_lock(vp, lkflags);
if (error) {
vput(vp);
return (error);
}
}
*vpp = vp;
return (0);
}
static int
ntfs_vget(
struct mount *mp,
ino_t ino,
int lkflags,
struct vnode **vpp)
{
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, lkflags, 0,
curthread, vpp);
}
static void
ntfs_bufstrategy(struct bufobj *bo, struct buf *bp)
{
struct vnode *vp;
int rc;
vp = bo->bo_private;
KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
vp, &vp->v_bufobj, bo));
rc = VOP_STRATEGY(vp, bp);
KASSERT(rc == 0, ("NTFS VOP_STRATEGY failed: bp=%p, "
"vp=%p, rc=%d", bp, vp, rc));
}
static struct vfsops ntfs_vfsops = {
.vfs_fhtovp = ntfs_fhtovp,
.vfs_init = ntfs_init,
.vfs_cmount = ntfs_cmount,
.vfs_mount = ntfs_mount,
.vfs_root = ntfs_root,
.vfs_statfs = ntfs_statfs,
.vfs_uninit = ntfs_uninit,
.vfs_unmount = ntfs_unmount,
.vfs_vget = ntfs_vget,
};
VFS_SET(ntfs_vfsops, ntfs, VFCF_READONLY);
MODULE_VERSION(ntfs, 1);

View File

@ -1,43 +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 thread;
struct vnode;
int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
struct thread *, struct vnode **);

View File

@ -1,687 +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.
* 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>
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
#include <vm/vm_extern.h>
#include <sys/sysctl.h>
/*#define NTFS_DEBUG 1*/
#include <fs/ntfs/ntfs.h>
#include <fs/ntfs/ntfs_inode.h>
#include <fs/ntfs/ntfs_subr.h>
#include <sys/unistd.h> /* for pathconf(2) constants */
static vop_read_t ntfs_read;
static vop_getattr_t ntfs_getattr;
static vop_inactive_t ntfs_inactive;
static vop_reclaim_t ntfs_reclaim;
static vop_bmap_t ntfs_bmap;
static vop_strategy_t ntfs_strategy;
static vop_access_t ntfs_access;
static vop_open_t ntfs_open;
static vop_close_t ntfs_close;
static vop_readdir_t ntfs_readdir;
static vop_cachedlookup_t ntfs_lookup;
static vop_pathconf_t ntfs_pathconf;
static vop_vptofh_t ntfs_vptofh;
/*
* 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 bufobj **a_bop;
daddr_t *a_bnp;
int *a_runp;
int *a_runb;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn));
if (ap->a_bop != NULL)
*ap->a_bop = &vp->v_bufobj;
if (ap->a_bnp != NULL)
*ap->a_bnp = ap->a_bn;
if (ap->a_runp != NULL)
*ap->a_runp = 0;
if (ap->a_runb != NULL)
*ap->a_runb = 0;
return (0);
}
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;
struct buf *bp;
daddr_t cn;
int resid, off, toread;
int error;
dprintf(("ntfs_read: ino: %ju, off: %jd resid: %d, segflg: %d\n",
(uintmax_t)ip->i_number, (intmax_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)
return (0);
resid = MIN(uio->uio_resid, fp->f_size - uio->uio_offset);
dprintf((", resid: %d\n", resid));
error = 0;
while (resid) {
cn = ntfs_btocn(uio->uio_offset);
off = ntfs_btocnoff(uio->uio_offset);
toread = MIN(off + resid, ntfs_cntob(1));
error = bread(vp, cn, ntfs_cntob(1), NOCRED, &bp);
if (error) {
brelse(bp);
break;
}
error = uiomove(bp->b_data + off, toread - off, uio);
if(error) {
brelse(bp);
break;
}
brelse(bp);
resid -= toread - off;
}
return (error);
}
static int
ntfs_getattr(ap)
struct vop_getattr_args /* {
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
struct thread *a_td;
} */ *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: %ju, flags: %d\n",
(uintmax_t)ip->i_number, ip->i_flag));
vap->va_fsid = dev2udev(ip->i_dev);
vap->va_fileid = ip->i_number;
vap->va_mode = ip->i_mp->ntm_mode;
vap->va_nlink = (ip->i_nlink || ip->i_flag & IN_LOADED ? ip->i_nlink : 1);
vap->va_uid = ip->i_mp->ntm_uid;
vap->va_gid = ip->i_mp->ntm_gid;
vap->va_rdev = NODEV;
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;
{
#ifdef NTFS_DEBUG
register struct ntnode *ip = VTONT(ap->a_vp);
#endif
dprintf(("ntfs_inactive: vnode: %p, ntnode: %ju\n", ap->a_vp,
(uintmax_t)ip->i_number));
/* 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: %ju\n",
vp, (uintmax_t)ip->i_number));
/*
* Destroy the vm object and flush associated pages.
*/
vnode_destroy_vobject(vp);
if ((error = ntfs_ntget(ip)) != 0)
return (error);
/* Purge old data structures associated with the inode. */
ntfs_frele(fp);
ntfs_ntput(ip);
vp->v_data = NULL;
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 = ap->a_vp;
register struct fnode *fp = VTOF(vp);
register struct ntnode *ip = FTONT(fp);
struct ntfsmount *ntmp = ip->i_mp;
u_int32_t toread;
int error;
dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
(u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno,
(u_int32_t)bp->b_lblkno));
dprintf(("strategy: bcount: %d flags: 0x%x\n",
(u_int32_t)bp->b_bcount,bp->b_flags));
KASSERT(bp->b_iocmd == BIO_READ, ("Invalid buffer\n"));
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);
}
bufdone(bp);
return (0);
}
int
ntfs_access(ap)
struct vop_access_args /* {
struct vnode *a_vp;
accmode_t a_accmode;
struct ucred *a_cred;
struct thread *a_td;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct ntnode *ip = VTONT(vp);
accmode_t accmode = ap->a_accmode;
dprintf(("ntfs_access: %d\n",ip->i_number));
/*
* Disallow write attempts as we assume read-only filesystems;
* unless the file is a socket, fifo, or a block or
* character device resident on the filesystem.
*/
if (accmode & VWRITE) {
switch ((int)vp->v_type) {
case VDIR:
case VLNK:
case VREG:
return (EROFS);
default:
break;
}
}
return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid,
ip->i_mp->ntm_gid, ap->a_accmode, 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 thread *a_td;
} */ *ap;
{
#ifdef NTFS_DEBUG
register struct vnode *vp = ap->a_vp;
register struct ntnode *ip = VTONT(vp);
printf("ntfs_open: %d\n",ip->i_number);
#endif
vnode_create_vobject(ap->a_vp, VTOF(ap->a_vp)->f_size, ap->a_td);
/*
* 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 thread *a_td;
} */ *ap;
{
#ifdef 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, j, error = 0;
char *c, tmpbuf[5];
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 = {
.d_fileno = NTFS_ROOTINO,
.d_reclen = sizeof(struct dirent),
.d_type = DT_DIR,
.d_namlen = 1,
.d_name = "."
};
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 = {
.d_fileno = NTFS_ROOTINO,
.d_reclen = sizeof(struct dirent),
.d_type = DT_DIR,
.d_namlen = 2,
.d_name = ".."
};
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, j=0; i<iep->ie_fnamelen; i++) {
c = NTFS_U28(iep->ie_fname[i]);
while (*c != '\0')
cde.d_name[j++] = *c++;
}
cde.d_name[j] = '\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 = j;
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;
u_long *cookies;
u_long *cookiep;
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));
cookies = malloc(ncookies * sizeof(u_long),
M_TEMP, M_WAITOK);
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_cachedlookup_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;
dprintf(("ntfs_lookup: \"%.*s\" (%ld bytes) in %d\n",
(int)cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_namelen,
dip->i_number));
error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_thread);
if(error)
return (error);
if ((cnp->cn_flags & ISLASTCN) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
return (EROFS);
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);
dprintf(("ntfs_lookup: parentdir: %d\n",
vap->va_a_name->n_pnumber));
error = VFS_VGET(ntmp->ntm_mountp, vap->va_a_name->n_pnumber,
LK_EXCLUSIVE, ap->a_vpp);
ntfs_ntvattrrele(vap);
if (error) {
vn_lock(dvp,LK_EXCLUSIVE|LK_RETRY);
return (error);
}
} 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: %ju\n",
(uintmax_t)VTONT(*ap->a_vpp)->i_number));
}
if (cnp->cn_flags & MAKEENTRY)
cache_enter(dvp, *ap->a_vpp, cnp);
return (error);
}
/*
* Return POSIX pathconf information applicable to NTFS filesystem
*/
int
ntfs_pathconf(ap)
struct vop_pathconf_args *ap;
{
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);
default:
return (EINVAL);
}
/* NOTREACHED */
}
int
ntfs_vptofh(ap)
struct vop_vptofh_args /* {
struct vnode *a_vp;
struct fid *a_fhp;
} */ *ap;
{
register struct ntnode *ntp;
register struct ntfid *ntfhp;
ddprintf(("ntfs_fhtovp(): %p\n", ap->a_vp));
ntp = VTONT(ap->a_vp);
ntfhp = (struct ntfid *)ap->a_fhp;
ntfhp->ntfid_len = sizeof(struct ntfid);
ntfhp->ntfid_ino = ntp->i_number;
/* ntfhp->ntfid_gen = ntp->i_gen; */
return (0);
}
/*
* Global vfs data structures
*/
struct vop_vector ntfs_vnodeops = {
.vop_default = &default_vnodeops,
.vop_access = ntfs_access,
.vop_bmap = ntfs_bmap,
.vop_cachedlookup = ntfs_lookup,
.vop_close = ntfs_close,
.vop_getattr = ntfs_getattr,
.vop_inactive = ntfs_inactive,
.vop_lookup = vfs_cache_lookup,
.vop_open = ntfs_open,
.vop_pathconf = ntfs_pathconf,
.vop_read = ntfs_read,
.vop_readdir = ntfs_readdir,
.vop_reclaim = ntfs_reclaim,
.vop_strategy = ntfs_strategy,
.vop_vptofh = ntfs_vptofh,
};

View File

@ -1,44 +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
#define NTFS_MFLAG_KICONV 0x00000004
struct ntfs_args {
char *fspec; /* block special device to mount */
struct oexport_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 */
char *cs_ntfs; /* NTFS Charset */
char *cs_local; /* Local Charset */
};

View File

@ -1,11 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../fs/ntfs
KMOD= ntfs
SRCS= vnode_if.h \
ntfs_vfsops.c ntfs_vnops.c ntfs_subr.c ntfs_ihash.c \
ntfs_compr.c
EXPORT_SYMS= ntfs_iconv
.include <bsd.kmod.mk>

View File

@ -1,7 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../fs/ntfs
KMOD= ntfs_iconv
SRCS= ntfs_iconv.c
.include <bsd.kmod.mk>