diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2018-06-19 17:08:02 +0300 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2018-07-02 18:27:32 +0300 |
commit | 967bcc91b044936e85dbb5848952dc1335a846f4 (patch) | |
tree | 730618d2da59b6097f6799c17ad2a4effb9ca34a /fs/gfs2/bmap.c | |
parent | bcfe94139a45fae128844558d6e27a0258860a90 (diff) | |
download | linux-967bcc91b044936e85dbb5848952dc1335a846f4.tar.xz |
gfs2: iomap direct I/O support
The page unmapping previously done in gfs2_direct_IO is now done
generically in iomap_dio_rw.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r-- | fs/gfs2/bmap.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 8b5876e19ecf..29391090d5b7 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -915,6 +915,9 @@ do_alloc: } else if (flags & IOMAP_WRITE) { u64 alloc_size; + if (flags & IOMAP_DIRECT) + goto out; /* (see gfs2_file_direct_write) */ + len = gfs2_alloc_size(inode, mp, len); alloc_size = len << inode->i_blkbits; if (alloc_size < iomap->length) @@ -1082,11 +1085,18 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, int ret; trace_gfs2_iomap_start(ip, pos, length, flags); - if (flags & IOMAP_WRITE) { + if ((flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)) { ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap); } else { ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp); release_metapath(&mp); + /* + * Silently fall back to buffered I/O for stuffed files or if + * we've hot a hole (see gfs2_file_direct_write). + */ + if ((flags & IOMAP_WRITE) && (flags & IOMAP_DIRECT) && + iomap->type != IOMAP_MAPPED) + ret = -ENOTBLK; } trace_gfs2_iomap_end(ip, iomap, ret); return ret; @@ -1100,7 +1110,7 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length, struct gfs2_trans *tr = current->journal_info; struct buffer_head *dibh = iomap->private; - if (!(flags & IOMAP_WRITE)) + if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) != IOMAP_WRITE) goto out; if (iomap->type != IOMAP_INLINE) { |