diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_super.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 884 |
1 files changed, 300 insertions, 584 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 37ebe36056eb..36f6cc703ef2 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "xfs.h" | 18 | #include "xfs.h" |
19 | #include "xfs_bit.h" | 19 | #include "xfs_bit.h" |
20 | #include "xfs_log.h" | 20 | #include "xfs_log.h" |
21 | #include "xfs_clnt.h" | ||
22 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 22 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
@@ -36,6 +35,7 @@ | |||
36 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
37 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
38 | #include "xfs_btree.h" | 37 | #include "xfs_btree.h" |
38 | #include "xfs_btree_trace.h" | ||
39 | #include "xfs_ialloc.h" | 39 | #include "xfs_ialloc.h" |
40 | #include "xfs_bmap.h" | 40 | #include "xfs_bmap.h" |
41 | #include "xfs_rtalloc.h" | 41 | #include "xfs_rtalloc.h" |
@@ -48,7 +48,6 @@ | |||
48 | #include "xfs_buf_item.h" | 48 | #include "xfs_buf_item.h" |
49 | #include "xfs_utils.h" | 49 | #include "xfs_utils.h" |
50 | #include "xfs_vnodeops.h" | 50 | #include "xfs_vnodeops.h" |
51 | #include "xfs_vfsops.h" | ||
52 | #include "xfs_version.h" | 51 | #include "xfs_version.h" |
53 | #include "xfs_log_priv.h" | 52 | #include "xfs_log_priv.h" |
54 | #include "xfs_trans_priv.h" | 53 | #include "xfs_trans_priv.h" |
@@ -58,6 +57,7 @@ | |||
58 | #include "xfs_extfree_item.h" | 57 | #include "xfs_extfree_item.h" |
59 | #include "xfs_mru_cache.h" | 58 | #include "xfs_mru_cache.h" |
60 | #include "xfs_inode_item.h" | 59 | #include "xfs_inode_item.h" |
60 | #include "xfs_sync.h" | ||
61 | 61 | ||
62 | #include <linux/namei.h> | 62 | #include <linux/namei.h> |
63 | #include <linux/init.h> | 63 | #include <linux/init.h> |
@@ -70,36 +70,9 @@ | |||
70 | 70 | ||
71 | static struct quotactl_ops xfs_quotactl_operations; | 71 | static struct quotactl_ops xfs_quotactl_operations; |
72 | static struct super_operations xfs_super_operations; | 72 | static struct super_operations xfs_super_operations; |
73 | static kmem_zone_t *xfs_vnode_zone; | ||
74 | static kmem_zone_t *xfs_ioend_zone; | 73 | static kmem_zone_t *xfs_ioend_zone; |
75 | mempool_t *xfs_ioend_pool; | 74 | mempool_t *xfs_ioend_pool; |
76 | 75 | ||
77 | STATIC struct xfs_mount_args * | ||
78 | xfs_args_allocate( | ||
79 | struct super_block *sb, | ||
80 | int silent) | ||
81 | { | ||
82 | struct xfs_mount_args *args; | ||
83 | |||
84 | args = kzalloc(sizeof(struct xfs_mount_args), GFP_KERNEL); | ||
85 | if (!args) | ||
86 | return NULL; | ||
87 | |||
88 | args->logbufs = args->logbufsize = -1; | ||
89 | strncpy(args->fsname, sb->s_id, MAXNAMELEN); | ||
90 | |||
91 | /* Copy the already-parsed mount(2) flags we're interested in */ | ||
92 | if (sb->s_flags & MS_DIRSYNC) | ||
93 | args->flags |= XFSMNT_DIRSYNC; | ||
94 | if (sb->s_flags & MS_SYNCHRONOUS) | ||
95 | args->flags |= XFSMNT_WSYNC; | ||
96 | if (silent) | ||
97 | args->flags |= XFSMNT_QUIET; | ||
98 | args->flags |= XFSMNT_32BITINODES; | ||
99 | |||
100 | return args; | ||
101 | } | ||
102 | |||
103 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | 76 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ |
104 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | 77 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ |
105 | #define MNTOPT_LOGDEV "logdev" /* log device */ | 78 | #define MNTOPT_LOGDEV "logdev" /* log device */ |
@@ -188,26 +161,54 @@ suffix_strtoul(char *s, char **endp, unsigned int base) | |||
188 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; | 161 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; |
189 | } | 162 | } |
190 | 163 | ||
164 | /* | ||
165 | * This function fills in xfs_mount_t fields based on mount args. | ||
166 | * Note: the superblock has _not_ yet been read in. | ||
167 | * | ||
168 | * Note that this function leaks the various device name allocations on | ||
169 | * failure. The caller takes care of them. | ||
170 | */ | ||
191 | STATIC int | 171 | STATIC int |
192 | xfs_parseargs( | 172 | xfs_parseargs( |
193 | struct xfs_mount *mp, | 173 | struct xfs_mount *mp, |
194 | char *options, | 174 | char *options, |
195 | struct xfs_mount_args *args, | 175 | char **mtpt) |
196 | int update) | ||
197 | { | 176 | { |
177 | struct super_block *sb = mp->m_super; | ||
198 | char *this_char, *value, *eov; | 178 | char *this_char, *value, *eov; |
199 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | 179 | int dsunit = 0; |
200 | int iosize; | 180 | int dswidth = 0; |
181 | int iosize = 0; | ||
201 | int dmapi_implies_ikeep = 1; | 182 | int dmapi_implies_ikeep = 1; |
183 | uchar_t iosizelog = 0; | ||
184 | |||
185 | /* | ||
186 | * Copy binary VFS mount flags we are interested in. | ||
187 | */ | ||
188 | if (sb->s_flags & MS_RDONLY) | ||
189 | mp->m_flags |= XFS_MOUNT_RDONLY; | ||
190 | if (sb->s_flags & MS_DIRSYNC) | ||
191 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | ||
192 | if (sb->s_flags & MS_SYNCHRONOUS) | ||
193 | mp->m_flags |= XFS_MOUNT_WSYNC; | ||
194 | |||
195 | /* | ||
196 | * Set some default flags that could be cleared by the mount option | ||
197 | * parsing. | ||
198 | */ | ||
199 | mp->m_flags |= XFS_MOUNT_BARRIER; | ||
200 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | ||
201 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | ||
202 | 202 | ||
203 | args->flags |= XFSMNT_BARRIER; | 203 | /* |
204 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | 204 | * These can be overridden by the mount option parsing. |
205 | */ | ||
206 | mp->m_logbufs = -1; | ||
207 | mp->m_logbsize = -1; | ||
205 | 208 | ||
206 | if (!options) | 209 | if (!options) |
207 | goto done; | 210 | goto done; |
208 | 211 | ||
209 | iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0; | ||
210 | |||
211 | while ((this_char = strsep(&options, ",")) != NULL) { | 212 | while ((this_char = strsep(&options, ",")) != NULL) { |
212 | if (!*this_char) | 213 | if (!*this_char) |
213 | continue; | 214 | continue; |
@@ -221,7 +222,7 @@ xfs_parseargs( | |||
221 | this_char); | 222 | this_char); |
222 | return EINVAL; | 223 | return EINVAL; |
223 | } | 224 | } |
224 | args->logbufs = simple_strtoul(value, &eov, 10); | 225 | mp->m_logbufs = simple_strtoul(value, &eov, 10); |
225 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | 226 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { |
226 | if (!value || !*value) { | 227 | if (!value || !*value) { |
227 | cmn_err(CE_WARN, | 228 | cmn_err(CE_WARN, |
@@ -229,7 +230,7 @@ xfs_parseargs( | |||
229 | this_char); | 230 | this_char); |
230 | return EINVAL; | 231 | return EINVAL; |
231 | } | 232 | } |
232 | args->logbufsize = suffix_strtoul(value, &eov, 10); | 233 | mp->m_logbsize = suffix_strtoul(value, &eov, 10); |
233 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 234 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { |
234 | if (!value || !*value) { | 235 | if (!value || !*value) { |
235 | cmn_err(CE_WARN, | 236 | cmn_err(CE_WARN, |
@@ -237,7 +238,9 @@ xfs_parseargs( | |||
237 | this_char); | 238 | this_char); |
238 | return EINVAL; | 239 | return EINVAL; |
239 | } | 240 | } |
240 | strncpy(args->logname, value, MAXNAMELEN); | 241 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
242 | if (!mp->m_logname) | ||
243 | return ENOMEM; | ||
241 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 244 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
242 | if (!value || !*value) { | 245 | if (!value || !*value) { |
243 | cmn_err(CE_WARN, | 246 | cmn_err(CE_WARN, |
@@ -245,7 +248,9 @@ xfs_parseargs( | |||
245 | this_char); | 248 | this_char); |
246 | return EINVAL; | 249 | return EINVAL; |
247 | } | 250 | } |
248 | strncpy(args->mtpt, value, MAXNAMELEN); | 251 | *mtpt = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
252 | if (!*mtpt) | ||
253 | return ENOMEM; | ||
249 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 254 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
250 | if (!value || !*value) { | 255 | if (!value || !*value) { |
251 | cmn_err(CE_WARN, | 256 | cmn_err(CE_WARN, |
@@ -253,7 +258,9 @@ xfs_parseargs( | |||
253 | this_char); | 258 | this_char); |
254 | return EINVAL; | 259 | return EINVAL; |
255 | } | 260 | } |
256 | strncpy(args->rtname, value, MAXNAMELEN); | 261 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
262 | if (!mp->m_rtname) | ||
263 | return ENOMEM; | ||
257 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | 264 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { |
258 | if (!value || !*value) { | 265 | if (!value || !*value) { |
259 | cmn_err(CE_WARN, | 266 | cmn_err(CE_WARN, |
@@ -262,8 +269,7 @@ xfs_parseargs( | |||
262 | return EINVAL; | 269 | return EINVAL; |
263 | } | 270 | } |
264 | iosize = simple_strtoul(value, &eov, 10); | 271 | iosize = simple_strtoul(value, &eov, 10); |
265 | args->flags |= XFSMNT_IOSIZE; | 272 | iosizelog = ffs(iosize) - 1; |
266 | args->iosizelog = (uint8_t) iosize; | ||
267 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | 273 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { |
268 | if (!value || !*value) { | 274 | if (!value || !*value) { |
269 | cmn_err(CE_WARN, | 275 | cmn_err(CE_WARN, |
@@ -272,8 +278,7 @@ xfs_parseargs( | |||
272 | return EINVAL; | 278 | return EINVAL; |
273 | } | 279 | } |
274 | iosize = suffix_strtoul(value, &eov, 10); | 280 | iosize = suffix_strtoul(value, &eov, 10); |
275 | args->flags |= XFSMNT_IOSIZE; | 281 | iosizelog = ffs(iosize) - 1; |
276 | args->iosizelog = ffs(iosize) - 1; | ||
277 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | 282 | } else if (!strcmp(this_char, MNTOPT_GRPID) || |
278 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | 283 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { |
279 | mp->m_flags |= XFS_MOUNT_GRPID; | 284 | mp->m_flags |= XFS_MOUNT_GRPID; |
@@ -281,23 +286,25 @@ xfs_parseargs( | |||
281 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | 286 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { |
282 | mp->m_flags &= ~XFS_MOUNT_GRPID; | 287 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
283 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 288 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { |
284 | args->flags |= XFSMNT_WSYNC; | 289 | mp->m_flags |= XFS_MOUNT_WSYNC; |
285 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { | 290 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { |
286 | args->flags |= XFSMNT_OSYNCISOSYNC; | 291 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; |
287 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | 292 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { |
288 | args->flags |= XFSMNT_NORECOVERY; | 293 | mp->m_flags |= XFS_MOUNT_NORECOVERY; |
289 | } else if (!strcmp(this_char, MNTOPT_INO64)) { | 294 | } else if (!strcmp(this_char, MNTOPT_INO64)) { |
290 | args->flags |= XFSMNT_INO64; | 295 | #if XFS_BIG_INUMS |
291 | #if !XFS_BIG_INUMS | 296 | mp->m_flags |= XFS_MOUNT_INO64; |
297 | mp->m_inoadd = XFS_INO64_OFFSET; | ||
298 | #else | ||
292 | cmn_err(CE_WARN, | 299 | cmn_err(CE_WARN, |
293 | "XFS: %s option not allowed on this system", | 300 | "XFS: %s option not allowed on this system", |
294 | this_char); | 301 | this_char); |
295 | return EINVAL; | 302 | return EINVAL; |
296 | #endif | 303 | #endif |
297 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 304 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { |
298 | args->flags |= XFSMNT_NOALIGN; | 305 | mp->m_flags |= XFS_MOUNT_NOALIGN; |
299 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | 306 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { |
300 | args->flags |= XFSMNT_SWALLOC; | 307 | mp->m_flags |= XFS_MOUNT_SWALLOC; |
301 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 308 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { |
302 | if (!value || !*value) { | 309 | if (!value || !*value) { |
303 | cmn_err(CE_WARN, | 310 | cmn_err(CE_WARN, |
@@ -315,7 +322,7 @@ xfs_parseargs( | |||
315 | } | 322 | } |
316 | dswidth = simple_strtoul(value, &eov, 10); | 323 | dswidth = simple_strtoul(value, &eov, 10); |
317 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 324 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { |
318 | args->flags &= ~XFSMNT_32BITINODES; | 325 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
319 | #if !XFS_BIG_INUMS | 326 | #if !XFS_BIG_INUMS |
320 | cmn_err(CE_WARN, | 327 | cmn_err(CE_WARN, |
321 | "XFS: %s option not allowed on this system", | 328 | "XFS: %s option not allowed on this system", |
@@ -323,56 +330,61 @@ xfs_parseargs( | |||
323 | return EINVAL; | 330 | return EINVAL; |
324 | #endif | 331 | #endif |
325 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 332 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { |
326 | args->flags |= XFSMNT_NOUUID; | 333 | mp->m_flags |= XFS_MOUNT_NOUUID; |
327 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | 334 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { |
328 | args->flags |= XFSMNT_BARRIER; | 335 | mp->m_flags |= XFS_MOUNT_BARRIER; |
329 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 336 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { |
330 | args->flags &= ~XFSMNT_BARRIER; | 337 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
331 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 338 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
332 | args->flags |= XFSMNT_IKEEP; | 339 | mp->m_flags |= XFS_MOUNT_IKEEP; |
333 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 340 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
334 | dmapi_implies_ikeep = 0; | 341 | dmapi_implies_ikeep = 0; |
335 | args->flags &= ~XFSMNT_IKEEP; | 342 | mp->m_flags &= ~XFS_MOUNT_IKEEP; |
336 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 343 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { |
337 | args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; | 344 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
338 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | 345 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { |
339 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | 346 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
340 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | 347 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { |
341 | args->flags |= XFSMNT_ATTR2; | 348 | mp->m_flags |= XFS_MOUNT_ATTR2; |
342 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 349 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { |
343 | args->flags &= ~XFSMNT_ATTR2; | 350 | mp->m_flags &= ~XFS_MOUNT_ATTR2; |
344 | args->flags |= XFSMNT_NOATTR2; | 351 | mp->m_flags |= XFS_MOUNT_NOATTR2; |
345 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | 352 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { |
346 | args->flags2 |= XFSMNT2_FILESTREAMS; | 353 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
347 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | 354 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { |
348 | args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); | 355 | mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
349 | args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); | 356 | XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
357 | XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | | ||
358 | XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD); | ||
350 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | 359 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || |
351 | !strcmp(this_char, MNTOPT_UQUOTA) || | 360 | !strcmp(this_char, MNTOPT_UQUOTA) || |
352 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | 361 | !strcmp(this_char, MNTOPT_USRQUOTA)) { |
353 | args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; | 362 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
363 | XFS_UQUOTA_ENFD); | ||
354 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | 364 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || |
355 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | 365 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { |
356 | args->flags |= XFSMNT_UQUOTA; | 366 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
357 | args->flags &= ~XFSMNT_UQUOTAENF; | 367 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
358 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | 368 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || |
359 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | 369 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { |
360 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | 370 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
371 | XFS_OQUOTA_ENFD); | ||
361 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | 372 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { |
362 | args->flags |= XFSMNT_PQUOTA; | 373 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
363 | args->flags &= ~XFSMNT_PQUOTAENF; | 374 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
364 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 375 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || |
365 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 376 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { |
366 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | 377 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
378 | XFS_OQUOTA_ENFD); | ||
367 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | 379 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { |
368 | args->flags |= XFSMNT_GQUOTA; | 380 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
369 | args->flags &= ~XFSMNT_GQUOTAENF; | 381 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
370 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { | 382 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { |
371 | args->flags |= XFSMNT_DMAPI; | 383 | mp->m_flags |= XFS_MOUNT_DMAPI; |
372 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { | 384 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { |
373 | args->flags |= XFSMNT_DMAPI; | 385 | mp->m_flags |= XFS_MOUNT_DMAPI; |
374 | } else if (!strcmp(this_char, MNTOPT_DMI)) { | 386 | } else if (!strcmp(this_char, MNTOPT_DMI)) { |
375 | args->flags |= XFSMNT_DMAPI; | 387 | mp->m_flags |= XFS_MOUNT_DMAPI; |
376 | } else if (!strcmp(this_char, "ihashsize")) { | 388 | } else if (!strcmp(this_char, "ihashsize")) { |
377 | cmn_err(CE_WARN, | 389 | cmn_err(CE_WARN, |
378 | "XFS: ihashsize no longer used, option is deprecated."); | 390 | "XFS: ihashsize no longer used, option is deprecated."); |
@@ -390,27 +402,29 @@ xfs_parseargs( | |||
390 | } | 402 | } |
391 | } | 403 | } |
392 | 404 | ||
393 | if (args->flags & XFSMNT_NORECOVERY) { | 405 | /* |
394 | if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) { | 406 | * no recovery flag requires a read-only mount |
395 | cmn_err(CE_WARN, | 407 | */ |
396 | "XFS: no-recovery mounts must be read-only."); | 408 | if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && |
397 | return EINVAL; | 409 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
398 | } | 410 | cmn_err(CE_WARN, "XFS: no-recovery mounts must be read-only."); |
411 | return EINVAL; | ||
399 | } | 412 | } |
400 | 413 | ||
401 | if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { | 414 | if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { |
402 | cmn_err(CE_WARN, | 415 | cmn_err(CE_WARN, |
403 | "XFS: sunit and swidth options incompatible with the noalign option"); | 416 | "XFS: sunit and swidth options incompatible with the noalign option"); |
404 | return EINVAL; | 417 | return EINVAL; |
405 | } | 418 | } |
406 | 419 | ||
407 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | 420 | if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && |
421 | (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { | ||
408 | cmn_err(CE_WARN, | 422 | cmn_err(CE_WARN, |
409 | "XFS: cannot mount with both project and group quota"); | 423 | "XFS: cannot mount with both project and group quota"); |
410 | return EINVAL; | 424 | return EINVAL; |
411 | } | 425 | } |
412 | 426 | ||
413 | if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { | 427 | if ((mp->m_flags & XFS_MOUNT_DMAPI) && (!*mtpt || *mtpt[0] == '\0')) { |
414 | printk("XFS: %s option needs the mount point option as well\n", | 428 | printk("XFS: %s option needs the mount point option as well\n", |
415 | MNTOPT_DMAPI); | 429 | MNTOPT_DMAPI); |
416 | return EINVAL; | 430 | return EINVAL; |
@@ -438,27 +452,66 @@ xfs_parseargs( | |||
438 | * Note that if "ikeep" or "noikeep" mount options are | 452 | * Note that if "ikeep" or "noikeep" mount options are |
439 | * supplied, then they are honored. | 453 | * supplied, then they are honored. |
440 | */ | 454 | */ |
441 | if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) | 455 | if ((mp->m_flags & XFS_MOUNT_DMAPI) && dmapi_implies_ikeep) |
442 | args->flags |= XFSMNT_IKEEP; | 456 | mp->m_flags |= XFS_MOUNT_IKEEP; |
443 | 457 | ||
444 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | 458 | done: |
459 | if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) { | ||
460 | /* | ||
461 | * At this point the superblock has not been read | ||
462 | * in, therefore we do not know the block size. | ||
463 | * Before the mount call ends we will convert | ||
464 | * these to FSBs. | ||
465 | */ | ||
445 | if (dsunit) { | 466 | if (dsunit) { |
446 | args->sunit = dsunit; | 467 | mp->m_dalign = dsunit; |
447 | args->flags |= XFSMNT_RETERR; | 468 | mp->m_flags |= XFS_MOUNT_RETERR; |
448 | } else { | ||
449 | args->sunit = vol_dsunit; | ||
450 | } | 469 | } |
451 | dswidth ? (args->swidth = dswidth) : | 470 | |
452 | (args->swidth = vol_dswidth); | 471 | if (dswidth) |
453 | } else { | 472 | mp->m_swidth = dswidth; |
454 | args->sunit = args->swidth = 0; | 473 | } |
474 | |||
475 | if (mp->m_logbufs != -1 && | ||
476 | mp->m_logbufs != 0 && | ||
477 | (mp->m_logbufs < XLOG_MIN_ICLOGS || | ||
478 | mp->m_logbufs > XLOG_MAX_ICLOGS)) { | ||
479 | cmn_err(CE_WARN, | ||
480 | "XFS: invalid logbufs value: %d [not %d-%d]", | ||
481 | mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | ||
482 | return XFS_ERROR(EINVAL); | ||
483 | } | ||
484 | if (mp->m_logbsize != -1 && | ||
485 | mp->m_logbsize != 0 && | ||
486 | (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || | ||
487 | mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || | ||
488 | !is_power_of_2(mp->m_logbsize))) { | ||
489 | cmn_err(CE_WARN, | ||
490 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | ||
491 | mp->m_logbsize); | ||
492 | return XFS_ERROR(EINVAL); | ||
493 | } | ||
494 | |||
495 | mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); | ||
496 | if (!mp->m_fsname) | ||
497 | return ENOMEM; | ||
498 | mp->m_fsname_len = strlen(mp->m_fsname) + 1; | ||
499 | |||
500 | if (iosizelog) { | ||
501 | if (iosizelog > XFS_MAX_IO_LOG || | ||
502 | iosizelog < XFS_MIN_IO_LOG) { | ||
503 | cmn_err(CE_WARN, | ||
504 | "XFS: invalid log iosize: %d [not %d-%d]", | ||
505 | iosizelog, XFS_MIN_IO_LOG, | ||
506 | XFS_MAX_IO_LOG); | ||
507 | return XFS_ERROR(EINVAL); | ||
508 | } | ||
509 | |||
510 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | ||
511 | mp->m_readio_log = iosizelog; | ||
512 | mp->m_writeio_log = iosizelog; | ||
455 | } | 513 | } |
456 | 514 | ||
457 | done: | ||
458 | if (args->flags & XFSMNT_32BITINODES) | ||
459 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | ||
460 | if (args->flags2) | ||
461 | args->flags |= XFSMNT_FLAGS2; | ||
462 | return 0; | 515 | return 0; |
463 | } | 516 | } |
464 | 517 | ||
@@ -704,8 +757,7 @@ xfs_close_devices( | |||
704 | */ | 757 | */ |
705 | STATIC int | 758 | STATIC int |
706 | xfs_open_devices( | 759 | xfs_open_devices( |
707 | struct xfs_mount *mp, | 760 | struct xfs_mount *mp) |
708 | struct xfs_mount_args *args) | ||
709 | { | 761 | { |
710 | struct block_device *ddev = mp->m_super->s_bdev; | 762 | struct block_device *ddev = mp->m_super->s_bdev; |
711 | struct block_device *logdev = NULL, *rtdev = NULL; | 763 | struct block_device *logdev = NULL, *rtdev = NULL; |
@@ -714,14 +766,14 @@ xfs_open_devices( | |||
714 | /* | 766 | /* |
715 | * Open real time and log devices - order is important. | 767 | * Open real time and log devices - order is important. |
716 | */ | 768 | */ |
717 | if (args->logname[0]) { | 769 | if (mp->m_logname) { |
718 | error = xfs_blkdev_get(mp, args->logname, &logdev); | 770 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); |
719 | if (error) | 771 | if (error) |
720 | goto out; | 772 | goto out; |
721 | } | 773 | } |
722 | 774 | ||
723 | if (args->rtname[0]) { | 775 | if (mp->m_rtname) { |
724 | error = xfs_blkdev_get(mp, args->rtname, &rtdev); | 776 | error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev); |
725 | if (error) | 777 | if (error) |
726 | goto out_close_logdev; | 778 | goto out_close_logdev; |
727 | 779 | ||
@@ -813,18 +865,18 @@ xfs_setup_devices( | |||
813 | */ | 865 | */ |
814 | void | 866 | void |
815 | xfsaild_wakeup( | 867 | xfsaild_wakeup( |
816 | xfs_mount_t *mp, | 868 | struct xfs_ail *ailp, |
817 | xfs_lsn_t threshold_lsn) | 869 | xfs_lsn_t threshold_lsn) |
818 | { | 870 | { |
819 | mp->m_ail.xa_target = threshold_lsn; | 871 | ailp->xa_target = threshold_lsn; |
820 | wake_up_process(mp->m_ail.xa_task); | 872 | wake_up_process(ailp->xa_task); |
821 | } | 873 | } |
822 | 874 | ||
823 | int | 875 | int |
824 | xfsaild( | 876 | xfsaild( |
825 | void *data) | 877 | void *data) |
826 | { | 878 | { |
827 | xfs_mount_t *mp = (xfs_mount_t *)data; | 879 | struct xfs_ail *ailp = data; |
828 | xfs_lsn_t last_pushed_lsn = 0; | 880 | xfs_lsn_t last_pushed_lsn = 0; |
829 | long tout = 0; | 881 | long tout = 0; |
830 | 882 | ||
@@ -836,11 +888,11 @@ xfsaild( | |||
836 | /* swsusp */ | 888 | /* swsusp */ |
837 | try_to_freeze(); | 889 | try_to_freeze(); |
838 | 890 | ||
839 | ASSERT(mp->m_log); | 891 | ASSERT(ailp->xa_mount->m_log); |
840 | if (XFS_FORCED_SHUTDOWN(mp)) | 892 | if (XFS_FORCED_SHUTDOWN(ailp->xa_mount)) |
841 | continue; | 893 | continue; |
842 | 894 | ||
843 | tout = xfsaild_push(mp, &last_pushed_lsn); | 895 | tout = xfsaild_push(ailp, &last_pushed_lsn); |
844 | } | 896 | } |
845 | 897 | ||
846 | return 0; | 898 | return 0; |
@@ -848,43 +900,82 @@ xfsaild( | |||
848 | 900 | ||
849 | int | 901 | int |
850 | xfsaild_start( | 902 | xfsaild_start( |
851 | xfs_mount_t *mp) | 903 | struct xfs_ail *ailp) |
852 | { | 904 | { |
853 | mp->m_ail.xa_target = 0; | 905 | ailp->xa_target = 0; |
854 | mp->m_ail.xa_task = kthread_run(xfsaild, mp, "xfsaild"); | 906 | ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild"); |
855 | if (IS_ERR(mp->m_ail.xa_task)) | 907 | if (IS_ERR(ailp->xa_task)) |
856 | return -PTR_ERR(mp->m_ail.xa_task); | 908 | return -PTR_ERR(ailp->xa_task); |
857 | return 0; | 909 | return 0; |
858 | } | 910 | } |
859 | 911 | ||
860 | void | 912 | void |
861 | xfsaild_stop( | 913 | xfsaild_stop( |
862 | xfs_mount_t *mp) | 914 | struct xfs_ail *ailp) |
863 | { | 915 | { |
864 | kthread_stop(mp->m_ail.xa_task); | 916 | kthread_stop(ailp->xa_task); |
865 | } | 917 | } |
866 | 918 | ||
867 | 919 | ||
868 | 920 | /* Catch misguided souls that try to use this interface on XFS */ | |
869 | STATIC struct inode * | 921 | STATIC struct inode * |
870 | xfs_fs_alloc_inode( | 922 | xfs_fs_alloc_inode( |
871 | struct super_block *sb) | 923 | struct super_block *sb) |
872 | { | 924 | { |
873 | return kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); | 925 | BUG(); |
926 | return NULL; | ||
874 | } | 927 | } |
875 | 928 | ||
929 | /* | ||
930 | * Now that the generic code is guaranteed not to be accessing | ||
931 | * the linux inode, we can reclaim the inode. | ||
932 | */ | ||
876 | STATIC void | 933 | STATIC void |
877 | xfs_fs_destroy_inode( | 934 | xfs_fs_destroy_inode( |
878 | struct inode *inode) | 935 | struct inode *inode) |
879 | { | 936 | { |
880 | kmem_zone_free(xfs_vnode_zone, inode); | 937 | xfs_inode_t *ip = XFS_I(inode); |
938 | |||
939 | XFS_STATS_INC(vn_reclaim); | ||
940 | if (xfs_reclaim(ip)) | ||
941 | panic("%s: cannot reclaim 0x%p\n", __func__, inode); | ||
881 | } | 942 | } |
882 | 943 | ||
944 | /* | ||
945 | * Slab object creation initialisation for the XFS inode. | ||
946 | * This covers only the idempotent fields in the XFS inode; | ||
947 | * all other fields need to be initialised on allocation | ||
948 | * from the slab. This avoids the need to repeatedly intialise | ||
949 | * fields in the xfs inode that left in the initialise state | ||
950 | * when freeing the inode. | ||
951 | */ | ||
883 | STATIC void | 952 | STATIC void |
884 | xfs_fs_inode_init_once( | 953 | xfs_fs_inode_init_once( |
885 | void *vnode) | 954 | void *inode) |
886 | { | 955 | { |
887 | inode_init_once((struct inode *)vnode); | 956 | struct xfs_inode *ip = inode; |
957 | |||
958 | memset(ip, 0, sizeof(struct xfs_inode)); | ||
959 | |||
960 | /* vfs inode */ | ||
961 | inode_init_once(VFS_I(ip)); | ||
962 | |||
963 | /* xfs inode */ | ||
964 | atomic_set(&ip->i_iocount, 0); | ||
965 | atomic_set(&ip->i_pincount, 0); | ||
966 | spin_lock_init(&ip->i_flags_lock); | ||
967 | init_waitqueue_head(&ip->i_ipin_wait); | ||
968 | /* | ||
969 | * Because we want to use a counting completion, complete | ||
970 | * the flush completion once to allow a single access to | ||
971 | * the flush completion without blocking. | ||
972 | */ | ||
973 | init_completion(&ip->i_flush); | ||
974 | complete(&ip->i_flush); | ||
975 | |||
976 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | ||
977 | "xfsino", ip->i_ino); | ||
978 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
888 | } | 979 | } |
889 | 980 | ||
890 | /* | 981 | /* |
@@ -898,21 +989,26 @@ xfs_fs_write_inode( | |||
898 | struct inode *inode, | 989 | struct inode *inode, |
899 | int sync) | 990 | int sync) |
900 | { | 991 | { |
992 | struct xfs_inode *ip = XFS_I(inode); | ||
901 | int error = 0; | 993 | int error = 0; |
902 | int flags = 0; | 994 | int flags = 0; |
903 | 995 | ||
904 | xfs_itrace_entry(XFS_I(inode)); | 996 | xfs_itrace_entry(ip); |
905 | if (sync) { | 997 | if (sync) { |
906 | filemap_fdatawait(inode->i_mapping); | 998 | error = xfs_wait_on_pages(ip, 0, -1); |
999 | if (error) | ||
1000 | goto out_error; | ||
907 | flags |= FLUSH_SYNC; | 1001 | flags |= FLUSH_SYNC; |
908 | } | 1002 | } |
909 | error = xfs_inode_flush(XFS_I(inode), flags); | 1003 | error = xfs_inode_flush(ip, flags); |
1004 | |||
1005 | out_error: | ||
910 | /* | 1006 | /* |
911 | * if we failed to write out the inode then mark | 1007 | * if we failed to write out the inode then mark |
912 | * it dirty again so we'll try again later. | 1008 | * it dirty again so we'll try again later. |
913 | */ | 1009 | */ |
914 | if (error) | 1010 | if (error) |
915 | mark_inode_dirty_sync(inode); | 1011 | xfs_mark_inode_dirty_sync(ip); |
916 | 1012 | ||
917 | return -error; | 1013 | return -error; |
918 | } | 1014 | } |
@@ -923,164 +1019,12 @@ xfs_fs_clear_inode( | |||
923 | { | 1019 | { |
924 | xfs_inode_t *ip = XFS_I(inode); | 1020 | xfs_inode_t *ip = XFS_I(inode); |
925 | 1021 | ||
926 | /* | 1022 | xfs_itrace_entry(ip); |
927 | * ip can be null when xfs_iget_core calls xfs_idestroy if we | 1023 | XFS_STATS_INC(vn_rele); |
928 | * find an inode with di_mode == 0 but without IGET_CREATE set. | 1024 | XFS_STATS_INC(vn_remove); |
929 | */ | 1025 | XFS_STATS_DEC(vn_active); |
930 | if (ip) { | ||
931 | xfs_itrace_entry(ip); | ||
932 | XFS_STATS_INC(vn_rele); | ||
933 | XFS_STATS_INC(vn_remove); | ||
934 | XFS_STATS_INC(vn_reclaim); | ||
935 | XFS_STATS_DEC(vn_active); | ||
936 | |||
937 | xfs_inactive(ip); | ||
938 | xfs_iflags_clear(ip, XFS_IMODIFIED); | ||
939 | if (xfs_reclaim(ip)) | ||
940 | panic("%s: cannot reclaim 0x%p\n", __func__, inode); | ||
941 | } | ||
942 | |||
943 | ASSERT(XFS_I(inode) == NULL); | ||
944 | } | ||
945 | 1026 | ||
946 | /* | 1027 | xfs_inactive(ip); |
947 | * Enqueue a work item to be picked up by the vfs xfssyncd thread. | ||
948 | * Doing this has two advantages: | ||
949 | * - It saves on stack space, which is tight in certain situations | ||
950 | * - It can be used (with care) as a mechanism to avoid deadlocks. | ||
951 | * Flushing while allocating in a full filesystem requires both. | ||
952 | */ | ||
953 | STATIC void | ||
954 | xfs_syncd_queue_work( | ||
955 | struct xfs_mount *mp, | ||
956 | void *data, | ||
957 | void (*syncer)(struct xfs_mount *, void *)) | ||
958 | { | ||
959 | struct bhv_vfs_sync_work *work; | ||
960 | |||
961 | work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP); | ||
962 | INIT_LIST_HEAD(&work->w_list); | ||
963 | work->w_syncer = syncer; | ||
964 | work->w_data = data; | ||
965 | work->w_mount = mp; | ||
966 | spin_lock(&mp->m_sync_lock); | ||
967 | list_add_tail(&work->w_list, &mp->m_sync_list); | ||
968 | spin_unlock(&mp->m_sync_lock); | ||
969 | wake_up_process(mp->m_sync_task); | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * Flush delayed allocate data, attempting to free up reserved space | ||
974 | * from existing allocations. At this point a new allocation attempt | ||
975 | * has failed with ENOSPC and we are in the process of scratching our | ||
976 | * heads, looking about for more room... | ||
977 | */ | ||
978 | STATIC void | ||
979 | xfs_flush_inode_work( | ||
980 | struct xfs_mount *mp, | ||
981 | void *arg) | ||
982 | { | ||
983 | struct inode *inode = arg; | ||
984 | filemap_flush(inode->i_mapping); | ||
985 | iput(inode); | ||
986 | } | ||
987 | |||
988 | void | ||
989 | xfs_flush_inode( | ||
990 | xfs_inode_t *ip) | ||
991 | { | ||
992 | struct inode *inode = VFS_I(ip); | ||
993 | |||
994 | igrab(inode); | ||
995 | xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work); | ||
996 | delay(msecs_to_jiffies(500)); | ||
997 | } | ||
998 | |||
999 | /* | ||
1000 | * This is the "bigger hammer" version of xfs_flush_inode_work... | ||
1001 | * (IOW, "If at first you don't succeed, use a Bigger Hammer"). | ||
1002 | */ | ||
1003 | STATIC void | ||
1004 | xfs_flush_device_work( | ||
1005 | struct xfs_mount *mp, | ||
1006 | void *arg) | ||
1007 | { | ||
1008 | struct inode *inode = arg; | ||
1009 | sync_blockdev(mp->m_super->s_bdev); | ||
1010 | iput(inode); | ||
1011 | } | ||
1012 | |||
1013 | void | ||
1014 | xfs_flush_device( | ||
1015 | xfs_inode_t *ip) | ||
1016 | { | ||
1017 | struct inode *inode = VFS_I(ip); | ||
1018 | |||
1019 | igrab(inode); | ||
1020 | xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work); | ||
1021 | delay(msecs_to_jiffies(500)); | ||
1022 | xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
1023 | } | ||
1024 | |||
1025 | STATIC void | ||
1026 | xfs_sync_worker( | ||
1027 | struct xfs_mount *mp, | ||
1028 | void *unused) | ||
1029 | { | ||
1030 | int error; | ||
1031 | |||
1032 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) | ||
1033 | error = xfs_sync(mp, SYNC_FSDATA | SYNC_BDFLUSH | SYNC_ATTR); | ||
1034 | mp->m_sync_seq++; | ||
1035 | wake_up(&mp->m_wait_single_sync_task); | ||
1036 | } | ||
1037 | |||
1038 | STATIC int | ||
1039 | xfssyncd( | ||
1040 | void *arg) | ||
1041 | { | ||
1042 | struct xfs_mount *mp = arg; | ||
1043 | long timeleft; | ||
1044 | bhv_vfs_sync_work_t *work, *n; | ||
1045 | LIST_HEAD (tmp); | ||
1046 | |||
1047 | set_freezable(); | ||
1048 | timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); | ||
1049 | for (;;) { | ||
1050 | timeleft = schedule_timeout_interruptible(timeleft); | ||
1051 | /* swsusp */ | ||
1052 | try_to_freeze(); | ||
1053 | if (kthread_should_stop() && list_empty(&mp->m_sync_list)) | ||
1054 | break; | ||
1055 | |||
1056 | spin_lock(&mp->m_sync_lock); | ||
1057 | /* | ||
1058 | * We can get woken by laptop mode, to do a sync - | ||
1059 | * that's the (only!) case where the list would be | ||
1060 | * empty with time remaining. | ||
1061 | */ | ||
1062 | if (!timeleft || list_empty(&mp->m_sync_list)) { | ||
1063 | if (!timeleft) | ||
1064 | timeleft = xfs_syncd_centisecs * | ||
1065 | msecs_to_jiffies(10); | ||
1066 | INIT_LIST_HEAD(&mp->m_sync_work.w_list); | ||
1067 | list_add_tail(&mp->m_sync_work.w_list, | ||
1068 | &mp->m_sync_list); | ||
1069 | } | ||
1070 | list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list) | ||
1071 | list_move(&work->w_list, &tmp); | ||
1072 | spin_unlock(&mp->m_sync_lock); | ||
1073 | |||
1074 | list_for_each_entry_safe(work, n, &tmp, w_list) { | ||
1075 | (*work->w_syncer)(mp, work->w_data); | ||
1076 | list_del(&work->w_list); | ||
1077 | if (work == &mp->m_sync_work) | ||
1078 | continue; | ||
1079 | kmem_free(work); | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | return 0; | ||
1084 | } | 1028 | } |
1085 | 1029 | ||
1086 | STATIC void | 1030 | STATIC void |
@@ -1099,11 +1043,9 @@ xfs_fs_put_super( | |||
1099 | struct xfs_mount *mp = XFS_M(sb); | 1043 | struct xfs_mount *mp = XFS_M(sb); |
1100 | struct xfs_inode *rip = mp->m_rootip; | 1044 | struct xfs_inode *rip = mp->m_rootip; |
1101 | int unmount_event_flags = 0; | 1045 | int unmount_event_flags = 0; |
1102 | int error; | ||
1103 | 1046 | ||
1104 | kthread_stop(mp->m_sync_task); | 1047 | xfs_syncd_stop(mp); |
1105 | 1048 | xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI); | |
1106 | xfs_sync(mp, SYNC_ATTR | SYNC_DELWRI); | ||
1107 | 1049 | ||
1108 | #ifdef HAVE_DMAPI | 1050 | #ifdef HAVE_DMAPI |
1109 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | 1051 | if (mp->m_flags & XFS_MOUNT_DMAPI) { |
@@ -1128,18 +1070,6 @@ xfs_fs_put_super( | |||
1128 | xfs_filestream_unmount(mp); | 1070 | xfs_filestream_unmount(mp); |
1129 | 1071 | ||
1130 | XFS_bflush(mp->m_ddev_targp); | 1072 | XFS_bflush(mp->m_ddev_targp); |
1131 | error = xfs_unmount_flush(mp, 0); | ||
1132 | WARN_ON(error); | ||
1133 | |||
1134 | /* | ||
1135 | * If we're forcing a shutdown, typically because of a media error, | ||
1136 | * we want to make sure we invalidate dirty pages that belong to | ||
1137 | * referenced vnodes as well. | ||
1138 | */ | ||
1139 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
1140 | error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE); | ||
1141 | ASSERT(error != EFSCORRUPTED); | ||
1142 | } | ||
1143 | 1073 | ||
1144 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | 1074 | if (mp->m_flags & XFS_MOUNT_DMAPI) { |
1145 | XFS_SEND_UNMOUNT(mp, rip, DM_RIGHT_NULL, 0, 0, | 1075 | XFS_SEND_UNMOUNT(mp, rip, DM_RIGHT_NULL, 0, 0, |
@@ -1161,7 +1091,7 @@ xfs_fs_write_super( | |||
1161 | struct super_block *sb) | 1091 | struct super_block *sb) |
1162 | { | 1092 | { |
1163 | if (!(sb->s_flags & MS_RDONLY)) | 1093 | if (!(sb->s_flags & MS_RDONLY)) |
1164 | xfs_sync(XFS_M(sb), SYNC_FSDATA); | 1094 | xfs_sync_fsdata(XFS_M(sb), 0); |
1165 | sb->s_dirt = 0; | 1095 | sb->s_dirt = 0; |
1166 | } | 1096 | } |
1167 | 1097 | ||
@@ -1172,7 +1102,6 @@ xfs_fs_sync_super( | |||
1172 | { | 1102 | { |
1173 | struct xfs_mount *mp = XFS_M(sb); | 1103 | struct xfs_mount *mp = XFS_M(sb); |
1174 | int error; | 1104 | int error; |
1175 | int flags; | ||
1176 | 1105 | ||
1177 | /* | 1106 | /* |
1178 | * Treat a sync operation like a freeze. This is to work | 1107 | * Treat a sync operation like a freeze. This is to work |
@@ -1186,20 +1115,10 @@ xfs_fs_sync_super( | |||
1186 | * dirty the Linux inode until after the transaction I/O | 1115 | * dirty the Linux inode until after the transaction I/O |
1187 | * completes. | 1116 | * completes. |
1188 | */ | 1117 | */ |
1189 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { | 1118 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) |
1190 | /* | 1119 | error = xfs_quiesce_data(mp); |
1191 | * First stage of freeze - no more writers will make progress | 1120 | else |
1192 | * now we are here, so we flush delwri and delalloc buffers | 1121 | error = xfs_sync_fsdata(mp, 0); |
1193 | * here, then wait for all I/O to complete. Data is frozen at | ||
1194 | * that point. Metadata is not frozen, transactions can still | ||
1195 | * occur here so don't bother flushing the buftarg (i.e | ||
1196 | * SYNC_QUIESCE) because it'll just get dirty again. | ||
1197 | */ | ||
1198 | flags = SYNC_DATA_QUIESCE; | ||
1199 | } else | ||
1200 | flags = SYNC_FSDATA; | ||
1201 | |||
1202 | error = xfs_sync(mp, flags); | ||
1203 | sb->s_dirt = 0; | 1122 | sb->s_dirt = 0; |
1204 | 1123 | ||
1205 | if (unlikely(laptop_mode)) { | 1124 | if (unlikely(laptop_mode)) { |
@@ -1337,9 +1256,8 @@ xfs_fs_remount( | |||
1337 | 1256 | ||
1338 | /* rw -> ro */ | 1257 | /* rw -> ro */ |
1339 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { | 1258 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { |
1340 | xfs_filestream_flush(mp); | 1259 | xfs_quiesce_data(mp); |
1341 | xfs_sync(mp, SYNC_DATA_QUIESCE); | 1260 | xfs_quiesce_attr(mp); |
1342 | xfs_attr_quiesce(mp); | ||
1343 | mp->m_flags |= XFS_MOUNT_RDONLY; | 1261 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1344 | } | 1262 | } |
1345 | 1263 | ||
@@ -1348,7 +1266,7 @@ xfs_fs_remount( | |||
1348 | 1266 | ||
1349 | /* | 1267 | /* |
1350 | * Second stage of a freeze. The data is already frozen so we only | 1268 | * Second stage of a freeze. The data is already frozen so we only |
1351 | * need to take care of themetadata. Once that's done write a dummy | 1269 | * need to take care of the metadata. Once that's done write a dummy |
1352 | * record to dirty the log in case of a crash while frozen. | 1270 | * record to dirty the log in case of a crash while frozen. |
1353 | */ | 1271 | */ |
1354 | STATIC void | 1272 | STATIC void |
@@ -1357,7 +1275,7 @@ xfs_fs_lockfs( | |||
1357 | { | 1275 | { |
1358 | struct xfs_mount *mp = XFS_M(sb); | 1276 | struct xfs_mount *mp = XFS_M(sb); |
1359 | 1277 | ||
1360 | xfs_attr_quiesce(mp); | 1278 | xfs_quiesce_attr(mp); |
1361 | xfs_fs_log_dummy(mp); | 1279 | xfs_fs_log_dummy(mp); |
1362 | } | 1280 | } |
1363 | 1281 | ||
@@ -1422,175 +1340,28 @@ xfs_fs_setxquota( | |||
1422 | 1340 | ||
1423 | /* | 1341 | /* |
1424 | * This function fills in xfs_mount_t fields based on mount args. | 1342 | * This function fills in xfs_mount_t fields based on mount args. |
1425 | * Note: the superblock has _not_ yet been read in. | ||
1426 | */ | ||
1427 | STATIC int | ||
1428 | xfs_start_flags( | ||
1429 | struct xfs_mount_args *ap, | ||
1430 | struct xfs_mount *mp) | ||
1431 | { | ||
1432 | int error; | ||
1433 | |||
1434 | /* Values are in BBs */ | ||
1435 | if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
1436 | /* | ||
1437 | * At this point the superblock has not been read | ||
1438 | * in, therefore we do not know the block size. | ||
1439 | * Before the mount call ends we will convert | ||
1440 | * these to FSBs. | ||
1441 | */ | ||
1442 | mp->m_dalign = ap->sunit; | ||
1443 | mp->m_swidth = ap->swidth; | ||
1444 | } | ||
1445 | |||
1446 | if (ap->logbufs != -1 && | ||
1447 | ap->logbufs != 0 && | ||
1448 | (ap->logbufs < XLOG_MIN_ICLOGS || | ||
1449 | ap->logbufs > XLOG_MAX_ICLOGS)) { | ||
1450 | cmn_err(CE_WARN, | ||
1451 | "XFS: invalid logbufs value: %d [not %d-%d]", | ||
1452 | ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | ||
1453 | return XFS_ERROR(EINVAL); | ||
1454 | } | ||
1455 | mp->m_logbufs = ap->logbufs; | ||
1456 | if (ap->logbufsize != -1 && | ||
1457 | ap->logbufsize != 0 && | ||
1458 | (ap->logbufsize < XLOG_MIN_RECORD_BSIZE || | ||
1459 | ap->logbufsize > XLOG_MAX_RECORD_BSIZE || | ||
1460 | !is_power_of_2(ap->logbufsize))) { | ||
1461 | cmn_err(CE_WARN, | ||
1462 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | ||
1463 | ap->logbufsize); | ||
1464 | return XFS_ERROR(EINVAL); | ||
1465 | } | ||
1466 | |||
1467 | error = ENOMEM; | ||
1468 | |||
1469 | mp->m_logbsize = ap->logbufsize; | ||
1470 | mp->m_fsname_len = strlen(ap->fsname) + 1; | ||
1471 | |||
1472 | mp->m_fsname = kstrdup(ap->fsname, GFP_KERNEL); | ||
1473 | if (!mp->m_fsname) | ||
1474 | goto out; | ||
1475 | |||
1476 | if (ap->rtname[0]) { | ||
1477 | mp->m_rtname = kstrdup(ap->rtname, GFP_KERNEL); | ||
1478 | if (!mp->m_rtname) | ||
1479 | goto out_free_fsname; | ||
1480 | |||
1481 | } | ||
1482 | |||
1483 | if (ap->logname[0]) { | ||
1484 | mp->m_logname = kstrdup(ap->logname, GFP_KERNEL); | ||
1485 | if (!mp->m_logname) | ||
1486 | goto out_free_rtname; | ||
1487 | } | ||
1488 | |||
1489 | if (ap->flags & XFSMNT_WSYNC) | ||
1490 | mp->m_flags |= XFS_MOUNT_WSYNC; | ||
1491 | #if XFS_BIG_INUMS | ||
1492 | if (ap->flags & XFSMNT_INO64) { | ||
1493 | mp->m_flags |= XFS_MOUNT_INO64; | ||
1494 | mp->m_inoadd = XFS_INO64_OFFSET; | ||
1495 | } | ||
1496 | #endif | ||
1497 | if (ap->flags & XFSMNT_RETERR) | ||
1498 | mp->m_flags |= XFS_MOUNT_RETERR; | ||
1499 | if (ap->flags & XFSMNT_NOALIGN) | ||
1500 | mp->m_flags |= XFS_MOUNT_NOALIGN; | ||
1501 | if (ap->flags & XFSMNT_SWALLOC) | ||
1502 | mp->m_flags |= XFS_MOUNT_SWALLOC; | ||
1503 | if (ap->flags & XFSMNT_OSYNCISOSYNC) | ||
1504 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; | ||
1505 | if (ap->flags & XFSMNT_32BITINODES) | ||
1506 | mp->m_flags |= XFS_MOUNT_32BITINODES; | ||
1507 | |||
1508 | if (ap->flags & XFSMNT_IOSIZE) { | ||
1509 | if (ap->iosizelog > XFS_MAX_IO_LOG || | ||
1510 | ap->iosizelog < XFS_MIN_IO_LOG) { | ||
1511 | cmn_err(CE_WARN, | ||
1512 | "XFS: invalid log iosize: %d [not %d-%d]", | ||
1513 | ap->iosizelog, XFS_MIN_IO_LOG, | ||
1514 | XFS_MAX_IO_LOG); | ||
1515 | return XFS_ERROR(EINVAL); | ||
1516 | } | ||
1517 | |||
1518 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | ||
1519 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | ||
1520 | } | ||
1521 | |||
1522 | if (ap->flags & XFSMNT_IKEEP) | ||
1523 | mp->m_flags |= XFS_MOUNT_IKEEP; | ||
1524 | if (ap->flags & XFSMNT_DIRSYNC) | ||
1525 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | ||
1526 | if (ap->flags & XFSMNT_ATTR2) | ||
1527 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
1528 | if (ap->flags & XFSMNT_NOATTR2) | ||
1529 | mp->m_flags |= XFS_MOUNT_NOATTR2; | ||
1530 | |||
1531 | if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) | ||
1532 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | ||
1533 | |||
1534 | /* | ||
1535 | * no recovery flag requires a read-only mount | ||
1536 | */ | ||
1537 | if (ap->flags & XFSMNT_NORECOVERY) { | ||
1538 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { | ||
1539 | cmn_err(CE_WARN, | ||
1540 | "XFS: tried to mount a FS read-write without recovery!"); | ||
1541 | return XFS_ERROR(EINVAL); | ||
1542 | } | ||
1543 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | ||
1544 | } | ||
1545 | |||
1546 | if (ap->flags & XFSMNT_NOUUID) | ||
1547 | mp->m_flags |= XFS_MOUNT_NOUUID; | ||
1548 | if (ap->flags & XFSMNT_BARRIER) | ||
1549 | mp->m_flags |= XFS_MOUNT_BARRIER; | ||
1550 | else | ||
1551 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
1552 | |||
1553 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
1554 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
1555 | |||
1556 | if (ap->flags & XFSMNT_DMAPI) | ||
1557 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
1558 | return 0; | ||
1559 | |||
1560 | |||
1561 | out_free_rtname: | ||
1562 | kfree(mp->m_rtname); | ||
1563 | out_free_fsname: | ||
1564 | kfree(mp->m_fsname); | ||
1565 | out: | ||
1566 | return error; | ||
1567 | } | ||
1568 | |||
1569 | /* | ||
1570 | * This function fills in xfs_mount_t fields based on mount args. | ||
1571 | * Note: the superblock _has_ now been read in. | 1343 | * Note: the superblock _has_ now been read in. |
1572 | */ | 1344 | */ |
1573 | STATIC int | 1345 | STATIC int |
1574 | xfs_finish_flags( | 1346 | xfs_finish_flags( |
1575 | struct xfs_mount_args *ap, | ||
1576 | struct xfs_mount *mp) | 1347 | struct xfs_mount *mp) |
1577 | { | 1348 | { |
1578 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | 1349 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); |
1579 | 1350 | ||
1580 | /* Fail a mount where the logbuf is smaller then the log stripe */ | 1351 | /* Fail a mount where the logbuf is smaller then the log stripe */ |
1581 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | 1352 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { |
1582 | if ((ap->logbufsize <= 0) && | 1353 | if (mp->m_logbsize <= 0 && |
1583 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { | 1354 | mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) { |
1584 | mp->m_logbsize = mp->m_sb.sb_logsunit; | 1355 | mp->m_logbsize = mp->m_sb.sb_logsunit; |
1585 | } else if (ap->logbufsize > 0 && | 1356 | } else if (mp->m_logbsize > 0 && |
1586 | ap->logbufsize < mp->m_sb.sb_logsunit) { | 1357 | mp->m_logbsize < mp->m_sb.sb_logsunit) { |
1587 | cmn_err(CE_WARN, | 1358 | cmn_err(CE_WARN, |
1588 | "XFS: logbuf size must be greater than or equal to log stripe size"); | 1359 | "XFS: logbuf size must be greater than or equal to log stripe size"); |
1589 | return XFS_ERROR(EINVAL); | 1360 | return XFS_ERROR(EINVAL); |
1590 | } | 1361 | } |
1591 | } else { | 1362 | } else { |
1592 | /* Fail a mount if the logbuf is larger than 32K */ | 1363 | /* Fail a mount if the logbuf is larger than 32K */ |
1593 | if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) { | 1364 | if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) { |
1594 | cmn_err(CE_WARN, | 1365 | cmn_err(CE_WARN, |
1595 | "XFS: logbuf size for version 1 logs must be 16K or 32K"); | 1366 | "XFS: logbuf size for version 1 logs must be 16K or 32K"); |
1596 | return XFS_ERROR(EINVAL); | 1367 | return XFS_ERROR(EINVAL); |
@@ -1602,7 +1373,7 @@ xfs_finish_flags( | |||
1602 | * told by noattr2 to turn it off | 1373 | * told by noattr2 to turn it off |
1603 | */ | 1374 | */ |
1604 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | 1375 | if (xfs_sb_version_hasattr2(&mp->m_sb) && |
1605 | !(ap->flags & XFSMNT_NOATTR2)) | 1376 | !(mp->m_flags & XFS_MOUNT_NOATTR2)) |
1606 | mp->m_flags |= XFS_MOUNT_ATTR2; | 1377 | mp->m_flags |= XFS_MOUNT_ATTR2; |
1607 | 1378 | ||
1608 | /* | 1379 | /* |
@@ -1614,48 +1385,6 @@ xfs_finish_flags( | |||
1614 | return XFS_ERROR(EROFS); | 1385 | return XFS_ERROR(EROFS); |
1615 | } | 1386 | } |
1616 | 1387 | ||
1617 | /* | ||
1618 | * check for shared mount. | ||
1619 | */ | ||
1620 | if (ap->flags & XFSMNT_SHARED) { | ||
1621 | if (!xfs_sb_version_hasshared(&mp->m_sb)) | ||
1622 | return XFS_ERROR(EINVAL); | ||
1623 | |||
1624 | /* | ||
1625 | * For IRIX 6.5, shared mounts must have the shared | ||
1626 | * version bit set, have the persistent readonly | ||
1627 | * field set, must be version 0 and can only be mounted | ||
1628 | * read-only. | ||
1629 | */ | ||
1630 | if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) || | ||
1631 | (mp->m_sb.sb_shared_vn != 0)) | ||
1632 | return XFS_ERROR(EINVAL); | ||
1633 | |||
1634 | mp->m_flags |= XFS_MOUNT_SHARED; | ||
1635 | |||
1636 | /* | ||
1637 | * Shared XFS V0 can't deal with DMI. Return EINVAL. | ||
1638 | */ | ||
1639 | if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) | ||
1640 | return XFS_ERROR(EINVAL); | ||
1641 | } | ||
1642 | |||
1643 | if (ap->flags & XFSMNT_UQUOTA) { | ||
1644 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
1645 | if (ap->flags & XFSMNT_UQUOTAENF) | ||
1646 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
1647 | } | ||
1648 | |||
1649 | if (ap->flags & XFSMNT_GQUOTA) { | ||
1650 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
1651 | if (ap->flags & XFSMNT_GQUOTAENF) | ||
1652 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
1653 | } else if (ap->flags & XFSMNT_PQUOTA) { | ||
1654 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
1655 | if (ap->flags & XFSMNT_PQUOTAENF) | ||
1656 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
1657 | } | ||
1658 | |||
1659 | return 0; | 1388 | return 0; |
1660 | } | 1389 | } |
1661 | 1390 | ||
@@ -1667,19 +1396,14 @@ xfs_fs_fill_super( | |||
1667 | { | 1396 | { |
1668 | struct inode *root; | 1397 | struct inode *root; |
1669 | struct xfs_mount *mp = NULL; | 1398 | struct xfs_mount *mp = NULL; |
1670 | struct xfs_mount_args *args; | ||
1671 | int flags = 0, error = ENOMEM; | 1399 | int flags = 0, error = ENOMEM; |
1672 | 1400 | char *mtpt = NULL; | |
1673 | args = xfs_args_allocate(sb, silent); | ||
1674 | if (!args) | ||
1675 | return -ENOMEM; | ||
1676 | 1401 | ||
1677 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); | 1402 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
1678 | if (!mp) | 1403 | if (!mp) |
1679 | goto out_free_args; | 1404 | goto out; |
1680 | 1405 | ||
1681 | spin_lock_init(&mp->m_sb_lock); | 1406 | spin_lock_init(&mp->m_sb_lock); |
1682 | mutex_init(&mp->m_ilock); | ||
1683 | mutex_init(&mp->m_growlock); | 1407 | mutex_init(&mp->m_growlock); |
1684 | atomic_set(&mp->m_active_trans, 0); | 1408 | atomic_set(&mp->m_active_trans, 0); |
1685 | INIT_LIST_HEAD(&mp->m_sync_list); | 1409 | INIT_LIST_HEAD(&mp->m_sync_list); |
@@ -1689,12 +1413,9 @@ xfs_fs_fill_super( | |||
1689 | mp->m_super = sb; | 1413 | mp->m_super = sb; |
1690 | sb->s_fs_info = mp; | 1414 | sb->s_fs_info = mp; |
1691 | 1415 | ||
1692 | if (sb->s_flags & MS_RDONLY) | 1416 | error = xfs_parseargs(mp, (char *)data, &mtpt); |
1693 | mp->m_flags |= XFS_MOUNT_RDONLY; | ||
1694 | |||
1695 | error = xfs_parseargs(mp, (char *)data, args, 0); | ||
1696 | if (error) | 1417 | if (error) |
1697 | goto out_free_mp; | 1418 | goto out_free_fsname; |
1698 | 1419 | ||
1699 | sb_min_blocksize(sb, BBSIZE); | 1420 | sb_min_blocksize(sb, BBSIZE); |
1700 | sb->s_xattr = xfs_xattr_handlers; | 1421 | sb->s_xattr = xfs_xattr_handlers; |
@@ -1702,33 +1423,28 @@ xfs_fs_fill_super( | |||
1702 | sb->s_qcop = &xfs_quotactl_operations; | 1423 | sb->s_qcop = &xfs_quotactl_operations; |
1703 | sb->s_op = &xfs_super_operations; | 1424 | sb->s_op = &xfs_super_operations; |
1704 | 1425 | ||
1705 | error = xfs_dmops_get(mp, args); | 1426 | error = xfs_dmops_get(mp); |
1706 | if (error) | 1427 | if (error) |
1707 | goto out_free_mp; | 1428 | goto out_free_fsname; |
1708 | error = xfs_qmops_get(mp, args); | 1429 | error = xfs_qmops_get(mp); |
1709 | if (error) | 1430 | if (error) |
1710 | goto out_put_dmops; | 1431 | goto out_put_dmops; |
1711 | 1432 | ||
1712 | if (args->flags & XFSMNT_QUIET) | 1433 | if (silent) |
1713 | flags |= XFS_MFSI_QUIET; | 1434 | flags |= XFS_MFSI_QUIET; |
1714 | 1435 | ||
1715 | error = xfs_open_devices(mp, args); | 1436 | error = xfs_open_devices(mp); |
1716 | if (error) | 1437 | if (error) |
1717 | goto out_put_qmops; | 1438 | goto out_put_qmops; |
1718 | 1439 | ||
1719 | if (xfs_icsb_init_counters(mp)) | 1440 | if (xfs_icsb_init_counters(mp)) |
1720 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; | 1441 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; |
1721 | 1442 | ||
1722 | /* | ||
1723 | * Setup flags based on mount(2) options and then the superblock | ||
1724 | */ | ||
1725 | error = xfs_start_flags(args, mp); | ||
1726 | if (error) | ||
1727 | goto out_free_fsname; | ||
1728 | error = xfs_readsb(mp, flags); | 1443 | error = xfs_readsb(mp, flags); |
1729 | if (error) | 1444 | if (error) |
1730 | goto out_free_fsname; | 1445 | goto out_destroy_counters; |
1731 | error = xfs_finish_flags(args, mp); | 1446 | |
1447 | error = xfs_finish_flags(mp); | ||
1732 | if (error) | 1448 | if (error) |
1733 | goto out_free_sb; | 1449 | goto out_free_sb; |
1734 | 1450 | ||
@@ -1747,7 +1463,7 @@ xfs_fs_fill_super( | |||
1747 | if (error) | 1463 | if (error) |
1748 | goto out_filestream_unmount; | 1464 | goto out_filestream_unmount; |
1749 | 1465 | ||
1750 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); | 1466 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname); |
1751 | 1467 | ||
1752 | sb->s_dirt = 1; | 1468 | sb->s_dirt = 1; |
1753 | sb->s_magic = XFS_SB_MAGIC; | 1469 | sb->s_magic = XFS_SB_MAGIC; |
@@ -1772,35 +1488,31 @@ xfs_fs_fill_super( | |||
1772 | goto fail_vnrele; | 1488 | goto fail_vnrele; |
1773 | } | 1489 | } |
1774 | 1490 | ||
1775 | mp->m_sync_work.w_syncer = xfs_sync_worker; | 1491 | error = xfs_syncd_init(mp); |
1776 | mp->m_sync_work.w_mount = mp; | 1492 | if (error) |
1777 | mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd"); | ||
1778 | if (IS_ERR(mp->m_sync_task)) { | ||
1779 | error = -PTR_ERR(mp->m_sync_task); | ||
1780 | goto fail_vnrele; | 1493 | goto fail_vnrele; |
1781 | } | ||
1782 | 1494 | ||
1783 | xfs_itrace_exit(XFS_I(sb->s_root->d_inode)); | 1495 | kfree(mtpt); |
1784 | 1496 | ||
1785 | kfree(args); | 1497 | xfs_itrace_exit(XFS_I(sb->s_root->d_inode)); |
1786 | return 0; | 1498 | return 0; |
1787 | 1499 | ||
1788 | out_filestream_unmount: | 1500 | out_filestream_unmount: |
1789 | xfs_filestream_unmount(mp); | 1501 | xfs_filestream_unmount(mp); |
1790 | out_free_sb: | 1502 | out_free_sb: |
1791 | xfs_freesb(mp); | 1503 | xfs_freesb(mp); |
1792 | out_free_fsname: | 1504 | out_destroy_counters: |
1793 | xfs_free_fsname(mp); | ||
1794 | xfs_icsb_destroy_counters(mp); | 1505 | xfs_icsb_destroy_counters(mp); |
1795 | xfs_close_devices(mp); | 1506 | xfs_close_devices(mp); |
1796 | out_put_qmops: | 1507 | out_put_qmops: |
1797 | xfs_qmops_put(mp); | 1508 | xfs_qmops_put(mp); |
1798 | out_put_dmops: | 1509 | out_put_dmops: |
1799 | xfs_dmops_put(mp); | 1510 | xfs_dmops_put(mp); |
1800 | out_free_mp: | 1511 | out_free_fsname: |
1512 | xfs_free_fsname(mp); | ||
1513 | kfree(mtpt); | ||
1801 | kfree(mp); | 1514 | kfree(mp); |
1802 | out_free_args: | 1515 | out: |
1803 | kfree(args); | ||
1804 | return -error; | 1516 | return -error; |
1805 | 1517 | ||
1806 | fail_vnrele: | 1518 | fail_vnrele: |
@@ -1820,8 +1532,6 @@ xfs_fs_fill_super( | |||
1820 | xfs_filestream_unmount(mp); | 1532 | xfs_filestream_unmount(mp); |
1821 | 1533 | ||
1822 | XFS_bflush(mp->m_ddev_targp); | 1534 | XFS_bflush(mp->m_ddev_targp); |
1823 | error = xfs_unmount_flush(mp, 0); | ||
1824 | WARN_ON(error); | ||
1825 | 1535 | ||
1826 | xfs_unmountfs(mp); | 1536 | xfs_unmountfs(mp); |
1827 | goto out_free_sb; | 1537 | goto out_free_sb; |
@@ -1882,10 +1592,19 @@ xfs_alloc_trace_bufs(void) | |||
1882 | if (!xfs_bmap_trace_buf) | 1592 | if (!xfs_bmap_trace_buf) |
1883 | goto out_free_alloc_trace; | 1593 | goto out_free_alloc_trace; |
1884 | #endif | 1594 | #endif |
1885 | #ifdef XFS_BMBT_TRACE | 1595 | #ifdef XFS_BTREE_TRACE |
1596 | xfs_allocbt_trace_buf = ktrace_alloc(XFS_ALLOCBT_TRACE_SIZE, | ||
1597 | KM_MAYFAIL); | ||
1598 | if (!xfs_allocbt_trace_buf) | ||
1599 | goto out_free_bmap_trace; | ||
1600 | |||
1601 | xfs_inobt_trace_buf = ktrace_alloc(XFS_INOBT_TRACE_SIZE, KM_MAYFAIL); | ||
1602 | if (!xfs_inobt_trace_buf) | ||
1603 | goto out_free_allocbt_trace; | ||
1604 | |||
1886 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_MAYFAIL); | 1605 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_MAYFAIL); |
1887 | if (!xfs_bmbt_trace_buf) | 1606 | if (!xfs_bmbt_trace_buf) |
1888 | goto out_free_bmap_trace; | 1607 | goto out_free_inobt_trace; |
1889 | #endif | 1608 | #endif |
1890 | #ifdef XFS_ATTR_TRACE | 1609 | #ifdef XFS_ATTR_TRACE |
1891 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_MAYFAIL); | 1610 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_MAYFAIL); |
@@ -1907,8 +1626,12 @@ xfs_alloc_trace_bufs(void) | |||
1907 | ktrace_free(xfs_attr_trace_buf); | 1626 | ktrace_free(xfs_attr_trace_buf); |
1908 | out_free_bmbt_trace: | 1627 | out_free_bmbt_trace: |
1909 | #endif | 1628 | #endif |
1910 | #ifdef XFS_BMBT_TRACE | 1629 | #ifdef XFS_BTREE_TRACE |
1911 | ktrace_free(xfs_bmbt_trace_buf); | 1630 | ktrace_free(xfs_bmbt_trace_buf); |
1631 | out_free_inobt_trace: | ||
1632 | ktrace_free(xfs_inobt_trace_buf); | ||
1633 | out_free_allocbt_trace: | ||
1634 | ktrace_free(xfs_allocbt_trace_buf); | ||
1912 | out_free_bmap_trace: | 1635 | out_free_bmap_trace: |
1913 | #endif | 1636 | #endif |
1914 | #ifdef XFS_BMAP_TRACE | 1637 | #ifdef XFS_BMAP_TRACE |
@@ -1931,8 +1654,10 @@ xfs_free_trace_bufs(void) | |||
1931 | #ifdef XFS_ATTR_TRACE | 1654 | #ifdef XFS_ATTR_TRACE |
1932 | ktrace_free(xfs_attr_trace_buf); | 1655 | ktrace_free(xfs_attr_trace_buf); |
1933 | #endif | 1656 | #endif |
1934 | #ifdef XFS_BMBT_TRACE | 1657 | #ifdef XFS_BTREE_TRACE |
1935 | ktrace_free(xfs_bmbt_trace_buf); | 1658 | ktrace_free(xfs_bmbt_trace_buf); |
1659 | ktrace_free(xfs_inobt_trace_buf); | ||
1660 | ktrace_free(xfs_allocbt_trace_buf); | ||
1936 | #endif | 1661 | #endif |
1937 | #ifdef XFS_BMAP_TRACE | 1662 | #ifdef XFS_BMAP_TRACE |
1938 | ktrace_free(xfs_bmap_trace_buf); | 1663 | ktrace_free(xfs_bmap_trace_buf); |
@@ -1945,16 +1670,10 @@ xfs_free_trace_bufs(void) | |||
1945 | STATIC int __init | 1670 | STATIC int __init |
1946 | xfs_init_zones(void) | 1671 | xfs_init_zones(void) |
1947 | { | 1672 | { |
1948 | xfs_vnode_zone = kmem_zone_init_flags(sizeof(struct inode), "xfs_vnode", | ||
1949 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | | ||
1950 | KM_ZONE_SPREAD, | ||
1951 | xfs_fs_inode_init_once); | ||
1952 | if (!xfs_vnode_zone) | ||
1953 | goto out; | ||
1954 | 1673 | ||
1955 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); | 1674 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); |
1956 | if (!xfs_ioend_zone) | 1675 | if (!xfs_ioend_zone) |
1957 | goto out_destroy_vnode_zone; | 1676 | goto out; |
1958 | 1677 | ||
1959 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, | 1678 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, |
1960 | xfs_ioend_zone); | 1679 | xfs_ioend_zone); |
@@ -1970,6 +1689,7 @@ xfs_init_zones(void) | |||
1970 | "xfs_bmap_free_item"); | 1689 | "xfs_bmap_free_item"); |
1971 | if (!xfs_bmap_free_item_zone) | 1690 | if (!xfs_bmap_free_item_zone) |
1972 | goto out_destroy_log_ticket_zone; | 1691 | goto out_destroy_log_ticket_zone; |
1692 | |||
1973 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), | 1693 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), |
1974 | "xfs_btree_cur"); | 1694 | "xfs_btree_cur"); |
1975 | if (!xfs_btree_cur_zone) | 1695 | if (!xfs_btree_cur_zone) |
@@ -2017,8 +1737,8 @@ xfs_init_zones(void) | |||
2017 | 1737 | ||
2018 | xfs_inode_zone = | 1738 | xfs_inode_zone = |
2019 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", | 1739 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", |
2020 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | | 1740 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, |
2021 | KM_ZONE_SPREAD, NULL); | 1741 | xfs_fs_inode_init_once); |
2022 | if (!xfs_inode_zone) | 1742 | if (!xfs_inode_zone) |
2023 | goto out_destroy_efi_zone; | 1743 | goto out_destroy_efi_zone; |
2024 | 1744 | ||
@@ -2066,8 +1786,6 @@ xfs_init_zones(void) | |||
2066 | mempool_destroy(xfs_ioend_pool); | 1786 | mempool_destroy(xfs_ioend_pool); |
2067 | out_destroy_ioend_zone: | 1787 | out_destroy_ioend_zone: |
2068 | kmem_zone_destroy(xfs_ioend_zone); | 1788 | kmem_zone_destroy(xfs_ioend_zone); |
2069 | out_destroy_vnode_zone: | ||
2070 | kmem_zone_destroy(xfs_vnode_zone); | ||
2071 | out: | 1789 | out: |
2072 | return -ENOMEM; | 1790 | return -ENOMEM; |
2073 | } | 1791 | } |
@@ -2092,7 +1810,6 @@ xfs_destroy_zones(void) | |||
2092 | kmem_zone_destroy(xfs_log_ticket_zone); | 1810 | kmem_zone_destroy(xfs_log_ticket_zone); |
2093 | mempool_destroy(xfs_ioend_pool); | 1811 | mempool_destroy(xfs_ioend_pool); |
2094 | kmem_zone_destroy(xfs_ioend_zone); | 1812 | kmem_zone_destroy(xfs_ioend_zone); |
2095 | kmem_zone_destroy(xfs_vnode_zone); | ||
2096 | 1813 | ||
2097 | } | 1814 | } |
2098 | 1815 | ||
@@ -2100,13 +1817,12 @@ STATIC int __init | |||
2100 | init_xfs_fs(void) | 1817 | init_xfs_fs(void) |
2101 | { | 1818 | { |
2102 | int error; | 1819 | int error; |
2103 | static char message[] __initdata = KERN_INFO \ | ||
2104 | XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n"; | ||
2105 | 1820 | ||
2106 | printk(message); | 1821 | printk(KERN_INFO XFS_VERSION_STRING " with " |
1822 | XFS_BUILD_OPTIONS " enabled\n"); | ||
2107 | 1823 | ||
2108 | ktrace_init(64); | 1824 | ktrace_init(64); |
2109 | vn_init(); | 1825 | xfs_ioend_init(); |
2110 | xfs_dir_startup(); | 1826 | xfs_dir_startup(); |
2111 | 1827 | ||
2112 | error = xfs_init_zones(); | 1828 | error = xfs_init_zones(); |