0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/dcache.h>
0010 #include <linux/exportfs.h>
0011 #include <linux/security.h>
0012 #include <linux/slab.h>
0013
0014 #include "attrib.h"
0015 #include "debug.h"
0016 #include "dir.h"
0017 #include "mft.h"
0018 #include "ntfs.h"
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
0090 unsigned int flags)
0091 {
0092 ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
0093 struct inode *dent_inode;
0094 ntfschar *uname;
0095 ntfs_name *name = NULL;
0096 MFT_REF mref;
0097 unsigned long dent_ino;
0098 int uname_len;
0099
0100 ntfs_debug("Looking up %pd in directory inode 0x%lx.",
0101 dent, dir_ino->i_ino);
0102
0103 uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len,
0104 &uname);
0105 if (uname_len < 0) {
0106 if (uname_len != -ENAMETOOLONG)
0107 ntfs_error(vol->sb, "Failed to convert name to "
0108 "Unicode.");
0109 return ERR_PTR(uname_len);
0110 }
0111 mref = ntfs_lookup_inode_by_name(NTFS_I(dir_ino), uname, uname_len,
0112 &name);
0113 kmem_cache_free(ntfs_name_cache, uname);
0114 if (!IS_ERR_MREF(mref)) {
0115 dent_ino = MREF(mref);
0116 ntfs_debug("Found inode 0x%lx. Calling ntfs_iget.", dent_ino);
0117 dent_inode = ntfs_iget(vol->sb, dent_ino);
0118 if (!IS_ERR(dent_inode)) {
0119
0120 if (is_bad_inode(dent_inode) || MSEQNO(mref) ==
0121 NTFS_I(dent_inode)->seq_no ||
0122 dent_ino == FILE_MFT) {
0123
0124 if (!name) {
0125 ntfs_debug("Done. (Case 1.)");
0126 return d_splice_alias(dent_inode, dent);
0127 }
0128
0129
0130
0131
0132 goto handle_name;
0133 }
0134 ntfs_error(vol->sb, "Found stale reference to inode "
0135 "0x%lx (reference sequence number = "
0136 "0x%x, inode sequence number = 0x%x), "
0137 "returning -EIO. Run chkdsk.",
0138 dent_ino, MSEQNO(mref),
0139 NTFS_I(dent_inode)->seq_no);
0140 iput(dent_inode);
0141 dent_inode = ERR_PTR(-EIO);
0142 } else
0143 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
0144 "error code %li.", dent_ino,
0145 PTR_ERR(dent_inode));
0146 kfree(name);
0147
0148 return ERR_CAST(dent_inode);
0149 }
0150
0151 if (MREF_ERR(mref) == -ENOENT) {
0152 ntfs_debug("Entry was not found, adding negative dentry.");
0153
0154 d_add(dent, NULL);
0155 ntfs_debug("Done.");
0156 return NULL;
0157 }
0158 ntfs_error(vol->sb, "ntfs_lookup_ino_by_name() failed with error "
0159 "code %i.", -MREF_ERR(mref));
0160 return ERR_PTR(MREF_ERR(mref));
0161
0162 handle_name:
0163 {
0164 MFT_RECORD *m;
0165 ntfs_attr_search_ctx *ctx;
0166 ntfs_inode *ni = NTFS_I(dent_inode);
0167 int err;
0168 struct qstr nls_name;
0169
0170 nls_name.name = NULL;
0171 if (name->type != FILE_NAME_DOS) {
0172 ntfs_debug("Case 2.");
0173 nls_name.len = (unsigned)ntfs_ucstonls(vol,
0174 (ntfschar*)&name->name, name->len,
0175 (unsigned char**)&nls_name.name, 0);
0176 kfree(name);
0177 } else {
0178 FILE_NAME_ATTR *fn;
0179
0180 ntfs_debug("Case 3.");
0181 kfree(name);
0182
0183
0184 ni = NTFS_I(dent_inode);
0185 m = map_mft_record(ni);
0186 if (IS_ERR(m)) {
0187 err = PTR_ERR(m);
0188 m = NULL;
0189 ctx = NULL;
0190 goto err_out;
0191 }
0192 ctx = ntfs_attr_get_search_ctx(ni, m);
0193 if (unlikely(!ctx)) {
0194 err = -ENOMEM;
0195 goto err_out;
0196 }
0197 do {
0198 ATTR_RECORD *a;
0199 u32 val_len;
0200
0201 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
0202 NULL, 0, ctx);
0203 if (unlikely(err)) {
0204 ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
0205 "namespace counterpart to DOS "
0206 "file name. Run chkdsk.");
0207 if (err == -ENOENT)
0208 err = -EIO;
0209 goto err_out;
0210 }
0211
0212 a = ctx->attr;
0213 if (a->non_resident || a->flags)
0214 goto eio_err_out;
0215 val_len = le32_to_cpu(a->data.resident.value_length);
0216 if (le16_to_cpu(a->data.resident.value_offset) +
0217 val_len > le32_to_cpu(a->length))
0218 goto eio_err_out;
0219 fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
0220 ctx->attr->data.resident.value_offset));
0221 if ((u32)(fn->file_name_length * sizeof(ntfschar) +
0222 sizeof(FILE_NAME_ATTR)) > val_len)
0223 goto eio_err_out;
0224 } while (fn->file_name_type != FILE_NAME_WIN32);
0225
0226
0227 nls_name.len = (unsigned)ntfs_ucstonls(vol,
0228 (ntfschar*)&fn->file_name, fn->file_name_length,
0229 (unsigned char**)&nls_name.name, 0);
0230
0231 ntfs_attr_put_search_ctx(ctx);
0232 unmap_mft_record(ni);
0233 }
0234 m = NULL;
0235 ctx = NULL;
0236
0237
0238 if ((signed)nls_name.len < 0) {
0239 err = (signed)nls_name.len;
0240 goto err_out;
0241 }
0242 nls_name.hash = full_name_hash(dent, nls_name.name, nls_name.len);
0243
0244 dent = d_add_ci(dent, dent_inode, &nls_name);
0245 kfree(nls_name.name);
0246 return dent;
0247
0248 eio_err_out:
0249 ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
0250 err = -EIO;
0251 err_out:
0252 if (ctx)
0253 ntfs_attr_put_search_ctx(ctx);
0254 if (m)
0255 unmap_mft_record(ni);
0256 iput(dent_inode);
0257 ntfs_error(vol->sb, "Failed, returning error code %i.", err);
0258 return ERR_PTR(err);
0259 }
0260 }
0261
0262
0263
0264
0265 const struct inode_operations ntfs_dir_inode_ops = {
0266 .lookup = ntfs_lookup,
0267 };
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286 static struct dentry *ntfs_get_parent(struct dentry *child_dent)
0287 {
0288 struct inode *vi = d_inode(child_dent);
0289 ntfs_inode *ni = NTFS_I(vi);
0290 MFT_RECORD *mrec;
0291 ntfs_attr_search_ctx *ctx;
0292 ATTR_RECORD *attr;
0293 FILE_NAME_ATTR *fn;
0294 unsigned long parent_ino;
0295 int err;
0296
0297 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
0298
0299 mrec = map_mft_record(ni);
0300 if (IS_ERR(mrec))
0301 return ERR_CAST(mrec);
0302
0303 ctx = ntfs_attr_get_search_ctx(ni, mrec);
0304 if (unlikely(!ctx)) {
0305 unmap_mft_record(ni);
0306 return ERR_PTR(-ENOMEM);
0307 }
0308 try_next:
0309 err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
0310 0, ctx);
0311 if (unlikely(err)) {
0312 ntfs_attr_put_search_ctx(ctx);
0313 unmap_mft_record(ni);
0314 if (err == -ENOENT)
0315 ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
0316 "file name attribute. Run chkdsk.",
0317 vi->i_ino);
0318 return ERR_PTR(err);
0319 }
0320 attr = ctx->attr;
0321 if (unlikely(attr->non_resident))
0322 goto try_next;
0323 fn = (FILE_NAME_ATTR *)((u8 *)attr +
0324 le16_to_cpu(attr->data.resident.value_offset));
0325 if (unlikely((u8 *)fn + le32_to_cpu(attr->data.resident.value_length) >
0326 (u8*)attr + le32_to_cpu(attr->length)))
0327 goto try_next;
0328
0329 parent_ino = MREF_LE(fn->parent_directory);
0330
0331 ntfs_attr_put_search_ctx(ctx);
0332 unmap_mft_record(ni);
0333
0334 return d_obtain_alias(ntfs_iget(vi->i_sb, parent_ino));
0335 }
0336
0337 static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
0338 u64 ino, u32 generation)
0339 {
0340 struct inode *inode;
0341
0342 inode = ntfs_iget(sb, ino);
0343 if (!IS_ERR(inode)) {
0344 if (is_bad_inode(inode) || inode->i_generation != generation) {
0345 iput(inode);
0346 inode = ERR_PTR(-ESTALE);
0347 }
0348 }
0349
0350 return inode;
0351 }
0352
0353 static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
0354 int fh_len, int fh_type)
0355 {
0356 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
0357 ntfs_nfs_get_inode);
0358 }
0359
0360 static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
0361 int fh_len, int fh_type)
0362 {
0363 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
0364 ntfs_nfs_get_inode);
0365 }
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 const struct export_operations ntfs_export_ops = {
0387 .get_parent = ntfs_get_parent,
0388
0389 .fh_to_dentry = ntfs_fh_to_dentry,
0390 .fh_to_parent = ntfs_fh_to_parent,
0391 };