Blame view

fs/xfs/xfs_filestream.c 8.68 KB
0b61f8a40   Dave Chinner   xfs: convert to S...
1
  // SPDX-License-Identifier: GPL-2.0
2a82b8be8   David Chinner   [XFS] Concurrent ...
2
3
  /*
   * Copyright (c) 2006-2007 Silicon Graphics, Inc.
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
4
   * Copyright (c) 2014 Christoph Hellwig.
2a82b8be8   David Chinner   [XFS] Concurrent ...
5
   * All Rights Reserved.
2a82b8be8   David Chinner   [XFS] Concurrent ...
6
7
   */
  #include "xfs.h"
5467b34bd   Darrick J. Wong   xfs: move xfs_ino...
8
  #include "xfs_shared.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
9
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
10
11
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
239880ef6   Dave Chinner   xfs: decouple log...
12
13
  #include "xfs_sb.h"
  #include "xfs_mount.h"
2a82b8be8   David Chinner   [XFS] Concurrent ...
14
  #include "xfs_inode.h"
2a82b8be8   David Chinner   [XFS] Concurrent ...
15
16
  #include "xfs_bmap.h"
  #include "xfs_alloc.h"
2a82b8be8   David Chinner   [XFS] Concurrent ...
17
  #include "xfs_mru_cache.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
18
  #include "xfs_trace.h"
3fd129b63   Darrick J. Wong   xfs: set up per-A...
19
  #include "xfs_ag_resv.h"
3e3673e30   Brian Foster   xfs: remove struc...
20
  #include "xfs_trans.h"
f368b29ba   Darrick J. Wong   xfs: fix another ...
21
  #include "xfs_filestream.h"
2a82b8be8   David Chinner   [XFS] Concurrent ...
22

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
23
24
  struct xfs_fstrm_item {
  	struct xfs_mru_cache_elem	mru;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
25
26
27
28
29
30
31
  	xfs_agnumber_t			ag; /* AG in use for this directory */
  };
  
  enum xfs_fstrm_alloc {
  	XFS_PICK_USERDATA = 1,
  	XFS_PICK_LOWSPACE = 2,
  };
2a82b8be8   David Chinner   [XFS] Concurrent ...
32

0664ce8d0   Christoph Hellwig   xfs: clean up fil...
33
34
  /*
   * Allocation group filestream associations are tracked with per-ag atomic
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
35
   * counters.  These counters allow xfs_filestream_pick_ag() to tell whether a
b38e07401   Gao Xiang   xfs: drop the obs...
36
   * particular AG already has active filestreams associated with it.
0664ce8d0   Christoph Hellwig   xfs: clean up fil...
37
   */
b94acd478   Christoph Hellwig   xfs: add filestre...
38
  int
0664ce8d0   Christoph Hellwig   xfs: clean up fil...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  xfs_filestream_peek_ag(
  	xfs_mount_t	*mp,
  	xfs_agnumber_t	agno)
  {
  	struct xfs_perag *pag;
  	int		ret;
  
  	pag = xfs_perag_get(mp, agno);
  	ret = atomic_read(&pag->pagf_fstrms);
  	xfs_perag_put(pag);
  	return ret;
  }
  
  static int
  xfs_filestream_get_ag(
  	xfs_mount_t	*mp,
  	xfs_agnumber_t	agno)
  {
  	struct xfs_perag *pag;
  	int		ret;
  
  	pag = xfs_perag_get(mp, agno);
  	ret = atomic_inc_return(&pag->pagf_fstrms);
  	xfs_perag_put(pag);
  	return ret;
  }
  
  static void
  xfs_filestream_put_ag(
  	xfs_mount_t	*mp,
  	xfs_agnumber_t	agno)
  {
  	struct xfs_perag *pag;
  
  	pag = xfs_perag_get(mp, agno);
  	atomic_dec(&pag->pagf_fstrms);
  	xfs_perag_put(pag);
  }
2a82b8be8   David Chinner   [XFS] Concurrent ...
77

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
78
79
  static void
  xfs_fstrm_free_func(
7fcd3efa1   Christoph Hellwig   xfs: remove files...
80
  	void			*data,
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
81
82
  	struct xfs_mru_cache_elem *mru)
  {
7fcd3efa1   Christoph Hellwig   xfs: remove files...
83
  	struct xfs_mount	*mp = data;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
84
85
  	struct xfs_fstrm_item	*item =
  		container_of(mru, struct xfs_fstrm_item, mru);
7fcd3efa1   Christoph Hellwig   xfs: remove files...
86
87
  	xfs_filestream_put_ag(mp, item->ag);
  	trace_xfs_filestream_free(mp, mru->key, item->ag);
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
88

1919adda0   Christoph Hellwig   xfs: don't create...
89
  	kmem_free(item);
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
90
  }
