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#include <linux/slab.h>
27
28#include "attrib.h"
29#include "debug.h"
30#include "dir.h"
31#include "mft.h"
32#include "ntfs.h"
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
102
103static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
104 unsigned int flags)
105{
106 ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
107 struct inode *dent_inode;
108 ntfschar *uname;
109 ntfs_name *name = NULL;
110 MFT_REF mref;
111 unsigned long dent_ino;
112 int uname_len;
113
114 ntfs_debug("Looking up %s in directory inode 0x%lx.",
115 dent->d_name.name, dir_ino->i_ino);
116
117 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
118 &uname);
119 if (uname_len < 0) {
120 if (uname_len != -ENAMETOOLONG)
121 ntfs_error(vol->sb, "Failed to convert name to "
122 "Unicode.");
123 return ERR_PTR(uname_len);
124 }
125 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
126 &name);
127 kmem_cache_free(ntfs_name_cache, uname);
128 if (!IS_ERR_MREF(mref)) {
129 dent_ino = MREF(mref);
130 ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
131 dent_inode = ntfs_iget(vol->sb, dent_ino);
132 if (likely(!IS_ERR(dent_inode))) {
133
134 if (is_bad_inode(dent_inode) || MSEQNO(mref) ==
135 NTFS_I(dent_inode)->seq_no ||
136 dent_ino == FILE_MFT) {
137
138 if (!name) {
139 ntfs_debug("Done. (Case 1.)");
140 return d_splice_alias(dent_inode, dent);
141 }
142
143
144
145
146 goto handle_name;
147 }
148 ntfs_error(vol->sb, "Found stale reference to inode "
149 "0x%lx (reference sequence number = "
150 "0x%x, inode sequence number = 0x%x), "
151 "returning -EIO. Run chkdsk.",
152 dent_ino, MSEQNO(mref),
153 NTFS_I(dent_inode)->seq_no);
154 iput(dent_inode);
155 dent_inode = ERR_PTR(-EIO);
156 } else
157 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
158 "error code %li.", dent_ino,
159 PTR_ERR(dent_inode));
160 kfree(name);
161
162 return (struct dentry *)dent_inode;
163 }
164
165 if (MREF_ERR(mref) == -ENOENT) {
166 ntfs_debug("Entry was not found, adding negative dentry.");
167
168 d_add(dent, NULL);
169 ntfs_debug("Done.");
170 return NULL;
171 }
172 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
173 "code %i.", -MREF_ERR(mref));
174 return ERR_PTR(MREF_ERR(mref));
175
176handle_name:
177 {
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 dent = d_add_ci(dent, dent_inode, &nls_name);
259 kfree(nls_name.name);
260 return dent;
261
262eio_err_out:
263 ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
264 err = -EIO;
265err_out:
266 if (ctx)
267 ntfs_attr_put_search_ctx(ctx);
268 if (m)
269 unmap_mft_record(ni);
270 iput(dent_inode);
271 ntfs_error(vol->sb, "Failed, returning error code %i.", err);
272 return ERR_PTR(err);
273 }
274}
275
276
277
278
279const struct inode_operations ntfs_dir_inode_ops = {
280 .lookup = ntfs_lookup,
281};
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300static struct dentry *ntfs_get_parent(struct dentry *child_dent)
301{
302 struct inode *vi = child_dent->d_inode;
303 ntfs_inode *ni = NTFS_I(vi);
304 MFT_RECORD *mrec;
305 ntfs_attr_search_ctx *ctx;
306 ATTR_RECORD *attr;
307 FILE_NAME_ATTR *fn;
308 unsigned long parent_ino;
309 int err;
310
311 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
312
313 mrec = map_mft_record(ni);
314 if (IS_ERR(mrec))
315 return (struct dentry *)mrec;
316
317 ctx = ntfs_attr_get_search_ctx(ni, mrec);
318 if (unlikely(!ctx)) {
319 unmap_mft_record(ni);
320 return ERR_PTR(-ENOMEM);
321 }
322try_next:
323 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
324 0, ctx);
325 if (unlikely(err)) {
326 ntfs_attr_put_search_ctx(ctx);
327 unmap_mft_record(ni);
328 if (err == -ENOENT)
329 ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
330 "file name attribute. Run chkdsk.",
331 vi->i_ino);
332 return ERR_PTR(err);
333 }
334 attr = ctx->attr;
335 if (unlikely(attr->non_resident))
336 goto try_next;
337 fn = (FILE_NAME_ATTR *)((u8 *)attr +
338 le16_to_cpu(attr->data.resident.value_offset));
339 if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
340 (u8*)attr + le32_to_cpu(attr->length)))
341 goto try_next;
342
343 parent_ino = MREF_LE(fn->parent_directory);
344
345 ntfs_attr_put_search_ctx(ctx);
346 unmap_mft_record(ni);
347
348 return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
349}
350
351static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
352 u64 ino, u32 generation)
353{
354 struct inode *inode;
355
356 inode = ntfs_iget(sb, ino);
357 if (!IS_ERR(inode)) {
358 if (is_bad_inode(inode) || inode->i_generation != generation) {
359 iput(inode);
360 inode = ERR_PTR(-ESTALE);
361 }
362 }
363
364 return inode;
365}
366
367static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
368 int fh_len, int fh_type)
369{
370 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
371 ntfs_nfs_get_inode);
372}
373
374static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
375 int fh_len, int fh_type)
376{
377 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
378 ntfs_nfs_get_inode);
379}
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400const struct export_operations ntfs_export_ops = {
401 .get_parent = ntfs_get_parent,
402
403 .fh_to_dentry = ntfs_fh_to_dentry,
404 .fh_to_parent = ntfs_fh_to_parent,
405};
406