Commit 3cde4635 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: Improve error handling in fs/ntfs/inode.c::ntfs_truncate().

Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent f4debff8
...@@ -21,6 +21,10 @@ ToDo/Notes: ...@@ -21,6 +21,10 @@ ToDo/Notes:
- Enable the code for setting the NT4 compatibility flag when we start - Enable the code for setting the NT4 compatibility flag when we start
making NTFS 1.2 specific modifications. making NTFS 1.2 specific modifications.
2.1.22-WIP
- Improve error handling in fs/ntfs/inode.c::ntfs_truncate().
2.1.21 - Fix some races and bugs, rewrite mft write code, add mft allocator. 2.1.21 - Fix some races and bugs, rewrite mft write code, add mft allocator.
- Implement extent mft record deallocation - Implement extent mft record deallocation
......
...@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ ...@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
unistr.o upcase.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.21\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.22-WIP\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
...@@ -2272,57 +2272,66 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt) ...@@ -2272,57 +2272,66 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
void ntfs_truncate(struct inode *vi) void ntfs_truncate(struct inode *vi)
{ {
ntfs_inode *ni = NTFS_I(vi); ntfs_inode *ni = NTFS_I(vi);
ntfs_volume *vol = ni->vol;
ntfs_attr_search_ctx *ctx; ntfs_attr_search_ctx *ctx;
MFT_RECORD *m; MFT_RECORD *m;
const char *te = " Leaving file length out of sync with i_size.";
int err; int err;
ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
BUG_ON(NInoAttr(ni)); BUG_ON(NInoAttr(ni));
BUG_ON(ni->nr_extents < 0); BUG_ON(ni->nr_extents < 0);
m = map_mft_record(ni); m = map_mft_record(ni);
if (IS_ERR(m)) { if (IS_ERR(m)) {
err = PTR_ERR(m);
ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx " ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx "
"(error code %ld).", vi->i_ino, PTR_ERR(m)); "(error code %d).%s", vi->i_ino, err, te);
if (PTR_ERR(m) != ENOMEM) ctx = NULL;
make_bad_inode(vi); m = NULL;
return; goto err_out;
} }
ctx = ntfs_attr_get_search_ctx(ni, m); ctx = ntfs_attr_get_search_ctx(ni, m);
if (unlikely(!ctx)) { if (unlikely(!ctx)) {
ntfs_error(vi->i_sb, "Failed to allocate a search context: " ntfs_error(vi->i_sb, "Failed to allocate a search context for "
"Not enough memory"); "inode 0x%lx (not enough memory).%s",
// FIXME: We can't report an error code upstream. So what do vi->i_ino, te);
// we do?!? make_bad_inode() seems a bit harsh... err = -ENOMEM;
unmap_mft_record(ni); goto err_out;
return;
} }
err = 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);
if (unlikely(err)) { if (unlikely(err)) {
if (err == -ENOENT) { if (err == -ENOENT)
ntfs_error(vi->i_sb, "Open attribute is missing from " ntfs_error(vi->i_sb, "Open attribute is missing from "
"mft record. Inode 0x%lx is corrupt. " "mft record. Inode 0x%lx is corrupt. "
"Run chkdsk.", vi->i_ino); "Run chkdsk.", vi->i_ino);
make_bad_inode(vi); else
} else {
ntfs_error(vi->i_sb, "Failed to lookup attribute in " ntfs_error(vi->i_sb, "Failed to lookup attribute in "
"inode 0x%lx (error code %d).", "inode 0x%lx (error code %d).",
vi->i_ino, err); vi->i_ino, err);
// FIXME: We can't report an error code upstream. So goto err_out;
// what do we do?!? make_bad_inode() seems a bit
// harsh...
}
goto out;
} }
/* If the size has not changed there is nothing to do. */ /* If the size has not changed there is nothing to do. */
if (ntfs_attr_size(ctx->attr) == i_size_read(vi)) if (ntfs_attr_size(ctx->attr) == i_size_read(vi))
goto out; goto done;
// TODO: Implement the truncate... // TODO: Implement the truncate...
ntfs_error(vi->i_sb, "Inode size has changed but this is not " ntfs_error(vi->i_sb, "Inode size has changed but this is not "
"implemented yet. Resetting inode size to old value. " "implemented yet. Resetting inode size to old value. "
" This is most likely a bug in the ntfs driver!"); " This is most likely a bug in the ntfs driver!");
i_size_write(vi, ntfs_attr_size(ctx->attr)); i_size_write(vi, ntfs_attr_size(ctx->attr));
out: done:
ntfs_attr_put_search_ctx(ctx);
unmap_mft_record(ni);
ntfs_debug("Done.");
return;
err_out:
if (err != -ENOMEM) {
NVolSetErrors(vol);
make_bad_inode(vi);
}
if (ctx)
ntfs_attr_put_search_ctx(ctx); ntfs_attr_put_search_ctx(ctx);
if (m)
unmap_mft_record(ni); unmap_mft_record(ni);
return; return;
} }
......
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