From f1a6254cf1f400d6c3fdfc28daf601fc3074dedf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 May 2012 21:03:47 +0200 Subject: [PATCH] Flush block cache on adding disk to device map. * grub-core/kern/emu/hostdisk.c (flush_initial_buffer): New function. (grub_hostdisk_os_dev_to_grub_drive): Call flush_initial_buffer on adding. (read_device_map): Likewise. (open_device): Flush on opening. --- ChangeLog | 10 ++++++++++ grub-core/kern/emu/hostdisk.c | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/ChangeLog b/ChangeLog index c18c1d1db..62df29c96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-05-10 Vladimir Serbinenko + + Flush block cache on adding disk to device map. + + * grub-core/kern/emu/hostdisk.c (flush_initial_buffer): New function. + (grub_hostdisk_os_dev_to_grub_drive): Call flush_initial_buffer on + adding. + (read_device_map): Likewise. + (open_device): Flush on opening. + 2012-05-10 Vladimir Serbinenko * grub-core/fs/cpio.c (grub_cpio_find_file): Handle prefix. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e3d8c8f7d..bc41551a8 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -764,6 +764,21 @@ grub_util_fd_seek (int fd, const char *name, grub_uint64_t off) } #endif +static void +flush_initial_buffer (const char *os_dev __attribute__ ((unused))) +{ +#ifdef __linux__ + int fd; + struct stat st; + + fd = open (os_dev, O_RDONLY); + if (fd >= 0 && fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode)) + ioctl (fd, BLKFLSBUF, 0); + if (fd >= 0) + close (fd); +#endif +} + const char * grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add) { @@ -788,6 +803,8 @@ grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add) strcpy (map[i].drive + sizeof ("hostdisk/") - 1, os_disk); map[i].device_map = 0; + flush_initial_buffer (os_disk); + return map[i].drive; } @@ -872,6 +889,11 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags, data->dev = xstrdup (dev); data->access_mode = (flags & O_ACCMODE); data->fd = fd; + +#ifdef __linux__ + if (data->is_disk) + ioctl (data->fd, BLKFLSBUF, 0); +#endif } if (is_partition) @@ -1329,6 +1351,8 @@ read_device_map (const char *dev_map) drive_e, map[drive].drive); *drive_p = c; } + + flush_initial_buffer (map[drive].device); } fclose (fp);