9p: introduce the V9fsDir type
If we are to switch back to readdir(), we need a more complex type than DIR * to be able to serialize concurrent accesses to the directory stream. This patch introduces a placeholder type and fixes all users. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
This commit is contained in:
parent
8762a46d36
commit
f314ea4e30
@ -112,7 +112,7 @@ static int handle_close(FsContext *ctx, V9fsFidOpenState *fs)
|
|||||||
|
|
||||||
static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return closedir(fs->dir);
|
return closedir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_open(FsContext *ctx, V9fsPath *fs_path,
|
static int handle_open(FsContext *ctx, V9fsPath *fs_path,
|
||||||
@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fs->dir = fdopendir(ret);
|
fs->dir.stream = fdopendir(ret);
|
||||||
if (!fs->dir) {
|
if (!fs->dir.stream) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -141,24 +141,24 @@ static int handle_opendir(FsContext *ctx,
|
|||||||
|
|
||||||
static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
rewinddir(fs->dir);
|
rewinddir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return telldir(fs->dir);
|
return telldir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
struct dirent *entry,
|
struct dirent *entry,
|
||||||
struct dirent **result)
|
struct dirent **result)
|
||||||
{
|
{
|
||||||
return readdir_r(fs->dir, entry, result);
|
return readdir_r(fs->dir.stream, entry, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
||||||
{
|
{
|
||||||
seekdir(fs->dir, off);
|
seekdir(fs->dir.stream, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
@ -262,7 +262,7 @@ static int handle_fstat(FsContext *fs_ctx, int fid_type,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ static int handle_fsync(FsContext *ctx, int fid_type,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ static int local_close(FsContext *ctx, V9fsFidOpenState *fs)
|
|||||||
|
|
||||||
static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return closedir(fs->dir);
|
return closedir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
||||||
@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx,
|
|||||||
char *path = fs_path->data;
|
char *path = fs_path->data;
|
||||||
|
|
||||||
buffer = rpath(ctx, path);
|
buffer = rpath(ctx, path);
|
||||||
fs->dir = opendir(buffer);
|
fs->dir.stream = opendir(buffer);
|
||||||
g_free(buffer);
|
g_free(buffer);
|
||||||
if (!fs->dir) {
|
if (!fs->dir.stream) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -380,12 +380,12 @@ static int local_opendir(FsContext *ctx,
|
|||||||
|
|
||||||
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
rewinddir(fs->dir);
|
rewinddir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return telldir(fs->dir);
|
return telldir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
@ -395,7 +395,7 @@ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
ret = readdir_r(fs->dir, entry, result);
|
ret = readdir_r(fs->dir.stream, entry, result);
|
||||||
if (ctx->export_flags & V9FS_SM_MAPPED) {
|
if (ctx->export_flags & V9FS_SM_MAPPED) {
|
||||||
entry->d_type = DT_UNKNOWN;
|
entry->d_type = DT_UNKNOWN;
|
||||||
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
||||||
@ -411,7 +411,7 @@ again:
|
|||||||
|
|
||||||
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
||||||
{
|
{
|
||||||
seekdir(fs->dir, off);
|
seekdir(fs->dir.stream, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
@ -610,7 +610,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
|
|||||||
int err, fd;
|
int err, fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
@ -998,7 +998,7 @@ static int local_fsync(FsContext *ctx, int fid_type,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,7 @@ static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs)
|
|||||||
|
|
||||||
static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return closedir(fs->dir);
|
return closedir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
|
static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
|
||||||
@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx,
|
|||||||
{
|
{
|
||||||
int serrno, fd;
|
int serrno, fd;
|
||||||
|
|
||||||
fs->dir = NULL;
|
fs->dir.stream = NULL;
|
||||||
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
|
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
errno = -fd;
|
errno = -fd;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fs->dir = fdopendir(fd);
|
fs->dir.stream = fdopendir(fd);
|
||||||
if (!fs->dir) {
|
if (!fs->dir.stream) {
|
||||||
serrno = errno;
|
serrno = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
errno = serrno;
|
errno = serrno;
|
||||||
@ -670,24 +670,24 @@ static int proxy_opendir(FsContext *ctx,
|
|||||||
|
|
||||||
static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
rewinddir(fs->dir);
|
rewinddir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||||
{
|
{
|
||||||
return telldir(fs->dir);
|
return telldir(fs->dir.stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
struct dirent *entry,
|
struct dirent *entry,
|
||||||
struct dirent **result)
|
struct dirent **result)
|
||||||
{
|
{
|
||||||
return readdir_r(fs->dir, entry, result);
|
return readdir_r(fs->dir.stream, entry, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
||||||
{
|
{
|
||||||
seekdir(fs->dir, off);
|
seekdir(fs->dir.stream, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
||||||
@ -791,7 +791,7 @@ static int proxy_fstat(FsContext *fs_ctx, int fid_type,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
@ -936,7 +936,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (fid_type == P9_FID_DIR) {
|
if (fid_type == P9_FID_DIR) {
|
||||||
fd = dirfd(fs->dir);
|
fd = dirfd(fs->dir.stream);
|
||||||
} else {
|
} else {
|
||||||
fd = fs->fd;
|
fd = fs->fd;
|
||||||
}
|
}
|
||||||
|
12
hw/9pfs/9p.c
12
hw/9pfs/9p.c
@ -231,7 +231,7 @@ static int v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f)
|
|||||||
} while (err == -EINTR && !pdu->cancelled);
|
} while (err == -EINTR && !pdu->cancelled);
|
||||||
}
|
}
|
||||||
} else if (f->fid_type == P9_FID_DIR) {
|
} else if (f->fid_type == P9_FID_DIR) {
|
||||||
if (f->fs.dir == NULL) {
|
if (f->fs.dir.stream == NULL) {
|
||||||
do {
|
do {
|
||||||
err = v9fs_co_opendir(pdu, f);
|
err = v9fs_co_opendir(pdu, f);
|
||||||
} while (err == -EINTR && !pdu->cancelled);
|
} while (err == -EINTR && !pdu->cancelled);
|
||||||
@ -345,7 +345,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
|
|||||||
retval = v9fs_co_close(pdu, &fidp->fs);
|
retval = v9fs_co_close(pdu, &fidp->fs);
|
||||||
}
|
}
|
||||||
} else if (fidp->fid_type == P9_FID_DIR) {
|
} else if (fidp->fid_type == P9_FID_DIR) {
|
||||||
if (fidp->fs.dir != NULL) {
|
if (fidp->fs.dir.stream != NULL) {
|
||||||
retval = v9fs_co_closedir(pdu, &fidp->fs);
|
retval = v9fs_co_closedir(pdu, &fidp->fs);
|
||||||
}
|
}
|
||||||
} else if (fidp->fid_type == P9_FID_XATTR) {
|
} else if (fidp->fid_type == P9_FID_XATTR) {
|
||||||
@ -443,7 +443,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
|
|||||||
reclaim_count++;
|
reclaim_count++;
|
||||||
}
|
}
|
||||||
} else if (f->fid_type == P9_FID_DIR) {
|
} else if (f->fid_type == P9_FID_DIR) {
|
||||||
if (f->fs.dir != NULL) {
|
if (f->fs.dir.stream != NULL) {
|
||||||
/*
|
/*
|
||||||
* Up the reference count so that
|
* Up the reference count so that
|
||||||
* a clunk request won't free this fid
|
* a clunk request won't free this fid
|
||||||
@ -451,8 +451,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
|
|||||||
f->ref++;
|
f->ref++;
|
||||||
f->rclm_lst = reclaim_list;
|
f->rclm_lst = reclaim_list;
|
||||||
reclaim_list = f;
|
reclaim_list = f;
|
||||||
f->fs_reclaim.dir = f->fs.dir;
|
f->fs_reclaim.dir.stream = f->fs.dir.stream;
|
||||||
f->fs.dir = NULL;
|
f->fs.dir.stream = NULL;
|
||||||
reclaim_count++;
|
reclaim_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1883,7 +1883,7 @@ static void v9fs_readdir(void *opaque)
|
|||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
goto out_nofid;
|
goto out_nofid;
|
||||||
}
|
}
|
||||||
if (!fidp->fs.dir) {
|
if (!fidp->fs.dir.stream) {
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -167,13 +167,17 @@ typedef struct V9fsXattr
|
|||||||
int flags;
|
int flags;
|
||||||
} V9fsXattr;
|
} V9fsXattr;
|
||||||
|
|
||||||
|
typedef struct V9fsDir {
|
||||||
|
DIR *stream;
|
||||||
|
} V9fsDir;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Filled by fs driver on open and other
|
* Filled by fs driver on open and other
|
||||||
* calls.
|
* calls.
|
||||||
*/
|
*/
|
||||||
union V9fsFidOpenState {
|
union V9fsFidOpenState {
|
||||||
int fd;
|
int fd;
|
||||||
DIR *dir;
|
V9fsDir dir;
|
||||||
V9fsXattr xattr;
|
V9fsXattr xattr;
|
||||||
/*
|
/*
|
||||||
* private pointer for fs drivers, that
|
* private pointer for fs drivers, that
|
||||||
|
Loading…
Reference in New Issue
Block a user