Commit d406f66ddb0d7491ddd53e4600c425d76a8a245f

Authored by Harvey Harrison
Committed by Linus Torvalds
1 parent 32be1d2232

omfs: sparse annotations

Missing cpu_to_be64 on some constant assignments.
fs/omfs/dir.c:107:16: warning: incorrect type in assignment (different base types)
fs/omfs/dir.c:107:16:    expected restricted __be64 [usertype] i_sibling
fs/omfs/dir.c:107:16:    got unsigned long long
fs/omfs/file.c:33:13: warning: incorrect type in assignment (different base types)
fs/omfs/file.c:33:13:    expected restricted __be64 [usertype] e_next
fs/omfs/file.c:33:13:    got unsigned long long
fs/omfs/file.c:36:24: warning: incorrect type in assignment (different base types)
fs/omfs/file.c:36:24:    expected restricted __be64 [usertype] e_cluster
fs/omfs/file.c:36:24:    got unsigned long long
fs/omfs/file.c:37:23: warning: incorrect type in assignment (different base types)
fs/omfs/file.c:37:23:    expected restricted __be64 [usertype] e_blocks
fs/omfs/file.c:37:23:    got unsigned long long

fs/omfs/bitmap.c:74:18: warning: incorrect type in argument 2 (different signedness)
fs/omfs/bitmap.c:74:18:    expected unsigned long volatile *addr
fs/omfs/bitmap.c:74:18:    got long *<noident>
fs/omfs/bitmap.c:77:20: warning: incorrect type in argument 2 (different signedness)
fs/omfs/bitmap.c:77:20:    expected unsigned long volatile *addr
fs/omfs/bitmap.c:77:20:    got long *<noident>
fs/omfs/bitmap.c:112:17: warning: incorrect type in argument 2 (different signedness)
fs/omfs/bitmap.c:112:17:    expected unsigned long volatile *addr
fs/omfs/bitmap.c:112:17:    got long *<noident>

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Acked-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 7 additions and 7 deletions Inline Diff

