2 * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
6 #include "linux/slab.h"
7 #include "linux/list.h"
8 #include "linux/spinlock.h"
10 #include "linux/errno.h"
11 #include "filehandle.h"
13 #include "kern_util.h"
15 static spinlock_t open_files_lock = SPIN_LOCK_UNLOCKED;
16 static struct list_head open_files = LIST_HEAD_INIT(open_files);
18 #define NUM_RECLAIM 128
20 static void reclaim_fds(void)
22 struct file_handle *victim;
23 int closed = NUM_RECLAIM;
25 spin_lock(&open_files_lock);
26 while(!list_empty(&open_files) && closed--){
27 victim = list_entry(open_files.prev, struct file_handle, list);
28 os_close_file(victim->fd);
30 list_del_init(&victim->list);
32 spin_unlock(&open_files_lock);
35 int open_file(char *name, struct openflags flags, int mode)
39 fd = os_open_file(name, flags, mode);
44 fd = os_open_file(name, flags, mode);
49 void *open_dir(char *file)
54 dir = os_open_dir(file, &err);
62 dir = os_open_dir(file, &err);
69 void not_reclaimable(struct file_handle *fh)
73 if(fh->get_name == NULL)
76 if(list_empty(&fh->list)){
77 name = (*fh->get_name)(fh->inode);
79 fh->fd = open_file(name, fh->flags, 0);
82 else printk("File descriptor %d has no name\n", fh->fd);
85 spin_lock(&open_files_lock);
86 list_del_init(&fh->list);
87 spin_unlock(&open_files_lock);
91 void is_reclaimable(struct file_handle *fh, char *(name_proc)(struct inode *),
94 fh->get_name = name_proc;
97 spin_lock(&open_files_lock);
98 list_add(&fh->list, &open_files);
99 spin_unlock(&open_files_lock);
102 static int active_handle(struct file_handle *fh)
107 if(!list_empty(&fh->list))
108 list_move(&fh->list, &open_files);
113 if(fh->inode == NULL)
116 name = (*fh->get_name)(fh->inode);
120 fd = open_file(name, fh->flags, 0);
126 is_reclaimable(fh, fh->get_name, fh->inode);
131 int filehandle_fd(struct file_handle *fh)
135 err = active_handle(fh);
142 static void init_fh(struct file_handle *fh, int fd, struct openflags flags)
145 *fh = ((struct file_handle) { .list = LIST_HEAD_INIT(fh->list),
152 int open_filehandle(char *name, struct openflags flags, int mode,
153 struct file_handle *fh)
157 fd = open_file(name, flags, mode);
161 init_fh(fh, fd, flags);
165 int close_file(struct file_handle *fh)
167 spin_lock(&open_files_lock);
169 spin_unlock(&open_files_lock);
171 os_close_file(fh->fd);
177 int read_file(struct file_handle *fh, unsigned long long offset, char *buf,
182 err = active_handle(fh);
186 err = os_seek_file(fh->fd, offset);
190 return(os_read_file(fh->fd, buf, len));
193 int write_file(struct file_handle *fh, unsigned long long offset,
194 const char *buf, int len)
198 err = active_handle(fh);
203 err = os_seek_file(fh->fd, offset);
207 return(os_write_file(fh->fd, buf, len));
210 int truncate_file(struct file_handle *fh, unsigned long long size)
214 err = active_handle(fh);
218 return(os_truncate_fd(fh->fd, size));
221 int make_pipe(struct file_handle *fhs)
225 err = os_pipe(fds, 1, 1);
226 if(err && (err != -EMFILE))
231 err = os_pipe(fds, 1, 1);
236 init_fh(&fhs[0], fds[0], OPENFLAGS());
237 init_fh(&fhs[1], fds[1], OPENFLAGS());
242 * Overrides for Emacs so that we follow Linus's tabbing style.
243 * Emacs will notice this stuff at the end of the file and automatically
244 * adjust the settings for this buffer only. This must remain at the end
246 * ---------------------------------------------------------------------------
248 * c-file-style: "linux"