summaryrefslogtreecommitdiffstats
path: root/fs/hostfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hostfs')
-rw-r--r--fs/hostfs/hostfs.h20
-rw-r--r--fs/hostfs/hostfs_kern.c31
-rw-r--r--fs/hostfs/hostfs_user.c75
3 files changed, 58 insertions, 68 deletions
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 2f34f8f..3a52ede 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -53,11 +53,21 @@ struct hostfs_iattr {
struct timespec ia_ctime;
};
-extern 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);
+struct hostfs_stat {
+ unsigned long long ino;
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned long long size;
+ struct timespec atime, mtime, ctime;
+ unsigned int blksize;
+ unsigned long long blocks;
+ unsigned int maj;
+ unsigned int min;
+};
+
+extern int stat_file(const char *path, struct hostfs_stat *p, int fd);
extern int access_file(char *path, int r, int w, int x);
extern int open_file(char *path, int r, int w, int append);
extern int file_type(const char *path, int *maj, int *min);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 5a77ed3..420a826 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -131,28 +131,21 @@ static char *inode_name(struct inode *ino, int extra)
static int read_name(struct inode *ino, char *name)
{
- /*
- * The non-int inode fields are copied into ints by stat_file and
- * then copied into the inode because passing the actual pointers
- * in and having them treated as int * breaks on big-endian machines
- */
- int err;
- int i_mode, i_nlink, i_blksize;
- unsigned long long i_size;
- unsigned long long i_ino;
- unsigned long long i_blocks;
-
- err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
- &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
- &ino->i_ctime, &i_blksize, &i_blocks, -1);
+ struct hostfs_stat st;
+ int err = stat_file(name, &st, -1);
if (err)
return err;
- ino->i_ino = i_ino;
- ino->i_mode = i_mode;
- ino->i_nlink = i_nlink;
- ino->i_size = i_size;
- ino->i_blocks = i_blocks;
+ ino->i_ino = st.ino;
+ ino->i_mode = st.mode;
+ ino->i_nlink = st.nlink;
+ ino->i_uid = st.uid;
+ ino->i_gid = st.gid;
+ ino->i_atime = st.atime;
+ ino->i_mtime = st.mtime;
+ ino->i_ctime = st.ctime;
+ ino->i_size = st.size;
+ ino->i_blocks = st.blocks;
return 0;
}
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 4b8c666..701d454 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -19,11 +19,27 @@
#include "user.h"
#include <utime.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)
+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;
@@ -33,35 +49,7 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
} 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;
}
@@ -235,8 +223,8 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
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) {
@@ -279,15 +267,14 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
*/
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;
@@ -308,9 +295,9 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
/* Note: ctime is not handled */
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);
+ err = stat_file(file, &st, fd);
+ attrs->ia_atime = st.atime;
+ attrs->ia_mtime = st.mtime;
if (err != 0)
return err;
}
OpenPOWER on IntegriCloud