svn commit: r243722 - head/sys/security/audit

Pawel Jakub Dawidek pjd at FreeBSD.org
Fri Nov 30 22:59:21 UTC 2012


Author: pjd
Date: Fri Nov 30 22:59:20 2012
New Revision: 243722
URL: http://svnweb.freebsd.org/changeset/base/243722

Log:
  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

Modified:
  head/sys/security/audit/audit_worker.c

Modified: head/sys/security/audit/audit_worker.c
==============================================================================
--- head/sys/security/audit/audit_worker.c	Fri Nov 30 22:54:14 2012	(r243721)
+++ head/sys/security/audit/audit_worker.c	Fri Nov 30 22:59:20 2012	(r243722)
@@ -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, str
 	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, str
 	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, str
 	 * 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, str
 		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, s
 {
 	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, s
 	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();


More information about the svn-src-all mailing list