#ifndef FS_P9FS_P9_CLIENT_H
#define FS_P9FS_P9_CLIENT_H
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/_unrhdr.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/dirent.h>
#include <sys/stdarg.h>
#include <fs/p9fs/p9_protocol.h>
enum p9_proto_versions {
p9_proto_legacy,
p9_proto_2000u,
p9_proto_2000L,
};
struct p9_req_t {
struct p9_buffer *tc;
struct p9_buffer *rc;
};
enum transport_status {
P9FS_CONNECT,
P9FS_BEGIN_DISCONNECT,
P9FS_DISCONNECT,
};
#define P9FS_MTU 8192
#define P9FS_IOUNIT (P9FS_MTU - 24)
#define P9FS_DIRENT_LEN 256
#define P9_NOTAG 0
struct p9_client {
struct p9_trans_module *ops;
void *handle;
struct mtx clnt_mtx;
struct mtx req_mtx;
struct cv req_cv;
unsigned int msize;
unsigned char proto_version;
struct unrhdr fidpool;
struct unrhdr tagpool;
enum transport_status trans_status;
};
struct p9_fid {
struct p9_client *clnt;
uint32_t fid;
int mode;
struct p9_qid qid;
uint32_t mtu;
uid_t uid;
int v_opens;
STAILQ_ENTRY(p9_fid) fid_next;
};
struct p9_dirent {
struct p9_qid qid;
uint64_t d_off;
unsigned char d_type;
char d_name[P9FS_DIRENT_LEN];
int len;
};
void p9_init_zones(void);
void p9_destroy_zones(void);
struct p9_client *p9_client_create(struct mount *mp, int *error,
const char *mount_tag);
void p9_client_destroy(struct p9_client *clnt);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *fid,
const char *uname, uid_t n_uname, const char *aname, int *error);
int p9_client_open(struct p9_fid *fid, int mode);
int p9_client_close(struct p9_fid *fid);
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwnames,
char **wnames, int clone, int *error);
struct p9_fid *p9_fid_create(struct p9_client *clnt);
void p9_fid_destroy(struct p9_fid *fid);
uint16_t p9_tag_create(struct p9_client *clnt);
void p9_tag_destroy(struct p9_client *clnt, uint16_t tag);
int p9_client_clunk(struct p9_fid *fid);
int p9_client_version(struct p9_client *clnt);
int p9_client_readdir(struct p9_fid *fid, char *data, uint64_t offset, uint32_t count);
int p9_client_read(struct p9_fid *fid, uint64_t offset, uint32_t count, char *data);
int p9_client_write(struct p9_fid *fid, uint64_t offset, uint32_t count, char *data);
int p9_client_file_create(struct p9_fid *fid, char *name, uint32_t perm, int mode,
char *extension);
int p9_client_remove(struct p9_fid *fid);
int p9_client_unlink(struct p9_fid *dfid, const char *name, int32_t flags);
int p9_dirent_read(struct p9_client *clnt, char *buf, int start, int len,
struct p9_dirent *dirent);
int p9_client_statfs(struct p9_fid *fid, struct p9_statfs *stat);
int p9_client_statread(struct p9_client *clnt, char *data, size_t len, struct p9_wstat *st);
int p9_is_proto_dotu(struct p9_client *clnt);
int p9_is_proto_dotl(struct p9_client *clnt);
void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
int p9stat_read(struct p9_client *clnt, char *data, size_t len, struct p9_wstat *st);
void p9_client_disconnect(struct p9_client *clnt);
void p9_client_begin_disconnect(struct p9_client *clnt);
int p9_create_symlink(struct p9_fid *fid, char *name, char *symtgt, gid_t gid);
int p9_create_hardlink(struct p9_fid *dfid, struct p9_fid *oldfid, char *name);
int p9_readlink(struct p9_fid *fid, char **target);
int p9_client_renameat(struct p9_fid *oldfid, char *oldname, struct p9_fid *newfid, char *newname);
int p9_client_getattr(struct p9_fid *fid, struct p9_stat_dotl *stat_dotl,
uint64_t request_mask);
int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr);
int p9_buf_vwritef(struct p9_buffer *buf, int proto_version, const char *fmt,
va_list ap);
int p9_buf_readf(struct p9_buffer *buf, int proto_version, const char *fmt, ...);
int p9_buf_prepare(struct p9_buffer *buf, int8_t type);
int p9_buf_finalize(struct p9_client *clnt, struct p9_buffer *buf);
void p9_buf_reset(struct p9_buffer *buf);
#endif