VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    1) // SPDX-License-Identifier: GPL-2.0-or-later
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    2) /*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    3)  * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    4)  */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    5) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    6) #include <linux/iversion.h>
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    7) #include <linux/namei.h>
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    8) #include <linux/slab.h>
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900    9) #include <linux/buffer_head.h>
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   10) #include <linux/nls.h>
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   11) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   12) #include "exfat_raw.h"
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   13) #include "exfat_fs.h"
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   14) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   15) static inline unsigned long exfat_d_version(struct dentry *dentry)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   16) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   17) 	return (unsigned long) dentry->d_fsdata;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   18) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   19) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   20) static inline void exfat_d_version_set(struct dentry *dentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   21) 		unsigned long version)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   22) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   23) 	dentry->d_fsdata = (void *) version;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   24) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   25) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   26) /*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   27)  * If new entry was created in the parent, it could create the 8.3 alias (the
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   28)  * shortname of logname).  So, the parent may have the negative-dentry which
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   29)  * matches the created 8.3 alias.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   30)  *
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   31)  * If it happened, the negative dentry isn't actually negative anymore.  So,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   32)  * drop it.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   33)  */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   34) static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   35) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   36) 	int ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   37) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   38) 	if (flags & LOOKUP_RCU)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   39) 		return -ECHILD;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   40) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   41) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   42) 	 * This is not negative dentry. Always valid.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   43) 	 *
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   44) 	 * Note, rename() to existing directory entry will have ->d_inode, and
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   45) 	 * will use existing name which isn't specified name by user.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   46) 	 *
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   47) 	 * We may be able to drop this positive dentry here. But dropping
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   48) 	 * positive dentry isn't good idea. So it's unsupported like
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   49) 	 * rename("filename", "FILENAME") for now.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   50) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   51) 	if (d_really_is_positive(dentry))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   52) 		return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   53) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   54) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   55) 	 * Drop the negative dentry, in order to make sure to use the case
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   56) 	 * sensitive name which is specified by user if this is for creation.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   57) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   58) 	if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   59) 		return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   60) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   61) 	spin_lock(&dentry->d_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   62) 	ret = inode_eq_iversion(d_inode(dentry->d_parent),
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   63) 			exfat_d_version(dentry));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   64) 	spin_unlock(&dentry->d_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   65) 	return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   66) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   67) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   68) /* returns the length of a struct qstr, ignoring trailing dots */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   69) static unsigned int exfat_striptail_len(unsigned int len, const char *name)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   70) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   71) 	while (len && name[len - 1] == '.')
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   72) 		len--;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   73) 	return len;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   74) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   75) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   76) /*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   77)  * Compute the hash for the exfat name corresponding to the dentry.  If the name
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   78)  * is invalid, we leave the hash code unchanged so that the existing dentry can
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   79)  * be used. The exfat fs routines will return ENOENT or EINVAL as appropriate.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   80)  */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   81) static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   82) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   83) 	struct super_block *sb = dentry->d_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   84) 	struct nls_table *t = EXFAT_SB(sb)->nls_io;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   85) 	const unsigned char *name = qstr->name;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   86) 	unsigned int len = exfat_striptail_len(qstr->len, qstr->name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   87) 	unsigned long hash = init_name_hash(dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   88) 	int i, charlen;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   89) 	wchar_t c;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   90) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   91) 	for (i = 0; i < len; i += charlen) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   92) 		charlen = t->char2uni(&name[i], len - i, &c);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   93) 		if (charlen < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   94) 			return charlen;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   95) 		hash = partial_name_hash(exfat_toupper(sb, c), hash);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   96) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   97) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   98) 	qstr->hash = end_name_hash(hash);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900   99) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  100) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  101) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  102) static int exfat_d_cmp(const struct dentry *dentry, unsigned int len,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  103) 		const char *str, const struct qstr *name)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  104) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  105) 	struct super_block *sb = dentry->d_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  106) 	struct nls_table *t = EXFAT_SB(sb)->nls_io;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  107) 	unsigned int alen = exfat_striptail_len(name->len, name->name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  108) 	unsigned int blen = exfat_striptail_len(len, str);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  109) 	wchar_t c1, c2;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  110) 	int charlen, i;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  111) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  112) 	if (alen != blen)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  113) 		return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  114) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  115) 	for (i = 0; i < len; i += charlen) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  116) 		charlen = t->char2uni(&name->name[i], alen - i, &c1);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  117) 		if (charlen < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  118) 			return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  119) 		if (charlen != t->char2uni(&str[i], blen - i, &c2))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  120) 			return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  121) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  122) 		if (exfat_toupper(sb, c1) != exfat_toupper(sb, c2))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  123) 			return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  124) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  125) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  126) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  127) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  128) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  129) const struct dentry_operations exfat_dentry_ops = {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  130) 	.d_revalidate	= exfat_d_revalidate,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  131) 	.d_hash		= exfat_d_hash,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  132) 	.d_compare	= exfat_d_cmp,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  133) };
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  134) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  135) static int exfat_utf8_d_hash(const struct dentry *dentry, struct qstr *qstr)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  136) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  137) 	struct super_block *sb = dentry->d_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  138) 	const unsigned char *name = qstr->name;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  139) 	unsigned int len = exfat_striptail_len(qstr->len, qstr->name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  140) 	unsigned long hash = init_name_hash(dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  141) 	int i, charlen;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  142) 	unicode_t u;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  143) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  144) 	for (i = 0; i < len; i += charlen) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  145) 		charlen = utf8_to_utf32(&name[i], len - i, &u);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  146) 		if (charlen < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  147) 			return charlen;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  148) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  149) 		/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  150) 		 * exfat_toupper() works only for code points up to the U+FFFF.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  151) 		 */
dddf7da3985ee (Pali Rohár        2020-03-17 23:25:52 +0100  152) 		hash = partial_name_hash(u <= 0xFFFF ? exfat_toupper(sb, u) : u,
dddf7da3985ee (Pali Rohár        2020-03-17 23:25:52 +0100  153) 					 hash);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  154) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  155) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  156) 	qstr->hash = end_name_hash(hash);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  157) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  158) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  159) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  160) static int exfat_utf8_d_cmp(const struct dentry *dentry, unsigned int len,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  161) 		const char *str, const struct qstr *name)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  162) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  163) 	struct super_block *sb = dentry->d_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  164) 	unsigned int alen = exfat_striptail_len(name->len, name->name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  165) 	unsigned int blen = exfat_striptail_len(len, str);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  166) 	unicode_t u_a, u_b;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  167) 	int charlen, i;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  168) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  169) 	if (alen != blen)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  170) 		return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  171) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  172) 	for (i = 0; i < alen; i += charlen) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  173) 		charlen = utf8_to_utf32(&name->name[i], alen - i, &u_a);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  174) 		if (charlen < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  175) 			return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  176) 		if (charlen != utf8_to_utf32(&str[i], blen - i, &u_b))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  177) 			return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  178) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  179) 		if (u_a <= 0xFFFF && u_b <= 0xFFFF) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  180) 			if (exfat_toupper(sb, u_a) != exfat_toupper(sb, u_b))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  181) 				return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  182) 		} else {
197298a64983e (Pali Rohár        2020-03-17 22:34:33 +0100  183) 			if (u_a != u_b)
197298a64983e (Pali Rohár        2020-03-17 22:34:33 +0100  184) 				return 1;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  185) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  186) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  187) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  188) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  189) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  190) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  191) const struct dentry_operations exfat_utf8_dentry_ops = {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  192) 	.d_revalidate	= exfat_d_revalidate,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  193) 	.d_hash		= exfat_utf8_d_hash,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  194) 	.d_compare	= exfat_utf8_d_cmp,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  195) };
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  196) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  197) /* used only in search empty_slot() */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  198) #define CNT_UNUSED_NOHIT        (-1)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  199) #define CNT_UNUSED_HIT          (-2)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  200) /* search EMPTY CONTINUOUS "num_entries" entries */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  201) static int exfat_search_empty_slot(struct super_block *sb,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  202) 		struct exfat_hint_femp *hint_femp, struct exfat_chain *p_dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  203) 		int num_entries)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  204) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  205) 	int i, dentry, num_empty = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  206) 	int dentries_per_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  207) 	unsigned int type;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  208) 	struct exfat_chain clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  209) 	struct exfat_dentry *ep;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  210) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  211) 	struct buffer_head *bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  212) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  213) 	dentries_per_clu = sbi->dentries_per_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  214) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  215) 	if (hint_femp->eidx != EXFAT_HINT_NONE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  216) 		dentry = hint_femp->eidx;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  217) 		if (num_entries <= hint_femp->count) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  218) 			hint_femp->eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  219) 			return dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  220) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  221) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  222) 		exfat_chain_dup(&clu, &hint_femp->cur);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  223) 	} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  224) 		exfat_chain_dup(&clu, p_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  225) 		dentry = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  226) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  227) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  228) 	while (clu.dir != EXFAT_EOF_CLUSTER) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  229) 		i = dentry & (dentries_per_clu - 1);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  230) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  231) 		for (; i < dentries_per_clu; i++, dentry++) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  232) 			ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  233) 			if (!ep)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  234) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  235) 			type = exfat_get_entry_type(ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  236) 			brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  237) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  238) 			if (type == TYPE_UNUSED || type == TYPE_DELETED) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  239) 				num_empty++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  240) 				if (hint_femp->eidx == EXFAT_HINT_NONE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  241) 					hint_femp->eidx = dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  242) 					hint_femp->count = CNT_UNUSED_NOHIT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  243) 					exfat_chain_set(&hint_femp->cur,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  244) 						clu.dir, clu.size, clu.flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  245) 				}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  246) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  247) 				if (type == TYPE_UNUSED &&
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  248) 				    hint_femp->count != CNT_UNUSED_HIT)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  249) 					hint_femp->count = CNT_UNUSED_HIT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  250) 			} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  251) 				if (hint_femp->eidx != EXFAT_HINT_NONE &&
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  252) 				    hint_femp->count == CNT_UNUSED_HIT) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  253) 					/* unused empty group means
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  254) 					 * an empty group which includes
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  255) 					 * unused dentry
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  256) 					 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  257) 					exfat_fs_error(sb,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  258) 						"found bogus dentry(%d) beyond unused empty group(%d) (start_clu : %u, cur_clu : %u)",
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  259) 						dentry, hint_femp->eidx,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  260) 						p_dir->dir, clu.dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  261) 					return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  262) 				}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  263) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  264) 				num_empty = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  265) 				hint_femp->eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  266) 			}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  267) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  268) 			if (num_empty >= num_entries) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  269) 				/* found and invalidate hint_femp */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  270) 				hint_femp->eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  271) 				return (dentry - (num_entries - 1));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  272) 			}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  273) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  274) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  275) 		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  276) 			if (--clu.size > 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  277) 				clu.dir++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  278) 			else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  279) 				clu.dir = EXFAT_EOF_CLUSTER;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  280) 		} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  281) 			if (exfat_get_next_cluster(sb, &clu.dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  282) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  283) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  284) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  285) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  286) 	return -ENOSPC;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  287) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  288) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  289) static int exfat_check_max_dentries(struct inode *inode)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  290) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  291) 	if (EXFAT_B_TO_DEN(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  292) 		/*
9e456aeaacb6b (Namjae Jeon       2020-08-14 11:03:46 +0900  293) 		 * exFAT spec allows a dir to grow up to 8388608(256MB)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  294) 		 * dentries
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  295) 		 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  296) 		return -ENOSPC;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  297) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  298) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  299) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  300) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  301) /* find empty directory entry.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  302)  * if there isn't any empty slot, expand cluster chain.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  303)  */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  304) static int exfat_find_empty_entry(struct inode *inode,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  305) 		struct exfat_chain *p_dir, int num_entries)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  306) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  307) 	int dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  308) 	unsigned int ret, last_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  309) 	sector_t sector;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  310) 	loff_t size = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  311) 	struct exfat_chain clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  312) 	struct exfat_dentry *ep = NULL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  313) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  314) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  315) 	struct exfat_inode_info *ei = EXFAT_I(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  316) 	struct exfat_hint_femp hint_femp;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  317) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  318) 	hint_femp.eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  319) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  320) 	if (ei->hint_femp.eidx != EXFAT_HINT_NONE) {
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900  321) 		hint_femp = ei->hint_femp;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  322) 		ei->hint_femp.eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  323) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  324) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  325) 	while ((dentry = exfat_search_empty_slot(sb, &hint_femp, p_dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  326) 					num_entries)) < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  327) 		if (dentry == -EIO)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  328) 			break;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  329) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  330) 		if (exfat_check_max_dentries(inode))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  331) 			return -ENOSPC;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  332) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  333) 		/* we trust p_dir->size regardless of FAT type */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  334) 		if (exfat_find_last_cluster(sb, p_dir, &last_clu))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  335) 			return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  336) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  337) 		/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  338) 		 * Allocate new cluster to this directory
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  339) 		 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  340) 		exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  341) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  342) 		/* allocate a cluster */
23befe490ba88 (Hyeongseok Kim    2021-03-15 13:12:55 +0900  343) 		ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  344) 		if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  345) 			return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  346) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  347) 		if (exfat_zeroed_cluster(inode, clu.dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  348) 			return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  349) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  350) 		/* append to the FAT chain */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  351) 		if (clu.flags != p_dir->flags) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  352) 			/* no-fat-chain bit is disabled,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  353) 			 * so fat-chain should be synced with alloc-bitmap
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  354) 			 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  355) 			exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  356) 			p_dir->flags = ALLOC_FAT_CHAIN;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  357) 			hint_femp.cur.flags = ALLOC_FAT_CHAIN;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  358) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  359) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  360) 		if (clu.flags == ALLOC_FAT_CHAIN)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  361) 			if (exfat_ent_set(sb, last_clu, clu.dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  362) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  363) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  364) 		if (hint_femp.eidx == EXFAT_HINT_NONE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  365) 			/* the special case that new dentry
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  366) 			 * should be allocated from the start of new cluster
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  367) 			 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  368) 			hint_femp.eidx = EXFAT_B_TO_DEN_IDX(p_dir->size, sbi);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  369) 			hint_femp.count = sbi->dentries_per_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  370) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  371) 			exfat_chain_set(&hint_femp.cur, clu.dir, 0, clu.flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  372) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  373) 		hint_femp.cur.size++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  374) 		p_dir->size++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  375) 		size = EXFAT_CLU_TO_B(p_dir->size, sbi);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  376) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  377) 		/* update the directory entry */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  378) 		if (p_dir->dir != sbi->root_dir) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  379) 			struct buffer_head *bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  380) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  381) 			ep = exfat_get_dentry(sb,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  382) 				&(ei->dir), ei->entry + 1, &bh, &sector);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  383) 			if (!ep)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  384) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  385) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  386) 			ep->dentry.stream.valid_size = cpu_to_le64(size);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  387) 			ep->dentry.stream.size = ep->dentry.stream.valid_size;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  388) 			ep->dentry.stream.flags = p_dir->flags;
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900  389) 			exfat_update_bh(bh, IS_DIRSYNC(inode));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  390) 			brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  391) 			if (exfat_update_dir_chksum(inode, &(ei->dir),
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  392) 			    ei->entry))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  393) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  394) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  395) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  396) 		/* directory inode should be updated in here */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  397) 		i_size_write(inode, size);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  398) 		EXFAT_I(inode)->i_size_ondisk += sbi->cluster_size;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  399) 		EXFAT_I(inode)->i_size_aligned += sbi->cluster_size;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  400) 		EXFAT_I(inode)->flags = p_dir->flags;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  401) 		inode->i_blocks += 1 << sbi->sect_per_clus_bits;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  402) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  403) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  404) 	return dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  405) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  406) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  407) /*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  408)  * Name Resolution Functions :
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  409)  * Zero if it was successful; otherwise nonzero.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  410)  */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  411) static int __exfat_resolve_path(struct inode *inode, const unsigned char *path,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  412) 		struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  413) 		int lookup)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  414) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  415) 	int namelen;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  416) 	int lossy = NLS_NAME_NO_LOSSY;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  417) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  418) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  419) 	struct exfat_inode_info *ei = EXFAT_I(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  420) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  421) 	/* strip all trailing periods */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  422) 	namelen = exfat_striptail_len(strlen(path), path);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  423) 	if (!namelen)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  424) 		return -ENOENT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  425) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  426) 	if (strlen(path) > (MAX_NAME_LENGTH * MAX_CHARSET_SIZE))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  427) 		return -ENAMETOOLONG;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  428) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  429) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  430) 	 * strip all leading spaces :
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  431) 	 * "MS windows 7" supports leading spaces.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  432) 	 * So we should skip this preprocessing for compatibility.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  433) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  434) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  435) 	/* file name conversion :
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  436) 	 * If lookup case, we allow bad-name for compatibility.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  437) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  438) 	namelen = exfat_nls_to_utf16(sb, path, namelen, p_uniname,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  439) 			&lossy);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  440) 	if (namelen < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  441) 		return namelen; /* return error value */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  442) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  443) 	if ((lossy && !lookup) || !namelen)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  444) 		return -EINVAL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  445) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  446) 	exfat_chain_set(p_dir, ei->start_clu,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  447) 		EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  448) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  449) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  450) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  451) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  452) static inline int exfat_resolve_path(struct inode *inode,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  453) 		const unsigned char *path, struct exfat_chain *dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  454) 		struct exfat_uni_name *uni)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  455) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  456) 	return __exfat_resolve_path(inode, path, dir, uni, 0);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  457) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  458) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  459) static inline int exfat_resolve_path_for_lookup(struct inode *inode,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  460) 		const unsigned char *path, struct exfat_chain *dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  461) 		struct exfat_uni_name *uni)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  462) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  463) 	return __exfat_resolve_path(inode, path, dir, uni, 1);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  464) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  465) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  466) static inline loff_t exfat_make_i_pos(struct exfat_dir_entry *info)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  467) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  468) 	return ((loff_t) info->dir.dir << 32) | (info->entry & 0xffffffff);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  469) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  470) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  471) static int exfat_add_entry(struct inode *inode, const char *path,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  472) 		struct exfat_chain *p_dir, unsigned int type,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  473) 		struct exfat_dir_entry *info)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  474) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  475) 	int ret, dentry, num_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  476) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  477) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  478) 	struct exfat_uni_name uniname;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  479) 	struct exfat_chain clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  480) 	int clu_size = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  481) 	unsigned int start_clu = EXFAT_FREE_CLUSTER;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  482) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  483) 	ret = exfat_resolve_path(inode, path, p_dir, &uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  484) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  485) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  486) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  487) 	num_entries = exfat_calc_num_entries(&uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  488) 	if (num_entries < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  489) 		ret = num_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  490) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  491) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  492) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  493) 	/* exfat_find_empty_entry must be called before alloc_cluster() */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  494) 	dentry = exfat_find_empty_entry(inode, p_dir, num_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  495) 	if (dentry < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  496) 		ret = dentry; /* -EIO or -ENOSPC */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  497) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  498) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  499) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  500) 	if (type == TYPE_DIR) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  501) 		ret = exfat_alloc_new_dir(inode, &clu);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  502) 		if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  503) 			goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  504) 		start_clu = clu.dir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  505) 		clu_size = sbi->cluster_size;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  506) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  507) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  508) 	/* update the directory entry */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  509) 	/* fill the dos name directory entry information of the created file.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  510) 	 * the first cluster is not determined yet. (0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  511) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  512) 	ret = exfat_init_dir_entry(inode, p_dir, dentry, type,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  513) 		start_clu, clu_size);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  514) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  515) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  516) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  517) 	ret = exfat_init_ext_entry(inode, p_dir, dentry, num_entries, &uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  518) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  519) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  520) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900  521) 	info->dir = *p_dir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  522) 	info->entry = dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  523) 	info->flags = ALLOC_NO_FAT_CHAIN;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  524) 	info->type = type;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  525) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  526) 	if (type == TYPE_FILE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  527) 		info->attr = ATTR_ARCHIVE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  528) 		info->start_clu = EXFAT_EOF_CLUSTER;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  529) 		info->size = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  530) 		info->num_subdirs = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  531) 	} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  532) 		info->attr = ATTR_SUBDIR;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  533) 		info->start_clu = start_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  534) 		info->size = clu_size;
6c958a0955551 (Tetsuhiro Kohada  2020-09-11 13:44:39 +0900  535) 		info->num_subdirs = EXFAT_MIN_SUBDIR;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  536) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  537) 	memset(&info->crtime, 0, sizeof(info->crtime));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  538) 	memset(&info->mtime, 0, sizeof(info->mtime));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  539) 	memset(&info->atime, 0, sizeof(info->atime));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  540) out:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  541) 	return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  542) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  543) 
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100  544) static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100  545) 			struct dentry *dentry, umode_t mode, bool excl)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  546) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  547) 	struct super_block *sb = dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  548) 	struct inode *inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  549) 	struct exfat_chain cdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  550) 	struct exfat_dir_entry info;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  551) 	loff_t i_pos;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  552) 	int err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  553) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  554) 	mutex_lock(&EXFAT_SB(sb)->s_lock);
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  555) 	exfat_set_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  556) 	err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_FILE,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  557) 		&info);
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  558) 	exfat_clear_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  559) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  560) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  561) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  562) 	inode_inc_iversion(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  563) 	dir->i_ctime = dir->i_mtime = current_time(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  564) 	if (IS_DIRSYNC(dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  565) 		exfat_sync_inode(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  566) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  567) 		mark_inode_dirty(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  568) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  569) 	i_pos = exfat_make_i_pos(&info);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  570) 	inode = exfat_build_inode(sb, &info, i_pos);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  571) 	err = PTR_ERR_OR_ZERO(inode);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  572) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  573) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  574) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  575) 	inode_inc_iversion(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  576) 	inode->i_mtime = inode->i_atime = inode->i_ctime =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  577) 		EXFAT_I(inode)->i_crtime = current_time(inode);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  578) 	exfat_truncate_atime(&inode->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  579) 	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  580) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  581) 	d_instantiate(dentry, inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  582) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  583) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  584) 	return err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  585) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  586) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  587) /* lookup a file */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  588) static int exfat_find(struct inode *dir, struct qstr *qname,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  589) 		struct exfat_dir_entry *info)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  590) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  591) 	int ret, dentry, num_entries, count;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  592) 	struct exfat_chain cdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  593) 	struct exfat_uni_name uni_name;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  594) 	struct super_block *sb = dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  595) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  596) 	struct exfat_inode_info *ei = EXFAT_I(dir);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  597) 	struct exfat_dentry *ep, *ep2;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  598) 	struct exfat_entry_set_cache *es;
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  599) 	/* for optimized dir & entry to prevent long traverse of cluster chain */
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  600) 	struct exfat_hint hint_opt;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  601) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  602) 	if (qname->len == 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  603) 		return -ENOENT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  604) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  605) 	/* check the validity of directory name in the given pathname */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  606) 	ret = exfat_resolve_path_for_lookup(dir, qname->name, &cdir, &uni_name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  607) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  608) 		return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  609) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  610) 	num_entries = exfat_calc_num_entries(&uni_name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  611) 	if (num_entries < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  612) 		return num_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  613) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  614) 	/* check the validation of hint_stat and initialize it if required */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  615) 	if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  616) 		ei->hint_stat.clu = cdir.dir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  617) 		ei->hint_stat.eidx = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  618) 		ei->version = (inode_peek_iversion_raw(dir) & 0xffffffff);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  619) 		ei->hint_femp.eidx = EXFAT_HINT_NONE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  620) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  621) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  622) 	/* search the file name for directories */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  623) 	dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  624) 			num_entries, TYPE_ALL, &hint_opt);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  625) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  626) 	if (dentry < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  627) 		return dentry; /* -error value */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  628) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900  629) 	info->dir = cdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  630) 	info->entry = dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  631) 	info->num_subdirs = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  632) 
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  633) 	/* adjust cdir to the optimized value */
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  634) 	cdir.dir = hint_opt.clu;
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  635) 	if (cdir.flags & ALLOC_NO_FAT_CHAIN)
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  636) 		cdir.size -= dentry / sbi->dentries_per_clu;
c6e2f52e3051e (Hyeongseok Kim    2021-03-22 12:53:36 +0900  637) 	dentry = hint_opt.eidx;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  638) 	es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  639) 	if (!es)
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  640) 		return -EIO;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  641) 	ep = exfat_get_dentry_cached(es, 0);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  642) 	ep2 = exfat_get_dentry_cached(es, 1);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  643) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  644) 	info->type = exfat_get_entry_type(ep);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  645) 	info->attr = le16_to_cpu(ep->dentry.file.attr);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  646) 	info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  647) 	if ((info->type == TYPE_FILE) && (info->size == 0)) {
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  648) 		info->flags = ALLOC_NO_FAT_CHAIN;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  649) 		info->start_clu = EXFAT_EOF_CLUSTER;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  650) 	} else {
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  651) 		info->flags = ep2->dentry.stream.flags;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  652) 		info->start_clu =
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  653) 			le32_to_cpu(ep2->dentry.stream.start_clu);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  654) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  655) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  656) 	exfat_get_entry_time(sbi, &info->crtime,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  657) 			     ep->dentry.file.create_tz,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  658) 			     ep->dentry.file.create_time,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  659) 			     ep->dentry.file.create_date,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  660) 			     ep->dentry.file.create_time_cs);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  661) 	exfat_get_entry_time(sbi, &info->mtime,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  662) 			     ep->dentry.file.modify_tz,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  663) 			     ep->dentry.file.modify_time,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  664) 			     ep->dentry.file.modify_date,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  665) 			     ep->dentry.file.modify_time_cs);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  666) 	exfat_get_entry_time(sbi, &info->atime,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  667) 			     ep->dentry.file.access_tz,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  668) 			     ep->dentry.file.access_time,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  669) 			     ep->dentry.file.access_date,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  670) 			     0);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  671) 	exfat_free_dentry_set(es, false);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  672) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  673) 	if (ei->start_clu == EXFAT_FREE_CLUSTER) {
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  674) 		exfat_fs_error(sb,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  675) 			       "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)",
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  676) 			       i_size_read(dir), ei->dir.dir, ei->entry);
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  677) 		return -EIO;
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  678) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  679) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  680) 	if (info->type == TYPE_DIR) {
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  681) 		exfat_chain_set(&cdir, info->start_clu,
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  682) 				EXFAT_B_TO_CLU(info->size, sbi), info->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  683) 		count = exfat_count_dir_entries(sb, &cdir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  684) 		if (count < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  685) 			return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  686) 
188df41f212c9 (Tetsuhiro Kohada  2020-09-02 16:53:06 +0900  687) 		info->num_subdirs = count + EXFAT_MIN_SUBDIR;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  688) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  689) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  690) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  691) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  692) static int exfat_d_anon_disconn(struct dentry *dentry)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  693) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  694) 	return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  695) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  696) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  697) static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  698) 		unsigned int flags)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  699) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  700) 	struct super_block *sb = dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  701) 	struct inode *inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  702) 	struct dentry *alias;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  703) 	struct exfat_dir_entry info;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  704) 	int err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  705) 	loff_t i_pos;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  706) 	mode_t i_mode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  707) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  708) 	mutex_lock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  709) 	err = exfat_find(dir, &dentry->d_name, &info);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  710) 	if (err) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  711) 		if (err == -ENOENT) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  712) 			inode = NULL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  713) 			goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  714) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  715) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  716) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  717) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  718) 	i_pos = exfat_make_i_pos(&info);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  719) 	inode = exfat_build_inode(sb, &info, i_pos);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  720) 	err = PTR_ERR_OR_ZERO(inode);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  721) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  722) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  723) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  724) 	i_mode = inode->i_mode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  725) 	alias = d_find_alias(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  726) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  727) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  728) 	 * Checking "alias->d_parent == dentry->d_parent" to make sure
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  729) 	 * FS is not corrupted (especially double linked dir).
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  730) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  731) 	if (alias && alias->d_parent == dentry->d_parent &&
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  732) 			!exfat_d_anon_disconn(alias)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  733) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  734) 		/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  735) 		 * Unhashed alias is able to exist because of revalidate()
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  736) 		 * called by lookup_fast. You can easily make this status
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  737) 		 * by calling create and lookup concurrently
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  738) 		 * In such case, we reuse an alias instead of new dentry
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  739) 		 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  740) 		if (d_unhashed(alias)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  741) 			WARN_ON(alias->d_name.hash_len !=
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  742) 				dentry->d_name.hash_len);
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  743) 			exfat_info(sb, "rehashed a dentry(%p) in read lookup",
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  744) 				   alias);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  745) 			d_drop(dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  746) 			d_rehash(alias);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  747) 		} else if (!S_ISDIR(i_mode)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  748) 			/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  749) 			 * This inode has non anonymous-DCACHE_DISCONNECTED
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  750) 			 * dentry. This means, the user did ->lookup() by an
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  751) 			 * another name (longname vs 8.3 alias of it) in past.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  752) 			 *
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  753) 			 * Switch to new one for reason of locality if possible.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  754) 			 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  755) 			d_move(alias, dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  756) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  757) 		iput(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  758) 		mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  759) 		return alias;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  760) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  761) 	dput(alias);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  762) out:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  763) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  764) 	if (!inode)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  765) 		exfat_d_version_set(dentry, inode_query_iversion(dir));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  766) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  767) 	return d_splice_alias(inode, dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  768) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  769) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  770) 	return ERR_PTR(err);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  771) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  772) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  773) /* remove an entry, BUT don't truncate */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  774) static int exfat_unlink(struct inode *dir, struct dentry *dentry)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  775) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  776) 	struct exfat_chain cdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  777) 	struct exfat_dentry *ep;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  778) 	struct super_block *sb = dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  779) 	struct inode *inode = dentry->d_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  780) 	struct exfat_inode_info *ei = EXFAT_I(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  781) 	struct buffer_head *bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  782) 	sector_t sector;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  783) 	int num_entries, entry, err = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  784) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  785) 	mutex_lock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  786) 	exfat_chain_dup(&cdir, &ei->dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  787) 	entry = ei->entry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  788) 	if (ei->dir.dir == DIR_DELETED) {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  789) 		exfat_err(sb, "abnormal access to deleted dentry");
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  790) 		err = -ENOENT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  791) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  792) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  793) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  794) 	ep = exfat_get_dentry(sb, &cdir, entry, &bh, &sector);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  795) 	if (!ep) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  796) 		err = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  797) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  798) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  799) 	num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  800) 	if (num_entries < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  801) 		err = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  802) 		brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  803) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  804) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  805) 	num_entries++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  806) 	brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  807) 
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  808) 	exfat_set_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  809) 	/* update the directory entry */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  810) 	if (exfat_remove_entries(dir, &cdir, entry, 0, num_entries)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  811) 		err = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  812) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  813) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  814) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  815) 	/* This doesn't modify ei */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  816) 	ei->dir.dir = DIR_DELETED;
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  817) 	exfat_clear_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  818) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  819) 	inode_inc_iversion(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  820) 	dir->i_mtime = dir->i_atime = current_time(dir);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  821) 	exfat_truncate_atime(&dir->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  822) 	if (IS_DIRSYNC(dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  823) 		exfat_sync_inode(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  824) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  825) 		mark_inode_dirty(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  826) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  827) 	clear_nlink(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  828) 	inode->i_mtime = inode->i_atime = current_time(inode);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  829) 	exfat_truncate_atime(&inode->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  830) 	exfat_unhash_inode(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  831) 	exfat_d_version_set(dentry, inode_query_iversion(dir));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  832) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  833) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  834) 	return err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  835) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  836) 
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100  837) static int exfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100  838) 		       struct dentry *dentry, umode_t mode)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  839) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  840) 	struct super_block *sb = dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  841) 	struct inode *inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  842) 	struct exfat_dir_entry info;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  843) 	struct exfat_chain cdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  844) 	loff_t i_pos;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  845) 	int err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  846) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  847) 	mutex_lock(&EXFAT_SB(sb)->s_lock);
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  848) 	exfat_set_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  849) 	err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_DIR,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  850) 		&info);
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  851) 	exfat_clear_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  852) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  853) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  854) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  855) 	inode_inc_iversion(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  856) 	dir->i_ctime = dir->i_mtime = current_time(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  857) 	if (IS_DIRSYNC(dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  858) 		exfat_sync_inode(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  859) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  860) 		mark_inode_dirty(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  861) 	inc_nlink(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  862) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  863) 	i_pos = exfat_make_i_pos(&info);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  864) 	inode = exfat_build_inode(sb, &info, i_pos);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  865) 	err = PTR_ERR_OR_ZERO(inode);
d6c9efd92443b (Tetsuhiro Kohada  2020-08-26 10:18:29 +0900  866) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  867) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  868) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  869) 	inode_inc_iversion(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  870) 	inode->i_mtime = inode->i_atime = inode->i_ctime =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  871) 		EXFAT_I(inode)->i_crtime = current_time(inode);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  872) 	exfat_truncate_atime(&inode->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  873) 	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  874) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  875) 	d_instantiate(dentry, inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  876) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  877) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  878) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  879) 	return err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  880) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  881) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  882) static int exfat_check_dir_empty(struct super_block *sb,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  883) 		struct exfat_chain *p_dir)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  884) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  885) 	int i, dentries_per_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  886) 	unsigned int type;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  887) 	struct exfat_chain clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  888) 	struct exfat_dentry *ep;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  889) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  890) 	struct buffer_head *bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  891) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  892) 	dentries_per_clu = sbi->dentries_per_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  893) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  894) 	exfat_chain_dup(&clu, p_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  895) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  896) 	while (clu.dir != EXFAT_EOF_CLUSTER) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  897) 		for (i = 0; i < dentries_per_clu; i++) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  898) 			ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  899) 			if (!ep)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  900) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  901) 			type = exfat_get_entry_type(ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  902) 			brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  903) 			if (type == TYPE_UNUSED)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  904) 				return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  905) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  906) 			if (type != TYPE_FILE && type != TYPE_DIR)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  907) 				continue;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  908) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  909) 			return -ENOTEMPTY;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  910) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  911) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  912) 		if (clu.flags == ALLOC_NO_FAT_CHAIN) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  913) 			if (--clu.size > 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  914) 				clu.dir++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  915) 			else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  916) 				clu.dir = EXFAT_EOF_CLUSTER;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  917) 		} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  918) 			if (exfat_get_next_cluster(sb, &(clu.dir)))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  919) 				return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  920) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  921) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  922) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  923) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  924) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  925) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  926) static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  927) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  928) 	struct inode *inode = dentry->d_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  929) 	struct exfat_dentry *ep;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  930) 	struct exfat_chain cdir, clu_to_free;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  931) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  932) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  933) 	struct exfat_inode_info *ei = EXFAT_I(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  934) 	struct buffer_head *bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  935) 	sector_t sector;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  936) 	int num_entries, entry, err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  937) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  938) 	mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  939) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  940) 	exfat_chain_dup(&cdir, &ei->dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  941) 	entry = ei->entry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  942) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  943) 	if (ei->dir.dir == DIR_DELETED) {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  944) 		exfat_err(sb, "abnormal access to deleted dentry");
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  945) 		err = -ENOENT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  946) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  947) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  948) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  949) 	exfat_chain_set(&clu_to_free, ei->start_clu,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  950) 		EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  951) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  952) 	err = exfat_check_dir_empty(sb, &clu_to_free);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  953) 	if (err) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  954) 		if (err == -EIO)
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  955) 			exfat_err(sb, "failed to exfat_check_dir_empty : err(%d)",
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  956) 				  err);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  957) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  958) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  959) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  960) 	ep = exfat_get_dentry(sb, &cdir, entry, &bh, &sector);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  961) 	if (!ep) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  962) 		err = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  963) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  964) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  965) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  966) 	num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  967) 	if (num_entries < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  968) 		err = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  969) 		brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  970) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  971) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  972) 	num_entries++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  973) 	brelse(bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  974) 
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  975) 	exfat_set_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  976) 	err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  977) 	if (err) {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900  978) 		exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  979) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  980) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  981) 	ei->dir.dir = DIR_DELETED;
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900  982) 	exfat_clear_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  983) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  984) 	inode_inc_iversion(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  985) 	dir->i_mtime = dir->i_atime = current_time(dir);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  986) 	exfat_truncate_atime(&dir->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  987) 	if (IS_DIRSYNC(dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  988) 		exfat_sync_inode(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  989) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  990) 		mark_inode_dirty(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  991) 	drop_nlink(dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  992) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  993) 	clear_nlink(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  994) 	inode->i_mtime = inode->i_atime = current_time(inode);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900  995) 	exfat_truncate_atime(&inode->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  996) 	exfat_unhash_inode(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  997) 	exfat_d_version_set(dentry, inode_query_iversion(dir));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  998) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900  999) 	mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1000) 	return err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1001) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1002) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1003) static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1004) 		int oldentry, struct exfat_uni_name *p_uniname,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1005) 		struct exfat_inode_info *ei)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1006) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1007) 	int ret, num_old_entries, num_new_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1008) 	sector_t sector_old, sector_new;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1009) 	struct exfat_dentry *epold, *epnew;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1010) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1011) 	struct buffer_head *new_bh, *old_bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1012) 	int sync = IS_DIRSYNC(inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1013) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1014) 	epold = exfat_get_dentry(sb, p_dir, oldentry, &old_bh, &sector_old);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1015) 	if (!epold)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1016) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1017) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1018) 	num_old_entries = exfat_count_ext_entries(sb, p_dir, oldentry, epold);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1019) 	if (num_old_entries < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1020) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1021) 	num_old_entries++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1022) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1023) 	num_new_entries = exfat_calc_num_entries(p_uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1024) 	if (num_new_entries < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1025) 		return num_new_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1026) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1027) 	if (num_old_entries < num_new_entries) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1028) 		int newentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1029) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1030) 		newentry =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1031) 			exfat_find_empty_entry(inode, p_dir, num_new_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1032) 		if (newentry < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1033) 			return newentry; /* -EIO or -ENOSPC */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1034) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1035) 		epnew = exfat_get_dentry(sb, p_dir, newentry, &new_bh,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1036) 			&sector_new);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1037) 		if (!epnew)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1038) 			return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1039) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900 1040) 		*epnew = *epold;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1041) 		if (exfat_get_entry_type(epnew) == TYPE_FILE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1042) 			epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1043) 			ei->attr |= ATTR_ARCHIVE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1044) 		}
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900 1045) 		exfat_update_bh(new_bh, sync);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1046) 		brelse(old_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1047) 		brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1048) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1049) 		epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1050) 			&sector_old);
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1051) 		if (!epold)
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1052) 			return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1053) 		epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1054) 			&sector_new);
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1055) 		if (!epnew) {
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1056) 			brelse(old_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1057) 			return -EIO;
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1058) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1059) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900 1060) 		*epnew = *epold;
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900 1061) 		exfat_update_bh(new_bh, sync);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1062) 		brelse(old_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1063) 		brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1064) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1065) 		ret = exfat_init_ext_entry(inode, p_dir, newentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1066) 			num_new_entries, p_uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1067) 		if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1068) 			return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1069) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1070) 		exfat_remove_entries(inode, p_dir, oldentry, 0,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1071) 			num_old_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1072) 		ei->entry = newentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1073) 	} else {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1074) 		if (exfat_get_entry_type(epold) == TYPE_FILE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1075) 			epold->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1076) 			ei->attr |= ATTR_ARCHIVE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1077) 		}
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900 1078) 		exfat_update_bh(old_bh, sync);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1079) 		brelse(old_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1080) 		ret = exfat_init_ext_entry(inode, p_dir, oldentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1081) 			num_new_entries, p_uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1082) 		if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1083) 			return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1084) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1085) 		exfat_remove_entries(inode, p_dir, oldentry, num_new_entries,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1086) 			num_old_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1087) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1088) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1089) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1090) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1091) static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1092) 		int oldentry, struct exfat_chain *p_newdir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1093) 		struct exfat_uni_name *p_uniname, struct exfat_inode_info *ei)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1094) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1095) 	int ret, newentry, num_new_entries, num_old_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1096) 	sector_t sector_mov, sector_new;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1097) 	struct exfat_dentry *epmov, *epnew;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1098) 	struct super_block *sb = inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1099) 	struct buffer_head *mov_bh, *new_bh;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1100) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1101) 	epmov = exfat_get_dentry(sb, p_olddir, oldentry, &mov_bh, &sector_mov);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1102) 	if (!epmov)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1103) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1104) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1105) 	num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1106) 		epmov);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1107) 	if (num_old_entries < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1108) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1109) 	num_old_entries++;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1110) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1111) 	num_new_entries = exfat_calc_num_entries(p_uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1112) 	if (num_new_entries < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1113) 		return num_new_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1114) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1115) 	newentry = exfat_find_empty_entry(inode, p_newdir, num_new_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1116) 	if (newentry < 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1117) 		return newentry; /* -EIO or -ENOSPC */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1118) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1119) 	epnew = exfat_get_dentry(sb, p_newdir, newentry, &new_bh, &sector_new);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1120) 	if (!epnew)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1121) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1122) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900 1123) 	*epnew = *epmov;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1124) 	if (exfat_get_entry_type(epnew) == TYPE_FILE) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1125) 		epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1126) 		ei->attr |= ATTR_ARCHIVE;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1127) 	}
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900 1128) 	exfat_update_bh(new_bh, IS_DIRSYNC(inode));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1129) 	brelse(mov_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1130) 	brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1131) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1132) 	epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1133) 		&sector_mov);
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1134) 	if (!epmov)
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1135) 		return -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1136) 	epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1137) 		&sector_new);
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1138) 	if (!epnew) {
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1139) 		brelse(mov_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1140) 		return -EIO;
e8dd3cda86671 (Dan Carpenter     2020-06-10 20:22:13 +0300 1141) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1142) 
a7a241686c8f8 (Tetsuhiro Kohada  2020-09-11 13:45:19 +0900 1143) 	*epnew = *epmov;
2c7f8937ef915 (Tetsuhiro Kohada  2020-06-16 11:18:07 +0900 1144) 	exfat_update_bh(new_bh, IS_DIRSYNC(inode));
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1145) 	brelse(mov_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1146) 	brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1147) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1148) 	ret = exfat_init_ext_entry(inode, p_newdir, newentry, num_new_entries,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1149) 		p_uniname);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1150) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1151) 		return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1152) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1153) 	exfat_remove_entries(inode, p_olddir, oldentry, 0, num_old_entries);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1154) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1155) 	exfat_chain_set(&ei->dir, p_newdir->dir, p_newdir->size,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1156) 		p_newdir->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1157) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1158) 	ei->entry = newentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1159) 	return 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1160) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1161) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1162) static void exfat_update_parent_info(struct exfat_inode_info *ei,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1163) 		struct inode *parent_inode)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1164) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1165) 	struct exfat_sb_info *sbi = EXFAT_SB(parent_inode->i_sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1166) 	struct exfat_inode_info *parent_ei = EXFAT_I(parent_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1167) 	loff_t parent_isize = i_size_read(parent_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1168) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1169) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1170) 	 * the problem that struct exfat_inode_info caches wrong parent info.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1171) 	 *
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1172) 	 * because of flag-mismatch of ei->dir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1173) 	 * there is abnormal traversing cluster chain.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1174) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1175) 	if (unlikely(parent_ei->flags != ei->dir.flags ||
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1176) 		     parent_isize != EXFAT_CLU_TO_B(ei->dir.size, sbi) ||
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1177) 		     parent_ei->start_clu != ei->dir.dir)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1178) 		exfat_chain_set(&ei->dir, parent_ei->start_clu,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1179) 			EXFAT_B_TO_CLU_ROUND_UP(parent_isize, sbi),
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1180) 			parent_ei->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1181) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1182) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1183) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1184) /* rename or move a old file into a new file */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1185) static int __exfat_rename(struct inode *old_parent_inode,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1186) 		struct exfat_inode_info *ei, struct inode *new_parent_inode,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1187) 		struct dentry *new_dentry)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1188) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1189) 	int ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1190) 	int dentry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1191) 	struct exfat_chain olddir, newdir;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1192) 	struct exfat_chain *p_dir = NULL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1193) 	struct exfat_uni_name uni_name;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1194) 	struct exfat_dentry *ep;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1195) 	struct super_block *sb = old_parent_inode->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1196) 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1197) 	const unsigned char *new_path = new_dentry->d_name.name;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1198) 	struct inode *new_inode = new_dentry->d_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1199) 	int num_entries;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1200) 	struct exfat_inode_info *new_ei = NULL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1201) 	unsigned int new_entry_type = TYPE_UNUSED;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1202) 	int new_entry = 0;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1203) 	struct buffer_head *old_bh, *new_bh = NULL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1204) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1205) 	/* check the validity of pointer parameters */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1206) 	if (new_path == NULL || strlen(new_path) == 0)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1207) 		return -EINVAL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1208) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1209) 	if (ei->dir.dir == DIR_DELETED) {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900 1210) 		exfat_err(sb, "abnormal access to deleted source dentry");
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1211) 		return -ENOENT;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1212) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1213) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1214) 	exfat_update_parent_info(ei, old_parent_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1215) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1216) 	exfat_chain_dup(&olddir, &ei->dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1217) 	dentry = ei->entry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1218) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1219) 	ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh, NULL);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1220) 	if (!ep) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1221) 		ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1222) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1223) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1224) 	brelse(old_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1225) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1226) 	/* check whether new dir is existing directory and empty */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1227) 	if (new_inode) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1228) 		ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1229) 		new_ei = EXFAT_I(new_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1230) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1231) 		if (new_ei->dir.dir == DIR_DELETED) {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900 1232) 			exfat_err(sb, "abnormal access to deleted target dentry");
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1233) 			goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1234) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1235) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1236) 		exfat_update_parent_info(new_ei, new_parent_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1237) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1238) 		p_dir = &(new_ei->dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1239) 		new_entry = new_ei->entry;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1240) 		ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1241) 		if (!ep)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1242) 			goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1243) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1244) 		new_entry_type = exfat_get_entry_type(ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1245) 		brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1246) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1247) 		/* if new_inode exists, update ei */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1248) 		if (new_entry_type == TYPE_DIR) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1249) 			struct exfat_chain new_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1250) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1251) 			new_clu.dir = new_ei->start_clu;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1252) 			new_clu.size =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1253) 				EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1254) 				sbi);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1255) 			new_clu.flags = new_ei->flags;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1256) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1257) 			ret = exfat_check_dir_empty(sb, &new_clu);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1258) 			if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1259) 				goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1260) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1261) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1262) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1263) 	/* check the validity of directory name in the given new pathname */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1264) 	ret = exfat_resolve_path(new_parent_inode, new_path, &newdir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1265) 			&uni_name);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1266) 	if (ret)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1267) 		goto out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1268) 
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900 1269) 	exfat_set_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1270) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1271) 	if (olddir.dir == newdir.dir)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1272) 		ret = exfat_rename_file(new_parent_inode, &olddir, dentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1273) 				&uni_name, ei);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1274) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1275) 		ret = exfat_move_file(new_parent_inode, &olddir, dentry,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1276) 				&newdir, &uni_name, ei);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1277) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1278) 	if (!ret && new_inode) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1279) 		/* delete entries of new_dir */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1280) 		ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1281) 		if (!ep) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1282) 			ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1283) 			goto del_out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1284) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1285) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1286) 		num_entries = exfat_count_ext_entries(sb, p_dir, new_entry, ep);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1287) 		if (num_entries < 0) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1288) 			ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1289) 			goto del_out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1290) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1291) 		brelse(new_bh);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1292) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1293) 		if (exfat_remove_entries(new_inode, p_dir, new_entry, 0,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1294) 				num_entries + 1)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1295) 			ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1296) 			goto del_out;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1297) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1298) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1299) 		/* Free the clusters if new_inode is a dir(as if exfat_rmdir) */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1300) 		if (new_entry_type == TYPE_DIR) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1301) 			/* new_ei, new_clu_to_free */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1302) 			struct exfat_chain new_clu_to_free;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1303) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1304) 			exfat_chain_set(&new_clu_to_free, new_ei->start_clu,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1305) 				EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1306) 				sbi), new_ei->flags);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1307) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1308) 			if (exfat_free_cluster(new_inode, &new_clu_to_free)) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1309) 				/* just set I/O error only */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1310) 				ret = -EIO;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1311) 			}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1312) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1313) 			i_size_write(new_inode, 0);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1314) 			new_ei->start_clu = EXFAT_EOF_CLUSTER;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1315) 			new_ei->flags = ALLOC_NO_FAT_CHAIN;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1316) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1317) del_out:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1318) 		/* Update new_inode ei
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1319) 		 * Prevent syncing removed new_inode
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1320) 		 * (new_ei is already initialized above code ("if (new_inode)")
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1321) 		 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1322) 		new_ei->dir.dir = DIR_DELETED;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1323) 	}
7018ec68f0824 (Tetsuhiro Kohada  2020-07-31 14:58:26 +0900 1324) 	exfat_clear_volume_dirty(sb);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1325) out:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1326) 	return ret;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1327) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1328) 
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 1329) static int exfat_rename(struct user_namespace *mnt_userns,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 1330) 			struct inode *old_dir, struct dentry *old_dentry,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 1331) 			struct inode *new_dir, struct dentry *new_dentry,
549c7297717c3 (Christian Brauner 2021-01-21 14:19:43 +0100 1332) 			unsigned int flags)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1333) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1334) 	struct inode *old_inode, *new_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1335) 	struct super_block *sb = old_dir->i_sb;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1336) 	loff_t i_pos;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1337) 	int err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1338) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1339) 	/*
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1340) 	 * The VFS already checks for existence, so for local filesystems
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1341) 	 * the RENAME_NOREPLACE implementation is equivalent to plain rename.
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1342) 	 * Don't support any other flags
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1343) 	 */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1344) 	if (flags & ~RENAME_NOREPLACE)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1345) 		return -EINVAL;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1346) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1347) 	mutex_lock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1348) 	old_inode = old_dentry->d_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1349) 	new_inode = new_dentry->d_inode;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1350) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1351) 	err = __exfat_rename(old_dir, EXFAT_I(old_inode), new_dir, new_dentry);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1352) 	if (err)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1353) 		goto unlock;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1354) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1355) 	inode_inc_iversion(new_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1356) 	new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1357) 		EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
81df1ad40644b (Eric Sandeen      2020-04-21 11:13:10 +0900 1358) 	exfat_truncate_atime(&new_dir->i_atime);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1359) 	if (IS_DIRSYNC(new_dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1360) 		exfat_sync_inode(new_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1361) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1362) 		mark_inode_dirty(new_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1363) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1364) 	i_pos = ((loff_t)EXFAT_I(old_inode)->dir.dir << 32) |
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1365) 		(EXFAT_I(old_inode)->entry & 0xffffffff);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1366) 	exfat_unhash_inode(old_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1367) 	exfat_hash_inode(old_inode, i_pos);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1368) 	if (IS_DIRSYNC(new_dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1369) 		exfat_sync_inode(old_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1370) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1371) 		mark_inode_dirty(old_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1372) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1373) 	if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1374) 		drop_nlink(old_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1375) 		if (!new_inode)
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1376) 			inc_nlink(new_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1377) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1378) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1379) 	inode_inc_iversion(old_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1380) 	old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1381) 	if (IS_DIRSYNC(old_dir))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1382) 		exfat_sync_inode(old_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1383) 	else
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1384) 		mark_inode_dirty(old_dir);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1385) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1386) 	if (new_inode) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1387) 		exfat_unhash_inode(new_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1388) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1389) 		/* skip drop_nlink if new_inode already has been dropped */
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1390) 		if (new_inode->i_nlink) {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1391) 			drop_nlink(new_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1392) 			if (S_ISDIR(new_inode->i_mode))
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1393) 				drop_nlink(new_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1394) 		} else {
d1727d55c0327 (Joe Perches       2020-04-24 13:31:12 +0900 1395) 			exfat_warn(sb, "abnormal access to an inode dropped");
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1396) 			WARN_ON(new_inode->i_nlink == 0);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1397) 		}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1398) 		new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1399) 			current_time(new_inode);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1400) 	}
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1401) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1402) unlock:
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1403) 	mutex_unlock(&EXFAT_SB(sb)->s_lock);
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1404) 	return err;
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1405) }
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1406) 
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1407) const struct inode_operations exfat_dir_inode_operations = {
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1408) 	.create		= exfat_create,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1409) 	.lookup		= exfat_lookup,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1410) 	.unlink		= exfat_unlink,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1411) 	.mkdir		= exfat_mkdir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1412) 	.rmdir		= exfat_rmdir,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1413) 	.rename		= exfat_rename,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1414) 	.setattr	= exfat_setattr,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1415) 	.getattr	= exfat_getattr,
5f2aa075070cf (Namjae Jeon       2020-03-02 15:21:34 +0900 1416) };