2a82b8be8   David Chinner   [XFS] Concurrent ...
91
92
93
94
95
  /*
   * Scan the AGs starting at startag looking for an AG that isn't in use and has
   * at least minlen blocks free.
   */
  static int
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
96
97
98
99
100
101
  xfs_filestream_pick_ag(
  	struct xfs_inode	*ip,
  	xfs_agnumber_t		startag,
  	xfs_agnumber_t		*agp,
  	int			flags,
  	xfs_extlen_t		minlen)
2a82b8be8   David Chinner   [XFS] Concurrent ...
102
  {
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
103
104
105
  	struct xfs_mount	*mp = ip->i_mount;
  	struct xfs_fstrm_item	*item;
  	struct xfs_perag	*pag;
b94acd478   Christoph Hellwig   xfs: add filestre...
106
  	xfs_extlen_t		longest, free = 0, minfree, maxfree = 0;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
107
  	xfs_agnumber_t		ag, max_ag = NULLAGNUMBER;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
108
  	int			err, trylock, nscan;
c19b3b05a   Dave Chinner   xfs: mode di_mode...
109
  	ASSERT(S_ISDIR(VFS_I(ip)->i_mode));
2a82b8be8   David Chinner   [XFS] Concurrent ...
110
111
112
113
114
115
116
117
118
119
120
  
  	/* 2% of an AG's blocks must be free for it to be chosen. */
  	minfree = mp->m_sb.sb_agblocks / 50;
  
  	ag = startag;
  	*agp = NULLAGNUMBER;
  
  	/* For the first pass, don't sleep trying to init the per-AG. */
  	trylock = XFS_ALLOC_FLAG_TRYLOCK;
  
  	for (nscan = 0; 1; nscan++) {
7fcd3efa1   Christoph Hellwig   xfs: remove files...
121
  		trace_xfs_filestream_scan(mp, ip->i_ino, ag);
b94acd478   Christoph Hellwig   xfs: add filestre...
122

4196ac08c   Dave Chinner   xfs: Convert file...
123
  		pag = xfs_perag_get(mp, ag);
2a82b8be8   David Chinner   [XFS] Concurrent ...
124
125
126
  
  		if (!pag->pagf_init) {
  			err = xfs_alloc_pagf_init(mp, NULL, ag, trylock);
f48e2df8a   Darrick J. Wong   xfs: make xfs_*re...
127
  			if (err) {
4196ac08c   Dave Chinner   xfs: Convert file...
128
  				xfs_perag_put(pag);
f48e2df8a   Darrick J. Wong   xfs: make xfs_*re...
129
130
131
132
  				if (err != -EAGAIN)
  					return err;
  				/* Couldn't lock the AGF, skip this AG. */
  				continue;
4196ac08c   Dave Chinner   xfs: Convert file...
133
  			}
2a82b8be8   David Chinner   [XFS] Concurrent ...
134
  		}
2a82b8be8   David Chinner   [XFS] Concurrent ...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  		/* Keep track of the AG with the most free blocks. */
  		if (pag->pagf_freeblks > maxfree) {
  			maxfree = pag->pagf_freeblks;
  			max_ag = ag;
  		}
  
  		/*
  		 * The AG reference count does two things: it enforces mutual
  		 * exclusion when examining the suitability of an AG in this
  		 * loop, and it guards against two filestreams being established
  		 * in the same AG as each other.
  		 */
  		if (xfs_filestream_get_ag(mp, ag) > 1) {
  			xfs_filestream_put_ag(mp, ag);
  			goto next_ag;
  		}
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
151
  		longest = xfs_alloc_longest_free_extent(pag,
3fd129b63   Darrick J. Wong   xfs: set up per-A...
152
153
  				xfs_alloc_min_freelist(mp, pag),
  				xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE));
2a82b8be8   David Chinner   [XFS] Concurrent ...
154
155
156
157
158
159
160
  		if (((minlen && longest >= minlen) ||
  		     (!minlen && pag->pagf_freeblks >= minfree)) &&
  		    (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) ||
  		     (flags & XFS_PICK_LOWSPACE))) {
  
  			/* Break out, retaining the reference on the AG. */
  			free = pag->pagf_freeblks;
4196ac08c   Dave Chinner   xfs: Convert file...
161
  			xfs_perag_put(pag);
2a82b8be8   David Chinner   [XFS] Concurrent ...
162
163
164
165
166
167
168
  			*agp = ag;
  			break;
  		}
  
  		/* Drop the reference on this AG, it's not usable. */
  		xfs_filestream_put_ag(mp, ag);
  next_ag:
