1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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/init.h>
71
72STATIC struct quotactl_ops linvfs_qops;
73STATIC struct super_operations linvfs_sops;
74STATIC kmem_zone_t *linvfs_inode_zone;
75STATIC kmem_shaker_t xfs_inode_shaker;
76
77STATIC struct xfs_mount_args *
78xfs_args_allocate(
79 struct super_block *sb)
80{
81 struct xfs_mount_args *args;
82
83 args = kmem_zalloc(sizeof(struct xfs_mount_args), KM_SLEEP);
84 args->logbufs = args->logbufsize = -1;
85 strncpy(args->fsname, bdevname(sb->s_dev), MAXNAMELEN);
86
87
88 if (sb->s_flags & MS_NOATIME)
89 args->flags |= XFSMNT_NOATIME;
90
91
92 args->flags |= XFSMNT_32BITINODES;
93
94 return args;
95}
96
97__uint64_t
98xfs_max_file_offset(
99 unsigned int blockshift)
100{
101 unsigned int pagefactor = 1;
102 unsigned int bitshift = BITS_PER_LONG - 1;
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118#if BITS_PER_LONG == 32
119 pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
120#endif
121
122 return (((__uint64_t)pagefactor) << bitshift) - 1;
123}
124
125STATIC __inline__ void
126xfs_set_inodeops(
127 struct inode *inode)
128{
129 vnode_t *vp = LINVFS_GET_VP(inode);
130
131 if (vp->v_type == VNON) {
132 remove_inode_hash(inode);
133 make_bad_inode(inode);
134 } else if (S_ISREG(inode->i_mode)) {
135 inode->i_op = &linvfs_file_inode_operations;
136 inode->i_fop = &linvfs_file_operations;
137 inode->i_mapping->a_ops = &linvfs_aops;
138 } else if (S_ISDIR(inode->i_mode)) {
139 inode->i_op = &linvfs_dir_inode_operations;
140 inode->i_fop = &linvfs_dir_operations;
141 } else if (S_ISLNK(inode->i_mode)) {
142 inode->i_op = &linvfs_symlink_inode_operations;
143 if (inode->i_blocks)
144 inode->i_mapping->a_ops = &linvfs_aops;
145 } else {
146 inode->i_op = &linvfs_file_inode_operations;
147 init_special_inode(inode, inode->i_mode,
148 kdev_t_to_nr(inode->i_rdev));
149 }
150}
151
152STATIC __inline__ void
153xfs_revalidate_inode(
154 xfs_mount_t *mp,
155 vnode_t *vp,
156 xfs_inode_t *ip)
157{
158 struct inode *inode = LINVFS_GET_IP(vp);
159
160 inode->i_mode = (ip->i_d.di_mode & MODEMASK) | VTTOIF(vp->v_type);
161 inode->i_nlink = ip->i_d.di_nlink;
162 inode->i_uid = ip->i_d.di_uid;
163 inode->i_gid = ip->i_d.di_gid;
164 if (((1 << vp->v_type) & ((1<<VBLK) | (1<<VCHR))) == 0) {
165 inode->i_rdev = NODEV;
166 } else {
167 xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
168 inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
169 }
170 inode->i_blksize = PAGE_CACHE_SIZE;
171 inode->i_generation = ip->i_d.di_gen;
172 i_size_write(inode, ip->i_d.di_size);
173 inode->i_blocks =
174 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
175 inode->i_atime = ip->i_d.di_atime.t_sec;
176 inode->i_mtime = ip->i_d.di_mtime.t_sec;
177 inode->i_ctime = ip->i_d.di_ctime.t_sec;
178 if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
179 inode->i_flags |= S_IMMUTABLE;
180 else
181 inode->i_flags &= ~S_IMMUTABLE;
182 if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
183 inode->i_flags |= S_APPEND;
184 else
185 inode->i_flags &= ~S_APPEND;
186 if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
187 inode->i_flags |= S_SYNC;
188 else
189 inode->i_flags &= ~S_SYNC;
190 if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
191 inode->i_flags |= S_NOATIME;
192 else
193 inode->i_flags &= ~S_NOATIME;
194
195 vp->v_flag &= ~VMODIFIED;
196}
197
198void
199xfs_initialize_vnode(
200 bhv_desc_t *bdp,
201 vnode_t *vp,
202 bhv_desc_t *inode_bhv,
203 int unlock)
204{
205 xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
206 struct inode *inode = LINVFS_GET_IP(vp);
207
208 if (!inode_bhv->bd_vobj) {
209 vp->v_vfsp = bhvtovfs(bdp);
210 bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops);
211 bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
212 }
213
214 vp->v_type = IFTOVT(ip->i_d.di_mode);
215
216
217
218
219 if (vp->v_type == VNON)
220 return;
221
222 xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
223
224
225
226
227 if (unlock && (inode->i_state & I_NEW)) {
228 xfs_set_inodeops(inode);
229 unlock_new_inode(inode);
230 }
231}
232
233int
234xfs_inode_shake(
235 int priority,
236 unsigned int gfp_mask)
237{
238 int pages;
239
240 pages = kmem_zone_shrink(linvfs_inode_zone);
241 pages += kmem_zone_shrink(xfs_inode_zone);
242 return pages;
243}
244
245struct inode *
246xfs_get_inode(
247 bhv_desc_t *bdp,
248 xfs_ino_t ino,
249 int flags)
250{
251 struct vfs *vfsp = bhvtovfs(bdp);
252
253 return iget_locked(vfsp->vfs_super, ino);
254}
255
256void
257xfs_flush_inode(
258 xfs_inode_t *ip)
259{
260 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
261
262 filemap_fdatawrite(inode->i_mapping);
263}
264
265void
266xfs_flush_device(
267 xfs_inode_t *ip)
268{
269 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
270
271 fsync_no_super(inode->i_dev);
272 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
273}
274
275struct dentry *
276d_alloc_anon(struct inode *inode)
277{
278 struct dentry *dentry;
279
280 spin_lock(&dcache_lock);
281 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
282 if (!(dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
283 goto found;
284 }
285 spin_unlock(&dcache_lock);
286
287 dentry = d_alloc_root(inode);
288 if (likely(dentry != NULL))
289 dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
290 return dentry;
291 found:
292 dget_locked(dentry);
293 dentry->d_vfs_flags |= DCACHE_REFERENCED;
294 spin_unlock(&dcache_lock);
295 iput(inode);
296 return dentry;
297}
298
299
300int
301xfs_blkdev_get(
302 xfs_mount_t *mp,
303 const char *name,
304 struct block_device **bdevp)
305{
306 struct nameidata nd;
307 int error;
308
309 error = path_lookup(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd);
310 if (error) {
311 printk("XFS: Invalid device [%s], error=%d\n", name, error);
312 return -error;
313 }
314
315
316 *bdevp = bdget(kdev_t_to_nr(nd.dentry->d_inode->i_rdev));
317 if (*bdevp)
318 error = blkdev_get(*bdevp, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
319 else
320 error = -ENOMEM;
321
322 path_release(&nd);
323 return -error;
324}
325
326void
327xfs_blkdev_put(
328 struct block_device *bdev)
329{
330 if (bdev)
331 blkdev_put(bdev, BDEV_FS);
332}
333
334STATIC struct inode *
335linvfs_alloc_inode(
336 struct super_block *sb)
337{
338 vnode_t *vp;
339
340 vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_zone,
341 kmem_flags_convert(KM_SLEEP));
342 if (!vp)
343 return NULL;
344 return LINVFS_GET_IP(vp);
345}
346
347STATIC void
348linvfs_destroy_inode(
349 struct inode *inode)
350{
351 kmem_cache_free(linvfs_inode_zone, LINVFS_GET_VP(inode));
352}
353
354#define VNODE_SIZE \
355 (sizeof(vnode_t) - sizeof(struct inode) + offsetof(struct inode, u))
356
357STATIC void
358init_once(
359 void *data,
360 kmem_cache_t *cachep,
361 unsigned long flags)
362{
363 vnode_t *vp = (vnode_t *)data;
364
365 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
366 SLAB_CTOR_CONSTRUCTOR) {
367 struct inode *inode = LINVFS_GET_IP(vp);
368 memset(vp, 0, VNODE_SIZE);
369 __inode_init_once(inode);
370 }
371}
372
373STATIC int
374init_inodecache( void )
375{
376 linvfs_inode_zone = kmem_cache_create("linvfs_icache",
377 VNODE_SIZE, 0, SLAB_HWCACHE_ALIGN,
378 init_once, NULL);
379 if (linvfs_inode_zone == NULL)
380 return -ENOMEM;
381 return 0;
382}
383
384STATIC void
385destroy_inodecache( void )
386{
387 if (kmem_cache_destroy(linvfs_inode_zone))
388 printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__);
389}
390
391
392
393
394
395
396
397STATIC void
398linvfs_write_inode(
399 struct inode *inode,
400 int sync)
401{
402 vnode_t *vp = LINVFS_GET_VP(inode);
403 int error, flags = FLUSH_INODE;
404
405 if (vp) {
406 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
407 if (sync)
408 flags |= FLUSH_SYNC;
409 VOP_IFLUSH(vp, flags, error);
410 }
411}
412
413STATIC void
414linvfs_clear_inode(
415 struct inode *inode)
416{
417 vnode_t *vp = LINVFS_GET_VP(inode);
418
419 if (vp) {
420 vn_rele(vp);
421 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
422
423
424
425 vn_remove(vp);
426 }
427}
428
429
430#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
431
432STATIC int
433xfssyncd(
434 void *arg)
435{
436 vfs_t *vfsp = (vfs_t *) arg;
437 int error;
438
439 daemonize();
440 reparent_to_init();
441 sigmask_lock();
442 sigfillset(¤t->blocked);
443 __recalc_sigpending(current);
444 sigmask_unlock();
445
446 sprintf(current->comm, "xfssyncd");
447
448 vfsp->vfs_sync_task = current;
449 wmb();
450 wake_up(&vfsp->vfs_wait_sync_task);
451
452 for (;;) {
453 set_current_state(TASK_INTERRUPTIBLE);
454 schedule_timeout((xfs_syncd_centisecs * HZ) / 100);
455 if (vfsp->vfs_flag & VFS_UMOUNT)
456 break;
457 if (vfsp->vfs_flag & VFS_RDONLY)
458 continue;
459 VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
460 }
461
462 vfsp->vfs_sync_task = NULL;
463 wmb();
464 wake_up(&vfsp->vfs_wait_sync_task);
465
466 return 0;
467}
468
469STATIC int
470linvfs_start_syncd(
471 vfs_t *vfsp)
472{
473 int pid;
474
475 pid = kernel_thread(xfssyncd, (void *) vfsp,
476 CLONE_VM | CLONE_FS | CLONE_FILES);
477 if (pid < 0)
478 return pid;
479 wait_event(vfsp->vfs_wait_sync_task, vfsp->vfs_sync_task);
480 return 0;
481}
482
483STATIC void
484linvfs_stop_syncd(
485 vfs_t *vfsp)
486{
487 vfsp->vfs_flag |= VFS_UMOUNT;
488 wmb();
489
490 wake_up_process(vfsp->vfs_sync_task);
491 wait_event(vfsp->vfs_wait_sync_task, !vfsp->vfs_sync_task);
492}
493
494STATIC void
495linvfs_put_super(
496 struct super_block *sb)
497{
498 vfs_t *vfsp = LINVFS_GET_VFS(sb);
499 int error;
500
501 linvfs_stop_syncd(vfsp);
502 VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
503 if (!error)
504 VFS_UNMOUNT(vfsp, 0, NULL, error);
505 if (error) {
506 printk("XFS unmount got error %d\n", error);
507 printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
508 return;
509 }
510
511 vfs_deallocate(vfsp);
512}
513
514STATIC void
515linvfs_write_super(
516 struct super_block *sb)
517{
518 vfs_t *vfsp = LINVFS_GET_VFS(sb);
519 int error;
520
521 if (sb->s_flags & MS_RDONLY) {
522 sb->s_dirt = 0;
523 return;
524 }
525
526 VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
527 sb->s_dirt = 0;
528}
529
530STATIC int
531linvfs_sync_super(
532 struct super_block *sb)
533{
534 vfs_t *vfsp = LINVFS_GET_VFS(sb);
535 int error;
536
537 VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_WAIT, NULL, error);
538 sb->s_dirt = 0;
539 return -error;
540}
541
542STATIC int
543linvfs_statfs(
544 struct super_block *sb,
545 struct statfs *statp)
546{
547 vfs_t *vfsp = LINVFS_GET_VFS(sb);
548 int error;
549
550 VFS_STATVFS(vfsp, statp, NULL, error);
551 return -error;
552}
553
554STATIC int
555linvfs_remount(
556 struct super_block *sb,
557 int *flags,
558 char *options)
559{
560 vfs_t *vfsp = LINVFS_GET_VFS(sb);
561 struct xfs_mount_args *args = xfs_args_allocate(sb);
562 int error;
563
564 VFS_PARSEARGS(vfsp, options, args, 1, error);
565 if (!error)
566 VFS_MNTUPDATE(vfsp, flags, args, error);
567 kmem_free(args, sizeof(*args));
568 return -error;
569}
570
571struct super_block *freeze_bdev(struct block_device *bdev)
572{
573 struct super_block *sb;
574 struct vfs *vfsp;
575 int error;
576
577 sb = get_super(to_kdev_t(bdev->bd_dev));
578 if (sb && !(sb->s_flags & MS_RDONLY)) {
579 vfsp = LINVFS_GET_VFS(sb);
580
581
582 vfsp->vfs_frozen = SB_FREEZE_WRITE;
583 wmb();
584
585
586 VFS_SYNC(vfsp, SYNC_REFCACHE|SYNC_WAIT, NULL, error);
587
588
589 VFS_SYNC(vfsp, SYNC_DELWRI|SYNC_WAIT, NULL, error);
590
591
592 vfsp->vfs_frozen = SB_FREEZE_TRANS;
593 wmb();
594
595
596 VFS_SYNC(vfsp, SYNC_ATTR|SYNC_WAIT, NULL, error);
597
598
599 sync_buffers(sb->s_dev, 1);
600
601
602 VFS_FREEZE(vfsp);
603 }
604
605 sync_buffers(to_kdev_t(bdev->bd_dev), 1);
606 return sb;
607}
608
609void thaw_bdev(struct block_device *bdev, struct super_block *sb)
610{
611 if (sb) {
612 struct vfs *vfsp = LINVFS_GET_VFS(sb);
613
614 BUG_ON(sb->s_bdev != bdev);
615
616 vfsp->vfs_frozen = SB_UNFROZEN;
617 wmb();
618 wake_up(&vfsp->vfs_wait_unfrozen);
619
620 drop_super(sb);
621 }
622}
623
624STATIC void
625linvfs_freeze_fs(
626 struct super_block *sb)
627{
628 if (sb->s_flags & MS_RDONLY)
629 return;
630 freeze_bdev(sb->s_bdev);
631}
632
633STATIC void
634linvfs_unfreeze_fs(
635 struct super_block *sb)
636{
637 thaw_bdev(sb->s_bdev, sb);
638}
639
640STATIC int
641linvfs_dentry_to_fh(
642 struct dentry *dentry,
643 __u32 *data,
644 int *lenp,
645 int need_parent)
646{
647 struct inode *inode = dentry->d_inode ;
648 vnode_t *vp = LINVFS_GET_VP(inode);
649 int maxlen = *lenp;
650 xfs_fid2_t fid;
651 int error;
652
653 if (maxlen < 3)
654 return 255 ;
655
656 VOP_FID2(vp, (struct fid *)&fid, error);
657 data[0] = (__u32)fid.fid_ino;
658 data[1] = fid.fid_gen;
659
660 *lenp = 2 ;
661 if (maxlen < 4 || ! need_parent)
662 return 2 ;
663
664 inode = dentry->d_parent->d_inode ;
665 vp = LINVFS_GET_VP(inode);
666
667 VOP_FID2(vp, (struct fid *)&fid, error);
668 data[2] = (__u32)fid.fid_ino;
669 *lenp = 3 ;
670 if (maxlen < 4)
671 return 3 ;
672 data[3] = fid.fid_gen;
673 *lenp = 4 ;
674 return 4 ;
675}
676
677STATIC struct dentry *
678linvfs_fh_to_dentry(
679 struct super_block *sb,
680 __u32 *data,
681 int len,
682 int fhtype,
683 int parent)
684{
685 vnode_t *vp;
686 struct inode *inode = NULL;
687 struct dentry *result;
688 xfs_fid2_t xfid;
689 vfs_t *vfsp = LINVFS_GET_VFS(sb);
690 int error;
691
692 xfid.fid_len = sizeof(xfs_fid2_t) - sizeof(xfid.fid_len);
693 xfid.fid_pad = 0;
694
695 if (!parent) {
696 xfid.fid_gen = data[1];
697 xfid.fid_ino = (__u64)data[0];
698 } else {
699 if (fhtype == 4)
700 xfid.fid_gen = data[3];
701 else
702 xfid.fid_gen = 0;
703 xfid.fid_ino = (__u64)data[2];
704 }
705
706 VFS_VGET(vfsp, &vp, (fid_t *)&xfid, error);
707 if (error || vp == NULL)
708 return ERR_PTR(-ESTALE) ;
709
710 inode = LINVFS_GET_IP(vp);
711
712 result = d_alloc_anon(inode);
713 if (unlikely(result == NULL)) {
714 iput(inode);
715 return ERR_PTR(-ENOMEM);
716 }
717 return result;
718}
719
720STATIC int
721linvfs_show_options(
722 struct seq_file *m,
723 struct vfsmount *mnt)
724{
725 struct vfs *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
726 int error;
727
728 VFS_SHOWARGS(vfsp, m, error);
729 return error;
730}
731
732STATIC int
733linvfs_getxstate(
734 struct super_block *sb,
735 struct fs_quota_stat *fqs)
736{
737 struct vfs *vfsp = LINVFS_GET_VFS(sb);
738 int error;
739
740 VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
741 return -error;
742}
743
744STATIC int
745linvfs_setxstate(
746 struct super_block *sb,
747 unsigned int flags,
748 int op)
749{
750 struct vfs *vfsp = LINVFS_GET_VFS(sb);
751 int error;
752
753 VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
754 return -error;
755}
756
757STATIC int
758linvfs_getxquota(
759 struct super_block *sb,
760 int type,
761 qid_t id,
762 struct fs_disk_quota *fdq)
763{
764 struct vfs *vfsp = LINVFS_GET_VFS(sb);
765 int error, getmode;
766
767 getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
768 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
769 return -error;
770}
771
772STATIC int
773linvfs_setxquota(
774 struct super_block *sb,
775 int type,
776 qid_t id,
777 struct fs_disk_quota *fdq)
778{
779 struct vfs *vfsp = LINVFS_GET_VFS(sb);
780 int error, setmode;
781
782 setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
783 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
784 return -error;
785}
786
787STATIC struct super_block *
788linvfs_read_super(
789 struct super_block *sb,
790 void *data,
791 int silent)
792{
793 vnode_t *rootvp;
794 struct vfs *vfsp = vfs_allocate();
795 struct xfs_mount_args *args = xfs_args_allocate(sb);
796 struct statfs statvfs;
797 int error;
798
799 vfsp->vfs_super = sb;
800 LINVFS_SET_VFS(sb, vfsp);
801 if (sb->s_flags & MS_RDONLY)
802 vfsp->vfs_flag |= VFS_RDONLY;
803 bhv_insert_all_vfsops(vfsp);
804
805 VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
806 if (error) {
807 bhv_remove_all_vfsops(vfsp, 1);
808 goto fail_vfsop;
809 }
810
811 sb_min_blocksize(sb, BBSIZE);
812 sb->s_qcop = &linvfs_qops;
813 sb->s_op = &linvfs_sops;
814
815 VFS_MOUNT(vfsp, args, NULL, error);
816 if (error) {
817 bhv_remove_all_vfsops(vfsp, 1);
818 goto fail_vfsop;
819 }
820
821 VFS_STATVFS(vfsp, &statvfs, NULL, error);
822 if (error)
823 goto fail_unmount;
824
825 sb->s_dirt = 1;
826 sb->s_magic = statvfs.f_type;
827 sb->s_blocksize = statvfs.f_bsize;
828 sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
829 sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
830 set_posix_acl_flag(sb);
831
832 VFS_ROOT(vfsp, &rootvp, error);
833 if (error)
834 goto fail_unmount;
835
836 sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp));
837 if (!sb->s_root)
838 goto fail_vnrele;
839 if (is_bad_inode(sb->s_root->d_inode))
840 goto fail_vnrele;
841 if (linvfs_start_syncd(vfsp))
842 goto fail_vnrele;
843 vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
844
845 kmem_free(args, sizeof(*args));
846 return sb;
847
848fail_vnrele:
849 if (sb->s_root) {
850 dput(sb->s_root);
851 sb->s_root = NULL;
852 } else {
853 VN_RELE(rootvp);
854 }
855
856fail_unmount:
857 VFS_UNMOUNT(vfsp, 0, NULL, error);
858
859fail_vfsop:
860 vfs_deallocate(vfsp);
861 kmem_free(args, sizeof(*args));
862 return NULL;
863}
864
865
866STATIC struct super_operations linvfs_sops = {
867 .alloc_inode = linvfs_alloc_inode,
868 .destroy_inode = linvfs_destroy_inode,
869 .write_inode = linvfs_write_inode,
870 .clear_inode = linvfs_clear_inode,
871 .put_super = linvfs_put_super,
872 .write_super = linvfs_write_super,
873 .sync_fs = linvfs_sync_super,
874 .write_super_lockfs = linvfs_freeze_fs,
875 .unlockfs = linvfs_unfreeze_fs,
876 .statfs = linvfs_statfs,
877 .remount_fs = linvfs_remount,
878 .fh_to_dentry = linvfs_fh_to_dentry,
879 .dentry_to_fh = linvfs_dentry_to_fh,
880 .show_options = linvfs_show_options,
881};
882
883STATIC struct quotactl_ops linvfs_qops = {
884 .get_xstate = linvfs_getxstate,
885 .set_xstate = linvfs_setxstate,
886 .get_xquota = linvfs_getxquota,
887 .set_xquota = linvfs_setxquota,
888};
889
890STATIC struct file_system_type xfs_fs_type = {
891 .owner = THIS_MODULE,
892 .name = "xfs",
893 .read_super = linvfs_read_super,
894 .fs_flags = FS_REQUIRES_DEV,
895};
896
897
898STATIC int __init
899init_xfs_fs( void )
900{
901 int error;
902 struct sysinfo si;
903 static char message[] __initdata = KERN_INFO \
904 XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
905
906 printk(message);
907
908 si_meminfo(&si);
909 xfs_physmem = si.totalram;
910
911 ktrace_init(64);
912
913 error = init_inodecache();
914 if (error < 0)
915 goto undo_inodecache;
916
917 error = pagebuf_init();
918 if (error < 0)
919 goto undo_pagebuf;
920
921 vn_init();
922 xfs_init();
923 uuid_init();
924 vfs_initdmapi();
925 vfs_initquota();
926
927 xfs_inode_shaker = kmem_shake_register(xfs_inode_shake);
928 if (!xfs_inode_shaker) {
929 error = -ENOMEM;
930 goto undo_shaker;
931 }
932
933 error = register_filesystem(&xfs_fs_type);
934 if (error)
935 goto undo_register;
936 XFS_DM_INIT(&xfs_fs_type);
937 return 0;
938
939undo_register:
940 kmem_shake_deregister(xfs_inode_shaker);
941
942undo_shaker:
943 pagebuf_terminate();
944
945undo_pagebuf:
946 destroy_inodecache();
947
948undo_inodecache:
949 return error;
950}
951
952STATIC void __exit
953exit_xfs_fs( void )
954{
955 XFS_DM_EXIT(&xfs_fs_type);
956 unregister_filesystem(&xfs_fs_type);
957 kmem_shake_deregister(xfs_inode_shaker);
958 xfs_cleanup();
959 vfs_exitquota();
960 vfs_exitdmapi();
961 pagebuf_terminate();
962 destroy_inodecache();
963 ktrace_uninit();
964}
965
966module_init(init_xfs_fs);
967module_exit(exit_xfs_fs);
968
969MODULE_AUTHOR("Silicon Graphics, Inc.");
970MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled");
971MODULE_LICENSE("GPL");
972