linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / ntfs / file.c
index 2e42c2d..89449d3 100644 (file)
@@ -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 = {};