mirror of https://github.com/xqemu/xqemu.git
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
|
@ -2568,6 +2568,19 @@ if compile_prog "" "" ; then
|
||||||
open_by_handle_at=yes
|
open_by_handle_at=yes
|
||||||
fi
|
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
|
# End of CC checks
|
||||||
# After here, no more $cc or $ld runs
|
# 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
|
echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$linux_magic_h" = "yes" ; then
|
||||||
|
echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
|
|
||||||
# USB host support
|
# USB host support
|
||||||
case "$usb" in
|
case "$usb" in
|
||||||
linux)
|
linux)
|
||||||
|
|
|
@ -49,6 +49,13 @@ typedef struct FsCred
|
||||||
} FsCred;
|
} FsCred;
|
||||||
|
|
||||||
struct xattr_operations;
|
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 */
|
/* FsContext flag values */
|
||||||
#define PATHNAME_FSCONTEXT 0x1
|
#define PATHNAME_FSCONTEXT 0x1
|
||||||
|
@ -64,6 +71,7 @@ typedef struct FsContext
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
int export_flags;
|
int export_flags;
|
||||||
struct xattr_operations **xops;
|
struct xattr_operations **xops;
|
||||||
|
struct extended_ops exops;
|
||||||
/* fs driver specific data */
|
/* fs driver specific data */
|
||||||
void *private;
|
void *private;
|
||||||
} FsContext;
|
} FsContext;
|
||||||
|
|
|
@ -17,6 +17,30 @@
|
||||||
#include "qemu-coroutine.h"
|
#include "qemu-coroutine.h"
|
||||||
#include "virtio-9p-coth.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 v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -101,4 +101,7 @@ extern int v9fs_co_preadv(V9fsPDU *, V9fsFidState *,
|
||||||
struct iovec *, int, int64_t);
|
struct iovec *, int, int64_t);
|
||||||
extern int v9fs_co_name_to_path(V9fsPDU *, V9fsPath *,
|
extern int v9fs_co_name_to_path(V9fsPDU *, V9fsPath *,
|
||||||
const char *, V9fsPath *);
|
const char *, V9fsPath *);
|
||||||
|
extern int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t,
|
||||||
|
V9fsStatDotl *v9stat);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -117,6 +117,8 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
|
||||||
|
|
||||||
s->ctx.export_flags = fse->export_flags;
|
s->ctx.export_flags = fse->export_flags;
|
||||||
s->ctx.fs_root = g_strdup(fse->path);
|
s->ctx.fs_root = g_strdup(fse->path);
|
||||||
|
s->ctx.exops.get_st_gen = NULL;
|
||||||
|
|
||||||
len = strlen(conf->tag);
|
len = strlen(conf->tag);
|
||||||
if (len > MAX_TAG_LEN) {
|
if (len > MAX_TAG_LEN) {
|
||||||
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
|
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
|
||||||
|
|
|
@ -20,6 +20,24 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <attr/xattr.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)
|
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;
|
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)
|
static int local_init(FsContext *ctx)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
struct statfs stbuf;
|
||||||
|
|
||||||
ctx->flags |= PATHNAME_FSCONTEXT;
|
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 = {
|
FileOperations local_ops = {
|
||||||
|
|
|
@ -1402,6 +1402,15 @@ static void v9fs_getattr(void *opaque)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl);
|
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 = offset;
|
||||||
retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);
|
retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue