Support BtrFS embedding.
* grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. (grub_btrfs_fs) [GRUB_UTIL]: Set embed. * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. * util/grub-setup.c (setup): Use fs embedding if available. Add additional sanity check.
This commit is contained in:
		
							parent
							
								
									455377d93d
								
							
						
					
					
						commit
						c7ba4f6984
					
				
					 4 changed files with 74 additions and 7 deletions
				
			
		
							
								
								
									
										10
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								ChangeLog
									
										
									
									
									
								
							|  | @ -1,3 +1,13 @@ | ||||||
|  | 2011-11-05  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
|  | 
 | ||||||
|  | 	Support BtrFS embedding. | ||||||
|  | 
 | ||||||
|  | 	* grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. | ||||||
|  | 	(grub_btrfs_fs) [GRUB_UTIL]: Set embed. | ||||||
|  | 	* include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. | ||||||
|  | 	* util/grub-setup.c (setup): Use fs embedding if available. | ||||||
|  | 	Add additional sanity check. | ||||||
|  | 
 | ||||||
| 2011-11-05  Vladimir Serbinenko  <phcoder@gmail.com> | 2011-11-05  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
| 
 | 
 | ||||||
| 	* util/grub-install.in: Fix condition for config_opt. | 	* util/grub-install.in: Fix condition for config_opt. | ||||||
|  |  | ||||||
|  | @ -1596,6 +1596,35 @@ grub_btrfs_label (grub_device_t device, char **label) | ||||||
|   return grub_errno; |   return grub_errno; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #ifdef GRUB_UTIL | ||||||
|  | static grub_err_t | ||||||
|  | grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), | ||||||
|  | 		  unsigned int *nsectors, | ||||||
|  | 		  grub_embed_type_t embed_type, | ||||||
|  | 		  grub_disk_addr_t **sectors) | ||||||
|  | { | ||||||
|  |   unsigned i; | ||||||
|  | 
 | ||||||
|  |   if (embed_type != GRUB_EMBED_PCBIOS) | ||||||
|  |     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, | ||||||
|  | 		       "BtrFS curently supports only PC-BIOS embedding"); | ||||||
|  | 
 | ||||||
|  |   if (64 * 2 - 1 < *nsectors) | ||||||
|  |     return grub_error (GRUB_ERR_OUT_OF_RANGE, | ||||||
|  | 		       "Your core.img is unusually large.  " | ||||||
|  | 		       "It won't fit in the embedding area."); | ||||||
|  | 
 | ||||||
|  |   *nsectors = 64 * 2 - 1; | ||||||
|  |   *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | ||||||
|  |   if (!*sectors) | ||||||
|  |     return grub_errno; | ||||||
|  |   for (i = 0; i < *nsectors; i++) | ||||||
|  |     (*sectors)[i] = i + 1; | ||||||
|  | 
 | ||||||
|  |   return GRUB_ERR_NONE; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static struct grub_fs grub_btrfs_fs = { | static struct grub_fs grub_btrfs_fs = { | ||||||
|   .name = "btrfs", |   .name = "btrfs", | ||||||
|   .dir = grub_btrfs_dir, |   .dir = grub_btrfs_dir, | ||||||
|  | @ -1605,6 +1634,7 @@ static struct grub_fs grub_btrfs_fs = { | ||||||
|   .uuid = grub_btrfs_uuid, |   .uuid = grub_btrfs_uuid, | ||||||
|   .label = grub_btrfs_label, |   .label = grub_btrfs_label, | ||||||
| #ifdef GRUB_UTIL | #ifdef GRUB_UTIL | ||||||
|  |   .embed = grub_btrfs_embed, | ||||||
|   .reserved_first_sector = 1, |   .reserved_first_sector = 1, | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -25,6 +25,10 @@ | ||||||
| #include <grub/types.h> | #include <grub/types.h> | ||||||
| 
 | 
 | ||||||
| #include <grub/list.h> | #include <grub/list.h> | ||||||
|  | /* For embedding types.  */ | ||||||
|  | #ifdef GRUB_UTIL | ||||||
|  | #include <grub/partition.h> | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /* Forward declaration is required, because of mutual reference.  */ | /* Forward declaration is required, because of mutual reference.  */ | ||||||
| struct grub_file; | struct grub_file; | ||||||
|  | @ -74,6 +78,11 @@ struct grub_fs | ||||||
|   grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); |   grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); | ||||||
| 
 | 
 | ||||||
| #ifdef GRUB_UTIL | #ifdef GRUB_UTIL | ||||||
|  |   /* Determine sectors available for embedding.  */ | ||||||
|  |   grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors, | ||||||
|  | 		       grub_embed_type_t embed_type, | ||||||
|  | 		       grub_disk_addr_t **sectors); | ||||||
|  | 
 | ||||||
