diff options
Diffstat (limited to 'kernel/power/user.c')
| -rw-r--r-- | kernel/power/user.c | 32 | 
1 files changed, 22 insertions, 10 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c index 72e8f4fd616..526e8911460 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -36,9 +36,10 @@ static struct snapshot_data {  	struct snapshot_handle handle;  	int swap;  	int mode; -	char frozen; -	char ready; -	char platform_support; +	bool frozen; +	bool ready; +	bool platform_support; +	bool free_bitmaps;  } snapshot_state;  atomic_t snapshot_device_available = ATOMIC_INIT(1); @@ -48,6 +49,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)  	struct snapshot_data *data;  	int error; +	if (!hibernation_available()) +		return -EPERM; +  	lock_system_sleep();  	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { @@ -69,6 +73,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)  		data->swap = swsusp_resume_device ?  			swap_type_of(swsusp_resume_device, 0, NULL) : -1;  		data->mode = O_RDONLY; +		data->free_bitmaps = false;  		error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);  		if (error)  			pm_notifier_call_chain(PM_POST_HIBERNATION); @@ -82,15 +87,19 @@ static int snapshot_open(struct inode *inode, struct file *filp)  		data->swap = -1;  		data->mode = O_WRONLY;  		error = pm_notifier_call_chain(PM_RESTORE_PREPARE); +		if (!error) { +			error = create_basic_memory_bitmaps(); +			data->free_bitmaps = !error; +		}  		if (error)  			pm_notifier_call_chain(PM_POST_RESTORE);  	}  	if (error)  		atomic_inc(&snapshot_device_available); -	data->frozen = 0; -	data->ready = 0; -	data->platform_support = 0; +	data->frozen = false; +	data->ready = false; +	data->platform_support = false;   Unlock:  	unlock_system_sleep(); @@ -111,6 +120,8 @@ static int snapshot_release(struct inode *inode, struct file *filp)  		pm_restore_gfp_mask();  		free_basic_memory_bitmaps();  		thaw_processes(); +	} else if (data->free_bitmaps) { +		free_basic_memory_bitmaps();  	}  	pm_notifier_call_chain(data->mode == O_RDONLY ?  			PM_POST_HIBERNATION : PM_POST_RESTORE); @@ -222,7 +233,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,  		if (error)  			thaw_processes();  		else -			data->frozen = 1; +			data->frozen = true;  		break; @@ -231,8 +242,9 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,  			break;  		pm_restore_gfp_mask();  		free_basic_memory_bitmaps(); +		data->free_bitmaps = false;  		thaw_processes(); -		data->frozen = 0; +		data->frozen = false;  		break;  	case SNAPSHOT_CREATE_IMAGE: @@ -262,7 +274,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,  	case SNAPSHOT_FREE:  		swsusp_free();  		memset(&data->handle, 0, sizeof(struct snapshot_handle)); -		data->ready = 0; +		data->ready = false;  		/*  		 * It is necessary to thaw kernel threads here, because  		 * SNAPSHOT_CREATE_IMAGE may be invoked directly after @@ -326,7 +338,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,  		 * PM_HIBERNATION_PREPARE  		 */  		error = suspend_devices_and_enter(PM_SUSPEND_MEM); -		data->ready = 0; +		data->ready = false;  		break;  	case SNAPSHOT_PLATFORM_SUPPORT:  | 
