diff options
-rw-r--r-- | Documentation/power/userland-swsusp.txt | 12 | ||||
-rw-r--r-- | kernel/power/power.h | 4 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 7 | ||||
-rw-r--r-- | kernel/power/user.c | 18 |
4 files changed, 28 insertions, 13 deletions
diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt index e00c6cf09e85..32f187479697 100644 --- a/Documentation/power/userland-swsusp.txt +++ b/Documentation/power/userland-swsusp.txt | |||
@@ -54,6 +54,8 @@ SNAPSHOT_SET_IMAGE_SIZE - set the preferred maximum size of the image | |||
54 | this number, but if it turns out to be impossible, the kernel will | 54 | this number, but if it turns out to be impossible, the kernel will |
55 | create the smallest image possible) | 55 | create the smallest image possible) |
56 | 56 | ||
57 | SNAPSHOT_GET_IMAGE_SIZE - return the actual size of the hibernation image | ||
58 | |||
57 | SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last | 59 | SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last |
58 | argument should be a pointer to an unsigned int variable that will | 60 | argument should be a pointer to an unsigned int variable that will |
59 | contain the result if the call is successful). | 61 | contain the result if the call is successful). |
@@ -136,13 +138,9 @@ required, as they can use, for example, a special (blank) suspend partition or | |||
136 | a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and | 138 | a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and |
137 | mounted afterwards. | 139 | mounted afterwards. |
138 | 140 | ||
139 | These utilities SHOULD NOT make any assumptions regarding the ordering of | 141 | These utilities MUST NOT make any assumptions regarding the ordering of |
140 | data within the snapshot image, except for the image header that MAY be | 142 | data within the snapshot image. The contents of the image are entirely owned |
141 | assumed to start with an swsusp_info structure, as specified in | 143 | by the kernel and its structure may be changed in future kernel releases. |
142 | kernel/power/power.h. This structure MAY be used by the userland utilities | ||
143 | to obtain some information about the snapshot image, such as the size | ||
144 | of the snapshot image, including the metadata and the header itself, | ||
145 | contained in the .size member of swsusp_info. | ||
146 | 144 | ||
147 | The snapshot image MUST be written to the kernel unaltered (ie. all of the image | 145 | The snapshot image MUST be written to the kernel unaltered (ie. all of the image |
148 | data, metadata and header MUST be written in _exactly_ the same amount, form | 146 | data, metadata and header MUST be written in _exactly_ the same amount, form |
diff --git a/kernel/power/power.h b/kernel/power/power.h index 2093c3a9a994..23c17031ed21 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
@@ -128,6 +128,7 @@ struct snapshot_handle { | |||
128 | #define data_of(handle) ((handle).buffer + (handle).buf_offset) | 128 | #define data_of(handle) ((handle).buffer + (handle).buf_offset) |
129 | 129 | ||
130 | extern unsigned int snapshot_additional_pages(struct zone *zone); | 130 | extern unsigned int snapshot_additional_pages(struct zone *zone); |
131 | extern unsigned long snapshot_get_image_size(void); | ||
131 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); | 132 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); |
132 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); | 133 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); |
133 | extern void snapshot_write_finalize(struct snapshot_handle *handle); | 134 | extern void snapshot_write_finalize(struct snapshot_handle *handle); |
@@ -158,7 +159,8 @@ struct resume_swap_area { | |||
158 | #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) | 159 | #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) |
159 | #define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ | 160 | #define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ |
160 | struct resume_swap_area) | 161 | struct resume_swap_area) |
161 | #define SNAPSHOT_IOC_MAXNR 13 | 162 | #define SNAPSHOT_GET_IMAGE_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 14, loff_t) |
163 | #define SNAPSHOT_IOC_MAXNR 14 | ||
162 | 164 | ||
163 | #define PMOPS_PREPARE 1 | 165 | #define PMOPS_PREPARE 1 |
164 | #define PMOPS_ENTER 2 | 166 | #define PMOPS_ENTER 2 |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 78039b477d2b..c5ce0f34a5d4 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1264,12 +1264,17 @@ static char *check_image_kernel(struct swsusp_info *info) | |||
1264 | } | 1264 | } |
1265 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | 1265 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ |
1266 | 1266 | ||
1267 | unsigned long snapshot_get_image_size(void) | ||
1268 | { | ||
1269 | return nr_copy_pages + nr_meta_pages + 1; | ||
1270 | } | ||
1271 | |||
1267 | static int init_header(struct swsusp_info *info) | 1272 | static int init_header(struct swsusp_info *info) |
1268 | { | 1273 | { |
1269 | memset(info, 0, sizeof(struct swsusp_info)); | 1274 | memset(info, 0, sizeof(struct swsusp_info)); |
1270 | info->num_physpages = num_physpages; | 1275 | info->num_physpages = num_physpages; |
1271 | info->image_pages = nr_copy_pages; | 1276 | info->image_pages = nr_copy_pages; |
1272 | info->pages = nr_copy_pages + nr_meta_pages + 1; | 1277 | info->pages = snapshot_get_image_size(); |
1273 | info->size = info->pages; | 1278 | info->size = info->pages; |
1274 | info->size <<= PAGE_SHIFT; | 1279 | info->size <<= PAGE_SHIFT; |
1275 | return init_header_complete(info); | 1280 | return init_header_complete(info); |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 5bd321bcbb75..88aac26e598a 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -133,7 +133,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
133 | { | 133 | { |
134 | int error = 0; | 134 | int error = 0; |
135 | struct snapshot_data *data; | 135 | struct snapshot_data *data; |
136 | loff_t avail; | 136 | loff_t size; |
137 | sector_t offset; | 137 | sector_t offset; |
138 | 138 | ||
139 | if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) | 139 | if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) |
@@ -210,10 +210,20 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
210 | image_size = arg; | 210 | image_size = arg; |
211 | break; | 211 | break; |
212 | 212 | ||
213 | case SNAPSHOT_GET_IMAGE_SIZE: | ||
214 | if (!data->ready) { | ||
215 | error = -ENODATA; | ||
216 | break; | ||
217 | } | ||
218 | size = snapshot_get_image_size(); | ||
219 | size <<= PAGE_SHIFT; | ||
220 | error = put_user(size, (loff_t __user *)arg); | ||
221 | break; | ||
222 | |||
213 | case SNAPSHOT_AVAIL_SWAP: | 223 | case SNAPSHOT_AVAIL_SWAP: |
214 | avail = count_swap_pages(data->swap, 1); | 224 | size = count_swap_pages(data->swap, 1); |
215 | avail <<= PAGE_SHIFT; | 225 | size <<= PAGE_SHIFT; |
216 | error = put_user(avail, (loff_t __user *)arg); | 226 | error = put_user(size, (loff_t __user *)arg); |
217 | break; | 227 | break; |
218 | 228 | ||
219 | case SNAPSHOT_GET_SWAP_PAGE: | 229 | case SNAPSHOT_GET_SWAP_PAGE: |