11e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* 21e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This file is part of UBIFS. 31e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 41e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation. 51e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 61e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This program is free software; you can redistribute it and/or modify it 71e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * under the terms of the GNU General Public License version 2 as published by 81e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the Free Software Foundation. 91e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This program is distributed in the hope that it will be useful, but WITHOUT 111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * more details. 141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * You should have received a copy of the GNU General Public License along with 161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * this program; if not, write to the Free Software Foundation, Inc., 51 171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Authors: Adrian Hunter 201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Artem Bityutskiy (Битюцкий Артём) 211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* 241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This file implements TNC (Tree Node Cache) which caches indexing nodes of 251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the UBIFS B-tree. 261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * At the moment the locking rules of the TNC tree are quite simple and 281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * straightforward. We just have a mutex and lock it when we traverse the 291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tree. If a znode is not in memory, we read it from flash while still having 301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the mutex locked. 311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#include <linux/crc32.h> 345a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#include "ubifs.h" 361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* 381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions. 391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @NAME_LESS: name corresponding to the first argument is less than second 401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @NAME_MATCHES: names match 411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @NAME_GREATER: name corresponding to the second argument is greater than 421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * first 431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @NOT_ON_MEDIA: node referred by zbranch does not exist on the media 441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * These constants were introduce to improve readability. 461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyenum { 481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy NAME_LESS = 0, 491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy NAME_MATCHES = 1, 501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy NAME_GREATER = 2, 511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy NOT_ON_MEDIA = 3, 521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}; 531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * insert_old_idx - record an index node obsoleted since the last commit start. 561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of obsoleted index node 581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset of obsoleted index node 591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success, and a negative error code on failure. 611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * For recovery, there must always be a complete intact version of the index on 631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * flash at all times. That is called the "old index". It is the index as at the 641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * time of the last successful commit. Many of the index nodes in the old index 651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * may be dirty, but they must not be erased until the next successful commit 661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * (at which point that index becomes the old index). 671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * That means that the garbage collection and the in-the-gaps method of 691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * committing must be able to determine if an index node is in the old index. 701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Most of the old index nodes can be found by looking up the TNC using the 711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'lookup_znode()' function. However, some of the old index nodes may have 721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * been deleted from the current index or may have been changed so much that 731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * they cannot be easily found. In those cases, an entry is added to an RB-tree. 741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * That is what this function does. The RB-tree is ordered by LEB number and 751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * offset because they uniquely identify the old index node. 761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int insert_old_idx(struct ubifs_info *c, int lnum, int offs) 781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_old_idx *old_idx, *o; 801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct rb_node **p, *parent = NULL; 811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); 831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(!old_idx)) 841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOMEM; 851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy old_idx->lnum = lnum; 861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy old_idx->offs = offs; 871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy p = &c->old_idx.rb_node; 891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (*p) { 901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy parent = *p; 911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o = rb_entry(parent, struct ubifs_old_idx, rb); 921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (lnum < o->lnum) 931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy p = &(*p)->rb_left; 941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (lnum > o->lnum) 951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy p = &(*p)->rb_right; 961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (offs < o->offs) 971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy p = &(*p)->rb_left; 981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (offs > o->offs) 991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy p = &(*p)->rb_right; 1001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else { 1011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_err("old idx added twice!"); 1021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(old_idx); 1031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 1041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 1051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 1061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy rb_link_node(&old_idx->rb, parent, p); 1071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy rb_insert_color(&old_idx->rb, &c->old_idx); 1081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 1091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 1101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 1121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * insert_old_idx_znode - record a znode obsoleted since last commit start. 1131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 1141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode of obsoleted index node 1151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success, and a negative error code on failure. 1171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint insert_old_idx_znode(struct ubifs_info *c, struct ubifs_znode *znode) 1191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 1201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->parent) { 1211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 1221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->parent->zbranch[znode->iip]; 1241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->len) 1251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return insert_old_idx(c, zbr->lnum, zbr->offs); 1261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 1271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.len) 1281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return insert_old_idx(c, c->zroot.lnum, 1291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.offs); 1301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 1311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 1321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 1341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ins_clr_old_idx_znode - record a znode obsoleted since last commit start. 1351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 1361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode of obsoleted index node 1371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success, and a negative error code on failure. 1391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ins_clr_old_idx_znode(struct ubifs_info *c, 1411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 1421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 1431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 1441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->parent) { 1461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 1471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->parent->zbranch[znode->iip]; 1491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->len) { 1501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = insert_old_idx(c, zbr->lnum, zbr->offs); 1511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 1521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 1531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = 0; 1541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = 0; 1551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = 0; 1561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 1571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 1581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.len) { 1591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = insert_old_idx(c, c->zroot.lnum, c->zroot.offs); 1601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 1611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 1621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.lnum = 0; 1631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.offs = 0; 1641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.len = 0; 1651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 1661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 1671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 1681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 1701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * destroy_old_idx - destroy the old_idx RB-tree. 1711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 1721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * During start commit, the old_idx RB-tree is used to avoid overwriting index 1741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * nodes that were in the index last commit but have since been deleted. This 1751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is necessary for recovery i.e. the old index must be kept intact until the 1761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * new index is successfully written. The old-idx RB-tree is used for the 1771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * in-the-gaps method of writing index nodes and is destroyed every commit. 1781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyvoid destroy_old_idx(struct ubifs_info *c) 1801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 181bb25e49ff8ab0ef0b3c073c09d55cf10ef8a2aa0Cody P Schafer struct ubifs_old_idx *old_idx, *n; 182bb25e49ff8ab0ef0b3c073c09d55cf10ef8a2aa0Cody P Schafer 183bb25e49ff8ab0ef0b3c073c09d55cf10ef8a2aa0Cody P Schafer rbtree_postorder_for_each_entry_safe(old_idx, n, &c->old_idx, rb) 1841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(old_idx); 185bb25e49ff8ab0ef0b3c073c09d55cf10ef8a2aa0Cody P Schafer 1861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->old_idx = RB_ROOT; 1871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 1881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 1901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * copy_znode - copy a dirty znode. 1911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 1921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode to copy 1931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * A dirty znode being committed may not be changed, so it is copied. 1951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *copy_znode(struct ubifs_info *c, 1971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 1981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 1991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zn; 2001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn = kmalloc(c->max_znode_sz, GFP_NOFS); 2021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(!zn)) 2031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(-ENOMEM); 2041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy memcpy(zn, znode, c->max_znode_sz); 2061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->cnext = NULL; 2071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(DIRTY_ZNODE, &zn->flags); 2081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __clear_bit(COW_ZNODE, &zn->flags); 2091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 210f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy ubifs_assert(!ubifs_zn_obsolete(znode)); 2111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(OBSOLETE_ZNODE, &znode->flags); 2121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->level != 0) { 2141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int i; 2151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const int n = zn->child_cnt; 2161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* The children now have new parent */ 2181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = 0; i < n; i++) { 2191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr = &zn->zbranch[i]; 2201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->znode) 2221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->znode->parent = zn; 2231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 2241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 2251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->dirty_zn_cnt); 2271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return zn; 2281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 2291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 2311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * add_idx_dirt - add dirt due to a dirty znode. 2321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 2331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of index node 2341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @dirt: size of index node 2351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 2361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function updates lprops dirty space and the new size of the index. 2371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 2381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt) 2391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 2401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->calc_idx_sz -= ALIGN(dirt, 8); 2411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ubifs_add_dirt(c, lnum, dirt); 2421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 2431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 2451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirty_cow_znode - ensure a znode is not being committed. 2461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 2471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: branch of znode to check 2481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 2491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns dirtied znode on success or negative error code on failure. 2501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 2511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, 2521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr) 2531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 2541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode = zbr->znode; 2551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zn; 2561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 2571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 258f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy if (!ubifs_zn_cow(znode)) { 2591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* znode is not being committed */ 2601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) { 2611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->dirty_zn_cnt); 2621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_dec(&c->clean_zn_cnt); 2631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_dec(&ubifs_clean_zn_cnt); 2641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = add_idx_dirt(c, zbr->lnum, zbr->len); 2651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err)) 2661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(err); 2671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 2681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 2691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 2701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn = copy_znode(c, znode); 2728d47aef43ba166bdd11d522307c61ab23aab61c3Hirofumi Nakagawa if (IS_ERR(zn)) 2731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return zn; 2741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->len) { 2761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = insert_old_idx(c, zbr->lnum, zbr->offs); 2771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err)) 2781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(err); 2791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = add_idx_dirt(c, zbr->lnum, zbr->len); 2801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 2811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = 0; 2821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->znode = zn; 2841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = 0; 2851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = 0; 2861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = 0; 2871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err)) 2891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(err); 2901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return zn; 2911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 2921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 2941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lnc_add - add a leaf node to the leaf node cache. 2951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 2961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of leaf node 2971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: leaf node 2981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 2991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Leaf nodes are non-index nodes directory entry nodes or data nodes. The 3001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * purpose of the leaf node cache is to save re-reading the same leaf node over 3011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * and over again. Most things are cached by VFS, however the file system must 3021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * cache directory entries for readdir and for resolving hash collisions. The 3031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * present implementation of the leaf node cache is extremely simple, and 3041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * allows for error returns that are not used but that may be needed if a more 3051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * complex implementation is created. 3061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 3071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, this function does not add the @node object to LNC directly, but 3081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * allocates a copy of the object and adds the copy to LNC. The reason for this 3091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is that @node has been allocated outside of the TNC subsystem and will be 3101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * used with @c->tnc_mutex unlock upon return from the TNC subsystem. But LNC 3111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * may be changed at any time, e.g. freed by the shrinker. 3121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 3131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int lnc_add(struct ubifs_info *c, struct ubifs_zbranch *zbr, 3141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const void *node) 3151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 3161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 3171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *lnc_node; 3181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct ubifs_dent_node *dent = node; 3191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(!zbr->leaf); 3211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(zbr->len != 0); 3221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(is_hash_key(c, &zbr->key)); 3231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_validate_entry(c, dent); 3251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 3267c46d0ae29ba880963db283706950de7aa86c0a0Artem Bityutskiy dump_stack(); 327edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_node(c, dent); 3281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 3291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 3301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 331eaecf43a6970c8d0ef54a31427c82a99e4863fe8Thomas Meyer lnc_node = kmemdup(node, zbr->len, GFP_NOFS); 3321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!lnc_node) 3331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* We don't have to have the cache, so no error */ 3341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 3351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->leaf = lnc_node; 3371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 3381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 3391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /** 3411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lnc_add_directly - add a leaf node to the leaf-node-cache. 3421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 3431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of leaf node 3441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: leaf node 3451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 3461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function is similar to 'lnc_add()', but it does not create a copy of 3471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node but inserts @node to TNC directly. 3481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 3491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int lnc_add_directly(struct ubifs_info *c, struct ubifs_zbranch *zbr, 3501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *node) 3511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 3521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 3531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(!zbr->leaf); 3551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(zbr->len != 0); 3561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_validate_entry(c, node); 3581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 3597c46d0ae29ba880963db283706950de7aa86c0a0Artem Bityutskiy dump_stack(); 360edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_node(c, node); 3611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 3621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 3631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->leaf = node; 3651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 3661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 3671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 3691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lnc_free - remove a leaf node from the leaf node cache. 3701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of leaf node 3711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: leaf node 3721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 3731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void lnc_free(struct ubifs_zbranch *zbr) 3741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 3751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zbr->leaf) 3761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return; 3771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(zbr->leaf); 3781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->leaf = NULL; 3791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 3801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 3821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_read_node_nm - read a "hashed" leaf node. 3831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 3841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: key and position of the node 3851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: node is returned here 3861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 3871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function reads a "hashed" node defined by @zbr from the leaf node cache 3881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * (in it is there) or from the hash media, in which case the node is also 3891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * added to LNC. Returns zero in case of success or a negative negative error 3901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * code in case of failure. 3911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 3921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr, 3931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *node) 3941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 3951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 3961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(is_hash_key(c, &zbr->key)); 3981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 3991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->leaf) { 4001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Read from the leaf node cache */ 4011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(zbr->len != 0); 4021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy memcpy(node, zbr->leaf, zbr->len); 4031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 4041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 4051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_tnc_read_node(c, zbr, node); 4071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 4081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 4091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Add the node to the leaf node cache */ 4111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = lnc_add(c, zbr, node); 4121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 4131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 4141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 4161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * try_read_node - read a node if it is a node. 4171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 4181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @buf: buffer to read to 4191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @type: node type 4201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @len: node length (not aligned) 4211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of node to read 4221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset of node to read 4231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 4241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function tries to read a node of known type and length, checks it and 4251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * stores it in @buf. This function returns %1 if a node is present and %0 if 4261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * a node is not present. A negative error code is returned for I/O errors. 4271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function performs that same function as ubifs_read_node except that 4281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * it does not require that there is actually a node present and instead 4291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the return code indicates if a node was read. 4306f7ab6d458bbfc2f55d295fa3e6b9e69cdb1d517Artem Bityutskiy * 4316f7ab6d458bbfc2f55d295fa3e6b9e69cdb1d517Artem Bityutskiy * Note, this function does not check CRC of data nodes if @c->no_chk_data_crc 4326f7ab6d458bbfc2f55d295fa3e6b9e69cdb1d517Artem Bityutskiy * is true (it is controlled by corresponding mount option). However, if 43318d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy * @c->mounting or @c->remounting_rw is true (we are mounting or re-mounting to 43418d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy * R/W mode), @c->no_chk_data_crc is ignored and CRC is checked. This is 43518d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy * because during mounting or re-mounting from R/O mode to R/W mode we may read 43618d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy * journal nodes (when replying the journal or doing the recovery) and the 43718d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy * journal nodes may potentially be corrupted, so checking is required. 4381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 4391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int try_read_node(const struct ubifs_info *c, void *buf, int type, 4401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int len, int lnum, int offs) 4411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 4421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err, node_len; 4431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_ch *ch = buf; 4441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy uint32_t crc, node_crc; 4451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); 4471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 448d304820a1f6cdacab691bbcb7faa35ec631c6398Artem Bityutskiy err = ubifs_leb_read(c, lnum, buf, offs, len, 1); 4491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 4501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_err("cannot read node type %d from LEB %d:%d, error %d", 4511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy type, lnum, offs, err); 4521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 4531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 4541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) 4561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 4571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (ch->node_type != type) 4591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 4601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy node_len = le32_to_cpu(ch->len); 4621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (node_len != len) 4631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 4641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 46518d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy if (type == UBIFS_DATA_NODE && c->no_chk_data_crc && !c->mounting && 46618d1d7fbcc260e67d249bf90b454d8cf34288453Artem Bityutskiy !c->remounting_rw) 4676f7ab6d458bbfc2f55d295fa3e6b9e69cdb1d517Artem Bityutskiy return 1; 4682953e73f1ce4b3284b409aefb9d46bbde6515c37Adrian Hunter 4691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); 4701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy node_crc = le32_to_cpu(ch->crc); 4711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (crc != node_crc) 4721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 4731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 4751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 4761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 4781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * fallible_read_node - try to read a leaf node. 4791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 4801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of node to read 4811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: position of node 4821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: node returned 4831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 4841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function tries to read a node and returns %1 if the node is read, %0 4851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if the node is not present, and a negative error code in the case of error. 4861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 4871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, 4881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr, void *node) 4891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 4901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int ret; 4911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 492515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "LEB %d:%d, key ", zbr->lnum, zbr->offs); 4931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 4941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ret = try_read_node(c, node, key_type(c, key), zbr->len, zbr->lnum, 4951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs); 4961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (ret == 1) { 4971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key node_key; 4981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_dent_node *dent = node; 4991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* All nodes have key in the same place */ 5011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_read(c, &dent->key, &node_key); 5021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, &node_key) != 0) 5031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ret = 0; 5041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 505601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (ret == 0 && c->replaying) 506515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_mntk(key, "dangling branch LEB %d:%d len %d, key ", 507515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy zbr->lnum, zbr->offs, zbr->len); 5081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ret; 5091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 5101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 5121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * matches_name - determine if a direntry or xattr entry matches a given name. 5131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 5141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of dent 5151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: name to match 5161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 5171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function checks if xentry/direntry referred by zbranch @zbr matches name 5181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm. Returns %NAME_MATCHES if it does, %NAME_LESS if the name referred by 5191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr is less than @nm, and %NAME_GREATER if it is greater than @nm. In case 5201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * of failure, a negative error code is returned. 5211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 5221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr, 5231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm) 5241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 5251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_dent_node *dent; 5261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nlen, err; 5271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* If possible, match against the dent in the leaf node cache */ 5291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zbr->leaf) { 5301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dent = kmalloc(zbr->len, GFP_NOFS); 5311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!dent) 5321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOMEM; 5331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_tnc_read_node(c, zbr, dent); 5351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 5361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 5371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Add the node to the leaf node cache */ 5391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = lnc_add_directly(c, zbr, dent); 5401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 5411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 5421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 5431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dent = zbr->leaf; 5441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nlen = le16_to_cpu(dent->nlen); 5461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); 5471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == 0) { 5481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nlen == nm->len) 5491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_MATCHES; 5501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (nlen < nm->len) 5511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_LESS; 5521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 5531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_GREATER; 5541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (err < 0) 5551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_LESS; 5561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 5571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_GREATER; 5581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_free: 5601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(dent); 5611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 5621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 5631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 5651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * get_znode - get a TNC znode that may not be loaded yet. 5661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 5671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: parent znode 5681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: znode branch slot number 5691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 5701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns the znode or a negative error code. 5711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 5721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *get_znode(struct ubifs_info *c, 5731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode, int n) 5741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 5751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 5761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 5781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->znode) 5791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zbr->znode; 5801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 5811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, zbr, znode, n); 5821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 5831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 5841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 5861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_next - find next TNC entry. 5871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 5881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is passed and returned here 5891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: znode branch slot number is passed and returned here 5901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 5911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %0 if the next TNC entry is found, %-ENOENT if there is 5921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * no next entry, or a negative error code otherwise. 5931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 5941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int tnc_next(struct ubifs_info *c, struct ubifs_znode **zn, int *n) 5951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 5961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode = *zn; 5971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nn = *n; 5981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 5991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn += 1; 6001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nn < znode->child_cnt) { 6011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 6021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 6031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 6051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zp; 6061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 6081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zp) 6091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOENT; 6101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = znode->iip + 1; 6111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zp; 6121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nn < znode->child_cnt) { 6131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, nn); 6141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 6151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 6161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (znode->level != 0) { 6171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, 0); 6181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 6191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 6201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = 0; 6221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 6231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 6261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 6271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 6281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 6291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 6311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_prev - find previous TNC entry. 6321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 6331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is returned here 6341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: znode branch slot number is passed and returned here 6351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 6361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %0 if the previous TNC entry is found, %-ENOENT if 6371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * there is no next entry, or a negative error code otherwise. 6381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 6391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int tnc_prev(struct ubifs_info *c, struct ubifs_znode **zn, int *n) 6401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 6411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode = *zn; 6421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nn = *n; 6431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nn > 0) { 6451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn - 1; 6461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 6471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 6491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zp; 6501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 6521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zp) 6531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOENT; 6541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = znode->iip - 1; 6551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zp; 6561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nn >= 0) { 6571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, nn); 6581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 6591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 6601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (znode->level != 0) { 6611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = znode->child_cnt - 1; 6621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, nn); 6631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 6641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 6651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = znode->child_cnt - 1; 6671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 6681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 6701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 6711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 6721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 6731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 6741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 6761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * resolve_collision - resolve a collision. 6771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 6781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of a directory or extended attribute entry 6791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is returned here 6801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: zbranch number is passed and returned here 6811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: name of the entry 6821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 6831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function is called for "hashed" keys to make sure that the found key 6841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * really corresponds to the looked up node (directory or extended attribute 6851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * entry). It returns %1 and sets @zn and @n if the collision is resolved. 6861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * %0 is returned if @nm is not found and @zn and @n are set to the previous 6871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * entry, i.e. to the entry after which @nm could follow if it were in TNC. 6881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This means that @n may be set to %-1 if the leftmost key in @zn is the 6891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * previous one. A negative error code is returned on failures. 6901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 6911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int resolve_collision(struct ubifs_info *c, const union ubifs_key *key, 6921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode **zn, int *n, 6931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm) 6941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 6951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 6961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 6971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = matches_name(c, &(*zn)->zbranch[*n], nm); 6981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 6991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_MATCHES) 7011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 7021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 7031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_GREATER) { 7041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look left */ 7051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 7061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, zn, n); 7071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) { 7081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(*n == 0); 7091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 7101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 7131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &(*zn)->zbranch[*n].key, key)) { 7151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 7161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We have found the branch after which we would 7171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * like to insert, but inserting in this znode 7181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * may still be wrong. Consider the following 3 7191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znodes, in the case where we are resolving a 7201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collision with Key2. 7211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 7221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode zp 7231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ---------------------- 7241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * level 1 | Key0 | Key1 | 7251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ----------------------- 7261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | | 7271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode za | | znode zb 7281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ------------ ------------ 7291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * level 0 | Key0 | | Key2 | 7301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ------------ ------------ 7311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 7321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The lookup finds Key2 in znode zb. Lets say 7331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * there is no match and the name is greater so 7341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * we look left. When we find Key0, we end up 7351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * here. If we return now, we will insert into 7361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode za at slot n = 1. But that is invalid 7371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * according to the parent's keys. Key2 must 7381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * be inserted into znode zb. 7391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 7401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, this problem is not relevant for the 7411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * case when we go right, because 7421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'tnc_insert()' would correct the parent key. 7431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 7441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (*n == (*zn)->child_cnt - 1) { 7451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, zn, n); 7461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 7471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Should be impossible */ 7481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(0); 7491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 7501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -EINVAL; 7511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(*n == 0); 7541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 7551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = matches_name(c, &(*zn)->zbranch[*n], nm); 7591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 7601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_LESS) 7621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_MATCHES) 7641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 7651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(err == NAME_GREATER); 7661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else { 7681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nn = *n; 7691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode = *zn; 7701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 7711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look right */ 7721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 7731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &nn); 7741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 7751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 7771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[nn].key, key)) 7791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = matches_name(c, &znode->zbranch[nn], nm); 7811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 7821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 7831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_GREATER) 7841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 7851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 7861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 7871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_MATCHES) 7881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 7891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(err == NAME_LESS); 7901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 7921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 7931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 7941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 7951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * fallible_matches_name - determine if a dent matches a given name. 7961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 7971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of dent 7981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: name to match 7991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 8001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is a "fallible" version of 'matches_name()' function which does not 8011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * panic if the direntry/xentry referred by @zbr does not exist on the media. 8021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 8031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function checks if xentry/direntry referred by zbranch @zbr matches name 8041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm. Returns %NAME_MATCHES it does, %NAME_LESS if the name referred by @zbr 8051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is less than @nm, %NAME_GREATER if it is greater than @nm, and @NOT_ON_MEDIA 8061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if xentry/direntry referred by @zbr does not exist on the media. A negative 8071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * error code is returned in case of failure. 8081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 8091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int fallible_matches_name(struct ubifs_info *c, 8101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr, 8111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm) 8121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 8131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_dent_node *dent; 8141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nlen, err; 8151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* If possible, match against the dent in the leaf node cache */ 8171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zbr->leaf) { 8181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dent = kmalloc(zbr->len, GFP_NOFS); 8191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!dent) 8201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOMEM; 8211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = fallible_read_node(c, &zbr->key, zbr, dent); 8231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 8241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 8251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == 0) { 8261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* The node was not present */ 8271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = NOT_ON_MEDIA; 8281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 8291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 8301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(err == 1); 8311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = lnc_add_directly(c, zbr, dent); 8331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 8341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 8351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 8361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dent = zbr->leaf; 8371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nlen = le16_to_cpu(dent->nlen); 8391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); 8401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == 0) { 8411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nlen == nm->len) 8421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_MATCHES; 8431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (nlen < nm->len) 8441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_LESS; 8451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 8461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_GREATER; 8471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (err < 0) 8481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_LESS; 8491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 8501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NAME_GREATER; 8511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_free: 8531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(dent); 8541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 8551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 8561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 8581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * fallible_resolve_collision - resolve a collision even if nodes are missing. 8591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 8601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key 8611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is returned here 8621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: branch number is passed and returned here 8631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: name of directory entry 8641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @adding: indicates caller is adding a key to the TNC 8651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 8661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is a "fallible" version of the 'resolve_collision()' function which 8671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * does not panic if one of the nodes referred to by TNC does not exist on the 8681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * media. This may happen when replaying the journal if a deleted node was 8691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Garbage-collected and the commit was not done. A branch that refers to a node 8701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * that is not present is called a dangling branch. The following are the return 8711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * codes for this function: 8721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o if @nm was found, %1 is returned and @zn and @n are set to the found 8731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * branch; 8741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o if we are @adding and @nm was not found, %0 is returned; 8751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o if we are not @adding and @nm was not found, but a dangling branch was 8761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * found, then %1 is returned and @zn and @n are set to the dangling branch; 8771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o a negative error code is returned in case of failure. 8781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 8791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int fallible_resolve_collision(struct ubifs_info *c, 8801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const union ubifs_key *key, 8811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode **zn, int *n, 8821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm, int adding) 8831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 8841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *o_znode = NULL, *znode = *zn; 8851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n; 8861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 8871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy cmp = fallible_matches_name(c, &znode->zbranch[nn], nm); 8881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(cmp < 0)) 8891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return cmp; 8901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (cmp == NAME_MATCHES) 8911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 8921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (cmp == NOT_ON_MEDIA) { 8931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_znode = znode; 8941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_n = nn; 8951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 8961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We are unlucky and hit a dangling branch straight away. 8971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Now we do not really know where to go to find the needed 8981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * branch - to the left or to the right. Well, let's try left. 8991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 9001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy unsure = 1; 9011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (!adding) 9021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy unsure = 1; /* Remove a dangling branch wherever it is */ 9031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 9041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (cmp == NAME_GREATER || unsure) { 9051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look left */ 9061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 9071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, zn, n); 9081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) { 9091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(*n == 0); 9101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 9111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 9141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 9151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &(*zn)->zbranch[*n].key, key)) { 9161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* See comments in 'resolve_collision()' */ 9171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (*n == (*zn)->child_cnt - 1) { 9181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, zn, n); 9191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 9201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Should be impossible */ 9211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(0); 9221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 9231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -EINVAL; 9241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 9251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(*n == 0); 9271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 9281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = fallible_matches_name(c, &(*zn)->zbranch[*n], nm); 9321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 9331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 9341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_MATCHES) 9351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 9361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NOT_ON_MEDIA) { 9371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_znode = *zn; 9381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_n = *n; 9391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy continue; 9401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!adding) 9421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy continue; 9431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_LESS) 9441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 9461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy unsure = 0; 9471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 9501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (cmp == NAME_LESS || unsure) { 9511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look right */ 9521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 9531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 9541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 9551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &nn); 9561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 9571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 9591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 9601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[nn].key, key)) 9611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = fallible_matches_name(c, &znode->zbranch[nn], nm); 9631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 9641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 9651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_GREATER) 9661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 9671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 9681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 9691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NAME_MATCHES) 9701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 9711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == NOT_ON_MEDIA) { 9721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_znode = znode; 9731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_n = nn; 9741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 9771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 9781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Never match a dangling branch when adding */ 9791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (adding || !o_znode) 9801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 9811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 982515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_mntk(key, "dangling match LEB %d:%d len %d key ", 9831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy o_znode->zbranch[o_n].lnum, o_znode->zbranch[o_n].offs, 984515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy o_znode->zbranch[o_n].len); 9851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = o_znode; 9861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = o_n; 9871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 9881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 9891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 9901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 9911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * matches_position - determine if a zbranch matches a given position. 9921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch of dent 9931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of dent to match 9941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset of dent to match 9951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 9961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %1 if @lnum:@offs matches, and %0 otherwise. 9971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 9981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int matches_position(struct ubifs_zbranch *zbr, int lnum, int offs) 9991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 10001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->lnum == lnum && zbr->offs == offs) 10011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 10021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 10031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 10041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 10051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 10071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * resolve_collision_directly - resolve a collision directly. 10081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 10091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of directory entry 10101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is passed and returned here 10111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: zbranch number is passed and returned here 10121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of dent node to match 10131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset of dent node to match 10141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 10151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function is used for "hashed" keys to make sure the found directory or 10161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * extended attribute entry node is what was looked for. It is used when the 10171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * flash address of the right node is known (@lnum:@offs) which makes it much 10181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * easier to resolve collisions (no need to read entries and match full 10191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * names). This function returns %1 and sets @zn and @n if the collision is 10201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * resolved, %0 if @lnum:@offs is not found and @zn and @n are set to the 10211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * previous directory entry. Otherwise a negative error code is returned. 10221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 10231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int resolve_collision_directly(struct ubifs_info *c, 10241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const union ubifs_key *key, 10251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode **zn, int *n, 10261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs) 10271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 10281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 10291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int nn, err; 10301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = *zn; 10321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = *n; 10331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (matches_position(&znode->zbranch[nn], lnum, offs)) 10341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 10351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look left */ 10371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 10381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, &znode, &nn); 10391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 10401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 10411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 10421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 10431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[nn].key, key)) 10441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 10451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (matches_position(&znode->zbranch[nn], lnum, offs)) { 10461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 10471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 10481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 10491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 10501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 10511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look right */ 10531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = *zn; 10541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = *n; 10551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 10561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &nn); 10571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 10581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 10591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 10601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 10611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[nn].key, key)) 10621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 10631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 10641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = nn; 10651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (matches_position(&znode->zbranch[nn], lnum, offs)) 10661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 10671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 10681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 10691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 10711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirty_cow_bottom_up - dirty a znode and its ancestors. 10721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 10731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode to dirty 10741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 10751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * If we do not have a unique key that resides in a znode, then we cannot 10761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirty that znode from the top down (i.e. by using lookup_level0_dirty) 10771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function records the path back to the last dirty ancestor, and then 10781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirties the znodes on that path. 10791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 10801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, 10811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 10821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 10831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zp; 10841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int *path = c->bottom_up_buf, p = 0; 10851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 10861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(c->zroot.znode); 10871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode); 10881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) { 10891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(c->bottom_up_buf); 10901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->bottom_up_buf = kmalloc(c->zroot.znode->level * sizeof(int), 10911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy GFP_NOFS); 10921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!c->bottom_up_buf) 10931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(-ENOMEM); 10941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy path = c->bottom_up_buf; 10951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 10961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.znode->level) { 10971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Go up until parent is dirty */ 10981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 10991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n; 11001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 11021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zp) 11031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 11041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = znode->iip; 11051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(p < c->zroot.znode->level); 11061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy path[p++] = n; 11071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zp->cnext && ubifs_zn_dirty(znode)) 11081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 11091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zp; 11101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Come back down, dirtying as we go */ 11141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 11151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 11161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 11181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zp) { 11191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(path[p - 1] >= 0); 11201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(path[p - 1] < zp->child_cnt); 11211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &zp->zbranch[path[--p]]; 11221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, zbr); 11231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else { 11241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode == c->zroot.znode); 11251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, &c->zroot); 11261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11278d47aef43ba166bdd11d522307c61ab23aab61c3Hirofumi Nakagawa if (IS_ERR(znode) || !p) 11281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 11291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(path[p - 1] >= 0); 11301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(path[p - 1] < znode->child_cnt); 11311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = znode->zbranch[path[p - 1]].znode; 11321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 11351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 11361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 11381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_lookup_level0 - search for zero-level znode. 11391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 11401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to lookup 11411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is returned here 11421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: znode branch slot number is returned here 11431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 11441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function looks up the TNC tree and search for zero-level znode which 11451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * refers key @key. The found zero-level znode is returned in @zn. There are 3 11461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * cases: 11471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o exact match, i.e. the found zero-level znode contains key @key, then %1 11481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is returned and slot number of the matched branch is stored in @n; 11491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o not exact match, which means that zero-level znode does not contain 1150e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * @key, then %0 is returned and slot number of the closest branch is stored 1151e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * in @n; 11521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o @key is so small that it is even less than the lowest key of the 11531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * leftmost zero-level node, then %0 is returned and %0 is stored in @n. 11541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 11551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, when the TNC tree is traversed, some znodes may be absent, then this 11561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * function reads corresponding indexing nodes and inserts them to TNC. In 11571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * case of failure, a negative error code is returned. 11581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 11591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key, 11601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode **zn, int *n) 11611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 11621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err, exact; 11631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 11641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy unsigned long time = get_seconds(); 11651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1166515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "search key "); 1167ba2f48f70efcf4d82deafb2be327ed64b1f043a5Artem Bityutskiy ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY); 11681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = c->zroot.znode; 11701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(!znode)) { 11711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, &c->zroot, NULL, 0); 11721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 11731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 11741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->time = time; 11771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 11791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 11801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy exact = ubifs_search_zbranch(c, znode, key, n); 11821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->level == 0) 11841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 11851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (*n < 0) 11871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = 0; 11881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[*n]; 11891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->znode) { 11911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->time = time; 11921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zbr->znode; 11931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy continue; 11941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 11951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 11961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* znode is not in TNC cache, load it from the media */ 11971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, zbr, znode, *n); 11981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 11991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 12001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 12011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 12021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 12031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (exact || !is_hash_key(c, key) || *n != -1) { 12041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found %d, lvl %d, n %d", exact, znode->level, *n); 12051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return exact; 12061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 12071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 12081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 12091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Here is a tricky place. We have not found the key and this is a 12101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * "hashed" key, which may collide. The rest of the code deals with 12111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * situations like this: 12121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 3 | 5 | 12141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * / \ 12151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 3 | 5 | | 6 | 7 | (x) 12161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Or more a complex example: 12181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 1 | 5 | 12201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * / \ 12211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 1 | 3 | | 5 | 8 | 12221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * \ / 12231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 5 | 5 | | 6 | 7 | (x) 12241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * In the examples, if we are looking for key "5", we may reach nodes 12261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * marked with "(x)". In this case what we have do is to look at the 12271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * left and see if there is "5" key there. If there is, we have to 12281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * return it. 12291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, this whole situation is possible because we allow to have 12311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * elements which are equivalent to the next key in the parent in the 12321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * children of current znode. For example, this happens if we split a 12331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode like this: | 3 | 5 | 5 | 6 | 7 |, which results in something 12341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * like this: 12351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 3 | 5 | 12361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * / \ 12371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * | 3 | 5 | | 5 | 6 | 7 | 12381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ^ 12391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * And this becomes what is at the first "picture" after key "5" marked 12401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * with "^" is removed. What could be done is we could prohibit 12411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * splitting in the middle of the colliding sequence. Also, when 12421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * removing the leftmost key, we would have to correct the key of the 12431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * parent node, which would introduce additional complications. Namely, 12447d4e9ccb435e51e013e63abd340b4f496428139cArtem Bityutskiy * if we changed the leftmost key of the parent znode, the garbage 12451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collector would be unable to find it (GC is doing this when GC'ing 12461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * indexing LEBs). Although we already have an additional RB-tree where 12471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * we save such changed znodes (see 'ins_clr_old_idx_znode()') until 12481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * after the commit. But anyway, this does not look easy to implement 12491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * so we did not try this. 12501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 12511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, &znode, n); 12521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) { 12531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 0, lvl %d, n -1", znode->level); 12541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 12551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 12561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 12571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 12581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 12591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, &znode->zbranch[*n].key)) { 12601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 0, lvl %d, n -1", znode->level); 12611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 12621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 12631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 12641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 12651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 1, lvl %d, n %d", znode->level, *n); 12661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 12671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 12681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 12691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 12701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 12711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lookup_level0_dirty - search for zero-level znode dirtying. 12721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 12731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to lookup 12741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zn: znode is returned here 12751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: znode branch slot number is returned here 12761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function looks up the TNC tree and search for zero-level znode which 12781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * refers key @key. The found zero-level znode is returned in @zn. There are 3 12791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * cases: 12801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o exact match, i.e. the found zero-level znode contains key @key, then %1 12811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is returned and slot number of the matched branch is stored in @n; 12821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o not exact match, which means that zero-level znode does not contain @key 12831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * then %0 is returned and slot number of the closed branch is stored in 12841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n; 12851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o @key is so small that it is even less than the lowest key of the 12861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * leftmost zero-level node, then %0 is returned and %-1 is stored in @n. 12871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Additionally all znodes in the path from the root to the located zero-level 12891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode are marked as dirty. 12901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 12911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, when the TNC tree is traversed, some znodes may be absent, then this 12921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * function reads corresponding indexing nodes and inserts them to TNC. In 12931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * case of failure, a negative error code is returned. 12941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 12951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int lookup_level0_dirty(struct ubifs_info *c, const union ubifs_key *key, 12961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode **zn, int *n) 12971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 12981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err, exact; 12991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 13001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy unsigned long time = get_seconds(); 13011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1302515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "search and dirty key "); 13031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = c->zroot.znode; 13051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(!znode)) { 13061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, &c->zroot, NULL, 0); 13071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, &c->zroot); 13121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->time = time; 13161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 13181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 13191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy exact = ubifs_search_zbranch(c, znode, key, n); 13211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->level == 0) 13231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 13241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (*n < 0) 13261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = 0; 13271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[*n]; 13281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->znode) { 13301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->time = time; 13311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, zbr); 13321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy continue; 13351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* znode is not in TNC cache, load it from the media */ 13381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, zbr, znode, *n); 13391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, zbr); 13421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 13471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (exact || !is_hash_key(c, key) || *n != -1) { 13481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found %d, lvl %d, n %d", exact, znode->level, *n); 13491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return exact; 13501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 13531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * See huge comment at 'lookup_level0_dirty()' what is the rest of the 13541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * code. 13551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 13561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, &znode, n); 13571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) { 13581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 13591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 0, lvl %d, n -1", znode->level); 13601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 13611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 13631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 13641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, &znode->zbranch[*n].key)) { 13651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *n = -1; 13661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 0, lvl %d, n -1", znode->level); 13671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 13681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext || !ubifs_zn_dirty(znode)) { 13711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 13721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 13731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 13741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 13751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("found 1, lvl %d, n %d", znode->level, *n); 13771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *zn = znode; 13781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 13791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 13801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 13811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 1382601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * maybe_leb_gced - determine if a LEB may have been garbage collected. 13831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 1384601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * @lnum: LEB number 1385601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * @gc_seq1: garbage collection sequence number 13861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1387601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * This function determines if @lnum may have been garbage collected since 1388601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * sequence number @gc_seq1. If it may have been then %1 is returned, otherwise 1389601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * %0 is returned. 13901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1391601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunterstatic int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1) 13921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 1393601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter int gc_seq2, gced_lnum; 13941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1395601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter gced_lnum = c->gced_lnum; 1396601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter smp_rmb(); 1397601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter gc_seq2 = c->gc_seq; 1398601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* Same seq means no GC */ 1399601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (gc_seq1 == gc_seq2) 1400601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 0; 1401601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* Different by more than 1 means we don't know */ 1402601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (gc_seq1 + 1 != gc_seq2) 1403601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 1; 1404601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* 1405601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * We have seen the sequence number has increased by 1. Now we need to 1406601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * be sure we read the right LEB number, so read it again. 1407601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter */ 1408601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter smp_rmb(); 1409601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (gced_lnum != c->gced_lnum) 1410601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 1; 1411601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* Finally we can check lnum */ 1412601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (gced_lnum == lnum) 1413601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 1; 1414601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 0; 14151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 14161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 14171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 14181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_locate - look up a file-system node and return it and its location. 14191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 14201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: node key to lookup 14211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: the node is returned here 14221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number is returned here 14231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset is returned here 14241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 1425e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * This function looks up and reads node with key @key. The caller has to make 1426601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * sure the @node buffer is large enough to fit the node. Returns zero in case 1427601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * of success, %-ENOENT if the node was not found, and a negative error code in 1428601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * case of failure. The node location can be returned in @lnum and @offs. 14291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 14301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, 14311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *node, int *lnum, int *offs) 14321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 1433601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter int found, n, err, safely = 0, gc_seq1; 14341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 14351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch zbr, *zt; 14361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1437601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunteragain: 14381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 14391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = ubifs_lookup_level0(c, key, &znode, &n); 14401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) { 14411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -ENOENT; 14421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out; 14431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (found < 0) { 14441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 14451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out; 14461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 14471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zt = &znode->zbranch[n]; 1448601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (lnum) { 1449601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter *lnum = zt->lnum; 1450601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter *offs = zt->offs; 1451601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter } 14521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (is_hash_key(c, key)) { 14531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 14541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * In this case the leaf node cache gets used, so we pass the 14551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * address of the zbranch and keep the mutex locked 14561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 14571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_read_node_nm(c, zt, node); 14581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out; 14591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 1460601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (safely) { 1461601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter err = ubifs_tnc_read_node(c, zt, node); 1462601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter goto out; 1463601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter } 1464601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* Drop the TNC mutex prematurely and race with garbage collection */ 14651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = znode->zbranch[n]; 1466601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter gc_seq1 = c->gc_seq; 14671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 14681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1469601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter if (ubifs_get_wbuf(c, zbr.lnum)) { 1470601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* We do not GC journal heads */ 1471601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter err = ubifs_tnc_read_node(c, &zbr, node); 1472601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return err; 1473601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter } 14741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1475601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter err = fallible_read_node(c, key, &zbr, node); 14766dcfac4f13d6b32fbaa60b64a23249999e66af8eAdrian Hunter if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) { 1477601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter /* 1478601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * The node may have been GC'ed out from under us so try again 1479601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter * while keeping the TNC mutex locked. 1480601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter */ 1481601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter safely = 1; 1482601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter goto again; 1483601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter } 1484601c0bc46753007be011b513ba4fc50ed8e30aefAdrian Hunter return 0; 14851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 14861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout: 14871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 14881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 14891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 14901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 14911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 14924793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * ubifs_tnc_get_bu_keys - lookup keys for bulk-read. 14934793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @c: UBIFS file-system description object 14944793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @bu: bulk-read parameters and results 14954793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * 14964793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * Lookup consecutive data node keys for the same inode that reside 14976c0c42cdfd73fb161417403d8d077cb136e10bbfArtem Bityutskiy * consecutively in the same LEB. This function returns zero in case of success 14986c0c42cdfd73fb161417403d8d077cb136e10bbfArtem Bityutskiy * and a negative error code in case of failure. 14996c0c42cdfd73fb161417403d8d077cb136e10bbfArtem Bityutskiy * 15006c0c42cdfd73fb161417403d8d077cb136e10bbfArtem Bityutskiy * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function 15016c0c42cdfd73fb161417403d8d077cb136e10bbfArtem Bityutskiy * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares 15026f7ab6d458bbfc2f55d295fa3e6b9e69cdb1d517Artem Bityutskiy * maximum possible amount of nodes for bulk-read. 15034793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 15044793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterint ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) 15054793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter{ 15064793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int n, err = 0, lnum = -1, uninitialized_var(offs); 15074793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int uninitialized_var(len); 15084793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter unsigned int block = key_block(c, &bu->key); 15094793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter struct ubifs_znode *znode; 15104793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 15114793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->cnt = 0; 15124793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt = 0; 15134793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->eof = 0; 15144793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 15154793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter mutex_lock(&c->tnc_mutex); 15164793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Find first key */ 15174793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = ubifs_lookup_level0(c, &bu->key, &znode, &n); 15184793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err < 0) 15194793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15204793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err) { 15214793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Key found */ 15224793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len = znode->zbranch[n].len; 15234793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* The buffer must be big enough for at least 1 node */ 15244793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (len > bu->buf_len) { 15254793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = -EINVAL; 15264793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15274793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15284793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Add this key */ 15294793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->zbranch[bu->cnt++] = znode->zbranch[n]; 15304793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt += 1; 15314793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter lnum = znode->zbranch[n].lnum; 15324793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter offs = ALIGN(znode->zbranch[n].offs + len, 8); 15334793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15344793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter while (1) { 15354793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter struct ubifs_zbranch *zbr; 15364793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter union ubifs_key *key; 15374793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter unsigned int next_block; 15384793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 15394793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Find next key */ 15404793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = tnc_next(c, &znode, &n); 15414793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err) 15424793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15434793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter zbr = &znode->zbranch[n]; 15444793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter key = &zbr->key; 15454793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* See if there is another data key for this file */ 15464793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (key_inum(c, key) != key_inum(c, &bu->key) || 15474793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter key_type(c, key) != UBIFS_DATA_KEY) { 15484793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = -ENOENT; 15494793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15504793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15514793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (lnum < 0) { 15524793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* First key found */ 15534793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter lnum = zbr->lnum; 15544793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter offs = ALIGN(zbr->offs + zbr->len, 8); 15554793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len = zbr->len; 15564793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (len > bu->buf_len) { 15574793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = -EINVAL; 15584793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15594793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15604793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } else { 15614793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* 15624793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * The data nodes must be in consecutive positions in 15634793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * the same LEB. 15644793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 15654793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (zbr->lnum != lnum || zbr->offs != offs) 15664793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15674793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter offs += ALIGN(zbr->len, 8); 15684793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len = ALIGN(len, 8) + zbr->len; 15694793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Must not exceed buffer length */ 15704793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (len > bu->buf_len) 15714793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15724793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15734793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Allow for holes */ 15744793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter next_block = key_block(c, key); 15754793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt += (next_block - block - 1); 15764793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (bu->blk_cnt >= UBIFS_MAX_BULK_READ) 15774793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15784793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter block = next_block; 15794793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Add this key */ 15804793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->zbranch[bu->cnt++] = *zbr; 15814793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt += 1; 15824793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* See if we have room for more */ 15834793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (bu->cnt >= UBIFS_MAX_BULK_READ) 15844793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15854793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (bu->blk_cnt >= UBIFS_MAX_BULK_READ) 15864793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 15874793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15884793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterout: 15894793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err == -ENOENT) { 15904793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->eof = 1; 15914793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = 0; 15924793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 15934793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->gc_seq = c->gc_seq; 15944793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter mutex_unlock(&c->tnc_mutex); 15954793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err) 15964793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return err; 15974793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* 15984793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * An enormous hole could cause bulk-read to encompass too many 15994793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * page cache pages, so limit the number here. 16004793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 160163c300b68fd93a9fadc5e317d4d001b7a6985486Adrian Hunter if (bu->blk_cnt > UBIFS_MAX_BULK_READ) 16024793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt = UBIFS_MAX_BULK_READ; 16034793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* 16044793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * Ensure that bulk-read covers a whole number of page cache 16054793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * pages. 16064793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 16074793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (UBIFS_BLOCKS_PER_PAGE == 1 || 16084793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter !(bu->blk_cnt & (UBIFS_BLOCKS_PER_PAGE - 1))) 16094793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 16104793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (bu->eof) { 16114793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* At the end of file we can round up */ 16124793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->blk_cnt += UBIFS_BLOCKS_PER_PAGE - 1; 16134793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 16144793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 16154793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Exclude data nodes that do not make up a whole page cache page */ 16164793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter block = key_block(c, &bu->key) + bu->blk_cnt; 16174793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter block &= ~(UBIFS_BLOCKS_PER_PAGE - 1); 16184793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter while (bu->cnt) { 16194793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (key_block(c, &bu->zbranch[bu->cnt - 1].key) < block) 16204793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter break; 16214793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter bu->cnt -= 1; 16224793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 16234793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 16244793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter} 16254793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16264793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter/** 16274793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * read_wbuf - bulk-read from a LEB with a wbuf. 16284793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @wbuf: wbuf that may overlap the read 16294793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @buf: buffer into which to read 16304793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @len: read length 16314793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @lnum: LEB number from which to read 16324793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @offs: offset from which to read 16334793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * 16344793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * This functions returns %0 on success or a negative error code on failure. 16354793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 16364793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterstatic int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum, 16374793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int offs) 16384793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter{ 16394793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter const struct ubifs_info *c = wbuf->c; 16404793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int rlen, overlap; 16414793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16424793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter dbg_io("LEB %d:%d, length %d", lnum, offs, len); 16434793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); 16444793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_assert(!(offs & 7) && offs < c->leb_size); 16454793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_assert(offs + len <= c->leb_size); 16464793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16474793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter spin_lock(&wbuf->lock); 16484793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs); 16494793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (!overlap) { 16504793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* We may safely unlock the write-buffer and read the data */ 16514793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter spin_unlock(&wbuf->lock); 1652d304820a1f6cdacab691bbcb7faa35ec631c6398Artem Bityutskiy return ubifs_leb_read(c, lnum, buf, offs, len, 0); 16534793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 16544793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16554793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Don't read under wbuf */ 16564793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter rlen = wbuf->offs - offs; 16574793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (rlen < 0) 16584793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter rlen = 0; 16594793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16604793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Copy the rest from the write-buffer */ 16614793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter memcpy(buf + rlen, wbuf->buf + offs + rlen - wbuf->offs, len - rlen); 16624793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter spin_unlock(&wbuf->lock); 16634793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16644793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (rlen > 0) 16654793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Read everything that goes before write-buffer */ 1666d304820a1f6cdacab691bbcb7faa35ec631c6398Artem Bityutskiy return ubifs_leb_read(c, lnum, buf, offs, rlen, 0); 16674793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16684793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 16694793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter} 16704793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16714793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter/** 16724793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * validate_data_node - validate data nodes for bulk-read. 16734793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @c: UBIFS file-system description object 16744793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @buf: buffer containing data node to validate 16754793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @zbr: zbranch of data node to validate 16764793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * 16774793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * This functions returns %0 on success or a negative error code on failure. 16784793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 16794793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterstatic int validate_data_node(struct ubifs_info *c, void *buf, 16804793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter struct ubifs_zbranch *zbr) 16814793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter{ 16824793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter union ubifs_key key1; 16834793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter struct ubifs_ch *ch = buf; 16844793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int err, len; 16854793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16864793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (ch->node_type != UBIFS_DATA_NODE) { 16874793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("bad node type (%d but expected %d)", 16884793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ch->node_type, UBIFS_DATA_NODE); 16894793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out_err; 16904793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 16914793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16922953e73f1ce4b3284b409aefb9d46bbde6515c37Adrian Hunter err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0); 16934793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err) { 16944793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("expected node type %d", UBIFS_DATA_NODE); 16954793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out; 16964793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 16974793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 16984793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len = le32_to_cpu(ch->len); 16994793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (len != zbr->len) { 17004793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("bad node length %d, expected %d", len, zbr->len); 17014793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out_err; 17024793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 17034793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17044793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Make sure the key of the read node is correct */ 17054793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter key_read(c, buf + UBIFS_KEY_OFFSET, &key1); 17064793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (!keys_eq(c, &zbr->key, &key1)) { 17074793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("bad key in node at LEB %d:%d", 17084793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter zbr->lnum, zbr->offs); 1709515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(&zbr->key, "looked for key "); 1710515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(&key1, "found node's key "); 17114793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter goto out_err; 17124793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 17134793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17144793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 17154793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17164793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterout_err: 17174793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = -EINVAL; 17184793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterout: 17194793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("bad node at LEB %d:%d", zbr->lnum, zbr->offs); 1720edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_node(c, buf); 17217c46d0ae29ba880963db283706950de7aa86c0a0Artem Bityutskiy dump_stack(); 17224793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return err; 17234793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter} 17244793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17254793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter/** 17264793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * ubifs_tnc_bulk_read - read a number of data nodes in one go. 17274793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @c: UBIFS file-system description object 17284793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * @bu: bulk-read parameters and results 17294793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * 17304793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * This functions reads and validates the data nodes that were identified by the 17314793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * 'ubifs_tnc_get_bu_keys()' function. This functions returns %0 on success, 17324793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * -EAGAIN to indicate a race with GC, or another negative error code on 17334793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter * failure. 17344793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter */ 17354793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunterint ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu) 17364793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter{ 17374793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter int lnum = bu->zbranch[0].lnum, offs = bu->zbranch[0].offs, len, err, i; 17384793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter struct ubifs_wbuf *wbuf; 17394793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter void *buf; 17404793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17414793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len = bu->zbranch[bu->cnt - 1].offs; 17424793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter len += bu->zbranch[bu->cnt - 1].len - offs; 17434793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (len > bu->buf_len) { 17444793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("buffer too small %d vs %d", bu->buf_len, len); 17454793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return -EINVAL; 17464793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 17474793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17484793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Do the read */ 17494793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter wbuf = ubifs_get_wbuf(c, lnum); 17504793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (wbuf) 17514793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = read_wbuf(wbuf, bu->buf, len, lnum, offs); 17524793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter else 1753d304820a1f6cdacab691bbcb7faa35ec631c6398Artem Bityutskiy err = ubifs_leb_read(c, lnum, bu->buf, offs, len, 0); 17544793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17554793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Check for a race with GC */ 17564793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (maybe_leb_gced(c, lnum, bu->gc_seq)) 17574793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return -EAGAIN; 17584793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17594793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err && err != -EBADMSG) { 17604793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter ubifs_err("failed to read from LEB %d:%d, error %d", 17614793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter lnum, offs, err); 17627c46d0ae29ba880963db283706950de7aa86c0a0Artem Bityutskiy dump_stack(); 1763515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(&bu->key, "key "); 17644793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return err; 17654793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 17664793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17674793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter /* Validate the nodes read */ 17684793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter buf = bu->buf; 17694793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter for (i = 0; i < bu->cnt; i++) { 17704793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter err = validate_data_node(c, buf, &bu->zbranch[i]); 17714793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter if (err) 17724793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return err; 17734793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter buf = buf + ALIGN(bu->zbranch[i].len, 8); 17744793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter } 17754793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17764793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter return 0; 17774793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter} 17784793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter 17794793e7c5e1c88382ead18db5ca072bac54467318Adrian Hunter/** 17801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * do_lookup_nm- look up a "hashed" node. 17811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 17821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: node key to lookup 17831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: the node is returned here 17841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: node name 17851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 17861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function look up and reads a node which contains name hash in the key. 17871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Since the hash may have collisions, there may be many nodes with the same 17881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * key, so we have to sequentially look to all of them until the needed one is 17891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * found. This function returns zero in case of success, %-ENOENT if the node 17901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * was not found, and a negative error code in case of failure. 17911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 17921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, 17931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *node, const struct qstr *nm) 17941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 17951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int found, n, err; 17961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 17971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1798515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name); 17991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 18001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = ubifs_lookup_level0(c, key, &znode, &n); 18011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) { 18021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -ENOENT; 18031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 18041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (found < 0) { 18051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 18061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 18071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 18081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(n >= 0); 18101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = resolve_collision(c, key, &znode, &n, nm); 18121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); 18131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 18141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 18151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == 0) { 18161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -ENOENT; 18171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 18181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 18191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 1820761e29f3bb19b05bea55285dfdf2d28e001a63b8Adrian Hunter err = tnc_read_node_nm(c, &znode->zbranch[n], node); 18211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 18231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 18241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 18251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 18261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 18281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_lookup_nm - look up a "hashed" node. 18291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 18301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: node key to lookup 18311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @node: the node is returned here 18321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: node name 18331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 18341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function look up and reads a node which contains name hash in the key. 18351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Since the hash may have collisions, there may be many nodes with the same 18361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * key, so we have to sequentially look to all of them until the needed one is 18371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * found. This function returns zero in case of success, %-ENOENT if the node 18381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * was not found, and a negative error code in case of failure. 18391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 18401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, 18411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy void *node, const struct qstr *nm) 18421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 18431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err, len; 18441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct ubifs_dent_node *dent = node; 18451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 18471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We assume that in most of the cases there are no name collisions and 18481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'ubifs_tnc_lookup()' returns us the right direntry. 18491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 18501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_tnc_lookup(c, key, node); 18511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 18521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 18531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy len = le16_to_cpu(dent->nlen); 18551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nm->len == len && !memcmp(dent->name, nm->name, len)) 18561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 18571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 18591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Unluckily, there are hash collisions and we have to iterate over 18601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * them look at each direntry with colliding name hash sequentially. 18611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 18621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return do_lookup_nm(c, key, node, nm); 18631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 18641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 18661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * correct_parent_keys - correct parent znodes' keys. 18671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 18681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode to correct parent znodes for 18691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 18701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is a helper function for 'tnc_insert()'. When the key of the leftmost 18711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * zbranch changes, keys of parent znodes have to be corrected. This helper 18721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * function is called in such situations and corrects the keys if needed. 18731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 18741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void correct_parent_keys(const struct ubifs_info *c, 18751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 18761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 18771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *key, *key1; 18781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode->parent); 18801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode->iip == 0); 18811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key = &znode->zbranch[0].key; 18831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key1 = &znode->parent->zbranch[0].key; 18841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (keys_cmp(c, key, key1) < 0) { 18861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_copy(c, key, key1); 18871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = znode->parent; 18881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->alt = 1; 18891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode->parent || znode->iip) 18901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 18911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key1 = &znode->parent->zbranch[0].key; 18921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 18931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 18941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 18951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 18961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * insert_zbranch - insert a zbranch into a znode. 18971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode into which to insert 18981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: zbranch to insert 18991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: slot number to insert to 19001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 19011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is a helper function for 'tnc_insert()'. UBIFS does not allow "gaps" in 19021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode's array of zbranches and keeps zbranches consolidated, so when a new 19031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th 19041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * slot, zbranches starting from @n have to be moved right. 19051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 19061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void insert_zbranch(struct ubifs_znode *znode, 19071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct ubifs_zbranch *zbr, int n) 19081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 19091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int i; 19101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(ubifs_zn_dirty(znode)); 19121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->level) { 19141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = znode->child_cnt; i > n; i--) { 19151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i] = znode->zbranch[i - 1]; 19161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->zbranch[i].znode) 19171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i].znode->iip = i; 19181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 19191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->znode) 19201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->znode->iip = n; 19211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 19221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = znode->child_cnt; i > n; i--) 19231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i] = znode->zbranch[i - 1]; 19241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[n] = *zbr; 19261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->child_cnt += 1; 19271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 19291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * After inserting at slot zero, the lower bound of the key range of 19301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * this znode may have changed. If this znode is subsequently split 19311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * then the upper bound of the key range may change, and furthermore 19321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * it could change to be lower than the original lower bound. If that 19331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * happens, then it will no longer be possible to find this znode in the 19341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * TNC using the key from the index node on flash. That is bad because 19351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if it is not found, we will assume it is obsolete and may overwrite 19361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * it. Then if there is an unclean unmount, we will start using the 19371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * old index which will be broken. 19381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 19391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * So we first mark znodes that have insertions at slot zero, and then 19401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if they are split we add their lnum/offs to the old_idx tree. 19411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 19421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n == 0) 19431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->alt = 1; 19441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 19451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 19471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_insert - insert a node into TNC. 19481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 19491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode to insert into 19501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @zbr: branch to insert 19511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: slot number to insert new zbranch to 19521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 19531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function inserts a new node described by @zbr into znode @znode. If 19541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode does not have a free slot for new zbranch, it is split. Parent znodes 19551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * are splat as well if needed. Returns zero in case of success or a negative 19561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * error code in case of failure. 19571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 19581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, 19591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr, int n) 19601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 19611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zn, *zi, *zp; 19621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int i, keep, move, appending = 0; 19632242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter union ubifs_key *key = &zbr->key, *key1; 19641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(n >= 0 && n <= c->fanout); 19661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Implement naive insert for now */ 19681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyagain: 19691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 19701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->child_cnt < c->fanout) { 19711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(n != c->fanout); 1972515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level); 19731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy insert_zbranch(znode, zbr, n); 19751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Ensure parent's key is correct */ 19771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n == 0 && zp && znode->iip == 0) 19781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy correct_parent_keys(c, znode); 19791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 19811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 19821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 19841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Unfortunately, @znode does not have more empty slots and we have to 19851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * split it. 19861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 1987515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "splitting level %d, key ", znode->level); 19881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->alt) 19901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 19911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We can no longer be sure of finding this znode by key, so we 19921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * record it in the old_idx tree. 19931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 19941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ins_clr_old_idx_znode(c, znode); 19951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 19961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn = kzalloc(c->max_znode_sz, GFP_NOFS); 19971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zn) 19981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOMEM; 19991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->parent = zp; 20001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->level = znode->level; 20011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Decide where to split */ 20032242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (znode->level == 0 && key_type(c, key) == UBIFS_DATA_KEY) { 20042242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter /* Try not to split consecutive data keys */ 20052242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (n == c->fanout) { 20062242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key1 = &znode->zbranch[n - 1].key; 20072242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (key_inum(c, key1) == key_inum(c, key) && 20082242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key_type(c, key1) == UBIFS_DATA_KEY) 20092242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter appending = 1; 20102242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter } else 20112242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter goto check_split; 20122242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter } else if (appending && n != c->fanout) { 20132242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter /* Try not to split consecutive data keys */ 20142242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter appending = 0; 20152242c689ecc390fb4719f595751351d1ecc5c409Adrian Huntercheck_split: 20162242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (n >= (c->fanout + 1) / 2) { 20172242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key1 = &znode->zbranch[0].key; 20182242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (key_inum(c, key1) == key_inum(c, key) && 20192242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key_type(c, key1) == UBIFS_DATA_KEY) { 20202242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key1 = &znode->zbranch[n].key; 20212242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (key_inum(c, key1) != key_inum(c, key) || 20222242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter key_type(c, key1) != UBIFS_DATA_KEY) { 20232242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter keep = n; 20242242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter move = c->fanout - keep; 20252242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter zi = znode; 20262242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter goto do_split; 20272242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter } 20282242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter } 20292242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter } 20301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 20311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (appending) { 20331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy keep = c->fanout; 20341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy move = 0; 20351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else { 20361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy keep = (c->fanout + 1) / 2; 20371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy move = c->fanout - keep; 20381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 20391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 20411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Although we don't at present, we could look at the neighbors and see 20421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if we can move some zbranches there. 20431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 20441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n < keep) { 20461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Insert into existing znode */ 20471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi = znode; 20481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy move += 1; 20491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy keep -= 1; 20501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else { 20511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Insert into new znode */ 20521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi = zn; 20531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n -= keep; 20541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Re-parent */ 20551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zn->level != 0) 20561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->znode->parent = zn; 20571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 20581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20592242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunterdo_split: 20602242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter 20611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(DIRTY_ZNODE, &zn->flags); 20621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->dirty_zn_cnt); 20631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->child_cnt = move; 20651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->child_cnt = keep; 20661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("moving %d, keeping %d", move, keep); 20681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Move zbranch */ 20701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = 0; i < move; i++) { 20711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->zbranch[i] = znode->zbranch[keep + i]; 20721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Re-parent */ 20731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zn->level != 0) 20741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zn->zbranch[i].znode) { 20751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->zbranch[i].znode->parent = zn; 20761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->zbranch[i].znode->iip = i; 20771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 20781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 20791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Insert new key and branch */ 2081515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level); 20821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy insert_zbranch(zi, zbr, n); 20841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Insert new znode (produced by spitting) into the parent */ 20861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zp) { 20872242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter if (n == 0 && zi == znode && znode->iip == 0) 20882242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter correct_parent_keys(c, znode); 20892242c689ecc390fb4719f595751351d1ecc5c409Adrian Hunter 20901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Locate insertion point */ 20911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = znode->iip + 1; 20921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 20931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Tail recursion */ 20941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->key = zn->zbranch[0].key; 20951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->znode = zn; 20961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = 0; 20971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = 0; 20981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = 0; 20991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zp; 21001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto again; 21021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 21031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* We have to split root znode */ 21051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("creating new zroot at level %d", znode->level + 1); 21061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi = kzalloc(c->max_znode_sz, GFP_NOFS); 21081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!zi) 21091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return -ENOMEM; 21101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->child_cnt = 2; 21121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->level = znode->level + 1; 21131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(DIRTY_ZNODE, &zi->flags); 21151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->dirty_zn_cnt); 21161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[0].key = znode->zbranch[0].key; 21181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[0].znode = znode; 21191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[0].lnum = c->zroot.lnum; 21201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[0].offs = c->zroot.offs; 21211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[0].len = c->zroot.len; 21221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[1].key = zn->zbranch[0].key; 21231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zi->zbranch[1].znode = zn; 21241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.lnum = 0; 21261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.offs = 0; 21271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.len = 0; 21281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.znode = zi; 21291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->parent = zi; 21311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn->iip = 1; 21321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->parent = zi; 21331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->iip = 0; 21341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 21361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 21371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 21391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_add - add a node to TNC. 21401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 21411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to add 21421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of node 21431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: node offset 21441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @len: node length 21451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 21461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function adds a node with key @key to TNC. The node may be new or it may 21471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * obsolete some existing one. Returns %0 on success or negative error code on 21481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * failure. 21491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 21501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, 21511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int offs, int len) 21521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 21531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int found, n, err = 0; 21541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 21551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 2157515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "%d:%d, len %d, key ", lnum, offs, len); 21581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = lookup_level0_dirty(c, key, &znode, &n); 21591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) { 21601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch zbr; 21611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.znode = NULL; 21631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.lnum = lnum; 21641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.offs = offs; 21651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.len = len; 21661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_copy(c, key, &zbr.key); 21671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_insert(c, znode, &zbr, n + 1); 21681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (found == 1) { 21691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr = &znode->zbranch[n]; 21701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(zbr); 21721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, zbr->lnum, zbr->len); 21731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = lnum; 21741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = offs; 21751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = len; 21761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 21771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 21781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 21791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 21801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 21811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 21831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 21841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 21851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 21861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_replace - replace a node in the TNC only if the old node is found. 21871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 21881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to add 21891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @old_lnum: LEB number of old node 21901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @old_offs: old node offset 21911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of node 21921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: node offset 21931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @len: node length 21941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 21951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function replaces a node with key @key in the TNC only if the old node 21961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is found. This function is called by garbage collection when node are moved. 21971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success or negative error code on failure. 21981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 21991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, 22001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int old_lnum, int old_offs, int lnum, int offs, int len) 22011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 22021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int found, n, err = 0; 22031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 22041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 2206515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "old LEB %d:%d, new LEB %d:%d, len %d, key ", old_lnum, 2207515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy old_offs, lnum, offs, len); 22081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = lookup_level0_dirty(c, key, &znode, &n); 22091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) { 22101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 22111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 22121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found == 1) { 22151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr = &znode->zbranch[n]; 22161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = 0; 22181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zbr->lnum == old_lnum && zbr->offs == old_offs) { 22191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(zbr); 22201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, zbr->lnum, zbr->len); 22211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 22221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 22231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = lnum; 22241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = offs; 22251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = len; 22261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = 1; 22271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else if (is_hash_key(c, key)) { 22281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = resolve_collision_directly(c, key, &znode, &n, 22291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy old_lnum, old_offs); 22301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("rc returned %d, znode %p, n %d, LEB %d:%d", 22311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found, znode, n, old_lnum, old_offs); 22321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) { 22331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 22341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 22351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found) { 22381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Ensure the znode is dirtied */ 22391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext || !ubifs_zn_dirty(znode)) { 2240f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 2241f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy if (IS_ERR(znode)) { 2242f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy err = PTR_ERR(znode); 2243f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy goto out_unlock; 2244f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy } 22451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 22471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(zbr); 22481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, zbr->lnum, 22491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len); 22501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 22511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 22521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = lnum; 22531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = offs; 22541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = len; 22551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) 22601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, lnum, len); 22611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 22631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 22641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 22661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 22671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 22681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 22691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 22711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_add_nm - add a "hashed" node to TNC. 22721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 22731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to add 22741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of node 22751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: node offset 22761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @len: node length 22771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: node name 22781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 22791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is the same as 'ubifs_tnc_add()' but it should be used with keys which 22801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * may have collisions, like directory entry keys. 22811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 22821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, 22831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs, int len, const struct qstr *nm) 22841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 22851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int found, n, err = 0; 22861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 22871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 2289515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "LEB %d:%d, name '%.*s', key ", 2290515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy lnum, offs, nm->len, nm->name); 22911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = lookup_level0_dirty(c, key, &znode, &n); 22921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) { 22931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 22941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 22951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 22961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 22971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found == 1) { 22981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->replaying) 22991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = fallible_resolve_collision(c, key, &znode, &n, 23001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nm, 1); 23011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 23021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = resolve_collision(c, key, &znode, &n, nm); 23031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("rc returned %d, znode %p, n %d", found, znode, n); 23041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) { 23051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 23061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 23071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Ensure the znode is dirtied */ 23101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext || !ubifs_zn_dirty(znode)) { 2311f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 2312f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy if (IS_ERR(znode)) { 2313f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy err = PTR_ERR(znode); 2314f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy goto out_unlock; 2315f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy } 23161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found == 1) { 23191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr = &znode->zbranch[n]; 23201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(zbr); 23221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, zbr->lnum, zbr->len); 23231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->lnum = lnum; 23241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->offs = offs; 23251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr->len = len; 23261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 23271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) { 23311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch zbr; 23321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.znode = NULL; 23341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.lnum = lnum; 23351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.offs = offs; 23361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr.len = len; 23371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_copy(c, key, &zbr.key); 23381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_insert(c, znode, &zbr, n + 1); 23391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 23401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 23411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->replaying) { 23421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 23431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We did not find it in the index so there may be a 23441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dangling branch still in the index. So we remove it 23451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * by passing 'ubifs_tnc_remove_nm()' the same key but 23461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * an unmatchable name. 23471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 234826fe575028703948880fce4355a210c76bb0536eLinus Torvalds struct qstr noname = { .name = "" }; 23491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 23511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 23521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 23531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 23541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ubifs_tnc_remove_nm(c, key, &noname); 23551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 23591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 23601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 23611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 23621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 23631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 23641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 23661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_delete - delete a znode form TNC. 23671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 23681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode to delete from 23691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @n: zbranch slot number to delete 23701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 23711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function deletes a leaf node from @n-th slot of @znode. Returns zero in 23721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * case of success and a negative error code in case of failure. 23731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 23741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n) 23751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 23761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 23771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *zp; 23781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int i, err; 23791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Delete without merge for now */ 23811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode->level == 0); 23821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(n >= 0 && n < c->fanout); 2383515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(&znode->zbranch[n].key, "deleting key "); 23841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 23861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(zbr); 23871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, zbr->lnum, zbr->len); 23891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 2390edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_znode(c, znode); 23911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 23921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 23931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* We do not "gap" zbranch slots */ 23951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = n; i < znode->child_cnt - 1; i++) 23961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i] = znode->zbranch[i + 1]; 23971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->child_cnt -= 1; 23981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 23991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->child_cnt > 0) 24001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 24011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 24031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This was the last zbranch, we have to delete this znode from the 24041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * parent. 24051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 24061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy do { 2408f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy ubifs_assert(!ubifs_zn_obsolete(znode)); 24091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(ubifs_zn_dirty(znode)); 24101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode->parent; 24121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = znode->iip; 24131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_dec(&c->dirty_zn_cnt); 24151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = insert_old_idx_znode(c, znode); 24171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 24181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 24191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext) { 24211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(OBSOLETE_ZNODE, &znode->flags); 24221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->clean_zn_cnt); 24231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&ubifs_clean_zn_cnt); 24241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 24251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(znode); 24261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zp; 24271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } while (znode->child_cnt == 1); /* while removing last child */ 24281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Remove from znode, entry n - 1 */ 24301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->child_cnt -= 1; 24311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(znode->level != 0); 24321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = n; i < znode->child_cnt; i++) { 24331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i] = znode->zbranch[i + 1]; 24341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->zbranch[i].znode) 24351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i].znode->iip = i; 24361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 24371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 24391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * If this is the root and it has only 1 child then 24401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collapse the tree. 24411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 24421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode->parent) { 24431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (znode->child_cnt == 1 && znode->level != 0) { 24441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zp = znode; 24451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[0]; 24461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, 0); 24471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 24481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 24491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_znode(c, zbr); 24501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 24511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 24521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->parent = NULL; 24531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->iip = 0; 24541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.len) { 24551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = insert_old_idx(c, c->zroot.lnum, 24561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.offs); 24571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 24581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 24591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 24601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.lnum = zbr->lnum; 24611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.offs = zbr->offs; 24621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.len = zbr->len; 24631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy c->zroot.znode = znode; 2464f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy ubifs_assert(!ubifs_zn_obsolete(zp)); 2465f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy ubifs_assert(ubifs_zn_dirty(zp)); 24661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_dec(&c->dirty_zn_cnt); 24671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (zp->cnext) { 24691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy __set_bit(OBSOLETE_ZNODE, &zp->flags); 24701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&c->clean_zn_cnt); 24711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy atomic_long_inc(&ubifs_clean_zn_cnt); 24721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 24731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(zp); 24741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 24751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 24761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 24781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 24791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 24811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_remove - remove an index entry of a node. 24821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 24831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of node 24841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 24851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success or negative error code on failure. 24861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 24871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key) 24881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 24891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int found, n, err = 0; 24901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 24911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 24921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 2493515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "key "); 24941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = lookup_level0_dirty(c, key, &znode, &n); 24951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) { 24961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = found; 24971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 24981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 24991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found == 1) 25001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_delete(c, znode, n); 25011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 25021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 25031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 25051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 25061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 25071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 25081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 25101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_remove_nm - remove an index entry for a "hashed" node. 25111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 25121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of node 25131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: directory entry name 25141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 25151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Returns %0 on success or negative error code on failure. 25161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 25171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, 25181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm) 25191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 25201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n, err; 25211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 25221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 2524515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "%.*s, key ", nm->len, nm->name); 25251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = lookup_level0_dirty(c, key, &znode, &n); 25261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 25271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 25281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 25301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->replaying) 25311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = fallible_resolve_collision(c, key, &znode, &n, 25321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nm, 0); 25331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 25341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = resolve_collision(c, key, &znode, &n, nm); 25351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); 25361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 25371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 25381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 25391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Ensure the znode is dirtied */ 25401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext || !ubifs_zn_dirty(znode)) { 2541c43615702f9c5957981693a4d966ed81d8fc1eccArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 2542c43615702f9c5957981693a4d966ed81d8fc1eccArtem Bityutskiy if (IS_ERR(znode)) { 2543c43615702f9c5957981693a4d966ed81d8fc1eccArtem Bityutskiy err = PTR_ERR(znode); 2544c43615702f9c5957981693a4d966ed81d8fc1eccArtem Bityutskiy goto out_unlock; 2545c43615702f9c5957981693a4d966ed81d8fc1eccArtem Bityutskiy } 25461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 25471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_delete(c, znode, n); 25481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 25491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 25501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 25521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 25531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 25541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 25551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 25561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 25571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 25591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * key_in_range - determine if a key falls within a range of keys. 25601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 25611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key to check 25621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @from_key: lowest key in range 25631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @to_key: highest key in range 25641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 25651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %1 if the key is in range and %0 otherwise. 25661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 25671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int key_in_range(struct ubifs_info *c, union ubifs_key *key, 25681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *from_key, union ubifs_key *to_key) 25691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 25701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, from_key) < 0) 25711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 25721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, to_key) > 0) 25731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 25741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; 25751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 25761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 25781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_remove_range - remove index entries in range. 25791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 25801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @from_key: lowest key to remove 25811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @to_key: highest key to remove 25821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 25831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function removes index entries starting at @from_key and ending at 25841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @to_key. This function returns zero in case of success and a negative error 25851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * code in case of failure. 25861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 25871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, 25881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *to_key) 25891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 25901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int i, n, k, err = 0; 25911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 25921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *key; 25931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 25941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 25951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 25961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Find first level 0 znode that contains keys to remove */ 25971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_lookup_level0(c, from_key, &znode, &n); 25981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 25991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 26021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key = from_key; 26031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else { 26041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &n); 26051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) { 26061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = 0; 26071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 26101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key = &znode->zbranch[n].key; 26121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!key_in_range(c, key, from_key, to_key)) { 26131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = 0; 26141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Ensure the znode is dirtied */ 26191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->cnext || !ubifs_zn_dirty(znode)) { 2620f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 2621f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy if (IS_ERR(znode)) { 2622f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy err = PTR_ERR(znode); 2623f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy goto out_unlock; 2624f92b982680e4b4149c559789a54e1e9db190752aArtem Bityutskiy } 26251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Remove all keys in range except the first */ 26281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = n + 1, k = 0; i < znode->child_cnt; i++, k++) { 26291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key = &znode->zbranch[i].key; 26301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!key_in_range(c, key, from_key, to_key)) 26311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 26321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lnc_free(&znode->zbranch[i]); 26331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_add_dirt(c, znode->zbranch[i].lnum, 26341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i].len); 26351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 2636edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_znode(c, znode); 26371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 2639515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "removing key "); 26401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (k) { 26421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy for (i = n + 1 + k; i < znode->child_cnt; i++) 26431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[i - k] = znode->zbranch[i]; 26441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->child_cnt -= k; 26451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Now delete the first */ 26481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_delete(c, znode, n); 26491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 26501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 26511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 26541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) 26551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = dbg_check_tnc(c, 0); 26561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 26571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 26581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 26591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 26611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_remove_ino - remove an inode from TNC. 26621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 26631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inum: inode number to remove 26641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 26651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function remove inode @inum and all the extended attributes associated 26661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * with the anode from TNC and returns zero in case of success or a negative 26671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * error code in case of failure. 26681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 26691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum) 26701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 26711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key key1, key2; 26721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_dent_node *xent, *pxent = NULL; 26731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct qstr nm = { .name = NULL }; 26741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2675e84461ad9c4f0ff91ab8553596acdb7bf5522df4Artem Bityutskiy dbg_tnc("ino %lu", (unsigned long)inum); 26761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 26781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Walk all extended attribute entries and remove them together with 26791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * corresponding extended attribute inodes. 26801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 26811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lowest_xent_key(c, &key1, inum); 26821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 26831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ino_t xattr_inum; 26841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 26851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy xent = ubifs_tnc_next_ent(c, &key1, &nm); 26871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(xent)) { 26881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = PTR_ERR(xent); 26891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 26901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 26911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 26921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 26931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy xattr_inum = le64_to_cpu(xent->inum); 2695e84461ad9c4f0ff91ab8553596acdb7bf5522df4Artem Bityutskiy dbg_tnc("xent '%s', ino %lu", xent->name, 2696e84461ad9c4f0ff91ab8553596acdb7bf5522df4Artem Bityutskiy (unsigned long)xattr_inum); 26971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 26981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nm.name = xent->name; 26991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nm.len = le16_to_cpu(xent->nlen); 27001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_tnc_remove_nm(c, &key1, &nm); 27011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 27021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(xent); 27031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 27041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lowest_ino_key(c, &key1, xattr_inum); 27071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy highest_ino_key(c, &key2, xattr_inum); 27081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_tnc_remove_range(c, &key1, &key2); 27091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 27101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(xent); 27111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 27121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(pxent); 27151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy pxent = xent; 27161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_read(c, &xent->key, &key1); 27171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(pxent); 27201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy lowest_ino_key(c, &key1, inum); 27211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy highest_ino_key(c, &key2, inum); 27221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ubifs_tnc_remove_range(c, &key1, &key2); 27241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 27251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 27271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_next_ent - walk directory or extended attribute entries. 27281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 27291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of last entry 27301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm: name of last entry found or %NULL 27311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 27321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function finds and reads the next directory or extended attribute entry 27331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * after the given key (@key) if there is one. @nm is used to resolve 27341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collisions. 27351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 27361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * If the name of the current entry is not known and only the key is known, 27371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @nm->name has to be %NULL. In this case the semantics of this function is a 27381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * little bit different and it returns the entry corresponding to this key, not 27391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the next one. If the key was not found, the closest "right" entry is 27401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * returned. 27411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 27421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * If the fist entry has to be found, @key has to contain the lowest possible 27431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * key value for this inode and @name has to be %NULL. 27441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 27451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns the found directory or extended attribute entry node 27461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * in case of success, %-ENOENT is returned if no entry was found, and a 27471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * negative error code is returned in case of failure. 27481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 27491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystruct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, 27501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *key, 27511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const struct qstr *nm) 27521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 27531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n, err, type = key_type(c, key); 27541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 27551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_dent_node *dent; 27561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 27571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *dkey; 27581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2759515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)"); 27601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(is_hash_key(c, key)); 27611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 27631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = ubifs_lookup_level0(c, key, &znode, &n); 27641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 27651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 27661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (nm->name) { 27681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 27691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Handle collisions */ 27701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = resolve_collision(c, key, &znode, &n, nm); 27711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dbg_tnc("rc returned %d, znode %p, n %d", 27721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err, znode, n); 27731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err < 0)) 27741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 27751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Now find next entry */ 27781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &n); 27791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err)) 27801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 27811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else { 27821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 27831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The full name of the entry was not given, in which case the 27841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * behavior of this function is a little different and it 27851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * returns current entry, not the next one. 27861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 27871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!err) { 27881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 27891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * However, the given key does not exist in the TNC 27901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tree and @znode/@n variables contain the closest 27911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * "preceding" element. Switch to the next one. 27921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 27931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &n); 27941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 27951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 27961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 27981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 27991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 28001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dent = kmalloc(zbr->len, GFP_NOFS); 28011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(!dent)) { 28021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -ENOMEM; 28031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 28041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 28051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 28071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The above 'tnc_next()' call could lead us to the next inode, check 28081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * this. 28091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 28101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy dkey = &zbr->key; 28111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (key_inum(c, dkey) != key_inum(c, key) || 28121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy key_type(c, dkey) != type) { 28131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = -ENOENT; 28141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 28151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 28161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_read_node_nm(c, zbr, dent); 28181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unlikely(err)) 28191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_free; 28201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 28221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return dent; 28231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_free: 28251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(dent); 28261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 28271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 28281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(err); 28291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 28301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 28321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * tnc_destroy_cnext - destroy left-over obsolete znodes from a failed commit. 28331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 28341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 28351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Destroy left-over obsolete znodes from a failed commit. 28361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 28371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void tnc_destroy_cnext(struct ubifs_info *c) 28381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 28391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *cnext; 28401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!c->cnext) 28421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return; 28431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(c->cmt_state == COMMIT_BROKEN); 28441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy cnext = c->cnext; 28451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy do { 28461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode = cnext; 28471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy cnext = cnext->cnext; 2849f42eed7cba7f83197b0ffbb023e7d89a0b2fd71dArtem Bityutskiy if (ubifs_zn_obsolete(znode)) 28501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(znode); 28511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } while (cnext && cnext != c->cnext); 28521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 28531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 28551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_close - close TNC subsystem and free all related resources. 28561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 28571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 28581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyvoid ubifs_tnc_close(struct ubifs_info *c) 28591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 28601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy tnc_destroy_cnext(c); 28611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.znode) { 2862380347e9ca76828ee9bac63cfc338ca99cdee4f3hujianyang long n, freed; 2863837072377034d0a0b18b851d1ab95676b245cc0aArtem Bityutskiy 2864837072377034d0a0b18b851d1ab95676b245cc0aArtem Bityutskiy n = atomic_long_read(&c->clean_zn_cnt); 2865380347e9ca76828ee9bac63cfc338ca99cdee4f3hujianyang freed = ubifs_destroy_tnc_subtree(c->zroot.znode); 2866380347e9ca76828ee9bac63cfc338ca99cdee4f3hujianyang ubifs_assert(freed == n); 2867837072377034d0a0b18b851d1ab95676b245cc0aArtem Bityutskiy atomic_long_sub(n, &ubifs_clean_zn_cnt); 28681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 28691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(c->gap_lebs); 28701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy kfree(c->ilebs); 28711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy destroy_old_idx(c); 28721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 28731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 28751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * left_znode - get the znode to the left. 28761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 28771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode 28781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 28791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns a pointer to the znode to the left of @znode or NULL if 28801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * there is not one. A negative error code is returned on failure. 28811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 28821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *left_znode(struct ubifs_info *c, 28831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 28841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 28851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int level = znode->level; 28861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 28881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n = znode->iip - 1; 28891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 28901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Go up until we can go left */ 28911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = znode->parent; 28921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 28931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 28941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n >= 0) { 28951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Now go down the rightmost branch to 'level' */ 28961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, n); 28971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 28981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 28991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (znode->level != level) { 29001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = znode->child_cnt - 1; 29011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, n); 29021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 29031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 29061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 29101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 29111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 29121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * right_znode - get the znode to the right. 29131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 29141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @znode: znode 29151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 29161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns a pointer to the znode to the right of @znode or NULL 29171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if there is not one. A negative error code is returned on failure. 29181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 29191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *right_znode(struct ubifs_info *c, 29201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode) 29211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 29221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int level = znode->level; 29231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 29241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 29251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n = znode->iip + 1; 29261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 29271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Go up until we can go right */ 29281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = znode->parent; 29291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 29301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 29311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n < znode->child_cnt) { 29321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Now go down the leftmost branch to 'level' */ 29331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, n); 29341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 29351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (znode->level != level) { 29371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, 0); 29381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 29391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 29421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 29461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 29471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 29481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lookup_znode - find a particular indexing node from TNC. 29491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 29501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: index node key to lookup 29511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @level: index node level 29521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: index node LEB number 29531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: index node offset 29541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 29551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function searches an indexing node by its first key @key and its 29561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * address @lnum:@offs. It looks up the indexing tree by pulling all indexing 2957ba2f48f70efcf4d82deafb2be327ed64b1f043a5Artem Bityutskiy * nodes it traverses to TNC. This function is called for indexing nodes which 29581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * were found on the media by scanning, for example when garbage-collecting or 29591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * when doing in-the-gaps commit. This means that the indexing node which is 29601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * looked for does not have to have exactly the same leftmost key @key, because 29611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the leftmost key may have been changed, in which case TNC will contain a 29621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirty znode which still refers the same @lnum:@offs. This function is clever 29631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * enough to recognize such indexing nodes. 29641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 29651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, if a znode was deleted or changed too much, then this function will 29661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * not find it. For situations like this UBIFS has the old index RB-tree 29671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * (indexed by @lnum:@offs). 29681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 29691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns a pointer to the znode found or %NULL if it is not 29701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * found. A negative error code is returned on failure. 29711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 29721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct ubifs_znode *lookup_znode(struct ubifs_info *c, 29731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy union ubifs_key *key, int level, 29741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs) 29751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 29761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode, *zn; 29771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n, nn; 29781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 2979ba2f48f70efcf4d82deafb2be327ed64b1f043a5Artem Bityutskiy ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY); 2980ba2f48f70efcf4d82deafb2be327ed64b1f043a5Artem Bityutskiy 29811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 29821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The arguments have probably been read off flash, so don't assume 29831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * they are valid. 29841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 29851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (level < 0) 29861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ERR_PTR(-EINVAL); 29871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 29881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Get the root znode */ 29891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = c->zroot.znode; 29901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) { 29911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = ubifs_load_znode(c, &c->zroot, NULL, 0); 29921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 29931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 29951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Check if it is the one we are looking for */ 29961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (c->zroot.lnum == lnum && c->zroot.offs == offs) 29971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 29981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Descend to the parent level i.e. (level + 1) */ 29991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (level >= znode->level) 30001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 30011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 30021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_search_zbranch(c, znode, key, &n); 30031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n < 0) { 30041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 30051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * We reached a znode where the leftmost key is greater 30061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * than the key we are searching for. This is the same 30071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * situation as the one described in a huge comment at 30081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the end of the 'ubifs_lookup_level0()' function. And 30091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * for exactly the same reasons we have to try to look 30101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * left before giving up. 30111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 30121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = left_znode(c, znode); 30131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 30141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 30151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 30161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 30171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_search_zbranch(c, znode, key, &n); 30181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy ubifs_assert(n >= 0); 30191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->level == level + 1) 30211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 30221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = get_znode(c, znode, n); 30231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 30241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 30251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Check if the child is the one we are looking for */ 30271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->zbranch[n].lnum == lnum && znode->zbranch[n].offs == offs) 30281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return get_znode(c, znode, n); 30291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* If the key is unique, there is nowhere else to look */ 30301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!is_hash_key(c, key)) 30311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 30321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 30331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The key is not unique and so may be also in the znodes to either 30341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * side. 30351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 30361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn = znode; 30371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = n; 30381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look left */ 30391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 30401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Move one branch to the left */ 30411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (n) 30421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n -= 1; 30431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else { 30441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = left_znode(c, znode); 30451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 30461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 30471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 30481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 30491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = znode->child_cnt - 1; 30501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Check it */ 30521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->zbranch[n].lnum == lnum && 30531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[n].offs == offs) 30541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return get_znode(c, znode, n); 30551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Stop if the key is less than the one we are looking for */ 30561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[n].key, key) < 0) 30571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 30581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Back to the middle */ 30601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zn; 30611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = nn; 30621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look right */ 30631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 30641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Move one branch to the right */ 30651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (++n >= znode->child_cnt) { 30661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = right_znode(c, znode); 30671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 30681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 30691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 30701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return znode; 30711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = 0; 30721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Check it */ 30741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (znode->zbranch[n].lnum == lnum && 30751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode->zbranch[n].offs == offs) 30761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return get_znode(c, znode, n); 30771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Stop if the key is greater than the one we are looking for */ 30781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, &znode->zbranch[n].key, key) > 0) 30791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 30801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 30811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return NULL; 30821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 30831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 30841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 30851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is_idx_node_in_tnc - determine if an index node is in the TNC. 30861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 30871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: key of index node 30881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @level: index node level 30891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: LEB number of index node 30901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: offset of index node 30911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 30921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %0 if the index node is not referred to in the TNC, %1 30931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if the index node is referred to in the TNC and the corresponding znode is 30941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * dirty, %2 if an index node is referred to in the TNC and the corresponding 30951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * znode is clean, and a negative error code in case of failure. 30961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 30971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, the @key argument has to be the key of the first child. Also note, 30981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * this function relies on the fact that 0:0 is never a valid LEB number and 30991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * offset for a main-area node. 31001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 31011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level, 31021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs) 31031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 31041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 31051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 31061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = lookup_znode(c, key, level, lnum, offs); 31071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 31081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 31091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) 31101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return PTR_ERR(znode); 31111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 31121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return ubifs_zn_dirty(znode) ? 1 : 2; 31131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 31141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 31151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 31161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * is_leaf_node_in_tnc - determine if a non-indexing not is in the TNC. 31171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 31181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: node key 31191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: node LEB number 31201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: node offset 31211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 31221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %1 if the node is referred to in the TNC, %0 if it is 31231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * not, and a negative error code in case of failure. 31241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 31251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Note, this function relies on the fact that 0:0 is never a valid LEB number 31261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * and offset for a main-area node. 31271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 31281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int is_leaf_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, 31291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs) 31301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 31311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_zbranch *zbr; 31321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode, *zn; 31331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int n, found, err, nn; 31341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy const int unique = !is_hash_key(c, key); 31351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 31361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy found = ubifs_lookup_level0(c, key, &znode, &n); 31371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (found < 0) 31381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return found; /* Error code */ 31391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!found) 31401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 31411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 31421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (lnum == zbr->lnum && offs == zbr->offs) 31431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; /* Found it */ 31441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (unique) 31451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 31461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* 31471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Because the key is not unique, we have to look left 31481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * and right as well 31491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 31501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zn = znode; 31511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy nn = n; 31521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look left */ 31531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 31541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_prev(c, &znode, &n); 31551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 31561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 31571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) 31581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 31591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, &znode->zbranch[n].key)) 31601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 31611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 31621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (lnum == zbr->lnum && offs == zbr->offs) 31631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; /* Found it */ 31641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 31651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* Look right */ 31661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = zn; 31671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy n = nn; 31681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy while (1) { 31691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = tnc_next(c, &znode, &n); 31701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err) { 31711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == -ENOENT) 31721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 31731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 31741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 31751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (keys_cmp(c, key, &znode->zbranch[n].key)) 31761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy break; 31771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy zbr = &znode->zbranch[n]; 31781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (lnum == zbr->lnum && offs == zbr->offs) 31791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 1; /* Found it */ 31801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 31811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return 0; 31821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 31831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 31841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 31851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_tnc_has_node - determine whether a node is in the TNC. 31861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 31871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: node key 31881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @level: index node level (if it is an index node) 31891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: node LEB number 31901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: node offset 31911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @is_idx: non-zero if the node is an index node 31921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 31931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns %1 if the node is in the TNC, %0 if it is not, and a 31941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * negative error code in case of failure. For index nodes, @key has to be the 31951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * key of the first child. An index node is considered to be in the TNC only if 31961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the corresponding znode is clean or has not been loaded. 31971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 31981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level, 31991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs, int is_idx) 32001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 32011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err; 32021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 32031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 32041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (is_idx) { 32051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = is_idx_node_in_tnc(c, key, level, lnum, offs); 32061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err < 0) 32071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 32081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (err == 1) 32091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* The index node was found but it was dirty */ 32101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = 0; 32111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else if (err == 2) 32121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy /* The index node was found and it was clean */ 32131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = 1; 32141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy else 32151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy BUG_ON(err != 0); 32161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } else 32171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = is_leaf_node_in_tnc(c, key, lnum, offs); 32181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 32191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 32201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 32211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 32221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 32231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 32241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/** 32251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_dirty_idx_node - dirty an index node. 32261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object 32271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @key: index node key 32281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @level: index node level 32291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @lnum: index node LEB number 32301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @offs: index node offset 32311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 32321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function loads and dirties an index node so that it can be garbage 32331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collected. The @key argument has to be the key of the first child. This 32341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * function relies on the fact that 0:0 is never a valid LEB number and offset 32351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * for a main-area node. Returns %0 on success and a negative error code on 32361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * failure. 32371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */ 32381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_dirty_idx_node(struct ubifs_info *c, union ubifs_key *key, int level, 32391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int lnum, int offs) 32401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{ 32411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy struct ubifs_znode *znode; 32421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy int err = 0; 32431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 32441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_lock(&c->tnc_mutex); 32451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = lookup_znode(c, key, level, lnum, offs); 32461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (!znode) 32471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 32481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) { 32491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = PTR_ERR(znode); 32501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 32511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 32521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy znode = dirty_cow_bottom_up(c, znode); 32531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy if (IS_ERR(znode)) { 32541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy err = PTR_ERR(znode); 32551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy goto out_unlock; 32561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy } 32571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy 32581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_unlock: 32591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 32601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy return err; 32611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy} 3262e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3263e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy/** 3264e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * dbg_check_inode_size - check if inode size is correct. 3265e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * @c: UBIFS file-system description object 3266e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * @inum: inode number 3267e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * @size: inode size 3268e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * 3269e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * This function makes sure that the inode size (@size) is correct and it does 3270e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * not have any pages beyond @size. Returns zero if the inode is OK, %-EINVAL 3271e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * if it has a data page beyond @size, and other negative error code in case of 3272e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy * other errors. 3273e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy */ 3274e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiyint dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, 3275e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy loff_t size) 3276e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy{ 3277e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy int err, n; 3278e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy union ubifs_key from_key, to_key, *key; 3279e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy struct ubifs_znode *znode; 3280e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy unsigned int block; 3281e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3282e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (!S_ISREG(inode->i_mode)) 3283e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy return 0; 32842b1844a8c934723134ee1ff313e51d0d281cdef1Artem Bityutskiy if (!dbg_is_chk_gen(c)) 3285e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy return 0; 3286e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3287e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; 3288e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy data_key_init(c, &from_key, inode->i_ino, block); 3289e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy highest_data_key(c, &to_key, inode->i_ino); 3290e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3291e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy mutex_lock(&c->tnc_mutex); 3292e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy err = ubifs_lookup_level0(c, &from_key, &znode, &n); 3293e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (err < 0) 3294e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy goto out_unlock; 3295e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3296e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (err) { 3297e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy key = &from_key; 3298e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy goto out_dump; 3299e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy } 3300e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3301e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy err = tnc_next(c, &znode, &n); 3302e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (err == -ENOENT) { 3303e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy err = 0; 3304e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy goto out_unlock; 3305e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy } 3306e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (err < 0) 3307e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy goto out_unlock; 3308e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3309e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy ubifs_assert(err == 0); 3310e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy key = &znode->zbranch[n].key; 3311e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy if (!key_in_range(c, key, &from_key, &to_key)) 3312e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy goto out_unlock; 3313e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3314e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiyout_dump: 3315e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy block = key_block(c, key); 3316515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy ubifs_err("inode %lu has size %lld, but there are data at offset %lld", 3317515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy (unsigned long)inode->i_ino, size, 3318515315a123af641a9533e4ff0f178c470dc08fc7Artem Bityutskiy ((loff_t)block) << UBIFS_BLOCK_SHIFT); 33194315fb4072905e45da94d51e2c1e86fa41c5fc5fArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 3320edf6be245fd34a4438646375cecb11f5feb92646Artem Bityutskiy ubifs_dump_inode(c, inode); 33217c46d0ae29ba880963db283706950de7aa86c0a0Artem Bityutskiy dump_stack(); 33224315fb4072905e45da94d51e2c1e86fa41c5fc5fArtem Bityutskiy return -EINVAL; 3323e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy 3324e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiyout_unlock: 3325e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy mutex_unlock(&c->tnc_mutex); 3326e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy return err; 3327e3c3efc243462d67ba9fa7f67620dcbc4597bf0aArtem Bityutskiy} 3328