~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/file_table.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 
 15 /* sysctl tunables... */
 16 struct files_stat_struct files_stat = {0, 0, NR_FILE};
 17 
 18 /* Here the new files go */
 19 static LIST_HEAD(anon_list);
 20 /* And here the free ones sit */
 21 static LIST_HEAD(free_list);
 22 /* public *and* exported. Not pretty! */
 23 spinlock_t files_lock = SPIN_LOCK_UNLOCKED;
 24 
 25 /* Find an unused file structure and return a pointer to it.
 26  * Returns NULL, if there are no more free file structures or
 27  * we run out of memory.
 28  *
 29  * SMP-safe.
 30  */
 31 struct file * get_empty_filp(void)
 32 {
 33         static int old_max = 0;
 34         struct file * f;
 35 
 36         file_list_lock();
 37         if (files_stat.nr_free_files > NR_RESERVED_FILES) {
 38         used_one:
 39                 f = list_entry(free_list.next, struct file, f_list);
 40                 list_del(&f->f_list);
 41                 files_stat.nr_free_files--;
 42         new_one:
 43                 memset(f, 0, sizeof(*f));
 44                 atomic_set(&f->f_count,1);
 45                 f->f_version = ++event;
 46                 f->f_uid = current->fsuid;
 47                 f->f_gid = current->fsgid;
 48                 list_add(&f->f_list, &anon_list);
 49                 file_list_unlock();
 50                 return f;
 51         }
 52         /*
 53          * Use a reserved one if we're the superuser
 54          */
 55         if (files_stat.nr_free_files && !current->euid)
 56                 goto used_one;
 57         /*
 58          * Allocate a new one if we're below the limit.
 59          */
 60         if (files_stat.nr_files < files_stat.max_files) {
 61                 file_list_unlock();
 62                 f = kmem_cache_alloc(filp_cachep, SLAB_KERNEL);
 63                 file_list_lock();
 64                 if (f) {
 65                         files_stat.nr_files++;
 66                         goto new_one;
 67                 }
 68                 /* Big problems... */
 69                 printk("VFS: filp allocation failed\n");
 70 
 71         } else if (files_stat.max_files > old_max) {
 72                 printk("VFS: file-max limit %d reached\n", files_stat.max_files);
 73                 old_max = files_stat.max_files;
 74         }
 75         file_list_unlock();
 76         return NULL;
 77 }
 78 
 79 /*
 80  * Clear and initialize a (private) struct file for the given dentry,
 81  * and call the open function (if any).  The caller must verify that
 82  * inode->i_fop is not NULL.
 83  */
 84 int init_private_file(struct file *filp, struct dentry *dentry, int mode)
 85 {
 86         memset(filp, 0, sizeof(*filp));
 87         filp->f_mode   = mode;
 88         atomic_set(&filp->f_count, 1);
 89         filp->f_dentry = dentry;
 90         filp->f_uid    = current->fsuid;
 91         filp->f_gid    = current->fsgid;
 92         filp->f_op     = dentry->d_inode->i_fop;
 93         if (filp->f_op->open)
 94                 return filp->f_op->open(dentry->d_inode, filp);
 95         else
 96                 return 0;
 97 }
 98 
 99 void fput(struct file * file)
100 {
101         struct dentry * dentry = file->f_dentry;
102         struct vfsmount * mnt = file->f_vfsmnt;
103         struct inode * inode = dentry->d_inode;
104 
105         if (atomic_dec_and_test(&file->f_count)) {
106                 locks_remove_flock(file);
107                 if (file->f_op && file->f_op->release)
108                         file->f_op->release(inode, file);
109                 fops_put(file->f_op);
110                 file->f_dentry = NULL;
111                 file->f_vfsmnt = NULL;
112                 if (file->f_mode & FMODE_WRITE)
113                         put_write_access(inode);
114                 dput(dentry);
115                 if (mnt)
116                         mntput(mnt);
117                 file_list_lock();
118                 list_del(&file->f_list);
119                 list_add(&file->f_list, &free_list);
120                 files_stat.nr_free_files++;
121                 file_list_unlock();
122         }
123 }
124 
125 struct file * fget(unsigned int fd)
126 {
127         struct file * file;
128         struct files_struct *files = current->files;
129 
130         read_lock(&files->file_lock);
131         file = fcheck(fd);
132         if (file)
133                 get_file(file);
134         read_unlock(&files->file_lock);
135         return file;
136 }
137 
138 /* Here. put_filp() is SMP-safe now. */
139 
140 void put_filp(struct file *file)
141 {
142         if(atomic_dec_and_test(&file->f_count)) {
143                 file_list_lock();
144                 list_del(&file->f_list);
145                 list_add(&file->f_list, &free_list);
146                 files_stat.nr_free_files++;
147                 file_list_unlock();
148         }
149 }
150 
151 void file_move(struct file *file, struct list_head *list)
152 {
153         if (!list)
154                 return;
155         file_list_lock();
156         list_del(&file->f_list);
157         list_add(&file->f_list, list);
158         file_list_unlock();
159 }
160 
161 void file_moveto(struct file *new, struct file *old)
162 {
163         file_list_lock();
164         list_del(&new->f_list);
165         list_add(&new->f_list, &old->f_list);
166         file_list_unlock();
167 }
168 
169 int fs_may_remount_ro(struct super_block *sb)
170 {
171         struct list_head *p;
172 
173         /* Check that no files are currently opened for writing. */
174         file_list_lock();
175         for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
176                 struct file *file = list_entry(p, struct file, f_list);
177                 struct inode *inode;
178 
179                 if (!file->f_dentry)
180                         continue;
181 
182                 inode = file->f_dentry->d_inode;
183 
184                 /* File with pending delete? */
185                 if (inode->i_nlink == 0)
186                         goto too_bad;
187 
188                 /* Writable file? */
189                 if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
190                         goto too_bad;
191         }
192         file_list_unlock();
193         return 1; /* Tis' cool bro. */
194 too_bad:
195         file_list_unlock();
196         return 0;
197 }
198 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.