diff options
author | Dave Jones <davej@redhat.com> | 2006-06-29 16:01:54 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2006-06-29 16:01:54 -0400 |
commit | 55b4d6a52195a8f277ffddf755ddaff359878f41 (patch) | |
tree | 06a3183a562f8da4688f65023f7a18dcad702956 /fs/ufs | |
parent | adf8a287150667feb5747f8beade62acacc17d4e (diff) | |
parent | 1f1332f727c3229eb2166a83fec5d3de6a73dce2 (diff) |
Merge ../linus
Conflicts:
drivers/char/agp/Kconfig
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/balloc.c | 448 | ||||
-rw-r--r-- | fs/ufs/cylinder.c | 49 | ||||
-rw-r--r-- | fs/ufs/dir.c | 1000 | ||||
-rw-r--r-- | fs/ufs/file.c | 21 | ||||
-rw-r--r-- | fs/ufs/ialloc.c | 63 | ||||
-rw-r--r-- | fs/ufs/inode.c | 374 | ||||
-rw-r--r-- | fs/ufs/namei.c | 84 | ||||
-rw-r--r-- | fs/ufs/super.c | 436 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 104 | ||||
-rw-r--r-- | fs/ufs/util.c | 48 | ||||
-rw-r--r-- | fs/ufs/util.h | 107 |
11 files changed, 1443 insertions, 1291 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 3ada9dcf55..95b878e5c7 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -21,14 +21,6 @@ | |||
21 | #include "swab.h" | 21 | #include "swab.h" |
22 | #include "util.h" | 22 | #include "util.h" |
23 | 23 | ||
24 | #undef UFS_BALLOC_DEBUG | ||
25 | |||
26 | #ifdef UFS_BALLOC_DEBUG | ||
27 | #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
28 | #else | ||
29 | #define UFSD(x) | ||
30 | #endif | ||
31 | |||
32 | static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *); | 24 | static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *); |
33 | static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *); | 25 | static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *); |
34 | static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *); | 26 | static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *); |
@@ -39,7 +31,8 @@ static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, | |||
39 | /* | 31 | /* |
40 | * Free 'count' fragments from fragment number 'fragment' | 32 | * Free 'count' fragments from fragment number 'fragment' |
41 | */ | 33 | */ |
42 | void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count) { | 34 | void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) |
35 | { | ||
43 | struct super_block * sb; | 36 | struct super_block * sb; |
44 | struct ufs_sb_private_info * uspi; | 37 | struct ufs_sb_private_info * uspi; |
45 | struct ufs_super_block_first * usb1; | 38 | struct ufs_super_block_first * usb1; |
@@ -51,7 +44,7 @@ void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count | |||
51 | uspi = UFS_SB(sb)->s_uspi; | 44 | uspi = UFS_SB(sb)->s_uspi; |
52 | usb1 = ubh_get_usb_first(uspi); | 45 | usb1 = ubh_get_usb_first(uspi); |
53 | 46 | ||
54 | UFSD(("ENTER, fragment %u, count %u\n", fragment, count)) | 47 | UFSD("ENTER, fragment %u, count %u\n", fragment, count); |
55 | 48 | ||
56 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) | 49 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) |
57 | ufs_error (sb, "ufs_free_fragments", "internal error"); | 50 | ufs_error (sb, "ufs_free_fragments", "internal error"); |
@@ -68,7 +61,7 @@ void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count | |||
68 | ucpi = ufs_load_cylinder (sb, cgno); | 61 | ucpi = ufs_load_cylinder (sb, cgno); |
69 | if (!ucpi) | 62 | if (!ucpi) |
70 | goto failed; | 63 | goto failed; |
71 | ucg = ubh_get_ucg (UCPI_UBH); | 64 | ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
72 | if (!ufs_cg_chkmagic(sb, ucg)) { | 65 | if (!ufs_cg_chkmagic(sb, ucg)) { |
73 | ufs_panic (sb, "ufs_free_fragments", "internal error, bad magic number on cg %u", cgno); | 66 | ufs_panic (sb, "ufs_free_fragments", "internal error, bad magic number on cg %u", cgno); |
74 | goto failed; | 67 | goto failed; |
@@ -76,11 +69,11 @@ void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count | |||
76 | 69 | ||
77 | end_bit = bit + count; | 70 | end_bit = bit + count; |
78 | bbase = ufs_blknum (bit); | 71 | bbase = ufs_blknum (bit); |
79 | blkmap = ubh_blkmap (UCPI_UBH, ucpi->c_freeoff, bbase); | 72 | blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
80 | ufs_fragacct (sb, blkmap, ucg->cg_frsum, -1); | 73 | ufs_fragacct (sb, blkmap, ucg->cg_frsum, -1); |
81 | for (i = bit; i < end_bit; i++) { | 74 | for (i = bit; i < end_bit; i++) { |
82 | if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, i)) | 75 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, i)) |
83 | ubh_setbit (UCPI_UBH, ucpi->c_freeoff, i); | 76 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, i); |
84 | else | 77 | else |
85 | ufs_error (sb, "ufs_free_fragments", | 78 | ufs_error (sb, "ufs_free_fragments", |
86 | "bit already cleared for fragment %u", i); | 79 | "bit already cleared for fragment %u", i); |
@@ -90,51 +83,52 @@ void ufs_free_fragments (struct inode * inode, unsigned fragment, unsigned count | |||
90 | 83 | ||
91 | 84 | ||
92 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); | 85 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); |
93 | fs32_add(sb, &usb1->fs_cstotal.cs_nffree, count); | 86 | uspi->cs_total.cs_nffree += count; |
94 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 87 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
95 | blkmap = ubh_blkmap (UCPI_UBH, ucpi->c_freeoff, bbase); | 88 | blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
96 | ufs_fragacct(sb, blkmap, ucg->cg_frsum, 1); | 89 | ufs_fragacct(sb, blkmap, ucg->cg_frsum, 1); |
97 | 90 | ||
98 | /* | 91 | /* |
99 | * Trying to reassemble free fragments into block | 92 | * Trying to reassemble free fragments into block |
100 | */ | 93 | */ |
101 | blkno = ufs_fragstoblks (bbase); | 94 | blkno = ufs_fragstoblks (bbase); |
102 | if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, blkno)) { | 95 | if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
103 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb); | 96 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb); |
104 | fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, uspi->s_fpb); | 97 | uspi->cs_total.cs_nffree -= uspi->s_fpb; |
105 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb); | 98 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb); |
106 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 99 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
107 | ufs_clusteracct (sb, ucpi, blkno, 1); | 100 | ufs_clusteracct (sb, ucpi, blkno, 1); |
108 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); | 101 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
109 | fs32_add(sb, &usb1->fs_cstotal.cs_nbfree, 1); | 102 | uspi->cs_total.cs_nbfree++; |
110 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); | 103 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
111 | cylno = ufs_cbtocylno (bbase); | 104 | cylno = ufs_cbtocylno (bbase); |
112 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1); | 105 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1); |
113 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 106 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); |
114 | } | 107 | } |
115 | 108 | ||
116 | ubh_mark_buffer_dirty (USPI_UBH); | 109 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
117 | ubh_mark_buffer_dirty (UCPI_UBH); | 110 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
118 | if (sb->s_flags & MS_SYNCHRONOUS) { | 111 | if (sb->s_flags & MS_SYNCHRONOUS) { |
119 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); | 112 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
120 | ubh_wait_on_buffer (UCPI_UBH); | 113 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
121 | } | 114 | } |
122 | sb->s_dirt = 1; | 115 | sb->s_dirt = 1; |
123 | 116 | ||
124 | unlock_super (sb); | 117 | unlock_super (sb); |
125 | UFSD(("EXIT\n")) | 118 | UFSD("EXIT\n"); |
126 | return; | 119 | return; |
127 | 120 | ||
128 | failed: | 121 | failed: |
129 | unlock_super (sb); | 122 | unlock_super (sb); |
130 | UFSD(("EXIT (FAILED)\n")) | 123 | UFSD("EXIT (FAILED)\n"); |
131 | return; | 124 | return; |
132 | } | 125 | } |
133 | 126 | ||
134 | /* | 127 | /* |
135 | * Free 'count' fragments from fragment number 'fragment' (free whole blocks) | 128 | * Free 'count' fragments from fragment number 'fragment' (free whole blocks) |
136 | */ | 129 | */ |
137 | void ufs_free_blocks (struct inode * inode, unsigned fragment, unsigned count) { | 130 | void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) |
131 | { | ||
138 | struct super_block * sb; | 132 | struct super_block * sb; |
139 | struct ufs_sb_private_info * uspi; | 133 | struct ufs_sb_private_info * uspi; |
140 | struct ufs_super_block_first * usb1; | 134 | struct ufs_super_block_first * usb1; |
@@ -146,7 +140,7 @@ void ufs_free_blocks (struct inode * inode, unsigned fragment, unsigned count) { | |||
146 | uspi = UFS_SB(sb)->s_uspi; | 140 | uspi = UFS_SB(sb)->s_uspi; |
147 | usb1 = ubh_get_usb_first(uspi); | 141 | usb1 = ubh_get_usb_first(uspi); |
148 | 142 | ||
149 | UFSD(("ENTER, fragment %u, count %u\n", fragment, count)) | 143 | UFSD("ENTER, fragment %u, count %u\n", fragment, count); |
150 | 144 | ||
151 | if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { | 145 | if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { |
152 | ufs_error (sb, "ufs_free_blocks", "internal error, " | 146 | ufs_error (sb, "ufs_free_blocks", "internal error, " |
@@ -162,7 +156,7 @@ do_more: | |||
162 | bit = ufs_dtogd (fragment); | 156 | bit = ufs_dtogd (fragment); |
163 | if (cgno >= uspi->s_ncg) { | 157 | if (cgno >= uspi->s_ncg) { |
164 | ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); | 158 | ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); |
165 | goto failed; | 159 | goto failed_unlock; |
166 | } | 160 | } |
167 | end_bit = bit + count; | 161 | end_bit = bit + count; |
168 | if (end_bit > uspi->s_fpg) { | 162 | if (end_bit > uspi->s_fpg) { |
@@ -173,36 +167,36 @@ do_more: | |||
173 | 167 | ||
174 | ucpi = ufs_load_cylinder (sb, cgno); | 168 | ucpi = ufs_load_cylinder (sb, cgno); |
175 | if (!ucpi) | 169 | if (!ucpi) |
176 | goto failed; | 170 | goto failed_unlock; |
177 | ucg = ubh_get_ucg (UCPI_UBH); | 171 | ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
178 | if (!ufs_cg_chkmagic(sb, ucg)) { | 172 | if (!ufs_cg_chkmagic(sb, ucg)) { |
179 | ufs_panic (sb, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno); | 173 | ufs_panic (sb, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno); |
180 | goto failed; | 174 | goto failed_unlock; |
181 | } | 175 | } |
182 | 176 | ||
183 | for (i = bit; i < end_bit; i += uspi->s_fpb) { | 177 | for (i = bit; i < end_bit; i += uspi->s_fpb) { |
184 | blkno = ufs_fragstoblks(i); | 178 | blkno = ufs_fragstoblks(i); |
185 | if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, blkno)) { | 179 | if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
186 | ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); | 180 | ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); |
187 | } | 181 | } |
188 | ubh_setblock(UCPI_UBH, ucpi->c_freeoff, blkno); | 182 | ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
189 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 183 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
190 | ufs_clusteracct (sb, ucpi, blkno, 1); | 184 | ufs_clusteracct (sb, ucpi, blkno, 1); |
191 | DQUOT_FREE_BLOCK(inode, uspi->s_fpb); | 185 | DQUOT_FREE_BLOCK(inode, uspi->s_fpb); |
192 | 186 | ||
193 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); | 187 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
194 | fs32_add(sb, &usb1->fs_cstotal.cs_nbfree, 1); | 188 | uspi->cs_total.cs_nbfree++; |
195 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); | 189 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
196 | cylno = ufs_cbtocylno(i); | 190 | cylno = ufs_cbtocylno(i); |
197 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1); | 191 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1); |
198 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 192 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); |
199 | } | 193 | } |
200 | 194 | ||
201 | ubh_mark_buffer_dirty (USPI_UBH); | 195 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
202 | ubh_mark_buffer_dirty (UCPI_UBH); | 196 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
203 | if (sb->s_flags & MS_SYNCHRONOUS) { | 197 | if (sb->s_flags & MS_SYNCHRONOUS) { |
204 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); | 198 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
205 | ubh_wait_on_buffer (UCPI_UBH); | 199 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
206 | } | 200 | } |
207 | 201 | ||
208 | if (overflow) { | 202 | if (overflow) { |
@@ -213,38 +207,127 @@ do_more: | |||
213 | 207 | ||
214 | sb->s_dirt = 1; | 208 | sb->s_dirt = 1; |
215 | unlock_super (sb); | 209 | unlock_super (sb); |
216 | UFSD(("EXIT\n")) | 210 | UFSD("EXIT\n"); |
217 | return; | 211 | return; |
218 | 212 | ||
219 | failed: | 213 | failed_unlock: |
220 | unlock_super (sb); | 214 | unlock_super (sb); |
221 | UFSD(("EXIT (FAILED)\n")) | 215 | failed: |
216 | UFSD("EXIT (FAILED)\n"); | ||
222 | return; | 217 | return; |
223 | } | 218 | } |
224 | 219 | ||
220 | static struct page *ufs_get_locked_page(struct address_space *mapping, | ||
221 | unsigned long index) | ||
222 | { | ||
223 | struct page *page; | ||
224 | |||
225 | try_again: | ||
226 | page = find_lock_page(mapping, index); | ||
227 | if (!page) { | ||
228 | page = read_cache_page(mapping, index, | ||
229 | (filler_t*)mapping->a_ops->readpage, | ||
230 | NULL); | ||
231 | if (IS_ERR(page)) { | ||
232 | printk(KERN_ERR "ufs_change_blocknr: " | ||
233 | "read_cache_page error: ino %lu, index: %lu\n", | ||
234 | mapping->host->i_ino, index); | ||
235 | goto out; | ||
236 | } | ||
225 | 237 | ||
238 | lock_page(page); | ||
226 | 239 | ||
227 | #define NULLIFY_FRAGMENTS \ | 240 | if (!PageUptodate(page) || PageError(page)) { |
228 | for (i = oldcount; i < newcount; i++) { \ | 241 | unlock_page(page); |
229 | bh = sb_getblk(sb, result + i); \ | 242 | page_cache_release(page); |
230 | memset (bh->b_data, 0, sb->s_blocksize); \ | 243 | |
231 | set_buffer_uptodate(bh); \ | 244 | printk(KERN_ERR "ufs_change_blocknr: " |
232 | mark_buffer_dirty (bh); \ | 245 | "can not read page: ino %lu, index: %lu\n", |
233 | if (IS_SYNC(inode)) \ | 246 | mapping->host->i_ino, index); |
234 | sync_dirty_buffer(bh); \ | 247 | |
235 | brelse (bh); \ | 248 | page = ERR_PTR(-EIO); |
249 | goto out; | ||
250 | } | ||
236 | } | 251 | } |
237 | 252 | ||
238 | unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | 253 | if (unlikely(!page->mapping || !page_has_buffers(page))) { |
239 | unsigned goal, unsigned count, int * err ) | 254 | unlock_page(page); |
255 | page_cache_release(page); | ||
256 | goto try_again;/*we really need these buffers*/ | ||
257 | } | ||
258 | out: | ||
259 | return page; | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * Modify inode page cache in such way: | ||
264 | * have - blocks with b_blocknr equal to oldb...oldb+count-1 | ||
265 | * get - blocks with b_blocknr equal to newb...newb+count-1 | ||
266 | * also we suppose that oldb...oldb+count-1 blocks | ||
267 | * situated at the end of file. | ||
268 | * | ||
269 | * We can come here from ufs_writepage or ufs_prepare_write, | ||
270 | * locked_page is argument of these functions, so we already lock it. | ||
271 | */ | ||
272 | static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, | ||
273 | unsigned int count, unsigned int oldb, | ||
274 | unsigned int newb, struct page *locked_page) | ||
275 | { | ||
276 | unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
277 | struct address_space *mapping = inode->i_mapping; | ||
278 | pgoff_t index, cur_index = locked_page->index; | ||
279 | unsigned int i, j; | ||
280 | struct page *page; | ||
281 | struct buffer_head *head, *bh; | ||
282 | |||
283 | UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", | ||
284 | inode->i_ino, count, oldb, newb); | ||
285 | |||
286 | BUG_ON(!PageLocked(locked_page)); | ||
287 | |||
288 | for (i = 0; i < count; i += blk_per_page) { | ||
289 | index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
290 | |||
291 | if (likely(cur_index != index)) { | ||
292 | page = ufs_get_locked_page(mapping, index); | ||
293 | if (IS_ERR(page)) | ||
294 | continue; | ||
295 | } else | ||
296 | page = locked_page; | ||
297 | |||
298 | j = i; | ||
299 | head = page_buffers(page); | ||
300 | bh = head; | ||
301 | do { | ||
302 | if (likely(bh->b_blocknr == j + oldb && j < count)) { | ||
303 | unmap_underlying_metadata(bh->b_bdev, | ||
304 | bh->b_blocknr); | ||
305 | bh->b_blocknr = newb + j++; | ||
306 | mark_buffer_dirty(bh); | ||
307 | } | ||
308 | |||
309 | bh = bh->b_this_page; | ||
310 | } while (bh != head); | ||
311 | |||
312 | set_page_dirty(page); | ||
313 | |||
314 | if (likely(cur_index != index)) { | ||
315 | unlock_page(page); | ||
316 | page_cache_release(page); | ||
317 | } | ||
318 | } | ||
319 | UFSD("EXIT\n"); | ||
320 | } | ||
321 | |||
322 | unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | ||
323 | unsigned goal, unsigned count, int * err, struct page *locked_page) | ||
240 | { | 324 | { |
241 | struct super_block * sb; | 325 | struct super_block * sb; |
242 | struct ufs_sb_private_info * uspi; | 326 | struct ufs_sb_private_info * uspi; |
243 | struct ufs_super_block_first * usb1; | 327 | struct ufs_super_block_first * usb1; |
244 | struct buffer_head * bh; | 328 | unsigned cgno, oldcount, newcount, tmp, request, result; |
245 | unsigned cgno, oldcount, newcount, tmp, request, i, result; | ||
246 | 329 | ||
247 | UFSD(("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count)) | 330 | UFSD("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count); |
248 | 331 | ||
249 | sb = inode->i_sb; | 332 | sb = inode->i_sb; |
250 | uspi = UFS_SB(sb)->s_uspi; | 333 | uspi = UFS_SB(sb)->s_uspi; |
@@ -273,14 +356,14 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
273 | return (unsigned)-1; | 356 | return (unsigned)-1; |
274 | } | 357 | } |
275 | if (fragment < UFS_I(inode)->i_lastfrag) { | 358 | if (fragment < UFS_I(inode)->i_lastfrag) { |
276 | UFSD(("EXIT (ALREADY ALLOCATED)\n")) | 359 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
277 | unlock_super (sb); | 360 | unlock_super (sb); |
278 | return 0; | 361 | return 0; |
279 | } | 362 | } |
280 | } | 363 | } |
281 | else { | 364 | else { |
282 | if (tmp) { | 365 | if (tmp) { |
283 | UFSD(("EXIT (ALREADY ALLOCATED)\n")) | 366 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
284 | unlock_super(sb); | 367 | unlock_super(sb); |
285 | return 0; | 368 | return 0; |
286 | } | 369 | } |
@@ -289,9 +372,9 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
289 | /* | 372 | /* |
290 | * There is not enough space for user on the device | 373 | * There is not enough space for user on the device |
291 | */ | 374 | */ |
292 | if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(usb1, UFS_MINFREE) <= 0) { | 375 | if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { |
293 | unlock_super (sb); | 376 | unlock_super (sb); |
294 | UFSD(("EXIT (FAILED)\n")) | 377 | UFSD("EXIT (FAILED)\n"); |
295 | return 0; | 378 | return 0; |
296 | } | 379 | } |
297 | 380 | ||
@@ -310,12 +393,10 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
310 | if (result) { | 393 | if (result) { |
311 | *p = cpu_to_fs32(sb, result); | 394 | *p = cpu_to_fs32(sb, result); |
312 | *err = 0; | 395 | *err = 0; |
313 | inode->i_blocks += count << uspi->s_nspfshift; | ||
314 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 396 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
315 | NULLIFY_FRAGMENTS | ||
316 | } | 397 | } |
317 | unlock_super(sb); | 398 | unlock_super(sb); |
318 | UFSD(("EXIT, result %u\n", result)) | 399 | UFSD("EXIT, result %u\n", result); |
319 | return result; | 400 | return result; |
320 | } | 401 | } |
321 | 402 | ||
@@ -325,11 +406,9 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
325 | result = ufs_add_fragments (inode, tmp, oldcount, newcount, err); | 406 | result = ufs_add_fragments (inode, tmp, oldcount, newcount, err); |
326 | if (result) { | 407 | if (result) { |
327 | *err = 0; | 408 | *err = 0; |
328 | inode->i_blocks += count << uspi->s_nspfshift; | ||
329 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 409 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
330 | NULLIFY_FRAGMENTS | ||
331 | unlock_super(sb); | 410 | unlock_super(sb); |
332 | UFSD(("EXIT, result %u\n", result)) | 411 | UFSD("EXIT, result %u\n", result); |
333 | return result; | 412 | return result; |
334 | } | 413 | } |
335 | 414 | ||
@@ -339,8 +418,8 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
339 | switch (fs32_to_cpu(sb, usb1->fs_optim)) { | 418 | switch (fs32_to_cpu(sb, usb1->fs_optim)) { |
340 | case UFS_OPTSPACE: | 419 | case UFS_OPTSPACE: |
341 | request = newcount; | 420 | request = newcount; |
342 | if (uspi->s_minfree < 5 || fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) | 421 | if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree |
343 | > uspi->s_dsize * uspi->s_minfree / (2 * 100) ) | 422 | > uspi->s_dsize * uspi->s_minfree / (2 * 100)) |
344 | break; | 423 | break; |
345 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); | 424 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); |
346 | break; | 425 | break; |
@@ -349,7 +428,7 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
349 | 428 | ||
350 | case UFS_OPTTIME: | 429 | case UFS_OPTTIME: |
351 | request = uspi->s_fpb; | 430 | request = uspi->s_fpb; |
352 | if (fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) < uspi->s_dsize * | 431 | if (uspi->cs_total.cs_nffree < uspi->s_dsize * |
353 | (uspi->s_minfree - 2) / 100) | 432 | (uspi->s_minfree - 2) / 100) |
354 | break; | 433 | break; |
355 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); | 434 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); |
@@ -357,39 +436,22 @@ unsigned ufs_new_fragments (struct inode * inode, __fs32 * p, unsigned fragment, | |||
357 | } | 436 | } |
358 | result = ufs_alloc_fragments (inode, cgno, goal, request, err); | 437 | result = ufs_alloc_fragments (inode, cgno, goal, request, err); |
359 | if (result) { | 438 | if (result) { |
360 | for (i = 0; i < oldcount; i++) { | 439 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, |
361 | bh = sb_bread(sb, tmp + i); | 440 | result, locked_page); |
362 | if(bh) | 441 | |
363 | { | ||
364 | clear_buffer_dirty(bh); | ||
365 | bh->b_blocknr = result + i; | ||
366 | mark_buffer_dirty (bh); | ||
367 | if (IS_SYNC(inode)) | ||
368 | sync_dirty_buffer(bh); | ||
369 | brelse (bh); | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | printk(KERN_ERR "ufs_new_fragments: bread fail\n"); | ||
374 | unlock_super(sb); | ||
375 | return 0; | ||
376 | } | ||
377 | } | ||
378 | *p = cpu_to_fs32(sb, result); | 442 | *p = cpu_to_fs32(sb, result); |
379 | *err = 0; | 443 | *err = 0; |
380 | inode->i_blocks += count << uspi->s_nspfshift; | ||
381 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 444 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
382 | NULLIFY_FRAGMENTS | ||
383 | unlock_super(sb); | 445 | unlock_super(sb); |
384 | if (newcount < request) | 446 | if (newcount < request) |
385 | ufs_free_fragments (inode, result + newcount, request - newcount); | 447 | ufs_free_fragments (inode, result + newcount, request - newcount); |
386 | ufs_free_fragments (inode, tmp, oldcount); | 448 | ufs_free_fragments (inode, tmp, oldcount); |
387 | UFSD(("EXIT, result %u\n", result)) | 449 | UFSD("EXIT, result %u\n", result); |
388 | return result; | 450 | return result; |
389 | } | 451 | } |
390 | 452 | ||
391 | unlock_super(sb); | 453 | unlock_super(sb); |
392 | UFSD(("EXIT (FAILED)\n")) | 454 | UFSD("EXIT (FAILED)\n"); |
393 | return 0; | 455 | return 0; |
394 | } | 456 | } |
395 | 457 | ||
@@ -404,7 +466,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
404 | struct ufs_cylinder_group * ucg; | 466 | struct ufs_cylinder_group * ucg; |
405 | unsigned cgno, fragno, fragoff, count, fragsize, i; | 467 | unsigned cgno, fragno, fragoff, count, fragsize, i; |
406 | 468 | ||
407 | UFSD(("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount)) | 469 | UFSD("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount); |
408 | 470 | ||
409 | sb = inode->i_sb; | 471 | sb = inode->i_sb; |
410 | uspi = UFS_SB(sb)->s_uspi; | 472 | uspi = UFS_SB(sb)->s_uspi; |
@@ -419,7 +481,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
419 | ucpi = ufs_load_cylinder (sb, cgno); | 481 | ucpi = ufs_load_cylinder (sb, cgno); |
420 | if (!ucpi) | 482 | if (!ucpi) |
421 | return 0; | 483 | return 0; |
422 | ucg = ubh_get_ucg (UCPI_UBH); | 484 | ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
423 | if (!ufs_cg_chkmagic(sb, ucg)) { | 485 | if (!ufs_cg_chkmagic(sb, ucg)) { |
424 | ufs_panic (sb, "ufs_add_fragments", | 486 | ufs_panic (sb, "ufs_add_fragments", |
425 | "internal error, bad magic number on cg %u", cgno); | 487 | "internal error, bad magic number on cg %u", cgno); |
@@ -429,14 +491,14 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
429 | fragno = ufs_dtogd (fragment); | 491 | fragno = ufs_dtogd (fragment); |
430 | fragoff = ufs_fragnum (fragno); | 492 | fragoff = ufs_fragnum (fragno); |
431 | for (i = oldcount; i < newcount; i++) | 493 | for (i = oldcount; i < newcount; i++) |
432 | if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, fragno + i)) | 494 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
433 | return 0; | 495 | return 0; |
434 | /* | 496 | /* |
435 | * Block can be extended | 497 | * Block can be extended |
436 | */ | 498 | */ |
437 | ucg->cg_time = cpu_to_fs32(sb, get_seconds()); | 499 | ucg->cg_time = cpu_to_fs32(sb, get_seconds()); |
438 | for (i = newcount; i < (uspi->s_fpb - fragoff); i++) | 500 | for (i = newcount; i < (uspi->s_fpb - fragoff); i++) |
439 | if (ubh_isclr (UCPI_UBH, ucpi->c_freeoff, fragno + i)) | 501 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
440 | break; | 502 | break; |
441 | fragsize = i - oldcount; | 503 | fragsize = i - oldcount; |
442 | if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize])) | 504 | if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize])) |
@@ -446,7 +508,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
446 | if (fragsize != count) | 508 | if (fragsize != count) |
447 | fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); | 509 | fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); |
448 | for (i = oldcount; i < newcount; i++) | 510 | for (i = oldcount; i < newcount; i++) |
449 | ubh_clrbit (UCPI_UBH, ucpi->c_freeoff, fragno + i); | 511 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); |
450 | if(DQUOT_ALLOC_BLOCK(inode, count)) { | 512 | if(DQUOT_ALLOC_BLOCK(inode, count)) { |
451 | *err = -EDQUOT; | 513 | *err = -EDQUOT; |
452 | return 0; | 514 | return 0; |
@@ -454,17 +516,17 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
454 | 516 | ||
455 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); | 517 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); |
456 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 518 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
457 | fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count); | 519 | uspi->cs_total.cs_nffree -= count; |
458 | 520 | ||
459 | ubh_mark_buffer_dirty (USPI_UBH); | 521 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
460 | ubh_mark_buffer_dirty (UCPI_UBH); | 522 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
461 | if (sb->s_flags & MS_SYNCHRONOUS) { | 523 | if (sb->s_flags & MS_SYNCHRONOUS) { |
462 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); | 524 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
463 | ubh_wait_on_buffer (UCPI_UBH); | 525 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
464 | } | 526 | } |
465 | sb->s_dirt = 1; | 527 | sb->s_dirt = 1; |
466 | 528 | ||
467 | UFSD(("EXIT, fragment %u\n", fragment)) | 529 | UFSD("EXIT, fragment %u\n", fragment); |
468 | 530 | ||
469 | return fragment; | 531 | return fragment; |
470 | } | 532 | } |
@@ -487,7 +549,7 @@ static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, | |||
487 | struct ufs_cylinder_group * ucg; | 549 | struct ufs_cylinder_group * ucg; |
488 | unsigned oldcg, i, j, k, result, allocsize; | 550 | unsigned oldcg, i, j, k, result, allocsize; |
489 | 551 | ||
490 | UFSD(("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count)) | 552 | UFSD("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count); |
491 | 553 | ||
492 | sb = inode->i_sb; | 554 | sb = inode->i_sb; |
493 | uspi = UFS_SB(sb)->s_uspi; | 555 | uspi = UFS_SB(sb)->s_uspi; |
@@ -521,14 +583,14 @@ static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, | |||
521 | UFS_TEST_FREE_SPACE_CG | 583 | UFS_TEST_FREE_SPACE_CG |
522 | } | 584 | } |
523 | 585 | ||
524 | UFSD(("EXIT (FAILED)\n")) | 586 | UFSD("EXIT (FAILED)\n"); |
525 | return 0; | 587 | return 0; |
526 | 588 | ||
527 | cg_found: | 589 | cg_found: |
528 | ucpi = ufs_load_cylinder (sb, cgno); | 590 | ucpi = ufs_load_cylinder (sb, cgno); |
529 | if (!ucpi) | 591 | if (!ucpi) |
530 | return 0; | 592 | return 0; |
531 | ucg = ubh_get_ucg (UCPI_UBH); | 593 | ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
532 | if (!ufs_cg_chkmagic(sb, ucg)) | 594 | if (!ufs_cg_chkmagic(sb, ucg)) |
533 | ufs_panic (sb, "ufs_alloc_fragments", | 595 | ufs_panic (sb, "ufs_alloc_fragments", |
534 | "internal error, bad magic number on cg %u", cgno); | 596 | "internal error, bad magic number on cg %u", cgno); |
@@ -551,12 +613,12 @@ cg_found: | |||
551 | return 0; | 613 | return 0; |
552 | goal = ufs_dtogd (result); | 614 | goal = ufs_dtogd (result); |
553 | for (i = count; i < uspi->s_fpb; i++) | 615 | for (i = count; i < uspi->s_fpb; i++) |
554 | ubh_setbit (UCPI_UBH, ucpi->c_freeoff, goal + i); | 616 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
555 | i = uspi->s_fpb - count; | 617 | i = uspi->s_fpb - count; |
556 | DQUOT_FREE_BLOCK(inode, i); | 618 | DQUOT_FREE_BLOCK(inode, i); |
557 | 619 | ||
558 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); | 620 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); |
559 | fs32_add(sb, &usb1->fs_cstotal.cs_nffree, i); | 621 | uspi->cs_total.cs_nffree += i; |
560 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); | 622 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); |
561 | fs32_add(sb, &ucg->cg_frsum[i], 1); | 623 | fs32_add(sb, &ucg->cg_frsum[i], 1); |
562 | goto succed; | 624 | goto succed; |
@@ -570,10 +632,10 @@ cg_found: | |||
570 | return 0; | 632 | return 0; |
571 | } | 633 | } |
572 | for (i = 0; i < count; i++) | 634 | for (i = 0; i < count; i++) |
573 | ubh_clrbit (UCPI_UBH, ucpi->c_freeoff, result + i); | 635 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); |
574 | 636 | ||
575 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); | 637 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); |
576 | fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count); | 638 | uspi->cs_total.cs_nffree -= count; |
577 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 639 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
578 | fs32_sub(sb, &ucg->cg_frsum[allocsize], 1); | 640 | fs32_sub(sb, &ucg->cg_frsum[allocsize], 1); |
579 | 641 | ||
@@ -581,16 +643,16 @@ cg_found: | |||
581 | fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1); | 643 | fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1); |
582 | 644 | ||
583 | succed: | 645 | succed: |
584 | ubh_mark_buffer_dirty (USPI_UBH); | 646 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
585 | ubh_mark_buffer_dirty (UCPI_UBH); | 647 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
586 | if (sb->s_flags & MS_SYNCHRONOUS) { | 648 | if (sb->s_flags & MS_SYNCHRONOUS) { |
587 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **)&ucpi); | 649 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
588 | ubh_wait_on_buffer (UCPI_UBH); | 650 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
589 | } | 651 | } |
590 | sb->s_dirt = 1; | 652 | sb->s_dirt = 1; |
591 | 653 | ||
592 | result += cgno * uspi->s_fpg; | 654 | result += cgno * uspi->s_fpg; |
593 | UFSD(("EXIT3, result %u\n", result)) | 655 | UFSD("EXIT3, result %u\n", result); |
594 | return result; | 656 | return result; |
595 | } | 657 | } |
596 | 658 | ||
@@ -603,12 +665,12 @@ static unsigned ufs_alloccg_block (struct inode * inode, | |||
603 | struct ufs_cylinder_group * ucg; | 665 | struct ufs_cylinder_group * ucg; |
604 | unsigned result, cylno, blkno; | 666 | unsigned result, cylno, blkno; |
605 | 667 | ||
606 | UFSD(("ENTER, goal %u\n", goal)) | 668 | UFSD("ENTER, goal %u\n", goal); |
607 | 669 | ||
608 | sb = inode->i_sb; | 670 | sb = inode->i_sb; |
609 | uspi = UFS_SB(sb)->s_uspi; | 671 | uspi = UFS_SB(sb)->s_uspi; |
610 | usb1 = ubh_get_usb_first(uspi); | 672 | usb1 = ubh_get_usb_first(uspi); |
611 | ucg = ubh_get_ucg(UCPI_UBH); | 673 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
612 | 674 | ||
613 | if (goal == 0) { | 675 | if (goal == 0) { |
614 | goal = ucpi->c_rotor; | 676 | goal = ucpi->c_rotor; |
@@ -620,7 +682,7 @@ static unsigned ufs_alloccg_block (struct inode * inode, | |||
620 | /* | 682 | /* |
621 | * If the requested block is available, use it. | 683 | * If the requested block is available, use it. |
622 | */ | 684 | */ |
623 | if (ubh_isblockset(UCPI_UBH, ucpi->c_freeoff, ufs_fragstoblks(goal))) { | 685 | if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) { |
624 | result = goal; | 686 | result = goal; |
625 | goto gotit; | 687 | goto gotit; |
626 | } | 688 | } |
@@ -632,7 +694,7 @@ norot: | |||
632 | ucpi->c_rotor = result; | 694 | ucpi->c_rotor = result; |
633 | gotit: | 695 | gotit: |
634 | blkno = ufs_fragstoblks(result); | 696 | blkno = ufs_fragstoblks(result); |
635 | ubh_clrblock (UCPI_UBH, ucpi->c_freeoff, blkno); | 697 | ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
636 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 698 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
637 | ufs_clusteracct (sb, ucpi, blkno, -1); | 699 | ufs_clusteracct (sb, ucpi, blkno, -1); |
638 | if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { | 700 | if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { |
@@ -641,31 +703,76 @@ gotit: | |||
641 | } | 703 | } |
642 | 704 | ||
643 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); | 705 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); |
644 | fs32_sub(sb, &usb1->fs_cstotal.cs_nbfree, 1); | 706 | uspi->cs_total.cs_nbfree--; |
645 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); | 707 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); |
646 | cylno = ufs_cbtocylno(result); | 708 | cylno = ufs_cbtocylno(result); |
647 | fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)), 1); | 709 | fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)), 1); |
648 | fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 710 | fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); |
649 | 711 | ||
650 | UFSD(("EXIT, result %u\n", result)) | 712 | UFSD("EXIT, result %u\n", result); |
651 | 713 | ||
652 | return result; | 714 | return result; |
653 | } | 715 | } |
654 | 716 | ||
655 | static unsigned ufs_bitmap_search (struct super_block * sb, | 717 | static unsigned ubh_scanc(struct ufs_sb_private_info *uspi, |
656 | struct ufs_cg_private_info * ucpi, unsigned goal, unsigned count) | 718 | struct ufs_buffer_head *ubh, |
719 | unsigned begin, unsigned size, | ||
720 | unsigned char *table, unsigned char mask) | ||
657 | { | 721 | { |
658 | struct ufs_sb_private_info * uspi; | 722 | unsigned rest, offset; |
659 | struct ufs_super_block_first * usb1; | 723 | unsigned char *cp; |
660 | struct ufs_cylinder_group * ucg; | 724 | |
661 | unsigned start, length, location, result; | 725 | |
662 | unsigned possition, fragsize, blockmap, mask; | 726 | offset = begin & ~uspi->s_fmask; |
663 | 727 | begin >>= uspi->s_fshift; | |
664 | UFSD(("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count)) | 728 | for (;;) { |
729 | if ((offset + size) < uspi->s_fsize) | ||
730 | rest = size; | ||
731 | else | ||
732 | rest = uspi->s_fsize - offset; | ||
733 | size -= rest; | ||
734 | cp = ubh->bh[begin]->b_data + offset; | ||
735 | while ((table[*cp++] & mask) == 0 && --rest) | ||
736 | ; | ||
737 | if (rest || !size) | ||
738 | break; | ||
739 | begin++; | ||
740 | offset = 0; | ||
741 | } | ||
742 | return (size + rest); | ||
743 | } | ||
744 | |||
745 | /* | ||
746 | * Find a block of the specified size in the specified cylinder group. | ||
747 | * @sp: pointer to super block | ||
748 | * @ucpi: pointer to cylinder group info | ||
749 | * @goal: near which block we want find new one | ||
750 | * @count: specified size | ||
751 | */ | ||
752 | static unsigned ufs_bitmap_search(struct super_block *sb, | ||
753 | struct ufs_cg_private_info *ucpi, | ||
754 | unsigned goal, unsigned count) | ||
755 | { | ||
756 | /* | ||
757 | * Bit patterns for identifying fragments in the block map | ||
758 | * used as ((map & mask_arr) == want_arr) | ||
759 | */ | ||
760 | static const int mask_arr[9] = { | ||
761 | 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff | ||
762 | }; | ||
763 | static const int want_arr[9] = { | ||
764 | 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe | ||
765 | }; | ||
766 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | ||
767 | struct ufs_super_block_first *usb1; | ||
768 | struct ufs_cylinder_group *ucg; | ||
769 | unsigned start, length, loc, result; | ||
770 | unsigned pos, want, blockmap, mask, end; | ||
771 | |||
772 | UFSD("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count); | ||
665 | 773 | ||
666 | uspi = UFS_SB(sb)->s_uspi; | ||
667 | usb1 = ubh_get_usb_first (uspi); | 774 | usb1 = ubh_get_usb_first (uspi); |
668 | ucg = ubh_get_ucg(UCPI_UBH); | 775 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
669 | 776 | ||
670 | if (goal) | 777 | if (goal) |
671 | start = ufs_dtogd(goal) >> 3; | 778 | start = ufs_dtogd(goal) >> 3; |
@@ -673,53 +780,50 @@ static unsigned ufs_bitmap_search (struct super_block * sb, | |||
673 | start = ucpi->c_frotor >> 3; | 780 | start = ucpi->c_frotor >> 3; |
674 | 781 | ||
675 | length = ((uspi->s_fpg + 7) >> 3) - start; | 782 | length = ((uspi->s_fpg + 7) >> 3) - start; |
676 | location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff + start, length, | 783 | loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff + start, length, |
677 | (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, | 784 | (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, |
678 | 1 << (count - 1 + (uspi->s_fpb & 7))); | 785 | 1 << (count - 1 + (uspi->s_fpb & 7))); |
679 | if (location == 0) { | 786 | if (loc == 0) { |
680 | length = start + 1; | 787 | length = start + 1; |
681 | location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff, length, | 788 | loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, length, |
682 | (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, | 789 | (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : |
683 | 1 << (count - 1 + (uspi->s_fpb & 7))); | 790 | ufs_fragtable_other, |
684 | if (location == 0) { | 791 | 1 << (count - 1 + (uspi->s_fpb & 7))); |
685 | ufs_error (sb, "ufs_bitmap_search", | 792 | if (loc == 0) { |
686 | "bitmap corrupted on cg %u, start %u, length %u, count %u, freeoff %u\n", | 793 | ufs_error(sb, "ufs_bitmap_search", |
687 | ucpi->c_cgx, start, length, count, ucpi->c_freeoff); | 794 | "bitmap corrupted on cg %u, start %u," |
795 | " length %u, count %u, freeoff %u\n", | ||
796 | ucpi->c_cgx, start, length, count, | ||
797 | ucpi->c_freeoff); | ||
688 | return (unsigned)-1; | 798 | return (unsigned)-1; |
689 | } | 799 | } |
690 | start = 0; | 800 | start = 0; |
691 | } | 801 | } |
692 | result = (start + length - location) << 3; | 802 | result = (start + length - loc) << 3; |
693 | ucpi->c_frotor = result; | 803 | ucpi->c_frotor = result; |
694 | 804 | ||
695 | /* | 805 | /* |
696 | * found the byte in the map | 806 | * found the byte in the map |
697 | */ | 807 | */ |
698 | blockmap = ubh_blkmap(UCPI_UBH, ucpi->c_freeoff, result); | 808 | |
699 | fragsize = 0; | 809 | for (end = result + 8; result < end; result += uspi->s_fpb) { |
700 | for (possition = 0, mask = 1; possition < 8; possition++, mask <<= 1) { | 810 | blockmap = ubh_blkmap(UCPI_UBH(ucpi), ucpi->c_freeoff, result); |
701 | if (blockmap & mask) { | 811 | blockmap <<= 1; |
702 | if (!(possition & uspi->s_fpbmask)) | 812 | mask = mask_arr[count]; |
703 | fragsize = 1; | 813 | want = want_arr[count]; |
704 | else | 814 | for (pos = 0; pos <= uspi->s_fpb - count; pos++) { |
705 | fragsize++; | 815 | if ((blockmap & mask) == want) { |
706 | } | 816 | UFSD("EXIT, result %u\n", result); |
707 | else { | 817 | return result + pos; |
708 | if (fragsize == count) { | 818 | } |
709 | result += possition - count; | 819 | mask <<= 1; |
710 | UFSD(("EXIT, result %u\n", result)) | 820 | want <<= 1; |
711 | return result; | 821 | } |
712 | } | 822 | } |
713 | fragsize = 0; | 823 | |
714 | } | 824 | ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n", |
715 | } | 825 | ucpi->c_cgx); |
716 | if (fragsize == count) { | 826 | UFSD("EXIT (FAILED)\n"); |
717 | result += possition - count; | ||
718 | UFSD(("EXIT, result %u\n", result)) | ||
719 | return result; | ||
720 | } | ||
721 | ufs_error (sb, "ufs_bitmap_search", "block not in map on cg %u\n", ucpi->c_cgx); | ||
722 | UFSD(("EXIT (FAILED)\n")) | ||
723 | return (unsigned)-1; | 827 | return (unsigned)-1; |
724 | } | 828 | } |
725 | 829 | ||
@@ -734,9 +838,9 @@ static void ufs_clusteracct(struct super_block * sb, | |||
734 | return; | 838 | return; |
735 | 839 | ||
736 | if (cnt > 0) | 840 | if (cnt > 0) |
737 | ubh_setbit(UCPI_UBH, ucpi->c_clusteroff, blkno); | 841 | ubh_setbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
738 | else | 842 | else |
739 | ubh_clrbit(UCPI_UBH, ucpi->c_clusteroff, blkno); | 843 | ubh_clrbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
740 | 844 | ||
741 | /* | 845 | /* |
742 | * Find the size of the cluster going forward. | 846 | * Find the size of the cluster going forward. |
@@ -745,7 +849,7 @@ static void ufs_clusteracct(struct super_block * sb, | |||
745 | end = start + uspi->s_contigsumsize; | 849 | end = start + uspi->s_contigsumsize; |
746 | if ( end >= ucpi->c_nclusterblks) | 850 | if ( end >= ucpi->c_nclusterblks) |
747 | end = ucpi->c_nclusterblks; | 851 | end = ucpi->c_nclusterblks; |
748 | i = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_clusteroff, end, start); | 852 | i = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, end, start); |
749 | if (i > end) | 853 | if (i > end) |
750 | i = end; | 854 | i = end; |
751 | forw = i - start; | 855 | forw = i - start; |
@@ -757,7 +861,7 @@ static void ufs_clusteracct(struct super_block * sb, | |||
757 | end = start - uspi->s_contigsumsize; | 861 | end = start - uspi->s_contigsumsize; |
758 | if (end < 0 ) | 862 | if (end < 0 ) |
759 | end = -1; | 863 | end = -1; |
760 | i = ubh_find_last_zero_bit (UCPI_UBH, ucpi->c_clusteroff, start, end); | 864 | i = ubh_find_last_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, start, end); |
761 | if ( i < end) | 865 | if ( i < end) |
762 | i = end; | 866 | i = end; |
763 | back = start - i; | 867 | back = start - i; |
@@ -769,11 +873,11 @@ static void ufs_clusteracct(struct super_block * sb, | |||
769 | i = back + forw + 1; | 873 | i = back + forw + 1; |
770 | if (i > uspi->s_contigsumsize) | 874 | if (i > uspi->s_contigsumsize) |
771 | i = uspi->s_contigsumsize; | 875 | i = uspi->s_contigsumsize; |
772 | fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (i << 2)), cnt); | 876 | fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (i << 2)), cnt); |
773 | if (back > 0) | 877 | if (back > 0) |
774 | fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (back << 2)), cnt); | 878 | fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (back << 2)), cnt); |
775 | if (forw > 0) | 879 | if (forw > 0) |
776 | fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (forw << 2)), cnt); | 880 | fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (forw << 2)), cnt); |
777 | } | 881 | } |
778 | 882 | ||
779 | 883 | ||
diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c index 14abb8b835..09c39e5e63 100644 --- a/fs/ufs/cylinder.c +++ b/fs/ufs/cylinder.c | |||
@@ -20,15 +20,6 @@ | |||
20 | #include "swab.h" | 20 | #include "swab.h" |
21 | #include "util.h" | 21 | #include "util.h" |
22 | 22 | ||
23 | #undef UFS_CYLINDER_DEBUG | ||
24 | |||
25 | #ifdef UFS_CYLINDER_DEBUG | ||
26 | #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
27 | #else | ||
28 | #define UFSD(x) | ||
29 | #endif | ||
30 | |||
31 | |||
32 | /* | 23 | /* |
33 | * Read cylinder group into cache. The memory space for ufs_cg_private_info | 24 | * Read cylinder group into cache. The memory space for ufs_cg_private_info |
34 | * structure is already allocated during ufs_read_super. | 25 | * structure is already allocated during ufs_read_super. |
@@ -42,19 +33,19 @@ static void ufs_read_cylinder (struct super_block * sb, | |||
42 | struct ufs_cylinder_group * ucg; | 33 | struct ufs_cylinder_group * ucg; |
43 | unsigned i, j; | 34 | unsigned i, j; |
44 | 35 | ||
45 | UFSD(("ENTER, cgno %u, bitmap_nr %u\n", cgno, bitmap_nr)) | 36 | UFSD("ENTER, cgno %u, bitmap_nr %u\n", cgno, bitmap_nr); |
46 | uspi = sbi->s_uspi; | 37 | uspi = sbi->s_uspi; |
47 | ucpi = sbi->s_ucpi[bitmap_nr]; | 38 | ucpi = sbi->s_ucpi[bitmap_nr]; |
48 | ucg = (struct ufs_cylinder_group *)sbi->s_ucg[cgno]->b_data; | 39 | ucg = (struct ufs_cylinder_group *)sbi->s_ucg[cgno]->b_data; |
49 | 40 | ||
50 | UCPI_UBH->fragment = ufs_cgcmin(cgno); | 41 | UCPI_UBH(ucpi)->fragment = ufs_cgcmin(cgno); |
51 | UCPI_UBH->count = uspi->s_cgsize >> sb->s_blocksize_bits; | 42 | UCPI_UBH(ucpi)->count = uspi->s_cgsize >> sb->s_blocksize_bits; |
52 | /* | 43 | /* |
53 | * We have already the first fragment of cylinder group block in buffer | 44 | * We have already the first fragment of cylinder group block in buffer |
54 | */ | 45 | */ |
55 | UCPI_UBH->bh[0] = sbi->s_ucg[cgno]; | 46 | UCPI_UBH(ucpi)->bh[0] = sbi->s_ucg[cgno]; |
56 | for (i = 1; i < UCPI_UBH->count; i++) | 47 | for (i = 1; i < UCPI_UBH(ucpi)->count; i++) |
57 | if (!(UCPI_UBH->bh[i] = sb_bread(sb, UCPI_UBH->fragment + i))) | 48 | if (!(UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i))) |
58 | goto failed; | 49 | goto failed; |
59 | sbi->s_cgno[bitmap_nr] = cgno; | 50 | sbi->s_cgno[bitmap_nr] = cgno; |
60 | 51 | ||
@@ -73,7 +64,7 @@ static void ufs_read_cylinder (struct super_block * sb, | |||
73 | ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff); | 64 | ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff); |
74 | ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff); | 65 | ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff); |
75 | ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks); | 66 | ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks); |
76 | UFSD(("EXIT\n")) | 67 | UFSD("EXIT\n"); |
77 | return; | 68 | return; |
78 | 69 | ||
79 | failed: | 70 | failed: |
@@ -95,15 +86,15 @@ void ufs_put_cylinder (struct super_block * sb, unsigned bitmap_nr) | |||
95 | struct ufs_cylinder_group * ucg; | 86 | struct ufs_cylinder_group * ucg; |
96 | unsigned i; | 87 | unsigned i; |
97 | 88 | ||
98 | UFSD(("ENTER, bitmap_nr %u\n", bitmap_nr)) | 89 | UFSD("ENTER, bitmap_nr %u\n", bitmap_nr); |
99 | 90 | ||
100 | uspi = sbi->s_uspi; | 91 | uspi = sbi->s_uspi; |
101 | if (sbi->s_cgno[bitmap_nr] == UFS_CGNO_EMPTY) { | 92 | if (sbi->s_cgno[bitmap_nr] == UFS_CGNO_EMPTY) { |
102 | UFSD(("EXIT\n")) | 93 | UFSD("EXIT\n"); |
103 | return; | 94 | return; |
104 | } | 95 | } |
105 | ucpi = sbi->s_ucpi[bitmap_nr]; | 96 | ucpi = sbi->s_ucpi[bitmap_nr]; |
106 | ucg = ubh_get_ucg(UCPI_UBH); | 97 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
107 | 98 | ||
108 | if (uspi->s_ncg > UFS_MAX_GROUP_LOADED && bitmap_nr >= sbi->s_cg_loaded) { | 99 | if (uspi->s_ncg > UFS_MAX_GROUP_LOADED && bitmap_nr >= sbi->s_cg_loaded) { |
109 | ufs_panic (sb, "ufs_put_cylinder", "internal error"); | 100 | ufs_panic (sb, "ufs_put_cylinder", "internal error"); |
@@ -116,13 +107,13 @@ void ufs_put_cylinder (struct super_block * sb, unsigned bitmap_nr) | |||
116 | ucg->cg_rotor = cpu_to_fs32(sb, ucpi->c_rotor); | 107 | ucg->cg_rotor = cpu_to_fs32(sb, ucpi->c_rotor); |
117 | ucg->cg_frotor = cpu_to_fs32(sb, ucpi->c_frotor); | 108 | ucg->cg_frotor = cpu_to_fs32(sb, ucpi->c_frotor); |
118 | ucg->cg_irotor = cpu_to_fs32(sb, ucpi->c_irotor); | 109 | ucg->cg_irotor = cpu_to_fs32(sb, ucpi->c_irotor); |
119 | ubh_mark_buffer_dirty (UCPI_UBH); | 110 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
120 | for (i = 1; i < UCPI_UBH->count; i++) { | 111 | for (i = 1; i < UCPI_UBH(ucpi)->count; i++) { |
121 | brelse (UCPI_UBH->bh[i]); | 112 | brelse (UCPI_UBH(ucpi)->bh[i]); |
122 | } | 113 | } |
123 | 114 | ||
124 | sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY; | 115 | sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY; |
125 | UFSD(("EXIT\n")) | 116 | UFSD("EXIT\n"); |
126 | } | 117 | } |
127 | 118 | ||
128 | /* | 119 | /* |
@@ -139,7 +130,7 @@ struct ufs_cg_private_info * ufs_load_cylinder ( | |||
139 | struct ufs_cg_private_info * ucpi; | 130 | struct ufs_cg_private_info * ucpi; |
140 | unsigned cg, i, j; | 131 | unsigned cg, i, j; |
141 | 132 | ||
142 | UFSD(("ENTER, cgno %u\n", cgno)) | 133 | UFSD("ENTER, cgno %u\n", cgno); |
143 | 134 | ||
144 | uspi = sbi->s_uspi; | 135 | uspi = sbi->s_uspi; |
145 | if (cgno >= uspi->s_ncg) { | 136 | if (cgno >= uspi->s_ncg) { |
@@ -150,7 +141,7 @@ struct ufs_cg_private_info * ufs_load_cylinder ( | |||
150 | * Cylinder group number cg it in cache and it was last used | 141 | * Cylinder group number cg it in cache and it was last used |
151 | */ | 142 | */ |
152 | if (sbi->s_cgno[0] == cgno) { | 143 | if (sbi->s_cgno[0] == cgno) { |
153 | UFSD(("EXIT\n")) | 144 | UFSD("EXIT\n"); |
154 | return sbi->s_ucpi[0]; | 145 | return sbi->s_ucpi[0]; |
155 | } | 146 | } |
156 | /* | 147 | /* |
@@ -160,16 +151,16 @@ struct ufs_cg_private_info * ufs_load_cylinder ( | |||
160 | if (sbi->s_cgno[cgno] != UFS_CGNO_EMPTY) { | 151 | if (sbi->s_cgno[cgno] != UFS_CGNO_EMPTY) { |
161 | if (sbi->s_cgno[cgno] != cgno) { | 152 | if (sbi->s_cgno[cgno] != cgno) { |
162 | ufs_panic (sb, "ufs_load_cylinder", "internal error, wrong number of cg in cache"); | 153 | ufs_panic (sb, "ufs_load_cylinder", "internal error, wrong number of cg in cache"); |
163 | UFSD(("EXIT (FAILED)\n")) | 154 | UFSD("EXIT (FAILED)\n"); |
164 | return NULL; | 155 | return NULL; |
165 | } | 156 | } |
166 | else { | 157 | else { |
167 | UFSD(("EXIT\n")) | 158 | UFSD("EXIT\n"); |
168 | return sbi->s_ucpi[cgno]; | 159 | return sbi->s_ucpi[cgno]; |
169 | } | 160 | } |
170 | } else { | 161 | } else { |
171 | ufs_read_cylinder (sb, cgno, cgno); | 162 | ufs_read_cylinder (sb, cgno, cgno); |
172 | UFSD(("EXIT\n")) | 163 | UFSD("EXIT\n"); |
173 | return sbi->s_ucpi[cgno]; | 164 | return sbi->s_ucpi[cgno]; |
174 | } | 165 | } |
175 | } | 166 | } |
@@ -204,6 +195,6 @@ struct ufs_cg_private_info * ufs_load_cylinder ( | |||
204 | sbi->s_ucpi[0] = ucpi; | 195 | sbi->s_ucpi[0] = ucpi; |
205 | ufs_read_cylinder (sb, cgno, 0); | 196 | ufs_read_cylinder (sb, cgno, 0); |
206 | } | 197 | } |
207 | UFSD(("EXIT\n")) | 198 | UFSD("EXIT\n"); |
208 | return sbi->s_ucpi[0]; | 199 | return sbi->s_ucpi[0]; |
209 | } | 200 | } |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 1a561202d3..7f0a0aa635 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -11,31 +11,20 @@ | |||
11 | * 4.4BSD (FreeBSD) support added on February 1st 1998 by | 11 | * 4.4BSD (FreeBSD) support added on February 1st 1998 by |
12 | * Niels Kristian Bech Jensen <nkbj@image.dk> partially based | 12 | * Niels Kristian Bech Jensen <nkbj@image.dk> partially based |
13 | * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>. | 13 | * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>. |
14 | * | ||
15 | * Migration to usage of "page cache" on May 2006 by | ||
16 | * Evgeniy Dushistov <dushistov@mail.ru> based on ext2 code base. | ||
14 | */ | 17 | */ |
15 | 18 | ||
16 | #include <linux/time.h> | 19 | #include <linux/time.h> |
17 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
18 | #include <linux/ufs_fs.h> | 21 | #include <linux/ufs_fs.h> |
19 | #include <linux/smp_lock.h> | 22 | #include <linux/smp_lock.h> |
20 | #include <linux/buffer_head.h> | ||
21 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
22 | 24 | ||
23 | #include "swab.h" | 25 | #include "swab.h" |
24 | #include "util.h" | 26 | #include "util.h" |
25 | 27 | ||
26 | #undef UFS_DIR_DEBUG | ||
27 | |||
28 | #ifdef UFS_DIR_DEBUG | ||
29 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
30 | #else | ||
31 | #define UFSD(x) | ||
32 | #endif | ||
33 | |||
34 | static int | ||
35 | ufs_check_dir_entry (const char *, struct inode *, struct ufs_dir_entry *, | ||
36 | struct buffer_head *, unsigned long); | ||
37 | |||
38 | |||
39 | /* | 28 | /* |
40 | * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure. | 29 | * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure. |
41 | * | 30 | * |
@@ -51,495 +40,541 @@ static inline int ufs_match(struct super_block *sb, int len, | |||
51 | return !memcmp(name, de->d_name, len); | 40 | return !memcmp(name, de->d_name, len); |
52 | } | 41 | } |
53 | 42 | ||
54 | /* | 43 | static int ufs_commit_chunk(struct page *page, unsigned from, unsigned to) |
55 | * This is blatantly stolen from ext2fs | ||
56 | */ | ||
57 | static int | ||
58 | ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) | ||
59 | { | 44 | { |
60 | struct inode *inode = filp->f_dentry->d_inode; | 45 | struct inode *dir = page->mapping->host; |
61 | int error = 0; | 46 | int err = 0; |
62 | unsigned long offset, lblk; | 47 | dir->i_version++; |
63 | int i, stored; | 48 | page->mapping->a_ops->commit_write(NULL, page, from, to); |
64 | struct buffer_head * bh; | 49 | if (IS_DIRSYNC(dir)) |
65 | struct ufs_dir_entry * de; | 50 | err = write_one_page(page, 1); |
66 | struct super_block * sb; | 51 | else |
67 | int de_reclen; | 52 | unlock_page(page); |
68 | unsigned flags; | 53 | return err; |
69 | u64 blk= 0L; | 54 | } |
70 | |||
71 | lock_kernel(); | ||
72 | |||
73 | sb = inode->i_sb; | ||
74 | flags = UFS_SB(sb)->s_flags; | ||
75 | |||
76 | UFSD(("ENTER, ino %lu f_pos %lu\n", inode->i_ino, (unsigned long) filp->f_pos)) | ||
77 | |||
78 | stored = 0; | ||
79 | bh = NULL; | ||
80 | offset = filp->f_pos & (sb->s_blocksize - 1); | ||
81 | |||
82 | while (!error && !stored && filp->f_pos < inode->i_size) { | ||
83 | lblk = (filp->f_pos) >> sb->s_blocksize_bits; | ||
84 | blk = ufs_frag_map(inode, lblk); | ||
85 | if (!blk || !(bh = sb_bread(sb, blk))) { | ||
86 | /* XXX - error - skip to the next block */ | ||
87 | printk("ufs_readdir: " | ||
88 | "dir inode %lu has a hole at offset %lu\n", | ||
89 | inode->i_ino, (unsigned long int)filp->f_pos); | ||
90 | filp->f_pos += sb->s_blocksize - offset; | ||
91 | continue; | ||
92 | } | ||
93 | |||
94 | revalidate: | ||
95 | /* If the dir block has changed since the last call to | ||
96 | * readdir(2), then we might be pointing to an invalid | ||
97 | * dirent right now. Scan from the start of the block | ||
98 | * to make sure. */ | ||
99 | if (filp->f_version != inode->i_version) { | ||
100 | for (i = 0; i < sb->s_blocksize && i < offset; ) { | ||
101 | de = (struct ufs_dir_entry *)(bh->b_data + i); | ||
102 | /* It's too expensive to do a full | ||
103 | * dirent test each time round this | ||
104 | * loop, but we do have to test at | ||
105 | * least that it is non-zero. A | ||
106 | * failure will be detected in the | ||
107 | * dirent test below. */ | ||
108 | de_reclen = fs16_to_cpu(sb, de->d_reclen); | ||
109 | if (de_reclen < 1) | ||
110 | break; | ||
111 | i += de_reclen; | ||
112 | } | ||
113 | offset = i; | ||
114 | filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1)) | ||
115 | | offset; | ||
116 | filp->f_version = inode->i_version; | ||
117 | } | ||
118 | 55 | ||
119 | while (!error && filp->f_pos < inode->i_size | 56 | static inline void ufs_put_page(struct page *page) |
120 | && offset < sb->s_blocksize) { | 57 | { |
121 | de = (struct ufs_dir_entry *) (bh->b_data + offset); | 58 | kunmap(page); |
122 | /* XXX - put in a real ufs_check_dir_entry() */ | 59 | page_cache_release(page); |
123 | if ((de->d_reclen == 0) || (ufs_get_de_namlen(sb, de) == 0)) { | 60 | } |
124 | filp->f_pos = (filp->f_pos & | ||
125 | (sb->s_blocksize - 1)) + | ||
126 | sb->s_blocksize; | ||
127 | brelse(bh); | ||
128 | unlock_kernel(); | ||
129 | return stored; | ||
130 | } | ||
131 | if (!ufs_check_dir_entry ("ufs_readdir", inode, de, | ||
132 | bh, offset)) { | ||
133 | /* On error, skip the f_pos to the | ||
134 | next block. */ | ||
135 | filp->f_pos = (filp->f_pos | | ||
136 | (sb->s_blocksize - 1)) + | ||
137 | 1; | ||
138 | brelse (bh); | ||
139 | unlock_kernel(); | ||
140 | return stored; | ||
141 | } | ||
142 | offset += fs16_to_cpu(sb, de->d_reclen); | ||
143 | if (de->d_ino) { | ||
144 | /* We might block in the next section | ||
145 | * if the data destination is | ||
146 | * currently swapped out. So, use a | ||
147 | * version stamp to detect whether or | ||
148 | * not the directory has been modified | ||
149 | * during the copy operation. */ | ||
150 | unsigned long version = filp->f_version; | ||
151 | unsigned char d_type = DT_UNKNOWN; | ||
152 | 61 | ||
153 | UFSD(("filldir(%s,%u)\n", de->d_name, | 62 | static inline unsigned long ufs_dir_pages(struct inode *inode) |
154 | fs32_to_cpu(sb, de->d_ino))) | 63 | { |
155 | UFSD(("namlen %u\n", ufs_get_de_namlen(sb, de))) | 64 | return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; |
65 | } | ||
156 | 66 | ||
157 | if ((flags & UFS_DE_MASK) == UFS_DE_44BSD) | 67 | ino_t ufs_inode_by_name(struct inode *dir, struct dentry *dentry) |
158 | d_type = de->d_u.d_44.d_type; | 68 | { |
159 | error = filldir(dirent, de->d_name, | 69 | ino_t res = 0; |
160 | ufs_get_de_namlen(sb, de), filp->f_pos, | 70 | struct ufs_dir_entry *de; |
161 | fs32_to_cpu(sb, de->d_ino), d_type); | 71 | struct page *page; |
162 | if (error) | 72 | |
163 | break; | 73 | de = ufs_find_entry(dir, dentry, &page); |
164 | if (version != filp->f_version) | 74 | if (de) { |
165 | goto revalidate; | 75 | res = fs32_to_cpu(dir->i_sb, de->d_ino); |
166 | stored ++; | 76 | ufs_put_page(page); |
167 | } | ||
168 | filp->f_pos += fs16_to_cpu(sb, de->d_reclen); | ||
169 | } | ||
170 | offset = 0; | ||
171 | brelse (bh); | ||
172 | } | 77 | } |
173 | unlock_kernel(); | 78 | return res; |
174 | return 0; | ||
175 | } | 79 | } |
176 | 80 | ||
177 | /* | ||
178 | * define how far ahead to read directories while searching them. | ||
179 | */ | ||
180 | #define NAMEI_RA_CHUNKS 2 | ||
181 | #define NAMEI_RA_BLOCKS 4 | ||
182 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) | ||
183 | #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) | ||
184 | 81 | ||
185 | /* | 82 | /* Releases the page */ |
186 | * ufs_find_entry() | 83 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
187 | * | 84 | struct page *page, struct inode *inode) |
188 | * finds an entry in the specified directory with the wanted name. It | ||
189 | * returns the cache buffer in which the entry was found, and the entry | ||
190 | * itself (as a parameter - res_bh). It does NOT read the inode of the | ||
191 | * entry - you'll have to do that yourself if you want to. | ||
192 | */ | ||
193 | struct ufs_dir_entry * ufs_find_entry (struct dentry *dentry, | ||
194 | struct buffer_head ** res_bh) | ||
195 | { | 85 | { |
196 | struct super_block * sb; | 86 | unsigned from = (char *) de - (char *) page_address(page); |
197 | struct buffer_head * bh_use[NAMEI_RA_SIZE]; | 87 | unsigned to = from + fs16_to_cpu(dir->i_sb, de->d_reclen); |
198 | struct buffer_head * bh_read[NAMEI_RA_SIZE]; | 88 | int err; |
199 | unsigned long offset; | ||
200 | int block, toread, i, err; | ||
201 | struct inode *dir = dentry->d_parent->d_inode; | ||
202 | const char *name = dentry->d_name.name; | ||
203 | int namelen = dentry->d_name.len; | ||
204 | 89 | ||
205 | UFSD(("ENTER, dir_ino %lu, name %s, namlen %u\n", dir->i_ino, name, namelen)) | 90 | lock_page(page); |
206 | 91 | err = page->mapping->a_ops->prepare_write(NULL, page, from, to); | |
207 | *res_bh = NULL; | 92 | BUG_ON(err); |
208 | 93 | de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); | |
209 | sb = dir->i_sb; | 94 | ufs_set_de_type(dir->i_sb, de, inode->i_mode); |
210 | 95 | err = ufs_commit_chunk(page, from, to); | |
211 | if (namelen > UFS_MAXNAMLEN) | 96 | ufs_put_page(page); |
212 | return NULL; | 97 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
98 | mark_inode_dirty(dir); | ||
99 | } | ||
213 | 100 | ||
214 | memset (bh_use, 0, sizeof (bh_use)); | ||
215 | toread = 0; | ||
216 | for (block = 0; block < NAMEI_RA_SIZE; ++block) { | ||
217 | struct buffer_head * bh; | ||
218 | 101 | ||
219 | if ((block << sb->s_blocksize_bits) >= dir->i_size) | 102 | static void ufs_check_page(struct page *page) |
220 | break; | 103 | { |
221 | bh = ufs_getfrag (dir, block, 0, &err); | 104 | struct inode *dir = page->mapping->host; |
222 | bh_use[block] = bh; | 105 | struct super_block *sb = dir->i_sb; |
223 | if (bh && !buffer_uptodate(bh)) | 106 | char *kaddr = page_address(page); |
224 | bh_read[toread++] = bh; | 107 | unsigned offs, rec_len; |
108 | unsigned limit = PAGE_CACHE_SIZE; | ||
109 | struct ufs_dir_entry *p; | ||
110 | char *error; | ||
111 | |||
112 | if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { | ||
113 | limit = dir->i_size & ~PAGE_CACHE_MASK; | ||
114 | if (limit & (UFS_SECTOR_SIZE - 1)) | ||
115 | goto Ebadsize; | ||
116 | if (!limit) | ||
117 | goto out; | ||
225 | } | 118 | } |
119 | for (offs = 0; offs <= limit - UFS_DIR_REC_LEN(1); offs += rec_len) { | ||
120 | p = (struct ufs_dir_entry *)(kaddr + offs); | ||
121 | rec_len = fs16_to_cpu(sb, p->d_reclen); | ||
122 | |||
123 | if (rec_len < UFS_DIR_REC_LEN(1)) | ||
124 | goto Eshort; | ||
125 | if (rec_len & 3) | ||
126 | goto Ealign; | ||
127 | if (rec_len < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, p))) | ||
128 | goto Enamelen; | ||
129 | if (((offs + rec_len - 1) ^ offs) & ~(UFS_SECTOR_SIZE-1)) | ||
130 | goto Espan; | ||
131 | if (fs32_to_cpu(sb, p->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg * | ||
132 | UFS_SB(sb)->s_uspi->s_ncg)) | ||
133 | goto Einumber; | ||
134 | } | ||
135 | if (offs != limit) | ||
136 | goto Eend; | ||
137 | out: | ||
138 | SetPageChecked(page); | ||
139 | return; | ||
140 | |||
141 | /* Too bad, we had an error */ | ||
142 | |||
143 | Ebadsize: | ||
144 | ufs_error(sb, "ufs_check_page", | ||
145 | "size of directory #%lu is not a multiple of chunk size", | ||
146 | dir->i_ino | ||
147 | ); | ||
148 | goto fail; | ||
149 | Eshort: | ||
150 | error = "rec_len is smaller than minimal"; | ||
151 | goto bad_entry; | ||
152 | Ealign: | ||
153 | error = "unaligned directory entry"; | ||
154 | goto bad_entry; | ||
155 | Enamelen: | ||
156 | error = "rec_len is too small for name_len"; | ||
157 | goto bad_entry; | ||
158 | Espan: | ||
159 | error = "directory entry across blocks"; | ||
160 | goto bad_entry; | ||
161 | Einumber: | ||
162 | error = "inode out of bounds"; | ||
163 | bad_entry: | ||
164 | ufs_error (sb, "ufs_check_page", "bad entry in directory #%lu: %s - " | ||
165 | "offset=%lu, rec_len=%d, name_len=%d", | ||
166 | dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs, | ||
167 | rec_len, ufs_get_de_namlen(sb, p)); | ||
168 | goto fail; | ||
169 | Eend: | ||
170 | p = (struct ufs_dir_entry *)(kaddr + offs); | ||
171 | ufs_error (sb, "ext2_check_page", | ||
172 | "entry in directory #%lu spans the page boundary" | ||
173 | "offset=%lu", | ||
174 | dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs); | ||
175 | fail: | ||
176 | SetPageChecked(page); | ||
177 | SetPageError(page); | ||
178 | } | ||
226 | 179 | ||
227 | for (block = 0, offset = 0; offset < dir->i_size; block++) { | 180 | static struct page *ufs_get_page(struct inode *dir, unsigned long n) |
228 | struct buffer_head * bh; | 181 | { |
229 | struct ufs_dir_entry * de; | 182 | struct address_space *mapping = dir->i_mapping; |
230 | char * dlimit; | 183 | struct page *page = read_cache_page(mapping, n, |
231 | 184 | (filler_t*)mapping->a_ops->readpage, NULL); | |
232 | if ((block % NAMEI_RA_BLOCKS) == 0 && toread) { | 185 | if (!IS_ERR(page)) { |
233 | ll_rw_block (READ, toread, bh_read); | 186 | wait_on_page_locked(page); |
234 | toread = 0; | 187 | kmap(page); |
235 | } | 188 | if (!PageUptodate(page)) |
236 | bh = bh_use[block % NAMEI_RA_SIZE]; | 189 | goto fail; |
237 | if (!bh) { | 190 | if (!PageChecked(page)) |
238 | ufs_error (sb, "ufs_find_entry", | 191 | ufs_check_page(page); |
239 | "directory #%lu contains a hole at offset %lu", | 192 | if (PageError(page)) |
240 | dir->i_ino, offset); | 193 | goto fail; |
241 | offset += sb->s_blocksize; | ||
242 | continue; | ||
243 | } | ||
244 | wait_on_buffer (bh); | ||
245 | if (!buffer_uptodate(bh)) { | ||
246 | /* | ||
247 | * read error: all bets are off | ||
248 | */ | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | de = (struct ufs_dir_entry *) bh->b_data; | ||
253 | dlimit = bh->b_data + sb->s_blocksize; | ||
254 | while ((char *) de < dlimit && offset < dir->i_size) { | ||
255 | /* this code is executed quadratically often */ | ||
256 | /* do minimal checking by hand */ | ||
257 | int de_len; | ||
258 | |||
259 | if ((char *) de + namelen <= dlimit && | ||
260 | ufs_match(sb, namelen, name, de)) { | ||
261 | /* found a match - | ||
262 | just to be sure, do a full check */ | ||
263 | if (!ufs_check_dir_entry("ufs_find_entry", | ||
264 | dir, de, bh, offset)) | ||
265 | goto failed; | ||
266 | for (i = 0; i < NAMEI_RA_SIZE; ++i) { | ||
267 | if (bh_use[i] != bh) | ||
268 | brelse (bh_use[i]); | ||
269 | } | ||
270 | *res_bh = bh; | ||
271 | return de; | ||
272 | } | ||
273 | /* prevent looping on a bad block */ | ||
274 | de_len = fs16_to_cpu(sb, de->d_reclen); | ||
275 | if (de_len <= 0) | ||
276 | goto failed; | ||
277 | offset += de_len; | ||
278 | de = (struct ufs_dir_entry *) ((char *) de + de_len); | ||
279 | } | ||
280 | |||
281 | brelse (bh); | ||
282 | if (((block + NAMEI_RA_SIZE) << sb->s_blocksize_bits ) >= | ||
283 | dir->i_size) | ||
284 | bh = NULL; | ||
285 | else | ||
286 | bh = ufs_getfrag (dir, block + NAMEI_RA_SIZE, 0, &err); | ||
287 | bh_use[block % NAMEI_RA_SIZE] = bh; | ||
288 | if (bh && !buffer_uptodate(bh)) | ||
289 | bh_read[toread++] = bh; | ||
290 | } | 194 | } |
195 | return page; | ||
291 | 196 | ||
292 | failed: | 197 | fail: |
293 | for (i = 0; i < NAMEI_RA_SIZE; ++i) brelse (bh_use[i]); | 198 | ufs_put_page(page); |
294 | UFSD(("EXIT\n")) | 199 | return ERR_PTR(-EIO); |
295 | return NULL; | ||
296 | } | 200 | } |
297 | 201 | ||
298 | static int | 202 | /* |
299 | ufs_check_dir_entry (const char *function, struct inode *dir, | 203 | * Return the offset into page `page_nr' of the last valid |
300 | struct ufs_dir_entry *de, struct buffer_head *bh, | 204 | * byte in that page, plus one. |
301 | unsigned long offset) | 205 | */ |
206 | static unsigned | ||
207 | ufs_last_byte(struct inode *inode, unsigned long page_nr) | ||
302 | { | 208 | { |
303 | struct super_block *sb = dir->i_sb; | 209 | unsigned last_byte = inode->i_size; |
304 | const char *error_msg = NULL; | 210 | |
305 | int rlen = fs16_to_cpu(sb, de->d_reclen); | 211 | last_byte -= page_nr << PAGE_CACHE_SHIFT; |
306 | 212 | if (last_byte > PAGE_CACHE_SIZE) | |
307 | if (rlen < UFS_DIR_REC_LEN(1)) | 213 | last_byte = PAGE_CACHE_SIZE; |
308 | error_msg = "reclen is smaller than minimal"; | 214 | return last_byte; |
309 | else if (rlen % 4 != 0) | ||
310 | error_msg = "reclen % 4 != 0"; | ||
311 | else if (rlen < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de))) | ||
312 | error_msg = "reclen is too small for namlen"; | ||
313 | else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) | ||
314 | error_msg = "directory entry across blocks"; | ||
315 | else if (fs32_to_cpu(sb, de->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg * | ||
316 | UFS_SB(sb)->s_uspi->s_ncg)) | ||
317 | error_msg = "inode out of bounds"; | ||
318 | |||
319 | if (error_msg != NULL) | ||
320 | ufs_error (sb, function, "bad entry in directory #%lu, size %Lu: %s - " | ||
321 | "offset=%lu, inode=%lu, reclen=%d, namlen=%d", | ||
322 | dir->i_ino, dir->i_size, error_msg, offset, | ||
323 | (unsigned long)fs32_to_cpu(sb, de->d_ino), | ||
324 | rlen, ufs_get_de_namlen(sb, de)); | ||
325 | |||
326 | return (error_msg == NULL ? 1 : 0); | ||
327 | } | 215 | } |
328 | 216 | ||
329 | struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct buffer_head **p) | 217 | static inline struct ufs_dir_entry * |
218 | ufs_next_entry(struct super_block *sb, struct ufs_dir_entry *p) | ||
330 | { | 219 | { |
331 | int err; | 220 | return (struct ufs_dir_entry *)((char *)p + |
332 | struct buffer_head *bh = ufs_bread (dir, 0, 0, &err); | 221 | fs16_to_cpu(sb, p->d_reclen)); |
333 | struct ufs_dir_entry *res = NULL; | ||
334 | |||
335 | if (bh) { | ||
336 | res = (struct ufs_dir_entry *) bh->b_data; | ||
337 | res = (struct ufs_dir_entry *)((char *)res + | ||
338 | fs16_to_cpu(dir->i_sb, res->d_reclen)); | ||
339 | } | ||
340 | *p = bh; | ||
341 | return res; | ||
342 | } | 222 | } |
343 | ino_t ufs_inode_by_name(struct inode * dir, struct dentry *dentry) | 223 | |
224 | struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct page **p) | ||
344 | { | 225 | { |
345 | ino_t res = 0; | 226 | struct page *page = ufs_get_page(dir, 0); |
346 | struct ufs_dir_entry * de; | 227 | struct ufs_dir_entry *de = NULL; |
347 | struct buffer_head *bh; | ||
348 | 228 | ||
349 | de = ufs_find_entry (dentry, &bh); | 229 | if (!IS_ERR(page)) { |
350 | if (de) { | 230 | de = ufs_next_entry(dir->i_sb, |
351 | res = fs32_to_cpu(dir->i_sb, de->d_ino); | 231 | (struct ufs_dir_entry *)page_address(page)); |
352 | brelse(bh); | 232 | *p = page; |
353 | } | 233 | } |
354 | return res; | 234 | return de; |
355 | } | 235 | } |
356 | 236 | ||
357 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | 237 | /* |
358 | struct buffer_head *bh, struct inode *inode) | 238 | * ufs_find_entry() |
239 | * | ||
240 | * finds an entry in the specified directory with the wanted name. It | ||
241 | * returns the page in which the entry was found, and the entry itself | ||
242 | * (as a parameter - res_dir). Page is returned mapped and unlocked. | ||
243 | * Entry is guaranteed to be valid. | ||
244 | */ | ||
245 | struct ufs_dir_entry *ufs_find_entry(struct inode *dir, struct dentry *dentry, | ||
246 | struct page **res_page) | ||
359 | { | 247 | { |
360 | dir->i_version++; | 248 | struct super_block *sb = dir->i_sb; |
361 | de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); | 249 | const char *name = dentry->d_name.name; |
362 | mark_buffer_dirty(bh); | 250 | int namelen = dentry->d_name.len; |
363 | if (IS_DIRSYNC(dir)) | 251 | unsigned reclen = UFS_DIR_REC_LEN(namelen); |
364 | sync_dirty_buffer(bh); | 252 | unsigned long start, n; |
365 | brelse (bh); | 253 | unsigned long npages = ufs_dir_pages(dir); |
254 | struct page *page = NULL; | ||
255 | struct ufs_inode_info *ui = UFS_I(dir); | ||
256 | struct ufs_dir_entry *de; | ||
257 | |||
258 | UFSD("ENTER, dir_ino %lu, name %s, namlen %u\n", dir->i_ino, name, namelen); | ||
259 | |||
260 | if (npages == 0 || namelen > UFS_MAXNAMLEN) | ||
261 | goto out; | ||
262 | |||
263 | /* OFFSET_CACHE */ | ||
264 | *res_page = NULL; | ||
265 | |||
266 | start = ui->i_dir_start_lookup; | ||
267 | |||
268 | if (start >= npages) | ||
269 | start = 0; | ||
270 | n = start; | ||
271 | do { | ||
272 | char *kaddr; | ||
273 | page = ufs_get_page(dir, n); | ||
274 | if (!IS_ERR(page)) { | ||
275 | kaddr = page_address(page); | ||
276 | de = (struct ufs_dir_entry *) kaddr; | ||
277 | kaddr += ufs_last_byte(dir, n) - reclen; | ||
278 | while ((char *) de <= kaddr) { | ||
279 | if (de->d_reclen == 0) { | ||
280 | ufs_error(dir->i_sb, __FUNCTION__, | ||
281 | "zero-length directory entry"); | ||
282 | ufs_put_page(page); | ||
283 | goto out; | ||
284 | } | ||
285 | if (ufs_match(sb, namelen, name, de)) | ||
286 | goto found; | ||
287 | de = ufs_next_entry(sb, de); | ||
288 | } | ||
289 | ufs_put_page(page); | ||
290 | } | ||
291 | if (++n >= npages) | ||
292 | n = 0; | ||
293 | } while (n != start); | ||
294 | out: | ||
295 | return NULL; | ||
296 | |||
297 | found: | ||
298 | *res_page = page; | ||
299 | ui->i_dir_start_lookup = n; | ||
300 | return de; | ||
366 | } | 301 | } |
367 | 302 | ||
368 | /* | 303 | /* |
369 | * ufs_add_entry() | 304 | * Parent is locked. |
370 | * | ||
371 | * adds a file entry to the specified directory, using the same | ||
372 | * semantics as ufs_find_entry(). It returns NULL if it failed. | ||
373 | */ | 305 | */ |
374 | int ufs_add_link(struct dentry *dentry, struct inode *inode) | 306 | int ufs_add_link(struct dentry *dentry, struct inode *inode) |
375 | { | 307 | { |
376 | struct super_block * sb; | ||
377 | struct ufs_sb_private_info * uspi; | ||
378 | unsigned long offset; | ||
379 | unsigned fragoff; | ||
380 | unsigned short rec_len; | ||
381 | struct buffer_head * bh; | ||
382 | struct ufs_dir_entry * de, * de1; | ||
383 | struct inode *dir = dentry->d_parent->d_inode; | 308 | struct inode *dir = dentry->d_parent->d_inode; |
384 | const char *name = dentry->d_name.name; | 309 | const char *name = dentry->d_name.name; |
385 | int namelen = dentry->d_name.len; | 310 | int namelen = dentry->d_name.len; |
311 | struct super_block *sb = dir->i_sb; | ||
312 | unsigned reclen = UFS_DIR_REC_LEN(namelen); | ||
313 | unsigned short rec_len, name_len; | ||
314 | struct page *page = NULL; | ||
315 | struct ufs_dir_entry *de; | ||
316 | unsigned long npages = ufs_dir_pages(dir); | ||
317 | unsigned long n; | ||
318 | char *kaddr; | ||
319 | unsigned from, to; | ||
386 | int err; | 320 | int err; |
387 | 321 | ||
388 | UFSD(("ENTER, name %s, namelen %u\n", name, namelen)) | 322 | UFSD("ENTER, name %s, namelen %u\n", name, namelen); |
389 | 323 | ||
390 | sb = dir->i_sb; | 324 | /* |
391 | uspi = UFS_SB(sb)->s_uspi; | 325 | * We take care of directory expansion in the same loop. |
392 | 326 | * This code plays outside i_size, so it locks the page | |
393 | if (!namelen) | 327 | * to protect that region. |
394 | return -EINVAL; | 328 | */ |
395 | bh = ufs_bread (dir, 0, 0, &err); | 329 | for (n = 0; n <= npages; n++) { |
396 | if (!bh) | 330 | char *dir_end; |
397 | return err; | 331 | |
398 | rec_len = UFS_DIR_REC_LEN(namelen); | 332 | page = ufs_get_page(dir, n); |
399 | offset = 0; | 333 | err = PTR_ERR(page); |
400 | de = (struct ufs_dir_entry *) bh->b_data; | 334 | if (IS_ERR(page)) |
401 | while (1) { | 335 | goto out; |
402 | if ((char *)de >= UFS_SECTOR_SIZE + bh->b_data) { | 336 | lock_page(page); |
403 | fragoff = offset & ~uspi->s_fmask; | 337 | kaddr = page_address(page); |
404 | if (fragoff != 0 && fragoff != UFS_SECTOR_SIZE) | 338 | dir_end = kaddr + ufs_last_byte(dir, n); |
405 | ufs_error (sb, "ufs_add_entry", "internal error" | 339 | de = (struct ufs_dir_entry *)kaddr; |
406 | " fragoff %u", fragoff); | 340 | kaddr += PAGE_CACHE_SIZE - reclen; |
407 | if (!fragoff) { | 341 | while ((char *)de <= kaddr) { |
408 | brelse (bh); | 342 | if ((char *)de == dir_end) { |
409 | bh = ufs_bread (dir, offset >> sb->s_blocksize_bits, 1, &err); | 343 | /* We hit i_size */ |
410 | if (!bh) | 344 | name_len = 0; |
411 | return err; | 345 | rec_len = UFS_SECTOR_SIZE; |
412 | } | ||
413 | if (dir->i_size <= offset) { | ||
414 | if (dir->i_size == 0) { | ||
415 | brelse(bh); | ||
416 | return -ENOENT; | ||
417 | } | ||
418 | de = (struct ufs_dir_entry *) (bh->b_data + fragoff); | ||
419 | de->d_ino = 0; | ||
420 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE); | 346 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE); |
421 | ufs_set_de_namlen(sb, de, 0); | 347 | de->d_ino = 0; |
422 | dir->i_size = offset + UFS_SECTOR_SIZE; | 348 | goto got_it; |
423 | mark_inode_dirty(dir); | ||
424 | } else { | ||
425 | de = (struct ufs_dir_entry *) bh->b_data; | ||
426 | } | 349 | } |
350 | if (de->d_reclen == 0) { | ||
351 | ufs_error(dir->i_sb, __FUNCTION__, | ||
352 | "zero-length directory entry"); | ||
353 | err = -EIO; | ||
354 | goto out_unlock; | ||
355 | } | ||
356 | err = -EEXIST; | ||
357 | if (ufs_match(sb, namelen, name, de)) | ||
358 | goto out_unlock; | ||
359 | name_len = UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)); | ||
360 | rec_len = fs16_to_cpu(sb, de->d_reclen); | ||
361 | if (!de->d_ino && rec_len >= reclen) | ||
362 | goto got_it; | ||
363 | if (rec_len >= name_len + reclen) | ||
364 | goto got_it; | ||
365 | de = (struct ufs_dir_entry *) ((char *) de + rec_len); | ||
427 | } | 366 | } |
428 | if (!ufs_check_dir_entry ("ufs_add_entry", dir, de, bh, offset)) { | 367 | unlock_page(page); |
429 | brelse (bh); | 368 | ufs_put_page(page); |
430 | return -ENOENT; | ||
431 | } | ||
432 | if (ufs_match(sb, namelen, name, de)) { | ||
433 | brelse (bh); | ||
434 | return -EEXIST; | ||
435 | } | ||
436 | if (de->d_ino == 0 && fs16_to_cpu(sb, de->d_reclen) >= rec_len) | ||
437 | break; | ||
438 | |||
439 | if (fs16_to_cpu(sb, de->d_reclen) >= | ||
440 | UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de)) + rec_len) | ||
441 | break; | ||
442 | offset += fs16_to_cpu(sb, de->d_reclen); | ||
443 | de = (struct ufs_dir_entry *) ((char *) de + fs16_to_cpu(sb, de->d_reclen)); | ||
444 | } | 369 | } |
445 | 370 | BUG(); | |
371 | return -EINVAL; | ||
372 | |||
373 | got_it: | ||
374 | from = (char*)de - (char*)page_address(page); | ||
375 | to = from + rec_len; | ||
376 | err = page->mapping->a_ops->prepare_write(NULL, page, from, to); | ||
377 | if (err) | ||
378 | goto out_unlock; | ||
446 | if (de->d_ino) { | 379 | if (de->d_ino) { |
447 | de1 = (struct ufs_dir_entry *) ((char *) de + | 380 | struct ufs_dir_entry *de1 = |
448 | UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de))); | 381 | (struct ufs_dir_entry *) ((char *) de + name_len); |
449 | de1->d_reclen = | 382 | de1->d_reclen = cpu_to_fs16(sb, rec_len - name_len); |
450 | cpu_to_fs16(sb, fs16_to_cpu(sb, de->d_reclen) - | 383 | de->d_reclen = cpu_to_fs16(sb, name_len); |
451 | UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de))); | 384 | |
452 | de->d_reclen = | ||
453 | cpu_to_fs16(sb, UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de))); | ||
454 | de = de1; | 385 | de = de1; |
455 | } | 386 | } |
456 | de->d_ino = 0; | 387 | |
457 | ufs_set_de_namlen(sb, de, namelen); | 388 | ufs_set_de_namlen(sb, de, namelen); |
458 | memcpy (de->d_name, name, namelen + 1); | 389 | memcpy(de->d_name, name, namelen + 1); |
459 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); | 390 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); |
460 | ufs_set_de_type(sb, de, inode->i_mode); | 391 | ufs_set_de_type(sb, de, inode->i_mode); |
461 | mark_buffer_dirty(bh); | 392 | |
462 | if (IS_DIRSYNC(dir)) | 393 | err = ufs_commit_chunk(page, from, to); |
463 | sync_dirty_buffer(bh); | ||
464 | brelse (bh); | ||
465 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 394 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
466 | dir->i_version++; | 395 | |
467 | mark_inode_dirty(dir); | 396 | mark_inode_dirty(dir); |
397 | /* OFFSET_CACHE */ | ||
398 | out_put: | ||
399 | ufs_put_page(page); | ||
400 | out: | ||
401 | return err; | ||
402 | out_unlock: | ||
403 | unlock_page(page); | ||
404 | goto out_put; | ||
405 | } | ||
468 | 406 | ||
469 | UFSD(("EXIT\n")) | 407 | static inline unsigned |
408 | ufs_validate_entry(struct super_block *sb, char *base, | ||
409 | unsigned offset, unsigned mask) | ||
410 | { | ||
411 | struct ufs_dir_entry *de = (struct ufs_dir_entry*)(base + offset); | ||
412 | struct ufs_dir_entry *p = (struct ufs_dir_entry*)(base + (offset&mask)); | ||
413 | while ((char*)p < (char*)de) { | ||
414 | if (p->d_reclen == 0) | ||
415 | break; | ||
416 | p = ufs_next_entry(sb, p); | ||
417 | } | ||
418 | return (char *)p - base; | ||
419 | } | ||
420 | |||
421 | |||
422 | /* | ||
423 | * This is blatantly stolen from ext2fs | ||
424 | */ | ||
425 | static int | ||
426 | ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) | ||
427 | { | ||
428 | loff_t pos = filp->f_pos; | ||
429 | struct inode *inode = filp->f_dentry->d_inode; | ||
430 | struct super_block *sb = inode->i_sb; | ||
431 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | ||
432 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | ||
433 | unsigned long npages = ufs_dir_pages(inode); | ||
434 | unsigned chunk_mask = ~(UFS_SECTOR_SIZE - 1); | ||
435 | int need_revalidate = filp->f_version != inode->i_version; | ||
436 | unsigned flags = UFS_SB(sb)->s_flags; | ||
437 | |||
438 | UFSD("BEGIN\n"); | ||
439 | |||
440 | if (pos > inode->i_size - UFS_DIR_REC_LEN(1)) | ||
441 | return 0; | ||
442 | |||
443 | for ( ; n < npages; n++, offset = 0) { | ||
444 | char *kaddr, *limit; | ||
445 | struct ufs_dir_entry *de; | ||
446 | |||
447 | struct page *page = ufs_get_page(inode, n); | ||
448 | |||
449 | if (IS_ERR(page)) { | ||
450 | ufs_error(sb, __FUNCTION__, | ||
451 | "bad page in #%lu", | ||
452 | inode->i_ino); | ||
453 | filp->f_pos += PAGE_CACHE_SIZE - offset; | ||
454 | return -EIO; | ||
455 | } | ||
456 | kaddr = page_address(page); | ||
457 | if (unlikely(need_revalidate)) { | ||
458 | if (offset) { | ||
459 | offset = ufs_validate_entry(sb, kaddr, offset, chunk_mask); | ||
460 | filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; | ||
461 | } | ||
462 | filp->f_version = inode->i_version; | ||
463 | need_revalidate = 0; | ||
464 | } | ||
465 | de = (struct ufs_dir_entry *)(kaddr+offset); | ||
466 | limit = kaddr + ufs_last_byte(inode, n) - UFS_DIR_REC_LEN(1); | ||
467 | for ( ;(char*)de <= limit; de = ufs_next_entry(sb, de)) { | ||
468 | if (de->d_reclen == 0) { | ||
469 | ufs_error(sb, __FUNCTION__, | ||
470 | "zero-length directory entry"); | ||
471 | ufs_put_page(page); | ||
472 | return -EIO; | ||
473 | } | ||
474 | if (de->d_ino) { | ||
475 | int over; | ||
476 | unsigned char d_type = DT_UNKNOWN; | ||
477 | |||
478 | offset = (char *)de - kaddr; | ||
479 | |||
480 | UFSD("filldir(%s,%u)\n", de->d_name, | ||
481 | fs32_to_cpu(sb, de->d_ino)); | ||
482 | UFSD("namlen %u\n", ufs_get_de_namlen(sb, de)); | ||
483 | |||
484 | if ((flags & UFS_DE_MASK) == UFS_DE_44BSD) | ||
485 | d_type = de->d_u.d_44.d_type; | ||
486 | |||
487 | over = filldir(dirent, de->d_name, | ||
488 | ufs_get_de_namlen(sb, de), | ||
489 | (n<<PAGE_CACHE_SHIFT) | offset, | ||
490 | fs32_to_cpu(sb, de->d_ino), d_type); | ||
491 | if (over) { | ||
492 | ufs_put_page(page); | ||
493 | return 0; | ||
494 | } | ||
495 | } | ||
496 | filp->f_pos += fs16_to_cpu(sb, de->d_reclen); | ||
497 | } | ||
498 | ufs_put_page(page); | ||
499 | } | ||
470 | return 0; | 500 | return 0; |
471 | } | 501 | } |
472 | 502 | ||
503 | |||
473 | /* | 504 | /* |
474 | * ufs_delete_entry deletes a directory entry by merging it with the | 505 | * ufs_delete_entry deletes a directory entry by merging it with the |
475 | * previous entry. | 506 | * previous entry. |
476 | */ | 507 | */ |
477 | int ufs_delete_entry (struct inode * inode, struct ufs_dir_entry * dir, | 508 | int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, |
478 | struct buffer_head * bh ) | 509 | struct page * page) |
479 | |||
480 | { | 510 | { |
481 | struct super_block * sb; | 511 | struct super_block *sb = inode->i_sb; |
482 | struct ufs_dir_entry * de, * pde; | 512 | struct address_space *mapping = page->mapping; |
483 | unsigned i; | 513 | char *kaddr = page_address(page); |
484 | 514 | unsigned from = ((char*)dir - kaddr) & ~(UFS_SECTOR_SIZE - 1); | |
485 | UFSD(("ENTER\n")) | 515 | unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); |
516 | struct ufs_dir_entry *pde = NULL; | ||
517 | struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); | ||
518 | int err; | ||
486 | 519 | ||
487 | sb = inode->i_sb; | 520 | UFSD("ENTER\n"); |
488 | i = 0; | 521 | |
489 | pde = NULL; | 522 | UFSD("ino %u, reclen %u, namlen %u, name %s\n", |
490 | de = (struct ufs_dir_entry *) bh->b_data; | 523 | fs32_to_cpu(sb, de->d_ino), |
491 | 524 | fs16_to_cpu(sb, de->d_reclen), | |
492 | UFSD(("ino %u, reclen %u, namlen %u, name %s\n", | 525 | ufs_get_de_namlen(sb, de), de->d_name); |
493 | fs32_to_cpu(sb, de->d_ino), | 526 | |
494 | fs16_to_cpu(sb, de->d_reclen), | 527 | while ((char*)de < (char*)dir) { |
495 | ufs_get_de_namlen(sb, de), de->d_name)) | 528 | if (de->d_reclen == 0) { |
496 | 529 | ufs_error(inode->i_sb, __FUNCTION__, | |
497 | while (i < bh->b_size) { | 530 | "zero-length directory entry"); |
498 | if (!ufs_check_dir_entry ("ufs_delete_entry", inode, de, bh, i)) { | 531 | err = -EIO; |
499 | brelse(bh); | 532 | goto out; |
500 | return -EIO; | ||
501 | } | ||
502 | if (de == dir) { | ||
503 | if (pde) | ||
504 | fs16_add(sb, &pde->d_reclen, | ||
505 | fs16_to_cpu(sb, dir->d_reclen)); | ||
506 | dir->d_ino = 0; | ||
507 | inode->i_version++; | ||
508 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
509 | mark_inode_dirty(inode); | ||
510 | mark_buffer_dirty(bh); | ||
511 | if (IS_DIRSYNC(inode)) | ||
512 | sync_dirty_buffer(bh); | ||
513 | brelse(bh); | ||
514 | UFSD(("EXIT\n")) | ||
515 | return 0; | ||
516 | } | 533 | } |
517 | i += fs16_to_cpu(sb, de->d_reclen); | 534 | pde = de; |
518 | if (i == UFS_SECTOR_SIZE) pde = NULL; | 535 | de = ufs_next_entry(sb, de); |
519 | else pde = de; | ||
520 | de = (struct ufs_dir_entry *) | ||
521 | ((char *) de + fs16_to_cpu(sb, de->d_reclen)); | ||
522 | if (i == UFS_SECTOR_SIZE && de->d_reclen == 0) | ||
523 | break; | ||
524 | } | 536 | } |
525 | UFSD(("EXIT\n")) | 537 | if (pde) |
526 | brelse(bh); | 538 | from = (char*)pde - (char*)page_address(page); |
527 | return -ENOENT; | 539 | lock_page(page); |
540 | err = mapping->a_ops->prepare_write(NULL, page, from, to); | ||
541 | BUG_ON(err); | ||
542 | if (pde) | ||
543 | pde->d_reclen = cpu_to_fs16(sb, to-from); | ||
544 | dir->d_ino = 0; | ||
545 | err = ufs_commit_chunk(page, from, to); | ||
546 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
547 | mark_inode_dirty(inode); | ||
548 | out: | ||
549 | ufs_put_page(page); | ||
550 | UFSD("EXIT\n"); | ||
551 | return err; | ||
528 | } | 552 | } |
529 | 553 | ||
530 | int ufs_make_empty(struct inode * inode, struct inode *dir) | 554 | int ufs_make_empty(struct inode * inode, struct inode *dir) |
531 | { | 555 | { |
532 | struct super_block * sb = dir->i_sb; | 556 | struct super_block * sb = dir->i_sb; |
533 | struct buffer_head * dir_block; | 557 | struct address_space *mapping = inode->i_mapping; |
558 | struct page *page = grab_cache_page(mapping, 0); | ||
534 | struct ufs_dir_entry * de; | 559 | struct ufs_dir_entry * de; |
560 | char *base; | ||
535 | int err; | 561 | int err; |
536 | 562 | ||
537 | dir_block = ufs_bread (inode, 0, 1, &err); | 563 | if (!page) |
538 | if (!dir_block) | 564 | return -ENOMEM; |
539 | return err; | 565 | kmap(page); |
566 | err = mapping->a_ops->prepare_write(NULL, page, 0, UFS_SECTOR_SIZE); | ||
567 | if (err) { | ||
568 | unlock_page(page); | ||
569 | goto fail; | ||
570 | } | ||
571 | |||
572 | |||
573 | base = (char*)page_address(page); | ||
574 | memset(base, 0, PAGE_CACHE_SIZE); | ||
575 | |||
576 | de = (struct ufs_dir_entry *) base; | ||
540 | 577 | ||
541 | inode->i_blocks = sb->s_blocksize / UFS_SECTOR_SIZE; | ||
542 | de = (struct ufs_dir_entry *) dir_block->b_data; | ||
543 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); | 578 | de->d_ino = cpu_to_fs32(sb, inode->i_ino); |
544 | ufs_set_de_type(sb, de, inode->i_mode); | 579 | ufs_set_de_type(sb, de, inode->i_mode); |
545 | ufs_set_de_namlen(sb, de, 1); | 580 | ufs_set_de_namlen(sb, de, 1); |
@@ -552,72 +587,65 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) | |||
552 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1)); | 587 | de->d_reclen = cpu_to_fs16(sb, UFS_SECTOR_SIZE - UFS_DIR_REC_LEN(1)); |
553 | ufs_set_de_namlen(sb, de, 2); | 588 | ufs_set_de_namlen(sb, de, 2); |
554 | strcpy (de->d_name, ".."); | 589 | strcpy (de->d_name, ".."); |
555 | mark_buffer_dirty(dir_block); | 590 | |
556 | brelse (dir_block); | 591 | err = ufs_commit_chunk(page, 0, UFS_SECTOR_SIZE); |
557 | mark_inode_dirty(inode); | 592 | fail: |
558 | return 0; | 593 | kunmap(page); |
594 | page_cache_release(page); | ||
595 | return err; | ||
559 | } | 596 | } |
560 | 597 | ||
561 | /* | 598 | /* |
562 | * routine to check that the specified directory is empty (for rmdir) | 599 | * routine to check that the specified directory is empty (for rmdir) |
563 | */ | 600 | */ |
564 | int ufs_empty_dir (struct inode * inode) | 601 | int ufs_empty_dir(struct inode * inode) |
565 | { | 602 | { |
566 | struct super_block * sb; | 603 | struct super_block *sb = inode->i_sb; |
567 | unsigned long offset; | 604 | struct page *page = NULL; |
568 | struct buffer_head * bh; | 605 | unsigned long i, npages = ufs_dir_pages(inode); |
569 | struct ufs_dir_entry * de, * de1; | 606 | |
570 | int err; | 607 | for (i = 0; i < npages; i++) { |
571 | 608 | char *kaddr; | |
572 | sb = inode->i_sb; | 609 | struct ufs_dir_entry *de; |
573 | 610 | page = ufs_get_page(inode, i); | |
574 | if (inode->i_size < UFS_DIR_REC_LEN(1) + UFS_DIR_REC_LEN(2) || | 611 | |
575 | !(bh = ufs_bread (inode, 0, 0, &err))) { | 612 | if (IS_ERR(page)) |
576 | ufs_warning (inode->i_sb, "empty_dir", | 613 | continue; |
577 | "bad directory (dir #%lu) - no data block", | 614 | |
578 | inode->i_ino); | 615 | kaddr = page_address(page); |
579 | return 1; | 616 | de = (struct ufs_dir_entry *)kaddr; |
580 | } | 617 | kaddr += ufs_last_byte(inode, i) - UFS_DIR_REC_LEN(1); |
581 | de = (struct ufs_dir_entry *) bh->b_data; | 618 | |
582 | de1 = (struct ufs_dir_entry *) | 619 | while ((char *)de <= kaddr) { |
583 | ((char *)de + fs16_to_cpu(sb, de->d_reclen)); | 620 | if (de->d_reclen == 0) { |
584 | if (fs32_to_cpu(sb, de->d_ino) != inode->i_ino || de1->d_ino == 0 || | 621 | ufs_error(inode->i_sb, __FUNCTION__, |
585 | strcmp (".", de->d_name) || strcmp ("..", de1->d_name)) { | 622 | "zero-length directory entry: " |
586 | ufs_warning (inode->i_sb, "empty_dir", | 623 | "kaddr=%p, de=%p\n", kaddr, de); |
587 | "bad directory (dir #%lu) - no `.' or `..'", | 624 | goto not_empty; |
588 | inode->i_ino); | ||
589 | return 1; | ||
590 | } | ||
591 | offset = fs16_to_cpu(sb, de->d_reclen) + fs16_to_cpu(sb, de1->d_reclen); | ||
592 | de = (struct ufs_dir_entry *) | ||
593 | ((char *)de1 + fs16_to_cpu(sb, de1->d_reclen)); | ||
594 | while (offset < inode->i_size ) { | ||
595 | if (!bh || (void *) de >= (void *) (bh->b_data + sb->s_blocksize)) { | ||
596 | brelse (bh); | ||
597 | bh = ufs_bread (inode, offset >> sb->s_blocksize_bits, 1, &err); | ||
598 | if (!bh) { | ||
599 | ufs_error (sb, "empty_dir", | ||
600 | "directory #%lu contains a hole at offset %lu", | ||
601 | inode->i_ino, offset); | ||
602 | offset += sb->s_blocksize; | ||
603 | continue; | ||
604 | } | 625 | } |
605 | de = (struct ufs_dir_entry *) bh->b_data; | 626 | if (de->d_ino) { |
606 | } | 627 | u16 namelen=ufs_get_de_namlen(sb, de); |
607 | if (!ufs_check_dir_entry ("empty_dir", inode, de, bh, offset)) { | 628 | /* check for . and .. */ |
608 | brelse (bh); | 629 | if (de->d_name[0] != '.') |
609 | return 1; | 630 | goto not_empty; |
610 | } | 631 | if (namelen > 2) |
611 | if (de->d_ino) { | 632 | goto not_empty; |
612 | brelse (bh); | 633 | if (namelen < 2) { |
613 | return 0; | 634 | if (inode->i_ino != |
635 | fs32_to_cpu(sb, de->d_ino)) | ||
636 | goto not_empty; | ||
637 | } else if (de->d_name[1] != '.') | ||
638 | goto not_empty; | ||
639 | } | ||
640 | de = ufs_next_entry(sb, de); | ||
614 | } | 641 | } |
615 | offset += fs16_to_cpu(sb, de->d_reclen); | 642 | ufs_put_page(page); |
616 | de = (struct ufs_dir_entry *) | ||
617 | ((char *)de + fs16_to_cpu(sb, de->d_reclen)); | ||
618 | } | 643 | } |
619 | brelse (bh); | ||
620 | return 1; | 644 | return 1; |
645 | |||
646 | not_empty: | ||
647 | ufs_put_page(page); | ||
648 | return 0; | ||
621 | } | 649 | } |
622 | 650 | ||
623 | const struct file_operations ufs_dir_operations = { | 651 | const struct file_operations ufs_dir_operations = { |
diff --git a/fs/ufs/file.c b/fs/ufs/file.c index 312fd3f863..0e5001512a 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c | |||
@@ -25,6 +25,26 @@ | |||
25 | 25 | ||
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/ufs_fs.h> | 27 | #include <linux/ufs_fs.h> |
28 | #include <linux/buffer_head.h> /* for sync_mapping_buffers() */ | ||
29 | |||
30 | static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync) | ||
31 | { | ||
32 | struct inode *inode = dentry->d_inode; | ||
33 | int err; | ||
34 | int ret; | ||
35 | |||
36 | ret = sync_mapping_buffers(inode->i_mapping); | ||
37 | if (!(inode->i_state & I_DIRTY)) | ||
38 | return ret; | ||
39 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | ||
40 | return ret; | ||
41 | |||
42 | err = ufs_sync_inode(inode); | ||
43 | if (ret == 0) | ||
44 | ret = err; | ||
45 | return ret; | ||
46 | } | ||
47 | |||
28 | 48 | ||
29 | /* | 49 | /* |
30 | * We have mostly NULL's here: the current defaults are ok for | 50 | * We have mostly NULL's here: the current defaults are ok for |
@@ -37,6 +57,7 @@ const struct file_operations ufs_file_operations = { | |||
37 | .write = generic_file_write, | 57 | .write = generic_file_write, |
38 | .mmap = generic_file_mmap, | 58 | .mmap = generic_file_mmap, |
39 | .open = generic_file_open, | 59 | .open = generic_file_open, |
60 | .fsync = ufs_sync_file, | ||
40 | .sendfile = generic_file_sendfile, | 61 | .sendfile = generic_file_sendfile, |
41 | }; | 62 | }; |
42 | 63 | ||
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index c7a47ed4f4..9501dcd3b2 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -34,14 +34,6 @@ | |||
34 | #include "swab.h" | 34 | #include "swab.h" |
35 | #include "util.h" | 35 | #include "util.h" |
36 | 36 | ||
37 | #undef UFS_IALLOC_DEBUG | ||
38 | |||
39 | #ifdef UFS_IALLOC_DEBUG | ||
40 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
41 | #else | ||
42 | #define UFSD(x) | ||
43 | #endif | ||
44 | |||
45 | /* | 37 | /* |
46 | * NOTE! When we get the inode, we're the only people | 38 | * NOTE! When we get the inode, we're the only people |
47 | * that have access to it, and as such there are no | 39 | * that have access to it, and as such there are no |
@@ -68,7 +60,7 @@ void ufs_free_inode (struct inode * inode) | |||
68 | int is_directory; | 60 | int is_directory; |
69 | unsigned ino, cg, bit; | 61 | unsigned ino, cg, bit; |
70 | 62 | ||
71 | UFSD(("ENTER, ino %lu\n", inode->i_ino)) | 63 | UFSD("ENTER, ino %lu\n", inode->i_ino); |
72 | 64 | ||
73 | sb = inode->i_sb; | 65 | sb = inode->i_sb; |
74 | uspi = UFS_SB(sb)->s_uspi; | 66 | uspi = UFS_SB(sb)->s_uspi; |
@@ -91,7 +83,7 @@ void ufs_free_inode (struct inode * inode) | |||
91 | unlock_super (sb); | 83 | unlock_super (sb); |
92 | return; | 84 | return; |
93 | } | 85 | } |
94 | ucg = ubh_get_ucg(UCPI_UBH); | 86 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
95 | if (!ufs_cg_chkmagic(sb, ucg)) | 87 | if (!ufs_cg_chkmagic(sb, ucg)) |
96 | ufs_panic (sb, "ufs_free_fragments", "internal error, bad cg magic number"); | 88 | ufs_panic (sb, "ufs_free_fragments", "internal error, bad cg magic number"); |
97 | 89 | ||
@@ -104,33 +96,33 @@ void ufs_free_inode (struct inode * inode) | |||
104 | 96 | ||
105 | clear_inode (inode); | 97 | clear_inode (inode); |
106 | 98 | ||
107 | if (ubh_isclr (UCPI_UBH, ucpi->c_iusedoff, bit)) | 99 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit)) |
108 | ufs_error(sb, "ufs_free_inode", "bit already cleared for inode %u", ino); | 100 | ufs_error(sb, "ufs_free_inode", "bit already cleared for inode %u", ino); |
109 | else { | 101 | else { |
110 | ubh_clrbit (UCPI_UBH, ucpi->c_iusedoff, bit); | 102 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit); |
111 | if (ino < ucpi->c_irotor) | 103 | if (ino < ucpi->c_irotor) |
112 | ucpi->c_irotor = ino; | 104 | ucpi->c_irotor = ino; |
113 | fs32_add(sb, &ucg->cg_cs.cs_nifree, 1); | 105 | fs32_add(sb, &ucg->cg_cs.cs_nifree, 1); |
114 | fs32_add(sb, &usb1->fs_cstotal.cs_nifree, 1); | 106 | uspi->cs_total.cs_nifree++; |
115 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cg).cs_nifree, 1); | 107 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cg).cs_nifree, 1); |
116 | 108 | ||
117 | if (is_directory) { | 109 | if (is_directory) { |
118 | fs32_sub(sb, &ucg->cg_cs.cs_ndir, 1); | 110 | fs32_sub(sb, &ucg->cg_cs.cs_ndir, 1); |
119 | fs32_sub(sb, &usb1->fs_cstotal.cs_ndir, 1); | 111 | uspi->cs_total.cs_ndir--; |
120 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cg).cs_ndir, 1); | 112 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cg).cs_ndir, 1); |
121 | } | 113 | } |
122 | } | 114 | } |
123 | 115 | ||
124 | ubh_mark_buffer_dirty (USPI_UBH); | 116 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
125 | ubh_mark_buffer_dirty (UCPI_UBH); | 117 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
126 | if (sb->s_flags & MS_SYNCHRONOUS) { | 118 | if (sb->s_flags & MS_SYNCHRONOUS) { |
127 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **) &ucpi); | 119 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
128 | ubh_wait_on_buffer (UCPI_UBH); | 120 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
129 | } | 121 | } |
130 | 122 | ||
131 | sb->s_dirt = 1; | 123 | sb->s_dirt = 1; |
132 | unlock_super (sb); | 124 | unlock_super (sb); |
133 | UFSD(("EXIT\n")) | 125 | UFSD("EXIT\n"); |
134 | } | 126 | } |
135 | 127 | ||
136 | /* | 128 | /* |
@@ -155,7 +147,7 @@ struct inode * ufs_new_inode(struct inode * dir, int mode) | |||
155 | unsigned cg, bit, i, j, start; | 147 | unsigned cg, bit, i, j, start; |
156 | struct ufs_inode_info *ufsi; | 148 | struct ufs_inode_info *ufsi; |
157 | 149 | ||
158 | UFSD(("ENTER\n")) | 150 | UFSD("ENTER\n"); |
159 | 151 | ||
160 | /* Cannot create files in a deleted directory */ | 152 | /* Cannot create files in a deleted directory */ |
161 | if (!dir || !dir->i_nlink) | 153 | if (!dir || !dir->i_nlink) |
@@ -213,43 +205,43 @@ cg_found: | |||
213 | ucpi = ufs_load_cylinder (sb, cg); | 205 | ucpi = ufs_load_cylinder (sb, cg); |
214 | if (!ucpi) | 206 | if (!ucpi) |
215 | goto failed; | 207 | goto failed; |
216 | ucg = ubh_get_ucg(UCPI_UBH); | 208 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
217 | if (!ufs_cg_chkmagic(sb, ucg)) | 209 | if (!ufs_cg_chkmagic(sb, ucg)) |
218 | ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number"); | 210 | ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number"); |
219 | 211 | ||
220 | start = ucpi->c_irotor; | 212 | start = ucpi->c_irotor; |
221 | bit = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_iusedoff, uspi->s_ipg, start); | 213 | bit = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_iusedoff, uspi->s_ipg, start); |
222 | if (!(bit < uspi->s_ipg)) { | 214 | if (!(bit < uspi->s_ipg)) { |
223 | bit = ubh_find_first_zero_bit (UCPI_UBH, ucpi->c_iusedoff, start); | 215 | bit = ubh_find_first_zero_bit (UCPI_UBH(ucpi), ucpi->c_iusedoff, start); |
224 | if (!(bit < start)) { | 216 | if (!(bit < start)) { |
225 | ufs_error (sb, "ufs_new_inode", | 217 | ufs_error (sb, "ufs_new_inode", |
226 | "cylinder group %u corrupted - error in inode bitmap\n", cg); | 218 | "cylinder group %u corrupted - error in inode bitmap\n", cg); |
227 | goto failed; | 219 | goto failed; |
228 | } | 220 | } |
229 | } | 221 | } |
230 | UFSD(("start = %u, bit = %u, ipg = %u\n", start, bit, uspi->s_ipg)) | 222 | UFSD("start = %u, bit = %u, ipg = %u\n", start, bit, uspi->s_ipg); |
231 | if (ubh_isclr (UCPI_UBH, ucpi->c_iusedoff, bit)) | 223 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit)) |
232 | ubh_setbit (UCPI_UBH, ucpi->c_iusedoff, bit); | 224 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit); |
233 | else { | 225 | else { |
234 | ufs_panic (sb, "ufs_new_inode", "internal error"); | 226 | ufs_panic (sb, "ufs_new_inode", "internal error"); |
235 | goto failed; | 227 | goto failed; |
236 | } | 228 | } |
237 | 229 | ||
238 | fs32_sub(sb, &ucg->cg_cs.cs_nifree, 1); | 230 | fs32_sub(sb, &ucg->cg_cs.cs_nifree, 1); |
239 | fs32_sub(sb, &usb1->fs_cstotal.cs_nifree, 1); | 231 | uspi->cs_total.cs_nifree--; |
240 | fs32_sub(sb, &sbi->fs_cs(cg).cs_nifree, 1); | 232 | fs32_sub(sb, &sbi->fs_cs(cg).cs_nifree, 1); |
241 | 233 | ||
242 | if (S_ISDIR(mode)) { | 234 | if (S_ISDIR(mode)) { |
243 | fs32_add(sb, &ucg->cg_cs.cs_ndir, 1); | 235 | fs32_add(sb, &ucg->cg_cs.cs_ndir, 1); |
244 | fs32_add(sb, &usb1->fs_cstotal.cs_ndir, 1); | 236 | uspi->cs_total.cs_ndir++; |
245 | fs32_add(sb, &sbi->fs_cs(cg).cs_ndir, 1); | 237 | fs32_add(sb, &sbi->fs_cs(cg).cs_ndir, 1); |
246 | } | 238 | } |
247 | 239 | ||
248 | ubh_mark_buffer_dirty (USPI_UBH); | 240 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
249 | ubh_mark_buffer_dirty (UCPI_UBH); | 241 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
250 | if (sb->s_flags & MS_SYNCHRONOUS) { | 242 | if (sb->s_flags & MS_SYNCHRONOUS) { |
251 | ubh_ll_rw_block (SWRITE, 1, (struct ufs_buffer_head **) &ucpi); | 243 | ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi)); |
252 | ubh_wait_on_buffer (UCPI_UBH); | 244 | ubh_wait_on_buffer (UCPI_UBH(ucpi)); |
253 | } | 245 | } |
254 | sb->s_dirt = 1; | 246 | sb->s_dirt = 1; |
255 | 247 | ||
@@ -272,6 +264,7 @@ cg_found: | |||
272 | ufsi->i_shadow = 0; | 264 | ufsi->i_shadow = 0; |
273 | ufsi->i_osync = 0; | 265 | ufsi->i_osync = 0; |
274 | ufsi->i_oeftflag = 0; | 266 | ufsi->i_oeftflag = 0; |
267 | ufsi->i_dir_start_lookup = 0; | ||
275 | memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); | 268 | memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); |
276 | 269 | ||
277 | insert_inode_hash(inode); | 270 | insert_inode_hash(inode); |
@@ -287,14 +280,14 @@ cg_found: | |||
287 | return ERR_PTR(-EDQUOT); | 280 | return ERR_PTR(-EDQUOT); |
288 | } | 281 | } |
289 | 282 | ||
290 | UFSD(("allocating inode %lu\n", inode->i_ino)) | 283 | UFSD("allocating inode %lu\n", inode->i_ino); |
291 | UFSD(("EXIT\n")) | 284 | UFSD("EXIT\n"); |
292 | return inode; | 285 | return inode; |
293 | 286 | ||
294 | failed: | 287 | failed: |
295 | unlock_super (sb); | 288 | unlock_super (sb); |
296 | make_bad_inode(inode); | 289 | make_bad_inode(inode); |
297 | iput (inode); | 290 | iput (inode); |
298 | UFSD(("EXIT (FAILED)\n")) | 291 | UFSD("EXIT (FAILED)\n"); |
299 | return ERR_PTR(-ENOSPC); | 292 | return ERR_PTR(-ENOSPC); |
300 | } | 293 | } |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 3c3f62ce2a..488b5ff48a 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -41,14 +41,7 @@ | |||
41 | #include "swab.h" | 41 | #include "swab.h" |
42 | #include "util.h" | 42 | #include "util.h" |
43 | 43 | ||
44 | #undef UFS_INODE_DEBUG | 44 | static u64 ufs_frag_map(struct inode *inode, sector_t frag); |
45 | #undef UFS_INODE_DEBUG_MORE | ||
46 | |||
47 | #ifdef UFS_INODE_DEBUG | ||
48 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
49 | #else | ||
50 | #define UFSD(x) | ||
51 | #endif | ||
52 | 45 | ||
53 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) | 46 | static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4]) |
54 | { | 47 | { |
@@ -61,7 +54,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
61 | int n = 0; | 54 | int n = 0; |
62 | 55 | ||
63 | 56 | ||
64 | UFSD(("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks)); | 57 | UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); |
65 | if (i_block < 0) { | 58 | if (i_block < 0) { |
66 | ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); | 59 | ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); |
67 | } else if (i_block < direct_blocks) { | 60 | } else if (i_block < direct_blocks) { |
@@ -89,7 +82,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off | |||
89 | * the begining of the filesystem. | 82 | * the begining of the filesystem. |
90 | */ | 83 | */ |
91 | 84 | ||
92 | u64 ufs_frag_map(struct inode *inode, sector_t frag) | 85 | static u64 ufs_frag_map(struct inode *inode, sector_t frag) |
93 | { | 86 | { |
94 | struct ufs_inode_info *ufsi = UFS_I(inode); | 87 | struct ufs_inode_info *ufsi = UFS_I(inode); |
95 | struct super_block *sb = inode->i_sb; | 88 | struct super_block *sb = inode->i_sb; |
@@ -104,8 +97,10 @@ u64 ufs_frag_map(struct inode *inode, sector_t frag) | |||
104 | unsigned flags = UFS_SB(sb)->s_flags; | 97 | unsigned flags = UFS_SB(sb)->s_flags; |
105 | u64 temp = 0L; | 98 | u64 temp = 0L; |
106 | 99 | ||
107 | UFSD((": frag = %llu depth = %d\n", (unsigned long long)frag, depth)); | 100 | UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth); |
108 | UFSD((": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask)); | 101 | UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n", |
102 | uspi->s_fpbshift, uspi->s_apbmask, | ||
103 | (unsigned long long)mask); | ||
109 | 104 | ||
110 | if (depth == 0) | 105 | if (depth == 0) |
111 | return 0; | 106 | return 0; |
@@ -161,26 +156,64 @@ out: | |||
161 | return ret; | 156 | return ret; |
162 | } | 157 | } |
163 | 158 | ||
164 | static struct buffer_head * ufs_inode_getfrag (struct inode *inode, | 159 | static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) |
165 | unsigned int fragment, unsigned int new_fragment, | 160 | { |
166 | unsigned int required, int *err, int metadata, long *phys, int *new) | 161 | lock_buffer(bh); |
162 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | ||
163 | set_buffer_uptodate(bh); | ||
164 | mark_buffer_dirty(bh); | ||
165 | unlock_buffer(bh); | ||
166 | if (IS_SYNC(inode)) | ||
167 | sync_dirty_buffer(bh); | ||
168 | } | ||
169 | |||
170 | static struct buffer_head * | ||
171 | ufs_clear_frags(struct inode *inode, sector_t beg, | ||
172 | unsigned int n) | ||
173 | { | ||
174 | struct buffer_head *res, *bh; | ||
175 | sector_t end = beg + n; | ||
176 | |||
177 | res = sb_getblk(inode->i_sb, beg); | ||
178 | ufs_clear_frag(inode, res); | ||
179 | for (++beg; beg < end; ++beg) { | ||
180 | bh = sb_getblk(inode->i_sb, beg); | ||
181 | ufs_clear_frag(inode, bh); | ||
182 | brelse(bh); | ||
183 | } | ||
184 | return res; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * ufs_inode_getfrag() - allocate new fragment(s) | ||
189 | * @inode - pointer to inode | ||
190 | * @fragment - number of `fragment' which hold pointer | ||
191 | * to new allocated fragment(s) | ||
192 | * @new_fragment - number of new allocated fragment(s) | ||
193 | * @required - how many fragment(s) we require | ||
194 | * @err - we set it if something wrong | ||
195 | * @phys - pointer to where we save physical number of new allocated fragments, | ||
196 | * NULL if we allocate not data(indirect blocks for example). | ||
197 | * @new - we set it if we allocate new block | ||
198 | * @locked_page - for ufs_new_fragments() | ||
199 | */ | ||
200 | static struct buffer_head * | ||
201 | ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | ||
202 | sector_t new_fragment, unsigned int required, int *err, | ||
203 | long *phys, int *new, struct page *locked_page) | ||
167 | { | 204 | { |
168 | struct ufs_inode_info *ufsi = UFS_I(inode); | 205 | struct ufs_inode_info *ufsi = UFS_I(inode); |
169 | struct super_block * sb; | 206 | struct super_block *sb = inode->i_sb; |
170 | struct ufs_sb_private_info * uspi; | 207 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
171 | struct buffer_head * result; | 208 | struct buffer_head * result; |
172 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; | 209 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; |
173 | unsigned tmp, goal; | 210 | unsigned tmp, goal; |
174 | __fs32 * p, * p2; | 211 | __fs32 * p, * p2; |
175 | unsigned flags = 0; | ||
176 | 212 | ||
177 | UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u, required %u\n", | 213 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, required %u, " |
178 | inode->i_ino, fragment, new_fragment, required)) | 214 | "metadata %d\n", inode->i_ino, fragment, |
215 | (unsigned long long)new_fragment, required, !phys); | ||
179 | 216 | ||
180 | sb = inode->i_sb; | ||
181 | uspi = UFS_SB(sb)->s_uspi; | ||
182 | |||
183 | flags = UFS_SB(sb)->s_flags; | ||
184 | /* TODO : to be done for write support | 217 | /* TODO : to be done for write support |
185 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 218 | if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
186 | goto ufs2; | 219 | goto ufs2; |
@@ -195,16 +228,16 @@ repeat: | |||
195 | tmp = fs32_to_cpu(sb, *p); | 228 | tmp = fs32_to_cpu(sb, *p); |
196 | lastfrag = ufsi->i_lastfrag; | 229 | lastfrag = ufsi->i_lastfrag; |
197 | if (tmp && fragment < lastfrag) { | 230 | if (tmp && fragment < lastfrag) { |
198 | if (metadata) { | 231 | if (!phys) { |
199 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 232 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
200 | if (tmp == fs32_to_cpu(sb, *p)) { | 233 | if (tmp == fs32_to_cpu(sb, *p)) { |
201 | UFSD(("EXIT, result %u\n", tmp + blockoff)) | 234 | UFSD("EXIT, result %u\n", tmp + blockoff); |
202 | return result; | 235 | return result; |
203 | } | 236 | } |
204 | brelse (result); | 237 | brelse (result); |
205 | goto repeat; | 238 | goto repeat; |
206 | } else { | 239 | } else { |
207 | *phys = tmp; | 240 | *phys = tmp + blockoff; |
208 | return NULL; | 241 | return NULL; |
209 | } | 242 | } |
210 | } | 243 | } |
@@ -221,7 +254,8 @@ repeat: | |||
221 | if (lastblockoff) { | 254 | if (lastblockoff) { |
222 | p2 = ufsi->i_u1.i_data + lastblock; | 255 | p2 = ufsi->i_u1.i_data + lastblock; |
223 | tmp = ufs_new_fragments (inode, p2, lastfrag, | 256 | tmp = ufs_new_fragments (inode, p2, lastfrag, |
224 | fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff, err); | 257 | fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff, |
258 | err, locked_page); | ||
225 | if (!tmp) { | 259 | if (!tmp) { |
226 | if (lastfrag != ufsi->i_lastfrag) | 260 | if (lastfrag != ufsi->i_lastfrag) |
227 | goto repeat; | 261 | goto repeat; |
@@ -233,14 +267,16 @@ repeat: | |||
233 | } | 267 | } |
234 | goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; | 268 | goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; |
235 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 269 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, |
236 | goal, required + blockoff, err); | 270 | goal, required + blockoff, |
271 | err, locked_page); | ||
237 | } | 272 | } |
238 | /* | 273 | /* |
239 | * We will extend last allocated block | 274 | * We will extend last allocated block |
240 | */ | 275 | */ |
241 | else if (lastblock == block) { | 276 | else if (lastblock == block) { |
242 | tmp = ufs_new_fragments (inode, p, fragment - (blockoff - lastblockoff), | 277 | tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), |
243 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), err); | 278 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), |
279 | err, locked_page); | ||
244 | } | 280 | } |
245 | /* | 281 | /* |
246 | * We will allocate new block before last allocated block | 282 | * We will allocate new block before last allocated block |
@@ -248,8 +284,8 @@ repeat: | |||
248 | else /* (lastblock > block) */ { | 284 | else /* (lastblock > block) */ { |
249 | if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) | 285 | if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) |
250 | goal = tmp + uspi->s_fpb; | 286 | goal = tmp + uspi->s_fpb; |
251 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 287 | tmp = ufs_new_fragments(inode, p, fragment - blockoff, |
252 | goal, uspi->s_fpb, err); | 288 | goal, uspi->s_fpb, err, locked_page); |
253 | } | 289 | } |
254 | if (!tmp) { | 290 | if (!tmp) { |
255 | if ((!blockoff && *p) || | 291 | if ((!blockoff && *p) || |
@@ -259,14 +295,10 @@ repeat: | |||
259 | return NULL; | 295 | return NULL; |
260 | } | 296 | } |
261 | 297 | ||
262 | /* The nullification of framgents done in ufs/balloc.c is | 298 | if (!phys) { |
263 | * something I don't have the stomache to move into here right | 299 | result = ufs_clear_frags(inode, tmp + blockoff, required); |
264 | * now. -DaveM | ||
265 | */ | ||
266 | if (metadata) { | ||
267 | result = sb_getblk(inode->i_sb, tmp + blockoff); | ||
268 | } else { | 300 | } else { |
269 | *phys = tmp; | 301 | *phys = tmp + blockoff; |
270 | result = NULL; | 302 | result = NULL; |
271 | *err = 0; | 303 | *err = 0; |
272 | *new = 1; | 304 | *new = 1; |
@@ -276,7 +308,7 @@ repeat: | |||
276 | if (IS_SYNC(inode)) | 308 | if (IS_SYNC(inode)) |
277 | ufs_sync_inode (inode); | 309 | ufs_sync_inode (inode); |
278 | mark_inode_dirty(inode); | 310 | mark_inode_dirty(inode); |
279 | UFSD(("EXIT, result %u\n", tmp + blockoff)) | 311 | UFSD("EXIT, result %u\n", tmp + blockoff); |
280 | return result; | 312 | return result; |
281 | 313 | ||
282 | /* This part : To be implemented .... | 314 | /* This part : To be implemented .... |
@@ -295,22 +327,35 @@ repeat2: | |||
295 | */ | 327 | */ |
296 | } | 328 | } |
297 | 329 | ||
298 | static struct buffer_head * ufs_block_getfrag (struct inode *inode, | 330 | /** |
299 | struct buffer_head *bh, unsigned int fragment, unsigned int new_fragment, | 331 | * ufs_inode_getblock() - allocate new block |
300 | unsigned int blocksize, int * err, int metadata, long *phys, int *new) | 332 | * @inode - pointer to inode |
333 | * @bh - pointer to block which hold "pointer" to new allocated block | ||
334 | * @fragment - number of `fragment' which hold pointer | ||
335 | * to new allocated block | ||
336 | * @new_fragment - number of new allocated fragment | ||
337 | * (block will hold this fragment and also uspi->s_fpb-1) | ||
338 | * @err - see ufs_inode_getfrag() | ||
339 | * @phys - see ufs_inode_getfrag() | ||
340 | * @new - see ufs_inode_getfrag() | ||
341 | * @locked_page - see ufs_inode_getfrag() | ||
342 | */ | ||
343 | static struct buffer_head * | ||
344 | ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, | ||
345 | unsigned int fragment, sector_t new_fragment, int *err, | ||
346 | long *phys, int *new, struct page *locked_page) | ||
301 | { | 347 | { |
302 | struct super_block * sb; | 348 | struct super_block *sb = inode->i_sb; |
303 | struct ufs_sb_private_info * uspi; | 349 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
304 | struct buffer_head * result; | 350 | struct buffer_head * result; |
305 | unsigned tmp, goal, block, blockoff; | 351 | unsigned tmp, goal, block, blockoff; |
306 | __fs32 * p; | 352 | __fs32 * p; |
307 | 353 | ||
308 | sb = inode->i_sb; | ||
309 | uspi = UFS_SB(sb)->s_uspi; | ||
310 | block = ufs_fragstoblks (fragment); | 354 | block = ufs_fragstoblks (fragment); |
311 | blockoff = ufs_fragnum (fragment); | 355 | blockoff = ufs_fragnum (fragment); |
312 | 356 | ||
313 | UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment)) | 357 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, metadata %d\n", |
358 | inode->i_ino, fragment, (unsigned long long)new_fragment, !phys); | ||
314 | 359 | ||
315 | result = NULL; | 360 | result = NULL; |
316 | if (!bh) | 361 | if (!bh) |
@@ -326,14 +371,14 @@ static struct buffer_head * ufs_block_getfrag (struct inode *inode, | |||
326 | repeat: | 371 | repeat: |
327 | tmp = fs32_to_cpu(sb, *p); | 372 | tmp = fs32_to_cpu(sb, *p); |
328 | if (tmp) { | 373 | if (tmp) { |
329 | if (metadata) { | 374 | if (!phys) { |
330 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 375 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
331 | if (tmp == fs32_to_cpu(sb, *p)) | 376 | if (tmp == fs32_to_cpu(sb, *p)) |
332 | goto out; | 377 | goto out; |
333 | brelse (result); | 378 | brelse (result); |
334 | goto repeat; | 379 | goto repeat; |
335 | } else { | 380 | } else { |
336 | *phys = tmp; | 381 | *phys = tmp + blockoff; |
337 | goto out; | 382 | goto out; |
338 | } | 383 | } |
339 | } | 384 | } |
@@ -342,21 +387,19 @@ repeat: | |||
342 | goal = tmp + uspi->s_fpb; | 387 | goal = tmp + uspi->s_fpb; |
343 | else | 388 | else |
344 | goal = bh->b_blocknr + uspi->s_fpb; | 389 | goal = bh->b_blocknr + uspi->s_fpb; |
345 | tmp = ufs_new_fragments (inode, p, ufs_blknum(new_fragment), goal, uspi->s_fpb, err); | 390 | tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal, |
391 | uspi->s_fpb, err, locked_page); | ||
346 | if (!tmp) { | 392 | if (!tmp) { |
347 | if (fs32_to_cpu(sb, *p)) | 393 | if (fs32_to_cpu(sb, *p)) |
348 | goto repeat; | 394 | goto repeat; |
349 | goto out; | 395 | goto out; |
350 | } | 396 | } |
351 | 397 | ||
352 | /* The nullification of framgents done in ufs/balloc.c is | 398 | |
353 | * something I don't have the stomache to move into here right | 399 | if (!phys) { |
354 | * now. -DaveM | 400 | result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb); |
355 | */ | ||
356 | if (metadata) { | ||
357 | result = sb_getblk(sb, tmp + blockoff); | ||
358 | } else { | 401 | } else { |
359 | *phys = tmp; | 402 | *phys = tmp + blockoff; |
360 | *new = 1; | 403 | *new = 1; |
361 | } | 404 | } |
362 | 405 | ||
@@ -365,18 +408,19 @@ repeat: | |||
365 | sync_dirty_buffer(bh); | 408 | sync_dirty_buffer(bh); |
366 | inode->i_ctime = CURRENT_TIME_SEC; | 409 | inode->i_ctime = CURRENT_TIME_SEC; |
367 | mark_inode_dirty(inode); | 410 | mark_inode_dirty(inode); |
368 | UFSD(("result %u\n", tmp + blockoff)); | 411 | UFSD("result %u\n", tmp + blockoff); |
369 | out: | 412 | out: |
370 | brelse (bh); | 413 | brelse (bh); |
371 | UFSD(("EXIT\n")); | 414 | UFSD("EXIT\n"); |
372 | return result; | 415 | return result; |
373 | } | 416 | } |
374 | 417 | ||
375 | /* | 418 | /** |
376 | * This function gets the block which contains the fragment. | 419 | * ufs_getfrag_bloc() - `get_block_t' function, interface between UFS and |
420 | * readpage, writepage and so on | ||
377 | */ | 421 | */ |
378 | 422 | ||
379 | int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 423 | int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
380 | { | 424 | { |
381 | struct super_block * sb = inode->i_sb; | 425 | struct super_block * sb = inode->i_sb; |
382 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; | 426 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; |
@@ -387,7 +431,7 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
387 | 431 | ||
388 | if (!create) { | 432 | if (!create) { |
389 | phys64 = ufs_frag_map(inode, fragment); | 433 | phys64 = ufs_frag_map(inode, fragment); |
390 | UFSD(("phys64 = %llu \n",phys64)); | 434 | UFSD("phys64 = %llu\n", (unsigned long long)phys64); |
391 | if (phys64) | 435 | if (phys64) |
392 | map_bh(bh_result, sb, phys64); | 436 | map_bh(bh_result, sb, phys64); |
393 | return 0; | 437 | return 0; |
@@ -402,7 +446,7 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
402 | 446 | ||
403 | lock_kernel(); | 447 | lock_kernel(); |
404 | 448 | ||
405 | UFSD(("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment)) | 449 | UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
406 | if (fragment < 0) | 450 | if (fragment < 0) |
407 | goto abort_negative; | 451 | goto abort_negative; |
408 | if (fragment > | 452 | if (fragment > |
@@ -418,15 +462,15 @@ int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_hea | |||
418 | * it much more readable: | 462 | * it much more readable: |
419 | */ | 463 | */ |
420 | #define GET_INODE_DATABLOCK(x) \ | 464 | #define GET_INODE_DATABLOCK(x) \ |
421 | ufs_inode_getfrag(inode, x, fragment, 1, &err, 0, &phys, &new) | 465 | ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) |
422 | #define GET_INODE_PTR(x) \ | 466 | #define GET_INODE_PTR(x) \ |
423 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, 1, NULL, NULL) | 467 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, bh_result->b_page) |
424 | #define GET_INDIRECT_DATABLOCK(x) \ | 468 | #define GET_INDIRECT_DATABLOCK(x) \ |
425 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 469 | ufs_inode_getblock(inode, bh, x, fragment, \ |
426 | &err, 0, &phys, &new); | 470 | &err, &phys, &new, bh_result->b_page); |
427 | #define GET_INDIRECT_PTR(x) \ | 471 | #define GET_INDIRECT_PTR(x) \ |
428 | ufs_block_getfrag(inode, bh, x, fragment, sb->s_blocksize, \ | 472 | ufs_inode_getblock(inode, bh, x, fragment, \ |
429 | &err, 1, NULL, NULL); | 473 | &err, NULL, NULL, bh_result->b_page); |
430 | 474 | ||
431 | if (ptr < UFS_NDIR_FRAGMENT) { | 475 | if (ptr < UFS_NDIR_FRAGMENT) { |
432 | bh = GET_INODE_DATABLOCK(ptr); | 476 | bh = GET_INODE_DATABLOCK(ptr); |
@@ -474,8 +518,9 @@ abort_too_big: | |||
474 | goto abort; | 518 | goto abort; |
475 | } | 519 | } |
476 | 520 | ||
477 | struct buffer_head *ufs_getfrag(struct inode *inode, unsigned int fragment, | 521 | static struct buffer_head *ufs_getfrag(struct inode *inode, |
478 | int create, int *err) | 522 | unsigned int fragment, |
523 | int create, int *err) | ||
479 | { | 524 | { |
480 | struct buffer_head dummy; | 525 | struct buffer_head dummy; |
481 | int error; | 526 | int error; |
@@ -502,7 +547,7 @@ struct buffer_head * ufs_bread (struct inode * inode, unsigned fragment, | |||
502 | { | 547 | { |
503 | struct buffer_head * bh; | 548 | struct buffer_head * bh; |
504 | 549 | ||
505 | UFSD(("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment)) | 550 | UFSD("ENTER, ino %lu, fragment %u\n", inode->i_ino, fragment); |
506 | bh = ufs_getfrag (inode, fragment, create, err); | 551 | bh = ufs_getfrag (inode, fragment, create, err); |
507 | if (!bh || buffer_uptodate(bh)) | 552 | if (!bh || buffer_uptodate(bh)) |
508 | return bh; | 553 | return bh; |
@@ -531,7 +576,7 @@ static sector_t ufs_bmap(struct address_space *mapping, sector_t block) | |||
531 | { | 576 | { |
532 | return generic_block_bmap(mapping,block,ufs_getfrag_block); | 577 | return generic_block_bmap(mapping,block,ufs_getfrag_block); |
533 | } | 578 | } |
534 | struct address_space_operations ufs_aops = { | 579 | const struct address_space_operations ufs_aops = { |
535 | .readpage = ufs_readpage, | 580 | .readpage = ufs_readpage, |
536 | .writepage = ufs_writepage, | 581 | .writepage = ufs_writepage, |
537 | .sync_page = block_sync_page, | 582 | .sync_page = block_sync_page, |
@@ -540,39 +585,34 @@ struct address_space_operations ufs_aops = { | |||
540 | .bmap = ufs_bmap | 585 | .bmap = ufs_bmap |
541 | }; | 586 | }; |
542 | 587 | ||
543 | void ufs_read_inode (struct inode * inode) | 588 | static void ufs_set_inode_ops(struct inode *inode) |
589 | { | ||
590 | if (S_ISREG(inode->i_mode)) { | ||
591 | inode->i_op = &ufs_file_inode_operations; | ||
592 | inode->i_fop = &ufs_file_operations; | ||
593 | inode->i_mapping->a_ops = &ufs_aops; | ||
594 | } else if (S_ISDIR(inode->i_mode)) { | ||
595 | inode->i_op = &ufs_dir_inode_operations; | ||
596 | inode->i_fop = &ufs_dir_operations; | ||
597 | inode->i_mapping->a_ops = &ufs_aops; | ||
598 | } else if (S_ISLNK(inode->i_mode)) { | ||
599 | if (!inode->i_blocks) | ||
600 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
601 | else { | ||
602 | inode->i_op = &page_symlink_inode_operations; | ||
603 | inode->i_mapping->a_ops = &ufs_aops; | ||
604 | } | ||
605 | } else | ||
606 | init_special_inode(inode, inode->i_mode, | ||
607 | ufs_get_inode_dev(inode->i_sb, UFS_I(inode))); | ||
608 | } | ||
609 | |||
610 | static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) | ||
544 | { | 611 | { |
545 | struct ufs_inode_info *ufsi = UFS_I(inode); | 612 | struct ufs_inode_info *ufsi = UFS_I(inode); |
546 | struct super_block * sb; | 613 | struct super_block *sb = inode->i_sb; |
547 | struct ufs_sb_private_info * uspi; | ||
548 | struct ufs_inode * ufs_inode; | ||
549 | struct ufs2_inode *ufs2_inode; | ||
550 | struct buffer_head * bh; | ||
551 | mode_t mode; | 614 | mode_t mode; |
552 | unsigned i; | 615 | unsigned i; |
553 | unsigned flags; | ||
554 | |||
555 | UFSD(("ENTER, ino %lu\n", inode->i_ino)) | ||
556 | |||
557 | sb = inode->i_sb; | ||
558 | uspi = UFS_SB(sb)->s_uspi; | ||
559 | flags = UFS_SB(sb)->s_flags; | ||
560 | |||
561 | if (inode->i_ino < UFS_ROOTINO || | ||
562 | inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) { | ||
563 | ufs_warning (sb, "ufs_read_inode", "bad inode number (%lu)\n", inode->i_ino); | ||
564 | goto bad_inode; | ||
565 | } | ||
566 | |||
567 | bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino)); | ||
568 | if (!bh) { | ||
569 | ufs_warning (sb, "ufs_read_inode", "unable to read inode %lu\n", inode->i_ino); | ||
570 | goto bad_inode; | ||
571 | } | ||
572 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | ||
573 | goto ufs2_inode; | ||
574 | |||
575 | ufs_inode = (struct ufs_inode *) (bh->b_data + sizeof(struct ufs_inode) * ufs_inotofsbo(inode->i_ino)); | ||
576 | 616 | ||
577 | /* | 617 | /* |
578 | * Copy data to the in-core inode. | 618 | * Copy data to the in-core inode. |
@@ -596,56 +636,29 @@ void ufs_read_inode (struct inode * inode) | |||
596 | inode->i_atime.tv_nsec = 0; | 636 | inode->i_atime.tv_nsec = 0; |
597 | inode->i_ctime.tv_nsec = 0; | 637 | inode->i_ctime.tv_nsec = 0; |
598 | inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks); | 638 | inode->i_blocks = fs32_to_cpu(sb, ufs_inode->ui_blocks); |
599 | inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat) */ | ||
600 | inode->i_version++; | ||
601 | ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags); | 639 | ufsi->i_flags = fs32_to_cpu(sb, ufs_inode->ui_flags); |
602 | ufsi->i_gen = fs32_to_cpu(sb, ufs_inode->ui_gen); | 640 | ufsi->i_gen = fs32_to_cpu(sb, ufs_inode->ui_gen); |
603 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); | 641 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); |
604 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); | 642 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); |
605 | ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; | 643 | |
606 | 644 | ||
607 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { | 645 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { |
608 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) | 646 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) |
609 | ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; | 647 | ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; |
610 | } | 648 | } else { |
611 | else { | ||
612 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) | 649 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) |
613 | ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i]; | 650 | ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i]; |
614 | } | 651 | } |
615 | ufsi->i_osync = 0; | 652 | } |
616 | |||
617 | if (S_ISREG(inode->i_mode)) { | ||
618 | inode->i_op = &ufs_file_inode_operations; | ||
619 | inode->i_fop = &ufs_file_operations; | ||
620 | inode->i_mapping->a_ops = &ufs_aops; | ||
621 | } else if (S_ISDIR(inode->i_mode)) { | ||
622 | inode->i_op = &ufs_dir_inode_operations; | ||
623 | inode->i_fop = &ufs_dir_operations; | ||
624 | } else if (S_ISLNK(inode->i_mode)) { | ||
625 | if (!inode->i_blocks) | ||
626 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
627 | else { | ||
628 | inode->i_op = &page_symlink_inode_operations; | ||
629 | inode->i_mapping->a_ops = &ufs_aops; | ||
630 | } | ||
631 | } else | ||
632 | init_special_inode(inode, inode->i_mode, | ||
633 | ufs_get_inode_dev(sb, ufsi)); | ||
634 | |||
635 | brelse (bh); | ||
636 | |||
637 | UFSD(("EXIT\n")) | ||
638 | return; | ||
639 | |||
640 | bad_inode: | ||
641 | make_bad_inode(inode); | ||
642 | return; | ||
643 | |||
644 | ufs2_inode : | ||
645 | UFSD(("Reading ufs2 inode, ino %lu\n", inode->i_ino)) | ||
646 | 653 | ||
647 | ufs2_inode = (struct ufs2_inode *)(bh->b_data + sizeof(struct ufs2_inode) * ufs_inotofsbo(inode->i_ino)); | 654 | static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) |
655 | { | ||
656 | struct ufs_inode_info *ufsi = UFS_I(inode); | ||
657 | struct super_block *sb = inode->i_sb; | ||
658 | mode_t mode; | ||
659 | unsigned i; | ||
648 | 660 | ||
661 | UFSD("Reading ufs2 inode, ino %lu\n", inode->i_ino); | ||
649 | /* | 662 | /* |
650 | * Copy data to the in-core inode. | 663 | * Copy data to the in-core inode. |
651 | */ | 664 | */ |
@@ -668,50 +681,75 @@ ufs2_inode : | |||
668 | inode->i_atime.tv_nsec = 0; | 681 | inode->i_atime.tv_nsec = 0; |
669 | inode->i_ctime.tv_nsec = 0; | 682 | inode->i_ctime.tv_nsec = 0; |
670 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); | 683 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
671 | inode->i_blksize = PAGE_SIZE; /*This is the optimal IO size(for stat)*/ | ||
672 | |||
673 | inode->i_version++; | ||
674 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); | 684 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
675 | ufsi->i_gen = fs32_to_cpu(sb, ufs2_inode->ui_gen); | 685 | ufsi->i_gen = fs32_to_cpu(sb, ufs2_inode->ui_gen); |
676 | /* | 686 | /* |
677 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); | 687 | ufsi->i_shadow = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_shadow); |
678 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); | 688 | ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); |
679 | */ | 689 | */ |
680 | ufsi->i_lastfrag= (inode->i_size + uspi->s_fsize- 1) >> uspi->s_fshift; | ||
681 | 690 | ||
682 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { | 691 | if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { |
683 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) | 692 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) |
684 | ufsi->i_u1.u2_i_data[i] = | 693 | ufsi->i_u1.u2_i_data[i] = |
685 | ufs2_inode->ui_u2.ui_addr.ui_db[i]; | 694 | ufs2_inode->ui_u2.ui_addr.ui_db[i]; |
686 | } | 695 | } else { |
687 | else { | ||
688 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) | 696 | for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++) |
689 | ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i]; | 697 | ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i]; |
690 | } | 698 | } |
699 | } | ||
700 | |||
701 | void ufs_read_inode(struct inode * inode) | ||
702 | { | ||
703 | struct ufs_inode_info *ufsi = UFS_I(inode); | ||
704 | struct super_block * sb; | ||
705 | struct ufs_sb_private_info * uspi; | ||
706 | struct buffer_head * bh; | ||
707 | |||
708 | UFSD("ENTER, ino %lu\n", inode->i_ino); | ||
709 | |||
710 | sb = inode->i_sb; | ||
711 | uspi = UFS_SB(sb)->s_uspi; | ||
712 | |||
713 | if (inode->i_ino < UFS_ROOTINO || | ||
714 | inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) { | ||
715 | ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu)\n", | ||
716 | inode->i_ino); | ||
717 | goto bad_inode; | ||
718 | } | ||
719 | |||
720 | bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino)); | ||
721 | if (!bh) { | ||
722 | ufs_warning(sb, "ufs_read_inode", "unable to read inode %lu\n", | ||
723 | inode->i_ino); | ||
724 | goto bad_inode; | ||
725 | } | ||
726 | if ((UFS_SB(sb)->s_flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { | ||
727 | struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data; | ||
728 | |||
729 | ufs2_read_inode(inode, | ||
730 | ufs2_inode + ufs_inotofsbo(inode->i_ino)); | ||
731 | } else { | ||
732 | struct ufs_inode *ufs_inode = (struct ufs_inode *)bh->b_data; | ||
733 | |||
734 | ufs1_read_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino)); | ||
735 | } | ||
736 | |||
737 | inode->i_blksize = PAGE_SIZE;/*This is the optimal IO size (for stat)*/ | ||
738 | inode->i_version++; | ||
739 | ufsi->i_lastfrag = | ||
740 | (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; | ||
741 | ufsi->i_dir_start_lookup = 0; | ||
691 | ufsi->i_osync = 0; | 742 | ufsi->i_osync = 0; |
692 | 743 | ||
693 | if (S_ISREG(inode->i_mode)) { | 744 | ufs_set_inode_ops(inode); |
694 | inode->i_op = &ufs_file_inode_operations; | ||
695 | inode->i_fop = &ufs_file_operations; | ||
696 | inode->i_mapping->a_ops = &ufs_aops; | ||
697 | } else if (S_ISDIR(inode->i_mode)) { | ||
698 | inode->i_op = &ufs_dir_inode_operations; | ||
699 | inode->i_fop = &ufs_dir_operations; | ||
700 | } else if (S_ISLNK(inode->i_mode)) { | ||
701 | if (!inode->i_blocks) | ||
702 | inode->i_op = &ufs_fast_symlink_inode_operations; | ||
703 | else { | ||
704 | inode->i_op = &page_symlink_inode_operations; | ||
705 | inode->i_mapping->a_ops = &ufs_aops; | ||
706 | } | ||
707 | } else /* TODO : here ...*/ | ||
708 | init_special_inode(inode, inode->i_mode, | ||
709 | ufs_get_inode_dev(sb, ufsi)); | ||
710 | 745 | ||
711 | brelse(bh); | 746 | brelse(bh); |
712 | 747 | ||
713 | UFSD(("EXIT\n")) | 748 | UFSD("EXIT\n"); |
714 | return; | 749 | return; |
750 | |||
751 | bad_inode: | ||
752 | make_bad_inode(inode); | ||
715 | } | 753 | } |
716 | 754 | ||
717 | static int ufs_update_inode(struct inode * inode, int do_sync) | 755 | static int ufs_update_inode(struct inode * inode, int do_sync) |
@@ -724,7 +762,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
724 | unsigned i; | 762 | unsigned i; |
725 | unsigned flags; | 763 | unsigned flags; |
726 | 764 | ||
727 | UFSD(("ENTER, ino %lu\n", inode->i_ino)) | 765 | UFSD("ENTER, ino %lu\n", inode->i_ino); |
728 | 766 | ||
729 | sb = inode->i_sb; | 767 | sb = inode->i_sb; |
730 | uspi = UFS_SB(sb)->s_uspi; | 768 | uspi = UFS_SB(sb)->s_uspi; |
@@ -785,7 +823,7 @@ static int ufs_update_inode(struct inode * inode, int do_sync) | |||
785 | sync_dirty_buffer(bh); | 823 | sync_dirty_buffer(bh); |
786 | brelse (bh); | 824 | brelse (bh); |
787 | 825 | ||
788 | UFSD(("EXIT\n")) | 826 | UFSD("EXIT\n"); |
789 | return 0; | 827 | return 0; |
790 | } | 828 | } |
791 | 829 | ||
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 8d5f98a01c..abd5f23a42 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/ufs/namei.c | 2 | * linux/fs/ufs/namei.c |
3 | * | 3 | * |
4 | * Migration to usage of "page cache" on May 2006 by | ||
5 | * Evgeniy Dushistov <dushistov@mail.ru> based on ext2 code base. | ||
6 | * | ||
4 | * Copyright (C) 1998 | 7 | * Copyright (C) 1998 |
5 | * Daniel Pirkl <daniel.pirkl@email.cz> | 8 | * Daniel Pirkl <daniel.pirkl@email.cz> |
6 | * Charles University, Faculty of Mathematics and Physics | 9 | * Charles University, Faculty of Mathematics and Physics |
@@ -28,21 +31,9 @@ | |||
28 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
29 | #include <linux/ufs_fs.h> | 32 | #include <linux/ufs_fs.h> |
30 | #include <linux/smp_lock.h> | 33 | #include <linux/smp_lock.h> |
31 | #include <linux/buffer_head.h> | ||
32 | #include "swab.h" /* will go away - see comment in mknod() */ | 34 | #include "swab.h" /* will go away - see comment in mknod() */ |
33 | #include "util.h" | 35 | #include "util.h" |
34 | 36 | ||
35 | /* | ||
36 | #undef UFS_NAMEI_DEBUG | ||
37 | */ | ||
38 | #define UFS_NAMEI_DEBUG | ||
39 | |||
40 | #ifdef UFS_NAMEI_DEBUG | ||
41 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
42 | #else | ||
43 | #define UFSD(x) | ||
44 | #endif | ||
45 | |||
46 | static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) | 37 | static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) |
47 | { | 38 | { |
48 | int err = ufs_add_link(dentry, inode); | 39 | int err = ufs_add_link(dentry, inode); |
@@ -88,8 +79,13 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru | |||
88 | static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, | 79 | static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, |
89 | struct nameidata *nd) | 80 | struct nameidata *nd) |
90 | { | 81 | { |
91 | struct inode * inode = ufs_new_inode(dir, mode); | 82 | struct inode *inode; |
92 | int err = PTR_ERR(inode); | 83 | int err; |
84 | |||
85 | UFSD("BEGIN\n"); | ||
86 | inode = ufs_new_inode(dir, mode); | ||
87 | err = PTR_ERR(inode); | ||
88 | |||
93 | if (!IS_ERR(inode)) { | 89 | if (!IS_ERR(inode)) { |
94 | inode->i_op = &ufs_file_inode_operations; | 90 | inode->i_op = &ufs_file_inode_operations; |
95 | inode->i_fop = &ufs_file_operations; | 91 | inode->i_fop = &ufs_file_operations; |
@@ -99,6 +95,7 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, | |||
99 | err = ufs_add_nondir(dentry, inode); | 95 | err = ufs_add_nondir(dentry, inode); |
100 | unlock_kernel(); | 96 | unlock_kernel(); |
101 | } | 97 | } |
98 | UFSD("END: err=%d\n", err); | ||
102 | return err; | 99 | return err; |
103 | } | 100 | } |
104 | 101 | ||
@@ -205,6 +202,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
205 | 202 | ||
206 | inode->i_op = &ufs_dir_inode_operations; | 203 | inode->i_op = &ufs_dir_inode_operations; |
207 | inode->i_fop = &ufs_dir_operations; | 204 | inode->i_fop = &ufs_dir_operations; |
205 | inode->i_mapping->a_ops = &ufs_aops; | ||
208 | 206 | ||
209 | inode_inc_link_count(inode); | 207 | inode_inc_link_count(inode); |
210 | 208 | ||
@@ -231,19 +229,18 @@ out_dir: | |||
231 | goto out; | 229 | goto out; |
232 | } | 230 | } |
233 | 231 | ||
234 | static int ufs_unlink(struct inode * dir, struct dentry *dentry) | 232 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) |
235 | { | 233 | { |
236 | struct inode * inode = dentry->d_inode; | 234 | struct inode * inode = dentry->d_inode; |
237 | struct buffer_head * bh; | 235 | struct ufs_dir_entry *de; |
238 | struct ufs_dir_entry * de; | 236 | struct page *page; |
239 | int err = -ENOENT; | 237 | int err = -ENOENT; |
240 | 238 | ||
241 | lock_kernel(); | 239 | de = ufs_find_entry(dir, dentry, &page); |
242 | de = ufs_find_entry (dentry, &bh); | ||
243 | if (!de) | 240 | if (!de) |
244 | goto out; | 241 | goto out; |
245 | 242 | ||
246 | err = ufs_delete_entry (dir, de, bh); | 243 | err = ufs_delete_entry(dir, de, page); |
247 | if (err) | 244 | if (err) |
248 | goto out; | 245 | goto out; |
249 | 246 | ||
@@ -251,7 +248,6 @@ static int ufs_unlink(struct inode * dir, struct dentry *dentry) | |||
251 | inode_dec_link_count(inode); | 248 | inode_dec_link_count(inode); |
252 | err = 0; | 249 | err = 0; |
253 | out: | 250 | out: |
254 | unlock_kernel(); | ||
255 | return err; | 251 | return err; |
256 | } | 252 | } |
257 | 253 | ||
@@ -273,42 +269,42 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
273 | return err; | 269 | return err; |
274 | } | 270 | } |
275 | 271 | ||
276 | static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry, | 272 | static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, |
277 | struct inode * new_dir, struct dentry * new_dentry ) | 273 | struct inode *new_dir, struct dentry *new_dentry) |
278 | { | 274 | { |
279 | struct inode *old_inode = old_dentry->d_inode; | 275 | struct inode *old_inode = old_dentry->d_inode; |
280 | struct inode *new_inode = new_dentry->d_inode; | 276 | struct inode *new_inode = new_dentry->d_inode; |
281 | struct buffer_head *dir_bh = NULL; | 277 | struct page *dir_page = NULL; |
282 | struct ufs_dir_entry *dir_de = NULL; | 278 | struct ufs_dir_entry * dir_de = NULL; |
283 | struct buffer_head *old_bh; | 279 | struct page *old_page; |
284 | struct ufs_dir_entry *old_de; | 280 | struct ufs_dir_entry *old_de; |
285 | int err = -ENOENT; | 281 | int err = -ENOENT; |
286 | 282 | ||
287 | lock_kernel(); | 283 | old_de = ufs_find_entry(old_dir, old_dentry, &old_page); |
288 | old_de = ufs_find_entry (old_dentry, &old_bh); | ||
289 | if (!old_de) | 284 | if (!old_de) |
290 | goto out; | 285 | goto out; |
291 | 286 | ||
292 | if (S_ISDIR(old_inode->i_mode)) { | 287 | if (S_ISDIR(old_inode->i_mode)) { |
293 | err = -EIO; | 288 | err = -EIO; |
294 | dir_de = ufs_dotdot(old_inode, &dir_bh); | 289 | dir_de = ufs_dotdot(old_inode, &dir_page); |
295 | if (!dir_de) | 290 | if (!dir_de) |
296 | goto out_old; | 291 | goto out_old; |
297 | } | 292 | } |
298 | 293 | ||
299 | if (new_inode) { | 294 | if (new_inode) { |
300 | struct buffer_head *new_bh; | 295 | struct page *new_page; |
301 | struct ufs_dir_entry *new_de; | 296 | struct ufs_dir_entry *new_de; |
302 | 297 | ||
303 | err = -ENOTEMPTY; | 298 | err = -ENOTEMPTY; |
304 | if (dir_de && !ufs_empty_dir (new_inode)) | 299 | if (dir_de && !ufs_empty_dir(new_inode)) |
305 | goto out_dir; | 300 | goto out_dir; |
301 | |||
306 | err = -ENOENT; | 302 | err = -ENOENT; |
307 | new_de = ufs_find_entry (new_dentry, &new_bh); | 303 | new_de = ufs_find_entry(new_dir, new_dentry, &new_page); |
308 | if (!new_de) | 304 | if (!new_de) |
309 | goto out_dir; | 305 | goto out_dir; |
310 | inode_inc_link_count(old_inode); | 306 | inode_inc_link_count(old_inode); |
311 | ufs_set_link(new_dir, new_de, new_bh, old_inode); | 307 | ufs_set_link(new_dir, new_de, new_page, old_inode); |
312 | new_inode->i_ctime = CURRENT_TIME_SEC; | 308 | new_inode->i_ctime = CURRENT_TIME_SEC; |
313 | if (dir_de) | 309 | if (dir_de) |
314 | new_inode->i_nlink--; | 310 | new_inode->i_nlink--; |
@@ -329,24 +325,32 @@ static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
329 | inode_inc_link_count(new_dir); | 325 | inode_inc_link_count(new_dir); |
330 | } | 326 | } |
331 | 327 | ||
332 | ufs_delete_entry (old_dir, old_de, old_bh); | 328 | /* |
329 | * Like most other Unix systems, set the ctime for inodes on a | ||
330 | * rename. | ||
331 | * inode_dec_link_count() will mark the inode dirty. | ||
332 | */ | ||
333 | old_inode->i_ctime = CURRENT_TIME_SEC; | ||
333 | 334 | ||
335 | ufs_delete_entry(old_dir, old_de, old_page); | ||
334 | inode_dec_link_count(old_inode); | 336 | inode_dec_link_count(old_inode); |
335 | 337 | ||
336 | if (dir_de) { | 338 | if (dir_de) { |
337 | ufs_set_link(old_inode, dir_de, dir_bh, new_dir); | 339 | ufs_set_link(old_inode, dir_de, dir_page, new_dir); |
338 | inode_dec_link_count(old_dir); | 340 | inode_dec_link_count(old_dir); |
339 | } | 341 | } |
340 | unlock_kernel(); | ||
341 | return 0; | 342 | return 0; |
342 | 343 | ||
344 | |||
343 | out_dir: | 345 | out_dir: |
344 | if (dir_de) | 346 | if (dir_de) { |
345 | brelse(dir_bh); | 347 | kunmap(dir_page); |
348 | page_cache_release(dir_page); | ||
349 | } | ||
346 | out_old: | 350 | out_old: |
347 | brelse (old_bh); | 351 | kunmap(old_page); |
352 | page_cache_release(old_page); | ||
348 | out: | 353 | out: |
349 | unlock_kernel(); | ||
350 | return err; | 354 | return err; |
351 | } | 355 | } |
352 | 356 | ||
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index db98a4c71e..74ef5e9bed 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -90,95 +90,84 @@ | |||
90 | #include "swab.h" | 90 | #include "swab.h" |
91 | #include "util.h" | 91 | #include "util.h" |
92 | 92 | ||
93 | #undef UFS_SUPER_DEBUG | 93 | #ifdef CONFIG_UFS_DEBUG |
94 | #undef UFS_SUPER_DEBUG_MORE | ||
95 | |||
96 | |||
97 | #undef UFS_SUPER_DEBUG_MORE | ||
98 | #ifdef UFS_SUPER_DEBUG | ||
99 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
100 | #else | ||
101 | #define UFSD(x) | ||
102 | #endif | ||
103 | |||
104 | #ifdef UFS_SUPER_DEBUG_MORE | ||
105 | /* | 94 | /* |
106 | * Print contents of ufs_super_block, useful for debugging | 95 | * Print contents of ufs_super_block, useful for debugging |
107 | */ | 96 | */ |
108 | void ufs_print_super_stuff(struct super_block *sb, | 97 | static void ufs_print_super_stuff(struct super_block *sb, unsigned flags, |
109 | struct ufs_super_block_first * usb1, | 98 | struct ufs_super_block_first *usb1, |
110 | struct ufs_super_block_second * usb2, | 99 | struct ufs_super_block_second *usb2, |
111 | struct ufs_super_block_third * usb3) | 100 | struct ufs_super_block_third *usb3) |
112 | { | 101 | { |
113 | printk("ufs_print_super_stuff\n"); | 102 | printk("ufs_print_super_stuff\n"); |
114 | printk("size of usb: %u\n", sizeof(struct ufs_super_block)); | 103 | printk(" magic: 0x%x\n", fs32_to_cpu(sb, usb3->fs_magic)); |
115 | printk(" magic: 0x%x\n", fs32_to_cpu(sb, usb3->fs_magic)); | 104 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { |
116 | printk(" sblkno: %u\n", fs32_to_cpu(sb, usb1->fs_sblkno)); | 105 | printk(" fs_size: %llu\n", (unsigned long long) |
117 | printk(" cblkno: %u\n", fs32_to_cpu(sb, usb1->fs_cblkno)); | 106 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size)); |
118 | printk(" iblkno: %u\n", fs32_to_cpu(sb, usb1->fs_iblkno)); | 107 | printk(" fs_dsize: %llu\n", (unsigned long long) |
119 | printk(" dblkno: %u\n", fs32_to_cpu(sb, usb1->fs_dblkno)); | 108 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize)); |
120 | printk(" cgoffset: %u\n", fs32_to_cpu(sb, usb1->fs_cgoffset)); | 109 | printk(" bsize: %u\n", |
121 | printk(" ~cgmask: 0x%x\n", ~fs32_to_cpu(sb, usb1->fs_cgmask)); | 110 | fs32_to_cpu(sb, usb1->fs_bsize)); |
122 | printk(" size: %u\n", fs32_to_cpu(sb, usb1->fs_size)); | 111 | printk(" fsize: %u\n", |
123 | printk(" dsize: %u\n", fs32_to_cpu(sb, usb1->fs_dsize)); | 112 | fs32_to_cpu(sb, usb1->fs_fsize)); |
124 | printk(" ncg: %u\n", fs32_to_cpu(sb, usb1->fs_ncg)); | 113 | printk(" fs_volname: %s\n", usb2->fs_un.fs_u2.fs_volname); |
125 | printk(" bsize: %u\n", fs32_to_cpu(sb, usb1->fs_bsize)); | 114 | printk(" fs_sblockloc: %llu\n", (unsigned long long) |
126 | printk(" fsize: %u\n", fs32_to_cpu(sb, usb1->fs_fsize)); | 115 | fs64_to_cpu(sb, usb2->fs_un.fs_u2.fs_sblockloc)); |
127 | printk(" frag: %u\n", fs32_to_cpu(sb, usb1->fs_frag)); | 116 | printk(" cs_ndir(No of dirs): %llu\n", (unsigned long long) |
128 | printk(" fragshift: %u\n", fs32_to_cpu(sb, usb1->fs_fragshift)); | 117 | fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir)); |
129 | printk(" ~fmask: %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask)); | 118 | printk(" cs_nbfree(No of free blocks): %llu\n", |
130 | printk(" fshift: %u\n", fs32_to_cpu(sb, usb1->fs_fshift)); | 119 | (unsigned long long) |
131 | printk(" sbsize: %u\n", fs32_to_cpu(sb, usb1->fs_sbsize)); | 120 | fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree)); |
132 | printk(" spc: %u\n", fs32_to_cpu(sb, usb1->fs_spc)); | 121 | } else { |
133 | printk(" cpg: %u\n", fs32_to_cpu(sb, usb1->fs_cpg)); | 122 | printk(" sblkno: %u\n", fs32_to_cpu(sb, usb1->fs_sblkno)); |
134 | printk(" ipg: %u\n", fs32_to_cpu(sb, usb1->fs_ipg)); | 123 | printk(" cblkno: %u\n", fs32_to_cpu(sb, usb1->fs_cblkno)); |
135 | printk(" fpg: %u\n", fs32_to_cpu(sb, usb1->fs_fpg)); | 124 | printk(" iblkno: %u\n", fs32_to_cpu(sb, usb1->fs_iblkno)); |
136 | printk(" csaddr: %u\n", fs32_to_cpu(sb, usb1->fs_csaddr)); | 125 | printk(" dblkno: %u\n", fs32_to_cpu(sb, usb1->fs_dblkno)); |
137 | printk(" cssize: %u\n", fs32_to_cpu(sb, usb1->fs_cssize)); | 126 | printk(" cgoffset: %u\n", |
138 | printk(" cgsize: %u\n", fs32_to_cpu(sb, usb1->fs_cgsize)); | 127 | fs32_to_cpu(sb, usb1->fs_cgoffset)); |
139 | printk(" fstodb: %u\n", fs32_to_cpu(sb, usb1->fs_fsbtodb)); | 128 | printk(" ~cgmask: 0x%x\n", |
140 | printk(" contigsumsize: %d\n", fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize)); | 129 | ~fs32_to_cpu(sb, usb1->fs_cgmask)); |
141 | printk(" postblformat: %u\n", fs32_to_cpu(sb, usb3->fs_postblformat)); | 130 | printk(" size: %u\n", fs32_to_cpu(sb, usb1->fs_size)); |
142 | printk(" nrpos: %u\n", fs32_to_cpu(sb, usb3->fs_nrpos)); | 131 | printk(" dsize: %u\n", fs32_to_cpu(sb, usb1->fs_dsize)); |
143 | printk(" ndir %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir)); | 132 | printk(" ncg: %u\n", fs32_to_cpu(sb, usb1->fs_ncg)); |
144 | printk(" nifree %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree)); | 133 | printk(" bsize: %u\n", fs32_to_cpu(sb, usb1->fs_bsize)); |
145 | printk(" nbfree %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)); | 134 | printk(" fsize: %u\n", fs32_to_cpu(sb, usb1->fs_fsize)); |
146 | printk(" nffree %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree)); | 135 | printk(" frag: %u\n", fs32_to_cpu(sb, usb1->fs_frag)); |
147 | printk("\n"); | 136 | printk(" fragshift: %u\n", |
148 | } | 137 | fs32_to_cpu(sb, usb1->fs_fragshift)); |
149 | 138 | printk(" ~fmask: %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask)); | |
150 | /* | 139 | printk(" fshift: %u\n", fs32_to_cpu(sb, usb1->fs_fshift)); |
151 | * Print contents of ufs2 ufs_super_block, useful for debugging | 140 | printk(" sbsize: %u\n", fs32_to_cpu(sb, usb1->fs_sbsize)); |
152 | */ | 141 | printk(" spc: %u\n", fs32_to_cpu(sb, usb1->fs_spc)); |
153 | void ufs2_print_super_stuff( | 142 | printk(" cpg: %u\n", fs32_to_cpu(sb, usb1->fs_cpg)); |
154 | struct super_block *sb, | 143 | printk(" ipg: %u\n", fs32_to_cpu(sb, usb1->fs_ipg)); |
155 | struct ufs_super_block *usb) | 144 | printk(" fpg: %u\n", fs32_to_cpu(sb, usb1->fs_fpg)); |
156 | { | 145 | printk(" csaddr: %u\n", fs32_to_cpu(sb, usb1->fs_csaddr)); |
157 | printk("ufs_print_super_stuff\n"); | 146 | printk(" cssize: %u\n", fs32_to_cpu(sb, usb1->fs_cssize)); |
158 | printk("size of usb: %u\n", sizeof(struct ufs_super_block)); | 147 | printk(" cgsize: %u\n", fs32_to_cpu(sb, usb1->fs_cgsize)); |
159 | printk(" magic: 0x%x\n", fs32_to_cpu(sb, usb->fs_magic)); | 148 | printk(" fstodb: %u\n", |
160 | printk(" fs_size: %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_size)); | 149 | fs32_to_cpu(sb, usb1->fs_fsbtodb)); |
161 | printk(" fs_dsize: %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize)); | 150 | printk(" nrpos: %u\n", fs32_to_cpu(sb, usb3->fs_nrpos)); |
162 | printk(" bsize: %u\n", fs32_to_cpu(usb, usb->fs_bsize)); | 151 | printk(" ndir %u\n", |
163 | printk(" fsize: %u\n", fs32_to_cpu(usb, usb->fs_fsize)); | 152 | fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir)); |
164 | printk(" fs_volname: %s\n", usb->fs_u11.fs_u2.fs_volname); | 153 | printk(" nifree %u\n", |
165 | printk(" fs_fsmnt: %s\n", usb->fs_u11.fs_u2.fs_fsmnt); | 154 | fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree)); |
166 | printk(" fs_sblockloc: %u\n",fs64_to_cpu(sb, | 155 | printk(" nbfree %u\n", |
167 | usb->fs_u11.fs_u2.fs_sblockloc)); | 156 | fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)); |
168 | printk(" cs_ndir(No of dirs): %u\n",fs64_to_cpu(sb, | 157 | printk(" nffree %u\n", |
169 | usb->fs_u11.fs_u2.fs_cstotal.cs_ndir)); | 158 | fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree)); |
170 | printk(" cs_nbfree(No of free blocks): %u\n",fs64_to_cpu(sb, | 159 | } |
171 | usb->fs_u11.fs_u2.fs_cstotal.cs_nbfree)); | ||
172 | printk("\n"); | 160 | printk("\n"); |
173 | } | 161 | } |
174 | 162 | ||
175 | /* | 163 | /* |
176 | * Print contents of ufs_cylinder_group, useful for debugging | 164 | * Print contents of ufs_cylinder_group, useful for debugging |
177 | */ | 165 | */ |
178 | void ufs_print_cylinder_stuff(struct super_block *sb, struct ufs_cylinder_group *cg) | 166 | static void ufs_print_cylinder_stuff(struct super_block *sb, |
167 | struct ufs_cylinder_group *cg) | ||
179 | { | 168 | { |
180 | printk("\nufs_print_cylinder_stuff\n"); | 169 | printk("\nufs_print_cylinder_stuff\n"); |
181 | printk("size of ucg: %u\n", sizeof(struct ufs_cylinder_group)); | 170 | printk("size of ucg: %zu\n", sizeof(struct ufs_cylinder_group)); |
182 | printk(" magic: %x\n", fs32_to_cpu(sb, cg->cg_magic)); | 171 | printk(" magic: %x\n", fs32_to_cpu(sb, cg->cg_magic)); |
183 | printk(" time: %u\n", fs32_to_cpu(sb, cg->cg_time)); | 172 | printk(" time: %u\n", fs32_to_cpu(sb, cg->cg_time)); |
184 | printk(" cgx: %u\n", fs32_to_cpu(sb, cg->cg_cgx)); | 173 | printk(" cgx: %u\n", fs32_to_cpu(sb, cg->cg_cgx)); |
@@ -202,12 +191,18 @@ void ufs_print_cylinder_stuff(struct super_block *sb, struct ufs_cylinder_group | |||
202 | printk(" iuseoff: %u\n", fs32_to_cpu(sb, cg->cg_iusedoff)); | 191 | printk(" iuseoff: %u\n", fs32_to_cpu(sb, cg->cg_iusedoff)); |
203 | printk(" freeoff: %u\n", fs32_to_cpu(sb, cg->cg_freeoff)); | 192 | printk(" freeoff: %u\n", fs32_to_cpu(sb, cg->cg_freeoff)); |
204 | printk(" nextfreeoff: %u\n", fs32_to_cpu(sb, cg->cg_nextfreeoff)); | 193 | printk(" nextfreeoff: %u\n", fs32_to_cpu(sb, cg->cg_nextfreeoff)); |
205 | printk(" clustersumoff %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff)); | 194 | printk(" clustersumoff %u\n", |
206 | printk(" clusteroff %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff)); | 195 | fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff)); |
207 | printk(" nclusterblks %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks)); | 196 | printk(" clusteroff %u\n", |
197 | fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff)); | ||
198 | printk(" nclusterblks %u\n", | ||
199 | fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks)); | ||
208 | printk("\n"); | 200 | printk("\n"); |
209 | } | 201 | } |
210 | #endif /* UFS_SUPER_DEBUG_MORE */ | 202 | #else |
203 | # define ufs_print_super_stuff(sb, flags, usb1, usb2, usb3) /**/ | ||
204 | # define ufs_print_cylinder_stuff(sb, cg) /**/ | ||
205 | #endif /* CONFIG_UFS_DEBUG */ | ||
211 | 206 | ||
212 | static struct super_operations ufs_super_ops; | 207 | static struct super_operations ufs_super_ops; |
213 | 208 | ||
@@ -225,7 +220,7 @@ void ufs_error (struct super_block * sb, const char * function, | |||
225 | 220 | ||
226 | if (!(sb->s_flags & MS_RDONLY)) { | 221 | if (!(sb->s_flags & MS_RDONLY)) { |
227 | usb1->fs_clean = UFS_FSBAD; | 222 | usb1->fs_clean = UFS_FSBAD; |
228 | ubh_mark_buffer_dirty(USPI_UBH); | 223 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); |
229 | sb->s_dirt = 1; | 224 | sb->s_dirt = 1; |
230 | sb->s_flags |= MS_RDONLY; | 225 | sb->s_flags |= MS_RDONLY; |
231 | } | 226 | } |
@@ -257,7 +252,7 @@ void ufs_panic (struct super_block * sb, const char * function, | |||
257 | 252 | ||
258 | if (!(sb->s_flags & MS_RDONLY)) { | 253 | if (!(sb->s_flags & MS_RDONLY)) { |
259 | usb1->fs_clean = UFS_FSBAD; | 254 | usb1->fs_clean = UFS_FSBAD; |
260 | ubh_mark_buffer_dirty(USPI_UBH); | 255 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); |
261 | sb->s_dirt = 1; | 256 | sb->s_dirt = 1; |
262 | } | 257 | } |
263 | va_start (args, fmt); | 258 | va_start (args, fmt); |
@@ -309,7 +304,7 @@ static int ufs_parse_options (char * options, unsigned * mount_options) | |||
309 | { | 304 | { |
310 | char * p; | 305 | char * p; |
311 | 306 | ||
312 | UFSD(("ENTER\n")) | 307 | UFSD("ENTER\n"); |
313 | 308 | ||
314 | if (!options) | 309 | if (!options) |
315 | return 1; | 310 | return 1; |
@@ -386,27 +381,57 @@ static int ufs_parse_options (char * options, unsigned * mount_options) | |||
386 | } | 381 | } |
387 | 382 | ||
388 | /* | 383 | /* |
384 | * Diffrent types of UFS hold fs_cstotal in different | ||
385 | * places, and use diffrent data structure for it. | ||
386 | * To make things simplier we just copy fs_cstotal to ufs_sb_private_info | ||
387 | */ | ||
388 | static void ufs_setup_cstotal(struct super_block *sb) | ||
389 | { | ||
390 | struct ufs_sb_info *sbi = UFS_SB(sb); | ||
391 | struct ufs_sb_private_info *uspi = sbi->s_uspi; | ||
392 | struct ufs_super_block_first *usb1; | ||
393 | struct ufs_super_block_second *usb2; | ||
394 | struct ufs_super_block_third *usb3; | ||
395 | unsigned mtype = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE; | ||
396 | |||
397 | UFSD("ENTER, mtype=%u\n", mtype); | ||
398 | usb1 = ubh_get_usb_first(uspi); | ||
399 | usb2 = ubh_get_usb_second(uspi); | ||
400 | usb3 = ubh_get_usb_third(uspi); | ||
401 | |||
402 | if ((mtype == UFS_MOUNT_UFSTYPE_44BSD && | ||
403 | (usb1->fs_flags & UFS_FLAGS_UPDATED)) || | ||
404 | mtype == UFS_MOUNT_UFSTYPE_UFS2) { | ||
405 | /*we have statistic in different place, then usual*/ | ||
406 | uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir); | ||
407 | uspi->cs_total.cs_nbfree = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree); | ||
408 | uspi->cs_total.cs_nifree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree); | ||
409 | uspi->cs_total.cs_nffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree); | ||
410 | } else { | ||
411 | uspi->cs_total.cs_ndir = fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir); | ||
412 | uspi->cs_total.cs_nbfree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree); | ||
413 | uspi->cs_total.cs_nifree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree); | ||
414 | uspi->cs_total.cs_nffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree); | ||
415 | } | ||
416 | UFSD("EXIT\n"); | ||
417 | } | ||
418 | |||
419 | /* | ||
389 | * Read on-disk structures associated with cylinder groups | 420 | * Read on-disk structures associated with cylinder groups |
390 | */ | 421 | */ |
391 | static int ufs_read_cylinder_structures (struct super_block *sb) | 422 | static int ufs_read_cylinder_structures(struct super_block *sb) |
392 | { | 423 | { |
393 | struct ufs_sb_info * sbi = UFS_SB(sb); | 424 | struct ufs_sb_info *sbi = UFS_SB(sb); |
394 | struct ufs_sb_private_info * uspi; | 425 | struct ufs_sb_private_info *uspi = sbi->s_uspi; |
395 | struct ufs_super_block *usb; | 426 | unsigned flags = sbi->s_flags; |
396 | struct ufs_buffer_head * ubh; | 427 | struct ufs_buffer_head * ubh; |
397 | unsigned char * base, * space; | 428 | unsigned char * base, * space; |
398 | unsigned size, blks, i; | 429 | unsigned size, blks, i; |
399 | unsigned flags = 0; | 430 | struct ufs_super_block_third *usb3; |
400 | |||
401 | UFSD(("ENTER\n")) | ||
402 | |||
403 | uspi = sbi->s_uspi; | ||
404 | 431 | ||
405 | usb = (struct ufs_super_block *) | 432 | UFSD("ENTER\n"); |
406 | ((struct ufs_buffer_head *)uspi)->bh[0]->b_data; | ||
407 | 433 | ||
408 | flags = UFS_SB(sb)->s_flags; | 434 | usb3 = ubh_get_usb_third(uspi); |
409 | |||
410 | /* | 435 | /* |
411 | * Read cs structures from (usually) first data block | 436 | * Read cs structures from (usually) first data block |
412 | * on the device. | 437 | * on the device. |
@@ -424,7 +449,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) | |||
424 | 449 | ||
425 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 450 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
426 | ubh = ubh_bread(sb, | 451 | ubh = ubh_bread(sb, |
427 | fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_csaddr) + i, size); | 452 | fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_csaddr) + i, size); |
428 | else | 453 | else |
429 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); | 454 | ubh = ubh_bread(sb, uspi->s_csaddr + i, size); |
430 | 455 | ||
@@ -451,14 +476,13 @@ static int ufs_read_cylinder_structures (struct super_block *sb) | |||
451 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; | 476 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; |
452 | } | 477 | } |
453 | for (i = 0; i < uspi->s_ncg; i++) { | 478 | for (i = 0; i < uspi->s_ncg; i++) { |
454 | UFSD(("read cg %u\n", i)) | 479 | UFSD("read cg %u\n", i); |
455 | if (!(sbi->s_ucg[i] = sb_bread(sb, ufs_cgcmin(i)))) | 480 | if (!(sbi->s_ucg[i] = sb_bread(sb, ufs_cgcmin(i)))) |
456 | goto failed; | 481 | goto failed; |
457 | if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data)) | 482 | if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data)) |
458 | goto failed; | 483 | goto failed; |
459 | #ifdef UFS_SUPER_DEBUG_MORE | 484 | |
460 | ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data); | 485 | ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data); |
461 | #endif | ||
462 | } | 486 | } |
463 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) { | 487 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) { |
464 | if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL))) | 488 | if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL))) |
@@ -466,7 +490,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) | |||
466 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; | 490 | sbi->s_cgno[i] = UFS_CGNO_EMPTY; |
467 | } | 491 | } |
468 | sbi->s_cg_loaded = 0; | 492 | sbi->s_cg_loaded = 0; |
469 | UFSD(("EXIT\n")) | 493 | UFSD("EXIT\n"); |
470 | return 1; | 494 | return 1; |
471 | 495 | ||
472 | failed: | 496 | failed: |
@@ -479,26 +503,69 @@ failed: | |||
479 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) | 503 | for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) |
480 | kfree (sbi->s_ucpi[i]); | 504 | kfree (sbi->s_ucpi[i]); |
481 | } | 505 | } |
482 | UFSD(("EXIT (FAILED)\n")) | 506 | UFSD("EXIT (FAILED)\n"); |
483 | return 0; | 507 | return 0; |
484 | } | 508 | } |
485 | 509 | ||
486 | /* | 510 | /* |
487 | * Put on-disk structures associated with cylinder groups and | 511 | * Sync our internal copy of fs_cstotal with disk |
488 | * write them back to disk | ||
489 | */ | 512 | */ |
490 | static void ufs_put_cylinder_structures (struct super_block *sb) | 513 | static void ufs_put_cstotal(struct super_block *sb) |
491 | { | 514 | { |
492 | struct ufs_sb_info * sbi = UFS_SB(sb); | 515 | unsigned mtype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE; |
493 | struct ufs_sb_private_info * uspi; | 516 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
517 | struct ufs_super_block_first *usb1; | ||
518 | struct ufs_super_block_second *usb2; | ||
519 | struct ufs_super_block_third *usb3; | ||
520 | |||
521 | UFSD("ENTER\n"); | ||
522 | usb1 = ubh_get_usb_first(uspi); | ||
523 | usb2 = ubh_get_usb_second(uspi); | ||
524 | usb3 = ubh_get_usb_third(uspi); | ||
525 | |||
526 | if ((mtype == UFS_MOUNT_UFSTYPE_44BSD && | ||
527 | (usb1->fs_flags & UFS_FLAGS_UPDATED)) || | ||
528 | mtype == UFS_MOUNT_UFSTYPE_UFS2) { | ||
529 | /*we have statistic in different place, then usual*/ | ||
530 | usb2->fs_un.fs_u2.cs_ndir = | ||
531 | cpu_to_fs64(sb, uspi->cs_total.cs_ndir); | ||
532 | usb2->fs_un.fs_u2.cs_nbfree = | ||
533 | cpu_to_fs64(sb, uspi->cs_total.cs_nbfree); | ||
534 | usb3->fs_un1.fs_u2.cs_nifree = | ||
535 | cpu_to_fs64(sb, uspi->cs_total.cs_nifree); | ||
536 | usb3->fs_un1.fs_u2.cs_nffree = | ||
537 | cpu_to_fs64(sb, uspi->cs_total.cs_nffree); | ||
538 | } else { | ||
539 | usb1->fs_cstotal.cs_ndir = | ||
540 | cpu_to_fs32(sb, uspi->cs_total.cs_ndir); | ||
541 | usb1->fs_cstotal.cs_nbfree = | ||
542 | cpu_to_fs32(sb, uspi->cs_total.cs_nbfree); | ||
543 | usb1->fs_cstotal.cs_nifree = | ||
544 | cpu_to_fs32(sb, uspi->cs_total.cs_nifree); | ||
545 | usb1->fs_cstotal.cs_nffree = | ||
546 | cpu_to_fs32(sb, uspi->cs_total.cs_nffree); | ||
547 | } | ||
548 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); | ||
549 | UFSD("EXIT\n"); | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * ufs_put_super_internal() - put on-disk intrenal structures | ||
554 | * @sb: pointer to super_block structure | ||
555 | * Put on-disk structures associated with cylinder groups | ||
556 | * and write them back to disk, also update cs_total on disk | ||
557 | */ | ||
558 | static void ufs_put_super_internal(struct super_block *sb) | ||
559 | { | ||
560 | struct ufs_sb_info *sbi = UFS_SB(sb); | ||
561 | struct ufs_sb_private_info *uspi = sbi->s_uspi; | ||
494 | struct ufs_buffer_head * ubh; | 562 | struct ufs_buffer_head * ubh; |
495 | unsigned char * base, * space; | 563 | unsigned char * base, * space; |
496 | unsigned blks, size, i; | 564 | unsigned blks, size, i; |
497 | |||
498 | UFSD(("ENTER\n")) | ||
499 | |||
500 | uspi = sbi->s_uspi; | ||
501 | 565 | ||
566 | |||
567 | UFSD("ENTER\n"); | ||
568 | ufs_put_cstotal(sb); | ||
502 | size = uspi->s_cssize; | 569 | size = uspi->s_cssize; |
503 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; | 570 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; |
504 | base = space = (char*) sbi->s_csp; | 571 | base = space = (char*) sbi->s_csp; |
@@ -523,7 +590,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) | |||
523 | brelse (sbi->s_ucg[i]); | 590 | brelse (sbi->s_ucg[i]); |
524 | kfree (sbi->s_ucg); | 591 | kfree (sbi->s_ucg); |
525 | kfree (base); | 592 | kfree (base); |
526 | UFSD(("EXIT\n")) | 593 | UFSD("EXIT\n"); |
527 | } | 594 | } |
528 | 595 | ||
529 | static int ufs_fill_super(struct super_block *sb, void *data, int silent) | 596 | static int ufs_fill_super(struct super_block *sb, void *data, int silent) |
@@ -533,7 +600,6 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
533 | struct ufs_super_block_first * usb1; | 600 | struct ufs_super_block_first * usb1; |
534 | struct ufs_super_block_second * usb2; | 601 | struct ufs_super_block_second * usb2; |
535 | struct ufs_super_block_third * usb3; | 602 | struct ufs_super_block_third * usb3; |
536 | struct ufs_super_block *usb; | ||
537 | struct ufs_buffer_head * ubh; | 603 | struct ufs_buffer_head * ubh; |
538 | struct inode *inode; | 604 | struct inode *inode; |
539 | unsigned block_size, super_block_size; | 605 | unsigned block_size, super_block_size; |
@@ -544,7 +610,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
544 | ubh = NULL; | 610 | ubh = NULL; |
545 | flags = 0; | 611 | flags = 0; |
546 | 612 | ||
547 | UFSD(("ENTER\n")) | 613 | UFSD("ENTER\n"); |
548 | 614 | ||
549 | sbi = kmalloc(sizeof(struct ufs_sb_info), GFP_KERNEL); | 615 | sbi = kmalloc(sizeof(struct ufs_sb_info), GFP_KERNEL); |
550 | if (!sbi) | 616 | if (!sbi) |
@@ -552,7 +618,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
552 | sb->s_fs_info = sbi; | 618 | sb->s_fs_info = sbi; |
553 | memset(sbi, 0, sizeof(struct ufs_sb_info)); | 619 | memset(sbi, 0, sizeof(struct ufs_sb_info)); |
554 | 620 | ||
555 | UFSD(("flag %u\n", (int)(sb->s_flags & MS_RDONLY))) | 621 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); |
556 | 622 | ||
557 | #ifndef CONFIG_UFS_FS_WRITE | 623 | #ifndef CONFIG_UFS_FS_WRITE |
558 | if (!(sb->s_flags & MS_RDONLY)) { | 624 | if (!(sb->s_flags & MS_RDONLY)) { |
@@ -593,7 +659,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
593 | the rules */ | 659 | the rules */ |
594 | switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) { | 660 | switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) { |
595 | case UFS_MOUNT_UFSTYPE_44BSD: | 661 | case UFS_MOUNT_UFSTYPE_44BSD: |
596 | UFSD(("ufstype=44bsd\n")) | 662 | UFSD("ufstype=44bsd\n"); |
597 | uspi->s_fsize = block_size = 512; | 663 | uspi->s_fsize = block_size = 512; |
598 | uspi->s_fmask = ~(512 - 1); | 664 | uspi->s_fmask = ~(512 - 1); |
599 | uspi->s_fshift = 9; | 665 | uspi->s_fshift = 9; |
@@ -602,7 +668,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
602 | flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; | 668 | flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; |
603 | break; | 669 | break; |
604 | case UFS_MOUNT_UFSTYPE_UFS2: | 670 | case UFS_MOUNT_UFSTYPE_UFS2: |
605 | UFSD(("ufstype=ufs2\n")); | 671 | UFSD("ufstype=ufs2\n"); |
606 | super_block_offset=SBLOCK_UFS2; | 672 | super_block_offset=SBLOCK_UFS2; |
607 | uspi->s_fsize = block_size = 512; | 673 | uspi->s_fsize = block_size = 512; |
608 | uspi->s_fmask = ~(512 - 1); | 674 | uspi->s_fmask = ~(512 - 1); |
@@ -617,7 +683,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
617 | break; | 683 | break; |
618 | 684 | ||
619 | case UFS_MOUNT_UFSTYPE_SUN: | 685 | case UFS_MOUNT_UFSTYPE_SUN: |
620 | UFSD(("ufstype=sun\n")) | 686 | UFSD("ufstype=sun\n"); |
621 | uspi->s_fsize = block_size = 1024; | 687 | uspi->s_fsize = block_size = 1024; |
622 | uspi->s_fmask = ~(1024 - 1); | 688 | uspi->s_fmask = ~(1024 - 1); |
623 | uspi->s_fshift = 10; | 689 | uspi->s_fshift = 10; |
@@ -628,7 +694,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
628 | break; | 694 | break; |
629 | 695 | ||
630 | case UFS_MOUNT_UFSTYPE_SUNx86: | 696 | case UFS_MOUNT_UFSTYPE_SUNx86: |
631 | UFSD(("ufstype=sunx86\n")) | 697 | UFSD("ufstype=sunx86\n"); |
632 | uspi->s_fsize = block_size = 1024; | 698 | uspi->s_fsize = block_size = 1024; |
633 | uspi->s_fmask = ~(1024 - 1); | 699 | uspi->s_fmask = ~(1024 - 1); |
634 | uspi->s_fshift = 10; | 700 | uspi->s_fshift = 10; |
@@ -639,7 +705,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
639 | break; | 705 | break; |
640 | 706 | ||
641 | case UFS_MOUNT_UFSTYPE_OLD: | 707 | case UFS_MOUNT_UFSTYPE_OLD: |
642 | UFSD(("ufstype=old\n")) | 708 | UFSD("ufstype=old\n"); |
643 | uspi->s_fsize = block_size = 1024; | 709 | uspi->s_fsize = block_size = 1024; |
644 | uspi->s_fmask = ~(1024 - 1); | 710 | uspi->s_fmask = ~(1024 - 1); |
645 | uspi->s_fshift = 10; | 711 | uspi->s_fshift = 10; |
@@ -654,7 +720,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
654 | break; | 720 | break; |
655 | 721 | ||
656 | case UFS_MOUNT_UFSTYPE_NEXTSTEP: | 722 | case UFS_MOUNT_UFSTYPE_NEXTSTEP: |
657 | UFSD(("ufstype=nextstep\n")) | 723 | UFSD("ufstype=nextstep\n"); |
658 | uspi->s_fsize = block_size = 1024; | 724 | uspi->s_fsize = block_size = 1024; |
659 | uspi->s_fmask = ~(1024 - 1); | 725 | uspi->s_fmask = ~(1024 - 1); |
660 | uspi->s_fshift = 10; | 726 | uspi->s_fshift = 10; |
@@ -669,7 +735,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
669 | break; | 735 | break; |
670 | 736 | ||
671 | case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD: | 737 | case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD: |
672 | UFSD(("ufstype=nextstep-cd\n")) | 738 | UFSD("ufstype=nextstep-cd\n"); |
673 | uspi->s_fsize = block_size = 2048; | 739 | uspi->s_fsize = block_size = 2048; |
674 | uspi->s_fmask = ~(2048 - 1); | 740 | uspi->s_fmask = ~(2048 - 1); |
675 | uspi->s_fshift = 11; | 741 | uspi->s_fshift = 11; |
@@ -684,7 +750,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
684 | break; | 750 | break; |
685 | 751 | ||
686 | case UFS_MOUNT_UFSTYPE_OPENSTEP: | 752 | case UFS_MOUNT_UFSTYPE_OPENSTEP: |
687 | UFSD(("ufstype=openstep\n")) | 753 | UFSD("ufstype=openstep\n"); |
688 | uspi->s_fsize = block_size = 1024; | 754 | uspi->s_fsize = block_size = 1024; |
689 | uspi->s_fmask = ~(1024 - 1); | 755 | uspi->s_fmask = ~(1024 - 1); |
690 | uspi->s_fshift = 10; | 756 | uspi->s_fshift = 10; |
@@ -699,7 +765,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
699 | break; | 765 | break; |
700 | 766 | ||
701 | case UFS_MOUNT_UFSTYPE_HP: | 767 | case UFS_MOUNT_UFSTYPE_HP: |
702 | UFSD(("ufstype=hp\n")) | 768 | UFSD("ufstype=hp\n"); |
703 | uspi->s_fsize = block_size = 1024; | 769 | uspi->s_fsize = block_size = 1024; |
704 | uspi->s_fmask = ~(1024 - 1); | 770 | uspi->s_fmask = ~(1024 - 1); |
705 | uspi->s_fshift = 10; | 771 | uspi->s_fshift = 10; |
@@ -737,8 +803,6 @@ again: | |||
737 | usb1 = ubh_get_usb_first(uspi); | 803 | usb1 = ubh_get_usb_first(uspi); |
738 | usb2 = ubh_get_usb_second(uspi); | 804 | usb2 = ubh_get_usb_second(uspi); |
739 | usb3 = ubh_get_usb_third(uspi); | 805 | usb3 = ubh_get_usb_third(uspi); |
740 | usb = (struct ufs_super_block *) | ||
741 | ((struct ufs_buffer_head *)uspi)->bh[0]->b_data ; | ||
742 | 806 | ||
743 | /* | 807 | /* |
744 | * Check ufs magic number | 808 | * Check ufs magic number |
@@ -820,16 +884,12 @@ magic_found: | |||
820 | ubh = NULL; | 884 | ubh = NULL; |
821 | block_size = uspi->s_fsize; | 885 | block_size = uspi->s_fsize; |
822 | super_block_size = uspi->s_sbsize; | 886 | super_block_size = uspi->s_sbsize; |
823 | UFSD(("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size)) | 887 | UFSD("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size); |
824 | goto again; | 888 | goto again; |
825 | } | 889 | } |
826 | 890 | ||
827 | #ifdef UFS_SUPER_DEBUG_MORE | 891 | |
828 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) | 892 | ufs_print_super_stuff(sb, flags, usb1, usb2, usb3); |
829 | ufs2_print_super_stuff(sb,usb); | ||
830 | else | ||
831 | ufs_print_super_stuff(sb, usb1, usb2, usb3); | ||
832 | #endif | ||
833 | 893 | ||
834 | /* | 894 | /* |
835 | * Check, if file system was correctly unmounted. | 895 | * Check, if file system was correctly unmounted. |
@@ -842,13 +902,13 @@ magic_found: | |||
842 | (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) { | 902 | (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) { |
843 | switch(usb1->fs_clean) { | 903 | switch(usb1->fs_clean) { |
844 | case UFS_FSCLEAN: | 904 | case UFS_FSCLEAN: |
845 | UFSD(("fs is clean\n")) | 905 | UFSD("fs is clean\n"); |
846 | break; | 906 | break; |
847 | case UFS_FSSTABLE: | 907 | case UFS_FSSTABLE: |
848 | UFSD(("fs is stable\n")) | 908 | UFSD("fs is stable\n"); |
849 | break; | 909 | break; |
850 | case UFS_FSOSF1: | 910 | case UFS_FSOSF1: |
851 | UFSD(("fs is DEC OSF/1\n")) | 911 | UFSD("fs is DEC OSF/1\n"); |
852 | break; | 912 | break; |
853 | case UFS_FSACTIVE: | 913 | case UFS_FSACTIVE: |
854 | printk("ufs_read_super: fs is active\n"); | 914 | printk("ufs_read_super: fs is active\n"); |
@@ -863,8 +923,7 @@ magic_found: | |||
863 | sb->s_flags |= MS_RDONLY; | 923 | sb->s_flags |= MS_RDONLY; |
864 | break; | 924 | break; |
865 | } | 925 | } |
866 | } | 926 | } else { |
867 | else { | ||
868 | printk("ufs_read_super: fs needs fsck\n"); | 927 | printk("ufs_read_super: fs needs fsck\n"); |
869 | sb->s_flags |= MS_RDONLY; | 928 | sb->s_flags |= MS_RDONLY; |
870 | } | 929 | } |
@@ -884,10 +943,9 @@ magic_found: | |||
884 | uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask); | 943 | uspi->s_cgmask = fs32_to_cpu(sb, usb1->fs_cgmask); |
885 | 944 | ||
886 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { | 945 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { |
887 | uspi->s_u2_size = fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_size); | 946 | uspi->s_u2_size = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size); |
888 | uspi->s_u2_dsize = fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize); | 947 | uspi->s_u2_dsize = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize); |
889 | } | 948 | } else { |
890 | else { | ||
891 | uspi->s_size = fs32_to_cpu(sb, usb1->fs_size); | 949 | uspi->s_size = fs32_to_cpu(sb, usb1->fs_size); |
892 | uspi->s_dsize = fs32_to_cpu(sb, usb1->fs_dsize); | 950 | uspi->s_dsize = fs32_to_cpu(sb, usb1->fs_dsize); |
893 | } | 951 | } |
@@ -901,8 +959,8 @@ magic_found: | |||
901 | uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask); | 959 | uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask); |
902 | uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift); | 960 | uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift); |
903 | uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift); | 961 | uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift); |
904 | UFSD(("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift, | 962 | UFSD("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift, |
905 | uspi->s_fshift)); | 963 | uspi->s_fshift); |
906 | uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift); | 964 | uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift); |
907 | uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb); | 965 | uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb); |
908 | /* s_sbsize already set */ | 966 | /* s_sbsize already set */ |
@@ -922,8 +980,8 @@ magic_found: | |||
922 | uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc); | 980 | uspi->s_spc = fs32_to_cpu(sb, usb1->fs_spc); |
923 | uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg); | 981 | uspi->s_ipg = fs32_to_cpu(sb, usb1->fs_ipg); |
924 | uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg); | 982 | uspi->s_fpg = fs32_to_cpu(sb, usb1->fs_fpg); |
925 | uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_cpc); | 983 | uspi->s_cpc = fs32_to_cpu(sb, usb2->fs_un.fs_u1.fs_cpc); |
926 | uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize); | 984 | uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_contigsumsize); |
927 | uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3); | 985 | uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3); |
928 | uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3); | 986 | uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3); |
929 | uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat); | 987 | uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat); |
@@ -935,12 +993,11 @@ magic_found: | |||
935 | * Compute another frequently used values | 993 | * Compute another frequently used values |
936 | */ | 994 | */ |
937 | uspi->s_fpbmask = uspi->s_fpb - 1; | 995 | uspi->s_fpbmask = uspi->s_fpb - 1; |
938 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { | 996 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) |
939 | uspi->s_apbshift = uspi->s_bshift - 3; | 997 | uspi->s_apbshift = uspi->s_bshift - 3; |
940 | } | 998 | else |
941 | else { | ||
942 | uspi->s_apbshift = uspi->s_bshift - 2; | 999 | uspi->s_apbshift = uspi->s_bshift - 2; |
943 | } | 1000 | |
944 | uspi->s_2apbshift = uspi->s_apbshift * 2; | 1001 | uspi->s_2apbshift = uspi->s_apbshift * 2; |
945 | uspi->s_3apbshift = uspi->s_apbshift * 3; | 1002 | uspi->s_3apbshift = uspi->s_apbshift * 3; |
946 | uspi->s_apb = 1 << uspi->s_apbshift; | 1003 | uspi->s_apb = 1 << uspi->s_apbshift; |
@@ -956,7 +1013,7 @@ magic_found: | |||
956 | if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == | 1013 | if ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == |
957 | UFS_MOUNT_UFSTYPE_44BSD) | 1014 | UFS_MOUNT_UFSTYPE_44BSD) |
958 | uspi->s_maxsymlinklen = | 1015 | uspi->s_maxsymlinklen = |
959 | fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_maxsymlinklen); | 1016 | fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen); |
960 | 1017 | ||
961 | sbi->s_flags = flags; | 1018 | sbi->s_flags = flags; |
962 | 1019 | ||
@@ -967,7 +1024,7 @@ magic_found: | |||
967 | if (!sb->s_root) | 1024 | if (!sb->s_root) |
968 | goto dalloc_failed; | 1025 | goto dalloc_failed; |
969 | 1026 | ||
970 | 1027 | ufs_setup_cstotal(sb); | |
971 | /* | 1028 | /* |
972 | * Read cylinder group structures | 1029 | * Read cylinder group structures |
973 | */ | 1030 | */ |
@@ -975,7 +1032,7 @@ magic_found: | |||
975 | if (!ufs_read_cylinder_structures(sb)) | 1032 | if (!ufs_read_cylinder_structures(sb)) |
976 | goto failed; | 1033 | goto failed; |
977 | 1034 | ||
978 | UFSD(("EXIT\n")) | 1035 | UFSD("EXIT\n"); |
979 | return 0; | 1036 | return 0; |
980 | 1037 | ||
981 | dalloc_failed: | 1038 | dalloc_failed: |
@@ -986,15 +1043,16 @@ failed: | |||
986 | kfree (uspi); | 1043 | kfree (uspi); |
987 | kfree(sbi); | 1044 | kfree(sbi); |
988 | sb->s_fs_info = NULL; | 1045 | sb->s_fs_info = NULL; |
989 | UFSD(("EXIT (FAILED)\n")) | 1046 | UFSD("EXIT (FAILED)\n"); |
990 | return -EINVAL; | 1047 | return -EINVAL; |
991 | 1048 | ||
992 | failed_nomem: | 1049 | failed_nomem: |
993 | UFSD(("EXIT (NOMEM)\n")) | 1050 | UFSD("EXIT (NOMEM)\n"); |
994 | return -ENOMEM; | 1051 | return -ENOMEM; |
995 | } | 1052 | } |
996 | 1053 | ||
997 | static void ufs_write_super (struct super_block *sb) { | 1054 | static void ufs_write_super(struct super_block *sb) |
1055 | { | ||
998 | struct ufs_sb_private_info * uspi; | 1056 | struct ufs_sb_private_info * uspi; |
999 | struct ufs_super_block_first * usb1; | 1057 | struct ufs_super_block_first * usb1; |
1000 | struct ufs_super_block_third * usb3; | 1058 | struct ufs_super_block_third * usb3; |
@@ -1002,7 +1060,7 @@ static void ufs_write_super (struct super_block *sb) { | |||
1002 | 1060 | ||
1003 | lock_kernel(); | 1061 | lock_kernel(); |
1004 | 1062 | ||
1005 | UFSD(("ENTER\n")) | 1063 | UFSD("ENTER\n"); |
1006 | flags = UFS_SB(sb)->s_flags; | 1064 | flags = UFS_SB(sb)->s_flags; |
1007 | uspi = UFS_SB(sb)->s_uspi; | 1065 | uspi = UFS_SB(sb)->s_uspi; |
1008 | usb1 = ubh_get_usb_first(uspi); | 1066 | usb1 = ubh_get_usb_first(uspi); |
@@ -1014,26 +1072,27 @@ static void ufs_write_super (struct super_block *sb) { | |||
1014 | || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) | 1072 | || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) |
1015 | ufs_set_fs_state(sb, usb1, usb3, | 1073 | ufs_set_fs_state(sb, usb1, usb3, |
1016 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); | 1074 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); |
1017 | ubh_mark_buffer_dirty (USPI_UBH); | 1075 | ufs_put_cstotal(sb); |
1018 | } | 1076 | } |
1019 | sb->s_dirt = 0; | 1077 | sb->s_dirt = 0; |
1020 | UFSD(("EXIT\n")) | 1078 | UFSD("EXIT\n"); |
1021 | unlock_kernel(); | 1079 | unlock_kernel(); |
1022 | } | 1080 | } |
1023 | 1081 | ||
1024 | static void ufs_put_super (struct super_block *sb) | 1082 | static void ufs_put_super(struct super_block *sb) |
1025 | { | 1083 | { |
1026 | struct ufs_sb_info * sbi = UFS_SB(sb); | 1084 | struct ufs_sb_info * sbi = UFS_SB(sb); |
1027 | 1085 | ||
1028 | UFSD(("ENTER\n")) | 1086 | UFSD("ENTER\n"); |
1029 | 1087 | ||
1030 | if (!(sb->s_flags & MS_RDONLY)) | 1088 | if (!(sb->s_flags & MS_RDONLY)) |
1031 | ufs_put_cylinder_structures (sb); | 1089 | ufs_put_super_internal(sb); |
1032 | 1090 | ||
1033 | ubh_brelse_uspi (sbi->s_uspi); | 1091 | ubh_brelse_uspi (sbi->s_uspi); |
1034 | kfree (sbi->s_uspi); | 1092 | kfree (sbi->s_uspi); |
1035 | kfree (sbi); | 1093 | kfree (sbi); |
1036 | sb->s_fs_info = NULL; | 1094 | sb->s_fs_info = NULL; |
1095 | UFSD("EXIT\n"); | ||
1037 | return; | 1096 | return; |
1038 | } | 1097 | } |
1039 | 1098 | ||
@@ -1062,8 +1121,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1062 | return -EINVAL; | 1121 | return -EINVAL; |
1063 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { | 1122 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { |
1064 | new_mount_opt |= ufstype; | 1123 | new_mount_opt |= ufstype; |
1065 | } | 1124 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
1066 | else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { | ||
1067 | printk("ufstype can't be changed during remount\n"); | 1125 | printk("ufstype can't be changed during remount\n"); |
1068 | return -EINVAL; | 1126 | return -EINVAL; |
1069 | } | 1127 | } |
@@ -1077,20 +1135,19 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1077 | * fs was mouted as rw, remounting ro | 1135 | * fs was mouted as rw, remounting ro |
1078 | */ | 1136 | */ |
1079 | if (*mount_flags & MS_RDONLY) { | 1137 | if (*mount_flags & MS_RDONLY) { |
1080 | ufs_put_cylinder_structures(sb); | 1138 | ufs_put_super_internal(sb); |
1081 | usb1->fs_time = cpu_to_fs32(sb, get_seconds()); | 1139 | usb1->fs_time = cpu_to_fs32(sb, get_seconds()); |
1082 | if ((flags & UFS_ST_MASK) == UFS_ST_SUN | 1140 | if ((flags & UFS_ST_MASK) == UFS_ST_SUN |
1083 | || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) | 1141 | || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) |
1084 | ufs_set_fs_state(sb, usb1, usb3, | 1142 | ufs_set_fs_state(sb, usb1, usb3, |
1085 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); | 1143 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); |
1086 | ubh_mark_buffer_dirty (USPI_UBH); | 1144 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
1087 | sb->s_dirt = 0; | 1145 | sb->s_dirt = 0; |
1088 | sb->s_flags |= MS_RDONLY; | 1146 | sb->s_flags |= MS_RDONLY; |
1089 | } | 1147 | } else { |
1090 | /* | 1148 | /* |
1091 | * fs was mounted as ro, remounting rw | 1149 | * fs was mounted as ro, remounting rw |
1092 | */ | 1150 | */ |
1093 | else { | ||
1094 | #ifndef CONFIG_UFS_FS_WRITE | 1151 | #ifndef CONFIG_UFS_FS_WRITE |
1095 | printk("ufs was compiled with read-only support, " | 1152 | printk("ufs was compiled with read-only support, " |
1096 | "can't be mounted as read-write\n"); | 1153 | "can't be mounted as read-write\n"); |
@@ -1102,7 +1159,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1102 | printk("this ufstype is read-only supported\n"); | 1159 | printk("this ufstype is read-only supported\n"); |
1103 | return -EINVAL; | 1160 | return -EINVAL; |
1104 | } | 1161 | } |
1105 | if (!ufs_read_cylinder_structures (sb)) { | 1162 | if (!ufs_read_cylinder_structures(sb)) { |
1106 | printk("failed during remounting\n"); | 1163 | printk("failed during remounting\n"); |
1107 | return -EPERM; | 1164 | return -EPERM; |
1108 | } | 1165 | } |
@@ -1113,36 +1170,31 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1113 | return 0; | 1170 | return 0; |
1114 | } | 1171 | } |
1115 | 1172 | ||
1116 | static int ufs_statfs (struct super_block *sb, struct kstatfs *buf) | 1173 | static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1117 | { | 1174 | { |
1118 | struct ufs_sb_private_info * uspi; | 1175 | struct super_block *sb = dentry->d_sb; |
1119 | struct ufs_super_block_first * usb1; | 1176 | struct ufs_sb_private_info *uspi= UFS_SB(sb)->s_uspi; |
1120 | struct ufs_super_block * usb; | 1177 | unsigned flags = UFS_SB(sb)->s_flags; |
1121 | unsigned flags = 0; | 1178 | struct ufs_super_block_first *usb1; |
1179 | struct ufs_super_block_second *usb2; | ||
1180 | struct ufs_super_block_third *usb3; | ||
1122 | 1181 | ||
1123 | lock_kernel(); | 1182 | lock_kernel(); |
1124 | 1183 | ||
1125 | uspi = UFS_SB(sb)->s_uspi; | 1184 | usb1 = ubh_get_usb_first(uspi); |
1126 | usb1 = ubh_get_usb_first (uspi); | 1185 | usb2 = ubh_get_usb_second(uspi); |
1127 | usb = (struct ufs_super_block *) | 1186 | usb3 = ubh_get_usb_third(uspi); |
1128 | ((struct ufs_buffer_head *)uspi)->bh[0]->b_data ; | ||
1129 | 1187 | ||
1130 | flags = UFS_SB(sb)->s_flags; | ||
1131 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { | 1188 | if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) { |
1132 | buf->f_type = UFS2_MAGIC; | 1189 | buf->f_type = UFS2_MAGIC; |
1133 | buf->f_blocks = fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize); | 1190 | buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize); |
1134 | buf->f_bfree = ufs_blkstofrags(fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_cstotal.cs_nbfree)) + | 1191 | } else { |
1135 | fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_cstotal.cs_nffree); | ||
1136 | buf->f_ffree = fs64_to_cpu(sb, | ||
1137 | usb->fs_u11.fs_u2.fs_cstotal.cs_nifree); | ||
1138 | } | ||
1139 | else { | ||
1140 | buf->f_type = UFS_MAGIC; | 1192 | buf->f_type = UFS_MAGIC; |
1141 | buf->f_blocks = uspi->s_dsize; | 1193 | buf->f_blocks = uspi->s_dsize; |
1142 | buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) + | ||
1143 | fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree); | ||
1144 | buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree); | ||
1145 | } | 1194 | } |
1195 | buf->f_bfree = ufs_blkstofrags(uspi->cs_total.cs_nbfree) + | ||
1196 | uspi->cs_total.cs_nffree; | ||
1197 | buf->f_ffree = uspi->cs_total.cs_nifree; | ||
1146 | buf->f_bsize = sb->s_blocksize; | 1198 | buf->f_bsize = sb->s_blocksize; |
1147 | buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree)) | 1199 | buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree)) |
1148 | ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0; | 1200 | ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0; |
@@ -1311,10 +1363,10 @@ out: | |||
1311 | 1363 | ||
1312 | #endif | 1364 | #endif |
1313 | 1365 | ||
1314 | static struct super_block *ufs_get_sb(struct file_system_type *fs_type, | 1366 | static int ufs_get_sb(struct file_system_type *fs_type, |
1315 | int flags, const char *dev_name, void *data) | 1367 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
1316 | { | 1368 | { |
1317 | return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super); | 1369 | return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt); |
1318 | } | 1370 | } |
1319 | 1371 | ||
1320 | static struct file_system_type ufs_fs_type = { | 1372 | static struct file_system_type ufs_fs_type = { |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 02e86291ef..3c3b301f87 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -49,14 +49,6 @@ | |||
49 | #include "swab.h" | 49 | #include "swab.h" |
50 | #include "util.h" | 50 | #include "util.h" |
51 | 51 | ||
52 | #undef UFS_TRUNCATE_DEBUG | ||
53 | |||
54 | #ifdef UFS_TRUNCATE_DEBUG | ||
55 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
56 | #else | ||
57 | #define UFSD(x) | ||
58 | #endif | ||
59 | |||
60 | /* | 52 | /* |
61 | * Secure deletion currently doesn't work. It interacts very badly | 53 | * Secure deletion currently doesn't work. It interacts very badly |
62 | * with buffers shared with memory mappings, and for that reason | 54 | * with buffers shared with memory mappings, and for that reason |
@@ -82,7 +74,7 @@ static int ufs_trunc_direct (struct inode * inode) | |||
82 | unsigned i, tmp; | 74 | unsigned i, tmp; |
83 | int retry; | 75 | int retry; |
84 | 76 | ||
85 | UFSD(("ENTER\n")) | 77 | UFSD("ENTER\n"); |
86 | 78 | ||
87 | sb = inode->i_sb; | 79 | sb = inode->i_sb; |
88 | uspi = UFS_SB(sb)->s_uspi; | 80 | uspi = UFS_SB(sb)->s_uspi; |
@@ -105,7 +97,7 @@ static int ufs_trunc_direct (struct inode * inode) | |||
105 | block2 = ufs_fragstoblks (frag3); | 97 | block2 = ufs_fragstoblks (frag3); |
106 | } | 98 | } |
107 | 99 | ||
108 | UFSD(("frag1 %u, frag2 %u, block1 %u, block2 %u, frag3 %u, frag4 %u\n", frag1, frag2, block1, block2, frag3, frag4)) | 100 | UFSD("frag1 %u, frag2 %u, block1 %u, block2 %u, frag3 %u, frag4 %u\n", frag1, frag2, block1, block2, frag3, frag4); |
109 | 101 | ||
110 | if (frag1 >= frag2) | 102 | if (frag1 >= frag2) |
111 | goto next1; | 103 | goto next1; |
@@ -120,9 +112,8 @@ static int ufs_trunc_direct (struct inode * inode) | |||
120 | frag1 = ufs_fragnum (frag1); | 112 | frag1 = ufs_fragnum (frag1); |
121 | frag2 = ufs_fragnum (frag2); | 113 | frag2 = ufs_fragnum (frag2); |
122 | 114 | ||
123 | inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift; | ||
124 | mark_inode_dirty(inode); | ||
125 | ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); | 115 | ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); |
116 | mark_inode_dirty(inode); | ||
126 | frag_to_free = tmp + frag1; | 117 | frag_to_free = tmp + frag1; |
127 | 118 | ||
128 | next1: | 119 | next1: |
@@ -136,8 +127,7 @@ next1: | |||
136 | continue; | 127 | continue; |
137 | 128 | ||
138 | *p = 0; | 129 | *p = 0; |
139 | inode->i_blocks -= uspi->s_nspb; | 130 | |
140 | mark_inode_dirty(inode); | ||
141 | if (free_count == 0) { | 131 | if (free_count == 0) { |
142 | frag_to_free = tmp; | 132 | frag_to_free = tmp; |
143 | free_count = uspi->s_fpb; | 133 | free_count = uspi->s_fpb; |
@@ -148,6 +138,7 @@ next1: | |||
148 | frag_to_free = tmp; | 138 | frag_to_free = tmp; |
149 | free_count = uspi->s_fpb; | 139 | free_count = uspi->s_fpb; |
150 | } | 140 | } |
141 | mark_inode_dirty(inode); | ||
151 | } | 142 | } |
152 | 143 | ||
153 | if (free_count > 0) | 144 | if (free_count > 0) |
@@ -166,12 +157,12 @@ next1: | |||
166 | frag4 = ufs_fragnum (frag4); | 157 | frag4 = ufs_fragnum (frag4); |
167 | 158 | ||
168 | *p = 0; | 159 | *p = 0; |
169 | inode->i_blocks -= frag4 << uspi->s_nspfshift; | 160 | |
170 | mark_inode_dirty(inode); | ||
171 | ufs_free_fragments (inode, tmp, frag4); | 161 | ufs_free_fragments (inode, tmp, frag4); |
162 | mark_inode_dirty(inode); | ||
172 | next3: | 163 | next3: |
173 | 164 | ||
174 | UFSD(("EXIT\n")) | 165 | UFSD("EXIT\n"); |
175 | return retry; | 166 | return retry; |
176 | } | 167 | } |
177 | 168 | ||
@@ -186,7 +177,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
186 | unsigned frag_to_free, free_count; | 177 | unsigned frag_to_free, free_count; |
187 | int retry; | 178 | int retry; |
188 | 179 | ||
189 | UFSD(("ENTER\n")) | 180 | UFSD("ENTER\n"); |
190 | 181 | ||
191 | sb = inode->i_sb; | 182 | sb = inode->i_sb; |
192 | uspi = UFS_SB(sb)->s_uspi; | 183 | uspi = UFS_SB(sb)->s_uspi; |
@@ -227,7 +218,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
227 | frag_to_free = tmp; | 218 | frag_to_free = tmp; |
228 | free_count = uspi->s_fpb; | 219 | free_count = uspi->s_fpb; |
229 | } | 220 | } |
230 | inode->i_blocks -= uspi->s_nspb; | 221 | |
231 | mark_inode_dirty(inode); | 222 | mark_inode_dirty(inode); |
232 | } | 223 | } |
233 | 224 | ||
@@ -238,26 +229,21 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
238 | if (*ubh_get_addr32(ind_ubh,i)) | 229 | if (*ubh_get_addr32(ind_ubh,i)) |
239 | break; | 230 | break; |
240 | if (i >= uspi->s_apb) { | 231 | if (i >= uspi->s_apb) { |
241 | if (ubh_max_bcount(ind_ubh) != 1) { | 232 | tmp = fs32_to_cpu(sb, *p); |
242 | retry = 1; | 233 | *p = 0; |
243 | } | 234 | |
244 | else { | 235 | ufs_free_blocks (inode, tmp, uspi->s_fpb); |
245 | tmp = fs32_to_cpu(sb, *p); | 236 | mark_inode_dirty(inode); |
246 | *p = 0; | 237 | ubh_bforget(ind_ubh); |
247 | inode->i_blocks -= uspi->s_nspb; | 238 | ind_ubh = NULL; |
248 | mark_inode_dirty(inode); | ||
249 | ufs_free_blocks (inode, tmp, uspi->s_fpb); | ||
250 | ubh_bforget(ind_ubh); | ||
251 | ind_ubh = NULL; | ||
252 | } | ||
253 | } | 239 | } |
254 | if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) { | 240 | if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) { |
255 | ubh_ll_rw_block (SWRITE, 1, &ind_ubh); | 241 | ubh_ll_rw_block(SWRITE, ind_ubh); |
256 | ubh_wait_on_buffer (ind_ubh); | 242 | ubh_wait_on_buffer (ind_ubh); |
257 | } | 243 | } |
258 | ubh_brelse (ind_ubh); | 244 | ubh_brelse (ind_ubh); |
259 | 245 | ||
260 | UFSD(("EXIT\n")) | 246 | UFSD("EXIT\n"); |
261 | 247 | ||
262 | return retry; | 248 | return retry; |
263 | } | 249 | } |
@@ -271,7 +257,7 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | |||
271 | __fs32 * dind; | 257 | __fs32 * dind; |
272 | int retry = 0; | 258 | int retry = 0; |
273 | 259 | ||
274 | UFSD(("ENTER\n")) | 260 | UFSD("ENTER\n"); |
275 | 261 | ||
276 | sb = inode->i_sb; | 262 | sb = inode->i_sb; |
277 | uspi = UFS_SB(sb)->s_uspi; | 263 | uspi = UFS_SB(sb)->s_uspi; |
@@ -306,25 +292,21 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | |||
306 | if (*ubh_get_addr32 (dind_bh, i)) | 292 | if (*ubh_get_addr32 (dind_bh, i)) |
307 | break; | 293 | break; |
308 | if (i >= uspi->s_apb) { | 294 | if (i >= uspi->s_apb) { |
309 | if (ubh_max_bcount(dind_bh) != 1) | 295 | tmp = fs32_to_cpu(sb, *p); |
310 | retry = 1; | 296 | *p = 0; |
311 | else { | 297 | |
312 | tmp = fs32_to_cpu(sb, *p); | 298 | ufs_free_blocks(inode, tmp, uspi->s_fpb); |
313 | *p = 0; | 299 | mark_inode_dirty(inode); |
314 | inode->i_blocks -= uspi->s_nspb; | 300 | ubh_bforget(dind_bh); |
315 | mark_inode_dirty(inode); | 301 | dind_bh = NULL; |
316 | ufs_free_blocks (inode, tmp, uspi->s_fpb); | ||
317 | ubh_bforget(dind_bh); | ||
318 | dind_bh = NULL; | ||
319 | } | ||
320 | } | 302 | } |
321 | if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) { | 303 | if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) { |
322 | ubh_ll_rw_block (SWRITE, 1, &dind_bh); | 304 | ubh_ll_rw_block(SWRITE, dind_bh); |
323 | ubh_wait_on_buffer (dind_bh); | 305 | ubh_wait_on_buffer (dind_bh); |
324 | } | 306 | } |
325 | ubh_brelse (dind_bh); | 307 | ubh_brelse (dind_bh); |
326 | 308 | ||
327 | UFSD(("EXIT\n")) | 309 | UFSD("EXIT\n"); |
328 | 310 | ||
329 | return retry; | 311 | return retry; |
330 | } | 312 | } |
@@ -339,7 +321,7 @@ static int ufs_trunc_tindirect (struct inode * inode) | |||
339 | __fs32 * tind, * p; | 321 | __fs32 * tind, * p; |
340 | int retry; | 322 | int retry; |
341 | 323 | ||
342 | UFSD(("ENTER\n")) | 324 | UFSD("ENTER\n"); |
343 | 325 | ||
344 | sb = inode->i_sb; | 326 | sb = inode->i_sb; |
345 | uspi = UFS_SB(sb)->s_uspi; | 327 | uspi = UFS_SB(sb)->s_uspi; |
@@ -370,25 +352,21 @@ static int ufs_trunc_tindirect (struct inode * inode) | |||
370 | if (*ubh_get_addr32 (tind_bh, i)) | 352 | if (*ubh_get_addr32 (tind_bh, i)) |
371 | break; | 353 | break; |
372 | if (i >= uspi->s_apb) { | 354 | if (i >= uspi->s_apb) { |
373 | if (ubh_max_bcount(tind_bh) != 1) | 355 | tmp = fs32_to_cpu(sb, *p); |
374 | retry = 1; | 356 | *p = 0; |
375 | else { | 357 | |
376 | tmp = fs32_to_cpu(sb, *p); | 358 | ufs_free_blocks(inode, tmp, uspi->s_fpb); |
377 | *p = 0; | 359 | mark_inode_dirty(inode); |
378 | inode->i_blocks -= uspi->s_nspb; | 360 | ubh_bforget(tind_bh); |
379 | mark_inode_dirty(inode); | 361 | tind_bh = NULL; |
380 | ufs_free_blocks (inode, tmp, uspi->s_fpb); | ||
381 | ubh_bforget(tind_bh); | ||
382 | tind_bh = NULL; | ||
383 | } | ||
384 | } | 362 | } |
385 | if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) { | 363 | if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) { |
386 | ubh_ll_rw_block (SWRITE, 1, &tind_bh); | 364 | ubh_ll_rw_block(SWRITE, tind_bh); |
387 | ubh_wait_on_buffer (tind_bh); | 365 | ubh_wait_on_buffer (tind_bh); |
388 | } | 366 | } |
389 | ubh_brelse (tind_bh); | 367 | ubh_brelse (tind_bh); |
390 | 368 | ||
391 | UFSD(("EXIT\n")) | 369 | UFSD("EXIT\n"); |
392 | return retry; | 370 | return retry; |
393 | } | 371 | } |
394 | 372 | ||
@@ -399,7 +377,7 @@ void ufs_truncate (struct inode * inode) | |||
399 | struct ufs_sb_private_info * uspi; | 377 | struct ufs_sb_private_info * uspi; |
400 | int retry; | 378 | int retry; |
401 | 379 | ||
402 | UFSD(("ENTER\n")) | 380 | UFSD("ENTER\n"); |
403 | sb = inode->i_sb; | 381 | sb = inode->i_sb; |
404 | uspi = UFS_SB(sb)->s_uspi; | 382 | uspi = UFS_SB(sb)->s_uspi; |
405 | 383 | ||
@@ -430,5 +408,5 @@ void ufs_truncate (struct inode * inode) | |||
430 | ufsi->i_lastfrag = DIRECT_FRAGMENT; | 408 | ufsi->i_lastfrag = DIRECT_FRAGMENT; |
431 | unlock_kernel(); | 409 | unlock_kernel(); |
432 | mark_inode_dirty(inode); | 410 | mark_inode_dirty(inode); |
433 | UFSD(("EXIT\n")) | 411 | UFSD("EXIT\n"); |
434 | } | 412 | } |
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 59acc8f073..a2f13f4570 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
@@ -14,15 +14,6 @@ | |||
14 | #include "swab.h" | 14 | #include "swab.h" |
15 | #include "util.h" | 15 | #include "util.h" |
16 | 16 | ||
17 | #undef UFS_UTILS_DEBUG | ||
18 | |||
19 | #ifdef UFS_UTILS_DEBUG | ||
20 | #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; | ||
21 | #else | ||
22 | #define UFSD(x) | ||
23 | #endif | ||
24 | |||
25 | |||
26 | struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, | 17 | struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, |
27 | struct super_block *sb, u64 fragment, u64 size) | 18 | struct super_block *sb, u64 fragment, u64 size) |
28 | { | 19 | { |
@@ -63,17 +54,17 @@ struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi, | |||
63 | count = size >> uspi->s_fshift; | 54 | count = size >> uspi->s_fshift; |
64 | if (count <= 0 || count > UFS_MAXFRAG) | 55 | if (count <= 0 || count > UFS_MAXFRAG) |
65 | return NULL; | 56 | return NULL; |
66 | USPI_UBH->fragment = fragment; | 57 | USPI_UBH(uspi)->fragment = fragment; |
67 | USPI_UBH->count = count; | 58 | USPI_UBH(uspi)->count = count; |
68 | for (i = 0; i < count; i++) | 59 | for (i = 0; i < count; i++) |
69 | if (!(USPI_UBH->bh[i] = sb_bread(sb, fragment + i))) | 60 | if (!(USPI_UBH(uspi)->bh[i] = sb_bread(sb, fragment + i))) |
70 | goto failed; | 61 | goto failed; |
71 | for (; i < UFS_MAXFRAG; i++) | 62 | for (; i < UFS_MAXFRAG; i++) |
72 | USPI_UBH->bh[i] = NULL; | 63 | USPI_UBH(uspi)->bh[i] = NULL; |
73 | return USPI_UBH; | 64 | return USPI_UBH(uspi); |
74 | failed: | 65 | failed: |
75 | for (j = 0; j < i; j++) | 66 | for (j = 0; j < i; j++) |
76 | brelse (USPI_UBH->bh[j]); | 67 | brelse (USPI_UBH(uspi)->bh[j]); |
77 | return NULL; | 68 | return NULL; |
78 | } | 69 | } |
79 | 70 | ||
@@ -90,11 +81,11 @@ void ubh_brelse (struct ufs_buffer_head * ubh) | |||
90 | void ubh_brelse_uspi (struct ufs_sb_private_info * uspi) | 81 | void ubh_brelse_uspi (struct ufs_sb_private_info * uspi) |
91 | { | 82 | { |
92 | unsigned i; | 83 | unsigned i; |
93 | if (!USPI_UBH) | 84 | if (!USPI_UBH(uspi)) |
94 | return; | 85 | return; |
95 | for ( i = 0; i < USPI_UBH->count; i++ ) { | 86 | for ( i = 0; i < USPI_UBH(uspi)->count; i++ ) { |
96 | brelse (USPI_UBH->bh[i]); | 87 | brelse (USPI_UBH(uspi)->bh[i]); |
97 | USPI_UBH->bh[i] = NULL; | 88 | USPI_UBH(uspi)->bh[i] = NULL; |
98 | } | 89 | } |
99 | } | 90 | } |
100 | 91 | ||
@@ -121,13 +112,12 @@ void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag) | |||
121 | } | 112 | } |
122 | } | 113 | } |
123 | 114 | ||
124 | void ubh_ll_rw_block (int rw, unsigned nr, struct ufs_buffer_head * ubh[]) | 115 | void ubh_ll_rw_block(int rw, struct ufs_buffer_head *ubh) |
125 | { | 116 | { |
126 | unsigned i; | ||
127 | if (!ubh) | 117 | if (!ubh) |
128 | return; | 118 | return; |
129 | for ( i = 0; i < nr; i++ ) | 119 | |
130 | ll_rw_block (rw, ubh[i]->count, ubh[i]->bh); | 120 | ll_rw_block(rw, ubh->count, ubh->bh); |
131 | } | 121 | } |
132 | 122 | ||
133 | void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) | 123 | void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) |
@@ -139,18 +129,6 @@ void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) | |||
139 | wait_on_buffer (ubh->bh[i]); | 129 | wait_on_buffer (ubh->bh[i]); |
140 | } | 130 | } |
141 | 131 | ||
142 | unsigned ubh_max_bcount (struct ufs_buffer_head * ubh) | ||
143 | { | ||
144 | unsigned i; | ||
145 | unsigned max = 0; | ||
146 | if (!ubh) | ||
147 | return 0; | ||
148 | for ( i = 0; i < ubh->count; i++ ) | ||
149 | if ( atomic_read(&ubh->bh[i]->b_count) > max ) | ||
150 | max = atomic_read(&ubh->bh[i]->b_count); | ||
151 | return max; | ||
152 | } | ||
153 | |||
154 | void ubh_bforget (struct ufs_buffer_head * ubh) | 132 | void ubh_bforget (struct ufs_buffer_head * ubh) |
155 | { | 133 | { |
156 | unsigned i; | 134 | unsigned i; |
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 48d6d9bcc1..406981fff5 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -17,10 +17,16 @@ | |||
17 | #define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) | 17 | #define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * macros used for retyping | 20 | * functions used for retyping |
21 | */ | 21 | */ |
22 | #define UCPI_UBH ((struct ufs_buffer_head *)ucpi) | 22 | static inline struct ufs_buffer_head *UCPI_UBH(struct ufs_cg_private_info *cpi) |
23 | #define USPI_UBH ((struct ufs_buffer_head *)uspi) | 23 | { |
24 | return &cpi->c_ubh; | ||
25 | } | ||
26 | static inline struct ufs_buffer_head *USPI_UBH(struct ufs_sb_private_info *spi) | ||
27 | { | ||
28 | return &spi->s_ubh; | ||
29 | } | ||
24 | 30 | ||
25 | 31 | ||
26 | 32 | ||
@@ -33,12 +39,12 @@ ufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, | |||
33 | { | 39 | { |
34 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { | 40 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
35 | case UFS_ST_SUN: | 41 | case UFS_ST_SUN: |
36 | return fs32_to_cpu(sb, usb3->fs_u2.fs_sun.fs_state); | 42 | return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state); |
37 | case UFS_ST_SUNx86: | 43 | case UFS_ST_SUNx86: |
38 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state); | 44 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state); |
39 | case UFS_ST_44BSD: | 45 | case UFS_ST_44BSD: |
40 | default: | 46 | default: |
41 | return fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_state); | 47 | return fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_state); |
42 | } | 48 | } |
43 | } | 49 | } |
44 | 50 | ||
@@ -48,13 +54,13 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, | |||
48 | { | 54 | { |
49 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { | 55 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
50 | case UFS_ST_SUN: | 56 | case UFS_ST_SUN: |
51 | usb3->fs_u2.fs_sun.fs_state = cpu_to_fs32(sb, value); | 57 | usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value); |
52 | break; | 58 | break; |
53 | case UFS_ST_SUNx86: | 59 | case UFS_ST_SUNx86: |
54 | usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value); | 60 | usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value); |
55 | break; | 61 | break; |
56 | case UFS_ST_44BSD: | 62 | case UFS_ST_44BSD: |
57 | usb3->fs_u2.fs_44.fs_state = cpu_to_fs32(sb, value); | 63 | usb3->fs_un2.fs_44.fs_state = cpu_to_fs32(sb, value); |
58 | break; | 64 | break; |
59 | } | 65 | } |
60 | } | 66 | } |
@@ -64,7 +70,7 @@ ufs_get_fs_npsect(struct super_block *sb, struct ufs_super_block_first *usb1, | |||
64 | struct ufs_super_block_third *usb3) | 70 | struct ufs_super_block_third *usb3) |
65 | { | 71 | { |
66 | if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) | 72 | if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) |
67 | return fs32_to_cpu(sb, usb3->fs_u2.fs_sunx86.fs_npsect); | 73 | return fs32_to_cpu(sb, usb3->fs_un2.fs_sunx86.fs_npsect); |
68 | else | 74 | else |
69 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect); | 75 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect); |
70 | } | 76 | } |
@@ -76,16 +82,16 @@ ufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3) | |||
76 | 82 | ||
77 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { | 83 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
78 | case UFS_ST_SUN: | 84 | case UFS_ST_SUN: |
79 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sun.fs_qbmask[0]; | 85 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0]; |
80 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qbmask[1]; | 86 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1]; |
81 | break; | 87 | break; |
82 | case UFS_ST_SUNx86: | 88 | case UFS_ST_SUNx86: |
83 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qbmask[0]; | 89 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qbmask[0]; |
84 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qbmask[1]; | 90 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qbmask[1]; |
85 | break; | 91 | break; |
86 | case UFS_ST_44BSD: | 92 | case UFS_ST_44BSD: |
87 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qbmask[0]; | 93 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qbmask[0]; |
88 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qbmask[1]; | 94 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qbmask[1]; |
89 | break; | 95 | break; |
90 | } | 96 | } |
91 | 97 | ||
@@ -99,16 +105,16 @@ ufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3) | |||
99 | 105 | ||
100 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { | 106 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
101 | case UFS_ST_SUN: | 107 | case UFS_ST_SUN: |
102 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sun.fs_qfmask[0]; | 108 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0]; |
103 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qfmask[1]; | 109 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1]; |
104 | break; | 110 | break; |
105 | case UFS_ST_SUNx86: | 111 | case UFS_ST_SUNx86: |
106 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qfmask[0]; | 112 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qfmask[0]; |
107 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qfmask[1]; | 113 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qfmask[1]; |
108 | break; | 114 | break; |
109 | case UFS_ST_44BSD: | 115 | case UFS_ST_44BSD: |
110 | ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qfmask[0]; | 116 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qfmask[0]; |
111 | ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qfmask[1]; | 117 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qfmask[1]; |
112 | break; | 118 | break; |
113 | } | 119 | } |
114 | 120 | ||
@@ -236,9 +242,8 @@ extern void ubh_brelse (struct ufs_buffer_head *); | |||
236 | extern void ubh_brelse_uspi (struct ufs_sb_private_info *); | 242 | extern void ubh_brelse_uspi (struct ufs_sb_private_info *); |
237 | extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); | 243 | extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); |
238 | extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); | 244 | extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); |
239 | extern void ubh_ll_rw_block (int, unsigned, struct ufs_buffer_head **); | 245 | extern void ubh_ll_rw_block(int, struct ufs_buffer_head *); |
240 | extern void ubh_wait_on_buffer (struct ufs_buffer_head *); | 246 | extern void ubh_wait_on_buffer (struct ufs_buffer_head *); |
241 | extern unsigned ubh_max_bcount (struct ufs_buffer_head *); | ||
242 | extern void ubh_bforget (struct ufs_buffer_head *); | 247 | extern void ubh_bforget (struct ufs_buffer_head *); |
243 | extern int ubh_buffer_dirty (struct ufs_buffer_head *); | 248 | extern int ubh_buffer_dirty (struct ufs_buffer_head *); |
244 | #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) | 249 | #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) |
@@ -297,40 +302,26 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, | |||
297 | #define ubh_blkmap(ubh,begin,bit) \ | 302 | #define ubh_blkmap(ubh,begin,bit) \ |
298 | ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) | 303 | ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) |
299 | 304 | ||
300 | |||
301 | /* | ||
302 | * Macros for access to superblock array structures | ||
303 | */ | ||
304 | #define ubh_postbl(ubh,cylno,i) \ | ||
305 | ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \ | ||
306 | ? (*(__s16*)(ubh_get_addr(ubh, \ | ||
307 | (unsigned)(&((struct ufs_super_block *)0)->fs_opostbl) \ | ||
308 | + (((cylno) * 16 + (i)) << 1) ) )) \ | ||
309 | : (*(__s16*)(ubh_get_addr(ubh, \ | ||
310 | uspi->s_postbloff + (((cylno) * uspi->s_nrpos + (i)) << 1) )))) | ||
311 | |||
312 | #define ubh_rotbl(ubh,i) \ | ||
313 | ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \ | ||
314 | ? (*(__u8*)(ubh_get_addr(ubh, \ | ||
315 | (unsigned)(&((struct ufs_super_block *)0)->fs_space) + (i)))) \ | ||
316 | : (*(__u8*)(ubh_get_addr(ubh, uspi->s_rotbloff + (i))))) | ||
317 | |||
318 | /* | 305 | /* |
319 | * Determine the number of available frags given a | 306 | * Determine the number of available frags given a |
320 | * percentage to hold in reserve. | 307 | * percentage to hold in reserve. |
321 | */ | 308 | */ |
322 | #define ufs_freespace(usb, percentreserved) \ | 309 | static inline u64 |
323 | (ufs_blkstofrags(fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nbfree)) + \ | 310 | ufs_freespace(struct ufs_sb_private_info *uspi, int percentreserved) |
324 | fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nffree) - (uspi->s_dsize * (percentreserved) / 100)) | 311 | { |
312 | return ufs_blkstofrags(uspi->cs_total.cs_nbfree) + | ||
313 | uspi->cs_total.cs_nffree - | ||
314 | (uspi->s_dsize * (percentreserved) / 100); | ||
315 | } | ||
325 | 316 | ||
326 | /* | 317 | /* |
327 | * Macros to access cylinder group array structures | 318 | * Macros to access cylinder group array structures |
328 | */ | 319 | */ |
329 | #define ubh_cg_blktot(ucpi,cylno) \ | 320 | #define ubh_cg_blktot(ucpi,cylno) \ |
330 | (*((__fs32*)ubh_get_addr(UCPI_UBH, (ucpi)->c_btotoff + ((cylno) << 2)))) | 321 | (*((__fs32*)ubh_get_addr(UCPI_UBH(ucpi), (ucpi)->c_btotoff + ((cylno) << 2)))) |
331 | 322 | ||
332 | #define ubh_cg_blks(ucpi,cylno,rpos) \ | 323 | #define ubh_cg_blks(ucpi,cylno,rpos) \ |
333 | (*((__fs16*)ubh_get_addr(UCPI_UBH, \ | 324 | (*((__fs16*)ubh_get_addr(UCPI_UBH(ucpi), \ |
334 | (ucpi)->c_boff + (((cylno) * uspi->s_nrpos + (rpos)) << 1 )))) | 325 | (ucpi)->c_boff + (((cylno) * uspi->s_nrpos + (rpos)) << 1 )))) |
335 | 326 | ||
336 | /* | 327 | /* |
@@ -508,29 +499,3 @@ static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap, | |||
508 | if (fragsize > 0 && fragsize < uspi->s_fpb) | 499 | if (fragsize > 0 && fragsize < uspi->s_fpb) |
509 | fs32_add(sb, &fraglist[fragsize], cnt); | 500 | fs32_add(sb, &fraglist[fragsize], cnt); |
510 | } | 501 | } |
511 | |||
512 | #define ubh_scanc(ubh,begin,size,table,mask) _ubh_scanc_(uspi,ubh,begin,size,table,mask) | ||
513 | static inline unsigned _ubh_scanc_(struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, | ||
514 | unsigned begin, unsigned size, unsigned char * table, unsigned char mask) | ||
515 | { | ||
516 | unsigned rest, offset; | ||
517 | unsigned char * cp; | ||
518 | |||
519 | |||
520 | offset = begin & ~uspi->s_fmask; | ||
521 | begin >>= uspi->s_fshift; | ||
522 | for (;;) { | ||
523 | if ((offset + size) < uspi->s_fsize) | ||
524 | rest = size; | ||
525 | else | ||
526 | rest = uspi->s_fsize - offset; | ||
527 | size -= rest; | ||
528 | cp = ubh->bh[begin]->b_data + offset; | ||
529 | while ((table[*cp++] & mask) == 0 && --rest); | ||
530 | if (rest || !size) | ||
531 | break; | ||
532 | begin++; | ||
533 | offset = 0; | ||
534 | } | ||
535 | return (size + rest); | ||
536 | } | ||