diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2010-09-04 21:35:59 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2010-09-04 21:35:59 +0000 |
commit | a1a7ffe8d6492c421846f4481a42ee6ad08fb638 (patch) | |
tree | 14439df99c4db5727d68dde8429acf62cf361170 /sys/ntfs/ntfs_subr.c | |
parent | 4890afe69020fe918091de424fbecba5d6bd83cc (diff) |
revert previous "simplification". kcornies at gmail says it doesn't work.
Diffstat (limited to 'sys/ntfs/ntfs_subr.c')
-rw-r--r-- | sys/ntfs/ntfs_subr.c | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/sys/ntfs/ntfs_subr.c b/sys/ntfs/ntfs_subr.c index 75396c01f47..185c040fa08 100644 --- a/sys/ntfs/ntfs_subr.c +++ b/sys/ntfs/ntfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntfs_subr.c,v 1.21 2010/08/22 21:23:07 tedu Exp $ */ +/* $OpenBSD: ntfs_subr.c,v 1.22 2010/09/04 21:35:58 tedu Exp $ */ /* $NetBSD: ntfs_subr.c,v 1.4 2003/04/10 21:37:32 jdolecek Exp $ */ /*- @@ -32,6 +32,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/namei.h> +#include <sys/proc.h> #include <sys/kernel.h> #include <sys/vnode.h> #include <sys/mount.h> @@ -55,6 +56,13 @@ int ntfs_debug = NTFS_DEBUG; #endif +#ifdef MALLOC_DEFINE +MALLOC_DEFINE(M_NTFSNTVATTR, "NTFS vattr", "NTFS file attribute information"); +MALLOC_DEFINE(M_NTFSRDATA, "NTFS res data", "NTFS resident data"); +MALLOC_DEFINE(M_NTFSRUN, "NTFS vrun", "NTFS vrun storage"); +MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary"); +#endif + /* Local struct used in ntfs_ntlookupfile() */ struct ntfs_lookup_ctx { u_int32_t aoff; @@ -68,10 +76,13 @@ static int ntfs_findvattr(struct ntfsmount *, struct ntnode *, struct ntvattr ** static int ntfs_uastricmp(struct ntfsmount *, const wchar *, size_t, const char *, size_t); static int ntfs_uastrcmp(struct ntfsmount *, const wchar *, size_t, const char *, size_t); -/* table for mapping Unicode chars into uppercase */ +/* table for mapping Unicode chars into uppercase; it's filled upon first + * ntfs mount, freed upon last ntfs umount */ static wchar *ntfs_toupper_tab; #define NTFS_U28(ch) ((((ch) & 0xE0) == 0) ? '_' : (ch) & 0xFF) #define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(unsigned char)(ch)]) +struct rwlock ntfs_toupper_lock = RWLOCK_INITIALIZER("ntfs_toupper"); +static signed int ntfs_toupper_usecount; /* support macro for ntfs_ntvattrget() */ #define NTFS_AALPCMP(aalp,type,name,namelen) ( \ @@ -1965,16 +1976,32 @@ ntfs_runtocn( #endif /* - * if the ntfs_toupper_tab[] is not filled already - * read the data from the filesystem we are currently mounting + * this initializes toupper table & dependant variables to be ready for + * later work + */ +void +ntfs_toupper_init() +{ + ntfs_toupper_tab = (wchar *) NULL; + ntfs_toupper_usecount = 0; +} + +/* + * if the ntfs_toupper_tab[] is filled already, just raise use count; + * otherwise read the data from the filesystem we are currently mounting */ int -ntfs_load_toupper(struct mount *mp, struct ntfsmount *ntmp) +ntfs_toupper_use(mp, ntmp, p) + struct mount *mp; + struct ntfsmount *ntmp; + struct proc *p; { int error = 0; - wchar *buf = NULL; struct vnode *vp; + /* get exclusive access */ + rw_enter_write(&ntfs_toupper_lock); + /* only read the translation data from a file if it hasn't been * read already */ if (ntfs_toupper_tab) @@ -1985,23 +2012,45 @@ ntfs_load_toupper(struct mount *mp, struct ntfsmount *ntmp) * XXX for now, just the first 256 entries are used anyway, * so don't bother reading more */ - buf = malloc(256 * sizeof(wchar), M_NTFSRDATA, M_WAITOK); + ntfs_toupper_tab = malloc(256 * 256 * sizeof(wchar), M_NTFSRDATA, + M_WAITOK); if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp))) goto out; - error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, 0, - 256 * sizeof(wchar), ntfs_toupper_tab, NULL); + error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, + 0, 256*256*sizeof(wchar), (char *) ntfs_toupper_tab, + NULL); vput(vp); - /* check we didn't lose a race */ - if (!ntfs_toupper_tab) { - ntfs_toupper_tab = buf; - buf = NULL; - } + out: + ntfs_toupper_usecount++; + rw_exit_write(&ntfs_toupper_lock); + return (error); +} -out: - if (buf) - free(buf, M_NTFSRDATA); +/* + * lower the use count and if it reaches zero, free the memory + * tied by toupper table + */ +void +ntfs_toupper_unuse(p) + struct proc *p; +{ + /* get exclusive access */ + rw_enter_write(&ntfs_toupper_lock); - return (error); + ntfs_toupper_usecount--; + if (ntfs_toupper_usecount == 0) { + free(ntfs_toupper_tab, M_NTFSRDATA); + ntfs_toupper_tab = NULL; + } +#ifdef DIAGNOSTIC + else if (ntfs_toupper_usecount < 0) { + panic("ntfs_toupper_unuse(): use count negative: %d", + ntfs_toupper_usecount); + } +#endif + + /* release the lock */ + rw_exit_write(&ntfs_toupper_lock); } |