diff options
author | Martin Brandenburg <martin@omnibond.com> | 2018-11-06 19:54:49 +0000 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2019-05-03 14:32:38 -0400 |
commit | 3e9dfc6e1e8bce62a329f1452c7eeccbac230980 (patch) | |
tree | 0624e753c394d07519e2834032626d77d25b791a /fs/orangefs/inode.c | |
parent | 43f34576042eb3256c39b502b22c6755144f7517 (diff) |
orangefs: move do_readv_writev to direct_IO
direct_IO was the only caller and all direct_IO did was call it,
so there's no use in having the code spread out into so many functions.
Signed-off-by: Martin Brandenburg <martin@omnibond.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs/inode.c')
-rw-r--r-- | fs/orangefs/inode.c | 114 |
1 files changed, 111 insertions, 3 deletions
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 3b54974817ea..1c72aa38317d 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -128,10 +128,118 @@ static int orangefs_releasepage(struct page *page, gfp_t foo) static ssize_t orangefs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) { + /* + * Comment from original do_readv_writev: + * Common entry point for read/write/readv/writev + * This function will dispatch it to either the direct I/O + * or buffered I/O path depending on the mount options and/or + * augmented/extended metadata attached to the file. + * Note: File extended attributes override any mount options. + */ struct file *file = iocb->ki_filp; - loff_t pos = *(&iocb->ki_pos); - return do_readv_writev(iov_iter_rw(iter) == WRITE ? - ORANGEFS_IO_WRITE : ORANGEFS_IO_READ, file, &pos, iter); + loff_t pos = iocb->ki_pos; + enum ORANGEFS_io_type type = iov_iter_rw(iter) == WRITE ? + ORANGEFS_IO_WRITE : ORANGEFS_IO_READ; + loff_t *offset = &pos; + struct inode *inode = file->f_mapping->host; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_khandle *handle = &orangefs_inode->refn.khandle; + size_t count = iov_iter_count(iter); + size_t ORIGINALcount = iov_iter_count(iter); + ssize_t total_count = 0; + ssize_t ret = -EINVAL; + int i = 0; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n", + __func__, + handle, + (int)count); + + if (type == ORANGEFS_IO_WRITE) { + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): proceeding with offset : %llu, " + "size %d\n", + __func__, + handle, + llu(*offset), + (int)count); + } + + if (count == 0) { + ret = 0; + goto out; + } + + while (iov_iter_count(iter)) { + size_t each_count = iov_iter_count(iter); + size_t amt_complete; + i++; + + /* how much to transfer in this loop iteration */ + if (each_count > orangefs_bufmap_size_query()) + each_count = orangefs_bufmap_size_query(); + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): size of each_count(%d)\n", + __func__, + handle, + (int)each_count); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): BEFORE wait_for_io: offset is %d\n", + __func__, + handle, + (int)*offset); + + ret = wait_for_direct_io(type, inode, offset, iter, + each_count, 0); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): return from wait_for_io:%d\n", + __func__, + handle, + (int)ret); + + if (ret < 0) + goto out; + + *offset += ret; + total_count += ret; + amt_complete = ret; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): AFTER wait_for_io: offset is %d\n", + __func__, + handle, + (int)*offset); + + /* + * if we got a short I/O operations, + * fall out and return what we got so far + */ + if (amt_complete < each_count) + break; + } /*end while */ + +out: + if (total_count > 0) + ret = total_count; + if (ret > 0) { + if (type == ORANGEFS_IO_READ) { + file_accessed(file); + } else { + file_update_time(file); + if (*offset > i_size_read(inode)) + i_size_write(inode, *offset); + } + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): Value(%d) returned.\n", + __func__, + handle, + (int)ret); + + return ret; } /** ORANGEFS2 implementation of address space operations */ |