Blame view

fs/xfs/xfs_super.c 55.7 KB
0b61f8a40   Dave Chinner   xfs: convert to S...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
a805bad5d   Nathan Scott   [XFS] Remove unne...
3
   * Copyright (c) 2000-2006 Silicon Graphics, Inc.
7b7187698   Nathan Scott   [XFS] Update lice...
4
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   */
0b1b213fc   Christoph Hellwig   xfs: event tracin...
6

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
  #include "xfs.h"
70a9883c5   Dave Chinner   xfs: create a sha...
8
  #include "xfs_shared.h"
6ca1c9063   Dave Chinner   xfs: separate dqu...
9
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
10
11
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
  #include "xfs_sb.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
  #include "xfs_mount.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include "xfs_inode.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
15
  #include "xfs_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include "xfs_bmap.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
17
  #include "xfs_alloc.h"
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
18
  #include "xfs_fsops.h"
239880ef6   Dave Chinner   xfs: decouple log...
19
  #include "xfs_trans.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include "xfs_buf_item.h"
239880ef6   Dave Chinner   xfs: decouple log...
21
  #include "xfs_log.h"
a67d7c5f5   David Chinner   [XFS] Move platfo...
22
  #include "xfs_log_priv.h"
2b9ab5ab9   Dave Chinner   xfs: reshuffle di...
23
  #include "xfs_dir2.h"
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
24
25
26
  #include "xfs_extfree_item.h"
  #include "xfs_mru_cache.h"
  #include "xfs_inode_item.h"
6d8b79cfc   Dave Chinner   xfs: rename xfs_s...
27
  #include "xfs_icache.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
28
  #include "xfs_trace.h"
3ebe7d2d7   Dave Chinner   xfs: Inode create...
29
  #include "xfs_icreate_item.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
30
31
  #include "xfs_filestream.h"
  #include "xfs_quota.h"
65b65735f   Brian Foster   xfs: add debug sy...
32
  #include "xfs_sysfs.h"
30cbc591c   Darrick J. Wong   xfs: check sizes ...
33
  #include "xfs_ondisk.h"
5880f2d78   Darrick J. Wong   xfs: create rmap ...
34
  #include "xfs_rmap_item.h"
baf4bcacb   Darrick J. Wong   xfs: create refco...
35
  #include "xfs_refcount_item.h"
6413a0142   Darrick J. Wong   xfs: create bmbt ...
36
  #include "xfs_bmap_item.h"
5e7e605c4   Darrick J. Wong   xfs: cancel pendi...
37
  #include "xfs_reflink.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38

dddde68b8   Adam Borowski   xfs: add a define...
39
  #include <linux/magic.h>
73e5fff98   Ian Kent   xfs: switch to us...
40
41
  #include <linux/fs_context.h>
  #include <linux/fs_parser.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42

b87221de6   Alexey Dobriyan   const: mark remai...
43
  static const struct super_operations xfs_super_operations;
65b65735f   Brian Foster   xfs: add debug sy...
44

e3aed1a08   Dave Chinner   xfs: xfs_kset sho...
45
  static struct kset *xfs_kset;		/* top-level xfs sysfs dir */
65b65735f   Brian Foster   xfs: add debug sy...
46
47
48
  #ifdef DEBUG
  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs attrs */
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
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
77
78
79
80
81
  enum xfs_dax_mode {
  	XFS_DAX_INODE = 0,
  	XFS_DAX_ALWAYS = 1,
  	XFS_DAX_NEVER = 2,
  };
  
  static void
  xfs_mount_set_dax_mode(
  	struct xfs_mount	*mp,
  	enum xfs_dax_mode	mode)
  {
  	switch (mode) {
  	case XFS_DAX_INODE:
  		mp->m_flags &= ~(XFS_MOUNT_DAX_ALWAYS | XFS_MOUNT_DAX_NEVER);
  		break;
  	case XFS_DAX_ALWAYS:
  		mp->m_flags |= XFS_MOUNT_DAX_ALWAYS;
  		mp->m_flags &= ~XFS_MOUNT_DAX_NEVER;
  		break;
  	case XFS_DAX_NEVER:
  		mp->m_flags |= XFS_MOUNT_DAX_NEVER;
  		mp->m_flags &= ~XFS_MOUNT_DAX_ALWAYS;
  		break;
  	}
  }
  
  static const struct constant_table dax_param_enums[] = {
  	{"inode",	XFS_DAX_INODE },
  	{"always",	XFS_DAX_ALWAYS },
  	{"never",	XFS_DAX_NEVER },
  	{}
  };
62a877e35   Christoph Hellwig   [XFS] fix mount o...
82
83
  /*
   * Table driven mount option parser.
62a877e35   Christoph Hellwig   [XFS] fix mount o...
84
85
   */
  enum {
8da57c5c0   Ian Kent   xfs: remove the b...
86
  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev,
2e74af0e1   Eric Sandeen   xfs: convert moun...
87
  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
940792857   Christoph Hellwig   xfs: don't parse ...
88
  	Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups,
1c02d502c   Eric Sandeen   xfs: remove depre...
89
90
91
92
  	Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep,
  	Opt_noikeep, Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2,
  	Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota,
  	Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota,
2e74af0e1   Eric Sandeen   xfs: convert moun...
93
  	Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
94
  	Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum,
62a877e35   Christoph Hellwig   [XFS] fix mount o...
95
  };
d7167b149   Al Viro   fs_parse: fold fs...
96
  static const struct fs_parameter_spec xfs_fs_parameters[] = {
73e5fff98   Ian Kent   xfs: switch to us...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  	fsparam_u32("logbufs",		Opt_logbufs),
  	fsparam_string("logbsize",	Opt_logbsize),
  	fsparam_string("logdev",	Opt_logdev),
  	fsparam_string("rtdev",		Opt_rtdev),
  	fsparam_flag("wsync",		Opt_wsync),
  	fsparam_flag("noalign",		Opt_noalign),
  	fsparam_flag("swalloc",		Opt_swalloc),
  	fsparam_u32("sunit",		Opt_sunit),
  	fsparam_u32("swidth",		Opt_swidth),
  	fsparam_flag("nouuid",		Opt_nouuid),
  	fsparam_flag("grpid",		Opt_grpid),
  	fsparam_flag("nogrpid",		Opt_nogrpid),
  	fsparam_flag("bsdgroups",	Opt_bsdgroups),
  	fsparam_flag("sysvgroups",	Opt_sysvgroups),
  	fsparam_string("allocsize",	Opt_allocsize),
  	fsparam_flag("norecovery",	Opt_norecovery),
  	fsparam_flag("inode64",		Opt_inode64),
  	fsparam_flag("inode32",		Opt_inode32),
  	fsparam_flag("ikeep",		Opt_ikeep),
  	fsparam_flag("noikeep",		Opt_noikeep),
  	fsparam_flag("largeio",		Opt_largeio),
  	fsparam_flag("nolargeio",	Opt_nolargeio),
  	fsparam_flag("attr2",		Opt_attr2),
  	fsparam_flag("noattr2",		Opt_noattr2),
  	fsparam_flag("filestreams",	Opt_filestreams),
  	fsparam_flag("quota",		Opt_quota),
  	fsparam_flag("noquota",		Opt_noquota),
  	fsparam_flag("usrquota",	Opt_usrquota),
  	fsparam_flag("grpquota",	Opt_grpquota),
  	fsparam_flag("prjquota",	Opt_prjquota),
  	fsparam_flag("uquota",		Opt_uquota),
  	fsparam_flag("gquota",		Opt_gquota),
  	fsparam_flag("pquota",		Opt_pquota),
  	fsparam_flag("uqnoenforce",	Opt_uqnoenforce),
  	fsparam_flag("gqnoenforce",	Opt_gqnoenforce),
  	fsparam_flag("pqnoenforce",	Opt_pqnoenforce),
  	fsparam_flag("qnoenforce",	Opt_qnoenforce),
  	fsparam_flag("discard",		Opt_discard),
  	fsparam_flag("nodiscard",	Opt_nodiscard),
  	fsparam_flag("dax",		Opt_dax),
8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
137
  	fsparam_enum("dax",		Opt_dax_enum, dax_param_enums),
73e5fff98   Ian Kent   xfs: switch to us...
138
  	{}
62a877e35   Christoph Hellwig   [XFS] fix mount o...
139
  };
a67d7c5f5   David Chinner   [XFS] Move platfo...
140
  struct proc_xfs_info {
cbe4dab11   Dave Chinner   xfs: add initial ...
141
142
  	uint64_t	flag;
  	char		*str;
a67d7c5f5   David Chinner   [XFS] Move platfo...
143
  };
21f55993e   Christoph Hellwig   xfs: merge xfs_sh...
144
145
146
147
  static int
  xfs_fs_show_options(
  	struct seq_file		*m,
  	struct dentry		*root)
a67d7c5f5   David Chinner   [XFS] Move platfo...
148
149
150
  {
  	static struct proc_xfs_info xfs_info_set[] = {
  		/* the few simple ones we can get from the mount struct */
2e74af0e1   Eric Sandeen   xfs: convert moun...
151
152
153
154
155
156
157
158
159
160
  		{ XFS_MOUNT_IKEEP,		",ikeep" },
  		{ XFS_MOUNT_WSYNC,		",wsync" },
  		{ XFS_MOUNT_NOALIGN,		",noalign" },
  		{ XFS_MOUNT_SWALLOC,		",swalloc" },
  		{ XFS_MOUNT_NOUUID,		",nouuid" },
  		{ XFS_MOUNT_NORECOVERY,		",norecovery" },
  		{ XFS_MOUNT_ATTR2,		",attr2" },
  		{ XFS_MOUNT_FILESTREAMS,	",filestreams" },
  		{ XFS_MOUNT_GRPID,		",grpid" },
  		{ XFS_MOUNT_DISCARD,		",discard" },
7c6b94b1b   Christoph Hellwig   xfs: reverse the ...
161
  		{ XFS_MOUNT_LARGEIO,		",largeio" },
8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
162
163
  		{ XFS_MOUNT_DAX_ALWAYS,		",dax=always" },
  		{ XFS_MOUNT_DAX_NEVER,		",dax=never" },
a67d7c5f5   David Chinner   [XFS] Move platfo...
164
165
  		{ 0, NULL }
  	};
21f55993e   Christoph Hellwig   xfs: merge xfs_sh...
166
  	struct xfs_mount	*mp = XFS_M(root->d_sb);
a67d7c5f5   David Chinner   [XFS] Move platfo...
167
168
169
170
171
172
  	struct proc_xfs_info	*xfs_infop;
  
  	for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) {
  		if (mp->m_flags & xfs_infop->flag)
  			seq_puts(m, xfs_infop->str);
  	}
1775c506a   Christoph Hellwig   xfs: clean up pri...
173
174
175
  
  	seq_printf(m, ",inode%d",
  		(mp->m_flags & XFS_MOUNT_SMALL_INUMS) ? 32 : 64);
a67d7c5f5   David Chinner   [XFS] Move platfo...
176

3274d0080   Christoph Hellwig   xfs: rename the X...
177
  	if (mp->m_flags & XFS_MOUNT_ALLOCSIZE)
2e74af0e1   Eric Sandeen   xfs: convert moun...
178
  		seq_printf(m, ",allocsize=%dk",
aa58d4455   Christoph Hellwig   xfs: clean up pri...
179
  			   (1 << mp->m_allocsize_log) >> 10);
a67d7c5f5   David Chinner   [XFS] Move platfo...
180
181
  
  	if (mp->m_logbufs > 0)
2e74af0e1   Eric Sandeen   xfs: convert moun...
182
  		seq_printf(m, ",logbufs=%d", mp->m_logbufs);
a67d7c5f5   David Chinner   [XFS] Move platfo...
183
  	if (mp->m_logbsize > 0)
2e74af0e1   Eric Sandeen   xfs: convert moun...
184
  		seq_printf(m, ",logbsize=%dk", mp->m_logbsize >> 10);
a67d7c5f5   David Chinner   [XFS] Move platfo...
185
186
  
  	if (mp->m_logname)
2e74af0e1   Eric Sandeen   xfs: convert moun...
187
  		seq_show_option(m, "logdev", mp->m_logname);
a67d7c5f5   David Chinner   [XFS] Move platfo...
188
  	if (mp->m_rtname)
2e74af0e1   Eric Sandeen   xfs: convert moun...
189
  		seq_show_option(m, "rtdev", mp->m_rtname);
a67d7c5f5   David Chinner   [XFS] Move platfo...
190
191
  
  	if (mp->m_dalign > 0)
2e74af0e1   Eric Sandeen   xfs: convert moun...
192
  		seq_printf(m, ",sunit=%d",
a67d7c5f5   David Chinner   [XFS] Move platfo...
193
194
  				(int)XFS_FSB_TO_BB(mp, mp->m_dalign));
  	if (mp->m_swidth > 0)
2e74af0e1   Eric Sandeen   xfs: convert moun...
195
  		seq_printf(m, ",swidth=%d",
a67d7c5f5   David Chinner   [XFS] Move platfo...
196
197
198
  				(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
  
  	if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
2e74af0e1   Eric Sandeen   xfs: convert moun...
199
  		seq_puts(m, ",usrquota");
a67d7c5f5   David Chinner   [XFS] Move platfo...
200
  	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
2e74af0e1   Eric Sandeen   xfs: convert moun...
201
  		seq_puts(m, ",uqnoenforce");
a67d7c5f5   David Chinner   [XFS] Move platfo...
202

988abe407   Alex Elder   xfs: xfs_showargs...
203
  	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
204
  		if (mp->m_qflags & XFS_PQUOTA_ENFD)
2e74af0e1   Eric Sandeen   xfs: convert moun...
205
  			seq_puts(m, ",prjquota");
988abe407   Alex Elder   xfs: xfs_showargs...
206
  		else
2e74af0e1   Eric Sandeen   xfs: convert moun...
207
  			seq_puts(m, ",pqnoenforce");
d892d5864   Chandra Seetharaman   xfs: Start using ...
208
209
  	}
  	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
210
  		if (mp->m_qflags & XFS_GQUOTA_ENFD)
2e74af0e1   Eric Sandeen   xfs: convert moun...
211
  			seq_puts(m, ",grpquota");
988abe407   Alex Elder   xfs: xfs_showargs...
212
  		else
2e74af0e1   Eric Sandeen   xfs: convert moun...
213
  			seq_puts(m, ",gqnoenforce");
988abe407   Alex Elder   xfs: xfs_showargs...
214
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
215
216
  
  	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
2e74af0e1   Eric Sandeen   xfs: convert moun...
217
  		seq_puts(m, ",noquota");
21f55993e   Christoph Hellwig   xfs: merge xfs_sh...
218
219
  
  	return 0;
a67d7c5f5   David Chinner   [XFS] Move platfo...
220
  }
910832697   Eric Sandeen   xfs: change some ...
221

9de67c3ba   Eric Sandeen   xfs: allow inode ...
222
  /*
12c3f05c7   Eric Sandeen   xfs: fix up inode...
223
224
225
226
227
228
229
230
231
232
233
234
235
   * Set parameters for inode allocation heuristics, taking into account
   * filesystem size and inode32/inode64 mount options; i.e. specifically
   * whether or not XFS_MOUNT_SMALL_INUMS is set.
   *
   * Inode allocation patterns are altered only if inode32 is requested
   * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
   * If altered, XFS_MOUNT_32BITINODES is set as well.
   *
   * An agcount independent of that in the mount structure is provided
   * because in the growfs case, mp->m_sb.sb_agcount is not yet updated
   * to the potentially higher ag count.
   *
   * Returns the maximum AG index which may contain inodes.
9de67c3ba   Eric Sandeen   xfs: allow inode ...
236
   */
2d2194f61   Carlos Maiolino   xfs: reduce code ...
237
  xfs_agnumber_t
12c3f05c7   Eric Sandeen   xfs: fix up inode...
238
239
240
  xfs_set_inode_alloc(
  	struct xfs_mount *mp,
  	xfs_agnumber_t	agcount)
2d2194f61   Carlos Maiolino   xfs: reduce code ...
241
  {
12c3f05c7   Eric Sandeen   xfs: fix up inode...
242
  	xfs_agnumber_t	index;
4056c1d08   Carlos Maiolino   xfs: add inode64-...
243
  	xfs_agnumber_t	maxagi = 0;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
244
245
  	xfs_sb_t	*sbp = &mp->m_sb;
  	xfs_agnumber_t	max_metadata;
54aa61f82   Eric Sandeen   xfs: tidy up xfs_...
246
247
  	xfs_agino_t	agino;
  	xfs_ino_t	ino;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
248

12c3f05c7   Eric Sandeen   xfs: fix up inode...
249
250
251
  	/*
  	 * Calculate how much should be reserved for inodes to meet
  	 * the max inode percentage.  Used only for inode32.
2d2194f61   Carlos Maiolino   xfs: reduce code ...
252
  	 */
ef3259599   Darrick J. Wong   xfs: separate ino...
253
  	if (M_IGEO(mp)->maxicount) {
c8ce540db   Darrick J. Wong   xfs: remove doubl...
254
  		uint64_t	icount;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
255
256
257
258
259
260
261
  
  		icount = sbp->sb_dblocks * sbp->sb_imax_pct;
  		do_div(icount, 100);
  		icount += sbp->sb_agblocks - 1;
  		do_div(icount, sbp->sb_agblocks);
  		max_metadata = icount;
  	} else {
9de67c3ba   Eric Sandeen   xfs: allow inode ...
262
  		max_metadata = agcount;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
263
  	}
12c3f05c7   Eric Sandeen   xfs: fix up inode...
264
  	/* Get the last possible inode in the filesystem */
43004b2a8   Darrick J. Wong   xfs: add a block ...
265
  	agino =	XFS_AGB_TO_AGINO(mp, sbp->sb_agblocks - 1);
12c3f05c7   Eric Sandeen   xfs: fix up inode...
266
267
268
269
270
271
272
273
274
275
276
  	ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
  
  	/*
  	 * If user asked for no more than 32-bit inodes, and the fs is
  	 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
  	 * the allocator to accommodate the request.
  	 */
  	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
  		mp->m_flags |= XFS_MOUNT_32BITINODES;
  	else
  		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
54aa61f82   Eric Sandeen   xfs: tidy up xfs_...
277

9de67c3ba   Eric Sandeen   xfs: allow inode ...
278
  	for (index = 0; index < agcount; index++) {
12c3f05c7   Eric Sandeen   xfs: fix up inode...
279
  		struct xfs_perag	*pag;
4056c1d08   Carlos Maiolino   xfs: add inode64-...
280

12c3f05c7   Eric Sandeen   xfs: fix up inode...
281
  		ino = XFS_AGINO_TO_INO(mp, index, agino);
2d2194f61   Carlos Maiolino   xfs: reduce code ...
282
283
  
  		pag = xfs_perag_get(mp, index);
2d2194f61   Carlos Maiolino   xfs: reduce code ...
284

12c3f05c7   Eric Sandeen   xfs: fix up inode...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  		if (mp->m_flags & XFS_MOUNT_32BITINODES) {
  			if (ino > XFS_MAXINUMBER_32) {
  				pag->pagi_inodeok = 0;
  				pag->pagf_metadata = 0;
  			} else {
  				pag->pagi_inodeok = 1;
  				maxagi++;
  				if (index < max_metadata)
  					pag->pagf_metadata = 1;
  				else
  					pag->pagf_metadata = 0;
  			}
  		} else {
  			pag->pagi_inodeok = 1;
  			pag->pagf_metadata = 0;
  		}
2d2194f61   Carlos Maiolino   xfs: reduce code ...
301

2d2194f61   Carlos Maiolino   xfs: reduce code ...
302
303
  		xfs_perag_put(pag);
  	}
12c3f05c7   Eric Sandeen   xfs: fix up inode...
304
  	return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
305
  }
