1

非常に単純なファイルシステム ドライバー カーネル モジュールを実装しようとしています。マウントフォルダー内にファイルを作成し、マウントされたデバイスへの読み取り/書き込みアクセスを提供するだけです。いくつかのファイルに接続されたループ デバイスを考えてみましょう。次に、このデバイスが新しいファイルシステムタイプを使用して何らかのディレクトリにマウントされている場合、ユーザーは、単一のファイルシステムファイルを一種のインターフェイスとして使用して、ループに接続されたファイルを読み取り/書き込み/変更できるようになります。ファイルへのアクセスは、メモリ ページ メカニズムを使用して実装する必要があります。

これまでのところ、FS 単一ファイルを正常に作成できました。ルート用の inode と dentry と、ルート フォルダ内のファイルがあります。ここで、ファイル アクセスの操作を提供する必要があります。そこで、file_operationsfile として使用する型構造を作成しましたinode->f_opsread/write/aio_read/aio_write関数がありますが、関数はread単に呼び出しdo_sync_read、. それは書くことにも言えることです。aio_readgeneric_file_aio_read

static struct file_operations fs_file_ops = {
    .read       = do_sync_read,
    .aio_read   = generic_file_aio_read,
    .write      = do_sync_write,
    .aio_write  = generic_file_aio_write,
}

address_space_operationsまた、として使用する構造を作成しましたinode->i_mapping->a_ops。機能がreadpageありwritepageます。私のreadpage実装はmpage_readpage標準関数を呼び出します。引数と関数mpage_readpageで呼び出されます。readpage pageget_block

static struct address_space_operations fs_aops = {
    .readpage = fs_readpage,
    .writepage = fs_writepage 
};

static int fs_readpage(struct file *file, struct page *page)
{
     return mpage_readpage(page, fs_get_block);
}

get_block関数はスーパーブロックをバッファにマップし、メモリ ページ処理用のブロックを提供します。これは次の方法で実装されます。

static int fs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, int create)
{
    map_bh(bh, inode->i_sb, block);
    size_t i_b_size = bh->b_size >> inode->i_blkbits;
    size_t r_b_size = i_size_read(inode) >> inode->i_blkbits - block;
    bh->b_size = min(i_b_size, r_b_size) << inode->i_blkbits;
    return 0;
}

したがって、ユーザーがファイルから何かを読み取ろうとすると、do_sync_readが呼び出され、 が使用されますgeneric_file_aio_read。これは関数を呼び出し、readpage関数はページのブロックを提供する引数として取る をreadpage呼び出します。この関数は、ページごとにファイルの読み取りを実装する必要があります。mpage_readpagefs_get_block

問題は、今のところ、FS ファイルから必要な出力を取得できていないことです。では、私の実装の何が問題なのですか? 不完全な場合、それを機能させるためにモジュールにどの関数を実装する必要がありますか? または、おそらく、問題は私の実装にあるget_block?

4

0 に答える 0