diff options
author | David Howells <dhowells@redhat.com> | 2021-09-08 22:55:19 +0200 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2021-09-13 10:14:21 +0200 |
commit | 9d37e1cab2a9d2cee2737973fa455e6f89eee46a (patch) | |
tree | d9243277c6562bfc552895293edd2c4a1ad3dede /fs/afs/internal.h | |
parent | afs: Fix corruption in reads at fpos 2G-4G from an OpenAFS server (diff) | |
download | linux-9d37e1cab2a9d2cee2737973fa455e6f89eee46a.tar.xz linux-9d37e1cab2a9d2cee2737973fa455e6f89eee46a.zip |
afs: Fix updating of i_blocks on file/dir extension
When an afs file or directory is modified locally such that the total file
size is extended, i_blocks needs to be recalculated too.
Fix this by making afs_write_end() and afs_edit_dir_add() call
afs_set_i_size() rather than setting inode->i_size directly as that also
recalculates inode->i_blocks.
This can be tested by creating and writing into directories and files and
then examining them with du. Without this change, directories show a 4
blocks (they start out at 2048 bytes) and files show 0 blocks; with this
change, they should show a number of blocks proportional to the file size
rounded up to 1024.
Fixes: 31143d5d515e ("AFS: implement basic file write support")
Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...")
Reported-by: Markus Suvanto <markus.suvanto@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Marc Dionne <marc.dionne@auristor.com>
Tested-by: Markus Suvanto <markus.suvanto@gmail.com>
cc: linux-afs@lists.infradead.org
Link: https://lore.kernel.org/r/163113612442.352844.11162345591911691150.stgit@warthog.procyon.org.uk/
Diffstat (limited to 'fs/afs/internal.h')
-rw-r--r-- | fs/afs/internal.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index b0fe27ae60db..0ad97a8fc0d4 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1597,6 +1597,16 @@ static inline void afs_update_dentry_version(struct afs_operation *op, } /* + * Set the file size and block count. Estimate the number of 512 bytes blocks + * used, rounded up to nearest 1K for consistency with other AFS clients. + */ +static inline void afs_set_i_size(struct afs_vnode *vnode, u64 size) +{ + i_size_write(&vnode->vfs_inode, size); + vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1; +} + +/* * Check for a conflicting operation on a directory that we just unlinked from. * If someone managed to sneak a link or an unlink in on the file we just * unlinked, we won't be able to trust nlink on an AFS file (but not YFS). |