xref: /OK3568_Linux_fs/kernel/fs/jffs2/write.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * JFFS2 -- Journalling Flash File System, Version 2.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright © 2001-2007 Red Hat, Inc.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Created by David Woodhouse <dwmw2@infradead.org>
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * For licensing information, see the file 'LICENCE' in this directory.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/fs.h>
16*4882a593Smuzhiyun #include <linux/crc32.h>
17*4882a593Smuzhiyun #include <linux/pagemap.h>
18*4882a593Smuzhiyun #include <linux/mtd/mtd.h>
19*4882a593Smuzhiyun #include "nodelist.h"
20*4882a593Smuzhiyun #include "compr.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 
jffs2_do_new_inode(struct jffs2_sb_info * c,struct jffs2_inode_info * f,uint32_t mode,struct jffs2_raw_inode * ri)23*4882a593Smuzhiyun int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
24*4882a593Smuzhiyun 		       uint32_t mode, struct jffs2_raw_inode *ri)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	struct jffs2_inode_cache *ic;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	ic = jffs2_alloc_inode_cache();
29*4882a593Smuzhiyun 	if (!ic) {
30*4882a593Smuzhiyun 		return -ENOMEM;
31*4882a593Smuzhiyun 	}
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	memset(ic, 0, sizeof(*ic));
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	f->inocache = ic;
36*4882a593Smuzhiyun 	f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */
37*4882a593Smuzhiyun 	f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
38*4882a593Smuzhiyun 	f->inocache->state = INO_STATE_PRESENT;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	jffs2_add_ino_cache(c, f->inocache);
41*4882a593Smuzhiyun 	jffs2_dbg(1, "%s(): Assigned ino# %d\n", __func__, f->inocache->ino);
42*4882a593Smuzhiyun 	ri->ino = cpu_to_je32(f->inocache->ino);
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
45*4882a593Smuzhiyun 	ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
46*4882a593Smuzhiyun 	ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
47*4882a593Smuzhiyun 	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
48*4882a593Smuzhiyun 	ri->mode = cpu_to_jemode(mode);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	f->highest_version = 1;
51*4882a593Smuzhiyun 	ri->version = cpu_to_je32(f->highest_version);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	return 0;
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
57*4882a593Smuzhiyun    write it to the flash, link it into the existing inode/fragment list */
58*4882a593Smuzhiyun 
jffs2_write_dnode(struct jffs2_sb_info * c,struct jffs2_inode_info * f,struct jffs2_raw_inode * ri,const unsigned char * data,uint32_t datalen,int alloc_mode)59*4882a593Smuzhiyun struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
60*4882a593Smuzhiyun 					   struct jffs2_raw_inode *ri, const unsigned char *data,
61*4882a593Smuzhiyun 					   uint32_t datalen, int alloc_mode)
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct jffs2_full_dnode *fn;
65*4882a593Smuzhiyun 	size_t retlen;
66*4882a593Smuzhiyun 	uint32_t flash_ofs;
67*4882a593Smuzhiyun 	struct kvec vecs[2];
68*4882a593Smuzhiyun 	int ret;
69*4882a593Smuzhiyun 	int retried = 0;
70*4882a593Smuzhiyun 	unsigned long cnt = 2;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
73*4882a593Smuzhiyun 		pr_crit("Eep. CRC not correct in jffs2_write_dnode()\n");
74*4882a593Smuzhiyun 		BUG();
75*4882a593Smuzhiyun 	}
76*4882a593Smuzhiyun 	   );
77*4882a593Smuzhiyun 	vecs[0].iov_base = ri;
78*4882a593Smuzhiyun 	vecs[0].iov_len = sizeof(*ri);
79*4882a593Smuzhiyun 	vecs[1].iov_base = (unsigned char *)data;
80*4882a593Smuzhiyun 	vecs[1].iov_len = datalen;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
83*4882a593Smuzhiyun 		pr_warn("%s(): ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n",
84*4882a593Smuzhiyun 			__func__, je32_to_cpu(ri->totlen),
85*4882a593Smuzhiyun 			sizeof(*ri), datalen);
86*4882a593Smuzhiyun 	}
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	fn = jffs2_alloc_full_dnode();
89*4882a593Smuzhiyun 	if (!fn)
90*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	/* check number of valid vecs */
93*4882a593Smuzhiyun 	if (!datalen || !data)
94*4882a593Smuzhiyun 		cnt = 1;
95*4882a593Smuzhiyun  retry:
96*4882a593Smuzhiyun 	flash_ofs = write_ofs(c);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
101*4882a593Smuzhiyun 		BUG_ON(!retried);
102*4882a593Smuzhiyun 		jffs2_dbg(1, "%s(): dnode_version %d, highest version %d -> updating dnode\n",
103*4882a593Smuzhiyun 			  __func__,
104*4882a593Smuzhiyun 			  je32_to_cpu(ri->version), f->highest_version);
105*4882a593Smuzhiyun 		ri->version = cpu_to_je32(++f->highest_version);
106*4882a593Smuzhiyun 		ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
110*4882a593Smuzhiyun 				 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	if (ret || (retlen != sizeof(*ri) + datalen)) {
113*4882a593Smuzhiyun 		pr_notice("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
114*4882a593Smuzhiyun 			  sizeof(*ri) + datalen, flash_ofs, ret, retlen);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 		/* Mark the space as dirtied */
117*4882a593Smuzhiyun 		if (retlen) {
118*4882a593Smuzhiyun 			/* Don't change raw->size to match retlen. We may have
119*4882a593Smuzhiyun 			   written the node header already, and only the data will
120*4882a593Smuzhiyun 			   seem corrupted, in which case the scan would skip over
121*4882a593Smuzhiyun 			   any node we write before the original intended end of
122*4882a593Smuzhiyun 			   this node */
123*4882a593Smuzhiyun 			jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL);
124*4882a593Smuzhiyun 		} else {
125*4882a593Smuzhiyun 			pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n",
126*4882a593Smuzhiyun 				  flash_ofs);
127*4882a593Smuzhiyun 		}
128*4882a593Smuzhiyun 		if (!retried && alloc_mode != ALLOC_NORETRY) {
129*4882a593Smuzhiyun 			/* Try to reallocate space and retry */
130*4882a593Smuzhiyun 			uint32_t dummy;
131*4882a593Smuzhiyun 			struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 			retried = 1;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 			jffs2_dbg(1, "Retrying failed write.\n");
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 			jffs2_dbg_acct_sanity_check(c,jeb);
138*4882a593Smuzhiyun 			jffs2_dbg_acct_paranoia_check(c, jeb);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 			if (alloc_mode == ALLOC_GC) {
141*4882a593Smuzhiyun 				ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &dummy,
142*4882a593Smuzhiyun 							     JFFS2_SUMMARY_INODE_SIZE);
143*4882a593Smuzhiyun 			} else {
144*4882a593Smuzhiyun 				/* Locking pain */
145*4882a593Smuzhiyun 				mutex_unlock(&f->sem);
146*4882a593Smuzhiyun 				jffs2_complete_reservation(c);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 				ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &dummy,
149*4882a593Smuzhiyun 							  alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
150*4882a593Smuzhiyun 				mutex_lock(&f->sem);
151*4882a593Smuzhiyun 			}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 			if (!ret) {
154*4882a593Smuzhiyun 				flash_ofs = write_ofs(c);
155*4882a593Smuzhiyun 				jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write.\n",
156*4882a593Smuzhiyun 					  flash_ofs);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 				jffs2_dbg_acct_sanity_check(c,jeb);
159*4882a593Smuzhiyun 				jffs2_dbg_acct_paranoia_check(c, jeb);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 				goto retry;
162*4882a593Smuzhiyun 			}
163*4882a593Smuzhiyun 			jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n",
164*4882a593Smuzhiyun 				  ret);
165*4882a593Smuzhiyun 		}
166*4882a593Smuzhiyun 		/* Release the full_dnode which is now useless, and return */
167*4882a593Smuzhiyun 		jffs2_free_full_dnode(fn);
168*4882a593Smuzhiyun 		return ERR_PTR(ret?ret:-EIO);
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 	/* Mark the space used */
171*4882a593Smuzhiyun 	/* If node covers at least a whole page, or if it starts at the
172*4882a593Smuzhiyun 	   beginning of a page and runs to the end of the file, or if
173*4882a593Smuzhiyun 	   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
174*4882a593Smuzhiyun 	*/
175*4882a593Smuzhiyun 	if ((je32_to_cpu(ri->dsize) >= PAGE_SIZE) ||
176*4882a593Smuzhiyun 	    ( ((je32_to_cpu(ri->offset)&(PAGE_SIZE-1))==0) &&
177*4882a593Smuzhiyun 	      (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) ==  je32_to_cpu(ri->isize)))) {
178*4882a593Smuzhiyun 		flash_ofs |= REF_PRISTINE;
179*4882a593Smuzhiyun 	} else {
180*4882a593Smuzhiyun 		flash_ofs |= REF_NORMAL;
181*4882a593Smuzhiyun 	}
182*4882a593Smuzhiyun 	fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache);
183*4882a593Smuzhiyun 	if (IS_ERR(fn->raw)) {
184*4882a593Smuzhiyun 		void *hold_err = fn->raw;
185*4882a593Smuzhiyun 		/* Release the full_dnode which is now useless, and return */
186*4882a593Smuzhiyun 		jffs2_free_full_dnode(fn);
187*4882a593Smuzhiyun 		return ERR_CAST(hold_err);
188*4882a593Smuzhiyun 	}
189*4882a593Smuzhiyun 	fn->ofs = je32_to_cpu(ri->offset);
190*4882a593Smuzhiyun 	fn->size = je32_to_cpu(ri->dsize);
191*4882a593Smuzhiyun 	fn->frags = 0;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	jffs2_dbg(1, "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
194*4882a593Smuzhiyun 		  flash_ofs & ~3, flash_ofs & 3, je32_to_cpu(ri->dsize),
195*4882a593Smuzhiyun 		  je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
196*4882a593Smuzhiyun 		  je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen));
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	if (retried) {
199*4882a593Smuzhiyun 		jffs2_dbg_acct_sanity_check(c,NULL);
200*4882a593Smuzhiyun 	}
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	return fn;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
jffs2_write_dirent(struct jffs2_sb_info * c,struct jffs2_inode_info * f,struct jffs2_raw_dirent * rd,const unsigned char * name,uint32_t namelen,int alloc_mode)205*4882a593Smuzhiyun struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
206*4882a593Smuzhiyun 					     struct jffs2_raw_dirent *rd, const unsigned char *name,
207*4882a593Smuzhiyun 					     uint32_t namelen, int alloc_mode)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	struct jffs2_full_dirent *fd;
210*4882a593Smuzhiyun 	size_t retlen;
211*4882a593Smuzhiyun 	struct kvec vecs[2];
212*4882a593Smuzhiyun 	uint32_t flash_ofs;
213*4882a593Smuzhiyun 	int retried = 0;
214*4882a593Smuzhiyun 	int ret;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	jffs2_dbg(1, "%s(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
217*4882a593Smuzhiyun 		  __func__,
218*4882a593Smuzhiyun 		  je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
219*4882a593Smuzhiyun 		  je32_to_cpu(rd->name_crc));
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
222*4882a593Smuzhiyun 		pr_crit("Eep. CRC not correct in jffs2_write_dirent()\n");
223*4882a593Smuzhiyun 		BUG();
224*4882a593Smuzhiyun 	   });
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	if (strnlen(name, namelen) != namelen) {
227*4882a593Smuzhiyun 		/* This should never happen, but seems to have done on at least one
228*4882a593Smuzhiyun 		   occasion: https://dev.laptop.org/ticket/4184 */
229*4882a593Smuzhiyun 		pr_crit("Error in jffs2_write_dirent() -- name contains zero bytes!\n");
230*4882a593Smuzhiyun 		pr_crit("Directory inode #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x\n",
231*4882a593Smuzhiyun 			je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
232*4882a593Smuzhiyun 			je32_to_cpu(rd->name_crc));
233*4882a593Smuzhiyun 		WARN_ON(1);
234*4882a593Smuzhiyun 		return ERR_PTR(-EIO);
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	vecs[0].iov_base = rd;
238*4882a593Smuzhiyun 	vecs[0].iov_len = sizeof(*rd);
239*4882a593Smuzhiyun 	vecs[1].iov_base = (unsigned char *)name;
240*4882a593Smuzhiyun 	vecs[1].iov_len = namelen;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	fd = jffs2_alloc_full_dirent(namelen+1);
243*4882a593Smuzhiyun 	if (!fd)
244*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	fd->version = je32_to_cpu(rd->version);
247*4882a593Smuzhiyun 	fd->ino = je32_to_cpu(rd->ino);
248*4882a593Smuzhiyun 	fd->nhash = full_name_hash(NULL, name, namelen);
249*4882a593Smuzhiyun 	fd->type = rd->type;
250*4882a593Smuzhiyun 	memcpy(fd->name, name, namelen);
251*4882a593Smuzhiyun 	fd->name[namelen]=0;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun  retry:
254*4882a593Smuzhiyun 	flash_ofs = write_ofs(c);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
259*4882a593Smuzhiyun 		BUG_ON(!retried);
260*4882a593Smuzhiyun 		jffs2_dbg(1, "%s(): dirent_version %d, highest version %d -> updating dirent\n",
261*4882a593Smuzhiyun 			  __func__,
262*4882a593Smuzhiyun 			  je32_to_cpu(rd->version), f->highest_version);
263*4882a593Smuzhiyun 		rd->version = cpu_to_je32(++f->highest_version);
264*4882a593Smuzhiyun 		fd->version = je32_to_cpu(rd->version);
265*4882a593Smuzhiyun 		rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
269*4882a593Smuzhiyun 				 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
270*4882a593Smuzhiyun 	if (ret || (retlen != sizeof(*rd) + namelen)) {
271*4882a593Smuzhiyun 		pr_notice("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
272*4882a593Smuzhiyun 			  sizeof(*rd) + namelen, flash_ofs, ret, retlen);
273*4882a593Smuzhiyun 		/* Mark the space as dirtied */
274*4882a593Smuzhiyun 		if (retlen) {
275*4882a593Smuzhiyun 			jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL);
276*4882a593Smuzhiyun 		} else {
277*4882a593Smuzhiyun 			pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n",
278*4882a593Smuzhiyun 				  flash_ofs);
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 		if (!retried) {
281*4882a593Smuzhiyun 			/* Try to reallocate space and retry */
282*4882a593Smuzhiyun 			uint32_t dummy;
283*4882a593Smuzhiyun 			struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 			retried = 1;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 			jffs2_dbg(1, "Retrying failed write.\n");
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 			jffs2_dbg_acct_sanity_check(c,jeb);
290*4882a593Smuzhiyun 			jffs2_dbg_acct_paranoia_check(c, jeb);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 			if (alloc_mode == ALLOC_GC) {
293*4882a593Smuzhiyun 				ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &dummy,
294*4882a593Smuzhiyun 							     JFFS2_SUMMARY_DIRENT_SIZE(namelen));
295*4882a593Smuzhiyun 			} else {
296*4882a593Smuzhiyun 				/* Locking pain */
297*4882a593Smuzhiyun 				mutex_unlock(&f->sem);
298*4882a593Smuzhiyun 				jffs2_complete_reservation(c);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 				ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &dummy,
301*4882a593Smuzhiyun 							  alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
302*4882a593Smuzhiyun 				mutex_lock(&f->sem);
303*4882a593Smuzhiyun 			}
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 			if (!ret) {
306*4882a593Smuzhiyun 				flash_ofs = write_ofs(c);
307*4882a593Smuzhiyun 				jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write\n",
308*4882a593Smuzhiyun 					  flash_ofs);
309*4882a593Smuzhiyun 				jffs2_dbg_acct_sanity_check(c,jeb);
310*4882a593Smuzhiyun 				jffs2_dbg_acct_paranoia_check(c, jeb);
311*4882a593Smuzhiyun 				goto retry;
312*4882a593Smuzhiyun 			}
313*4882a593Smuzhiyun 			jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n",
314*4882a593Smuzhiyun 				  ret);
315*4882a593Smuzhiyun 		}
316*4882a593Smuzhiyun 		/* Release the full_dnode which is now useless, and return */
317*4882a593Smuzhiyun 		jffs2_free_full_dirent(fd);
318*4882a593Smuzhiyun 		return ERR_PTR(ret?ret:-EIO);
319*4882a593Smuzhiyun 	}
320*4882a593Smuzhiyun 	/* Mark the space used */
321*4882a593Smuzhiyun 	fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | dirent_node_state(rd),
322*4882a593Smuzhiyun 					      PAD(sizeof(*rd)+namelen), f->inocache);
323*4882a593Smuzhiyun 	if (IS_ERR(fd->raw)) {
324*4882a593Smuzhiyun 		void *hold_err = fd->raw;
325*4882a593Smuzhiyun 		/* Release the full_dirent which is now useless, and return */
326*4882a593Smuzhiyun 		jffs2_free_full_dirent(fd);
327*4882a593Smuzhiyun 		return ERR_CAST(hold_err);
328*4882a593Smuzhiyun 	}
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	if (retried) {
331*4882a593Smuzhiyun 		jffs2_dbg_acct_sanity_check(c,NULL);
332*4882a593Smuzhiyun 	}
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	return fd;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun /* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that
338*4882a593Smuzhiyun    we don't have to go digging in struct inode or its equivalent. It should set:
339*4882a593Smuzhiyun    mode, uid, gid, (starting)isize, atime, ctime, mtime */
jffs2_write_inode_range(struct jffs2_sb_info * c,struct jffs2_inode_info * f,struct jffs2_raw_inode * ri,unsigned char * buf,uint32_t offset,uint32_t writelen,uint32_t * retlen)340*4882a593Smuzhiyun int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
341*4882a593Smuzhiyun 			    struct jffs2_raw_inode *ri, unsigned char *buf,
342*4882a593Smuzhiyun 			    uint32_t offset, uint32_t writelen, uint32_t *retlen)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	int ret = 0;
345*4882a593Smuzhiyun 	uint32_t writtenlen = 0;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	jffs2_dbg(1, "%s(): Ino #%u, ofs 0x%x, len 0x%x\n",
348*4882a593Smuzhiyun 		  __func__, f->inocache->ino, offset, writelen);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	while(writelen) {
351*4882a593Smuzhiyun 		struct jffs2_full_dnode *fn;
352*4882a593Smuzhiyun 		unsigned char *comprbuf = NULL;
353*4882a593Smuzhiyun 		uint16_t comprtype = JFFS2_COMPR_NONE;
354*4882a593Smuzhiyun 		uint32_t alloclen;
355*4882a593Smuzhiyun 		uint32_t datalen, cdatalen;
356*4882a593Smuzhiyun 		int retried = 0;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	retry:
359*4882a593Smuzhiyun 		jffs2_dbg(2, "jffs2_commit_write() loop: 0x%x to write to 0x%x\n",
360*4882a593Smuzhiyun 			  writelen, offset);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 		ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN,
363*4882a593Smuzhiyun 					&alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
364*4882a593Smuzhiyun 		if (ret) {
365*4882a593Smuzhiyun 			jffs2_dbg(1, "jffs2_reserve_space returned %d\n", ret);
366*4882a593Smuzhiyun 			break;
367*4882a593Smuzhiyun 		}
368*4882a593Smuzhiyun 		mutex_lock(&f->sem);
369*4882a593Smuzhiyun 		datalen = min_t(uint32_t, writelen,
370*4882a593Smuzhiyun 				PAGE_SIZE - (offset & (PAGE_SIZE-1)));
371*4882a593Smuzhiyun 		cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 		comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
376*4882a593Smuzhiyun 		ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
377*4882a593Smuzhiyun 		ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
378*4882a593Smuzhiyun 		ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 		ri->ino = cpu_to_je32(f->inocache->ino);
381*4882a593Smuzhiyun 		ri->version = cpu_to_je32(++f->highest_version);
382*4882a593Smuzhiyun 		ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
383*4882a593Smuzhiyun 		ri->offset = cpu_to_je32(offset);
384*4882a593Smuzhiyun 		ri->csize = cpu_to_je32(cdatalen);
385*4882a593Smuzhiyun 		ri->dsize = cpu_to_je32(datalen);
386*4882a593Smuzhiyun 		ri->compr = comprtype & 0xff;
387*4882a593Smuzhiyun 		ri->usercompr = (comprtype >> 8 ) & 0xff;
388*4882a593Smuzhiyun 		ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
389*4882a593Smuzhiyun 		ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 		jffs2_free_comprbuf(comprbuf, buf);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 		if (IS_ERR(fn)) {
396*4882a593Smuzhiyun 			ret = PTR_ERR(fn);
397*4882a593Smuzhiyun 			mutex_unlock(&f->sem);
398*4882a593Smuzhiyun 			jffs2_complete_reservation(c);
399*4882a593Smuzhiyun 			if (!retried) {
400*4882a593Smuzhiyun 				/* Write error to be retried */
401*4882a593Smuzhiyun 				retried = 1;
402*4882a593Smuzhiyun 				jffs2_dbg(1, "Retrying node write in jffs2_write_inode_range()\n");
403*4882a593Smuzhiyun 				goto retry;
404*4882a593Smuzhiyun 			}
405*4882a593Smuzhiyun 			break;
406*4882a593Smuzhiyun 		}
407*4882a593Smuzhiyun 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
408*4882a593Smuzhiyun 		if (f->metadata) {
409*4882a593Smuzhiyun 			jffs2_mark_node_obsolete(c, f->metadata->raw);
410*4882a593Smuzhiyun 			jffs2_free_full_dnode(f->metadata);
411*4882a593Smuzhiyun 			f->metadata = NULL;
412*4882a593Smuzhiyun 		}
413*4882a593Smuzhiyun 		if (ret) {
414*4882a593Smuzhiyun 			/* Eep */
415*4882a593Smuzhiyun 			jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n",
416*4882a593Smuzhiyun 				  ret);
417*4882a593Smuzhiyun 			jffs2_mark_node_obsolete(c, fn->raw);
418*4882a593Smuzhiyun 			jffs2_free_full_dnode(fn);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 			mutex_unlock(&f->sem);
421*4882a593Smuzhiyun 			jffs2_complete_reservation(c);
422*4882a593Smuzhiyun 			break;
423*4882a593Smuzhiyun 		}
424*4882a593Smuzhiyun 		mutex_unlock(&f->sem);
425*4882a593Smuzhiyun 		jffs2_complete_reservation(c);
426*4882a593Smuzhiyun 		if (!datalen) {
427*4882a593Smuzhiyun 			pr_warn("Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
428*4882a593Smuzhiyun 			ret = -EIO;
429*4882a593Smuzhiyun 			break;
430*4882a593Smuzhiyun 		}
431*4882a593Smuzhiyun 		jffs2_dbg(1, "increasing writtenlen by %d\n", datalen);
432*4882a593Smuzhiyun 		writtenlen += datalen;
433*4882a593Smuzhiyun 		offset += datalen;
434*4882a593Smuzhiyun 		writelen -= datalen;
435*4882a593Smuzhiyun 		buf += datalen;
436*4882a593Smuzhiyun 	}
437*4882a593Smuzhiyun 	*retlen = writtenlen;
438*4882a593Smuzhiyun 	return ret;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
jffs2_do_create(struct jffs2_sb_info * c,struct jffs2_inode_info * dir_f,struct jffs2_inode_info * f,struct jffs2_raw_inode * ri,const struct qstr * qstr)441*4882a593Smuzhiyun int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
442*4882a593Smuzhiyun 		    struct jffs2_inode_info *f, struct jffs2_raw_inode *ri,
443*4882a593Smuzhiyun 		    const struct qstr *qstr)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct jffs2_raw_dirent *rd;
446*4882a593Smuzhiyun 	struct jffs2_full_dnode *fn;
447*4882a593Smuzhiyun 	struct jffs2_full_dirent *fd;
448*4882a593Smuzhiyun 	uint32_t alloclen;
449*4882a593Smuzhiyun 	int ret;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	/* Try to reserve enough space for both node and dirent.
452*4882a593Smuzhiyun 	 * Just the node will do for now, though
453*4882a593Smuzhiyun 	 */
454*4882a593Smuzhiyun 	ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
455*4882a593Smuzhiyun 				JFFS2_SUMMARY_INODE_SIZE);
456*4882a593Smuzhiyun 	jffs2_dbg(1, "%s(): reserved 0x%x bytes\n", __func__, alloclen);
457*4882a593Smuzhiyun 	if (ret)
458*4882a593Smuzhiyun 		return ret;
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	mutex_lock(&f->sem);
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	ri->data_crc = cpu_to_je32(0);
463*4882a593Smuzhiyun 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	jffs2_dbg(1, "jffs2_do_create created file with mode 0x%x\n",
468*4882a593Smuzhiyun 		  jemode_to_cpu(ri->mode));
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	if (IS_ERR(fn)) {
471*4882a593Smuzhiyun 		jffs2_dbg(1, "jffs2_write_dnode() failed\n");
472*4882a593Smuzhiyun 		/* Eeek. Wave bye bye */
473*4882a593Smuzhiyun 		mutex_unlock(&f->sem);
474*4882a593Smuzhiyun 		jffs2_complete_reservation(c);
475*4882a593Smuzhiyun 		return PTR_ERR(fn);
476*4882a593Smuzhiyun 	}
477*4882a593Smuzhiyun 	/* No data here. Only a metadata node, which will be
478*4882a593Smuzhiyun 	   obsoleted by the first data write
479*4882a593Smuzhiyun 	*/
480*4882a593Smuzhiyun 	f->metadata = fn;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	mutex_unlock(&f->sem);
483*4882a593Smuzhiyun 	jffs2_complete_reservation(c);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr);
486*4882a593Smuzhiyun 	if (ret)
487*4882a593Smuzhiyun 		return ret;
488*4882a593Smuzhiyun 	ret = jffs2_init_acl_post(&f->vfs_inode);
489*4882a593Smuzhiyun 	if (ret)
490*4882a593Smuzhiyun 		return ret;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen,
493*4882a593Smuzhiyun 				ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len));
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	if (ret) {
496*4882a593Smuzhiyun 		/* Eep. */
497*4882a593Smuzhiyun 		jffs2_dbg(1, "jffs2_reserve_space() for dirent failed\n");
498*4882a593Smuzhiyun 		return ret;
499*4882a593Smuzhiyun 	}
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	rd = jffs2_alloc_raw_dirent();
502*4882a593Smuzhiyun 	if (!rd) {
503*4882a593Smuzhiyun 		/* Argh. Now we treat it like a normal delete */
504*4882a593Smuzhiyun 		jffs2_complete_reservation(c);
505*4882a593Smuzhiyun 		return -ENOMEM;
506*4882a593Smuzhiyun 	}
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	mutex_lock(&dir_f->sem);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
511*4882a593Smuzhiyun 	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
512*4882a593Smuzhiyun 	rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len);
513*4882a593Smuzhiyun 	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	rd->pino = cpu_to_je32(dir_f->inocache->ino);
516*4882a593Smuzhiyun 	rd->version = cpu_to_je32(++dir_f->highest_version);
517*4882a593Smuzhiyun 	rd->ino = ri->ino;
518*4882a593Smuzhiyun 	rd->mctime = ri->ctime;
519*4882a593Smuzhiyun 	rd->nsize = qstr->len;
520*4882a593Smuzhiyun 	rd->type = DT_REG;
521*4882a593Smuzhiyun 	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
522*4882a593Smuzhiyun 	rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len));
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	jffs2_free_raw_dirent(rd);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	if (IS_ERR(fd)) {
529*4882a593Smuzhiyun 		/* dirent failed to write. Delete the inode normally
530*4882a593Smuzhiyun 		   as if it were the final unlink() */
531*4882a593Smuzhiyun 		jffs2_complete_reservation(c);
532*4882a593Smuzhiyun 		mutex_unlock(&dir_f->sem);
533*4882a593Smuzhiyun 		return PTR_ERR(fd);
534*4882a593Smuzhiyun 	}
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	/* Link the fd into the inode's list, obsoleting an old
537*4882a593Smuzhiyun 	   one if necessary. */
538*4882a593Smuzhiyun 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	jffs2_complete_reservation(c);
541*4882a593Smuzhiyun 	mutex_unlock(&dir_f->sem);
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	return 0;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 
jffs2_do_unlink(struct jffs2_sb_info * c,struct jffs2_inode_info * dir_f,const char * name,int namelen,struct jffs2_inode_info * dead_f,uint32_t time)547*4882a593Smuzhiyun int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
548*4882a593Smuzhiyun 		    const char *name, int namelen, struct jffs2_inode_info *dead_f,
549*4882a593Smuzhiyun 		    uint32_t time)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun 	struct jffs2_raw_dirent *rd;
552*4882a593Smuzhiyun 	struct jffs2_full_dirent *fd;
553*4882a593Smuzhiyun 	uint32_t alloclen;
554*4882a593Smuzhiyun 	int ret;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	if (!jffs2_can_mark_obsolete(c)) {
557*4882a593Smuzhiyun 		/* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 		rd = jffs2_alloc_raw_dirent();
560*4882a593Smuzhiyun 		if (!rd)
561*4882a593Smuzhiyun 			return -ENOMEM;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 		ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
564*4882a593Smuzhiyun 					ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
565*4882a593Smuzhiyun 		if (ret) {
566*4882a593Smuzhiyun 			jffs2_free_raw_dirent(rd);
567*4882a593Smuzhiyun 			return ret;
568*4882a593Smuzhiyun 		}
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 		mutex_lock(&dir_f->sem);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 		/* Build a deletion node */
573*4882a593Smuzhiyun 		rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
574*4882a593Smuzhiyun 		rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
575*4882a593Smuzhiyun 		rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
576*4882a593Smuzhiyun 		rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 		rd->pino = cpu_to_je32(dir_f->inocache->ino);
579*4882a593Smuzhiyun 		rd->version = cpu_to_je32(++dir_f->highest_version);
580*4882a593Smuzhiyun 		rd->ino = cpu_to_je32(0);
581*4882a593Smuzhiyun 		rd->mctime = cpu_to_je32(time);
582*4882a593Smuzhiyun 		rd->nsize = namelen;
583*4882a593Smuzhiyun 		rd->type = DT_UNKNOWN;
584*4882a593Smuzhiyun 		rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
585*4882a593Smuzhiyun 		rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 		fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 		jffs2_free_raw_dirent(rd);
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 		if (IS_ERR(fd)) {
592*4882a593Smuzhiyun 			jffs2_complete_reservation(c);
593*4882a593Smuzhiyun 			mutex_unlock(&dir_f->sem);
594*4882a593Smuzhiyun 			return PTR_ERR(fd);
595*4882a593Smuzhiyun 		}
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 		/* File it. This will mark the old one obsolete. */
598*4882a593Smuzhiyun 		jffs2_add_fd_to_list(c, fd, &dir_f->dents);
599*4882a593Smuzhiyun 		mutex_unlock(&dir_f->sem);
600*4882a593Smuzhiyun 	} else {
601*4882a593Smuzhiyun 		uint32_t nhash = full_name_hash(NULL, name, namelen);
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 		fd = dir_f->dents;
604*4882a593Smuzhiyun 		/* We don't actually want to reserve any space, but we do
605*4882a593Smuzhiyun 		   want to be holding the alloc_sem when we write to flash */
606*4882a593Smuzhiyun 		mutex_lock(&c->alloc_sem);
607*4882a593Smuzhiyun 		mutex_lock(&dir_f->sem);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 		for (fd = dir_f->dents; fd; fd = fd->next) {
610*4882a593Smuzhiyun 			if (fd->nhash == nhash &&
611*4882a593Smuzhiyun 			    !memcmp(fd->name, name, namelen) &&
612*4882a593Smuzhiyun 			    !fd->name[namelen]) {
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 				jffs2_dbg(1, "Marking old dirent node (ino #%u) @%08x obsolete\n",
615*4882a593Smuzhiyun 					  fd->ino, ref_offset(fd->raw));
616*4882a593Smuzhiyun 				jffs2_mark_node_obsolete(c, fd->raw);
617*4882a593Smuzhiyun 				/* We don't want to remove it from the list immediately,
618*4882a593Smuzhiyun 				   because that screws up getdents()/seek() semantics even
619*4882a593Smuzhiyun 				   more than they're screwed already. Turn it into a
620*4882a593Smuzhiyun 				   node-less deletion dirent instead -- a placeholder */
621*4882a593Smuzhiyun 				fd->raw = NULL;
622*4882a593Smuzhiyun 				fd->ino = 0;
623*4882a593Smuzhiyun 				break;
624*4882a593Smuzhiyun 			}
625*4882a593Smuzhiyun 		}
626*4882a593Smuzhiyun 		mutex_unlock(&dir_f->sem);
627*4882a593Smuzhiyun 	}
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	/* dead_f is NULL if this was a rename not a real unlink */
630*4882a593Smuzhiyun 	/* Also catch the !f->inocache case, where there was a dirent
631*4882a593Smuzhiyun 	   pointing to an inode which didn't exist. */
632*4882a593Smuzhiyun 	if (dead_f && dead_f->inocache) {
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 		mutex_lock(&dead_f->sem);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 		if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
637*4882a593Smuzhiyun 			while (dead_f->dents) {
638*4882a593Smuzhiyun 				/* There can be only deleted ones */
639*4882a593Smuzhiyun 				fd = dead_f->dents;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 				dead_f->dents = fd->next;
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 				if (fd->ino) {
644*4882a593Smuzhiyun 					pr_warn("Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
645*4882a593Smuzhiyun 						dead_f->inocache->ino,
646*4882a593Smuzhiyun 						fd->name, fd->ino);
647*4882a593Smuzhiyun 				} else {
648*4882a593Smuzhiyun 					jffs2_dbg(1, "Removing deletion dirent for \"%s\" from dir ino #%u\n",
649*4882a593Smuzhiyun 						  fd->name,
650*4882a593Smuzhiyun 						  dead_f->inocache->ino);
651*4882a593Smuzhiyun 				}
652*4882a593Smuzhiyun 				if (fd->raw)
653*4882a593Smuzhiyun 					jffs2_mark_node_obsolete(c, fd->raw);
654*4882a593Smuzhiyun 				jffs2_free_full_dirent(fd);
655*4882a593Smuzhiyun 			}
656*4882a593Smuzhiyun 			dead_f->inocache->pino_nlink = 0;
657*4882a593Smuzhiyun 		} else
658*4882a593Smuzhiyun 			dead_f->inocache->pino_nlink--;
659*4882a593Smuzhiyun 		/* NB: Caller must set inode nlink if appropriate */
660*4882a593Smuzhiyun 		mutex_unlock(&dead_f->sem);
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	jffs2_complete_reservation(c);
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	return 0;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun 
jffs2_do_link(struct jffs2_sb_info * c,struct jffs2_inode_info * dir_f,uint32_t ino,uint8_t type,const char * name,int namelen,uint32_t time)669*4882a593Smuzhiyun int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time)
670*4882a593Smuzhiyun {
671*4882a593Smuzhiyun 	struct jffs2_raw_dirent *rd;
672*4882a593Smuzhiyun 	struct jffs2_full_dirent *fd;
673*4882a593Smuzhiyun 	uint32_t alloclen;
674*4882a593Smuzhiyun 	int ret;
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 	rd = jffs2_alloc_raw_dirent();
677*4882a593Smuzhiyun 	if (!rd)
678*4882a593Smuzhiyun 		return -ENOMEM;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
681*4882a593Smuzhiyun 				ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
682*4882a593Smuzhiyun 	if (ret) {
683*4882a593Smuzhiyun 		jffs2_free_raw_dirent(rd);
684*4882a593Smuzhiyun 		return ret;
685*4882a593Smuzhiyun 	}
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	mutex_lock(&dir_f->sem);
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* Build a deletion node */
690*4882a593Smuzhiyun 	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
691*4882a593Smuzhiyun 	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
692*4882a593Smuzhiyun 	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
693*4882a593Smuzhiyun 	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun 	rd->pino = cpu_to_je32(dir_f->inocache->ino);
696*4882a593Smuzhiyun 	rd->version = cpu_to_je32(++dir_f->highest_version);
697*4882a593Smuzhiyun 	rd->ino = cpu_to_je32(ino);
698*4882a593Smuzhiyun 	rd->mctime = cpu_to_je32(time);
699*4882a593Smuzhiyun 	rd->nsize = namelen;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	rd->type = type;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
704*4882a593Smuzhiyun 	rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	jffs2_free_raw_dirent(rd);
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	if (IS_ERR(fd)) {
711*4882a593Smuzhiyun 		jffs2_complete_reservation(c);
712*4882a593Smuzhiyun 		mutex_unlock(&dir_f->sem);
713*4882a593Smuzhiyun 		return PTR_ERR(fd);
714*4882a593Smuzhiyun 	}
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	/* File it. This will mark the old one obsolete. */
717*4882a593Smuzhiyun 	jffs2_add_fd_to_list(c, fd, &dir_f->dents);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	jffs2_complete_reservation(c);
720*4882a593Smuzhiyun 	mutex_unlock(&dir_f->sem);
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun 	return 0;
723*4882a593Smuzhiyun }
724