/** * ext4_free_blocks() -- Free given blocks and update quota * @handle: handle for this transaction * @inode: inode * @block: start physical block to free * @count: number of blocks to count * @metadata: Are these metadata blocks */ void ext4_free_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t block, unsigned long count, int metadata) { struct super_block *sb; unsigned long dquot_freed_blocks; /* this isn't the right place to decide whether block is metadata * inode.c/extents.c knows better, but for safety ... */ if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) metadata = 1; /* We need to make sure we don't reuse * block released untill the transaction commit. * writeback mode have weak data consistency so * don't force data as metadata when freeing block * for writeback mode. */ if (metadata == 0 && !ext4_should_writeback_data(inode)) metadata = 1; sb = inode->i_sb; ext4_mb_free_blocks(handle, inode, block, count, metadata, &dquot_freed_blocks); if (dquot_freed_blocks) vfs_dq_free_block(inode, dquot_freed_blocks); return; }
static void udf_bitmap_free_blocks(struct super_block *sb, struct inode *inode, struct udf_bitmap *bitmap, kernel_lb_addr bloc, uint32_t offset, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = NULL; unsigned long block; unsigned long block_group; unsigned long bit; unsigned long i; int bitmap_nr; unsigned long overflow; mutex_lock(&sbi->s_alloc_mutex); if (bloc.logicalBlockNum < 0 || (bloc.logicalBlockNum + count) > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, sbi->s_partmaps[bloc.partitionReferenceNum]. s_partition_len); goto error_return; } block = bloc.logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); do { overflow = 0; block_group = block >> (sb->s_blocksize_bits + 3); bit = block % (sb->s_blocksize << 3); /* * Check to see if we are freeing blocks across a group boundary. */ if (bit + count > (sb->s_blocksize << 3)) { overflow = bit + count - (sb->s_blocksize << 3); count -= overflow; } bitmap_nr = load_block_bitmap(sb, bitmap, block_group); if (bitmap_nr < 0) goto error_return; bh = bitmap->s_block_bitmap[bitmap_nr]; for (i = 0; i < count; i++) { if (udf_set_bit(bit + i, bh->b_data)) { udf_debug("bit %ld already set\n", bit + i); udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]); } else { if (inode) vfs_dq_free_block(inode, 1); udf_add_free_space(sbi, sbi->s_partition, 1); } }