|
Lines 54-64
static int ext4_release_file(struct inode *inode, struct file *filp)
Link Here
|
| 54 |
return 0; |
54 |
return 0; |
| 55 |
} |
55 |
} |
| 56 |
|
56 |
|
|
|
57 |
static void ext4_aiodio_wait(struct inode *inode) |
| 58 |
{ |
| 59 |
wait_queue_head_t *wq = ext4_ioend_wq(inode); |
| 60 |
|
| 61 |
wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0)); |
| 62 |
} |
| 63 |
|
| 64 |
/* |
| 65 |
* This tests whether the IO in question is block-aligned or not. |
| 66 |
* Ext4 utilizes unwritten extents when hole-filling during direct IO, and they |
| 67 |
* are converted to written only after the IO is complete. Until they are |
| 68 |
* mapped, these blocks appear as holes, so dio_zero_block() will assume that |
| 69 |
* it needs to zero out portions of the start and/or end block. If 2 AIO |
| 70 |
* threads are at work on the same unwritten block, they must be synchronized |
| 71 |
* or one thread will zero the other's data, causing corruption. |
| 72 |
*/ |
| 73 |
static int |
| 74 |
ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, |
| 75 |
unsigned long nr_segs, loff_t pos) |
| 76 |
{ |
| 77 |
struct super_block *sb = inode->i_sb; |
| 78 |
int blockmask = sb->s_blocksize - 1; |
| 79 |
size_t count = iov_length(iov, nr_segs); |
| 80 |
loff_t final_size = pos + count; |
| 81 |
|
| 82 |
if (pos >= inode->i_size) |
| 83 |
return 0; |
| 84 |
|
| 85 |
if ((pos & blockmask) || (final_size & blockmask)) |
| 86 |
return 1; |
| 87 |
|
| 88 |
return 0; |
| 89 |
} |
| 90 |
|
| 57 |
static ssize_t |
91 |
static ssize_t |
| 58 |
ext4_file_write(struct kiocb *iocb, const struct iovec *iov, |
92 |
ext4_file_write(struct kiocb *iocb, const struct iovec *iov, |
| 59 |
unsigned long nr_segs, loff_t pos) |
93 |
unsigned long nr_segs, loff_t pos) |
| 60 |
{ |
94 |
{ |
| 61 |
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
95 |
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
|
|
96 |
int unaligned_aio = 0; |
| 97 |
int ret; |
| 62 |
|
98 |
|
| 63 |
/* |
99 |
/* |
| 64 |
* If we have encountered a bitmap-format file, the size limit |
100 |
* If we have encountered a bitmap-format file, the size limit |
|
Lines 76-84
ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
Link Here
|
| 76 |
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, |
112 |
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, |
| 77 |
sbi->s_bitmap_maxbytes - pos); |
113 |
sbi->s_bitmap_maxbytes - pos); |
| 78 |
} |
114 |
} |
|
|
115 |
} else if (unlikely((iocb->ki_filp->f_flags & O_DIRECT) && |
| 116 |
!is_sync_kiocb(iocb))) { |
| 117 |
unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs, pos); |
| 79 |
} |
118 |
} |
| 80 |
|
119 |
|
| 81 |
return generic_file_aio_write(iocb, iov, nr_segs, pos); |
120 |
/* Unaligned direct AIO must be serialized; see comment above */ |
|
|
121 |
if (unaligned_aio) { |
| 122 |
static unsigned long unaligned_warn_time; |
| 123 |
|
| 124 |
/* Warn about this once per day */ |
| 125 |
if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ)) |
| 126 |
ext4_msg(inode->i_sb, KERN_WARNING, |
| 127 |
"Unaligned AIO/DIO on inode %ld by %s; " |
| 128 |
"performance will be poor.", |
| 129 |
inode->i_ino, current->comm); |
| 130 |
mutex_lock(ext4_aio_mutex(inode)); |
| 131 |
ext4_aiodio_wait(inode); |
| 132 |
} |
| 133 |
|
| 134 |
ret = generic_file_aio_write(iocb, iov, nr_segs, pos); |
| 135 |
|
| 136 |
if (unaligned_aio) |
| 137 |
mutex_unlock(ext4_aio_mutex(inode)); |
| 138 |
|
| 139 |
return ret; |
| 82 |
} |
140 |
} |
| 83 |
|
141 |
|
| 84 |
static const struct vm_operations_struct ext4_file_vm_ops = { |
142 |
static const struct vm_operations_struct ext4_file_vm_ops = { |