From addc9be334e80551a2b07085e7875788db55f6ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Tue, 8 Feb 2011 13:52:12 +0100 Subject: [PATCH] Merged sparse testing when appending with ntfsprogs requirement --- include/ntfs-3g/attrib.h | 5 ----- libntfs-3g/attrib.c | 40 +++++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/include/ntfs-3g/attrib.h b/include/ntfs-3g/attrib.h index 35ad4cf9..3bf538cf 100644 --- a/include/ntfs-3g/attrib.h +++ b/include/ntfs-3g/attrib.h @@ -203,7 +203,6 @@ typedef enum { NA_BeingNonResident, /* 1: Attribute is being made not resident. */ NA_FullyMapped, /* 1: Attribute has been fully mapped */ NA_DataAppending, /* 1: Attribute is being appended to */ - NA_DelaySparsing, /* 1: Delay checking attribute being sparse */ NA_ComprClosing, /* 1: Compressed attribute is being closed */ } ntfs_attr_state_bits; @@ -231,10 +230,6 @@ typedef enum { #define NAttrSetDataAppending(na) set_nattr_flag(na, DataAppending) #define NAttrClearDataAppending(na) clear_nattr_flag(na, DataAppending) -#define NAttrDelaySparsing(na) test_nattr_flag(na, DelaySparsing) -#define NAttrSetDelaySparsing(na) set_nattr_flag(na, DelaySparsing) -#define NAttrClearDelaySparsing(na) clear_nattr_flag(na, DelaySparsing) - #define NAttrComprClosing(na) test_nattr_flag(na, ComprClosing) #define NAttrSetComprClosing(na) set_nattr_flag(na, ComprClosing) #define NAttrClearComprClosing(na) clear_nattr_flag(na, ComprClosing) diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index 87b0744b..ff6583c0 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -1711,6 +1711,8 @@ static int borrow_from_hole(ntfs_attr *na, runlist_element **prl, return (compressed_part); } +static int ntfs_attr_truncate_i(ntfs_attr *na, const s64 newsize, BOOL holes); + /** * ntfs_attr_pwrite - positioned write to an ntfs attribute * @na: ntfs attribute to write to @@ -1815,20 +1817,19 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b) * attribute to be made temporarily sparse, which * implies reformating the inode and reorganizing the * full runlist. To avoid unnecessary reorganization, - * we delay sparse testing until the data is filled in. - * - * Note : should add a specific argument to truncate() - * instead of the hackish test of a flag... + * we avoid sparse testing until the data is filled in. */ - if (NAttrDataAppending(na)) - NAttrSetDelaySparsing(na); -#endif - if (ntfs_attr_truncate(na, pos + count)) { - NAttrClearDelaySparsing(na); + if (ntfs_attr_truncate_i(na, pos + count, + !NAttrDataAppending(na))) { ntfs_log_perror("Failed to enlarge attribute"); goto errno_set; } - NAttrClearDelaySparsing(na); +#else + if (ntfs_attr_truncate(na, pos + count)) { + ntfs_log_perror("Failed to enlarge attribute"); + goto errno_set; + } +#endif /* resizing may change the compression mode */ compressed = (na->data_flags & ATTR_COMPRESSION_MASK) != const_cpu_to_le16(0); @@ -5348,7 +5349,7 @@ static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx) * update allocated and compressed size. */ static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m, - ntfs_attr_search_ctx *ctx) + BOOL holes, ntfs_attr_search_ctx *ctx) { int sparse, ret = 0; @@ -5361,7 +5362,7 @@ static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m, a->allocated_size = cpu_to_sle64(na->allocated_size); /* Update sparse bit, unless this is an intermediate state */ - if (NAttrDelaySparsing(na)) + if (!holes) sparse = (a->flags & ATTR_IS_SPARSE) != const_cpu_to_le16(0); else { sparse = ntfs_rl_sparse(na->rl); @@ -5372,7 +5373,7 @@ static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m, } /* Check whether attribute becomes sparse, unless check is delayed. */ - if (!NAttrDelaySparsing(na) + if (holes && sparse && !(a->flags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) { /* @@ -5474,7 +5475,8 @@ error: ret = -3; goto out; /** * ntfs_attr_update_mapping_pairs_i - see ntfs_attr_update_mapping_pairs */ -static int ntfs_attr_update_mapping_pairs_i(ntfs_attr *na, VCN from_vcn) +static int ntfs_attr_update_mapping_pairs_i(ntfs_attr *na, VCN from_vcn, + BOOL holes) { ntfs_attr_search_ctx *ctx; ntfs_inode *ni, *base_ni; @@ -5510,7 +5512,7 @@ retry: * Same if the file was sparse and is not any more. * Note : not needed if the full runlist is to be processed */ - if (!NAttrDelaySparsing(na) + if (holes && (!NAttrFullyMapped(na) || from_vcn) && !(na->data_flags & ATTR_IS_COMPRESSED)) { BOOL changed; @@ -5616,7 +5618,7 @@ retry: continue; } - switch (ntfs_attr_update_meta(a, na, m, ctx)) { + switch (ntfs_attr_update_meta(a, na, m, holes, ctx)) { case -1: return -1; case -2: goto retry; case -3: goto put_err_out; @@ -5912,7 +5914,7 @@ int ntfs_attr_update_mapping_pairs(ntfs_attr *na, VCN from_vcn) int ret; ntfs_log_enter("Entering\n"); - ret = ntfs_attr_update_mapping_pairs_i(na, from_vcn); + ret = ntfs_attr_update_mapping_pairs_i(na, from_vcn, TRUE); ntfs_log_leave("\n"); return ret; } @@ -6147,7 +6149,7 @@ static int ntfs_non_resident_attr_expand_i(ntfs_attr *na, const s64 newsize, * If we extend $DATA attribute on NTFS 3+ volume, we can add * sparse runs instead of real allocation of clusters. */ - if ((na->type == AT_DATA && vol->major_ver >= 3) && holes) { + if ((na->type == AT_DATA) && (vol->major_ver >= 3) && holes) { rl = ntfs_malloc(0x1000); if (!rl) return -1; @@ -6218,7 +6220,7 @@ static int ntfs_non_resident_attr_expand_i(ntfs_attr *na, const s64 newsize, na->allocated_size = first_free_vcn << vol->cluster_size_bits; /* Write mapping pairs for new runlist. */ #if PARTIAL_RUNLIST_UPDATING - if (ntfs_attr_update_mapping_pairs(na, start_update)) { + if (ntfs_attr_update_mapping_pairs_i(na, start_update, holes)) { #else if (ntfs_attr_update_mapping_pairs(na, 0)) { #endif