/* * Check whether there are new backup superblocks exist * in the last group. If there are some, mark them or clear * them in the bitmap. * * Return how many backups we find in the last group. */ static u16 ocfs2_calc_new_backup_super(struct inode *inode, struct ocfs2_group_desc *gd, int new_clusters, u32 first_new_cluster, u16 cl_cpg, int set) { int i; u16 backups = 0; u32 cluster; u64 blkno, gd_blkno, lgd_blkno = le64_to_cpu(gd->bg_blkno); for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) { blkno = ocfs2_backup_super_blkno(inode->i_sb, i); cluster = ocfs2_blocks_to_clusters(inode->i_sb, blkno); gd_blkno = ocfs2_which_cluster_group(inode, cluster); if (gd_blkno < lgd_blkno) continue; else if (gd_blkno > lgd_blkno) break; if (set) ocfs2_set_bit(cluster % cl_cpg, (unsigned long *)gd->bg_bitmap); else ocfs2_clear_bit(cluster % cl_cpg, (unsigned long *)gd->bg_bitmap); backups++; } mlog_exit_void(); return backups; }
/* * Like ocfs2_hamming_encode(), this can handle hunks. nr is the bit * offset of the current hunk. If bit to be fixed is not part of the * current hunk, this does nothing. * * If you only have one hunk, use ocfs2_hamming_fix_block(). */ void ocfs2_hamming_fix(void *data, unsigned int d, unsigned int nr, unsigned int fix) { unsigned int i, b; BUG_ON(!d); /* * If the bit to fix has an hweight of 1, it's a parity bit. One * busted parity bit is its own error. Nothing to do here. */ if (hweight32(fix) == 1) return; /* * nr + d is the bit right past the data hunk we're looking at. * If fix after that, nothing to do */ if (fix >= calc_code_bit(nr + d, NULL)) return; /* * nr is the offset in the data hunk we're starting at. Let's * start b at the offset in the code buffer. See hamming_encode() * for a more detailed description of 'b'. */ b = calc_code_bit(nr, NULL); /* If the fix is before this hunk, nothing to do */ if (fix < b) return; for (i = 0; i < d; i++, b++) { /* Skip past parity bits */ while (hweight32(b) == 1) b++; /* * i is the offset in this data hunk. * nr + i is the offset in the total data buffer. * b is the offset in the total code buffer. * * Thus, when b == fix, bit i in the current hunk needs * fixing. */ if (b == fix) { if (ocfs2_test_bit(i, data)) ocfs2_clear_bit(i, data); else ocfs2_set_bit(i, data); break; } } }
static inline int ocfs2_block_group_clear_bits(handle_t *handle, struct inode *alloc_inode, struct ocfs2_group_desc *bg, struct buffer_head *group_bh, unsigned int bit_off, unsigned int num_bits) { int status; unsigned int tmp; int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; struct ocfs2_group_desc *undo_bg = NULL; mlog_entry_void(); if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); status = -EIO; goto bail; } mlog(0, "off = %u, num = %u\n", bit_off, num_bits); if (ocfs2_is_cluster_bitmap(alloc_inode)) journal_type = OCFS2_JOURNAL_ACCESS_UNDO; status = ocfs2_journal_access(handle, alloc_inode, group_bh, journal_type); if (status < 0) { mlog_errno(status); goto bail; } if (ocfs2_is_cluster_bitmap(alloc_inode)) undo_bg = (struct ocfs2_group_desc *) bh2jh(group_bh)->b_committed_data; tmp = num_bits; while(tmp--) { ocfs2_clear_bit((bit_off + tmp), (unsigned long *) bg->bg_bitmap); if (ocfs2_is_cluster_bitmap(alloc_inode)) ocfs2_set_bit(bit_off + tmp, (unsigned long *) undo_bg->bg_bitmap); } le16_add_cpu(&bg->bg_free_bits_count, num_bits); status = ocfs2_journal_dirty(handle, group_bh); if (status < 0) mlog_errno(status); bail: return status; }
int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, handle_t *handle, struct ocfs2_alloc_context *ac, u32 bit_off, u32 num_bits) { int status, start; u32 clear_bits; struct inode *local_alloc_inode; void *bitmap; struct ocfs2_dinode *alloc; struct ocfs2_local_alloc *la; BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); local_alloc_inode = ac->ac_inode; alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; la = OCFS2_LOCAL_ALLOC(alloc); bitmap = la->la_bitmap; start = bit_off - le32_to_cpu(la->la_bm_off); clear_bits = num_bits; status = ocfs2_journal_access_di(handle, INODE_CACHE(local_alloc_inode), osb->local_alloc_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto bail; } while (clear_bits--) ocfs2_clear_bit(start++, bitmap); le32_add_cpu(&alloc->id1.bitmap1.i_used, -num_bits); ocfs2_journal_dirty(handle, osb->local_alloc_bh); bail: return status; }
/* * Check whether there are new backup superblocks exist * in the last group. If there are some, mark them or clear * them in the bitmap. * * Return how many backups we find in the last group. */ static u16 ocfs2_calc_new_backup_super(struct inode *inode, struct ocfs2_group_desc *gd, u16 cl_cpg, u16 old_bg_clusters, int set) { int i; u16 backups = 0; u32 cluster, lgd_cluster; u64 blkno, gd_blkno, lgd_blkno = le64_to_cpu(gd->bg_blkno); for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) { blkno = ocfs2_backup_super_blkno(inode->i_sb, i); cluster = ocfs2_blocks_to_clusters(inode->i_sb, blkno); gd_blkno = ocfs2_which_cluster_group(inode, cluster); if (gd_blkno < lgd_blkno) continue; else if (gd_blkno > lgd_blkno) break; /* check if already done backup super */ lgd_cluster = ocfs2_blocks_to_clusters(inode->i_sb, lgd_blkno); lgd_cluster += old_bg_clusters; if (lgd_cluster >= cluster) continue; if (set) ocfs2_set_bit(cluster % cl_cpg, (unsigned long *)gd->bg_bitmap); else ocfs2_clear_bit(cluster % cl_cpg, (unsigned long *)gd->bg_bitmap); backups++; } return backups; }