blob: 97caa77d60cf23db5ce8dc98848780e2a1caf49c [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;
David Woodhouseaef9ab42006-05-19 00:28:49 +010036 union jffs2_device_node dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 unsigned char *mdata = NULL;
38 int mdatalen = 0;
39 unsigned int ivalid;
David Woodhouse9fe48542006-05-23 00:38:06 +010040 uint32_t alloclen;
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 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 */
David Woodhouseaef9ab42006-05-19 00:28:49 +010054 mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 mdata = (char *)&dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
57 } else if (S_ISLNK(inode->i_mode)) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010058 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 mdatalen = f->metadata->size;
60 mdata = kmalloc(f->metadata->size, GFP_USER);
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010061 if (!mdata) {
62 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 return -ENOMEM;
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010064 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
66 if (ret) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010067 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 kfree(mdata);
69 return ret;
70 }
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010071 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
73 }
74
75 ri = jffs2_alloc_raw_inode();
76 if (!ri) {
77 if (S_ISLNK(inode->i_mode))
78 kfree(mdata);
79 return -ENOMEM;
80 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000081
David Woodhouse9fe48542006-05-23 00:38:06 +010082 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen,
83 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 if (ret) {
85 jffs2_free_raw_inode(ri);
86 if (S_ISLNK(inode->i_mode & S_IFMT))
87 kfree(mdata);
88 return ret;
89 }
90 down(&f->sem);
91 ivalid = iattr->ia_valid;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000092
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
94 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
95 ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
96 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
97
98 ri->ino = cpu_to_je32(inode->i_ino);
99 ri->version = cpu_to_je32(++f->highest_version);
100
101 ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
102 ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
103
104 if (ivalid & ATTR_MODE)
105 if (iattr->ia_mode & S_ISGID &&
106 !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
107 ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000108 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 ri->mode = cpu_to_jemode(iattr->ia_mode);
110 else
111 ri->mode = cpu_to_jemode(inode->i_mode);
112
113
114 ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
115 ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
116 ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
117 ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));
118
119 ri->offset = cpu_to_je32(0);
120 ri->csize = ri->dsize = cpu_to_je32(mdatalen);
121 ri->compr = JFFS2_COMPR_NONE;
122 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
123 /* It's an extension. Make it a hole node */
124 ri->compr = JFFS2_COMPR_ZERO;
125 ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
126 ri->offset = cpu_to_je32(inode->i_size);
127 }
128 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
129 if (mdatalen)
130 ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
131 else
132 ri->data_crc = cpu_to_je32(0);
133
David Woodhouse9fe48542006-05-23 00:38:06 +0100134 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, ALLOC_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 if (S_ISLNK(inode->i_mode))
136 kfree(mdata);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000137
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 if (IS_ERR(new_metadata)) {
139 jffs2_complete_reservation(c);
140 jffs2_free_raw_inode(ri);
141 up(&f->sem);
142 return PTR_ERR(new_metadata);
143 }
144 /* It worked. Update the inode */
145 inode->i_atime = ITIME(je32_to_cpu(ri->atime));
146 inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
147 inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
148 inode->i_mode = jemode_to_cpu(ri->mode);
149 inode->i_uid = je16_to_cpu(ri->uid);
150 inode->i_gid = je16_to_cpu(ri->gid);
151
152
153 old_metadata = f->metadata;
154
155 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
Artem B. Bityutskiyf302cd02005-07-24 16:29:59 +0100156 jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157
158 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
159 jffs2_add_full_dnode_to_inode(c, f, new_metadata);
160 inode->i_size = iattr->ia_size;
161 f->metadata = NULL;
162 } else {
163 f->metadata = new_metadata;
164 }
165 if (old_metadata) {
166 jffs2_mark_node_obsolete(c, old_metadata->raw);
167 jffs2_free_full_dnode(old_metadata);
168 }
169 jffs2_free_raw_inode(ri);
170
171 up(&f->sem);
172 jffs2_complete_reservation(c);
173
174 /* We have to do the vmtruncate() without f->sem held, since
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000175 some pages may be locked and waiting for it in readpage().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 We are protected from a simultaneous write() extending i_size
177 back past iattr->ia_size, because do_truncate() holds the
178 generic inode semaphore. */
179 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
180 vmtruncate(inode, iattr->ia_size);
181
182 return 0;
183}
184
185int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
186{
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900187 int rc;
188
189 rc = jffs2_do_setattr(dentry->d_inode, iattr);
190 if (!rc && (iattr->ia_valid & ATTR_MODE))
191 rc = jffs2_acl_chmod(dentry->d_inode);
192 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193}
194
David Howells726c3342006-06-23 02:02:58 -0700195int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196{
David Howells726c3342006-06-23 02:02:58 -0700197 struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 unsigned long avail;
199
200 buf->f_type = JFFS2_SUPER_MAGIC;
201 buf->f_bsize = 1 << PAGE_SHIFT;
202 buf->f_blocks = c->flash_size >> PAGE_SHIFT;
203 buf->f_files = 0;
204 buf->f_ffree = 0;
205 buf->f_namelen = JFFS2_MAX_NAME_LEN;
206
207 spin_lock(&c->erase_completion_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 avail = c->dirty_size + c->free_size;
209 if (avail > c->sector_size * c->resv_blocks_write)
210 avail -= c->sector_size * c->resv_blocks_write;
211 else
212 avail = 0;
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100213 spin_unlock(&c->erase_completion_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
215 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
216
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 return 0;
218}
219
220
221void jffs2_clear_inode (struct inode *inode)
222{
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000223 /* We can forget about this inode for now - drop all
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 * the nodelists associated with it, etc.
225 */
226 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
227 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 jffs2_do_clear_inode(c, f);
231}
232
233void jffs2_read_inode (struct inode *inode)
234{
235 struct jffs2_inode_info *f;
236 struct jffs2_sb_info *c;
237 struct jffs2_raw_inode latest_node;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100238 union jffs2_device_node jdev;
239 dev_t rdev = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 int ret;
241
242 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
243
244 f = JFFS2_INODE_INFO(inode);
245 c = JFFS2_SB_INFO(inode->i_sb);
246
247 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100248 down(&f->sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
251
252 if (ret) {
253 make_bad_inode(inode);
254 up(&f->sem);
255 return;
256 }
257 inode->i_mode = jemode_to_cpu(latest_node.mode);
258 inode->i_uid = je16_to_cpu(latest_node.uid);
259 inode->i_gid = je16_to_cpu(latest_node.gid);
260 inode->i_size = je32_to_cpu(latest_node.isize);
261 inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
262 inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
263 inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
264
265 inode->i_nlink = f->inocache->nlink;
266
267 inode->i_blksize = PAGE_SIZE;
268 inode->i_blocks = (inode->i_size + 511) >> 9;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000269
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 switch (inode->i_mode & S_IFMT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272 case S_IFLNK:
273 inode->i_op = &jffs2_symlink_inode_operations;
274 break;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 case S_IFDIR:
277 {
278 struct jffs2_full_dirent *fd;
279
280 for (fd=f->dents; fd; fd = fd->next) {
281 if (fd->type == DT_DIR && fd->ino)
282 inode->i_nlink++;
283 }
284 /* and '..' */
285 inode->i_nlink++;
286 /* Root dir gets i_nlink 3 for some reason */
287 if (inode->i_ino == 1)
288 inode->i_nlink++;
289
290 inode->i_op = &jffs2_dir_inode_operations;
291 inode->i_fop = &jffs2_dir_operations;
292 break;
293 }
294 case S_IFREG:
295 inode->i_op = &jffs2_file_inode_operations;
296 inode->i_fop = &jffs2_file_operations;
297 inode->i_mapping->a_ops = &jffs2_file_address_operations;
298 inode->i_mapping->nrpages = 0;
299 break;
300
301 case S_IFBLK:
302 case S_IFCHR:
303 /* Read the device numbers from the media */
David Woodhouseaef9ab42006-05-19 00:28:49 +0100304 if (f->metadata->size != sizeof(jdev.old) &&
305 f->metadata->size != sizeof(jdev.new)) {
306 printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
307 up(&f->sem);
308 jffs2_do_clear_inode(c, f);
309 make_bad_inode(inode);
310 return;
311 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
David Woodhouseaef9ab42006-05-19 00:28:49 +0100313 if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 /* Eep */
315 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
316 up(&f->sem);
317 jffs2_do_clear_inode(c, f);
318 make_bad_inode(inode);
319 return;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000320 }
David Woodhouseaef9ab42006-05-19 00:28:49 +0100321 if (f->metadata->size == sizeof(jdev.old))
322 rdev = old_decode_dev(je16_to_cpu(jdev.old));
323 else
324 rdev = new_decode_dev(je32_to_cpu(jdev.new));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
326 case S_IFSOCK:
327 case S_IFIFO:
328 inode->i_op = &jffs2_file_inode_operations;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100329 init_special_inode(inode, inode->i_mode, rdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 break;
331
332 default:
333 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
334 }
335
336 up(&f->sem);
337
338 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
339}
340
341void jffs2_dirty_inode(struct inode *inode)
342{
343 struct iattr iattr;
344
345 if (!(inode->i_state & I_DIRTY_DATASYNC)) {
346 D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
347 return;
348 }
349
350 D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
351
352 iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
353 iattr.ia_mode = inode->i_mode;
354 iattr.ia_uid = inode->i_uid;
355 iattr.ia_gid = inode->i_gid;
356 iattr.ia_atime = inode->i_atime;
357 iattr.ia_mtime = inode->i_mtime;
358 iattr.ia_ctime = inode->i_ctime;
359
360 jffs2_do_setattr(inode, &iattr);
361}
362
363int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
364{
365 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
366
367 if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
368 return -EROFS;
369
370 /* We stop if it was running, then restart if it needs to.
371 This also catches the case where it was stopped and this
372 is just a remount to restart it.
373 Flush the writebuffer, if neccecary, else we loose it */
374 if (!(sb->s_flags & MS_RDONLY)) {
375 jffs2_stop_garbage_collect_thread(c);
376 down(&c->alloc_sem);
377 jffs2_flush_wbuf_pad(c);
378 up(&c->alloc_sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000379 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
381 if (!(*flags & MS_RDONLY))
382 jffs2_start_garbage_collect_thread(c);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 *flags |= MS_NOATIME;
385
386 return 0;
387}
388
389void jffs2_write_super (struct super_block *sb)
390{
391 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
392 sb->s_dirt = 0;
393
394 if (sb->s_flags & MS_RDONLY)
395 return;
396
397 D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
398 jffs2_garbage_collect_trigger(c);
399 jffs2_erase_pending_blocks(c, 0);
400 jffs2_flush_wbuf_gc(c, 0);
401}
402
403
404/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
405 fill in the raw_inode while you're at it. */
406struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
407{
408 struct inode *inode;
409 struct super_block *sb = dir_i->i_sb;
410 struct jffs2_sb_info *c;
411 struct jffs2_inode_info *f;
412 int ret;
413
414 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
415
416 c = JFFS2_SB_INFO(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 inode = new_inode(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 if (!inode)
421 return ERR_PTR(-ENOMEM);
422
423 f = JFFS2_INODE_INFO(inode);
424 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100425 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427 memset(ri, 0, sizeof(*ri));
428 /* Set OS-specific defaults for new inodes */
429 ri->uid = cpu_to_je16(current->fsuid);
430
431 if (dir_i->i_mode & S_ISGID) {
432 ri->gid = cpu_to_je16(dir_i->i_gid);
433 if (S_ISDIR(mode))
434 mode |= S_ISGID;
435 } else {
436 ri->gid = cpu_to_je16(current->fsgid);
437 }
438 ri->mode = cpu_to_jemode(mode);
439 ret = jffs2_do_new_inode (c, f, mode, ri);
440 if (ret) {
441 make_bad_inode(inode);
442 iput(inode);
443 return ERR_PTR(ret);
444 }
445 inode->i_nlink = 1;
446 inode->i_ino = je32_to_cpu(ri->ino);
447 inode->i_mode = jemode_to_cpu(ri->mode);
448 inode->i_gid = je16_to_cpu(ri->gid);
449 inode->i_uid = je16_to_cpu(ri->uid);
450 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
451 ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
452
453 inode->i_blksize = PAGE_SIZE;
454 inode->i_blocks = 0;
455 inode->i_size = 0;
456
457 insert_inode_hash(inode);
458
459 return inode;
460}
461
462
463int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
464{
465 struct jffs2_sb_info *c;
466 struct inode *root_i;
467 int ret;
468 size_t blocks;
469
470 c = JFFS2_SB_INFO(sb);
471
Andrew Victor2f82ce12005-02-09 09:24:26 +0000472#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 if (c->mtd->type == MTD_NANDFLASH) {
474 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
475 return -EINVAL;
476 }
Andrew Victor8f15fd52005-02-09 09:17:45 +0000477 if (c->mtd->type == MTD_DATAFLASH) {
478 printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
479 return -EINVAL;
480 }
481#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
483 c->flash_size = c->mtd->size;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000484 c->sector_size = c->mtd->erasesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 blocks = c->flash_size / c->sector_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 /*
488 * Size alignment check
489 */
490 if ((c->sector_size * blocks) != c->flash_size) {
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000491 c->flash_size = c->sector_size * blocks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
493 c->flash_size / 1024);
494 }
495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 if (c->flash_size < 5*c->sector_size) {
497 printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
498 return -EINVAL;
499 }
500
501 c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
503 /* NAND (or other bizarre) flash... do setup accordingly */
504 ret = jffs2_flash_setup(c);
505 if (ret)
506 return ret;
507
508 c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
509 if (!c->inocache_list) {
510 ret = -ENOMEM;
511 goto out_wbuf;
512 }
513 memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
514
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900515 jffs2_init_xattr_subsystem(c);
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 if ((ret = jffs2_do_mount_fs(c)))
518 goto out_inohash;
519
520 ret = -EINVAL;
521
522 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
523 root_i = iget(sb, 1);
524 if (is_bad_inode(root_i)) {
525 D1(printk(KERN_WARNING "get root inode failed\n"));
Artem B. Bityutskiy6dac02a2005-07-18 12:21:23 +0100526 goto out_root_i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 }
528
529 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
530 sb->s_root = d_alloc_root(root_i);
531 if (!sb->s_root)
532 goto out_root_i;
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 sb->s_maxbytes = 0xFFFFFFFF;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 sb->s_blocksize = PAGE_CACHE_SIZE;
536 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
537 sb->s_magic = JFFS2_SUPER_MAGIC;
538 if (!(sb->s_flags & MS_RDONLY))
539 jffs2_start_garbage_collect_thread(c);
540 return 0;
541
542 out_root_i:
543 iput(root_i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 jffs2_free_ino_caches(c);
545 jffs2_free_raw_node_refs(c);
Ferenc Havasi4ce1f562005-08-31 14:51:04 +0100546 if (jffs2_blocks_use_vmalloc(c))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 vfree(c->blocks);
548 else
549 kfree(c->blocks);
550 out_inohash:
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900551 jffs2_clear_xattr_subsystem(c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 kfree(c->inocache_list);
553 out_wbuf:
554 jffs2_flash_cleanup(c);
555
556 return ret;
557}
558
559void jffs2_gc_release_inode(struct jffs2_sb_info *c,
560 struct jffs2_inode_info *f)
561{
562 iput(OFNI_EDONI_2SFFJ(f));
563}
564
565struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
566 int inum, int nlink)
567{
568 struct inode *inode;
569 struct jffs2_inode_cache *ic;
570 if (!nlink) {
571 /* The inode has zero nlink but its nodes weren't yet marked
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000572 obsolete. This has to be because we're still waiting for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 the final (close() and) iput() to happen.
574
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000575 There's a possibility that the final iput() could have
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 happened while we were contemplating. In order to ensure
577 that we don't cause a new read_inode() (which would fail)
578 for the inode in question, we use ilookup() in this case
579 instead of iget().
580
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000581 The nlink can't _become_ zero at this point because we're
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 holding the alloc_sem, and jffs2_do_unlink() would also
583 need that while decrementing nlink on any inode.
584 */
585 inode = ilookup(OFNI_BS_2SFFJ(c), inum);
586 if (!inode) {
587 D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
588 inum));
589
590 spin_lock(&c->inocache_lock);
591 ic = jffs2_get_ino_cache(c, inum);
592 if (!ic) {
593 D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
594 spin_unlock(&c->inocache_lock);
595 return NULL;
596 }
597 if (ic->state != INO_STATE_CHECKEDABSENT) {
598 /* Wait for progress. Don't just loop */
599 D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
600 ic->ino, ic->state));
601 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
602 } else {
603 spin_unlock(&c->inocache_lock);
604 }
605
606 return NULL;
607 }
608 } else {
609 /* Inode has links to it still; they're not going away because
610 jffs2_do_unlink() would need the alloc_sem and we have it.
611 Just iget() it, and if read_inode() is necessary that's OK.
612 */
613 inode = iget(OFNI_BS_2SFFJ(c), inum);
614 if (!inode)
615 return ERR_PTR(-ENOMEM);
616 }
617 if (is_bad_inode(inode)) {
618 printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
619 inum, nlink);
620 /* NB. This will happen again. We need to do something appropriate here. */
621 iput(inode);
622 return ERR_PTR(-EIO);
623 }
624
625 return JFFS2_INODE_INFO(inode);
626}
627
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000628unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
629 struct jffs2_inode_info *f,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 unsigned long offset,
631 unsigned long *priv)
632{
633 struct inode *inode = OFNI_EDONI_2SFFJ(f);
634 struct page *pg;
635
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000636 pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 (void *)jffs2_do_readpage_unlock, inode);
638 if (IS_ERR(pg))
639 return (void *)pg;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000640
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 *priv = (unsigned long)pg;
642 return kmap(pg);
643}
644
645void jffs2_gc_release_page(struct jffs2_sb_info *c,
646 unsigned char *ptr,
647 unsigned long *priv)
648{
649 struct page *pg = (void *)*priv;
650
651 kunmap(pg);
652 page_cache_release(pg);
653}
654
655static int jffs2_flash_setup(struct jffs2_sb_info *c) {
656 int ret = 0;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000657
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 if (jffs2_cleanmarker_oob(c)) {
659 /* NAND flash... do setup accordingly */
660 ret = jffs2_nand_flash_setup(c);
661 if (ret)
662 return ret;
663 }
664
Andrew Victor8f15fd52005-02-09 09:17:45 +0000665 /* and Dataflash */
666 if (jffs2_dataflash(c)) {
667 ret = jffs2_dataflash_setup(c);
668 if (ret)
669 return ret;
670 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100671
672 /* and Intel "Sibley" flash */
673 if (jffs2_nor_wbuf_flash(c)) {
674 ret = jffs2_nor_wbuf_flash_setup(c);
675 if (ret)
676 return ret;
677 }
678
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 return ret;
680}
681
682void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
683
684 if (jffs2_cleanmarker_oob(c)) {
685 jffs2_nand_flash_cleanup(c);
686 }
687
Andrew Victor8f15fd52005-02-09 09:17:45 +0000688 /* and DataFlash */
689 if (jffs2_dataflash(c)) {
690 jffs2_dataflash_cleanup(c);
691 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100692
693 /* and Intel "Sibley" flash */
694 if (jffs2_nor_wbuf_flash(c)) {
695 jffs2_nor_wbuf_flash_cleanup(c);
696 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697}