diff options
Diffstat (limited to 'fs/jffs2/super.c')
-rw-r--r-- | fs/jffs2/super.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index efd401257ed9..4c4e18c54a51 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mtd/super.h> | 22 | #include <linux/mtd/super.h> |
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
25 | #include <linux/exportfs.h> | ||
25 | #include "compr.h" | 26 | #include "compr.h" |
26 | #include "nodelist.h" | 27 | #include "nodelist.h" |
27 | 28 | ||
@@ -62,6 +63,52 @@ static int jffs2_sync_fs(struct super_block *sb, int wait) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | static struct inode *jffs2_nfs_get_inode(struct super_block *sb, uint64_t ino, | ||
67 | uint32_t generation) | ||
68 | { | ||
69 | /* We don't care about i_generation. We'll destroy the flash | ||
70 | before we start re-using inode numbers anyway. And even | ||
71 | if that wasn't true, we'd have other problems...*/ | ||
72 | return jffs2_iget(sb, ino); | ||
73 | } | ||
74 | |||
75 | static struct dentry *jffs2_fh_to_dentry(struct super_block *sb, struct fid *fid, | ||
76 | int fh_len, int fh_type) | ||
77 | { | ||
78 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | ||
79 | jffs2_nfs_get_inode); | ||
80 | } | ||
81 | |||
82 | static struct dentry *jffs2_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
83 | int fh_len, int fh_type) | ||
84 | { | ||
85 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | ||
86 | jffs2_nfs_get_inode); | ||
87 | } | ||
88 | |||
89 | static struct dentry *jffs2_get_parent(struct dentry *child) | ||
90 | { | ||
91 | struct jffs2_inode_info *f; | ||
92 | uint32_t pino; | ||
93 | |||
94 | BUG_ON(!S_ISDIR(child->d_inode->i_mode)); | ||
95 | |||
96 | f = JFFS2_INODE_INFO(child->d_inode); | ||
97 | |||
98 | pino = f->inocache->pino_nlink; | ||
99 | |||
100 | JFFS2_DEBUG("Parent of directory ino #%u is #%u\n", | ||
101 | f->inocache->ino, pino); | ||
102 | |||
103 | return d_obtain_alias(jffs2_iget(child->d_inode->i_sb, pino)); | ||
104 | } | ||
105 | |||
106 | static struct export_operations jffs2_export_ops = { | ||
107 | .get_parent = jffs2_get_parent, | ||
108 | .fh_to_dentry = jffs2_fh_to_dentry, | ||
109 | .fh_to_parent = jffs2_fh_to_parent, | ||
110 | }; | ||
111 | |||
65 | static const struct super_operations jffs2_super_operations = | 112 | static const struct super_operations jffs2_super_operations = |
66 | { | 113 | { |
67 | .alloc_inode = jffs2_alloc_inode, | 114 | .alloc_inode = jffs2_alloc_inode, |
@@ -104,6 +151,7 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent) | |||
104 | spin_lock_init(&c->inocache_lock); | 151 | spin_lock_init(&c->inocache_lock); |
105 | 152 | ||
106 | sb->s_op = &jffs2_super_operations; | 153 | sb->s_op = &jffs2_super_operations; |
154 | sb->s_export_op = &jffs2_export_ops; | ||
107 | sb->s_flags = sb->s_flags | MS_NOATIME; | 155 | sb->s_flags = sb->s_flags | MS_NOATIME; |
108 | sb->s_xattr = jffs2_xattr_handlers; | 156 | sb->s_xattr = jffs2_xattr_handlers; |
109 | #ifdef CONFIG_JFFS2_FS_POSIX_ACL | 157 | #ifdef CONFIG_JFFS2_FS_POSIX_ACL |