// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of UBIFS. * * Copyright (C) 2006-2008 Nokia Corporation. * Copyright (C) 2006, 2007 University of Szeged, Hungary * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter * Zoltan Sogor */ /* * This file implements directory operations. * * All FS operations in this file allocate budget before writing anything to the * media. If they fail to allocate it, the error is returned. The only * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even * if they unable to allocate the budget, because deletion %-ENOSPC failure is * not what users are usually ready to get. UBIFS budgeting subsystem has some * space reserved for these purposes. * * All operations in this file write all inodes which they change straight * away, instead of marking them dirty. For example, 'ubifs_link()' changes * @i_size of the parent inode and writes the parent inode together with the * target inode. This was done to simplify file-system recovery which would * otherwise be very difficult to do. The only exception is rename which marks * the re-named inode dirty (because its @i_ctime is updated) but does not * write it, but just marks it as dirty. */ #include "ubifs.h" /** * inherit_flags - inherit flags of the parent inode. * @dir: parent inode * @mode: new inode mode flags * * This is a helper function for 'ubifs_new_inode()' which inherits flag of the * parent directory inode @dir. UBIFS inodes inherit the following flags: * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on * sub-directory basis; * o %UBIFS_SYNC_FL - useful for the same reasons; * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories. * * This function returns the inherited flags. */ static int inherit_flags(const struct inode *dir, umode_t mode) { … } /** * ubifs_new_inode - allocate new UBIFS inode object. * @c: UBIFS file-system description object * @dir: parent directory inode * @mode: inode mode flags * @is_xattr: whether the inode is xattr inode * * This function finds an unused inode number, allocates new inode and * initializes it. Non-xattr new inode may be written with xattrs(selinux/ * encryption) before writing dentry, which could cause inconsistent problem * when powercut happens between two operations. To deal with it, non-xattr * new inode is initialized with zero-nlink and added into orphan list, caller * should make sure that inode is relinked later, and make sure that orphan * removing and journal writing into an committing atomic operation. Returns * new inode in case of success and an error code in case of failure. */ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, umode_t mode, bool is_xattr) { … } static int dbg_check_name(const struct ubifs_info *c, const struct ubifs_dent_node *dent, const struct fscrypt_name *nm) { … } static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { … } static int ubifs_prepare_create(struct inode *dir, struct dentry *dentry, struct fscrypt_name *nm) { … } static int ubifs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { … } static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry) { … } /** * lock_2_inodes - a wrapper for locking two UBIFS inodes. * @inode1: first inode * @inode2: second inode * * We do not implement any tricks to guarantee strict lock ordering, because * VFS has already done it for us on the @i_mutex. So this is just a simple * wrapper function. */ static void lock_2_inodes(struct inode *inode1, struct inode *inode2) { … } /** * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes. * @inode1: first inode * @inode2: second inode */ static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) { … } static int ubifs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, struct file *file, umode_t mode) { … } /** * vfs_dent_type - get VFS directory entry type. * @type: UBIFS directory entry type * * This function converts UBIFS directory entry type into VFS directory entry * type. */ static unsigned int vfs_dent_type(uint8_t type) { … } /* * The classical Unix view for directory is that it is a linear array of * (name, inode number) entries. Linux/VFS assumes this model as well. * Particularly, 'readdir()' call wants us to return a directory entry offset * which later may be used to continue 'readdir()'ing the directory or to * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this * model because directory entries are identified by keys, which may collide. * * UBIFS uses directory entry hash value for directory offsets, so * 'seekdir()'/'telldir()' may not always work because of possible key * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work * properly by means of saving full directory entry name in the private field * of the file description object. * * This means that UBIFS cannot support NFS which requires full * 'seekdir()'/'telldir()' support. */ static int ubifs_readdir(struct file *file, struct dir_context *ctx) { … } /* Free saved readdir() state when the directory is closed */ static int ubifs_dir_release(struct inode *dir, struct file *file) { … } static int ubifs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { … } static int ubifs_unlink(struct inode *dir, struct dentry *dentry) { … } /** * ubifs_check_dir_empty - check if a directory is empty or not. * @dir: VFS inode object of the directory to check * * This function checks if directory @dir is empty. Returns zero if the * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes * in case of errors. */ int ubifs_check_dir_empty(struct inode *dir) { … } static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) { … } static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode) { … } static int ubifs_mknod(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { … } static int ubifs_symlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, const char *symname) { … } /** * lock_4_inodes - a wrapper for locking three UBIFS inodes. * @inode1: first inode * @inode2: second inode * @inode3: third inode * @inode4: fourth inode * * This function is used for 'ubifs_rename()' and @inode1 may be the same as * @inode2 whereas @inode3 and @inode4 may be %NULL. * * We do not implement any tricks to guarantee strict lock ordering, because * VFS has already done it for us on the @i_mutex. So this is just a simple * wrapper function. */ static void lock_4_inodes(struct inode *inode1, struct inode *inode2, struct inode *inode3, struct inode *inode4) { … } /** * unlock_4_inodes - a wrapper for unlocking three UBIFS inodes for rename. * @inode1: first inode * @inode2: second inode * @inode3: third inode * @inode4: fourth inode */ static void unlock_4_inodes(struct inode *inode1, struct inode *inode2, struct inode *inode3, struct inode *inode4) { … } static int do_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { … } static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { … } static int ubifs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { … } int ubifs_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { … } const struct inode_operations ubifs_dir_inode_operations = …; const struct file_operations ubifs_dir_operations = …;