- // TODO: Implement...
- ntfs_warning(vi->i_sb, "Eeek: i_size may have changed! If you see "
- "this right after a message from "
- "ntfs_{prepare,commit}_{,nonresident_}write() then "
- "just ignore it. Otherwise it is bad news.");
- // TODO: reset i_size now!
+ ntfs_inode *ni = NTFS_I(vi);
+ ntfs_attr_search_ctx *ctx;
+ MFT_RECORD *m;
+ int err;
+
+ m = map_mft_record(ni);
+ if (IS_ERR(m)) {
+ ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx "
+ "(error code %ld).", vi->i_ino, PTR_ERR(m));
+ if (PTR_ERR(m) != ENOMEM)
+ make_bad_inode(vi);
+ return;
+ }
+ ctx = ntfs_attr_get_search_ctx(ni, m);
+ if (unlikely(!ctx)) {
+ ntfs_error(vi->i_sb, "Failed to allocate a search context: "
+ "Not enough memory");
+ // FIXME: We can't report an error code upstream. So what do
+ // we do?!? make_bad_inode() seems a bit harsh...
+ unmap_mft_record(ni);
+ return;
+ }
+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+ CASE_SENSITIVE, 0, NULL, 0, ctx);
+ if (unlikely(err)) {
+ if (err == -ENOENT) {
+ ntfs_error(vi->i_sb, "Open attribute is missing from "
+ "mft record. Inode 0x%lx is corrupt. "
+ "Run chkdsk.", vi->i_ino);
+ make_bad_inode(vi);
+ } else {
+ ntfs_error(vi->i_sb, "Failed to lookup attribute in "
+ "inode 0x%lx (error code %d).",
+ vi->i_ino, err);
+ // FIXME: We can't report an error code upstream. So
+ // 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 (ntfs_attr_size(ctx->attr) == i_size_read(vi))
+ goto out;
+ // TODO: Implement the truncate...
+ ntfs_error(vi->i_sb, "Inode size has changed but this is not "
+ "implemented yet. Resetting inode size to old value. "
+ " This is most likely a bug in the ntfs driver!");
+ i_size_write(vi, ntfs_attr_size(ctx->attr));
+out:
+ ntfs_attr_put_search_ctx(ctx);
+ unmap_mft_record(ni);