blob: ea1f37d4fc5867deb21f46e6539721cb70dd42a5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
Artem B. Bityutskiy2f0077e2005-09-27 14:17:32 +010010 * $Id: fs.c,v 1.66 2005/09/27 13:17:29 dedekind Exp $
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 *
12 */
13
Randy Dunlap16f7e0f2006-01-11 12:17:46 -080014#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/fs.h>
19#include <linux/list.h>
20#include <linux/mtd/mtd.h>
21#include <linux/pagemap.h>
22#include <linux/slab.h>
23#include <linux/vmalloc.h>
24#include <linux/vfs.h>
25#include <linux/crc32.h>
26#include "nodelist.h"
27
28static int jffs2_flash_setup(struct jffs2_sb_info *c);
29
30static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
31{
32 struct jffs2_full_dnode *old_metadata, *new_metadata;
33 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
34 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
35 struct jffs2_raw_inode *ri;
36 unsigned short dev;
37 unsigned char *mdata = NULL;
38 int mdatalen = 0;
39 unsigned int ivalid;
40 uint32_t phys_ofs, alloclen;
41 int ret;
42 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
43 ret = inode_change_ok(inode, iattr);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000044 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 return ret;
46
47 /* Special cases - we don't want more than one data node
48 for these types on the medium at any time. So setattr
49 must read the original data associated with the node
50 (i.e. the device numbers or the target name) and write
51 it out again with the appropriate data attached */
52 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
53 /* For these, we don't actually need to read the old node */
54 dev = old_encode_dev(inode->i_rdev);
55 mdata = (char *)&dev;
56 mdatalen = sizeof(dev);
57 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
58 } else if (S_ISLNK(inode->i_mode)) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010059 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 mdatalen = f->metadata->size;
61 mdata = kmalloc(f->metadata->size, GFP_USER);
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010062 if (!mdata) {
63 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 return -ENOMEM;
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010065 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
67 if (ret) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010068 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069 kfree(mdata);
70 return ret;
71 }
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010072 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
74 }
75
76 ri = jffs2_alloc_raw_inode();
77 if (!ri) {
78 if (S_ISLNK(inode->i_mode))
79 kfree(mdata);
80 return -ENOMEM;
81 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000082
Ferenc Havasie631ddb2005-09-07 09:35:26 +010083 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
84 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 if (ret) {
86 jffs2_free_raw_inode(ri);
87 if (S_ISLNK(inode->i_mode & S_IFMT))
88 kfree(mdata);
89 return ret;
90 }
91 down(&f->sem);
92 ivalid = iattr->ia_valid;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
95 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
96 ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
97 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
98
99 ri->ino = cpu_to_je32(inode->i_ino);
100 ri->version = cpu_to_je32(++f->highest_version);
101
102 ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
103 ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
104
105 if (ivalid & ATTR_MODE)
106 if (iattr->ia_mode & S_ISGID &&
107 !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
108 ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000109 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 ri->mode = cpu_to_jemode(iattr->ia_mode);
111 else
112 ri->mode = cpu_to_jemode(inode->i_mode);
113
114
115 ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
116 ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
117 ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
118 ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));
119
120 ri->offset = cpu_to_je32(0);
121 ri->csize = ri->dsize = cpu_to_je32(mdatalen);
122 ri->compr = JFFS2_COMPR_NONE;
123 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
124 /* It's an extension. Make it a hole node */
125 ri->compr = JFFS2_COMPR_ZERO;
126 ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
127 ri->offset = cpu_to_je32(inode->i_size);
128 }
129 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
130 if (mdatalen)
131 ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
132 else
133 ri->data_crc = cpu_to_je32(0);
134
135 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
136 if (S_ISLNK(inode->i_mode))
137 kfree(mdata);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000138
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 if (IS_ERR(new_metadata)) {
140 jffs2_complete_reservation(c);
141 jffs2_free_raw_inode(ri);
142 up(&f->sem);
143 return PTR_ERR(new_metadata);
144 }
145 /* It worked. Update the inode */
146 inode->i_atime = ITIME(je32_to_cpu(ri->atime));
147 inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
148 inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
149 inode->i_mode = jemode_to_cpu(ri->mode);
150 inode->i_uid = je16_to_cpu(ri->uid);
151 inode->i_gid = je16_to_cpu(ri->gid);
152
153
154 old_metadata = f->metadata;
155
156 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
Artem B. Bityutskiyf302cd02005-07-24 16:29:59 +0100157 jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
159 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
160 jffs2_add_full_dnode_to_inode(c, f, new_metadata);
161 inode->i_size = iattr->ia_size;
162 f->metadata = NULL;
163 } else {
164 f->metadata = new_metadata;
165 }
166 if (old_metadata) {
167 jffs2_mark_node_obsolete(c, old_metadata->raw);
168 jffs2_free_full_dnode(old_metadata);
169 }
170 jffs2_free_raw_inode(ri);
171
172 up(&f->sem);
173 jffs2_complete_reservation(c);
174
175 /* We have to do the vmtruncate() without f->sem held, since
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000176 some pages may be locked and waiting for it in readpage().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 We are protected from a simultaneous write() extending i_size
178 back past iattr->ia_size, because do_truncate() holds the
179 generic inode semaphore. */
180 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
181 vmtruncate(inode, iattr->ia_size);
182
183 return 0;
184}
185
186int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
187{
188 return jffs2_do_setattr(dentry->d_inode, iattr);
189}
190
191int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
192{
193 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
194 unsigned long avail;
195
196 buf->f_type = JFFS2_SUPER_MAGIC;
197 buf->f_bsize = 1 << PAGE_SHIFT;
198 buf->f_blocks = c->flash_size >> PAGE_SHIFT;
199 buf->f_files = 0;
200 buf->f_ffree = 0;
201 buf->f_namelen = JFFS2_MAX_NAME_LEN;
202
203 spin_lock(&c->erase_completion_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 avail = c->dirty_size + c->free_size;
205 if (avail > c->sector_size * c->resv_blocks_write)
206 avail -= c->sector_size * c->resv_blocks_write;
207 else
208 avail = 0;
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100209 spin_unlock(&c->erase_completion_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
211 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 return 0;
214}
215
216
217void jffs2_clear_inode (struct inode *inode)
218{
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000219 /* We can forget about this inode for now - drop all
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 * the nodelists associated with it, etc.
221 */
222 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
223 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
226
227 jffs2_do_clear_inode(c, f);
228}
229
230void jffs2_read_inode (struct inode *inode)
231{
232 struct jffs2_inode_info *f;
233 struct jffs2_sb_info *c;
234 struct jffs2_raw_inode latest_node;
235 int ret;
236
237 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
238
239 f = JFFS2_INODE_INFO(inode);
240 c = JFFS2_SB_INFO(inode->i_sb);
241
242 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100243 down(&f->sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
246
247 if (ret) {
248 make_bad_inode(inode);
249 up(&f->sem);
250 return;
251 }
252 inode->i_mode = jemode_to_cpu(latest_node.mode);
253 inode->i_uid = je16_to_cpu(latest_node.uid);
254 inode->i_gid = je16_to_cpu(latest_node.gid);
255 inode->i_size = je32_to_cpu(latest_node.isize);
256 inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
257 inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
258 inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
259
260 inode->i_nlink = f->inocache->nlink;
261
262 inode->i_blksize = PAGE_SIZE;
263 inode->i_blocks = (inode->i_size + 511) >> 9;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 switch (inode->i_mode & S_IFMT) {
266 jint16_t rdev;
267
268 case S_IFLNK:
269 inode->i_op = &jffs2_symlink_inode_operations;
270 break;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 case S_IFDIR:
273 {
274 struct jffs2_full_dirent *fd;
275
276 for (fd=f->dents; fd; fd = fd->next) {
277 if (fd->type == DT_DIR && fd->ino)
278 inode->i_nlink++;
279 }
280 /* and '..' */
281 inode->i_nlink++;
282 /* Root dir gets i_nlink 3 for some reason */
283 if (inode->i_ino == 1)
284 inode->i_nlink++;
285
286 inode->i_op = &jffs2_dir_inode_operations;
287 inode->i_fop = &jffs2_dir_operations;
288 break;
289 }
290 case S_IFREG:
291 inode->i_op = &jffs2_file_inode_operations;
292 inode->i_fop = &jffs2_file_operations;
293 inode->i_mapping->a_ops = &jffs2_file_address_operations;
294 inode->i_mapping->nrpages = 0;
295 break;
296
297 case S_IFBLK:
298 case S_IFCHR:
299 /* Read the device numbers from the media */
300 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
301 if (jffs2_read_dnode(c, f, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
302 /* Eep */
303 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
304 up(&f->sem);
305 jffs2_do_clear_inode(c, f);
306 make_bad_inode(inode);
307 return;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
310 case S_IFSOCK:
311 case S_IFIFO:
312 inode->i_op = &jffs2_file_inode_operations;
313 init_special_inode(inode, inode->i_mode,
314 old_decode_dev((je16_to_cpu(rdev))));
315 break;
316
317 default:
318 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
319 }
320
321 up(&f->sem);
322
323 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
324}
325
326void jffs2_dirty_inode(struct inode *inode)
327{
328 struct iattr iattr;
329
330 if (!(inode->i_state & I_DIRTY_DATASYNC)) {
331 D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
332 return;
333 }
334
335 D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
336
337 iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
338 iattr.ia_mode = inode->i_mode;
339 iattr.ia_uid = inode->i_uid;
340 iattr.ia_gid = inode->i_gid;
341 iattr.ia_atime = inode->i_atime;
342 iattr.ia_mtime = inode->i_mtime;
343 iattr.ia_ctime = inode->i_ctime;
344
345 jffs2_do_setattr(inode, &iattr);
346}
347
348int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
349{
350 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
351
352 if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
353 return -EROFS;
354
355 /* We stop if it was running, then restart if it needs to.
356 This also catches the case where it was stopped and this
357 is just a remount to restart it.
358 Flush the writebuffer, if neccecary, else we loose it */
359 if (!(sb->s_flags & MS_RDONLY)) {
360 jffs2_stop_garbage_collect_thread(c);
361 down(&c->alloc_sem);
362 jffs2_flush_wbuf_pad(c);
363 up(&c->alloc_sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366 if (!(*flags & MS_RDONLY))
367 jffs2_start_garbage_collect_thread(c);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 *flags |= MS_NOATIME;
370
371 return 0;
372}
373
374void jffs2_write_super (struct super_block *sb)
375{
376 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
377 sb->s_dirt = 0;
378
379 if (sb->s_flags & MS_RDONLY)
380 return;
381
382 D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
383 jffs2_garbage_collect_trigger(c);
384 jffs2_erase_pending_blocks(c, 0);
385 jffs2_flush_wbuf_gc(c, 0);
386}
387
388
389/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
390 fill in the raw_inode while you're at it. */
391struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
392{
393 struct inode *inode;
394 struct super_block *sb = dir_i->i_sb;
395 struct jffs2_sb_info *c;
396 struct jffs2_inode_info *f;
397 int ret;
398
399 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
400
401 c = JFFS2_SB_INFO(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000402
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 inode = new_inode(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 if (!inode)
406 return ERR_PTR(-ENOMEM);
407
408 f = JFFS2_INODE_INFO(inode);
409 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100410 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412 memset(ri, 0, sizeof(*ri));
413 /* Set OS-specific defaults for new inodes */
414 ri->uid = cpu_to_je16(current->fsuid);
415
416 if (dir_i->i_mode & S_ISGID) {
417 ri->gid = cpu_to_je16(dir_i->i_gid);
418 if (S_ISDIR(mode))
419 mode |= S_ISGID;
420 } else {
421 ri->gid = cpu_to_je16(current->fsgid);
422 }
423 ri->mode = cpu_to_jemode(mode);
424 ret = jffs2_do_new_inode (c, f, mode, ri);
425 if (ret) {
426 make_bad_inode(inode);
427 iput(inode);
428 return ERR_PTR(ret);
429 }
430 inode->i_nlink = 1;
431 inode->i_ino = je32_to_cpu(ri->ino);
432 inode->i_mode = jemode_to_cpu(ri->mode);
433 inode->i_gid = je16_to_cpu(ri->gid);
434 inode->i_uid = je16_to_cpu(ri->uid);
435 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
436 ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
437
438 inode->i_blksize = PAGE_SIZE;
439 inode->i_blocks = 0;
440 inode->i_size = 0;
441
442 insert_inode_hash(inode);
443
444 return inode;
445}
446
447
448int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
449{
450 struct jffs2_sb_info *c;
451 struct inode *root_i;
452 int ret;
453 size_t blocks;
454
455 c = JFFS2_SB_INFO(sb);
456
Andrew Victor2f82ce12005-02-09 09:24:26 +0000457#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 if (c->mtd->type == MTD_NANDFLASH) {
459 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
460 return -EINVAL;
461 }
Andrew Victor8f15fd52005-02-09 09:17:45 +0000462 if (c->mtd->type == MTD_DATAFLASH) {
463 printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
464 return -EINVAL;
465 }
466#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467
468 c->flash_size = c->mtd->size;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000469 c->sector_size = c->mtd->erasesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 blocks = c->flash_size / c->sector_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471
472 /*
473 * Size alignment check
474 */
475 if ((c->sector_size * blocks) != c->flash_size) {
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000476 c->flash_size = c->sector_size * blocks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
478 c->flash_size / 1024);
479 }
480
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 if (c->flash_size < 5*c->sector_size) {
482 printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
483 return -EINVAL;
484 }
485
486 c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
488 /* NAND (or other bizarre) flash... do setup accordingly */
489 ret = jffs2_flash_setup(c);
490 if (ret)
491 return ret;
492
493 c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
494 if (!c->inocache_list) {
495 ret = -ENOMEM;
496 goto out_wbuf;
497 }
498 memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
499
500 if ((ret = jffs2_do_mount_fs(c)))
501 goto out_inohash;
502
503 ret = -EINVAL;
504
505 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
506 root_i = iget(sb, 1);
507 if (is_bad_inode(root_i)) {
508 D1(printk(KERN_WARNING "get root inode failed\n"));
Artem B. Bityutskiy6dac02a2005-07-18 12:21:23 +0100509 goto out_root_i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511
512 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
513 sb->s_root = d_alloc_root(root_i);
514 if (!sb->s_root)
515 goto out_root_i;
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 sb->s_maxbytes = 0xFFFFFFFF;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 sb->s_blocksize = PAGE_CACHE_SIZE;
519 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
520 sb->s_magic = JFFS2_SUPER_MAGIC;
521 if (!(sb->s_flags & MS_RDONLY))
522 jffs2_start_garbage_collect_thread(c);
523 return 0;
524
525 out_root_i:
526 iput(root_i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 jffs2_free_ino_caches(c);
528 jffs2_free_raw_node_refs(c);
Ferenc Havasi4ce1f562005-08-31 14:51:04 +0100529 if (jffs2_blocks_use_vmalloc(c))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 vfree(c->blocks);
531 else
532 kfree(c->blocks);
533 out_inohash:
534 kfree(c->inocache_list);
535 out_wbuf:
536 jffs2_flash_cleanup(c);
537
538 return ret;
539}
540
541void jffs2_gc_release_inode(struct jffs2_sb_info *c,
542 struct jffs2_inode_info *f)
543{
544 iput(OFNI_EDONI_2SFFJ(f));
545}
546
547struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
548 int inum, int nlink)
549{
550 struct inode *inode;
551 struct jffs2_inode_cache *ic;
552 if (!nlink) {
553 /* The inode has zero nlink but its nodes weren't yet marked
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000554 obsolete. This has to be because we're still waiting for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 the final (close() and) iput() to happen.
556
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000557 There's a possibility that the final iput() could have
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 happened while we were contemplating. In order to ensure
559 that we don't cause a new read_inode() (which would fail)
560 for the inode in question, we use ilookup() in this case
561 instead of iget().
562
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000563 The nlink can't _become_ zero at this point because we're
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 holding the alloc_sem, and jffs2_do_unlink() would also
565 need that while decrementing nlink on any inode.
566 */
567 inode = ilookup(OFNI_BS_2SFFJ(c), inum);
568 if (!inode) {
569 D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
570 inum));
571
572 spin_lock(&c->inocache_lock);
573 ic = jffs2_get_ino_cache(c, inum);
574 if (!ic) {
575 D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
576 spin_unlock(&c->inocache_lock);
577 return NULL;
578 }
579 if (ic->state != INO_STATE_CHECKEDABSENT) {
580 /* Wait for progress. Don't just loop */
581 D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
582 ic->ino, ic->state));
583 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
584 } else {
585 spin_unlock(&c->inocache_lock);
586 }
587
588 return NULL;
589 }
590 } else {
591 /* Inode has links to it still; they're not going away because
592 jffs2_do_unlink() would need the alloc_sem and we have it.
593 Just iget() it, and if read_inode() is necessary that's OK.
594 */
595 inode = iget(OFNI_BS_2SFFJ(c), inum);
596 if (!inode)
597 return ERR_PTR(-ENOMEM);
598 }
599 if (is_bad_inode(inode)) {
600 printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
601 inum, nlink);
602 /* NB. This will happen again. We need to do something appropriate here. */
603 iput(inode);
604 return ERR_PTR(-EIO);
605 }
606
607 return JFFS2_INODE_INFO(inode);
608}
609
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000610unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
611 struct jffs2_inode_info *f,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 unsigned long offset,
613 unsigned long *priv)
614{
615 struct inode *inode = OFNI_EDONI_2SFFJ(f);
616 struct page *pg;
617
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000618 pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 (void *)jffs2_do_readpage_unlock, inode);
620 if (IS_ERR(pg))
621 return (void *)pg;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000622
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 *priv = (unsigned long)pg;
624 return kmap(pg);
625}
626
627void jffs2_gc_release_page(struct jffs2_sb_info *c,
628 unsigned char *ptr,
629 unsigned long *priv)
630{
631 struct page *pg = (void *)*priv;
632
633 kunmap(pg);
634 page_cache_release(pg);
635}
636
637static int jffs2_flash_setup(struct jffs2_sb_info *c) {
638 int ret = 0;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (jffs2_cleanmarker_oob(c)) {
641 /* NAND flash... do setup accordingly */
642 ret = jffs2_nand_flash_setup(c);
643 if (ret)
644 return ret;
645 }
646
647 /* add setups for other bizarre flashes here... */
648 if (jffs2_nor_ecc(c)) {
649 ret = jffs2_nor_ecc_flash_setup(c);
650 if (ret)
651 return ret;
652 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000653
Andrew Victor8f15fd52005-02-09 09:17:45 +0000654 /* and Dataflash */
655 if (jffs2_dataflash(c)) {
656 ret = jffs2_dataflash_setup(c);
657 if (ret)
658 return ret;
659 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100660
661 /* and Intel "Sibley" flash */
662 if (jffs2_nor_wbuf_flash(c)) {
663 ret = jffs2_nor_wbuf_flash_setup(c);
664 if (ret)
665 return ret;
666 }
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 return ret;
669}
670
671void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
672
673 if (jffs2_cleanmarker_oob(c)) {
674 jffs2_nand_flash_cleanup(c);
675 }
676
677 /* add cleanups for other bizarre flashes here... */
678 if (jffs2_nor_ecc(c)) {
679 jffs2_nor_ecc_flash_cleanup(c);
680 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000681
Andrew Victor8f15fd52005-02-09 09:17:45 +0000682 /* and DataFlash */
683 if (jffs2_dataflash(c)) {
684 jffs2_dataflash_cleanup(c);
685 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100686
687 /* and Intel "Sibley" flash */
688 if (jffs2_nor_wbuf_flash(c)) {
689 jffs2_nor_wbuf_flash_cleanup(c);
690 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691}