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 戻せって簡単に書いてあるんですが、何を戻せば良いのやら。