*参照元 [#ma0f0012] #backlinks *説明 [#j6deac7d] -パス: [[linux-2.6.33/mm/filemap.c]] -FIXME: これは何? --説明 **引数 [#l5ea757d] -struct kiocb *iocb -- --[[linux-2.6.33/kiocb]] -const struct iovec *iov -- --[[linux-2.6.33/iovec]] -unsigned long nr_segs -- -loff_t *ppos -- **返り値 [#l060fdd7] -ssize_t -- **参考 [#la70e4ed] *実装 [#nbae314b] /** * __generic_file_aio_write - write data to a file * @iocb: IO state structure (file, offset, etc.) * @iov: vector with data to write * @nr_segs: number of segments in the vector * @ppos: position where to write * * This function does all the work needed for actually writing data to a * file. It does all basic checks, removes SUID from the file, updates * modification times and calls proper subroutines depending on whether we * do direct IO or a standard buffered write. * * It expects i_mutex to be grabbed unless we work on a block device or similar * object which does not need locking at all. * * This function does *not* take care of syncing data in case of O_SYNC write. * A caller has to handle it. This is mainly due to the fact that we want to * avoid syncing under i_mutex. */ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos) { struct file *file = iocb->ki_filp; struct address_space * mapping = file->f_mapping; size_t ocount; /* original count */ size_t count; /* after file limit checks */ struct inode *inode = mapping->host; loff_t pos; ssize_t written; ssize_t err; - --[[linux-2.6.33/file]] - --[[linux-2.6.33/address_space]] - --[[linux-2.6.33/inode]] ocount = 0; err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); if (err) return err; - --[[linux-2.6.33/generic_segment_checks()]] count = ocount; pos = *ppos; vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); - --[[linux-2.6.33/vfs_check_frozen()]] /* We can write back this queue in page reclaim */ current->backing_dev_info = mapping->backing_dev_info; written = 0; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); if (err) goto out; - --[[linux-2.6.33/generic_write_checks()]] - --[[linux-2.6.33/S_ISBLK()]] if (count == 0) goto out; err = file_remove_suid(file); if (err) goto out; - --[[linux-2.6.33/file_remove_suid()]] file_update_time(file); - --[[linux-2.6.33/file_update_time()]] /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ if (unlikely(file->f_flags & O_DIRECT)) { - --[[linux-2.6.33/unlikely()]] loff_t endbyte; ssize_t written_buffered; written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos, count, ocount); if (written < 0 || written == count) goto out; - --[[linux-2.6.33/generic_file_direct_write()]] /* * direct-io write to a hole: fall through to buffered I/O * for completing the rest of the request. */ pos += written; count -= written; written_buffered = generic_file_buffered_write(iocb, iov, nr_segs, pos, ppos, count, written); - --[[linux-2.6.33/generic_file_buffered_write()]] /* * If generic_file_buffered_write() retuned a synchronous error * then we want to return the number of bytes which were * direct-written, or the error code if that was zero. Note * that this differs from normal direct-io semantics, which * will return -EFOO even if some bytes were written. */ if (written_buffered < 0) { err = written_buffered; goto out; } /* * We need to ensure that the page cache pages are written to * disk and invalidated to preserve the expected O_DIRECT * semantics. */ endbyte = pos + written_buffered - written - 1; err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte); - --[[linux-2.6.33/filemap_write_and_wait_range()]] if (err == 0) { written = written_buffered; invalidate_mapping_pages(mapping, pos >> PAGE_CACHE_SHIFT, endbyte >> PAGE_CACHE_SHIFT); - --[[linux-2.6.33/invalidate_mapping_pages()]] - --[[linux-2.6.33/PAGE_CACHE_SHIFT]] } else { /* * We don't know how much we wrote, so just return * the number of bytes which were direct-written */ } } else { written = generic_file_buffered_write(iocb, iov, nr_segs, pos, ppos, count, written); } out: current->backing_dev_info = NULL; return written ? written : err; } EXPORT_SYMBOL(__generic_file_aio_write); -ライセンスに関わらずシンボルを公開する。 --[[linux-2.6.33/EXPORT_SYMBOL()]] *コメント [#b5813b22]