Statistics
| Branch: | Revision:

root / hw / 9pfs / codir.c @ 737e150e

History | View | Annotate | Download (3.7 kB)

1

    
2
/*
3
 * Virtio 9p backend
4
 *
5
 * Copyright IBM, Corp. 2011
6
 *
7
 * Authors:
8
 *  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
9
 *
10
 * This work is licensed under the terms of the GNU GPL, version 2.  See
11
 * the COPYING file in the top-level directory.
12
 *
13
 */
14

    
15
#include "fsdev/qemu-fsdev.h"
16
#include "qemu-thread.h"
17
#include "block/coroutine.h"
18
#include "virtio-9p-coth.h"
19

    
20
int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
21
                      struct dirent **result)
22
{
23
    int err;
24
    V9fsState *s = pdu->s;
25

    
26
    if (v9fs_request_cancelled(pdu)) {
27
        return -EINTR;
28
    }
29
    v9fs_co_run_in_worker(
30
        {
31
            errno = 0;
32
            err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
33
            if (!*result && errno) {
34
                err = -errno;
35
            } else {
36
                err = 0;
37
            }
38
        });
39
    return err;
40
}
41

    
42
off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
43
{
44
    off_t err;
45
    V9fsState *s = pdu->s;
46

    
47
    if (v9fs_request_cancelled(pdu)) {
48
        return -EINTR;
49
    }
50
    v9fs_co_run_in_worker(
51
        {
52
            err = s->ops->telldir(&s->ctx, &fidp->fs);
53
            if (err < 0) {
54
                err = -errno;
55
            }
56
        });
57
    return err;
58
}
59

    
60
void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
61
{
62
    V9fsState *s = pdu->s;
63
    if (v9fs_request_cancelled(pdu)) {
64
        return;
65
    }
66
    v9fs_co_run_in_worker(
67
        {
68
            s->ops->seekdir(&s->ctx, &fidp->fs, offset);
69
        });
70
}
71

    
72
void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
73
{
74
    V9fsState *s = pdu->s;
75
    if (v9fs_request_cancelled(pdu)) {
76
        return;
77
    }
78
    v9fs_co_run_in_worker(
79
        {
80
            s->ops->rewinddir(&s->ctx, &fidp->fs);
81
        });
82
}
83

    
84
int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name,
85
                  mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf)
86
{
87
    int err;
88
    FsCred cred;
89
    V9fsPath path;
90
    V9fsState *s = pdu->s;
91

    
92
    if (v9fs_request_cancelled(pdu)) {
93
        return -EINTR;
94
    }
95
    cred_init(&cred);
96
    cred.fc_mode = mode;
97
    cred.fc_uid = uid;
98
    cred.fc_gid = gid;
99
    v9fs_path_read_lock(s);
100
    v9fs_co_run_in_worker(
101
        {
102
            err = s->ops->mkdir(&s->ctx, &fidp->path, name->data,  &cred);
103
            if (err < 0) {
104
                err = -errno;
105
            } else {
106
                v9fs_path_init(&path);
107
                err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
108
                if (!err) {
109
                    err = s->ops->lstat(&s->ctx, &path, stbuf);
110
                    if (err < 0) {
111
                        err = -errno;
112
                    }
113
                }
114
                v9fs_path_free(&path);
115
            }
116
        });
117
    v9fs_path_unlock(s);
118
    return err;
119
}
120

    
121
int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
122
{
123
    int err;
124
    V9fsState *s = pdu->s;
125

    
126
    if (v9fs_request_cancelled(pdu)) {
127
        return -EINTR;
128
    }
129
    v9fs_path_read_lock(s);
130
    v9fs_co_run_in_worker(
131
        {
132
            err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
133
            if (err < 0) {
134
                err = -errno;
135
            } else {
136
                err = 0;
137
            }
138
        });
139
    v9fs_path_unlock(s);
140
    if (!err) {
141
        total_open_fd++;
142
        if (total_open_fd > open_fd_hw) {
143
            v9fs_reclaim_fd(pdu);
144
        }
145
    }
146
    return err;
147
}
148

    
149
int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
150
{
151
    int err;
152
    V9fsState *s = pdu->s;
153

    
154
    if (v9fs_request_cancelled(pdu)) {
155
        return -EINTR;
156
    }
157
    v9fs_co_run_in_worker(
158
        {
159
            err = s->ops->closedir(&s->ctx, fs);
160
            if (err < 0) {
161
                err = -errno;
162
            }
163
        });
164
    if (!err) {
165
        total_open_fd--;
166
    }
167
    return err;
168
}