3180e66d7   Hannes Eder   xfs: make symbols...
306
  STATIC int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
  xfs_blkdev_get(
  	xfs_mount_t		*mp,
  	const char		*name,
  	struct block_device	**bdevp)
  {
  	int			error = 0;
d4d776299   Tejun Heo   block: clean up b...
313
314
  	*bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
  				    mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
  	if (IS_ERR(*bdevp)) {
  		error = PTR_ERR(*bdevp);
77af574ee   Eric Sandeen   xfs: remove extra...
317
  		xfs_warn(mp, "Invalid device [%s], error=%d", name, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
  	}
2451337dd   Dave Chinner   xfs: global error...
319
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  }
3180e66d7   Hannes Eder   xfs: make symbols...
321
  STATIC void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
  xfs_blkdev_put(
  	struct block_device	*bdev)
  {
  	if (bdev)
e525fd89d   Tejun Heo   block: make blkde...
326
  		blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  }
f538d4da8   Christoph Hellwig   [XFS] write barri...
328
329
330
331
  void
  xfs_blkdev_issue_flush(
  	xfs_buftarg_t		*buftarg)
  {
9398554fb   Christoph Hellwig   block: remove the...
332
  	blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS);
f538d4da8   Christoph Hellwig   [XFS] write barri...
333
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334

19f354d4c   Christoph Hellwig   [XFS] sort out op...
335
336
337
338
  STATIC void
  xfs_close_devices(
  	struct xfs_mount	*mp)
  {
486aff5e0   Dan Williams   xfs: perform dax_...
339
  	struct dax_device *dax_ddev = mp->m_ddev_targp->bt_daxdev;
19f354d4c   Christoph Hellwig   [XFS] sort out op...
340
  	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
341
  		struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
486aff5e0   Dan Williams   xfs: perform dax_...
342
  		struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
343
  		xfs_free_buftarg(mp->m_logdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
344
  		xfs_blkdev_put(logdev);
486aff5e0   Dan Williams   xfs: perform dax_...
345
  		fs_put_dax(dax_logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
346
347
  	}
  	if (mp->m_rtdev_targp) {
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
348
  		struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
486aff5e0   Dan Williams   xfs: perform dax_...
349
  		struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
350
  		xfs_free_buftarg(mp->m_rtdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
351
  		xfs_blkdev_put(rtdev);
486aff5e0   Dan Williams   xfs: perform dax_...
352
  		fs_put_dax(dax_rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
353
  	}
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
354
  	xfs_free_buftarg(mp->m_ddev_targp);
486aff5e0   Dan Williams   xfs: perform dax_...
355
  	fs_put_dax(dax_ddev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  }
  
  /*
   * The file system configurations are:
   *	(1) device (partition) with data and internal log
   *	(2) logical volume with data and log subvolumes.
   *	(3) logical volume with data, log, and realtime subvolumes.
   *
   * We only have to handle opening the log and realtime volumes here if
   * they are present.  The data subvolume has already been opened by
   * get_sb_bdev() and is stored in sb->s_bdev.
   */
  STATIC int
  xfs_open_devices(
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
370
  	struct xfs_mount	*mp)
19f354d4c   Christoph Hellwig   [XFS] sort out op...
371
372
  {
  	struct block_device	*ddev = mp->m_super->s_bdev;
486aff5e0   Dan Williams   xfs: perform dax_...
373
374
  	struct dax_device	*dax_ddev = fs_dax_get_by_bdev(ddev);
  	struct dax_device	*dax_logdev = NULL, *dax_rtdev = NULL;
19f354d4c   Christoph Hellwig   [XFS] sort out op...
375
376
377
378
379
380
  	struct block_device	*logdev = NULL, *rtdev = NULL;
  	int			error;
  
  	/*
  	 * Open real time and log devices - order is important.
  	 */
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
381
382
  	if (mp->m_logname) {
  		error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
383
384
  		if (error)
  			goto out;
486aff5e0   Dan Williams   xfs: perform dax_...
385
  		dax_logdev = fs_dax_get_by_bdev(logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
386
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
387
388
  	if (mp->m_rtname) {
  		error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
389
390
391
392
  		if (error)
  			goto out_close_logdev;
  
  		if (rtdev == ddev || rtdev == logdev) {
4f10700a2   Dave Chinner   xfs: Convert linu...
393
394
  			xfs_warn(mp,
  	"Cannot mount filesystem with identical rtdev and ddev/logdev.");
2451337dd   Dave Chinner   xfs: global error...
395
  			error = -EINVAL;
19f354d4c   Christoph Hellwig   [XFS] sort out op...
396
397
  			goto out_close_rtdev;
  		}
486aff5e0   Dan Williams   xfs: perform dax_...
398
  		dax_rtdev = fs_dax_get_by_bdev(rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
399
400
401
402
403
  	}
  
  	/*
  	 * Setup xfs_mount buffer target pointers
  	 */
2451337dd   Dave Chinner   xfs: global error...
404
  	error = -ENOMEM;
486aff5e0   Dan Williams   xfs: perform dax_...
405
  	mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
406
407
408
409
  	if (!mp->m_ddev_targp)
  		goto out_close_rtdev;
  
  	if (rtdev) {
486aff5e0   Dan Williams   xfs: perform dax_...
410
  		mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
411
412
413
414
415
  		if (!mp->m_rtdev_targp)
  			goto out_free_ddev_targ;
  	}
  
  	if (logdev && logdev != ddev) {
486aff5e0   Dan Williams   xfs: perform dax_...
416
  		mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
417
418
419
420
421
422
423
424
425
426
  		if (!mp->m_logdev_targp)
  			goto out_free_rtdev_targ;
  	} else {
  		mp->m_logdev_targp = mp->m_ddev_targp;
  	}
  
  	return 0;
  
   out_free_rtdev_targ:
  	if (mp->m_rtdev_targp)
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
427
  		xfs_free_buftarg(mp->m_rtdev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
428
   out_free_ddev_targ:
a1f69417c   Eric Sandeen   xfs: non-scrub - ...
429
  	xfs_free_buftarg(mp->m_ddev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
430
   out_close_rtdev:
d2a5e3c6f   Markus Elfring   xfs: remove unnec...
431
  	xfs_blkdev_put(rtdev);
486aff5e0   Dan Williams   xfs: perform dax_...
432
  	fs_put_dax(dax_rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
433
   out_close_logdev:
486aff5e0   Dan Williams   xfs: perform dax_...
434
  	if (logdev && logdev != ddev) {
19f354d4c   Christoph Hellwig   [XFS] sort out op...
435
  		xfs_blkdev_put(logdev);
486aff5e0   Dan Williams   xfs: perform dax_...
436
437
  		fs_put_dax(dax_logdev);
  	}
19f354d4c   Christoph Hellwig   [XFS] sort out op...
438
   out:
486aff5e0   Dan Williams   xfs: perform dax_...
439
  	fs_put_dax(dax_ddev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
440
441
  	return error;
  }
e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
442
443
444
445
446
447
448
449
  /*
   * Setup xfs_mount buffer target pointers based on superblock
   */
  STATIC int
  xfs_setup_devices(
  	struct xfs_mount	*mp)
  {
  	int			error;
19f354d4c   Christoph Hellwig   [XFS] sort out op...
450

a96c41519   Eric Sandeen   xfs: remove unuse...
451
  	error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_sectsize);
e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
452
453
454
455
456
457
458
459
460
  	if (error)
  		return error;
  
  	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
  		unsigned int	log_sector_size = BBSIZE;
  
  		if (xfs_sb_version_hassector(&mp->m_sb))
  			log_sector_size = mp->m_sb.sb_logsectsize;
  		error = xfs_setsize_buftarg(mp->m_logdev_targp,
e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
461
462
463
464
465
466
  					    log_sector_size);
  		if (error)
  			return error;
  	}
  	if (mp->m_rtdev_targp) {
  		error = xfs_setsize_buftarg(mp->m_rtdev_targp,
e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
467
468
469
470
471
472
473
  					    mp->m_sb.sb_sectsize);
  		if (error)
  			return error;
  	}
  
  	return 0;
  }
19f354d4c   Christoph Hellwig   [XFS] sort out op...
474

aa6bf01d3   Christoph Hellwig   xfs: use per-file...
475
476
477
478
  STATIC int
  xfs_init_mount_workqueues(
  	struct xfs_mount	*mp)
  {
78c931b8b   Brian Foster   xfs: replace glob...
479
  	mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
e1d3d2188   Ian Kent   xfs: use super s_...
480
  			WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_super->s_id);
78c931b8b   Brian Foster   xfs: replace glob...
481
482
  	if (!mp->m_buf_workqueue)
  		goto out;
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
483
  	mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s",
e1d3d2188   Ian Kent   xfs: use super s_...
484
  			WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
485
  	if (!mp->m_unwritten_workqueue)
284082437   Darrick J. Wong   xfs: remove unuse...
486
  		goto out_destroy_buf;
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
487

4c2d542f2   Dave Chinner   xfs: Do backgroun...
488
  	mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s",
8ab39f11d   Dave Chinner   xfs: prevent CIL ...
489
  			WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND,
e1d3d2188   Ian Kent   xfs: use super s_...
490
  			0, mp->m_super->s_id);
4c2d542f2   Dave Chinner   xfs: Do backgroun...
491
492
  	if (!mp->m_cil_workqueue)
  		goto out_destroy_unwritten;
5889608df   Dave Chinner   xfs: syncd workqu...
493
494
  
  	mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s",
e1d3d2188   Ian Kent   xfs: use super s_...
495
  			WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id);
5889608df   Dave Chinner   xfs: syncd workqu...
496
497
  	if (!mp->m_reclaim_workqueue)
  		goto out_destroy_cil;
579b62faa   Brian Foster   xfs: add backgrou...
498
  	mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s",
e1d3d2188   Ian Kent   xfs: use super s_...
499
  			WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id);
579b62faa   Brian Foster   xfs: add backgrou...
500
  	if (!mp->m_eofblocks_workqueue)
1058d0f5e   Christoph Hellwig   xfs: move the log...
501
  		goto out_destroy_reclaim;
579b62faa   Brian Foster   xfs: add backgrou...
502

696a56207   Brian Foster   xfs: use dedicate...
503
  	mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", WQ_FREEZABLE, 0,
e1d3d2188   Ian Kent   xfs: use super s_...
504
  					       mp->m_super->s_id);
696a56207   Brian Foster   xfs: use dedicate...
505
506
  	if (!mp->m_sync_workqueue)
  		goto out_destroy_eofb;
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
507
  	return 0;
696a56207   Brian Foster   xfs: use dedicate...
508
509
  out_destroy_eofb:
  	destroy_workqueue(mp->m_eofblocks_workqueue);
5889608df   Dave Chinner   xfs: syncd workqu...
510
511
512
513
  out_destroy_reclaim:
  	destroy_workqueue(mp->m_reclaim_workqueue);
  out_destroy_cil:
  	destroy_workqueue(mp->m_cil_workqueue);
4c2d542f2   Dave Chinner   xfs: Do backgroun...
514
515
  out_destroy_unwritten:
  	destroy_workqueue(mp->m_unwritten_workqueue);
78c931b8b   Brian Foster   xfs: replace glob...
516
517
  out_destroy_buf:
  	destroy_workqueue(mp->m_buf_workqueue);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
518
519
520
521
522
523
524
525
  out:
  	return -ENOMEM;
  }
  
  STATIC void
  xfs_destroy_mount_workqueues(
  	struct xfs_mount	*mp)
  {
696a56207   Brian Foster   xfs: use dedicate...
526
  	destroy_workqueue(mp->m_sync_workqueue);
579b62faa   Brian Foster   xfs: add backgrou...
527
  	destroy_workqueue(mp->m_eofblocks_workqueue);
5889608df   Dave Chinner   xfs: syncd workqu...
528
  	destroy_workqueue(mp->m_reclaim_workqueue);
4c2d542f2   Dave Chinner   xfs: Do backgroun...
529
  	destroy_workqueue(mp->m_cil_workqueue);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
530
  	destroy_workqueue(mp->m_unwritten_workqueue);
78c931b8b   Brian Foster   xfs: replace glob...
531
  	destroy_workqueue(mp->m_buf_workqueue);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
532
  }
f0f7a674d   Darrick J. Wong   xfs: move inode f...
533
534
535
536
537
538
539
540
541
542
543
544
545
  static void
  xfs_flush_inodes_worker(
  	struct work_struct	*work)
  {
  	struct xfs_mount	*mp = container_of(work, struct xfs_mount,
  						   m_flush_inodes_work);
  	struct super_block	*sb = mp->m_super;
  
  	if (down_read_trylock(&sb->s_umount)) {
  		sync_inodes_sb(sb);
  		up_read(&sb->s_umount);
  	}
  }
9aa05000f   Dave Chinner   xfs: xfs_sync_dat...
546
547
548
549
550
551
552
553
554
555
  /*
   * Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK
   * or a page lock. We use sync_inodes_sb() here to ensure we block while waiting
   * for IO to complete so that we effectively throttle multiple callers to the
   * rate at which IO is completing.
   */
  void
  xfs_flush_inodes(
  	struct xfs_mount	*mp)
  {
f0f7a674d   Darrick J. Wong   xfs: move inode f...
556
557
558
559
560
  	/*
  	 * If flush_work() returns true then that means we waited for a flush
  	 * which was already in progress.  Don't bother running another scan.
  	 */
  	if (flush_work(&mp->m_flush_inodes_work))
c6425702f   Darrick J. Wong   xfs: ratelimit in...
561
  		return;
f0f7a674d   Darrick J. Wong   xfs: move inode f...
562
563
  	queue_work(mp->m_sync_workqueue, &mp->m_flush_inodes_work);
  	flush_work(&mp->m_flush_inodes_work);
9aa05000f   Dave Chinner   xfs: xfs_sync_dat...
564
  }
bf904248a   David Chinner   [XFS] Combine the...
565
  /* Catch misguided souls that try to use this interface on XFS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
  STATIC struct inode *
a50cd2692   Nathan Scott   [XFS] Switch over...
567
  xfs_fs_alloc_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
  	struct super_block	*sb)
  {
bf904248a   David Chinner   [XFS] Combine the...
570
  	BUG();
493dca617   Lachlan McIlroy   [XFS] Fix build w...
571
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
572
  }
4831822ff   Christoph Hellwig   xfs: print dangli...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  #ifdef DEBUG
  static void
  xfs_check_delalloc(
  	struct xfs_inode	*ip,
  	int			whichfork)
  {
  	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
  	struct xfs_bmbt_irec	got;
  	struct xfs_iext_cursor	icur;
  
  	if (!ifp || !xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got))
  		return;
  	do {
  		if (isnullstartblock(got.br_startblock)) {
  			xfs_warn(ip->i_mount,
  	"ino %llx %s fork has delalloc extent at [0x%llx:0x%llx]",
  				ip->i_ino,
  				whichfork == XFS_DATA_FORK ? "data" : "cow",
  				got.br_startoff, got.br_blockcount);
  		}
  	} while (xfs_iext_next_extent(ifp, &icur, &got));
  }
  #else
  #define xfs_check_delalloc(ip, whichfork)	do { } while (0)
  #endif
bf904248a   David Chinner   [XFS] Combine the...
598
  /*
99fa8cb3c   David Chinner   [XFS] Prevent use...
599
   * Now that the generic code is guaranteed not to be accessing
8179c0362   Dave Chinner   xfs: remove xfs_f...
600
   * the linux inode, we can inactivate and reclaim the inode.
bf904248a   David Chinner   [XFS] Combine the...
601
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  STATIC void
a50cd2692   Nathan Scott   [XFS] Switch over...
603
  xfs_fs_destroy_inode(
848ce8f73   Christoph Hellwig   xfs: simplify ino...
604
  	struct inode		*inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
  {
848ce8f73   Christoph Hellwig   xfs: simplify ino...
606
  	struct xfs_inode	*ip = XFS_I(inode);
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
607
  	trace_xfs_destroy_inode(ip);
99fa8cb3c   David Chinner   [XFS] Prevent use...
608

655232183   Christoph Hellwig   xfs: remove i_iol...
609
  	ASSERT(!rwsem_is_locked(&inode->i_rwsem));
8179c0362   Dave Chinner   xfs: remove xfs_f...
610
611
612
613
  	XFS_STATS_INC(ip->i_mount, vn_rele);
  	XFS_STATS_INC(ip->i_mount, vn_remove);
  
  	xfs_inactive(ip);
848ce8f73   Christoph Hellwig   xfs: simplify ino...
614

4831822ff   Christoph Hellwig   xfs: print dangli...
615
616
617
618
619
  	if (!XFS_FORCED_SHUTDOWN(ip->i_mount) && ip->i_delayed_blks) {
  		xfs_check_delalloc(ip, XFS_DATA_FORK);
  		xfs_check_delalloc(ip, XFS_COW_FORK);
  		ASSERT(0);
  	}
8179c0362   Dave Chinner   xfs: remove xfs_f...
620
  	XFS_STATS_INC(ip->i_mount, vn_reclaim);
848ce8f73   Christoph Hellwig   xfs: simplify ino...
621
622
623
624
625
626
627
628
  
  	/*
  	 * We should never get here with one of the reclaim flags already set.
  	 */
  	ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
  	ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM));
  
  	/*
718ecc503   Dave Chinner   xfs: xfs_iflock i...
629
630
631
632
633
  	 * We always use background reclaim here because even if the inode is
  	 * clean, it still may be under IO and hence we have wait for IO
  	 * completion to occur before we can reclaim the inode. The background
  	 * reclaim path handles this more efficiently than we can here, so
  	 * simply let background reclaim tear down all inodes.
848ce8f73   Christoph Hellwig   xfs: simplify ino...
634
  	 */
57817c682   Dave Chinner   xfs: reclaim all ...
635
  	xfs_inode_set_reclaim_tag(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  }
c3b1b1319   Christoph Hellwig   xfs: implement th...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  static void
  xfs_fs_dirty_inode(
  	struct inode			*inode,
  	int				flag)
  {
  	struct xfs_inode		*ip = XFS_I(inode);
  	struct xfs_mount		*mp = ip->i_mount;
  	struct xfs_trans		*tp;
  
  	if (!(inode->i_sb->s_flags & SB_LAZYTIME))
  		return;
  	if (flag != I_DIRTY_SYNC || !(inode->i_state & I_DIRTY_TIME))
  		return;
  
  	if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp))
  		return;
  	xfs_ilock(ip, XFS_ILOCK_EXCL);
  	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
  	xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
  	xfs_trans_commit(tp);
  }
07c8f6758   David Chinner   [XFS] Make use of...
658
659
660
661
  /*
   * Slab object creation initialisation for the XFS inode.
   * This covers only the idempotent fields in the XFS inode;
   * all other fields need to be initialised on allocation
b595076a1   Uwe Kleine-König   tree-wide: fix co...
662
   * from the slab. This avoids the need to repeatedly initialise
07c8f6758   David Chinner   [XFS] Make use of...
663
664
665
   * fields in the xfs inode that left in the initialise state
   * when freeing the inode.
   */
bf904248a   David Chinner   [XFS] Combine the...
666
667
  STATIC void
  xfs_fs_inode_init_once(
07c8f6758   David Chinner   [XFS] Make use of...
668
669
670
671
672
  	void			*inode)
  {
  	struct xfs_inode	*ip = inode;
  
  	memset(ip, 0, sizeof(struct xfs_inode));
bf904248a   David Chinner   [XFS] Combine the...
673
674
675
676
677
  
  	/* vfs inode */
  	inode_init_once(VFS_I(ip));
  
  	/* xfs inode */
07c8f6758   David Chinner   [XFS] Make use of...
678
679
  	atomic_set(&ip->i_pincount, 0);
  	spin_lock_init(&ip->i_flags_lock);
07c8f6758   David Chinner   [XFS] Make use of...
680

653c60b63   Dave Chinner   xfs: introduce mm...
681
682
  	mrlock_init(&ip->i_mmaplock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
  		     "xfsino", ip->i_ino);
07c8f6758   David Chinner   [XFS] Make use of...
683
684
  	mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
  		     "xfsino", ip->i_ino);
07c8f6758   David Chinner   [XFS] Make use of...
685
  }
5132ba8f2   Dave Chinner   xfs: don't cache ...
686
687
688
689
690
691
692
693
694
695
696
697
  /*
   * We do an unlocked check for XFS_IDONTCACHE here because we are already
   * serialised against cache hits here via the inode->i_lock and igrab() in
   * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be
   * racing with us, and it avoids needing to grab a spinlock here for every inode
   * we drop the final reference on.
   */
  STATIC int
  xfs_fs_drop_inode(
  	struct inode		*inode)
  {
  	struct xfs_inode	*ip = XFS_I(inode);
17c12bcd3   Darrick J. Wong   xfs: when replayi...
698
699
700
701
702
703
704
705
706
  	/*
  	 * If this unlinked inode is in the middle of recovery, don't
  	 * drop the inode just yet; log recovery will take care of
  	 * that.  See the comment for this inode flag.
  	 */
  	if (ip->i_flags & XFS_IRECOVERY) {
  		ASSERT(ip->i_mount->m_log->l_flags & XLOG_RECOVERY_NEEDED);
  		return 0;
  	}
dae2f8ed7   Ira Weiny   fs: Lift XFS_IDON...
707
  	return generic_drop_inode(inode);
5132ba8f2   Dave Chinner   xfs: don't cache ...
708
  }
a943f372c   Ian Kent   xfs: merge freein...
709
710
  static void
  xfs_mount_free(
a738159df   Christoph Hellwig   [XFS] don't leak ...
711
712
  	struct xfs_mount	*mp)
  {
a738159df   Christoph Hellwig   [XFS] don't leak ...
713
714
  	kfree(mp->m_rtname);
  	kfree(mp->m_logname);
a943f372c   Ian Kent   xfs: merge freein...
715
  	kmem_free(mp);
a738159df   Christoph Hellwig   [XFS] don't leak ...
716
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  STATIC int
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
718
  xfs_fs_sync_fs(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
  	struct super_block	*sb,
  	int			wait)
  {
745f69191   Christoph Hellwig   [XFS] call common...
722
  	struct xfs_mount	*mp = XFS_M(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723

e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
724
  	/*
34625c661   Christoph Hellwig   xfs: remove xfs_q...
725
  	 * Doing anything during the async pass would be counterproductive.
e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
726
  	 */
34625c661   Christoph Hellwig   xfs: remove xfs_q...
727
  	if (!wait)
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
728
  		return 0;
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
729

34061f5c4   Dave Chinner   xfs: xfs_sync_fsd...
730
  	xfs_log_force(mp, XFS_LOG_SYNC);
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
731
  	if (laptop_mode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
  		/*
  		 * The disk must be active because we're syncing.
f661f1e0b   Dave Chinner   xfs: sync work is...
734
  		 * We schedule log work now (now that the disk is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
736
  		 * active) instead of later (when it might not be).
  		 */
f661f1e0b   Dave Chinner   xfs: sync work is...
737
  		flush_delayed_work(&mp->m_log->l_work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
  	}
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
739
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740
741
742
  }
  
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
743
  xfs_fs_statfs(
726c33422   David Howells   [PATCH] VFS: Perm...
744
  	struct dentry		*dentry,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
746
  	struct kstatfs		*statp)
  {
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
747
748
  	struct xfs_mount	*mp = XFS_M(dentry->d_sb);
  	xfs_sb_t		*sbp = &mp->m_sb;
2b0143b5c   David Howells   VFS: normal files...
749
  	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
c8ce540db   Darrick J. Wong   xfs: remove doubl...
750
751
752
753
  	uint64_t		fakeinos, id;
  	uint64_t		icount;
  	uint64_t		ifree;
  	uint64_t		fdblocks;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
754
  	xfs_extlen_t		lsize;
c8ce540db   Darrick J. Wong   xfs: remove doubl...
755
  	int64_t			ffree;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
756

dddde68b8   Adam Borowski   xfs: add a define...
757
  	statp->f_type = XFS_SUPER_MAGIC;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
758
759
760
  	statp->f_namelen = MAXNAMELEN - 1;
  
  	id = huge_encode_dev(mp->m_ddev_targp->bt_dev);
6d1349c76   Al Viro   [PATCH] reduce bo...
761
  	statp->f_fsid = u64_to_fsid(id);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
762

501ab3238   Dave Chinner   xfs: use generic ...
763
  	icount = percpu_counter_sum(&mp->m_icount);
e88b64ea1   Dave Chinner   xfs: use generic ...
764
  	ifree = percpu_counter_sum(&mp->m_ifree);
0d485ada4   Dave Chinner   xfs: use generic ...
765
  	fdblocks = percpu_counter_sum(&mp->m_fdblocks);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
766
767
768
769
770
  
  	spin_lock(&mp->m_sb_lock);
  	statp->f_bsize = sbp->sb_blocksize;
  	lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
  	statp->f_blocks = sbp->sb_dblocks - lsize;
0d485ada4   Dave Chinner   xfs: use generic ...
771
  	spin_unlock(&mp->m_sb_lock);
237aac462   Zheng Bin   xfs: ensure f_bfr...
772
773
  	/* make sure statp->f_bfree does not underflow */
  	statp->f_bfree = max_t(int64_t, fdblocks - mp->m_alloc_set_aside, 0);
0d485ada4   Dave Chinner   xfs: use generic ...
774
  	statp->f_bavail = statp->f_bfree;
43004b2a8   Darrick J. Wong   xfs: add a block ...
775
  	fakeinos = XFS_FSB_TO_INO(mp, statp->f_bfree);
9bb54cb56   Dave Chinner   xfs: clean up MIN...
776
  	statp->f_files = min(icount + fakeinos, (uint64_t)XFS_MAXINUMBER);
ef3259599   Darrick J. Wong   xfs: separate ino...
777
  	if (M_IGEO(mp)->maxicount)
a19d9f887   Christoph Hellwig   xfs: kill ino64 m...
778
779
  		statp->f_files = min_t(typeof(statp->f_files),
  					statp->f_files,
ef3259599   Darrick J. Wong   xfs: separate ino...
780
  					M_IGEO(mp)->maxicount);
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
781

01f9882ea   Eric Sandeen   xfs: report prope...
782
783
784
785
  	/* If sb_icount overshot maxicount, report actual allocation */
  	statp->f_files = max_t(typeof(statp->f_files),
  					statp->f_files,
  					sbp->sb_icount);
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
786
  	/* make sure statp->f_ffree does not underflow */
e88b64ea1   Dave Chinner   xfs: use generic ...
787
  	ffree = statp->f_files - (icount - ifree);
c8ce540db   Darrick J. Wong   xfs: remove doubl...
788
  	statp->f_ffree = max_t(int64_t, ffree, 0);
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
789

4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
790

da5bf95e3   Jie Liu   xfs: don't fill s...
791
  	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
792
793
  	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
  			      (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
794
  		xfs_qm_statvfs(ip, statp);
a01583159   Richard Wareing   xfs: Show realtim...
795
796
797
798
799
800
801
  
  	if (XFS_IS_REALTIME_MOUNT(mp) &&
  	    (ip->i_d.di_flags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) {
  		statp->f_blocks = sbp->sb_rblocks;
  		statp->f_bavail = statp->f_bfree =
  			sbp->sb_frextents * sbp->sb_rextsize;
  	}
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
802
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  }
d5db0f97f   Eric Sandeen   xfs: more reserve...
804
805
806
  STATIC void
  xfs_save_resvblks(struct xfs_mount *mp)
  {
c8ce540db   Darrick J. Wong   xfs: remove doubl...
807
  	uint64_t resblks = 0;
d5db0f97f   Eric Sandeen   xfs: more reserve...
808
809
810
811
812
813
814
815
  
  	mp->m_resblks_save = mp->m_resblks;
  	xfs_reserve_blocks(mp, &resblks, NULL);
  }
  
  STATIC void
  xfs_restore_resvblks(struct xfs_mount *mp)
  {
c8ce540db   Darrick J. Wong   xfs: remove doubl...
816
  	uint64_t resblks;
d5db0f97f   Eric Sandeen   xfs: more reserve...
817
818
819
820
821
822
823
824
825
  
  	if (mp->m_resblks_save) {
  		resblks = mp->m_resblks_save;
  		mp->m_resblks_save = 0;
  	} else
  		resblks = xfs_default_resblks(mp);
  
  	xfs_reserve_blocks(mp, &resblks, NULL);
  }
8757c38f2   Ian Kent   xfs: move xfs_fc_...
826
827
828
829
830
831
832
833
  /*
   * Trigger writeback of all the dirty metadata in the file system.
   *
   * This ensures that the metadata is written to their location on disk rather
   * than just existing in transactions in the log. This means after a quiesce
   * there is no log replay required to write the inodes to disk - this is the
   * primary difference between a sync and a quiesce.
   *
b41b46c20   Dave Chinner   xfs: remove the m...
834
835
836
837
   * We cancel log work early here to ensure all transactions the log worker may
   * run have finished before we clean up and log the superblock and write an
   * unmount record. The unfreeze process is responsible for restarting the log
   * worker correctly.
8757c38f2   Ian Kent   xfs: move xfs_fc_...
838
839
840
841
842
843
   */
  void
  xfs_quiesce_attr(
  	struct xfs_mount	*mp)
  {
  	int	error = 0;
b41b46c20   Dave Chinner   xfs: remove the m...
844
  	cancel_delayed_work_sync(&mp->m_log->l_work);
8757c38f2   Ian Kent   xfs: move xfs_fc_...
845
846
847
  
  	/* force the log to unpin objects from the now complete transactions */
  	xfs_log_force(mp, XFS_LOG_SYNC);
8757c38f2   Ian Kent   xfs: move xfs_fc_...
848
849
850
851
852
853
  
  	/* Push the superblock and write an unmount record */
  	error = xfs_log_sbcount(mp);
  	if (error)
  		xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. "
  				"Frozen image may not be consistent.");
8757c38f2   Ian Kent   xfs: move xfs_fc_...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
  	xfs_log_quiesce(mp);
  }
  
  /*
   * Second stage of a freeze. The data is already frozen so we only
   * need to take care of the metadata. Once that's done sync the superblock
   * to the log to dirty it in case of a crash while frozen. This ensures that we
   * will recover the unlinked inode lists on the next mount.
   */
  STATIC int
  xfs_fs_freeze(
  	struct super_block	*sb)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
c3f2375b9   Waiman Long   xfs: Fix false po...
868
869
  	unsigned int		flags;
  	int			ret;
8757c38f2   Ian Kent   xfs: move xfs_fc_...
870

c3f2375b9   Waiman Long   xfs: Fix false po...
871
872
873
874
875
876
  	/*
  	 * The filesystem is now frozen far enough that memory reclaim
  	 * cannot safely operate on the filesystem. Hence we need to
  	 * set a GFP_NOFS context here to avoid recursion deadlocks.
  	 */
  	flags = memalloc_nofs_save();
8757c38f2   Ian Kent   xfs: move xfs_fc_...
877
878
879
  	xfs_stop_block_reaping(mp);
  	xfs_save_resvblks(mp);
  	xfs_quiesce_attr(mp);
c3f2375b9   Waiman Long   xfs: Fix false po...
880
881
882
  	ret = xfs_sync_sb(mp, true);
  	memalloc_nofs_restore(flags);
  	return ret;
8757c38f2   Ian Kent   xfs: move xfs_fc_...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
  }
  
  STATIC int
  xfs_fs_unfreeze(
  	struct super_block	*sb)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	xfs_restore_resvblks(mp);
  	xfs_log_work_queue(mp);
  	xfs_start_block_reaping(mp);
  	return 0;
  }
  
  /*
   * This function fills in xfs_mount_t fields based on mount args.
   * Note: the superblock _has_ now been read in.
   */
  STATIC int
  xfs_finish_flags(
  	struct xfs_mount	*mp)
  {
  	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
  
  	/* Fail a mount where the logbuf is smaller than the log stripe */
  	if (xfs_sb_version_haslogv2(&mp->m_sb)) {
  		if (mp->m_logbsize <= 0 &&
  		    mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
  			mp->m_logbsize = mp->m_sb.sb_logsunit;
  		} else if (mp->m_logbsize > 0 &&
  			   mp->m_logbsize < mp->m_sb.sb_logsunit) {
  			xfs_warn(mp,
  		"logbuf size must be greater than or equal to log stripe size");
  			return -EINVAL;
  		}
  	} else {
  		/* Fail a mount if the logbuf is larger than 32K */
  		if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) {
  			xfs_warn(mp,
  		"logbuf size for version 1 logs must be 16K or 32K");
  			return -EINVAL;
  		}
  	}
  
  	/*
  	 * V5 filesystems always use attr2 format for attributes.
  	 */
  	if (xfs_sb_version_hascrc(&mp->m_sb) &&
  	    (mp->m_flags & XFS_MOUNT_NOATTR2)) {
  		xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
  			     "attr2 is always enabled for V5 filesystems.");
  		return -EINVAL;
  	}
  
  	/*
  	 * mkfs'ed attr2 will turn on attr2 mount unless explicitly
  	 * told by noattr2 to turn it off
  	 */
  	if (xfs_sb_version_hasattr2(&mp->m_sb) &&
  	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
  		mp->m_flags |= XFS_MOUNT_ATTR2;
  
  	/*
  	 * prohibit r/w mounts of read-only filesystems
  	 */
  	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
  		xfs_warn(mp,
  			"cannot mount a read-only filesystem as read-write");
  		return -EROFS;
  	}
  
  	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
  	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE)) &&
  	    !xfs_sb_version_has_pquotino(&mp->m_sb)) {
  		xfs_warn(mp,
  		  "Super block does not support project and group quota together");
  		return -EINVAL;
  	}
  
  	return 0;
  }
  
  static int
  xfs_init_percpu_counters(
  	struct xfs_mount	*mp)
  {
  	int		error;
  
  	error = percpu_counter_init(&mp->m_icount, 0, GFP_KERNEL);
  	if (error)
  		return -ENOMEM;
  
  	error = percpu_counter_init(&mp->m_ifree, 0, GFP_KERNEL);
  	if (error)
  		goto free_icount;
  
  	error = percpu_counter_init(&mp->m_fdblocks, 0, GFP_KERNEL);
  	if (error)
  		goto free_ifree;
  
  	error = percpu_counter_init(&mp->m_delalloc_blks, 0, GFP_KERNEL);
  	if (error)
  		goto free_fdblocks;
  
  	return 0;
  
  free_fdblocks:
  	percpu_counter_destroy(&mp->m_fdblocks);
  free_ifree:
  	percpu_counter_destroy(&mp->m_ifree);
  free_icount:
  	percpu_counter_destroy(&mp->m_icount);
  	return -ENOMEM;
  }
  
  void
  xfs_reinit_percpu_counters(
  	struct xfs_mount	*mp)
  {
  	percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount);
  	percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree);
  	percpu_counter_set(&mp->m_fdblocks, mp->m_sb.sb_fdblocks);
  }
  
  static void
  xfs_destroy_percpu_counters(
  	struct xfs_mount	*mp)
  {
  	percpu_counter_destroy(&mp->m_icount);
  	percpu_counter_destroy(&mp->m_ifree);
  	percpu_counter_destroy(&mp->m_fdblocks);
  	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
  	       percpu_counter_sum(&mp->m_delalloc_blks) == 0);
  	percpu_counter_destroy(&mp->m_delalloc_blks);
  }
  
  static void
  xfs_fs_put_super(
  	struct super_block	*sb)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	/* if ->fill_super failed, we have no mount to tear down */
  	if (!sb->s_fs_info)
  		return;
  
  	xfs_notice(mp, "Unmounting Filesystem");
  	xfs_filestream_unmount(mp);
  	xfs_unmountfs(mp);
  
  	xfs_freesb(mp);
  	free_percpu(mp->m_stats.xs_stats);
  	xfs_destroy_percpu_counters(mp);
  	xfs_destroy_mount_workqueues(mp);
  	xfs_close_devices(mp);
  
  	sb->s_fs_info = NULL;
  	xfs_mount_free(mp);
  }
  
  static long
  xfs_fs_nr_cached_objects(
  	struct super_block	*sb,
  	struct shrink_control	*sc)
  {
  	/* Paranoia: catch incorrect calls during mount setup or teardown */
  	if (WARN_ON_ONCE(!sb->s_fs_info))
  		return 0;
  	return xfs_reclaim_inodes_count(XFS_M(sb));
  }
  
  static long
  xfs_fs_free_cached_objects(
  	struct super_block	*sb,
  	struct shrink_control	*sc)
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1058
  {
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1059
1060
  	return xfs_reclaim_inodes_nr(XFS_M(sb), sc->nr_to_scan);
  }
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1061

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
  static const struct super_operations xfs_super_operations = {
  	.alloc_inode		= xfs_fs_alloc_inode,
  	.destroy_inode		= xfs_fs_destroy_inode,
  	.dirty_inode		= xfs_fs_dirty_inode,
  	.drop_inode		= xfs_fs_drop_inode,
  	.put_super		= xfs_fs_put_super,
  	.sync_fs		= xfs_fs_sync_fs,
  	.freeze_fs		= xfs_fs_freeze,
  	.unfreeze_fs		= xfs_fs_unfreeze,
  	.statfs			= xfs_fs_statfs,
  	.show_options		= xfs_fs_show_options,
  	.nr_cached_objects	= xfs_fs_nr_cached_objects,
  	.free_cached_objects	= xfs_fs_free_cached_objects,
  };
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1076

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
  static int
  suffix_kstrtoint(
  	const char	*s,
  	unsigned int	base,
  	int		*res)
  {
  	int		last, shift_left_factor = 0, _res;
  	char		*value;
  	int		ret = 0;
  
  	value = kstrdup(s, GFP_KERNEL);
  	if (!value)
  		return -ENOMEM;
  
  	last = strlen(value) - 1;
  	if (value[last] == 'K' || value[last] == 'k') {
  		shift_left_factor = 10;
  		value[last] = '\0';
  	}
  	if (value[last] == 'M' || value[last] == 'm') {
  		shift_left_factor = 20;
  		value[last] = '\0';
  	}
  	if (value[last] == 'G' || value[last] == 'g') {
  		shift_left_factor = 30;
  		value[last] = '\0';
  	}
  
  	if (kstrtoint(value, base, &_res))
  		ret = -EINVAL;
  	kfree(value);
  	*res = _res << shift_left_factor;
  	return ret;
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1110
  }
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1111
  /*
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1112
1113
1114
   * Set mount state from a mount option.
   *
   * NOTE: mp->m_super is NULL here!
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1115
   */
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1116
1117
1118
1119
  static int
  xfs_fc_parse_param(
  	struct fs_context	*fc,
  	struct fs_parameter	*param)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1120
  {
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1121
1122
1123
1124
  	struct xfs_mount	*mp = fc->s_fs_info;
  	struct fs_parse_result	result;
  	int			size = 0;
  	int			opt;
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1125

d7167b149   Al Viro   fs_parse: fold fs...
1126
  	opt = fs_parse(fc, xfs_fs_parameters, param, &result);
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1127
1128
  	if (opt < 0)
  		return opt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1129

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  	switch (opt) {
  	case Opt_logbufs:
  		mp->m_logbufs = result.uint_32;
  		return 0;
  	case Opt_logbsize:
  		if (suffix_kstrtoint(param->string, 10, &mp->m_logbsize))
  			return -EINVAL;
  		return 0;
  	case Opt_logdev:
  		kfree(mp->m_logname);
  		mp->m_logname = kstrdup(param->string, GFP_KERNEL);
  		if (!mp->m_logname)
  			return -ENOMEM;
  		return 0;
  	case Opt_rtdev:
  		kfree(mp->m_rtname);
  		mp->m_rtname = kstrdup(param->string, GFP_KERNEL);
  		if (!mp->m_rtname)
  			return -ENOMEM;
  		return 0;
  	case Opt_allocsize:
  		if (suffix_kstrtoint(param->string, 10, &size))
  			return -EINVAL;
  		mp->m_allocsize_log = ffs(size) - 1;
  		mp->m_flags |= XFS_MOUNT_ALLOCSIZE;
  		return 0;
  	case Opt_grpid:
  	case Opt_bsdgroups:
  		mp->m_flags |= XFS_MOUNT_GRPID;
  		return 0;
  	case Opt_nogrpid:
  	case Opt_sysvgroups:
  		mp->m_flags &= ~XFS_MOUNT_GRPID;
  		return 0;
  	case Opt_wsync:
  		mp->m_flags |= XFS_MOUNT_WSYNC;
  		return 0;
  	case Opt_norecovery:
  		mp->m_flags |= XFS_MOUNT_NORECOVERY;
  		return 0;
  	case Opt_noalign:
  		mp->m_flags |= XFS_MOUNT_NOALIGN;
  		return 0;
  	case Opt_swalloc:
  		mp->m_flags |= XFS_MOUNT_SWALLOC;
  		return 0;
  	case Opt_sunit:
  		mp->m_dalign = result.uint_32;
  		return 0;
  	case Opt_swidth:
  		mp->m_swidth = result.uint_32;
  		return 0;
  	case Opt_inode32:
  		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
  		return 0;
  	case Opt_inode64:
  		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
  		return 0;
  	case Opt_nouuid:
  		mp->m_flags |= XFS_MOUNT_NOUUID;
  		return 0;
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1191
1192
1193
1194
1195
1196
  	case Opt_largeio:
  		mp->m_flags |= XFS_MOUNT_LARGEIO;
  		return 0;
  	case Opt_nolargeio:
  		mp->m_flags &= ~XFS_MOUNT_LARGEIO;
  		return 0;
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
  	case Opt_filestreams:
  		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
  		return 0;
  	case Opt_noquota:
  		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
  		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
  		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
  		return 0;
  	case Opt_quota:
  	case Opt_uquota:
  	case Opt_usrquota:
  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
  				 XFS_UQUOTA_ENFD);
  		return 0;
  	case Opt_qnoenforce:
  	case Opt_uqnoenforce:
  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
  		mp->m_qflags &= ~XFS_UQUOTA_ENFD;
  		return 0;
  	case Opt_pquota:
  	case Opt_prjquota:
  		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
  				 XFS_PQUOTA_ENFD);
  		return 0;
  	case Opt_pqnoenforce:
  		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
  		mp->m_qflags &= ~XFS_PQUOTA_ENFD;
  		return 0;
  	case Opt_gquota:
  	case Opt_grpquota:
  		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
  				 XFS_GQUOTA_ENFD);
  		return 0;
  	case Opt_gqnoenforce:
  		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
  		mp->m_qflags &= ~XFS_GQUOTA_ENFD;
  		return 0;
  	case Opt_discard:
  		mp->m_flags |= XFS_MOUNT_DISCARD;
  		return 0;
  	case Opt_nodiscard:
  		mp->m_flags &= ~XFS_MOUNT_DISCARD;
  		return 0;
  #ifdef CONFIG_FS_DAX
  	case Opt_dax:
8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
1242
1243
1244
1245
  		xfs_mount_set_dax_mode(mp, XFS_DAX_ALWAYS);
  		return 0;
  	case Opt_dax_enum:
  		xfs_mount_set_dax_mode(mp, result.uint_32);
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1246
1247
  		return 0;
  #endif
c23c393ea   Pavel Reichl   xfs: remove depre...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
  	/* Following mount options will be removed in September 2025 */
  	case Opt_ikeep:
  		xfs_warn(mp, "%s mount option is deprecated.", param->key);
  		mp->m_flags |= XFS_MOUNT_IKEEP;
  		return 0;
  	case Opt_noikeep:
  		xfs_warn(mp, "%s mount option is deprecated.", param->key);
  		mp->m_flags &= ~XFS_MOUNT_IKEEP;
  		return 0;
  	case Opt_attr2:
  		xfs_warn(mp, "%s mount option is deprecated.", param->key);
  		mp->m_flags |= XFS_MOUNT_ATTR2;
  		return 0;
  	case Opt_noattr2:
  		xfs_warn(mp, "%s mount option is deprecated.", param->key);
  		mp->m_flags &= ~XFS_MOUNT_ATTR2;
  		mp->m_flags |= XFS_MOUNT_NOATTR2;
  		return 0;
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1266
1267
1268
1269
  	default:
  		xfs_warn(mp, "unknown mount option [%s].", param->key);
  		return -EINVAL;
  	}
d5db0f97f   Eric Sandeen   xfs: more reserve...
1270

d5db0f97f   Eric Sandeen   xfs: more reserve...
1271
1272
  	return 0;
  }
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1273
1274
  static int
  xfs_fc_validate_params(
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1275
1276
  	struct xfs_mount	*mp)
  {
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1277
  	/*
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1278
  	 * no recovery flag requires a read-only mount
d3eaace84   Dave Chinner   xfs: disable noat...
1279
  	 */
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1280
1281
1282
  	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
  	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
  		xfs_warn(mp, "no-recovery mounts must be read-only.");
2451337dd   Dave Chinner   xfs: global error...
1283
  		return -EINVAL;
d3eaace84   Dave Chinner   xfs: disable noat...
1284
  	}
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1285
1286
  	if ((mp->m_flags & XFS_MOUNT_NOALIGN) &&
  	    (mp->m_dalign || mp->m_swidth)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1287
  		xfs_warn(mp,
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1288
1289
  	"sunit and swidth options incompatible with the noalign option");
  		return -EINVAL;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1290
  	}
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1291
1292
  	if (!IS_ENABLED(CONFIG_XFS_QUOTA) && mp->m_qflags != 0) {
  		xfs_warn(mp, "quota support not available in this kernel.");
2451337dd   Dave Chinner   xfs: global error...
1293
  		return -EINVAL;
d892d5864   Chandra Seetharaman   xfs: Start using ...
1294
  	}
8757c38f2   Ian Kent   xfs: move xfs_fc_...
1295
1296
1297
1298
1299
  	if ((mp->m_dalign && !mp->m_swidth) ||
  	    (!mp->m_dalign && mp->m_swidth)) {
  		xfs_warn(mp, "sunit and swidth must be specified together");
  		return -EINVAL;
  	}
5681ca400   Dave Chinner   xfs: Remove icsb ...
1300

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1301
1302
1303
1304
1305
1306
  	if (mp->m_dalign && (mp->m_swidth % mp->m_dalign != 0)) {
  		xfs_warn(mp,
  	"stripe width (%d) must be a multiple of the stripe unit (%d)",
  			mp->m_swidth, mp->m_dalign);
  		return -EINVAL;
  	}
5681ca400   Dave Chinner   xfs: Remove icsb ...
1307

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1308
1309
1310
1311
1312
1313
1314
1315
  	if (mp->m_logbufs != -1 &&
  	    mp->m_logbufs != 0 &&
  	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
  	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
  		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
  			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
  		return -EINVAL;
  	}
5681ca400   Dave Chinner   xfs: Remove icsb ...
1316

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  	if (mp->m_logbsize != -1 &&
  	    mp->m_logbsize !=  0 &&
  	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
  	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
  	     !is_power_of_2(mp->m_logbsize))) {
  		xfs_warn(mp,
  			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
  			mp->m_logbsize);
  		return -EINVAL;
  	}
5681ca400   Dave Chinner   xfs: Remove icsb ...
1327

8757c38f2   Ian Kent   xfs: move xfs_fc_...
1328
1329
1330
1331
1332
1333
1334
  	if ((mp->m_flags & XFS_MOUNT_ALLOCSIZE) &&
  	    (mp->m_allocsize_log > XFS_MAX_IO_LOG ||
  	     mp->m_allocsize_log < XFS_MIN_IO_LOG)) {
  		xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
  			mp->m_allocsize_log, XFS_MIN_IO_LOG, XFS_MAX_IO_LOG);
  		return -EINVAL;
  	}
9fe82b8c4   Darrick J. Wong   xfs: track delaye...
1335

5681ca400   Dave Chinner   xfs: Remove icsb ...
1336
  	return 0;
72c44e35f   Brian Foster   xfs: clean up xfs...
1337
  }
743944967   Christoph Hellwig   [XFS] move syncin...
1338

73e5fff98   Ian Kent   xfs: switch to us...
1339
1340
  static int
  xfs_fc_fill_super(
72c44e35f   Brian Foster   xfs: clean up xfs...
1341
  	struct super_block	*sb,
73e5fff98   Ian Kent   xfs: switch to us...
1342
  	struct fs_context	*fc)
