diff options
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r-- | fs/xfs/xfs_iomap.c | 123 |
1 files changed, 39 insertions, 84 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 0b65039951a0..ef14943829da 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -55,71 +55,33 @@ | |||
55 | #define XFS_STRAT_WRITE_IMAPS 2 | 55 | #define XFS_STRAT_WRITE_IMAPS 2 |
56 | #define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP | 56 | #define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP |
57 | 57 | ||
58 | STATIC int | 58 | STATIC int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, |
59 | xfs_imap_to_bmap( | 59 | int, struct xfs_bmbt_irec *, int *); |
60 | xfs_inode_t *ip, | 60 | STATIC int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int, |
61 | xfs_off_t offset, | 61 | struct xfs_bmbt_irec *, int *); |
62 | xfs_bmbt_irec_t *imap, | 62 | STATIC int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, |
63 | xfs_iomap_t *iomapp, | 63 | struct xfs_bmbt_irec *, int *); |
64 | int imaps, /* Number of imap entries */ | ||
65 | int iomaps, /* Number of iomap entries */ | ||
66 | int flags) | ||
67 | { | ||
68 | xfs_mount_t *mp = ip->i_mount; | ||
69 | int pbm; | ||
70 | xfs_fsblock_t start_block; | ||
71 | |||
72 | |||
73 | for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { | ||
74 | iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); | ||
75 | iomapp->iomap_delta = offset - iomapp->iomap_offset; | ||
76 | iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); | ||
77 | iomapp->iomap_flags = flags; | ||
78 | |||
79 | if (XFS_IS_REALTIME_INODE(ip)) { | ||
80 | iomapp->iomap_flags |= IOMAP_REALTIME; | ||
81 | iomapp->iomap_target = mp->m_rtdev_targp; | ||
82 | } else { | ||
83 | iomapp->iomap_target = mp->m_ddev_targp; | ||
84 | } | ||
85 | start_block = imap->br_startblock; | ||
86 | if (start_block == HOLESTARTBLOCK) { | ||
87 | iomapp->iomap_bn = IOMAP_DADDR_NULL; | ||
88 | iomapp->iomap_flags |= IOMAP_HOLE; | ||
89 | } else if (start_block == DELAYSTARTBLOCK) { | ||
90 | iomapp->iomap_bn = IOMAP_DADDR_NULL; | ||
91 | iomapp->iomap_flags |= IOMAP_DELAY; | ||
92 | } else { | ||
93 | iomapp->iomap_bn = xfs_fsb_to_db(ip, start_block); | ||
94 | if (ISUNWRITTEN(imap)) | ||
95 | iomapp->iomap_flags |= IOMAP_UNWRITTEN; | ||
96 | } | ||
97 | |||
98 | offset += iomapp->iomap_bsize - iomapp->iomap_delta; | ||
99 | } | ||
100 | return pbm; /* Return the number filled */ | ||
101 | } | ||
102 | 64 | ||
103 | int | 65 | int |
104 | xfs_iomap( | 66 | xfs_iomap( |
105 | xfs_inode_t *ip, | 67 | struct xfs_inode *ip, |
106 | xfs_off_t offset, | 68 | xfs_off_t offset, |
107 | ssize_t count, | 69 | ssize_t count, |
108 | int flags, | 70 | int flags, |
109 | xfs_iomap_t *iomapp, | 71 | struct xfs_bmbt_irec *imap, |
110 | int *niomaps) | 72 | int *nimaps, |
73 | int *new) | ||
111 | { | 74 | { |
112 | xfs_mount_t *mp = ip->i_mount; | 75 | struct xfs_mount *mp = ip->i_mount; |
113 | xfs_fileoff_t offset_fsb, end_fsb; | 76 | xfs_fileoff_t offset_fsb, end_fsb; |
114 | int error = 0; | 77 | int error = 0; |
115 | int lockmode = 0; | 78 | int lockmode = 0; |
116 | xfs_bmbt_irec_t imap; | 79 | int bmapi_flags = 0; |
117 | int nimaps = 1; | ||
118 | int bmapi_flags = 0; | ||
119 | int iomap_flags = 0; | ||
120 | 80 | ||
121 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | 81 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); |
122 | 82 | ||
83 | *new = 0; | ||
84 | |||
123 | if (XFS_FORCED_SHUTDOWN(mp)) | 85 | if (XFS_FORCED_SHUTDOWN(mp)) |
124 | return XFS_ERROR(EIO); | 86 | return XFS_ERROR(EIO); |
125 | 87 | ||
@@ -160,8 +122,8 @@ xfs_iomap( | |||
160 | 122 | ||
161 | error = xfs_bmapi(NULL, ip, offset_fsb, | 123 | error = xfs_bmapi(NULL, ip, offset_fsb, |
162 | (xfs_filblks_t)(end_fsb - offset_fsb), | 124 | (xfs_filblks_t)(end_fsb - offset_fsb), |
163 | bmapi_flags, NULL, 0, &imap, | 125 | bmapi_flags, NULL, 0, imap, |
164 | &nimaps, NULL, NULL); | 126 | nimaps, NULL, NULL); |
165 | 127 | ||
166 | if (error) | 128 | if (error) |
167 | goto out; | 129 | goto out; |
@@ -169,46 +131,41 @@ xfs_iomap( | |||
169 | switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) { | 131 | switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) { |
170 | case BMAPI_WRITE: | 132 | case BMAPI_WRITE: |
171 | /* If we found an extent, return it */ | 133 | /* If we found an extent, return it */ |
172 | if (nimaps && | 134 | if (*nimaps && |
173 | (imap.br_startblock != HOLESTARTBLOCK) && | 135 | (imap->br_startblock != HOLESTARTBLOCK) && |
174 | (imap.br_startblock != DELAYSTARTBLOCK)) { | 136 | (imap->br_startblock != DELAYSTARTBLOCK)) { |
175 | trace_xfs_iomap_found(ip, offset, count, flags, &imap); | 137 | trace_xfs_iomap_found(ip, offset, count, flags, imap); |
176 | break; | 138 | break; |
177 | } | 139 | } |
178 | 140 | ||
179 | if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { | 141 | if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { |
180 | error = xfs_iomap_write_direct(ip, offset, count, flags, | 142 | error = xfs_iomap_write_direct(ip, offset, count, flags, |
181 | &imap, &nimaps, nimaps); | 143 | imap, nimaps); |
182 | } else { | 144 | } else { |
183 | error = xfs_iomap_write_delay(ip, offset, count, flags, | 145 | error = xfs_iomap_write_delay(ip, offset, count, flags, |
184 | &imap, &nimaps); | 146 | imap, nimaps); |
185 | } | 147 | } |
186 | if (!error) { | 148 | if (!error) { |
187 | trace_xfs_iomap_alloc(ip, offset, count, flags, &imap); | 149 | trace_xfs_iomap_alloc(ip, offset, count, flags, imap); |
188 | } | 150 | } |
189 | iomap_flags = IOMAP_NEW; | 151 | *new = 1; |
190 | break; | 152 | break; |
191 | case BMAPI_ALLOCATE: | 153 | case BMAPI_ALLOCATE: |
192 | /* If we found an extent, return it */ | 154 | /* If we found an extent, return it */ |
193 | xfs_iunlock(ip, lockmode); | 155 | xfs_iunlock(ip, lockmode); |
194 | lockmode = 0; | 156 | lockmode = 0; |
195 | 157 | ||
196 | if (nimaps && !isnullstartblock(imap.br_startblock)) { | 158 | if (*nimaps && !isnullstartblock(imap->br_startblock)) { |
197 | trace_xfs_iomap_found(ip, offset, count, flags, &imap); | 159 | trace_xfs_iomap_found(ip, offset, count, flags, imap); |
198 | break; | 160 | break; |
199 | } | 161 | } |
200 | 162 | ||
201 | error = xfs_iomap_write_allocate(ip, offset, count, | 163 | error = xfs_iomap_write_allocate(ip, offset, count, |
202 | &imap, &nimaps); | 164 | imap, nimaps); |
203 | break; | 165 | break; |
204 | } | 166 | } |
205 | 167 | ||
206 | if (nimaps) { | 168 | ASSERT(*nimaps <= 1); |
207 | *niomaps = xfs_imap_to_bmap(ip, offset, &imap, | ||
208 | iomapp, nimaps, *niomaps, iomap_flags); | ||
209 | } else if (niomaps) { | ||
210 | *niomaps = 0; | ||
211 | } | ||
212 | 169 | ||
213 | out: | 170 | out: |
214 | if (lockmode) | 171 | if (lockmode) |
@@ -216,7 +173,6 @@ out: | |||
216 | return XFS_ERROR(error); | 173 | return XFS_ERROR(error); |
217 | } | 174 | } |
218 | 175 | ||
219 | |||
220 | STATIC int | 176 | STATIC int |
221 | xfs_iomap_eof_align_last_fsb( | 177 | xfs_iomap_eof_align_last_fsb( |
222 | xfs_mount_t *mp, | 178 | xfs_mount_t *mp, |
@@ -285,15 +241,14 @@ xfs_cmn_err_fsblock_zero( | |||
285 | return EFSCORRUPTED; | 241 | return EFSCORRUPTED; |
286 | } | 242 | } |
287 | 243 | ||
288 | int | 244 | STATIC int |
289 | xfs_iomap_write_direct( | 245 | xfs_iomap_write_direct( |
290 | xfs_inode_t *ip, | 246 | xfs_inode_t *ip, |
291 | xfs_off_t offset, | 247 | xfs_off_t offset, |
292 | size_t count, | 248 | size_t count, |
293 | int flags, | 249 | int flags, |
294 | xfs_bmbt_irec_t *ret_imap, | 250 | xfs_bmbt_irec_t *ret_imap, |
295 | int *nmaps, | 251 | int *nmaps) |
296 | int found) | ||
297 | { | 252 | { |
298 | xfs_mount_t *mp = ip->i_mount; | 253 | xfs_mount_t *mp = ip->i_mount; |
299 | xfs_fileoff_t offset_fsb; | 254 | xfs_fileoff_t offset_fsb; |
@@ -330,7 +285,7 @@ xfs_iomap_write_direct( | |||
330 | if (error) | 285 | if (error) |
331 | goto error_out; | 286 | goto error_out; |
332 | } else { | 287 | } else { |
333 | if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) | 288 | if (*nmaps && (ret_imap->br_startblock == HOLESTARTBLOCK)) |
334 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) | 289 | last_fsb = MIN(last_fsb, (xfs_fileoff_t) |
335 | ret_imap->br_blockcount + | 290 | ret_imap->br_blockcount + |
336 | ret_imap->br_startoff); | 291 | ret_imap->br_startoff); |
@@ -485,7 +440,7 @@ xfs_iomap_eof_want_preallocate( | |||
485 | return 0; | 440 | return 0; |
486 | } | 441 | } |
487 | 442 | ||
488 | int | 443 | STATIC int |
489 | xfs_iomap_write_delay( | 444 | xfs_iomap_write_delay( |
490 | xfs_inode_t *ip, | 445 | xfs_inode_t *ip, |
491 | xfs_off_t offset, | 446 | xfs_off_t offset, |
@@ -588,7 +543,7 @@ retry: | |||
588 | * We no longer bother to look at the incoming map - all we have to | 543 | * We no longer bother to look at the incoming map - all we have to |
589 | * guarantee is that whatever we allocate fills the required range. | 544 | * guarantee is that whatever we allocate fills the required range. |
590 | */ | 545 | */ |
591 | int | 546 | STATIC int |
592 | xfs_iomap_write_allocate( | 547 | xfs_iomap_write_allocate( |
593 | xfs_inode_t *ip, | 548 | xfs_inode_t *ip, |
594 | xfs_off_t offset, | 549 | xfs_off_t offset, |