diff --git a/fcall.h b/fcall.h index a67cb7a..5453d6b 100644 --- a/fcall.h +++ b/fcall.h @@ -37,6 +37,46 @@ #define L9P_MAX_WELEM 256 enum l9p_ftype { + L9P_TLERROR = 6, + L9P_RLERROR, + L9P_TSTATFS = 8, + L9P_RSTATFS, + L9P_TLOPEN = 12, + L9P_RLOPEN, + L9P_TLCREATE = 14, + L9P_RLCREATE, + L9P_TSYMLINK = 16, + L9P_RSYMLINK, + L9P_TMKNOD = 18, + L9P_RMKNOD, + L9P_TRENAME = 20, + L9P_RRENAME, + L9P_TREADLINK = 22, + L9P_RREADLINK, + L9P_TGETATTR = 24, + L9P_RGETATTR, + L9P_TSETATTR = 26, + L9P_RSETATTR, + L9P_TXATTRWALK = 30, + L9P_RXATTRWALK, + L9P_TXATTRCREATE = 32, + L9P_RXATTRCREATE, + L9P_TREADDIR = 40, + L9P_RREADDIR, + L9P_TFSYNC = 50, + L9P_RFSYNC, + L9P_TLOCK = 52, + L9P_RLOCK, + L9P_TGETLOCK = 54, + L9P_RGETLOCK, + L9P_TLINK = 70, + L9P_RLINK, + L9P_TMKDIR = 72, + L9P_RMKDIR, + L9P_TRENAMEAT = 74, + L9P_RRENAMEAT, + L9P_TUNLINKAT = 76, + L9P_RUNLINKAT, L9P_TVERSION = 100, L9P_RVERSION, L9P_TAUTH = 102, @@ -139,6 +179,184 @@ struct l9p_stat { uid_t n_muid; }; +struct l9p_f_rstatfs { + struct l9p_hdr hdr; + uint32_t type; + uint32_t bsize; + uint64_t blocks; + uint64_t bfree; + uint64_t bavail; + uint64_t files; + uint64_t ffree; + uint64_t fsid; + uint32_t namelen; +}; + +struct l9p_f_tlcreate { + struct l9p_hdr hdr; + char *name; + uint32_t flags; + uint32_t mode; + uint32_t gid; +}; + +struct l9p_f_tsymlink { + struct l9p_hdr hdr; + char *name; + char *symtgt; + uint32_t gid; +}; + +struct l9p_f_tmknod { + struct l9p_hdr hdr; + char *name; + uint32_t mode; + uint32_t major; + uint32_t minor; + uint32_t gid; +}; + +struct l9p_f_trename { + struct l9p_hdr hdr; + uint32_t dfid; + char *name; +}; + +struct l9p_f_rreadlink { + struct l9p_hdr hdr; + char *target; +}; + +struct l9p_f_tgetattr { + struct l9p_hdr hdr; + uint64_t request_mask; +}; + +struct l9p_f_rgetattr { + struct l9p_hdr hdr; + uint64_t valid; + struct l9p_qid qid; + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint64_t nlink; + uint64_t rdev; + uint64_t size; + uint64_t blksize; + uint64_t blocks; + uint64_t atime_sec; + uint64_t atime_nsec; + uint64_t mtime_sec; + uint64_t mtime_nsec; + uint64_t ctime_sec; + uint64_t ctime_nsec; + uint64_t btime_sec; + uint64_t btime_nsec; + uint64_t gen; + uint64_t data_version; +}; + +struct l9p_f_tsetattr { + struct l9p_hdr hdr; + uint32_t valid; + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint64_t size; + uint64_t atime_sec; + uint64_t atime_nsec; + uint64_t mtime_sec; + uint64_t mtime_nsec; +}; + +struct l9p_f_txattrwalk { + struct l9p_hdr hdr; + uint32_t newfid; + char *name; +}; + +struct l9p_f_rxattrwalk { + struct l9p_hdr hdr; + uint64_t size; +}; + +struct l9p_f_txattrcreate { + struct l9p_hdr hdr; + char *name; + uint64_t attr_size; + uint32_t flags; +}; + +struct l9p_f_tlock { + struct l9p_hdr hdr; + uint8_t type; + uint32_t flags; + uint64_t start; + uint64_t length; + uint32_t proc_id; + char *client_id; +}; + +struct l9p_f_rlock { + struct l9p_hdr hdr; + uint8_t status; + uint8_t type; + uint32_t flags; + uint64_t start; + uint64_t length; + uint32_t proc_id; + char *client_id; +}; + +struct l9p_f_tgetlock { + struct l9p_hdr hdr; + uint8_t type; + uint64_t start; + uint64_t length; + uint32_t proc_id; + char *client_id; +}; + +struct l9p_f_rgetlock { + struct l9p_hdr hdr; + uint8_t type; + uint64_t start; + uint64_t length; + uint32_t proc_id; + char *client_id; +}; + +struct l9p_f_tlink { + struct l9p_hdr hdr; + uint32_t dfid; + char *name; +}; + +struct l9p_f_tmkdir { + struct l9p_hdr hdr; + char *name; + uint32_t mode; + uint32_t gid; +}; + +struct l9p_f_rmkdir { + struct l9p_hdr hdr; + struct l9p_qid qid; +}; + +struct l9p_f_trenameat { + struct l9p_hdr hdr; + char *oldname; + uint32_t newdirfid; + char *newname; +}; + +struct l9p_f_tunlinkat { + struct l9p_hdr hdr; + char *name; + uint32_t flags; +}; + struct l9p_f_version { struct l9p_hdr hdr; uint32_t msize; @@ -215,6 +433,24 @@ struct l9p_f_twstat { union l9p_fcall { struct l9p_hdr hdr; + struct l9p_f_rstatfs rstatfs; + struct l9p_f_tsymlink tsymlink; + struct l9p_f_tmknod tmknod; + struct l9p_f_trename trename; + struct l9p_f_rreadlink rreadlink; + struct l9p_f_tgetattr tgetattr; + struct l9p_f_rgetattr rgetattr; + struct l9p_f_tsetattr tsetattr; + struct l9p_f_txattrwalk txattrwalk; + struct l9p_f_rxattrwalk rxattrwalk; + struct l9p_f_txattrcreate txattrcreate; + struct l9p_f_tlock tlock; + struct l9p_f_rlock rlock; + struct l9p_f_tlink tlink; + struct l9p_f_tmkdir tmkdir; + struct l9p_f_rmkdir rmkdir; + struct l9p_f_trenameat trenameat; + struct l9p_f_tunlinkat tunlinkat; struct l9p_f_version version; struct l9p_f_tflush tflush; struct l9p_f_ropen ropen; diff --git a/lib9p.h b/lib9p.h index 4de3d26..d7e89d3 100644 --- a/lib9p.h +++ b/lib9p.h @@ -30,6 +30,7 @@ #define LIB9P_LIB9P_H #include +#include #include #include #include @@ -81,6 +82,7 @@ struct l9p_message { size_t lm_cursor_iov; size_t lm_cursor_offset; size_t lm_size; + bool lm_estimate; }; struct l9p_request { @@ -92,8 +94,10 @@ struct l9p_request { union l9p_fcall lr_resp; struct l9p_openfile *lr_fid; struct l9p_openfile *lr_newfid; - struct l9p_connection *lr_conn; - pthread_t lr_thread; + union { + struct l9p_connection *lr_conn; + struct l9p_client *lr_client; + }; void *lr_aux; struct iovec lr_data_iov[L9P_MAX_IOV]; size_t lr_data_niov; @@ -128,6 +132,31 @@ struct l9p_server { LIST_HEAD(, l9p_connection) ls_conns; }; +struct l9p_client { + enum l9p_version lc_version; + bool lc_attached; + struct ht lc_files; + struct ht lc_requests; + uint32_t lc_maxfid; + uint32_t lc_maxtag; +}; + +struct l9p_client_request { + struct l9p_client *lcr_client; + uint32_t lcr_tag; + struct l9p_message lcr_req_msg; + struct l9p_message lcr_resp_msg; + struct l9p_message lcr_readdir_msg; + union l9p_fcall lcr_req; + union l9p_fcall lcr_resp; +}; + +struct l9p_client_file { + struct l9p_client *lcf_client; + struct l9p_qid lcf_qid; + uint32_t lcf_fid; +}; + struct l9p_backend { void *softc; void (*attach)(void *, struct l9p_request *); @@ -183,4 +212,16 @@ void l9p_freestat(struct l9p_stat *stat); int l9p_backend_fs_init(struct l9p_backend **backendp, const char *root); +int l9p_create_client(struct l9p_client **clientp); +struct l9p_client_file *l9p_alloc_file(struct l9p_client *client); +int l9p_client_attach(struct l9p_client *client, const char *aname, + const char *uname, uid_t uid); +struct l9p_client_file * l9p_client_walk(struct l9p_client *client, + struct l9p_client_file *start, const char *path); +int l9p_client_open(struct l9p_client_file *file, int mode); +int l9p_client_clunk(struct l9p_client_file *file); +int l9p_client_read(struct l9p_client_file *file, off_t offset, size_t count, + struct iovec *iov, size_t niov); +int l9p_client_stat(struct l9p_client_file *file, struct l9p_stat *stat); + #endif /* LIB9P_LIB9P_H */ diff --git a/pack.c b/pack.c index 13758c5..5739dcc 100644 --- a/pack.c +++ b/pack.c @@ -62,6 +62,9 @@ l9p_iov_io(struct l9p_message *msg, void *buffer, size_t len) if (len == 0) return (0); + + if (msg->lm_estimate) + return ((int)len); if (msg->lm_cursor_iov >= msg->lm_niov) return (-1); @@ -249,6 +252,220 @@ l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall, l9p_pu16(msg, &fcall->hdr.tag); switch (fcall->hdr.type) { + case L9P_TSTATFS: + l9p_pu32(msg, &fcall->hdr.fid); + break; + + case L9P_RSTATFS: + l9p_pu32(msg, &fcall->rstatfs.type); + l9p_pu32(msg, &fcall->rstatfs.bsize); + l9p_pu64(msg, &fcall->rstatfs.blocks); + l9p_pu64(msg, &fcall->rstatfs.bfree); + l9p_pu64(msg, &fcall->rstatfs.bavail); + l9p_pu64(msg, &fcall->rstatfs.files); + l9p_pu64(msg, &fcall->rstatfs.ffree); + l9p_pu64(msg, &fcall->rstatfs.fsid); + l9p_pu32(msg, &fcall->rstatfs.namelen); + break; + + case L9P_TLCREATE: + break; + + case L9P_RLCREATE: + break; + + case L9P_TSYMLINK: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->tsymlink.name); + l9p_pustring(msg, &fcall->tsymlink.symtgt); + l9p_pu32(msg, &fcall->tsymlink.gid); + break; + + case L9P_RSYMLINK: + break; + + case L9P_TMKNOD: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->tmknod.name); + l9p_pu32(msg, &fcall->tmknod.mode); + l9p_pu32(msg, &fcall->tmknod.major); + l9p_pu32(msg, &fcall->tmknod.minor); + l9p_pu32(msg, &fcall->tmknod.gid); + break; + + case L9P_RMKNOD: + break; + + case L9P_TRENAME: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu32(msg, &fcall->trename.dfid); + l9p_pustring(msg, &fcall->trename.name); + break; + + case L9P_RRENAME: + break; + + case L9P_TREADLINK: + l9p_pu32(msg, &fcall->hdr.fid); + break; + + case L9P_RREADLINK: + l9p_pustring(msg, &fcall->rreadlink.target); + break; + + case L9P_TGETATTR: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu64(msg, &fcall->tgetattr.request_mask); + break; + + case L9P_RGETATTR: + l9p_pu64(msg, &fcall->rgetattr.valid); + l9p_puqid(msg, &fcall->rgetattr.qid); + l9p_pu32(msg, &fcall->rgetattr.mode); + l9p_pu32(msg, &fcall->rgetattr.uid); + l9p_pu32(msg, &fcall->rgetattr.gid); + l9p_pu64(msg, &fcall->rgetattr.nlink); + l9p_pu64(msg, &fcall->rgetattr.rdev); + l9p_pu64(msg, &fcall->rgetattr.size); + l9p_pu64(msg, &fcall->rgetattr.blksize); + l9p_pu64(msg, &fcall->rgetattr.blocks); + l9p_pu64(msg, &fcall->rgetattr.atime_sec); + l9p_pu64(msg, &fcall->rgetattr.atime_nsec); + l9p_pu64(msg, &fcall->rgetattr.mtime_sec); + l9p_pu64(msg, &fcall->rgetattr.mtime_nsec); + l9p_pu64(msg, &fcall->rgetattr.ctime_sec); + l9p_pu64(msg, &fcall->rgetattr.ctime_nsec); + l9p_pu64(msg, &fcall->rgetattr.btime_sec); + l9p_pu64(msg, &fcall->rgetattr.btime_nsec); + l9p_pu64(msg, &fcall->rgetattr.gen); + l9p_pu64(msg, &fcall->rgetattr.data_version); + break; + + case L9P_TSETATTR: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu32(msg, &fcall->tsetattr.valid); + l9p_pu32(msg, &fcall->tsetattr.mode); + l9p_pu32(msg, &fcall->tsetattr.uid); + l9p_pu32(msg, &fcall->tsetattr.gid); + l9p_pu64(msg, &fcall->tsetattr.size); + l9p_pu64(msg, &fcall->tsetattr.atime_sec); + l9p_pu64(msg, &fcall->tsetattr.atime_nsec); + l9p_pu64(msg, &fcall->tsetattr.mtime_sec); + l9p_pu64(msg, &fcall->tsetattr.mtime_nsec); + break; + + case L9P_RSETATTR: + break; + + case L9P_TXATTRWALK: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu32(msg, &fcall->txattrwalk.newfid); + l9p_pustring(msg, &fcall->txattrwalk.name); + break; + + case L9P_RXATTRWALK: + l9p_pu64(msg, &fcall->rxattrwalk.size); + break; + + case L9P_TXATTRCREATE: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->txattrcreate.name); + l9p_pu64(msg, &fcall->txattrcreate.attr_size); + l9p_pu32(msg, &fcall->txattrcreate.flags); + break; + + case L9P_RXATTRCREATE: + break; + + case L9P_TREADDIR: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu64(msg, &fcall->io.offset); + l9p_pu32(msg, &fcall->io.count); + break; + + case L9P_RREADDIR: + break; + + case L9P_TFSYNC: + l9p_pu32(msg, &fcall->hdr.fid); + break; + + case L9P_RFSYNC: + break; + + case L9P_TLOCK: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu8(msg, &fcall->tlock.type); + l9p_pu32(msg, &fcall->tlock.flags); + l9p_pu64(msg, &fcall->tlock.start); + l9p_pu64(msg, &fcall->tlock.length); + l9p_pu32(msg, &fcall->tlock.proc_id); + l9p_pustring(msg, &fcall->tlock.client_id); + break; + + case L9P_RLOCK: + l9p_pu8(msg, &fcall->rlock.status); + break; + + case L9P_TGETLOCK: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu8(msg, &fcall->tlock.type); + l9p_pu32(msg, &fcall->tlock.flags); + l9p_pu64(msg, &fcall->tlock.start); + l9p_pu64(msg, &fcall->tlock.length); + l9p_pu32(msg, &fcall->tlock.proc_id); + l9p_pustring(msg, &fcall->tlock.client_id); + break; + + case L9P_RGETLOCK: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pu8(msg, &fcall->rlock.type); + l9p_pu32(msg, &fcall->rlock.flags); + l9p_pu64(msg, &fcall->rlock.start); + l9p_pu64(msg, &fcall->rlock.length); + l9p_pu32(msg, &fcall->rlock.proc_id); + l9p_pustring(msg, &fcall->rlock.client_id); + break; + + case L9P_TLINK: + l9p_pu32(msg, &fcall->tlink.dfid); + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->tlink.name); + break; + + case L9P_RLINK: + break; + + case L9P_TMKDIR: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->tmkdir.name); + l9p_pu32(msg, &fcall->tmkdir.mode); + l9p_pu32(msg, &fcall->tmkdir.gid); + break; + + case L9P_RMKDIR: + l9p_puqid(msg, &fcall->rmkdir.qid); + break; + + case L9P_TRENAMEAT: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->trenameat.oldname); + l9p_pu32(msg, &fcall->trenameat.newdirfid); + l9p_pustring(msg, &fcall->trenameat.newname); + break; + + case L9P_RRENAMEAT: + break; + + case L9P_TUNLINKAT: + l9p_pu32(msg, &fcall->hdr.fid); + l9p_pustring(msg, &fcall->tunlinkat.name); + l9p_pu32(msg, &fcall->tunlinkat.flags); + break; + + case L9P_RUNLINKAT: + break; + case L9P_TVERSION: case L9P_RVERSION: l9p_pu32(msg, &fcall->version.msize);