LCOV - code coverage report
Current view: top level - libubifs - journal.c (source / functions) Hit Total Coverage
Test: a simple test Lines: 141 232 60.8 %
Date: 2024-06-05 20:10:43 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * This file is part of UBIFS.
       4             :  *
       5             :  * Copyright (C) 2006-2008 Nokia Corporation.
       6             :  *
       7             :  * Authors: Artem Bityutskiy (Битюцкий Артём)
       8             :  *          Adrian Hunter
       9             :  */
      10             : 
      11             : /*
      12             :  * This file implements UBIFS journal.
      13             :  *
      14             :  * The journal consists of 2 parts - the log and bud LEBs. The log has fixed
      15             :  * length and position, while a bud logical eraseblock is any LEB in the main
      16             :  * area. Buds contain file system data - data nodes, inode nodes, etc. The log
      17             :  * contains only references to buds and some other stuff like commit
      18             :  * start node. The idea is that when we commit the journal, we do
      19             :  * not copy the data, the buds just become indexed. Since after the commit the
      20             :  * nodes in bud eraseblocks become leaf nodes of the file system index tree, we
      21             :  * use term "bud". Analogy is obvious, bud eraseblocks contain nodes which will
      22             :  * become leafs in the future.
      23             :  *
      24             :  * The journal is multi-headed because we want to write data to the journal as
      25             :  * optimally as possible. It is nice to have nodes belonging to the same inode
      26             :  * in one LEB, so we may write data owned by different inodes to different
      27             :  * journal heads, although at present only one data head is used.
      28             :  *
      29             :  * For recovery reasons, the base head contains all inode nodes, all directory
      30             :  * entry nodes and all truncate nodes. This means that the other heads contain
      31             :  * only data nodes.
      32             :  *
      33             :  * Bud LEBs may be half-indexed. For example, if the bud was not full at the
      34             :  * time of commit, the bud is retained to continue to be used in the journal,
      35             :  * even though the "front" of the LEB is now indexed. In that case, the log
      36             :  * reference contains the offset where the bud starts for the purposes of the
      37             :  * journal.
      38             :  *
      39             :  * The journal size has to be limited, because the larger is the journal, the
      40             :  * longer it takes to mount UBIFS (scanning the journal) and the more memory it
      41             :  * takes (indexing in the TNC).
      42             :  *
      43             :  * All the journal write operations like 'ubifs_jnl_update()' here, which write
      44             :  * multiple UBIFS nodes to the journal at one go, are atomic with respect to
      45             :  * unclean reboots. Should the unclean reboot happen, the recovery code drops
      46             :  * all the nodes.
      47             :  */
      48             : 
      49             : #include "bitops.h"
      50             : #include "kmem.h"
      51             : #include "ubifs.h"
      52             : #include "defs.h"
      53             : #include "debug.h"
      54             : #include "key.h"
      55             : #include "misc.h"
      56             : 
      57             : /**
      58             :  * zero_ino_node_unused - zero out unused fields of an on-flash inode node.
      59             :  * @ino: the inode to zero out
      60             :  */
      61         469 : static inline void zero_ino_node_unused(struct ubifs_ino_node *ino)
      62             : {
      63         469 :         memset(ino->padding1, 0, 4);
      64         469 :         memset(ino->padding2, 0, 26);
      65         469 : }
      66             : 
      67             : /**
      68             :  * zero_dent_node_unused - zero out unused fields of an on-flash directory
      69             :  *                         entry node.
      70             :  * @dent: the directory entry to zero out
      71             :  */
      72             : static inline void zero_dent_node_unused(struct ubifs_dent_node *dent)
      73             : {
      74         232 :         dent->padding1 = 0;
      75             : }
      76             : 
      77             : static void ubifs_add_auth_dirt(struct ubifs_info *c, int lnum)
      78             : {
      79         237 :         if (ubifs_authenticated(c))
      80           0 :                 ubifs_add_dirt(c, lnum, ubifs_auth_node_sz(c));
      81             : }
      82             : 
      83             : /**
      84             :  * reserve_space - reserve space in the journal.
      85             :  * @c: UBIFS file-system description object
      86             :  * @jhead: journal head number
      87             :  * @len: node length
      88             :  *
      89             :  * This function reserves space in journal head @head. If the reservation
      90             :  * succeeded, the journal head stays locked and later has to be unlocked using
      91             :  * 'release_head()'. Returns zero in case of success, %-EAGAIN if commit has to
      92             :  * be done, and other negative error codes in case of other failures.
      93             :  */
      94         237 : static int reserve_space(struct ubifs_info *c, int jhead, int len)
      95             : {
      96         237 :         int err = 0, err1, retries = 0, avail, lnum, offs, squeeze;
      97         237 :         struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
      98             : 
      99             :         /*
     100             :          * Typically, the base head has smaller nodes written to it, so it is
     101             :          * better to try to allocate space at the ends of eraseblocks. This is
     102             :          * what the squeeze parameter does.
     103             :          */
     104         237 :         ubifs_assert(c, !c->ro_media && !c->ro_mount);
     105         237 :         squeeze = (jhead == BASEHD);
     106             : again:
     107         237 :         mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
     108             : 
     109         237 :         if (c->ro_error) {
     110             :                 err = -EROFS;
     111             :                 goto out_unlock;
     112             :         }
     113             : 
     114         237 :         avail = c->leb_size - wbuf->offs - wbuf->used;
     115         237 :         if (wbuf->lnum != -1 && avail >= len)
     116             :                 return 0;
     117             : 
     118             :         /*
     119             :          * Write buffer wasn't seek'ed or there is no enough space - look for an
     120             :          * LEB with some empty space.
     121             :          */
     122          12 :         lnum = ubifs_find_free_space(c, len, &offs, squeeze);
     123          12 :         if (lnum >= 0)
     124             :                 goto out;
     125             : 
     126           0 :         err = lnum;
     127           0 :         if (err != -ENOSPC)
     128             :                 goto out_unlock;
     129             : 
     130             :         /*
     131             :          * No free space, we have to run garbage collector to make
     132             :          * some. But the write-buffer mutex has to be unlocked because
     133             :          * GC also takes it.
     134             :          */
     135           0 :         dbg_jnl("no free space in jhead %s, run GC", dbg_jhead(jhead));
     136           0 :         mutex_unlock(&wbuf->io_mutex);
     137             : 
     138           0 :         lnum = ubifs_garbage_collect(c, 0);
     139           0 :         if (lnum < 0) {
     140           0 :                 err = lnum;
     141           0 :                 if (err != -ENOSPC)
     142             :                         return err;
     143             : 
     144             :                 /*
     145             :                  * GC could not make a free LEB. But someone else may
     146             :                  * have allocated new bud for this journal head,
     147             :                  * because we dropped @wbuf->io_mutex, so try once
     148             :                  * again.
     149             :                  */
     150           0 :                 dbg_jnl("GC couldn't make a free LEB for jhead %s",
     151             :                         dbg_jhead(jhead));
     152           0 :                 if (retries++ < 2) {
     153           0 :                         dbg_jnl("retry (%d)", retries);
     154             :                         goto again;
     155             :                 }
     156             : 
     157           0 :                 dbg_jnl("return -ENOSPC");
     158             :                 return err;
     159             :         }
     160             : 
     161           0 :         mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
     162           0 :         dbg_jnl("got LEB %d for jhead %s", lnum, dbg_jhead(jhead));
     163           0 :         avail = c->leb_size - wbuf->offs - wbuf->used;
     164             : 
     165           0 :         if (wbuf->lnum != -1 && avail >= len) {
     166             :                 /*
     167             :                  * Someone else has switched the journal head and we have
     168             :                  * enough space now. This happens when more than one process is
     169             :                  * trying to write to the same journal head at the same time.
     170             :                  */
     171           0 :                 dbg_jnl("return LEB %d back, already have LEB %d:%d",
     172             :                         lnum, wbuf->lnum, wbuf->offs + wbuf->used);
     173           0 :                 err = ubifs_return_leb(c, lnum);
     174           0 :                 if (err)
     175             :                         goto out_unlock;
     176             :                 return 0;
     177             :         }
     178             : 
     179           0 :         offs = 0;
     180             : 
     181          24 : out:
     182             :         /*
     183             :          * Make sure we synchronize the write-buffer before we add the new bud
     184             :          * to the log. Otherwise we may have a power cut after the log
     185             :          * reference node for the last bud (@lnum) is written but before the
     186             :          * write-buffer data are written to the next-to-last bud
     187             :          * (@wbuf->lnum). And the effect would be that the recovery would see
     188             :          * that there is corruption in the next-to-last bud.
     189             :          */
     190          12 :         err = ubifs_wbuf_sync_nolock(wbuf);
     191          12 :         if (err)
     192             :                 goto out_return;
     193          12 :         err = ubifs_add_bud_to_log(c, jhead, lnum, offs);
     194          12 :         if (err)
     195             :                 goto out_return;
     196          12 :         err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs);
     197          12 :         if (err)
     198             :                 goto out_unlock;
     199             : 
     200             :         return 0;
     201             : 
     202           0 : out_unlock:
     203           0 :         mutex_unlock(&wbuf->io_mutex);
     204           0 :         return err;
     205             : 
     206           0 : out_return:
     207             :         /* An error occurred and the LEB has to be returned to lprops */
     208           0 :         ubifs_assert(c, err < 0);
     209           0 :         err1 = ubifs_return_leb(c, lnum);
     210           0 :         if (err1 && err == -EAGAIN)
     211             :                 /*
     212             :                  * Return original error code only if it is not %-EAGAIN,
     213             :                  * which is not really an error. Otherwise, return the error
     214             :                  * code of 'ubifs_return_leb()'.
     215             :                  */
     216           0 :                 err = err1;
     217           0 :         mutex_unlock(&wbuf->io_mutex);
     218           0 :         return err;
     219             : }
     220             : 
     221           0 : static int ubifs_hash_nodes(struct ubifs_info *c, void *node,
     222             :                              int len, struct shash_desc *hash)
     223             : {
     224           0 :         int auth_node_size = ubifs_auth_node_sz(c);
     225             :         int err;
     226             : 
     227           0 :         while (1) {
     228           0 :                 const struct ubifs_ch *ch = node;
     229           0 :                 int nodelen = le32_to_cpu(ch->len);
     230             : 
     231           0 :                 ubifs_assert(c, len >= auth_node_size);
     232             : 
     233           0 :                 if (len == auth_node_size)
     234             :                         break;
     235             : 
     236           0 :                 ubifs_assert(c, len > nodelen);
     237           0 :                 ubifs_assert(c, ch->magic == cpu_to_le32(UBIFS_NODE_MAGIC));
     238             : 
     239           0 :                 err = ubifs_shash_update(c, hash, (void *)node, nodelen);
     240           0 :                 if (err)
     241             :                         return err;
     242             : 
     243           0 :                 node += ALIGN(nodelen, 8);
     244           0 :                 len -= ALIGN(nodelen, 8);
     245             :         }
     246             : 
     247             :         return ubifs_prepare_auth_node(c, node, hash);
     248             : }
     249             : 
     250             : /**
     251             :  * write_head - write data to a journal head.
     252             :  * @c: UBIFS file-system description object
     253             :  * @jhead: journal head
     254             :  * @buf: buffer to write
     255             :  * @len: length to write
     256             :  * @lnum: LEB number written is returned here
     257             :  * @offs: offset written is returned here
     258             :  * @sync: non-zero if the write-buffer has to by synchronized
     259             :  *
     260             :  * This function writes data to the reserved space of journal head @jhead.
     261             :  * Returns zero in case of success and a negative error code in case of
     262             :  * failure.
     263             :  */
     264         237 : static int write_head(struct ubifs_info *c, int jhead, void *buf, int len,
     265             :                       int *lnum, int *offs, int sync)
     266             : {
     267             :         int err;
     268         237 :         struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
     269             : 
     270         237 :         ubifs_assert(c, jhead != GCHD);
     271             : 
     272         237 :         *lnum = c->jheads[jhead].wbuf.lnum;
     273         237 :         *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
     274         237 :         dbg_jnl("jhead %s, LEB %d:%d, len %d",
     275             :                 dbg_jhead(jhead), *lnum, *offs, len);
     276             : 
     277         237 :         if (ubifs_authenticated(c)) {
     278           0 :                 err = ubifs_hash_nodes(c, buf, len, c->jheads[jhead].log_hash);
     279           0 :                 if (err)
     280             :                         return err;
     281             :         }
     282             : 
     283         237 :         err = ubifs_wbuf_write_nolock(wbuf, buf, len);
     284         237 :         if (err)
     285             :                 return err;
     286         237 :         if (sync)
     287           0 :                 err = ubifs_wbuf_sync_nolock(wbuf);
     288             :         return err;
     289             : }
     290             : 
     291             : /**
     292             :  * make_reservation - reserve journal space.
     293             :  * @c: UBIFS file-system description object
     294             :  * @jhead: journal head
     295             :  * @len: how many bytes to reserve
     296             :  *
     297             :  * This function makes space reservation in journal head @jhead. The function
     298             :  * takes the commit lock and locks the journal head, and the caller has to
     299             :  * unlock the head and finish the reservation with 'finish_reservation()'.
     300             :  * Returns zero in case of success and a negative error code in case of
     301             :  * failure.
     302             :  *
     303             :  * Note, the journal head may be unlocked as soon as the data is written, while
     304             :  * the commit lock has to be released after the data has been added to the
     305             :  * TNC.
     306             :  */
     307         237 : static int make_reservation(struct ubifs_info *c, int jhead, int len)
     308             : {
     309         237 :         int err, cmt_retries = 0, nospc_retries = 0;
     310             : 
     311         237 : again:
     312         237 :         down_read(&c->commit_sem);
     313         237 :         err = reserve_space(c, jhead, len);
     314         237 :         if (!err)
     315             :                 /* c->commit_sem will get released via finish_reservation(). */
     316             :                 return 0;
     317           0 :         up_read(&c->commit_sem);
     318             : 
     319           0 :         if (err == -ENOSPC) {
     320             :                 /*
     321             :                  * GC could not make any progress. We should try to commit
     322             :                  * once because it could make some dirty space and GC would
     323             :                  * make progress, so make the error -EAGAIN so that the below
     324             :                  * will commit and re-try.
     325             :                  */
     326           0 :                 if (nospc_retries++ < 2) {
     327           0 :                         dbg_jnl("no space, retry");
     328             :                         err = -EAGAIN;
     329             :                 }
     330             : 
     331             :                 /*
     332             :                  * This means that the budgeting is incorrect. We always have
     333             :                  * to be able to write to the media, because all operations are
     334             :                  * budgeted. Deletions are not budgeted, though, but we reserve
     335             :                  * an extra LEB for them.
     336             :                  */
     337             :         }
     338             : 
     339           0 :         if (err != -EAGAIN)
     340             :                 goto out;
     341             : 
     342             :         /*
     343             :          * -EAGAIN means that the journal is full or too large, or the above
     344             :          * code wants to do one commit. Do this and re-try.
     345             :          */
     346           0 :         if (cmt_retries > 128) {
     347             :                 /*
     348             :                  * This should not happen unless the journal size limitations
     349             :                  * are too tough.
     350             :                  */
     351           0 :                 ubifs_err(c, "stuck in space allocation");
     352             :                 err = -ENOSPC;
     353             :                 goto out;
     354           0 :         } else if (cmt_retries > 32)
     355           0 :                 ubifs_warn(c, "too many space allocation re-tries (%d)",
     356             :                            cmt_retries);
     357             : 
     358           0 :         dbg_jnl("-EAGAIN, commit and retry (retried %d times)",
     359             :                 cmt_retries);
     360           0 :         cmt_retries += 1;
     361             : 
     362           0 :         err = ubifs_run_commit(c);
     363           0 :         if (err)
     364             :                 return err;
     365             :         goto again;
     366             : 
     367           0 : out:
     368           0 :         ubifs_err(c, "cannot reserve %d bytes in jhead %d, error %d",
     369             :                   len, jhead, err);
     370           0 :         if (err == -ENOSPC) {
     371             :                 /* This are some budgeting problems, print useful information */
     372           0 :                 down_write(&c->commit_sem);
     373           0 :                 dump_stack();
     374           0 :                 ubifs_dump_budg(c, &c->bi);
     375           0 :                 ubifs_dump_lprops(c);
     376           0 :                 cmt_retries = dbg_check_lprops(c);
     377           0 :                 up_write(&c->commit_sem);
     378             :         }
     379             :         return err;
     380             : }
     381             : 
     382             : /**
     383             :  * release_head - release a journal head.
     384             :  * @c: UBIFS file-system description object
     385             :  * @jhead: journal head
     386             :  *
     387             :  * This function releases journal head @jhead which was locked by
     388             :  * the 'make_reservation()' function. It has to be called after each successful
     389             :  * 'make_reservation()' invocation.
     390             :  */
     391             : static inline void release_head(struct ubifs_info *c, int jhead)
     392             : {
     393         237 :         mutex_unlock(&c->jheads[jhead].wbuf.io_mutex);
     394             : }
     395             : 
     396             : /**
     397             :  * finish_reservation - finish a reservation.
     398             :  * @c: UBIFS file-system description object
     399             :  *
     400             :  * This function finishes journal space reservation. It must be called after
     401             :  * 'make_reservation()'.
     402             :  */
     403             : static void finish_reservation(struct ubifs_info *c)
     404             : {
     405         237 :         up_read(&c->commit_sem);
     406             : }
     407             : 
     408             : /**
     409             :  * ubifs_get_dent_type - translate VFS inode mode to UBIFS directory entry type.
     410             :  * @mode: inode mode
     411             :  */
     412   222637527 : int ubifs_get_dent_type(int mode)
     413             : {
     414   222637527 :         switch (mode & S_IFMT) {
     415             :         case S_IFREG:
     416             :                 return UBIFS_ITYPE_REG;
     417    24850344 :         case S_IFDIR:
     418    24850344 :                 return UBIFS_ITYPE_DIR;
     419    24145993 :         case S_IFLNK:
     420    24145993 :                 return UBIFS_ITYPE_LNK;
     421         150 :         case S_IFBLK:
     422         150 :                 return UBIFS_ITYPE_BLK;
     423    48228747 :         case S_IFCHR:
     424    48228747 :                 return UBIFS_ITYPE_CHR;
     425           0 :         case S_IFIFO:
     426           0 :                 return UBIFS_ITYPE_FIFO;
     427          10 :         case S_IFSOCK:
     428          10 :                 return UBIFS_ITYPE_SOCK;
     429             :         default:
     430           0 :                 BUG();
     431             :         }
     432             :         return 0;
     433             : }
     434             : 
     435             : static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent)
     436             : {
     437         232 :         if (c->double_hash)
     438          18 :                 dent->cookie = (__force __le32) get_random_u32();
     439             :         else
     440         214 :                 dent->cookie = 0;
     441             : }
     442             : 
     443             : /**
     444             :  * pack_inode - pack an ubifs inode node.
     445             :  * @c: UBIFS file-system description object
     446             :  * @ino: buffer in which to pack inode node
     447             :  * @ui: ubifs inode to pack
     448             :  * @last: indicates the last node of the group
     449             :  */
     450         469 : static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino,
     451             :                        const struct ubifs_inode *ui, int last)
     452             : {
     453         469 :         const struct inode *inode = &ui->vfs_inode;
     454         469 :         int data_len = 0, last_reference = !inode->nlink;
     455             : 
     456         469 :         ino->ch.node_type = UBIFS_INO_NODE;
     457         938 :         ino_key_init_flash(c, &ino->key, inode->inum);
     458         469 :         ino->creat_sqnum = cpu_to_le64(ui->creat_sqnum);
     459         469 :         ino->atime_sec  = cpu_to_le64(inode->atime_sec);
     460         469 :         ino->atime_nsec = cpu_to_le32(inode->atime_nsec);
     461         469 :         ino->ctime_sec  = cpu_to_le64(inode->ctime_sec);
     462         469 :         ino->ctime_nsec = cpu_to_le32(inode->ctime_nsec);
     463         469 :         ino->mtime_sec  = cpu_to_le64(inode->mtime_sec);
     464         469 :         ino->mtime_nsec = cpu_to_le32(inode->mtime_nsec);
     465         469 :         ino->uid   = cpu_to_le32(inode->uid);
     466         469 :         ino->gid   = cpu_to_le32(inode->gid);
     467         469 :         ino->mode  = cpu_to_le32(inode->mode);
     468         469 :         ino->flags = cpu_to_le32(ui->flags);
     469         469 :         ino->size  = cpu_to_le64(ui->ui_size);
     470         469 :         ino->nlink = cpu_to_le32(inode->nlink);
     471         469 :         ino->compr_type  = cpu_to_le16(ui->compr_type);
     472         469 :         ino->data_len    = cpu_to_le32(ui->data_len);
     473         469 :         ino->xattr_cnt   = cpu_to_le32(ui->xattr_cnt);
     474         469 :         ino->xattr_size  = cpu_to_le32(ui->xattr_size);
     475         469 :         ino->xattr_names = cpu_to_le32(ui->xattr_names);
     476         469 :         zero_ino_node_unused(ino);
     477             : 
     478             :         /*
     479             :          * Drop the attached data if this is a deletion inode, the data is not
     480             :          * needed anymore.
     481             :          */
     482         469 :         if (!last_reference) {
     483         469 :                 memcpy(ino->data, ui->data, ui->data_len);
     484         469 :                 data_len = ui->data_len;
     485             :         }
     486             : 
     487         469 :         ubifs_prep_grp_node(c, ino, UBIFS_INO_NODE_SZ + data_len, last);
     488         469 : }
     489             : 
     490             : /**
     491             :  * ubifs_jnl_update_file - update file.
     492             :  * @c: UBIFS file-system description object
     493             :  * @dir_ui: parent ubifs inode
     494             :  * @nm: directory entry name
     495             :  * @ui: ubifs inode to update
     496             :  *
     497             :  * This function updates an file by writing a directory entry node, the inode
     498             :  * node itself, and the parent directory inode node to the journal. If the
     499             :  * @dir_ui and @nm are NULL, only update @ui.
     500             :  *
     501             :  * Returns zero on success. In case of failure, a negative error code is
     502             :  * returned.
     503             :  */
     504         237 : int ubifs_jnl_update_file(struct ubifs_info *c,
     505             :                           const struct ubifs_inode *dir_ui,
     506             :                           const struct fscrypt_name *nm,
     507             :                           const struct ubifs_inode *ui)
     508             : {
     509         237 :         const struct inode *dir = NULL, *inode = &ui->vfs_inode;
     510             :         int err, dlen, ilen, len, lnum, ino_offs, dent_offs, dir_ilen;
     511             :         int aligned_dlen, aligned_ilen;
     512             :         struct ubifs_dent_node *dent;
     513             :         struct ubifs_ino_node *ino;
     514             :         union ubifs_key dent_key, ino_key;
     515             :         u8 hash_dent[UBIFS_HASH_ARR_SZ];
     516             :         u8 hash_ino[UBIFS_HASH_ARR_SZ];
     517             :         u8 hash_ino_dir[UBIFS_HASH_ARR_SZ];
     518             : 
     519         237 :         ubifs_assert(c, (!nm && !dir_ui) || (nm && dir_ui));
     520         237 :         ubifs_assert(c, inode->nlink != 0);
     521             : 
     522         237 :         ilen = UBIFS_INO_NODE_SZ + ui->data_len;
     523             : 
     524         237 :         if (nm)
     525         232 :                 dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
     526             :         else
     527             :                 dlen = 0;
     528             : 
     529         237 :         if (dir_ui) {
     530         232 :                 dir = &dir_ui->vfs_inode;
     531         232 :                 ubifs_assert(c, dir->nlink != 0);
     532         232 :                 dir_ilen = UBIFS_INO_NODE_SZ + dir_ui->data_len;
     533             :         } else
     534             :                 dir_ilen = 0;
     535             : 
     536         237 :         aligned_dlen = ALIGN(dlen, 8);
     537         237 :         aligned_ilen = ALIGN(ilen, 8);
     538         237 :         len = aligned_dlen + aligned_ilen + dir_ilen;
     539         237 :         if (ubifs_authenticated(c))
     540           0 :                 len += ALIGN(dir_ilen, 8) + ubifs_auth_node_sz(c);
     541             : 
     542         474 :         dent = kzalloc(len, GFP_NOFS);
     543         237 :         if (!dent)
     544             :                 return -ENOMEM;
     545             : 
     546             :         /* Make reservation before allocating sequence numbers */
     547         237 :         err = make_reservation(c, BASEHD, len);
     548         237 :         if (err)
     549             :                 goto out_free;
     550             : 
     551         237 :         if (nm) {
     552         232 :                 dent->ch.node_type = UBIFS_DENT_NODE;
     553         232 :                 dent_key_init(c, &dent_key, dir->inum, nm);
     554             : 
     555         464 :                 key_write(c, &dent_key, dent->key);
     556         232 :                 dent->inum = cpu_to_le64(inode->inum);
     557         232 :                 dent->type = ubifs_get_dent_type(inode->mode);
     558         232 :                 dent->nlen = cpu_to_le16(fname_len(nm));
     559         232 :                 memcpy(dent->name, fname_name(nm), fname_len(nm));
     560         232 :                 dent->name[fname_len(nm)] = '\0';
     561         232 :                 set_dent_cookie(c, dent);
     562             : 
     563         232 :                 zero_dent_node_unused(dent);
     564         232 :                 ubifs_prep_grp_node(c, dent, dlen, 0);
     565           0 :                 err = ubifs_node_calc_hash(c, dent, hash_dent);
     566           0 :                 if (err)
     567             :                         goto out_release;
     568             :         }
     569             : 
     570         237 :         ino = (void *)dent + aligned_dlen;
     571         237 :         pack_inode(c, ino, ui, dir_ui == NULL ? 1 : 0);
     572           0 :         err = ubifs_node_calc_hash(c, ino, hash_ino);
     573           0 :         if (err)
     574             :                 goto out_release;
     575             : 
     576         237 :         if (dir_ui) {
     577         232 :                 ino = (void *)ino + aligned_ilen;
     578         232 :                 pack_inode(c, ino, dir_ui, 1);
     579           0 :                 err = ubifs_node_calc_hash(c, ino, hash_ino_dir);
     580           0 :                 if (err)
     581             :                         goto out_release;
     582             :         }
     583             : 
     584         237 :         err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, 0);
     585         237 :         if (err)
     586             :                 goto out_release;
     587         237 :         release_head(c, BASEHD);
     588         237 :         kfree(dent);
     589         474 :         ubifs_add_auth_dirt(c, lnum);
     590             : 
     591         237 :         if (nm) {
     592         232 :                 err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen,
     593             :                                        hash_dent, nm);
     594         232 :                 if (err) {
     595           0 :                         ubifs_assert(c, !get_failure_reason_callback(c));
     596             :                         goto out_ro;
     597             :                 }
     598             :         }
     599             : 
     600         474 :         ino_key_init(c, &ino_key, inode->inum);
     601         237 :         ino_offs = dent_offs + aligned_dlen;
     602         237 :         err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen, hash_ino);
     603         237 :         if (err) {
     604           0 :                 ubifs_assert(c, !get_failure_reason_callback(c));
     605             :                 goto out_ro;
     606             :         }
     607             : 
     608         237 :         if (dir_ui) {
     609         464 :                 ino_key_init(c, &ino_key, dir->inum);
     610         232 :                 ino_offs += aligned_ilen;
     611         232 :                 err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, dir_ilen,
     612             :                                     hash_ino_dir);
     613         232 :                 if (err) {
     614           0 :                         ubifs_assert(c, !get_failure_reason_callback(c));
     615             :                         goto out_ro;
     616             :                 }
     617             :         }
     618             : 
     619         237 :         finish_reservation(c);
     620         237 :         return 0;
     621             : 
     622           0 : out_free:
     623           0 :         kfree(dent);
     624           0 :         return err;
     625             : 
     626           0 : out_release:
     627           0 :         release_head(c, BASEHD);
     628             :         kfree(dent);
     629           0 : out_ro:
     630           0 :         ubifs_ro_mode(c, err);
     631           0 :         finish_reservation(c);
     632           0 :         return err;
     633             : }

Generated by: LCOV version 1.13