Cleared the sparse flags when clearing the bad cluster list

The bad cluster list may be updated in ntfsresize and ntfsfix. Though
technically it is organized as a sparse file, Windows does not set
the sparse flags. Do the same to avoid problems with third-party
packages.
This commit is contained in:
Jean-Pierre André 2016-07-19 11:44:59 +02:00
parent 191e47ff9d
commit 38ff4602a7
2 changed files with 53 additions and 3 deletions

View File

@ -341,6 +341,39 @@ static int empty_journal(ntfs_volume *vol)
return 0;
}
/*
* Clear the sparse flag of an attribute
*/
static int clear_sparse(ntfs_attr *na, const char *name)
{
ntfs_attr_search_ctx *ctx;
int res;
res = -1;
ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
if (ctx) {
if (!ntfs_attr_lookup(na->type, na->name, na->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
na->data_flags &= ~ATTR_IS_SPARSE;
ctx->attr->data_size = cpu_to_sle64(na->data_size);
ctx->attr->initialized_size
= cpu_to_sle64(na->initialized_size);
ctx->attr->flags = cpu_to_le16(na->data_flags);
ctx->attr->compression_unit = 0;
ntfs_inode_mark_dirty(ctx->ntfs_ino);
NInoFileNameSetDirty(na->ni);
res = 0;
} else
ntfs_log_perror("Could not locate attribute for %s",
name);
ntfs_attr_put_search_ctx(ctx);
} else
ntfs_log_perror("Could not get a search context for %s",
name);
return (res);
}
/**
* Clear the bad cluster marks (option)
*/
@ -372,15 +405,14 @@ static int clear_badclus(ntfs_volume *vol)
* (which requires setting the data size according
* to allocation), then reallocate a sparse stream
* to full size of volume and reset the data size.
* Note : the sparse flags should not be set.
*/
na->data_size = na->allocated_size;
na->initialized_size = na->allocated_size;
if (!ntfs_attr_truncate(na,0)
&& !ntfs_attr_truncate(na,vol->nr_clusters
<< vol->cluster_size_bits)) {
na->data_size = 0;
na->initialized_size = 0;
ni->flags |= FILE_ATTR_SPARSE_FILE;
NInoFileNameSetDirty(ni);
ok = TRUE;
} else {
@ -390,6 +422,14 @@ static int clear_badclus(ntfs_volume *vol)
ntfs_log_info("No bad clusters...");
ok = TRUE;
}
/*
* The sparse flags are not set after an initial
* formatting, so do the same.
*/
if (ok) {
ni->flags &= ~FILE_ATTR_SPARSE_FILE;
ok = !clear_sparse(na, "$BadClus::$Bad");
}
ntfs_attr_close(na);
} else {
ntfs_log_perror("Failed to open $BadClus::$Bad");

View File

@ -2377,6 +2377,7 @@ static void truncate_badclust_bad_attr(ntfs_resize_t *resize)
{
ntfs_inode *base_ni;
ntfs_attr *na;
ntfs_attr_search_ctx *ctx;
s64 nr_clusters = resize->new_volume_size;
ntfs_volume *vol = resize->vol;
@ -2390,7 +2391,16 @@ static void truncate_badclust_bad_attr(ntfs_resize_t *resize)
err_printf("Could not adjust the bad sector list\n");
exit(1);
}
na->ni->flags |= FILE_ATTR_SPARSE_FILE;
/* Clear the sparse flags, even if there are bad clusters */
na->ni->flags &= ~FILE_ATTR_SPARSE_FILE;
na->data_flags &= ~ATTR_IS_SPARSE;
ctx = resize->ctx;
ctx->attr->data_size = cpu_to_sle64(na->data_size);
ctx->attr->initialized_size = cpu_to_sle64(na->initialized_size);
ctx->attr->flags = cpu_to_le16(na->data_flags);
ctx->attr->compression_unit = 0;
ntfs_inode_mark_dirty(ctx->ntfs_ino);
NInoFileNameSetDirty(na->ni);
NInoFileNameSetDirty(na->ni);
ntfs_attr_close(na);