kfifo なソレを盛り込んでみる

ちょっとズルっぽいんですが、ヤッてみます。

とりあえず

init なソレで kfifo_alloc() を呼び出す事に。正常でないケースでこの関数が戻すのはどのレンジな値なのかが微妙、と言いつつ IS_ERR で調べれば良さげに見えるな。
で、kfifo_alloc の結果が IS_ERR だったら何を戻せばよいのやら。errno の一覧みたいのが無いんかな。いちいち errno なヘッダ見るのは面倒。このケイスだと -ENOMEM を戻せば良さげ。てーコトで init/exit なソレがとりあえず以下。

static int yamanetoshi_init(void) {
	int ret;

	printk("initialize the fifo device\n");

	ret = register_chrdev(fifo_major, DRIVERNAME, &fifo_fops);

	if(ret < 0)
		return ret;

	if(fifo_major == 0)
		fifo_major = ret;

	fifo_ptr = fifo_alloc(BUFSIZ, GFP_KERNEL, &fifo_lock);

	if(IS_ERR(kfifo_ptr))
		return -ENOMEM;

	return 0;
}

static void yamanetoshi_exit(void) {
	printk("cleanup the fifo device\n");

	kfifo_free(fifo_ptr);

	unregister_chrdev(fifo_major, DRIVERNAME);
}

module_init(yamanetoshi_init);
module_exit(yamanetoshi_exit);

read/write ですな。ちょっとずづ確認しつつ実装。

static ssize_t yamanetoshi_read(struct file *file, 
				char __user *buf, 
				size_t size, 
				loff_t *offset)
{
	DEBUG_OUT("read start");

	if(0 == kfifo_len(fifo_ptr))
		return EOF;

	DEBUG_OUT("read end");
}

なソレで確認してみる。

わははは

試験なプログラム作って動かしてみたら、ものの見事に OS ごとストール。なんで vmware 使わないんだ、と。(とほほほ
で、後天性記憶不全なおやぢはリトライしかけて vmware を起動してる所です。

そして

リトライしたら当たり前ですがストール。上記 read_start が出力されてカタマっている模様。これは spinlock なソレが微妙に違いない、と当たりを付けて google 先生にお伺いすると、どうも spinlock_t 型なソレは spin_lock_init() という関数で初期化しないと駄目なんでしょうか。
という事で、spin_lock_init() を盛り込んだ init が以下

static int yamanetoshi_init(void) {
	int ret;

	printk("initialize the fifo device\n");

	ret = register_chrdev(fifo_major, DRIVERNAME, &fifo_fops);

	if(ret < 0)
		return ret;

	if(fifo_major == 0)
		fifo_major = ret;

	spin_lock_init(&fifo_lock);
	fifo_ptr = kfifo_alloc(BUFSIZ, GFP_KERNEL, &fifo_lock);

	if(IS_ERR(fifo_ptr))
		return -ENOMEM;

	return 0;
}

で、insmod して tail したら以下の微妙な出力。

# insmod yamanetoshi.ko
initialize the fifo device
# tail ./fifo101130
yamanetoshi open
 MINOR(inode->r_rdev): 101
read start
tail: error reading './fifo101130': Operation not permitted
yamanetoshi close
#

なんか違うな。因みに fifo101130 は読み込む権限はある。

敗因

spinlock_t はゼロだったら lock されている、と見るとの事。そのまま使えば unlock 待ちでストールしますな。無知さに自分事ながら呆れますが、ログはそのまま投入。

read の戻り

EOF ではだめなのかなぁ。挙動にあたる errno の絶対値を戻す、とか??
これはこれで根拠を調べる必要あり。

とほほ

asm-generic/errno-base.h を見てみたら

#define	EPERM		 1	/* Operation not permitted */

との事。そのまんま。
EOF 戻せって簡単に書いてあるんですが、何を戻せば良いのやら。