12b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21e51764aSArtem Bityutskiy /* * This file is part of UBIFS.
31e51764aSArtem Bityutskiy *
41e51764aSArtem Bityutskiy * Copyright (C) 2006-2008 Nokia Corporation.
51e51764aSArtem Bityutskiy * Copyright (C) 2006, 2007 University of Szeged, Hungary
61e51764aSArtem Bityutskiy *
71e51764aSArtem Bityutskiy * Authors: Artem Bityutskiy (Битюцкий Артём)
81e51764aSArtem Bityutskiy * Adrian Hunter
91e51764aSArtem Bityutskiy * Zoltan Sogor
101e51764aSArtem Bityutskiy */
111e51764aSArtem Bityutskiy
121e51764aSArtem Bityutskiy /*
131e51764aSArtem Bityutskiy * This file implements directory operations.
141e51764aSArtem Bityutskiy *
151e51764aSArtem Bityutskiy * All FS operations in this file allocate budget before writing anything to the
161e51764aSArtem Bityutskiy * media. If they fail to allocate it, the error is returned. The only
171e51764aSArtem Bityutskiy * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even
181e51764aSArtem Bityutskiy * if they unable to allocate the budget, because deletion %-ENOSPC failure is
191e51764aSArtem Bityutskiy * not what users are usually ready to get. UBIFS budgeting subsystem has some
201e51764aSArtem Bityutskiy * space reserved for these purposes.
211e51764aSArtem Bityutskiy *
221e51764aSArtem Bityutskiy * All operations in this file write all inodes which they change straight
231e51764aSArtem Bityutskiy * away, instead of marking them dirty. For example, 'ubifs_link()' changes
241e51764aSArtem Bityutskiy * @i_size of the parent inode and writes the parent inode together with the
251e51764aSArtem Bityutskiy * target inode. This was done to simplify file-system recovery which would
261e51764aSArtem Bityutskiy * otherwise be very difficult to do. The only exception is rename which marks
271e51764aSArtem Bityutskiy * the re-named inode dirty (because its @i_ctime is updated) but does not
281e51764aSArtem Bityutskiy * write it, but just marks it as dirty.
291e51764aSArtem Bityutskiy */
301e51764aSArtem Bityutskiy
311e51764aSArtem Bityutskiy #include "ubifs.h"
321e51764aSArtem Bityutskiy
331e51764aSArtem Bityutskiy /**
341e51764aSArtem Bityutskiy * inherit_flags - inherit flags of the parent inode.
351e51764aSArtem Bityutskiy * @dir: parent inode
361e51764aSArtem Bityutskiy * @mode: new inode mode flags
371e51764aSArtem Bityutskiy *
381e51764aSArtem Bityutskiy * This is a helper function for 'ubifs_new_inode()' which inherits flag of the
391e51764aSArtem Bityutskiy * parent directory inode @dir. UBIFS inodes inherit the following flags:
401e51764aSArtem Bityutskiy * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on
411e51764aSArtem Bityutskiy * sub-directory basis;
421e51764aSArtem Bityutskiy * o %UBIFS_SYNC_FL - useful for the same reasons;
431e51764aSArtem Bityutskiy * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories.
441e51764aSArtem Bityutskiy *
451e51764aSArtem Bityutskiy * This function returns the inherited flags.
461e51764aSArtem Bityutskiy */
inherit_flags(const struct inode * dir,umode_t mode)47ad44be5cSAl Viro static int inherit_flags(const struct inode *dir, umode_t mode)
481e51764aSArtem Bityutskiy {
491e51764aSArtem Bityutskiy int flags;
501e51764aSArtem Bityutskiy const struct ubifs_inode *ui = ubifs_inode(dir);
511e51764aSArtem Bityutskiy
521e51764aSArtem Bityutskiy if (!S_ISDIR(dir->i_mode))
531e51764aSArtem Bityutskiy /*
541e51764aSArtem Bityutskiy * The parent is not a directory, which means that an extended
551e51764aSArtem Bityutskiy * attribute inode is being created. No flags.
561e51764aSArtem Bityutskiy */
571e51764aSArtem Bityutskiy return 0;
581e51764aSArtem Bityutskiy
591e51764aSArtem Bityutskiy flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL);
601e51764aSArtem Bityutskiy if (!S_ISDIR(mode))
611e51764aSArtem Bityutskiy /* The "DIRSYNC" flag only applies to directories */
621e51764aSArtem Bityutskiy flags &= ~UBIFS_DIRSYNC_FL;
631e51764aSArtem Bityutskiy return flags;
641e51764aSArtem Bityutskiy }
651e51764aSArtem Bityutskiy
661e51764aSArtem Bityutskiy /**
671e51764aSArtem Bityutskiy * ubifs_new_inode - allocate new UBIFS inode object.
681e51764aSArtem Bityutskiy * @c: UBIFS file-system description object
691e51764aSArtem Bityutskiy * @dir: parent directory inode
701e51764aSArtem Bityutskiy * @mode: inode mode flags
71a0c51565SZhihao Cheng * @is_xattr: whether the inode is xattr inode
721e51764aSArtem Bityutskiy *
731e51764aSArtem Bityutskiy * This function finds an unused inode number, allocates new inode and
741e51764aSArtem Bityutskiy * initializes it. Returns new inode in case of success and an error code in
751e51764aSArtem Bityutskiy * case of failure.
761e51764aSArtem Bityutskiy */
ubifs_new_inode(struct ubifs_info * c,struct inode * dir,umode_t mode,bool is_xattr)77d475a507SRichard Weinberger struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
78a0c51565SZhihao Cheng umode_t mode, bool is_xattr)
791e51764aSArtem Bityutskiy {
80d475a507SRichard Weinberger int err;
811e51764aSArtem Bityutskiy struct inode *inode;
821e51764aSArtem Bityutskiy struct ubifs_inode *ui;
83d475a507SRichard Weinberger bool encrypted = false;
84d475a507SRichard Weinberger
851e51764aSArtem Bityutskiy inode = new_inode(c->vfs_sb);
861e51764aSArtem Bityutskiy ui = ubifs_inode(inode);
871e51764aSArtem Bityutskiy if (!inode)
881e51764aSArtem Bityutskiy return ERR_PTR(-ENOMEM);
891e51764aSArtem Bityutskiy
901e51764aSArtem Bityutskiy /*
911e51764aSArtem Bityutskiy * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and
921e51764aSArtem Bityutskiy * marking them dirty in file write path (see 'file_update_time()').
931e51764aSArtem Bityutskiy * UBIFS has to fully control "clean <-> dirty" transitions of inodes
941e51764aSArtem Bityutskiy * to make budgeting work.
951e51764aSArtem Bityutskiy */
9612e776a0SArtem Bityutskiy inode->i_flags |= S_NOCMTIME;
971e51764aSArtem Bityutskiy
98f2d40141SChristian Brauner inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
99d07d3a7eSJeff Layton inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
1001e51764aSArtem Bityutskiy inode->i_mapping->nrpages = 0;
1011e51764aSArtem Bityutskiy
102a0c51565SZhihao Cheng if (!is_xattr) {
1034c030fa8SEric Biggers err = fscrypt_prepare_new_inode(dir, inode, &encrypted);
1044c030fa8SEric Biggers if (err) {
1054c030fa8SEric Biggers ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err);
1064c030fa8SEric Biggers goto out_iput;
1074c030fa8SEric Biggers }
108a0c51565SZhihao Cheng }
1094c030fa8SEric Biggers
1101e51764aSArtem Bityutskiy switch (mode & S_IFMT) {
1111e51764aSArtem Bityutskiy case S_IFREG:
1121e51764aSArtem Bityutskiy inode->i_mapping->a_ops = &ubifs_file_address_operations;
1131e51764aSArtem Bityutskiy inode->i_op = &ubifs_file_inode_operations;
1141e51764aSArtem Bityutskiy inode->i_fop = &ubifs_file_operations;
1151e51764aSArtem Bityutskiy break;
1161e51764aSArtem Bityutskiy case S_IFDIR:
1171e51764aSArtem Bityutskiy inode->i_op = &ubifs_dir_inode_operations;
1181e51764aSArtem Bityutskiy inode->i_fop = &ubifs_dir_operations;
1191e51764aSArtem Bityutskiy inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ;
1201e51764aSArtem Bityutskiy break;
1211e51764aSArtem Bityutskiy case S_IFLNK:
1221e51764aSArtem Bityutskiy inode->i_op = &ubifs_symlink_inode_operations;
1231e51764aSArtem Bityutskiy break;
1241e51764aSArtem Bityutskiy case S_IFSOCK:
1251e51764aSArtem Bityutskiy case S_IFIFO:
1261e51764aSArtem Bityutskiy case S_IFBLK:
1271e51764aSArtem Bityutskiy case S_IFCHR:
1281e51764aSArtem Bityutskiy inode->i_op = &ubifs_file_inode_operations;
1291e51764aSArtem Bityutskiy break;
1301e51764aSArtem Bityutskiy default:
1311e51764aSArtem Bityutskiy BUG();
1321e51764aSArtem Bityutskiy }
1331e51764aSArtem Bityutskiy
1341e51764aSArtem Bityutskiy ui->flags = inherit_flags(dir, mode);
1351e51764aSArtem Bityutskiy ubifs_set_inode_flags(inode);
1361e51764aSArtem Bityutskiy if (S_ISREG(mode))
1371e51764aSArtem Bityutskiy ui->compr_type = c->default_compr;
1381e51764aSArtem Bityutskiy else
1391e51764aSArtem Bityutskiy ui->compr_type = UBIFS_COMPR_NONE;
1401e51764aSArtem Bityutskiy ui->synced_i_size = 0;
1411e51764aSArtem Bityutskiy
1421e51764aSArtem Bityutskiy spin_lock(&c->cnt_lock);
1431e51764aSArtem Bityutskiy /* Inode number overflow is currently not supported */
1441e51764aSArtem Bityutskiy if (c->highest_inum >= INUM_WARN_WATERMARK) {
1451e51764aSArtem Bityutskiy if (c->highest_inum >= INUM_WATERMARK) {
1461e51764aSArtem Bityutskiy spin_unlock(&c->cnt_lock);
147235c362bSSheng Yong ubifs_err(c, "out of inode numbers");
1484c030fa8SEric Biggers err = -EINVAL;
1494c030fa8SEric Biggers goto out_iput;
1501e51764aSArtem Bityutskiy }
1511a7e985dSSheng Yong ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
152e84461adSArtem Bityutskiy (unsigned long)c->highest_inum, INUM_WATERMARK);
1531e51764aSArtem Bityutskiy }
1541e51764aSArtem Bityutskiy
1551e51764aSArtem Bityutskiy inode->i_ino = ++c->highest_inum;
1561e51764aSArtem Bityutskiy /*
1571e51764aSArtem Bityutskiy * The creation sequence number remains with this inode for its
1581e51764aSArtem Bityutskiy * lifetime. All nodes for this inode have a greater sequence number,
1591e51764aSArtem Bityutskiy * and so it is possible to distinguish obsolete nodes belonging to a
1601e51764aSArtem Bityutskiy * previous incarnation of the same inode number - for example, for the
1611e51764aSArtem Bityutskiy * purpose of rebuilding the index.
1621e51764aSArtem Bityutskiy */
1631e51764aSArtem Bityutskiy ui->creat_sqnum = ++c->max_sqnum;
1641e51764aSArtem Bityutskiy spin_unlock(&c->cnt_lock);
165d475a507SRichard Weinberger
166d475a507SRichard Weinberger if (encrypted) {
1674c030fa8SEric Biggers err = fscrypt_set_context(inode, NULL);
168d475a507SRichard Weinberger if (err) {
1694c030fa8SEric Biggers ubifs_err(c, "fscrypt_set_context failed: %i", err);
1704c030fa8SEric Biggers goto out_iput;
171d475a507SRichard Weinberger }
172d475a507SRichard Weinberger }
173d475a507SRichard Weinberger
1741e51764aSArtem Bityutskiy return inode;
1754c030fa8SEric Biggers
1764c030fa8SEric Biggers out_iput:
1774c030fa8SEric Biggers make_bad_inode(inode);
1784c030fa8SEric Biggers iput(inode);
1794c030fa8SEric Biggers return ERR_PTR(err);
1801e51764aSArtem Bityutskiy }
1811e51764aSArtem Bityutskiy
dbg_check_name(const struct ubifs_info * c,const struct ubifs_dent_node * dent,const struct fscrypt_name * nm)182bb2615d4SArtem Bityutskiy static int dbg_check_name(const struct ubifs_info *c,
183bb2615d4SArtem Bityutskiy const struct ubifs_dent_node *dent,
184f4f61d2cSRichard Weinberger const struct fscrypt_name *nm)
1851e51764aSArtem Bityutskiy {
1862b1844a8SArtem Bityutskiy if (!dbg_is_chk_gen(c))
1871e51764aSArtem Bityutskiy return 0;
188f4f61d2cSRichard Weinberger if (le16_to_cpu(dent->nlen) != fname_len(nm))
1891e51764aSArtem Bityutskiy return -EINVAL;
190f4f61d2cSRichard Weinberger if (memcmp(dent->name, fname_name(nm), fname_len(nm)))
1911e51764aSArtem Bityutskiy return -EINVAL;
1921e51764aSArtem Bityutskiy return 0;
1931e51764aSArtem Bityutskiy }
1941e51764aSArtem Bityutskiy
ubifs_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)1951e51764aSArtem Bityutskiy static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
19600cd8dd3SAl Viro unsigned int flags)
1971e51764aSArtem Bityutskiy {
1981e51764aSArtem Bityutskiy int err;
1991e51764aSArtem Bityutskiy union ubifs_key key;
2001e51764aSArtem Bityutskiy struct inode *inode = NULL;
201191ac107SAl Viro struct ubifs_dent_node *dent = NULL;
2021e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
203f4f61d2cSRichard Weinberger struct fscrypt_name nm;
2041e51764aSArtem Bityutskiy
2054cb2a01dSAl Viro dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
2061e51764aSArtem Bityutskiy
207b01531dbSEric Biggers err = fscrypt_prepare_lookup(dir, dentry, &nm);
208bb9cd910SDaniel Rosenberg generic_set_encrypted_ci_d_ops(dentry);
209b01531dbSEric Biggers if (err == -ENOENT)
210b01531dbSEric Biggers return d_splice_alias(NULL, dentry);
211f4f61d2cSRichard Weinberger if (err)
212f4f61d2cSRichard Weinberger return ERR_PTR(err);
213f4f61d2cSRichard Weinberger
214f4f61d2cSRichard Weinberger if (fname_len(&nm) > UBIFS_MAX_NLEN) {
215191ac107SAl Viro inode = ERR_PTR(-ENAMETOOLONG);
216191ac107SAl Viro goto done;
217f4f61d2cSRichard Weinberger }
2181e51764aSArtem Bityutskiy
2191e51764aSArtem Bityutskiy dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
220f4f61d2cSRichard Weinberger if (!dent) {
221191ac107SAl Viro inode = ERR_PTR(-ENOMEM);
222191ac107SAl Viro goto done;
223f4f61d2cSRichard Weinberger }
2241e51764aSArtem Bityutskiy
225aec992aaSEric Biggers if (fname_name(&nm) == NULL) {
226f0d07a98SEric Biggers if (nm.hash & ~UBIFS_S_KEY_HASH_MASK)
227f0d07a98SEric Biggers goto done; /* ENOENT */
228f4f61d2cSRichard Weinberger dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
229528e3d17SRichard Weinberger err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
230f4f61d2cSRichard Weinberger } else {
231f4f61d2cSRichard Weinberger dent_key_init(c, &key, dir->i_ino, &nm);
232f4f61d2cSRichard Weinberger err = ubifs_tnc_lookup_nm(c, &key, dent, &nm);
233f4f61d2cSRichard Weinberger }
2341e51764aSArtem Bityutskiy
2351e51764aSArtem Bityutskiy if (err) {
236191ac107SAl Viro if (err == -ENOENT)
2371e51764aSArtem Bityutskiy dbg_gen("not found");
238191ac107SAl Viro else
239191ac107SAl Viro inode = ERR_PTR(err);
2401e51764aSArtem Bityutskiy goto done;
2411e51764aSArtem Bityutskiy }
2421e51764aSArtem Bityutskiy
243f4f61d2cSRichard Weinberger if (dbg_check_name(c, dent, &nm)) {
244191ac107SAl Viro inode = ERR_PTR(-EINVAL);
245191ac107SAl Viro goto done;
2461e51764aSArtem Bityutskiy }
2471e51764aSArtem Bityutskiy
2481e51764aSArtem Bityutskiy inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum));
2491e51764aSArtem Bityutskiy if (IS_ERR(inode)) {
2501e51764aSArtem Bityutskiy /*
2511e51764aSArtem Bityutskiy * This should not happen. Probably the file-system needs
2521e51764aSArtem Bityutskiy * checking.
2531e51764aSArtem Bityutskiy */
2541e51764aSArtem Bityutskiy err = PTR_ERR(inode);
255235c362bSSheng Yong ubifs_err(c, "dead directory entry '%pd', error %d",
2564cb2a01dSAl Viro dentry, err);
2571e51764aSArtem Bityutskiy ubifs_ro_mode(c, err);
258191ac107SAl Viro goto done;
2591e51764aSArtem Bityutskiy }
2601e51764aSArtem Bityutskiy
26150d9fad7SEric Biggers if (IS_ENCRYPTED(dir) &&
262413d5a9eSEric Biggers (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
263413d5a9eSEric Biggers !fscrypt_has_permitted_context(dir, inode)) {
264413d5a9eSEric Biggers ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu",
265413d5a9eSEric Biggers dir->i_ino, inode->i_ino);
266191ac107SAl Viro iput(inode);
267191ac107SAl Viro inode = ERR_PTR(-EPERM);
268413d5a9eSEric Biggers }
269413d5a9eSEric Biggers
2701e51764aSArtem Bityutskiy done:
2711e51764aSArtem Bityutskiy kfree(dent);
272f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
273191ac107SAl Viro return d_splice_alias(inode, dentry);
2741e51764aSArtem Bityutskiy }
2751e51764aSArtem Bityutskiy
ubifs_prepare_create(struct inode * dir,struct dentry * dentry,struct fscrypt_name * nm)27676786a0fSEric Biggers static int ubifs_prepare_create(struct inode *dir, struct dentry *dentry,
27776786a0fSEric Biggers struct fscrypt_name *nm)
27876786a0fSEric Biggers {
27976786a0fSEric Biggers if (fscrypt_is_nokey_name(dentry))
28076786a0fSEric Biggers return -ENOKEY;
28176786a0fSEric Biggers
28276786a0fSEric Biggers return fscrypt_setup_filename(dir, &dentry->d_name, 0, nm);
28376786a0fSEric Biggers }
28476786a0fSEric Biggers
ubifs_create(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)2856c960e68SChristian Brauner static int ubifs_create(struct mnt_idmap *idmap, struct inode *dir,
286549c7297SChristian Brauner struct dentry *dentry, umode_t mode, bool excl)
2871e51764aSArtem Bityutskiy {
2881e51764aSArtem Bityutskiy struct inode *inode;
2891e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
2901e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
2911e51764aSArtem Bityutskiy .dirtied_ino = 1 };
2921e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
293f4f61d2cSRichard Weinberger struct fscrypt_name nm;
294f4f61d2cSRichard Weinberger int err, sz_change;
2951e51764aSArtem Bityutskiy
2961e51764aSArtem Bityutskiy /*
2971e51764aSArtem Bityutskiy * Budget request settings: new inode, new direntry, changing the
2981e51764aSArtem Bityutskiy * parent directory inode.
2991e51764aSArtem Bityutskiy */
3001e51764aSArtem Bityutskiy
3014cb2a01dSAl Viro dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
3024cb2a01dSAl Viro dentry, mode, dir->i_ino);
3031e51764aSArtem Bityutskiy
3041e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
3051e51764aSArtem Bityutskiy if (err)
3061e51764aSArtem Bityutskiy return err;
3071e51764aSArtem Bityutskiy
30876786a0fSEric Biggers err = ubifs_prepare_create(dir, dentry, &nm);
309f4f61d2cSRichard Weinberger if (err)
310f4f61d2cSRichard Weinberger goto out_budg;
311f4f61d2cSRichard Weinberger
312f4f61d2cSRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
313f4f61d2cSRichard Weinberger
314a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, mode, false);
3151e51764aSArtem Bityutskiy if (IS_ERR(inode)) {
3161e51764aSArtem Bityutskiy err = PTR_ERR(inode);
317f4f61d2cSRichard Weinberger goto out_fname;
3181e51764aSArtem Bityutskiy }
3191e51764aSArtem Bityutskiy
320d7f0b70dSSubodh Nijsure err = ubifs_init_security(dir, inode, &dentry->d_name);
321d7f0b70dSSubodh Nijsure if (err)
3229401a795STaesoo Kim goto out_inode;
323d7f0b70dSSubodh Nijsure
3241e51764aSArtem Bityutskiy mutex_lock(&dir_ui->ui_mutex);
3251e51764aSArtem Bityutskiy dir->i_size += sz_change;
3261e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
327d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
328f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
3291e51764aSArtem Bityutskiy if (err)
3301e51764aSArtem Bityutskiy goto out_cancel;
3311e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
3321e51764aSArtem Bityutskiy
3331e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
334f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
3351e51764aSArtem Bityutskiy insert_inode_hash(inode);
3361e51764aSArtem Bityutskiy d_instantiate(dentry, inode);
3371e51764aSArtem Bityutskiy return 0;
3381e51764aSArtem Bityutskiy
3391e51764aSArtem Bityutskiy out_cancel:
3401e51764aSArtem Bityutskiy dir->i_size -= sz_change;
3411e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
3421e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
3439401a795STaesoo Kim out_inode:
3441e51764aSArtem Bityutskiy make_bad_inode(inode);
3451e51764aSArtem Bityutskiy iput(inode);
346f4f61d2cSRichard Weinberger out_fname:
347f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
3481e51764aSArtem Bityutskiy out_budg:
3491e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
350235c362bSSheng Yong ubifs_err(c, "cannot create regular file, error %d", err);
3511e51764aSArtem Bityutskiy return err;
3521e51764aSArtem Bityutskiy }
3531e51764aSArtem Bityutskiy
create_whiteout(struct inode * dir,struct dentry * dentry)354278d9a24SZhihao Cheng static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
355278d9a24SZhihao Cheng {
356278d9a24SZhihao Cheng int err;
357278d9a24SZhihao Cheng umode_t mode = S_IFCHR | WHITEOUT_MODE;
358278d9a24SZhihao Cheng struct inode *inode;
359278d9a24SZhihao Cheng struct ubifs_info *c = dir->i_sb->s_fs_info;
360278d9a24SZhihao Cheng
361278d9a24SZhihao Cheng /*
362278d9a24SZhihao Cheng * Create an inode('nlink = 1') for whiteout without updating journal,
363278d9a24SZhihao Cheng * let ubifs_jnl_rename() store it on flash to complete rename whiteout
364278d9a24SZhihao Cheng * atomically.
365278d9a24SZhihao Cheng */
366278d9a24SZhihao Cheng
367278d9a24SZhihao Cheng dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
368278d9a24SZhihao Cheng dentry, mode, dir->i_ino);
369278d9a24SZhihao Cheng
370a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, mode, false);
371278d9a24SZhihao Cheng if (IS_ERR(inode)) {
372278d9a24SZhihao Cheng err = PTR_ERR(inode);
373278d9a24SZhihao Cheng goto out_free;
374278d9a24SZhihao Cheng }
375278d9a24SZhihao Cheng
376278d9a24SZhihao Cheng init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
377278d9a24SZhihao Cheng ubifs_assert(c, inode->i_op == &ubifs_file_inode_operations);
378278d9a24SZhihao Cheng
379278d9a24SZhihao Cheng err = ubifs_init_security(dir, inode, &dentry->d_name);
380278d9a24SZhihao Cheng if (err)
381278d9a24SZhihao Cheng goto out_inode;
382278d9a24SZhihao Cheng
383278d9a24SZhihao Cheng /* The dir size is updated by do_rename. */
384278d9a24SZhihao Cheng insert_inode_hash(inode);
385278d9a24SZhihao Cheng
386278d9a24SZhihao Cheng return inode;
387278d9a24SZhihao Cheng
388278d9a24SZhihao Cheng out_inode:
389278d9a24SZhihao Cheng make_bad_inode(inode);
390278d9a24SZhihao Cheng iput(inode);
391278d9a24SZhihao Cheng out_free:
392278d9a24SZhihao Cheng ubifs_err(c, "cannot create whiteout file, error %d", err);
393278d9a24SZhihao Cheng return ERR_PTR(err);
394278d9a24SZhihao Cheng }
395278d9a24SZhihao Cheng
39660eb3b9cSZhihao Cheng /**
39760eb3b9cSZhihao Cheng * lock_2_inodes - a wrapper for locking two UBIFS inodes.
39860eb3b9cSZhihao Cheng * @inode1: first inode
39960eb3b9cSZhihao Cheng * @inode2: second inode
40060eb3b9cSZhihao Cheng *
40160eb3b9cSZhihao Cheng * We do not implement any tricks to guarantee strict lock ordering, because
40260eb3b9cSZhihao Cheng * VFS has already done it for us on the @i_mutex. So this is just a simple
40360eb3b9cSZhihao Cheng * wrapper function.
40460eb3b9cSZhihao Cheng */
lock_2_inodes(struct inode * inode1,struct inode * inode2)40560eb3b9cSZhihao Cheng static void lock_2_inodes(struct inode *inode1, struct inode *inode2)
40660eb3b9cSZhihao Cheng {
40760eb3b9cSZhihao Cheng mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
40860eb3b9cSZhihao Cheng mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
40960eb3b9cSZhihao Cheng }
41060eb3b9cSZhihao Cheng
41160eb3b9cSZhihao Cheng /**
41260eb3b9cSZhihao Cheng * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes.
41360eb3b9cSZhihao Cheng * @inode1: first inode
41460eb3b9cSZhihao Cheng * @inode2: second inode
41560eb3b9cSZhihao Cheng */
unlock_2_inodes(struct inode * inode1,struct inode * inode2)41660eb3b9cSZhihao Cheng static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
41760eb3b9cSZhihao Cheng {
41860eb3b9cSZhihao Cheng mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
41960eb3b9cSZhihao Cheng mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
42060eb3b9cSZhihao Cheng }
42160eb3b9cSZhihao Cheng
ubifs_tmpfile(struct mnt_idmap * idmap,struct inode * dir,struct file * file,umode_t mode)422011e2b71SChristian Brauner static int ubifs_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
423863f144fSMiklos Szeredi struct file *file, umode_t mode)
424474b9370SRichard Weinberger {
425863f144fSMiklos Szeredi struct dentry *dentry = file->f_path.dentry;
426474b9370SRichard Weinberger struct inode *inode;
427474b9370SRichard Weinberger struct ubifs_info *c = dir->i_sb->s_fs_info;
428a6dab660SZhihao Cheng struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
429a6dab660SZhihao Cheng .dirtied_ino = 1};
430474b9370SRichard Weinberger struct ubifs_budget_req ino_req = { .dirtied_ino = 1 };
43160eb3b9cSZhihao Cheng struct ubifs_inode *ui;
432474b9370SRichard Weinberger int err, instantiated = 0;
433f4f61d2cSRichard Weinberger struct fscrypt_name nm;
434474b9370SRichard Weinberger
435474b9370SRichard Weinberger /*
436a6dab660SZhihao Cheng * Budget request settings: new inode, new direntry, changing the
437a6dab660SZhihao Cheng * parent directory inode.
438a6dab660SZhihao Cheng * Allocate budget separately for new dirtied inode, the budget will
439a6dab660SZhihao Cheng * be released via writeback.
440474b9370SRichard Weinberger */
441474b9370SRichard Weinberger
442474b9370SRichard Weinberger dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
443474b9370SRichard Weinberger dentry, mode, dir->i_ino);
444474b9370SRichard Weinberger
445f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
446f4f61d2cSRichard Weinberger if (err)
447f4f61d2cSRichard Weinberger return err;
448f4f61d2cSRichard Weinberger
449f4f61d2cSRichard Weinberger err = ubifs_budget_space(c, &req);
450f4f61d2cSRichard Weinberger if (err) {
451f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
452f4f61d2cSRichard Weinberger return err;
453f4f61d2cSRichard Weinberger }
454f4f61d2cSRichard Weinberger
455474b9370SRichard Weinberger err = ubifs_budget_space(c, &ino_req);
456474b9370SRichard Weinberger if (err) {
457474b9370SRichard Weinberger ubifs_release_budget(c, &req);
458f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
459474b9370SRichard Weinberger return err;
460474b9370SRichard Weinberger }
461474b9370SRichard Weinberger
462a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, mode, false);
463474b9370SRichard Weinberger if (IS_ERR(inode)) {
464474b9370SRichard Weinberger err = PTR_ERR(inode);
465474b9370SRichard Weinberger goto out_budg;
466474b9370SRichard Weinberger }
467474b9370SRichard Weinberger ui = ubifs_inode(inode);
468474b9370SRichard Weinberger
469474b9370SRichard Weinberger err = ubifs_init_security(dir, inode, &dentry->d_name);
470474b9370SRichard Weinberger if (err)
471474b9370SRichard Weinberger goto out_inode;
472474b9370SRichard Weinberger
473474b9370SRichard Weinberger mutex_lock(&ui->ui_mutex);
474474b9370SRichard Weinberger insert_inode_hash(inode);
475863f144fSMiklos Szeredi d_tmpfile(file, inode);
4766eb61d58SRichard Weinberger ubifs_assert(c, ui->dirty);
4779e0a1fffSRichard Weinberger
478474b9370SRichard Weinberger instantiated = 1;
479474b9370SRichard Weinberger mutex_unlock(&ui->ui_mutex);
480474b9370SRichard Weinberger
48160eb3b9cSZhihao Cheng lock_2_inodes(dir, inode);
482f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
483474b9370SRichard Weinberger if (err)
484474b9370SRichard Weinberger goto out_cancel;
48560eb3b9cSZhihao Cheng unlock_2_inodes(dir, inode);
486474b9370SRichard Weinberger
487474b9370SRichard Weinberger ubifs_release_budget(c, &req);
4881fb815b3SMårten Lindahl fscrypt_free_filename(&nm);
489474b9370SRichard Weinberger
490863f144fSMiklos Szeredi return finish_open_simple(file, 0);
491474b9370SRichard Weinberger
492474b9370SRichard Weinberger out_cancel:
49360eb3b9cSZhihao Cheng unlock_2_inodes(dir, inode);
494474b9370SRichard Weinberger out_inode:
495474b9370SRichard Weinberger make_bad_inode(inode);
496474b9370SRichard Weinberger if (!instantiated)
497474b9370SRichard Weinberger iput(inode);
498474b9370SRichard Weinberger out_budg:
499474b9370SRichard Weinberger ubifs_release_budget(c, &req);
500474b9370SRichard Weinberger if (!instantiated)
501474b9370SRichard Weinberger ubifs_release_budget(c, &ino_req);
502f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
503474b9370SRichard Weinberger ubifs_err(c, "cannot create temporary file, error %d", err);
504474b9370SRichard Weinberger return err;
505474b9370SRichard Weinberger }
506474b9370SRichard Weinberger
5071e51764aSArtem Bityutskiy /**
5081e51764aSArtem Bityutskiy * vfs_dent_type - get VFS directory entry type.
5091e51764aSArtem Bityutskiy * @type: UBIFS directory entry type
5101e51764aSArtem Bityutskiy *
5111e51764aSArtem Bityutskiy * This function converts UBIFS directory entry type into VFS directory entry
5121e51764aSArtem Bityutskiy * type.
5131e51764aSArtem Bityutskiy */
vfs_dent_type(uint8_t type)5141e51764aSArtem Bityutskiy static unsigned int vfs_dent_type(uint8_t type)
5151e51764aSArtem Bityutskiy {
5161e51764aSArtem Bityutskiy switch (type) {
5171e51764aSArtem Bityutskiy case UBIFS_ITYPE_REG:
5181e51764aSArtem Bityutskiy return DT_REG;
5191e51764aSArtem Bityutskiy case UBIFS_ITYPE_DIR:
5201e51764aSArtem Bityutskiy return DT_DIR;
5211e51764aSArtem Bityutskiy case UBIFS_ITYPE_LNK:
5221e51764aSArtem Bityutskiy return DT_LNK;
5231e51764aSArtem Bityutskiy case UBIFS_ITYPE_BLK:
5241e51764aSArtem Bityutskiy return DT_BLK;
5251e51764aSArtem Bityutskiy case UBIFS_ITYPE_CHR:
5261e51764aSArtem Bityutskiy return DT_CHR;
5271e51764aSArtem Bityutskiy case UBIFS_ITYPE_FIFO:
5281e51764aSArtem Bityutskiy return DT_FIFO;
5291e51764aSArtem Bityutskiy case UBIFS_ITYPE_SOCK:
5301e51764aSArtem Bityutskiy return DT_SOCK;
5311e51764aSArtem Bityutskiy default:
5321e51764aSArtem Bityutskiy BUG();
5331e51764aSArtem Bityutskiy }
5341e51764aSArtem Bityutskiy return 0;
5351e51764aSArtem Bityutskiy }
5361e51764aSArtem Bityutskiy
5371e51764aSArtem Bityutskiy /*
5381e51764aSArtem Bityutskiy * The classical Unix view for directory is that it is a linear array of
5391e51764aSArtem Bityutskiy * (name, inode number) entries. Linux/VFS assumes this model as well.
5401e51764aSArtem Bityutskiy * Particularly, 'readdir()' call wants us to return a directory entry offset
5411e51764aSArtem Bityutskiy * which later may be used to continue 'readdir()'ing the directory or to
5421e51764aSArtem Bityutskiy * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this
5431e51764aSArtem Bityutskiy * model because directory entries are identified by keys, which may collide.
5441e51764aSArtem Bityutskiy *
5451e51764aSArtem Bityutskiy * UBIFS uses directory entry hash value for directory offsets, so
5461e51764aSArtem Bityutskiy * 'seekdir()'/'telldir()' may not always work because of possible key
5471e51764aSArtem Bityutskiy * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work
5481e51764aSArtem Bityutskiy * properly by means of saving full directory entry name in the private field
5491e51764aSArtem Bityutskiy * of the file description object.
5501e51764aSArtem Bityutskiy *
5511e51764aSArtem Bityutskiy * This means that UBIFS cannot support NFS which requires full
5521e51764aSArtem Bityutskiy * 'seekdir()'/'telldir()' support.
5531e51764aSArtem Bityutskiy */
ubifs_readdir(struct file * file,struct dir_context * ctx)55401122e06SAl Viro static int ubifs_readdir(struct file *file, struct dir_context *ctx)
5551e51764aSArtem Bityutskiy {
556ba75d570SRichard Weinberger int fstr_real_len = 0, err = 0;
557f4f61d2cSRichard Weinberger struct fscrypt_name nm;
558f4f61d2cSRichard Weinberger struct fscrypt_str fstr = {0};
5591e51764aSArtem Bityutskiy union ubifs_key key;
5601e51764aSArtem Bityutskiy struct ubifs_dent_node *dent;
561496ad9aaSAl Viro struct inode *dir = file_inode(file);
5621e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
56350d9fad7SEric Biggers bool encrypted = IS_ENCRYPTED(dir);
5641e51764aSArtem Bityutskiy
56501122e06SAl Viro dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
5661e51764aSArtem Bityutskiy
56701122e06SAl Viro if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2)
5681e51764aSArtem Bityutskiy /*
5691e51764aSArtem Bityutskiy * The directory was seek'ed to a senseless position or there
5701e51764aSArtem Bityutskiy * are no more entries.
5711e51764aSArtem Bityutskiy */
5721e51764aSArtem Bityutskiy return 0;
5731e51764aSArtem Bityutskiy
574f4f61d2cSRichard Weinberger if (encrypted) {
575ec0caa97SEric Biggers err = fscrypt_prepare_readdir(dir);
5763b1ada55SEric Biggers if (err)
577f4f61d2cSRichard Weinberger return err;
578f4f61d2cSRichard Weinberger
5798b10fe68SJeff Layton err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr);
580f4f61d2cSRichard Weinberger if (err)
581f4f61d2cSRichard Weinberger return err;
582f4f61d2cSRichard Weinberger
583f4f61d2cSRichard Weinberger fstr_real_len = fstr.len;
584f4f61d2cSRichard Weinberger }
585f4f61d2cSRichard Weinberger
586605c912bSArtem Bityutskiy if (file->f_version == 0) {
587605c912bSArtem Bityutskiy /*
588605c912bSArtem Bityutskiy * The file was seek'ed, which means that @file->private_data
589605c912bSArtem Bityutskiy * is now invalid. This may also be just the first
590605c912bSArtem Bityutskiy * 'ubifs_readdir()' invocation, in which case
591605c912bSArtem Bityutskiy * @file->private_data is NULL, and the below code is
592605c912bSArtem Bityutskiy * basically a no-op.
593605c912bSArtem Bityutskiy */
594605c912bSArtem Bityutskiy kfree(file->private_data);
595605c912bSArtem Bityutskiy file->private_data = NULL;
596605c912bSArtem Bityutskiy }
597605c912bSArtem Bityutskiy
598605c912bSArtem Bityutskiy /*
599605c912bSArtem Bityutskiy * 'generic_file_llseek()' unconditionally sets @file->f_version to
600605c912bSArtem Bityutskiy * zero, and we use this for detecting whether the file was seek'ed.
601605c912bSArtem Bityutskiy */
602605c912bSArtem Bityutskiy file->f_version = 1;
603605c912bSArtem Bityutskiy
6041e51764aSArtem Bityutskiy /* File positions 0 and 1 correspond to "." and ".." */
60501122e06SAl Viro if (ctx->pos < 2) {
6066eb61d58SRichard Weinberger ubifs_assert(c, !file->private_data);
607f4f61d2cSRichard Weinberger if (!dir_emit_dots(file, ctx)) {
608f4f61d2cSRichard Weinberger if (encrypted)
609f4f61d2cSRichard Weinberger fscrypt_fname_free_buffer(&fstr);
6101e51764aSArtem Bityutskiy return 0;
611f4f61d2cSRichard Weinberger }
6121e51764aSArtem Bityutskiy
6131e51764aSArtem Bityutskiy /* Find the first entry in TNC and save it */
6141e51764aSArtem Bityutskiy lowest_dent_key(c, &key, dir->i_ino);
615f4f61d2cSRichard Weinberger fname_len(&nm) = 0;
6161e51764aSArtem Bityutskiy dent = ubifs_tnc_next_ent(c, &key, &nm);
6171e51764aSArtem Bityutskiy if (IS_ERR(dent)) {
6181e51764aSArtem Bityutskiy err = PTR_ERR(dent);
6191e51764aSArtem Bityutskiy goto out;
6201e51764aSArtem Bityutskiy }
6211e51764aSArtem Bityutskiy
62201122e06SAl Viro ctx->pos = key_hash_flash(c, &dent->key);
6231e51764aSArtem Bityutskiy file->private_data = dent;
6241e51764aSArtem Bityutskiy }
6251e51764aSArtem Bityutskiy
6261e51764aSArtem Bityutskiy dent = file->private_data;
6271e51764aSArtem Bityutskiy if (!dent) {
6281e51764aSArtem Bityutskiy /*
6291e51764aSArtem Bityutskiy * The directory was seek'ed to and is now readdir'ed.
63001122e06SAl Viro * Find the entry corresponding to @ctx->pos or the closest one.
6311e51764aSArtem Bityutskiy */
63201122e06SAl Viro dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
633f4f61d2cSRichard Weinberger fname_len(&nm) = 0;
6341e51764aSArtem Bityutskiy dent = ubifs_tnc_next_ent(c, &key, &nm);
6351e51764aSArtem Bityutskiy if (IS_ERR(dent)) {
6361e51764aSArtem Bityutskiy err = PTR_ERR(dent);
6371e51764aSArtem Bityutskiy goto out;
6381e51764aSArtem Bityutskiy }
63901122e06SAl Viro ctx->pos = key_hash_flash(c, &dent->key);
6401e51764aSArtem Bityutskiy file->private_data = dent;
6411e51764aSArtem Bityutskiy }
6421e51764aSArtem Bityutskiy
6431e51764aSArtem Bityutskiy while (1) {
644b20e2d99SHyunchul Lee dbg_gen("ino %llu, new f_pos %#x",
645b20e2d99SHyunchul Lee (unsigned long long)le64_to_cpu(dent->inum),
6461e51764aSArtem Bityutskiy key_hash_flash(c, &dent->key));
6476eb61d58SRichard Weinberger ubifs_assert(c, le64_to_cpu(dent->ch.sqnum) >
6480ecb9529SHarvey Harrison ubifs_inode(dir)->creat_sqnum);
6491e51764aSArtem Bityutskiy
650f4f61d2cSRichard Weinberger fname_len(&nm) = le16_to_cpu(dent->nlen);
651f4f61d2cSRichard Weinberger fname_name(&nm) = dent->name;
652f4f61d2cSRichard Weinberger
653f4f61d2cSRichard Weinberger if (encrypted) {
654f4f61d2cSRichard Weinberger fstr.len = fstr_real_len;
655f4f61d2cSRichard Weinberger
656528e3d17SRichard Weinberger err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c,
657528e3d17SRichard Weinberger &dent->key),
658528e3d17SRichard Weinberger le32_to_cpu(dent->cookie),
659528e3d17SRichard Weinberger &nm.disk_name, &fstr);
660ca7f85beSRichard Weinberger if (err)
661f4f61d2cSRichard Weinberger goto out;
662f4f61d2cSRichard Weinberger } else {
663f4f61d2cSRichard Weinberger fstr.len = fname_len(&nm);
664f4f61d2cSRichard Weinberger fstr.name = fname_name(&nm);
665f4f61d2cSRichard Weinberger }
666f4f61d2cSRichard Weinberger
667f4f61d2cSRichard Weinberger if (!dir_emit(ctx, fstr.name, fstr.len,
6681e51764aSArtem Bityutskiy le64_to_cpu(dent->inum),
669f4f61d2cSRichard Weinberger vfs_dent_type(dent->type))) {
670f4f61d2cSRichard Weinberger if (encrypted)
671f4f61d2cSRichard Weinberger fscrypt_fname_free_buffer(&fstr);
6721e51764aSArtem Bityutskiy return 0;
673f4f61d2cSRichard Weinberger }
6741e51764aSArtem Bityutskiy
6751e51764aSArtem Bityutskiy /* Switch to the next entry */
6761e51764aSArtem Bityutskiy key_read(c, &dent->key, &key);
6771e51764aSArtem Bityutskiy dent = ubifs_tnc_next_ent(c, &key, &nm);
6781e51764aSArtem Bityutskiy if (IS_ERR(dent)) {
6791e51764aSArtem Bityutskiy err = PTR_ERR(dent);
6801e51764aSArtem Bityutskiy goto out;
6811e51764aSArtem Bityutskiy }
6821e51764aSArtem Bityutskiy
6831e51764aSArtem Bityutskiy kfree(file->private_data);
68401122e06SAl Viro ctx->pos = key_hash_flash(c, &dent->key);
6851e51764aSArtem Bityutskiy file->private_data = dent;
6861e51764aSArtem Bityutskiy cond_resched();
6871e51764aSArtem Bityutskiy }
6881e51764aSArtem Bityutskiy
6891e51764aSArtem Bityutskiy out:
690aeeb14f7SRichard Weinberger kfree(file->private_data);
691aeeb14f7SRichard Weinberger file->private_data = NULL;
692aeeb14f7SRichard Weinberger
693f4f61d2cSRichard Weinberger if (encrypted)
694f4f61d2cSRichard Weinberger fscrypt_fname_free_buffer(&fstr);
695f4f61d2cSRichard Weinberger
696c83ed4c9SRichard Weinberger if (err != -ENOENT)
697235c362bSSheng Yong ubifs_err(c, "cannot find next direntry, error %d", err);
698a00052a2SRichard Weinberger else
699a00052a2SRichard Weinberger /*
700a00052a2SRichard Weinberger * -ENOENT is a non-fatal error in this context, the TNC uses
701a00052a2SRichard Weinberger * it to indicate that the cursor moved past the current directory
702a00052a2SRichard Weinberger * and readdir() has to stop.
703a00052a2SRichard Weinberger */
704a00052a2SRichard Weinberger err = 0;
705a00052a2SRichard Weinberger
7061e51764aSArtem Bityutskiy
707605c912bSArtem Bityutskiy /* 2 is a special value indicating that there are no more direntries */
70801122e06SAl Viro ctx->pos = 2;
709c83ed4c9SRichard Weinberger return err;
7101e51764aSArtem Bityutskiy }
7111e51764aSArtem Bityutskiy
7121e51764aSArtem Bityutskiy /* Free saved readdir() state when the directory is closed */
ubifs_dir_release(struct inode * dir,struct file * file)7131e51764aSArtem Bityutskiy static int ubifs_dir_release(struct inode *dir, struct file *file)
7141e51764aSArtem Bityutskiy {
7151e51764aSArtem Bityutskiy kfree(file->private_data);
7161e51764aSArtem Bityutskiy file->private_data = NULL;
7171e51764aSArtem Bityutskiy return 0;
7181e51764aSArtem Bityutskiy }
7191e51764aSArtem Bityutskiy
ubifs_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)7201e51764aSArtem Bityutskiy static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
7211e51764aSArtem Bityutskiy struct dentry *dentry)
7221e51764aSArtem Bityutskiy {
7231e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
7242b0143b5SDavid Howells struct inode *inode = d_inode(old_dentry);
7251e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode);
7261e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
7271e51764aSArtem Bityutskiy int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len);
7281e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2,
729dab4b4d2SArtem Bityutskiy .dirtied_ino_d = ALIGN(ui->data_len, 8) };
730f4f61d2cSRichard Weinberger struct fscrypt_name nm;
7311e51764aSArtem Bityutskiy
7321e51764aSArtem Bityutskiy /*
7331e51764aSArtem Bityutskiy * Budget request settings: new direntry, changing the target inode,
7341e51764aSArtem Bityutskiy * changing the parent inode.
7351e51764aSArtem Bityutskiy */
7361e51764aSArtem Bityutskiy
7374cb2a01dSAl Viro dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
7384cb2a01dSAl Viro dentry, inode->i_ino,
7391e51764aSArtem Bityutskiy inode->i_nlink, dir->i_ino);
7406eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(dir));
7416eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(inode));
7428b3884a8SHunter Adrian
7435653878cSEric Biggers err = fscrypt_prepare_link(old_dentry, dir, dentry);
7445653878cSEric Biggers if (err)
7455653878cSEric Biggers return err;
746ac7e47a9SRichard Weinberger
747f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
748f4f61d2cSRichard Weinberger if (err)
749f4f61d2cSRichard Weinberger return err;
750f4f61d2cSRichard Weinberger
751d808efb4SArtem Bityutskiy err = dbg_check_synced_i_size(c, inode);
7521e51764aSArtem Bityutskiy if (err)
753f4f61d2cSRichard Weinberger goto out_fname;
7541e51764aSArtem Bityutskiy
7551e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
7561e51764aSArtem Bityutskiy if (err)
757f4f61d2cSRichard Weinberger goto out_fname;
7581e51764aSArtem Bityutskiy
7591e51764aSArtem Bityutskiy lock_2_inodes(dir, inode);
76032fe905cSRichard Weinberger
76132fe905cSRichard Weinberger /* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
76232fe905cSRichard Weinberger if (inode->i_nlink == 0)
76332fe905cSRichard Weinberger ubifs_delete_orphan(c, inode->i_ino);
76432fe905cSRichard Weinberger
7651e51764aSArtem Bityutskiy inc_nlink(inode);
7667de9c6eeSAl Viro ihold(inode);
767d07d3a7eSJeff Layton inode_set_ctime_current(inode);
7681e51764aSArtem Bityutskiy dir->i_size += sz_change;
7691e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
770d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
771f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
7721e51764aSArtem Bityutskiy if (err)
7731e51764aSArtem Bityutskiy goto out_cancel;
7741e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
7751e51764aSArtem Bityutskiy
7761e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
7771e51764aSArtem Bityutskiy d_instantiate(dentry, inode);
778f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
7791e51764aSArtem Bityutskiy return 0;
7801e51764aSArtem Bityutskiy
7811e51764aSArtem Bityutskiy out_cancel:
7821e51764aSArtem Bityutskiy dir->i_size -= sz_change;
7831e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
7841e51764aSArtem Bityutskiy drop_nlink(inode);
78532fe905cSRichard Weinberger if (inode->i_nlink == 0)
78632fe905cSRichard Weinberger ubifs_add_orphan(c, inode->i_ino);
7871e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
7881e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
7891e51764aSArtem Bityutskiy iput(inode);
790f4f61d2cSRichard Weinberger out_fname:
791f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
7921e51764aSArtem Bityutskiy return err;
7931e51764aSArtem Bityutskiy }
7941e51764aSArtem Bityutskiy
ubifs_unlink(struct inode * dir,struct dentry * dentry)7951e51764aSArtem Bityutskiy static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
7961e51764aSArtem Bityutskiy {
7971e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
7982b0143b5SDavid Howells struct inode *inode = d_inode(dentry);
7991e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
800f4f61d2cSRichard Weinberger int err, sz_change, budgeted = 1;
8011e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
802c43be108SArtem Bityutskiy unsigned int saved_nlink = inode->i_nlink;
803f4f61d2cSRichard Weinberger struct fscrypt_name nm;
8041e51764aSArtem Bityutskiy
8051e51764aSArtem Bityutskiy /*
8061e51764aSArtem Bityutskiy * Budget request settings: deletion direntry, deletion inode (+1 for
8071e51764aSArtem Bityutskiy * @dirtied_ino), changing the parent directory inode. If budgeting
8081e51764aSArtem Bityutskiy * fails, go ahead anyway because we have extra space reserved for
8091e51764aSArtem Bityutskiy * deletions.
8101e51764aSArtem Bityutskiy */
8111e51764aSArtem Bityutskiy
8124cb2a01dSAl Viro dbg_gen("dent '%pd' from ino %lu (nlink %d) in dir ino %lu",
8134cb2a01dSAl Viro dentry, inode->i_ino,
8141e51764aSArtem Bityutskiy inode->i_nlink, dir->i_ino);
815f4f61d2cSRichard Weinberger
816f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
817f4f61d2cSRichard Weinberger if (err)
818f4f61d2cSRichard Weinberger return err;
819f4f61d2cSRichard Weinberger
8209ca2d732SRichard Weinberger err = ubifs_purge_xattrs(inode);
8219ca2d732SRichard Weinberger if (err)
8229ca2d732SRichard Weinberger return err;
8239ca2d732SRichard Weinberger
824f4f61d2cSRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
825f4f61d2cSRichard Weinberger
8266eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(dir));
8276eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(inode));
828d808efb4SArtem Bityutskiy err = dbg_check_synced_i_size(c, inode);
8291e51764aSArtem Bityutskiy if (err)
830f4f61d2cSRichard Weinberger goto out_fname;
8311e51764aSArtem Bityutskiy
8321e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
8331e51764aSArtem Bityutskiy if (err) {
8341e51764aSArtem Bityutskiy if (err != -ENOSPC)
835f4f61d2cSRichard Weinberger goto out_fname;
8361e51764aSArtem Bityutskiy budgeted = 0;
8371e51764aSArtem Bityutskiy }
8381e51764aSArtem Bityutskiy
8391e51764aSArtem Bityutskiy lock_2_inodes(dir, inode);
840d07d3a7eSJeff Layton inode_set_ctime_current(inode);
8411e51764aSArtem Bityutskiy drop_nlink(inode);
8421e51764aSArtem Bityutskiy dir->i_size -= sz_change;
8431e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
844d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
845f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
8461e51764aSArtem Bityutskiy if (err)
8471e51764aSArtem Bityutskiy goto out_cancel;
8481e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
8491e51764aSArtem Bityutskiy
8501e51764aSArtem Bityutskiy if (budgeted)
8511e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
8521e51764aSArtem Bityutskiy else {
8531e51764aSArtem Bityutskiy /* We've deleted something - clean the "no space" flags */
854b137545cSArtem Bityutskiy c->bi.nospace = c->bi.nospace_rp = 0;
8551e51764aSArtem Bityutskiy smp_wmb();
8561e51764aSArtem Bityutskiy }
857f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
8581e51764aSArtem Bityutskiy return 0;
8591e51764aSArtem Bityutskiy
8601e51764aSArtem Bityutskiy out_cancel:
8611e51764aSArtem Bityutskiy dir->i_size += sz_change;
8621e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
863c43be108SArtem Bityutskiy set_nlink(inode, saved_nlink);
8641e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
8651e51764aSArtem Bityutskiy if (budgeted)
8661e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
867f4f61d2cSRichard Weinberger out_fname:
868f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
8691e51764aSArtem Bityutskiy return err;
8701e51764aSArtem Bityutskiy }
8711e51764aSArtem Bityutskiy
8721e51764aSArtem Bityutskiy /**
87327ef523aSYang Li * ubifs_check_dir_empty - check if a directory is empty or not.
8741e51764aSArtem Bityutskiy * @dir: VFS inode object of the directory to check
8751e51764aSArtem Bityutskiy *
8761e51764aSArtem Bityutskiy * This function checks if directory @dir is empty. Returns zero if the
8771e51764aSArtem Bityutskiy * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes
878b8f1da98SRandy Dunlap * in case of errors.
8791e51764aSArtem Bityutskiy */
ubifs_check_dir_empty(struct inode * dir)880f6337d84SRichard Weinberger int ubifs_check_dir_empty(struct inode *dir)
8811e51764aSArtem Bityutskiy {
882f6337d84SRichard Weinberger struct ubifs_info *c = dir->i_sb->s_fs_info;
883f4f61d2cSRichard Weinberger struct fscrypt_name nm = { 0 };
8841e51764aSArtem Bityutskiy struct ubifs_dent_node *dent;
8851e51764aSArtem Bityutskiy union ubifs_key key;
8861e51764aSArtem Bityutskiy int err;
8871e51764aSArtem Bityutskiy
8881e51764aSArtem Bityutskiy lowest_dent_key(c, &key, dir->i_ino);
8891e51764aSArtem Bityutskiy dent = ubifs_tnc_next_ent(c, &key, &nm);
8901e51764aSArtem Bityutskiy if (IS_ERR(dent)) {
8911e51764aSArtem Bityutskiy err = PTR_ERR(dent);
8921e51764aSArtem Bityutskiy if (err == -ENOENT)
8931e51764aSArtem Bityutskiy err = 0;
8941e51764aSArtem Bityutskiy } else {
8951e51764aSArtem Bityutskiy kfree(dent);
8961e51764aSArtem Bityutskiy err = -ENOTEMPTY;
8971e51764aSArtem Bityutskiy }
8981e51764aSArtem Bityutskiy return err;
8991e51764aSArtem Bityutskiy }
9001e51764aSArtem Bityutskiy
ubifs_rmdir(struct inode * dir,struct dentry * dentry)9011e51764aSArtem Bityutskiy static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
9021e51764aSArtem Bityutskiy {
9031e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
9042b0143b5SDavid Howells struct inode *inode = d_inode(dentry);
905f4f61d2cSRichard Weinberger int err, sz_change, budgeted = 1;
9061e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
9071e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
908f4f61d2cSRichard Weinberger struct fscrypt_name nm;
9091e51764aSArtem Bityutskiy
9101e51764aSArtem Bityutskiy /*
9111e51764aSArtem Bityutskiy * Budget request settings: deletion direntry, deletion inode and
9121e51764aSArtem Bityutskiy * changing the parent inode. If budgeting fails, go ahead anyway
9131e51764aSArtem Bityutskiy * because we have extra space reserved for deletions.
9141e51764aSArtem Bityutskiy */
9151e51764aSArtem Bityutskiy
9164cb2a01dSAl Viro dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
9174cb2a01dSAl Viro inode->i_ino, dir->i_ino);
9186eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(dir));
9196eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(inode));
920f6337d84SRichard Weinberger err = ubifs_check_dir_empty(d_inode(dentry));
9211e51764aSArtem Bityutskiy if (err)
9221e51764aSArtem Bityutskiy return err;
9231e51764aSArtem Bityutskiy
924f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm);
925f4f61d2cSRichard Weinberger if (err)
926f4f61d2cSRichard Weinberger return err;
927f4f61d2cSRichard Weinberger
9289ca2d732SRichard Weinberger err = ubifs_purge_xattrs(inode);
9299ca2d732SRichard Weinberger if (err)
9309ca2d732SRichard Weinberger return err;
9319ca2d732SRichard Weinberger
932f4f61d2cSRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
933f4f61d2cSRichard Weinberger
9341e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
9351e51764aSArtem Bityutskiy if (err) {
9361e51764aSArtem Bityutskiy if (err != -ENOSPC)
937f4f61d2cSRichard Weinberger goto out_fname;
9381e51764aSArtem Bityutskiy budgeted = 0;
9391e51764aSArtem Bityutskiy }
9401e51764aSArtem Bityutskiy
9411e51764aSArtem Bityutskiy lock_2_inodes(dir, inode);
942d07d3a7eSJeff Layton inode_set_ctime_current(inode);
9431e51764aSArtem Bityutskiy clear_nlink(inode);
9441e51764aSArtem Bityutskiy drop_nlink(dir);
9451e51764aSArtem Bityutskiy dir->i_size -= sz_change;
9461e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
947d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
948f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
9491e51764aSArtem Bityutskiy if (err)
9501e51764aSArtem Bityutskiy goto out_cancel;
9511e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
9521e51764aSArtem Bityutskiy
9531e51764aSArtem Bityutskiy if (budgeted)
9541e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
9551e51764aSArtem Bityutskiy else {
9561e51764aSArtem Bityutskiy /* We've deleted something - clean the "no space" flags */
957b137545cSArtem Bityutskiy c->bi.nospace = c->bi.nospace_rp = 0;
9581e51764aSArtem Bityutskiy smp_wmb();
9591e51764aSArtem Bityutskiy }
960f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
9611e51764aSArtem Bityutskiy return 0;
9621e51764aSArtem Bityutskiy
9631e51764aSArtem Bityutskiy out_cancel:
9641e51764aSArtem Bityutskiy dir->i_size += sz_change;
9651e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
9661e51764aSArtem Bityutskiy inc_nlink(dir);
967c43be108SArtem Bityutskiy set_nlink(inode, 2);
9681e51764aSArtem Bityutskiy unlock_2_inodes(dir, inode);
9691e51764aSArtem Bityutskiy if (budgeted)
9701e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
971f4f61d2cSRichard Weinberger out_fname:
972f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
9731e51764aSArtem Bityutskiy return err;
9741e51764aSArtem Bityutskiy }
9751e51764aSArtem Bityutskiy
ubifs_mkdir(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode)976c54bd91eSChristian Brauner static int ubifs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
977549c7297SChristian Brauner struct dentry *dentry, umode_t mode)
9781e51764aSArtem Bityutskiy {
9791e51764aSArtem Bityutskiy struct inode *inode;
9801e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
9811e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
982f4f61d2cSRichard Weinberger int err, sz_change;
983a6dab660SZhihao Cheng struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
984a6dab660SZhihao Cheng .dirtied_ino = 1};
985f4f61d2cSRichard Weinberger struct fscrypt_name nm;
9861e51764aSArtem Bityutskiy
9871e51764aSArtem Bityutskiy /*
9881e51764aSArtem Bityutskiy * Budget request settings: new inode, new direntry and changing parent
9891e51764aSArtem Bityutskiy * directory inode.
9901e51764aSArtem Bityutskiy */
9911e51764aSArtem Bityutskiy
9924cb2a01dSAl Viro dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
9934cb2a01dSAl Viro dentry, mode, dir->i_ino);
9941e51764aSArtem Bityutskiy
9951e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
9961e51764aSArtem Bityutskiy if (err)
9971e51764aSArtem Bityutskiy return err;
9981e51764aSArtem Bityutskiy
99976786a0fSEric Biggers err = ubifs_prepare_create(dir, dentry, &nm);
1000f4f61d2cSRichard Weinberger if (err)
1001f4f61d2cSRichard Weinberger goto out_budg;
1002f4f61d2cSRichard Weinberger
1003f4f61d2cSRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
1004f4f61d2cSRichard Weinberger
1005a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, S_IFDIR | mode, false);
10061e51764aSArtem Bityutskiy if (IS_ERR(inode)) {
10071e51764aSArtem Bityutskiy err = PTR_ERR(inode);
1008f4f61d2cSRichard Weinberger goto out_fname;
10091e51764aSArtem Bityutskiy }
10101e51764aSArtem Bityutskiy
1011d7f0b70dSSubodh Nijsure err = ubifs_init_security(dir, inode, &dentry->d_name);
1012d7f0b70dSSubodh Nijsure if (err)
10139401a795STaesoo Kim goto out_inode;
1014d7f0b70dSSubodh Nijsure
10151e51764aSArtem Bityutskiy mutex_lock(&dir_ui->ui_mutex);
10161e51764aSArtem Bityutskiy insert_inode_hash(inode);
10171e51764aSArtem Bityutskiy inc_nlink(inode);
10181e51764aSArtem Bityutskiy inc_nlink(dir);
10191e51764aSArtem Bityutskiy dir->i_size += sz_change;
10201e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
1021d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
1022f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
10231e51764aSArtem Bityutskiy if (err) {
1024235c362bSSheng Yong ubifs_err(c, "cannot create directory, error %d", err);
10251e51764aSArtem Bityutskiy goto out_cancel;
10261e51764aSArtem Bityutskiy }
10271e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
10281e51764aSArtem Bityutskiy
10291e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
10301e51764aSArtem Bityutskiy d_instantiate(dentry, inode);
1031f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
10321e51764aSArtem Bityutskiy return 0;
10331e51764aSArtem Bityutskiy
10341e51764aSArtem Bityutskiy out_cancel:
10351e51764aSArtem Bityutskiy dir->i_size -= sz_change;
10361e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
10371e51764aSArtem Bityutskiy drop_nlink(dir);
10381e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
10399401a795STaesoo Kim out_inode:
10401e51764aSArtem Bityutskiy make_bad_inode(inode);
10411e51764aSArtem Bityutskiy iput(inode);
1042f4f61d2cSRichard Weinberger out_fname:
1043f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
10441e51764aSArtem Bityutskiy out_budg:
10451e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
10461e51764aSArtem Bityutskiy return err;
10471e51764aSArtem Bityutskiy }
10481e51764aSArtem Bityutskiy
ubifs_mknod(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,dev_t rdev)10495ebb29beSChristian Brauner static int ubifs_mknod(struct mnt_idmap *idmap, struct inode *dir,
1050549c7297SChristian Brauner struct dentry *dentry, umode_t mode, dev_t rdev)
10511e51764aSArtem Bityutskiy {
10521e51764aSArtem Bityutskiy struct inode *inode;
10531e51764aSArtem Bityutskiy struct ubifs_inode *ui;
10541e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
10551e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
10561e51764aSArtem Bityutskiy union ubifs_dev_desc *dev = NULL;
1057f4f61d2cSRichard Weinberger int sz_change;
10581e51764aSArtem Bityutskiy int err, devlen = 0;
10591e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
1060dab4b4d2SArtem Bityutskiy .dirtied_ino = 1 };
1061f4f61d2cSRichard Weinberger struct fscrypt_name nm;
10621e51764aSArtem Bityutskiy
10631e51764aSArtem Bityutskiy /*
10641e51764aSArtem Bityutskiy * Budget request settings: new inode, new direntry and changing parent
10651e51764aSArtem Bityutskiy * directory inode.
10661e51764aSArtem Bityutskiy */
10671e51764aSArtem Bityutskiy
10684cb2a01dSAl Viro dbg_gen("dent '%pd' in dir ino %lu", dentry, dir->i_ino);
10691e51764aSArtem Bityutskiy
10701e51764aSArtem Bityutskiy if (S_ISBLK(mode) || S_ISCHR(mode)) {
10711e51764aSArtem Bityutskiy dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
10721e51764aSArtem Bityutskiy if (!dev)
10731e51764aSArtem Bityutskiy return -ENOMEM;
10741e51764aSArtem Bityutskiy devlen = ubifs_encode_dev(dev, rdev);
10751e51764aSArtem Bityutskiy }
10761e51764aSArtem Bityutskiy
10774d35ca4fSHyunchul Lee req.new_ino_d = ALIGN(devlen, 8);
10781e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
10791e51764aSArtem Bityutskiy if (err) {
10801e51764aSArtem Bityutskiy kfree(dev);
10811e51764aSArtem Bityutskiy return err;
10821e51764aSArtem Bityutskiy }
10831e51764aSArtem Bityutskiy
108476786a0fSEric Biggers err = ubifs_prepare_create(dir, dentry, &nm);
108563ed6573SRichard Weinberger if (err) {
108663ed6573SRichard Weinberger kfree(dev);
1087f4f61d2cSRichard Weinberger goto out_budg;
108863ed6573SRichard Weinberger }
1089f4f61d2cSRichard Weinberger
1090f4f61d2cSRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
1091f4f61d2cSRichard Weinberger
1092a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, mode, false);
10931e51764aSArtem Bityutskiy if (IS_ERR(inode)) {
10941e51764aSArtem Bityutskiy kfree(dev);
10951e51764aSArtem Bityutskiy err = PTR_ERR(inode);
1096f4f61d2cSRichard Weinberger goto out_fname;
10971e51764aSArtem Bityutskiy }
10981e51764aSArtem Bityutskiy
10991e51764aSArtem Bityutskiy init_special_inode(inode, inode->i_mode, rdev);
11001e51764aSArtem Bityutskiy inode->i_size = ubifs_inode(inode)->ui_size = devlen;
11011e51764aSArtem Bityutskiy ui = ubifs_inode(inode);
11021e51764aSArtem Bityutskiy ui->data = dev;
11031e51764aSArtem Bityutskiy ui->data_len = devlen;
11041e51764aSArtem Bityutskiy
1105d7f0b70dSSubodh Nijsure err = ubifs_init_security(dir, inode, &dentry->d_name);
1106d7f0b70dSSubodh Nijsure if (err)
11079401a795STaesoo Kim goto out_inode;
1108d7f0b70dSSubodh Nijsure
11091e51764aSArtem Bityutskiy mutex_lock(&dir_ui->ui_mutex);
11101e51764aSArtem Bityutskiy dir->i_size += sz_change;
11111e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
1112d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
1113f4f61d2cSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
11141e51764aSArtem Bityutskiy if (err)
11151e51764aSArtem Bityutskiy goto out_cancel;
11161e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
11171e51764aSArtem Bityutskiy
11181e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
11191e51764aSArtem Bityutskiy insert_inode_hash(inode);
11201e51764aSArtem Bityutskiy d_instantiate(dentry, inode);
1121f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
11221e51764aSArtem Bityutskiy return 0;
11231e51764aSArtem Bityutskiy
11241e51764aSArtem Bityutskiy out_cancel:
11251e51764aSArtem Bityutskiy dir->i_size -= sz_change;
11261e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
11271e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
11289401a795STaesoo Kim out_inode:
11291e51764aSArtem Bityutskiy make_bad_inode(inode);
11301e51764aSArtem Bityutskiy iput(inode);
1131f4f61d2cSRichard Weinberger out_fname:
1132f4f61d2cSRichard Weinberger fscrypt_free_filename(&nm);
11331e51764aSArtem Bityutskiy out_budg:
11341e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
11351e51764aSArtem Bityutskiy return err;
11361e51764aSArtem Bityutskiy }
11371e51764aSArtem Bityutskiy
ubifs_symlink(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,const char * symname)11387a77db95SChristian Brauner static int ubifs_symlink(struct mnt_idmap *idmap, struct inode *dir,
1139549c7297SChristian Brauner struct dentry *dentry, const char *symname)
11401e51764aSArtem Bityutskiy {
11411e51764aSArtem Bityutskiy struct inode *inode;
11421e51764aSArtem Bityutskiy struct ubifs_inode *ui;
11431e51764aSArtem Bityutskiy struct ubifs_inode *dir_ui = ubifs_inode(dir);
11441e51764aSArtem Bityutskiy struct ubifs_info *c = dir->i_sb->s_fs_info;
114500ee8b60SRichard Weinberger int err, sz_change, len = strlen(symname);
11460e4dda29SEric Biggers struct fscrypt_str disk_link;
11471e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
1148dab4b4d2SArtem Bityutskiy .dirtied_ino = 1 };
1149ca7f85beSRichard Weinberger struct fscrypt_name nm;
1150ca7f85beSRichard Weinberger
11510e4dda29SEric Biggers dbg_gen("dent '%pd', target '%s' in dir ino %lu", dentry,
11520e4dda29SEric Biggers symname, dir->i_ino);
11530e4dda29SEric Biggers
11540e4dda29SEric Biggers err = fscrypt_prepare_symlink(dir, symname, len, UBIFS_MAX_INO_DATA,
11550e4dda29SEric Biggers &disk_link);
1156ca7f85beSRichard Weinberger if (err)
11570e4dda29SEric Biggers return err;
11581e51764aSArtem Bityutskiy
11591e51764aSArtem Bityutskiy /*
11601e51764aSArtem Bityutskiy * Budget request settings: new inode, new direntry and changing parent
11611e51764aSArtem Bityutskiy * directory inode.
11621e51764aSArtem Bityutskiy */
1163c2c36cc6SZhihao Cheng req.new_ino_d = ALIGN(disk_link.len - 1, 8);
11641e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &req);
11651e51764aSArtem Bityutskiy if (err)
11661e51764aSArtem Bityutskiy return err;
11671e51764aSArtem Bityutskiy
116876786a0fSEric Biggers err = ubifs_prepare_create(dir, dentry, &nm);
1169ca7f85beSRichard Weinberger if (err)
1170ca7f85beSRichard Weinberger goto out_budg;
1171ca7f85beSRichard Weinberger
117200ee8b60SRichard Weinberger sz_change = CALC_DENT_SIZE(fname_len(&nm));
117300ee8b60SRichard Weinberger
1174a0c51565SZhihao Cheng inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO, false);
11751e51764aSArtem Bityutskiy if (IS_ERR(inode)) {
11761e51764aSArtem Bityutskiy err = PTR_ERR(inode);
1177ca7f85beSRichard Weinberger goto out_fname;
11781e51764aSArtem Bityutskiy }
11791e51764aSArtem Bityutskiy
11801e51764aSArtem Bityutskiy ui = ubifs_inode(inode);
1181ca7f85beSRichard Weinberger ui->data = kmalloc(disk_link.len, GFP_NOFS);
11821e51764aSArtem Bityutskiy if (!ui->data) {
11831e51764aSArtem Bityutskiy err = -ENOMEM;
11841e51764aSArtem Bityutskiy goto out_inode;
11851e51764aSArtem Bityutskiy }
11861e51764aSArtem Bityutskiy
11870e4dda29SEric Biggers if (IS_ENCRYPTED(inode)) {
11880e4dda29SEric Biggers disk_link.name = ui->data; /* encrypt directly into ui->data */
11890e4dda29SEric Biggers err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
11906b46d444SEric Biggers if (err)
1191ca7f85beSRichard Weinberger goto out_inode;
1192ca7f85beSRichard Weinberger } else {
11930e4dda29SEric Biggers memcpy(ui->data, disk_link.name, disk_link.len);
11940f301bd3SAl Viro inode->i_link = ui->data;
1195ca7f85beSRichard Weinberger }
1196ca7f85beSRichard Weinberger
11971e51764aSArtem Bityutskiy /*
11981e51764aSArtem Bityutskiy * The terminating zero byte is not written to the flash media and it
11991e51764aSArtem Bityutskiy * is put just to make later in-memory string processing simpler. Thus,
12000e4dda29SEric Biggers * data length is @disk_link.len - 1, not @disk_link.len.
12011e51764aSArtem Bityutskiy */
1202ca7f85beSRichard Weinberger ui->data_len = disk_link.len - 1;
1203ca7f85beSRichard Weinberger inode->i_size = ubifs_inode(inode)->ui_size = disk_link.len - 1;
12041e51764aSArtem Bityutskiy
1205d7f0b70dSSubodh Nijsure err = ubifs_init_security(dir, inode, &dentry->d_name);
1206d7f0b70dSSubodh Nijsure if (err)
12079401a795STaesoo Kim goto out_inode;
1208d7f0b70dSSubodh Nijsure
12091e51764aSArtem Bityutskiy mutex_lock(&dir_ui->ui_mutex);
12101e51764aSArtem Bityutskiy dir->i_size += sz_change;
12111e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
1212d07d3a7eSJeff Layton dir->i_mtime = inode_set_ctime_to_ts(dir, inode_get_ctime(inode));
1213ca7f85beSRichard Weinberger err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
12141e51764aSArtem Bityutskiy if (err)
12151e51764aSArtem Bityutskiy goto out_cancel;
12161e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
12171e51764aSArtem Bityutskiy
12181e51764aSArtem Bityutskiy insert_inode_hash(inode);
12191e51764aSArtem Bityutskiy d_instantiate(dentry, inode);
12206b46d444SEric Biggers err = 0;
12216b46d444SEric Biggers goto out_fname;
12221e51764aSArtem Bityutskiy
12231e51764aSArtem Bityutskiy out_cancel:
12241e51764aSArtem Bityutskiy dir->i_size -= sz_change;
12251e51764aSArtem Bityutskiy dir_ui->ui_size = dir->i_size;
12261e51764aSArtem Bityutskiy mutex_unlock(&dir_ui->ui_mutex);
12271e51764aSArtem Bityutskiy out_inode:
1228*17be0edeSZhihao Cheng /* Free inode->i_link before inode is marked as bad. */
1229*17be0edeSZhihao Cheng fscrypt_free_inode(inode);
12301e51764aSArtem Bityutskiy make_bad_inode(inode);
12311e51764aSArtem Bityutskiy iput(inode);
1232ca7f85beSRichard Weinberger out_fname:
1233ca7f85beSRichard Weinberger fscrypt_free_filename(&nm);
12341e51764aSArtem Bityutskiy out_budg:
12351e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
12361e51764aSArtem Bityutskiy return err;
12371e51764aSArtem Bityutskiy }
12381e51764aSArtem Bityutskiy
12391e51764aSArtem Bityutskiy /**
12409e0a1fffSRichard Weinberger * lock_4_inodes - a wrapper for locking three UBIFS inodes.
12411e51764aSArtem Bityutskiy * @inode1: first inode
12421e51764aSArtem Bityutskiy * @inode2: second inode
12431e51764aSArtem Bityutskiy * @inode3: third inode
12447296c8afSAlexander Dahl * @inode4: fourth inode
12451e51764aSArtem Bityutskiy *
124682c1593cSArtem Bityutskiy * This function is used for 'ubifs_rename()' and @inode1 may be the same as
12479e0a1fffSRichard Weinberger * @inode2 whereas @inode3 and @inode4 may be %NULL.
124882c1593cSArtem Bityutskiy *
124982c1593cSArtem Bityutskiy * We do not implement any tricks to guarantee strict lock ordering, because
125082c1593cSArtem Bityutskiy * VFS has already done it for us on the @i_mutex. So this is just a simple
125182c1593cSArtem Bityutskiy * wrapper function.
12521e51764aSArtem Bityutskiy */
lock_4_inodes(struct inode * inode1,struct inode * inode2,struct inode * inode3,struct inode * inode4)12539e0a1fffSRichard Weinberger static void lock_4_inodes(struct inode *inode1, struct inode *inode2,
12549e0a1fffSRichard Weinberger struct inode *inode3, struct inode *inode4)
12551e51764aSArtem Bityutskiy {
12561e51764aSArtem Bityutskiy mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
125782c1593cSArtem Bityutskiy if (inode2 != inode1)
125882c1593cSArtem Bityutskiy mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
125982c1593cSArtem Bityutskiy if (inode3)
126082c1593cSArtem Bityutskiy mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3);
12619e0a1fffSRichard Weinberger if (inode4)
12629e0a1fffSRichard Weinberger mutex_lock_nested(&ubifs_inode(inode4)->ui_mutex, WB_MUTEX_4);
12631e51764aSArtem Bityutskiy }
12641e51764aSArtem Bityutskiy
12651e51764aSArtem Bityutskiy /**
12669e0a1fffSRichard Weinberger * unlock_4_inodes - a wrapper for unlocking three UBIFS inodes for rename.
12671e51764aSArtem Bityutskiy * @inode1: first inode
12681e51764aSArtem Bityutskiy * @inode2: second inode
12691e51764aSArtem Bityutskiy * @inode3: third inode
12707296c8afSAlexander Dahl * @inode4: fourth inode
12711e51764aSArtem Bityutskiy */
unlock_4_inodes(struct inode * inode1,struct inode * inode2,struct inode * inode3,struct inode * inode4)12729e0a1fffSRichard Weinberger static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
12739e0a1fffSRichard Weinberger struct inode *inode3, struct inode *inode4)
12741e51764aSArtem Bityutskiy {
12759e0a1fffSRichard Weinberger if (inode4)
12769e0a1fffSRichard Weinberger mutex_unlock(&ubifs_inode(inode4)->ui_mutex);
12771e51764aSArtem Bityutskiy if (inode3)
12781e51764aSArtem Bityutskiy mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
127982c1593cSArtem Bityutskiy if (inode1 != inode2)
128082c1593cSArtem Bityutskiy mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
128182c1593cSArtem Bityutskiy mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
12821e51764aSArtem Bityutskiy }
12831e51764aSArtem Bityutskiy
do_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)1284390975acSRichard Weinberger static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
1285f03b8ad8SMiklos Szeredi struct inode *new_dir, struct dentry *new_dentry,
1286f03b8ad8SMiklos Szeredi unsigned int flags)
12871e51764aSArtem Bityutskiy {
12881e51764aSArtem Bityutskiy struct ubifs_info *c = old_dir->i_sb->s_fs_info;
12892b0143b5SDavid Howells struct inode *old_inode = d_inode(old_dentry);
12902b0143b5SDavid Howells struct inode *new_inode = d_inode(new_dentry);
12919e0a1fffSRichard Weinberger struct inode *whiteout = NULL;
12921e51764aSArtem Bityutskiy struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode);
12939e0a1fffSRichard Weinberger struct ubifs_inode *whiteout_ui = NULL;
12941e51764aSArtem Bityutskiy int err, release, sync = 0, move = (new_dir != old_dir);
12951e51764aSArtem Bityutskiy int is_dir = S_ISDIR(old_inode->i_mode);
1296f4f61d2cSRichard Weinberger int unlink = !!new_inode, new_sz, old_sz;
12971e51764aSArtem Bityutskiy struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
12981e51764aSArtem Bityutskiy .dirtied_ino = 3 };
12991e51764aSArtem Bityutskiy struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
1300dab4b4d2SArtem Bityutskiy .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
1301278d9a24SZhihao Cheng struct ubifs_budget_req wht_req;
13023f649ab7SKees Cook unsigned int saved_nlink;
1303f4f61d2cSRichard Weinberger struct fscrypt_name old_nm, new_nm;
13041e51764aSArtem Bityutskiy
13051e51764aSArtem Bityutskiy /*
1306278d9a24SZhihao Cheng * Budget request settings:
1307278d9a24SZhihao Cheng * req: deletion direntry, new direntry, removing the old inode,
1308278d9a24SZhihao Cheng * and changing old and new parent directory inodes.
13091e51764aSArtem Bityutskiy *
1310278d9a24SZhihao Cheng * wht_req: new whiteout inode for RENAME_WHITEOUT.
1311278d9a24SZhihao Cheng *
1312278d9a24SZhihao Cheng * ino_req: marks the target inode as dirty and does not write it.
13131e51764aSArtem Bityutskiy */
13141e51764aSArtem Bityutskiy
13159e0a1fffSRichard Weinberger dbg_gen("dent '%pd' ino %lu in dir ino %lu to dent '%pd' in dir ino %lu flags 0x%x",
13164cb2a01dSAl Viro old_dentry, old_inode->i_ino, old_dir->i_ino,
13179e0a1fffSRichard Weinberger new_dentry, new_dir->i_ino, flags);
13189e0a1fffSRichard Weinberger
13199ca2d732SRichard Weinberger if (unlink) {
13206eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(new_inode));
132182c1593cSArtem Bityutskiy
132225fce616SZhihao Cheng /* Budget for old inode's data when its nlink > 1. */
132325fce616SZhihao Cheng req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8);
13249ca2d732SRichard Weinberger err = ubifs_purge_xattrs(new_inode);
13259ca2d732SRichard Weinberger if (err)
13269ca2d732SRichard Weinberger return err;
13279ca2d732SRichard Weinberger }
13289ca2d732SRichard Weinberger
13291e51764aSArtem Bityutskiy if (unlink && is_dir) {
1330f6337d84SRichard Weinberger err = ubifs_check_dir_empty(new_inode);
13311e51764aSArtem Bityutskiy if (err)
13321e51764aSArtem Bityutskiy return err;
13331e51764aSArtem Bityutskiy }
13341e51764aSArtem Bityutskiy
1335f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_nm);
13361e51764aSArtem Bityutskiy if (err)
13371e51764aSArtem Bityutskiy return err;
1338f4f61d2cSRichard Weinberger
1339f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &new_nm);
1340f4f61d2cSRichard Weinberger if (err) {
1341f4f61d2cSRichard Weinberger fscrypt_free_filename(&old_nm);
1342f4f61d2cSRichard Weinberger return err;
1343f4f61d2cSRichard Weinberger }
1344f4f61d2cSRichard Weinberger
1345f4f61d2cSRichard Weinberger new_sz = CALC_DENT_SIZE(fname_len(&new_nm));
1346f4f61d2cSRichard Weinberger old_sz = CALC_DENT_SIZE(fname_len(&old_nm));
1347f4f61d2cSRichard Weinberger
1348f4f61d2cSRichard Weinberger err = ubifs_budget_space(c, &req);
1349f4f61d2cSRichard Weinberger if (err) {
1350f4f61d2cSRichard Weinberger fscrypt_free_filename(&old_nm);
1351f4f61d2cSRichard Weinberger fscrypt_free_filename(&new_nm);
1352f4f61d2cSRichard Weinberger return err;
1353f4f61d2cSRichard Weinberger }
13541e51764aSArtem Bityutskiy err = ubifs_budget_space(c, &ino_req);
13551e51764aSArtem Bityutskiy if (err) {
1356f4f61d2cSRichard Weinberger fscrypt_free_filename(&old_nm);
1357f4f61d2cSRichard Weinberger fscrypt_free_filename(&new_nm);
13581e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
13591e51764aSArtem Bityutskiy return err;
13601e51764aSArtem Bityutskiy }
13611e51764aSArtem Bityutskiy
13629e0a1fffSRichard Weinberger if (flags & RENAME_WHITEOUT) {
13639e0a1fffSRichard Weinberger union ubifs_dev_desc *dev = NULL;
13649e0a1fffSRichard Weinberger
13659e0a1fffSRichard Weinberger dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
13669e0a1fffSRichard Weinberger if (!dev) {
1367bb50c632SHyunchul Lee err = -ENOMEM;
1368bb50c632SHyunchul Lee goto out_release;
13699e0a1fffSRichard Weinberger }
13709e0a1fffSRichard Weinberger
1371278d9a24SZhihao Cheng /*
1372278d9a24SZhihao Cheng * The whiteout inode without dentry is pinned in memory,
1373278d9a24SZhihao Cheng * umount won't happen during rename process because we
1374278d9a24SZhihao Cheng * got parent dentry.
1375278d9a24SZhihao Cheng */
1376278d9a24SZhihao Cheng whiteout = create_whiteout(old_dir, old_dentry);
1377278d9a24SZhihao Cheng if (IS_ERR(whiteout)) {
1378278d9a24SZhihao Cheng err = PTR_ERR(whiteout);
13799e0a1fffSRichard Weinberger kfree(dev);
1380bb50c632SHyunchul Lee goto out_release;
13819e0a1fffSRichard Weinberger }
13829e0a1fffSRichard Weinberger
13839e0a1fffSRichard Weinberger whiteout_ui = ubifs_inode(whiteout);
13849e0a1fffSRichard Weinberger whiteout_ui->data = dev;
13859e0a1fffSRichard Weinberger whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0));
13866eb61d58SRichard Weinberger ubifs_assert(c, !whiteout_ui->dirty);
1387afd42704SZhihao Cheng
1388afd42704SZhihao Cheng memset(&wht_req, 0, sizeof(struct ubifs_budget_req));
1389278d9a24SZhihao Cheng wht_req.new_ino = 1;
1390278d9a24SZhihao Cheng wht_req.new_ino_d = ALIGN(whiteout_ui->data_len, 8);
1391afd42704SZhihao Cheng /*
1392afd42704SZhihao Cheng * To avoid deadlock between space budget (holds ui_mutex and
1393afd42704SZhihao Cheng * waits wb work) and writeback work(waits ui_mutex), do space
1394afd42704SZhihao Cheng * budget before ubifs inodes locked.
1395afd42704SZhihao Cheng */
1396afd42704SZhihao Cheng err = ubifs_budget_space(c, &wht_req);
1397afd42704SZhihao Cheng if (err) {
1398278d9a24SZhihao Cheng /*
1399278d9a24SZhihao Cheng * Whiteout inode can not be written on flash by
1400278d9a24SZhihao Cheng * ubifs_jnl_write_inode(), because it's neither
1401278d9a24SZhihao Cheng * dirty nor zero-nlink.
1402278d9a24SZhihao Cheng */
1403afd42704SZhihao Cheng iput(whiteout);
1404afd42704SZhihao Cheng goto out_release;
1405afd42704SZhihao Cheng }
140670575727SBaokun Li
140770575727SBaokun Li /* Add the old_dentry size to the old_dir size. */
140870575727SBaokun Li old_sz -= CALC_DENT_SIZE(fname_len(&old_nm));
14099e0a1fffSRichard Weinberger }
14109e0a1fffSRichard Weinberger
14119e0a1fffSRichard Weinberger lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
14121e51764aSArtem Bityutskiy
14131e51764aSArtem Bityutskiy /*
14141e51764aSArtem Bityutskiy * Like most other Unix systems, set the @i_ctime for inodes on a
14151e51764aSArtem Bityutskiy * rename.
14161e51764aSArtem Bityutskiy */
1417e54c86fdSJeff Layton simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
14181e51764aSArtem Bityutskiy
14191e51764aSArtem Bityutskiy /* We must adjust parent link count when renaming directories */
14201e51764aSArtem Bityutskiy if (is_dir) {
14211e51764aSArtem Bityutskiy if (move) {
14221e51764aSArtem Bityutskiy /*
14231e51764aSArtem Bityutskiy * @old_dir loses a link because we are moving
14241e51764aSArtem Bityutskiy * @old_inode to a different directory.
14251e51764aSArtem Bityutskiy */
14261e51764aSArtem Bityutskiy drop_nlink(old_dir);
14271e51764aSArtem Bityutskiy /*
14281e51764aSArtem Bityutskiy * @new_dir only gains a link if we are not also
14291e51764aSArtem Bityutskiy * overwriting an existing directory.
14301e51764aSArtem Bityutskiy */
14311e51764aSArtem Bityutskiy if (!unlink)
14321e51764aSArtem Bityutskiy inc_nlink(new_dir);
14331e51764aSArtem Bityutskiy } else {
14341e51764aSArtem Bityutskiy /*
14351e51764aSArtem Bityutskiy * @old_inode is not moving to a different directory,
14361e51764aSArtem Bityutskiy * but @old_dir still loses a link if we are
14371e51764aSArtem Bityutskiy * overwriting an existing directory.
14381e51764aSArtem Bityutskiy */
14391e51764aSArtem Bityutskiy if (unlink)
14401e51764aSArtem Bityutskiy drop_nlink(old_dir);
14411e51764aSArtem Bityutskiy }
14421e51764aSArtem Bityutskiy }
14431e51764aSArtem Bityutskiy
14441e51764aSArtem Bityutskiy old_dir->i_size -= old_sz;
14451e51764aSArtem Bityutskiy ubifs_inode(old_dir)->ui_size = old_dir->i_size;
14461e51764aSArtem Bityutskiy
14471e51764aSArtem Bityutskiy /*
14481e51764aSArtem Bityutskiy * And finally, if we unlinked a direntry which happened to have the
14491e51764aSArtem Bityutskiy * same name as the moved direntry, we have to decrement @i_nlink of
1450e54c86fdSJeff Layton * the unlinked inode.
14511e51764aSArtem Bityutskiy */
14521e51764aSArtem Bityutskiy if (unlink) {
14531e51764aSArtem Bityutskiy /*
14541e51764aSArtem Bityutskiy * Directories cannot have hard-links, so if this is a
1455c43be108SArtem Bityutskiy * directory, just clear @i_nlink.
14561e51764aSArtem Bityutskiy */
1457c43be108SArtem Bityutskiy saved_nlink = new_inode->i_nlink;
14581e51764aSArtem Bityutskiy if (is_dir)
1459c43be108SArtem Bityutskiy clear_nlink(new_inode);
1460c43be108SArtem Bityutskiy else
14611e51764aSArtem Bityutskiy drop_nlink(new_inode);
14621e51764aSArtem Bityutskiy } else {
14631e51764aSArtem Bityutskiy new_dir->i_size += new_sz;
14641e51764aSArtem Bityutskiy ubifs_inode(new_dir)->ui_size = new_dir->i_size;
14651e51764aSArtem Bityutskiy }
14661e51764aSArtem Bityutskiy
14671e51764aSArtem Bityutskiy /*
14681e51764aSArtem Bityutskiy * Do not ask 'ubifs_jnl_rename()' to flush write-buffer if @old_inode
14691e51764aSArtem Bityutskiy * is dirty, because this will be done later on at the end of
14701e51764aSArtem Bityutskiy * 'ubifs_rename()'.
14711e51764aSArtem Bityutskiy */
14721e51764aSArtem Bityutskiy if (IS_SYNC(old_inode)) {
14731e51764aSArtem Bityutskiy sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir);
14741e51764aSArtem Bityutskiy if (unlink && IS_SYNC(new_inode))
14751e51764aSArtem Bityutskiy sync = 1;
1476278d9a24SZhihao Cheng /*
1477278d9a24SZhihao Cheng * S_SYNC flag of whiteout inherits from the old_dir, and we
1478278d9a24SZhihao Cheng * have already checked the old dir inode. So there is no need
1479278d9a24SZhihao Cheng * to check whiteout.
1480278d9a24SZhihao Cheng */
14819e0a1fffSRichard Weinberger }
14829e0a1fffSRichard Weinberger
1483f4f61d2cSRichard Weinberger err = ubifs_jnl_rename(c, old_dir, old_inode, &old_nm, new_dir,
1484f4f61d2cSRichard Weinberger new_inode, &new_nm, whiteout, sync);
14851e51764aSArtem Bityutskiy if (err)
14861e51764aSArtem Bityutskiy goto out_cancel;
14871e51764aSArtem Bityutskiy
14889e0a1fffSRichard Weinberger unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
14891e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
14901e51764aSArtem Bityutskiy
1491278d9a24SZhihao Cheng if (whiteout) {
1492278d9a24SZhihao Cheng ubifs_release_budget(c, &wht_req);
1493278d9a24SZhihao Cheng iput(whiteout);
1494278d9a24SZhihao Cheng }
1495278d9a24SZhihao Cheng
14961e51764aSArtem Bityutskiy mutex_lock(&old_inode_ui->ui_mutex);
14971e51764aSArtem Bityutskiy release = old_inode_ui->dirty;
14981e51764aSArtem Bityutskiy mark_inode_dirty_sync(old_inode);
14991e51764aSArtem Bityutskiy mutex_unlock(&old_inode_ui->ui_mutex);
15001e51764aSArtem Bityutskiy
15011e51764aSArtem Bityutskiy if (release)
15021e51764aSArtem Bityutskiy ubifs_release_budget(c, &ino_req);
15031e51764aSArtem Bityutskiy if (IS_SYNC(old_inode))
1504278d9a24SZhihao Cheng /*
1505278d9a24SZhihao Cheng * Rename finished here. Although old inode cannot be updated
1506278d9a24SZhihao Cheng * on flash, old ctime is not a big problem, don't return err
1507278d9a24SZhihao Cheng * code to userspace.
1508278d9a24SZhihao Cheng */
1509278d9a24SZhihao Cheng old_inode->i_sb->s_op->write_inode(old_inode, NULL);
1510f4f61d2cSRichard Weinberger
1511f4f61d2cSRichard Weinberger fscrypt_free_filename(&old_nm);
1512f4f61d2cSRichard Weinberger fscrypt_free_filename(&new_nm);
1513278d9a24SZhihao Cheng return 0;
15141e51764aSArtem Bityutskiy
15151e51764aSArtem Bityutskiy out_cancel:
15161e51764aSArtem Bityutskiy if (unlink) {
1517c43be108SArtem Bityutskiy set_nlink(new_inode, saved_nlink);
15181e51764aSArtem Bityutskiy } else {
15191e51764aSArtem Bityutskiy new_dir->i_size -= new_sz;
15201e51764aSArtem Bityutskiy ubifs_inode(new_dir)->ui_size = new_dir->i_size;
15211e51764aSArtem Bityutskiy }
15221e51764aSArtem Bityutskiy old_dir->i_size += old_sz;
15231e51764aSArtem Bityutskiy ubifs_inode(old_dir)->ui_size = old_dir->i_size;
15241e51764aSArtem Bityutskiy if (is_dir) {
15251e51764aSArtem Bityutskiy if (move) {
15261e51764aSArtem Bityutskiy inc_nlink(old_dir);
15271e51764aSArtem Bityutskiy if (!unlink)
15281e51764aSArtem Bityutskiy drop_nlink(new_dir);
15291e51764aSArtem Bityutskiy } else {
15301e51764aSArtem Bityutskiy if (unlink)
15311e51764aSArtem Bityutskiy inc_nlink(old_dir);
15321e51764aSArtem Bityutskiy }
15331e51764aSArtem Bityutskiy }
1534278d9a24SZhihao Cheng unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
15359e0a1fffSRichard Weinberger if (whiteout) {
1536278d9a24SZhihao Cheng ubifs_release_budget(c, &wht_req);
15379e0a1fffSRichard Weinberger iput(whiteout);
15389e0a1fffSRichard Weinberger }
1539bb50c632SHyunchul Lee out_release:
15401e51764aSArtem Bityutskiy ubifs_release_budget(c, &ino_req);
15411e51764aSArtem Bityutskiy ubifs_release_budget(c, &req);
1542f4f61d2cSRichard Weinberger fscrypt_free_filename(&old_nm);
1543f4f61d2cSRichard Weinberger fscrypt_free_filename(&new_nm);
15441e51764aSArtem Bityutskiy return err;
15451e51764aSArtem Bityutskiy }
15461e51764aSArtem Bityutskiy
ubifs_xrename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry)15479ec64962SRichard Weinberger static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
15489ec64962SRichard Weinberger struct inode *new_dir, struct dentry *new_dentry)
15499ec64962SRichard Weinberger {
15509ec64962SRichard Weinberger struct ubifs_info *c = old_dir->i_sb->s_fs_info;
15519ec64962SRichard Weinberger struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1,
15529ec64962SRichard Weinberger .dirtied_ino = 2 };
15539ec64962SRichard Weinberger int sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir);
15549ec64962SRichard Weinberger struct inode *fst_inode = d_inode(old_dentry);
15559ec64962SRichard Weinberger struct inode *snd_inode = d_inode(new_dentry);
15569ec64962SRichard Weinberger int err;
1557f4f61d2cSRichard Weinberger struct fscrypt_name fst_nm, snd_nm;
15589ec64962SRichard Weinberger
15596eb61d58SRichard Weinberger ubifs_assert(c, fst_inode && snd_inode);
15609ec64962SRichard Weinberger
1561c04cc68dSZhihao Cheng /*
1562c04cc68dSZhihao Cheng * Budget request settings: changing two direntries, changing the two
1563c04cc68dSZhihao Cheng * parent directory inodes.
1564c04cc68dSZhihao Cheng */
1565c04cc68dSZhihao Cheng
1566c04cc68dSZhihao Cheng dbg_gen("dent '%pd' ino %lu in dir ino %lu exchange dent '%pd' ino %lu in dir ino %lu",
1567c04cc68dSZhihao Cheng old_dentry, fst_inode->i_ino, old_dir->i_ino,
1568c04cc68dSZhihao Cheng new_dentry, snd_inode->i_ino, new_dir->i_ino);
1569c04cc68dSZhihao Cheng
1570f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm);
1571f4f61d2cSRichard Weinberger if (err)
1572f4f61d2cSRichard Weinberger return err;
1573f4f61d2cSRichard Weinberger
1574f4f61d2cSRichard Weinberger err = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &snd_nm);
1575f4f61d2cSRichard Weinberger if (err) {
1576f4f61d2cSRichard Weinberger fscrypt_free_filename(&fst_nm);
1577f4f61d2cSRichard Weinberger return err;
1578f4f61d2cSRichard Weinberger }
1579f4f61d2cSRichard Weinberger
15801b2ba090SZhihao Cheng err = ubifs_budget_space(c, &req);
15811b2ba090SZhihao Cheng if (err)
15821b2ba090SZhihao Cheng goto out;
15831b2ba090SZhihao Cheng
15849ec64962SRichard Weinberger lock_4_inodes(old_dir, new_dir, NULL, NULL);
15859ec64962SRichard Weinberger
1586e54c86fdSJeff Layton simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
15879ec64962SRichard Weinberger
15889ec64962SRichard Weinberger if (old_dir != new_dir) {
15899ec64962SRichard Weinberger if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
15909ec64962SRichard Weinberger inc_nlink(new_dir);
15919ec64962SRichard Weinberger drop_nlink(old_dir);
15929ec64962SRichard Weinberger }
15939ec64962SRichard Weinberger else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
15949ec64962SRichard Weinberger drop_nlink(new_dir);
15959ec64962SRichard Weinberger inc_nlink(old_dir);
15969ec64962SRichard Weinberger }
15979ec64962SRichard Weinberger }
15989ec64962SRichard Weinberger
1599f4f61d2cSRichard Weinberger err = ubifs_jnl_xrename(c, old_dir, fst_inode, &fst_nm, new_dir,
1600f4f61d2cSRichard Weinberger snd_inode, &snd_nm, sync);
16019ec64962SRichard Weinberger
16029ec64962SRichard Weinberger unlock_4_inodes(old_dir, new_dir, NULL, NULL);
16039ec64962SRichard Weinberger ubifs_release_budget(c, &req);
16049ec64962SRichard Weinberger
16051b2ba090SZhihao Cheng out:
1606f4f61d2cSRichard Weinberger fscrypt_free_filename(&fst_nm);
1607f4f61d2cSRichard Weinberger fscrypt_free_filename(&snd_nm);
16089ec64962SRichard Weinberger return err;
16099ec64962SRichard Weinberger }
16109ec64962SRichard Weinberger
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)1611e18275aeSChristian Brauner static int ubifs_rename(struct mnt_idmap *idmap,
1612549c7297SChristian Brauner struct inode *old_dir, struct dentry *old_dentry,
16139ec64962SRichard Weinberger struct inode *new_dir, struct dentry *new_dentry,
16149ec64962SRichard Weinberger unsigned int flags)
16159ec64962SRichard Weinberger {
16160c1ad524SEric Biggers int err;
16176eb61d58SRichard Weinberger struct ubifs_info *c = old_dir->i_sb->s_fs_info;
16180c1ad524SEric Biggers
16199ec64962SRichard Weinberger if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
16209ec64962SRichard Weinberger return -EINVAL;
16219ec64962SRichard Weinberger
16226eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(old_dir));
16236eb61d58SRichard Weinberger ubifs_assert(c, inode_is_locked(new_dir));
16249ec64962SRichard Weinberger
16250c1ad524SEric Biggers err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
16260c1ad524SEric Biggers flags);
16270c1ad524SEric Biggers if (err)
16280c1ad524SEric Biggers return err;
16290c1ad524SEric Biggers
16309ec64962SRichard Weinberger if (flags & RENAME_EXCHANGE)
16319ec64962SRichard Weinberger return ubifs_xrename(old_dir, old_dentry, new_dir, new_dentry);
16329ec64962SRichard Weinberger
1633390975acSRichard Weinberger return do_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
16349ec64962SRichard Weinberger }
16359ec64962SRichard Weinberger
ubifs_getattr(struct mnt_idmap * idmap,const struct path * path,struct kstat * stat,u32 request_mask,unsigned int flags)1636b74d24f7SChristian Brauner int ubifs_getattr(struct mnt_idmap *idmap, const struct path *path,
1637549c7297SChristian Brauner struct kstat *stat, u32 request_mask, unsigned int flags)
16381e51764aSArtem Bityutskiy {
16391e51764aSArtem Bityutskiy loff_t size;
1640a528d35eSDavid Howells struct inode *inode = d_inode(path->dentry);
16411e51764aSArtem Bityutskiy struct ubifs_inode *ui = ubifs_inode(inode);
16421e51764aSArtem Bityutskiy
16431e51764aSArtem Bityutskiy mutex_lock(&ui->ui_mutex);
1644a02a6ebaSRichard Weinberger
1645a02a6ebaSRichard Weinberger if (ui->flags & UBIFS_APPEND_FL)
1646a02a6ebaSRichard Weinberger stat->attributes |= STATX_ATTR_APPEND;
1647a02a6ebaSRichard Weinberger if (ui->flags & UBIFS_COMPR_FL)
1648a02a6ebaSRichard Weinberger stat->attributes |= STATX_ATTR_COMPRESSED;
1649a02a6ebaSRichard Weinberger if (ui->flags & UBIFS_CRYPT_FL)
1650a02a6ebaSRichard Weinberger stat->attributes |= STATX_ATTR_ENCRYPTED;
1651a02a6ebaSRichard Weinberger if (ui->flags & UBIFS_IMMUTABLE_FL)
1652a02a6ebaSRichard Weinberger stat->attributes |= STATX_ATTR_IMMUTABLE;
1653a02a6ebaSRichard Weinberger
1654a02a6ebaSRichard Weinberger stat->attributes_mask |= (STATX_ATTR_APPEND |
1655a02a6ebaSRichard Weinberger STATX_ATTR_COMPRESSED |
1656a02a6ebaSRichard Weinberger STATX_ATTR_ENCRYPTED |
1657a02a6ebaSRichard Weinberger STATX_ATTR_IMMUTABLE);
1658a02a6ebaSRichard Weinberger
16590d72b928SJeff Layton generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
16601e51764aSArtem Bityutskiy stat->blksize = UBIFS_BLOCK_SIZE;
16611e51764aSArtem Bityutskiy stat->size = ui->ui_size;
16621e51764aSArtem Bityutskiy
16631e51764aSArtem Bityutskiy /*
16641e51764aSArtem Bityutskiy * Unfortunately, the 'stat()' system call was designed for block
16651e51764aSArtem Bityutskiy * device based file systems, and it is not appropriate for UBIFS,
16661e51764aSArtem Bityutskiy * because UBIFS does not have notion of "block". For example, it is
16671e51764aSArtem Bityutskiy * difficult to tell how many block a directory takes - it actually
16681e51764aSArtem Bityutskiy * takes less than 300 bytes, but we have to round it to block size,
16691e51764aSArtem Bityutskiy * which introduces large mistake. This makes utilities like 'du' to
16701e51764aSArtem Bityutskiy * report completely senseless numbers. This is the reason why UBIFS
16711e51764aSArtem Bityutskiy * goes the same way as JFFS2 - it reports zero blocks for everything
16721e51764aSArtem Bityutskiy * but regular files, which makes more sense than reporting completely
16731e51764aSArtem Bityutskiy * wrong sizes.
16741e51764aSArtem Bityutskiy */
16751e51764aSArtem Bityutskiy if (S_ISREG(inode->i_mode)) {
16761e51764aSArtem Bityutskiy size = ui->xattr_size;
16771e51764aSArtem Bityutskiy size += stat->size;
16781e51764aSArtem Bityutskiy size = ALIGN(size, UBIFS_BLOCK_SIZE);
16791e51764aSArtem Bityutskiy /*
16801e51764aSArtem Bityutskiy * Note, user-space expects 512-byte blocks count irrespectively
16811e51764aSArtem Bityutskiy * of what was reported in @stat->size.
16821e51764aSArtem Bityutskiy */
16831e51764aSArtem Bityutskiy stat->blocks = size >> 9;
16841e51764aSArtem Bityutskiy } else
16851e51764aSArtem Bityutskiy stat->blocks = 0;
16861e51764aSArtem Bityutskiy mutex_unlock(&ui->ui_mutex);
16871e51764aSArtem Bityutskiy return 0;
16881e51764aSArtem Bityutskiy }
16891e51764aSArtem Bityutskiy
1690e8b81566SArtem Bityutskiy const struct inode_operations ubifs_dir_inode_operations = {
16911e51764aSArtem Bityutskiy .lookup = ubifs_lookup,
16921e51764aSArtem Bityutskiy .create = ubifs_create,
16931e51764aSArtem Bityutskiy .link = ubifs_link,
16941e51764aSArtem Bityutskiy .symlink = ubifs_symlink,
16951e51764aSArtem Bityutskiy .unlink = ubifs_unlink,
16961e51764aSArtem Bityutskiy .mkdir = ubifs_mkdir,
16971e51764aSArtem Bityutskiy .rmdir = ubifs_rmdir,
16981e51764aSArtem Bityutskiy .mknod = ubifs_mknod,
1699390975acSRichard Weinberger .rename = ubifs_rename,
17001e51764aSArtem Bityutskiy .setattr = ubifs_setattr,
17011e51764aSArtem Bityutskiy .getattr = ubifs_getattr,
17021e51764aSArtem Bityutskiy .listxattr = ubifs_listxattr,
17038c1c5f26SDongsheng Yang .update_time = ubifs_update_time,
1704474b9370SRichard Weinberger .tmpfile = ubifs_tmpfile,
17058871d84cSMiklos Szeredi .fileattr_get = ubifs_fileattr_get,
17068871d84cSMiklos Szeredi .fileattr_set = ubifs_fileattr_set,
17071e51764aSArtem Bityutskiy };
17081e51764aSArtem Bityutskiy
1709e8b81566SArtem Bityutskiy const struct file_operations ubifs_dir_operations = {
171001122e06SAl Viro .llseek = generic_file_llseek,
17111e51764aSArtem Bityutskiy .release = ubifs_dir_release,
17121e51764aSArtem Bityutskiy .read = generic_read_dir,
1713c51da20cSAl Viro .iterate_shared = ubifs_readdir,
17141e51764aSArtem Bityutskiy .fsync = ubifs_fsync,
17151e51764aSArtem Bityutskiy .unlocked_ioctl = ubifs_ioctl,
17161e51764aSArtem Bityutskiy #ifdef CONFIG_COMPAT
17171e51764aSArtem Bityutskiy .compat_ioctl = ubifs_compat_ioctl,
17181e51764aSArtem Bityutskiy #endif
17191e51764aSArtem Bityutskiy };
1720