aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/power/userland-swsusp.txt12
-rw-r--r--kernel/power/power.h4
-rw-r--r--kernel/power/snapshot.c7
-rw-r--r--kernel/power/user.c18
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
57SNAPSHOT_GET_IMAGE_SIZE - return the actual size of the hibernation image
58
57SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last 59SNAPSHOT_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
136a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and 138a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and
137mounted afterwards. 139mounted afterwards.
138 140
139These utilities SHOULD NOT make any assumptions regarding the ordering of 141These utilities MUST NOT make any assumptions regarding the ordering of
140data within the snapshot image, except for the image header that MAY be 142data within the snapshot image. The contents of the image are entirely owned
141assumed to start with an swsusp_info structure, as specified in 143by the kernel and its structure may be changed in future kernel releases.
142kernel/power/power.h. This structure MAY be used by the userland utilities
143to obtain some information about the snapshot image, such as the size
144of the snapshot image, including the metadata and the header itself,
145contained in the .size member of swsusp_info.
146 144
147The snapshot image MUST be written to the kernel unaltered (ie. all of the image 145The snapshot image MUST be written to the kernel unaltered (ie. all of the image
148data, metadata and header MUST be written in _exactly_ the same amount, form 146data, 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
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: