Blame view

fs/xfs/xfs_super.c 45.1 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"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
20
  #include "xfs_bit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #include "xfs_log.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
22
  #include "xfs_inum.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
  #include "xfs_trans.h"
  #include "xfs_sb.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
25
  #include "xfs_ag.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  #include "xfs_dir2.h"
  #include "xfs_alloc.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
  #include "xfs_quota.h"
  #include "xfs_mount.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  #include "xfs_bmap_btree.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
31
  #include "xfs_alloc_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  #include "xfs_ialloc_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  #include "xfs_dinode.h"
  #include "xfs_inode.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
35
36
  #include "xfs_btree.h"
  #include "xfs_ialloc.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  #include "xfs_bmap.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
  #include "xfs_rtalloc.h"
  #include "xfs_error.h"
  #include "xfs_itable.h"
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
41
  #include "xfs_fsops.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
44
  #include "xfs_attr.h"
  #include "xfs_buf_item.h"
  #include "xfs_utils.h"
739bfb2a7   Christoph Hellwig   [XFS] call common...
45
  #include "xfs_vnodeops.h"
a67d7c5f5   David Chinner   [XFS] Move platfo...
46
  #include "xfs_log_priv.h"
249a8c112   David Chinner   [XFS] Move AIL pu...
47
  #include "xfs_trans_priv.h"
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
48
  #include "xfs_filestream.h"
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
49
  #include "xfs_da_btree.h"
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
50
51
52
  #include "xfs_extfree_item.h"
  #include "xfs_mru_cache.h"
  #include "xfs_inode_item.h"
fe4fa4b8e   David Chinner   [XFS] move sync c...
53
  #include "xfs_sync.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
54
  #include "xfs_trace.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
  
  #include <linux/namei.h>
  #include <linux/init.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
58
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  #include <linux/mount.h>
0829c3602   Christoph Hellwig   [XFS] Add infrast...
60
  #include <linux/mempool.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #include <linux/writeback.h>
4df08c525   Christoph Hellwig   [XFS] Switch kern...
62
  #include <linux/kthread.h>
7dfb71030   Nigel Cunningham   [PATCH] Add inclu...
63
  #include <linux/freezer.h>
62a877e35   Christoph Hellwig   [XFS] fix mount o...
64
  #include <linux/parser.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65

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

a67d7c5f5   David Chinner   [XFS] Move platfo...
70
71
72
73
74
75
  #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...
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  #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...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  #define MNTOPT_64BITINODE   "inode64"	/* inodes can be allocated anywhere */
  #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...
112
113
114
115
  #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...
116

62a877e35   Christoph Hellwig   [XFS] fix mount o...
117
118
119
120
121
122
123
124
125
  /*
   * Table driven mount option parser.
   *
   * Currently only used for remount, but it will be used for mount
   * in the future, too.
   */
  enum {
  	Opt_barrier, Opt_nobarrier, Opt_err
  };
a447c0932   Steven Whitehouse   vfs: Use const fo...
126
  static const match_table_t tokens = {
62a877e35   Christoph Hellwig   [XFS] fix mount o...
127
128
129
130
  	{Opt_barrier, "barrier"},
  	{Opt_nobarrier, "nobarrier"},
  	{Opt_err, NULL}
  };
a67d7c5f5   David Chinner   [XFS] Move platfo...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  STATIC unsigned long
  suffix_strtoul(char *s, char **endp, unsigned int base)
  {
  	int	last, shift_left_factor = 0;
  	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';
  	}
  
  	return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
  }
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
153
154
155
156
157
158
159
  /*
   * 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...
160
161
162
  STATIC int
  xfs_parseargs(
  	struct xfs_mount	*mp,
288699fec   Christoph Hellwig   xfs: drop dmapi h...
163
  	char			*options)
a67d7c5f5   David Chinner   [XFS] Move platfo...
164
  {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
165
  	struct super_block	*sb = mp->m_super;
a67d7c5f5   David Chinner   [XFS] Move platfo...
166
  	char			*this_char, *value, *eov;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
167
168
169
  	int			dsunit = 0;
  	int			dswidth = 0;
  	int			iosize = 0;
a56877873   Christoph Hellwig   xfs: remove uchar...
170
  	__uint8_t		iosizelog = 0;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
171
172
  
  	/*
4f10700a2   Dave Chinner   xfs: Convert linu...
173
174
175
176
177
178
179
180
181
  	 * 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...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  	 * 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;
  	mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
198

9d565ffa3   Christoph Hellwig   [XFS] kill struct...
199
200
201
202
203
  	/*
  	 * These can be overridden by the mount option parsing.
  	 */
  	mp->m_logbufs = -1;
  	mp->m_logbsize = -1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
204
205
206
  
  	if (!options)
  		goto done;
a67d7c5f5   David Chinner   [XFS] Move platfo...
207
208
209
210
211
212
213
214
  	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...
215
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
216
217
218
  					this_char);
  				return EINVAL;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
219
  			mp->m_logbufs = simple_strtoul(value, &eov, 10);
a67d7c5f5   David Chinner   [XFS] Move platfo...
220
221
  		} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
  			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;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
226
  			mp->m_logbsize = suffix_strtoul(value, &eov, 10);
a67d7c5f5   David Chinner   [XFS] Move platfo...
227
228
  		} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
229
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
230
231
232
  					this_char);
  				return EINVAL;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
233
234
235
  			mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
  			if (!mp->m_logname)
  				return ENOMEM;
a67d7c5f5   David Chinner   [XFS] Move platfo...
236
  		} else if (!strcmp(this_char, MNTOPT_MTPT)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
237
  			xfs_warn(mp, "%s option not allowed on this system",
288699fec   Christoph Hellwig   xfs: drop dmapi h...
238
239
  				this_char);
  			return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
240
241
  		} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
242
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
243
244
245
  					this_char);
  				return EINVAL;
  			}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
246
247
248
  			mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
  			if (!mp->m_rtname)
  				return ENOMEM;
a67d7c5f5   David Chinner   [XFS] Move platfo...
249
250
  		} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
  			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
255
  					this_char);
  				return EINVAL;
  			}
  			iosize = simple_strtoul(value, &eov, 10);
1ec7944be   Christoph Hellwig   [XFS] fix biosize...
256
  			iosizelog = ffs(iosize) - 1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
257
258
  		} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
259
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
260
261
262
263
  					this_char);
  				return EINVAL;
  			}
  			iosize = suffix_strtoul(value, &eov, 10);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
264
  			iosizelog = ffs(iosize) - 1;
a67d7c5f5   David Chinner   [XFS] Move platfo...
265
266
267
268
269
270
271
  		} 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...
272
  			mp->m_flags |= XFS_MOUNT_WSYNC;
a67d7c5f5   David Chinner   [XFS] Move platfo...
273
  		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
274
  			mp->m_flags |= XFS_MOUNT_NORECOVERY;
a67d7c5f5   David Chinner   [XFS] Move platfo...
275
  		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
276
  			mp->m_flags |= XFS_MOUNT_NOALIGN;
a67d7c5f5   David Chinner   [XFS] Move platfo...
277
  		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
278
  			mp->m_flags |= XFS_MOUNT_SWALLOC;
a67d7c5f5   David Chinner   [XFS] Move platfo...
279
280
  		} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
281
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
282
283
284
285
286
287
  					this_char);
  				return EINVAL;
  			}
  			dsunit = simple_strtoul(value, &eov, 10);
  		} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
  			if (!value || !*value) {
4f10700a2   Dave Chinner   xfs: Convert linu...
288
  				xfs_warn(mp, "%s option requires an argument",
a67d7c5f5   David Chinner   [XFS] Move platfo...
289
290
291
292
293
  					this_char);
  				return EINVAL;
  			}
  			dswidth = simple_strtoul(value, &eov, 10);
  		} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
294
  			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
295
  #if !XFS_BIG_INUMS
4f10700a2   Dave Chinner   xfs: Convert linu...
296
  			xfs_warn(mp, "%s option not allowed on this system",
a67d7c5f5   David Chinner   [XFS] Move platfo...
297
298
299
300
  				this_char);
  			return EINVAL;
  #endif
  		} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
301
  			mp->m_flags |= XFS_MOUNT_NOUUID;
a67d7c5f5   David Chinner   [XFS] Move platfo...
302
  		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
303
  			mp->m_flags |= XFS_MOUNT_BARRIER;
a67d7c5f5   David Chinner   [XFS] Move platfo...
304
  		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
305
  			mp->m_flags &= ~XFS_MOUNT_BARRIER;
a67d7c5f5   David Chinner   [XFS] Move platfo...
306
  		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
307
  			mp->m_flags |= XFS_MOUNT_IKEEP;
a67d7c5f5   David Chinner   [XFS] Move platfo...
308
  		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
309
  			mp->m_flags &= ~XFS_MOUNT_IKEEP;
a67d7c5f5   David Chinner   [XFS] Move platfo...
310
  		} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
311
  			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
a67d7c5f5   David Chinner   [XFS] Move platfo...
312
  		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
313
  			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
a67d7c5f5   David Chinner   [XFS] Move platfo...
314
  		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
315
  			mp->m_flags |= XFS_MOUNT_ATTR2;
a67d7c5f5   David Chinner   [XFS] Move platfo...
316
  		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
317
318
  			mp->m_flags &= ~XFS_MOUNT_ATTR2;
  			mp->m_flags |= XFS_MOUNT_NOATTR2;
a67d7c5f5   David Chinner   [XFS] Move platfo...
319
  		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
320
  			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
a67d7c5f5   David Chinner   [XFS] Move platfo...
321
  		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
322
323
  			mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
  					  XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
469fc23d5   Christoph Hellwig   [XFS] fix the noq...
324
  					  XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
325
  					  XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
326
327
328
  		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
  			   !strcmp(this_char, MNTOPT_UQUOTA) ||
  			   !strcmp(this_char, MNTOPT_USRQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
329
330
  			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
  					 XFS_UQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
331
332
  		} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
  			   !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
333
334
  			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
  			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
a67d7c5f5   David Chinner   [XFS] Move platfo...
335
336
  		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
  			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
337
338
  			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
  					 XFS_OQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
339
  		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
340
341
  			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
  			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
a67d7c5f5   David Chinner   [XFS] Move platfo...
342
343
  		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
  			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
344
345
  			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
  					 XFS_OQUOTA_ENFD);
a67d7c5f5   David Chinner   [XFS] Move platfo...
346
  		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
347
348
  			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
  			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
71e330b59   Dave Chinner   xfs: Introduce de...
349
  		} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
93b8a5854   Christoph Hellwig   xfs: remove the d...
350
351
  			xfs_warn(mp,
  	"delaylog is the default now, option is deprecated.");
71e330b59   Dave Chinner   xfs: Introduce de...
352
  		} else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
242d62196   Christoph Hellwig   xfs: deprecate th...
353
  			xfs_warn(mp,
93b8a5854   Christoph Hellwig   xfs: remove the d...
354
  	"nodelaylog support has been removed, option is deprecated.");
e84661aa8   Christoph Hellwig   xfs: add online d...
355
356
357
358
  		} 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...
359
  		} else if (!strcmp(this_char, "ihashsize")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
360
361
  			xfs_warn(mp,
  	"ihashsize no longer used, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
362
  		} else if (!strcmp(this_char, "osyncisdsync")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
363
364
  			xfs_warn(mp,
  	"osyncisdsync has no effect, option is deprecated.");
a64afb057   Christoph Hellwig   xfs: remove obsol...
365
  		} else if (!strcmp(this_char, "osyncisosync")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
366
367
  			xfs_warn(mp,
  	"osyncisosync has no effect, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
368
  		} else if (!strcmp(this_char, "irixsgid")) {
4f10700a2   Dave Chinner   xfs: Convert linu...
369
370
  			xfs_warn(mp,
  	"irixsgid is now a sysctl(2) variable, option is deprecated.");
a67d7c5f5   David Chinner   [XFS] Move platfo...
371
  		} else {
4f10700a2   Dave Chinner   xfs: Convert linu...
372
  			xfs_warn(mp, "unknown mount option [%s].", this_char);
a67d7c5f5   David Chinner   [XFS] Move platfo...
373
374
375
  			return EINVAL;
  		}
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
376
377
378
379
380
  	/*
  	 * 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...
381
  		xfs_warn(mp, "no-recovery mounts must be read-only.");
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
382
  		return EINVAL;
a67d7c5f5   David Chinner   [XFS] Move platfo...
383
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
384
  	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
385
386
  		xfs_warn(mp,
  	"sunit and swidth options incompatible with the noalign option");
a67d7c5f5   David Chinner   [XFS] Move platfo...
387
388
  		return EINVAL;
  	}
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
389
390
  #ifndef CONFIG_XFS_QUOTA
  	if (XFS_IS_QUOTA_RUNNING(mp)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
391
  		xfs_warn(mp, "quota support not available in this kernel.");
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
392
393
394
  		return EINVAL;
  	}
  #endif
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
395
396
  	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
  	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) {
4f10700a2   Dave Chinner   xfs: Convert linu...
397
  		xfs_warn(mp, "cannot mount with both project and group quota");
a67d7c5f5   David Chinner   [XFS] Move platfo...
398
399
  		return EINVAL;
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
400
  	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
401
  		xfs_warn(mp, "sunit and swidth must be specified together");
a67d7c5f5   David Chinner   [XFS] Move platfo...
402
403
404
405
  		return EINVAL;
  	}
  
  	if (dsunit && (dswidth % dsunit != 0)) {
4f10700a2   Dave Chinner   xfs: Convert linu...
406
407
  		xfs_warn(mp,
  	"stripe width (%d) must be a multiple of the stripe unit (%d)",
a67d7c5f5   David Chinner   [XFS] Move platfo...
408
409
410
  			dswidth, dsunit);
  		return EINVAL;
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
411
412
413
414
415
416
417
418
  done:
  	if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) {
  		/*
  		 * 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.
  		 */
a67d7c5f5   David Chinner   [XFS] Move platfo...
419
  		if (dsunit) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
420
421
  			mp->m_dalign = dsunit;
  			mp->m_flags |= XFS_MOUNT_RETERR;
a67d7c5f5   David Chinner   [XFS] Move platfo...
422
  		}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
423
424
425
426
427
428
429
430
431
  
  		if (dswidth)
  			mp->m_swidth = dswidth;
  	}
  
  	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...
432
  		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
433
434
435
436
437
438
439
440
  			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...
