support make_ext4fs
[firefly-linux-kernel-4.4.55.git] / fs / block_dev.c
old mode 100644 (file)
new mode 100755 (executable)
index 8bed055..2085707
@@ -28,6 +28,8 @@
 #include <linux/kmemleak.h>
 #include <asm/uaccess.h>
 #include "internal.h"
+#include <linux/mtd/blktrans.h>
+#include <linux/mtd/mtd.h>
 
 struct bdev_inode {
        struct block_device bdev;
@@ -246,7 +248,8 @@ struct super_block *freeze_bdev(struct block_device *bdev)
        if (!sb)
                goto out;
        if (sb->s_flags & MS_RDONLY) {
-               deactivate_locked_super(sb);
+               sb->s_frozen = SB_FREEZE_TRANS;
+               up_write(&sb->s_umount);
                mutex_unlock(&bdev->bd_fsfreeze_mutex);
                return sb;
        }
@@ -307,7 +310,7 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
        BUG_ON(sb->s_bdev != bdev);
        down_write(&sb->s_umount);
        if (sb->s_flags & MS_RDONLY)
-               goto out_deactivate;
+               goto out_unfrozen;
 
        if (sb->s_op->unfreeze_fs) {
                error = sb->s_op->unfreeze_fs(sb);
@@ -321,11 +324,11 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
                }
        }
 
+out_unfrozen:
        sb->s_frozen = SB_UNFROZEN;
        smp_wmb();
        wake_up(&sb->s_wait_unfrozen);
 
-out_deactivate:
        if (sb)
                deactivate_locked_super(sb);
 out_unlock:
@@ -403,7 +406,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
  *     NULL first argument is nfsd_sync_dir() and that's not a directory.
  */
  
-static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
 {
        return sync_blockdev(I_BDEV(filp->f_mapping->host));
 }
@@ -422,6 +425,7 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
                return NULL;
        return &ei->vfs_inode;
 }
