]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/gnu/fs/xfs/FreeBSD/xfs_super.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / gnu / fs / xfs / FreeBSD / xfs_super.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_bit.h"
20 #include "xfs_log.h"
21 #include "xfs_clnt.h"
22 #include "xfs_inum.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_dir.h"
27 #include "xfs_dir2.h"
28 #include "xfs_alloc.h"
29 #include "xfs_dmapi.h"
30 #include "xfs_quota.h"
31 #include "xfs_mount.h"
32 #include "xfs_bmap_btree.h"
33 #include "xfs_alloc_btree.h"
34 #include "xfs_ialloc_btree.h"
35 #include "xfs_dir_sf.h"
36 #include "xfs_dir2_sf.h"
37 #include "xfs_attr_sf.h"
38 #include "xfs_dinode.h"
39 #include "xfs_inode.h"
40 #include "xfs_btree.h"
41 #include "xfs_ialloc.h"
42 #include "xfs_bmap.h"
43 #include "xfs_rtalloc.h"
44 #include "xfs_error.h"
45 #include "xfs_itable.h"
46 #include "xfs_rw.h"
47 #include "xfs_acl.h"
48 #include "xfs_cap.h"
49 #include "xfs_mac.h"
50 #include "xfs_attr.h"
51 #include "xfs_buf_item.h"
52 #include "xfs_utils.h"
53 #include "xfs_version.h"
54 #include "xfs_buf.h"
55
56 #include <sys/priv.h>
57
58 #include <geom/geom.h>
59 #include <geom/geom_vfs.h>
60
61 extern struct vop_vector xfs_fifoops;
62 extern struct xfs_vnodeops xfs_vnodeops;
63
64 __uint64_t
65 xfs_max_file_offset(
66         unsigned int            blockshift)
67 {
68
69         return (OFF_MAX);
70 }
71
72 void
73 xfs_initialize_vnode(
74         bhv_desc_t              *bdp,
75         xfs_vnode_t             *xvp,
76         bhv_desc_t              *inode_bhv,
77         int                     unlock)
78 {
79         xfs_inode_t             *ip = XFS_BHVTOI(inode_bhv);
80
81         if (!inode_bhv->bd_vobj) {
82                 xvp->v_vfsp = bhvtovfs(bdp);
83                 bhv_desc_init(inode_bhv, ip, xvp, &xfs_vnodeops);
84                 bhv_insert(VN_BHV_HEAD(xvp), inode_bhv);
85         }
86
87         /*
88          * XXX: Use VNON as an indication of freshly allocated vnode
89          * which need to be initialized and unlocked.
90          * This is _not_ like the same place in Linux version of
91          * routine.
92          */
93
94         if (xvp->v_vnode->v_type != VNON)
95           return;
96
97         xvp->v_vnode->v_type =  IFTOVT(ip->i_d.di_mode);
98
99         if (xvp->v_vnode->v_type == VFIFO)
100                 xvp->v_vnode->v_op = &xfs_fifoops;
101
102         ASSERT_VOP_LOCKED(xvp->v_vnode, "xfs_initialize_vnode");
103
104         /* For new inodes we need to set the ops vectors,
105          * and unlock the inode.
106          */
107         if (ip->i_d.di_mode != 0 && unlock)
108                 VOP_UNLOCK(xvp->v_vnode, 0);
109 }
110
111 #if 0
112 struct vnode *
113 xfs_get_inode(
114         bhv_desc_t      *bdp,
115         xfs_ino_t       ino,
116         int             flags)
117 {
118         return NULL;
119 }
120 #endif
121
122 /*ARGSUSED*/
123 int
124 xfs_blkdev_get(
125         xfs_mount_t             *mp,
126         const char              *name,
127         struct vnode            **bdevp)
128 {
129         struct nameidata        nd;
130         struct nameidata        *ndp = &nd;
131         int                     error, ronly;
132         struct thread           *td;
133         struct vnode            *devvp;
134         struct g_consumer       *cp;
135         struct g_provider       *pp;
136         accmode_t               accmode;
137
138         td = curthread;
139
140         NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, name, td);
141         if ((error = namei(ndp)) != 0)
142                 return (error);
143         NDFREE(ndp, NDF_ONLY_PNBUF);
144         devvp = ndp->ni_vp;
145
146         if (!vn_isdisk(devvp, &error)) {
147                 vrele(devvp);
148                 return (error);
149         }
150
151         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
152
153         ronly = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) != 0);
154         accmode = VREAD;
155         if (!ronly)
156                 accmode |= VWRITE;
157         error = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
158         if (error)
159                 error = priv_check(td, PRIV_VFS_MOUNT_PERM);
160         if (error) {
161                 vput(devvp);
162                 return (error);
163         }
164
165         DROP_GIANT();
166         g_topology_lock();
167
168         /*
169          * XXX: Do not allow more than one consumer to open a device
170          *      associated with a particular GEOM provider.
171          *      This disables multiple read-only mounts of a device,
172          *      but it gets rid of panics in bmemfree() when you try to
173          *      mount the same device more than once.
174          *      During mounting, XFS does a bread() of the superblock, but does
175          *      not brelse() it.  A subsequent mount of the same device
176          *      will try to bread() the superblock, resulting in a panic in 
177          *      bremfree(), "buffer not on queue".
178          */
179         pp = g_dev_getprovider(devvp->v_rdev);
180         if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0)) 
181                 error = EPERM;
182         else 
183                 error = g_vfs_open(devvp, &cp, "xfs", ronly ? 0 : 1);
184
185         g_topology_unlock();
186         PICKUP_GIANT();
187
188         if (error) {
189                 vput(devvp);
190                 return (error);
191         }
192         VOP_UNLOCK(devvp, 0);
193
194         devvp->v_bufobj.bo_private = cp;
195         devvp->v_bufobj.bo_ops = &xfs_bo_ops;
196
197         *bdevp = devvp;
198         return (0);
199 }
200
201 void
202 xfs_blkdev_put(
203         struct vnode    *devvp)
204 {
205         struct g_consumer       *cp;
206
207         if (devvp == NULL)
208                 return;
209
210         vinvalbuf(devvp, V_SAVE, 0, 0);
211
212         cp = devvp->v_bufobj.bo_private;
213         DROP_GIANT();
214         g_topology_lock();
215         g_wither_geom_close(cp->geom, ENXIO);
216         g_topology_unlock();
217         PICKUP_GIANT();
218
219         vrele(devvp);
220 }
221
222 void
223 xfs_mountfs_check_barriers(xfs_mount_t *mp)
224 {
225         printf("xfs_mountfs_check_barriers NI\n");
226 }
227
228 void
229 xfs_flush_inode(
230                 xfs_inode_t     *ip)
231 {
232         printf("xfs_flush_inode NI\n");
233 }
234
235 void
236 xfs_flush_device(
237                  xfs_inode_t    *ip)
238 {
239         printf("xfs_flush_device NI\n");
240         xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
241 }
242
243
244 void
245 xfs_blkdev_issue_flush(
246         xfs_buftarg_t           *buftarg)
247 {
248         printf("xfs_blkdev_issue_flush NI\n");
249 }
250
251 int
252 init_xfs_fs( void )
253 {
254         static const char       message[] =
255                 XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
256
257         printf(message);
258
259         vn_init();
260         xfs_init();
261         uuid_init();
262 #ifdef RMC
263         vfs_initdmapi();
264 #endif
265         vfs_initquota();
266
267         return 0;
268 }
269
270 void
271 exit_xfs_fs(void)
272 {
273         xfs_cleanup();
274         vfs_exitquota();
275 #ifdef RMC
276         vfs_exitdmapi();
277 #endif
278 }
279