4196ac08c   Dave Chinner   xfs: Convert file...
169
  		xfs_perag_put(pag);
2a82b8be8   David Chinner   [XFS] Concurrent ...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  		/* Move to the next AG, wrapping to AG 0 if necessary. */
  		if (++ag >= mp->m_sb.sb_agcount)
  			ag = 0;
  
  		/* If a full pass of the AGs hasn't been done yet, continue. */
  		if (ag != startag)
  			continue;
  
  		/* Allow sleeping in xfs_alloc_pagf_init() on the 2nd pass. */
  		if (trylock != 0) {
  			trylock = 0;
  			continue;
  		}
  
  		/* Finally, if lowspace wasn't set, set it for the 3rd pass. */
  		if (!(flags & XFS_PICK_LOWSPACE)) {
  			flags |= XFS_PICK_LOWSPACE;
  			continue;
  		}
  
  		/*
  		 * Take the AG with the most free space, regardless of whether
  		 * it's already in use by another filestream.
  		 */
  		if (max_ag != NULLAGNUMBER) {
  			xfs_filestream_get_ag(mp, max_ag);
2a82b8be8   David Chinner   [XFS] Concurrent ...
196
197
198
199
200
201
  			free = maxfree;
  			*agp = max_ag;
  			break;
  		}
  
  		/* take AG 0 if none matched */
b94acd478   Christoph Hellwig   xfs: add filestre...
202
  		trace_xfs_filestream_pick(ip, *agp, free, nscan);
2a82b8be8   David Chinner   [XFS] Concurrent ...
203
204
205
  		*agp = 0;
  		return 0;
  	}
b94acd478   Christoph Hellwig   xfs: add filestre...
206
  	trace_xfs_filestream_pick(ip, *agp, free, nscan);
2a82b8be8   David Chinner   [XFS] Concurrent ...
207

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
208
  	if (*agp == NULLAGNUMBER)
2a82b8be8   David Chinner   [XFS] Concurrent ...
209
  		return 0;
2a82b8be8   David Chinner   [XFS] Concurrent ...
210

2451337dd   Dave Chinner   xfs: global error...
211
  	err = -ENOMEM;
1919adda0   Christoph Hellwig   xfs: don't create...
212
  	item = kmem_alloc(sizeof(*item), KM_MAYFAIL);
2a82b8be8   David Chinner   [XFS] Concurrent ...
213
  	if (!item)
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
214
  		goto out_put_ag;
2a82b8be8   David Chinner   [XFS] Concurrent ...
215

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
216
  	item->ag = *agp;
2a82b8be8   David Chinner   [XFS] Concurrent ...
217

22328d712   Christoph Hellwig   xfs: embedd mru_e...
218
  	err = xfs_mru_cache_insert(mp->m_filestream, ip->i_ino, &item->mru);
2a82b8be8   David Chinner   [XFS] Concurrent ...
219
  	if (err) {
2451337dd   Dave Chinner   xfs: global error...
220
  		if (err == -EEXIST)
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
221
222
  			err = 0;
  		goto out_free_item;
2a82b8be8   David Chinner   [XFS] Concurrent ...
223
  	}
2a82b8be8   David Chinner   [XFS] Concurrent ...
224
  	return 0;
2a82b8be8   David Chinner   [XFS] Concurrent ...
225

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
226
  out_free_item:
1919adda0   Christoph Hellwig   xfs: don't create...
227
  	kmem_free(item);
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
228
229
230
  out_put_ag:
  	xfs_filestream_put_ag(mp, *agp);
  	return err;
2a82b8be8   David Chinner   [XFS] Concurrent ...
231
  }
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
232
233
234
  static struct xfs_inode *
  xfs_filestream_get_parent(
  	struct xfs_inode	*ip)
