2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
6 #include <linux/slab.h>
7 #include <linux/init.h>
10 #include "kern_util.h"
12 #define METADATA_FILE_PATH(meta) (meta)->root, "file_metadata"
13 #define METADATA_DIR_PATH(meta) (meta)->root, "dir_metadata"
21 struct humfs_file humfs;
22 struct file_handle fh;
25 static int meta_file_path(const char *path, struct meta_fs *meta,
26 const char *path_out[])
28 const char *data_path[] = { meta->root, "data", path, NULL };
29 char data_tmp[HOSTFS_BUFSIZE];
30 char *data_file = get_path(data_path, data_tmp, sizeof(data_tmp));
35 path_out[0] = meta->root;
37 if(os_file_type(data_file) == OS_TYPE_DIR){
38 path_out[1] = "dir_metadata";
39 path_out[3] = "metadata";
43 path_out[1] = "file_metadata";
50 static int open_meta_file(const char *path, struct humfs *humfs,
51 struct file_handle *fh)
53 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
54 const char *meta_path[5];
55 char meta_tmp[HOSTFS_BUFSIZE];
59 err = meta_file_path(path, meta, meta_path);
63 meta_file = get_path(meta_path, meta_tmp, sizeof(meta_tmp));
67 err = open_filehandle(meta_file, of_rdwr(OPENFLAGS()), 0, fh);
73 static char *meta_fs_name(struct inode *inode)
75 struct humfs *mount = inode_humfs_info(inode);
76 struct meta_fs *meta = container_of(mount, struct meta_fs, humfs);
77 const char *metadata_path[5];
78 char tmp[HOSTFS_BUFSIZE], *name, *file;
80 if(meta_file_path("", meta, metadata_path))
83 file = get_path(metadata_path, tmp, sizeof(tmp));
87 name = inode_name_prefix(inode, file);
93 static void metafs_invisible(struct humfs_file *hf)
95 struct meta_file *mf = container_of(hf, struct meta_file, humfs);
97 not_reclaimable(&mf->fh);
100 static struct humfs_file *metafs_init_file(void)
102 struct meta_file *mf;
105 mf = kmalloc(sizeof(*mf), GFP_KERNEL);
107 return(ERR_PTR(err));
112 static int metafs_open_file(struct humfs_file *hf, const char *path,
113 struct inode *inode, struct humfs *humfs)
115 struct meta_file *mf = container_of(hf, struct meta_file, humfs);
118 err = open_meta_file(path, humfs, &mf->fh);
122 is_reclaimable(&mf->fh, meta_fs_name, inode);
127 static void metafs_close_file(struct humfs_file *hf)
129 struct meta_file *meta = container_of(hf, struct meta_file, humfs);
131 close_file(&meta->fh);
135 static int metafs_create_file(struct humfs_file *hf, const char *path,
136 int mode, int uid, int gid, struct inode *inode,
139 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
140 struct meta_file *mf = container_of(hf, struct meta_file, humfs);
141 char tmp[HOSTFS_BUFSIZE];
142 const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
143 char *file = get_path(metadata_path, tmp, sizeof(tmp));
144 char buf[sizeof("mmmm uuuuuuuuuu gggggggggg")];
150 err = open_filehandle(file, of_write(of_create(OPENFLAGS())), 0644,
156 is_reclaimable(&mf->fh, meta_fs_name, inode);
158 sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
159 err = write_file(&mf->fh, 0, buf, strlen(buf));
163 free_path(file, tmp);
168 os_remove_file(file);
170 free_path(file, tmp);
175 static int metafs_create_link(const char *to, const char *from,
178 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
179 const char *path_to[] = { METADATA_FILE_PATH(meta), to, NULL };
180 const char *path_from[] = { METADATA_FILE_PATH(meta), from, NULL };
182 return(host_link_file(path_to, path_from));
185 static int metafs_remove_file(const char *path, struct humfs *humfs)
187 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
188 char tmp[HOSTFS_BUFSIZE];
189 const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
190 char *file = get_path(metadata_path, tmp, sizeof(tmp));
196 err = os_remove_file(file);
199 free_path(file, tmp);
203 static int metafs_create_directory(const char *path, int mode, int uid,
204 int gid, struct humfs *humfs)
206 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
207 char tmp[HOSTFS_BUFSIZE];
208 const char *dir_path[] = { METADATA_DIR_PATH(meta), path, NULL, NULL };
209 const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL,
211 char *file, dir_meta[sizeof("mmmm uuuuuuuuuu gggggggggg\n")];
214 err = host_make_dir(dir_path, 0755);
218 err = host_make_dir(file_path, 0755);
222 /* This to make the index independent of the number of elements in
223 * METADATA_DIR_PATH().
225 dir_path[sizeof(dir_path) / sizeof(dir_path[0]) - 2] = "metadata";
228 file = get_path(dir_path, tmp, sizeof(tmp));
232 fd = os_open_file(file, of_create(of_rdwr(OPENFLAGS())), 0644);
238 sprintf(dir_meta, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
239 err = os_write_file(fd, dir_meta, strlen(dir_meta));
246 free_path(file, tmp);
248 host_remove_dir(dir_path);
253 static int metafs_remove_directory(const char *path, struct humfs *humfs)
255 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
256 char tmp[HOSTFS_BUFSIZE], *file;
257 const char *dir_path[] = { METADATA_DIR_PATH(meta), path, "metadata",
259 const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL };
264 file = get_path(dir_path, tmp, sizeof(tmp));
268 err = os_remove_file(file);
272 slash = strrchr(file, '/');
274 printk("remove_shadow_directory failed to find last slash\n");
278 err = os_remove_dir(file);
279 free_path(file, tmp);
281 file = get_path(file_path, tmp, sizeof(tmp));
285 err = os_remove_dir(file);
292 free_path(file, tmp);
296 static int metafs_make_node(const char *path, int mode, int uid, int gid,
297 int type, int maj, int min, struct humfs *humfs)
299 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
300 struct file_handle fh;
301 char tmp[HOSTFS_BUFSIZE];
302 const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
304 char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")], *file;
306 sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid, type,
310 file = get_path(metadata_path, tmp, sizeof(tmp));
314 err = open_filehandle(file,
315 of_create(of_rdwr(OPENFLAGS())), 0644, &fh);
319 err = write_file(&fh, 0, buf, strlen(buf));
326 free_path(file, tmp);
331 static int metafs_ownerships(const char *path, int *mode_out, int *uid_out,
332 int *gid_out, char *type_out, int *maj_out,
333 int *min_out, struct humfs *humfs)
335 struct file_handle fh;
336 char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")];
337 int err, n, mode, uid, gid, maj, min;
340 err = open_meta_file(path, humfs, &fh);
344 err = os_read_file(fh.fd, buf, sizeof(buf) - 1);
351 n = sscanf(buf, "%d %d %d %c %d %d", &mode, &uid, &gid, &type, &maj,
381 static int metafs_change_ownerships(const char *path, int mode, int uid,
382 int gid, struct humfs *humfs)
384 struct file_handle fh;
386 char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")];
387 int err = -ENOMEM, old_mode, old_uid, old_gid, n, maj, min;
389 err = open_meta_file(path, humfs, &fh);
393 err = read_file(&fh, 0, buf, sizeof(buf) - 1);
399 n = sscanf(buf, "%d %d %d %c %d %d\n", &old_mode, &old_uid, &old_gid,
401 if((n != 3) && (n != 6)){
414 sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
416 sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid,
419 err = write_file(&fh, 0, buf, strlen(buf));
423 err = truncate_file(&fh, strlen(buf));
431 static int metafs_rename_file(const char *from, const char *to,
434 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
435 const char *metadata_path_from[5], *metadata_path_to[5];
438 err = meta_file_path(from, meta, metadata_path_from);
442 err = meta_file_path(to, meta, metadata_path_to);
446 return(host_rename_file(metadata_path_from, metadata_path_to));
449 static struct humfs *metafs_init_mount(char *root)
451 struct meta_fs *meta;
454 meta = kmalloc(sizeof(*meta), GFP_KERNEL);
458 meta->root = uml_strdup(root);
459 if(meta->root == NULL)
462 return(&meta->humfs);
467 return(ERR_PTR(err));
470 static void metafs_free_mount(struct humfs *humfs)
472 struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
477 struct humfs_meta_ops hum_fs_meta_fs_ops = {
478 .list = LIST_HEAD_INIT(hum_fs_meta_fs_ops.list),
480 .init_file = metafs_init_file,
481 .open_file = metafs_open_file,
482 .close_file = metafs_close_file,
483 .ownerships = metafs_ownerships,
484 .make_node = metafs_make_node,
485 .create_file = metafs_create_file,
486 .create_link = metafs_create_link,
487 .remove_file = metafs_remove_file,
488 .create_dir = metafs_create_directory,
489 .remove_dir = metafs_remove_directory,
490 .change_ownerships = metafs_change_ownerships,
491 .rename_file = metafs_rename_file,
492 .invisible = metafs_invisible,
493 .init_mount = metafs_init_mount,
494 .free_mount = metafs_free_mount,
497 static int __init init_meta_fs(void)
499 register_meta(&hum_fs_meta_fs_ops);
503 static void __exit exit_meta_fs(void)
505 unregister_meta(&hum_fs_meta_fs_ops);
508 __initcall(init_meta_fs);
509 __exitcall(exit_meta_fs);
512 * Overrides for Emacs so that we follow Linus's tabbing style.
513 * Emacs will notice this stuff at the end of the file and automatically
514 * adjust the settings for this buffer only. This must remain at the end
516 * ---------------------------------------------------------------------------
518 * c-file-style: "linux"