Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
namei.c
Go to the documentation of this file.
1 /*
2  * namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
3  * project.
4  *
5  * Copyright (c) 2001-2006 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 #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 
103 static 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  /* Convert the name of the dentry to Unicode. */
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);
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  /* Consistency check. */
134  if (is_bad_inode(dent_inode) || MSEQNO(mref) ==
135  NTFS_I(dent_inode)->seq_no ||
136  dent_ino == FILE_MFT) {
137  /* Perfect WIN32/POSIX match. -- Case 1. */
138  if (!name) {
139  ntfs_debug("Done. (Case 1.)");
140  return d_splice_alias(dent_inode, dent);
141  }
142  /*
143  * We are too indented. Handle imperfect
144  * matches and short file names further below.
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  /* Return the error code. */
162  return (struct dentry *)dent_inode;
163  }
164  /* It is guaranteed that @name is no longer allocated at this point. */
165  if (MREF_ERR(mref) == -ENOENT) {
166  ntfs_debug("Entry was not found, adding negative dentry.");
167  /* The dcache will handle negative entries. */
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  // TODO: Consider moving this lot to a separate function! (AIA)
176 handle_name:
177  {
178  MFT_RECORD *m;
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) { /* Case 2. */
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 /* if (name->type == FILE_NAME_DOS) */ { /* Case 3. */
192  FILE_NAME_ATTR *fn;
193 
194  ntfs_debug("Case 3.");
195  kfree(name);
196 
197  /* Find the WIN32 name corresponding to the matched DOS name. */
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  /* Consistency checks. */
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  /* Convert the found WIN32 name to current NLS code page. */
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 
246  unmap_mft_record(ni);
247  }
248  m = NULL;
249  ctx = NULL;
250 
251  /* Check if a conversion error occurred. */
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 
262 eio_err_out:
263  ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
264  err = -EIO;
265 err_out:
266  if (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 
280  .lookup = ntfs_lookup, /* VFS: Lookup directory. */
281 };
282 
300 static 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;
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  /* Get the mft record of the inode belonging to the child dentry. */
313  mrec = map_mft_record(ni);
314  if (IS_ERR(mrec))
315  return (struct dentry *)mrec;
316  /* Find the first file name attribute in the mft record. */
317  ctx = ntfs_attr_get_search_ctx(ni, mrec);
318  if (unlikely(!ctx)) {
319  unmap_mft_record(ni);
320  return ERR_PTR(-ENOMEM);
321  }
322 try_next:
324  0, ctx);
325  if (unlikely(err)) {
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  /* Get the inode number of the parent directory. */
343  parent_ino = MREF_LE(fn->parent_directory);
344  /* Release the search context and the mft record of the child. */
346  unmap_mft_record(ni);
347 
348  return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
349 }
350 
351 static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
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 
367 static 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 
374 static 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 
401  .get_parent = ntfs_get_parent, /* Find the parent of a given
402  directory. */
403  .fh_to_dentry = ntfs_fh_to_dentry,
404  .fh_to_parent = ntfs_fh_to_parent,
405 };