Move grub_disk_write out of kernel into disk.mod.
This commit is contained in:
		
							parent
							
								
									04dea7e6c2
								
							
						
					
					
						commit
						442b86de32
					
				
					 8 changed files with 259 additions and 189 deletions
				
			
		
							
								
								
									
										154
									
								
								grub-core/lib/disk.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								grub-core/lib/disk.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | |||
| /*
 | ||||
|  *  GRUB  --  GRand Unified Bootloader | ||||
|  *  Copyright (C) 2002,2003,2004,2006,2007,2008,2009,2010  Free Software Foundation, Inc. | ||||
|  * | ||||
|  *  GRUB is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  GRUB is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include <grub/disk.h> | ||||
| #include <grub/err.h> | ||||
| #include <grub/mm.h> | ||||
| #include <grub/types.h> | ||||
| #include <grub/partition.h> | ||||
| #include <grub/misc.h> | ||||
| #include <grub/time.h> | ||||
| #include <grub/file.h> | ||||
| #include <grub/i18n.h> | ||||
| 
 | ||||
| GRUB_MOD_LICENSE ("GPLv3+"); | ||||
| 
 | ||||
| #include "../kern/disk_common.c" | ||||
| 
 | ||||
| static void | ||||
| grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id, | ||||
| 			    grub_disk_addr_t sector) | ||||
| { | ||||
|   unsigned cache_index; | ||||
|   struct grub_disk_cache *cache; | ||||
| 
 | ||||
|   sector &= ~(GRUB_DISK_CACHE_SIZE - 1); | ||||
|   cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); | ||||
|   cache = grub_disk_cache_table + cache_index; | ||||
| 
 | ||||
|   if (cache->dev_id == dev_id && cache->disk_id == disk_id | ||||
|       && cache->sector == sector && cache->data) | ||||
|     { | ||||
|       cache->lock = 1; | ||||
|       grub_free (cache->data); | ||||
|       cache->data = 0; | ||||
|       cache->lock = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| grub_err_t | ||||
| grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, | ||||
| 		 grub_off_t offset, grub_size_t size, const void *buf) | ||||
| { | ||||
|   unsigned real_offset; | ||||
|   grub_disk_addr_t aligned_sector; | ||||
| 
 | ||||
|   grub_dprintf ("disk", "Writing `%s'...\n", disk->name); | ||||
| 
 | ||||
|   if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) | ||||
|     return -1; | ||||
| 
 | ||||
|   aligned_sector = (sector & ~((1 << (disk->log_sector_size | ||||
| 				      - GRUB_DISK_SECTOR_BITS)) - 1)); | ||||
|   real_offset = offset + ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); | ||||
|   sector = aligned_sector; | ||||
| 
 | ||||
|   while (size) | ||||
|     { | ||||
|       if (real_offset != 0 || (size < (1U << disk->log_sector_size) | ||||
| 			       && size != 0)) | ||||
| 	{ | ||||
| 	  char *tmp_buf; | ||||
| 	  grub_size_t len; | ||||
| 	  grub_partition_t part; | ||||
| 
 | ||||
| 	  tmp_buf = grub_malloc (1 << disk->log_sector_size); | ||||
| 	  if (!tmp_buf) | ||||
| 	    return grub_errno; | ||||
| 
 | ||||
| 	  part = disk->partition; | ||||
| 	  disk->partition = 0; | ||||
| 	  if (grub_disk_read (disk, sector, | ||||
| 			      0, (1 << disk->log_sector_size), tmp_buf) | ||||
| 	      != GRUB_ERR_NONE) | ||||
| 	    { | ||||
| 	      disk->partition = part; | ||||
| 	      grub_free (tmp_buf); | ||||
| 	      goto finish; | ||||
| 	    } | ||||
| 	  disk->partition = part; | ||||
| 
 | ||||
| 	  len = (1 << disk->log_sector_size) - real_offset; | ||||
| 	  if (len > size) | ||||
| 	    len = size; | ||||
| 
 | ||||
| 	  grub_memcpy (tmp_buf + real_offset, buf, len); | ||||
| 
 | ||||
| 	  grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); | ||||
| 
 | ||||
| 	  if ((disk->dev->write) (disk, transform_sector (disk, sector), | ||||
| 				  1, tmp_buf) != GRUB_ERR_NONE) | ||||
| 	    { | ||||
| 	      grub_free (tmp_buf); | ||||
| 	      goto finish; | ||||
| 	    } | ||||
| 
 | ||||
| 	  grub_free (tmp_buf); | ||||
| 
 | ||||
| 	  sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); | ||||
| 	  buf = (const char *) buf + len; | ||||
| 	  size -= len; | ||||
| 	  real_offset = 0; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  grub_size_t len; | ||||
| 	  grub_size_t n; | ||||
| 
 | ||||
| 	  len = size & ~((1 << disk->log_sector_size) - 1); | ||||
| 	  n = size >> disk->log_sector_size; | ||||
| 
 | ||||
| 	  if ((disk->dev->write) (disk, transform_sector (disk, sector), | ||||
| 				  n, buf) != GRUB_ERR_NONE) | ||||
| 	    goto finish; | ||||
| 
 | ||||
| 	  while (n--) | ||||
| 	    { | ||||
| 	      grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); | ||||
| 	      sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); | ||||
| 	    } | ||||
| 
 | ||||
| 	  buf = (const char *) buf + len; | ||||
| 	  size -= len; | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|  finish: | ||||
| 
 | ||||
|   return grub_errno; | ||||
| } | ||||
| 
 | ||||
| GRUB_MOD_INIT(disk) | ||||
| { | ||||
|   grub_disk_write_weak = grub_disk_write; | ||||
| } | ||||
| 
 | ||||
| GRUB_MOD_FINI(disk) | ||||
| { | ||||
|   grub_disk_write_weak = NULL; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue