aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bfs/inode.c
diff options
context:
space:
mode:
authorAndrew Stribblehill <a.d.stribblehill@durham.ac.uk>2005-09-09 16:02:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:32 -0400
commitfac92becdaecff64dd91daab0292c5131de92f0d (patch)
tree6c91bdbbe527682813d7c27ed13bdb0531298146 /fs/bfs/inode.c
parent383f2835eb9afb723af71850037b2f074ac9db60 (diff)
[PATCH] bfs: fix endianness, signedness; add trivial bugfix
* Makes BFS code endianness-clean. * Fixes some signedness warnings. * Fixes a problem in fs/bfs/inode.c:164 where inodes not synced to disk don't get fully marked as clean. Here's how to reproduce it: # mount -o loop -t bfs /bfs.img /mnt # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 1 47 3% /mnt # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 5 508 1% /mnt # cp 60k-archive.zip /mnt/mt.zip # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 65 447 13% /mnt # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 2 46 5% /mnt # rm /mnt/mt.zip # echo $? 0 [If the unlink happens before the buffers flush, the following happens:] # df -i /mnt Filesystem Inodes IUsed IFree IUse% Mounted on /bfs.img 48 2 46 5% /mnt # df -k /mnt Filesystem 1K-blocks Used Available Use% Mounted on /bfs.img 512 65 447 13% /mnt fs/bfs/bfs.h | 1 Signed-off-by: Andrew Stribblehill <ads@wompom.org> Cc: <tigran@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r--fs/bfs/inode.c102
1 files changed, 55 insertions, 47 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 628c2c1a7d7e..c7b39aa279d7 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -3,6 +3,8 @@
3 * BFS superblock and inode operations. 3 * BFS superblock and inode operations.
4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> 4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. 5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
6 *
7 * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
6 */ 8 */
7 9
8#include <linux/module.h> 10#include <linux/module.h>
@@ -54,46 +56,50 @@ static void bfs_read_inode(struct inode * inode)
54 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; 56 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
55 di = (struct bfs_inode *)bh->b_data + off; 57 di = (struct bfs_inode *)bh->b_data + off;
56 58
57 inode->i_mode = 0x0000FFFF & di->i_mode; 59 inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
58 if (di->i_vtype == BFS_VDIR) { 60 if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
59 inode->i_mode |= S_IFDIR; 61 inode->i_mode |= S_IFDIR;
60 inode->i_op = &bfs_dir_inops; 62 inode->i_op = &bfs_dir_inops;
61 inode->i_fop = &bfs_dir_operations; 63 inode->i_fop = &bfs_dir_operations;
62 } else if (di->i_vtype == BFS_VREG) { 64 } else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
63 inode->i_mode |= S_IFREG; 65 inode->i_mode |= S_IFREG;
64 inode->i_op = &bfs_file_inops; 66 inode->i_op = &bfs_file_inops;
65 inode->i_fop = &bfs_file_operations; 67 inode->i_fop = &bfs_file_operations;
66 inode->i_mapping->a_ops = &bfs_aops; 68 inode->i_mapping->a_ops = &bfs_aops;
67 } 69 }
68 70
69 inode->i_uid = di->i_uid; 71 BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock);
70 inode->i_gid = di->i_gid; 72 BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock);
71 inode->i_nlink = di->i_nlink; 73 inode->i_uid = le32_to_cpu(di->i_uid);
74 inode->i_gid = le32_to_cpu(di->i_gid);
75 inode->i_nlink = le32_to_cpu(di->i_nlink);
72 inode->i_size = BFS_FILESIZE(di); 76 inode->i_size = BFS_FILESIZE(di);
73 inode->i_blocks = BFS_FILEBLOCKS(di); 77 inode->i_blocks = BFS_FILEBLOCKS(di);
78 if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks\n", inode->i_size, inode->i_blocks);
74 inode->i_blksize = PAGE_SIZE; 79 inode->i_blksize = PAGE_SIZE;
75 inode->i_atime.tv_sec = di->i_atime; 80 inode->i_atime.tv_sec = le32_to_cpu(di->i_atime);
76 inode->i_mtime.tv_sec = di->i_mtime; 81 inode->i_mtime.tv_sec = le32_to_cpu(di->i_mtime);
77 inode->i_ctime.tv_sec = di->i_ctime; 82 inode->i_ctime.tv_sec = le32_to_cpu(di->i_ctime);
78 inode->i_atime.tv_nsec = 0; 83 inode->i_atime.tv_nsec = 0;
79 inode->i_mtime.tv_nsec = 0; 84 inode->i_mtime.tv_nsec = 0;
80 inode->i_ctime.tv_nsec = 0; 85 inode->i_ctime.tv_nsec = 0;
81 BFS_I(inode)->i_dsk_ino = di->i_ino; /* can be 0 so we store a copy */ 86 BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */
82 BFS_I(inode)->i_sblock = di->i_sblock;
83 BFS_I(inode)->i_eblock = di->i_eblock;
84 87
85 brelse(bh); 88 brelse(bh);
86} 89}
87 90
88static int bfs_write_inode(struct inode * inode, int unused) 91static int bfs_write_inode(struct inode * inode, int unused)
89{ 92{
90 unsigned long ino = inode->i_ino; 93 unsigned int ino = (u16)inode->i_ino;
94 unsigned long i_sblock;
91 struct bfs_inode * di; 95 struct bfs_inode * di;
92 struct buffer_head * bh; 96 struct buffer_head * bh;
93 int block, off; 97 int block, off;
94 98
99 dprintf("ino=%08x\n", ino);
100
95 if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) { 101 if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
96 printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino); 102 printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
97 return -EIO; 103 return -EIO;
98 } 104 }
99 105
@@ -101,7 +107,7 @@ static int bfs_write_inode(struct inode * inode, int unused)
101 block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; 107 block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
102 bh = sb_bread(inode->i_sb, block); 108 bh = sb_bread(inode->i_sb, block);
103 if (!bh) { 109 if (!bh) {
104 printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); 110 printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino);
105 unlock_kernel(); 111 unlock_kernel();
106 return -EIO; 112 return -EIO;
107 } 113 }
@@ -109,24 +115,26 @@ static int bfs_write_inode(struct inode * inode, int unused)
109 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; 115 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
110 di = (struct bfs_inode *)bh->b_data + off; 116 di = (struct bfs_inode *)bh->b_data + off;
111 117
112 if (inode->i_ino == BFS_ROOT_INO) 118 if (ino == BFS_ROOT_INO)
113 di->i_vtype = BFS_VDIR; 119 di->i_vtype = cpu_to_le32(BFS_VDIR);
114 else 120 else
115 di->i_vtype = BFS_VREG; 121 di->i_vtype = cpu_to_le32(BFS_VREG);
116 122
117 di->i_ino = inode->i_ino; 123 di->i_ino = cpu_to_le16(ino);
118 di->i_mode = inode->i_mode; 124 di->i_mode = cpu_to_le32(inode->i_mode);
119 di->i_uid = inode->i_uid; 125 di->i_uid = cpu_to_le32(inode->i_uid);
120 di->i_gid = inode->i_gid; 126 di->i_gid = cpu_to_le32(inode->i_gid);
121 di->i_nlink = inode->i_nlink; 127 di->i_nlink = cpu_to_le32(inode->i_nlink);
122 di->i_atime = inode->i_atime.tv_sec; 128 di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
123 di->i_mtime = inode->i_mtime.tv_sec; 129 di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
124 di->i_ctime = inode->i_ctime.tv_sec; 130 di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
125 di->i_sblock = BFS_I(inode)->i_sblock; 131 i_sblock = BFS_I(inode)->i_sblock;
126 di->i_eblock = BFS_I(inode)->i_eblock; 132 di->i_sblock = cpu_to_le32(i_sblock);
127 di->i_eoffset = di->i_sblock * BFS_BSIZE + inode->i_size - 1; 133 di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
134 di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
128 135
129 mark_buffer_dirty(bh); 136 mark_buffer_dirty(bh);
137 dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di->i_ino),block,off);
130 brelse(bh); 138 brelse(bh);
131 unlock_kernel(); 139 unlock_kernel();
132 return 0; 140 return 0;
@@ -140,13 +148,14 @@ static void bfs_delete_inode(struct inode * inode)
140 int block, off; 148 int block, off;
141 struct super_block * s = inode->i_sb; 149 struct super_block * s = inode->i_sb;
142 struct bfs_sb_info * info = BFS_SB(s); 150 struct bfs_sb_info * info = BFS_SB(s);
151 struct bfs_inode_info * bi = BFS_I(inode);
143 152
144 dprintf("ino=%08lx\n", inode->i_ino); 153 dprintf("ino=%08lx\n", ino);
145 154
146 truncate_inode_pages(&inode->i_data, 0); 155 truncate_inode_pages(&inode->i_data, 0);
147 156
148 if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > info->si_lasti) { 157 if (ino < BFS_ROOT_INO || ino > info->si_lasti) {
149 printf("invalid ino=%08lx\n", inode->i_ino); 158 printf("invalid ino=%08lx\n", ino);
150 return; 159 return;
151 } 160 }
152 161
@@ -162,13 +171,13 @@ static void bfs_delete_inode(struct inode * inode)
162 return; 171 return;
163 } 172 }
164 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; 173 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
165 di = (struct bfs_inode *)bh->b_data + off; 174 di = (struct bfs_inode *) bh->b_data + off;
166 if (di->i_ino) { 175 if (bi->i_dsk_ino) {
167 info->si_freeb += BFS_FILEBLOCKS(di); 176 info->si_freeb += 1 + bi->i_eblock - bi->i_sblock;
168 info->si_freei++; 177 info->si_freei++;
169 clear_bit(di->i_ino, info->si_imap); 178 clear_bit(ino, info->si_imap);
170 dump_imap("delete_inode", s); 179 dump_imap("delete_inode", s);
171 } 180 }
172 di->i_ino = 0; 181 di->i_ino = 0;
173 di->i_sblock = 0; 182 di->i_sblock = 0;
174 mark_buffer_dirty(bh); 183 mark_buffer_dirty(bh);
@@ -274,14 +283,14 @@ static struct super_operations bfs_sops = {
274 283
275void dump_imap(const char *prefix, struct super_block * s) 284void dump_imap(const char *prefix, struct super_block * s)
276{ 285{
277#if 0 286#ifdef DEBUG
278 int i; 287 int i;
279 char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL); 288 char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
280 289
281 if (!tmpbuf) 290 if (!tmpbuf)
282 return; 291 return;
283 for (i=BFS_SB(s)->si_lasti; i>=0; i--) { 292 for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
284 if (i>PAGE_SIZE-100) break; 293 if (i > PAGE_SIZE-100) break;
285 if (test_bit(i, BFS_SB(s)->si_imap)) 294 if (test_bit(i, BFS_SB(s)->si_imap))
286 strcat(tmpbuf, "1"); 295 strcat(tmpbuf, "1");
287 else 296 else
@@ -297,7 +306,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
297 struct buffer_head * bh; 306 struct buffer_head * bh;
298 struct bfs_super_block * bfs_sb; 307 struct bfs_super_block * bfs_sb;
299 struct inode * inode; 308 struct inode * inode;
300 int i, imap_len; 309 unsigned i, imap_len;
301 struct bfs_sb_info * info; 310 struct bfs_sb_info * info;
302 311
303 info = kmalloc(sizeof(*info), GFP_KERNEL); 312 info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -312,19 +321,18 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
312 if(!bh) 321 if(!bh)
313 goto out; 322 goto out;
314 bfs_sb = (struct bfs_super_block *)bh->b_data; 323 bfs_sb = (struct bfs_super_block *)bh->b_data;
315 if (bfs_sb->s_magic != BFS_MAGIC) { 324 if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
316 if (!silent) 325 if (!silent)
317 printf("No BFS filesystem on %s (magic=%08x)\n", 326 printf("No BFS filesystem on %s (magic=%08x)\n",
318 s->s_id, bfs_sb->s_magic); 327 s->s_id, le32_to_cpu(bfs_sb->s_magic));
319 goto out; 328 goto out;
320 } 329 }
321 if (BFS_UNCLEAN(bfs_sb, s) && !silent) 330 if (BFS_UNCLEAN(bfs_sb, s) && !silent)
322 printf("%s is unclean, continuing\n", s->s_id); 331 printf("%s is unclean, continuing\n", s->s_id);
323 332
324 s->s_magic = BFS_MAGIC; 333 s->s_magic = BFS_MAGIC;
325 info->si_bfs_sb = bfs_sb;
326 info->si_sbh = bh; 334 info->si_sbh = bh;
327 info->si_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode) 335 info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode)
328 + BFS_ROOT_INO - 1; 336 + BFS_ROOT_INO - 1;
329 337
330 imap_len = info->si_lasti/8 + 1; 338 imap_len = info->si_lasti/8 + 1;
@@ -348,8 +356,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
348 goto out; 356 goto out;
349 } 357 }
350 358
351 info->si_blocks = (bfs_sb->s_end + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */ 359 info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
352 info->si_freeb = (bfs_sb->s_end + 1 - bfs_sb->s_start)>>BFS_BSIZE_BITS; 360 info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - cpu_to_le32(bfs_sb->s_start))>>BFS_BSIZE_BITS;
353 info->si_freei = 0; 361 info->si_freei = 0;
354 info->si_lf_eblk = 0; 362 info->si_lf_eblk = 0;
355 info->si_lf_sblk = 0; 363 info->si_lf_sblk = 0;