WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [patch 4/6] xenblk: Add O_DIRECT and O_SYNC support -- gener

To: Joe Jin <joe.jin@xxxxxxxxxx>
Subject: [Xen-devel] [patch 4/6] xenblk: Add O_DIRECT and O_SYNC support -- generic support for O_SYNC.
From: Joe Jin <joe.jin@xxxxxxxxxx>
Date: Tue, 4 Nov 2008 10:54:14 +0800
Cc: Xen-devel@xxxxxxxxxxxxxxxxxxx, kurt.hackel@xxxxxxxxxx, shinya.narahara@xxxxxxxxxx, greg.marsden@xxxxxxxxxx, wen.gang.wang@xxxxxxxxxx, jens.axboe@xxxxxxxxxx
Delivery-date: Mon, 03 Nov 2008 18:54:54 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20081104025055.GA18236@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20081104025055.GA18236@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.2.2i
[patch 4/6] xenblk: Add O_DIRECT and O_SYNC support -- generic support for 
O_SYNC.

Add new buffer_head flag BH_Sync_Write for sync write.
If the inode with sync flag(always is a mount options) or file open with
O_SYNC flag, mark the buffer_head(s) to Sync_Write flag. On buffer try 
to submit, check the flag, if the flag have setted, mark submit_bio()
rw flag to WRITE_SYNC, then frontend would pass the flag to backend.

diff -r 2fb13b8cbe13 include/linux/buffer_head.h
--- a/include/linux/buffer_head.h       Thu Oct 30 13:34:43 2008 +0000
+++ b/include/linux/buffer_head.h       Mon Nov 03 10:31:41 2008 +0800
@@ -27,6 +27,7 @@
        BH_New,         /* Disk mapping was newly created by get_block */
        BH_Async_Read,  /* Is under end_buffer_async_read I/O */
        BH_Async_Write, /* Is under end_buffer_async_write I/O */
+       BH_Sync_Write,  /* For xenblk O_SYNC write support */
        BH_Delay,       /* Buffer is not yet allocated on disk */
        BH_Boundary,    /* Block is followed by a discontiguity */
        BH_Write_EIO,   /* I/O error on write */
@@ -118,6 +119,7 @@
 BUFFER_FNS(Async_Read, async_read)
 BUFFER_FNS(Async_Write, async_write)
 BUFFER_FNS(Delay, delay)
+BUFFER_FNS(Sync_Write, sync_write)
 BUFFER_FNS(Boundary, boundary)
 BUFFER_FNS(Write_EIO, write_io_error)
 BUFFER_FNS(Ordered, ordered)
@@ -185,6 +187,25 @@
                        sector_t bblock, unsigned blocksize);
 
 extern int buffer_heads_over_limit;
+
+#if defined(CONFIG_XEN) && (defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE) || 
defined(CONFIG_XEN_BLKDEV_FRONTEND))
+#define mark_sync_write_bh(bh) set_buffer_sync_write(bh)
+static inline void mark_sync_write_bhs(struct page *page)
+{
+       struct buffer_head *bh, *head;
+
+       BUG_ON(!page_has_buffers(page));
+       bh = head = page_buffers(page);
+       do {
+               set_buffer_sync_write(bh);
+               bh = bh->b_this_page;
+       } while (bh != head);
+
+}
+#else
+#define mark_sync_write_bh(bh)  do { } while(0)
+#define mark_sync_write_bhs(struct page *page) do { } while(0)
+#endif
 
 /*
  * Generic address_space_operations implementations for buffer_head-backed
 /*
  * Recognised if "feature-flush-cache" is present in backend xenbus
  * info.  A flush will ask the underlying storage hardware to flush its
diff -r 2fb13b8cbe13 fs/buffer.c
--- a/fs/buffer.c       Thu Oct 30 13:34:43 2008 +0000
+++ b/fs/buffer.c       Mon Nov 03 10:31:41 2008 +0800
@@ -616,6 +616,38 @@
        bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
        local_irq_restore(flags);
        return;
+}
+
+static void end_buffer_sync_write(struct buffer_head *bh)
+{
+       unsigned long flags;
+
+       BUG_ON(!buffer_sync_write(bh));
+
+
+       local_irq_save(flags);
+       bit_spin_lock(BH_Uptodate_Lock, &bh->b_state);
+       clear_buffer_sync_write(bh);
+       bit_spin_unlock(BH_Uptodate_Lock, &bh->b_state);
+       local_irq_restore(flags);
+       return;
+}
+
+static int end_bio_bh_io_sync_write(struct bio *bio, unsigned int bytes_done, 
int err)
+{
+       struct buffer_head *bh = bio->bi_private;
+
+       if (bio->bi_size)
+               return 1;
+
+       if (err == -EOPNOTSUPP) {
+               set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+               set_bit(BH_Eopnotsupp, &bh->b_state);
+       }
+       end_buffer_sync_write(bh);
+       bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags));
+       bio_put(bio);
+       return 0;
 }
 
 /*
@@ -2840,6 +2872,13 @@
        bio->bi_end_io = end_bio_bh_io_sync;
        bio->bi_private = bh;
 
+       /* for xenblk O_SYNC support, let frontend mark it as SYNC io,
+        * then backend would submit it immedately */
+       if ((rw & WRITE) && buffer_sync_write(bh))  {
+               bio->bi_end_io = end_bio_bh_io_sync_write;
+               rw |= WRITE_SYNC;
+       }
+
        bio_get(bio);
        submit_bio(rw, bio);
 
@@ -2921,6 +2960,7 @@
        if (test_clear_buffer_dirty(bh)) {
                get_bh(bh);
                bh->b_end_io = end_buffer_write_sync;
+               mark_sync_write_bh(bh);
                ret = submit_bh(WRITE, bh);
                wait_on_buffer(bh);
                if (buffer_eopnotsupp(bh)) {

diff -r 2fb13b8cbe13 mm/filemap.c
--- a/mm/filemap.c      Thu Oct 30 13:34:43 2008 +0000
+++ b/mm/filemap.c      Mon Nov 03 10:31:41 2008 +0800
@@ -2145,6 +2145,8 @@
                                vmtruncate(inode, isize);
                        break;
                }
+               if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+                       mark_sync_write_bhs(page);
                if (likely(nr_segs == 1))
                        copied = filemap_copy_from_user(page, offset,
                                                        buf, bytes);




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel