diff options
-rw-r--r-- | lib9p/9P2000.txt | 37 | ||||
-rw-r--r-- | lib9p/9P2000.u.txt | 21 | ||||
-rw-r--r-- | lib9p/include/lib9p/_types.h | 38 | ||||
-rw-r--r-- | lib9p/types.c | 36 | ||||
-rwxr-xr-x | lib9p/types.gen | 2 |
5 files changed, 102 insertions, 32 deletions
diff --git a/lib9p/9P2000.txt b/lib9p/9P2000.txt index da9b223..3fb9e51 100644 --- a/lib9p/9P2000.txt +++ b/lib9p/9P2000.txt @@ -30,18 +30,37 @@ d = "len[4] len*(dat[1])" # string (u16le `n`, then `n` bytes of UTF-8) s = "len[2] len*(utf8[1])" +# "d"? mode - (file permissions and attributes) +bitfield dm 32 + 31/DIR + 30/APPEND + 29/EXCL + # DMMOUNT has been around in Plan 9 forever, but is + # undocumented, and is explicitly excluded from the 9P2000 + # draft RFC. As I understand it, DMMOUNT indicates that the + # file is mounted by the kernel as a 9P transport; that the + # kernel has a lock on doing I/O on it, so userspace can't do + # I/O on it. + 28/_PLAN9_MOUNT + 27/AUTH + 26/TMP + #... + 8/OWNER_R + 7/OWNER_W + 6/OWNER_X + 5/GROUP_R + 4/GROUP_W + 3/GROUP_X + 2/OTHER_R + 1/OTHER_W + 0/OTHER_X + # QID Type (see qid below) bitfield qt 8 7/DIR 6/APPEND 5/EXCL - # QTMOUNT has been around in Plan 9 forever, but is - # undocumented, and is explicitly excluded from the 9P2000 - # draft RFC. As I understand it, QTMOUNT indicates that the - # file is mounted by the kernel as a 9P transport; that the - # kernel has a lock on doing I/O on it, so userspace can't do - # I/O on it. - 4/_PLAN9_MOUNT + 4/_PLAN9_MOUNT # see DMMOUNT above 3/AUTH # Fun historical fact: QTTMP was a relatively late addition to # Plan 9, in 2003-12. @@ -73,7 +92,7 @@ stat = "stat_size[2]" "kern_type[2]" "kern_dev[4]" "file_qid[qid]" - "file_mode[4]" + "file_mode[dm]" "file_atime[4]" "file_mtime[4]" "file_size[8]" @@ -117,7 +136,7 @@ bitfield o 8 111/Rwalk = "nwqid[2] nwqid*(wqid[qid])" 112/Topen = "fid[4] mode[o]" 113/Ropen = "qid[qid] iounit[4]" -114/Tcreate = "fid[4] name[s] perm[4] mode[o]" +114/Tcreate = "fid[4] name[s] perm[dm] mode[o]" 115/Rcreate = "qid[qid] iounit[4]" 116/Tread = "fid[4] offset[8] count[4]" 117/Rread = "data[d]" # for directories data is the sequence "cnt*(entries[stat])" diff --git a/lib9p/9P2000.u.txt b/lib9p/9P2000.u.txt index 29fd2d8..3958a92 100644 --- a/lib9p/9P2000.u.txt +++ b/lib9p/9P2000.u.txt @@ -19,19 +19,10 @@ Tauth += "n_uname[4]" Rerror += "errno[4]" -qt += 1/SYMLINK +dm += 23/DEVICE + 21/NAMEDPIPE + 20/SOCKET + 19/SETUID + 18/SETGID -# DMDIR = 1<<31 -# DMAPPEND = 1<<30 -# DMEXCL = 1<<29 -# DMMOUNT = 1<<28 -# DMAUTH = 1<<27 -# DMTMP = 1<<26 -# # = 1<<25 -# # = 1<<24 -# DMDEVICE = 1<<23 # .u -# # = 1<<22 -# DMNAMEDPIPE = 1<<21 # .u -# DMSOCKET = 1<<20 # .u -# DMSETUID = 1<<19 # .u -# DMSETGID = 1<<18 # .u +qt += 1/SYMLINK diff --git a/lib9p/include/lib9p/_types.h b/lib9p/include/lib9p/_types.h index d853cf3..e22404c 100644 --- a/lib9p/include/lib9p/_types.h +++ b/lib9p/include/lib9p/_types.h @@ -19,6 +19,40 @@ const char *lib9p_version_str(enum lib9p_version); /* non-message types **********************************************************/ +typedef uint32_t lib9p_dm_t; +#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31)) +#define LIB9P_DM_APPEND ((lib9p_dm_t)(1<<30)) +#define LIB9P_DM_EXCL ((lib9p_dm_t)(1<<29)) +#define _LIB9P_DM_PLAN9_MOUNT ((lib9p_dm_t)(1<<28)) +#define LIB9P_DM_AUTH ((lib9p_dm_t)(1<<27)) +#define LIB9P_DM_TMP ((lib9p_dm_t)(1<<26)) +#define _LIB9P_DM_UNUSED_25 ((lib9p_dm_t)(1<<25)) +#define _LIB9P_DM_UNUSED_24 ((lib9p_dm_t)(1<<24)) +#define LIB9P_DM_DEVICE ((lib9p_dm_t)(1<<23)) /* 9P2000.u */ +#define _LIB9P_DM_UNUSED_22 ((lib9p_dm_t)(1<<22)) +#define LIB9P_DM_NAMEDPIPE ((lib9p_dm_t)(1<<21)) /* 9P2000.u */ +#define LIB9P_DM_SOCKET ((lib9p_dm_t)(1<<20)) /* 9P2000.u */ +#define LIB9P_DM_SETUID ((lib9p_dm_t)(1<<19)) /* 9P2000.u */ +#define LIB9P_DM_SETGID ((lib9p_dm_t)(1<<18)) /* 9P2000.u */ +#define _LIB9P_DM_UNUSED_17 ((lib9p_dm_t)(1<<17)) +#define _LIB9P_DM_UNUSED_16 ((lib9p_dm_t)(1<<16)) +#define _LIB9P_DM_UNUSED_15 ((lib9p_dm_t)(1<<15)) +#define _LIB9P_DM_UNUSED_14 ((lib9p_dm_t)(1<<14)) +#define _LIB9P_DM_UNUSED_13 ((lib9p_dm_t)(1<<13)) +#define _LIB9P_DM_UNUSED_12 ((lib9p_dm_t)(1<<12)) +#define _LIB9P_DM_UNUSED_11 ((lib9p_dm_t)(1<<11)) +#define _LIB9P_DM_UNUSED_10 ((lib9p_dm_t)(1<<10)) +#define _LIB9P_DM_UNUSED_9 ((lib9p_dm_t)(1<<9)) +#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(1<<8)) +#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(1<<7)) +#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(1<<6)) +#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(1<<5)) +#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(1<<4)) +#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(1<<3)) +#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(1<<2)) +#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(1<<1)) +#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(1<<0)) + typedef uint8_t lib9p_qt_t; #define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7)) #define LIB9P_QT_APPEND ((lib9p_qt_t)(1<<6)) @@ -65,7 +99,7 @@ struct lib9p_stat { uint16_t kern_type; uint32_t kern_dev; struct lib9p_qid file_qid; - uint32_t file_mode; + lib9p_dm_t file_mode; uint32_t file_atime; uint32_t file_mtime; uint64_t file_size; @@ -187,7 +221,7 @@ struct lib9p_msg_Ropen { struct lib9p_msg_Tcreate { uint32_t fid; struct lib9p_s name; - uint32_t perm; + lib9p_dm_t perm; lib9p_o_t mode; }; diff --git a/lib9p/types.c b/lib9p/types.c index 50ac1cf..2d0bb1b 100644 --- a/lib9p/types.c +++ b/lib9p/types.c @@ -343,6 +343,22 @@ static ALWAYS_INLINE bool validate_s(struct _validate_ctx *ctx) { return false; } +static ALWAYS_INLINE bool validate_dm(struct _validate_ctx *ctx) { + if (validate_4(ctx)) + return true; + static const lib9p_dm_t masks[LIB9P_VER_NUM] = { + [LIB9P_VER_9P2000] = 0b11111100000000000000000111111111, + [LIB9P_VER_9P2000_e] = 0b11111100000000000000000111111111, + [LIB9P_VER_9P2000_u] = 0b11111100101111000000000111111111, + }; + lib9p_dm_t mask = masks[ctx->ctx->version]; + lib9p_dm_t val = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); + if (val & ~mask) + return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#04"PRIx32, + val & ~mask); + return false; +} + static ALWAYS_INLINE bool validate_qt(struct _validate_ctx *ctx) { if (validate_1(ctx)) return true; @@ -370,7 +386,7 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) { || validate_2(ctx) || validate_4(ctx) || validate_qid(ctx) - || validate_4(ctx) + || validate_dm(ctx) || validate_4(ctx) || validate_4(ctx) || validate_8(ctx) @@ -465,7 +481,7 @@ static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) { static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) { return validate_4(ctx) || validate_s(ctx) - || validate_4(ctx) + || validate_dm(ctx) || validate_o(ctx); } @@ -596,6 +612,10 @@ static ALWAYS_INLINE void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s unmarshal_1(ctx, &out->utf8[i]); } +static ALWAYS_INLINE void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) { + unmarshal_4(ctx, (uint32_t *)out); +} + static ALWAYS_INLINE void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) { unmarshal_1(ctx, (uint8_t *)out); } @@ -613,7 +633,7 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9 unmarshal_2(ctx, &out->kern_type); unmarshal_4(ctx, &out->kern_dev); unmarshal_qid(ctx, &out->file_qid); - unmarshal_4(ctx, &out->file_mode); + unmarshal_dm(ctx, &out->file_mode); unmarshal_4(ctx, &out->file_atime); unmarshal_4(ctx, &out->file_mtime); unmarshal_8(ctx, &out->file_size); @@ -720,7 +740,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m memset(out, 0, sizeof(*out)); unmarshal_4(ctx, &out->fid); unmarshal_s(ctx, &out->name); - unmarshal_4(ctx, &out->perm); + unmarshal_dm(ctx, &out->perm); unmarshal_o(ctx, &out->mode); } @@ -894,6 +914,10 @@ static ALWAYS_INLINE bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *va }); } +static ALWAYS_INLINE bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) { + return marshal_4(ctx, (uint32_t *)val); +} + static ALWAYS_INLINE bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) { return marshal_1(ctx, (uint8_t *)val); } @@ -909,7 +933,7 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st || marshal_2(ctx, &val->kern_type) || marshal_4(ctx, &val->kern_dev) || marshal_qid(ctx, &val->file_qid) - || marshal_4(ctx, &val->file_mode) + || marshal_dm(ctx, &val->file_mode) || marshal_4(ctx, &val->file_atime) || marshal_4(ctx, &val->file_mtime) || marshal_8(ctx, &val->file_size) @@ -1007,7 +1031,7 @@ static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Rop static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) { return marshal_4(ctx, &val->fid) || marshal_s(ctx, &val->name) - || marshal_4(ctx, &val->perm) + || marshal_dm(ctx, &val->perm) || marshal_o(ctx, &val->mode); } diff --git a/lib9p/types.gen b/lib9p/types.gen index 1b43fa4..3e800e8 100755 --- a/lib9p/types.gen +++ b/lib9p/types.gen @@ -238,6 +238,7 @@ def parse_file( if not isinstance(_bf, Bitfield): raise NameError(f"Type {repr(_bf.name)} is not a bitfield") bf = _bf + prev = bf else: if not isinstance(prev, Bitfield): raise SyntaxError( @@ -269,6 +270,7 @@ def parse_file( if not isinstance(_bf, Bitfield): raise NameError(f"Type {repr(_bf.name)} is not a bitfield") bf = _bf + prev = bf else: if not isinstance(prev, Bitfield): raise SyntaxError( |