Bug 626686

Summary: GFS2: Not enough space reserved in gfs2_write_begin and possibly elsewhere.
Product: [Fedora] Fedora Reporter: Ben Marzinski <bmarzins>
Component: kernelAssignee: Ben Marzinski <bmarzins>
Status: CLOSED UPSTREAM QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: rawhideCC: adas, anton, aquini, dougsland, gansalmon, itamar, jonathan, kernel-maint, madhu.chinakonda, rpeterso, swhiteho
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 637970 637972 (view as bug list) Environment:
Last Closed: 2010-10-27 13:25:15 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 637970, 637972    
Attachments:
Description Flags
latest patch to fix issue none

Description Ben Marzinski 2010-08-24 05:58:06 UTC
For a non journaled write, gfs2 reserves enough space to for all the indirect blocks it may possibly need to allocate or modify, plus a block for the dinode, a block for the local statfs change file, a block for quota changes, and an block if there are no journalled datablocks.

By picking a specific set of writes, I can get GFS2 to modify: all the indirect blocks that it reserves, the dinode, the local statfs change file, a resource group header block, and a resource group bit block.

This happens to come out the same number.  However, if it is possible that gfs2 might need to write to the quota file during a transaction, then it will fail. Also, if gfs2 can't allocate all the blocks from one resource group bit block, it will fail.

The solution seems to be to make gfs2 additionally reserve either as many blocks as it might allocate (both direct and indirect) or as many blocks as there are bit blocks in the resource group, whichever is fewer.  This guarantees that gfs2 will be able to allocate all of the blocks for the write, even if that requires modifying the maximum number of resource group bit blocks possible.

To make gfs2 use up at least all of the reserved blocks, I made a 1024 byte filesystem, mounted it, and then ran

# dd if=/dev/zero of=/mnt/test/foo bs=512 count=1
# dd if=/dev/zero of=/mnt/test/foo bs=4096 seek=238418579101562 count=1

This will force gfs2 to allocate all of the indirect blocks that it reserved.

Comment 1 Ben Marzinski 2010-09-27 21:19:43 UTC
Created attachment 450040 [details]
latest patch to fix issue

This is the latest patch I submitted to cluster-devel to fix this issue.  It adds an inline function, gfs2_rg_blocks() that returns either the number of allocated blocks plus one for the rg header, or the total number of blocks in the rg, whichever is less.  This is used by functions that need to allocate blocks in transactions to makes sure and reserve enough blocks to deal with the resource groups.

Comment 2 Steve Whitehouse 2010-10-27 13:25:15 UTC
Now in Linus kernel