skge: default WOL should be magic only (rev2)
[powerpc.git] / fs / block_dev.c
index d9bdf2b..7428992 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mount.h>
 #include <linux/uio.h>
 #include <linux/namei.h>
+#include <linux/log2.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -55,17 +56,19 @@ static sector_t max_block(struct block_device *bdev)
        return retval;
 }
 
-/* Kill _all_ buffers, dirty or not.. */
+/* Kill _all_ buffers and pagecache , dirty or not.. */
 static void kill_bdev(struct block_device *bdev)
 {
-       invalidate_bdev(bdev, 1);
+       if (bdev->bd_inode->i_mapping->nrpages == 0)
+               return;
+       invalidate_bh_lrus();
        truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 }      
 
 int set_blocksize(struct block_device *bdev, int size)
 {
        /* Size must be a power of two, and between 512 and PAGE_SIZE */
-       if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
+       if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
                return -EINVAL;
 
        /* Size cannot be smaller than the size supported by the device */
@@ -129,6 +132,46 @@ blkdev_get_block(struct inode *inode, sector_t iblock,
        return 0;
 }
 
+static int
+blkdev_get_blocks(struct inode *inode, sector_t iblock,
+               struct buffer_head *bh, int create)
+{
+       sector_t end_block = max_block(I_BDEV(inode));
+       unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
+
+       if ((iblock + max_blocks) > end_block) {
+               max_blocks = end_block - iblock;
+               if ((long)max_blocks <= 0) {
+                       if (create)
+                               return -EIO;    /* write fully beyond EOF */
+                       /*
+                        * It is a read which is fully beyond EOF.  We return
+                        * a !buffer_mapped buffer
+                        */
+                       max_blocks = 0;
+               }
+       }
+
+       bh->b_bdev = I_BDEV(inode);
+       bh->b_blocknr = iblock;
+       bh->b_size = max_blocks << inode->i_blkbits;
+       if (max_blocks)
+               set_buffer_mapped(bh);
+       return 0;
+}
+
+static ssize_t
+blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+                       loff_t offset, unsigned long nr_segs)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file->f_mapping->host;
+
+       return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode),
+                               iov, offset, nr_segs, blkdev_get_blocks, NULL);
+}
+
+#if 0
 static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
 {
        struct kiocb *iocb = bio->bi_private;
@@ -323,6 +366,7 @@ backout:
                return PTR_ERR(page);
        goto completion;
 }
+#endif
 
 static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
 {
@@ -414,9 +458,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
        struct bdev_inode *ei = (struct bdev_inode *) foo;
        struct block_device *bdev = &ei->bdev;
 
-       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-           SLAB_CTOR_CONSTRUCTOR)
-       {
+       if (flags & SLAB_CTOR_CONSTRUCTOR) {
                memset(bdev, 0, sizeof(*bdev));
                mutex_init(&bdev->bd_mutex);
                sema_init(&bdev->bd_mount_sem, 1);
@@ -448,7 +490,7 @@ static void bdev_clear_inode(struct inode *inode)
        spin_unlock(&bdev_lock);
 }
 
-static struct super_operations bdev_sops = {
+static const struct super_operations bdev_sops = {
        .statfs = simple_statfs,
        .alloc_inode = bdev_alloc_inode,
        .destroy_inode = bdev_destroy_inode,
@@ -1060,6 +1102,13 @@ static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags,
                        int for_part);
 static int __blkdev_put(struct block_device *bdev, int for_part);
 
+/*
+ * bd_mutex locking:
+ *
+ *  mutex_lock(part->bd_mutex)
+ *    mutex_lock_nested(whole->bd_mutex, 1)
+ */
+
 static int do_open(struct block_device *bdev, struct file *file, int for_part)
 {
        struct module *owner = NULL;
@@ -1430,7 +1479,7 @@ int __invalidate_device(struct block_device *bdev)
                res = invalidate_inodes(sb);
                drop_super(sb);
        }
-       invalidate_bdev(bdev, 0);
+       invalidate_bdev(bdev);
        return res;
 }
 EXPORT_SYMBOL(__invalidate_device);