VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / xfs / linux-2.6 / xfs_super.c
1 /*
2  * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32
33 #include "xfs.h"
34
35 #include "xfs_inum.h"
36 #include "xfs_log.h"
37 #include "xfs_clnt.h"
38 #include "xfs_trans.h"
39 #include "xfs_sb.h"
40 #include "xfs_dir.h"
41 #include "xfs_dir2.h"
42 #include "xfs_alloc.h"
43 #include "xfs_dmapi.h"
44 #include "xfs_quota.h"
45 #include "xfs_mount.h"
46 #include "xfs_alloc_btree.h"
47 #include "xfs_bmap_btree.h"
48 #include "xfs_ialloc_btree.h"
49 #include "xfs_btree.h"
50 #include "xfs_ialloc.h"
51 #include "xfs_attr_sf.h"
52 #include "xfs_dir_sf.h"
53 #include "xfs_dir2_sf.h"
54 #include "xfs_dinode.h"
55 #include "xfs_inode.h"
56 #include "xfs_bmap.h"
57 #include "xfs_bit.h"
58 #include "xfs_rtalloc.h"
59 #include "xfs_error.h"
60 #include "xfs_itable.h"
61 #include "xfs_rw.h"
62 #include "xfs_acl.h"
63 #include "xfs_cap.h"
64 #include "xfs_mac.h"
65 #include "xfs_attr.h"
66 #include "xfs_buf_item.h"
67 #include "xfs_utils.h"
68 #include "xfs_version.h"
69
70 #include <linux/namei.h>
71 #include <linux/init.h>
72 #include <linux/mount.h>
73 #include <linux/suspend.h>
74 #include <linux/writeback.h>
75
76 STATIC struct quotactl_ops linvfs_qops;
77 STATIC struct super_operations linvfs_sops;
78 STATIC struct export_operations linvfs_export_ops;
79 STATIC kmem_zone_t *linvfs_inode_zone;
80 STATIC kmem_shaker_t xfs_inode_shaker;
81
82 STATIC struct xfs_mount_args *
83 xfs_args_allocate(
84         struct super_block      *sb)
85 {
86         struct xfs_mount_args   *args;
87
88         args = kmem_zalloc(sizeof(struct xfs_mount_args), KM_SLEEP);
89         args->logbufs = args->logbufsize = -1;
90         strncpy(args->fsname, sb->s_id, MAXNAMELEN);
91
92         /* Copy the already-parsed mount(2) flags we're interested in */
93         if (sb->s_flags & MS_NOATIME)
94                 args->flags |= XFSMNT_NOATIME;
95
96         /* Default to 32 bit inodes on Linux all the time */
97         args->flags |= XFSMNT_32BITINODES;
98
99         return args;
100 }
101
102 __uint64_t
103 xfs_max_file_offset(
104         unsigned int            blockshift)
105 {
106         unsigned int            pagefactor = 1;
107         unsigned int            bitshift = BITS_PER_LONG - 1;
108
109         /* Figure out maximum filesize, on Linux this can depend on
110          * the filesystem blocksize (on 32 bit platforms).
111          * __block_prepare_write does this in an [unsigned] long...
112          *      page->index << (PAGE_CACHE_SHIFT - bbits)
113          * So, for page sized blocks (4K on 32 bit platforms),
114          * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
115          *      (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
116          * but for smaller blocksizes it is less (bbits = log2 bsize).
117          * Note1: get_block_t takes a long (implicit cast from above)
118          * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
119          * can optionally convert the [unsigned] long from above into
120          * an [unsigned] long long.
121          */
122
123 #if BITS_PER_LONG == 32
124 # if defined(CONFIG_LBD)
125         ASSERT(sizeof(sector_t) == 8);
126         pagefactor = PAGE_CACHE_SIZE;
127         bitshift = BITS_PER_LONG;
128 # else
129         pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
130 # endif
131 #endif
132
133         return (((__uint64_t)pagefactor) << bitshift) - 1;
134 }
135
136 STATIC __inline__ void
137 xfs_set_inodeops(
138         struct inode            *inode)
139 {
140         vnode_t                 *vp = LINVFS_GET_VP(inode);
141
142         if (vp->v_type == VNON) {
143                 make_bad_inode(inode);
144         } else if (S_ISREG(inode->i_mode)) {
145                 inode->i_op = &linvfs_file_inode_operations;
146                 inode->i_fop = &linvfs_file_operations;
147                 inode->i_mapping->a_ops = &linvfs_aops;
148         } else if (S_ISDIR(inode->i_mode)) {
149                 inode->i_op = &linvfs_dir_inode_operations;
150                 inode->i_fop = &linvfs_dir_operations;
151         } else if (S_ISLNK(inode->i_mode)) {
152                 inode->i_op = &linvfs_symlink_inode_operations;
153                 if (inode->i_blocks)
154                         inode->i_mapping->a_ops = &linvfs_aops;
155         } else {
156                 inode->i_op = &linvfs_file_inode_operations;
157                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
158         }
159 }
160
161 STATIC __inline__ void
162 xfs_revalidate_inode(
163         xfs_mount_t             *mp,
164         vnode_t                 *vp,
165         xfs_inode_t             *ip)
166 {
167         struct inode            *inode = LINVFS_GET_IP(vp);
168
169         inode->i_mode   = (ip->i_d.di_mode & MODEMASK) | VTTOIF(vp->v_type);
170         inode->i_nlink  = ip->i_d.di_nlink;
171         inode->i_uid    = ip->i_d.di_uid;
172         inode->i_gid    = ip->i_d.di_gid;
173         if (((1 << vp->v_type) & ((1<<VBLK) | (1<<VCHR))) == 0) {
174                 inode->i_rdev = 0;
175         } else {
176                 xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
177                 inode->i_rdev = MKDEV(sysv_major(dev) & 0x1ff, sysv_minor(dev));
178         }
179         inode->i_blksize = PAGE_CACHE_SIZE;
180         inode->i_generation = ip->i_d.di_gen;
181         i_size_write(inode, ip->i_d.di_size);
182         inode->i_blocks =
183                 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
184         inode->i_atime.tv_sec   = ip->i_d.di_atime.t_sec;
185         inode->i_atime.tv_nsec  = ip->i_d.di_atime.t_nsec;
186         inode->i_mtime.tv_sec   = ip->i_d.di_mtime.t_sec;
187         inode->i_mtime.tv_nsec  = ip->i_d.di_mtime.t_nsec;
188         inode->i_ctime.tv_sec   = ip->i_d.di_ctime.t_sec;
189         inode->i_ctime.tv_nsec  = ip->i_d.di_ctime.t_nsec;
190         if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
191                 inode->i_flags |= S_IMMUTABLE;
192         else
193                 inode->i_flags &= ~S_IMMUTABLE;
194         if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
195                 inode->i_flags |= S_IUNLINK;
196         else
197                 inode->i_flags &= ~S_IUNLINK;
198         if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
199                 inode->i_flags |= S_BARRIER;
200         else
201                 inode->i_flags &= ~S_BARRIER;
202         if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
203                 inode->i_flags |= S_APPEND;
204         else
205                 inode->i_flags &= ~S_APPEND;
206         if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
207                 inode->i_flags |= S_SYNC;
208         else
209                 inode->i_flags &= ~S_SYNC;
210         if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
211                 inode->i_flags |= S_NOATIME;
212         else
213                 inode->i_flags &= ~S_NOATIME;
214         vp->v_flag &= ~VMODIFIED;
215 }
216
217 void
218 xfs_initialize_vnode(
219         bhv_desc_t              *bdp,
220         vnode_t                 *vp,
221         bhv_desc_t              *inode_bhv,
222         int                     unlock)
223 {
224         xfs_inode_t             *ip = XFS_BHVTOI(inode_bhv);
225         struct inode            *inode = LINVFS_GET_IP(vp);
226
227         if (!inode_bhv->bd_vobj) {
228                 vp->v_vfsp = bhvtovfs(bdp);
229                 bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops);
230                 bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
231         }
232
233         vp->v_type = IFTOVT(ip->i_d.di_mode);
234
235         /* Have we been called during the new inode create process,
236          * in which case we are too early to fill in the Linux inode.
237          */
238         if (vp->v_type == VNON)
239                 return;
240
241         xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
242
243         /* For new inodes we need to set the ops vectors,
244          * and unlock the inode.
245          */
246         if (unlock && (inode->i_state & I_NEW)) {
247                 xfs_set_inodeops(inode);
248                 unlock_new_inode(inode);
249         }
250 }
251
252 void
253 xfs_flush_inode(
254         xfs_inode_t     *ip)
255 {
256         struct inode    *inode = LINVFS_GET_IP(XFS_ITOV(ip));
257
258         filemap_flush(inode->i_mapping);
259 }
260
261 void
262 xfs_flush_device(
263         xfs_inode_t     *ip)
264 {
265         sync_blockdev(XFS_ITOV(ip)->v_vfsp->vfs_super->s_bdev);
266         xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
267 }
268
269 int
270 xfs_blkdev_get(
271         xfs_mount_t             *mp,
272         const char              *name,
273         struct block_device     **bdevp)
274 {
275         int                     error = 0;
276
277         *bdevp = open_bdev_excl(name, 0, mp);
278         if (IS_ERR(*bdevp)) {
279                 error = PTR_ERR(*bdevp);
280                 printk("XFS: Invalid device [%s], error=%d\n", name, error);
281         }
282
283         return -error;
284 }
285
286 void
287 xfs_blkdev_put(
288         struct block_device     *bdev)
289 {
290         if (bdev)
291                 close_bdev_excl(bdev);
292 }
293
294
295 STATIC struct inode *
296 linvfs_alloc_inode(
297         struct super_block      *sb)
298 {
299         vnode_t                 *vp;
300
301         vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_zone, 
302                 kmem_flags_convert(KM_SLEEP));
303         if (!vp)
304                 return NULL;
305         return LINVFS_GET_IP(vp);
306 }
307
308 STATIC void
309 linvfs_destroy_inode(
310         struct inode            *inode)
311 {
312         kmem_cache_free(linvfs_inode_zone, LINVFS_GET_VP(inode));
313 }
314
315 int
316 xfs_inode_shake(
317         int             priority,
318         unsigned int    gfp_mask)
319 {
320         int             pages;
321
322         
323         pages = kmem_zone_shrink(linvfs_inode_zone);
324         pages += kmem_zone_shrink(xfs_inode_zone);
325         return pages;
326 }
327
328 STATIC void
329 init_once(
330         void                    *data,
331         kmem_cache_t            *cachep,
332         unsigned long           flags)
333 {
334         vnode_t                 *vp = (vnode_t *)data;
335
336         if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
337             SLAB_CTOR_CONSTRUCTOR)
338                 inode_init_once(LINVFS_GET_IP(vp));
339 }
340
341 STATIC int
342 init_inodecache( void )
343 {
344         linvfs_inode_zone = kmem_cache_create("linvfs_icache",
345                                 sizeof(vnode_t), 0,
346                                 SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
347                                 init_once, NULL);
348
349         if (linvfs_inode_zone == NULL)
350                 return -ENOMEM;
351         return 0;
352 }
353
354 STATIC void
355 destroy_inodecache( void )
356 {
357         if (kmem_cache_destroy(linvfs_inode_zone))
358                 printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__);
359 }
360
361 /*
362  * Attempt to flush the inode, this will actually fail
363  * if the inode is pinned, but we dirty the inode again
364  * at the point when it is unpinned after a log write,
365  * since this is when the inode itself becomes flushable. 
366  */
367 STATIC void
368 linvfs_write_inode(
369         struct inode            *inode,
370         int                     sync)
371 {
372         vnode_t                 *vp = LINVFS_GET_VP(inode);
373         int                     error, flags = FLUSH_INODE;
374
375         if (vp) {
376                 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
377                 if (sync)
378                         flags |= FLUSH_SYNC;
379                 VOP_IFLUSH(vp, flags, error);
380         }
381 }
382
383 STATIC void
384 linvfs_clear_inode(
385         struct inode            *inode)
386 {
387         vnode_t                 *vp = LINVFS_GET_VP(inode);
388
389         if (vp) {
390                 vn_rele(vp);
391                 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
392                 /*
393                  * Do all our cleanup, and remove this vnode.
394                  */
395                 vn_remove(vp);
396         }
397 }
398
399
400 #define SYNCD_FLAGS     (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR)
401
402 STATIC int
403 xfssyncd(
404         void                    *arg)
405 {
406         vfs_t                   *vfsp = (vfs_t *) arg;
407         int                     error;
408
409         daemonize("xfssyncd");
410
411         vfsp->vfs_sync_task = current;
412         wmb();
413         wake_up(&vfsp->vfs_wait_sync_task);
414
415         for (;;) {
416                 set_current_state(TASK_INTERRUPTIBLE);
417                 schedule_timeout((xfs_syncd_centisecs * HZ) / 100);
418                 /* swsusp */
419                 if (current->flags & PF_FREEZE)
420                         refrigerator(PF_FREEZE);
421                 if (vfsp->vfs_flag & VFS_UMOUNT)
422                         break;
423                 if (vfsp->vfs_flag & VFS_RDONLY)
424                         continue;
425                 VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
426
427                 vfsp->vfs_sync_seq++;
428                 wmb();
429                 wake_up(&vfsp->vfs_wait_single_sync_task);
430         }
431
432         vfsp->vfs_sync_task = NULL;
433         wmb();
434         wake_up(&vfsp->vfs_wait_sync_task);
435
436         return 0;
437 }
438
439 STATIC int
440 linvfs_start_syncd(
441         vfs_t                   *vfsp)
442 {
443         int                     pid;
444
445         pid = kernel_thread(xfssyncd, (void *) vfsp,
446                         CLONE_VM | CLONE_FS | CLONE_FILES);
447         if (pid < 0)
448                 return -pid;
449         wait_event(vfsp->vfs_wait_sync_task, vfsp->vfs_sync_task);
450         return 0;
451 }
452
453 STATIC void
454 linvfs_stop_syncd(
455         vfs_t                   *vfsp)
456 {
457         vfsp->vfs_flag |= VFS_UMOUNT;
458         wmb();
459
460         wake_up_process(vfsp->vfs_sync_task);
461         wait_event(vfsp->vfs_wait_sync_task, !vfsp->vfs_sync_task);
462 }
463
464 STATIC void
465 linvfs_put_super(
466         struct super_block      *sb)
467 {
468         vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
469         int                     error;
470
471         linvfs_stop_syncd(vfsp);
472         VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
473         if (!error)
474                 VFS_UNMOUNT(vfsp, 0, NULL, error);
475         if (error) {
476                 printk("XFS unmount got error %d\n", error);
477                 printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
478                 return;
479         }
480
481         vfs_deallocate(vfsp);
482 }
483
484 STATIC void
485 linvfs_write_super(
486         struct super_block      *sb)
487 {
488         vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
489         int                     error;
490
491         if (sb->s_flags & MS_RDONLY) {
492                 sb->s_dirt = 0; /* paranoia */
493                 return;
494         }
495         /* Push the log and superblock a little */
496         VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
497         sb->s_dirt = 0;
498 }
499
500 STATIC int
501 linvfs_sync_super(
502         struct super_block      *sb,
503         int                     wait)
504 {
505         vfs_t           *vfsp = LINVFS_GET_VFS(sb);
506         int             error;
507         int             flags = SYNC_FSDATA;
508
509         if (wait)
510                 flags |= SYNC_WAIT;
511
512         VFS_SYNC(vfsp, flags, NULL, error);
513         sb->s_dirt = 0;
514
515         if (unlikely(laptop_mode)) {
516                 int     prev_sync_seq = vfsp->vfs_sync_seq;
517                 /*
518                  * The disk must be active because we're syncing.
519                  * We schedule syncd now (now that the disk is
520                  * active) instead of later (when it might not be).
521                  */
522                 wake_up_process(vfsp->vfs_sync_task);
523                 /*
524                  * We have to wait for the sync iteration to complete.
525                  * If we don't, the disk activity caused by the sync
526                  * will come after the sync is completed, and that
527                  * triggers another sync from laptop mode.
528                  */
529                 wait_event(vfsp->vfs_wait_single_sync_task,
530                                 vfsp->vfs_sync_seq != prev_sync_seq);
531         }
532
533         return -error;
534 }
535
536 STATIC int
537 linvfs_statfs(
538         struct super_block      *sb,
539         struct kstatfs          *statp)
540 {
541         vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
542         int                     error;
543
544         VFS_STATVFS(vfsp, statp, NULL, error);
545         return -error;
546 }
547
548 STATIC int
549 linvfs_remount(
550         struct super_block      *sb,
551         int                     *flags,
552         char                    *options)
553 {
554         vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
555         struct xfs_mount_args   *args = xfs_args_allocate(sb);
556         int                     error;
557
558         VFS_PARSEARGS(vfsp, options, args, 1, error);
559         if (!error)
560                 VFS_MNTUPDATE(vfsp, flags, args, error);
561         kmem_free(args, sizeof(*args));
562         return -error;
563 }
564
565 STATIC void
566 linvfs_freeze_fs(
567         struct super_block      *sb)
568 {
569         VFS_FREEZE(LINVFS_GET_VFS(sb));
570 }
571
572 STATIC struct dentry *
573 linvfs_get_parent(
574         struct dentry           *child)
575 {
576         int                     error;
577         vnode_t                 *vp, *cvp;
578         struct dentry           *parent;
579         struct inode            *ip = NULL;
580         struct dentry           dotdot;
581
582         dotdot.d_name.name = "..";
583         dotdot.d_name.len = 2;
584         dotdot.d_inode = 0;
585
586         cvp = NULL;
587         vp = LINVFS_GET_VP(child->d_inode);
588         VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
589
590         if (!error) {
591                 ASSERT(cvp);
592                 ip = LINVFS_GET_IP(cvp);
593                 if (!ip) {
594                         VN_RELE(cvp);
595                         return ERR_PTR(-EACCES);
596                 }
597         }
598         if (error)
599                 return ERR_PTR(-error);
600         parent = d_alloc_anon(ip);
601         if (!parent) {
602                 VN_RELE(cvp);
603                 parent = ERR_PTR(-ENOMEM);
604         }
605         return parent;
606 }
607
608 STATIC struct dentry *
609 linvfs_get_dentry(
610         struct super_block      *sb,
611         void                    *data)
612 {
613         vnode_t                 *vp;
614         struct inode            *inode;
615         struct dentry           *result;
616         xfs_fid2_t              xfid;
617         vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
618         int                     error;
619
620         xfid.fid_len = sizeof(xfs_fid2_t) - sizeof(xfid.fid_len);
621         xfid.fid_pad = 0;
622         xfid.fid_gen = ((__u32 *)data)[1];
623         xfid.fid_ino = ((__u32 *)data)[0];
624
625         VFS_VGET(vfsp, &vp, (fid_t *)&xfid, error);
626         if (error || vp == NULL)
627                 return ERR_PTR(-ESTALE) ;
628
629         inode = LINVFS_GET_IP(vp);
630         result = d_alloc_anon(inode);
631         if (!result) {
632                 iput(inode);
633                 return ERR_PTR(-ENOMEM);
634         }
635         return result;
636 }
637
638 STATIC int
639 linvfs_show_options(
640         struct seq_file         *m,
641         struct vfsmount         *mnt)
642 {
643         struct vfs              *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
644         int                     error;
645
646         VFS_SHOWARGS(vfsp, m, error);
647         return error;
648 }
649
650 STATIC int
651 linvfs_getxstate(
652         struct super_block      *sb,
653         struct fs_quota_stat    *fqs)
654 {
655         struct vfs              *vfsp = LINVFS_GET_VFS(sb);
656         int                     error;
657
658         VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
659         return -error;
660 }
661
662 STATIC int
663 linvfs_setxstate(
664         struct super_block      *sb,
665         unsigned int            flags,
666         int                     op)
667 {
668         struct vfs              *vfsp = LINVFS_GET_VFS(sb);
669         int                     error;
670
671         VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
672         return -error;
673 }
674
675 STATIC int
676 linvfs_getxquota(
677         struct super_block      *sb,
678         int                     type,
679         qid_t                   id,
680         struct fs_disk_quota    *fdq)
681 {
682         struct vfs              *vfsp = LINVFS_GET_VFS(sb);
683         int                     error, getmode;
684
685         getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
686         VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
687         return -error;
688 }
689
690 STATIC int
691 linvfs_setxquota(
692         struct super_block      *sb,
693         int                     type,
694         qid_t                   id,
695         struct fs_disk_quota    *fdq)
696 {
697         struct vfs              *vfsp = LINVFS_GET_VFS(sb);
698         int                     error, setmode;
699
700         setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
701         VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
702         return -error;
703 }
704
705 STATIC int
706 linvfs_fill_super(
707         struct super_block      *sb,
708         void                    *data,
709         int                     silent)
710 {
711         vnode_t                 *rootvp;
712         struct vfs              *vfsp = vfs_allocate();
713         struct xfs_mount_args   *args = xfs_args_allocate(sb);
714         struct kstatfs          statvfs;
715         int                     error, error2;
716
717         vfsp->vfs_super = sb;
718         LINVFS_SET_VFS(sb, vfsp);
719         if (sb->s_flags & MS_RDONLY)
720                 vfsp->vfs_flag |= VFS_RDONLY;
721         bhv_insert_all_vfsops(vfsp);
722
723         VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
724         if (error) {
725                 bhv_remove_all_vfsops(vfsp, 1);
726                 goto fail_vfsop;
727         }
728
729         sb_min_blocksize(sb, BBSIZE);
730         sb->s_export_op = &linvfs_export_ops;
731         sb->s_qcop = &linvfs_qops;
732         sb->s_op = &linvfs_sops;
733
734         VFS_MOUNT(vfsp, args, NULL, error);
735         if (error) {
736                 bhv_remove_all_vfsops(vfsp, 1);
737                 goto fail_vfsop;
738         }
739
740         VFS_STATVFS(vfsp, &statvfs, NULL, error);
741         if (error)
742                 goto fail_unmount;
743
744         sb->s_dirt = 1;
745         sb->s_magic = statvfs.f_type;
746         sb->s_blocksize = statvfs.f_bsize;
747         sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
748         sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
749         set_posix_acl_flag(sb);
750
751         VFS_ROOT(vfsp, &rootvp, error);
752         if (error)
753                 goto fail_unmount;
754
755         sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp));
756         if (!sb->s_root) {
757                 error = ENOMEM;
758                 goto fail_vnrele;
759         }
760         if (is_bad_inode(sb->s_root->d_inode)) {
761                 error = EINVAL;
762                 goto fail_vnrele;
763         }
764         if ((error = linvfs_start_syncd(vfsp)))
765                 goto fail_vnrele;
766         vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
767
768         kmem_free(args, sizeof(*args));
769         return 0;
770
771 fail_vnrele:
772         if (sb->s_root) {
773                 dput(sb->s_root);
774                 sb->s_root = NULL;
775         } else {
776                 VN_RELE(rootvp);
777         }
778
779 fail_unmount:
780         VFS_UNMOUNT(vfsp, 0, NULL, error2);
781
782 fail_vfsop:
783         vfs_deallocate(vfsp);
784         kmem_free(args, sizeof(*args));
785         return -error;
786 }
787
788 STATIC struct super_block *
789 linvfs_get_sb(
790         struct file_system_type *fs_type,
791         int                     flags,
792         const char              *dev_name,
793         void                    *data)
794 {
795         return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super);
796 }
797
798
799 STATIC struct export_operations linvfs_export_ops = {
800         .get_parent             = linvfs_get_parent,
801         .get_dentry             = linvfs_get_dentry,
802 };
803
804 STATIC struct super_operations linvfs_sops = {
805         .alloc_inode            = linvfs_alloc_inode,
806         .destroy_inode          = linvfs_destroy_inode,
807         .write_inode            = linvfs_write_inode,
808         .clear_inode            = linvfs_clear_inode,
809         .put_super              = linvfs_put_super,
810         .write_super            = linvfs_write_super,
811         .sync_fs                = linvfs_sync_super,
812         .write_super_lockfs     = linvfs_freeze_fs,
813         .statfs                 = linvfs_statfs,
814         .remount_fs             = linvfs_remount,
815         .show_options           = linvfs_show_options,
816 };
817
818 STATIC struct quotactl_ops linvfs_qops = {
819         .get_xstate             = linvfs_getxstate,
820         .set_xstate             = linvfs_setxstate,
821         .get_xquota             = linvfs_getxquota,
822         .set_xquota             = linvfs_setxquota,
823 };
824
825 STATIC struct file_system_type xfs_fs_type = {
826         .owner                  = THIS_MODULE,
827         .name                   = "xfs",
828         .get_sb                 = linvfs_get_sb,
829         .kill_sb                = kill_block_super,
830         .fs_flags               = FS_REQUIRES_DEV,
831 };
832
833
834 STATIC int __init
835 init_xfs_fs( void )
836 {
837         int                     error;
838         struct sysinfo          si;
839         static char             message[] __initdata = KERN_INFO \
840                 XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
841
842         printk(message);
843
844         si_meminfo(&si);
845         xfs_physmem = si.totalram;
846
847         ktrace_init(64);
848
849         error = init_inodecache();
850         if (error < 0)
851                 goto undo_inodecache;
852
853         error = pagebuf_init();
854         if (error < 0)
855                 goto undo_pagebuf;
856
857         vn_init();
858         xfs_init();
859         uuid_init();
860         vfs_initquota();
861
862         xfs_inode_shaker = kmem_shake_register(xfs_inode_shake);
863         if (!xfs_inode_shaker) {
864                 error = -ENOMEM;
865                 goto undo_shaker;
866         }
867
868         error = register_filesystem(&xfs_fs_type);
869         if (error)
870                 goto undo_register;
871         XFS_DM_INIT(&xfs_fs_type);
872         return 0;
873
874 undo_register:
875         kmem_shake_deregister(xfs_inode_shaker);
876
877 undo_shaker:
878         pagebuf_terminate();
879
880 undo_pagebuf:
881         destroy_inodecache();
882
883 undo_inodecache:
884         return error;
885 }
886
887 STATIC void __exit
888 exit_xfs_fs( void )
889 {
890         vfs_exitquota();
891         XFS_DM_EXIT(&xfs_fs_type);
892         unregister_filesystem(&xfs_fs_type);
893         kmem_shake_deregister(xfs_inode_shaker);
894         xfs_cleanup();
895         pagebuf_terminate();
896         destroy_inodecache();
897         ktrace_uninit();
898 }
899
900 module_init(init_xfs_fs);
901 module_exit(exit_xfs_fs);
902
903 MODULE_AUTHOR("Silicon Graphics, Inc.");
904 MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled");
905 MODULE_LICENSE("GPL");