diff options
Diffstat (limited to 'fs/hostfs/hostfs_user.c')
| -rw-r--r-- | fs/hostfs/hostfs_user.c | 201 |
1 files changed, 90 insertions, 111 deletions
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index 5625e2481dd..67838f3aa20 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c @@ -3,88 +3,65 @@ * Licensed under the GPL */ -#include <unistd.h> #include <stdio.h> -#include <fcntl.h> +#include <stddef.h> +#include <unistd.h> #include <dirent.h> #include <errno.h> -#include <utime.h> +#include <fcntl.h> #include <string.h> #include <sys/stat.h> #include <sys/time.h> +#include <sys/types.h> #include <sys/vfs.h> #include "hostfs.h" -#include "kern_util.h" -#include "user.h" - -int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, - int *nlink_out, int *uid_out, int *gid_out, - unsigned long long *size_out, struct timespec *atime_out, - struct timespec *mtime_out, struct timespec *ctime_out, - int *blksize_out, unsigned long long *blocks_out, int fd) +#include <utime.h> + +static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p) +{ + p->ino = buf->st_ino; + p->mode = buf->st_mode; + p->nlink = buf->st_nlink; + p->uid = buf->st_uid; + p->gid = buf->st_gid; + p->size = buf->st_size; + p->atime.tv_sec = buf->st_atime; + p->atime.tv_nsec = 0; + p->ctime.tv_sec = buf->st_ctime; + p->ctime.tv_nsec = 0; + p->mtime.tv_sec = buf->st_mtime; + p->mtime.tv_nsec = 0; + p->blksize = buf->st_blksize; + p->blocks = buf->st_blocks; + p->maj = os_major(buf->st_rdev); + p->min = os_minor(buf->st_rdev); +} + +int stat_file(const char *path, struct hostfs_stat *p, int fd) { struct stat64 buf; - if(fd >= 0) { + if (fd >= 0) { if (fstat64(fd, &buf) < 0) return -errno; - } else if(lstat64(path, &buf) < 0) { + } else if (lstat64(path, &buf) < 0) { return -errno; } - - if(inode_out != NULL) *inode_out = buf.st_ino; - if(mode_out != NULL) *mode_out = buf.st_mode; - if(nlink_out != NULL) *nlink_out = buf.st_nlink; - if(uid_out != NULL) *uid_out = buf.st_uid; - if(gid_out != NULL) *gid_out = buf.st_gid; - if(size_out != NULL) *size_out = buf.st_size; - if(atime_out != NULL) { - atime_out->tv_sec = buf.st_atime; - atime_out->tv_nsec = 0; - } - if(mtime_out != NULL) { - mtime_out->tv_sec = buf.st_mtime; - mtime_out->tv_nsec = 0; - } - if(ctime_out != NULL) { - ctime_out->tv_sec = buf.st_ctime; - ctime_out->tv_nsec = 0; - } - if(blksize_out != NULL) *blksize_out = buf.st_blksize; - if(blocks_out != NULL) *blocks_out = buf.st_blocks; + stat64_to_hostfs(&buf, p); return 0; } -int file_type(const char *path, int *maj, int *min) -{ - struct stat64 buf; - - if(lstat64(path, &buf) < 0) - return -errno; - /*We cannot pass rdev as is because glibc and the kernel disagree - *about its definition.*/ - if(maj != NULL) - *maj = major(buf.st_rdev); - if(min != NULL) - *min = minor(buf.st_rdev); - - if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR; - else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK; - else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV; - else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV; - else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO; - else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK; - else return OS_TYPE_FILE; -} - int access_file(char *path, int r, int w, int x) { int mode = 0; - if(r) mode = R_OK; - if(w) mode |= W_OK; - if(x) mode |= X_OK; - if(access(path, mode) != 0) + if (r) + mode = R_OK; + if (w) + mode |= W_OK; + if (x) + mode |= X_OK; + if (access(path, mode) != 0) return -errno; else return 0; } @@ -93,18 +70,18 @@ int open_file(char *path, int r, int w, int append) { int mode = 0, fd; - if(r && !w) + if (r && !w) mode = O_RDONLY; - else if(!r && w) + else if (!r && w) mode = O_WRONLY; - else if(r && w) + else if (r && w) mode = O_RDWR; else panic("Impossible mode in open_file"); - if(append) + if (append) mode |= O_APPEND; fd = open64(path, mode); - if(fd < 0) + if (fd < 0) return -errno; else return fd; } @@ -115,23 +92,24 @@ void *open_dir(char *path, int *err_out) dir = opendir(path); *err_out = errno; - if(dir == NULL) - return NULL; + return dir; } char *read_dir(void *stream, unsigned long long *pos, - unsigned long long *ino_out, int *len_out) + unsigned long long *ino_out, int *len_out, + unsigned int *type_out) { DIR *dir = stream; struct dirent *ent; seekdir(dir, *pos); ent = readdir(dir); - if(ent == NULL) + if (ent == NULL) return NULL; *len_out = strlen(ent->d_name); *ino_out = ent->d_ino; + *type_out = ent->d_type; *pos = telldir(dir); return ent->d_name; } @@ -141,7 +119,7 @@ int read_file(int fd, unsigned long long *offset, char *buf, int len) int n; n = pread64(fd, buf, len, *offset); - if(n < 0) + if (n < 0) return -errno; *offset += n; return n; @@ -152,7 +130,7 @@ int write_file(int fd, unsigned long long *offset, const char *buf, int len) int n; n = pwrite64(fd, buf, len, *offset); - if(n < 0) + if (n < 0) return -errno; *offset += n; return n; @@ -163,7 +141,7 @@ int lseek_file(int fd, long long offset, int whence) int ret; ret = lseek64(fd, offset, whence); - if(ret < 0) + if (ret < 0) return -errno; return 0; } @@ -181,6 +159,11 @@ int fsync_file(int fd, int datasync) return 0; } +int replace_file(int oldfd, int fd) +{ + return dup2(oldfd, fd); +} + void close_file(void *stream) { close(*((int *) stream)); @@ -207,21 +190,21 @@ int file_create(char *name, int ur, int uw, int ux, int gr, mode |= ow ? S_IWOTH : 0; mode |= ox ? S_IXOTH : 0; fd = open64(name, O_CREAT | O_RDWR, mode); - if(fd < 0) + if (fd < 0) return -errno; return fd; } int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) { + struct hostfs_stat st; struct timeval times[2]; - struct timespec atime_ts, mtime_ts; int err, ma; if (attrs->ia_valid & HOSTFS_ATTR_MODE) { if (fd >= 0) { if (fchmod(fd, attrs->ia_mode) != 0) - return (-errno); + return -errno; } else if (chmod(file, attrs->ia_mode) != 0) { return -errno; } @@ -230,7 +213,7 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) if (fd >= 0) { if (fchown(fd, attrs->ia_uid, -1)) return -errno; - } else if(chown(file, attrs->ia_uid, -1)) { + } else if (chown(file, attrs->ia_uid, -1)) { return -errno; } } @@ -251,28 +234,29 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) } } - /* Update accessed and/or modified time, in two parts: first set + /* + * Update accessed and/or modified time, in two parts: first set * times according to the changes to perform, and then call futimes() - * or utimes() to apply them. */ + * or utimes() to apply them. + */ ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); if (attrs->ia_valid & ma) { - err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, - &atime_ts, &mtime_ts, NULL, NULL, NULL, fd); + err = stat_file(file, &st, fd); if (err != 0) return err; - times[0].tv_sec = atime_ts.tv_sec; - times[0].tv_usec = atime_ts.tv_nsec * 1000; - times[1].tv_sec = mtime_ts.tv_sec; - times[1].tv_usec = mtime_ts.tv_nsec * 1000; + times[0].tv_sec = st.atime.tv_sec; + times[0].tv_usec = st.atime.tv_nsec / 1000; + times[1].tv_sec = st.mtime.tv_sec; + times[1].tv_usec = st.mtime.tv_nsec / 1000; if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) { times[0].tv_sec = attrs->ia_atime.tv_sec; - times[0].tv_usec = attrs->ia_atime.tv_nsec * 1000; + times[0].tv_usec = attrs->ia_atime.tv_nsec / 1000; } if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) { times[1].tv_sec = attrs->ia_mtime.tv_sec; - times[1].tv_usec = attrs->ia_mtime.tv_nsec * 1000; + times[1].tv_usec = attrs->ia_mtime.tv_nsec / 1000; } if (fd >= 0) { @@ -283,12 +267,12 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) } } - if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; - if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ - err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, - &attrs->ia_atime, &attrs->ia_mtime, NULL, - NULL, NULL, fd); - if(err != 0) + /* Note: ctime is not handled */ + if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) { + err = stat_file(file, &st, fd); + attrs->ia_atime = st.atime; + attrs->ia_mtime = st.mtime; + if (err != 0) return err; } return 0; @@ -299,7 +283,7 @@ int make_symlink(const char *from, const char *to) int err; err = symlink(to, from); - if(err) + if (err) return -errno; return 0; } @@ -309,7 +293,7 @@ int unlink_file(const char *file) int err; err = unlink(file); - if(err) + if (err) return -errno; return 0; } @@ -319,7 +303,7 @@ int do_mkdir(const char *file, int mode) int err; err = mkdir(file, mode); - if(err) + if (err) return -errno; return 0; } @@ -329,7 +313,7 @@ int do_rmdir(const char *file) int err; err = rmdir(file); - if(err) + if (err) return -errno; return 0; } @@ -338,8 +322,8 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor) { int err; - err = mknod(file, mode, makedev(major, minor)); - if(err) + err = mknod(file, mode, os_makedev(major, minor)); + if (err) return -errno; return 0; } @@ -349,19 +333,19 @@ int link_file(const char *to, const char *from) int err; err = link(to, from); - if(err) + if (err) return -errno; return 0; } -int do_readlink(char *file, char *buf, int size) +int hostfs_do_readlink(char *file, char *buf, int size) { int n; n = readlink(file, buf, size); - if(n < 0) + if (n < 0) return -errno; - if(n < size) + if (n < size) buf[n] = '\0'; return n; } @@ -371,7 +355,7 @@ int rename_file(char *from, char *to) int err; err = rename(from, to); - if(err < 0) + if (err < 0) return -errno; return 0; } @@ -379,14 +363,13 @@ int rename_file(char *from, char *to) int do_statfs(char *root, long *bsize_out, long long *blocks_out, long long *bfree_out, long long *bavail_out, long long *files_out, long long *ffree_out, - void *fsid_out, int fsid_size, long *namelen_out, - long *spare_out) + void *fsid_out, int fsid_size, long *namelen_out) { struct statfs64 buf; int err; err = statfs64(root, &buf); - if(err < 0) + if (err < 0) return -errno; *bsize_out = buf.f_bsize; @@ -399,10 +382,6 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out, sizeof(buf.f_fsid) > fsid_size ? fsid_size : sizeof(buf.f_fsid)); *namelen_out = buf.f_namelen; - spare_out[0] = buf.f_spare[0]; - spare_out[1] = buf.f_spare[1]; - spare_out[2] = buf.f_spare[2]; - spare_out[3] = buf.f_spare[3]; - spare_out[4] = buf.f_spare[4]; + return 0; } |
