aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMark Tinguely <tinguely@sgi.com>2013-11-07 16:43:28 -0500
committerBen Myers <bpm@sgi.com>2013-11-18 10:12:54 -0500
commit9e3908e342eba6684621e616529669c17e271e7e (patch)
tree1538ff2599edc1523535e6032e91a1146a25bb42 /fs
parentec715cacd53f63b21da3a9bc96a9bb4c527e25b1 (diff)
xfs: fix unlock in xfs_bmap_add_attrfork
xfs_trans_ijoin() activates the inode in a transaction and also can specify which lock to free when the transaction is committed or canceled. xfs_bmap_add_attrfork call locks and adds the lock to the transaction but also manually removes the lock. Change the routine to not add the lock to the transaction and manually remove lock on completion. While here, clean up the xfs_trans_cancel flags and goto names. Signed-off-by: Mark Tinguely <tinguely@sgi.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_bmap.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 1c02da8bb7df..3ef11b22e750 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1137,6 +1137,7 @@ xfs_bmap_add_attrfork(
1137 int committed; /* xaction was committed */ 1137 int committed; /* xaction was committed */
1138 int logflags; /* logging flags */ 1138 int logflags; /* logging flags */
1139 int error; /* error return value */ 1139 int error; /* error return value */
1140 int cancel_flags = 0;
1140 1141
1141 ASSERT(XFS_IFORK_Q(ip) == 0); 1142 ASSERT(XFS_IFORK_Q(ip) == 0);
1142 1143
@@ -1147,19 +1148,20 @@ xfs_bmap_add_attrfork(
1147 if (rsvd) 1148 if (rsvd)
1148 tp->t_flags |= XFS_TRANS_RESERVE; 1149 tp->t_flags |= XFS_TRANS_RESERVE;
1149 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0); 1150 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0);
1150 if (error) 1151 if (error) {
1151 goto error0; 1152 xfs_trans_cancel(tp, 0);
1153 return error;
1154 }
1155 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1152 xfs_ilock(ip, XFS_ILOCK_EXCL); 1156 xfs_ilock(ip, XFS_ILOCK_EXCL);
1153 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? 1157 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
1154 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 1158 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
1155 XFS_QMOPT_RES_REGBLKS); 1159 XFS_QMOPT_RES_REGBLKS);
1156 if (error) { 1160 if (error)
1157 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1161 goto trans_cancel;
1158 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); 1162 cancel_flags |= XFS_TRANS_ABORT;
1159 return error;
1160 }
1161 if (XFS_IFORK_Q(ip)) 1163 if (XFS_IFORK_Q(ip))
1162 goto error1; 1164 goto trans_cancel;
1163 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { 1165 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
1164 /* 1166 /*
1165 * For inodes coming from pre-6.2 filesystems. 1167 * For inodes coming from pre-6.2 filesystems.
@@ -1169,7 +1171,7 @@ xfs_bmap_add_attrfork(
1169 } 1171 }
1170 ASSERT(ip->i_d.di_anextents == 0); 1172 ASSERT(ip->i_d.di_anextents == 0);
1171 1173
1172 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1174 xfs_trans_ijoin(tp, ip, 0);
1173 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1175 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1174 1176
1175 switch (ip->i_d.di_format) { 1177 switch (ip->i_d.di_format) {
@@ -1191,7 +1193,7 @@ xfs_bmap_add_attrfork(
1191 default: 1193 default:
1192 ASSERT(0); 1194 ASSERT(0);
1193 error = XFS_ERROR(EINVAL); 1195 error = XFS_ERROR(EINVAL);
1194 goto error1; 1196 goto trans_cancel;
1195 } 1197 }
1196 1198
1197 ASSERT(ip->i_afp == NULL); 1199 ASSERT(ip->i_afp == NULL);
@@ -1219,7 +1221,7 @@ xfs_bmap_add_attrfork(
1219 if (logflags) 1221 if (logflags)
1220 xfs_trans_log_inode(tp, ip, logflags); 1222 xfs_trans_log_inode(tp, ip, logflags);
1221 if (error) 1223 if (error)
1222 goto error2; 1224 goto bmap_cancel;
1223 if (!xfs_sb_version_hasattr(&mp->m_sb) || 1225 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
1224 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { 1226 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
1225 __int64_t sbfields = 0; 1227 __int64_t sbfields = 0;
@@ -1242,14 +1244,16 @@ xfs_bmap_add_attrfork(
1242 1244
1243 error = xfs_bmap_finish(&tp, &flist, &committed); 1245 error = xfs_bmap_finish(&tp, &flist, &committed);
1244 if (error) 1246 if (error)
1245 goto error2; 1247 goto bmap_cancel;
1246 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 1248 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1247error2: 1249 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1250 return error;
1251
1252bmap_cancel:
1248 xfs_bmap_cancel(&flist); 1253 xfs_bmap_cancel(&flist);
1249error1: 1254trans_cancel:
1255 xfs_trans_cancel(tp, cancel_flags);
1250 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1256 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1251error0:
1252 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1253 return error; 1257 return error;
1254} 1258}
1255 1259