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
  7. add_dquot_ref
  8. reset_dquot_ptrs

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

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