/*
* linux/fs/block_dev.c
*
* (C) 1991 Linus Torvalds
*/

#include <errno.h>		// ͷļϵͳиֳš(Linus minix )

#include <linux/sched.h>	// ȳͷļṹtask_structʼ0 ݣ
// һЩйúͻȡǶʽຯ䡣
#include <linux/kernel.h>	// ںͷļһЩں˳úԭζ塣
#include <asm/segment.h>	// βͷļйضμĴǶʽຯ
#include <asm/system.h>		// ϵͳͷļû޸/жŵȵǶʽꡣ

//// ݿд - ָ豸Ӹƫƴдָֽݡ
// dev - 豸ţpos - 豸ļƫָ룻buf - ûַռлַ
// count - Ҫ͵ֽ
// ں˵дٻдݣʲôʱд豸ɸٻ
// ġ⣬Ϊ豸ԿΪλждģ˶дʼλòڿʼ
// ʱҪȽʼֽڵȻҪдݴдʼдÿ飬ٽ
// һд̣ɸٻȥ
int
block_write (int dev, long *pos, char *buf, int count)
{
// pos ַɿʼдĿblock1 ֽڸÿеƫλoffset
  int block = *pos >> BLOCK_SIZE_BITS;
  int offset = *pos & (BLOCK_SIZE - 1);
  int chars;
  int written = 0;
  struct buffer_head *bh;
  register char *p;

// Ҫдֽcountѭִ²ֱȫд롣
  while (count > 0)
    {
// ڸÿпдֽҪдֽһ飬ֻдcount ֽڡ
      chars = BLOCK_SIZE - offset;
      if (chars > count)
	chars = count;
// Ҫд1 ݣֱ1 ٻ飬Ҫ뽫޸ĵݿ飬Ԥ
// ݣȻ󽫿ŵ1
      if (chars == BLOCK_SIZE)
	bh = getblk (dev, block);
      else
	bh = breada (dev, block, block + 1, block + 2, -1);
      block++;
// ʧܣ򷵻дֽûдκֽڣ򷵻سţ
      if (!bh)
	return written ? written : -EIO;
// p ָݿпʼдλáдݲһ飬ӿ鿪ʼд޸ģ
// ֽڣoffset Ϊ㡣
      p = offset + bh->b_data;
      offset = 0;
// ļƫָǰдֽۼдֽcharsͼֵȥ˴Ѵֽ
      *pos += chars;
      written += chars;
      count -= chars;
// ûchars ֽڵp ָĸٻпʼдλá
      while (chars-- > 0)
	*(p++) = get_fs_byte (buf++);
// øû޸ı־ͷŸûҲûüݼ1
      bh->b_dirt = 1;
      brelse (bh);
    }
  return written;		// дֽ˳
}

//// ݿ - ָ豸λöָֽݵٻС
int
block_read (int dev, unsigned long *pos, char *buf, int count)
{
// pos ַɿʼдĿblock1 ֽڸÿеƫλoffset
  int block = *pos >> BLOCK_SIZE_BITS;
  int offset = *pos & (BLOCK_SIZE - 1);
  int chars;
  int read = 0;
  struct buffer_head *bh;
  register char *p;

// Ҫֽcountѭִ²ֱȫ롣
  while (count > 0)
    {
// ڸÿֽҪֽһ飬ֻcount ֽڡ
      chars = BLOCK_SIZE - offset;
      if (chars > count)
	chars = count;
// Ҫݿ飬Ԥݣ򷵻Ѷֽûжκ
// ֽڣ򷵻سšȻ󽫿ŵ1
      if (!(bh = breada (dev, block, block + 1, block + 2, -1)))
	return read ? read : -EIO;
      block++;
// p ָ豸ݿҪȡĿʼλáҪȡݲһ飬ӿ鿪ʼ
// ȡֽڣ轫offset 㡣
      p = offset + bh->b_data;
      offset = 0;
// ļƫָǰѶֽcharsۼѶֽͼֵȥ˴Ѵֽ
      *pos += chars;
      read += chars;
      count -= chars;
// Ӹٻp ָĿʼλøchars ֽݵûͷŸøٻ
      while (chars-- > 0)
	put_fs_byte (*(p++), buf++);
      brelse (bh);
    }
  return read;			// Ѷȡֽ˳
}
