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