Added limited write ability. Now we can use some kind
of files for swap holders. See mount_ntfs..8 for details.
This commit is contained in:
parent
eb7abf9254
commit
05d36e7aea
@ -182,6 +182,7 @@ struct attr_indexentry {
|
||||
};
|
||||
|
||||
#define NTFS_FILEMAGIC (u_int32_t)(0x454C4946)
|
||||
#define NTFS_FRFLAG_DIR 0x0002
|
||||
struct filerec {
|
||||
struct fixuphdr fr_fixup;
|
||||
u_int8_t reserved[8];
|
||||
@ -195,10 +196,11 @@ struct filerec {
|
||||
u_int16_t fr_attrnum; /* maximum attr number + 1 ??? */
|
||||
};
|
||||
|
||||
#define NTFS_ATTRNAME_MAXLEN 0x40
|
||||
#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */
|
||||
#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */
|
||||
struct attrdef {
|
||||
wchar ad_name[0x40];
|
||||
wchar ad_name[NTFS_ATTRNAME_MAXLEN];
|
||||
u_int32_t ad_type;
|
||||
u_int32_t reserved1[2];
|
||||
u_int32_t ad_flag;
|
||||
@ -261,8 +263,10 @@ struct ntfsmount {
|
||||
|
||||
/* Convert mount ptr to ntfsmount ptr. */
|
||||
#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data))
|
||||
#define VTONT(v) ((struct ntnode *)((struct vnode *)(v)->v_data))
|
||||
#define NTTOV(i) (i->i_vnode)
|
||||
#define VTONT(v) FTONT(VTOF(v))
|
||||
#define VTOF(v) ((struct fnode *)((v)->v_data))
|
||||
#define FTOV(f) ((f)->f_vp)
|
||||
#define FTONT(f) ((f)->f_ip)
|
||||
#define ntfs_cntobn(cn) (daddr_t)((cn) * (ntmp->ntm_spc))
|
||||
#define ntfs_cntob(cn) (off_t)((cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps)
|
||||
#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
|
||||
@ -274,9 +278,10 @@ struct ntfsmount {
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
MALLOC_DECLARE(M_NTFSMNT);
|
||||
MALLOC_DECLARE(M_NTFSNODE);
|
||||
MALLOC_DECLARE(M_NTFSNTNODE);
|
||||
MALLOC_DECLARE(M_NTFSFNODE);
|
||||
MALLOC_DECLARE(M_NTFSDIR);
|
||||
MALLOC_DECLARE(M_NTFSIHASH);
|
||||
MALLOC_DECLARE(M_NTFSNTHASH);
|
||||
#endif
|
||||
|
||||
#if defined(NTFS_DEBUG)
|
||||
@ -292,10 +297,3 @@ MALLOC_DECLARE(M_NTFSIHASH);
|
||||
#endif
|
||||
|
||||
extern vop_t **ntfs_vnodeop_p;
|
||||
struct ntnode;
|
||||
|
||||
void ntfs_ihashinit __P((void));
|
||||
struct vnode *ntfs_ihashlookup __P((dev_t, ino_t));
|
||||
struct vnode *ntfs_ihashget __P((dev_t, ino_t));
|
||||
void ntfs_ihashins __P((struct ntnode *));
|
||||
void ntfs_ihashrem __P((register struct ntnode *));
|
||||
|
@ -48,7 +48,7 @@
|
||||
int
|
||||
ntfs_uncompblock(
|
||||
u_int8_t * buf,
|
||||
const u_int8_t * cbuf)
|
||||
u_int8_t * cbuf)
|
||||
{
|
||||
u_int32_t ctag;
|
||||
int len, dshift, lmask;
|
||||
@ -100,7 +100,7 @@ int
|
||||
ntfs_uncompunit(
|
||||
struct ntfsmount * ntmp,
|
||||
u_int8_t * uup,
|
||||
const u_int8_t * cup)
|
||||
u_int8_t * cup)
|
||||
{
|
||||
int i;
|
||||
int off = 0;
|
||||
|
@ -29,5 +29,5 @@
|
||||
#define NTFS_COMPBLOCK_SIZE 0x1000
|
||||
#define NTFS_COMPUNIT_CL 16
|
||||
|
||||
int ntfs_uncompblock(u_int8_t *, const u_int8_t *);
|
||||
int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, const u_int8_t *);
|
||||
int ntfs_uncompblock(u_int8_t *, u_int8_t *);
|
||||
int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, u_int8_t *);
|
||||
|
@ -44,107 +44,75 @@
|
||||
|
||||
#include <ntfs/ntfs.h>
|
||||
#include <ntfs/ntfs_inode.h>
|
||||
#include <ntfs/ntfs_ihash.h>
|
||||
|
||||
MALLOC_DEFINE(M_NTFSIHASH, "NTFS ihash", "NTFS Inode hash tables");
|
||||
MALLOC_DEFINE(M_NTFSNTHASH, "NTFS nthash", "NTFS ntnode hash tables");
|
||||
|
||||
/*
|
||||
* Structures associated with inode cacheing.
|
||||
*/
|
||||
static LIST_HEAD(ihashhead, ntnode) *ntfs_ihashtbl;
|
||||
static u_long ntfs_ihash; /* size of hash table - 1 */
|
||||
#define NTNOHASH(device, inum) (&ntfs_ihashtbl[((device) + (inum)) & ntfs_ihash])
|
||||
static struct simplelock ntfs_ihash_slock;
|
||||
static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
|
||||
static u_long ntfs_nthash; /* size of hash table - 1 */
|
||||
#define NTNOHASH(device, inum) (&ntfs_nthashtbl[((device) + (inum)) & ntfs_nthash])
|
||||
#ifndef NULL_SIMPLELOCKS
|
||||
static struct simplelock ntfs_nthash_slock;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize inode hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashinit()
|
||||
ntfs_nthashinit()
|
||||
{
|
||||
|
||||
ntfs_ihashtbl = hashinit(desiredvnodes, M_NTFSIHASH, &ntfs_ihash);
|
||||
simple_lock_init(&ntfs_ihash_slock);
|
||||
ntfs_nthashtbl = hashinit(desiredvnodes, M_NTFSNTHASH, &ntfs_nthash);
|
||||
simple_lock_init(&ntfs_nthash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the device/inum pair to find the incore inode, and return a pointer
|
||||
* to it. If it is in core, return it, even if it is locked.
|
||||
*/
|
||||
struct vnode *
|
||||
ntfs_ihashlookup(dev, inum)
|
||||
struct ntnode *
|
||||
ntfs_nthashlookup(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct ntnode *ip;
|
||||
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
for (ip = NTNOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next)
|
||||
if (inum == ip->i_number && dev == ip->i_dev)
|
||||
break;
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
|
||||
if (ip)
|
||||
return (NTTOV(ip));
|
||||
return (NULLVP);
|
||||
return (ip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the device/inum pair to find the incore inode, and return a pointer
|
||||
* to it. If it is in core, but locked, wait for it.
|
||||
*/
|
||||
struct vnode *
|
||||
ntfs_ihashget(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct ntnode *ip;
|
||||
struct vnode *vp;
|
||||
|
||||
loop:
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
for (ip = NTNOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
|
||||
if (inum == ip->i_number && dev == ip->i_dev) {
|
||||
vp = NTTOV(ip);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
return (vp);
|
||||
}
|
||||
}
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the inode into the hash table, and return it locked.
|
||||
* Insert the ntnode into the hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashins(ip)
|
||||
ntfs_nthashins(ip)
|
||||
struct ntnode *ip;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct ihashhead *ipp;
|
||||
struct nthashhead *ipp;
|
||||
|
||||
/* lock the inode, then put it on the appropriate hash list */
|
||||
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
|
||||
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
ipp = NTNOHASH(ip->i_dev, ip->i_number);
|
||||
LIST_INSERT_HEAD(ipp, ip, i_hash);
|
||||
ip->i_flag |= IN_HASHED;
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from the hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashrem(ip)
|
||||
ntfs_nthashrem(ip)
|
||||
struct ntnode *ip;
|
||||
{
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
if (ip->i_flag & IN_HASHED) {
|
||||
ip->i_flag &= ~IN_HASHED;
|
||||
LIST_REMOVE(ip, i_hash);
|
||||
@ -153,5 +121,5 @@ ntfs_ihashrem(ip)
|
||||
ip->i_hash.le_prev = NULL;
|
||||
#endif
|
||||
}
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
}
|
||||
|
33
sys/fs/ntfs/ntfs_ihash.h
Normal file
33
sys/fs/ntfs/ntfs_ihash.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id: ntfs.h,v 1.9 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
|
||||
void ntfs_nthashinit __P((void));
|
||||
struct ntnode *ntfs_nthashlookup __P((dev_t, ino_t));
|
||||
struct ntnode *ntfs_nthashget __P((dev_t, ino_t));
|
||||
void ntfs_nthashins __P((struct ntnode *));
|
||||
void ntfs_nthashrem __P((register struct ntnode *));
|
@ -53,48 +53,58 @@
|
||||
|
||||
#define IN_LOADED 0x8000 /* ntvattrs loaded */
|
||||
#define IN_PRELOADED 0x4000 /* loaded from directory entry */
|
||||
#define IN_AATTRNAME 0x2000 /* spaec allocated for i_defattrname */
|
||||
|
||||
struct ntnode {
|
||||
#if __FreeBSD_version >= 300000
|
||||
struct lock i_lock; /* Must be first */
|
||||
#endif
|
||||
LIST_ENTRY(ntnode) i_hash;
|
||||
struct ntnode *i_next;
|
||||
struct ntnode **i_prev;
|
||||
struct vnode *i_vnode;
|
||||
struct vnode *i_devvp;
|
||||
struct ntfsmount *i_mp;
|
||||
enum vtype i_type;
|
||||
dev_t i_dev;
|
||||
ino_t i_number;
|
||||
dev_t i_dev;
|
||||
u_int32_t i_flag;
|
||||
int i_usecount;
|
||||
|
||||
LIST_HEAD(,fnode) i_fnlist;
|
||||
struct ntvattr *i_vattrp; /* ntvattrs list */
|
||||
|
||||
long i_nlink; /* MFR */
|
||||
ino_t i_mainrec; /* MFR */
|
||||
u_int32_t i_frflag; /* MFR */
|
||||
ntfs_times_t i_times; /* $NAME/dirinfo */
|
||||
ino_t i_pnumber; /* $NAME/dirinfo */
|
||||
u_int32_t i_fflag; /* $NAME/dirinfo */
|
||||
u_int64_t i_size; /* defattr/dirinfo: */
|
||||
u_int64_t i_allocated; /* defattr/dirinfo */
|
||||
|
||||
u_int32_t i_lastdattr;
|
||||
u_int32_t i_lastdblnum;
|
||||
u_int32_t i_lastdoff;
|
||||
u_int32_t i_lastdnum;
|
||||
caddr_t i_dirblbuf;
|
||||
u_int32_t i_dirblsz;
|
||||
|
||||
uid_t i_uid;
|
||||
gid_t i_gid;
|
||||
mode_t i_mode;
|
||||
|
||||
u_int32_t i_defattr;
|
||||
char *i_defattrname;
|
||||
struct ntvattr *i_vattrp;
|
||||
|
||||
int i_lockcount; /* Process lock count (recursion) */
|
||||
pid_t i_lockholder; /* DEBUG: holder of ntnode lock. */
|
||||
pid_t i_lockwaiter; /* DEBUG: waiter of ntnode lock. */
|
||||
};
|
||||
|
||||
#define FN_PRELOADED 0x0001
|
||||
#define FN_DEFAULT 0x0002
|
||||
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
|
||||
struct fnode {
|
||||
struct lock f_lock; /* Must be first */
|
||||
|
||||
LIST_ENTRY(fnode) f_fnlist;
|
||||
struct vnode *f_vp; /* Associatied vnode */
|
||||
struct ntnode *f_ip;
|
||||
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 */
|
||||
u_int32_t f_fflag; /* $NAME/dirinfo */
|
||||
u_int64_t f_size; /* defattr/dirinfo: */
|
||||
u_int64_t f_allocated; /* defattr/dirinfo */
|
||||
|
||||
u_int32_t f_attrtype;
|
||||
char *f_attrname;
|
||||
|
||||
/* for ntreaddir */
|
||||
u_int32_t f_lastdattr;
|
||||
u_int32_t f_lastdblnum;
|
||||
u_int32_t f_lastdoff;
|
||||
u_int32_t f_lastdnum;
|
||||
caddr_t f_dirblbuf;
|
||||
u_int32_t f_dirblsz;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,10 +26,14 @@
|
||||
* $Id: ntfs_subr.h,v 1.3 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
|
||||
#define VA_LOADED 0x0001
|
||||
#define VA_PRELOADED 0x0002
|
||||
|
||||
struct ntvattr {
|
||||
struct ntvattr *va_nextp;
|
||||
|
||||
u_int32_t va_vflag;
|
||||
struct vnode *va_vp;
|
||||
struct ntnode *va_ip;
|
||||
|
||||
u_int32_t va_flag;
|
||||
@ -48,7 +52,7 @@ struct ntvattr {
|
||||
struct {
|
||||
cn_t * cn;
|
||||
cn_t * cl;
|
||||
u_int32_t cnt;
|
||||
u_long cnt;
|
||||
} vrun;
|
||||
caddr_t datap;
|
||||
struct attr_name *name;
|
||||
@ -67,30 +71,41 @@ struct ntvattr {
|
||||
|
||||
#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 *, size_t, int *));
|
||||
int ntfs_runtocn __P(( cn_t *, struct ntfsmount *, u_int8_t *, size_t, cn_t));
|
||||
int ntfs_breadntvattr_plain __P(( struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *,size_t *));
|
||||
int ntfs_breadattr_plain __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *));
|
||||
int ntfs_breadattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *));
|
||||
int ntfs_filesize __P(( struct ntfsmount *, struct ntnode *, u_int64_t *, u_int64_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_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 ntnode *, u_int32_t, struct attr_indexentry **));
|
||||
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 *, wchar *, int, char *, int ));
|
||||
int ntfs_uastrcmp __P(( struct ntfsmount *, wchar *, int, char *, int ));
|
||||
int ntfs_runtovrun __P(( cn_t **, cn_t **, u_int32_t *, u_int8_t *));
|
||||
int ntfs_runtovrun __P(( cn_t **, cn_t **, u_long *, u_int8_t *));
|
||||
int ntfs_attrtontvattr __P(( struct ntfsmount *, struct ntvattr **, struct attr * ));
|
||||
void ntfs_freentvattr __P(( struct ntvattr * ));
|
||||
int ntfs_loadntvattrs __P(( struct ntfsmount *, struct vnode *, caddr_t, struct ntvattr **));
|
||||
struct ntvattr * ntfs_findntvattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, cn_t ));
|
||||
int ntfs_ntlookup __P(( struct ntfsmount *, struct ntnode *, struct componentname *, struct ntnode **));
|
||||
int ntfs_ntlookup __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_ntget __P(( struct ntfsmount *, ino_t, struct ntnode **));
|
||||
void ntfs_ntrele __P(( struct ntnode *));
|
||||
int ntfs_loadnode __P(( struct ntfsmount *, struct ntnode * ));
|
||||
int ntfs_ntlookupattr __P(( struct ntfsmount *, char *, int, int *, char **));
|
||||
int ntfs_loadntnode __P(( struct ntfsmount *, struct ntnode * ));
|
||||
int ntfs_ntlookupattr(struct ntfsmount *, 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 *);
|
||||
|
@ -52,12 +52,15 @@
|
||||
#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 __FreeBSD_version >= 300000
|
||||
MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure");
|
||||
MALLOC_DEFINE(M_NTFSNODE,"NTFS node", "NTFS node information");
|
||||
MALLOC_DEFINE(M_NTFSNTNODE,"NTFS ntnode", "NTFS ntnode information");
|
||||
MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode", "NTFS fnode information");
|
||||
MALLOC_DEFINE(M_NTFSDIR,"NTFS dir", "NTFS dir buffer");
|
||||
#endif
|
||||
|
||||
@ -106,7 +109,7 @@ ntfs_init ()
|
||||
|
||||
printf("ntfs_init(): \n");
|
||||
|
||||
ntfs_ihashinit();
|
||||
ntfs_nthashinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -411,7 +414,13 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
printf("ntfs_mountfs(): reading system nodes...\n");
|
||||
{
|
||||
i = NTFS_MFTINO;
|
||||
error = VFS_VGET(mp, i, &ntmp->ntm_sysvn[i]);
|
||||
error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i]));
|
||||
if(error)
|
||||
goto out1;
|
||||
VREF(ntmp->ntm_sysvn[i]);
|
||||
vput(ntmp->ntm_sysvn[i]);
|
||||
i = NTFS_ROOTINO;
|
||||
error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i]));
|
||||
if(error)
|
||||
goto out1;
|
||||
VREF(ntmp->ntm_sysvn[i]);
|
||||
@ -426,7 +435,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
if(error)
|
||||
goto out1;
|
||||
printf("ntfs_mountfs(): reading $UpCase\n");
|
||||
error = ntfs_breadattr( ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
error = ntfs_readattr( ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, 65536*sizeof(wchar), ntmp->ntm_upcase);
|
||||
printf("ntfs_mountfs(): closing $UpCase\n");
|
||||
vput(vp);
|
||||
@ -443,7 +452,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
goto out1;
|
||||
|
||||
for(num=0;;num++) {
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp),
|
||||
error = ntfs_readattr(ntmp, VTONT(vp),
|
||||
NTFS_A_DATA, NULL,
|
||||
num * sizeof(ad), sizeof(ad),
|
||||
&ad);
|
||||
@ -461,7 +470,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
ntmp->ntm_adnum = num;
|
||||
|
||||
for(i=0;i<num;i++){
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp),
|
||||
error = ntfs_readattr(ntmp, VTONT(vp),
|
||||
NTFS_A_DATA, NULL,
|
||||
i * sizeof(ad), sizeof(ad),
|
||||
&ad);
|
||||
@ -537,13 +546,16 @@ ntfs_unmount(
|
||||
flags |= FORCECLOSE;
|
||||
|
||||
printf("ntfs_unmount: vflushing...\n");
|
||||
for(i=0;i<NTFS_SYSNODESNUM;i++)
|
||||
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
|
||||
error = vflush(mp,NULLVP,flags);
|
||||
error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
|
||||
if (error) {
|
||||
printf("ntfs_unmount: vflush failed: %d\n",error);
|
||||
return (error);
|
||||
}
|
||||
for(i=0;i<NTFS_SYSNODESNUM;i++)
|
||||
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
|
||||
error = vflush(mp,NULLVP,flags);
|
||||
if (error)
|
||||
printf("ntfs_unmount: vflush failed: %d\n",error);
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
ntmp->ntm_devvp->v_specmountpoint = NULL;
|
||||
@ -578,7 +590,8 @@ ntfs_root(
|
||||
struct vnode *nvp;
|
||||
int error = 0;
|
||||
|
||||
dprintf(("ntfs_root():\n"));
|
||||
dprintf(("ntfs_root(): sysvn: %p\n",
|
||||
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
|
||||
error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
|
||||
if(error) {
|
||||
printf("ntfs_root: VFS_VGET failed: %d\n",error);
|
||||
@ -615,18 +628,18 @@ ntfs_statfs(
|
||||
|
||||
dprintf(("ntfs_statfs():"));
|
||||
|
||||
ntfs_filesize(ntmp, VTONT(ntmp->ntm_sysvn[NTFS_MFTINO]),
|
||||
ntfs_filesize(ntmp, VTOF(ntmp->ntm_sysvn[NTFS_MFTINO]),
|
||||
&mftsize, &mftallocated);
|
||||
|
||||
error = VFS_VGET(mp, NTFS_BITMAPINO, &vp);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
ntfs_filesize(ntmp, VTONT(vp), &bmsize, &bmallocated);
|
||||
ntfs_filesize(ntmp, VTOF(vp), &bmsize, &bmallocated);
|
||||
|
||||
MALLOC(tmp, u_int8_t *, bmsize,M_TEMP, M_WAITOK);
|
||||
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, bmsize, tmp);
|
||||
if(error) {
|
||||
FREE(tmp, M_TEMP);
|
||||
@ -660,6 +673,7 @@ ntfs_statfs(
|
||||
bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
|
||||
(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
|
||||
}
|
||||
sbp->f_flags = mp->mnt_flag;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -708,58 +722,107 @@ ntfs_vptofh(
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
ntfs_vgetex(
|
||||
struct mount *mp,
|
||||
ino_t ino,
|
||||
u_int32_t attrtype,
|
||||
char *attrname,
|
||||
u_long lkflags,
|
||||
u_long flags,
|
||||
struct proc *p,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
int error;
|
||||
register struct ntfsmount *ntmp;
|
||||
struct ntnode *ip;
|
||||
struct fnode *fp;
|
||||
struct vnode *vp;
|
||||
|
||||
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%x, f: 0x%x\n",
|
||||
ino, attrtype, attrname?attrname:"", lkflags, flags ));
|
||||
|
||||
ntmp = VFSTONTFS(mp);
|
||||
*vpp = NULL;
|
||||
|
||||
/* Get ntnode */
|
||||
error = ntfs_ntget(ntmp, ino, &ip);
|
||||
if (error) {
|
||||
printf("ntfs_vget: ntfs_ntget failed\n");
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
|
||||
if (error) {
|
||||
printf("ntfs_vget: ntfs_fget failed\n");
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (FTOV(fp)) {
|
||||
vget(FTOV(fp), lkflags, p);
|
||||
*vpp = FTOV(fp);
|
||||
ntfs_ntrele(ip);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* It may be not initialized fully, so force load it */
|
||||
if (!(flags & VG_DONTLOAD) && !(ip->i_flag & IN_LOADED)) {
|
||||
error = ntfs_loadntnode(ntmp, ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
|
||||
ip->i_number);
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
|
||||
if(error) {
|
||||
ntfs_frele(fp);
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
|
||||
|
||||
lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
|
||||
fp->f_vp = vp;
|
||||
vp->v_data = fp;
|
||||
|
||||
if (ip->i_frflag & NTFS_FRFLAG_DIR)
|
||||
vp->v_type = fp->f_type = VDIR;
|
||||
else
|
||||
vp->v_type = fp->f_type = VREG;
|
||||
|
||||
if (ino == NTFS_ROOTINO)
|
||||
vp->v_flag |= VROOT;
|
||||
if (ino < NTFS_SYSNODESNUM)
|
||||
vp->v_flag |= VSYSTEM;
|
||||
|
||||
ntfs_ntrele(ip);
|
||||
|
||||
if (lkflags & LK_TYPE_MASK) {
|
||||
error = vn_lock(vp, lkflags, p);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
VREF(fp->f_devvp);
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_vget(
|
||||
struct mount *mp,
|
||||
ino_t ino,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
int error=0;
|
||||
struct vnode *vp;
|
||||
register struct ntfsmount *ntmp;
|
||||
struct ntnode *ip;
|
||||
|
||||
dprintf(("ntfs_vget: ino: %d\n",ino));
|
||||
|
||||
ntmp = VFSTONTFS(mp);
|
||||
|
||||
*vpp = NULL;
|
||||
|
||||
dprintf(("ntfs_ntvget: ihashlookup\n"));
|
||||
if( (*vpp = ntfs_ihashget(ntmp->ntm_dev, ino)) != NULL )
|
||||
return (0);
|
||||
|
||||
error = ntfs_ntget(ntmp,ino,&ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: ntfs_ntget failed\n");
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
|
||||
if(error) {
|
||||
/* XXX */
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
ip->i_vnode = vp;
|
||||
vp->v_data = ip;
|
||||
vp->v_type = ip->i_type;
|
||||
|
||||
ntfs_ihashins(ip);
|
||||
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
error = ntfs_loadnode(ntmp, ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
|
||||
ip->i_number);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
*vpp = vp;
|
||||
|
||||
return (0);
|
||||
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
|
||||
LK_EXCLUSIVE, 0, curproc, vpp);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
|
33
sys/fs/ntfs/ntfs_vfsops.h
Normal file
33
sys/fs/ntfs/ntfs_vfsops.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ntfs_vfsops.h,v 1.1 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
#define VG_DONTLOAD 0x0001 /* Tells ntfs_vgetex to do not call */
|
||||
/* ntfs_loadnode on ntnode, even if */
|
||||
/* ntnode not loaded */
|
||||
|
||||
int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
|
||||
struct proc *, struct vnode **);
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ntfs_vnops.c,v 1.9 1999/02/02 01:54:55 semen Exp $
|
||||
* $Id: ntfs_vnops.c,v 1.10 1999/02/02 03:15:13 semen Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -66,11 +66,12 @@
|
||||
#include <ntfs/ntfs.h>
|
||||
#include <ntfs/ntfs_inode.h>
|
||||
#include <ntfs/ntfs_subr.h>
|
||||
#include <ntfs/ntfs_extern.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
|
||||
static int ntfs_bypass __P((struct vop_generic_args *ap));
|
||||
static int ntfs_read __P((struct vop_read_args *));
|
||||
static int ntfs_bwrite __P((struct vop_bwrite_args *ap));
|
||||
static int ntfs_write __P((struct vop_write_args *ap));
|
||||
static int ntfs_getattr __P((struct vop_getattr_args *ap));
|
||||
static int ntfs_inactive __P((struct vop_inactive_args *ap));
|
||||
static int ntfs_print __P((struct vop_print_args *ap));
|
||||
@ -88,120 +89,25 @@ static int ntfs_readdir __P((struct vop_readdir_args *ap));
|
||||
static int ntfs_lookup __P((struct vop_lookup_args *ap));
|
||||
static int ntfs_bmap __P((struct vop_bmap_args *ap));
|
||||
static int ntfs_getpages __P((struct vop_getpages_args *ap));
|
||||
static int ntfs_putpages __P((struct vop_putpages_args *));
|
||||
static int ntfs_fsync __P((struct vop_fsync_args *ap));
|
||||
|
||||
int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
/*
|
||||
* Vnode op for VM getpages.
|
||||
*/
|
||||
int
|
||||
ntfs_getpages(ap)
|
||||
struct vop_getpages_args *ap;
|
||||
{
|
||||
int i, error, nextoff, size, toff, npages, count;
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
vm_offset_t kva;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
struct proc *p;
|
||||
struct ucred *cred;
|
||||
struct ntfsmount *ntmp;
|
||||
vm_page_t *pages;
|
||||
return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
|
||||
ap->a_reqpage);
|
||||
}
|
||||
|
||||
vp = ap->a_vp;
|
||||
p = curproc; /* XXX */
|
||||
cred = curproc->p_ucred; /* XXX */
|
||||
ntmp = VFSTONTFS(vp->v_mount);
|
||||
pages = ap->a_m;
|
||||
count = ap->a_count;
|
||||
|
||||
if (vp->v_object == NULL) {
|
||||
printf("ntfs_getpages: called with non-merged cache vnode??\n");
|
||||
return VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We use only the kva address for the buffer, but this is extremely
|
||||
* convienient and fast.
|
||||
*/
|
||||
#if __FreeBSD_version >= 400000
|
||||
bp = getpbuf(NULL);
|
||||
#else
|
||||
bp = getpbuf();
|
||||
#endif
|
||||
|
||||
npages = btoc(count);
|
||||
kva = (vm_offset_t) bp->b_data;
|
||||
pmap_qenter(kva, pages, npages);
|
||||
|
||||
iov.iov_base = (caddr_t) kva;
|
||||
iov.iov_len = count;
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
|
||||
uio.uio_resid = count;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_rw = UIO_READ;
|
||||
uio.uio_procp = p;
|
||||
|
||||
error = VOP_READ(vp, &uio, 0, cred);
|
||||
pmap_qremove(kva, npages);
|
||||
|
||||
#if __FreeBSD_version >= 400000
|
||||
relpbuf(bp,NULL);
|
||||
#else
|
||||
relpbuf(bp);
|
||||
#endif
|
||||
|
||||
if (error && (uio.uio_resid == count))
|
||||
return VM_PAGER_ERROR;
|
||||
|
||||
size = count - uio.uio_resid;
|
||||
|
||||
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
|
||||
vm_page_t m;
|
||||
nextoff = toff + PAGE_SIZE;
|
||||
m = pages[i];
|
||||
|
||||
m->flags &= ~PG_ZERO;
|
||||
|
||||
if (nextoff <= size) {
|
||||
m->valid = VM_PAGE_BITS_ALL;
|
||||
m->dirty = 0;
|
||||
} else {
|
||||
int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1);
|
||||
vm_page_set_validclean(m, 0, nvalid);
|
||||
}
|
||||
|
||||
if (i != ap->a_reqpage) {
|
||||
/*
|
||||
* Whether or not to leave the page activated is up in
|
||||
* the air, but we should put the page on a page queue
|
||||
* somewhere (it already is in the object). Result:
|
||||
* It appears that emperical results show that
|
||||
* deactivating pages is best.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Just in case someone was asking for this page we
|
||||
* now tell them that it is ok to use.
|
||||
*/
|
||||
if (!error) {
|
||||
if (m->flags & PG_WANTED)
|
||||
vm_page_activate(m);
|
||||
else
|
||||
vm_page_deactivate(m);
|
||||
#if __FreeBSD_version >= 300000
|
||||
vm_page_wakeup(m);
|
||||
#endif
|
||||
} else {
|
||||
vnode_pager_freepage(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
int
|
||||
ntfs_putpages(ap)
|
||||
struct vop_putpages_args *ap;
|
||||
{
|
||||
return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
|
||||
ap->a_sync, ap->a_rtvals);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -218,6 +124,7 @@ ntfs_bmap(ap)
|
||||
int *a_runb;
|
||||
} */ *ap;
|
||||
{
|
||||
dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn));
|
||||
if (ap->a_vpp != NULL)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
@ -239,7 +146,8 @@ ntfs_read(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int8_t *data;
|
||||
@ -248,7 +156,7 @@ ntfs_read(ap)
|
||||
|
||||
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));
|
||||
|
||||
ntfs_filesize( ntmp, ip, &toread, NULL );
|
||||
ntfs_filesize(ntmp, fp, &toread, NULL);
|
||||
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
|
||||
|
||||
toread = min( uio->uio_resid, toread - uio->uio_offset );
|
||||
@ -257,16 +165,17 @@ ntfs_read(ap)
|
||||
|
||||
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
|
||||
|
||||
error = ntfs_breadattr( ntmp, ip, ip->i_defattr, ip->i_defattrname,
|
||||
uio->uio_offset, toread, data );
|
||||
error = ntfs_readattr( ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, uio->uio_offset, toread, data);
|
||||
if(error) {
|
||||
printf("ntfs_read: ntfs_breadattr failed: %d\n",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);
|
||||
}
|
||||
@ -284,7 +193,7 @@ ntfs_bypass(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
int error = ENOTTY;
|
||||
dprintf (("ntfs_bypass: %s\n", ap->a_desc->vdesc_name));
|
||||
dprintf(("ntfs_bypass: %s\n", ap->a_desc->vdesc_name));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -299,33 +208,28 @@ ntfs_getattr(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
register struct vattr *vap = ap->a_vap;
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag));
|
||||
|
||||
if ((ip->i_flag & (IN_LOADED | IN_PRELOADED)) == 0) {
|
||||
error = ntfs_loadnode(ip->i_mp,ip);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
vap->va_fsid = ip->i_dev;
|
||||
vap->va_fsid = fp->f_dev;
|
||||
vap->va_fileid = ip->i_number;
|
||||
vap->va_mode = ip->i_mode;
|
||||
vap->va_nlink = ip->i_nlink;
|
||||
vap->va_uid = ip->i_uid;
|
||||
vap->va_gid = ip->i_gid;
|
||||
vap->va_rdev = (dev_t)0;
|
||||
vap->va_size = ip->i_size;
|
||||
vap->va_bytes = ip->i_allocated;
|
||||
vap->va_atime = ntfs_nttimetounix(ip->i_times.t_access);
|
||||
vap->va_mtime = ntfs_nttimetounix(ip->i_times.t_write);
|
||||
vap->va_ctime = ntfs_nttimetounix(ip->i_times.t_create);
|
||||
vap->va_size = fp->f_size;
|
||||
vap->va_bytes = fp->f_allocated;
|
||||
vap->va_atime = ntfs_nttimetounix(fp->f_times.t_access);
|
||||
vap->va_mtime = ntfs_nttimetounix(fp->f_times.t_write);
|
||||
vap->va_ctime = ntfs_nttimetounix(fp->f_times.t_create);
|
||||
vap->va_flags = ip->i_flag;
|
||||
vap->va_gen = 0;
|
||||
vap->va_blocksize = ip->i_mp->ntm_spc * ip->i_mp->ntm_bps;
|
||||
vap->va_type = ip->i_type;
|
||||
vap->va_type = fp->f_type;
|
||||
vap->va_filerev = 0;
|
||||
return (0);
|
||||
}
|
||||
@ -346,8 +250,7 @@ ntfs_inactive(ap)
|
||||
#endif
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_inactive: %d (%d locks)\n",
|
||||
ip->i_number,ip->i_lockcount));
|
||||
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);
|
||||
@ -391,34 +294,25 @@ ntfs_reclaim(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
#if NTFS_DEBUG
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
#endif
|
||||
|
||||
dprintf(("ntfs_reclaim: reclaim: %d\n",ip->i_number));
|
||||
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
VOP_UNLOCK(vp,0,ap->a_p);
|
||||
#endif
|
||||
|
||||
if(ip->i_dirblbuf) {
|
||||
FREE(ip->i_dirblbuf, M_NTFSDIR);
|
||||
ip->i_dirblbuf = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
ntfs_ihashrem(ip);
|
||||
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
/* Purge old data structures associated with the inode. */
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
if (fp->f_devvp) {
|
||||
vrele(fp->f_devvp);
|
||||
fp->f_devvp = NULL;
|
||||
}
|
||||
|
||||
ntfs_ntrele(ip);
|
||||
ntfs_frele(fp);
|
||||
|
||||
vp->v_data = NULL;
|
||||
|
||||
@ -447,47 +341,126 @@ ntfs_strategy(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct buf *bp = ap->a_bp;
|
||||
struct ucred *cr;
|
||||
struct proc *p;
|
||||
int error = 0;
|
||||
register struct vnode *vp = bp->b_vp;
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
int error;
|
||||
|
||||
dprintf(("strategy: data: %p, npages: %d,dirty: %d\n",bp->b_data,bp->b_npages,bp->b_dirtyend));
|
||||
if (bp->b_flags & B_PHYS)
|
||||
panic("ntfs physio");
|
||||
if (bp->b_flags & B_ASYNC)
|
||||
p = (struct proc *)0;
|
||||
else
|
||||
p = curproc; /* XXX */
|
||||
if (bp->b_flags & B_READ)
|
||||
cr = bp->b_rcred;
|
||||
else
|
||||
cr = bp->b_wcred;
|
||||
/*
|
||||
* If the op is asynchronous and an i/o daemon is waiting
|
||||
* queue the request, wake it up and wait for completion
|
||||
* otherwise just do it ourselves.
|
||||
*/
|
||||
/*
|
||||
if ((bp->b_flags & B_ASYNC) == 0 ||
|
||||
nfs_asyncio(bp, NOCRED))
|
||||
error = nfs_doio(bp, cr, p);
|
||||
*/
|
||||
dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
|
||||
(u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno,
|
||||
(u_int32_t)bp->b_lblkno));
|
||||
dprintf(("strategy: bcount: %d flags: 0x%x\n",
|
||||
(u_int32_t)bp->b_bcount,bp->b_flags));
|
||||
|
||||
return (ENOTTY);
|
||||
if (bp->b_flags & B_READ) {
|
||||
u_int32_t toread;
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
|
||||
clrbuf(bp);
|
||||
error = 0;
|
||||
} else {
|
||||
toread = min(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
|
||||
toread,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),
|
||||
toread, bp->b_data);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_readattr failed\n");
|
||||
bp->b_error = error;
|
||||
bp->b_flags |= B_ERROR;
|
||||
}
|
||||
|
||||
bzero(bp->b_data + toread, bp->b_bcount - toread);
|
||||
}
|
||||
} else {
|
||||
size_t tmp;
|
||||
u_int32_t towrite;
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) {
|
||||
printf("ntfs_strategy: CAN'T EXTEND FILE\n");
|
||||
bp->b_error = error = EFBIG;
|
||||
bp->b_flags |= B_ERROR;
|
||||
} else {
|
||||
towrite = min(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n",
|
||||
towrite,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
|
||||
bp->b_data, &tmp);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_writeattr fail\n");
|
||||
bp->b_error = error;
|
||||
bp->b_flags |= B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
biodone(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_bwrite(ap)
|
||||
struct vop_bwrite_args /* {
|
||||
struct buf *a_bp;
|
||||
ntfs_write(ap)
|
||||
struct vop_write_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
int error = ENOTTY;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int8_t *data;
|
||||
u_int64_t towrite;
|
||||
off_t off;
|
||||
size_t written;
|
||||
int error;
|
||||
|
||||
printf("ntfs_bwrite: \n");
|
||||
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));
|
||||
|
||||
return (error);
|
||||
ntfs_filesize(ntmp, fp, &towrite, NULL);
|
||||
|
||||
if (uio->uio_resid + uio->uio_offset > towrite) {
|
||||
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
|
||||
return (EFBIG);
|
||||
}
|
||||
|
||||
dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
|
||||
|
||||
towrite = min(uio->uio_resid, towrite - uio->uio_offset);
|
||||
off = 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);
|
||||
}
|
||||
|
||||
FREE(data, M_TEMP);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 300000
|
||||
@ -502,7 +475,7 @@ ntfs_islocked(ap)
|
||||
{
|
||||
register struct ntnode *ip = VTONT(ap->a_vp);
|
||||
|
||||
dprintf(("ntfs_islocked %d (%d locks)\n",ip->i_number,ip->i_lockcount));
|
||||
dprintf(("ntfs_islocked %d\n",ip->i_number));
|
||||
|
||||
if (ip->i_flag & IN_LOCKED)
|
||||
return (1);
|
||||
@ -522,7 +495,7 @@ ntfs_unlock(ap)
|
||||
register struct ntnode *ip = VTONT(ap->a_vp);
|
||||
struct proc *p = curproc;
|
||||
|
||||
dprintf(("ntfs_unlock %d (%d locks)\n",ip->i_number,ip->i_lockcount));
|
||||
dprintf(("ntfs_unlock %d\n",ip->i_number));
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
|
||||
@ -639,7 +612,7 @@ ntfs_access(ap)
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
switch ((int)vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
@ -717,7 +690,7 @@ ntfs_open(ap)
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
|
||||
printf("ntfs_open: %d (%d locks)\n",ip->i_number,ip->i_lockcount);
|
||||
printf("ntfs_open: %d\n",ip->i_number);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -746,7 +719,7 @@ ntfs_close(ap)
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
|
||||
printf("ntfs_close: %d (%d locks)\n",ip->i_number,ip->i_lockcount);
|
||||
printf("ntfs_close: %d\n",ip->i_number);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
@ -767,7 +740,8 @@ ntfs_readdir(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
int i, error = 0;
|
||||
@ -813,7 +787,7 @@ ntfs_readdir(ap)
|
||||
while( uio->uio_resid >= sizeof(struct dirent) ) {
|
||||
struct attr_indexentry *iep;
|
||||
|
||||
error = ntfs_ntreaddir(ntmp, ip, num, &iep);
|
||||
error = ntfs_ntreaddir(ntmp, fp, num, &iep);
|
||||
|
||||
if(error)
|
||||
return (error);
|
||||
@ -919,7 +893,7 @@ ntfs_lookup(ap)
|
||||
cnp->cn_nameptr, cnp->cn_namelen,
|
||||
dip->i_number,lockparent, wantparent));
|
||||
|
||||
error = VOP_ACCESS(dvp,VEXEC, cred, cnp->cn_proc);
|
||||
error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
@ -974,39 +948,12 @@ ntfs_lookup(ap)
|
||||
}
|
||||
return (error);
|
||||
} else {
|
||||
struct ntnode * nip;
|
||||
|
||||
error = ntfs_ntlookup(ntmp, dip, cnp, &nip);
|
||||
error = ntfs_ntlookup(ntmp, dvp, cnp, ap->a_vpp);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
dprintf(("ntfs_lookup: found ino: %d\n", nip->i_number));
|
||||
if( nip->i_number == dip->i_number ) {
|
||||
ntfs_ntrele(nip);
|
||||
VREF(dvp);
|
||||
*ap->a_vpp = dvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
*ap->a_vpp = ntfs_ihashget(ntmp->ntm_dev, nip->i_number);
|
||||
if(*ap->a_vpp == NULL) {
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp,
|
||||
ntfs_vnodeop_p, ap->a_vpp);
|
||||
if(error) {
|
||||
ntfs_ntrele(nip);
|
||||
return (error);
|
||||
}
|
||||
nip->i_vnode = *(ap->a_vpp);
|
||||
(*ap->a_vpp)->v_data = nip;
|
||||
(*ap->a_vpp)->v_type = nip->i_type;
|
||||
|
||||
ntfs_ihashins(nip);
|
||||
|
||||
VREF(nip->i_devvp);
|
||||
} else {
|
||||
printf("found in cache\n");
|
||||
ntfs_ntrele(nip);
|
||||
}
|
||||
dprintf(("ntfs_lookup: found ino: %d\n",
|
||||
VTONT(*ap->a_vpp)->i_number));
|
||||
|
||||
if(!lockparent || !(cnp->cn_flags & ISLASTCN))
|
||||
#if __FreeBSD_version >= 300000
|
||||
@ -1070,10 +1017,12 @@ static struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
|
||||
|
||||
{ &vop_bmap_desc, (vop_t *)ntfs_bmap },
|
||||
{ &vop_getpages_desc, (vop_t *)ntfs_getpages },
|
||||
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
|
||||
|
||||
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
|
||||
{ &vop_bwrite_desc, (vop_t *)ntfs_bwrite },
|
||||
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
|
||||
{ &vop_read_desc, (vop_t *)ntfs_read },
|
||||
{ &vop_write_desc, (vop_t *)ntfs_write },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -182,6 +182,7 @@ struct attr_indexentry {
|
||||
};
|
||||
|
||||
#define NTFS_FILEMAGIC (u_int32_t)(0x454C4946)
|
||||
#define NTFS_FRFLAG_DIR 0x0002
|
||||
struct filerec {
|
||||
struct fixuphdr fr_fixup;
|
||||
u_int8_t reserved[8];
|
||||
@ -195,10 +196,11 @@ struct filerec {
|
||||
u_int16_t fr_attrnum; /* maximum attr number + 1 ??? */
|
||||
};
|
||||
|
||||
#define NTFS_ATTRNAME_MAXLEN 0x40
|
||||
#define NTFS_ADFLAG_NONRES 0x0080 /* Attrib can be non resident */
|
||||
#define NTFS_ADFLAG_INDEX 0x0002 /* Attrib can be indexed */
|
||||
struct attrdef {
|
||||
wchar ad_name[0x40];
|
||||
wchar ad_name[NTFS_ATTRNAME_MAXLEN];
|
||||
u_int32_t ad_type;
|
||||
u_int32_t reserved1[2];
|
||||
u_int32_t ad_flag;
|
||||
@ -261,8 +263,10 @@ struct ntfsmount {
|
||||
|
||||
/* Convert mount ptr to ntfsmount ptr. */
|
||||
#define VFSTONTFS(mp) ((struct ntfsmount *)((mp)->mnt_data))
|
||||
#define VTONT(v) ((struct ntnode *)((struct vnode *)(v)->v_data))
|
||||
#define NTTOV(i) (i->i_vnode)
|
||||
#define VTONT(v) FTONT(VTOF(v))
|
||||
#define VTOF(v) ((struct fnode *)((v)->v_data))
|
||||
#define FTOV(f) ((f)->f_vp)
|
||||
#define FTONT(f) ((f)->f_ip)
|
||||
#define ntfs_cntobn(cn) (daddr_t)((cn) * (ntmp->ntm_spc))
|
||||
#define ntfs_cntob(cn) (off_t)((cn) * (ntmp)->ntm_spc * (ntmp)->ntm_bps)
|
||||
#define ntfs_btocn(off) (cn_t)((off) / ((ntmp)->ntm_spc * (ntmp)->ntm_bps))
|
||||
@ -274,9 +278,10 @@ struct ntfsmount {
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
MALLOC_DECLARE(M_NTFSMNT);
|
||||
MALLOC_DECLARE(M_NTFSNODE);
|
||||
MALLOC_DECLARE(M_NTFSNTNODE);
|
||||
MALLOC_DECLARE(M_NTFSFNODE);
|
||||
MALLOC_DECLARE(M_NTFSDIR);
|
||||
MALLOC_DECLARE(M_NTFSIHASH);
|
||||
MALLOC_DECLARE(M_NTFSNTHASH);
|
||||
#endif
|
||||
|
||||
#if defined(NTFS_DEBUG)
|
||||
@ -292,10 +297,3 @@ MALLOC_DECLARE(M_NTFSIHASH);
|
||||
#endif
|
||||
|
||||
extern vop_t **ntfs_vnodeop_p;
|
||||
struct ntnode;
|
||||
|
||||
void ntfs_ihashinit __P((void));
|
||||
struct vnode *ntfs_ihashlookup __P((dev_t, ino_t));
|
||||
struct vnode *ntfs_ihashget __P((dev_t, ino_t));
|
||||
void ntfs_ihashins __P((struct ntnode *));
|
||||
void ntfs_ihashrem __P((register struct ntnode *));
|
||||
|
@ -48,7 +48,7 @@
|
||||
int
|
||||
ntfs_uncompblock(
|
||||
u_int8_t * buf,
|
||||
const u_int8_t * cbuf)
|
||||
u_int8_t * cbuf)
|
||||
{
|
||||
u_int32_t ctag;
|
||||
int len, dshift, lmask;
|
||||
@ -100,7 +100,7 @@ int
|
||||
ntfs_uncompunit(
|
||||
struct ntfsmount * ntmp,
|
||||
u_int8_t * uup,
|
||||
const u_int8_t * cup)
|
||||
u_int8_t * cup)
|
||||
{
|
||||
int i;
|
||||
int off = 0;
|
||||
|
@ -29,5 +29,5 @@
|
||||
#define NTFS_COMPBLOCK_SIZE 0x1000
|
||||
#define NTFS_COMPUNIT_CL 16
|
||||
|
||||
int ntfs_uncompblock(u_int8_t *, const u_int8_t *);
|
||||
int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, const u_int8_t *);
|
||||
int ntfs_uncompblock(u_int8_t *, u_int8_t *);
|
||||
int ntfs_uncompunit(struct ntfsmount *, u_int8_t *, u_int8_t *);
|
||||
|
@ -27,3 +27,5 @@
|
||||
*/
|
||||
|
||||
struct sockaddr;
|
||||
int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
|
||||
void ntfs_frele(struct fnode *);
|
||||
|
@ -44,107 +44,75 @@
|
||||
|
||||
#include <ntfs/ntfs.h>
|
||||
#include <ntfs/ntfs_inode.h>
|
||||
#include <ntfs/ntfs_ihash.h>
|
||||
|
||||
MALLOC_DEFINE(M_NTFSIHASH, "NTFS ihash", "NTFS Inode hash tables");
|
||||
MALLOC_DEFINE(M_NTFSNTHASH, "NTFS nthash", "NTFS ntnode hash tables");
|
||||
|
||||
/*
|
||||
* Structures associated with inode cacheing.
|
||||
*/
|
||||
static LIST_HEAD(ihashhead, ntnode) *ntfs_ihashtbl;
|
||||
static u_long ntfs_ihash; /* size of hash table - 1 */
|
||||
#define NTNOHASH(device, inum) (&ntfs_ihashtbl[((device) + (inum)) & ntfs_ihash])
|
||||
static struct simplelock ntfs_ihash_slock;
|
||||
static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
|
||||
static u_long ntfs_nthash; /* size of hash table - 1 */
|
||||
#define NTNOHASH(device, inum) (&ntfs_nthashtbl[((device) + (inum)) & ntfs_nthash])
|
||||
#ifndef NULL_SIMPLELOCKS
|
||||
static struct simplelock ntfs_nthash_slock;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize inode hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashinit()
|
||||
ntfs_nthashinit()
|
||||
{
|
||||
|
||||
ntfs_ihashtbl = hashinit(desiredvnodes, M_NTFSIHASH, &ntfs_ihash);
|
||||
simple_lock_init(&ntfs_ihash_slock);
|
||||
ntfs_nthashtbl = hashinit(desiredvnodes, M_NTFSNTHASH, &ntfs_nthash);
|
||||
simple_lock_init(&ntfs_nthash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the device/inum pair to find the incore inode, and return a pointer
|
||||
* to it. If it is in core, return it, even if it is locked.
|
||||
*/
|
||||
struct vnode *
|
||||
ntfs_ihashlookup(dev, inum)
|
||||
struct ntnode *
|
||||
ntfs_nthashlookup(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct ntnode *ip;
|
||||
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
for (ip = NTNOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next)
|
||||
if (inum == ip->i_number && dev == ip->i_dev)
|
||||
break;
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
|
||||
if (ip)
|
||||
return (NTTOV(ip));
|
||||
return (NULLVP);
|
||||
return (ip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the device/inum pair to find the incore inode, and return a pointer
|
||||
* to it. If it is in core, but locked, wait for it.
|
||||
*/
|
||||
struct vnode *
|
||||
ntfs_ihashget(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct ntnode *ip;
|
||||
struct vnode *vp;
|
||||
|
||||
loop:
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
for (ip = NTNOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
|
||||
if (inum == ip->i_number && dev == ip->i_dev) {
|
||||
vp = NTTOV(ip);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
return (vp);
|
||||
}
|
||||
}
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the inode into the hash table, and return it locked.
|
||||
* Insert the ntnode into the hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashins(ip)
|
||||
ntfs_nthashins(ip)
|
||||
struct ntnode *ip;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct ihashhead *ipp;
|
||||
struct nthashhead *ipp;
|
||||
|
||||
/* lock the inode, then put it on the appropriate hash list */
|
||||
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
|
||||
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
ipp = NTNOHASH(ip->i_dev, ip->i_number);
|
||||
LIST_INSERT_HEAD(ipp, ip, i_hash);
|
||||
ip->i_flag |= IN_HASHED;
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from the hash table.
|
||||
*/
|
||||
void
|
||||
ntfs_ihashrem(ip)
|
||||
ntfs_nthashrem(ip)
|
||||
struct ntnode *ip;
|
||||
{
|
||||
simple_lock(&ntfs_ihash_slock);
|
||||
simple_lock(&ntfs_nthash_slock);
|
||||
if (ip->i_flag & IN_HASHED) {
|
||||
ip->i_flag &= ~IN_HASHED;
|
||||
LIST_REMOVE(ip, i_hash);
|
||||
@ -153,5 +121,5 @@ ntfs_ihashrem(ip)
|
||||
ip->i_hash.le_prev = NULL;
|
||||
#endif
|
||||
}
|
||||
simple_unlock(&ntfs_ihash_slock);
|
||||
simple_unlock(&ntfs_nthash_slock);
|
||||
}
|
||||
|
33
sys/ntfs/ntfs_ihash.h
Normal file
33
sys/ntfs/ntfs_ihash.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id: ntfs.h,v 1.9 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
|
||||
void ntfs_nthashinit __P((void));
|
||||
struct ntnode *ntfs_nthashlookup __P((dev_t, ino_t));
|
||||
struct ntnode *ntfs_nthashget __P((dev_t, ino_t));
|
||||
void ntfs_nthashins __P((struct ntnode *));
|
||||
void ntfs_nthashrem __P((register struct ntnode *));
|
@ -53,48 +53,58 @@
|
||||
|
||||
#define IN_LOADED 0x8000 /* ntvattrs loaded */
|
||||
#define IN_PRELOADED 0x4000 /* loaded from directory entry */
|
||||
#define IN_AATTRNAME 0x2000 /* spaec allocated for i_defattrname */
|
||||
|
||||
struct ntnode {
|
||||
#if __FreeBSD_version >= 300000
|
||||
struct lock i_lock; /* Must be first */
|
||||
#endif
|
||||
LIST_ENTRY(ntnode) i_hash;
|
||||
struct ntnode *i_next;
|
||||
struct ntnode **i_prev;
|
||||
struct vnode *i_vnode;
|
||||
struct vnode *i_devvp;
|
||||
struct ntfsmount *i_mp;
|
||||
enum vtype i_type;
|
||||
dev_t i_dev;
|
||||
ino_t i_number;
|
||||
dev_t i_dev;
|
||||
u_int32_t i_flag;
|
||||
int i_usecount;
|
||||
|
||||
LIST_HEAD(,fnode) i_fnlist;
|
||||
struct ntvattr *i_vattrp; /* ntvattrs list */
|
||||
|
||||
long i_nlink; /* MFR */
|
||||
ino_t i_mainrec; /* MFR */
|
||||
u_int32_t i_frflag; /* MFR */
|
||||
ntfs_times_t i_times; /* $NAME/dirinfo */
|
||||
ino_t i_pnumber; /* $NAME/dirinfo */
|
||||
u_int32_t i_fflag; /* $NAME/dirinfo */
|
||||
u_int64_t i_size; /* defattr/dirinfo: */
|
||||
u_int64_t i_allocated; /* defattr/dirinfo */
|
||||
|
||||
u_int32_t i_lastdattr;
|
||||
u_int32_t i_lastdblnum;
|
||||
u_int32_t i_lastdoff;
|
||||
u_int32_t i_lastdnum;
|
||||
caddr_t i_dirblbuf;
|
||||
u_int32_t i_dirblsz;
|
||||
|
||||
uid_t i_uid;
|
||||
gid_t i_gid;
|
||||
mode_t i_mode;
|
||||
|
||||
u_int32_t i_defattr;
|
||||
char *i_defattrname;
|
||||
struct ntvattr *i_vattrp;
|
||||
|
||||
int i_lockcount; /* Process lock count (recursion) */
|
||||
pid_t i_lockholder; /* DEBUG: holder of ntnode lock. */
|
||||
pid_t i_lockwaiter; /* DEBUG: waiter of ntnode lock. */
|
||||
};
|
||||
|
||||
#define FN_PRELOADED 0x0001
|
||||
#define FN_DEFAULT 0x0002
|
||||
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
|
||||
struct fnode {
|
||||
struct lock f_lock; /* Must be first */
|
||||
|
||||
LIST_ENTRY(fnode) f_fnlist;
|
||||
struct vnode *f_vp; /* Associatied vnode */
|
||||
struct ntnode *f_ip;
|
||||
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 */
|
||||
u_int32_t f_fflag; /* $NAME/dirinfo */
|
||||
u_int64_t f_size; /* defattr/dirinfo: */
|
||||
u_int64_t f_allocated; /* defattr/dirinfo */
|
||||
|
||||
u_int32_t f_attrtype;
|
||||
char *f_attrname;
|
||||
|
||||
/* for ntreaddir */
|
||||
u_int32_t f_lastdattr;
|
||||
u_int32_t f_lastdblnum;
|
||||
u_int32_t f_lastdoff;
|
||||
u_int32_t f_lastdnum;
|
||||
caddr_t f_dirblbuf;
|
||||
u_int32_t f_dirblsz;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,10 +26,14 @@
|
||||
* $Id: ntfs_subr.h,v 1.3 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
|
||||
#define VA_LOADED 0x0001
|
||||
#define VA_PRELOADED 0x0002
|
||||
|
||||
struct ntvattr {
|
||||
struct ntvattr *va_nextp;
|
||||
|
||||
u_int32_t va_vflag;
|
||||
struct vnode *va_vp;
|
||||
struct ntnode *va_ip;
|
||||
|
||||
u_int32_t va_flag;
|
||||
@ -48,7 +52,7 @@ struct ntvattr {
|
||||
struct {
|
||||
cn_t * cn;
|
||||
cn_t * cl;
|
||||
u_int32_t cnt;
|
||||
u_long cnt;
|
||||
} vrun;
|
||||
caddr_t datap;
|
||||
struct attr_name *name;
|
||||
@ -67,30 +71,41 @@ struct ntvattr {
|
||||
|
||||
#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 *, size_t, int *));
|
||||
int ntfs_runtocn __P(( cn_t *, struct ntfsmount *, u_int8_t *, size_t, cn_t));
|
||||
int ntfs_breadntvattr_plain __P(( struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *,size_t *));
|
||||
int ntfs_breadattr_plain __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *,size_t *));
|
||||
int ntfs_breadattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *));
|
||||
int ntfs_filesize __P(( struct ntfsmount *, struct ntnode *, u_int64_t *, u_int64_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_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 ntnode *, u_int32_t, struct attr_indexentry **));
|
||||
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 *, wchar *, int, char *, int ));
|
||||
int ntfs_uastrcmp __P(( struct ntfsmount *, wchar *, int, char *, int ));
|
||||
int ntfs_runtovrun __P(( cn_t **, cn_t **, u_int32_t *, u_int8_t *));
|
||||
int ntfs_runtovrun __P(( cn_t **, cn_t **, u_long *, u_int8_t *));
|
||||
int ntfs_attrtontvattr __P(( struct ntfsmount *, struct ntvattr **, struct attr * ));
|
||||
void ntfs_freentvattr __P(( struct ntvattr * ));
|
||||
int ntfs_loadntvattrs __P(( struct ntfsmount *, struct vnode *, caddr_t, struct ntvattr **));
|
||||
struct ntvattr * ntfs_findntvattr __P(( struct ntfsmount *, struct ntnode *, u_int32_t, cn_t ));
|
||||
int ntfs_ntlookup __P(( struct ntfsmount *, struct ntnode *, struct componentname *, struct ntnode **));
|
||||
int ntfs_ntlookup __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_ntget __P(( struct ntfsmount *, ino_t, struct ntnode **));
|
||||
void ntfs_ntrele __P(( struct ntnode *));
|
||||
int ntfs_loadnode __P(( struct ntfsmount *, struct ntnode * ));
|
||||
int ntfs_ntlookupattr __P(( struct ntfsmount *, char *, int, int *, char **));
|
||||
int ntfs_loadntnode __P(( struct ntfsmount *, struct ntnode * ));
|
||||
int ntfs_ntlookupattr(struct ntfsmount *, 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 *);
|
||||
|
@ -52,12 +52,15 @@
|
||||
#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 __FreeBSD_version >= 300000
|
||||
MALLOC_DEFINE(M_NTFSMNT, "NTFS mount", "NTFS mount structure");
|
||||
MALLOC_DEFINE(M_NTFSNODE,"NTFS node", "NTFS node information");
|
||||
MALLOC_DEFINE(M_NTFSNTNODE,"NTFS ntnode", "NTFS ntnode information");
|
||||
MALLOC_DEFINE(M_NTFSFNODE,"NTFS fnode", "NTFS fnode information");
|
||||
MALLOC_DEFINE(M_NTFSDIR,"NTFS dir", "NTFS dir buffer");
|
||||
#endif
|
||||
|
||||
@ -106,7 +109,7 @@ ntfs_init ()
|
||||
|
||||
printf("ntfs_init(): \n");
|
||||
|
||||
ntfs_ihashinit();
|
||||
ntfs_nthashinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -411,7 +414,13 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
printf("ntfs_mountfs(): reading system nodes...\n");
|
||||
{
|
||||
i = NTFS_MFTINO;
|
||||
error = VFS_VGET(mp, i, &ntmp->ntm_sysvn[i]);
|
||||
error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i]));
|
||||
if(error)
|
||||
goto out1;
|
||||
VREF(ntmp->ntm_sysvn[i]);
|
||||
vput(ntmp->ntm_sysvn[i]);
|
||||
i = NTFS_ROOTINO;
|
||||
error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i]));
|
||||
if(error)
|
||||
goto out1;
|
||||
VREF(ntmp->ntm_sysvn[i]);
|
||||
@ -426,7 +435,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
if(error)
|
||||
goto out1;
|
||||
printf("ntfs_mountfs(): reading $UpCase\n");
|
||||
error = ntfs_breadattr( ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
error = ntfs_readattr( ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, 65536*sizeof(wchar), ntmp->ntm_upcase);
|
||||
printf("ntfs_mountfs(): closing $UpCase\n");
|
||||
vput(vp);
|
||||
@ -443,7 +452,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
goto out1;
|
||||
|
||||
for(num=0;;num++) {
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp),
|
||||
error = ntfs_readattr(ntmp, VTONT(vp),
|
||||
NTFS_A_DATA, NULL,
|
||||
num * sizeof(ad), sizeof(ad),
|
||||
&ad);
|
||||
@ -461,7 +470,7 @@ ntfs_mountfs(devvp, mp, argsp, p)
|
||||
ntmp->ntm_adnum = num;
|
||||
|
||||
for(i=0;i<num;i++){
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp),
|
||||
error = ntfs_readattr(ntmp, VTONT(vp),
|
||||
NTFS_A_DATA, NULL,
|
||||
i * sizeof(ad), sizeof(ad),
|
||||
&ad);
|
||||
@ -537,13 +546,16 @@ ntfs_unmount(
|
||||
flags |= FORCECLOSE;
|
||||
|
||||
printf("ntfs_unmount: vflushing...\n");
|
||||
for(i=0;i<NTFS_SYSNODESNUM;i++)
|
||||
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
|
||||
error = vflush(mp,NULLVP,flags);
|
||||
error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
|
||||
if (error) {
|
||||
printf("ntfs_unmount: vflush failed: %d\n",error);
|
||||
return (error);
|
||||
}
|
||||
for(i=0;i<NTFS_SYSNODESNUM;i++)
|
||||
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
|
||||
error = vflush(mp,NULLVP,flags);
|
||||
if (error)
|
||||
printf("ntfs_unmount: vflush failed: %d\n",error);
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
ntmp->ntm_devvp->v_specmountpoint = NULL;
|
||||
@ -578,7 +590,8 @@ ntfs_root(
|
||||
struct vnode *nvp;
|
||||
int error = 0;
|
||||
|
||||
dprintf(("ntfs_root():\n"));
|
||||
dprintf(("ntfs_root(): sysvn: %p\n",
|
||||
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
|
||||
error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
|
||||
if(error) {
|
||||
printf("ntfs_root: VFS_VGET failed: %d\n",error);
|
||||
@ -615,18 +628,18 @@ ntfs_statfs(
|
||||
|
||||
dprintf(("ntfs_statfs():"));
|
||||
|
||||
ntfs_filesize(ntmp, VTONT(ntmp->ntm_sysvn[NTFS_MFTINO]),
|
||||
ntfs_filesize(ntmp, VTOF(ntmp->ntm_sysvn[NTFS_MFTINO]),
|
||||
&mftsize, &mftallocated);
|
||||
|
||||
error = VFS_VGET(mp, NTFS_BITMAPINO, &vp);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
ntfs_filesize(ntmp, VTONT(vp), &bmsize, &bmallocated);
|
||||
ntfs_filesize(ntmp, VTOF(vp), &bmsize, &bmallocated);
|
||||
|
||||
MALLOC(tmp, u_int8_t *, bmsize,M_TEMP, M_WAITOK);
|
||||
|
||||
error = ntfs_breadattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, bmsize, tmp);
|
||||
if(error) {
|
||||
FREE(tmp, M_TEMP);
|
||||
@ -660,6 +673,7 @@ ntfs_statfs(
|
||||
bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
|
||||
(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
|
||||
}
|
||||
sbp->f_flags = mp->mnt_flag;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -708,58 +722,107 @@ ntfs_vptofh(
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
ntfs_vgetex(
|
||||
struct mount *mp,
|
||||
ino_t ino,
|
||||
u_int32_t attrtype,
|
||||
char *attrname,
|
||||
u_long lkflags,
|
||||
u_long flags,
|
||||
struct proc *p,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
int error;
|
||||
register struct ntfsmount *ntmp;
|
||||
struct ntnode *ip;
|
||||
struct fnode *fp;
|
||||
struct vnode *vp;
|
||||
|
||||
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%x, f: 0x%x\n",
|
||||
ino, attrtype, attrname?attrname:"", lkflags, flags ));
|
||||
|
||||
ntmp = VFSTONTFS(mp);
|
||||
*vpp = NULL;
|
||||
|
||||
/* Get ntnode */
|
||||
error = ntfs_ntget(ntmp, ino, &ip);
|
||||
if (error) {
|
||||
printf("ntfs_vget: ntfs_ntget failed\n");
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
|
||||
if (error) {
|
||||
printf("ntfs_vget: ntfs_fget failed\n");
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (FTOV(fp)) {
|
||||
vget(FTOV(fp), lkflags, p);
|
||||
*vpp = FTOV(fp);
|
||||
ntfs_ntrele(ip);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* It may be not initialized fully, so force load it */
|
||||
if (!(flags & VG_DONTLOAD) && !(ip->i_flag & IN_LOADED)) {
|
||||
error = ntfs_loadntnode(ntmp, ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
|
||||
ip->i_number);
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
|
||||
if(error) {
|
||||
ntfs_frele(fp);
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
|
||||
|
||||
lockinit(&fp->f_lock, PINOD, "fnode", 0, 0);
|
||||
fp->f_vp = vp;
|
||||
vp->v_data = fp;
|
||||
|
||||
if (ip->i_frflag & NTFS_FRFLAG_DIR)
|
||||
vp->v_type = fp->f_type = VDIR;
|
||||
else
|
||||
vp->v_type = fp->f_type = VREG;
|
||||
|
||||
if (ino == NTFS_ROOTINO)
|
||||
vp->v_flag |= VROOT;
|
||||
if (ino < NTFS_SYSNODESNUM)
|
||||
vp->v_flag |= VSYSTEM;
|
||||
|
||||
ntfs_ntrele(ip);
|
||||
|
||||
if (lkflags & LK_TYPE_MASK) {
|
||||
error = vn_lock(vp, lkflags, p);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
VREF(fp->f_devvp);
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_vget(
|
||||
struct mount *mp,
|
||||
ino_t ino,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
int error=0;
|
||||
struct vnode *vp;
|
||||
register struct ntfsmount *ntmp;
|
||||
struct ntnode *ip;
|
||||
|
||||
dprintf(("ntfs_vget: ino: %d\n",ino));
|
||||
|
||||
ntmp = VFSTONTFS(mp);
|
||||
|
||||
*vpp = NULL;
|
||||
|
||||
dprintf(("ntfs_ntvget: ihashlookup\n"));
|
||||
if( (*vpp = ntfs_ihashget(ntmp->ntm_dev, ino)) != NULL )
|
||||
return (0);
|
||||
|
||||
error = ntfs_ntget(ntmp,ino,&ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: ntfs_ntget failed\n");
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
|
||||
if(error) {
|
||||
/* XXX */
|
||||
ntfs_ntrele(ip);
|
||||
return (error);
|
||||
}
|
||||
ip->i_vnode = vp;
|
||||
vp->v_data = ip;
|
||||
vp->v_type = ip->i_type;
|
||||
|
||||
ntfs_ihashins(ip);
|
||||
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
error = ntfs_loadnode(ntmp, ip);
|
||||
if(error) {
|
||||
printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
|
||||
ip->i_number);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
*vpp = vp;
|
||||
|
||||
return (0);
|
||||
return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
|
||||
LK_EXCLUSIVE, 0, curproc, vpp);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
|
33
sys/ntfs/ntfs_vfsops.h
Normal file
33
sys/ntfs/ntfs_vfsops.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ntfs_vfsops.h,v 1.1 1999/02/02 01:54:54 semen Exp $
|
||||
*/
|
||||
#define VG_DONTLOAD 0x0001 /* Tells ntfs_vgetex to do not call */
|
||||
/* ntfs_loadnode on ntnode, even if */
|
||||
/* ntnode not loaded */
|
||||
|
||||
int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
|
||||
struct proc *, struct vnode **);
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ntfs_vnops.c,v 1.9 1999/02/02 01:54:55 semen Exp $
|
||||
* $Id: ntfs_vnops.c,v 1.10 1999/02/02 03:15:13 semen Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -66,11 +66,12 @@
|
||||
#include <ntfs/ntfs.h>
|
||||
#include <ntfs/ntfs_inode.h>
|
||||
#include <ntfs/ntfs_subr.h>
|
||||
#include <ntfs/ntfs_extern.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
|
||||
static int ntfs_bypass __P((struct vop_generic_args *ap));
|
||||
static int ntfs_read __P((struct vop_read_args *));
|
||||
static int ntfs_bwrite __P((struct vop_bwrite_args *ap));
|
||||
static int ntfs_write __P((struct vop_write_args *ap));
|
||||
static int ntfs_getattr __P((struct vop_getattr_args *ap));
|
||||
static int ntfs_inactive __P((struct vop_inactive_args *ap));
|
||||
static int ntfs_print __P((struct vop_print_args *ap));
|
||||
@ -88,120 +89,25 @@ static int ntfs_readdir __P((struct vop_readdir_args *ap));
|
||||
static int ntfs_lookup __P((struct vop_lookup_args *ap));
|
||||
static int ntfs_bmap __P((struct vop_bmap_args *ap));
|
||||
static int ntfs_getpages __P((struct vop_getpages_args *ap));
|
||||
static int ntfs_putpages __P((struct vop_putpages_args *));
|
||||
static int ntfs_fsync __P((struct vop_fsync_args *ap));
|
||||
|
||||
int ntfs_prtactive = 1; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
/*
|
||||
* Vnode op for VM getpages.
|
||||
*/
|
||||
int
|
||||
ntfs_getpages(ap)
|
||||
struct vop_getpages_args *ap;
|
||||
{
|
||||
int i, error, nextoff, size, toff, npages, count;
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
vm_offset_t kva;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
struct proc *p;
|
||||
struct ucred *cred;
|
||||
struct ntfsmount *ntmp;
|
||||
vm_page_t *pages;
|
||||
return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
|
||||
ap->a_reqpage);
|
||||
}
|
||||
|
||||
vp = ap->a_vp;
|
||||
p = curproc; /* XXX */
|
||||
cred = curproc->p_ucred; /* XXX */
|
||||
ntmp = VFSTONTFS(vp->v_mount);
|
||||
pages = ap->a_m;
|
||||
count = ap->a_count;
|
||||
|
||||
if (vp->v_object == NULL) {
|
||||
printf("ntfs_getpages: called with non-merged cache vnode??\n");
|
||||
return VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We use only the kva address for the buffer, but this is extremely
|
||||
* convienient and fast.
|
||||
*/
|
||||
#if __FreeBSD_version >= 400000
|
||||
bp = getpbuf(NULL);
|
||||
#else
|
||||
bp = getpbuf();
|
||||
#endif
|
||||
|
||||
npages = btoc(count);
|
||||
kva = (vm_offset_t) bp->b_data;
|
||||
pmap_qenter(kva, pages, npages);
|
||||
|
||||
iov.iov_base = (caddr_t) kva;
|
||||
iov.iov_len = count;
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
|
||||
uio.uio_resid = count;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_rw = UIO_READ;
|
||||
uio.uio_procp = p;
|
||||
|
||||
error = VOP_READ(vp, &uio, 0, cred);
|
||||
pmap_qremove(kva, npages);
|
||||
|
||||
#if __FreeBSD_version >= 400000
|
||||
relpbuf(bp,NULL);
|
||||
#else
|
||||
relpbuf(bp);
|
||||
#endif
|
||||
|
||||
if (error && (uio.uio_resid == count))
|
||||
return VM_PAGER_ERROR;
|
||||
|
||||
size = count - uio.uio_resid;
|
||||
|
||||
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
|
||||
vm_page_t m;
|
||||
nextoff = toff + PAGE_SIZE;
|
||||
m = pages[i];
|
||||
|
||||
m->flags &= ~PG_ZERO;
|
||||
|
||||
if (nextoff <= size) {
|
||||
m->valid = VM_PAGE_BITS_ALL;
|
||||
m->dirty = 0;
|
||||
} else {
|
||||
int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1);
|
||||
vm_page_set_validclean(m, 0, nvalid);
|
||||
}
|
||||
|
||||
if (i != ap->a_reqpage) {
|
||||
/*
|
||||
* Whether or not to leave the page activated is up in
|
||||
* the air, but we should put the page on a page queue
|
||||
* somewhere (it already is in the object). Result:
|
||||
* It appears that emperical results show that
|
||||
* deactivating pages is best.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Just in case someone was asking for this page we
|
||||
* now tell them that it is ok to use.
|
||||
*/
|
||||
if (!error) {
|
||||
if (m->flags & PG_WANTED)
|
||||
vm_page_activate(m);
|
||||
else
|
||||
vm_page_deactivate(m);
|
||||
#if __FreeBSD_version >= 300000
|
||||
vm_page_wakeup(m);
|
||||
#endif
|
||||
} else {
|
||||
vnode_pager_freepage(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
int
|
||||
ntfs_putpages(ap)
|
||||
struct vop_putpages_args *ap;
|
||||
{
|
||||
return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
|
||||
ap->a_sync, ap->a_rtvals);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -218,6 +124,7 @@ ntfs_bmap(ap)
|
||||
int *a_runb;
|
||||
} */ *ap;
|
||||
{
|
||||
dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn));
|
||||
if (ap->a_vpp != NULL)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
@ -239,7 +146,8 @@ ntfs_read(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int8_t *data;
|
||||
@ -248,7 +156,7 @@ ntfs_read(ap)
|
||||
|
||||
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));
|
||||
|
||||
ntfs_filesize( ntmp, ip, &toread, NULL );
|
||||
ntfs_filesize(ntmp, fp, &toread, NULL);
|
||||
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
|
||||
|
||||
toread = min( uio->uio_resid, toread - uio->uio_offset );
|
||||
@ -257,16 +165,17 @@ ntfs_read(ap)
|
||||
|
||||
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
|
||||
|
||||
error = ntfs_breadattr( ntmp, ip, ip->i_defattr, ip->i_defattrname,
|
||||
uio->uio_offset, toread, data );
|
||||
error = ntfs_readattr( ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, uio->uio_offset, toread, data);
|
||||
if(error) {
|
||||
printf("ntfs_read: ntfs_breadattr failed: %d\n",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);
|
||||
}
|
||||
@ -284,7 +193,7 @@ ntfs_bypass(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
int error = ENOTTY;
|
||||
dprintf (("ntfs_bypass: %s\n", ap->a_desc->vdesc_name));
|
||||
dprintf(("ntfs_bypass: %s\n", ap->a_desc->vdesc_name));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -299,33 +208,28 @@ ntfs_getattr(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
register struct vattr *vap = ap->a_vap;
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_getattr: %d, flags: %d\n",ip->i_number,ip->i_flag));
|
||||
|
||||
if ((ip->i_flag & (IN_LOADED | IN_PRELOADED)) == 0) {
|
||||
error = ntfs_loadnode(ip->i_mp,ip);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
vap->va_fsid = ip->i_dev;
|
||||
vap->va_fsid = fp->f_dev;
|
||||
vap->va_fileid = ip->i_number;
|
||||
vap->va_mode = ip->i_mode;
|
||||
vap->va_nlink = ip->i_nlink;
|
||||
vap->va_uid = ip->i_uid;
|
||||
vap->va_gid = ip->i_gid;
|
||||
vap->va_rdev = (dev_t)0;
|
||||
vap->va_size = ip->i_size;
|
||||
vap->va_bytes = ip->i_allocated;
|
||||
vap->va_atime = ntfs_nttimetounix(ip->i_times.t_access);
|
||||
vap->va_mtime = ntfs_nttimetounix(ip->i_times.t_write);
|
||||
vap->va_ctime = ntfs_nttimetounix(ip->i_times.t_create);
|
||||
vap->va_size = fp->f_size;
|
||||
vap->va_bytes = fp->f_allocated;
|
||||
vap->va_atime = ntfs_nttimetounix(fp->f_times.t_access);
|
||||
vap->va_mtime = ntfs_nttimetounix(fp->f_times.t_write);
|
||||
vap->va_ctime = ntfs_nttimetounix(fp->f_times.t_create);
|
||||
vap->va_flags = ip->i_flag;
|
||||
vap->va_gen = 0;
|
||||
vap->va_blocksize = ip->i_mp->ntm_spc * ip->i_mp->ntm_bps;
|
||||
vap->va_type = ip->i_type;
|
||||
vap->va_type = fp->f_type;
|
||||
vap->va_filerev = 0;
|
||||
return (0);
|
||||
}
|
||||
@ -346,8 +250,7 @@ ntfs_inactive(ap)
|
||||
#endif
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_inactive: %d (%d locks)\n",
|
||||
ip->i_number,ip->i_lockcount));
|
||||
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);
|
||||
@ -391,34 +294,25 @@ ntfs_reclaim(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
#if NTFS_DEBUG
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
#endif
|
||||
|
||||
dprintf(("ntfs_reclaim: reclaim: %d\n",ip->i_number));
|
||||
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
VOP_UNLOCK(vp,0,ap->a_p);
|
||||
#endif
|
||||
|
||||
if(ip->i_dirblbuf) {
|
||||
FREE(ip->i_dirblbuf, M_NTFSDIR);
|
||||
ip->i_dirblbuf = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
ntfs_ihashrem(ip);
|
||||
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
/* Purge old data structures associated with the inode. */
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
if (fp->f_devvp) {
|
||||
vrele(fp->f_devvp);
|
||||
fp->f_devvp = NULL;
|
||||
}
|
||||
|
||||
ntfs_ntrele(ip);
|
||||
ntfs_frele(fp);
|
||||
|
||||
vp->v_data = NULL;
|
||||
|
||||
@ -447,47 +341,126 @@ ntfs_strategy(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct buf *bp = ap->a_bp;
|
||||
struct ucred *cr;
|
||||
struct proc *p;
|
||||
int error = 0;
|
||||
register struct vnode *vp = bp->b_vp;
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
int error;
|
||||
|
||||
dprintf(("strategy: data: %p, npages: %d,dirty: %d\n",bp->b_data,bp->b_npages,bp->b_dirtyend));
|
||||
if (bp->b_flags & B_PHYS)
|
||||
panic("ntfs physio");
|
||||
if (bp->b_flags & B_ASYNC)
|
||||
p = (struct proc *)0;
|
||||
else
|
||||
p = curproc; /* XXX */
|
||||
if (bp->b_flags & B_READ)
|
||||
cr = bp->b_rcred;
|
||||
else
|
||||
cr = bp->b_wcred;
|
||||
/*
|
||||
* If the op is asynchronous and an i/o daemon is waiting
|
||||
* queue the request, wake it up and wait for completion
|
||||
* otherwise just do it ourselves.
|
||||
*/
|
||||
/*
|
||||
if ((bp->b_flags & B_ASYNC) == 0 ||
|
||||
nfs_asyncio(bp, NOCRED))
|
||||
error = nfs_doio(bp, cr, p);
|
||||
*/
|
||||
dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
|
||||
(u_int32_t)bp->b_offset,(u_int32_t)bp->b_blkno,
|
||||
(u_int32_t)bp->b_lblkno));
|
||||
dprintf(("strategy: bcount: %d flags: 0x%x\n",
|
||||
(u_int32_t)bp->b_bcount,bp->b_flags));
|
||||
|
||||
return (ENOTTY);
|
||||
if (bp->b_flags & B_READ) {
|
||||
u_int32_t toread;
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
|
||||
clrbuf(bp);
|
||||
error = 0;
|
||||
} else {
|
||||
toread = min(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
|
||||
toread,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),
|
||||
toread, bp->b_data);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_readattr failed\n");
|
||||
bp->b_error = error;
|
||||
bp->b_flags |= B_ERROR;
|
||||
}
|
||||
|
||||
bzero(bp->b_data + toread, bp->b_bcount - toread);
|
||||
}
|
||||
} else {
|
||||
size_t tmp;
|
||||
u_int32_t towrite;
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) {
|
||||
printf("ntfs_strategy: CAN'T EXTEND FILE\n");
|
||||
bp->b_error = error = EFBIG;
|
||||
bp->b_flags |= B_ERROR;
|
||||
} else {
|
||||
towrite = min(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n",
|
||||
towrite,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
|
||||
bp->b_data, &tmp);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_writeattr fail\n");
|
||||
bp->b_error = error;
|
||||
bp->b_flags |= B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
biodone(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_bwrite(ap)
|
||||
struct vop_bwrite_args /* {
|
||||
struct buf *a_bp;
|
||||
ntfs_write(ap)
|
||||
struct vop_write_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
int error = ENOTTY;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int8_t *data;
|
||||
u_int64_t towrite;
|
||||
off_t off;
|
||||
size_t written;
|
||||
int error;
|
||||
|
||||
printf("ntfs_bwrite: \n");
|
||||
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));
|
||||
|
||||
return (error);
|
||||
ntfs_filesize(ntmp, fp, &towrite, NULL);
|
||||
|
||||
if (uio->uio_resid + uio->uio_offset > towrite) {
|
||||
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
|
||||
return (EFBIG);
|
||||
}
|
||||
|
||||
dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
|
||||
|
||||
towrite = min(uio->uio_resid, towrite - uio->uio_offset);
|
||||
off = 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);
|
||||
}
|
||||
|
||||
FREE(data, M_TEMP);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 300000
|
||||
@ -502,7 +475,7 @@ ntfs_islocked(ap)
|
||||
{
|
||||
register struct ntnode *ip = VTONT(ap->a_vp);
|
||||
|
||||
dprintf(("ntfs_islocked %d (%d locks)\n",ip->i_number,ip->i_lockcount));
|
||||
dprintf(("ntfs_islocked %d\n",ip->i_number));
|
||||
|
||||
if (ip->i_flag & IN_LOCKED)
|
||||
return (1);
|
||||
@ -522,7 +495,7 @@ ntfs_unlock(ap)
|
||||
register struct ntnode *ip = VTONT(ap->a_vp);
|
||||
struct proc *p = curproc;
|
||||
|
||||
dprintf(("ntfs_unlock %d (%d locks)\n",ip->i_number,ip->i_lockcount));
|
||||
dprintf(("ntfs_unlock %d\n",ip->i_number));
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
|
||||
@ -639,7 +612,7 @@ ntfs_access(ap)
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
switch ((int)vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
@ -717,7 +690,7 @@ ntfs_open(ap)
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
|
||||
printf("ntfs_open: %d (%d locks)\n",ip->i_number,ip->i_lockcount);
|
||||
printf("ntfs_open: %d\n",ip->i_number);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -746,7 +719,7 @@ ntfs_close(ap)
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
|
||||
printf("ntfs_close: %d (%d locks)\n",ip->i_number,ip->i_lockcount);
|
||||
printf("ntfs_close: %d\n",ip->i_number);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
@ -767,7 +740,8 @@ ntfs_readdir(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct ntnode *ip = VTONT(vp);
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
int i, error = 0;
|
||||
@ -813,7 +787,7 @@ ntfs_readdir(ap)
|
||||
while( uio->uio_resid >= sizeof(struct dirent) ) {
|
||||
struct attr_indexentry *iep;
|
||||
|
||||
error = ntfs_ntreaddir(ntmp, ip, num, &iep);
|
||||
error = ntfs_ntreaddir(ntmp, fp, num, &iep);
|
||||
|
||||
if(error)
|
||||
return (error);
|
||||
@ -919,7 +893,7 @@ ntfs_lookup(ap)
|
||||
cnp->cn_nameptr, cnp->cn_namelen,
|
||||
dip->i_number,lockparent, wantparent));
|
||||
|
||||
error = VOP_ACCESS(dvp,VEXEC, cred, cnp->cn_proc);
|
||||
error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_proc);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
@ -974,39 +948,12 @@ ntfs_lookup(ap)
|
||||
}
|
||||
return (error);
|
||||
} else {
|
||||
struct ntnode * nip;
|
||||
|
||||
error = ntfs_ntlookup(ntmp, dip, cnp, &nip);
|
||||
error = ntfs_ntlookup(ntmp, dvp, cnp, ap->a_vpp);
|
||||
if(error)
|
||||
return (error);
|
||||
|
||||
dprintf(("ntfs_lookup: found ino: %d\n", nip->i_number));
|
||||
if( nip->i_number == dip->i_number ) {
|
||||
ntfs_ntrele(nip);
|
||||
VREF(dvp);
|
||||
*ap->a_vpp = dvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
*ap->a_vpp = ntfs_ihashget(ntmp->ntm_dev, nip->i_number);
|
||||
if(*ap->a_vpp == NULL) {
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp,
|
||||
ntfs_vnodeop_p, ap->a_vpp);
|
||||
if(error) {
|
||||
ntfs_ntrele(nip);
|
||||
return (error);
|
||||
}
|
||||
nip->i_vnode = *(ap->a_vpp);
|
||||
(*ap->a_vpp)->v_data = nip;
|
||||
(*ap->a_vpp)->v_type = nip->i_type;
|
||||
|
||||
ntfs_ihashins(nip);
|
||||
|
||||
VREF(nip->i_devvp);
|
||||
} else {
|
||||
printf("found in cache\n");
|
||||
ntfs_ntrele(nip);
|
||||
}
|
||||
dprintf(("ntfs_lookup: found ino: %d\n",
|
||||
VTONT(*ap->a_vpp)->i_number));
|
||||
|
||||
if(!lockparent || !(cnp->cn_flags & ISLASTCN))
|
||||
#if __FreeBSD_version >= 300000
|
||||
@ -1070,10 +1017,12 @@ static struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {
|
||||
|
||||
{ &vop_bmap_desc, (vop_t *)ntfs_bmap },
|
||||
{ &vop_getpages_desc, (vop_t *)ntfs_getpages },
|
||||
{ &vop_putpages_desc, (vop_t *) ntfs_putpages },
|
||||
|
||||
{ &vop_strategy_desc, (vop_t *)ntfs_strategy },
|
||||
{ &vop_bwrite_desc, (vop_t *)ntfs_bwrite },
|
||||
{ &vop_bwrite_desc, (vop_t *)vop_stdbwrite },
|
||||
{ &vop_read_desc, (vop_t *)ntfs_read },
|
||||
{ &vop_write_desc, (vop_t *)ntfs_write },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user