Commit c801720c authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: - Fix endianness bug in ntfs_external_attr_find().

      - Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT
	if the attribute is not found, and -EIO on real error.  In the case
	of -ENOENT, the search context is updated to describe the attribute
	before which the attribute being searched for would need to be
	inserted if such an action were to be desired and in the case of
	ntfs_external_attr_find() the search context is also updated to
	indicate the attribute list entry before which the attribute list
	entry of the attribute being searched for would need to be inserted
	if such an action were to be desired.  Also make ntfs_find_attr()
	static and remove its prototype from attrib.h as it is not used
	anywhere other than attrib.c.  Update ntfs_attr_lookup() and all
	callers of ntfs_{external,}attr_{find,lookup}() for the new return
	values.
      - Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching
	for the attribute list attribute itself.
Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent ecd731d4
...@@ -38,6 +38,22 @@ ToDo/Notes: ...@@ -38,6 +38,22 @@ ToDo/Notes:
- Rename {{re,}init,get,put}_attr_search_ctx() to - Rename {{re,}init,get,put}_attr_search_ctx() to
ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type
attr_search_context to ntfs_attr_search_ctx. attr_search_context to ntfs_attr_search_ctx.
- Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching
for the attribute list attribute itself.
- Fix endianness bug in ntfs_external_attr_find().
- Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT
if the attribute is not found, and -EIO on real error. In the case
of -ENOENT, the search context is updated to describe the attribute
before which the attribute being searched for would need to be
inserted if such an action were to be desired and in the case of
ntfs_external_attr_find() the search context is also updated to
indicate the attribute list entry before which the attribute list
entry of the attribute being searched for would need to be inserted
if such an action were to be desired. Also make ntfs_find_attr()
static and remove its prototype from attrib.h as it is not used
anywhere other than attrib.c. Update ntfs_attr_lookup() and all
callers of ntfs_{external,}attr_{find,lookup}() for the new return
values.
2.1.17 - Fix bugs in mount time error code paths and other updates. 2.1.17 - Fix bugs in mount time error code paths and other updates.
......
...@@ -402,11 +402,10 @@ int ntfs_readpage(struct file *file, struct page *page) ...@@ -402,11 +402,10 @@ int ntfs_readpage(struct file *file, struct page *page)
err = -ENOMEM; err = -ENOMEM;
goto unm_err_out; goto unm_err_out;
} }
if (unlikely(!ntfs_attr_lookup(ni->type, ni->name, ni->name_len, err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx))) { CASE_SENSITIVE, 0, NULL, 0, ctx);
err = -ENOENT; if (unlikely(err))
goto put_unm_err_out; goto put_unm_err_out;
}
/* Starting position of the page within the attribute value. */ /* Starting position of the page within the attribute value. */
attr_pos = page->index << PAGE_CACHE_SHIFT; attr_pos = page->index << PAGE_CACHE_SHIFT;
...@@ -1122,11 +1121,10 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) ...@@ -1122,11 +1121,10 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
if (unlikely(!ntfs_attr_lookup(ni->type, ni->name, ni->name_len, err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx))) { CASE_SENSITIVE, 0, NULL, 0, ctx);
err = -ENOENT; if (unlikely(err))
goto err_out; goto err_out;
}
/* Starting position of the page within the attribute value. */ /* Starting position of the page within the attribute value. */
attr_pos = page->index << PAGE_CACHE_SHIFT; attr_pos = page->index << PAGE_CACHE_SHIFT;
...@@ -1896,11 +1894,10 @@ static int ntfs_commit_write(struct file *file, struct page *page, ...@@ -1896,11 +1894,10 @@ static int ntfs_commit_write(struct file *file, struct page *page,
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
if (unlikely(!ntfs_attr_lookup(ni->type, ni->name, ni->name_len, err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx))) { CASE_SENSITIVE, 0, NULL, 0, ctx);
err = -ENOENT; if (unlikely(err))
goto err_out; goto err_out;
}
/* Starting position of the page within the attribute value. */ /* Starting position of the page within the attribute value. */
attr_pos = page->index << PAGE_CACHE_SHIFT; attr_pos = page->index << PAGE_CACHE_SHIFT;
......
This diff is collapsed.
...@@ -81,11 +81,7 @@ extern LCN ntfs_vcn_to_lcn(const runlist_element *rl, const VCN vcn); ...@@ -81,11 +81,7 @@ extern LCN ntfs_vcn_to_lcn(const runlist_element *rl, const VCN vcn);
extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn,
const BOOL need_write); const BOOL need_write);
extern BOOL ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name, int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
const u32 name_len, const IGNORE_CASE_BOOL ic, const u8 *val,
const u32 val_len, ntfs_attr_search_ctx *ctx);
BOOL ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
const u32 name_len, const IGNORE_CASE_BOOL ic, const u32 name_len, const IGNORE_CASE_BOOL ic,
const VCN lowest_vcn, const u8 *val, const u32 val_len, const VCN lowest_vcn, const u8 *val, const u32 val_len,
ntfs_attr_search_ctx *ctx); ntfs_attr_search_ctx *ctx);
......
...@@ -106,11 +106,15 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname, ...@@ -106,11 +106,15 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
goto err_out; goto err_out;
} }
/* Find the index root attribute in the mft record. */ /* Find the index root attribute in the mft record. */
if (!ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
0, ctx)) { 0, ctx);
ntfs_error(sb, "Index root attribute missing in directory " if (unlikely(err)) {
"inode 0x%lx.", dir_ni->mft_no); if (err == -ENOENT) {
ntfs_error(sb, "Index root attribute missing in "
"directory inode 0x%lx.",
dir_ni->mft_no);
err = -EIO; err = -EIO;
}
goto err_out; goto err_out;
} }
/* Get to the index root value (it's been verified in read_inode). */ /* Get to the index root value (it's been verified in read_inode). */
...@@ -655,11 +659,15 @@ u64 ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname, ...@@ -655,11 +659,15 @@ u64 ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
goto err_out; goto err_out;
} }
/* Find the index root attribute in the mft record. */ /* Find the index root attribute in the mft record. */
if (!ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
0, ctx)) { 0, ctx);
ntfs_error(sb, "Index root attribute missing in directory " if (unlikely(err)) {
"inode 0x%lx.", dir_ni->mft_no); if (err == -ENOENT) {
ntfs_error(sb, "Index root attribute missing in "
"directory inode 0x%lx.",
dir_ni->mft_no);
err = -EIO; err = -EIO;
}
goto err_out; goto err_out;
} }
/* Get to the index root value (it's been verified in read_inode). */ /* Get to the index root value (it's been verified in read_inode). */
...@@ -1183,8 +1191,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -1183,8 +1191,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* Get the offset into the index root attribute. */ /* Get the offset into the index root attribute. */
ir_pos = (s64)fpos; ir_pos = (s64)fpos;
/* Find the index root attribute in the mft record. */ /* Find the index root attribute in the mft record. */
if (unlikely(!ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
0, NULL, 0, ctx))) { 0, ctx);
if (unlikely(err)) {
ntfs_error(sb, "Index root attribute missing in directory " ntfs_error(sb, "Index root attribute missing in directory "
"inode 0x%lx.", vdir->i_ino); "inode 0x%lx.", vdir->i_ino);
goto err_out; goto err_out;
......
...@@ -125,6 +125,7 @@ void ntfs_index_ctx_put(ntfs_index_context *ictx) ...@@ -125,6 +125,7 @@ void ntfs_index_ctx_put(ntfs_index_context *ictx)
int ntfs_index_lookup(const void *key, const int key_len, int ntfs_index_lookup(const void *key, const int key_len,
ntfs_index_context *ictx) ntfs_index_context *ictx)
{ {
VCN vcn, old_vcn;
ntfs_inode *idx_ni = ictx->idx_ni; ntfs_inode *idx_ni = ictx->idx_ni;
ntfs_volume *vol = idx_ni->vol; ntfs_volume *vol = idx_ni->vol;
struct super_block *sb = vol->sb; struct super_block *sb = vol->sb;
...@@ -133,13 +134,11 @@ int ntfs_index_lookup(const void *key, const int key_len, ...@@ -133,13 +134,11 @@ int ntfs_index_lookup(const void *key, const int key_len,
INDEX_ROOT *ir; INDEX_ROOT *ir;
INDEX_ENTRY *ie; INDEX_ENTRY *ie;
INDEX_ALLOCATION *ia; INDEX_ALLOCATION *ia;
u8 *index_end; u8 *index_end, *kaddr;
ntfs_attr_search_ctx *actx; ntfs_attr_search_ctx *actx;
int rc, err = 0;
VCN vcn, old_vcn;
struct address_space *ia_mapping; struct address_space *ia_mapping;
struct page *page; struct page *page;
u8 *kaddr; int rc, err = 0;
ntfs_debug("Entering."); ntfs_debug("Entering.");
BUG_ON(!NInoAttr(idx_ni)); BUG_ON(!NInoAttr(idx_ni));
...@@ -168,11 +167,14 @@ int ntfs_index_lookup(const void *key, const int key_len, ...@@ -168,11 +167,14 @@ int ntfs_index_lookup(const void *key, const int key_len,
goto err_out; goto err_out;
} }
/* Find the index root attribute in the mft record. */ /* Find the index root attribute in the mft record. */
if (!ntfs_attr_lookup(AT_INDEX_ROOT, idx_ni->name, idx_ni->name_len, err = ntfs_attr_lookup(AT_INDEX_ROOT, idx_ni->name, idx_ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, actx)) { CASE_SENSITIVE, 0, NULL, 0, actx);
ntfs_error(sb, "Index root attribute missing in inode 0x%lx.", if (unlikely(err)) {
idx_ni->mft_no); if (err == -ENOENT) {
ntfs_error(sb, "Index root attribute missing in inode "
"0x%lx.", idx_ni->mft_no);
err = -EIO; err = -EIO;
}
goto err_out; goto err_out;
} }
/* Get to the index root value (it has been verified in read_inode). */ /* Get to the index root value (it has been verified in read_inode). */
......
...@@ -428,11 +428,11 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, ...@@ -428,11 +428,11 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
* Return values: * Return values:
* 1: file is in $Extend directory * 1: file is in $Extend directory
* 0: file is not in $Extend directory * 0: file is not in $Extend directory
* -EIO: file is corrupt * -errno: failed to determine if the file is in the $Extend directory
*/ */
static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx) static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx)
{ {
int nr_links; int nr_links, err;
/* Restart search. */ /* Restart search. */
ntfs_attr_reinit_search_ctx(ctx); ntfs_attr_reinit_search_ctx(ctx);
...@@ -441,7 +441,8 @@ static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx) ...@@ -441,7 +441,8 @@ static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx)
nr_links = le16_to_cpu(ctx->mrec->link_count); nr_links = le16_to_cpu(ctx->mrec->link_count);
/* Loop through all hard links. */ /* Loop through all hard links. */
while (ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) { while (!(err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0,
ctx))) {
FILE_NAME_ATTR *file_name_attr; FILE_NAME_ATTR *file_name_attr;
ATTR_RECORD *attr = ctx->attr; ATTR_RECORD *attr = ctx->attr;
u8 *p, *p2; u8 *p, *p2;
...@@ -484,7 +485,9 @@ static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx) ...@@ -484,7 +485,9 @@ static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx)
if (MREF_LE(file_name_attr->parent_directory) == FILE_Extend) if (MREF_LE(file_name_attr->parent_directory) == FILE_Extend)
return 1; /* YES, it's an extended system file. */ return 1; /* YES, it's an extended system file. */
} }
if (nr_links) { if (unlikely(err != -ENOENT))
return err;
if (unlikely(nr_links)) {
ntfs_error(ctx->ntfs_ino->vol->sb, "Inode hard link count " ntfs_error(ctx->ntfs_ino->vol->sb, "Inode hard link count "
"doesn't match number of name attributes. You " "doesn't match number of name attributes. You "
"should run chkdsk."); "should run chkdsk.");
...@@ -608,14 +611,18 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -608,14 +611,18 @@ static int ntfs_read_locked_inode(struct inode *vi)
* in fact fail if the standard information is in an extent record, but * in fact fail if the standard information is in an extent record, but
* I don't think this actually ever happens. * I don't think this actually ever happens.
*/ */
if (!ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0, 0, 0, NULL, 0, err = ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0, 0, 0, NULL, 0,
ctx)) { ctx);
if (unlikely(err)) {
if (err == -ENOENT) {
/* /*
* TODO: We should be performing a hot fix here (if the recover * TODO: We should be performing a hot fix here (if the
* mount option is set) by creating a new attribute. * recover mount option is set) by creating a new
* attribute.
*/ */
ntfs_error(vi->i_sb, "$STANDARD_INFORMATION attribute is " ntfs_error(vi->i_sb, "$STANDARD_INFORMATION attribute "
"missing."); "is missing.");
}
goto unm_err_out; goto unm_err_out;
} }
/* Get the standard information attribute value. */ /* Get the standard information attribute value. */
...@@ -647,7 +654,14 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -647,7 +654,14 @@ static int ntfs_read_locked_inode(struct inode *vi)
/* Find the attribute list attribute if present. */ /* Find the attribute list attribute if present. */
ntfs_attr_reinit_search_ctx(ctx); ntfs_attr_reinit_search_ctx(ctx);
if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx)) { err = ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx);
if (err) {
if (unlikely(err != -ENOENT)) {
ntfs_error(vi->i_sb, "Failed to lookup attribute list "
"attribute. You should run chkdsk.");
goto unm_err_out;
}
} else /* if (!err) */ {
if (vi->i_ino == FILE_MFT) if (vi->i_ino == FILE_MFT)
goto skip_attr_list_load; goto skip_attr_list_load;
ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino); ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino);
...@@ -734,12 +748,16 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -734,12 +748,16 @@ static int ntfs_read_locked_inode(struct inode *vi)
/* It is a directory, find index root attribute. */ /* It is a directory, find index root attribute. */
ntfs_attr_reinit_search_ctx(ctx); ntfs_attr_reinit_search_ctx(ctx);
if (!ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE,
NULL, 0, ctx)) { 0, NULL, 0, ctx);
// FIXME: File is corrupt! Hot-fix with empty index if (unlikely(err)) {
// root attribute if recovery option is set. if (err == -ENOENT) {
ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is " // FIXME: File is corrupt! Hot-fix with empty
"missing."); // index root attribute if recovery option is
// set.
ntfs_error(vi->i_sb, "$INDEX_ROOT attribute "
"is missing.");
}
goto unm_err_out; goto unm_err_out;
} }
/* Set up the state. */ /* Set up the state. */
...@@ -850,11 +868,18 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -850,11 +868,18 @@ static int ntfs_read_locked_inode(struct inode *vi)
NInoSetIndexAllocPresent(ni); NInoSetIndexAllocPresent(ni);
/* Find index allocation attribute. */ /* Find index allocation attribute. */
ntfs_attr_reinit_search_ctx(ctx); ntfs_attr_reinit_search_ctx(ctx);
if (!ntfs_attr_lookup(AT_INDEX_ALLOCATION, I30, 4, err = ntfs_attr_lookup(AT_INDEX_ALLOCATION, I30, 4,
CASE_SENSITIVE, 0, NULL, 0, ctx)) { CASE_SENSITIVE, 0, NULL, 0, ctx);
ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " if (unlikely(err)) {
"is not present but $INDEX_ROOT " if (err == -ENOENT)
"indicated it is."); ntfs_error(vi->i_sb, "$INDEX_ALLOCATION "
"attribute is not present but "
"$INDEX_ROOT indicated it "
"is.");
else
ntfs_error(vi->i_sb, "Failed to lookup "
"$INDEX_ALLOCATION "
"attribute.");
goto unm_err_out; goto unm_err_out;
} }
if (!ctx->attr->non_resident) { if (!ctx->attr->non_resident) {
...@@ -946,9 +971,15 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -946,9 +971,15 @@ static int ntfs_read_locked_inode(struct inode *vi)
ni->name_len = 0; ni->name_len = 0;
/* Find first extent of the unnamed data attribute. */ /* Find first extent of the unnamed data attribute. */
if (!ntfs_attr_lookup(AT_DATA, NULL, 0, 0, 0, NULL, 0, ctx)) { err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, 0, NULL, 0, ctx);
if (unlikely(err)) {
vi->i_size = ni->initialized_size = vi->i_size = ni->initialized_size =
ni->allocated_size = 0LL; ni->allocated_size = 0;
if (err != -ENOENT) {
ntfs_error(vi->i_sb, "Failed to lookup $DATA "
"attribute.");
goto unm_err_out;
}
/* /*
* FILE_Secure does not have an unnamed $DATA * FILE_Secure does not have an unnamed $DATA
* attribute, so we special case it here. * attribute, so we special case it here.
...@@ -1169,8 +1200,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1169,8 +1200,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
} }
/* Find the attribute. */ /* Find the attribute. */
if (!ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE, err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
0, NULL, 0, ctx)) CASE_SENSITIVE, 0, NULL, 0, ctx);
if (unlikely(err))
goto unm_err_out; goto unm_err_out;
if (!ctx->attr->non_resident) { if (!ctx->attr->non_resident) {
...@@ -1425,9 +1457,12 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) ...@@ -1425,9 +1457,12 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
goto unm_err_out; goto unm_err_out;
} }
/* Find the index root attribute. */ /* Find the index root attribute. */
if (!ntfs_attr_lookup(AT_INDEX_ROOT, ni->name, ni->name_len, err = ntfs_attr_lookup(AT_INDEX_ROOT, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) { CASE_SENSITIVE, 0, NULL, 0, ctx);
ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is missing."); if (unlikely(err)) {
if (err == -ENOENT)
ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is "
"missing.");
goto unm_err_out; goto unm_err_out;
} }
/* Set up the state. */ /* Set up the state. */
...@@ -1506,10 +1541,16 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) ...@@ -1506,10 +1541,16 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
NInoSetIndexAllocPresent(ni); NInoSetIndexAllocPresent(ni);
/* Find index allocation attribute. */ /* Find index allocation attribute. */
ntfs_attr_reinit_search_ctx(ctx); ntfs_attr_reinit_search_ctx(ctx);
if (!ntfs_attr_lookup(AT_INDEX_ALLOCATION, ni->name, ni->name_len, err = ntfs_attr_lookup(AT_INDEX_ALLOCATION, ni->name, ni->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) { CASE_SENSITIVE, 0, NULL, 0, ctx);
ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is not " if (unlikely(err)) {
"present but $INDEX_ROOT indicated it is."); if (err == -ENOENT)
ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
"not present but $INDEX_ROOT "
"indicated it is.");
else
ntfs_error(vi->i_sb, "Failed to lookup "
"$INDEX_ALLOCATION attribute.");
goto unm_err_out; goto unm_err_out;
} }
if (!ctx->attr->non_resident) { if (!ctx->attr->non_resident) {
...@@ -1726,7 +1767,14 @@ int ntfs_read_inode_mount(struct inode *vi) ...@@ -1726,7 +1767,14 @@ int ntfs_read_inode_mount(struct inode *vi)
} }
/* Find the attribute list attribute if present. */ /* Find the attribute list attribute if present. */
if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx)) { err = ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 0, 0, NULL, 0, ctx);
if (err) {
if (unlikely(err != -ENOENT)) {
ntfs_error(sb, "Failed to lookup attribute list "
"attribute. You should run chkdsk.");
goto put_err_out;
}
} else /* if (!err) */ {
ATTR_LIST_ENTRY *al_entry, *next_al_entry; ATTR_LIST_ENTRY *al_entry, *next_al_entry;
u8 *al_end; u8 *al_end;
...@@ -1860,7 +1908,8 @@ int ntfs_read_inode_mount(struct inode *vi) ...@@ -1860,7 +1908,8 @@ int ntfs_read_inode_mount(struct inode *vi)
/* Now load all attribute extents. */ /* Now load all attribute extents. */
attr = NULL; attr = NULL;
next_vcn = last_vcn = highest_vcn = 0; next_vcn = last_vcn = highest_vcn = 0;
while (ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0, ctx)) { while (!(err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0,
ctx))) {
runlist_element *nrl; runlist_element *nrl;
/* Cache the current attribute. */ /* Cache the current attribute. */
...@@ -1991,15 +2040,20 @@ int ntfs_read_inode_mount(struct inode *vi) ...@@ -1991,15 +2040,20 @@ int ntfs_read_inode_mount(struct inode *vi)
goto put_err_out; goto put_err_out;
} }
} }
if (err != -ENOENT) {
ntfs_error(sb, "Failed to lookup $MFT/$DATA attribute extent. "
"$MFT is corrupt. Run chkdsk.");
goto put_err_out;
}
if (!attr) { if (!attr) {
ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is " ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is "
"corrupt. Run chkdsk."); "corrupt. Run chkdsk.");
goto put_err_out; goto put_err_out;
} }
if (highest_vcn && highest_vcn != last_vcn - 1) { if (highest_vcn && highest_vcn != last_vcn - 1) {
ntfs_error(sb, "Failed to load the complete runlist " ntfs_error(sb, "Failed to load the complete runlist for "
"for $MFT/$DATA. Driver bug or " "$MFT/$DATA. Driver bug or corrupt $MFT. "
"corrupt $MFT. Run chkdsk."); "Run chkdsk.");
ntfs_debug("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx", ntfs_debug("highest_vcn = 0x%llx, last_vcn - 1 = 0x%llx",
(unsigned long long)highest_vcn, (unsigned long long)highest_vcn,
(unsigned long long)last_vcn - 1); (unsigned long long)last_vcn - 1);
...@@ -2347,10 +2401,10 @@ int ntfs_write_inode(struct inode *vi, int sync) ...@@ -2347,10 +2401,10 @@ int ntfs_write_inode(struct inode *vi, int sync)
err = -ENOMEM; err = -ENOMEM;
goto unm_err_out; goto unm_err_out;
} }
if (unlikely(!ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0, err = ntfs_attr_lookup(AT_STANDARD_INFORMATION, NULL, 0,
CASE_SENSITIVE, 0, NULL, 0, ctx))) { CASE_SENSITIVE, 0, NULL, 0, ctx);
if (unlikely(err)) {
ntfs_attr_put_search_ctx(ctx); ntfs_attr_put_search_ctx(ctx);
err = -ENOENT;
goto unm_err_out; goto unm_err_out;
} }
si = (STANDARD_INFORMATION*)((u8*)ctx->attr + si = (STANDARD_INFORMATION*)((u8*)ctx->attr +
......
...@@ -197,7 +197,7 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, ...@@ -197,7 +197,7 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
goto err_out; goto err_out;
} }
ctx = ntfs_attr_get_search_ctx(ni, m); ctx = ntfs_attr_get_search_ctx(ni, m);
if (!ctx) { if (unlikely(!ctx)) {
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
...@@ -205,11 +205,13 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, ...@@ -205,11 +205,13 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
ATTR_RECORD *a; ATTR_RECORD *a;
u32 val_len; u32 val_len;
if (!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0,
NULL, 0, ctx)) { NULL, 0, ctx);
if (unlikely(err)) {
ntfs_error(vol->sb, "Inode corrupt: No WIN32 " ntfs_error(vol->sb, "Inode corrupt: No WIN32 "
"namespace counterpart to DOS " "namespace counterpart to DOS "
"file name. Run chkdsk."); "file name. Run chkdsk.");
if (err == -ENOENT)
err = -EIO; err = -EIO;
goto err_out; goto err_out;
} }
...@@ -372,6 +374,7 @@ struct dentry *ntfs_get_parent(struct dentry *child_dent) ...@@ -372,6 +374,7 @@ struct dentry *ntfs_get_parent(struct dentry *child_dent)
struct inode *parent_vi; struct inode *parent_vi;
struct dentry *parent_dent; struct dentry *parent_dent;
unsigned long parent_ino; unsigned long parent_ino;
int err;
ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
/* Get the mft record of the inode belonging to the child dentry. */ /* Get the mft record of the inode belonging to the child dentry. */
...@@ -385,13 +388,16 @@ struct dentry *ntfs_get_parent(struct dentry *child_dent) ...@@ -385,13 +388,16 @@ struct dentry *ntfs_get_parent(struct dentry *child_dent)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
try_next: try_next:
if (unlikely(!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, err = ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,
0, NULL, 0, ctx))) { 0, ctx);
if (unlikely(err)) {
ntfs_attr_put_search_ctx(ctx); ntfs_attr_put_search_ctx(ctx);
unmap_mft_record(ni); unmap_mft_record(ni);
ntfs_error(vi->i_sb, "Inode 0x%lx does not have a file name " if (err == -ENOENT)
"attribute. Run chkdsk.", vi->i_ino); ntfs_error(vi->i_sb, "Inode 0x%lx does not have a "
return ERR_PTR(-ENOENT); "file name attribute. Run chkdsk.",
vi->i_ino);
return ERR_PTR(err);
} }
attr = ctx->attr; attr = ctx->attr;
if (unlikely(attr->non_resident)) if (unlikely(attr->non_resident))
......
...@@ -336,11 +336,10 @@ static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags) ...@@ -336,11 +336,10 @@ static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags)
err = -ENOMEM; err = -ENOMEM;
goto put_unm_err_out; goto put_unm_err_out;
} }
if (!ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, err = ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0,
ctx)) { ctx);
err = -EIO; if (err)
goto put_unm_err_out; goto put_unm_err_out;
}
vi = (VOLUME_INFORMATION*)((u8*)ctx->attr + vi = (VOLUME_INFORMATION*)((u8*)ctx->attr +
le16_to_cpu(ctx->attr->data.resident.value_offset)); le16_to_cpu(ctx->attr->data.resident.value_offset));
vol->vol_flags = vi->flags = flags; vol->vol_flags = vi->flags = flags;
...@@ -1433,7 +1432,7 @@ static BOOL load_system_files(ntfs_volume *vol) ...@@ -1433,7 +1432,7 @@ static BOOL load_system_files(ntfs_volume *vol)
ntfs_error(sb, "Failed to get attribute search context."); ntfs_error(sb, "Failed to get attribute search context.");
goto get_ctx_vol_failed; goto get_ctx_vol_failed;
} }
if (!ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0,
ctx) || ctx->attr->non_resident || ctx->attr->flags) { ctx) || ctx->attr->non_resident || ctx->attr->flags) {
err_put_vol: err_put_vol:
ntfs_attr_put_search_ctx(ctx); ntfs_attr_put_search_ctx(ctx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment