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
)
110 *len_out
= strlen(ent
->d_name
);
111 *ino_out
= ent
->d_ino
;
116 int read_file(int fd
, unsigned long long *offset
, char *buf
, int len
)
120 n
= pread64(fd
, buf
, len
, *offset
);
127 int write_file(int fd
, unsigned long long *offset
, const char *buf
, int len
)
131 n
= pwrite64(fd
, buf
, len
, *offset
);
138 int lseek_file(int fd
, long long offset
, int whence
)
142 ret
= lseek64(fd
, offset
, whence
);
148 int fsync_file(int fd
, int datasync
)
161 int replace_file(int oldfd
, int fd
)
163 return dup2(oldfd
, fd
);
166 void close_file(void *stream
)
168 close(*((int *) stream
));
171 void close_dir(void *stream
)
176 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
177 int gw
, int gx
, int or, int ow
, int ox
)
182 mode
|= ur
? S_IRUSR
: 0;
183 mode
|= uw
? S_IWUSR
: 0;
184 mode
|= ux
? S_IXUSR
: 0;
185 mode
|= gr
? S_IRGRP
: 0;
186 mode
|= gw
? S_IWGRP
: 0;
187 mode
|= gx
? S_IXGRP
: 0;
188 mode
|= or ? S_IROTH
: 0;
189 mode
|= ow
? S_IWOTH
: 0;
190 mode
|= ox
? S_IXOTH
: 0;
191 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
197 int set_attr(const char *file
, struct hostfs_iattr
*attrs
, int fd
)
199 struct hostfs_stat st
;
200 struct timeval times
[2];
203 if (attrs
->ia_valid
& HOSTFS_ATTR_MODE
) {
205 if (fchmod(fd
, attrs
->ia_mode
) != 0)
207 } else if (chmod(file
, attrs
->ia_mode
) != 0) {
211 if (attrs
->ia_valid
& HOSTFS_ATTR_UID
) {
213 if (fchown(fd
, attrs
->ia_uid
, -1))
215 } else if (chown(file
, attrs
->ia_uid
, -1)) {
219 if (attrs
->ia_valid
& HOSTFS_ATTR_GID
) {
221 if (fchown(fd
, -1, attrs
->ia_gid
))
223 } else if (chown(file
, -1, attrs
->ia_gid
)) {
227 if (attrs
->ia_valid
& HOSTFS_ATTR_SIZE
) {
229 if (ftruncate(fd
, attrs
->ia_size
))
231 } else if (truncate(file
, attrs
->ia_size
)) {
237 * Update accessed and/or modified time, in two parts: first set
238 * times according to the changes to perform, and then call futimes()
239 * or utimes() to apply them.
241 ma
= (HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
);
242 if (attrs
->ia_valid
& ma
) {
243 err
= stat_file(file
, &st
, fd
);
247 times
[0].tv_sec
= st
.atime
.tv_sec
;
248 times
[0].tv_usec
= st
.atime
.tv_nsec
/ 1000;
249 times
[1].tv_sec
= st
.mtime
.tv_sec
;
250 times
[1].tv_usec
= st
.mtime
.tv_nsec
/ 1000;
252 if (attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
) {
253 times
[0].tv_sec
= attrs
->ia_atime
.tv_sec
;
254 times
[0].tv_usec
= attrs
->ia_atime
.tv_nsec
/ 1000;
256 if (attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
) {
257 times
[1].tv_sec
= attrs
->ia_mtime
.tv_sec
;
258 times
[1].tv_usec
= attrs
->ia_mtime
.tv_nsec
/ 1000;
262 if (futimes(fd
, times
) != 0)
264 } else if (utimes(file
, times
) != 0) {
269 /* Note: ctime is not handled */
270 if (attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)) {
271 err
= stat_file(file
, &st
, fd
);
272 attrs
->ia_atime
= st
.atime
;
273 attrs
->ia_mtime
= st
.mtime
;
280 int make_symlink(const char *from
, const char *to
)
284 err
= symlink(to
, from
);
290 int unlink_file(const char *file
)
300 int do_mkdir(const char *file
, int mode
)
304 err
= mkdir(file
, mode
);
310 int do_rmdir(const char *file
)
320 int do_mknod(const char *file
, int mode
, unsigned int major
, unsigned int minor
)
324 err
= mknod(file
, mode
, os_makedev(major
, minor
));
330 int link_file(const char *to
, const char *from
)
334 err
= link(to
, from
);
340 int hostfs_do_readlink(char *file
, char *buf
, int size
)
344 n
= readlink(file
, buf
, size
);
352 int rename_file(char *from
, char *to
)
356 err
= rename(from
, to
);
362 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
363 long long *bfree_out
, long long *bavail_out
,
364 long long *files_out
, long long *ffree_out
,
365 void *fsid_out
, int fsid_size
, long *namelen_out
)
370 err
= statfs64(root
, &buf
);
374 *bsize_out
= buf
.f_bsize
;
375 *blocks_out
= buf
.f_blocks
;
376 *bfree_out
= buf
.f_bfree
;
377 *bavail_out
= buf
.f_bavail
;
378 *files_out
= buf
.f_files
;
379 *ffree_out
= buf
.f_ffree
;
380 memcpy(fsid_out
, &buf
.f_fsid
,
381 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
383 *namelen_out
= buf
.f_namelen
;