AFS fixes
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEqG5UsNXhtOCrfGQP+7dXa6fLC2sFAmRRU+QACgkQ+7dXa6fL C2ujORAAgYRY+jNv0a4xV2tgekLL/Y3N6ARMm+85X+luLYtPRehDhhroO/85Bnc+ ajxUGObY1aNLZBXu4Oz8XAzb/EAwjLbvXqMzVuNqNq/a8YzysPYlSByKLzORU9dl ZCFMa3O+etV3LxkjLUCgQ/7MAR94vniIrqcHLg5pcMV4dUXSXVEJqZktntISQvRV bMgktcGo65q8/diCL0VX3D+3/eemWOIMUHLP4yhm0G1RKVv1QDdTf9gq7/JqjkMR 02+e/HD0Ezt0OXoP72tUR2d+6DUiifRJjWpB2hPHaab1eKJWvG2Y4Iy+A5oZJQGZ 2+Tmq5nJkbF82sgQQ9BwqK6dtLzibKFQlddcDZlSEm/yYxrv45hVrqSjvsDp1YKP ZH6vJqVMiQh8hXYYL9J+AtyIhPil6u7hxoyLosmrbECZhJzJd/gOO5U4XMfYPY73 zdeKSFpCmJ7E9EbW1F55zuQeZcRX3m0hSvfdfQ/65z7K777O8NlUWMeefzYqMwt5 VRKr5XY0Pkdp4cF8tAuMe9PT+9ZFrIOn6l6rqGsHvGv3N25T+0FVZd98WxF8mOrE 6L+9WQoGM4XTuAEviVSOJJacZv/mErPrau0O4jmN26RYAacLI7jD+SgozFeahck1 PKXStSx2PF7M7/sOnS+JSwph9qsx25icrby7hJkvpv4fGAqJ4Zs= =tpZl -----END PGP SIGNATURE----- Merge tag 'afs-fixes-20230502' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs Pull AFS updates from David Howells: "Three fixes to AFS directory handling: - Make sure that afs_read_dir() sees any increase in file size if the file unexpectedly changed on the server (e.g. due to another client making a change). - Make afs_getattr() always return the server's dir file size, not the locally edited one, so that pagecache eviction doesn't cause the dir file size to change unexpectedly. - Prevent afs_read_dir() from getting into an endless loop if the server indicates that the directory file size is larger than expected" * tag 'afs-fixes-20230502' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: afs: Avoid endless loop if file is larger than expected afs: Fix getattr to report server i_size on dirs, not local size afs: Fix updating of i_size with dv jump from server
This commit is contained in:
commit
21d2be6460
@ -275,6 +275,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
|
||||
loff_t i_size;
|
||||
int nr_pages, i;
|
||||
int ret;
|
||||
loff_t remote_size = 0;
|
||||
|
||||
_enter("");
|
||||
|
||||
@ -289,6 +290,8 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
|
||||
|
||||
expand:
|
||||
i_size = i_size_read(&dvnode->netfs.inode);
|
||||
if (i_size < remote_size)
|
||||
i_size = remote_size;
|
||||
if (i_size < 2048) {
|
||||
ret = afs_bad(dvnode, afs_file_error_dir_small);
|
||||
goto error;
|
||||
@ -364,6 +367,7 @@ expand:
|
||||
* buffer.
|
||||
*/
|
||||
up_write(&dvnode->validate_lock);
|
||||
remote_size = req->file_size;
|
||||
goto expand;
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,7 @@ static void afs_apply_status(struct afs_operation *op,
|
||||
set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
|
||||
}
|
||||
change_size = true;
|
||||
data_changed = true;
|
||||
} else if (vnode->status.type == AFS_FTYPE_DIR) {
|
||||
/* Expected directory change is handled elsewhere so
|
||||
* that we can locally edit the directory and save on a
|
||||
@ -449,7 +450,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
|
||||
0 : FSCACHE_ADV_SINGLE_CHUNK,
|
||||
&key, sizeof(key),
|
||||
&aux, sizeof(aux),
|
||||
vnode->status.size));
|
||||
i_size_read(&vnode->netfs.inode)));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -776,6 +777,13 @@ int afs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
|
||||
stat->nlink > 0)
|
||||
stat->nlink -= 1;
|
||||
|
||||
/* Lie about the size of directories. We maintain a locally
|
||||
* edited copy and may make different allocation decisions on
|
||||
* it, but we need to give userspace the server's size.
|
||||
*/
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
stat->size = vnode->netfs.remote_i_size;
|
||||
} while (need_seqretry(&vnode->cb_lock, seq));
|
||||
|
||||
done_seqretry(&vnode->cb_lock, seq);
|
||||
|
Loading…
x
Reference in New Issue
Block a user