~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/hostfs/hostfs_user.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  3  * Licensed under the GPL
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stddef.h>
  8 #include <unistd.h>
  9 #include <dirent.h>
 10 #include <errno.h>
 11 #include <fcntl.h>
 12 #include <string.h>
 13 #include <sys/stat.h>
 14 #include <sys/time.h>
 15 #include <sys/types.h>
 16 #include <sys/vfs.h>
 17 #include "hostfs.h"
 18 #include "os.h"
 19 #include "user.h"
 20 #include <utime.h>
 21 
 22 int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
 23               int *nlink_out, int *uid_out, int *gid_out,
 24               unsigned long long *size_out, struct timespec *atime_out,
 25               struct timespec *mtime_out, struct timespec *ctime_out,
 26               int *blksize_out, unsigned long long *blocks_out, int fd)
 27 {
 28         struct stat64 buf;
 29 
 30         if (fd >= 0) {
 31                 if (fstat64(fd, &buf) < 0)
 32                         return -errno;
 33         } else if (lstat64(path, &buf) < 0) {
 34                 return -errno;
 35         }
 36 
 37         if (inode_out != NULL)
 38                 *inode_out = buf.st_ino;
 39         if (mode_out != NULL)
 40                 *mode_out = buf.st_mode;
 41         if (nlink_out != NULL)
 42                 *nlink_out = buf.st_nlink;
 43         if (uid_out != NULL)
 44                 *uid_out = buf.st_uid;
 45         if (gid_out != NULL)
 46                 *gid_out = buf.st_gid;
 47         if (size_out != NULL)
 48                 *size_out = buf.st_size;
 49         if (atime_out != NULL) {
 50                 atime_out->tv_sec = buf.st_atime;
 51                 atime_out->tv_nsec = 0;
 52         }
 53         if (mtime_out != NULL) {
 54                 mtime_out->tv_sec = buf.st_mtime;
 55                 mtime_out->tv_nsec = 0;
 56         }
 57         if (ctime_out != NULL) {
 58                 ctime_out->tv_sec = buf.st_ctime;
 59                 ctime_out->tv_nsec = 0;
 60         }
 61         if (blksize_out != NULL)
 62                 *blksize_out = buf.st_blksize;
 63         if (blocks_out != NULL)
 64                 *blocks_out = buf.st_blocks;
 65         return 0;
 66 }
 67 
 68 int file_type(const char *path, int *maj, int *min)
 69 {
 70         struct stat64 buf;
 71 
 72         if (lstat64(path, &buf) < 0)
 73                 return -errno;
 74         /*
 75          * We cannot pass rdev as is because glibc and the kernel disagree
 76          * about its definition.
 77          */
 78         if (maj != NULL)
 79                 *maj = major(buf.st_rdev);
 80         if (min != NULL)
 81                 *min = minor(buf.st_rdev);
 82 
 83         if (S_ISDIR(buf.st_mode))
 84                 return OS_TYPE_DIR;
 85         else if (S_ISLNK(buf.st_mode))
 86                 return OS_TYPE_SYMLINK;
 87         else if (S_ISCHR(buf.st_mode))
 88                 return OS_TYPE_CHARDEV;
 89         else if (S_ISBLK(buf.st_mode))
 90                 return OS_TYPE_BLOCKDEV;
 91         else if (S_ISFIFO(buf.st_mode))
 92                 return OS_TYPE_FIFO;
 93         else if (S_ISSOCK(buf.st_mode))
 94                 return OS_TYPE_SOCK;
 95         else return OS_TYPE_FILE;
 96 }
 97 
 98 int access_file(char *path, int r, int w, int x)
 99 {
100         int mode = 0;
101 
102         if (r)
103                 mode = R_OK;
104         if (w)
105                 mode |= W_OK;
106         if (x)
107                 mode |= X_OK;
108         if (access(path, mode) != 0)
109                 return -errno;
110         else return 0;
111 }
112 
113 int open_file(char *path, int r, int w, int append)
114 {
115         int mode = 0, fd;
116 
117         if (r && !w)
118                 mode = O_RDONLY;
119         else if (!r && w)
120                 mode = O_WRONLY;
121         else if (r && w)
122                 mode = O_RDWR;
123         else panic("Impossible mode in open_file");
124 
125         if (append)
126                 mode |= O_APPEND;
127         fd = open64(path, mode);
128         if (fd < 0)
129                 return -errno;
130         else return fd;
131 }
132 
133 void *open_dir(char *path, int *err_out)
134 {
135         DIR *dir;
136 
137         dir = opendir(path);
138         *err_out = errno;
139         if (dir == NULL)
140                 return NULL;
141         return dir;
142 }
143 
144 char *read_dir(void *stream, unsigned long long *pos,
145                unsigned long long *ino_out, int *len_out)
146 {
147         DIR *dir = stream;
148         struct dirent *ent;
149 
150         seekdir(dir, *pos);
151         ent = readdir(dir);
152         if (ent == NULL)
153                 return NULL;
154         *len_out = strlen(ent->d_name);
155         *ino_out = ent->d_ino;
156         *pos = telldir(dir);
157         return ent->d_name;
158 }
159 
160 int read_file(int fd, unsigned long long *offset, char *buf, int len)
161 {
162         int n;
163 
164         n = pread64(fd, buf, len, *offset);
165         if (n < 0)
166                 return -errno;
167         *offset += n;
168         return n;
169 }
170 
171 int write_file(int fd, unsigned long long *offset, const char *buf, int len)
172 {
173         int n;
174 
175         n = pwrite64(fd, buf, len, *offset);
176         if (n < 0)
177                 return -errno;
178         *offset += n;
179         return n;
180 }
181 
182 int lseek_file(int fd, long long offset, int whence)
183 {
184         int ret;
185 
186         ret = lseek64(fd, offset, whence);
187         if (ret < 0)
188                 return -errno;
189         return 0;
190 }
191 
192 int fsync_file(int fd, int datasync)
193 {
194         int ret;
195         if (datasync)
196                 ret = fdatasync(fd);
197         else
198                 ret = fsync(fd);
199 
200         if (ret < 0)
201                 return -errno;
202         return 0;
203 }
204 
205 void close_file(void *stream)
206 {
207         close(*((int *) stream));
208 }
209 
210 void close_dir(void *stream)
211 {
212         closedir(stream);
213 }
214 
215 int file_create(char *name, int ur, int uw, int ux, int gr,
216                 int gw, int gx, int or, int ow, int ox)
217 {
218         int mode, fd;
219 
220         mode = 0;
221         mode |= ur ? S_IRUSR : 0;
222         mode |= uw ? S_IWUSR : 0;
223         mode |= ux ? S_IXUSR : 0;
224         mode |= gr ? S_IRGRP : 0;
225         mode |= gw ? S_IWGRP : 0;
226         mode |= gx ? S_IXGRP : 0;
227         mode |= or ? S_IROTH : 0;
228         mode |= ow ? S_IWOTH : 0;
229         mode |= ox ? S_IXOTH : 0;
230         fd = open64(name, O_CREAT | O_RDWR, mode);
231         if (fd < 0)
232                 return -errno;
233         return fd;
234 }
235 
236 int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
237 {
238         struct timeval times[2];
239         struct timespec atime_ts, mtime_ts;
240         int err, ma;
241 
242         if (attrs->ia_valid & HOSTFS_ATTR_MODE) {
243                 if (fd >= 0) {
244                         if (fchmod(fd, attrs->ia_mode) != 0)
245                                 return (-errno);
246                 } else if (chmod(file, attrs->ia_mode) != 0) {
247                         return -errno;
248                 }
249         }
250         if (attrs->ia_valid & HOSTFS_ATTR_UID) {
251                 if (fd >= 0) {
252                         if (fchown(fd, attrs->ia_uid, -1))
253                                 return -errno;
254                 } else if (chown(file, attrs->ia_uid, -1)) {
255                         return -errno;
256                 }
257         }
258         if (attrs->ia_valid & HOSTFS_ATTR_GID) {
259                 if (fd >= 0) {
260                         if (fchown(fd, -1, attrs->ia_gid))
261                                 return -errno;
262                 } else if (chown(file, -1, attrs->ia_gid)) {
263                         return -errno;
264                 }
265         }
266         if (attrs->ia_valid & HOSTFS_ATTR_SIZE) {
267                 if (fd >= 0) {
268                         if (ftruncate(fd, attrs->ia_size))
269                                 return -errno;
270                 } else if (truncate(file, attrs->ia_size)) {
271                         return -errno;
272                 }
273         }
274 
275         /*
276          * Update accessed and/or modified time, in two parts: first set
277          * times according to the changes to perform, and then call futimes()
278          * or utimes() to apply them.
279          */
280         ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
281         if (attrs->ia_valid & ma) {
282                 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
283                                 &atime_ts, &mtime_ts, NULL, NULL, NULL, fd);
284                 if (err != 0)
285                         return err;
286 
287                 times[0].tv_sec = atime_ts.tv_sec;
288                 times[0].tv_usec = atime_ts.tv_nsec / 1000;
289                 times[1].tv_sec = mtime_ts.tv_sec;
290                 times[1].tv_usec = mtime_ts.tv_nsec / 1000;
291 
292                 if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) {
293                         times[0].tv_sec = attrs->ia_atime.tv_sec;
294                         times[0].tv_usec = attrs->ia_atime.tv_nsec / 1000;
295                 }
296                 if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) {
297                         times[1].tv_sec = attrs->ia_mtime.tv_sec;
298                         times[1].tv_usec = attrs->ia_mtime.tv_nsec / 1000;
299                 }
300 
301                 if (fd >= 0) {
302                         if (futimes(fd, times) != 0)
303                                 return -errno;
304                 } else if (utimes(file, times) != 0) {
305                         return -errno;
306                 }
307         }
308 
309         /* Note: ctime is not handled */
310         if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) {
311                 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
312                                 &attrs->ia_atime, &attrs->ia_mtime, NULL,
313                                 NULL, NULL, fd);
314                 if (err != 0)
315                         return err;
316         }
317         return 0;
318 }
319 
320 int make_symlink(const char *from, const char *to)
321 {
322         int err;
323 
324         err = symlink(to, from);
325         if (err)
326                 return -errno;
327         return 0;
328 }
329 
330 int unlink_file(const char *file)
331 {
332         int err;
333 
334         err = unlink(file);
335         if (err)
336                 return -errno;
337         return 0;
338 }
339 
340 int do_mkdir(const char *file, int mode)
341 {
342         int err;
343 
344         err = mkdir(file, mode);
345         if (err)
346                 return -errno;
347         return 0;
348 }
349 
350 int do_rmdir(const char *file)
351 {
352         int err;
353 
354         err = rmdir(file);
355         if (err)
356                 return -errno;
357         return 0;
358 }
359 
360 int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
361 {
362         int err;
363 
364         err = mknod(file, mode, makedev(major, minor));
365         if (err)
366                 return -errno;
367         return 0;
368 }
369 
370 int link_file(const char *to, const char *from)
371 {
372         int err;
373 
374         err = link(to, from);
375         if (err)
376                 return -errno;
377         return 0;
378 }
379 
380 int hostfs_do_readlink(char *file, char *buf, int size)
381 {
382         int n;
383 
384         n = readlink(file, buf, size);
385         if (n < 0)
386                 return -errno;
387         if (n < size)
388                 buf[n] = '\0';
389         return n;
390 }
391 
392 int rename_file(char *from, char *to)
393 {
394         int err;
395 
396         err = rename(from, to);
397         if (err < 0)
398                 return -errno;
399         return 0;
400 }
401 
402 int do_statfs(char *root, long *bsize_out, long long *blocks_out,
403               long long *bfree_out, long long *bavail_out,
404               long long *files_out, long long *ffree_out,
405               void *fsid_out, int fsid_size, long *namelen_out,
406               long *spare_out)
407 {
408         struct statfs64 buf;
409         int err;
410 
411         err = statfs64(root, &buf);
412         if (err < 0)
413                 return -errno;
414 
415         *bsize_out = buf.f_bsize;
416         *blocks_out = buf.f_blocks;
417         *bfree_out = buf.f_bfree;
418         *bavail_out = buf.f_bavail;
419         *files_out = buf.f_files;
420         *ffree_out = buf.f_ffree;
421         memcpy(fsid_out, &buf.f_fsid,
422                sizeof(buf.f_fsid) > fsid_size ? fsid_size :
423                sizeof(buf.f_fsid));
424         *namelen_out = buf.f_namelen;
425         spare_out[0] = buf.f_spare[0];
426         spare_out[1] = buf.f_spare[1];
427         spare_out[2] = buf.f_spare[2];
428         spare_out[3] = buf.f_spare[3];
429         spare_out[4] = buf.f_spare[4];
430         return 0;
431 }
432 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp