Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 46276
b: refs/heads/master
c: c7b3383
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Feb 5, 2007
1 parent 902e888 commit 1666c21
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 927255f0383342f5d49b82adb6689b9cba52a6f5
refs/heads/master: c7b3383437ff41781964d1bf7f40ff8d7dd5bc47
74 changes: 45 additions & 29 deletions trunk/fs/gfs2/ops_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,36 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset)
return;
}

/**
* gfs2_ok_for_dio - check that dio is valid on this file
* @ip: The inode
* @rw: READ or WRITE
* @offset: The offset at which we are reading or writing
*
* Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o)
* 1 (to accept the i/o request)
*/
static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset)
{
/*
* Should we return an error here? I can't see that O_DIRECT for
* a journaled file makes any sense. For now we'll silently fall
* back to buffered I/O, likewise we do the same for stuffed
* files since they are (a) small and (b) unaligned.
*/
if (gfs2_is_jdata(ip))
return 0;

if (gfs2_is_stuffed(ip))
return 0;

if (offset > i_size_read(&ip->i_inode))
return 0;
return 1;
}



static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset,
unsigned long nr_segs)
Expand All @@ -604,42 +634,28 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
struct gfs2_holder gh;
int rv;

if (rw == READ)
mutex_lock(&inode->i_mutex);
/*
* Shared lock, even if its a write, since we do no allocation
* on this path. All we need change is atime.
* Deferred lock, even if its a write, since we do no allocation
* on this path. All we need change is atime, and this lock mode
* ensures that other nodes have flushed their buffered read caches
* (i.e. their page cache entries for this inode). We do not,
* unfortunately have the option of only flushing a range like
* the VFS does.
*/
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, GL_ATIME, &gh);
rv = gfs2_glock_nq_atime(&gh);
if (rv)
goto out;

if (offset > i_size_read(inode))
goto out;

/*
* Should we return an error here? I can't see that O_DIRECT for
* a journaled file makes any sense. For now we'll silently fall
* back to buffered I/O, likewise we do the same for stuffed
* files since they are (a) small and (b) unaligned.
*/
if (gfs2_is_jdata(ip))
goto out;

if (gfs2_is_stuffed(ip))
goto out;

rv = blockdev_direct_IO_own_locking(rw, iocb, inode,
inode->i_sb->s_bdev,
iov, offset, nr_segs,
gfs2_get_block_direct, NULL);
return rv;
rv = gfs2_ok_for_dio(ip, rw, offset);
if (rv != 1)
goto out; /* dio not valid, fall back to buffered i/o */

rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev,
iov, offset, nr_segs,
gfs2_get_block_direct, NULL);
out:
gfs2_glock_dq_m(1, &gh);
gfs2_holder_uninit(&gh);
if (rw == READ)
mutex_unlock(&inode->i_mutex);

return rv;
}

Expand Down

0 comments on commit 1666c21

Please sign in to comment.