summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/ntfs/ntfs.h13
-rw-r--r--sys/ntfs/ntfs_inode.h5
-rw-r--r--sys/ntfs/ntfs_subr.c56
-rw-r--r--sys/ntfs/ntfs_vfsops.c3
4 files changed, 63 insertions, 14 deletions
diff --git a/sys/ntfs/ntfs.h b/sys/ntfs/ntfs.h
index 8220e750d39..4a9f60b50fa 100644
--- a/sys/ntfs/ntfs.h
+++ b/sys/ntfs/ntfs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntfs.h,v 1.12 2010/12/21 20:14:43 thib Exp $ */
+/* $OpenBSD: ntfs.h,v 1.13 2013/01/18 05:09:21 jsing Exp $ */
/* $NetBSD: ntfs.h,v 1.5 2003/04/24 07:50:19 christos Exp $ */
/*-
@@ -240,6 +240,15 @@ typedef wchar (ntfs_wget_func_t)(const char **);
typedef int (ntfs_wput_func_t)(char *, size_t, wchar);
typedef int (ntfs_wcmp_func_t)(wchar, wchar);
+/*
+ * Maximum number of ntnodes to keep in memory. We do not want to leave
+ * large data structures hanging off vnodes indefinitely and the data
+ * needed to reload the ntnode should already be in the buffer cache.
+ */
+#define LOADED_NTNODE_HI 16
+struct ntnode;
+TAILQ_HEAD(ntnodeq, ntnode);
+
#define NTFS_SYSNODESNUM 0x0B
struct ntfsmount {
struct mount *ntm_mountp; /* filesystem vfs structure */
@@ -259,6 +268,8 @@ struct ntfsmount {
ntfs_wget_func_t *ntm_wget; /* decode string to Unicode string */
ntfs_wput_func_t *ntm_wput; /* encode Unicode string to string */
ntfs_wcmp_func_t *ntm_wcmp; /* compare to wide characters */
+ int ntm_ntnodes; /* Number of loaded ntnodes. */
+ struct ntnodeq ntm_ntnodeq; /* Queue of ntnodes (LRU). */
};
#define ntm_mftcn ntm_bootfile.bf_mftcn
diff --git a/sys/ntfs/ntfs_inode.h b/sys/ntfs/ntfs_inode.h
index 282303ba36a..7e255985e7a 100644
--- a/sys/ntfs/ntfs_inode.h
+++ b/sys/ntfs/ntfs_inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntfs_inode.h,v 1.5 2009/08/13 16:00:53 jasper Exp $ */
+/* $OpenBSD: ntfs_inode.h,v 1.6 2013/01/18 05:09:21 jsing Exp $ */
/* $NetBSD: ntfs_inode.h,v 1.1 2002/12/23 17:38:33 jdolecek Exp $ */
/*-
@@ -38,8 +38,11 @@ struct ntnode {
dev_t i_dev; /* Device associated with the inode. */
LIST_ENTRY(ntnode) i_hash;
+ TAILQ_ENTRY(ntnode) i_loaded;
+
struct ntnode *i_next;
struct ntnode **i_prev;
+
struct ntfsmount *i_mp;
ino_t i_number;
u_int32_t i_flag;
diff --git a/sys/ntfs/ntfs_subr.c b/sys/ntfs/ntfs_subr.c
index 4a862470dc4..c214d3a6814 100644
--- a/sys/ntfs/ntfs_subr.c
+++ b/sys/ntfs/ntfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntfs_subr.c,v 1.29 2013/01/14 02:41:03 jsing Exp $ */
+/* $OpenBSD: ntfs_subr.c,v 1.30 2013/01/18 05:09:21 jsing Exp $ */
/* $NetBSD: ntfs_subr.c,v 1.4 2003/04/10 21:37:32 jdolecek Exp $ */
/*-
@@ -115,6 +115,10 @@ ntfs_findvattr(struct ntfsmount *ntmp, struct ntnode *ip,
ip->i_number);
return (error);
}
+ } else {
+ /* Update LRU loaded list. */
+ TAILQ_REMOVE(&ntmp->ntm_ntnodeq, ip, i_loaded);
+ TAILQ_INSERT_HEAD(&ntmp->ntm_ntnodeq, ip, i_loaded);
}
*lvapp = NULL;
@@ -253,16 +257,35 @@ out:
int
ntfs_loadntnode(struct ntfsmount *ntmp, struct ntnode *ip)
{
- struct filerec *mfrp;
- daddr64_t bn;
- int error,off;
- struct attr *ap;
- struct ntvattr *nvap;
+ struct ntnode *oip;
+ struct ntvattr *vap;
+ struct filerec *mfrp;
+ struct attr *ap;
+ daddr64_t bn;
+ int error,off;
+
+ dprintf(("ntfs_loadntnode: loading ino: %d\n",ip->i_number));
+
+ KASSERT((ip->i_flag & IN_LOADED) == 0);
- dprintf(("ntfs_loadntnode: loading ino: %d\n",ip->i_number));
+ if (ntmp->ntm_ntnodes >= LOADED_NTNODE_HI) {
+ oip = TAILQ_LAST(&ntmp->ntm_ntnodeq, ntnodeq);
+ TAILQ_REMOVE(&ntmp->ntm_ntnodeq, oip, i_loaded);
+ ntmp->ntm_ntnodes--;
- mfrp = malloc(ntfs_bntob(ntmp->ntm_bpmftrec), M_TEMP, M_WAITOK);
+ dprintf(("ntfs_loadntnode: unloading ino: %d\n",
+ oip->i_number));
+
+ KASSERT((oip->i_flag & IN_LOADED));
+ oip->i_flag &= ~IN_LOADED;
+ while ((vap = LIST_FIRST(&oip->i_valist)) != NULL) {
+ LIST_REMOVE(vap, va_list);
+ ntfs_freentvattr(vap);
+ }
+ }
+ mfrp = malloc(ntfs_bntob(ntmp->ntm_bpmftrec), M_TEMP, M_WAITOK);
+
if (ip->i_number < NTFS_SYSNODESNUM) {
struct buf *bp;
@@ -309,12 +332,12 @@ ntfs_loadntnode(struct ntfsmount *ntmp, struct ntnode *ip)
LIST_INIT(&ip->i_valist);
while (ap->a_hdr.a_type != -1) {
- error = ntfs_attrtontvattr(ntmp, &nvap, ap);
+ error = ntfs_attrtontvattr(ntmp, &vap, ap);
if (error)
break;
- nvap->va_ip = ip;
+ vap->va_ip = ip;
- LIST_INSERT_HEAD(&ip->i_valist, nvap, va_list);
+ LIST_INSERT_HEAD(&ip->i_valist, vap, va_list);
off += ap->a_hdr.reclen;
ap = (struct attr *) ((caddr_t)mfrp + off);
@@ -331,6 +354,10 @@ ntfs_loadntnode(struct ntfsmount *ntmp, struct ntnode *ip)
ip->i_flag |= IN_LOADED;
+ /* Add to loaded list. */
+ TAILQ_INSERT_HEAD(&ntmp->ntm_ntnodeq, ip, i_loaded);
+ ntmp->ntm_ntnodes++;
+
out:
free(mfrp, M_TEMP);
return (error);
@@ -415,6 +442,7 @@ ntfs_ntlookup(struct ntfsmount *ntmp, ino_t ino, struct ntnode **ipp,
void
ntfs_ntput(struct ntnode *ip, struct proc *p)
{
+ struct ntfsmount *ntmp = ip->i_mp;
struct ntvattr *vap;
dprintf(("ntfs_ntput: rele ntnode %d: %p, usecount: %d\n",
@@ -441,6 +469,12 @@ ntfs_ntput(struct ntnode *ip, struct proc *p)
ntfs_nthashrem(ip);
+ /* Remove from loaded list. */
+ if (ip->i_flag & IN_LOADED) {
+ TAILQ_REMOVE(&ntmp->ntm_ntnodeq, ip, i_loaded);
+ ntmp->ntm_ntnodes--;
+ }
+
while ((vap = LIST_FIRST(&ip->i_valist)) != NULL) {
LIST_REMOVE(vap, va_list);
ntfs_freentvattr(vap);
diff --git a/sys/ntfs/ntfs_vfsops.c b/sys/ntfs/ntfs_vfsops.c
index 44cb3952c0e..fd08a45c480 100644
--- a/sys/ntfs/ntfs_vfsops.c
+++ b/sys/ntfs/ntfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntfs_vfsops.c,v 1.32 2013/01/14 02:41:03 jsing Exp $ */
+/* $OpenBSD: ntfs_vfsops.c,v 1.33 2013/01/18 05:09:21 jsing Exp $ */
/* $NetBSD: ntfs_vfsops.c,v 1.7 2003/04/24 07:50:19 christos Exp $ */
/*-
@@ -343,6 +343,7 @@ ntfs_mountfs(struct vnode *devvp, struct mount *mp, struct ntfs_args *argsp,
ntmp->ntm_mode = argsp->mode;
ntmp->ntm_flag = argsp->flag;
mp->mnt_data = (qaddr_t) ntmp;
+ TAILQ_INIT(&ntmp->ntm_ntnodeq);
/* set file name encode/decode hooks XXX utf-8 only for now */
ntmp->ntm_wget = ntfs_utf8_wget;