xref: /linux/fs/ntfs/namei.c (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
11e9ea7e0SNamjae Jeon // SPDX-License-Identifier: GPL-2.0-or-later
21e9ea7e0SNamjae Jeon /*
3af0db57dSNamjae Jeon  * NTFS kernel directory inode operations.
41e9ea7e0SNamjae Jeon  *
51e9ea7e0SNamjae Jeon  * Copyright (c) 2001-2006 Anton Altaparmakov
6af0db57dSNamjae Jeon  * Copyright (c) 2025 LG Electronics Co., Ltd.
71e9ea7e0SNamjae Jeon  */
81e9ea7e0SNamjae Jeon 
91e9ea7e0SNamjae Jeon #include <linux/exportfs.h>
10af0db57dSNamjae Jeon #include <linux/iversion.h>
111e9ea7e0SNamjae Jeon 
121e9ea7e0SNamjae Jeon #include "ntfs.h"
13af0db57dSNamjae Jeon #include "time.h"
14af0db57dSNamjae Jeon #include "index.h"
15af0db57dSNamjae Jeon #include "reparse.h"
16af0db57dSNamjae Jeon #include "object_id.h"
17af0db57dSNamjae Jeon #include "ea.h"
181e9ea7e0SNamjae Jeon 
19af0db57dSNamjae Jeon static const __le16 aux_name_le[3] = {
20af0db57dSNamjae Jeon 	cpu_to_le16('A'), cpu_to_le16('U'), cpu_to_le16('X')
21af0db57dSNamjae Jeon };
22af0db57dSNamjae Jeon 
23af0db57dSNamjae Jeon static const __le16 con_name_le[3] = {
24af0db57dSNamjae Jeon 	cpu_to_le16('C'), cpu_to_le16('O'), cpu_to_le16('N')
25af0db57dSNamjae Jeon };
26af0db57dSNamjae Jeon 
27af0db57dSNamjae Jeon static const __le16 com_name_le[3] = {
28af0db57dSNamjae Jeon 	cpu_to_le16('C'), cpu_to_le16('O'), cpu_to_le16('M')
29af0db57dSNamjae Jeon };
30af0db57dSNamjae Jeon 
31af0db57dSNamjae Jeon static const __le16 lpt_name_le[3] = {
32af0db57dSNamjae Jeon 	cpu_to_le16('L'), cpu_to_le16('P'), cpu_to_le16('T')
33af0db57dSNamjae Jeon };
34af0db57dSNamjae Jeon 
35af0db57dSNamjae Jeon static const __le16 nul_name_le[3] = {
36af0db57dSNamjae Jeon 	cpu_to_le16('N'), cpu_to_le16('U'), cpu_to_le16('L')
37af0db57dSNamjae Jeon };
38af0db57dSNamjae Jeon 
39af0db57dSNamjae Jeon static const __le16 prn_name_le[3] = {
40af0db57dSNamjae Jeon 	cpu_to_le16('P'), cpu_to_le16('R'), cpu_to_le16('N')
41af0db57dSNamjae Jeon };
42af0db57dSNamjae Jeon 
43af0db57dSNamjae Jeon static inline int ntfs_check_bad_char(const __le16 *wc, unsigned int wc_len)
44af0db57dSNamjae Jeon {
45af0db57dSNamjae Jeon 	int i;
46af0db57dSNamjae Jeon 
47af0db57dSNamjae Jeon 	for (i = 0; i < wc_len; i++) {
48af0db57dSNamjae Jeon 		u16 c = le16_to_cpu(wc[i]);
49af0db57dSNamjae Jeon 
50af0db57dSNamjae Jeon 		if (c < 0x0020 ||
51af0db57dSNamjae Jeon 		    c == 0x0022 || c == 0x002A || c == 0x002F ||
52af0db57dSNamjae Jeon 		    c == 0x003A || c == 0x003C || c == 0x003E ||
53af0db57dSNamjae Jeon 		    c == 0x003F || c == 0x005C || c == 0x007C)
54af0db57dSNamjae Jeon 			return -EINVAL;
55af0db57dSNamjae Jeon 	}
56af0db57dSNamjae Jeon 
57af0db57dSNamjae Jeon 	return 0;
58af0db57dSNamjae Jeon }
59af0db57dSNamjae Jeon 
60af0db57dSNamjae Jeon static int ntfs_check_bad_windows_name(struct ntfs_volume *vol,
61af0db57dSNamjae Jeon 				       const __le16 *wc,
62af0db57dSNamjae Jeon 				       unsigned int wc_len)
63af0db57dSNamjae Jeon {
64af0db57dSNamjae Jeon 	if (ntfs_check_bad_char(wc, wc_len))
65af0db57dSNamjae Jeon 		return -EINVAL;
66af0db57dSNamjae Jeon 
67af0db57dSNamjae Jeon 	if (!NVolCheckWindowsNames(vol))
68af0db57dSNamjae Jeon 		return 0;
69af0db57dSNamjae Jeon 
70af0db57dSNamjae Jeon 	/* Check for trailing space or dot. */
71af0db57dSNamjae Jeon 	if (wc_len > 0 &&
72af0db57dSNamjae Jeon 	    (wc[wc_len - 1] == cpu_to_le16(' ') ||
73af0db57dSNamjae Jeon 	    wc[wc_len - 1] == cpu_to_le16('.')))
74af0db57dSNamjae Jeon 		return -EINVAL;
75af0db57dSNamjae Jeon 
76af0db57dSNamjae Jeon 	if (wc_len == 3 || (wc_len > 3 && wc[3] == cpu_to_le16('.'))) {
77af0db57dSNamjae Jeon 		__le16 *upcase = vol->upcase;
78af0db57dSNamjae Jeon 		u32 size = vol->upcase_len;
79af0db57dSNamjae Jeon 
80af0db57dSNamjae Jeon 		if (ntfs_are_names_equal(wc, 3, aux_name_le, 3, IGNORE_CASE, upcase, size) ||
81af0db57dSNamjae Jeon 		    ntfs_are_names_equal(wc, 3, con_name_le, 3, IGNORE_CASE, upcase, size) ||
82af0db57dSNamjae Jeon 		    ntfs_are_names_equal(wc, 3, nul_name_le, 3, IGNORE_CASE, upcase, size) ||
83af0db57dSNamjae Jeon 		    ntfs_are_names_equal(wc, 3, prn_name_le, 3, IGNORE_CASE, upcase, size))
84af0db57dSNamjae Jeon 			return -EINVAL;
85af0db57dSNamjae Jeon 	}
86af0db57dSNamjae Jeon 
87af0db57dSNamjae Jeon 	if (wc_len == 4 || (wc_len > 4 && wc[4] == cpu_to_le16('.'))) {
88af0db57dSNamjae Jeon 		__le16 *upcase = vol->upcase;
89af0db57dSNamjae Jeon 		u32 size = vol->upcase_len, port;
90af0db57dSNamjae Jeon 
91af0db57dSNamjae Jeon 		if (ntfs_are_names_equal(wc, 3, com_name_le, 3, IGNORE_CASE, upcase, size) ||
92af0db57dSNamjae Jeon 		    ntfs_are_names_equal(wc, 3, lpt_name_le, 3, IGNORE_CASE, upcase, size)) {
93af0db57dSNamjae Jeon 			port = le16_to_cpu(wc[3]);
94af0db57dSNamjae Jeon 			if (port >= '1' && port <= '9')
95af0db57dSNamjae Jeon 				return -EINVAL;
96af0db57dSNamjae Jeon 		}
97af0db57dSNamjae Jeon 	}
98af0db57dSNamjae Jeon 	return 0;
99af0db57dSNamjae Jeon }
100af0db57dSNamjae Jeon 
101af0db57dSNamjae Jeon /*
1021e9ea7e0SNamjae Jeon  * ntfs_lookup - find the inode represented by a dentry in a directory inode
1031e9ea7e0SNamjae Jeon  * @dir_ino:	directory inode in which to look for the inode
1041e9ea7e0SNamjae Jeon  * @dent:	dentry representing the inode to look for
1051e9ea7e0SNamjae Jeon  * @flags:	lookup flags
1061e9ea7e0SNamjae Jeon  *
1071e9ea7e0SNamjae Jeon  * In short, ntfs_lookup() looks for the inode represented by the dentry @dent
1081e9ea7e0SNamjae Jeon  * in the directory inode @dir_ino and if found attaches the inode to the
1091e9ea7e0SNamjae Jeon  * dentry @dent.
1101e9ea7e0SNamjae Jeon  *
1111e9ea7e0SNamjae Jeon  * In more detail, the dentry @dent specifies which inode to look for by
1121e9ea7e0SNamjae Jeon  * supplying the name of the inode in @dent->d_name.name. ntfs_lookup()
1131e9ea7e0SNamjae Jeon  * converts the name to Unicode and walks the contents of the directory inode
1141e9ea7e0SNamjae Jeon  * @dir_ino looking for the converted Unicode name. If the name is found in the
1151e9ea7e0SNamjae Jeon  * directory, the corresponding inode is loaded by calling ntfs_iget() on its
1161e9ea7e0SNamjae Jeon  * inode number and the inode is associated with the dentry @dent via a call to
1171e9ea7e0SNamjae Jeon  * d_splice_alias().
1181e9ea7e0SNamjae Jeon  *
1191e9ea7e0SNamjae Jeon  * If the name is not found in the directory, a NULL inode is inserted into the
1201e9ea7e0SNamjae Jeon  * dentry @dent via a call to d_add(). The dentry is then termed a negative
1211e9ea7e0SNamjae Jeon  * dentry.
1221e9ea7e0SNamjae Jeon  *
1231e9ea7e0SNamjae Jeon  * Only if an actual error occurs, do we return an error via ERR_PTR().
1241e9ea7e0SNamjae Jeon  *
1251e9ea7e0SNamjae Jeon  * In order to handle the case insensitivity issues of NTFS with regards to the
1261e9ea7e0SNamjae Jeon  * dcache and the dcache requiring only one dentry per directory, we deal with
1271e9ea7e0SNamjae Jeon  * dentry aliases that only differ in case in ->ntfs_lookup() while maintaining
1281e9ea7e0SNamjae Jeon  * a case sensitive dcache. This means that we get the full benefit of dcache
1291e9ea7e0SNamjae Jeon  * speed when the file/directory is looked up with the same case as returned by
1301e9ea7e0SNamjae Jeon  * ->ntfs_readdir() but that a lookup for any other case (or for the short file
1311e9ea7e0SNamjae Jeon  * name) will not find anything in dcache and will enter ->ntfs_lookup()
1321e9ea7e0SNamjae Jeon  * instead, where we search the directory for a fully matching file name
1331e9ea7e0SNamjae Jeon  * (including case) and if that is not found, we search for a file name that
1341e9ea7e0SNamjae Jeon  * matches with different case and if that has non-POSIX semantics we return
1351e9ea7e0SNamjae Jeon  * that. We actually do only one search (case sensitive) and keep tabs on
1361e9ea7e0SNamjae Jeon  * whether we have found a case insensitive match in the process.
1371e9ea7e0SNamjae Jeon  *
1381e9ea7e0SNamjae Jeon  * To simplify matters for us, we do not treat the short vs long filenames as
1391e9ea7e0SNamjae Jeon  * two hard links but instead if the lookup matches a short filename, we
1401e9ea7e0SNamjae Jeon  * return the dentry for the corresponding long filename instead.
1411e9ea7e0SNamjae Jeon  *
1421e9ea7e0SNamjae Jeon  * There are three cases we need to distinguish here:
1431e9ea7e0SNamjae Jeon  *
1441e9ea7e0SNamjae Jeon  * 1) @dent perfectly matches (i.e. including case) a directory entry with a
1451e9ea7e0SNamjae Jeon  *    file name in the WIN32 or POSIX namespaces. In this case
1461e9ea7e0SNamjae Jeon  *    ntfs_lookup_inode_by_name() will return with name set to NULL and we
1471e9ea7e0SNamjae Jeon  *    just d_splice_alias() @dent.
1481e9ea7e0SNamjae Jeon  * 2) @dent matches (not including case) a directory entry with a file name in
1491e9ea7e0SNamjae Jeon  *    the WIN32 namespace. In this case ntfs_lookup_inode_by_name() will return
1501e9ea7e0SNamjae Jeon  *    with name set to point to a kmalloc()ed ntfs_name structure containing
1511e9ea7e0SNamjae Jeon  *    the properly cased little endian Unicode name. We convert the name to the
1521e9ea7e0SNamjae Jeon  *    current NLS code page, search if a dentry with this name already exists
1531e9ea7e0SNamjae Jeon  *    and if so return that instead of @dent.  At this point things are
1541e9ea7e0SNamjae Jeon  *    complicated by the possibility of 'disconnected' dentries due to NFS
1551e9ea7e0SNamjae Jeon  *    which we deal with appropriately (see the code comments).  The VFS will
1561e9ea7e0SNamjae Jeon  *    then destroy the old @dent and use the one we returned.  If a dentry is
1571e9ea7e0SNamjae Jeon  *    not found, we allocate a new one, d_splice_alias() it, and return it as
1581e9ea7e0SNamjae Jeon  *    above.
1591e9ea7e0SNamjae Jeon  * 3) @dent matches either perfectly or not (i.e. we don't care about case) a
1601e9ea7e0SNamjae Jeon  *    directory entry with a file name in the DOS namespace. In this case
1611e9ea7e0SNamjae Jeon  *    ntfs_lookup_inode_by_name() will return with name set to point to a
1621e9ea7e0SNamjae Jeon  *    kmalloc()ed ntfs_name structure containing the mft reference (cpu endian)
1631e9ea7e0SNamjae Jeon  *    of the inode. We use the mft reference to read the inode and to find the
1641e9ea7e0SNamjae Jeon  *    file name in the WIN32 namespace corresponding to the matched short file
1651e9ea7e0SNamjae Jeon  *    name. We then convert the name to the current NLS code page, and proceed
1661e9ea7e0SNamjae Jeon  *    searching for a dentry with this name, etc, as in case 2), above.
1671e9ea7e0SNamjae Jeon  *
1681e9ea7e0SNamjae Jeon  * Locking: Caller must hold i_mutex on the directory.
1691e9ea7e0SNamjae Jeon  */
1701e9ea7e0SNamjae Jeon static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
1711e9ea7e0SNamjae Jeon 		unsigned int flags)
1721e9ea7e0SNamjae Jeon {
173af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
1741e9ea7e0SNamjae Jeon 	struct inode *dent_inode;
175af0db57dSNamjae Jeon 	__le16 *uname;
176af0db57dSNamjae Jeon 	struct ntfs_name *name = NULL;
177af0db57dSNamjae Jeon 	u64 mref;
1781e9ea7e0SNamjae Jeon 	unsigned long dent_ino;
1791e9ea7e0SNamjae Jeon 	int uname_len;
1801e9ea7e0SNamjae Jeon 
181e7d82353SNamjae Jeon 	ntfs_debug("Looking up %pd in directory inode 0x%llx.",
182e7d82353SNamjae Jeon 			dent, NTFS_I(dir_ino)->mft_no);
1831e9ea7e0SNamjae Jeon 	/* Convert the name of the dentry to Unicode. */
1841e9ea7e0SNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
185af0db57dSNamjae Jeon 				  &uname, NTFS_MAX_NAME_LEN);
1861e9ea7e0SNamjae Jeon 	if (uname_len < 0) {
1871e9ea7e0SNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
188af0db57dSNamjae Jeon 			ntfs_debug("Failed to convert name to Unicode.");
1891e9ea7e0SNamjae Jeon 		return ERR_PTR(uname_len);
1901e9ea7e0SNamjae Jeon 	}
191af0db57dSNamjae Jeon 	mutex_lock(&NTFS_I(dir_ino)->mrec_lock);
1921e9ea7e0SNamjae Jeon 	mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
1931e9ea7e0SNamjae Jeon 			&name);
194af0db57dSNamjae Jeon 	mutex_unlock(&NTFS_I(dir_ino)->mrec_lock);
1951e9ea7e0SNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
1961e9ea7e0SNamjae Jeon 	if (!IS_ERR_MREF(mref)) {
1971e9ea7e0SNamjae Jeon 		dent_ino = MREF(mref);
1981e9ea7e0SNamjae Jeon 		ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
1991e9ea7e0SNamjae Jeon 		dent_inode = ntfs_iget(vol->sb, dent_ino);
2001e9ea7e0SNamjae Jeon 		if (!IS_ERR(dent_inode)) {
2011e9ea7e0SNamjae Jeon 			/* Consistency check. */
202af0db57dSNamjae Jeon 			if (MSEQNO(mref) == NTFS_I(dent_inode)->seq_no ||
2031e9ea7e0SNamjae Jeon 			    dent_ino == FILE_MFT) {
2041e9ea7e0SNamjae Jeon 				/* Perfect WIN32/POSIX match. -- Case 1. */
2051e9ea7e0SNamjae Jeon 				if (!name) {
2061e9ea7e0SNamjae Jeon 					ntfs_debug("Done.  (Case 1.)");
2071e9ea7e0SNamjae Jeon 					return d_splice_alias(dent_inode, dent);
2081e9ea7e0SNamjae Jeon 				}
2091e9ea7e0SNamjae Jeon 				/*
2101e9ea7e0SNamjae Jeon 				 * We are too indented.  Handle imperfect
2111e9ea7e0SNamjae Jeon 				 * matches and short file names further below.
2121e9ea7e0SNamjae Jeon 				 */
2131e9ea7e0SNamjae Jeon 				goto handle_name;
2141e9ea7e0SNamjae Jeon 			}
215af0db57dSNamjae Jeon 			ntfs_error(vol->sb,
216af0db57dSNamjae Jeon 				"Found stale reference to inode 0x%lx (reference sequence number = 0x%x, inode sequence number = 0x%x), returning -EIO. Run chkdsk.",
2171e9ea7e0SNamjae Jeon 				dent_ino, MSEQNO(mref),
2181e9ea7e0SNamjae Jeon 				NTFS_I(dent_inode)->seq_no);
2191e9ea7e0SNamjae Jeon 			iput(dent_inode);
2201e9ea7e0SNamjae Jeon 			dent_inode = ERR_PTR(-EIO);
2211e9ea7e0SNamjae Jeon 		} else
222af0db57dSNamjae Jeon 			ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with error code %li.",
223af0db57dSNamjae Jeon 					dent_ino, PTR_ERR(dent_inode));
2241e9ea7e0SNamjae Jeon 		kfree(name);
2251e9ea7e0SNamjae Jeon 		/* Return the error code. */
2261e9ea7e0SNamjae Jeon 		return ERR_CAST(dent_inode);
2271e9ea7e0SNamjae Jeon 	}
228af0db57dSNamjae Jeon 	kfree(name);
2291e9ea7e0SNamjae Jeon 	/* It is guaranteed that @name is no longer allocated at this point. */
2301e9ea7e0SNamjae Jeon 	if (MREF_ERR(mref) == -ENOENT) {
2311e9ea7e0SNamjae Jeon 		ntfs_debug("Entry was not found, adding negative dentry.");
2321e9ea7e0SNamjae Jeon 		/* The dcache will handle negative entries. */
2331e9ea7e0SNamjae Jeon 		d_add(dent, NULL);
2341e9ea7e0SNamjae Jeon 		ntfs_debug("Done.");
2351e9ea7e0SNamjae Jeon 		return NULL;
2361e9ea7e0SNamjae Jeon 	}
237af0db57dSNamjae Jeon 	ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error code %i.",
238af0db57dSNamjae Jeon 			-MREF_ERR(mref));
2391e9ea7e0SNamjae Jeon 	return ERR_PTR(MREF_ERR(mref));
2401e9ea7e0SNamjae Jeon handle_name:
2411e9ea7e0SNamjae Jeon 	{
242af0db57dSNamjae Jeon 		struct mft_record *m;
243af0db57dSNamjae Jeon 		struct ntfs_attr_search_ctx *ctx;
244af0db57dSNamjae Jeon 		struct ntfs_inode *ni = NTFS_I(dent_inode);
2451e9ea7e0SNamjae Jeon 		int err;
2461e9ea7e0SNamjae Jeon 		struct qstr nls_name;
2471e9ea7e0SNamjae Jeon 
2481e9ea7e0SNamjae Jeon 		nls_name.name = NULL;
2491e9ea7e0SNamjae Jeon 		if (name->type != FILE_NAME_DOS) {			/* Case 2. */
2501e9ea7e0SNamjae Jeon 			ntfs_debug("Case 2.");
251af0db57dSNamjae Jeon 			nls_name.len = (unsigned int)ntfs_ucstonls(vol,
252af0db57dSNamjae Jeon 					(__le16 *)&name->name, name->len,
2531e9ea7e0SNamjae Jeon 					(unsigned char **)&nls_name.name, 0);
2541e9ea7e0SNamjae Jeon 			kfree(name);
2551e9ea7e0SNamjae Jeon 		} else /* if (name->type == FILE_NAME_DOS) */ {		/* Case 3. */
256af0db57dSNamjae Jeon 			struct file_name_attr *fn;
2571e9ea7e0SNamjae Jeon 
2581e9ea7e0SNamjae Jeon 			ntfs_debug("Case 3.");
2591e9ea7e0SNamjae Jeon 			kfree(name);
2601e9ea7e0SNamjae Jeon 
2611e9ea7e0SNamjae Jeon 			/* Find the WIN32 name corresponding to the matched DOS name. */
2621e9ea7e0SNamjae Jeon 			ni = NTFS_I(dent_inode);
2631e9ea7e0SNamjae Jeon 			m = map_mft_record(ni);
2641e9ea7e0SNamjae Jeon 			if (IS_ERR(m)) {
2651e9ea7e0SNamjae Jeon 				err = PTR_ERR(m);
2661e9ea7e0SNamjae Jeon 				m = NULL;
2671e9ea7e0SNamjae Jeon 				ctx = NULL;
2681e9ea7e0SNamjae Jeon 				goto err_out;
2691e9ea7e0SNamjae Jeon 			}
2701e9ea7e0SNamjae Jeon 			ctx = ntfs_attr_get_search_ctx(ni, m);
2711e9ea7e0SNamjae Jeon 			if (unlikely(!ctx)) {
2721e9ea7e0SNamjae Jeon 				err = -ENOMEM;
2731e9ea7e0SNamjae Jeon 				goto err_out;
2741e9ea7e0SNamjae Jeon 			}
2751e9ea7e0SNamjae Jeon 			do {
276af0db57dSNamjae Jeon 				struct attr_record *a;
2771e9ea7e0SNamjae Jeon 
2781e9ea7e0SNamjae Jeon 				err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
2791e9ea7e0SNamjae Jeon 						NULL, 0, ctx);
2801e9ea7e0SNamjae Jeon 				if (unlikely(err)) {
281af0db57dSNamjae Jeon 					ntfs_error(vol->sb,
282af0db57dSNamjae Jeon 						"Inode corrupt: No WIN32 namespace counterpart to DOS file name. Run chkdsk.");
2831e9ea7e0SNamjae Jeon 					if (err == -ENOENT)
2841e9ea7e0SNamjae Jeon 						err = -EIO;
2851e9ea7e0SNamjae Jeon 					goto err_out;
2861e9ea7e0SNamjae Jeon 				}
2871e9ea7e0SNamjae Jeon 				/* Consistency checks. */
2881e9ea7e0SNamjae Jeon 				a = ctx->attr;
2891e9ea7e0SNamjae Jeon 				if (a->non_resident || a->flags)
2901e9ea7e0SNamjae Jeon 					goto eio_err_out;
291af0db57dSNamjae Jeon 				fn = (struct file_name_attr *)((u8 *)ctx->attr + le16_to_cpu(
2921e9ea7e0SNamjae Jeon 							ctx->attr->data.resident.value_offset));
2931e9ea7e0SNamjae Jeon 			} while (fn->file_name_type != FILE_NAME_WIN32);
2941e9ea7e0SNamjae Jeon 
2951e9ea7e0SNamjae Jeon 			/* Convert the found WIN32 name to current NLS code page. */
296af0db57dSNamjae Jeon 			nls_name.len = (unsigned int)ntfs_ucstonls(vol,
297af0db57dSNamjae Jeon 					(__le16 *)&fn->file_name, fn->file_name_length,
2981e9ea7e0SNamjae Jeon 					(unsigned char **)&nls_name.name, 0);
2991e9ea7e0SNamjae Jeon 
3001e9ea7e0SNamjae Jeon 			ntfs_attr_put_search_ctx(ctx);
3011e9ea7e0SNamjae Jeon 			unmap_mft_record(ni);
3021e9ea7e0SNamjae Jeon 		}
3031e9ea7e0SNamjae Jeon 		m = NULL;
3041e9ea7e0SNamjae Jeon 		ctx = NULL;
3051e9ea7e0SNamjae Jeon 
3061e9ea7e0SNamjae Jeon 		/* Check if a conversion error occurred. */
307af0db57dSNamjae Jeon 		if ((int)nls_name.len < 0) {
308af0db57dSNamjae Jeon 			err = (int)nls_name.len;
3091e9ea7e0SNamjae Jeon 			goto err_out;
3101e9ea7e0SNamjae Jeon 		}
3111e9ea7e0SNamjae Jeon 		nls_name.hash = full_name_hash(dent, nls_name.name, nls_name.len);
3121e9ea7e0SNamjae Jeon 
3131e9ea7e0SNamjae Jeon 		dent = d_add_ci(dent, dent_inode, &nls_name);
3141e9ea7e0SNamjae Jeon 		kfree(nls_name.name);
3151e9ea7e0SNamjae Jeon 		return dent;
3161e9ea7e0SNamjae Jeon 
3171e9ea7e0SNamjae Jeon eio_err_out:
3181e9ea7e0SNamjae Jeon 		ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
3191e9ea7e0SNamjae Jeon 		err = -EIO;
3201e9ea7e0SNamjae Jeon err_out:
3211e9ea7e0SNamjae Jeon 		if (ctx)
3221e9ea7e0SNamjae Jeon 			ntfs_attr_put_search_ctx(ctx);
3231e9ea7e0SNamjae Jeon 		if (m)
3241e9ea7e0SNamjae Jeon 			unmap_mft_record(ni);
3251e9ea7e0SNamjae Jeon 		iput(dent_inode);
3261e9ea7e0SNamjae Jeon 		ntfs_error(vol->sb, "Failed, returning error code %i.", err);
3271e9ea7e0SNamjae Jeon 		return ERR_PTR(err);
3281e9ea7e0SNamjae Jeon 	}
3291e9ea7e0SNamjae Jeon }
3301e9ea7e0SNamjae Jeon 
331af0db57dSNamjae Jeon static int ntfs_sd_add_everyone(struct ntfs_inode *ni)
332af0db57dSNamjae Jeon {
333af0db57dSNamjae Jeon 	struct security_descriptor_relative *sd;
334af0db57dSNamjae Jeon 	struct ntfs_acl *acl;
335af0db57dSNamjae Jeon 	struct ntfs_ace *ace;
336af0db57dSNamjae Jeon 	struct ntfs_sid *sid;
337af0db57dSNamjae Jeon 	int ret, sd_len;
338af0db57dSNamjae Jeon 
339af0db57dSNamjae Jeon 	/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
340af0db57dSNamjae Jeon 	/*
341af0db57dSNamjae Jeon 	 * Calculate security descriptor length. We have 2 sub-authorities in
342af0db57dSNamjae Jeon 	 * owner and group SIDs, So add 8 bytes to every SID.
343af0db57dSNamjae Jeon 	 */
344af0db57dSNamjae Jeon 	sd_len = sizeof(struct security_descriptor_relative) + 2 *
345af0db57dSNamjae Jeon 		(sizeof(struct ntfs_sid) + 8) + sizeof(struct ntfs_acl) +
346af0db57dSNamjae Jeon 		sizeof(struct ntfs_ace) + 4;
347af0db57dSNamjae Jeon 	sd = kmalloc(sd_len, GFP_NOFS);
348af0db57dSNamjae Jeon 	if (!sd)
349af0db57dSNamjae Jeon 		return -1;
350af0db57dSNamjae Jeon 
351af0db57dSNamjae Jeon 	sd->revision = 1;
352af0db57dSNamjae Jeon 	sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
353af0db57dSNamjae Jeon 
354af0db57dSNamjae Jeon 	sid = (struct ntfs_sid *)((u8 *)sd + sizeof(struct security_descriptor_relative));
355af0db57dSNamjae Jeon 	sid->revision = 1;
356af0db57dSNamjae Jeon 	sid->sub_authority_count = 2;
357af0db57dSNamjae Jeon 	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
358af0db57dSNamjae Jeon 	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
359af0db57dSNamjae Jeon 	sid->identifier_authority.value[5] = 5;
360af0db57dSNamjae Jeon 	sd->owner = cpu_to_le32((u8 *)sid - (u8 *)sd);
361af0db57dSNamjae Jeon 
362af0db57dSNamjae Jeon 	sid = (struct ntfs_sid *)((u8 *)sid + sizeof(struct ntfs_sid) + 8);
363af0db57dSNamjae Jeon 	sid->revision = 1;
364af0db57dSNamjae Jeon 	sid->sub_authority_count = 2;
365af0db57dSNamjae Jeon 	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
366af0db57dSNamjae Jeon 	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
367af0db57dSNamjae Jeon 	sid->identifier_authority.value[5] = 5;
368af0db57dSNamjae Jeon 	sd->group = cpu_to_le32((u8 *)sid - (u8 *)sd);
369af0db57dSNamjae Jeon 
370af0db57dSNamjae Jeon 	acl = (struct ntfs_acl *)((u8 *)sid + sizeof(struct ntfs_sid) + 8);
371af0db57dSNamjae Jeon 	acl->revision = 2;
372af0db57dSNamjae Jeon 	acl->size = cpu_to_le16(sizeof(struct ntfs_acl) + sizeof(struct ntfs_ace) + 4);
373af0db57dSNamjae Jeon 	acl->ace_count = cpu_to_le16(1);
374af0db57dSNamjae Jeon 	sd->dacl = cpu_to_le32((u8 *)acl - (u8 *)sd);
375af0db57dSNamjae Jeon 
376af0db57dSNamjae Jeon 	ace = (struct ntfs_ace *)((u8 *)acl + sizeof(struct ntfs_acl));
377af0db57dSNamjae Jeon 	ace->type = ACCESS_ALLOWED_ACE_TYPE;
378af0db57dSNamjae Jeon 	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
379af0db57dSNamjae Jeon 	ace->size = cpu_to_le16(sizeof(struct ntfs_ace) + 4);
380af0db57dSNamjae Jeon 	ace->mask = cpu_to_le32(0x1f01ff);
381af0db57dSNamjae Jeon 	ace->sid.revision = 1;
382af0db57dSNamjae Jeon 	ace->sid.sub_authority_count = 1;
383af0db57dSNamjae Jeon 	ace->sid.sub_authority[0] = 0;
384af0db57dSNamjae Jeon 	ace->sid.identifier_authority.value[5] = 1;
385af0db57dSNamjae Jeon 
386af0db57dSNamjae Jeon 	ret = ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0, (u8 *)sd,
387af0db57dSNamjae Jeon 			sd_len);
388af0db57dSNamjae Jeon 	if (ret)
389af0db57dSNamjae Jeon 		ntfs_error(ni->vol->sb, "Failed to add SECURITY_DESCRIPTOR\n");
390af0db57dSNamjae Jeon 
391af0db57dSNamjae Jeon 	kfree(sd);
392af0db57dSNamjae Jeon 	return ret;
393af0db57dSNamjae Jeon }
394af0db57dSNamjae Jeon 
395af0db57dSNamjae Jeon static struct ntfs_inode *__ntfs_create(struct mnt_idmap *idmap, struct inode *dir,
396af0db57dSNamjae Jeon 		__le16 *name, u8 name_len, mode_t mode, dev_t dev,
397af0db57dSNamjae Jeon 		__le16 *target, int target_len)
398af0db57dSNamjae Jeon {
399af0db57dSNamjae Jeon 	struct ntfs_inode *dir_ni = NTFS_I(dir);
400af0db57dSNamjae Jeon 	struct ntfs_volume *vol = dir_ni->vol;
401af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
402af0db57dSNamjae Jeon 	bool rollback_data = false, rollback_sd = false, rollback_reparse = false;
403af0db57dSNamjae Jeon 	struct file_name_attr *fn = NULL;
404af0db57dSNamjae Jeon 	struct standard_information *si = NULL;
405af0db57dSNamjae Jeon 	int err = 0, fn_len, si_len;
406af0db57dSNamjae Jeon 	struct inode *vi;
407af0db57dSNamjae Jeon 	struct mft_record *ni_mrec, *dni_mrec;
408af0db57dSNamjae Jeon 	struct super_block *sb = dir_ni->vol->sb;
409af0db57dSNamjae Jeon 	__le64 parent_mft_ref;
410af0db57dSNamjae Jeon 	u64 child_mft_ref;
411af0db57dSNamjae Jeon 	__le16 ea_size;
412af0db57dSNamjae Jeon 
413af0db57dSNamjae Jeon 	vi = new_inode(vol->sb);
414af0db57dSNamjae Jeon 	if (!vi)
415af0db57dSNamjae Jeon 		return ERR_PTR(-ENOMEM);
416af0db57dSNamjae Jeon 
417af0db57dSNamjae Jeon 	ntfs_init_big_inode(vi);
418af0db57dSNamjae Jeon 	ni = NTFS_I(vi);
419af0db57dSNamjae Jeon 	ni->vol = dir_ni->vol;
420af0db57dSNamjae Jeon 	ni->name_len = 0;
421af0db57dSNamjae Jeon 	ni->name = NULL;
422af0db57dSNamjae Jeon 
423af0db57dSNamjae Jeon 	/*
424af0db57dSNamjae Jeon 	 * Set the appropriate mode, attribute type, and name.  For
425af0db57dSNamjae Jeon 	 * directories, also setup the index values to the defaults.
426af0db57dSNamjae Jeon 	 */
427af0db57dSNamjae Jeon 	if (S_ISDIR(mode)) {
428af0db57dSNamjae Jeon 		mode &= ~vol->dmask;
429af0db57dSNamjae Jeon 
430af0db57dSNamjae Jeon 		NInoSetMstProtected(ni);
431af0db57dSNamjae Jeon 		ni->itype.index.block_size = 4096;
432af0db57dSNamjae Jeon 		ni->itype.index.block_size_bits = ntfs_ffs(4096) - 1;
433af0db57dSNamjae Jeon 		ni->itype.index.collation_rule = COLLATION_FILE_NAME;
434af0db57dSNamjae Jeon 		if (vol->cluster_size <= ni->itype.index.block_size) {
435af0db57dSNamjae Jeon 			ni->itype.index.vcn_size = vol->cluster_size;
436af0db57dSNamjae Jeon 			ni->itype.index.vcn_size_bits =
437af0db57dSNamjae Jeon 				vol->cluster_size_bits;
438af0db57dSNamjae Jeon 		} else {
439af0db57dSNamjae Jeon 			ni->itype.index.vcn_size = vol->sector_size;
440af0db57dSNamjae Jeon 			ni->itype.index.vcn_size_bits =
441af0db57dSNamjae Jeon 				vol->sector_size_bits;
442af0db57dSNamjae Jeon 		}
443af0db57dSNamjae Jeon 	} else {
444af0db57dSNamjae Jeon 		mode &= ~vol->fmask;
445af0db57dSNamjae Jeon 	}
446af0db57dSNamjae Jeon 
447af0db57dSNamjae Jeon 	if (IS_RDONLY(vi))
448af0db57dSNamjae Jeon 		mode &= ~0222;
449af0db57dSNamjae Jeon 
450af0db57dSNamjae Jeon 	inode_init_owner(idmap, vi, dir, mode);
451af0db57dSNamjae Jeon 
452af0db57dSNamjae Jeon 	mode = vi->i_mode;
453af0db57dSNamjae Jeon 
454af0db57dSNamjae Jeon #ifdef CONFIG_NTFS_FS_POSIX_ACL
455af0db57dSNamjae Jeon 	if (!S_ISLNK(mode) && (sb->s_flags & SB_POSIXACL)) {
456af0db57dSNamjae Jeon 		err = ntfs_init_acl(idmap, vi, dir);
457af0db57dSNamjae Jeon 		if (err)
458af0db57dSNamjae Jeon 			goto err_out;
459af0db57dSNamjae Jeon 	} else
460af0db57dSNamjae Jeon #endif
461af0db57dSNamjae Jeon 	{
462af0db57dSNamjae Jeon 		vi->i_flags |= S_NOSEC;
463af0db57dSNamjae Jeon 	}
464af0db57dSNamjae Jeon 
465af0db57dSNamjae Jeon 	if (uid_valid(vol->uid))
466af0db57dSNamjae Jeon 		vi->i_uid = vol->uid;
467af0db57dSNamjae Jeon 
468af0db57dSNamjae Jeon 	if (gid_valid(vol->gid))
469af0db57dSNamjae Jeon 		vi->i_gid = vol->gid;
470af0db57dSNamjae Jeon 
471af0db57dSNamjae Jeon 	/*
472af0db57dSNamjae Jeon 	 * Set the file size to 0, the ntfs inode sizes are set to 0 by
473af0db57dSNamjae Jeon 	 * the call to ntfs_init_big_inode() below.
474af0db57dSNamjae Jeon 	 */
475af0db57dSNamjae Jeon 	vi->i_size = 0;
476af0db57dSNamjae Jeon 	vi->i_blocks = 0;
477af0db57dSNamjae Jeon 
478af0db57dSNamjae Jeon 	inode_inc_iversion(vi);
479af0db57dSNamjae Jeon 
480af0db57dSNamjae Jeon 	simple_inode_init_ts(vi);
481af0db57dSNamjae Jeon 	ni->i_crtime = inode_get_ctime(vi);
482af0db57dSNamjae Jeon 
483af0db57dSNamjae Jeon 	inode_set_mtime_to_ts(dir, ni->i_crtime);
484af0db57dSNamjae Jeon 	inode_set_ctime_to_ts(dir, ni->i_crtime);
485af0db57dSNamjae Jeon 	mark_inode_dirty(dir);
486af0db57dSNamjae Jeon 
487af0db57dSNamjae Jeon 	err = ntfs_mft_record_alloc(dir_ni->vol, mode, &ni, NULL,
488af0db57dSNamjae Jeon 				    &ni_mrec);
489af0db57dSNamjae Jeon 	if (err) {
490af0db57dSNamjae Jeon 		iput(vi);
491af0db57dSNamjae Jeon 		return ERR_PTR(err);
492af0db57dSNamjae Jeon 	}
493af0db57dSNamjae Jeon 
494af0db57dSNamjae Jeon 	/*
495af0db57dSNamjae Jeon 	 * Prevent iget and writeback from finding this inode.
496af0db57dSNamjae Jeon 	 * Caller must call d_instantiate_new instead of d_instantiate.
497af0db57dSNamjae Jeon 	 */
498af0db57dSNamjae Jeon 	spin_lock(&vi->i_lock);
499af0db57dSNamjae Jeon 	inode_state_set(vi, I_NEW | I_CREATING);
500af0db57dSNamjae Jeon 	spin_unlock(&vi->i_lock);
501af0db57dSNamjae Jeon 
502af0db57dSNamjae Jeon 	/* Add the inode to the inode hash for the superblock. */
503d9038d99SNamjae Jeon 	vi->i_ino = (unsigned long)ni->mft_no;
504af0db57dSNamjae Jeon 	inode_set_iversion(vi, 1);
505af0db57dSNamjae Jeon 	insert_inode_hash(vi);
506af0db57dSNamjae Jeon 
507af0db57dSNamjae Jeon 	mutex_lock_nested(&ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL);
508af0db57dSNamjae Jeon 	mutex_lock_nested(&dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT);
509af0db57dSNamjae Jeon 	if (NInoBeingDeleted(dir_ni)) {
510af0db57dSNamjae Jeon 		err = -ENOENT;
511af0db57dSNamjae Jeon 		goto err_out;
512af0db57dSNamjae Jeon 	}
513af0db57dSNamjae Jeon 
514af0db57dSNamjae Jeon 	dni_mrec = map_mft_record(dir_ni);
515af0db57dSNamjae Jeon 	if (IS_ERR(dni_mrec)) {
516d9038d99SNamjae Jeon 		ntfs_error(dir_ni->vol->sb, "failed to map mft record for file 0x%llx.\n",
517af0db57dSNamjae Jeon 			   dir_ni->mft_no);
518af0db57dSNamjae Jeon 		err = -EIO;
519af0db57dSNamjae Jeon 		goto err_out;
520af0db57dSNamjae Jeon 	}
521af0db57dSNamjae Jeon 	parent_mft_ref = MK_LE_MREF(dir_ni->mft_no,
522af0db57dSNamjae Jeon 				    le16_to_cpu(dni_mrec->sequence_number));
523af0db57dSNamjae Jeon 	unmap_mft_record(dir_ni);
524af0db57dSNamjae Jeon 
525af0db57dSNamjae Jeon 	/*
526af0db57dSNamjae Jeon 	 * Create STANDARD_INFORMATION attribute. Write STANDARD_INFORMATION
527af0db57dSNamjae Jeon 	 * version 1.2, windows will upgrade it to version 3 if needed.
528af0db57dSNamjae Jeon 	 */
529af0db57dSNamjae Jeon 	si_len = offsetof(struct standard_information, file_attributes) +
530af0db57dSNamjae Jeon 		sizeof(__le32) + 12;
531af0db57dSNamjae Jeon 	si = kzalloc(si_len, GFP_NOFS);
532af0db57dSNamjae Jeon 	if (!si) {
533af0db57dSNamjae Jeon 		err = -ENOMEM;
534af0db57dSNamjae Jeon 		goto err_out;
535af0db57dSNamjae Jeon 	}
536af0db57dSNamjae Jeon 
537af0db57dSNamjae Jeon 	si->creation_time = si->last_data_change_time = utc2ntfs(ni->i_crtime);
538af0db57dSNamjae Jeon 	si->last_mft_change_time = si->last_access_time = si->creation_time;
539af0db57dSNamjae Jeon 
540af0db57dSNamjae Jeon 	if (!S_ISREG(mode) && !S_ISDIR(mode))
541af0db57dSNamjae Jeon 		si->file_attributes = FILE_ATTR_SYSTEM;
542af0db57dSNamjae Jeon 
543af0db57dSNamjae Jeon 	/* Add STANDARD_INFORMATION to inode. */
544af0db57dSNamjae Jeon 	err = ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0, (u8 *)si,
545af0db57dSNamjae Jeon 			si_len);
546af0db57dSNamjae Jeon 	if (err) {
547af0db57dSNamjae Jeon 		ntfs_error(sb, "Failed to add STANDARD_INFORMATION attribute.\n");
548af0db57dSNamjae Jeon 		goto err_out;
549af0db57dSNamjae Jeon 	}
550af0db57dSNamjae Jeon 
551af0db57dSNamjae Jeon 	err = ntfs_sd_add_everyone(ni);
552af0db57dSNamjae Jeon 	if (err)
553af0db57dSNamjae Jeon 		goto err_out;
554af0db57dSNamjae Jeon 	rollback_sd = true;
555af0db57dSNamjae Jeon 
556af0db57dSNamjae Jeon 	if (S_ISDIR(mode)) {
557af0db57dSNamjae Jeon 		struct index_root *ir = NULL;
558af0db57dSNamjae Jeon 		struct index_entry *ie;
559af0db57dSNamjae Jeon 		int ir_len, index_len;
560af0db57dSNamjae Jeon 
561af0db57dSNamjae Jeon 		/* Create struct index_root attribute. */
562af0db57dSNamjae Jeon 		index_len = sizeof(struct index_header) + sizeof(struct index_entry_header);
563af0db57dSNamjae Jeon 		ir_len = offsetof(struct index_root, index) + index_len;
564af0db57dSNamjae Jeon 		ir = kzalloc(ir_len, GFP_NOFS);
565af0db57dSNamjae Jeon 		if (!ir) {
566af0db57dSNamjae Jeon 			err = -ENOMEM;
567af0db57dSNamjae Jeon 			goto err_out;
568af0db57dSNamjae Jeon 		}
569af0db57dSNamjae Jeon 		ir->type = AT_FILE_NAME;
570af0db57dSNamjae Jeon 		ir->collation_rule = COLLATION_FILE_NAME;
571af0db57dSNamjae Jeon 		ir->index_block_size = cpu_to_le32(ni->vol->index_record_size);
572af0db57dSNamjae Jeon 		if (ni->vol->cluster_size <= ni->vol->index_record_size)
573af0db57dSNamjae Jeon 			ir->clusters_per_index_block =
574af0db57dSNamjae Jeon 				NTFS_B_TO_CLU(vol, ni->vol->index_record_size);
575af0db57dSNamjae Jeon 		else
576af0db57dSNamjae Jeon 			ir->clusters_per_index_block =
577af0db57dSNamjae Jeon 				ni->vol->index_record_size >> ni->vol->sector_size_bits;
578af0db57dSNamjae Jeon 		ir->index.entries_offset = cpu_to_le32(sizeof(struct index_header));
579af0db57dSNamjae Jeon 		ir->index.index_length = cpu_to_le32(index_len);
580af0db57dSNamjae Jeon 		ir->index.allocated_size = cpu_to_le32(index_len);
581af0db57dSNamjae Jeon 		ie = (struct index_entry *)((u8 *)ir + sizeof(struct index_root));
582af0db57dSNamjae Jeon 		ie->length = cpu_to_le16(sizeof(struct index_entry_header));
583af0db57dSNamjae Jeon 		ie->key_length = 0;
584af0db57dSNamjae Jeon 		ie->flags = INDEX_ENTRY_END;
585af0db57dSNamjae Jeon 
586af0db57dSNamjae Jeon 		/* Add struct index_root attribute to inode. */
587af0db57dSNamjae Jeon 		err = ntfs_attr_add(ni, AT_INDEX_ROOT, I30, 4, (u8 *)ir, ir_len);
588af0db57dSNamjae Jeon 		if (err) {
589af0db57dSNamjae Jeon 			kfree(ir);
590af0db57dSNamjae Jeon 			ntfs_error(vi->i_sb, "Failed to add struct index_root attribute.\n");
591af0db57dSNamjae Jeon 			goto err_out;
592af0db57dSNamjae Jeon 		}
593af0db57dSNamjae Jeon 		kfree(ir);
594af0db57dSNamjae Jeon 		err = ntfs_attr_open(ni, AT_INDEX_ROOT, I30, 4);
595af0db57dSNamjae Jeon 		if (err)
596af0db57dSNamjae Jeon 			goto err_out;
597af0db57dSNamjae Jeon 	} else {
598af0db57dSNamjae Jeon 		/* Add DATA attribute to inode. */
599af0db57dSNamjae Jeon 		err = ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, NULL, 0);
600af0db57dSNamjae Jeon 		if (err) {
601af0db57dSNamjae Jeon 			ntfs_error(dir_ni->vol->sb, "Failed to add DATA attribute.\n");
602af0db57dSNamjae Jeon 			goto err_out;
603af0db57dSNamjae Jeon 		}
604af0db57dSNamjae Jeon 		rollback_data = true;
605af0db57dSNamjae Jeon 
606af0db57dSNamjae Jeon 		err = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
607af0db57dSNamjae Jeon 		if (err)
608af0db57dSNamjae Jeon 			goto err_out;
609af0db57dSNamjae Jeon 
610af0db57dSNamjae Jeon 		if (S_ISLNK(mode)) {
611af0db57dSNamjae Jeon 			err = ntfs_reparse_set_wsl_symlink(ni, target, target_len);
612af0db57dSNamjae Jeon 			if (!err)
613af0db57dSNamjae Jeon 				rollback_reparse = true;
614af0db57dSNamjae Jeon 		} else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISSOCK(mode) ||
615af0db57dSNamjae Jeon 			   S_ISFIFO(mode)) {
616af0db57dSNamjae Jeon 			si->file_attributes = FILE_ATTRIBUTE_RECALL_ON_OPEN;
617af0db57dSNamjae Jeon 			ni->flags = FILE_ATTRIBUTE_RECALL_ON_OPEN;
618af0db57dSNamjae Jeon 			err = ntfs_reparse_set_wsl_not_symlink(ni, mode);
619af0db57dSNamjae Jeon 			if (!err)
620af0db57dSNamjae Jeon 				rollback_reparse = true;
621af0db57dSNamjae Jeon 		}
622af0db57dSNamjae Jeon 		if (err)
623af0db57dSNamjae Jeon 			goto err_out;
624af0db57dSNamjae Jeon 	}
625af0db57dSNamjae Jeon 
626af0db57dSNamjae Jeon 	err = ntfs_ea_set_wsl_inode(vi, dev, &ea_size,
627af0db57dSNamjae Jeon 			NTFS_EA_UID | NTFS_EA_GID | NTFS_EA_MODE);
628af0db57dSNamjae Jeon 	if (err)
629af0db57dSNamjae Jeon 		goto err_out;
630af0db57dSNamjae Jeon 
631af0db57dSNamjae Jeon 	/* Create FILE_NAME attribute. */
632af0db57dSNamjae Jeon 	fn_len = sizeof(struct file_name_attr) + name_len * sizeof(__le16);
633af0db57dSNamjae Jeon 	fn = kzalloc(fn_len, GFP_NOFS);
634af0db57dSNamjae Jeon 	if (!fn) {
635af0db57dSNamjae Jeon 		err = -ENOMEM;
636af0db57dSNamjae Jeon 		goto err_out;
637af0db57dSNamjae Jeon 	}
638af0db57dSNamjae Jeon 
639af0db57dSNamjae Jeon 	fn->file_attributes |= ni->flags;
640af0db57dSNamjae Jeon 	fn->parent_directory = parent_mft_ref;
641af0db57dSNamjae Jeon 	fn->file_name_length = name_len;
642af0db57dSNamjae Jeon 	fn->file_name_type = FILE_NAME_POSIX;
643af0db57dSNamjae Jeon 	fn->type.ea.packed_ea_size = ea_size;
644af0db57dSNamjae Jeon 	if (S_ISDIR(mode)) {
645af0db57dSNamjae Jeon 		fn->file_attributes = FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT;
646af0db57dSNamjae Jeon 		fn->allocated_size = fn->data_size = 0;
647af0db57dSNamjae Jeon 	} else {
648af0db57dSNamjae Jeon 		fn->data_size = cpu_to_le64(ni->data_size);
649af0db57dSNamjae Jeon 		fn->allocated_size = cpu_to_le64(ni->allocated_size);
650af0db57dSNamjae Jeon 	}
651af0db57dSNamjae Jeon 	if (!S_ISREG(mode) && !S_ISDIR(mode)) {
652af0db57dSNamjae Jeon 		fn->file_attributes = FILE_ATTR_SYSTEM;
653af0db57dSNamjae Jeon 		if (rollback_reparse)
654af0db57dSNamjae Jeon 			fn->file_attributes |= FILE_ATTR_REPARSE_POINT;
655af0db57dSNamjae Jeon 	}
656af0db57dSNamjae Jeon 	if (NVolHideDotFiles(vol) && name_len > 0 && name[0] == cpu_to_le16('.'))
657af0db57dSNamjae Jeon 		fn->file_attributes |= FILE_ATTR_HIDDEN;
658af0db57dSNamjae Jeon 	fn->creation_time = fn->last_data_change_time = utc2ntfs(ni->i_crtime);
659af0db57dSNamjae Jeon 	fn->last_mft_change_time = fn->last_access_time = fn->creation_time;
660af0db57dSNamjae Jeon 	memcpy(fn->file_name, name, name_len * sizeof(__le16));
661af0db57dSNamjae Jeon 
662af0db57dSNamjae Jeon 	/* Add FILE_NAME attribute to inode. */
663af0db57dSNamjae Jeon 	err = ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8 *)fn, fn_len);
664af0db57dSNamjae Jeon 	if (err) {
665af0db57dSNamjae Jeon 		ntfs_error(sb, "Failed to add FILE_NAME attribute.\n");
666af0db57dSNamjae Jeon 		goto err_out;
667af0db57dSNamjae Jeon 	}
668af0db57dSNamjae Jeon 
669af0db57dSNamjae Jeon 	child_mft_ref = MK_MREF(ni->mft_no,
670af0db57dSNamjae Jeon 				le16_to_cpu(ni_mrec->sequence_number));
671af0db57dSNamjae Jeon 	/* Set hard links count and directory flag. */
672af0db57dSNamjae Jeon 	ni_mrec->link_count = cpu_to_le16(1);
673af0db57dSNamjae Jeon 	mark_mft_record_dirty(ni);
674af0db57dSNamjae Jeon 
675af0db57dSNamjae Jeon 	/* Add FILE_NAME attribute to index. */
676af0db57dSNamjae Jeon 	err = ntfs_index_add_filename(dir_ni, fn, child_mft_ref);
677af0db57dSNamjae Jeon 	if (err) {
678af0db57dSNamjae Jeon 		ntfs_debug("Failed to add entry to the index");
679af0db57dSNamjae Jeon 		goto err_out;
680af0db57dSNamjae Jeon 	}
681af0db57dSNamjae Jeon 
682af0db57dSNamjae Jeon 	unmap_mft_record(ni);
683af0db57dSNamjae Jeon 	mutex_unlock(&dir_ni->mrec_lock);
684af0db57dSNamjae Jeon 	mutex_unlock(&ni->mrec_lock);
685af0db57dSNamjae Jeon 
686af0db57dSNamjae Jeon 	ni->flags = fn->file_attributes;
687af0db57dSNamjae Jeon 	/* Set the sequence number. */
688af0db57dSNamjae Jeon 	vi->i_generation = ni->seq_no;
689af0db57dSNamjae Jeon 	set_nlink(vi, 1);
690af0db57dSNamjae Jeon 	ntfs_set_vfs_operations(vi, mode, dev);
691af0db57dSNamjae Jeon 
692af0db57dSNamjae Jeon 	/* Done! */
693af0db57dSNamjae Jeon 	kfree(fn);
694af0db57dSNamjae Jeon 	kfree(si);
695af0db57dSNamjae Jeon 	ntfs_debug("Done.\n");
696af0db57dSNamjae Jeon 	return ni;
697af0db57dSNamjae Jeon 
698af0db57dSNamjae Jeon err_out:
699af0db57dSNamjae Jeon 	if (rollback_sd)
700af0db57dSNamjae Jeon 		ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
701af0db57dSNamjae Jeon 
702af0db57dSNamjae Jeon 	if (rollback_data)
703af0db57dSNamjae Jeon 		ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
704af0db57dSNamjae Jeon 
705af0db57dSNamjae Jeon 	if (rollback_reparse)
706af0db57dSNamjae Jeon 		ntfs_delete_reparse_index(ni);
707af0db57dSNamjae Jeon 	/*
708af0db57dSNamjae Jeon 	 * Free extent MFT records (should not exist any with current
709af0db57dSNamjae Jeon 	 * ntfs_create implementation, but for any case if something will be
710af0db57dSNamjae Jeon 	 * changed in the future).
711af0db57dSNamjae Jeon 	 */
712af0db57dSNamjae Jeon 	while (ni->nr_extents != 0) {
713af0db57dSNamjae Jeon 		int err2;
714af0db57dSNamjae Jeon 
715af0db57dSNamjae Jeon 		err2 = ntfs_mft_record_free(ni->vol, *(ni->ext.extent_ntfs_inos));
716af0db57dSNamjae Jeon 		if (err2)
717af0db57dSNamjae Jeon 			ntfs_error(sb,
718af0db57dSNamjae Jeon 				"Failed to free extent MFT record. Leaving inconsistent metadata.\n");
719af0db57dSNamjae Jeon 		ntfs_inode_close(*(ni->ext.extent_ntfs_inos));
720af0db57dSNamjae Jeon 	}
721af0db57dSNamjae Jeon 	if (ntfs_mft_record_free(ni->vol, ni))
722af0db57dSNamjae Jeon 		ntfs_error(sb,
723af0db57dSNamjae Jeon 			"Failed to free MFT record. Leaving inconsistent metadata. Run chkdsk.\n");
724af0db57dSNamjae Jeon 	unmap_mft_record(ni);
725af0db57dSNamjae Jeon 	kfree(fn);
726af0db57dSNamjae Jeon 	kfree(si);
727af0db57dSNamjae Jeon 
728af0db57dSNamjae Jeon 	mutex_unlock(&dir_ni->mrec_lock);
729af0db57dSNamjae Jeon 	mutex_unlock(&ni->mrec_lock);
730af0db57dSNamjae Jeon 
731af0db57dSNamjae Jeon 	remove_inode_hash(vi);
732af0db57dSNamjae Jeon 	discard_new_inode(vi);
733af0db57dSNamjae Jeon 	return ERR_PTR(err);
734af0db57dSNamjae Jeon }
735af0db57dSNamjae Jeon 
736af0db57dSNamjae Jeon static int ntfs_create(struct mnt_idmap *idmap, struct inode *dir,
737af0db57dSNamjae Jeon 		struct dentry *dentry, umode_t mode, bool excl)
738af0db57dSNamjae Jeon {
739af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(dir->i_sb);
740af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
741af0db57dSNamjae Jeon 	__le16 *uname;
742af0db57dSNamjae Jeon 	int uname_len, err;
743af0db57dSNamjae Jeon 
744af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
745af0db57dSNamjae Jeon 		return -EIO;
746af0db57dSNamjae Jeon 
747af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name, dentry->d_name.len,
748af0db57dSNamjae Jeon 				  &uname, NTFS_MAX_NAME_LEN);
749af0db57dSNamjae Jeon 	if (uname_len < 0) {
750af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
751af0db57dSNamjae Jeon 			ntfs_error(vol->sb, "Failed to convert name to unicode.");
752af0db57dSNamjae Jeon 		return uname_len;
753af0db57dSNamjae Jeon 	}
754af0db57dSNamjae Jeon 
755af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname, uname_len);
756af0db57dSNamjae Jeon 	if (err) {
757af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname);
758af0db57dSNamjae Jeon 		return err;
759af0db57dSNamjae Jeon 	}
760af0db57dSNamjae Jeon 
761af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
762af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
763af0db57dSNamjae Jeon 
764af0db57dSNamjae Jeon 	ni = __ntfs_create(idmap, dir, uname, uname_len, S_IFREG | mode, 0, NULL, 0);
765af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
766af0db57dSNamjae Jeon 	if (IS_ERR(ni))
767af0db57dSNamjae Jeon 		return PTR_ERR(ni);
768af0db57dSNamjae Jeon 
769af0db57dSNamjae Jeon 	d_instantiate_new(dentry, VFS_I(ni));
770af0db57dSNamjae Jeon 
771af0db57dSNamjae Jeon 	return 0;
772af0db57dSNamjae Jeon }
773af0db57dSNamjae Jeon 
774af0db57dSNamjae Jeon static int ntfs_check_unlinkable_dir(struct ntfs_attr_search_ctx *ctx, struct file_name_attr *fn)
775af0db57dSNamjae Jeon {
776af0db57dSNamjae Jeon 	int link_count;
777af0db57dSNamjae Jeon 	int ret;
778af0db57dSNamjae Jeon 	struct ntfs_inode *ni = ctx->base_ntfs_ino ? ctx->base_ntfs_ino : ctx->ntfs_ino;
779af0db57dSNamjae Jeon 	struct mft_record *ni_mrec = ctx->base_mrec ? ctx->base_mrec : ctx->mrec;
780af0db57dSNamjae Jeon 
781af0db57dSNamjae Jeon 	ret = ntfs_check_empty_dir(ni, ni_mrec);
782af0db57dSNamjae Jeon 	if (!ret || ret != -ENOTEMPTY)
783af0db57dSNamjae Jeon 		return ret;
784af0db57dSNamjae Jeon 
785af0db57dSNamjae Jeon 	link_count = le16_to_cpu(ni_mrec->link_count);
786af0db57dSNamjae Jeon 	/*
787af0db57dSNamjae Jeon 	 * Directory is non-empty, so we can unlink only if there is more than
788af0db57dSNamjae Jeon 	 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
789af0db57dSNamjae Jeon 	 */
790af0db57dSNamjae Jeon 	if ((link_count == 1) ||
791af0db57dSNamjae Jeon 	    (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
792af0db57dSNamjae Jeon 		ret = -ENOTEMPTY;
793af0db57dSNamjae Jeon 		ntfs_debug("Non-empty directory without hard links\n");
794af0db57dSNamjae Jeon 		goto no_hardlink;
795af0db57dSNamjae Jeon 	}
796af0db57dSNamjae Jeon 
797af0db57dSNamjae Jeon 	ret = 0;
798af0db57dSNamjae Jeon no_hardlink:
799af0db57dSNamjae Jeon 	return ret;
800af0db57dSNamjae Jeon }
801af0db57dSNamjae Jeon 
802af0db57dSNamjae Jeon static int ntfs_test_inode_attr(struct inode *vi, void *data)
803af0db57dSNamjae Jeon {
804af0db57dSNamjae Jeon 	struct ntfs_inode *ni = NTFS_I(vi);
805*d7bf74c9SHyunchul Lee 	u64 mft_no = (u64)(uintptr_t)data;
806af0db57dSNamjae Jeon 
807af0db57dSNamjae Jeon 	if (ni->mft_no != mft_no)
808af0db57dSNamjae Jeon 		return 0;
809af0db57dSNamjae Jeon 	if (NInoAttr(ni) || ni->nr_extents == -1)
810af0db57dSNamjae Jeon 		return 1;
811af0db57dSNamjae Jeon 	else
812af0db57dSNamjae Jeon 		return 0;
813af0db57dSNamjae Jeon }
814af0db57dSNamjae Jeon 
815af0db57dSNamjae Jeon /*
816af0db57dSNamjae Jeon  * ntfs_delete - delete file or directory from ntfs volume
817af0db57dSNamjae Jeon  * @ni:         ntfs inode for object to delte
818af0db57dSNamjae Jeon  * @dir_ni:     ntfs inode for directory in which delete object
819af0db57dSNamjae Jeon  * @name:       unicode name of the object to delete
820af0db57dSNamjae Jeon  * @name_len:   length of the name in unicode characters
821af0db57dSNamjae Jeon  * @need_lock:  whether mrec lock is needed or not
822af0db57dSNamjae Jeon  *
823af0db57dSNamjae Jeon  * Delete the specified name from the directory index @dir_ni and decrement
824af0db57dSNamjae Jeon  * the link count of the target inode @ni.
825af0db57dSNamjae Jeon  *
826af0db57dSNamjae Jeon  * Return 0 on success and -errno on error.
827af0db57dSNamjae Jeon  */
828af0db57dSNamjae Jeon static int ntfs_delete(struct ntfs_inode *ni, struct ntfs_inode *dir_ni,
829af0db57dSNamjae Jeon 		__le16 *name, u8 name_len, bool need_lock)
830af0db57dSNamjae Jeon {
831af0db57dSNamjae Jeon 	struct ntfs_attr_search_ctx *actx = NULL;
832af0db57dSNamjae Jeon 	struct file_name_attr *fn = NULL;
833af0db57dSNamjae Jeon 	bool looking_for_dos_name = false, looking_for_win32_name = false;
834af0db57dSNamjae Jeon 	bool case_sensitive_match = true;
835af0db57dSNamjae Jeon 	int err = 0;
836af0db57dSNamjae Jeon 	struct mft_record *ni_mrec;
837af0db57dSNamjae Jeon 	struct super_block *sb;
838af0db57dSNamjae Jeon 	bool link_count_zero = false;
839af0db57dSNamjae Jeon 
840af0db57dSNamjae Jeon 	ntfs_debug("Entering.\n");
841af0db57dSNamjae Jeon 
842af0db57dSNamjae Jeon 	if (need_lock == true) {
843af0db57dSNamjae Jeon 		mutex_lock_nested(&ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL);
844af0db57dSNamjae Jeon 		mutex_lock_nested(&dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT);
845af0db57dSNamjae Jeon 	}
846af0db57dSNamjae Jeon 
847af0db57dSNamjae Jeon 	sb = dir_ni->vol->sb;
848af0db57dSNamjae Jeon 
849af0db57dSNamjae Jeon 	if (ni->nr_extents == -1)
850af0db57dSNamjae Jeon 		ni = ni->ext.base_ntfs_ino;
851af0db57dSNamjae Jeon 	if (dir_ni->nr_extents == -1)
852af0db57dSNamjae Jeon 		dir_ni = dir_ni->ext.base_ntfs_ino;
853af0db57dSNamjae Jeon 	/*
854af0db57dSNamjae Jeon 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
855af0db57dSNamjae Jeon 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
856af0db57dSNamjae Jeon 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
857af0db57dSNamjae Jeon 	 * only then remove WIN32 name.
858af0db57dSNamjae Jeon 	 */
859af0db57dSNamjae Jeon 	actx = ntfs_attr_get_search_ctx(ni, NULL);
860af0db57dSNamjae Jeon 	if (!actx) {
861af0db57dSNamjae Jeon 		ntfs_error(sb, "%s, Failed to get search context", __func__);
862af0db57dSNamjae Jeon 		if (need_lock) {
863af0db57dSNamjae Jeon 			mutex_unlock(&dir_ni->mrec_lock);
864af0db57dSNamjae Jeon 			mutex_unlock(&ni->mrec_lock);
865af0db57dSNamjae Jeon 		}
866af0db57dSNamjae Jeon 		return -ENOMEM;
867af0db57dSNamjae Jeon 	}
868af0db57dSNamjae Jeon search:
869af0db57dSNamjae Jeon 	while ((err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
870af0db57dSNamjae Jeon 				0, NULL, 0, actx)) == 0) {
871af0db57dSNamjae Jeon #ifdef DEBUG
872af0db57dSNamjae Jeon 		unsigned char *s;
873af0db57dSNamjae Jeon #endif
874af0db57dSNamjae Jeon 		bool case_sensitive = IGNORE_CASE;
875af0db57dSNamjae Jeon 
876af0db57dSNamjae Jeon 		fn = (struct file_name_attr *)((u8 *)actx->attr +
877af0db57dSNamjae Jeon 				le16_to_cpu(actx->attr->data.resident.value_offset));
878af0db57dSNamjae Jeon #ifdef DEBUG
879af0db57dSNamjae Jeon 		s = ntfs_attr_name_get(ni->vol, fn->file_name, fn->file_name_length);
880af0db57dSNamjae Jeon 		ntfs_debug("name: '%s'  type: %d  dos: %d  win32: %d case: %d\n",
881af0db57dSNamjae Jeon 				s, fn->file_name_type,
882af0db57dSNamjae Jeon 				looking_for_dos_name, looking_for_win32_name,
883af0db57dSNamjae Jeon 				case_sensitive_match);
884af0db57dSNamjae Jeon 		ntfs_attr_name_free(&s);
885af0db57dSNamjae Jeon #endif
886af0db57dSNamjae Jeon 		if (looking_for_dos_name) {
887af0db57dSNamjae Jeon 			if (fn->file_name_type == FILE_NAME_DOS)
888af0db57dSNamjae Jeon 				break;
889af0db57dSNamjae Jeon 			continue;
890af0db57dSNamjae Jeon 		}
891af0db57dSNamjae Jeon 		if (looking_for_win32_name) {
892af0db57dSNamjae Jeon 			if  (fn->file_name_type == FILE_NAME_WIN32)
893af0db57dSNamjae Jeon 				break;
894af0db57dSNamjae Jeon 			continue;
895af0db57dSNamjae Jeon 		}
896af0db57dSNamjae Jeon 
897af0db57dSNamjae Jeon 		/* Ignore hard links from other directories */
898af0db57dSNamjae Jeon 		if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
899d9038d99SNamjae Jeon 			ntfs_debug("MFT record numbers don't match (%llu != %lu)\n",
900af0db57dSNamjae Jeon 					dir_ni->mft_no,
901af0db57dSNamjae Jeon 					MREF_LE(fn->parent_directory));
902af0db57dSNamjae Jeon 			continue;
903af0db57dSNamjae Jeon 		}
904af0db57dSNamjae Jeon 
905af0db57dSNamjae Jeon 		if (fn->file_name_type == FILE_NAME_POSIX || case_sensitive_match)
906af0db57dSNamjae Jeon 			case_sensitive = CASE_SENSITIVE;
907af0db57dSNamjae Jeon 
908af0db57dSNamjae Jeon 		if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
909af0db57dSNamjae Jeon 					name, name_len, case_sensitive,
910af0db57dSNamjae Jeon 					ni->vol->upcase, ni->vol->upcase_len)) {
911af0db57dSNamjae Jeon 			if (fn->file_name_type == FILE_NAME_WIN32) {
912af0db57dSNamjae Jeon 				looking_for_dos_name = true;
913af0db57dSNamjae Jeon 				ntfs_attr_reinit_search_ctx(actx);
914af0db57dSNamjae Jeon 				continue;
915af0db57dSNamjae Jeon 			}
916af0db57dSNamjae Jeon 			if (fn->file_name_type == FILE_NAME_DOS)
917af0db57dSNamjae Jeon 				looking_for_dos_name = true;
918af0db57dSNamjae Jeon 			break;
919af0db57dSNamjae Jeon 		}
920af0db57dSNamjae Jeon 	}
921af0db57dSNamjae Jeon 	if (err) {
922af0db57dSNamjae Jeon 		/*
923af0db57dSNamjae Jeon 		 * If case sensitive search failed, then try once again
924af0db57dSNamjae Jeon 		 * ignoring case.
925af0db57dSNamjae Jeon 		 */
926af0db57dSNamjae Jeon 		if (err == -ENOENT && case_sensitive_match) {
927af0db57dSNamjae Jeon 			case_sensitive_match = false;
928af0db57dSNamjae Jeon 			ntfs_attr_reinit_search_ctx(actx);
929af0db57dSNamjae Jeon 			goto search;
930af0db57dSNamjae Jeon 		}
931af0db57dSNamjae Jeon 		goto err_out;
932af0db57dSNamjae Jeon 	}
933af0db57dSNamjae Jeon 
934af0db57dSNamjae Jeon 	err = ntfs_check_unlinkable_dir(actx, fn);
935af0db57dSNamjae Jeon 	if (err)
936af0db57dSNamjae Jeon 		goto err_out;
937af0db57dSNamjae Jeon 
938af0db57dSNamjae Jeon 	err = ntfs_index_remove(dir_ni, fn, le32_to_cpu(actx->attr->data.resident.value_length));
939af0db57dSNamjae Jeon 	if (err)
940af0db57dSNamjae Jeon 		goto err_out;
941af0db57dSNamjae Jeon 
942af0db57dSNamjae Jeon 	err = ntfs_attr_record_rm(actx);
943af0db57dSNamjae Jeon 	if (err)
944af0db57dSNamjae Jeon 		goto err_out;
945af0db57dSNamjae Jeon 
946af0db57dSNamjae Jeon 	ni_mrec = actx->base_mrec ? actx->base_mrec : actx->mrec;
947af0db57dSNamjae Jeon 	ni_mrec->link_count = cpu_to_le16(le16_to_cpu(ni_mrec->link_count) - 1);
948af0db57dSNamjae Jeon 	drop_nlink(VFS_I(ni));
949af0db57dSNamjae Jeon 
950af0db57dSNamjae Jeon 	mark_mft_record_dirty(ni);
951af0db57dSNamjae Jeon 	if (looking_for_dos_name) {
952af0db57dSNamjae Jeon 		looking_for_dos_name = false;
953af0db57dSNamjae Jeon 		looking_for_win32_name = true;
954af0db57dSNamjae Jeon 		ntfs_attr_reinit_search_ctx(actx);
955af0db57dSNamjae Jeon 		goto search;
956af0db57dSNamjae Jeon 	}
957af0db57dSNamjae Jeon 
958af0db57dSNamjae Jeon 	/*
959af0db57dSNamjae Jeon 	 * If hard link count is not equal to zero then we are done. In other
960af0db57dSNamjae Jeon 	 * case there are no reference to this inode left, so we should free all
961af0db57dSNamjae Jeon 	 * non-resident attributes and mark all MFT record as not in use.
962af0db57dSNamjae Jeon 	 */
963af0db57dSNamjae Jeon 	if (ni_mrec->link_count == 0) {
964af0db57dSNamjae Jeon 		NInoSetBeingDeleted(ni);
965af0db57dSNamjae Jeon 		ntfs_delete_reparse_index(ni);
966af0db57dSNamjae Jeon 		ntfs_delete_object_id_index(ni);
967af0db57dSNamjae Jeon 		link_count_zero = true;
968af0db57dSNamjae Jeon 	}
969af0db57dSNamjae Jeon 
970af0db57dSNamjae Jeon 	ntfs_attr_put_search_ctx(actx);
971af0db57dSNamjae Jeon 	if (need_lock == true) {
972af0db57dSNamjae Jeon 		mutex_unlock(&dir_ni->mrec_lock);
973af0db57dSNamjae Jeon 		mutex_unlock(&ni->mrec_lock);
974af0db57dSNamjae Jeon 	}
975af0db57dSNamjae Jeon 
976af0db57dSNamjae Jeon 	/*
977af0db57dSNamjae Jeon 	 * If hard link count is not equal to zero then we are done. In other
978af0db57dSNamjae Jeon 	 * case there are no reference to this inode left, so we should free all
979af0db57dSNamjae Jeon 	 * non-resident attributes and mark all MFT record as not in use.
980af0db57dSNamjae Jeon 	 */
981af0db57dSNamjae Jeon 	if (link_count_zero == true) {
982af0db57dSNamjae Jeon 		struct inode *attr_vi;
983af0db57dSNamjae Jeon 
984af0db57dSNamjae Jeon 		while ((attr_vi = ilookup5(sb, ni->mft_no, ntfs_test_inode_attr,
985*d7bf74c9SHyunchul Lee 					   (void *)(uintptr_t)ni->mft_no)) != NULL) {
986af0db57dSNamjae Jeon 			clear_nlink(attr_vi);
987af0db57dSNamjae Jeon 			iput(attr_vi);
988af0db57dSNamjae Jeon 		}
989af0db57dSNamjae Jeon 	}
990af0db57dSNamjae Jeon 	ntfs_debug("Done.\n");
991af0db57dSNamjae Jeon 	return 0;
992af0db57dSNamjae Jeon err_out:
993af0db57dSNamjae Jeon 	ntfs_attr_put_search_ctx(actx);
994af0db57dSNamjae Jeon 	if (need_lock) {
995af0db57dSNamjae Jeon 		mutex_unlock(&dir_ni->mrec_lock);
996af0db57dSNamjae Jeon 		mutex_unlock(&ni->mrec_lock);
997af0db57dSNamjae Jeon 	}
998af0db57dSNamjae Jeon 	return err;
999af0db57dSNamjae Jeon }
1000af0db57dSNamjae Jeon 
1001af0db57dSNamjae Jeon static int ntfs_unlink(struct inode *dir, struct dentry *dentry)
1002af0db57dSNamjae Jeon {
1003af0db57dSNamjae Jeon 	struct inode *vi = dentry->d_inode;
1004af0db57dSNamjae Jeon 	struct super_block *sb = dir->i_sb;
1005af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1006af0db57dSNamjae Jeon 	int err = 0;
1007af0db57dSNamjae Jeon 	struct ntfs_inode *ni = NTFS_I(vi);
1008af0db57dSNamjae Jeon 	__le16 *uname = NULL;
1009af0db57dSNamjae Jeon 	int uname_len;
1010af0db57dSNamjae Jeon 
1011af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1012af0db57dSNamjae Jeon 		return -EIO;
1013af0db57dSNamjae Jeon 
1014af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name, dentry->d_name.len,
1015af0db57dSNamjae Jeon 				  &uname, NTFS_MAX_NAME_LEN);
1016af0db57dSNamjae Jeon 	if (uname_len < 0) {
1017af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
1018af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to Unicode.");
1019af0db57dSNamjae Jeon 		return -ENOMEM;
1020af0db57dSNamjae Jeon 	}
1021af0db57dSNamjae Jeon 
1022af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname, uname_len);
1023af0db57dSNamjae Jeon 	if (err) {
1024af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname);
1025af0db57dSNamjae Jeon 		return err;
1026af0db57dSNamjae Jeon 	}
1027af0db57dSNamjae Jeon 
1028af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1029af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1030af0db57dSNamjae Jeon 
1031af0db57dSNamjae Jeon 	err = ntfs_delete(ni, NTFS_I(dir), uname, uname_len, true);
1032af0db57dSNamjae Jeon 	if (err)
1033af0db57dSNamjae Jeon 		goto out;
1034af0db57dSNamjae Jeon 
1035af0db57dSNamjae Jeon 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
1036af0db57dSNamjae Jeon 	mark_inode_dirty(dir);
1037af0db57dSNamjae Jeon 	inode_set_ctime_to_ts(vi, inode_get_ctime(dir));
1038af0db57dSNamjae Jeon 	if (vi->i_nlink)
1039af0db57dSNamjae Jeon 		mark_inode_dirty(vi);
1040af0db57dSNamjae Jeon out:
1041af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
1042af0db57dSNamjae Jeon 	return err;
1043af0db57dSNamjae Jeon }
1044af0db57dSNamjae Jeon 
1045af0db57dSNamjae Jeon static struct dentry *ntfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
1046af0db57dSNamjae Jeon 		struct dentry *dentry, umode_t mode)
1047af0db57dSNamjae Jeon {
1048af0db57dSNamjae Jeon 	struct super_block *sb = dir->i_sb;
1049af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1050af0db57dSNamjae Jeon 	int err = 0;
1051af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
1052af0db57dSNamjae Jeon 	__le16 *uname;
1053af0db57dSNamjae Jeon 	int uname_len;
1054af0db57dSNamjae Jeon 
1055af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1056af0db57dSNamjae Jeon 		return ERR_PTR(-EIO);
1057af0db57dSNamjae Jeon 
1058af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name, dentry->d_name.len,
1059af0db57dSNamjae Jeon 				  &uname, NTFS_MAX_NAME_LEN);
1060af0db57dSNamjae Jeon 	if (uname_len < 0) {
1061af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
1062af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to unicode.");
1063af0db57dSNamjae Jeon 		return ERR_PTR(-ENOMEM);
1064af0db57dSNamjae Jeon 	}
1065af0db57dSNamjae Jeon 
1066af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname, uname_len);
1067af0db57dSNamjae Jeon 	if (err) {
1068af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname);
1069af0db57dSNamjae Jeon 		return ERR_PTR(err);
1070af0db57dSNamjae Jeon 	}
1071af0db57dSNamjae Jeon 
1072af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1073af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1074af0db57dSNamjae Jeon 
1075af0db57dSNamjae Jeon 	ni = __ntfs_create(idmap, dir, uname, uname_len, S_IFDIR | mode, 0, NULL, 0);
1076af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
1077af0db57dSNamjae Jeon 	if (IS_ERR(ni)) {
1078af0db57dSNamjae Jeon 		err = PTR_ERR(ni);
1079af0db57dSNamjae Jeon 		return ERR_PTR(err);
1080af0db57dSNamjae Jeon 	}
1081af0db57dSNamjae Jeon 
1082af0db57dSNamjae Jeon 	d_instantiate_new(dentry, VFS_I(ni));
1083ec8676c8SEthan Tidmore 	return NULL;
1084af0db57dSNamjae Jeon }
1085af0db57dSNamjae Jeon 
1086af0db57dSNamjae Jeon static int ntfs_rmdir(struct inode *dir, struct dentry *dentry)
1087af0db57dSNamjae Jeon {
1088af0db57dSNamjae Jeon 	struct inode *vi = dentry->d_inode;
1089af0db57dSNamjae Jeon 	struct super_block *sb = dir->i_sb;
1090af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1091af0db57dSNamjae Jeon 	int err = 0;
1092af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
1093af0db57dSNamjae Jeon 	__le16 *uname = NULL;
1094af0db57dSNamjae Jeon 	int uname_len;
1095af0db57dSNamjae Jeon 
1096af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1097af0db57dSNamjae Jeon 		return -EIO;
1098af0db57dSNamjae Jeon 
1099af0db57dSNamjae Jeon 	ni = NTFS_I(vi);
1100af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name, dentry->d_name.len,
1101af0db57dSNamjae Jeon 				  &uname, NTFS_MAX_NAME_LEN);
1102af0db57dSNamjae Jeon 	if (uname_len < 0) {
1103af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
1104af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to unicode.");
1105af0db57dSNamjae Jeon 		return -ENOMEM;
1106af0db57dSNamjae Jeon 	}
1107af0db57dSNamjae Jeon 
1108af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname, uname_len);
1109af0db57dSNamjae Jeon 	if (err) {
1110af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname);
1111af0db57dSNamjae Jeon 		return err;
1112af0db57dSNamjae Jeon 	}
1113af0db57dSNamjae Jeon 
1114af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1115af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1116af0db57dSNamjae Jeon 
1117af0db57dSNamjae Jeon 	err = ntfs_delete(ni, NTFS_I(dir), uname, uname_len, true);
1118af0db57dSNamjae Jeon 	if (err)
1119af0db57dSNamjae Jeon 		goto out;
1120af0db57dSNamjae Jeon 
1121af0db57dSNamjae Jeon 	inode_set_mtime_to_ts(vi, inode_set_atime_to_ts(vi, current_time(vi)));
1122af0db57dSNamjae Jeon out:
1123af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
1124af0db57dSNamjae Jeon 	return err;
1125af0db57dSNamjae Jeon }
1126af0db57dSNamjae Jeon 
1127af0db57dSNamjae Jeon /*
1128af0db57dSNamjae Jeon  * __ntfs_link - create hard link for file or directory
1129af0db57dSNamjae Jeon  * @ni:		ntfs inode for object to create hard link
1130af0db57dSNamjae Jeon  * @dir_ni:	ntfs inode for directory in which new link should be placed
1131af0db57dSNamjae Jeon  * @name:	unicode name of the new link
1132af0db57dSNamjae Jeon  * @name_len:	length of the name in unicode characters
1133af0db57dSNamjae Jeon  *
1134af0db57dSNamjae Jeon  * Create a new hard link. This involves adding an entry to the directory
1135af0db57dSNamjae Jeon  * index and adding a new FILE_NAME attribute to the target inode.
1136af0db57dSNamjae Jeon  *
1137af0db57dSNamjae Jeon  * Return 0 on success and -errno on error.
1138af0db57dSNamjae Jeon  */
1139af0db57dSNamjae Jeon static int __ntfs_link(struct ntfs_inode *ni, struct ntfs_inode *dir_ni,
1140af0db57dSNamjae Jeon 		__le16 *name, u8 name_len)
1141af0db57dSNamjae Jeon {
1142af0db57dSNamjae Jeon 	struct super_block *sb;
1143af0db57dSNamjae Jeon 	struct inode *vi = VFS_I(ni);
1144af0db57dSNamjae Jeon 	struct file_name_attr *fn = NULL;
1145af0db57dSNamjae Jeon 	int fn_len, err = 0;
1146af0db57dSNamjae Jeon 	struct mft_record *dir_mrec = NULL, *ni_mrec = NULL;
1147af0db57dSNamjae Jeon 
1148af0db57dSNamjae Jeon 	ntfs_debug("Entering.\n");
1149af0db57dSNamjae Jeon 
1150af0db57dSNamjae Jeon 	sb = dir_ni->vol->sb;
1151af0db57dSNamjae Jeon 	if (NInoBeingDeleted(dir_ni) || NInoBeingDeleted(ni))
1152af0db57dSNamjae Jeon 		return -ENOENT;
1153af0db57dSNamjae Jeon 
1154af0db57dSNamjae Jeon 	ni_mrec = map_mft_record(ni);
1155af0db57dSNamjae Jeon 	if (IS_ERR(ni_mrec)) {
1156af0db57dSNamjae Jeon 		err = -EIO;
1157af0db57dSNamjae Jeon 		goto err_out;
1158af0db57dSNamjae Jeon 	}
1159af0db57dSNamjae Jeon 
1160af0db57dSNamjae Jeon 	if (le16_to_cpu(ni_mrec->link_count) == 0) {
1161af0db57dSNamjae Jeon 		err = -ENOENT;
1162af0db57dSNamjae Jeon 		goto err_out;
1163af0db57dSNamjae Jeon 	}
1164af0db57dSNamjae Jeon 
1165af0db57dSNamjae Jeon 	/* Create FILE_NAME attribute. */
1166af0db57dSNamjae Jeon 	fn_len = sizeof(struct file_name_attr) + name_len * sizeof(__le16);
11677c76484fSEthan Tidmore 
1168af0db57dSNamjae Jeon 	fn = kzalloc(fn_len, GFP_NOFS);
1169af0db57dSNamjae Jeon 	if (!fn) {
1170af0db57dSNamjae Jeon 		err = -ENOMEM;
1171af0db57dSNamjae Jeon 		goto err_out;
1172af0db57dSNamjae Jeon 	}
1173af0db57dSNamjae Jeon 
1174af0db57dSNamjae Jeon 	dir_mrec = map_mft_record(dir_ni);
1175af0db57dSNamjae Jeon 	if (IS_ERR(dir_mrec)) {
1176af0db57dSNamjae Jeon 		err = -EIO;
1177af0db57dSNamjae Jeon 		goto err_out;
1178af0db57dSNamjae Jeon 	}
1179af0db57dSNamjae Jeon 
1180af0db57dSNamjae Jeon 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1181af0db57dSNamjae Jeon 			le16_to_cpu(dir_mrec->sequence_number));
1182af0db57dSNamjae Jeon 	unmap_mft_record(dir_ni);
1183af0db57dSNamjae Jeon 	fn->file_name_length = name_len;
1184af0db57dSNamjae Jeon 	fn->file_name_type = FILE_NAME_POSIX;
1185af0db57dSNamjae Jeon 	fn->file_attributes = ni->flags;
1186af0db57dSNamjae Jeon 	if (ni_mrec->flags & MFT_RECORD_IS_DIRECTORY) {
1187af0db57dSNamjae Jeon 		fn->file_attributes |= FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT;
1188af0db57dSNamjae Jeon 		fn->allocated_size = fn->data_size = 0;
1189af0db57dSNamjae Jeon 	} else {
1190af0db57dSNamjae Jeon 		if (NInoSparse(ni) || NInoCompressed(ni))
1191af0db57dSNamjae Jeon 			fn->allocated_size =
1192af0db57dSNamjae Jeon 				cpu_to_le64(ni->itype.compressed.size);
1193af0db57dSNamjae Jeon 		else
1194af0db57dSNamjae Jeon 			fn->allocated_size = cpu_to_le64(ni->allocated_size);
1195af0db57dSNamjae Jeon 		fn->data_size = cpu_to_le64(ni->data_size);
1196af0db57dSNamjae Jeon 	}
1197af0db57dSNamjae Jeon 	if (NVolHideDotFiles(dir_ni->vol) && name_len > 0 && name[0] == cpu_to_le16('.'))
1198af0db57dSNamjae Jeon 		fn->file_attributes |= FILE_ATTR_HIDDEN;
1199af0db57dSNamjae Jeon 
1200af0db57dSNamjae Jeon 	fn->creation_time = utc2ntfs(ni->i_crtime);
1201af0db57dSNamjae Jeon 	fn->last_data_change_time = utc2ntfs(inode_get_mtime(vi));
1202af0db57dSNamjae Jeon 	fn->last_mft_change_time = utc2ntfs(inode_get_ctime(vi));
1203af0db57dSNamjae Jeon 	fn->last_access_time = utc2ntfs(inode_get_atime(vi));
1204af0db57dSNamjae Jeon 	memcpy(fn->file_name, name, name_len * sizeof(__le16));
1205af0db57dSNamjae Jeon 
1206af0db57dSNamjae Jeon 	/* Add FILE_NAME attribute to index. */
1207af0db57dSNamjae Jeon 	err = ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1208af0db57dSNamjae Jeon 					le16_to_cpu(ni_mrec->sequence_number)));
1209af0db57dSNamjae Jeon 	if (err) {
1210af0db57dSNamjae Jeon 		ntfs_error(sb, "Failed to add filename to the index");
1211af0db57dSNamjae Jeon 		goto err_out;
1212af0db57dSNamjae Jeon 	}
1213af0db57dSNamjae Jeon 	/* Add FILE_NAME attribute to inode. */
1214af0db57dSNamjae Jeon 	err = ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8 *)fn, fn_len);
1215af0db57dSNamjae Jeon 	if (err) {
1216af0db57dSNamjae Jeon 		ntfs_error(sb, "Failed to add FILE_NAME attribute.\n");
1217af0db57dSNamjae Jeon 		/* Try to remove just added attribute from index. */
1218af0db57dSNamjae Jeon 		if (ntfs_index_remove(dir_ni, fn, fn_len))
1219af0db57dSNamjae Jeon 			goto rollback_failed;
1220af0db57dSNamjae Jeon 		goto err_out;
1221af0db57dSNamjae Jeon 	}
1222af0db57dSNamjae Jeon 	/* Increment hard links count. */
1223af0db57dSNamjae Jeon 	ni_mrec->link_count = cpu_to_le16(le16_to_cpu(ni_mrec->link_count) + 1);
1224af0db57dSNamjae Jeon 	inc_nlink(VFS_I(ni));
1225af0db57dSNamjae Jeon 
1226af0db57dSNamjae Jeon 	/* Done! */
1227af0db57dSNamjae Jeon 	mark_mft_record_dirty(ni);
1228af0db57dSNamjae Jeon 	kfree(fn);
1229af0db57dSNamjae Jeon 	unmap_mft_record(ni);
1230af0db57dSNamjae Jeon 
1231af0db57dSNamjae Jeon 	ntfs_debug("Done.\n");
1232af0db57dSNamjae Jeon 
1233af0db57dSNamjae Jeon 	return 0;
1234af0db57dSNamjae Jeon rollback_failed:
1235af0db57dSNamjae Jeon 	ntfs_error(sb, "Rollback failed. Leaving inconsistent metadata.\n");
1236af0db57dSNamjae Jeon err_out:
1237af0db57dSNamjae Jeon 	kfree(fn);
1238af0db57dSNamjae Jeon 	if (!IS_ERR_OR_NULL(ni_mrec))
1239af0db57dSNamjae Jeon 		unmap_mft_record(ni);
1240af0db57dSNamjae Jeon 	return err;
1241af0db57dSNamjae Jeon }
1242af0db57dSNamjae Jeon 
1243af0db57dSNamjae Jeon static int ntfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
1244af0db57dSNamjae Jeon 		struct dentry *old_dentry, struct inode *new_dir,
1245af0db57dSNamjae Jeon 		struct dentry *new_dentry, unsigned int flags)
1246af0db57dSNamjae Jeon {
1247af0db57dSNamjae Jeon 	struct inode *old_inode, *new_inode = NULL;
1248af0db57dSNamjae Jeon 	int err = 0;
1249af0db57dSNamjae Jeon 	int is_dir;
1250af0db57dSNamjae Jeon 	struct super_block *sb = old_dir->i_sb;
1251af0db57dSNamjae Jeon 	__le16 *uname_new = NULL;
1252af0db57dSNamjae Jeon 	__le16 *uname_old = NULL;
1253af0db57dSNamjae Jeon 	int new_name_len;
1254af0db57dSNamjae Jeon 	int old_name_len;
1255af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1256af0db57dSNamjae Jeon 	struct ntfs_inode *old_ni, *new_ni = NULL;
1257af0db57dSNamjae Jeon 	struct ntfs_inode *old_dir_ni = NTFS_I(old_dir), *new_dir_ni = NTFS_I(new_dir);
1258af0db57dSNamjae Jeon 
1259af0db57dSNamjae Jeon 	if (NVolShutdown(old_dir_ni->vol))
1260af0db57dSNamjae Jeon 		return -EIO;
1261af0db57dSNamjae Jeon 
1262af0db57dSNamjae Jeon 	if (flags & (RENAME_EXCHANGE | RENAME_WHITEOUT))
1263af0db57dSNamjae Jeon 		return -EINVAL;
1264af0db57dSNamjae Jeon 
1265af0db57dSNamjae Jeon 	new_name_len = ntfs_nlstoucs(NTFS_I(new_dir)->vol, new_dentry->d_name.name,
1266af0db57dSNamjae Jeon 				     new_dentry->d_name.len, &uname_new,
1267af0db57dSNamjae Jeon 				     NTFS_MAX_NAME_LEN);
1268af0db57dSNamjae Jeon 	if (new_name_len < 0) {
1269af0db57dSNamjae Jeon 		if (new_name_len != -ENAMETOOLONG)
1270af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to unicode.");
1271af0db57dSNamjae Jeon 		return -ENOMEM;
1272af0db57dSNamjae Jeon 	}
1273af0db57dSNamjae Jeon 
1274af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname_new, new_name_len);
1275af0db57dSNamjae Jeon 	if (err) {
1276af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname_new);
1277af0db57dSNamjae Jeon 		return err;
1278af0db57dSNamjae Jeon 	}
1279af0db57dSNamjae Jeon 
1280af0db57dSNamjae Jeon 	old_name_len = ntfs_nlstoucs(NTFS_I(old_dir)->vol, old_dentry->d_name.name,
1281af0db57dSNamjae Jeon 				     old_dentry->d_name.len, &uname_old,
1282af0db57dSNamjae Jeon 				     NTFS_MAX_NAME_LEN);
1283af0db57dSNamjae Jeon 	if (old_name_len < 0) {
1284af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname_new);
1285af0db57dSNamjae Jeon 		if (old_name_len != -ENAMETOOLONG)
1286af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to unicode.");
1287af0db57dSNamjae Jeon 		return -ENOMEM;
1288af0db57dSNamjae Jeon 	}
1289af0db57dSNamjae Jeon 
1290af0db57dSNamjae Jeon 	old_inode = old_dentry->d_inode;
1291af0db57dSNamjae Jeon 	new_inode = new_dentry->d_inode;
1292af0db57dSNamjae Jeon 	old_ni = NTFS_I(old_inode);
1293af0db57dSNamjae Jeon 
1294af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1295af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1296af0db57dSNamjae Jeon 
1297af0db57dSNamjae Jeon 	mutex_lock_nested(&old_ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL);
1298af0db57dSNamjae Jeon 	mutex_lock_nested(&old_dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT);
1299af0db57dSNamjae Jeon 
1300af0db57dSNamjae Jeon 	if (NInoBeingDeleted(old_ni) || NInoBeingDeleted(old_dir_ni)) {
1301af0db57dSNamjae Jeon 		err = -ENOENT;
1302af0db57dSNamjae Jeon 		goto unlock_old;
1303af0db57dSNamjae Jeon 	}
1304af0db57dSNamjae Jeon 
1305af0db57dSNamjae Jeon 	is_dir = S_ISDIR(old_inode->i_mode);
1306af0db57dSNamjae Jeon 
1307af0db57dSNamjae Jeon 	if (new_inode) {
1308af0db57dSNamjae Jeon 		new_ni = NTFS_I(new_inode);
1309af0db57dSNamjae Jeon 		mutex_lock_nested(&new_ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL_2);
1310af0db57dSNamjae Jeon 		if (old_dir != new_dir) {
1311af0db57dSNamjae Jeon 			mutex_lock_nested(&new_dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT_2);
1312af0db57dSNamjae Jeon 			if (NInoBeingDeleted(new_dir_ni)) {
1313af0db57dSNamjae Jeon 				err = -ENOENT;
1314af0db57dSNamjae Jeon 				goto err_out;
1315af0db57dSNamjae Jeon 			}
1316af0db57dSNamjae Jeon 		}
1317af0db57dSNamjae Jeon 
1318af0db57dSNamjae Jeon 		if (NInoBeingDeleted(new_ni)) {
1319af0db57dSNamjae Jeon 			err = -ENOENT;
1320af0db57dSNamjae Jeon 			goto err_out;
1321af0db57dSNamjae Jeon 		}
1322af0db57dSNamjae Jeon 
1323af0db57dSNamjae Jeon 		if (is_dir) {
1324af0db57dSNamjae Jeon 			struct mft_record *ni_mrec;
1325af0db57dSNamjae Jeon 
1326af0db57dSNamjae Jeon 			ni_mrec = map_mft_record(NTFS_I(new_inode));
1327af0db57dSNamjae Jeon 			if (IS_ERR(ni_mrec)) {
1328af0db57dSNamjae Jeon 				err = -EIO;
1329af0db57dSNamjae Jeon 				goto err_out;
1330af0db57dSNamjae Jeon 			}
1331af0db57dSNamjae Jeon 			err = ntfs_check_empty_dir(NTFS_I(new_inode), ni_mrec);
1332af0db57dSNamjae Jeon 			unmap_mft_record(NTFS_I(new_inode));
1333af0db57dSNamjae Jeon 			if (err)
1334af0db57dSNamjae Jeon 				goto err_out;
1335af0db57dSNamjae Jeon 		}
1336af0db57dSNamjae Jeon 
1337af0db57dSNamjae Jeon 		err = ntfs_delete(new_ni, new_dir_ni, uname_new, new_name_len, false);
1338af0db57dSNamjae Jeon 		if (err)
1339af0db57dSNamjae Jeon 			goto err_out;
1340af0db57dSNamjae Jeon 	} else {
1341af0db57dSNamjae Jeon 		if (old_dir != new_dir) {
1342af0db57dSNamjae Jeon 			mutex_lock_nested(&new_dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT_2);
1343af0db57dSNamjae Jeon 			if (NInoBeingDeleted(new_dir_ni)) {
1344af0db57dSNamjae Jeon 				err = -ENOENT;
1345af0db57dSNamjae Jeon 				goto err_out;
1346af0db57dSNamjae Jeon 			}
1347af0db57dSNamjae Jeon 		}
1348af0db57dSNamjae Jeon 	}
1349af0db57dSNamjae Jeon 
1350af0db57dSNamjae Jeon 	err = __ntfs_link(old_ni, new_dir_ni, uname_new, new_name_len);
1351af0db57dSNamjae Jeon 	if (err)
1352af0db57dSNamjae Jeon 		goto err_out;
1353af0db57dSNamjae Jeon 
1354af0db57dSNamjae Jeon 	err = ntfs_delete(old_ni, old_dir_ni, uname_old, old_name_len, false);
1355af0db57dSNamjae Jeon 	if (err) {
1356af0db57dSNamjae Jeon 		int err2;
1357af0db57dSNamjae Jeon 
1358d9038d99SNamjae Jeon 		ntfs_error(sb, "Failed to delete old ntfs inode(%llu) in old dir, err : %d\n",
1359af0db57dSNamjae Jeon 				old_ni->mft_no, err);
1360af0db57dSNamjae Jeon 		err2 = ntfs_delete(old_ni, new_dir_ni, uname_new, new_name_len, false);
1361af0db57dSNamjae Jeon 		if (err2)
1362af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to delete old ntfs inode in new dir, err : %d\n",
1363af0db57dSNamjae Jeon 					err2);
1364af0db57dSNamjae Jeon 		goto err_out;
1365af0db57dSNamjae Jeon 	}
1366af0db57dSNamjae Jeon 
1367af0db57dSNamjae Jeon 	simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
1368af0db57dSNamjae Jeon 	mark_inode_dirty(old_inode);
1369af0db57dSNamjae Jeon 	mark_inode_dirty(old_dir);
1370af0db57dSNamjae Jeon 	if (old_dir != new_dir)
1371af0db57dSNamjae Jeon 		mark_inode_dirty(new_dir);
1372af0db57dSNamjae Jeon 	if (new_inode)
1373af0db57dSNamjae Jeon 		mark_inode_dirty(old_inode);
1374af0db57dSNamjae Jeon 
1375af0db57dSNamjae Jeon 	inode_inc_iversion(new_dir);
1376af0db57dSNamjae Jeon 
1377af0db57dSNamjae Jeon err_out:
1378af0db57dSNamjae Jeon 	if (old_dir != new_dir)
1379af0db57dSNamjae Jeon 		mutex_unlock(&new_dir_ni->mrec_lock);
1380af0db57dSNamjae Jeon 	if (new_inode)
1381af0db57dSNamjae Jeon 		mutex_unlock(&new_ni->mrec_lock);
1382af0db57dSNamjae Jeon 
1383af0db57dSNamjae Jeon unlock_old:
1384af0db57dSNamjae Jeon 	mutex_unlock(&old_dir_ni->mrec_lock);
1385af0db57dSNamjae Jeon 	mutex_unlock(&old_ni->mrec_lock);
1386af0db57dSNamjae Jeon 	if (uname_new)
1387af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname_new);
1388af0db57dSNamjae Jeon 	if (uname_old)
1389af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname_old);
1390af0db57dSNamjae Jeon 
1391af0db57dSNamjae Jeon 	return err;
1392af0db57dSNamjae Jeon }
1393af0db57dSNamjae Jeon 
1394af0db57dSNamjae Jeon static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
1395af0db57dSNamjae Jeon 		struct dentry *dentry, const char *symname)
1396af0db57dSNamjae Jeon {
1397af0db57dSNamjae Jeon 	struct super_block *sb = dir->i_sb;
1398af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1399af0db57dSNamjae Jeon 	struct inode *vi;
1400af0db57dSNamjae Jeon 	int err = 0;
1401af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
1402af0db57dSNamjae Jeon 	__le16 *usrc;
1403af0db57dSNamjae Jeon 	__le16 *utarget;
1404af0db57dSNamjae Jeon 	int usrc_len;
1405af0db57dSNamjae Jeon 	int utarget_len;
1406af0db57dSNamjae Jeon 	int symlen = strlen(symname);
1407af0db57dSNamjae Jeon 
1408af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1409af0db57dSNamjae Jeon 		return -EIO;
1410af0db57dSNamjae Jeon 
1411af0db57dSNamjae Jeon 	usrc_len = ntfs_nlstoucs(vol, dentry->d_name.name,
1412af0db57dSNamjae Jeon 				 dentry->d_name.len, &usrc, NTFS_MAX_NAME_LEN);
1413af0db57dSNamjae Jeon 	if (usrc_len < 0) {
1414af0db57dSNamjae Jeon 		if (usrc_len != -ENAMETOOLONG)
1415af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to Unicode.");
1416af0db57dSNamjae Jeon 		err =  -ENOMEM;
1417af0db57dSNamjae Jeon 		goto out;
1418af0db57dSNamjae Jeon 	}
1419af0db57dSNamjae Jeon 
1420af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, usrc, usrc_len);
1421af0db57dSNamjae Jeon 	if (err) {
1422af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, usrc);
1423af0db57dSNamjae Jeon 		goto out;
1424af0db57dSNamjae Jeon 	}
1425af0db57dSNamjae Jeon 
1426af0db57dSNamjae Jeon 	utarget_len = ntfs_nlstoucs(vol, symname, symlen, &utarget,
1427af0db57dSNamjae Jeon 				    PATH_MAX);
1428af0db57dSNamjae Jeon 	if (utarget_len < 0) {
1429af0db57dSNamjae Jeon 		if (utarget_len != -ENAMETOOLONG)
1430af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert target name to Unicode.");
1431af0db57dSNamjae Jeon 		err =  -ENOMEM;
1432af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, usrc);
1433af0db57dSNamjae Jeon 		goto out;
1434af0db57dSNamjae Jeon 	}
1435af0db57dSNamjae Jeon 
1436af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1437af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1438af0db57dSNamjae Jeon 
1439af0db57dSNamjae Jeon 	ni = __ntfs_create(idmap, dir, usrc, usrc_len, S_IFLNK | 0777, 0,
1440af0db57dSNamjae Jeon 			utarget, utarget_len);
1441af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, usrc);
1442af0db57dSNamjae Jeon 	kvfree(utarget);
1443af0db57dSNamjae Jeon 	if (IS_ERR(ni)) {
1444af0db57dSNamjae Jeon 		err = PTR_ERR(ni);
1445af0db57dSNamjae Jeon 		goto out;
1446af0db57dSNamjae Jeon 	}
1447af0db57dSNamjae Jeon 
1448af0db57dSNamjae Jeon 	vi = VFS_I(ni);
1449af0db57dSNamjae Jeon 	vi->i_size = symlen;
1450af0db57dSNamjae Jeon 	d_instantiate_new(dentry, vi);
1451af0db57dSNamjae Jeon out:
1452af0db57dSNamjae Jeon 	return err;
1453af0db57dSNamjae Jeon }
1454af0db57dSNamjae Jeon 
1455af0db57dSNamjae Jeon static int ntfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
1456af0db57dSNamjae Jeon 		struct dentry *dentry, umode_t mode, dev_t rdev)
1457af0db57dSNamjae Jeon {
1458af0db57dSNamjae Jeon 	struct super_block *sb = dir->i_sb;
1459af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1460af0db57dSNamjae Jeon 	int err = 0;
1461af0db57dSNamjae Jeon 	struct ntfs_inode *ni;
1462af0db57dSNamjae Jeon 	__le16 *uname = NULL;
1463af0db57dSNamjae Jeon 	int uname_len;
1464af0db57dSNamjae Jeon 
1465af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1466af0db57dSNamjae Jeon 		return -EIO;
1467af0db57dSNamjae Jeon 
1468af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name,
1469af0db57dSNamjae Jeon 			dentry->d_name.len, &uname, NTFS_MAX_NAME_LEN);
1470af0db57dSNamjae Jeon 	if (uname_len < 0) {
1471af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
1472af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to Unicode.");
1473af0db57dSNamjae Jeon 		return -ENOMEM;
1474af0db57dSNamjae Jeon 	}
1475af0db57dSNamjae Jeon 
1476af0db57dSNamjae Jeon 	err = ntfs_check_bad_windows_name(vol, uname, uname_len);
1477af0db57dSNamjae Jeon 	if (err) {
1478af0db57dSNamjae Jeon 		kmem_cache_free(ntfs_name_cache, uname);
1479af0db57dSNamjae Jeon 		return err;
1480af0db57dSNamjae Jeon 	}
1481af0db57dSNamjae Jeon 
1482af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1483af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1484af0db57dSNamjae Jeon 
1485af0db57dSNamjae Jeon 	switch (mode & S_IFMT) {
1486af0db57dSNamjae Jeon 	case S_IFCHR:
1487af0db57dSNamjae Jeon 	case S_IFBLK:
1488af0db57dSNamjae Jeon 		ni = __ntfs_create(idmap, dir, uname, uname_len,
1489af0db57dSNamjae Jeon 				mode, rdev, NULL, 0);
1490af0db57dSNamjae Jeon 		break;
1491af0db57dSNamjae Jeon 	default:
1492af0db57dSNamjae Jeon 		ni = __ntfs_create(idmap, dir, uname, uname_len,
1493af0db57dSNamjae Jeon 				mode, 0, NULL, 0);
1494af0db57dSNamjae Jeon 	}
1495af0db57dSNamjae Jeon 
1496af0db57dSNamjae Jeon 	kmem_cache_free(ntfs_name_cache, uname);
1497af0db57dSNamjae Jeon 	if (IS_ERR(ni)) {
1498af0db57dSNamjae Jeon 		err = PTR_ERR(ni);
1499af0db57dSNamjae Jeon 		goto out;
1500af0db57dSNamjae Jeon 	}
1501af0db57dSNamjae Jeon 
1502af0db57dSNamjae Jeon 	d_instantiate_new(dentry, VFS_I(ni));
1503af0db57dSNamjae Jeon out:
1504af0db57dSNamjae Jeon 	return err;
1505af0db57dSNamjae Jeon }
1506af0db57dSNamjae Jeon 
1507af0db57dSNamjae Jeon static int ntfs_link(struct dentry *old_dentry, struct inode *dir,
1508af0db57dSNamjae Jeon 		struct dentry *dentry)
1509af0db57dSNamjae Jeon {
1510af0db57dSNamjae Jeon 	struct inode *vi = old_dentry->d_inode;
1511af0db57dSNamjae Jeon 	struct super_block *sb = vi->i_sb;
1512af0db57dSNamjae Jeon 	struct ntfs_volume *vol = NTFS_SB(sb);
1513af0db57dSNamjae Jeon 	__le16 *uname = NULL;
1514af0db57dSNamjae Jeon 	int uname_len;
1515af0db57dSNamjae Jeon 	int err;
1516af0db57dSNamjae Jeon 	struct ntfs_inode *ni = NTFS_I(vi), *dir_ni = NTFS_I(dir);
1517af0db57dSNamjae Jeon 
1518af0db57dSNamjae Jeon 	if (NVolShutdown(vol))
1519af0db57dSNamjae Jeon 		return -EIO;
1520af0db57dSNamjae Jeon 
1521af0db57dSNamjae Jeon 	uname_len = ntfs_nlstoucs(vol, dentry->d_name.name,
1522af0db57dSNamjae Jeon 			dentry->d_name.len, &uname, NTFS_MAX_NAME_LEN);
1523af0db57dSNamjae Jeon 	if (uname_len < 0) {
1524af0db57dSNamjae Jeon 		if (uname_len != -ENAMETOOLONG)
1525af0db57dSNamjae Jeon 			ntfs_error(sb, "Failed to convert name to unicode.");
1526af0db57dSNamjae Jeon 		err = -ENOMEM;
1527af0db57dSNamjae Jeon 		goto out;
1528af0db57dSNamjae Jeon 	}
1529af0db57dSNamjae Jeon 
1530af0db57dSNamjae Jeon 	if (!(vol->vol_flags & VOLUME_IS_DIRTY))
1531af0db57dSNamjae Jeon 		ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
1532af0db57dSNamjae Jeon 
1533af0db57dSNamjae Jeon 	ihold(vi);
1534af0db57dSNamjae Jeon 	mutex_lock_nested(&ni->mrec_lock, NTFS_INODE_MUTEX_NORMAL);
1535af0db57dSNamjae Jeon 	mutex_lock_nested(&dir_ni->mrec_lock, NTFS_INODE_MUTEX_PARENT);
1536af0db57dSNamjae Jeon 	err = __ntfs_link(NTFS_I(vi), NTFS_I(dir), uname, uname_len);
1537af0db57dSNamjae Jeon 	if (err) {
1538af0db57dSNamjae Jeon 		mutex_unlock(&dir_ni->mrec_lock);
1539af0db57dSNamjae Jeon 		mutex_unlock(&ni->mrec_lock);
1540af0db57dSNamjae Jeon 		iput(vi);
1541af0db57dSNamjae Jeon 		pr_err("failed to create link, err = %d\n", err);
1542af0db57dSNamjae Jeon 		goto out;
1543af0db57dSNamjae Jeon 	}
1544af0db57dSNamjae Jeon 
1545af0db57dSNamjae Jeon 	inode_inc_iversion(dir);
1546af0db57dSNamjae Jeon 	simple_inode_init_ts(dir);
1547af0db57dSNamjae Jeon 
1548af0db57dSNamjae Jeon 	inode_inc_iversion(vi);
1549af0db57dSNamjae Jeon 	simple_inode_init_ts(vi);
1550af0db57dSNamjae Jeon 
1551af0db57dSNamjae Jeon 	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
1552af0db57dSNamjae Jeon 	d_instantiate(dentry, vi);
1553af0db57dSNamjae Jeon 	mutex_unlock(&dir_ni->mrec_lock);
1554af0db57dSNamjae Jeon 	mutex_unlock(&ni->mrec_lock);
1555af0db57dSNamjae Jeon 
1556af0db57dSNamjae Jeon out:
1557af0db57dSNamjae Jeon 	kfree(uname);
1558af0db57dSNamjae Jeon 	return err;
1559af0db57dSNamjae Jeon }
1560af0db57dSNamjae Jeon 
15611e9ea7e0SNamjae Jeon /*
15621e9ea7e0SNamjae Jeon  * Inode operations for directories.
15631e9ea7e0SNamjae Jeon  */
15641e9ea7e0SNamjae Jeon const struct inode_operations ntfs_dir_inode_ops = {
15651e9ea7e0SNamjae Jeon 	.lookup		= ntfs_lookup,	/* VFS: Lookup directory. */
1566af0db57dSNamjae Jeon 	.create		= ntfs_create,
1567af0db57dSNamjae Jeon 	.unlink		= ntfs_unlink,
1568af0db57dSNamjae Jeon 	.mkdir		= ntfs_mkdir,
1569af0db57dSNamjae Jeon 	.rmdir		= ntfs_rmdir,
1570af0db57dSNamjae Jeon 	.rename		= ntfs_rename,
1571af0db57dSNamjae Jeon 	.get_acl	= ntfs_get_acl,
1572af0db57dSNamjae Jeon 	.set_acl	= ntfs_set_acl,
1573af0db57dSNamjae Jeon 	.listxattr	= ntfs_listxattr,
1574af0db57dSNamjae Jeon 	.setattr	= ntfs_setattr,
1575af0db57dSNamjae Jeon 	.getattr	= ntfs_getattr,
1576af0db57dSNamjae Jeon 	.symlink	= ntfs_symlink,
1577af0db57dSNamjae Jeon 	.mknod		= ntfs_mknod,
1578af0db57dSNamjae Jeon 	.link		= ntfs_link,
15791e9ea7e0SNamjae Jeon };
15801e9ea7e0SNamjae Jeon 
1581af0db57dSNamjae Jeon /*
15821e9ea7e0SNamjae Jeon  * ntfs_get_parent - find the dentry of the parent of a given directory dentry
15831e9ea7e0SNamjae Jeon  * @child_dent:		dentry of the directory whose parent directory to find
15841e9ea7e0SNamjae Jeon  *
15851e9ea7e0SNamjae Jeon  * Find the dentry for the parent directory of the directory specified by the
15861e9ea7e0SNamjae Jeon  * dentry @child_dent.  This function is called from
15871e9ea7e0SNamjae Jeon  * fs/exportfs/expfs.c::find_exported_dentry() which in turn is called from the
15881e9ea7e0SNamjae Jeon  * default ->decode_fh() which is export_decode_fh() in the same file.
15891e9ea7e0SNamjae Jeon  *
15901e9ea7e0SNamjae Jeon  * Note: ntfs_get_parent() is called with @d_inode(child_dent)->i_mutex down.
15911e9ea7e0SNamjae Jeon  *
15921e9ea7e0SNamjae Jeon  * Return the dentry of the parent directory on success or the error code on
15931e9ea7e0SNamjae Jeon  * error (IS_ERR() is true).
15941e9ea7e0SNamjae Jeon  */
15951e9ea7e0SNamjae Jeon static struct dentry *ntfs_get_parent(struct dentry *child_dent)
15961e9ea7e0SNamjae Jeon {
15971e9ea7e0SNamjae Jeon 	struct inode *vi = d_inode(child_dent);
1598af0db57dSNamjae Jeon 	struct ntfs_inode *ni = NTFS_I(vi);
1599af0db57dSNamjae Jeon 	struct mft_record *mrec;
1600af0db57dSNamjae Jeon 	struct ntfs_attr_search_ctx *ctx;
1601af0db57dSNamjae Jeon 	struct attr_record *attr;
1602af0db57dSNamjae Jeon 	struct file_name_attr *fn;
16031e9ea7e0SNamjae Jeon 	unsigned long parent_ino;
16041e9ea7e0SNamjae Jeon 	int err;
16051e9ea7e0SNamjae Jeon 
1606e7d82353SNamjae Jeon 	ntfs_debug("Entering for inode 0x%llx.", ni->mft_no);
16071e9ea7e0SNamjae Jeon 	/* Get the mft record of the inode belonging to the child dentry. */
16081e9ea7e0SNamjae Jeon 	mrec = map_mft_record(ni);
16091e9ea7e0SNamjae Jeon 	if (IS_ERR(mrec))
16101e9ea7e0SNamjae Jeon 		return ERR_CAST(mrec);
16111e9ea7e0SNamjae Jeon 	/* Find the first file name attribute in the mft record. */
16121e9ea7e0SNamjae Jeon 	ctx = ntfs_attr_get_search_ctx(ni, mrec);
16131e9ea7e0SNamjae Jeon 	if (unlikely(!ctx)) {
16141e9ea7e0SNamjae Jeon 		unmap_mft_record(ni);
16151e9ea7e0SNamjae Jeon 		return ERR_PTR(-ENOMEM);
16161e9ea7e0SNamjae Jeon 	}
16171e9ea7e0SNamjae Jeon try_next:
16181e9ea7e0SNamjae Jeon 	err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
16191e9ea7e0SNamjae Jeon 			0, ctx);
16201e9ea7e0SNamjae Jeon 	if (unlikely(err)) {
16211e9ea7e0SNamjae Jeon 		ntfs_attr_put_search_ctx(ctx);
16221e9ea7e0SNamjae Jeon 		unmap_mft_record(ni);
16231e9ea7e0SNamjae Jeon 		if (err == -ENOENT)
1624af0db57dSNamjae Jeon 			ntfs_error(vi->i_sb,
1625e7d82353SNamjae Jeon 				   "Inode 0x%llx does not have a file name attribute.  Run chkdsk.",
1626e7d82353SNamjae Jeon 				   ni->mft_no);
16271e9ea7e0SNamjae Jeon 		return ERR_PTR(err);
16281e9ea7e0SNamjae Jeon 	}
16291e9ea7e0SNamjae Jeon 	attr = ctx->attr;
16301e9ea7e0SNamjae Jeon 	if (unlikely(attr->non_resident))
16311e9ea7e0SNamjae Jeon 		goto try_next;
1632af0db57dSNamjae Jeon 	fn = (struct file_name_attr *)((u8 *)attr +
16331e9ea7e0SNamjae Jeon 			le16_to_cpu(attr->data.resident.value_offset));
16341e9ea7e0SNamjae Jeon 	if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
16351e9ea7e0SNamjae Jeon 	    (u8 *)attr + le32_to_cpu(attr->length)))
16361e9ea7e0SNamjae Jeon 		goto try_next;
16371e9ea7e0SNamjae Jeon 	/* Get the inode number of the parent directory. */
16381e9ea7e0SNamjae Jeon 	parent_ino = MREF_LE(fn->parent_directory);
16391e9ea7e0SNamjae Jeon 	/* Release the search context and the mft record of the child. */
16401e9ea7e0SNamjae Jeon 	ntfs_attr_put_search_ctx(ctx);
16411e9ea7e0SNamjae Jeon 	unmap_mft_record(ni);
16421e9ea7e0SNamjae Jeon 
16431e9ea7e0SNamjae Jeon 	return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
16441e9ea7e0SNamjae Jeon }
16451e9ea7e0SNamjae Jeon 
16461e9ea7e0SNamjae Jeon static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
16471e9ea7e0SNamjae Jeon 		u64 ino, u32 generation)
16481e9ea7e0SNamjae Jeon {
16491e9ea7e0SNamjae Jeon 	struct inode *inode;
16501e9ea7e0SNamjae Jeon 
16511e9ea7e0SNamjae Jeon 	inode = ntfs_iget(sb, ino);
16521e9ea7e0SNamjae Jeon 	if (!IS_ERR(inode)) {
1653af0db57dSNamjae Jeon 		if (inode->i_generation != generation) {
16541e9ea7e0SNamjae Jeon 			iput(inode);
16551e9ea7e0SNamjae Jeon 			inode = ERR_PTR(-ESTALE);
16561e9ea7e0SNamjae Jeon 		}
16571e9ea7e0SNamjae Jeon 	}
16581e9ea7e0SNamjae Jeon 
16591e9ea7e0SNamjae Jeon 	return inode;
16601e9ea7e0SNamjae Jeon }
16611e9ea7e0SNamjae Jeon 
16621e9ea7e0SNamjae Jeon static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
16631e9ea7e0SNamjae Jeon 		int fh_len, int fh_type)
16641e9ea7e0SNamjae Jeon {
16651e9ea7e0SNamjae Jeon 	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
16661e9ea7e0SNamjae Jeon 				    ntfs_nfs_get_inode);
16671e9ea7e0SNamjae Jeon }
16681e9ea7e0SNamjae Jeon 
16691e9ea7e0SNamjae Jeon static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
16701e9ea7e0SNamjae Jeon 		int fh_len, int fh_type)
16711e9ea7e0SNamjae Jeon {
16721e9ea7e0SNamjae Jeon 	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
16731e9ea7e0SNamjae Jeon 				    ntfs_nfs_get_inode);
16741e9ea7e0SNamjae Jeon }
16751e9ea7e0SNamjae Jeon 
16761e9ea7e0SNamjae Jeon /*
16771e9ea7e0SNamjae Jeon  * Export operations allowing NFS exporting of mounted NTFS partitions.
16781e9ea7e0SNamjae Jeon  */
16791e9ea7e0SNamjae Jeon const struct export_operations ntfs_export_ops = {
16801e9ea7e0SNamjae Jeon 	.encode_fh = generic_encode_ino32_fh,
1681af0db57dSNamjae Jeon 	.get_parent	= ntfs_get_parent,	/* Find the parent of a given directory. */
16821e9ea7e0SNamjae Jeon 	.fh_to_dentry	= ntfs_fh_to_dentry,
16831e9ea7e0SNamjae Jeon 	.fh_to_parent	= ntfs_fh_to_parent,
16841e9ea7e0SNamjae Jeon };
1685