diff options
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r-- | fs/xfs/xfs_file.c | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 1f66779d7a46..076b1708d134 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "xfs_trace.h" | 38 | #include "xfs_trace.h" |
39 | #include "xfs_log.h" | 39 | #include "xfs_log.h" |
40 | #include "xfs_dinode.h" | 40 | #include "xfs_dinode.h" |
41 | #include "xfs_icache.h" | ||
41 | 42 | ||
42 | #include <linux/aio.h> | 43 | #include <linux/aio.h> |
43 | #include <linux/dcache.h> | 44 | #include <linux/dcache.h> |
@@ -155,7 +156,7 @@ xfs_dir_fsync( | |||
155 | 156 | ||
156 | if (!lsn) | 157 | if (!lsn) |
157 | return 0; | 158 | return 0; |
158 | return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); | 159 | return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); |
159 | } | 160 | } |
160 | 161 | ||
161 | STATIC int | 162 | STATIC int |
@@ -179,7 +180,7 @@ xfs_file_fsync( | |||
179 | return error; | 180 | return error; |
180 | 181 | ||
181 | if (XFS_FORCED_SHUTDOWN(mp)) | 182 | if (XFS_FORCED_SHUTDOWN(mp)) |
182 | return -XFS_ERROR(EIO); | 183 | return -EIO; |
183 | 184 | ||
184 | xfs_iflags_clear(ip, XFS_ITRUNCATED); | 185 | xfs_iflags_clear(ip, XFS_ITRUNCATED); |
185 | 186 | ||
@@ -225,7 +226,7 @@ xfs_file_fsync( | |||
225 | !log_flushed) | 226 | !log_flushed) |
226 | xfs_blkdev_issue_flush(mp->m_ddev_targp); | 227 | xfs_blkdev_issue_flush(mp->m_ddev_targp); |
227 | 228 | ||
228 | return -error; | 229 | return error; |
229 | } | 230 | } |
230 | 231 | ||
231 | STATIC ssize_t | 232 | STATIC ssize_t |
@@ -246,11 +247,11 @@ xfs_file_read_iter( | |||
246 | XFS_STATS_INC(xs_read_calls); | 247 | XFS_STATS_INC(xs_read_calls); |
247 | 248 | ||
248 | if (unlikely(file->f_flags & O_DIRECT)) | 249 | if (unlikely(file->f_flags & O_DIRECT)) |
249 | ioflags |= IO_ISDIRECT; | 250 | ioflags |= XFS_IO_ISDIRECT; |
250 | if (file->f_mode & FMODE_NOCMTIME) | 251 | if (file->f_mode & FMODE_NOCMTIME) |
251 | ioflags |= IO_INVIS; | 252 | ioflags |= XFS_IO_INVIS; |
252 | 253 | ||
253 | if (unlikely(ioflags & IO_ISDIRECT)) { | 254 | if (unlikely(ioflags & XFS_IO_ISDIRECT)) { |
254 | xfs_buftarg_t *target = | 255 | xfs_buftarg_t *target = |
255 | XFS_IS_REALTIME_INODE(ip) ? | 256 | XFS_IS_REALTIME_INODE(ip) ? |
256 | mp->m_rtdev_targp : mp->m_ddev_targp; | 257 | mp->m_rtdev_targp : mp->m_ddev_targp; |
@@ -258,7 +259,7 @@ xfs_file_read_iter( | |||
258 | if ((pos | size) & target->bt_logical_sectormask) { | 259 | if ((pos | size) & target->bt_logical_sectormask) { |
259 | if (pos == i_size_read(inode)) | 260 | if (pos == i_size_read(inode)) |
260 | return 0; | 261 | return 0; |
261 | return -XFS_ERROR(EINVAL); | 262 | return -EINVAL; |
262 | } | 263 | } |
263 | } | 264 | } |
264 | 265 | ||
@@ -283,7 +284,7 @@ xfs_file_read_iter( | |||
283 | * proceeed concurrently without serialisation. | 284 | * proceeed concurrently without serialisation. |
284 | */ | 285 | */ |
285 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); | 286 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); |
286 | if ((ioflags & IO_ISDIRECT) && inode->i_mapping->nrpages) { | 287 | if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) { |
287 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); | 288 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); |
288 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); | 289 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); |
289 | 290 | ||
@@ -325,7 +326,7 @@ xfs_file_splice_read( | |||
325 | XFS_STATS_INC(xs_read_calls); | 326 | XFS_STATS_INC(xs_read_calls); |
326 | 327 | ||
327 | if (infilp->f_mode & FMODE_NOCMTIME) | 328 | if (infilp->f_mode & FMODE_NOCMTIME) |
328 | ioflags |= IO_INVIS; | 329 | ioflags |= XFS_IO_INVIS; |
329 | 330 | ||
330 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 331 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
331 | return -EIO; | 332 | return -EIO; |
@@ -524,7 +525,7 @@ restart: | |||
524 | xfs_rw_ilock(ip, *iolock); | 525 | xfs_rw_ilock(ip, *iolock); |
525 | goto restart; | 526 | goto restart; |
526 | } | 527 | } |
527 | error = -xfs_zero_eof(ip, *pos, i_size_read(inode)); | 528 | error = xfs_zero_eof(ip, *pos, i_size_read(inode)); |
528 | if (error) | 529 | if (error) |
529 | return error; | 530 | return error; |
530 | } | 531 | } |
@@ -594,7 +595,7 @@ xfs_file_dio_aio_write( | |||
594 | 595 | ||
595 | /* DIO must be aligned to device logical sector size */ | 596 | /* DIO must be aligned to device logical sector size */ |
596 | if ((pos | count) & target->bt_logical_sectormask) | 597 | if ((pos | count) & target->bt_logical_sectormask) |
597 | return -XFS_ERROR(EINVAL); | 598 | return -EINVAL; |
598 | 599 | ||
599 | /* "unaligned" here means not aligned to a filesystem block */ | 600 | /* "unaligned" here means not aligned to a filesystem block */ |
600 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) | 601 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) |
@@ -689,14 +690,28 @@ write_retry: | |||
689 | ret = generic_perform_write(file, from, pos); | 690 | ret = generic_perform_write(file, from, pos); |
690 | if (likely(ret >= 0)) | 691 | if (likely(ret >= 0)) |
691 | iocb->ki_pos = pos + ret; | 692 | iocb->ki_pos = pos + ret; |
693 | |||
692 | /* | 694 | /* |
693 | * If we just got an ENOSPC, try to write back all dirty inodes to | 695 | * If we hit a space limit, try to free up some lingering preallocated |
694 | * convert delalloc space to free up some of the excess reserved | 696 | * space before returning an error. In the case of ENOSPC, first try to |
695 | * metadata space. | 697 | * write back all dirty inodes to free up some of the excess reserved |
698 | * metadata space. This reduces the chances that the eofblocks scan | ||
699 | * waits on dirty mappings. Since xfs_flush_inodes() is serialized, this | ||
700 | * also behaves as a filter to prevent too many eofblocks scans from | ||
701 | * running at the same time. | ||
696 | */ | 702 | */ |
697 | if (ret == -ENOSPC && !enospc) { | 703 | if (ret == -EDQUOT && !enospc) { |
704 | enospc = xfs_inode_free_quota_eofblocks(ip); | ||
705 | if (enospc) | ||
706 | goto write_retry; | ||
707 | } else if (ret == -ENOSPC && !enospc) { | ||
708 | struct xfs_eofblocks eofb = {0}; | ||
709 | |||
698 | enospc = 1; | 710 | enospc = 1; |
699 | xfs_flush_inodes(ip->i_mount); | 711 | xfs_flush_inodes(ip->i_mount); |
712 | eofb.eof_scan_owner = ip->i_ino; /* for locking */ | ||
713 | eofb.eof_flags = XFS_EOF_FLAGS_SYNC; | ||
714 | xfs_icache_free_eofblocks(ip->i_mount, &eofb); | ||
700 | goto write_retry; | 715 | goto write_retry; |
701 | } | 716 | } |
702 | 717 | ||
@@ -772,7 +787,7 @@ xfs_file_fallocate( | |||
772 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; | 787 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; |
773 | 788 | ||
774 | if (offset & blksize_mask || len & blksize_mask) { | 789 | if (offset & blksize_mask || len & blksize_mask) { |
775 | error = EINVAL; | 790 | error = -EINVAL; |
776 | goto out_unlock; | 791 | goto out_unlock; |
777 | } | 792 | } |
778 | 793 | ||
@@ -781,7 +796,7 @@ xfs_file_fallocate( | |||
781 | * in which case it is effectively a truncate operation | 796 | * in which case it is effectively a truncate operation |
782 | */ | 797 | */ |
783 | if (offset + len >= i_size_read(inode)) { | 798 | if (offset + len >= i_size_read(inode)) { |
784 | error = EINVAL; | 799 | error = -EINVAL; |
785 | goto out_unlock; | 800 | goto out_unlock; |
786 | } | 801 | } |
787 | 802 | ||
@@ -794,7 +809,7 @@ xfs_file_fallocate( | |||
794 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | 809 | if (!(mode & FALLOC_FL_KEEP_SIZE) && |
795 | offset + len > i_size_read(inode)) { | 810 | offset + len > i_size_read(inode)) { |
796 | new_size = offset + len; | 811 | new_size = offset + len; |
797 | error = -inode_newsize_ok(inode, new_size); | 812 | error = inode_newsize_ok(inode, new_size); |
798 | if (error) | 813 | if (error) |
799 | goto out_unlock; | 814 | goto out_unlock; |
800 | } | 815 | } |
@@ -844,7 +859,7 @@ xfs_file_fallocate( | |||
844 | 859 | ||
845 | out_unlock: | 860 | out_unlock: |
846 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 861 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
847 | return -error; | 862 | return error; |
848 | } | 863 | } |
849 | 864 | ||
850 | 865 | ||
@@ -889,7 +904,7 @@ xfs_file_release( | |||
889 | struct inode *inode, | 904 | struct inode *inode, |
890 | struct file *filp) | 905 | struct file *filp) |
891 | { | 906 | { |
892 | return -xfs_release(XFS_I(inode)); | 907 | return xfs_release(XFS_I(inode)); |
893 | } | 908 | } |
894 | 909 | ||
895 | STATIC int | 910 | STATIC int |
@@ -918,7 +933,7 @@ xfs_file_readdir( | |||
918 | 933 | ||
919 | error = xfs_readdir(ip, ctx, bufsize); | 934 | error = xfs_readdir(ip, ctx, bufsize); |
920 | if (error) | 935 | if (error) |
921 | return -error; | 936 | return error; |
922 | return 0; | 937 | return 0; |
923 | } | 938 | } |
924 | 939 | ||
@@ -1184,7 +1199,7 @@ xfs_seek_data( | |||
1184 | 1199 | ||
1185 | isize = i_size_read(inode); | 1200 | isize = i_size_read(inode); |
1186 | if (start >= isize) { | 1201 | if (start >= isize) { |
1187 | error = ENXIO; | 1202 | error = -ENXIO; |
1188 | goto out_unlock; | 1203 | goto out_unlock; |
1189 | } | 1204 | } |
1190 | 1205 | ||
@@ -1206,7 +1221,7 @@ xfs_seek_data( | |||
1206 | 1221 | ||
1207 | /* No extents at given offset, must be beyond EOF */ | 1222 | /* No extents at given offset, must be beyond EOF */ |
1208 | if (nmap == 0) { | 1223 | if (nmap == 0) { |
1209 | error = ENXIO; | 1224 | error = -ENXIO; |
1210 | goto out_unlock; | 1225 | goto out_unlock; |
1211 | } | 1226 | } |
1212 | 1227 | ||
@@ -1237,7 +1252,7 @@ xfs_seek_data( | |||
1237 | * we are reading after EOF if nothing in map[1]. | 1252 | * we are reading after EOF if nothing in map[1]. |
1238 | */ | 1253 | */ |
1239 | if (nmap == 1) { | 1254 | if (nmap == 1) { |
1240 | error = ENXIO; | 1255 | error = -ENXIO; |
1241 | goto out_unlock; | 1256 | goto out_unlock; |
1242 | } | 1257 | } |
1243 | 1258 | ||
@@ -1250,7 +1265,7 @@ xfs_seek_data( | |||
1250 | fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount; | 1265 | fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount; |
1251 | start = XFS_FSB_TO_B(mp, fsbno); | 1266 | start = XFS_FSB_TO_B(mp, fsbno); |
1252 | if (start >= isize) { | 1267 | if (start >= isize) { |
1253 | error = ENXIO; | 1268 | error = -ENXIO; |
1254 | goto out_unlock; | 1269 | goto out_unlock; |
1255 | } | 1270 | } |
1256 | } | 1271 | } |
@@ -1262,7 +1277,7 @@ out_unlock: | |||
1262 | xfs_iunlock(ip, lock); | 1277 | xfs_iunlock(ip, lock); |
1263 | 1278 | ||
1264 | if (error) | 1279 | if (error) |
1265 | return -error; | 1280 | return error; |
1266 | return offset; | 1281 | return offset; |
1267 | } | 1282 | } |
1268 | 1283 | ||
@@ -1282,13 +1297,13 @@ xfs_seek_hole( | |||
1282 | int error; | 1297 | int error; |
1283 | 1298 | ||
1284 | if (XFS_FORCED_SHUTDOWN(mp)) | 1299 | if (XFS_FORCED_SHUTDOWN(mp)) |
1285 | return -XFS_ERROR(EIO); | 1300 | return -EIO; |
1286 | 1301 | ||
1287 | lock = xfs_ilock_data_map_shared(ip); | 1302 | lock = xfs_ilock_data_map_shared(ip); |
1288 | 1303 | ||
1289 | isize = i_size_read(inode); | 1304 | isize = i_size_read(inode); |
1290 | if (start >= isize) { | 1305 | if (start >= isize) { |
1291 | error = ENXIO; | 1306 | error = -ENXIO; |
1292 | goto out_unlock; | 1307 | goto out_unlock; |
1293 | } | 1308 | } |
1294 | 1309 | ||
@@ -1307,7 +1322,7 @@ xfs_seek_hole( | |||
1307 | 1322 | ||
1308 | /* No extents at given offset, must be beyond EOF */ | 1323 | /* No extents at given offset, must be beyond EOF */ |
1309 | if (nmap == 0) { | 1324 | if (nmap == 0) { |
1310 | error = ENXIO; | 1325 | error = -ENXIO; |
1311 | goto out_unlock; | 1326 | goto out_unlock; |
1312 | } | 1327 | } |
1313 | 1328 | ||
@@ -1370,7 +1385,7 @@ out_unlock: | |||
1370 | xfs_iunlock(ip, lock); | 1385 | xfs_iunlock(ip, lock); |
1371 | 1386 | ||
1372 | if (error) | 1387 | if (error) |
1373 | return -error; | 1388 | return error; |
1374 | return offset; | 1389 | return offset; |
1375 | } | 1390 | } |
1376 | 1391 | ||