qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [V9fs-developer] [PATCH] virtio-9p: getattr server impl


From: Aneesh Kumar K. V
Subject: [Qemu-devel] Re: [V9fs-developer] [PATCH] virtio-9p: getattr server implementation for 9P2000.L protocol.
Date: Wed, 02 Jun 2010 19:49:24 +0530
User-agent: Notmuch/ (http://notmuchmail.org) Emacs/24.0.50.1 (i686-pc-linux-gnu)

On Fri, 28 May 2010 16:08:43 +0530, Sripathi Kodi <address@hidden> wrote:
> From: M. Mohan Kumar <address@hidden>
> 
> SYNOPSIS
> 
>       size[4] Tgetattr tag[2] fid[4]
> 
>       size[4] Rgetattr tag[2] lstat[n]
> 
>    DESCRIPTION
> 
>       The getattr transaction inquires about the file identified by fid.
>       The reply will contain a machine-independent directory entry,
>       laid out as follows:
> 
>          qid.type[1]
>             the type of the file (directory, etc.), represented as a bit
>             vector corresponding to the high 8 bits of the file's mode
>             word.
> 
>          qid.vers[4]
>             version number for given path
> 
>          qid.path[8]
>             the file server's unique identification for the file
> 
>          st_mode[4]
>             Permission and flags
> 
>          st_nlink[8]
>             Number of hard links
> 
>          st_uid[4]
>             User id of owner
> 
>          st_gid[4]
>             Group ID of owner
> 
>          st_rdev[8]
>             Device ID (if special file)
> 
>          st_size[8]
>             Size, in bytes
> 
>          st_blksize[8]
>             Block size for file system IO


So it should be scaled by iounit right ? If we say 9p block size is iounit.


> 
>          st_blocks[8]
>             Number of file system blocks allocated

same here. 

> 
>          st_atime_sec[8]
>             Time of last access, seconds
> 
>          st_atime_nsec[8]
>             Time of last access, nanoseconds
> 
>          st_mtime_sec[8]
>             Time of last modification, seconds
> 
>          st_mtime_nsec[8]
>             Time of last modification, nanoseconds
> 
>          st_ctime_sec[8]
>             Time of last status change, seconds
> 
>          st_ctime_nsec[8]
>             Time of last status change, nanoseconds
> 
> 
> This patch implements the client side of getattr implementation for 9P2000.L.
> It introduces a new structure p9_stat_dotl for getting Linux stat information
> along with QID. The data layout is similar to stat structure in Linux user
> space with the following major differences:
> 
> inode (st_ino) is not part of data. Instead qid is.
> 
> device (st_dev) is not part of data because this doesn't make sense on the
> client.
> 
> All time variables are 64 bit wide on the wire. The kernel seems to use
> 32 bit variables for these variables. However, some of the architectures
> have used 64 bit variables and glibc exposes 64 bit variables to user
> space on some architectures. Hence to be on the safer side we have made
> these 64 bit in the protocol. Refer to the comments in
> include/asm-generic/stat.h
> 
> 
> Signed-off-by: M. Mohan Kumar <address@hidden>
> Signed-off-by: Sripathi Kodi <address@hidden>
> ---
> 
>  hw/virtio-9p-debug.c |   32 ++++++++++++++++++++
>  hw/virtio-9p.c       |   82 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/virtio-9p.h       |   28 +++++++++++++++++
>  3 files changed, 142 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
> index a82b771..8bb817d 100644
> --- a/hw/virtio-9p-debug.c
> +++ b/hw/virtio-9p-debug.c
> @@ -178,6 +178,30 @@ static void pprint_stat(V9fsPDU *pdu, int rx, size_t 
> *offsetp, const char *name)
>      fprintf(llogfile, "}");
>  }
> 
> +static void pprint_stat_dotl(V9fsPDU *pdu, int rx, size_t *offsetp,
> +                                                  const char *name)
> +{
> +    fprintf(llogfile, "%s={", name);
> +    pprint_qid(pdu, rx, offsetp, "qid");
> +    pprint_int32(pdu, rx, offsetp, ", st_mode");
> +    pprint_int64(pdu, rx, offsetp, ", st_nlink");
> +    pprint_int32(pdu, rx, offsetp, ", st_uid");
> +    pprint_int32(pdu, rx, offsetp, ", st_gid");
> +    pprint_int64(pdu, rx, offsetp, ", st_rdev");
> +    pprint_int64(pdu, rx, offsetp, ", st_size");
> +    pprint_int64(pdu, rx, offsetp, ", st_blksize");
> +    pprint_int64(pdu, rx, offsetp, ", st_blocks");
> +    pprint_int64(pdu, rx, offsetp, ", atime");
> +    pprint_int64(pdu, rx, offsetp, ", atime_nsec");
> +    pprint_int64(pdu, rx, offsetp, ", mtime");
> +    pprint_int64(pdu, rx, offsetp, ", mtime_nsec");
> +    pprint_int64(pdu, rx, offsetp, ", ctime");
> +    pprint_int64(pdu, rx, offsetp, ", ctime_nsec");
> +    fprintf(llogfile, "}");
> +}
> +
> +
> +
>  static void pprint_strs(V9fsPDU *pdu, int rx, size_t *offsetp, const char 
> *name)
>  {
>      int sg_count = get_sg_count(pdu, rx);
> @@ -351,6 +375,14 @@ void pprint_pdu(V9fsPDU *pdu)
>          pprint_int32(pdu, 1, &offset, "msize");
>          pprint_str(pdu, 1, &offset, ", version");
>          break;
> +    case P9_TGETATTR:
> +        fprintf(llogfile, "TGETATTR: (");
> +        pprint_int32(pdu, 0, &offset, "fid");
> +        break;
> +    case P9_RGETATTR:
> +        fprintf(llogfile, "RGETATTR: (");
> +        pprint_stat_dotl(pdu, 1, &offset, "getattr");
> +        break;
>      case P9_TAUTH:
>          fprintf(llogfile, "TAUTH: (");
>          pprint_int32(pdu, 0, &offset, "afid");
> diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
> index 097dce8..23ae8b8 100644
> --- a/hw/virtio-9p.c
> +++ b/hw/virtio-9p.c
> @@ -737,6 +737,17 @@ static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, 
> const char *fmt, ...)
>                          statp->n_gid, statp->n_muid);
>              break;
>          }
> +        case 'A': {
> +            V9fsStatDotl *statp = va_arg(ap, V9fsStatDotl *);
> +            offset += pdu_marshal(pdu, offset, "Qdqddqqqqqqqqqq",
> +                        &statp->qid, statp->st_mode, statp->st_nlink,
> +                        statp->st_uid, statp->st_gid, statp->st_rdev,
> +                        statp->st_size, statp->st_blksize, statp->st_blocks,
> +                        statp->st_atime_sec, statp->st_atime_nsec,
> +                        statp->st_mtime_sec, statp->st_mtime_nsec,
> +                        statp->st_ctime_sec, statp->st_ctime_nsec);
> +            break;
> +        }
>          default:
>              break;
>          }
> @@ -964,6 +975,29 @@ static int stat_to_v9stat(V9fsState *s, V9fsString *name,
>      return 0;
>  }
> 
> +static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf,
> +                            V9fsStatDotl *v9lstat)
> +{
> +    memset(v9lstat, 0, sizeof(*v9lstat));
> +
> +    v9lstat->st_mode = stbuf->st_mode;
> +    v9lstat->st_nlink = stbuf->st_nlink;
> +    v9lstat->st_uid = stbuf->st_uid;
> +    v9lstat->st_gid = stbuf->st_gid;
> +    v9lstat->st_rdev = stbuf->st_rdev;
> +    v9lstat->st_size = stbuf->st_size;
> +    v9lstat->st_blksize = stbuf->st_blksize;
> +    v9lstat->st_blocks = stbuf->st_blocks;
> +    v9lstat->st_atime_sec = stbuf->st_atime;
> +    v9lstat->st_atime_nsec = stbuf->st_atim.tv_nsec;
> +    v9lstat->st_mtime_sec = stbuf->st_mtime;
> +    v9lstat->st_mtime_nsec = stbuf->st_mtim.tv_nsec;
> +    v9lstat->st_ctime_sec = stbuf->st_ctime;
> +    v9lstat->st_ctime_nsec = stbuf->st_ctim.tv_nsec;
> +
> +    stat_to_qid(stbuf, &v9lstat->qid);
> +}
> +
>  static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt)
>  {
>      while (len && *iovcnt) {
> @@ -1131,6 +1165,53 @@ out:
>      qemu_free(vs);
>  }
> 
> +static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
> +                                                                int err)
> +{
> +    if (err == -1) {
> +        err = -errno;
> +        goto out;
> +    }
> +
> +    stat_to_v9stat_dotl(s, &vs->stbuf, &vs->v9stat_dotl);
> +    vs->offset += pdu_marshal(vs->pdu, vs->offset, "A", &vs->v9stat_dotl);
> +    err = vs->offset;
> +
> +out:
> +    complete_pdu(s, vs->pdu, err);
> +    qemu_free(vs);
> +}
> +
> +static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
> +{
> +    int32_t fid;
> +    V9fsStatStateDotl *vs;
> +    ssize_t err = 0;
> +    V9fsFidState *fidp;
> +
> +    vs = qemu_malloc(sizeof(*vs));
> +    vs->pdu = pdu;
> +    vs->offset = 7;
> +
> +    memset(&vs->v9stat_dotl, 0, sizeof(vs->v9stat_dotl));
> +
> +    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
> +
> +    fidp = lookup_fid(s, fid);
> +    if (fidp == NULL) {
> +        err = -ENOENT;
> +        goto out;
> +    }
> +
> +    err = v9fs_do_lstat(s, &fidp->path, &vs->stbuf);
> +    v9fs_getattr_post_lstat(s, vs, err);
> +    return;
> +
> +out:
> +    complete_pdu(s, vs->pdu, err);
> +    qemu_free(vs);
> +}
> +
>  static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
>  {
>      complete_pdu(s, vs->pdu, err);
> @@ -2343,6 +2424,7 @@ typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU 
> *pdu);
>  static pdu_handler_t *pdu_handlers[] = {
>      [P9_TREADDIR] = v9fs_readdir,
>      [P9_TSTATFS] = v9fs_statfs,
> +    [P9_TGETATTR] = v9fs_getattr,
>      [P9_TVERSION] = v9fs_version,
>      [P9_TATTACH] = v9fs_attach,
>      [P9_TSTAT] = v9fs_stat,
> diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
> index 9773659..7e5609e 100644
> --- a/hw/virtio-9p.h
> +++ b/hw/virtio-9p.h
> @@ -15,6 +15,8 @@
>  enum {
>      P9_TSTATFS = 8,
>      P9_RSTATFS,
> +    P9_TGETATTR = 24,
> +    P9_RGETATTR,
>      P9_TREADDIR = 40,
>      P9_RREADDIR,
>      P9_TVERSION = 100,
> @@ -177,6 +179,32 @@ typedef struct V9fsStatState {
>      struct stat stbuf;
>  } V9fsStatState;
> 
> +typedef struct V9fsStatDotl {
> +    V9fsQID qid;
> +    uint32_t st_mode;
> +    uint64_t st_nlink;
> +    uint32_t st_uid;
> +    uint32_t st_gid;
> +    uint64_t st_rdev;
> +    uint64_t st_size;
> +    uint64_t st_blksize;
> +    uint64_t st_blocks;
> +    uint64_t st_atime_sec;
> +    uint64_t st_atime_nsec;
> +    uint64_t st_mtime_sec;
> +    uint64_t st_mtime_nsec;
> +    uint64_t st_ctime_sec;
> +    uint64_t st_ctime_nsec;
> +} V9fsStatDotl;
> +
> +typedef struct V9fsStatStateDotl {
> +    V9fsPDU *pdu;
> +    size_t offset;
> +    V9fsStatDotl v9stat_dotl;
> +    struct stat stbuf;
> +} V9fsStatStateDotl;
> +
> +
>  typedef struct V9fsWalkState {
>      V9fsPDU *pdu;
>      size_t offset;
> 


-aneesh



reply via email to

[Prev in Thread] Current Thread [Next in Thread]