aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c22
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
937static inline bool imap_needs_alloc(struct xfs_bmbt_irec *imap, int nimaps) 937static 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
944static int 946static 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