|   /* Whether this filesystem reserves first sector for DOS-style boot.  */ |   /* Whether this filesystem reserves first sector for DOS-style boot.  */ | ||||||
|   int reserved_first_sector; |   int reserved_first_sector; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -408,29 +408,44 @@ setup (const char *dir, | ||||||
| 
 | 
 | ||||||
|     free (tmp_img); |     free (tmp_img); | ||||||
|      |      | ||||||
|     if (! dest_partmap) |     if (! dest_partmap && ! fs) | ||||||
|       { |       { | ||||||
| 	grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea.")); | 	grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea.")); | ||||||
| 	goto unable_to_embed; | 	goto unable_to_embed; | ||||||
|       } |       } | ||||||
|     if (multiple_partmaps || fs) |     if (multiple_partmaps || (dest_partmap && fs)) | ||||||
|       { |       { | ||||||
| 	grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem.  This is not supported yet.")); | 	grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem.  This is not supported yet.")); | ||||||
| 	goto unable_to_embed; | 	goto unable_to_embed; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|     if (!dest_partmap->embed) |     if (dest_partmap && !dest_partmap->embed) | ||||||
|       { |       { | ||||||
| 	grub_util_warn ("Partition style '%s' doesn't support embeding", | 	grub_util_warn ("Partition style '%s' doesn't support embeding", | ||||||
| 			dest_partmap->name); | 			dest_partmap->name); | ||||||
| 	goto unable_to_embed; | 	goto unable_to_embed; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  |     if (fs && !fs->embed) | ||||||
|  |       { | ||||||
|  | 	grub_util_warn ("File system '%s' doesn't support embeding", | ||||||
|  | 			fs->name); | ||||||
|  | 	goto unable_to_embed; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|     nsec = core_sectors; |     nsec = core_sectors; | ||||||
|  |     if (dest_partmap) | ||||||
|       err = dest_partmap->embed (dest_dev->disk, &nsec, |       err = dest_partmap->embed (dest_dev->disk, &nsec, | ||||||
| 				 GRUB_EMBED_PCBIOS, §ors); | 				 GRUB_EMBED_PCBIOS, §ors); | ||||||
|     if (nsec > 2 * core_sectors) |     else | ||||||
|       nsec = 2 * core_sectors; |       err = fs->embed (dest_dev, &nsec, | ||||||
|  | 		       GRUB_EMBED_PCBIOS, §ors); | ||||||
|  |     if (!err && nsec < core_sectors) | ||||||
|  |       { | ||||||
|  | 	err = grub_error (GRUB_ERR_OUT_OF_RANGE, | ||||||
|  | 			  "Your embedding area is unusually small.  " | ||||||
|  | 			  "core.img won't fit in it."); | ||||||
|  |       } | ||||||
|      |      | ||||||
|     if (err) |     if (err) | ||||||
|       { |       { | ||||||
|  | @ -439,6 +454,9 @@ setup (const char *dir, | ||||||
| 	goto unable_to_embed; | 	goto unable_to_embed; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  |     if (nsec > 2 * core_sectors) | ||||||
|  |       nsec = 2 * core_sectors; | ||||||
|  | 
 | ||||||
|     /* Clean out the blocklists.  */ |     /* Clean out the blocklists.  */ | ||||||
|     block = first_block; |     block = first_block; | ||||||
|     while (block->len) |     while (block->len) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue