Blame view

fs/xfs/xfs_super.c 47.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
a805bad5d   Nathan Scott   [XFS] Remove unne...
2
   * Copyright (c) 2000-2006 Silicon Graphics, Inc.
7b7187698   Nathan Scott   [XFS] Update lice...
3
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
7b7187698   Nathan Scott   [XFS] Update lice...
5
6
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * published by the Free Software Foundation.
   *
7b7187698   Nathan Scott   [XFS] Update lice...
9
10
11
12
   * This program is distributed in the hope that it would be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
   *
7b7187698   Nathan Scott   [XFS] Update lice...
14
15
16
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
0b1b213fc   Christoph Hellwig   xfs: event tracin...
18

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  #include "xfs.h"
70a9883c5   Dave Chinner   xfs: create a sha...
20
  #include "xfs_shared.h"
6ca1c9063   Dave Chinner   xfs: separate dqu...
21
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
22
23
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
24
  #include "xfs_inum.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  #include "xfs_sb.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
26
  #include "xfs_ag.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  #include "xfs_mount.h"
570627875   Dave Chinner   xfs: unify direct...
28
  #include "xfs_da_format.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include "xfs_inode.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
30
  #include "xfs_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  #include "xfs_bmap.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
32
  #include "xfs_alloc.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  #include "xfs_error.h"
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
34
  #include "xfs_fsops.h"
239880ef6   Dave Chinner   xfs: decouple log...
35
  #include "xfs_trans.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include "xfs_buf_item.h"
239880ef6   Dave Chinner   xfs: decouple log...
37
  #include "xfs_log.h"
a67d7c5f5   David Chinner   [XFS] Move platfo...
38
  #include "xfs_log_priv.h"
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
39
  #include "xfs_da_btree.h"
2b9ab5ab9   Dave Chinner   xfs: reshuffle di...
40
  #include "xfs_dir2.h"
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
41
42
43
  #include "xfs_extfree_item.h"
  #include "xfs_mru_cache.h"
  #include "xfs_inode_item.h"
6d8b79cfc   Dave Chinner   xfs: rename xfs_s...
44
  #include "xfs_icache.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
45
  #include "xfs_trace.h"
3ebe7d2d7   Dave Chinner   xfs: Inode create...
46
  #include "xfs_icreate_item.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
47
48
49
  #include "xfs_dinode.h"
  #include "xfs_filestream.h"
  #include "xfs_quota.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
  
  #include <linux/namei.h>
  #include <linux/init.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
53
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #include <linux/mount.h>
0829c3602   Christoph Hellwig   [XFS] Add infrast...
55
  #include <linux/mempool.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  #include <linux/writeback.h>
4df08c525   Christoph Hellwig   [XFS] Switch kern...
57
  #include <linux/kthread.h>
7dfb71030   Nigel Cunningham   [PATCH] Add inclu...
58
  #include <linux/freezer.h>
62a877e35   Christoph Hellwig   [XFS] fix mount o...
59
  #include <linux/parser.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60

b87221de6   Alexey Dobriyan   const: mark remai...
61
  static const struct super_operations xfs_super_operations;
7989cb8ef   David Chinner   [XFS] Keep stack ...
62
  static kmem_zone_t *xfs_ioend_zone;
0829c3602   Christoph Hellwig   [XFS] Add infrast...
63
  mempool_t *xfs_ioend_pool;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64

a67d7c5f5   David Chinner   [XFS] Move platfo...
65
66
67
68
69
70
  #define MNTOPT_LOGBUFS	"logbufs"	/* number of XFS log buffers */
  #define MNTOPT_LOGBSIZE	"logbsize"	/* size of XFS log buffers */
  #define MNTOPT_LOGDEV	"logdev"	/* log device */
  #define MNTOPT_RTDEV	"rtdev"		/* realtime I/O device */
  #define MNTOPT_BIOSIZE	"biosize"	/* log2 of preferred buffered io size */
  #define MNTOPT_WSYNC	"wsync"		/* safe-mode nfs compatible mount */
a67d7c5f5   David Chinner   [XFS] Move platfo...
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  #define MNTOPT_NOALIGN	"noalign"	/* turn off stripe alignment */
  #define MNTOPT_SWALLOC	"swalloc"	/* turn on stripe width allocation */
  #define MNTOPT_SUNIT	"sunit"		/* data volume stripe unit */
  #define MNTOPT_SWIDTH	"swidth"	/* data volume stripe width */
  #define MNTOPT_NOUUID	"nouuid"	/* ignore filesystem UUID */
  #define MNTOPT_MTPT	"mtpt"		/* filesystem mount point */
  #define MNTOPT_GRPID	"grpid"		/* group-ID from parent directory */
  #define MNTOPT_NOGRPID	"nogrpid"	/* group-ID from current process */
  #define MNTOPT_BSDGROUPS    "bsdgroups"    /* group-ID from parent directory */
  #define MNTOPT_SYSVGROUPS   "sysvgroups"   /* group-ID from current process */
  #define MNTOPT_ALLOCSIZE    "allocsize"    /* preferred allocation size */
  #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
  #define MNTOPT_BARRIER	"barrier"	/* use writer barriers for log write and
  					 * unwritten extent conversion */
  #define MNTOPT_NOBARRIER "nobarrier"	/* .. disable */
a67d7c5f5   David Chinner   [XFS] Move platfo...
86
  #define MNTOPT_64BITINODE   "inode64"	/* inodes can be allocated anywhere */
08bf54041   Carlos Maiolino   xfs: make inode64...
87
88
  #define MNTOPT_32BITINODE   "inode32"	/* inode allocation limited to
  					 * XFS_MAXINUMBER_32 */
a67d7c5f5   David Chinner   [XFS] Move platfo...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  #define MNTOPT_IKEEP	"ikeep"		/* do not free empty inode clusters */
  #define MNTOPT_NOIKEEP	"noikeep"	/* free empty inode clusters */
  #define MNTOPT_LARGEIO	   "largeio"	/* report large I/O sizes in stat() */
  #define MNTOPT_NOLARGEIO   "nolargeio"	/* do not report large I/O sizes
  					 * in stat(). */
  #define MNTOPT_ATTR2	"attr2"		/* do use attr2 attribute format */
  #define MNTOPT_NOATTR2	"noattr2"	/* do not use attr2 attribute format */
  #define MNTOPT_FILESTREAM  "filestreams" /* use filestreams allocator */
  #define MNTOPT_QUOTA	"quota"		/* disk quotas (user) */
  #define MNTOPT_NOQUOTA	"noquota"	/* no quotas */
  #define MNTOPT_USRQUOTA	"usrquota"	/* user quota enabled */
  #define MNTOPT_GRPQUOTA	"grpquota"	/* group quota enabled */
  #define MNTOPT_PRJQUOTA	"prjquota"	/* project quota enabled */
  #define MNTOPT_UQUOTA	"uquota"	/* user quota (IRIX variant) */
  #define MNTOPT_GQUOTA	"gquota"	/* group quota (IRIX variant) */
  #define MNTOPT_PQUOTA	"pquota"	/* project quota (IRIX variant) */
  #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
  #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
  #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
  #define MNTOPT_QUOTANOENF  "qnoenforce"	/* same as uqnoenforce */
e84661aa8   Christoph Hellwig   xfs: add online d...
109
110
111
112
  #define MNTOPT_DELAYLOG    "delaylog"	/* Delayed logging enabled */
  #define MNTOPT_NODELAYLOG  "nodelaylog"	/* Delayed logging disabled */
  #define MNTOPT_DISCARD	   "discard"	/* Discard unused blocks */
  #define MNTOPT_NODISCARD   "nodiscard"	/* Do not discard unused blocks */
a67d7c5f5   David Chinner   [XFS] Move platfo...
113

62a877e35   Christoph Hellwig   [XFS] fix mount o...
114
115
116
117
118
119
120
  /*
   * Table driven mount option parser.
   *
   * Currently only used for remount, but it will be used for mount
   * in the future, too.
   */
  enum {
2ea039298   Carlos Maiolino   xfs: Make inode32...
121
122
123
124
125
  	Opt_barrier,
  	Opt_nobarrier,
  	Opt_inode64,
  	Opt_inode32,
  	Opt_err
62a877e35   Christoph Hellwig   [XFS] fix mount o...
126
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
127
  static const match_table_t tokens = {
62a877e35   Christoph Hellwig   [XFS] fix mount o...
128
129
  	{Opt_barrier, "barrier"},
  	{Opt_nobarrier, "nobarrier"},
c3a58fecd   Carlos Maiolino   Make inode64 a re...
130
  	{Opt_inode64, "inode64"},
2ea039298   Carlos Maiolino   xfs: Make inode32...
131
  	{Opt_inode32, "inode32"},
62a877e35   Christoph Hellwig   [XFS] fix mount o...
132
133
  	{Opt_err, NULL}
  };
a67d7c5f5   David Chinner   [XFS] Move platfo...
134
  STATIC unsigned long
a17164e54   Abhijit Pawar   fs/xfs remove obs...
135
  suffix_kstrtoint(char *s, unsigned int base, int *res)
a67d7c5f5   David Chinner   [XFS] Move platfo...
136
  {
a17164e54   Abhijit Pawar   fs/xfs remove obs...
137
  	int	last, shift_left_factor = 0, _res;
a67d7c5f5   David Chinner   [XFS] Move platfo...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  	char	*value = s;
  
  	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';
  	}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
153
154
155
156
  	if (kstrtoint(s, base, &_res))
  		return -EINVAL;
  	*res = _res << shift_left_factor;
  	return 0;
a67d7c5f5   David Chinner   [XFS] Move platfo...
157
  }
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
158
159
160
161
162
163
164
  /*
   * This function fills in xfs_mount_t fields based on mount args.
   * Note: the superblock has _not_ yet been read in.
   *
   * Note that this function leaks the various device name allocations on
   * failure.  The caller takes care of them.
   */
a67d7c5f5   David Chinner   [XFS] Move platfo...
165
166
167
  STATIC int
  xfs_parseargs(
  	struct xfs_mount	*mp,
288699fec   Christoph Hellwig   xfs: drop dmapi h...
168
  	char			*options)
a67d7c5f5   David Chinner   [XFS] Move platfo...
169
  {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
170
  	struct super_block	*sb = mp->m_super;
a17164e54   Abhijit Pawar   fs/xfs remove obs...
171
  	char			*this_char, *value;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
172
173
174
  	int			dsunit = 0;
  	int			dswidth = 0;
  	int			iosize = 0;
a56877873   Christoph Hellwig   xfs: remove uchar...
175
  	__uint8_t		iosizelog = 0;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
176
177
  
  	/*
4f10700a2   Dave Chinner   xfs: Convert linu...
178
179
180
181
182
183
184
185
186
  	 * set up the mount name first so all the errors will refer to the
  	 * correct device.
  	 */
  	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
  	if (!mp->m_fsname)
  		return ENOMEM;
  	mp->m_fsname_len = strlen(mp->m_fsname) + 1;
  
  	/*
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  	 * Copy binary VFS mount flags we are interested in.
  	 */
  	if (sb->s_flags & MS_RDONLY)
  		mp->m_flags |= XFS_MOUNT_RDONLY;
  	if (sb->s_flags & MS_DIRSYNC)
  		mp->m_flags |= XFS_MOUNT_DIRSYNC;
  	if (sb->s_flags & MS_SYNCHRONOUS)
  		mp->m_flags |= XFS_MOUNT_WSYNC;
  
  	/*
  	 * Set some default flags that could be cleared by the mount option
  	 * parsing.
  	 */
  	mp->m_flags |= XFS_MOUNT_BARRIER;
  	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
08bf54041   Carlos Maiolino   xfs: make inode64...
202
  #if !XFS_BIG_INUMS
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
203
  	mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
08bf54041   Carlos Maiolino   xfs: make inode64...
204
  #endif
a67d7c5f5   David Chinner   [XFS] Move platfo...
205

9d565ffa3   Christoph Hellwig   [XFS] kill struct...
206
207
208
209
210
  	/*
  	 * These can be overridden by the mount option parsing.
  	 */
  	mp->m_logbufs = -1;
  	mp->m_logbsize = -1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
211
212
213
  
  	if (!options)
  		goto done;
a67d7c5f5   David Chinner   [XFS] Move platfo...
214
215
216
217
218
219
220
221
  	while ((this_char = strsep(&options, ",")) != NULL) {
  		if (!*this_char)
  			continue;
  		if ((value = strchr(this_char, '=')) != NULL)
  			*value++ = 0;
  
  		if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
222
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
223
224
225
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
226
227
  			if (kstrtoint(value, 10, &mp->m_logbufs))
  				return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
228
229
  		} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
230
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
231
232
233
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
234
235
  			if (suffix_kstrtoint(value, 10, &mp->m_logbsize))
  				return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
236
237
  		} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
238
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
239
240
241
  					this_char);
  				return EINVAL;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
242
243
244
  			mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
  			if (!mp->m_logname)
  				return ENOMEM;
a67d7c5f5   David Chinner   [XFS] Move platfo...
245
  		} else if (!strcmp(this_char, MNTOPT_MTPT)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
246
  			xfs_warn(mp, "%s option not allowed on this system",
288699fec   Christoph Hellwig   xfs: drop dmapi h...
247
248
  				this_char);
  			return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
249
250
  		} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
251
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
252
253
254
  					this_char);
  				return EINVAL;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
255
256
257
  			mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
  			if (!mp->m_rtname)
  				return ENOMEM;
a67d7c5f5   David Chinner   [XFS] Move platfo...
258
259
  		} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
260
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
261
262
263
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
264
265
  			if (kstrtoint(value, 10, &iosize))
  				return EINVAL;
1ec7944be   Christoph Hellwig   [XFS] fix biosize...
266
  			iosizelog = ffs(iosize) - 1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
267
268
  		} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
269
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
270
271
272
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
273
274
  			if (suffix_kstrtoint(value, 10, &iosize))
  				return EINVAL;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
275
  			iosizelog = ffs(iosize) - 1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
276
277
278
279
280
281
282
  		} else if (!strcmp(this_char, MNTOPT_GRPID) ||
  			   !strcmp(this_char, MNTOPT_BSDGROUPS)) {
  			mp->m_flags |= XFS_MOUNT_GRPID;
  		} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
  			   !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
  			mp->m_flags &= ~XFS_MOUNT_GRPID;
  		} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
283
  			mp->m_flags |= XFS_MOUNT_WSYNC;
a67d7c5f5   David Chinner   [XFS] Move platfo...
284
  		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
285
  			mp->m_flags |= XFS_MOUNT_NORECOVERY;
a67d7c5f5   David Chinner   [XFS] Move platfo...
286
  		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
287
  			mp->m_flags |= XFS_MOUNT_NOALIGN;
a67d7c5f5   David Chinner   [XFS] Move platfo...
288
  		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
289
  			mp->m_flags |= XFS_MOUNT_SWALLOC;
a67d7c5f5   David Chinner   [XFS] Move platfo...
290
291
  		} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
292
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
293
294
295
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
296
297
  			if (kstrtoint(value, 10, &dsunit))
  				return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
298
299
  		} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
300
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
301
302
303
  					this_char);
  				return EINVAL;
  			}
a17164e54   Abhijit Pawar   fs/xfs remove obs...
304
305
  			if (kstrtoint(value, 10, &dswidth))
  				return EINVAL;
08bf54041   Carlos Maiolino   xfs: make inode64...
306
307
  		} else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
  			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
308
  		} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
309
  			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
310
  #if !XFS_BIG_INUMS
4f10700a2   Dave Chinner   xfs: Convert linu...
311
  			xfs_warn(mp, "%s option not allowed on this system",
a67d7c5f5   David Chinner   [XFS] Move platfo...
312
313
314
315
  				this_char);
  			return EINVAL;
  #endif
  		} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
316
  			mp->m_flags |= XFS_MOUNT_NOUUID;
a67d7c5f5   David Chinner   [XFS] Move platfo...
317
  		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
318
  			mp->m_flags |= XFS_MOUNT_BARRIER;
a67d7c5f5   David Chinner   [XFS] Move platfo...
319
  		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
320
  			mp->m_flags &= ~XFS_MOUNT_BARRIER;
a67d7c5f5   David Chinner   [XFS] Move platfo...
321
  		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
322
  			mp->m_flags |= XFS_MOUNT_IKEEP;
a67d7c5f5   David Chinner   [XFS] Move platfo...
323
  		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
324
  			mp->m_flags &= ~XFS_MOUNT_IKEEP;
a67d7c5f5   David Chinner   [XFS] Move platfo...
325
  		} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
326
  			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
a67d7c5f5   David Chinner   [XFS] Move platfo...
327
  		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
328
  			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
a67d7c5f5   David Chinner   [XFS] Move platfo...
329
  		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
330
  			mp->m_flags |= XFS_MOUNT_ATTR2;
a67d7c5f5   David Chinner   [XFS] Move platfo...
331
  		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
332
333
  			mp->m_flags &= ~XFS_MOUNT_ATTR2;
  			mp->m_flags |= XFS_MOUNT_NOATTR2;
a67d7c5f5   David Chinner   [XFS] Move platfo...
334
  		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
335
  			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
336
  		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
4177af3a8   Chandra Seetharaman   Define new macro ...
337
338
339
  			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
  			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
  			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
a67d7c5f5   David Chinner   [XFS] Move platfo...
340
341
342
  		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
  			   !strcmp(this_char, MNTOPT_UQUOTA) ||
  			   !strcmp(this_char, MNTOPT_USRQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
343
344
  			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
  					 XFS_UQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
345
346
  		} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
  			   !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
347
348
  			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
  			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
a67d7c5f5   David Chinner   [XFS] Move platfo...
349
350
  		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
  			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
351
  			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
352
  					 XFS_PQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
353
  		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
354
  			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
355
  			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
a67d7c5f5   David Chinner   [XFS] Move platfo...
356
357
  		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
  			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
358
  			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
359
  					 XFS_GQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
360
  		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
361
  			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
362
  			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
71e330b59   Dave Chinner   xfs: Introduce de...
363
  		} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
93b8a5854   Christoph Hellwig   xfs: remove the d...
364
365
  			xfs_warn(mp,
  	"delaylog is the default now, option is deprecated.");
71e330b59   Dave Chinner   xfs: Introduce de...
366
  		} else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
242d62196   Christoph Hellwig   xfs: deprecate th...
367
  			xfs_warn(mp,
93b8a5854   Christoph Hellwig   xfs: remove the d...
368
  	"nodelaylog support has been removed, option is deprecated.");
e84661aa8   Christoph Hellwig   xfs: add online d...
369
370
371
372
  		} else if (!strcmp(this_char, MNTOPT_DISCARD)) {
  			mp->m_flags |= XFS_MOUNT_DISCARD;
  		} else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
  			mp->m_flags &= ~XFS_MOUNT_DISCARD;
a67d7c5f5   David Chinner   [XFS] Move platfo...
373
  		} else if (!strcmp(this_char, "ihashsize")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
374
375
  			xfs_warn(mp,
  	"ihashsize no longer used, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
376
  		} else if (!strcmp(this_char, "osyncisdsync")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
377
378
  			xfs_warn(mp,
  	"osyncisdsync has no effect, option is deprecated.");
a64afb057   Christoph Hellwig   xfs: remove obsol...
379
  		} else if (!strcmp(this_char, "osyncisosync")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
380
381
  			xfs_warn(mp,
  	"osyncisosync has no effect, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
382
  		} else if (!strcmp(this_char, "irixsgid")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
383
384
  			xfs_warn(mp,
  	"irixsgid is now a sysctl(2) variable, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
385
  		} else {
4f10700a2   Dave Chinner   xfs: Convert linu...
386
  			xfs_warn(mp, "unknown mount option [%s].", this_char);
a67d7c5f5   David Chinner   [XFS] Move platfo...
387
388
389
  			return EINVAL;
  		}
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
390
391
392
393
394
  	/*
  	 * no recovery flag requires a read-only mount
  	 */
  	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
  	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
395
  		xfs_warn(mp, "no-recovery mounts must be read-only.");
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
396
  		return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
397
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
398
  	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
399
400
  		xfs_warn(mp,
  	"sunit and swidth options incompatible with the noalign option");
a67d7c5f5   David Chinner   [XFS] Move platfo...
401
402
  		return EINVAL;
  	}
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
403
404
  #ifndef CONFIG_XFS_QUOTA
  	if (XFS_IS_QUOTA_RUNNING(mp)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
405
  		xfs_warn(mp, "quota support not available in this kernel.");
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
406
407
408
  		return EINVAL;
  	}
  #endif
a67d7c5f5   David Chinner   [XFS] Move platfo...
409
  	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
410
  		xfs_warn(mp, "sunit and swidth must be specified together");
a67d7c5f5   David Chinner   [XFS] Move platfo...
411
412
413
414
  		return EINVAL;
  	}
  
  	if (dsunit && (dswidth % dsunit != 0)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
415
416
  		xfs_warn(mp,
  	"stripe width (%d) must be a multiple of the stripe unit (%d)",
a67d7c5f5   David Chinner   [XFS] Move platfo...
417
418
419
  			dswidth, dsunit);
  		return EINVAL;
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
420
  done:
39a45d846   Jie Liu   xfs: Remove XFS_M...
421
  	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
422
423
424
425
426
427
  		/*
  		 * At this point the superblock has not been read
  		 * in, therefore we do not know the block size.
  		 * Before the mount call ends we will convert
  		 * these to FSBs.
  		 */
39a45d846   Jie Liu   xfs: Remove XFS_M...
428
429
  		mp->m_dalign = dsunit;
  		mp->m_swidth = dswidth;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
430
431
432
433
434
435
  	}
  
  	if (mp->m_logbufs != -1 &&
  	    mp->m_logbufs != 0 &&
  	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
  	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
436
  		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
437
438
439
440
441
442
443
444
  			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
  		return XFS_ERROR(EINVAL);
  	}
  	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))) {
4f10700a2   Dave Chinner   xfs: Convert linu...
445
446
  		xfs_warn(mp,
  			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
447
448
449
  			mp->m_logbsize);
  		return XFS_ERROR(EINVAL);
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
450
451
452
  	if (iosizelog) {
  		if (iosizelog > XFS_MAX_IO_LOG ||
  		    iosizelog < XFS_MIN_IO_LOG) {
4f10700a2   Dave Chinner   xfs: Convert linu...
453
  			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
454
455
456
457
458
459
460
461
  				iosizelog, XFS_MIN_IO_LOG,
  				XFS_MAX_IO_LOG);
  			return XFS_ERROR(EINVAL);
  		}
  
  		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
  		mp->m_readio_log = iosizelog;
  		mp->m_writeio_log = iosizelog;
a67d7c5f5   David Chinner   [XFS] Move platfo...
462
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  	return 0;
  }
  
  struct proc_xfs_info {
  	int	flag;
  	char	*str;
  };
  
  STATIC int
  xfs_showargs(
  	struct xfs_mount	*mp,
  	struct seq_file		*m)
  {
  	static struct proc_xfs_info xfs_info_set[] = {
  		/* the few simple ones we can get from the mount struct */
1bd960ee2   Josef Jeff Sipek   [XFS] If you moun...
478
  		{ XFS_MOUNT_IKEEP,		"," MNTOPT_IKEEP },
a67d7c5f5   David Chinner   [XFS] Move platfo...
479
  		{ XFS_MOUNT_WSYNC,		"," MNTOPT_WSYNC },
a67d7c5f5   David Chinner   [XFS] Move platfo...
480
481
482
483
  		{ XFS_MOUNT_NOALIGN,		"," MNTOPT_NOALIGN },
  		{ XFS_MOUNT_SWALLOC,		"," MNTOPT_SWALLOC },
  		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },
  		{ XFS_MOUNT_NORECOVERY,		"," MNTOPT_NORECOVERY },
a67d7c5f5   David Chinner   [XFS] Move platfo...
484
485
  		{ XFS_MOUNT_ATTR2,		"," MNTOPT_ATTR2 },
  		{ XFS_MOUNT_FILESTREAMS,	"," MNTOPT_FILESTREAM },
a67d7c5f5   David Chinner   [XFS] Move platfo...
486
  		{ XFS_MOUNT_GRPID,		"," MNTOPT_GRPID },
e84661aa8   Christoph Hellwig   xfs: add online d...
487
  		{ XFS_MOUNT_DISCARD,		"," MNTOPT_DISCARD },
08bf54041   Carlos Maiolino   xfs: make inode64...
488
  		{ XFS_MOUNT_SMALL_INUMS,	"," MNTOPT_32BITINODE },
a67d7c5f5   David Chinner   [XFS] Move platfo...
489
490
491
492
  		{ 0, NULL }
  	};
  	static struct proc_xfs_info xfs_info_unset[] = {
  		/* the few simple ones we can get from the mount struct */
a67d7c5f5   David Chinner   [XFS] Move platfo...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  		{ XFS_MOUNT_COMPAT_IOSIZE,	"," MNTOPT_LARGEIO },
  		{ XFS_MOUNT_BARRIER,		"," MNTOPT_NOBARRIER },
  		{ XFS_MOUNT_SMALL_INUMS,	"," MNTOPT_64BITINODE },
  		{ 0, NULL }
  	};
  	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);
  	}
  	for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) {
  		if (!(mp->m_flags & xfs_infop->flag))
  			seq_puts(m, xfs_infop->str);
  	}
  
  	if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
  		seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
  				(int)(1 << mp->m_writeio_log) >> 10);
  
  	if (mp->m_logbufs > 0)
  		seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
  	if (mp->m_logbsize > 0)
  		seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
  
  	if (mp->m_logname)
  		seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
  	if (mp->m_rtname)
  		seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
  
  	if (mp->m_dalign > 0)
  		seq_printf(m, "," MNTOPT_SUNIT "=%d",
  				(int)XFS_FSB_TO_BB(mp, mp->m_dalign));
  	if (mp->m_swidth > 0)
  		seq_printf(m, "," MNTOPT_SWIDTH "=%d",
  				(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
  
  	if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
  		seq_puts(m, "," MNTOPT_USRQUOTA);
  	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
  		seq_puts(m, "," MNTOPT_UQUOTANOENF);
988abe407   Alex Elder   xfs: xfs_showargs...
534
  	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
535
  		if (mp->m_qflags & XFS_PQUOTA_ENFD)
988abe407   Alex Elder   xfs: xfs_showargs...
536
537
538
  			seq_puts(m, "," MNTOPT_PRJQUOTA);
  		else
  			seq_puts(m, "," MNTOPT_PQUOTANOENF);
d892d5864   Chandra Seetharaman   xfs: Start using ...
539
540
  	}
  	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
541
  		if (mp->m_qflags & XFS_GQUOTA_ENFD)
988abe407   Alex Elder   xfs: xfs_showargs...
542
543
544
545
  			seq_puts(m, "," MNTOPT_GRPQUOTA);
  		else
  			seq_puts(m, "," MNTOPT_GQUOTANOENF);
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
546
547
548
549
550
551
  
  	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
  		seq_puts(m, "," MNTOPT_NOQUOTA);
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
555
556
557
558
559
560
  __uint64_t
  xfs_max_file_offset(
  	unsigned int		blockshift)
  {
  	unsigned int		pagefactor = 1;
  	unsigned int		bitshift = BITS_PER_LONG - 1;
  
  	/* Figure out maximum filesize, on Linux this can depend on
  	 * the filesystem blocksize (on 32 bit platforms).
ebdec241d   Christoph Hellwig   fs: kill block_pr...
561
  	 * __block_write_begin does this in an [unsigned] long...
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
564
565
566
567
568
569
570
571
572
573
  	 *      page->index << (PAGE_CACHE_SHIFT - bbits)
  	 * So, for page sized blocks (4K on 32 bit platforms),
  	 * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
  	 *      (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
  	 * but for smaller blocksizes it is less (bbits = log2 bsize).
  	 * Note1: get_block_t takes a long (implicit cast from above)
  	 * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
  	 * can optionally convert the [unsigned] long from above into
  	 * an [unsigned] long long.
  	 */
  
  #if BITS_PER_LONG == 32
90c699a9e   Bartlomiej Zolnierkiewicz   block: rename CON...
574
  # if defined(CONFIG_LBDAF)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
576
577
578
579
580
581
582
583
584
  	ASSERT(sizeof(sector_t) == 8);
  	pagefactor = PAGE_CACHE_SIZE;
  	bitshift = BITS_PER_LONG;
  # else
  	pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
  # endif
  #endif
  
  	return (((__uint64_t)pagefactor) << bitshift) - 1;
  }
2d2194f61   Carlos Maiolino   xfs: reduce code ...
585
586
587
588
  xfs_agnumber_t
  xfs_set_inode32(struct xfs_mount *mp)
  {
  	xfs_agnumber_t	index = 0;
4056c1d08   Carlos Maiolino   xfs: add inode64-...
589
  	xfs_agnumber_t	maxagi = 0;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
  	xfs_sb_t	*sbp = &mp->m_sb;
  	xfs_agnumber_t	max_metadata;
  	xfs_agino_t	agino =	XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0);
  	xfs_ino_t	ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino);
  	xfs_perag_t	*pag;
  
  	/* Calculate how much should be reserved for inodes to meet
  	 * the max inode percentage.
  	 */
  	if (mp->m_maxicount) {
  		__uint64_t	icount;
  
  		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 {
  		max_metadata = sbp->sb_agcount;
  	}
  
  	for (index = 0; index < sbp->sb_agcount; index++) {
  		ino = XFS_AGINO_TO_INO(mp, index, agino);
4056c1d08   Carlos Maiolino   xfs: add inode64-...
613

2d2194f61   Carlos Maiolino   xfs: reduce code ...
614
  		if (ino > XFS_MAXINUMBER_32) {
4056c1d08   Carlos Maiolino   xfs: add inode64-...
615
616
617
618
619
  			pag = xfs_perag_get(mp, index);
  			pag->pagi_inodeok = 0;
  			pag->pagf_metadata = 0;
  			xfs_perag_put(pag);
  			continue;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
620
621
622
623
  		}
  
  		pag = xfs_perag_get(mp, index);
  		pag->pagi_inodeok = 1;
4056c1d08   Carlos Maiolino   xfs: add inode64-...
624
  		maxagi++;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
625
626
627
628
  		if (index < max_metadata)
  			pag->pagf_metadata = 1;
  		xfs_perag_put(pag);
  	}
4056c1d08   Carlos Maiolino   xfs: add inode64-...
629
630
631
632
  	mp->m_flags |= (XFS_MOUNT_32BITINODES |
  			XFS_MOUNT_SMALL_INUMS);
  
  	return maxagi;
2d2194f61   Carlos Maiolino   xfs: reduce code ...
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  }
  
  xfs_agnumber_t
  xfs_set_inode64(struct xfs_mount *mp)
  {
  	xfs_agnumber_t index = 0;
  
  	for (index = 0; index < mp->m_sb.sb_agcount; index++) {
  		struct xfs_perag	*pag;
  
  		pag = xfs_perag_get(mp, index);
  		pag->pagi_inodeok = 1;
  		pag->pagf_metadata = 0;
  		xfs_perag_put(pag);
  	}
  
  	/* There is no need for lock protection on m_flags,
  	 * the rw_semaphore of the VFS superblock is locked
  	 * during mount/umount/remount operations, so this is
  	 * enough to avoid concurency on the m_flags field
  	 */
  	mp->m_flags &= ~(XFS_MOUNT_32BITINODES |
  			 XFS_MOUNT_SMALL_INUMS);
  	return index;
  }
3180e66d7   Hannes Eder   xfs: make symbols...
658
  STATIC int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
660
661
662
663
664
  xfs_blkdev_get(
  	xfs_mount_t		*mp,
  	const char		*name,
  	struct block_device	**bdevp)
  {
  	int			error = 0;
d4d776299   Tejun Heo   block: clean up b...
665
666
  	*bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
  				    mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
  	if (IS_ERR(*bdevp)) {
  		error = PTR_ERR(*bdevp);
4f10700a2   Dave Chinner   xfs: Convert linu...
669
670
  		xfs_warn(mp, "Invalid device [%s], error=%d
  ", name, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
673
674
  	}
  
  	return -error;
  }
3180e66d7   Hannes Eder   xfs: make symbols...
675
  STATIC void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
679
  xfs_blkdev_put(
  	struct block_device	*bdev)
  {
  	if (bdev)
e525fd89d   Tejun Heo   block: make blkde...
680
  		blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
  }
f538d4da8   Christoph Hellwig   [XFS] write barri...
682
683
684
685
  void
  xfs_blkdev_issue_flush(
  	xfs_buftarg_t		*buftarg)
  {
7582df516   Shaohua Li   xfs: using GFP_NO...
686
  	blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL);
f538d4da8   Christoph Hellwig   [XFS] write barri...
687
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688

19f354d4c   Christoph Hellwig   [XFS] sort out op...
689
690
691
692
693
  STATIC void
  xfs_close_devices(
  	struct xfs_mount	*mp)
  {
  	if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
694
  		struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
b79631330   Christoph Hellwig   xfs: only issues ...
695
  		xfs_free_buftarg(mp, mp->m_logdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
696
  		xfs_blkdev_put(logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
697
698
  	}
  	if (mp->m_rtdev_targp) {
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
699
  		struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
b79631330   Christoph Hellwig   xfs: only issues ...
700
  		xfs_free_buftarg(mp, mp->m_rtdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
701
  		xfs_blkdev_put(rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
702
  	}
b79631330   Christoph Hellwig   xfs: only issues ...
703
  	xfs_free_buftarg(mp, mp->m_ddev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
704
705
706
707
708
709
710
711
712
713
714
715
716
717
  }
  
  /*
   * 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...
718
  	struct xfs_mount	*mp)
19f354d4c   Christoph Hellwig   [XFS] sort out op...
719
720
721
722
723
724
725
726
  {
  	struct block_device	*ddev = mp->m_super->s_bdev;
  	struct block_device	*logdev = NULL, *rtdev = NULL;
  	int			error;
  
  	/*
  	 * Open real time and log devices - order is important.
  	 */
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
727
728
  	if (mp->m_logname) {
  		error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
729
730
731
  		if (error)
  			goto out;
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
732
733
  	if (mp->m_rtname) {
  		error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
734
735
736
737
  		if (error)
  			goto out_close_logdev;
  
  		if (rtdev == ddev || rtdev == logdev) {
4f10700a2   Dave Chinner   xfs: Convert linu...
738
739
  			xfs_warn(mp,
  	"Cannot mount filesystem with identical rtdev and ddev/logdev.");
19f354d4c   Christoph Hellwig   [XFS] sort out op...
740
741
742
743
744
745
746
747
748
  			error = EINVAL;
  			goto out_close_rtdev;
  		}
  	}
  
  	/*
  	 * Setup xfs_mount buffer target pointers
  	 */
  	error = ENOMEM;
ebad861b5   Dave Chinner   xfs: store xfs_mo...
749
  	mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
750
751
752
753
  	if (!mp->m_ddev_targp)
  		goto out_close_rtdev;
  
  	if (rtdev) {
ebad861b5   Dave Chinner   xfs: store xfs_mo...
754
755
  		mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1,
  							mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
756
757
758
759
760
  		if (!mp->m_rtdev_targp)
  			goto out_free_ddev_targ;
  	}
  
  	if (logdev && logdev != ddev) {
ebad861b5   Dave Chinner   xfs: store xfs_mo...
761
762
  		mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1,
  							mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
763
764
765
766
767
768
769
770
771
772
  		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)
b79631330   Christoph Hellwig   xfs: only issues ...
773
  		xfs_free_buftarg(mp, mp->m_rtdev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
774
   out_free_ddev_targ:
b79631330   Christoph Hellwig   xfs: only issues ...
775
  	xfs_free_buftarg(mp, mp->m_ddev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
776
777
778
779
780
781
782
783
784
   out_close_rtdev:
  	if (rtdev)
  		xfs_blkdev_put(rtdev);
   out_close_logdev:
  	if (logdev && logdev != ddev)
  		xfs_blkdev_put(logdev);
   out:
  	return error;
  }
e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
785
786
787
788
789
790
791
792
  /*
   * 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...
793

e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
  	error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
  				    mp->m_sb.sb_sectsize);
  	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,
  					    mp->m_sb.sb_blocksize,
  					    log_sector_size);
  		if (error)
  			return error;
  	}
  	if (mp->m_rtdev_targp) {
  		error = xfs_setsize_buftarg(mp->m_rtdev_targp,
  					    mp->m_sb.sb_blocksize,
  					    mp->m_sb.sb_sectsize);
  		if (error)
  			return error;
  	}
  
  	return 0;
  }
19f354d4c   Christoph Hellwig   [XFS] sort out op...
820

aa6bf01d3   Christoph Hellwig   xfs: use per-file...
821
822
823
824
825
826
827
828
829
830
831
832
833
  STATIC int
  xfs_init_mount_workqueues(
  	struct xfs_mount	*mp)
  {
  	mp->m_data_workqueue = alloc_workqueue("xfs-data/%s",
  			WQ_MEM_RECLAIM, 0, mp->m_fsname);
  	if (!mp->m_data_workqueue)
  		goto out;
  
  	mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s",
  			WQ_MEM_RECLAIM, 0, mp->m_fsname);
  	if (!mp->m_unwritten_workqueue)
  		goto out_destroy_data_iodone_queue;
4c2d542f2   Dave Chinner   xfs: Do backgroun...
834
835
836
837
  	mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s",
  			WQ_MEM_RECLAIM, 0, mp->m_fsname);
  	if (!mp->m_cil_workqueue)
  		goto out_destroy_unwritten;
5889608df   Dave Chinner   xfs: syncd workqu...
838
839
  
  	mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s",
7a378c9ae   Tejun Heo   xfs: WQ_NON_REENT...
840
  			0, 0, mp->m_fsname);
5889608df   Dave Chinner   xfs: syncd workqu...
841
842
843
844
  	if (!mp->m_reclaim_workqueue)
  		goto out_destroy_cil;
  
  	mp->m_log_workqueue = alloc_workqueue("xfs-log/%s",
7a378c9ae   Tejun Heo   xfs: WQ_NON_REENT...
845
  			0, 0, mp->m_fsname);
5889608df   Dave Chinner   xfs: syncd workqu...
846
847
  	if (!mp->m_log_workqueue)
  		goto out_destroy_reclaim;
579b62faa   Brian Foster   xfs: add backgrou...
848
  	mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s",
7a378c9ae   Tejun Heo   xfs: WQ_NON_REENT...
849
  			0, 0, mp->m_fsname);
579b62faa   Brian Foster   xfs: add backgrou...
850
851
  	if (!mp->m_eofblocks_workqueue)
  		goto out_destroy_log;
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
852
  	return 0;
579b62faa   Brian Foster   xfs: add backgrou...
853
854
  out_destroy_log:
  	destroy_workqueue(mp->m_log_workqueue);
5889608df   Dave Chinner   xfs: syncd workqu...
855
856
857
858
  out_destroy_reclaim:
  	destroy_workqueue(mp->m_reclaim_workqueue);
  out_destroy_cil:
  	destroy_workqueue(mp->m_cil_workqueue);
4c2d542f2   Dave Chinner   xfs: Do backgroun...
859
860
  out_destroy_unwritten:
  	destroy_workqueue(mp->m_unwritten_workqueue);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
861
862
863
864
865
866
867
868
869
870
  out_destroy_data_iodone_queue:
  	destroy_workqueue(mp->m_data_workqueue);
  out:
  	return -ENOMEM;
  }
  
  STATIC void
  xfs_destroy_mount_workqueues(
  	struct xfs_mount	*mp)
  {
579b62faa   Brian Foster   xfs: add backgrou...
871
  	destroy_workqueue(mp->m_eofblocks_workqueue);
5889608df   Dave Chinner   xfs: syncd workqu...
872
873
  	destroy_workqueue(mp->m_log_workqueue);
  	destroy_workqueue(mp->m_reclaim_workqueue);
4c2d542f2   Dave Chinner   xfs: Do backgroun...
874
  	destroy_workqueue(mp->m_cil_workqueue);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
875
876
877
  	destroy_workqueue(mp->m_data_workqueue);
  	destroy_workqueue(mp->m_unwritten_workqueue);
  }
9aa05000f   Dave Chinner   xfs: xfs_sync_dat...
878
879
880
881
882
883
884
885
886
887
888
889
890
  /*
   * 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)
  {
  	struct super_block	*sb = mp->m_super;
  
  	if (down_read_trylock(&sb->s_umount)) {
0dc83bd30   Jan Kara   Revert "writeback...
891
  		sync_inodes_sb(sb);
9aa05000f   Dave Chinner   xfs: xfs_sync_dat...
892
893
894
  		up_read(&sb->s_umount);
  	}
  }
bf904248a   David Chinner   [XFS] Combine the...
895
  /* Catch misguided souls that try to use this interface on XFS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  STATIC struct inode *
a50cd2692   Nathan Scott   [XFS] Switch over...
897
  xfs_fs_alloc_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
899
  	struct super_block	*sb)
  {
bf904248a   David Chinner   [XFS] Combine the...
900
  	BUG();
493dca617   Lachlan McIlroy   [XFS] Fix build w...
901
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
  }
bf904248a   David Chinner   [XFS] Combine the...
903
  /*
99fa8cb3c   David Chinner   [XFS] Prevent use...
904
905
   * Now that the generic code is guaranteed not to be accessing
   * the linux inode, we can reclaim the inode.
bf904248a   David Chinner   [XFS] Combine the...
906
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
  STATIC void
a50cd2692   Nathan Scott   [XFS] Switch over...
908
  xfs_fs_destroy_inode(
848ce8f73   Christoph Hellwig   xfs: simplify ino...
909
  	struct inode		*inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
910
  {
848ce8f73   Christoph Hellwig   xfs: simplify ino...
911
  	struct xfs_inode	*ip = XFS_I(inode);
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
912
  	trace_xfs_destroy_inode(ip);
99fa8cb3c   David Chinner   [XFS] Prevent use...
913
914
  
  	XFS_STATS_INC(vn_reclaim);
848ce8f73   Christoph Hellwig   xfs: simplify ino...
915

848ce8f73   Christoph Hellwig   xfs: simplify ino...
916
917
918
919
920
921
922
923
924
  	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
  
  	/*
  	 * 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));
  
  	/*
57817c682   Dave Chinner   xfs: reclaim all ...
925
926
927
928
929
  	 * We always use background reclaim here because even if the
  	 * inode is clean, it still may be under IO and hence we have
  	 * to take the flush lock. 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...
930
  	 */
57817c682   Dave Chinner   xfs: reclaim all ...
931
  	xfs_inode_set_reclaim_tag(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
  }
07c8f6758   David Chinner   [XFS] Make use of...
933
934
935
936
  /*
   * 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...
937
   * from the slab. This avoids the need to repeatedly initialise
07c8f6758   David Chinner   [XFS] Make use of...
938
939
940
   * fields in the xfs inode that left in the initialise state
   * when freeing the inode.
   */
bf904248a   David Chinner   [XFS] Combine the...
941
942
  STATIC void
  xfs_fs_inode_init_once(
07c8f6758   David Chinner   [XFS] Make use of...
943
944
945
946
947
  	void			*inode)
  {
  	struct xfs_inode	*ip = inode;
  
  	memset(ip, 0, sizeof(struct xfs_inode));
bf904248a   David Chinner   [XFS] Combine the...
948
949
950
951
952
  
  	/* vfs inode */
  	inode_init_once(VFS_I(ip));
  
  	/* xfs inode */
07c8f6758   David Chinner   [XFS] Make use of...
953
954
  	atomic_set(&ip->i_pincount, 0);
  	spin_lock_init(&ip->i_flags_lock);
07c8f6758   David Chinner   [XFS] Make use of...
955
956
957
  
  	mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
  		     "xfsino", ip->i_ino);
07c8f6758   David Chinner   [XFS] Make use of...
958
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
  STATIC void
b57922d97   Al Viro   convert remaining...
960
  xfs_fs_evict_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
962
  	struct inode		*inode)
  {
1543d79c4   Christoph Hellwig   [XFS] move v_trac...
963
  	xfs_inode_t		*ip = XFS_I(inode);
56d433e43   Christoph Hellwig   [XFS] streamline ...
964

4f59af758   Christoph Hellwig   xfs: remove ioloc...
965
  	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
b57922d97   Al Viro   convert remaining...
966
  	trace_xfs_evict_inode(ip);
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
967

91b0abe36   Johannes Weiner   mm + fs: store sh...
968
  	truncate_inode_pages_final(&inode->i_data);
dbd5768f8   Jan Kara   vfs: Rename end_w...
969
  	clear_inode(inode);
99fa8cb3c   David Chinner   [XFS] Prevent use...
970
971
972
973
974
  	XFS_STATS_INC(vn_rele);
  	XFS_STATS_INC(vn_remove);
  	XFS_STATS_DEC(vn_active);
  
  	xfs_inactive(ip);
56d433e43   Christoph Hellwig   [XFS] streamline ...
975
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
976

5132ba8f2   Dave Chinner   xfs: don't cache ...
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
  /*
   * 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);
  
  	return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
  STATIC void
a738159df   Christoph Hellwig   [XFS] don't leak ...
993
994
995
996
997
998
999
1000
1001
  xfs_free_fsname(
  	struct xfs_mount	*mp)
  {
  	kfree(mp->m_fsname);
  	kfree(mp->m_rtname);
  	kfree(mp->m_logname);
  }
  
  STATIC void
a50cd2692   Nathan Scott   [XFS] Switch over...
1002
  xfs_fs_put_super(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
  	struct super_block	*sb)
  {
745f69191   Christoph Hellwig   [XFS] call common...
1005
  	struct xfs_mount	*mp = XFS_M(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1006

7e18530be   Dave Chinner   xfs: rationalise ...
1007
1008
  	xfs_filestream_unmount(mp);
  	xfs_unmountfs(mp);
6203300e5   Christoph Hellwig   [XFS] don't call ...
1009
  	xfs_freesb(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1010
  	xfs_icsb_destroy_counters(mp);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1011
  	xfs_destroy_mount_workqueues(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1012
  	xfs_close_devices(mp);
a738159df   Christoph Hellwig   [XFS] don't leak ...
1013
  	xfs_free_fsname(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1014
  	kfree(mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1015
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  STATIC int
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1017
  xfs_fs_sync_fs(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1018
1019
1020
  	struct super_block	*sb,
  	int			wait)
  {
745f69191   Christoph Hellwig   [XFS] call common...
1021
  	struct xfs_mount	*mp = XFS_M(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1022

e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
1023
  	/*
34625c661   Christoph Hellwig   xfs: remove xfs_q...
1024
  	 * Doing anything during the async pass would be counterproductive.
e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
1025
  	 */
34625c661   Christoph Hellwig   xfs: remove xfs_q...
1026
  	if (!wait)
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1027
  		return 0;
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1028

34061f5c4   Dave Chinner   xfs: xfs_sync_fsd...
1029
  	xfs_log_force(mp, XFS_LOG_SYNC);
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1030
  	if (laptop_mode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
1032
  		/*
  		 * The disk must be active because we're syncing.
f661f1e0b   Dave Chinner   xfs: sync work is...
1033
  		 * We schedule log work now (now that the disk is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1034
1035
  		 * active) instead of later (when it might not be).
  		 */
f661f1e0b   Dave Chinner   xfs: sync work is...
1036
  		flush_delayed_work(&mp->m_log->l_work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
  	}
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1038
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
1040
1041
  }
  
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1042
  xfs_fs_statfs(
726c33422   David Howells   [PATCH] VFS: Perm...
1043
  	struct dentry		*dentry,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
1045
  	struct kstatfs		*statp)
  {
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1046
1047
  	struct xfs_mount	*mp = XFS_M(dentry->d_sb);
  	xfs_sb_t		*sbp = &mp->m_sb;
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
1048
  	struct xfs_inode	*ip = XFS_I(dentry->d_inode);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1049
1050
  	__uint64_t		fakeinos, id;
  	xfs_extlen_t		lsize;
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
1051
  	__int64_t		ffree;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1052
1053
1054
1055
1056
1057
1058
  
  	statp->f_type = XFS_SB_MAGIC;
  	statp->f_namelen = MAXNAMELEN - 1;
  
  	id = huge_encode_dev(mp->m_ddev_targp->bt_dev);
  	statp->f_fsid.val[0] = (u32)id;
  	statp->f_fsid.val[1] = (u32)(id >> 32);
d4d90b577   Christoph Hellwig   [XFS] Add xfs_ics...
1059
  	xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1060
1061
1062
1063
1064
1065
1066
1067
  
  	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;
  	statp->f_bfree = statp->f_bavail =
  				sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
  	fakeinos = statp->f_bfree << sbp->sb_inopblog;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1068
1069
1070
  	statp->f_files =
  	    MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
  	if (mp->m_maxicount)
a19d9f887   Christoph Hellwig   xfs: kill ino64 m...
1071
1072
1073
  		statp->f_files = min_t(typeof(statp->f_files),
  					statp->f_files,
  					mp->m_maxicount);
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
1074
1075
1076
1077
  
  	/* make sure statp->f_ffree does not underflow */
  	ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
  	statp->f_ffree = max_t(__int64_t, ffree, 0);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1078
  	spin_unlock(&mp->m_sb_lock);
da5bf95e3   Jie Liu   xfs: don't fill s...
1079
  	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
1080
1081
  	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
  			      (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
1082
  		xfs_qm_statvfs(ip, statp);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1083
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1084
  }
d5db0f97f   Eric Sandeen   xfs: more reserve...
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
  STATIC void
  xfs_save_resvblks(struct xfs_mount *mp)
  {
  	__uint64_t resblks = 0;
  
  	mp->m_resblks_save = mp->m_resblks;
  	xfs_reserve_blocks(mp, &resblks, NULL);
  }
  
  STATIC void
  xfs_restore_resvblks(struct xfs_mount *mp)
  {
  	__uint64_t resblks;
  
  	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);
  }
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1107
1108
1109
1110
1111
  /*
   * 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
c75921a72   Dave Chinner   xfs: xfs_quiesce_...
1112
1113
   * there is no log replay required to write the inodes to disk - this is the
   * primary difference between a sync and a quiesce.
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1114
   *
c75921a72   Dave Chinner   xfs: xfs_quiesce_...
1115
1116
   * Note: xfs_log_quiesce() stops background log work - the callers must ensure
   * it is started again when appropriate.
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1117
   */
632b89e82   Dave Chinner   xfs: fix static a...
1118
  static void
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
  xfs_quiesce_attr(
  	struct xfs_mount	*mp)
  {
  	int	error = 0;
  
  	/* wait for all modifications to complete */
  	while (atomic_read(&mp->m_active_trans) > 0)
  		delay(100);
  
  	/* force the log to unpin objects from the now complete transactions */
  	xfs_log_force(mp, XFS_LOG_SYNC);
  
  	/* reclaim inodes to do any IO before the freeze completes */
  	xfs_reclaim_inodes(mp, 0);
  	xfs_reclaim_inodes(mp, SYNC_WAIT);
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1134
1135
1136
1137
1138
  	/* 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.");
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1139
  	/*
c75921a72   Dave Chinner   xfs: xfs_quiesce_...
1140
1141
  	 * Just warn here till VFS can correctly support
  	 * read-only remount without racing.
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1142
  	 */
c75921a72   Dave Chinner   xfs: xfs_quiesce_...
1143
  	WARN_ON(atomic_read(&mp->m_active_trans) != 0);
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1144

c75921a72   Dave Chinner   xfs: xfs_quiesce_...
1145
  	xfs_log_quiesce(mp);
c7eea6f7a   Dave Chinner   xfs: move xfs_qui...
1146
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1148
  xfs_fs_remount(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
1150
1151
1152
  	struct super_block	*sb,
  	int			*flags,
  	char			*options)
  {
745f69191   Christoph Hellwig   [XFS] call common...
1153
  	struct xfs_mount	*mp = XFS_M(sb);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1154
1155
  	substring_t		args[MAX_OPT_ARGS];
  	char			*p;
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1156
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157

02b9984d6   Theodore Ts'o   fs: push sync_fil...
1158
  	sync_filesystem(sb);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1159
1160
  	while ((p = strsep(&options, ",")) != NULL) {
  		int token;
bdd907bab   Christoph Hellwig   [XFS] allow xfs_a...
1161

62a877e35   Christoph Hellwig   [XFS] fix mount o...
1162
1163
  		if (!*p)
  			continue;
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1164

62a877e35   Christoph Hellwig   [XFS] fix mount o...
1165
1166
1167
  		token = match_token(p, tokens, args);
  		switch (token) {
  		case Opt_barrier:
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1168
  			mp->m_flags |= XFS_MOUNT_BARRIER;
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1169
1170
  			break;
  		case Opt_nobarrier:
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1171
  			mp->m_flags &= ~XFS_MOUNT_BARRIER;
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1172
  			break;
c3a58fecd   Carlos Maiolino   Make inode64 a re...
1173
  		case Opt_inode64:
4c0837224   Carlos Maiolino   xfs: Fix mp->m_ma...
1174
  			mp->m_maxagi = xfs_set_inode64(mp);
c3a58fecd   Carlos Maiolino   Make inode64 a re...
1175
  			break;
2ea039298   Carlos Maiolino   xfs: Make inode32...
1176
1177
1178
  		case Opt_inode32:
  			mp->m_maxagi = xfs_set_inode32(mp);
  			break;
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1179
  		default:
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  			/*
  			 * 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.
  			 */
  #if 0
4f10700a2   Dave Chinner   xfs: Convert linu...
1197
  			xfs_info(mp,
08e96e1a3   Eric Sandeen   xfs: remove newli...
1198
  		"mount option \"%s\" not supported for remount", p);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1199
  			return -EINVAL;
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1200
  #else
6c5e51dae   Christoph Hellwig   xfs: fix remount ...
1201
  			break;
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1202
  #endif
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1203
  		}
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1204
  	}
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1205
  	/* ro -> rw */
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1206
1207
  	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
  		mp->m_flags &= ~XFS_MOUNT_RDONLY;
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1208
1209
1210
1211
1212
1213
1214
1215
  
  		/*
  		 * If this is the first remount to writeable state we
  		 * might have some superblock changes to update.
  		 */
  		if (mp->m_update_flags) {
  			error = xfs_mount_log_sb(mp, mp->m_update_flags);
  			if (error) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1216
  				xfs_warn(mp, "failed to write sb changes");
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1217
1218
1219
1220
  				return error;
  			}
  			mp->m_update_flags = 0;
  		}
cbe132a8b   Dave Chinner   xfs: don't hold o...
1221
1222
1223
1224
1225
  
  		/*
  		 * Fill out the reserve pool if it is empty. Use the stashed
  		 * value if it is non-zero, otherwise go with the default.
  		 */
d5db0f97f   Eric Sandeen   xfs: more reserve...
1226
  		xfs_restore_resvblks(mp);
f661f1e0b   Dave Chinner   xfs: sync work is...
1227
  		xfs_log_work_queue(mp);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1228
1229
1230
1231
  	}
  
  	/* rw -> ro */
  	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
cbe132a8b   Dave Chinner   xfs: don't hold o...
1232
  		/*
34061f5c4   Dave Chinner   xfs: xfs_sync_fsd...
1233
1234
1235
1236
1237
  		 * 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.
cbe132a8b   Dave Chinner   xfs: don't hold o...
1238
  		 */
d5db0f97f   Eric Sandeen   xfs: more reserve...
1239
  		xfs_save_resvblks(mp);
76bf105cb   David Chinner   [XFS] Move remain...
1240
  		xfs_quiesce_attr(mp);
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1241
1242
  		mp->m_flags |= XFS_MOUNT_RDONLY;
  	}
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1243
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
  }
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1245
1246
  /*
   * Second stage of a freeze. The data is already frozen so we only
76bf105cb   David Chinner   [XFS] Move remain...
1247
   * need to take care of the metadata. Once that's done write a dummy
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1248
1249
   * record to dirty the log in case of a crash while frozen.
   */
c4be0c1dc   Takashi Sato   filesystem freeze...
1250
1251
  STATIC int
  xfs_fs_freeze(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1252
1253
  	struct super_block	*sb)
  {
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1254
  	struct xfs_mount	*mp = XFS_M(sb);
d5db0f97f   Eric Sandeen   xfs: more reserve...
1255
  	xfs_save_resvblks(mp);
76bf105cb   David Chinner   [XFS] Move remain...
1256
  	xfs_quiesce_attr(mp);
c58efdb44   Dave Chinner   xfs: ensure log c...
1257
  	return -xfs_fs_log_dummy(mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1258
1259
1260
  }
  
  STATIC int
d5db0f97f   Eric Sandeen   xfs: more reserve...
1261
1262
1263
1264
1265
1266
  xfs_fs_unfreeze(
  	struct super_block	*sb)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	xfs_restore_resvblks(mp);
f661f1e0b   Dave Chinner   xfs: sync work is...
1267
  	xfs_log_work_queue(mp);
d5db0f97f   Eric Sandeen   xfs: more reserve...
1268
1269
1270
1271
  	return 0;
  }
  
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1272
  xfs_fs_show_options(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1273
  	struct seq_file		*m,
34c80b1d9   Al Viro   vfs: switch ->sho...
1274
  	struct dentry		*root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
1276
  	return -xfs_showargs(XFS_M(root->d_sb), m);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277
  }
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1278
1279
  /*
   * This function fills in xfs_mount_t fields based on mount args.
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1280
1281
1282
1283
   * Note: the superblock _has_ now been read in.
   */
  STATIC int
  xfs_finish_flags(
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1284
1285
1286
  	struct xfs_mount	*mp)
  {
  	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
025dfdafe   Frederik Schwarzer   trivial: fix then...
1287
  	/* Fail a mount where the logbuf is smaller than the log stripe */
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1288
  	if (xfs_sb_version_haslogv2(&mp->m_sb)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1289
1290
  		if (mp->m_logbsize <= 0 &&
  		    mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1291
  			mp->m_logbsize = mp->m_sb.sb_logsunit;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1292
1293
  		} else if (mp->m_logbsize > 0 &&
  			   mp->m_logbsize < mp->m_sb.sb_logsunit) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1294
1295
  			xfs_warn(mp,
  		"logbuf size must be greater than or equal to log stripe size");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1296
1297
1298
1299
  			return XFS_ERROR(EINVAL);
  		}
  	} else {
  		/* Fail a mount if the logbuf is larger than 32K */
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1300
  		if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1301
1302
  			xfs_warn(mp,
  		"logbuf size for version 1 logs must be 16K or 32K");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1303
1304
1305
1306
1307
  			return XFS_ERROR(EINVAL);
  		}
  	}
  
  	/*
d3eaace84   Dave Chinner   xfs: disable noat...
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
  	 * 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 %s. %s is always enabled for V5 filesystems.",
  			MNTOPT_NOATTR2, MNTOPT_ATTR2);
  		return XFS_ERROR(EINVAL);
  	}
  
  	/*
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1319
1320
1321
1322
  	 * 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) &&
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1323
  	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1324
1325
1326
1327
1328
1329
  		mp->m_flags |= XFS_MOUNT_ATTR2;
  
  	/*
  	 * prohibit r/w mounts of read-only filesystems
  	 */
  	if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1330
1331
  		xfs_warn(mp,
  			"cannot mount a read-only filesystem as read-write");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1332
1333
  		return XFS_ERROR(EROFS);
  	}
d892d5864   Chandra Seetharaman   xfs: Start using ...
1334
1335
1336
1337
1338
1339
1340
  	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 XFS_ERROR(EINVAL);
  	}
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1341
1342
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1343
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1344
  xfs_fs_fill_super(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345
1346
1347
1348
  	struct super_block	*sb,
  	void			*data,
  	int			silent)
  {
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1349
  	struct inode		*root;
745f69191   Christoph Hellwig   [XFS] call common...
1350
  	struct xfs_mount	*mp = NULL;
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1351
  	int			flags = 0, error = ENOMEM;
bdd907bab   Christoph Hellwig   [XFS] allow xfs_a...
1352

c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1353
1354
  	mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL);
  	if (!mp)
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1355
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356

c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1357
  	spin_lock_init(&mp->m_sb_lock);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1358
1359
  	mutex_init(&mp->m_growlock);
  	atomic_set(&mp->m_active_trans, 0);
7e18530be   Dave Chinner   xfs: rationalise ...
1360
  	INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
579b62faa   Brian Foster   xfs: add backgrou...
1361
  	INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
743944967   Christoph Hellwig   [XFS] move syncin...
1362

b267ce995   Christoph Hellwig   [XFS] kill struct...
1363
1364
  	mp->m_super = sb;
  	sb->s_fs_info = mp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1365

288699fec   Christoph Hellwig   xfs: drop dmapi h...
1366
  	error = xfs_parseargs(mp, (char *)data);
745f69191   Christoph Hellwig   [XFS] call common...
1367
  	if (error)
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1368
  		goto out_free_fsname;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
1370
  
  	sb_min_blocksize(sb, BBSIZE);
0ec585163   Lachlan McIlroy   [XFS] Use the gen...
1371
  	sb->s_xattr = xfs_xattr_handlers;
a50cd2692   Nathan Scott   [XFS] Switch over...
1372
  	sb->s_export_op = &xfs_export_operations;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1373
  #ifdef CONFIG_XFS_QUOTA
a50cd2692   Nathan Scott   [XFS] Switch over...
1374
  	sb->s_qcop = &xfs_quotactl_operations;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1375
  #endif
a50cd2692   Nathan Scott   [XFS] Switch over...
1376
  	sb->s_op = &xfs_super_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1377

9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1378
  	if (silent)
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1379
  		flags |= XFS_MFSI_QUIET;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1380
  	error = xfs_open_devices(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1381
  	if (error)
288699fec   Christoph Hellwig   xfs: drop dmapi h...
1382
  		goto out_free_fsname;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1383

aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1384
  	error = xfs_init_mount_workqueues(mp);
61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1385
1386
  	if (error)
  		goto out_close_devices;
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1387

aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1388
1389
1390
  	error = xfs_icsb_init_counters(mp);
  	if (error)
  		goto out_destroy_workqueues;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1391
1392
  	error = xfs_readsb(mp, flags);
  	if (error)
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1393
1394
1395
  		goto out_destroy_counters;
  
  	error = xfs_finish_flags(mp);
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1396
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1397
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1398

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

f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1403
1404
  	error = xfs_filestream_mount(mp);
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1405
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1406

704b2907c   Dave Chinner   xfs: register the...
1407
1408
1409
  	/*
  	 * 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...
1410
  	 */
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1411
1412
1413
  	sb->s_magic = XFS_SB_MAGIC;
  	sb->s_blocksize = mp->m_sb.sb_blocksize;
  	sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
  	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
8de527787   Al Viro   vfs: check i_nlin...
1415
  	sb->s_max_links = XFS_MAXLINK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
1417
  	sb->s_time_gran = 1;
  	set_posix_acl_flag(sb);
dc037ad7d   Dave Chinner   xfs: implement in...
1418
1419
1420
  	/* version 5 superblocks support inode version counters. */
  	if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
  		sb->s_flags |= MS_I_VERSION;
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1421
  	error = xfs_mountfs(mp);
2bcf6e970   Christoph Hellwig   xfs: start period...
1422
  	if (error)
7e18530be   Dave Chinner   xfs: rationalise ...
1423
  		goto out_filestream_unmount;
704b2907c   Dave Chinner   xfs: register the...
1424

016516462   David Chinner   [XFS] Avoid direc...
1425
  	root = igrab(VFS_I(mp->m_rootip));
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1426
  	if (!root) {
cbc89dcfd   Christoph Hellwig   [XFS] kill xfs_root
1427
  		error = ENOENT;
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1428
  		goto out_unmount;
cbc89dcfd   Christoph Hellwig   [XFS] kill xfs_root
1429
  	}
48fde701a   Al Viro   switch open-coded...
1430
  	sb->s_root = d_make_root(root);
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1431
1432
  	if (!sb->s_root) {
  		error = ENOMEM;
8a00ebe4c   Dave Chinner   xfs: Ensure inode...
1433
  		goto out_unmount;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1434
  	}
743944967   Christoph Hellwig   [XFS] move syncin...
1435

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

7e18530be   Dave Chinner   xfs: rationalise ...
1438
   out_filestream_unmount:
120226c11   Christoph Hellwig   [XFS] add missing...
1439
  	xfs_filestream_unmount(mp);
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1440
1441
   out_free_sb:
  	xfs_freesb(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1442
   out_destroy_counters:
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1443
  	xfs_icsb_destroy_counters(mp);
aa6bf01d3   Christoph Hellwig   xfs: use per-file...
1444
1445
  out_destroy_workqueues:
  	xfs_destroy_mount_workqueues(mp);
61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1446
   out_close_devices:
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1447
  	xfs_close_devices(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1448
1449
   out_free_fsname:
  	xfs_free_fsname(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1450
  	kfree(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1451
   out:
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1452
  	return -error;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1453

2bcf6e970   Christoph Hellwig   xfs: start period...
1454
   out_unmount:
e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
1455
  	xfs_filestream_unmount(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1456
  	xfs_unmountfs(mp);
6203300e5   Christoph Hellwig   [XFS] don't call ...
1457
  	goto out_free_sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1458
  }
152a08366   Al Viro   new helper: mount...
1459
1460
  STATIC struct dentry *
  xfs_fs_mount(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1461
1462
1463
  	struct file_system_type	*fs_type,
  	int			flags,
  	const char		*dev_name,
152a08366   Al Viro   new helper: mount...
1464
  	void			*data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1465
  {
152a08366   Al Viro   new helper: mount...
1466
  	return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
a50cd2692   Nathan Scott   [XFS] Switch over...
1467
  }
0a234c6dc   Dave Chinner   shrinker: convert...
1468
  static long
8daaa8314   Dave Chinner   xfs: make use of ...
1469
  xfs_fs_nr_cached_objects(
9b17c6238   Dave Chinner   fs: convert inode...
1470
1471
  	struct super_block	*sb,
  	int			nid)
8daaa8314   Dave Chinner   xfs: make use of ...
1472
1473
1474
  {
  	return xfs_reclaim_inodes_count(XFS_M(sb));
  }
0a234c6dc   Dave Chinner   shrinker: convert...
1475
  static long
8daaa8314   Dave Chinner   xfs: make use of ...
1476
1477
  xfs_fs_free_cached_objects(
  	struct super_block	*sb,
9b17c6238   Dave Chinner   fs: convert inode...
1478
1479
  	long			nr_to_scan,
  	int			nid)
8daaa8314   Dave Chinner   xfs: make use of ...
1480
  {
0a234c6dc   Dave Chinner   shrinker: convert...
1481
  	return xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan);
8daaa8314   Dave Chinner   xfs: make use of ...
1482
  }
b87221de6   Alexey Dobriyan   const: mark remai...
1483
  static const struct super_operations xfs_super_operations = {
a50cd2692   Nathan Scott   [XFS] Switch over...
1484
1485
  	.alloc_inode		= xfs_fs_alloc_inode,
  	.destroy_inode		= xfs_fs_destroy_inode,
b57922d97   Al Viro   convert remaining...
1486
  	.evict_inode		= xfs_fs_evict_inode,
5132ba8f2   Dave Chinner   xfs: don't cache ...
1487
  	.drop_inode		= xfs_fs_drop_inode,
a50cd2692   Nathan Scott   [XFS] Switch over...
1488
  	.put_super		= xfs_fs_put_super,
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1489
  	.sync_fs		= xfs_fs_sync_fs,
c4be0c1dc   Takashi Sato   filesystem freeze...
1490
  	.freeze_fs		= xfs_fs_freeze,
d5db0f97f   Eric Sandeen   xfs: more reserve...
1491
  	.unfreeze_fs		= xfs_fs_unfreeze,
a50cd2692   Nathan Scott   [XFS] Switch over...
1492
1493
1494
  	.statfs			= xfs_fs_statfs,
  	.remount_fs		= xfs_fs_remount,
  	.show_options		= xfs_fs_show_options,
8daaa8314   Dave Chinner   xfs: make use of ...
1495
1496
  	.nr_cached_objects	= xfs_fs_nr_cached_objects,
  	.free_cached_objects	= xfs_fs_free_cached_objects,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
  };
5085b607f   Andrew Morton   [PATCH] xfs warni...
1498
  static struct file_system_type xfs_fs_type = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
1500
  	.owner			= THIS_MODULE,
  	.name			= "xfs",
152a08366   Al Viro   new helper: mount...
1501
  	.mount			= xfs_fs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502
1503
1504
  	.kill_sb		= kill_block_super,
  	.fs_flags		= FS_REQUIRES_DEV,
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1505
  MODULE_ALIAS_FS("xfs");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1507
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1508
1509
  xfs_init_zones(void)
  {
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1510
1511
1512
  
  	xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend");
  	if (!xfs_ioend_zone)
bf904248a   David Chinner   [XFS] Combine the...
1513
  		goto out;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
  
  	xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE,
  						  xfs_ioend_zone);
  	if (!xfs_ioend_pool)
  		goto out_destroy_ioend_zone;
  
  	xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t),
  						"xfs_log_ticket");
  	if (!xfs_log_ticket_zone)
  		goto out_destroy_ioend_pool;
  
  	xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t),
  						"xfs_bmap_free_item");
  	if (!xfs_bmap_free_item_zone)
  		goto out_destroy_log_ticket_zone;
bf904248a   David Chinner   [XFS] Combine the...
1529

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1530
1531
1532
1533
1534
1535
1536
1537
1538
  	xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
  						"xfs_btree_cur");
  	if (!xfs_btree_cur_zone)
  		goto out_destroy_bmap_free_item_zone;
  
  	xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t),
  						"xfs_da_state");
  	if (!xfs_da_state_zone)
  		goto out_destroy_btree_cur_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1539
1540
  	xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
  	if (!xfs_ifork_zone)
1d9025e56   Dave Chinner   xfs: remove struc...
1541
  		goto out_destroy_da_state_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1542
1543
1544
1545
  
  	xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans");
  	if (!xfs_trans_zone)
  		goto out_destroy_ifork_zone;
e98c414f9   Christoph Hellwig   xfs: simplify log...
1546
1547
1548
1549
1550
  	xfs_log_item_desc_zone =
  		kmem_zone_init(sizeof(struct xfs_log_item_desc),
  			       "xfs_log_item_desc");
  	if (!xfs_log_item_desc_zone)
  		goto out_destroy_trans_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1551
1552
1553
1554
1555
  	/*
  	 * 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.
  	 */
77c1a08fc   Dave Chinner   xfs: struct xfs_b...
1556
1557
  	xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item),
  					   "xfs_buf_item");
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1558
  	if (!xfs_buf_item_zone)
e98c414f9   Christoph Hellwig   xfs: simplify log...
1559
  		goto out_destroy_log_item_desc_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
  
  	xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) +
  			((XFS_EFD_MAX_FAST_EXTENTS - 1) *
  				 sizeof(xfs_extent_t))), "xfs_efd_item");
  	if (!xfs_efd_zone)
  		goto out_destroy_buf_item_zone;
  
  	xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) +
  			((XFS_EFI_MAX_FAST_EXTENTS - 1) *
  				sizeof(xfs_extent_t))), "xfs_efi_item");
  	if (!xfs_efi_zone)
  		goto out_destroy_efd_zone;
  
  	xfs_inode_zone =
  		kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
bf904248a   David Chinner   [XFS] Combine the...
1575
1576
  			KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD,
  			xfs_fs_inode_init_once);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1577
1578
1579
1580
1581
1582
1583
1584
  	if (!xfs_inode_zone)
  		goto out_destroy_efi_zone;
  
  	xfs_ili_zone =
  		kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
  					KM_ZONE_SPREAD, NULL);
  	if (!xfs_ili_zone)
  		goto out_destroy_inode_zone;
3ebe7d2d7   Dave Chinner   xfs: Inode create...
1585
1586
1587
1588
  	xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item),
  					"xfs_icr");
  	if (!xfs_icreate_zone)
  		goto out_destroy_ili_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1589

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1590
  	return 0;
3ebe7d2d7   Dave Chinner   xfs: Inode create...
1591
1592
   out_destroy_ili_zone:
  	kmem_zone_destroy(xfs_ili_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1593
1594
1595
1596
1597
1598
1599
1600
   out_destroy_inode_zone:
  	kmem_zone_destroy(xfs_inode_zone);
   out_destroy_efi_zone:
  	kmem_zone_destroy(xfs_efi_zone);
   out_destroy_efd_zone:
  	kmem_zone_destroy(xfs_efd_zone);
   out_destroy_buf_item_zone:
  	kmem_zone_destroy(xfs_buf_item_zone);
e98c414f9   Christoph Hellwig   xfs: simplify log...
1601
1602
   out_destroy_log_item_desc_zone:
  	kmem_zone_destroy(xfs_log_item_desc_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1603
1604
1605
1606
   out_destroy_trans_zone:
  	kmem_zone_destroy(xfs_trans_zone);
   out_destroy_ifork_zone:
  	kmem_zone_destroy(xfs_ifork_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
   out_destroy_da_state_zone:
  	kmem_zone_destroy(xfs_da_state_zone);
   out_destroy_btree_cur_zone:
  	kmem_zone_destroy(xfs_btree_cur_zone);
   out_destroy_bmap_free_item_zone:
  	kmem_zone_destroy(xfs_bmap_free_item_zone);
   out_destroy_log_ticket_zone:
  	kmem_zone_destroy(xfs_log_ticket_zone);
   out_destroy_ioend_pool:
  	mempool_destroy(xfs_ioend_pool);
   out_destroy_ioend_zone:
  	kmem_zone_destroy(xfs_ioend_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1619
1620
1621
1622
1623
1624
1625
   out:
  	return -ENOMEM;
  }
  
  STATIC void
  xfs_destroy_zones(void)
  {
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
1626
1627
1628
1629
1630
  	/*
  	 * Make sure all delayed rcu free are flushed before we
  	 * destroy caches.
  	 */
  	rcu_barrier();
3ebe7d2d7   Dave Chinner   xfs: Inode create...
1631
  	kmem_zone_destroy(xfs_icreate_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1632
1633
1634
1635
1636
  	kmem_zone_destroy(xfs_ili_zone);
  	kmem_zone_destroy(xfs_inode_zone);
  	kmem_zone_destroy(xfs_efi_zone);
  	kmem_zone_destroy(xfs_efd_zone);
  	kmem_zone_destroy(xfs_buf_item_zone);
e98c414f9   Christoph Hellwig   xfs: simplify log...
1637
  	kmem_zone_destroy(xfs_log_item_desc_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1638
1639
  	kmem_zone_destroy(xfs_trans_zone);
  	kmem_zone_destroy(xfs_ifork_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1640
1641
1642
1643
1644
1645
  	kmem_zone_destroy(xfs_da_state_zone);
  	kmem_zone_destroy(xfs_btree_cur_zone);
  	kmem_zone_destroy(xfs_bmap_free_item_zone);
  	kmem_zone_destroy(xfs_log_ticket_zone);
  	mempool_destroy(xfs_ioend_pool);
  	kmem_zone_destroy(xfs_ioend_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1646
1647
  
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1648
1649
  
  STATIC int __init
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1650
1651
1652
  xfs_init_workqueues(void)
  {
  	/*
c999a223c   Dave Chinner   xfs: introduce an...
1653
1654
1655
1656
1657
1658
1659
  	 * 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.
  	 */
  	xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0);
  	if (!xfs_alloc_wq)
5889608df   Dave Chinner   xfs: syncd workqu...
1660
  		return -ENOMEM;
c999a223c   Dave Chinner   xfs: introduce an...
1661

0bf6a5bd4   Dave Chinner   xfs: convert the ...
1662
  	return 0;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1663
  }
39411f81e   Tony Luck   xfs_destroy_workq...
1664
  STATIC void
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1665
1666
  xfs_destroy_workqueues(void)
  {
c999a223c   Dave Chinner   xfs: introduce an...
1667
  	destroy_workqueue(xfs_alloc_wq);
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1668
1669
1670
  }
  
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1671
  init_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
1673
  {
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674

65795910c   Christoph Hellwig   [XFS] fix spuriou...
1675
1676
1677
  	printk(KERN_INFO XFS_VERSION_STRING " with "
  			 XFS_BUILD_OPTIONS " enabled
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678

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

8758280fc   Nathan Scott   [XFS] Cleanup the...
1681
  	error = xfs_init_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1682
1683
  	if (error)
  		goto out;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1684
  	error = xfs_init_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1685
  	if (error)
0b1b213fc   Christoph Hellwig   xfs: event tracin...
1686
  		goto out_destroy_zones;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1687

0bf6a5bd4   Dave Chinner   xfs: convert the ...
1688
1689
1690
  	error = xfs_mru_cache_init();
  	if (error)
  		goto out_destroy_wq;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1691
1692
1693
  	error = xfs_filestream_init();
  	if (error)
  		goto out_mru_cache_uninit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694

ce8e922c0   Nathan Scott   [XFS] Complete th...
1695
  	error = xfs_buf_init();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
  	if (error)
  		goto out_filestream_uninit;
  
  	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
1706

a05931ceb   Christoph Hellwig   xfs: remove the g...
1707
1708
1709
  	error = xfs_qm_init();
  	if (error)
  		goto out_sysctl_unregister;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1710
1711
1712
  
  	error = register_filesystem(&xfs_fs_type);
  	if (error)
a05931ceb   Christoph Hellwig   xfs: remove the g...
1713
  		goto out_qm_exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714
  	return 0;
a05931ceb   Christoph Hellwig   xfs: remove the g...
1715
1716
   out_qm_exit:
  	xfs_qm_exit();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1717
1718
1719
1720
1721
   out_sysctl_unregister:
  	xfs_sysctl_unregister();
   out_cleanup_procfs:
  	xfs_cleanup_procfs();
   out_buf_terminate:
ce8e922c0   Nathan Scott   [XFS] Complete th...
1722
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1723
1724
1725
1726
   out_filestream_uninit:
  	xfs_filestream_uninit();
   out_mru_cache_uninit:
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1727
1728
   out_destroy_wq:
  	xfs_destroy_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1729
   out_destroy_zones:
8758280fc   Nathan Scott   [XFS] Cleanup the...
1730
  	xfs_destroy_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1731
   out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
1733
1734
1735
  	return error;
  }
  
  STATIC void __exit
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1736
  exit_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
  {
a05931ceb   Christoph Hellwig   xfs: remove the g...
1738
  	xfs_qm_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1739
  	unregister_filesystem(&xfs_fs_type);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1740
1741
  	xfs_sysctl_unregister();
  	xfs_cleanup_procfs();
ce8e922c0   Nathan Scott   [XFS] Complete th...
1742
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1743
1744
  	xfs_filestream_uninit();
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1745
  	xfs_destroy_workqueues();
8758280fc   Nathan Scott   [XFS] Cleanup the...
1746
  	xfs_destroy_zones();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1747
1748
1749
1750
1751
1752
1753
1754
  }
  
  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");