~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/jffs2/write.c

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.15 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.73 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.144 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.193 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.193 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.73 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 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         ic = jffs2_alloc_inode_cache();
 29         if (!ic) {
 30                 return -ENOMEM;
 31         }
 32 
 33         memset(ic, 0, sizeof(*ic));
 34 
 35         f->inocache = ic;
 36         f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */
 37         f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
 38         f->inocache->state = INO_STATE_PRESENT;
 39 
 40         jffs2_add_ino_cache(c, f->inocache);
 41         jffs2_dbg(1, "%s(): Assigned ino# %d\n", __func__, f->inocache->ino);
 42         ri->ino = cpu_to_je32(f->inocache->ino);
 43 
 44         ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
 45         ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
 46         ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
 47         ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
 48         ri->mode = cpu_to_jemode(mode);
 49 
 50         f->highest_version = 1;
 51         ri->version = cpu_to_je32(f->highest_version);
 52 
 53         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 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         vecs[0].iov_base = ri;
 78         vecs[0].iov_len = sizeof(*ri);
 79         vecs[1].iov_base = (unsigned char *)data;
 80         vecs[1].iov_len = datalen;
 81 
 82         if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
 83                 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         fn = jffs2_alloc_full_dnode();
 89         if (!fn)
 90                 return ERR_PTR(-ENOMEM);
 91 
 92         /* check number of valid vecs */
 93         if (!datalen || !data)
 94                 cnt = 1;
 95  retry:
 96         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         if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
