aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-10-25 18:59:31 -0400
committerLen Brown <len.brown@intel.com>2008-02-01 18:30:52 -0500
commitaf508b34d27e3341287d89e0eae6752fdb1b873f (patch)
treeb5d2a337d78dc25aadb02d481443d484e0dd368c /kernel/power
parentaa6299926950c8dfe2fea638276cad6def092bc9 (diff)
Hibernation: Introduce SNAPSHOT_GET_IMAGE_SIZE ioctl
Add a new ioctl, SNAPSHOT_GET_IMAGE_SIZE, returning the size of the (just created) hibernation image, to the hibernation userland interface. This ioctl is necessary so that the userland utilities using the interface need not access the hibernation image header, owned by the kernel, in order to obtain the size of the image. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/power.h4
-rw-r--r--kernel/power/snapshot.c7
-rw-r--r--kernel/power/user.c18
3 files changed, 23 insertions, 6 deletions
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
130extern unsigned int snapshot_additional_pages(struct zone *zone); 130extern unsigned int snapshot_additional_pages(struct zone *zone);
131extern unsigned long snapshot_get_image_size(void);
131extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); 132extern int snapshot_read_next(struct snapshot_handle *handle, size_t count);
132extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); 133extern int snapshot_write_next(struct snapshot_handle *handle, size_t count);
133extern void snapshot_write_finalize(struct snapshot_handle *handle); 134extern 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
1267unsigned long snapshot_get_image_size(void)
1268{
1269 return nr_copy_pages + nr_meta_pages + 1;
1270}
1271
1267static int init_header(struct swsusp_info *info) 1272static 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: