diff options
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r-- | fs/xfs/xfs_iomap.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f96c8ffce5f4..c08253e11545 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -934,11 +934,13 @@ error_on_bmapi_transaction: | |||
934 | return error; | 934 | return error; |
935 | } | 935 | } |
936 | 936 | ||
937 | static inline bool imap_needs_alloc(struct xfs_bmbt_irec *imap, int nimaps) | 937 | static inline bool imap_needs_alloc(struct inode *inode, |
938 | struct xfs_bmbt_irec *imap, int nimaps) | ||
938 | { | 939 | { |
939 | return !nimaps || | 940 | return !nimaps || |
940 | imap->br_startblock == HOLESTARTBLOCK || | 941 | imap->br_startblock == HOLESTARTBLOCK || |
941 | imap->br_startblock == DELAYSTARTBLOCK; | 942 | imap->br_startblock == DELAYSTARTBLOCK || |
943 | (IS_DAX(inode) && ISUNWRITTEN(imap)); | ||
942 | } | 944 | } |
943 | 945 | ||
944 | static int | 946 | static int |
@@ -954,16 +956,18 @@ xfs_file_iomap_begin( | |||
954 | struct xfs_bmbt_irec imap; | 956 | struct xfs_bmbt_irec imap; |
955 | xfs_fileoff_t offset_fsb, end_fsb; | 957 | xfs_fileoff_t offset_fsb, end_fsb; |
956 | int nimaps = 1, error = 0; | 958 | int nimaps = 1, error = 0; |
959 | unsigned lockmode; | ||
957 | 960 | ||
958 | if (XFS_FORCED_SHUTDOWN(mp)) | 961 | if (XFS_FORCED_SHUTDOWN(mp)) |
959 | return -EIO; | 962 | return -EIO; |
960 | 963 | ||
961 | if ((flags & IOMAP_WRITE) && !xfs_get_extsz_hint(ip)) { | 964 | if ((flags & IOMAP_WRITE) && |
965 | !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) { | ||
962 | return xfs_file_iomap_begin_delay(inode, offset, length, flags, | 966 | return xfs_file_iomap_begin_delay(inode, offset, length, flags, |
963 | iomap); | 967 | iomap); |
964 | } | 968 | } |
965 | 969 | ||
966 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 970 | lockmode = xfs_ilock_data_map_shared(ip); |
967 | 971 | ||
968 | ASSERT(offset <= mp->m_super->s_maxbytes); | 972 | ASSERT(offset <= mp->m_super->s_maxbytes); |
969 | if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes) | 973 | if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes) |
@@ -974,11 +978,11 @@ xfs_file_iomap_begin( | |||
974 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, | 978 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, |
975 | &nimaps, XFS_BMAPI_ENTIRE); | 979 | &nimaps, XFS_BMAPI_ENTIRE); |
976 | if (error) { | 980 | if (error) { |
977 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 981 | xfs_iunlock(ip, lockmode); |
978 | return error; | 982 | return error; |
979 | } | 983 | } |
980 | 984 | ||
981 | if ((flags & IOMAP_WRITE) && imap_needs_alloc(&imap, nimaps)) { | 985 | if ((flags & IOMAP_WRITE) && imap_needs_alloc(inode, &imap, nimaps)) { |
982 | /* | 986 | /* |
983 | * We cap the maximum length we map here to MAX_WRITEBACK_PAGES | 987 | * We cap the maximum length we map here to MAX_WRITEBACK_PAGES |
984 | * pages to keep the chunks of work done where somewhat symmetric | 988 | * pages to keep the chunks of work done where somewhat symmetric |
@@ -994,17 +998,19 @@ xfs_file_iomap_begin( | |||
994 | * xfs_iomap_write_direct() expects the shared lock. It | 998 | * xfs_iomap_write_direct() expects the shared lock. It |
995 | * is unlocked on return. | 999 | * is unlocked on return. |
996 | */ | 1000 | */ |
997 | xfs_ilock_demote(ip, XFS_ILOCK_EXCL); | 1001 | if (lockmode == XFS_ILOCK_EXCL) |
1002 | xfs_ilock_demote(ip, lockmode); | ||
998 | error = xfs_iomap_write_direct(ip, offset, length, &imap, | 1003 | error = xfs_iomap_write_direct(ip, offset, length, &imap, |
999 | nimaps); | 1004 | nimaps); |
1000 | if (error) | 1005 | if (error) |
1001 | return error; | 1006 | return error; |
1002 | 1007 | ||
1008 | iomap->flags = IOMAP_F_NEW; | ||
1003 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); | 1009 | trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); |
1004 | } else { | 1010 | } else { |
1005 | ASSERT(nimaps); | 1011 | ASSERT(nimaps); |
1006 | 1012 | ||
1007 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 1013 | xfs_iunlock(ip, lockmode); |
1008 | trace_xfs_iomap_found(ip, offset, length, 0, &imap); | 1014 | trace_xfs_iomap_found(ip, offset, length, 0, &imap); |
1009 | } | 1015 | } |
1010 | 1016 | ||