v9fs:Support ioctl to get relpath

Summary:
  1.The relpath information is stored in the fid structure
  2.The relative path information is only saved in the client. When the server changes, the relpath saved in the fid will not change.

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This commit is contained in:
chenrun1 2024-08-10 01:14:12 +08:00 committed by Alan Carvalho de Assis
parent 97338c9f3d
commit fa7403db5a
3 changed files with 60 additions and 5 deletions

View File

@ -368,6 +368,7 @@ struct v9fs_fid_s
{
uint32_t iounit;
uint32_t refcount;
char relpath[1];
};
/****************************************************************************
@ -481,12 +482,15 @@ static uint32_t v9fs_map_open_flags(int flags)
* v9fs_fid_create
****************************************************************************/
static int v9fs_fid_create(FAR struct v9fs_client_s *client)
static int v9fs_fid_create(FAR struct v9fs_client_s *client,
FAR const char *relpath)
{
FAR struct v9fs_fid_s *fid;
size_t len;
int ret;
fid = kmm_zalloc(sizeof(struct v9fs_fid_s));
len = strlen(relpath);
fid = kmm_zalloc(sizeof(struct v9fs_fid_s) + len);
if (fid == NULL)
{
return -ENOMEM;
@ -498,6 +502,7 @@ static int v9fs_fid_create(FAR struct v9fs_client_s *client)
nxmutex_unlock(&client->lock);
if (ret >= 0)
{
memcpy(fid->relpath, relpath, len + 1);
return ret;
}
@ -626,7 +631,7 @@ static int v9fs_client_attach(FAR struct v9fs_client_s *client, uint32_t fid,
* size[4] Rattach tag[2] qid[13]
*/
ret = v9fs_fid_create(client);
ret = v9fs_fid_create(client, "");
if (ret < 0)
{
return ret;
@ -1419,6 +1424,28 @@ int v9fs_client_open(FAR struct v9fs_client_s *client,
return 0;
}
/****************************************************************************
* v9fs_client_getname
****************************************************************************/
int v9fs_client_getname(FAR struct v9fs_client_s *client, uint32_t fid,
FAR char *path)
{
FAR struct v9fs_fid_s *fidp;
nxmutex_lock(&client->lock);
fidp = idr_find(client->fids, fid);
if (fidp == NULL)
{
nxmutex_unlock(&client->lock);
return -ENOENT;
}
strlcat(path, fidp->relpath, PATH_MAX);
nxmutex_unlock(&client->lock);
return 0;
}
/****************************************************************************
* v9fs_client_walk
****************************************************************************/
@ -1496,7 +1523,7 @@ int v9fs_client_walk(FAR struct v9fs_client_s *client, FAR const char *path,
return -ENOMEM;
}
newfid = v9fs_fid_create(client);
newfid = v9fs_fid_create(client, path);
if (newfid < 0)
{
goto err;

View File

@ -110,6 +110,8 @@ int v9fs_client_create(FAR struct v9fs_client_s *client, uint32_t fid,
FAR const char *name, int oflags, int mode);
int v9fs_client_open(FAR struct v9fs_client_s *client,
uint32_t fid, int oflags);
int v9fs_client_getname(FAR struct v9fs_client_s *client, uint32_t fid,
FAR char *path);
int v9fs_client_walk(FAR struct v9fs_client_s *client, FAR const char *path,
FAR const char **childname);
int v9fs_client_init(FAR struct v9fs_client_s *client, FAR const char *data);

View File

@ -30,6 +30,7 @@
#include <string.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/kmalloc.h>
#include "inode/inode.h"
@ -69,6 +70,8 @@ static ssize_t v9fs_vfs_write(FAR struct file *filep,
FAR const char *buffer, size_t buflen);
static off_t v9fs_vfs_seek(FAR struct file *filep, off_t offset,
int whence);
static int v9fs_vfs_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);
static int v9fs_vfs_sync(FAR struct file *filep);
static int v9fs_vfs_dup(FAR const struct file *oldp, FAR struct file *newp);
static int v9fs_vfs_fstat(FAR const struct file *filep,
@ -118,7 +121,7 @@ const struct mountpt_operations g_v9fs_operations =
v9fs_vfs_read, /* read */
v9fs_vfs_write, /* write */
v9fs_vfs_seek, /* seek */
NULL, /* ioctl */
v9fs_vfs_ioctl, /* ioctl */
NULL, /* mmap */
v9fs_vfs_truncate, /* truncate */
NULL, /* poll */
@ -372,6 +375,29 @@ static off_t v9fs_vfs_seek(FAR struct file *filep, off_t offset, int whence)
return ret;
}
/****************************************************************************
* Name: v9fs_vfs_ioctl
****************************************************************************/
static int v9fs_vfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR struct v9fs_vfs_file_s *file;
FAR struct v9fs_client_s *client;
int ret = -ENOTTY;
client = filep->f_inode->i_private;
file = filep->f_priv;
if (cmd == FIOC_FILEPATH)
{
FAR char *ptr = (FAR char *)((uintptr_t)arg);
inode_getpath(filep->f_inode, ptr, PATH_MAX);
ret = v9fs_client_getname(client, file->fid, ptr);
}
return ret;
}
/****************************************************************************
* Name: v9fs_vfs_sync
****************************************************************************/