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

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

Version: ~ [ linux-5.10-rc6 ] ~ [ linux-5.9.12 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.81 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.161 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.210 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.247 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.247 ] ~ [ 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.85 ] ~ [ 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-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_SIZE) ||
176             ( ((je32_to_cpu(ri->offset)&(PAGE_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(NULL, 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,
370                                 PAGE_SIZE - (offset & (PAGE_SIZE-1)));
371                 cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
372 
373                 comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);
374 
375                 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
376                 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
377                 ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
378                 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
379 
380                 ri->ino = cpu_to_je32(f->inocache->ino);
381                 ri->version = cpu_to_je32(++f->highest_version);
382                 ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
383                 ri->offset = cpu_to_je32(offset);
384                 ri->csize = cpu_to_je32(cdatalen);
385                 ri->dsize = cpu_to_je32(datalen);
386                 ri->compr = comprtype & 0xff;
387                 ri->usercompr = (comprtype >> 8 ) & 0xff;
388                 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
389                 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
390 
391                 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
392 
393                 jffs2_free_comprbuf(comprbuf, buf);
394 
395                 if (IS_ERR(fn)) {
396                         ret = PTR_ERR(fn);
397                         mutex_unlock(&f->sem);
398                         jffs2_complete_reservation(c);
399                         if (!retried) {
400                                 /* Write error to be retried */
401                                 retried = 1;
402                                 jffs2_dbg(1, "Retrying node write in jffs2_write_inode_range()\n");
403                                 goto retry;
404                         }
405                         break;
406                 }
407                 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
408                 if (f->metadata) {
409                         jffs2_mark_node_obsolete(c, f->metadata->raw);
410                         jffs2_free_full_dnode(f->metadata);
411                         f->metadata = NULL;
412                 }
413                 if (ret) {
414                         /* Eep */
415                         jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n",
416                                   ret);
417                         jffs2_mark_node_obsolete(c, fn->raw);
418                         jffs2_free_full_dnode(fn);
419 
420                         mutex_unlock(&f->sem);
421                         jffs2_complete_reservation(c);
422                         break;
423                 }
424                 mutex_unlock(&f->sem);
425                 jffs2_complete_reservation(c);
426                 if (!datalen) {
427                         pr_warn("Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
428                         ret = -EIO;
429                         break;
430                 }
431                 jffs2_dbg(1, "increasing writtenlen by %d\n", datalen);
432                 writtenlen += datalen;
433                 offset += datalen;
434                 writelen -= datalen;
435                 buf += datalen;
436         }
437         *retlen = writtenlen;
438         return ret;
439 }
440 
441 int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
442                     struct jffs2_inode_info *f, struct jffs2_raw_inode *ri,
443                     const struct qstr *qstr)
444 {
445         struct jffs2_raw_dirent *rd;
446         struct jffs2_full_dnode *fn;
447         struct jffs2_full_dirent *fd;
448         uint32_t alloclen;
449         int ret;
450 
451         /* Try to reserve enough space for both node and dirent.
452          * Just the node will do for now, though
453          */
454         ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
455                                 JFFS2_SUMMARY_INODE_SIZE);
456         jffs2_dbg(1, "%s(): reserved 0x%x bytes\n", __func__, alloclen);
457         if (ret)
458                 return ret;
459 
460         mutex_lock(&f->sem);
461 
462         ri->data_crc = cpu_to_je32(0);
463         ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
464 
465         fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
466 
467         jffs2_dbg(1, "jffs2_do_create created file with mode 0x%x\n",
468                   jemode_to_cpu(ri->mode));
469 
470         if (IS_ERR(fn)) {
471                 jffs2_dbg(1, "jffs2_write_dnode() failed\n");
472                 /* Eeek. Wave bye bye */
473                 mutex_unlock(&f->sem);
474                 jffs2_complete_reservation(c);
475                 return PTR_ERR(fn);
476         }
477         /* No data here. Only a metadata node, which will be
478            obsoleted by the first data write
479         */
480         f->metadata = fn;
481 
482         mutex_unlock(&f->sem);
483         jffs2_complete_reservation(c);
484 
485         ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode, qstr);
486         if (ret)
487                 return ret;
488         ret = jffs2_init_acl_post(&f->vfs_inode);
489         if (ret)
490                 return ret;
491 
492         ret = jffs2_reserve_space(c, sizeof(*rd)+qstr->len, &alloclen,
493                                 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(qstr->len));
494 
495         if (ret) {
496                 /* Eep. */
497                 jffs2_dbg(1, "jffs2_reserve_space() for dirent failed\n");
498                 return ret;
499         }
500 
501         rd = jffs2_alloc_raw_dirent();
502         if (!rd) {
503                 /* Argh. Now we treat it like a normal delete */
504                 jffs2_complete_reservation(c);
505                 return -ENOMEM;
506         }
507 
508         mutex_lock(&dir_f->sem);
509 
510         rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
511         rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
512         rd->totlen = cpu_to_je32(sizeof(*rd) + qstr->len);
513         rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
514 
515         rd->pino = cpu_to_je32(dir_f->inocache->ino);
516         rd->version = cpu_to_je32(++dir_f->highest_version);
517         rd->ino = ri->ino;
518         rd->mctime = ri->ctime;
519         rd->nsize = qstr->len;
520         rd->type = DT_REG;
521         rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
522         rd->name_crc = cpu_to_je32(crc32(0, qstr->name, qstr->len));
523 
524         fd = jffs2_write_dirent(c, dir_f, rd, qstr->name, qstr->len, ALLOC_NORMAL);
525 
526         jffs2_free_raw_dirent(rd);
527 
528         if (IS_ERR(fd)) {
529                 /* dirent failed to write. Delete the inode normally
530                    as if it were the final unlink() */
531                 jffs2_complete_reservation(c);
532                 mutex_unlock(&dir_f->sem);
533                 return PTR_ERR(fd);
534         }
535 
536         /* Link the fd into the inode's list, obsoleting an old
537            one if necessary. */
538         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
539 
540         jffs2_complete_reservation(c);
541         mutex_unlock(&dir_f->sem);
542 
543         return 0;
544 }
545 
546 
547 int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
548                     const char *name, int namelen, struct jffs2_inode_info *dead_f,
549                     uint32_t time)
550 {
551         struct jffs2_raw_dirent *rd;
552         struct jffs2_full_dirent *fd;
553         uint32_t alloclen;
554         int ret;
555 
556         if (!jffs2_can_mark_obsolete(c)) {
557                 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
558 
559                 rd = jffs2_alloc_raw_dirent();
560                 if (!rd)
561                         return -ENOMEM;
562 
563                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
564                                         ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
565                 if (ret) {
566                         jffs2_free_raw_dirent(rd);
567                         return ret;
568                 }
569 
570                 mutex_lock(&dir_f->sem);
571 
572                 /* Build a deletion node */
573                 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
574                 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
575                 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
576                 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
577 
578                 rd->pino = cpu_to_je32(dir_f->inocache->ino);
579                 rd->version = cpu_to_je32(++dir_f->highest_version);
580                 rd->ino = cpu_to_je32(0);
581                 rd->mctime = cpu_to_je32(time);
582                 rd->nsize = namelen;
583                 rd->type = DT_UNKNOWN;
584                 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
585                 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
586 
587                 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION);
588 
589                 jffs2_free_raw_dirent(rd);
590 
591                 if (IS_ERR(fd)) {
592                         jffs2_complete_reservation(c);
593                         mutex_unlock(&dir_f->sem);
594                         return PTR_ERR(fd);
595                 }
596 
597                 /* File it. This will mark the old one obsolete. */
598                 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
599                 mutex_unlock(&dir_f->sem);
600         } else {
601                 uint32_t nhash = full_name_hash(NULL, name, namelen);
602 
603                 fd = dir_f->dents;
604                 /* We don't actually want to reserve any space, but we do
605                    want to be holding the alloc_sem when we write to flash */
606                 mutex_lock(&c->alloc_sem);
607                 mutex_lock(&dir_f->sem);
608 
609                 for (fd = dir_f->dents; fd; fd = fd->next) {
610                         if (fd->nhash == nhash &&
611                             !memcmp(fd->name, name, namelen) &&
612                             !fd->name[namelen]) {
613 
614                                 jffs2_dbg(1, "Marking old dirent node (ino #%u) @%08x obsolete\n",
615                                           fd->ino, ref_offset(fd->raw));
616                                 jffs2_mark_node_obsolete(c, fd->raw);
617                                 /* We don't want to remove it from the list immediately,
618                                    because that screws up getdents()/seek() semantics even
619                                    more than they're screwed already. Turn it into a
620                                    node-less deletion dirent instead -- a placeholder */
621                                 fd->raw = NULL;
622                                 fd->ino = 0;
623                                 break;
624                         }
625                 }
626                 mutex_unlock(&dir_f->sem);
627         }
628 
629         /* dead_f is NULL if this was a rename not a real unlink */
630         /* Also catch the !f->inocache case, where there was a dirent
631            pointing to an inode which didn't exist. */
632         if (dead_f && dead_f->inocache) {
633 
634                 mutex_lock(&dead_f->sem);
635 
636                 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
637                         while (dead_f->dents) {
638                                 /* There can be only deleted ones */
639                                 fd = dead_f->dents;
640 
641                                 dead_f->dents = fd->next;
642 
643                                 if (fd->ino) {
644                                         pr_warn("Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
645                                                 dead_f->inocache->ino,
646                                                 fd->name, fd->ino);
647                                 } else {
648                                         jffs2_dbg(1, "Removing deletion dirent for \"%s\" from dir ino #%u\n",
649                                                   fd->name,
650                                                   dead_f->inocache->ino);
651                                 }
652                                 if (fd->raw)
653                                         jffs2_mark_node_obsolete(c, fd->raw);
654                                 jffs2_free_full_dirent(fd);
655                         }
656                         dead_f->inocache->pino_nlink = 0;
657                 } else
658                         dead_f->inocache->pino_nlink--;
659                 /* NB: Caller must set inode nlink if appropriate */
660                 mutex_unlock(&dead_f->sem);
661         }
662 
663         jffs2_complete_reservation(c);
664 
665         return 0;
666 }
667 
668 
669 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 {
671         struct jffs2_raw_dirent *rd;
672         struct jffs2_full_dirent *fd;
673         uint32_t alloclen;
674         int ret;
675 
676         rd = jffs2_alloc_raw_dirent();
677         if (!rd)
678                 return -ENOMEM;
679 
680         ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
681                                 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
682         if (ret) {
683                 jffs2_free_raw_dirent(rd);
684                 return ret;
685         }
686 
687         mutex_lock(&dir_f->sem);
688 
689         /* Build a deletion node */
690         rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
691         rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
692         rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
693         rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
694 
695         rd->pino = cpu_to_je32(dir_f->inocache->ino);
696         rd->version = cpu_to_je32(++dir_f->highest_version);
697         rd->ino = cpu_to_je32(ino);
698         rd->mctime = cpu_to_je32(time);
699         rd->nsize = namelen;
700 
701         rd->type = type;
702 
703         rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
704         rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
705 
706         fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
707 
708         jffs2_free_raw_dirent(rd);
709 
710         if (IS_ERR(fd)) {
711                 jffs2_complete_reservation(c);
712                 mutex_unlock(&dir_f->sem);
713                 return PTR_ERR(fd);
714         }
715 
716         /* File it. This will mark the old one obsolete. */
717         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
718 
719         jffs2_complete_reservation(c);
720         mutex_unlock(&dir_f->sem);
721 
722         return 0;
723 }
724 

~ [ 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