AUDIT: Add helper functions to allocate and free audit_buffers.
authorChris Wright <chrisw@osdl.org>
Fri, 6 May 2005 14:53:34 +0000 (15:53 +0100)
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 6 May 2005 14:53:34 +0000 (15:53 +0100)
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
kernel/audit.c

index 6f344b44d3d3e6320335427050aec9c04598ba23..e5bdba3e3ae1e9fcf3168060b6ef9acc8ababe34 100644 (file)
@@ -620,6 +620,42 @@ static int __init audit_enable(char *str)
 
 __setup("audit=", audit_enable);
 
+static void audit_buffer_free(struct audit_buffer *ab)
+{
+       unsigned long flags;
+
+       atomic_dec(&audit_backlog);
+       spin_lock_irqsave(&audit_freelist_lock, flags);
+       if (++audit_freelist_count > AUDIT_MAXFREE)
+               kfree(ab);
+       else
+               list_add(&ab->list, &audit_freelist);
+       spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
+{
+       unsigned long flags;
+       struct audit_buffer *ab = NULL;
+
+       spin_lock_irqsave(&audit_freelist_lock, flags);
+       if (!list_empty(&audit_freelist)) {
+               ab = list_entry(audit_freelist.next,
+                               struct audit_buffer, list);
+               list_del(&ab->list);
+               --audit_freelist_count;
+       }
+       spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+       if (!ab) {
+               ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+               if (!ab)
+                       goto out;
+       }
+       atomic_inc(&audit_backlog);
+out:
+       return ab;
+}
 
 /* Obtain an audit buffer.  This routine does locking to obtain the
  * audit buffer, but then no locking is required for calls to
@@ -630,7 +666,6 @@ __setup("audit=", audit_enable);
 struct audit_buffer *audit_log_start(struct audit_context *ctx)
 {
        struct audit_buffer     *ab     = NULL;
-       unsigned long           flags;
        struct timespec         t;
        unsigned int            serial;
 
@@ -649,23 +684,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
                return NULL;
        }
 
-       spin_lock_irqsave(&audit_freelist_lock, flags);
-       if (!list_empty(&audit_freelist)) {
-               ab = list_entry(audit_freelist.next,
-                               struct audit_buffer, list);
-               list_del(&ab->list);
-               --audit_freelist_count;
-       }
-       spin_unlock_irqrestore(&audit_freelist_lock, flags);
-
-       if (!ab)
-               ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+       ab = audit_buffer_alloc(GFP_ATOMIC);
        if (!ab) {
                audit_log_lost("out of memory in audit_log_start");
                return NULL;
        }
 
-       atomic_inc(&audit_backlog);
        skb_queue_head_init(&ab->sklist);
 
        ab->ctx   = ctx;
@@ -824,8 +848,6 @@ static void audit_log_end_irq(struct audit_buffer *ab)
  * be called in an irq context. */
 static void audit_log_end_fast(struct audit_buffer *ab)
 {
-       unsigned long flags;
-
        BUG_ON(in_irq());
        if (!ab)
                return;
@@ -836,14 +858,7 @@ static void audit_log_end_fast(struct audit_buffer *ab)
                if (audit_log_drain(ab))
                        return;
        }
-
-       atomic_dec(&audit_backlog);
-       spin_lock_irqsave(&audit_freelist_lock, flags);
-       if (++audit_freelist_count > AUDIT_MAXFREE)
-               kfree(ab);
-       else
-               list_add(&ab->list, &audit_freelist);
-       spin_unlock_irqrestore(&audit_freelist_lock, flags);
+       audit_buffer_free(ab);
 }
 
 /* Send or queue the message in the audit buffer, depending on the