2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
6 #include "linux/stddef.h"
7 #include "linux/string.h"
8 #include "linux/errno.h"
9 #include "linux/types.h"
10 #include "linux/slab.h"
12 #include "asm/fcntl.h"
14 #include "filehandle.h"
18 char *get_path(const char *path[], char *buf, int size)
24 for(s = path; *s != NULL; s++){
26 if((*(s + 1) != NULL) && (strlen(*s) > 0) &&
27 ((*s)[strlen(*s) - 1] != '/'))
32 buf = kmalloc(new, GFP_KERNEL);
38 for(s = path; *s != NULL; s++){
41 if((*(s + 1) != NULL) && (strlen(*s) > 0) &&
42 ((*s)[strlen(*s) - 1] != '/'))
49 void free_path(const char *buf, char *tmp)
51 if((buf != tmp) && (buf != NULL))
55 int host_open_file(const char *path[], int r, int w, struct file_handle *fh)
57 char tmp[HOSTFS_BUFSIZE], *file;
59 struct openflags flags = OPENFLAGS();
62 flags = of_read(flags);
64 flags = of_write(flags);
66 flags = of_append(flags);
69 file = get_path(path, tmp, sizeof(tmp));
73 err = open_filehandle(file, flags, mode, fh);
79 void *host_open_dir(const char *path[])
81 char tmp[HOSTFS_BUFSIZE], *file;
82 void *dir = ERR_PTR(-ENOMEM);
84 file = get_path(path, tmp, sizeof(tmp));
94 char *host_read_dir(void *stream, unsigned long long *pos,
95 unsigned long long *ino_out, int *len_out)
100 err = os_seek_dir(stream, *pos);
102 return(ERR_PTR(err));
104 err = os_read_dir(stream, ino_out, &name);
106 return(ERR_PTR(err));
111 *len_out = strlen(name);
112 *pos = os_tell_dir(stream);
116 int host_file_type(const char *path[], int *rdev)
118 char tmp[HOSTFS_BUFSIZE], *file;
123 file = get_path(path, tmp, sizeof(tmp));
128 ret = os_lstat_file(file, &buf);
131 *rdev = MKDEV(buf.ust_rmajor, buf.ust_rminor);
134 ret = os_file_type(file);
136 free_path(file, tmp);
140 int host_create_file(const char *path[], int mode, struct file_handle *fh)
142 char tmp[HOSTFS_BUFSIZE], *file;
145 file = get_path(path, tmp, sizeof(tmp));
149 err = open_filehandle(file, of_create(of_rdwr(OPENFLAGS())), mode, fh);
151 free_path(file, tmp);
155 static int do_stat_file(const char *path, int *dev_out,
156 unsigned long long *inode_out, int *mode_out,
157 int *nlink_out, int *uid_out, int *gid_out,
158 unsigned long long *size_out, unsigned long *atime_out,
159 unsigned long *mtime_out, unsigned long *ctime_out,
160 int *blksize_out, unsigned long long *blocks_out)
165 err = os_lstat_file(path, &buf);
169 if(dev_out != NULL) *dev_out = MKDEV(buf.ust_major, buf.ust_minor);
170 if(inode_out != NULL) *inode_out = buf.ust_ino;
171 if(mode_out != NULL) *mode_out = buf.ust_mode;
172 if(nlink_out != NULL) *nlink_out = buf.ust_nlink;
173 if(uid_out != NULL) *uid_out = buf.ust_uid;
174 if(gid_out != NULL) *gid_out = buf.ust_gid;
175 if(size_out != NULL) *size_out = buf.ust_size;
176 if(atime_out != NULL) *atime_out = buf.ust_atime;
177 if(mtime_out != NULL) *mtime_out = buf.ust_mtime;
178 if(ctime_out != NULL) *ctime_out = buf.ust_ctime;
179 if(blksize_out != NULL) *blksize_out = buf.ust_blksize;
180 if(blocks_out != NULL) *blocks_out = buf.ust_blocks;
185 int host_stat_file(const char *path[], int *dev_out,
186 unsigned long long *inode_out, int *mode_out,
187 int *nlink_out, int *uid_out, int *gid_out,
188 unsigned long long *size_out, unsigned long *atime_out,
189 unsigned long *mtime_out, unsigned long *ctime_out,
190 int *blksize_out, unsigned long long *blocks_out)
192 char tmp[HOSTFS_BUFSIZE], *file;
196 file = get_path(path, tmp, sizeof(tmp));
200 err = do_stat_file(file, dev_out, inode_out, mode_out, nlink_out,
201 uid_out, gid_out, size_out, atime_out, mtime_out,
202 ctime_out, blksize_out, blocks_out);
204 free_path(file, tmp);
208 int host_set_attr(const char *path[], struct externfs_iattr *attrs)
210 char tmp[HOSTFS_BUFSIZE], *file;
214 if(append && (attrs->ia_valid & EXTERNFS_ATTR_SIZE))
218 file = get_path(path, tmp, sizeof(tmp));
222 if(attrs->ia_valid & EXTERNFS_ATTR_MODE){
223 err = os_set_file_perms(file, attrs->ia_mode);
227 if(attrs->ia_valid & EXTERNFS_ATTR_UID){
228 err = os_set_file_owner(file, attrs->ia_uid, -1);
232 if(attrs->ia_valid & EXTERNFS_ATTR_GID){
233 err = os_set_file_owner(file, -1, attrs->ia_gid);
237 if(attrs->ia_valid & EXTERNFS_ATTR_SIZE){
238 err = os_truncate_file(file, attrs->ia_size);
242 ma = EXTERNFS_ATTR_ATIME_SET | EXTERNFS_ATTR_MTIME_SET;
243 if((attrs->ia_valid & ma) == ma){
244 err = os_set_file_time(file, attrs->ia_atime, attrs->ia_mtime);
249 if(attrs->ia_valid & EXTERNFS_ATTR_ATIME_SET){
250 err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL,
251 NULL, NULL, NULL, &time,
256 err = os_set_file_time(file, attrs->ia_atime, time);
260 if(attrs->ia_valid & EXTERNFS_ATTR_MTIME_SET){
261 err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL,
262 NULL, NULL, &time, NULL,
267 err = os_set_file_time(file, time, attrs->ia_mtime);
272 if(attrs->ia_valid & EXTERNFS_ATTR_CTIME) ;
273 if(attrs->ia_valid & (EXTERNFS_ATTR_ATIME | EXTERNFS_ATTR_MTIME)){
274 err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL,
275 NULL, NULL, &attrs->ia_atime,
276 &attrs->ia_mtime, NULL, NULL, NULL);
283 free_path(file, tmp);
287 int host_make_symlink(const char *from[], const char *to)
289 char tmp[HOSTFS_BUFSIZE], *file;
292 file = get_path(from, tmp, sizeof(tmp));
296 err = os_make_symlink(to, file);
298 free_path(file, tmp);
302 int host_unlink_file(const char *path[])
304 char tmp[HOSTFS_BUFSIZE], *file;
310 file = get_path(path, tmp, sizeof(tmp));
314 err = os_remove_file(file);
316 free_path(file, tmp);
320 int host_make_dir(const char *path[], int mode)
322 char tmp[HOSTFS_BUFSIZE], *file;
325 file = get_path(path, tmp, sizeof(tmp));
329 err = os_make_dir(file, mode);
331 free_path(file, tmp);
335 int host_remove_dir(const char *path[])
337 char tmp[HOSTFS_BUFSIZE], *file;
340 file = get_path(path, tmp, sizeof(tmp));
344 err = os_remove_dir(file);
346 free_path(file, tmp);
350 int host_link_file(const char *to[], const char *from[])
352 char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
355 f = get_path(from, from_tmp, sizeof(from_tmp));
356 t = get_path(to, to_tmp, sizeof(to_tmp));
357 if((f == NULL) || (t == NULL))
360 err = os_link_file(t, f);
362 free_path(f, from_tmp);
363 free_path(t, to_tmp);
367 int host_read_link(const char *path[], char *buf, int size)
369 char tmp[HOSTFS_BUFSIZE], *file;
372 file = get_path(path, tmp, sizeof(tmp));
376 n = os_read_symlink(file, buf, size);
380 free_path(file, tmp);
384 int host_rename_file(const char *from[], const char *to[])
386 char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
389 f = get_path(from, from_tmp, sizeof(from_tmp));
390 t = get_path(to, to_tmp, sizeof(to_tmp));
391 if((f == NULL) || (t == NULL))
394 err = os_move_file(f, t);
396 free_path(f, from_tmp);
397 free_path(t, to_tmp);
401 int host_stat_fs(const char *path[], long *bsize_out, long long *blocks_out,
402 long long *bfree_out, long long *bavail_out,
403 long long *files_out, long long *ffree_out, void *fsid_out,
404 int fsid_size, long *namelen_out, long *spare_out)
406 char tmp[HOSTFS_BUFSIZE], *file;
409 file = get_path(path, tmp, sizeof(tmp));
413 err = os_stat_filesystem(file, bsize_out, blocks_out, bfree_out,
414 bavail_out, files_out, ffree_out, fsid_out,
415 fsid_size, namelen_out, spare_out);
417 free_path(file, tmp);
421 char *generic_host_read_dir(void *stream, unsigned long long *pos,
422 unsigned long long *ino_out, int *len_out,
425 return(host_read_dir(stream, pos, ino_out, len_out));
428 int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m)
430 return(truncate_file(fh, size));
434 * Overrides for Emacs so that we follow Linus's tabbing style.
435 * Emacs will notice this stuff at the end of the file and automatically
436 * adjust the settings for this buffer only. This must remain at the end
438 * ---------------------------------------------------------------------------
440 * c-file-style: "linux"