blob: e26ea78c7892f7a4f157819a06e052add03057fd [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
David Woodhousec00c3102007-04-25 14:16:47 +01004 * Copyright © 2001-2007 Red Hat, Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 */
11
Randy Dunlap16f7e0f2006-01-11 12:17:46 -080012#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/fs.h>
16#include <linux/list.h>
17#include <linux/mtd/mtd.h>
18#include <linux/pagemap.h>
19#include <linux/slab.h>
20#include <linux/vmalloc.h>
21#include <linux/vfs.h>
22#include <linux/crc32.h>
23#include "nodelist.h"
24
25static int jffs2_flash_setup(struct jffs2_sb_info *c);
26
David Woodhouse9ed437c2007-08-22 12:39:19 +010027int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
Linus Torvalds1da177e2005-04-16 15:20:36 -070028{
29 struct jffs2_full_dnode *old_metadata, *new_metadata;
30 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
31 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
32 struct jffs2_raw_inode *ri;
David Woodhouseaef9ab42006-05-19 00:28:49 +010033 union jffs2_device_node dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 unsigned char *mdata = NULL;
35 int mdatalen = 0;
36 unsigned int ivalid;
David Woodhouse9fe48542006-05-23 00:38:06 +010037 uint32_t alloclen;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038 int ret;
David Woodhouse9ed437c2007-08-22 12:39:19 +010039
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42 /* Special cases - we don't want more than one data node
43 for these types on the medium at any time. So setattr
44 must read the original data associated with the node
45 (i.e. the device numbers or the target name) and write
46 it out again with the appropriate data attached */
47 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
48 /* For these, we don't actually need to read the old node */
David Woodhouseaef9ab42006-05-19 00:28:49 +010049 mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 mdata = (char *)&dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
52 } else if (S_ISLNK(inode->i_mode)) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010053 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 mdatalen = f->metadata->size;
55 mdata = kmalloc(f->metadata->size, GFP_USER);
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010056 if (!mdata) {
57 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 return -ENOMEM;
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010059 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
61 if (ret) {
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010062 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 kfree(mdata);
64 return ret;
65 }
Dmitry Bazhenov422138d2006-05-05 22:46:49 +010066 up(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
68 }
69
70 ri = jffs2_alloc_raw_inode();
71 if (!ri) {
72 if (S_ISLNK(inode->i_mode))
73 kfree(mdata);
74 return -ENOMEM;
75 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000076
David Woodhouse9fe48542006-05-23 00:38:06 +010077 ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen,
78 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 if (ret) {
80 jffs2_free_raw_inode(ri);
81 if (S_ISLNK(inode->i_mode & S_IFMT))
82 kfree(mdata);
83 return ret;
84 }
85 down(&f->sem);
86 ivalid = iattr->ia_valid;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000087
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
89 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
90 ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
91 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
92
93 ri->ino = cpu_to_je32(inode->i_ino);
94 ri->version = cpu_to_je32(++f->highest_version);
95
96 ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
97 ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
98
99 if (ivalid & ATTR_MODE)
David Woodhouse857013b2007-11-01 16:27:38 -0400100 ri->mode = cpu_to_jemode(iattr->ia_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 else
102 ri->mode = cpu_to_jemode(inode->i_mode);
103
104
105 ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
106 ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
107 ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
108 ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));
109
110 ri->offset = cpu_to_je32(0);
111 ri->csize = ri->dsize = cpu_to_je32(mdatalen);
112 ri->compr = JFFS2_COMPR_NONE;
113 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
114 /* It's an extension. Make it a hole node */
115 ri->compr = JFFS2_COMPR_ZERO;
116 ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
117 ri->offset = cpu_to_je32(inode->i_size);
118 }
119 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
120 if (mdatalen)
121 ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
122 else
123 ri->data_crc = cpu_to_je32(0);
124
David Woodhouse9fe48542006-05-23 00:38:06 +0100125 new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, ALLOC_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 if (S_ISLNK(inode->i_mode))
127 kfree(mdata);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 if (IS_ERR(new_metadata)) {
130 jffs2_complete_reservation(c);
131 jffs2_free_raw_inode(ri);
132 up(&f->sem);
133 return PTR_ERR(new_metadata);
134 }
135 /* It worked. Update the inode */
136 inode->i_atime = ITIME(je32_to_cpu(ri->atime));
137 inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
138 inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
139 inode->i_mode = jemode_to_cpu(ri->mode);
140 inode->i_uid = je16_to_cpu(ri->uid);
141 inode->i_gid = je16_to_cpu(ri->gid);
142
143
144 old_metadata = f->metadata;
145
146 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
Artem B. Bityutskiyf302cd02005-07-24 16:29:59 +0100147 jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
149 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
150 jffs2_add_full_dnode_to_inode(c, f, new_metadata);
151 inode->i_size = iattr->ia_size;
152 f->metadata = NULL;
153 } else {
154 f->metadata = new_metadata;
155 }
156 if (old_metadata) {
157 jffs2_mark_node_obsolete(c, old_metadata->raw);
158 jffs2_free_full_dnode(old_metadata);
159 }
160 jffs2_free_raw_inode(ri);
161
162 up(&f->sem);
163 jffs2_complete_reservation(c);
164
165 /* We have to do the vmtruncate() without f->sem held, since
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000166 some pages may be locked and waiting for it in readpage().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 We are protected from a simultaneous write() extending i_size
168 back past iattr->ia_size, because do_truncate() holds the
169 generic inode semaphore. */
170 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
171 vmtruncate(inode, iattr->ia_size);
172
173 return 0;
174}
175
176int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
177{
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900178 int rc;
179
David Woodhouse9ed437c2007-08-22 12:39:19 +0100180 rc = inode_change_ok(dentry->d_inode, iattr);
181 if (rc)
182 return rc;
183
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900184 rc = jffs2_do_setattr(dentry->d_inode, iattr);
185 if (!rc && (iattr->ia_valid & ATTR_MODE))
186 rc = jffs2_acl_chmod(dentry->d_inode);
David Woodhouse9ed437c2007-08-22 12:39:19 +0100187
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900188 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189}
190
David Howells726c3342006-06-23 02:02:58 -0700191int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192{
David Howells726c3342006-06-23 02:02:58 -0700193 struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 jffs2_do_clear_inode(c, f);
227}
228
David Howells5451f792008-02-07 00:15:42 -0800229struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230{
231 struct jffs2_inode_info *f;
232 struct jffs2_sb_info *c;
233 struct jffs2_raw_inode latest_node;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100234 union jffs2_device_node jdev;
David Howells5451f792008-02-07 00:15:42 -0800235 struct inode *inode;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100236 dev_t rdev = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 int ret;
238
David Howells5451f792008-02-07 00:15:42 -0800239 D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino));
240
241 inode = iget_locked(sb, ino);
242 if (!inode)
243 return ERR_PTR(-ENOMEM);
244 if (!(inode->i_state & I_NEW))
245 return inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247 f = JFFS2_INODE_INFO(inode);
248 c = JFFS2_SB_INFO(inode->i_sb);
249
250 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100251 down(&f->sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
254
255 if (ret) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 up(&f->sem);
David Howells5451f792008-02-07 00:15:42 -0800257 iget_failed(inode);
258 return ERR_PTR(ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 }
260 inode->i_mode = jemode_to_cpu(latest_node.mode);
261 inode->i_uid = je16_to_cpu(latest_node.uid);
262 inode->i_gid = je16_to_cpu(latest_node.gid);
263 inode->i_size = je32_to_cpu(latest_node.isize);
264 inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
265 inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
266 inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
267
268 inode->i_nlink = f->inocache->nlink;
269
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 inode->i_blocks = (inode->i_size + 511) >> 9;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 switch (inode->i_mode & S_IFMT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273
274 case S_IFLNK:
275 inode->i_op = &jffs2_symlink_inode_operations;
276 break;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 case S_IFDIR:
279 {
280 struct jffs2_full_dirent *fd;
281
282 for (fd=f->dents; fd; fd = fd->next) {
283 if (fd->type == DT_DIR && fd->ino)
Dave Hansend8c76e62006-09-30 23:29:04 -0700284 inc_nlink(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 }
286 /* and '..' */
Dave Hansend8c76e62006-09-30 23:29:04 -0700287 inc_nlink(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 /* Root dir gets i_nlink 3 for some reason */
289 if (inode->i_ino == 1)
Dave Hansend8c76e62006-09-30 23:29:04 -0700290 inc_nlink(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291
292 inode->i_op = &jffs2_dir_inode_operations;
293 inode->i_fop = &jffs2_dir_operations;
294 break;
295 }
296 case S_IFREG:
297 inode->i_op = &jffs2_file_inode_operations;
298 inode->i_fop = &jffs2_file_operations;
299 inode->i_mapping->a_ops = &jffs2_file_address_operations;
300 inode->i_mapping->nrpages = 0;
301 break;
302
303 case S_IFBLK:
304 case S_IFCHR:
305 /* Read the device numbers from the media */
David Woodhouseaef9ab42006-05-19 00:28:49 +0100306 if (f->metadata->size != sizeof(jdev.old) &&
307 f->metadata->size != sizeof(jdev.new)) {
308 printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
David Howells5451f792008-02-07 00:15:42 -0800309 goto error_io;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100310 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
David Howells5451f792008-02-07 00:15:42 -0800312 ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size);
313 if (ret < 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);
David Howells5451f792008-02-07 00:15:42 -0800316 goto error;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000317 }
David Woodhouseaef9ab42006-05-19 00:28:49 +0100318 if (f->metadata->size == sizeof(jdev.old))
319 rdev = old_decode_dev(je16_to_cpu(jdev.old));
320 else
321 rdev = new_decode_dev(je32_to_cpu(jdev.new));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
323 case S_IFSOCK:
324 case S_IFIFO:
325 inode->i_op = &jffs2_file_inode_operations;
David Woodhouseaef9ab42006-05-19 00:28:49 +0100326 init_special_inode(inode, inode->i_mode, rdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 break;
328
329 default:
330 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
331 }
332
333 up(&f->sem);
334
335 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
David Howells5451f792008-02-07 00:15:42 -0800336 unlock_new_inode(inode);
337 return inode;
338
339error_io:
340 ret = -EIO;
341error:
342 up(&f->sem);
343 jffs2_do_clear_inode(c, f);
344 iget_failed(inode);
345 return ERR_PTR(ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346}
347
348void jffs2_dirty_inode(struct inode *inode)
349{
350 struct iattr iattr;
351
352 if (!(inode->i_state & I_DIRTY_DATASYNC)) {
353 D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
354 return;
355 }
356
357 D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
358
359 iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
360 iattr.ia_mode = inode->i_mode;
361 iattr.ia_uid = inode->i_uid;
362 iattr.ia_gid = inode->i_gid;
363 iattr.ia_atime = inode->i_atime;
364 iattr.ia_mtime = inode->i_mtime;
365 iattr.ia_ctime = inode->i_ctime;
366
367 jffs2_do_setattr(inode, &iattr);
368}
369
370int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
371{
372 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
373
374 if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
375 return -EROFS;
376
377 /* We stop if it was running, then restart if it needs to.
378 This also catches the case where it was stopped and this
379 is just a remount to restart it.
380 Flush the writebuffer, if neccecary, else we loose it */
381 if (!(sb->s_flags & MS_RDONLY)) {
382 jffs2_stop_garbage_collect_thread(c);
383 down(&c->alloc_sem);
384 jffs2_flush_wbuf_pad(c);
385 up(&c->alloc_sem);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000386 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
388 if (!(*flags & MS_RDONLY))
389 jffs2_start_garbage_collect_thread(c);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 *flags |= MS_NOATIME;
392
393 return 0;
394}
395
396void jffs2_write_super (struct super_block *sb)
397{
398 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
399 sb->s_dirt = 0;
400
401 if (sb->s_flags & MS_RDONLY)
402 return;
403
404 D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
405 jffs2_garbage_collect_trigger(c);
406 jffs2_erase_pending_blocks(c, 0);
407 jffs2_flush_wbuf_gc(c, 0);
408}
409
410
411/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
412 fill in the raw_inode while you're at it. */
KaiGai Koheicfc8dc62007-09-14 15:16:35 +0900413struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
415 struct inode *inode;
416 struct super_block *sb = dir_i->i_sb;
417 struct jffs2_sb_info *c;
418 struct jffs2_inode_info *f;
419 int ret;
420
421 D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
422
423 c = JFFS2_SB_INFO(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 inode = new_inode(sb);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000426
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 if (!inode)
428 return ERR_PTR(-ENOMEM);
429
430 f = JFFS2_INODE_INFO(inode);
431 jffs2_init_inode_info(f);
Thomas Gleixner21eeb7a2005-11-29 16:57:17 +0100432 down(&f->sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
434 memset(ri, 0, sizeof(*ri));
435 /* Set OS-specific defaults for new inodes */
436 ri->uid = cpu_to_je16(current->fsuid);
437
438 if (dir_i->i_mode & S_ISGID) {
439 ri->gid = cpu_to_je16(dir_i->i_gid);
440 if (S_ISDIR(mode))
441 mode |= S_ISGID;
442 } else {
443 ri->gid = cpu_to_je16(current->fsgid);
444 }
David Woodhouse9ed437c2007-08-22 12:39:19 +0100445
446 /* POSIX ACLs have to be processed now, at least partly.
447 The umask is only applied if there's no default ACL */
KaiGai Koheicfc8dc62007-09-14 15:16:35 +0900448 ret = jffs2_init_acl_pre(dir_i, inode, &mode);
449 if (ret) {
450 make_bad_inode(inode);
451 iput(inode);
452 return ERR_PTR(ret);
David Woodhouse9ed437c2007-08-22 12:39:19 +0100453 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 ret = jffs2_do_new_inode (c, f, mode, ri);
455 if (ret) {
456 make_bad_inode(inode);
457 iput(inode);
458 return ERR_PTR(ret);
459 }
460 inode->i_nlink = 1;
461 inode->i_ino = je32_to_cpu(ri->ino);
462 inode->i_mode = jemode_to_cpu(ri->mode);
463 inode->i_gid = je16_to_cpu(ri->gid);
464 inode->i_uid = je16_to_cpu(ri->uid);
465 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
466 ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
467
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 inode->i_blocks = 0;
469 inode->i_size = 0;
470
471 insert_inode_hash(inode);
472
473 return inode;
474}
475
476
477int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
478{
479 struct jffs2_sb_info *c;
480 struct inode *root_i;
481 int ret;
482 size_t blocks;
483
484 c = JFFS2_SB_INFO(sb);
485
Andrew Victor2f82ce12005-02-09 09:24:26 +0000486#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 if (c->mtd->type == MTD_NANDFLASH) {
488 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
489 return -EINVAL;
490 }
Andrew Victor8f15fd52005-02-09 09:17:45 +0000491 if (c->mtd->type == MTD_DATAFLASH) {
492 printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
493 return -EINVAL;
494 }
495#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
497 c->flash_size = c->mtd->size;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000498 c->sector_size = c->mtd->erasesize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 blocks = c->flash_size / c->sector_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
501 /*
502 * Size alignment check
503 */
504 if ((c->sector_size * blocks) != c->flash_size) {
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000505 c->flash_size = c->sector_size * blocks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
507 c->flash_size / 1024);
508 }
509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 if (c->flash_size < 5*c->sector_size) {
511 printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
512 return -EINVAL;
513 }
514
515 c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517 /* NAND (or other bizarre) flash... do setup accordingly */
518 ret = jffs2_flash_setup(c);
519 if (ret)
520 return ret;
521
Yan Burman3d375d92006-12-04 15:03:01 -0800522 c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 if (!c->inocache_list) {
524 ret = -ENOMEM;
525 goto out_wbuf;
526 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900528 jffs2_init_xattr_subsystem(c);
529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if ((ret = jffs2_do_mount_fs(c)))
531 goto out_inohash;
532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
David Howells5451f792008-02-07 00:15:42 -0800534 root_i = jffs2_iget(sb, 1);
535 if (IS_ERR(root_i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 D1(printk(KERN_WARNING "get root inode failed\n"));
David Howells5451f792008-02-07 00:15:42 -0800537 ret = PTR_ERR(root_i);
538 goto out_root;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 }
540
David Howells5451f792008-02-07 00:15:42 -0800541 ret = -ENOMEM;
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
544 sb->s_root = d_alloc_root(root_i);
545 if (!sb->s_root)
546 goto out_root_i;
547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 sb->s_maxbytes = 0xFFFFFFFF;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 sb->s_blocksize = PAGE_CACHE_SIZE;
550 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
551 sb->s_magic = JFFS2_SUPER_MAGIC;
552 if (!(sb->s_flags & MS_RDONLY))
553 jffs2_start_garbage_collect_thread(c);
554 return 0;
555
556 out_root_i:
557 iput(root_i);
David Howells5451f792008-02-07 00:15:42 -0800558out_root:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 jffs2_free_ino_caches(c);
560 jffs2_free_raw_node_refs(c);
Ferenc Havasi4ce1f562005-08-31 14:51:04 +0100561 if (jffs2_blocks_use_vmalloc(c))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 vfree(c->blocks);
563 else
564 kfree(c->blocks);
565 out_inohash:
KaiGai Koheiaa98d7c2006-05-13 15:09:47 +0900566 jffs2_clear_xattr_subsystem(c);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 kfree(c->inocache_list);
568 out_wbuf:
569 jffs2_flash_cleanup(c);
570
571 return ret;
572}
573
574void jffs2_gc_release_inode(struct jffs2_sb_info *c,
575 struct jffs2_inode_info *f)
576{
577 iput(OFNI_EDONI_2SFFJ(f));
578}
579
580struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
581 int inum, int nlink)
582{
583 struct inode *inode;
584 struct jffs2_inode_cache *ic;
585 if (!nlink) {
586 /* The inode has zero nlink but its nodes weren't yet marked
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000587 obsolete. This has to be because we're still waiting for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 the final (close() and) iput() to happen.
589
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000590 There's a possibility that the final iput() could have
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 happened while we were contemplating. In order to ensure
592 that we don't cause a new read_inode() (which would fail)
593 for the inode in question, we use ilookup() in this case
594 instead of iget().
595
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000596 The nlink can't _become_ zero at this point because we're
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 holding the alloc_sem, and jffs2_do_unlink() would also
598 need that while decrementing nlink on any inode.
599 */
600 inode = ilookup(OFNI_BS_2SFFJ(c), inum);
601 if (!inode) {
602 D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
603 inum));
604
605 spin_lock(&c->inocache_lock);
606 ic = jffs2_get_ino_cache(c, inum);
607 if (!ic) {
608 D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
609 spin_unlock(&c->inocache_lock);
610 return NULL;
611 }
612 if (ic->state != INO_STATE_CHECKEDABSENT) {
613 /* Wait for progress. Don't just loop */
614 D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
615 ic->ino, ic->state));
616 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
617 } else {
618 spin_unlock(&c->inocache_lock);
619 }
620
621 return NULL;
622 }
623 } else {
624 /* Inode has links to it still; they're not going away because
625 jffs2_do_unlink() would need the alloc_sem and we have it.
626 Just iget() it, and if read_inode() is necessary that's OK.
627 */
David Howells5451f792008-02-07 00:15:42 -0800628 inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);
629 if (IS_ERR(inode))
630 return ERR_CAST(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 }
632 if (is_bad_inode(inode)) {
633 printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
634 inum, nlink);
635 /* NB. This will happen again. We need to do something appropriate here. */
636 iput(inode);
637 return ERR_PTR(-EIO);
638 }
639
640 return JFFS2_INODE_INFO(inode);
641}
642
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000643unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
644 struct jffs2_inode_info *f,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 unsigned long offset,
646 unsigned long *priv)
647{
648 struct inode *inode = OFNI_EDONI_2SFFJ(f);
649 struct page *pg;
650
Jason Lunzfc0e0192007-09-01 12:06:03 -0700651 pg = read_cache_page_async(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 (void *)jffs2_do_readpage_unlock, inode);
653 if (IS_ERR(pg))
654 return (void *)pg;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 *priv = (unsigned long)pg;
657 return kmap(pg);
658}
659
660void jffs2_gc_release_page(struct jffs2_sb_info *c,
661 unsigned char *ptr,
662 unsigned long *priv)
663{
664 struct page *pg = (void *)*priv;
665
666 kunmap(pg);
667 page_cache_release(pg);
668}
669
670static int jffs2_flash_setup(struct jffs2_sb_info *c) {
671 int ret = 0;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 if (jffs2_cleanmarker_oob(c)) {
674 /* NAND flash... do setup accordingly */
675 ret = jffs2_nand_flash_setup(c);
676 if (ret)
677 return ret;
678 }
679
Andrew Victor8f15fd52005-02-09 09:17:45 +0000680 /* and Dataflash */
681 if (jffs2_dataflash(c)) {
682 ret = jffs2_dataflash_setup(c);
683 if (ret)
684 return ret;
685 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100686
687 /* and Intel "Sibley" flash */
688 if (jffs2_nor_wbuf_flash(c)) {
689 ret = jffs2_nor_wbuf_flash_setup(c);
690 if (ret)
691 return ret;
692 }
693
Artem Bityutskiy0029da32006-10-04 19:15:21 +0300694 /* and an UBI volume */
695 if (jffs2_ubivol(c)) {
696 ret = jffs2_ubivol_setup(c);
697 if (ret)
698 return ret;
699 }
700
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 return ret;
702}
703
704void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
705
706 if (jffs2_cleanmarker_oob(c)) {
707 jffs2_nand_flash_cleanup(c);
708 }
709
Andrew Victor8f15fd52005-02-09 09:17:45 +0000710 /* and DataFlash */
711 if (jffs2_dataflash(c)) {
712 jffs2_dataflash_cleanup(c);
713 }
Nicolas Pitre59da7212005-08-06 05:51:33 +0100714
715 /* and Intel "Sibley" flash */
716 if (jffs2_nor_wbuf_flash(c)) {
717 jffs2_nor_wbuf_flash_cleanup(c);
718 }
Artem Bityutskiy0029da32006-10-04 19:15:21 +0300719
720 /* and an UBI volume */
721 if (jffs2_ubivol(c)) {
722 jffs2_ubivol_cleanup(c);
723 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724}