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
61extern struct vop_vector xfs_fifoops;
62extern struct xfs_vnodeops xfs_vnodeops;
63
64__uint64_t
65xfs_max_file_offset(
66	unsigned int		blockshift)
67{
68
69	return (OFF_MAX);
70}
71
72void
73xfs_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
112struct vnode *
113xfs_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*/
123int
124xfs_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
201void
202xfs_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
222void
223xfs_mountfs_check_barriers(xfs_mount_t *mp)
224{
225	printf("xfs_mountfs_check_barriers NI\n");
226}
227
228void
229xfs_flush_inode(
230		xfs_inode_t	*ip)
231{
232	printf("xfs_flush_inode NI\n");
233}
234
235void
236xfs_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
244void
245xfs_blkdev_issue_flush(
246	xfs_buftarg_t		*buftarg)
247{
248	printf("xfs_blkdev_issue_flush NI\n");
249}
250
251int
252init_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
270void
271exit_xfs_fs(void)
272{
273	xfs_cleanup();
274	vfs_exitquota();
275#ifdef RMC
276	vfs_exitdmapi();
277#endif
278}
279
280