|
@@ -1013,41 +1013,50 @@ skip_large_dir_stuff:
|
|
}
|
|
}
|
|
a = ctx->attr;
|
|
a = ctx->attr;
|
|
/* Setup the state. */
|
|
/* Setup the state. */
|
|
- if (a->non_resident) {
|
|
|
|
- NInoSetNonResident(ni);
|
|
|
|
- if (a->flags & (ATTR_COMPRESSION_MASK |
|
|
|
|
- ATTR_IS_SPARSE)) {
|
|
|
|
- if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
- NInoSetCompressed(ni);
|
|
|
|
- if (vol->cluster_size > 4096) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found "
|
|
|
|
|
|
+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
|
|
|
|
+ if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
+ NInoSetCompressed(ni);
|
|
|
|
+ if (vol->cluster_size > 4096) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found "
|
|
"compressed data but "
|
|
"compressed data but "
|
|
"compression is "
|
|
"compression is "
|
|
"disabled due to "
|
|
"disabled due to "
|
|
"cluster size (%i) > "
|
|
"cluster size (%i) > "
|
|
"4kiB.",
|
|
"4kiB.",
|
|
vol->cluster_size);
|
|
vol->cluster_size);
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- if ((a->flags & ATTR_COMPRESSION_MASK)
|
|
|
|
- != ATTR_IS_COMPRESSED) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found "
|
|
|
|
- "unknown compression "
|
|
|
|
- "method or corrupt "
|
|
|
|
- "file.");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ if ((a->flags & ATTR_COMPRESSION_MASK)
|
|
|
|
+ != ATTR_IS_COMPRESSED) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found unknown "
|
|
|
|
+ "compression method "
|
|
|
|
+ "or corrupt file.");
|
|
|
|
+ goto unm_err_out;
|
|
}
|
|
}
|
|
- if (a->flags & ATTR_IS_SPARSE)
|
|
|
|
- NInoSetSparse(ni);
|
|
|
|
|
|
+ }
|
|
|
|
+ if (a->flags & ATTR_IS_SPARSE)
|
|
|
|
+ NInoSetSparse(ni);
|
|
|
|
+ }
|
|
|
|
+ if (a->flags & ATTR_IS_ENCRYPTED) {
|
|
|
|
+ if (NInoCompressed(ni)) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found encrypted and "
|
|
|
|
+ "compressed data.");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ NInoSetEncrypted(ni);
|
|
|
|
+ }
|
|
|
|
+ if (a->non_resident) {
|
|
|
|
+ NInoSetNonResident(ni);
|
|
|
|
+ if (NInoCompressed(ni) || NInoSparse(ni)) {
|
|
if (a->data.non_resident.compression_unit !=
|
|
if (a->data.non_resident.compression_unit !=
|
|
4) {
|
|
4) {
|
|
ntfs_error(vi->i_sb, "Found "
|
|
ntfs_error(vi->i_sb, "Found "
|
|
- "nonstandard compression unit "
|
|
|
|
- "(%u instead of 4). Cannot "
|
|
|
|
- "handle this.",
|
|
|
|
- a->data.non_resident.
|
|
|
|
- compression_unit);
|
|
|
|
|
|
+ "nonstandard "
|
|
|
|
+ "compression unit (%u "
|
|
|
|
+ "instead of 4). "
|
|
|
|
+ "Cannot handle this.",
|
|
|
|
+ a->data.non_resident.
|
|
|
|
+ compression_unit);
|
|
err = -EOPNOTSUPP;
|
|
err = -EOPNOTSUPP;
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
}
|
|
}
|
|
@@ -1065,14 +1074,6 @@ skip_large_dir_stuff:
|
|
a->data.non_resident.
|
|
a->data.non_resident.
|
|
compressed_size);
|
|
compressed_size);
|
|
}
|
|
}
|
|
- if (a->flags & ATTR_IS_ENCRYPTED) {
|
|
|
|
- if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found encrypted "
|
|
|
|
- "and compressed data.");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- NInoSetEncrypted(ni);
|
|
|
|
- }
|
|
|
|
if (a->data.non_resident.lowest_vcn) {
|
|
if (a->data.non_resident.lowest_vcn) {
|
|
ntfs_error(vi->i_sb, "First extent of $DATA "
|
|
ntfs_error(vi->i_sb, "First extent of $DATA "
|
|
"attribute has non zero "
|
|
"attribute has non zero "
|
|
@@ -1212,6 +1213,75 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
|
|
if (unlikely(err))
|
|
if (unlikely(err))
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
a = ctx->attr;
|
|
a = ctx->attr;
|
|
|
|
+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
|
|
|
|
+ if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
+ NInoSetCompressed(ni);
|
|
|
|
+ if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&
|
|
|
|
+ ni->name_len)) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found compressed "
|
|
|
|
+ "non-data or named data "
|
|
|
|
+ "attribute. Please report "
|
|
|
|
+ "you saw this message to "
|
|
|
|
+ "linux-ntfs-dev@lists."
|
|
|
|
+ "sourceforge.net");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ if (vol->cluster_size > 4096) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found compressed "
|
|
|
|
+ "attribute but compression is "
|
|
|
|
+ "disabled due to cluster size "
|
|
|
|
+ "(%i) > 4kiB.",
|
|
|
|
+ vol->cluster_size);
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ if ((a->flags & ATTR_COMPRESSION_MASK) !=
|
|
|
|
+ ATTR_IS_COMPRESSED) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found unknown "
|
|
|
|
+ "compression method.");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /*
|
|
|
|
+ * The encryption flag set in an index root just means to
|
|
|
|
+ * compress all files.
|
|
|
|
+ */
|
|
|
|
+ if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found mst protected attribute "
|
|
|
|
+ "but the attribute is %s. Please "
|
|
|
|
+ "report you saw this message to "
|
|
|
|
+ "linux-ntfs-dev@lists.sourceforge.net",
|
|
|
|
+ NInoCompressed(ni) ? "compressed" :
|
|
|
|
+ "sparse");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ if (a->flags & ATTR_IS_SPARSE)
|
|
|
|
+ NInoSetSparse(ni);
|
|
|
|
+ }
|
|
|
|
+ if (a->flags & ATTR_IS_ENCRYPTED) {
|
|
|
|
+ if (NInoCompressed(ni)) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found encrypted and compressed "
|
|
|
|
+ "data.");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ /*
|
|
|
|
+ * The encryption flag set in an index root just means to
|
|
|
|
+ * encrypt all files.
|
|
|
|
+ */
|
|
|
|
+ if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found mst protected attribute "
|
|
|
|
+ "but the attribute is encrypted. "
|
|
|
|
+ "Please report you saw this message "
|
|
|
|
+ "to linux-ntfs-dev@lists.sourceforge."
|
|
|
|
+ "net");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ if (ni->type != AT_DATA) {
|
|
|
|
+ ntfs_error(vi->i_sb, "Found encrypted non-data "
|
|
|
|
+ "attribute.");
|
|
|
|
+ goto unm_err_out;
|
|
|
|
+ }
|
|
|
|
+ NInoSetEncrypted(ni);
|
|
|
|
+ }
|
|
if (!a->non_resident) {
|
|
if (!a->non_resident) {
|
|
/* Ensure the attribute name is placed before the value. */
|
|
/* Ensure the attribute name is placed before the value. */
|
|
if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
|
|
if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
|
|
@@ -1220,11 +1290,10 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
|
|
"the attribute value.");
|
|
"the attribute value.");
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
}
|
|
}
|
|
- if (NInoMstProtected(ni) || a->flags) {
|
|
|
|
|
|
+ if (NInoMstProtected(ni)) {
|
|
ntfs_error(vi->i_sb, "Found mst protected attribute "
|
|
ntfs_error(vi->i_sb, "Found mst protected attribute "
|
|
- "or attribute with non-zero flags but "
|
|
|
|
- "the attribute is resident. Please "
|
|
|
|
- "report you saw this message to "
|
|
|
|
|
|
+ "but the attribute is resident. "
|
|
|
|
+ "Please report you saw this message to "
|
|
"linux-ntfs-dev@lists.sourceforge.net");
|
|
"linux-ntfs-dev@lists.sourceforge.net");
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
}
|
|
}
|
|
@@ -1250,50 +1319,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
|
|
"the mapping pairs array.");
|
|
"the mapping pairs array.");
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
}
|
|
}
|
|
- if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
|
|
|
|
- if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
- NInoSetCompressed(ni);
|
|
|
|
- if ((ni->type != AT_DATA) || (ni->type ==
|
|
|
|
- AT_DATA && ni->name_len)) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found compressed "
|
|
|
|
- "non-data or named "
|
|
|
|
- "data attribute. "
|
|
|
|
- "Please report you "
|
|
|
|
- "saw this message to "
|
|
|
|
- "linux-ntfs-dev@lists."
|
|
|
|
- "sourceforge.net");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- if (vol->cluster_size > 4096) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found compressed "
|
|
|
|
- "attribute but "
|
|
|
|
- "compression is "
|
|
|
|
- "disabled due to "
|
|
|
|
- "cluster size (%i) > "
|
|
|
|
- "4kiB.",
|
|
|
|
- vol->cluster_size);
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- if ((a->flags & ATTR_COMPRESSION_MASK) !=
|
|
|
|
- ATTR_IS_COMPRESSED) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found unknown "
|
|
|
|
- "compression method.");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (NInoMstProtected(ni)) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found mst protected "
|
|
|
|
- "attribute but the attribute "
|
|
|
|
- "is %s. Please report you "
|
|
|
|
- "saw this message to "
|
|
|
|
- "linux-ntfs-dev@lists."
|
|
|
|
- "sourceforge.net",
|
|
|
|
- NInoCompressed(ni) ?
|
|
|
|
- "compressed" : "sparse");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- if (a->flags & ATTR_IS_SPARSE)
|
|
|
|
- NInoSetSparse(ni);
|
|
|
|
|
|
+ if ((NInoCompressed(ni) || NInoSparse(ni)) &&
|
|
|
|
+ ni->type != AT_INDEX_ROOT) {
|
|
if (a->data.non_resident.compression_unit != 4) {
|
|
if (a->data.non_resident.compression_unit != 4) {
|
|
ntfs_error(vi->i_sb, "Found nonstandard "
|
|
ntfs_error(vi->i_sb, "Found nonstandard "
|
|
"compression unit (%u instead "
|
|
"compression unit (%u instead "
|
|
@@ -1313,23 +1340,6 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
|
|
ni->itype.compressed.size = sle64_to_cpu(
|
|
ni->itype.compressed.size = sle64_to_cpu(
|
|
a->data.non_resident.compressed_size);
|
|
a->data.non_resident.compressed_size);
|
|
}
|
|
}
|
|
- if (a->flags & ATTR_IS_ENCRYPTED) {
|
|
|
|
- if (a->flags & ATTR_COMPRESSION_MASK) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found encrypted and "
|
|
|
|
- "compressed data.");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- if (NInoMstProtected(ni)) {
|
|
|
|
- ntfs_error(vi->i_sb, "Found mst protected "
|
|
|
|
- "attribute but the attribute "
|
|
|
|
- "is encrypted. Please report "
|
|
|
|
- "you saw this message to "
|
|
|
|
- "linux-ntfs-dev@lists."
|
|
|
|
- "sourceforge.net");
|
|
|
|
- goto unm_err_out;
|
|
|
|
- }
|
|
|
|
- NInoSetEncrypted(ni);
|
|
|
|
- }
|
|
|
|
if (a->data.non_resident.lowest_vcn) {
|
|
if (a->data.non_resident.lowest_vcn) {
|
|
ntfs_error(vi->i_sb, "First extent of attribute has "
|
|
ntfs_error(vi->i_sb, "First extent of attribute has "
|
|
"non-zero lowest_vcn.");
|
|
"non-zero lowest_vcn.");
|
|
@@ -1348,12 +1358,12 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
|
|
vi->i_mapping->a_ops = &ntfs_mst_aops;
|
|
vi->i_mapping->a_ops = &ntfs_mst_aops;
|
|
else
|
|
else
|
|
vi->i_mapping->a_ops = &ntfs_aops;
|
|
vi->i_mapping->a_ops = &ntfs_aops;
|
|
- if (NInoCompressed(ni) || NInoSparse(ni))
|
|
|
|
|
|
+ if ((NInoCompressed(ni) || NInoSparse(ni)) && ni->type != AT_INDEX_ROOT)
|
|
vi->i_blocks = ni->itype.compressed.size >> 9;
|
|
vi->i_blocks = ni->itype.compressed.size >> 9;
|
|
else
|
|
else
|
|
vi->i_blocks = ni->allocated_size >> 9;
|
|
vi->i_blocks = ni->allocated_size >> 9;
|
|
/*
|
|
/*
|
|
- * Make sure the base inode doesn't go away and attach it to the
|
|
|
|
|
|
+ * Make sure the base inode does not go away and attach it to the
|
|
* attribute inode.
|
|
* attribute inode.
|
|
*/
|
|
*/
|
|
igrab(base_vi);
|
|
igrab(base_vi);
|
|
@@ -1480,7 +1490,10 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
|
|
"after the attribute value.");
|
|
"after the attribute value.");
|
|
goto unm_err_out;
|
|
goto unm_err_out;
|
|
}
|
|
}
|
|
- /* Compressed/encrypted/sparse index root is not allowed. */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Compressed/encrypted/sparse index root is not allowed, except for
|
|
|
|
+ * directories of course but those are not dealt with here.
|
|
|
|
+ */
|
|
if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
|
|
if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
|
|
ATTR_IS_SPARSE)) {
|
|
ATTR_IS_SPARSE)) {
|
|
ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "
|
|
ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "
|