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)
|
||||
{
|
||||
return closedir(fs->dir);
|
||||
return closedir(fs->dir.stream);
|
||||
}
|
||||
|
||||
static int handle_open(FsContext *ctx, V9fsPath *fs_path,
|
||||
@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx,
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
fs->dir = fdopendir(ret);
|
||||
if (!fs->dir) {
|
||||
fs->dir.stream = fdopendir(ret);
|
||||
if (!fs->dir.stream) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -141,24 +141,24 @@ static int handle_opendir(FsContext *ctx,
|
||||
|
||||
static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||
{
|
||||
rewinddir(fs->dir);
|
||||
rewinddir(fs->dir.stream);
|
||||
}
|
||||
|
||||
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,
|
||||
struct dirent *entry,
|
||||
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)
|
||||
{
|
||||
seekdir(fs->dir, off);
|
||||
seekdir(fs->dir.stream, off);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
@ -409,7 +409,7 @@ static int handle_fsync(FsContext *ctx, int fid_type,
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ static int local_close(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,
|
||||
@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx,
|
||||
char *path = fs_path->data;
|
||||
|
||||
buffer = rpath(ctx, path);
|
||||
fs->dir = opendir(buffer);
|
||||
fs->dir.stream = opendir(buffer);
|
||||
g_free(buffer);
|
||||
if (!fs->dir) {
|
||||
if (!fs->dir.stream) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -380,12 +380,12 @@ static int local_opendir(FsContext *ctx,
|
||||
|
||||
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||
{
|
||||
rewinddir(fs->dir);
|
||||
rewinddir(fs->dir.stream);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -395,7 +395,7 @@ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
|
||||
int ret;
|
||||
|
||||
again:
|
||||
ret = readdir_r(fs->dir, entry, result);
|
||||
ret = readdir_r(fs->dir.stream, entry, result);
|
||||
if (ctx->export_flags & V9FS_SM_MAPPED) {
|
||||
entry->d_type = DT_UNKNOWN;
|
||||
} 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)
|
||||
{
|
||||
seekdir(fs->dir, off);
|
||||
seekdir(fs->dir.stream, off);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
@ -998,7 +998,7 @@ static int local_fsync(FsContext *ctx, int fid_type,
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
|
@ -633,7 +633,7 @@ static int proxy_close(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,
|
||||
@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx,
|
||||
{
|
||||
int serrno, fd;
|
||||
|
||||
fs->dir = NULL;
|
||||
fs->dir.stream = NULL;
|
||||
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
|
||||
if (fd < 0) {
|
||||
errno = -fd;
|
||||
return -1;
|
||||
}
|
||||
fs->dir = fdopendir(fd);
|
||||
if (!fs->dir) {
|
||||
fs->dir.stream = fdopendir(fd);
|
||||
if (!fs->dir.stream) {
|
||||
serrno = errno;
|
||||
close(fd);
|
||||
errno = serrno;
|
||||
@ -670,24 +670,24 @@ static int proxy_opendir(FsContext *ctx,
|
||||
|
||||
static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||
{
|
||||
rewinddir(fs->dir);
|
||||
rewinddir(fs->dir.stream);
|
||||
}
|
||||
|
||||
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,
|
||||
struct dirent *entry,
|
||||
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)
|
||||
{
|
||||
seekdir(fs->dir, off);
|
||||
seekdir(fs->dir.stream, off);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
@ -936,7 +936,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
fd = dirfd(fs->dir.stream);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
} else if (f->fid_type == P9_FID_DIR) {
|
||||
if (f->fs.dir == NULL) {
|
||||
if (f->fs.dir.stream == NULL) {
|
||||
do {
|
||||
err = v9fs_co_opendir(pdu, f);
|
||||
} while (err == -EINTR && !pdu->cancelled);
|
||||
@ -345,7 +345,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
|
||||
retval = v9fs_co_close(pdu, &fidp->fs);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
} else if (fidp->fid_type == P9_FID_XATTR) {
|
||||
@ -443,7 +443,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
|
||||
reclaim_count++;
|
||||
}
|
||||
} 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
|
||||
* a clunk request won't free this fid
|
||||
@ -451,8 +451,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
|
||||
f->ref++;
|
||||
f->rclm_lst = reclaim_list;
|
||||
reclaim_list = f;
|
||||
f->fs_reclaim.dir = f->fs.dir;
|
||||
f->fs.dir = NULL;
|
||||
f->fs_reclaim.dir.stream = f->fs.dir.stream;
|
||||
f->fs.dir.stream = NULL;
|
||||
reclaim_count++;
|
||||
}
|
||||
}
|
||||
@ -1883,7 +1883,7 @@ static void v9fs_readdir(void *opaque)
|
||||
retval = -EINVAL;
|
||||
goto out_nofid;
|
||||
}
|
||||
if (!fidp->fs.dir) {
|
||||
if (!fidp->fs.dir.stream) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -167,13 +167,17 @@ typedef struct V9fsXattr
|
||||
int flags;
|
||||
} V9fsXattr;
|
||||
|
||||
typedef struct V9fsDir {
|
||||
DIR *stream;
|
||||
} V9fsDir;
|
||||
|
||||
/*
|
||||
* Filled by fs driver on open and other
|
||||
* calls.
|
||||
*/
|
||||
union V9fsFidOpenState {
|
||||
int fd;
|
||||
DIR *dir;
|
||||
V9fsDir dir;
|
||||
V9fsXattr xattr;
|
||||
/*
|
||||
* private pointer for fs drivers, that
|
||||
|
Loading…
Reference in New Issue
Block a user