From 1eed61e1a9c9fee19938a00674e30cd7c9a64864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Tue, 25 May 2010 10:29:34 +0200 Subject: [PATCH] enabled downsizing compressed files --- libntfs-3g/attrib.c | 24 +++++++++++++++++------- src/lowntfs-3g.c | 9 +-------- src/ntfs-3g.c | 9 +-------- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index eb841fce..48906157 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -5533,8 +5533,19 @@ static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize) } /* The first cluster outside the new allocation. */ - first_free_vcn = (newsize + vol->cluster_size - 1) >> - vol->cluster_size_bits; + if (na->data_flags & ATTR_COMPRESSION_MASK) + /* + * For compressed files we must keep full compressions blocks, + * but currently we do not decompress/recompress the last + * block to truncate the data, so we may leave more allocated + * clusters than really needed. + */ + first_free_vcn = (((newsize - 1) + | (na->compression_block_size - 1)) + 1) + >> vol->cluster_size_bits; + else + first_free_vcn = (newsize + vol->cluster_size - 1) >> + vol->cluster_size_bits; /* * Compare the new allocation with the old one and only deallocate * clusters if there is a change. @@ -5923,8 +5934,7 @@ int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize) != const_cpu_to_le16(0); if (compressed && NAttrNonResident(na) - && (((na->data_flags & ATTR_COMPRESSION_MASK) != ATTR_IS_COMPRESSED) - || (newsize && (newsize < na->data_size)))) { + && ((na->data_flags & ATTR_COMPRESSION_MASK) != ATTR_IS_COMPRESSED)) { errno = EOPNOTSUPP; ntfs_log_perror("Failed to truncate compressed attribute"); goto out; @@ -5932,16 +5942,16 @@ int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize) if (NAttrNonResident(na)) { /* * For compressed data, the last block must be fully - * allocated, and we do not known the size of compression + * allocated, and we do not know the size of compression * block until the attribute has been made non-resident. * Moreover we can only process a single compression * block at a time (from where we are about to write), * so we silently do not allocate more. * - * Note : do not request truncate on compressed files + * Note : do not request upsizing of compressed files * unless being able to face the consequences ! */ - if (compressed && newsize) + if (compressed && newsize && (newsize > na->data_size)) fullsize = (na->initialized_size | (na->compression_block_size - 1)) + 1; else diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 2cf6e0e5..f89eac92 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -1554,16 +1554,9 @@ static int ntfs_fuse_trunc(struct SECURITY_CONTEXT *scx, fuse_ino_t ino, } #endif /* - * for compressed files, only deleting contents and expanding - * are implemented. Expanding is done by inserting a final + * for compressed files, upsizing is done by inserting a final * zero, which is optimized as creating a hole when possible. */ - if ((na->data_flags & ATTR_COMPRESSION_MASK) - && size - && (size < na->initialized_size)) { - errno = EOPNOTSUPP; - goto exit; - } oldsize = na->data_size; if ((na->data_flags & ATTR_COMPRESSION_MASK) && (size > na->initialized_size)) { diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 50bd80f9..970b0456 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -1413,16 +1413,9 @@ static int ntfs_fuse_trunc(const char *org_path, off_t size, } #endif /* - * for compressed files, only deleting contents and expanding - * are implemented. Expanding is done by inserting a final + * For compressed files, upsizing is done by inserting a final * zero, which is optimized as creating a hole when possible. */ - if ((na->data_flags & ATTR_COMPRESSION_MASK) - && size - && (size < na->initialized_size)) { - errno = EOPNOTSUPP; - goto exit; - } oldsize = na->data_size; if ((na->data_flags & ATTR_COMPRESSION_MASK) && (size > na->initialized_size)) {