diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2013-01-18 05:09:22 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2013-01-18 05:09:22 +0000 |
commit | fd9fe78e14c556c9623d71c9b952fa97b4b279c5 (patch) | |
tree | 7caebae67c45eab6a0fd20c8a1a80e89060ef910 /sys/ntfs | |
parent | 6fc066f972e18a57fae0e5376f520e34678b363f (diff) |
Constrain the amount of kernel memory used by NTFS. Keep a small cache of
loaded ntnodes and once the maximum is reached, unload the least recently
used ntnode before loading a new one. This avoids leaving large data
structures hanging around, which only get cleaned up when the vnode is
reclaimed. Additionally, the buffer cache should contain the data needed
to reload the ntnode.
ok beck@
Diffstat (limited to 'sys/ntfs')
-rw-r--r-- | sys/ntfs/ntfs.h | 13 | ||||
-rw-r--r-- | sys/ntfs/ntfs_inode.h | 5 | ||||
-rw-r--r-- | sys/ntfs/ntfs_subr.c | 56 | ||||
-rw-r--r-- | sys/ntfs/ntfs_vfsops.c | 3 |
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; |