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:
semenu 1999-02-19 12:31:02 +00:00
parent eb7abf9254
commit 05d36e7aea
23 changed files with 1798 additions and 1152 deletions

View File

@ -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 *));

View File

@ -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;

View File

@ -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 *);

View File

@ -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
View 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 *));

View File

@ -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

View File

@ -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 *);

View File

@ -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
View 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 **);

View File

@ -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 }
};

View File

@ -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 *));

View File

@ -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;

View File

@ -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 *);

View File

@ -27,3 +27,5 @@
*/
struct sockaddr;
int ntfs_fget(struct ntfsmount *, struct ntnode *, int, char *, struct fnode **);
void ntfs_frele(struct fnode *);

View File

@ -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
View 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 *));

View File

@ -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

View File

@ -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 *);

View File

@ -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
View 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 **);

View File

@ -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 }
};