aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/inode.c')
-rw-r--r--fs/ntfs/inode.c111
1 files changed, 66 insertions, 45 deletions
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 55263b7de9c0..4c86b7e1d1eb 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. 2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2005 Anton Altaparmakov 4 * Copyright (c) 2001-2006 Anton Altaparmakov
5 * 5 *
6 * This program/include file is free software; you can redistribute it and/or 6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published 7 * modify it under the terms of the GNU General Public License as published
@@ -19,13 +19,19 @@
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/pagemap.h>
23#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
24#include <linux/smp_lock.h> 23#include <linux/fs.h>
25#include <linux/quotaops.h> 24#include <linux/mm.h>
26#include <linux/mount.h> 25#include <linux/mount.h>
26#include <linux/mutex.h>
27#include <linux/pagemap.h>
28#include <linux/quotaops.h>
29#include <linux/slab.h>
30#include <linux/smp_lock.h>
27 31
28#include "aops.h" 32#include "aops.h"
33#include "attrib.h"
34#include "bitmap.h"
29#include "dir.h" 35#include "dir.h"
30#include "debug.h" 36#include "debug.h"
31#include "inode.h" 37#include "inode.h"
@@ -382,7 +388,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
382 atomic_set(&ni->count, 1); 388 atomic_set(&ni->count, 1);
383 ni->vol = NTFS_SB(sb); 389 ni->vol = NTFS_SB(sb);
384 ntfs_init_runlist(&ni->runlist); 390 ntfs_init_runlist(&ni->runlist);
385 init_MUTEX(&ni->mrec_lock); 391 mutex_init(&ni->mrec_lock);
386 ni->page = NULL; 392 ni->page = NULL;
387 ni->page_ofs = 0; 393 ni->page_ofs = 0;
388 ni->attr_list_size = 0; 394 ni->attr_list_size = 0;
@@ -394,7 +400,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
394 ni->itype.index.collation_rule = 0; 400 ni->itype.index.collation_rule = 0;
395 ni->itype.index.block_size_bits = 0; 401 ni->itype.index.block_size_bits = 0;
396 ni->itype.index.vcn_size_bits = 0; 402 ni->itype.index.vcn_size_bits = 0;
397 init_MUTEX(&ni->extent_lock); 403 mutex_init(&ni->extent_lock);
398 ni->nr_extents = 0; 404 ni->nr_extents = 0;
399 ni->ext.base_ntfs_ino = NULL; 405 ni->ext.base_ntfs_ino = NULL;
400} 406}
@@ -1064,10 +1070,10 @@ skip_large_dir_stuff:
1064 if (a->non_resident) { 1070 if (a->non_resident) {
1065 NInoSetNonResident(ni); 1071 NInoSetNonResident(ni);
1066 if (NInoCompressed(ni) || NInoSparse(ni)) { 1072 if (NInoCompressed(ni) || NInoSparse(ni)) {
1067 if (a->data.non_resident.compression_unit != 1073 if (NInoCompressed(ni) && a->data.non_resident.
1068 4) { 1074 compression_unit != 4) {
1069 ntfs_error(vi->i_sb, "Found " 1075 ntfs_error(vi->i_sb, "Found "
1070 "nonstandard " 1076 "non-standard "
1071 "compression unit (%u " 1077 "compression unit (%u "
1072 "instead of 4). " 1078 "instead of 4). "
1073 "Cannot handle this.", 1079 "Cannot handle this.",
@@ -1076,16 +1082,26 @@ skip_large_dir_stuff:
1076 err = -EOPNOTSUPP; 1082 err = -EOPNOTSUPP;
1077 goto unm_err_out; 1083 goto unm_err_out;
1078 } 1084 }
1079 ni->itype.compressed.block_clusters = 1U << 1085 if (a->data.non_resident.compression_unit) {
1080 a->data.non_resident. 1086 ni->itype.compressed.block_size = 1U <<
1081 compression_unit; 1087 (a->data.non_resident.
1082 ni->itype.compressed.block_size = 1U << ( 1088 compression_unit +
1083 a->data.non_resident. 1089 vol->cluster_size_bits);
1084 compression_unit + 1090 ni->itype.compressed.block_size_bits =
1085 vol->cluster_size_bits); 1091 ffs(ni->itype.
1086 ni->itype.compressed.block_size_bits = ffs( 1092 compressed.
1087 ni->itype.compressed. 1093 block_size) - 1;
1088 block_size) - 1; 1094 ni->itype.compressed.block_clusters =
1095 1U << a->data.
1096 non_resident.
1097 compression_unit;
1098 } else {
1099 ni->itype.compressed.block_size = 0;
1100 ni->itype.compressed.block_size_bits =
1101 0;
1102 ni->itype.compressed.block_clusters =
1103 0;
1104 }
1089 ni->itype.compressed.size = sle64_to_cpu( 1105 ni->itype.compressed.size = sle64_to_cpu(
1090 a->data.non_resident. 1106 a->data.non_resident.
1091 compressed_size); 1107 compressed_size);
@@ -1338,8 +1354,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1338 goto unm_err_out; 1354 goto unm_err_out;
1339 } 1355 }
1340 if (NInoCompressed(ni) || NInoSparse(ni)) { 1356 if (NInoCompressed(ni) || NInoSparse(ni)) {
1341 if (a->data.non_resident.compression_unit != 4) { 1357 if (NInoCompressed(ni) && a->data.non_resident.
1342 ntfs_error(vi->i_sb, "Found nonstandard " 1358 compression_unit != 4) {
1359 ntfs_error(vi->i_sb, "Found non-standard "
1343 "compression unit (%u instead " 1360 "compression unit (%u instead "
1344 "of 4). Cannot handle this.", 1361 "of 4). Cannot handle this.",
1345 a->data.non_resident. 1362 a->data.non_resident.
@@ -1347,13 +1364,22 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1347 err = -EOPNOTSUPP; 1364 err = -EOPNOTSUPP;
1348 goto unm_err_out; 1365 goto unm_err_out;
1349 } 1366 }
1350 ni->itype.compressed.block_clusters = 1U << 1367 if (a->data.non_resident.compression_unit) {
1351 a->data.non_resident.compression_unit; 1368 ni->itype.compressed.block_size = 1U <<
1352 ni->itype.compressed.block_size = 1U << ( 1369 (a->data.non_resident.
1353 a->data.non_resident.compression_unit + 1370 compression_unit +
1354 vol->cluster_size_bits); 1371 vol->cluster_size_bits);
1355 ni->itype.compressed.block_size_bits = ffs( 1372 ni->itype.compressed.block_size_bits =
1356 ni->itype.compressed.block_size) - 1; 1373 ffs(ni->itype.compressed.
1374 block_size) - 1;
1375 ni->itype.compressed.block_clusters = 1U <<
1376 a->data.non_resident.
1377 compression_unit;
1378 } else {
1379 ni->itype.compressed.block_size = 0;
1380 ni->itype.compressed.block_size_bits = 0;
1381 ni->itype.compressed.block_clusters = 0;
1382 }
1357 ni->itype.compressed.size = sle64_to_cpu( 1383 ni->itype.compressed.size = sle64_to_cpu(
1358 a->data.non_resident.compressed_size); 1384 a->data.non_resident.compressed_size);
1359 } 1385 }
@@ -1406,7 +1432,6 @@ err_out:
1406 "Run chkdsk.", err, vi->i_ino, ni->type, ni->name_len, 1432 "Run chkdsk.", err, vi->i_ino, ni->type, ni->name_len,
1407 base_vi->i_ino); 1433 base_vi->i_ino);
1408 make_bad_inode(vi); 1434 make_bad_inode(vi);
1409 make_bad_inode(base_vi);
1410 if (err != -ENOMEM) 1435 if (err != -ENOMEM)
1411 NVolSetErrors(vol); 1436 NVolSetErrors(vol);
1412 return err; 1437 return err;
@@ -1591,6 +1616,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
1591 "$INDEX_ALLOCATION attribute."); 1616 "$INDEX_ALLOCATION attribute.");
1592 goto unm_err_out; 1617 goto unm_err_out;
1593 } 1618 }
1619 a = ctx->attr;
1594 if (!a->non_resident) { 1620 if (!a->non_resident) {
1595 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " 1621 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
1596 "resident."); 1622 "resident.");
@@ -2823,11 +2849,8 @@ done:
2823old_bad_out: 2849old_bad_out:
2824 old_size = -1; 2850 old_size = -1;
2825bad_out: 2851bad_out:
2826 if (err != -ENOMEM && err != -EOPNOTSUPP) { 2852 if (err != -ENOMEM && err != -EOPNOTSUPP)
2827 make_bad_inode(vi);
2828 make_bad_inode(VFS_I(base_ni));
2829 NVolSetErrors(vol); 2853 NVolSetErrors(vol);
2830 }
2831 if (err != -EOPNOTSUPP) 2854 if (err != -EOPNOTSUPP)
2832 NInoSetTruncateFailed(ni); 2855 NInoSetTruncateFailed(ni);
2833 else if (old_size >= 0) 2856 else if (old_size >= 0)
@@ -2842,11 +2865,8 @@ out:
2842 ntfs_debug("Failed. Returning error code %i.", err); 2865 ntfs_debug("Failed. Returning error code %i.", err);
2843 return err; 2866 return err;
2844conv_err_out: 2867conv_err_out:
2845 if (err != -ENOMEM && err != -EOPNOTSUPP) { 2868 if (err != -ENOMEM && err != -EOPNOTSUPP)
2846 make_bad_inode(vi);
2847 make_bad_inode(VFS_I(base_ni));
2848 NVolSetErrors(vol); 2869 NVolSetErrors(vol);
2849 }
2850 if (err != -EOPNOTSUPP) 2870 if (err != -EOPNOTSUPP)
2851 NInoSetTruncateFailed(ni); 2871 NInoSetTruncateFailed(ni);
2852 else 2872 else
@@ -3044,15 +3064,18 @@ int ntfs_write_inode(struct inode *vi, int sync)
3044 * record will be cleaned and written out to disk below, i.e. before 3064 * record will be cleaned and written out to disk below, i.e. before
3045 * this function returns. 3065 * this function returns.
3046 */ 3066 */
3047 if (modified && !NInoTestSetDirty(ctx->ntfs_ino)) 3067 if (modified) {
3048 mark_ntfs_record_dirty(ctx->ntfs_ino->page, 3068 flush_dcache_mft_record_page(ctx->ntfs_ino);
3049 ctx->ntfs_ino->page_ofs); 3069 if (!NInoTestSetDirty(ctx->ntfs_ino))
3070 mark_ntfs_record_dirty(ctx->ntfs_ino->page,
3071 ctx->ntfs_ino->page_ofs);
3072 }
3050 ntfs_attr_put_search_ctx(ctx); 3073 ntfs_attr_put_search_ctx(ctx);
3051 /* Now the access times are updated, write the base mft record. */ 3074 /* Now the access times are updated, write the base mft record. */
3052 if (NInoDirty(ni)) 3075 if (NInoDirty(ni))
3053 err = write_mft_record(ni, m, sync); 3076 err = write_mft_record(ni, m, sync);
3054 /* Write all attached extent mft records. */ 3077 /* Write all attached extent mft records. */
3055 down(&ni->extent_lock); 3078 mutex_lock(&ni->extent_lock);
3056 if (ni->nr_extents > 0) { 3079 if (ni->nr_extents > 0) {
3057 ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos; 3080 ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;
3058 int i; 3081 int i;
@@ -3079,7 +3102,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
3079 } 3102 }
3080 } 3103 }
3081 } 3104 }
3082 up(&ni->extent_lock); 3105 mutex_unlock(&ni->extent_lock);
3083 unmap_mft_record(ni); 3106 unmap_mft_record(ni);
3084 if (unlikely(err)) 3107 if (unlikely(err))
3085 goto err_out; 3108 goto err_out;
@@ -3094,9 +3117,7 @@ err_out:
3094 "retries later."); 3117 "retries later.");
3095 mark_inode_dirty(vi); 3118 mark_inode_dirty(vi);
3096 } else { 3119 } else {
3097 ntfs_error(vi->i_sb, "Failed (error code %i): Marking inode " 3120 ntfs_error(vi->i_sb, "Failed (error %i): Run chkdsk.", -err);
3098 "as bad. You should run chkdsk.", -err);
3099 make_bad_inode(vi);
3100 NVolSetErrors(ni->vol); 3121 NVolSetErrors(ni->vol);
3101 } 3122 }
3102 return err; 3123 return err;