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