|
|
1.1 root 1:
2: /*
3: * Virtio 9p backend
4: *
5: * Copyright IBM, Corp. 2011
6: *
7: * Authors:
8: * Aneesh Kumar K.V <[email protected]>
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 "qemu-coroutine.h"
18: #include "virtio-9p-coth.h"
19:
20: int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
21: V9fsStatDotl *v9stat)
22: {
23: int err = 0;
24: V9fsState *s = pdu->s;
25:
26: if (v9fs_request_cancelled(pdu)) {
27: return -EINTR;
28: }
29: if (s->ctx.exops.get_st_gen) {
30: v9fs_path_read_lock(s);
31: v9fs_co_run_in_worker(
32: {
33: err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
34: &v9stat->st_gen);
35: if (err < 0) {
36: err = -errno;
37: }
38: });
39: v9fs_path_unlock(s);
40: }
41: return err;
42: }
43:
44: int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
45: {
46: int err;
47: V9fsState *s = pdu->s;
48:
49: if (v9fs_request_cancelled(pdu)) {
50: return -EINTR;
51: }
52: v9fs_path_read_lock(s);
53: v9fs_co_run_in_worker(
54: {
55: err = s->ops->lstat(&s->ctx, path, stbuf);
56: if (err < 0) {
57: err = -errno;
58: }
59: });
60: v9fs_path_unlock(s);
61: return err;
62: }
63:
64: int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
65: {
66: int err;
67: V9fsState *s = pdu->s;
68:
69: if (v9fs_request_cancelled(pdu)) {
70: return -EINTR;
71: }
72: v9fs_co_run_in_worker(
73: {
74: err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
75: if (err < 0) {
76: err = -errno;
77: }
78: });
1.1.1.2 ! root 79: /*
! 80: * Some FS driver (local:mapped-file) can't support fetching attributes
! 81: * using file descriptor. Use Path name in that case.
! 82: */
! 83: if (err == -EOPNOTSUPP) {
! 84: err = v9fs_co_lstat(pdu, &fidp->path, stbuf);
! 85: if (err == -ENOENT) {
! 86: /*
! 87: * fstat on an unlinked file. Work with partial results
! 88: * returned from s->ops->fstat
! 89: */
! 90: err = 0;
! 91: }
! 92: }
1.1 root 93: return err;
94: }
95:
96: int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
97: {
98: int err;
99: V9fsState *s = pdu->s;
100:
101: if (v9fs_request_cancelled(pdu)) {
102: return -EINTR;
103: }
104: v9fs_path_read_lock(s);
105: v9fs_co_run_in_worker(
106: {
107: err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs);
108: if (err == -1) {
109: err = -errno;
110: } else {
111: err = 0;
112: }
113: });
114: v9fs_path_unlock(s);
115: if (!err) {
116: total_open_fd++;
117: if (total_open_fd > open_fd_hw) {
118: v9fs_reclaim_fd(pdu);
119: }
120: }
121: return err;
122: }
123:
124: int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
125: int flags, int mode, struct stat *stbuf)
126: {
127: int err;
128: FsCred cred;
129: V9fsPath path;
130: V9fsState *s = pdu->s;
131:
132: if (v9fs_request_cancelled(pdu)) {
133: return -EINTR;
134: }
135: cred_init(&cred);
136: cred.fc_mode = mode & 07777;
137: cred.fc_uid = fidp->uid;
138: cred.fc_gid = gid;
139: /*
140: * Hold the directory fid lock so that directory path name
141: * don't change. Read lock is fine because this fid cannot
142: * be used by any other operation.
143: */
144: v9fs_path_read_lock(s);
145: v9fs_co_run_in_worker(
146: {
147: err = s->ops->open2(&s->ctx, &fidp->path,
148: name->data, flags, &cred, &fidp->fs);
149: if (err < 0) {
150: err = -errno;
151: } else {
152: v9fs_path_init(&path);
153: err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
154: if (!err) {
155: err = s->ops->lstat(&s->ctx, &path, stbuf);
156: if (err < 0) {
157: err = -errno;
158: s->ops->close(&s->ctx, &fidp->fs);
159: } else {
160: v9fs_path_copy(&fidp->path, &path);
161: }
162: } else {
163: s->ops->close(&s->ctx, &fidp->fs);
164: }
165: v9fs_path_free(&path);
166: }
167: });
168: v9fs_path_unlock(s);
169: if (!err) {
170: total_open_fd++;
171: if (total_open_fd > open_fd_hw) {
172: v9fs_reclaim_fd(pdu);
173: }
174: }
175: return err;
176: }
177:
178: int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs)
179: {
180: int err;
181: V9fsState *s = pdu->s;
182:
183: if (v9fs_request_cancelled(pdu)) {
184: return -EINTR;
185: }
186: v9fs_co_run_in_worker(
187: {
188: err = s->ops->close(&s->ctx, fs);
189: if (err < 0) {
190: err = -errno;
191: }
192: });
193: if (!err) {
194: total_open_fd--;
195: }
196: return err;
197: }
198:
199: int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
200: {
201: int err;
202: V9fsState *s = pdu->s;
203:
204: if (v9fs_request_cancelled(pdu)) {
205: return -EINTR;
206: }
207: v9fs_co_run_in_worker(
208: {
209: err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
210: if (err < 0) {
211: err = -errno;
212: }
213: });
214: return err;
215: }
216:
217: int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
218: V9fsFidState *newdirfid, V9fsString *name)
219: {
220: int err;
221: V9fsState *s = pdu->s;
222:
223: if (v9fs_request_cancelled(pdu)) {
224: return -EINTR;
225: }
226: v9fs_path_read_lock(s);
227: v9fs_co_run_in_worker(
228: {
229: err = s->ops->link(&s->ctx, &oldfid->path,
230: &newdirfid->path, name->data);
231: if (err < 0) {
232: err = -errno;
233: }
234: });
235: v9fs_path_unlock(s);
236: return err;
237: }
238:
239: int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
240: struct iovec *iov, int iovcnt, int64_t offset)
241: {
242: int err;
243: V9fsState *s = pdu->s;
244:
245: if (v9fs_request_cancelled(pdu)) {
246: return -EINTR;
247: }
248: v9fs_co_run_in_worker(
249: {
250: err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset);
251: if (err < 0) {
252: err = -errno;
253: }
254: });
255: return err;
256: }
257:
258: int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
259: struct iovec *iov, int iovcnt, int64_t offset)
260: {
261: int err;
262: V9fsState *s = pdu->s;
263:
264: if (v9fs_request_cancelled(pdu)) {
265: return -EINTR;
266: }
267: v9fs_co_run_in_worker(
268: {
269: err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset);
270: if (err < 0) {
271: err = -errno;
272: }
273: });
274: return err;
275: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.