2a82b8be8   David Chinner   [XFS] Concurrent ...
235
  {
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
236
237
  	struct inode		*inode = VFS_I(ip), *dir = NULL;
  	struct dentry		*dentry, *parent;
2a82b8be8   David Chinner   [XFS] Concurrent ...
238

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
239
240
241
  	dentry = d_find_alias(inode);
  	if (!dentry)
  		goto out;
2a82b8be8   David Chinner   [XFS] Concurrent ...
242

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
243
244
245
  	parent = dget_parent(dentry);
  	if (!parent)
  		goto out_dput;
2a82b8be8   David Chinner   [XFS] Concurrent ...
246

2b0143b5c   David Howells   VFS: normal files...
247
  	dir = igrab(d_inode(parent));
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
248
  	dput(parent);
2a82b8be8   David Chinner   [XFS] Concurrent ...
249

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
250
251
252
253
  out_dput:
  	dput(dentry);
  out:
  	return dir ? XFS_I(dir) : NULL;
2a82b8be8   David Chinner   [XFS] Concurrent ...
254
255
256
  }
  
  /*
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
257
258
259
260
   * Find the right allocation group for a file, either by finding an
   * existing file stream or creating a new one.
   *
   * Returns NULLAGNUMBER in case of an error.
2a82b8be8   David Chinner   [XFS] Concurrent ...
261
262
263
   */
  xfs_agnumber_t
  xfs_filestream_lookup_ag(
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
264
  	struct xfs_inode	*ip)
2a82b8be8   David Chinner   [XFS] Concurrent ...
265
  {
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
266
  	struct xfs_mount	*mp = ip->i_mount;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
267
  	struct xfs_inode	*pip = NULL;
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
268
  	xfs_agnumber_t		startag, ag = NULLAGNUMBER;
22328d712   Christoph Hellwig   xfs: embedd mru_e...
269
  	struct xfs_mru_cache_elem *mru;
2a82b8be8   David Chinner   [XFS] Concurrent ...
270

c19b3b05a   Dave Chinner   xfs: mode di_mode...
271
  	ASSERT(S_ISREG(VFS_I(ip)->i_mode));
2a82b8be8   David Chinner   [XFS] Concurrent ...
272

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
273
274
  	pip = xfs_filestream_get_parent(ip);
  	if (!pip)
b26384dc5   Eric Sandeen   xfs: fix NULL poi...
275
  		return NULLAGNUMBER;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
276
277
  
  	mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino);
22328d712   Christoph Hellwig   xfs: embedd mru_e...
278
  	if (mru) {
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
279
  		ag = container_of(mru, struct xfs_fstrm_item, mru)->ag;
22328d712   Christoph Hellwig   xfs: embedd mru_e...
280
  		xfs_mru_cache_done(mp->m_filestream);
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
281

7fcd3efa1   Christoph Hellwig   xfs: remove files...
282
  		trace_xfs_filestream_lookup(mp, ip->i_ino, ag);
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
283
  		goto out;
2a82b8be8   David Chinner   [XFS] Concurrent ...
284
285
286
287
288
289
290
  	}
  
  	/*
  	 * Set the starting AG using the rotor for inode32, otherwise
  	 * use the directory inode's AG.
  	 */
  	if (mp->m_flags & XFS_MOUNT_32BITINODES) {
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
291
  		xfs_agnumber_t	 rotorstep = xfs_rotorstep;
2a82b8be8   David Chinner   [XFS] Concurrent ...
292
293
294
295
296
  		startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount;
  		mp->m_agfrotor = (mp->m_agfrotor + 1) %
  		                 (mp->m_sb.sb_agcount * rotorstep);
  	} else
  		startag = XFS_INO_TO_AGNO(mp, pip->i_ino);
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
297
298
299
  	if (xfs_filestream_pick_ag(pip, startag, &ag, 0, 0))
  		ag = NULLAGNUMBER;
  out:
44a8736bd   Darrick J. Wong   xfs: clean up IRE...
300
  	xfs_irele(pip);
3b8d90766   Christoph Hellwig   xfs: remove xfs_f...
301
  	return ag;
2a82b8be8   David Chinner   [XFS] Concurrent ...
302
303
304
  }
  
  /*
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
305
306
307
308
   * Pick a new allocation group for the current file and its file stream.
   *
   * This is called when the allocator can't find a suitable extent in the
   * current AG, and we have to move the stream into a new AG with more space.
2a82b8be8   David Chinner   [XFS] Concurrent ...
309
310
311
   */
  int
  xfs_filestream_new_ag(
689881145   Dave Chinner   xfs: create xfs_b...
312
313
  	struct xfs_bmalloca	*ap,
  	xfs_agnumber_t		*agp)
