diff options
Diffstat (limited to 'fs/cramfs/inode.c')
-rw-r--r-- | fs/cramfs/inode.c | 88 |
1 files changed, 38 insertions, 50 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index dd3634e4c967..a53b130b366c 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -39,66 +39,55 @@ static DEFINE_MUTEX(read_mutex); | |||
39 | #define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1) | 39 | #define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1) |
40 | #define OFFSET(x) ((x)->i_ino) | 40 | #define OFFSET(x) ((x)->i_ino) |
41 | 41 | ||
42 | 42 | static void setup_inode(struct inode *inode, struct cramfs_inode * cramfs_inode) | |
43 | static int cramfs_iget5_test(struct inode *inode, void *opaque) | ||
44 | { | ||
45 | struct cramfs_inode *cramfs_inode = opaque; | ||
46 | return inode->i_ino == CRAMINO(cramfs_inode) && inode->i_ino != 1; | ||
47 | } | ||
48 | |||
49 | static int cramfs_iget5_set(struct inode *inode, void *opaque) | ||
50 | { | 43 | { |
51 | struct cramfs_inode *cramfs_inode = opaque; | 44 | static struct timespec zerotime; |
52 | inode->i_ino = CRAMINO(cramfs_inode); | 45 | inode->i_mode = cramfs_inode->mode; |
53 | return 0; | 46 | inode->i_uid = cramfs_inode->uid; |
47 | inode->i_size = cramfs_inode->size; | ||
48 | inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | ||
49 | inode->i_gid = cramfs_inode->gid; | ||
50 | /* Struct copy intentional */ | ||
51 | inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; | ||
52 | /* inode->i_nlink is left 1 - arguably wrong for directories, | ||
53 | but it's the best we can do without reading the directory | ||
54 | contents. 1 yields the right result in GNU find, even | ||
55 | without -noleaf option. */ | ||
56 | if (S_ISREG(inode->i_mode)) { | ||
57 | inode->i_fop = &generic_ro_fops; | ||
58 | inode->i_data.a_ops = &cramfs_aops; | ||
59 | } else if (S_ISDIR(inode->i_mode)) { | ||
60 | inode->i_op = &cramfs_dir_inode_operations; | ||
61 | inode->i_fop = &cramfs_directory_operations; | ||
62 | } else if (S_ISLNK(inode->i_mode)) { | ||
63 | inode->i_op = &page_symlink_inode_operations; | ||
64 | inode->i_data.a_ops = &cramfs_aops; | ||
65 | } else { | ||
66 | init_special_inode(inode, inode->i_mode, | ||
67 | old_decode_dev(cramfs_inode->size)); | ||
68 | } | ||
54 | } | 69 | } |
55 | 70 | ||
56 | static struct inode *get_cramfs_inode(struct super_block *sb, | 71 | static struct inode *get_cramfs_inode(struct super_block *sb, |
57 | struct cramfs_inode * cramfs_inode) | 72 | struct cramfs_inode * cramfs_inode) |
58 | { | 73 | { |
59 | struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), | 74 | struct inode *inode; |
60 | cramfs_iget5_test, cramfs_iget5_set, | 75 | if (CRAMINO(cramfs_inode) == 1) { |
61 | cramfs_inode); | 76 | inode = new_inode(sb); |
62 | static struct timespec zerotime; | 77 | if (inode) { |
63 | 78 | inode->i_ino = 1; | |
64 | if (inode && (inode->i_state & I_NEW)) { | 79 | setup_inode(inode, cramfs_inode); |
65 | inode->i_mode = cramfs_inode->mode; | 80 | } |
66 | inode->i_uid = cramfs_inode->uid; | 81 | } else { |
67 | inode->i_size = cramfs_inode->size; | 82 | inode = iget_locked(sb, CRAMINO(cramfs_inode)); |
68 | inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | 83 | if (inode) { |
69 | inode->i_gid = cramfs_inode->gid; | 84 | setup_inode(inode, cramfs_inode); |
70 | /* Struct copy intentional */ | 85 | unlock_new_inode(inode); |
71 | inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; | ||
72 | /* inode->i_nlink is left 1 - arguably wrong for directories, | ||
73 | but it's the best we can do without reading the directory | ||
74 | contents. 1 yields the right result in GNU find, even | ||
75 | without -noleaf option. */ | ||
76 | if (S_ISREG(inode->i_mode)) { | ||
77 | inode->i_fop = &generic_ro_fops; | ||
78 | inode->i_data.a_ops = &cramfs_aops; | ||
79 | } else if (S_ISDIR(inode->i_mode)) { | ||
80 | inode->i_op = &cramfs_dir_inode_operations; | ||
81 | inode->i_fop = &cramfs_directory_operations; | ||
82 | } else if (S_ISLNK(inode->i_mode)) { | ||
83 | inode->i_op = &page_symlink_inode_operations; | ||
84 | inode->i_data.a_ops = &cramfs_aops; | ||
85 | } else { | ||
86 | init_special_inode(inode, inode->i_mode, | ||
87 | old_decode_dev(cramfs_inode->size)); | ||
88 | } | 86 | } |
89 | unlock_new_inode(inode); | ||
90 | } | 87 | } |
91 | return inode; | 88 | return inode; |
92 | } | 89 | } |
93 | 90 | ||
94 | static void cramfs_drop_inode(struct inode *inode) | ||
95 | { | ||
96 | if (inode->i_ino == 1) | ||
97 | generic_delete_inode(inode); | ||
98 | else | ||
99 | generic_drop_inode(inode); | ||
100 | } | ||
101 | |||
102 | /* | 91 | /* |
103 | * We have our own block cache: don't fill up the buffer cache | 92 | * We have our own block cache: don't fill up the buffer cache |
104 | * with the rom-image, because the way the filesystem is set | 93 | * with the rom-image, because the way the filesystem is set |
@@ -542,7 +531,6 @@ static const struct super_operations cramfs_ops = { | |||
542 | .put_super = cramfs_put_super, | 531 | .put_super = cramfs_put_super, |
543 | .remount_fs = cramfs_remount, | 532 | .remount_fs = cramfs_remount, |
544 | .statfs = cramfs_statfs, | 533 | .statfs = cramfs_statfs, |
545 | .drop_inode = cramfs_drop_inode, | ||
546 | }; | 534 | }; |
547 | 535 | ||
548 | static int cramfs_get_sb(struct file_system_type *fs_type, | 536 | static int cramfs_get_sb(struct file_system_type *fs_type, |