diff options
| author | Jeff Garzik <jeff@garzik.org> | 2006-08-19 17:27:12 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-08-19 17:27:12 -0400 |
| commit | d14b50cc60ca465290fcdb3b88e7d5fb684361ed (patch) | |
| tree | c4a712123b94cd4c0ab4d8d9d87a7619e9bcb6ba /fs | |
| parent | a34b6fc04d58ad72fe0cc74cd448f4551bd2ebaf (diff) | |
| parent | ef7d1b244fa6c94fb76d5f787b8629df64ea4046 (diff) | |
Merge branch 'master' into upstream-fixes
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/adfs/super.c | 2 | ||||
| -rw-r--r-- | fs/fuse/file.c | 10 | ||||
| -rw-r--r-- | fs/jfs/inode.c | 16 | ||||
| -rw-r--r-- | fs/jfs/jfs_inode.h | 1 | ||||
| -rw-r--r-- | fs/jfs/super.c | 118 | ||||
| -rw-r--r-- | fs/locks.c | 6 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 1 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmunlock.c | 43 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.c | 8 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.c | 261 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/super.c | 8 | ||||
| -rw-r--r-- | fs/udf/super.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_alloc.c | 103 |
15 files changed, 457 insertions, 131 deletions
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index ba1c88af49fe..82011019494c 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
| @@ -308,7 +308,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di | |||
| 308 | if (adfs_checkmap(sb, dm)) | 308 | if (adfs_checkmap(sb, dm)) |
| 309 | return dm; | 309 | return dm; |
| 310 | 310 | ||
| 311 | adfs_error(sb, NULL, "map corrupted"); | 311 | adfs_error(sb, "map corrupted"); |
| 312 | 312 | ||
| 313 | error_free: | 313 | error_free: |
| 314 | while (--zone >= 0) | 314 | while (--zone >= 0) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 63614ed16336..5c4fcd1dbf59 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -395,14 +395,16 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
| 395 | struct fuse_readpages_data data; | 395 | struct fuse_readpages_data data; |
| 396 | int err; | 396 | int err; |
| 397 | 397 | ||
| 398 | err = -EIO; | ||
| 398 | if (is_bad_inode(inode)) | 399 | if (is_bad_inode(inode)) |
| 399 | return -EIO; | 400 | goto clean_pages_up; |
| 400 | 401 | ||
| 401 | data.file = file; | 402 | data.file = file; |
| 402 | data.inode = inode; | 403 | data.inode = inode; |
| 403 | data.req = fuse_get_req(fc); | 404 | data.req = fuse_get_req(fc); |
| 405 | err = PTR_ERR(data.req); | ||
| 404 | if (IS_ERR(data.req)) | 406 | if (IS_ERR(data.req)) |
| 405 | return PTR_ERR(data.req); | 407 | goto clean_pages_up; |
| 406 | 408 | ||
| 407 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); | 409 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
| 408 | if (!err) { | 410 | if (!err) { |
| @@ -412,6 +414,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
| 412 | fuse_put_request(fc, data.req); | 414 | fuse_put_request(fc, data.req); |
| 413 | } | 415 | } |
| 414 | return err; | 416 | return err; |
| 417 | |||
| 418 | clean_pages_up: | ||
| 419 | put_pages_list(pages); | ||
| 420 | return err; | ||
| 415 | } | 421 | } |
| 416 | 422 | ||
| 417 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, | 423 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 43e3f566aad6..a223cf4faa9b 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
| @@ -168,16 +168,15 @@ void jfs_dirty_inode(struct inode *inode) | |||
| 168 | set_cflag(COMMIT_Dirty, inode); | 168 | set_cflag(COMMIT_Dirty, inode); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static int | 171 | int jfs_get_block(struct inode *ip, sector_t lblock, |
| 172 | jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | 172 | struct buffer_head *bh_result, int create) |
| 173 | struct buffer_head *bh_result, int create) | ||
| 174 | { | 173 | { |
| 175 | s64 lblock64 = lblock; | 174 | s64 lblock64 = lblock; |
| 176 | int rc = 0; | 175 | int rc = 0; |
| 177 | xad_t xad; | 176 | xad_t xad; |
| 178 | s64 xaddr; | 177 | s64 xaddr; |
| 179 | int xflag; | 178 | int xflag; |
| 180 | s32 xlen = max_blocks; | 179 | s32 xlen = bh_result->b_size >> ip->i_blkbits; |
| 181 | 180 | ||
| 182 | /* | 181 | /* |
| 183 | * Take appropriate lock on inode | 182 | * Take appropriate lock on inode |
| @@ -188,7 +187,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
| 188 | IREAD_LOCK(ip); | 187 | IREAD_LOCK(ip); |
| 189 | 188 | ||
| 190 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && | 189 | if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && |
| 191 | (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) && | 190 | (!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) && |
| 192 | xaddr) { | 191 | xaddr) { |
| 193 | if (xflag & XAD_NOTRECORDED) { | 192 | if (xflag & XAD_NOTRECORDED) { |
| 194 | if (!create) | 193 | if (!create) |
| @@ -255,13 +254,6 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, | |||
| 255 | return rc; | 254 | return rc; |
| 256 | } | 255 | } |
| 257 | 256 | ||
| 258 | static int jfs_get_block(struct inode *ip, sector_t lblock, | ||
| 259 | struct buffer_head *bh_result, int create) | ||
| 260 | { | ||
| 261 | return jfs_get_blocks(ip, lblock, bh_result->b_size >> ip->i_blkbits, | ||
| 262 | bh_result, create); | ||
| 263 | } | ||
| 264 | |||
| 265 | static int jfs_writepage(struct page *page, struct writeback_control *wbc) | 257 | static int jfs_writepage(struct page *page, struct writeback_control *wbc) |
| 266 | { | 258 | { |
| 267 | return nobh_writepage(page, jfs_get_block, wbc); | 259 | return nobh_writepage(page, jfs_get_block, wbc); |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index b5c7da6190dc..1fc48df670c8 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
| @@ -32,6 +32,7 @@ extern void jfs_truncate_nolock(struct inode *, loff_t); | |||
| 32 | extern void jfs_free_zero_link(struct inode *); | 32 | extern void jfs_free_zero_link(struct inode *); |
| 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); | 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); |
| 34 | extern void jfs_set_inode_flags(struct inode *); | 34 | extern void jfs_set_inode_flags(struct inode *); |
| 35 | extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); | ||
| 35 | 36 | ||
| 36 | extern const struct address_space_operations jfs_aops; | 37 | extern const struct address_space_operations jfs_aops; |
| 37 | extern struct inode_operations jfs_dir_inode_operations; | 38 | extern struct inode_operations jfs_dir_inode_operations; |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 4f6cfebc82db..143bcd1d5eaa 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| 27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
| 28 | #include <linux/posix_acl.h> | 28 | #include <linux/posix_acl.h> |
| 29 | #include <linux/buffer_head.h> | ||
| 29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
| 30 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
| 31 | 32 | ||
| @@ -298,7 +299,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
| 298 | break; | 299 | break; |
| 299 | } | 300 | } |
| 300 | 301 | ||
| 301 | #if defined(CONFIG_QUOTA) | 302 | #ifdef CONFIG_QUOTA |
| 302 | case Opt_quota: | 303 | case Opt_quota: |
| 303 | case Opt_usrquota: | 304 | case Opt_usrquota: |
| 304 | *flag |= JFS_USRQUOTA; | 305 | *flag |= JFS_USRQUOTA; |
| @@ -597,7 +598,7 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 597 | if (sbi->flag & JFS_NOINTEGRITY) | 598 | if (sbi->flag & JFS_NOINTEGRITY) |
| 598 | seq_puts(seq, ",nointegrity"); | 599 | seq_puts(seq, ",nointegrity"); |
| 599 | 600 | ||
| 600 | #if defined(CONFIG_QUOTA) | 601 | #ifdef CONFIG_QUOTA |
| 601 | if (sbi->flag & JFS_USRQUOTA) | 602 | if (sbi->flag & JFS_USRQUOTA) |
| 602 | seq_puts(seq, ",usrquota"); | 603 | seq_puts(seq, ",usrquota"); |
| 603 | 604 | ||
| @@ -608,6 +609,113 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 608 | return 0; | 609 | return 0; |
| 609 | } | 610 | } |
| 610 | 611 | ||
| 612 | #ifdef CONFIG_QUOTA | ||
| 613 | |||
| 614 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | ||
| 615 | * acquiring the locks... As quota files are never truncated and quota code | ||
| 616 | * itself serializes the operations (and noone else should touch the files) | ||
| 617 | * we don't have to be afraid of races */ | ||
| 618 | static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, | ||
| 619 | size_t len, loff_t off) | ||
| 620 | { | ||
| 621 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
| 622 | sector_t blk = off >> sb->s_blocksize_bits; | ||
| 623 | int err = 0; | ||
| 624 | int offset = off & (sb->s_blocksize - 1); | ||
| 625 | int tocopy; | ||
| 626 | size_t toread; | ||
| 627 | struct buffer_head tmp_bh; | ||
| 628 | struct buffer_head *bh; | ||
| 629 | loff_t i_size = i_size_read(inode); | ||
| 630 | |||
| 631 | if (off > i_size) | ||
| 632 | return 0; | ||
| 633 | if (off+len > i_size) | ||
| 634 | len = i_size-off; | ||
| 635 | toread = len; | ||
| 636 | while (toread > 0) { | ||
| 637 | tocopy = sb->s_blocksize - offset < toread ? | ||
| 638 | sb->s_blocksize - offset : toread; | ||
| 639 | |||
| 640 | tmp_bh.b_state = 0; | ||
| 641 | tmp_bh.b_size = 1 << inode->i_blkbits; | ||
| 642 | err = jfs_get_block(inode, blk, &tmp_bh, 0); | ||
| 643 | if (err) | ||
| 644 | return err; | ||
| 645 | if (!buffer_mapped(&tmp_bh)) /* A hole? */ | ||
| 646 | memset(data, 0, tocopy); | ||
| 647 | else { | ||
| 648 | bh = sb_bread(sb, tmp_bh.b_blocknr); | ||
| 649 | if (!bh) | ||
| 650 | return -EIO; | ||
| 651 | memcpy(data, bh->b_data+offset, tocopy); | ||
| 652 | brelse(bh); | ||
| 653 | } | ||
| 654 | offset = 0; | ||
| 655 | toread -= tocopy; | ||
| 656 | data += tocopy; | ||
| 657 | blk++; | ||
| 658 | } | ||
| 659 | return len; | ||
| 660 | } | ||
| 661 | |||
| 662 | /* Write to quotafile */ | ||
| 663 | static ssize_t jfs_quota_write(struct super_block *sb, int type, | ||
| 664 | const char *data, size_t len, loff_t off) | ||
| 665 | { | ||
| 666 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
| 667 | sector_t blk = off >> sb->s_blocksize_bits; | ||
| 668 | int err = 0; | ||
| 669 | int offset = off & (sb->s_blocksize - 1); | ||
| 670 | int tocopy; | ||
| 671 | size_t towrite = len; | ||
| 672 | struct buffer_head tmp_bh; | ||
| 673 | struct buffer_head *bh; | ||
| 674 | |||
| 675 | mutex_lock(&inode->i_mutex); | ||
| 676 | while (towrite > 0) { | ||
| 677 | tocopy = sb->s_blocksize - offset < towrite ? | ||
| 678 | sb->s_blocksize - offset : towrite; | ||
| 679 | |||
| 680 | tmp_bh.b_state = 0; | ||
| 681 | tmp_bh.b_size = 1 << inode->i_blkbits; | ||
| 682 | err = jfs_get_block(inode, blk, &tmp_bh, 1); | ||
| 683 | if (err) | ||
| 684 | goto out; | ||
| 685 | if (offset || tocopy != sb->s_blocksize) | ||
| 686 | bh = sb_bread(sb, tmp_bh.b_blocknr); | ||
| 687 | else | ||
| 688 | bh = sb_getblk(sb, tmp_bh.b_blocknr); | ||
| 689 | if (!bh) { | ||
| 690 | err = -EIO; | ||
| 691 | goto out; | ||
| 692 | } | ||
| 693 | lock_buffer(bh); | ||
| 694 | memcpy(bh->b_data+offset, data, tocopy); | ||
| 695 | flush_dcache_page(bh->b_page); | ||
| 696 | set_buffer_uptodate(bh); | ||
| 697 | mark_buffer_dirty(bh); | ||
| 698 | unlock_buffer(bh); | ||
| 699 | brelse(bh); | ||
| 700 | offset = 0; | ||
| 701 | towrite -= tocopy; | ||
| 702 | data += tocopy; | ||
| 703 | blk++; | ||
| 704 | } | ||
| 705 | out: | ||
| 706 | if (len == towrite) | ||
| 707 | return err; | ||
| 708 | if (inode->i_size < off+len-towrite) | ||
| 709 | i_size_write(inode, off+len-towrite); | ||
| 710 | inode->i_version++; | ||
| 711 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 712 | mark_inode_dirty(inode); | ||
| 713 | mutex_unlock(&inode->i_mutex); | ||
| 714 | return len - towrite; | ||
| 715 | } | ||
| 716 | |||
| 717 | #endif | ||
| 718 | |||
| 611 | static struct super_operations jfs_super_operations = { | 719 | static struct super_operations jfs_super_operations = { |
| 612 | .alloc_inode = jfs_alloc_inode, | 720 | .alloc_inode = jfs_alloc_inode, |
| 613 | .destroy_inode = jfs_destroy_inode, | 721 | .destroy_inode = jfs_destroy_inode, |
| @@ -621,7 +729,11 @@ static struct super_operations jfs_super_operations = { | |||
| 621 | .unlockfs = jfs_unlockfs, | 729 | .unlockfs = jfs_unlockfs, |
| 622 | .statfs = jfs_statfs, | 730 | .statfs = jfs_statfs, |
| 623 | .remount_fs = jfs_remount, | 731 | .remount_fs = jfs_remount, |
| 624 | .show_options = jfs_show_options | 732 | .show_options = jfs_show_options, |
| 733 | #ifdef CONFIG_QUOTA | ||
| 734 | .quota_read = jfs_quota_read, | ||
| 735 | .quota_write = jfs_quota_write, | ||
| 736 | #endif | ||
| 625 | }; | 737 | }; |
| 626 | 738 | ||
| 627 | static struct export_operations jfs_export_operations = { | 739 | static struct export_operations jfs_export_operations = { |
diff --git a/fs/locks.c b/fs/locks.c index b0b41a64e10b..d7c53392cac1 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -1421,8 +1421,9 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) | |||
| 1421 | if (!leases_enable) | 1421 | if (!leases_enable) |
| 1422 | goto out; | 1422 | goto out; |
| 1423 | 1423 | ||
| 1424 | error = lease_alloc(filp, arg, &fl); | 1424 | error = -ENOMEM; |
| 1425 | if (error) | 1425 | fl = locks_alloc_lock(); |
| 1426 | if (fl == NULL) | ||
| 1426 | goto out; | 1427 | goto out; |
| 1427 | 1428 | ||
| 1428 | locks_copy_lock(fl, lease); | 1429 | locks_copy_lock(fl, lease); |
| @@ -1430,6 +1431,7 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) | |||
| 1430 | locks_insert_lock(before, fl); | 1431 | locks_insert_lock(before, fl); |
| 1431 | 1432 | ||
| 1432 | *flp = fl; | 1433 | *flp = fl; |
| 1434 | error = 0; | ||
| 1433 | out: | 1435 | out: |
| 1434 | return error; | 1436 | return error; |
| 1435 | } | 1437 | } |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 1b8346dd0572..9503240ef0e5 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -2375,7 +2375,6 @@ leave: | |||
| 2375 | mlog(0, "returning %d\n", ret); | 2375 | mlog(0, "returning %d\n", ret); |
| 2376 | return ret; | 2376 | return ret; |
| 2377 | } | 2377 | } |
| 2378 | EXPORT_SYMBOL_GPL(dlm_migrate_lockres); | ||
| 2379 | 2378 | ||
| 2380 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock) | 2379 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock) |
| 2381 | { | 2380 | { |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index b0c3134f4f70..37be4b2e0d4a 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
| @@ -155,7 +155,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 155 | else | 155 | else |
| 156 | status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions); | 156 | status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions); |
| 157 | 157 | ||
| 158 | if (status != DLM_NORMAL) | 158 | if (status != DLM_NORMAL && (status != DLM_CANCELGRANT || !master_node)) |
| 159 | goto leave; | 159 | goto leave; |
| 160 | 160 | ||
| 161 | /* By now this has been masked out of cancel requests. */ | 161 | /* By now this has been masked out of cancel requests. */ |
| @@ -183,8 +183,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 183 | spin_lock(&lock->spinlock); | 183 | spin_lock(&lock->spinlock); |
| 184 | /* if the master told us the lock was already granted, | 184 | /* if the master told us the lock was already granted, |
| 185 | * let the ast handle all of these actions */ | 185 | * let the ast handle all of these actions */ |
| 186 | if (status == DLM_NORMAL && | 186 | if (status == DLM_CANCELGRANT) { |
| 187 | lksb->status == DLM_CANCELGRANT) { | ||
| 188 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| | 187 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| |
| 189 | DLM_UNLOCK_REGRANT_LOCK| | 188 | DLM_UNLOCK_REGRANT_LOCK| |
| 190 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 189 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
| @@ -349,14 +348,9 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, | |||
| 349 | vec, veclen, owner, &status); | 348 | vec, veclen, owner, &status); |
| 350 | if (tmpret >= 0) { | 349 | if (tmpret >= 0) { |
| 351 | // successfully sent and received | 350 | // successfully sent and received |
| 352 | if (status == DLM_CANCELGRANT) | 351 | if (status == DLM_FORWARD) |
| 353 | ret = DLM_NORMAL; | ||
| 354 | else if (status == DLM_FORWARD) { | ||
| 355 | mlog(0, "master was in-progress. retry\n"); | 352 | mlog(0, "master was in-progress. retry\n"); |
| 356 | ret = DLM_FORWARD; | 353 | ret = status; |
| 357 | } else | ||
| 358 | ret = status; | ||
| 359 | lksb->status = status; | ||
| 360 | } else { | 354 | } else { |
| 361 | mlog_errno(tmpret); | 355 | mlog_errno(tmpret); |
| 362 | if (dlm_is_host_down(tmpret)) { | 356 | if (dlm_is_host_down(tmpret)) { |
| @@ -372,7 +366,6 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, | |||
| 372 | /* something bad. this will BUG in ocfs2 */ | 366 | /* something bad. this will BUG in ocfs2 */ |
| 373 | ret = dlm_err_to_dlm_status(tmpret); | 367 | ret = dlm_err_to_dlm_status(tmpret); |
| 374 | } | 368 | } |
| 375 | lksb->status = ret; | ||
| 376 | } | 369 | } |
| 377 | 370 | ||
| 378 | return ret; | 371 | return ret; |
| @@ -483,6 +476,10 @@ int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 483 | 476 | ||
| 484 | /* lock was found on queue */ | 477 | /* lock was found on queue */ |
| 485 | lksb = lock->lksb; | 478 | lksb = lock->lksb; |
| 479 | if (flags & (LKM_VALBLK|LKM_PUT_LVB) && | ||
| 480 | lock->ml.type != LKM_EXMODE) | ||
| 481 | flags &= ~(LKM_VALBLK|LKM_PUT_LVB); | ||
| 482 | |||
| 486 | /* unlockast only called on originating node */ | 483 | /* unlockast only called on originating node */ |
| 487 | if (flags & LKM_PUT_LVB) { | 484 | if (flags & LKM_PUT_LVB) { |
| 488 | lksb->flags |= DLM_LKSB_PUT_LVB; | 485 | lksb->flags |= DLM_LKSB_PUT_LVB; |
| @@ -507,11 +504,8 @@ not_found: | |||
| 507 | "cookie=%u:%llu\n", | 504 | "cookie=%u:%llu\n", |
| 508 | dlm_get_lock_cookie_node(unlock->cookie), | 505 | dlm_get_lock_cookie_node(unlock->cookie), |
| 509 | dlm_get_lock_cookie_seq(unlock->cookie)); | 506 | dlm_get_lock_cookie_seq(unlock->cookie)); |
| 510 | else { | 507 | else |
| 511 | /* send the lksb->status back to the other node */ | ||
| 512 | status = lksb->status; | ||
| 513 | dlm_lock_put(lock); | 508 | dlm_lock_put(lock); |
| 514 | } | ||
| 515 | 509 | ||
| 516 | leave: | 510 | leave: |
| 517 | if (res) | 511 | if (res) |
| @@ -533,26 +527,22 @@ static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm, | |||
| 533 | 527 | ||
| 534 | if (dlm_lock_on_list(&res->blocked, lock)) { | 528 | if (dlm_lock_on_list(&res->blocked, lock)) { |
| 535 | /* cancel this outright */ | 529 | /* cancel this outright */ |
| 536 | lksb->status = DLM_NORMAL; | ||
| 537 | status = DLM_NORMAL; | 530 | status = DLM_NORMAL; |
| 538 | *actions = (DLM_UNLOCK_CALL_AST | | 531 | *actions = (DLM_UNLOCK_CALL_AST | |
| 539 | DLM_UNLOCK_REMOVE_LOCK); | 532 | DLM_UNLOCK_REMOVE_LOCK); |
| 540 | } else if (dlm_lock_on_list(&res->converting, lock)) { | 533 | } else if (dlm_lock_on_list(&res->converting, lock)) { |
| 541 | /* cancel the request, put back on granted */ | 534 | /* cancel the request, put back on granted */ |
| 542 | lksb->status = DLM_NORMAL; | ||
| 543 | status = DLM_NORMAL; | 535 | status = DLM_NORMAL; |
| 544 | *actions = (DLM_UNLOCK_CALL_AST | | 536 | *actions = (DLM_UNLOCK_CALL_AST | |
| 545 | DLM_UNLOCK_REMOVE_LOCK | | 537 | DLM_UNLOCK_REMOVE_LOCK | |
| 546 | DLM_UNLOCK_REGRANT_LOCK | | 538 | DLM_UNLOCK_REGRANT_LOCK | |
| 547 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 539 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
| 548 | } else if (dlm_lock_on_list(&res->granted, lock)) { | 540 | } else if (dlm_lock_on_list(&res->granted, lock)) { |
| 549 | /* too late, already granted. DLM_CANCELGRANT */ | 541 | /* too late, already granted. */ |
| 550 | lksb->status = DLM_CANCELGRANT; | 542 | status = DLM_CANCELGRANT; |
| 551 | status = DLM_NORMAL; | ||
| 552 | *actions = DLM_UNLOCK_CALL_AST; | 543 | *actions = DLM_UNLOCK_CALL_AST; |
| 553 | } else { | 544 | } else { |
| 554 | mlog(ML_ERROR, "lock to cancel is not on any list!\n"); | 545 | mlog(ML_ERROR, "lock to cancel is not on any list!\n"); |
| 555 | lksb->status = DLM_IVLOCKID; | ||
| 556 | status = DLM_IVLOCKID; | 546 | status = DLM_IVLOCKID; |
| 557 | *actions = 0; | 547 | *actions = 0; |
| 558 | } | 548 | } |
| @@ -569,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm, | |||
| 569 | 559 | ||
| 570 | /* unlock request */ | 560 | /* unlock request */ |
| 571 | if (!dlm_lock_on_list(&res->granted, lock)) { | 561 | if (!dlm_lock_on_list(&res->granted, lock)) { |
| 572 | lksb->status = DLM_DENIED; | ||
| 573 | status = DLM_DENIED; | 562 | status = DLM_DENIED; |
| 574 | dlm_error(status); | 563 | dlm_error(status); |
| 575 | *actions = 0; | 564 | *actions = 0; |
| 576 | } else { | 565 | } else { |
| 577 | /* unlock granted lock */ | 566 | /* unlock granted lock */ |
| 578 | lksb->status = DLM_NORMAL; | ||
| 579 | status = DLM_NORMAL; | 567 | status = DLM_NORMAL; |
| 580 | *actions = (DLM_UNLOCK_FREE_LOCK | | 568 | *actions = (DLM_UNLOCK_FREE_LOCK | |
| 581 | DLM_UNLOCK_CALL_AST | | 569 | DLM_UNLOCK_CALL_AST | |
| @@ -632,6 +620,8 @@ retry: | |||
| 632 | 620 | ||
| 633 | spin_lock(&res->spinlock); | 621 | spin_lock(&res->spinlock); |
| 634 | is_master = (res->owner == dlm->node_num); | 622 | is_master = (res->owner == dlm->node_num); |
| 623 | if (flags & LKM_VALBLK && lock->ml.type != LKM_EXMODE) | ||
| 624 | flags &= ~LKM_VALBLK; | ||
| 635 | spin_unlock(&res->spinlock); | 625 | spin_unlock(&res->spinlock); |
| 636 | 626 | ||
| 637 | if (is_master) { | 627 | if (is_master) { |
| @@ -665,7 +655,7 @@ retry: | |||
| 665 | } | 655 | } |
| 666 | 656 | ||
| 667 | if (call_ast) { | 657 | if (call_ast) { |
| 668 | mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status); | 658 | mlog(0, "calling unlockast(%p, %d)\n", data, status); |
| 669 | if (is_master) { | 659 | if (is_master) { |
| 670 | /* it is possible that there is one last bast | 660 | /* it is possible that there is one last bast |
| 671 | * pending. make sure it is flushed, then | 661 | * pending. make sure it is flushed, then |
| @@ -677,9 +667,12 @@ retry: | |||
| 677 | wait_event(dlm->ast_wq, | 667 | wait_event(dlm->ast_wq, |
| 678 | dlm_lock_basts_flushed(dlm, lock)); | 668 | dlm_lock_basts_flushed(dlm, lock)); |
| 679 | } | 669 | } |
| 680 | (*unlockast)(data, lksb->status); | 670 | (*unlockast)(data, status); |
| 681 | } | 671 | } |
| 682 | 672 | ||
| 673 | if (status == DLM_CANCELGRANT) | ||
| 674 | status = DLM_NORMAL; | ||
| 675 | |||
| 683 | if (status == DLM_NORMAL) { | 676 | if (status == DLM_NORMAL) { |
| 684 | mlog(0, "kicking the thread\n"); | 677 | mlog(0, "kicking the thread\n"); |
| 685 | dlm_kick_thread(dlm, res); | 678 | dlm_kick_thread(dlm, res); |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 0d1973ea32b0..1f17a4d08287 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -840,6 +840,12 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | |||
| 840 | 840 | ||
| 841 | mlog(0, "Allocating %u clusters for a new window.\n", | 841 | mlog(0, "Allocating %u clusters for a new window.\n", |
| 842 | ocfs2_local_alloc_window_bits(osb)); | 842 | ocfs2_local_alloc_window_bits(osb)); |
| 843 | |||
| 844 | /* Instruct the allocation code to try the most recently used | ||
| 845 | * cluster group. We'll re-record the group used this pass | ||
| 846 | * below. */ | ||
| 847 | ac->ac_last_group = osb->la_last_gd; | ||
| 848 | |||
| 843 | /* we used the generic suballoc reserve function, but we set | 849 | /* we used the generic suballoc reserve function, but we set |
| 844 | * everything up nicely, so there's no reason why we can't use | 850 | * everything up nicely, so there's no reason why we can't use |
| 845 | * the more specific cluster api to claim bits. */ | 851 | * the more specific cluster api to claim bits. */ |
| @@ -852,6 +858,8 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | |||
| 852 | goto bail; | 858 | goto bail; |
| 853 | } | 859 | } |
| 854 | 860 | ||
| 861 | osb->la_last_gd = ac->ac_last_group; | ||
| 862 | |||
| 855 | la->la_bm_off = cpu_to_le32(cluster_off); | 863 | la->la_bm_off = cpu_to_le32(cluster_off); |
| 856 | alloc->id1.bitmap1.i_total = cpu_to_le32(cluster_count); | 864 | alloc->id1.bitmap1.i_total = cpu_to_le32(cluster_count); |
| 857 | /* just in case... In the future when we find space ourselves, | 865 | /* just in case... In the future when we find space ourselves, |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index cd4a6f253d13..0462a7f4e21b 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
| @@ -197,7 +197,6 @@ struct ocfs2_super | |||
| 197 | struct ocfs2_node_map recovery_map; | 197 | struct ocfs2_node_map recovery_map; |
| 198 | struct ocfs2_node_map umount_map; | 198 | struct ocfs2_node_map umount_map; |
| 199 | 199 | ||
| 200 | u32 num_clusters; | ||
| 201 | u64 root_blkno; | 200 | u64 root_blkno; |
| 202 | u64 system_dir_blkno; | 201 | u64 system_dir_blkno; |
| 203 | u64 bitmap_blkno; | 202 | u64 bitmap_blkno; |
| @@ -237,6 +236,7 @@ struct ocfs2_super | |||
| 237 | 236 | ||
| 238 | enum ocfs2_local_alloc_state local_alloc_state; | 237 | enum ocfs2_local_alloc_state local_alloc_state; |
| 239 | struct buffer_head *local_alloc_bh; | 238 | struct buffer_head *local_alloc_bh; |
| 239 | u64 la_last_gd; | ||
| 240 | 240 | ||
| 241 | /* Next two fields are for local node slot recovery during | 241 | /* Next two fields are for local node slot recovery during |
| 242 | * mount. */ | 242 | * mount. */ |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 195523090c87..9d91e66f51a9 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -70,12 +70,6 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
| 70 | struct buffer_head *group_bh, | 70 | struct buffer_head *group_bh, |
| 71 | u32 bits_wanted, u32 min_bits, | 71 | u32 bits_wanted, u32 min_bits, |
| 72 | u16 *bit_off, u16 *bits_found); | 72 | u16 *bit_off, u16 *bits_found); |
| 73 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | ||
| 74 | u32 bits_wanted, | ||
| 75 | u32 min_bits, | ||
| 76 | u16 *bit_off, | ||
| 77 | unsigned int *num_bits, | ||
| 78 | u64 *bg_blkno); | ||
| 79 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | 73 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, |
| 80 | struct ocfs2_alloc_context *ac, | 74 | struct ocfs2_alloc_context *ac, |
| 81 | u32 bits_wanted, | 75 | u32 bits_wanted, |
| @@ -85,11 +79,6 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 85 | u64 *bg_blkno); | 79 | u64 *bg_blkno); |
| 86 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, | 80 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, |
| 87 | int nr); | 81 | int nr); |
| 88 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | ||
| 89 | struct buffer_head *bg_bh, | ||
| 90 | unsigned int bits_wanted, | ||
| 91 | u16 *bit_off, | ||
| 92 | u16 *bits_found); | ||
| 93 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, | 82 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, |
| 94 | struct inode *alloc_inode, | 83 | struct inode *alloc_inode, |
| 95 | struct ocfs2_group_desc *bg, | 84 | struct ocfs2_group_desc *bg, |
| @@ -143,6 +132,64 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
| 143 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); | 132 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); |
| 144 | } | 133 | } |
| 145 | 134 | ||
| 135 | /* somewhat more expensive than our other checks, so use sparingly. */ | ||
| 136 | static int ocfs2_check_group_descriptor(struct super_block *sb, | ||
| 137 | struct ocfs2_dinode *di, | ||
| 138 | struct ocfs2_group_desc *gd) | ||
| 139 | { | ||
| 140 | unsigned int max_bits; | ||
| 141 | |||
| 142 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | ||
| 143 | OCFS2_RO_ON_INVALID_GROUP_DESC(sb, gd); | ||
| 144 | return -EIO; | ||
| 145 | } | ||
| 146 | |||
| 147 | if (di->i_blkno != gd->bg_parent_dinode) { | ||
| 148 | ocfs2_error(sb, "Group descriptor # %llu has bad parent " | ||
| 149 | "pointer (%llu, expected %llu)", | ||
| 150 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 151 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), | ||
| 152 | (unsigned long long)le64_to_cpu(di->i_blkno)); | ||
| 153 | return -EIO; | ||
| 154 | } | ||
| 155 | |||
| 156 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); | ||
| 157 | if (le16_to_cpu(gd->bg_bits) > max_bits) { | ||
| 158 | ocfs2_error(sb, "Group descriptor # %llu has bit count of %u", | ||
| 159 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 160 | le16_to_cpu(gd->bg_bits)); | ||
| 161 | return -EIO; | ||
| 162 | } | ||
| 163 | |||
| 164 | if (le16_to_cpu(gd->bg_chain) >= | ||
| 165 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { | ||
| 166 | ocfs2_error(sb, "Group descriptor # %llu has bad chain %u", | ||
| 167 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 168 | le16_to_cpu(gd->bg_chain)); | ||
| 169 | return -EIO; | ||
| 170 | } | ||
| 171 | |||
| 172 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { | ||
| 173 | ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " | ||
| 174 | "claims that %u are free", | ||
| 175 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 176 | le16_to_cpu(gd->bg_bits), | ||
| 177 | le16_to_cpu(gd->bg_free_bits_count)); | ||
| 178 | return -EIO; | ||
| 179 | } | ||
| 180 | |||
| 181 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { | ||
| 182 | ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " | ||
| 183 | "max bitmap bits of %u", | ||
| 184 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 185 | le16_to_cpu(gd->bg_bits), | ||
| 186 | 8 * le16_to_cpu(gd->bg_size)); | ||
| 187 | return -EIO; | ||
| 188 | } | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 146 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, | 193 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, |
| 147 | struct inode *alloc_inode, | 194 | struct inode *alloc_inode, |
| 148 | struct buffer_head *bg_bh, | 195 | struct buffer_head *bg_bh, |
| @@ -663,6 +710,7 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, | |||
| 663 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | 710 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, |
| 664 | struct buffer_head *bg_bh, | 711 | struct buffer_head *bg_bh, |
| 665 | unsigned int bits_wanted, | 712 | unsigned int bits_wanted, |
| 713 | unsigned int total_bits, | ||
| 666 | u16 *bit_off, | 714 | u16 *bit_off, |
| 667 | u16 *bits_found) | 715 | u16 *bits_found) |
| 668 | { | 716 | { |
| @@ -679,10 +727,8 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | |||
| 679 | found = start = best_offset = best_size = 0; | 727 | found = start = best_offset = best_size = 0; |
| 680 | bitmap = bg->bg_bitmap; | 728 | bitmap = bg->bg_bitmap; |
| 681 | 729 | ||
| 682 | while((offset = ocfs2_find_next_zero_bit(bitmap, | 730 | while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) { |
| 683 | le16_to_cpu(bg->bg_bits), | 731 | if (offset == total_bits) |
| 684 | start)) != -1) { | ||
| 685 | if (offset == le16_to_cpu(bg->bg_bits)) | ||
| 686 | break; | 732 | break; |
| 687 | 733 | ||
| 688 | if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { | 734 | if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { |
| @@ -911,14 +957,35 @@ static int ocfs2_cluster_group_search(struct inode *inode, | |||
| 911 | { | 957 | { |
| 912 | int search = -ENOSPC; | 958 | int search = -ENOSPC; |
| 913 | int ret; | 959 | int ret; |
| 914 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data; | 960 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *) group_bh->b_data; |
| 915 | u16 tmp_off, tmp_found; | 961 | u16 tmp_off, tmp_found; |
| 962 | unsigned int max_bits, gd_cluster_off; | ||
| 916 | 963 | ||
| 917 | BUG_ON(!ocfs2_is_cluster_bitmap(inode)); | 964 | BUG_ON(!ocfs2_is_cluster_bitmap(inode)); |
| 918 | 965 | ||
| 919 | if (bg->bg_free_bits_count) { | 966 | if (gd->bg_free_bits_count) { |
| 967 | max_bits = le16_to_cpu(gd->bg_bits); | ||
| 968 | |||
| 969 | /* Tail groups in cluster bitmaps which aren't cpg | ||
| 970 | * aligned are prone to partial extention by a failed | ||
| 971 | * fs resize. If the file system resize never got to | ||
| 972 | * update the dinode cluster count, then we don't want | ||
| 973 | * to trust any clusters past it, regardless of what | ||
| 974 | * the group descriptor says. */ | ||
| 975 | gd_cluster_off = ocfs2_blocks_to_clusters(inode->i_sb, | ||
| 976 | le64_to_cpu(gd->bg_blkno)); | ||
| 977 | if ((gd_cluster_off + max_bits) > | ||
| 978 | OCFS2_I(inode)->ip_clusters) { | ||
| 979 | max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off; | ||
| 980 | mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n", | ||
| 981 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
| 982 | le16_to_cpu(gd->bg_bits), | ||
| 983 | OCFS2_I(inode)->ip_clusters, max_bits); | ||
| 984 | } | ||
| 985 | |||
| 920 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), | 986 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), |
| 921 | group_bh, bits_wanted, | 987 | group_bh, bits_wanted, |
| 988 | max_bits, | ||
| 922 | &tmp_off, &tmp_found); | 989 | &tmp_off, &tmp_found); |
| 923 | if (ret) | 990 | if (ret) |
| 924 | return ret; | 991 | return ret; |
| @@ -951,17 +1018,109 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
| 951 | if (bg->bg_free_bits_count) | 1018 | if (bg->bg_free_bits_count) |
| 952 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), | 1019 | ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), |
| 953 | group_bh, bits_wanted, | 1020 | group_bh, bits_wanted, |
| 1021 | le16_to_cpu(bg->bg_bits), | ||
| 954 | bit_off, bits_found); | 1022 | bit_off, bits_found); |
| 955 | 1023 | ||
| 956 | return ret; | 1024 | return ret; |
| 957 | } | 1025 | } |
| 958 | 1026 | ||
| 1027 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, | ||
| 1028 | struct ocfs2_journal_handle *handle, | ||
| 1029 | struct buffer_head *di_bh, | ||
| 1030 | u32 num_bits, | ||
| 1031 | u16 chain) | ||
| 1032 | { | ||
| 1033 | int ret; | ||
| 1034 | u32 tmp_used; | ||
| 1035 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; | ||
| 1036 | struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &di->id2.i_chain; | ||
| 1037 | |||
| 1038 | ret = ocfs2_journal_access(handle, inode, di_bh, | ||
| 1039 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 1040 | if (ret < 0) { | ||
| 1041 | mlog_errno(ret); | ||
| 1042 | goto out; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | tmp_used = le32_to_cpu(di->id1.bitmap1.i_used); | ||
| 1046 | di->id1.bitmap1.i_used = cpu_to_le32(num_bits + tmp_used); | ||
| 1047 | le32_add_cpu(&cl->cl_recs[chain].c_free, -num_bits); | ||
| 1048 | |||
| 1049 | ret = ocfs2_journal_dirty(handle, di_bh); | ||
| 1050 | if (ret < 0) | ||
| 1051 | mlog_errno(ret); | ||
| 1052 | |||
| 1053 | out: | ||
| 1054 | return ret; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | ||
| 1058 | u32 bits_wanted, | ||
| 1059 | u32 min_bits, | ||
| 1060 | u16 *bit_off, | ||
| 1061 | unsigned int *num_bits, | ||
| 1062 | u64 gd_blkno, | ||
| 1063 | u16 *bits_left) | ||
| 1064 | { | ||
| 1065 | int ret; | ||
| 1066 | u16 found; | ||
| 1067 | struct buffer_head *group_bh = NULL; | ||
| 1068 | struct ocfs2_group_desc *gd; | ||
| 1069 | struct inode *alloc_inode = ac->ac_inode; | ||
| 1070 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
| 1071 | |||
| 1072 | ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, | ||
| 1073 | &group_bh, OCFS2_BH_CACHED, alloc_inode); | ||
| 1074 | if (ret < 0) { | ||
| 1075 | mlog_errno(ret); | ||
| 1076 | return ret; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | gd = (struct ocfs2_group_desc *) group_bh->b_data; | ||
| 1080 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | ||
| 1081 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd); | ||
| 1082 | ret = -EIO; | ||
| 1083 | goto out; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, | ||
| 1087 | bit_off, &found); | ||
| 1088 | if (ret < 0) { | ||
| 1089 | if (ret != -ENOSPC) | ||
| 1090 | mlog_errno(ret); | ||
| 1091 | goto out; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | *num_bits = found; | ||
| 1095 | |||
| 1096 | ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, | ||
| 1097 | *num_bits, | ||
| 1098 | le16_to_cpu(gd->bg_chain)); | ||
| 1099 | if (ret < 0) { | ||
| 1100 | mlog_errno(ret); | ||
| 1101 | goto out; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh, | ||
| 1105 | *bit_off, *num_bits); | ||
| 1106 | if (ret < 0) | ||
| 1107 | mlog_errno(ret); | ||
| 1108 | |||
| 1109 | *bits_left = le16_to_cpu(gd->bg_free_bits_count); | ||
| 1110 | |||
| 1111 | out: | ||
| 1112 | brelse(group_bh); | ||
| 1113 | |||
| 1114 | return ret; | ||
| 1115 | } | ||
| 1116 | |||
| 959 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | 1117 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, |
| 960 | u32 bits_wanted, | 1118 | u32 bits_wanted, |
| 961 | u32 min_bits, | 1119 | u32 min_bits, |
| 962 | u16 *bit_off, | 1120 | u16 *bit_off, |
| 963 | unsigned int *num_bits, | 1121 | unsigned int *num_bits, |
| 964 | u64 *bg_blkno) | 1122 | u64 *bg_blkno, |
| 1123 | u16 *bits_left) | ||
| 965 | { | 1124 | { |
| 966 | int status; | 1125 | int status; |
| 967 | u16 chain, tmp_bits; | 1126 | u16 chain, tmp_bits; |
| @@ -988,9 +1147,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 988 | goto bail; | 1147 | goto bail; |
| 989 | } | 1148 | } |
| 990 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1149 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
| 991 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 1150 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); |
| 992 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | 1151 | if (status) { |
| 993 | status = -EIO; | 1152 | mlog_errno(status); |
| 994 | goto bail; | 1153 | goto bail; |
| 995 | } | 1154 | } |
| 996 | 1155 | ||
| @@ -1018,9 +1177,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1018 | goto bail; | 1177 | goto bail; |
| 1019 | } | 1178 | } |
| 1020 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1179 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
| 1021 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 1180 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); |
| 1022 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | 1181 | if (status) { |
| 1023 | status = -EIO; | 1182 | mlog_errno(status); |
| 1024 | goto bail; | 1183 | goto bail; |
| 1025 | } | 1184 | } |
| 1026 | } | 1185 | } |
| @@ -1099,6 +1258,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1099 | (unsigned long long)fe->i_blkno); | 1258 | (unsigned long long)fe->i_blkno); |
| 1100 | 1259 | ||
| 1101 | *bg_blkno = le64_to_cpu(bg->bg_blkno); | 1260 | *bg_blkno = le64_to_cpu(bg->bg_blkno); |
| 1261 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); | ||
| 1102 | bail: | 1262 | bail: |
| 1103 | if (group_bh) | 1263 | if (group_bh) |
| 1104 | brelse(group_bh); | 1264 | brelse(group_bh); |
| @@ -1120,6 +1280,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 1120 | { | 1280 | { |
| 1121 | int status; | 1281 | int status; |
| 1122 | u16 victim, i; | 1282 | u16 victim, i; |
| 1283 | u16 bits_left = 0; | ||
| 1284 | u64 hint_blkno = ac->ac_last_group; | ||
| 1123 | struct ocfs2_chain_list *cl; | 1285 | struct ocfs2_chain_list *cl; |
| 1124 | struct ocfs2_dinode *fe; | 1286 | struct ocfs2_dinode *fe; |
| 1125 | 1287 | ||
| @@ -1146,6 +1308,28 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 1146 | goto bail; | 1308 | goto bail; |
| 1147 | } | 1309 | } |
| 1148 | 1310 | ||
| 1311 | if (hint_blkno) { | ||
| 1312 | /* Attempt to short-circuit the usual search mechanism | ||
| 1313 | * by jumping straight to the most recently used | ||
| 1314 | * allocation group. This helps us mantain some | ||
| 1315 | * contiguousness across allocations. */ | ||
| 1316 | status = ocfs2_search_one_group(ac, bits_wanted, min_bits, | ||
| 1317 | bit_off, num_bits, | ||
| 1318 | hint_blkno, &bits_left); | ||
| 1319 | if (!status) { | ||
| 1320 | /* Be careful to update *bg_blkno here as the | ||
| 1321 | * caller is expecting it to be filled in, and | ||
| 1322 | * ocfs2_search_one_group() won't do that for | ||
| 1323 | * us. */ | ||
| 1324 | *bg_blkno = hint_blkno; | ||
| 1325 | goto set_hint; | ||
| 1326 | } | ||
| 1327 | if (status < 0 && status != -ENOSPC) { | ||
| 1328 | mlog_errno(status); | ||
| 1329 | goto bail; | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | |||
| 1149 | cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; | 1333 | cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; |
| 1150 | 1334 | ||
| 1151 | victim = ocfs2_find_victim_chain(cl); | 1335 | victim = ocfs2_find_victim_chain(cl); |
| @@ -1153,9 +1337,9 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 1153 | ac->ac_allow_chain_relink = 1; | 1337 | ac->ac_allow_chain_relink = 1; |
| 1154 | 1338 | ||
| 1155 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, | 1339 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, |
| 1156 | num_bits, bg_blkno); | 1340 | num_bits, bg_blkno, &bits_left); |
| 1157 | if (!status) | 1341 | if (!status) |
| 1158 | goto bail; | 1342 | goto set_hint; |
| 1159 | if (status < 0 && status != -ENOSPC) { | 1343 | if (status < 0 && status != -ENOSPC) { |
| 1160 | mlog_errno(status); | 1344 | mlog_errno(status); |
| 1161 | goto bail; | 1345 | goto bail; |
| @@ -1177,8 +1361,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 1177 | 1361 | ||
| 1178 | ac->ac_chain = i; | 1362 | ac->ac_chain = i; |
| 1179 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, | 1363 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, |
| 1180 | bit_off, num_bits, | 1364 | bit_off, num_bits, bg_blkno, |
| 1181 | bg_blkno); | 1365 | &bits_left); |
| 1182 | if (!status) | 1366 | if (!status) |
| 1183 | break; | 1367 | break; |
| 1184 | if (status < 0 && status != -ENOSPC) { | 1368 | if (status < 0 && status != -ENOSPC) { |
| @@ -1186,8 +1370,19 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
| 1186 | goto bail; | 1370 | goto bail; |
| 1187 | } | 1371 | } |
| 1188 | } | 1372 | } |
| 1189 | bail: | ||
| 1190 | 1373 | ||
| 1374 | set_hint: | ||
| 1375 | if (status != -ENOSPC) { | ||
| 1376 | /* If the next search of this group is not likely to | ||
| 1377 | * yield a suitable extent, then we reset the last | ||
| 1378 | * group hint so as to not waste a disk read */ | ||
| 1379 | if (bits_left < min_bits) | ||
| 1380 | ac->ac_last_group = 0; | ||
| 1381 | else | ||
| 1382 | ac->ac_last_group = *bg_blkno; | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | bail: | ||
| 1191 | mlog_exit(status); | 1386 | mlog_exit(status); |
| 1192 | return status; | 1387 | return status; |
| 1193 | } | 1388 | } |
| @@ -1341,7 +1536,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
| 1341 | { | 1536 | { |
| 1342 | int status; | 1537 | int status; |
| 1343 | unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given; | 1538 | unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given; |
| 1344 | u64 bg_blkno; | 1539 | u64 bg_blkno = 0; |
| 1345 | u16 bg_bit_off; | 1540 | u16 bg_bit_off; |
| 1346 | 1541 | ||
| 1347 | mlog_entry_void(); | 1542 | mlog_entry_void(); |
| @@ -1494,9 +1689,9 @@ static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, | |||
| 1494 | } | 1689 | } |
| 1495 | 1690 | ||
| 1496 | group = (struct ocfs2_group_desc *) group_bh->b_data; | 1691 | group = (struct ocfs2_group_desc *) group_bh->b_data; |
| 1497 | if (!OCFS2_IS_VALID_GROUP_DESC(group)) { | 1692 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group); |
| 1498 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, group); | 1693 | if (status) { |
| 1499 | status = -EIO; | 1694 | mlog_errno(status); |
| 1500 | goto bail; | 1695 | goto bail; |
| 1501 | } | 1696 | } |
| 1502 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); | 1697 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); |
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index a76c82a7ceac..c787838d1052 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
| @@ -49,6 +49,8 @@ struct ocfs2_alloc_context { | |||
| 49 | u16 ac_chain; | 49 | u16 ac_chain; |
| 50 | int ac_allow_chain_relink; | 50 | int ac_allow_chain_relink; |
| 51 | group_search_t *ac_group_search; | 51 | group_search_t *ac_group_search; |
| 52 | |||
| 53 | u64 ac_last_group; | ||
| 52 | }; | 54 | }; |
| 53 | 55 | ||
| 54 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac); | 56 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 382706a67ffd..d17e33e66a1e 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -1442,8 +1442,13 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1442 | 1442 | ||
| 1443 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; | 1443 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; |
| 1444 | 1444 | ||
| 1445 | /* We don't have a cluster lock on the bitmap here because | ||
| 1446 | * we're only interested in static information and the extra | ||
| 1447 | * complexity at mount time isn't worht it. Don't pass the | ||
| 1448 | * inode in to the read function though as we don't want it to | ||
| 1449 | * be put in the cache. */ | ||
| 1445 | status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0, | 1450 | status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0, |
| 1446 | inode); | 1451 | NULL); |
| 1447 | iput(inode); | 1452 | iput(inode); |
| 1448 | if (status < 0) { | 1453 | if (status < 0) { |
| 1449 | mlog_errno(status); | 1454 | mlog_errno(status); |
| @@ -1452,7 +1457,6 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1452 | 1457 | ||
| 1453 | di = (struct ocfs2_dinode *) bitmap_bh->b_data; | 1458 | di = (struct ocfs2_dinode *) bitmap_bh->b_data; |
| 1454 | osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg); | 1459 | osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg); |
| 1455 | osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total); | ||
| 1456 | brelse(bitmap_bh); | 1460 | brelse(bitmap_bh); |
| 1457 | mlog(0, "cluster bitmap inode: %llu, clusters per group: %u\n", | 1461 | mlog(0, "cluster bitmap inode: %llu, clusters per group: %u\n", |
| 1458 | (unsigned long long)osb->bitmap_blkno, osb->bitmap_cpg); | 1462 | (unsigned long long)osb->bitmap_blkno, osb->bitmap_cpg); |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 4df822c881b6..7de172efa084 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -115,6 +115,13 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
| 115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); | 115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); |
| 116 | if (!ei) | 116 | if (!ei) |
| 117 | return NULL; | 117 | return NULL; |
| 118 | |||
| 119 | ei->i_unique = 0; | ||
| 120 | ei->i_lenExtents = 0; | ||
| 121 | ei->i_next_alloc_block = 0; | ||
| 122 | ei->i_next_alloc_goal = 0; | ||
| 123 | ei->i_strat4096 = 0; | ||
| 124 | |||
| 118 | return &ei->vfs_inode; | 125 | return &ei->vfs_inode; |
| 119 | } | 126 | } |
| 120 | 127 | ||
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index eef6763f3a67..d2bbcd882a69 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
| @@ -1835,40 +1835,47 @@ xfs_alloc_fix_freelist( | |||
| 1835 | &agbp))) | 1835 | &agbp))) |
| 1836 | return error; | 1836 | return error; |
| 1837 | if (!pag->pagf_init) { | 1837 | if (!pag->pagf_init) { |
| 1838 | ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); | ||
| 1839 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1838 | args->agbp = NULL; | 1840 | args->agbp = NULL; |
| 1839 | return 0; | 1841 | return 0; |
| 1840 | } | 1842 | } |
| 1841 | } else | 1843 | } else |
| 1842 | agbp = NULL; | 1844 | agbp = NULL; |
| 1843 | 1845 | ||
| 1844 | /* If this is a metadata preferred pag and we are user data | 1846 | /* |
| 1847 | * If this is a metadata preferred pag and we are user data | ||
| 1845 | * then try somewhere else if we are not being asked to | 1848 | * then try somewhere else if we are not being asked to |
| 1846 | * try harder at this point | 1849 | * try harder at this point |
| 1847 | */ | 1850 | */ |
| 1848 | if (pag->pagf_metadata && args->userdata && flags) { | 1851 | if (pag->pagf_metadata && args->userdata && |
| 1852 | (flags & XFS_ALLOC_FLAG_TRYLOCK)) { | ||
| 1853 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1849 | args->agbp = NULL; | 1854 | args->agbp = NULL; |
| 1850 | return 0; | 1855 | return 0; |
| 1851 | } | 1856 | } |
| 1852 | 1857 | ||
| 1853 | need = XFS_MIN_FREELIST_PAG(pag, mp); | 1858 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { |
| 1854 | delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; | 1859 | need = XFS_MIN_FREELIST_PAG(pag, mp); |
| 1855 | /* | 1860 | delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; |
| 1856 | * If it looks like there isn't a long enough extent, or enough | 1861 | /* |
| 1857 | * total blocks, reject it. | 1862 | * If it looks like there isn't a long enough extent, or enough |
| 1858 | */ | 1863 | * total blocks, reject it. |
| 1859 | longest = (pag->pagf_longest > delta) ? | 1864 | */ |
| 1860 | (pag->pagf_longest - delta) : | 1865 | longest = (pag->pagf_longest > delta) ? |
| 1861 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); | 1866 | (pag->pagf_longest - delta) : |
| 1862 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1867 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); |
| 1863 | (!(flags & XFS_ALLOC_FLAG_FREEING) && | 1868 | if ((args->minlen + args->alignment + args->minalignslop - 1) > |
| 1864 | (int)(pag->pagf_freeblks + pag->pagf_flcount - | 1869 | longest || |
| 1865 | need - args->total) < | 1870 | ((int)(pag->pagf_freeblks + pag->pagf_flcount - |
| 1866 | (int)args->minleft)) { | 1871 | need - args->total) < (int)args->minleft)) { |
| 1867 | if (agbp) | 1872 | if (agbp) |
| 1868 | xfs_trans_brelse(tp, agbp); | 1873 | xfs_trans_brelse(tp, agbp); |
| 1869 | args->agbp = NULL; | 1874 | args->agbp = NULL; |
| 1870 | return 0; | 1875 | return 0; |
| 1876 | } | ||
| 1871 | } | 1877 | } |
| 1878 | |||
| 1872 | /* | 1879 | /* |
| 1873 | * Get the a.g. freespace buffer. | 1880 | * Get the a.g. freespace buffer. |
| 1874 | * Can fail if we're not blocking on locks, and it's held. | 1881 | * Can fail if we're not blocking on locks, and it's held. |
| @@ -1878,6 +1885,8 @@ xfs_alloc_fix_freelist( | |||
| 1878 | &agbp))) | 1885 | &agbp))) |
| 1879 | return error; | 1886 | return error; |
| 1880 | if (agbp == NULL) { | 1887 | if (agbp == NULL) { |
| 1888 | ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); | ||
| 1889 | ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); | ||
| 1881 | args->agbp = NULL; | 1890 | args->agbp = NULL; |
| 1882 | return 0; | 1891 | return 0; |
| 1883 | } | 1892 | } |
| @@ -1887,22 +1896,24 @@ xfs_alloc_fix_freelist( | |||
| 1887 | */ | 1896 | */ |
| 1888 | agf = XFS_BUF_TO_AGF(agbp); | 1897 | agf = XFS_BUF_TO_AGF(agbp); |
| 1889 | need = XFS_MIN_FREELIST(agf, mp); | 1898 | need = XFS_MIN_FREELIST(agf, mp); |
| 1890 | delta = need > be32_to_cpu(agf->agf_flcount) ? | ||
| 1891 | (need - be32_to_cpu(agf->agf_flcount)) : 0; | ||
| 1892 | /* | 1899 | /* |
| 1893 | * If there isn't enough total or single-extent, reject it. | 1900 | * If there isn't enough total or single-extent, reject it. |
| 1894 | */ | 1901 | */ |
| 1895 | longest = be32_to_cpu(agf->agf_longest); | 1902 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { |
| 1896 | longest = (longest > delta) ? (longest - delta) : | 1903 | delta = need > be32_to_cpu(agf->agf_flcount) ? |
| 1897 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); | 1904 | (need - be32_to_cpu(agf->agf_flcount)) : 0; |
| 1898 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1905 | longest = be32_to_cpu(agf->agf_longest); |
| 1899 | (!(flags & XFS_ALLOC_FLAG_FREEING) && | 1906 | longest = (longest > delta) ? (longest - delta) : |
| 1900 | (int)(be32_to_cpu(agf->agf_freeblks) + | 1907 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); |
| 1901 | be32_to_cpu(agf->agf_flcount) - need - args->total) < | 1908 | if ((args->minlen + args->alignment + args->minalignslop - 1) > |
| 1902 | (int)args->minleft)) { | 1909 | longest || |
| 1903 | xfs_trans_brelse(tp, agbp); | 1910 | ((int)(be32_to_cpu(agf->agf_freeblks) + |
| 1904 | args->agbp = NULL; | 1911 | be32_to_cpu(agf->agf_flcount) - need - args->total) < |
| 1905 | return 0; | 1912 | (int)args->minleft)) { |
| 1913 | xfs_trans_brelse(tp, agbp); | ||
| 1914 | args->agbp = NULL; | ||
| 1915 | return 0; | ||
| 1916 | } | ||
| 1906 | } | 1917 | } |
| 1907 | /* | 1918 | /* |
| 1908 | * Make the freelist shorter if it's too long. | 1919 | * Make the freelist shorter if it's too long. |
| @@ -1950,12 +1961,11 @@ xfs_alloc_fix_freelist( | |||
| 1950 | * on a completely full ag. | 1961 | * on a completely full ag. |
| 1951 | */ | 1962 | */ |
| 1952 | if (targs.agbno == NULLAGBLOCK) { | 1963 | if (targs.agbno == NULLAGBLOCK) { |
| 1953 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { | 1964 | if (flags & XFS_ALLOC_FLAG_FREEING) |
| 1954 | xfs_trans_brelse(tp, agflbp); | 1965 | break; |
| 1955 | args->agbp = NULL; | 1966 | xfs_trans_brelse(tp, agflbp); |
| 1956 | return 0; | 1967 | args->agbp = NULL; |
| 1957 | } | 1968 | return 0; |
| 1958 | break; | ||
| 1959 | } | 1969 | } |
| 1960 | /* | 1970 | /* |
| 1961 | * Put each allocated block on the list. | 1971 | * Put each allocated block on the list. |
| @@ -2442,31 +2452,26 @@ xfs_free_extent( | |||
| 2442 | xfs_fsblock_t bno, /* starting block number of extent */ | 2452 | xfs_fsblock_t bno, /* starting block number of extent */ |
| 2443 | xfs_extlen_t len) /* length of extent */ | 2453 | xfs_extlen_t len) /* length of extent */ |
| 2444 | { | 2454 | { |
| 2445 | #ifdef DEBUG | 2455 | xfs_alloc_arg_t args; |
| 2446 | xfs_agf_t *agf; /* a.g. freespace header */ | ||
| 2447 | #endif | ||
| 2448 | xfs_alloc_arg_t args; /* allocation argument structure */ | ||
| 2449 | int error; | 2456 | int error; |
| 2450 | 2457 | ||
| 2451 | ASSERT(len != 0); | 2458 | ASSERT(len != 0); |
| 2459 | memset(&args, 0, sizeof(xfs_alloc_arg_t)); | ||
| 2452 | args.tp = tp; | 2460 | args.tp = tp; |
| 2453 | args.mp = tp->t_mountp; | 2461 | args.mp = tp->t_mountp; |
| 2454 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); | 2462 | args.agno = XFS_FSB_TO_AGNO(args.mp, bno); |
| 2455 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); | 2463 | ASSERT(args.agno < args.mp->m_sb.sb_agcount); |
| 2456 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); | 2464 | args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); |
| 2457 | args.alignment = 1; | ||
| 2458 | args.minlen = args.minleft = args.minalignslop = 0; | ||
| 2459 | down_read(&args.mp->m_peraglock); | 2465 | down_read(&args.mp->m_peraglock); |
| 2460 | args.pag = &args.mp->m_perag[args.agno]; | 2466 | args.pag = &args.mp->m_perag[args.agno]; |
| 2461 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) | 2467 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) |
| 2462 | goto error0; | 2468 | goto error0; |
| 2463 | #ifdef DEBUG | 2469 | #ifdef DEBUG |
| 2464 | ASSERT(args.agbp != NULL); | 2470 | ASSERT(args.agbp != NULL); |
| 2465 | agf = XFS_BUF_TO_AGF(args.agbp); | 2471 | ASSERT((args.agbno + len) <= |
| 2466 | ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length)); | 2472 | be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); |
| 2467 | #endif | 2473 | #endif |
| 2468 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, | 2474 | error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); |
| 2469 | len, 0); | ||
| 2470 | error0: | 2475 | error0: |
| 2471 | up_read(&args.mp->m_peraglock); | 2476 | up_read(&args.mp->m_peraglock); |
| 2472 | return error; | 2477 | return error; |
