aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-09-29 22:25:56 -0400
committerAlex Elder <aelder@sgi.com>2010-10-18 16:08:00 -0400
commit1b0407125f9a5be63e861eb27c8af9e32f20619c (patch)
tree206f43a7131ad11b8c603247254a8eb9aa2fc17e /fs/xfs/xfs_mount.c
parent96540c78583a417113df4d027e6b68a595ab9a09 (diff)
xfs: do not use xfs_mod_incore_sb_batch for per-cpu counters
Update the per-cpu counters manually in xfs_trans_unreserve_and_mod_sb and remove support for per-cpu counters from xfs_mod_incore_sb_batch to simplify it. And added benefit is that we don't have to take m_sb_lock for transactions that only modify per-cpu counters. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c114
1 files changed, 35 insertions, 79 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 20c67ff57536..00538b7e694a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1856,98 +1856,54 @@ xfs_mod_incore_sb(
1856} 1856}
1857 1857
1858/* 1858/*
1859 * xfs_mod_incore_sb_batch() is used to change more than one field 1859 * Change more than one field in the in-core superblock structure at a time.
1860 * in the in-core superblock structure at a time. This modification
1861 * is protected by a lock internal to this module. The fields and
1862 * changes to those fields are specified in the array of xfs_mod_sb
1863 * structures passed in.
1864 * 1860 *
1865 * Either all of the specified deltas will be applied or none of 1861 * The fields and changes to those fields are specified in the array of
1866 * them will. If any modified field dips below 0, then all modifications 1862 * xfs_mod_sb structures passed in. Either all of the specified deltas
1867 * will be backed out and EINVAL will be returned. 1863 * will be applied or none of them will. If any modified field dips below 0,
1864 * then all modifications will be backed out and EINVAL will be returned.
1865 *
1866 * Note that this function may not be used for the superblock values that
1867 * are tracked with the in-memory per-cpu counters - a direct call to
1868 * xfs_icsb_modify_counters is required for these.
1868 */ 1869 */
1869int 1870int
1870xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) 1871xfs_mod_incore_sb_batch(
1872 struct xfs_mount *mp,
1873 xfs_mod_sb_t *msb,
1874 uint nmsb,
1875 int rsvd)
1871{ 1876{
1872 int status=0; 1877 xfs_mod_sb_t *msbp = &msb[0];
1873 xfs_mod_sb_t *msbp; 1878 int error = 0;
1874 1879
1875 /* 1880 /*
1876 * Loop through the array of mod structures and apply each 1881 * Loop through the array of mod structures and apply each individually.
1877 * individually. If any fail, then back out all those 1882 * If any fail, then back out all those which have already been applied.
1878 * which have already been applied. Do all of this within 1883 * Do all of this within the scope of the m_sb_lock so that all of the
1879 * the scope of the m_sb_lock so that all of the changes will 1884 * changes will be atomic.
1880 * be atomic.
1881 */ 1885 */
1882 spin_lock(&mp->m_sb_lock); 1886 spin_lock(&mp->m_sb_lock);
1883 msbp = &msb[0];
1884 for (msbp = &msbp[0]; msbp < (msb + nmsb); msbp++) { 1887 for (msbp = &msbp[0]; msbp < (msb + nmsb); msbp++) {
1885 /* 1888 ASSERT(msbp->msb_field < XFS_SBS_ICOUNT ||
1886 * Apply the delta at index n. If it fails, break 1889 msbp->msb_field > XFS_SBS_FDBLOCKS);
1887 * from the loop so we'll fall into the undo loop
1888 * below.
1889 */
1890 switch (msbp->msb_field) {
1891#ifdef HAVE_PERCPU_SB
1892 case XFS_SBS_ICOUNT:
1893 case XFS_SBS_IFREE:
1894 case XFS_SBS_FDBLOCKS:
1895 spin_unlock(&mp->m_sb_lock);
1896 status = xfs_icsb_modify_counters(mp,
1897 msbp->msb_field,
1898 msbp->msb_delta, rsvd);
1899 spin_lock(&mp->m_sb_lock);
1900 break;
1901#endif
1902 default:
1903 status = xfs_mod_incore_sb_unlocked(mp,
1904 msbp->msb_field,
1905 msbp->msb_delta, rsvd);
1906 break;
1907 }
1908 1890
1909 if (status != 0) { 1891 error = xfs_mod_incore_sb_unlocked(mp, msbp->msb_field,
1910 break; 1892 msbp->msb_delta, rsvd);
1911 } 1893 if (error)
1894 goto unwind;
1912 } 1895 }
1896 spin_unlock(&mp->m_sb_lock);
1897 return 0;
1913 1898
1914 /* 1899unwind:
1915 * If we didn't complete the loop above, then back out 1900 while (--msbp >= msb) {
1916 * any changes made to the superblock. If you add code 1901 error = xfs_mod_incore_sb_unlocked(mp, msbp->msb_field,
1917 * between the loop above and here, make sure that you 1902 -msbp->msb_delta, rsvd);
1918 * preserve the value of status. Loop back until 1903 ASSERT(error == 0);
1919 * we step below the beginning of the array. Make sure
1920 * we don't touch anything back there.
1921 */
1922 if (status != 0) {
1923 msbp--;
1924 while (msbp >= msb) {
1925 switch (msbp->msb_field) {
1926#ifdef HAVE_PERCPU_SB
1927 case XFS_SBS_ICOUNT:
1928 case XFS_SBS_IFREE:
1929 case XFS_SBS_FDBLOCKS:
1930 spin_unlock(&mp->m_sb_lock);
1931 status = xfs_icsb_modify_counters(mp,
1932 msbp->msb_field,
1933 -(msbp->msb_delta),
1934 rsvd);
1935 spin_lock(&mp->m_sb_lock);
1936 break;
1937#endif
1938 default:
1939 status = xfs_mod_incore_sb_unlocked(mp,
1940 msbp->msb_field,
1941 -(msbp->msb_delta),
1942 rsvd);
1943 break;
1944 }
1945 ASSERT(status == 0);
1946 msbp--;
1947 }
1948 } 1904 }
1949 spin_unlock(&mp->m_sb_lock); 1905 spin_unlock(&mp->m_sb_lock);
1950 return status; 1906 return error;
1951} 1907}
1952 1908
1953/* 1909/*
@@ -2478,7 +2434,7 @@ xfs_icsb_balance_counter(
2478 spin_unlock(&mp->m_sb_lock); 2434 spin_unlock(&mp->m_sb_lock);
2479} 2435}
2480 2436
2481STATIC int 2437int
2482xfs_icsb_modify_counters( 2438xfs_icsb_modify_counters(
2483 xfs_mount_t *mp, 2439 xfs_mount_t *mp,
2484 xfs_sb_field_t field, 2440 xfs_sb_field_t field,