aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2006-03-23 10:53:03 -0500
committerAnton Altaparmakov <aia21@cantab.net>2006-03-23 10:53:03 -0500
commita0646a1f04f1ec4c7514e5b00496b54e054a2c99 (patch)
tree2cdf9023dd85b968a1cd3e4150019e1bbac19f1a
parent949763b2b8822c6dc6da0d0e1d4af092152546c2 (diff)
NTFS: Add support for sparse files which have a compression unit of 0.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
-rw-r--r--fs/ntfs/ChangeLog1
-rw-r--r--fs/ntfs/attrib.c25
-rw-r--r--fs/ntfs/inode.c68
-rw-r--r--fs/ntfs/layout.h19
4 files changed, 75 insertions, 38 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 548d9059a697..b5774233ef1d 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -31,6 +31,7 @@ ToDo/Notes:
31 - Fix comparison of $MFT and $MFTMirr to not bail out when there are 31 - Fix comparison of $MFT and $MFTMirr to not bail out when there are
32 unused, invalid mft records which are the same in both $MFT and 32 unused, invalid mft records which are the same in both $MFT and
33 $MFTMirr. 33 $MFTMirr.
34 - Add support for sparse files which have a compression unit of 0.
34 35
352.1.26 - Minor bug fixes and updates. 362.1.26 - Minor bug fixes and updates.
36 37
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index a92b9e9db91d..7a568eb7d80f 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1695,7 +1695,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1695 a->data.non_resident.initialized_size = 1695 a->data.non_resident.initialized_size =
1696 cpu_to_sle64(attr_size); 1696 cpu_to_sle64(attr_size);
1697 if (NInoSparse(ni) || NInoCompressed(ni)) { 1697 if (NInoSparse(ni) || NInoCompressed(ni)) {
1698 a->data.non_resident.compression_unit = 4; 1698 a->data.non_resident.compression_unit = 0;
1699 if (NInoCompressed(ni) || vol->major_ver < 3)
1700 a->data.non_resident.compression_unit = 4;
1699 a->data.non_resident.compressed_size = 1701 a->data.non_resident.compressed_size =
1700 a->data.non_resident.allocated_size; 1702 a->data.non_resident.allocated_size;
1701 } else 1703 } else
@@ -1714,13 +1716,20 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1714 ni->allocated_size = new_size; 1716 ni->allocated_size = new_size;
1715 if (NInoSparse(ni) || NInoCompressed(ni)) { 1717 if (NInoSparse(ni) || NInoCompressed(ni)) {
1716 ni->itype.compressed.size = ni->allocated_size; 1718 ni->itype.compressed.size = ni->allocated_size;
1717 ni->itype.compressed.block_size = 1U << 1719 if (a->data.non_resident.compression_unit) {
1718 (a->data.non_resident.compression_unit + 1720 ni->itype.compressed.block_size = 1U << (a->data.
1719 vol->cluster_size_bits); 1721 non_resident.compression_unit +
1720 ni->itype.compressed.block_size_bits = 1722 vol->cluster_size_bits);
1721 ffs(ni->itype.compressed.block_size) - 1; 1723 ni->itype.compressed.block_size_bits =
1722 ni->itype.compressed.block_clusters = 1U << 1724 ffs(ni->itype.compressed.block_size) -
1723 a->data.non_resident.compression_unit; 1725 1;
1726 ni->itype.compressed.block_clusters = 1U <<
1727 a->data.non_resident.compression_unit;
1728 } else {
1729 ni->itype.compressed.block_size = 0;
1730 ni->itype.compressed.block_size_bits = 0;
1731 ni->itype.compressed.block_clusters = 0;
1732 }
1724 vi->i_blocks = ni->itype.compressed.size >> 9; 1733 vi->i_blocks = ni->itype.compressed.size >> 9;
1725 } else 1734 } else
1726 vi->i_blocks = ni->allocated_size >> 9; 1735 vi->i_blocks = ni->allocated_size >> 9;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 55263b7de9c0..ae341922f423 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
@@ -24,8 +24,10 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/quotaops.h> 25#include <linux/quotaops.h>
26#include <linux/mount.h> 26#include <linux/mount.h>
27#include <linux/mutex.h>
27 28
28#include "aops.h" 29#include "aops.h"
30#include "attrib.h"
29#include "dir.h" 31#include "dir.h"
30#include "debug.h" 32#include "debug.h"
31#include "inode.h" 33#include "inode.h"
@@ -1064,10 +1066,10 @@ skip_large_dir_stuff:
1064 if (a->non_resident) { 1066 if (a->non_resident) {
1065 NInoSetNonResident(ni); 1067 NInoSetNonResident(ni);
1066 if (NInoCompressed(ni) || NInoSparse(ni)) { 1068 if (NInoCompressed(ni) || NInoSparse(ni)) {
1067 if (a->data.non_resident.compression_unit != 1069 if (NInoCompressed(ni) && a->data.non_resident.
1068 4) { 1070 compression_unit != 4) {
1069 ntfs_error(vi->i_sb, "Found " 1071 ntfs_error(vi->i_sb, "Found "
1070 "nonstandard " 1072 "non-standard "
1071 "compression unit (%u " 1073 "compression unit (%u "
1072 "instead of 4). " 1074 "instead of 4). "
1073 "Cannot handle this.", 1075 "Cannot handle this.",
@@ -1076,16 +1078,26 @@ skip_large_dir_stuff:
1076 err = -EOPNOTSUPP; 1078 err = -EOPNOTSUPP;
1077 goto unm_err_out; 1079 goto unm_err_out;
1078 } 1080 }
1079 ni->itype.compressed.block_clusters = 1U << 1081 if (a->data.non_resident.compression_unit) {
1080 a->data.non_resident. 1082 ni->itype.compressed.block_size = 1U <<
1081 compression_unit; 1083 (a->data.non_resident.
1082 ni->itype.compressed.block_size = 1U << ( 1084 compression_unit +
1083 a->data.non_resident. 1085 vol->cluster_size_bits);
1084 compression_unit + 1086 ni->itype.compressed.block_size_bits =
1085 vol->cluster_size_bits); 1087 ffs(ni->itype.
1086 ni->itype.compressed.block_size_bits = ffs( 1088 compressed.
1087 ni->itype.compressed. 1089 block_size) - 1;
1088 block_size) - 1; 1090 ni->itype.compressed.block_clusters =
1091 1U << a->data.
1092 non_resident.
1093 compression_unit;
1094 } else {
1095 ni->itype.compressed.block_size = 0;
1096 ni->itype.compressed.block_size_bits =
1097 0;
1098 ni->itype.compressed.block_clusters =
1099 0;
1100 }
1089 ni->itype.compressed.size = sle64_to_cpu( 1101 ni->itype.compressed.size = sle64_to_cpu(
1090 a->data.non_resident. 1102 a->data.non_resident.
1091 compressed_size); 1103 compressed_size);
@@ -1338,8 +1350,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1338 goto unm_err_out; 1350 goto unm_err_out;
1339 } 1351 }
1340 if (NInoCompressed(ni) || NInoSparse(ni)) { 1352 if (NInoCompressed(ni) || NInoSparse(ni)) {
1341 if (a->data.non_resident.compression_unit != 4) { 1353 if (NInoCompressed(ni) && a->data.non_resident.
1342 ntfs_error(vi->i_sb, "Found nonstandard " 1354 compression_unit != 4) {
1355 ntfs_error(vi->i_sb, "Found non-standard "
1343 "compression unit (%u instead " 1356 "compression unit (%u instead "
1344 "of 4). Cannot handle this.", 1357 "of 4). Cannot handle this.",
1345 a->data.non_resident. 1358 a->data.non_resident.
@@ -1347,13 +1360,22 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1347 err = -EOPNOTSUPP; 1360 err = -EOPNOTSUPP;
1348 goto unm_err_out; 1361 goto unm_err_out;
1349 } 1362 }
1350 ni->itype.compressed.block_clusters = 1U << 1363 if (a->data.non_resident.compression_unit) {
1351 a->data.non_resident.compression_unit; 1364 ni->itype.compressed.block_size = 1U <<
1352 ni->itype.compressed.block_size = 1U << ( 1365 (a->data.non_resident.
1353 a->data.non_resident.compression_unit + 1366 compression_unit +
1354 vol->cluster_size_bits); 1367 vol->cluster_size_bits);
1355 ni->itype.compressed.block_size_bits = ffs( 1368 ni->itype.compressed.block_size_bits =
1356 ni->itype.compressed.block_size) - 1; 1369 ffs(ni->itype.compressed.
1370 block_size) - 1;
1371 ni->itype.compressed.block_clusters = 1U <<
1372 a->data.non_resident.
1373 compression_unit;
1374 } else {
1375 ni->itype.compressed.block_size = 0;
1376 ni->itype.compressed.block_size_bits = 0;
1377 ni->itype.compressed.block_clusters = 0;
1378 }
1357 ni->itype.compressed.size = sle64_to_cpu( 1379 ni->itype.compressed.size = sle64_to_cpu(
1358 a->data.non_resident.compressed_size); 1380 a->data.non_resident.compressed_size);
1359 } 1381 }
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index bb408d4dcbb0..f4283e120709 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -769,7 +769,7 @@ typedef struct {
769 compressed. (This effectively limits the 769 compressed. (This effectively limits the
770 compression unit size to be a power of two 770 compression unit size to be a power of two
771 clusters.) WinNT4 only uses a value of 4. 771 clusters.) WinNT4 only uses a value of 4.
772 Sparse files also have this set to 4. */ 772 Sparse files have this set to 0 on XPSP2. */
773/* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */ 773/* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */
774/* The sizes below are only used when lowest_vcn is zero, as otherwise it would 774/* The sizes below are only used when lowest_vcn is zero, as otherwise it would
775 be difficult to keep them up-to-date.*/ 775 be difficult to keep them up-to-date.*/
@@ -1076,16 +1076,21 @@ typedef struct {
1076/* 20*/ sle64 last_access_time; /* Time this mft record was last 1076/* 20*/ sle64 last_access_time; /* Time this mft record was last
1077 accessed. */ 1077 accessed. */
1078/* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space 1078/* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space
1079 for the data attribute. So for 1079 for the unnamed data attribute. So
1080 normal $DATA, this is the 1080 for normal $DATA, this is the
1081 allocated_size from the unnamed 1081 allocated_size from the unnamed
1082 $DATA attribute and for compressed 1082 $DATA attribute and for compressed
1083 and/or sparse $DATA, this is the 1083 and/or sparse $DATA, this is the
1084 compressed_size from the unnamed 1084 compressed_size from the unnamed
1085 $DATA attribute. NOTE: This is a 1085 $DATA attribute. For a directory or
1086 multiple of the cluster size. */ 1086 other inode without an unnamed $DATA
1087/* 30*/ sle64 data_size; /* Byte size of actual data in data 1087 attribute, this is always 0. NOTE:
1088 attribute. */ 1088 This is a multiple of the cluster
1089 size. */
1090/* 30*/ sle64 data_size; /* Byte size of actual data in unnamed
1091 data attribute. For a directory or
1092 other inode without an unnamed $DATA
1093 attribute, this is always 0. */
1089/* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */ 1094/* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
1090/* 3c*/ union { 1095/* 3c*/ union {
1091 /* 3c*/ struct { 1096 /* 3c*/ struct {