72c44e35f   Brian Foster   xfs: clean up xfs...
1343
  {
73e5fff98   Ian Kent   xfs: switch to us...
1344
  	struct xfs_mount	*mp = sb->s_fs_info;
72c44e35f   Brian Foster   xfs: clean up xfs...
1345
  	struct inode		*root;
0279c71fe   Colin Ian King   xfs: remove redun...
1346
  	int			flags = 0, error;
72c44e35f   Brian Foster   xfs: clean up xfs...
1347

7c89fcb27   Ian Kent   xfs: dont set sb ...
1348
  	mp->m_super = sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1349

73e5fff98   Ian Kent   xfs: switch to us...
1350
  	error = xfs_fc_validate_params(mp);
745f69191   Christoph Hellwig   [XFS] call common...
1351
  	if (error)
e1d3d2188   Ian Kent   xfs: use super s_...
1352
  		goto out_free_names;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
1354
  
  	sb_min_blocksize(sb, BBSIZE);
0ec585163   Lachlan McIlroy   [XFS] Use the gen...
1355
  	sb->s_xattr = xfs_xattr_handlers;
a50cd2692   Nathan Scott   [XFS] Switch over...
1356
  	sb->s_export_op = &xfs_export_operations;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1357
  #ifdef CONFIG_XFS_QUOTA
a50cd2692   Nathan Scott   [XFS] Switch over...
1358
  	sb->s_qcop = &xfs_quotactl_operations;
17ef4fdd3   Jan Kara   xfs: Set allowed ...
1359
  	sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1360
  #endif
a50cd2692   Nathan Scott   [XFS] Switch over...
1361
  	sb->s_op = &xfs_super_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362

dae5cd811   Dave Chinner   xfs: add mount de...
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
  	/*
  	 * Delay mount work if the debug hook is set. This is debug
  	 * instrumention to coordinate simulation of xfs mount failures with
  	 * VFS superblock operations
  	 */
  	if (xfs_globals.mount_delay) {
  		xfs_notice(mp, "Delaying mount for %d seconds.",
  			xfs_globals.mount_delay);
  		msleep(xfs_globals.mount_delay * 1000);
  	}
73e5fff98   Ian Kent   xfs: switch to us...
1373
  	if (fc->sb_flags & SB_SILENT)
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1374
  		flags |= XFS_MFSI_QUIET;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1375
  	error = xfs_open_devices(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1376
  	if (error)
e1d3d2188   Ian Kent   xfs: use super s_...
1377
  		goto out_free_names;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1378

2451337dd   Dave Chinner   xfs: global error...
1379
  	error = xfs_init_mount_workqueues(mp);
61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1380
1381
  	if (error)
  		goto out_close_devices;
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1382

5681ca400   Dave Chinner   xfs: Remove icsb ...
1383
  	error = xfs_init_percpu_counters(mp);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1384
1385
  	if (error)
  		goto out_destroy_workqueues;
225e46355   Bill O'Donnell   xfs: per-filesyst...
1386
1387
1388
  	/* Allocate stats memory before we do operations that might use it */
  	mp->m_stats.xs_stats = alloc_percpu(struct xfsstats);
  	if (!mp->m_stats.xs_stats) {
f9d460b34   Dan Carpenter   xfs: fix an error...
1389
  		error = -ENOMEM;
225e46355   Bill O'Donnell   xfs: per-filesyst...
1390
1391
  		goto out_destroy_counters;
  	}
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1392
1393
  	error = xfs_readsb(mp, flags);
  	if (error)
225e46355   Bill O'Donnell   xfs: per-filesyst...
1394
  		goto out_free_stats;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1395
1396
  
  	error = xfs_finish_flags(mp);
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1397
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1398
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1399

e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
1400
  	error = xfs_setup_devices(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1401
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1402
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1403

b96cb835e   Darrick J. Wong   xfs: deprecate th...
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
  	/* V4 support is undergoing deprecation. */
  	if (!xfs_sb_version_hascrc(&mp->m_sb)) {
  #ifdef CONFIG_XFS_SUPPORT_V4
  		xfs_warn_once(mp,
  	"Deprecated V4 format (crc=0) will not be supported after September 2030.");
  #else
  		xfs_warn(mp,
  	"Deprecated V4 format (crc=0) not supported by kernel.");
  		error = -EINVAL;
  		goto out_free_sb;
  #endif
  	}
932befe39   Darrick J. Wong   xfs: fix s_maxbyt...
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
  	/*
  	 * XFS block mappings use 54 bits to store the logical block offset.
  	 * This should suffice to handle the maximum file size that the VFS
  	 * supports (currently 2^63 bytes on 64-bit and ULONG_MAX << PAGE_SHIFT
  	 * bytes on 32-bit), but as XFS and VFS have gotten the s_maxbytes
  	 * calculation wrong on 32-bit kernels in the past, we'll add a WARN_ON
  	 * to check this assertion.
  	 *
  	 * Avoid integer overflow by comparing the maximum bmbt offset to the
  	 * maximum pagecache offset in units of fs blocks.
  	 */
  	if (XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE) > XFS_MAX_FILEOFF) {
  		xfs_warn(mp,
  "MAX_LFS_FILESIZE block offset (%llu) exceeds extent map maximum (%llu)!",
  			 XFS_B_TO_FSBT(mp, MAX_LFS_FILESIZE),
  			 XFS_MAX_FILEOFF);
  		error = -EINVAL;
  		goto out_free_sb;
  	}
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1435
1436
  	error = xfs_filestream_mount(mp);
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1437
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1438

704b2907c   Dave Chinner   xfs: register the...
1439
1440
1441
  	/*
  	 * we must configure the block size in the superblock before we run the
  	 * full mount process as the mount process can lookup and cache inodes.
704b2907c   Dave Chinner   xfs: register the...
1442
  	 */
dddde68b8   Adam Borowski   xfs: add a define...
1443
  	sb->s_magic = XFS_SUPER_MAGIC;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1444
1445
  	sb->s_blocksize = mp->m_sb.sb_blocksize;
  	sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
932befe39   Darrick J. Wong   xfs: fix s_maxbyt...
1446
  	sb->s_maxbytes = MAX_LFS_FILESIZE;
8de527787   Al Viro   vfs: check i_nlin...
1447
  	sb->s_max_links = XFS_MAXLINK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  	sb->s_time_gran = 1;
f93e5436f   Darrick J. Wong   xfs: widen ondisk...
1449
1450
1451
1452
1453
1454
1455
  	if (xfs_sb_version_hasbigtime(&mp->m_sb)) {
  		sb->s_time_min = xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MIN);
  		sb->s_time_max = xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MAX);
  	} else {
  		sb->s_time_min = XFS_LEGACY_TIME_MIN;
  		sb->s_time_max = XFS_LEGACY_TIME_MAX;
  	}
06dbf82b0   Darrick J. Wong   xfs: trace timest...
1456
  	trace_xfs_inode_timestamp_range(mp, sb->s_time_min, sb->s_time_max);
adfb5fb46   Christoph Hellwig   xfs: implement cg...
1457
  	sb->s_iflags |= SB_I_CGROUPWB;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1458
  	set_posix_acl_flag(sb);
dc037ad7d   Dave Chinner   xfs: implement in...
1459
1460
  	/* version 5 superblocks support inode version counters. */
  	if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
357fdad07   Matthew Garrett   Convert fs/*/* to...
1461
  		sb->s_flags |= SB_I_VERSION;
dc037ad7d   Dave Chinner   xfs: implement in...
1462

f93e5436f   Darrick J. Wong   xfs: widen ondisk...
1463
1464
1465
  	if (xfs_sb_version_hasbigtime(&mp->m_sb))
  		xfs_warn(mp,
   "EXPERIMENTAL big timestamp feature in use. Use at your own risk!");
606723d98   Ira Weiny   fs/xfs: Change XF...
1466
  	if (mp->m_flags & XFS_MOUNT_DAX_ALWAYS) {
80660f202   Dave Jiang   dax: change bdev_...
1467
  		bool rtdev_is_dax = false, datadev_is_dax;
ba23cba9b   Darrick J. Wong   fs: allow per-dev...
1468

cbe4dab11   Dave Chinner   xfs: add initial ...
1469
  		xfs_warn(mp,
1e937cddd   Toshi Kani   xfs: Add alignmen...
1470
  		"DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
80660f202   Dave Jiang   dax: change bdev_...
1471
1472
  		datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
  			sb->s_blocksize);
ba23cba9b   Darrick J. Wong   fs: allow per-dev...
1473
  		if (mp->m_rtdev_targp)
80660f202   Dave Jiang   dax: change bdev_...
1474
1475
1476
  			rtdev_is_dax = bdev_dax_supported(
  				mp->m_rtdev_targp->bt_bdev, sb->s_blocksize);
  		if (!rtdev_is_dax && !datadev_is_dax) {
cbe4dab11   Dave Chinner   xfs: add initial ...
1477
  			xfs_alert(mp,
1e937cddd   Toshi Kani   xfs: Add alignmen...
1478
  			"DAX unsupported by block device. Turning off DAX.");
8d6c3446e   Ira Weiny   fs/xfs: Make DAX ...
1479
  			xfs_mount_set_dax_mode(mp, XFS_DAX_NEVER);
cbe4dab11   Dave Chinner   xfs: add initial ...
1480
  		}
b6e03c10b   Darrick J. Wong   xfs: don't allow ...
1481
  		if (xfs_sb_version_hasreflink(&mp->m_sb)) {
e54b5bf9d   Darrick J. Wong   xfs: recognize th...
1482
  			xfs_alert(mp,
1e369b0e1   Christoph Hellwig   xfs: remove exper...
1483
  		"DAX and reflink cannot be used together!");
b6e03c10b   Darrick J. Wong   xfs: don't allow ...
1484
1485
1486
  			error = -EINVAL;
  			goto out_filestream_unmount;
  		}
cbe4dab11   Dave Chinner   xfs: add initial ...
1487
  	}
1e6fa688b   Kenjiro Nakayama   xfs: Output warni...
1488
1489
1490
1491
1492
1493
1494
1495
1496
  	if (mp->m_flags & XFS_MOUNT_DISCARD) {
  		struct request_queue *q = bdev_get_queue(sb->s_bdev);
  
  		if (!blk_queue_discard(q)) {
  			xfs_warn(mp, "mounting with \"discard\" option, but "
  					"the device does not support discard");
  			mp->m_flags &= ~XFS_MOUNT_DISCARD;
  		}
  	}
66ae56a53   Christoph Hellwig   xfs: introduce an...
1497
1498
1499
  	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
  		if (mp->m_sb.sb_rblocks) {
  			xfs_alert(mp,
c14632dda   Darrick J. Wong   xfs: don't allow ...
1500
  	"reflink not compatible with realtime device!");
66ae56a53   Christoph Hellwig   xfs: introduce an...
1501
1502
1503
1504
1505
1506
1507
1508
  			error = -EINVAL;
  			goto out_filestream_unmount;
  		}
  
  		if (xfs_globals.always_cow) {
  			xfs_info(mp, "using DEBUG-only always_cow mode.");
  			mp->m_always_cow = true;
  		}
c14632dda   Darrick J. Wong   xfs: don't allow ...
1509
  	}
76883f798   Darrick J. Wong   xfs: remove exper...
1510
  	if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks) {
1c0607ace   Darrick J. Wong   xfs: enable the r...
1511
  		xfs_alert(mp,
76883f798   Darrick J. Wong   xfs: remove exper...
1512
1513
1514
  	"reverse mapping btree not compatible with realtime device!");
  		error = -EINVAL;
  		goto out_filestream_unmount;
738f57c16   Darrick J. Wong   xfs: disallow mou...
1515
  	}
1c0607ace   Darrick J. Wong   xfs: enable the r...
1516

2a39946c9   Darrick J. Wong   xfs: store inode ...
1517
1518
1519
  	if (xfs_sb_version_hasinobtcounts(&mp->m_sb))
  		xfs_warn(mp,
   "EXPERIMENTAL inode btree counters feature in use. Use at your own risk!");
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1520
  	error = xfs_mountfs(mp);
2bcf6e970   Christoph Hellwig   xfs: start period...
1521
  	if (error)
7e18530be   Dave Chinner   xfs: rationalise ...
1522
  		goto out_filestream_unmount;
704b2907c   Dave Chinner   xfs: register the...
1523

016516462   David Chinner   [XFS] Avoid direc...
1524
  	root = igrab(VFS_I(mp->m_rootip));
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1525
  	if (!root) {
2451337dd   Dave Chinner   xfs: global error...
1526
  		error = -ENOENT;
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1527
  		goto out_unmount;
cbc89dcfd   Christoph Hellwig   [XFS] kill xfs_root
1528
  	}
48fde701a   Al Viro   switch open-coded...
1529
  	sb->s_root = d_make_root(root);
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1530
  	if (!sb->s_root) {
2451337dd   Dave Chinner   xfs: global error...
1531
  		error = -ENOMEM;
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1532
  		goto out_unmount;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1533
  	}
743944967   Christoph Hellwig   [XFS] move syncin...
1534

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
  	return 0;
33c7a2bc4   Dave Chinner   xfs: xfs_syncd_st...
1536

7e18530be   Dave Chinner   xfs: rationalise ...
1537
   out_filestream_unmount:
120226c11   Christoph Hellwig   [XFS] add missing...
1538
  	xfs_filestream_unmount(mp);
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1539
1540
   out_free_sb:
  	xfs_freesb(mp);
225e46355   Bill O'Donnell   xfs: per-filesyst...
1541
1542
   out_free_stats:
  	free_percpu(mp->m_stats.xs_stats);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1543
   out_destroy_counters:
5681ca400   Dave Chinner   xfs: Remove icsb ...
1544
  	xfs_destroy_percpu_counters(mp);
225e46355   Bill O'Donnell   xfs: per-filesyst...
1545
   out_destroy_workqueues:
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1546
  	xfs_destroy_mount_workqueues(mp);
61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1547
   out_close_devices:
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1548
  	xfs_close_devices(mp);
e1d3d2188   Ian Kent   xfs: use super s_...
1549
   out_free_names:
c9fbd7bbc   Dave Chinner   xfs: clear sb->s_...
1550
  	sb->s_fs_info = NULL;
a943f372c   Ian Kent   xfs: merge freein...
1551
  	xfs_mount_free(mp);
2451337dd   Dave Chinner   xfs: global error...
1552
  	return error;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1553

2bcf6e970   Christoph Hellwig   xfs: start period...
1554
   out_unmount:
e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
1555
  	xfs_filestream_unmount(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1556
  	xfs_unmountfs(mp);
6203300e5   Christoph Hellwig   [XFS] don't call ...
1557
  	goto out_free_sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558
  }
73e5fff98   Ian Kent   xfs: switch to us...
1559
1560
1561
1562
1563
1564
  static int
  xfs_fc_get_tree(
  	struct fs_context	*fc)
  {
  	return get_tree_bdev(fc, xfs_fc_fill_super);
  }
63cd1e9b0   Ian Kent   xfs: move xfs_fc_...
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
  static int
  xfs_remount_rw(
  	struct xfs_mount	*mp)
  {
  	struct xfs_sb		*sbp = &mp->m_sb;
  	int error;
  
  	if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
  		xfs_warn(mp,
  			"ro->rw transition prohibited on norecovery mount");
  		return -EINVAL;
  	}
  
  	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
  	    xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
  		xfs_warn(mp,
  	"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
  			(sbp->sb_features_ro_compat &
  				XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
  		return -EINVAL;
  	}
  
  	mp->m_flags &= ~XFS_MOUNT_RDONLY;
  
  	/*
  	 * If this is the first remount to writeable state we might have some
  	 * superblock changes to update.
  	 */
  	if (mp->m_update_sb) {
  		error = xfs_sync_sb(mp, false);
  		if (error) {
  			xfs_warn(mp, "failed to write sb changes");
  			return error;
  		}
  		mp->m_update_sb = false;
  	}
  
  	/*
  	 * Fill out the reserve pool if it is empty. Use the stashed value if
  	 * it is non-zero, otherwise go with the default.
  	 */
  	xfs_restore_resvblks(mp);
  	xfs_log_work_queue(mp);
  
  	/* Recover any CoW blocks that never got remapped. */
  	error = xfs_reflink_recover_cow(mp);
  	if (error) {
  		xfs_err(mp,
  			"Error %d recovering leftover CoW allocations.", error);
7f6bcf7c2   Dan Carpenter   xfs: remove a str...
1614
  		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
63cd1e9b0   Ian Kent   xfs: move xfs_fc_...
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
  		return error;
  	}
  	xfs_start_block_reaping(mp);
  
  	/* Create the per-AG metadata reservation pool .*/
  	error = xfs_fs_reserve_ag_blocks(mp);
  	if (error && error != -ENOSPC)
  		return error;
  
  	return 0;
  }
  
  static int
  xfs_remount_ro(
  	struct xfs_mount	*mp)
  {
  	int error;
  
  	/*
  	 * Cancel background eofb scanning so it cannot race with the final
  	 * log force+buftarg wait and deadlock the remount.
  	 */
  	xfs_stop_block_reaping(mp);
  
  	/* Get rid of any leftover CoW reservations... */
  	error = xfs_icache_free_cowblocks(mp, NULL);
  	if (error) {
  		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
  		return error;
  	}
  
  	/* Free the per-AG metadata reservation pool. */
  	error = xfs_fs_unreserve_ag_blocks(mp);
  	if (error) {
  		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
  		return error;
  	}
  
  	/*
  	 * Before we sync the metadata, we need to free up the reserve block
  	 * pool so that the used block count in the superblock on disk is
  	 * correct at the end of the remount. Stash the current* reserve pool
  	 * size so that if we get remounted rw, we can return it to the same
  	 * size.
  	 */
  	xfs_save_resvblks(mp);
  
  	xfs_quiesce_attr(mp);
  	mp->m_flags |= XFS_MOUNT_RDONLY;
  
  	return 0;
  }
  
  /*
   * Logically we would return an error here to prevent users from believing
   * they might have changed mount options using remount which can't be changed.
   *
   * But unfortunately mount(8) adds all options from mtab and fstab to the mount
   * arguments in some cases so we can't blindly reject options, but have to
   * check for each specified option if it actually differs from the currently
   * set option and only reject it if that's the case.
   *
   * Until that is implemented we return success for every remount request, and
   * silently ignore all options that we can't actually change.
   */
  static int
  xfs_fc_reconfigure(
  	struct fs_context *fc)
  {
  	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
  	struct xfs_mount        *new_mp = fc->s_fs_info;
  	xfs_sb_t		*sbp = &mp->m_sb;
  	int			flags = fc->sb_flags;
  	int			error;
4750a171c   Eric Sandeen   xfs: preserve ino...
1689
1690
1691
  	/* version 5 superblocks always support version counters. */
  	if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
  		fc->sb_flags |= SB_I_VERSION;
63cd1e9b0   Ian Kent   xfs: move xfs_fc_...
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
  	error = xfs_fc_validate_params(new_mp);
  	if (error)
  		return error;
  
  	sync_filesystem(mp->m_super);
  
  	/* inode32 -> inode64 */
  	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
  	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
  		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
  		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
  	}
  
  	/* inode64 -> inode32 */
  	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
  	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
  		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
  		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
  	}
  
  	/* ro -> rw */
  	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
  		error = xfs_remount_rw(mp);
  		if (error)
  			return error;
  	}
  
  	/* rw -> ro */
  	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
  		error = xfs_remount_ro(mp);
  		if (error)
  			return error;
  	}
  
  	return 0;
  }
73e5fff98   Ian Kent   xfs: switch to us...
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
  static void xfs_fc_free(
  	struct fs_context	*fc)
  {
  	struct xfs_mount	*mp = fc->s_fs_info;
  
  	/*
  	 * mp is stored in the fs_context when it is initialized.
  	 * mp is transferred to the superblock on a successful mount,
  	 * but if an error occurs before the transfer we have to free
  	 * it here.
  	 */
  	if (mp)
  		xfs_mount_free(mp);
  }
  
  static const struct fs_context_operations xfs_context_ops = {
  	.parse_param = xfs_fc_parse_param,
  	.get_tree    = xfs_fc_get_tree,
  	.reconfigure = xfs_fc_reconfigure,
  	.free        = xfs_fc_free,
  };
  
  static int xfs_init_fs_context(
  	struct fs_context	*fc)
  {
  	struct xfs_mount	*mp;
50f830090   Ian Kent   xfs: fold xfs_mou...
1754
  	mp = kmem_alloc(sizeof(struct xfs_mount), KM_ZERO);
73e5fff98   Ian Kent   xfs: switch to us...
1755
1756
  	if (!mp)
  		return -ENOMEM;
50f830090   Ian Kent   xfs: fold xfs_mou...
1757
1758
1759
1760
1761
  	spin_lock_init(&mp->m_sb_lock);
  	spin_lock_init(&mp->m_agirotor_lock);
  	INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
  	spin_lock_init(&mp->m_perag_lock);
  	mutex_init(&mp->m_growlock);
f0f7a674d   Darrick J. Wong   xfs: move inode f...
1762
  	INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker);
50f830090   Ian Kent   xfs: fold xfs_mou...
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
  	INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
  	INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
  	INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
  	mp->m_kobj.kobject.kset = xfs_kset;
  	/*
  	 * We don't create the finobt per-ag space reservation until after log
  	 * recovery, so we must set this to true so that an ifree transaction
  	 * started during log recovery will not depend on space reservations
  	 * for finobt expansion.
  	 */
  	mp->m_finobt_nores = true;
73e5fff98   Ian Kent   xfs: switch to us...
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
  	/*
  	 * These can be overridden by the mount option parsing.
  	 */
  	mp->m_logbufs = -1;
  	mp->m_logbsize = -1;
  	mp->m_allocsize_log = 16; /* 64k */
  
  	/*
  	 * Copy binary VFS mount flags we are interested in.
  	 */
  	if (fc->sb_flags & SB_RDONLY)
  		mp->m_flags |= XFS_MOUNT_RDONLY;
  	if (fc->sb_flags & SB_DIRSYNC)
  		mp->m_flags |= XFS_MOUNT_DIRSYNC;
  	if (fc->sb_flags & SB_SYNCHRONOUS)
  		mp->m_flags |= XFS_MOUNT_WSYNC;
  
  	fc->s_fs_info = mp;
  	fc->ops = &xfs_context_ops;
  
  	return 0;
  }
5085b607f   Andrew Morton   [PATCH] xfs warni...
1796
  static struct file_system_type xfs_fs_type = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1797
1798
  	.owner			= THIS_MODULE,
  	.name			= "xfs",
73e5fff98   Ian Kent   xfs: switch to us...
1799
  	.init_fs_context	= xfs_init_fs_context,
d7167b149   Al Viro   fs_parse: fold fs...
1800
  	.parameters		= xfs_fs_parameters,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801
