Do not create holes in ntfs_attr_pwrite that will be instantiated right after creation
* Add new API: __ntfs_attr_truncate that allow user to select whether holes should be created or clusters allocated * Update ntfs_attr_pwrite and ntfscp to use it.edge.strict_endians
parent
52d034e5f3
commit
e6620be16d
|
@ -315,6 +315,7 @@ extern int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra);
|
|||
|
||||
extern int ntfs_attr_update_mapping_pairs(ntfs_attr *na, VCN from_vcn);
|
||||
|
||||
extern int __ntfs_attr_truncate(ntfs_attr *na, const s64 newsize, BOOL sparse);
|
||||
extern int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize);
|
||||
|
||||
extern int ntfs_attr_exist(ntfs_inode *ni, const ATTR_TYPES type,
|
||||
|
|
|
@ -986,7 +986,7 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b)
|
|||
/* If the write reaches beyond the end, extend the attribute. */
|
||||
old_data_size = na->data_size;
|
||||
if (pos + count > na->data_size) {
|
||||
if (ntfs_attr_truncate(na, pos + count)) {
|
||||
if (__ntfs_attr_truncate(na, pos + count, FALSE)) {
|
||||
eo = errno;
|
||||
ntfs_log_trace("Attribute extend failed.\n");
|
||||
errno = eo;
|
||||
|
@ -4698,6 +4698,7 @@ put_err_out:
|
|||
* ntfs_non_resident_attr_expand - expand a non-resident, open ntfs attribute
|
||||
* @na: non-resident ntfs attribute to expand
|
||||
* @newsize: new size (in bytes) to which to expand the attribute
|
||||
* @sparse: if TRUE then will create hole if possible
|
||||
*
|
||||
* Expand the size of a non-resident, open ntfs attribute @na to @newsize bytes,
|
||||
* by allocating new clusters.
|
||||
|
@ -4708,7 +4709,8 @@ put_err_out:
|
|||
* ERANGE - @newsize is not valid for the attribute type of @na.
|
||||
* ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST.
|
||||
*/
|
||||
static int ntfs_non_resident_attr_expand(ntfs_attr *na, const s64 newsize)
|
||||
static int ntfs_non_resident_attr_expand(ntfs_attr *na, const s64 newsize,
|
||||
BOOL sparse)
|
||||
{
|
||||
LCN lcn_seek_from;
|
||||
VCN first_free_vcn;
|
||||
|
@ -4758,7 +4760,7 @@ static int ntfs_non_resident_attr_expand(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) {
|
||||
if (na->type == AT_DATA && vol->major_ver >= 3 && sparse) {
|
||||
rl = ntfs_malloc(0x1000);
|
||||
if (!rl)
|
||||
return -1;
|
||||
|
@ -4903,10 +4905,12 @@ put_err_out:
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ntfs_attr_truncate - resize an ntfs attribute
|
||||
* __ntfs_attr_truncate - resize an ntfs attribute
|
||||
* @na: open ntfs attribute to resize
|
||||
* @newsize: new size (in bytes) to which to resize the attribute
|
||||
* @sparse: if TRUE then will create hole if possible
|
||||
*
|
||||
* Change the size of an open ntfs attribute @na to @newsize bytes. If the
|
||||
* attribute is made bigger and the attribute is resident the newly
|
||||
|
@ -4926,7 +4930,7 @@ put_err_out:
|
|||
* @newsize bytes length.
|
||||
* EOPNOTSUPP - The desired resize is not implemented yet.
|
||||
*/
|
||||
int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
||||
int __ntfs_attr_truncate(ntfs_attr *na, const s64 newsize, BOOL sparse)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -4959,7 +4963,8 @@ int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
|||
}
|
||||
if (NAttrNonResident(na)) {
|
||||
if (newsize > na->data_size)
|
||||
ret = ntfs_non_resident_attr_expand(na, newsize);
|
||||
ret = ntfs_non_resident_attr_expand(na, newsize,
|
||||
sparse);
|
||||
else
|
||||
ret = ntfs_non_resident_attr_shrink(na, newsize);
|
||||
} else
|
||||
|
@ -4971,6 +4976,16 @@ int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper around __ntfs_attr_truncate that always tries to creates hole
|
||||
*/
|
||||
int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
||||
{
|
||||
return __ntfs_attr_truncate(na, newsize, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ntfs_attr_readall - read the entire data from an ntfs attribute
|
||||
* @ni: open ntfs inode in which the ntfs attribute resides
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* ntfscp - Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2004-2006 Yura Pakhuchiy
|
||||
* Copyright (c) 2004-2007 Yura Pakhuchiy
|
||||
* Copyright (c) 2005 Anton Altaparmakov
|
||||
* Copyright (c) 2006 Hil Liao
|
||||
*
|
||||
|
@ -85,7 +85,7 @@ static void version(void)
|
|||
{
|
||||
ntfs_log_info("\n%s v%s (libntfs %s) - Overwrite files on NTFS "
|
||||
"volume.\n\n", EXEC_NAME, VERSION, ntfs_libntfs_version());
|
||||
ntfs_log_info("Copyright (c) 2004-2006 Yura Pakhuchiy\n");
|
||||
ntfs_log_info("Copyright (c) 2004-2007 Yura Pakhuchiy\n");
|
||||
ntfs_log_info("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
|
||||
}
|
||||
|
||||
|
@ -524,7 +524,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
ntfs_log_verbose("Old file size: %lld\n", na->data_size);
|
||||
if (na->data_size != new_size) {
|
||||
if (ntfs_attr_truncate(na, new_size)) {
|
||||
if (__ntfs_attr_truncate(na, new_size, FALSE)) {
|
||||
ntfs_log_perror("ERROR: Couldn't resize attribute");
|
||||
goto close_attr;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue