hw/9pfs: Add st_gen support in getattr reply
This patch use file system specific ioctl for getting i_generation value. Not all file system support the ioctl. So we add an export specific extended operation and assign right callback for the file system that support i_generation ioctl ["M. Mohan Kumar" <mohan@in.ibm.com> we can do ioctl only for regular files and directories on the server] Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
parent
9844081bca
commit
e06a765efb
17
configure
vendored
17
configure
vendored
@ -2568,6 +2568,19 @@ if compile_prog "" "" ; then
|
||||
open_by_handle_at=yes
|
||||
fi
|
||||
|
||||
########################################
|
||||
# check if we have linux/magic.h
|
||||
|
||||
linux_magic_h=no
|
||||
cat > $TMPC << EOF
|
||||
#include <linux/magic.h>
|
||||
int main(void) {
|
||||
}
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
linux_magic_h=yes
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# End of CC checks
|
||||
# After here, no more $cc or $ld runs
|
||||
@ -3051,6 +3064,10 @@ if test "$open_by_handle_at" = "yes" ; then
|
||||
echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$linux_magic_h" = "yes" ; then
|
||||
echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
# USB host support
|
||||
case "$usb" in
|
||||
linux)
|
||||
|
@ -49,6 +49,13 @@ typedef struct FsCred
|
||||
} FsCred;
|
||||
|
||||
struct xattr_operations;
|
||||
struct FsContext;
|
||||
struct V9fsPath;
|
||||
|
||||
typedef struct extended_ops {
|
||||
int (*get_st_gen)(struct FsContext *, struct V9fsPath *,
|
||||
mode_t, uint64_t *);
|
||||
} extended_ops;
|
||||
|
||||
/* FsContext flag values */
|
||||
#define PATHNAME_FSCONTEXT 0x1
|
||||
@ -64,6 +71,7 @@ typedef struct FsContext
|
||||
uid_t uid;
|
||||
int export_flags;
|
||||
struct xattr_operations **xops;
|
||||
struct extended_ops exops;
|
||||
/* fs driver specific data */
|
||||
void *private;
|
||||
} FsContext;
|
||||
|
@ -17,6 +17,30 @@
|
||||
#include "qemu-coroutine.h"
|
||||
#include "virtio-9p-coth.h"
|
||||
|
||||
int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
|
||||
V9fsStatDotl *v9stat)
|
||||
{
|
||||
int err = 0;
|
||||
V9fsState *s = pdu->s;
|
||||
|
||||
if (v9fs_request_cancelled(pdu)) {
|
||||
return -EINTR;
|
||||
}
|
||||
if (s->ctx.exops.get_st_gen) {
|
||||
v9fs_path_read_lock(s);
|
||||
v9fs_co_run_in_worker(
|
||||
{
|
||||
err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
|
||||
&v9stat->st_gen);
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
}
|
||||
});
|
||||
v9fs_path_unlock(s);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
|
||||
{
|
||||
int err;
|
||||
|
@ -101,4 +101,7 @@ extern int v9fs_co_preadv(V9fsPDU *, V9fsFidState *,
|
||||
struct iovec *, int, int64_t);
|
||||
extern int v9fs_co_name_to_path(V9fsPDU *, V9fsPath *,
|
||||
const char *, V9fsPath *);
|
||||
extern int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t,
|
||||
V9fsStatDotl *v9stat);
|
||||
|
||||
#endif
|
||||
|
@ -117,6 +117,8 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
|
||||
|
||||
s->ctx.export_flags = fse->export_flags;
|
||||
s->ctx.fs_root = g_strdup(fse->path);
|
||||
s->ctx.exops.get_st_gen = NULL;
|
||||
|
||||
len = strlen(conf->tag);
|
||||
if (len > MAX_TAG_LEN) {
|
||||
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
|
||||
|
@ -20,6 +20,24 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <attr/xattr.h>
|
||||
#include <linux/fs.h>
|
||||
#ifdef CONFIG_LINUX_MAGIC_H
|
||||
#include <linux/magic.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifndef XFS_SUPER_MAGIC
|
||||
#define XFS_SUPER_MAGIC 0x58465342
|
||||
#endif
|
||||
#ifndef EXT2_SUPER_MAGIC
|
||||
#define EXT2_SUPER_MAGIC 0xEF53
|
||||
#endif
|
||||
#ifndef REISERFS_SUPER_MAGIC
|
||||
#define REISERFS_SUPER_MAGIC 0x52654973
|
||||
#endif
|
||||
#ifndef BTRFS_SUPER_MAGIC
|
||||
#define BTRFS_SUPER_MAGIC 0x9123683E
|
||||
#endif
|
||||
|
||||
static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
|
||||
{
|
||||
@ -659,10 +677,44 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
|
||||
mode_t st_mode, uint64_t *st_gen)
|
||||
{
|
||||
int err, fd;
|
||||
/*
|
||||
* Do not try to open special files like device nodes, fifos etc
|
||||
* We can get fd for regular files and directories only
|
||||
*/
|
||||
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
|
||||
return 0;
|
||||
}
|
||||
fd = local_open(ctx, path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
err = ioctl(fd, FS_IOC_GETVERSION, st_gen);
|
||||
local_close(ctx, fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int local_init(FsContext *ctx)
|
||||
{
|
||||
int err;
|
||||
struct statfs stbuf;
|
||||
|
||||
ctx->flags |= PATHNAME_FSCONTEXT;
|
||||
return 0;
|
||||
err = statfs(ctx->fs_root, &stbuf);
|
||||
if (!err) {
|
||||
switch (stbuf.f_type) {
|
||||
case EXT2_SUPER_MAGIC:
|
||||
case BTRFS_SUPER_MAGIC:
|
||||
case REISERFS_SUPER_MAGIC:
|
||||
case XFS_SUPER_MAGIC:
|
||||
ctx->exops.get_st_gen = local_ioc_getversion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
FileOperations local_ops = {
|
||||
|
@ -1402,6 +1402,15 @@ static void v9fs_getattr(void *opaque)
|
||||
goto out;
|
||||
}
|
||||
stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl);
|
||||
|
||||
/* fill st_gen if requested and supported by underlying fs */
|
||||
if (request_mask & P9_STATS_GEN) {
|
||||
retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl);
|
||||
if (retval < 0) {
|
||||
goto out;
|
||||
}
|
||||
v9stat_dotl.st_result_mask |= P9_STATS_GEN;
|
||||
}
|
||||
retval = offset;
|
||||
retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user