summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>1999-04-20 21:06:44 +0000
committersemenu <semenu@FreeBSD.org>1999-04-20 21:06:44 +0000
commit42e01703dca788bba764956ba12647f3dcdd7ec9 (patch)
tree94575bff8659b4709ed4f7205ce68df7fce0790e
parentc8cbbb76c7dbcc506d7786d8a80159d227b2cf4c (diff)
downloadFreeBSD-src-42e01703dca788bba764956ba12647f3dcdd7ec9.zip
FreeBSD-src-42e01703dca788bba764956ba12647f3dcdd7ec9.tar.gz
Removed annoying messaged during boot,added some check
before mounting (should help to do not mount extended partitions:-). Fixed problem with hanging while unmounting busy fs. And (the most important) added some locks to prevent simulaneous access to kernel structures!
-rw-r--r--sys/fs/ntfs/ntfs.h5
-rw-r--r--sys/fs/ntfs/ntfs_inode.h11
-rw-r--r--sys/fs/ntfs/ntfs_subr.c318
-rw-r--r--sys/fs/ntfs/ntfs_subr.h16
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c225
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.h6
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c30
-rw-r--r--sys/ntfs/ntfs.h5
-rw-r--r--sys/ntfs/ntfs_inode.h11
-rw-r--r--sys/ntfs/ntfs_subr.c318
-rw-r--r--sys/ntfs/ntfs_subr.h16
-rw-r--r--sys/ntfs/ntfs_vfsops.c225
-rw-r--r--sys/ntfs/ntfs_vfsops.h6
-rw-r--r--sys/ntfs/ntfs_vnops.c30
14 files changed, 868 insertions, 354 deletions
diff --git a/sys/fs/ntfs/ntfs.h b/sys/fs/ntfs/ntfs.h
index e2bda5e..e9fa1b3 100644
--- a/sys/fs/ntfs/ntfs.h
+++ b/sys/fs/ntfs/ntfs.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ntfs.h,v 1.2 1999/02/19 12:31:02 semenu Exp $
+ * $Id: ntfs.h,v 1.9 1999/02/02 01:54:54 semen Exp $
*/
/*#define NTFS_DEBUG 1*/
@@ -213,6 +213,8 @@ struct ntvattrdef {
u_int32_t ad_type;
};
+#define NTFS_BBID "NTFS "
+#define NTFS_BBIDLEN 8
struct bootfile {
u_int8_t reserved1[3]; /* asm jmp near ... */
u_int8_t bf_sysid[8]; /* 'NTFS ' */
@@ -246,6 +248,7 @@ struct ntfsmount {
gid_t ntm_gid;
mode_t ntm_mode;
u_long ntm_flag;
+ cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
int ntm_adnum;
};
diff --git a/sys/fs/ntfs/ntfs_inode.h b/sys/fs/ntfs/ntfs_inode.h
index 2e6fb78..bf1e26c 100644
--- a/sys/fs/ntfs/ntfs_inode.h
+++ b/sys/fs/ntfs/ntfs_inode.h
@@ -55,17 +55,18 @@
#define IN_PRELOADED 0x4000 /* loaded from directory entry */
struct ntnode {
- LIST_ENTRY(ntnode) i_hash;
+ LIST_ENTRY(ntnode) i_hash;
struct ntnode *i_next;
struct ntnode **i_prev;
- struct ntfsmount *i_mp;
+ struct ntfsmount *i_mp;
ino_t i_number;
dev_t i_dev;
u_int32_t i_flag;
+ int i_lock;
int i_usecount;
- LIST_HEAD(,fnode) i_fnlist;
- struct ntvattr *i_vattrp; /* ntvattrs list */
+ LIST_HEAD(,fnode) i_fnlist;
+ LIST_HEAD(,ntvattr) i_valist;
long i_nlink; /* MFR */
ino_t i_mainrec; /* MFR */
@@ -77,7 +78,7 @@ struct ntnode {
};
#define FN_PRELOADED 0x0001
-#define FN_DEFAULT 0x0002
+#define FN_VALID 0x0002
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
struct fnode {
struct lock f_lock; /* Must be first */
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
index 901ea69..cecc00a 100644
--- a/sys/fs/ntfs/ntfs_subr.c
+++ b/sys/fs/ntfs/ntfs_subr.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
+ * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,9 @@ MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage");
MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary");
#endif
+/*
+ *
+ */
int
ntfs_ntvattrrele(
struct ntvattr * vap)
@@ -70,6 +73,13 @@ ntfs_ntvattrrele(
return (0);
}
+/*
+ * Search attribute specifed in ntnode (load ntnode if nessecary).
+ * If not found but ATTR_A_ATTRLIST present, read it in and search throught.
+ * VOP_VGET node needed, and lookup througth it's ntnode (load if nessesary).
+ *
+ * ntnode should be locked
+ */
int
ntfs_ntvattrget(
struct ntfsmount * ntmp,
@@ -113,7 +123,7 @@ ntfs_ntvattrget(
}
}
- for (vap = ip->i_vattrp; vap; vap = vap->va_nextp) {
+ for (vap = ip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
ddprintf(("type: 0x%x, vcn: %d - %d\n", \
vap->va_type, (u_int32_t) vap->va_vcnstart, \
(u_int32_t) vap->va_vcnend));
@@ -171,14 +181,20 @@ ntfs_ntvattrget(
dprintf(("ntfs_ntvattrget: attrbute in ino: %d\n",
aalp->al_inumber));
+/*
error = VFS_VGET(ntmp->ntm_mountp, aalp->al_inumber,
&newvp);
+*/
+ error = ntfs_vgetex(ntmp->ntm_mountp, aalp->al_inumber,
+ NTFS_A_DATA, NULL, LK_EXCLUSIVE,
+ VG_EXT, curproc, &newvp);
if (error) {
printf("ntfs_ntvattrget: CAN'T VGET INO: %d\n",
aalp->al_inumber);
goto out;
}
newip = VTONT(newvp);
+ /* XXX have to lock ntnode */
if(~newip->i_flag & IN_LOADED) {
dprintf(("ntfs_ntvattrget: node not loaded," \
" ino: %d\n", newip->i_number));
@@ -190,7 +206,7 @@ ntfs_ntvattrget(
goto out;
}
}
- for (vap = newip->i_vattrp; vap; vap = vap->va_nextp) {
+ for (vap = newip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
if ((vap->va_type == type) &&
(vap->va_vcnstart <= vcn) &&
(vap->va_vcnend >= vcn) &&
@@ -219,10 +235,14 @@ ntfs_ntvattrget(
ip->i_number, type, name, (u_int32_t) vcn));
out:
FREE(alpool, M_TEMP);
-
return (error);
}
+/*
+ * Read ntnode from disk, make ntvattr list.
+ *
+ * ntnode should be locked
+ */
int
ntfs_loadntnode(
struct ntfsmount * ntmp,
@@ -232,7 +252,7 @@ ntfs_loadntnode(
daddr_t bn;
int error,off;
struct attr *ap;
- struct ntvattr**vapp;
+ struct ntvattr *nvap;
dprintf(("ntfs_loadnode: loading ino: %d\n",ip->i_number));
@@ -269,6 +289,7 @@ ntfs_loadntnode(
goto out;
}
}
+
/* Check if magic and fixups are correct */
error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp,
ntfs_bntob(ntmp->ntm_bpmftrec));
@@ -281,16 +302,16 @@ ntfs_loadntnode(
dprintf(("ntfs_loadnode: load attrs for ino: %d\n",ip->i_number));
off = mfrp->fr_attroff;
ap = (struct attr *) ((caddr_t)mfrp + off);
- if (ip->i_vattrp)
- printf("ntfs_ntloadnode: WARNING! already loaded?\n");
+
+ LIST_INIT(&ip->i_valist);
- vapp = &ip->i_vattrp;
while (ap->a_hdr.a_type != -1) {
- error = ntfs_attrtontvattr(ntmp, vapp, ap);
+ error = ntfs_attrtontvattr(ntmp, &nvap, ap);
if (error)
break;
- (*vapp)->va_ip = ip;
- vapp = &((*vapp)->va_nextp);
+ nvap->va_ip = ip;
+
+ LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list);
off += ap->a_hdr.reclen;
ap = (struct attr *) ((caddr_t)mfrp + off);
@@ -312,44 +333,74 @@ out:
return (error);
}
+/*
+ * Routine locks ntnode and increase usecount, just opposite of
+ * ntfs_ntput.
+ */
+int
+ntfs_ntget(
+ struct ntnode *ip)
+{
+ dprintf(("ntfs_ntget: get ntnode %d: %p, usecount: %d\n",
+ ip->i_number, ip, ip->i_usecount));
+
+ ip->i_usecount++;
+
+restart:
+ if (ip->i_lock) {
+ while (ip->i_lock) {
+ ip->i_lock = -1;
+ tsleep(&ip->i_lock, PVM, "ntnode", 0);
+ }
+ goto restart;
+ }
+ ip->i_lock = 1;
+
+ return 0;
+}
+/*
+ * Routine search ntnode in hash, if found: lock, inc usecount and return.
+ * If not in hash allocate structure for ntnode, prefill it, lock,
+ * inc count and return.
+ *
+ * ntnode returned locked
+ */
static int ntfs_ntnode_hash_lock;
int
-ntfs_ntget(
+ntfs_ntlookup(
struct ntfsmount * ntmp,
ino_t ino,
struct ntnode ** ipp)
{
struct ntnode *ip;
- dprintf(("ntfs_ntget: ntget ntnode %d\n", ino));
+ dprintf(("ntfs_ntlookup: for ntnode %d\n", ino));
*ipp = NULL;
restart:
- ip = ntfs_nthashlookup(ntmp->ntm_dev, ino);
+ ip = ntfs_nthashlookup(ntmp->ntm_dev, ino); /* XXX */
if (ip) {
- ip->i_usecount++;
+ ntfs_ntget(ip);
*ipp = ip;
- dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
+ dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
ino, ip, ip->i_usecount));
return (0);
}
if (ntfs_ntnode_hash_lock) {
- printf("waiting for hash_lock to free...\n");
while(ntfs_ntnode_hash_lock) {
ntfs_ntnode_hash_lock = -1;
tsleep(&ntfs_ntnode_hash_lock, PVM, "ntfsntgt", 0);
}
- printf("hash_lock freeed\n");
goto restart;
}
ntfs_ntnode_hash_lock = 1;
MALLOC(ip, struct ntnode *, sizeof(struct ntnode),
M_NTFSNTNODE, M_WAITOK);
- ddprintf(("ntfs_ntget: allocating ntnode: %d: %p\n", ino, ip));
+ ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip));
bzero((caddr_t) ip, sizeof(struct ntnode));
/* Generic initialization */
@@ -361,6 +412,8 @@ restart:
ip->i_mode = ntmp->ntm_mode;
ip->i_usecount++;
+ ip->i_lock = 1;
+
LIST_INIT(&ip->i_fnlist);
ntfs_nthashins(ip);
@@ -371,45 +424,77 @@ restart:
*ipp = ip;
- dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
+ dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
ino, ip, ip->i_usecount));
return (0);
}
+/*
+ * Decrement usecount of ntnode and unlock it, if usecount reach zero,
+ * deallocate ntnode.
+ *
+ * ntnode should be locked on entry, and unlocked on return.
+ */
void
-ntfs_ntrele(
- struct ntnode * ip)
+ntfs_ntput(
+ struct ntnode *ip)
{
struct ntvattr *vap;
- dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
+ if (!ip->i_lock) printf("ntfs_ntput: NOT LOCKED");
+
+ dprintf(("ntfs_ntput: rele ntnode %d: %p, usecount: %d\n",
ip->i_number, ip, ip->i_usecount));
ip->i_usecount--;
if (ip->i_usecount < 0) {
- panic("ntfs_ntrele: ino: %d usecount: %d \n",
+ panic("ntfs_ntput: ino: %d usecount: %d \n",
ip->i_number,ip->i_usecount);
} else if (ip->i_usecount == 0) {
- dprintf(("ntfs_ntrele: deallocating ntnode: %d\n",
+ dprintf(("ntfs_ntput: deallocating ntnode: %d\n",
ip->i_number));
if (ip->i_fnlist.lh_first)
- panic("ntfs_ntrele: ntnode has fnodes\n");
+ panic("ntfs_ntput: ntnode has fnodes\n");
ntfs_nthashrem(ip);
- while (ip->i_vattrp) {
- vap = ip->i_vattrp;
- ip->i_vattrp = vap->va_nextp;
+ while (ip->i_valist.lh_first != NULL) {
+ vap = ip->i_valist.lh_first;
+ LIST_REMOVE(vap,va_list);
ntfs_freentvattr(vap);
}
FREE(ip, M_NTFSNTNODE);
+ } else {
+ if (ip->i_lock < 0)
+ wakeup(&ip->i_lock);
+ ip->i_lock = 0;
}
- dprintf(("ntfs_ntrele: rele ok\n"));
}
+/*
+ * Decrement usecount of ntnode.
+ */
+void
+ntfs_ntrele(
+ struct ntnode * ip)
+{
+ dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
+ ip->i_number, ip, ip->i_usecount));
+
+ ip->i_usecount--;
+
+ if (ip->i_usecount < 0)
+ panic("ntfs_ntrele: ino: %d usecount: %d \n",
+ ip->i_number,ip->i_usecount);
+}
+
+/*
+ * Deallocate all memory allocated for ntvattr by call to
+ * ntfs_attrtontvattr and some other functions.
+ */
void
ntfs_freentvattr(
struct ntvattr * vap)
@@ -426,6 +511,10 @@ ntfs_freentvattr(
FREE(vap, M_NTFSNTVATTR);
}
+/*
+ * Convert disk image of attribute into ntvattr structure,
+ * runs are expanded also.
+ */
int
ntfs_attrtontvattr(
struct ntfsmount * ntmp,
@@ -493,6 +582,9 @@ ntfs_attrtontvattr(
return (error);
}
+/*
+ * Expand run into more utilizable and more memory eating format.
+ */
int
ntfs_runtovrun(
cn_t ** rcnp,
@@ -552,7 +644,9 @@ ntfs_runtovrun(
return (0);
}
-
+/*
+ * Convert wchar to uppercase wchar, should be macros?
+ */
wchar
ntfs_toupper(
struct ntfsmount * ntmp,
@@ -561,6 +655,9 @@ ntfs_toupper(
return (ntmp->ntm_upcase[wc & 0xFF]);
}
+/*
+ * Compare to unicode strings case insensible.
+ */
int
ntfs_uustricmp(
struct ntfsmount * ntmp,
@@ -581,6 +678,9 @@ ntfs_uustricmp(
return (str1len - str2len);
}
+/*
+ * Compare unicode and ascii string case insens.
+ */
int
ntfs_uastricmp(
struct ntfsmount * ntmp,
@@ -601,6 +701,9 @@ ntfs_uastricmp(
return (str1len - str2len);
}
+/*
+ * Compare unicode and ascii string case sens.
+ */
int
ntfs_uastrcmp(
struct ntfsmount * ntmp,
@@ -620,6 +723,11 @@ ntfs_uastrcmp(
return (str1len - str2len);
}
+/*
+ * Search fnode in ntnode, if not found allocate and preinitialize.
+ *
+ * ntnode should be locked on entry.
+ */
int
ntfs_fget(
struct ntfsmount *ntmp,
@@ -628,7 +736,6 @@ ntfs_fget(
char *attrname,
struct fnode **fpp)
{
- int error;
struct fnode *fp;
dprintf(("ntfs_fget: ino: %d, attrtype: 0x%x, attrname: %s\n",
@@ -662,15 +769,6 @@ ntfs_fget(
fp->f_attrname = attrname;
if (fp->f_attrname) fp->f_flag |= FN_AATTRNAME;
fp->f_attrtype = attrtype;
- if ((fp->f_attrtype == NTFS_A_DATA) && (fp->f_attrname == NULL))
- fp->f_flag |= FN_DEFAULT;
- else {
- error = ntfs_filesize(ntmp, fp, &fp->f_size, &fp->f_allocated);
- if (error) {
- FREE(fp,M_NTFSFNODE);
- return (error);
- }
- }
ntfs_ntref(ip);
@@ -681,6 +779,11 @@ ntfs_fget(
return (0);
}
+/*
+ * Deallocate fnode, remove it from ntnode's fnode list.
+ *
+ * ntnode should be locked.
+ */
void
ntfs_frele(
struct fnode *fp)
@@ -699,6 +802,11 @@ ntfs_frele(
ntfs_ntrele(ip);
}
+/*
+ * Lookup attribute name in format: [[:$ATTR_TYPE]:$ATTR_NAME],
+ * $ATTR_TYPE is searched in attrdefs read from $AttrDefs.
+ * If $ATTR_TYPE nott specifed, ATTR_A_DATA assumed.
+ */
int
ntfs_ntlookupattr(
struct ntfsmount * ntmp,
@@ -753,12 +861,13 @@ ntfs_ntlookupattr(
return (0);
}
+
/*
* Lookup specifed node for filename, matching cnp,
* return fnode filled.
*/
int
-ntfs_ntlookup(
+ntfs_ntlookupfile(
struct ntfsmount * ntmp,
struct vnode * vp,
struct componentname * cnp,
@@ -776,6 +885,10 @@ ntfs_ntlookup(
char *fname,*aname;
u_int32_t aoff;
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
if (error || (vap->va_flag & NTFS_AF_INRUN))
return (ENOTDIR);
@@ -783,6 +896,10 @@ ntfs_ntlookup(
blsize = vap->va_a_iroot->ir_size;
rdsize = vap->va_datalen;
+ /*
+ * Divide file name into: foofilefoofilefoofile[:attrspec]
+ * Store like this: fname:fnamelen [aname:anamelen]
+ */
fname = cnp->cn_nameptr;
aname = NULL;
anamelen = 0;
@@ -790,12 +907,12 @@ ntfs_ntlookup(
if(fname[fnamelen] == ':') {
aname = fname + fnamelen + 1;
anamelen = cnp->cn_namelen - fnamelen - 1;
- dprintf(("ntfs_ntlookup: file %s (%d), attr: %s (%d)\n",
+ dprintf(("ntfs_ntlookupfile: %s (%d), attr: %s (%d)\n",
fname, fnamelen, aname, anamelen));
break;
}
- dprintf(("ntfs_ntlookup: blocksize: %d, rdsize: %d\n", blsize, rdsize));
+ dprintf(("ntfs_ntlookupfile: blksz: %d, rdsz: %d\n", blsize, rdsize));
MALLOC(rdbuf, caddr_t, blsize, M_TEMP, M_WAITOK);
@@ -856,7 +973,8 @@ ntfs_ntlookup(
attrtype,
attrname,
LK_EXCLUSIVE,
- VG_DONTLOAD,
+ VG_DONTLOADIN |
+ VG_DONTVALIDFN,
curproc,
&nvp);
if(error)
@@ -864,6 +982,11 @@ ntfs_ntlookup(
nfp = VTOF(nvp);
+ if (nfp->f_flag & FN_VALID) {
+ *vpp = nvp;
+ goto fail;
+ }
+
nfp->f_fflag = iep->ie_fflag;
nfp->f_pnumber = iep->ie_fpnumber;
nfp->f_times = iep->ie_ftimes;
@@ -883,7 +1006,17 @@ ntfs_ntlookup(
nfp->f_size = iep->ie_fsize;
nfp->f_allocated = iep->ie_fallocated;
nfp->f_flag |= FN_PRELOADED;
+ } else {
+ error = ntfs_filesize(ntmp, nfp,
+ &nfp->f_size,
+ &nfp->f_allocated);
+ if (error) {
+ vput(nvp);
+ goto fail;
+ }
}
+
+ nfp->f_flag &= ~FN_VALID;
*vpp = nvp;
goto fail;
}
@@ -896,7 +1029,7 @@ ntfs_ntlookup(
/* Dive if possible */
if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
- dprintf(("ntfs_ntlookup: diving\n"));
+ dprintf(("ntfs_ntlookupfile: diving\n"));
cn = *(cn_t *) (rdbuf + aoff +
iep->reclen - sizeof(cn_t));
@@ -915,7 +1048,7 @@ ntfs_ntlookup(
aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize +
0x18);
} else {
- dprintf(("ntfs_ntlookup: nowhere to dive :-(\n"));
+ dprintf(("ntfs_ntlookupfile: nowhere to dive :-(\n"));
error = ENOENT;
break;
}
@@ -925,10 +1058,14 @@ ntfs_ntlookup(
fail:
ntfs_ntvattrrele(vap);
+ ntfs_ntput(ip);
FREE(rdbuf, M_TEMP);
return (error);
}
+/*
+ * Check if name type is permitted to show.
+ */
int
ntfs_isnamepermitted(
struct ntfsmount * ntmp,
@@ -942,9 +1079,7 @@ ntfs_isnamepermitted(
case 2:
ddprintf(("ntfs_isnamepermitted: skiped DOS name\n"));
return 0;
- case 0:
- case 1:
- case 3:
+ case 0: case 1: case 3:
return 1;
default:
printf("ntfs_isnamepermitted: " \
@@ -955,6 +1090,14 @@ ntfs_isnamepermitted(
return 0;
}
+/*
+ * Read ntfs dir like stream of attr_indexentry, not like btree of them.
+ * This is done by scaning $BITMAP:$I30 for busy clusters and reading them.
+ * Ofcouse $INDEX_ROOT:$I30 is read before. Last read values are stored in
+ * fnode, so we can skip toward record number num almost immediatly.
+ * Anyway this is rather slow routine. The problem is that we don't know
+ * how many records are there in $INDEX_ALLOCATION:$I30 block.
+ */
int
ntfs_ntreaddir(
struct ntfsmount * ntmp,
@@ -978,6 +1121,10 @@ ntfs_ntreaddir(
u_int32_t aoff, cnum;
dprintf(("ntfs_ntreaddir: read ino: %d, num: %d\n", ip->i_number, num));
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
if (error)
return (ENOTDIR);
@@ -1106,12 +1253,14 @@ fail:
ntfs_ntvattrrele(iavap);
if (bmp)
FREE(bmp, M_TEMP);
+ ntfs_ntput(ip);
return (error);
}
+
/*
- * #undef dprintf #define dprintf(a)
+ * Convert NTFS times that are in 100 ns units and begins from
+ * 1601 Jan 1 into unix times.
*/
-
struct timespec
ntfs_nttimetounix(
u_int64_t nt)
@@ -1126,6 +1275,9 @@ ntfs_nttimetounix(
return (t);
}
+/*
+ * Get file times from NTFS_A_NAME attribute.
+ */
int
ntfs_times(
struct ntfsmount * ntmp,
@@ -1136,15 +1288,28 @@ ntfs_times(
int error;
dprintf(("ntfs_times: ino: %d...\n", ip->i_number));
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
+
+ error = ntfs_ntget(ip);
if (error)
return (error);
+
+ error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
+ if (error) {
+ ntfs_ntput(ip);
+ return (error);
+ }
*tm = vap->va_a_name->n_times;
ntfs_ntvattrrele(vap);
+ ntfs_ntput(ip);
return (0);
}
+/*
+ * Get file sizes from corresponding attribute.
+ *
+ * ntnode under fnode should be locked.
+ */
int
ntfs_filesize(
struct ntfsmount * ntmp,
@@ -1158,15 +1323,12 @@ ntfs_filesize(
int error;
dprintf(("ntfs_filesize: ino: %d\n", ip->i_number));
- if (fp->f_flag & FN_DEFAULT) {
- error = ntfs_ntvattrget(ntmp, ip,
- NTFS_A_DATA, NULL, 0, &vap);
- } else {
- error = ntfs_ntvattrget(ntmp, ip,
- fp->f_attrtype, fp->f_attrname, 0, &vap);
- }
+
+ error = ntfs_ntvattrget(ntmp, ip,
+ fp->f_attrtype, fp->f_attrname, 0, &vap);
if (error)
return (error);
+
bn = vap->va_allocated;
sz = vap->va_datalen;
@@ -1183,6 +1345,11 @@ ntfs_filesize(
return (0);
}
+/*
+ * This is one of write routine.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_writeattr_plain(
struct ntfsmount * ntmp,
@@ -1234,6 +1401,11 @@ ntfs_writeattr_plain(
return (error);
}
+/*
+ * This is one of write routine.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_writentvattr_plain(
struct ntfsmount * ntmp,
@@ -1313,7 +1485,7 @@ ntfs_writentvattr_plain(
}
}
memcpy(bp->b_data + off, data, tocopy);
- bwrite(bp);
+ bawrite(bp);
data = data + tocopy;
*initp += tocopy;
off = 0;
@@ -1336,6 +1508,11 @@ ntfs_writentvattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readntvattr_plain(
struct ntfsmount * ntmp,
@@ -1379,7 +1556,7 @@ ntfs_readntvattr_plain(
cnt++;
continue;
}
- if (ccn || ip->i_number == NTFS_BOOTINO) { /* XXX */
+ if (ccn || ip->i_number == NTFS_BOOTINO) {
ccl -= ntfs_btocn(off);
cn = ccn + ntfs_btocn(off);
off = ntfs_btocnoff(off);
@@ -1442,6 +1619,11 @@ ntfs_readntvattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readattr_plain(
struct ntfsmount * ntmp,
@@ -1493,6 +1675,11 @@ ntfs_readattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readattr(
struct ntfsmount * ntmp,
@@ -1574,6 +1761,7 @@ ntfs_readattr(
return (error);
}
+#if UNUSED_CODE
int
ntfs_parserun(
cn_t * cn,
@@ -1616,7 +1804,11 @@ ntfs_parserun(
return (0);
}
+#endif
+/*
+ * Process fixup routine on given buffer.
+ */
int
ntfs_procfixups(
struct ntfsmount * ntmp,
@@ -1659,6 +1851,7 @@ ntfs_procfixups(
return (0);
}
+#if UNUSED_CODE
int
ntfs_runtocn(
cn_t * cn,
@@ -1701,3 +1894,4 @@ ntfs_runtocn(
*cn = ccn + vcn;
return (0);
}
+#endif
diff --git a/sys/fs/ntfs/ntfs_subr.h b/sys/fs/ntfs/ntfs_subr.h
index 692bb54..3cfc783 100644
--- a/sys/fs/ntfs/ntfs_subr.h
+++ b/sys/fs/ntfs/ntfs_subr.h
@@ -30,7 +30,7 @@
#define VA_PRELOADED 0x0002
struct ntvattr {
- struct ntvattr *va_nextp;
+ LIST_ENTRY(ntvattr) va_list;
u_int32_t va_vflag;
struct vnode *va_vp;
@@ -99,12 +99,14 @@ 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 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_ntlookupfile __P((struct ntfsmount *, struct vnode *, struct componentname *, struct vnode **));
+int ntfs_isnamepermitted __P((struct ntfsmount *, struct attr_indexentry * ));
+int ntfs_ntvattrrele __P((struct ntvattr * ));
+int ntfs_ntvattrget __P((struct ntfsmount *, struct ntnode *, u_int32_t, char *, cn_t , struct ntvattr **));
+int ntfs_ntlookup __P((struct ntfsmount *, ino_t, struct ntnode **));
+int ntfs_ntget __P((struct ntnode *));
+void ntfs_ntrele __P((struct ntnode *));
+void ntfs_ntput __P((struct ntnode *));
int ntfs_loadntnode __P(( struct ntfsmount *, struct ntnode * ));
int ntfs_ntlookupattr(struct ntfsmount *, char *, int, int *, char **);
int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *);
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
index a371319..7d1f91d 100644
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ b/sys/fs/ntfs/ntfs_vfsops.c
@@ -102,13 +102,6 @@ static int
ntfs_init ()
#endif
{
- static first=1;
-
- if(!first) return (0);
- first = 1;
-
- printf("ntfs_init(): \n");
-
ntfs_nthashinit();
return 0;
@@ -384,6 +377,12 @@ ntfs_mountfs(devvp, mp, argsp, p)
brelse( bp );
bp = NULL;
+ if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
+ error = EINVAL;
+ printf("ntfs_mountfs: invalid boot block\n");
+ goto out;
+ }
+
{
int8_t cpr = ntmp->ntm_mftrecsz;
if( cpr > 0 )
@@ -391,11 +390,11 @@ ntfs_mountfs(devvp, mp, argsp, p)
else
ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
}
- printf("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
+ dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
- ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec);
- printf("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
- (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn);
+ ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
+ dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
+ (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
ntmp->ntm_mountp = mp;
ntmp->ntm_dev = dev;
@@ -406,51 +405,64 @@ ntfs_mountfs(devvp, mp, argsp, p)
ntmp->ntm_flag = argsp->flag;
mp->mnt_data = (qaddr_t)ntmp;
- printf("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
+ dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
(ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
- ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode);
+ ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
- printf("ntfs_mountfs(): reading system nodes...\n");
+ /*
+ * We read in some system nodes to do not allow
+ * reclaim them and to have everytime access to them.
+ */
{
- i = NTFS_MFTINO;
- 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]);
- vput(ntmp->ntm_sysvn[i]);
+ int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
+ for (i=0; i<3; i++) {
+ error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
+ if(error)
+ goto out1;
+ ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
+ VREF(ntmp->ntm_sysvn[pi[i]]);
+ vput(ntmp->ntm_sysvn[pi[i]]);
+ }
}
- MALLOC( ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
+ /*
+ * Read in WHOLE lowcase -> upcase translation
+ * file.
+ */
+ MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
M_NTFSMNT, M_WAITOK);
- printf("ntfs_mountfs(): opening $UpCase\n");
- error = VFS_VGET(mp, NTFS_UPCASEINO, &vp );
+ error = VFS_VGET(mp, NTFS_UPCASEINO, &vp);
if(error)
goto out1;
- printf("ntfs_mountfs(): reading $UpCase\n");
- error = ntfs_readattr( 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);
if(error)
goto out1;
+ /*
+ * Scan $BitMap and count free clusters
+ */
+ error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
+ if(error)
+ goto out1;
+
+ /*
+ * Read and translate to internal format attribute
+ * definition file.
+ */
{
int num,j;
struct attrdef ad;
- printf("ntfs_mountfs(): opening $AttrDef\n");
+ /* Open $AttrDef */
error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp );
if(error)
goto out1;
+ /* Count valid entries */
for(num=0;;num++) {
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
@@ -461,14 +473,15 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (ad.ad_name[0] == 0)
break;
}
- printf("ntfs_mountfs(): reading %d attrdefs\n",num);
+ /* Alloc memory for attribute definitions */
MALLOC(ntmp->ntm_ad, struct ntvattrdef *,
num * sizeof(struct ntvattrdef),
M_NTFSMNT, M_WAITOK);
ntmp->ntm_adnum = num;
+ /* Read them and translate */
for(i=0;i<num;i++){
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
@@ -482,11 +495,8 @@ ntfs_mountfs(devvp, mp, argsp, p)
} while(ad.ad_name[j++]);
ntmp->ntm_ad[i].ad_namelen = j - 1;
ntmp->ntm_ad[i].ad_type = ad.ad_type;
- printf("ntfs_mountfs(): attribute: %s, type: 0x%x\n",
- ntmp->ntm_ad[i].ad_name,
- ntmp->ntm_ad[i].ad_type);
}
- printf("ntfs_mountfs(): closing $AttrDef\n");
+
vput(vp);
}
@@ -504,9 +514,14 @@ ntfs_mountfs(devvp, mp, argsp, p)
devvp->v_specflags |= SI_MOUNTEDON;
#endif
return (0);
+
out1:
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
+
+ if (vflush(mp,NULLVP,0))
+ printf("ntfs_mountfs: vflush failed\n");
+
out:
#if __FreeBSD_version >= 300000
devvp->v_specmountpoint = NULL;
@@ -525,7 +540,6 @@ ntfs_start (
int flags,
struct proc *p )
{
- printf("\nntfs_start():\n");
return (0);
}
@@ -538,24 +552,33 @@ ntfs_unmount(
register struct ntfsmount *ntmp;
int error, ronly = 0, flags, i;
- printf("ntfs_unmount: unmounting...\n");
+ dprintf(("ntfs_unmount: unmounting...\n"));
ntmp = VFSTONTFS(mp);
flags = 0;
if(mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- printf("ntfs_unmount: vflushing...\n");
+ dprintf(("ntfs_unmount: vflushing...\n"));
error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
if (error) {
printf("ntfs_unmount: vflush failed: %d\n",error);
return (error);
}
+
+ /* Check if only system vnodes are rest */
+ for(i=0;i<NTFS_SYSNODESNUM;i++)
+ if((ntmp->ntm_sysvn[i]) &&
+ (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
+
+ /* Derefernce all system vnodes */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
+
+ /* vflush system vnodes */
error = vflush(mp,NULLVP,flags);
if (error)
- printf("ntfs_unmount: vflush failed: %d\n",error);
+ printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
#if __FreeBSD_version >= 300000
ntmp->ntm_devvp->v_specmountpoint = NULL;
@@ -573,7 +596,7 @@ ntfs_unmount(
vrele(ntmp->ntm_devvp);
- printf("ntfs_umount: freeing memory...\n");
+ dprintf(("ntfs_umount: freeing memory...\n"));
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
FREE(ntmp->ntm_ad, M_NTFSMNT);
@@ -614,47 +637,55 @@ ntfs_quotactl (
return EOPNOTSUPP;
}
-static int
-ntfs_statfs(
- struct mount *mp,
- struct statfs *sbp,
- struct proc *p)
+int
+ntfs_calccfree(
+ struct ntfsmount *ntmp,
+ cn_t *cfreep)
{
- struct ntfsmount *ntmp = VFSTONTFS(mp);
- u_int64_t mftsize,mftallocated,bmsize,bmallocated;
struct vnode *vp;
- int error,j,i;
u_int8_t *tmp;
+ int j, error;
+ long cfree = 0;
+ size_t bmsize, i;
- dprintf(("ntfs_statfs():"));
-
- ntfs_filesize(ntmp, VTOF(ntmp->ntm_sysvn[NTFS_MFTINO]),
- &mftsize, &mftallocated);
-
- error = VFS_VGET(mp, NTFS_BITMAPINO, &vp);
- if(error)
- return (error);
+ vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
- ntfs_filesize(ntmp, VTOF(vp), &bmsize, &bmallocated);
+ bmsize = VTOF(vp)->f_size;
- MALLOC(tmp, u_int8_t *, bmsize,M_TEMP, M_WAITOK);
+ MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, bmsize, tmp);
if(error) {
FREE(tmp, M_TEMP);
- vput(vp);
return (error);
}
- vput(vp);
- sbp->f_bfree = 0;
for(i=0;i<bmsize;i++)
for(j=0;j<8;j++)
- if(~tmp[i] & (1 << j)) sbp->f_bfree++;
+ if(~tmp[i] & (1 << j)) cfree++;
FREE(tmp, M_TEMP);
+ *cfreep = cfree;
+
+ return(0);
+}
+
+static int
+ntfs_statfs(
+ struct mount *mp,
+ struct statfs *sbp,
+ struct proc *p)
+{
+ struct ntfsmount *ntmp = VFSTONTFS(mp);
+ u_int64_t mftsize,mftallocated;
+
+ dprintf(("ntfs_statfs():\n"));
+
+ mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size;
+ mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
+
#if __FreeBSD_version >= 300000
sbp->f_type = mp->mnt_vfc->vfc_typenum;
#else
@@ -663,7 +694,7 @@ ntfs_statfs(
sbp->f_bsize = ntmp->ntm_bps;
sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
- sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(sbp->f_bfree);
+ sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
sbp->f_ffree;
@@ -746,41 +777,63 @@ ntfs_vgetex(
*vpp = NULL;
/* Get ntnode */
- error = ntfs_ntget(ntmp, ino, &ip);
+ error = ntfs_ntlookup(ntmp, ino, &ip);
if (error) {
printf("ntfs_vget: ntfs_ntget failed\n");
return (error);
}
+ /* It may be not initialized fully, so force load it */
+ if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
+ error = ntfs_loadntnode(ntmp, ip);
+ if(error) {
+ printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
+ ip->i_number);
+ ntfs_ntput(ip);
+ return (error);
+ }
+ }
+
error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
if (error) {
printf("ntfs_vget: ntfs_fget failed\n");
- ntfs_ntrele(ip);
+ ntfs_ntput(ip);
return (error);
}
+ if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
+ if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
+ (fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) {
+ fp->f_type = VDIR;
+ } else if(flags & VG_EXT) {
+ fp->f_type = VNON;
+
+ fp->f_size =fp->f_allocated = 0;
+ } else {
+ fp->f_type = VREG;
+
+ error = ntfs_filesize(ntmp, fp,
+ &fp->f_size, &fp->f_allocated);
+ if (error) {
+ ntfs_ntput(ip);
+ return (error);
+ }
+ }
+
+ fp->f_flag |= FN_VALID;
+ }
+
if (FTOV(fp)) {
vget(FTOV(fp), lkflags, p);
*vpp = FTOV(fp);
- ntfs_ntrele(ip);
+ ntfs_ntput(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);
+ ntfs_ntput(ip);
return (error);
}
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
@@ -788,18 +841,12 @@ ntfs_vgetex(
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;
+ vp->v_type = fp->f_type;
if (ino == NTFS_ROOTINO)
vp->v_flag |= VROOT;
- if (ino < NTFS_SYSNODESNUM)
- vp->v_flag |= VSYSTEM;
- ntfs_ntrele(ip);
+ ntfs_ntput(ip);
if (lkflags & LK_TYPE_MASK) {
error = vn_lock(vp, lkflags, p);
diff --git a/sys/fs/ntfs/ntfs_vfsops.h b/sys/fs/ntfs/ntfs_vfsops.h
index c8788c4..af5ce9d 100644
--- a/sys/fs/ntfs/ntfs_vfsops.h
+++ b/sys/fs/ntfs/ntfs_vfsops.h
@@ -25,9 +25,13 @@
*
* $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 */
+#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */
/* ntfs_loadnode on ntnode, even if */
/* ntnode not loaded */
+#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */
+ /* fnode */
+#define VG_EXT 0x0004 /* This is not main record */
int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
struct proc *, struct vnode **);
+int ntfs_calccfree(struct ntfsmount *, cn_t *);
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
index f1a822a..d22ea5f 100644
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ b/sys/fs/ntfs/ntfs_vnops.c
@@ -156,7 +156,8 @@ 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, fp, &toread, NULL);
+ toread = fp->f_size;
+
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
toread = min( uio->uio_resid, toread - uio->uio_offset );
@@ -165,7 +166,7 @@ ntfs_read(ap)
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
- error = ntfs_readattr( ntmp, ip, fp->f_attrtype,
+ error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, uio->uio_offset, toread, data);
if(error) {
printf("ntfs_read: ntfs_readattr failed: %d\n",error);
@@ -245,9 +246,7 @@ ntfs_inactive(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
-#if defined(NTFS_DEBUG) || defined(DISGNOSTIC)
register struct ntnode *ip = VTONT(vp);
-#endif
int error;
dprintf(("ntfs_inactive: vnode: %p, ntnode: %d\n", vp, ip->i_number));
@@ -262,7 +261,7 @@ ntfs_inactive(ap)
#else
#ifdef DIAGNOSTIC
if (VOP_ISLOCKED(vp))
- panic("ntfs_inactive: locked ntnode");
+ panic("ntfs_inactive: locked vnode");
if (curproc)
ip->i_lockholder = curproc->p_pid;
else
@@ -275,7 +274,7 @@ ntfs_inactive(ap)
* If we are done with the ntnode, reclaim it
* so that it can be reused immediately.
*/
- if (vp->v_usecount == 0 /*&& ip->i_mode == 0*/)
+ if (vp->v_usecount == 0 && ip->i_mode == 0)
#if __FreeBSD_version >= 300000
vrecycle(vp, (struct simplelock *)0, ap->a_p);
#else
@@ -295,12 +294,15 @@ ntfs_reclaim(ap)
{
register struct vnode *vp = ap->a_vp;
register struct fnode *fp = VTOF(vp);
-#if NTFS_DEBUG
register struct ntnode *ip = FTONT(fp);
-#endif
+ int error;
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
#if __FreeBSD_version >= 300000
VOP_UNLOCK(vp,0,ap->a_p);
#endif
@@ -316,6 +318,8 @@ ntfs_reclaim(ap)
vp->v_data = NULL;
+ ntfs_ntput(ip);
+
return (0);
}
@@ -428,15 +432,15 @@ ntfs_write(ap)
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));
- ntfs_filesize(ntmp, fp, &towrite, NULL);
+ towrite = fp->f_size;
+
+ dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
if (uio->uio_resid + uio->uio_offset > towrite) {
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
return (EFBIG);
}
- dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
-
towrite = min(uio->uio_resid, towrite - uio->uio_offset);
off = uio->uio_offset;
@@ -948,7 +952,7 @@ ntfs_lookup(ap)
}
return (error);
} else {
- error = ntfs_ntlookup(ntmp, dvp, cnp, ap->a_vpp);
+ error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
if(error)
return (error);
@@ -961,6 +965,8 @@ ntfs_lookup(ap)
#else
VOP_UNLOCK(dvp);
#endif
+ if (cnp->cn_flags & MAKEENTRY)
+ cache_enter(dvp, *ap->a_vpp, cnp);
}
return (error);
diff --git a/sys/ntfs/ntfs.h b/sys/ntfs/ntfs.h
index e2bda5e..e9fa1b3 100644
--- a/sys/ntfs/ntfs.h
+++ b/sys/ntfs/ntfs.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ntfs.h,v 1.2 1999/02/19 12:31:02 semenu Exp $
+ * $Id: ntfs.h,v 1.9 1999/02/02 01:54:54 semen Exp $
*/
/*#define NTFS_DEBUG 1*/
@@ -213,6 +213,8 @@ struct ntvattrdef {
u_int32_t ad_type;
};
+#define NTFS_BBID "NTFS "
+#define NTFS_BBIDLEN 8
struct bootfile {
u_int8_t reserved1[3]; /* asm jmp near ... */
u_int8_t bf_sysid[8]; /* 'NTFS ' */
@@ -246,6 +248,7 @@ struct ntfsmount {
gid_t ntm_gid;
mode_t ntm_mode;
u_long ntm_flag;
+ cn_t ntm_cfree;
struct ntvattrdef *ntm_ad;
int ntm_adnum;
};
diff --git a/sys/ntfs/ntfs_inode.h b/sys/ntfs/ntfs_inode.h
index 2e6fb78..bf1e26c 100644
--- a/sys/ntfs/ntfs_inode.h
+++ b/sys/ntfs/ntfs_inode.h
@@ -55,17 +55,18 @@
#define IN_PRELOADED 0x4000 /* loaded from directory entry */
struct ntnode {
- LIST_ENTRY(ntnode) i_hash;
+ LIST_ENTRY(ntnode) i_hash;
struct ntnode *i_next;
struct ntnode **i_prev;
- struct ntfsmount *i_mp;
+ struct ntfsmount *i_mp;
ino_t i_number;
dev_t i_dev;
u_int32_t i_flag;
+ int i_lock;
int i_usecount;
- LIST_HEAD(,fnode) i_fnlist;
- struct ntvattr *i_vattrp; /* ntvattrs list */
+ LIST_HEAD(,fnode) i_fnlist;
+ LIST_HEAD(,ntvattr) i_valist;
long i_nlink; /* MFR */
ino_t i_mainrec; /* MFR */
@@ -77,7 +78,7 @@ struct ntnode {
};
#define FN_PRELOADED 0x0001
-#define FN_DEFAULT 0x0002
+#define FN_VALID 0x0002
#define FN_AATTRNAME 0x0004 /* space allocated for f_attrname */
struct fnode {
struct lock f_lock; /* Must be first */
diff --git a/sys/ntfs/ntfs_subr.c b/sys/ntfs/ntfs_subr.c
index 901ea69..cecc00a 100644
--- a/sys/ntfs/ntfs_subr.c
+++ b/sys/ntfs/ntfs_subr.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998, 1999 Semen Ustimenko
+ * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,9 @@ MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage");
MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary");
#endif
+/*
+ *
+ */
int
ntfs_ntvattrrele(
struct ntvattr * vap)
@@ -70,6 +73,13 @@ ntfs_ntvattrrele(
return (0);
}
+/*
+ * Search attribute specifed in ntnode (load ntnode if nessecary).
+ * If not found but ATTR_A_ATTRLIST present, read it in and search throught.
+ * VOP_VGET node needed, and lookup througth it's ntnode (load if nessesary).
+ *
+ * ntnode should be locked
+ */
int
ntfs_ntvattrget(
struct ntfsmount * ntmp,
@@ -113,7 +123,7 @@ ntfs_ntvattrget(
}
}
- for (vap = ip->i_vattrp; vap; vap = vap->va_nextp) {
+ for (vap = ip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
ddprintf(("type: 0x%x, vcn: %d - %d\n", \
vap->va_type, (u_int32_t) vap->va_vcnstart, \
(u_int32_t) vap->va_vcnend));
@@ -171,14 +181,20 @@ ntfs_ntvattrget(
dprintf(("ntfs_ntvattrget: attrbute in ino: %d\n",
aalp->al_inumber));
+/*
error = VFS_VGET(ntmp->ntm_mountp, aalp->al_inumber,
&newvp);
+*/
+ error = ntfs_vgetex(ntmp->ntm_mountp, aalp->al_inumber,
+ NTFS_A_DATA, NULL, LK_EXCLUSIVE,
+ VG_EXT, curproc, &newvp);
if (error) {
printf("ntfs_ntvattrget: CAN'T VGET INO: %d\n",
aalp->al_inumber);
goto out;
}
newip = VTONT(newvp);
+ /* XXX have to lock ntnode */
if(~newip->i_flag & IN_LOADED) {
dprintf(("ntfs_ntvattrget: node not loaded," \
" ino: %d\n", newip->i_number));
@@ -190,7 +206,7 @@ ntfs_ntvattrget(
goto out;
}
}
- for (vap = newip->i_vattrp; vap; vap = vap->va_nextp) {
+ for (vap = newip->i_valist.lh_first; vap; vap = vap->va_list.le_next) {
if ((vap->va_type == type) &&
(vap->va_vcnstart <= vcn) &&
(vap->va_vcnend >= vcn) &&
@@ -219,10 +235,14 @@ ntfs_ntvattrget(
ip->i_number, type, name, (u_int32_t) vcn));
out:
FREE(alpool, M_TEMP);
-
return (error);
}
+/*
+ * Read ntnode from disk, make ntvattr list.
+ *
+ * ntnode should be locked
+ */
int
ntfs_loadntnode(
struct ntfsmount * ntmp,
@@ -232,7 +252,7 @@ ntfs_loadntnode(
daddr_t bn;
int error,off;
struct attr *ap;
- struct ntvattr**vapp;
+ struct ntvattr *nvap;
dprintf(("ntfs_loadnode: loading ino: %d\n",ip->i_number));
@@ -269,6 +289,7 @@ ntfs_loadntnode(
goto out;
}
}
+
/* Check if magic and fixups are correct */
error = ntfs_procfixups(ntmp, NTFS_FILEMAGIC, (caddr_t)mfrp,
ntfs_bntob(ntmp->ntm_bpmftrec));
@@ -281,16 +302,16 @@ ntfs_loadntnode(
dprintf(("ntfs_loadnode: load attrs for ino: %d\n",ip->i_number));
off = mfrp->fr_attroff;
ap = (struct attr *) ((caddr_t)mfrp + off);
- if (ip->i_vattrp)
- printf("ntfs_ntloadnode: WARNING! already loaded?\n");
+
+ LIST_INIT(&ip->i_valist);
- vapp = &ip->i_vattrp;
while (ap->a_hdr.a_type != -1) {
- error = ntfs_attrtontvattr(ntmp, vapp, ap);
+ error = ntfs_attrtontvattr(ntmp, &nvap, ap);
if (error)
break;
- (*vapp)->va_ip = ip;
- vapp = &((*vapp)->va_nextp);
+ nvap->va_ip = ip;
+
+ LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list);
off += ap->a_hdr.reclen;
ap = (struct attr *) ((caddr_t)mfrp + off);
@@ -312,44 +333,74 @@ out:
return (error);
}
+/*
+ * Routine locks ntnode and increase usecount, just opposite of
+ * ntfs_ntput.
+ */
+int
+ntfs_ntget(
+ struct ntnode *ip)
+{
+ dprintf(("ntfs_ntget: get ntnode %d: %p, usecount: %d\n",
+ ip->i_number, ip, ip->i_usecount));
+
+ ip->i_usecount++;
+
+restart:
+ if (ip->i_lock) {
+ while (ip->i_lock) {
+ ip->i_lock = -1;
+ tsleep(&ip->i_lock, PVM, "ntnode", 0);
+ }
+ goto restart;
+ }
+ ip->i_lock = 1;
+
+ return 0;
+}
+/*
+ * Routine search ntnode in hash, if found: lock, inc usecount and return.
+ * If not in hash allocate structure for ntnode, prefill it, lock,
+ * inc count and return.
+ *
+ * ntnode returned locked
+ */
static int ntfs_ntnode_hash_lock;
int
-ntfs_ntget(
+ntfs_ntlookup(
struct ntfsmount * ntmp,
ino_t ino,
struct ntnode ** ipp)
{
struct ntnode *ip;
- dprintf(("ntfs_ntget: ntget ntnode %d\n", ino));
+ dprintf(("ntfs_ntlookup: for ntnode %d\n", ino));
*ipp = NULL;
restart:
- ip = ntfs_nthashlookup(ntmp->ntm_dev, ino);
+ ip = ntfs_nthashlookup(ntmp->ntm_dev, ino); /* XXX */
if (ip) {
- ip->i_usecount++;
+ ntfs_ntget(ip);
*ipp = ip;
- dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
+ dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
ino, ip, ip->i_usecount));
return (0);
}
if (ntfs_ntnode_hash_lock) {
- printf("waiting for hash_lock to free...\n");
while(ntfs_ntnode_hash_lock) {
ntfs_ntnode_hash_lock = -1;
tsleep(&ntfs_ntnode_hash_lock, PVM, "ntfsntgt", 0);
}
- printf("hash_lock freeed\n");
goto restart;
}
ntfs_ntnode_hash_lock = 1;
MALLOC(ip, struct ntnode *, sizeof(struct ntnode),
M_NTFSNTNODE, M_WAITOK);
- ddprintf(("ntfs_ntget: allocating ntnode: %d: %p\n", ino, ip));
+ ddprintf(("ntfs_ntlookup: allocating ntnode: %d: %p\n", ino, ip));
bzero((caddr_t) ip, sizeof(struct ntnode));
/* Generic initialization */
@@ -361,6 +412,8 @@ restart:
ip->i_mode = ntmp->ntm_mode;
ip->i_usecount++;
+ ip->i_lock = 1;
+
LIST_INIT(&ip->i_fnlist);
ntfs_nthashins(ip);
@@ -371,45 +424,77 @@ restart:
*ipp = ip;
- dprintf(("ntfs_ntget: ntnode %d: %p, usecount: %d\n",
+ dprintf(("ntfs_ntlookup: ntnode %d: %p, usecount: %d\n",
ino, ip, ip->i_usecount));
return (0);
}
+/*
+ * Decrement usecount of ntnode and unlock it, if usecount reach zero,
+ * deallocate ntnode.
+ *
+ * ntnode should be locked on entry, and unlocked on return.
+ */
void
-ntfs_ntrele(
- struct ntnode * ip)
+ntfs_ntput(
+ struct ntnode *ip)
{
struct ntvattr *vap;
- dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
+ if (!ip->i_lock) printf("ntfs_ntput: NOT LOCKED");
+
+ dprintf(("ntfs_ntput: rele ntnode %d: %p, usecount: %d\n",
ip->i_number, ip, ip->i_usecount));
ip->i_usecount--;
if (ip->i_usecount < 0) {
- panic("ntfs_ntrele: ino: %d usecount: %d \n",
+ panic("ntfs_ntput: ino: %d usecount: %d \n",
ip->i_number,ip->i_usecount);
} else if (ip->i_usecount == 0) {
- dprintf(("ntfs_ntrele: deallocating ntnode: %d\n",
+ dprintf(("ntfs_ntput: deallocating ntnode: %d\n",
ip->i_number));
if (ip->i_fnlist.lh_first)
- panic("ntfs_ntrele: ntnode has fnodes\n");
+ panic("ntfs_ntput: ntnode has fnodes\n");
ntfs_nthashrem(ip);
- while (ip->i_vattrp) {
- vap = ip->i_vattrp;
- ip->i_vattrp = vap->va_nextp;
+ while (ip->i_valist.lh_first != NULL) {
+ vap = ip->i_valist.lh_first;
+ LIST_REMOVE(vap,va_list);
ntfs_freentvattr(vap);
}
FREE(ip, M_NTFSNTNODE);
+ } else {
+ if (ip->i_lock < 0)
+ wakeup(&ip->i_lock);
+ ip->i_lock = 0;
}
- dprintf(("ntfs_ntrele: rele ok\n"));
}
+/*
+ * Decrement usecount of ntnode.
+ */
+void
+ntfs_ntrele(
+ struct ntnode * ip)
+{
+ dprintf(("ntfs_ntrele: rele ntnode %d: %p, usecount: %d\n",
+ ip->i_number, ip, ip->i_usecount));
+
+ ip->i_usecount--;
+
+ if (ip->i_usecount < 0)
+ panic("ntfs_ntrele: ino: %d usecount: %d \n",
+ ip->i_number,ip->i_usecount);
+}
+
+/*
+ * Deallocate all memory allocated for ntvattr by call to
+ * ntfs_attrtontvattr and some other functions.
+ */
void
ntfs_freentvattr(
struct ntvattr * vap)
@@ -426,6 +511,10 @@ ntfs_freentvattr(
FREE(vap, M_NTFSNTVATTR);
}
+/*
+ * Convert disk image of attribute into ntvattr structure,
+ * runs are expanded also.
+ */
int
ntfs_attrtontvattr(
struct ntfsmount * ntmp,
@@ -493,6 +582,9 @@ ntfs_attrtontvattr(
return (error);
}
+/*
+ * Expand run into more utilizable and more memory eating format.
+ */
int
ntfs_runtovrun(
cn_t ** rcnp,
@@ -552,7 +644,9 @@ ntfs_runtovrun(
return (0);
}
-
+/*
+ * Convert wchar to uppercase wchar, should be macros?
+ */
wchar
ntfs_toupper(
struct ntfsmount * ntmp,
@@ -561,6 +655,9 @@ ntfs_toupper(
return (ntmp->ntm_upcase[wc & 0xFF]);
}
+/*
+ * Compare to unicode strings case insensible.
+ */
int
ntfs_uustricmp(
struct ntfsmount * ntmp,
@@ -581,6 +678,9 @@ ntfs_uustricmp(
return (str1len - str2len);
}
+/*
+ * Compare unicode and ascii string case insens.
+ */
int
ntfs_uastricmp(
struct ntfsmount * ntmp,
@@ -601,6 +701,9 @@ ntfs_uastricmp(
return (str1len - str2len);
}
+/*
+ * Compare unicode and ascii string case sens.
+ */
int
ntfs_uastrcmp(
struct ntfsmount * ntmp,
@@ -620,6 +723,11 @@ ntfs_uastrcmp(
return (str1len - str2len);
}
+/*
+ * Search fnode in ntnode, if not found allocate and preinitialize.
+ *
+ * ntnode should be locked on entry.
+ */
int
ntfs_fget(
struct ntfsmount *ntmp,
@@ -628,7 +736,6 @@ ntfs_fget(
char *attrname,
struct fnode **fpp)
{
- int error;
struct fnode *fp;
dprintf(("ntfs_fget: ino: %d, attrtype: 0x%x, attrname: %s\n",
@@ -662,15 +769,6 @@ ntfs_fget(
fp->f_attrname = attrname;
if (fp->f_attrname) fp->f_flag |= FN_AATTRNAME;
fp->f_attrtype = attrtype;
- if ((fp->f_attrtype == NTFS_A_DATA) && (fp->f_attrname == NULL))
- fp->f_flag |= FN_DEFAULT;
- else {
- error = ntfs_filesize(ntmp, fp, &fp->f_size, &fp->f_allocated);
- if (error) {
- FREE(fp,M_NTFSFNODE);
- return (error);
- }
- }
ntfs_ntref(ip);
@@ -681,6 +779,11 @@ ntfs_fget(
return (0);
}
+/*
+ * Deallocate fnode, remove it from ntnode's fnode list.
+ *
+ * ntnode should be locked.
+ */
void
ntfs_frele(
struct fnode *fp)
@@ -699,6 +802,11 @@ ntfs_frele(
ntfs_ntrele(ip);
}
+/*
+ * Lookup attribute name in format: [[:$ATTR_TYPE]:$ATTR_NAME],
+ * $ATTR_TYPE is searched in attrdefs read from $AttrDefs.
+ * If $ATTR_TYPE nott specifed, ATTR_A_DATA assumed.
+ */
int
ntfs_ntlookupattr(
struct ntfsmount * ntmp,
@@ -753,12 +861,13 @@ ntfs_ntlookupattr(
return (0);
}
+
/*
* Lookup specifed node for filename, matching cnp,
* return fnode filled.
*/
int
-ntfs_ntlookup(
+ntfs_ntlookupfile(
struct ntfsmount * ntmp,
struct vnode * vp,
struct componentname * cnp,
@@ -776,6 +885,10 @@ ntfs_ntlookup(
char *fname,*aname;
u_int32_t aoff;
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
if (error || (vap->va_flag & NTFS_AF_INRUN))
return (ENOTDIR);
@@ -783,6 +896,10 @@ ntfs_ntlookup(
blsize = vap->va_a_iroot->ir_size;
rdsize = vap->va_datalen;
+ /*
+ * Divide file name into: foofilefoofilefoofile[:attrspec]
+ * Store like this: fname:fnamelen [aname:anamelen]
+ */
fname = cnp->cn_nameptr;
aname = NULL;
anamelen = 0;
@@ -790,12 +907,12 @@ ntfs_ntlookup(
if(fname[fnamelen] == ':') {
aname = fname + fnamelen + 1;
anamelen = cnp->cn_namelen - fnamelen - 1;
- dprintf(("ntfs_ntlookup: file %s (%d), attr: %s (%d)\n",
+ dprintf(("ntfs_ntlookupfile: %s (%d), attr: %s (%d)\n",
fname, fnamelen, aname, anamelen));
break;
}
- dprintf(("ntfs_ntlookup: blocksize: %d, rdsize: %d\n", blsize, rdsize));
+ dprintf(("ntfs_ntlookupfile: blksz: %d, rdsz: %d\n", blsize, rdsize));
MALLOC(rdbuf, caddr_t, blsize, M_TEMP, M_WAITOK);
@@ -856,7 +973,8 @@ ntfs_ntlookup(
attrtype,
attrname,
LK_EXCLUSIVE,
- VG_DONTLOAD,
+ VG_DONTLOADIN |
+ VG_DONTVALIDFN,
curproc,
&nvp);
if(error)
@@ -864,6 +982,11 @@ ntfs_ntlookup(
nfp = VTOF(nvp);
+ if (nfp->f_flag & FN_VALID) {
+ *vpp = nvp;
+ goto fail;
+ }
+
nfp->f_fflag = iep->ie_fflag;
nfp->f_pnumber = iep->ie_fpnumber;
nfp->f_times = iep->ie_ftimes;
@@ -883,7 +1006,17 @@ ntfs_ntlookup(
nfp->f_size = iep->ie_fsize;
nfp->f_allocated = iep->ie_fallocated;
nfp->f_flag |= FN_PRELOADED;
+ } else {
+ error = ntfs_filesize(ntmp, nfp,
+ &nfp->f_size,
+ &nfp->f_allocated);
+ if (error) {
+ vput(nvp);
+ goto fail;
+ }
}
+
+ nfp->f_flag &= ~FN_VALID;
*vpp = nvp;
goto fail;
}
@@ -896,7 +1029,7 @@ ntfs_ntlookup(
/* Dive if possible */
if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
- dprintf(("ntfs_ntlookup: diving\n"));
+ dprintf(("ntfs_ntlookupfile: diving\n"));
cn = *(cn_t *) (rdbuf + aoff +
iep->reclen - sizeof(cn_t));
@@ -915,7 +1048,7 @@ ntfs_ntlookup(
aoff = (((struct attr_indexalloc *) rdbuf)->ia_hdrsize +
0x18);
} else {
- dprintf(("ntfs_ntlookup: nowhere to dive :-(\n"));
+ dprintf(("ntfs_ntlookupfile: nowhere to dive :-(\n"));
error = ENOENT;
break;
}
@@ -925,10 +1058,14 @@ ntfs_ntlookup(
fail:
ntfs_ntvattrrele(vap);
+ ntfs_ntput(ip);
FREE(rdbuf, M_TEMP);
return (error);
}
+/*
+ * Check if name type is permitted to show.
+ */
int
ntfs_isnamepermitted(
struct ntfsmount * ntmp,
@@ -942,9 +1079,7 @@ ntfs_isnamepermitted(
case 2:
ddprintf(("ntfs_isnamepermitted: skiped DOS name\n"));
return 0;
- case 0:
- case 1:
- case 3:
+ case 0: case 1: case 3:
return 1;
default:
printf("ntfs_isnamepermitted: " \
@@ -955,6 +1090,14 @@ ntfs_isnamepermitted(
return 0;
}
+/*
+ * Read ntfs dir like stream of attr_indexentry, not like btree of them.
+ * This is done by scaning $BITMAP:$I30 for busy clusters and reading them.
+ * Ofcouse $INDEX_ROOT:$I30 is read before. Last read values are stored in
+ * fnode, so we can skip toward record number num almost immediatly.
+ * Anyway this is rather slow routine. The problem is that we don't know
+ * how many records are there in $INDEX_ALLOCATION:$I30 block.
+ */
int
ntfs_ntreaddir(
struct ntfsmount * ntmp,
@@ -978,6 +1121,10 @@ ntfs_ntreaddir(
u_int32_t aoff, cnum;
dprintf(("ntfs_ntreaddir: read ino: %d, num: %d\n", ip->i_number, num));
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
error = ntfs_ntvattrget(ntmp, ip, NTFS_A_INDXROOT, "$I30", 0, &vap);
if (error)
return (ENOTDIR);
@@ -1106,12 +1253,14 @@ fail:
ntfs_ntvattrrele(iavap);
if (bmp)
FREE(bmp, M_TEMP);
+ ntfs_ntput(ip);
return (error);
}
+
/*
- * #undef dprintf #define dprintf(a)
+ * Convert NTFS times that are in 100 ns units and begins from
+ * 1601 Jan 1 into unix times.
*/
-
struct timespec
ntfs_nttimetounix(
u_int64_t nt)
@@ -1126,6 +1275,9 @@ ntfs_nttimetounix(
return (t);
}
+/*
+ * Get file times from NTFS_A_NAME attribute.
+ */
int
ntfs_times(
struct ntfsmount * ntmp,
@@ -1136,15 +1288,28 @@ ntfs_times(
int error;
dprintf(("ntfs_times: ino: %d...\n", ip->i_number));
- error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
+
+ error = ntfs_ntget(ip);
if (error)
return (error);
+
+ error = ntfs_ntvattrget(ntmp, ip, NTFS_A_NAME, NULL, 0, &vap);
+ if (error) {
+ ntfs_ntput(ip);
+ return (error);
+ }
*tm = vap->va_a_name->n_times;
ntfs_ntvattrrele(vap);
+ ntfs_ntput(ip);
return (0);
}
+/*
+ * Get file sizes from corresponding attribute.
+ *
+ * ntnode under fnode should be locked.
+ */
int
ntfs_filesize(
struct ntfsmount * ntmp,
@@ -1158,15 +1323,12 @@ ntfs_filesize(
int error;
dprintf(("ntfs_filesize: ino: %d\n", ip->i_number));
- if (fp->f_flag & FN_DEFAULT) {
- error = ntfs_ntvattrget(ntmp, ip,
- NTFS_A_DATA, NULL, 0, &vap);
- } else {
- error = ntfs_ntvattrget(ntmp, ip,
- fp->f_attrtype, fp->f_attrname, 0, &vap);
- }
+
+ error = ntfs_ntvattrget(ntmp, ip,
+ fp->f_attrtype, fp->f_attrname, 0, &vap);
if (error)
return (error);
+
bn = vap->va_allocated;
sz = vap->va_datalen;
@@ -1183,6 +1345,11 @@ ntfs_filesize(
return (0);
}
+/*
+ * This is one of write routine.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_writeattr_plain(
struct ntfsmount * ntmp,
@@ -1234,6 +1401,11 @@ ntfs_writeattr_plain(
return (error);
}
+/*
+ * This is one of write routine.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_writentvattr_plain(
struct ntfsmount * ntmp,
@@ -1313,7 +1485,7 @@ ntfs_writentvattr_plain(
}
}
memcpy(bp->b_data + off, data, tocopy);
- bwrite(bp);
+ bawrite(bp);
data = data + tocopy;
*initp += tocopy;
off = 0;
@@ -1336,6 +1508,11 @@ ntfs_writentvattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readntvattr_plain(
struct ntfsmount * ntmp,
@@ -1379,7 +1556,7 @@ ntfs_readntvattr_plain(
cnt++;
continue;
}
- if (ccn || ip->i_number == NTFS_BOOTINO) { /* XXX */
+ if (ccn || ip->i_number == NTFS_BOOTINO) {
ccl -= ntfs_btocn(off);
cn = ccn + ntfs_btocn(off);
off = ntfs_btocnoff(off);
@@ -1442,6 +1619,11 @@ ntfs_readntvattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readattr_plain(
struct ntfsmount * ntmp,
@@ -1493,6 +1675,11 @@ ntfs_readattr_plain(
return (error);
}
+/*
+ * This is one of read routines.
+ *
+ * ntnode should be locked.
+ */
int
ntfs_readattr(
struct ntfsmount * ntmp,
@@ -1574,6 +1761,7 @@ ntfs_readattr(
return (error);
}
+#if UNUSED_CODE
int
ntfs_parserun(
cn_t * cn,
@@ -1616,7 +1804,11 @@ ntfs_parserun(
return (0);
}
+#endif
+/*
+ * Process fixup routine on given buffer.
+ */
int
ntfs_procfixups(
struct ntfsmount * ntmp,
@@ -1659,6 +1851,7 @@ ntfs_procfixups(
return (0);
}
+#if UNUSED_CODE
int
ntfs_runtocn(
cn_t * cn,
@@ -1701,3 +1894,4 @@ ntfs_runtocn(
*cn = ccn + vcn;
return (0);
}
+#endif
diff --git a/sys/ntfs/ntfs_subr.h b/sys/ntfs/ntfs_subr.h
index 692bb54..3cfc783 100644
--- a/sys/ntfs/ntfs_subr.h
+++ b/sys/ntfs/ntfs_subr.h
@@ -30,7 +30,7 @@
#define VA_PRELOADED 0x0002
struct ntvattr {
- struct ntvattr *va_nextp;
+ LIST_ENTRY(ntvattr) va_list;
u_int32_t va_vflag;
struct vnode *va_vp;
@@ -99,12 +99,14 @@ 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 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_ntlookupfile __P((struct ntfsmount *, struct vnode *, struct componentname *, struct vnode **));
+int ntfs_isnamepermitted __P((struct ntfsmount *, struct attr_indexentry * ));
+int ntfs_ntvattrrele __P((struct ntvattr * ));
+int ntfs_ntvattrget __P((struct ntfsmount *, struct ntnode *, u_int32_t, char *, cn_t , struct ntvattr **));
+int ntfs_ntlookup __P((struct ntfsmount *, ino_t, struct ntnode **));
+int ntfs_ntget __P((struct ntnode *));
+void ntfs_ntrele __P((struct ntnode *));
+void ntfs_ntput __P((struct ntnode *));
int ntfs_loadntnode __P(( struct ntfsmount *, struct ntnode * ));
int ntfs_ntlookupattr(struct ntfsmount *, char *, int, int *, char **);
int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *);
diff --git a/sys/ntfs/ntfs_vfsops.c b/sys/ntfs/ntfs_vfsops.c
index a371319..7d1f91d 100644
--- a/sys/ntfs/ntfs_vfsops.c
+++ b/sys/ntfs/ntfs_vfsops.c
@@ -102,13 +102,6 @@ static int
ntfs_init ()
#endif
{
- static first=1;
-
- if(!first) return (0);
- first = 1;
-
- printf("ntfs_init(): \n");
-
ntfs_nthashinit();
return 0;
@@ -384,6 +377,12 @@ ntfs_mountfs(devvp, mp, argsp, p)
brelse( bp );
bp = NULL;
+ if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) {
+ error = EINVAL;
+ printf("ntfs_mountfs: invalid boot block\n");
+ goto out;
+ }
+
{
int8_t cpr = ntmp->ntm_mftrecsz;
if( cpr > 0 )
@@ -391,11 +390,11 @@ ntfs_mountfs(devvp, mp, argsp, p)
else
ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps;
}
- printf("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
+ dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n",
ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media,
- ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec);
- printf("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
- (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn);
+ ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec));
+ dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n",
+ (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn));
ntmp->ntm_mountp = mp;
ntmp->ntm_dev = dev;
@@ -406,51 +405,64 @@ ntfs_mountfs(devvp, mp, argsp, p)
ntmp->ntm_flag = argsp->flag;
mp->mnt_data = (qaddr_t)ntmp;
- printf("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
+ dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
(ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.",
(ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
- ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode);
+ ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
- printf("ntfs_mountfs(): reading system nodes...\n");
+ /*
+ * We read in some system nodes to do not allow
+ * reclaim them and to have everytime access to them.
+ */
{
- i = NTFS_MFTINO;
- 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]);
- vput(ntmp->ntm_sysvn[i]);
+ int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
+ for (i=0; i<3; i++) {
+ error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
+ if(error)
+ goto out1;
+ ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
+ VREF(ntmp->ntm_sysvn[pi[i]]);
+ vput(ntmp->ntm_sysvn[pi[i]]);
+ }
}
- MALLOC( ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
+ /*
+ * Read in WHOLE lowcase -> upcase translation
+ * file.
+ */
+ MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar),
M_NTFSMNT, M_WAITOK);
- printf("ntfs_mountfs(): opening $UpCase\n");
- error = VFS_VGET(mp, NTFS_UPCASEINO, &vp );
+ error = VFS_VGET(mp, NTFS_UPCASEINO, &vp);
if(error)
goto out1;
- printf("ntfs_mountfs(): reading $UpCase\n");
- error = ntfs_readattr( 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);
if(error)
goto out1;
+ /*
+ * Scan $BitMap and count free clusters
+ */
+ error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree);
+ if(error)
+ goto out1;
+
+ /*
+ * Read and translate to internal format attribute
+ * definition file.
+ */
{
int num,j;
struct attrdef ad;
- printf("ntfs_mountfs(): opening $AttrDef\n");
+ /* Open $AttrDef */
error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp );
if(error)
goto out1;
+ /* Count valid entries */
for(num=0;;num++) {
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
@@ -461,14 +473,15 @@ ntfs_mountfs(devvp, mp, argsp, p)
if (ad.ad_name[0] == 0)
break;
}
- printf("ntfs_mountfs(): reading %d attrdefs\n",num);
+ /* Alloc memory for attribute definitions */
MALLOC(ntmp->ntm_ad, struct ntvattrdef *,
num * sizeof(struct ntvattrdef),
M_NTFSMNT, M_WAITOK);
ntmp->ntm_adnum = num;
+ /* Read them and translate */
for(i=0;i<num;i++){
error = ntfs_readattr(ntmp, VTONT(vp),
NTFS_A_DATA, NULL,
@@ -482,11 +495,8 @@ ntfs_mountfs(devvp, mp, argsp, p)
} while(ad.ad_name[j++]);
ntmp->ntm_ad[i].ad_namelen = j - 1;
ntmp->ntm_ad[i].ad_type = ad.ad_type;
- printf("ntfs_mountfs(): attribute: %s, type: 0x%x\n",
- ntmp->ntm_ad[i].ad_name,
- ntmp->ntm_ad[i].ad_type);
}
- printf("ntfs_mountfs(): closing $AttrDef\n");
+
vput(vp);
}
@@ -504,9 +514,14 @@ ntfs_mountfs(devvp, mp, argsp, p)
devvp->v_specflags |= SI_MOUNTEDON;
#endif
return (0);
+
out1:
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
+
+ if (vflush(mp,NULLVP,0))
+ printf("ntfs_mountfs: vflush failed\n");
+
out:
#if __FreeBSD_version >= 300000
devvp->v_specmountpoint = NULL;
@@ -525,7 +540,6 @@ ntfs_start (
int flags,
struct proc *p )
{
- printf("\nntfs_start():\n");
return (0);
}
@@ -538,24 +552,33 @@ ntfs_unmount(
register struct ntfsmount *ntmp;
int error, ronly = 0, flags, i;
- printf("ntfs_unmount: unmounting...\n");
+ dprintf(("ntfs_unmount: unmounting...\n"));
ntmp = VFSTONTFS(mp);
flags = 0;
if(mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- printf("ntfs_unmount: vflushing...\n");
+ dprintf(("ntfs_unmount: vflushing...\n"));
error = vflush(mp,NULLVP,flags | SKIPSYSTEM);
if (error) {
printf("ntfs_unmount: vflush failed: %d\n",error);
return (error);
}
+
+ /* Check if only system vnodes are rest */
+ for(i=0;i<NTFS_SYSNODESNUM;i++)
+ if((ntmp->ntm_sysvn[i]) &&
+ (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY);
+
+ /* Derefernce all system vnodes */
for(i=0;i<NTFS_SYSNODESNUM;i++)
if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]);
+
+ /* vflush system vnodes */
error = vflush(mp,NULLVP,flags);
if (error)
- printf("ntfs_unmount: vflush failed: %d\n",error);
+ printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error);
#if __FreeBSD_version >= 300000
ntmp->ntm_devvp->v_specmountpoint = NULL;
@@ -573,7 +596,7 @@ ntfs_unmount(
vrele(ntmp->ntm_devvp);
- printf("ntfs_umount: freeing memory...\n");
+ dprintf(("ntfs_umount: freeing memory...\n"));
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
FREE(ntmp->ntm_ad, M_NTFSMNT);
@@ -614,47 +637,55 @@ ntfs_quotactl (
return EOPNOTSUPP;
}
-static int
-ntfs_statfs(
- struct mount *mp,
- struct statfs *sbp,
- struct proc *p)
+int
+ntfs_calccfree(
+ struct ntfsmount *ntmp,
+ cn_t *cfreep)
{
- struct ntfsmount *ntmp = VFSTONTFS(mp);
- u_int64_t mftsize,mftallocated,bmsize,bmallocated;
struct vnode *vp;
- int error,j,i;
u_int8_t *tmp;
+ int j, error;
+ long cfree = 0;
+ size_t bmsize, i;
- dprintf(("ntfs_statfs():"));
-
- ntfs_filesize(ntmp, VTOF(ntmp->ntm_sysvn[NTFS_MFTINO]),
- &mftsize, &mftallocated);
-
- error = VFS_VGET(mp, NTFS_BITMAPINO, &vp);
- if(error)
- return (error);
+ vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
- ntfs_filesize(ntmp, VTOF(vp), &bmsize, &bmallocated);
+ bmsize = VTOF(vp)->f_size;
- MALLOC(tmp, u_int8_t *, bmsize,M_TEMP, M_WAITOK);
+ MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, bmsize, tmp);
if(error) {
FREE(tmp, M_TEMP);
- vput(vp);
return (error);
}
- vput(vp);
- sbp->f_bfree = 0;
for(i=0;i<bmsize;i++)
for(j=0;j<8;j++)
- if(~tmp[i] & (1 << j)) sbp->f_bfree++;
+ if(~tmp[i] & (1 << j)) cfree++;
FREE(tmp, M_TEMP);
+ *cfreep = cfree;
+
+ return(0);
+}
+
+static int
+ntfs_statfs(
+ struct mount *mp,
+ struct statfs *sbp,
+ struct proc *p)
+{
+ struct ntfsmount *ntmp = VFSTONTFS(mp);
+ u_int64_t mftsize,mftallocated;
+
+ dprintf(("ntfs_statfs():\n"));
+
+ mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size;
+ mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated;
+
#if __FreeBSD_version >= 300000
sbp->f_type = mp->mnt_vfc->vfc_typenum;
#else
@@ -663,7 +694,7 @@ ntfs_statfs(
sbp->f_bsize = ntmp->ntm_bps;
sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc;
sbp->f_blocks = ntmp->ntm_bootfile.bf_spv;
- sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(sbp->f_bfree);
+ sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree);
sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec;
sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) +
sbp->f_ffree;
@@ -746,41 +777,63 @@ ntfs_vgetex(
*vpp = NULL;
/* Get ntnode */
- error = ntfs_ntget(ntmp, ino, &ip);
+ error = ntfs_ntlookup(ntmp, ino, &ip);
if (error) {
printf("ntfs_vget: ntfs_ntget failed\n");
return (error);
}
+ /* It may be not initialized fully, so force load it */
+ if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) {
+ error = ntfs_loadntnode(ntmp, ip);
+ if(error) {
+ printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n",
+ ip->i_number);
+ ntfs_ntput(ip);
+ return (error);
+ }
+ }
+
error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp);
if (error) {
printf("ntfs_vget: ntfs_fget failed\n");
- ntfs_ntrele(ip);
+ ntfs_ntput(ip);
return (error);
}
+ if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) {
+ if ((ip->i_frflag & NTFS_FRFLAG_DIR) &&
+ (fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) {
+ fp->f_type = VDIR;
+ } else if(flags & VG_EXT) {
+ fp->f_type = VNON;
+
+ fp->f_size =fp->f_allocated = 0;
+ } else {
+ fp->f_type = VREG;
+
+ error = ntfs_filesize(ntmp, fp,
+ &fp->f_size, &fp->f_allocated);
+ if (error) {
+ ntfs_ntput(ip);
+ return (error);
+ }
+ }
+
+ fp->f_flag |= FN_VALID;
+ }
+
if (FTOV(fp)) {
vget(FTOV(fp), lkflags, p);
*vpp = FTOV(fp);
- ntfs_ntrele(ip);
+ ntfs_ntput(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);
+ ntfs_ntput(ip);
return (error);
}
dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino));
@@ -788,18 +841,12 @@ ntfs_vgetex(
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;
+ vp->v_type = fp->f_type;
if (ino == NTFS_ROOTINO)
vp->v_flag |= VROOT;
- if (ino < NTFS_SYSNODESNUM)
- vp->v_flag |= VSYSTEM;
- ntfs_ntrele(ip);
+ ntfs_ntput(ip);
if (lkflags & LK_TYPE_MASK) {
error = vn_lock(vp, lkflags, p);
diff --git a/sys/ntfs/ntfs_vfsops.h b/sys/ntfs/ntfs_vfsops.h
index c8788c4..af5ce9d 100644
--- a/sys/ntfs/ntfs_vfsops.h
+++ b/sys/ntfs/ntfs_vfsops.h
@@ -25,9 +25,13 @@
*
* $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 */
+#define VG_DONTLOADIN 0x0001 /* Tells ntfs_vgetex to do not call */
/* ntfs_loadnode on ntnode, even if */
/* ntnode not loaded */
+#define VG_DONTVALIDFN 0x0002 /* Tells ntfs_vgetex to do not validate */
+ /* fnode */
+#define VG_EXT 0x0004 /* This is not main record */
int ntfs_vgetex(struct mount *, ino_t, u_int32_t, char *, u_long, u_long,
struct proc *, struct vnode **);
+int ntfs_calccfree(struct ntfsmount *, cn_t *);
diff --git a/sys/ntfs/ntfs_vnops.c b/sys/ntfs/ntfs_vnops.c
index f1a822a..d22ea5f 100644
--- a/sys/ntfs/ntfs_vnops.c
+++ b/sys/ntfs/ntfs_vnops.c
@@ -156,7 +156,8 @@ 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, fp, &toread, NULL);
+ toread = fp->f_size;
+
dprintf(("ntfs_read: filesize: %d",(u_int32_t)toread));
toread = min( uio->uio_resid, toread - uio->uio_offset );
@@ -165,7 +166,7 @@ ntfs_read(ap)
MALLOC(data, u_int8_t *, toread, M_TEMP,M_WAITOK);
- error = ntfs_readattr( ntmp, ip, fp->f_attrtype,
+ error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
fp->f_attrname, uio->uio_offset, toread, data);
if(error) {
printf("ntfs_read: ntfs_readattr failed: %d\n",error);
@@ -245,9 +246,7 @@ ntfs_inactive(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
-#if defined(NTFS_DEBUG) || defined(DISGNOSTIC)
register struct ntnode *ip = VTONT(vp);
-#endif
int error;
dprintf(("ntfs_inactive: vnode: %p, ntnode: %d\n", vp, ip->i_number));
@@ -262,7 +261,7 @@ ntfs_inactive(ap)
#else
#ifdef DIAGNOSTIC
if (VOP_ISLOCKED(vp))
- panic("ntfs_inactive: locked ntnode");
+ panic("ntfs_inactive: locked vnode");
if (curproc)
ip->i_lockholder = curproc->p_pid;
else
@@ -275,7 +274,7 @@ ntfs_inactive(ap)
* If we are done with the ntnode, reclaim it
* so that it can be reused immediately.
*/
- if (vp->v_usecount == 0 /*&& ip->i_mode == 0*/)
+ if (vp->v_usecount == 0 && ip->i_mode == 0)
#if __FreeBSD_version >= 300000
vrecycle(vp, (struct simplelock *)0, ap->a_p);
#else
@@ -295,12 +294,15 @@ ntfs_reclaim(ap)
{
register struct vnode *vp = ap->a_vp;
register struct fnode *fp = VTOF(vp);
-#if NTFS_DEBUG
register struct ntnode *ip = FTONT(fp);
-#endif
+ int error;
dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number));
+ error = ntfs_ntget(ip);
+ if (error)
+ return (error);
+
#if __FreeBSD_version >= 300000
VOP_UNLOCK(vp,0,ap->a_p);
#endif
@@ -316,6 +318,8 @@ ntfs_reclaim(ap)
vp->v_data = NULL;
+ ntfs_ntput(ip);
+
return (0);
}
@@ -428,15 +432,15 @@ ntfs_write(ap)
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));
- ntfs_filesize(ntmp, fp, &towrite, NULL);
+ towrite = fp->f_size;
+
+ dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
if (uio->uio_resid + uio->uio_offset > towrite) {
printf("ntfs_write: CAN'T WRITE BEYOND OF FILE\n");
return (EFBIG);
}
- dprintf(("ntfs_write: filesize: %d",(u_int32_t)towrite));
-
towrite = min(uio->uio_resid, towrite - uio->uio_offset);
off = uio->uio_offset;
@@ -948,7 +952,7 @@ ntfs_lookup(ap)
}
return (error);
} else {
- error = ntfs_ntlookup(ntmp, dvp, cnp, ap->a_vpp);
+ error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
if(error)
return (error);
@@ -961,6 +965,8 @@ ntfs_lookup(ap)
#else
VOP_UNLOCK(dvp);
#endif
+ if (cnp->cn_flags & MAKEENTRY)
+ cache_enter(dvp, *ap->a_vpp, cnp);
}
return (error);
OpenPOWER on IntegriCloud