aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-22 11:37:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-22 11:37:47 -0500
commit6ea9786e76d74350aee6cd9339c6f7cb765ba291 (patch)
treea5ac36956a33cd1b2e349800333234876c311dc6
parent24f971abbda045c24d5d6f2438a7785567d2fde9 (diff)
parent2fe8c1c08b3fbd87dd2641c8f032ff6e965d5803 (diff)
Merge tag 'xfs-for-linus-v3.13-rc1-2' of git://oss.sgi.com/xfs/xfs
Pull second xfs update from Ben Myers: "There are a couple of patches that I wasn't quite sure about in time for our initial 3.13 pull request, a bugfix, and an update to add Dave to MAINTAINERS: Here we have a performance fix for inode iversion, increased inode cluster size for v5 superblock filesystems, a fix for error handling in xfs_bmap_add_attrfork, and a MAINTAINERS update to add Dave" * tag 'xfs-for-linus-v3.13-rc1-2' of git://oss.sgi.com/xfs/xfs: xfs: open code inc_inode_iversion when logging an inode xfs: increase inode cluster size for v5 filesystems xfs: fix unlock in xfs_bmap_add_attrfork xfs: update maintainers
-rw-r--r--MAINTAINERS2
-rw-r--r--fs/xfs/xfs_bmap.c38
-rw-r--r--fs/xfs/xfs_mount.c15
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_trans_inode.c8
-rw-r--r--fs/xfs/xfs_trans_resv.c3
6 files changed, 44 insertions, 24 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d9c97dce6635..8285ed4676b6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9525,8 +9525,8 @@ F: drivers/xen/*swiotlb*
9525 9525
9526XFS FILESYSTEM 9526XFS FILESYSTEM
9527P: Silicon Graphics Inc 9527P: Silicon Graphics Inc
9528M: Dave Chinner <dchinner@fromorbit.com>
9528M: Ben Myers <bpm@sgi.com> 9529M: Ben Myers <bpm@sgi.com>
9529M: Alex Elder <elder@kernel.org>
9530M: xfs@oss.sgi.com 9530M: xfs@oss.sgi.com
9531L: xfs@oss.sgi.com 9531L: xfs@oss.sgi.com
9532W: http://oss.sgi.com/projects/xfs 9532W: http://oss.sgi.com/projects/xfs
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
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index da88f167af78..02df7b408a26 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -41,6 +41,7 @@
41#include "xfs_fsops.h" 41#include "xfs_fsops.h"
42#include "xfs_trace.h" 42#include "xfs_trace.h"
43#include "xfs_icache.h" 43#include "xfs_icache.h"
44#include "xfs_dinode.h"
44 45
45 46
46#ifdef HAVE_PERCPU_SB 47#ifdef HAVE_PERCPU_SB
@@ -718,8 +719,22 @@ xfs_mountfs(
718 * Set the inode cluster size. 719 * Set the inode cluster size.
719 * This may still be overridden by the file system 720 * This may still be overridden by the file system
720 * block size if it is larger than the chosen cluster size. 721 * block size if it is larger than the chosen cluster size.
722 *
723 * For v5 filesystems, scale the cluster size with the inode size to
724 * keep a constant ratio of inode per cluster buffer, but only if mkfs
725 * has set the inode alignment value appropriately for larger cluster
726 * sizes.
721 */ 727 */
722 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; 728 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
729 if (xfs_sb_version_hascrc(&mp->m_sb)) {
730 int new_size = mp->m_inode_cluster_size;
731
732 new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
733 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
734 mp->m_inode_cluster_size = new_size;
735 xfs_info(mp, "Using inode cluster size of %d bytes",
736 mp->m_inode_cluster_size);
737 }
723 738
724 /* 739 /*
725 * Set inode alignment fields 740 * Set inode alignment fields
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 1d8101a10d8e..a466c5e5826e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -112,7 +112,7 @@ typedef struct xfs_mount {
112 __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ 112 __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
113 __uint8_t m_agno_log; /* log #ag's */ 113 __uint8_t m_agno_log; /* log #ag's */
114 __uint8_t m_agino_log; /* #bits for agino in inum */ 114 __uint8_t m_agino_log; /* #bits for agino in inum */
115 __uint16_t m_inode_cluster_size;/* min inode buf size */ 115 uint m_inode_cluster_size;/* min inode buf size */
116 uint m_blockmask; /* sb_blocksize-1 */ 116 uint m_blockmask; /* sb_blocksize-1 */
117 uint m_blockwsize; /* sb_blocksize in words */ 117 uint m_blockwsize; /* sb_blocksize in words */
118 uint m_blockwmask; /* blockwsize-1 */ 118 uint m_blockwmask; /* blockwsize-1 */
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 1bba7f60d94c..50c3f5614288 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -111,12 +111,14 @@ xfs_trans_log_inode(
111 111
112 /* 112 /*
113 * First time we log the inode in a transaction, bump the inode change 113 * First time we log the inode in a transaction, bump the inode change
114 * counter if it is configured for this to occur. 114 * counter if it is configured for this to occur. We don't use
115 * inode_inc_version() because there is no need for extra locking around
116 * i_version as we already hold the inode locked exclusively for
117 * metadata modification.
115 */ 118 */
116 if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) && 119 if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) &&
117 IS_I_VERSION(VFS_I(ip))) { 120 IS_I_VERSION(VFS_I(ip))) {
118 inode_inc_iversion(VFS_I(ip)); 121 ip->i_d.di_changecount = ++VFS_I(ip)->i_version;
119 ip->i_d.di_changecount = VFS_I(ip)->i_version;
120 flags |= XFS_ILOG_CORE; 122 flags |= XFS_ILOG_CORE;
121 } 123 }
122 124
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c
index d53d9f0627a7..2fd59c0dae66 100644
--- a/fs/xfs/xfs_trans_resv.c
+++ b/fs/xfs/xfs_trans_resv.c
@@ -385,8 +385,7 @@ xfs_calc_ifree_reservation(
385 xfs_calc_inode_res(mp, 1) + 385 xfs_calc_inode_res(mp, 1) +
386 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 386 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
387 xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) + 387 xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
388 MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), 388 max_t(uint, XFS_FSB_TO_B(mp, 1), XFS_INODE_CLUSTER_SIZE(mp)) +
389 XFS_INODE_CLUSTER_SIZE(mp)) +
390 xfs_calc_buf_res(1, 0) + 389 xfs_calc_buf_res(1, 0) +
391 xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) + 390 xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
392 mp->m_in_maxlevels, 0) + 391 mp->m_in_maxlevels, 0) +