mirror of
https://github.com/torvalds/linux
synced 2024-10-15 07:47:34 +00:00
fs/ntfs3: Always make file nonresident on fallocate call
xfstest 438 is starting to pass with this change. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
This commit is contained in:
parent
c935c66878
commit
40bb3c5905
|
@ -2558,3 +2558,35 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
|
||||||
|
|
||||||
goto out;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -578,6 +578,15 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
|
||||||
/* Check new size. */
|
/* Check new size. */
|
||||||
u8 cluster_bits = sbi->cluster_bits;
|
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. */
|
/* generic/213: expected -ENOSPC instead of -EFBIG. */
|
||||||
if (!is_supported_holes) {
|
if (!is_supported_holes) {
|
||||||
loff_t to_alloc = new_size - inode_get_bytes(inode);
|
loff_t to_alloc = new_size - inode_get_bytes(inode);
|
||||||
|
|
|
@ -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_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
|
||||||
int attr_insert_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_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 */
|
/* Functions from attrlist.c */
|
||||||
void al_destroy(struct ntfs_inode *ni);
|
void al_destroy(struct ntfs_inode *ni);
|
||||||
|
|
Loading…
Reference in a new issue