1 #include <linux/kernel.h> 1 #include <linux/kernel.h>
2 #include <linux/fs.h> 2 #include <linux/fs.h>
3 #include <linux/buffer_head.h> 3 #include <linux/buffer_head.h>
4 #include <asm/div64.h> 4 #include <asm/div64.h>
5 #include "omfs.h" 5 #include "omfs.h"
6 6
7 unsigned long omfs_count_free(struct super_block *sb) 7 unsigned long omfs_count_free(struct super_block *sb)
8 { 8 {
9 unsigned int i; 9 unsigned int i;
10 unsigned long sum = 0; 10 unsigned long sum = 0;
11 struct omfs_sb_info *sbi = OMFS_SB(sb); 11 struct omfs_sb_info *sbi = OMFS_SB(sb);
12 int nbits = sb->s_blocksize * 8; 12 int nbits = sb->s_blocksize * 8;
13 13
14 for (i = 0; i < sbi->s_imap_size; i++) 14 for (i = 0; i < sbi->s_imap_size; i++)
15 sum += nbits - bitmap_weight(sbi->s_imap[i], nbits); 15 sum += nbits - bitmap_weight(sbi->s_imap[i], nbits);
16 16
17 return sum; 17 return sum;
18 } 18 }
19 19
20 /* 20 /*
21 * Counts the run of zero bits starting at bit up to max. 21 * Counts the run of zero bits starting at bit up to max.
22 * It handles the case where a run might spill over a buffer. 22 * It handles the case where a run might spill over a buffer.
23 * Called with bitmap lock. 23 * Called with bitmap lock.
24 */ 24 */
25 static int count_run(unsigned long **addr, int nbits, 25 static int count_run(unsigned long **addr, int nbits,
26 int addrlen, int bit, int max) 26 int addrlen, int bit, int max)
27 { 27 {
28 int count = 0; 28 int count = 0;
29 int x; 29 int x;
30 30
31 for (; addrlen > 0; addrlen--, addr++) { 31 for (; addrlen > 0; addrlen--, addr++) {
32 x = find_next_bit(*addr, nbits, bit); 32 x = find_next_bit(*addr, nbits, bit);
33 count += x - bit; 33 count += x - bit;
34 34
35 if (x < nbits || count > max) 35 if (x < nbits || count > max)
36 return min(count, max); 36 return min(count, max);
37 37
38 bit = 0; 38 bit = 0;
39 } 39 }
40 return min(count, max); 40 return min(count, max);
41 } 41 }
42 42
43 /* 43 /*
44 * Sets or clears the run of count bits starting with bit. 44 * Sets or clears the run of count bits starting with bit.
45 * Called with bitmap lock. 45 * Called with bitmap lock.
46 */ 46 */
47 static int set_run(struct super_block *sb, int map, 47 static int set_run(struct super_block *sb, int map,
48 int nbits, int bit, int count, int set) 48 int nbits, int bit, int count, int set)
49 { 49 {
50 int i; 50 int i;
51 int err; 51 int err;
52 struct buffer_head *bh; 52 struct buffer_head *bh;
53 struct omfs_sb_info *sbi = OMFS_SB(sb); 53 struct omfs_sb_info *sbi = OMFS_SB(sb);
54 54
55 err = -ENOMEM; 55 err = -ENOMEM;
56 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); 56 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
57 if (!bh) 57 if (!bh)
58 goto out; 58 goto out;
59 59
60 for (i = 0; i < count; i++, bit++) { 60 for (i = 0; i < count; i++, bit++) {
61 if (bit >= nbits) { 61 if (bit >= nbits) {
62 bit = 0; 62 bit = 0;
63 map++; 63 map++;
64 64
65 mark_buffer_dirty(bh); 65 mark_buffer_dirty(bh);
66 brelse(bh); 66 brelse(bh);
67 bh = sb_bread(sb, 67 bh = sb_bread(sb,
68 clus_to_blk(sbi, sbi->s_bitmap_ino) + map); 68 clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
69 if (!bh) 69 if (!bh)
70 goto out; 70 goto out;
71 } 71 }
72 if (set) { 72 if (set) {
73 set_bit(bit, sbi->s_imap[map]); 73 set_bit(bit, sbi->s_imap[map]);
74 set_bit(bit, (long *) bh->b_data); 74 set_bit(bit, (unsigned long *)bh->b_data);
75 } else { 75 } else {
76 clear_bit(bit, sbi->s_imap[map]); 76 clear_bit(bit, sbi->s_imap[map]);
77 clear_bit(bit, (long *) bh->b_data); 77 clear_bit(bit, (unsigned long *)bh->b_data);
78 } 78 }
79 } 79 }
80 mark_buffer_dirty(bh); 80 mark_buffer_dirty(bh);
81 brelse(bh); 81 brelse(bh);
82 err = 0; 82 err = 0;
83 out: 83 out:
84 return err; 84 return err;
85 } 85 }
86 86
87 /* 87 /*
88 * Tries to allocate exactly one block. Returns true if sucessful. 88 * Tries to allocate exactly one block. Returns true if sucessful.
89 */ 89 */
90 int omfs_allocate_block(struct super_block *sb, u64 block) 90 int omfs_allocate_block(struct super_block *sb, u64 block)
91 { 91 {
92 struct buffer_head *bh; 92 struct buffer_head *bh;
93 struct omfs_sb_info *sbi = OMFS_SB(sb); 93 struct omfs_sb_info *sbi = OMFS_SB(sb);
94 int bits_per_entry = 8 * sb->s_blocksize; 94 int bits_per_entry = 8 * sb->s_blocksize;
95 int map, bit; 95 int map, bit;
96 int ret = 0; 96 int ret = 0;
97 u64 tmp; 97 u64 tmp;
98 98
99 tmp = block; 99 tmp = block;
100 bit = do_div(tmp, bits_per_entry); 100 bit = do_div(tmp, bits_per_entry);
101 map = tmp; 101 map = tmp;
102 102
103 mutex_lock(&sbi->s_bitmap_lock); 103 mutex_lock(&sbi->s_bitmap_lock);
104 if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map])) 104 if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map]))
105 goto out; 105 goto out;
106 106
107 if (sbi->s_bitmap_ino > 0) { 107 if (sbi->s_bitmap_ino > 0) {
108 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); 108 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
109 if (!bh) 109 if (!bh)
110 goto out; 110 goto out;
111 111
112 set_bit(bit, (long *) bh->b_data); 112 set_bit(bit, (unsigned long *)bh->b_data);
113 mark_buffer_dirty(bh); 113 mark_buffer_dirty(bh);
114 brelse(bh); 114 brelse(bh);
115 } 115 }
116 ret = 1; 116 ret = 1;
117 out: 117 out:
118 mutex_unlock(&sbi->s_bitmap_lock); 118 mutex_unlock(&sbi->s_bitmap_lock);
119 return ret; 119 return ret;
120 } 120 }
121 121
122 122
123 /* 123 /*
124 * Tries to allocate a set of blocks. The request size depends on the 124 * Tries to allocate a set of blocks. The request size depends on the
125 * type: for inodes, we must allocate sbi->s_mirrors blocks, and for file 125 * type: for inodes, we must allocate sbi->s_mirrors blocks, and for file
126 * blocks, we try to allocate sbi->s_clustersize, but can always get away 126 * blocks, we try to allocate sbi->s_clustersize, but can always get away
127 * with just one block. 127 * with just one block.
128 */ 128 */
129 int omfs_allocate_range(struct super_block *sb, 129 int omfs_allocate_range(struct super_block *sb,
130 int min_request, 130 int min_request,
131 int max_request, 131 int max_request,
132 u64 *return_block, 132 u64 *return_block,
133 int *return_size) 133 int *return_size)
134 { 134 {
135 struct omfs_sb_info *sbi = OMFS_SB(sb); 135 struct omfs_sb_info *sbi = OMFS_SB(sb);
136 int bits_per_entry = 8 * sb->s_blocksize; 136 int bits_per_entry = 8 * sb->s_blocksize;
137 int ret = 0; 137 int ret = 0;
138 int i, run, bit; 138 int i, run, bit;
139 139
140 mutex_lock(&sbi->s_bitmap_lock); 140 mutex_lock(&sbi->s_bitmap_lock);
141 for (i = 0; i < sbi->s_imap_size; i++) { 141 for (i = 0; i < sbi->s_imap_size; i++) {
142 bit = 0; 142 bit = 0;
143 while (bit < bits_per_entry) { 143 while (bit < bits_per_entry) {
144 bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry, 144 bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry,
145 bit); 145 bit);
146 146
147 if (bit == bits_per_entry) 147 if (bit == bits_per_entry)
148 break; 148 break;
149 149
150 run = count_run(&sbi->s_imap[i], bits_per_entry, 150 run = count_run(&sbi->s_imap[i], bits_per_entry,
151 sbi->s_imap_size-i, bit, max_request); 151 sbi->s_imap_size-i, bit, max_request);
152 152
153 if (run >= min_request) 153 if (run >= min_request)
154 goto found; 154 goto found;
155 bit += run; 155 bit += run;
156 } 156 }
157 } 157 }
158 ret = -ENOSPC; 158 ret = -ENOSPC;
159 goto out; 159 goto out;
160 160
161 found: 161 found:
162 *return_block = i * bits_per_entry + bit; 162 *return_block = i * bits_per_entry + bit;
163 *return_size = run; 163 *return_size = run;
164 ret = set_run(sb, i, bits_per_entry, bit, run, 1); 164 ret = set_run(sb, i, bits_per_entry, bit, run, 1);
165 165
166 out: 166 out:
167 mutex_unlock(&sbi->s_bitmap_lock); 167 mutex_unlock(&sbi->s_bitmap_lock);
168 return ret; 168 return ret;
169 } 169 }
170 170
171 /* 171 /*
172 * Clears count bits starting at a given block. 172 * Clears count bits starting at a given block.
173 */ 173 */
174 int omfs_clear_range(struct super_block *sb, u64 block, int count) 174 int omfs_clear_range(struct super_block *sb, u64 block, int count)
175 { 175 {
176 struct omfs_sb_info *sbi = OMFS_SB(sb); 176 struct omfs_sb_info *sbi = OMFS_SB(sb);
177 int bits_per_entry = 8 * sb->s_blocksize; 177 int bits_per_entry = 8 * sb->s_blocksize;
178 u64 tmp; 178 u64 tmp;
179 int map, bit, ret; 179 int map, bit, ret;
180 180
181 tmp = block; 181 tmp = block;
182 bit = do_div(tmp, bits_per_entry); 182 bit = do_div(tmp, bits_per_entry);
183 map = tmp; 183 map = tmp;
184 184
185 if (map >= sbi->s_imap_size) 185 if (map >= sbi->s_imap_size)
186 return 0; 186 return 0;
187 187
188 mutex_lock(&sbi->s_bitmap_lock); 188 mutex_lock(&sbi->s_bitmap_lock);
189 ret = set_run(sb, map, bits_per_entry, bit, count, 0); 189 ret = set_run(sb, map, bits_per_entry, bit, count, 0);
190 mutex_unlock(&sbi->s_bitmap_lock); 190 mutex_unlock(&sbi->s_bitmap_lock);
191 return ret; 191 return ret;
192 } 192 }
193 193
1 /* 1 /*
2 * OMFS (as used by RIO Karma) directory operations. 2 * OMFS (as used by RIO Karma) directory operations.
3 * Copyright (C) 2005 Bob Copeland <me@bobcopeland.com> 3 * Copyright (C) 2005 Bob Copeland <me@bobcopeland.com>
4 * Released under GPL v2. 4 * Released under GPL v2.
5 */ 5 */
6 6
7 #include <linux/fs.h> 7 #include <linux/fs.h>
8 #include <linux/ctype.h> 8 #include <linux/ctype.h>
9 #include <linux/buffer_head.h> 9 #include <linux/buffer_head.h>
10 #include "omfs.h" 10 #include "omfs.h"
11 11
12 static int omfs_hash(const char *name, int namelen, int mod) 12 static int omfs_hash(const char *name, int namelen, int mod)
13 { 13 {
14 int i, hash = 0; 14 int i, hash = 0;
15 for (i = 0; i < namelen; i++) 15 for (i = 0; i < namelen; i++)
16 hash ^= tolower(name[i]) << (i % 24); 16 hash ^= tolower(name[i]) << (i % 24);
17 return hash % mod; 17 return hash % mod;
18 } 18 }
19 19
20 /* 20 /*
21 * Finds the bucket for a given name and reads the containing block; 21 * Finds the bucket for a given name and reads the containing block;
22 * *ofs is set to the offset of the first list entry. 22 * *ofs is set to the offset of the first list entry.
23 */ 23 */
24 static struct buffer_head *omfs_get_bucket(struct inode *dir, 24 static struct buffer_head *omfs_get_bucket(struct inode *dir,
25 const char *name, int namelen, int *ofs) 25 const char *name, int namelen, int *ofs)
26 { 26 {
27 int nbuckets = (dir->i_size - OMFS_DIR_START)/8; 27 int nbuckets = (dir->i_size - OMFS_DIR_START)/8;
28 int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino); 28 int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino);
29 int bucket = omfs_hash(name, namelen, nbuckets); 29 int bucket = omfs_hash(name, namelen, nbuckets);
30 30
31 *ofs = OMFS_DIR_START + bucket * 8; 31 *ofs = OMFS_DIR_START + bucket * 8;
32 return sb_bread(dir->i_sb, block); 32 return sb_bread(dir->i_sb, block);
33 } 33 }
34 34
35 static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block, 35 static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block,
36 const char *name, int namelen, 36 const char *name, int namelen,
37 u64 *prev_block) 37 u64 *prev_block)
38 { 38 {
39 struct buffer_head *bh; 39 struct buffer_head *bh;
40 struct omfs_inode *oi; 40 struct omfs_inode *oi;
41 int err = -ENOENT; 41 int err = -ENOENT;
42 *prev_block = ~0; 42 *prev_block = ~0;
43 43
44 while (block != ~0) { 44 while (block != ~0) {
45 bh = sb_bread(dir->i_sb, 45 bh = sb_bread(dir->i_sb,
46 clus_to_blk(OMFS_SB(dir->i_sb), block)); 46 clus_to_blk(OMFS_SB(dir->i_sb), block));
47 if (!bh) { 47 if (!bh) {
48 err = -EIO; 48 err = -EIO;
49 goto err; 49 goto err;
50 } 50 }
51 51
52 oi = (struct omfs_inode *) bh->b_data; 52 oi = (struct omfs_inode *) bh->b_data;
53 if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, block)) { 53 if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, block)) {
54 brelse(bh); 54 brelse(bh);
55 goto err; 55 goto err;
56 } 56 }
57 57
58 if (strncmp(oi->i_name, name, namelen) == 0) 58 if (strncmp(oi->i_name, name, namelen) == 0)
59 return bh; 59 return bh;
60 60
61 *prev_block = block; 61 *prev_block = block;
62 block = be64_to_cpu(oi->i_sibling); 62 block = be64_to_cpu(oi->i_sibling);
63 brelse(bh); 63 brelse(bh);
64 } 64 }
65 err: 65 err:
66 return ERR_PTR(err); 66 return ERR_PTR(err);
67 } 67 }
68 68
69 static struct buffer_head *omfs_find_entry(struct inode *dir, 69 static struct buffer_head *omfs_find_entry(struct inode *dir,
70 const char *name, int namelen) 70 const char *name, int namelen)
71 { 71 {
72 struct buffer_head *bh; 72 struct buffer_head *bh;
73 int ofs; 73 int ofs;
74 u64 block, dummy; 74 u64 block, dummy;
75 75
76 bh = omfs_get_bucket(dir, name, namelen, &ofs); 76 bh = omfs_get_bucket(dir, name, namelen, &ofs);
77 if (!bh) 77 if (!bh)
78 return ERR_PTR(-EIO); 78 return ERR_PTR(-EIO);
79 79
80 block = be64_to_cpu(*((__be64 *) &bh->b_data[ofs])); 80 block = be64_to_cpu(*((__be64 *) &bh->b_data[ofs]));
81 brelse(bh); 81 brelse(bh);
82 82
83 return omfs_scan_list(dir, block, name, namelen, &dummy); 83 return omfs_scan_list(dir, block, name, namelen, &dummy);
84 } 84 }
85 85
86 int omfs_make_empty(struct inode *inode, struct super_block *sb) 86 int omfs_make_empty(struct inode *inode, struct super_block *sb)
87 { 87 {
88 struct omfs_sb_info *sbi = OMFS_SB(sb); 88 struct omfs_sb_info *sbi = OMFS_SB(sb);
89 int block = clus_to_blk(sbi, inode->i_ino); 89 int block = clus_to_blk(sbi, inode->i_ino);
90 struct buffer_head *bh; 90 struct buffer_head *bh;
91 struct omfs_inode *oi; 91 struct omfs_inode *oi;
92 92
93 bh = sb_bread(sb, block); 93 bh = sb_bread(sb, block);
94 if (!bh) 94 if (!bh)
95 return -ENOMEM; 95 return -ENOMEM;
96 96
97 memset(bh->b_data, 0, sizeof(struct omfs_inode)); 97 memset(bh->b_data, 0, sizeof(struct omfs_inode));
98 98
99 if (inode->i_mode & S_IFDIR) { 99 if (inode->i_mode & S_IFDIR) {
100 memset(&bh->b_data[OMFS_DIR_START], 0xff, 100 memset(&bh->b_data[OMFS_DIR_START], 0xff,
101 sbi->s_sys_blocksize - OMFS_DIR_START); 101 sbi->s_sys_blocksize - OMFS_DIR_START);
102 } else 102 } else
103 omfs_make_empty_table(bh, OMFS_EXTENT_START); 103 omfs_make_empty_table(bh, OMFS_EXTENT_START);
104 104
105 oi = (struct omfs_inode *) bh->b_data; 105 oi = (struct omfs_inode *) bh->b_data;
106 oi->i_head.h_self = cpu_to_be64(inode->i_ino); 106 oi->i_head.h_self = cpu_to_be64(inode->i_ino);
107 oi->i_sibling = ~0ULL; 107 oi->i_sibling = ~cpu_to_be64(0ULL);
108 108
109 mark_buffer_dirty(bh); 109 mark_buffer_dirty(bh);
110 brelse(bh); 110 brelse(bh);
111 return 0; 111 return 0;
112 } 112 }
113 113
114 static int omfs_add_link(struct dentry *dentry, struct inode *inode) 114 static int omfs_add_link(struct dentry *dentry, struct inode *inode)
115 { 115 {
116 struct inode *dir = dentry->d_parent->d_inode; 116 struct inode *dir = dentry->d_parent->d_inode;
117 const char *name = dentry->d_name.name; 117 const char *name = dentry->d_name.name;
118 int namelen = dentry->d_name.len; 118 int namelen = dentry->d_name.len;
119 struct omfs_inode *oi; 119 struct omfs_inode *oi;
120 struct buffer_head *bh; 120 struct buffer_head *bh;
121 u64 block; 121 u64 block;
122 __be64 *entry; 122 __be64 *entry;
123 int ofs; 123 int ofs;
124 124
125 /* just prepend to head of queue in proper bucket */ 125 /* just prepend to head of queue in proper bucket */
126 bh = omfs_get_bucket(dir, name, namelen, &ofs); 126 bh = omfs_get_bucket(dir, name, namelen, &ofs);
127 if (!bh) 127 if (!bh)
128 goto out; 128 goto out;
129 129
130 entry = (__be64 *) &bh->b_data[ofs]; 130 entry = (__be64 *) &bh->b_data[ofs];
131 block = be64_to_cpu(*entry); 131 block = be64_to_cpu(*entry);
132 *entry = cpu_to_be64(inode->i_ino); 132 *entry = cpu_to_be64(inode->i_ino);
133 mark_buffer_dirty(bh); 133 mark_buffer_dirty(bh);
134 brelse(bh); 134 brelse(bh);
135 135
136 /* now set the sibling and parent pointers on the new inode */ 136 /* now set the sibling and parent pointers on the new inode */
137 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino)); 137 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino));
138 if (!bh) 138 if (!bh)
139 goto out; 139 goto out;
140 140
141 oi = (struct omfs_inode *) bh->b_data; 141 oi = (struct omfs_inode *) bh->b_data;
142 memcpy(oi->i_name, name, namelen); 142 memcpy(oi->i_name, name, namelen);
143 memset(oi->i_name + namelen, 0, OMFS_NAMELEN - namelen); 143 memset(oi->i_name + namelen, 0, OMFS_NAMELEN - namelen);
144 oi->i_sibling = cpu_to_be64(block); 144 oi->i_sibling = cpu_to_be64(block);
145 oi->i_parent = cpu_to_be64(dir->i_ino); 145 oi->i_parent = cpu_to_be64(dir->i_ino);
146 mark_buffer_dirty(bh); 146 mark_buffer_dirty(bh);
147 brelse(bh); 147 brelse(bh);
148 148
149 dir->i_ctime = CURRENT_TIME_SEC; 149 dir->i_ctime = CURRENT_TIME_SEC;
150 150
151 /* mark affected inodes dirty to rebuild checksums */ 151 /* mark affected inodes dirty to rebuild checksums */
152 mark_inode_dirty(dir); 152 mark_inode_dirty(dir);
153 mark_inode_dirty(inode); 153 mark_inode_dirty(inode);
154 return 0; 154 return 0;
155 out: 155 out:
156 return -ENOMEM; 156 return -ENOMEM;
157 } 157 }
158 158
159 static int omfs_delete_entry(struct dentry *dentry) 159 static int omfs_delete_entry(struct dentry *dentry)
160 { 160 {
161 struct inode *dir = dentry->d_parent->d_inode; 161 struct inode *dir = dentry->d_parent->d_inode;
162 struct inode *dirty; 162 struct inode *dirty;
163 const char *name = dentry->d_name.name; 163 const char *name = dentry->d_name.name;
164 int namelen = dentry->d_name.len; 164 int namelen = dentry->d_name.len;
165 struct omfs_inode *oi; 165 struct omfs_inode *oi;
166 struct buffer_head *bh, *bh2; 166 struct buffer_head *bh, *bh2;
167 __be64 *entry, next; 167 __be64 *entry, next;
168 u64 block, prev; 168 u64 block, prev;
169 int ofs; 169 int ofs;
170 int err = -ENOMEM; 170 int err = -ENOMEM;
171 171
172 /* delete the proper node in the bucket's linked list */ 172 /* delete the proper node in the bucket's linked list */
173 bh = omfs_get_bucket(dir, name, namelen, &ofs); 173 bh = omfs_get_bucket(dir, name, namelen, &ofs);
174 if (!bh) 174 if (!bh)
175 goto out; 175 goto out;
176 176
177 entry = (__be64 *) &bh->b_data[ofs]; 177 entry = (__be64 *) &bh->b_data[ofs];
178 block = be64_to_cpu(*entry); 178 block = be64_to_cpu(*entry);
179 179
180 bh2 = omfs_scan_list(dir, block, name, namelen, &prev); 180 bh2 = omfs_scan_list(dir, block, name, namelen, &prev);
181 if (IS_ERR(bh2)) { 181 if (IS_ERR(bh2)) {
182 err = PTR_ERR(bh2); 182 err = PTR_ERR(bh2);
183 goto out_free_bh; 183 goto out_free_bh;
184 } 184 }
185 185
186 oi = (struct omfs_inode *) bh2->b_data; 186 oi = (struct omfs_inode *) bh2->b_data;
187 next = oi->i_sibling; 187 next = oi->i_sibling;
188 brelse(bh2); 188 brelse(bh2);
189 189
190 if (prev != ~0) { 190 if (prev != ~0) {
191 /* found in middle of list, get list ptr */ 191 /* found in middle of list, get list ptr */
192 brelse(bh); 192 brelse(bh);
193 bh = sb_bread(dir->i_sb, 193 bh = sb_bread(dir->i_sb,
194 clus_to_blk(OMFS_SB(dir->i_sb), prev)); 194 clus_to_blk(OMFS_SB(dir->i_sb), prev));
195 if (!bh) 195 if (!bh)
196 goto out; 196 goto out;
197 197
198 oi = (struct omfs_inode *) bh->b_data; 198 oi = (struct omfs_inode *) bh->b_data;
199 entry = &oi->i_sibling; 199 entry = &oi->i_sibling;
200 } 200 }
201 201
202 *entry = next; 202 *entry = next;
203 mark_buffer_dirty(bh); 203 mark_buffer_dirty(bh);
204 204
205 if (prev != ~0) { 205 if (prev != ~0) {
206 dirty = omfs_iget(dir->i_sb, prev); 206 dirty = omfs_iget(dir->i_sb, prev);
207 if (!IS_ERR(dirty)) { 207 if (!IS_ERR(dirty)) {
208 mark_inode_dirty(dirty); 208 mark_inode_dirty(dirty);
209 iput(dirty); 209 iput(dirty);
210 } 210 }
211 } 211 }
212 212
213 err = 0; 213 err = 0;
214 out_free_bh: 214 out_free_bh:
215 brelse(bh); 215 brelse(bh);
216 out: 216 out:
217 return err; 217 return err;
218 } 218 }
219 219
220 static int omfs_dir_is_empty(struct inode *inode) 220 static int omfs_dir_is_empty(struct inode *inode)
221 { 221 {
222 int nbuckets = (inode->i_size - OMFS_DIR_START) / 8; 222 int nbuckets = (inode->i_size - OMFS_DIR_START) / 8;
223 struct buffer_head *bh; 223 struct buffer_head *bh;
224 u64 *ptr; 224 u64 *ptr;
225 int i; 225 int i;
226 226
227 bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb), 227 bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb),
228 inode->i_ino)); 228 inode->i_ino));
229 229
230 if (!bh) 230 if (!bh)
231 return 0; 231 return 0;
232 232
233 ptr = (u64 *) &bh->b_data[OMFS_DIR_START]; 233 ptr = (u64 *) &bh->b_data[OMFS_DIR_START];
234 234
235 for (i = 0; i < nbuckets; i++, ptr++) 235 for (i = 0; i < nbuckets; i++, ptr++)
236 if (*ptr != ~0) 236 if (*ptr != ~0)
237 break; 237 break;
238 238
239 brelse(bh); 239 brelse(bh);
240 return *ptr != ~0; 240 return *ptr != ~0;
241 } 241 }
242 242
243 static int omfs_unlink(struct inode *dir, struct dentry *dentry) 243 static int omfs_unlink(struct inode *dir, struct dentry *dentry)
244 { 244 {
245 int ret; 245 int ret;
246 struct inode *inode = dentry->d_inode; 246 struct inode *inode = dentry->d_inode;
247 247
248 ret = omfs_delete_entry(dentry); 248 ret = omfs_delete_entry(dentry);
249 if (ret) 249 if (ret)
250 goto end_unlink; 250 goto end_unlink;
251 251
252 inode_dec_link_count(inode); 252 inode_dec_link_count(inode);
253 mark_inode_dirty(dir); 253 mark_inode_dirty(dir);
254 254
255 end_unlink: 255 end_unlink:
256 return ret; 256 return ret;
257 } 257 }
258 258
259 static int omfs_rmdir(struct inode *dir, struct dentry *dentry) 259 static int omfs_rmdir(struct inode *dir, struct dentry *dentry)
260 { 260 {
261 int err = -ENOTEMPTY; 261 int err = -ENOTEMPTY;
262 struct inode *inode = dentry->d_inode; 262 struct inode *inode = dentry->d_inode;
263 263
264 if (omfs_dir_is_empty(inode)) { 264 if (omfs_dir_is_empty(inode)) {
265 err = omfs_unlink(dir, dentry); 265 err = omfs_unlink(dir, dentry);
266 if (!err) 266 if (!err)
267 inode_dec_link_count(inode); 267 inode_dec_link_count(inode);
268 } 268 }
269 return err; 269 return err;
270 } 270 }
271 271
272 static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) 272 static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode)
273 { 273 {
274 int err; 274 int err;
275 struct inode *inode = omfs_new_inode(dir, mode); 275 struct inode *inode = omfs_new_inode(dir, mode);
276 276
277 if (IS_ERR(inode)) 277 if (IS_ERR(inode))
278 return PTR_ERR(inode); 278 return PTR_ERR(inode);
279 279
280 err = omfs_make_empty(inode, dir->i_sb); 280 err = omfs_make_empty(inode, dir->i_sb);
281 if (err) 281 if (err)
282 goto out_free_inode; 282 goto out_free_inode;
283 283
284 err = omfs_add_link(dentry, inode); 284 err = omfs_add_link(dentry, inode);
285 if (err) 285 if (err)
286 goto out_free_inode; 286 goto out_free_inode;
287 287
288 d_instantiate(dentry, inode); 288 d_instantiate(dentry, inode);
289 return 0; 289 return 0;
290 290
291 out_free_inode: 291 out_free_inode:
292 iput(inode); 292 iput(inode);
293 return err; 293 return err;
294 } 294 }
295 295
296 static int omfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 296 static int omfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
297 { 297 {
298 return omfs_add_node(dir, dentry, mode | S_IFDIR); 298 return omfs_add_node(dir, dentry, mode | S_IFDIR);
299 } 299 }
300 300
301 static int omfs_create(struct inode *dir, struct dentry *dentry, int mode, 301 static int omfs_create(struct inode *dir, struct dentry *dentry, int mode,
302 struct nameidata *nd) 302 struct nameidata *nd)
303 { 303 {
304 return omfs_add_node(dir, dentry, mode | S_IFREG); 304 return omfs_add_node(dir, dentry, mode | S_IFREG);
305 } 305 }
306 306
307 static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry, 307 static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry,
308 struct nameidata *nd) 308 struct nameidata *nd)
309 { 309 {
310 struct buffer_head *bh; 310 struct buffer_head *bh;
311 struct inode *inode = NULL; 311 struct inode *inode = NULL;
312 312
313 if (dentry->d_name.len > OMFS_NAMELEN) 313 if (dentry->d_name.len > OMFS_NAMELEN)
314 return ERR_PTR(-ENAMETOOLONG); 314 return ERR_PTR(-ENAMETOOLONG);
315 315
316 bh = omfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); 316 bh = omfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
317 if (!IS_ERR(bh)) { 317 if (!IS_ERR(bh)) {
318 struct omfs_inode *oi = (struct omfs_inode *)bh->b_data; 318 struct omfs_inode *oi = (struct omfs_inode *)bh->b_data;
319 ino_t ino = be64_to_cpu(oi->i_head.h_self); 319 ino_t ino = be64_to_cpu(oi->i_head.h_self);
320 brelse(bh); 320 brelse(bh);
321 inode = omfs_iget(dir->i_sb, ino); 321 inode = omfs_iget(dir->i_sb, ino);
322 if (IS_ERR(inode)) 322 if (IS_ERR(inode))
323 return ERR_CAST(inode); 323 return ERR_CAST(inode);
324 } 324 }
325 d_add(dentry, inode); 325 d_add(dentry, inode);
326 return NULL; 326 return NULL;
327 } 327 }
328 328
329 /* sanity check block's self pointer */ 329 /* sanity check block's self pointer */
330 int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, 330 int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
331 u64 fsblock) 331 u64 fsblock)
332 { 332 {
333 int is_bad; 333 int is_bad;
334 u64 ino = be64_to_cpu(header->h_self); 334 u64 ino = be64_to_cpu(header->h_self);
335 is_bad = ((ino != fsblock) || (ino < sbi->s_root_ino) || 335 is_bad = ((ino != fsblock) || (ino < sbi->s_root_ino) ||
336 (ino > sbi->s_num_blocks)); 336 (ino > sbi->s_num_blocks));
337 337
338 if (is_bad) 338 if (is_bad)
339 printk(KERN_WARNING "omfs: bad hash chain detected\n"); 339 printk(KERN_WARNING "omfs: bad hash chain detected\n");
340 340
341 return is_bad; 341 return is_bad;
342 } 342 }
343 343
344 static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir, 344 static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
345 u64 fsblock, int hindex) 345 u64 fsblock, int hindex)
346 { 346 {
347 struct inode *dir = filp->f_dentry->d_inode; 347 struct inode *dir = filp->f_dentry->d_inode;
348 struct buffer_head *bh; 348 struct buffer_head *bh;
349 struct omfs_inode *oi; 349 struct omfs_inode *oi;
350 u64 self; 350 u64 self;
351 int res = 0; 351 int res = 0;
352 unsigned char d_type; 352 unsigned char d_type;
353 353
354 /* follow chain in this bucket */ 354 /* follow chain in this bucket */
355 while (fsblock != ~0) { 355 while (fsblock != ~0) {
356 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), 356 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb),
357 fsblock)); 357 fsblock));
358 if (!bh) 358 if (!bh)
359 goto out; 359 goto out;
360 360
361 oi = (struct omfs_inode *) bh->b_data; 361 oi = (struct omfs_inode *) bh->b_data;
362 if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, fsblock)) { 362 if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, fsblock)) {
363 brelse(bh); 363 brelse(bh);
364 goto out; 364 goto out;
365 } 365 }
366 366
367 self = fsblock; 367 self = fsblock;
368 fsblock = be64_to_cpu(oi->i_sibling); 368 fsblock = be64_to_cpu(oi->i_sibling);
369 369
370 /* skip visited nodes */ 370 /* skip visited nodes */
371 if (hindex) { 371 if (hindex) {
372 hindex--; 372 hindex--;
373 brelse(bh); 373 brelse(bh);
374 continue; 374 continue;
375 } 375 }
376 376
377 d_type = (oi->i_type == OMFS_DIR) ? DT_DIR : DT_REG; 377 d_type = (oi->i_type == OMFS_DIR) ? DT_DIR : DT_REG;
378 378
379 res = filldir(dirent, oi->i_name, strnlen(oi->i_name, 379 res = filldir(dirent, oi->i_name, strnlen(oi->i_name,
380 OMFS_NAMELEN), filp->f_pos, self, d_type); 380 OMFS_NAMELEN), filp->f_pos, self, d_type);
381 if (res == 0) 381 if (res == 0)
382 filp->f_pos++; 382 filp->f_pos++;
383 brelse(bh); 383 brelse(bh);
384 } 384 }
385 out: 385 out:
386 return res; 386 return res;
387 } 387 }
388 388
389 static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, 389 static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
390 struct inode *new_dir, struct dentry *new_dentry) 390 struct inode *new_dir, struct dentry *new_dentry)
391 { 391 {
392 struct inode *new_inode = new_dentry->d_inode; 392 struct inode *new_inode = new_dentry->d_inode;
393 struct inode *old_inode = old_dentry->d_inode; 393 struct inode *old_inode = old_dentry->d_inode;
394 struct buffer_head *bh; 394 struct buffer_head *bh;
395 int is_dir; 395 int is_dir;
396 int err; 396 int err;
397 397
398 is_dir = S_ISDIR(old_inode->i_mode); 398 is_dir = S_ISDIR(old_inode->i_mode);
399 399
400 if (new_inode) { 400 if (new_inode) {
401 /* overwriting existing file/dir */ 401 /* overwriting existing file/dir */
402 err = -ENOTEMPTY; 402 err = -ENOTEMPTY;
403 if (is_dir && !omfs_dir_is_empty(new_inode)) 403 if (is_dir && !omfs_dir_is_empty(new_inode))
404 goto out; 404 goto out;
405 405
406 err = -ENOENT; 406 err = -ENOENT;
407 bh = omfs_find_entry(new_dir, new_dentry->d_name.name, 407 bh = omfs_find_entry(new_dir, new_dentry->d_name.name,
408 new_dentry->d_name.len); 408 new_dentry->d_name.len);
409 if (IS_ERR(bh)) 409 if (IS_ERR(bh))
410 goto out; 410 goto out;
411 brelse(bh); 411 brelse(bh);
412 412
413 err = omfs_unlink(new_dir, new_dentry); 413 err = omfs_unlink(new_dir, new_dentry);
414 if (err) 414 if (err)
415 goto out; 415 goto out;
416 } 416 }
417 417
418 /* since omfs locates files by name, we need to unlink _before_ 418 /* since omfs locates files by name, we need to unlink _before_
419 * adding the new link or we won't find the old one */ 419 * adding the new link or we won't find the old one */
420 inode_inc_link_count(old_inode); 420 inode_inc_link_count(old_inode);
421 err = omfs_unlink(old_dir, old_dentry); 421 err = omfs_unlink(old_dir, old_dentry);
422 if (err) { 422 if (err) {
423 inode_dec_link_count(old_inode); 423 inode_dec_link_count(old_inode);
424 goto out; 424 goto out;
425 } 425 }
426 426
427 err = omfs_add_link(new_dentry, old_inode); 427 err = omfs_add_link(new_dentry, old_inode);
428 if (err) 428 if (err)
429 goto out; 429 goto out;
430 430
431 old_inode->i_ctime = CURRENT_TIME_SEC; 431 old_inode->i_ctime = CURRENT_TIME_SEC;
432 out: 432 out:
433 return err; 433 return err;
434 } 434 }
435 435
436 static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 436 static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
437 { 437 {
438 struct inode *dir = filp->f_dentry->d_inode; 438 struct inode *dir = filp->f_dentry->d_inode;
439 struct buffer_head *bh; 439 struct buffer_head *bh;
440 loff_t offset, res; 440 loff_t offset, res;
441 unsigned int hchain, hindex; 441 unsigned int hchain, hindex;
442 int nbuckets; 442 int nbuckets;
443 u64 fsblock; 443 u64 fsblock;
444 int ret = -EINVAL; 444 int ret = -EINVAL;
445 445
446 if (filp->f_pos >> 32) 446 if (filp->f_pos >> 32)
447 goto success; 447 goto success;
448 448
449 switch ((unsigned long) filp->f_pos) { 449 switch ((unsigned long) filp->f_pos) {
450 case 0: 450 case 0:
451 if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) 451 if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
452 goto success; 452 goto success;
453 filp->f_pos++; 453 filp->f_pos++;
454 /* fall through */ 454 /* fall through */
455 case 1: 455 case 1:
456 if (filldir(dirent, "..", 2, 1, 456 if (filldir(dirent, "..", 2, 1,
457 parent_ino(filp->f_dentry), DT_DIR) < 0) 457 parent_ino(filp->f_dentry), DT_DIR) < 0)
458 goto success; 458 goto success;
459 filp->f_pos = 1 << 20; 459 filp->f_pos = 1 << 20;
460 /* fall through */ 460 /* fall through */
461 } 461 }
462 462
463 nbuckets = (dir->i_size - OMFS_DIR_START) / 8; 463 nbuckets = (dir->i_size - OMFS_DIR_START) / 8;
464 464
465 /* high 12 bits store bucket + 1 and low 20 bits store hash index */ 465 /* high 12 bits store bucket + 1 and low 20 bits store hash index */
466 hchain = (filp->f_pos >> 20) - 1; 466 hchain = (filp->f_pos >> 20) - 1;
467 hindex = filp->f_pos & 0xfffff; 467 hindex = filp->f_pos & 0xfffff;
468 468
469 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino)); 469 bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino));
470 if (!bh) 470 if (!bh)
471 goto out; 471 goto out;
472 472
473 offset = OMFS_DIR_START + hchain * 8; 473 offset = OMFS_DIR_START + hchain * 8;
474 474
475 for (; hchain < nbuckets; hchain++, offset += 8) { 475 for (; hchain < nbuckets; hchain++, offset += 8) {
476 fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset])); 476 fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset]));
477 477
478 res = omfs_fill_chain(filp, dirent, filldir, fsblock, hindex); 478 res = omfs_fill_chain(filp, dirent, filldir, fsblock, hindex);
479 hindex = 0; 479 hindex = 0;
480 if (res < 0) 480 if (res < 0)
481 break; 481 break;
482 482
483 filp->f_pos = (hchain+2) << 20; 483 filp->f_pos = (hchain+2) << 20;
484 } 484 }
485 brelse(bh); 485 brelse(bh);
486 success: 486 success:
487 ret = 0; 487 ret = 0;
488 out: 488 out:
489 return ret; 489 return ret;
490 } 490 }
491 491
492 struct inode_operations omfs_dir_inops = { 492 struct inode_operations omfs_dir_inops = {
493 .lookup = omfs_lookup, 493 .lookup = omfs_lookup,
494 .mkdir = omfs_mkdir, 494 .mkdir = omfs_mkdir,
495 .rename = omfs_rename, 495 .rename = omfs_rename,
496 .create = omfs_create, 496 .create = omfs_create,
497 .unlink = omfs_unlink, 497 .unlink = omfs_unlink,
498 .rmdir = omfs_rmdir, 498 .rmdir = omfs_rmdir,
499 }; 499 };
500 500
501 struct file_operations omfs_dir_operations = { 501 struct file_operations omfs_dir_operations = {
502 .read = generic_read_dir, 502 .read = generic_read_dir,
503 .readdir = omfs_readdir, 503 .readdir = omfs_readdir,
504 }; 504 };
505 505
1 /* 1 /*
2 * OMFS (as used by RIO Karma) file operations. 2 * OMFS (as used by RIO Karma) file operations.
3 * Copyright (C) 2005 Bob Copeland <me@bobcopeland.com> 3 * Copyright (C) 2005 Bob Copeland <me@bobcopeland.com>
4 * Released under GPL v2. 4 * Released under GPL v2.
5 */ 5 */
6 6
7 #include <linux/version.h> 7 #include <linux/version.h>
8 #include <linux/module.h> 8 #include <linux/module.h>
9 #include <linux/fs.h> 9 #include <linux/fs.h>
10 #include <linux/buffer_head.h> 10 #include <linux/buffer_head.h>
11 #include <linux/mpage.h> 11 #include <linux/mpage.h>
12 #include "omfs.h" 12 #include "omfs.h"
13 13
14 static int omfs_sync_file(struct file *file, struct dentry *dentry, 14 static int omfs_sync_file(struct file *file, struct dentry *dentry,
15 int datasync) 15 int datasync)
16 { 16 {
17 struct inode *inode = dentry->d_inode; 17 struct inode *inode = dentry->d_inode;
18 int err; 18 int err;
19 19
20 err = sync_mapping_buffers(inode->i_mapping); 20 err = sync_mapping_buffers(inode->i_mapping);
21 if (!(inode->i_state & I_DIRTY)) 21 if (!(inode->i_state & I_DIRTY))
22 return err; 22 return err;
23 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 23 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
24 return err; 24 return err;
25 err |= omfs_sync_inode(inode); 25 err |= omfs_sync_inode(inode);
26 return err ? -EIO : 0; 26 return err ? -EIO : 0;
27 } 27 }
28 28
29 void omfs_make_empty_table(struct buffer_head *bh, int offset) 29 void omfs_make_empty_table(struct buffer_head *bh, int offset)
30 { 30 {
31 struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; 31 struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset];
32 32
33 oe->e_next = ~0ULL; 33 oe->e_next = ~cpu_to_be64(0ULL);
34 oe->e_extent_count = cpu_to_be32(1), 34 oe->e_extent_count = cpu_to_be32(1),
35 oe->e_fill = cpu_to_be32(0x22), 35 oe->e_fill = cpu_to_be32(0x22),
36 oe->e_entry.e_cluster = ~0ULL; 36 oe->e_entry.e_cluster = ~cpu_to_be64(0ULL);
37 oe->e_entry.e_blocks = ~0ULL; 37 oe->e_entry.e_blocks = ~cpu_to_be64(0ULL);
38 } 38 }
39 39
40 int omfs_shrink_inode(struct inode *inode) 40 int omfs_shrink_inode(struct inode *inode)
41 { 41 {
42 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); 42 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
43 struct omfs_extent *oe; 43 struct omfs_extent *oe;
44 struct omfs_extent_entry *entry; 44 struct omfs_extent_entry *entry;
45 struct buffer_head *bh; 45 struct buffer_head *bh;
46 u64 next, last; 46 u64 next, last;
47 u32 extent_count; 47 u32 extent_count;
48 int ret; 48 int ret;
49 49
50 /* traverse extent table, freeing each entry that is greater 50 /* traverse extent table, freeing each entry that is greater
51 * than inode->i_size; 51 * than inode->i_size;
52 */ 52 */
53 next = inode->i_ino; 53 next = inode->i_ino;
54 54
55 /* only support truncate -> 0 for now */ 55 /* only support truncate -> 0 for now */
56 ret = -EIO; 56 ret = -EIO;
57 if (inode->i_size != 0) 57 if (inode->i_size != 0)
58 goto out; 58 goto out;
59 59
60 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 60 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
61 if (!bh) 61 if (!bh)
62 goto out; 62 goto out;
63 63
64 oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); 64 oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]);
65 65
66 for (;;) { 66 for (;;) {
67 67
68 if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) { 68 if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) {
69 brelse(bh); 69 brelse(bh);
70 goto out; 70 goto out;
71 } 71 }
72 72
73 extent_count = be32_to_cpu(oe->e_extent_count); 73 extent_count = be32_to_cpu(oe->e_extent_count);
74 last = next; 74 last = next;
75 next = be64_to_cpu(oe->e_next); 75 next = be64_to_cpu(oe->e_next);
76 entry = &oe->e_entry; 76 entry = &oe->e_entry;
77 77
78 /* ignore last entry as it is the terminator */ 78 /* ignore last entry as it is the terminator */
79 for (; extent_count > 1; extent_count--) { 79 for (; extent_count > 1; extent_count--) {
80 u64 start, count; 80 u64 start, count;
81 start = be64_to_cpu(entry->e_cluster); 81 start = be64_to_cpu(entry->e_cluster);
82 count = be64_to_cpu(entry->e_blocks); 82 count = be64_to_cpu(entry->e_blocks);
83 83
84 omfs_clear_range(inode->i_sb, start, (int) count); 84 omfs_clear_range(inode->i_sb, start, (int) count);
85 entry++; 85 entry++;
86 } 86 }
87 omfs_make_empty_table(bh, (char *) oe - bh->b_data); 87 omfs_make_empty_table(bh, (char *) oe - bh->b_data);
88 mark_buffer_dirty(bh); 88 mark_buffer_dirty(bh);
89 brelse(bh); 89 brelse(bh);
90 90
91 if (last != inode->i_ino) 91 if (last != inode->i_ino)
92 omfs_clear_range(inode->i_sb, last, sbi->s_mirrors); 92 omfs_clear_range(inode->i_sb, last, sbi->s_mirrors);
93 93
94 if (next == ~0) 94 if (next == ~0)
95 break; 95 break;
96 96
97 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 97 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
98 if (!bh) 98 if (!bh)
99 goto out; 99 goto out;
100 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); 100 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
101 } 101 }
102 ret = 0; 102 ret = 0;
103 out: 103 out:
104 return ret; 104 return ret;
105 } 105 }
106 106
107 static void omfs_truncate(struct inode *inode) 107 static void omfs_truncate(struct inode *inode)
108 { 108 {
109 omfs_shrink_inode(inode); 109 omfs_shrink_inode(inode);
110 mark_inode_dirty(inode); 110 mark_inode_dirty(inode);
111 } 111 }
112 112
113 /* 113 /*
114 * Add new blocks to the current extent, or create new entries/continuations 114 * Add new blocks to the current extent, or create new entries/continuations
115 * as necessary. 115 * as necessary.
116 */ 116 */
117 static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, 117 static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe,
118 u64 *ret_block) 118 u64 *ret_block)
119 { 119 {
120 struct omfs_extent_entry *terminator; 120 struct omfs_extent_entry *terminator;
121 struct omfs_extent_entry *entry = &oe->e_entry; 121 struct omfs_extent_entry *entry = &oe->e_entry;
122 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); 122 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
123 u32 extent_count = be32_to_cpu(oe->e_extent_count); 123 u32 extent_count = be32_to_cpu(oe->e_extent_count);
124 u64 new_block = 0; 124 u64 new_block = 0;
125 u32 max_count; 125 u32 max_count;
126 int new_count; 126 int new_count;
127 int ret = 0; 127 int ret = 0;
128 128
129 /* reached the end of the extent table with no blocks mapped. 129 /* reached the end of the extent table with no blocks mapped.
130 * there are three possibilities for adding: grow last extent, 130 * there are three possibilities for adding: grow last extent,
131 * add a new extent to the current extent table, and add a 131 * add a new extent to the current extent table, and add a
132 * continuation inode. in last two cases need an allocator for 132 * continuation inode. in last two cases need an allocator for
133 * sbi->s_cluster_size 133 * sbi->s_cluster_size
134 */ 134 */
135 135
136 /* TODO: handle holes */ 136 /* TODO: handle holes */
137 137
138 /* should always have a terminator */ 138 /* should always have a terminator */
139 if (extent_count < 1) 139 if (extent_count < 1)
140 return -EIO; 140 return -EIO;
141 141
142 /* trivially grow current extent, if next block is not taken */ 142 /* trivially grow current extent, if next block is not taken */
143 terminator = entry + extent_count - 1; 143 terminator = entry + extent_count - 1;
144 if (extent_count > 1) { 144 if (extent_count > 1) {
145 entry = terminator-1; 145 entry = terminator-1;
146 new_block = be64_to_cpu(entry->e_cluster) + 146 new_block = be64_to_cpu(entry->e_cluster) +
147 be64_to_cpu(entry->e_blocks); 147 be64_to_cpu(entry->e_blocks);
148 148
149 if (omfs_allocate_block(inode->i_sb, new_block)) { 149 if (omfs_allocate_block(inode->i_sb, new_block)) {
150 entry->e_blocks = 150 entry->e_blocks =
151 cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1); 151 cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1);
152 terminator->e_blocks = ~(cpu_to_be64( 152 terminator->e_blocks = ~(cpu_to_be64(
153 be64_to_cpu(~terminator->e_blocks) + 1)); 153 be64_to_cpu(~terminator->e_blocks) + 1));
154 goto out; 154 goto out;
155 } 155 }
156 } 156 }
157 max_count = (sbi->s_sys_blocksize - OMFS_EXTENT_START - 157 max_count = (sbi->s_sys_blocksize - OMFS_EXTENT_START -
158 sizeof(struct omfs_extent)) / 158 sizeof(struct omfs_extent)) /
159 sizeof(struct omfs_extent_entry) + 1; 159 sizeof(struct omfs_extent_entry) + 1;
160 160
161 /* TODO: add a continuation block here */ 161 /* TODO: add a continuation block here */
162 if (be32_to_cpu(oe->e_extent_count) > max_count-1) 162 if (be32_to_cpu(oe->e_extent_count) > max_count-1)
163 return -EIO; 163 return -EIO;
164 164
165 /* try to allocate a new cluster */ 165 /* try to allocate a new cluster */
166 ret = omfs_allocate_range(inode->i_sb, 1, sbi->s_clustersize, 166 ret = omfs_allocate_range(inode->i_sb, 1, sbi->s_clustersize,
167 &new_block, &new_count); 167 &new_block, &new_count);
168 if (ret) 168 if (ret)
169 goto out_fail; 169 goto out_fail;
170 170
171 /* copy terminator down an entry */ 171 /* copy terminator down an entry */
172 entry = terminator; 172 entry = terminator;
173 terminator++; 173 terminator++;
174 memcpy(terminator, entry, sizeof(struct omfs_extent_entry)); 174 memcpy(terminator, entry, sizeof(struct omfs_extent_entry));
175 175
176 entry->e_cluster = cpu_to_be64(new_block); 176 entry->e_cluster = cpu_to_be64(new_block);
177 entry->e_blocks = cpu_to_be64((u64) new_count); 177 entry->e_blocks = cpu_to_be64((u64) new_count);
178 178
179 terminator->e_blocks = ~(cpu_to_be64( 179 terminator->e_blocks = ~(cpu_to_be64(
180 be64_to_cpu(~terminator->e_blocks) + (u64) new_count)); 180 be64_to_cpu(~terminator->e_blocks) + (u64) new_count));
181 181
182 /* write in new entry */ 182 /* write in new entry */
183 oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count)); 183 oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count));
184 184
185 out: 185 out:
186 *ret_block = new_block; 186 *ret_block = new_block;
187 out_fail: 187 out_fail:
188 return ret; 188 return ret;
189 } 189 }
190 190
191 /* 191 /*
192 * Scans across the directory table for a given file block number. 192 * Scans across the directory table for a given file block number.
193 * If block not found, return 0. 193 * If block not found, return 0.
194 */ 194 */
195 static sector_t find_block(struct inode *inode, struct omfs_extent_entry *ent, 195 static sector_t find_block(struct inode *inode, struct omfs_extent_entry *ent,
196 sector_t block, int count, int *left) 196 sector_t block, int count, int *left)
197 { 197 {
198 /* count > 1 because of terminator */ 198 /* count > 1 because of terminator */
199 sector_t searched = 0; 199 sector_t searched = 0;
200 for (; count > 1; count--) { 200 for (; count > 1; count--) {
201 int numblocks = clus_to_blk(OMFS_SB(inode->i_sb), 201 int numblocks = clus_to_blk(OMFS_SB(inode->i_sb),
202 be64_to_cpu(ent->e_blocks)); 202 be64_to_cpu(ent->e_blocks));
203 203
204 if (block >= searched && 204 if (block >= searched &&
205 block < searched + numblocks) { 205 block < searched + numblocks) {
206 /* 206 /*
207 * found it at cluster + (block - searched) 207 * found it at cluster + (block - searched)
208 * numblocks - (block - searched) is remainder 208 * numblocks - (block - searched) is remainder
209 */ 209 */
210 *left = numblocks - (block - searched); 210 *left = numblocks - (block - searched);
211 return clus_to_blk(OMFS_SB(inode->i_sb), 211 return clus_to_blk(OMFS_SB(inode->i_sb),
212 be64_to_cpu(ent->e_cluster)) + 212 be64_to_cpu(ent->e_cluster)) +
213 block - searched; 213 block - searched;
214 } 214 }
215 searched += numblocks; 215 searched += numblocks;
216 ent++; 216 ent++;
217 } 217 }
218 return 0; 218 return 0;
219 } 219 }
220 220
221 static int omfs_get_block(struct inode *inode, sector_t block, 221 static int omfs_get_block(struct inode *inode, sector_t block,
222 struct buffer_head *bh_result, int create) 222 struct buffer_head *bh_result, int create)
223 { 223 {
224 struct buffer_head *bh; 224 struct buffer_head *bh;
225 sector_t next, offset; 225 sector_t next, offset;
226 int ret; 226 int ret;
227 u64 new_block; 227 u64 new_block;
228 int extent_count; 228 int extent_count;
229 struct omfs_extent *oe; 229 struct omfs_extent *oe;
230 struct omfs_extent_entry *entry; 230 struct omfs_extent_entry *entry;
231 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); 231 struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
232 int max_blocks = bh_result->b_size >> inode->i_blkbits; 232 int max_blocks = bh_result->b_size >> inode->i_blkbits;
233 int remain; 233 int remain;
234 234
235 ret = -EIO; 235 ret = -EIO;
236 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino)); 236 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino));
237 if (!bh) 237 if (!bh)
238 goto out; 238 goto out;
239 239
240 oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); 240 oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]);
241 next = inode->i_ino; 241 next = inode->i_ino;
242 242
243 for (;;) { 243 for (;;) {
244 244
245 if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) 245 if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next))
246 goto out_brelse; 246 goto out_brelse;
247 247
248 extent_count = be32_to_cpu(oe->e_extent_count); 248 extent_count = be32_to_cpu(oe->e_extent_count);
249 next = be64_to_cpu(oe->e_next); 249 next = be64_to_cpu(oe->e_next);
250 entry = &oe->e_entry; 250 entry = &oe->e_entry;
251 251
252 offset = find_block(inode, entry, block, extent_count, &remain); 252 offset = find_block(inode, entry, block, extent_count, &remain);
253 if (offset > 0) { 253 if (offset > 0) {
254 ret = 0; 254 ret = 0;
255 map_bh(bh_result, inode->i_sb, offset); 255 map_bh(bh_result, inode->i_sb, offset);
256 if (remain > max_blocks) 256 if (remain > max_blocks)
257 remain = max_blocks; 257 remain = max_blocks;
258 bh_result->b_size = (remain << inode->i_blkbits); 258 bh_result->b_size = (remain << inode->i_blkbits);
259 goto out_brelse; 259 goto out_brelse;
260 } 260 }
261 if (next == ~0) 261 if (next == ~0)
262 break; 262 break;
263 263
264 brelse(bh); 264 brelse(bh);
265 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); 265 bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
266 if (!bh) 266 if (!bh)
267 goto out; 267 goto out;
268 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); 268 oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
269 } 269 }
270 if (create) { 270 if (create) {
271 ret = omfs_grow_extent(inode, oe, &new_block); 271 ret = omfs_grow_extent(inode, oe, &new_block);
272 if (ret == 0) { 272 if (ret == 0) {
273 mark_buffer_dirty(bh); 273 mark_buffer_dirty(bh);
274 mark_inode_dirty(inode); 274 mark_inode_dirty(inode);
275 map_bh(bh_result, inode->i_sb, 275 map_bh(bh_result, inode->i_sb,
276 clus_to_blk(sbi, new_block)); 276 clus_to_blk(sbi, new_block));
277 } 277 }
278 } 278 }
279 out_brelse: 279 out_brelse:
280 brelse(bh); 280 brelse(bh);
281 out: 281 out:
282 return ret; 282 return ret;
283 } 283 }
284 284
285 static int omfs_readpage(struct file *file, struct page *page) 285 static int omfs_readpage(struct file *file, struct page *page)
286 { 286 {
287 return block_read_full_page(page, omfs_get_block); 287 return block_read_full_page(page, omfs_get_block);
288 } 288 }
289 289
290 static int omfs_readpages(struct file *file, struct address_space *mapping, 290 static int omfs_readpages(struct file *file, struct address_space *mapping,
291 struct list_head *pages, unsigned nr_pages) 291 struct list_head *pages, unsigned nr_pages)
292 { 292 {
293 return mpage_readpages(mapping, pages, nr_pages, omfs_get_block); 293 return mpage_readpages(mapping, pages, nr_pages, omfs_get_block);
294 } 294 }
295 295
296 static int omfs_writepage(struct page *page, struct writeback_control *wbc) 296 static int omfs_writepage(struct page *page, struct writeback_control *wbc)
297 { 297 {
298 return block_write_full_page(page, omfs_get_block, wbc); 298 return block_write_full_page(page, omfs_get_block, wbc);
299 } 299 }
300 300
301 static int 301 static int
302 omfs_writepages(struct address_space *mapping, struct writeback_control *wbc) 302 omfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
303 { 303 {
304 return mpage_writepages(mapping, wbc, omfs_get_block); 304 return mpage_writepages(mapping, wbc, omfs_get_block);
305 } 305 }
306 306
307 static int omfs_write_begin(struct file *file, struct address_space *mapping, 307 static int omfs_write_begin(struct file *file, struct address_space *mapping,
308 loff_t pos, unsigned len, unsigned flags, 308 loff_t pos, unsigned len, unsigned flags,
309 struct page **pagep, void **fsdata) 309 struct page **pagep, void **fsdata)
310 { 310 {
311 *pagep = NULL; 311 *pagep = NULL;
312 return block_write_begin(file, mapping, pos, len, flags, 312 return block_write_begin(file, mapping, pos, len, flags,
313 pagep, fsdata, omfs_get_block); 313 pagep, fsdata, omfs_get_block);
314 } 314 }
315 315
316 static sector_t omfs_bmap(struct address_space *mapping, sector_t block) 316 static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
317 { 317 {
318 return generic_block_bmap(mapping, block, omfs_get_block); 318 return generic_block_bmap(mapping, block, omfs_get_block);
319 } 319 }
320 320
321 struct file_operations omfs_file_operations = { 321 struct file_operations omfs_file_operations = {
322 .llseek = generic_file_llseek, 322 .llseek = generic_file_llseek,
323 .read = do_sync_read, 323 .read = do_sync_read,
324 .write = do_sync_write, 324 .write = do_sync_write,
325 .aio_read = generic_file_aio_read, 325 .aio_read = generic_file_aio_read,
326 .aio_write = generic_file_aio_write, 326 .aio_write = generic_file_aio_write,
327 .mmap = generic_file_mmap, 327 .mmap = generic_file_mmap,
328 .fsync = omfs_sync_file, 328 .fsync = omfs_sync_file,
329 .splice_read = generic_file_splice_read, 329 .splice_read = generic_file_splice_read,
330 }; 330 };
331 331
332 struct inode_operations omfs_file_inops = { 332 struct inode_operations omfs_file_inops = {
333 .truncate = omfs_truncate 333 .truncate = omfs_truncate
334 }; 334 };
335 335
336 struct address_space_operations omfs_aops = { 336 struct address_space_operations omfs_aops = {
337 .readpage = omfs_readpage, 337 .readpage = omfs_readpage,
338 .readpages = omfs_readpages, 338 .readpages = omfs_readpages,
339 .writepage = omfs_writepage, 339 .writepage = omfs_writepage,
340 .writepages = omfs_writepages, 340 .writepages = omfs_writepages,
341 .sync_page = block_sync_page, 341 .sync_page = block_sync_page,
342 .write_begin = omfs_write_begin, 342 .write_begin = omfs_write_begin,
343 .write_end = generic_write_end, 343 .write_end = generic_write_end,
344 .bmap = omfs_bmap, 344 .bmap = omfs_bmap,
345 }; 345 };
346 346
347 347