sort out blockdev_direct_IO variants
Move the call to vmtruncate to get rid of accessive blocks to the callers in prepearation of the new truncate calling sequence. This was only done for DIO_LOCKING filesystems, so the __blockdev_direct_IO_newtrunc variant was not needed anyway. Get rid of blockdev_direct_IO_no_locking and its _newtrunc variant while at it as just opencoding the two additional paramters is shorted than the name suffix. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
256249584b
commit
eafdc7d190
@@ -1136,8 +1136,27 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a library function for use by filesystem drivers.
|
||||
*
|
||||
* The locking rules are governed by the flags parameter:
|
||||
* - if the flags value contains DIO_LOCKING we use a fancy locking
|
||||
* scheme for dumb filesystems.
|
||||
* For writes this function is called under i_mutex and returns with
|
||||
* i_mutex held, for reads, i_mutex is not held on entry, but it is
|
||||
* taken and dropped again before returning.
|
||||
* For reads and writes i_alloc_sem is taken in shared mode and released
|
||||
* on I/O completion (which may happen asynchronously after returning to
|
||||
* the caller).
|
||||
*
|
||||
* - if the flags value does NOT contain DIO_LOCKING we don't use any
|
||||
* internal locking but rather rely on the filesystem to synchronize
|
||||
* direct I/O reads/writes versus each other and truncate.
|
||||
* For reads and writes both i_mutex and i_alloc_sem are not held on
|
||||
* entry and are never taken.
|
||||
*/
|
||||
ssize_t
|
||||
__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
struct block_device *bdev, const struct iovec *iov, loff_t offset,
|
||||
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
|
||||
dio_submit_t submit_io, int flags)
|
||||
@@ -1233,57 +1252,4 @@ __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc);
|
||||
|
||||
/*
|
||||
* This is a library function for use by filesystem drivers.
|
||||
*
|
||||
* The locking rules are governed by the flags parameter:
|
||||
* - if the flags value contains DIO_LOCKING we use a fancy locking
|
||||
* scheme for dumb filesystems.
|
||||
* For writes this function is called under i_mutex and returns with
|
||||
* i_mutex held, for reads, i_mutex is not held on entry, but it is
|
||||
* taken and dropped again before returning.
|
||||
* For reads and writes i_alloc_sem is taken in shared mode and released
|
||||
* on I/O completion (which may happen asynchronously after returning to
|
||||
* the caller).
|
||||
*
|
||||
* - if the flags value does NOT contain DIO_LOCKING we don't use any
|
||||
* internal locking but rather rely on the filesystem to synchronize
|
||||
* direct I/O reads/writes versus each other and truncate.
|
||||
* For reads and writes both i_mutex and i_alloc_sem are not held on
|
||||
* entry and are never taken.
|
||||
*/
|
||||
ssize_t
|
||||
__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
struct block_device *bdev, const struct iovec *iov, loff_t offset,
|
||||
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
|
||||
dio_submit_t submit_io, int flags)
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov,
|
||||
offset, nr_segs, get_block, end_io, submit_io, flags);
|
||||
/*
|
||||
* In case of error extending write may have instantiated a few
|
||||
* blocks outside i_size. Trim these off again for DIO_LOCKING.
|
||||
* NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in
|
||||
* their own manner. This is a further example of where the old
|
||||
* truncate sequence is inadequate.
|
||||
*
|
||||
* NOTE: filesystems with their own locking have to handle this
|
||||
* on their own.
|
||||
*/
|
||||
if (flags & DIO_LOCKING) {
|
||||
if (unlikely((rw & WRITE) && retval < 0)) {
|
||||
loff_t isize = i_size_read(inode);
|
||||
loff_t end = offset + iov_length(iov, nr_segs);
|
||||
|
||||
if (end > isize)
|
||||
vmtruncate(inode, isize);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(__blockdev_direct_IO);
|
||||
|
Reference in New Issue
Block a user