441
442
  		xfs_warn(mp,
  			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
443
444
445
  			mp->m_logbsize);
  		return XFS_ERROR(EINVAL);
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
446
447
448
  	if (iosizelog) {
  		if (iosizelog > XFS_MAX_IO_LOG ||
  		    iosizelog < XFS_MIN_IO_LOG) {
4f10700a2   Dave Chinner   xfs: Convert linu...
449
  			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
450
451
452
453
454
455
456
457
  				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...
458
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
  	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...
474
  		{ XFS_MOUNT_IKEEP,		"," MNTOPT_IKEEP },
a67d7c5f5   David Chinner   [XFS] Move platfo...
475
  		{ XFS_MOUNT_WSYNC,		"," MNTOPT_WSYNC },
a67d7c5f5   David Chinner   [XFS] Move platfo...
476
477
478
479
  		{ 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...
480
481
  		{ XFS_MOUNT_ATTR2,		"," MNTOPT_ATTR2 },
  		{ XFS_MOUNT_FILESTREAMS,	"," MNTOPT_FILESTREAM },
a67d7c5f5   David Chinner   [XFS] Move platfo...
482
  		{ XFS_MOUNT_GRPID,		"," MNTOPT_GRPID },
e84661aa8   Christoph Hellwig   xfs: add online d...
483
  		{ XFS_MOUNT_DISCARD,		"," MNTOPT_DISCARD },
a67d7c5f5   David Chinner   [XFS] Move platfo...
484
485
486
487
  		{ 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...
488
489
490
491
492
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
  		{ 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...
529
530
531
532
533
534
535
536
537
538
539
540
541
  	/* Either project or group quotas can be active, not both */
  
  	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
  		if (mp->m_qflags & XFS_OQUOTA_ENFD)
  			seq_puts(m, "," MNTOPT_PRJQUOTA);
  		else
  			seq_puts(m, "," MNTOPT_PQUOTANOENF);
  	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
  		if (mp->m_qflags & XFS_OQUOTA_ENFD)
  			seq_puts(m, "," MNTOPT_GRPQUOTA);
  		else
  			seq_puts(m, "," MNTOPT_GQUOTANOENF);
  	}
a67d7c5f5   David Chinner   [XFS] Move platfo...
542
543
544
545
546
547
  
  	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
  		seq_puts(m, "," MNTOPT_NOQUOTA);
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
550
551
552
553
554
555
556
  __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...
557
  	 * __block_write_begin does this in an [unsigned] long...
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
562
563
564
565
566
567
568
569
  	 *      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...
570
  # if defined(CONFIG_LBDAF)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
574
575
576
577
578
579
580
  	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;
  }
3180e66d7   Hannes Eder   xfs: make symbols...
581
  STATIC int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
583
584
585
586
587
  xfs_blkdev_get(
  	xfs_mount_t		*mp,
  	const char		*name,
  	struct block_device	**bdevp)
  {
  	int			error = 0;
d4d776299   Tejun Heo   block: clean up b...
588
589
  	*bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
  				    mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
  	if (IS_ERR(*bdevp)) {
  		error = PTR_ERR(*bdevp);
4f10700a2   Dave Chinner   xfs: Convert linu...
592
593
  		xfs_warn(mp, "Invalid device [%s], error=%d
  ", name, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
597
  	}
  
  	return -error;
  }
3180e66d7   Hannes Eder   xfs: make symbols...
598
  STATIC void
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
600
601
602
  xfs_blkdev_put(
  	struct block_device	*bdev)
  {
  	if (bdev)
e525fd89d   Tejun Heo   block: make blkde...
603
  		blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  }
f538d4da8   Christoph Hellwig   [XFS] write barri...
605
606
607
608
  void
  xfs_blkdev_issue_flush(
  	xfs_buftarg_t		*buftarg)
  {
dd3932edd   Christoph Hellwig   block: remove BLK...
609
  	blkdev_issue_flush(buftarg->bt_bdev, GFP_KERNEL, NULL);
f538d4da8   Christoph Hellwig   [XFS] write barri...
610
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611

19f354d4c   Christoph Hellwig   [XFS] sort out op...
612
613
614
615
616
  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...
617
  		struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
b79631330   Christoph Hellwig   xfs: only issues ...
618
  		xfs_free_buftarg(mp, mp->m_logdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
619
  		xfs_blkdev_put(logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
620
621
  	}
  	if (mp->m_rtdev_targp) {
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
622
  		struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
b79631330   Christoph Hellwig   xfs: only issues ...
623
  		xfs_free_buftarg(mp, mp->m_rtdev_targp);
c032bfcf4   Lachlan McIlroy   [XFS] fix use aft...
624
  		xfs_blkdev_put(rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
625
  	}
b79631330   Christoph Hellwig   xfs: only issues ...
626
  	xfs_free_buftarg(mp, mp->m_ddev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  }
  
  /*
   * 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...
641
  	struct xfs_mount	*mp)
19f354d4c   Christoph Hellwig   [XFS] sort out op...
642
643
644
645
646
647
648
649
  {
  	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...
650
651
  	if (mp->m_logname) {
  		error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
652
653
654
  		if (error)
  			goto out;
  	}
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
655
656
  	if (mp->m_rtname) {
  		error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
657
658
659
660
  		if (error)
  			goto out_close_logdev;
  
  		if (rtdev == ddev || rtdev == logdev) {
4f10700a2   Dave Chinner   xfs: Convert linu...
661
662
  			xfs_warn(mp,
  	"Cannot mount filesystem with identical rtdev and ddev/logdev.");
19f354d4c   Christoph Hellwig   [XFS] sort out op...
663
664
665
666
667
668
669
670
671
  			error = EINVAL;
  			goto out_close_rtdev;
  		}
  	}
  
  	/*
  	 * Setup xfs_mount buffer target pointers
  	 */
  	error = ENOMEM;
ebad861b5   Dave Chinner   xfs: store xfs_mo...
672
  	mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
673
674
675
676
  	if (!mp->m_ddev_targp)
  		goto out_close_rtdev;
  
  	if (rtdev) {
ebad861b5   Dave Chinner   xfs: store xfs_mo...
677
678
  		mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1,
  							mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
679
680
681
682
683
  		if (!mp->m_rtdev_targp)
  			goto out_free_ddev_targ;
  	}
  
  	if (logdev && logdev != ddev) {
ebad861b5   Dave Chinner   xfs: store xfs_mo...
684
685
  		mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1,
  							mp->m_fsname);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
686
687
688
689
690
691
692
693
694
695
  		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 ...
696
  		xfs_free_buftarg(mp, mp->m_rtdev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
697
   out_free_ddev_targ:
b79631330   Christoph Hellwig   xfs: only issues ...
698
  	xfs_free_buftarg(mp, mp->m_ddev_targp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
699
700
701
702
703
704
705
706
707
   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...
708
709
710
711
712
713
714
715
  /*
   * 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...
716

e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  	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...
743

bf904248a   David Chinner   [XFS] Combine the...
744
  /* Catch misguided souls that try to use this interface on XFS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
  STATIC struct inode *
a50cd2692   Nathan Scott   [XFS] Switch over...
746
  xfs_fs_alloc_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
  	struct super_block	*sb)
  {
bf904248a   David Chinner   [XFS] Combine the...
749
  	BUG();
493dca617   Lachlan McIlroy   [XFS] Fix build w...
750
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
  }
bf904248a   David Chinner   [XFS] Combine the...
752
  /*
99fa8cb3c   David Chinner   [XFS] Prevent use...
753
754
   * 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...
755
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
  STATIC void
a50cd2692   Nathan Scott   [XFS] Switch over...
757
  xfs_fs_destroy_inode(
848ce8f73   Christoph Hellwig   xfs: simplify ino...
758
  	struct inode		*inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
  {
848ce8f73   Christoph Hellwig   xfs: simplify ino...
760
  	struct xfs_inode	*ip = XFS_I(inode);
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
761
  	trace_xfs_destroy_inode(ip);
99fa8cb3c   David Chinner   [XFS] Prevent use...
762
763
  
  	XFS_STATS_INC(vn_reclaim);
848ce8f73   Christoph Hellwig   xfs: simplify ino...
764
765
766
767
  
  	/* bad inode, get out here ASAP */
  	if (is_bad_inode(inode))
  		goto out_reclaim;
848ce8f73   Christoph Hellwig   xfs: simplify ino...
768
769
770
771
772
773
774
775
776
  	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 ...
777
778
779
780
781
  	 * 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...
782
  	 */
848ce8f73   Christoph Hellwig   xfs: simplify ino...
783
  out_reclaim:
57817c682   Dave Chinner   xfs: reclaim all ...
784
  	xfs_inode_set_reclaim_tag(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
  }
07c8f6758   David Chinner   [XFS] Make use of...
786
787
788
789
  /*
   * 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...
790
   * from the slab. This avoids the need to repeatedly initialise
07c8f6758   David Chinner   [XFS] Make use of...
791
792
793
   * fields in the xfs inode that left in the initialise state
   * when freeing the inode.
   */
bf904248a   David Chinner   [XFS] Combine the...
794
795
  STATIC void
  xfs_fs_inode_init_once(
07c8f6758   David Chinner   [XFS] Make use of...
796
797
798
799
800
  	void			*inode)
  {
  	struct xfs_inode	*ip = inode;
  
  	memset(ip, 0, sizeof(struct xfs_inode));
bf904248a   David Chinner   [XFS] Combine the...
801
802
803
804
805
  
  	/* vfs inode */
  	inode_init_once(VFS_I(ip));
  
  	/* xfs inode */
07c8f6758   David Chinner   [XFS] Make use of...
806
807
  	atomic_set(&ip->i_pincount, 0);
  	spin_lock_init(&ip->i_flags_lock);
07c8f6758   David Chinner   [XFS] Make use of...
808
809
810
811
812
813
814
815
816
817
818
  	init_waitqueue_head(&ip->i_ipin_wait);
  	/*
  	 * Because we want to use a counting completion, complete
  	 * the flush completion once to allow a single access to
  	 * the flush completion without blocking.
  	 */
  	init_completion(&ip->i_flush);
  	complete(&ip->i_flush);
  
  	mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
  		     "xfsino", ip->i_ino);
07c8f6758   David Chinner   [XFS] Make use of...
819
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
820
  /*
f9581b144   Christoph Hellwig   xfs: implement ->...
821
   * Dirty the XFS inode when mark_inode_dirty_sync() is called so that
dcd79a142   Dave Chinner   xfs: don't use vf...
822
   * we catch unlogged VFS level updates to the inode.
f9581b144   Christoph Hellwig   xfs: implement ->...
823
824
825
826
827
828
829
830
   *
   * We need the barrier() to maintain correct ordering between unlogged
   * updates and the transaction commit code that clears the i_update_core
   * field. This requires all updates to be completed before marking the
   * inode dirty.
   */
  STATIC void
  xfs_fs_dirty_inode(
aa3857295   Christoph Hellwig   fs: pass exact ty...
831
832
  	struct inode	*inode,
  	int		flags)
f9581b144   Christoph Hellwig   xfs: implement ->...
833
834
835
836
  {
  	barrier();
  	XFS_I(inode)->i_update_core = 1;
  }
07fec7362   Christoph Hellwig   xfs: log changed ...
837
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
838
  xfs_fs_write_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
  	struct inode		*inode,
a9185b41a   Christoph Hellwig   pass writeback_co...
840
  	struct writeback_control *wbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
  {
2e6560929   Dave Chinner   [XFS] fix error i...
842
  	struct xfs_inode	*ip = XFS_I(inode);
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
843
  	struct xfs_mount	*mp = ip->i_mount;
07fec7362   Christoph Hellwig   xfs: log changed ...
844
  	int			error = EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845

cca28fb83   Christoph Hellwig   xfs: split xfs_it...
846
  	trace_xfs_write_inode(ip);
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
847
848
  
  	if (XFS_FORCED_SHUTDOWN(mp))
58d84c4ee   Christoph Hellwig   xfs: fix ->write_...
849
  		return -XFS_ERROR(EIO);
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
850

0b8fd3033   Christoph Hellwig   xfs: log the inod...
851
  	if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) {
07fec7362   Christoph Hellwig   xfs: log changed ...
852
  		/*
7a36c8a98   Christoph Hellwig   xfs: avoid synchr...
853
854
855
856
  		 * Make sure the inode has made it it into the log.  Instead
  		 * of forcing it all the way to stable storage using a
  		 * synchronous transaction we let the log force inside the
  		 * ->sync_fs call do that for thus, which reduces the number
4a06fd262   Christoph Hellwig   xfs: remove i_ioc...
857
  		 * of synchronous log forces dramatically.
07fec7362   Christoph Hellwig   xfs: log changed ...
858
  		 */
be4f1ac82   Christoph Hellwig   xfs: log all dirt...
859
  		error = xfs_log_dirty_inode(ip, NULL, 0);
58d84c4ee   Christoph Hellwig   xfs: fix ->write_...
860
861
862
  		if (error)
  			goto out;
  		return 0;
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
863
  	} else {
be4f1ac82   Christoph Hellwig   xfs: log all dirt...
864
865
  		if (!ip->i_update_core)
  			return 0;
07fec7362   Christoph Hellwig   xfs: log changed ...
866
867
868
869
  		/*
  		 * We make this non-blocking if the inode is contended, return
  		 * EAGAIN to indicate to the caller that they did not succeed.
  		 * This prevents the flush path from blocking on inodes inside
7a36c8a98   Christoph Hellwig   xfs: avoid synchr...
870
871
  		 * another operation right now, they get caught later by
  		 * xfs_sync.
07fec7362   Christoph Hellwig   xfs: log changed ...
872
  		 */
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
873
874
  		if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
  			goto out;
07fec7362   Christoph Hellwig   xfs: log changed ...
875

7a36c8a98   Christoph Hellwig   xfs: avoid synchr...
876
877
  		if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
  			goto out_unlock;
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
878

7a36c8a98   Christoph Hellwig   xfs: avoid synchr...
879
880
881
882
883
884
885
886
887
888
889
890
  		/*
  		 * Now we have the flush lock and the inode is not pinned, we
  		 * can check if the inode is really clean as we know that
  		 * there are no pending transaction completions, it is not
  		 * waiting on the delayed write queue and there is no IO in
  		 * progress.
  		 */
  		if (xfs_inode_clean(ip)) {
  			xfs_ifunlock(ip);
  			error = 0;
  			goto out_unlock;
  		}
1bfd8d041   Dave Chinner   xfs: introduce in...
891
  		error = xfs_iflush(ip, SYNC_TRYLOCK);
d4bb6d069   Christoph Hellwig   xfs: merge xfs_in...
892
893
894
895
896
  	}
  
   out_unlock:
  	xfs_iunlock(ip, XFS_ILOCK_SHARED);
   out:
e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
897
898
899
900
901
  	/*
  	 * if we failed to write out the inode then mark
  	 * it dirty again so we'll try again later.
  	 */
  	if (error)
2e6560929   Dave Chinner   [XFS] fix error i...
902
  		xfs_mark_inode_dirty_sync(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
904
905
906
  	return -error;
  }
  
  STATIC void
b57922d97   Al Viro   convert remaining...
907
  xfs_fs_evict_inode(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
909
  	struct inode		*inode)
  {
1543d79c4   Christoph Hellwig   [XFS] move v_trac...
910
  	xfs_inode_t		*ip = XFS_I(inode);
56d433e43   Christoph Hellwig   [XFS] streamline ...
911

b57922d97   Al Viro   convert remaining...
912
  	trace_xfs_evict_inode(ip);
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
913

b57922d97   Al Viro   convert remaining...
914
915
  	truncate_inode_pages(&inode->i_data, 0);
  	end_writeback(inode);
99fa8cb3c   David Chinner   [XFS] Prevent use...
916
917
918
  	XFS_STATS_INC(vn_rele);
  	XFS_STATS_INC(vn_remove);
  	XFS_STATS_DEC(vn_active);
033da48fd   Christoph Hellwig   xfs: reset the i_...
919
920
921
922
923
924
925
926
927
928
929
930
931
  	/*
  	 * The iolock is used by the file system to coordinate reads,
  	 * writes, and block truncates.  Up to this point the lock
  	 * protected concurrent accesses by users of the inode.  But
  	 * from here forward we're doing some final processing of the
  	 * inode because we're done with it, and although we reuse the
  	 * iolock for protection it is really a distinct lock class
  	 * (in the lockdep sense) from before.  To keep lockdep happy
  	 * (and basically indicate what we are doing), we explicitly
  	 * re-init the iolock here.
  	 */
  	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
  	mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
dcfcf2051   Dave Chinner   xfs: provide a in...
932
933
  	lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
  			&xfs_iolock_reclaimable, "xfs_iolock_reclaimable");
033da48fd   Christoph Hellwig   xfs: reset the i_...
934

99fa8cb3c   David Chinner   [XFS] Prevent use...
935
  	xfs_inactive(ip);
56d433e43   Christoph Hellwig   [XFS] streamline ...
936
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  STATIC void
a738159df   Christoph Hellwig   [XFS] don't leak ...
939
940
941
942
943
944
945
946
947
  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...
948
  xfs_fs_put_super(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
950
  	struct super_block	*sb)
  {
745f69191   Christoph Hellwig   [XFS] call common...
951
  	struct xfs_mount	*mp = XFS_M(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952

a167b17e8   David Chinner   [XFS] move xfssyn...
953
  	xfs_syncd_stop(mp);
075fe1028   Christoph Hellwig   xfs: split xfs_sy...
954

e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
955
956
957
958
959
960
  	/*
  	 * Blow away any referenced inode in the filestreams cache.
  	 * This can and will cause log traffic as inodes go inactive
  	 * here.
  	 */
  	xfs_filestream_unmount(mp);
a9add83e5   Christoph Hellwig   xfs: remove XFS_b...
961
  	xfs_flush_buftarg(mp->m_ddev_targp, 1);
e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
962

19f354d4c   Christoph Hellwig   [XFS] sort out op...
963
  	xfs_unmountfs(mp);
6203300e5   Christoph Hellwig   [XFS] don't call ...
964
  	xfs_freesb(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
965
  	xfs_icsb_destroy_counters(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
966
  	xfs_close_devices(mp);
a738159df   Christoph Hellwig   [XFS] don't leak ...
967
  	xfs_free_fsname(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
968
  	kfree(mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
  STATIC int
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
971
  xfs_fs_sync_fs(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
973
974
  	struct super_block	*sb,
  	int			wait)
  {
745f69191   Christoph Hellwig   [XFS] call common...
975
  	struct xfs_mount	*mp = XFS_M(sb);
b83bd1388   Nathan Scott   [XFS] Resolve a n...
976
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977

e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
978
  	/*
34625c661   Christoph Hellwig   xfs: remove xfs_q...
979
  	 * Doing anything during the async pass would be counterproductive.
e893bffd4   Lachlan McIlroy   [XFS] avoid race ...
980
  	 */
34625c661   Christoph Hellwig   xfs: remove xfs_q...
981
  	if (!wait)
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
982
  		return 0;
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
983
984
985
986
  
  	error = xfs_quiesce_data(mp);
  	if (error)
  		return -error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
987

69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
988
  	if (laptop_mode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
990
991
992
993
  		/*
  		 * The disk must be active because we're syncing.
  		 * We schedule xfssyncd now (now that the disk is
  		 * active) instead of later (when it might not be).
  		 */
c6d09b666   Dave Chinner   xfs: introduce a ...
994
  		flush_delayed_work_sync(&mp->m_sync_work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
  	}
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
996
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
999
  }
  
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1000
  xfs_fs_statfs(
726c33422   David Howells   [PATCH] VFS: Perm...
1001
  	struct dentry		*dentry,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1002
1003
  	struct kstatfs		*statp)
  {
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1004
1005
  	struct xfs_mount	*mp = XFS_M(dentry->d_sb);
  	xfs_sb_t		*sbp = &mp->m_sb;
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
1006
  	struct xfs_inode	*ip = XFS_I(dentry->d_inode);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1007
1008
  	__uint64_t		fakeinos, id;
  	xfs_extlen_t		lsize;
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
1009
  	__int64_t		ffree;
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1010
1011
1012
1013
1014
1015
1016
  
  	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...
1017
  	xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1018
1019
1020
1021
1022
1023
1024
1025
  
  	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...
1026
1027
1028
  	statp->f_files =
  	    MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
  	if (mp->m_maxicount)
a19d9f887   Christoph Hellwig   xfs: kill ino64 m...
1029
1030
1031
  		statp->f_files = min_t(typeof(statp->f_files),
  					statp->f_files,
  					mp->m_maxicount);
2fe33661f   Stuart Brodsky   xfs: ensure f_ffr...
1032
1033
1034
1035
  
  	/* 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...
1036
  	spin_unlock(&mp->m_sb_lock);
7d095257e   Christoph Hellwig   xfs: kill xfs_qmops
1037
1038
1039
1040
  	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
  	    ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
  			      (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
  		xfs_qm_statvfs(ip, statp);
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1041
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
  }
d5db0f97f   Eric Sandeen   xfs: more reserve...
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
  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);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1066
  xfs_fs_remount(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1067
1068
1069
1070
  	struct super_block	*sb,
  	int			*flags,
  	char			*options)
  {
745f69191   Christoph Hellwig   [XFS] call common...
1071
  	struct xfs_mount	*mp = XFS_M(sb);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1072
1073
  	substring_t		args[MAX_OPT_ARGS];
  	char			*p;
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1074
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1075

62a877e35   Christoph Hellwig   [XFS] fix mount o...
1076
1077
  	while ((p = strsep(&options, ",")) != NULL) {
  		int token;
bdd907bab   Christoph Hellwig   [XFS] allow xfs_a...
1078

62a877e35   Christoph Hellwig   [XFS] fix mount o...
1079
1080
  		if (!*p)
  			continue;
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1081

62a877e35   Christoph Hellwig   [XFS] fix mount o...
1082
1083
1084
  		token = match_token(p, tokens, args);
  		switch (token) {
  		case Opt_barrier:
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1085
  			mp->m_flags |= XFS_MOUNT_BARRIER;
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1086
1087
  			break;
  		case Opt_nobarrier:
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1088
  			mp->m_flags &= ~XFS_MOUNT_BARRIER;
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1089
1090
  			break;
  		default:
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
  			/*
  			 * 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...
1108
1109
1110
  			xfs_info(mp,
  		"mount option \"%s\" not supported for remount
  ", p);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1111
  			return -EINVAL;
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1112
  #else
6c5e51dae   Christoph Hellwig   xfs: fix remount ...
1113
  			break;
6efdf2817   Christoph Hellwig   [XFS] Fix regress...
1114
  #endif
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1115
  		}
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1116
  	}
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1117
  	/* ro -> rw */
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1118
1119
  	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
  		mp->m_flags &= ~XFS_MOUNT_RDONLY;
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1120
1121
1122
1123
1124
1125
1126
1127
  
  		/*
  		 * 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...
1128
  				xfs_warn(mp, "failed to write sb changes");
7884bc861   Christoph Hellwig   xfs: fix bad_feat...
1129
1130
1131
1132
  				return error;
  			}
  			mp->m_update_flags = 0;
  		}
cbe132a8b   Dave Chinner   xfs: don't hold o...
1133
1134
1135
1136
1137
  
  		/*
  		 * 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...
1138
  		xfs_restore_resvblks(mp);
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1139
1140
1141
1142
  	}
  
  	/* rw -> ro */
  	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
cbe132a8b   Dave Chinner   xfs: don't hold o...
1143
1144
1145
1146
1147
1148
1149
1150
  		/*
  		 * After we have synced the data but 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...
1151

e9f1c6ee1   David Chinner   [XFS] make SYNC_D...
1152
  		xfs_quiesce_data(mp);
d5db0f97f   Eric Sandeen   xfs: more reserve...
1153
  		xfs_save_resvblks(mp);
76bf105cb   David Chinner   [XFS] Move remain...
1154
  		xfs_quiesce_attr(mp);
48b62a1a9   Christoph Hellwig   [XFS] merge xfs_m...
1155
1156
  		mp->m_flags |= XFS_MOUNT_RDONLY;
  	}
62a877e35   Christoph Hellwig   [XFS] fix mount o...
1157
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1158
  }
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1159
1160
  /*
   * Second stage of a freeze. The data is already frozen so we only
76bf105cb   David Chinner   [XFS] Move remain...
1161
   * need to take care of the metadata. Once that's done write a dummy
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1162
1163
   * record to dirty the log in case of a crash while frozen.
   */
c4be0c1dc   Takashi Sato   filesystem freeze...
1164
1165
  STATIC int
  xfs_fs_freeze(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166
1167
  	struct super_block	*sb)
  {
9909c4aa1   Christoph Hellwig   [XFS] kill xfs_fr...
1168
  	struct xfs_mount	*mp = XFS_M(sb);
d5db0f97f   Eric Sandeen   xfs: more reserve...
1169
  	xfs_save_resvblks(mp);
76bf105cb   David Chinner   [XFS] Move remain...
1170
  	xfs_quiesce_attr(mp);
c58efdb44   Dave Chinner   xfs: ensure log c...
1171
  	return -xfs_fs_log_dummy(mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1172
1173
1174
  }
  
  STATIC int
d5db0f97f   Eric Sandeen   xfs: more reserve...
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
  xfs_fs_unfreeze(
  	struct super_block	*sb)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	xfs_restore_resvblks(mp);
  	return 0;
  }
  
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1185
  xfs_fs_show_options(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
  	struct seq_file		*m,
34c80b1d9   Al Viro   vfs: switch ->sho...
1187
  	struct dentry		*root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
1189
  	return -xfs_showargs(XFS_M(root->d_sb), m);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1190
  }
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1191
1192
  /*
   * This function fills in xfs_mount_t fields based on mount args.
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1193
1194
1195
1196
   * Note: the superblock _has_ now been read in.
   */
  STATIC int
  xfs_finish_flags(
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1197
1198
1199
  	struct xfs_mount	*mp)
  {
  	int			ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
025dfdafe   Frederik Schwarzer   trivial: fix then...
1200
  	/* Fail a mount where the logbuf is smaller than the log stripe */
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1201
  	if (xfs_sb_version_haslogv2(&mp->m_sb)) {
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1202
1203
  		if (mp->m_logbsize <= 0 &&
  		    mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1204
  			mp->m_logbsize = mp->m_sb.sb_logsunit;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1205
1206
  		} else if (mp->m_logbsize > 0 &&
  			   mp->m_logbsize < mp->m_sb.sb_logsunit) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1207
1208
  			xfs_warn(mp,
  		"logbuf size must be greater than or equal to log stripe size");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1209
1210
1211
1212
  			return XFS_ERROR(EINVAL);
  		}
  	} else {
  		/* Fail a mount if the logbuf is larger than 32K */
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1213
  		if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) {
4f10700a2   Dave Chinner   xfs: Convert linu...
1214
1215
  			xfs_warn(mp,
  		"logbuf size for version 1 logs must be 16K or 32K");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1216
1217
1218
1219
1220
1221
1222
1223
1224
  			return XFS_ERROR(EINVAL);
  		}
  	}
  
  	/*
  	 * mkfs'ed attr2 will turn on attr2 mount unless explicitly
  	 * told by noattr2 to turn it off
  	 */
  	if (xfs_sb_version_hasattr2(&mp->m_sb) &&
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1225
  	    !(mp->m_flags & XFS_MOUNT_NOATTR2))
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1226
1227
1228
1229
1230
1231
  		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...
1232
1233
  		xfs_warn(mp,
  			"cannot mount a read-only filesystem as read-write");
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1234
1235
  		return XFS_ERROR(EROFS);
  	}
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1236
1237
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
  STATIC int
a50cd2692   Nathan Scott   [XFS] Switch over...
1239
  xfs_fs_fill_super(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
1241
1242
1243
  	struct super_block	*sb,
  	void			*data,
  	int			silent)
  {
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1244
  	struct inode		*root;
745f69191   Christoph Hellwig   [XFS] call common...
1245
  	struct xfs_mount	*mp = NULL;
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1246
  	int			flags = 0, error = ENOMEM;
bdd907bab   Christoph Hellwig   [XFS] allow xfs_a...
1247

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

c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1252
  	spin_lock_init(&mp->m_sb_lock);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1253
1254
  	mutex_init(&mp->m_growlock);
  	atomic_set(&mp->m_active_trans, 0);
743944967   Christoph Hellwig   [XFS] move syncin...
1255

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

288699fec   Christoph Hellwig   xfs: drop dmapi h...
1259
  	error = xfs_parseargs(mp, (char *)data);
745f69191   Christoph Hellwig   [XFS] call common...
1260
  	if (error)
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1261
  		goto out_free_fsname;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262
1263
  
  	sb_min_blocksize(sb, BBSIZE);
0ec585163   Lachlan McIlroy   [XFS] Use the gen...
1264
  	sb->s_xattr = xfs_xattr_handlers;
a50cd2692   Nathan Scott   [XFS] Switch over...
1265
  	sb->s_export_op = &xfs_export_operations;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1266
  #ifdef CONFIG_XFS_QUOTA
a50cd2692   Nathan Scott   [XFS] Switch over...
1267
  	sb->s_qcop = &xfs_quotactl_operations;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1268
  #endif
a50cd2692   Nathan Scott   [XFS] Switch over...
1269
  	sb->s_op = &xfs_super_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1270

9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1271
  	if (silent)
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1272
  		flags |= XFS_MFSI_QUIET;
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1273
  	error = xfs_open_devices(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1274
  	if (error)
288699fec   Christoph Hellwig   xfs: drop dmapi h...
1275
  		goto out_free_fsname;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1276

61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1277
1278
1279
  	error = xfs_icsb_init_counters(mp);
  	if (error)
  		goto out_close_devices;
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1280

f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1281
1282
  	error = xfs_readsb(mp, flags);
  	if (error)
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1283
1284
1285
  		goto out_destroy_counters;
  
  	error = xfs_finish_flags(mp);
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1286
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1287
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1288

e34b562c6   Christoph Hellwig   [XFS] add xfs_set...
1289
  	error = xfs_setup_devices(mp);
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1290
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1291
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1292

f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1293
1294
  	error = xfs_filestream_mount(mp);
  	if (error)
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1295
  		goto out_free_sb;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1296

704b2907c   Dave Chinner   xfs: register the...
1297
1298
1299
1300
1301
1302
1303
1304
  	/*
  	 * 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.
  	 * For the same reason we must also initialise the syncd and register
  	 * the inode cache shrinker so that inodes can be reclaimed during
  	 * operations like a quotacheck that iterate all inodes in the
  	 * filesystem.
  	 */
4ca488eb4   Christoph Hellwig   [XFS] Kill off xf...
1305
1306
1307
  	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
1308
1309
1310
  	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
  	sb->s_time_gran = 1;
  	set_posix_acl_flag(sb);
704b2907c   Dave Chinner   xfs: register the...
1311
1312
  	error = xfs_mountfs(mp);
  	if (error)
2bcf6e970   Christoph Hellwig   xfs: start period...
1313
1314
1315
1316
1317
  		goto out_filestream_unmount;
  
  	error = xfs_syncd_init(mp);
  	if (error)
  		goto out_unmount;
704b2907c   Dave Chinner   xfs: register the...
1318

016516462   David Chinner   [XFS] Avoid direc...
1319
  	root = igrab(VFS_I(mp->m_rootip));
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1320
  	if (!root) {
cbc89dcfd   Christoph Hellwig   [XFS] kill xfs_root
1321
  		error = ENOENT;
2bcf6e970   Christoph Hellwig   xfs: start period...
1322
  		goto out_syncd_stop;
cbc89dcfd   Christoph Hellwig   [XFS] kill xfs_root
1323
  	}
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1324
1325
  	if (is_bad_inode(root)) {
  		error = EINVAL;
2bcf6e970   Christoph Hellwig   xfs: start period...
1326
  		goto out_syncd_stop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
  	}
f3dcc13f6   Christoph Hellwig   [XFS] cleanup roo...
1328
1329
1330
  	sb->s_root = d_alloc_root(root);
  	if (!sb->s_root) {
  		error = ENOMEM;
2bcf6e970   Christoph Hellwig   xfs: start period...
1331
  		goto out_iput;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
  	}
743944967   Christoph Hellwig   [XFS] move syncin...
1333

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1334
  	return 0;
120226c11   Christoph Hellwig   [XFS] add missing...
1335
1336
   out_filestream_unmount:
  	xfs_filestream_unmount(mp);
effa2eda3   Christoph Hellwig   [XFS] rename erro...
1337
1338
   out_free_sb:
  	xfs_freesb(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1339
   out_destroy_counters:
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1340
  	xfs_icsb_destroy_counters(mp);
61ba35dea   Christoph Hellwig   xfs: remove XFS_M...
1341
   out_close_devices:
19f354d4c   Christoph Hellwig   [XFS] sort out op...
1342
  	xfs_close_devices(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1343
1344
   out_free_fsname:
  	xfs_free_fsname(mp);
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1345
  	kfree(mp);
9d565ffa3   Christoph Hellwig   [XFS] kill struct...
1346
   out:
c962fb790   Christoph Hellwig   [XFS] kill xfs_mo...
1347
  	return -error;
f8f15e42b   Christoph Hellwig   [XFS] merge xfs_m...
1348

2bcf6e970   Christoph Hellwig   xfs: start period...
1349
1350
1351
   out_iput:
  	iput(root);
   out_syncd_stop:
704b2907c   Dave Chinner   xfs: register the...
1352
  	xfs_syncd_stop(mp);
2bcf6e970   Christoph Hellwig   xfs: start period...
1353
   out_unmount:
e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
1354
1355
1356
1357
1358
1359
  	/*
  	 * Blow away any referenced inode in the filestreams cache.
  	 * This can and will cause log traffic as inodes go inactive
  	 * here.
  	 */
  	xfs_filestream_unmount(mp);
a9add83e5   Christoph Hellwig   xfs: remove XFS_b...
1360
  	xfs_flush_buftarg(mp->m_ddev_targp, 1);
e48ad3160   Christoph Hellwig   [XFS] merge xfs_u...
1361

19f354d4c   Christoph Hellwig   [XFS] sort out op...
1362
  	xfs_unmountfs(mp);
6203300e5   Christoph Hellwig   [XFS] don't call ...
1363
  	goto out_free_sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1364
  }
152a08366   Al Viro   new helper: mount...
1365
1366
  STATIC struct dentry *
  xfs_fs_mount(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
1368
1369
  	struct file_system_type	*fs_type,
  	int			flags,
  	const char		*dev_name,
152a08366   Al Viro   new helper: mount...
1370
  	void			*data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
  {
152a08366   Al Viro   new helper: mount...
1372
  	return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
a50cd2692   Nathan Scott   [XFS] Switch over...
1373
  }
8daaa8314   Dave Chinner   xfs: make use of ...
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
  static int
  xfs_fs_nr_cached_objects(
  	struct super_block	*sb)
  {
  	return xfs_reclaim_inodes_count(XFS_M(sb));
  }
  
  static void
  xfs_fs_free_cached_objects(
  	struct super_block	*sb,
  	int			nr_to_scan)
  {
  	xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan);
  }
b87221de6   Alexey Dobriyan   const: mark remai...
1388
  static const struct super_operations xfs_super_operations = {
a50cd2692   Nathan Scott   [XFS] Switch over...
1389
1390
  	.alloc_inode		= xfs_fs_alloc_inode,
  	.destroy_inode		= xfs_fs_destroy_inode,
f9581b144   Christoph Hellwig   xfs: implement ->...
1391
  	.dirty_inode		= xfs_fs_dirty_inode,
a50cd2692   Nathan Scott   [XFS] Switch over...
1392
  	.write_inode		= xfs_fs_write_inode,
b57922d97   Al Viro   convert remaining...
1393
  	.evict_inode		= xfs_fs_evict_inode,
a50cd2692   Nathan Scott   [XFS] Switch over...
1394
  	.put_super		= xfs_fs_put_super,
69961a26b   Christoph Hellwig   xfs: cleanup ->sy...
1395
  	.sync_fs		= xfs_fs_sync_fs,
c4be0c1dc   Takashi Sato   filesystem freeze...
1396
  	.freeze_fs		= xfs_fs_freeze,
d5db0f97f   Eric Sandeen   xfs: more reserve...
1397
  	.unfreeze_fs		= xfs_fs_unfreeze,
a50cd2692   Nathan Scott   [XFS] Switch over...
1398
1399
1400
  	.statfs			= xfs_fs_statfs,
  	.remount_fs		= xfs_fs_remount,
  	.show_options		= xfs_fs_show_options,
8daaa8314   Dave Chinner   xfs: make use of ...
1401
1402
  	.nr_cached_objects	= xfs_fs_nr_cached_objects,
  	.free_cached_objects	= xfs_fs_free_cached_objects,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
  };
5085b607f   Andrew Morton   [PATCH] xfs warni...
1404
  static struct file_system_type xfs_fs_type = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405
1406
  	.owner			= THIS_MODULE,
  	.name			= "xfs",
152a08366   Al Viro   new helper: mount...
1407
  	.mount			= xfs_fs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
1409
1410
  	.kill_sb		= kill_block_super,
  	.fs_flags		= FS_REQUIRES_DEV,
  };
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1411
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1412
1413
  xfs_init_zones(void)
  {
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1414
1415
1416
  
  	xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend");
  	if (!xfs_ioend_zone)
bf904248a   David Chinner   [XFS] Combine the...
1417
  		goto out;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
  
  	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...
1433

9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
  	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;
  
  	xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
  	if (!xfs_dabuf_zone)
  		goto out_destroy_da_state_zone;
  
  	xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
  	if (!xfs_ifork_zone)
  		goto out_destroy_dabuf_zone;
  
  	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...
1455
1456
1457
1458
1459
  	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 ...
1460
1461
1462
1463
1464
1465
  	/*
  	 * 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.
  	 */
  	xfs_buf_item_zone = kmem_zone_init((sizeof(xfs_buf_log_item_t) +
c11554104   Dave Chinner   xfs: Clean up XFS...
1466
  				(((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) /
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1467
1468
  				  NBWORD) * sizeof(int))), "xfs_buf_item");
  	if (!xfs_buf_item_zone)
e98c414f9   Christoph Hellwig   xfs: simplify log...
1469
  		goto out_destroy_log_item_desc_zone;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
  
  	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...
1485
1486
  			KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD,
  			xfs_fs_inode_init_once);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1487
1488
1489
1490
1491
1492
1493
1494
  	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;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1495
  	return 0;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1496
1497
1498
1499
1500
1501
1502
1503
   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...
1504
1505
   out_destroy_log_item_desc_zone:
  	kmem_zone_destroy(xfs_log_item_desc_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
   out_destroy_trans_zone:
  	kmem_zone_destroy(xfs_trans_zone);
   out_destroy_ifork_zone:
  	kmem_zone_destroy(xfs_ifork_zone);
   out_destroy_dabuf_zone:
  	kmem_zone_destroy(xfs_dabuf_zone);
   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 ...
1524
1525
1526
1527
1528
1529
1530
   out:
  	return -ENOMEM;
  }
  
  STATIC void
  xfs_destroy_zones(void)
  {
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1531
1532
1533
1534
1535
  	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...
1536
  	kmem_zone_destroy(xfs_log_item_desc_zone);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1537
1538
1539
1540
1541
1542
1543
1544
1545
  	kmem_zone_destroy(xfs_trans_zone);
  	kmem_zone_destroy(xfs_ifork_zone);
  	kmem_zone_destroy(xfs_dabuf_zone);
  	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 ...
1546
1547
  
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1548
1549
  
  STATIC int __init
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1550
1551
1552
  xfs_init_workqueues(void)
  {
  	/*
40d344ec5   Christoph Hellwig   xfs: mark the xfs...
1553
1554
1555
1556
  	 * We never want to the same work item to run twice, reclaiming inodes
  	 * or idling the log is not going to get any faster by multiple CPUs
  	 * competing for ressources.  Use the default large max_active value
  	 * so that even lots of filesystems can perform these task in parallel.
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1557
  	 */
40d344ec5   Christoph Hellwig   xfs: mark the xfs...
1558
  	xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0);
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1559
  	if (!xfs_syncd_wq)
0030807c6   Christoph Hellwig   xfs: revert to us...
1560
  		return -ENOMEM;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1561
  	return 0;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1562
  }
39411f81e   Tony Luck   xfs_destroy_workq...
1563
  STATIC void
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1564
1565
  xfs_destroy_workqueues(void)
  {
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1566
1567
1568
1569
  	destroy_workqueue(xfs_syncd_wq);
  }
  
  STATIC int __init
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1570
  init_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
1572
  {
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573

65795910c   Christoph Hellwig   [XFS] fix spuriou...
1574
1575
1576
  	printk(KERN_INFO XFS_VERSION_STRING " with "
  			 XFS_BUILD_OPTIONS " enabled
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577

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

8758280fc   Nathan Scott   [XFS] Cleanup the...
1580
  	error = xfs_init_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1581
1582
  	if (error)
  		goto out;
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1583
  	error = xfs_init_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1584
  	if (error)
0b1b213fc   Christoph Hellwig   xfs: event tracin...
1585
  		goto out_destroy_zones;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1586

0bf6a5bd4   Dave Chinner   xfs: convert the ...
1587
1588
1589
  	error = xfs_mru_cache_init();
  	if (error)
  		goto out_destroy_wq;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1590
1591
1592
  	error = xfs_filestream_init();
  	if (error)
  		goto out_mru_cache_uninit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1593

ce8e922c0   Nathan Scott   [XFS] Complete th...
1594
  	error = xfs_buf_init();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
  	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
1605

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1606
1607
1608
1609
  	vfs_initquota();
  
  	error = register_filesystem(&xfs_fs_type);
  	if (error)
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1610
  		goto out_sysctl_unregister;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
  	return 0;
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1612
1613
1614
1615
1616
   out_sysctl_unregister:
  	xfs_sysctl_unregister();
   out_cleanup_procfs:
  	xfs_cleanup_procfs();
   out_buf_terminate:
ce8e922c0   Nathan Scott   [XFS] Complete th...
1617
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1618
1619
1620
1621
   out_filestream_uninit:
  	xfs_filestream_uninit();
   out_mru_cache_uninit:
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1622
1623
   out_destroy_wq:
  	xfs_destroy_workqueues();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1624
   out_destroy_zones:
8758280fc   Nathan Scott   [XFS] Cleanup the...
1625
  	xfs_destroy_zones();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1626
   out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627
1628
1629
1630
  	return error;
  }
  
  STATIC void __exit
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1631
  exit_xfs_fs(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
1633
  {
  	vfs_exitquota();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1634
  	unregister_filesystem(&xfs_fs_type);
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1635
1636
  	xfs_sysctl_unregister();
  	xfs_cleanup_procfs();
ce8e922c0   Nathan Scott   [XFS] Complete th...
1637
  	xfs_buf_terminate();
9f8868ffb   Christoph Hellwig   [XFS] streamline ...
1638
1639
  	xfs_filestream_uninit();
  	xfs_mru_cache_uninit();
0bf6a5bd4   Dave Chinner   xfs: convert the ...
1640
  	xfs_destroy_workqueues();
8758280fc   Nathan Scott   [XFS] Cleanup the...
1641
  	xfs_destroy_zones();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1642
1643
1644
1645
1646
1647
1648
1649
  }
  
  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");