xref: /linux/fs/jffs2/fs.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * JFFS2 -- Journalling Flash File System, Version 2.
31da177e4SLinus Torvalds  *
4c00c310eSDavid Woodhouse  * Copyright © 2001-2007 Red Hat, Inc.
56088c058SDavid Woodhouse  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Created by David Woodhouse <dwmw2@infradead.org>
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  * For licensing information, see the file 'LICENCE' in this directory.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  */
121da177e4SLinus Torvalds 
135a528957SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
145a528957SJoe Perches 
1516f7e0feSRandy Dunlap #include <linux/capability.h>
161da177e4SLinus Torvalds #include <linux/kernel.h>
171da177e4SLinus Torvalds #include <linux/sched.h>
185b825c3aSIngo Molnar #include <linux/cred.h>
191da177e4SLinus Torvalds #include <linux/fs.h>
20ec10a24fSDavid Howells #include <linux/fs_context.h>
211da177e4SLinus Torvalds #include <linux/list.h>
221da177e4SLinus Torvalds #include <linux/mtd/mtd.h>
231da177e4SLinus Torvalds #include <linux/pagemap.h>
241da177e4SLinus Torvalds #include <linux/slab.h>
251da177e4SLinus Torvalds #include <linux/vmalloc.h>
261da177e4SLinus Torvalds #include <linux/vfs.h>
271da177e4SLinus Torvalds #include <linux/crc32.h>
281da177e4SLinus Torvalds #include "nodelist.h"
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds static int jffs2_flash_setup(struct jffs2_sb_info *c);
311da177e4SLinus Torvalds 
jffs2_do_setattr(struct inode * inode,struct iattr * iattr)329ed437c5SDavid Woodhouse int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
331da177e4SLinus Torvalds {
341da177e4SLinus Torvalds 	struct jffs2_full_dnode *old_metadata, *new_metadata;
351da177e4SLinus Torvalds 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
361da177e4SLinus Torvalds 	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
371da177e4SLinus Torvalds 	struct jffs2_raw_inode *ri;
38aef9ab47SDavid Woodhouse 	union jffs2_device_node dev;
391da177e4SLinus Torvalds 	unsigned char *mdata = NULL;
401da177e4SLinus Torvalds 	int mdatalen = 0;
411da177e4SLinus Torvalds 	unsigned int ivalid;
429fe4854cSDavid Woodhouse 	uint32_t alloclen;
431da177e4SLinus Torvalds 	int ret;
44dd919660SDavid Woodhouse 	int alloc_type = ALLOC_NORMAL;
459ed437c5SDavid Woodhouse 
469c261b33SJoe Perches 	jffs2_dbg(1, "%s(): ino #%lu\n", __func__, inode->i_ino);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds 	/* Special cases - we don't want more than one data node
491da177e4SLinus Torvalds 	   for these types on the medium at any time. So setattr
501da177e4SLinus Torvalds 	   must read the original data associated with the node
511da177e4SLinus Torvalds 	   (i.e. the device numbers or the target name) and write
521da177e4SLinus Torvalds 	   it out again with the appropriate data attached */
531da177e4SLinus Torvalds 	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
541da177e4SLinus Torvalds 		/* For these, we don't actually need to read the old node */
55aef9ab47SDavid Woodhouse 		mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
561da177e4SLinus Torvalds 		mdata = (char *)&dev;
579c261b33SJoe Perches 		jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n",
589c261b33SJoe Perches 			  __func__, mdatalen);
591da177e4SLinus Torvalds 	} else if (S_ISLNK(inode->i_mode)) {
60ced22070SDavid Woodhouse 		mutex_lock(&f->sem);
611da177e4SLinus Torvalds 		mdatalen = f->metadata->size;
621da177e4SLinus Torvalds 		mdata = kmalloc(f->metadata->size, GFP_USER);
63422138ddSDmitry Bazhenov 		if (!mdata) {
64ced22070SDavid Woodhouse 			mutex_unlock(&f->sem);
651da177e4SLinus Torvalds 			return -ENOMEM;
66422138ddSDmitry Bazhenov 		}
671da177e4SLinus Torvalds 		ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
681da177e4SLinus Torvalds 		if (ret) {
69ced22070SDavid Woodhouse 			mutex_unlock(&f->sem);
701da177e4SLinus Torvalds 			kfree(mdata);
711da177e4SLinus Torvalds 			return ret;
721da177e4SLinus Torvalds 		}
73ced22070SDavid Woodhouse 		mutex_unlock(&f->sem);
749c261b33SJoe Perches 		jffs2_dbg(1, "%s(): Writing %d bytes of symlink target\n",
759c261b33SJoe Perches 			  __func__, mdatalen);
761da177e4SLinus Torvalds 	}
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 	ri = jffs2_alloc_raw_inode();
791da177e4SLinus Torvalds 	if (!ri) {
801da177e4SLinus Torvalds 		if (S_ISLNK(inode->i_mode))
811da177e4SLinus Torvalds 			kfree(mdata);
821da177e4SLinus Torvalds 		return -ENOMEM;
831da177e4SLinus Torvalds 	}
841da177e4SLinus Torvalds 
859fe4854cSDavid Woodhouse 	ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen,
86e631ddbaSFerenc Havasi 				  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
871da177e4SLinus Torvalds 	if (ret) {
881da177e4SLinus Torvalds 		jffs2_free_raw_inode(ri);
8961effb51SAl Viro 		if (S_ISLNK(inode->i_mode))
901da177e4SLinus Torvalds 			 kfree(mdata);
911da177e4SLinus Torvalds 		return ret;
921da177e4SLinus Torvalds 	}
93ced22070SDavid Woodhouse 	mutex_lock(&f->sem);
941da177e4SLinus Torvalds 	ivalid = iattr->ia_valid;
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 	ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
971da177e4SLinus Torvalds 	ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
981da177e4SLinus Torvalds 	ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
991da177e4SLinus Torvalds 	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds 	ri->ino = cpu_to_je32(inode->i_ino);
1021da177e4SLinus Torvalds 	ri->version = cpu_to_je32(++f->highest_version);
1031da177e4SLinus Torvalds 
1040cfe53d3SEric W. Biederman 	ri->uid = cpu_to_je16((ivalid & ATTR_UID)?
1050cfe53d3SEric W. Biederman 		from_kuid(&init_user_ns, iattr->ia_uid):i_uid_read(inode));
1060cfe53d3SEric W. Biederman 	ri->gid = cpu_to_je16((ivalid & ATTR_GID)?
1070cfe53d3SEric W. Biederman 		from_kgid(&init_user_ns, iattr->ia_gid):i_gid_read(inode));
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds 	if (ivalid & ATTR_MODE)
1101da177e4SLinus Torvalds 		ri->mode = cpu_to_jemode(iattr->ia_mode);
1111da177e4SLinus Torvalds 	else
1121da177e4SLinus Torvalds 		ri->mode = cpu_to_jemode(inode->i_mode);
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
116*95af66c4SJeff Layton 	ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode_get_atime(inode)));
117*95af66c4SJeff Layton 	ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode_get_mtime(inode)));
118d8b23c61SJeff Layton 	ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode_get_ctime(inode)));
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	ri->offset = cpu_to_je32(0);
1211da177e4SLinus Torvalds 	ri->csize = ri->dsize = cpu_to_je32(mdatalen);
1221da177e4SLinus Torvalds 	ri->compr = JFFS2_COMPR_NONE;
1231da177e4SLinus Torvalds 	if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
1241da177e4SLinus Torvalds 		/* It's an extension. Make it a hole node */
1251da177e4SLinus Torvalds 		ri->compr = JFFS2_COMPR_ZERO;
1261da177e4SLinus Torvalds 		ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
1271da177e4SLinus Torvalds 		ri->offset = cpu_to_je32(inode->i_size);
128dd919660SDavid Woodhouse 	} else if (ivalid & ATTR_SIZE && !iattr->ia_size) {
129dd919660SDavid Woodhouse 		/* For truncate-to-zero, treat it as deletion because
130dd919660SDavid Woodhouse 		   it'll always be obsoleting all previous nodes */
131dd919660SDavid Woodhouse 		alloc_type = ALLOC_DELETION;
1321da177e4SLinus Torvalds 	}
1331da177e4SLinus Torvalds 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
1341da177e4SLinus Torvalds 	if (mdatalen)
1351da177e4SLinus Torvalds 		ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
1361da177e4SLinus Torvalds 	else
1371da177e4SLinus Torvalds 		ri->data_crc = cpu_to_je32(0);
1381da177e4SLinus Torvalds 
139dd919660SDavid Woodhouse 	new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, alloc_type);
1401da177e4SLinus Torvalds 	if (S_ISLNK(inode->i_mode))
1411da177e4SLinus Torvalds 		kfree(mdata);
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 	if (IS_ERR(new_metadata)) {
1441da177e4SLinus Torvalds 		jffs2_complete_reservation(c);
1451da177e4SLinus Torvalds 		jffs2_free_raw_inode(ri);
146ced22070SDavid Woodhouse 		mutex_unlock(&f->sem);
1471da177e4SLinus Torvalds 		return PTR_ERR(new_metadata);
1481da177e4SLinus Torvalds 	}
1491da177e4SLinus Torvalds 	/* It worked. Update the inode */
150*95af66c4SJeff Layton 	inode_set_atime_to_ts(inode, ITIME(je32_to_cpu(ri->atime)));
151d8b23c61SJeff Layton 	inode_set_ctime_to_ts(inode, ITIME(je32_to_cpu(ri->ctime)));
152*95af66c4SJeff Layton 	inode_set_mtime_to_ts(inode, ITIME(je32_to_cpu(ri->mtime)));
1531da177e4SLinus Torvalds 	inode->i_mode = jemode_to_cpu(ri->mode);
1540cfe53d3SEric W. Biederman 	i_uid_write(inode, je16_to_cpu(ri->uid));
1550cfe53d3SEric W. Biederman 	i_gid_write(inode, je16_to_cpu(ri->gid));
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 	old_metadata = f->metadata;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
161f302cd02SArtem B. Bityutskiy 		jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 	if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
1641da177e4SLinus Torvalds 		jffs2_add_full_dnode_to_inode(c, f, new_metadata);
1651da177e4SLinus Torvalds 		inode->i_size = iattr->ia_size;
166b28ba9faSDavid Woodhouse 		inode->i_blocks = (inode->i_size + 511) >> 9;
1671da177e4SLinus Torvalds 		f->metadata = NULL;
1681da177e4SLinus Torvalds 	} else {
1691da177e4SLinus Torvalds 		f->metadata = new_metadata;
1701da177e4SLinus Torvalds 	}
1711da177e4SLinus Torvalds 	if (old_metadata) {
1721da177e4SLinus Torvalds 		jffs2_mark_node_obsolete(c, old_metadata->raw);
1731da177e4SLinus Torvalds 		jffs2_free_full_dnode(old_metadata);
1741da177e4SLinus Torvalds 	}
1751da177e4SLinus Torvalds 	jffs2_free_raw_inode(ri);
1761da177e4SLinus Torvalds 
177ced22070SDavid Woodhouse 	mutex_unlock(&f->sem);
1781da177e4SLinus Torvalds 	jffs2_complete_reservation(c);
1791da177e4SLinus Torvalds 
1802c27c65eSChristoph Hellwig 	/* We have to do the truncate_setsize() without f->sem held, since
18175a47803SMatthew Wilcox (Oracle) 	   some pages may be locked and waiting for it in read_folio().
1821da177e4SLinus Torvalds 	   We are protected from a simultaneous write() extending i_size
1831da177e4SLinus Torvalds 	   back past iattr->ia_size, because do_truncate() holds the
1841da177e4SLinus Torvalds 	   generic inode semaphore. */
185b28ba9faSDavid Woodhouse 	if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
1862c27c65eSChristoph Hellwig 		truncate_setsize(inode, iattr->ia_size);
187b28ba9faSDavid Woodhouse 		inode->i_blocks = (inode->i_size + 511) >> 9;
188b28ba9faSDavid Woodhouse 	}
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	return 0;
1911da177e4SLinus Torvalds }
1921da177e4SLinus Torvalds 
jffs2_setattr(struct mnt_idmap * idmap,struct dentry * dentry,struct iattr * iattr)193c1632a0fSChristian Brauner int jffs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
194549c7297SChristian Brauner 		  struct iattr *iattr)
1951da177e4SLinus Torvalds {
1962b0143b5SDavid Howells 	struct inode *inode = d_inode(dentry);
197aa98d7cfSKaiGai Kohei 	int rc;
198aa98d7cfSKaiGai Kohei 
199c1632a0fSChristian Brauner 	rc = setattr_prepare(&nop_mnt_idmap, dentry, iattr);
2009ed437c5SDavid Woodhouse 	if (rc)
2019ed437c5SDavid Woodhouse 		return rc;
2029ed437c5SDavid Woodhouse 
203f2963d45SChristoph Hellwig 	rc = jffs2_do_setattr(inode, iattr);
204aa98d7cfSKaiGai Kohei 	if (!rc && (iattr->ia_valid & ATTR_MODE))
20513e83a49SChristian Brauner 		rc = posix_acl_chmod(&nop_mnt_idmap, dentry, inode->i_mode);
2069ed437c5SDavid Woodhouse 
207aa98d7cfSKaiGai Kohei 	return rc;
2081da177e4SLinus Torvalds }
2091da177e4SLinus Torvalds 
jffs2_statfs(struct dentry * dentry,struct kstatfs * buf)210726c3342SDavid Howells int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
2111da177e4SLinus Torvalds {
212726c3342SDavid Howells 	struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb);
2131da177e4SLinus Torvalds 	unsigned long avail;
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	buf->f_type = JFFS2_SUPER_MAGIC;
2161da177e4SLinus Torvalds 	buf->f_bsize = 1 << PAGE_SHIFT;
2171da177e4SLinus Torvalds 	buf->f_blocks = c->flash_size >> PAGE_SHIFT;
2181da177e4SLinus Torvalds 	buf->f_files = 0;
2191da177e4SLinus Torvalds 	buf->f_ffree = 0;
2201da177e4SLinus Torvalds 	buf->f_namelen = JFFS2_MAX_NAME_LEN;
22175caf6b5SDavid Woodhouse 	buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC;
22275caf6b5SDavid Woodhouse 	buf->f_fsid.val[1] = c->mtd->index;
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	spin_lock(&c->erase_completion_lock);
2251da177e4SLinus Torvalds 	avail = c->dirty_size + c->free_size;
2261da177e4SLinus Torvalds 	if (avail > c->sector_size * c->resv_blocks_write)
2271da177e4SLinus Torvalds 		avail -= c->sector_size * c->resv_blocks_write;
2281da177e4SLinus Torvalds 	else
2291da177e4SLinus Torvalds 		avail = 0;
230e0c8e42fSArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
2311da177e4SLinus Torvalds 
2321da177e4SLinus Torvalds 	buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
2331da177e4SLinus Torvalds 
2341da177e4SLinus Torvalds 	return 0;
2351da177e4SLinus Torvalds }
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds 
jffs2_evict_inode(struct inode * inode)238b57922d9SAl Viro void jffs2_evict_inode (struct inode *inode)
2391da177e4SLinus Torvalds {
2401da177e4SLinus Torvalds 	/* We can forget about this inode for now - drop all
2411da177e4SLinus Torvalds 	 *  the nodelists associated with it, etc.
2421da177e4SLinus Torvalds 	 */
2431da177e4SLinus Torvalds 	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
2441da177e4SLinus Torvalds 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
2451da177e4SLinus Torvalds 
2469c261b33SJoe Perches 	jffs2_dbg(1, "%s(): ino #%lu mode %o\n",
2479c261b33SJoe Perches 		  __func__, inode->i_ino, inode->i_mode);
24891b0abe3SJohannes Weiner 	truncate_inode_pages_final(&inode->i_data);
249dbd5768fSJan Kara 	clear_inode(inode);
2501da177e4SLinus Torvalds 	jffs2_do_clear_inode(c, f);
2511da177e4SLinus Torvalds }
2521da177e4SLinus Torvalds 
jffs2_iget(struct super_block * sb,unsigned long ino)2535451f79fSDavid Howells struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
2541da177e4SLinus Torvalds {
2551da177e4SLinus Torvalds 	struct jffs2_inode_info *f;
2561da177e4SLinus Torvalds 	struct jffs2_sb_info *c;
2571da177e4SLinus Torvalds 	struct jffs2_raw_inode latest_node;
258aef9ab47SDavid Woodhouse 	union jffs2_device_node jdev;
2595451f79fSDavid Howells 	struct inode *inode;
260aef9ab47SDavid Woodhouse 	dev_t rdev = 0;
2611da177e4SLinus Torvalds 	int ret;
2621da177e4SLinus Torvalds 
2639c261b33SJoe Perches 	jffs2_dbg(1, "%s(): ino == %lu\n", __func__, ino);
2645451f79fSDavid Howells 
2655451f79fSDavid Howells 	inode = iget_locked(sb, ino);
2665451f79fSDavid Howells 	if (!inode)
2675451f79fSDavid Howells 		return ERR_PTR(-ENOMEM);
2685451f79fSDavid Howells 	if (!(inode->i_state & I_NEW))
2695451f79fSDavid Howells 		return inode;
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds 	f = JFFS2_INODE_INFO(inode);
2721da177e4SLinus Torvalds 	c = JFFS2_SB_INFO(inode->i_sb);
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds 	jffs2_init_inode_info(f);
275ced22070SDavid Woodhouse 	mutex_lock(&f->sem);
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds 	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
2787aaea760SBrian Norris 	if (ret)
2797aaea760SBrian Norris 		goto error;
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds 	inode->i_mode = jemode_to_cpu(latest_node.mode);
2820cfe53d3SEric W. Biederman 	i_uid_write(inode, je16_to_cpu(latest_node.uid));
2830cfe53d3SEric W. Biederman 	i_gid_write(inode, je16_to_cpu(latest_node.gid));
2841da177e4SLinus Torvalds 	inode->i_size = je32_to_cpu(latest_node.isize);
285*95af66c4SJeff Layton 	inode_set_atime_to_ts(inode, ITIME(je32_to_cpu(latest_node.atime)));
286*95af66c4SJeff Layton 	inode_set_mtime_to_ts(inode, ITIME(je32_to_cpu(latest_node.mtime)));
287d8b23c61SJeff Layton 	inode_set_ctime_to_ts(inode, ITIME(je32_to_cpu(latest_node.ctime)));
2881da177e4SLinus Torvalds 
289bfe86848SMiklos Szeredi 	set_nlink(inode, f->inocache->pino_nlink);
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds 	inode->i_blocks = (inode->i_size + 511) >> 9;
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	switch (inode->i_mode & S_IFMT) {
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	case S_IFLNK:
2961da177e4SLinus Torvalds 		inode->i_op = &jffs2_symlink_inode_operations;
297a8db149fSAl Viro 		inode->i_link = f->target;
2981da177e4SLinus Torvalds 		break;
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds 	case S_IFDIR:
3011da177e4SLinus Torvalds 	{
3021da177e4SLinus Torvalds 		struct jffs2_full_dirent *fd;
303bfe86848SMiklos Szeredi 		set_nlink(inode, 2); /* parent and '.' */
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds 		for (fd=f->dents; fd; fd = fd->next) {
3061da177e4SLinus Torvalds 			if (fd->type == DT_DIR && fd->ino)
307d8c76e6fSDave Hansen 				inc_nlink(inode);
3081da177e4SLinus Torvalds 		}
3091da177e4SLinus Torvalds 		/* Root dir gets i_nlink 3 for some reason */
3101da177e4SLinus Torvalds 		if (inode->i_ino == 1)
311d8c76e6fSDave Hansen 			inc_nlink(inode);
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds 		inode->i_op = &jffs2_dir_inode_operations;
3141da177e4SLinus Torvalds 		inode->i_fop = &jffs2_dir_operations;
3151da177e4SLinus Torvalds 		break;
3161da177e4SLinus Torvalds 	}
3171da177e4SLinus Torvalds 	case S_IFREG:
3181da177e4SLinus Torvalds 		inode->i_op = &jffs2_file_inode_operations;
3191da177e4SLinus Torvalds 		inode->i_fop = &jffs2_file_operations;
3201da177e4SLinus Torvalds 		inode->i_mapping->a_ops = &jffs2_file_address_operations;
3211da177e4SLinus Torvalds 		inode->i_mapping->nrpages = 0;
3221da177e4SLinus Torvalds 		break;
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds 	case S_IFBLK:
3251da177e4SLinus Torvalds 	case S_IFCHR:
3261da177e4SLinus Torvalds 		/* Read the device numbers from the media */
32791f80266SAndrew Morton 		if (f->metadata->size != sizeof(jdev.old_id) &&
32891f80266SAndrew Morton 		    f->metadata->size != sizeof(jdev.new_id)) {
329da320f05SJoe Perches 			pr_notice("Device node has strange size %d\n",
330da320f05SJoe Perches 				  f->metadata->size);
3315451f79fSDavid Howells 			goto error_io;
332aef9ab47SDavid Woodhouse 		}
3339c261b33SJoe Perches 		jffs2_dbg(1, "Reading device numbers from flash\n");
3345451f79fSDavid Howells 		ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size);
3355451f79fSDavid Howells 		if (ret < 0) {
3361da177e4SLinus Torvalds 			/* Eep */
337da320f05SJoe Perches 			pr_notice("Read device numbers for inode %lu failed\n",
338da320f05SJoe Perches 				  (unsigned long)inode->i_ino);
3395451f79fSDavid Howells 			goto error;
3401da177e4SLinus Torvalds 		}
34191f80266SAndrew Morton 		if (f->metadata->size == sizeof(jdev.old_id))
34291f80266SAndrew Morton 			rdev = old_decode_dev(je16_to_cpu(jdev.old_id));
343aef9ab47SDavid Woodhouse 		else
34491f80266SAndrew Morton 			rdev = new_decode_dev(je32_to_cpu(jdev.new_id));
345df561f66SGustavo A. R. Silva 		fallthrough;
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds 	case S_IFSOCK:
3481da177e4SLinus Torvalds 	case S_IFIFO:
3491da177e4SLinus Torvalds 		inode->i_op = &jffs2_file_inode_operations;
350aef9ab47SDavid Woodhouse 		init_special_inode(inode, inode->i_mode, rdev);
3511da177e4SLinus Torvalds 		break;
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds 	default:
354da320f05SJoe Perches 		pr_warn("%s(): Bogus i_mode %o for ino %lu\n",
355da320f05SJoe Perches 			__func__, inode->i_mode, (unsigned long)inode->i_ino);
3561da177e4SLinus Torvalds 	}
3571da177e4SLinus Torvalds 
358ced22070SDavid Woodhouse 	mutex_unlock(&f->sem);
3591da177e4SLinus Torvalds 
3609c261b33SJoe Perches 	jffs2_dbg(1, "jffs2_read_inode() returning\n");
3615451f79fSDavid Howells 	unlock_new_inode(inode);
3625451f79fSDavid Howells 	return inode;
3635451f79fSDavid Howells 
3645451f79fSDavid Howells error_io:
3655451f79fSDavid Howells 	ret = -EIO;
3665451f79fSDavid Howells error:
367ced22070SDavid Woodhouse 	mutex_unlock(&f->sem);
3685451f79fSDavid Howells 	iget_failed(inode);
3695451f79fSDavid Howells 	return ERR_PTR(ret);
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
jffs2_dirty_inode(struct inode * inode,int flags)372aa385729SChristoph Hellwig void jffs2_dirty_inode(struct inode *inode, int flags)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	struct iattr iattr;
3751da177e4SLinus Torvalds 
3761da177e4SLinus Torvalds 	if (!(inode->i_state & I_DIRTY_DATASYNC)) {
3779c261b33SJoe Perches 		jffs2_dbg(2, "%s(): not calling setattr() for ino #%lu\n",
3789c261b33SJoe Perches 			  __func__, inode->i_ino);
3791da177e4SLinus Torvalds 		return;
3801da177e4SLinus Torvalds 	}
3811da177e4SLinus Torvalds 
3829c261b33SJoe Perches 	jffs2_dbg(1, "%s(): calling setattr() for ino #%lu\n",
3839c261b33SJoe Perches 		  __func__, inode->i_ino);
3841da177e4SLinus Torvalds 
3851da177e4SLinus Torvalds 	iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
3861da177e4SLinus Torvalds 	iattr.ia_mode = inode->i_mode;
3871da177e4SLinus Torvalds 	iattr.ia_uid = inode->i_uid;
3881da177e4SLinus Torvalds 	iattr.ia_gid = inode->i_gid;
389*95af66c4SJeff Layton 	iattr.ia_atime = inode_get_atime(inode);
390*95af66c4SJeff Layton 	iattr.ia_mtime = inode_get_mtime(inode);
391d8b23c61SJeff Layton 	iattr.ia_ctime = inode_get_ctime(inode);
3921da177e4SLinus Torvalds 
3931da177e4SLinus Torvalds 	jffs2_do_setattr(inode, &iattr);
3941da177e4SLinus Torvalds }
3951da177e4SLinus Torvalds 
jffs2_do_remount_fs(struct super_block * sb,struct fs_context * fc)396ec10a24fSDavid Howells int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc)
3971da177e4SLinus Torvalds {
3981da177e4SLinus Torvalds 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
3991da177e4SLinus Torvalds 
400bc98a42cSDavid Howells 	if (c->flags & JFFS2_SB_FLAG_RO && !sb_rdonly(sb))
4011da177e4SLinus Torvalds 		return -EROFS;
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds 	/* We stop if it was running, then restart if it needs to.
4041da177e4SLinus Torvalds 	   This also catches the case where it was stopped and this
4051da177e4SLinus Torvalds 	   is just a remount to restart it.
4067198c9c0SYu Zhe 	   Flush the writebuffer, if necessary, else we loose it */
407bc98a42cSDavid Howells 	if (!sb_rdonly(sb)) {
4081da177e4SLinus Torvalds 		jffs2_stop_garbage_collect_thread(c);
409ced22070SDavid Woodhouse 		mutex_lock(&c->alloc_sem);
4101da177e4SLinus Torvalds 		jffs2_flush_wbuf_pad(c);
411ced22070SDavid Woodhouse 		mutex_unlock(&c->alloc_sem);
4121da177e4SLinus Torvalds 	}
4131da177e4SLinus Torvalds 
414ec10a24fSDavid Howells 	if (!(fc->sb_flags & SB_RDONLY))
4151da177e4SLinus Torvalds 		jffs2_start_garbage_collect_thread(c);
4161da177e4SLinus Torvalds 
417ec10a24fSDavid Howells 	fc->sb_flags |= SB_NOATIME;
4181da177e4SLinus Torvalds 	return 0;
4191da177e4SLinus Torvalds }
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
4221da177e4SLinus Torvalds    fill in the raw_inode while you're at it. */
jffs2_new_inode(struct inode * dir_i,umode_t mode,struct jffs2_raw_inode * ri)423d3fb6120SAl Viro struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_raw_inode *ri)
4241da177e4SLinus Torvalds {
4251da177e4SLinus Torvalds 	struct inode *inode;
4261da177e4SLinus Torvalds 	struct super_block *sb = dir_i->i_sb;
4271da177e4SLinus Torvalds 	struct jffs2_sb_info *c;
4281da177e4SLinus Torvalds 	struct jffs2_inode_info *f;
4291da177e4SLinus Torvalds 	int ret;
4301da177e4SLinus Torvalds 
4319c261b33SJoe Perches 	jffs2_dbg(1, "%s(): dir_i %ld, mode 0x%x\n",
4329c261b33SJoe Perches 		  __func__, dir_i->i_ino, mode);
4331da177e4SLinus Torvalds 
4341da177e4SLinus Torvalds 	c = JFFS2_SB_INFO(sb);
4351da177e4SLinus Torvalds 
4361da177e4SLinus Torvalds 	inode = new_inode(sb);
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds 	if (!inode)
4391da177e4SLinus Torvalds 		return ERR_PTR(-ENOMEM);
4401da177e4SLinus Torvalds 
4411da177e4SLinus Torvalds 	f = JFFS2_INODE_INFO(inode);
4421da177e4SLinus Torvalds 	jffs2_init_inode_info(f);
443ced22070SDavid Woodhouse 	mutex_lock(&f->sem);
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds 	memset(ri, 0, sizeof(*ri));
4461da177e4SLinus Torvalds 	/* Set OS-specific defaults for new inodes */
4470cfe53d3SEric W. Biederman 	ri->uid = cpu_to_je16(from_kuid(&init_user_ns, current_fsuid()));
4481da177e4SLinus Torvalds 
4491da177e4SLinus Torvalds 	if (dir_i->i_mode & S_ISGID) {
4500cfe53d3SEric W. Biederman 		ri->gid = cpu_to_je16(i_gid_read(dir_i));
4511da177e4SLinus Torvalds 		if (S_ISDIR(mode))
4521da177e4SLinus Torvalds 			mode |= S_ISGID;
4531da177e4SLinus Torvalds 	} else {
4540cfe53d3SEric W. Biederman 		ri->gid = cpu_to_je16(from_kgid(&init_user_ns, current_fsgid()));
4551da177e4SLinus Torvalds 	}
4569ed437c5SDavid Woodhouse 
4579ed437c5SDavid Woodhouse 	/* POSIX ACLs have to be processed now, at least partly.
4589ed437c5SDavid Woodhouse 	   The umask is only applied if there's no default ACL */
459cfc8dc6fSKaiGai Kohei 	ret = jffs2_init_acl_pre(dir_i, inode, &mode);
460cfc8dc6fSKaiGai Kohei 	if (ret) {
46101887a3aSWang Guoli 		mutex_unlock(&f->sem);
4629ed437c5SDavid Woodhouse 		make_bad_inode(inode);
4639ed437c5SDavid Woodhouse 		iput(inode);
464cfc8dc6fSKaiGai Kohei 		return ERR_PTR(ret);
4659ed437c5SDavid Woodhouse 	}
4661da177e4SLinus Torvalds 	ret = jffs2_do_new_inode (c, f, mode, ri);
4671da177e4SLinus Torvalds 	if (ret) {
46801887a3aSWang Guoli 		mutex_unlock(&f->sem);
4691da177e4SLinus Torvalds 		make_bad_inode(inode);
4701da177e4SLinus Torvalds 		iput(inode);
4711da177e4SLinus Torvalds 		return ERR_PTR(ret);
4721da177e4SLinus Torvalds 	}
473bfe86848SMiklos Szeredi 	set_nlink(inode, 1);
4741da177e4SLinus Torvalds 	inode->i_ino = je32_to_cpu(ri->ino);
4751da177e4SLinus Torvalds 	inode->i_mode = jemode_to_cpu(ri->mode);
4760cfe53d3SEric W. Biederman 	i_gid_write(inode, je16_to_cpu(ri->gid));
4770cfe53d3SEric W. Biederman 	i_uid_write(inode, je16_to_cpu(ri->uid));
478*95af66c4SJeff Layton 	simple_inode_init_ts(inode);
479*95af66c4SJeff Layton 	ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode_get_mtime(inode)));
4801da177e4SLinus Torvalds 
4811da177e4SLinus Torvalds 	inode->i_blocks = 0;
4821da177e4SLinus Torvalds 	inode->i_size = 0;
4831da177e4SLinus Torvalds 
484e72e6497SDavid Woodhouse 	if (insert_inode_locked(inode) < 0) {
48501887a3aSWang Guoli 		mutex_unlock(&f->sem);
486e72e6497SDavid Woodhouse 		make_bad_inode(inode);
487e72e6497SDavid Woodhouse 		iput(inode);
488e72e6497SDavid Woodhouse 		return ERR_PTR(-EINVAL);
489e72e6497SDavid Woodhouse 	}
4901da177e4SLinus Torvalds 
4911da177e4SLinus Torvalds 	return inode;
4921da177e4SLinus Torvalds }
4931da177e4SLinus Torvalds 
calculate_inocache_hashsize(uint32_t flash_size)49465e5a0e1SDaniel Drake static int calculate_inocache_hashsize(uint32_t flash_size)
49565e5a0e1SDaniel Drake {
49665e5a0e1SDaniel Drake 	/*
49765e5a0e1SDaniel Drake 	 * Pick a inocache hash size based on the size of the medium.
49865e5a0e1SDaniel Drake 	 * Count how many megabytes we're dealing with, apply a hashsize twice
49965e5a0e1SDaniel Drake 	 * that size, but rounding down to the usual big powers of 2. And keep
50065e5a0e1SDaniel Drake 	 * to sensible bounds.
50165e5a0e1SDaniel Drake 	 */
50265e5a0e1SDaniel Drake 
50365e5a0e1SDaniel Drake 	int size_mb = flash_size / 1024 / 1024;
50465e5a0e1SDaniel Drake 	int hashsize = (size_mb * 2) & ~0x3f;
50565e5a0e1SDaniel Drake 
50665e5a0e1SDaniel Drake 	if (hashsize < INOCACHE_HASHSIZE_MIN)
50765e5a0e1SDaniel Drake 		return INOCACHE_HASHSIZE_MIN;
50865e5a0e1SDaniel Drake 	if (hashsize > INOCACHE_HASHSIZE_MAX)
50965e5a0e1SDaniel Drake 		return INOCACHE_HASHSIZE_MAX;
51065e5a0e1SDaniel Drake 
51165e5a0e1SDaniel Drake 	return hashsize;
51265e5a0e1SDaniel Drake }
5131da177e4SLinus Torvalds 
jffs2_do_fill_super(struct super_block * sb,struct fs_context * fc)514ec10a24fSDavid Howells int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
5151da177e4SLinus Torvalds {
5161da177e4SLinus Torvalds 	struct jffs2_sb_info *c;
5171da177e4SLinus Torvalds 	struct inode *root_i;
5181da177e4SLinus Torvalds 	int ret;
5191da177e4SLinus Torvalds 	size_t blocks;
5201da177e4SLinus Torvalds 
5211da177e4SLinus Torvalds 	c = JFFS2_SB_INFO(sb);
5221da177e4SLinus Torvalds 
523e104f1e9SHuang Shijie 	/* Do not support the MLC nand */
524e104f1e9SHuang Shijie 	if (c->mtd->type == MTD_MLCNANDFLASH)
525e104f1e9SHuang Shijie 		return -EINVAL;
526e104f1e9SHuang Shijie 
5272f82ce1eSAndrew Victor #ifndef CONFIG_JFFS2_FS_WRITEBUFFER
5281da177e4SLinus Torvalds 	if (c->mtd->type == MTD_NANDFLASH) {
529ec10a24fSDavid Howells 		errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in");
5301da177e4SLinus Torvalds 		return -EINVAL;
5311da177e4SLinus Torvalds 	}
5328f15fd55SAndrew Victor 	if (c->mtd->type == MTD_DATAFLASH) {
533ec10a24fSDavid Howells 		errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in");
5348f15fd55SAndrew Victor 		return -EINVAL;
5358f15fd55SAndrew Victor 	}
5368f15fd55SAndrew Victor #endif
5371da177e4SLinus Torvalds 
5381da177e4SLinus Torvalds 	c->flash_size = c->mtd->size;
5391da177e4SLinus Torvalds 	c->sector_size = c->mtd->erasesize;
5401da177e4SLinus Torvalds 	blocks = c->flash_size / c->sector_size;
5411da177e4SLinus Torvalds 
5421da177e4SLinus Torvalds 	/*
5431da177e4SLinus Torvalds 	 * Size alignment check
5441da177e4SLinus Torvalds 	 */
5451da177e4SLinus Torvalds 	if ((c->sector_size * blocks) != c->flash_size) {
5461da177e4SLinus Torvalds 		c->flash_size = c->sector_size * blocks;
547ec10a24fSDavid Howells 		infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB",
5481da177e4SLinus Torvalds 		      c->flash_size / 1024);
5491da177e4SLinus Torvalds 	}
5501da177e4SLinus Torvalds 
5511da177e4SLinus Torvalds 	if (c->flash_size < 5*c->sector_size) {
552ec10a24fSDavid Howells 		errorf(fc, "Too few erase blocks (%d)",
553da320f05SJoe Perches 		       c->flash_size / c->sector_size);
5541da177e4SLinus Torvalds 		return -EINVAL;
5551da177e4SLinus Torvalds 	}
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 	c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
5581da177e4SLinus Torvalds 
5591da177e4SLinus Torvalds 	/* NAND (or other bizarre) flash... do setup accordingly */
5601da177e4SLinus Torvalds 	ret = jffs2_flash_setup(c);
5611da177e4SLinus Torvalds 	if (ret)
5621da177e4SLinus Torvalds 		return ret;
5631da177e4SLinus Torvalds 
56465e5a0e1SDaniel Drake 	c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size);
56565e5a0e1SDaniel Drake 	c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
5661da177e4SLinus Torvalds 	if (!c->inocache_list) {
5671da177e4SLinus Torvalds 		ret = -ENOMEM;
5681da177e4SLinus Torvalds 		goto out_wbuf;
5691da177e4SLinus Torvalds 	}
5701da177e4SLinus Torvalds 
571aa98d7cfSKaiGai Kohei 	jffs2_init_xattr_subsystem(c);
572aa98d7cfSKaiGai Kohei 
5731da177e4SLinus Torvalds 	if ((ret = jffs2_do_mount_fs(c)))
5741da177e4SLinus Torvalds 		goto out_inohash;
5751da177e4SLinus Torvalds 
5769c261b33SJoe Perches 	jffs2_dbg(1, "%s(): Getting root inode\n", __func__);
5775451f79fSDavid Howells 	root_i = jffs2_iget(sb, 1);
5785451f79fSDavid Howells 	if (IS_ERR(root_i)) {
5799c261b33SJoe Perches 		jffs2_dbg(1, "get root inode failed\n");
5805451f79fSDavid Howells 		ret = PTR_ERR(root_i);
5815451f79fSDavid Howells 		goto out_root;
5821da177e4SLinus Torvalds 	}
5831da177e4SLinus Torvalds 
5845451f79fSDavid Howells 	ret = -ENOMEM;
5855451f79fSDavid Howells 
586623ff773SLinus Torvalds 	jffs2_dbg(1, "%s(): d_make_root()\n", __func__);
58748fde701SAl Viro 	sb->s_root = d_make_root(root_i);
5881da177e4SLinus Torvalds 	if (!sb->s_root)
58948fde701SAl Viro 		goto out_root;
5901da177e4SLinus Torvalds 
5911da177e4SLinus Torvalds 	sb->s_maxbytes = 0xFFFFFFFF;
59209cbfeafSKirill A. Shutemov 	sb->s_blocksize = PAGE_SIZE;
59309cbfeafSKirill A. Shutemov 	sb->s_blocksize_bits = PAGE_SHIFT;
5941da177e4SLinus Torvalds 	sb->s_magic = JFFS2_SUPER_MAGIC;
59522b13969SDeepa Dinamani 	sb->s_time_min = 0;
59622b13969SDeepa Dinamani 	sb->s_time_max = U32_MAX;
59722b13969SDeepa Dinamani 
598bc98a42cSDavid Howells 	if (!sb_rdonly(sb))
5991da177e4SLinus Torvalds 		jffs2_start_garbage_collect_thread(c);
6001da177e4SLinus Torvalds 	return 0;
6011da177e4SLinus Torvalds 
6025451f79fSDavid Howells out_root:
6031da177e4SLinus Torvalds 	jffs2_free_ino_caches(c);
6041da177e4SLinus Torvalds 	jffs2_free_raw_node_refs(c);
6051d5cfdb0STetsuo Handa 	kvfree(c->blocks);
606aa98d7cfSKaiGai Kohei 	jffs2_clear_xattr_subsystem(c);
607c14adb1cSBaokun Li 	jffs2_sum_exit(c);
6084c7c44eeSBaokun Li  out_inohash:
6091da177e4SLinus Torvalds 	kfree(c->inocache_list);
6101da177e4SLinus Torvalds  out_wbuf:
6111da177e4SLinus Torvalds 	jffs2_flash_cleanup(c);
6121da177e4SLinus Torvalds 
6131da177e4SLinus Torvalds 	return ret;
6141da177e4SLinus Torvalds }
6151da177e4SLinus Torvalds 
jffs2_gc_release_inode(struct jffs2_sb_info * c,struct jffs2_inode_info * f)6161da177e4SLinus Torvalds void jffs2_gc_release_inode(struct jffs2_sb_info *c,
6171da177e4SLinus Torvalds 				   struct jffs2_inode_info *f)
6181da177e4SLinus Torvalds {
6191da177e4SLinus Torvalds 	iput(OFNI_EDONI_2SFFJ(f));
6201da177e4SLinus Torvalds }
6211da177e4SLinus Torvalds 
jffs2_gc_fetch_inode(struct jffs2_sb_info * c,int inum,int unlinked)6221da177e4SLinus Torvalds struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
6231b690b48SDavid Woodhouse 					      int inum, int unlinked)
6241da177e4SLinus Torvalds {
6251da177e4SLinus Torvalds 	struct inode *inode;
6261da177e4SLinus Torvalds 	struct jffs2_inode_cache *ic;
6271b690b48SDavid Woodhouse 
6281b690b48SDavid Woodhouse 	if (unlinked) {
6291da177e4SLinus Torvalds 		/* The inode has zero nlink but its nodes weren't yet marked
6301da177e4SLinus Torvalds 		   obsolete. This has to be because we're still waiting for
6311da177e4SLinus Torvalds 		   the final (close() and) iput() to happen.
6321da177e4SLinus Torvalds 
6331da177e4SLinus Torvalds 		   There's a possibility that the final iput() could have
6341da177e4SLinus Torvalds 		   happened while we were contemplating. In order to ensure
6351da177e4SLinus Torvalds 		   that we don't cause a new read_inode() (which would fail)
6361da177e4SLinus Torvalds 		   for the inode in question, we use ilookup() in this case
6371da177e4SLinus Torvalds 		   instead of iget().
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 		   The nlink can't _become_ zero at this point because we're
6401da177e4SLinus Torvalds 		   holding the alloc_sem, and jffs2_do_unlink() would also
6411da177e4SLinus Torvalds 		   need that while decrementing nlink on any inode.
6421da177e4SLinus Torvalds 		*/
6431da177e4SLinus Torvalds 		inode = ilookup(OFNI_BS_2SFFJ(c), inum);
6441da177e4SLinus Torvalds 		if (!inode) {
6459c261b33SJoe Perches 			jffs2_dbg(1, "ilookup() failed for ino #%u; inode is probably deleted.\n",
6469c261b33SJoe Perches 				  inum);
6471da177e4SLinus Torvalds 
6481da177e4SLinus Torvalds 			spin_lock(&c->inocache_lock);
6491da177e4SLinus Torvalds 			ic = jffs2_get_ino_cache(c, inum);
6501da177e4SLinus Torvalds 			if (!ic) {
6519c261b33SJoe Perches 				jffs2_dbg(1, "Inode cache for ino #%u is gone\n",
6529c261b33SJoe Perches 					  inum);
6531da177e4SLinus Torvalds 				spin_unlock(&c->inocache_lock);
6541da177e4SLinus Torvalds 				return NULL;
6551da177e4SLinus Torvalds 			}
6561da177e4SLinus Torvalds 			if (ic->state != INO_STATE_CHECKEDABSENT) {
6571da177e4SLinus Torvalds 				/* Wait for progress. Don't just loop */
6589c261b33SJoe Perches 				jffs2_dbg(1, "Waiting for ino #%u in state %d\n",
6599c261b33SJoe Perches 					  ic->ino, ic->state);
6601da177e4SLinus Torvalds 				sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
6611da177e4SLinus Torvalds 			} else {
6621da177e4SLinus Torvalds 				spin_unlock(&c->inocache_lock);
6631da177e4SLinus Torvalds 			}
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds 			return NULL;
6661da177e4SLinus Torvalds 		}
6671da177e4SLinus Torvalds 	} else {
6681da177e4SLinus Torvalds 		/* Inode has links to it still; they're not going away because
6691da177e4SLinus Torvalds 		   jffs2_do_unlink() would need the alloc_sem and we have it.
6701da177e4SLinus Torvalds 		   Just iget() it, and if read_inode() is necessary that's OK.
6711da177e4SLinus Torvalds 		*/
6725451f79fSDavid Howells 		inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);
6735451f79fSDavid Howells 		if (IS_ERR(inode))
6745451f79fSDavid Howells 			return ERR_CAST(inode);
6751da177e4SLinus Torvalds 	}
6761da177e4SLinus Torvalds 	if (is_bad_inode(inode)) {
677da320f05SJoe Perches 		pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d\n",
6781b690b48SDavid Woodhouse 			  inum, unlinked);
6791da177e4SLinus Torvalds 		/* NB. This will happen again. We need to do something appropriate here. */
6801da177e4SLinus Torvalds 		iput(inode);
6811da177e4SLinus Torvalds 		return ERR_PTR(-EIO);
6821da177e4SLinus Torvalds 	}
6831da177e4SLinus Torvalds 
6841da177e4SLinus Torvalds 	return JFFS2_INODE_INFO(inode);
6851da177e4SLinus Torvalds }
6861da177e4SLinus Torvalds 
jffs2_flash_setup(struct jffs2_sb_info * c)6871da177e4SLinus Torvalds static int jffs2_flash_setup(struct jffs2_sb_info *c) {
6881da177e4SLinus Torvalds 	int ret = 0;
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds 	if (jffs2_cleanmarker_oob(c)) {
6911da177e4SLinus Torvalds 		/* NAND flash... do setup accordingly */
6921da177e4SLinus Torvalds 		ret = jffs2_nand_flash_setup(c);
6931da177e4SLinus Torvalds 		if (ret)
6941da177e4SLinus Torvalds 			return ret;
6951da177e4SLinus Torvalds 	}
6961da177e4SLinus Torvalds 
6978f15fd55SAndrew Victor 	/* and Dataflash */
6988f15fd55SAndrew Victor 	if (jffs2_dataflash(c)) {
6998f15fd55SAndrew Victor 		ret = jffs2_dataflash_setup(c);
7008f15fd55SAndrew Victor 		if (ret)
7018f15fd55SAndrew Victor 			return ret;
7028f15fd55SAndrew Victor 	}
7038f15fd55SAndrew Victor 
70459da721aSNicolas Pitre 	/* and Intel "Sibley" flash */
70559da721aSNicolas Pitre 	if (jffs2_nor_wbuf_flash(c)) {
70659da721aSNicolas Pitre 		ret = jffs2_nor_wbuf_flash_setup(c);
70759da721aSNicolas Pitre 		if (ret)
70859da721aSNicolas Pitre 			return ret;
70959da721aSNicolas Pitre 	}
71059da721aSNicolas Pitre 
7110029da3bSArtem Bityutskiy 	/* and an UBI volume */
7120029da3bSArtem Bityutskiy 	if (jffs2_ubivol(c)) {
7130029da3bSArtem Bityutskiy 		ret = jffs2_ubivol_setup(c);
7140029da3bSArtem Bityutskiy 		if (ret)
7150029da3bSArtem Bityutskiy 			return ret;
7160029da3bSArtem Bityutskiy 	}
7170029da3bSArtem Bityutskiy 
7181da177e4SLinus Torvalds 	return ret;
7191da177e4SLinus Torvalds }
7201da177e4SLinus Torvalds 
jffs2_flash_cleanup(struct jffs2_sb_info * c)7211da177e4SLinus Torvalds void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
7221da177e4SLinus Torvalds 
7231da177e4SLinus Torvalds 	if (jffs2_cleanmarker_oob(c)) {
7241da177e4SLinus Torvalds 		jffs2_nand_flash_cleanup(c);
7251da177e4SLinus Torvalds 	}
7261da177e4SLinus Torvalds 
7278f15fd55SAndrew Victor 	/* and DataFlash */
7288f15fd55SAndrew Victor 	if (jffs2_dataflash(c)) {
7298f15fd55SAndrew Victor 		jffs2_dataflash_cleanup(c);
7308f15fd55SAndrew Victor 	}
73159da721aSNicolas Pitre 
73259da721aSNicolas Pitre 	/* and Intel "Sibley" flash */
73359da721aSNicolas Pitre 	if (jffs2_nor_wbuf_flash(c)) {
73459da721aSNicolas Pitre 		jffs2_nor_wbuf_flash_cleanup(c);
73559da721aSNicolas Pitre 	}
7360029da3bSArtem Bityutskiy 
7370029da3bSArtem Bityutskiy 	/* and an UBI volume */
7380029da3bSArtem Bityutskiy 	if (jffs2_ubivol(c)) {
7390029da3bSArtem Bityutskiy 		jffs2_ubivol_cleanup(c);
7400029da3bSArtem Bityutskiy 	}
7411da177e4SLinus Torvalds }
742