12b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21e51764aSArtem Bityutskiy /* 31e51764aSArtem Bityutskiy * This file is part of UBIFS. 41e51764aSArtem Bityutskiy * 51e51764aSArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation. 61e51764aSArtem Bityutskiy * 71e51764aSArtem Bityutskiy * Authors: Artem Bityutskiy (Битюцкий Артём) 81e51764aSArtem Bityutskiy * Adrian Hunter 91e51764aSArtem Bityutskiy */ 101e51764aSArtem Bityutskiy 111e51764aSArtem Bityutskiy /* 121e51764aSArtem Bityutskiy * This file implements UBIFS journal. 131e51764aSArtem Bityutskiy * 141e51764aSArtem Bityutskiy * The journal consists of 2 parts - the log and bud LEBs. The log has fixed 151e51764aSArtem Bityutskiy * length and position, while a bud logical eraseblock is any LEB in the main 161e51764aSArtem Bityutskiy * area. Buds contain file system data - data nodes, inode nodes, etc. The log 171e51764aSArtem Bityutskiy * contains only references to buds and some other stuff like commit 181e51764aSArtem Bityutskiy * start node. The idea is that when we commit the journal, we do 191e51764aSArtem Bityutskiy * not copy the data, the buds just become indexed. Since after the commit the 201e51764aSArtem Bityutskiy * nodes in bud eraseblocks become leaf nodes of the file system index tree, we 211e51764aSArtem Bityutskiy * use term "bud". Analogy is obvious, bud eraseblocks contain nodes which will 221e51764aSArtem Bityutskiy * become leafs in the future. 231e51764aSArtem Bityutskiy * 241e51764aSArtem Bityutskiy * The journal is multi-headed because we want to write data to the journal as 251e51764aSArtem Bityutskiy * optimally as possible. It is nice to have nodes belonging to the same inode 261e51764aSArtem Bityutskiy * in one LEB, so we may write data owned by different inodes to different 271e51764aSArtem Bityutskiy * journal heads, although at present only one data head is used. 281e51764aSArtem Bityutskiy * 291e51764aSArtem Bityutskiy * For recovery reasons, the base head contains all inode nodes, all directory 301e51764aSArtem Bityutskiy * entry nodes and all truncate nodes. This means that the other heads contain 311e51764aSArtem Bityutskiy * only data nodes. 321e51764aSArtem Bityutskiy * 331e51764aSArtem Bityutskiy * Bud LEBs may be half-indexed. For example, if the bud was not full at the 341e51764aSArtem Bityutskiy * time of commit, the bud is retained to continue to be used in the journal, 351e51764aSArtem Bityutskiy * even though the "front" of the LEB is now indexed. In that case, the log 361e51764aSArtem Bityutskiy * reference contains the offset where the bud starts for the purposes of the 371e51764aSArtem Bityutskiy * journal. 381e51764aSArtem Bityutskiy * 391e51764aSArtem Bityutskiy * The journal size has to be limited, because the larger is the journal, the 401e51764aSArtem Bityutskiy * longer it takes to mount UBIFS (scanning the journal) and the more memory it 411e51764aSArtem Bityutskiy * takes (indexing in the TNC). 421e51764aSArtem Bityutskiy * 431e51764aSArtem Bityutskiy * All the journal write operations like 'ubifs_jnl_update()' here, which write 441e51764aSArtem Bityutskiy * multiple UBIFS nodes to the journal at one go, are atomic with respect to 451e51764aSArtem Bityutskiy * unclean reboots. Should the unclean reboot happen, the recovery code drops 461e51764aSArtem Bityutskiy * all the nodes. 471e51764aSArtem Bityutskiy */ 481e51764aSArtem Bityutskiy 491e51764aSArtem Bityutskiy #include "ubifs.h" 501e51764aSArtem Bityutskiy 511e51764aSArtem Bityutskiy /** 521e51764aSArtem Bityutskiy * zero_ino_node_unused - zero out unused fields of an on-flash inode node. 531e51764aSArtem Bityutskiy * @ino: the inode to zero out 541e51764aSArtem Bityutskiy */ 551e51764aSArtem Bityutskiy static inline void zero_ino_node_unused(struct ubifs_ino_node *ino) 561e51764aSArtem Bityutskiy { 571e51764aSArtem Bityutskiy memset(ino->padding1, 0, 4); 581e51764aSArtem Bityutskiy memset(ino->padding2, 0, 26); 591e51764aSArtem Bityutskiy } 601e51764aSArtem Bityutskiy 611e51764aSArtem Bityutskiy /** 621e51764aSArtem Bityutskiy * zero_dent_node_unused - zero out unused fields of an on-flash directory 631e51764aSArtem Bityutskiy * entry node. 641e51764aSArtem Bityutskiy * @dent: the directory entry to zero out 651e51764aSArtem Bityutskiy */ 661e51764aSArtem Bityutskiy static inline void zero_dent_node_unused(struct ubifs_dent_node *dent) 671e51764aSArtem Bityutskiy { 681e51764aSArtem Bityutskiy dent->padding1 = 0; 691e51764aSArtem Bityutskiy } 701e51764aSArtem Bityutskiy 711e51764aSArtem Bityutskiy /** 721e51764aSArtem Bityutskiy * zero_trun_node_unused - zero out unused fields of an on-flash truncation 731e51764aSArtem Bityutskiy * node. 741e51764aSArtem Bityutskiy * @trun: the truncation node to zero out 751e51764aSArtem Bityutskiy */ 761e51764aSArtem Bityutskiy static inline void zero_trun_node_unused(struct ubifs_trun_node *trun) 771e51764aSArtem Bityutskiy { 781e51764aSArtem Bityutskiy memset(trun->padding, 0, 12); 791e51764aSArtem Bityutskiy } 801e51764aSArtem Bityutskiy 816a98bc46SSascha Hauer static void ubifs_add_auth_dirt(struct ubifs_info *c, int lnum) 826a98bc46SSascha Hauer { 836a98bc46SSascha Hauer if (ubifs_authenticated(c)) 846a98bc46SSascha Hauer ubifs_add_dirt(c, lnum, ubifs_auth_node_sz(c)); 856a98bc46SSascha Hauer } 866a98bc46SSascha Hauer 871e51764aSArtem Bityutskiy /** 881e51764aSArtem Bityutskiy * reserve_space - reserve space in the journal. 891e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 901e51764aSArtem Bityutskiy * @jhead: journal head number 911e51764aSArtem Bityutskiy * @len: node length 921e51764aSArtem Bityutskiy * 931e51764aSArtem Bityutskiy * This function reserves space in journal head @head. If the reservation 941e51764aSArtem Bityutskiy * succeeded, the journal head stays locked and later has to be unlocked using 95671b9b75SSascha Hauer * 'release_head()'. Returns zero in case of success, %-EAGAIN if commit has to 96671b9b75SSascha Hauer * be done, and other negative error codes in case of other failures. 971e51764aSArtem Bityutskiy */ 981e51764aSArtem Bityutskiy static int reserve_space(struct ubifs_info *c, int jhead, int len) 991e51764aSArtem Bityutskiy { 1003edaae7cSArtem Bityutskiy int err = 0, err1, retries = 0, avail, lnum, offs, squeeze; 1011e51764aSArtem Bityutskiy struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; 1021e51764aSArtem Bityutskiy 1031e51764aSArtem Bityutskiy /* 1041e51764aSArtem Bityutskiy * Typically, the base head has smaller nodes written to it, so it is 1051e51764aSArtem Bityutskiy * better to try to allocate space at the ends of eraseblocks. This is 1061e51764aSArtem Bityutskiy * what the squeeze parameter does. 1071e51764aSArtem Bityutskiy */ 1086eb61d58SRichard Weinberger ubifs_assert(c, !c->ro_media && !c->ro_mount); 1091e51764aSArtem Bityutskiy squeeze = (jhead == BASEHD); 1101e51764aSArtem Bityutskiy again: 1111e51764aSArtem Bityutskiy mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); 1121e51764aSArtem Bityutskiy 1132680d722SArtem Bityutskiy if (c->ro_error) { 1141e51764aSArtem Bityutskiy err = -EROFS; 1151e51764aSArtem Bityutskiy goto out_unlock; 1161e51764aSArtem Bityutskiy } 1171e51764aSArtem Bityutskiy 1181e51764aSArtem Bityutskiy avail = c->leb_size - wbuf->offs - wbuf->used; 1191e51764aSArtem Bityutskiy if (wbuf->lnum != -1 && avail >= len) 1201e51764aSArtem Bityutskiy return 0; 1211e51764aSArtem Bityutskiy 1221e51764aSArtem Bityutskiy /* 1231e51764aSArtem Bityutskiy * Write buffer wasn't seek'ed or there is no enough space - look for an 1241e51764aSArtem Bityutskiy * LEB with some empty space. 1251e51764aSArtem Bityutskiy */ 1263edaae7cSArtem Bityutskiy lnum = ubifs_find_free_space(c, len, &offs, squeeze); 127cb14a184SArtem Bityutskiy if (lnum >= 0) 1281e51764aSArtem Bityutskiy goto out; 1291e51764aSArtem Bityutskiy 1301e51764aSArtem Bityutskiy err = lnum; 1311e51764aSArtem Bityutskiy if (err != -ENOSPC) 1321e51764aSArtem Bityutskiy goto out_unlock; 1331e51764aSArtem Bityutskiy 1341e51764aSArtem Bityutskiy /* 1351e51764aSArtem Bityutskiy * No free space, we have to run garbage collector to make 1361e51764aSArtem Bityutskiy * some. But the write-buffer mutex has to be unlocked because 1371e51764aSArtem Bityutskiy * GC also takes it. 1381e51764aSArtem Bityutskiy */ 13977a7ae58SArtem Bityutskiy dbg_jnl("no free space in jhead %s, run GC", dbg_jhead(jhead)); 1401e51764aSArtem Bityutskiy mutex_unlock(&wbuf->io_mutex); 1411e51764aSArtem Bityutskiy 1421e51764aSArtem Bityutskiy lnum = ubifs_garbage_collect(c, 0); 1431e51764aSArtem Bityutskiy if (lnum < 0) { 1441e51764aSArtem Bityutskiy err = lnum; 1451e51764aSArtem Bityutskiy if (err != -ENOSPC) 1461e51764aSArtem Bityutskiy return err; 1471e51764aSArtem Bityutskiy 1481e51764aSArtem Bityutskiy /* 1491e51764aSArtem Bityutskiy * GC could not make a free LEB. But someone else may 1501e51764aSArtem Bityutskiy * have allocated new bud for this journal head, 1511e51764aSArtem Bityutskiy * because we dropped @wbuf->io_mutex, so try once 1521e51764aSArtem Bityutskiy * again. 1531e51764aSArtem Bityutskiy */ 15477a7ae58SArtem Bityutskiy dbg_jnl("GC couldn't make a free LEB for jhead %s", 15577a7ae58SArtem Bityutskiy dbg_jhead(jhead)); 1561e51764aSArtem Bityutskiy if (retries++ < 2) { 1571e51764aSArtem Bityutskiy dbg_jnl("retry (%d)", retries); 1581e51764aSArtem Bityutskiy goto again; 1591e51764aSArtem Bityutskiy } 1601e51764aSArtem Bityutskiy 1611e51764aSArtem Bityutskiy dbg_jnl("return -ENOSPC"); 1621e51764aSArtem Bityutskiy return err; 1631e51764aSArtem Bityutskiy } 1641e51764aSArtem Bityutskiy 1651e51764aSArtem Bityutskiy mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); 16677a7ae58SArtem Bityutskiy dbg_jnl("got LEB %d for jhead %s", lnum, dbg_jhead(jhead)); 1671e51764aSArtem Bityutskiy avail = c->leb_size - wbuf->offs - wbuf->used; 1681e51764aSArtem Bityutskiy 1691e51764aSArtem Bityutskiy if (wbuf->lnum != -1 && avail >= len) { 1701e51764aSArtem Bityutskiy /* 1711e51764aSArtem Bityutskiy * Someone else has switched the journal head and we have 172025dfdafSFrederik Schwarzer * enough space now. This happens when more than one process is 1731e51764aSArtem Bityutskiy * trying to write to the same journal head at the same time. 1741e51764aSArtem Bityutskiy */ 1751e51764aSArtem Bityutskiy dbg_jnl("return LEB %d back, already have LEB %d:%d", 1761e51764aSArtem Bityutskiy lnum, wbuf->lnum, wbuf->offs + wbuf->used); 1771e51764aSArtem Bityutskiy err = ubifs_return_leb(c, lnum); 1781e51764aSArtem Bityutskiy if (err) 1791e51764aSArtem Bityutskiy goto out_unlock; 1801e51764aSArtem Bityutskiy return 0; 1811e51764aSArtem Bityutskiy } 1821e51764aSArtem Bityutskiy 1831e51764aSArtem Bityutskiy offs = 0; 1841e51764aSArtem Bityutskiy 1851e51764aSArtem Bityutskiy out: 186cb14a184SArtem Bityutskiy /* 187cb14a184SArtem Bityutskiy * Make sure we synchronize the write-buffer before we add the new bud 188cb14a184SArtem Bityutskiy * to the log. Otherwise we may have a power cut after the log 189cb14a184SArtem Bityutskiy * reference node for the last bud (@lnum) is written but before the 190cb14a184SArtem Bityutskiy * write-buffer data are written to the next-to-last bud 191cb14a184SArtem Bityutskiy * (@wbuf->lnum). And the effect would be that the recovery would see 192cb14a184SArtem Bityutskiy * that there is corruption in the next-to-last bud. 193cb14a184SArtem Bityutskiy */ 194cb14a184SArtem Bityutskiy err = ubifs_wbuf_sync_nolock(wbuf); 195cb14a184SArtem Bityutskiy if (err) 196cb14a184SArtem Bityutskiy goto out_return; 197cb14a184SArtem Bityutskiy err = ubifs_add_bud_to_log(c, jhead, lnum, offs); 198cb14a184SArtem Bityutskiy if (err) 199cb14a184SArtem Bityutskiy goto out_return; 200b36a261eSRichard Weinberger err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs); 2011e51764aSArtem Bityutskiy if (err) 2021e51764aSArtem Bityutskiy goto out_unlock; 2031e51764aSArtem Bityutskiy 2041e51764aSArtem Bityutskiy return 0; 2051e51764aSArtem Bityutskiy 2061e51764aSArtem Bityutskiy out_unlock: 2071e51764aSArtem Bityutskiy mutex_unlock(&wbuf->io_mutex); 2081e51764aSArtem Bityutskiy return err; 2091e51764aSArtem Bityutskiy 2101e51764aSArtem Bityutskiy out_return: 2111e51764aSArtem Bityutskiy /* An error occurred and the LEB has to be returned to lprops */ 2126eb61d58SRichard Weinberger ubifs_assert(c, err < 0); 2131e51764aSArtem Bityutskiy err1 = ubifs_return_leb(c, lnum); 2141e51764aSArtem Bityutskiy if (err1 && err == -EAGAIN) 2151e51764aSArtem Bityutskiy /* 2161e51764aSArtem Bityutskiy * Return original error code only if it is not %-EAGAIN, 2171e51764aSArtem Bityutskiy * which is not really an error. Otherwise, return the error 2181e51764aSArtem Bityutskiy * code of 'ubifs_return_leb()'. 2191e51764aSArtem Bityutskiy */ 2201e51764aSArtem Bityutskiy err = err1; 2211e51764aSArtem Bityutskiy mutex_unlock(&wbuf->io_mutex); 2221e51764aSArtem Bityutskiy return err; 2231e51764aSArtem Bityutskiy } 2241e51764aSArtem Bityutskiy 2256a98bc46SSascha Hauer static int ubifs_hash_nodes(struct ubifs_info *c, void *node, 2266a98bc46SSascha Hauer int len, struct shash_desc *hash) 2276a98bc46SSascha Hauer { 2286a98bc46SSascha Hauer int auth_node_size = ubifs_auth_node_sz(c); 2296a98bc46SSascha Hauer int err; 2306a98bc46SSascha Hauer 2316a98bc46SSascha Hauer while (1) { 2326a98bc46SSascha Hauer const struct ubifs_ch *ch = node; 2336a98bc46SSascha Hauer int nodelen = le32_to_cpu(ch->len); 2346a98bc46SSascha Hauer 2356a98bc46SSascha Hauer ubifs_assert(c, len >= auth_node_size); 2366a98bc46SSascha Hauer 2376a98bc46SSascha Hauer if (len == auth_node_size) 2386a98bc46SSascha Hauer break; 2396a98bc46SSascha Hauer 2406a98bc46SSascha Hauer ubifs_assert(c, len > nodelen); 2416a98bc46SSascha Hauer ubifs_assert(c, ch->magic == cpu_to_le32(UBIFS_NODE_MAGIC)); 2426a98bc46SSascha Hauer 2436a98bc46SSascha Hauer err = ubifs_shash_update(c, hash, (void *)node, nodelen); 2446a98bc46SSascha Hauer if (err) 2456a98bc46SSascha Hauer return err; 2466a98bc46SSascha Hauer 2476a98bc46SSascha Hauer node += ALIGN(nodelen, 8); 2486a98bc46SSascha Hauer len -= ALIGN(nodelen, 8); 2496a98bc46SSascha Hauer } 2506a98bc46SSascha Hauer 2516a98bc46SSascha Hauer return ubifs_prepare_auth_node(c, node, hash); 2526a98bc46SSascha Hauer } 2536a98bc46SSascha Hauer 2541e51764aSArtem Bityutskiy /** 2551e51764aSArtem Bityutskiy * write_head - write data to a journal head. 2561e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2571e51764aSArtem Bityutskiy * @jhead: journal head 2581e51764aSArtem Bityutskiy * @buf: buffer to write 2591e51764aSArtem Bityutskiy * @len: length to write 2601e51764aSArtem Bityutskiy * @lnum: LEB number written is returned here 2611e51764aSArtem Bityutskiy * @offs: offset written is returned here 2621e51764aSArtem Bityutskiy * @sync: non-zero if the write-buffer has to by synchronized 2631e51764aSArtem Bityutskiy * 26483407437SSascha Hauer * This function writes data to the reserved space of journal head @jhead. 26583407437SSascha Hauer * Returns zero in case of success and a negative error code in case of 26683407437SSascha Hauer * failure. 2671e51764aSArtem Bityutskiy */ 2681e51764aSArtem Bityutskiy static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, 2691e51764aSArtem Bityutskiy int *lnum, int *offs, int sync) 2701e51764aSArtem Bityutskiy { 2711e51764aSArtem Bityutskiy int err; 2721e51764aSArtem Bityutskiy struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; 2731e51764aSArtem Bityutskiy 2746eb61d58SRichard Weinberger ubifs_assert(c, jhead != GCHD); 2751e51764aSArtem Bityutskiy 2761e51764aSArtem Bityutskiy *lnum = c->jheads[jhead].wbuf.lnum; 2771e51764aSArtem Bityutskiy *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; 27877a7ae58SArtem Bityutskiy dbg_jnl("jhead %s, LEB %d:%d, len %d", 27977a7ae58SArtem Bityutskiy dbg_jhead(jhead), *lnum, *offs, len); 2801e51764aSArtem Bityutskiy 2816a98bc46SSascha Hauer if (ubifs_authenticated(c)) { 2826a98bc46SSascha Hauer err = ubifs_hash_nodes(c, buf, len, c->jheads[jhead].log_hash); 2836a98bc46SSascha Hauer if (err) 2846a98bc46SSascha Hauer return err; 2856a98bc46SSascha Hauer } 2866a98bc46SSascha Hauer 2871e51764aSArtem Bityutskiy err = ubifs_wbuf_write_nolock(wbuf, buf, len); 2881e51764aSArtem Bityutskiy if (err) 2891e51764aSArtem Bityutskiy return err; 2901e51764aSArtem Bityutskiy if (sync) 2911e51764aSArtem Bityutskiy err = ubifs_wbuf_sync_nolock(wbuf); 2921e51764aSArtem Bityutskiy return err; 2931e51764aSArtem Bityutskiy } 2941e51764aSArtem Bityutskiy 2951e51764aSArtem Bityutskiy /** 2961e51764aSArtem Bityutskiy * make_reservation - reserve journal space. 2971e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2981e51764aSArtem Bityutskiy * @jhead: journal head 2991e51764aSArtem Bityutskiy * @len: how many bytes to reserve 3001e51764aSArtem Bityutskiy * 3011e51764aSArtem Bityutskiy * This function makes space reservation in journal head @jhead. The function 3021e51764aSArtem Bityutskiy * takes the commit lock and locks the journal head, and the caller has to 3031e51764aSArtem Bityutskiy * unlock the head and finish the reservation with 'finish_reservation()'. 3041e51764aSArtem Bityutskiy * Returns zero in case of success and a negative error code in case of 3051e51764aSArtem Bityutskiy * failure. 3061e51764aSArtem Bityutskiy * 3071e51764aSArtem Bityutskiy * Note, the journal head may be unlocked as soon as the data is written, while 3081e51764aSArtem Bityutskiy * the commit lock has to be released after the data has been added to the 3091e51764aSArtem Bityutskiy * TNC. 3101e51764aSArtem Bityutskiy */ 3111e51764aSArtem Bityutskiy static int make_reservation(struct ubifs_info *c, int jhead, int len) 3121e51764aSArtem Bityutskiy { 3131e51764aSArtem Bityutskiy int err, cmt_retries = 0, nospc_retries = 0; 3141e51764aSArtem Bityutskiy 3151e51764aSArtem Bityutskiy again: 3161e51764aSArtem Bityutskiy down_read(&c->commit_sem); 3171e51764aSArtem Bityutskiy err = reserve_space(c, jhead, len); 3181e51764aSArtem Bityutskiy if (!err) 31949d2e05fSRichard Weinberger /* c->commit_sem will get released via finish_reservation(). */ 3201e51764aSArtem Bityutskiy return 0; 3211e51764aSArtem Bityutskiy up_read(&c->commit_sem); 3221e51764aSArtem Bityutskiy 3231e51764aSArtem Bityutskiy if (err == -ENOSPC) { 3241e51764aSArtem Bityutskiy /* 3251e51764aSArtem Bityutskiy * GC could not make any progress. We should try to commit 3261e51764aSArtem Bityutskiy * once because it could make some dirty space and GC would 3271e51764aSArtem Bityutskiy * make progress, so make the error -EAGAIN so that the below 3281e51764aSArtem Bityutskiy * will commit and re-try. 3291e51764aSArtem Bityutskiy */ 3301e51764aSArtem Bityutskiy if (nospc_retries++ < 2) { 3311e51764aSArtem Bityutskiy dbg_jnl("no space, retry"); 3321e51764aSArtem Bityutskiy err = -EAGAIN; 3331e51764aSArtem Bityutskiy } 3341e51764aSArtem Bityutskiy 3351e51764aSArtem Bityutskiy /* 3361e51764aSArtem Bityutskiy * This means that the budgeting is incorrect. We always have 3371e51764aSArtem Bityutskiy * to be able to write to the media, because all operations are 3381e51764aSArtem Bityutskiy * budgeted. Deletions are not budgeted, though, but we reserve 3391e51764aSArtem Bityutskiy * an extra LEB for them. 3401e51764aSArtem Bityutskiy */ 3411e51764aSArtem Bityutskiy } 3421e51764aSArtem Bityutskiy 3431e51764aSArtem Bityutskiy if (err != -EAGAIN) 3441e51764aSArtem Bityutskiy goto out; 3451e51764aSArtem Bityutskiy 3461e51764aSArtem Bityutskiy /* 3471e51764aSArtem Bityutskiy * -EAGAIN means that the journal is full or too large, or the above 3481e51764aSArtem Bityutskiy * code wants to do one commit. Do this and re-try. 3491e51764aSArtem Bityutskiy */ 3501e51764aSArtem Bityutskiy if (cmt_retries > 128) { 3511e51764aSArtem Bityutskiy /* 3521e51764aSArtem Bityutskiy * This should not happen unless the journal size limitations 3531e51764aSArtem Bityutskiy * are too tough. 3541e51764aSArtem Bityutskiy */ 355235c362bSSheng Yong ubifs_err(c, "stuck in space allocation"); 3561e51764aSArtem Bityutskiy err = -ENOSPC; 3571e51764aSArtem Bityutskiy goto out; 3581e51764aSArtem Bityutskiy } else if (cmt_retries > 32) 359235c362bSSheng Yong ubifs_warn(c, "too many space allocation re-tries (%d)", 3601e51764aSArtem Bityutskiy cmt_retries); 3611e51764aSArtem Bityutskiy 3621e51764aSArtem Bityutskiy dbg_jnl("-EAGAIN, commit and retry (retried %d times)", 3631e51764aSArtem Bityutskiy cmt_retries); 3641e51764aSArtem Bityutskiy cmt_retries += 1; 3651e51764aSArtem Bityutskiy 3661e51764aSArtem Bityutskiy err = ubifs_run_commit(c); 3671e51764aSArtem Bityutskiy if (err) 3681e51764aSArtem Bityutskiy return err; 3691e51764aSArtem Bityutskiy goto again; 3701e51764aSArtem Bityutskiy 3711e51764aSArtem Bityutskiy out: 372235c362bSSheng Yong ubifs_err(c, "cannot reserve %d bytes in jhead %d, error %d", 3731e51764aSArtem Bityutskiy len, jhead, err); 3741e51764aSArtem Bityutskiy if (err == -ENOSPC) { 3751e51764aSArtem Bityutskiy /* This are some budgeting problems, print useful information */ 3761e51764aSArtem Bityutskiy down_write(&c->commit_sem); 3777c46d0aeSArtem Bityutskiy dump_stack(); 378edf6be24SArtem Bityutskiy ubifs_dump_budg(c, &c->bi); 379edf6be24SArtem Bityutskiy ubifs_dump_lprops(c); 3801e51764aSArtem Bityutskiy cmt_retries = dbg_check_lprops(c); 3811e51764aSArtem Bityutskiy up_write(&c->commit_sem); 3821e51764aSArtem Bityutskiy } 3831e51764aSArtem Bityutskiy return err; 3841e51764aSArtem Bityutskiy } 3851e51764aSArtem Bityutskiy 3861e51764aSArtem Bityutskiy /** 3871e51764aSArtem Bityutskiy * release_head - release a journal head. 3881e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3891e51764aSArtem Bityutskiy * @jhead: journal head 3901e51764aSArtem Bityutskiy * 3911e51764aSArtem Bityutskiy * This function releases journal head @jhead which was locked by 3921e51764aSArtem Bityutskiy * the 'make_reservation()' function. It has to be called after each successful 3931e51764aSArtem Bityutskiy * 'make_reservation()' invocation. 3941e51764aSArtem Bityutskiy */ 3951e51764aSArtem Bityutskiy static inline void release_head(struct ubifs_info *c, int jhead) 3961e51764aSArtem Bityutskiy { 3971e51764aSArtem Bityutskiy mutex_unlock(&c->jheads[jhead].wbuf.io_mutex); 3981e51764aSArtem Bityutskiy } 3991e51764aSArtem Bityutskiy 4001e51764aSArtem Bityutskiy /** 4011e51764aSArtem Bityutskiy * finish_reservation - finish a reservation. 4021e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4031e51764aSArtem Bityutskiy * 4041e51764aSArtem Bityutskiy * This function finishes journal space reservation. It must be called after 4051e51764aSArtem Bityutskiy * 'make_reservation()'. 4061e51764aSArtem Bityutskiy */ 4071e51764aSArtem Bityutskiy static void finish_reservation(struct ubifs_info *c) 4081e51764aSArtem Bityutskiy { 4091e51764aSArtem Bityutskiy up_read(&c->commit_sem); 4101e51764aSArtem Bityutskiy } 4111e51764aSArtem Bityutskiy 4121e51764aSArtem Bityutskiy /** 4131e51764aSArtem Bityutskiy * get_dent_type - translate VFS inode mode to UBIFS directory entry type. 4141e51764aSArtem Bityutskiy * @mode: inode mode 4151e51764aSArtem Bityutskiy */ 4161e51764aSArtem Bityutskiy static int get_dent_type(int mode) 4171e51764aSArtem Bityutskiy { 4181e51764aSArtem Bityutskiy switch (mode & S_IFMT) { 4191e51764aSArtem Bityutskiy case S_IFREG: 4201e51764aSArtem Bityutskiy return UBIFS_ITYPE_REG; 4211e51764aSArtem Bityutskiy case S_IFDIR: 4221e51764aSArtem Bityutskiy return UBIFS_ITYPE_DIR; 4231e51764aSArtem Bityutskiy case S_IFLNK: 4241e51764aSArtem Bityutskiy return UBIFS_ITYPE_LNK; 4251e51764aSArtem Bityutskiy case S_IFBLK: 4261e51764aSArtem Bityutskiy return UBIFS_ITYPE_BLK; 4271e51764aSArtem Bityutskiy case S_IFCHR: 4281e51764aSArtem Bityutskiy return UBIFS_ITYPE_CHR; 4291e51764aSArtem Bityutskiy case S_IFIFO: 4301e51764aSArtem Bityutskiy return UBIFS_ITYPE_FIFO; 4311e51764aSArtem Bityutskiy case S_IFSOCK: 4321e51764aSArtem Bityutskiy return UBIFS_ITYPE_SOCK; 4331e51764aSArtem Bityutskiy default: 4341e51764aSArtem Bityutskiy BUG(); 4351e51764aSArtem Bityutskiy } 4361e51764aSArtem Bityutskiy return 0; 4371e51764aSArtem Bityutskiy } 4381e51764aSArtem Bityutskiy 4391e51764aSArtem Bityutskiy /** 4401e51764aSArtem Bityutskiy * pack_inode - pack an inode node. 4411e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4421e51764aSArtem Bityutskiy * @ino: buffer in which to pack inode node 4431e51764aSArtem Bityutskiy * @inode: inode to pack 4441e51764aSArtem Bityutskiy * @last: indicates the last node of the group 4451e51764aSArtem Bityutskiy */ 4461e51764aSArtem Bityutskiy static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino, 447fd6c6b51SArtem Bityutskiy const struct inode *inode, int last) 4481e51764aSArtem Bityutskiy { 449fd6c6b51SArtem Bityutskiy int data_len = 0, last_reference = !inode->i_nlink; 4501e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 4511e51764aSArtem Bityutskiy 4521e51764aSArtem Bityutskiy ino->ch.node_type = UBIFS_INO_NODE; 4531e51764aSArtem Bityutskiy ino_key_init_flash(c, &ino->key, inode->i_ino); 4541e51764aSArtem Bityutskiy ino->creat_sqnum = cpu_to_le64(ui->creat_sqnum); 4551e51764aSArtem Bityutskiy ino->atime_sec = cpu_to_le64(inode->i_atime.tv_sec); 4561e51764aSArtem Bityutskiy ino->atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); 4571e51764aSArtem Bityutskiy ino->ctime_sec = cpu_to_le64(inode->i_ctime.tv_sec); 4581e51764aSArtem Bityutskiy ino->ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); 4591e51764aSArtem Bityutskiy ino->mtime_sec = cpu_to_le64(inode->i_mtime.tv_sec); 4601e51764aSArtem Bityutskiy ino->mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); 46139241bebSEric W. Biederman ino->uid = cpu_to_le32(i_uid_read(inode)); 46239241bebSEric W. Biederman ino->gid = cpu_to_le32(i_gid_read(inode)); 4631e51764aSArtem Bityutskiy ino->mode = cpu_to_le32(inode->i_mode); 4641e51764aSArtem Bityutskiy ino->flags = cpu_to_le32(ui->flags); 4651e51764aSArtem Bityutskiy ino->size = cpu_to_le64(ui->ui_size); 4661e51764aSArtem Bityutskiy ino->nlink = cpu_to_le32(inode->i_nlink); 4671e51764aSArtem Bityutskiy ino->compr_type = cpu_to_le16(ui->compr_type); 4681e51764aSArtem Bityutskiy ino->data_len = cpu_to_le32(ui->data_len); 4691e51764aSArtem Bityutskiy ino->xattr_cnt = cpu_to_le32(ui->xattr_cnt); 4701e51764aSArtem Bityutskiy ino->xattr_size = cpu_to_le32(ui->xattr_size); 4711e51764aSArtem Bityutskiy ino->xattr_names = cpu_to_le32(ui->xattr_names); 4721e51764aSArtem Bityutskiy zero_ino_node_unused(ino); 4731e51764aSArtem Bityutskiy 4741e51764aSArtem Bityutskiy /* 4751e51764aSArtem Bityutskiy * Drop the attached data if this is a deletion inode, the data is not 4761e51764aSArtem Bityutskiy * needed anymore. 4771e51764aSArtem Bityutskiy */ 4781e51764aSArtem Bityutskiy if (!last_reference) { 4791e51764aSArtem Bityutskiy memcpy(ino->data, ui->data, ui->data_len); 4801e51764aSArtem Bityutskiy data_len = ui->data_len; 4811e51764aSArtem Bityutskiy } 4821e51764aSArtem Bityutskiy 4831e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, ino, UBIFS_INO_NODE_SZ + data_len, last); 4841e51764aSArtem Bityutskiy } 4851e51764aSArtem Bityutskiy 4861e51764aSArtem Bityutskiy /** 4871e51764aSArtem Bityutskiy * mark_inode_clean - mark UBIFS inode as clean. 4881e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4891e51764aSArtem Bityutskiy * @ui: UBIFS inode to mark as clean 4901e51764aSArtem Bityutskiy * 4911e51764aSArtem Bityutskiy * This helper function marks UBIFS inode @ui as clean by cleaning the 4921e51764aSArtem Bityutskiy * @ui->dirty flag and releasing its budget. Note, VFS may still treat the 4931e51764aSArtem Bityutskiy * inode as dirty and try to write it back, but 'ubifs_write_inode()' would 4941e51764aSArtem Bityutskiy * just do nothing. 4951e51764aSArtem Bityutskiy */ 4961e51764aSArtem Bityutskiy static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui) 4971e51764aSArtem Bityutskiy { 4981e51764aSArtem Bityutskiy if (ui->dirty) 4991e51764aSArtem Bityutskiy ubifs_release_dirty_inode_budget(c, ui); 5001e51764aSArtem Bityutskiy ui->dirty = 0; 5011e51764aSArtem Bityutskiy } 5021e51764aSArtem Bityutskiy 503d63d61c1SRichard Weinberger static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent) 504d63d61c1SRichard Weinberger { 505d63d61c1SRichard Weinberger if (c->double_hash) 5063cfa4412SBen Dooks (Codethink) dent->cookie = (__force __le32) prandom_u32(); 507d63d61c1SRichard Weinberger else 508d63d61c1SRichard Weinberger dent->cookie = 0; 509d63d61c1SRichard Weinberger } 510d63d61c1SRichard Weinberger 5111e51764aSArtem Bityutskiy /** 5121e51764aSArtem Bityutskiy * ubifs_jnl_update - update inode. 5131e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 5141e51764aSArtem Bityutskiy * @dir: parent inode or host inode in case of extended attributes 5151e51764aSArtem Bityutskiy * @nm: directory entry name 5161e51764aSArtem Bityutskiy * @inode: inode to update 5171e51764aSArtem Bityutskiy * @deletion: indicates a directory entry deletion i.e unlink or rmdir 5181e51764aSArtem Bityutskiy * @xent: non-zero if the directory entry is an extended attribute entry 5191e51764aSArtem Bityutskiy * 5201e51764aSArtem Bityutskiy * This function updates an inode by writing a directory entry (or extended 5211e51764aSArtem Bityutskiy * attribute entry), the inode itself, and the parent directory inode (or the 5221e51764aSArtem Bityutskiy * host inode) to the journal. 5231e51764aSArtem Bityutskiy * 5241e51764aSArtem Bityutskiy * The function writes the host inode @dir last, which is important in case of 5251e51764aSArtem Bityutskiy * extended attributes. Indeed, then we guarantee that if the host inode gets 5261e51764aSArtem Bityutskiy * synchronized (with 'fsync()'), and the write-buffer it sits in gets flushed, 5271e51764aSArtem Bityutskiy * the extended attribute inode gets flushed too. And this is exactly what the 5281e51764aSArtem Bityutskiy * user expects - synchronizing the host inode synchronizes its extended 5291e51764aSArtem Bityutskiy * attributes. Similarly, this guarantees that if @dir is synchronized, its 5301e51764aSArtem Bityutskiy * directory entry corresponding to @nm gets synchronized too. 5311e51764aSArtem Bityutskiy * 5321e51764aSArtem Bityutskiy * If the inode (@inode) or the parent directory (@dir) are synchronous, this 5331e51764aSArtem Bityutskiy * function synchronizes the write-buffer. 5341e51764aSArtem Bityutskiy * 5351e51764aSArtem Bityutskiy * This function marks the @dir and @inode inodes as clean and returns zero on 5361e51764aSArtem Bityutskiy * success. In case of failure, a negative error code is returned. 5371e51764aSArtem Bityutskiy */ 5381e51764aSArtem Bityutskiy int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, 539f4f61d2cSRichard Weinberger const struct fscrypt_name *nm, const struct inode *inode, 5401e51764aSArtem Bityutskiy int deletion, int xent) 5411e51764aSArtem Bityutskiy { 542094b6d12SZhihao Cheng int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added = 0; 5431e51764aSArtem Bityutskiy int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir); 5441e51764aSArtem Bityutskiy int last_reference = !!(deletion && inode->i_nlink == 0); 5451e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 546d577bc10SRichard Weinberger struct ubifs_inode *host_ui = ubifs_inode(dir); 5471e51764aSArtem Bityutskiy struct ubifs_dent_node *dent; 5481e51764aSArtem Bityutskiy struct ubifs_ino_node *ino; 5491e51764aSArtem Bityutskiy union ubifs_key dent_key, ino_key; 550823838a4SSascha Hauer u8 hash_dent[UBIFS_HASH_ARR_SZ]; 551823838a4SSascha Hauer u8 hash_ino[UBIFS_HASH_ARR_SZ]; 552823838a4SSascha Hauer u8 hash_ino_host[UBIFS_HASH_ARR_SZ]; 5531e51764aSArtem Bityutskiy 5546eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); 5551e51764aSArtem Bityutskiy 556f4f61d2cSRichard Weinberger dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1; 5571e51764aSArtem Bityutskiy ilen = UBIFS_INO_NODE_SZ; 5581e51764aSArtem Bityutskiy 5591e51764aSArtem Bityutskiy /* 5601e51764aSArtem Bityutskiy * If the last reference to the inode is being deleted, then there is 5611e51764aSArtem Bityutskiy * no need to attach and write inode data, it is being deleted anyway. 5621e51764aSArtem Bityutskiy * And if the inode is being deleted, no need to synchronize 5631e51764aSArtem Bityutskiy * write-buffer even if the inode is synchronous. 5641e51764aSArtem Bityutskiy */ 5651e51764aSArtem Bityutskiy if (!last_reference) { 5661e51764aSArtem Bityutskiy ilen += ui->data_len; 5671e51764aSArtem Bityutskiy sync |= IS_SYNC(inode); 5681e51764aSArtem Bityutskiy } 5691e51764aSArtem Bityutskiy 5701e51764aSArtem Bityutskiy aligned_dlen = ALIGN(dlen, 8); 5711e51764aSArtem Bityutskiy aligned_ilen = ALIGN(ilen, 8); 572a76284e6SSubodh Nijsure 5731e51764aSArtem Bityutskiy len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; 574a76284e6SSubodh Nijsure /* Make sure to also account for extended attributes */ 5756a98bc46SSascha Hauer if (ubifs_authenticated(c)) 5766a98bc46SSascha Hauer len += ALIGN(host_ui->data_len, 8) + ubifs_auth_node_sz(c); 5776a98bc46SSascha Hauer else 578a76284e6SSubodh Nijsure len += host_ui->data_len; 579a76284e6SSubodh Nijsure 5804acadda7SRichard Weinberger dent = kzalloc(len, GFP_NOFS); 5811e51764aSArtem Bityutskiy if (!dent) 5821e51764aSArtem Bityutskiy return -ENOMEM; 5831e51764aSArtem Bityutskiy 5841e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 5851e51764aSArtem Bityutskiy err = make_reservation(c, BASEHD, len); 5861e51764aSArtem Bityutskiy if (err) 5871e51764aSArtem Bityutskiy goto out_free; 5881e51764aSArtem Bityutskiy 5891e51764aSArtem Bityutskiy if (!xent) { 5901e51764aSArtem Bityutskiy dent->ch.node_type = UBIFS_DENT_NODE; 591aec992aaSEric Biggers if (fname_name(nm) == NULL) 592781f675eSRichard Weinberger dent_key_init_hash(c, &dent_key, dir->i_ino, nm->hash); 593781f675eSRichard Weinberger else 5941e51764aSArtem Bityutskiy dent_key_init(c, &dent_key, dir->i_ino, nm); 5951e51764aSArtem Bityutskiy } else { 5961e51764aSArtem Bityutskiy dent->ch.node_type = UBIFS_XENT_NODE; 5971e51764aSArtem Bityutskiy xent_key_init(c, &dent_key, dir->i_ino, nm); 5981e51764aSArtem Bityutskiy } 5991e51764aSArtem Bityutskiy 6001e51764aSArtem Bityutskiy key_write(c, &dent_key, dent->key); 6011e51764aSArtem Bityutskiy dent->inum = deletion ? 0 : cpu_to_le64(inode->i_ino); 6021e51764aSArtem Bityutskiy dent->type = get_dent_type(inode->i_mode); 603f4f61d2cSRichard Weinberger dent->nlen = cpu_to_le16(fname_len(nm)); 604f4f61d2cSRichard Weinberger memcpy(dent->name, fname_name(nm), fname_len(nm)); 605f4f61d2cSRichard Weinberger dent->name[fname_len(nm)] = '\0'; 606d63d61c1SRichard Weinberger set_dent_cookie(c, dent); 607f4f61d2cSRichard Weinberger 6081e51764aSArtem Bityutskiy zero_dent_node_unused(dent); 6091e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, dent, dlen, 0); 610823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dent, hash_dent); 611823838a4SSascha Hauer if (err) 612823838a4SSascha Hauer goto out_release; 6131e51764aSArtem Bityutskiy 6141e51764aSArtem Bityutskiy ino = (void *)dent + aligned_dlen; 615fd6c6b51SArtem Bityutskiy pack_inode(c, ino, inode, 0); 616823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash_ino); 617823838a4SSascha Hauer if (err) 618823838a4SSascha Hauer goto out_release; 619823838a4SSascha Hauer 6201e51764aSArtem Bityutskiy ino = (void *)ino + aligned_ilen; 621fd6c6b51SArtem Bityutskiy pack_inode(c, ino, dir, 1); 622823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash_ino_host); 623823838a4SSascha Hauer if (err) 624823838a4SSascha Hauer goto out_release; 6251e51764aSArtem Bityutskiy 6261e51764aSArtem Bityutskiy if (last_reference) { 6271e51764aSArtem Bityutskiy err = ubifs_add_orphan(c, inode->i_ino); 6281e51764aSArtem Bityutskiy if (err) { 6291e51764aSArtem Bityutskiy release_head(c, BASEHD); 6301e51764aSArtem Bityutskiy goto out_finish; 6311e51764aSArtem Bityutskiy } 632de94eb55SArtem Bityutskiy ui->del_cmtno = c->cmt_no; 633094b6d12SZhihao Cheng orphan_added = 1; 6341e51764aSArtem Bityutskiy } 6351e51764aSArtem Bityutskiy 6361e51764aSArtem Bityutskiy err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); 6371e51764aSArtem Bityutskiy if (err) 6381e51764aSArtem Bityutskiy goto out_release; 6391e51764aSArtem Bityutskiy if (!sync) { 6401e51764aSArtem Bityutskiy struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; 6411e51764aSArtem Bityutskiy 6421e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, inode->i_ino); 6431e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, dir->i_ino); 6441e51764aSArtem Bityutskiy } 6451e51764aSArtem Bityutskiy release_head(c, BASEHD); 6461e51764aSArtem Bityutskiy kfree(dent); 6476a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 6481e51764aSArtem Bityutskiy 6491e51764aSArtem Bityutskiy if (deletion) { 650aec992aaSEric Biggers if (fname_name(nm) == NULL) 651781f675eSRichard Weinberger err = ubifs_tnc_remove_dh(c, &dent_key, nm->minor_hash); 652781f675eSRichard Weinberger else 6531e51764aSArtem Bityutskiy err = ubifs_tnc_remove_nm(c, &dent_key, nm); 6541e51764aSArtem Bityutskiy if (err) 6551e51764aSArtem Bityutskiy goto out_ro; 6561e51764aSArtem Bityutskiy err = ubifs_add_dirt(c, lnum, dlen); 6571e51764aSArtem Bityutskiy } else 658823838a4SSascha Hauer err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, 659823838a4SSascha Hauer hash_dent, nm); 6601e51764aSArtem Bityutskiy if (err) 6611e51764aSArtem Bityutskiy goto out_ro; 6621e51764aSArtem Bityutskiy 6631e51764aSArtem Bityutskiy /* 6641e51764aSArtem Bityutskiy * Note, we do not remove the inode from TNC even if the last reference 6651e51764aSArtem Bityutskiy * to it has just been deleted, because the inode may still be opened. 6661e51764aSArtem Bityutskiy * Instead, the inode has been added to orphan lists and the orphan 6671e51764aSArtem Bityutskiy * subsystem will take further care about it. 6681e51764aSArtem Bityutskiy */ 6691e51764aSArtem Bityutskiy ino_key_init(c, &ino_key, inode->i_ino); 6701e51764aSArtem Bityutskiy ino_offs = dent_offs + aligned_dlen; 671823838a4SSascha Hauer err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen, hash_ino); 6721e51764aSArtem Bityutskiy if (err) 6731e51764aSArtem Bityutskiy goto out_ro; 6741e51764aSArtem Bityutskiy 6751e51764aSArtem Bityutskiy ino_key_init(c, &ino_key, dir->i_ino); 6761e51764aSArtem Bityutskiy ino_offs += aligned_ilen; 677a76284e6SSubodh Nijsure err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, 678823838a4SSascha Hauer UBIFS_INO_NODE_SZ + host_ui->data_len, hash_ino_host); 6791e51764aSArtem Bityutskiy if (err) 6801e51764aSArtem Bityutskiy goto out_ro; 6811e51764aSArtem Bityutskiy 6821e51764aSArtem Bityutskiy finish_reservation(c); 6831e51764aSArtem Bityutskiy spin_lock(&ui->ui_lock); 6841e51764aSArtem Bityutskiy ui->synced_i_size = ui->ui_size; 6851e51764aSArtem Bityutskiy spin_unlock(&ui->ui_lock); 68659965593SRichard Weinberger if (xent) { 68759965593SRichard Weinberger spin_lock(&host_ui->ui_lock); 68859965593SRichard Weinberger host_ui->synced_i_size = host_ui->ui_size; 68959965593SRichard Weinberger spin_unlock(&host_ui->ui_lock); 69059965593SRichard Weinberger } 6911e51764aSArtem Bityutskiy mark_inode_clean(c, ui); 692d577bc10SRichard Weinberger mark_inode_clean(c, host_ui); 6931e51764aSArtem Bityutskiy return 0; 6941e51764aSArtem Bityutskiy 6951e51764aSArtem Bityutskiy out_finish: 6961e51764aSArtem Bityutskiy finish_reservation(c); 6971e51764aSArtem Bityutskiy out_free: 6981e51764aSArtem Bityutskiy kfree(dent); 6991e51764aSArtem Bityutskiy return err; 7001e51764aSArtem Bityutskiy 7011e51764aSArtem Bityutskiy out_release: 7021e51764aSArtem Bityutskiy release_head(c, BASEHD); 703812eb258SArtem Bityutskiy kfree(dent); 7041e51764aSArtem Bityutskiy out_ro: 7051e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 706094b6d12SZhihao Cheng if (orphan_added) 7071e51764aSArtem Bityutskiy ubifs_delete_orphan(c, inode->i_ino); 7081e51764aSArtem Bityutskiy finish_reservation(c); 7091e51764aSArtem Bityutskiy return err; 7101e51764aSArtem Bityutskiy } 7111e51764aSArtem Bityutskiy 7121e51764aSArtem Bityutskiy /** 7131e51764aSArtem Bityutskiy * ubifs_jnl_write_data - write a data node to the journal. 7141e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 7151e51764aSArtem Bityutskiy * @inode: inode the data node belongs to 7161e51764aSArtem Bityutskiy * @key: node key 7171e51764aSArtem Bityutskiy * @buf: buffer to write 7181e51764aSArtem Bityutskiy * @len: data length (must not exceed %UBIFS_BLOCK_SIZE) 7191e51764aSArtem Bityutskiy * 7201e51764aSArtem Bityutskiy * This function writes a data node to the journal. Returns %0 if the data node 7211e51764aSArtem Bityutskiy * was successfully written, and a negative error code in case of failure. 7221e51764aSArtem Bityutskiy */ 7231e51764aSArtem Bityutskiy int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, 7241e51764aSArtem Bityutskiy const union ubifs_key *key, const void *buf, int len) 7251e51764aSArtem Bityutskiy { 7261e51764aSArtem Bityutskiy struct ubifs_data_node *data; 7276a98bc46SSascha Hauer int err, lnum, offs, compr_type, out_len, compr_len, auth_len; 728d882962fSMatthew L. Creech int dlen = COMPRESSED_DATA_NODE_BUF_SZ, allocated = 1; 7296a98bc46SSascha Hauer int write_len; 7301e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 73150d9fad7SEric Biggers bool encrypted = IS_ENCRYPTED(inode); 732823838a4SSascha Hauer u8 hash[UBIFS_HASH_ARR_SZ]; 7331e51764aSArtem Bityutskiy 734515315a1SArtem Bityutskiy dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", 735515315a1SArtem Bityutskiy (unsigned long)key_inum(c, key), key_block(c, key), len); 7366eb61d58SRichard Weinberger ubifs_assert(c, len <= UBIFS_BLOCK_SIZE); 7371e51764aSArtem Bityutskiy 7387799953bSRichard Weinberger if (encrypted) 7397799953bSRichard Weinberger dlen += UBIFS_CIPHER_BLOCK_SIZE; 7407799953bSRichard Weinberger 7416a98bc46SSascha Hauer auth_len = ubifs_auth_node_sz(c); 7426a98bc46SSascha Hauer 7436a98bc46SSascha Hauer data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN); 744d882962fSMatthew L. Creech if (!data) { 745d882962fSMatthew L. Creech /* 746d882962fSMatthew L. Creech * Fall-back to the write reserve buffer. Note, we might be 747d882962fSMatthew L. Creech * currently on the memory reclaim path, when the kernel is 748d882962fSMatthew L. Creech * trying to free some memory by writing out dirty pages. The 749d882962fSMatthew L. Creech * write reserve buffer helps us to guarantee that we are 750d882962fSMatthew L. Creech * always able to write the data. 751d882962fSMatthew L. Creech */ 752d882962fSMatthew L. Creech allocated = 0; 753d882962fSMatthew L. Creech mutex_lock(&c->write_reserve_mutex); 754d882962fSMatthew L. Creech data = c->write_reserve_buf; 755d882962fSMatthew L. Creech } 7561e51764aSArtem Bityutskiy 7571e51764aSArtem Bityutskiy data->ch.node_type = UBIFS_DATA_NODE; 7581e51764aSArtem Bityutskiy key_write(c, key, &data->key); 7591e51764aSArtem Bityutskiy data->size = cpu_to_le32(len); 7601e51764aSArtem Bityutskiy 761a9f2fc0eSArtem Bityutskiy if (!(ui->flags & UBIFS_COMPR_FL)) 7621e51764aSArtem Bityutskiy /* Compression is disabled for this inode */ 7631e51764aSArtem Bityutskiy compr_type = UBIFS_COMPR_NONE; 7641e51764aSArtem Bityutskiy else 7651e51764aSArtem Bityutskiy compr_type = ui->compr_type; 7661e51764aSArtem Bityutskiy 7677799953bSRichard Weinberger out_len = compr_len = dlen - UBIFS_DATA_NODE_SZ; 7687799953bSRichard Weinberger ubifs_compress(c, buf, len, &data->data, &compr_len, &compr_type); 7696eb61d58SRichard Weinberger ubifs_assert(c, compr_len <= UBIFS_BLOCK_SIZE); 7707799953bSRichard Weinberger 7717799953bSRichard Weinberger if (encrypted) { 7727799953bSRichard Weinberger err = ubifs_encrypt(inode, data, compr_len, &out_len, key_block(c, key)); 7737799953bSRichard Weinberger if (err) 7747799953bSRichard Weinberger goto out_free; 7757799953bSRichard Weinberger 7767799953bSRichard Weinberger } else { 7777799953bSRichard Weinberger data->compr_size = 0; 778507502adSPeter Rosin out_len = compr_len; 7797799953bSRichard Weinberger } 7801e51764aSArtem Bityutskiy 7811e51764aSArtem Bityutskiy dlen = UBIFS_DATA_NODE_SZ + out_len; 7826a98bc46SSascha Hauer if (ubifs_authenticated(c)) 7836a98bc46SSascha Hauer write_len = ALIGN(dlen, 8) + auth_len; 7846a98bc46SSascha Hauer else 7856a98bc46SSascha Hauer write_len = dlen; 7866a98bc46SSascha Hauer 7871e51764aSArtem Bityutskiy data->compr_type = cpu_to_le16(compr_type); 7881e51764aSArtem Bityutskiy 7891e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 7906a98bc46SSascha Hauer err = make_reservation(c, DATAHD, write_len); 7911e51764aSArtem Bityutskiy if (err) 7921e51764aSArtem Bityutskiy goto out_free; 7931e51764aSArtem Bityutskiy 79483407437SSascha Hauer ubifs_prepare_node(c, data, dlen, 0); 7956a98bc46SSascha Hauer err = write_head(c, DATAHD, data, write_len, &lnum, &offs, 0); 7961e51764aSArtem Bityutskiy if (err) 7971e51764aSArtem Bityutskiy goto out_release; 798823838a4SSascha Hauer 799823838a4SSascha Hauer err = ubifs_node_calc_hash(c, data, hash); 800823838a4SSascha Hauer if (err) 801823838a4SSascha Hauer goto out_release; 802823838a4SSascha Hauer 8031e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); 8041e51764aSArtem Bityutskiy release_head(c, DATAHD); 8051e51764aSArtem Bityutskiy 8066a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 8076a98bc46SSascha Hauer 808823838a4SSascha Hauer err = ubifs_tnc_add(c, key, lnum, offs, dlen, hash); 8091e51764aSArtem Bityutskiy if (err) 8101e51764aSArtem Bityutskiy goto out_ro; 8111e51764aSArtem Bityutskiy 8121e51764aSArtem Bityutskiy finish_reservation(c); 813d882962fSMatthew L. Creech if (!allocated) 814d882962fSMatthew L. Creech mutex_unlock(&c->write_reserve_mutex); 815d882962fSMatthew L. Creech else 8161e51764aSArtem Bityutskiy kfree(data); 8171e51764aSArtem Bityutskiy return 0; 8181e51764aSArtem Bityutskiy 8191e51764aSArtem Bityutskiy out_release: 8201e51764aSArtem Bityutskiy release_head(c, DATAHD); 8211e51764aSArtem Bityutskiy out_ro: 8221e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 8231e51764aSArtem Bityutskiy finish_reservation(c); 8241e51764aSArtem Bityutskiy out_free: 825d882962fSMatthew L. Creech if (!allocated) 826d882962fSMatthew L. Creech mutex_unlock(&c->write_reserve_mutex); 827d882962fSMatthew L. Creech else 8281e51764aSArtem Bityutskiy kfree(data); 8291e51764aSArtem Bityutskiy return err; 8301e51764aSArtem Bityutskiy } 8311e51764aSArtem Bityutskiy 8321e51764aSArtem Bityutskiy /** 8331e51764aSArtem Bityutskiy * ubifs_jnl_write_inode - flush inode to the journal. 8341e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 8351e51764aSArtem Bityutskiy * @inode: inode to flush 8361e51764aSArtem Bityutskiy * 8371e51764aSArtem Bityutskiy * This function writes inode @inode to the journal. If the inode is 8381e51764aSArtem Bityutskiy * synchronous, it also synchronizes the write-buffer. Returns zero in case of 8391e51764aSArtem Bityutskiy * success and a negative error code in case of failure. 8401e51764aSArtem Bityutskiy */ 8411f28681aSArtem Bityutskiy int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) 8421e51764aSArtem Bityutskiy { 8431f28681aSArtem Bityutskiy int err, lnum, offs; 8447959cf3aSRichard Weinberger struct ubifs_ino_node *ino, *ino_start; 8451e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 8467959cf3aSRichard Weinberger int sync = 0, write_len = 0, ilen = UBIFS_INO_NODE_SZ; 8476a98bc46SSascha Hauer int last_reference = !inode->i_nlink; 8487959cf3aSRichard Weinberger int kill_xattrs = ui->xattr_cnt && last_reference; 849823838a4SSascha Hauer u8 hash[UBIFS_HASH_ARR_SZ]; 8501e51764aSArtem Bityutskiy 8511f28681aSArtem Bityutskiy dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); 8521e51764aSArtem Bityutskiy 8531e51764aSArtem Bityutskiy /* 8541e51764aSArtem Bityutskiy * If the inode is being deleted, do not write the attached data. No 8551e51764aSArtem Bityutskiy * need to synchronize the write-buffer either. 8561e51764aSArtem Bityutskiy */ 8571f28681aSArtem Bityutskiy if (!last_reference) { 8586a98bc46SSascha Hauer ilen += ui->data_len; 8591e51764aSArtem Bityutskiy sync = IS_SYNC(inode); 8607959cf3aSRichard Weinberger } else if (kill_xattrs) { 8617959cf3aSRichard Weinberger write_len += UBIFS_INO_NODE_SZ * ui->xattr_cnt; 8621e51764aSArtem Bityutskiy } 8636a98bc46SSascha Hauer 8646a98bc46SSascha Hauer if (ubifs_authenticated(c)) 8657959cf3aSRichard Weinberger write_len += ALIGN(ilen, 8) + ubifs_auth_node_sz(c); 8666a98bc46SSascha Hauer else 8677959cf3aSRichard Weinberger write_len += ilen; 8686a98bc46SSascha Hauer 8697959cf3aSRichard Weinberger ino_start = ino = kmalloc(write_len, GFP_NOFS); 8701e51764aSArtem Bityutskiy if (!ino) 8711e51764aSArtem Bityutskiy return -ENOMEM; 8721e51764aSArtem Bityutskiy 8731e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 8746a98bc46SSascha Hauer err = make_reservation(c, BASEHD, write_len); 8751e51764aSArtem Bityutskiy if (err) 8761e51764aSArtem Bityutskiy goto out_free; 8771e51764aSArtem Bityutskiy 8787959cf3aSRichard Weinberger if (kill_xattrs) { 8797959cf3aSRichard Weinberger union ubifs_key key; 8807959cf3aSRichard Weinberger struct fscrypt_name nm = {0}; 8817959cf3aSRichard Weinberger struct inode *xino; 8827959cf3aSRichard Weinberger struct ubifs_dent_node *xent, *pxent = NULL; 8837959cf3aSRichard Weinberger 884d984bcf5SSascha Hauer if (ui->xattr_cnt > ubifs_xattr_max_cnt(c)) { 885a2c2a622SZhen Lei err = -EPERM; 8869ca2d732SRichard Weinberger ubifs_err(c, "Cannot delete inode, it has too much xattrs!"); 8879ca2d732SRichard Weinberger goto out_release; 8889ca2d732SRichard Weinberger } 8899ca2d732SRichard Weinberger 8907959cf3aSRichard Weinberger lowest_xent_key(c, &key, inode->i_ino); 8917959cf3aSRichard Weinberger while (1) { 8927959cf3aSRichard Weinberger xent = ubifs_tnc_next_ent(c, &key, &nm); 8937959cf3aSRichard Weinberger if (IS_ERR(xent)) { 8947959cf3aSRichard Weinberger err = PTR_ERR(xent); 8957959cf3aSRichard Weinberger if (err == -ENOENT) 8967959cf3aSRichard Weinberger break; 8977959cf3aSRichard Weinberger 898f2aae745SZhihao Cheng kfree(pxent); 8997959cf3aSRichard Weinberger goto out_release; 9007959cf3aSRichard Weinberger } 9017959cf3aSRichard Weinberger 9027959cf3aSRichard Weinberger fname_name(&nm) = xent->name; 9037959cf3aSRichard Weinberger fname_len(&nm) = le16_to_cpu(xent->nlen); 9047959cf3aSRichard Weinberger 905df22b5b3SBen Dooks (Codethink) xino = ubifs_iget(c->vfs_sb, le64_to_cpu(xent->inum)); 9069ca2d732SRichard Weinberger if (IS_ERR(xino)) { 9079ca2d732SRichard Weinberger err = PTR_ERR(xino); 9089ca2d732SRichard Weinberger ubifs_err(c, "dead directory entry '%s', error %d", 9099ca2d732SRichard Weinberger xent->name, err); 9109ca2d732SRichard Weinberger ubifs_ro_mode(c, err); 911f2aae745SZhihao Cheng kfree(pxent); 91281423c78SZhihao Cheng kfree(xent); 9139ca2d732SRichard Weinberger goto out_release; 9149ca2d732SRichard Weinberger } 9157959cf3aSRichard Weinberger ubifs_assert(c, ubifs_inode(xino)->xattr); 9167959cf3aSRichard Weinberger 9177959cf3aSRichard Weinberger clear_nlink(xino); 9187959cf3aSRichard Weinberger pack_inode(c, ino, xino, 0); 9197959cf3aSRichard Weinberger ino = (void *)ino + UBIFS_INO_NODE_SZ; 9207959cf3aSRichard Weinberger iput(xino); 9217959cf3aSRichard Weinberger 9227959cf3aSRichard Weinberger kfree(pxent); 9237959cf3aSRichard Weinberger pxent = xent; 9247959cf3aSRichard Weinberger key_read(c, &xent->key, &key); 9257959cf3aSRichard Weinberger } 9267959cf3aSRichard Weinberger kfree(pxent); 9277959cf3aSRichard Weinberger } 9287959cf3aSRichard Weinberger 929fd6c6b51SArtem Bityutskiy pack_inode(c, ino, inode, 1); 930823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash); 931823838a4SSascha Hauer if (err) 932823838a4SSascha Hauer goto out_release; 933823838a4SSascha Hauer 9347959cf3aSRichard Weinberger err = write_head(c, BASEHD, ino_start, write_len, &lnum, &offs, sync); 9351e51764aSArtem Bityutskiy if (err) 9361e51764aSArtem Bityutskiy goto out_release; 9371e51764aSArtem Bityutskiy if (!sync) 9381e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, 9391e51764aSArtem Bityutskiy inode->i_ino); 9401e51764aSArtem Bityutskiy release_head(c, BASEHD); 9411e51764aSArtem Bityutskiy 9421f28681aSArtem Bityutskiy if (last_reference) { 9431e51764aSArtem Bityutskiy err = ubifs_tnc_remove_ino(c, inode->i_ino); 9441e51764aSArtem Bityutskiy if (err) 9451e51764aSArtem Bityutskiy goto out_ro; 9461e51764aSArtem Bityutskiy ubifs_delete_orphan(c, inode->i_ino); 9477959cf3aSRichard Weinberger err = ubifs_add_dirt(c, lnum, write_len); 9481e51764aSArtem Bityutskiy } else { 9491e51764aSArtem Bityutskiy union ubifs_key key; 9501e51764aSArtem Bityutskiy 95178c7d49fSRichard Weinberger ubifs_add_auth_dirt(c, lnum); 95278c7d49fSRichard Weinberger 9531e51764aSArtem Bityutskiy ino_key_init(c, &key, inode->i_ino); 9546a98bc46SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash); 9551e51764aSArtem Bityutskiy } 9561e51764aSArtem Bityutskiy if (err) 9571e51764aSArtem Bityutskiy goto out_ro; 9581e51764aSArtem Bityutskiy 9591e51764aSArtem Bityutskiy finish_reservation(c); 9601e51764aSArtem Bityutskiy spin_lock(&ui->ui_lock); 9611e51764aSArtem Bityutskiy ui->synced_i_size = ui->ui_size; 9621e51764aSArtem Bityutskiy spin_unlock(&ui->ui_lock); 9637959cf3aSRichard Weinberger kfree(ino_start); 9641e51764aSArtem Bityutskiy return 0; 9651e51764aSArtem Bityutskiy 9661e51764aSArtem Bityutskiy out_release: 9671e51764aSArtem Bityutskiy release_head(c, BASEHD); 9681e51764aSArtem Bityutskiy out_ro: 9691e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 9701e51764aSArtem Bityutskiy finish_reservation(c); 9711e51764aSArtem Bityutskiy out_free: 9727959cf3aSRichard Weinberger kfree(ino_start); 9731e51764aSArtem Bityutskiy return err; 9741e51764aSArtem Bityutskiy } 9751e51764aSArtem Bityutskiy 9761e51764aSArtem Bityutskiy /** 9777d62ff2cSAdrian Hunter * ubifs_jnl_delete_inode - delete an inode. 978de94eb55SArtem Bityutskiy * @c: UBIFS file-system description object 979de94eb55SArtem Bityutskiy * @inode: inode to delete 980de94eb55SArtem Bityutskiy * 981de94eb55SArtem Bityutskiy * This function deletes inode @inode which includes removing it from orphans, 982de94eb55SArtem Bityutskiy * deleting it from TNC and, in some cases, writing a deletion inode to the 983de94eb55SArtem Bityutskiy * journal. 984de94eb55SArtem Bityutskiy * 985de94eb55SArtem Bityutskiy * When regular file inodes are unlinked or a directory inode is removed, the 9867d62ff2cSAdrian Hunter * 'ubifs_jnl_update()' function writes a corresponding deletion inode and 987de94eb55SArtem Bityutskiy * direntry to the media, and adds the inode to orphans. After this, when the 988de94eb55SArtem Bityutskiy * last reference to this inode has been dropped, this function is called. In 989de94eb55SArtem Bityutskiy * general, it has to write one more deletion inode to the media, because if 990de94eb55SArtem Bityutskiy * a commit happened between 'ubifs_jnl_update()' and 991de94eb55SArtem Bityutskiy * 'ubifs_jnl_delete_inode()', the deletion inode is not in the journal 9927d62ff2cSAdrian Hunter * anymore, and in fact it might not be on the flash anymore, because it might 9937d62ff2cSAdrian Hunter * have been garbage-collected already. And for optimization reasons UBIFS does 994de94eb55SArtem Bityutskiy * not read the orphan area if it has been unmounted cleanly, so it would have 995de94eb55SArtem Bityutskiy * no indication in the journal that there is a deleted inode which has to be 996de94eb55SArtem Bityutskiy * removed from TNC. 997de94eb55SArtem Bityutskiy * 998de94eb55SArtem Bityutskiy * However, if there was no commit between 'ubifs_jnl_update()' and 999de94eb55SArtem Bityutskiy * 'ubifs_jnl_delete_inode()', then there is no need to write the deletion 10007d62ff2cSAdrian Hunter * inode to the media for the second time. And this is quite a typical case. 1001de94eb55SArtem Bityutskiy * 1002de94eb55SArtem Bityutskiy * This function returns zero in case of success and a negative error code in 1003de94eb55SArtem Bityutskiy * case of failure. 1004de94eb55SArtem Bityutskiy */ 1005de94eb55SArtem Bityutskiy int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode) 1006de94eb55SArtem Bityutskiy { 1007de94eb55SArtem Bityutskiy int err; 1008de94eb55SArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 1009de94eb55SArtem Bityutskiy 10106eb61d58SRichard Weinberger ubifs_assert(c, inode->i_nlink == 0); 1011de94eb55SArtem Bityutskiy 10127959cf3aSRichard Weinberger if (ui->xattr_cnt || ui->del_cmtno != c->cmt_no) 10137959cf3aSRichard Weinberger /* A commit happened for sure or inode hosts xattrs */ 1014de94eb55SArtem Bityutskiy return ubifs_jnl_write_inode(c, inode); 1015de94eb55SArtem Bityutskiy 1016de94eb55SArtem Bityutskiy down_read(&c->commit_sem); 1017de94eb55SArtem Bityutskiy /* 1018de94eb55SArtem Bityutskiy * Check commit number again, because the first test has been done 1019de94eb55SArtem Bityutskiy * without @c->commit_sem, so a commit might have happened. 1020de94eb55SArtem Bityutskiy */ 1021de94eb55SArtem Bityutskiy if (ui->del_cmtno != c->cmt_no) { 1022de94eb55SArtem Bityutskiy up_read(&c->commit_sem); 1023de94eb55SArtem Bityutskiy return ubifs_jnl_write_inode(c, inode); 1024de94eb55SArtem Bityutskiy } 1025de94eb55SArtem Bityutskiy 1026de94eb55SArtem Bityutskiy err = ubifs_tnc_remove_ino(c, inode->i_ino); 1027de94eb55SArtem Bityutskiy if (err) 1028de94eb55SArtem Bityutskiy ubifs_ro_mode(c, err); 1029f7691084SAdrian Hunter else 1030f7691084SAdrian Hunter ubifs_delete_orphan(c, inode->i_ino); 1031de94eb55SArtem Bityutskiy up_read(&c->commit_sem); 1032de94eb55SArtem Bityutskiy return err; 1033de94eb55SArtem Bityutskiy } 1034de94eb55SArtem Bityutskiy 1035de94eb55SArtem Bityutskiy /** 10369ec64962SRichard Weinberger * ubifs_jnl_xrename - cross rename two directory entries. 10379ec64962SRichard Weinberger * @c: UBIFS file-system description object 10389ec64962SRichard Weinberger * @fst_dir: parent inode of 1st directory entry to exchange 1039f4f61d2cSRichard Weinberger * @fst_inode: 1st inode to exchange 1040f4f61d2cSRichard Weinberger * @fst_nm: name of 1st inode to exchange 10419ec64962SRichard Weinberger * @snd_dir: parent inode of 2nd directory entry to exchange 1042f4f61d2cSRichard Weinberger * @snd_inode: 2nd inode to exchange 1043f4f61d2cSRichard Weinberger * @snd_nm: name of 2nd inode to exchange 10449ec64962SRichard Weinberger * @sync: non-zero if the write-buffer has to be synchronized 10459ec64962SRichard Weinberger * 10469ec64962SRichard Weinberger * This function implements the cross rename operation which may involve 10479ec64962SRichard Weinberger * writing 2 inodes and 2 directory entries. It marks the written inodes as clean 10489ec64962SRichard Weinberger * and returns zero on success. In case of failure, a negative error code is 10499ec64962SRichard Weinberger * returned. 10509ec64962SRichard Weinberger */ 10519ec64962SRichard Weinberger int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, 1052f4f61d2cSRichard Weinberger const struct inode *fst_inode, 1053f4f61d2cSRichard Weinberger const struct fscrypt_name *fst_nm, 10549ec64962SRichard Weinberger const struct inode *snd_dir, 1055f4f61d2cSRichard Weinberger const struct inode *snd_inode, 1056f4f61d2cSRichard Weinberger const struct fscrypt_name *snd_nm, int sync) 10579ec64962SRichard Weinberger { 10589ec64962SRichard Weinberger union ubifs_key key; 10599ec64962SRichard Weinberger struct ubifs_dent_node *dent1, *dent2; 10609ec64962SRichard Weinberger int err, dlen1, dlen2, lnum, offs, len, plen = UBIFS_INO_NODE_SZ; 10619ec64962SRichard Weinberger int aligned_dlen1, aligned_dlen2; 10629ec64962SRichard Weinberger int twoparents = (fst_dir != snd_dir); 10639ec64962SRichard Weinberger void *p; 1064823838a4SSascha Hauer u8 hash_dent1[UBIFS_HASH_ARR_SZ]; 1065823838a4SSascha Hauer u8 hash_dent2[UBIFS_HASH_ARR_SZ]; 1066823838a4SSascha Hauer u8 hash_p1[UBIFS_HASH_ARR_SZ]; 1067823838a4SSascha Hauer u8 hash_p2[UBIFS_HASH_ARR_SZ]; 10689ec64962SRichard Weinberger 10696eb61d58SRichard Weinberger ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0); 10706eb61d58SRichard Weinberger ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0); 10716eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex)); 10726eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex)); 10739ec64962SRichard Weinberger 1074f4f61d2cSRichard Weinberger dlen1 = UBIFS_DENT_NODE_SZ + fname_len(snd_nm) + 1; 1075f4f61d2cSRichard Weinberger dlen2 = UBIFS_DENT_NODE_SZ + fname_len(fst_nm) + 1; 10769ec64962SRichard Weinberger aligned_dlen1 = ALIGN(dlen1, 8); 10779ec64962SRichard Weinberger aligned_dlen2 = ALIGN(dlen2, 8); 10789ec64962SRichard Weinberger 10799ec64962SRichard Weinberger len = aligned_dlen1 + aligned_dlen2 + ALIGN(plen, 8); 10809ec64962SRichard Weinberger if (twoparents) 10819ec64962SRichard Weinberger len += plen; 10829ec64962SRichard Weinberger 10836a98bc46SSascha Hauer len += ubifs_auth_node_sz(c); 10846a98bc46SSascha Hauer 10854acadda7SRichard Weinberger dent1 = kzalloc(len, GFP_NOFS); 10869ec64962SRichard Weinberger if (!dent1) 10879ec64962SRichard Weinberger return -ENOMEM; 10889ec64962SRichard Weinberger 10899ec64962SRichard Weinberger /* Make reservation before allocating sequence numbers */ 10909ec64962SRichard Weinberger err = make_reservation(c, BASEHD, len); 10919ec64962SRichard Weinberger if (err) 10929ec64962SRichard Weinberger goto out_free; 10939ec64962SRichard Weinberger 10949ec64962SRichard Weinberger /* Make new dent for 1st entry */ 10959ec64962SRichard Weinberger dent1->ch.node_type = UBIFS_DENT_NODE; 1096f4f61d2cSRichard Weinberger dent_key_init_flash(c, &dent1->key, snd_dir->i_ino, snd_nm); 10979ec64962SRichard Weinberger dent1->inum = cpu_to_le64(fst_inode->i_ino); 10989ec64962SRichard Weinberger dent1->type = get_dent_type(fst_inode->i_mode); 1099f4f61d2cSRichard Weinberger dent1->nlen = cpu_to_le16(fname_len(snd_nm)); 1100f4f61d2cSRichard Weinberger memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm)); 1101f4f61d2cSRichard Weinberger dent1->name[fname_len(snd_nm)] = '\0'; 1102a6664433SRichard Weinberger set_dent_cookie(c, dent1); 11039ec64962SRichard Weinberger zero_dent_node_unused(dent1); 11049ec64962SRichard Weinberger ubifs_prep_grp_node(c, dent1, dlen1, 0); 1105823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dent1, hash_dent1); 1106823838a4SSascha Hauer if (err) 1107823838a4SSascha Hauer goto out_release; 11089ec64962SRichard Weinberger 11099ec64962SRichard Weinberger /* Make new dent for 2nd entry */ 11109ec64962SRichard Weinberger dent2 = (void *)dent1 + aligned_dlen1; 11119ec64962SRichard Weinberger dent2->ch.node_type = UBIFS_DENT_NODE; 1112f4f61d2cSRichard Weinberger dent_key_init_flash(c, &dent2->key, fst_dir->i_ino, fst_nm); 11139ec64962SRichard Weinberger dent2->inum = cpu_to_le64(snd_inode->i_ino); 11149ec64962SRichard Weinberger dent2->type = get_dent_type(snd_inode->i_mode); 1115f4f61d2cSRichard Weinberger dent2->nlen = cpu_to_le16(fname_len(fst_nm)); 1116f4f61d2cSRichard Weinberger memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm)); 1117f4f61d2cSRichard Weinberger dent2->name[fname_len(fst_nm)] = '\0'; 1118a6664433SRichard Weinberger set_dent_cookie(c, dent2); 11199ec64962SRichard Weinberger zero_dent_node_unused(dent2); 11209ec64962SRichard Weinberger ubifs_prep_grp_node(c, dent2, dlen2, 0); 1121823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dent2, hash_dent2); 1122823838a4SSascha Hauer if (err) 1123823838a4SSascha Hauer goto out_release; 11249ec64962SRichard Weinberger 11259ec64962SRichard Weinberger p = (void *)dent2 + aligned_dlen2; 1126823838a4SSascha Hauer if (!twoparents) { 11279ec64962SRichard Weinberger pack_inode(c, p, fst_dir, 1); 1128823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_p1); 1129823838a4SSascha Hauer if (err) 1130823838a4SSascha Hauer goto out_release; 1131823838a4SSascha Hauer } else { 11329ec64962SRichard Weinberger pack_inode(c, p, fst_dir, 0); 1133823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_p1); 1134823838a4SSascha Hauer if (err) 1135823838a4SSascha Hauer goto out_release; 11369ec64962SRichard Weinberger p += ALIGN(plen, 8); 11379ec64962SRichard Weinberger pack_inode(c, p, snd_dir, 1); 1138823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_p2); 1139823838a4SSascha Hauer if (err) 1140823838a4SSascha Hauer goto out_release; 11419ec64962SRichard Weinberger } 11429ec64962SRichard Weinberger 11439ec64962SRichard Weinberger err = write_head(c, BASEHD, dent1, len, &lnum, &offs, sync); 11449ec64962SRichard Weinberger if (err) 11459ec64962SRichard Weinberger goto out_release; 11469ec64962SRichard Weinberger if (!sync) { 11479ec64962SRichard Weinberger struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; 11489ec64962SRichard Weinberger 11499ec64962SRichard Weinberger ubifs_wbuf_add_ino_nolock(wbuf, fst_dir->i_ino); 11509ec64962SRichard Weinberger ubifs_wbuf_add_ino_nolock(wbuf, snd_dir->i_ino); 11519ec64962SRichard Weinberger } 11529ec64962SRichard Weinberger release_head(c, BASEHD); 11539ec64962SRichard Weinberger 11546a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 11556a98bc46SSascha Hauer 1156f4f61d2cSRichard Weinberger dent_key_init(c, &key, snd_dir->i_ino, snd_nm); 1157823838a4SSascha Hauer err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, snd_nm); 11589ec64962SRichard Weinberger if (err) 11599ec64962SRichard Weinberger goto out_ro; 11609ec64962SRichard Weinberger 11619ec64962SRichard Weinberger offs += aligned_dlen1; 1162f4f61d2cSRichard Weinberger dent_key_init(c, &key, fst_dir->i_ino, fst_nm); 1163823838a4SSascha Hauer err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, fst_nm); 11649ec64962SRichard Weinberger if (err) 11659ec64962SRichard Weinberger goto out_ro; 11669ec64962SRichard Weinberger 11679ec64962SRichard Weinberger offs += aligned_dlen2; 11689ec64962SRichard Weinberger 11699ec64962SRichard Weinberger ino_key_init(c, &key, fst_dir->i_ino); 1170823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p1); 11719ec64962SRichard Weinberger if (err) 11729ec64962SRichard Weinberger goto out_ro; 11739ec64962SRichard Weinberger 11749ec64962SRichard Weinberger if (twoparents) { 11759ec64962SRichard Weinberger offs += ALIGN(plen, 8); 11769ec64962SRichard Weinberger ino_key_init(c, &key, snd_dir->i_ino); 1177823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_p2); 11789ec64962SRichard Weinberger if (err) 11799ec64962SRichard Weinberger goto out_ro; 11809ec64962SRichard Weinberger } 11819ec64962SRichard Weinberger 11829ec64962SRichard Weinberger finish_reservation(c); 11839ec64962SRichard Weinberger 11849ec64962SRichard Weinberger mark_inode_clean(c, ubifs_inode(fst_dir)); 11859ec64962SRichard Weinberger if (twoparents) 11869ec64962SRichard Weinberger mark_inode_clean(c, ubifs_inode(snd_dir)); 11879ec64962SRichard Weinberger kfree(dent1); 11889ec64962SRichard Weinberger return 0; 11899ec64962SRichard Weinberger 11909ec64962SRichard Weinberger out_release: 11919ec64962SRichard Weinberger release_head(c, BASEHD); 11929ec64962SRichard Weinberger out_ro: 11939ec64962SRichard Weinberger ubifs_ro_mode(c, err); 11949ec64962SRichard Weinberger finish_reservation(c); 11959ec64962SRichard Weinberger out_free: 11969ec64962SRichard Weinberger kfree(dent1); 11979ec64962SRichard Weinberger return err; 11989ec64962SRichard Weinberger } 11999ec64962SRichard Weinberger 12009ec64962SRichard Weinberger /** 12011e51764aSArtem Bityutskiy * ubifs_jnl_rename - rename a directory entry. 12021e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 12031e51764aSArtem Bityutskiy * @old_dir: parent inode of directory entry to rename 12041e51764aSArtem Bityutskiy * @old_dentry: directory entry to rename 12051e51764aSArtem Bityutskiy * @new_dir: parent inode of directory entry to rename 12061e51764aSArtem Bityutskiy * @new_dentry: new directory entry (or directory entry to replace) 12071e51764aSArtem Bityutskiy * @sync: non-zero if the write-buffer has to be synchronized 12081e51764aSArtem Bityutskiy * 12091e51764aSArtem Bityutskiy * This function implements the re-name operation which may involve writing up 1210278d9a24SZhihao Cheng * to 4 inodes(new inode, whiteout inode, old and new parent directory inodes) 1211278d9a24SZhihao Cheng * and 2 directory entries. It marks the written inodes as clean and returns 1212278d9a24SZhihao Cheng * zero on success. In case of failure, a negative error code is returned. 12131e51764aSArtem Bityutskiy */ 12141e51764aSArtem Bityutskiy int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, 1215f4f61d2cSRichard Weinberger const struct inode *old_inode, 1216f4f61d2cSRichard Weinberger const struct fscrypt_name *old_nm, 12171e51764aSArtem Bityutskiy const struct inode *new_dir, 1218f4f61d2cSRichard Weinberger const struct inode *new_inode, 1219f4f61d2cSRichard Weinberger const struct fscrypt_name *new_nm, 12209e0a1fffSRichard Weinberger const struct inode *whiteout, int sync) 12211e51764aSArtem Bityutskiy { 12221e51764aSArtem Bityutskiy void *p; 12231e51764aSArtem Bityutskiy union ubifs_key key; 12241e51764aSArtem Bityutskiy struct ubifs_dent_node *dent, *dent2; 1225278d9a24SZhihao Cheng int err, dlen1, dlen2, ilen, wlen, lnum, offs, len, orphan_added = 0; 12261e51764aSArtem Bityutskiy int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ; 12271e51764aSArtem Bityutskiy int last_reference = !!(new_inode && new_inode->i_nlink == 0); 12281e51764aSArtem Bityutskiy int move = (old_dir != new_dir); 1229278d9a24SZhihao Cheng struct ubifs_inode *new_ui, *whiteout_ui; 1230823838a4SSascha Hauer u8 hash_old_dir[UBIFS_HASH_ARR_SZ]; 1231823838a4SSascha Hauer u8 hash_new_dir[UBIFS_HASH_ARR_SZ]; 1232823838a4SSascha Hauer u8 hash_new_inode[UBIFS_HASH_ARR_SZ]; 1233278d9a24SZhihao Cheng u8 hash_whiteout_inode[UBIFS_HASH_ARR_SZ]; 1234823838a4SSascha Hauer u8 hash_dent1[UBIFS_HASH_ARR_SZ]; 1235823838a4SSascha Hauer u8 hash_dent2[UBIFS_HASH_ARR_SZ]; 12361e51764aSArtem Bityutskiy 12376eb61d58SRichard Weinberger ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0); 12386eb61d58SRichard Weinberger ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0); 12396eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex)); 12406eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex)); 12411e51764aSArtem Bityutskiy 1242f4f61d2cSRichard Weinberger dlen1 = UBIFS_DENT_NODE_SZ + fname_len(new_nm) + 1; 1243f4f61d2cSRichard Weinberger dlen2 = UBIFS_DENT_NODE_SZ + fname_len(old_nm) + 1; 12441e51764aSArtem Bityutskiy if (new_inode) { 12451e51764aSArtem Bityutskiy new_ui = ubifs_inode(new_inode); 12466eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&new_ui->ui_mutex)); 12471e51764aSArtem Bityutskiy ilen = UBIFS_INO_NODE_SZ; 12481e51764aSArtem Bityutskiy if (!last_reference) 12491e51764aSArtem Bityutskiy ilen += new_ui->data_len; 12501e51764aSArtem Bityutskiy } else 12511e51764aSArtem Bityutskiy ilen = 0; 12521e51764aSArtem Bityutskiy 1253278d9a24SZhihao Cheng if (whiteout) { 1254278d9a24SZhihao Cheng whiteout_ui = ubifs_inode(whiteout); 1255278d9a24SZhihao Cheng ubifs_assert(c, mutex_is_locked(&whiteout_ui->ui_mutex)); 1256278d9a24SZhihao Cheng ubifs_assert(c, whiteout->i_nlink == 1); 1257278d9a24SZhihao Cheng ubifs_assert(c, !whiteout_ui->dirty); 1258278d9a24SZhihao Cheng wlen = UBIFS_INO_NODE_SZ; 1259278d9a24SZhihao Cheng wlen += whiteout_ui->data_len; 1260278d9a24SZhihao Cheng } else 1261278d9a24SZhihao Cheng wlen = 0; 1262278d9a24SZhihao Cheng 12631e51764aSArtem Bityutskiy aligned_dlen1 = ALIGN(dlen1, 8); 12641e51764aSArtem Bityutskiy aligned_dlen2 = ALIGN(dlen2, 8); 1265278d9a24SZhihao Cheng len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + 1266278d9a24SZhihao Cheng ALIGN(wlen, 8) + ALIGN(plen, 8); 12671e039533SRichard Weinberger if (move) 12681e51764aSArtem Bityutskiy len += plen; 12696a98bc46SSascha Hauer 12706a98bc46SSascha Hauer len += ubifs_auth_node_sz(c); 12716a98bc46SSascha Hauer 12724acadda7SRichard Weinberger dent = kzalloc(len, GFP_NOFS); 12731e51764aSArtem Bityutskiy if (!dent) 12741e51764aSArtem Bityutskiy return -ENOMEM; 12751e51764aSArtem Bityutskiy 12761e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 12771e51764aSArtem Bityutskiy err = make_reservation(c, BASEHD, len); 12781e51764aSArtem Bityutskiy if (err) 12791e51764aSArtem Bityutskiy goto out_free; 12801e51764aSArtem Bityutskiy 12811e51764aSArtem Bityutskiy /* Make new dent */ 12821e51764aSArtem Bityutskiy dent->ch.node_type = UBIFS_DENT_NODE; 1283f4f61d2cSRichard Weinberger dent_key_init_flash(c, &dent->key, new_dir->i_ino, new_nm); 12841e51764aSArtem Bityutskiy dent->inum = cpu_to_le64(old_inode->i_ino); 12851e51764aSArtem Bityutskiy dent->type = get_dent_type(old_inode->i_mode); 1286f4f61d2cSRichard Weinberger dent->nlen = cpu_to_le16(fname_len(new_nm)); 1287f4f61d2cSRichard Weinberger memcpy(dent->name, fname_name(new_nm), fname_len(new_nm)); 1288f4f61d2cSRichard Weinberger dent->name[fname_len(new_nm)] = '\0'; 1289d63d61c1SRichard Weinberger set_dent_cookie(c, dent); 12901e51764aSArtem Bityutskiy zero_dent_node_unused(dent); 12911e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, dent, dlen1, 0); 1292823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dent, hash_dent1); 1293823838a4SSascha Hauer if (err) 1294823838a4SSascha Hauer goto out_release; 12951e51764aSArtem Bityutskiy 12961e51764aSArtem Bityutskiy dent2 = (void *)dent + aligned_dlen1; 12971e51764aSArtem Bityutskiy dent2->ch.node_type = UBIFS_DENT_NODE; 1298f4f61d2cSRichard Weinberger dent_key_init_flash(c, &dent2->key, old_dir->i_ino, old_nm); 12999e0a1fffSRichard Weinberger 13009e0a1fffSRichard Weinberger if (whiteout) { 13019e0a1fffSRichard Weinberger dent2->inum = cpu_to_le64(whiteout->i_ino); 13029e0a1fffSRichard Weinberger dent2->type = get_dent_type(whiteout->i_mode); 13039e0a1fffSRichard Weinberger } else { 13049e0a1fffSRichard Weinberger /* Make deletion dent */ 13051e51764aSArtem Bityutskiy dent2->inum = 0; 13061e51764aSArtem Bityutskiy dent2->type = DT_UNKNOWN; 13079e0a1fffSRichard Weinberger } 1308f4f61d2cSRichard Weinberger dent2->nlen = cpu_to_le16(fname_len(old_nm)); 1309f4f61d2cSRichard Weinberger memcpy(dent2->name, fname_name(old_nm), fname_len(old_nm)); 1310f4f61d2cSRichard Weinberger dent2->name[fname_len(old_nm)] = '\0'; 1311d63d61c1SRichard Weinberger set_dent_cookie(c, dent2); 13121e51764aSArtem Bityutskiy zero_dent_node_unused(dent2); 13131e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, dent2, dlen2, 0); 1314823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dent2, hash_dent2); 1315823838a4SSascha Hauer if (err) 1316823838a4SSascha Hauer goto out_release; 13171e51764aSArtem Bityutskiy 13181e51764aSArtem Bityutskiy p = (void *)dent2 + aligned_dlen2; 13191e51764aSArtem Bityutskiy if (new_inode) { 1320fd6c6b51SArtem Bityutskiy pack_inode(c, p, new_inode, 0); 1321823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_new_inode); 1322823838a4SSascha Hauer if (err) 1323823838a4SSascha Hauer goto out_release; 1324823838a4SSascha Hauer 13251e51764aSArtem Bityutskiy p += ALIGN(ilen, 8); 13261e51764aSArtem Bityutskiy } 13271e51764aSArtem Bityutskiy 1328278d9a24SZhihao Cheng if (whiteout) { 1329278d9a24SZhihao Cheng pack_inode(c, p, whiteout, 0); 1330278d9a24SZhihao Cheng err = ubifs_node_calc_hash(c, p, hash_whiteout_inode); 1331278d9a24SZhihao Cheng if (err) 1332278d9a24SZhihao Cheng goto out_release; 1333278d9a24SZhihao Cheng 1334278d9a24SZhihao Cheng p += ALIGN(wlen, 8); 1335278d9a24SZhihao Cheng } 1336278d9a24SZhihao Cheng 1337823838a4SSascha Hauer if (!move) { 1338fd6c6b51SArtem Bityutskiy pack_inode(c, p, old_dir, 1); 1339823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_old_dir); 1340823838a4SSascha Hauer if (err) 1341823838a4SSascha Hauer goto out_release; 1342823838a4SSascha Hauer } else { 1343fd6c6b51SArtem Bityutskiy pack_inode(c, p, old_dir, 0); 1344823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_old_dir); 1345823838a4SSascha Hauer if (err) 1346823838a4SSascha Hauer goto out_release; 1347823838a4SSascha Hauer 13481e51764aSArtem Bityutskiy p += ALIGN(plen, 8); 1349fd6c6b51SArtem Bityutskiy pack_inode(c, p, new_dir, 1); 1350823838a4SSascha Hauer err = ubifs_node_calc_hash(c, p, hash_new_dir); 1351823838a4SSascha Hauer if (err) 1352823838a4SSascha Hauer goto out_release; 13531e51764aSArtem Bityutskiy } 13541e51764aSArtem Bityutskiy 13551e51764aSArtem Bityutskiy if (last_reference) { 13561e51764aSArtem Bityutskiy err = ubifs_add_orphan(c, new_inode->i_ino); 13571e51764aSArtem Bityutskiy if (err) { 13581e51764aSArtem Bityutskiy release_head(c, BASEHD); 13591e51764aSArtem Bityutskiy goto out_finish; 13601e51764aSArtem Bityutskiy } 1361de94eb55SArtem Bityutskiy new_ui->del_cmtno = c->cmt_no; 1362094b6d12SZhihao Cheng orphan_added = 1; 13631e51764aSArtem Bityutskiy } 13641e51764aSArtem Bityutskiy 13651e51764aSArtem Bityutskiy err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); 13661e51764aSArtem Bityutskiy if (err) 13671e51764aSArtem Bityutskiy goto out_release; 13681e51764aSArtem Bityutskiy if (!sync) { 13691e51764aSArtem Bityutskiy struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; 13701e51764aSArtem Bityutskiy 13711e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, new_dir->i_ino); 13721e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, old_dir->i_ino); 13731e51764aSArtem Bityutskiy if (new_inode) 13741e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, 13751e51764aSArtem Bityutskiy new_inode->i_ino); 1376278d9a24SZhihao Cheng if (whiteout) 1377278d9a24SZhihao Cheng ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, 1378278d9a24SZhihao Cheng whiteout->i_ino); 13791e51764aSArtem Bityutskiy } 13801e51764aSArtem Bityutskiy release_head(c, BASEHD); 13811e51764aSArtem Bityutskiy 13826a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 13836a98bc46SSascha Hauer 1384f4f61d2cSRichard Weinberger dent_key_init(c, &key, new_dir->i_ino, new_nm); 1385823838a4SSascha Hauer err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, hash_dent1, new_nm); 13861e51764aSArtem Bityutskiy if (err) 13871e51764aSArtem Bityutskiy goto out_ro; 13881e51764aSArtem Bityutskiy 13899e0a1fffSRichard Weinberger offs += aligned_dlen1; 13909e0a1fffSRichard Weinberger if (whiteout) { 1391f4f61d2cSRichard Weinberger dent_key_init(c, &key, old_dir->i_ino, old_nm); 1392823838a4SSascha Hauer err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, hash_dent2, old_nm); 13939e0a1fffSRichard Weinberger if (err) 13949e0a1fffSRichard Weinberger goto out_ro; 13959e0a1fffSRichard Weinberger } else { 13961e51764aSArtem Bityutskiy err = ubifs_add_dirt(c, lnum, dlen2); 13971e51764aSArtem Bityutskiy if (err) 13981e51764aSArtem Bityutskiy goto out_ro; 13991e51764aSArtem Bityutskiy 1400f4f61d2cSRichard Weinberger dent_key_init(c, &key, old_dir->i_ino, old_nm); 1401f4f61d2cSRichard Weinberger err = ubifs_tnc_remove_nm(c, &key, old_nm); 14021e51764aSArtem Bityutskiy if (err) 14031e51764aSArtem Bityutskiy goto out_ro; 14049e0a1fffSRichard Weinberger } 14051e51764aSArtem Bityutskiy 14069e0a1fffSRichard Weinberger offs += aligned_dlen2; 14071e51764aSArtem Bityutskiy if (new_inode) { 14081e51764aSArtem Bityutskiy ino_key_init(c, &key, new_inode->i_ino); 1409823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, ilen, hash_new_inode); 14101e51764aSArtem Bityutskiy if (err) 14111e51764aSArtem Bityutskiy goto out_ro; 14121e51764aSArtem Bityutskiy offs += ALIGN(ilen, 8); 14131e51764aSArtem Bityutskiy } 14141e51764aSArtem Bityutskiy 1415278d9a24SZhihao Cheng if (whiteout) { 1416278d9a24SZhihao Cheng ino_key_init(c, &key, whiteout->i_ino); 1417278d9a24SZhihao Cheng err = ubifs_tnc_add(c, &key, lnum, offs, wlen, 1418278d9a24SZhihao Cheng hash_whiteout_inode); 1419278d9a24SZhihao Cheng if (err) 1420278d9a24SZhihao Cheng goto out_ro; 1421278d9a24SZhihao Cheng offs += ALIGN(wlen, 8); 1422278d9a24SZhihao Cheng } 1423278d9a24SZhihao Cheng 14241e51764aSArtem Bityutskiy ino_key_init(c, &key, old_dir->i_ino); 1425823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_old_dir); 14261e51764aSArtem Bityutskiy if (err) 14271e51764aSArtem Bityutskiy goto out_ro; 14281e51764aSArtem Bityutskiy 14291e039533SRichard Weinberger if (move) { 14301e51764aSArtem Bityutskiy offs += ALIGN(plen, 8); 14311e51764aSArtem Bityutskiy ino_key_init(c, &key, new_dir->i_ino); 1432823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, plen, hash_new_dir); 14331e51764aSArtem Bityutskiy if (err) 14341e51764aSArtem Bityutskiy goto out_ro; 14351e51764aSArtem Bityutskiy } 14361e51764aSArtem Bityutskiy 14371e51764aSArtem Bityutskiy finish_reservation(c); 14381e51764aSArtem Bityutskiy if (new_inode) { 14391e51764aSArtem Bityutskiy mark_inode_clean(c, new_ui); 14401e51764aSArtem Bityutskiy spin_lock(&new_ui->ui_lock); 14411e51764aSArtem Bityutskiy new_ui->synced_i_size = new_ui->ui_size; 14421e51764aSArtem Bityutskiy spin_unlock(&new_ui->ui_lock); 14431e51764aSArtem Bityutskiy } 1444278d9a24SZhihao Cheng /* 1445278d9a24SZhihao Cheng * No need to mark whiteout inode clean. 1446278d9a24SZhihao Cheng * Whiteout doesn't have non-zero size, no need to update 1447278d9a24SZhihao Cheng * synced_i_size for whiteout_ui. 1448278d9a24SZhihao Cheng */ 14491e51764aSArtem Bityutskiy mark_inode_clean(c, ubifs_inode(old_dir)); 14501e51764aSArtem Bityutskiy if (move) 14511e51764aSArtem Bityutskiy mark_inode_clean(c, ubifs_inode(new_dir)); 14521e51764aSArtem Bityutskiy kfree(dent); 14531e51764aSArtem Bityutskiy return 0; 14541e51764aSArtem Bityutskiy 14551e51764aSArtem Bityutskiy out_release: 14561e51764aSArtem Bityutskiy release_head(c, BASEHD); 14571e51764aSArtem Bityutskiy out_ro: 14581e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 1459094b6d12SZhihao Cheng if (orphan_added) 14601e51764aSArtem Bityutskiy ubifs_delete_orphan(c, new_inode->i_ino); 14611e51764aSArtem Bityutskiy out_finish: 14621e51764aSArtem Bityutskiy finish_reservation(c); 14631e51764aSArtem Bityutskiy out_free: 14641e51764aSArtem Bityutskiy kfree(dent); 14651e51764aSArtem Bityutskiy return err; 14661e51764aSArtem Bityutskiy } 14671e51764aSArtem Bityutskiy 14681e51764aSArtem Bityutskiy /** 14697799953bSRichard Weinberger * truncate_data_node - re-compress/encrypt a truncated data node. 14707799953bSRichard Weinberger * @c: UBIFS file-system description object 147107c32de4SZheng Yongjun * @inode: inode which refers to the data node 14727799953bSRichard Weinberger * @block: data block number 14731e51764aSArtem Bityutskiy * @dn: data node to re-compress 14741e51764aSArtem Bityutskiy * @new_len: new length 14751e51764aSArtem Bityutskiy * 14761e51764aSArtem Bityutskiy * This function is used when an inode is truncated and the last data node of 14777799953bSRichard Weinberger * the inode has to be re-compressed/encrypted and re-written. 14781e51764aSArtem Bityutskiy */ 14797799953bSRichard Weinberger static int truncate_data_node(const struct ubifs_info *c, const struct inode *inode, 14807799953bSRichard Weinberger unsigned int block, struct ubifs_data_node *dn, 14817799953bSRichard Weinberger int *new_len) 14821e51764aSArtem Bityutskiy { 14831e51764aSArtem Bityutskiy void *buf; 148408acbdd6SRichard Weinberger int err, dlen, compr_type, out_len, old_dlen; 14851e51764aSArtem Bityutskiy 14861e51764aSArtem Bityutskiy out_len = le32_to_cpu(dn->size); 1487a3d21828SRichard Weinberger buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS); 14881e51764aSArtem Bityutskiy if (!buf) 14891e51764aSArtem Bityutskiy return -ENOMEM; 14901e51764aSArtem Bityutskiy 14917799953bSRichard Weinberger dlen = old_dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; 14921e51764aSArtem Bityutskiy compr_type = le16_to_cpu(dn->compr_type); 14937799953bSRichard Weinberger 149450d9fad7SEric Biggers if (IS_ENCRYPTED(inode)) { 14957799953bSRichard Weinberger err = ubifs_decrypt(inode, dn, &dlen, block); 14967799953bSRichard Weinberger if (err) 14977799953bSRichard Weinberger goto out; 14987799953bSRichard Weinberger } 14997799953bSRichard Weinberger 150059a74990SDavid Oberhollenzer if (compr_type == UBIFS_COMPR_NONE) { 150159a74990SDavid Oberhollenzer out_len = *new_len; 150259a74990SDavid Oberhollenzer } else { 15037799953bSRichard Weinberger err = ubifs_decompress(c, &dn->data, dlen, buf, &out_len, compr_type); 15041e51764aSArtem Bityutskiy if (err) 15051e51764aSArtem Bityutskiy goto out; 15061e51764aSArtem Bityutskiy 1507235c362bSSheng Yong ubifs_compress(c, buf, *new_len, &dn->data, &out_len, &compr_type); 15087799953bSRichard Weinberger } 15097799953bSRichard Weinberger 151050d9fad7SEric Biggers if (IS_ENCRYPTED(inode)) { 15117799953bSRichard Weinberger err = ubifs_encrypt(inode, dn, out_len, &old_dlen, block); 15127799953bSRichard Weinberger if (err) 15137799953bSRichard Weinberger goto out; 15147799953bSRichard Weinberger 15157799953bSRichard Weinberger out_len = old_dlen; 15167799953bSRichard Weinberger } else { 15177799953bSRichard Weinberger dn->compr_size = 0; 15187799953bSRichard Weinberger } 15197799953bSRichard Weinberger 15206eb61d58SRichard Weinberger ubifs_assert(c, out_len <= UBIFS_BLOCK_SIZE); 15211e51764aSArtem Bityutskiy dn->compr_type = cpu_to_le16(compr_type); 15221e51764aSArtem Bityutskiy dn->size = cpu_to_le32(*new_len); 15231e51764aSArtem Bityutskiy *new_len = UBIFS_DATA_NODE_SZ + out_len; 1524e8f19746SColin Ian King err = 0; 15251e51764aSArtem Bityutskiy out: 15261e51764aSArtem Bityutskiy kfree(buf); 15271e51764aSArtem Bityutskiy return err; 15281e51764aSArtem Bityutskiy } 15291e51764aSArtem Bityutskiy 15301e51764aSArtem Bityutskiy /** 15311e51764aSArtem Bityutskiy * ubifs_jnl_truncate - update the journal for a truncation. 15321e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 15331e51764aSArtem Bityutskiy * @inode: inode to truncate 15341e51764aSArtem Bityutskiy * @old_size: old size 15351e51764aSArtem Bityutskiy * @new_size: new size 15361e51764aSArtem Bityutskiy * 15371e51764aSArtem Bityutskiy * When the size of a file decreases due to truncation, a truncation node is 15381e51764aSArtem Bityutskiy * written, the journal tree is updated, and the last data block is re-written 15391e51764aSArtem Bityutskiy * if it has been affected. The inode is also updated in order to synchronize 15401e51764aSArtem Bityutskiy * the new inode size. 15411e51764aSArtem Bityutskiy * 15421e51764aSArtem Bityutskiy * This function marks the inode as clean and returns zero on success. In case 15431e51764aSArtem Bityutskiy * of failure, a negative error code is returned. 15441e51764aSArtem Bityutskiy */ 15451e51764aSArtem Bityutskiy int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, 15461e51764aSArtem Bityutskiy loff_t old_size, loff_t new_size) 15471e51764aSArtem Bityutskiy { 15481e51764aSArtem Bityutskiy union ubifs_key key, to_key; 15491e51764aSArtem Bityutskiy struct ubifs_ino_node *ino; 15501e51764aSArtem Bityutskiy struct ubifs_trun_node *trun; 15513f649ab7SKees Cook struct ubifs_data_node *dn; 15521e51764aSArtem Bityutskiy int err, dlen, len, lnum, offs, bit, sz, sync = IS_SYNC(inode); 15531e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode); 15541e51764aSArtem Bityutskiy ino_t inum = inode->i_ino; 15551e51764aSArtem Bityutskiy unsigned int blk; 1556823838a4SSascha Hauer u8 hash_ino[UBIFS_HASH_ARR_SZ]; 1557823838a4SSascha Hauer u8 hash_dn[UBIFS_HASH_ARR_SZ]; 15581e51764aSArtem Bityutskiy 1559e84461adSArtem Bityutskiy dbg_jnl("ino %lu, size %lld -> %lld", 1560e84461adSArtem Bityutskiy (unsigned long)inum, old_size, new_size); 15616eb61d58SRichard Weinberger ubifs_assert(c, !ui->data_len); 15626eb61d58SRichard Weinberger ubifs_assert(c, S_ISREG(inode->i_mode)); 15636eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&ui->ui_mutex)); 15641e51764aSArtem Bityutskiy 15651e51764aSArtem Bityutskiy sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + 15661e51764aSArtem Bityutskiy UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; 15676a98bc46SSascha Hauer 15686a98bc46SSascha Hauer sz += ubifs_auth_node_sz(c); 15696a98bc46SSascha Hauer 15701e51764aSArtem Bityutskiy ino = kmalloc(sz, GFP_NOFS); 15711e51764aSArtem Bityutskiy if (!ino) 15721e51764aSArtem Bityutskiy return -ENOMEM; 15731e51764aSArtem Bityutskiy 15741e51764aSArtem Bityutskiy trun = (void *)ino + UBIFS_INO_NODE_SZ; 15751e51764aSArtem Bityutskiy trun->ch.node_type = UBIFS_TRUN_NODE; 15761e51764aSArtem Bityutskiy trun->inum = cpu_to_le32(inum); 15771e51764aSArtem Bityutskiy trun->old_size = cpu_to_le64(old_size); 15781e51764aSArtem Bityutskiy trun->new_size = cpu_to_le64(new_size); 15791e51764aSArtem Bityutskiy zero_trun_node_unused(trun); 15801e51764aSArtem Bityutskiy 15811e51764aSArtem Bityutskiy dlen = new_size & (UBIFS_BLOCK_SIZE - 1); 15821e51764aSArtem Bityutskiy if (dlen) { 15831e51764aSArtem Bityutskiy /* Get last data block so it can be truncated */ 15841e51764aSArtem Bityutskiy dn = (void *)trun + UBIFS_TRUN_NODE_SZ; 15851e51764aSArtem Bityutskiy blk = new_size >> UBIFS_BLOCK_SHIFT; 15861e51764aSArtem Bityutskiy data_key_init(c, &key, inum, blk); 1587515315a1SArtem Bityutskiy dbg_jnlk(&key, "last block key "); 15881e51764aSArtem Bityutskiy err = ubifs_tnc_lookup(c, &key, dn); 15891e51764aSArtem Bityutskiy if (err == -ENOENT) 15901e51764aSArtem Bityutskiy dlen = 0; /* Not found (so it is a hole) */ 15911e51764aSArtem Bityutskiy else if (err) 15921e51764aSArtem Bityutskiy goto out_free; 15931e51764aSArtem Bityutskiy else { 159495a22d20SRichard Weinberger int dn_len = le32_to_cpu(dn->size); 159595a22d20SRichard Weinberger 159695a22d20SRichard Weinberger if (dn_len <= 0 || dn_len > UBIFS_BLOCK_SIZE) { 159795a22d20SRichard Weinberger ubifs_err(c, "bad data node (block %u, inode %lu)", 159895a22d20SRichard Weinberger blk, inode->i_ino); 1599a33e30a0SZhihao Cheng ubifs_dump_node(c, dn, sz - UBIFS_INO_NODE_SZ - 1600a33e30a0SZhihao Cheng UBIFS_TRUN_NODE_SZ); 160195a22d20SRichard Weinberger goto out_free; 160295a22d20SRichard Weinberger } 160395a22d20SRichard Weinberger 160495a22d20SRichard Weinberger if (dn_len <= dlen) 16051e51764aSArtem Bityutskiy dlen = 0; /* Nothing to do */ 16061e51764aSArtem Bityutskiy else { 16077799953bSRichard Weinberger err = truncate_data_node(c, inode, blk, dn, &dlen); 16081e51764aSArtem Bityutskiy if (err) 16091e51764aSArtem Bityutskiy goto out_free; 16101e51764aSArtem Bityutskiy } 16111e51764aSArtem Bityutskiy } 16121e51764aSArtem Bityutskiy } 16131e51764aSArtem Bityutskiy 16141e51764aSArtem Bityutskiy /* Must make reservation before allocating sequence numbers */ 16151e51764aSArtem Bityutskiy len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; 16166a98bc46SSascha Hauer 16176a98bc46SSascha Hauer if (ubifs_authenticated(c)) 16186a98bc46SSascha Hauer len += ALIGN(dlen, 8) + ubifs_auth_node_sz(c); 16196a98bc46SSascha Hauer else 16201e51764aSArtem Bityutskiy len += dlen; 16216a98bc46SSascha Hauer 16221e51764aSArtem Bityutskiy err = make_reservation(c, BASEHD, len); 16231e51764aSArtem Bityutskiy if (err) 16241e51764aSArtem Bityutskiy goto out_free; 16251e51764aSArtem Bityutskiy 1626fd6c6b51SArtem Bityutskiy pack_inode(c, ino, inode, 0); 1627823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash_ino); 1628823838a4SSascha Hauer if (err) 1629823838a4SSascha Hauer goto out_release; 1630823838a4SSascha Hauer 16311e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); 1632823838a4SSascha Hauer if (dlen) { 16331e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, dn, dlen, 1); 1634823838a4SSascha Hauer err = ubifs_node_calc_hash(c, dn, hash_dn); 1635823838a4SSascha Hauer if (err) 1636823838a4SSascha Hauer goto out_release; 1637823838a4SSascha Hauer } 16381e51764aSArtem Bityutskiy 16391e51764aSArtem Bityutskiy err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); 16401e51764aSArtem Bityutskiy if (err) 16411e51764aSArtem Bityutskiy goto out_release; 16421e51764aSArtem Bityutskiy if (!sync) 16431e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); 16441e51764aSArtem Bityutskiy release_head(c, BASEHD); 16451e51764aSArtem Bityutskiy 16466a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 16476a98bc46SSascha Hauer 16481e51764aSArtem Bityutskiy if (dlen) { 16491e51764aSArtem Bityutskiy sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; 1650823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, sz, dlen, hash_dn); 16511e51764aSArtem Bityutskiy if (err) 16521e51764aSArtem Bityutskiy goto out_ro; 16531e51764aSArtem Bityutskiy } 16541e51764aSArtem Bityutskiy 16551e51764aSArtem Bityutskiy ino_key_init(c, &key, inum); 1656823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ, hash_ino); 16571e51764aSArtem Bityutskiy if (err) 16581e51764aSArtem Bityutskiy goto out_ro; 16591e51764aSArtem Bityutskiy 16601e51764aSArtem Bityutskiy err = ubifs_add_dirt(c, lnum, UBIFS_TRUN_NODE_SZ); 16611e51764aSArtem Bityutskiy if (err) 16621e51764aSArtem Bityutskiy goto out_ro; 16631e51764aSArtem Bityutskiy 16641e51764aSArtem Bityutskiy bit = new_size & (UBIFS_BLOCK_SIZE - 1); 16651e51764aSArtem Bityutskiy blk = (new_size >> UBIFS_BLOCK_SHIFT) + (bit ? 1 : 0); 16661e51764aSArtem Bityutskiy data_key_init(c, &key, inum, blk); 16671e51764aSArtem Bityutskiy 16681e51764aSArtem Bityutskiy bit = old_size & (UBIFS_BLOCK_SIZE - 1); 16691e51764aSArtem Bityutskiy blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0 : 1); 16701e51764aSArtem Bityutskiy data_key_init(c, &to_key, inum, blk); 16711e51764aSArtem Bityutskiy 16721e51764aSArtem Bityutskiy err = ubifs_tnc_remove_range(c, &key, &to_key); 16731e51764aSArtem Bityutskiy if (err) 16741e51764aSArtem Bityutskiy goto out_ro; 16751e51764aSArtem Bityutskiy 16761e51764aSArtem Bityutskiy finish_reservation(c); 16771e51764aSArtem Bityutskiy spin_lock(&ui->ui_lock); 16781e51764aSArtem Bityutskiy ui->synced_i_size = ui->ui_size; 16791e51764aSArtem Bityutskiy spin_unlock(&ui->ui_lock); 16801e51764aSArtem Bityutskiy mark_inode_clean(c, ui); 16811e51764aSArtem Bityutskiy kfree(ino); 16821e51764aSArtem Bityutskiy return 0; 16831e51764aSArtem Bityutskiy 16841e51764aSArtem Bityutskiy out_release: 16851e51764aSArtem Bityutskiy release_head(c, BASEHD); 16861e51764aSArtem Bityutskiy out_ro: 16871e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 16881e51764aSArtem Bityutskiy finish_reservation(c); 16891e51764aSArtem Bityutskiy out_free: 16901e51764aSArtem Bityutskiy kfree(ino); 16911e51764aSArtem Bityutskiy return err; 16921e51764aSArtem Bityutskiy } 16931e51764aSArtem Bityutskiy 16941e51764aSArtem Bityutskiy 16951e51764aSArtem Bityutskiy /** 16961e51764aSArtem Bityutskiy * ubifs_jnl_delete_xattr - delete an extended attribute. 16971e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 16981e51764aSArtem Bityutskiy * @host: host inode 16991e51764aSArtem Bityutskiy * @inode: extended attribute inode 17001e51764aSArtem Bityutskiy * @nm: extended attribute entry name 17011e51764aSArtem Bityutskiy * 17021e51764aSArtem Bityutskiy * This function delete an extended attribute which is very similar to 17031e51764aSArtem Bityutskiy * un-linking regular files - it writes a deletion xentry, a deletion inode and 17041e51764aSArtem Bityutskiy * updates the target inode. Returns zero in case of success and a negative 17051e51764aSArtem Bityutskiy * error code in case of failure. 17061e51764aSArtem Bityutskiy */ 17071e51764aSArtem Bityutskiy int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, 1708f4f61d2cSRichard Weinberger const struct inode *inode, 1709f4f61d2cSRichard Weinberger const struct fscrypt_name *nm) 17101e51764aSArtem Bityutskiy { 17116a98bc46SSascha Hauer int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen, write_len; 17121e51764aSArtem Bityutskiy struct ubifs_dent_node *xent; 17131e51764aSArtem Bityutskiy struct ubifs_ino_node *ino; 17141e51764aSArtem Bityutskiy union ubifs_key xent_key, key1, key2; 17151e51764aSArtem Bityutskiy int sync = IS_DIRSYNC(host); 17161e51764aSArtem Bityutskiy struct ubifs_inode *host_ui = ubifs_inode(host); 1717823838a4SSascha Hauer u8 hash[UBIFS_HASH_ARR_SZ]; 17181e51764aSArtem Bityutskiy 17196eb61d58SRichard Weinberger ubifs_assert(c, inode->i_nlink == 0); 17206eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); 17211e51764aSArtem Bityutskiy 17221e51764aSArtem Bityutskiy /* 17231e51764aSArtem Bityutskiy * Since we are deleting the inode, we do not bother to attach any data 17241e51764aSArtem Bityutskiy * to it and assume its length is %UBIFS_INO_NODE_SZ. 17251e51764aSArtem Bityutskiy */ 1726f4f61d2cSRichard Weinberger xlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1; 17271e51764aSArtem Bityutskiy aligned_xlen = ALIGN(xlen, 8); 17281e51764aSArtem Bityutskiy hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; 17291e51764aSArtem Bityutskiy len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); 17301e51764aSArtem Bityutskiy 17316a98bc46SSascha Hauer write_len = len + ubifs_auth_node_sz(c); 17326a98bc46SSascha Hauer 17336a98bc46SSascha Hauer xent = kzalloc(write_len, GFP_NOFS); 17341e51764aSArtem Bityutskiy if (!xent) 17351e51764aSArtem Bityutskiy return -ENOMEM; 17361e51764aSArtem Bityutskiy 17371e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 17386a98bc46SSascha Hauer err = make_reservation(c, BASEHD, write_len); 17391e51764aSArtem Bityutskiy if (err) { 17401e51764aSArtem Bityutskiy kfree(xent); 17411e51764aSArtem Bityutskiy return err; 17421e51764aSArtem Bityutskiy } 17431e51764aSArtem Bityutskiy 17441e51764aSArtem Bityutskiy xent->ch.node_type = UBIFS_XENT_NODE; 17451e51764aSArtem Bityutskiy xent_key_init(c, &xent_key, host->i_ino, nm); 17461e51764aSArtem Bityutskiy key_write(c, &xent_key, xent->key); 17471e51764aSArtem Bityutskiy xent->inum = 0; 17481e51764aSArtem Bityutskiy xent->type = get_dent_type(inode->i_mode); 1749f4f61d2cSRichard Weinberger xent->nlen = cpu_to_le16(fname_len(nm)); 1750f4f61d2cSRichard Weinberger memcpy(xent->name, fname_name(nm), fname_len(nm)); 1751f4f61d2cSRichard Weinberger xent->name[fname_len(nm)] = '\0'; 17521e51764aSArtem Bityutskiy zero_dent_node_unused(xent); 17531e51764aSArtem Bityutskiy ubifs_prep_grp_node(c, xent, xlen, 0); 17541e51764aSArtem Bityutskiy 17551e51764aSArtem Bityutskiy ino = (void *)xent + aligned_xlen; 1756fd6c6b51SArtem Bityutskiy pack_inode(c, ino, inode, 0); 17571e51764aSArtem Bityutskiy ino = (void *)ino + UBIFS_INO_NODE_SZ; 1758fd6c6b51SArtem Bityutskiy pack_inode(c, ino, host, 1); 1759823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash); 1760823838a4SSascha Hauer if (err) 1761823838a4SSascha Hauer goto out_release; 17621e51764aSArtem Bityutskiy 17636a98bc46SSascha Hauer err = write_head(c, BASEHD, xent, write_len, &lnum, &xent_offs, sync); 17641e51764aSArtem Bityutskiy if (!sync && !err) 17651e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); 17661e51764aSArtem Bityutskiy release_head(c, BASEHD); 17676a98bc46SSascha Hauer 17686a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 17691e51764aSArtem Bityutskiy kfree(xent); 17701e51764aSArtem Bityutskiy if (err) 17711e51764aSArtem Bityutskiy goto out_ro; 17721e51764aSArtem Bityutskiy 17731e51764aSArtem Bityutskiy /* Remove the extended attribute entry from TNC */ 17741e51764aSArtem Bityutskiy err = ubifs_tnc_remove_nm(c, &xent_key, nm); 17751e51764aSArtem Bityutskiy if (err) 17761e51764aSArtem Bityutskiy goto out_ro; 17771e51764aSArtem Bityutskiy err = ubifs_add_dirt(c, lnum, xlen); 17781e51764aSArtem Bityutskiy if (err) 17791e51764aSArtem Bityutskiy goto out_ro; 17801e51764aSArtem Bityutskiy 17811e51764aSArtem Bityutskiy /* 17821e51764aSArtem Bityutskiy * Remove all nodes belonging to the extended attribute inode from TNC. 17831e51764aSArtem Bityutskiy * Well, there actually must be only one node - the inode itself. 17841e51764aSArtem Bityutskiy */ 17851e51764aSArtem Bityutskiy lowest_ino_key(c, &key1, inode->i_ino); 17861e51764aSArtem Bityutskiy highest_ino_key(c, &key2, inode->i_ino); 17871e51764aSArtem Bityutskiy err = ubifs_tnc_remove_range(c, &key1, &key2); 17881e51764aSArtem Bityutskiy if (err) 17891e51764aSArtem Bityutskiy goto out_ro; 17901e51764aSArtem Bityutskiy err = ubifs_add_dirt(c, lnum, UBIFS_INO_NODE_SZ); 17911e51764aSArtem Bityutskiy if (err) 17921e51764aSArtem Bityutskiy goto out_ro; 17931e51764aSArtem Bityutskiy 17941e51764aSArtem Bityutskiy /* And update TNC with the new host inode position */ 17951e51764aSArtem Bityutskiy ino_key_init(c, &key1, host->i_ino); 1796823838a4SSascha Hauer err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen, hash); 17971e51764aSArtem Bityutskiy if (err) 17981e51764aSArtem Bityutskiy goto out_ro; 17991e51764aSArtem Bityutskiy 18001e51764aSArtem Bityutskiy finish_reservation(c); 18011e51764aSArtem Bityutskiy spin_lock(&host_ui->ui_lock); 18021e51764aSArtem Bityutskiy host_ui->synced_i_size = host_ui->ui_size; 18031e51764aSArtem Bityutskiy spin_unlock(&host_ui->ui_lock); 18041e51764aSArtem Bityutskiy mark_inode_clean(c, host_ui); 18051e51764aSArtem Bityutskiy return 0; 18061e51764aSArtem Bityutskiy 1807823838a4SSascha Hauer out_release: 1808823838a4SSascha Hauer kfree(xent); 1809823838a4SSascha Hauer release_head(c, BASEHD); 18101e51764aSArtem Bityutskiy out_ro: 18111e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 18121e51764aSArtem Bityutskiy finish_reservation(c); 18131e51764aSArtem Bityutskiy return err; 18141e51764aSArtem Bityutskiy } 18151e51764aSArtem Bityutskiy 18161e51764aSArtem Bityutskiy /** 18171e51764aSArtem Bityutskiy * ubifs_jnl_change_xattr - change an extended attribute. 18181e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 18191e51764aSArtem Bityutskiy * @inode: extended attribute inode 18201e51764aSArtem Bityutskiy * @host: host inode 18211e51764aSArtem Bityutskiy * 18221e51764aSArtem Bityutskiy * This function writes the updated version of an extended attribute inode and 18237d4e9ccbSArtem Bityutskiy * the host inode to the journal (to the base head). The host inode is written 18241e51764aSArtem Bityutskiy * after the extended attribute inode in order to guarantee that the extended 18251e51764aSArtem Bityutskiy * attribute will be flushed when the inode is synchronized by 'fsync()' and 18261e51764aSArtem Bityutskiy * consequently, the write-buffer is synchronized. This function returns zero 18271e51764aSArtem Bityutskiy * in case of success and a negative error code in case of failure. 18281e51764aSArtem Bityutskiy */ 18291e51764aSArtem Bityutskiy int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, 18301e51764aSArtem Bityutskiy const struct inode *host) 18311e51764aSArtem Bityutskiy { 18321e51764aSArtem Bityutskiy int err, len1, len2, aligned_len, aligned_len1, lnum, offs; 1833c78c7e35SArtem Bityutskiy struct ubifs_inode *host_ui = ubifs_inode(host); 18341e51764aSArtem Bityutskiy struct ubifs_ino_node *ino; 18351e51764aSArtem Bityutskiy union ubifs_key key; 18361e51764aSArtem Bityutskiy int sync = IS_DIRSYNC(host); 1837823838a4SSascha Hauer u8 hash_host[UBIFS_HASH_ARR_SZ]; 1838823838a4SSascha Hauer u8 hash[UBIFS_HASH_ARR_SZ]; 18391e51764aSArtem Bityutskiy 18401e51764aSArtem Bityutskiy dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); 18416eb61d58SRichard Weinberger ubifs_assert(c, inode->i_nlink > 0); 18426eb61d58SRichard Weinberger ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex)); 18431e51764aSArtem Bityutskiy 18441e51764aSArtem Bityutskiy len1 = UBIFS_INO_NODE_SZ + host_ui->data_len; 18451e51764aSArtem Bityutskiy len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len; 18461e51764aSArtem Bityutskiy aligned_len1 = ALIGN(len1, 8); 18471e51764aSArtem Bityutskiy aligned_len = aligned_len1 + ALIGN(len2, 8); 18481e51764aSArtem Bityutskiy 18496a98bc46SSascha Hauer aligned_len += ubifs_auth_node_sz(c); 18506a98bc46SSascha Hauer 18514acadda7SRichard Weinberger ino = kzalloc(aligned_len, GFP_NOFS); 18521e51764aSArtem Bityutskiy if (!ino) 18531e51764aSArtem Bityutskiy return -ENOMEM; 18541e51764aSArtem Bityutskiy 18551e51764aSArtem Bityutskiy /* Make reservation before allocating sequence numbers */ 18561e51764aSArtem Bityutskiy err = make_reservation(c, BASEHD, aligned_len); 18571e51764aSArtem Bityutskiy if (err) 18581e51764aSArtem Bityutskiy goto out_free; 18591e51764aSArtem Bityutskiy 1860fd6c6b51SArtem Bityutskiy pack_inode(c, ino, host, 0); 1861823838a4SSascha Hauer err = ubifs_node_calc_hash(c, ino, hash_host); 1862823838a4SSascha Hauer if (err) 1863823838a4SSascha Hauer goto out_release; 1864fd6c6b51SArtem Bityutskiy pack_inode(c, (void *)ino + aligned_len1, inode, 1); 1865823838a4SSascha Hauer err = ubifs_node_calc_hash(c, (void *)ino + aligned_len1, hash); 1866823838a4SSascha Hauer if (err) 1867823838a4SSascha Hauer goto out_release; 18681e51764aSArtem Bityutskiy 18691e51764aSArtem Bityutskiy err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); 18701e51764aSArtem Bityutskiy if (!sync && !err) { 18711e51764aSArtem Bityutskiy struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; 18721e51764aSArtem Bityutskiy 18731e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, host->i_ino); 18741e51764aSArtem Bityutskiy ubifs_wbuf_add_ino_nolock(wbuf, inode->i_ino); 18751e51764aSArtem Bityutskiy } 18761e51764aSArtem Bityutskiy release_head(c, BASEHD); 18771e51764aSArtem Bityutskiy if (err) 18781e51764aSArtem Bityutskiy goto out_ro; 18791e51764aSArtem Bityutskiy 18806a98bc46SSascha Hauer ubifs_add_auth_dirt(c, lnum); 18816a98bc46SSascha Hauer 18821e51764aSArtem Bityutskiy ino_key_init(c, &key, host->i_ino); 1883823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs, len1, hash_host); 18841e51764aSArtem Bityutskiy if (err) 18851e51764aSArtem Bityutskiy goto out_ro; 18861e51764aSArtem Bityutskiy 18871e51764aSArtem Bityutskiy ino_key_init(c, &key, inode->i_ino); 1888823838a4SSascha Hauer err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2, hash); 18891e51764aSArtem Bityutskiy if (err) 18901e51764aSArtem Bityutskiy goto out_ro; 18911e51764aSArtem Bityutskiy 18921e51764aSArtem Bityutskiy finish_reservation(c); 18931e51764aSArtem Bityutskiy spin_lock(&host_ui->ui_lock); 18941e51764aSArtem Bityutskiy host_ui->synced_i_size = host_ui->ui_size; 18951e51764aSArtem Bityutskiy spin_unlock(&host_ui->ui_lock); 18961e51764aSArtem Bityutskiy mark_inode_clean(c, host_ui); 18971e51764aSArtem Bityutskiy kfree(ino); 18981e51764aSArtem Bityutskiy return 0; 18991e51764aSArtem Bityutskiy 1900823838a4SSascha Hauer out_release: 1901823838a4SSascha Hauer release_head(c, BASEHD); 19021e51764aSArtem Bityutskiy out_ro: 19031e51764aSArtem Bityutskiy ubifs_ro_mode(c, err); 19041e51764aSArtem Bityutskiy finish_reservation(c); 19051e51764aSArtem Bityutskiy out_free: 19061e51764aSArtem Bityutskiy kfree(ino); 19071e51764aSArtem Bityutskiy return err; 19081e51764aSArtem Bityutskiy } 19091e51764aSArtem Bityutskiy 1910