1802
1803
  	.kill_sb		= kill_block_super,
  	.fs_flags		= FS_REQUIRES_DEV,
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1804
  MODULE_ALIAS_FS("xfs");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1805

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1806
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1807
1808
  xfs_init_zones(void)
  {
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1809
1810
1811
  	xfs_log_ticket_zone = kmem_cache_create("xfs_log_ticket",
  						sizeof(struct xlog_ticket),
  						0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1812
  	if (!xfs_log_ticket_zone)
598ecfbaa   Christoph Hellwig   iomap: lift the x...
1813
  		goto out;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1814

b1231760e   Carlos Maiolino   xfs: Remove slab ...
1815
1816
1817
  	xfs_bmap_free_item_zone = kmem_cache_create("xfs_bmap_free_item",
  					sizeof(struct xfs_extent_free_item),
  					0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1818
1819
  	if (!xfs_bmap_free_item_zone)
  		goto out_destroy_log_ticket_zone;
bf904248a   David Chinner   [XFS] Combine the...
1820

b1231760e   Carlos Maiolino   xfs: Remove slab ...
1821
1822
1823
  	xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur",
  					       sizeof(struct xfs_btree_cur),
  					       0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1824
1825
  	if (!xfs_btree_cur_zone)
  		goto out_destroy_bmap_free_item_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1826
1827
1828
  	xfs_da_state_zone = kmem_cache_create("xfs_da_state",
  					      sizeof(struct xfs_da_state),
  					      0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1829
1830
  	if (!xfs_da_state_zone)
  		goto out_destroy_btree_cur_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1831
1832
1833
  	xfs_ifork_zone = kmem_cache_create("xfs_ifork",
  					   sizeof(struct xfs_ifork),
  					   0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1834
  	if (!xfs_ifork_zone)
1d9025e56   Dave Chinner   xfs: remove struc...
1835
  		goto out_destroy_da_state_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1836

b1231760e   Carlos Maiolino   xfs: Remove slab ...
1837
1838
1839
  	xfs_trans_zone = kmem_cache_create("xf_trans",
  					   sizeof(struct xfs_trans),
  					   0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1840
1841
  	if (!xfs_trans_zone)
  		goto out_destroy_ifork_zone;
e98c414f9   Christoph Hellwig   xfs: simplify log...
1842

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1843
1844
1845
1846
1847
  	/*
  	 * The size of the zone allocated buf log item is the maximum
  	 * size possible under XFS.  This wastes a little bit of memory,
  	 * but it is much faster.
  	 */
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1848
1849
1850
  	xfs_buf_item_zone = kmem_cache_create("xfs_buf_item",
  					      sizeof(struct xfs_buf_log_item),
  					      0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1851
  	if (!xfs_buf_item_zone)
e6631f855   Dave Chinner   xfs: get rid of t...
1852
  		goto out_destroy_trans_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1853

b1231760e   Carlos Maiolino   xfs: Remove slab ...
1854
1855
1856
1857
1858
  	xfs_efd_zone = kmem_cache_create("xfs_efd_item",
  					(sizeof(struct xfs_efd_log_item) +
  					(XFS_EFD_MAX_FAST_EXTENTS - 1) *
  					sizeof(struct xfs_extent)),
  					0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1859
1860
  	if (!xfs_efd_zone)
  		goto out_destroy_buf_item_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1861
1862
1863
1864
1865
  	xfs_efi_zone = kmem_cache_create("xfs_efi_item",
  					 (sizeof(struct xfs_efi_log_item) +
  					 (XFS_EFI_MAX_FAST_EXTENTS - 1) *
  					 sizeof(struct xfs_extent)),
  					 0, 0, NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1866
1867
  	if (!xfs_efi_zone)
  		goto out_destroy_efd_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1868
1869
1870
1871
1872
1873
  	xfs_inode_zone = kmem_cache_create("xfs_inode",
  					   sizeof(struct xfs_inode), 0,
  					   (SLAB_HWCACHE_ALIGN |
  					    SLAB_RECLAIM_ACCOUNT |
  					    SLAB_MEM_SPREAD | SLAB_ACCOUNT),
  					   xfs_fs_inode_init_once);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1874
1875
  	if (!xfs_inode_zone)
  		goto out_destroy_efi_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1876
1877
  	xfs_ili_zone = kmem_cache_create("xfs_ili",
  					 sizeof(struct xfs_inode_log_item), 0,
d59eadaea   Dave Chinner   xfs: correctly ac...
1878
1879
  					 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
  					 NULL);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1880
1881
  	if (!xfs_ili_zone)
  		goto out_destroy_inode_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1882
1883
1884
1885
  
  	xfs_icreate_zone = kmem_cache_create("xfs_icr",
  					     sizeof(struct xfs_icreate_item),
  					     0, 0, NULL);
3ebe7d2d7   Dave Chinner   xfs: Inode create...
1886
1887
  	if (!xfs_icreate_zone)
  		goto out_destroy_ili_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1888

b1231760e   Carlos Maiolino   xfs: Remove slab ...
1889
1890
1891
  	xfs_rud_zone = kmem_cache_create("xfs_rud_item",
  					 sizeof(struct xfs_rud_log_item),
  					 0, 0, NULL);
5880f2d78   Darrick J. Wong   xfs: create rmap ...
1892
1893
  	if (!xfs_rud_zone)
  		goto out_destroy_icreate_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1894
  	xfs_rui_zone = kmem_cache_create("xfs_rui_item",
cd00158ce   Darrick J. Wong   xfs: convert RUI ...
1895
  			xfs_rui_log_item_sizeof(XFS_RUI_MAX_FAST_EXTENTS),
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1896
  			0, 0, NULL);
5880f2d78   Darrick J. Wong   xfs: create rmap ...
1897
1898
  	if (!xfs_rui_zone)
  		goto out_destroy_rud_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1899
1900
1901
  	xfs_cud_zone = kmem_cache_create("xfs_cud_item",
  					 sizeof(struct xfs_cud_log_item),
  					 0, 0, NULL);
baf4bcacb   Darrick J. Wong   xfs: create refco...
1902
1903
  	if (!xfs_cud_zone)
  		goto out_destroy_rui_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1904
  	xfs_cui_zone = kmem_cache_create("xfs_cui_item",
baf4bcacb   Darrick J. Wong   xfs: create refco...
1905
  			xfs_cui_log_item_sizeof(XFS_CUI_MAX_FAST_EXTENTS),
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1906
  			0, 0, NULL);
baf4bcacb   Darrick J. Wong   xfs: create refco...
1907
1908
  	if (!xfs_cui_zone)
  		goto out_destroy_cud_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1909
1910
1911
  	xfs_bud_zone = kmem_cache_create("xfs_bud_item",
  					 sizeof(struct xfs_bud_log_item),
  					 0, 0, NULL);
6413a0142   Darrick J. Wong   xfs: create bmbt ...
1912
1913
  	if (!xfs_bud_zone)
  		goto out_destroy_cui_zone;
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1914
  	xfs_bui_zone = kmem_cache_create("xfs_bui_item",
6413a0142   Darrick J. Wong   xfs: create bmbt ...
1915
  			xfs_bui_log_item_sizeof(XFS_BUI_MAX_FAST_EXTENTS),
b1231760e   Carlos Maiolino   xfs: Remove slab ...
1916
  			0, 0, NULL);
6413a0142   Darrick J. Wong   xfs: create bmbt ...
1917
1918
  	if (!xfs_bui_zone)
  		goto out_destroy_bud_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1919
  	return 0;
6413a0142   Darrick J. Wong   xfs: create bmbt ...
1920
   out_destroy_bud_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1921
  	kmem_cache_destroy(xfs_bud_zone);
6413a0142   Darrick J. Wong   xfs: create bmbt ...
1922
   out_destroy_cui_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1923
  	kmem_cache_destroy(xfs_cui_zone);
baf4bcacb   Darrick J. Wong   xfs: create refco...
1924
   out_destroy_cud_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1925
  	kmem_cache_destroy(xfs_cud_zone);
baf4bcacb   Darrick J. Wong   xfs: create refco...
1926
   out_destroy_rui_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1927
  	kmem_cache_destroy(xfs_rui_zone);
5880f2d78   Darrick J. Wong   xfs: create rmap ...
1928
   out_destroy_rud_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1929
  	kmem_cache_destroy(xfs_rud_zone);
5880f2d78   Darrick J. Wong   xfs: create rmap ...
1930
   out_destroy_icreate_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1931
  	kmem_cache_destroy(xfs_icreate_zone);
3ebe7d2d7   Dave Chinner   xfs: Inode create...
1932
   out_destroy_ili_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1933
  	kmem_cache_destroy(xfs_ili_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1934
   out_destroy_inode_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1935
  	kmem_cache_destroy(xfs_inode_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1936
   out_destroy_efi_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1937
  	kmem_cache_destroy(xfs_efi_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1938
   out_destroy_efd_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1939
  	kmem_cache_destroy(xfs_efd_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1940
   out_destroy_buf_item_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1941
  	kmem_cache_destroy(xfs_buf_item_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1942
   out_destroy_trans_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1943
  	kmem_cache_destroy(xfs_trans_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1944
   out_destroy_ifork_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1945
  	kmem_cache_destroy(xfs_ifork_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1946
   out_destroy_da_state_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1947
  	kmem_cache_destroy(xfs_da_state_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1948
   out_destroy_btree_cur_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1949
  	kmem_cache_destroy(xfs_btree_cur_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1950
   out_destroy_bmap_free_item_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1951
  	kmem_cache_destroy(xfs_bmap_free_item_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1952
   out_destroy_log_ticket_zone:
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1953
  	kmem_cache_destroy(xfs_log_ticket_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1954
1955
1956
1957
1958
1959
1960
   out:
  	return -ENOMEM;
  }
  
  STATIC void
  xfs_destroy_zones(void)
  {
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
1961
1962
1963
1964
1965
  	/*
  	 * Make sure all delayed rcu free are flushed before we
  	 * destroy caches.
  	 */
  	rcu_barrier();
aaf54eb8b   Carlos Maiolino   xfs: Remove kmem_...
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
  	kmem_cache_destroy(xfs_bui_zone);
  	kmem_cache_destroy(xfs_bud_zone);
  	kmem_cache_destroy(xfs_cui_zone);
  	kmem_cache_destroy(xfs_cud_zone);
  	kmem_cache_destroy(xfs_rui_zone);
  	kmem_cache_destroy(xfs_rud_zone);
  	kmem_cache_destroy(xfs_icreate_zone);
  	kmem_cache_destroy(xfs_ili_zone);
  	kmem_cache_destroy(xfs_inode_zone);
  	kmem_cache_destroy(xfs_efi_zone);
  	kmem_cache_destroy(xfs_efd_zone);
  	kmem_cache_destroy(xfs_buf_item_zone);
  	kmem_cache_destroy(xfs_trans_zone);
  	kmem_cache_destroy(xfs_ifork_zone);
  	kmem_cache_destroy(xfs_da_state_zone);
  	kmem_cache_destroy(xfs_btree_cur_zone);
  	kmem_cache_destroy(xfs_bmap_free_item_zone);
  	kmem_cache_destroy(xfs_log_ticket_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1984
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1985
1986
  
  STATIC int __init
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1987
1988
1989
  xfs_init_workqueues(void)
  {
  	/*
c999a223c   Dave Chinner   xfs: introduce an...
1990
1991
1992
1993
1994
  	 * The allocation workqueue can be used in memory reclaim situations
  	 * (writepage path), and parallelism is only limited by the number of
  	 * AGs in all the filesystems mounted. Hence use the default large
  	 * max_active value for this workqueue.
  	 */
8018ec083   Brian Foster   xfs: mark all int...
1995
1996
  	xfs_alloc_wq = alloc_workqueue("xfsalloc",
  			WQ_MEM_RECLAIM|WQ_FREEZABLE, 0);
c999a223c   Dave Chinner   xfs: introduce an...
1997
  	if (!xfs_alloc_wq)
5889608df   Dave Chinner   xfs: syncd workqu...
1998
  		return -ENOMEM;
c999a223c   Dave Chinner   xfs: introduce an...
1999

4560e78f4   Christoph Hellwig   xfs: don't block ...
2000
2001
2002
  	xfs_discard_wq = alloc_workqueue("xfsdiscard", WQ_UNBOUND, 0);
  	if (!xfs_discard_wq)
  		goto out_free_alloc_wq;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2003
  	return 0;
4560e78f4   Christoph Hellwig   xfs: don't block ...
2004
2005
2006
  out_free_alloc_wq:
  	destroy_workqueue(xfs_alloc_wq);
  	return -ENOMEM;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2007
  }
39411f81e   Tony Luck   xfs_destroy_workq...
2008
  STATIC void
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2009
2010
  xfs_destroy_workqueues(void)
  {
4560e78f4   Christoph Hellwig   xfs: don't block ...
2011
  	destroy_workqueue(xfs_discard_wq);
c999a223c   Dave Chinner   xfs: introduce an...
2012
  	destroy_workqueue(xfs_alloc_wq);
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2013
2014
2015
  }
  
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2016
  init_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2017
2018
  {
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2019

30cbc591c   Darrick J. Wong   xfs: check sizes ...
2020
  	xfs_check_ondisk_structs();
65795910c   Christoph Hellwig   [XFS] fix spuriou...
2021
2022
2023
  	printk(KERN_INFO XFS_VERSION_STRING " with "
  			 XFS_BUILD_OPTIONS " enabled
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2024

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2025
  	xfs_dir_startup();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2026

8758280fc   Nathan Scott   [XFS] Cleanup the...
2027
  	error = xfs_init_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2028
2029
  	if (error)
  		goto out;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2030
  	error = xfs_init_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2031
  	if (error)
0b1b213fc   Christoph Hellwig   xfs: event tracin...
2032
  		goto out_destroy_zones;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2033

0bf6a5bd4   Dave Chinner   xfs: convert the ...
2034
2035
2036
  	error = xfs_mru_cache_init();
  	if (error)
  		goto out_destroy_wq;
ce8e922c0   Nathan Scott   [XFS] Complete th...
2037
  	error = xfs_buf_init();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2038
  	if (error)
1919adda0   Christoph Hellwig   xfs: don't create...
2039
  		goto out_mru_cache_uninit;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2040
2041
2042
2043
2044
2045
2046
2047
  
  	error = xfs_init_procfs();
  	if (error)
  		goto out_buf_terminate;
  
  	error = xfs_sysctl_register();
  	if (error)
  		goto out_cleanup_procfs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2048

3d8712265   Brian Foster   xfs: add a sysfs ...
2049
2050
2051
  	xfs_kset = kset_create_and_add("xfs", NULL, fs_kobj);
  	if (!xfs_kset) {
  		error = -ENOMEM;
bb230c124   Bill O'Donnell   xfs: create globa...
2052
  		goto out_sysctl_unregister;
3d8712265   Brian Foster   xfs: add a sysfs ...
2053
  	}
80529c45a   Bill O'Donnell   xfs: pass xfsstat...
2054
2055
2056
2057
2058
2059
2060
2061
2062
  	xfsstats.xs_kobj.kobject.kset = xfs_kset;
  
  	xfsstats.xs_stats = alloc_percpu(struct xfsstats);
  	if (!xfsstats.xs_stats) {
  		error = -ENOMEM;
  		goto out_kset_unregister;
  	}
  
  	error = xfs_sysfs_init(&xfsstats.xs_kobj, &xfs_stats_ktype, NULL,
bb230c124   Bill O'Donnell   xfs: create globa...
2063
2064
  			       "stats");
  	if (error)
80529c45a   Bill O'Donnell   xfs: pass xfsstat...
2065
  		goto out_free_stats;
bb230c124   Bill O'Donnell   xfs: create globa...
2066

65b65735f   Brian Foster   xfs: add debug sy...
2067
2068
2069
  #ifdef DEBUG
  	xfs_dbg_kobj.kobject.kset = xfs_kset;
  	error = xfs_sysfs_init(&xfs_dbg_kobj, &xfs_dbg_ktype, NULL, "debug");
a05931ceb   Christoph Hellwig   xfs: remove the g...
2070
  	if (error)
bb230c124   Bill O'Donnell   xfs: create globa...
2071
  		goto out_remove_stats_kobj;
65b65735f   Brian Foster   xfs: add debug sy...
2072
2073
2074
2075
  #endif
  
  	error = xfs_qm_init();
  	if (error)
bb230c124   Bill O'Donnell   xfs: create globa...
2076
  		goto out_remove_dbg_kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2077
2078
2079
  
  	error = register_filesystem(&xfs_fs_type);
  	if (error)
a05931ceb   Christoph Hellwig   xfs: remove the g...
2080
  		goto out_qm_exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2081
  	return 0;
a05931ceb   Christoph Hellwig   xfs: remove the g...
2082
2083
   out_qm_exit:
  	xfs_qm_exit();
bb230c124   Bill O'Donnell   xfs: create globa...
2084
   out_remove_dbg_kobj:
65b65735f   Brian Foster   xfs: add debug sy...
2085
2086
  #ifdef DEBUG
  	xfs_sysfs_del(&xfs_dbg_kobj);
bb230c124   Bill O'Donnell   xfs: create globa...
2087
   out_remove_stats_kobj:
65b65735f   Brian Foster   xfs: add debug sy...
2088
  #endif
80529c45a   Bill O'Donnell   xfs: pass xfsstat...
2089
2090
2091
  	xfs_sysfs_del(&xfsstats.xs_kobj);
   out_free_stats:
  	free_percpu(xfsstats.xs_stats);
bb230c124   Bill O'Donnell   xfs: create globa...
2092
   out_kset_unregister:
3d8712265   Brian Foster   xfs: add a sysfs ...
2093
  	kset_unregister(xfs_kset);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2094
2095
2096
2097
2098
   out_sysctl_unregister:
  	xfs_sysctl_unregister();
   out_cleanup_procfs:
  	xfs_cleanup_procfs();
   out_buf_terminate:
ce8e922c0   Nathan Scott   [XFS] Complete th...
2099
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2100
2101
   out_mru_cache_uninit:
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2102
2103
   out_destroy_wq:
  	xfs_destroy_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2104
   out_destroy_zones:
8758280fc   Nathan Scott   [XFS] Cleanup the...
2105
  	xfs_destroy_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2106
   out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2107
2108
2109
2110
  	return error;
  }
  
  STATIC void __exit
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2111
  exit_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2112
  {
a05931ceb   Christoph Hellwig   xfs: remove the g...
2113
  	xfs_qm_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2114
  	unregister_filesystem(&xfs_fs_type);
65b65735f   Brian Foster   xfs: add debug sy...
2115
2116
2117
  #ifdef DEBUG
  	xfs_sysfs_del(&xfs_dbg_kobj);
  #endif
80529c45a   Bill O'Donnell   xfs: pass xfsstat...
2118
2119
  	xfs_sysfs_del(&xfsstats.xs_kobj);
  	free_percpu(xfsstats.xs_stats);
3d8712265   Brian Foster   xfs: add a sysfs ...
2120
  	kset_unregister(xfs_kset);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2121
2122
  	xfs_sysctl_unregister();
  	xfs_cleanup_procfs();
ce8e922c0   Nathan Scott   [XFS] Complete th...
2123
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
2124
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
2125
  	xfs_destroy_workqueues();
8758280fc   Nathan Scott   [XFS] Cleanup the...
2126
  	xfs_destroy_zones();
af3b63822   Darrick J. Wong   xfs: don't leak u...
2127
  	xfs_uuid_table_free();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2128
2129
2130
2131
2132
2133
2134
2135
  }
  
  module_init(init_xfs_fs);
  module_exit(exit_xfs_fs);
  
  MODULE_AUTHOR("Silicon Graphics, Inc.");
  MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled");
  MODULE_LICENSE("GPL");