summaryrefslogtreecommitdiffstats
path: root/fs/file_table.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
commit86464aed71025541805e7b1515541aee89879e33 (patch)
treee01a457a4912a8553bc65524aa3125d51f29f810 /fs/file_table.c
parent88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff)
Merge with Linux 2.2.1.
Diffstat (limited to 'fs/file_table.c')
-rw-r--r--fs/file_table.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index 200b6049b..cbc33634a 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -20,7 +20,7 @@ int max_files = NR_FILE;/* tunable */
/* Free list management, if you are here you must have f_count == 0 */
static struct file * free_filps = NULL;
-void insert_file_free(struct file *file)
+static void insert_file_free(struct file *file)
{
if((file->f_next = free_filps) != NULL)
free_filps->f_pprev = &file->f_next;
@@ -40,6 +40,15 @@ static inline void put_inuse(struct file *file)
file->f_pprev = &inuse_filps;
}
+/* It does not matter which list it is on. */
+static inline void remove_filp(struct file *file)
+{
+ if(file->f_next)
+ file->f_next->f_pprev = file->f_pprev;
+ *file->f_pprev = file->f_next;
+}
+
+
void __init file_table_init(void)
{
filp_cache = kmem_cache_create("filp", sizeof(struct file),
@@ -116,3 +125,25 @@ int init_private_file(struct file *filp, struct dentry *dentry, int mode)
else
return 0;
}
+
+void fput(struct file *file)
+{
+ int count = file->f_count-1;
+
+ if (!count) {
+ locks_remove_flock(file);
+ __fput(file);
+ file->f_count = 0;
+ remove_filp(file);
+ insert_file_free(file);
+ } else
+ file->f_count = count;
+}
+
+void put_filp(struct file *file)
+{
+ if(--file->f_count == 0) {
+ remove_filp(file);
+ insert_file_free(file);
+ }
+}