diff options
Diffstat (limited to 'fs/minix/inode.c')
-rw-r--r-- | fs/minix/inode.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 629e09b38c5c..92e383af3709 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Minix V2 fs support. | 7 | * Minix V2 fs support. |
8 | * | 8 | * |
9 | * Modified for 680x0 by Andreas Schwab | 9 | * Modified for 680x0 by Andreas Schwab |
10 | * Updated to filesystem version 3 by Daniel Aragones | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -36,7 +37,8 @@ static void minix_put_super(struct super_block *sb) | |||
36 | struct minix_sb_info *sbi = minix_sb(sb); | 37 | struct minix_sb_info *sbi = minix_sb(sb); |
37 | 38 | ||
38 | if (!(sb->s_flags & MS_RDONLY)) { | 39 | if (!(sb->s_flags & MS_RDONLY)) { |
39 | sbi->s_ms->s_state = sbi->s_mount_state; | 40 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ |
41 | sbi->s_ms->s_state = sbi->s_mount_state; | ||
40 | mark_buffer_dirty(sbi->s_sbh); | 42 | mark_buffer_dirty(sbi->s_sbh); |
41 | } | 43 | } |
42 | for (i = 0; i < sbi->s_imap_blocks; i++) | 44 | for (i = 0; i < sbi->s_imap_blocks; i++) |
@@ -93,7 +95,7 @@ static void destroy_inodecache(void) | |||
93 | kmem_cache_destroy(minix_inode_cachep); | 95 | kmem_cache_destroy(minix_inode_cachep); |
94 | } | 96 | } |
95 | 97 | ||
96 | static struct super_operations minix_sops = { | 98 | static const struct super_operations minix_sops = { |
97 | .alloc_inode = minix_alloc_inode, | 99 | .alloc_inode = minix_alloc_inode, |
98 | .destroy_inode = minix_destroy_inode, | 100 | .destroy_inode = minix_destroy_inode, |
99 | .read_inode = minix_read_inode, | 101 | .read_inode = minix_read_inode, |
@@ -117,12 +119,17 @@ static int minix_remount (struct super_block * sb, int * flags, char * data) | |||
117 | !(sbi->s_mount_state & MINIX_VALID_FS)) | 119 | !(sbi->s_mount_state & MINIX_VALID_FS)) |
118 | return 0; | 120 | return 0; |
119 | /* Mounting a rw partition read-only. */ | 121 | /* Mounting a rw partition read-only. */ |
120 | ms->s_state = sbi->s_mount_state; | 122 | if (sbi->s_version != MINIX_V3) |
123 | ms->s_state = sbi->s_mount_state; | ||
121 | mark_buffer_dirty(sbi->s_sbh); | 124 | mark_buffer_dirty(sbi->s_sbh); |
122 | } else { | 125 | } else { |
123 | /* Mount a partition which is read-only, read-write. */ | 126 | /* Mount a partition which is read-only, read-write. */ |
124 | sbi->s_mount_state = ms->s_state; | 127 | if (sbi->s_version != MINIX_V3) { |
125 | ms->s_state &= ~MINIX_VALID_FS; | 128 | sbi->s_mount_state = ms->s_state; |
129 | ms->s_state &= ~MINIX_VALID_FS; | ||
130 | } else { | ||
131 | sbi->s_mount_state = MINIX_VALID_FS; | ||
132 | } | ||
126 | mark_buffer_dirty(sbi->s_sbh); | 133 | mark_buffer_dirty(sbi->s_sbh); |
127 | 134 | ||
128 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) | 135 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) |
@@ -140,7 +147,8 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
140 | struct buffer_head *bh; | 147 | struct buffer_head *bh; |
141 | struct buffer_head **map; | 148 | struct buffer_head **map; |
142 | struct minix_super_block *ms; | 149 | struct minix_super_block *ms; |
143 | int i, block; | 150 | struct minix3_super_block *m3s = NULL; |
151 | unsigned long i, block; | ||
144 | struct inode *root_inode; | 152 | struct inode *root_inode; |
145 | struct minix_sb_info *sbi; | 153 | struct minix_sb_info *sbi; |
146 | 154 | ||
@@ -192,6 +200,22 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
192 | sbi->s_dirsize = 32; | 200 | sbi->s_dirsize = 32; |
193 | sbi->s_namelen = 30; | 201 | sbi->s_namelen = 30; |
194 | sbi->s_link_max = MINIX2_LINK_MAX; | 202 | sbi->s_link_max = MINIX2_LINK_MAX; |
203 | } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { | ||
204 | m3s = (struct minix3_super_block *) bh->b_data; | ||
205 | s->s_magic = m3s->s_magic; | ||
206 | sbi->s_imap_blocks = m3s->s_imap_blocks; | ||
207 | sbi->s_zmap_blocks = m3s->s_zmap_blocks; | ||
208 | sbi->s_firstdatazone = m3s->s_firstdatazone; | ||
209 | sbi->s_log_zone_size = m3s->s_log_zone_size; | ||
210 | sbi->s_max_size = m3s->s_max_size; | ||
211 | sbi->s_ninodes = m3s->s_ninodes; | ||
212 | sbi->s_nzones = m3s->s_zones; | ||
213 | sbi->s_dirsize = 64; | ||
214 | sbi->s_namelen = 60; | ||
215 | sbi->s_version = MINIX_V3; | ||
216 | sbi->s_link_max = MINIX2_LINK_MAX; | ||
217 | sbi->s_mount_state = MINIX_VALID_FS; | ||
218 | sb_set_blocksize(s, m3s->s_blocksize); | ||
195 | } else | 219 | } else |
196 | goto out_no_fs; | 220 | goto out_no_fs; |
197 | 221 | ||
@@ -236,7 +260,8 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
236 | s->s_root->d_op = &minix_dentry_operations; | 260 | s->s_root->d_op = &minix_dentry_operations; |
237 | 261 | ||
238 | if (!(s->s_flags & MS_RDONLY)) { | 262 | if (!(s->s_flags & MS_RDONLY)) { |
239 | ms->s_state &= ~MINIX_VALID_FS; | 263 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ |
264 | ms->s_state &= ~MINIX_VALID_FS; | ||
240 | mark_buffer_dirty(bh); | 265 | mark_buffer_dirty(bh); |
241 | } | 266 | } |
242 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) | 267 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) |
@@ -278,8 +303,8 @@ out_illegal_sb: | |||
278 | 303 | ||
279 | out_no_fs: | 304 | out_no_fs: |
280 | if (!silent) | 305 | if (!silent) |
281 | printk("VFS: Can't find a Minix or Minix V2 filesystem " | 306 | printk("VFS: Can't find a Minix filesystem V1 | V2 | V3 " |
282 | "on device %s\n", s->s_id); | 307 | "on device %s.\n", s->s_id); |
283 | out_release: | 308 | out_release: |
284 | brelse(bh); | 309 | brelse(bh); |
285 | goto out; | 310 | goto out; |
@@ -344,7 +369,7 @@ static const struct address_space_operations minix_aops = { | |||
344 | .bmap = minix_bmap | 369 | .bmap = minix_bmap |
345 | }; | 370 | }; |
346 | 371 | ||
347 | static struct inode_operations minix_symlink_inode_operations = { | 372 | static const struct inode_operations minix_symlink_inode_operations = { |
348 | .readlink = generic_readlink, | 373 | .readlink = generic_readlink, |
349 | .follow_link = page_follow_link_light, | 374 | .follow_link = page_follow_link_light, |
350 | .put_link = page_put_link, | 375 | .put_link = page_put_link, |
@@ -537,12 +562,14 @@ int minix_sync_inode(struct inode * inode) | |||
537 | 562 | ||
538 | int minix_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 563 | int minix_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
539 | { | 564 | { |
565 | struct inode *dir = dentry->d_parent->d_inode; | ||
566 | struct super_block *sb = dir->i_sb; | ||
540 | generic_fillattr(dentry->d_inode, stat); | 567 | generic_fillattr(dentry->d_inode, stat); |
541 | if (INODE_VERSION(dentry->d_inode) == MINIX_V1) | 568 | if (INODE_VERSION(dentry->d_inode) == MINIX_V1) |
542 | stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size); | 569 | stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size, sb); |
543 | else | 570 | else |
544 | stat->blocks = (BLOCK_SIZE / 512) * V2_minix_blocks(stat->size); | 571 | stat->blocks = (sb->s_blocksize / 512) * V2_minix_blocks(stat->size, sb); |
545 | stat->blksize = BLOCK_SIZE; | 572 | stat->blksize = sb->s_blocksize; |
546 | return 0; | 573 | return 0; |
547 | } | 574 | } |
548 | 575 | ||