linux-bk/fs/file_table.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/file_table.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *  Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
   6 */
   7
   8#include <linux/string.h>
   9#include <linux/slab.h>
  10#include <linux/file.h>
  11#include <linux/init.h>
  12#include <linux/module.h>
  13#include <linux/smp_lock.h>
  14#include <linux/iobuf.h>
  15#include <linux/fs.h>
  16#include <linux/security.h>
  17
  18/* sysctl tunables... */
  19struct files_stat_struct files_stat = {0, 0, NR_FILE};
  20
  21/* Here the new files go */
  22static LIST_HEAD(anon_list);
  23/* And here the free ones sit */
  24static LIST_HEAD(free_list);
  25/* public *and* exported. Not pretty! */
  26spinlock_t files_lock = SPIN_LOCK_UNLOCKED;
  27
  28/* Find an unused file structure and return a pointer to it.
  29 * Returns NULL, if there are no more free file structures or
  30 * we run out of memory.
  31 *
  32 * SMP-safe.
  33 */
  34struct file * get_empty_filp(void)
  35{
  36        static int old_max = 0;
  37        struct file * f;
  38
  39        file_list_lock();
  40        if (files_stat.nr_free_files > NR_RESERVED_FILES) {
  41        used_one:
  42                f = list_entry(free_list.next, struct file, f_list);
  43                list_del(&f->f_list);
  44                files_stat.nr_free_files--;
  45        new_one:
  46                memset(f, 0, sizeof(*f));
  47                if (security_ops->file_alloc_security(f)) {
  48                        list_add(&f->f_list, &free_list);
  49                        files_stat.nr_free_files++;
  50                        file_list_unlock();
  51                        return NULL;
  52                }
  53                atomic_set(&f->f_count,1);
  54                f->f_version = ++event;
  55                f->f_uid = current->fsuid;
  56                f->f_gid = current->fsgid;
  57                f->f_owner.lock = RW_LOCK_UNLOCKED;
  58                list_add(&f->f_list, &anon_list);
  59                file_list_unlock();
  60                return f;
  61        }
  62        /*
  63         * Use a reserved one if we're the superuser
  64         */
  65        if (files_stat.nr_free_files && !current->euid)
  66                goto used_one;
  67        /*
  68         * Allocate a new one if we're below the limit.
  69         */
  70        if (files_stat.nr_files < files_stat.max_files) {
  71                file_list_unlock();
  72                f = kmem_cache_alloc(filp_cachep, SLAB_KERNEL);
  73                file_list_lock();
  74                if (f) {
  75                        files_stat.nr_files++;
  76                        goto new_one;
  77                }
  78                /* Big problems... */
  79                printk(KERN_WARNING "VFS: filp allocation failed\n");
  80
  81        } else if (files_stat.max_files > old_max) {
  82                printk(KERN_INFO "VFS: file-max limit %d reached\n", files_stat.max_files);
  83                old_max = files_stat.max_files;
  84        }
  85        file_list_unlock();
  86        return NULL;
  87}
  88
  89/*
  90 * Clear and initialize a (private) struct file for the given dentry,
  91 * and call the open function (if any).  The caller must verify that
  92 * inode->i_fop is not NULL.
  93 */
  94int init_private_file(struct file *filp, struct dentry *dentry, int mode)
  95{
  96        memset(filp, 0, sizeof(*filp));
  97        filp->f_mode   = mode;
  98        atomic_set(&filp->f_count, 1);
  99        filp->f_dentry = dentry;
 100        filp->f_uid    = current->fsuid;
 101        filp->f_gid    = current->fsgid;
 102        filp->f_op     = dentry->d_inode->i_fop;
 103        if (filp->f_op->open)
 104                return filp->f_op->open(dentry->d_inode, filp);
 105        else
 106                return 0;
 107}
 108
 109void fput(struct file * file)
 110{
 111        if (atomic_dec_and_test(&file->f_count))
 112                __fput(file);
 113}
 114
 115/* __fput is called from task context when aio completion releases the last
 116 * last use of a struct file *.  Do not use otherwise.
 117 */
 118void __fput(struct file * file)
 119{
 120        struct dentry * dentry = file->f_dentry;
 121        struct vfsmount * mnt = file->f_vfsmnt;
 122        struct inode * inode = dentry->d_inode;
 123
 124        locks_remove_flock(file);
 125
 126        if (file->f_op && file->f_op->release)
 127                file->f_op->release(inode, file);
 128        security_ops->file_free_security(file);
 129        fops_put(file->f_op);
 130        if (file->f_mode & FMODE_WRITE)
 131                put_write_access(inode);
 132        file_list_lock();
 133        file->f_dentry = NULL;
 134        file->f_vfsmnt = NULL;
 135        list_del(&file->f_list);
 136        list_add(&file->f_list, &free_list);
 137        files_stat.nr_free_files++;
 138        file_list_unlock();
 139        dput(dentry);
 140        mntput(mnt);
 141}
 142
 143struct file * fget(unsigned int fd)
 144{
 145        struct file * file;
 146        struct files_struct *files = current->files;
 147
 148        read_lock(&files->file_lock);
 149        file = fcheck(fd);
 150        if (file)
 151                get_file(file);
 152        read_unlock(&files->file_lock);
 153        return file;
 154}
 155
 156/* Here. put_filp() is SMP-safe now. */
 157
 158void put_filp(struct file *file)
 159{
 160        if(atomic_dec_and_test(&file->f_count)) {
 161                security_ops->file_free_security(file);
 162                file_list_lock();
 163                list_del(&file->f_list);
 164                list_add(&file->f_list, &free_list);
 165                files_stat.nr_free_files++;
 166                file_list_unlock();
 167        }
 168}
 169
 170void file_move(struct file *file, struct list_head *list)
 171{
 172        if (!list)
 173                return;
 174        file_list_lock();
 175        list_del(&file->f_list);
 176        list_add(&file->f_list, list);
 177        file_list_unlock();
 178}
 179
 180int fs_may_remount_ro(struct super_block *sb)
 181{
 182        struct list_head *p;
 183
 184        /* Check that no files are currently opened for writing. */
 185        file_list_lock();
 186        list_for_each(p, &sb->s_files) {
 187                struct file *file = list_entry(p, struct file, f_list);
 188                struct inode *inode = file->f_dentry->d_inode;
 189
 190                /* File with pending delete? */
 191                if (inode->i_nlink == 0)
 192                        goto too_bad;
 193
 194                /* Writable file? */
 195                if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
 196                        goto too_bad;
 197        }
 198        file_list_unlock();
 199        return 1; /* Tis' cool bro. */
 200too_bad:
 201        file_list_unlock();
 202        return 0;
 203}
 204
 205void __init files_init(unsigned long mempages)
 206{ 
 207        int n; 
 208        /* One file with associated inode and dcache is very roughly 1K. 
 209         * Per default don't use more than 10% of our memory for files. 
 210         */ 
 211
 212        n = (mempages * (PAGE_SIZE / 1024)) / 10;
 213        files_stat.max_files = n; 
 214        if (files_stat.max_files < NR_FILE)
 215                files_stat.max_files = NR_FILE;
 216} 
 217
 218
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.