diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 38 | ||||
| -rw-r--r-- | fs/xfs/xfs_mount.c | 15 | ||||
| -rw-r--r-- | fs/xfs/xfs_mount.h | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_inode.c | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_resv.c | 3 |
5 files changed, 43 insertions, 23 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); |
| 1247 | error2: | 1249 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 1250 | return error; | ||
| 1251 | |||
| 1252 | bmap_cancel: | ||
| 1248 | xfs_bmap_cancel(&flist); | 1253 | xfs_bmap_cancel(&flist); |
| 1249 | error1: | 1254 | trans_cancel: |
| 1255 | xfs_trans_cancel(tp, cancel_flags); | ||
| 1250 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 1256 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 1251 | error0: | ||
| 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) + |
