11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/fs/minix/inode.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6f762dd68218665bb87d4e4a0eeac86fde7530293Gertjan van Wingerde * Copyright (C) 1996 Gertjan van Wingerde 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Minix V2 fs support. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified for 680x0 by Andreas Schwab 10939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer * Updated to filesystem version 3 by Daniel Aragones 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "minix.h" 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/buffer_head.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/highuid.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vfs.h> 20a9185b41a4f84971b930c519f0c63bd450c4810dChristoph Hellwig#include <linux/writeback.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22a9185b41a4f84971b930c519f0c63bd450c4810dChristoph Hellwigstatic int minix_write_inode(struct inode *inode, 23a9185b41a4f84971b930c519f0c63bd450c4810dChristoph Hellwig struct writeback_control *wbc); 24726c334223180e3c0197cc980a432681370d4bafDavid Howellsstatic int minix_statfs(struct dentry *dentry, struct kstatfs *buf); 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_remount (struct super_block * sb, int * flags, char * data); 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 275ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Virostatic void minix_evict_inode(struct inode *inode) 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2991b0abe36a7b2b3b02d7500925a5f8455334f0e5Johannes Weiner truncate_inode_pages_final(&inode->i_data); 305ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro if (!inode->i_nlink) { 315ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro inode->i_size = 0; 325ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro minix_truncate(inode); 335ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro } 345ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro invalidate_inode_buffers(inode); 35dbd5768f87ff6fb0a4fe09c4d7b6c4a24de99430Jan Kara clear_inode(inode); 365ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro if (!inode->i_nlink) 375ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro minix_free_inode(inode); 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void minix_put_super(struct super_block *sb) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi = minix_sb(sb); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sb->s_flags & MS_RDONLY)) { 46939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ 47939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_ms->s_state = sbi->s_mount_state; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_buffer_dirty(sbi->s_sbh); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sbi->s_imap_blocks; i++) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(sbi->s_imap[i]); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sbi->s_zmap_blocks; i++) 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(sbi->s_zmap[i]); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse (sbi->s_sbh); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sbi->s_imap); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sb->s_fs_info = NULL; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sbi); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60e18b890bb0881bbab6f4f1a6cd20d9c60d66b003Christoph Lameterstatic struct kmem_cache * minix_inode_cachep; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct inode *minix_alloc_inode(struct super_block *sb) 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *ei; 65e94b1766097d53e6f3ccfb36c8baa562ffeda3fcChristoph Lameter ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ei) 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &ei->vfs_inode; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Pigginstatic void minix_i_callback(struct rcu_head *head) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 73fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Piggin struct inode *inode = container_of(head, struct inode, i_rcu); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kmem_cache_free(minix_inode_cachep, minix_i(inode)); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 77fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Pigginstatic void minix_destroy_inode(struct inode *inode) 78fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Piggin{ 79fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Piggin call_rcu(&inode->i_rcu, minix_i_callback); 80fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Piggin} 81fa0d7e3de6d6fc5004ad9dea0dd6b286af8f03e9Nick Piggin 8251cc50685a4275c6a02653670af9f108a64e01cfAlexey Dobriyanstatic void init_once(void *foo) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *ei = (struct minix_inode_info *) foo; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 86a35afb830f8d71ec211531aeb9a621b09a2efb39Christoph Lameter inode_init_once(&ei->vfs_inode); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8820c2df83d25c6a95affe6157a4c9cac4cf5ffaacPaul Mundt 8984ee353df07e9beec200da44ac70f583449fffb1Fabian Frederickstatic int __init init_inodecache(void) 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_inode_cachep = kmem_cache_create("minix_inode_cache", 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct minix_inode_info), 93fffb60f93ce5880aade88e01d7133b52a4879710Paul Jackson 0, (SLAB_RECLAIM_ACCOUNT| 94fffb60f93ce5880aade88e01d7133b52a4879710Paul Jackson SLAB_MEM_SPREAD), 9520c2df83d25c6a95affe6157a4c9cac4cf5ffaacPaul Mundt init_once); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (minix_inode_cachep == NULL) 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void destroy_inodecache(void) 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1038c0a85377048b64c880e76ec7368904fe46d0b94Kirill A. Shutemov /* 1048c0a85377048b64c880e76ec7368904fe46d0b94Kirill A. Shutemov * Make sure all delayed rcu free inodes are flushed before we 1058c0a85377048b64c880e76ec7368904fe46d0b94Kirill A. Shutemov * destroy cache. 1068c0a85377048b64c880e76ec7368904fe46d0b94Kirill A. Shutemov */ 1078c0a85377048b64c880e76ec7368904fe46d0b94Kirill A. Shutemov rcu_barrier(); 1081a1d92c10dd24bbdc28b3d6e2d03ec199dd3a65bAlexey Dobriyan kmem_cache_destroy(minix_inode_cachep); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111ee9b6d61a2a43c5952eb43283f8db284a4e70b8aJosef 'Jeff' Sipekstatic const struct super_operations minix_sops = { 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .alloc_inode = minix_alloc_inode, 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .destroy_inode = minix_destroy_inode, 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write_inode = minix_write_inode, 1155ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro .evict_inode = minix_evict_inode, 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .put_super = minix_put_super, 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .statfs = minix_statfs, 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .remount_fs = minix_remount, 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_remount (struct super_block * sb, int * flags, char * data) 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info * sbi = minix_sb(sb); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_super_block * ms; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12602b9984d640873b7b3809e63f81a0d7e13496886Theodore Ts'o sync_filesystem(sb); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms = sbi->s_ms; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*flags & MS_RDONLY) { 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ms->s_state & MINIX_VALID_FS || 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds !(sbi->s_mount_state & MINIX_VALID_FS)) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Mounting a rw partition read-only. */ 135939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version != MINIX_V3) 136939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer ms->s_state = sbi->s_mount_state; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_buffer_dirty(sbi->s_sbh); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Mount a partition which is read-only, read-write. */ 140939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer if (sbi->s_version != MINIX_V3) { 141939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_mount_state = ms->s_state; 142939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer ms->s_state &= ~MINIX_VALID_FS; 143939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else { 144939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_mount_state = MINIX_VALID_FS; 145939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_buffer_dirty(sbi->s_sbh); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sbi->s_mount_state & MINIX_VALID_FS)) 14911b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko printk("MINIX-fs warning: remounting unchecked fs, " 15011b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko "running fsck is recommended\n"); 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if ((sbi->s_mount_state & MINIX_ERROR_FS)) 15211b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko printk("MINIX-fs warning: remounting fs with errors, " 15311b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko "running fsck is recommended\n"); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_fill_super(struct super_block *s, void *data, int silent) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head *bh; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head **map; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_super_block *ms; 163939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer struct minix3_super_block *m3s = NULL; 164939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer unsigned long i, block; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *root_inode; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_sb_info *sbi; 167a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells int ret = -EINVAL; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 169f8314dc60ccba7e41f425048c4160dc7f63377d5Panagiotis Issaris sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sbi) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s->s_fs_info = sbi; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1742ecd05ae68a903761e736e9e0aca40d6ace4319eAlexey Dobriyan BUILD_BUG_ON(32 != sizeof (struct minix_inode)); 1752ecd05ae68a903761e736e9e0aca40d6ace4319eAlexey Dobriyan BUILD_BUG_ON(64 != sizeof(struct minix2_inode)); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sb_set_blocksize(s, BLOCK_SIZE)) 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_bad_hblock; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bh = sb_bread(s, 1))) 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_bad_sb; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms = (struct minix_super_block *) bh->b_data; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_ms = ms; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_sbh = bh; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_mount_state = ms->s_state; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_ninodes = ms->s_ninodes; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_nzones = ms->s_nzones; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_imap_blocks = ms->s_imap_blocks; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_zmap_blocks = ms->s_zmap_blocks; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_firstdatazone = ms->s_firstdatazone; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_log_zone_size = ms->s_log_zone_size; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_max_size = ms->s_max_size; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s->s_magic = ms->s_magic; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (s->s_magic == MINIX_SUPER_MAGIC) { 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_version = MINIX_V1; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_dirsize = 16; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_namelen = 14; 1998de52778798fe39660a8d6b26f290e0c93202761Al Viro s->s_max_links = MINIX_LINK_MAX; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (s->s_magic == MINIX_SUPER_MAGIC2) { 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_version = MINIX_V1; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_dirsize = 32; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_namelen = 30; 2048de52778798fe39660a8d6b26f290e0c93202761Al Viro s->s_max_links = MINIX_LINK_MAX; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (s->s_magic == MINIX2_SUPER_MAGIC) { 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_version = MINIX_V2; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_nzones = ms->s_zones; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_dirsize = 16; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_namelen = 14; 2108de52778798fe39660a8d6b26f290e0c93202761Al Viro s->s_max_links = MINIX2_LINK_MAX; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (s->s_magic == MINIX2_SUPER_MAGIC2) { 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_version = MINIX_V2; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_nzones = ms->s_zones; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_dirsize = 32; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_namelen = 30; 2168de52778798fe39660a8d6b26f290e0c93202761Al Viro s->s_max_links = MINIX2_LINK_MAX; 217939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { 218939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer m3s = (struct minix3_super_block *) bh->b_data; 219939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer s->s_magic = m3s->s_magic; 220939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_imap_blocks = m3s->s_imap_blocks; 221939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_zmap_blocks = m3s->s_zmap_blocks; 222939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_firstdatazone = m3s->s_firstdatazone; 223939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_log_zone_size = m3s->s_log_zone_size; 224939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_max_size = m3s->s_max_size; 225939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_ninodes = m3s->s_ninodes; 226939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_nzones = m3s->s_zones; 227939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_dirsize = 64; 228939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_namelen = 60; 229939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_version = MINIX_V3; 230939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sbi->s_mount_state = MINIX_VALID_FS; 231939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer sb_set_blocksize(s, m3s->s_blocksize); 2328de52778798fe39660a8d6b26f290e0c93202761Al Viro s->s_max_links = MINIX2_LINK_MAX; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_no_fs; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocate the buffer map to keep the superblock small. 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 239f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0) 240f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer goto out_illegal_sb; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh); 242f8314dc60ccba7e41f425048c4160dc7f63377d5Panagiotis Issaris map = kzalloc(i, GFP_KERNEL); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!map) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_no_map; 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_imap = &map[0]; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sbi->s_zmap = &map[sbi->s_imap_blocks]; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block=2; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0 ; i < sbi->s_imap_blocks ; i++) { 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sbi->s_imap[i]=sb_bread(s, block))) 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_no_bitmap; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block++; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0 ; i < sbi->s_zmap_blocks ; i++) { 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sbi->s_zmap[i]=sb_bread(s, block))) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_no_bitmap; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block++; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_set_bit(0,sbi->s_imap[0]->b_data); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_set_bit(0,sbi->s_zmap[0]->b_data); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 263016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer /* Apparently minix can create filesystems that allocate more blocks for 264016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer * the bitmaps than needed. We simply ignore that, but verify it didn't 265016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer * create one with not enough blocks and bail out if so. 266016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer */ 267016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize); 268016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer if (sbi->s_imap_blocks < block) { 269016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer printk("MINIX-fs: file system does not have enough " 2706d6747f85314687f72012ae85cde401db531e130Qi Yong "imap blocks allocated. Refusing to mount.\n"); 271ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro goto out_no_bitmap; 272016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer } 273016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer 274016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer block = minix_blocks_needed( 2756d6747f85314687f72012ae85cde401db531e130Qi Yong (sbi->s_nzones - sbi->s_firstdatazone + 1), 276016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer s->s_blocksize); 277016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer if (sbi->s_zmap_blocks < block) { 278016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer printk("MINIX-fs: file system does not have enough " 279016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer "zmap blocks allocated. Refusing to mount.\n"); 280ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro goto out_no_bitmap; 281ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro } 282ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro 283ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro /* set up enough so that it can read an inode */ 284ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro s->s_op = &minix_sops; 285ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro root_inode = minix_iget(s, MINIX_ROOT_INO); 286ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro if (IS_ERR(root_inode)) { 287ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro ret = PTR_ERR(root_inode); 288ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro goto out_no_root; 289016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer } 290016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer 291d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro ret = -ENOMEM; 292ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro s->s_root = d_make_root(root_inode); 293d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro if (!s->s_root) 294ca85c07809ca19de3391cb79ee1198f3dd91fa8dAl Viro goto out_no_root; 295d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro 296d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro if (!(s->s_flags & MS_RDONLY)) { 297d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ 298d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro ms->s_state &= ~MINIX_VALID_FS; 299d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro mark_buffer_dirty(bh); 300d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro } 301d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro if (!(sbi->s_mount_state & MINIX_VALID_FS)) 302d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro printk("MINIX-fs: mounting unchecked file system, " 303d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro "running fsck is recommended\n"); 304d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro else if (sbi->s_mount_state & MINIX_ERROR_FS) 305d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro printk("MINIX-fs: mounting file system with errors, " 306d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro "running fsck is recommended\n"); 307d6042eac44b54dc5c7cb839175eb51dfd03d7633Al Viro 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_no_root: 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!silent) 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("MINIX-fs: get root inode failed\n"); 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_freemap; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_no_bitmap: 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("MINIX-fs: bad superblock or unable to read bitmaps\n"); 317f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwerout_freemap: 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sbi->s_imap_blocks; i++) 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(sbi->s_imap[i]); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < sbi->s_zmap_blocks; i++) 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(sbi->s_zmap[i]); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sbi->s_imap); 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_release; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_no_map: 326a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells ret = -ENOMEM; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!silent) 32811b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko printk("MINIX-fs: can't allocate map\n"); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_release; 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwerout_illegal_sb: 332f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer if (!silent) 333f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer printk("MINIX-fs: bad superblock\n"); 334f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer goto out_release; 335f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwer 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_no_fs: 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!silent) 338939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer printk("VFS: Can't find a Minix filesystem V1 | V2 | V3 " 339939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer "on device %s.\n", s->s_id); 340f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwerout_release: 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(bh); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_bad_hblock: 34511b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko printk("MINIX-fs: blocksize too small for device\n"); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_bad_sb: 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("MINIX-fs: unable to read superblock\n"); 350f5fb09fa3392ad43fbcfc2f4580752f383ab5996Andries Brouwerout: 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s->s_fs_info = NULL; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sbi); 353a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return ret; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 356726c334223180e3c0197cc980a432681370d4bafDavid Howellsstatic int minix_statfs(struct dentry *dentry, struct kstatfs *buf) 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 358054475d2af2640a6d6cb83b528512c7b49eef9caColy Li struct super_block *sb = dentry->d_sb; 359054475d2af2640a6d6cb83b528512c7b49eef9caColy Li struct minix_sb_info *sbi = minix_sb(sb); 360054475d2af2640a6d6cb83b528512c7b49eef9caColy Li u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 361054475d2af2640a6d6cb83b528512c7b49eef9caColy Li buf->f_type = sb->s_magic; 362054475d2af2640a6d6cb83b528512c7b49eef9caColy Li buf->f_bsize = sb->s_blocksize; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size; 364016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer buf->f_bfree = minix_count_free_blocks(sb); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf->f_bavail = buf->f_bfree; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf->f_files = sbi->s_ninodes; 367016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer buf->f_ffree = minix_count_free_inodes(sb); 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf->f_namelen = sbi->s_namelen; 369054475d2af2640a6d6cb83b528512c7b49eef9caColy Li buf->f_fsid.val[0] = (u32)id; 370054475d2af2640a6d6cb83b528512c7b49eef9caColy Li buf->f_fsid.val[1] = (u32)(id >> 32); 371054475d2af2640a6d6cb83b528512c7b49eef9caColy Li 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_get_block(struct inode *inode, sector_t block, 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head *bh_result, int create) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INODE_VERSION(inode) == MINIX_V1) 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return V1_minix_get_block(inode, block, bh_result, create); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return V2_minix_get_block(inode, block, bh_result, create); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_writepage(struct page *page, struct writeback_control *wbc) 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return block_write_full_page(page, minix_get_block, wbc); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3884a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int minix_readpage(struct file *file, struct page *page) 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return block_read_full_page(page,minix_get_block); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3934a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 394f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwigint minix_prepare_chunk(struct page *page, loff_t pos, unsigned len) 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3966e1db88d536adcbbfe562b2d4b7d6425784fff12Christoph Hellwig return __block_write_begin(page, pos, len, minix_get_block); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3984a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 3997fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornellistatic void minix_write_failed(struct address_space *mapping, loff_t to) 4007fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli{ 4017fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli struct inode *inode = mapping->host; 4027fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli 4037fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli if (to > inode->i_size) { 4047caef26767c1727d7abfbbbfbe8b2bb473430d48Kirill A. Shutemov truncate_pagecache(inode, inode->i_size); 4057fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli minix_truncate(inode); 4067fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli } 4077fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli} 4087fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli 4094a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Pigginstatic int minix_write_begin(struct file *file, struct address_space *mapping, 4104a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin loff_t pos, unsigned len, unsigned flags, 4114a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin struct page **pagep, void **fsdata) 4124a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin{ 413155130a4f7848b1aac439cab6bda1a175507c71cChristoph Hellwig int ret; 414155130a4f7848b1aac439cab6bda1a175507c71cChristoph Hellwig 415155130a4f7848b1aac439cab6bda1a175507c71cChristoph Hellwig ret = block_write_begin(mapping, pos, len, flags, pagep, 416f4e420dc423148fba637af1ab618fa8896dfb2d6Christoph Hellwig minix_get_block); 4177fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli if (unlikely(ret)) 4187fc7cd00f616e38973fe3acd0dc7e473da94c52eMarco Stornelli minix_write_failed(mapping, pos + len); 419155130a4f7848b1aac439cab6bda1a175507c71cChristoph Hellwig 420155130a4f7848b1aac439cab6bda1a175507c71cChristoph Hellwig return ret; 4214a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin} 4224a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic sector_t minix_bmap(struct address_space *mapping, sector_t block) 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return generic_block_bmap(mapping,block,minix_get_block); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4274a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin 428f5e54d6e53a20cef45af7499e86164f0e0d16bb2Christoph Hellwigstatic const struct address_space_operations minix_aops = { 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readpage = minix_readpage, 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .writepage = minix_writepage, 4314a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin .write_begin = minix_write_begin, 4324a66af9eaa9531372cfcb9e20103ed147c729ff9Nick Piggin .write_end = generic_write_end, 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .bmap = minix_bmap 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43692e1d5be91a0e3ffa5c4697eeb09b2aa22792122Arjan van de Venstatic const struct inode_operations minix_symlink_inode_operations = { 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .readlink = generic_readlink, 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .follow_link = page_follow_link_light, 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .put_link = page_put_link, 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .getattr = minix_getattr, 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid minix_set_inode(struct inode *inode, dev_t rdev) 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (S_ISREG(inode->i_mode)) { 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_op = &minix_file_inode_operations; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_fop = &minix_file_operations; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mapping->a_ops = &minix_aops; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (S_ISDIR(inode->i_mode)) { 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_op = &minix_dir_inode_operations; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_fop = &minix_dir_operations; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mapping->a_ops = &minix_aops; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (S_ISLNK(inode->i_mode)) { 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_op = &minix_symlink_inode_operations; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mapping->a_ops = &minix_aops; 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_special_inode(inode, inode->i_mode, rdev); 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The minix V1 function to read an inode. 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 463a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howellsstatic struct inode *V1_minix_iget(struct inode *inode) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head * bh; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode * raw_inode; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *minix_inode = minix_i(inode); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!raw_inode) { 472a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells iget_failed(inode); 473a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return ERR_PTR(-EIO); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mode = raw_inode->i_mode; 476f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman i_uid_write(inode, raw_inode->i_uid); 477f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman i_gid_write(inode, raw_inode->i_gid); 478bfe8684869601dacfcb2cd69ef8cfd9045f62170Miklos Szeredi set_nlink(inode, raw_inode->i_nlinks); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_size = raw_inode->i_size; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = raw_inode->i_time; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mtime.tv_nsec = 0; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_atime.tv_nsec = 0; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_ctime.tv_nsec = 0; 484ba52de123d454b57369f291348266d86f4b35070Theodore Ts'o inode->i_blocks = 0; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 9; i++) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_inode->u.i1_data[i] = raw_inode->i_zone[i]; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0])); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(bh); 489a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells unlock_new_inode(inode); 490a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return inode; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The minix V2 function to read an inode. 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 496a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howellsstatic struct inode *V2_minix_iget(struct inode *inode) 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head * bh; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix2_inode * raw_inode; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *minix_inode = minix_i(inode); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!raw_inode) { 505a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells iget_failed(inode); 506a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return ERR_PTR(-EIO); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mode = raw_inode->i_mode; 509f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman i_uid_write(inode, raw_inode->i_uid); 510f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman i_gid_write(inode, raw_inode->i_gid); 511bfe8684869601dacfcb2cd69ef8cfd9045f62170Miklos Szeredi set_nlink(inode, raw_inode->i_nlinks); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_size = raw_inode->i_size; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mtime.tv_sec = raw_inode->i_mtime; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_atime.tv_sec = raw_inode->i_atime; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_ctime.tv_sec = raw_inode->i_ctime; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_mtime.tv_nsec = 0; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_atime.tv_nsec = 0; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_ctime.tv_nsec = 0; 519ba52de123d454b57369f291348266d86f4b35070Theodore Ts'o inode->i_blocks = 0; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 10; i++) 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_inode->u.i2_data[i] = raw_inode->i_zone[i]; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0])); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse(bh); 524a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells unlock_new_inode(inode); 525a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return inode; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The global function to read an inode. 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 531a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howellsstruct inode *minix_iget(struct super_block *sb, unsigned long ino) 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 533a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells struct inode *inode; 534a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells 535a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells inode = iget_locked(sb, ino); 536a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells if (!inode) 537a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return ERR_PTR(-ENOMEM); 538a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells if (!(inode->i_state & I_NEW)) 539a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return inode; 540a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INODE_VERSION(inode) == MINIX_V1) 542a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return V1_minix_iget(inode); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 544a90a088021f8f1e9a9cd83f06ac90e1f3aada4d4David Howells return V2_minix_iget(inode); 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The minix V1 function to synchronize an inode. 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct buffer_head * V1_minix_update_inode(struct inode * inode) 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head * bh; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode * raw_inode; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *minix_inode = minix_i(inode); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!raw_inode) 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_mode = inode->i_mode; 561f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode)); 562f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode)); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_nlinks = inode->i_nlink; 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_size = inode->i_size; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_time = inode->i_mtime.tv_sec; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_zone[0] = old_encode_dev(inode->i_rdev); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else for (i = 0; i < 9; i++) 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_zone[i] = minix_inode->u.i1_data[i]; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_buffer_dirty(bh); 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bh; 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The minix V2 function to synchronize an inode. 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct buffer_head * V2_minix_update_inode(struct inode * inode) 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head * bh; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix2_inode * raw_inode; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct minix_inode_info *minix_inode = minix_i(inode); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!raw_inode) 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_mode = inode->i_mode; 588f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode)); 589f303bdc55e9e74890eadc836c1edd8b5c21a7b89Eric W. Biederman raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode)); 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_nlinks = inode->i_nlink; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_size = inode->i_size; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_mtime = inode->i_mtime.tv_sec; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_atime = inode->i_atime.tv_sec; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_ctime = inode->i_ctime.tv_sec; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_zone[0] = old_encode_dev(inode->i_rdev); 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else for (i = 0; i < 10; i++) 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_inode->i_zone[i] = minix_inode->u.i2_data[i]; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mark_buffer_dirty(bh); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bh; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 603a9185b41a4f84971b930c519f0c63bd450c4810dChristoph Hellwigstatic int minix_write_inode(struct inode *inode, struct writeback_control *wbc) 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buffer_head *bh; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6080d7916d7e985da52cdd2989c900485e17b035972Al Viro if (INODE_VERSION(inode) == MINIX_V1) 6090d7916d7e985da52cdd2989c900485e17b035972Al Viro bh = V1_minix_update_inode(inode); 6100d7916d7e985da52cdd2989c900485e17b035972Al Viro else 6110d7916d7e985da52cdd2989c900485e17b035972Al Viro bh = V2_minix_update_inode(inode); 6120d7916d7e985da52cdd2989c900485e17b035972Al Viro if (!bh) 6130d7916d7e985da52cdd2989c900485e17b035972Al Viro return -EIO; 614a9185b41a4f84971b930c519f0c63bd450c4810dChristoph Hellwig if (wbc->sync_mode == WB_SYNC_ALL && buffer_dirty(bh)) { 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sync_dirty_buffer(bh); 6160d7916d7e985da52cdd2989c900485e17b035972Al Viro if (buffer_req(bh) && !buffer_uptodate(bh)) { 61711b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko printk("IO error syncing minix inode [%s:%08lx]\n", 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds inode->i_sb->s_id, inode->i_ino); 6190d7916d7e985da52cdd2989c900485e17b035972Al Viro err = -EIO; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brelse (bh); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6282def9e4ec75e6771def66a07960dd516e119ab4cAl Viro struct super_block *sb = dentry->d_sb; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds generic_fillattr(dentry->d_inode, stat); 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INODE_VERSION(dentry->d_inode) == MINIX_V1) 631939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size, sb); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 633939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer stat->blocks = (sb->s_blocksize / 512) * V2_minix_blocks(stat->size, sb); 634939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer stat->blksize = sb->s_blocksize; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The function that is called for file truncation. 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid minix_truncate(struct inode * inode) 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (INODE_VERSION(inode) == MINIX_V1) 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds V1_minix_truncate(inode); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds V2_minix_truncate(inode); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651152a08366671080f27b32e0c411ad620c5f88b57Al Virostatic struct dentry *minix_mount(struct file_system_type *fs_type, 652152a08366671080f27b32e0c411ad620c5f88b57Al Viro int flags, const char *dev_name, void *data) 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 654152a08366671080f27b32e0c411ad620c5f88b57Al Viro return mount_bdev(fs_type, flags, dev_name, data, minix_fill_super); 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct file_system_type minix_fs_type = { 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "minix", 660152a08366671080f27b32e0c411ad620c5f88b57Al Viro .mount = minix_mount, 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .kill_sb = kill_block_super, 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fs_flags = FS_REQUIRES_DEV, 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 6647f78e0351394052e1a6293e175825eb5c7869507Eric W. BiedermanMODULE_ALIAS_FS("minix"); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_minix_fs(void) 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = init_inodecache(); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out1; 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = register_filesystem(&minix_fs_type); 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds destroy_inodecache(); 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout1: 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit exit_minix_fs(void) 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_filesystem(&minix_fs_type); 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds destroy_inodecache(); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(init_minix_fs) 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(exit_minix_fs) 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691