2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
15 #include <sys/types.h>
20 static void stat64_to_hostfs(const struct stat64
*buf
, struct hostfs_stat
*p
)
23 p
->mode
= buf
->st_mode
;
24 p
->nlink
= buf
->st_nlink
;
27 p
->size
= buf
->st_size
;
28 p
->atime
.tv_sec
= buf
->st_atime
;
30 p
->ctime
.tv_sec
= buf
->st_ctime
;
32 p
->mtime
.tv_sec
= buf
->st_mtime
;
34 p
->blksize
= buf
->st_blksize
;
35 p
->blocks
= buf
->st_blocks
;
36 p
->maj
= os_major(buf
->st_rdev
);
37 p
->min
= os_minor(buf
->st_rdev
);
40 int stat_file(const char *path
, struct hostfs_stat
*p
, int fd
)
45 if (fstat64(fd
, &buf
) < 0)
47 } else if (lstat64(path
, &buf
) < 0) {
50 stat64_to_hostfs(&buf
, p
);
54 int access_file(char *path
, int r
, int w
, int x
)
64 if (access(path
, mode
) != 0)
69 int open_file(char *path
, int r
, int w
, int append
)
79 else panic("Impossible mode in open_file");
83 fd
= open64(path
, mode
);
89 void *open_dir(char *path
, int *err_out
)
99 char *read_dir(void *stream
, unsigned long long *pos
,
100 unsigned long long *ino_out
, int *len_out
,
101 unsigned int *type_out
)
110 *len_out
= strlen(ent
->d_name
);
111 *ino_out
= ent
->d_ino
;
112 *type_out
= ent
->d_type
;
117 int read_file(int fd
, unsigned long long *offset
, char *buf
, int len
)
121 n
= pread64(fd
, buf
, len
, *offset
);
128 int write_file(int fd
, unsigned long long *offset
, const char *buf
, int len
)
132 n
= pwrite64(fd
, buf
, len
, *offset
);
139 int lseek_file(int fd
, long long offset
, int whence
)
143 ret
= lseek64(fd
, offset
, whence
);
149 int fsync_file(int fd
, int datasync
)
162 int replace_file(int oldfd
, int fd
)
164 return dup2(oldfd
, fd
);
167 void close_file(void *stream
)
169 close(*((int *) stream
));
172 void close_dir(void *stream
)
177 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
178 int gw
, int gx
, int or, int ow
, int ox
)
183 mode
|= ur
? S_IRUSR
: 0;
184 mode
|= uw
? S_IWUSR
: 0;
185 mode
|= ux
? S_IXUSR
: 0;
186 mode
|= gr
? S_IRGRP
: 0;
187 mode
|= gw
? S_IWGRP
: 0;
188 mode
|= gx
? S_IXGRP
: 0;
189 mode
|= or ? S_IROTH
: 0;
190 mode
|= ow
? S_IWOTH
: 0;
191 mode
|= ox
? S_IXOTH
: 0;
192 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
198 int set_attr(const char *file
, struct hostfs_iattr
*attrs
, int fd
)
200 struct hostfs_stat st
;
201 struct timeval times
[2];
204 if (attrs
->ia_valid
& HOSTFS_ATTR_MODE
) {
206 if (fchmod(fd
, attrs
->ia_mode
) != 0)
208 } else if (chmod(file
, attrs
->ia_mode
) != 0) {
212 if (attrs
->ia_valid
& HOSTFS_ATTR_UID
) {
214 if (fchown(fd
, attrs
->ia_uid
, -1))
216 } else if (chown(file
, attrs
->ia_uid
, -1)) {
220 if (attrs
->ia_valid
& HOSTFS_ATTR_GID
) {
222 if (fchown(fd
, -1, attrs
->ia_gid
))
224 } else if (chown(file
, -1, attrs
->ia_gid
)) {
228 if (attrs
->ia_valid
& HOSTFS_ATTR_SIZE
) {
230 if (ftruncate(fd
, attrs
->ia_size
))
232 } else if (truncate(file
, attrs
->ia_size
)) {
238 * Update accessed and/or modified time, in two parts: first set
239 * times according to the changes to perform, and then call futimes()
240 * or utimes() to apply them.
242 ma
= (HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
);
243 if (attrs
->ia_valid
& ma
) {
244 err
= stat_file(file
, &st
, fd
);
248 times
[0].tv_sec
= st
.atime
.tv_sec
;
249 times
[0].tv_usec
= st
.atime
.tv_nsec
/ 1000;
250 times
[1].tv_sec
= st
.mtime
.tv_sec
;
251 times
[1].tv_usec
= st
.mtime
.tv_nsec
/ 1000;
253 if (attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
) {
254 times
[0].tv_sec
= attrs
->ia_atime
.tv_sec
;
255 times
[0].tv_usec
= attrs
->ia_atime
.tv_nsec
/ 1000;
257 if (attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
) {
258 times
[1].tv_sec
= attrs
->ia_mtime
.tv_sec
;
259 times
[1].tv_usec
= attrs
->ia_mtime
.tv_nsec
/ 1000;
263 if (futimes(fd
, times
) != 0)
265 } else if (utimes(file
, times
) != 0) {
270 /* Note: ctime is not handled */
271 if (attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)) {
272 err
= stat_file(file
, &st
, fd
);
273 attrs
->ia_atime
= st
.atime
;
274 attrs
->ia_mtime
= st
.mtime
;
281 int make_symlink(const char *from
, const char *to
)
285 err
= symlink(to
, from
);
291 int unlink_file(const char *file
)
301 int do_mkdir(const char *file
, int mode
)
305 err
= mkdir(file
, mode
);
311 int do_rmdir(const char *file
)
321 int do_mknod(const char *file
, int mode
, unsigned int major
, unsigned int minor
)
325 err
= mknod(file
, mode
, os_makedev(major
, minor
));
331 int link_file(const char *to
, const char *from
)
335 err
= link(to
, from
);
341 int hostfs_do_readlink(char *file
, char *buf
, int size
)
345 n
= readlink(file
, buf
, size
);
353 int rename_file(char *from
, char *to
)
357 err
= rename(from
, to
);
363 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
364 long long *bfree_out
, long long *bavail_out
,
365 long long *files_out
, long long *ffree_out
,
366 void *fsid_out
, int fsid_size
, long *namelen_out
)
371 err
= statfs64(root
, &buf
);
375 *bsize_out
= buf
.f_bsize
;
376 *blocks_out
= buf
.f_blocks
;
377 *bfree_out
= buf
.f_bfree
;
378 *bavail_out
= buf
.f_bavail
;
379 *files_out
= buf
.f_files
;
380 *ffree_out
= buf
.f_ffree
;
381 memcpy(fsid_out
, &buf
.f_fsid
,
382 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
384 *namelen_out
= buf
.f_namelen
;