Home | History | Annotate | Download | only in server
      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