Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 339399
b: refs/heads/master
c: 72b53ef
h: refs/heads/master
i:
  339397: afd74eb
  339395: f074454
  339391: 0961433
v: v3
  • Loading branch information
Brian Foster authored and Ben Myers committed Nov 8, 2012
1 parent 34aeb93 commit ec17f7f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a454f7428ffa03c8e1321124d9074101b7290be6
refs/heads/master: 72b53efa4a6125a4c334871c58268c430605819a
37 changes: 37 additions & 0 deletions trunk/fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3912,3 +3912,40 @@ xfs_iext_irec_update_extoffs(
ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
}
}

/*
* Test whether it is appropriate to check an inode for and free post EOF
* blocks. The 'force' parameter determines whether we should also consider
* regular files that are marked preallocated or append-only.
*/
bool
xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
{
/* prealloc/delalloc exists only on regular files */
if (!S_ISREG(ip->i_d.di_mode))
return false;

/*
* Zero sized files with no cached pages and delalloc blocks will not
* have speculative prealloc/delalloc blocks to remove.
*/
if (VFS_I(ip)->i_size == 0 &&
VN_CACHED(VFS_I(ip)) == 0 &&
ip->i_delayed_blks == 0)
return false;

/* If we haven't read in the extent list, then don't do it now. */
if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
return false;

/*
* Do not free real preallocated or append-only files unless the file
* has delalloc blocks and we are forced to remove them.
*/
if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))
if (!force || ip->i_delayed_blks == 0)
return false;

return true;
}

1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ void xfs_iext_irec_compact(xfs_ifork_t *);
void xfs_iext_irec_compact_pages(xfs_ifork_t *);
void xfs_iext_irec_compact_full(xfs_ifork_t *);
void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
bool xfs_can_free_eofblocks(struct xfs_inode *, bool);

#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))

Expand Down
19 changes: 7 additions & 12 deletions trunk/fs/xfs/xfs_vnodeops.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,7 @@ xfs_release(
if (ip->i_d.di_nlink == 0)
return 0;

if ((S_ISREG(ip->i_d.di_mode) &&
(VFS_I(ip)->i_size > 0 ||
(VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) &&
(ip->i_df.if_flags & XFS_IFEXTENTS)) &&
(!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
if (xfs_can_free_eofblocks(ip, false)) {

/*
* If we can't get the iolock just skip truncating the blocks
Expand Down Expand Up @@ -516,13 +512,12 @@ xfs_inactive(
goto out;

if (ip->i_d.di_nlink != 0) {
if ((S_ISREG(ip->i_d.di_mode) &&
(VFS_I(ip)->i_size > 0 ||
(VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) &&
(ip->i_df.if_flags & XFS_IFEXTENTS) &&
(!(ip->i_d.di_flags &
(XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
ip->i_delayed_blks != 0))) {
/*
* force is true because we are evicting an inode from the
* cache. Post-eof blocks must be freed, lest we end up with
* broken free space accounting.
*/
if (xfs_can_free_eofblocks(ip, true)) {
error = xfs_free_eofblocks(mp, ip, false);
if (error)
return VN_INACTIVE_CACHE;
Expand Down

0 comments on commit ec17f7f

Please sign in to comment.