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, |
