diff options
author | Steve French <sfrench@us.ibm.com> | 2008-05-06 13:55:32 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-05-06 13:55:32 -0400 |
commit | a815752ac0ffdb910e92958d41d28f4fb28e5296 (patch) | |
tree | a3aa16a282354da0debe8e3a3a7ed8aac6e54001 /fs/xfs/xfs_mount.c | |
parent | 5ade9deaaa3e1f7291467d97b238648e43eae15e (diff) | |
parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 2fec452afbcc..da3988453b71 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -54,8 +54,9 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *); | |||
54 | #ifdef HAVE_PERCPU_SB | 54 | #ifdef HAVE_PERCPU_SB |
55 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); | 55 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); |
56 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, | 56 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, |
57 | int, int); | 57 | int); |
58 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); | 58 | STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t, |
59 | int); | ||
59 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, | 60 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, |
60 | int64_t, int); | 61 | int64_t, int); |
61 | STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | 62 | STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); |
@@ -63,8 +64,8 @@ STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | |||
63 | #else | 64 | #else |
64 | 65 | ||
65 | #define xfs_icsb_destroy_counters(mp) do { } while (0) | 66 | #define xfs_icsb_destroy_counters(mp) do { } while (0) |
66 | #define xfs_icsb_balance_counter(mp, a, b, c) do { } while (0) | 67 | #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) |
67 | #define xfs_icsb_sync_counters(mp) do { } while (0) | 68 | #define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0) |
68 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) | 69 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) |
69 | 70 | ||
70 | #endif | 71 | #endif |
@@ -1400,7 +1401,7 @@ xfs_log_sbcount( | |||
1400 | if (!xfs_fs_writable(mp)) | 1401 | if (!xfs_fs_writable(mp)) |
1401 | return 0; | 1402 | return 0; |
1402 | 1403 | ||
1403 | xfs_icsb_sync_counters(mp); | 1404 | xfs_icsb_sync_counters(mp, 0); |
1404 | 1405 | ||
1405 | /* | 1406 | /* |
1406 | * we don't need to do this if we are updating the superblock | 1407 | * we don't need to do this if we are updating the superblock |
@@ -2026,9 +2027,9 @@ xfs_icsb_cpu_notify( | |||
2026 | case CPU_ONLINE: | 2027 | case CPU_ONLINE: |
2027 | case CPU_ONLINE_FROZEN: | 2028 | case CPU_ONLINE_FROZEN: |
2028 | xfs_icsb_lock(mp); | 2029 | xfs_icsb_lock(mp); |
2029 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); | 2030 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); |
2030 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); | 2031 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); |
2031 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | 2032 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
2032 | xfs_icsb_unlock(mp); | 2033 | xfs_icsb_unlock(mp); |
2033 | break; | 2034 | break; |
2034 | case CPU_DEAD: | 2035 | case CPU_DEAD: |
@@ -2048,12 +2049,9 @@ xfs_icsb_cpu_notify( | |||
2048 | 2049 | ||
2049 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 2050 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
2050 | 2051 | ||
2051 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, | 2052 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_ICOUNT, 0); |
2052 | XFS_ICSB_SB_LOCKED, 0); | 2053 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_IFREE, 0); |
2053 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, | 2054 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0); |
2054 | XFS_ICSB_SB_LOCKED, 0); | ||
2055 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, | ||
2056 | XFS_ICSB_SB_LOCKED, 0); | ||
2057 | spin_unlock(&mp->m_sb_lock); | 2055 | spin_unlock(&mp->m_sb_lock); |
2058 | xfs_icsb_unlock(mp); | 2056 | xfs_icsb_unlock(mp); |
2059 | break; | 2057 | break; |
@@ -2105,9 +2103,9 @@ xfs_icsb_reinit_counters( | |||
2105 | * initial balance kicks us off correctly | 2103 | * initial balance kicks us off correctly |
2106 | */ | 2104 | */ |
2107 | mp->m_icsb_counters = -1; | 2105 | mp->m_icsb_counters = -1; |
2108 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); | 2106 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); |
2109 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); | 2107 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); |
2110 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | 2108 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
2111 | xfs_icsb_unlock(mp); | 2109 | xfs_icsb_unlock(mp); |
2112 | } | 2110 | } |
2113 | 2111 | ||
@@ -2223,7 +2221,7 @@ xfs_icsb_disable_counter( | |||
2223 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { | 2221 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { |
2224 | /* drain back to superblock */ | 2222 | /* drain back to superblock */ |
2225 | 2223 | ||
2226 | xfs_icsb_count(mp, &cnt, XFS_ICSB_SB_LOCKED|XFS_ICSB_LAZY_COUNT); | 2224 | xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT); |
2227 | switch(field) { | 2225 | switch(field) { |
2228 | case XFS_SBS_ICOUNT: | 2226 | case XFS_SBS_ICOUNT: |
2229 | mp->m_sb.sb_icount = cnt.icsb_icount; | 2227 | mp->m_sb.sb_icount = cnt.icsb_icount; |
@@ -2278,38 +2276,33 @@ xfs_icsb_enable_counter( | |||
2278 | } | 2276 | } |
2279 | 2277 | ||
2280 | void | 2278 | void |
2281 | xfs_icsb_sync_counters_flags( | 2279 | xfs_icsb_sync_counters_locked( |
2282 | xfs_mount_t *mp, | 2280 | xfs_mount_t *mp, |
2283 | int flags) | 2281 | int flags) |
2284 | { | 2282 | { |
2285 | xfs_icsb_cnts_t cnt; | 2283 | xfs_icsb_cnts_t cnt; |
2286 | 2284 | ||
2287 | /* Pass 1: lock all counters */ | ||
2288 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | ||
2289 | spin_lock(&mp->m_sb_lock); | ||
2290 | |||
2291 | xfs_icsb_count(mp, &cnt, flags); | 2285 | xfs_icsb_count(mp, &cnt, flags); |
2292 | 2286 | ||
2293 | /* Step 3: update mp->m_sb fields */ | ||
2294 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT)) | 2287 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT)) |
2295 | mp->m_sb.sb_icount = cnt.icsb_icount; | 2288 | mp->m_sb.sb_icount = cnt.icsb_icount; |
2296 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE)) | 2289 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE)) |
2297 | mp->m_sb.sb_ifree = cnt.icsb_ifree; | 2290 | mp->m_sb.sb_ifree = cnt.icsb_ifree; |
2298 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) | 2291 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) |
2299 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; | 2292 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; |
2300 | |||
2301 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | ||
2302 | spin_unlock(&mp->m_sb_lock); | ||
2303 | } | 2293 | } |
2304 | 2294 | ||
2305 | /* | 2295 | /* |
2306 | * Accurate update of per-cpu counters to incore superblock | 2296 | * Accurate update of per-cpu counters to incore superblock |
2307 | */ | 2297 | */ |
2308 | STATIC void | 2298 | void |
2309 | xfs_icsb_sync_counters( | 2299 | xfs_icsb_sync_counters( |
2310 | xfs_mount_t *mp) | 2300 | xfs_mount_t *mp, |
2301 | int flags) | ||
2311 | { | 2302 | { |
2312 | xfs_icsb_sync_counters_flags(mp, 0); | 2303 | spin_lock(&mp->m_sb_lock); |
2304 | xfs_icsb_sync_counters_locked(mp, flags); | ||
2305 | spin_unlock(&mp->m_sb_lock); | ||
2313 | } | 2306 | } |
2314 | 2307 | ||
2315 | /* | 2308 | /* |
@@ -2332,19 +2325,15 @@ xfs_icsb_sync_counters( | |||
2332 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ | 2325 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ |
2333 | (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp)) | 2326 | (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp)) |
2334 | STATIC void | 2327 | STATIC void |
2335 | xfs_icsb_balance_counter( | 2328 | xfs_icsb_balance_counter_locked( |
2336 | xfs_mount_t *mp, | 2329 | xfs_mount_t *mp, |
2337 | xfs_sb_field_t field, | 2330 | xfs_sb_field_t field, |
2338 | int flags, | ||
2339 | int min_per_cpu) | 2331 | int min_per_cpu) |
2340 | { | 2332 | { |
2341 | uint64_t count, resid; | 2333 | uint64_t count, resid; |
2342 | int weight = num_online_cpus(); | 2334 | int weight = num_online_cpus(); |
2343 | uint64_t min = (uint64_t)min_per_cpu; | 2335 | uint64_t min = (uint64_t)min_per_cpu; |
2344 | 2336 | ||
2345 | if (!(flags & XFS_ICSB_SB_LOCKED)) | ||
2346 | spin_lock(&mp->m_sb_lock); | ||
2347 | |||
2348 | /* disable counter and sync counter */ | 2337 | /* disable counter and sync counter */ |
2349 | xfs_icsb_disable_counter(mp, field); | 2338 | xfs_icsb_disable_counter(mp, field); |
2350 | 2339 | ||
@@ -2354,19 +2343,19 @@ xfs_icsb_balance_counter( | |||
2354 | count = mp->m_sb.sb_icount; | 2343 | count = mp->m_sb.sb_icount; |
2355 | resid = do_div(count, weight); | 2344 | resid = do_div(count, weight); |
2356 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) | 2345 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2357 | goto out; | 2346 | return; |
2358 | break; | 2347 | break; |
2359 | case XFS_SBS_IFREE: | 2348 | case XFS_SBS_IFREE: |
2360 | count = mp->m_sb.sb_ifree; | 2349 | count = mp->m_sb.sb_ifree; |
2361 | resid = do_div(count, weight); | 2350 | resid = do_div(count, weight); |
2362 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) | 2351 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2363 | goto out; | 2352 | return; |
2364 | break; | 2353 | break; |
2365 | case XFS_SBS_FDBLOCKS: | 2354 | case XFS_SBS_FDBLOCKS: |
2366 | count = mp->m_sb.sb_fdblocks; | 2355 | count = mp->m_sb.sb_fdblocks; |
2367 | resid = do_div(count, weight); | 2356 | resid = do_div(count, weight); |
2368 | if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp))) | 2357 | if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp))) |
2369 | goto out; | 2358 | return; |
2370 | break; | 2359 | break; |
2371 | default: | 2360 | default: |
2372 | BUG(); | 2361 | BUG(); |
@@ -2375,9 +2364,17 @@ xfs_icsb_balance_counter( | |||
2375 | } | 2364 | } |
2376 | 2365 | ||
2377 | xfs_icsb_enable_counter(mp, field, count, resid); | 2366 | xfs_icsb_enable_counter(mp, field, count, resid); |
2378 | out: | 2367 | } |
2379 | if (!(flags & XFS_ICSB_SB_LOCKED)) | 2368 | |
2380 | spin_unlock(&mp->m_sb_lock); | 2369 | STATIC void |
2370 | xfs_icsb_balance_counter( | ||
2371 | xfs_mount_t *mp, | ||
2372 | xfs_sb_field_t fields, | ||
2373 | int min_per_cpu) | ||
2374 | { | ||
2375 | spin_lock(&mp->m_sb_lock); | ||
2376 | xfs_icsb_balance_counter_locked(mp, fields, min_per_cpu); | ||
2377 | spin_unlock(&mp->m_sb_lock); | ||
2381 | } | 2378 | } |
2382 | 2379 | ||
2383 | STATIC int | 2380 | STATIC int |
@@ -2484,7 +2481,7 @@ slow_path: | |||
2484 | * we are done. | 2481 | * we are done. |
2485 | */ | 2482 | */ |
2486 | if (ret != ENOSPC) | 2483 | if (ret != ENOSPC) |
2487 | xfs_icsb_balance_counter(mp, field, 0, 0); | 2484 | xfs_icsb_balance_counter(mp, field, 0); |
2488 | xfs_icsb_unlock(mp); | 2485 | xfs_icsb_unlock(mp); |
2489 | return ret; | 2486 | return ret; |
2490 | 2487 | ||
@@ -2508,7 +2505,7 @@ balance_counter: | |||
2508 | * will either succeed through the fast path or slow path without | 2505 | * will either succeed through the fast path or slow path without |
2509 | * another balance operation being required. | 2506 | * another balance operation being required. |
2510 | */ | 2507 | */ |
2511 | xfs_icsb_balance_counter(mp, field, 0, delta); | 2508 | xfs_icsb_balance_counter(mp, field, delta); |
2512 | xfs_icsb_unlock(mp); | 2509 | xfs_icsb_unlock(mp); |
2513 | goto again; | 2510 | goto again; |
2514 | } | 2511 | } |