diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/xfs/xfs_filestream.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/xfs/xfs_filestream.c')
-rw-r--r-- | fs/xfs/xfs_filestream.c | 50 |
1 files changed, 16 insertions, 34 deletions
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index edf8bdf4141f..390850ee6603 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "xfs_utils.h" | 34 | #include "xfs_utils.h" |
35 | #include "xfs_mru_cache.h" | 35 | #include "xfs_mru_cache.h" |
36 | #include "xfs_filestream.h" | 36 | #include "xfs_filestream.h" |
37 | #include "xfs_trace.h" | ||
37 | 38 | ||
38 | #ifdef XFS_FILESTREAMS_TRACE | 39 | #ifdef XFS_FILESTREAMS_TRACE |
39 | 40 | ||
@@ -139,6 +140,7 @@ _xfs_filestream_pick_ag( | |||
139 | int flags, | 140 | int flags, |
140 | xfs_extlen_t minlen) | 141 | xfs_extlen_t minlen) |
141 | { | 142 | { |
143 | int streams, max_streams; | ||
142 | int err, trylock, nscan; | 144 | int err, trylock, nscan; |
143 | xfs_extlen_t longest, free, minfree, maxfree = 0; | 145 | xfs_extlen_t longest, free, minfree, maxfree = 0; |
144 | xfs_agnumber_t ag, max_ag = NULLAGNUMBER; | 146 | xfs_agnumber_t ag, max_ag = NULLAGNUMBER; |
@@ -154,15 +156,15 @@ _xfs_filestream_pick_ag( | |||
154 | trylock = XFS_ALLOC_FLAG_TRYLOCK; | 156 | trylock = XFS_ALLOC_FLAG_TRYLOCK; |
155 | 157 | ||
156 | for (nscan = 0; 1; nscan++) { | 158 | for (nscan = 0; 1; nscan++) { |
157 | 159 | pag = xfs_perag_get(mp, ag); | |
158 | TRACE_AG_SCAN(mp, ag, xfs_filestream_peek_ag(mp, ag)); | 160 | TRACE_AG_SCAN(mp, ag, atomic_read(&pag->pagf_fstrms)); |
159 | |||
160 | pag = mp->m_perag + ag; | ||
161 | 161 | ||
162 | if (!pag->pagf_init) { | 162 | if (!pag->pagf_init) { |
163 | err = xfs_alloc_pagf_init(mp, NULL, ag, trylock); | 163 | err = xfs_alloc_pagf_init(mp, NULL, ag, trylock); |
164 | if (err && !trylock) | 164 | if (err && !trylock) { |
165 | xfs_perag_put(pag); | ||
165 | return err; | 166 | return err; |
167 | } | ||
166 | } | 168 | } |
167 | 169 | ||
168 | /* Might fail sometimes during the 1st pass with trylock set. */ | 170 | /* Might fail sometimes during the 1st pass with trylock set. */ |
@@ -172,6 +174,7 @@ _xfs_filestream_pick_ag( | |||
172 | /* Keep track of the AG with the most free blocks. */ | 174 | /* Keep track of the AG with the most free blocks. */ |
173 | if (pag->pagf_freeblks > maxfree) { | 175 | if (pag->pagf_freeblks > maxfree) { |
174 | maxfree = pag->pagf_freeblks; | 176 | maxfree = pag->pagf_freeblks; |
177 | max_streams = atomic_read(&pag->pagf_fstrms); | ||
175 | max_ag = ag; | 178 | max_ag = ag; |
176 | } | 179 | } |
177 | 180 | ||
@@ -194,6 +197,8 @@ _xfs_filestream_pick_ag( | |||
194 | 197 | ||
195 | /* Break out, retaining the reference on the AG. */ | 198 | /* Break out, retaining the reference on the AG. */ |
196 | free = pag->pagf_freeblks; | 199 | free = pag->pagf_freeblks; |
200 | streams = atomic_read(&pag->pagf_fstrms); | ||
201 | xfs_perag_put(pag); | ||
197 | *agp = ag; | 202 | *agp = ag; |
198 | break; | 203 | break; |
199 | } | 204 | } |
@@ -201,6 +206,7 @@ _xfs_filestream_pick_ag( | |||
201 | /* Drop the reference on this AG, it's not usable. */ | 206 | /* Drop the reference on this AG, it's not usable. */ |
202 | xfs_filestream_put_ag(mp, ag); | 207 | xfs_filestream_put_ag(mp, ag); |
203 | next_ag: | 208 | next_ag: |
209 | xfs_perag_put(pag); | ||
204 | /* Move to the next AG, wrapping to AG 0 if necessary. */ | 210 | /* Move to the next AG, wrapping to AG 0 if necessary. */ |
205 | if (++ag >= mp->m_sb.sb_agcount) | 211 | if (++ag >= mp->m_sb.sb_agcount) |
206 | ag = 0; | 212 | ag = 0; |
@@ -228,6 +234,7 @@ next_ag: | |||
228 | if (max_ag != NULLAGNUMBER) { | 234 | if (max_ag != NULLAGNUMBER) { |
229 | xfs_filestream_get_ag(mp, max_ag); | 235 | xfs_filestream_get_ag(mp, max_ag); |
230 | TRACE_AG_PICK1(mp, max_ag, maxfree); | 236 | TRACE_AG_PICK1(mp, max_ag, maxfree); |
237 | streams = max_streams; | ||
231 | free = maxfree; | 238 | free = maxfree; |
232 | *agp = max_ag; | 239 | *agp = max_ag; |
233 | break; | 240 | break; |
@@ -239,16 +246,14 @@ next_ag: | |||
239 | return 0; | 246 | return 0; |
240 | } | 247 | } |
241 | 248 | ||
242 | TRACE_AG_PICK2(mp, startag, *agp, xfs_filestream_peek_ag(mp, *agp), | 249 | TRACE_AG_PICK2(mp, startag, *agp, streams, free, nscan, flags); |
243 | free, nscan, flags); | ||
244 | 250 | ||
245 | return 0; | 251 | return 0; |
246 | } | 252 | } |
247 | 253 | ||
248 | /* | 254 | /* |
249 | * Set the allocation group number for a file or a directory, updating inode | 255 | * Set the allocation group number for a file or a directory, updating inode |
250 | * references and per-AG references as appropriate. Must be called with the | 256 | * references and per-AG references as appropriate. |
251 | * m_peraglock held in read mode. | ||
252 | */ | 257 | */ |
253 | static int | 258 | static int |
254 | _xfs_filestream_update_ag( | 259 | _xfs_filestream_update_ag( |
@@ -394,9 +399,7 @@ xfs_filestream_init(void) | |||
394 | item_zone = kmem_zone_init(sizeof(fstrm_item_t), "fstrm_item"); | 399 | item_zone = kmem_zone_init(sizeof(fstrm_item_t), "fstrm_item"); |
395 | if (!item_zone) | 400 | if (!item_zone) |
396 | return -ENOMEM; | 401 | return -ENOMEM; |
397 | #ifdef XFS_FILESTREAMS_TRACE | 402 | |
398 | xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_NOFS); | ||
399 | #endif | ||
400 | return 0; | 403 | return 0; |
401 | } | 404 | } |
402 | 405 | ||
@@ -407,9 +410,6 @@ xfs_filestream_init(void) | |||
407 | void | 410 | void |
408 | xfs_filestream_uninit(void) | 411 | xfs_filestream_uninit(void) |
409 | { | 412 | { |
410 | #ifdef XFS_FILESTREAMS_TRACE | ||
411 | ktrace_free(xfs_filestreams_trace_buf); | ||
412 | #endif | ||
413 | kmem_zone_destroy(item_zone); | 413 | kmem_zone_destroy(item_zone); |
414 | } | 414 | } |
415 | 415 | ||
@@ -455,20 +455,6 @@ xfs_filestream_unmount( | |||
455 | } | 455 | } |
456 | 456 | ||
457 | /* | 457 | /* |
458 | * If the mount point's m_perag array is going to be reallocated, all | ||
459 | * outstanding cache entries must be flushed to avoid accessing reference count | ||
460 | * addresses that have been freed. The call to xfs_filestream_flush() must be | ||
461 | * made inside the block that holds the m_peraglock in write mode to do the | ||
462 | * reallocation. | ||
463 | */ | ||
464 | void | ||
465 | xfs_filestream_flush( | ||
466 | xfs_mount_t *mp) | ||
467 | { | ||
468 | xfs_mru_cache_flush(mp->m_filestream); | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Return the AG of the filestream the file or directory belongs to, or | 458 | * Return the AG of the filestream the file or directory belongs to, or |
473 | * NULLAGNUMBER otherwise. | 459 | * NULLAGNUMBER otherwise. |
474 | */ | 460 | */ |
@@ -530,7 +516,6 @@ xfs_filestream_associate( | |||
530 | 516 | ||
531 | mp = pip->i_mount; | 517 | mp = pip->i_mount; |
532 | cache = mp->m_filestream; | 518 | cache = mp->m_filestream; |
533 | down_read(&mp->m_peraglock); | ||
534 | 519 | ||
535 | /* | 520 | /* |
536 | * We have a problem, Houston. | 521 | * We have a problem, Houston. |
@@ -547,10 +532,8 @@ xfs_filestream_associate( | |||
547 | * | 532 | * |
548 | * So, if we can't get the iolock without sleeping then just give up | 533 | * So, if we can't get the iolock without sleeping then just give up |
549 | */ | 534 | */ |
550 | if (!xfs_ilock_nowait(pip, XFS_IOLOCK_EXCL)) { | 535 | if (!xfs_ilock_nowait(pip, XFS_IOLOCK_EXCL)) |
551 | up_read(&mp->m_peraglock); | ||
552 | return 1; | 536 | return 1; |
553 | } | ||
554 | 537 | ||
555 | /* If the parent directory is already in the cache, use its AG. */ | 538 | /* If the parent directory is already in the cache, use its AG. */ |
556 | item = xfs_mru_cache_lookup(cache, pip->i_ino); | 539 | item = xfs_mru_cache_lookup(cache, pip->i_ino); |
@@ -605,7 +588,6 @@ exit_did_pick: | |||
605 | 588 | ||
606 | exit: | 589 | exit: |
607 | xfs_iunlock(pip, XFS_IOLOCK_EXCL); | 590 | xfs_iunlock(pip, XFS_IOLOCK_EXCL); |
608 | up_read(&mp->m_peraglock); | ||
609 | return -err; | 591 | return -err; |
610 | } | 592 | } |
611 | 593 | ||