remove whitespace from end of lines
[reactos.git] / reactos / drivers / fs / ntfs / linux-ntfs / namei.c
1 /*
2 * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
3 * project.
4 *
5 * Copyright (c) 2001-2003 Anton Altaparmakov
6 *
7 * This program/include file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program/include file is distributed in the hope that it will be
13 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program (in the main directory of the Linux-NTFS
19 * distribution in the file COPYING); if not, write to the Free Software
20 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <linux/dcache.h>
24
25 #include "ntfs.h"
26 #include "dir.h"
27
28 /**
29 * ntfs_lookup - find the inode represented by a dentry in a directory inode
30 * @dir_ino: directory inode in which to look for the inode
31 * @dent: dentry representing the inode to look for
32 * @nd: lookup nameidata
33 *
34 * In short, ntfs_lookup() looks for the inode represented by the dentry @dent
35 * in the directory inode @dir_ino and if found attaches the inode to the
36 * dentry @dent.
37 *
38 * In more detail, the dentry @dent specifies which inode to look for by
39 * supplying the name of the inode in @dent->d_name.name. ntfs_lookup()
40 * converts the name to Unicode and walks the contents of the directory inode
41 * @dir_ino looking for the converted Unicode name. If the name is found in the
42 * directory, the corresponding inode is loaded by calling ntfs_iget() on its
43 * inode number and the inode is associated with the dentry @dent via a call to
44 * d_add().
45 *
46 * If the name is not found in the directory, a NULL inode is inserted into the
47 * dentry @dent. The dentry is then termed a negative dentry.
48 *
49 * Only if an actual error occurs, do we return an error via ERR_PTR().
50 *
51 * In order to handle the case insensitivity issues of NTFS with regards to the
52 * dcache and the dcache requiring only one dentry per directory, we deal with
53 * dentry aliases that only differ in case in ->ntfs_lookup() while maintining
54 * a case sensitive dcache. This means that we get the full benefit of dcache
55 * speed when the file/directory is looked up with the same case as returned by
56 * ->ntfs_readdir() but that a lookup for any other case (or for the short file
57 * name) will not find anything in dcache and will enter ->ntfs_lookup()
58 * instead, where we search the directory for a fully matching file name
59 * (including case) and if that is not found, we search for a file name that
60 * matches with different case and if that has non-POSIX semantics we return
61 * that. We actually do only one search (case sensitive) and keep tabs on
62 * whether we have found a case insensitive match in the process.
63 *
64 * To simplify matters for us, we do not treat the short vs long filenames as
65 * two hard links but instead if the lookup matches a short filename, we
66 * return the dentry for the corresponding long filename instead.
67 *
68 * There are three cases we need to distinguish here:
69 *
70 * 1) @dent perfectly matches (i.e. including case) a directory entry with a
71 * file name in the WIN32 or POSIX namespaces. In this case
72 * ntfs_lookup_inode_by_name() will return with name set to NULL and we
73 * just d_add() @dent.
74 * 2) @dent matches (not including case) a directory entry with a file name in
75 * the WIN32 namespace. In this case ntfs_lookup_inode_by_name() will return
76 * with name set to point to a kmalloc()ed ntfs_name structure containing
77 * the properly cased little endian Unicode name. We convert the name to the
78 * current NLS code page, search if a dentry with this name already exists
79 * and if so return that instead of @dent. The VFS will then destroy the old
80 * @dent and use the one we returned. If a dentry is not found, we allocate
81 * a new one, d_add() it, and return it as above.
82 * 3) @dent matches either perfectly or not (i.e. we don't care about case) a
83 * directory entry with a file name in the DOS namespace. In this case
84 * ntfs_lookup_inode_by_name() will return with name set to point to a
85 * kmalloc()ed ntfs_name structure containing the mft reference (cpu endian)
86 * of the inode. We use the mft reference to read the inode and to find the
87 * file name in the WIN32 namespace corresponding to the matched short file
88 * name. We then convert the name to the current NLS code page, and proceed
89 * searching for a dentry with this name, etc, as in case 2), above.
90 */
91 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, struct nameidata *nd)
92 {
93 ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
94 struct inode *dent_inode;
95 uchar_t *uname;
96 ntfs_name *name = NULL;
97 MFT_REF mref;
98 unsigned long dent_ino;
99 int uname_len;
100
101 ntfs_debug("Looking up %s in directory inode 0x%lx.",
102 dent->d_name.name, dir_ino->i_ino);
103 /* Convert the name of the dentry to Unicode. */
104 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
105 &uname);
106 if (uname_len < 0) {
107 ntfs_error(vol->sb, "Failed to convert name to Unicode.");
108 return ERR_PTR(uname_len);
109 }
110 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
111 &name);
112 kmem_cache_free(ntfs_name_cache, uname);
113 if (!IS_ERR_MREF(mref)) {
114 dent_ino = MREF(mref);
115 ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
116 dent_inode = ntfs_iget(vol->sb, dent_ino);
117 if (likely(!IS_ERR(dent_inode))) {
118 /* Consistency check. */
119 if (MSEQNO(mref) == NTFS_I(dent_inode)->seq_no ||
120 dent_ino == FILE_MFT) {
121 /* Perfect WIN32/POSIX match. -- Case 1. */
122 if (!name) {
123 d_add(dent, dent_inode);
124 ntfs_debug("Done.");
125 return NULL;
126 }
127 /*
128 * We are too indented. Handle imperfect
129 * matches and short file names further below.
130 */
131 goto handle_name;
132 }
133 ntfs_error(vol->sb, "Found stale reference to inode "
134 "0x%lx (reference sequence number = "
135 "0x%x, inode sequence number = 0x%x, "
136 "returning -EIO. Run chkdsk.",
137 dent_ino, MSEQNO(mref),
138 NTFS_I(dent_inode)->seq_no);
139 iput(dent_inode);
140 dent_inode = ERR_PTR(-EIO);
141 } else
142 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
143 "error code %li.", dent_ino,
144 PTR_ERR(dent_inode));
145 if (name)
146 kfree(name);
147 /* Return the error code. */
148 return (struct dentry *)dent_inode;
149 }
150 /* It is guaranteed that name is no longer allocated at this point. */
151 if (MREF_ERR(mref) == -ENOENT) {
152 ntfs_debug("Entry was not found, adding negative dentry.");
153 /* The dcache will handle negative entries. */
154 d_add(dent, NULL);
155 ntfs_debug("Done.");
156 return NULL;
157 }
158 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
159 "code %i.", -MREF_ERR(mref));
160 return ERR_PTR(MREF_ERR(mref));
161
162 // TODO: Consider moving this lot to a separate function! (AIA)
163 handle_name:
164 {
165 struct dentry *real_dent;
166 MFT_RECORD *m;
167 attr_search_context *ctx;
168 ntfs_inode *ni = NTFS_I(dent_inode);
169 int err;
170 struct qstr nls_name;
171
172 nls_name.name = NULL;
173 if (name->type != FILE_NAME_DOS) { /* Case 2. */
174 nls_name.len = (unsigned)ntfs_ucstonls(vol,
175 (uchar_t*)&name->name, name->len,
176 (unsigned char**)&nls_name.name,
177 name->len * 3 + 1);
178 kfree(name);
179 } else /* if (name->type == FILE_NAME_DOS) */ { /* Case 3. */
180 FILE_NAME_ATTR *fn;
181
182 kfree(name);
183
184 /* Find the WIN32 name corresponding to the matched DOS name. */
185 ni = NTFS_I(dent_inode);
186 m = map_mft_record(ni);
187 if (IS_ERR(m)) {
188 err = PTR_ERR(m);
189 m = NULL;
190 ctx = NULL;
191 goto err_out;
192 }
193 ctx = get_attr_search_ctx(ni, m);
194 if (!ctx) {
195 err = -ENOMEM;
196 goto err_out;
197 }
198 do {
199 ATTR_RECORD *a;
200 u32 val_len;
201
202 if (!lookup_attr(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0,
203 ctx)) {
204 ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
205 "namespace counterpart to DOS "
206 "file name. Run chkdsk.");
207 err = -EIO;
208 goto err_out;
209 }
210 /* Consistency checks. */
211 a = ctx->attr;
212 if (a->non_resident || a->flags)
213 goto eio_err_out;
214 val_len = le32_to_cpu(a->data.resident.value_length);
215 if (le16_to_cpu(a->data.resident.value_offset) +
216 val_len > le32_to_cpu(a->length))
217 goto eio_err_out;
218 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
219 ctx->attr->data.resident.value_offset));
220 if ((u32)(fn->file_name_length * sizeof(uchar_t) +
221 sizeof(FILE_NAME_ATTR)) > val_len)
222 goto eio_err_out;
223 } while (fn->file_name_type != FILE_NAME_WIN32);
224
225 /* Convert the found WIN32 name to current NLS code page. */
226 nls_name.len = (unsigned)ntfs_ucstonls(vol,
227 (uchar_t*)&fn->file_name, fn->file_name_length,
228 (unsigned char**)&nls_name.name,
229 fn->file_name_length * 3 + 1);
230
231 put_attr_search_ctx(ctx);
232 unmap_mft_record(ni);
233 }
234 m = NULL;
235 ctx = NULL;
236
237 /* Check if a conversion error occurred. */
238 if ((signed)nls_name.len < 0) {
239 err = (signed)nls_name.len;
240 goto err_out;
241 }
242 nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
243
244 /*
245 * Note: No need for dent->d_lock lock as i_sem is held on the
246 * parent inode.
247 */
248
249 /* Does a dentry matching the nls_name exist already? */
250 real_dent = d_lookup(dent->d_parent, &nls_name);
251 /* If not, create it now. */
252 if (!real_dent) {
253 real_dent = d_alloc(dent->d_parent, &nls_name);
254 kfree(nls_name.name);
255 if (!real_dent) {
256 err = -ENOMEM;
257 goto err_out;
258 }
259 d_add(real_dent, dent_inode);
260 return real_dent;
261 }
262 kfree(nls_name.name);
263 /* Matching dentry exists, check if it is negative. */
264 if (real_dent->d_inode) {
265 BUG_ON(real_dent->d_inode != dent_inode);
266 /*
267 * Already have the inode and the dentry attached, decrement
268 * the reference count to balance the ntfs_iget() we did
269 * earlier on.
270 */
271 iput(dent_inode);
272 return real_dent;
273 }
274 /* Negative dentry: instantiate it. */
275 d_instantiate(real_dent, dent_inode);
276 return real_dent;
277
278 eio_err_out:
279 ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
280 err = -EIO;
281 err_out:
282 if (ctx)
283 put_attr_search_ctx(ctx);
284 if (m)
285 unmap_mft_record(ni);
286 iput(dent_inode);
287 return ERR_PTR(err);
288 }
289 }
290
291 /*
292 * Inode operations for directories.
293 */
294 struct inode_operations ntfs_dir_inode_ops = {
295 .lookup = ntfs_lookup, /* VFS: Lookup directory. */
296 };
297