diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-09-29 22:25:56 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-10-18 16:08:00 -0400 |
commit | 1b0407125f9a5be63e861eb27c8af9e32f20619c (patch) | |
tree | 206f43a7131ad11b8c603247254a8eb9aa2fc17e /fs/xfs/xfs_mount.c | |
parent | 96540c78583a417113df4d027e6b68a595ab9a09 (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.c | 114 |
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 | */ |
1869 | int | 1870 | int |
1870 | xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | 1871 | xfs_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 | /* | 1899 | unwind: |
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 | ||
2481 | STATIC int | 2437 | int |
2482 | xfs_icsb_modify_counters( | 2438 | xfs_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, |