Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 38 additions & 20 deletions components/dfs/dfs_v1/filesystems/9pfs/dfs_9pfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,48 @@ static rt_list_t _protocol_nodes = RT_LIST_OBJECT_INIT(_protocol_nodes);
static struct rt_spinlock _protocol_lock = { 0 };

#ifndef rt_le8_to_cpu
#define rt_le8_to_cpu
#define rt_le8_to_cpu(x) (x)
#endif
#ifndef rt_cpu_to_le8
#define rt_cpu_to_le8
#define rt_cpu_to_le8(x) (x)
#endif

#define P9_OF_OPS_GET(width, dir) \
rt_inline rt_uint##width##_t get_##dir##_##value##width##_of( \
struct p9_connection *conn, unsigned idx) \
{ \
rt_uint##width##_t *vp = (void *)&conn->dir##_buffer[idx]; \
return rt_le##width##_to_cpu(*vp); \
/*
* The 9P messages are not aligned inside `rx_buffer`/`tx_buffer`, a 64 bit
* field can start at any offset (e.g. the `length` field of an `Rstat` reply
* always starts at P9_MSG_STAT_LEN == 42). Dereferencing a casted pointer
* makes GCC emit `LDRD`/`STRD` on ARMv7-A, which faults on any address that
* is not 8 byte aligned, so always go through an aligned local variable.
*/
#define P9_OF_OPS_GET(width, dir) \
rt_inline rt_uint##width##_t get_##dir##_##value##width##_of( \
struct p9_connection *conn, unsigned idx) \
{ \
rt_uint##width##_t value; \
\
rt_memcpy(&value, &conn->dir##_buffer[idx], sizeof(value)); \
\
return rt_le##width##_to_cpu(value); \
}

#define P9_OF_OPS_PUT(width, dir) \
rt_inline void put_##dir##_##value##width##_of( \
struct p9_connection *conn, unsigned idx, \
rt_uint##width##_t value) \
{ \
rt_uint##width##_t *vp = (void *)&conn->dir##_buffer[idx]; \
*vp = rt_cpu_to_le##width(value); \
#define P9_OF_OPS_PUT(width, dir) \
rt_inline void put_##dir##_##value##width##_of( \
struct p9_connection *conn, unsigned idx, \
rt_uint##width##_t value) \
{ \
value = rt_cpu_to_le##width(value); \
\
rt_memcpy(&conn->dir##_buffer[idx], &value, sizeof(value)); \
}

#define P9_OPS_PUT(width) \
rt_inline rt_off_t put_value##width(struct p9_connection *conn, \
rt_off_t off, rt_uint##width##_t value) \
{ \
((rt_uint##width##_t *)(conn->tx_buffer + off))[0] = \
rt_cpu_to_le##width(value); \
value = rt_cpu_to_le##width(value); \
\
rt_memcpy(conn->tx_buffer + off, &value, sizeof(value)); \
\
return off + sizeof(value); \
}

Expand Down Expand Up @@ -367,7 +380,7 @@ rt_err_t dfs_9pfs_del_tag(struct p9_protocol *p9p)

static int p9_to_fs_err(int rc)
{
const int p9_err[] = {
const int p9_err[-P9_MSG_SIZE_TOO_BIG + 1] = {
[0] = RT_EOK,
[-P9_ERROR] = -EIO,
[-P9_UNKNOWN_VERSION] = -ENOSYS,
Expand All @@ -384,7 +397,12 @@ static int p9_to_fs_err(int rc)
[-P9_MSG_SIZE_TOO_BIG] = -ENOSPC,
};

return p9_err[-rc];
if (rc <= 0 && -rc < (int)(sizeof(p9_err) / sizeof(p9_err[0])))
{
return p9_err[-rc];
}

return -EIO;
}

static int p9_alloc_fid(struct p9_connection *conn)
Expand Down Expand Up @@ -547,7 +565,7 @@ rt_inline int p9_walk_subpath(struct p9_connection *conn, const char *path)

static int dfs_9pfs_open(struct dfs_file *fd)
{
int rc;
int rc = 0;
rt_uint32_t size;
rt_bool_t is_root;
struct p9_connection *conn;
Expand Down
Loading