2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
17 #include "kern_util.h"
20 int stat_file(const char *path
, unsigned long long *inode_out
, int *mode_out
,
21 int *nlink_out
, int *uid_out
, int *gid_out
,
22 unsigned long long *size_out
, struct timespec
*atime_out
,
23 struct timespec
*mtime_out
, struct timespec
*ctime_out
,
24 int *blksize_out
, unsigned long long *blocks_out
, int fd
)
29 if (fstat64(fd
, &buf
) < 0)
31 } else if(lstat64(path
, &buf
) < 0) {
35 if(inode_out
!= NULL
) *inode_out
= buf
.st_ino
;
36 if(mode_out
!= NULL
) *mode_out
= buf
.st_mode
;
37 if(nlink_out
!= NULL
) *nlink_out
= buf
.st_nlink
;
38 if(uid_out
!= NULL
) *uid_out
= buf
.st_uid
;
39 if(gid_out
!= NULL
) *gid_out
= buf
.st_gid
;
40 if(size_out
!= NULL
) *size_out
= buf
.st_size
;
41 if(atime_out
!= NULL
) {
42 atime_out
->tv_sec
= buf
.st_atime
;
43 atime_out
->tv_nsec
= 0;
45 if(mtime_out
!= NULL
) {
46 mtime_out
->tv_sec
= buf
.st_mtime
;
47 mtime_out
->tv_nsec
= 0;
49 if(ctime_out
!= NULL
) {
50 ctime_out
->tv_sec
= buf
.st_ctime
;
51 ctime_out
->tv_nsec
= 0;
53 if(blksize_out
!= NULL
) *blksize_out
= buf
.st_blksize
;
54 if(blocks_out
!= NULL
) *blocks_out
= buf
.st_blocks
;
58 int file_type(const char *path
, int *maj
, int *min
)
62 if(lstat64(path
, &buf
) < 0)
64 /*We cannot pass rdev as is because glibc and the kernel disagree
65 *about its definition.*/
67 *maj
= major(buf
.st_rdev
);
69 *min
= minor(buf
.st_rdev
);
71 if(S_ISDIR(buf
.st_mode
)) return OS_TYPE_DIR
;
72 else if(S_ISLNK(buf
.st_mode
)) return OS_TYPE_SYMLINK
;
73 else if(S_ISCHR(buf
.st_mode
)) return OS_TYPE_CHARDEV
;
74 else if(S_ISBLK(buf
.st_mode
)) return OS_TYPE_BLOCKDEV
;
75 else if(S_ISFIFO(buf
.st_mode
))return OS_TYPE_FIFO
;
76 else if(S_ISSOCK(buf
.st_mode
))return OS_TYPE_SOCK
;
77 else return OS_TYPE_FILE
;
80 int access_file(char *path
, int r
, int w
, int x
)
87 if(access(path
, mode
) != 0)
92 int open_file(char *path
, int r
, int w
, int append
)
102 else panic("Impossible mode in open_file");
106 fd
= open64(path
, mode
);
112 void *open_dir(char *path
, int *err_out
)
123 char *read_dir(void *stream
, unsigned long long *pos
,
124 unsigned long long *ino_out
, int *len_out
)
133 *len_out
= strlen(ent
->d_name
);
134 *ino_out
= ent
->d_ino
;
139 int read_file(int fd
, unsigned long long *offset
, char *buf
, int len
)
143 n
= pread64(fd
, buf
, len
, *offset
);
150 int write_file(int fd
, unsigned long long *offset
, const char *buf
, int len
)
154 n
= pwrite64(fd
, buf
, len
, *offset
);
161 int lseek_file(int fd
, long long offset
, int whence
)
165 ret
= lseek64(fd
, offset
, whence
);
171 int fsync_file(int fd
, int datasync
)
184 void close_file(void *stream
)
186 close(*((int *) stream
));
189 void close_dir(void *stream
)
194 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
195 int gw
, int gx
, int or, int ow
, int ox
)
200 mode
|= ur
? S_IRUSR
: 0;
201 mode
|= uw
? S_IWUSR
: 0;
202 mode
|= ux
? S_IXUSR
: 0;
203 mode
|= gr
? S_IRGRP
: 0;
204 mode
|= gw
? S_IWGRP
: 0;
205 mode
|= gx
? S_IXGRP
: 0;
206 mode
|= or ? S_IROTH
: 0;
207 mode
|= ow
? S_IWOTH
: 0;
208 mode
|= ox
? S_IXOTH
: 0;
209 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
215 int set_attr(const char *file
, struct hostfs_iattr
*attrs
, int fd
)
217 struct timeval times
[2];
218 struct timespec atime_ts
, mtime_ts
;
221 if (attrs
->ia_valid
& HOSTFS_ATTR_MODE
) {
223 if (fchmod(fd
, attrs
->ia_mode
) != 0)
225 } else if (chmod(file
, attrs
->ia_mode
) != 0) {
229 if (attrs
->ia_valid
& HOSTFS_ATTR_UID
) {
231 if (fchown(fd
, attrs
->ia_uid
, -1))
233 } else if(chown(file
, attrs
->ia_uid
, -1)) {
237 if (attrs
->ia_valid
& HOSTFS_ATTR_GID
) {
239 if (fchown(fd
, -1, attrs
->ia_gid
))
241 } else if (chown(file
, -1, attrs
->ia_gid
)) {
245 if (attrs
->ia_valid
& HOSTFS_ATTR_SIZE
) {
247 if (ftruncate(fd
, attrs
->ia_size
))
249 } else if (truncate(file
, attrs
->ia_size
)) {
254 /* Update accessed and/or modified time, in two parts: first set
255 * times according to the changes to perform, and then call futimes()
256 * or utimes() to apply them. */
257 ma
= (HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
);
258 if (attrs
->ia_valid
& ma
) {
259 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
260 &atime_ts
, &mtime_ts
, NULL
, NULL
, NULL
, fd
);
264 times
[0].tv_sec
= atime_ts
.tv_sec
;
265 times
[0].tv_usec
= atime_ts
.tv_nsec
* 1000;
266 times
[1].tv_sec
= mtime_ts
.tv_sec
;
267 times
[1].tv_usec
= mtime_ts
.tv_nsec
* 1000;
269 if (attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
) {
270 times
[0].tv_sec
= attrs
->ia_atime
.tv_sec
;
271 times
[0].tv_usec
= attrs
->ia_atime
.tv_nsec
* 1000;
273 if (attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
) {
274 times
[1].tv_sec
= attrs
->ia_mtime
.tv_sec
;
275 times
[1].tv_usec
= attrs
->ia_mtime
.tv_nsec
* 1000;
279 if (futimes(fd
, times
) != 0)
281 } else if (utimes(file
, times
) != 0) {
286 if(attrs
->ia_valid
& HOSTFS_ATTR_CTIME
) ;
287 if(attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)){
288 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
289 &attrs
->ia_atime
, &attrs
->ia_mtime
, NULL
,
297 int make_symlink(const char *from
, const char *to
)
301 err
= symlink(to
, from
);
307 int unlink_file(const char *file
)
317 int do_mkdir(const char *file
, int mode
)
321 err
= mkdir(file
, mode
);
327 int do_rmdir(const char *file
)
337 int do_mknod(const char *file
, int mode
, unsigned int major
, unsigned int minor
)
341 err
= mknod(file
, mode
, makedev(major
, minor
));
347 int link_file(const char *to
, const char *from
)
351 err
= link(to
, from
);
357 int do_readlink(char *file
, char *buf
, int size
)
361 n
= readlink(file
, buf
, size
);
369 int rename_file(char *from
, char *to
)
373 err
= rename(from
, to
);
379 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
380 long long *bfree_out
, long long *bavail_out
,
381 long long *files_out
, long long *ffree_out
,
382 void *fsid_out
, int fsid_size
, long *namelen_out
,
388 err
= statfs64(root
, &buf
);
392 *bsize_out
= buf
.f_bsize
;
393 *blocks_out
= buf
.f_blocks
;
394 *bfree_out
= buf
.f_bfree
;
395 *bavail_out
= buf
.f_bavail
;
396 *files_out
= buf
.f_files
;
397 *ffree_out
= buf
.f_ffree
;
398 memcpy(fsid_out
, &buf
.f_fsid
,
399 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
401 *namelen_out
= buf
.f_namelen
;
402 spare_out
[0] = buf
.f_spare
[0];
403 spare_out
[1] = buf
.f_spare
[1];
404 spare_out
[2] = buf
.f_spare
[2];
405 spare_out
[3] = buf
.f_spare
[3];
406 spare_out
[4] = buf
.f_spare
[4];