Skip to content

Commit 9a2d6a4

Browse files
fs/ntfs3: Implement fallocate for compressed files
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent 70dd48c commit 9a2d6a4

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

fs/ntfs3/attrib.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -976,15 +976,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
976976
goto out;
977977

978978
/* Check for compressed frame. */
979-
err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint);
979+
err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT,
980+
&hint);
980981
if (err)
981982
goto out;
982983

983984
if (hint) {
984985
/* if frame is compressed - don't touch it. */
985986
*lcn = COMPRESSED_LCN;
986-
*len = hint;
987-
err = -EOPNOTSUPP;
987+
/* length to the end of frame. */
988+
*len = NTFS_LZNT_CLUSTERS - (vcn & (NTFS_LZNT_CLUSTERS - 1));
989+
err = 0;
988990
goto out;
989991
}
990992

@@ -1027,16 +1029,16 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
10271029

10281030
/* Check if 'vcn' and 'vcn0' in different attribute segments. */
10291031
if (vcn < svcn || evcn1 <= vcn) {
1030-
/* Load attribute for truncated vcn. */
1031-
attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0,
1032-
&vcn, &mi);
1033-
if (!attr) {
1032+
struct ATTRIB *attr2;
1033+
/* Load runs for truncated vcn. */
1034+
attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL,
1035+
0, &vcn, &mi);
1036+
if (!attr2) {
10341037
err = -EINVAL;
10351038
goto out;
10361039
}
1037-
svcn = le64_to_cpu(attr->nres.svcn);
1038-
evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
1039-
err = attr_load_runs(attr, ni, run, NULL);
1040+
evcn1 = le64_to_cpu(attr2->nres.evcn) + 1;
1041+
err = attr_load_runs(attr2, ni, run, NULL);
10401042
if (err)
10411043
goto out;
10421044
}
@@ -1517,6 +1519,9 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
15171519

15181520
/*
15191521
* attr_is_frame_compressed - Used to detect compressed frame.
1522+
*
1523+
* attr - base (primary) attribute segment.
1524+
* Only base segments contains valid 'attr->nres.c_unit'
15201525
*/
15211526
int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
15221527
CLST frame, CLST *clst_data)

fs/ntfs3/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo,
609609

610610
bytes = ((u64)len << cluster_bits) - off;
611611

612-
if (lcn == SPARSE_LCN) {
612+
if (lcn >= sbi->used.bitmap.nbits) {
613+
/* This case includes resident/compressed/sparse. */
613614
if (!create) {
614615
if (bh->b_size > bytes)
615616
bh->b_size = bytes;

0 commit comments

Comments
 (0)