1153323Srodrigc/*
2159451Srodrigc * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3159451Srodrigc * All Rights Reserved.
4153323Srodrigc *
5159451Srodrigc * This program is free software; you can redistribute it and/or
6159451Srodrigc * modify it under the terms of the GNU General Public License as
7153323Srodrigc * published by the Free Software Foundation.
8153323Srodrigc *
9159451Srodrigc * This program is distributed in the hope that it would be useful,
10159451Srodrigc * but WITHOUT ANY WARRANTY; without even the implied warranty of
11159451Srodrigc * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12159451Srodrigc * GNU General Public License for more details.
13153323Srodrigc *
14159451Srodrigc * You should have received a copy of the GNU General Public License
15159451Srodrigc * along with this program; if not, write the Free Software Foundation,
16159451Srodrigc * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17153323Srodrigc */
18153323Srodrigc#include "xfs.h"
19159451Srodrigc#include "xfs_bit.h"
20153323Srodrigc#include "xfs_log.h"
21153323Srodrigc#include "xfs_clnt.h"
22159451Srodrigc#include "xfs_inum.h"
23153323Srodrigc#include "xfs_trans.h"
24153323Srodrigc#include "xfs_sb.h"
25159451Srodrigc#include "xfs_ag.h"
26153323Srodrigc#include "xfs_dir.h"
27153323Srodrigc#include "xfs_dir2.h"
28153323Srodrigc#include "xfs_alloc.h"
29153323Srodrigc#include "xfs_dmapi.h"
30153323Srodrigc#include "xfs_quota.h"
31153323Srodrigc#include "xfs_mount.h"
32159451Srodrigc#include "xfs_bmap_btree.h"
33153323Srodrigc#include "xfs_alloc_btree.h"
34153323Srodrigc#include "xfs_ialloc_btree.h"
35153323Srodrigc#include "xfs_dir_sf.h"
36153323Srodrigc#include "xfs_dir2_sf.h"
37159451Srodrigc#include "xfs_attr_sf.h"
38153323Srodrigc#include "xfs_dinode.h"
39153323Srodrigc#include "xfs_inode.h"
40159451Srodrigc#include "xfs_btree.h"
41159451Srodrigc#include "xfs_ialloc.h"
42153323Srodrigc#include "xfs_bmap.h"
43153323Srodrigc#include "xfs_rtalloc.h"
44153323Srodrigc#include "xfs_error.h"
45153323Srodrigc#include "xfs_itable.h"
46153323Srodrigc#include "xfs_rw.h"
47153323Srodrigc#include "xfs_acl.h"
48153323Srodrigc#include "xfs_cap.h"
49153323Srodrigc#include "xfs_mac.h"
50153323Srodrigc#include "xfs_attr.h"
51153323Srodrigc#include "xfs_buf_item.h"
52153323Srodrigc#include "xfs_utils.h"
53153323Srodrigc#include "xfs_version.h"
54159451Srodrigc#include "xfs_buf.h"
55153323Srodrigc
56164033Srwatson#include <sys/priv.h>
57164033Srwatson
58153323Srodrigc#include <geom/geom.h>
59153323Srodrigc#include <geom/geom_vfs.h>
60153323Srodrigc
61153323Srodrigcextern struct vop_vector xfs_fifoops;
62159451Srodrigcextern struct xfs_vnodeops xfs_vnodeops;
63153323Srodrigc
64153323Srodrigc__uint64_t
65153323Srodrigcxfs_max_file_offset(
66153323Srodrigc	unsigned int		blockshift)
67153323Srodrigc{
68153323Srodrigc
69153323Srodrigc	return (OFF_MAX);
70153323Srodrigc}
71153323Srodrigc
72153323Srodrigcvoid
73153323Srodrigcxfs_initialize_vnode(
74153323Srodrigc	bhv_desc_t		*bdp,
75159451Srodrigc	xfs_vnode_t		*xvp,
76153323Srodrigc	bhv_desc_t		*inode_bhv,
77153323Srodrigc	int			unlock)
78153323Srodrigc{
79153323Srodrigc	xfs_inode_t		*ip = XFS_BHVTOI(inode_bhv);
80153323Srodrigc
81153323Srodrigc	if (!inode_bhv->bd_vobj) {
82159451Srodrigc		xvp->v_vfsp = bhvtovfs(bdp);
83159451Srodrigc		bhv_desc_init(inode_bhv, ip, xvp, &xfs_vnodeops);
84159451Srodrigc		bhv_insert(VN_BHV_HEAD(xvp), inode_bhv);
85153323Srodrigc	}
86153323Srodrigc
87153323Srodrigc	/*
88153323Srodrigc	 * XXX: Use VNON as an indication of freshly allocated vnode
89153323Srodrigc	 * which need to be initialized and unlocked.
90153323Srodrigc	 * This is _not_ like the same place in Linux version of
91153323Srodrigc	 * routine.
92153323Srodrigc	 */
93153323Srodrigc
94159451Srodrigc	if (xvp->v_vnode->v_type != VNON)
95159451Srodrigc	  return;
96153323Srodrigc
97159451Srodrigc	xvp->v_vnode->v_type =  IFTOVT(ip->i_d.di_mode);
98153323Srodrigc
99159451Srodrigc	if (xvp->v_vnode->v_type == VFIFO)
100159451Srodrigc		xvp->v_vnode->v_op = &xfs_fifoops;
101153323Srodrigc
102159451Srodrigc	ASSERT_VOP_LOCKED(xvp->v_vnode, "xfs_initialize_vnode");
103159451Srodrigc
104153323Srodrigc	/* For new inodes we need to set the ops vectors,
105153323Srodrigc	 * and unlock the inode.
106153323Srodrigc	 */
107159451Srodrigc	if (ip->i_d.di_mode != 0 && unlock)
108175294Sattilio		VOP_UNLOCK(xvp->v_vnode, 0);
109153323Srodrigc}
110153323Srodrigc
111159451Srodrigc#if 0
112153323Srodrigcstruct vnode *
113153323Srodrigcxfs_get_inode(
114153323Srodrigc	bhv_desc_t	*bdp,
115153323Srodrigc	xfs_ino_t	ino,
116153323Srodrigc	int		flags)
117153323Srodrigc{
118153323Srodrigc	return NULL;
119153323Srodrigc}
120159451Srodrigc#endif
121153323Srodrigc
122153323Srodrigc/*ARGSUSED*/
123153323Srodrigcint
124153323Srodrigcxfs_blkdev_get(
125153323Srodrigc	xfs_mount_t		*mp,
126153323Srodrigc	const char		*name,
127153323Srodrigc	struct vnode		**bdevp)
128153323Srodrigc{
129153323Srodrigc	struct nameidata	nd;
130153323Srodrigc	struct nameidata	*ndp = &nd;
131153323Srodrigc	int			error, ronly;
132153323Srodrigc	struct thread		*td;
133153323Srodrigc	struct vnode		*devvp;
134153323Srodrigc	struct g_consumer	*cp;
135153323Srodrigc	struct g_provider	*pp;
136184413Strasz	accmode_t		accmode;
137153323Srodrigc
138153323Srodrigc	td = curthread;
139153323Srodrigc
140153323Srodrigc	NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, name, td);
141153323Srodrigc	if ((error = namei(ndp)) != 0)
142153323Srodrigc		return (error);
143153323Srodrigc	NDFREE(ndp, NDF_ONLY_PNBUF);
144153323Srodrigc	devvp = ndp->ni_vp;
145153323Srodrigc
146153323Srodrigc	if (!vn_isdisk(devvp, &error)) {
147153323Srodrigc		vrele(devvp);
148153323Srodrigc		return (error);
149153323Srodrigc	}
150153323Srodrigc
151175202Sattilio	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
152153323Srodrigc
153153323Srodrigc	ronly = ((XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) != 0);
154184413Strasz	accmode = VREAD;
155164033Srwatson	if (!ronly)
156184413Strasz		accmode |= VWRITE;
157184413Strasz	error = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
158164033Srwatson	if (error)
159164033Srwatson		error = priv_check(td, PRIV_VFS_MOUNT_PERM);
160164033Srwatson	if (error) {
161164033Srwatson		vput(devvp);
162164033Srwatson		return (error);
163153323Srodrigc	}
164153323Srodrigc
165153323Srodrigc	DROP_GIANT();
166153323Srodrigc	g_topology_lock();
167153323Srodrigc
168153323Srodrigc	/*
169153323Srodrigc	 * XXX: Do not allow more than one consumer to open a device
170153323Srodrigc	 *      associated with a particular GEOM provider.
171153323Srodrigc	 *      This disables multiple read-only mounts of a device,
172153323Srodrigc	 *      but it gets rid of panics in bmemfree() when you try to
173153323Srodrigc	 *      mount the same device more than once.
174153323Srodrigc	 *      During mounting, XFS does a bread() of the superblock, but does
175153323Srodrigc	 *      not brelse() it.  A subsequent mount of the same device
176153323Srodrigc	 *      will try to bread() the superblock, resulting in a panic in
177153323Srodrigc	 *      bremfree(), "buffer not on queue".
178153323Srodrigc	 */
179153323Srodrigc	pp = g_dev_getprovider(devvp->v_rdev);
180153323Srodrigc 	if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
181153323Srodrigc		error = EPERM;
182153323Srodrigc	else
183153323Srodrigc		error = g_vfs_open(devvp, &cp, "xfs", ronly ? 0 : 1);
184153323Srodrigc
185153323Srodrigc	g_topology_unlock();
186153323Srodrigc	PICKUP_GIANT();
187153323Srodrigc
188153323Srodrigc	if (error) {
189153323Srodrigc		vput(devvp);
190153323Srodrigc		return (error);
191153323Srodrigc	}
192175294Sattilio	VOP_UNLOCK(devvp, 0);
193153323Srodrigc
194153323Srodrigc	devvp->v_bufobj.bo_private = cp;
195159451Srodrigc	devvp->v_bufobj.bo_ops = &xfs_bo_ops;
196153323Srodrigc
197153323Srodrigc	*bdevp = devvp;
198153323Srodrigc	return (0);
199153323Srodrigc}
200153323Srodrigc
201153323Srodrigcvoid
202153323Srodrigcxfs_blkdev_put(
203153323Srodrigc	struct vnode	*devvp)
204153323Srodrigc{
205153323Srodrigc	struct g_consumer	*cp;
206153323Srodrigc
207153323Srodrigc	if (devvp == NULL)
208153323Srodrigc		return;
209153323Srodrigc
210183754Sattilio	vinvalbuf(devvp, V_SAVE, 0, 0);
211153323Srodrigc
212153323Srodrigc	cp = devvp->v_bufobj.bo_private;
213153323Srodrigc	DROP_GIANT();
214153323Srodrigc	g_topology_lock();
215153323Srodrigc	g_wither_geom_close(cp->geom, ENXIO);
216153323Srodrigc	g_topology_unlock();
217153323Srodrigc	PICKUP_GIANT();
218153323Srodrigc
219153323Srodrigc        vrele(devvp);
220153323Srodrigc}
221153323Srodrigc
222153323Srodrigcvoid
223159451Srodrigcxfs_mountfs_check_barriers(xfs_mount_t *mp)
224153323Srodrigc{
225159451Srodrigc	printf("xfs_mountfs_check_barriers NI\n");
226153323Srodrigc}
227153323Srodrigc
228153323Srodrigcvoid
229159451Srodrigcxfs_flush_inode(
230159451Srodrigc		xfs_inode_t	*ip)
231153323Srodrigc{
232159451Srodrigc	printf("xfs_flush_inode NI\n");
233153323Srodrigc}
234153323Srodrigc
235153323Srodrigcvoid
236159451Srodrigcxfs_flush_device(
237159451Srodrigc		 xfs_inode_t	*ip)
238153323Srodrigc{
239159451Srodrigc	printf("xfs_flush_device NI\n");
240159451Srodrigc        xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
241153323Srodrigc}
242153323Srodrigc
243153323Srodrigc
244153323Srodrigcvoid
245159451Srodrigcxfs_blkdev_issue_flush(
246159451Srodrigc	xfs_buftarg_t		*buftarg)
247153323Srodrigc{
248159451Srodrigc	printf("xfs_blkdev_issue_flush NI\n");
249153323Srodrigc}
250153323Srodrigc
251153323Srodrigcint
252153323Srodrigcinit_xfs_fs( void )
253153323Srodrigc{
254240207Sdim	static const char	message[] =
255153323Srodrigc		XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
256153323Srodrigc
257153323Srodrigc	printf(message);
258153323Srodrigc
259153323Srodrigc	vn_init();
260153323Srodrigc	xfs_init();
261153323Srodrigc	uuid_init();
262159451Srodrigc#ifdef RMC
263153323Srodrigc	vfs_initdmapi();
264159451Srodrigc#endif
265153323Srodrigc	vfs_initquota();
266153323Srodrigc
267153323Srodrigc	return 0;
268153323Srodrigc}
269153323Srodrigc
270153323Srodrigcvoid
271153323Srodrigcexit_xfs_fs(void)
272153323Srodrigc{
273153323Srodrigc	xfs_cleanup();
274153323Srodrigc	vfs_exitquota();
275159451Srodrigc#ifdef RMC
276153323Srodrigc	vfs_exitdmapi();
277159451Srodrigc#endif
278153323Srodrigc}
279153323Srodrigc
280