Re: [Cluster-devel] [PATCH] fs: record task name which froze superblock
On Mon, Feb 16, 2015 at 10:38:52AM +0100, Jan Kara wrote: On Sat 14-02-15 21:55:24, Alexey Dobriyan wrote: Freezing and thawing are separate system calls, task which is supposed to thaw filesystem/superblock can disappear due to crash or not thaw due to a bug. Record at least task name (we can't take task_struct reference) to make support engineer's life easier. Hopefully 16 bytes per superblock isn't much. P.S.: Cc'ing GFS2 people just in case they want to correct my understanding of GFS2 having async freeze code. Signed-off-by: Alexey Dobriyan adobri...@gmail.com Hum, and when do you show the task name? Or do you expect that customer takes a crashdump and support just finds it in memory? Yeah, having at least something in crashdump is fine. --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -518,6 +518,7 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp, static int ioctl_fsfreeze(struct file *filp) { struct super_block *sb = file_inode(filp)-i_sb; + int rv; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -527,22 +528,31 @@ static int ioctl_fsfreeze(struct file *filp) return -EOPNOTSUPP; /* Freeze */ - if (sb-s_op-freeze_super) - return sb-s_op-freeze_super(sb); - return freeze_super(sb); + if (sb-s_op-freeze_super) { + rv = sb-s_op-freeze_super(sb); + if (rv == 0) + get_task_comm(sb-s_writers.freeze_comm, current); + } else + rv = freeze_super(sb); + return rv; Why don't you just set the name in ioctl_fsfreeze() in both cases? There are users of freeze_super() in GFS2 unless I'm misreading code. Also you seem to be missing freezing / thawing in freeze/thaw_bdev() functions. You are correct. Resending patch (blockdev freezing tested with XFS). --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1221,6 +1221,8 @@ struct sb_writers { int frozen; /* Is sb frozen? */ wait_queue_head_t wait_unfrozen; /* queue for waiting for sb to be thawed */ + /* who froze superblock */ + charfreeze_comm[16]; Here should be TASK_COMM_LEN, shouldn't it? It will pull sched.h, dunno if we care about headers anymore. Alexey
[Cluster-devel] [PATCH v2] fs: record task name which froze superblock
Freezing and thawing are separate system calls, task which is supposed to thaw filesystem/superblock can disappear due to crash or not thaw due to a bug. Record at least task name (we can't take task_struct reference) to make support engineer's life easier. Hopefully 16 bytes per superblock isn't much. Signed-off-by: Alexey Dobriyan adobri...@gmail.com --- fs/block_dev.c | 12 fs/ioctl.c | 22 -- fs/super.c |2 ++ include/linux/fs.h |2 ++ 4 files changed, 28 insertions(+), 10 deletions(-) --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -227,9 +227,11 @@ struct super_block *freeze_bdev(struct block_device *bdev) sb = get_active_super(bdev); if (!sb) goto out; - if (sb-s_op-freeze_super) + if (sb-s_op-freeze_super) { error = sb-s_op-freeze_super(sb); - else + if (error == 0) + get_task_comm(sb-s_writers.freeze_comm, current); + } else error = freeze_super(sb); if (error) { deactivate_super(sb); @@ -267,9 +269,11 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) if (!sb) goto out; - if (sb-s_op-thaw_super) + if (sb-s_op-thaw_super) { error = sb-s_op-thaw_super(sb); - else + if (error == 0) + memset(sb-s_writers.freeze_comm, 0, TASK_COMM_LEN); + } else error = thaw_super(sb); if (error) { bdev-bd_fsfreeze_count++; --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -518,6 +518,7 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp, static int ioctl_fsfreeze(struct file *filp) { struct super_block *sb = file_inode(filp)-i_sb; + int rv; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -527,22 +528,31 @@ static int ioctl_fsfreeze(struct file *filp) return -EOPNOTSUPP; /* Freeze */ - if (sb-s_op-freeze_super) - return sb-s_op-freeze_super(sb); - return freeze_super(sb); + if (sb-s_op-freeze_super) { + rv = sb-s_op-freeze_super(sb); + if (rv == 0) + get_task_comm(sb-s_writers.freeze_comm, current); + } else + rv = freeze_super(sb); + return rv; } static int ioctl_fsthaw(struct file *filp) { struct super_block *sb = file_inode(filp)-i_sb; + int rv; if (!capable(CAP_SYS_ADMIN)) return -EPERM; /* Thaw */ - if (sb-s_op-thaw_super) - return sb-s_op-thaw_super(sb); - return thaw_super(sb); + if (sb-s_op-thaw_super) { + rv = sb-s_op-thaw_super(sb); + if (rv == 0) + memset(sb-s_writers.freeze_comm, 0, TASK_COMM_LEN); + } else + rv = thaw_super(sb); + return rv; } /* --- a/fs/super.c +++ b/fs/super.c @@ -1355,6 +1355,7 @@ int freeze_super(struct super_block *sb) * sees write activity when frozen is set to SB_FREEZE_COMPLETE. */ sb-s_writers.frozen = SB_FREEZE_COMPLETE; + get_task_comm(sb-s_writers.freeze_comm, current); up_write(sb-s_umount); return 0; } @@ -1391,6 +1392,7 @@ int thaw_super(struct super_block *sb) out: sb-s_writers.frozen = SB_UNFROZEN; + memset(sb-s_writers.freeze_comm, 0, TASK_COMM_LEN); smp_wmb(); wake_up(sb-s_writers.wait_unfrozen); deactivate_locked_super(sb); --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1221,6 +1221,8 @@ struct sb_writers { int frozen; /* Is sb frozen? */ wait_queue_head_t wait_unfrozen; /* queue for waiting for sb to be thawed */ + /* who froze superblock and forgot to thaw it */ + charfreeze_comm[16]; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map lock_map[SB_FREEZE_LEVELS]; #endif
[Cluster-devel] [GFS2 PATCH] GFS2: Allocate reservation during write_begin if needed
Hi, This patch adds a call to function gfs2_rs_alloc to make sure a reservation structure has been allocated before attempting to reserve blocks. Regards, Bob Peterson Red Hat File Systems Signed-off-by: Bob Peterson rpete...@redhat.com --- fs/gfs2/aops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 805b37f..6453e23 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -675,6 +675,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, if (error) goto out_unlock; + error = gfs2_rs_alloc(ip); + if (error) + goto out_qunlock; requested = data_blocks + ind_blocks; ap.target = requested; error = gfs2_inplace_reserve(ip, ap);
Re: [Cluster-devel] [GFS2 PATCH 1/3] gfs2: perform quota checks against allocation parameters
- Original Message - From: Steven Whitehouse swhit...@redhat.com To: Abhi Das a...@redhat.com, cluster-devel@redhat.com Sent: Tuesday, February 17, 2015 3:38:07 AM Subject: Re: [Cluster-devel] [GFS2 PATCH 1/3] gfs2: perform quota checks against allocation parameters Hi, On 16/02/15 17:59, Abhi Das wrote: Use struct gfs2_alloc_parms as an argument to gfs2_quota_check() and gfs2_quota_lock_check() to check for quota violations while accounting for the new blocks requested by the current operation in ap-target. Previously, the number of new blocks requested during an operation were not accounted for during quota_check and would allow these operations to exceed quota. This was not very apparent since most operations allocated only 1 block at a time and quotas would get violated in the next operation. i.e. quota excess would only be by 1 block or so. With fallocate, (where we allocate a bunch of blocks at once) the quota excess is non-trivial and is addressed by this patch. Resolves: rhbz#1174295 Signed-off-by: Abhi Das a...@redhat.com --- fs/gfs2/aops.c | 6 +++--- fs/gfs2/bmap.c | 2 +- fs/gfs2/file.c | 9 + fs/gfs2/incore.h | 2 +- fs/gfs2/inode.c | 18 ++ fs/gfs2/quota.c | 6 +++--- fs/gfs2/quota.h | 8 +--- fs/gfs2/xattr.c | 2 +- 8 files changed, 29 insertions(+), 24 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 805b37f..0261126 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -671,12 +671,12 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, if (alloc_required) { struct gfs2_alloc_parms ap = { .aflags = 0, }; - error = gfs2_quota_lock_check(ip); + requested = data_blocks + ind_blocks; + ap.target = requested; + error = gfs2_quota_lock_check(ip, ap); if (error) goto out_unlock; - requested = data_blocks + ind_blocks; - ap.target = requested; error = gfs2_inplace_reserve(ip, ap); if (error) goto out_qunlock; diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index f0b945a..61296ec 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1224,7 +1224,7 @@ static int do_grow(struct inode *inode, u64 size) if (gfs2_is_stuffed(ip) (size (sdp-sd_sb.sb_bsize - sizeof(struct gfs2_dinode { - error = gfs2_quota_lock_check(ip); + error = gfs2_quota_lock_check(ip, ap); if (error) return error; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 6e600ab..2ea420a 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -429,11 +429,11 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto out_unlock; - ret = gfs2_quota_lock_check(ip); - if (ret) - goto out_unlock; gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, data_blocks, ind_blocks); ap.target = data_blocks + ind_blocks; + ret = gfs2_quota_lock_check(ip, ap); + if (ret) + goto out_unlock; ret = gfs2_inplace_reserve(ip, ap); if (ret) goto out_quota_unlock; @@ -828,7 +828,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t offset += bytes; continue; } - error = gfs2_quota_lock_check(ip); + ap.target = bytes sdp-sd_sb.sb_bsize_shift; + error = gfs2_quota_lock_check(ip, ap); if (error) return error; retry: diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 7a2dbbc..3a4ea50 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -301,7 +301,7 @@ struct gfs2_blkreserv { * to the allocation code. */ struct gfs2_alloc_parms { - u32 target; + u64 target; Why does this need to be 64 bits in size? The max size of an rgrp is 2^32, so there should be no need to represent an extent larger than that, Steve. This has got to do with setattr_chown() which calls gfs2_get_inode_blocks() to get the number of blocks used by the inode being chowned. This is a u64 value and since we also use ap.target to check against quotas in gfs2_quota_check(), I had to change its size. Cheers! --Abhi
Re: [Cluster-devel] [GFS2 PATCH 3/3] gfs2: allow fallocate to max out quotas/fs efficiently
- Original Message - From: Steven Whitehouse swhit...@redhat.com To: Abhi Das a...@redhat.com, cluster-devel@redhat.com Sent: Tuesday, February 17, 2015 3:41:15 AM Subject: Re: [Cluster-devel] [GFS2 PATCH 3/3] gfs2: allow fallocate to max out quotas/fs efficiently Hi, On 16/02/15 17:59, Abhi Das wrote: We can quickly get an estimate of how many more blocks are available for allocation restricted by quota and fs size respectively using the ap-allowed field in the gfs2_alloc_parms structure. gfs2_quota_check() and gfs2_inplace_reserve() provide these values. By re-trying to allocate what's available instead of guessing, we can max out quotas or the filesystem efficiently. Bear in mind that this applies only when the requested fallocate operation would otherwise error out with -EDQUOT or -ENOSPC without utilizing all the blocks that might still be available. Signed-off-by: Abhi Das a...@redhat.com --- fs/gfs2/file.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 2ea420a..57129fa 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -829,20 +829,24 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t continue; } ap.target = bytes sdp-sd_sb.sb_bsize_shift; + quota_retry: error = gfs2_quota_lock_check(ip, ap); - if (error) + if (error) { + if (error == -EDQUOT ap.allowed) { + bytes = ap.allowed sdp-sd_sb.sb_bsize_shift; + ap.target = ap.allowed; + goto quota_retry; + } return error; Do you really need to loop here if -EDQUOT is returned and ap.allowed is set? Why not just continue after having updated the target value? Otherwise I think these patches look good, Steve. If gfs2_quota_lock_check() fails, the quota isn't locked, which we'd have to do anyway. And I figured there's a race here where some other process could use up all or part of ap.allowed blocks before we re-lock the quota thereby causing us to exceed quotas. So, I decided to retry gfs2_quota_lock_check() itself. Cheers! --Abhi
Re: [Cluster-devel] [GFS2 PATCH] GFS2: Allocate reservation during write_begin if needed
- Original Message - Hi, Since we set the allocation structure when the write call begins, and it is not deallocated until there are no writers left with the file open, how does this happen? Steve. Hi, In a normal write, the code goes through gfs2_page_mkwrite or gfs2_file_aio_write. In the failing scenario, it's going through sendfile. I suppose I could patch sendfile as an alternative, but the advantage here is that this patch will do it only if a block allocation is needed. Regards, Bob Peterson Red Hat File Systems
Re: [Cluster-devel] [GFS2 PATCH] GFS2: Allocate reservation during write_begin if needed
Hi, Since we set the allocation structure when the write call begins, and it is not deallocated until there are no writers left with the file open, how does this happen? Steve. On 17/02/15 17:09, Bob Peterson wrote: Hi, This patch adds a call to function gfs2_rs_alloc to make sure a reservation structure has been allocated before attempting to reserve blocks. Regards, Bob Peterson Red Hat File Systems Signed-off-by: Bob Peterson rpete...@redhat.com --- fs/gfs2/aops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 805b37f..6453e23 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -675,6 +675,9 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, if (error) goto out_unlock; + error = gfs2_rs_alloc(ip); + if (error) + goto out_qunlock; requested = data_blocks + ind_blocks; ap.target = requested; error = gfs2_inplace_reserve(ip, ap);
Re: [Cluster-devel] [GFS2 PATCH] GFS2: Allocate reservation during write_begin if needed
Hi, On 17/02/15 19:09, Bob Peterson wrote: - Original Message - Hi, Since we set the allocation structure when the write call begins, and it is not deallocated until there are no writers left with the file open, how does this happen? Steve. Hi, In a normal write, the code goes through gfs2_page_mkwrite or gfs2_file_aio_write. In the failing scenario, it's going through sendfile. I suppose I could patch sendfile as an alternative, but the advantage here is that this patch will do it only if a block allocation is needed. Regards, Bob Peterson Red Hat File Systems Ah, I see. In which case that code path should be patched. So it should be part of the splice code I think, since it should be done at the higher level, and not at the write_begin level, since that is too late. We should have a call to the reservation code too at that point, to ensure that we don't have fragmentation issues. So we need a wrapper for |iter_file_splice_write| along the lines of gfs2_file_write_iter I think, Steve.
Re: [Cluster-devel] [PATCH] Add myself (Bob Peterson) as a maintainer of GFS2
- Original Message - Hi Bob, On Mon, 16 Feb 2015 09:20:56 -0500 (EST) Bob Peterson rpete...@redhat.com wrote: This patch adds Bob Peterson as a maintainer of the GFS2 file system. It also changes the development repository to a shared location rather than Steve Whitehouse's private location. Please also consider letting the linux-next maintainer know :-) i.e. does this mean I should change the repo/branch I fetch into linux-next each day and should I add you to the contacts? -- Cheers, Stephen Rothwells...@canb.auug.org.au Hi Stephen, Yes, indeed. I was going to let you know as soon as I got things set up. Unfortunately, I've been pulled in a lot of directions lately. I've set up a for-next branch from which you can do your daily fetch: pub/scm/linux/kernel/git/gfs2/linux-gfs2.git Currently it's empty, and yes, please add me to the contacts. Regards, Bob Peterson Red Hat File Systems
Re: [Cluster-devel] [GFS2 PATCH 1/3] gfs2: perform quota checks against allocation parameters
Hi, On 16/02/15 17:59, Abhi Das wrote: Use struct gfs2_alloc_parms as an argument to gfs2_quota_check() and gfs2_quota_lock_check() to check for quota violations while accounting for the new blocks requested by the current operation in ap-target. Previously, the number of new blocks requested during an operation were not accounted for during quota_check and would allow these operations to exceed quota. This was not very apparent since most operations allocated only 1 block at a time and quotas would get violated in the next operation. i.e. quota excess would only be by 1 block or so. With fallocate, (where we allocate a bunch of blocks at once) the quota excess is non-trivial and is addressed by this patch. Resolves: rhbz#1174295 Signed-off-by: Abhi Das a...@redhat.com --- fs/gfs2/aops.c | 6 +++--- fs/gfs2/bmap.c | 2 +- fs/gfs2/file.c | 9 + fs/gfs2/incore.h | 2 +- fs/gfs2/inode.c | 18 ++ fs/gfs2/quota.c | 6 +++--- fs/gfs2/quota.h | 8 +--- fs/gfs2/xattr.c | 2 +- 8 files changed, 29 insertions(+), 24 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 805b37f..0261126 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -671,12 +671,12 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, if (alloc_required) { struct gfs2_alloc_parms ap = { .aflags = 0, }; - error = gfs2_quota_lock_check(ip); + requested = data_blocks + ind_blocks; + ap.target = requested; + error = gfs2_quota_lock_check(ip, ap); if (error) goto out_unlock; - requested = data_blocks + ind_blocks; - ap.target = requested; error = gfs2_inplace_reserve(ip, ap); if (error) goto out_qunlock; diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index f0b945a..61296ec 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1224,7 +1224,7 @@ static int do_grow(struct inode *inode, u64 size) if (gfs2_is_stuffed(ip) (size (sdp-sd_sb.sb_bsize - sizeof(struct gfs2_dinode { - error = gfs2_quota_lock_check(ip); + error = gfs2_quota_lock_check(ip, ap); if (error) return error; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 6e600ab..2ea420a 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -429,11 +429,11 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto out_unlock; - ret = gfs2_quota_lock_check(ip); - if (ret) - goto out_unlock; gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, data_blocks, ind_blocks); ap.target = data_blocks + ind_blocks; + ret = gfs2_quota_lock_check(ip, ap); + if (ret) + goto out_unlock; ret = gfs2_inplace_reserve(ip, ap); if (ret) goto out_quota_unlock; @@ -828,7 +828,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t offset += bytes; continue; } - error = gfs2_quota_lock_check(ip); + ap.target = bytes sdp-sd_sb.sb_bsize_shift; + error = gfs2_quota_lock_check(ip, ap); if (error) return error; retry: diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 7a2dbbc..3a4ea50 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -301,7 +301,7 @@ struct gfs2_blkreserv { * to the allocation code. */ struct gfs2_alloc_parms { - u32 target; + u64 target; Why does this need to be 64 bits in size? The max size of an rgrp is 2^32, so there should be no need to represent an extent larger than that, Steve. u32 aflags; }; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 73c72253..08bc84d 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -382,7 +382,7 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks) struct gfs2_alloc_parms ap = { .target = *dblocks, .aflags = flags, }; int error; - error = gfs2_quota_lock_check(ip); + error = gfs2_quota_lock_check(ip, ap); if (error) goto out; @@ -525,7 +525,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, int error; if (da-nr_blocks) { - error = gfs2_quota_lock_check(dip); + error = gfs2_quota_lock_check(dip, ap); if (error) goto fail_quota_locks; @@ -953,7 +953,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, if (da.nr_blocks) { struct gfs2_alloc_parms ap = { .target = da.nr_blocks, }; - error = gfs2_quota_lock_check(dip); + error = gfs2_quota_lock_check(dip, ap);
Re: [Cluster-devel] [GFS2 PATCH 3/3] gfs2: allow fallocate to max out quotas/fs efficiently
Hi, On 16/02/15 17:59, Abhi Das wrote: We can quickly get an estimate of how many more blocks are available for allocation restricted by quota and fs size respectively using the ap-allowed field in the gfs2_alloc_parms structure. gfs2_quota_check() and gfs2_inplace_reserve() provide these values. By re-trying to allocate what's available instead of guessing, we can max out quotas or the filesystem efficiently. Bear in mind that this applies only when the requested fallocate operation would otherwise error out with -EDQUOT or -ENOSPC without utilizing all the blocks that might still be available. Signed-off-by: Abhi Das a...@redhat.com --- fs/gfs2/file.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 2ea420a..57129fa 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -829,20 +829,24 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t continue; } ap.target = bytes sdp-sd_sb.sb_bsize_shift; + quota_retry: error = gfs2_quota_lock_check(ip, ap); - if (error) + if (error) { + if (error == -EDQUOT ap.allowed) { + bytes = ap.allowed sdp-sd_sb.sb_bsize_shift; + ap.target = ap.allowed; + goto quota_retry; + } return error; Do you really need to loop here if -EDQUOT is returned and ap.allowed is set? Why not just continue after having updated the target value? Otherwise I think these patches look good, Steve. -retry: + } + retry: gfs2_write_calc_reserv(ip, bytes, data_blocks, ind_blocks); ap.target = data_blocks + ind_blocks; error = gfs2_inplace_reserve(ip, ap); if (error) { - if (error == -ENOSPC bytes sdp-sd_sb.sb_bsize) { - bytes = 1; - bytes = bsize_mask; - if (bytes == 0) - bytes = sdp-sd_sb.sb_bsize; + if (error == -ENOSPC ap.allowed) { + bytes = ap.allowed sdp-sd_sb.sb_bsize_shift; goto retry; } goto out_qunlock;