aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_filestream.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/xfs/xfs_filestream.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c50
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);
203next_ag: 208next_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 */
253static int 258static 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)
407void 410void
408xfs_filestream_uninit(void) 411xfs_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 */
464void
465xfs_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
606exit: 589exit:
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