root / hw / 9pfs / virtio-9p-handle.c @ 1f51470d
History | View | Annotate | Download (17.8 kB)
1 | 5f542225 | Aneesh Kumar K.V | /*
|
---|---|---|---|
2 | 5f542225 | Aneesh Kumar K.V | * Virtio 9p handle callback
|
3 | 5f542225 | Aneesh Kumar K.V | *
|
4 | 5f542225 | Aneesh Kumar K.V | * Copyright IBM, Corp. 2011
|
5 | 5f542225 | Aneesh Kumar K.V | *
|
6 | 5f542225 | Aneesh Kumar K.V | * Authors:
|
7 | 5f542225 | Aneesh Kumar K.V | * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
8 | 5f542225 | Aneesh Kumar K.V | *
|
9 | 5f542225 | Aneesh Kumar K.V | * This work is licensed under the terms of the GNU GPL, version 2. See
|
10 | 5f542225 | Aneesh Kumar K.V | * the COPYING file in the top-level directory.
|
11 | 5f542225 | Aneesh Kumar K.V | *
|
12 | 5f542225 | Aneesh Kumar K.V | */
|
13 | 5f542225 | Aneesh Kumar K.V | |
14 | 5f542225 | Aneesh Kumar K.V | #include "hw/virtio.h" |
15 | 5f542225 | Aneesh Kumar K.V | #include "virtio-9p.h" |
16 | 5f542225 | Aneesh Kumar K.V | #include "virtio-9p-xattr.h" |
17 | 5f542225 | Aneesh Kumar K.V | #include <arpa/inet.h> |
18 | 5f542225 | Aneesh Kumar K.V | #include <pwd.h> |
19 | 5f542225 | Aneesh Kumar K.V | #include <grp.h> |
20 | 5f542225 | Aneesh Kumar K.V | #include <sys/socket.h> |
21 | 5f542225 | Aneesh Kumar K.V | #include <sys/un.h> |
22 | 4f26f2b6 | Avi Kivity | #include "qemu-xattr.h" |
23 | 5f542225 | Aneesh Kumar K.V | #include <unistd.h> |
24 | edb9eb73 | Harsh Prateek Bora | #include <linux/fs.h> |
25 | edb9eb73 | Harsh Prateek Bora | #ifdef CONFIG_LINUX_MAGIC_H
|
26 | edb9eb73 | Harsh Prateek Bora | #include <linux/magic.h> |
27 | edb9eb73 | Harsh Prateek Bora | #endif
|
28 | edb9eb73 | Harsh Prateek Bora | #include <sys/ioctl.h> |
29 | edb9eb73 | Harsh Prateek Bora | |
30 | edb9eb73 | Harsh Prateek Bora | #ifndef XFS_SUPER_MAGIC
|
31 | edb9eb73 | Harsh Prateek Bora | #define XFS_SUPER_MAGIC 0x58465342 |
32 | edb9eb73 | Harsh Prateek Bora | #endif
|
33 | edb9eb73 | Harsh Prateek Bora | #ifndef EXT2_SUPER_MAGIC
|
34 | edb9eb73 | Harsh Prateek Bora | #define EXT2_SUPER_MAGIC 0xEF53 |
35 | edb9eb73 | Harsh Prateek Bora | #endif
|
36 | edb9eb73 | Harsh Prateek Bora | #ifndef REISERFS_SUPER_MAGIC
|
37 | edb9eb73 | Harsh Prateek Bora | #define REISERFS_SUPER_MAGIC 0x52654973 |
38 | edb9eb73 | Harsh Prateek Bora | #endif
|
39 | edb9eb73 | Harsh Prateek Bora | #ifndef BTRFS_SUPER_MAGIC
|
40 | edb9eb73 | Harsh Prateek Bora | #define BTRFS_SUPER_MAGIC 0x9123683E |
41 | edb9eb73 | Harsh Prateek Bora | #endif
|
42 | 5f542225 | Aneesh Kumar K.V | |
43 | 5f542225 | Aneesh Kumar K.V | struct handle_data {
|
44 | 5f542225 | Aneesh Kumar K.V | int mountfd;
|
45 | 5f542225 | Aneesh Kumar K.V | int handle_bytes;
|
46 | 5f542225 | Aneesh Kumar K.V | }; |
47 | 5f542225 | Aneesh Kumar K.V | |
48 | d2042378 | Aneesh Kumar K.V | static inline int name_to_handle(int dirfd, const char *name, |
49 | d2042378 | Aneesh Kumar K.V | struct file_handle *fh, int *mnt_id, int flags) |
50 | d2042378 | Aneesh Kumar K.V | { |
51 | d2042378 | Aneesh Kumar K.V | return name_to_handle_at(dirfd, name, fh, mnt_id, flags);
|
52 | d2042378 | Aneesh Kumar K.V | } |
53 | d2042378 | Aneesh Kumar K.V | |
54 | d2042378 | Aneesh Kumar K.V | static inline int open_by_handle(int mountfd, const char *fh, int flags) |
55 | d2042378 | Aneesh Kumar K.V | { |
56 | d2042378 | Aneesh Kumar K.V | return open_by_handle_at(mountfd, (struct file_handle *)fh, flags); |
57 | d2042378 | Aneesh Kumar K.V | } |
58 | 5f542225 | Aneesh Kumar K.V | |
59 | 5f542225 | Aneesh Kumar K.V | static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp) |
60 | 5f542225 | Aneesh Kumar K.V | { |
61 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
62 | 3a93113a | Dong Xu Wang | fd = openat(dirfd, name, O_NONBLOCK | O_NOFOLLOW); |
63 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
64 | 5f542225 | Aneesh Kumar K.V | return fd;
|
65 | 5f542225 | Aneesh Kumar K.V | } |
66 | 2d40564a | M. Mohan Kumar | ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH);
|
67 | 5f542225 | Aneesh Kumar K.V | if (ret < 0) { |
68 | 5f542225 | Aneesh Kumar K.V | goto err_out;
|
69 | 5f542225 | Aneesh Kumar K.V | } |
70 | 2d40564a | M. Mohan Kumar | ret = fchmod(fd, credp->fc_mode & 07777);
|
71 | 5f542225 | Aneesh Kumar K.V | err_out:
|
72 | 5f542225 | Aneesh Kumar K.V | close(fd); |
73 | 5f542225 | Aneesh Kumar K.V | return ret;
|
74 | 5f542225 | Aneesh Kumar K.V | } |
75 | 5f542225 | Aneesh Kumar K.V | |
76 | 5f542225 | Aneesh Kumar K.V | |
77 | 5f542225 | Aneesh Kumar K.V | static int handle_lstat(FsContext *fs_ctx, V9fsPath *fs_path, |
78 | 5f542225 | Aneesh Kumar K.V | struct stat *stbuf)
|
79 | 5f542225 | Aneesh Kumar K.V | { |
80 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
81 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
82 | 5f542225 | Aneesh Kumar K.V | |
83 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); |
84 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
85 | 5f542225 | Aneesh Kumar K.V | return fd;
|
86 | 5f542225 | Aneesh Kumar K.V | } |
87 | 5f542225 | Aneesh Kumar K.V | ret = fstatat(fd, "", stbuf, AT_EMPTY_PATH);
|
88 | 5f542225 | Aneesh Kumar K.V | close(fd); |
89 | 5f542225 | Aneesh Kumar K.V | return ret;
|
90 | 5f542225 | Aneesh Kumar K.V | } |
91 | 5f542225 | Aneesh Kumar K.V | |
92 | 5f542225 | Aneesh Kumar K.V | static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
|
93 | 5f542225 | Aneesh Kumar K.V | char *buf, size_t bufsz)
|
94 | 5f542225 | Aneesh Kumar K.V | { |
95 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
96 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
97 | 5f542225 | Aneesh Kumar K.V | |
98 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); |
99 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
100 | 5f542225 | Aneesh Kumar K.V | return fd;
|
101 | 5f542225 | Aneesh Kumar K.V | } |
102 | 5f542225 | Aneesh Kumar K.V | ret = readlinkat(fd, "", buf, bufsz);
|
103 | 5f542225 | Aneesh Kumar K.V | close(fd); |
104 | 5f542225 | Aneesh Kumar K.V | return ret;
|
105 | 5f542225 | Aneesh Kumar K.V | } |
106 | 5f542225 | Aneesh Kumar K.V | |
107 | cc720ddb | Aneesh Kumar K.V | static int handle_close(FsContext *ctx, V9fsFidOpenState *fs) |
108 | 5f542225 | Aneesh Kumar K.V | { |
109 | cc720ddb | Aneesh Kumar K.V | return close(fs->fd);
|
110 | 5f542225 | Aneesh Kumar K.V | } |
111 | 5f542225 | Aneesh Kumar K.V | |
112 | cc720ddb | Aneesh Kumar K.V | static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs) |
113 | 5f542225 | Aneesh Kumar K.V | { |
114 | cc720ddb | Aneesh Kumar K.V | return closedir(fs->dir);
|
115 | 5f542225 | Aneesh Kumar K.V | } |
116 | 5f542225 | Aneesh Kumar K.V | |
117 | cc720ddb | Aneesh Kumar K.V | static int handle_open(FsContext *ctx, V9fsPath *fs_path, |
118 | cc720ddb | Aneesh Kumar K.V | int flags, V9fsFidOpenState *fs)
|
119 | 5f542225 | Aneesh Kumar K.V | { |
120 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
121 | 5f542225 | Aneesh Kumar K.V | |
122 | cc720ddb | Aneesh Kumar K.V | fs->fd = open_by_handle(data->mountfd, fs_path->data, flags); |
123 | cc720ddb | Aneesh Kumar K.V | return fs->fd;
|
124 | 5f542225 | Aneesh Kumar K.V | } |
125 | 5f542225 | Aneesh Kumar K.V | |
126 | cc720ddb | Aneesh Kumar K.V | static int handle_opendir(FsContext *ctx, |
127 | cc720ddb | Aneesh Kumar K.V | V9fsPath *fs_path, V9fsFidOpenState *fs) |
128 | 5f542225 | Aneesh Kumar K.V | { |
129 | cc720ddb | Aneesh Kumar K.V | int ret;
|
130 | cc720ddb | Aneesh Kumar K.V | ret = handle_open(ctx, fs_path, O_DIRECTORY, fs); |
131 | cc720ddb | Aneesh Kumar K.V | if (ret < 0) { |
132 | cc720ddb | Aneesh Kumar K.V | return -1; |
133 | 5f542225 | Aneesh Kumar K.V | } |
134 | cc720ddb | Aneesh Kumar K.V | fs->dir = fdopendir(ret); |
135 | cc720ddb | Aneesh Kumar K.V | if (!fs->dir) {
|
136 | cc720ddb | Aneesh Kumar K.V | return -1; |
137 | cc720ddb | Aneesh Kumar K.V | } |
138 | cc720ddb | Aneesh Kumar K.V | return 0; |
139 | 5f542225 | Aneesh Kumar K.V | } |
140 | 5f542225 | Aneesh Kumar K.V | |
141 | cc720ddb | Aneesh Kumar K.V | static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) |
142 | 5f542225 | Aneesh Kumar K.V | { |
143 | cc720ddb | Aneesh Kumar K.V | return rewinddir(fs->dir);
|
144 | 5f542225 | Aneesh Kumar K.V | } |
145 | 5f542225 | Aneesh Kumar K.V | |
146 | cc720ddb | Aneesh Kumar K.V | static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
147 | 5f542225 | Aneesh Kumar K.V | { |
148 | cc720ddb | Aneesh Kumar K.V | return telldir(fs->dir);
|
149 | 5f542225 | Aneesh Kumar K.V | } |
150 | 5f542225 | Aneesh Kumar K.V | |
151 | cc720ddb | Aneesh Kumar K.V | static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, |
152 | cc720ddb | Aneesh Kumar K.V | struct dirent *entry,
|
153 | 5f542225 | Aneesh Kumar K.V | struct dirent **result)
|
154 | 5f542225 | Aneesh Kumar K.V | { |
155 | cc720ddb | Aneesh Kumar K.V | return readdir_r(fs->dir, entry, result);
|
156 | 5f542225 | Aneesh Kumar K.V | } |
157 | 5f542225 | Aneesh Kumar K.V | |
158 | cc720ddb | Aneesh Kumar K.V | static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) |
159 | 5f542225 | Aneesh Kumar K.V | { |
160 | cc720ddb | Aneesh Kumar K.V | return seekdir(fs->dir, off);
|
161 | 5f542225 | Aneesh Kumar K.V | } |
162 | 5f542225 | Aneesh Kumar K.V | |
163 | cc720ddb | Aneesh Kumar K.V | static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
|
164 | cc720ddb | Aneesh Kumar K.V | const struct iovec *iov, |
165 | 5f542225 | Aneesh Kumar K.V | int iovcnt, off_t offset)
|
166 | 5f542225 | Aneesh Kumar K.V | { |
167 | 5f542225 | Aneesh Kumar K.V | #ifdef CONFIG_PREADV
|
168 | cc720ddb | Aneesh Kumar K.V | return preadv(fs->fd, iov, iovcnt, offset);
|
169 | 5f542225 | Aneesh Kumar K.V | #else
|
170 | cc720ddb | Aneesh Kumar K.V | int err = lseek(fs->fd, offset, SEEK_SET);
|
171 | 5f542225 | Aneesh Kumar K.V | if (err == -1) { |
172 | 5f542225 | Aneesh Kumar K.V | return err;
|
173 | 5f542225 | Aneesh Kumar K.V | } else {
|
174 | cc720ddb | Aneesh Kumar K.V | return readv(fs->fd, iov, iovcnt);
|
175 | 5f542225 | Aneesh Kumar K.V | } |
176 | 5f542225 | Aneesh Kumar K.V | #endif
|
177 | 5f542225 | Aneesh Kumar K.V | } |
178 | 5f542225 | Aneesh Kumar K.V | |
179 | cc720ddb | Aneesh Kumar K.V | static ssize_t handle_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
|
180 | cc720ddb | Aneesh Kumar K.V | const struct iovec *iov, |
181 | 5f542225 | Aneesh Kumar K.V | int iovcnt, off_t offset)
|
182 | 5f542225 | Aneesh Kumar K.V | { |
183 | d3ab98e6 | Aneesh Kumar K.V | ssize_t ret; |
184 | 5f542225 | Aneesh Kumar K.V | #ifdef CONFIG_PREADV
|
185 | cc720ddb | Aneesh Kumar K.V | ret = pwritev(fs->fd, iov, iovcnt, offset); |
186 | 5f542225 | Aneesh Kumar K.V | #else
|
187 | cc720ddb | Aneesh Kumar K.V | int err = lseek(fs->fd, offset, SEEK_SET);
|
188 | 5f542225 | Aneesh Kumar K.V | if (err == -1) { |
189 | 5f542225 | Aneesh Kumar K.V | return err;
|
190 | 5f542225 | Aneesh Kumar K.V | } else {
|
191 | cc720ddb | Aneesh Kumar K.V | ret = writev(fs->fd, iov, iovcnt); |
192 | 5f542225 | Aneesh Kumar K.V | } |
193 | 5f542225 | Aneesh Kumar K.V | #endif
|
194 | d3ab98e6 | Aneesh Kumar K.V | #ifdef CONFIG_SYNC_FILE_RANGE
|
195 | d3ab98e6 | Aneesh Kumar K.V | if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) { |
196 | d3ab98e6 | Aneesh Kumar K.V | /*
|
197 | d3ab98e6 | Aneesh Kumar K.V | * Initiate a writeback. This is not a data integrity sync.
|
198 | d3ab98e6 | Aneesh Kumar K.V | * We want to ensure that we don't leave dirty pages in the cache
|
199 | d3ab98e6 | Aneesh Kumar K.V | * after write when writeout=immediate is sepcified.
|
200 | d3ab98e6 | Aneesh Kumar K.V | */
|
201 | cc720ddb | Aneesh Kumar K.V | sync_file_range(fs->fd, offset, ret, |
202 | d3ab98e6 | Aneesh Kumar K.V | SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); |
203 | d3ab98e6 | Aneesh Kumar K.V | } |
204 | d3ab98e6 | Aneesh Kumar K.V | #endif
|
205 | d3ab98e6 | Aneesh Kumar K.V | return ret;
|
206 | 5f542225 | Aneesh Kumar K.V | } |
207 | 5f542225 | Aneesh Kumar K.V | |
208 | 5f542225 | Aneesh Kumar K.V | static int handle_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) |
209 | 5f542225 | Aneesh Kumar K.V | { |
210 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
211 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
212 | 5f542225 | Aneesh Kumar K.V | |
213 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
214 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
215 | 5f542225 | Aneesh Kumar K.V | return fd;
|
216 | 5f542225 | Aneesh Kumar K.V | } |
217 | 5f542225 | Aneesh Kumar K.V | ret = fchmod(fd, credp->fc_mode); |
218 | 5f542225 | Aneesh Kumar K.V | close(fd); |
219 | 5f542225 | Aneesh Kumar K.V | return ret;
|
220 | 5f542225 | Aneesh Kumar K.V | } |
221 | 5f542225 | Aneesh Kumar K.V | |
222 | 5f542225 | Aneesh Kumar K.V | static int handle_mknod(FsContext *fs_ctx, V9fsPath *dir_path, |
223 | 5f542225 | Aneesh Kumar K.V | const char *name, FsCred *credp) |
224 | 5f542225 | Aneesh Kumar K.V | { |
225 | 5f542225 | Aneesh Kumar K.V | int dirfd, ret;
|
226 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
227 | 5f542225 | Aneesh Kumar K.V | |
228 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); |
229 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
230 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
231 | 5f542225 | Aneesh Kumar K.V | } |
232 | 5f542225 | Aneesh Kumar K.V | ret = mknodat(dirfd, name, credp->fc_mode, credp->fc_rdev); |
233 | 5f542225 | Aneesh Kumar K.V | if (!ret) {
|
234 | 5f542225 | Aneesh Kumar K.V | ret = handle_update_file_cred(dirfd, name, credp); |
235 | 5f542225 | Aneesh Kumar K.V | } |
236 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
237 | 5f542225 | Aneesh Kumar K.V | return ret;
|
238 | 5f542225 | Aneesh Kumar K.V | } |
239 | 5f542225 | Aneesh Kumar K.V | |
240 | 5f542225 | Aneesh Kumar K.V | static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, |
241 | 5f542225 | Aneesh Kumar K.V | const char *name, FsCred *credp) |
242 | 5f542225 | Aneesh Kumar K.V | { |
243 | 5f542225 | Aneesh Kumar K.V | int dirfd, ret;
|
244 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
245 | 5f542225 | Aneesh Kumar K.V | |
246 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); |
247 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
248 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
249 | 5f542225 | Aneesh Kumar K.V | } |
250 | 5f542225 | Aneesh Kumar K.V | ret = mkdirat(dirfd, name, credp->fc_mode); |
251 | 5f542225 | Aneesh Kumar K.V | if (!ret) {
|
252 | 5f542225 | Aneesh Kumar K.V | ret = handle_update_file_cred(dirfd, name, credp); |
253 | 5f542225 | Aneesh Kumar K.V | } |
254 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
255 | 5f542225 | Aneesh Kumar K.V | return ret;
|
256 | 5f542225 | Aneesh Kumar K.V | } |
257 | 5f542225 | Aneesh Kumar K.V | |
258 | 8b888272 | Aneesh Kumar K.V | static int handle_fstat(FsContext *fs_ctx, int fid_type, |
259 | 8b888272 | Aneesh Kumar K.V | V9fsFidOpenState *fs, struct stat *stbuf)
|
260 | 5f542225 | Aneesh Kumar K.V | { |
261 | 8b888272 | Aneesh Kumar K.V | int fd;
|
262 | 8b888272 | Aneesh Kumar K.V | |
263 | 8b888272 | Aneesh Kumar K.V | if (fid_type == P9_FID_DIR) {
|
264 | 8b888272 | Aneesh Kumar K.V | fd = dirfd(fs->dir); |
265 | 8b888272 | Aneesh Kumar K.V | } else {
|
266 | 8b888272 | Aneesh Kumar K.V | fd = fs->fd; |
267 | 8b888272 | Aneesh Kumar K.V | } |
268 | 8b888272 | Aneesh Kumar K.V | return fstat(fd, stbuf);
|
269 | 5f542225 | Aneesh Kumar K.V | } |
270 | 5f542225 | Aneesh Kumar K.V | |
271 | 5f542225 | Aneesh Kumar K.V | static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, |
272 | cc720ddb | Aneesh Kumar K.V | int flags, FsCred *credp, V9fsFidOpenState *fs)
|
273 | 5f542225 | Aneesh Kumar K.V | { |
274 | 5f542225 | Aneesh Kumar K.V | int ret;
|
275 | 5f542225 | Aneesh Kumar K.V | int dirfd, fd;
|
276 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
277 | 5f542225 | Aneesh Kumar K.V | |
278 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); |
279 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
280 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
281 | 5f542225 | Aneesh Kumar K.V | } |
282 | 5f542225 | Aneesh Kumar K.V | fd = openat(dirfd, name, flags | O_NOFOLLOW, credp->fc_mode); |
283 | 5f542225 | Aneesh Kumar K.V | if (fd >= 0) { |
284 | 5f542225 | Aneesh Kumar K.V | ret = handle_update_file_cred(dirfd, name, credp); |
285 | 5f542225 | Aneesh Kumar K.V | if (ret < 0) { |
286 | 5f542225 | Aneesh Kumar K.V | close(fd); |
287 | 5f542225 | Aneesh Kumar K.V | fd = ret; |
288 | cc720ddb | Aneesh Kumar K.V | } else {
|
289 | cc720ddb | Aneesh Kumar K.V | fs->fd = fd; |
290 | 5f542225 | Aneesh Kumar K.V | } |
291 | 5f542225 | Aneesh Kumar K.V | } |
292 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
293 | 5f542225 | Aneesh Kumar K.V | return fd;
|
294 | 5f542225 | Aneesh Kumar K.V | } |
295 | 5f542225 | Aneesh Kumar K.V | |
296 | 5f542225 | Aneesh Kumar K.V | |
297 | 5f542225 | Aneesh Kumar K.V | static int handle_symlink(FsContext *fs_ctx, const char *oldpath, |
298 | 5f542225 | Aneesh Kumar K.V | V9fsPath *dir_path, const char *name, FsCred *credp) |
299 | 5f542225 | Aneesh Kumar K.V | { |
300 | 5f542225 | Aneesh Kumar K.V | int fd, dirfd, ret;
|
301 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
302 | 5f542225 | Aneesh Kumar K.V | |
303 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); |
304 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
305 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
306 | 5f542225 | Aneesh Kumar K.V | } |
307 | 5f542225 | Aneesh Kumar K.V | ret = symlinkat(oldpath, dirfd, name); |
308 | 5f542225 | Aneesh Kumar K.V | if (!ret) {
|
309 | 5f542225 | Aneesh Kumar K.V | fd = openat(dirfd, name, O_PATH | O_NOFOLLOW); |
310 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
311 | 5f542225 | Aneesh Kumar K.V | ret = fd; |
312 | 5f542225 | Aneesh Kumar K.V | goto err_out;
|
313 | 5f542225 | Aneesh Kumar K.V | } |
314 | 5f542225 | Aneesh Kumar K.V | ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH);
|
315 | 5f542225 | Aneesh Kumar K.V | close(fd); |
316 | 5f542225 | Aneesh Kumar K.V | } |
317 | 5f542225 | Aneesh Kumar K.V | err_out:
|
318 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
319 | 5f542225 | Aneesh Kumar K.V | return ret;
|
320 | 5f542225 | Aneesh Kumar K.V | } |
321 | 5f542225 | Aneesh Kumar K.V | |
322 | 5f542225 | Aneesh Kumar K.V | static int handle_link(FsContext *ctx, V9fsPath *oldpath, |
323 | 5f542225 | Aneesh Kumar K.V | V9fsPath *dirpath, const char *name) |
324 | 5f542225 | Aneesh Kumar K.V | { |
325 | 5f542225 | Aneesh Kumar K.V | int oldfd, newdirfd, ret;
|
326 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
327 | 5f542225 | Aneesh Kumar K.V | |
328 | 5f542225 | Aneesh Kumar K.V | oldfd = open_by_handle(data->mountfd, oldpath->data, O_PATH); |
329 | 5f542225 | Aneesh Kumar K.V | if (oldfd < 0) { |
330 | 5f542225 | Aneesh Kumar K.V | return oldfd;
|
331 | 5f542225 | Aneesh Kumar K.V | } |
332 | 5f542225 | Aneesh Kumar K.V | newdirfd = open_by_handle(data->mountfd, dirpath->data, O_PATH); |
333 | 5f542225 | Aneesh Kumar K.V | if (newdirfd < 0) { |
334 | 5f542225 | Aneesh Kumar K.V | close(oldfd); |
335 | 5f542225 | Aneesh Kumar K.V | return newdirfd;
|
336 | 5f542225 | Aneesh Kumar K.V | } |
337 | 5f542225 | Aneesh Kumar K.V | ret = linkat(oldfd, "", newdirfd, name, AT_EMPTY_PATH);
|
338 | 5f542225 | Aneesh Kumar K.V | close(newdirfd); |
339 | 5f542225 | Aneesh Kumar K.V | close(oldfd); |
340 | 5f542225 | Aneesh Kumar K.V | return ret;
|
341 | 5f542225 | Aneesh Kumar K.V | } |
342 | 5f542225 | Aneesh Kumar K.V | |
343 | 5f542225 | Aneesh Kumar K.V | static int handle_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size) |
344 | 5f542225 | Aneesh Kumar K.V | { |
345 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
346 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
347 | 5f542225 | Aneesh Kumar K.V | |
348 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK | O_WRONLY); |
349 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
350 | 5f542225 | Aneesh Kumar K.V | return fd;
|
351 | 5f542225 | Aneesh Kumar K.V | } |
352 | 5f542225 | Aneesh Kumar K.V | ret = ftruncate(fd, size); |
353 | 5f542225 | Aneesh Kumar K.V | close(fd); |
354 | 5f542225 | Aneesh Kumar K.V | return ret;
|
355 | 5f542225 | Aneesh Kumar K.V | } |
356 | 5f542225 | Aneesh Kumar K.V | |
357 | 5f542225 | Aneesh Kumar K.V | static int handle_rename(FsContext *ctx, const char *oldpath, |
358 | 5f542225 | Aneesh Kumar K.V | const char *newpath) |
359 | 5f542225 | Aneesh Kumar K.V | { |
360 | 5f542225 | Aneesh Kumar K.V | errno = EOPNOTSUPP; |
361 | 5f542225 | Aneesh Kumar K.V | return -1; |
362 | 5f542225 | Aneesh Kumar K.V | } |
363 | 5f542225 | Aneesh Kumar K.V | |
364 | 5f542225 | Aneesh Kumar K.V | static int handle_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) |
365 | 5f542225 | Aneesh Kumar K.V | { |
366 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
367 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)fs_ctx->private; |
368 | 5f542225 | Aneesh Kumar K.V | |
369 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); |
370 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
371 | 5f542225 | Aneesh Kumar K.V | return fd;
|
372 | 5f542225 | Aneesh Kumar K.V | } |
373 | 5f542225 | Aneesh Kumar K.V | ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH);
|
374 | 5f542225 | Aneesh Kumar K.V | close(fd); |
375 | 5f542225 | Aneesh Kumar K.V | return ret;
|
376 | 5f542225 | Aneesh Kumar K.V | } |
377 | 5f542225 | Aneesh Kumar K.V | |
378 | 5f542225 | Aneesh Kumar K.V | static int handle_utimensat(FsContext *ctx, V9fsPath *fs_path, |
379 | 5f542225 | Aneesh Kumar K.V | const struct timespec *buf) |
380 | 5f542225 | Aneesh Kumar K.V | { |
381 | d2042378 | Aneesh Kumar K.V | int ret;
|
382 | d2042378 | Aneesh Kumar K.V | #ifdef CONFIG_UTIMENSAT
|
383 | d2042378 | Aneesh Kumar K.V | int fd;
|
384 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
385 | 5f542225 | Aneesh Kumar K.V | |
386 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
387 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
388 | 5f542225 | Aneesh Kumar K.V | return fd;
|
389 | 5f542225 | Aneesh Kumar K.V | } |
390 | 5f542225 | Aneesh Kumar K.V | ret = futimens(fd, buf); |
391 | 5f542225 | Aneesh Kumar K.V | close(fd); |
392 | d2042378 | Aneesh Kumar K.V | #else
|
393 | d2042378 | Aneesh Kumar K.V | ret = -1;
|
394 | d2042378 | Aneesh Kumar K.V | errno = ENOSYS; |
395 | d2042378 | Aneesh Kumar K.V | #endif
|
396 | 5f542225 | Aneesh Kumar K.V | return ret;
|
397 | 5f542225 | Aneesh Kumar K.V | } |
398 | 5f542225 | Aneesh Kumar K.V | |
399 | 5f542225 | Aneesh Kumar K.V | static int handle_remove(FsContext *ctx, const char *path) |
400 | 5f542225 | Aneesh Kumar K.V | { |
401 | 5f542225 | Aneesh Kumar K.V | errno = EOPNOTSUPP; |
402 | 5f542225 | Aneesh Kumar K.V | return -1; |
403 | 5f542225 | Aneesh Kumar K.V | } |
404 | 5f542225 | Aneesh Kumar K.V | |
405 | 8b888272 | Aneesh Kumar K.V | static int handle_fsync(FsContext *ctx, int fid_type, |
406 | 8b888272 | Aneesh Kumar K.V | V9fsFidOpenState *fs, int datasync)
|
407 | 5f542225 | Aneesh Kumar K.V | { |
408 | 8b888272 | Aneesh Kumar K.V | int fd;
|
409 | 8b888272 | Aneesh Kumar K.V | |
410 | 8b888272 | Aneesh Kumar K.V | if (fid_type == P9_FID_DIR) {
|
411 | 8b888272 | Aneesh Kumar K.V | fd = dirfd(fs->dir); |
412 | 8b888272 | Aneesh Kumar K.V | } else {
|
413 | 8b888272 | Aneesh Kumar K.V | fd = fs->fd; |
414 | 8b888272 | Aneesh Kumar K.V | } |
415 | 8b888272 | Aneesh Kumar K.V | |
416 | 5f542225 | Aneesh Kumar K.V | if (datasync) {
|
417 | 8b888272 | Aneesh Kumar K.V | return qemu_fdatasync(fd);
|
418 | 5f542225 | Aneesh Kumar K.V | } else {
|
419 | 8b888272 | Aneesh Kumar K.V | return fsync(fd);
|
420 | 5f542225 | Aneesh Kumar K.V | } |
421 | 5f542225 | Aneesh Kumar K.V | } |
422 | 5f542225 | Aneesh Kumar K.V | |
423 | 5f542225 | Aneesh Kumar K.V | static int handle_statfs(FsContext *ctx, V9fsPath *fs_path, |
424 | 5f542225 | Aneesh Kumar K.V | struct statfs *stbuf)
|
425 | 5f542225 | Aneesh Kumar K.V | { |
426 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
427 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
428 | 5f542225 | Aneesh Kumar K.V | |
429 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
430 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
431 | 5f542225 | Aneesh Kumar K.V | return fd;
|
432 | 5f542225 | Aneesh Kumar K.V | } |
433 | 5f542225 | Aneesh Kumar K.V | ret = fstatfs(fd, stbuf); |
434 | 5f542225 | Aneesh Kumar K.V | close(fd); |
435 | 5f542225 | Aneesh Kumar K.V | return ret;
|
436 | 5f542225 | Aneesh Kumar K.V | } |
437 | 5f542225 | Aneesh Kumar K.V | |
438 | 5f542225 | Aneesh Kumar K.V | static ssize_t handle_lgetxattr(FsContext *ctx, V9fsPath *fs_path,
|
439 | 5f542225 | Aneesh Kumar K.V | const char *name, void *value, size_t size) |
440 | 5f542225 | Aneesh Kumar K.V | { |
441 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
442 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
443 | 5f542225 | Aneesh Kumar K.V | |
444 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
445 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
446 | 5f542225 | Aneesh Kumar K.V | return fd;
|
447 | 5f542225 | Aneesh Kumar K.V | } |
448 | 5f542225 | Aneesh Kumar K.V | ret = fgetxattr(fd, name, value, size); |
449 | 5f542225 | Aneesh Kumar K.V | close(fd); |
450 | 5f542225 | Aneesh Kumar K.V | return ret;
|
451 | 5f542225 | Aneesh Kumar K.V | } |
452 | 5f542225 | Aneesh Kumar K.V | |
453 | 5f542225 | Aneesh Kumar K.V | static ssize_t handle_llistxattr(FsContext *ctx, V9fsPath *fs_path,
|
454 | 5f542225 | Aneesh Kumar K.V | void *value, size_t size)
|
455 | 5f542225 | Aneesh Kumar K.V | { |
456 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
457 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
458 | 5f542225 | Aneesh Kumar K.V | |
459 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
460 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
461 | 5f542225 | Aneesh Kumar K.V | return fd;
|
462 | 5f542225 | Aneesh Kumar K.V | } |
463 | 5f542225 | Aneesh Kumar K.V | ret = flistxattr(fd, value, size); |
464 | 5f542225 | Aneesh Kumar K.V | close(fd); |
465 | 5f542225 | Aneesh Kumar K.V | return ret;
|
466 | 5f542225 | Aneesh Kumar K.V | } |
467 | 5f542225 | Aneesh Kumar K.V | |
468 | 5f542225 | Aneesh Kumar K.V | static int handle_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, |
469 | 5f542225 | Aneesh Kumar K.V | void *value, size_t size, int flags) |
470 | 5f542225 | Aneesh Kumar K.V | { |
471 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
472 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
473 | 5f542225 | Aneesh Kumar K.V | |
474 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
475 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
476 | 5f542225 | Aneesh Kumar K.V | return fd;
|
477 | 5f542225 | Aneesh Kumar K.V | } |
478 | 5f542225 | Aneesh Kumar K.V | ret = fsetxattr(fd, name, value, size, flags); |
479 | 5f542225 | Aneesh Kumar K.V | close(fd); |
480 | 5f542225 | Aneesh Kumar K.V | return ret;
|
481 | 5f542225 | Aneesh Kumar K.V | } |
482 | 5f542225 | Aneesh Kumar K.V | |
483 | 5f542225 | Aneesh Kumar K.V | static int handle_lremovexattr(FsContext *ctx, V9fsPath *fs_path, |
484 | 5f542225 | Aneesh Kumar K.V | const char *name) |
485 | 5f542225 | Aneesh Kumar K.V | { |
486 | 5f542225 | Aneesh Kumar K.V | int fd, ret;
|
487 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
488 | 5f542225 | Aneesh Kumar K.V | |
489 | 5f542225 | Aneesh Kumar K.V | fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); |
490 | 5f542225 | Aneesh Kumar K.V | if (fd < 0) { |
491 | 5f542225 | Aneesh Kumar K.V | return fd;
|
492 | 5f542225 | Aneesh Kumar K.V | } |
493 | 5f542225 | Aneesh Kumar K.V | ret = fremovexattr(fd, name); |
494 | 5f542225 | Aneesh Kumar K.V | close(fd); |
495 | 5f542225 | Aneesh Kumar K.V | return ret;
|
496 | 5f542225 | Aneesh Kumar K.V | } |
497 | 5f542225 | Aneesh Kumar K.V | |
498 | 5f542225 | Aneesh Kumar K.V | static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path, |
499 | 5f542225 | Aneesh Kumar K.V | const char *name, V9fsPath *target) |
500 | 5f542225 | Aneesh Kumar K.V | { |
501 | 5f542225 | Aneesh Kumar K.V | char buffer[PATH_MAX];
|
502 | 5f542225 | Aneesh Kumar K.V | struct file_handle *fh;
|
503 | 5f542225 | Aneesh Kumar K.V | int dirfd, ret, mnt_id;
|
504 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
505 | 5f542225 | Aneesh Kumar K.V | |
506 | 5f542225 | Aneesh Kumar K.V | /* "." and ".." are not allowed */
|
507 | 5f542225 | Aneesh Kumar K.V | if (!strcmp(name, ".") || !strcmp(name, "..")) { |
508 | 5f542225 | Aneesh Kumar K.V | errno = EINVAL; |
509 | 5f542225 | Aneesh Kumar K.V | return -1; |
510 | 5f542225 | Aneesh Kumar K.V | |
511 | 5f542225 | Aneesh Kumar K.V | } |
512 | 5f542225 | Aneesh Kumar K.V | if (dir_path) {
|
513 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); |
514 | 5f542225 | Aneesh Kumar K.V | } else {
|
515 | 5f542225 | Aneesh Kumar K.V | /* relative to export root */
|
516 | 5f542225 | Aneesh Kumar K.V | dirfd = open(rpath(ctx, ".", buffer), O_DIRECTORY);
|
517 | 5f542225 | Aneesh Kumar K.V | } |
518 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
519 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
520 | 5f542225 | Aneesh Kumar K.V | } |
521 | 5f542225 | Aneesh Kumar K.V | fh = g_malloc(sizeof(struct file_handle) + data->handle_bytes); |
522 | 5f542225 | Aneesh Kumar K.V | fh->handle_bytes = data->handle_bytes; |
523 | 66a0a2cb | Dong Xu Wang | /* add a "./" at the beginning of the path */
|
524 | 5f542225 | Aneesh Kumar K.V | snprintf(buffer, PATH_MAX, "./%s", name);
|
525 | 5f542225 | Aneesh Kumar K.V | /* flag = 0 imply don't follow symlink */
|
526 | 5f542225 | Aneesh Kumar K.V | ret = name_to_handle(dirfd, buffer, fh, &mnt_id, 0);
|
527 | 5f542225 | Aneesh Kumar K.V | if (!ret) {
|
528 | 5f542225 | Aneesh Kumar K.V | target->data = (char *)fh;
|
529 | 5f542225 | Aneesh Kumar K.V | target->size = sizeof(struct file_handle) + data->handle_bytes; |
530 | 5f542225 | Aneesh Kumar K.V | } else {
|
531 | 5f542225 | Aneesh Kumar K.V | g_free(fh); |
532 | 5f542225 | Aneesh Kumar K.V | } |
533 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
534 | 5f542225 | Aneesh Kumar K.V | return ret;
|
535 | 5f542225 | Aneesh Kumar K.V | } |
536 | 5f542225 | Aneesh Kumar K.V | |
537 | 5f542225 | Aneesh Kumar K.V | static int handle_renameat(FsContext *ctx, V9fsPath *olddir, |
538 | 5f542225 | Aneesh Kumar K.V | const char *old_name, V9fsPath *newdir, |
539 | 5f542225 | Aneesh Kumar K.V | const char *new_name) |
540 | 5f542225 | Aneesh Kumar K.V | { |
541 | 5f542225 | Aneesh Kumar K.V | int olddirfd, newdirfd, ret;
|
542 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
543 | 5f542225 | Aneesh Kumar K.V | |
544 | 5f542225 | Aneesh Kumar K.V | olddirfd = open_by_handle(data->mountfd, olddir->data, O_PATH); |
545 | 5f542225 | Aneesh Kumar K.V | if (olddirfd < 0) { |
546 | 5f542225 | Aneesh Kumar K.V | return olddirfd;
|
547 | 5f542225 | Aneesh Kumar K.V | } |
548 | 5f542225 | Aneesh Kumar K.V | newdirfd = open_by_handle(data->mountfd, newdir->data, O_PATH); |
549 | 5f542225 | Aneesh Kumar K.V | if (newdirfd < 0) { |
550 | 5f542225 | Aneesh Kumar K.V | close(olddirfd); |
551 | 5f542225 | Aneesh Kumar K.V | return newdirfd;
|
552 | 5f542225 | Aneesh Kumar K.V | } |
553 | 5f542225 | Aneesh Kumar K.V | ret = renameat(olddirfd, old_name, newdirfd, new_name); |
554 | 5f542225 | Aneesh Kumar K.V | close(newdirfd); |
555 | 5f542225 | Aneesh Kumar K.V | close(olddirfd); |
556 | 5f542225 | Aneesh Kumar K.V | return ret;
|
557 | 5f542225 | Aneesh Kumar K.V | } |
558 | 5f542225 | Aneesh Kumar K.V | |
559 | 5f542225 | Aneesh Kumar K.V | static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, |
560 | 5f542225 | Aneesh Kumar K.V | const char *name, int flags) |
561 | 5f542225 | Aneesh Kumar K.V | { |
562 | 5f542225 | Aneesh Kumar K.V | int dirfd, ret;
|
563 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = (struct handle_data *)ctx->private; |
564 | 930b5883 | Paolo Bonzini | int rflags;
|
565 | 5f542225 | Aneesh Kumar K.V | |
566 | 5f542225 | Aneesh Kumar K.V | dirfd = open_by_handle(data->mountfd, dir->data, O_PATH); |
567 | 5f542225 | Aneesh Kumar K.V | if (dirfd < 0) { |
568 | 5f542225 | Aneesh Kumar K.V | return dirfd;
|
569 | 5f542225 | Aneesh Kumar K.V | } |
570 | 5f542225 | Aneesh Kumar K.V | |
571 | 930b5883 | Paolo Bonzini | rflags = 0;
|
572 | 930b5883 | Paolo Bonzini | if (flags & P9_DOTL_AT_REMOVEDIR) {
|
573 | 930b5883 | Paolo Bonzini | rflags |= AT_REMOVEDIR; |
574 | 930b5883 | Paolo Bonzini | } |
575 | 930b5883 | Paolo Bonzini | |
576 | 930b5883 | Paolo Bonzini | ret = unlinkat(dirfd, name, rflags); |
577 | 930b5883 | Paolo Bonzini | |
578 | 5f542225 | Aneesh Kumar K.V | close(dirfd); |
579 | 5f542225 | Aneesh Kumar K.V | return ret;
|
580 | 5f542225 | Aneesh Kumar K.V | } |
581 | 5f542225 | Aneesh Kumar K.V | |
582 | edb9eb73 | Harsh Prateek Bora | static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, |
583 | edb9eb73 | Harsh Prateek Bora | mode_t st_mode, uint64_t *st_gen) |
584 | edb9eb73 | Harsh Prateek Bora | { |
585 | cc720ddb | Aneesh Kumar K.V | int err;
|
586 | cc720ddb | Aneesh Kumar K.V | V9fsFidOpenState fid_open; |
587 | edb9eb73 | Harsh Prateek Bora | |
588 | edb9eb73 | Harsh Prateek Bora | /*
|
589 | edb9eb73 | Harsh Prateek Bora | * Do not try to open special files like device nodes, fifos etc
|
590 | edb9eb73 | Harsh Prateek Bora | * We can get fd for regular files and directories only
|
591 | edb9eb73 | Harsh Prateek Bora | */
|
592 | edb9eb73 | Harsh Prateek Bora | if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
|
593 | edb9eb73 | Harsh Prateek Bora | return 0; |
594 | edb9eb73 | Harsh Prateek Bora | } |
595 | cc720ddb | Aneesh Kumar K.V | err = handle_open(ctx, path, O_RDONLY, &fid_open); |
596 | cc720ddb | Aneesh Kumar K.V | if (err < 0) { |
597 | cc720ddb | Aneesh Kumar K.V | return err;
|
598 | edb9eb73 | Harsh Prateek Bora | } |
599 | cc720ddb | Aneesh Kumar K.V | err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); |
600 | cc720ddb | Aneesh Kumar K.V | handle_close(ctx, &fid_open); |
601 | edb9eb73 | Harsh Prateek Bora | return err;
|
602 | edb9eb73 | Harsh Prateek Bora | } |
603 | edb9eb73 | Harsh Prateek Bora | |
604 | 5f542225 | Aneesh Kumar K.V | static int handle_init(FsContext *ctx) |
605 | 5f542225 | Aneesh Kumar K.V | { |
606 | 5f542225 | Aneesh Kumar K.V | int ret, mnt_id;
|
607 | edb9eb73 | Harsh Prateek Bora | struct statfs stbuf;
|
608 | 5f542225 | Aneesh Kumar K.V | struct file_handle fh;
|
609 | 5f542225 | Aneesh Kumar K.V | struct handle_data *data = g_malloc(sizeof(struct handle_data)); |
610 | d2042378 | Aneesh Kumar K.V | |
611 | 5f542225 | Aneesh Kumar K.V | data->mountfd = open(ctx->fs_root, O_DIRECTORY); |
612 | 5f542225 | Aneesh Kumar K.V | if (data->mountfd < 0) { |
613 | 5f542225 | Aneesh Kumar K.V | ret = data->mountfd; |
614 | 5f542225 | Aneesh Kumar K.V | goto err_out;
|
615 | 5f542225 | Aneesh Kumar K.V | } |
616 | edb9eb73 | Harsh Prateek Bora | ret = statfs(ctx->fs_root, &stbuf); |
617 | edb9eb73 | Harsh Prateek Bora | if (!ret) {
|
618 | edb9eb73 | Harsh Prateek Bora | switch (stbuf.f_type) {
|
619 | edb9eb73 | Harsh Prateek Bora | case EXT2_SUPER_MAGIC:
|
620 | edb9eb73 | Harsh Prateek Bora | case BTRFS_SUPER_MAGIC:
|
621 | edb9eb73 | Harsh Prateek Bora | case REISERFS_SUPER_MAGIC:
|
622 | edb9eb73 | Harsh Prateek Bora | case XFS_SUPER_MAGIC:
|
623 | edb9eb73 | Harsh Prateek Bora | ctx->exops.get_st_gen = handle_ioc_getversion; |
624 | edb9eb73 | Harsh Prateek Bora | break;
|
625 | edb9eb73 | Harsh Prateek Bora | } |
626 | edb9eb73 | Harsh Prateek Bora | } |
627 | 5f542225 | Aneesh Kumar K.V | memset(&fh, 0, sizeof(struct file_handle)); |
628 | 5f542225 | Aneesh Kumar K.V | ret = name_to_handle(data->mountfd, ".", &fh, &mnt_id, 0); |
629 | 5f542225 | Aneesh Kumar K.V | if (ret && errno == EOVERFLOW) {
|
630 | 5f542225 | Aneesh Kumar K.V | data->handle_bytes = fh.handle_bytes; |
631 | 5f542225 | Aneesh Kumar K.V | ctx->private = data; |
632 | 5f542225 | Aneesh Kumar K.V | ret = 0;
|
633 | 5f542225 | Aneesh Kumar K.V | goto out;
|
634 | 5f542225 | Aneesh Kumar K.V | } |
635 | 5f542225 | Aneesh Kumar K.V | /* we got 0 byte handle ? */
|
636 | 5f542225 | Aneesh Kumar K.V | ret = -1;
|
637 | 5f542225 | Aneesh Kumar K.V | close(data->mountfd); |
638 | 5f542225 | Aneesh Kumar K.V | err_out:
|
639 | 5f542225 | Aneesh Kumar K.V | g_free(data); |
640 | 5f542225 | Aneesh Kumar K.V | out:
|
641 | 5f542225 | Aneesh Kumar K.V | return ret;
|
642 | 5f542225 | Aneesh Kumar K.V | } |
643 | 5f542225 | Aneesh Kumar K.V | |
644 | 99519f0a | Aneesh Kumar K.V | static int handle_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse) |
645 | 99519f0a | Aneesh Kumar K.V | { |
646 | 99519f0a | Aneesh Kumar K.V | const char *sec_model = qemu_opt_get(opts, "security_model"); |
647 | 99519f0a | Aneesh Kumar K.V | const char *path = qemu_opt_get(opts, "path"); |
648 | 99519f0a | Aneesh Kumar K.V | |
649 | 99519f0a | Aneesh Kumar K.V | if (sec_model) {
|
650 | 99519f0a | Aneesh Kumar K.V | fprintf(stderr, "Invalid argument security_model specified with handle fsdriver\n");
|
651 | 99519f0a | Aneesh Kumar K.V | return -1; |
652 | 99519f0a | Aneesh Kumar K.V | } |
653 | 99519f0a | Aneesh Kumar K.V | |
654 | 99519f0a | Aneesh Kumar K.V | if (!path) {
|
655 | 99519f0a | Aneesh Kumar K.V | fprintf(stderr, "fsdev: No path specified.\n");
|
656 | 99519f0a | Aneesh Kumar K.V | return -1; |
657 | 99519f0a | Aneesh Kumar K.V | } |
658 | 99519f0a | Aneesh Kumar K.V | fse->path = g_strdup(path); |
659 | 99519f0a | Aneesh Kumar K.V | return 0; |
660 | 99519f0a | Aneesh Kumar K.V | |
661 | 99519f0a | Aneesh Kumar K.V | } |
662 | 99519f0a | Aneesh Kumar K.V | |
663 | 5f542225 | Aneesh Kumar K.V | FileOperations handle_ops = { |
664 | 99519f0a | Aneesh Kumar K.V | .parse_opts = handle_parse_opts, |
665 | 5f542225 | Aneesh Kumar K.V | .init = handle_init, |
666 | 5f542225 | Aneesh Kumar K.V | .lstat = handle_lstat, |
667 | 5f542225 | Aneesh Kumar K.V | .readlink = handle_readlink, |
668 | 5f542225 | Aneesh Kumar K.V | .close = handle_close, |
669 | 5f542225 | Aneesh Kumar K.V | .closedir = handle_closedir, |
670 | 5f542225 | Aneesh Kumar K.V | .open = handle_open, |
671 | 5f542225 | Aneesh Kumar K.V | .opendir = handle_opendir, |
672 | 5f542225 | Aneesh Kumar K.V | .rewinddir = handle_rewinddir, |
673 | 5f542225 | Aneesh Kumar K.V | .telldir = handle_telldir, |
674 | 5f542225 | Aneesh Kumar K.V | .readdir_r = handle_readdir_r, |
675 | 5f542225 | Aneesh Kumar K.V | .seekdir = handle_seekdir, |
676 | 5f542225 | Aneesh Kumar K.V | .preadv = handle_preadv, |
677 | 5f542225 | Aneesh Kumar K.V | .pwritev = handle_pwritev, |
678 | 5f542225 | Aneesh Kumar K.V | .chmod = handle_chmod, |
679 | 5f542225 | Aneesh Kumar K.V | .mknod = handle_mknod, |
680 | 5f542225 | Aneesh Kumar K.V | .mkdir = handle_mkdir, |
681 | 5f542225 | Aneesh Kumar K.V | .fstat = handle_fstat, |
682 | 5f542225 | Aneesh Kumar K.V | .open2 = handle_open2, |
683 | 5f542225 | Aneesh Kumar K.V | .symlink = handle_symlink, |
684 | 5f542225 | Aneesh Kumar K.V | .link = handle_link, |
685 | 5f542225 | Aneesh Kumar K.V | .truncate = handle_truncate, |
686 | 5f542225 | Aneesh Kumar K.V | .rename = handle_rename, |
687 | 5f542225 | Aneesh Kumar K.V | .chown = handle_chown, |
688 | 5f542225 | Aneesh Kumar K.V | .utimensat = handle_utimensat, |
689 | 5f542225 | Aneesh Kumar K.V | .remove = handle_remove, |
690 | 5f542225 | Aneesh Kumar K.V | .fsync = handle_fsync, |
691 | 5f542225 | Aneesh Kumar K.V | .statfs = handle_statfs, |
692 | 5f542225 | Aneesh Kumar K.V | .lgetxattr = handle_lgetxattr, |
693 | 5f542225 | Aneesh Kumar K.V | .llistxattr = handle_llistxattr, |
694 | 5f542225 | Aneesh Kumar K.V | .lsetxattr = handle_lsetxattr, |
695 | 5f542225 | Aneesh Kumar K.V | .lremovexattr = handle_lremovexattr, |
696 | 5f542225 | Aneesh Kumar K.V | .name_to_path = handle_name_to_path, |
697 | 5f542225 | Aneesh Kumar K.V | .renameat = handle_renameat, |
698 | 5f542225 | Aneesh Kumar K.V | .unlinkat = handle_unlinkat, |
699 | 5f542225 | Aneesh Kumar K.V | }; |