On Wed, 12 Mar 2025 15:07:20 +0100 Christian Schoenebeck <[email protected]> wrote:
> On Tuesday, March 11, 2025 6:28:06 PM CET Greg Kurz wrote: > > Add an ftruncate operation to the fs driver and use if when a fid has > > a valid file descriptor. This is required to support more cases where > > the client wants to do an action on an unlinked file which it still > > has an open file decriptor for. > > > > Only 9P2000.L was considered. > > > > Reviewed-by: Christian Schoenebeck <[email protected]> > > Signed-off-by: Greg Kurz <[email protected]> > > > > v2: - moved v9fs_co_ftruncate() near v9fs_co_truncate() in coth.h > > - similar change in file-op-9p.h > > --- > > fsdev/file-op-9p.h | 2 ++ > > hw/9pfs/9p-local.c | 9 +++++++++ > > hw/9pfs/9p-synth.c | 8 ++++++++ > > hw/9pfs/9p.c | 6 +++++- > > hw/9pfs/cofs.c | 18 ++++++++++++++++++ > > hw/9pfs/coth.h | 2 ++ > > 6 files changed, 44 insertions(+), 1 deletion(-) > > > > diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h > > index b815cea44e85..26ba1438c0ed 100644 > > --- a/fsdev/file-op-9p.h > > +++ b/fsdev/file-op-9p.h > > @@ -152,6 +152,8 @@ struct FileOperations { > > int (*fstat)(FsContext *, int, V9fsFidOpenState *, struct stat *); > > int (*rename)(FsContext *, const char *, const char *); > > int (*truncate)(FsContext *, V9fsPath *, off_t); > > + int (*ftruncate)(FsContext *ctx, int fid_type, V9fsFidOpenState *fs, > > + off_t size); > > int (*fsync)(FsContext *, int, V9fsFidOpenState *, int); > > int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf); > > ssize_t (*lgetxattr)(FsContext *, V9fsPath *, > > diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c > > index b16132299f2c..0b33da8d2a46 100644 > > --- a/hw/9pfs/9p-local.c > > +++ b/hw/9pfs/9p-local.c > > @@ -1042,6 +1042,14 @@ static int local_truncate(FsContext *ctx, V9fsPath > > *fs_path, off_t size) > > return ret; > > } > > > > +static int local_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState > > *fs, > > + off_t size) > > +{ > > + int fd = local_fid_fd(fid_type, fs); > > + > > + return ftruncate(fd, size); > > +} > > + > > static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) > > { > > char *dirpath = g_path_get_dirname(fs_path->data); > > @@ -1617,4 +1625,5 @@ FileOperations local_ops = { > > .renameat = local_renameat, > > .unlinkat = local_unlinkat, > > .has_valid_file_handle = local_has_valid_file_handle, > > + .ftruncate = local_ftruncate, > > }; > > diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c > > index be0492b400e1..3d28afc4d03d 100644 > > --- a/hw/9pfs/9p-synth.c > > +++ b/hw/9pfs/9p-synth.c > > @@ -356,6 +356,13 @@ static int synth_truncate(FsContext *ctx, V9fsPath > > *path, off_t offset) > > return -1; > > } > > > > +static int synth_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState > > *fs, > > + off_t size) > > +{ > > + errno = ENOSYS; > > + return -1; > > +} > > + > > static int synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp) > > { > > errno = EPERM; > > @@ -656,4 +663,5 @@ FileOperations synth_ops = { > > .renameat = synth_renameat, > > .unlinkat = synth_unlinkat, > > .has_valid_file_handle = synth_has_valid_file_handle, > > + .ftruncate = synth_ftruncate, > > }; > > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c > > index 10363f1a1df8..4616bd763012 100644 > > --- a/hw/9pfs/9p.c > > +++ b/hw/9pfs/9p.c > > @@ -1733,7 +1733,11 @@ static void coroutine_fn v9fs_setattr(void *opaque) > > } > > } > > if (v9iattr.valid & (P9_ATTR_SIZE)) { > > - err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size); > > + if (fid_has_valid_handle(pdu->s, fidp)) { > > + err = v9fs_co_ftruncate(pdu, fidp, v9iattr.size); > > + } else { > > + err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size); > > + } > > Like with previous patch, s/fid_has_valid_handle/fid_has_valid_file_handle/, > the rest is fine. > Oops... my bad. I'll fix that ! > Reviewed-by: Christian Schoenebeck <[email protected]> > > > if (err < 0) { > > goto out; > > } > > diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c > > index 67e3ae5c5ccd..893466fb1a44 100644 > > --- a/hw/9pfs/cofs.c > > +++ b/hw/9pfs/cofs.c > > @@ -184,6 +184,24 @@ int coroutine_fn v9fs_co_truncate(V9fsPDU *pdu, > > V9fsPath *path, off_t size) > > return err; > > } > > > > +int coroutine_fn v9fs_co_ftruncate(V9fsPDU *pdu, V9fsFidState *fidp, off_t > > size) > > +{ > > + int err; > > + V9fsState *s = pdu->s; > > + > > + if (v9fs_request_cancelled(pdu)) { > > + return -EINTR; > > + } > > + v9fs_co_run_in_worker( > > + { > > + err = s->ops->ftruncate(&s->ctx, fidp->fid_type, &fidp->fs, > > size); > > + if (err < 0) { > > + err = -errno; > > + } > > + }); > > + return err; > > +} > > + > > int coroutine_fn v9fs_co_mknod(V9fsPDU *pdu, V9fsFidState *fidp, > > V9fsString *name, uid_t uid, gid_t gid, > > dev_t dev, mode_t mode, struct stat *stbuf) > > diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h > > index 2c54249b3577..62e922dc12e3 100644 > > --- a/hw/9pfs/coth.h > > +++ b/hw/9pfs/coth.h > > @@ -73,6 +73,8 @@ int coroutine_fn v9fs_co_chmod(V9fsPDU *, V9fsPath *, > > mode_t); > > int coroutine_fn v9fs_co_utimensat(V9fsPDU *, V9fsPath *, struct timespec > > [2]); > > int coroutine_fn v9fs_co_chown(V9fsPDU *, V9fsPath *, uid_t, gid_t); > > int coroutine_fn v9fs_co_truncate(V9fsPDU *, V9fsPath *, off_t); > > +int coroutine_fn v9fs_co_ftruncate(V9fsPDU *pdu, V9fsFidState *fidp, > > + off_t size); > > int coroutine_fn v9fs_co_llistxattr(V9fsPDU *, V9fsPath *, void *, size_t); > > int coroutine_fn v9fs_co_lgetxattr(V9fsPDU *, V9fsPath *, > > V9fsString *, void *, size_t); > > > > -- Greg
