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