Example #1
0
int GLWorker::SignalWorker(Work *work, bool worker_exit) {
  int ret = 0;
  if (worker_exit_)
    return -EINVAL;
  TRY_RETURN(pthread_mutex_lock(&lock_), "lock GLThread");
  worker_work_ = work;
  worker_exit_ = worker_exit;
  ret = pthread_cond_signal(&work_ready_cond_);
  if (ret) {
    ALOGE("Failed to signal GLThread caller %d", ret);
    pthread_mutex_unlock(&lock_);
    return ret;
  }
  ret = pthread_cond_wait(&work_done_cond_, &lock_);
  if (ret) {
    ALOGE("Failed to wait on GLThread %d", ret);
    pthread_mutex_unlock(&lock_);
    return ret;
  }

  ret = worker_ret_;
  if (ret) {
    pthread_mutex_unlock(&lock_);
    return ret;
  }
  TRY_RETURN(pthread_mutex_unlock(&lock_), "unlock GLThread");
  return ret;
}
Example #2
0
int GLWorker::Init() {
  int ret = 0;

  worker_work_ = NULL;
  worker_exit_ = false;
  worker_ret_ = -1;

  ret = pthread_cond_init(&work_ready_cond_, NULL);
  if (ret) {
    ALOGE("Failed to int GLThread condition %d", ret);
    return ret;
  }

  ret = pthread_cond_init(&work_done_cond_, NULL);
  if (ret) {
    ALOGE("Failed to int GLThread condition %d", ret);
    pthread_cond_destroy(&work_ready_cond_);
    return ret;
  }

  ret = pthread_mutex_init(&lock_, NULL);
  if (ret) {
    ALOGE("Failed to init GLThread lock %d", ret);
    pthread_cond_destroy(&work_ready_cond_);
    pthread_cond_destroy(&work_done_cond_);
    return ret;
  }

  ret = pthread_create(&thread_, NULL, StartRoutine, this);
  if (ret) {
    ALOGE("Failed to create GLThread %d", ret);
    pthread_cond_destroy(&work_ready_cond_);
    pthread_cond_destroy(&work_done_cond_);
    pthread_mutex_destroy(&lock_);
    return ret;
  }

  initialized_ = true;

  TRY_RETURN(pthread_mutex_lock(&lock_), "lock GLThread");

  while (!worker_exit_ && worker_ret_ != 0)
    TRY(pthread_cond_wait(&work_done_cond_, &lock_), "wait on condition",
        goto out_unlock);

  ret = worker_ret_;

out_unlock:
  int unlock_ret = pthread_mutex_unlock(&lock_);
  if (unlock_ret) {
    ret = unlock_ret;
    ALOGE("Failed to unlock GLThread %d", unlock_ret);
  }
  return ret;
}
Example #3
0
NTSTATUS LklMount(IN PDEVICE_OBJECT dev,IN PVPB vpb)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT volume_device=NULL;
	PLKLVCB vcb = NULL;
	LARGE_INTEGER AllocationSize;
	ULONG ioctlSize;
	int sectors;
	PSTR dev_name;
	STATFS my_stat;
	ULONG rc;

	CHECK_OUT(dev == lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	CHECK_OUT(FLAG_ON(lklfsd.flags, VFS_UNLOAD_PENDING),STATUS_UNRECOGNIZED_VOLUME);
	
	DbgPrint("Mount volume");

	status = IoCreateDevice(lklfsd.driver, sizeof(LKLVCB), NULL,
				FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &volume_device);	
	CHECK_OUT(!NT_SUCCESS(status), status);
	
	if (dev->AlignmentRequirement > volume_device->AlignmentRequirement)
		volume_device->AlignmentRequirement = dev->AlignmentRequirement;
	
	
	CLEAR_FLAG(volume_device->Flags, DO_DEVICE_INITIALIZING);
	volume_device->StackSize = (CCHAR)(dev->StackSize+1);	
	CreateVcb(volume_device,dev,vpb,&AllocationSize);
	vcb = (PLKLVCB) volume_device->DeviceExtension;
	if(!FLAG_ON(vcb->flags, VFS_VCB_FLAGS_VCB_INITIALIZED))
		TRY_RETURN(STATUS_INSUFFICIENT_RESOURCES);
	
	
	// yup, here we read the disk geometry
	ioctlSize = sizeof(DISK_GEOMETRY);
	status = BlockDeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
				      &vcb->disk_geometry, &ioctlSize);
	CHECK_OUT(!NT_SUCCESS(status), status);

	
	ioctlSize = sizeof(PARTITION_INFORMATION);
	status = BlockDeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
				      &vcb->partition_information, &ioctlSize);
	CHECK_OUT(!NT_SUCCESS(status), status);

	int bytes_per_sector = 0;
	switch (vcb->disk_geometry.BytesPerSector)
	{
	case 256:
		bytes_per_sector = 8;
		break;
	case 512:
		bytes_per_sector = 9;
		break;
	case 1024:
		bytes_per_sector = 10;
		break;
	case 2048:
		bytes_per_sector = 11;
		break;
	case 4096:
		bytes_per_sector = 12;
		break;
	case 8192:
		bytes_per_sector = 13;
		break;
	}
	sectors = vcb->partition_information.PartitionLength.QuadPart >> bytes_per_sector;
	
	// try a linux mount if this fails, then we fail to mount
	// the volume
	ExAcquireResourceExclusiveLite(&(lklfsd.global_resource), TRUE);
	lklfsd.no_mounts++;
	status = sys_mount_wrapper(vcb->target_device, sectors, &vcb->linux_device);
	DbgPrint("Mounting device '%s' retstatus=%d", dev_name, status);
	ExFreePool(dev_name);
   	RELEASE(&(lklfsd.global_resource));
	CHECK_OUT(!NT_SUCCESS(status), status);
	
	
	//get info about the successfully mounted volume
	rc = sys_statfs_wrapper(vcb->linux_device.mnt, &my_stat);

	vpb->DeviceObject = volume_device;
	// complete vpb fields
	#define UNKNOWN_LABEL "Local Disk"
	CharToWchar(vpb->VolumeLabel, UNKNOWN_LABEL , sizeof(UNKNOWN_LABEL));
	vpb->VolumeLabel[sizeof(UNKNOWN_LABEL)] = 0;
	vpb->VolumeLabelLength = sizeof(UNKNOWN_LABEL)*2;
	vpb->SerialNumber = my_stat.f_type;
