source: rtems/cpukit/libfs/src/jffs2/src/write.c @ fb5bc64d

Last change on this file since fb5bc64d was fb5bc64d, checked in by Kirill A. Shutemov <kirill.shutemov@…>, on Apr 1, 2016 at 12:29:47 PM

mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros

PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.

This promise never materialized. And unlikely will.

We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.

Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.

Let's stop pretending that pages in page cache are special. They are
not.

The changes are pretty straight-forward:

  • <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
  • <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
  • PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
  • page_cache_get() -> get_page();
  • page_cache_release() -> put_page();

This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.

The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.

There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.

virtual patch

@@
expression E;
@@

  • E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)

+ E

@@
expression E;
@@

  • E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)

+ E

@@
@@

  • PAGE_CACHE_SHIFT

+ PAGE_SHIFT

@@
@@

  • PAGE_CACHE_SIZE

+ PAGE_SIZE

@@
@@

  • PAGE_CACHE_MASK

+ PAGE_MASK

@@
expression E;
@@

  • PAGE_CACHE_ALIGN(E)

+ PAGE_ALIGN(E)

@@
expression E;
@@

  • page_cache_get(E)

+ get_page(E)

@@
expression E;
@@

  • page_cache_release(E)

+ put_page(E)

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@…>
Acked-by: Michal Hocko <mhocko@…>
Signed-off-by: Linus Torvalds <torvalds@…>

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