Unverified Commit 40bb3c59 authored by Konstantin Komarov's avatar Konstantin Komarov
Browse files

fs/ntfs3: Always make file nonresident on fallocate call



xfstest 438 is starting to pass with this change.

Signed-off-by: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
parent c935c668
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -2558,3 +2558,35 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)

	goto out;
}

/*
 * attr_force_nonresident
 *
 * Convert default data attribute into non resident form.
 */
int attr_force_nonresident(struct ntfs_inode *ni)
{
	int err;
	struct ATTRIB *attr;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct mft_inode *mi;

	attr = ni_find_attr(ni, NULL, &le, ATTR_DATA, NULL, 0, NULL, &mi);
	if (!attr) {
		ntfs_bad_inode(&ni->vfs_inode, "no data attribute");
		return -ENOENT;
	}

	if (attr->non_res) {
		/* Already non resident. */
		return 0;
	}

	down_write(&ni->file.run_lock);
	err = attr_make_nonresident(ni, attr, le, mi,
				    le32_to_cpu(attr->res.data_size),
				    &ni->file.run, &attr, NULL);
	up_write(&ni->file.run_lock);

	return err;
}
+9 −0
Original line number Diff line number Diff line
@@ -578,6 +578,15 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
		/* Check new size. */
		u8 cluster_bits = sbi->cluster_bits;

		/* Be sure file is non resident. */
		if (is_resident(ni)) {
			ni_lock(ni);
			err = attr_force_nonresident(ni);
			ni_unlock(ni);
			if (err)
				goto out;
		}

		/* generic/213: expected -ENOSPC instead of -EFBIG. */
		if (!is_supported_holes) {
			loff_t to_alloc = new_size - inode_get_bytes(inode);
+1 −0
Original line number Diff line number Diff line
@@ -452,6 +452,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
int attr_force_nonresident(struct ntfs_inode *ni);

/* Functions from attrlist.c */
void al_destroy(struct ntfs_inode *ni);