dir.c revision 182854b46f9feb6f1b03abe747bb2beeebf2adb0
11e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* * This file is part of UBIFS.
21e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
31e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation.
41e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Copyright (C) 2006, 2007 University of Szeged, Hungary
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: Artem Bityutskiy (Битюцкий Артём)
201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *          Adrian Hunter
211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *          Zoltan Sogor
221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/*
251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This file implements directory operations.
261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * All FS operations in this file allocate budget before writing anything to the
281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * media. If they fail to allocate it, the error is returned. The only
291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even
301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * if they unable to allocate the budget, because deletion %-ENOSPC failure is
311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * not what users are usually ready to get. UBIFS budgeting subsystem has some
321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * space reserved for these purposes.
331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * All operations in this file write all inodes which they change straight
351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * away, instead of marking them dirty. For example, 'ubifs_link()' changes
361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @i_size of the parent inode and writes the parent inode together with the
371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * target inode. This was done to simplify file-system recovery which would
381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * otherwise be very difficult to do. The only exception is rename which marks
391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * the re-named inode dirty (because its @i_ctime is updated) but does not
401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * write it, but just marks it as dirty.
411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#include "ubifs.h"
441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * inherit_flags - inherit flags of the parent inode.
471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @dir: parent inode
481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @mode: new inode mode flags
491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This is a helper function for 'ubifs_new_inode()' which inherits flag of the
511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * parent directory inode @dir. UBIFS inodes inherit the following flags:
521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on
531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *   sub-directory basis;
541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o %UBIFS_SYNC_FL - useful for the same reasons;
551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories.
561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function returns the inherited flags.
581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int inherit_flags(const struct inode *dir, int mode)
601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int flags;
621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	const struct ubifs_inode *ui = ubifs_inode(dir);
631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!S_ISDIR(dir->i_mode))
651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * The parent is not a directory, which means that an extended
671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * attribute inode is being created. No flags.
681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return 0;
701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL);
721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!S_ISDIR(mode))
731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/* The "DIRSYNC" flag only applies to directories */
741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		flags &= ~UBIFS_DIRSYNC_FL;
751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return flags;
761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * ubifs_new_inode - allocate new UBIFS inode object.
801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object
811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @dir: parent directory inode
821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @mode: inode mode flags
831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function finds an unused inode number, allocates new inode and
851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * initializes it. Returns new inode in case of success and an error code in
861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * case of failure.
871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystruct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			      int mode)
901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode;
921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *ui;
931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = new_inode(c->vfs_sb);
951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui = ubifs_inode(inode);
961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!inode)
971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return ERR_PTR(-ENOMEM);
981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
1001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and
1011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * marking them dirty in file write path (see 'file_update_time()').
1021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * UBIFS has to fully control "clean <-> dirty" transitions of inodes
1031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * to make budgeting work.
1041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
1051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_flags |= (S_NOCMTIME);
1061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_uid = current->fsuid;
1081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (dir->i_mode & S_ISGID) {
1091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_gid = dir->i_gid;
1101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (S_ISDIR(mode))
1111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			mode |= S_ISGID;
1121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else
1131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_gid = current->fsgid;
1141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_mode = mode;
1151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_mtime = inode->i_atime = inode->i_ctime =
1161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 ubifs_current_time(inode);
1171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_mapping->nrpages = 0;
1181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/* Disable readahead */
1191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_mapping->backing_dev_info = &c->bdi;
1201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	switch (mode & S_IFMT) {
1221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFREG:
1231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_mapping->a_ops = &ubifs_file_address_operations;
1241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_op = &ubifs_file_inode_operations;
1251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_fop = &ubifs_file_operations;
1261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		break;
1271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFDIR:
1281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_op  = &ubifs_dir_inode_operations;
1291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_fop = &ubifs_dir_operations;
1301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ;
1311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		break;
1321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFLNK:
1331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_op = &ubifs_symlink_inode_operations;
1341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		break;
1351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFSOCK:
1361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFIFO:
1371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFBLK:
1381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case S_IFCHR:
1391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_op  = &ubifs_file_inode_operations;
1401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		break;
1411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	default:
1421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		BUG();
1431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
1441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->flags = inherit_flags(dir, mode);
1461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_set_inode_flags(inode);
1471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (S_ISREG(mode))
1481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ui->compr_type = c->default_compr;
1491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	else
1501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ui->compr_type = UBIFS_COMPR_NONE;
1511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->synced_i_size = 0;
1521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	spin_lock(&c->cnt_lock);
1541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/* Inode number overflow is currently not supported */
1551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (c->highest_inum >= INUM_WARN_WATERMARK) {
1561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (c->highest_inum >= INUM_WATERMARK) {
1571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			spin_unlock(&c->cnt_lock);
1581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			ubifs_err("out of inode numbers");
1591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			make_bad_inode(inode);
1601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			iput(inode);
1611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return ERR_PTR(-EINVAL);
1621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
1631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_warn("running out of inode numbers (current %lu, max %d)",
1641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			   c->highest_inum, INUM_WATERMARK);
1651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
1661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_ino = ++c->highest_inum;
1681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_generation = ++c->vfs_gen;
1691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
1701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * The creation sequence number remains with this inode for its
1711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * lifetime. All nodes for this inode have a greater sequence number,
1721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * and so it is possible to distinguish obsolete nodes belonging to a
1731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * previous incarnation of the same inode number - for example, for the
1741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * purpose of rebuilding the index.
1751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
1761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->creat_sqnum = ++c->max_sqnum;
1771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	spin_unlock(&c->cnt_lock);
1781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return inode;
1791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
1801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#ifdef CONFIG_UBIFS_FS_DEBUG
1821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
1841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
1851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
1861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return 0;
1871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (le16_to_cpu(dent->nlen) != nm->len)
1881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return -EINVAL;
1891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (memcmp(dent->name, nm->name, nm->len))
1901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return -EINVAL;
1911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
1921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
1931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#else
1951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#define dbg_check_name(dent, nm) 0
1971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
1981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#endif
1991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
2011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				   struct nameidata *nd)
2021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
2031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err;
2041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	union ubifs_key key;
2051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode = NULL;
2061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_dent_node *dent;
2071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
2081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("'%.*s' in dir ino %lu",
2101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, dir->i_ino);
2111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (dentry->d_name.len > UBIFS_MAX_NLEN)
2131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return ERR_PTR(-ENAMETOOLONG);
2141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
2161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!dent)
2171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return ERR_PTR(-ENOMEM);
2181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dent_key_init(c, &key, dir->i_ino, &dentry->d_name);
2201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name);
2221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
2231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
2241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * Do not hash the direntry if parent 'i_nlink' is zero, because
2251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * this has side-effects - '->delete_inode()' call will not be
2261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * called for the parent orphan inode, because 'd_count' of its
2271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * direntry will stay 1 (it'll be negative direntry I guess)
2281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * and prevent 'iput_final()' until the dentry is destroyed due
2291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * to unmount or memory pressure.
2301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
2311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (err == -ENOENT && dir->i_nlink != 0) {
2321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			dbg_gen("not found");
2331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			goto done;
2341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
2351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out;
2361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
2371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (dbg_check_name(dent, &dentry->d_name)) {
2391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = -EINVAL;
2401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out;
2411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
2421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum));
2441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(inode)) {
2451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
2461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * This should not happen. Probably the file-system needs
2471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * checking.
2481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
2491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(inode);
2501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_err("dead directory entry '%.*s', error %d",
2511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			  dentry->d_name.len, dentry->d_name.name, err);
2521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_ro_mode(c, err);
2531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out;
2541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
2551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiydone:
2571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	kfree(dent);
2581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
2591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Note, d_splice_alias() would be required instead if we supported
2601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * NFS.
2611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
2621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_add(dentry, inode);
2631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return NULL;
2641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout:
2661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	kfree(dent);
2671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return ERR_PTR(err);
2681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
2691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_create(struct inode *dir, struct dentry *dentry, int mode,
2711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			struct nameidata *nd)
2721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
2731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode;
2741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
2751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
2761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
2771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy					.dirtied_ino = 1 };
2781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
2791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
2811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: new inode, new direntry, changing the
2821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * parent directory inode.
2831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
2841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s', mode %#x in dir ino %lu",
2861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino);
2871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
2891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
2901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
2911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = ubifs_new_inode(c, dir, mode);
2931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(inode)) {
2941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(inode);
2951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_budg;
2961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
2971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
2981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&dir_ui->ui_mutex);
2991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
3001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
3011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
3021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
3031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
3041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
3051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
3061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
3081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	insert_inode_hash(inode);
3091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_instantiate(dentry, inode);
3101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
3111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
3131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
3141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
3151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
3161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	make_bad_inode(inode);
3171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	iput(inode);
3181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_budg:
3191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
3201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_err("cannot create regular file, error %d", err);
3211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
3221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
3231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
3251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * vfs_dent_type - get VFS directory entry type.
3261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @type: UBIFS directory entry type
3271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
3281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function converts UBIFS directory entry type into VFS directory entry
3291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * type.
3301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
3311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic unsigned int vfs_dent_type(uint8_t type)
3321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
3331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	switch (type) {
3341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_REG:
3351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_REG;
3361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_DIR:
3371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_DIR;
3381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_LNK:
3391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_LNK;
3401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_BLK:
3411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_BLK;
3421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_CHR:
3431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_CHR;
3441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_FIFO:
3451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_FIFO;
3461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	case UBIFS_ITYPE_SOCK:
3471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return DT_SOCK;
3481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	default:
3491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		BUG();
3501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
3511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
3521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
3531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/*
3551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * The classical Unix view for directory is that it is a linear array of
3561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * (name, inode number) entries. Linux/VFS assumes this model as well.
3571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * Particularly, 'readdir()' call wants us to return a directory entry offset
3581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * which later may be used to continue 'readdir()'ing the directory or to
3591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this
3601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * model because directory entries are identified by keys, which may collide.
3611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
3621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * UBIFS uses directory entry hash value for directory offsets, so
3631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'seekdir()'/'telldir()' may not always work because of possible key
3641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work
3651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * properly by means of saving full directory entry name in the private field
3661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * of the file description object.
3671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
3681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This means that UBIFS cannot support NFS which requires full
3691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * 'seekdir()'/'telldir()' support.
3701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
3711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
3721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
3731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, over = 0;
3741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct qstr nm;
3751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	union ubifs_key key;
3761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_dent_node *dent;
3771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *dir = file->f_path.dentry->d_inode;
3781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
3791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
3811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
3831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
3841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * The directory was seek'ed to a senseless position or there
3851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * are no more entries.
3861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
3871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return 0;
3881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/* File positions 0 and 1 correspond to "." and ".." */
3901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (file->f_pos == 0) {
3911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_assert(!file->private_data);
3921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
3931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (over)
3941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return 0;
3951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->f_pos = 1;
3961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
3971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
3981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (file->f_pos == 1) {
3991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_assert(!file->private_data);
4001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		over = filldir(dirent, "..", 2, 1,
4011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			       parent_ino(file->f_path.dentry), DT_DIR);
4021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (over)
4031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return 0;
4041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/* Find the first entry in TNC and save it */
4061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		lowest_dent_key(c, &key, dir->i_ino);
4071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		nm.name = NULL;
4081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dent = ubifs_tnc_next_ent(c, &key, &nm);
4091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (IS_ERR(dent)) {
4101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			err = PTR_ERR(dent);
4111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			goto out;
4121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
4131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->f_pos = key_hash_flash(c, &dent->key);
4151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->private_data = dent;
4161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
4171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dent = file->private_data;
4191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!dent) {
4201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
4211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * The directory was seek'ed to and is now readdir'ed.
4221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * Find the entry corresponding to @file->f_pos or the
4231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * closest one.
4241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
4251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
4261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		nm.name = NULL;
4271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dent = ubifs_tnc_next_ent(c, &key, &nm);
4281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (IS_ERR(dent)) {
4291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			err = PTR_ERR(dent);
4301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			goto out;
4311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
4321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->f_pos = key_hash_flash(c, &dent->key);
4331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->private_data = dent;
4341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
4351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	while (1) {
4371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dbg_gen("feed '%s', ino %llu, new f_pos %#x",
4381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			dent->name, le64_to_cpu(dent->inum),
4391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			key_hash_flash(c, &dent->key));
4401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum);
4411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		nm.len = le16_to_cpu(dent->nlen);
4431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		over = filldir(dirent, dent->name, nm.len, file->f_pos,
4441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			       le64_to_cpu(dent->inum),
4451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			       vfs_dent_type(dent->type));
4461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (over)
4471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return 0;
4481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/* Switch to the next entry */
4501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		key_read(c, &dent->key, &key);
4511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		nm.name = dent->name;
4521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dent = ubifs_tnc_next_ent(c, &key, &nm);
4531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (IS_ERR(dent)) {
4541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			err = PTR_ERR(dent);
4551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			goto out;
4561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
4571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		kfree(file->private_data);
4591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->f_pos = key_hash_flash(c, &dent->key);
4601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		file->private_data = dent;
4611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		cond_resched();
4621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
4631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout:
4651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err != -ENOENT) {
4661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_err("cannot find next direntry, error %d", err);
4671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
4681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
4691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	kfree(file->private_data);
4711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	file->private_data = NULL;
4721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	file->f_pos = 2;
4731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
4741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
4751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* If a directory is seeked, we have to free saved readdir() state */
4771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin)
4781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
4791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	kfree(file->private_data);
4801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	file->private_data = NULL;
4811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return generic_file_llseek(file, offset, origin);
4821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
4831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/* Free saved readdir() state when the directory is closed */
4851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_dir_release(struct inode *dir, struct file *file)
4861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
4871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	kfree(file->private_data);
4881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	file->private_data = NULL;
4891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
4901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
4911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
4921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
4931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lock_2_inodes - lock two UBIFS inodes.
4941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode1: first inode
4951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode2: second inode
4961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
4971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void lock_2_inodes(struct inode *inode1, struct inode *inode2)
4981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
4991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (inode1->i_ino < inode2->i_ino) {
5001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2);
5011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3);
5021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else {
5031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
5041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3);
5051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
5061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
5071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
5091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * unlock_2_inodes - unlock two UBIFS inodes inodes.
5101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode1: first inode
5111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode2: second inode
5121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
5131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
5141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
5151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
5161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
5171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
5181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_link(struct dentry *old_dentry, struct inode *dir,
5201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		      struct dentry *dentry)
5211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
5221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
5231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode = old_dentry->d_inode;
5241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *ui = ubifs_inode(inode);
5251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
5261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
5271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2,
5281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy					.dirtied_ino_d = ui->data_len };
5291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
5311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: new direntry, changing the target inode,
5321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * changing the parent inode.
5331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
5341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu",
5361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, inode->i_ino,
5371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_nlink, dir->i_ino);
5381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = dbg_check_synced_i_size(inode);
5391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
5401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
5411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
5431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
5441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
5451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lock_2_inodes(dir, inode);
5471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(inode);
5481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	atomic_inc(&inode->i_count);
5491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_ctime = ubifs_current_time(inode);
5501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
5511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
5521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
5531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
5541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
5551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
5561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
5571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
5591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_instantiate(dentry, inode);
5601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
5611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
5631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
5641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
5651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	drop_nlink(inode);
5661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
5671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
5681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	iput(inode);
5691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
5701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
5711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_unlink(struct inode *dir, struct dentry *dentry)
5731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
5741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
5751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode = dentry->d_inode;
5761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
5771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
5781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, budgeted = 1;
5791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
5801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
5821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: deletion direntry, deletion inode (+1 for
5831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * @dirtied_ino), changing the parent directory inode. If budgeting
5841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * fails, go ahead anyway because we have extra space reserved for
5851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * deletions.
5861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
5871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu",
5891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, inode->i_ino,
5901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inode->i_nlink, dir->i_ino);
5911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = dbg_check_synced_i_size(inode);
5921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
5931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
5941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
5951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
5961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
5971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (err != -ENOSPC)
5981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return err;
5991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = 0;
6001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		budgeted = 0;
6011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
6021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lock_2_inodes(dir, inode);
6041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_ctime = ubifs_current_time(dir);
6051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	drop_nlink(inode);
6061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
6071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
6081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
6091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
6101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
6111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
6121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
6131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (budgeted)
6151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &req);
6161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	else {
6171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/* We've deleted something - clean the "no space" flags */
6181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		c->nospace = c->nospace_rp = 0;
6191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		smp_wmb();
6201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
6211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
6221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
6241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
6251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
6261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(inode);
6271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
6281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (budgeted)
6291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &req);
6301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
6311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
6321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
6341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * check_dir_empty - check if a directory is empty or not.
6351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @c: UBIFS file-system description object
6361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @dir: VFS inode object of the directory to check
6371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
6381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * This function checks if directory @dir is empty. Returns zero if the
6391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes
6401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * in case of of errors.
6411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
6421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int check_dir_empty(struct ubifs_info *c, struct inode *dir)
6431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
6441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct qstr nm = { .name = NULL };
6451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_dent_node *dent;
6461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	union ubifs_key key;
6471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err;
6481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lowest_dent_key(c, &key, dir->i_ino);
6501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dent = ubifs_tnc_next_ent(c, &key, &nm);
6511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(dent)) {
6521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(dent);
6531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (err == -ENOENT)
6541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			err = 0;
6551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else {
6561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		kfree(dent);
6571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = -ENOTEMPTY;
6581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
6591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
6601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
6611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
6631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
6641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
6651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode = dentry->d_inode;
6661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
6671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, budgeted = 1;
6681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
6691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
6701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
6721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: deletion direntry, deletion inode and
6731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * changing the parent inode. If budgeting fails, go ahead anyway
6741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * because we have extra space reserved for deletions.
6751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
6761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len,
6781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.name, inode->i_ino, dir->i_ino);
6791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = check_dir_empty(c, dentry->d_inode);
6811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
6821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
6831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
6851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
6861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (err != -ENOSPC)
6871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return err;
6881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		budgeted = 0;
6891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
6901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
6911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lock_2_inodes(dir, inode);
6921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_ctime = ubifs_current_time(dir);
6931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	clear_nlink(inode);
6941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	drop_nlink(dir);
6951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
6961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
6971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
6981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0);
6991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
7001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
7011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
7021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (budgeted)
7041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &req);
7051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	else {
7061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/* We've deleted something - clean the "no space" flags */
7071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		c->nospace = c->nospace_rp = 0;
7081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		smp_wmb();
7091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
7101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
7111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
7131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
7141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
7151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(dir);
7161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(inode);
7171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(inode);
7181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_2_inodes(dir, inode);
7191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (budgeted)
7201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &req);
7211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
7221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
7231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
7251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
7261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode;
7271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
7281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
7291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
730182854b46f9feb6f1b03abe747bb2beeebf2adb0Artem Bityutskiy	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 };
7311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
7331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: new inode, new direntry and changing parent
7341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * directory inode.
7351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
7361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s', mode %#x in dir ino %lu",
7381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino);
7391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
7411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
7421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
7431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = ubifs_new_inode(c, dir, S_IFDIR | mode);
7451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(inode)) {
7461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(inode);
7471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_budg;
7481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
7491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&dir_ui->ui_mutex);
7511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	insert_inode_hash(inode);
7521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(inode);
7531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inc_nlink(dir);
7541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
7551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
7561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
7571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
7581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
7591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_err("cannot create directory, error %d", err);
7601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
7611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
7621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
7631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
7651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_instantiate(dentry, inode);
7661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
7671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
7691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
7701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
7711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	drop_nlink(dir);
7721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
7731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	make_bad_inode(inode);
7741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	iput(inode);
7751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_budg:
7761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
7771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
7781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
7791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_mknod(struct inode *dir, struct dentry *dentry,
7811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		       int mode, dev_t rdev)
7821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
7831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode;
7841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *ui;
7851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
7861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
7871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	union ubifs_dev_desc *dev = NULL;
7881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
7891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, devlen = 0;
7901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
7911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy					.new_ino_d = devlen, .dirtied_ino = 1 };
7921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
7941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: new inode, new direntry and changing parent
7951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * directory inode.
7961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
7971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
7981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s' in dir ino %lu",
7991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.len, dentry->d_name.name, dir->i_ino);
8001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!new_valid_dev(rdev))
8021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return -EINVAL;
8031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (S_ISBLK(mode) || S_ISCHR(mode)) {
8051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
8061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (!dev)
8071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return -ENOMEM;
8081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		devlen = ubifs_encode_dev(dev, rdev);
8091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
8101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
8121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
8131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		kfree(dev);
8141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
8151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
8161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = ubifs_new_inode(c, dir, mode);
8181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(inode)) {
8191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		kfree(dev);
8201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(inode);
8211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_budg;
8221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
8231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	init_special_inode(inode, inode->i_mode, rdev);
8251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_size = ubifs_inode(inode)->ui_size = devlen;
8261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui = ubifs_inode(inode);
8271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->data = dev;
8281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->data_len = devlen;
8291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&dir_ui->ui_mutex);
8311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
8321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
8331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
8341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
8351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
8361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
8371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
8381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
8401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	insert_inode_hash(inode);
8411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_instantiate(dentry, inode);
8421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
8431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
8451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
8461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
8471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
8481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	make_bad_inode(inode);
8491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	iput(inode);
8501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_budg:
8511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
8521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
8531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
8541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_symlink(struct inode *dir, struct dentry *dentry,
8561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 const char *symname)
8571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
8581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode;
8591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *ui;
8601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *dir_ui = ubifs_inode(dir);
8611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = dir->i_sb->s_fs_info;
8621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, len = strlen(symname);
8631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
8641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
8651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy					.new_ino_d = len, .dirtied_ino = 1 };
8661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
8681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: new inode, new direntry and changing parent
8691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * directory inode.
8701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
8711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s', target '%s' in dir ino %lu", dentry->d_name.len,
8731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		dentry->d_name.name, symname, dir->i_ino);
8741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (len > UBIFS_MAX_INO_DATA)
8761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return -ENAMETOOLONG;
8771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
8791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
8801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
8811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
8831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_ERR(inode)) {
8841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = PTR_ERR(inode);
8851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_budg;
8861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
8871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui = ubifs_inode(inode);
8891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->data = kmalloc(len + 1, GFP_NOFS);
8901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!ui->data) {
8911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = -ENOMEM;
8921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_inode;
8931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
8941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
8951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	memcpy(ui->data, symname, len);
8961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	((char *)ui->data)[len] = '\0';
8971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
8981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * The terminating zero byte is not written to the flash media and it
8991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * is put just to make later in-memory string processing simpler. Thus,
9001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * data length is @len, not @len + %1.
9011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
9021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ui->data_len = len;
9031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	inode->i_size = ubifs_inode(inode)->ui_size = len;
9041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&dir_ui->ui_mutex);
9061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size += sz_change;
9071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
9081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_mtime = dir->i_ctime = inode->i_ctime;
9091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0);
9101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
9111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
9121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
9131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
9151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	insert_inode_hash(inode);
9161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	d_instantiate(dentry, inode);
9171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
9181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
9201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir->i_size -= sz_change;
9211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dir_ui->ui_size = dir->i_size;
9221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&dir_ui->ui_mutex);
9231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_inode:
9241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	make_bad_inode(inode);
9251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	iput(inode);
9261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_budg:
9271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
9281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
9291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
9301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
9321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * lock_3_inodes - lock three UBIFS inodes for rename.
9331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode1: first inode
9341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode2: second inode
9351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode3: third inode
9361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy *
9371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may
9381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * be null.
9391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
9401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void lock_3_inodes(struct inode *inode1, struct inode *inode2,
9411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			  struct inode *inode3)
9421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
9431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *i1, *i2, *i3;
9441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (!inode3) {
9461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (inode1 != inode2) {
9471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			lock_2_inodes(inode1, inode2);
9481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return;
9491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
9501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
9511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return;
9521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
9531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (inode1 == inode2) {
9551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		lock_2_inodes(inode1, inode3);
9561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return;
9571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
9581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/* 3 different inodes */
9601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (inode1 < inode2) {
9611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		i3 = inode2;
9621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (inode1 < inode3) {
9631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i1 = inode1;
9641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i2 = inode3;
9651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		} else {
9661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i1 = inode3;
9671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i2 = inode1;
9681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
9691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else {
9701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		i3 = inode1;
9711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (inode2 < inode3) {
9721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i1 = inode2;
9731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i2 = inode3;
9741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		} else {
9751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i1 = inode3;
9761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			i2 = inode2;
9771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
9781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
9791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1);
9801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lock_2_inodes(i2, i3);
9811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
9821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy/**
9841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * unlock_3_inodes - unlock three UBIFS inodes for rename.
9851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode1: first inode
9861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode2: second inode
9871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy * @inode3: third inode
9881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy */
9891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic void unlock_3_inodes(struct inode *inode1, struct inode *inode2,
9901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			    struct inode *inode3)
9911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
9921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
9931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (inode1 != inode2)
9941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
9951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (inode3)
9961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
9971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
9981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
9991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystatic int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
10001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			struct inode *new_dir, struct dentry *new_dentry)
10011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
10021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_info *c = old_dir->i_sb->s_fs_info;
10031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *old_inode = old_dentry->d_inode;
10041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *new_inode = new_dentry->d_inode;
10051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode);
10061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int err, release, sync = 0, move = (new_dir != old_dir);
10071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int is_dir = S_ISDIR(old_inode->i_mode);
10081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int unlink = !!new_inode;
10091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int new_sz = CALC_DENT_SIZE(new_dentry->d_name.len);
10101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	int old_sz = CALC_DENT_SIZE(old_dentry->d_name.len);
10111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
10121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy					.dirtied_ino = 3 };
10131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
10141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				.dirtied_ino_d = old_inode_ui->data_len };
10151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct timespec time;
10161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
10181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Budget request settings: deletion direntry, new direntry, removing
10191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * the old inode, and changing old and new parent directory inodes.
10201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 *
10211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * However, this operation also marks the target inode as dirty and
10221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * does not write it, so we allocate budget for the target inode
10231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * separately.
10241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
10251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in "
10271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		"dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name,
10281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len,
10291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		new_dentry->d_name.name, new_dir->i_ino);
10301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (unlink && is_dir) {
10321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = check_dir_empty(c, new_inode);
10331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (err)
10341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			return err;
10351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
10361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &req);
10381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
10391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
10401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_budget_space(c, &ino_req);
10411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err) {
10421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &req);
10431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		return err;
10441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
10451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	lock_3_inodes(old_dir, new_dir, new_inode);
10471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
10491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Like most other Unix systems, set the @i_ctime for inodes on a
10501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * rename.
10511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
10521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	time = ubifs_current_time(old_dir);
10531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	old_inode->i_ctime = time;
10541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/* We must adjust parent link count when renaming directories */
10561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (is_dir) {
10571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (move) {
10581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			/*
10591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * @old_dir loses a link because we are moving
10601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * @old_inode to a different directory.
10611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 */
10621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			drop_nlink(old_dir);
10631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			/*
10641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * @new_dir only gains a link if we are not also
10651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * overwriting an existing directory.
10661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 */
10671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			if (!unlink)
10681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				inc_nlink(new_dir);
10691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		} else {
10701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			/*
10711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * @old_inode is not moving to a different directory,
10721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * but @old_dir still loses a link if we are
10731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 * overwriting an existing directory.
10741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			 */
10751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			if (unlink)
10761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				drop_nlink(old_dir);
10771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
10781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
10791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	old_dir->i_size -= old_sz;
10811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_inode(old_dir)->ui_size = old_dir->i_size;
10821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	old_dir->i_mtime = old_dir->i_ctime = time;
10831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	new_dir->i_mtime = new_dir->i_ctime = time;
10841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
10851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
10861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * And finally, if we unlinked a direntry which happened to have the
10871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * same name as the moved direntry, we have to decrement @i_nlink of
10881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * the unlinked inode and change its ctime.
10891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
10901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (unlink) {
10911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
10921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * Directories cannot have hard-links, so if this is a
10931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * directory, decrement its @i_nlink twice because an empty
10941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * directory has @i_nlink 2.
10951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
10961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (is_dir)
10971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			drop_nlink(new_inode);
10981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		new_inode->i_ctime = time;
10991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		drop_nlink(new_inode);
11001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else {
11011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		new_dir->i_size += new_sz;
11021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
11031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
11041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
11061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Do not ask 'ubifs_jnl_rename()' to flush write-buffer if @old_inode
11071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * is dirty, because this will be done later on at the end of
11081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * 'ubifs_rename()'.
11091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
11101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_SYNC(old_inode)) {
11111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir);
11121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (unlink && IS_SYNC(new_inode))
11131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			sync = 1;
11141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
11151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry,
11161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			       sync);
11171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (err)
11181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		goto out_cancel;
11191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_3_inodes(old_dir, new_dir, new_inode);
11211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
11221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&old_inode_ui->ui_mutex);
11241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	release = old_inode_ui->dirty;
11251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mark_inode_dirty_sync(old_inode);
11261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&old_inode_ui->ui_mutex);
11271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (release)
11291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_release_budget(c, &ino_req);
11301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (IS_SYNC(old_inode))
11311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		err = old_inode->i_sb->s_op->write_inode(old_inode, 1);
11321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
11331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyout_cancel:
11351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (unlink) {
11361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (is_dir)
11371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			inc_nlink(new_inode);
11381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		inc_nlink(new_inode);
11391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else {
11401e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		new_dir->i_size -= new_sz;
11411e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
11421e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
11431e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	old_dir->i_size += old_sz;
11441e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_inode(old_dir)->ui_size = old_dir->i_size;
11451e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (is_dir) {
11461e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		if (move) {
11471e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			inc_nlink(old_dir);
11481e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			if (!unlink)
11491e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				drop_nlink(new_dir);
11501e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		} else {
11511e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy			if (unlink)
11521e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy				inc_nlink(old_dir);
11531e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		}
11541e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	}
11551e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	unlock_3_inodes(old_dir, new_dir, new_inode);
11561e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &ino_req);
11571e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	ubifs_release_budget(c, &req);
11581e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return err;
11591e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
11601e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11611e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiyint ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
11621e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		  struct kstat *stat)
11631e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy{
11641e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	loff_t size;
11651e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct inode *inode = dentry->d_inode;
11661e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	struct ubifs_inode *ui = ubifs_inode(inode);
11671e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11681e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_lock(&ui->ui_mutex);
11691e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->dev = inode->i_sb->s_dev;
11701e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->ino = inode->i_ino;
11711e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->mode = inode->i_mode;
11721e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->nlink = inode->i_nlink;
11731e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->uid = inode->i_uid;
11741e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->gid = inode->i_gid;
11751e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->rdev = inode->i_rdev;
11761e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->atime = inode->i_atime;
11771e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->mtime = inode->i_mtime;
11781e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->ctime = inode->i_ctime;
11791e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->blksize = UBIFS_BLOCK_SIZE;
11801e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	stat->size = ui->ui_size;
11811e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
11821e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	/*
11831e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * Unfortunately, the 'stat()' system call was designed for block
11841e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * device based file systems, and it is not appropriate for UBIFS,
11851e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * because UBIFS does not have notion of "block". For example, it is
11861e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * difficult to tell how many block a directory takes - it actually
11871e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * takes less than 300 bytes, but we have to round it to block size,
11881e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * which introduces large mistake. This makes utilities like 'du' to
11891e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * report completely senseless numbers. This is the reason why UBIFS
11901e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * goes the same way as JFFS2 - it reports zero blocks for everything
11911e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * but regular files, which makes more sense than reporting completely
11921e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 * wrong sizes.
11931e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	 */
11941e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	if (S_ISREG(inode->i_mode)) {
11951e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		size = ui->xattr_size;
11961e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		size += stat->size;
11971e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		size = ALIGN(size, UBIFS_BLOCK_SIZE);
11981e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		/*
11991e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * Note, user-space expects 512-byte blocks count irrespectively
12001e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 * of what was reported in @stat->size.
12011e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		 */
12021e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		stat->blocks = size >> 9;
12031e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	} else
12041e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy		stat->blocks = 0;
12051e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	mutex_unlock(&ui->ui_mutex);
12061e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	return 0;
12071e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy}
12081e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
12091e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystruct inode_operations ubifs_dir_inode_operations = {
12101e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.lookup      = ubifs_lookup,
12111e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.create      = ubifs_create,
12121e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.link        = ubifs_link,
12131e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.symlink     = ubifs_symlink,
12141e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.unlink      = ubifs_unlink,
12151e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.mkdir       = ubifs_mkdir,
12161e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.rmdir       = ubifs_rmdir,
12171e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.mknod       = ubifs_mknod,
12181e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.rename      = ubifs_rename,
12191e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.setattr     = ubifs_setattr,
12201e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.getattr     = ubifs_getattr,
12211e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#ifdef CONFIG_UBIFS_FS_XATTR
12221e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.setxattr    = ubifs_setxattr,
12231e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.getxattr    = ubifs_getxattr,
12241e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.listxattr   = ubifs_listxattr,
12251e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.removexattr = ubifs_removexattr,
12261e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#endif
12271e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy};
12281e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy
12291e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiystruct file_operations ubifs_dir_operations = {
12301e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.llseek         = ubifs_dir_llseek,
12311e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.release        = ubifs_dir_release,
12321e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.read           = generic_read_dir,
12331e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.readdir        = ubifs_readdir,
12341e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.fsync          = ubifs_fsync,
12351e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.unlocked_ioctl = ubifs_ioctl,
12361e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#ifdef CONFIG_COMPAT
12371e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy	.compat_ioctl   = ubifs_compat_ioctl,
12381e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy#endif
12391e51764a3c2ac05a23a22b2a95ddee4d9bffb16dArtem Bityutskiy};
1240