try_exit:

	if(!NT_SUCCESS(status))
	{
		ExAcquireResourceExclusiveLite(&(lklfsd.global_resource), TRUE);
		lklfsd.no_mounts--;
		RELEASE(&(lklfsd.global_resource));
		
		
		if(volume_device) {
			FreeVcb((PLKLVCB) volume_device->DeviceExtension);
			IoDeleteDevice(volume_device);
		}
		
	}
	
	return status;
}
Example #4
0
//
//	FSCTL_LOCK_VOLUME
//
NTSTATUS DDKAPI VfsLockVolume(PIRP irp, PIO_STACK_LOCATION stack_location)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PDEVICE_OBJECT device = NULL;
	PLKLVCB vcb;
	BOOLEAN notified = FALSE;
	BOOLEAN resource_acquired = FALSE;
	PFILE_OBJECT file_obj = NULL;

	// request to fs device not permited
	device = stack_location->DeviceObject;
	CHECK_OUT(device == lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	// get vcb
	vcb = (PLKLVCB)device->DeviceExtension;
	ASSERT(vcb);

	// file object - should be the file object for a volume open, 
	// even so we accept it for any open file
	file_obj = stack_location->FileObject;
	ASSERT(file_obj);

	// notify volume locked
	FsRtlNotifyVolumeEvent(file_obj, FSRTL_VOLUME_LOCK);
	notified = TRUE;

	// acquire vcb lock
	ExAcquireResourceSharedLite(&vcb->vcb_resource, TRUE);
	resource_acquired = TRUE;

	// check lock flag
	if (FLAG_ON(vcb->flags, VFS_VCB_FLAGS_VOLUME_LOCKED)) {
		VfsReportError("Volume already locked");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// abort if open files still exist
	if (vcb->open_count) {
		VfsReportError("Open files still exist");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// release lock
	RELEASE(&vcb->vcb_resource);
	resource_acquired = FALSE;

	// purge volume
	VfsPurgeVolume(vcb, TRUE);

	ExAcquireResourceExclusiveLite(&vcb->vcb_resource, TRUE);
	resource_acquired = TRUE;
	
	// if there are still open referneces we can't lock the volume
	if (vcb->reference_count > 1) {
		VfsReportError("Could not purge cached files");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// set flag in both vcb and vpb structures
	SET_FLAG(vcb->flags, VFS_VCB_FLAGS_VOLUME_LOCKED);
	SetVpbFlag(vcb->vpb, VFS_VCB_FLAGS_VOLUME_LOCKED);
	DbgPrint("*** Volume LOCKED ***\n");
	status = STATUS_SUCCESS;
	
try_exit:
	
	if (resource_acquired)
		RELEASE(&vcb->vcb_resource);
	if (!NT_SUCCESS(status) && notified)
		FsRtlNotifyVolumeEvent(file_obj, FSRTL_VOLUME_LOCK_FAILED);
	
	return status;
}
Example #5
0
//
//	IRP_MJ_DEVICE_CONTROL - is synchronous
//
NTSTATUS DDKAPI VfsDeviceControl(PDEVICE_OBJECT device, PIRP irp)
{
	NTSTATUS status=STATUS_SUCCESS;
	BOOLEAN top_level;
	ULONG ioctl = 0;
	PIO_STACK_LOCATION stack_location = NULL;
	PIO_STACK_LOCATION next_stack_location = NULL;
	BOOLEAN complete_request = FALSE;
	PLKLVCB vcb = NULL;
	PLKLFCB fcb = NULL;
	PFILE_OBJECT file = NULL;
	PDEVICE_OBJECT targetDevice = NULL;

	ASSERT(device);
	ASSERT(irp);
	top_level = LklIsIrpTopLevel(irp);
	FsRtlEnterFileSystem();

	stack_location = IoGetCurrentIrpStackLocation(irp);
	ASSERT(stack_location);

	ioctl = stack_location->Parameters.DeviceIoControl.IoControlCode;

	if (ioctl == IOCTL_PREPARE_TO_UNLOAD) {
		complete_request = TRUE;
		DbgPrint("Prepare to unload");
		status = LklPrepareToUnload(device,irp);
		TRY_RETURN(status);
	}

	file = stack_location->FileObject;
	ASSERT(file);
	fcb = (PLKLFCB) file->FsContext;
	CHECK_OUT(fcb == NULL, STATUS_INVALID_PARAMETER);

	if (fcb->id.type == VCB) {
		vcb = (PLKLVCB) fcb;
	} else {
		vcb = fcb->vcb;
	}
	CHECK_OUT(vcb == NULL, STATUS_INVALID_PARAMETER);

	targetDevice = vcb->target_device;

	// Pass on the IOCTL to the driver below
	complete_request = FALSE;
	next_stack_location = IoGetNextIrpStackLocation(irp);
	*next_stack_location = *stack_location;
	IoSetCompletionRoutine(irp, LklIoctlCompletion, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(targetDevice, irp);

try_exit:
	
	if(complete_request)
		LklCompleteRequest(irp, status);
	if (top_level)
			IoSetTopLevelIrp(NULL);
	FsRtlExitFileSystem();

	return status;
}