diff options
Diffstat (limited to 'fs/hostfs/hostfs_user.c')
| -rw-r--r-- | fs/hostfs/hostfs_user.c | 112 |
1 files changed, 37 insertions, 75 deletions
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index b79424f93282..6777aa06ce2c 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
| @@ -19,11 +19,27 @@ | |||
| 19 | #include "user.h" | 19 | #include "user.h" |
| 20 | #include <utime.h> | 20 | #include <utime.h> |
| 21 | 21 | ||
| 22 | int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, | 22 | static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p) |
| 23 | int *nlink_out, int *uid_out, int *gid_out, | 23 | { |
| 24 | unsigned long long *size_out, struct timespec *atime_out, | 24 | p->ino = buf->st_ino; |
| 25 | struct timespec *mtime_out, struct timespec *ctime_out, | 25 | p->mode = buf->st_mode; |
| 26 | int *blksize_out, unsigned long long *blocks_out, int fd) | 26 | p->nlink = buf->st_nlink; |
| 27 | p->uid = buf->st_uid; | ||
| 28 | p->gid = buf->st_gid; | ||
| 29 | p->size = buf->st_size; | ||
| 30 | p->atime.tv_sec = buf->st_atime; | ||
| 31 | p->atime.tv_nsec = 0; | ||
| 32 | p->ctime.tv_sec = buf->st_ctime; | ||
| 33 | p->ctime.tv_nsec = 0; | ||
| 34 | p->mtime.tv_sec = buf->st_mtime; | ||
| 35 | p->mtime.tv_nsec = 0; | ||
| 36 | p->blksize = buf->st_blksize; | ||
| 37 | p->blocks = buf->st_blocks; | ||
| 38 | p->maj = os_major(buf->st_rdev); | ||
| 39 | p->min = os_minor(buf->st_rdev); | ||
| 40 | } | ||
| 41 | |||
| 42 | int stat_file(const char *path, struct hostfs_stat *p, int fd) | ||
| 27 | { | 43 | { |
| 28 | struct stat64 buf; | 44 | struct stat64 buf; |
| 29 | 45 | ||
| @@ -33,68 +49,10 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, | |||
| 33 | } else if (lstat64(path, &buf) < 0) { | 49 | } else if (lstat64(path, &buf) < 0) { |
| 34 | return -errno; | 50 | return -errno; |
| 35 | } | 51 | } |
| 36 | 52 | stat64_to_hostfs(&buf, p); | |
| 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; | 53 | return 0; |
| 66 | } | 54 | } |
| 67 | 55 | ||
| 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) | 56 | int access_file(char *path, int r, int w, int x) |
| 99 | { | 57 | { |
| 100 | int mode = 0; | 58 | int mode = 0; |
| @@ -202,6 +160,11 @@ int fsync_file(int fd, int datasync) | |||
| 202 | return 0; | 160 | return 0; |
| 203 | } | 161 | } |
| 204 | 162 | ||
| 163 | int replace_file(int oldfd, int fd) | ||
| 164 | { | ||
| 165 | return dup2(oldfd, fd); | ||
| 166 | } | ||
| 167 | |||
| 205 | void close_file(void *stream) | 168 | void close_file(void *stream) |
| 206 | { | 169 | { |
| 207 | close(*((int *) stream)); | 170 | close(*((int *) stream)); |
| @@ -235,8 +198,8 @@ int file_create(char *name, int ur, int uw, int ux, int gr, | |||
| 235 | 198 | ||
| 236 | int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) | 199 | int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) |
| 237 | { | 200 | { |
| 201 | struct hostfs_stat st; | ||
| 238 | struct timeval times[2]; | 202 | struct timeval times[2]; |
| 239 | struct timespec atime_ts, mtime_ts; | ||
| 240 | int err, ma; | 203 | int err, ma; |
| 241 | 204 | ||
| 242 | if (attrs->ia_valid & HOSTFS_ATTR_MODE) { | 205 | if (attrs->ia_valid & HOSTFS_ATTR_MODE) { |
| @@ -279,15 +242,14 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) | |||
| 279 | */ | 242 | */ |
| 280 | ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); | 243 | ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); |
| 281 | if (attrs->ia_valid & ma) { | 244 | if (attrs->ia_valid & ma) { |
| 282 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, | 245 | err = stat_file(file, &st, fd); |
| 283 | &atime_ts, &mtime_ts, NULL, NULL, NULL, fd); | ||
| 284 | if (err != 0) | 246 | if (err != 0) |
| 285 | return err; | 247 | return err; |
| 286 | 248 | ||
| 287 | times[0].tv_sec = atime_ts.tv_sec; | 249 | times[0].tv_sec = st.atime.tv_sec; |
| 288 | times[0].tv_usec = atime_ts.tv_nsec / 1000; | 250 | times[0].tv_usec = st.atime.tv_nsec / 1000; |
| 289 | times[1].tv_sec = mtime_ts.tv_sec; | 251 | times[1].tv_sec = st.mtime.tv_sec; |
| 290 | times[1].tv_usec = mtime_ts.tv_nsec / 1000; | 252 | times[1].tv_usec = st.mtime.tv_nsec / 1000; |
| 291 | 253 | ||
| 292 | if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) { | 254 | if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) { |
| 293 | times[0].tv_sec = attrs->ia_atime.tv_sec; | 255 | times[0].tv_sec = attrs->ia_atime.tv_sec; |
| @@ -308,9 +270,9 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) | |||
| 308 | 270 | ||
| 309 | /* Note: ctime is not handled */ | 271 | /* Note: ctime is not handled */ |
| 310 | if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) { | 272 | if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) { |
| 311 | err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, | 273 | err = stat_file(file, &st, fd); |
| 312 | &attrs->ia_atime, &attrs->ia_mtime, NULL, | 274 | attrs->ia_atime = st.atime; |
| 313 | NULL, NULL, fd); | 275 | attrs->ia_mtime = st.mtime; |
| 314 | if (err != 0) | 276 | if (err != 0) |
| 315 | return err; | 277 | return err; |
| 316 | } | 278 | } |
| @@ -361,7 +323,7 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor) | |||
| 361 | { | 323 | { |
| 362 | int err; | 324 | int err; |
| 363 | 325 | ||
| 364 | err = mknod(file, mode, makedev(major, minor)); | 326 | err = mknod(file, mode, os_makedev(major, minor)); |
| 365 | if (err) | 327 | if (err) |
| 366 | return -errno; | 328 | return -errno; |
| 367 | return 0; | 329 | return 0; |
