root/drivers/staging/exfat/exfat_blkdev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bdev_open
  2. bdev_close
  3. bdev_read
  4. bdev_write
  5. bdev_sync

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
   4  */
   5 
   6 #include <linux/blkdev.h>
   7 #include <linux/buffer_head.h>
   8 #include <linux/fs.h>
   9 #include "exfat.h"
  10 
  11 void bdev_open(struct super_block *sb)
  12 {
  13         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
  14 
  15         if (p_bd->opened)
  16                 return;
  17 
  18         p_bd->sector_size      = bdev_logical_block_size(sb->s_bdev);
  19         p_bd->sector_size_bits = ilog2(p_bd->sector_size);
  20         p_bd->sector_size_mask = p_bd->sector_size - 1;
  21         p_bd->num_sectors      = i_size_read(sb->s_bdev->bd_inode) >>
  22                                  p_bd->sector_size_bits;
  23         p_bd->opened = true;
  24 }
  25 
  26 void bdev_close(struct super_block *sb)
  27 {
  28         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
  29 
  30         p_bd->opened = false;
  31 }
  32 
  33 int bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh,
  34               u32 num_secs, bool read)
  35 {
  36         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
  37         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
  38 #ifdef CONFIG_EXFAT_KERNEL_DEBUG
  39         struct exfat_sb_info *sbi = EXFAT_SB(sb);
  40         long flags = sbi->debug_flags;
  41 
  42         if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
  43                 return FFS_MEDIAERR;
  44 #endif /* CONFIG_EXFAT_KERNEL_DEBUG */
  45 
  46         if (!p_bd->opened)
  47                 return FFS_MEDIAERR;
  48 
  49         if (*bh)
  50                 __brelse(*bh);
  51 
  52         if (read)
  53                 *bh = __bread(sb->s_bdev, secno,
  54                               num_secs << p_bd->sector_size_bits);
  55         else
  56                 *bh = __getblk(sb->s_bdev, secno,
  57                                num_secs << p_bd->sector_size_bits);
  58 
  59         if (*bh)
  60                 return 0;
  61 
  62         WARN(!p_fs->dev_ejected,
  63              "[EXFAT] No bh, device seems wrong or to be ejected.\n");
  64 
  65         return FFS_MEDIAERR;
  66 }
  67 
  68 int bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh,
  69                u32 num_secs, bool sync)
  70 {
  71         s32 count;
  72         struct buffer_head *bh2;
  73         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
  74         struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
  75 #ifdef CONFIG_EXFAT_KERNEL_DEBUG
  76         struct exfat_sb_info *sbi = EXFAT_SB(sb);
  77         long flags = sbi->debug_flags;
  78 
  79         if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
  80                 return FFS_MEDIAERR;
  81 #endif /* CONFIG_EXFAT_KERNEL_DEBUG */
  82 
  83         if (!p_bd->opened)
  84                 return FFS_MEDIAERR;
  85 
  86         if (secno == bh->b_blocknr) {
  87                 lock_buffer(bh);
  88                 set_buffer_uptodate(bh);
  89                 mark_buffer_dirty(bh);
  90                 unlock_buffer(bh);
  91                 if (sync && (sync_dirty_buffer(bh) != 0))
  92                         return FFS_MEDIAERR;
  93         } else {
  94                 count = num_secs << p_bd->sector_size_bits;
  95 
  96                 bh2 = __getblk(sb->s_bdev, secno, count);
  97                 if (!bh2)
  98                         goto no_bh;
  99 
 100                 lock_buffer(bh2);
 101                 memcpy(bh2->b_data, bh->b_data, count);
 102                 set_buffer_uptodate(bh2);
 103                 mark_buffer_dirty(bh2);
 104                 unlock_buffer(bh2);
 105                 if (sync && (sync_dirty_buffer(bh2) != 0)) {
 106                         __brelse(bh2);
 107                         goto no_bh;
 108                 }
 109                 __brelse(bh2);
 110         }
 111 
 112         return 0;
 113 
 114 no_bh:
 115         WARN(!p_fs->dev_ejected,
 116              "[EXFAT] No bh, device seems wrong or to be ejected.\n");
 117 
 118         return FFS_MEDIAERR;
 119 }
 120 
 121 int bdev_sync(struct super_block *sb)
 122 {
 123         struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
 124 #ifdef CONFIG_EXFAT_KERNEL_DEBUG
 125         struct exfat_sb_info *sbi = EXFAT_SB(sb);
 126         long flags = sbi->debug_flags;
 127 
 128         if (flags & EXFAT_DEBUGFLAGS_ERROR_RW)
 129                 return FFS_MEDIAERR;
 130 #endif /* CONFIG_EXFAT_KERNEL_DEBUG */
 131 
 132         if (!p_bd->opened)
 133                 return FFS_MEDIAERR;
 134 
 135         return sync_blockdev(sb->s_bdev);
 136 }

/* [<][>][^][v][top][bottom][index][help] */