Fixed compressed attribute made non resident to leave space for another one

This commit is contained in:
Jean-Pierre André 2010-06-18 14:02:58 +02:00
parent f2f4e8dc07
commit b1de6e16fb
2 changed files with 28 additions and 1 deletions

View File

@ -200,7 +200,8 @@ typedef enum {
NA_Initialized, /* 1: structure is initialized. */
NA_NonResident, /* 1: Attribute is not resident. */
NA_BeingNonResident, /* 1: Attribute is being made not resident. */
NA_FullyMapped, /* 1: Attribute has beed fully mapped */
NA_FullyMapped, /* 1: Attribute has been fully mapped */
NA_ComprClosing, /* 1: Compressed attribute is being closed */
} ntfs_attr_state_bits;
#define test_nattr_flag(na, flag) test_bit(NA_##flag, (na)->state)
@ -223,6 +224,10 @@ typedef enum {
#define NAttrSetFullyMapped(na) set_nattr_flag(na, FullyMapped)
#define NAttrClearFullyMapped(na) clear_nattr_flag(na, FullyMapped)
#define NAttrComprClosing(na) test_nattr_flag(na, ComprClosing)
#define NAttrSetComprClosing(na) set_nattr_flag(na, ComprClosing)
#define NAttrClearComprClosing(na) clear_nattr_flag(na, ComprClosing)
#define GenNAttrIno(func_name, flag) \
extern int NAttr##func_name(ntfs_attr *na); \
extern void NAttrSet##func_name(ntfs_attr *na); \

View File

@ -2127,6 +2127,7 @@ int ntfs_attr_pclose(ntfs_attr *na)
if (!compressed || !NAttrNonResident(na))
goto out;
NAttrSetComprClosing(na); /* for safety checks */
/*
* For a compressed attribute, we must be sure there are two
* available entries, so reserve them before it gets too late.
@ -4518,6 +4519,13 @@ int ntfs_attr_make_non_resident(ntfs_attr *na,
- 1) & ~(vol->cluster_size - 1);
if (new_allocated_size > 0) {
if ((a->flags & ATTR_COMPRESSION_MASK)
== ATTR_IS_COMPRESSED) {
/* must allocate full compression blocks */
new_allocated_size = ((new_allocated_size - 1)
| ((1L << (STANDARD_COMPRESSION_UNIT
+ vol->cluster_size_bits)) - 1)) + 1;
}
/* Start by allocating clusters to hold the attribute value. */
rl = ntfs_cluster_alloc(vol, 0, new_allocated_size >>
vol->cluster_size_bits, -1, DATA_ZONE);
@ -4791,6 +4799,20 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize)
ntfs_attr_close(tna);
continue;
}
if (((tna->data_flags & ATTR_COMPRESSION_MASK)
== ATTR_IS_COMPRESSED)
&& (NAttrComprClosing(tna) || ntfs_attr_pclose(tna))) {
/* safety check : no recursion on close */
if (NAttrComprClosing(tna)) {
err = EIO;
ntfs_log_error("Bad ntfs_attr_pclose"
" recursion on inode %lld\n",
(long long)tna->ni->mft_no);
} else
err = errno;
ntfs_attr_close(tna);
goto put_err_out;
}
ntfs_inode_mark_dirty(tna->ni);
ntfs_attr_close(tna);
ntfs_attr_put_search_ctx(ctx);