X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..04b8595b18b1b41ac7a206e4b3d51a635f8413d7:/bsd/kern/kern_acct.c diff --git a/bsd/kern/kern_acct.c b/bsd/kern/kern_acct.c index 516de08dc..aec90c9e0 100644 --- a/bsd/kern/kern_acct.c +++ b/bsd/kern/kern_acct.c @@ -116,7 +116,7 @@ */ comp_t encode_comp_t(uint32_t, uint32_t); void acctwatch(void *); -void acctwatch_funnel(void *); +void acct_init(void); /* * Accounting vnode pointer, and suspended accounting vnode pointer. States @@ -139,6 +139,21 @@ int acctsuspend = 2; /* stop accounting when < 2% free space left */ int acctresume = 4; /* resume when free space risen to > 4% */ int acctchkfreq = 15; /* frequency (in seconds) to check space */ + +static lck_grp_t *acct_subsys_lck_grp; +static lck_mtx_t *acct_subsys_mutex; + +#define ACCT_SUBSYS_LOCK() lck_mtx_lock(acct_subsys_mutex) +#define ACCT_SUBSYS_UNLOCK() lck_mtx_unlock(acct_subsys_mutex) + +void +acct_init(void) +{ + acct_subsys_lck_grp = lck_grp_alloc_init("acct", NULL); + acct_subsys_mutex = lck_mtx_alloc_init(acct_subsys_lck_grp, NULL); +} + + /* * Accounting system call. Written based on the specification and * previous implementation done by Mark Tinguely. @@ -191,21 +206,26 @@ acct(proc_t p, struct acct_args *uap, __unused int *retval) * If accounting was previously enabled, kill the old space-watcher, * close the file, and (if no new file was specified, leave). */ + ACCT_SUBSYS_LOCK(); if (acctp != NULLVP || suspend_acctp != NULLVP) { - untimeout(acctwatch_funnel, NULL); + untimeout(acctwatch, NULL); error = vn_close((acctp != NULLVP ? acctp : suspend_acctp), FWRITE, vfs_context_current()); acctp = suspend_acctp = NULLVP; } - if (uap->path == USER_ADDR_NULL) + if (uap->path == USER_ADDR_NULL) { + ACCT_SUBSYS_UNLOCK(); return (error); + } /* * Save the new accounting file vnode, and schedule the new * free space watcher. */ acctp = nd.ni_vp; + ACCT_SUBSYS_UNLOCK(); + acctwatch(NULL); return (error); } @@ -230,9 +250,12 @@ acct_process(proc_t p) struct tty *tp; /* If accounting isn't enabled, don't bother */ + ACCT_SUBSYS_LOCK(); vp = acctp; - if (vp == NULLVP) + if (vp == NULLVP) { + ACCT_SUBSYS_UNLOCK(); return (0); + } /* * Get process accounting information. @@ -301,6 +324,8 @@ acct_process(proc_t p) } kauth_cred_unref(&safecred); + ACCT_SUBSYS_UNLOCK(); + return (error); } @@ -342,16 +367,6 @@ encode_comp_t(uint32_t s, uint32_t us) return (exp); } -/* XXX The acctwatch() thread need to be protected by a mutex instead. */ -void -acctwatch_funnel(void *a) -{ - thread_funnel_set(kernel_flock, TRUE); - acctwatch(a); - thread_funnel_set(kernel_flock, FALSE); -} - - /* * Periodically check the file system to see if accounting * should be turned on or off. Beware the case where the vnode @@ -369,6 +384,7 @@ acctwatch(__unused void *a) VFSATTR_WANTED(&va, f_blocks); VFSATTR_WANTED(&va, f_bavail); + ACCT_SUBSYS_LOCK(); if (suspend_acctp != NULLVP) { /* * Resuming accounting when accounting is suspended, and the @@ -378,6 +394,7 @@ acctwatch(__unused void *a) if (suspend_acctp->v_type == VBAD) { (void) vn_close(suspend_acctp, FWRITE, vfs_context_kernel()); suspend_acctp = NULLVP; + ACCT_SUBSYS_UNLOCK(); return; } (void)vfs_getattr(suspend_acctp->v_mount, &va, ctx); @@ -395,6 +412,7 @@ acctwatch(__unused void *a) if (acctp->v_type == VBAD) { (void) vn_close(acctp, FWRITE, vfs_context_kernel()); acctp = NULLVP; + ACCT_SUBSYS_UNLOCK(); return; } (void)vfs_getattr(acctp->v_mount, &va, ctx); @@ -404,8 +422,10 @@ acctwatch(__unused void *a) log(LOG_NOTICE, "Accounting suspended\n"); } } else { + ACCT_SUBSYS_UNLOCK(); return; - } - - timeout(acctwatch_funnel, NULL, acctchkfreq * hz); + } + ACCT_SUBSYS_UNLOCK(); + + timeout(acctwatch, NULL, acctchkfreq * hz); }