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 MFT_RECORD *m;
178 ntfs_attr_search_ctx *ctx;
179 ntfs_inode *ni = NTFS_I(dent_inode);
180 int err;
181 struct qstr nls_name;
182
183 nls_name.name = NULL;
184 if (name->type != FILE_NAME_DOS) {
185 ntfs_debug("Case 2.");
186 nls_name.len = (unsigned)ntfs_ucstonls(vol,
187 (ntfschar*)&name->name, name->len,
188 (unsigned char**)&nls_name.name, 0);
189 kfree(name);
190 } else {
191 FILE_NAME_ATTR *fn;
192
193 ntfs_debug("Case 3.");
194 kfree(name);
195
196
197 ni = NTFS_I(dent_inode);
198 m = map_mft_record(ni);
199 if (IS_ERR(m)) {
200 err = PTR_ERR(m);
201 m = NULL;
202 ctx = NULL;
203 goto err_out;
204 }
205 ctx = ntfs_attr_get_search_ctx(ni, m);
206 if (unlikely(!ctx)) {
207 err = -ENOMEM;
208 goto err_out;
209 }
210 do {
211 ATTR_RECORD *a;
212 u32 val_len;
213
214 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
215 NULL, 0, ctx);
216 if (unlikely(err)) {
217 ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
218 "namespace counterpart to DOS "
219 "file name. Run chkdsk.");
220 if (err == -ENOENT)
221 err = -EIO;
222 goto err_out;
223 }
224
225 a = ctx->attr;
226 if (a->non_resident || a->flags)
227 goto eio_err_out;
228 val_len = le32_to_cpu(a->data.resident.value_length);
229 if (le16_to_cpu(a->data.resident.value_offset) +
230 val_len > le32_to_cpu(a->length))
231 goto eio_err_out;
232 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
233 ctx->attr->data.resident.value_offset));
234 if ((u32)(fn->file_name_length * sizeof(ntfschar) +
235 sizeof(FILE_NAME_ATTR)) > val_len)
236 goto eio_err_out;
237 } while (fn->file_name_type != FILE_NAME_WIN32);
238
239
240 nls_name.len = (unsigned)ntfs_ucstonls(vol,
241 (ntfschar*)&fn->file_name, fn->file_name_length,
242 (unsigned char**)&nls_name.name, 0);
243
244 ntfs_attr_put_search_ctx(ctx);
245 unmap_mft_record(ni);
246 }
247 m = NULL;
248 ctx = NULL;
249
250
251 if ((signed)nls_name.len < 0) {
252 err = (signed)nls_name.len;
253 goto err_out;
254 }
255 nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
256
257 dent = d_add_ci(dent, dent_inode, &nls_name);
258 kfree(nls_name.name);
259 return dent;
260
261eio_err_out:
262 ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
263 err = -EIO;
264err_out:
265 if (ctx)
266 ntfs_attr_put_search_ctx(ctx);
267 if (m)
268 unmap_mft_record(ni);
269 iput(dent_inode);
270 ntfs_error(vol->sb, "Failed, returning error code %i.", err);
271 return ERR_PTR(err);
272 }
273}
274
275
276
277
278const struct inode_operations ntfs_dir_inode_ops = {
279 .lookup = ntfs_lookup,
280};
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299static struct dentry *ntfs_get_parent(struct dentry *child_dent)
300{
301 struct inode *vi = child_dent->d_inode;
302 ntfs_inode *ni = NTFS_I(vi);
303 MFT_RECORD *mrec;
304 ntfs_attr_search_ctx *ctx;
305 ATTR_RECORD *attr;
306 FILE_NAME_ATTR *fn;
307 unsigned long parent_ino;
308 int err;
309
310 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
311
312 mrec = map_mft_record(ni);
313 if (IS_ERR(mrec))
314 return (struct dentry *)mrec;
315
316 ctx = ntfs_attr_get_search_ctx(ni, mrec);
317 if (unlikely(!ctx)) {
318 unmap_mft_record(ni);
319 return ERR_PTR(-ENOMEM);
320 }
321try_next:
322 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
323 0, ctx);
324 if (unlikely(err)) {
325 ntfs_attr_put_search_ctx(ctx);
326 unmap_mft_record(ni);
327 if (err == -ENOENT)
328 ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
329 "file name attribute. Run chkdsk.",
330 vi->i_ino);
331 return ERR_PTR(err);
332 }
333 attr = ctx->attr;
334 if (unlikely(attr->non_resident))
335 goto try_next;
336 fn = (FILE_NAME_ATTR *)((u8 *)attr +
337 le16_to_cpu(attr->data.resident.value_offset));
338 if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
339 (u8*)attr + le32_to_cpu(attr->length)))
340 goto try_next;
341
342 parent_ino = MREF_LE(fn->parent_directory);
343
344 ntfs_attr_put_search_ctx(ctx);
345 unmap_mft_record(ni);
346
347 return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
348}
349
350static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
351 u64 ino, u32 generation)
352{
353 struct inode *inode;
354
355 inode = ntfs_iget(sb, ino);
356 if (!IS_ERR(inode)) {
357 if (is_bad_inode(inode) || inode->i_generation != generation) {
358 iput(inode);
359 inode = ERR_PTR(-ESTALE);
360 }
361 }
362
363 return inode;
364}
365
366static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
367 int fh_len, int fh_type)
368{
369 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
370 ntfs_nfs_get_inode);
371}
372
373static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
374 int fh_len, int fh_type)
375{
376 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
377 ntfs_nfs_get_inode);
378}
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399const struct export_operations ntfs_export_ops = {
400 .get_parent = ntfs_get_parent,
401
402 .fh_to_dentry = ntfs_fh_to_dentry,
403 .fh_to_parent = ntfs_fh_to_parent,
404};
405