101                 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                 ri->version = cpu_to_je32(++f->highest_version);
106                 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
107         }
108 
109         ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
110                                  (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
111 
112         if (ret || (retlen != sizeof(*ri) + datalen)) {
113                 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                 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                         jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL);
124                 } else {
125                         pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n",
126                                   flash_ofs);
127                 }
128                 if (!retried && alloc_mode != ALLOC_NORETRY) {
129                         /* Try to reallocate space and retry */
130                         uint32_t dummy;
131                         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                         jffs2_dbg_acct_sanity_check(c,jeb);
138                         jffs2_dbg_acct_paranoia_check(c, jeb);
139 
140                         if (alloc_mode == ALLOC_GC) {
141                                 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &dummy,
142                                                              JFFS2_SUMMARY_INODE_SIZE);
143                         } else {
144                                 /* Locking pain */
145                                 mutex_unlock(&f->sem);
146                                 jffs2_complete_reservation(c);
147 
148                                 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &dummy,
149                                                           alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
150                                 mutex_lock(&f->sem);
151                         }
152 
153                         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                                 jffs2_dbg_acct_sanity_check(c,jeb);
159                                 jffs2_dbg_acct_paranoia_check(c, jeb);
160 
161                                 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                 jffs2_free_full_dnode(fn);
168                 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         if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
176             ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
177               (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) ==  je32_to_cpu(ri->isize)))) {
178                 flash_ofs |= REF_PRISTINE;
179         } else {
180                 flash_ofs |= REF_NORMAL;
181         }
182         fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache);
183         if (IS_ERR(fn->raw)) {
184                 void *hold_err = fn->raw;
185                 /* Release the full_dnode which is now useless, and return */
186                 jffs2_free_full_dnode(fn);
187                 return ERR_CAST(hold_err);
188         }
189         fn->ofs = je32_to_cpu(ri->offset);
190         fn->size = je32_to_cpu(ri->dsize);
191         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         if (retried) {
199                 jffs2_dbg_acct_sanity_check(c,NULL);
200         }
201 
202         return fn;
203 }
204 
205 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         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                 pr_crit("Error in jffs2_write_dirent() -- name contains zero bytes!\n");
230                 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                 WARN_ON(1);
234                 return ERR_PTR(-EIO);
235         }
236 
237         vecs[0].iov_base = rd;
238         vecs[0].iov_len = sizeof(*rd);
239         vecs[1].iov_base = (unsigned char *)name;
240         vecs[1].iov_len = namelen;
241 
242         fd = jffs2_alloc_full_dirent(namelen+1);
243         if (!fd)
244                 return ERR_PTR(-ENOMEM);
245 
246         fd->version = je32_to_cpu(rd->version);
247         fd->ino = je32_to_cpu(rd->ino);
248         fd->nhash = full_name_hash(name, namelen);
249         fd->type = rd->type;
250         memcpy(fd->name, name, namelen);
251         fd->name[namelen]=0;
252 
253  retry:
254         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         if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
259                 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                 rd->version = cpu_to_je32(++f->highest_version);
264                 fd->version = je32_to_cpu(rd->version);
265                 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
266         }
267 
268         ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
269                                  (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
270         if (ret || (retlen != sizeof(*rd) + namelen)) {
271                 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                 if (retlen) {
275                         jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL);
276                 } else {
277                         pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n",
278                                   flash_ofs);
279                 }
280                 if (!retried) {
281                         /* Try to reallocate space and retry */
282                         uint32_t dummy;
283                         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                         jffs2_dbg_acct_sanity_check(c,jeb);
290                         jffs2_dbg_acct_paranoia_check(c, jeb);
291 
292                         if (alloc_mode == ALLOC_GC) {
293                                 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &dummy,
294                                                              JFFS2_SUMMARY_DIRENT_SIZE(namelen));
295                         } else {
296                                 /* Locking pain */
297                                 mutex_unlock(&f->sem);
298                                 jffs2_complete_reservation(c);
299 
300                                 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &dummy,
301                                                           alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
302                                 mutex_lock(&f->sem);
303                         }
304 
305                         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                                 jffs2_dbg_acct_sanity_check(c,jeb);
310                                 jffs2_dbg_acct_paranoia_check(c, jeb);
311                                 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                 jffs2_free_full_dirent(fd);
318                 return ERR_PTR(ret?ret:-EIO);
319         }
320         /* Mark the space used */
321         fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | dirent_node_state(rd),
322                                               PAD(sizeof(*rd)+namelen), f->inocache);
323         if (IS_ERR(fd->raw)) {
324                 void *hold_err = fd->raw;
325                 /* Release the full_dirent which is now useless, and return */
326                 jffs2_free_full_dirent(fd);
327                 return ERR_CAST(hold_err);
328         }
329 
330         if (retried) {
331                 jffs2_dbg_acct_sanity_check(c,NULL);
332         }
333 
334         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 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         while(writelen) {
351                 struct jffs2_full_dnode *fn;
352                 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                 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN,
363                                         &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
364                 if (ret) {
365                         jffs2_dbg(1, "jffs2_reserve_space returned %d\n", ret);
366                         break;
367                 }
368                 mutex_lock(&f->sem);
369                 datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1)));
370                 cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
371 
372                 comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);
373 
374                 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
375                 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
376                 ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
377                 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
378 
379                 ri->ino = cpu_to_je32(f->inocache->ino);
380                 ri->version = cpu_to_je32(++f->highest_version);
381                 ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
382                 ri->offset = cpu_to_je32(offset);
383                 ri->csize = cpu_to_je32(cdatalen);
384                 ri->dsize = cpu_to_je32(datalen);
385                 ri->compr = comprtype & 0xff;
386                 ri->usercompr = (comprtype >> 8 ) & 0xff;
387                 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
388                 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
389 
390                 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
391 
392                 jffs2_free_comprbuf(comprbuf, buf);
393 
394                 if (IS_ERR(fn)) {
395                         ret = PTR_ERR(fn);
396                         mutex_unlock(&f->sem);
397                         jffs2_complete_reservation(c);
398                         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                 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
407                 if (f->metadata) {
408                         jffs2_mark_node_obsolete(c, f->metadata->raw);
409                         jffs2_free_full_dnode(f->metadata);
410                         f->metadata = NULL;
411                 }
412                 if (ret) {
413                         /* Eep */
414                         jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n",
415                                   ret);
416                         jffs2_mark_node_obsolete(c, fn->raw);
417                         jffs2_free_full_dnode(fn);
418 
419                         mutex_unlock(&f->sem);
420                         jffs2_complete_reservation(c);
421                         break;
422                 }
423                 mutex_unlock(&f->sem);
424                 jffs2_complete_reservation(c);
425                 if (!datalen) {
426                         pr_warn("Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
427                         ret = -EIO;
428                         break;
429                 }
430                 jffs2_dbg(1, "increasing writtenlen by %d\n", datalen);
431                 writtenlen += datalen;
432                 offset += datalen;
433                 writelen -= datalen;
434                 buf += datalen;
435         }
436         *retlen = writtenlen;
437         return ret;
438 }
439 
440 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         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         if (ret)
457                 return ret;
458 
459         mutex_lock(&f->sem);
460 
461         ri->data_crc = cpu_to_je32(0);
462         ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
463 
464         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         if (IS_ERR(fn)) {
470                 jffs2_dbg(1, "jffs2_write_dnode() failed\n");
471                 /* Eeek. Wave bye bye */
472                 mutex_unlock(&f->sem);
473                 jffs2_complete_reservation(c);
474                 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         f->metadata = fn;
480 
481         mutex_unlock(&f->sem);
482         jffs2_complete_reservation(c);
483 
484         ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr);
485         if (ret)
486                 return ret;
487         ret = jffs2_init_acl_post(&f->vfs_inode);
488         if (ret)
489                 return ret;
490 
491         ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen,
492                                 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len));
493 
494         if (ret) {
495                 /* Eep. */
496                 jffs2_dbg(1, "jffs2_reserve_space() for dirent failed\n");
497                 return ret;
498         }
499 
500         rd = jffs2_alloc_raw_dirent();
501         if (!rd) {
502                 /* Argh. Now we treat it like a normal delete */
503                 jffs2_complete_reservation(c);
504                 return -ENOMEM;
505         }
506 
507         mutex_lock(&dir_f->sem);
508 
509         rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
510         rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
511         rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len);
512         rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
513 
514         rd->pino = cpu_to_je32(dir_f->inocache->ino);
515         rd->version = cpu_to_je32(++dir_f->highest_version);
516         rd->ino = ri->ino;
517         rd->mctime = ri->ctime;
518         rd->nsize = qstr->len;
519         rd->type = DT_REG;
520         rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
521         rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len));
522 
523         fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL);
524 
525         jffs2_free_raw_dirent(rd);
526 
527         if (IS_ERR(fd)) {
528                 /* dirent failed to write. Delete the inode normally
529                    as if it were the final unlink() */
530                 jffs2_complete_reservation(c);
531                 mutex_unlock(&dir_f->sem);
532                 return PTR_ERR(fd);
533         }
534 
535         /* Link the fd into the inode's list, obsoleting an old
536            one if necessary. */
537         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
538 
539         jffs2_complete_reservation(c);
540         mutex_unlock(&dir_f->sem);
541 
542         return 0;
543 }
544 
545 
546 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                 rd = jffs2_alloc_raw_dirent();
559                 if (!rd)
560                         return -ENOMEM;
561 
562                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
563                                         ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
564                 if (ret) {
565                         jffs2_free_raw_dirent(rd);
566                         return ret;
567                 }
568 
569                 mutex_lock(&dir_f->sem);
570 
571                 /* Build a deletion node */
572                 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
573                 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
574                 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
575                 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
576 
577                 rd->pino = cpu_to_je32(dir_f->inocache->ino);
578                 rd->version = cpu_to_je32(++dir_f->highest_version);
579                 rd->ino = cpu_to_je32(0);
580                 rd->mctime = cpu_to_je32(time);
581                 rd->nsize = namelen;
582                 rd->type = DT_UNKNOWN;
583                 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
584                 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
585 
586                 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION);
587 
588                 jffs2_free_raw_dirent(rd);
589 
590                 if (IS_ERR(fd)) {
591                         jffs2_complete_reservation(c);
592                         mutex_unlock(&dir_f->sem);
593                         return PTR_ERR(fd);
594                 }
595 
596                 /* File it. This will mark the old one obsolete. */
597                 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
598                 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         if (dead_f && dead_f->inocache) {
632 
633                 mutex_lock(&dead_f->sem);
634 
635                 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
636                         while (dead_f->dents) {
637                                 /* There can be only deleted ones */
638                                 fd = dead_f->dents;
639 
640                                 dead_f->dents = fd->next;
641 
642                                 if (fd->ino) {
643                                         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                                 if (fd->raw)
652                                         jffs2_mark_node_obsolete(c, fd->raw);
653                                 jffs2_free_full_dirent(fd);
654                         }
655                         dead_f->inocache->pino_nlink = 0;
656                 } else
657                         dead_f->inocache->pino_nlink--;
658                 /* NB: Caller must set inode nlink if appropriate */
659                 mutex_unlock(&dead_f->sem);
660         }
661 
662         jffs2_complete_reservation(c);
663 
664         return 0;
665 }
666 
667 
668 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         rd = jffs2_alloc_raw_dirent();
676         if (!rd)
677                 return -ENOMEM;
678 
679         ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
680                                 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
681         if (ret) {
682                 jffs2_free_raw_dirent(rd);
683                 return ret;
684         }
685 
686         mutex_lock(&dir_f->sem);
687 
688         /* Build a deletion node */
689         rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
690         rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
691         rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
692         rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
693 
694         rd->pino = cpu_to_je32(dir_f->inocache->ino);
695         rd->version = cpu_to_je32(++dir_f->highest_version);
696         rd->ino = cpu_to_je32(ino);
697         rd->mctime = cpu_to_je32(time);
698         rd->nsize = namelen;
699 
700         rd->type = type;
701 
702         rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
703         rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
704 
705         fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
706 
707         jffs2_free_raw_dirent(rd);
708 
709         if (IS_ERR(fd)) {
710                 jffs2_complete_reservation(c);
711                 mutex_unlock(&dir_f->sem);
712                 return PTR_ERR(fd);
713         }
714 
715         /* File it. This will mark the old one obsolete. */
716         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
717 
718         jffs2_complete_reservation(c);
719         mutex_unlock(&dir_f->sem);
720 
721         return 0;
722 }
723 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp