1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/dcache.h>
24#include <linux/exportfs.h>
25#include <linux/security.h>
26
27#include "attrib.h"
28#include "debug.h"
29#include "dir.h"
30#include "mft.h"
31#include "ntfs.h"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
103 struct nameidata *nd)
104{
105 ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
106 struct inode *dent_inode;
107 ntfschar *uname;
108 ntfs_name *name = NULL;
109 MFT_REF mref;
110 unsigned long dent_ino;
111 int uname_len;
112
113 ntfs_debug("Looking up %s in directory inode 0x%lx.",
114 dent->d_name.name, dir_ino->i_ino);
115
116 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
117 &uname);
118 if (uname_len < 0) {
119 if (uname_len != -ENAMETOOLONG)
120 ntfs_error(vol->sb, "Failed to convert name to "
121 "Unicode.");
122 return ERR_PTR(uname_len);
123 }
124 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
125 &name);
126 kmem_cache_free(ntfs_name_cache, uname);
127 if (!IS_ERR_MREF(mref)) {
128 dent_ino = MREF(mref);
129 ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
130 dent_inode = ntfs_iget(vol->sb, dent_ino);
131 if (likely(!IS_ERR(dent_inode))) {
132
133 if (is_bad_inode(dent_inode) || MSEQNO(mref) ==
134 NTFS_I(dent_inode)->seq_no ||
135 dent_ino == FILE_MFT) {
136
137 if (!name) {
138 ntfs_debug("Done. (Case 1.)");
139 return d_splice_alias(dent_inode, dent);
140 }
141
142
143
144
145 goto handle_name;
146 }
147 ntfs_error(vol->sb, "Found stale reference to inode "
148 "0x%lx (reference sequence number = "
149 "0x%x, inode sequence number = 0x%x), "
150 "returning -EIO. Run chkdsk.",
151 dent_ino, MSEQNO(mref),
152 NTFS_I(dent_inode)->seq_no);
153 iput(dent_inode);
154 dent_inode = ERR_PTR(-EIO);
155 } else
156 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
157 "error code %li.", dent_ino,
158 PTR_ERR(dent_inode));
159 kfree(name);
160
161 return (struct dentry *)dent_inode;
162 }
163
164 if (MREF_ERR(mref) == -ENOENT) {
165 ntfs_debug("Entry was not found, adding negative dentry.");
166
167 d_add(dent, NULL);
168 ntfs_debug("Done.");
169 return NULL;
170 }
171 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
172 "code %i.", -MREF_ERR(mref));
173 return ERR_PTR(MREF_ERR(mref));
174
175handle_name:
176 {
177 struct dentry *real_dent, *new_dent;
178 MFT_RECORD *m;
179 ntfs_attr_search_ctx *ctx;
180 ntfs_inode *ni = NTFS_I(dent_inode);
181 int err;
182 struct qstr nls_name;
183
184 nls_name.name = NULL;
185 if (name->type != FILE_NAME_DOS) {
186 ntfs_debug("Case 2.");
187 nls_name.len = (unsigned)ntfs_ucstonls(vol,
188 (ntfschar*)&name->name, name->len,
189 (unsigned char**)&nls_name.name, 0);
190 kfree(name);
191 } else {
192 FILE_NAME_ATTR *fn;
193
194 ntfs_debug("Case 3.");
195 kfree(name);
196
197
198 ni = NTFS_I(dent_inode);
199 m = map_mft_record(ni);
200 if (IS_ERR(m)) {
201 err = PTR_ERR(m);
202 m = NULL;
203 ctx = NULL;
204 goto err_out;
205 }
206 ctx = ntfs_attr_get_search_ctx(ni, m);
207 if (unlikely(!ctx)) {
208 err = -ENOMEM;
209 goto err_out;
210 }
211 do {
212 ATTR_RECORD *a;
213 u32 val_len;
214
215 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
216 NULL, 0, ctx);
217 if (unlikely(err)) {
218 ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
219 "namespace counterpart to DOS "
220 "file name. Run chkdsk.");
221 if (err == -ENOENT)
222 err = -EIO;
223 goto err_out;
224 }
225
226 a = ctx->attr;
227 if (a->non_resident || a->flags)
228 goto eio_err_out;
229 val_len = le32_to_cpu(a->data.resident.value_length);
230 if (le16_to_cpu(a->data.resident.value_offset) +
231 val_len > le32_to_cpu(a->length))
232 goto eio_err_out;
233 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
234 ctx->attr->data.resident.value_offset));
235 if ((u32)(fn->file_name_length * sizeof(ntfschar) +
236 sizeof(FILE_NAME_ATTR)) > val_len)
237 goto eio_err_out;
238 } while (fn->file_name_type != FILE_NAME_WIN32);
239
240
241 nls_name.len = (unsigned)ntfs_ucstonls(vol,
242 (ntfschar*)&fn->file_name, fn->file_name_length,
243 (unsigned char**)&nls_name.name, 0);
244
245 ntfs_attr_put_search_ctx(ctx);
246 unmap_mft_record(ni);
247 }
248 m = NULL;
249 ctx = NULL;
250
251
252 if ((signed)nls_name.len < 0) {
253 err = (signed)nls_name.len;
254 goto err_out;
255 }
256 nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
257
258
259
260
261
262
263
264 real_dent = d_lookup(dent->d_parent, &nls_name);
265
266 if (!real_dent) {
267 real_dent = d_alloc(dent->d_parent, &nls_name);
268 kfree(nls_name.name);
269 if (!real_dent) {
270 err = -ENOMEM;
271 goto err_out;
272 }
273 new_dent = d_splice_alias(dent_inode, real_dent);
274 if (new_dent)
275 dput(real_dent);
276 else
277 new_dent = real_dent;
278 ntfs_debug("Done. (Created new dentry.)");
279 return new_dent;
280 }
281 kfree(nls_name.name);
282
283 if (real_dent->d_inode) {
284 if (unlikely(real_dent->d_inode != dent_inode)) {
285
286 BUG_ON(!is_bad_inode(dent_inode));
287 BUG_ON(!is_bad_inode(real_dent->d_inode));
288 }
289
290
291
292
293
294
295
296 iput(dent_inode);
297 ntfs_debug("Done. (Already had inode and dentry.)");
298 return real_dent;
299 }
300
301
302
303
304
305 if (!S_ISDIR(dent_inode->i_mode)) {
306
307 d_instantiate(real_dent, dent_inode);
308 ntfs_debug("Done. (Already had negative file dentry.)");
309 return real_dent;
310 }
311 spin_lock(&dcache_lock);
312 if (list_empty(&dent_inode->i_dentry)) {
313
314
315
316
317
318 list_add(&real_dent->d_alias, &dent_inode->i_dentry);
319 real_dent->d_inode = dent_inode;
320 spin_unlock(&dcache_lock);
321 security_d_instantiate(real_dent, dent_inode);
322 ntfs_debug("Done. (Already had negative directory dentry.)");
323 return real_dent;
324 }
325
326
327
328
329 new_dent = list_entry(dent_inode->i_dentry.next, struct dentry,
330 d_alias);
331 dget_locked(new_dent);
332 spin_unlock(&dcache_lock);
333
334 security_d_instantiate(real_dent, dent_inode);
335
336 d_move(new_dent, real_dent);
337
338 iput(dent_inode);
339
340 dput(real_dent);
341
342 ntfs_debug("Done. (Already had negative, disconnected directory "
343 "dentry.)");
344 return new_dent;
345
346eio_err_out:
347 ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
348 err = -EIO;
349err_out:
350 if (ctx)
351 ntfs_attr_put_search_ctx(ctx);
352 if (m)
353 unmap_mft_record(ni);
354 iput(dent_inode);
355 ntfs_error(vol->sb, "Failed, returning error code %i.", err);
356 return ERR_PTR(err);
357 }
358}
359
360
361
362
363const struct inode_operations ntfs_dir_inode_ops = {
364 .lookup = ntfs_lookup,
365};
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384static struct dentry *ntfs_get_parent(struct dentry *child_dent)
385{
386 struct inode *vi = child_dent->d_inode;
387 ntfs_inode *ni = NTFS_I(vi);
388 MFT_RECORD *mrec;
389 ntfs_attr_search_ctx *ctx;
390 ATTR_RECORD *attr;
391 FILE_NAME_ATTR *fn;
392 struct inode *parent_vi;
393 struct dentry *parent_dent;
394 unsigned long parent_ino;
395 int err;
396
397 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
398
399 mrec = map_mft_record(ni);
400 if (IS_ERR(mrec))
401 return (struct dentry *)mrec;
402
403 ctx = ntfs_attr_get_search_ctx(ni, mrec);
404 if (unlikely(!ctx)) {
405 unmap_mft_record(ni);
406 return ERR_PTR(-ENOMEM);
407 }
408try_next:
409 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
410 0, ctx);
411 if (unlikely(err)) {
412 ntfs_attr_put_search_ctx(ctx);
413 unmap_mft_record(ni);
414 if (err == -ENOENT)
415 ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
416 "file name attribute. Run chkdsk.",
417 vi->i_ino);
418 return ERR_PTR(err);
419 }
420 attr = ctx->attr;
421 if (unlikely(attr->non_resident))
422 goto try_next;
423 fn = (FILE_NAME_ATTR *)((u8 *)attr +
424 le16_to_cpu(attr->data.resident.value_offset));
425 if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
426 (u8*)attr + le32_to_cpu(attr->length)))
427 goto try_next;
428
429 parent_ino = MREF_LE(fn->parent_directory);
430
431 ntfs_attr_put_search_ctx(ctx);
432 unmap_mft_record(ni);
433
434 parent_vi = ntfs_iget(vi->i_sb, parent_ino);
435 if (IS_ERR(parent_vi) || unlikely(is_bad_inode(parent_vi))) {
436 if (!IS_ERR(parent_vi))
437 iput(parent_vi);
438 ntfs_error(vi->i_sb, "Failed to get parent directory inode "
439 "0x%lx of child inode 0x%lx.", parent_ino,
440 vi->i_ino);
441 return ERR_PTR(-EACCES);
442 }
443
444 parent_dent = d_alloc_anon(parent_vi);
445 if (unlikely(!parent_dent)) {
446 iput(parent_vi);
447 return ERR_PTR(-ENOMEM);
448 }
449 ntfs_debug("Done for inode 0x%lx.", vi->i_ino);
450 return parent_dent;
451}
452
453static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
454 u64 ino, u32 generation)
455{
456 struct inode *inode;
457
458 inode = ntfs_iget(sb, ino);
459 if (!IS_ERR(inode)) {
460 if (is_bad_inode(inode) || inode->i_generation != generation) {
461 iput(inode);
462 inode = ERR_PTR(-ESTALE);
463 }
464 }
465
466 return inode;
467}
468
469static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
470 int fh_len, int fh_type)
471{
472 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
473 ntfs_nfs_get_inode);
474}
475
476static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
477 int fh_len, int fh_type)
478{
479 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
480 ntfs_nfs_get_inode);
481}
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502const struct export_operations ntfs_export_ops = {
503 .get_parent = ntfs_get_parent,
504
505 .fh_to_dentry = ntfs_fh_to_dentry,
506 .fh_to_parent = ntfs_fh_to_parent,
507};
508