X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fntfs%2Ffile.c;fp=fs%2Fntfs%2Ffile.c;h=89449d3967a3a42bafde7ec5083b035d153f8779;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=2e42c2dcae12310d123c13642809219c5cb51126;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 2e42c2dca..89449d396 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -231,7 +231,8 @@ do_non_resident_extend: * Read the page. If the page is not present, this will zero * the uninitialized regions for us. */ - page = read_mapping_page(mapping, index, NULL); + page = read_cache_page(mapping, index, + (filler_t*)mapping->a_ops->readpage, NULL); if (IS_ERR(page)) { err = PTR_ERR(page); goto init_err_out; @@ -942,8 +943,7 @@ rl_not_mapped_enoent: } ni->runlist.rl = rl; status.runlist_merged = 1; - ntfs_debug("Allocated cluster, lcn 0x%llx.", - (unsigned long long)lcn); + ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn); /* Map and lock the mft record and get the attribute record. */ if (!NInoAttr(ni)) base_ni = ni; @@ -1206,6 +1206,8 @@ rl_not_mapped_enoent: "attribute runlist in error code " "path. Run chkdsk to recover the " "lost cluster."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); NVolSetErrors(vol); } else /* if (success) */ { status.runlist_merged = 0; @@ -1236,6 +1238,8 @@ rl_not_mapped_enoent: ntfs_error(vol->sb, "Failed to restore attribute " "record in error code path. Run " "chkdsk to recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); NVolSetErrors(vol); } else /* if (success) */ { if (ntfs_mapping_pairs_build(vol, (u8*)a + @@ -1248,6 +1252,8 @@ rl_not_mapped_enoent: "mapping pairs array in error " "code path. Run chkdsk to " "recover."); + make_bad_inode(vi); + make_bad_inode(VFS_I(base_ni)); NVolSetErrors(vol); } flush_dcache_mft_record_page(ctx->ntfs_ino); @@ -1358,7 +1364,7 @@ err_out: goto out; } -static size_t __ntfs_copy_from_user_iovec_inatomic(char *vaddr, +static size_t __ntfs_copy_from_user_iovec(char *vaddr, const struct iovec *iov, size_t iov_ofs, size_t bytes) { size_t total = 0; @@ -1376,6 +1382,10 @@ static size_t __ntfs_copy_from_user_iovec_inatomic(char *vaddr, bytes -= len; vaddr += len; if (unlikely(left)) { + /* + * Zero the rest of the target like __copy_from_user(). + */ + memset(vaddr, 0, bytes); total -= left; break; } @@ -1416,13 +1426,11 @@ static inline void ntfs_set_next_iovec(const struct iovec **iovp, * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s * single-segment behaviour. * - * We call the same helper (__ntfs_copy_from_user_iovec_inatomic()) both - * when atomic and when not atomic. This is ok because - * __ntfs_copy_from_user_iovec_inatomic() calls __copy_from_user_inatomic() - * and it is ok to call this when non-atomic. - * Infact, the only difference between __copy_from_user_inatomic() and - * __copy_from_user() is that the latter calls might_sleep() and the former - * should not zero the tail of the buffer on error. And on many + * We call the same helper (__ntfs_copy_from_user_iovec()) both when atomic and + * when not atomic. This is ok because __ntfs_copy_from_user_iovec() calls + * __copy_from_user_inatomic() and it is ok to call this when non-atomic. In + * fact, the only difference between __copy_from_user_inatomic() and + * __copy_from_user() is that the latter calls might_sleep(). And on many * architectures __copy_from_user_inatomic() is just defined to * __copy_from_user() so it makes no difference at all on those architectures. */ @@ -1439,18 +1447,14 @@ static inline size_t ntfs_copy_from_user_iovec(struct page **pages, if (len > bytes) len = bytes; kaddr = kmap_atomic(*pages, KM_USER0); - copied = __ntfs_copy_from_user_iovec_inatomic(kaddr + ofs, + copied = __ntfs_copy_from_user_iovec(kaddr + ofs, *iov, *iov_ofs, len); kunmap_atomic(kaddr, KM_USER0); if (unlikely(copied != len)) { /* Do it the slow way. */ kaddr = kmap(*pages); - copied = __ntfs_copy_from_user_iovec_inatomic(kaddr + ofs, + copied = __ntfs_copy_from_user_iovec(kaddr + ofs, *iov, *iov_ofs, len); - /* - * Zero the rest of the target like __copy_from_user(). - */ - memset(kaddr + ofs + copied, 0, len - copied); kunmap(*pages); if (unlikely(copied != len)) goto err_out; @@ -1619,8 +1623,11 @@ err_out: unmap_mft_record(base_ni); ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error " "code %i).", err); - if (err != -ENOMEM) + if (err != -ENOMEM) { NVolSetErrors(ni->vol); + make_bad_inode(VFS_I(base_ni)); + make_bad_inode(vi); + } return err; } @@ -1795,6 +1802,8 @@ err_out: ntfs_error(vi->i_sb, "Resident attribute commit write failed " "with error %i.", err); NVolSetErrors(ni->vol); + make_bad_inode(VFS_I(base_ni)); + make_bad_inode(vi); } if (ctx) ntfs_attr_put_search_ctx(ctx); @@ -2296,7 +2305,7 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, #endif /* NTFS_RW */ -const struct file_operations ntfs_file_ops = { +struct file_operations ntfs_file_ops = { .llseek = generic_file_llseek, /* Seek inside file. */ .read = generic_file_read, /* Read from file. */ .aio_read = generic_file_aio_read, /* Async read from file. */ @@ -2339,6 +2348,6 @@ struct inode_operations ntfs_file_inode_ops = { #endif /* NTFS_RW */ }; -const struct file_operations ntfs_empty_file_ops = {}; +struct file_operations ntfs_empty_file_ops = {}; struct inode_operations ntfs_empty_inode_ops = {};