diff options
-rw-r--r-- | fs/hostfs/hostfs.h | 1 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 107 | ||||
-rw-r--r-- | fs/hostfs/hostfs_user.c | 30 |
3 files changed, 45 insertions, 93 deletions
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index 3a52edef9948..ea87e224ed97 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h | |||
@@ -70,7 +70,6 @@ struct hostfs_stat { | |||
70 | extern int stat_file(const char *path, struct hostfs_stat *p, int fd); | 70 | extern int stat_file(const char *path, struct hostfs_stat *p, int fd); |
71 | extern int access_file(char *path, int r, int w, int x); | 71 | extern int access_file(char *path, int r, int w, int x); |
72 | extern int open_file(char *path, int r, int w, int append); | 72 | extern int open_file(char *path, int r, int w, int append); |
73 | extern int file_type(const char *path, int *maj, int *min); | ||
74 | extern void *open_dir(char *path, int *err_out); | 73 | extern void *open_dir(char *path, int *err_out); |
75 | extern char *read_dir(void *stream, unsigned long long *pos, | 74 | extern char *read_dir(void *stream, unsigned long long *pos, |
76 | unsigned long long *ino_out, int *len_out); | 75 | unsigned long long *ino_out, int *len_out); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 420a826ae0f2..b29a2b878f46 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -129,26 +129,6 @@ static char *inode_name(struct inode *ino, int extra) | |||
129 | return dentry_name(dentry, extra); | 129 | return dentry_name(dentry, extra); |
130 | } | 130 | } |
131 | 131 | ||
132 | static int read_name(struct inode *ino, char *name) | ||
133 | { | ||
134 | struct hostfs_stat st; | ||
135 | int err = stat_file(name, &st, -1); | ||
136 | if (err) | ||
137 | return err; | ||
138 | |||
139 | ino->i_ino = st.ino; | ||
140 | ino->i_mode = st.mode; | ||
141 | ino->i_nlink = st.nlink; | ||
142 | ino->i_uid = st.uid; | ||
143 | ino->i_gid = st.gid; | ||
144 | ino->i_atime = st.atime; | ||
145 | ino->i_mtime = st.mtime; | ||
146 | ino->i_ctime = st.ctime; | ||
147 | ino->i_size = st.size; | ||
148 | ino->i_blocks = st.blocks; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static char *follow_link(char *link) | 132 | static char *follow_link(char *link) |
153 | { | 133 | { |
154 | int len, n; | 134 | int len, n; |
@@ -478,43 +458,51 @@ static const struct address_space_operations hostfs_aops = { | |||
478 | .write_end = hostfs_write_end, | 458 | .write_end = hostfs_write_end, |
479 | }; | 459 | }; |
480 | 460 | ||
481 | static void init_inode(struct inode *inode, char *path) | 461 | static int read_name(struct inode *ino, char *name) |
482 | { | 462 | { |
483 | int type; | 463 | dev_t rdev; |
484 | int maj, min; | 464 | struct hostfs_stat st; |
485 | dev_t rdev = 0; | 465 | int err = stat_file(name, &st, -1); |
466 | if (err) | ||
467 | return err; | ||
486 | 468 | ||
487 | type = file_type(path, &maj, &min); | ||
488 | /* Reencode maj and min with the kernel encoding.*/ | 469 | /* Reencode maj and min with the kernel encoding.*/ |
489 | rdev = MKDEV(maj, min); | 470 | rdev = MKDEV(st.maj, st.min); |
490 | 471 | ||
491 | if (type == OS_TYPE_SYMLINK) | 472 | switch (st.mode & S_IFMT) { |
492 | inode->i_op = &page_symlink_inode_operations; | 473 | case S_IFLNK: |
493 | else if (type == OS_TYPE_DIR) | 474 | ino->i_op = &page_symlink_inode_operations; |
494 | inode->i_op = &hostfs_dir_iops; | 475 | ino->i_mapping->a_ops = &hostfs_link_aops; |
495 | else inode->i_op = &hostfs_iops; | ||
496 | |||
497 | if (type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops; | ||
498 | else inode->i_fop = &hostfs_file_fops; | ||
499 | |||
500 | if (type == OS_TYPE_SYMLINK) | ||
501 | inode->i_mapping->a_ops = &hostfs_link_aops; | ||
502 | else inode->i_mapping->a_ops = &hostfs_aops; | ||
503 | |||
504 | switch (type) { | ||
505 | case OS_TYPE_CHARDEV: | ||
506 | init_special_inode(inode, S_IFCHR, rdev); | ||
507 | break; | ||
508 | case OS_TYPE_BLOCKDEV: | ||
509 | init_special_inode(inode, S_IFBLK, rdev); | ||
510 | break; | 476 | break; |
511 | case OS_TYPE_FIFO: | 477 | case S_IFDIR: |
512 | init_special_inode(inode, S_IFIFO, 0); | 478 | ino->i_op = &hostfs_dir_iops; |
479 | ino->i_fop = &hostfs_dir_fops; | ||
513 | break; | 480 | break; |
514 | case OS_TYPE_SOCK: | 481 | case S_IFCHR: |
515 | init_special_inode(inode, S_IFSOCK, 0); | 482 | case S_IFBLK: |
483 | case S_IFIFO: | ||
484 | case S_IFSOCK: | ||
485 | init_special_inode(ino, st.mode & S_IFMT, rdev); | ||
486 | ino->i_op = &hostfs_iops; | ||
516 | break; | 487 | break; |
488 | |||
489 | default: | ||
490 | ino->i_op = &hostfs_iops; | ||
491 | ino->i_fop = &hostfs_file_fops; | ||
492 | ino->i_mapping->a_ops = &hostfs_aops; | ||
517 | } | 493 | } |
494 | |||
495 | ino->i_ino = st.ino; | ||
496 | ino->i_mode = st.mode; | ||
497 | ino->i_nlink = st.nlink; | ||
498 | ino->i_uid = st.uid; | ||
499 | ino->i_gid = st.gid; | ||
500 | ino->i_atime = st.atime; | ||
501 | ino->i_mtime = st.mtime; | ||
502 | ino->i_ctime = st.ctime; | ||
503 | ino->i_size = st.size; | ||
504 | ino->i_blocks = st.blocks; | ||
505 | return 0; | ||
518 | } | 506 | } |
519 | 507 | ||
520 | int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, | 508 | int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, |
@@ -539,12 +527,10 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
539 | mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, | 527 | mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, |
540 | mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, | 528 | mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, |
541 | mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH); | 529 | mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH); |
542 | if (fd < 0) { | 530 | if (fd < 0) |
543 | error = fd; | 531 | error = fd; |
544 | } else { | 532 | else |
545 | error = read_name(inode, name); | 533 | error = read_name(inode, name); |
546 | init_inode(inode, name); | ||
547 | } | ||
548 | 534 | ||
549 | kfree(name); | 535 | kfree(name); |
550 | if (error) | 536 | if (error) |
@@ -580,7 +566,6 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, | |||
580 | goto out_put; | 566 | goto out_put; |
581 | 567 | ||
582 | err = read_name(inode, name); | 568 | err = read_name(inode, name); |
583 | init_inode(inode, name); | ||
584 | 569 | ||
585 | kfree(name); | 570 | kfree(name); |
586 | if (err == -ENOENT) { | 571 | if (err == -ENOENT) { |
@@ -707,7 +692,6 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
707 | goto out_free; | 692 | goto out_free; |
708 | 693 | ||
709 | err = read_name(inode, name); | 694 | err = read_name(inode, name); |
710 | init_inode(inode, name); | ||
711 | if (err) | 695 | if (err) |
712 | goto out_put; | 696 | goto out_put; |
713 | kfree(name); | 697 | kfree(name); |
@@ -922,21 +906,20 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
922 | if (!root_inode) | 906 | if (!root_inode) |
923 | goto out; | 907 | goto out; |
924 | 908 | ||
925 | root_inode->i_op = &hostfs_dir_iops; | 909 | err = read_name(root_inode, host_root_path); |
926 | root_inode->i_fop = &hostfs_dir_fops; | 910 | if (err) |
911 | goto out_put; | ||
927 | 912 | ||
928 | if (file_type(host_root_path, NULL, NULL) == OS_TYPE_SYMLINK) { | 913 | if (S_ISLNK(root_inode->i_mode)) { |
929 | char *name = follow_link(host_root_path); | 914 | char *name = follow_link(host_root_path); |
930 | if (IS_ERR(name)) | 915 | if (IS_ERR(name)) |
931 | err = PTR_ERR(name); | 916 | err = PTR_ERR(name); |
932 | else | 917 | else |
933 | err = read_name(root_inode, name); | 918 | err = read_name(root_inode, name); |
934 | kfree(name); | 919 | kfree(name); |
935 | } else { | 920 | if (err) |
936 | err = read_name(root_inode, host_root_path); | 921 | goto out_put; |
937 | } | 922 | } |
938 | if (err) | ||
939 | goto out_put; | ||
940 | 923 | ||
941 | err = -ENOMEM; | 924 | err = -ENOMEM; |
942 | sb->s_root = d_alloc_root(root_inode); | 925 | sb->s_root = d_alloc_root(root_inode); |
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index 701d454a6791..91ebfcefa409 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
@@ -53,36 +53,6 @@ int stat_file(const char *path, struct hostfs_stat *p, int fd) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | int file_type(const char *path, int *maj, int *min) | ||
57 | { | ||
58 | struct stat64 buf; | ||
59 | |||
60 | if (lstat64(path, &buf) < 0) | ||
61 | return -errno; | ||
62 | /* | ||
63 | * We cannot pass rdev as is because glibc and the kernel disagree | ||
64 | * about its definition. | ||
65 | */ | ||
66 | if (maj != NULL) | ||
67 | *maj = os_major(buf.st_rdev); | ||
68 | if (min != NULL) | ||
69 | *min = os_minor(buf.st_rdev); | ||
70 | |||
71 | if (S_ISDIR(buf.st_mode)) | ||
72 | return OS_TYPE_DIR; | ||
73 | else if (S_ISLNK(buf.st_mode)) | ||
74 | return OS_TYPE_SYMLINK; | ||
75 | else if (S_ISCHR(buf.st_mode)) | ||
76 | return OS_TYPE_CHARDEV; | ||
77 | else if (S_ISBLK(buf.st_mode)) | ||
78 | return OS_TYPE_BLOCKDEV; | ||
79 | else if (S_ISFIFO(buf.st_mode)) | ||
80 | return OS_TYPE_FIFO; | ||
81 | else if (S_ISSOCK(buf.st_mode)) | ||
82 | return OS_TYPE_SOCK; | ||
83 | else return OS_TYPE_FILE; | ||
84 | } | ||
85 | |||
86 | int access_file(char *path, int r, int w, int x) | 56 | int access_file(char *path, int r, int w, int x) |
87 | { | 57 | { |
88 | int mode = 0; | 58 | int mode = 0; |