2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
15 #include <sys/types.h>
21 static void stat64_to_hostfs(const struct stat64
*buf
, struct hostfs_stat
*p
)
24 p
->mode
= buf
->st_mode
;
25 p
->nlink
= buf
->st_nlink
;
28 p
->size
= buf
->st_size
;
29 p
->atime
.tv_sec
= buf
->st_atime
;
31 p
->ctime
.tv_sec
= buf
->st_ctime
;
33 p
->mtime
.tv_sec
= buf
->st_mtime
;
35 p
->blksize
= buf
->st_blksize
;
36 p
->blocks
= buf
->st_blocks
;
37 p
->maj
= os_major(buf
->st_rdev
);
38 p
->min
= os_minor(buf
->st_rdev
);
41 int stat_file(const char *path
, struct hostfs_stat
*p
, int fd
)
46 if (fstat64(fd
, &buf
) < 0)
48 } else if (lstat64(path
, &buf
) < 0) {
51 stat64_to_hostfs(&buf
, p
);
55 int access_file(char *path
, int r
, int w
, int x
)
65 if (access(path
, mode
) != 0)
70 int open_file(char *path
, int r
, int w
, int append
)
80 else panic("Impossible mode in open_file");
84 fd
= open64(path
, mode
);
90 void *open_dir(char *path
, int *err_out
)
100 char *read_dir(void *stream
, unsigned long long *pos
,
101 unsigned long long *ino_out
, int *len_out
,
102 unsigned int *type_out
)
111 *len_out
= strlen(ent
->d_name
);
112 *ino_out
= ent
->d_ino
;
113 *type_out
= ent
->d_type
;
118 int read_file(int fd
, unsigned long long *offset
, char *buf
, int len
)
122 n
= pread64(fd
, buf
, len
, *offset
);
129 int write_file(int fd
, unsigned long long *offset
, const char *buf
, int len
)
133 n
= pwrite64(fd
, buf
, len
, *offset
);
140 int lseek_file(int fd
, long long offset
, int whence
)
144 ret
= lseek64(fd
, offset
, whence
);
150 int fsync_file(int fd
, int datasync
)
163 int replace_file(int oldfd
, int fd
)
165 return dup2(oldfd
, fd
);
168 void close_file(void *stream
)
170 close(*((int *) stream
));
173 void close_dir(void *stream
)
178 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
179 int gw
, int gx
, int or, int ow
, int ox
)
184 mode
|= ur
? S_IRUSR
: 0;
185 mode
|= uw
? S_IWUSR
: 0;
186 mode
|= ux
? S_IXUSR
: 0;
187 mode
|= gr
? S_IRGRP
: 0;
188 mode
|= gw
? S_IWGRP
: 0;
189 mode
|= gx
? S_IXGRP
: 0;
190 mode
|= or ? S_IROTH
: 0;
191 mode
|= ow
? S_IWOTH
: 0;
192 mode
|= ox
? S_IXOTH
: 0;
193 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
199 int set_attr(const char *file
, struct hostfs_iattr
*attrs
, int fd
)
201 struct hostfs_stat st
;
202 struct timeval times
[2];
205 if (attrs
->ia_valid
& HOSTFS_ATTR_MODE
) {
207 if (fchmod(fd
, attrs
->ia_mode
) != 0)
209 } else if (chmod(file
, attrs
->ia_mode
) != 0) {
213 if (attrs
->ia_valid
& HOSTFS_ATTR_UID
) {
215 if (fchown(fd
, attrs
->ia_uid
, -1))
217 } else if (chown(file
, attrs
->ia_uid
, -1)) {
221 if (attrs
->ia_valid
& HOSTFS_ATTR_GID
) {
223 if (fchown(fd
, -1, attrs
->ia_gid
))
225 } else if (chown(file
, -1, attrs
->ia_gid
)) {
229 if (attrs
->ia_valid
& HOSTFS_ATTR_SIZE
) {
231 if (ftruncate(fd
, attrs
->ia_size
))
233 } else if (truncate(file
, attrs
->ia_size
)) {
239 * Update accessed and/or modified time, in two parts: first set
240 * times according to the changes to perform, and then call futimes()
241 * or utimes() to apply them.
243 ma
= (HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
);
244 if (attrs
->ia_valid
& ma
) {
245 err
= stat_file(file
, &st
, fd
);
249 times
[0].tv_sec
= st
.atime
.tv_sec
;
250 times
[0].tv_usec
= st
.atime
.tv_nsec
/ 1000;
251 times
[1].tv_sec
= st
.mtime
.tv_sec
;
252 times
[1].tv_usec
= st
.mtime
.tv_nsec
/ 1000;
254 if (attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
) {
255 times
[0].tv_sec
= attrs
->ia_atime
.tv_sec
;
256 times
[0].tv_usec
= attrs
->ia_atime
.tv_nsec
/ 1000;
258 if (attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
) {
259 times
[1].tv_sec
= attrs
->ia_mtime
.tv_sec
;
260 times
[1].tv_usec
= attrs
->ia_mtime
.tv_nsec
/ 1000;
264 if (futimes(fd
, times
) != 0)
266 } else if (utimes(file
, times
) != 0) {
271 /* Note: ctime is not handled */
272 if (attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)) {
273 err
= stat_file(file
, &st
, fd
);
274 attrs
->ia_atime
= st
.atime
;
275 attrs
->ia_mtime
= st
.mtime
;
282 int make_symlink(const char *from
, const char *to
)
286 err
= symlink(to
, from
);
292 int unlink_file(const char *file
)
302 int do_mkdir(const char *file
, int mode
)
306 err
= mkdir(file
, mode
);
312 int do_rmdir(const char *file
)
322 int do_mknod(const char *file
, int mode
, unsigned int major
, unsigned int minor
)
326 err
= mknod(file
, mode
, os_makedev(major
, minor
));
332 int link_file(const char *to
, const char *from
)
336 err
= link(to
, from
);
342 int hostfs_do_readlink(char *file
, char *buf
, int size
)
346 n
= readlink(file
, buf
, size
);
354 int rename_file(char *from
, char *to
)
358 err
= rename(from
, to
);
364 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
365 long long *bfree_out
, long long *bavail_out
,
366 long long *files_out
, long long *ffree_out
,
367 void *fsid_out
, int fsid_size
, long *namelen_out
)
372 err
= statfs64(root
, &buf
);
376 *bsize_out
= buf
.f_bsize
;
377 *blocks_out
= buf
.f_blocks
;
378 *bfree_out
= buf
.f_bfree
;
379 *bavail_out
= buf
.f_bavail
;
380 *files_out
= buf
.f_files
;
381 *ffree_out
= buf
.f_ffree
;
382 memcpy(fsid_out
, &buf
.f_fsid
,
383 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
385 *namelen_out
= buf
.f_namelen
;