/* Handle I/O for a BIO component. */ int file_do_bvec(struct file *file, struct bio_vec *bvec, loff_t pos, int rw) { u8 *buf; ssize_t bw; mm_segment_t old_fs = get_fs(); buf = kmap_atomic(bvec->bv_page, KM_USER0) + bvec->bv_offset; set_fs(get_ds()); if (rw == WRITE) bw = vfs_write(file, buf, bvec->bv_len, &pos); else bw = vfs_read(file, buf, bvec->bv_len, &pos); set_fs(old_fs); kunmap_atomic(buf, KM_USER0); cond_resched(); if (likely(bw == len)) return 0; printk(KERN_ERR "Error at byte offset %llu, length %i.\n", (unsigned long long)pos, len); if (bw >= 0) bw = -EIO; return bw; } /* Handle I/O for a BIO. */ int file_do_bio(struct file *file, struct bio *bio, loff_t pos) { struct bio_vec *bvec; struct page *page = NULL; int i, ret = 0; /* Should have read-only check here, BIOs other than READ/WRITE. */ bio_for_each_segment(bvec, bio, i) { ret = file_do_bvec(file, bvec, pos, bio_rw(bio)); if (ret < 0) break; pos += bvec->bv_len; } /* * At some point we need to fsync. In this simple example - I'll do it here. * TBD: should check error. */ vfs_fsync(file, 0); return ret; }
Saturday, October 20, 2012
Linux kernel file I/O from a block driver
This code shows how a hypothetical block driver might handle submitted BIOs, servicing them with a file.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment