1 // 2 // CDDL HEADER START 3 // 4 // The contents of this file are subject to the terms of the 5 // Common Development and Distribution License (the License). 6 // You may not use this file except in compliance with the License. 7 // 8 // You can obtain a copy of the license at usr/src/CDDL.txt 9 // or http://www.opensolaris.org/os/licensing. 10 // See the License for the specific language governing permissions 11 // and limitations under the License. 12 // 13 // When distributing Covered Code, include this CDDL HEADER in each 14 // file and include the License file at usr/src/CDDL.txt. 15 // If applicable, add the following below this CDDL HEADER, with the 16 // fields enclosed by brackets [] replaced with your own identifying 17 // information: Portions Copyright [yyyy] [name of copyright owner] 18 // 19 // CDDL HEADER END 20 // 21 22 // 23 // Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 // Use is subject to license terms. 25 // 26 27 #pragma ident "@(#)fs_dependent_impl.cc 1.15 08/06/16 SMI" 28 29 #include <sys/mntent.h> 30 31 #include <orb/infrastructure/orb_conf.h> 32 33 #include "../version.h" 34 #include <pxfs/lib/pxfs_debug.h> 35 #include <pxfs/server/fs_dependent_impl.h> 36 #include <pxfs/server/fobj_impl.h> 37 #include <pxfs/server/fs_impl.h> 38 #include <pxfs/server/ufs_dependent_impl.h> 39 #include <pxfs/server/hsfs_dependent_impl.h> 40 41 #ifndef VXFS_DISABLED 42 #include <pxfs/server/vxfs_dependent_impl.h> 43 #endif 44 45 //lint -e1512 46 // 47 // Warning(1512) destructor for base class is not virtual -- In a 48 // final pass through all the classes, we have found a class that is 49 // the base class of a derivation and has a destructor but the 50 // destructor is not virtual. It is conventional for inherited classes 51 // to have virtual destructors so that is it safe to 'delete' a 52 // pointer to a base class. 53 // 54 55 extern "C" void set_server_copyops(void); 56 57 fs_dependent_impl default_fs_dependent_impl; 58 59 // Constructor. 60 fs_dependent_impl::fs_dependent_impl() 61 { 62 // Empty 63 } 64 65 // Virtual destructor. 66 fs_dependent_impl::~fs_dependent_impl() 67 { 68 // Empty 69 } 70 71 void 72 fs_dependent_impl::new_fobj(fobj_ii *) 73 { 74 // Empty 75 } 76 77 // We care about this only for UFS. Return 0 for other filesystems. 78 int 79 fs_dependent_impl::fs_preprocess(vnode_t *, u_offset_t, size_t *, 80 fdbuffer_t *, int, cred_t *) 81 { 82 return (0); 83 } 84 85 // 86 // Called when the FS is mounted using new mount options (via the 87 // MS_REMOUNT flag to mount). 88 // 89 void 90 fs_dependent_impl::set_mntopts(const char *) 91 { 92 // Empty 93 } 94 95 // 96 // Function called by fobj_ii::cascaded_ioctl() to process fs-specific ioctls. 97 // Returns true if the ioctl was processed in this function, and false 98 // if not. 99 // 100 bool 101 fs_dependent_impl::process_cascaded_ioctl(sol::nodeid_t, 102 fobj_ii *, int32_t, sol::intptr_t, int32_t, cred_t *, int *, 103 int &, Environment &) 104 { 105 return (false); 106 } 107 108 void 109 fs_dependent_impl::replay_ioctl(fobj_ii *, int32_t, sol::intptr_t, int32_t, 110 int32_t &, int &) 111 { 112 } 113 114 // 115 // Function called by fs_ii::convert_to_primary() to do any fs-specific 116 // functions. This default function simply returns with no errors. 117 // 118 int 119 fs_dependent_impl::convert_to_primary(fs_ii *) 120 { 121 return (0); 122 } 123 124 void 125 fs_dependent_impl::freeze_primary(const char *) 126 { 127 } 128 129 // Helper function for dumping state to a new secondary. 130 void 131 fs_dependent_impl::dump_state(REPL_PXFS_VER::fs_replica_ptr, Environment &) 132 { 133 } 134 135 // 136 // Helper function called from repl_pxfs_server::ckpt_lockfs_state() to 137 // checkpoint state of the UFS _FIOLFS ioctl call. The default implementation 138 // is empty, and should never get called. 139 // 140 void 141 fs_dependent_impl::ckpt_lockfs_state(uint64_t, uint64_t, uint64_t, 142 const char *) 143 { 144 ASSERT(0); 145 } 146 147 // 148 // Checkpoint tunefs parameters for VxFS. 149 // 150 void 151 fs_dependent_impl::ckpt_vx_tunefs(const REPL_PXFS_VER::vx_tunefs_t &) 152 { 153 ASSERT(0); 154 } 155 156 // 157 // Static function that returns a fs-specific instance of 158 // 'fs_dependent_impl', if required. This function is called from 159 // the 'fs_ii' constructor. 160 // 161 fs_dependent_impl * 162 fs_dependent_impl::get_fs_dependent_impl(fs_ii *fs_implp, const char *fstype, 163 const char *mntoptions) 164 { 165 if (strcmp(fstype, MNTTYPE_UFS) == 0) { 166 return (new ufs_dependent_impl(fs_implp, mntoptions)); 167 } else if (strcmp(fstype, MNTTYPE_HSFS) == 0) { 168 return (new hsfs_dependent_impl(fs_implp)); 169 #ifndef VXFS_DISABLED 170 } else if (strcmp(fstype, "vxfs") == 0) { 171 return (new vxfs_dependent_impl(fs_implp)); 172 #endif 173 } 174 175 return (&default_fs_dependent_impl); 176 } 177 178 void 179 fs_dependent_impl::free_fs_dependent_impl(fs_dependent_impl *fs_dep_implp) 180 { 181 if (fs_dep_implp != &default_fs_dependent_impl) 182 delete fs_dep_implp; 183 } 184 185 int 186 fs_dependent_impl::kernel_ioctl(vfs_t *vfsp, int operation, 187 intptr_t arg) 188 { 189 vnode_t *root_vp; 190 int error = 0, ret_val = 0; 191 192 ASSERT(vfsp != NULL); 193 194 // 195 // Get the root vnode. 196 // 197 // The read lock must be held across the call to VFS_ROOT() 198 // to prevent a concurrent unmount from destroying the vfs. 199 // 200 vfs_lock_wait(vfsp); 201 error = VFS_ROOT(vfsp, &root_vp); 202 vfs_unlock(vfsp); 203 if (error != 0) { 204 PXFS_DBPRINTF( 205 PXFS_TRACE_FS, 206 PXFS_RED, 207 ("fs_dependent_impl::kernel_ioctl: " 208 "VFS_ROOT() error %d\n", error)); // XXX 209 return (error); 210 } 211 // 212 // Set the copy_args 'pid' value to '0', to indicate that the 213 // kernel is performing the ioctl (see orb/copy.cc). 214 // 215 copy_args args(orb_conf::node_number(), 0); 216 copy::setcontext(&args); 217 218 // 219 // Convert the copyops functions to the mc_copyops 220 // functions as defined in the orb 221 // 222 bool restore_ops = false; 223 #if SOL_VERSION >= __s10 224 if (!copyops_installed(curthread)) { 225 #else 226 if (get_copyops(curthread) == &default_copyops) { 227 #endif 228 set_server_copyops(); 229 restore_ops = true; 230 } 231 232 // 233 // Make the ioctl call - use kcred because this ioctl has 234 // already suceeded on the old primary, and it must succeed 235 // during a switchover/failover. 236 // 237 #if SOL_VERSION >= __s11 238 error = VOP_IOCTL(root_vp, operation, arg, 239 FKIOCTL, kcred, &ret_val, NULL); 240 #else 241 error = VOP_IOCTL(root_vp, operation, arg, 242 FKIOCTL, kcred, &ret_val); 243 #endif 244 245 // Release the held vnode. 246 VN_RELE(root_vp); 247 248 // 249 // Restore copyops to default_copyops 250 // 251 if (restore_ops) { 252 remove_copyops(curthread); 253 } 254 255 // Trap future references. 256 copy::setcontext(NULL); 257 258 return (error); 259 } 260 261 int 262 fs_dependent_impl::fs_alloc_data(vnode_t *, u_offset_t, size_t *, fdbuffer_t *, 263 int, cred_t *) 264 { 265 return (EIO); 266 } 267 268 int 269 fs_dependent_impl::fs_rdwr_data(vnode_t *, u_offset_t, size_t, 270 size_t, fdbuffer_t *, int, cred_t *) 271 { 272 return (EIO); 273 } 274 275 // 276 // If the file system isn't a log based file system or directory operations 277 // aren't synchronous, override this default function. 278 // 279 int 280 fs_dependent_impl::fs_fsync(vnode_t *, cred_t *) 281 { 282 return (0); 283 } 284 285 // 286 // If the file system isn't a log based file system or directory operations 287 // aren't synchronous, override this default function. 288 // 289 int 290 fs_dependent_impl::do_fsync(vnode_t *vnodep, cred_t *credp) 291 { 292 #if SOL_VERSION >= __s11 293 return (VOP_FSYNC(vnodep, FSYNC, credp, NULL)); 294 #else 295 return (VOP_FSYNC(vnodep, FSYNC, credp)); 296 #endif 297 } 298 299 int 300 fs_dependent_impl::sync_if_necessary(os::hrtime_t &, vnode *, cred_t *) 301 { 302 return (0); 303 } 304 305 // 306 // Return 'true' if the device this filesystem is mounted on is a 307 // lofi device; else return false. 308 // 309 bool 310 fs_dependent_impl::device_is_lofi(struct vfs *vfsp) 311 { 312 dev_t dev; 313 major_t maj; 314 char *device_name; 315 316 maj = getmajor(vfsp->vfs_dev); 317 device_name = ddi_major_to_name(maj); 318 319 if (strncmp(device_name, LOFI_DRIVER_NAME, 320 sizeof (LOFI_DRIVER_NAME) + 1) == 0) { 321 return (true); 322 } else { 323 return (false); 324 } 325 } 326