diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/move_extents.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index ebaff625fc28..390354a4ecb4 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -555,3 +555,80 @@ static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh, | |||
555 | 555 | ||
556 | mlog(0, "found phys_cpos: %u to fit the wanted moving.\n", *phys_cpos); | 556 | mlog(0, "found phys_cpos: %u to fit the wanted moving.\n", *phys_cpos); |
557 | } | 557 | } |
558 | |||
559 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, | ||
560 | handle_t *handle, | ||
561 | struct buffer_head *di_bh, | ||
562 | u32 num_bits, | ||
563 | u16 chain) | ||
564 | { | ||
565 | int ret; | ||
566 | u32 tmp_used; | ||
567 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; | ||
568 | struct ocfs2_chain_list *cl = | ||
569 | (struct ocfs2_chain_list *) &di->id2.i_chain; | ||
570 | |||
571 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, | ||
572 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
573 | if (ret < 0) { | ||
574 | mlog_errno(ret); | ||
575 | goto out; | ||
576 | } | ||
577 | |||
578 | tmp_used = le32_to_cpu(di->id1.bitmap1.i_used); | ||
579 | di->id1.bitmap1.i_used = cpu_to_le32(num_bits + tmp_used); | ||
580 | le32_add_cpu(&cl->cl_recs[chain].c_free, -num_bits); | ||
581 | ocfs2_journal_dirty(handle, di_bh); | ||
582 | |||
583 | out: | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static inline int ocfs2_block_group_set_bits(handle_t *handle, | ||
588 | struct inode *alloc_inode, | ||
589 | struct ocfs2_group_desc *bg, | ||
590 | struct buffer_head *group_bh, | ||
591 | unsigned int bit_off, | ||
592 | unsigned int num_bits) | ||
593 | { | ||
594 | int status; | ||
595 | void *bitmap = bg->bg_bitmap; | ||
596 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; | ||
597 | |||
598 | /* All callers get the descriptor via | ||
599 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ | ||
600 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); | ||
601 | BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits); | ||
602 | |||
603 | mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off, | ||
604 | num_bits); | ||
605 | |||
606 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | ||
607 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; | ||
608 | |||
609 | status = ocfs2_journal_access_gd(handle, | ||
610 | INODE_CACHE(alloc_inode), | ||
611 | group_bh, | ||
612 | journal_type); | ||
613 | if (status < 0) { | ||
614 | mlog_errno(status); | ||
615 | goto bail; | ||
616 | } | ||
617 | |||
618 | le16_add_cpu(&bg->bg_free_bits_count, -num_bits); | ||
619 | if (le16_to_cpu(bg->bg_free_bits_count) > le16_to_cpu(bg->bg_bits)) { | ||
620 | ocfs2_error(alloc_inode->i_sb, "Group descriptor # %llu has bit" | ||
621 | " count %u but claims %u are freed. num_bits %d", | ||
622 | (unsigned long long)le64_to_cpu(bg->bg_blkno), | ||
623 | le16_to_cpu(bg->bg_bits), | ||
624 | le16_to_cpu(bg->bg_free_bits_count), num_bits); | ||
625 | return -EROFS; | ||
626 | } | ||
627 | while (num_bits--) | ||
628 | ocfs2_set_bit(bit_off++, bitmap); | ||
629 | |||
630 | ocfs2_journal_dirty(handle, group_bh); | ||
631 | |||
632 | bail: | ||
633 | return status; | ||
634 | } | ||