diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 23:00:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 23:00:43 -0500 |
commit | 4c9a44aebeaef35570a67aed17b72a2cf8d0b219 (patch) | |
tree | abb874fe7f50671627b282f6c7fb58db5e75a2e3 /fs/hfsplus | |
parent | 1f0377ff088ed2971c57debc9b0c3b846ec431fd (diff) | |
parent | cfde819088422503b5c69e03ab7bb90f87121d4d (diff) |
Merge branch 'akpm' (Andrew's patch-bomb)
Merge the rest of Andrew's patches for -rc1:
"A bunch of fixes and misc missed-out-on things.
That'll do for -rc1. I still have a batch of IPC patches which still
have a possible bug report which I'm chasing down."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (25 commits)
keys: use keyring_alloc() to create module signing keyring
keys: fix unreachable code
sendfile: allows bypassing of notifier events
SGI-XP: handle non-fatal traps
fat: fix incorrect function comment
Documentation: ABI: remove testing/sysfs-devices-node
proc: fix inconsistent lock state
linux/kernel.h: fix DIV_ROUND_CLOSEST with unsigned divisors
memcg: don't register hotcpu notifier from ->css_alloc()
checkpatch: warn on uapi #includes that #include <uapi/...
revert "rtc: recycle id when unloading a rtc driver"
mm: clean up transparent hugepage sysfs error messages
hfsplus: add error message for the case of failure of sync fs in delayed_sync_fs() method
hfsplus: rework processing of hfs_btree_write() returned error
hfsplus: rework processing errors in hfsplus_free_extents()
hfsplus: avoid crash on failed block map free
kcmp: include linux/ptrace.h
drivers/rtc/rtc-imxdi.c: must include <linux/spinlock.h>
mm: cma: WARN if freed memory is still in use
exec: do not leave bprm->interp on stack
...
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/bitmap.c | 13 | ||||
-rw-r--r-- | fs/hfsplus/btree.c | 5 | ||||
-rw-r--r-- | fs/hfsplus/extents.c | 24 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 2 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 15 |
5 files changed, 48 insertions, 11 deletions
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index 4cfbe2edd296..6feefc0cb48a 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c | |||
@@ -176,12 +176,14 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) | |||
176 | dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count); | 176 | dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count); |
177 | /* are all of the bits in range? */ | 177 | /* are all of the bits in range? */ |
178 | if ((offset + count) > sbi->total_blocks) | 178 | if ((offset + count) > sbi->total_blocks) |
179 | return -2; | 179 | return -ENOENT; |
180 | 180 | ||
181 | mutex_lock(&sbi->alloc_mutex); | 181 | mutex_lock(&sbi->alloc_mutex); |
182 | mapping = sbi->alloc_file->i_mapping; | 182 | mapping = sbi->alloc_file->i_mapping; |
183 | pnr = offset / PAGE_CACHE_BITS; | 183 | pnr = offset / PAGE_CACHE_BITS; |
184 | page = read_mapping_page(mapping, pnr, NULL); | 184 | page = read_mapping_page(mapping, pnr, NULL); |
185 | if (IS_ERR(page)) | ||
186 | goto kaboom; | ||
185 | pptr = kmap(page); | 187 | pptr = kmap(page); |
186 | curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; | 188 | curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; |
187 | end = pptr + PAGE_CACHE_BITS / 32; | 189 | end = pptr + PAGE_CACHE_BITS / 32; |
@@ -214,6 +216,8 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) | |||
214 | set_page_dirty(page); | 216 | set_page_dirty(page); |
215 | kunmap(page); | 217 | kunmap(page); |
216 | page = read_mapping_page(mapping, ++pnr, NULL); | 218 | page = read_mapping_page(mapping, ++pnr, NULL); |
219 | if (IS_ERR(page)) | ||
220 | goto kaboom; | ||
217 | pptr = kmap(page); | 221 | pptr = kmap(page); |
218 | curr = pptr; | 222 | curr = pptr; |
219 | end = pptr + PAGE_CACHE_BITS / 32; | 223 | end = pptr + PAGE_CACHE_BITS / 32; |
@@ -232,4 +236,11 @@ out: | |||
232 | mutex_unlock(&sbi->alloc_mutex); | 236 | mutex_unlock(&sbi->alloc_mutex); |
233 | 237 | ||
234 | return 0; | 238 | return 0; |
239 | |||
240 | kaboom: | ||
241 | printk(KERN_CRIT "hfsplus: unable to mark blocks free: error %ld\n", | ||
242 | PTR_ERR(page)); | ||
243 | mutex_unlock(&sbi->alloc_mutex); | ||
244 | |||
245 | return -EIO; | ||
235 | } | 246 | } |
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 21023d9f8ff3..685d07d0ed18 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c | |||
@@ -159,7 +159,7 @@ void hfs_btree_close(struct hfs_btree *tree) | |||
159 | kfree(tree); | 159 | kfree(tree); |
160 | } | 160 | } |
161 | 161 | ||
162 | void hfs_btree_write(struct hfs_btree *tree) | 162 | int hfs_btree_write(struct hfs_btree *tree) |
163 | { | 163 | { |
164 | struct hfs_btree_header_rec *head; | 164 | struct hfs_btree_header_rec *head; |
165 | struct hfs_bnode *node; | 165 | struct hfs_bnode *node; |
@@ -168,7 +168,7 @@ void hfs_btree_write(struct hfs_btree *tree) | |||
168 | node = hfs_bnode_find(tree, 0); | 168 | node = hfs_bnode_find(tree, 0); |
169 | if (IS_ERR(node)) | 169 | if (IS_ERR(node)) |
170 | /* panic? */ | 170 | /* panic? */ |
171 | return; | 171 | return -EIO; |
172 | /* Load the header */ | 172 | /* Load the header */ |
173 | page = node->page[0]; | 173 | page = node->page[0]; |
174 | head = (struct hfs_btree_header_rec *)(kmap(page) + | 174 | head = (struct hfs_btree_header_rec *)(kmap(page) + |
@@ -186,6 +186,7 @@ void hfs_btree_write(struct hfs_btree *tree) | |||
186 | kunmap(page); | 186 | kunmap(page); |
187 | set_page_dirty(page); | 187 | set_page_dirty(page); |
188 | hfs_bnode_put(node); | 188 | hfs_bnode_put(node); |
189 | return 0; | ||
189 | } | 190 | } |
190 | 191 | ||
191 | static struct hfs_bnode *hfs_bmap_new_bmap(struct hfs_bnode *prev, u32 idx) | 192 | static struct hfs_bnode *hfs_bmap_new_bmap(struct hfs_bnode *prev, u32 idx) |
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 5849e3ef35cc..eba76eab6d62 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
@@ -329,6 +329,7 @@ static int hfsplus_free_extents(struct super_block *sb, | |||
329 | { | 329 | { |
330 | u32 count, start; | 330 | u32 count, start; |
331 | int i; | 331 | int i; |
332 | int err = 0; | ||
332 | 333 | ||
333 | hfsplus_dump_extent(extent); | 334 | hfsplus_dump_extent(extent); |
334 | for (i = 0; i < 8; extent++, i++) { | 335 | for (i = 0; i < 8; extent++, i++) { |
@@ -345,18 +346,33 @@ found: | |||
345 | for (;;) { | 346 | for (;;) { |
346 | start = be32_to_cpu(extent->start_block); | 347 | start = be32_to_cpu(extent->start_block); |
347 | if (count <= block_nr) { | 348 | if (count <= block_nr) { |
348 | hfsplus_block_free(sb, start, count); | 349 | err = hfsplus_block_free(sb, start, count); |
350 | if (err) { | ||
351 | printk(KERN_ERR "hfs: can't free extent\n"); | ||
352 | dprint(DBG_EXTENT, " start: %u count: %u\n", | ||
353 | start, count); | ||
354 | } | ||
349 | extent->block_count = 0; | 355 | extent->block_count = 0; |
350 | extent->start_block = 0; | 356 | extent->start_block = 0; |
351 | block_nr -= count; | 357 | block_nr -= count; |
352 | } else { | 358 | } else { |
353 | count -= block_nr; | 359 | count -= block_nr; |
354 | hfsplus_block_free(sb, start + count, block_nr); | 360 | err = hfsplus_block_free(sb, start + count, block_nr); |
361 | if (err) { | ||
362 | printk(KERN_ERR "hfs: can't free extent\n"); | ||
363 | dprint(DBG_EXTENT, " start: %u count: %u\n", | ||
364 | start, count); | ||
365 | } | ||
355 | extent->block_count = cpu_to_be32(count); | 366 | extent->block_count = cpu_to_be32(count); |
356 | block_nr = 0; | 367 | block_nr = 0; |
357 | } | 368 | } |
358 | if (!block_nr || !i) | 369 | if (!block_nr || !i) { |
359 | return 0; | 370 | /* |
371 | * Try to free all extents and | ||
372 | * return only last error | ||
373 | */ | ||
374 | return err; | ||
375 | } | ||
360 | i--; | 376 | i--; |
361 | extent--; | 377 | extent--; |
362 | count = be32_to_cpu(extent->block_count); | 378 | count = be32_to_cpu(extent->block_count); |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index c571de224b15..a6da86b1b4c1 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -335,7 +335,7 @@ int hfsplus_block_free(struct super_block *, u32, u32); | |||
335 | /* btree.c */ | 335 | /* btree.c */ |
336 | struct hfs_btree *hfs_btree_open(struct super_block *, u32); | 336 | struct hfs_btree *hfs_btree_open(struct super_block *, u32); |
337 | void hfs_btree_close(struct hfs_btree *); | 337 | void hfs_btree_close(struct hfs_btree *); |
338 | void hfs_btree_write(struct hfs_btree *); | 338 | int hfs_btree_write(struct hfs_btree *); |
339 | struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *); | 339 | struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *); |
340 | void hfs_bmap_free(struct hfs_bnode *); | 340 | void hfs_bmap_free(struct hfs_bnode *); |
341 | 341 | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 811a84d2d964..796198d26553 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -127,8 +127,14 @@ static int hfsplus_system_write_inode(struct inode *inode) | |||
127 | hfsplus_mark_mdb_dirty(inode->i_sb); | 127 | hfsplus_mark_mdb_dirty(inode->i_sb); |
128 | } | 128 | } |
129 | hfsplus_inode_write_fork(inode, fork); | 129 | hfsplus_inode_write_fork(inode, fork); |
130 | if (tree) | 130 | if (tree) { |
131 | hfs_btree_write(tree); | 131 | int err = hfs_btree_write(tree); |
132 | if (err) { | ||
133 | printk(KERN_ERR "hfs: b-tree write err: %d, ino %lu\n", | ||
134 | err, inode->i_ino); | ||
135 | return err; | ||
136 | } | ||
137 | } | ||
132 | return 0; | 138 | return 0; |
133 | } | 139 | } |
134 | 140 | ||
@@ -226,6 +232,7 @@ out: | |||
226 | 232 | ||
227 | static void delayed_sync_fs(struct work_struct *work) | 233 | static void delayed_sync_fs(struct work_struct *work) |
228 | { | 234 | { |
235 | int err; | ||
229 | struct hfsplus_sb_info *sbi; | 236 | struct hfsplus_sb_info *sbi; |
230 | 237 | ||
231 | sbi = container_of(work, struct hfsplus_sb_info, sync_work.work); | 238 | sbi = container_of(work, struct hfsplus_sb_info, sync_work.work); |
@@ -234,7 +241,9 @@ static void delayed_sync_fs(struct work_struct *work) | |||
234 | sbi->work_queued = 0; | 241 | sbi->work_queued = 0; |
235 | spin_unlock(&sbi->work_lock); | 242 | spin_unlock(&sbi->work_lock); |
236 | 243 | ||
237 | hfsplus_sync_fs(sbi->alloc_file->i_sb, 1); | 244 | err = hfsplus_sync_fs(sbi->alloc_file->i_sb, 1); |
245 | if (err) | ||
246 | printk(KERN_ERR "hfs: delayed sync fs err %d\n", err); | ||
238 | } | 247 | } |
239 | 248 | ||
240 | void hfsplus_mark_mdb_dirty(struct super_block *sb) | 249 | void hfsplus_mark_mdb_dirty(struct super_block *sb) |