|
@@ -1875,12 +1875,29 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
|
|
|
ssize_t num_written = 0;
|
|
|
bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
|
|
|
ssize_t err;
|
|
|
- loff_t pos;
|
|
|
- size_t count;
|
|
|
+ loff_t pos = iocb->ki_pos;
|
|
|
+ size_t count = iov_iter_count(from);
|
|
|
loff_t oldsize;
|
|
|
int clean_page = 0;
|
|
|
|
|
|
- inode_lock(inode);
|
|
|
+ if ((iocb->ki_flags & IOCB_NOWAIT) &&
|
|
|
+ (iocb->ki_flags & IOCB_DIRECT)) {
|
|
|
+ /* Don't sleep on inode rwsem */
|
|
|
+ if (!inode_trylock(inode))
|
|
|
+ return -EAGAIN;
|
|
|
+ /*
|
|
|
+ * We will allocate space in case nodatacow is not set,
|
|
|
+ * so bail
|
|
|
+ */
|
|
|
+ if (!(BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
|
|
|
+ BTRFS_INODE_PREALLOC)) ||
|
|
|
+ check_can_nocow(BTRFS_I(inode), pos, &count) <= 0) {
|
|
|
+ inode_unlock(inode);
|
|
|
+ return -EAGAIN;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ inode_lock(inode);
|
|
|
+
|
|
|
err = generic_write_checks(iocb, from);
|
|
|
if (err <= 0) {
|
|
|
inode_unlock(inode);
|
|
@@ -1914,8 +1931,6 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
|
|
|
*/
|
|
|
update_time_for_write(inode);
|
|
|
|
|
|
- pos = iocb->ki_pos;
|
|
|
- count = iov_iter_count(from);
|
|
|
start_pos = round_down(pos, fs_info->sectorsize);
|
|
|
oldsize = i_size_read(inode);
|
|
|
if (start_pos > oldsize) {
|
|
@@ -3071,13 +3086,19 @@ out:
|
|
|
return offset;
|
|
|
}
|
|
|
|
|
|
+static int btrfs_file_open(struct inode *inode, struct file *filp)
|
|
|
+{
|
|
|
+ filp->f_mode |= FMODE_AIO_NOWAIT;
|
|
|
+ return generic_file_open(inode, filp);
|
|
|
+}
|
|
|
+
|
|
|
const struct file_operations btrfs_file_operations = {
|
|
|
.llseek = btrfs_file_llseek,
|
|
|
.read_iter = generic_file_read_iter,
|
|
|
.splice_read = generic_file_splice_read,
|
|
|
.write_iter = btrfs_file_write_iter,
|
|
|
.mmap = btrfs_file_mmap,
|
|
|
- .open = generic_file_open,
|
|
|
+ .open = btrfs_file_open,
|
|
|
.release = btrfs_release_file,
|
|
|
.fsync = btrfs_sync_file,
|
|
|
.fallocate = btrfs_fallocate,
|