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 struct file * first_file;
  12 int nr_files = 0;
  13 
  14 static void insert_file_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  15 {
  16         file->f_next = first_file;
  17         file->f_prev = first_file->f_prev;
  18         file->f_next->f_prev = file;
  19         file->f_prev->f_next = file;
  20         first_file = file;
  21 }
  22 
  23 static void remove_file_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  24 {
  25         if (first_file == file)
  26                 first_file = first_file->f_next;
  27         if (file->f_next)
  28                 file->f_next->f_prev = file->f_prev;
  29         if (file->f_prev)
  30                 file->f_prev->f_next = file->f_next;
  31         file->f_next = file->f_prev = NULL;
  32 }
  33 
  34 static void put_last_free(struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36         remove_file_free(file);
  37         file->f_prev = first_file->f_prev;
  38         file->f_prev->f_next = file;
  39         file->f_next = first_file;
  40         file->f_next->f_prev = file;
  41 }
  42 
  43 void grow_files(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  44 {
  45         unsigned long page;
  46         struct file * file;
  47         int i;
  48 
  49         page = get_free_page(GFP_KERNEL);
  50         if (!page)
  51                 return;
  52         file = (struct file *) page;
  53         for (i=0; i < (PAGE_SIZE / sizeof(struct file)); i++, file++)
  54         {
  55                 if (!first_file)
  56                 {
  57                         file->f_next = file;
  58                         file->f_prev = file;
  59                         first_file = file;
  60                 }
  61                 else
  62                         insert_file_free(file);
  63         }
  64         nr_files += i;
  65 }
  66 
  67 unsigned long file_table_init(unsigned long start, unsigned long end)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         first_file = NULL;
  70         return start;
  71 }
  72 
  73 struct file * get_empty_filp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         int i;
  76         struct file * f;
  77 
  78         if (!first_file)
  79                 grow_files();
  80 repeat:
  81         for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
  82                 if (!f->f_count) {
  83                         remove_file_free(f);
  84                         memset(f,0,sizeof(*f));
  85                         put_last_free(f);
  86                         f->f_count = 1;
  87                         return f;
  88                 }
  89         if (nr_files < NR_FILE) {
  90                 grow_files();
  91                 goto repeat;
  92         }
  93         return NULL;
  94 }

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