FAILED: patch "[PATCH] gfs2: gfs2_setattr_size error path fix" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7336905a89f19173bf9301cd50a24421162f417c Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <[email protected]>
Date: Fri, 10 Dec 2021 14:43:36 +0100
Subject: [PATCH] gfs2: gfs2_setattr_size error path fix
When gfs2_setattr_size() fails, it calls gfs2_rs_delete(ip, NULL) to get rid of any reservations the inode may have. Instead, it should pass in the inode's write count as the second parameter to allow gfs2_rs_delete() to figure out if the inode has any writers left.
In a next step, there are two instances of gfs2_rs_delete(ip, NULL) left where we know that there can be no other users of the inode. Replace those with gfs2_rs_deltree(&ip->i_res) to avoid the unnecessary write count check.
With that, gfs2_rs_delete() is only called with the inode's actual write count, so get rid of the second parameter.
fs/gfs2/bmap.c +1 -1
@@ -2146,7 +2146,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) ret =do_shrink (inode, newsize); out: -gfs2_rs_delete (ip,NULL ); +gfs2_rs_delete (ip);gfs2_qa_put (ip);return ret; }
fs/gfs2/file.c +1 -1
@@ -706,7 +706,7 @@ static int gfs2_release(struct inode *inode, struct file *file)if (file->f_mode &FMODE_WRITE ) {if (gfs2_rs_active (&ip->i_res)) -gfs2_rs_delete (ip, &inode->i_writecount); +gfs2_rs_delete (ip);gfs2_qa_put (ip); }return 0 ;
fs/gfs2/inode.c +1 -1
@@ -793,7 +793,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,if (free_vfs_inode)/* else evict will do the put for us */ gfs2_glock_put (ip->i_gl); } -gfs2_rs_delete (ip,NULL ); +gfs2_rs_deltree (&ip->i_res);gfs2_qa_put (ip); fail_free_acls:posix_acl_release (default_acl);
fs/gfs2/rgrp.c +4 -3
@@ -680,13 +680,14 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)/** * gfs2_rs_delete - delete a multi-block reservation * @ip: The inode for this reservation -* @wcount: The inode's write count, or NULL * */ -void gfs2_rs_delete (struct gfs2_inode *ip,atomic_t *wcount) +void gfs2_rs_delete (struct gfs2_inode *ip) { +struct inode *inode = &ip->i_inode; +down_write (&ip->i_rw_mutex); -if ((wcount ==NULL ) || (atomic_read (wcount) <=1 )) +if (atomic_read (&inode->i_writecount) <=1 )gfs2_rs_deltree (&ip->i_res);up_write (&ip->i_rw_mutex); }
fs/gfs2/rgrp.h +1 -1
@@ -45,7 +45,7 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, bool dinode, u64 *generation);extern void gfs2_rs_deltree (struct gfs2_blkreserv *rs); -extern void gfs2_rs_delete (struct gfs2_inode *ip,atomic_t *wcount); +extern void gfs2_rs_delete (struct gfs2_inode *ip);extern void __gfs2_free_blocks (struct gfs2_inode *ip,struct gfs2_rgrpd *rgd,u64 bstart,u32 blen,int meta); extern void gfs2_free_meta(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
fs/gfs2/super.c +1 -1
@@ -1396,7 +1396,7 @@ static void gfs2_evict_inode(struct inode *inode)truncate_inode_pages_final (&inode->i_data);if (ip->i_qadata)gfs2_assert_warn (sdp, ip->i_qadata->qa_ref ==0 ); -gfs2_rs_delete (ip,NULL ); +gfs2_rs_deltree (&ip->i_res);gfs2_ordered_del_inode (ip);clear_inode (inode);gfs2_dir_hash_inval (ip);