+EXPORT_SYMBOL(block_fsync);
 
 static void bdev_destroy_inode(struct inode *inode)
 {
@@ -1173,10 +1177,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
        /*
         * hooks: /n/, see "layering violations".
         */
-       ret = devcgroup_inode_permission(bdev->bd_inode, perm);
-       if (ret != 0) {
-               bdput(bdev);
-               return ret;
+       if (!for_part) {
+               ret = devcgroup_inode_permission(bdev->bd_inode, perm);
+               if (ret != 0) {
+                       bdput(bdev);
+                       return ret;
+               }
        }
 
        lock_kernel();
@@ -1199,6 +1205,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                        if (!bdev->bd_part)
                                goto out_clear;
 
+                       ret = 0;
                        if (disk->fops->open) {
                                ret = disk->fops->open(bdev, mode);
                                if (ret == -ERESTARTSYS) {
@@ -1214,9 +1221,18 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                                        mutex_unlock(&bdev->bd_mutex);
                                        goto restart;
                                }
-                               if (ret)
-                                       goto out_clear;
                        }
+                       /*
+                        * If the device is invalidated, rescan partition
+                        * if open succeeded or failed with -ENOMEDIUM.
+                        * The latter is necessary to prevent ghost
+                        * partitions on a removed medium.
+                        */
+                       if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
+                               rescan_partitions(disk, bdev);
+                       if (ret)
+                               goto out_clear;
+
                        if (!bdev->bd_openers) {
                                bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
                                bdi = blk_get_backing_dev_info(bdev);
@@ -1224,8 +1240,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                                        bdi = &default_backing_dev_info;
                                bdev->bd_inode->i_data.backing_dev_info = bdi;
                        }
-                       if (bdev->bd_invalidated)
-                               rescan_partitions(disk, bdev);
                } else {
                        struct block_device *whole;
                        whole = bdget_disk(disk, 0);
@@ -1252,13 +1266,14 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                put_disk(disk);
                disk = NULL;
                if (bdev->bd_contains == bdev) {
-                       if (bdev->bd_disk->fops->open) {
+                       ret = 0;
+                       if (bdev->bd_disk->fops->open)
                                ret = bdev->bd_disk->fops->open(bdev, mode);
-                               if (ret)
-                                       goto out_unlock_bdev;
-                       }
-                       if (bdev->bd_invalidated)
+                       /* the same as first opener case, read comment there */
+                       if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
                                rescan_partitions(bdev->bd_disk, bdev);
+                       if (ret)
+                               goto out_unlock_bdev;
                }
        }
        bdev->bd_openers++;
@@ -1461,12 +1476,85 @@ static const struct address_space_operations def_blk_aops = {
        .direct_IO      = blkdev_direct_IO,
 };
 
+
+ssize_t mydo_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+{
+    unsigned long buf_addr = (unsigned long)buf;
+    if((memcmp(filp->f_mapping->host->i_bdev->bd_disk->disk_name, "mtdblock", 8) == 0) &&(buf_addr >= 0xc0000000))// kernel mem is usb tran &&(buf_addr >= 0xc0000000)
+    {
+        struct mtd_blktrans_dev *dev;
+        struct mtd_blktrans_ops *tr;
+        struct mtd_info *mtd;
+        
+        dev = (filp->f_mapping->host->i_bdev->bd_disk->private_data);
+        mtd = dev->mtd;
+        /*if((buf_addr < 0xc0000000)&&(mtd->name[0]=='u' &&mtd->name[3]=='r' && mtd->name[4]==0)) // user part 
+        {
+            return(do_sync_read(filp, buf,len,ppos));
+        }*/
+        tr = dev->tr;
+               if (!tr->readsect)
+               {
+                       return(do_sync_read(filp, buf,len,ppos));
+           }
+        //printk("mydo_sync_read buf = 0x%lx LBA = 0x%lx len = 0x%x \n",buf, (unsigned long)(*ppos>>9),len);
+        if(tr->readsect(dev, (unsigned long)(*ppos>>9), len>>9, buf))
+        {
+            return 0 ;
+        }
+        *ppos += len;
+        return len;
+    }
+
+    else
+    {
+        return(do_sync_read(filp, buf,len,ppos));
+    }
+}
+
+ssize_t mydo_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+{
+    unsigned long buf_addr = (unsigned long)buf;
+    if((memcmp(filp->f_mapping->host->i_bdev->bd_disk->disk_name, "mtdblock", 8) == 0) &&(buf_addr >= 0xc0000000))// kernel mem is usb tran &&(buf_addr >= 0xc0000000)
+    {
+        struct mtd_blktrans_dev *dev;
+        struct mtd_blktrans_ops *tr;
+        struct mtd_info *mtd;
+        
+        dev = (filp->f_mapping->host->i_bdev->bd_disk->private_data);
+        
+        mtd = dev->mtd;
+        /*if((buf_addr < 0xc0000000)&&(mtd->name[0]=='u' &&mtd->name[3]=='r' && mtd->name[4]==0))
+        {
+            return(do_sync_write(filp, buf,len,ppos));
+        }*/
+
+        tr = dev->tr;
+
+               if (!tr->writesect)
+                       return 0;
+        //printk("mydo_sync_write buf = 0x%lx LBA = 0x%lx len = 0x%x \n",buf, (unsigned long)(*ppos>>9),len);
+        if(tr->writesect(dev, (unsigned long)(*ppos>>9), len>>9, buf))
+        {
+            return 0 ;
+        }
+        *ppos += len;
+        return len;
+    }
+
+    else
+    {
+        return(do_sync_write(filp, buf,len,ppos));
+    }
+}
+
+
 const struct file_operations def_blk_fops = {
        .open           = blkdev_open,
        .release        = blkdev_close,
        .llseek         = block_llseek,
-       .read           = do_sync_read,
-       .write          = do_sync_write,
+       .read           = mydo_sync_read,
+       .write          = mydo_sync_write,
        .aio_read       = generic_file_aio_read,
        .aio_write      = blkdev_aio_write,
        .mmap           = generic_file_mmap,