2a82b8be8   David Chinner   [XFS] Concurrent ...
314
  {
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
315
316
317
318
  	struct xfs_inode	*ip = ap->ip, *pip;
  	struct xfs_mount	*mp = ip->i_mount;
  	xfs_extlen_t		minlen = ap->length;
  	xfs_agnumber_t		startag = 0;
292378edc   Dave Chinner   xfs: remote attri...
319
320
  	int			flags = 0;
  	int			err = 0;
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
321
  	struct xfs_mru_cache_elem *mru;
2a82b8be8   David Chinner   [XFS] Concurrent ...
322

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
323
  	*agp = NULLAGNUMBER;
2a82b8be8   David Chinner   [XFS] Concurrent ...
324

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
325
326
327
  	pip = xfs_filestream_get_parent(ip);
  	if (!pip)
  		goto exit;
2a82b8be8   David Chinner   [XFS] Concurrent ...
328

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
329
330
331
332
333
  	mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino);
  	if (mru) {
  		struct xfs_fstrm_item *item =
  			container_of(mru, struct xfs_fstrm_item, mru);
  		startag = (item->ag + 1) % mp->m_sb.sb_agcount;
2a82b8be8   David Chinner   [XFS] Concurrent ...
334
  	}
c34d570d1   Christoph Hellwig   xfs: cleanup use ...
335
  	if (ap->datatype & XFS_ALLOC_USERDATA)
292378edc   Dave Chinner   xfs: remote attri...
336
  		flags |= XFS_PICK_USERDATA;
1214f1cf6   Brian Foster   xfs: replace dop_...
337
  	if (ap->tp->t_flags & XFS_TRANS_LOWMODE)
292378edc   Dave Chinner   xfs: remote attri...
338
  		flags |= XFS_PICK_LOWSPACE;
2a82b8be8   David Chinner   [XFS] Concurrent ...
339

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
340
  	err = xfs_filestream_pick_ag(pip, startag, agp, flags, minlen);
2a82b8be8   David Chinner   [XFS] Concurrent ...
341
342
  
  	/*
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
343
  	 * Only free the item here so we skip over the old AG earlier.
2a82b8be8   David Chinner   [XFS] Concurrent ...
344
  	 */
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
345
  	if (mru)
7fcd3efa1   Christoph Hellwig   xfs: remove files...
346
  		xfs_fstrm_free_func(mp, mru);
2a82b8be8   David Chinner   [XFS] Concurrent ...
347

44a8736bd   Darrick J. Wong   xfs: clean up IRE...
348
  	xfs_irele(pip);
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
349
350
351
352
353
  exit:
  	if (*agp == NULLAGNUMBER)
  		*agp = 0;
  	return err;
  }
2a82b8be8   David Chinner   [XFS] Concurrent ...
354

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
355
356
357
358
359
360
  void
  xfs_filestream_deassociate(
  	struct xfs_inode	*ip)
  {
  	xfs_mru_cache_delete(ip->i_mount->m_filestream, ip->i_ino);
  }
2a82b8be8   David Chinner   [XFS] Concurrent ...
361

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
362
363
364
365
  int
  xfs_filestream_mount(
  	xfs_mount_t	*mp)
  {
2a82b8be8   David Chinner   [XFS] Concurrent ...
366
  	/*
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
367
368
369
370
371
  	 * The filestream timer tunable is currently fixed within the range of
  	 * one second to four minutes, with five seconds being the default.  The
  	 * group count is somewhat arbitrary, but it'd be nice to adhere to the
  	 * timer tunable to within about 10 percent.  This requires at least 10
  	 * groups.
2a82b8be8   David Chinner   [XFS] Concurrent ...
372
  	 */
7fcd3efa1   Christoph Hellwig   xfs: remove files...
373
374
  	return xfs_mru_cache_create(&mp->m_filestream, mp,
  			xfs_fstrm_centisecs * 10, 10, xfs_fstrm_free_func);
2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
375
  }
2a82b8be8   David Chinner   [XFS] Concurrent ...
376

2cd2ef6a3   Christoph Hellwig   xfs: rewrite the ...
377
378
379
380
381
382
  void
  xfs_filestream_unmount(
  	xfs_mount_t	*mp)
  {
  	xfs_mru_cache_destroy(mp->m_filestream);
  }