file_table.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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