Main Page   File List   File Members  

bank.c File Reference

#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/bank.h>
#include <asm/bug.h>

Go to the source code of this file.

Defines

#define dprintk(format)
#define ELSACCT_MIN_PID   1024

Functions

elsa_bank * elsa_bank_alloc (void)
void elsa_bank_free (struct elsa_bank *b)
int elsa_bank_add (struct bank_root *br, struct elsa_bank *b, int(*fn)(int, struct elsa_bank *, struct elsa_data *), void *info)
int elsa_bank_remove (struct elsa_bank *b)
elsa_data * elsa_data_alloc (void)
void elsa_data_free (struct elsa_data *d)
int elsa_data_add (struct elsa_bank *b, struct elsa_data *d)
int elsa_data_remove (struct elsa_bank *b, struct elsa_data *d)
elsa_bank * elsa_get_bank (struct bank_root *br, __u32 bid)
elsa_data * elsa_get_data (pid_t pid, __u32 bid)
 EXPORT_SYMBOL (elsa_bank_alloc)


Define Documentation

#define dprintk format   
 

Definition at line 31 of file bank.c.

Referenced by elsa_bank_add(), elsa_bank_free(), elsa_bank_remove(), elsa_data_add(), elsa_data_free(), and elsacct_ioctl().

#define ELSACCT_MIN_PID   1024
 

Definition at line 34 of file bank.c.

Referenced by elsa_data_add(), and elsa_data_remove().


Function Documentation

int elsa_bank_add struct bank_root *    br,
struct elsa_bank *    b,
int(*    fn)(int, struct elsa_bank *, struct elsa_data *),
void *    info
 

elsa_bank_add - Add a new bank to a bank's root @br: a pointer to bank's root @b: a pointer to a bank @fn: pointer to a callback called when bank or data are destroyed @info: pointer that can be used to store information

Description: Add a new bank in the bank_root. It associates a callback to a bank. The callback will be called each time a bank or a data will be removed. pointer @info can be used to store usefull informations at bank level.

Definition at line 102 of file bank.c.

References dprintk.

Referenced by elsacct_ioctl().

00106 {
00107         /* 
00108          * give it an id. As it must be unique. As this function is only 
00109          * called from ioctl (drivers/erlsacct/elsacct.c) which is protected
00110          * by a spinlock, we know that only one instance will be execute. 
00111          * Currently we only used next_bid field but this mechnism 
00112          * can give problems if we use many banks and the bid go through
00113          * its maximum  
00114          */
00115         b->bid = br->next_bid++;
00116 
00117         if (b->bid <= 0) {
00118                 printk("elsa_bank_alloc: can not find bank identifier\n");
00119                 return 0;
00120         }
00121 
00122         /* Initialize fields */
00123         b->info = info;
00124         b->callback = fn;
00125 
00126         /* 
00127          * add the new bank to the list of banks 
00128          */
00129         list_add(&(b->bank_list), &(br->bank_head));
00130 
00131         dprintk("elsa_bank_alloc: bank #%d created\n", b->bid);
00132 
00133         return b->bid;
00134 }

struct elsa_bank* elsa_bank_alloc void   
 

elsa_bank_alloc - Allocates a new bank

Description: allocates a new bank and returns the new created bank.

Definition at line 48 of file bank.c.

References elsa_bank_alloc().

Referenced by elsa_bank_alloc(), and elsacct_ioctl().

00049 {
00050         struct elsa_bank *b;
00051 
00052         /* allocate space for the new bank */
00053         b = (struct elsa_bank *)kmalloc(sizeof(struct elsa_bank), GFP_KERNEL);
00054         if (!b) {
00055                 printk("elsa_bank_alloc: cannot allocate space\n");
00056                 return NULL;
00057         }
00058 
00059         /* Initialize fields */
00060         b->info = NULL;
00061         b->callback = NULL;
00062         INIT_LIST_HEAD(&(b->data_head));
00063 
00064         return b;
00065 }

void elsa_bank_free struct elsa_bank *    b
 

elsa_bank_free - Frees space occupied by a bank. @bank: a pointer to the bank to delete

Description: Free space used by bank

Definition at line 73 of file bank.c.

References dprintk.

Referenced by elsacct_ioctl(), and elsacct_process_remove().

00074 {
00075         /* 
00076          * Before releasing kernel memory occupied by the bank
00077          * we can do some action. We do it here instead of 
00078          * elsa_bank_remove() because elsa_bank_remove() is
00079          * called in a spinlock and the callback write records into
00080          * a file (and so cannot be done in a spinlock)
00081          */
00082         if (b->callback) {
00083                 (b->callback) (ELSA_BANK_CALLBACK, b, NULL);
00084         }
00085 
00086         dprintk("elsa_bank_free: bank released\n");
00087         kfree(b);
00088 }

int elsa_bank_remove struct elsa_bank *    b
 

elsa_bank_remove - remove a bank from the list of banks @b: a pointer to a bank

Description: remove a bank from a bank_root and returns the identifier of the removed bank. When this function is called bank _MUST_ be empty. Here are different steps of the operation: 1) Write accounting information 2) Remove it from the list of banks

Definition at line 147 of file bank.c.

References dprintk.

Referenced by elsacct_ioctl(), and elsacct_process_remove().

00148 {
00149         BUG_ON(b == NULL);
00150         BUG_ON(!list_empty(&b->data_head));
00151 
00152         /* 
00153          * remove bank from the bank's list
00154          */
00155         list_del(&(b->bank_list));
00156 
00157         dprintk("elsa_bank_remove: bank #%d removed\n", b->bid);
00158 
00159         return b->bid;
00160 }

int elsa_data_add struct elsa_bank *    b,
struct elsa_data *    d
 

elsa_data_add - Add a process to a given bank : pointer to a bank : pointer to a process

Description: add a data to a bank by setting lists. Other fields are unchanged If an error is encountered, a negative value is returned. It can not return 0. Here are steps to perform: 1) Check arguments 2) Check if process is already in the bank 3) Initialize its fields 4) Return BID

Definition at line 216 of file bank.c.

References dprintk, and ELSACCT_MIN_PID.

Referenced by elsacct_ioctl(), and elsacct_process_copy().

00217 {
00218         static int present;
00219 
00220         if (!b || !d || !(d->process)) {
00221                 dprintk("elsa_data_add: Wrong parameters\n");
00222                 return -EINVAL;
00223         }
00224 
00225         /* Bank ID cannot be equal to 0 */
00226         BUG_ON(b->bid == 0);
00227 
00228         if (d->process->pid < ELSACCT_MIN_PID) {
00229                 dprintk("elsa_data_add: PID < %d\n", ELSACCT_MIN_PID);
00230                 return -EINVAL;
00231         }
00232 
00233         /* check if process is already present */
00234         present = elsa_process_present(d->process, b);
00235         if (present) {
00236                 /* Process already in the bank, so we can not add it */
00237                 return -EPERM;
00238         }
00239 
00240         /* Set BID */
00241         d->bid = b->bid;
00242 
00243         /* Add data in the list of bank's data */
00244         list_add(&(d->data_list), &(b->data_head));
00245 
00246         /* 
00247          * Add data in the list of process's bank. We modify task struct so we 
00248          * need to protect that.
00249          */
00250         write_lock_irq(&tasklist_lock);
00251         list_add(&(d->bank_list), &(d->process->bank_head));
00252         write_unlock_irq(&tasklist_lock);
00253 
00254         dprintk("elsa_data_add: Add process #%d to bank #%d\n", d->process->pid,
00255                 b->bid);
00256 
00257         return b->bid;
00258 }

struct elsa_data* elsa_data_alloc void   
 

elsa_data_alloc - Allocates a new data

Description: allocates a new data and returns the new created item. If an error is encountered NULL is returned. Here are different steps of the operation: 1) Allocate space for the new data 2) Initialize different fields

Definition at line 171 of file bank.c.

References elsa_data_alloc().

Referenced by elsa_data_alloc(), elsacct_ioctl(), and elsacct_process_copy().

00172 {
00173         static struct elsa_data *d;
00174 
00175         /* allocate space for the new data */
00176         d = (struct elsa_data *)kmalloc(sizeof(struct elsa_data), GFP_KERNEL);
00177         if (!d) {
00178                 printk("elsa_data_alloc: cannot allocate space\n");
00179                 return NULL;
00180         }
00181 
00182         /* Initialize fields */
00183         d->bid = 0;
00184         d->process = NULL;
00185         INIT_LIST_HEAD(&(d->data_list));
00186         INIT_LIST_HEAD(&(d->bank_list));
00187 
00188         return d;
00189 }

