Merged NetBSD version, as they have done improvements:

1. ntfs_read*attr*() functions now accept
	uio structure to eliminate one data copying.
	2. found and removed deadlock caused
	by 6 concurent ls -lR.
	3. started implementation of nromal
	Unicode<->unix recodeing.

Obtained from:	NetBSD
This commit is contained in:
Semen Ustimenko 1999-12-03 20:37:40 +00:00
parent 2076235ada
commit b17f083b0f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=54095
25 changed files with 2212 additions and 2051 deletions

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs.h,v 1.2 1999/05/06 15:43:17 christos Exp $ */
/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -29,6 +29,9 @@
*/
/*#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;
@ -239,12 +242,11 @@ struct bootfile {
#define NTFS_SYSNODESNUM 0x0B
struct ntfsmount {
struct mount *ntm_mountp;
struct mount *ntm_mountp; /* filesystem vfs structure */
struct bootfile ntm_bootfile;
dev_t ntm_dev;
struct vnode *ntm_devvp;
dev_t ntm_dev; /* device mounted */
struct vnode *ntm_devvp; /* block device mounted vnode */
struct vnode *ntm_sysvn[NTFS_SYSNODESNUM];
wchar *ntm_upcase;
u_int32_t ntm_bpmftrec;
uid_t ntm_uid;
gid_t ntm_gid;
@ -253,6 +255,7 @@ struct ntfsmount {
cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
int ntm_adnum;
struct netexport ntm_export; /* export information */
};
#define ntm_mftcn ntm_bootfile.bf_mftcn
@ -290,29 +293,33 @@ MALLOC_DECLARE(M_NTFSNTHASH);
#ifdef __NetBSD__
#define MALLOC_DEFINE(a, b, c)
#define M_NTFSNTHASH M_TEMP
#define M_NTFSNTVATTR M_TEMP
#define M_NTFSRDATA M_TEMP
#define M_NTFSRUN M_TEMP
#define M_NTFSDECOMP M_TEMP
#define M_NTFSMNT M_TEMP
#define M_NTFSNTNODE M_TEMP
#define M_NTFSFNODE M_TEMP
#define M_NTFSDIR M_TEMP
#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__LOCK(a, b, c) VOP_LOCK((a), (b) ? LK_EXCLUSIVE : LK_SHARED)
#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), 0)
#define VGET(a, b, c) vget((a), LK_EXCLUSIVE)
#define VN_LOCK(a, b, c) vn_lock((a), LK_EXCLUSIVE)
#else
#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__LOCK(a, b, c) VOP_LOCK((a), (b), (c))
#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))
#endif
#define LOCKMGR(a, b, c) lockmgr((a), (b), (c), NULL)
/* PDIRUNLOCK is used by NetBSD to mark if vfs_lookup() unlocked parent dir;
* on FreeBSD, it's not defined and nothing similar exists */
#define PDIRUNLOCK 0
#endif /* NetBSD */
#if defined(NTFS_DEBUG)
#define dprintf(a) printf a

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_compr.c,v 1.2 1999/05/06 15:43:18 christos Exp $ */
/* $NetBSD: ntfs_compr.c,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -38,8 +38,9 @@
#include <sys/buf.h>
#include <sys/file.h>
#include <sys/malloc.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#if defined(__NetBSD__)
#include <miscfs/specfs/specdev.h>
#endif
#include <ntfs/ntfs.h>

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_compr.h,v 1.2 1999/05/06 15:43:18 christos Exp $ */
/* $NetBSD: ntfs_compr.h,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_ihash.c,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_ihash.c,v 1.5 1999/09/30 16:56:40 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
@ -43,6 +43,7 @@
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
@ -59,6 +60,7 @@ static u_long ntfs_nthash; /* size of hash table - 1 */
#ifndef NULL_SIMPLELOCKS
static struct simplelock ntfs_nthash_slock;
#endif
struct lock ntfs_hashlock;
/*
* Initialize inode hash table.
@ -66,7 +68,7 @@ static struct simplelock ntfs_nthash_slock;
void
ntfs_nthashinit()
{
lockinit(&ntfs_hashlock, PINOD, "ntfs_nthashlock", 0, 0);
ntfs_nthashtbl = HASHINIT(desiredvnodes, M_NTFSNTHASH, M_WAITOK,
&ntfs_nthash);
simple_lock_init(&ntfs_nthash_slock);

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_ihash.h,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_ihash.h,v 1.4 1999/09/30 16:56:40 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -28,6 +28,7 @@
* $FreeBSD$
*/
extern struct lock ntfs_hashlock;
void ntfs_nthashinit __P((void));
struct ntnode *ntfs_nthashlookup __P((dev_t, ino_t));
struct ntnode *ntfs_nthashget __P((dev_t, ino_t));

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_inode.h,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_inode.h,v 1.8 1999/10/31 19:45:26 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -57,46 +57,41 @@
#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;
dev_t i_dev;
u_int32_t i_flag;
int i_lock;
/* locking */
struct lock i_lock;
struct simplelock i_interlock;
int i_usecount;
#if defined(__NetBSD__)
pid_t i_lockholder;
pid_t i_lockwaiter;
int i_lockcount;
#endif
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 */
uid_t i_uid;
gid_t i_gid;
mode_t i_mode;
};
#define FN_PRELOADED 0x0001
#define FN_VALID 0x0002
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
struct fnode {
struct lock f_lock; /* Must be first */
#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;
struct ntnode *f_ip; /* Associated ntnode */
u_long f_flag;
struct vnode *f_devvp;
struct ntfsmount *f_mp;
dev_t f_dev;
enum vtype f_type;
ntfs_times_t f_times; /* $NAME/dirinfo */
ino_t f_pnumber; /* $NAME/dirinfo */
@ -115,3 +110,11 @@ struct fnode {
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,4 +1,4 @@
/* $NetBSD: ntfs_subr.h,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_subr.h,v 1.8 1999/10/10 14:48:37 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -70,34 +70,17 @@ struct ntvattr {
#define va_a_iroot va_d.iroot
#define va_a_ialloc va_d.ialloc
#define uastrcmp(a,b,c,d) ntfs_uastrcmp(ntmp,a,b,c,d)
#ifndef NTFS_DEBUG
#define ntfs_ntref(i) (i)->i_usecount++
#else
#define ntfs_ntref(i) { \
printf("ntfs_ntref: ino %d, usecount: %d\n", \
(i)->i_number, (i)->i_usecount++); \
}
#endif
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 *));
int ntfs_readattr_plain __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *));
int ntfs_readattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *));
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 **));
wchar ntfs_toupper __P(( struct ntfsmount *, wchar ));
int ntfs_uustricmp __P(( struct ntfsmount *, wchar *, int, wchar *, int ));
int ntfs_uastricmp __P(( struct ntfsmount *, const wchar *, int, const char *,
int ));
int ntfs_uastrcmp __P(( struct ntfsmount *, const wchar *, int, const char *,
int ));
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 * ));
@ -106,12 +89,17 @@ struct ntvattr * ntfs_findntvattr __P(( struct ntfsmount *, struct ntnode *, u_i
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, char *, cn_t , 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_ntlookupattr(struct ntfsmount *, const char *, int, int *, char **);
int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *);
int ntfs_writeattr_plain(struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, size_t *);
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));
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 *));

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vfsops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vfsops.c,v 1.23 1999/11/15 19:38:14 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -40,20 +40,30 @@
#include <sys/buf.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#if defined(__NetBSD__)
#include <sys/device.h>
#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
#if defined(__NetBSD__)
#include <vm/vm_prot.h>
#endif
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#if defined(__NetBSD__)
#include <miscfs/specfs/specdev.h>
#endif
/*#define NTFS_DEBUG 1*/
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
#include <ntfs/ntfs_subr.h>
#include <ntfs/ntfs_vfsops.h>
#include <ntfs/ntfs_ihash.h>
#include <ntfs/ntfs_extern.h>
#include <ntfs/ntfsmount.h>
#if defined(__FreeBSD__)
@ -63,13 +73,6 @@ MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode", "NTFS fnode information");
MALLOC_DEFINE(M_NTFSDIR,"NTFS dir", "NTFS dir buffer");
#endif
#if defined(__FreeBSD__)
static int ntfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
#else
static int ntfs_mount __P((struct mount *, const char *, void *,
struct nameidata *, struct proc *));
#endif
static int ntfs_root __P((struct mount *, struct vnode **));
static int ntfs_statfs __P((struct mount *, struct statfs *,
struct proc *));
@ -78,53 +81,70 @@ static int ntfs_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int ntfs_mountfs __P((register struct vnode *, struct mount *,
struct ntfs_args *, struct proc *));
static int ntfs_vptofh __P((struct vnode *, struct fid *));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
#if !defined(__FreeBSD__)
#if !defined (__FreeBSD__)
static int ntfs_quotactl __P((struct mount *, int, uid_t, caddr_t,
struct proc *));
static int ntfs_start __P((struct mount *, int, struct proc *));
static int ntfs_sync __P((struct mount *, int, struct ucred *,
struct proc *));
static int ntfs_vptofh __P((struct vnode *, struct fid *));
#endif /* !defined(__FreeBSD__) */
#endif
#if defined(__FreeBSD__)
struct sockaddr;
static int ntfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
static int ntfs_init __P((struct vfsconf *));
#if 0 /* may be implemented at a later date */
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
static int ntfs_checkexp __P((struct vnode *, struct mbuf *,
static int ntfs_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
#endif /* 0, default ops in FreeBSD */
#elif defined(__NetBSD__)
static int ntfs_mount __P((struct mount *, const char *, void *,
struct nameidata *, struct proc *));
static void ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
static int ntfs_checkexp __P((struct mount *, struct mbuf *,
int *, struct ucred **));
static int ntfs_mountroot __P((void));
static int ntfs_sysctl __P((int *, u_int, void *, size_t *, void *,
size_t, struct proc *));
#else
static int ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct mbuf *, struct vnode **,
int *, struct ucred **));
static int ntfs_checkexp __P((struct mount *, struct mbuf *,
int *, struct ucred **));
#endif
#ifdef __NetBSD__
/*ARGSUSED*/
/*
* Verify a remote client has export rights and return these rights via.
* exflagsp and credanonp.
*/
static int
ntfs_checkexp(mp, nam, exflagsp, credanonp)
#if defined(__FreeBSD__)
register struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
#else /* defined(__NetBSD__) */
register struct mount *mp;
struct mbuf *nam;
int *exflagsp;
struct ucred **credanonp;
#endif
{
register struct netcred *np;
register struct ntfsmount *ntm = VFSTONTFS(mp);
return (EINVAL);
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &ntm->ntm_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);
}
#if defined(__NetBSD__)
/*ARGSUSED*/
static int
ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
@ -142,28 +162,67 @@ ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
static int
ntfs_mountroot()
{
return (EINVAL);
}
#endif
struct mount *mp;
extern struct vnode *rootvp;
struct proc *p = curproc; /* XXX */
int error;
struct ntfs_args args;
if (root_device->dv_class != DV_DISK)
return (ENODEV);
/*
* Get vnodes for rootdev.
*/
if (bdevvp(rootdev, &rootvp))
panic("ntfs_mountroot: can't setup rootvp");
if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
vrele(rootvp);
return (error);
}
args.flag = 0;
args.uid = 0;
args.gid = 0;
args.mode = 0777;
if ((error = ntfs_mountfs(rootvp, mp, &args, p)) != 0) {
mp->mnt_op->vfs_refcount--;
vfs_unbusy(mp);
free(mp, M_MOUNT);
vrele(rootvp);
return (error);
}
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
simple_unlock(&mountlist_slock);
(void)ntfs_statfs(mp, &mp->mnt_stat, p);
vfs_unbusy(mp);
return (0);
}
static void
ntfs_init ()
{
ntfs_nthashinit();
ntfs_toupper_init();
}
#elif defined(__FreeBSD__)
#if defined(__FreeBSD__)
static int
ntfs_init (
struct vfsconf *vcp )
#elif defined(__NetBSD__)
static void
ntfs_init ()
#else
static int
ntfs_init ()
#endif
{
ntfs_nthashinit();
#if !defined(__NetBSD__)
ntfs_toupper_init();
return 0;
#endif
}
#endif /* NetBSD */
static int
ntfs_mount (
struct mount *mp,
@ -177,11 +236,12 @@ ntfs_mount (
struct nameidata *ndp,
struct proc *p )
{
u_int size;
size_t size;
int err = 0;
struct vnode *devvp;
struct ntfs_args args;
#ifdef __FreeBSD__
/*
* Use NULL path to flag a root mount
*/
@ -212,6 +272,7 @@ ntfs_mount (
goto dostatfs; /* success*/
}
#endif /* FreeBSD */
/*
***
@ -229,57 +290,20 @@ ntfs_mount (
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
printf("ntfs_mount(): MNT_UPDATE not supported\n");
err = EINVAL;
goto error_1;
#if 0
ump = VFSTOUFS(mp);
fs = ump->um_fs;
err = 0;
if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
if (vfs_busy(mp)) {
err = EBUSY;
goto error_1;
}
err = ffs_flushfiles(mp, flags, p);
vfs_unbusy(mp);
}
if (!err && (mp->mnt_flag & MNT_RELOAD))
err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
if (err) {
goto error_1;
}
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
if (!fs->fs_clean) {
if (mp->mnt_flag & MNT_FORCE) {
printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt);
} else {
printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",
fs->fs_fsmnt);
err = EPERM;
goto error_1;
}
}
fs->fs_ronly = 0;
}
if (fs->fs_ronly == 0) {
fs->fs_clean = 0;
ffs_sbupdate(ump, MNT_WAIT);
}
/* if not updating name...*/
if (args.fspec == 0) {
/*
* Process export requests. Jumping to "success"
* will return the vfs_export() error code.
*/
err = vfs_export(mp, &ump->um_export, &args.export);
struct ntfsmount *ntm = VFSTONTFS(mp);
err = vfs_export(mp, &ntm->ntm_export, &args.export);
goto success;
}
#endif
printf("ntfs_mount(): MNT_UPDATE not supported\n");
err = EINVAL;
goto error_1;
}
/*
@ -295,10 +319,21 @@ ntfs_mount (
devvp = ndp->ni_vp;
#if defined(__FreeBSD__)
if (!vn_isdisk(devvp)) {
err = ENOTBLK;
goto error_2;
}
#else
if (devvp->v_type != VBLK) {
err = ENOTBLK;
goto error_2;
}
if (major(devvp->v_rdev) >= nblkdev) {
err = ENXIO;
goto error_2;
}
#endif
if (mp->mnt_flag & MNT_UPDATE) {
#if 0
/*
@ -356,7 +391,9 @@ ntfs_mount (
goto error_2;
}
#ifdef __FreeBSD__
dostatfs:
#endif
/*
* Initialize FS stat information in mount struct; uses both
* mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
@ -376,7 +413,7 @@ ntfs_mount (
error_1: /* no state to back out*/
success:
return( err);
return(err);
}
/*
@ -412,9 +449,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (ncount > 1 && devvp != rootvp)
return (EBUSY);
#if defined(__FreeBSD__)
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
VOP_UNLOCK(devvp, 0, p);
VOP__UNLOCK(devvp, 0, p);
#else
error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
#endif
@ -422,9 +459,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
VOP_UNLOCK(devvp, 0, p);
VOP__UNLOCK(devvp, 0, p);
if (error)
return (error);
@ -441,7 +478,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
error = EINVAL;
printf("ntfs_mountfs: invalid boot block\n");
dprintf(("ntfs_mountfs: invalid boot block\n"));
goto out;
}
@ -488,20 +525,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
}
}
/*
* Read in WHOLE lowcase -> upcase translation
* file.
*/
MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
M_NTFSMNT, M_WAITOK);
error = VFS_VGET(mp, NTFS_UPCASEINO, &vp);
if(error)
goto out1;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, 65536*sizeof(wchar), ntmp->ntm_upcase);
vput(vp);
if(error)
/* read the Unicode lowercase --> uppercase translation table,
* if necessary */
if ((error = ntfs_toupper_use(mp, ntmp)))
goto out1;
/*
@ -529,7 +555,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
num * sizeof(ad), sizeof(ad),
&ad);
&ad, NULL);
if (error)
goto out1;
if (ad.ad_name[0] == 0)
@ -548,7 +574,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
i * sizeof(ad), sizeof(ad),
&ad);
&ad, NULL);
if (error)
goto out1;
j = 0;
@ -562,19 +588,16 @@ ntfs_mountfs(devvp, mp, argsp, p)
vput(vp);
}
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
#if defined(__FreeBSD__)
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
#else
mp->mnt_stat.f_fsid.val[0] = dev;
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_NTFS);
#endif
mp->mnt_maxsymlinklen = 0;
mp->mnt_flag |= MNT_LOCAL;
#if defined(__FreeBSD__)
devvp->v_specmountpoint = mp;
#else
devvp->v_specflags |= SI_MOUNTEDON;
#endif
return (0);
out1:
@ -582,17 +605,22 @@ ntfs_mountfs(devvp, mp, argsp, p)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
if (vflush(mp,NULLVP,0))
printf("ntfs_mountfs: vflush failed\n");
dprintf(("ntfs_mountfs: vflush failed\n"));
out:
#if defined(__FreeBSD__)
devvp->v_specmountpoint = NULL;
#else
devvp->v_specflags &= ~SI_MOUNTEDON;
#endif
if (bp)
brelse(bp);
#if defined __NetBSD__
/* lock the device vnode before calling VOP_CLOSE() */
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
VOP__UNLOCK(devvp, 0, p);
#else
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
#endif
return (error);
}
@ -605,7 +633,7 @@ ntfs_start (
{
return (0);
}
#endif /* !defined(__FreeBSD__) */
#endif
static int
ntfs_unmount(
@ -635,7 +663,7 @@ ntfs_unmount(
if((ntmp->ntm_sysvn[i]) &&
(ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
/* Derefernce all system vnodes */
/* Dereference all system vnodes */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
@ -644,23 +672,35 @@ ntfs_unmount(
if (error)
printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
#if defined(__FreeBSD__)
ntmp->ntm_devvp->v_specmountpoint = NULL;
#else
ntmp->ntm_devvp->v_specflags &= ~SI_MOUNTEDON;
#endif
/* Check if the type of device node isn't VBAD before
* touching v_specinfo. If the device vnode is revoked, the
* field is NULL and touching it causes null pointer derefercence.
*/
if (ntmp->ntm_devvp->v_type != VBAD)
ntmp->ntm_devvp->v_specmountpoint = NULL;
vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0);
#if defined(__NetBSD__)
/* lock the device vnode before calling VOP_CLOSE() */
VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY);
error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
VOP__UNLOCK(ntmp->ntm_devvp, 0, p);
#else
error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
#endif
vrele(ntmp->ntm_devvp);
/* free the toupper table, if this has been last mounted ntfs volume */
ntfs_toupper_unuse();
dprintf(("ntfs_umount: freeing memory...\n"));
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
FREE(ntmp->ntm_ad, M_NTFSMNT);
FREE(ntmp->ntm_upcase, M_NTFSMNT);
FREE(ntmp, M_NTFSMNT);
return (error);
}
@ -697,7 +737,7 @@ ntfs_quotactl (
printf("\nntfs_quotactl():\n");
return EOPNOTSUPP;
}
#endif /* !defined(__FreeBSD__) */
#endif
int
ntfs_calccfree(
@ -717,21 +757,18 @@ ntfs_calccfree(
MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, bmsize, tmp);
if(error) {
FREE(tmp, M_TEMP);
return (error);
}
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++;
FREE(tmp, M_TEMP);
*cfreep = cfree;
return(0);
out:
FREE(tmp, M_TEMP);
return(error);
}
static int
@ -769,6 +806,9 @@ ntfs_statfs(
(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
}
sbp->f_flags = mp->mnt_flag;
#ifdef __NetBSD__
strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
#endif
return (0);
}
@ -784,34 +824,31 @@ ntfs_sync (
/*dprintf(("ntfs_sync():\n"));*/
return (0);
}
#endif /* !defined(__FreeBSD__) */
#endif
#if !defined(__FreeBSD__)
/*ARGSUSED*/
static int
ntfs_fhtovp(
#if defined(__FreeBSD__)
struct mount *mp,
struct fid *fhp,
struct sockaddr *nam,
struct vnode **vpp,
int *exflagsp,
struct ucred **credanonp)
#elif defined(__NetBSD__)
struct mount *mp,
struct fid *fhp,
struct vnode **vpp)
#else
struct mount *mp,
struct fid *fhp,
struct mbuf *nam,
struct vnode **vpp,
int *exflagsp,
struct ucred **credanonp)
#endif
{
printf("\ntfs_fhtovp():\n");
return 0;
struct vnode *nvp;
struct ntfid *ntfhp = (struct ntfid *)fhp;
int error;
ddprintf(("ntfs_fhtovp(): %s: %d\n", mp->mnt_stat->f_mntonname,
ntfhp->ntfid_ino));
if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
/* XXX as unlink/rmdir/mkdir/creat are not currently possible
* with NTFS, we don't need to check anything else for now */
*vpp = nvp;
return (0);
}
static int
@ -819,10 +856,19 @@ ntfs_vptofh(
struct vnode *vp,
struct fid *fhp)
{
printf("ntfs_vptofh():\n");
return EOPNOTSUPP;
register struct ntnode *ntp;
register struct ntfid *ntfhp;
ddprintf(("ntfs_fhtovp(): %s: %p\n", vp->v_mount->mnt_stat->f_mntonname,
vp));
ntp = VTONT(vp);
ntfhp = (struct ntfid *)fhp;
ntfhp->ntfid_len = sizeof(struct ntfid);
ntfhp->ntfid_ino = ntp->i_number;
/* ntfhp->ntfid_gen = ntp->i_gen; */
return (0);
}
#endif /* !defined(__FreeBSD__) */
int
ntfs_vgetex(
@ -840,9 +886,11 @@ ntfs_vgetex(
struct ntnode *ip;
struct fnode *fp;
struct vnode *vp;
enum vtype f_type;
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%x, f: 0x%x\n",
ino, attrtype, attrname?attrname:"", lkflags, flags ));
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
ino, attrtype, attrname?attrname:"", (u_long)lkflags,
(u_long)flags ));
ntmp = VFSTONTFS(mp);
*vpp = NULL;
@ -872,16 +920,16 @@ ntfs_vgetex(
return (error);
}
f_type = VNON;
if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
(fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) {
fp->f_type = VDIR;
} else if(flags & VG_EXT) {
fp->f_type = VNON;
fp->f_size =fp->f_allocated = 0;
(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 {
fp->f_type = VREG;
f_type = VREG;
error = ntfs_filesize(ntmp, fp,
&fp->f_size, &fp->f_allocated);
@ -909,10 +957,12 @@ ntfs_vgetex(
}
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
#ifdef __FreeBSD__
lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
#endif
fp->f_vp = vp;
vp->v_data = fp;
vp->v_type = fp->f_type;
vp->v_type = f_type;
if (ino == NTFS_ROOTINO)
vp->v_flag |= VROOT;
@ -927,7 +977,7 @@ ntfs_vgetex(
}
}
VREF(fp->f_devvp);
VREF(ip->i_devvp);
*vpp = vp;
return (0);
@ -940,7 +990,7 @@ ntfs_vget(
struct vnode **vpp)
{
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
LK_EXCLUSIVE, 0, curproc, vpp);
LK_EXCLUSIVE | LK_RETRY, 0, curproc, vpp);
}
#if defined(__FreeBSD__)
@ -953,9 +1003,9 @@ static struct vfsops ntfs_vfsops = {
ntfs_statfs,
vfs_stdsync,
ntfs_vget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
ntfs_fhtovp,
ntfs_checkexp,
ntfs_vptofh,
ntfs_init,
NULL
};
@ -986,7 +1036,7 @@ struct vfsops ntfs_vfsops = {
ntfs_checkexp,
ntfs_vnodeopv_descs,
};
#else
#else /* !NetBSD && !FreeBSD */
static struct vfsops ntfs_vfsops = {
ntfs_mount,
ntfs_start,

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vfsops.h,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vfsops.h,v 1.4 1999/10/10 14:20:33 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
@ -28,7 +28,7 @@
* $FreeBSD$
*/
#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */
/* ntfs_loadnode on ntnode, even if */
/* ntfs_loadntnode() on ntnode, even if */
/* ntnode not loaded */
#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */
/* fnode */

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vnops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vnops.c,v 1.23 1999/10/31 19:45:27 jdolecek Exp $ */
/*
* Copyright (c) 1992, 1993
@ -42,7 +42,6 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -55,6 +54,9 @@
#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>
@ -65,12 +67,16 @@
#include <sys/sysctl.h>
/*#define NTFS_DEBUG 1*/
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
#include <ntfs/ntfs_subr.h>
#include <ntfs/ntfs_extern.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_bypass __P((struct vop_generic_args *ap));
static int ntfs_read __P((struct vop_read_args *));
@ -80,11 +86,6 @@ 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));
#if defined(__NetBSD__)
static int ntfs_islocked __P((struct vop_islocked_args *ap));
static int ntfs_unlock __P((struct vop_unlock_args *ap));
static int ntfs_lock __P((struct vop_lock_args *ap));
#endif
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));
@ -94,8 +95,9 @@ static int ntfs_bmap __P((struct vop_bmap_args *ap));
#if defined(__FreeBSD__)
static int ntfs_getpages __P((struct vop_getpages_args *ap));
static int ntfs_putpages __P((struct vop_putpages_args *));
#endif
static int ntfs_fsync __P((struct vop_fsync_args *ap));
#endif
static int ntfs_pathconf __P((void *));
int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */
@ -159,39 +161,31 @@ ntfs_read(ap)
register struct ntnode *ip = FTONT(fp);
struct uio *uio = ap->a_uio;
struct ntfsmount *ntmp = ip->i_mp;
u_int8_t *data;
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));
toread = fp->f_size;
dprintf(("ntfs_read: filesize: %d",(u_int32_t)fp->f_size));
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
toread = min( uio->uio_resid, toread - uio->uio_offset );
/* 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));
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
if (toread == 0)
return (0);
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, uio->uio_offset, toread, data);
if(error) {
fp->f_attrname, uio->uio_offset, toread, NULL, uio);
if (error) {
printf("ntfs_read: ntfs_readattr failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
error = uiomove(data, (int) toread, uio);
if(error) {
printf("ntfs_read: uiomove failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
FREE(data, M_TEMP);
return (0);
}
@ -224,12 +218,16 @@ ntfs_getattr(ap)
dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag));
vap->va_fsid = dev2udev(fp->f_dev);
#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_mode;
vap->va_mode = ip->i_mp->ntm_mode;
vap->va_nlink = ip->i_nlink;
vap->va_uid = ip->i_uid;
vap->va_gid = ip->i_gid;
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;
@ -239,7 +237,7 @@ ntfs_getattr(ap)
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 = fp->f_type;
vap->va_type = vp->v_type;
vap->va_filerev = 0;
return (0);
}
@ -255,33 +253,25 @@ ntfs_inactive(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
#ifdef NTFS_DEBUG
register struct ntnode *ip = VTONT(vp);
int error;
#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);
error = 0;
VOP__UNLOCK(vp, 0, ap->a_p);
VOP__UNLOCK(vp,0,ap->a_p);
/*
* If we are done with the ntnode, reclaim it
* so that it can be reused immediately.
/* XXX since we don't support any filesystem changes
* right now, nothing more needs to be done
*/
if (vp->v_usecount == 0 && ip->i_mode == 0)
#if defined(__FreeBSD__)
vrecycle(vp, (struct simplelock *)0, ap->a_p);
#else /* defined(__NetBSD__) */
vgone(vp);
#endif
return (error);
return (0);
}
/*
* Reclaim an inode so that it can be used for other purposes.
* Reclaim an fnode/ntnode so that it can be used for other purposes.
*/
int
ntfs_reclaim(ap)
@ -296,26 +286,22 @@ ntfs_reclaim(ap)
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
error = ntfs_ntget(ip);
if (error)
if (ntfs_prtactive && vp->v_usecount != 0)
vprint("ntfs_reclaim: pushing active", vp);
if ((error = ntfs_ntget(ip)) != 0)
return (error);
#if defined(__FreeBSD__)
VOP__UNLOCK(vp,0,ap->a_p);
#endif
/* Purge old data structures associated with the inode. */
cache_purge(vp);
if (fp->f_devvp) {
vrele(fp->f_devvp);
fp->f_devvp = NULL;
if (ip->i_devvp) {
vrele(ip->i_devvp);
ip->i_devvp = NULL;
}
ntfs_frele(fp);
vp->v_data = NULL;
ntfs_ntput(ip);
vp->v_data = NULL;
return (0);
}
@ -326,8 +312,6 @@ ntfs_print(ap)
struct vnode *a_vp;
} */ *ap;
{
/* printf("[ntfs_print]");*/
return (0);
}
@ -348,10 +332,17 @@ ntfs_strategy(ap)
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));
dprintf(("strategy: bcount: %d flags: 0x%x\n",
#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_flags & B_READ) {
@ -368,7 +359,7 @@ ntfs_strategy(ap)
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, ntfs_cntob(bp->b_blkno),
toread, bp->b_data);
toread, bp->b_data, NULL);
if (error) {
printf("ntfs_strategy: ntfs_readattr failed\n");
@ -394,7 +385,7 @@ ntfs_strategy(ap)
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
bp->b_data, &tmp);
bp->b_data, &tmp, NULL);
if (error) {
printf("ntfs_strategy: ntfs_writeattr fail\n");
@ -421,173 +412,32 @@ ntfs_write(ap)
register struct ntnode *ip = FTONT(fp);
struct uio *uio = ap->a_uio;
struct ntfsmount *ntmp = ip->i_mp;
u_int8_t *data;
u_int64_t towrite;
off_t off;
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));
towrite = fp->f_size;
dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
if (uio->uio_resid + uio->uio_offset > towrite) {
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
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, towrite - uio->uio_offset);
off = uio->uio_offset;
towrite = min(uio->uio_resid, fp->f_size - uio->uio_offset);
dprintf((", towrite: %d\n",(u_int32_t)towrite));
MALLOC(data, u_int8_t *, towrite, M_TEMP,M_WAITOK);
error = uiomove(data, (int) towrite, uio);
if(error) {
FREE(data, M_TEMP);
return (error);
}
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
fp->f_attrname, off, towrite, data, &written);
if(error) {
printf("ntfs_write: ntfs_writeattr failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
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
FREE(data, M_TEMP);
return (0);
return (error);
}
#if defined(__NetBSD__)
/*
* Check for a locked ntnode.
*/
int
ntfs_islocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
} */ *ap;
{
register struct ntnode *ip = VTONT(ap->a_vp);
dprintf(("ntfs_islocked %d\n",ip->i_number));
if (ip->i_flag & IN_LOCKED)
return (1);
return (0);
}
/*
* Unlock an ntnode. If WANT bit is on, wakeup.
*/
int ntfs_lockcount = 90;
int
ntfs_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
} */ *ap;
{
register struct ntnode *ip = VTONT(ap->a_vp);
#ifdef DIAGNOSTIC
struct proc *p = curproc;
#endif
dprintf(("ntfs_unlock %d\n",ip->i_number));
#ifdef DIAGNOSTIC
if ((ip->i_flag & IN_LOCKED) == 0) {
vprint("ntfs_unlock: unlocked ntnode", ap->a_vp);
panic("ntfs_unlock NOT LOCKED");
}
if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 &&
ip->i_lockholder > -1 && ntfs_lockcount++ < 100)
panic("unlocker (%d) != lock holder (%d)",
p->p_pid, ip->i_lockholder);
#endif
if (--ip->i_lockcount > 0) {
if ((ip->i_flag & IN_RECURSE) == 0)
panic("ntfs_unlock: recursive lock prematurely released, pid=%d\n", ip->i_lockholder);
return (0);
}
ip->i_lockholder = 0;
ip->i_flag &= ~(IN_LOCKED|IN_RECURSE);
if (ip->i_flag & IN_WANTED) {
ip->i_flag &= ~IN_WANTED;
wakeup((caddr_t)ip);
}
return (0);
}
/*
* Lock an ntnode. If its already locked, set the WANT bit and sleep.
*/
int
ntfs_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
} */ *ap;
{
struct proc *p = curproc;
register struct vnode *vp = ap->a_vp;
register struct ntnode *ip = VTONT(vp);
dprintf(("ntfs_lock %d (%d locks)\n",ip->i_number,ip->i_lockcount));
start:
while (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
(void) tsleep((caddr_t)vp, PINOD, "ntflk1", 0);
}
if (vp->v_tag == VT_NON)
return (ENOENT);
ip = VTONT(vp);
if (ip->i_flag & IN_LOCKED) {
if (p->p_pid == ip->i_lockholder) {
if( (ip->i_flag & IN_RECURSE) == 0)
panic("ntfs_lock: recursive lock not expected, pid: %d\n",
ip->i_lockholder);
} else {
ip->i_flag |= IN_WANTED;
#ifdef DIAGNOSTIC
if (p)
ip->i_lockwaiter = p->p_pid;
else
ip->i_lockwaiter = -1;
#endif
(void) tsleep((caddr_t)ip, PINOD, "ntflk2", 0);
goto start;
}
}
#ifdef DIAGNOSTIC
ip->i_lockwaiter = 0;
if (((ip->i_flag & IN_RECURSE) == 0) && (ip->i_lockholder != 0))
panic("lockholder (%d) != 0", ip->i_lockholder);
if (p && p->p_pid == 0)
printf("locking by process 0\n");
#endif
if ((ip->i_flag & IN_RECURSE) == 0)
ip->i_lockcount = 1;
else
++ip->i_lockcount;
if (p)
ip->i_lockholder = p->p_pid;
else
ip->i_lockholder = -1;
ip->i_flag |= IN_LOCKED;
return (0);
}
#endif
int
ntfs_access(ap)
struct vop_access_args /* {
@ -629,12 +479,6 @@ ntfs_access(ap)
}
}
/* If immutable bit set, nobody gets to write it. */
/*
if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
return (EPERM);
*/
/* Otherwise, user id 0 always gets access. */
if (cred->cr_uid == 0)
return (0);
@ -642,26 +486,26 @@ ntfs_access(ap)
mask = 0;
/* Otherwise, check the owner. */
if (cred->cr_uid == ip->i_uid) {
if (cred->cr_uid == ip->i_mp->ntm_uid) {
if (mode & VEXEC)
mask |= S_IXUSR;
if (mode & VREAD)
mask |= S_IRUSR;
if (mode & VWRITE)
mask |= S_IWUSR;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES);
}
/* Otherwise, check the groups. */
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
if (ip->i_gid == *gp) {
if (ip->i_mp->ntm_gid == *gp) {
if (mode & VEXEC)
mask |= S_IXGRP;
if (mode & VREAD)
mask |= S_IRGRP;
if (mode & VWRITE)
mask |= S_IWGRP;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode&mask) == mask ? 0 : EACCES);
}
/* Otherwise, check everyone else. */
@ -671,7 +515,7 @@ ntfs_access(ap)
mask |= S_IROTH;
if (mode & VWRITE)
mask |= S_IWOTH;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES);
}
/*
@ -794,31 +638,31 @@ ntfs_readdir(ap)
if( NULL == iep )
break;
while( !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent)) ) {
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;
if( ntfs_isnamepermitted(ntmp,iep) ) {
dprintf(("ntfs_readdir: elem: %d, fname:[",num));
for(i=0;i<iep->ie_fnamelen;i++) {
cde.d_name[i] = (char)iep->ie_fname[i];
dprintf(("%c", cde.d_name[i]));
}
dprintf(("] type: %d, flag: %d, ",iep->ie_fnametype, iep->ie_flag));
cde.d_name[i] = '\0';
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++;
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"));
iep = NTFS_NEXTREC(iep,struct attr_indexentry *);
error = uiomove((char *)&cde, sizeof(struct dirent), uio);
if(error)
return (error);
ncookies++;
num++;
}
}
@ -838,7 +682,7 @@ ntfs_readdir(ap)
off_t *cookiep;
#endif
printf("ntfs_readdir: %d cookies\n",ncookies);
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 *)
@ -885,25 +729,40 @@ ntfs_lookup(ap)
#if NTFS_DEBUG
int wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
#endif
dprintf(("ntfs_lookup: %s (%ld bytes) in %d, lp: %d, wp: %d \n",
cnp->cn_nameptr, cnp->cn_namelen,
dip->i_number,lockparent, wantparent));
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_namelen == 1) &&
!strncmp(cnp->cn_nameptr,".",1) ) {
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;
return (0);
} else if( (cnp->cn_namelen == 2) &&
!strncmp(cnp->cn_nameptr,"..",2) &&
(cnp->cn_flags & ISDOTDOT) ) {
error = 0;
} else if (cnp->cn_flags & ISDOTDOT) {
struct ntvattr *vap;
dprintf(("ntfs_lookup: faking .. directory in %d\n",
@ -914,40 +773,48 @@ ntfs_lookup(ap)
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) {
VOP__LOCK(dvp, 0, cnp->cn_proc);
return(error);
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 = VOP__LOCK(dvp, 0, cnp->cn_proc)) ) {
vput( *(ap->a_vpp) );
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;
}
return (error);
} else {
error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
if(error)
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);
}
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.
*
@ -965,6 +832,50 @@ ntfs_fsync(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
@ -972,7 +883,6 @@ ntfs_fsync(ap)
vop_t **ntfs_vnodeop_p;
#if defined(__FreeBSD__)
static
#endif
struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *)ntfs_bypass },
@ -980,19 +890,13 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &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 },
#if defined(__FreeBSD__)
{ &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 },
#else
{ &vop_islocked_desc, (vop_t *)ntfs_islocked },
{ &vop_unlock_desc, (vop_t *)ntfs_unlock },
{ &vop_lock_desc, (vop_t *)ntfs_lock },
{ &vop_lookup_desc, (vop_t *)ntfs_lookup },
#endif
{ &vop_access_desc, (vop_t *)ntfs_access },
{ &vop_close_desc, (vop_t *)ntfs_close },
@ -1001,28 +905,73 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_fsync_desc, (vop_t *)ntfs_fsync },
{ &vop_bmap_desc, (vop_t *)ntfs_bmap },
#if defined(__FreeBSD__)
{ &vop_getpages_desc, (vop_t *) ntfs_getpages },
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
#endif
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
#if defined(__FreeBSD__)
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
#else /* defined(__NetBSD__) */
{ &vop_bwrite_desc, (vop_t *)vn_bwrite },
#endif
{ &vop_read_desc, (vop_t *)ntfs_read },
{ &vop_write_desc, (vop_t *)ntfs_write },
{ NULL, NULL }
};
#if defined(__FreeBSD__)
static
#endif
struct vnodeopv_desc ntfs_vnodeop_opv_desc =
{ &ntfs_vnodeop_p, ntfs_vnodeop_entries };
#if defined(__FreeBSD__)
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_mmap_desc, genfs_eopnotsupp }, /* mmap */
{ &vop_fsync_desc, genfs_fsync }, /* fsync */
{ &vop_seek_desc, genfs_seek }, /* seek */
{ &vop_remove_desc, genfs_eopnotsupp }, /* remove */
{ &vop_link_desc, genfs_eopnotsupp }, /* link */
{ &vop_rename_desc, genfs_eopnotsupp }, /* rename */
{ &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */
{ &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */
{ &vop_symlink_desc, genfs_eopnotsupp }, /* symlink */
{ &vop_readdir_desc, (vop_t *) ntfs_readdir }, /* readdir */
{ &vop_readlink_desc, genfs_eopnotsupp }, /* readlink */
{ &vop_abortop_desc, genfs_abortop }, /* abortop */
{ &vop_inactive_desc, (vop_t *) ntfs_inactive }, /* inactive */
{ &vop_reclaim_desc, (vop_t *) ntfs_reclaim }, /* reclaim */
{ &vop_lock_desc, genfs_lock }, /* lock */
{ &vop_unlock_desc, genfs_unlock }, /* unlock */
{ &vop_bmap_desc, (vop_t *) ntfs_bmap }, /* bmap */
{ &vop_strategy_desc, (vop_t *) ntfs_strategy }, /* strategy */
{ &vop_print_desc, (vop_t *) ntfs_print }, /* print */
{ &vop_islocked_desc, genfs_islocked }, /* islocked */
{ &vop_pathconf_desc, ntfs_pathconf }, /* pathconf */
{ &vop_advlock_desc, genfs_nullop }, /* advlock */
{ &vop_blkatoff_desc, genfs_eopnotsupp }, /* blkatoff */
{ &vop_valloc_desc, genfs_eopnotsupp }, /* valloc */
{ &vop_reallocblks_desc, genfs_eopnotsupp }, /* reallocblks */
{ &vop_vfree_desc, genfs_eopnotsupp }, /* vfree */
{ &vop_truncate_desc, genfs_eopnotsupp }, /* truncate */
{ &vop_update_desc, genfs_eopnotsupp }, /* update */
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
{ (struct vnodeop_desc *)NULL, (int (*) __P((void *)))NULL }
};
struct vnodeopv_desc ntfs_vnodeop_opv_desc =
{ &ntfs_vnodeop_p, ntfs_vnodeop_entries };
#endif

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfsmount.h,v 1.2 1999/05/06 15:43:21 christos Exp $ */
/* $NetBSD: ntfsmount.h,v 1.3 1999/07/26 14:02:32 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs.h,v 1.2 1999/05/06 15:43:17 christos Exp $ */
/* $NetBSD: ntfs.h,v 1.9 1999/10/31 19:45:26 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -29,6 +29,9 @@
*/
/*#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;
@ -239,12 +242,11 @@ struct bootfile {
#define NTFS_SYSNODESNUM 0x0B
struct ntfsmount {
struct mount *ntm_mountp;
struct mount *ntm_mountp; /* filesystem vfs structure */
struct bootfile ntm_bootfile;
dev_t ntm_dev;
struct vnode *ntm_devvp;
dev_t ntm_dev; /* device mounted */
struct vnode *ntm_devvp; /* block device mounted vnode */
struct vnode *ntm_sysvn[NTFS_SYSNODESNUM];
wchar *ntm_upcase;
u_int32_t ntm_bpmftrec;
uid_t ntm_uid;
gid_t ntm_gid;
@ -253,6 +255,7 @@ struct ntfsmount {
cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
int ntm_adnum;
struct netexport ntm_export; /* export information */
};
#define ntm_mftcn ntm_bootfile.bf_mftcn
@ -290,29 +293,33 @@ MALLOC_DECLARE(M_NTFSNTHASH);
#ifdef __NetBSD__
#define MALLOC_DEFINE(a, b, c)
#define M_NTFSNTHASH M_TEMP
#define M_NTFSNTVATTR M_TEMP
#define M_NTFSRDATA M_TEMP
#define M_NTFSRUN M_TEMP
#define M_NTFSDECOMP M_TEMP
#define M_NTFSMNT M_TEMP
#define M_NTFSNTNODE M_TEMP
#define M_NTFSFNODE M_TEMP
#define M_NTFSDIR M_TEMP
#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__LOCK(a, b, c) VOP_LOCK((a), (b) ? LK_EXCLUSIVE : LK_SHARED)
#define VOP__UNLOCK(a, b, c) VOP_UNLOCK((a), 0)
#define VGET(a, b, c) vget((a), LK_EXCLUSIVE)
#define VN_LOCK(a, b, c) vn_lock((a), LK_EXCLUSIVE)
#else
#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__LOCK(a, b, c) VOP_LOCK((a), (b), (c))
#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))
#endif
#define LOCKMGR(a, b, c) lockmgr((a), (b), (c), NULL)
/* PDIRUNLOCK is used by NetBSD to mark if vfs_lookup() unlocked parent dir;
* on FreeBSD, it's not defined and nothing similar exists */
#define PDIRUNLOCK 0
#endif /* NetBSD */
#if defined(NTFS_DEBUG)
#define dprintf(a) printf a

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_compr.c,v 1.2 1999/05/06 15:43:18 christos Exp $ */
/* $NetBSD: ntfs_compr.c,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -38,8 +38,9 @@
#include <sys/buf.h>
#include <sys/file.h>
#include <sys/malloc.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#if defined(__NetBSD__)
#include <miscfs/specfs/specdev.h>
#endif
#include <ntfs/ntfs.h>

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_compr.h,v 1.2 1999/05/06 15:43:18 christos Exp $ */
/* $NetBSD: ntfs_compr.h,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko

View file

@ -1,33 +0,0 @@
/* $NetBSD: ntfs_extern.h,v 1.2 1999/05/06 15:43:18 christos 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$
*/
struct sockaddr;
int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
void ntfs_frele(struct fnode *);

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_ihash.c,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_ihash.c,v 1.5 1999/09/30 16:56:40 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
@ -43,6 +43,7 @@
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
@ -59,6 +60,7 @@ static u_long ntfs_nthash; /* size of hash table - 1 */
#ifndef NULL_SIMPLELOCKS
static struct simplelock ntfs_nthash_slock;
#endif
struct lock ntfs_hashlock;
/*
* Initialize inode hash table.
@ -66,7 +68,7 @@ static struct simplelock ntfs_nthash_slock;
void
ntfs_nthashinit()
{
lockinit(&ntfs_hashlock, PINOD, "ntfs_nthashlock", 0, 0);
ntfs_nthashtbl = HASHINIT(desiredvnodes, M_NTFSNTHASH, M_WAITOK,
&ntfs_nthash);
simple_lock_init(&ntfs_nthash_slock);

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_ihash.h,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_ihash.h,v 1.4 1999/09/30 16:56:40 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -28,6 +28,7 @@
* $FreeBSD$
*/
extern struct lock ntfs_hashlock;
void ntfs_nthashinit __P((void));
struct ntnode *ntfs_nthashlookup __P((dev_t, ino_t));
struct ntnode *ntfs_nthashget __P((dev_t, ino_t));

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_inode.h,v 1.2 1999/05/06 15:43:19 christos Exp $ */
/* $NetBSD: ntfs_inode.h,v 1.8 1999/10/31 19:45:26 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -57,46 +57,41 @@
#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;
dev_t i_dev;
u_int32_t i_flag;
int i_lock;
/* locking */
struct lock i_lock;
struct simplelock i_interlock;
int i_usecount;
#if defined(__NetBSD__)
pid_t i_lockholder;
pid_t i_lockwaiter;
int i_lockcount;
#endif
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 */
uid_t i_uid;
gid_t i_gid;
mode_t i_mode;
};
#define FN_PRELOADED 0x0001
#define FN_VALID 0x0002
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
struct fnode {
struct lock f_lock; /* Must be first */
#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;
struct ntnode *f_ip; /* Associated ntnode */
u_long f_flag;
struct vnode *f_devvp;
struct ntfsmount *f_mp;
dev_t f_dev;
enum vtype f_type;
ntfs_times_t f_times; /* $NAME/dirinfo */
ino_t f_pnumber; /* $NAME/dirinfo */
@ -115,3 +110,11 @@ struct fnode {
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,4 +1,4 @@
/* $NetBSD: ntfs_subr.h,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_subr.h,v 1.8 1999/10/10 14:48:37 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -70,34 +70,17 @@ struct ntvattr {
#define va_a_iroot va_d.iroot
#define va_a_ialloc va_d.ialloc
#define uastrcmp(a,b,c,d) ntfs_uastrcmp(ntmp,a,b,c,d)
#ifndef NTFS_DEBUG
#define ntfs_ntref(i) (i)->i_usecount++
#else
#define ntfs_ntref(i) { \
printf("ntfs_ntref: ino %d, usecount: %d\n", \
(i)->i_number, (i)->i_usecount++); \
}
#endif
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 *));
int ntfs_readattr_plain __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *));
int ntfs_readattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *));
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 **));
wchar ntfs_toupper __P(( struct ntfsmount *, wchar ));
int ntfs_uustricmp __P(( struct ntfsmount *, wchar *, int, wchar *, int ));
int ntfs_uastricmp __P(( struct ntfsmount *, const wchar *, int, const char *,
int ));
int ntfs_uastrcmp __P(( struct ntfsmount *, const wchar *, int, const char *,
int ));
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 * ));
@ -106,12 +89,17 @@ struct ntvattr * ntfs_findntvattr __P(( struct ntfsmount *, struct ntnode *, u_i
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, char *, cn_t , 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_ntlookupattr(struct ntfsmount *, const char *, int, int *, char **);
int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *);
int ntfs_writeattr_plain(struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, size_t *);
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));
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 *));

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vfsops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vfsops.c,v 1.23 1999/11/15 19:38:14 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko
@ -40,20 +40,30 @@
#include <sys/buf.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#if defined(__NetBSD__)
#include <sys/device.h>
#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
#if defined(__NetBSD__)
#include <vm/vm_prot.h>
#endif
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#if defined(__NetBSD__)
#include <miscfs/specfs/specdev.h>
#endif
/*#define NTFS_DEBUG 1*/
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
#include <ntfs/ntfs_subr.h>
#include <ntfs/ntfs_vfsops.h>
#include <ntfs/ntfs_ihash.h>
#include <ntfs/ntfs_extern.h>
#include <ntfs/ntfsmount.h>
#if defined(__FreeBSD__)
@ -63,13 +73,6 @@ MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode", "NTFS fnode information");
MALLOC_DEFINE(M_NTFSDIR,"NTFS dir", "NTFS dir buffer");
#endif
#if defined(__FreeBSD__)
static int ntfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
#else
static int ntfs_mount __P((struct mount *, const char *, void *,
struct nameidata *, struct proc *));
#endif
static int ntfs_root __P((struct mount *, struct vnode **));
static int ntfs_statfs __P((struct mount *, struct statfs *,
struct proc *));
@ -78,53 +81,70 @@ static int ntfs_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int ntfs_mountfs __P((register struct vnode *, struct mount *,
struct ntfs_args *, struct proc *));
static int ntfs_vptofh __P((struct vnode *, struct fid *));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
#if !defined(__FreeBSD__)
#if !defined (__FreeBSD__)
static int ntfs_quotactl __P((struct mount *, int, uid_t, caddr_t,
struct proc *));
static int ntfs_start __P((struct mount *, int, struct proc *));
static int ntfs_sync __P((struct mount *, int, struct ucred *,
struct proc *));
static int ntfs_vptofh __P((struct vnode *, struct fid *));
#endif /* !defined(__FreeBSD__) */
#endif
#if defined(__FreeBSD__)
struct sockaddr;
static int ntfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
static int ntfs_init __P((struct vfsconf *));
#if 0 /* may be implemented at a later date */
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
static int ntfs_checkexp __P((struct vnode *, struct mbuf *,
static int ntfs_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
#endif /* 0, default ops in FreeBSD */
#elif defined(__NetBSD__)
static int ntfs_mount __P((struct mount *, const char *, void *,
struct nameidata *, struct proc *));
static void ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct vnode **));
static int ntfs_checkexp __P((struct mount *, struct mbuf *,
int *, struct ucred **));
static int ntfs_mountroot __P((void));
static int ntfs_sysctl __P((int *, u_int, void *, size_t *, void *,
size_t, struct proc *));
#else
static int ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct mbuf *, struct vnode **,
int *, struct ucred **));
static int ntfs_checkexp __P((struct mount *, struct mbuf *,
int *, struct ucred **));
#endif
#ifdef __NetBSD__
/*ARGSUSED*/
/*
* Verify a remote client has export rights and return these rights via.
* exflagsp and credanonp.
*/
static int
ntfs_checkexp(mp, nam, exflagsp, credanonp)
#if defined(__FreeBSD__)
register struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
#else /* defined(__NetBSD__) */
register struct mount *mp;
struct mbuf *nam;
int *exflagsp;
struct ucred **credanonp;
#endif
{
register struct netcred *np;
register struct ntfsmount *ntm = VFSTONTFS(mp);
return (EINVAL);
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &ntm->ntm_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);
}
#if defined(__NetBSD__)
/*ARGSUSED*/
static int
ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
@ -142,28 +162,67 @@ ntfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
static int
ntfs_mountroot()
{
return (EINVAL);
}
#endif
struct mount *mp;
extern struct vnode *rootvp;
struct proc *p = curproc; /* XXX */
int error;
struct ntfs_args args;
if (root_device->dv_class != DV_DISK)
return (ENODEV);
/*
* Get vnodes for rootdev.
*/
if (bdevvp(rootdev, &rootvp))
panic("ntfs_mountroot: can't setup rootvp");
if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
vrele(rootvp);
return (error);
}
args.flag = 0;
args.uid = 0;
args.gid = 0;
args.mode = 0777;
if ((error = ntfs_mountfs(rootvp, mp, &args, p)) != 0) {
mp->mnt_op->vfs_refcount--;
vfs_unbusy(mp);
free(mp, M_MOUNT);
vrele(rootvp);
return (error);
}
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
simple_unlock(&mountlist_slock);
(void)ntfs_statfs(mp, &mp->mnt_stat, p);
vfs_unbusy(mp);
return (0);
}
static void
ntfs_init ()
{
ntfs_nthashinit();
ntfs_toupper_init();
}
#elif defined(__FreeBSD__)
#if defined(__FreeBSD__)
static int
ntfs_init (
struct vfsconf *vcp )
#elif defined(__NetBSD__)
static void
ntfs_init ()
#else
static int
ntfs_init ()
#endif
{
ntfs_nthashinit();
#if !defined(__NetBSD__)
ntfs_toupper_init();
return 0;
#endif
}
#endif /* NetBSD */
static int
ntfs_mount (
struct mount *mp,
@ -177,11 +236,12 @@ ntfs_mount (
struct nameidata *ndp,
struct proc *p )
{
u_int size;
size_t size;
int err = 0;
struct vnode *devvp;
struct ntfs_args args;
#ifdef __FreeBSD__
/*
* Use NULL path to flag a root mount
*/
@ -212,6 +272,7 @@ ntfs_mount (
goto dostatfs; /* success*/
}
#endif /* FreeBSD */
/*
***
@ -229,57 +290,20 @@ ntfs_mount (
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
printf("ntfs_mount(): MNT_UPDATE not supported\n");
err = EINVAL;
goto error_1;
#if 0
ump = VFSTOUFS(mp);
fs = ump->um_fs;
err = 0;
if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
if (vfs_busy(mp)) {
err = EBUSY;
goto error_1;
}
err = ffs_flushfiles(mp, flags, p);
vfs_unbusy(mp);
}
if (!err && (mp->mnt_flag & MNT_RELOAD))
err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
if (err) {
goto error_1;
}
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
if (!fs->fs_clean) {
if (mp->mnt_flag & MNT_FORCE) {
printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt);
} else {
printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",
fs->fs_fsmnt);
err = EPERM;
goto error_1;
}
}
fs->fs_ronly = 0;
}
if (fs->fs_ronly == 0) {
fs->fs_clean = 0;
ffs_sbupdate(ump, MNT_WAIT);
}
/* if not updating name...*/
if (args.fspec == 0) {
/*
* Process export requests. Jumping to "success"
* will return the vfs_export() error code.
*/
err = vfs_export(mp, &ump->um_export, &args.export);
struct ntfsmount *ntm = VFSTONTFS(mp);
err = vfs_export(mp, &ntm->ntm_export, &args.export);
goto success;
}
#endif
printf("ntfs_mount(): MNT_UPDATE not supported\n");
err = EINVAL;
goto error_1;
}
/*
@ -295,10 +319,21 @@ ntfs_mount (
devvp = ndp->ni_vp;
#if defined(__FreeBSD__)
if (!vn_isdisk(devvp)) {
err = ENOTBLK;
goto error_2;
}
#else
if (devvp->v_type != VBLK) {
err = ENOTBLK;
goto error_2;
}
if (major(devvp->v_rdev) >= nblkdev) {
err = ENXIO;
goto error_2;
}
#endif
if (mp->mnt_flag & MNT_UPDATE) {
#if 0
/*
@ -356,7 +391,9 @@ ntfs_mount (
goto error_2;
}
#ifdef __FreeBSD__
dostatfs:
#endif
/*
* Initialize FS stat information in mount struct; uses both
* mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
@ -376,7 +413,7 @@ ntfs_mount (
error_1: /* no state to back out*/
success:
return( err);
return(err);
}
/*
@ -412,9 +449,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (ncount > 1 && devvp != rootvp)
return (EBUSY);
#if defined(__FreeBSD__)
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
VOP_UNLOCK(devvp, 0, p);
VOP__UNLOCK(devvp, 0, p);
#else
error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
#endif
@ -422,9 +459,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
VOP_UNLOCK(devvp, 0, p);
VOP__UNLOCK(devvp, 0, p);
if (error)
return (error);
@ -441,7 +478,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
error = EINVAL;
printf("ntfs_mountfs: invalid boot block\n");
dprintf(("ntfs_mountfs: invalid boot block\n"));
goto out;
}
@ -488,20 +525,9 @@ ntfs_mountfs(devvp, mp, argsp, p)
}
}
/*
* Read in WHOLE lowcase -> upcase translation
* file.
*/
MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
M_NTFSMNT, M_WAITOK);
error = VFS_VGET(mp, NTFS_UPCASEINO, &vp);
if(error)
goto out1;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, 65536*sizeof(wchar), ntmp->ntm_upcase);
vput(vp);
if(error)
/* read the Unicode lowercase --> uppercase translation table,
* if necessary */
if ((error = ntfs_toupper_use(mp, ntmp)))
goto out1;
/*
@ -529,7 +555,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
num * sizeof(ad), sizeof(ad),
&ad);
&ad, NULL);
if (error)
goto out1;
if (ad.ad_name[0] == 0)
@ -548,7 +574,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
i * sizeof(ad), sizeof(ad),
&ad);
&ad, NULL);
if (error)
goto out1;
j = 0;
@ -562,19 +588,16 @@ ntfs_mountfs(devvp, mp, argsp, p)
vput(vp);
}
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
#if defined(__FreeBSD__)
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
#else
mp->mnt_stat.f_fsid.val[0] = dev;
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_NTFS);
#endif
mp->mnt_maxsymlinklen = 0;
mp->mnt_flag |= MNT_LOCAL;
#if defined(__FreeBSD__)
devvp->v_specmountpoint = mp;
#else
devvp->v_specflags |= SI_MOUNTEDON;
#endif
return (0);
out1:
@ -582,17 +605,22 @@ ntfs_mountfs(devvp, mp, argsp, p)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
if (vflush(mp,NULLVP,0))
printf("ntfs_mountfs: vflush failed\n");
dprintf(("ntfs_mountfs: vflush failed\n"));
out:
#if defined(__FreeBSD__)
devvp->v_specmountpoint = NULL;
#else
devvp->v_specflags &= ~SI_MOUNTEDON;
#endif
if (bp)
brelse(bp);
#if defined __NetBSD__
/* lock the device vnode before calling VOP_CLOSE() */
VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, p);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
VOP__UNLOCK(devvp, 0, p);
#else
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
#endif
return (error);
}
@ -605,7 +633,7 @@ ntfs_start (
{
return (0);
}
#endif /* !defined(__FreeBSD__) */
#endif
static int
ntfs_unmount(
@ -635,7 +663,7 @@ ntfs_unmount(
if((ntmp->ntm_sysvn[i]) &&
(ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
/* Derefernce all system vnodes */
/* Dereference all system vnodes */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
@ -644,23 +672,35 @@ ntfs_unmount(
if (error)
printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
#if defined(__FreeBSD__)
ntmp->ntm_devvp->v_specmountpoint = NULL;
#else
ntmp->ntm_devvp->v_specflags &= ~SI_MOUNTEDON;
#endif
/* Check if the type of device node isn't VBAD before
* touching v_specinfo. If the device vnode is revoked, the
* field is NULL and touching it causes null pointer derefercence.
*/
if (ntmp->ntm_devvp->v_type != VBAD)
ntmp->ntm_devvp->v_specmountpoint = NULL;
vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0);
#if defined(__NetBSD__)
/* lock the device vnode before calling VOP_CLOSE() */
VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY);
error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
VOP__UNLOCK(ntmp->ntm_devvp, 0, p);
#else
error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
#endif
vrele(ntmp->ntm_devvp);
/* free the toupper table, if this has been last mounted ntfs volume */
ntfs_toupper_unuse();
dprintf(("ntfs_umount: freeing memory...\n"));
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
FREE(ntmp->ntm_ad, M_NTFSMNT);
FREE(ntmp->ntm_upcase, M_NTFSMNT);
FREE(ntmp, M_NTFSMNT);
return (error);
}
@ -697,7 +737,7 @@ ntfs_quotactl (
printf("\nntfs_quotactl():\n");
return EOPNOTSUPP;
}
#endif /* !defined(__FreeBSD__) */
#endif
int
ntfs_calccfree(
@ -717,21 +757,18 @@ ntfs_calccfree(
MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, bmsize, tmp);
if(error) {
FREE(tmp, M_TEMP);
return (error);
}
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++;
FREE(tmp, M_TEMP);
*cfreep = cfree;
return(0);
out:
FREE(tmp, M_TEMP);
return(error);
}
static int
@ -769,6 +806,9 @@ ntfs_statfs(
(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
}
sbp->f_flags = mp->mnt_flag;
#ifdef __NetBSD__
strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
#endif
return (0);
}
@ -784,34 +824,31 @@ ntfs_sync (
/*dprintf(("ntfs_sync():\n"));*/
return (0);
}
#endif /* !defined(__FreeBSD__) */
#endif
#if !defined(__FreeBSD__)
/*ARGSUSED*/
static int
ntfs_fhtovp(
#if defined(__FreeBSD__)
struct mount *mp,
struct fid *fhp,
struct sockaddr *nam,
struct vnode **vpp,
int *exflagsp,
struct ucred **credanonp)
#elif defined(__NetBSD__)
struct mount *mp,
struct fid *fhp,
struct vnode **vpp)
#else
struct mount *mp,
struct fid *fhp,
struct mbuf *nam,
struct vnode **vpp,
int *exflagsp,
struct ucred **credanonp)
#endif
{
printf("\ntfs_fhtovp():\n");
return 0;
struct vnode *nvp;
struct ntfid *ntfhp = (struct ntfid *)fhp;
int error;
ddprintf(("ntfs_fhtovp(): %s: %d\n", mp->mnt_stat->f_mntonname,
ntfhp->ntfid_ino));
if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
/* XXX as unlink/rmdir/mkdir/creat are not currently possible
* with NTFS, we don't need to check anything else for now */
*vpp = nvp;
return (0);
}
static int
@ -819,10 +856,19 @@ ntfs_vptofh(
struct vnode *vp,
struct fid *fhp)
{
printf("ntfs_vptofh():\n");
return EOPNOTSUPP;
register struct ntnode *ntp;
register struct ntfid *ntfhp;
ddprintf(("ntfs_fhtovp(): %s: %p\n", vp->v_mount->mnt_stat->f_mntonname,
vp));
ntp = VTONT(vp);
ntfhp = (struct ntfid *)fhp;
ntfhp->ntfid_len = sizeof(struct ntfid);
ntfhp->ntfid_ino = ntp->i_number;
/* ntfhp->ntfid_gen = ntp->i_gen; */
return (0);
}
#endif /* !defined(__FreeBSD__) */
int
ntfs_vgetex(
@ -840,9 +886,11 @@ ntfs_vgetex(
struct ntnode *ip;
struct fnode *fp;
struct vnode *vp;
enum vtype f_type;
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%x, f: 0x%x\n",
ino, attrtype, attrname?attrname:"", lkflags, flags ));
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
ino, attrtype, attrname?attrname:"", (u_long)lkflags,
(u_long)flags ));
ntmp = VFSTONTFS(mp);
*vpp = NULL;
@ -872,16 +920,16 @@ ntfs_vgetex(
return (error);
}
f_type = VNON;
if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
(fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) {
fp->f_type = VDIR;
} else if(flags & VG_EXT) {
fp->f_type = VNON;
fp->f_size =fp->f_allocated = 0;
(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 {
fp->f_type = VREG;
f_type = VREG;
error = ntfs_filesize(ntmp, fp,
&fp->f_size, &fp->f_allocated);
@ -909,10 +957,12 @@ ntfs_vgetex(
}
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
#ifdef __FreeBSD__
lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
#endif
fp->f_vp = vp;
vp->v_data = fp;
vp->v_type = fp->f_type;
vp->v_type = f_type;
if (ino == NTFS_ROOTINO)
vp->v_flag |= VROOT;
@ -927,7 +977,7 @@ ntfs_vgetex(
}
}
VREF(fp->f_devvp);
VREF(ip->i_devvp);
*vpp = vp;
return (0);
@ -940,7 +990,7 @@ ntfs_vget(
struct vnode **vpp)
{
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
LK_EXCLUSIVE, 0, curproc, vpp);
LK_EXCLUSIVE | LK_RETRY, 0, curproc, vpp);
}
#if defined(__FreeBSD__)
@ -953,9 +1003,9 @@ static struct vfsops ntfs_vfsops = {
ntfs_statfs,
vfs_stdsync,
ntfs_vget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
ntfs_fhtovp,
ntfs_checkexp,
ntfs_vptofh,
ntfs_init,
NULL
};
@ -986,7 +1036,7 @@ struct vfsops ntfs_vfsops = {
ntfs_checkexp,
ntfs_vnodeopv_descs,
};
#else
#else /* !NetBSD && !FreeBSD */
static struct vfsops ntfs_vfsops = {
ntfs_mount,
ntfs_start,

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vfsops.h,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vfsops.h,v 1.4 1999/10/10 14:20:33 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
@ -28,7 +28,7 @@
* $FreeBSD$
*/
#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */
/* ntfs_loadnode on ntnode, even if */
/* ntfs_loadntnode() on ntnode, even if */
/* ntnode not loaded */
#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */
/* fnode */

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfs_vnops.c,v 1.2 1999/05/06 15:43:20 christos Exp $ */
/* $NetBSD: ntfs_vnops.c,v 1.23 1999/10/31 19:45:27 jdolecek Exp $ */
/*
* Copyright (c) 1992, 1993
@ -42,7 +42,6 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -55,6 +54,9 @@
#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>
@ -65,12 +67,16 @@
#include <sys/sysctl.h>
/*#define NTFS_DEBUG 1*/
#include <ntfs/ntfs.h>
#include <ntfs/ntfs_inode.h>
#include <ntfs/ntfs_subr.h>
#include <ntfs/ntfs_extern.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_bypass __P((struct vop_generic_args *ap));
static int ntfs_read __P((struct vop_read_args *));
@ -80,11 +86,6 @@ 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));
#if defined(__NetBSD__)
static int ntfs_islocked __P((struct vop_islocked_args *ap));
static int ntfs_unlock __P((struct vop_unlock_args *ap));
static int ntfs_lock __P((struct vop_lock_args *ap));
#endif
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));
@ -94,8 +95,9 @@ static int ntfs_bmap __P((struct vop_bmap_args *ap));
#if defined(__FreeBSD__)
static int ntfs_getpages __P((struct vop_getpages_args *ap));
static int ntfs_putpages __P((struct vop_putpages_args *));
#endif
static int ntfs_fsync __P((struct vop_fsync_args *ap));
#endif
static int ntfs_pathconf __P((void *));
int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */
@ -159,39 +161,31 @@ ntfs_read(ap)
register struct ntnode *ip = FTONT(fp);
struct uio *uio = ap->a_uio;
struct ntfsmount *ntmp = ip->i_mp;
u_int8_t *data;
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));
toread = fp->f_size;
dprintf(("ntfs_read: filesize: %d",(u_int32_t)fp->f_size));
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
toread = min( uio->uio_resid, toread - uio->uio_offset );
/* 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));
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
if (toread == 0)
return (0);
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, uio->uio_offset, toread, data);
if(error) {
fp->f_attrname, uio->uio_offset, toread, NULL, uio);
if (error) {
printf("ntfs_read: ntfs_readattr failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
error = uiomove(data, (int) toread, uio);
if(error) {
printf("ntfs_read: uiomove failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
FREE(data, M_TEMP);
return (0);
}
@ -224,12 +218,16 @@ ntfs_getattr(ap)
dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag));
vap->va_fsid = dev2udev(fp->f_dev);
#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_mode;
vap->va_mode = ip->i_mp->ntm_mode;
vap->va_nlink = ip->i_nlink;
vap->va_uid = ip->i_uid;
vap->va_gid = ip->i_gid;
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;
@ -239,7 +237,7 @@ ntfs_getattr(ap)
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 = fp->f_type;
vap->va_type = vp->v_type;
vap->va_filerev = 0;
return (0);
}
@ -255,33 +253,25 @@ ntfs_inactive(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
#ifdef NTFS_DEBUG
register struct ntnode *ip = VTONT(vp);
int error;
#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);
error = 0;
VOP__UNLOCK(vp, 0, ap->a_p);
VOP__UNLOCK(vp,0,ap->a_p);
/*
* If we are done with the ntnode, reclaim it
* so that it can be reused immediately.
/* XXX since we don't support any filesystem changes
* right now, nothing more needs to be done
*/
if (vp->v_usecount == 0 && ip->i_mode == 0)
#if defined(__FreeBSD__)
vrecycle(vp, (struct simplelock *)0, ap->a_p);
#else /* defined(__NetBSD__) */
vgone(vp);
#endif
return (error);
return (0);
}
/*
* Reclaim an inode so that it can be used for other purposes.
* Reclaim an fnode/ntnode so that it can be used for other purposes.
*/
int
ntfs_reclaim(ap)
@ -296,26 +286,22 @@ ntfs_reclaim(ap)
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
error = ntfs_ntget(ip);
if (error)
if (ntfs_prtactive && vp->v_usecount != 0)
vprint("ntfs_reclaim: pushing active", vp);
if ((error = ntfs_ntget(ip)) != 0)
return (error);
#if defined(__FreeBSD__)
VOP__UNLOCK(vp,0,ap->a_p);
#endif
/* Purge old data structures associated with the inode. */
cache_purge(vp);
if (fp->f_devvp) {
vrele(fp->f_devvp);
fp->f_devvp = NULL;
if (ip->i_devvp) {
vrele(ip->i_devvp);
ip->i_devvp = NULL;
}
ntfs_frele(fp);
vp->v_data = NULL;
ntfs_ntput(ip);
vp->v_data = NULL;
return (0);
}
@ -326,8 +312,6 @@ ntfs_print(ap)
struct vnode *a_vp;
} */ *ap;
{
/* printf("[ntfs_print]");*/
return (0);
}
@ -348,10 +332,17 @@ ntfs_strategy(ap)
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));
dprintf(("strategy: bcount: %d flags: 0x%x\n",
#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_flags & B_READ) {
@ -368,7 +359,7 @@ ntfs_strategy(ap)
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, ntfs_cntob(bp->b_blkno),
toread, bp->b_data);
toread, bp->b_data, NULL);
if (error) {
printf("ntfs_strategy: ntfs_readattr failed\n");
@ -394,7 +385,7 @@ ntfs_strategy(ap)
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
bp->b_data, &tmp);
bp->b_data, &tmp, NULL);
if (error) {
printf("ntfs_strategy: ntfs_writeattr fail\n");
@ -421,173 +412,32 @@ ntfs_write(ap)
register struct ntnode *ip = FTONT(fp);
struct uio *uio = ap->a_uio;
struct ntfsmount *ntmp = ip->i_mp;
u_int8_t *data;
u_int64_t towrite;
off_t off;
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));
towrite = fp->f_size;
dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
if (uio->uio_resid + uio->uio_offset > towrite) {
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
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, towrite - uio->uio_offset);
off = uio->uio_offset;
towrite = min(uio->uio_resid, fp->f_size - uio->uio_offset);
dprintf((", towrite: %d\n",(u_int32_t)towrite));
MALLOC(data, u_int8_t *, towrite, M_TEMP,M_WAITOK);
error = uiomove(data, (int) towrite, uio);
if(error) {
FREE(data, M_TEMP);
return (error);
}
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
fp->f_attrname, off, towrite, data, &written);
if(error) {
printf("ntfs_write: ntfs_writeattr failed: %d\n",error);
FREE(data, M_TEMP);
return (error);
}
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
FREE(data, M_TEMP);
return (0);
return (error);
}
#if defined(__NetBSD__)
/*
* Check for a locked ntnode.
*/
int
ntfs_islocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
} */ *ap;
{
register struct ntnode *ip = VTONT(ap->a_vp);
dprintf(("ntfs_islocked %d\n",ip->i_number));
if (ip->i_flag & IN_LOCKED)
return (1);
return (0);
}
/*
* Unlock an ntnode. If WANT bit is on, wakeup.
*/
int ntfs_lockcount = 90;
int
ntfs_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
} */ *ap;
{
register struct ntnode *ip = VTONT(ap->a_vp);
#ifdef DIAGNOSTIC
struct proc *p = curproc;
#endif
dprintf(("ntfs_unlock %d\n",ip->i_number));
#ifdef DIAGNOSTIC
if ((ip->i_flag & IN_LOCKED) == 0) {
vprint("ntfs_unlock: unlocked ntnode", ap->a_vp);
panic("ntfs_unlock NOT LOCKED");
}
if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 &&
ip->i_lockholder > -1 && ntfs_lockcount++ < 100)
panic("unlocker (%d) != lock holder (%d)",
p->p_pid, ip->i_lockholder);
#endif
if (--ip->i_lockcount > 0) {
if ((ip->i_flag & IN_RECURSE) == 0)
panic("ntfs_unlock: recursive lock prematurely released, pid=%d\n", ip->i_lockholder);
return (0);
}
ip->i_lockholder = 0;
ip->i_flag &= ~(IN_LOCKED|IN_RECURSE);
if (ip->i_flag & IN_WANTED) {
ip->i_flag &= ~IN_WANTED;
wakeup((caddr_t)ip);
}
return (0);
}
/*
* Lock an ntnode. If its already locked, set the WANT bit and sleep.
*/
int
ntfs_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
} */ *ap;
{
struct proc *p = curproc;
register struct vnode *vp = ap->a_vp;
register struct ntnode *ip = VTONT(vp);
dprintf(("ntfs_lock %d (%d locks)\n",ip->i_number,ip->i_lockcount));
start:
while (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
(void) tsleep((caddr_t)vp, PINOD, "ntflk1", 0);
}
if (vp->v_tag == VT_NON)
return (ENOENT);
ip = VTONT(vp);
if (ip->i_flag & IN_LOCKED) {
if (p->p_pid == ip->i_lockholder) {
if( (ip->i_flag & IN_RECURSE) == 0)
panic("ntfs_lock: recursive lock not expected, pid: %d\n",
ip->i_lockholder);
} else {
ip->i_flag |= IN_WANTED;
#ifdef DIAGNOSTIC
if (p)
ip->i_lockwaiter = p->p_pid;
else
ip->i_lockwaiter = -1;
#endif
(void) tsleep((caddr_t)ip, PINOD, "ntflk2", 0);
goto start;
}
}
#ifdef DIAGNOSTIC
ip->i_lockwaiter = 0;
if (((ip->i_flag & IN_RECURSE) == 0) && (ip->i_lockholder != 0))
panic("lockholder (%d) != 0", ip->i_lockholder);
if (p && p->p_pid == 0)
printf("locking by process 0\n");
#endif
if ((ip->i_flag & IN_RECURSE) == 0)
ip->i_lockcount = 1;
else
++ip->i_lockcount;
if (p)
ip->i_lockholder = p->p_pid;
else
ip->i_lockholder = -1;
ip->i_flag |= IN_LOCKED;
return (0);
}
#endif
int
ntfs_access(ap)
struct vop_access_args /* {
@ -629,12 +479,6 @@ ntfs_access(ap)
}
}
/* If immutable bit set, nobody gets to write it. */
/*
if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
return (EPERM);
*/
/* Otherwise, user id 0 always gets access. */
if (cred->cr_uid == 0)
return (0);
@ -642,26 +486,26 @@ ntfs_access(ap)
mask = 0;
/* Otherwise, check the owner. */
if (cred->cr_uid == ip->i_uid) {
if (cred->cr_uid == ip->i_mp->ntm_uid) {
if (mode & VEXEC)
mask |= S_IXUSR;
if (mode & VREAD)
mask |= S_IRUSR;
if (mode & VWRITE)
mask |= S_IWUSR;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES);
}
/* Otherwise, check the groups. */
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
if (ip->i_gid == *gp) {
if (ip->i_mp->ntm_gid == *gp) {
if (mode & VEXEC)
mask |= S_IXGRP;
if (mode & VREAD)
mask |= S_IRGRP;
if (mode & VWRITE)
mask |= S_IWGRP;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode&mask) == mask ? 0 : EACCES);
}
/* Otherwise, check everyone else. */
@ -671,7 +515,7 @@ ntfs_access(ap)
mask |= S_IROTH;
if (mode & VWRITE)
mask |= S_IWOTH;
return ((ip->i_mode & mask) == mask ? 0 : EACCES);
return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES);
}
/*
@ -794,31 +638,31 @@ ntfs_readdir(ap)
if( NULL == iep )
break;
while( !(iep->ie_flag & NTFS_IEFLAG_LAST) && (uio->uio_resid >= sizeof(struct dirent)) ) {
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;
if( ntfs_isnamepermitted(ntmp,iep) ) {
dprintf(("ntfs_readdir: elem: %d, fname:[",num));
for(i=0;i<iep->ie_fnamelen;i++) {
cde.d_name[i] = (char)iep->ie_fname[i];
dprintf(("%c", cde.d_name[i]));
}
dprintf(("] type: %d, flag: %d, ",iep->ie_fnametype, iep->ie_flag));
cde.d_name[i] = '\0';
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++;
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"));
iep = NTFS_NEXTREC(iep,struct attr_indexentry *);
error = uiomove((char *)&cde, sizeof(struct dirent), uio);
if(error)
return (error);
ncookies++;
num++;
}
}
@ -838,7 +682,7 @@ ntfs_readdir(ap)
off_t *cookiep;
#endif
printf("ntfs_readdir: %d cookies\n",ncookies);
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 *)
@ -885,25 +729,40 @@ ntfs_lookup(ap)
#if NTFS_DEBUG
int wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
#endif
dprintf(("ntfs_lookup: %s (%ld bytes) in %d, lp: %d, wp: %d \n",
cnp->cn_nameptr, cnp->cn_namelen,
dip->i_number,lockparent, wantparent));
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_namelen == 1) &&
!strncmp(cnp->cn_nameptr,".",1) ) {
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;
return (0);
} else if( (cnp->cn_namelen == 2) &&
!strncmp(cnp->cn_nameptr,"..",2) &&
(cnp->cn_flags & ISDOTDOT) ) {
error = 0;
} else if (cnp->cn_flags & ISDOTDOT) {
struct ntvattr *vap;
dprintf(("ntfs_lookup: faking .. directory in %d\n",
@ -914,40 +773,48 @@ ntfs_lookup(ap)
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) {
VOP__LOCK(dvp, 0, cnp->cn_proc);
return(error);
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 = VOP__LOCK(dvp, 0, cnp->cn_proc)) ) {
vput( *(ap->a_vpp) );
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;
}
return (error);
} else {
error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
if(error)
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);
}
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.
*
@ -965,6 +832,50 @@ ntfs_fsync(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
@ -972,7 +883,6 @@ ntfs_fsync(ap)
vop_t **ntfs_vnodeop_p;
#if defined(__FreeBSD__)
static
#endif
struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *)ntfs_bypass },
@ -980,19 +890,13 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &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 },
#if defined(__FreeBSD__)
{ &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 },
#else
{ &vop_islocked_desc, (vop_t *)ntfs_islocked },
{ &vop_unlock_desc, (vop_t *)ntfs_unlock },
{ &vop_lock_desc, (vop_t *)ntfs_lock },
{ &vop_lookup_desc, (vop_t *)ntfs_lookup },
#endif
{ &vop_access_desc, (vop_t *)ntfs_access },
{ &vop_close_desc, (vop_t *)ntfs_close },
@ -1001,28 +905,73 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
{ &vop_fsync_desc, (vop_t *)ntfs_fsync },
{ &vop_bmap_desc, (vop_t *)ntfs_bmap },
#if defined(__FreeBSD__)
{ &vop_getpages_desc, (vop_t *) ntfs_getpages },
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
#endif
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
#if defined(__FreeBSD__)
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
#else /* defined(__NetBSD__) */
{ &vop_bwrite_desc, (vop_t *)vn_bwrite },
#endif
{ &vop_read_desc, (vop_t *)ntfs_read },
{ &vop_write_desc, (vop_t *)ntfs_write },
{ NULL, NULL }
};
#if defined(__FreeBSD__)
static
#endif
struct vnodeopv_desc ntfs_vnodeop_opv_desc =
{ &ntfs_vnodeop_p, ntfs_vnodeop_entries };
#if defined(__FreeBSD__)
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_mmap_desc, genfs_eopnotsupp }, /* mmap */
{ &vop_fsync_desc, genfs_fsync }, /* fsync */
{ &vop_seek_desc, genfs_seek }, /* seek */
{ &vop_remove_desc, genfs_eopnotsupp }, /* remove */
{ &vop_link_desc, genfs_eopnotsupp }, /* link */
{ &vop_rename_desc, genfs_eopnotsupp }, /* rename */
{ &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */
{ &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */
{ &vop_symlink_desc, genfs_eopnotsupp }, /* symlink */
{ &vop_readdir_desc, (vop_t *) ntfs_readdir }, /* readdir */
{ &vop_readlink_desc, genfs_eopnotsupp }, /* readlink */
{ &vop_abortop_desc, genfs_abortop }, /* abortop */
{ &vop_inactive_desc, (vop_t *) ntfs_inactive }, /* inactive */
{ &vop_reclaim_desc, (vop_t *) ntfs_reclaim }, /* reclaim */
{ &vop_lock_desc, genfs_lock }, /* lock */
{ &vop_unlock_desc, genfs_unlock }, /* unlock */
{ &vop_bmap_desc, (vop_t *) ntfs_bmap }, /* bmap */
{ &vop_strategy_desc, (vop_t *) ntfs_strategy }, /* strategy */
{ &vop_print_desc, (vop_t *) ntfs_print }, /* print */
{ &vop_islocked_desc, genfs_islocked }, /* islocked */
{ &vop_pathconf_desc, ntfs_pathconf }, /* pathconf */
{ &vop_advlock_desc, genfs_nullop }, /* advlock */
{ &vop_blkatoff_desc, genfs_eopnotsupp }, /* blkatoff */
{ &vop_valloc_desc, genfs_eopnotsupp }, /* valloc */
{ &vop_reallocblks_desc, genfs_eopnotsupp }, /* reallocblks */
{ &vop_vfree_desc, genfs_eopnotsupp }, /* vfree */
{ &vop_truncate_desc, genfs_eopnotsupp }, /* truncate */
{ &vop_update_desc, genfs_eopnotsupp }, /* update */
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
{ (struct vnodeop_desc *)NULL, (int (*) __P((void *)))NULL }
};
struct vnodeopv_desc ntfs_vnodeop_opv_desc =
{ &ntfs_vnodeop_p, ntfs_vnodeop_entries };
#endif

View file

@ -1,4 +1,4 @@
/* $NetBSD: ntfsmount.h,v 1.2 1999/05/06 15:43:21 christos Exp $ */
/* $NetBSD: ntfsmount.h,v 1.3 1999/07/26 14:02:32 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 Semen Ustimenko