diff options
Diffstat (limited to 'sys')
-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; |