^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1) /*
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 2) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) * Licensed under the GPL
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) #include <stdio.h>
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 7) #include <stddef.h>
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 8) #include <unistd.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) #include <dirent.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) #include <errno.h>
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 11) #include <fcntl.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) #include <string.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13) #include <sys/stat.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) #include <sys/time.h>
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 15) #include <sys/types.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) #include <sys/vfs.h>
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 17) #include <sys/syscall.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) #include "hostfs.h"
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 19) #include <utime.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20)
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 21) static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p)
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 22) {
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 23) p->ino = buf->st_ino;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 24) p->mode = buf->st_mode;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 25) p->nlink = buf->st_nlink;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 26) p->uid = buf->st_uid;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 27) p->gid = buf->st_gid;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 28) p->size = buf->st_size;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 29) p->atime.tv_sec = buf->st_atime;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 30) p->atime.tv_nsec = 0;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 31) p->ctime.tv_sec = buf->st_ctime;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 32) p->ctime.tv_nsec = 0;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 33) p->mtime.tv_sec = buf->st_mtime;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 34) p->mtime.tv_nsec = 0;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 35) p->blksize = buf->st_blksize;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 36) p->blocks = buf->st_blocks;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 37) p->maj = os_major(buf->st_rdev);
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 38) p->min = os_minor(buf->st_rdev);
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 39) }
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 40)
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 41) int stat_file(const char *path, struct hostfs_stat *p, int fd)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) struct stat64 buf;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 45) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 46) if (fstat64(fd, &buf) < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 47) return -errno;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 48) } else if (lstat64(path, &buf) < 0) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 49) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 50) }
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 51) stat64_to_hostfs(&buf, p);
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 52) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 54)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) int access_file(char *path, int r, int w, int x)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 56) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 57) int mode = 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 59) if (r)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 60) mode = R_OK;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 61) if (w)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 62) mode |= W_OK;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 63) if (x)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 64) mode |= X_OK;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 65) if (access(path, mode) != 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 66) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 67) else return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 68) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) int open_file(char *path, int r, int w, int append)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) int mode = 0, fd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 74) if (r && !w)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) mode = O_RDONLY;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 76) else if (!r && w)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) mode = O_WRONLY;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 78) else if (r && w)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) mode = O_RDWR;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) else panic("Impossible mode in open_file");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 82) if (append)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 83) mode |= O_APPEND;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84) fd = open64(path, mode);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 85) if (fd < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 86) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 87) else return fd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 90) void *open_dir(char *path, int *err_out)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) DIR *dir;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) dir = opendir(path);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) *err_out = errno;
c5c6dd4e2dce3 (Richard Weinberger 2010-10-26 14:22:20 -0700 96)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 97) return dir;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 98) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 99)
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 100) void seek_dir(void *stream, unsigned long long pos)
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 101) {
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 102) DIR *dir = stream;
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 103)
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 104) seekdir(dir, pos);
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 105) }
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 106)
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 107) char *read_dir(void *stream, unsigned long long *pos_out,
3ee6bd8e8dc0c (Geert Uytterhoeven 2012-01-27 19:14:58 +0100 108) unsigned long long *ino_out, int *len_out,
3ee6bd8e8dc0c (Geert Uytterhoeven 2012-01-27 19:14:58 +0100 109) unsigned int *type_out)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111) DIR *dir = stream;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 112) struct dirent *ent;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 113)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 114) ent = readdir(dir);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 115) if (ent == NULL)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 116) return NULL;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 117) *len_out = strlen(ent->d_name);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 118) *ino_out = ent->d_ino;
3ee6bd8e8dc0c (Geert Uytterhoeven 2012-01-27 19:14:58 +0100 119) *type_out = ent->d_type;
0c9bd6365d0b2 (Richard Weinberger 2015-03-24 15:47:38 +0100 120) *pos_out = ent->d_off;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 121) return ent->d_name;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 122) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 123)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 124) int read_file(int fd, unsigned long long *offset, char *buf, int len)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 125) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 126) int n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 127)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 128) n = pread64(fd, buf, len, *offset);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 129) if (n < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 130) return -errno;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131) *offset += n;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 132) return n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 134)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 135) int write_file(int fd, unsigned long long *offset, const char *buf, int len)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 136) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 137) int n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 138)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 139) n = pwrite64(fd, buf, len, *offset);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 140) if (n < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 141) return -errno;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 142) *offset += n;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 143) return n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 144) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 145)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 146) int lseek_file(int fd, long long offset, int whence)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 147) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 148) int ret;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 149)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 150) ret = lseek64(fd, offset, whence);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 151) if (ret < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 152) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 153) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 154) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 155)
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 156) int fsync_file(int fd, int datasync)
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 157) {
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 158) int ret;
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 159) if (datasync)
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 160) ret = fdatasync(fd);
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 161) else
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 162) ret = fsync(fd);
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 163)
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 164) if (ret < 0)
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 165) return -errno;
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 166) return 0;
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 167) }
a2d76bd8fa29f (Paolo 'Blaisorblade' Giarrusso 2005-07-28 21:16:15 -0700 168)
f8ad850f11e11 (Al Viro 2010-06-06 23:49:18 -0400 169) int replace_file(int oldfd, int fd)
f8ad850f11e11 (Al Viro 2010-06-06 23:49:18 -0400 170) {
f8ad850f11e11 (Al Viro 2010-06-06 23:49:18 -0400 171) return dup2(oldfd, fd);
f8ad850f11e11 (Al Viro 2010-06-06 23:49:18 -0400 172) }
f8ad850f11e11 (Al Viro 2010-06-06 23:49:18 -0400 173)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 174) void close_file(void *stream)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 175) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 176) close(*((int *) stream));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 177) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 178)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 179) void close_dir(void *stream)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 181) closedir(stream);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 183)
b98b91029cf8a (Richard Weinberger 2015-03-04 23:44:54 +0100 184) int file_create(char *name, int mode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 185) {
b98b91029cf8a (Richard Weinberger 2015-03-04 23:44:54 +0100 186) int fd;
b98b91029cf8a (Richard Weinberger 2015-03-04 23:44:54 +0100 187)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 188) fd = open64(name, O_CREAT | O_RDWR, mode);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 189) if (fd < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 190) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 191) return fd;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 192) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 193)
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 194) int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 195) {
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 196) struct hostfs_stat st;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 197) struct timeval times[2];
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 198) int err, ma;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 199)
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 200) if (attrs->ia_valid & HOSTFS_ATTR_MODE) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 201) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 202) if (fchmod(fd, attrs->ia_mode) != 0)
c5c6dd4e2dce3 (Richard Weinberger 2010-10-26 14:22:20 -0700 203) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 204) } else if (chmod(file, attrs->ia_mode) != 0) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 205) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 206) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 207) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 208) if (attrs->ia_valid & HOSTFS_ATTR_UID) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 209) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 210) if (fchown(fd, attrs->ia_uid, -1))
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 211) return -errno;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 212) } else if (chown(file, attrs->ia_uid, -1)) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 213) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 214) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 215) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 216) if (attrs->ia_valid & HOSTFS_ATTR_GID) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 217) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 218) if (fchown(fd, -1, attrs->ia_gid))
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 219) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 220) } else if (chown(file, -1, attrs->ia_gid)) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 221) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 222) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 223) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 224) if (attrs->ia_valid & HOSTFS_ATTR_SIZE) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 225) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 226) if (ftruncate(fd, attrs->ia_size))
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 227) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 228) } else if (truncate(file, attrs->ia_size)) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 229) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 230) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 231) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 232)
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 233) /*
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 234) * Update accessed and/or modified time, in two parts: first set
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 235) * times according to the changes to perform, and then call futimes()
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 236) * or utimes() to apply them.
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 237) */
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 238) ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 239) if (attrs->ia_valid & ma) {
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 240) err = stat_file(file, &st, fd);
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 241) if (err != 0)
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 242) return err;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 243)
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 244) times[0].tv_sec = st.atime.tv_sec;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 245) times[0].tv_usec = st.atime.tv_nsec / 1000;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 246) times[1].tv_sec = st.mtime.tv_sec;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 247) times[1].tv_usec = st.mtime.tv_nsec / 1000;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 248)
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 249) if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 250) times[0].tv_sec = attrs->ia_atime.tv_sec;
d7b88513c504e (Dominique Quatravaux 2008-02-04 22:31:15 -0800 251) times[0].tv_usec = attrs->ia_atime.tv_nsec / 1000;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 252) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 253) if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 254) times[1].tv_sec = attrs->ia_mtime.tv_sec;
d7b88513c504e (Dominique Quatravaux 2008-02-04 22:31:15 -0800 255) times[1].tv_usec = attrs->ia_mtime.tv_nsec / 1000;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 256) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 257)
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 258) if (fd >= 0) {
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 259) if (futimes(fd, times) != 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 260) return -errno;
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 261) } else if (utimes(file, times) != 0) {
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 262) return -errno;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 264) }
5822b7faca709 (Alberto Bertogli 2007-05-08 00:23:16 -0700 265)
baabd156e243e (Jeff Dike 2007-10-16 01:27:13 -0700 266) /* Note: ctime is not handled */
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 267) if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) {
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 268) err = stat_file(file, &st, fd);
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 269) attrs->ia_atime = st.atime;
39b743c6199a3 (Al Viro 2010-06-06 20:08:56 -0400 270) attrs->ia_mtime = st.mtime;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 271) if (err != 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 272) return err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 273) }
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 274) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 275) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 276)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 277) int make_symlink(const char *from, const char *to)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 278) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 279) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 280)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 281) err = symlink(to, from);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 282) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 283) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 284) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 285) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 286)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 287) int unlink_file(const char *file)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 288) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 289) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 290)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 291) err = unlink(file);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 292) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 293) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 294) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 295) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 296)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 297) int do_mkdir(const char *file, int mode)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 298) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 299) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 300)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 301) err = mkdir(file, mode);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 302) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 303) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 304) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 305) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 306)
6380161ce9d08 (Dominik Brodowski 2018-03-11 11:34:48 +0100 307) int hostfs_do_rmdir(const char *file)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 308) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 309) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 310)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 311) err = rmdir(file);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 312) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 313) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 314) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 315) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 316)
88f6cd0c3bb5d (Johannes Stezenbach 2007-01-29 13:19:44 -0800 317) int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 318) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 319) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 320)
005a59ec745d2 (Al Viro 2009-04-21 01:27:08 -0400 321) err = mknod(file, mode, os_makedev(major, minor));
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 322) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 323) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 324) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 325) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 326)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 327) int link_file(const char *to, const char *from)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 328) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 329) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 330)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 331) err = link(to, from);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 332) if (err)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 333) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 334) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 335) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 336)
ea7e743e49b94 (WANG Cong 2008-11-19 15:36:46 -0800 337) int hostfs_do_readlink(char *file, char *buf, int size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 338) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 339) int n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 340)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 341) n = readlink(file, buf, size);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 342) if (n < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 343) return -errno;
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 344) if (n < size)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 345) buf[n] = '\0';
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 346) return n;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 347) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 348)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 349) int rename_file(char *from, char *to)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 350) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 351) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 352)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 353) err = rename(from, to);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 354) if (err < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 355) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 356) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 357) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 358)
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 359) int rename2_file(char *from, char *to, unsigned int flags)
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 360) {
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 361) int err;
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 362)
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 363) #ifndef SYS_renameat2
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 364) # ifdef __x86_64__
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 365) # define SYS_renameat2 316
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 366) # endif
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 367) # ifdef __i386__
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 368) # define SYS_renameat2 353
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 369) # endif
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 370) #endif
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 371)
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 372) #ifdef SYS_renameat2
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 373) err = syscall(SYS_renameat2, AT_FDCWD, from, AT_FDCWD, to, flags);
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 374) if (err < 0) {
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 375) if (errno != ENOSYS)
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 376) return -errno;
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 377) else
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 378) return -EINVAL;
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 379) }
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 380) return 0;
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 381) #else
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 382) return -EINVAL;
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 383) #endif
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 384) }
9a423bb6e3577 (Miklos Szeredi 2014-07-23 15:15:35 +0200 385)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 386) int do_statfs(char *root, long *bsize_out, long long *blocks_out,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 387) long long *bfree_out, long long *bavail_out,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 388) long long *files_out, long long *ffree_out,
1b627d5771312 (Richard Weinberger 2010-10-26 14:21:18 -0700 389) void *fsid_out, int fsid_size, long *namelen_out)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 390) {
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 391) struct statfs64 buf;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 392) int err;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 393)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 394) err = statfs64(root, &buf);
84b3db04ca15a (Jeff Dike 2007-10-16 01:27:13 -0700 395) if (err < 0)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 396) return -errno;
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 397)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 398) *bsize_out = buf.f_bsize;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 399) *blocks_out = buf.f_blocks;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 400) *bfree_out = buf.f_bfree;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 401) *bavail_out = buf.f_bavail;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 402) *files_out = buf.f_files;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 403) *ffree_out = buf.f_ffree;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 404) memcpy(fsid_out, &buf.f_fsid,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 405) sizeof(buf.f_fsid) > fsid_size ? fsid_size :
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 406) sizeof(buf.f_fsid));
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 407) *namelen_out = buf.f_namelen;
1b627d5771312 (Richard Weinberger 2010-10-26 14:21:18 -0700 408)
f1adc05e77383 (Jeff Dike 2007-05-08 00:23:18 -0700 409) return 0;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 410) }