void elsa_data_free struct elsa_data *    d
 

elsa_data_free - Free data @d: pointer to data to be removed

Description: releases memory used by data.

Definition at line 197 of file bank.c.

References dprintk.

Referenced by elsacct_ioctl(), elsacct_process_copy(), and elsacct_process_remove().

00198 {
00199         dprintk("elsa_data_free: data released\n");
00200         kfree(d);
00201 }

int elsa_data_remove struct elsa_bank *    b,
struct elsa_data *    d
 

elsa_data_remove - Remove a process to a given bank @b: pointer to the bank @d: pointer to the process

Description: removes a given process from a given bank. Return 0 if succedeed, BID of the bank if it is empty and negative value otherwise

Definition at line 269 of file bank.c.

References ELSACCT_MIN_PID.

Referenced by elsacct_ioctl(), and elsacct_process_remove().

00270 {
00271 
00272         if (!d)
00273                 return -EINVAL;
00274 
00275         BUG_ON(d->process->pid < ELSACCT_MIN_PID);
00276 
00277         /* callback, we are in the child so callback code */
00278         if (b && b->callback) {
00279                 (b->callback) (ELSA_DATA_CALLBACK, b, d);
00280         }
00281 
00282         /* remove data from the list of data */
00283         list_del(&d->data_list);
00284 
00285         /* Need access to head_list in task_struct */
00286         /* We are in a spin_lock */
00287         write_lock_irq(&tasklist_lock);
00288         list_del(&d->bank_list);
00289         write_unlock_irq(&tasklist_lock);
00290 
00291         if (list_empty(&(b->data_head)))
00292                 /* bank is empty so we return its BID */
00293                 return b->bid;
00294 
00295         return 0;               /* sucess and bank isn't empty */
00296 }

struct elsa_bank* elsa_get_bank struct bank_root *    br,
__u32    bid
 

elsa_get_bank - Returns a pointer to a bank @br: pointer to the root of banks @bid: the identifier of a bank

Description: finds the bank with given ID in the list of banks

Definition at line 305 of file bank.c.

Referenced by elsacct_ioctl(), elsacct_process_copy(), and elsacct_process_remove().

00306 {
00307         static struct list_head *entry;
00308         static struct elsa_bank *b;
00309 
00310         if (bid == 0)
00311                 return NULL;
00312 
00313         /*
00314          * We traverse the list searching for entries without changing
00315          * the list itself, so we use read_lock_irqsave
00316          */
00317         list_for_each(entry, &(br->bank_head)) {
00318                 b = list_entry(entry, struct elsa_bank, bank_list);
00319                 if (b->bid == bid) {
00320                         return b;
00321                 }
00322         }
00323 
00324         /* We don't find the bank with corresponding BID */
00325         return NULL;
00326 }

struct elsa_data* elsa_get_data pid_t    pid,
__u32    bid
 

elsa_get_data - Returns a pointer to an &elsa_data @pid: The identifier of the process @bid: The identifier of a bank

Description: returns a pointer to the container of a given pid in a given bank. If the data isn't found, NULL is returned.

Definition at line 336 of file bank.c.

Referenced by elsacct_ioctl().

00337 {
00338         static struct list_head *entry; /* entry == NULL */
00339         static struct task_struct *p;   /* p == NULL */
00340         static struct elsa_data *d;     /* d == NULL */
00341 
00342         read_lock(&tasklist_lock);
00343         p = find_task_by_pid(pid);
00344         read_unlock(&tasklist_lock);
00345 
00346         if ((p == NULL) || (bid == 0))
00347                 return NULL;
00348 
00349         list_for_each(entry, &(p->bank_head)) {
00350                 d = list_entry(entry, struct elsa_data, bank_list);
00351                 /*  bank can not be empty */
00352                 BUG_ON(d == NULL);
00353                 if (d->bid == bid) {
00354                         /* Got it */
00355                         return d;
00356                 }
00357         }
00358 
00359         return NULL;
00360 }

EXPORT_SYMBOL elsa_bank_alloc   
 

elsa_get_first - Returns a pointer to the first element of a list @head: a pointer to the head of a list

Description: returns a pointer to the first data in a list. If list is empty, NULL is returned.


Generated on Wed Jul 7 08:31:37 2004 for Enhanced Linux System Accounting by doxygen1.2.18