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:
parent
2076235ada
commit
b17f083b0f
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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
@ -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 *));
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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. */
|
||||
};
|
||||
|
1036
sys/ntfs/ntfs_subr.c
1036
sys/ntfs/ntfs_subr.c
File diff suppressed because it is too large
Load Diff
@ -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 *));
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user