aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/hostfs/hostfs.h1
-rw-r--r--fs/hostfs/hostfs_kern.c107
-rw-r--r--fs/hostfs/hostfs_user.c30
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 {
70extern int stat_file(const char *path, struct hostfs_stat *p, int fd); 70extern int stat_file(const char *path, struct hostfs_stat *p, int fd);
71extern int access_file(char *path, int r, int w, int x); 71extern int access_file(char *path, int r, int w, int x);
72extern int open_file(char *path, int r, int w, int append); 72extern int open_file(char *path, int r, int w, int append);
73extern int file_type(const char *path, int *maj, int *min);
74extern void *open_dir(char *path, int *err_out); 73extern void *open_dir(char *path, int *err_out);
75extern char *read_dir(void *stream, unsigned long long *pos, 74extern 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
132static 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
152static char *follow_link(char *link) 132static 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
481static void init_inode(struct inode *inode, char *path) 461static 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
520int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 508int 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
56int 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
86int access_file(char *path, int r, int w, int x) 56int access_file(char *path, int r, int w, int x)
87{ 57{
88 int mode = 0; 58 int mode = 0;