summaryrefslogtreecommitdiffstats
path: root/sys/security
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2012-11-30 22:59:20 +0000
committerpjd <pjd@FreeBSD.org>2012-11-30 22:59:20 +0000
commitdc3cd3e3a48e1501c08be6ab05483e6941eccb9f (patch)
tree00fabb7b10a8789628c1e13f909eaab4224dec43 /sys/security
parent552da73086100a3e6f4af630f5d30067a2462d84 (diff)
downloadFreeBSD-src-dc3cd3e3a48e1501c08be6ab05483e6941eccb9f.zip
FreeBSD-src-dc3cd3e3a48e1501c08be6ab05483e6941eccb9f.tar.gz
IFp4 @208382:
Currently on each record write we call VFS_STATFS() to get available space on the file system as well as VOP_GETATTR() to get trail file size. We can assume that trail file is only updated by the audit worker, so instead of asking for file size on every write, get file size on trail switch only (it should be zero, but it's not expensive) and use global variable audit_size protected by the audit worker lock to keep track of trail file's size. This eliminates VOP_GETATTR() call for every write. VFS_STATFS() is satisfied from in-memory data (mount->mnt_stat), so shouldn't be expensive. Sponsored by: FreeBSD Foundation (auditdistd) MFC after: 2 weeks
Diffstat (limited to 'sys/security')
-rw-r--r--sys/security/audit/audit_worker.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/sys/security/audit/audit_worker.c b/sys/security/audit/audit_worker.c
index 6247e49..dd0eac7 100644
--- a/sys/security/audit/audit_worker.c
+++ b/sys/security/audit/audit_worker.c
@@ -88,6 +88,7 @@ static struct proc *audit_thread;
static int audit_file_rotate_wait;
static struct ucred *audit_cred;
static struct vnode *audit_vp;
+static off_t audit_size;
static struct sx audit_worker_lock;
#define AUDIT_WORKER_LOCK_INIT() sx_init(&audit_worker_lock, \
@@ -115,7 +116,6 @@ audit_record_write(struct vnode *vp, struct ucred *cred, void *data,
struct statfs *mnt_stat;
int error;
static int cur_fail;
- struct vattr vattr;
long temp;
AUDIT_WORKER_LOCK_ASSERT();
@@ -133,12 +133,6 @@ audit_record_write(struct vnode *vp, struct ucred *cred, void *data,
error = VFS_STATFS(vp->v_mount, mnt_stat);
if (error)
goto fail;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
- if (error)
- goto fail;
- audit_fstat.af_currsz = vattr.va_size;
/*
* We handle four different space-related limits:
@@ -196,7 +190,7 @@ audit_record_write(struct vnode *vp, struct ucred *cred, void *data,
* records may be generated before the daemon rotates the file.
*/
if ((audit_fstat.af_filesz != 0) && (audit_file_rotate_wait == 0) &&
- (vattr.va_size >= audit_fstat.af_filesz)) {
+ (audit_size >= audit_fstat.af_filesz)) {
AUDIT_WORKER_LOCK_ASSERT();
audit_file_rotate_wait = 1;
@@ -238,6 +232,8 @@ audit_record_write(struct vnode *vp, struct ucred *cred, void *data,
goto fail_enospc;
else if (error)
goto fail;
+ AUDIT_WORKER_LOCK_ASSERT();
+ audit_size += len;
/*
* Catch completion of a queue drain here; if we're draining and the
@@ -448,10 +444,20 @@ audit_rotate_vnode(struct ucred *cred, struct vnode *vp)
{
struct ucred *old_audit_cred;
struct vnode *old_audit_vp;
+ struct vattr vattr;
KASSERT((cred != NULL && vp != NULL) || (cred == NULL && vp == NULL),
("audit_rotate_vnode: cred %p vp %p", cred, vp));
+ if (vp != NULL) {
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ if (VOP_GETATTR(vp, &vattr, cred) != 0)
+ vattr.va_size = 0;
+ VOP_UNLOCK(vp, 0);
+ } else {
+ vattr.va_size = 0;
+ }
+
/*
* Rotate the vnode/cred, and clear the rotate flag so that we will
* send a rotate trigger if the new file fills.
@@ -461,6 +467,7 @@ audit_rotate_vnode(struct ucred *cred, struct vnode *vp)
old_audit_vp = audit_vp;
audit_cred = cred;
audit_vp = vp;
+ audit_size = vattr.va_size;
audit_file_rotate_wait = 0;
audit_enabled = (audit_vp != NULL);
AUDIT_WORKER_UNLOCK();
OpenPOWER on IntegriCloud