Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
0004  *       project.
0005  *
0006  * Copyright (c) 2001-2006 Anton Altaparmakov
0007  */
0008 
0009 #include <linux/dcache.h>
0010 #include <linux/exportfs.h>
0011 #include <linux/security.h>
0012 #include <linux/slab.h>
0013 
0014 #include "attrib.h"
0015 #include "debug.h"
0016 #include "dir.h"
0017 #include "mft.h"
0018 #include "ntfs.h"
0019 
0020 /**
0021  * ntfs_lookup - find the inode represented by a dentry in a directory inode
0022  * @dir_ino:    directory inode in which to look for the inode
0023  * @dent:   dentry representing the inode to look for
0024  * @flags:  lookup flags
0025  *
0026  * In short, ntfs_lookup() looks for the inode represented by the dentry @dent
0027  * in the directory inode @dir_ino and if found attaches the inode to the
0028  * dentry @dent.
0029  *
0030  * In more detail, the dentry @dent specifies which inode to look for by
0031  * supplying the name of the inode in @dent->d_name.name. ntfs_lookup()
0032  * converts the name to Unicode and walks the contents of the directory inode
0033  * @dir_ino looking for the converted Unicode name. If the name is found in the
0034  * directory, the corresponding inode is loaded by calling ntfs_iget() on its
0035  * inode number and the inode is associated with the dentry @dent via a call to
0036  * d_splice_alias().
0037  *
0038  * If the name is not found in the directory, a NULL inode is inserted into the
0039  * dentry @dent via a call to d_add(). The dentry is then termed a negative
0040  * dentry.
0041  *
0042  * Only if an actual error occurs, do we return an error via ERR_PTR().
0043  *
0044  * In order to handle the case insensitivity issues of NTFS with regards to the
0045  * dcache and the dcache requiring only one dentry per directory, we deal with
0046  * dentry aliases that only differ in case in ->ntfs_lookup() while maintaining
0047  * a case sensitive dcache. This means that we get the full benefit of dcache
0048  * speed when the file/directory is looked up with the same case as returned by
0049  * ->ntfs_readdir() but that a lookup for any other case (or for the short file
0050  * name) will not find anything in dcache and will enter ->ntfs_lookup()
0051  * instead, where we search the directory for a fully matching file name
0052  * (including case) and if that is not found, we search for a file name that
0053  * matches with different case and if that has non-POSIX semantics we return
0054  * that. We actually do only one search (case sensitive) and keep tabs on
0055  * whether we have found a case insensitive match in the process.
0056  *
0057  * To simplify matters for us, we do not treat the short vs long filenames as
0058  * two hard links but instead if the lookup matches a short filename, we
0059  * return the dentry for the corresponding long filename instead.
0060  *
0061  * There are three cases we need to distinguish here:
0062  *
0063  * 1) @dent perfectly matches (i.e. including case) a directory entry with a
0064  *    file name in the WIN32 or POSIX namespaces. In this case
0065  *    ntfs_lookup_inode_by_name() will return with name set to NULL and we
0066  *    just d_splice_alias() @dent.
0067  * 2) @dent matches (not including case) a directory entry with a file name in
0068  *    the WIN32 namespace. In this case ntfs_lookup_inode_by_name() will return
0069  *    with name set to point to a kmalloc()ed ntfs_name structure containing
0070  *    the properly cased little endian Unicode name. We convert the name to the
0071  *    current NLS code page, search if a dentry with this name already exists
0072  *    and if so return that instead of @dent.  At this point things are
0073  *    complicated by the possibility of 'disconnected' dentries due to NFS
0074  *    which we deal with appropriately (see the code comments).  The VFS will
0075  *    then destroy the old @dent and use the one we returned.  If a dentry is
0076  *    not found, we allocate a new one, d_splice_alias() it, and return it as
0077  *    above.
0078  * 3) @dent matches either perfectly or not (i.e. we don't care about case) a
0079  *    directory entry with a file name in the DOS namespace. In this case
0080  *    ntfs_lookup_inode_by_name() will return with name set to point to a
0081  *    kmalloc()ed ntfs_name structure containing the mft reference (cpu endian)
0082  *    of the inode. We use the mft reference to read the inode and to find the
0083  *    file name in the WIN32 namespace corresponding to the matched short file
0084  *    name. We then convert the name to the current NLS code page, and proceed
0085  *    searching for a dentry with this name, etc, as in case 2), above.
0086  *
0087  * Locking: Caller must hold i_mutex on the directory.
0088  */
0089 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
0090         unsigned int flags)
0091 {
0092     ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
0093     struct inode *dent_inode;
0094     ntfschar *uname;
0095     ntfs_name *name = NULL;
0096     MFT_REF mref;
0097     unsigned long dent_ino;
0098     int uname_len;
0099 
0100     ntfs_debug("Looking up %pd in directory inode 0x%lx.",
0101             dent, dir_ino->i_ino);
0102     /* Convert the name of the dentry to Unicode. */
0103     uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
0104             &uname);
0105     if (uname_len < 0) {
0106         if (uname_len != -ENAMETOOLONG)
0107             ntfs_error(vol->sb, "Failed to convert name to "
0108                     "Unicode.");
0109         return ERR_PTR(uname_len);
0110     }
0111     mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
0112             &name);
0113     kmem_cache_free(ntfs_name_cache, uname);
0114     if (!IS_ERR_MREF(mref)) {
0115         dent_ino = MREF(mref);
0116         ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
0117         dent_inode = ntfs_iget(vol->sb, dent_ino);
0118         if (!IS_ERR(dent_inode)) {
0119             /* Consistency check. */
0120             if (is_bad_inode(dent_inode) || MSEQNO(mref) ==
0121                     NTFS_I(dent_inode)->seq_no ||
0122                     dent_ino == FILE_MFT) {
0123                 /* Perfect WIN32/POSIX match. -- Case 1. */
0124                 if (!name) {
0125                     ntfs_debug("Done.  (Case 1.)");
0126                     return d_splice_alias(dent_inode, dent);
0127                 }
0128                 /*
0129                  * We are too indented.  Handle imperfect
0130                  * matches and short file names further below.
0131                  */
0132                 goto handle_name;
0133             }
0134             ntfs_error(vol->sb, "Found stale reference to inode "
0135                     "0x%lx (reference sequence number = "
0136                     "0x%x, inode sequence number = 0x%x), "
0137                     "returning -EIO. Run chkdsk.",
0138                     dent_ino, MSEQNO(mref),
0139                     NTFS_I(dent_inode)->seq_no);
0140             iput(dent_inode);
0141             dent_inode = ERR_PTR(-EIO);
0142         } else
0143             ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
0144                     "error code %li.", dent_ino,
0145                     PTR_ERR(dent_inode));
0146         kfree(name);
0147         /* Return the error code. */
0148         return ERR_CAST(dent_inode);
0149     }
0150     /* It is guaranteed that @name is no longer allocated at this point. */
0151     if (MREF_ERR(mref) == -ENOENT) {
0152         ntfs_debug("Entry was not found, adding negative dentry.");
0153         /* The dcache will handle negative entries. */
0154         d_add(dent, NULL);
0155         ntfs_debug("Done.");
0156         return NULL;
0157     }
0158     ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
0159             "code %i.", -MREF_ERR(mref));
0160     return ERR_PTR(MREF_ERR(mref));
0161     // TODO: Consider moving this lot to a separate function! (AIA)
0162 handle_name:
0163    {
0164     MFT_RECORD *m;
0165     ntfs_attr_search_ctx *ctx;
0166     ntfs_inode *ni = NTFS_I(dent_inode);
0167     int err;
0168     struct qstr nls_name;
0169 
0170     nls_name.name = NULL;
0171     if (name->type != FILE_NAME_DOS) {          /* Case 2. */
0172         ntfs_debug("Case 2.");
0173         nls_name.len = (unsigned)ntfs_ucstonls(vol,
0174                 (ntfschar*)&name->name, name->len,
0175                 (unsigned char**)&nls_name.name, 0);
0176         kfree(name);
0177     } else /* if (name->type == FILE_NAME_DOS) */ {     /* Case 3. */
0178         FILE_NAME_ATTR *fn;
0179 
0180         ntfs_debug("Case 3.");
0181         kfree(name);
0182 
0183         /* Find the WIN32 name corresponding to the matched DOS name. */
0184         ni = NTFS_I(dent_inode);
0185         m = map_mft_record(ni);
0186         if (IS_ERR(m)) {
0187             err = PTR_ERR(m);
0188             m = NULL;
0189             ctx = NULL;
0190             goto err_out;
0191         }
0192         ctx = ntfs_attr_get_search_ctx(ni, m);
0193         if (unlikely(!ctx)) {
0194             err = -ENOMEM;
0195             goto err_out;
0196         }
0197         do {
0198             ATTR_RECORD *a;
0199             u32 val_len;
0200 
0201             err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
0202                     NULL, 0, ctx);
0203             if (unlikely(err)) {
0204                 ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
0205                         "namespace counterpart to DOS "
0206                         "file name. Run chkdsk.");
0207                 if (err == -ENOENT)
0208                     err = -EIO;
0209                 goto err_out;
0210             }
0211             /* Consistency checks. */
0212             a = ctx->attr;
0213             if (a->non_resident || a->flags)
0214                 goto eio_err_out;
0215             val_len = le32_to_cpu(a->data.resident.value_length);
0216             if (le16_to_cpu(a->data.resident.value_offset) +
0217                     val_len > le32_to_cpu(a->length))
0218                 goto eio_err_out;
0219             fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
0220                     ctx->attr->data.resident.value_offset));
0221             if ((u32)(fn->file_name_length * sizeof(ntfschar) +
0222                     sizeof(FILE_NAME_ATTR)) > val_len)
0223                 goto eio_err_out;
0224         } while (fn->file_name_type != FILE_NAME_WIN32);
0225 
0226         /* Convert the found WIN32 name to current NLS code page. */
0227         nls_name.len = (unsigned)ntfs_ucstonls(vol,
0228                 (ntfschar*)&fn->file_name, fn->file_name_length,
0229                 (unsigned char**)&nls_name.name, 0);
0230 
0231         ntfs_attr_put_search_ctx(ctx);
0232         unmap_mft_record(ni);
0233     }
0234     m = NULL;
0235     ctx = NULL;
0236 
0237     /* Check if a conversion error occurred. */
0238     if ((signed)nls_name.len < 0) {
0239         err = (signed)nls_name.len;
0240         goto err_out;
0241     }
0242     nls_name.hash = full_name_hash(dent, nls_name.name, nls_name.len);
0243 
0244     dent = d_add_ci(dent, dent_inode, &nls_name);
0245     kfree(nls_name.name);
0246     return dent;
0247 
0248 eio_err_out:
0249     ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
0250     err = -EIO;
0251 err_out:
0252     if (ctx)
0253         ntfs_attr_put_search_ctx(ctx);
0254     if (m)
0255         unmap_mft_record(ni);
0256     iput(dent_inode);
0257     ntfs_error(vol->sb, "Failed, returning error code %i.", err);
0258     return ERR_PTR(err);
0259    }
0260 }
0261 
0262 /**
0263  * Inode operations for directories.
0264  */
0265 const struct inode_operations ntfs_dir_inode_ops = {
0266     .lookup = ntfs_lookup,  /* VFS: Lookup directory. */
0267 };
0268 
0269 /**
0270  * ntfs_get_parent - find the dentry of the parent of a given directory dentry
0271  * @child_dent:     dentry of the directory whose parent directory to find
0272  *
0273  * Find the dentry for the parent directory of the directory specified by the
0274  * dentry @child_dent.  This function is called from
0275  * fs/exportfs/expfs.c::find_exported_dentry() which in turn is called from the
0276  * default ->decode_fh() which is export_decode_fh() in the same file.
0277  *
0278  * The code is based on the ext3 ->get_parent() implementation found in
0279  * fs/ext3/namei.c::ext3_get_parent().
0280  *
0281  * Note: ntfs_get_parent() is called with @d_inode(child_dent)->i_mutex down.
0282  *
0283  * Return the dentry of the parent directory on success or the error code on
0284  * error (IS_ERR() is true).
0285  */
0286 static struct dentry *ntfs_get_parent(struct dentry *child_dent)
0287 {
0288     struct inode *vi = d_inode(child_dent);
0289     ntfs_inode *ni = NTFS_I(vi);
0290     MFT_RECORD *mrec;
0291     ntfs_attr_search_ctx *ctx;
0292     ATTR_RECORD *attr;
0293     FILE_NAME_ATTR *fn;
0294     unsigned long parent_ino;
0295     int err;
0296 
0297     ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
0298     /* Get the mft record of the inode belonging to the child dentry. */
0299     mrec = map_mft_record(ni);
0300     if (IS_ERR(mrec))
0301         return ERR_CAST(mrec);
0302     /* Find the first file name attribute in the mft record. */
0303     ctx = ntfs_attr_get_search_ctx(ni, mrec);
0304     if (unlikely(!ctx)) {
0305         unmap_mft_record(ni);
0306         return ERR_PTR(-ENOMEM);
0307     }
0308 try_next:
0309     err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
0310             0, ctx);
0311     if (unlikely(err)) {
0312         ntfs_attr_put_search_ctx(ctx);
0313         unmap_mft_record(ni);
0314         if (err == -ENOENT)
0315             ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
0316                     "file name attribute.  Run chkdsk.",
0317                     vi->i_ino);
0318         return ERR_PTR(err);
0319     }
0320     attr = ctx->attr;
0321     if (unlikely(attr->non_resident))
0322         goto try_next;
0323     fn = (FILE_NAME_ATTR *)((u8 *)attr +
0324             le16_to_cpu(attr->data.resident.value_offset));
0325     if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
0326             (u8*)attr + le32_to_cpu(attr->length)))
0327         goto try_next;
0328     /* Get the inode number of the parent directory. */
0329     parent_ino = MREF_LE(fn->parent_directory);
0330     /* Release the search context and the mft record of the child. */
0331     ntfs_attr_put_search_ctx(ctx);
0332     unmap_mft_record(ni);
0333 
0334     return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
0335 }
0336 
0337 static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
0338         u64 ino, u32 generation)
0339 {
0340     struct inode *inode;
0341 
0342     inode = ntfs_iget(sb, ino);
0343     if (!IS_ERR(inode)) {
0344         if (is_bad_inode(inode) || inode->i_generation != generation) {
0345             iput(inode);
0346             inode = ERR_PTR(-ESTALE);
0347         }
0348     }
0349 
0350     return inode;
0351 }
0352 
0353 static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
0354         int fh_len, int fh_type)
0355 {
0356     return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
0357                     ntfs_nfs_get_inode);
0358 }
0359 
0360 static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
0361         int fh_len, int fh_type)
0362 {
0363     return generic_fh_to_parent(sb, fid, fh_len, fh_type,
0364                     ntfs_nfs_get_inode);
0365 }
0366 
0367 /**
0368  * Export operations allowing NFS exporting of mounted NTFS partitions.
0369  *
0370  * We use the default ->encode_fh() for now.  Note that they
0371  * use 32 bits to store the inode number which is an unsigned long so on 64-bit
0372  * architectures is usually 64 bits so it would all fail horribly on huge
0373  * volumes.  I guess we need to define our own encode and decode fh functions
0374  * that store 64-bit inode numbers at some point but for now we will ignore the
0375  * problem...
0376  *
0377  * We also use the default ->get_name() helper (used by ->decode_fh() via
0378  * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs
0379  * independent.
0380  *
0381  * The default ->get_parent() just returns -EACCES so we have to provide our
0382  * own and the default ->get_dentry() is incompatible with NTFS due to not
0383  * allowing the inode number 0 which is used in NTFS for the system file $MFT
0384  * and due to using iget() whereas NTFS needs ntfs_iget().
0385  */
0386 const struct export_operations ntfs_export_ops = {
0387     .get_parent = ntfs_get_parent,  /* Find the parent of a given
0388                            directory. */
0389     .fh_to_dentry   = ntfs_fh_to_dentry,
0390     .fh_to_parent   = ntfs_fh_to_parent,
0391 };