medium.c revision 18c2aff776a775d34a4c9893a4c72e0434d68e36
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Medium class implementation file.
*/
/*
* System include files
*/
#include <stdlib.h>
#include <strings.h>
#include <limits.h>
#include <unistd.h>
/*
* Local include files
*/
#include "medium.h"
#include "partition.h"
/*
* Definitions of private attributes and methods shared
* with friend classes like the partition class.
*/
#include "medium_private.h"
extern bool_t support_nomedia;
/*
* IMPORTANT NOTE:
*
* The strings in the medium_result_strings[] string array below
* MUST match the result types in typedef enum medium_result_t in
* medium.h. When you add or remove result types, keep the
* result types and the matching strings in alphabetical order
* to make it easier to maintain the match.
*/
static const char *medium_result_strings[] = {
"bad device",
"bad file descriptor",
"bad input parameter",
"can't create partitions",
"can't create pathnames",
"can't create vnodes",
"can't get access_mode",
"can't mount partitions",
"can't remount partitions",
"can't remove medium from the database",
"can't unmount partitions",
"out of memory",
"success"
};
/*
* Declarations of private methods
*/
static medium_result_t
char **block_pathnamepp);
/*
* Converts a raw pathname into a block pathname.
*/
static medium_result_t
/*
* Creates the "/vol" block and raw pathnames of the
* medium and writes pointers to them to the medium's
* block_pathnamep and raw_pathnamep attributes.
*/
static medium_result_t
/*
* When the medium contains more than one file system,
* creates a directory that will contain a symbolic link
* to each of the file systems. Creates a symbolic link
* to that directory, and stores a pointer to the symbolic
* link in the dp_symvn attribute of the device object
* that models the device in which the medium is inserted.
*/
static medium_result_t
/*
* Gets the access mode of the medium addressed by
* file_descriptor. Writes the encoded access mode to
* *permissionsp. If it can't get the access mode it
* returns an error code and writes READ_WRITE to
* *permissionsp.
*/
static medium_result_t
/*
* Removes all database entries for the medium object.
*/
/*
* Definitions of public functions
*/
static medium_result_t
{
}
if (medium_result == MEDIUM_SUCCESS) {
(size_t)sizeof (medium_private_t));
}
}
if (medium_result == MEDIUM_SUCCESS) {
} else {
}
}
if (medium_result == MEDIUM_SUCCESS) {
}
if (medium_result == MEDIUM_SUCCESS) {
if (device_get_fd == NULL) {
} else {
}
}
}
if (medium_result == MEDIUM_SUCCESS) {
privatep->partition_counts = (int *)
(size_t)sizeof (int));
}
}
if (medium_result == MEDIUM_SUCCESS) {
}
}
if (medium_result == MEDIUM_SUCCESS) {
}
if (medium_result == MEDIUM_SUCCESS) {
privatep->medium_capacity = 0;
&dkinfo) == 0) {
}
if (privatep->medium_capacity == 0) {
}
}
if (medium_result == MEDIUM_SUCCESS) {
&(privatep->top_partitionp));
if (partition_result != PARTITION_SUCCESS) {
}
}
/*
* we will start creating nodes which may be accessed from
* the main thread. vold_main_mutex needs to be acquired
* to avoid race condition between main and other threads
* which are reading mediums.
*/
(void) mutex_lock(&vold_main_mutex);
if (medium_result == MEDIUM_SUCCESS) {
}
}
if (medium_result == MEDIUM_SUCCESS) {
if (partition_result != PARTITION_SUCCESS) {
}
}
if (medium_result != MEDIUM_SUCCESS) {
}
/*
* In later versions of the volume management software
* device objects will create medium objects on insertion
* of media into the devices that the device objects model.
* They will therefore know which medium objects model the
* media they contain without having to be told. The
* current architecture of the volume manager software forces
* medium objects to tell device objects that they model
* media inserted in the devices that the device objects
* model.
*/
}
(void) mutex_unlock(&vold_main_mutex);
return (medium_result);
}
void
{
}
if (medium_result == MEDIUM_SUCCESS) {
}
}
if (medium_result == MEDIUM_SUCCESS) {
}
}
}
}
}
}
}
{
}
if (medium_result == MEDIUM_SUCCESS) {
}
if (partition_result != PARTITION_SUCCESS) {
}
return (medium_result);
}
{
}
if (medium_result == MEDIUM_SUCCESS) {
}
if (partition_result != PARTITION_SUCCESS) {
}
return (medium_result);
}
{
}
if (medium_result == MEDIUM_SUCCESS) {
if (partition_result != PARTITION_SUCCESS) {
}
}
return (medium_result);
}
static medium_result_t
{
error = 0;
if (error != 0) {
}
}
return (medium_result);
}
{
}
if (medium_result == MEDIUM_SUCCESS) {
}
}
if (medium_result == MEDIUM_SUCCESS) {
/*
* do the real work.
*/
}
if (medium_result != MEDIUM_SUCCESS) {
/*
* We'd better to eject the medium here. Otherwise user
* cannot do anything against the inserted medium since
* vold does not create a device node for it.
*/
/*
* Create "nomedia" device node.
*/
if (support_nomedia) {
(void) mutex_lock(&vold_main_mutex);
(void) mutex_unlock(&vold_main_mutex);
}
}
}
return (medium_result);
}
void
{
vol_t *v;
/*
* called only from main thread. No need to acquire
* lock.
*/
(void) remove_medium_from_db(mediump);
destroy_volume(v);
}
/*
* Definitions of private methods
*/
static medium_result_t
char **block_pathnamepp)
{
char *block_pathnamep;
char *device_namep;
char *device_numberp;
char *rdiskette_startp;
char *rdsk_startp;
/*
* malloc one less char than the number used in raw_pathnamep
* because "/dsk/" has one less character than "/rdsk/", and
* "diskette" has one less character than "rdiskette"
*/
if (block_pathnamep == NULL) {
}
if (medium_result == MEDIUM_SUCCESS) {
if (rdsk_startp != NULL) {
(rdsk_startp - raw_pathnamep));
} else {
if (rdiskette_startp != NULL) {
raw_pathnamep] = NULLC;
}
}
}
return (medium_result);
}
static medium_result_t
{
char *pathname_bufferp;
char *raw_devicep;
if (pathname_bufferp == NULL) {
}
if (raw_devicep != NULL) {
} else {
}
} else {
if (raw_devicep != NULL) {
} else {
&(medium_privatep->
}
} else {
/*
* The pathname is a test pathname of the
* form /vol/dev/voltestdrv/<number>, where
* <number> ranges from 1 through about 150.
*/
}
}
}
if (pathname_bufferp != NULL) {
}
return (medium_result);
}
static medium_result_t
{
/*
* When the medium contains more than one file system,
* contain a symbolic link to each of the file systems.
* Store a pointer to the subdirectory in the dp_symvn
* attribute of the device object that models the device
* in which the medium is inserted.
*/
char *device_symbolic_namep;
strlen("/") +
} else {
}
return (medium_result);
}
static medium_result_t
{
return (medium_result);
}
} else {
switch (wstate.sm_new_state) {
case SM_UNPROTECTED:
break;
case SM_WRITE_PROTECTED:
break;
case SM_WRITE_PROTECTED_WP:
break;
case SM_READ_WRITE_PROTECTED:
break;
case SM_STATUS_UNKNOWN:
break;
default:
/* the device returned an unknown protection state */
}
}
return (medium_result);
}