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!
This commit is contained in:
parent
c8cbbb76c7
commit
42e01703dc
@ -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;
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
static int ntfs_ntnode_hash_lock;
|
||||
/*
|
||||
* 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_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
|
||||
|
@ -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 *);
|
||||
|
@ -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,6 +637,41 @@ ntfs_quotactl (
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
ntfs_calccfree(
|
||||
struct ntfsmount *ntmp,
|
||||
cn_t *cfreep)
|
||||
{
|
||||
struct vnode *vp;
|
||||
u_int8_t *tmp;
|
||||
int j, error;
|
||||
long cfree = 0;
|
||||
size_t bmsize, i;
|
||||
|
||||
vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
|
||||
|
||||
bmsize = VTOF(vp)->f_size;
|
||||
|
||||
MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, bmsize, tmp);
|
||||
if(error) {
|
||||
FREE(tmp, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
for(i=0;i<bmsize;i++)
|
||||
for(j=0;j<8;j++)
|
||||
if(~tmp[i] & (1 << j)) cfree++;
|
||||
|
||||
FREE(tmp, M_TEMP);
|
||||
|
||||
*cfreep = cfree;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_statfs(
|
||||
struct mount *mp,
|
||||
@ -621,39 +679,12 @@ ntfs_statfs(
|
||||
struct proc *p)
|
||||
{
|
||||
struct ntfsmount *ntmp = VFSTONTFS(mp);
|
||||
u_int64_t mftsize,mftallocated,bmsize,bmallocated;
|
||||
struct vnode *vp;
|
||||
int error,j,i;
|
||||
u_int8_t *tmp;
|
||||
u_int64_t mftsize,mftallocated;
|
||||
|
||||
dprintf(("ntfs_statfs():"));
|
||||
dprintf(("ntfs_statfs():\n"));
|
||||
|
||||
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, VTOF(vp), &bmsize, &bmallocated);
|
||||
|
||||
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++;
|
||||
|
||||
FREE(tmp, M_TEMP);
|
||||
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;
|
||||
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
static int ntfs_ntnode_hash_lock;
|
||||
/*
|
||||
* 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_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
|
||||
|
@ -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 *);
|
||||
|
@ -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,6 +637,41 @@ ntfs_quotactl (
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
ntfs_calccfree(
|
||||
struct ntfsmount *ntmp,
|
||||
cn_t *cfreep)
|
||||
{
|
||||
struct vnode *vp;
|
||||
u_int8_t *tmp;
|
||||
int j, error;
|
||||
long cfree = 0;
|
||||
size_t bmsize, i;
|
||||
|
||||
vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
|
||||
|
||||
bmsize = VTOF(vp)->f_size;
|
||||
|
||||
MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
|
||||
0, bmsize, tmp);
|
||||
if(error) {
|
||||
FREE(tmp, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
for(i=0;i<bmsize;i++)
|
||||
for(j=0;j<8;j++)
|
||||
if(~tmp[i] & (1 << j)) cfree++;
|
||||
|
||||
FREE(tmp, M_TEMP);
|
||||
|
||||
*cfreep = cfree;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_statfs(
|
||||
struct mount *mp,
|
||||
@ -621,39 +679,12 @@ ntfs_statfs(
|
||||
struct proc *p)
|
||||
{
|
||||
struct ntfsmount *ntmp = VFSTONTFS(mp);
|
||||
u_int64_t mftsize,mftallocated,bmsize,bmallocated;
|
||||
struct vnode *vp;
|
||||
int error,j,i;
|
||||
u_int8_t *tmp;
|
||||
u_int64_t mftsize,mftallocated;
|
||||
|
||||
dprintf(("ntfs_statfs():"));
|
||||
dprintf(("ntfs_statfs():\n"));
|
||||
|
||||
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, VTOF(vp), &bmsize, &bmallocated);
|
||||
|
||||
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++;
|
||||
|
||||
FREE(tmp, M_TEMP);
|
||||
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;
|
||||
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user