OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [file_table.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1627 jcastillo
/*
2
 *  linux/fs/file_table.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 */
6
 
7
#include <linux/config.h>
8
#include <linux/stddef.h>
9
#include <linux/fs.h>
10
#include <linux/string.h>
11
#include <linux/mm.h>
12
 
13
/*
14
 * first_file points to a doubly linked list of all file structures in
15
 *            the system.
16
 * nr_files   holds the length of this list.
17
 */
18
struct file * first_file = NULL;
19
int nr_files = 0;
20
int max_files = NR_FILE;
21
 
22
/*
23
 * Insert a new file structure at the head of the list of available ones.
24
 */
25
static inline void insert_file_free(struct file *file)
26
{
27
        struct file *next, *prev;
28
 
29
        next = first_file;
30
        first_file = file;
31
        file->f_count = 0;
32
        prev = next->f_prev;
33
        file->f_next = next;
34
        next->f_prev = file;
35
        file->f_prev = prev;
36
        prev->f_next = file;
37
}
38
 
39
/*
40
 * Remove a file structure from the list of available ones.
41
 */
42
static inline void remove_file_free(struct file *file)
43
{
44
        struct file *next, *prev;
45
 
46
        next = file->f_next;
47
        prev = file->f_prev;
48
        file->f_next = file->f_prev = NULL;
49
        if (first_file == file)
50
                first_file = next;
51
        next->f_prev = prev;
52
        prev->f_next = next;
53
}
54
 
55
/*
56
 * Insert a file structure at the end of the list of available ones.
57
 */
58
static inline void put_last_free(struct file *file)
59
{
60
        struct file *next, *prev;
61
 
62
        next = first_file;
63
        file->f_next = next;
64
        prev = next->f_prev;
65
        next->f_prev = file;
66
        file->f_prev = prev;
67
        prev->f_next = file;
68
}
69
 
70
/*
71
 * Allocate a new memory page for file structures and
72
 * insert the new structures into the global list.
73
 * Returns 0, if there is no more memory, 1 otherwise.
74
 */
75
static int grow_files(void)
76
{
77
        struct file * file;
78
        int i;
79
 
80
        /*
81
         * We don't have to clear the page because we only look into
82
         * f_count, f_prev and f_next and they get initialized in
83
         * insert_file_free.  The rest of the file structure is cleared
84
         * by get_empty_filp before it is returned.
85
         */
86
        file = (struct file *) __get_free_page(GFP_KERNEL);
87
 
88
        if (!file)
89
                return 0;
90
 
91
        nr_files += i = PAGE_SIZE/sizeof(struct file);
92
 
93
        if (!first_file)
94
                file->f_count = 0,
95
                file->f_next = file->f_prev = first_file = file++,
96
                i--;
97
 
98
        for (; i ; i--)
99
                insert_file_free(file++);
100
 
101
        return 1;
102
}
103
 
104
unsigned long file_table_init(unsigned long start, unsigned long end)
105
{
106
        return start;
107
}
108
 
109
/*
110
 * Find an unused file structure and return a pointer to it.
111
 * Returns NULL, if there are no more free file structures or
112
 * we run out of memory.
113
 */
114
struct file * get_empty_filp(void)
115
{
116
        int i;
117
        int max = max_files;
118
        struct file * f;
119
 
120
        /*
121
         * Reserve a few files for the super-user..
122
         */
123
        if (current->euid)
124
                max -= 10;
125
 
126
        /* if the return is taken, we are in deep trouble */
127
        if (!first_file && !grow_files())
128
                return NULL;
129
 
130
        do {
131
                for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
132
                        if (!f->f_count) {
133
                                /* The f_next pointer is followed by the f_prev pointer */
134
                                memset(f, 0, offsetof(struct file, f_next));
135
                                memset(&f->f_prev + 1, 0, sizeof(*f) - sizeof(f->f_prev) - offsetof(struct file, f_prev));
136
                                f->f_count = 1;
137
                                f->f_version = ++event;
138
                                first_file = f->f_next;
139
                                return f;
140
                        }
141
        } while (nr_files < max && grow_files());
142
 
143
        return NULL;
144
}
145
 
146
#ifdef CONFIG_QUOTA
147
 
148
void add_dquot_ref(kdev_t dev, short type)
149
{
150
        struct file *filp;
151
        int cnt;
152
 
153
        for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) {
154
                if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev)
155
                        continue;
156
                if (filp->f_mode & FMODE_WRITE && filp->f_inode->i_sb->dq_op) {
157
                        filp->f_inode->i_sb->dq_op->initialize(filp->f_inode, type);
158
                        filp->f_inode->i_flags |= S_WRITE;
159
                }
160
        }
161
}
162
 
163
void reset_dquot_ptrs(kdev_t dev, short type)
164
{
165
        struct file *filp;
166
        int cnt;
167
 
168
        for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) {
169
                if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev)
170
                        continue;
171
                if (IS_WRITABLE(filp->f_inode)) {
172
                        filp->f_inode->i_dquot[type] = NODQUOT;
173
                        filp->f_inode->i_flags &= ~S_WRITE;
174
                }
175
        }
176
}
177
 
178
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.