root/fs/file_table.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. insert_file_free
  2. remove_file_free
  3. put_last_free
  4. grow_files
  5. file_table_init
  6. get_empty_filp

   1 /*
   2  *  linux/fs/file_table.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 #include <linux/fs.h>
   8 #include <linux/string.h>
   9 #include <linux/mm.h>
  10 
  11 /*
  12  * first_file points to a doubly linked list of all file structures in
  13  *            the system.
  14  * nr_files   holds the length of this list.
  15  */
  16 struct file * first_file = NULL;
  17 int nr_files = 0;
  18 
  19 /*
  20  * Insert a new file structure at the head of the list of available ones.
  21  */
  22 static void insert_file_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  23 {
  24         file->f_count = 0;
  25         file->f_next = first_file;
  26         file->f_prev = first_file->f_prev;
  27         file->f_next->f_prev = file;
  28         file->f_prev->f_next = file;
  29         first_file = file;
  30 }
  31 
  32 /*
  33  * Remove a file structure from the list of available ones.
  34  */
  35 static void remove_file_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  36 {
  37         if (first_file == file)
  38                 first_file = first_file->f_next;
  39         file->f_next->f_prev = file->f_prev;
  40         file->f_prev->f_next = file->f_next;
  41         file->f_next = file->f_prev = NULL;
  42 }
  43 
  44 /*
  45  * Insert a file structure at the end of the list of available ones.
  46  */
  47 static void put_last_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         file->f_prev = first_file->f_prev;
  50         file->f_prev->f_next = file;
  51         file->f_next = first_file;
  52         file->f_next->f_prev = file;
  53 }
  54 
  55 /*
  56  * Allocate a new memory page for file structures and
  57  * insert the new structures into the global list.
  58  * Returns 0, if there is no more memory, 1 otherwise.
  59  */
  60 static int grow_files(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62         struct file * file;
  63         int i;
  64 
  65         /*
  66          * We don't have to clear the page because we only look into
  67          * f_count, f_prev and f_next and they get initialized in
  68          * insert_file_free.  The rest of the file structure is cleared
  69          * by get_empty_filp before it is returned.
  70          */
  71         file = (struct file *) __get_free_page(GFP_KERNEL);
  72 
  73         if (!file)
  74                 return 0;
  75 
  76         nr_files += i = PAGE_SIZE/sizeof(struct file);
  77 
  78         if (!first_file)
  79                 file->f_count = 0,
  80                 file->f_next = file->f_prev = first_file = file++,
  81                 i--;
  82 
  83         for (; i ; i--)
  84                 insert_file_free(file++);
  85 
  86         return 1;
  87 }
  88 
  89 unsigned long file_table_init(unsigned long start, unsigned long end)
     /* [previous][next][first][last][top][bottom][index][help] */
  90 {
  91         return start;
  92 }
  93 
  94 /*
  95  * Find an unused file structure and return a pointer to it.
  96  * Returns NULL, if there are no more free file structures or
  97  * we run out of memory.
  98  */
  99 struct file * get_empty_filp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101         int i;
 102         struct file * f;
 103 
 104         /* if the return is taken, we are in deep trouble */
 105         if (!first_file && !grow_files())
 106                 return NULL;
 107 
 108         do {
 109                 for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
 110                         if (!f->f_count) {
 111                                 remove_file_free(f);
 112                                 memset(f,0,sizeof(*f));
 113                                 put_last_free(f);
 114                                 f->f_count = 1;
 115                                 f->f_version = ++event;
 116                                 return f;
 117                         }
 118         } while (nr_files < NR_FILE && grow_files());
 119 
 120         return NULL;
 121 }

/* [previous][next][first][last][top][bottom][index][help] */