mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-11-23 10:04:00 +08:00
Fixed compressed attribute made non resident to leave space for another one
This commit is contained in:
parent
f2f4e8dc07
commit
b1de6e16fb
@ -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); \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user