diff options
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; |