Pull one more egcs 1.1.2 workaround.
[linux-2.6/linux-mips.git] / fs / libfs.c
blobea1ec8d093106742694184950d572e67aa012672
1 /*
2 * fs/libfs.c
3 * Library for filesystems writers.
4 */
6 #include <linux/pagemap.h>
7 #include <linux/smp_lock.h>
9 int simple_statfs(struct super_block *sb, struct statfs *buf)
11 buf->f_type = sb->s_magic;
12 buf->f_bsize = PAGE_CACHE_SIZE;
13 buf->f_namelen = NAME_MAX;
14 return 0;
18 * Lookup the data. This is trivial - if the dentry didn't already
19 * exist, we know it is negative.
22 struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry)
24 d_add(dentry, NULL);
25 return NULL;
28 int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
30 return 0;
33 int dcache_dir_open(struct inode *inode, struct file *file)
35 static struct qstr cursor_name = {.len = 1, .name = "."};
37 file->private_data = d_alloc(file->f_dentry, &cursor_name);
39 return file->private_data ? 0 : -ENOMEM;
42 int dcache_dir_close(struct inode *inode, struct file *file)
44 dput(file->private_data);
45 return 0;
48 loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
50 down(&file->f_dentry->d_inode->i_sem);
51 switch (origin) {
52 case 1:
53 offset += file->f_pos;
54 case 0:
55 if (offset >= 0)
56 break;
57 default:
58 up(&file->f_dentry->d_inode->i_sem);
59 return -EINVAL;
61 if (offset != file->f_pos) {
62 file->f_pos = offset;
63 if (file->f_pos >= 2) {
64 struct list_head *p;
65 struct dentry *cursor = file->private_data;
66 loff_t n = file->f_pos - 2;
68 spin_lock(&dcache_lock);
69 p = file->f_dentry->d_subdirs.next;
70 while (n && p != &file->f_dentry->d_subdirs) {
71 struct dentry *next;
72 next = list_entry(p, struct dentry, d_child);
73 if (!list_empty(&next->d_hash) && next->d_inode)
74 n--;
75 p = p->next;
77 list_del(&cursor->d_child);
78 list_add_tail(&cursor->d_child, p);
79 spin_unlock(&dcache_lock);
82 up(&file->f_dentry->d_inode->i_sem);
83 return offset;
86 /* Relationship between i_mode and the DT_xxx types */
87 static inline unsigned char dt_type(struct inode *inode)
89 return (inode->i_mode >> 12) & 15;
93 * Directory is locked and all positive dentries in it are safe, since
94 * for ramfs-type trees they can't go away without unlink() or rmdir(),
95 * both impossible due to the lock on directory.
98 int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
100 struct dentry *dentry = filp->f_dentry;
101 struct dentry *cursor = filp->private_data;
102 struct list_head *p, *q = &cursor->d_child;
103 ino_t ino;
104 int i = filp->f_pos;
106 switch (i) {
107 case 0:
108 ino = dentry->d_inode->i_ino;
109 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
110 break;
111 filp->f_pos++;
112 i++;
113 /* fallthrough */
114 case 1:
115 ino = parent_ino(dentry);
116 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
117 break;
118 filp->f_pos++;
119 i++;
120 /* fallthrough */
121 default:
122 spin_lock(&dcache_lock);
123 if (filp->f_pos == 2) {
124 list_del(q);
125 list_add(q, &dentry->d_subdirs);
127 for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
128 struct dentry *next;
129 next = list_entry(p, struct dentry, d_child);
130 if (list_empty(&next->d_hash) || !next->d_inode)
131 continue;
133 spin_unlock(&dcache_lock);
134 if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0)
135 return 0;
136 spin_lock(&dcache_lock);
137 /* next is still alive */
138 list_del(q);
139 list_add(q, p);
140 p = q;
141 filp->f_pos++;
143 spin_unlock(&dcache_lock);
145 return 0;
148 ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos)
150 return -EISDIR;
153 struct file_operations simple_dir_operations = {
154 .open = dcache_dir_open,
155 .release = dcache_dir_close,
156 .llseek = dcache_dir_lseek,
157 .read = generic_read_dir,
158 .readdir = dcache_readdir,
161 struct inode_operations simple_dir_inode_operations = {
162 .lookup = simple_lookup,
166 * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
167 * will never be mountable)
169 struct super_block *
170 get_sb_pseudo(struct file_system_type *fs_type, char *name,
171 struct super_operations *ops, unsigned long magic)
173 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
174 static struct super_operations default_ops = {.statfs = simple_statfs};
175 struct dentry *dentry;
176 struct inode *root;
177 struct qstr d_name = {.name = name, .len = strlen(name)};
179 if (IS_ERR(s))
180 return s;
182 s->s_flags = MS_NOUSER;
183 s->s_maxbytes = ~0ULL;
184 s->s_blocksize = 1024;
185 s->s_blocksize_bits = 10;
186 s->s_magic = magic;
187 s->s_op = ops ? ops : &default_ops;
188 root = new_inode(s);
189 if (!root)
190 goto Enomem;
191 root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
192 root->i_uid = root->i_gid = 0;
193 root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
194 dentry = d_alloc(NULL, &d_name);
195 if (!dentry) {
196 iput(root);
197 goto Enomem;
199 dentry->d_sb = s;
200 dentry->d_parent = dentry;
201 d_instantiate(dentry, root);
202 s->s_root = dentry;
203 s->s_flags |= MS_ACTIVE;
204 return s;
206 Enomem:
207 up_write(&s->s_umount);
208 deactivate_super(s);
209 return ERR_PTR(-ENOMEM);
212 int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
214 struct inode *inode = old_dentry->d_inode;
216 inode->i_nlink++;
217 atomic_inc(&inode->i_count);
218 dget(dentry);
219 d_instantiate(dentry, inode);
220 return 0;
223 static inline int simple_positive(struct dentry *dentry)
225 return dentry->d_inode && !d_unhashed(dentry);
228 int simple_empty(struct dentry *dentry)
230 struct dentry *child;
231 int ret = 0;
233 spin_lock(&dcache_lock);
234 list_for_each_entry(child, &dentry->d_subdirs, d_child)
235 if (simple_positive(child))
236 goto out;
237 ret = 1;
238 out:
239 spin_unlock(&dcache_lock);
240 return ret;
243 int simple_unlink(struct inode *dir, struct dentry *dentry)
245 struct inode *inode = dentry->d_inode;
247 inode->i_nlink--;
248 dput(dentry);
249 return 0;
252 int simple_rmdir(struct inode *dir, struct dentry *dentry)
254 if (!simple_empty(dentry))
255 return -ENOTEMPTY;
257 dentry->d_inode->i_nlink--;
258 simple_unlink(dir, dentry);
259 dir->i_nlink--;
260 return 0;
263 int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
264 struct inode *new_dir, struct dentry *new_dentry)
266 int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode);
268 if (!simple_empty(new_dentry))
269 return -ENOTEMPTY;
271 if (new_dentry->d_inode) {
272 simple_unlink(new_dir, new_dentry);
273 if (they_are_dirs)
274 old_dir->i_nlink--;
275 } else if (they_are_dirs) {
276 old_dir->i_nlink--;
277 new_dir->i_nlink++;
279 return 0;
282 int simple_readpage(struct file *file, struct page *page)
284 void *kaddr;
286 if (PageUptodate(page))
287 goto out;
289 kaddr = kmap_atomic(page, KM_USER0);
290 memset(kaddr, 0, PAGE_CACHE_SIZE);
291 kunmap_atomic(kaddr, KM_USER0);
292 flush_dcache_page(page);
293 SetPageUptodate(page);
294 out:
295 unlock_page(page);
296 return 0;
299 int simple_prepare_write(struct file *file, struct page *page,
300 unsigned from, unsigned to)
302 if (!PageUptodate(page)) {
303 if (to - from != PAGE_CACHE_SIZE) {
304 void *kaddr = kmap_atomic(page, KM_USER0);
305 memset(kaddr, 0, from);
306 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
307 flush_dcache_page(page);
308 kunmap_atomic(kaddr, KM_USER0);
310 SetPageUptodate(page);
312 return 0;
315 int simple_commit_write(struct file *file, struct page *page,
316 unsigned offset, unsigned to)
318 struct inode *inode = page->mapping->host;
319 loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
321 if (pos > inode->i_size)
322 inode->i_size = pos;
323 set_page_dirty(page);
324 return 0;