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_fs.h" 20#include "xfs_inum.h" 21#include "xfs_log.h" 22#include "xfs_clnt.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_imap.h" 29#include "xfs_alloc.h" 30#include "xfs_dmapi.h" 31#include "xfs_mount.h" 32#include "xfs_quota.h" 33 34#include "xfs_mountops.h" 35 36int 37xvfs_mount( 38 struct bhv_desc *bdp, 39 struct xfs_mount_args *args, 40 struct cred *cr) 41{ 42 struct bhv_desc *next = bdp; 43 44 ASSERT(next); 45 while (! (bhvtovfsops(next))->xvfs_mount) 46 next = BHV_NEXT(next); 47 return ((*bhvtovfsops(next)->xvfs_mount)(next, args, cr)); 48} 49 50int 51xvfs_parseargs( 52 struct bhv_desc *bdp, 53 char *s, 54 struct xfs_mount_args *args, 55 int f) 56{ 57 struct bhv_desc *next = bdp; 58 59 ASSERT(next); 60 while (! (bhvtovfsops(next))->xvfs_parseargs) 61 next = BHV_NEXT(next); 62 return ((*bhvtovfsops(next)->xvfs_parseargs)(next, s, args, f)); 63} 64 65int 66xvfs_showargs( 67 struct bhv_desc *bdp, 68 struct sbuf *m) 69{ 70 struct bhv_desc *next = bdp; 71 72 ASSERT(next); 73 while (! (bhvtovfsops(next))->xvfs_showargs) 74 next = BHV_NEXT(next); 75 return ((*bhvtovfsops(next)->xvfs_showargs)(next, m)); 76} 77 78int 79xvfs_unmount( 80 struct bhv_desc *bdp, 81 int fl, 82 struct cred *cr) 83{ 84 struct bhv_desc *next = bdp; 85 86 ASSERT(next); 87 while (! (bhvtovfsops(next))->xvfs_unmount) 88 next = BHV_NEXT(next); 89 return ((*bhvtovfsops(next)->xvfs_unmount)(next, fl, cr)); 90} 91 92int 93xvfs_mntupdate( 94 struct bhv_desc *bdp, 95 int *fl, 96 struct xfs_mount_args *args) 97{ 98 struct bhv_desc *next = bdp; 99 100 ASSERT(next); 101 while (! (bhvtovfsops(next))->xvfs_mntupdate) 102 next = BHV_NEXT(next); 103 return ((*bhvtovfsops(next)->xvfs_mntupdate)(next, fl, args)); 104} 105 106int 107xvfs_root( 108 struct bhv_desc *bdp, 109 struct xfs_vnode **vpp) 110{ 111 struct bhv_desc *next = bdp; 112 113 ASSERT(next); 114 while (! (bhvtovfsops(next))->xvfs_root) 115 next = BHV_NEXT(next); 116 return ((*bhvtovfsops(next)->xvfs_root)(next, vpp)); 117} 118 119int 120xvfs_statvfs( 121 struct bhv_desc *bdp, 122 struct statfs *sp, 123 struct xfs_vnode *vp) 124{ 125 struct bhv_desc *next = bdp; 126 127 ASSERT(next); 128 while (! (bhvtovfsops(next))->xvfs_statvfs) 129 next = BHV_NEXT(next); 130 return ((*bhvtovfsops(next)->xvfs_statvfs)(next, sp, vp)); 131} 132 133int 134xvfs_sync( 135 struct bhv_desc *bdp, 136 int fl, 137 struct cred *cr) 138{ 139 struct bhv_desc *next = bdp; 140 141 ASSERT(next); 142 while (! (bhvtovfsops(next))->xvfs_sync) 143 next = BHV_NEXT(next); 144 return ((*bhvtovfsops(next)->xvfs_sync)(next, fl, cr)); 145} 146 147int 148xvfs_vget( 149 struct bhv_desc *bdp, 150 struct xfs_vnode **vpp, 151 struct fid *fidp) 152{ 153 struct bhv_desc *next = bdp; 154 155 ASSERT(next); 156 while (! (bhvtovfsops(next))->xvfs_vget) 157 next = BHV_NEXT(next); 158 return ((*bhvtovfsops(next)->xvfs_vget)(next, vpp, fidp)); 159} 160 161int 162xvfs_dmapiops( 163 struct bhv_desc *bdp, 164 caddr_t addr) 165{ 166 struct bhv_desc *next = bdp; 167 168 ASSERT(next); 169 while (! (bhvtovfsops(next))->xvfs_dmapiops) 170 next = BHV_NEXT(next); 171 return ((*bhvtovfsops(next)->xvfs_dmapiops)(next, addr)); 172} 173 174int 175xvfs_quotactl( 176 struct bhv_desc *bdp, 177 int cmd, 178 int id, 179 caddr_t addr) 180{ 181 struct bhv_desc *next = bdp; 182 183 ASSERT(next); 184 while (! (bhvtovfsops(next))->xvfs_quotactl) 185 next = BHV_NEXT(next); 186 return ((*bhvtovfsops(next)->xvfs_quotactl)(next, cmd, id, addr)); 187} 188 189struct inode * 190xvfs_get_inode( 191 struct bhv_desc *bdp, 192 xfs_ino_t ino, 193 int fl) 194{ 195 struct bhv_desc *next = bdp; 196 197 while (! (bhvtovfsops(next))->xvfs_get_inode) 198 next = BHV_NEXTNULL(next); 199 return ((*bhvtovfsops(next)->xvfs_get_inode)(next, ino, fl)); 200} 201 202void 203xvfs_init_vnode( 204 struct bhv_desc *bdp, 205 struct xfs_vnode *vp, 206 struct bhv_desc *bp, 207 int unlock) 208{ 209 struct bhv_desc *next = bdp; 210 211 ASSERT(next); 212 while (! (bhvtovfsops(next))->xvfs_init_vnode) 213 next = BHV_NEXT(next); 214 ((*bhvtovfsops(next)->xvfs_init_vnode)(next, vp, bp, unlock)); 215} 216 217void 218xvfs_force_shutdown( 219 struct bhv_desc *bdp, 220 int fl, 221 char *file, 222 int line) 223{ 224 struct bhv_desc *next = bdp; 225 226 ASSERT(next); 227 while (! (bhvtovfsops(next))->xvfs_force_shutdown) 228 next = BHV_NEXT(next); 229 ((*bhvtovfsops(next)->xvfs_force_shutdown)(next, fl, file, line)); 230} 231 232xfs_vfs_t * 233vfs_allocate(struct mount *mp) 234{ 235 struct xfs_vfs *vfsp; 236 struct xfsmount *xmp; 237 238 xmp = kmem_zalloc(sizeof(*xmp), KM_SLEEP); 239 vfsp = XFSTOVFS(xmp); 240 241 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); 242 243 xmp->m_mp = mp; 244 mp->mnt_data = xmp; 245 vfsp->vfs_mp = mp; 246 247 return vfsp; 248} 249 250void 251vfs_deallocate( 252 struct xfs_vfs *vfsp) 253{ 254 struct xfsmount *xmp; 255 256 bhv_head_destroy(VFS_BHVHEAD(vfsp)); 257 258 xmp = VFSTOXFS(vfsp); 259 kmem_free(xmp, sizeof(*xmp)); 260} 261 262/* 263 * Allocate and initialize a new XFS mount structure 264 */ 265struct xfsmount * 266xfsmount_allocate(struct mount *mp) 267{ 268 xfs_vfs_t *vfsp; 269 270 vfsp = vfs_allocate(mp); 271 272 ASSERT(vfsp); 273 274 if (mp->mnt_flag & MNT_RDONLY) 275 vfsp->vfs_flag |= VFS_RDONLY; 276 277 bhv_insert_all_vfsops(vfsp); 278 return (VFSTOXFS(vfsp)); 279} 280 281void 282xfsmount_deallocate(struct xfsmount *xmp) 283{ 284 xfs_vfs_t *vfsp; 285 286 vfsp = XFSTOVFS(xmp); 287 bhv_remove_all_vfsops(vfsp, 1); 288 vfs_deallocate(vfsp); 289} 290 291 292void 293vfs_insertops( 294 struct xfs_vfs *vfsp, 295 struct bhv_vfsops *vfsops) 296{ 297 struct bhv_desc *bdp; 298 299 bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP); 300 bhv_desc_init(bdp, NULL, vfsp, vfsops); 301 bhv_insert(&vfsp->vfs_bh, bdp); 302} 303 304void 305vfs_insertbhv( 306 struct xfs_vfs *vfsp, 307 struct bhv_desc *bdp, 308 struct xvfsops *vfsops, 309 void *mount) 310{ 311 bhv_desc_init(bdp, mount, vfsp, vfsops); 312 bhv_insert_initial(&vfsp->vfs_bh, bdp); 313} 314 315void 316bhv_remove_vfsops( 317 struct xfs_vfs *vfsp, 318 int pos) 319{ 320 struct bhv_desc *bhv; 321 322 bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos); 323 if (bhv) { 324 bhv_remove(&vfsp->vfs_bh, bhv); 325 kmem_free(bhv, sizeof(*bhv)); 326 } 327} 328 329void 330bhv_remove_all_vfsops( 331 struct xfs_vfs *vfsp, 332 int freebase) 333{ 334 struct xfs_mount *mp; 335 336 bhv_remove_vfsops(vfsp, VFS_POSITION_QM); 337 bhv_remove_vfsops(vfsp, VFS_POSITION_DM); 338 bhv_remove_vfsops(vfsp, VFS_POSITION_IO); 339 if (!freebase) 340 return; 341 mp = XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfsp), &xfs_vfsops)); 342 VFS_REMOVEBHV(vfsp, &mp->m_bhv); 343 xfs_mount_free(mp, 0); 344} 345 346void 347bhv_insert_all_vfsops( 348 struct xfs_vfs *vfsp) 349{ 350 struct xfs_mount *mp; 351 352 mp = xfs_mount_init(); 353 vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp); 354 vfs_insertdmapi(vfsp); 355 vfs_insertquota(vfsp); 356} 357