#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) |
|
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(). |
|
Definition at line 34 of file bank.c. Referenced by elsa_data_add(), and elsa_data_remove(). |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
elsa_data_add - Add a process to a given bank : pointer to a bank : 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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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. |