2010-04-29 16:14:44 +04:00
|
|
|
#ifndef _QEMU_VIRTIO_9P_H
|
|
|
|
#define _QEMU_VIRTIO_9P_H
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <utime.h>
|
2011-05-18 14:10:57 +04:00
|
|
|
#include <sys/resource.h>
|
2011-05-19 01:18:05 +04:00
|
|
|
#include "hw/virtio.h"
|
2011-01-28 15:39:08 +03:00
|
|
|
#include "fsdev/file-op-9p.h"
|
2011-05-24 13:40:56 +04:00
|
|
|
#include "qemu-thread.h"
|
|
|
|
#include "qemu-coroutine.h"
|
2010-04-29 16:14:44 +04:00
|
|
|
|
|
|
|
/* The feature bitmap for virtio 9P */
|
|
|
|
/* The mount point is specified in a config variable */
|
|
|
|
#define VIRTIO_9P_MOUNT_TAG 0
|
|
|
|
|
|
|
|
enum {
|
2010-07-28 12:40:22 +04:00
|
|
|
P9_TLERROR = 6,
|
|
|
|
P9_RLERROR,
|
2010-05-10 10:41:03 +04:00
|
|
|
P9_TSTATFS = 8,
|
|
|
|
P9_RSTATFS,
|
2010-06-22 18:17:04 +04:00
|
|
|
P9_TLOPEN = 12,
|
|
|
|
P9_RLOPEN,
|
2010-06-18 05:27:24 +04:00
|
|
|
P9_TLCREATE = 14,
|
|
|
|
P9_RLCREATE,
|
2010-06-10 01:02:08 +04:00
|
|
|
P9_TSYMLINK = 16,
|
|
|
|
P9_RSYMLINK,
|
2010-06-22 10:54:09 +04:00
|
|
|
P9_TMKNOD = 18,
|
|
|
|
P9_RMKNOD,
|
2010-06-22 10:59:41 +04:00
|
|
|
P9_TRENAME = 20,
|
|
|
|
P9_RRENAME,
|
2010-09-14 13:38:25 +04:00
|
|
|
P9_TREADLINK = 22,
|
|
|
|
P9_RREADLINK,
|
virtio-9p: getattr server implementation for 9P2000.L protocol.
SYNOPSIS
size[4] Tgetattr tag[2] fid[4] request_mask[8]
size[4] Rgetattr tag[2] lstat[n]
DESCRIPTION
The getattr transaction inquires about the file identified by fid.
request_mask is a bit mask that specifies which fields of the
stat structure is the client interested in.
The reply will contain a machine-independent directory entry,
laid out as follows:
st_result_mask[8]
Bit mask that indicates which fields in the stat structure
have been populated by the server
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_uid[4]
User id of owner
st_gid[4]
Group ID of owner
st_nlink[8]
Number of hard links
st_rdev[8]
Device ID (if special file)
st_size[8]
Size, in bytes
st_blksize[8]
Block size for file system IO
st_blocks[8]
Number of file system blocks allocated
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
st_btime_sec[8]
Time of creation (birth) of file, seconds
st_btime_nsec[8]
Time of creation (birth) of file, nanoseconds
st_gen[8]
Inode generation
st_data_version[8]
Data version number
request_mask and result_mask bit masks contain the following bits
#define P9_STATS_MODE 0x00000001ULL
#define P9_STATS_NLINK 0x00000002ULL
#define P9_STATS_UID 0x00000004ULL
#define P9_STATS_GID 0x00000008ULL
#define P9_STATS_RDEV 0x00000010ULL
#define P9_STATS_ATIME 0x00000020ULL
#define P9_STATS_MTIME 0x00000040ULL
#define P9_STATS_CTIME 0x00000080ULL
#define P9_STATS_INO 0x00000100ULL
#define P9_STATS_SIZE 0x00000200ULL
#define P9_STATS_BLOCKS 0x00000400ULL
#define P9_STATS_BTIME 0x00000800ULL
#define P9_STATS_GEN 0x00001000ULL
#define P9_STATS_DATA_VERSION 0x00002000ULL
#define P9_STATS_BASIC 0x000007ffULL
#define P9_STATS_ALL 0x00003fffULL
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
There are some additional fields: st_btime_sec, st_btime_nsec, st_gen,
st_data_version apart from the bitmask, st_result_mask. The bit mask
is filled by the server to indicate which stat fields have been
populated by the server. Currently there is no clean way for the
server to obtain these additional fields, so it sends back just the
basic fields.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
2010-07-20 10:14:41 +04:00
|
|
|
P9_TGETATTR = 24,
|
|
|
|
P9_RGETATTR,
|
virtio-9p: Implement server side of setattr for 9P2000.L protocol.
SYNOPSIS
size[4] Tsetattr tag[2] attr[n]
size[4] Rsetattr tag[2]
DESCRIPTION
The setattr command changes some of the file status information.
attr resembles the iattr structure used in Linux kernel. It
specifies which status parameter is to be changed and to what
value. It is laid out as follows:
valid[4]
specifies which status information is to be changed. Possible
values are:
ATTR_MODE (1 << 0)
ATTR_UID (1 << 1)
ATTR_GID (1 << 2)
ATTR_SIZE (1 << 3)
ATTR_ATIME (1 << 4)
ATTR_MTIME (1 << 5)
ATTR_CTIME (1 << 5)
ATTR_ATIME_SET (1 << 7)
ATTR_MTIME_SET (1 << 8)
The last two bits represent whether the time information
is being sent by the client's user space. In the absense
of these bits the server always uses server's time.
mode[4]
File permission bits
uid[4]
Owner id of file
gid[4]
Group id of the file
size[8]
File size
atime_sec[8]
Time of last file access, seconds
atime_nsec[8]
Time of last file access, nanoseconds
mtime_sec[8]
Time of last file modification, seconds
mtime_nsec[8]
Time of last file modification, nanoseconds
Explanation of the patches:
--------------------------
*) The kernel just copies relevent contents of iattr structure to p9_iattr_dotl
structure and passes it down to the client. The only check it has is calling
inode_change_ok()
*) The p9_iattr_dotl structure does not have ctime and ia_file parameters because
I don't think these are needed in our case. The client user space can request
updating just ctime by calling chown(fd, -1, -1). This is handled on server
side without a need for putting ctime on the wire.
*) The server currently supports changing mode, time, ownership and size of the
file.
*) 9P RFC says "Either all the changes in wstat request happen, or none of them
does: if the request succeeds, all changes were made; if it fails, none were."
I have not done anything to implement this specifically because I don't see
a reason.
[jvrao@linux.vnet.ibm.com: Parts of code for handling chown(-1,-1)
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
2010-06-17 16:48:47 +04:00
|
|
|
P9_TSETATTR = 26,
|
|
|
|
P9_RSETATTR,
|
2010-09-02 09:39:06 +04:00
|
|
|
P9_TXATTRWALK = 30,
|
|
|
|
P9_RXATTRWALK,
|
2010-09-02 09:39:07 +04:00
|
|
|
P9_TXATTRCREATE = 32,
|
|
|
|
P9_RXATTRCREATE,
|
2010-06-09 13:27:57 +04:00
|
|
|
P9_TREADDIR = 40,
|
|
|
|
P9_RREADDIR,
|
2010-09-23 04:18:33 +04:00
|
|
|
P9_TFSYNC = 50,
|
|
|
|
P9_RFSYNC,
|
[virto-9p] Implement TLOCK
Synopsis
size[4] TLock tag[2] fid[4] flock[n]
size[4] RLock tag[2] status[1]
Description
Tlock is used to acquire/release byte range posix locks on a file
identified by given fid. The reply contains status of the lock request
flock structure:
type[1] - Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
flags[4] - Flags could be either of
P9_LOCK_FLAGS_BLOCK(1) - Blocked lock request, if there is a
conflicting lock exists, wait for that lock to be released.
P9_LOCK_FLAGS_RECLAIM(2) - Reclaim lock request, used when client is
trying to reclaim a lock after a server restrart (due to crash)
start[8] - Starting offset for lock
length[8] - Number of bytes to lock
If length is 0, lock all bytes starting at the location 'start'
through to the end of file
pid[4] - PID of the process that wants to take lock
client_id[4] - Unique client id
status[1] - Status of the lock request, can be
P9_LOCK_SUCCESS(0), P9_LOCK_BLOCKED(1), P9_LOCK_ERROR(2) or
P9_LOCK_GRACE(3)
P9_LOCK_SUCCESS - Request was successful
P9_LOCK_BLOCKED - A conflicting lock is held by another process
P9_LOCK_ERROR - Error while processing the lock request
P9_LOCK_GRACE - Server is in grace period, it can't accept new lock
requests in this period (except locks with
P9_LOCK_FLAGS_RECLAIM flag set)
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
2010-09-08 00:49:32 +04:00
|
|
|
P9_TLOCK = 52,
|
|
|
|
P9_RLOCK,
|
2010-09-08 01:06:52 +04:00
|
|
|
P9_TGETLOCK = 54,
|
|
|
|
P9_RGETLOCK,
|
2010-06-09 22:21:15 +04:00
|
|
|
P9_TLINK = 70,
|
|
|
|
P9_RLINK,
|
2010-06-22 10:55:22 +04:00
|
|
|
P9_TMKDIR = 72,
|
|
|
|
P9_RMKDIR,
|
2011-05-23 21:54:41 +04:00
|
|
|
P9_TRENAMEAT = 74,
|
|
|
|
P9_RRENAMEAT,
|
2011-09-09 13:37:01 +04:00
|
|
|
P9_TUNLINKAT = 76,
|
|
|
|
P9_RUNLINKAT,
|
2010-04-29 16:14:44 +04:00
|
|
|
P9_TVERSION = 100,
|
|
|
|
P9_RVERSION,
|
|
|
|
P9_TAUTH = 102,
|
|
|
|
P9_RAUTH,
|
|
|
|
P9_TATTACH = 104,
|
|
|
|
P9_RATTACH,
|
|
|
|
P9_TERROR = 106,
|
|
|
|
P9_RERROR,
|
|
|
|
P9_TFLUSH = 108,
|
|
|
|
P9_RFLUSH,
|
|
|
|
P9_TWALK = 110,
|
|
|
|
P9_RWALK,
|
|
|
|
P9_TOPEN = 112,
|
|
|
|
P9_ROPEN,
|
|
|
|
P9_TCREATE = 114,
|
|
|
|
P9_RCREATE,
|
|
|
|
P9_TREAD = 116,
|
|
|
|
P9_RREAD,
|
|
|
|
P9_TWRITE = 118,
|
|
|
|
P9_RWRITE,
|
|
|
|
P9_TCLUNK = 120,
|
|
|
|
P9_RCLUNK,
|
|
|
|
P9_TREMOVE = 122,
|
|
|
|
P9_RREMOVE,
|
|
|
|
P9_TSTAT = 124,
|
|
|
|
P9_RSTAT,
|
|
|
|
P9_TWSTAT = 126,
|
|
|
|
P9_RWSTAT,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* qid.types */
|
|
|
|
enum {
|
|
|
|
P9_QTDIR = 0x80,
|
|
|
|
P9_QTAPPEND = 0x40,
|
|
|
|
P9_QTEXCL = 0x20,
|
|
|
|
P9_QTMOUNT = 0x10,
|
|
|
|
P9_QTAUTH = 0x08,
|
|
|
|
P9_QTTMP = 0x04,
|
|
|
|
P9_QTSYMLINK = 0x02,
|
|
|
|
P9_QTLINK = 0x01,
|
|
|
|
P9_QTFILE = 0x00,
|
|
|
|
};
|
|
|
|
|
2010-05-27 12:27:29 +04:00
|
|
|
enum p9_proto_version {
|
|
|
|
V9FS_PROTO_2000U = 0x01,
|
|
|
|
V9FS_PROTO_2000L = 0x02,
|
|
|
|
};
|
|
|
|
|
2010-04-29 16:14:44 +04:00
|
|
|
#define P9_NOTAG (u16)(~0)
|
|
|
|
#define P9_NOFID (u32)(~0)
|
|
|
|
#define P9_MAXWELEM 16
|
2011-05-18 14:10:57 +04:00
|
|
|
|
|
|
|
#define FID_REFERENCED 0x1
|
|
|
|
#define FID_NON_RECLAIMABLE 0x2
|
2011-06-01 11:05:14 +04:00
|
|
|
static inline const char *rpath(FsContext *ctx, const char *path, char *buffer)
|
|
|
|
{
|
|
|
|
snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path);
|
|
|
|
return buffer;
|
|
|
|
}
|
2010-04-29 16:14:44 +04:00
|
|
|
|
2010-06-09 17:44:28 +04:00
|
|
|
/*
|
|
|
|
* ample room for Twrite/Rread header
|
|
|
|
* size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
|
|
|
|
*/
|
|
|
|
#define P9_IOHDRSZ 24
|
|
|
|
|
2010-04-29 16:14:44 +04:00
|
|
|
typedef struct V9fsPDU V9fsPDU;
|
2011-05-19 01:18:05 +04:00
|
|
|
struct V9fsState;
|
2010-04-29 16:14:44 +04:00
|
|
|
|
|
|
|
struct V9fsPDU
|
|
|
|
{
|
|
|
|
uint32_t size;
|
|
|
|
uint16_t tag;
|
|
|
|
uint8_t id;
|
2011-08-02 10:06:17 +04:00
|
|
|
uint8_t cancelled;
|
|
|
|
CoQueue complete;
|
2010-04-29 16:14:44 +04:00
|
|
|
VirtQueueElement elem;
|
2011-05-19 01:18:05 +04:00
|
|
|
struct V9fsState *s;
|
2010-04-29 16:14:44 +04:00
|
|
|
QLIST_ENTRY(V9fsPDU) next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME
|
|
|
|
* 1) change user needs to set groups and stuff
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* from Linux's linux/virtio_9p.h */
|
|
|
|
|
|
|
|
/* The ID for virtio console */
|
|
|
|
#define VIRTIO_ID_9P 9
|
|
|
|
#define MAX_REQ 128
|
|
|
|
#define MAX_TAG_LEN 32
|
|
|
|
|
|
|
|
#define BUG_ON(cond) assert(!(cond))
|
|
|
|
|
|
|
|
typedef struct V9fsFidState V9fsFidState;
|
|
|
|
|
|
|
|
typedef struct V9fsString
|
|
|
|
{
|
2011-12-21 11:07:23 +04:00
|
|
|
uint16_t size;
|
2010-04-29 16:14:44 +04:00
|
|
|
char *data;
|
|
|
|
} V9fsString;
|
|
|
|
|
|
|
|
typedef struct V9fsQID
|
|
|
|
{
|
|
|
|
int8_t type;
|
|
|
|
int32_t version;
|
|
|
|
int64_t path;
|
|
|
|
} V9fsQID;
|
|
|
|
|
|
|
|
typedef struct V9fsStat
|
|
|
|
{
|
|
|
|
int16_t size;
|
|
|
|
int16_t type;
|
|
|
|
int32_t dev;
|
|
|
|
V9fsQID qid;
|
|
|
|
int32_t mode;
|
|
|
|
int32_t atime;
|
|
|
|
int32_t mtime;
|
|
|
|
int64_t length;
|
|
|
|
V9fsString name;
|
|
|
|
V9fsString uid;
|
|
|
|
V9fsString gid;
|
|
|
|
V9fsString muid;
|
|
|
|
/* 9p2000.u */
|
|
|
|
V9fsString extension;
|
|
|
|
int32_t n_uid;
|
|
|
|
int32_t n_gid;
|
|
|
|
int32_t n_muid;
|
|
|
|
} V9fsStat;
|
|
|
|
|
2010-09-02 09:39:06 +04:00
|
|
|
enum {
|
|
|
|
P9_FID_NONE = 0,
|
|
|
|
P9_FID_FILE,
|
|
|
|
P9_FID_DIR,
|
|
|
|
P9_FID_XATTR,
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct V9fsXattr
|
|
|
|
{
|
|
|
|
int64_t copied_len;
|
|
|
|
int64_t len;
|
|
|
|
void *value;
|
|
|
|
V9fsString name;
|
|
|
|
int flags;
|
|
|
|
} V9fsXattr;
|
|
|
|
|
2011-10-25 10:40:40 +04:00
|
|
|
/*
|
|
|
|
* Filled by fs driver on open and other
|
|
|
|
* calls.
|
|
|
|
*/
|
|
|
|
union V9fsFidOpenState {
|
|
|
|
int fd;
|
|
|
|
DIR *dir;
|
|
|
|
V9fsXattr xattr;
|
2011-10-25 10:40:40 +04:00
|
|
|
/*
|
|
|
|
* private pointer for fs drivers, that
|
|
|
|
* have its own internal representation of
|
|
|
|
* open files.
|
|
|
|
*/
|
|
|
|
void *private;
|
2011-10-25 10:40:40 +04:00
|
|
|
};
|
|
|
|
|
2010-04-29 16:14:44 +04:00
|
|
|
struct V9fsFidState
|
|
|
|
{
|
2010-09-02 09:39:06 +04:00
|
|
|
int fid_type;
|
2010-04-29 16:14:44 +04:00
|
|
|
int32_t fid;
|
2011-09-09 13:44:18 +04:00
|
|
|
V9fsPath path;
|
2011-10-25 10:40:40 +04:00
|
|
|
V9fsFidOpenState fs;
|
|
|
|
V9fsFidOpenState fs_reclaim;
|
2011-05-18 14:10:57 +04:00
|
|
|
int flags;
|
|
|
|
int open_flags;
|
2010-04-29 16:14:44 +04:00
|
|
|
uid_t uid;
|
2011-05-18 16:08:07 +04:00
|
|
|
int ref;
|
|
|
|
int clunked;
|
2010-04-29 16:14:44 +04:00
|
|
|
V9fsFidState *next;
|
2011-05-18 14:10:57 +04:00
|
|
|
V9fsFidState *rclm_lst;
|
2010-04-29 16:14:44 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct V9fsState
|
|
|
|
{
|
|
|
|
VirtIODevice vdev;
|
|
|
|
VirtQueue *vq;
|
|
|
|
V9fsPDU pdus[MAX_REQ];
|
|
|
|
QLIST_HEAD(, V9fsPDU) free_list;
|
2011-08-02 10:06:17 +04:00
|
|
|
QLIST_HEAD(, V9fsPDU) active_list;
|
2010-04-29 16:14:44 +04:00
|
|
|
V9fsFidState *fid_list;
|
|
|
|
FileOperations *ops;
|
|
|
|
FsContext ctx;
|
2011-12-04 21:05:28 +04:00
|
|
|
char *tag;
|
2010-04-29 16:14:44 +04:00
|
|
|
size_t config_size;
|
2010-05-27 12:27:29 +04:00
|
|
|
enum p9_proto_version proto_version;
|
2010-06-09 17:44:28 +04:00
|
|
|
int32_t msize;
|
2011-05-24 13:40:56 +04:00
|
|
|
/*
|
|
|
|
* lock ensuring atomic path update
|
|
|
|
* on rename.
|
|
|
|
*/
|
|
|
|
CoRwlock rename_lock;
|
2011-12-04 21:05:28 +04:00
|
|
|
int32_t root_fid;
|
|
|
|
Error *migration_blocker;
|
2010-04-29 16:14:44 +04:00
|
|
|
} V9fsState;
|
|
|
|
|
2010-06-02 00:30:51 +04:00
|
|
|
typedef struct V9fsStatState {
|
|
|
|
V9fsPDU *pdu;
|
|
|
|
size_t offset;
|
|
|
|
V9fsStat v9stat;
|
|
|
|
V9fsFidState *fidp;
|
|
|
|
struct stat stbuf;
|
|
|
|
} V9fsStatState;
|
|
|
|
|
virtio-9p: getattr server implementation for 9P2000.L protocol.
SYNOPSIS
size[4] Tgetattr tag[2] fid[4] request_mask[8]
size[4] Rgetattr tag[2] lstat[n]
DESCRIPTION
The getattr transaction inquires about the file identified by fid.
request_mask is a bit mask that specifies which fields of the
stat structure is the client interested in.
The reply will contain a machine-independent directory entry,
laid out as follows:
st_result_mask[8]
Bit mask that indicates which fields in the stat structure
have been populated by the server
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_uid[4]
User id of owner
st_gid[4]
Group ID of owner
st_nlink[8]
Number of hard links
st_rdev[8]
Device ID (if special file)
st_size[8]
Size, in bytes
st_blksize[8]
Block size for file system IO
st_blocks[8]
Number of file system blocks allocated
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
st_btime_sec[8]
Time of creation (birth) of file, seconds
st_btime_nsec[8]
Time of creation (birth) of file, nanoseconds
st_gen[8]
Inode generation
st_data_version[8]
Data version number
request_mask and result_mask bit masks contain the following bits
#define P9_STATS_MODE 0x00000001ULL
#define P9_STATS_NLINK 0x00000002ULL
#define P9_STATS_UID 0x00000004ULL
#define P9_STATS_GID 0x00000008ULL
#define P9_STATS_RDEV 0x00000010ULL
#define P9_STATS_ATIME 0x00000020ULL
#define P9_STATS_MTIME 0x00000040ULL
#define P9_STATS_CTIME 0x00000080ULL
#define P9_STATS_INO 0x00000100ULL
#define P9_STATS_SIZE 0x00000200ULL
#define P9_STATS_BLOCKS 0x00000400ULL
#define P9_STATS_BTIME 0x00000800ULL
#define P9_STATS_GEN 0x00001000ULL
#define P9_STATS_DATA_VERSION 0x00002000ULL
#define P9_STATS_BASIC 0x000007ffULL
#define P9_STATS_ALL 0x00003fffULL
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
There are some additional fields: st_btime_sec, st_btime_nsec, st_gen,
st_data_version apart from the bitmask, st_result_mask. The bit mask
is filled by the server to indicate which stat fields have been
populated by the server. Currently there is no clean way for the
server to obtain these additional fields, so it sends back just the
basic fields.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
2010-07-20 10:14:41 +04:00
|
|
|
typedef struct V9fsStatDotl {
|
|
|
|
uint64_t st_result_mask;
|
|
|
|
V9fsQID qid;
|
|
|
|
uint32_t st_mode;
|
|
|
|
uint32_t st_uid;
|
|
|
|
uint32_t st_gid;
|
|
|
|
uint64_t st_nlink;
|
|
|
|
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;
|
|
|
|
uint64_t st_btime_sec;
|
|
|
|
uint64_t st_btime_nsec;
|
|
|
|
uint64_t st_gen;
|
|
|
|
uint64_t st_data_version;
|
|
|
|
} V9fsStatDotl;
|
|
|
|
|
2010-06-02 00:30:51 +04:00
|
|
|
typedef struct V9fsOpenState {
|
|
|
|
V9fsPDU *pdu;
|
|
|
|
size_t offset;
|
2010-06-22 18:17:04 +04:00
|
|
|
int32_t mode;
|
2010-06-02 00:30:51 +04:00
|
|
|
V9fsFidState *fidp;
|
|
|
|
V9fsQID qid;
|
|
|
|
struct stat stbuf;
|
2010-06-09 17:44:28 +04:00
|
|
|
int iounit;
|
2010-06-02 00:30:51 +04:00
|
|
|
} V9fsOpenState;
|
|
|
|
|
|
|
|
typedef struct V9fsReadState {
|
|
|
|
V9fsPDU *pdu;
|
|
|
|
size_t offset;
|
|
|
|
int32_t count;
|
|
|
|
int32_t total;
|
|
|
|
int64_t off;
|
|
|
|
V9fsFidState *fidp;
|
|
|
|
struct iovec iov[128]; /* FIXME: bad, bad, bad */
|
|
|
|
struct iovec *sg;
|
|
|
|
off_t dir_pos;
|
|
|
|
struct dirent *dent;
|
|
|
|
struct stat stbuf;
|
|
|
|
V9fsString name;
|
|
|
|
V9fsStat v9stat;
|
|
|
|
int32_t len;
|
|
|
|
int32_t cnt;
|
|
|
|
int32_t max_count;
|
|
|
|
} V9fsReadState;
|
|
|
|
|
|
|
|
typedef struct V9fsWriteState {
|
|
|
|
V9fsPDU *pdu;
|
|
|
|
size_t offset;
|
|
|
|
int32_t len;
|
|
|
|
int32_t count;
|
|
|
|
int32_t total;
|
|
|
|
int64_t off;
|
|
|
|
V9fsFidState *fidp;
|
|
|
|
struct iovec iov[128]; /* FIXME: bad, bad, bad */
|
|
|
|
struct iovec *sg;
|
|
|
|
int cnt;
|
|
|
|
} V9fsWriteState;
|
|
|
|
|
virtio-9p: Implement server side of setattr for 9P2000.L protocol.
SYNOPSIS
size[4] Tsetattr tag[2] attr[n]
size[4] Rsetattr tag[2]
DESCRIPTION
The setattr command changes some of the file status information.
attr resembles the iattr structure used in Linux kernel. It
specifies which status parameter is to be changed and to what
value. It is laid out as follows:
valid[4]
specifies which status information is to be changed. Possible
values are:
ATTR_MODE (1 << 0)
ATTR_UID (1 << 1)
ATTR_GID (1 << 2)
ATTR_SIZE (1 << 3)
ATTR_ATIME (1 << 4)
ATTR_MTIME (1 << 5)
ATTR_CTIME (1 << 5)
ATTR_ATIME_SET (1 << 7)
ATTR_MTIME_SET (1 << 8)
The last two bits represent whether the time information
is being sent by the client's user space. In the absense
of these bits the server always uses server's time.
mode[4]
File permission bits
uid[4]
Owner id of file
gid[4]
Group id of the file
size[8]
File size
atime_sec[8]
Time of last file access, seconds
atime_nsec[8]
Time of last file access, nanoseconds
mtime_sec[8]
Time of last file modification, seconds
mtime_nsec[8]
Time of last file modification, nanoseconds
Explanation of the patches:
--------------------------
*) The kernel just copies relevent contents of iattr structure to p9_iattr_dotl
structure and passes it down to the client. The only check it has is calling
inode_change_ok()
*) The p9_iattr_dotl structure does not have ctime and ia_file parameters because
I don't think these are needed in our case. The client user space can request
updating just ctime by calling chown(fd, -1, -1). This is handled on server
side without a need for putting ctime on the wire.
*) The server currently supports changing mode, time, ownership and size of the
file.
*) 9P RFC says "Either all the changes in wstat request happen, or none of them
does: if the request succeeds, all changes were made; if it fails, none were."
I have not done anything to implement this specifically because I don't see
a reason.
[jvrao@linux.vnet.ibm.com: Parts of code for handling chown(-1,-1)
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
2010-06-17 16:48:47 +04:00
|
|
|
typedef struct V9fsIattr
|
|
|
|
{
|
|
|
|
int32_t valid;
|
|
|
|
int32_t mode;
|
|
|
|
int32_t uid;
|
|
|
|
int32_t gid;
|
|
|
|
int64_t size;
|
|
|
|
int64_t atime_sec;
|
|
|
|
int64_t atime_nsec;
|
|
|
|
int64_t mtime_sec;
|
|
|
|
int64_t mtime_nsec;
|
|
|
|
} V9fsIattr;
|
|
|
|
|
2010-04-29 16:14:44 +04:00
|
|
|
struct virtio_9p_config
|
|
|
|
{
|
|
|
|
/* number of characters in tag */
|
|
|
|
uint16_t tag_len;
|
|
|
|
/* Variable size tag name */
|
|
|
|
uint8_t tag[0];
|
2011-08-31 14:38:01 +04:00
|
|
|
} QEMU_PACKED;
|
2010-04-29 16:14:44 +04:00
|
|
|
|
2010-06-22 10:54:09 +04:00
|
|
|
typedef struct V9fsMkState {
|
|
|
|
V9fsPDU *pdu;
|
|
|
|
size_t offset;
|
|
|
|
V9fsQID qid;
|
|
|
|
struct stat stbuf;
|
|
|
|
V9fsString name;
|
|
|
|
V9fsString fullname;
|
|
|
|
} V9fsMkState;
|
|
|
|
|
2011-10-12 17:41:24 +04:00
|
|
|
/* 9p2000.L open flags */
|
|
|
|
#define P9_DOTL_RDONLY 00000000
|
|
|
|
#define P9_DOTL_WRONLY 00000001
|
|
|
|
#define P9_DOTL_RDWR 00000002
|
|
|
|
#define P9_DOTL_NOACCESS 00000003
|
|
|
|
#define P9_DOTL_CREATE 00000100
|
|
|
|
#define P9_DOTL_EXCL 00000200
|
|
|
|
#define P9_DOTL_NOCTTY 00000400
|
|
|
|
#define P9_DOTL_TRUNC 00001000
|
|
|
|
#define P9_DOTL_APPEND 00002000
|
|
|
|
#define P9_DOTL_NONBLOCK 00004000
|
|
|
|
#define P9_DOTL_DSYNC 00010000
|
|
|
|
#define P9_DOTL_FASYNC 00020000
|
|
|
|
#define P9_DOTL_DIRECT 00040000
|
|
|
|
#define P9_DOTL_LARGEFILE 00100000
|
|
|
|
#define P9_DOTL_DIRECTORY 00200000
|
|
|
|
#define P9_DOTL_NOFOLLOW 00400000
|
|
|
|
#define P9_DOTL_NOATIME 01000000
|
|
|
|
#define P9_DOTL_CLOEXEC 02000000
|
|
|
|
#define P9_DOTL_SYNC 04000000
|
|
|
|
|
|
|
|
/* 9p2000.L at flags */
|
|
|
|
#define P9_DOTL_AT_REMOVEDIR 0x200
|
|
|
|
|
2011-10-12 17:41:24 +04:00
|
|
|
/* 9P2000.L lock type */
|
|
|
|
#define P9_LOCK_TYPE_RDLCK 0
|
|
|
|
#define P9_LOCK_TYPE_WRLCK 1
|
|
|
|
#define P9_LOCK_TYPE_UNLCK 2
|
|
|
|
|
[virto-9p] Implement TLOCK
Synopsis
size[4] TLock tag[2] fid[4] flock[n]
size[4] RLock tag[2] status[1]
Description
Tlock is used to acquire/release byte range posix locks on a file
identified by given fid. The reply contains status of the lock request
flock structure:
type[1] - Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
flags[4] - Flags could be either of
P9_LOCK_FLAGS_BLOCK(1) - Blocked lock request, if there is a
conflicting lock exists, wait for that lock to be released.
P9_LOCK_FLAGS_RECLAIM(2) - Reclaim lock request, used when client is
trying to reclaim a lock after a server restrart (due to crash)
start[8] - Starting offset for lock
length[8] - Number of bytes to lock
If length is 0, lock all bytes starting at the location 'start'
through to the end of file
pid[4] - PID of the process that wants to take lock
client_id[4] - Unique client id
status[1] - Status of the lock request, can be
P9_LOCK_SUCCESS(0), P9_LOCK_BLOCKED(1), P9_LOCK_ERROR(2) or
P9_LOCK_GRACE(3)
P9_LOCK_SUCCESS - Request was successful
P9_LOCK_BLOCKED - A conflicting lock is held by another process
P9_LOCK_ERROR - Error while processing the lock request
P9_LOCK_GRACE - Server is in grace period, it can't accept new lock
requests in this period (except locks with
P9_LOCK_FLAGS_RECLAIM flag set)
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
2010-09-08 00:49:32 +04:00
|
|
|
#define P9_LOCK_SUCCESS 0
|
|
|
|
#define P9_LOCK_BLOCKED 1
|
|
|
|
#define P9_LOCK_ERROR 2
|
|
|
|
#define P9_LOCK_GRACE 3
|
|
|
|
|
|
|
|
#define P9_LOCK_FLAGS_BLOCK 1
|
|
|
|
#define P9_LOCK_FLAGS_RECLAIM 2
|
|
|
|
|
|
|
|
typedef struct V9fsFlock
|
|
|
|
{
|
|
|
|
uint8_t type;
|
|
|
|
uint32_t flags;
|
|
|
|
uint64_t start; /* absolute offset */
|
|
|
|
uint64_t length;
|
|
|
|
uint32_t proc_id;
|
|
|
|
V9fsString client_id;
|
|
|
|
} V9fsFlock;
|
|
|
|
|
2010-09-08 01:06:52 +04:00
|
|
|
typedef struct V9fsGetlock
|
|
|
|
{
|
|
|
|
uint8_t type;
|
|
|
|
uint64_t start; /* absolute offset */
|
|
|
|
uint64_t length;
|
|
|
|
uint32_t proc_id;
|
|
|
|
V9fsString client_id;
|
|
|
|
} V9fsGetlock;
|
|
|
|
|
2011-05-18 14:10:57 +04:00
|
|
|
extern int open_fd_hw;
|
|
|
|
extern int total_open_fd;
|
|
|
|
|
2011-01-23 19:21:20 +03:00
|
|
|
size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
|
|
|
|
size_t offset, size_t size, int pack);
|
2010-04-29 16:14:44 +04:00
|
|
|
|
|
|
|
static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
|
|
|
|
}
|
|
|
|
|
2011-08-02 10:05:54 +04:00
|
|
|
static inline void v9fs_path_write_lock(V9fsState *s)
|
|
|
|
{
|
2011-10-12 19:29:18 +04:00
|
|
|
if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
|
2011-08-02 10:05:54 +04:00
|
|
|
qemu_co_rwlock_wrlock(&s->rename_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void v9fs_path_read_lock(V9fsState *s)
|
|
|
|
{
|
2011-10-12 19:29:18 +04:00
|
|
|
if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
|
2011-08-02 10:05:54 +04:00
|
|
|
qemu_co_rwlock_rdlock(&s->rename_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void v9fs_path_unlock(V9fsState *s)
|
|
|
|
{
|
2011-10-12 19:29:18 +04:00
|
|
|
if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
|
2011-08-02 10:05:54 +04:00
|
|
|
qemu_co_rwlock_unlock(&s->rename_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-02 10:06:17 +04:00
|
|
|
static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
|
|
|
|
{
|
|
|
|
return pdu->cancelled;
|
|
|
|
}
|
|
|
|
|
2011-06-01 11:05:13 +04:00
|
|
|
extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
|
2011-05-18 14:10:57 +04:00
|
|
|
extern void virtio_9p_set_fd_limit(void);
|
2011-08-02 10:06:17 +04:00
|
|
|
extern void v9fs_reclaim_fd(V9fsPDU *pdu);
|
2011-05-24 13:51:27 +04:00
|
|
|
extern void v9fs_string_init(V9fsString *str);
|
|
|
|
extern void v9fs_string_free(V9fsString *str);
|
|
|
|
extern void v9fs_string_null(V9fsString *str);
|
|
|
|
extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...);
|
|
|
|
extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs);
|
2011-09-09 13:44:18 +04:00
|
|
|
extern void v9fs_path_init(V9fsPath *path);
|
|
|
|
extern void v9fs_path_free(V9fsPath *path);
|
|
|
|
extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
|
|
|
|
extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
|
|
|
|
const char *name, V9fsPath *path);
|
2010-04-29 16:14:44 +04:00
|
|
|
#endif
|