diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 22:12:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 22:12:12 -0500 |
commit | 0b61a2ba5dfd1620731e717d686e6ade657fd975 (patch) | |
tree | dea84efd43934a7d6139048f87c4ba86d68d4b6d /fs | |
parent | a13ff0bb3feda8b1fcffc69951320277ed7c4101 (diff) | |
parent | de2eeea609b55e8c3994133a565b39edeaaaaf69 (diff) |
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (62 commits)
[XFS] add __init/__exit mark to specific init/cleanup functions
[XFS] Fix oops in xfs_file_readdir()
[XFS] kill xfs_root
[XFS] keep i_nlink updated and use proper accessors
[XFS] stop updating inode->i_blocks
[XFS] Make xfs_ail_check check less by default
[XFS] Move AIL pushing into it's own thread
[XFS] use generic_permission
[XFS] stop re-checking permissions in xfs_swapext
[XFS] clean up xfs_swapext
[XFS] remove permission check from xfs_change_file_space
[XFS] prevent panic during log recovery due to bogus op_hdr length
[XFS] Cleanup various fid related bits:
[XFS] Fix xfs_lowbit64
[XFS] Remove CFORK macros and use code directly in IFORK and DFORK macros.
[XFS] kill superflous buffer locking (2nd attempt)
[XFS] Use kernel-supplied "roundup_pow_of_two" for simplicity
[XFS] Remove the BPCSHIFT and NB* based macros from XFS.
[XFS] Remove bogus assert
[XFS] optimize XFS_IS_REALTIME_INODE w/o realtime config
...
Diffstat (limited to 'fs')
85 files changed, 2303 insertions, 3184 deletions
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index d1491aa7a0e2..97316451fc6d 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -70,7 +70,6 @@ xfs-y += xfs_alloc.o \ | |||
70 | xfs_iget.o \ | 70 | xfs_iget.o \ |
71 | xfs_inode.o \ | 71 | xfs_inode.o \ |
72 | xfs_inode_item.o \ | 72 | xfs_inode_item.o \ |
73 | xfs_iocore.o \ | ||
74 | xfs_iomap.o \ | 73 | xfs_iomap.o \ |
75 | xfs_itable.o \ | 74 | xfs_itable.o \ |
76 | xfs_dfrag.o \ | 75 | xfs_dfrag.o \ |
diff --git a/fs/xfs/linux-2.6/spin.h b/fs/xfs/linux-2.6/spin.h deleted file mode 100644 index 50a6191178f4..000000000000 --- a/fs/xfs/linux-2.6/spin.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_SUPPORT_SPIN_H__ | ||
19 | #define __XFS_SUPPORT_SPIN_H__ | ||
20 | |||
21 | #include <linux/sched.h> /* preempt needs this */ | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | /* | ||
25 | * Map lock_t from IRIX to Linux spinlocks. | ||
26 | * | ||
27 | * We do not make use of lock_t from interrupt context, so we do not | ||
28 | * have to worry about disabling interrupts at all (unlike IRIX). | ||
29 | */ | ||
30 | |||
31 | typedef spinlock_t lock_t; | ||
32 | |||
33 | #define SPLDECL(s) unsigned long s | ||
34 | #ifndef DEFINE_SPINLOCK | ||
35 | #define DEFINE_SPINLOCK(s) spinlock_t s = SPIN_LOCK_UNLOCKED | ||
36 | #endif | ||
37 | |||
38 | #define spinlock_init(lock, name) spin_lock_init(lock) | ||
39 | #define spinlock_destroy(lock) | ||
40 | #define mutex_spinlock(lock) ({ spin_lock(lock); 0; }) | ||
41 | #define mutex_spinunlock(lock, s) do { spin_unlock(lock); (void)s; } while (0) | ||
42 | #define nested_spinlock(lock) spin_lock(lock) | ||
43 | #define nested_spinunlock(lock) spin_unlock(lock) | ||
44 | |||
45 | #endif /* __XFS_SUPPORT_SPIN_H__ */ | ||
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 2e34b104107c..e0519529c26c 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -107,6 +107,18 @@ xfs_page_trace( | |||
107 | #define xfs_page_trace(tag, inode, page, pgoff) | 107 | #define xfs_page_trace(tag, inode, page, pgoff) |
108 | #endif | 108 | #endif |
109 | 109 | ||
110 | STATIC struct block_device * | ||
111 | xfs_find_bdev_for_inode( | ||
112 | struct xfs_inode *ip) | ||
113 | { | ||
114 | struct xfs_mount *mp = ip->i_mount; | ||
115 | |||
116 | if (XFS_IS_REALTIME_INODE(ip)) | ||
117 | return mp->m_rtdev_targp->bt_bdev; | ||
118 | else | ||
119 | return mp->m_ddev_targp->bt_bdev; | ||
120 | } | ||
121 | |||
110 | /* | 122 | /* |
111 | * Schedule IO completion handling on a xfsdatad if this was | 123 | * Schedule IO completion handling on a xfsdatad if this was |
112 | * the final hold on this ioend. If we are asked to wait, | 124 | * the final hold on this ioend. If we are asked to wait, |
@@ -151,7 +163,7 @@ xfs_destroy_ioend( | |||
151 | /* | 163 | /* |
152 | * Update on-disk file size now that data has been written to disk. | 164 | * Update on-disk file size now that data has been written to disk. |
153 | * The current in-memory file size is i_size. If a write is beyond | 165 | * The current in-memory file size is i_size. If a write is beyond |
154 | * eof io_new_size will be the intended file size until i_size is | 166 | * eof i_new_size will be the intended file size until i_size is |
155 | * updated. If this write does not extend all the way to the valid | 167 | * updated. If this write does not extend all the way to the valid |
156 | * file size then restrict this update to the end of the write. | 168 | * file size then restrict this update to the end of the write. |
157 | */ | 169 | */ |
@@ -173,7 +185,7 @@ xfs_setfilesize( | |||
173 | 185 | ||
174 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 186 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
175 | 187 | ||
176 | isize = MAX(ip->i_size, ip->i_iocore.io_new_size); | 188 | isize = MAX(ip->i_size, ip->i_new_size); |
177 | isize = MIN(isize, bsize); | 189 | isize = MIN(isize, bsize); |
178 | 190 | ||
179 | if (ip->i_d.di_size < isize) { | 191 | if (ip->i_d.di_size < isize) { |
@@ -226,12 +238,13 @@ xfs_end_bio_unwritten( | |||
226 | { | 238 | { |
227 | xfs_ioend_t *ioend = | 239 | xfs_ioend_t *ioend = |
228 | container_of(work, xfs_ioend_t, io_work); | 240 | container_of(work, xfs_ioend_t, io_work); |
241 | struct xfs_inode *ip = XFS_I(ioend->io_inode); | ||
229 | xfs_off_t offset = ioend->io_offset; | 242 | xfs_off_t offset = ioend->io_offset; |
230 | size_t size = ioend->io_size; | 243 | size_t size = ioend->io_size; |
231 | 244 | ||
232 | if (likely(!ioend->io_error)) { | 245 | if (likely(!ioend->io_error)) { |
233 | xfs_bmap(XFS_I(ioend->io_inode), offset, size, | 246 | if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) |
234 | BMAPI_UNWRITTEN, NULL, NULL); | 247 | xfs_iomap_write_unwritten(ip, offset, size); |
235 | xfs_setfilesize(ioend); | 248 | xfs_setfilesize(ioend); |
236 | } | 249 | } |
237 | xfs_destroy_ioend(ioend); | 250 | xfs_destroy_ioend(ioend); |
@@ -304,7 +317,7 @@ xfs_map_blocks( | |||
304 | xfs_inode_t *ip = XFS_I(inode); | 317 | xfs_inode_t *ip = XFS_I(inode); |
305 | int error, nmaps = 1; | 318 | int error, nmaps = 1; |
306 | 319 | ||
307 | error = xfs_bmap(ip, offset, count, | 320 | error = xfs_iomap(ip, offset, count, |
308 | flags, mapp, &nmaps); | 321 | flags, mapp, &nmaps); |
309 | if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) | 322 | if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) |
310 | xfs_iflags_set(ip, XFS_IMODIFIED); | 323 | xfs_iflags_set(ip, XFS_IMODIFIED); |
@@ -1323,7 +1336,7 @@ __xfs_get_blocks( | |||
1323 | offset = (xfs_off_t)iblock << inode->i_blkbits; | 1336 | offset = (xfs_off_t)iblock << inode->i_blkbits; |
1324 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); | 1337 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); |
1325 | size = bh_result->b_size; | 1338 | size = bh_result->b_size; |
1326 | error = xfs_bmap(XFS_I(inode), offset, size, | 1339 | error = xfs_iomap(XFS_I(inode), offset, size, |
1327 | create ? flags : BMAPI_READ, &iomap, &niomap); | 1340 | create ? flags : BMAPI_READ, &iomap, &niomap); |
1328 | if (error) | 1341 | if (error) |
1329 | return -error; | 1342 | return -error; |
@@ -1471,28 +1484,21 @@ xfs_vm_direct_IO( | |||
1471 | { | 1484 | { |
1472 | struct file *file = iocb->ki_filp; | 1485 | struct file *file = iocb->ki_filp; |
1473 | struct inode *inode = file->f_mapping->host; | 1486 | struct inode *inode = file->f_mapping->host; |
1474 | xfs_iomap_t iomap; | 1487 | struct block_device *bdev; |
1475 | int maps = 1; | ||
1476 | int error; | ||
1477 | ssize_t ret; | 1488 | ssize_t ret; |
1478 | 1489 | ||
1479 | error = xfs_bmap(XFS_I(inode), offset, 0, | 1490 | bdev = xfs_find_bdev_for_inode(XFS_I(inode)); |
1480 | BMAPI_DEVICE, &iomap, &maps); | ||
1481 | if (error) | ||
1482 | return -error; | ||
1483 | 1491 | ||
1484 | if (rw == WRITE) { | 1492 | if (rw == WRITE) { |
1485 | iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); | 1493 | iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); |
1486 | ret = blockdev_direct_IO_own_locking(rw, iocb, inode, | 1494 | ret = blockdev_direct_IO_own_locking(rw, iocb, inode, |
1487 | iomap.iomap_target->bt_bdev, | 1495 | bdev, iov, offset, nr_segs, |
1488 | iov, offset, nr_segs, | ||
1489 | xfs_get_blocks_direct, | 1496 | xfs_get_blocks_direct, |
1490 | xfs_end_io_direct); | 1497 | xfs_end_io_direct); |
1491 | } else { | 1498 | } else { |
1492 | iocb->private = xfs_alloc_ioend(inode, IOMAP_READ); | 1499 | iocb->private = xfs_alloc_ioend(inode, IOMAP_READ); |
1493 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, | 1500 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, |
1494 | iomap.iomap_target->bt_bdev, | 1501 | bdev, iov, offset, nr_segs, |
1495 | iov, offset, nr_segs, | ||
1496 | xfs_get_blocks_direct, | 1502 | xfs_get_blocks_direct, |
1497 | xfs_end_io_direct); | 1503 | xfs_end_io_direct); |
1498 | } | 1504 | } |
@@ -1525,8 +1531,7 @@ xfs_vm_bmap( | |||
1525 | struct inode *inode = (struct inode *)mapping->host; | 1531 | struct inode *inode = (struct inode *)mapping->host; |
1526 | struct xfs_inode *ip = XFS_I(inode); | 1532 | struct xfs_inode *ip = XFS_I(inode); |
1527 | 1533 | ||
1528 | vn_trace_entry(XFS_I(inode), __FUNCTION__, | 1534 | xfs_itrace_entry(XFS_I(inode)); |
1529 | (inst_t *)__return_address); | ||
1530 | xfs_rwlock(ip, VRWLOCK_READ); | 1535 | xfs_rwlock(ip, VRWLOCK_READ); |
1531 | xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF); | 1536 | xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF); |
1532 | xfs_rwunlock(ip, VRWLOCK_READ); | 1537 | xfs_rwunlock(ip, VRWLOCK_READ); |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 0382c19d6523..e347bfd47c91 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -387,8 +387,6 @@ _xfs_buf_lookup_pages( | |||
387 | if (unlikely(page == NULL)) { | 387 | if (unlikely(page == NULL)) { |
388 | if (flags & XBF_READ_AHEAD) { | 388 | if (flags & XBF_READ_AHEAD) { |
389 | bp->b_page_count = i; | 389 | bp->b_page_count = i; |
390 | for (i = 0; i < bp->b_page_count; i++) | ||
391 | unlock_page(bp->b_pages[i]); | ||
392 | return -ENOMEM; | 390 | return -ENOMEM; |
393 | } | 391 | } |
394 | 392 | ||
@@ -418,24 +416,17 @@ _xfs_buf_lookup_pages( | |||
418 | ASSERT(!PagePrivate(page)); | 416 | ASSERT(!PagePrivate(page)); |
419 | if (!PageUptodate(page)) { | 417 | if (!PageUptodate(page)) { |
420 | page_count--; | 418 | page_count--; |
421 | if (blocksize >= PAGE_CACHE_SIZE) { | 419 | if (blocksize < PAGE_CACHE_SIZE && !PagePrivate(page)) { |
422 | if (flags & XBF_READ) | ||
423 | bp->b_locked = 1; | ||
424 | } else if (!PagePrivate(page)) { | ||
425 | if (test_page_region(page, offset, nbytes)) | 420 | if (test_page_region(page, offset, nbytes)) |
426 | page_count++; | 421 | page_count++; |
427 | } | 422 | } |
428 | } | 423 | } |
429 | 424 | ||
425 | unlock_page(page); | ||
430 | bp->b_pages[i] = page; | 426 | bp->b_pages[i] = page; |
431 | offset = 0; | 427 | offset = 0; |
432 | } | 428 | } |
433 | 429 | ||
434 | if (!bp->b_locked) { | ||
435 | for (i = 0; i < bp->b_page_count; i++) | ||
436 | unlock_page(bp->b_pages[i]); | ||
437 | } | ||
438 | |||
439 | if (page_count == bp->b_page_count) | 430 | if (page_count == bp->b_page_count) |
440 | bp->b_flags |= XBF_DONE; | 431 | bp->b_flags |= XBF_DONE; |
441 | 432 | ||
@@ -751,7 +742,6 @@ xfs_buf_associate_memory( | |||
751 | bp->b_pages[i] = mem_to_page((void *)pageaddr); | 742 | bp->b_pages[i] = mem_to_page((void *)pageaddr); |
752 | pageaddr += PAGE_CACHE_SIZE; | 743 | pageaddr += PAGE_CACHE_SIZE; |
753 | } | 744 | } |
754 | bp->b_locked = 0; | ||
755 | 745 | ||
756 | bp->b_count_desired = len; | 746 | bp->b_count_desired = len; |
757 | bp->b_buffer_length = buflen; | 747 | bp->b_buffer_length = buflen; |
@@ -1098,25 +1088,13 @@ xfs_buf_iostart( | |||
1098 | return status; | 1088 | return status; |
1099 | } | 1089 | } |
1100 | 1090 | ||
1101 | STATIC_INLINE int | ||
1102 | _xfs_buf_iolocked( | ||
1103 | xfs_buf_t *bp) | ||
1104 | { | ||
1105 | ASSERT(bp->b_flags & (XBF_READ | XBF_WRITE)); | ||
1106 | if (bp->b_flags & XBF_READ) | ||
1107 | return bp->b_locked; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | STATIC_INLINE void | 1091 | STATIC_INLINE void |
1112 | _xfs_buf_ioend( | 1092 | _xfs_buf_ioend( |
1113 | xfs_buf_t *bp, | 1093 | xfs_buf_t *bp, |
1114 | int schedule) | 1094 | int schedule) |
1115 | { | 1095 | { |
1116 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { | 1096 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) |
1117 | bp->b_locked = 0; | ||
1118 | xfs_buf_ioend(bp, schedule); | 1097 | xfs_buf_ioend(bp, schedule); |
1119 | } | ||
1120 | } | 1098 | } |
1121 | 1099 | ||
1122 | STATIC void | 1100 | STATIC void |
@@ -1147,10 +1125,6 @@ xfs_buf_bio_end_io( | |||
1147 | 1125 | ||
1148 | if (--bvec >= bio->bi_io_vec) | 1126 | if (--bvec >= bio->bi_io_vec) |
1149 | prefetchw(&bvec->bv_page->flags); | 1127 | prefetchw(&bvec->bv_page->flags); |
1150 | |||
1151 | if (_xfs_buf_iolocked(bp)) { | ||
1152 | unlock_page(page); | ||
1153 | } | ||
1154 | } while (bvec >= bio->bi_io_vec); | 1128 | } while (bvec >= bio->bi_io_vec); |
1155 | 1129 | ||
1156 | _xfs_buf_ioend(bp, 1); | 1130 | _xfs_buf_ioend(bp, 1); |
@@ -1161,13 +1135,12 @@ STATIC void | |||
1161 | _xfs_buf_ioapply( | 1135 | _xfs_buf_ioapply( |
1162 | xfs_buf_t *bp) | 1136 | xfs_buf_t *bp) |
1163 | { | 1137 | { |
1164 | int i, rw, map_i, total_nr_pages, nr_pages; | 1138 | int rw, map_i, total_nr_pages, nr_pages; |
1165 | struct bio *bio; | 1139 | struct bio *bio; |
1166 | int offset = bp->b_offset; | 1140 | int offset = bp->b_offset; |
1167 | int size = bp->b_count_desired; | 1141 | int size = bp->b_count_desired; |
1168 | sector_t sector = bp->b_bn; | 1142 | sector_t sector = bp->b_bn; |
1169 | unsigned int blocksize = bp->b_target->bt_bsize; | 1143 | unsigned int blocksize = bp->b_target->bt_bsize; |
1170 | int locking = _xfs_buf_iolocked(bp); | ||
1171 | 1144 | ||
1172 | total_nr_pages = bp->b_page_count; | 1145 | total_nr_pages = bp->b_page_count; |
1173 | map_i = 0; | 1146 | map_i = 0; |
@@ -1190,7 +1163,7 @@ _xfs_buf_ioapply( | |||
1190 | * filesystem block size is not smaller than the page size. | 1163 | * filesystem block size is not smaller than the page size. |
1191 | */ | 1164 | */ |
1192 | if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && | 1165 | if ((bp->b_buffer_length < PAGE_CACHE_SIZE) && |
1193 | (bp->b_flags & XBF_READ) && locking && | 1166 | (bp->b_flags & XBF_READ) && |
1194 | (blocksize >= PAGE_CACHE_SIZE)) { | 1167 | (blocksize >= PAGE_CACHE_SIZE)) { |
1195 | bio = bio_alloc(GFP_NOIO, 1); | 1168 | bio = bio_alloc(GFP_NOIO, 1); |
1196 | 1169 | ||
@@ -1207,24 +1180,6 @@ _xfs_buf_ioapply( | |||
1207 | goto submit_io; | 1180 | goto submit_io; |
1208 | } | 1181 | } |
1209 | 1182 | ||
1210 | /* Lock down the pages which we need to for the request */ | ||
1211 | if (locking && (bp->b_flags & XBF_WRITE) && (bp->b_locked == 0)) { | ||
1212 | for (i = 0; size; i++) { | ||
1213 | int nbytes = PAGE_CACHE_SIZE - offset; | ||
1214 | struct page *page = bp->b_pages[i]; | ||
1215 | |||
1216 | if (nbytes > size) | ||
1217 | nbytes = size; | ||
1218 | |||
1219 | lock_page(page); | ||
1220 | |||
1221 | size -= nbytes; | ||
1222 | offset = 0; | ||
1223 | } | ||
1224 | offset = bp->b_offset; | ||
1225 | size = bp->b_count_desired; | ||
1226 | } | ||
1227 | |||
1228 | next_chunk: | 1183 | next_chunk: |
1229 | atomic_inc(&bp->b_io_remaining); | 1184 | atomic_inc(&bp->b_io_remaining); |
1230 | nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT); | 1185 | nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT); |
@@ -1571,7 +1526,7 @@ xfs_alloc_delwrite_queue( | |||
1571 | 1526 | ||
1572 | INIT_LIST_HEAD(&btp->bt_list); | 1527 | INIT_LIST_HEAD(&btp->bt_list); |
1573 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); | 1528 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); |
1574 | spinlock_init(&btp->bt_delwrite_lock, "delwri_lock"); | 1529 | spin_lock_init(&btp->bt_delwrite_lock); |
1575 | btp->bt_flags = 0; | 1530 | btp->bt_flags = 0; |
1576 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd"); | 1531 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd"); |
1577 | if (IS_ERR(btp->bt_task)) { | 1532 | if (IS_ERR(btp->bt_task)) { |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index b5908a34b15d..a3d207de48b8 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -143,7 +143,6 @@ typedef struct xfs_buf { | |||
143 | void *b_fspriv2; | 143 | void *b_fspriv2; |
144 | void *b_fspriv3; | 144 | void *b_fspriv3; |
145 | unsigned short b_error; /* error code on I/O */ | 145 | unsigned short b_error; /* error code on I/O */ |
146 | unsigned short b_locked; /* page array is locked */ | ||
147 | unsigned int b_page_count; /* size of page array */ | 146 | unsigned int b_page_count; /* size of page array */ |
148 | unsigned int b_offset; /* page offset in first page */ | 147 | unsigned int b_offset; /* page offset in first page */ |
149 | struct page **b_pages; /* array of page pointers */ | 148 | struct page **b_pages; /* array of page pointers */ |
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 15bd4948832c..ca4f66c4de16 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
@@ -118,20 +118,29 @@ xfs_nfs_get_inode( | |||
118 | u64 ino, | 118 | u64 ino, |
119 | u32 generation) | 119 | u32 generation) |
120 | { | 120 | { |
121 | xfs_fid_t xfid; | 121 | xfs_mount_t *mp = XFS_M(sb); |
122 | bhv_vnode_t *vp; | 122 | xfs_inode_t *ip; |
123 | int error; | 123 | int error; |
124 | 124 | ||
125 | xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len); | 125 | /* |
126 | xfid.fid_pad = 0; | 126 | * NFS can sometimes send requests for ino 0. Fail them gracefully. |
127 | xfid.fid_ino = ino; | 127 | */ |
128 | xfid.fid_gen = generation; | 128 | if (ino == 0) |
129 | return ERR_PTR(-ESTALE); | ||
129 | 130 | ||
130 | error = xfs_vget(XFS_M(sb), &vp, &xfid); | 131 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); |
131 | if (error) | 132 | if (error) |
132 | return ERR_PTR(-error); | 133 | return ERR_PTR(-error); |
134 | if (!ip) | ||
135 | return ERR_PTR(-EIO); | ||
136 | |||
137 | if (!ip->i_d.di_mode || ip->i_d.di_gen != generation) { | ||
138 | xfs_iput_new(ip, XFS_ILOCK_SHARED); | ||
139 | return ERR_PTR(-ENOENT); | ||
140 | } | ||
133 | 141 | ||
134 | return vp ? vn_to_inode(vp) : NULL; | 142 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
143 | return ip->i_vnode; | ||
135 | } | 144 | } |
136 | 145 | ||
137 | STATIC struct dentry * | 146 | STATIC struct dentry * |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 21a1c2b1c5fc..edab1ffbb163 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -350,8 +350,8 @@ xfs_file_readdir( | |||
350 | 350 | ||
351 | size = buf.used; | 351 | size = buf.used; |
352 | de = (struct hack_dirent *)buf.dirent; | 352 | de = (struct hack_dirent *)buf.dirent; |
353 | curr_offset = de->offset /* & 0x7fffffff */; | ||
354 | while (size > 0) { | 353 | while (size > 0) { |
354 | curr_offset = de->offset /* & 0x7fffffff */; | ||
355 | if (filldir(dirent, de->name, de->namlen, | 355 | if (filldir(dirent, de->name, de->namlen, |
356 | curr_offset & 0x7fffffff, | 356 | curr_offset & 0x7fffffff, |
357 | de->ino, de->d_type)) { | 357 | de->ino, de->d_type)) { |
@@ -362,7 +362,6 @@ xfs_file_readdir( | |||
362 | sizeof(u64)); | 362 | sizeof(u64)); |
363 | size -= reclen; | 363 | size -= reclen; |
364 | de = (struct hack_dirent *)((char *)de + reclen); | 364 | de = (struct hack_dirent *)((char *)de + reclen); |
365 | curr_offset = de->offset /* & 0x7fffffff */; | ||
366 | } | 365 | } |
367 | } | 366 | } |
368 | 367 | ||
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index 9febf9dc999d..ef90e64641e6 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c | |||
@@ -47,5 +47,6 @@ xfs_param_t xfs_params = { | |||
47 | /* | 47 | /* |
48 | * Global system credential structure. | 48 | * Global system credential structure. |
49 | */ | 49 | */ |
50 | cred_t sys_cred_val, *sys_cred = &sys_cred_val; | 50 | static cred_t sys_cred_val; |
51 | cred_t *sys_cred = &sys_cred_val; | ||
51 | 52 | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 98a56568bb24..4c82a050a3a8 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -75,7 +75,6 @@ xfs_find_handle( | |||
75 | xfs_handle_t handle; | 75 | xfs_handle_t handle; |
76 | xfs_fsop_handlereq_t hreq; | 76 | xfs_fsop_handlereq_t hreq; |
77 | struct inode *inode; | 77 | struct inode *inode; |
78 | bhv_vnode_t *vp; | ||
79 | 78 | ||
80 | if (copy_from_user(&hreq, arg, sizeof(hreq))) | 79 | if (copy_from_user(&hreq, arg, sizeof(hreq))) |
81 | return -XFS_ERROR(EFAULT); | 80 | return -XFS_ERROR(EFAULT); |
@@ -134,21 +133,16 @@ xfs_find_handle( | |||
134 | return -XFS_ERROR(EBADF); | 133 | return -XFS_ERROR(EBADF); |
135 | } | 134 | } |
136 | 135 | ||
137 | /* we need the vnode */ | ||
138 | vp = vn_from_inode(inode); | ||
139 | |||
140 | /* now we can grab the fsid */ | 136 | /* now we can grab the fsid */ |
141 | memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid, | 137 | memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid, |
142 | sizeof(xfs_fsid_t)); | 138 | sizeof(xfs_fsid_t)); |
143 | hsize = sizeof(xfs_fsid_t); | 139 | hsize = sizeof(xfs_fsid_t); |
144 | 140 | ||
145 | if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { | 141 | if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { |
146 | xfs_inode_t *ip; | 142 | xfs_inode_t *ip = XFS_I(inode); |
147 | int lock_mode; | 143 | int lock_mode; |
148 | 144 | ||
149 | /* need to get access to the xfs_inode to read the generation */ | 145 | /* need to get access to the xfs_inode to read the generation */ |
150 | ip = xfs_vtoi(vp); | ||
151 | ASSERT(ip); | ||
152 | lock_mode = xfs_ilock_map_shared(ip); | 146 | lock_mode = xfs_ilock_map_shared(ip); |
153 | 147 | ||
154 | /* fill in fid section of handle from inode */ | 148 | /* fill in fid section of handle from inode */ |
@@ -176,21 +170,19 @@ xfs_find_handle( | |||
176 | 170 | ||
177 | 171 | ||
178 | /* | 172 | /* |
179 | * Convert userspace handle data into vnode (and inode). | 173 | * Convert userspace handle data into inode. |
180 | * We [ab]use the fact that all the fsop_handlereq ioctl calls | 174 | * |
181 | * have a data structure argument whose first component is always | 175 | * We use the fact that all the fsop_handlereq ioctl calls have a data |
182 | * a xfs_fsop_handlereq_t, so we can cast to and from this type. | 176 | * structure argument whose first component is always a xfs_fsop_handlereq_t, |
183 | * This allows us to optimise the copy_from_user calls and gives | 177 | * so we can pass that sub structure into this handy, shared routine. |
184 | * a handy, shared routine. | ||
185 | * | 178 | * |
186 | * If no error, caller must always VN_RELE the returned vp. | 179 | * If no error, caller must always iput the returned inode. |
187 | */ | 180 | */ |
188 | STATIC int | 181 | STATIC int |
189 | xfs_vget_fsop_handlereq( | 182 | xfs_vget_fsop_handlereq( |
190 | xfs_mount_t *mp, | 183 | xfs_mount_t *mp, |
191 | struct inode *parinode, /* parent inode pointer */ | 184 | struct inode *parinode, /* parent inode pointer */ |
192 | xfs_fsop_handlereq_t *hreq, | 185 | xfs_fsop_handlereq_t *hreq, |
193 | bhv_vnode_t **vp, | ||
194 | struct inode **inode) | 186 | struct inode **inode) |
195 | { | 187 | { |
196 | void __user *hanp; | 188 | void __user *hanp; |
@@ -199,8 +191,6 @@ xfs_vget_fsop_handlereq( | |||
199 | xfs_handle_t *handlep; | 191 | xfs_handle_t *handlep; |
200 | xfs_handle_t handle; | 192 | xfs_handle_t handle; |
201 | xfs_inode_t *ip; | 193 | xfs_inode_t *ip; |
202 | struct inode *inodep; | ||
203 | bhv_vnode_t *vpp; | ||
204 | xfs_ino_t ino; | 194 | xfs_ino_t ino; |
205 | __u32 igen; | 195 | __u32 igen; |
206 | int error; | 196 | int error; |
@@ -241,7 +231,7 @@ xfs_vget_fsop_handlereq( | |||
241 | } | 231 | } |
242 | 232 | ||
243 | /* | 233 | /* |
244 | * Get the XFS inode, building a vnode to go with it. | 234 | * Get the XFS inode, building a Linux inode to go with it. |
245 | */ | 235 | */ |
246 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); | 236 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); |
247 | if (error) | 237 | if (error) |
@@ -253,12 +243,9 @@ xfs_vget_fsop_handlereq( | |||
253 | return XFS_ERROR(ENOENT); | 243 | return XFS_ERROR(ENOENT); |
254 | } | 244 | } |
255 | 245 | ||
256 | vpp = XFS_ITOV(ip); | ||
257 | inodep = vn_to_inode(vpp); | ||
258 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 246 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
259 | 247 | ||
260 | *vp = vpp; | 248 | *inode = XFS_ITOV(ip); |
261 | *inode = inodep; | ||
262 | return 0; | 249 | return 0; |
263 | } | 250 | } |
264 | 251 | ||
@@ -275,7 +262,6 @@ xfs_open_by_handle( | |||
275 | struct file *filp; | 262 | struct file *filp; |
276 | struct inode *inode; | 263 | struct inode *inode; |
277 | struct dentry *dentry; | 264 | struct dentry *dentry; |
278 | bhv_vnode_t *vp; | ||
279 | xfs_fsop_handlereq_t hreq; | 265 | xfs_fsop_handlereq_t hreq; |
280 | 266 | ||
281 | if (!capable(CAP_SYS_ADMIN)) | 267 | if (!capable(CAP_SYS_ADMIN)) |
@@ -283,7 +269,7 @@ xfs_open_by_handle( | |||
283 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | 269 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) |
284 | return -XFS_ERROR(EFAULT); | 270 | return -XFS_ERROR(EFAULT); |
285 | 271 | ||
286 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); | 272 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); |
287 | if (error) | 273 | if (error) |
288 | return -error; | 274 | return -error; |
289 | 275 | ||
@@ -385,7 +371,6 @@ xfs_readlink_by_handle( | |||
385 | { | 371 | { |
386 | struct inode *inode; | 372 | struct inode *inode; |
387 | xfs_fsop_handlereq_t hreq; | 373 | xfs_fsop_handlereq_t hreq; |
388 | bhv_vnode_t *vp; | ||
389 | __u32 olen; | 374 | __u32 olen; |
390 | void *link; | 375 | void *link; |
391 | int error; | 376 | int error; |
@@ -395,7 +380,7 @@ xfs_readlink_by_handle( | |||
395 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | 380 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) |
396 | return -XFS_ERROR(EFAULT); | 381 | return -XFS_ERROR(EFAULT); |
397 | 382 | ||
398 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); | 383 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); |
399 | if (error) | 384 | if (error) |
400 | return -error; | 385 | return -error; |
401 | 386 | ||
@@ -438,34 +423,32 @@ xfs_fssetdm_by_handle( | |||
438 | struct fsdmidata fsd; | 423 | struct fsdmidata fsd; |
439 | xfs_fsop_setdm_handlereq_t dmhreq; | 424 | xfs_fsop_setdm_handlereq_t dmhreq; |
440 | struct inode *inode; | 425 | struct inode *inode; |
441 | bhv_vnode_t *vp; | ||
442 | 426 | ||
443 | if (!capable(CAP_MKNOD)) | 427 | if (!capable(CAP_MKNOD)) |
444 | return -XFS_ERROR(EPERM); | 428 | return -XFS_ERROR(EPERM); |
445 | if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) | 429 | if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) |
446 | return -XFS_ERROR(EFAULT); | 430 | return -XFS_ERROR(EFAULT); |
447 | 431 | ||
448 | error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &vp, &inode); | 432 | error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &inode); |
449 | if (error) | 433 | if (error) |
450 | return -error; | 434 | return -error; |
451 | 435 | ||
452 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { | 436 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { |
453 | VN_RELE(vp); | 437 | error = -XFS_ERROR(EPERM); |
454 | return -XFS_ERROR(EPERM); | 438 | goto out; |
455 | } | 439 | } |
456 | 440 | ||
457 | if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { | 441 | if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { |
458 | VN_RELE(vp); | 442 | error = -XFS_ERROR(EFAULT); |
459 | return -XFS_ERROR(EFAULT); | 443 | goto out; |
460 | } | 444 | } |
461 | 445 | ||
462 | error = xfs_set_dmattrs(xfs_vtoi(vp), | 446 | error = -xfs_set_dmattrs(XFS_I(inode), fsd.fsd_dmevmask, |
463 | fsd.fsd_dmevmask, fsd.fsd_dmstate); | 447 | fsd.fsd_dmstate); |
464 | 448 | ||
465 | VN_RELE(vp); | 449 | out: |
466 | if (error) | 450 | iput(inode); |
467 | return -error; | 451 | return error; |
468 | return 0; | ||
469 | } | 452 | } |
470 | 453 | ||
471 | STATIC int | 454 | STATIC int |
@@ -478,7 +461,6 @@ xfs_attrlist_by_handle( | |||
478 | attrlist_cursor_kern_t *cursor; | 461 | attrlist_cursor_kern_t *cursor; |
479 | xfs_fsop_attrlist_handlereq_t al_hreq; | 462 | xfs_fsop_attrlist_handlereq_t al_hreq; |
480 | struct inode *inode; | 463 | struct inode *inode; |
481 | bhv_vnode_t *vp; | ||
482 | char *kbuf; | 464 | char *kbuf; |
483 | 465 | ||
484 | if (!capable(CAP_SYS_ADMIN)) | 466 | if (!capable(CAP_SYS_ADMIN)) |
@@ -488,8 +470,7 @@ xfs_attrlist_by_handle( | |||
488 | if (al_hreq.buflen > XATTR_LIST_MAX) | 470 | if (al_hreq.buflen > XATTR_LIST_MAX) |
489 | return -XFS_ERROR(EINVAL); | 471 | return -XFS_ERROR(EINVAL); |
490 | 472 | ||
491 | error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, | 473 | error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, &inode); |
492 | &vp, &inode); | ||
493 | if (error) | 474 | if (error) |
494 | goto out; | 475 | goto out; |
495 | 476 | ||
@@ -509,7 +490,7 @@ xfs_attrlist_by_handle( | |||
509 | out_kfree: | 490 | out_kfree: |
510 | kfree(kbuf); | 491 | kfree(kbuf); |
511 | out_vn_rele: | 492 | out_vn_rele: |
512 | VN_RELE(vp); | 493 | iput(inode); |
513 | out: | 494 | out: |
514 | return -error; | 495 | return -error; |
515 | } | 496 | } |
@@ -531,7 +512,7 @@ xfs_attrmulti_attr_get( | |||
531 | if (!kbuf) | 512 | if (!kbuf) |
532 | return ENOMEM; | 513 | return ENOMEM; |
533 | 514 | ||
534 | error = xfs_attr_get(XFS_I(inode), name, kbuf, len, flags, NULL); | 515 | error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags, NULL); |
535 | if (error) | 516 | if (error) |
536 | goto out_kfree; | 517 | goto out_kfree; |
537 | 518 | ||
@@ -598,7 +579,6 @@ xfs_attrmulti_by_handle( | |||
598 | xfs_attr_multiop_t *ops; | 579 | xfs_attr_multiop_t *ops; |
599 | xfs_fsop_attrmulti_handlereq_t am_hreq; | 580 | xfs_fsop_attrmulti_handlereq_t am_hreq; |
600 | struct inode *inode; | 581 | struct inode *inode; |
601 | bhv_vnode_t *vp; | ||
602 | unsigned int i, size; | 582 | unsigned int i, size; |
603 | char *attr_name; | 583 | char *attr_name; |
604 | 584 | ||
@@ -607,7 +587,7 @@ xfs_attrmulti_by_handle( | |||
607 | if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) | 587 | if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) |
608 | return -XFS_ERROR(EFAULT); | 588 | return -XFS_ERROR(EFAULT); |
609 | 589 | ||
610 | error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &vp, &inode); | 590 | error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &inode); |
611 | if (error) | 591 | if (error) |
612 | goto out; | 592 | goto out; |
613 | 593 | ||
@@ -666,7 +646,7 @@ xfs_attrmulti_by_handle( | |||
666 | out_kfree_ops: | 646 | out_kfree_ops: |
667 | kfree(ops); | 647 | kfree(ops); |
668 | out_vn_rele: | 648 | out_vn_rele: |
669 | VN_RELE(vp); | 649 | iput(inode); |
670 | out: | 650 | out: |
671 | return -error; | 651 | return -error; |
672 | } | 652 | } |
@@ -702,7 +682,6 @@ xfs_ioc_fsgeometry( | |||
702 | 682 | ||
703 | STATIC int | 683 | STATIC int |
704 | xfs_ioc_xattr( | 684 | xfs_ioc_xattr( |
705 | bhv_vnode_t *vp, | ||
706 | xfs_inode_t *ip, | 685 | xfs_inode_t *ip, |
707 | struct file *filp, | 686 | struct file *filp, |
708 | unsigned int cmd, | 687 | unsigned int cmd, |
@@ -735,12 +714,10 @@ xfs_ioctl( | |||
735 | void __user *arg) | 714 | void __user *arg) |
736 | { | 715 | { |
737 | struct inode *inode = filp->f_path.dentry->d_inode; | 716 | struct inode *inode = filp->f_path.dentry->d_inode; |
738 | bhv_vnode_t *vp = vn_from_inode(inode); | ||
739 | xfs_mount_t *mp = ip->i_mount; | 717 | xfs_mount_t *mp = ip->i_mount; |
740 | int error; | 718 | int error; |
741 | 719 | ||
742 | vn_trace_entry(XFS_I(inode), "xfs_ioctl", (inst_t *)__return_address); | 720 | xfs_itrace_entry(XFS_I(inode)); |
743 | |||
744 | switch (cmd) { | 721 | switch (cmd) { |
745 | 722 | ||
746 | case XFS_IOC_ALLOCSP: | 723 | case XFS_IOC_ALLOCSP: |
@@ -764,7 +741,7 @@ xfs_ioctl( | |||
764 | case XFS_IOC_DIOINFO: { | 741 | case XFS_IOC_DIOINFO: { |
765 | struct dioattr da; | 742 | struct dioattr da; |
766 | xfs_buftarg_t *target = | 743 | xfs_buftarg_t *target = |
767 | (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 744 | XFS_IS_REALTIME_INODE(ip) ? |
768 | mp->m_rtdev_targp : mp->m_ddev_targp; | 745 | mp->m_rtdev_targp : mp->m_ddev_targp; |
769 | 746 | ||
770 | da.d_mem = da.d_miniosz = 1 << target->bt_sshift; | 747 | da.d_mem = da.d_miniosz = 1 << target->bt_sshift; |
@@ -796,7 +773,7 @@ xfs_ioctl( | |||
796 | case XFS_IOC_GETXFLAGS: | 773 | case XFS_IOC_GETXFLAGS: |
797 | case XFS_IOC_SETXFLAGS: | 774 | case XFS_IOC_SETXFLAGS: |
798 | case XFS_IOC_FSSETXATTR: | 775 | case XFS_IOC_FSSETXATTR: |
799 | return xfs_ioc_xattr(vp, ip, filp, cmd, arg); | 776 | return xfs_ioc_xattr(ip, filp, cmd, arg); |
800 | 777 | ||
801 | case XFS_IOC_FSSETDM: { | 778 | case XFS_IOC_FSSETDM: { |
802 | struct fsdmidata dmi; | 779 | struct fsdmidata dmi; |
@@ -1203,7 +1180,6 @@ xfs_ioc_fsgetxattr( | |||
1203 | 1180 | ||
1204 | STATIC int | 1181 | STATIC int |
1205 | xfs_ioc_xattr( | 1182 | xfs_ioc_xattr( |
1206 | bhv_vnode_t *vp, | ||
1207 | xfs_inode_t *ip, | 1183 | xfs_inode_t *ip, |
1208 | struct file *filp, | 1184 | struct file *filp, |
1209 | unsigned int cmd, | 1185 | unsigned int cmd, |
@@ -1237,7 +1213,7 @@ xfs_ioc_xattr( | |||
1237 | 1213 | ||
1238 | error = xfs_setattr(ip, vattr, attr_flags, NULL); | 1214 | error = xfs_setattr(ip, vattr, attr_flags, NULL); |
1239 | if (likely(!error)) | 1215 | if (likely(!error)) |
1240 | __vn_revalidate(vp, vattr); /* update flags */ | 1216 | vn_revalidate(XFS_ITOV(ip)); /* update flags */ |
1241 | error = -error; | 1217 | error = -error; |
1242 | break; | 1218 | break; |
1243 | } | 1219 | } |
@@ -1272,7 +1248,7 @@ xfs_ioc_xattr( | |||
1272 | 1248 | ||
1273 | error = xfs_setattr(ip, vattr, attr_flags, NULL); | 1249 | error = xfs_setattr(ip, vattr, attr_flags, NULL); |
1274 | if (likely(!error)) | 1250 | if (likely(!error)) |
1275 | __vn_revalidate(vp, vattr); /* update flags */ | 1251 | vn_revalidate(XFS_ITOV(ip)); /* update flags */ |
1276 | error = -error; | 1252 | error = -error; |
1277 | break; | 1253 | break; |
1278 | } | 1254 | } |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index bf2a956b63c2..a4b254eb43b2 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "xfs_error.h" | 44 | #include "xfs_error.h" |
45 | #include "xfs_dfrag.h" | 45 | #include "xfs_dfrag.h" |
46 | #include "xfs_vnodeops.h" | 46 | #include "xfs_vnodeops.h" |
47 | #include "xfs_ioctl32.h" | ||
47 | 48 | ||
48 | #define _NATIVE_IOC(cmd, type) \ | 49 | #define _NATIVE_IOC(cmd, type) \ |
49 | _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) | 50 | _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) |
@@ -379,9 +380,6 @@ xfs_compat_ioctl( | |||
379 | switch (cmd) { | 380 | switch (cmd) { |
380 | case XFS_IOC_DIOINFO: | 381 | case XFS_IOC_DIOINFO: |
381 | case XFS_IOC_FSGEOMETRY: | 382 | case XFS_IOC_FSGEOMETRY: |
382 | case XFS_IOC_GETVERSION: | ||
383 | case XFS_IOC_GETXFLAGS: | ||
384 | case XFS_IOC_SETXFLAGS: | ||
385 | case XFS_IOC_FSGETXATTR: | 383 | case XFS_IOC_FSGETXATTR: |
386 | case XFS_IOC_FSSETXATTR: | 384 | case XFS_IOC_FSSETXATTR: |
387 | case XFS_IOC_FSGETXATTRA: | 385 | case XFS_IOC_FSGETXATTRA: |
@@ -407,6 +405,11 @@ xfs_compat_ioctl( | |||
407 | case XFS_IOC_ERROR_CLEARALL: | 405 | case XFS_IOC_ERROR_CLEARALL: |
408 | break; | 406 | break; |
409 | 407 | ||
408 | case XFS_IOC32_GETXFLAGS: | ||
409 | case XFS_IOC32_SETXFLAGS: | ||
410 | case XFS_IOC32_GETVERSION: | ||
411 | cmd = _NATIVE_IOC(cmd, long); | ||
412 | break; | ||
410 | #ifdef BROKEN_X86_ALIGNMENT | 413 | #ifdef BROKEN_X86_ALIGNMENT |
411 | /* xfs_flock_t has wrong u32 vs u64 alignment */ | 414 | /* xfs_flock_t has wrong u32 vs u64 alignment */ |
412 | case XFS_IOC_ALLOCSP_32: | 415 | case XFS_IOC_ALLOCSP_32: |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 5e8bb7f71b5a..cc4abd3daa49 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/xattr.h> | 52 | #include <linux/xattr.h> |
53 | #include <linux/namei.h> | 53 | #include <linux/namei.h> |
54 | #include <linux/security.h> | 54 | #include <linux/security.h> |
55 | #include <linux/falloc.h> | ||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * Bring the atime in the XFS inode uptodate. | 58 | * Bring the atime in the XFS inode uptodate. |
@@ -71,6 +72,22 @@ xfs_synchronize_atime( | |||
71 | } | 72 | } |
72 | 73 | ||
73 | /* | 74 | /* |
75 | * If the linux inode exists, mark it dirty. | ||
76 | * Used when commiting a dirty inode into a transaction so that | ||
77 | * the inode will get written back by the linux code | ||
78 | */ | ||
79 | void | ||
80 | xfs_mark_inode_dirty_sync( | ||
81 | xfs_inode_t *ip) | ||
82 | { | ||
83 | bhv_vnode_t *vp; | ||
84 | |||
85 | vp = XFS_ITOV_NULL(ip); | ||
86 | if (vp) | ||
87 | mark_inode_dirty_sync(vn_to_inode(vp)); | ||
88 | } | ||
89 | |||
90 | /* | ||
74 | * Change the requested timestamp in the given inode. | 91 | * Change the requested timestamp in the given inode. |
75 | * We don't lock across timestamp updates, and we don't log them but | 92 | * We don't lock across timestamp updates, and we don't log them but |
76 | * we do record the fact that there is dirty information in core. | 93 | * we do record the fact that there is dirty information in core. |
@@ -184,10 +201,6 @@ xfs_validate_fields( | |||
184 | struct xfs_inode *ip = XFS_I(inode); | 201 | struct xfs_inode *ip = XFS_I(inode); |
185 | loff_t size; | 202 | loff_t size; |
186 | 203 | ||
187 | inode->i_nlink = ip->i_d.di_nlink; | ||
188 | inode->i_blocks = | ||
189 | XFS_FSB_TO_BB(ip->i_mount, ip->i_d.di_nblocks + | ||
190 | ip->i_delayed_blks); | ||
191 | /* we're under i_sem so i_size can't change under us */ | 204 | /* we're under i_sem so i_size can't change under us */ |
192 | size = XFS_ISIZE(ip); | 205 | size = XFS_ISIZE(ip); |
193 | if (i_size_read(inode) != size) | 206 | if (i_size_read(inode) != size) |
@@ -542,12 +555,31 @@ xfs_vn_put_link( | |||
542 | 555 | ||
543 | #ifdef CONFIG_XFS_POSIX_ACL | 556 | #ifdef CONFIG_XFS_POSIX_ACL |
544 | STATIC int | 557 | STATIC int |
558 | xfs_check_acl( | ||
559 | struct inode *inode, | ||
560 | int mask) | ||
561 | { | ||
562 | struct xfs_inode *ip = XFS_I(inode); | ||
563 | int error; | ||
564 | |||
565 | xfs_itrace_entry(ip); | ||
566 | |||
567 | if (XFS_IFORK_Q(ip)) { | ||
568 | error = xfs_acl_iaccess(ip, mask, NULL); | ||
569 | if (error != -1) | ||
570 | return -error; | ||
571 | } | ||
572 | |||
573 | return -EAGAIN; | ||
574 | } | ||
575 | |||
576 | STATIC int | ||
545 | xfs_vn_permission( | 577 | xfs_vn_permission( |
546 | struct inode *inode, | 578 | struct inode *inode, |
547 | int mode, | 579 | int mask, |
548 | struct nameidata *nd) | 580 | struct nameidata *nd) |
549 | { | 581 | { |
550 | return -xfs_access(XFS_I(inode), mode << 6, NULL); | 582 | return generic_permission(inode, mask, xfs_check_acl); |
551 | } | 583 | } |
552 | #else | 584 | #else |
553 | #define xfs_vn_permission NULL | 585 | #define xfs_vn_permission NULL |
@@ -555,33 +587,61 @@ xfs_vn_permission( | |||
555 | 587 | ||
556 | STATIC int | 588 | STATIC int |
557 | xfs_vn_getattr( | 589 | xfs_vn_getattr( |
558 | struct vfsmount *mnt, | 590 | struct vfsmount *mnt, |
559 | struct dentry *dentry, | 591 | struct dentry *dentry, |
560 | struct kstat *stat) | 592 | struct kstat *stat) |
561 | { | 593 | { |
562 | struct inode *inode = dentry->d_inode; | 594 | struct inode *inode = dentry->d_inode; |
563 | bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; | 595 | struct xfs_inode *ip = XFS_I(inode); |
564 | int error; | 596 | struct xfs_mount *mp = ip->i_mount; |
565 | 597 | ||
566 | error = xfs_getattr(XFS_I(inode), &vattr, ATTR_LAZY); | 598 | xfs_itrace_entry(ip); |
567 | if (likely(!error)) { | 599 | |
568 | stat->size = i_size_read(inode); | 600 | if (XFS_FORCED_SHUTDOWN(mp)) |
569 | stat->dev = inode->i_sb->s_dev; | 601 | return XFS_ERROR(EIO); |
570 | stat->rdev = (vattr.va_rdev == 0) ? 0 : | 602 | |
571 | MKDEV(sysv_major(vattr.va_rdev) & 0x1ff, | 603 | stat->size = XFS_ISIZE(ip); |
572 | sysv_minor(vattr.va_rdev)); | 604 | stat->dev = inode->i_sb->s_dev; |
573 | stat->mode = vattr.va_mode; | 605 | stat->mode = ip->i_d.di_mode; |
574 | stat->nlink = vattr.va_nlink; | 606 | stat->nlink = ip->i_d.di_nlink; |
575 | stat->uid = vattr.va_uid; | 607 | stat->uid = ip->i_d.di_uid; |
576 | stat->gid = vattr.va_gid; | 608 | stat->gid = ip->i_d.di_gid; |
577 | stat->ino = vattr.va_nodeid; | 609 | stat->ino = ip->i_ino; |
578 | stat->atime = vattr.va_atime; | 610 | #if XFS_BIG_INUMS |
579 | stat->mtime = vattr.va_mtime; | 611 | stat->ino += mp->m_inoadd; |
580 | stat->ctime = vattr.va_ctime; | 612 | #endif |
581 | stat->blocks = vattr.va_nblocks; | 613 | stat->atime = inode->i_atime; |
582 | stat->blksize = vattr.va_blocksize; | 614 | stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec; |
615 | stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | ||
616 | stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec; | ||
617 | stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; | ||
618 | stat->blocks = | ||
619 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
620 | |||
621 | |||
622 | switch (inode->i_mode & S_IFMT) { | ||
623 | case S_IFBLK: | ||
624 | case S_IFCHR: | ||
625 | stat->blksize = BLKDEV_IOSIZE; | ||
626 | stat->rdev = MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, | ||
627 | sysv_minor(ip->i_df.if_u2.if_rdev)); | ||
628 | break; | ||
629 | default: | ||
630 | if (XFS_IS_REALTIME_INODE(ip)) { | ||
631 | /* | ||
632 | * If the file blocks are being allocated from a | ||
633 | * realtime volume, then return the inode's realtime | ||
634 | * extent size or the realtime volume's extent size. | ||
635 | */ | ||
636 | stat->blksize = | ||
637 | xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; | ||
638 | } else | ||
639 | stat->blksize = xfs_preferred_iosize(mp); | ||
640 | stat->rdev = 0; | ||
641 | break; | ||
583 | } | 642 | } |
584 | return -error; | 643 | |
644 | return 0; | ||
585 | } | 645 | } |
586 | 646 | ||
587 | STATIC int | 647 | STATIC int |
@@ -636,7 +696,7 @@ xfs_vn_setattr( | |||
636 | 696 | ||
637 | error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL); | 697 | error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL); |
638 | if (likely(!error)) | 698 | if (likely(!error)) |
639 | __vn_revalidate(vn_from_inode(inode), &vattr); | 699 | vn_revalidate(vn_from_inode(inode)); |
640 | return -error; | 700 | return -error; |
641 | } | 701 | } |
642 | 702 | ||
@@ -750,6 +810,47 @@ xfs_vn_removexattr( | |||
750 | return namesp->attr_remove(vp, attr, xflags); | 810 | return namesp->attr_remove(vp, attr, xflags); |
751 | } | 811 | } |
752 | 812 | ||
813 | STATIC long | ||
814 | xfs_vn_fallocate( | ||
815 | struct inode *inode, | ||
816 | int mode, | ||
817 | loff_t offset, | ||
818 | loff_t len) | ||
819 | { | ||
820 | long error; | ||
821 | loff_t new_size = 0; | ||
822 | xfs_flock64_t bf; | ||
823 | xfs_inode_t *ip = XFS_I(inode); | ||
824 | |||
825 | /* preallocation on directories not yet supported */ | ||
826 | error = -ENODEV; | ||
827 | if (S_ISDIR(inode->i_mode)) | ||
828 | goto out_error; | ||
829 | |||
830 | bf.l_whence = 0; | ||
831 | bf.l_start = offset; | ||
832 | bf.l_len = len; | ||
833 | |||
834 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
835 | error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, | ||
836 | 0, NULL, ATTR_NOLOCK); | ||
837 | if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && | ||
838 | offset + len > i_size_read(inode)) | ||
839 | new_size = offset + len; | ||
840 | |||
841 | /* Change file size if needed */ | ||
842 | if (new_size) { | ||
843 | bhv_vattr_t va; | ||
844 | |||
845 | va.va_mask = XFS_AT_SIZE; | ||
846 | va.va_size = new_size; | ||
847 | error = xfs_setattr(ip, &va, ATTR_NOLOCK, NULL); | ||
848 | } | ||
849 | |||
850 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
851 | out_error: | ||
852 | return error; | ||
853 | } | ||
753 | 854 | ||
754 | const struct inode_operations xfs_inode_operations = { | 855 | const struct inode_operations xfs_inode_operations = { |
755 | .permission = xfs_vn_permission, | 856 | .permission = xfs_vn_permission, |
@@ -760,6 +861,7 @@ const struct inode_operations xfs_inode_operations = { | |||
760 | .getxattr = xfs_vn_getxattr, | 861 | .getxattr = xfs_vn_getxattr, |
761 | .listxattr = xfs_vn_listxattr, | 862 | .listxattr = xfs_vn_listxattr, |
762 | .removexattr = xfs_vn_removexattr, | 863 | .removexattr = xfs_vn_removexattr, |
864 | .fallocate = xfs_vn_fallocate, | ||
763 | }; | 865 | }; |
764 | 866 | ||
765 | const struct inode_operations xfs_dir_inode_operations = { | 867 | const struct inode_operations xfs_dir_inode_operations = { |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index dc3752de22da..3ca39c4e5d2a 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <kmem.h> | 44 | #include <kmem.h> |
45 | #include <mrlock.h> | 45 | #include <mrlock.h> |
46 | #include <spin.h> | ||
47 | #include <sv.h> | 46 | #include <sv.h> |
48 | #include <mutex.h> | 47 | #include <mutex.h> |
49 | #include <sema.h> | 48 | #include <sema.h> |
@@ -75,6 +74,7 @@ | |||
75 | #include <linux/notifier.h> | 74 | #include <linux/notifier.h> |
76 | #include <linux/delay.h> | 75 | #include <linux/delay.h> |
77 | #include <linux/log2.h> | 76 | #include <linux/log2.h> |
77 | #include <linux/spinlock.h> | ||
78 | 78 | ||
79 | #include <asm/page.h> | 79 | #include <asm/page.h> |
80 | #include <asm/div64.h> | 80 | #include <asm/div64.h> |
@@ -136,43 +136,19 @@ | |||
136 | #define current_restore_flags_nested(sp, f) \ | 136 | #define current_restore_flags_nested(sp, f) \ |
137 | (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) | 137 | (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) |
138 | 138 | ||
139 | #define NBPP PAGE_SIZE | 139 | #define spinlock_destroy(lock) |
140 | #define NDPP (1 << (PAGE_SHIFT - 9)) | ||
141 | 140 | ||
142 | #define NBBY 8 /* number of bits per byte */ | 141 | #define NBBY 8 /* number of bits per byte */ |
143 | #define NBPC PAGE_SIZE /* Number of bytes per click */ | ||
144 | #define BPCSHIFT PAGE_SHIFT /* LOG2(NBPC) if exact */ | ||
145 | 142 | ||
146 | /* | 143 | /* |
147 | * Size of block device i/o is parameterized here. | 144 | * Size of block device i/o is parameterized here. |
148 | * Currently the system supports page-sized i/o. | 145 | * Currently the system supports page-sized i/o. |
149 | */ | 146 | */ |
150 | #define BLKDEV_IOSHIFT BPCSHIFT | 147 | #define BLKDEV_IOSHIFT PAGE_CACHE_SHIFT |
151 | #define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT) | 148 | #define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT) |
152 | /* number of BB's per block device block */ | 149 | /* number of BB's per block device block */ |
153 | #define BLKDEV_BB BTOBB(BLKDEV_IOSIZE) | 150 | #define BLKDEV_BB BTOBB(BLKDEV_IOSIZE) |
154 | 151 | ||
155 | /* bytes to clicks */ | ||
156 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) | ||
157 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) | ||
158 | #define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) | ||
159 | #define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT) | ||
160 | |||
161 | /* off_t bytes to clicks */ | ||
162 | #define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) | ||
163 | #define offtoct(x) ((xfs_off_t)(x)>>BPCSHIFT) | ||
164 | |||
165 | /* clicks to off_t bytes */ | ||
166 | #define ctooff(x) ((xfs_off_t)(x)<<BPCSHIFT) | ||
167 | |||
168 | /* clicks to bytes */ | ||
169 | #define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT) | ||
170 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) | ||
171 | #define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT) | ||
172 | |||
173 | /* bytes to clicks */ | ||
174 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) | ||
175 | |||
176 | #define ENOATTR ENODATA /* Attribute not found */ | 152 | #define ENOATTR ENODATA /* Attribute not found */ |
177 | #define EWRONGFS EINVAL /* Mount with wrong filesystem type */ | 153 | #define EWRONGFS EINVAL /* Mount with wrong filesystem type */ |
178 | #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ | 154 | #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ |
@@ -205,10 +181,6 @@ | |||
205 | #define xfs_stack_trace() dump_stack() | 181 | #define xfs_stack_trace() dump_stack() |
206 | #define xfs_itruncate_data(ip, off) \ | 182 | #define xfs_itruncate_data(ip, off) \ |
207 | (-vmtruncate(vn_to_inode(XFS_ITOV(ip)), (off))) | 183 | (-vmtruncate(vn_to_inode(XFS_ITOV(ip)), (off))) |
208 | #define xfs_statvfs_fsid(statp, mp) \ | ||
209 | ({ u64 id = huge_encode_dev((mp)->m_ddev_targp->bt_dev); \ | ||
210 | __kernel_fsid_t *fsid = &(statp)->f_fsid; \ | ||
211 | (fsid->val[0] = (u32)id, fsid->val[1] = (u32)(id >> 32)); }) | ||
212 | 184 | ||
213 | 185 | ||
214 | /* Move the kernel do_div definition off to one side */ | 186 | /* Move the kernel do_div definition off to one side */ |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 6f614f35f650..166353388490 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -58,14 +58,12 @@ | |||
58 | void | 58 | void |
59 | xfs_rw_enter_trace( | 59 | xfs_rw_enter_trace( |
60 | int tag, | 60 | int tag, |
61 | xfs_iocore_t *io, | 61 | xfs_inode_t *ip, |
62 | void *data, | 62 | void *data, |
63 | size_t segs, | 63 | size_t segs, |
64 | loff_t offset, | 64 | loff_t offset, |
65 | int ioflags) | 65 | int ioflags) |
66 | { | 66 | { |
67 | xfs_inode_t *ip = XFS_IO_INODE(io); | ||
68 | |||
69 | if (ip->i_rwtrace == NULL) | 67 | if (ip->i_rwtrace == NULL) |
70 | return; | 68 | return; |
71 | ktrace_enter(ip->i_rwtrace, | 69 | ktrace_enter(ip->i_rwtrace, |
@@ -78,8 +76,8 @@ xfs_rw_enter_trace( | |||
78 | (void *)((unsigned long)((offset >> 32) & 0xffffffff)), | 76 | (void *)((unsigned long)((offset >> 32) & 0xffffffff)), |
79 | (void *)((unsigned long)(offset & 0xffffffff)), | 77 | (void *)((unsigned long)(offset & 0xffffffff)), |
80 | (void *)((unsigned long)ioflags), | 78 | (void *)((unsigned long)ioflags), |
81 | (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)), | 79 | (void *)((unsigned long)((ip->i_new_size >> 32) & 0xffffffff)), |
82 | (void *)((unsigned long)(io->io_new_size & 0xffffffff)), | 80 | (void *)((unsigned long)(ip->i_new_size & 0xffffffff)), |
83 | (void *)((unsigned long)current_pid()), | 81 | (void *)((unsigned long)current_pid()), |
84 | (void *)NULL, | 82 | (void *)NULL, |
85 | (void *)NULL, | 83 | (void *)NULL, |
@@ -89,13 +87,12 @@ xfs_rw_enter_trace( | |||
89 | 87 | ||
90 | void | 88 | void |
91 | xfs_inval_cached_trace( | 89 | xfs_inval_cached_trace( |
92 | xfs_iocore_t *io, | 90 | xfs_inode_t *ip, |
93 | xfs_off_t offset, | 91 | xfs_off_t offset, |
94 | xfs_off_t len, | 92 | xfs_off_t len, |
95 | xfs_off_t first, | 93 | xfs_off_t first, |
96 | xfs_off_t last) | 94 | xfs_off_t last) |
97 | { | 95 | { |
98 | xfs_inode_t *ip = XFS_IO_INODE(io); | ||
99 | 96 | ||
100 | if (ip->i_rwtrace == NULL) | 97 | if (ip->i_rwtrace == NULL) |
101 | return; | 98 | return; |
@@ -131,7 +128,7 @@ xfs_inval_cached_trace( | |||
131 | */ | 128 | */ |
132 | STATIC int | 129 | STATIC int |
133 | xfs_iozero( | 130 | xfs_iozero( |
134 | struct inode *ip, /* inode */ | 131 | struct xfs_inode *ip, /* inode */ |
135 | loff_t pos, /* offset in file */ | 132 | loff_t pos, /* offset in file */ |
136 | size_t count) /* size of data to zero */ | 133 | size_t count) /* size of data to zero */ |
137 | { | 134 | { |
@@ -139,7 +136,7 @@ xfs_iozero( | |||
139 | struct address_space *mapping; | 136 | struct address_space *mapping; |
140 | int status; | 137 | int status; |
141 | 138 | ||
142 | mapping = ip->i_mapping; | 139 | mapping = ip->i_vnode->i_mapping; |
143 | do { | 140 | do { |
144 | unsigned offset, bytes; | 141 | unsigned offset, bytes; |
145 | void *fsdata; | 142 | void *fsdata; |
@@ -205,7 +202,7 @@ xfs_read( | |||
205 | 202 | ||
206 | if (unlikely(ioflags & IO_ISDIRECT)) { | 203 | if (unlikely(ioflags & IO_ISDIRECT)) { |
207 | xfs_buftarg_t *target = | 204 | xfs_buftarg_t *target = |
208 | (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 205 | XFS_IS_REALTIME_INODE(ip) ? |
209 | mp->m_rtdev_targp : mp->m_ddev_targp; | 206 | mp->m_rtdev_targp : mp->m_ddev_targp; |
210 | if ((*offset & target->bt_smask) || | 207 | if ((*offset & target->bt_smask) || |
211 | (size & target->bt_smask)) { | 208 | (size & target->bt_smask)) { |
@@ -246,9 +243,8 @@ xfs_read( | |||
246 | 243 | ||
247 | if (unlikely(ioflags & IO_ISDIRECT)) { | 244 | if (unlikely(ioflags & IO_ISDIRECT)) { |
248 | if (VN_CACHED(vp)) | 245 | if (VN_CACHED(vp)) |
249 | ret = xfs_flushinval_pages(ip, | 246 | ret = xfs_flushinval_pages(ip, (*offset & PAGE_CACHE_MASK), |
250 | ctooff(offtoct(*offset)), | 247 | -1, FI_REMAPF_LOCKED); |
251 | -1, FI_REMAPF_LOCKED); | ||
252 | mutex_unlock(&inode->i_mutex); | 248 | mutex_unlock(&inode->i_mutex); |
253 | if (ret) { | 249 | if (ret) { |
254 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 250 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
@@ -256,7 +252,7 @@ xfs_read( | |||
256 | } | 252 | } |
257 | } | 253 | } |
258 | 254 | ||
259 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, | 255 | xfs_rw_enter_trace(XFS_READ_ENTER, ip, |
260 | (void *)iovp, segs, *offset, ioflags); | 256 | (void *)iovp, segs, *offset, ioflags); |
261 | 257 | ||
262 | iocb->ki_pos = *offset; | 258 | iocb->ki_pos = *offset; |
@@ -301,7 +297,7 @@ xfs_splice_read( | |||
301 | return -error; | 297 | return -error; |
302 | } | 298 | } |
303 | } | 299 | } |
304 | xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore, | 300 | xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, ip, |
305 | pipe, count, *ppos, ioflags); | 301 | pipe, count, *ppos, ioflags); |
306 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); | 302 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); |
307 | if (ret > 0) | 303 | if (ret > 0) |
@@ -323,7 +319,6 @@ xfs_splice_write( | |||
323 | { | 319 | { |
324 | bhv_vnode_t *vp = XFS_ITOV(ip); | 320 | bhv_vnode_t *vp = XFS_ITOV(ip); |
325 | xfs_mount_t *mp = ip->i_mount; | 321 | xfs_mount_t *mp = ip->i_mount; |
326 | xfs_iocore_t *io = &ip->i_iocore; | ||
327 | ssize_t ret; | 322 | ssize_t ret; |
328 | struct inode *inode = outfilp->f_mapping->host; | 323 | struct inode *inode = outfilp->f_mapping->host; |
329 | xfs_fsize_t isize, new_size; | 324 | xfs_fsize_t isize, new_size; |
@@ -350,10 +345,10 @@ xfs_splice_write( | |||
350 | 345 | ||
351 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 346 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
352 | if (new_size > ip->i_size) | 347 | if (new_size > ip->i_size) |
353 | io->io_new_size = new_size; | 348 | ip->i_new_size = new_size; |
354 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 349 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
355 | 350 | ||
356 | xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, | 351 | xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, ip, |
357 | pipe, count, *ppos, ioflags); | 352 | pipe, count, *ppos, ioflags); |
358 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | 353 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); |
359 | if (ret > 0) | 354 | if (ret > 0) |
@@ -370,9 +365,9 @@ xfs_splice_write( | |||
370 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 365 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
371 | } | 366 | } |
372 | 367 | ||
373 | if (io->io_new_size) { | 368 | if (ip->i_new_size) { |
374 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 369 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
375 | io->io_new_size = 0; | 370 | ip->i_new_size = 0; |
376 | if (ip->i_d.di_size > ip->i_size) | 371 | if (ip->i_d.di_size > ip->i_size) |
377 | ip->i_d.di_size = ip->i_size; | 372 | ip->i_d.di_size = ip->i_size; |
378 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 373 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
@@ -389,20 +384,19 @@ xfs_splice_write( | |||
389 | */ | 384 | */ |
390 | STATIC int /* error (positive) */ | 385 | STATIC int /* error (positive) */ |
391 | xfs_zero_last_block( | 386 | xfs_zero_last_block( |
392 | struct inode *ip, | 387 | xfs_inode_t *ip, |
393 | xfs_iocore_t *io, | ||
394 | xfs_fsize_t offset, | 388 | xfs_fsize_t offset, |
395 | xfs_fsize_t isize) | 389 | xfs_fsize_t isize) |
396 | { | 390 | { |
397 | xfs_fileoff_t last_fsb; | 391 | xfs_fileoff_t last_fsb; |
398 | xfs_mount_t *mp = io->io_mount; | 392 | xfs_mount_t *mp = ip->i_mount; |
399 | int nimaps; | 393 | int nimaps; |
400 | int zero_offset; | 394 | int zero_offset; |
401 | int zero_len; | 395 | int zero_len; |
402 | int error = 0; | 396 | int error = 0; |
403 | xfs_bmbt_irec_t imap; | 397 | xfs_bmbt_irec_t imap; |
404 | 398 | ||
405 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0); | 399 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); |
406 | 400 | ||
407 | zero_offset = XFS_B_FSB_OFFSET(mp, isize); | 401 | zero_offset = XFS_B_FSB_OFFSET(mp, isize); |
408 | if (zero_offset == 0) { | 402 | if (zero_offset == 0) { |
@@ -415,7 +409,7 @@ xfs_zero_last_block( | |||
415 | 409 | ||
416 | last_fsb = XFS_B_TO_FSBT(mp, isize); | 410 | last_fsb = XFS_B_TO_FSBT(mp, isize); |
417 | nimaps = 1; | 411 | nimaps = 1; |
418 | error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, | 412 | error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap, |
419 | &nimaps, NULL, NULL); | 413 | &nimaps, NULL, NULL); |
420 | if (error) { | 414 | if (error) { |
421 | return error; | 415 | return error; |
@@ -433,14 +427,14 @@ xfs_zero_last_block( | |||
433 | * out sync. We need to drop the ilock while we do this so we | 427 | * out sync. We need to drop the ilock while we do this so we |
434 | * don't deadlock when the buffer cache calls back to us. | 428 | * don't deadlock when the buffer cache calls back to us. |
435 | */ | 429 | */ |
436 | XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); | 430 | xfs_iunlock(ip, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); |
437 | 431 | ||
438 | zero_len = mp->m_sb.sb_blocksize - zero_offset; | 432 | zero_len = mp->m_sb.sb_blocksize - zero_offset; |
439 | if (isize + zero_len > offset) | 433 | if (isize + zero_len > offset) |
440 | zero_len = offset - isize; | 434 | zero_len = offset - isize; |
441 | error = xfs_iozero(ip, isize, zero_len); | 435 | error = xfs_iozero(ip, isize, zero_len); |
442 | 436 | ||
443 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 437 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); |
444 | ASSERT(error >= 0); | 438 | ASSERT(error >= 0); |
445 | return error; | 439 | return error; |
446 | } | 440 | } |
@@ -458,35 +452,33 @@ xfs_zero_last_block( | |||
458 | 452 | ||
459 | int /* error (positive) */ | 453 | int /* error (positive) */ |
460 | xfs_zero_eof( | 454 | xfs_zero_eof( |
461 | bhv_vnode_t *vp, | 455 | xfs_inode_t *ip, |
462 | xfs_iocore_t *io, | ||
463 | xfs_off_t offset, /* starting I/O offset */ | 456 | xfs_off_t offset, /* starting I/O offset */ |
464 | xfs_fsize_t isize) /* current inode size */ | 457 | xfs_fsize_t isize) /* current inode size */ |
465 | { | 458 | { |
466 | struct inode *ip = vn_to_inode(vp); | 459 | xfs_mount_t *mp = ip->i_mount; |
467 | xfs_fileoff_t start_zero_fsb; | 460 | xfs_fileoff_t start_zero_fsb; |
468 | xfs_fileoff_t end_zero_fsb; | 461 | xfs_fileoff_t end_zero_fsb; |
469 | xfs_fileoff_t zero_count_fsb; | 462 | xfs_fileoff_t zero_count_fsb; |
470 | xfs_fileoff_t last_fsb; | 463 | xfs_fileoff_t last_fsb; |
471 | xfs_fileoff_t zero_off; | 464 | xfs_fileoff_t zero_off; |
472 | xfs_fsize_t zero_len; | 465 | xfs_fsize_t zero_len; |
473 | xfs_mount_t *mp = io->io_mount; | ||
474 | int nimaps; | 466 | int nimaps; |
475 | int error = 0; | 467 | int error = 0; |
476 | xfs_bmbt_irec_t imap; | 468 | xfs_bmbt_irec_t imap; |
477 | 469 | ||
478 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); | 470 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); |
479 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); | 471 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); |
480 | ASSERT(offset > isize); | 472 | ASSERT(offset > isize); |
481 | 473 | ||
482 | /* | 474 | /* |
483 | * First handle zeroing the block on which isize resides. | 475 | * First handle zeroing the block on which isize resides. |
484 | * We only zero a part of that block so it is handled specially. | 476 | * We only zero a part of that block so it is handled specially. |
485 | */ | 477 | */ |
486 | error = xfs_zero_last_block(ip, io, offset, isize); | 478 | error = xfs_zero_last_block(ip, offset, isize); |
487 | if (error) { | 479 | if (error) { |
488 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); | 480 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); |
489 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); | 481 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); |
490 | return error; | 482 | return error; |
491 | } | 483 | } |
492 | 484 | ||
@@ -514,11 +506,11 @@ xfs_zero_eof( | |||
514 | while (start_zero_fsb <= end_zero_fsb) { | 506 | while (start_zero_fsb <= end_zero_fsb) { |
515 | nimaps = 1; | 507 | nimaps = 1; |
516 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; | 508 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; |
517 | error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, | 509 | error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb, |
518 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); | 510 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); |
519 | if (error) { | 511 | if (error) { |
520 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); | 512 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); |
521 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); | 513 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); |
522 | return error; | 514 | return error; |
523 | } | 515 | } |
524 | ASSERT(nimaps > 0); | 516 | ASSERT(nimaps > 0); |
@@ -542,7 +534,7 @@ xfs_zero_eof( | |||
542 | * Drop the inode lock while we're doing the I/O. | 534 | * Drop the inode lock while we're doing the I/O. |
543 | * We'll still have the iolock to protect us. | 535 | * We'll still have the iolock to protect us. |
544 | */ | 536 | */ |
545 | XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 537 | xfs_iunlock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); |
546 | 538 | ||
547 | zero_off = XFS_FSB_TO_B(mp, start_zero_fsb); | 539 | zero_off = XFS_FSB_TO_B(mp, start_zero_fsb); |
548 | zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount); | 540 | zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount); |
@@ -558,14 +550,13 @@ xfs_zero_eof( | |||
558 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; | 550 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; |
559 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); | 551 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); |
560 | 552 | ||
561 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 553 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); |
562 | } | 554 | } |
563 | 555 | ||
564 | return 0; | 556 | return 0; |
565 | 557 | ||
566 | out_lock: | 558 | out_lock: |
567 | 559 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | |
568 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | ||
569 | ASSERT(error >= 0); | 560 | ASSERT(error >= 0); |
570 | return error; | 561 | return error; |
571 | } | 562 | } |
@@ -587,7 +578,6 @@ xfs_write( | |||
587 | xfs_mount_t *mp; | 578 | xfs_mount_t *mp; |
588 | ssize_t ret = 0, error = 0; | 579 | ssize_t ret = 0, error = 0; |
589 | xfs_fsize_t isize, new_size; | 580 | xfs_fsize_t isize, new_size; |
590 | xfs_iocore_t *io; | ||
591 | int iolock; | 581 | int iolock; |
592 | int eventsent = 0; | 582 | int eventsent = 0; |
593 | bhv_vrwlock_t locktype; | 583 | bhv_vrwlock_t locktype; |
@@ -607,8 +597,7 @@ xfs_write( | |||
607 | if (count == 0) | 597 | if (count == 0) |
608 | return 0; | 598 | return 0; |
609 | 599 | ||
610 | io = &xip->i_iocore; | 600 | mp = xip->i_mount; |
611 | mp = io->io_mount; | ||
612 | 601 | ||
613 | xfs_wait_for_freeze(mp, SB_FREEZE_WRITE); | 602 | xfs_wait_for_freeze(mp, SB_FREEZE_WRITE); |
614 | 603 | ||
@@ -667,7 +656,7 @@ start: | |||
667 | 656 | ||
668 | if (ioflags & IO_ISDIRECT) { | 657 | if (ioflags & IO_ISDIRECT) { |
669 | xfs_buftarg_t *target = | 658 | xfs_buftarg_t *target = |
670 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 659 | XFS_IS_REALTIME_INODE(xip) ? |
671 | mp->m_rtdev_targp : mp->m_ddev_targp; | 660 | mp->m_rtdev_targp : mp->m_ddev_targp; |
672 | 661 | ||
673 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { | 662 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { |
@@ -688,7 +677,7 @@ start: | |||
688 | 677 | ||
689 | new_size = pos + count; | 678 | new_size = pos + count; |
690 | if (new_size > xip->i_size) | 679 | if (new_size > xip->i_size) |
691 | io->io_new_size = new_size; | 680 | xip->i_new_size = new_size; |
692 | 681 | ||
693 | if (likely(!(ioflags & IO_INVIS))) { | 682 | if (likely(!(ioflags & IO_INVIS))) { |
694 | file_update_time(file); | 683 | file_update_time(file); |
@@ -706,7 +695,7 @@ start: | |||
706 | */ | 695 | */ |
707 | 696 | ||
708 | if (pos > xip->i_size) { | 697 | if (pos > xip->i_size) { |
709 | error = xfs_zero_eof(vp, io, pos, xip->i_size); | 698 | error = xfs_zero_eof(xip, pos, xip->i_size); |
710 | if (error) { | 699 | if (error) { |
711 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 700 | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
712 | goto out_unlock_internal; | 701 | goto out_unlock_internal; |
@@ -740,10 +729,10 @@ retry: | |||
740 | if ((ioflags & IO_ISDIRECT)) { | 729 | if ((ioflags & IO_ISDIRECT)) { |
741 | if (VN_CACHED(vp)) { | 730 | if (VN_CACHED(vp)) { |
742 | WARN_ON(need_i_mutex == 0); | 731 | WARN_ON(need_i_mutex == 0); |
743 | xfs_inval_cached_trace(io, pos, -1, | 732 | xfs_inval_cached_trace(xip, pos, -1, |
744 | ctooff(offtoct(pos)), -1); | 733 | (pos & PAGE_CACHE_MASK), -1); |
745 | error = xfs_flushinval_pages(xip, | 734 | error = xfs_flushinval_pages(xip, |
746 | ctooff(offtoct(pos)), | 735 | (pos & PAGE_CACHE_MASK), |
747 | -1, FI_REMAPF_LOCKED); | 736 | -1, FI_REMAPF_LOCKED); |
748 | if (error) | 737 | if (error) |
749 | goto out_unlock_internal; | 738 | goto out_unlock_internal; |
@@ -751,7 +740,7 @@ retry: | |||
751 | 740 | ||
752 | if (need_i_mutex) { | 741 | if (need_i_mutex) { |
753 | /* demote the lock now the cached pages are gone */ | 742 | /* demote the lock now the cached pages are gone */ |
754 | XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL); | 743 | xfs_ilock_demote(xip, XFS_IOLOCK_EXCL); |
755 | mutex_unlock(&inode->i_mutex); | 744 | mutex_unlock(&inode->i_mutex); |
756 | 745 | ||
757 | iolock = XFS_IOLOCK_SHARED; | 746 | iolock = XFS_IOLOCK_SHARED; |
@@ -759,7 +748,7 @@ retry: | |||
759 | need_i_mutex = 0; | 748 | need_i_mutex = 0; |
760 | } | 749 | } |
761 | 750 | ||
762 | xfs_rw_enter_trace(XFS_DIOWR_ENTER, io, (void *)iovp, segs, | 751 | xfs_rw_enter_trace(XFS_DIOWR_ENTER, xip, (void *)iovp, segs, |
763 | *offset, ioflags); | 752 | *offset, ioflags); |
764 | ret = generic_file_direct_write(iocb, iovp, | 753 | ret = generic_file_direct_write(iocb, iovp, |
765 | &segs, pos, offset, count, ocount); | 754 | &segs, pos, offset, count, ocount); |
@@ -779,7 +768,7 @@ retry: | |||
779 | goto relock; | 768 | goto relock; |
780 | } | 769 | } |
781 | } else { | 770 | } else { |
782 | xfs_rw_enter_trace(XFS_WRITE_ENTER, io, (void *)iovp, segs, | 771 | xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs, |
783 | *offset, ioflags); | 772 | *offset, ioflags); |
784 | ret = generic_file_buffered_write(iocb, iovp, segs, | 773 | ret = generic_file_buffered_write(iocb, iovp, segs, |
785 | pos, offset, count, ret); | 774 | pos, offset, count, ret); |
@@ -843,9 +832,9 @@ retry: | |||
843 | } | 832 | } |
844 | 833 | ||
845 | out_unlock_internal: | 834 | out_unlock_internal: |
846 | if (io->io_new_size) { | 835 | if (xip->i_new_size) { |
847 | xfs_ilock(xip, XFS_ILOCK_EXCL); | 836 | xfs_ilock(xip, XFS_ILOCK_EXCL); |
848 | io->io_new_size = 0; | 837 | xip->i_new_size = 0; |
849 | /* | 838 | /* |
850 | * If this was a direct or synchronous I/O that failed (such | 839 | * If this was a direct or synchronous I/O that failed (such |
851 | * as ENOSPC) then part of the I/O may have been written to | 840 | * as ENOSPC) then part of the I/O may have been written to |
@@ -894,25 +883,6 @@ xfs_bdstrat_cb(struct xfs_buf *bp) | |||
894 | } | 883 | } |
895 | } | 884 | } |
896 | 885 | ||
897 | |||
898 | int | ||
899 | xfs_bmap( | ||
900 | xfs_inode_t *ip, | ||
901 | xfs_off_t offset, | ||
902 | ssize_t count, | ||
903 | int flags, | ||
904 | xfs_iomap_t *iomapp, | ||
905 | int *niomaps) | ||
906 | { | ||
907 | xfs_iocore_t *io = &ip->i_iocore; | ||
908 | |||
909 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | ||
910 | ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) == | ||
911 | ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0)); | ||
912 | |||
913 | return xfs_iomap(io, offset, count, flags, iomapp, niomaps); | ||
914 | } | ||
915 | |||
916 | /* | 886 | /* |
917 | * Wrapper around bdstrat so that we can stop data | 887 | * Wrapper around bdstrat so that we can stop data |
918 | * from going to disk in case we are shutting down the filesystem. | 888 | * from going to disk in case we are shutting down the filesystem. |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index 4b7747a828d9..e200253139cf 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #define __XFS_LRW_H__ | 19 | #define __XFS_LRW_H__ |
20 | 20 | ||
21 | struct xfs_mount; | 21 | struct xfs_mount; |
22 | struct xfs_iocore; | ||
23 | struct xfs_inode; | 22 | struct xfs_inode; |
24 | struct xfs_bmbt_irec; | 23 | struct xfs_bmbt_irec; |
25 | struct xfs_buf; | 24 | struct xfs_buf; |
@@ -60,20 +59,19 @@ struct xfs_iomap; | |||
60 | #define XFS_IOMAP_UNWRITTEN 27 | 59 | #define XFS_IOMAP_UNWRITTEN 27 |
61 | #define XFS_SPLICE_READ_ENTER 28 | 60 | #define XFS_SPLICE_READ_ENTER 28 |
62 | #define XFS_SPLICE_WRITE_ENTER 29 | 61 | #define XFS_SPLICE_WRITE_ENTER 29 |
63 | extern void xfs_rw_enter_trace(int, struct xfs_iocore *, | 62 | extern void xfs_rw_enter_trace(int, struct xfs_inode *, |
64 | void *, size_t, loff_t, int); | 63 | void *, size_t, loff_t, int); |
65 | extern void xfs_inval_cached_trace(struct xfs_iocore *, | 64 | extern void xfs_inval_cached_trace(struct xfs_inode *, |
66 | xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t); | 65 | xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t); |
67 | #else | 66 | #else |
68 | #define xfs_rw_enter_trace(tag, io, data, size, offset, ioflags) | 67 | #define xfs_rw_enter_trace(tag, ip, data, size, offset, ioflags) |
69 | #define xfs_inval_cached_trace(io, offset, len, first, last) | 68 | #define xfs_inval_cached_trace(ip, offset, len, first, last) |
70 | #endif | 69 | #endif |
71 | 70 | ||
72 | extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); | 71 | extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); |
73 | extern int xfs_bdstrat_cb(struct xfs_buf *); | 72 | extern int xfs_bdstrat_cb(struct xfs_buf *); |
74 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); | 73 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); |
75 | 74 | ||
76 | extern int xfs_zero_eof(struct inode *, struct xfs_iocore *, xfs_off_t, | 75 | extern int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); |
77 | xfs_fsize_t); | ||
78 | 76 | ||
79 | #endif /* __XFS_LRW_H__ */ | 77 | #endif /* __XFS_LRW_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 8cb63c60c048..21dfc9da235e 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "xfs_rtalloc.h" | 41 | #include "xfs_rtalloc.h" |
42 | #include "xfs_error.h" | 42 | #include "xfs_error.h" |
43 | #include "xfs_itable.h" | 43 | #include "xfs_itable.h" |
44 | #include "xfs_fsops.h" | ||
44 | #include "xfs_rw.h" | 45 | #include "xfs_rw.h" |
45 | #include "xfs_acl.h" | 46 | #include "xfs_acl.h" |
46 | #include "xfs_attr.h" | 47 | #include "xfs_attr.h" |
@@ -49,6 +50,8 @@ | |||
49 | #include "xfs_vnodeops.h" | 50 | #include "xfs_vnodeops.h" |
50 | #include "xfs_vfsops.h" | 51 | #include "xfs_vfsops.h" |
51 | #include "xfs_version.h" | 52 | #include "xfs_version.h" |
53 | #include "xfs_log_priv.h" | ||
54 | #include "xfs_trans_priv.h" | ||
52 | 55 | ||
53 | #include <linux/namei.h> | 56 | #include <linux/namei.h> |
54 | #include <linux/init.h> | 57 | #include <linux/init.h> |
@@ -87,6 +90,435 @@ xfs_args_allocate( | |||
87 | return args; | 90 | return args; |
88 | } | 91 | } |
89 | 92 | ||
93 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | ||
94 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | ||
95 | #define MNTOPT_LOGDEV "logdev" /* log device */ | ||
96 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ | ||
97 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ | ||
98 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ | ||
99 | #define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */ | ||
100 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ | ||
101 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ | ||
102 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ | ||
103 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | ||
104 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | ||
105 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | ||
106 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ | ||
107 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ | ||
108 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | ||
109 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | ||
110 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | ||
111 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | ||
112 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | ||
113 | * unwritten extent conversion */ | ||
114 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | ||
115 | #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ | ||
116 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | ||
117 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | ||
118 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | ||
119 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ | ||
120 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes | ||
121 | * in stat(). */ | ||
122 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | ||
123 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | ||
124 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | ||
125 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | ||
126 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | ||
127 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | ||
128 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | ||
129 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
130 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | ||
131 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | ||
132 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
133 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | ||
134 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | ||
135 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
136 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | ||
137 | #define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ | ||
138 | #define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ | ||
139 | #define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ | ||
140 | |||
141 | STATIC unsigned long | ||
142 | suffix_strtoul(char *s, char **endp, unsigned int base) | ||
143 | { | ||
144 | int last, shift_left_factor = 0; | ||
145 | char *value = s; | ||
146 | |||
147 | last = strlen(value) - 1; | ||
148 | if (value[last] == 'K' || value[last] == 'k') { | ||
149 | shift_left_factor = 10; | ||
150 | value[last] = '\0'; | ||
151 | } | ||
152 | if (value[last] == 'M' || value[last] == 'm') { | ||
153 | shift_left_factor = 20; | ||
154 | value[last] = '\0'; | ||
155 | } | ||
156 | if (value[last] == 'G' || value[last] == 'g') { | ||
157 | shift_left_factor = 30; | ||
158 | value[last] = '\0'; | ||
159 | } | ||
160 | |||
161 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; | ||
162 | } | ||
163 | |||
164 | STATIC int | ||
165 | xfs_parseargs( | ||
166 | struct xfs_mount *mp, | ||
167 | char *options, | ||
168 | struct xfs_mount_args *args, | ||
169 | int update) | ||
170 | { | ||
171 | char *this_char, *value, *eov; | ||
172 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | ||
173 | int iosize; | ||
174 | int ikeep = 0; | ||
175 | |||
176 | args->flags |= XFSMNT_BARRIER; | ||
177 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | ||
178 | |||
179 | if (!options) | ||
180 | goto done; | ||
181 | |||
182 | iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0; | ||
183 | |||
184 | while ((this_char = strsep(&options, ",")) != NULL) { | ||
185 | if (!*this_char) | ||
186 | continue; | ||
187 | if ((value = strchr(this_char, '=')) != NULL) | ||
188 | *value++ = 0; | ||
189 | |||
190 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | ||
191 | if (!value || !*value) { | ||
192 | cmn_err(CE_WARN, | ||
193 | "XFS: %s option requires an argument", | ||
194 | this_char); | ||
195 | return EINVAL; | ||
196 | } | ||
197 | args->logbufs = simple_strtoul(value, &eov, 10); | ||
198 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | ||
199 | if (!value || !*value) { | ||
200 | cmn_err(CE_WARN, | ||
201 | "XFS: %s option requires an argument", | ||
202 | this_char); | ||
203 | return EINVAL; | ||
204 | } | ||
205 | args->logbufsize = suffix_strtoul(value, &eov, 10); | ||
206 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | ||
207 | if (!value || !*value) { | ||
208 | cmn_err(CE_WARN, | ||
209 | "XFS: %s option requires an argument", | ||
210 | this_char); | ||
211 | return EINVAL; | ||
212 | } | ||
213 | strncpy(args->logname, value, MAXNAMELEN); | ||
214 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | ||
215 | if (!value || !*value) { | ||
216 | cmn_err(CE_WARN, | ||
217 | "XFS: %s option requires an argument", | ||
218 | this_char); | ||
219 | return EINVAL; | ||
220 | } | ||
221 | strncpy(args->mtpt, value, MAXNAMELEN); | ||
222 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | ||
223 | if (!value || !*value) { | ||
224 | cmn_err(CE_WARN, | ||
225 | "XFS: %s option requires an argument", | ||
226 | this_char); | ||
227 | return EINVAL; | ||
228 | } | ||
229 | strncpy(args->rtname, value, MAXNAMELEN); | ||
230 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | ||
231 | if (!value || !*value) { | ||
232 | cmn_err(CE_WARN, | ||
233 | "XFS: %s option requires an argument", | ||
234 | this_char); | ||
235 | return EINVAL; | ||
236 | } | ||
237 | iosize = simple_strtoul(value, &eov, 10); | ||
238 | args->flags |= XFSMNT_IOSIZE; | ||
239 | args->iosizelog = (uint8_t) iosize; | ||
240 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | ||
241 | if (!value || !*value) { | ||
242 | cmn_err(CE_WARN, | ||
243 | "XFS: %s option requires an argument", | ||
244 | this_char); | ||
245 | return EINVAL; | ||
246 | } | ||
247 | iosize = suffix_strtoul(value, &eov, 10); | ||
248 | args->flags |= XFSMNT_IOSIZE; | ||
249 | args->iosizelog = ffs(iosize) - 1; | ||
250 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | ||
251 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | ||
252 | mp->m_flags |= XFS_MOUNT_GRPID; | ||
253 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | ||
254 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | ||
255 | mp->m_flags &= ~XFS_MOUNT_GRPID; | ||
256 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | ||
257 | args->flags |= XFSMNT_WSYNC; | ||
258 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { | ||
259 | args->flags |= XFSMNT_OSYNCISOSYNC; | ||
260 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | ||
261 | args->flags |= XFSMNT_NORECOVERY; | ||
262 | } else if (!strcmp(this_char, MNTOPT_INO64)) { | ||
263 | args->flags |= XFSMNT_INO64; | ||
264 | #if !XFS_BIG_INUMS | ||
265 | cmn_err(CE_WARN, | ||
266 | "XFS: %s option not allowed on this system", | ||
267 | this_char); | ||
268 | return EINVAL; | ||
269 | #endif | ||
270 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | ||
271 | args->flags |= XFSMNT_NOALIGN; | ||
272 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | ||
273 | args->flags |= XFSMNT_SWALLOC; | ||
274 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | ||
275 | if (!value || !*value) { | ||
276 | cmn_err(CE_WARN, | ||
277 | "XFS: %s option requires an argument", | ||
278 | this_char); | ||
279 | return EINVAL; | ||
280 | } | ||
281 | dsunit = simple_strtoul(value, &eov, 10); | ||
282 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | ||
283 | if (!value || !*value) { | ||
284 | cmn_err(CE_WARN, | ||
285 | "XFS: %s option requires an argument", | ||
286 | this_char); | ||
287 | return EINVAL; | ||
288 | } | ||
289 | dswidth = simple_strtoul(value, &eov, 10); | ||
290 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | ||
291 | args->flags &= ~XFSMNT_32BITINODES; | ||
292 | #if !XFS_BIG_INUMS | ||
293 | cmn_err(CE_WARN, | ||
294 | "XFS: %s option not allowed on this system", | ||
295 | this_char); | ||
296 | return EINVAL; | ||
297 | #endif | ||
298 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | ||
299 | args->flags |= XFSMNT_NOUUID; | ||
300 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | ||
301 | args->flags |= XFSMNT_BARRIER; | ||
302 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | ||
303 | args->flags &= ~XFSMNT_BARRIER; | ||
304 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | ||
305 | ikeep = 1; | ||
306 | args->flags &= ~XFSMNT_IDELETE; | ||
307 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | ||
308 | args->flags |= XFSMNT_IDELETE; | ||
309 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | ||
310 | args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; | ||
311 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | ||
312 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | ||
313 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | ||
314 | args->flags |= XFSMNT_ATTR2; | ||
315 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | ||
316 | args->flags &= ~XFSMNT_ATTR2; | ||
317 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | ||
318 | args->flags2 |= XFSMNT2_FILESTREAMS; | ||
319 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | ||
320 | args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); | ||
321 | args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); | ||
322 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | ||
323 | !strcmp(this_char, MNTOPT_UQUOTA) || | ||
324 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | ||
325 | args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; | ||
326 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | ||
327 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | ||
328 | args->flags |= XFSMNT_UQUOTA; | ||
329 | args->flags &= ~XFSMNT_UQUOTAENF; | ||
330 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
331 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
332 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
333 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
334 | args->flags |= XFSMNT_PQUOTA; | ||
335 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
336 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | ||
337 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | ||
338 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | ||
339 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | ||
340 | args->flags |= XFSMNT_GQUOTA; | ||
341 | args->flags &= ~XFSMNT_GQUOTAENF; | ||
342 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { | ||
343 | args->flags |= XFSMNT_DMAPI; | ||
344 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { | ||
345 | args->flags |= XFSMNT_DMAPI; | ||
346 | } else if (!strcmp(this_char, MNTOPT_DMI)) { | ||
347 | args->flags |= XFSMNT_DMAPI; | ||
348 | } else if (!strcmp(this_char, "ihashsize")) { | ||
349 | cmn_err(CE_WARN, | ||
350 | "XFS: ihashsize no longer used, option is deprecated."); | ||
351 | } else if (!strcmp(this_char, "osyncisdsync")) { | ||
352 | /* no-op, this is now the default */ | ||
353 | cmn_err(CE_WARN, | ||
354 | "XFS: osyncisdsync is now the default, option is deprecated."); | ||
355 | } else if (!strcmp(this_char, "irixsgid")) { | ||
356 | cmn_err(CE_WARN, | ||
357 | "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); | ||
358 | } else { | ||
359 | cmn_err(CE_WARN, | ||
360 | "XFS: unknown mount option [%s].", this_char); | ||
361 | return EINVAL; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | if (args->flags & XFSMNT_NORECOVERY) { | ||
366 | if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) { | ||
367 | cmn_err(CE_WARN, | ||
368 | "XFS: no-recovery mounts must be read-only."); | ||
369 | return EINVAL; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { | ||
374 | cmn_err(CE_WARN, | ||
375 | "XFS: sunit and swidth options incompatible with the noalign option"); | ||
376 | return EINVAL; | ||
377 | } | ||
378 | |||
379 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
380 | cmn_err(CE_WARN, | ||
381 | "XFS: cannot mount with both project and group quota"); | ||
382 | return EINVAL; | ||
383 | } | ||
384 | |||
385 | if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { | ||
386 | printk("XFS: %s option needs the mount point option as well\n", | ||
387 | MNTOPT_DMAPI); | ||
388 | return EINVAL; | ||
389 | } | ||
390 | |||
391 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | ||
392 | cmn_err(CE_WARN, | ||
393 | "XFS: sunit and swidth must be specified together"); | ||
394 | return EINVAL; | ||
395 | } | ||
396 | |||
397 | if (dsunit && (dswidth % dsunit != 0)) { | ||
398 | cmn_err(CE_WARN, | ||
399 | "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)", | ||
400 | dswidth, dsunit); | ||
401 | return EINVAL; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * Applications using DMI filesystems often expect the | ||
406 | * inode generation number to be monotonically increasing. | ||
407 | * If we delete inode chunks we break this assumption, so | ||
408 | * keep unused inode chunks on disk for DMI filesystems | ||
409 | * until we come up with a better solution. | ||
410 | * Note that if "ikeep" or "noikeep" mount options are | ||
411 | * supplied, then they are honored. | ||
412 | */ | ||
413 | if (!(args->flags & XFSMNT_DMAPI) && !ikeep) | ||
414 | args->flags |= XFSMNT_IDELETE; | ||
415 | |||
416 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
417 | if (dsunit) { | ||
418 | args->sunit = dsunit; | ||
419 | args->flags |= XFSMNT_RETERR; | ||
420 | } else { | ||
421 | args->sunit = vol_dsunit; | ||
422 | } | ||
423 | dswidth ? (args->swidth = dswidth) : | ||
424 | (args->swidth = vol_dswidth); | ||
425 | } else { | ||
426 | args->sunit = args->swidth = 0; | ||
427 | } | ||
428 | |||
429 | done: | ||
430 | if (args->flags & XFSMNT_32BITINODES) | ||
431 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | ||
432 | if (args->flags2) | ||
433 | args->flags |= XFSMNT_FLAGS2; | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | struct proc_xfs_info { | ||
438 | int flag; | ||
439 | char *str; | ||
440 | }; | ||
441 | |||
442 | STATIC int | ||
443 | xfs_showargs( | ||
444 | struct xfs_mount *mp, | ||
445 | struct seq_file *m) | ||
446 | { | ||
447 | static struct proc_xfs_info xfs_info_set[] = { | ||
448 | /* the few simple ones we can get from the mount struct */ | ||
449 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | ||
450 | { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, | ||
451 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | ||
452 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | ||
453 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | ||
454 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | ||
455 | { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC }, | ||
456 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | ||
457 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | ||
458 | { XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI }, | ||
459 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | ||
460 | { 0, NULL } | ||
461 | }; | ||
462 | static struct proc_xfs_info xfs_info_unset[] = { | ||
463 | /* the few simple ones we can get from the mount struct */ | ||
464 | { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, | ||
465 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, | ||
466 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, | ||
467 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, | ||
468 | { 0, NULL } | ||
469 | }; | ||
470 | struct proc_xfs_info *xfs_infop; | ||
471 | |||
472 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { | ||
473 | if (mp->m_flags & xfs_infop->flag) | ||
474 | seq_puts(m, xfs_infop->str); | ||
475 | } | ||
476 | for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { | ||
477 | if (!(mp->m_flags & xfs_infop->flag)) | ||
478 | seq_puts(m, xfs_infop->str); | ||
479 | } | ||
480 | |||
481 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | ||
482 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | ||
483 | (int)(1 << mp->m_writeio_log) >> 10); | ||
484 | |||
485 | if (mp->m_logbufs > 0) | ||
486 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | ||
487 | if (mp->m_logbsize > 0) | ||
488 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); | ||
489 | |||
490 | if (mp->m_logname) | ||
491 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); | ||
492 | if (mp->m_rtname) | ||
493 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); | ||
494 | |||
495 | if (mp->m_dalign > 0) | ||
496 | seq_printf(m, "," MNTOPT_SUNIT "=%d", | ||
497 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); | ||
498 | if (mp->m_swidth > 0) | ||
499 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", | ||
500 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); | ||
501 | |||
502 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) | ||
503 | seq_puts(m, "," MNTOPT_USRQUOTA); | ||
504 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) | ||
505 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | ||
506 | |||
507 | if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) | ||
508 | seq_puts(m, "," MNTOPT_PRJQUOTA); | ||
509 | else if (mp->m_qflags & XFS_PQUOTA_ACCT) | ||
510 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
511 | |||
512 | if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD)) | ||
513 | seq_puts(m, "," MNTOPT_GRPQUOTA); | ||
514 | else if (mp->m_qflags & XFS_GQUOTA_ACCT) | ||
515 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | ||
516 | |||
517 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | ||
518 | seq_puts(m, "," MNTOPT_NOQUOTA); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
90 | __uint64_t | 522 | __uint64_t |
91 | xfs_max_file_offset( | 523 | xfs_max_file_offset( |
92 | unsigned int blockshift) | 524 | unsigned int blockshift) |
@@ -137,7 +569,7 @@ xfs_set_inodeops( | |||
137 | break; | 569 | break; |
138 | case S_IFLNK: | 570 | case S_IFLNK: |
139 | inode->i_op = &xfs_symlink_inode_operations; | 571 | inode->i_op = &xfs_symlink_inode_operations; |
140 | if (inode->i_blocks) | 572 | if (!(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE)) |
141 | inode->i_mapping->a_ops = &xfs_address_space_operations; | 573 | inode->i_mapping->a_ops = &xfs_address_space_operations; |
142 | break; | 574 | break; |
143 | default: | 575 | default: |
@@ -174,8 +606,6 @@ xfs_revalidate_inode( | |||
174 | 606 | ||
175 | inode->i_generation = ip->i_d.di_gen; | 607 | inode->i_generation = ip->i_d.di_gen; |
176 | i_size_write(inode, ip->i_d.di_size); | 608 | i_size_write(inode, ip->i_d.di_size); |
177 | inode->i_blocks = | ||
178 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
179 | inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; | 609 | inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; |
180 | inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; | 610 | inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; |
181 | inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; | 611 | inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; |
@@ -334,6 +764,64 @@ xfs_blkdev_issue_flush( | |||
334 | blkdev_issue_flush(buftarg->bt_bdev, NULL); | 764 | blkdev_issue_flush(buftarg->bt_bdev, NULL); |
335 | } | 765 | } |
336 | 766 | ||
767 | /* | ||
768 | * XFS AIL push thread support | ||
769 | */ | ||
770 | void | ||
771 | xfsaild_wakeup( | ||
772 | xfs_mount_t *mp, | ||
773 | xfs_lsn_t threshold_lsn) | ||
774 | { | ||
775 | mp->m_ail.xa_target = threshold_lsn; | ||
776 | wake_up_process(mp->m_ail.xa_task); | ||
777 | } | ||
778 | |||
779 | int | ||
780 | xfsaild( | ||
781 | void *data) | ||
782 | { | ||
783 | xfs_mount_t *mp = (xfs_mount_t *)data; | ||
784 | xfs_lsn_t last_pushed_lsn = 0; | ||
785 | long tout = 0; | ||
786 | |||
787 | while (!kthread_should_stop()) { | ||
788 | if (tout) | ||
789 | schedule_timeout_interruptible(msecs_to_jiffies(tout)); | ||
790 | tout = 1000; | ||
791 | |||
792 | /* swsusp */ | ||
793 | try_to_freeze(); | ||
794 | |||
795 | ASSERT(mp->m_log); | ||
796 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
797 | continue; | ||
798 | |||
799 | tout = xfsaild_push(mp, &last_pushed_lsn); | ||
800 | } | ||
801 | |||
802 | return 0; | ||
803 | } /* xfsaild */ | ||
804 | |||
805 | int | ||
806 | xfsaild_start( | ||
807 | xfs_mount_t *mp) | ||
808 | { | ||
809 | mp->m_ail.xa_target = 0; | ||
810 | mp->m_ail.xa_task = kthread_run(xfsaild, mp, "xfsaild"); | ||
811 | if (IS_ERR(mp->m_ail.xa_task)) | ||
812 | return -PTR_ERR(mp->m_ail.xa_task); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | void | ||
817 | xfsaild_stop( | ||
818 | xfs_mount_t *mp) | ||
819 | { | ||
820 | kthread_stop(mp->m_ail.xa_task); | ||
821 | } | ||
822 | |||
823 | |||
824 | |||
337 | STATIC struct inode * | 825 | STATIC struct inode * |
338 | xfs_fs_alloc_inode( | 826 | xfs_fs_alloc_inode( |
339 | struct super_block *sb) | 827 | struct super_block *sb) |
@@ -361,7 +849,7 @@ xfs_fs_inode_init_once( | |||
361 | inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); | 849 | inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); |
362 | } | 850 | } |
363 | 851 | ||
364 | STATIC int | 852 | STATIC int __init |
365 | xfs_init_zones(void) | 853 | xfs_init_zones(void) |
366 | { | 854 | { |
367 | xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode", | 855 | xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode", |
@@ -410,8 +898,7 @@ xfs_fs_write_inode( | |||
410 | { | 898 | { |
411 | int error = 0, flags = FLUSH_INODE; | 899 | int error = 0, flags = FLUSH_INODE; |
412 | 900 | ||
413 | vn_trace_entry(XFS_I(inode), __FUNCTION__, | 901 | xfs_itrace_entry(XFS_I(inode)); |
414 | (inst_t *)__return_address); | ||
415 | if (sync) { | 902 | if (sync) { |
416 | filemap_fdatawait(inode->i_mapping); | 903 | filemap_fdatawait(inode->i_mapping); |
417 | flags |= FLUSH_SYNC; | 904 | flags |= FLUSH_SYNC; |
@@ -438,8 +925,7 @@ xfs_fs_clear_inode( | |||
438 | * find an inode with di_mode == 0 but without IGET_CREATE set. | 925 | * find an inode with di_mode == 0 but without IGET_CREATE set. |
439 | */ | 926 | */ |
440 | if (ip) { | 927 | if (ip) { |
441 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 928 | xfs_itrace_entry(ip); |
442 | |||
443 | XFS_STATS_INC(vn_rele); | 929 | XFS_STATS_INC(vn_rele); |
444 | XFS_STATS_INC(vn_remove); | 930 | XFS_STATS_INC(vn_remove); |
445 | XFS_STATS_INC(vn_reclaim); | 931 | XFS_STATS_INC(vn_reclaim); |
@@ -683,8 +1169,44 @@ xfs_fs_statfs( | |||
683 | struct dentry *dentry, | 1169 | struct dentry *dentry, |
684 | struct kstatfs *statp) | 1170 | struct kstatfs *statp) |
685 | { | 1171 | { |
686 | return -xfs_statvfs(XFS_M(dentry->d_sb), statp, | 1172 | struct xfs_mount *mp = XFS_M(dentry->d_sb); |
687 | vn_from_inode(dentry->d_inode)); | 1173 | xfs_sb_t *sbp = &mp->m_sb; |
1174 | __uint64_t fakeinos, id; | ||
1175 | xfs_extlen_t lsize; | ||
1176 | |||
1177 | statp->f_type = XFS_SB_MAGIC; | ||
1178 | statp->f_namelen = MAXNAMELEN - 1; | ||
1179 | |||
1180 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); | ||
1181 | statp->f_fsid.val[0] = (u32)id; | ||
1182 | statp->f_fsid.val[1] = (u32)(id >> 32); | ||
1183 | |||
1184 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); | ||
1185 | |||
1186 | spin_lock(&mp->m_sb_lock); | ||
1187 | statp->f_bsize = sbp->sb_blocksize; | ||
1188 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | ||
1189 | statp->f_blocks = sbp->sb_dblocks - lsize; | ||
1190 | statp->f_bfree = statp->f_bavail = | ||
1191 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | ||
1192 | fakeinos = statp->f_bfree << sbp->sb_inopblog; | ||
1193 | #if XFS_BIG_INUMS | ||
1194 | fakeinos += mp->m_inoadd; | ||
1195 | #endif | ||
1196 | statp->f_files = | ||
1197 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); | ||
1198 | if (mp->m_maxicount) | ||
1199 | #if XFS_BIG_INUMS | ||
1200 | if (!mp->m_inoadd) | ||
1201 | #endif | ||
1202 | statp->f_files = min_t(typeof(statp->f_files), | ||
1203 | statp->f_files, | ||
1204 | mp->m_maxicount); | ||
1205 | statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | ||
1206 | spin_unlock(&mp->m_sb_lock); | ||
1207 | |||
1208 | XFS_QM_DQSTATVFS(XFS_I(dentry->d_inode), statp); | ||
1209 | return 0; | ||
688 | } | 1210 | } |
689 | 1211 | ||
690 | STATIC int | 1212 | STATIC int |
@@ -704,11 +1226,19 @@ xfs_fs_remount( | |||
704 | return -error; | 1226 | return -error; |
705 | } | 1227 | } |
706 | 1228 | ||
1229 | /* | ||
1230 | * Second stage of a freeze. The data is already frozen so we only | ||
1231 | * need to take care of themetadata. Once that's done write a dummy | ||
1232 | * record to dirty the log in case of a crash while frozen. | ||
1233 | */ | ||
707 | STATIC void | 1234 | STATIC void |
708 | xfs_fs_lockfs( | 1235 | xfs_fs_lockfs( |
709 | struct super_block *sb) | 1236 | struct super_block *sb) |
710 | { | 1237 | { |
711 | xfs_freeze(XFS_M(sb)); | 1238 | struct xfs_mount *mp = XFS_M(sb); |
1239 | |||
1240 | xfs_attr_quiesce(mp); | ||
1241 | xfs_fs_log_dummy(mp); | ||
712 | } | 1242 | } |
713 | 1243 | ||
714 | STATIC int | 1244 | STATIC int |
@@ -779,7 +1309,6 @@ xfs_fs_fill_super( | |||
779 | struct inode *rootvp; | 1309 | struct inode *rootvp; |
780 | struct xfs_mount *mp = NULL; | 1310 | struct xfs_mount *mp = NULL; |
781 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); | 1311 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); |
782 | struct kstatfs statvfs; | ||
783 | int error; | 1312 | int error; |
784 | 1313 | ||
785 | mp = xfs_mount_init(); | 1314 | mp = xfs_mount_init(); |
@@ -807,21 +1336,19 @@ xfs_fs_fill_super( | |||
807 | if (error) | 1336 | if (error) |
808 | goto fail_vfsop; | 1337 | goto fail_vfsop; |
809 | 1338 | ||
810 | error = xfs_statvfs(mp, &statvfs, NULL); | ||
811 | if (error) | ||
812 | goto fail_unmount; | ||
813 | |||
814 | sb->s_dirt = 1; | 1339 | sb->s_dirt = 1; |
815 | sb->s_magic = statvfs.f_type; | 1340 | sb->s_magic = XFS_SB_MAGIC; |
816 | sb->s_blocksize = statvfs.f_bsize; | 1341 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
817 | sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1; | 1342 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
818 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); | 1343 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); |
819 | sb->s_time_gran = 1; | 1344 | sb->s_time_gran = 1; |
820 | set_posix_acl_flag(sb); | 1345 | set_posix_acl_flag(sb); |
821 | 1346 | ||
822 | error = xfs_root(mp, &rootvp); | 1347 | rootvp = igrab(mp->m_rootip->i_vnode); |
823 | if (error) | 1348 | if (!rootvp) { |
1349 | error = ENOENT; | ||
824 | goto fail_unmount; | 1350 | goto fail_unmount; |
1351 | } | ||
825 | 1352 | ||
826 | sb->s_root = d_alloc_root(vn_to_inode(rootvp)); | 1353 | sb->s_root = d_alloc_root(vn_to_inode(rootvp)); |
827 | if (!sb->s_root) { | 1354 | if (!sb->s_root) { |
@@ -841,8 +1368,7 @@ xfs_fs_fill_super( | |||
841 | goto fail_vnrele; | 1368 | goto fail_vnrele; |
842 | } | 1369 | } |
843 | 1370 | ||
844 | vn_trace_exit(XFS_I(sb->s_root->d_inode), __FUNCTION__, | 1371 | xfs_itrace_exit(XFS_I(sb->s_root->d_inode)); |
845 | (inst_t *)__return_address); | ||
846 | 1372 | ||
847 | kmem_free(args, sizeof(*args)); | 1373 | kmem_free(args, sizeof(*args)); |
848 | return 0; | 1374 | return 0; |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 814169fd7e1e..bc7afe007338 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define vptosync(v) (&vsync[((unsigned long)v) % NVSYNC]) | 40 | #define vptosync(v) (&vsync[((unsigned long)v) % NVSYNC]) |
41 | static wait_queue_head_t vsync[NVSYNC]; | 41 | static wait_queue_head_t vsync[NVSYNC]; |
42 | 42 | ||
43 | void | 43 | void __init |
44 | vn_init(void) | 44 | vn_init(void) |
45 | { | 45 | { |
46 | int i; | 46 | int i; |
@@ -82,84 +82,55 @@ vn_ioerror( | |||
82 | xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l); | 82 | xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l); |
83 | } | 83 | } |
84 | 84 | ||
85 | bhv_vnode_t * | ||
86 | vn_initialize( | ||
87 | struct inode *inode) | ||
88 | { | ||
89 | bhv_vnode_t *vp = vn_from_inode(inode); | ||
90 | |||
91 | XFS_STATS_INC(vn_active); | ||
92 | XFS_STATS_INC(vn_alloc); | ||
93 | |||
94 | ASSERT(VN_CACHED(vp) == 0); | ||
95 | |||
96 | return vp; | ||
97 | } | ||
98 | |||
99 | /* | 85 | /* |
100 | * Revalidate the Linux inode from the vattr. | 86 | * Revalidate the Linux inode from the XFS inode. |
101 | * Note: i_size _not_ updated; we must hold the inode | 87 | * Note: i_size _not_ updated; we must hold the inode |
102 | * semaphore when doing that - callers responsibility. | 88 | * semaphore when doing that - callers responsibility. |
103 | */ | 89 | */ |
104 | void | 90 | int |
105 | vn_revalidate_core( | 91 | vn_revalidate( |
106 | bhv_vnode_t *vp, | 92 | bhv_vnode_t *vp) |
107 | bhv_vattr_t *vap) | ||
108 | { | 93 | { |
109 | struct inode *inode = vn_to_inode(vp); | 94 | struct inode *inode = vn_to_inode(vp); |
110 | 95 | struct xfs_inode *ip = XFS_I(inode); | |
111 | inode->i_mode = vap->va_mode; | 96 | struct xfs_mount *mp = ip->i_mount; |
112 | inode->i_nlink = vap->va_nlink; | 97 | unsigned long xflags; |
113 | inode->i_uid = vap->va_uid; | 98 | |
114 | inode->i_gid = vap->va_gid; | 99 | xfs_itrace_entry(ip); |
115 | inode->i_blocks = vap->va_nblocks; | 100 | |
116 | inode->i_mtime = vap->va_mtime; | 101 | if (XFS_FORCED_SHUTDOWN(mp)) |
117 | inode->i_ctime = vap->va_ctime; | 102 | return -EIO; |
118 | if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) | 103 | |
104 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
105 | inode->i_mode = ip->i_d.di_mode; | ||
106 | inode->i_uid = ip->i_d.di_uid; | ||
107 | inode->i_gid = ip->i_d.di_gid; | ||
108 | inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; | ||
109 | inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | ||
110 | inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec; | ||
111 | inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; | ||
112 | |||
113 | xflags = xfs_ip2xflags(ip); | ||
114 | if (xflags & XFS_XFLAG_IMMUTABLE) | ||
119 | inode->i_flags |= S_IMMUTABLE; | 115 | inode->i_flags |= S_IMMUTABLE; |
120 | else | 116 | else |
121 | inode->i_flags &= ~S_IMMUTABLE; | 117 | inode->i_flags &= ~S_IMMUTABLE; |
122 | if (vap->va_xflags & XFS_XFLAG_APPEND) | 118 | if (xflags & XFS_XFLAG_APPEND) |
123 | inode->i_flags |= S_APPEND; | 119 | inode->i_flags |= S_APPEND; |
124 | else | 120 | else |
125 | inode->i_flags &= ~S_APPEND; | 121 | inode->i_flags &= ~S_APPEND; |
126 | if (vap->va_xflags & XFS_XFLAG_SYNC) | 122 | if (xflags & XFS_XFLAG_SYNC) |
127 | inode->i_flags |= S_SYNC; | 123 | inode->i_flags |= S_SYNC; |
128 | else | 124 | else |
129 | inode->i_flags &= ~S_SYNC; | 125 | inode->i_flags &= ~S_SYNC; |
130 | if (vap->va_xflags & XFS_XFLAG_NOATIME) | 126 | if (xflags & XFS_XFLAG_NOATIME) |
131 | inode->i_flags |= S_NOATIME; | 127 | inode->i_flags |= S_NOATIME; |
132 | else | 128 | else |
133 | inode->i_flags &= ~S_NOATIME; | 129 | inode->i_flags &= ~S_NOATIME; |
134 | } | 130 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
135 | |||
136 | /* | ||
137 | * Revalidate the Linux inode from the vnode. | ||
138 | */ | ||
139 | int | ||
140 | __vn_revalidate( | ||
141 | bhv_vnode_t *vp, | ||
142 | bhv_vattr_t *vattr) | ||
143 | { | ||
144 | int error; | ||
145 | |||
146 | vn_trace_entry(xfs_vtoi(vp), __FUNCTION__, (inst_t *)__return_address); | ||
147 | vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; | ||
148 | error = xfs_getattr(xfs_vtoi(vp), vattr, 0); | ||
149 | if (likely(!error)) { | ||
150 | vn_revalidate_core(vp, vattr); | ||
151 | xfs_iflags_clear(xfs_vtoi(vp), XFS_IMODIFIED); | ||
152 | } | ||
153 | return -error; | ||
154 | } | ||
155 | |||
156 | int | ||
157 | vn_revalidate( | ||
158 | bhv_vnode_t *vp) | ||
159 | { | ||
160 | bhv_vattr_t vattr; | ||
161 | 131 | ||
162 | return __vn_revalidate(vp, &vattr); | 132 | xfs_iflags_clear(ip, XFS_IMODIFIED); |
133 | return 0; | ||
163 | } | 134 | } |
164 | 135 | ||
165 | /* | 136 | /* |
@@ -179,7 +150,7 @@ vn_hold( | |||
179 | return vp; | 150 | return vp; |
180 | } | 151 | } |
181 | 152 | ||
182 | #ifdef XFS_VNODE_TRACE | 153 | #ifdef XFS_INODE_TRACE |
183 | 154 | ||
184 | /* | 155 | /* |
185 | * Reference count of Linux inode if present, -1 if the xfs_inode | 156 | * Reference count of Linux inode if present, -1 if the xfs_inode |
@@ -211,32 +182,32 @@ static inline int xfs_icount(struct xfs_inode *ip) | |||
211 | * Vnode tracing code. | 182 | * Vnode tracing code. |
212 | */ | 183 | */ |
213 | void | 184 | void |
214 | vn_trace_entry(xfs_inode_t *ip, const char *func, inst_t *ra) | 185 | _xfs_itrace_entry(xfs_inode_t *ip, const char *func, inst_t *ra) |
215 | { | 186 | { |
216 | KTRACE_ENTER(ip, VNODE_KTRACE_ENTRY, func, 0, ra); | 187 | KTRACE_ENTER(ip, INODE_KTRACE_ENTRY, func, 0, ra); |
217 | } | 188 | } |
218 | 189 | ||
219 | void | 190 | void |
220 | vn_trace_exit(xfs_inode_t *ip, const char *func, inst_t *ra) | 191 | _xfs_itrace_exit(xfs_inode_t *ip, const char *func, inst_t *ra) |
221 | { | 192 | { |
222 | KTRACE_ENTER(ip, VNODE_KTRACE_EXIT, func, 0, ra); | 193 | KTRACE_ENTER(ip, INODE_KTRACE_EXIT, func, 0, ra); |
223 | } | 194 | } |
224 | 195 | ||
225 | void | 196 | void |
226 | vn_trace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra) | 197 | xfs_itrace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra) |
227 | { | 198 | { |
228 | KTRACE_ENTER(ip, VNODE_KTRACE_HOLD, file, line, ra); | 199 | KTRACE_ENTER(ip, INODE_KTRACE_HOLD, file, line, ra); |
229 | } | 200 | } |
230 | 201 | ||
231 | void | 202 | void |
232 | vn_trace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra) | 203 | _xfs_itrace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra) |
233 | { | 204 | { |
234 | KTRACE_ENTER(ip, VNODE_KTRACE_REF, file, line, ra); | 205 | KTRACE_ENTER(ip, INODE_KTRACE_REF, file, line, ra); |
235 | } | 206 | } |
236 | 207 | ||
237 | void | 208 | void |
238 | vn_trace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra) | 209 | xfs_itrace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra) |
239 | { | 210 | { |
240 | KTRACE_ENTER(ip, VNODE_KTRACE_RELE, file, line, ra); | 211 | KTRACE_ENTER(ip, INODE_KTRACE_RELE, file, line, ra); |
241 | } | 212 | } |
242 | #endif /* XFS_VNODE_TRACE */ | 213 | #endif /* XFS_INODE_TRACE */ |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 55fb46948589..b5ea418693b1 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -187,10 +187,7 @@ typedef struct bhv_vattr { | |||
187 | (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) | 187 | (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) |
188 | 188 | ||
189 | extern void vn_init(void); | 189 | extern void vn_init(void); |
190 | extern bhv_vnode_t *vn_initialize(struct inode *); | ||
191 | extern int vn_revalidate(bhv_vnode_t *); | 190 | extern int vn_revalidate(bhv_vnode_t *); |
192 | extern int __vn_revalidate(bhv_vnode_t *, bhv_vattr_t *); | ||
193 | extern void vn_revalidate_core(bhv_vnode_t *, bhv_vattr_t *); | ||
194 | 191 | ||
195 | /* | 192 | /* |
196 | * Yeah, these don't take vnode anymore at all, all this should be | 193 | * Yeah, these don't take vnode anymore at all, all this should be |
@@ -210,12 +207,12 @@ static inline int vn_count(bhv_vnode_t *vp) | |||
210 | */ | 207 | */ |
211 | extern bhv_vnode_t *vn_hold(bhv_vnode_t *); | 208 | extern bhv_vnode_t *vn_hold(bhv_vnode_t *); |
212 | 209 | ||
213 | #if defined(XFS_VNODE_TRACE) | 210 | #if defined(XFS_INODE_TRACE) |
214 | #define VN_HOLD(vp) \ | 211 | #define VN_HOLD(vp) \ |
215 | ((void)vn_hold(vp), \ | 212 | ((void)vn_hold(vp), \ |
216 | vn_trace_hold(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address)) | 213 | xfs_itrace_hold(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address)) |
217 | #define VN_RELE(vp) \ | 214 | #define VN_RELE(vp) \ |
218 | (vn_trace_rele(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address), \ | 215 | (xfs_itrace_rele(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address), \ |
219 | iput(vn_to_inode(vp))) | 216 | iput(vn_to_inode(vp))) |
220 | #else | 217 | #else |
221 | #define VN_HOLD(vp) ((void)vn_hold(vp)) | 218 | #define VN_HOLD(vp) ((void)vn_hold(vp)) |
@@ -238,11 +235,6 @@ static inline bhv_vnode_t *vn_grab(bhv_vnode_t *vp) | |||
238 | /* | 235 | /* |
239 | * Dealing with bad inodes | 236 | * Dealing with bad inodes |
240 | */ | 237 | */ |
241 | static inline void vn_mark_bad(bhv_vnode_t *vp) | ||
242 | { | ||
243 | make_bad_inode(vn_to_inode(vp)); | ||
244 | } | ||
245 | |||
246 | static inline int VN_BAD(bhv_vnode_t *vp) | 238 | static inline int VN_BAD(bhv_vnode_t *vp) |
247 | { | 239 | { |
248 | return is_bad_inode(vn_to_inode(vp)); | 240 | return is_bad_inode(vn_to_inode(vp)); |
@@ -296,26 +288,36 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) | |||
296 | /* | 288 | /* |
297 | * Tracking vnode activity. | 289 | * Tracking vnode activity. |
298 | */ | 290 | */ |
299 | #if defined(XFS_VNODE_TRACE) | 291 | #if defined(XFS_INODE_TRACE) |
300 | 292 | ||
301 | #define VNODE_TRACE_SIZE 16 /* number of trace entries */ | 293 | #define INODE_TRACE_SIZE 16 /* number of trace entries */ |
302 | #define VNODE_KTRACE_ENTRY 1 | 294 | #define INODE_KTRACE_ENTRY 1 |
303 | #define VNODE_KTRACE_EXIT 2 | 295 | #define INODE_KTRACE_EXIT 2 |
304 | #define VNODE_KTRACE_HOLD 3 | 296 | #define INODE_KTRACE_HOLD 3 |
305 | #define VNODE_KTRACE_REF 4 | 297 | #define INODE_KTRACE_REF 4 |
306 | #define VNODE_KTRACE_RELE 5 | 298 | #define INODE_KTRACE_RELE 5 |
307 | 299 | ||
308 | extern void vn_trace_entry(struct xfs_inode *, const char *, inst_t *); | 300 | extern void _xfs_itrace_entry(struct xfs_inode *, const char *, inst_t *); |
309 | extern void vn_trace_exit(struct xfs_inode *, const char *, inst_t *); | 301 | extern void _xfs_itrace_exit(struct xfs_inode *, const char *, inst_t *); |
310 | extern void vn_trace_hold(struct xfs_inode *, char *, int, inst_t *); | 302 | extern void xfs_itrace_hold(struct xfs_inode *, char *, int, inst_t *); |
311 | extern void vn_trace_ref(struct xfs_inode *, char *, int, inst_t *); | 303 | extern void _xfs_itrace_ref(struct xfs_inode *, char *, int, inst_t *); |
312 | extern void vn_trace_rele(struct xfs_inode *, char *, int, inst_t *); | 304 | extern void xfs_itrace_rele(struct xfs_inode *, char *, int, inst_t *); |
305 | #define xfs_itrace_entry(ip) \ | ||
306 | _xfs_itrace_entry(ip, __FUNCTION__, (inst_t *)__return_address) | ||
307 | #define xfs_itrace_exit(ip) \ | ||
308 | _xfs_itrace_exit(ip, __FUNCTION__, (inst_t *)__return_address) | ||
309 | #define xfs_itrace_exit_tag(ip, tag) \ | ||
310 | _xfs_itrace_exit(ip, tag, (inst_t *)__return_address) | ||
311 | #define xfs_itrace_ref(ip) \ | ||
312 | _xfs_itrace_ref(ip, __FILE__, __LINE__, (inst_t *)__return_address) | ||
313 | |||
313 | #else | 314 | #else |
314 | #define vn_trace_entry(a,b,c) | 315 | #define xfs_itrace_entry(a) |
315 | #define vn_trace_exit(a,b,c) | 316 | #define xfs_itrace_exit(a) |
316 | #define vn_trace_hold(a,b,c,d) | 317 | #define xfs_itrace_exit_tag(a, b) |
317 | #define vn_trace_ref(a,b,c,d) | 318 | #define xfs_itrace_hold(a, b, c, d) |
318 | #define vn_trace_rele(a,b,c,d) | 319 | #define xfs_itrace_ref(a) |
320 | #define xfs_itrace_rele(a, b, c, d) | ||
319 | #endif | 321 | #endif |
320 | 322 | ||
321 | #endif /* __XFS_VNODE_H__ */ | 323 | #endif /* __XFS_VNODE_H__ */ |
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index cfdd35ee9f7a..665babcca6a6 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -1209,7 +1209,6 @@ xfs_qm_dqflush( | |||
1209 | xfs_buf_t *bp; | 1209 | xfs_buf_t *bp; |
1210 | xfs_disk_dquot_t *ddqp; | 1210 | xfs_disk_dquot_t *ddqp; |
1211 | int error; | 1211 | int error; |
1212 | SPLDECL(s); | ||
1213 | 1212 | ||
1214 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 1213 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
1215 | ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp)); | 1214 | ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp)); |
@@ -1270,9 +1269,9 @@ xfs_qm_dqflush( | |||
1270 | mp = dqp->q_mount; | 1269 | mp = dqp->q_mount; |
1271 | 1270 | ||
1272 | /* lsn is 64 bits */ | 1271 | /* lsn is 64 bits */ |
1273 | AIL_LOCK(mp, s); | 1272 | spin_lock(&mp->m_ail_lock); |
1274 | dqp->q_logitem.qli_flush_lsn = dqp->q_logitem.qli_item.li_lsn; | 1273 | dqp->q_logitem.qli_flush_lsn = dqp->q_logitem.qli_item.li_lsn; |
1275 | AIL_UNLOCK(mp, s); | 1274 | spin_unlock(&mp->m_ail_lock); |
1276 | 1275 | ||
1277 | /* | 1276 | /* |
1278 | * Attach an iodone routine so that we can remove this dquot from the | 1277 | * Attach an iodone routine so that we can remove this dquot from the |
@@ -1318,7 +1317,6 @@ xfs_qm_dqflush_done( | |||
1318 | xfs_dq_logitem_t *qip) | 1317 | xfs_dq_logitem_t *qip) |
1319 | { | 1318 | { |
1320 | xfs_dquot_t *dqp; | 1319 | xfs_dquot_t *dqp; |
1321 | SPLDECL(s); | ||
1322 | 1320 | ||
1323 | dqp = qip->qli_dquot; | 1321 | dqp = qip->qli_dquot; |
1324 | 1322 | ||
@@ -1333,15 +1331,15 @@ xfs_qm_dqflush_done( | |||
1333 | if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && | 1331 | if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && |
1334 | qip->qli_item.li_lsn == qip->qli_flush_lsn) { | 1332 | qip->qli_item.li_lsn == qip->qli_flush_lsn) { |
1335 | 1333 | ||
1336 | AIL_LOCK(dqp->q_mount, s); | 1334 | spin_lock(&dqp->q_mount->m_ail_lock); |
1337 | /* | 1335 | /* |
1338 | * xfs_trans_delete_ail() drops the AIL lock. | 1336 | * xfs_trans_delete_ail() drops the AIL lock. |
1339 | */ | 1337 | */ |
1340 | if (qip->qli_item.li_lsn == qip->qli_flush_lsn) | 1338 | if (qip->qli_item.li_lsn == qip->qli_flush_lsn) |
1341 | xfs_trans_delete_ail(dqp->q_mount, | 1339 | xfs_trans_delete_ail(dqp->q_mount, |
1342 | (xfs_log_item_t*)qip, s); | 1340 | (xfs_log_item_t*)qip); |
1343 | else | 1341 | else |
1344 | AIL_UNLOCK(dqp->q_mount, s); | 1342 | spin_unlock(&dqp->q_mount->m_ail_lock); |
1345 | } | 1343 | } |
1346 | 1344 | ||
1347 | /* | 1345 | /* |
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 78d3ab95c5fd..5c371a92e3e2 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -123,11 +123,6 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
123 | vsema(&((dqp)->q_flock)); \ | 123 | vsema(&((dqp)->q_flock)); \ |
124 | (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } | 124 | (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } |
125 | 125 | ||
126 | #define XFS_DQ_PINLOCK(dqp) mutex_spinlock( \ | ||
127 | &(XFS_DQ_TO_QINF(dqp)->qi_pinlock)) | ||
128 | #define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ | ||
129 | &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) | ||
130 | |||
131 | #define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock))) | 126 | #define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock))) |
132 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) | 127 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) |
133 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 128 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index ddb61fe22a5c..1800e8d1f646 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -94,14 +94,13 @@ STATIC void | |||
94 | xfs_qm_dquot_logitem_pin( | 94 | xfs_qm_dquot_logitem_pin( |
95 | xfs_dq_logitem_t *logitem) | 95 | xfs_dq_logitem_t *logitem) |
96 | { | 96 | { |
97 | unsigned long s; | ||
98 | xfs_dquot_t *dqp; | 97 | xfs_dquot_t *dqp; |
99 | 98 | ||
100 | dqp = logitem->qli_dquot; | 99 | dqp = logitem->qli_dquot; |
101 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 100 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
102 | s = XFS_DQ_PINLOCK(dqp); | 101 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
103 | dqp->q_pincount++; | 102 | dqp->q_pincount++; |
104 | XFS_DQ_PINUNLOCK(dqp, s); | 103 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
105 | } | 104 | } |
106 | 105 | ||
107 | /* | 106 | /* |
@@ -115,17 +114,16 @@ xfs_qm_dquot_logitem_unpin( | |||
115 | xfs_dq_logitem_t *logitem, | 114 | xfs_dq_logitem_t *logitem, |
116 | int stale) | 115 | int stale) |
117 | { | 116 | { |
118 | unsigned long s; | ||
119 | xfs_dquot_t *dqp; | 117 | xfs_dquot_t *dqp; |
120 | 118 | ||
121 | dqp = logitem->qli_dquot; | 119 | dqp = logitem->qli_dquot; |
122 | ASSERT(dqp->q_pincount > 0); | 120 | ASSERT(dqp->q_pincount > 0); |
123 | s = XFS_DQ_PINLOCK(dqp); | 121 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
124 | dqp->q_pincount--; | 122 | dqp->q_pincount--; |
125 | if (dqp->q_pincount == 0) { | 123 | if (dqp->q_pincount == 0) { |
126 | sv_broadcast(&dqp->q_pinwait); | 124 | sv_broadcast(&dqp->q_pinwait); |
127 | } | 125 | } |
128 | XFS_DQ_PINUNLOCK(dqp, s); | 126 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
129 | } | 127 | } |
130 | 128 | ||
131 | /* ARGSUSED */ | 129 | /* ARGSUSED */ |
@@ -189,8 +187,6 @@ void | |||
189 | xfs_qm_dqunpin_wait( | 187 | xfs_qm_dqunpin_wait( |
190 | xfs_dquot_t *dqp) | 188 | xfs_dquot_t *dqp) |
191 | { | 189 | { |
192 | SPLDECL(s); | ||
193 | |||
194 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 190 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
195 | if (dqp->q_pincount == 0) { | 191 | if (dqp->q_pincount == 0) { |
196 | return; | 192 | return; |
@@ -200,9 +196,9 @@ xfs_qm_dqunpin_wait( | |||
200 | * Give the log a push so we don't wait here too long. | 196 | * Give the log a push so we don't wait here too long. |
201 | */ | 197 | */ |
202 | xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); | 198 | xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); |
203 | s = XFS_DQ_PINLOCK(dqp); | 199 | spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
204 | if (dqp->q_pincount == 0) { | 200 | if (dqp->q_pincount == 0) { |
205 | XFS_DQ_PINUNLOCK(dqp, s); | 201 | spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock)); |
206 | return; | 202 | return; |
207 | } | 203 | } |
208 | sv_wait(&(dqp->q_pinwait), PINOD, | 204 | sv_wait(&(dqp->q_pinwait), PINOD, |
@@ -216,8 +212,8 @@ xfs_qm_dqunpin_wait( | |||
216 | * If so, we want to push it out to help us take this item off the AIL as soon | 212 | * If so, we want to push it out to help us take this item off the AIL as soon |
217 | * as possible. | 213 | * as possible. |
218 | * | 214 | * |
219 | * We must not be holding the AIL_LOCK at this point. Calling incore() to | 215 | * We must not be holding the AIL lock at this point. Calling incore() to |
220 | * search the buffer cache can be a time consuming thing, and AIL_LOCK is a | 216 | * search the buffer cache can be a time consuming thing, and AIL lock is a |
221 | * spinlock. | 217 | * spinlock. |
222 | */ | 218 | */ |
223 | STATIC void | 219 | STATIC void |
@@ -322,7 +318,7 @@ xfs_qm_dquot_logitem_trylock( | |||
322 | * want to do that now since we might sleep in the device | 318 | * want to do that now since we might sleep in the device |
323 | * strategy routine. We also don't want to grab the buffer lock | 319 | * strategy routine. We also don't want to grab the buffer lock |
324 | * here because we'd like not to call into the buffer cache | 320 | * here because we'd like not to call into the buffer cache |
325 | * while holding the AIL_LOCK. | 321 | * while holding the AIL lock. |
326 | * Make sure to only return PUSHBUF if we set pushbuf_flag | 322 | * Make sure to only return PUSHBUF if we set pushbuf_flag |
327 | * ourselves. If someone else is doing it then we don't | 323 | * ourselves. If someone else is doing it then we don't |
328 | * want to go to the push routine and duplicate their efforts. | 324 | * want to go to the push routine and duplicate their efforts. |
@@ -562,15 +558,14 @@ xfs_qm_qoffend_logitem_committed( | |||
562 | xfs_lsn_t lsn) | 558 | xfs_lsn_t lsn) |
563 | { | 559 | { |
564 | xfs_qoff_logitem_t *qfs; | 560 | xfs_qoff_logitem_t *qfs; |
565 | SPLDECL(s); | ||
566 | 561 | ||
567 | qfs = qfe->qql_start_lip; | 562 | qfs = qfe->qql_start_lip; |
568 | AIL_LOCK(qfs->qql_item.li_mountp,s); | 563 | spin_lock(&qfs->qql_item.li_mountp->m_ail_lock); |
569 | /* | 564 | /* |
570 | * Delete the qoff-start logitem from the AIL. | 565 | * Delete the qoff-start logitem from the AIL. |
571 | * xfs_trans_delete_ail() drops the AIL lock. | 566 | * xfs_trans_delete_ail() drops the AIL lock. |
572 | */ | 567 | */ |
573 | xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs, s); | 568 | xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs); |
574 | kmem_free(qfs, sizeof(xfs_qoff_logitem_t)); | 569 | kmem_free(qfs, sizeof(xfs_qoff_logitem_t)); |
575 | kmem_free(qfe, sizeof(xfs_qoff_logitem_t)); | 570 | kmem_free(qfe, sizeof(xfs_qoff_logitem_t)); |
576 | return (xfs_lsn_t)-1; | 571 | return (xfs_lsn_t)-1; |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index d488645f833d..35582fe9d648 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -310,7 +310,6 @@ xfs_qm_mount_quotas( | |||
310 | xfs_mount_t *mp, | 310 | xfs_mount_t *mp, |
311 | int mfsi_flags) | 311 | int mfsi_flags) |
312 | { | 312 | { |
313 | unsigned long s; | ||
314 | int error = 0; | 313 | int error = 0; |
315 | uint sbf; | 314 | uint sbf; |
316 | 315 | ||
@@ -367,13 +366,13 @@ xfs_qm_mount_quotas( | |||
367 | 366 | ||
368 | write_changes: | 367 | write_changes: |
369 | /* | 368 | /* |
370 | * We actually don't have to acquire the SB_LOCK at all. | 369 | * We actually don't have to acquire the m_sb_lock at all. |
371 | * This can only be called from mount, and that's single threaded. XXX | 370 | * This can only be called from mount, and that's single threaded. XXX |
372 | */ | 371 | */ |
373 | s = XFS_SB_LOCK(mp); | 372 | spin_lock(&mp->m_sb_lock); |
374 | sbf = mp->m_sb.sb_qflags; | 373 | sbf = mp->m_sb.sb_qflags; |
375 | mp->m_sb.sb_qflags = mp->m_qflags & XFS_MOUNT_QUOTA_ALL; | 374 | mp->m_sb.sb_qflags = mp->m_qflags & XFS_MOUNT_QUOTA_ALL; |
376 | XFS_SB_UNLOCK(mp, s); | 375 | spin_unlock(&mp->m_sb_lock); |
377 | 376 | ||
378 | if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { | 377 | if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { |
379 | if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { | 378 | if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { |
@@ -1139,7 +1138,7 @@ xfs_qm_init_quotainfo( | |||
1139 | return error; | 1138 | return error; |
1140 | } | 1139 | } |
1141 | 1140 | ||
1142 | spinlock_init(&qinf->qi_pinlock, "xfs_qinf_pin"); | 1141 | spin_lock_init(&qinf->qi_pinlock); |
1143 | xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0); | 1142 | xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0); |
1144 | qinf->qi_dqreclaims = 0; | 1143 | qinf->qi_dqreclaims = 0; |
1145 | 1144 | ||
@@ -1370,7 +1369,6 @@ xfs_qm_qino_alloc( | |||
1370 | { | 1369 | { |
1371 | xfs_trans_t *tp; | 1370 | xfs_trans_t *tp; |
1372 | int error; | 1371 | int error; |
1373 | unsigned long s; | ||
1374 | int committed; | 1372 | int committed; |
1375 | 1373 | ||
1376 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE); | 1374 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE); |
@@ -1402,7 +1400,7 @@ xfs_qm_qino_alloc( | |||
1402 | * sbfields arg may contain fields other than *QUOTINO; | 1400 | * sbfields arg may contain fields other than *QUOTINO; |
1403 | * VERSIONNUM for example. | 1401 | * VERSIONNUM for example. |
1404 | */ | 1402 | */ |
1405 | s = XFS_SB_LOCK(mp); | 1403 | spin_lock(&mp->m_sb_lock); |
1406 | if (flags & XFS_QMOPT_SBVERSION) { | 1404 | if (flags & XFS_QMOPT_SBVERSION) { |
1407 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) | 1405 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) |
1408 | unsigned oldv = mp->m_sb.sb_versionnum; | 1406 | unsigned oldv = mp->m_sb.sb_versionnum; |
@@ -1429,7 +1427,7 @@ xfs_qm_qino_alloc( | |||
1429 | mp->m_sb.sb_uquotino = (*ip)->i_ino; | 1427 | mp->m_sb.sb_uquotino = (*ip)->i_ino; |
1430 | else | 1428 | else |
1431 | mp->m_sb.sb_gquotino = (*ip)->i_ino; | 1429 | mp->m_sb.sb_gquotino = (*ip)->i_ino; |
1432 | XFS_SB_UNLOCK(mp, s); | 1430 | spin_unlock(&mp->m_sb_lock); |
1433 | xfs_mod_sb(tp, sbfields); | 1431 | xfs_mod_sb(tp, sbfields); |
1434 | 1432 | ||
1435 | if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { | 1433 | if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 23ccaa5fceaf..baf537c1c177 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -52,8 +52,8 @@ extern kmem_zone_t *qm_dqtrxzone; | |||
52 | /* | 52 | /* |
53 | * Dquot hashtable constants/threshold values. | 53 | * Dquot hashtable constants/threshold values. |
54 | */ | 54 | */ |
55 | #define XFS_QM_HASHSIZE_LOW (NBPP / sizeof(xfs_dqhash_t)) | 55 | #define XFS_QM_HASHSIZE_LOW (PAGE_SIZE / sizeof(xfs_dqhash_t)) |
56 | #define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t)) | 56 | #define XFS_QM_HASHSIZE_HIGH ((PAGE_SIZE * 4) / sizeof(xfs_dqhash_t)) |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * This defines the unit of allocation of dquots. | 59 | * This defines the unit of allocation of dquots. |
@@ -106,7 +106,7 @@ typedef struct xfs_qm { | |||
106 | typedef struct xfs_quotainfo { | 106 | typedef struct xfs_quotainfo { |
107 | xfs_inode_t *qi_uquotaip; /* user quota inode */ | 107 | xfs_inode_t *qi_uquotaip; /* user quota inode */ |
108 | xfs_inode_t *qi_gquotaip; /* group quota inode */ | 108 | xfs_inode_t *qi_gquotaip; /* group quota inode */ |
109 | lock_t qi_pinlock; /* dquot pinning mutex */ | 109 | spinlock_t qi_pinlock; /* dquot pinning lock */ |
110 | xfs_dqlist_t qi_dqlist; /* all dquots in filesys */ | 110 | xfs_dqlist_t qi_dqlist; /* all dquots in filesys */ |
111 | int qi_dqreclaims; /* a change here indicates | 111 | int qi_dqreclaims; /* a change here indicates |
112 | a removal in the dqlist */ | 112 | a removal in the dqlist */ |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index ad5579d4eac4..2cc5886cfe85 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -200,7 +200,6 @@ xfs_qm_scall_quotaoff( | |||
200 | boolean_t force) | 200 | boolean_t force) |
201 | { | 201 | { |
202 | uint dqtype; | 202 | uint dqtype; |
203 | unsigned long s; | ||
204 | int error; | 203 | int error; |
205 | uint inactivate_flags; | 204 | uint inactivate_flags; |
206 | xfs_qoff_logitem_t *qoffstart; | 205 | xfs_qoff_logitem_t *qoffstart; |
@@ -237,9 +236,9 @@ xfs_qm_scall_quotaoff( | |||
237 | if ((flags & XFS_ALL_QUOTA_ACCT) == 0) { | 236 | if ((flags & XFS_ALL_QUOTA_ACCT) == 0) { |
238 | mp->m_qflags &= ~(flags); | 237 | mp->m_qflags &= ~(flags); |
239 | 238 | ||
240 | s = XFS_SB_LOCK(mp); | 239 | spin_lock(&mp->m_sb_lock); |
241 | mp->m_sb.sb_qflags = mp->m_qflags; | 240 | mp->m_sb.sb_qflags = mp->m_qflags; |
242 | XFS_SB_UNLOCK(mp, s); | 241 | spin_unlock(&mp->m_sb_lock); |
243 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 242 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
244 | 243 | ||
245 | /* XXX what to do if error ? Revert back to old vals incore ? */ | 244 | /* XXX what to do if error ? Revert back to old vals incore ? */ |
@@ -415,7 +414,6 @@ xfs_qm_scall_quotaon( | |||
415 | uint flags) | 414 | uint flags) |
416 | { | 415 | { |
417 | int error; | 416 | int error; |
418 | unsigned long s; | ||
419 | uint qf; | 417 | uint qf; |
420 | uint accflags; | 418 | uint accflags; |
421 | __int64_t sbflags; | 419 | __int64_t sbflags; |
@@ -468,10 +466,10 @@ xfs_qm_scall_quotaon( | |||
468 | * Change sb_qflags on disk but not incore mp->qflags | 466 | * Change sb_qflags on disk but not incore mp->qflags |
469 | * if this is the root filesystem. | 467 | * if this is the root filesystem. |
470 | */ | 468 | */ |
471 | s = XFS_SB_LOCK(mp); | 469 | spin_lock(&mp->m_sb_lock); |
472 | qf = mp->m_sb.sb_qflags; | 470 | qf = mp->m_sb.sb_qflags; |
473 | mp->m_sb.sb_qflags = qf | flags; | 471 | mp->m_sb.sb_qflags = qf | flags; |
474 | XFS_SB_UNLOCK(mp, s); | 472 | spin_unlock(&mp->m_sb_lock); |
475 | 473 | ||
476 | /* | 474 | /* |
477 | * There's nothing to change if it's the same. | 475 | * There's nothing to change if it's the same. |
@@ -815,7 +813,6 @@ xfs_qm_log_quotaoff( | |||
815 | { | 813 | { |
816 | xfs_trans_t *tp; | 814 | xfs_trans_t *tp; |
817 | int error; | 815 | int error; |
818 | unsigned long s; | ||
819 | xfs_qoff_logitem_t *qoffi=NULL; | 816 | xfs_qoff_logitem_t *qoffi=NULL; |
820 | uint oldsbqflag=0; | 817 | uint oldsbqflag=0; |
821 | 818 | ||
@@ -832,10 +829,10 @@ xfs_qm_log_quotaoff( | |||
832 | qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); | 829 | qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); |
833 | xfs_trans_log_quotaoff_item(tp, qoffi); | 830 | xfs_trans_log_quotaoff_item(tp, qoffi); |
834 | 831 | ||
835 | s = XFS_SB_LOCK(mp); | 832 | spin_lock(&mp->m_sb_lock); |
836 | oldsbqflag = mp->m_sb.sb_qflags; | 833 | oldsbqflag = mp->m_sb.sb_qflags; |
837 | mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; | 834 | mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; |
838 | XFS_SB_UNLOCK(mp, s); | 835 | spin_unlock(&mp->m_sb_lock); |
839 | 836 | ||
840 | xfs_mod_sb(tp, XFS_SB_QFLAGS); | 837 | xfs_mod_sb(tp, XFS_SB_QFLAGS); |
841 | 838 | ||
@@ -854,9 +851,9 @@ error0: | |||
854 | * No one else is modifying sb_qflags, so this is OK. | 851 | * No one else is modifying sb_qflags, so this is OK. |
855 | * We still hold the quotaofflock. | 852 | * We still hold the quotaofflock. |
856 | */ | 853 | */ |
857 | s = XFS_SB_LOCK(mp); | 854 | spin_lock(&mp->m_sb_lock); |
858 | mp->m_sb.sb_qflags = oldsbqflag; | 855 | mp->m_sb.sb_qflags = oldsbqflag; |
859 | XFS_SB_UNLOCK(mp, s); | 856 | spin_unlock(&mp->m_sb_lock); |
860 | } | 857 | } |
861 | *qoffstartp = qoffi; | 858 | *qoffstartp = qoffi; |
862 | return (error); | 859 | return (error); |
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c index f45a49ffd3a3..c27abef7b84f 100644 --- a/fs/xfs/support/debug.c +++ b/fs/xfs/support/debug.c | |||
@@ -17,7 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | #include <xfs.h> | 18 | #include <xfs.h> |
19 | #include "debug.h" | 19 | #include "debug.h" |
20 | #include "spin.h" | ||
21 | 20 | ||
22 | static char message[1024]; /* keep it off the stack */ | 21 | static char message[1024]; /* keep it off the stack */ |
23 | static DEFINE_SPINLOCK(xfs_err_lock); | 22 | static DEFINE_SPINLOCK(xfs_err_lock); |
@@ -81,3 +80,9 @@ assfail(char *expr, char *file, int line) | |||
81 | printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line); | 80 | printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line); |
82 | BUG(); | 81 | BUG(); |
83 | } | 82 | } |
83 | |||
84 | void | ||
85 | xfs_hex_dump(void *p, int length) | ||
86 | { | ||
87 | print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1); | ||
88 | } | ||
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c index 5cf2e86caa71..129067cfcb86 100644 --- a/fs/xfs/support/ktrace.c +++ b/fs/xfs/support/ktrace.c | |||
@@ -21,7 +21,7 @@ static kmem_zone_t *ktrace_hdr_zone; | |||
21 | static kmem_zone_t *ktrace_ent_zone; | 21 | static kmem_zone_t *ktrace_ent_zone; |
22 | static int ktrace_zentries; | 22 | static int ktrace_zentries; |
23 | 23 | ||
24 | void | 24 | void __init |
25 | ktrace_init(int zentries) | 25 | ktrace_init(int zentries) |
26 | { | 26 | { |
27 | ktrace_zentries = zentries; | 27 | ktrace_zentries = zentries; |
@@ -36,7 +36,7 @@ ktrace_init(int zentries) | |||
36 | ASSERT(ktrace_ent_zone); | 36 | ASSERT(ktrace_ent_zone); |
37 | } | 37 | } |
38 | 38 | ||
39 | void | 39 | void __exit |
40 | ktrace_uninit(void) | 40 | ktrace_uninit(void) |
41 | { | 41 | { |
42 | kmem_zone_destroy(ktrace_hdr_zone); | 42 | kmem_zone_destroy(ktrace_hdr_zone); |
@@ -90,8 +90,6 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) | |||
90 | return NULL; | 90 | return NULL; |
91 | } | 91 | } |
92 | 92 | ||
93 | spinlock_init(&(ktp->kt_lock), "kt_lock"); | ||
94 | |||
95 | ktp->kt_entries = ktep; | 93 | ktp->kt_entries = ktep; |
96 | ktp->kt_nentries = nentries; | 94 | ktp->kt_nentries = nentries; |
97 | ktp->kt_index = 0; | 95 | ktp->kt_index = 0; |
@@ -114,8 +112,6 @@ ktrace_free(ktrace_t *ktp) | |||
114 | if (ktp == (ktrace_t *)NULL) | 112 | if (ktp == (ktrace_t *)NULL) |
115 | return; | 113 | return; |
116 | 114 | ||
117 | spinlock_destroy(&ktp->kt_lock); | ||
118 | |||
119 | /* | 115 | /* |
120 | * Special treatment for the Vnode trace buffer. | 116 | * Special treatment for the Vnode trace buffer. |
121 | */ | 117 | */ |
diff --git a/fs/xfs/support/ktrace.h b/fs/xfs/support/ktrace.h index 0d73216287c0..56e72b40a859 100644 --- a/fs/xfs/support/ktrace.h +++ b/fs/xfs/support/ktrace.h | |||
@@ -18,8 +18,6 @@ | |||
18 | #ifndef __XFS_SUPPORT_KTRACE_H__ | 18 | #ifndef __XFS_SUPPORT_KTRACE_H__ |
19 | #define __XFS_SUPPORT_KTRACE_H__ | 19 | #define __XFS_SUPPORT_KTRACE_H__ |
20 | 20 | ||
21 | #include <spin.h> | ||
22 | |||
23 | /* | 21 | /* |
24 | * Trace buffer entry structure. | 22 | * Trace buffer entry structure. |
25 | */ | 23 | */ |
@@ -31,7 +29,6 @@ typedef struct ktrace_entry { | |||
31 | * Trace buffer header structure. | 29 | * Trace buffer header structure. |
32 | */ | 30 | */ |
33 | typedef struct ktrace { | 31 | typedef struct ktrace { |
34 | lock_t kt_lock; /* mutex to guard counters */ | ||
35 | int kt_nentries; /* number of entries in trace buf */ | 32 | int kt_nentries; /* number of entries in trace buf */ |
36 | int kt_index; /* current index in entries */ | 33 | int kt_index; /* current index in entries */ |
37 | int kt_rollover; | 34 | int kt_rollover; |
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c index e157015c70ff..493a6ecf8590 100644 --- a/fs/xfs/support/uuid.c +++ b/fs/xfs/support/uuid.c | |||
@@ -133,7 +133,7 @@ uuid_table_remove(uuid_t *uuid) | |||
133 | mutex_unlock(&uuid_monitor); | 133 | mutex_unlock(&uuid_monitor); |
134 | } | 134 | } |
135 | 135 | ||
136 | void | 136 | void __init |
137 | uuid_init(void) | 137 | uuid_init(void) |
138 | { | 138 | { |
139 | mutex_init(&uuid_monitor); | 139 | mutex_init(&uuid_monitor); |
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index b5a7d92c6843..540e4c989825 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #define XFS_LOG_TRACE 1 | 37 | #define XFS_LOG_TRACE 1 |
38 | #define XFS_RW_TRACE 1 | 38 | #define XFS_RW_TRACE 1 |
39 | #define XFS_BUF_TRACE 1 | 39 | #define XFS_BUF_TRACE 1 |
40 | #define XFS_VNODE_TRACE 1 | 40 | #define XFS_INODE_TRACE 1 |
41 | #define XFS_FILESTREAMS_TRACE 1 | 41 | #define XFS_FILESTREAMS_TRACE 1 |
42 | #endif | 42 | #endif |
43 | 43 | ||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 5bfb66f33caf..7272fe39a92d 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -392,32 +392,6 @@ xfs_acl_allow_set( | |||
392 | } | 392 | } |
393 | 393 | ||
394 | /* | 394 | /* |
395 | * The access control process to determine the access permission: | ||
396 | * if uid == file owner id, use the file owner bits. | ||
397 | * if gid == file owner group id, use the file group bits. | ||
398 | * scan ACL for a matching user or group, and use matched entry | ||
399 | * permission. Use total permissions of all matching group entries, | ||
400 | * until all acl entries are exhausted. The final permission produced | ||
401 | * by matching acl entry or entries needs to be & with group permission. | ||
402 | * if not owner, owning group, or matching entry in ACL, use file | ||
403 | * other bits. | ||
404 | */ | ||
405 | STATIC int | ||
406 | xfs_acl_capability_check( | ||
407 | mode_t mode, | ||
408 | cred_t *cr) | ||
409 | { | ||
410 | if ((mode & ACL_READ) && !capable_cred(cr, CAP_DAC_READ_SEARCH)) | ||
411 | return EACCES; | ||
412 | if ((mode & ACL_WRITE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) | ||
413 | return EACCES; | ||
414 | if ((mode & ACL_EXECUTE) && !capable_cred(cr, CAP_DAC_OVERRIDE)) | ||
415 | return EACCES; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Note: cr is only used here for the capability check if the ACL test fails. | 395 | * Note: cr is only used here for the capability check if the ACL test fails. |
422 | * It is not used to find out the credentials uid or groups etc, as was | 396 | * It is not used to find out the credentials uid or groups etc, as was |
423 | * done in IRIX. It is assumed that the uid and groups for the current | 397 | * done in IRIX. It is assumed that the uid and groups for the current |
@@ -438,7 +412,6 @@ xfs_acl_access( | |||
438 | 412 | ||
439 | matched.ae_tag = 0; /* Invalid type */ | 413 | matched.ae_tag = 0; /* Invalid type */ |
440 | matched.ae_perm = 0; | 414 | matched.ae_perm = 0; |
441 | md >>= 6; /* Normalize the bits for comparison */ | ||
442 | 415 | ||
443 | for (i = 0; i < fap->acl_cnt; i++) { | 416 | for (i = 0; i < fap->acl_cnt; i++) { |
444 | /* | 417 | /* |
@@ -520,7 +493,8 @@ xfs_acl_access( | |||
520 | break; | 493 | break; |
521 | } | 494 | } |
522 | 495 | ||
523 | return xfs_acl_capability_check(md, cr); | 496 | /* EACCES tells generic_permission to check for capability overrides */ |
497 | return EACCES; | ||
524 | } | 498 | } |
525 | 499 | ||
526 | /* | 500 | /* |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 34b7d3391299..332a772461c4 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -75,7 +75,6 @@ extern int xfs_acl_vremove(bhv_vnode_t *, int); | |||
75 | #define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) | 75 | #define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) |
76 | #define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access | 76 | #define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access |
77 | #define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default | 77 | #define _ACL_DEFAULT_EXISTS xfs_acl_vhasacl_default |
78 | #define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1) | ||
79 | 78 | ||
80 | #define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP)) | 79 | #define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP)) |
81 | #define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0) | 80 | #define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0) |
@@ -95,7 +94,6 @@ extern int xfs_acl_vremove(bhv_vnode_t *, int); | |||
95 | #define _ACL_GET_DEFAULT(pv,pd) (0) | 94 | #define _ACL_GET_DEFAULT(pv,pd) (0) |
96 | #define _ACL_ACCESS_EXISTS (NULL) | 95 | #define _ACL_ACCESS_EXISTS (NULL) |
97 | #define _ACL_DEFAULT_EXISTS (NULL) | 96 | #define _ACL_DEFAULT_EXISTS (NULL) |
98 | #define _ACL_XFS_IACCESS(i,m,c) (-1) | ||
99 | #endif | 97 | #endif |
100 | 98 | ||
101 | #endif /* __XFS_ACL_H__ */ | 99 | #endif /* __XFS_ACL_H__ */ |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 9381b0360c4b..61b292a9fb41 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -193,7 +193,7 @@ typedef struct xfs_perag | |||
193 | xfs_agino_t pagi_count; /* number of allocated inodes */ | 193 | xfs_agino_t pagi_count; /* number of allocated inodes */ |
194 | int pagb_count; /* pagb slots in use */ | 194 | int pagb_count; /* pagb slots in use */ |
195 | #ifdef __KERNEL__ | 195 | #ifdef __KERNEL__ |
196 | lock_t pagb_lock; /* lock for pagb_list */ | 196 | spinlock_t pagb_lock; /* lock for pagb_list */ |
197 | #endif | 197 | #endif |
198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ | 198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ |
199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ | 199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 012a649a19c3..ea6aa60ace06 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -2206,7 +2206,7 @@ xfs_alloc_read_agf( | |||
2206 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); | 2206 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); |
2207 | pag->pagf_levels[XFS_BTNUM_CNTi] = | 2207 | pag->pagf_levels[XFS_BTNUM_CNTi] = |
2208 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); | 2208 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); |
2209 | spinlock_init(&pag->pagb_lock, "xfspagb"); | 2209 | spin_lock_init(&pag->pagb_lock); |
2210 | pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS * | 2210 | pag->pagb_list = kmem_zalloc(XFS_PAGB_NUM_SLOTS * |
2211 | sizeof(xfs_perag_busy_t), KM_SLEEP); | 2211 | sizeof(xfs_perag_busy_t), KM_SLEEP); |
2212 | pag->pagf_init = 1; | 2212 | pag->pagf_init = 1; |
@@ -2500,10 +2500,9 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, | |||
2500 | xfs_mount_t *mp; | 2500 | xfs_mount_t *mp; |
2501 | xfs_perag_busy_t *bsy; | 2501 | xfs_perag_busy_t *bsy; |
2502 | int n; | 2502 | int n; |
2503 | SPLDECL(s); | ||
2504 | 2503 | ||
2505 | mp = tp->t_mountp; | 2504 | mp = tp->t_mountp; |
2506 | s = mutex_spinlock(&mp->m_perag[agno].pagb_lock); | 2505 | spin_lock(&mp->m_perag[agno].pagb_lock); |
2507 | 2506 | ||
2508 | /* search pagb_list for an open slot */ | 2507 | /* search pagb_list for an open slot */ |
2509 | for (bsy = mp->m_perag[agno].pagb_list, n = 0; | 2508 | for (bsy = mp->m_perag[agno].pagb_list, n = 0; |
@@ -2533,7 +2532,7 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, | |||
2533 | xfs_trans_set_sync(tp); | 2532 | xfs_trans_set_sync(tp); |
2534 | } | 2533 | } |
2535 | 2534 | ||
2536 | mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s); | 2535 | spin_unlock(&mp->m_perag[agno].pagb_lock); |
2537 | } | 2536 | } |
2538 | 2537 | ||
2539 | void | 2538 | void |
@@ -2543,11 +2542,10 @@ xfs_alloc_clear_busy(xfs_trans_t *tp, | |||
2543 | { | 2542 | { |
2544 | xfs_mount_t *mp; | 2543 | xfs_mount_t *mp; |
2545 | xfs_perag_busy_t *list; | 2544 | xfs_perag_busy_t *list; |
2546 | SPLDECL(s); | ||
2547 | 2545 | ||
2548 | mp = tp->t_mountp; | 2546 | mp = tp->t_mountp; |
2549 | 2547 | ||
2550 | s = mutex_spinlock(&mp->m_perag[agno].pagb_lock); | 2548 | spin_lock(&mp->m_perag[agno].pagb_lock); |
2551 | list = mp->m_perag[agno].pagb_list; | 2549 | list = mp->m_perag[agno].pagb_list; |
2552 | 2550 | ||
2553 | ASSERT(idx < XFS_PAGB_NUM_SLOTS); | 2551 | ASSERT(idx < XFS_PAGB_NUM_SLOTS); |
@@ -2559,7 +2557,7 @@ xfs_alloc_clear_busy(xfs_trans_t *tp, | |||
2559 | TRACE_UNBUSY("xfs_alloc_clear_busy", "missing", agno, idx, tp); | 2557 | TRACE_UNBUSY("xfs_alloc_clear_busy", "missing", agno, idx, tp); |
2560 | } | 2558 | } |
2561 | 2559 | ||
2562 | mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s); | 2560 | spin_unlock(&mp->m_perag[agno].pagb_lock); |
2563 | } | 2561 | } |
2564 | 2562 | ||
2565 | 2563 | ||
@@ -2578,11 +2576,10 @@ xfs_alloc_search_busy(xfs_trans_t *tp, | |||
2578 | xfs_agblock_t uend, bend; | 2576 | xfs_agblock_t uend, bend; |
2579 | xfs_lsn_t lsn; | 2577 | xfs_lsn_t lsn; |
2580 | int cnt; | 2578 | int cnt; |
2581 | SPLDECL(s); | ||
2582 | 2579 | ||
2583 | mp = tp->t_mountp; | 2580 | mp = tp->t_mountp; |
2584 | 2581 | ||
2585 | s = mutex_spinlock(&mp->m_perag[agno].pagb_lock); | 2582 | spin_lock(&mp->m_perag[agno].pagb_lock); |
2586 | cnt = mp->m_perag[agno].pagb_count; | 2583 | cnt = mp->m_perag[agno].pagb_count; |
2587 | 2584 | ||
2588 | uend = bno + len - 1; | 2585 | uend = bno + len - 1; |
@@ -2615,12 +2612,12 @@ xfs_alloc_search_busy(xfs_trans_t *tp, | |||
2615 | if (cnt) { | 2612 | if (cnt) { |
2616 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "found", agno, bno, len, n, tp); | 2613 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "found", agno, bno, len, n, tp); |
2617 | lsn = bsy->busy_tp->t_commit_lsn; | 2614 | lsn = bsy->busy_tp->t_commit_lsn; |
2618 | mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s); | 2615 | spin_unlock(&mp->m_perag[agno].pagb_lock); |
2619 | xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); | 2616 | xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); |
2620 | } else { | 2617 | } else { |
2621 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "not-found", agno, bno, len, n, tp); | 2618 | TRACE_BUSYSEARCH("xfs_alloc_search_busy", "not-found", agno, bno, len, n, tp); |
2622 | n = -1; | 2619 | n = -1; |
2623 | mutex_spinunlock(&mp->m_perag[agno].pagb_lock, s); | 2620 | spin_unlock(&mp->m_perag[agno].pagb_lock); |
2624 | } | 2621 | } |
2625 | 2622 | ||
2626 | return n; | 2623 | return n; |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 93fa64dd1be6..e58f321fdae9 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -929,7 +929,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) | |||
929 | * This leaf block cannot have a "remote" value, we only call this routine | 929 | * This leaf block cannot have a "remote" value, we only call this routine |
930 | * if bmap_one_block() says there is only one block (ie: no remote blks). | 930 | * if bmap_one_block() says there is only one block (ie: no remote blks). |
931 | */ | 931 | */ |
932 | int | 932 | STATIC int |
933 | xfs_attr_leaf_addname(xfs_da_args_t *args) | 933 | xfs_attr_leaf_addname(xfs_da_args_t *args) |
934 | { | 934 | { |
935 | xfs_inode_t *dp; | 935 | xfs_inode_t *dp; |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 81f45dae1c57..eb3815ebb7aa 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -226,17 +226,15 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) | |||
226 | STATIC void | 226 | STATIC void |
227 | xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) | 227 | xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) |
228 | { | 228 | { |
229 | unsigned long s; | ||
230 | |||
231 | if ((mp->m_flags & XFS_MOUNT_ATTR2) && | 229 | if ((mp->m_flags & XFS_MOUNT_ATTR2) && |
232 | !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) { | 230 | !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) { |
233 | s = XFS_SB_LOCK(mp); | 231 | spin_lock(&mp->m_sb_lock); |
234 | if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { | 232 | if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { |
235 | XFS_SB_VERSION_ADDATTR2(&mp->m_sb); | 233 | XFS_SB_VERSION_ADDATTR2(&mp->m_sb); |
236 | XFS_SB_UNLOCK(mp, s); | 234 | spin_unlock(&mp->m_sb_lock); |
237 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); | 235 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); |
238 | } else | 236 | } else |
239 | XFS_SB_UNLOCK(mp, s); | 237 | spin_unlock(&mp->m_sb_lock); |
240 | } | 238 | } |
241 | } | 239 | } |
242 | 240 | ||
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index fab0b6d5a41b..48228848f5ae 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c | |||
@@ -25,109 +25,6 @@ | |||
25 | * XFS bit manipulation routines, used in non-realtime code. | 25 | * XFS bit manipulation routines, used in non-realtime code. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #ifndef HAVE_ARCH_HIGHBIT | ||
29 | /* | ||
30 | * Index of high bit number in byte, -1 for none set, 0..7 otherwise. | ||
31 | */ | ||
32 | static const char xfs_highbit[256] = { | ||
33 | -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ | ||
34 | 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ | ||
35 | 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ | ||
36 | 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ | ||
37 | 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ | ||
38 | 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ | ||
39 | 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ | ||
40 | 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ | ||
41 | 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ | ||
42 | 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ | ||
43 | 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ | ||
44 | 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ | ||
45 | 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ | ||
46 | 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ | ||
47 | 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ | ||
48 | 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ | ||
49 | 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ | ||
50 | 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ | ||
51 | 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ | ||
52 | 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ | ||
53 | 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ | ||
54 | 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ | ||
55 | 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ | ||
56 | 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ | ||
57 | 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ | ||
58 | 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ | ||
59 | 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ | ||
60 | 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ | ||
61 | 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ | ||
62 | 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ | ||
63 | 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ | ||
64 | 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ | ||
65 | }; | ||
66 | #endif | ||
67 | |||
68 | /* | ||
69 | * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. | ||
70 | */ | ||
71 | inline int | ||
72 | xfs_highbit32( | ||
73 | __uint32_t v) | ||
74 | { | ||
75 | #ifdef HAVE_ARCH_HIGHBIT | ||
76 | return highbit32(v); | ||
77 | #else | ||
78 | int i; | ||
79 | |||
80 | if (v & 0xffff0000) | ||
81 | if (v & 0xff000000) | ||
82 | i = 24; | ||
83 | else | ||
84 | i = 16; | ||
85 | else if (v & 0x0000ffff) | ||
86 | if (v & 0x0000ff00) | ||
87 | i = 8; | ||
88 | else | ||
89 | i = 0; | ||
90 | else | ||
91 | return -1; | ||
92 | return i + xfs_highbit[(v >> i) & 0xff]; | ||
93 | #endif | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. | ||
98 | */ | ||
99 | int | ||
100 | xfs_lowbit64( | ||
101 | __uint64_t v) | ||
102 | { | ||
103 | __uint32_t w = (__uint32_t)v; | ||
104 | int n = 0; | ||
105 | |||
106 | if (w) { /* lower bits */ | ||
107 | n = ffs(w); | ||
108 | } else { /* upper bits */ | ||
109 | w = (__uint32_t)(v >> 32); | ||
110 | if (w && (n = ffs(w))) | ||
111 | n += 32; | ||
112 | } | ||
113 | return n - 1; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. | ||
118 | */ | ||
119 | int | ||
120 | xfs_highbit64( | ||
121 | __uint64_t v) | ||
122 | { | ||
123 | __uint32_t h = (__uint32_t)(v >> 32); | ||
124 | |||
125 | if (h) | ||
126 | return xfs_highbit32(h) + 32; | ||
127 | return xfs_highbit32((__uint32_t)v); | ||
128 | } | ||
129 | |||
130 | |||
131 | /* | 28 | /* |
132 | * Return whether bitmap is empty. | 29 | * Return whether bitmap is empty. |
133 | * Size is number of words in the bitmap, which is padded to word boundary | 30 | * Size is number of words in the bitmap, which is padded to word boundary |
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 082641a9782c..325a007dec91 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h | |||
@@ -47,13 +47,30 @@ static inline __uint64_t xfs_mask64lo(int n) | |||
47 | } | 47 | } |
48 | 48 | ||
49 | /* Get high bit set out of 32-bit argument, -1 if none set */ | 49 | /* Get high bit set out of 32-bit argument, -1 if none set */ |
50 | extern int xfs_highbit32(__uint32_t v); | 50 | static inline int xfs_highbit32(__uint32_t v) |
51 | 51 | { | |
52 | /* Get low bit set out of 64-bit argument, -1 if none set */ | 52 | return fls(v) - 1; |
53 | extern int xfs_lowbit64(__uint64_t v); | 53 | } |
54 | 54 | ||
55 | /* Get high bit set out of 64-bit argument, -1 if none set */ | 55 | /* Get high bit set out of 64-bit argument, -1 if none set */ |
56 | extern int xfs_highbit64(__uint64_t); | 56 | static inline int xfs_highbit64(__uint64_t v) |
57 | { | ||
58 | return fls64(v) - 1; | ||
59 | } | ||
60 | |||
61 | /* Get low bit set out of 32-bit argument, -1 if none set */ | ||
62 | static inline int xfs_lowbit32(__uint32_t v) | ||
63 | { | ||
64 | __uint32_t t = v; | ||
65 | return (t) ? find_first_bit((unsigned long *)&t, 32) : -1; | ||
66 | } | ||
67 | |||
68 | /* Get low bit set out of 64-bit argument, -1 if none set */ | ||
69 | static inline int xfs_lowbit64(__uint64_t v) | ||
70 | { | ||
71 | __uint64_t t = v; | ||
72 | return (t) ? find_first_bit((unsigned long *)&t, 64) : -1; | ||
73 | } | ||
57 | 74 | ||
58 | /* Return whether bitmap is empty (1 == empty) */ | 75 | /* Return whether bitmap is empty (1 == empty) */ |
59 | extern int xfs_bitmap_empty(uint *map, uint size); | 76 | extern int xfs_bitmap_empty(uint *map, uint size); |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 2e9b34b7344b..1c0a5a585a82 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -2830,11 +2830,11 @@ xfs_bmap_btalloc( | |||
2830 | args.prod = align; | 2830 | args.prod = align; |
2831 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) | 2831 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) |
2832 | args.mod = (xfs_extlen_t)(args.prod - args.mod); | 2832 | args.mod = (xfs_extlen_t)(args.prod - args.mod); |
2833 | } else if (mp->m_sb.sb_blocksize >= NBPP) { | 2833 | } else if (mp->m_sb.sb_blocksize >= PAGE_CACHE_SIZE) { |
2834 | args.prod = 1; | 2834 | args.prod = 1; |
2835 | args.mod = 0; | 2835 | args.mod = 0; |
2836 | } else { | 2836 | } else { |
2837 | args.prod = NBPP >> mp->m_sb.sb_blocklog; | 2837 | args.prod = PAGE_CACHE_SIZE >> mp->m_sb.sb_blocklog; |
2838 | if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) | 2838 | if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) |
2839 | args.mod = (xfs_extlen_t)(args.prod - args.mod); | 2839 | args.mod = (xfs_extlen_t)(args.prod - args.mod); |
2840 | } | 2840 | } |
@@ -2969,7 +2969,7 @@ STATIC int | |||
2969 | xfs_bmap_alloc( | 2969 | xfs_bmap_alloc( |
2970 | xfs_bmalloca_t *ap) /* bmap alloc argument struct */ | 2970 | xfs_bmalloca_t *ap) /* bmap alloc argument struct */ |
2971 | { | 2971 | { |
2972 | if ((ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata) | 2972 | if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) |
2973 | return xfs_bmap_rtalloc(ap); | 2973 | return xfs_bmap_rtalloc(ap); |
2974 | return xfs_bmap_btalloc(ap); | 2974 | return xfs_bmap_btalloc(ap); |
2975 | } | 2975 | } |
@@ -3096,8 +3096,7 @@ xfs_bmap_del_extent( | |||
3096 | /* | 3096 | /* |
3097 | * Realtime allocation. Free it and record di_nblocks update. | 3097 | * Realtime allocation. Free it and record di_nblocks update. |
3098 | */ | 3098 | */ |
3099 | if (whichfork == XFS_DATA_FORK && | 3099 | if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { |
3100 | (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | ||
3101 | xfs_fsblock_t bno; | 3100 | xfs_fsblock_t bno; |
3102 | xfs_filblks_t len; | 3101 | xfs_filblks_t len; |
3103 | 3102 | ||
@@ -3956,7 +3955,6 @@ xfs_bmap_add_attrfork( | |||
3956 | xfs_bmap_free_t flist; /* freed extent records */ | 3955 | xfs_bmap_free_t flist; /* freed extent records */ |
3957 | xfs_mount_t *mp; /* mount structure */ | 3956 | xfs_mount_t *mp; /* mount structure */ |
3958 | xfs_trans_t *tp; /* transaction pointer */ | 3957 | xfs_trans_t *tp; /* transaction pointer */ |
3959 | unsigned long s; /* spinlock spl value */ | ||
3960 | int blks; /* space reservation */ | 3958 | int blks; /* space reservation */ |
3961 | int version = 1; /* superblock attr version */ | 3959 | int version = 1; /* superblock attr version */ |
3962 | int committed; /* xaction was committed */ | 3960 | int committed; /* xaction was committed */ |
@@ -4053,7 +4051,7 @@ xfs_bmap_add_attrfork( | |||
4053 | (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) { | 4051 | (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) { |
4054 | __int64_t sbfields = 0; | 4052 | __int64_t sbfields = 0; |
4055 | 4053 | ||
4056 | s = XFS_SB_LOCK(mp); | 4054 | spin_lock(&mp->m_sb_lock); |
4057 | if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { | 4055 | if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { |
4058 | XFS_SB_VERSION_ADDATTR(&mp->m_sb); | 4056 | XFS_SB_VERSION_ADDATTR(&mp->m_sb); |
4059 | sbfields |= XFS_SB_VERSIONNUM; | 4057 | sbfields |= XFS_SB_VERSIONNUM; |
@@ -4063,10 +4061,10 @@ xfs_bmap_add_attrfork( | |||
4063 | sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); | 4061 | sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); |
4064 | } | 4062 | } |
4065 | if (sbfields) { | 4063 | if (sbfields) { |
4066 | XFS_SB_UNLOCK(mp, s); | 4064 | spin_unlock(&mp->m_sb_lock); |
4067 | xfs_mod_sb(tp, sbfields); | 4065 | xfs_mod_sb(tp, sbfields); |
4068 | } else | 4066 | } else |
4069 | XFS_SB_UNLOCK(mp, s); | 4067 | spin_unlock(&mp->m_sb_lock); |
4070 | } | 4068 | } |
4071 | if ((error = xfs_bmap_finish(&tp, &flist, &committed))) | 4069 | if ((error = xfs_bmap_finish(&tp, &flist, &committed))) |
4072 | goto error2; | 4070 | goto error2; |
@@ -6394,7 +6392,7 @@ xfs_bmap_count_blocks( | |||
6394 | * Recursively walks each level of a btree | 6392 | * Recursively walks each level of a btree |
6395 | * to count total fsblocks is use. | 6393 | * to count total fsblocks is use. |
6396 | */ | 6394 | */ |
6397 | int /* error */ | 6395 | STATIC int /* error */ |
6398 | xfs_bmap_count_tree( | 6396 | xfs_bmap_count_tree( |
6399 | xfs_mount_t *mp, /* file system mount point */ | 6397 | xfs_mount_t *mp, /* file system mount point */ |
6400 | xfs_trans_t *tp, /* transaction pointer */ | 6398 | xfs_trans_t *tp, /* transaction pointer */ |
@@ -6470,7 +6468,7 @@ xfs_bmap_count_tree( | |||
6470 | /* | 6468 | /* |
6471 | * Count leaf blocks given a range of extent records. | 6469 | * Count leaf blocks given a range of extent records. |
6472 | */ | 6470 | */ |
6473 | int | 6471 | STATIC int |
6474 | xfs_bmap_count_leaves( | 6472 | xfs_bmap_count_leaves( |
6475 | xfs_ifork_t *ifp, | 6473 | xfs_ifork_t *ifp, |
6476 | xfs_extnum_t idx, | 6474 | xfs_extnum_t idx, |
@@ -6490,7 +6488,7 @@ xfs_bmap_count_leaves( | |||
6490 | * Count leaf blocks given a range of extent records originally | 6488 | * Count leaf blocks given a range of extent records originally |
6491 | * in btree format. | 6489 | * in btree format. |
6492 | */ | 6490 | */ |
6493 | int | 6491 | STATIC int |
6494 | xfs_bmap_disk_count_leaves( | 6492 | xfs_bmap_disk_count_leaves( |
6495 | xfs_extnum_t idx, | 6493 | xfs_extnum_t idx, |
6496 | xfs_bmbt_block_t *block, | 6494 | xfs_bmbt_block_t *block, |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 68267d75ff19..87224b7d7984 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -25,6 +25,8 @@ struct xfs_inode; | |||
25 | struct xfs_mount; | 25 | struct xfs_mount; |
26 | struct xfs_trans; | 26 | struct xfs_trans; |
27 | 27 | ||
28 | extern kmem_zone_t *xfs_bmap_free_item_zone; | ||
29 | |||
28 | /* | 30 | /* |
29 | * DELTA: describe a change to the in-core extent list. | 31 | * DELTA: describe a change to the in-core extent list. |
30 | * | 32 | * |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 32b49ec00fb5..c4181d85605c 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -2062,8 +2062,7 @@ xfs_bmbt_insert( | |||
2062 | pcur->bc_private.b.allocated; | 2062 | pcur->bc_private.b.allocated; |
2063 | pcur->bc_private.b.allocated = 0; | 2063 | pcur->bc_private.b.allocated = 0; |
2064 | ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) || | 2064 | ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) || |
2065 | (cur->bc_private.b.ip->i_d.di_flags & | 2065 | XFS_IS_REALTIME_INODE(cur->bc_private.b.ip)); |
2066 | XFS_DIFLAG_REALTIME)); | ||
2067 | cur->bc_private.b.firstblock = | 2066 | cur->bc_private.b.firstblock = |
2068 | pcur->bc_private.b.firstblock; | 2067 | pcur->bc_private.b.firstblock; |
2069 | ASSERT(cur->bc_private.b.flist == | 2068 | ASSERT(cur->bc_private.b.flist == |
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 6e40a0a198ff..7440b78f9cec 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h | |||
@@ -24,6 +24,8 @@ struct xfs_inode; | |||
24 | struct xfs_mount; | 24 | struct xfs_mount; |
25 | struct xfs_trans; | 25 | struct xfs_trans; |
26 | 26 | ||
27 | extern kmem_zone_t *xfs_btree_cur_zone; | ||
28 | |||
27 | /* | 29 | /* |
28 | * This nonsense is to make -wlint happy. | 30 | * This nonsense is to make -wlint happy. |
29 | */ | 31 | */ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index c8f2c2886fe4..63debd147eb5 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -378,7 +378,6 @@ xfs_buf_item_unpin( | |||
378 | xfs_mount_t *mp; | 378 | xfs_mount_t *mp; |
379 | xfs_buf_t *bp; | 379 | xfs_buf_t *bp; |
380 | int freed; | 380 | int freed; |
381 | SPLDECL(s); | ||
382 | 381 | ||
383 | bp = bip->bli_buf; | 382 | bp = bip->bli_buf; |
384 | ASSERT(bp != NULL); | 383 | ASSERT(bp != NULL); |
@@ -409,8 +408,8 @@ xfs_buf_item_unpin( | |||
409 | XFS_BUF_SET_FSPRIVATE(bp, NULL); | 408 | XFS_BUF_SET_FSPRIVATE(bp, NULL); |
410 | XFS_BUF_CLR_IODONE_FUNC(bp); | 409 | XFS_BUF_CLR_IODONE_FUNC(bp); |
411 | } else { | 410 | } else { |
412 | AIL_LOCK(mp,s); | 411 | spin_lock(&mp->m_ail_lock); |
413 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip, s); | 412 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); |
414 | xfs_buf_item_relse(bp); | 413 | xfs_buf_item_relse(bp); |
415 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL); | 414 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL); |
416 | } | 415 | } |
@@ -1113,7 +1112,6 @@ xfs_buf_iodone( | |||
1113 | xfs_buf_log_item_t *bip) | 1112 | xfs_buf_log_item_t *bip) |
1114 | { | 1113 | { |
1115 | struct xfs_mount *mp; | 1114 | struct xfs_mount *mp; |
1116 | SPLDECL(s); | ||
1117 | 1115 | ||
1118 | ASSERT(bip->bli_buf == bp); | 1116 | ASSERT(bip->bli_buf == bp); |
1119 | 1117 | ||
@@ -1128,11 +1126,11 @@ xfs_buf_iodone( | |||
1128 | * | 1126 | * |
1129 | * Either way, AIL is useless if we're forcing a shutdown. | 1127 | * Either way, AIL is useless if we're forcing a shutdown. |
1130 | */ | 1128 | */ |
1131 | AIL_LOCK(mp,s); | 1129 | spin_lock(&mp->m_ail_lock); |
1132 | /* | 1130 | /* |
1133 | * xfs_trans_delete_ail() drops the AIL lock. | 1131 | * xfs_trans_delete_ail() drops the AIL lock. |
1134 | */ | 1132 | */ |
1135 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip, s); | 1133 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); |
1136 | 1134 | ||
1137 | #ifdef XFS_TRANS_DEBUG | 1135 | #ifdef XFS_TRANS_DEBUG |
1138 | kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp)); | 1136 | kmem_free(bip->bli_orig, XFS_BUF_COUNT(bp)); |
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index d7e136143066..5a41c348bb1c 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef __XFS_BUF_ITEM_H__ | 18 | #ifndef __XFS_BUF_ITEM_H__ |
19 | #define __XFS_BUF_ITEM_H__ | 19 | #define __XFS_BUF_ITEM_H__ |
20 | 20 | ||
21 | extern kmem_zone_t *xfs_buf_item_zone; | ||
22 | |||
21 | /* | 23 | /* |
22 | * This is the structure used to lay out a buf log item in the | 24 | * This is the structure used to lay out a buf log item in the |
23 | * log. The data map describes which 128 byte chunks of the buffer | 25 | * log. The data map describes which 128 byte chunks of the buffer |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 26d09e2e1a7f..1b446849fb3d 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -2218,7 +2218,7 @@ xfs_da_state_free(xfs_da_state_t *state) | |||
2218 | 2218 | ||
2219 | #ifdef XFS_DABUF_DEBUG | 2219 | #ifdef XFS_DABUF_DEBUG |
2220 | xfs_dabuf_t *xfs_dabuf_global_list; | 2220 | xfs_dabuf_t *xfs_dabuf_global_list; |
2221 | lock_t xfs_dabuf_global_lock; | 2221 | spinlock_t xfs_dabuf_global_lock; |
2222 | #endif | 2222 | #endif |
2223 | 2223 | ||
2224 | /* | 2224 | /* |
@@ -2264,10 +2264,9 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) | |||
2264 | } | 2264 | } |
2265 | #ifdef XFS_DABUF_DEBUG | 2265 | #ifdef XFS_DABUF_DEBUG |
2266 | { | 2266 | { |
2267 | SPLDECL(s); | ||
2268 | xfs_dabuf_t *p; | 2267 | xfs_dabuf_t *p; |
2269 | 2268 | ||
2270 | s = mutex_spinlock(&xfs_dabuf_global_lock); | 2269 | spin_lock(&xfs_dabuf_global_lock); |
2271 | for (p = xfs_dabuf_global_list; p; p = p->next) { | 2270 | for (p = xfs_dabuf_global_list; p; p = p->next) { |
2272 | ASSERT(p->blkno != dabuf->blkno || | 2271 | ASSERT(p->blkno != dabuf->blkno || |
2273 | p->target != dabuf->target); | 2272 | p->target != dabuf->target); |
@@ -2277,7 +2276,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) | |||
2277 | xfs_dabuf_global_list->prev = dabuf; | 2276 | xfs_dabuf_global_list->prev = dabuf; |
2278 | dabuf->next = xfs_dabuf_global_list; | 2277 | dabuf->next = xfs_dabuf_global_list; |
2279 | xfs_dabuf_global_list = dabuf; | 2278 | xfs_dabuf_global_list = dabuf; |
2280 | mutex_spinunlock(&xfs_dabuf_global_lock, s); | 2279 | spin_unlock(&xfs_dabuf_global_lock); |
2281 | } | 2280 | } |
2282 | #endif | 2281 | #endif |
2283 | return dabuf; | 2282 | return dabuf; |
@@ -2319,16 +2318,14 @@ xfs_da_buf_done(xfs_dabuf_t *dabuf) | |||
2319 | kmem_free(dabuf->data, BBTOB(dabuf->bbcount)); | 2318 | kmem_free(dabuf->data, BBTOB(dabuf->bbcount)); |
2320 | #ifdef XFS_DABUF_DEBUG | 2319 | #ifdef XFS_DABUF_DEBUG |
2321 | { | 2320 | { |
2322 | SPLDECL(s); | 2321 | spin_lock(&xfs_dabuf_global_lock); |
2323 | |||
2324 | s = mutex_spinlock(&xfs_dabuf_global_lock); | ||
2325 | if (dabuf->prev) | 2322 | if (dabuf->prev) |
2326 | dabuf->prev->next = dabuf->next; | 2323 | dabuf->prev->next = dabuf->next; |
2327 | else | 2324 | else |
2328 | xfs_dabuf_global_list = dabuf->next; | 2325 | xfs_dabuf_global_list = dabuf->next; |
2329 | if (dabuf->next) | 2326 | if (dabuf->next) |
2330 | dabuf->next->prev = dabuf->prev; | 2327 | dabuf->next->prev = dabuf->prev; |
2331 | mutex_spinunlock(&xfs_dabuf_global_lock, s); | 2328 | spin_unlock(&xfs_dabuf_global_lock); |
2332 | } | 2329 | } |
2333 | memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); | 2330 | memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf)); |
2334 | #endif | 2331 | #endif |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 44dabf02f2a3..7facf86f74f9 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -260,6 +260,7 @@ void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); | |||
260 | xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); | 260 | xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); |
261 | 261 | ||
262 | extern struct kmem_zone *xfs_da_state_zone; | 262 | extern struct kmem_zone *xfs_da_state_zone; |
263 | extern struct kmem_zone *xfs_dabuf_zone; | ||
263 | #endif /* __KERNEL__ */ | 264 | #endif /* __KERNEL__ */ |
264 | 265 | ||
265 | #endif /* __XFS_DA_BTREE_H__ */ | 266 | #endif /* __XFS_DA_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 584f1ae85cd9..3f53fad356a3 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -52,76 +52,72 @@ xfs_swapext( | |||
52 | xfs_swapext_t __user *sxu) | 52 | xfs_swapext_t __user *sxu) |
53 | { | 53 | { |
54 | xfs_swapext_t *sxp; | 54 | xfs_swapext_t *sxp; |
55 | xfs_inode_t *ip=NULL, *tip=NULL; | 55 | xfs_inode_t *ip, *tip; |
56 | xfs_mount_t *mp; | 56 | struct file *file, *target_file; |
57 | struct file *fp = NULL, *tfp = NULL; | ||
58 | bhv_vnode_t *vp, *tvp; | ||
59 | int error = 0; | 57 | int error = 0; |
60 | 58 | ||
61 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); | 59 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); |
62 | if (!sxp) { | 60 | if (!sxp) { |
63 | error = XFS_ERROR(ENOMEM); | 61 | error = XFS_ERROR(ENOMEM); |
64 | goto error0; | 62 | goto out; |
65 | } | 63 | } |
66 | 64 | ||
67 | if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) { | 65 | if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) { |
68 | error = XFS_ERROR(EFAULT); | 66 | error = XFS_ERROR(EFAULT); |
69 | goto error0; | 67 | goto out_free_sxp; |
70 | } | 68 | } |
71 | 69 | ||
72 | /* Pull information for the target fd */ | 70 | /* Pull information for the target fd */ |
73 | if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) || | 71 | file = fget((int)sxp->sx_fdtarget); |
74 | ((vp = vn_from_inode(fp->f_path.dentry->d_inode)) == NULL)) { | 72 | if (!file) { |
75 | error = XFS_ERROR(EINVAL); | 73 | error = XFS_ERROR(EINVAL); |
76 | goto error0; | 74 | goto out_free_sxp; |
77 | } | 75 | } |
78 | 76 | ||
79 | ip = xfs_vtoi(vp); | 77 | if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { |
80 | if (ip == NULL) { | ||
81 | error = XFS_ERROR(EBADF); | 78 | error = XFS_ERROR(EBADF); |
82 | goto error0; | 79 | goto out_put_file; |
83 | } | 80 | } |
84 | 81 | ||
85 | if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) || | 82 | target_file = fget((int)sxp->sx_fdtmp); |
86 | ((tvp = vn_from_inode(tfp->f_path.dentry->d_inode)) == NULL)) { | 83 | if (!target_file) { |
87 | error = XFS_ERROR(EINVAL); | 84 | error = XFS_ERROR(EINVAL); |
88 | goto error0; | 85 | goto out_put_file; |
89 | } | 86 | } |
90 | 87 | ||
91 | tip = xfs_vtoi(tvp); | 88 | if (!(target_file->f_mode & FMODE_WRITE) || |
92 | if (tip == NULL) { | 89 | (target_file->f_flags & O_APPEND)) { |
93 | error = XFS_ERROR(EBADF); | 90 | error = XFS_ERROR(EBADF); |
94 | goto error0; | 91 | goto out_put_target_file; |
95 | } | 92 | } |
96 | 93 | ||
94 | ip = XFS_I(file->f_path.dentry->d_inode); | ||
95 | tip = XFS_I(target_file->f_path.dentry->d_inode); | ||
96 | |||
97 | if (ip->i_mount != tip->i_mount) { | 97 | if (ip->i_mount != tip->i_mount) { |
98 | error = XFS_ERROR(EINVAL); | 98 | error = XFS_ERROR(EINVAL); |
99 | goto error0; | 99 | goto out_put_target_file; |
100 | } | 100 | } |
101 | 101 | ||
102 | if (ip->i_ino == tip->i_ino) { | 102 | if (ip->i_ino == tip->i_ino) { |
103 | error = XFS_ERROR(EINVAL); | 103 | error = XFS_ERROR(EINVAL); |
104 | goto error0; | 104 | goto out_put_target_file; |
105 | } | 105 | } |
106 | 106 | ||
107 | mp = ip->i_mount; | 107 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
108 | 108 | error = XFS_ERROR(EIO); | |
109 | if (XFS_FORCED_SHUTDOWN(mp)) { | 109 | goto out_put_target_file; |
110 | error = XFS_ERROR(EIO); | ||
111 | goto error0; | ||
112 | } | 110 | } |
113 | 111 | ||
114 | error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp); | 112 | error = xfs_swap_extents(ip, tip, sxp); |
115 | |||
116 | error0: | ||
117 | if (fp != NULL) | ||
118 | fput(fp); | ||
119 | if (tfp != NULL) | ||
120 | fput(tfp); | ||
121 | |||
122 | if (sxp != NULL) | ||
123 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
124 | 113 | ||
114 | out_put_target_file: | ||
115 | fput(target_file); | ||
116 | out_put_file: | ||
117 | fput(file); | ||
118 | out_free_sxp: | ||
119 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
120 | out: | ||
125 | return error; | 121 | return error; |
126 | } | 122 | } |
127 | 123 | ||
@@ -169,15 +165,6 @@ xfs_swap_extents( | |||
169 | xfs_lock_inodes(ips, 2, 0, lock_flags); | 165 | xfs_lock_inodes(ips, 2, 0, lock_flags); |
170 | locked = 1; | 166 | locked = 1; |
171 | 167 | ||
172 | /* Check permissions */ | ||
173 | error = xfs_iaccess(ip, S_IWUSR, NULL); | ||
174 | if (error) | ||
175 | goto error0; | ||
176 | |||
177 | error = xfs_iaccess(tip, S_IWUSR, NULL); | ||
178 | if (error) | ||
179 | goto error0; | ||
180 | |||
181 | /* Verify that both files have the same format */ | 168 | /* Verify that both files have the same format */ |
182 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { | 169 | if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { |
183 | error = XFS_ERROR(EINVAL); | 170 | error = XFS_ERROR(EINVAL); |
@@ -185,8 +172,7 @@ xfs_swap_extents( | |||
185 | } | 172 | } |
186 | 173 | ||
187 | /* Verify both files are either real-time or non-realtime */ | 174 | /* Verify both files are either real-time or non-realtime */ |
188 | if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != | 175 | if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) { |
189 | (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | ||
190 | error = XFS_ERROR(EINVAL); | 176 | error = XFS_ERROR(EINVAL); |
191 | goto error0; | 177 | goto error0; |
192 | } | 178 | } |
@@ -199,7 +185,7 @@ xfs_swap_extents( | |||
199 | } | 185 | } |
200 | 186 | ||
201 | if (VN_CACHED(tvp) != 0) { | 187 | if (VN_CACHED(tvp) != 0) { |
202 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); | 188 | xfs_inval_cached_trace(tip, 0, -1, 0, -1); |
203 | error = xfs_flushinval_pages(tip, 0, -1, | 189 | error = xfs_flushinval_pages(tip, 0, -1, |
204 | FI_REMAPF_LOCKED); | 190 | FI_REMAPF_LOCKED); |
205 | if (error) | 191 | if (error) |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index dedd713574e1..c9065eaf2a4d 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -171,69 +171,35 @@ typedef enum xfs_dinode_fmt | |||
171 | /* | 171 | /* |
172 | * Inode data & attribute fork sizes, per inode. | 172 | * Inode data & attribute fork sizes, per inode. |
173 | */ | 173 | */ |
174 | #define XFS_CFORK_Q(dcp) ((dcp)->di_forkoff != 0) | 174 | #define XFS_DFORK_Q(dip) ((dip)->di_core.di_forkoff != 0) |
175 | #define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0) | 175 | #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_core.di_forkoff << 3)) |
176 | |||
177 | #define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3)) | ||
178 | #define XFS_CFORK_BOFF_DISK(dcp) ((int)((dcp)->di_forkoff << 3)) | ||
179 | |||
180 | #define XFS_CFORK_DSIZE_DISK(dcp,mp) \ | ||
181 | (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp)) | ||
182 | #define XFS_CFORK_DSIZE(dcp,mp) \ | ||
183 | (XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp)) | ||
184 | |||
185 | #define XFS_CFORK_ASIZE_DISK(dcp,mp) \ | ||
186 | (XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0) | ||
187 | #define XFS_CFORK_ASIZE(dcp,mp) \ | ||
188 | (XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0) | ||
189 | |||
190 | #define XFS_CFORK_SIZE_DISK(dcp,mp,w) \ | ||
191 | ((w) == XFS_DATA_FORK ? \ | ||
192 | XFS_CFORK_DSIZE_DISK(dcp, mp) : \ | ||
193 | XFS_CFORK_ASIZE_DISK(dcp, mp)) | ||
194 | #define XFS_CFORK_SIZE(dcp,mp,w) \ | ||
195 | ((w) == XFS_DATA_FORK ? \ | ||
196 | XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp)) | ||
197 | 176 | ||
198 | #define XFS_DFORK_DSIZE(dip,mp) \ | 177 | #define XFS_DFORK_DSIZE(dip,mp) \ |
199 | XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp) | 178 | (XFS_DFORK_Q(dip) ? \ |
200 | #define XFS_DFORK_DSIZE_HOST(dip,mp) \ | 179 | XFS_DFORK_BOFF(dip) : \ |
201 | XFS_CFORK_DSIZE(&(dip)->di_core, mp) | 180 | XFS_LITINO(mp)) |
202 | #define XFS_DFORK_ASIZE(dip,mp) \ | 181 | #define XFS_DFORK_ASIZE(dip,mp) \ |
203 | XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp) | 182 | (XFS_DFORK_Q(dip) ? \ |
204 | #define XFS_DFORK_ASIZE_HOST(dip,mp) \ | 183 | XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \ |
205 | XFS_CFORK_ASIZE(&(dip)->di_core, mp) | 184 | 0) |
206 | #define XFS_DFORK_SIZE(dip,mp,w) \ | 185 | #define XFS_DFORK_SIZE(dip,mp,w) \ |
207 | XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w) | 186 | ((w) == XFS_DATA_FORK ? \ |
208 | #define XFS_DFORK_SIZE_HOST(dip,mp,w) \ | 187 | XFS_DFORK_DSIZE(dip, mp) : \ |
209 | XFS_CFORK_SIZE(&(dip)->di_core, mp, w) | 188 | XFS_DFORK_ASIZE(dip, mp)) |
210 | 189 | ||
211 | #define XFS_DFORK_Q(dip) XFS_CFORK_Q_DISK(&(dip)->di_core) | 190 | #define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c) |
212 | #define XFS_DFORK_BOFF(dip) XFS_CFORK_BOFF_DISK(&(dip)->di_core) | 191 | #define XFS_DFORK_APTR(dip) \ |
213 | #define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c) | ||
214 | #define XFS_DFORK_APTR(dip) \ | ||
215 | ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip)) | 192 | ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip)) |
216 | #define XFS_DFORK_PTR(dip,w) \ | 193 | #define XFS_DFORK_PTR(dip,w) \ |
217 | ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip)) | 194 | ((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip)) |
218 | #define XFS_CFORK_FORMAT(dcp,w) \ | 195 | #define XFS_DFORK_FORMAT(dip,w) \ |
219 | ((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat) | ||
220 | #define XFS_CFORK_FMT_SET(dcp,w,n) \ | ||
221 | ((w) == XFS_DATA_FORK ? \ | 196 | ((w) == XFS_DATA_FORK ? \ |
222 | ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n))) | 197 | (dip)->di_core.di_format : \ |
223 | #define XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w) | 198 | (dip)->di_core.di_aformat) |
224 | 199 | #define XFS_DFORK_NEXTENTS(dip,w) \ | |
225 | #define XFS_CFORK_NEXTENTS_DISK(dcp,w) \ | ||
226 | ((w) == XFS_DATA_FORK ? \ | 200 | ((w) == XFS_DATA_FORK ? \ |
227 | be32_to_cpu((dcp)->di_nextents) : \ | 201 | be32_to_cpu((dip)->di_core.di_nextents) : \ |
228 | be16_to_cpu((dcp)->di_anextents)) | 202 | be16_to_cpu((dip)->di_core.di_anextents)) |
229 | #define XFS_CFORK_NEXTENTS(dcp,w) \ | ||
230 | ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents) | ||
231 | #define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w) | ||
232 | #define XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w) | ||
233 | |||
234 | #define XFS_CFORK_NEXT_SET(dcp,w,n) \ | ||
235 | ((w) == XFS_DATA_FORK ? \ | ||
236 | ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n))) | ||
237 | 203 | ||
238 | #define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) | 204 | #define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) |
239 | 205 | ||
@@ -273,6 +239,12 @@ typedef enum xfs_dinode_fmt | |||
273 | #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) | 239 | #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) |
274 | #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) | 240 | #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) |
275 | 241 | ||
242 | #ifdef CONFIG_XFS_RT | ||
243 | #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) | ||
244 | #else | ||
245 | #define XFS_IS_REALTIME_INODE(ip) (0) | ||
246 | #endif | ||
247 | |||
276 | #define XFS_DIFLAG_ANY \ | 248 | #define XFS_DIFLAG_ANY \ |
277 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ | 249 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ |
278 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ | 250 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index b0f1ee8fcb90..be7c4251fa61 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "xfs_dir2_node.h" | 42 | #include "xfs_dir2_node.h" |
43 | #include "xfs_dir2_trace.h" | 43 | #include "xfs_dir2_trace.h" |
44 | #include "xfs_error.h" | 44 | #include "xfs_error.h" |
45 | #include "xfs_vnodeops.h" | ||
45 | 46 | ||
46 | 47 | ||
47 | void | 48 | void |
@@ -301,7 +302,7 @@ xfs_readdir( | |||
301 | int rval; /* return value */ | 302 | int rval; /* return value */ |
302 | int v; /* type-checking value */ | 303 | int v; /* type-checking value */ |
303 | 304 | ||
304 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 305 | xfs_itrace_entry(dp); |
305 | 306 | ||
306 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 307 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
307 | return XFS_ERROR(EIO); | 308 | return XFS_ERROR(EIO); |
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index a4634d94e561..05e5365d3c31 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c | |||
@@ -230,37 +230,6 @@ xfs_error_report( | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | STATIC void | ||
234 | xfs_hex_dump(void *p, int length) | ||
235 | { | ||
236 | __uint8_t *uip = (__uint8_t*)p; | ||
237 | int i; | ||
238 | char sbuf[128], *s; | ||
239 | |||
240 | s = sbuf; | ||
241 | *s = '\0'; | ||
242 | for (i=0; i<length; i++, uip++) { | ||
243 | if ((i % 16) == 0) { | ||
244 | if (*s != '\0') | ||
245 | cmn_err(CE_ALERT, "%s\n", sbuf); | ||
246 | s = sbuf; | ||
247 | sprintf(s, "0x%x: ", i); | ||
248 | while( *s != '\0') | ||
249 | s++; | ||
250 | } | ||
251 | sprintf(s, "%02x ", *uip); | ||
252 | |||
253 | /* | ||
254 | * the kernel sprintf is a void; user sprintf returns | ||
255 | * the sprintf'ed string's length. Find the new end- | ||
256 | * of-string | ||
257 | */ | ||
258 | while( *s != '\0') | ||
259 | s++; | ||
260 | } | ||
261 | cmn_err(CE_ALERT, "%s\n", sbuf); | ||
262 | } | ||
263 | |||
264 | void | 233 | void |
265 | xfs_corruption_error( | 234 | xfs_corruption_error( |
266 | char *tag, | 235 | char *tag, |
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index 10e9d9619ae5..6490d2a9f8e1 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h | |||
@@ -174,6 +174,8 @@ extern void xfs_cmn_err(int panic_tag, int level, struct xfs_mount *mp, | |||
174 | /* PRINTFLIKE3 */ | 174 | /* PRINTFLIKE3 */ |
175 | extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...); | 175 | extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...); |
176 | 176 | ||
177 | extern void xfs_hex_dump(void *p, int length); | ||
178 | |||
177 | #define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \ | 179 | #define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \ |
178 | xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args) | 180 | xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args) |
179 | 181 | ||
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index f938a51be81b..132bd07b9bb8 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -110,19 +110,18 @@ STATIC void | |||
110 | xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) | 110 | xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) |
111 | { | 111 | { |
112 | xfs_mount_t *mp; | 112 | xfs_mount_t *mp; |
113 | SPLDECL(s); | ||
114 | 113 | ||
115 | mp = efip->efi_item.li_mountp; | 114 | mp = efip->efi_item.li_mountp; |
116 | AIL_LOCK(mp, s); | 115 | spin_lock(&mp->m_ail_lock); |
117 | if (efip->efi_flags & XFS_EFI_CANCELED) { | 116 | if (efip->efi_flags & XFS_EFI_CANCELED) { |
118 | /* | 117 | /* |
119 | * xfs_trans_delete_ail() drops the AIL lock. | 118 | * xfs_trans_delete_ail() drops the AIL lock. |
120 | */ | 119 | */ |
121 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); | 120 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip); |
122 | xfs_efi_item_free(efip); | 121 | xfs_efi_item_free(efip); |
123 | } else { | 122 | } else { |
124 | efip->efi_flags |= XFS_EFI_COMMITTED; | 123 | efip->efi_flags |= XFS_EFI_COMMITTED; |
125 | AIL_UNLOCK(mp, s); | 124 | spin_unlock(&mp->m_ail_lock); |
126 | } | 125 | } |
127 | } | 126 | } |
128 | 127 | ||
@@ -138,10 +137,9 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) | |||
138 | { | 137 | { |
139 | xfs_mount_t *mp; | 138 | xfs_mount_t *mp; |
140 | xfs_log_item_desc_t *lidp; | 139 | xfs_log_item_desc_t *lidp; |
141 | SPLDECL(s); | ||
142 | 140 | ||
143 | mp = efip->efi_item.li_mountp; | 141 | mp = efip->efi_item.li_mountp; |
144 | AIL_LOCK(mp, s); | 142 | spin_lock(&mp->m_ail_lock); |
145 | if (efip->efi_flags & XFS_EFI_CANCELED) { | 143 | if (efip->efi_flags & XFS_EFI_CANCELED) { |
146 | /* | 144 | /* |
147 | * free the xaction descriptor pointing to this item | 145 | * free the xaction descriptor pointing to this item |
@@ -152,11 +150,11 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) | |||
152 | * pull the item off the AIL. | 150 | * pull the item off the AIL. |
153 | * xfs_trans_delete_ail() drops the AIL lock. | 151 | * xfs_trans_delete_ail() drops the AIL lock. |
154 | */ | 152 | */ |
155 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); | 153 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip); |
156 | xfs_efi_item_free(efip); | 154 | xfs_efi_item_free(efip); |
157 | } else { | 155 | } else { |
158 | efip->efi_flags |= XFS_EFI_COMMITTED; | 156 | efip->efi_flags |= XFS_EFI_COMMITTED; |
159 | AIL_UNLOCK(mp, s); | 157 | spin_unlock(&mp->m_ail_lock); |
160 | } | 158 | } |
161 | } | 159 | } |
162 | 160 | ||
@@ -350,13 +348,12 @@ xfs_efi_release(xfs_efi_log_item_t *efip, | |||
350 | { | 348 | { |
351 | xfs_mount_t *mp; | 349 | xfs_mount_t *mp; |
352 | int extents_left; | 350 | int extents_left; |
353 | SPLDECL(s); | ||
354 | 351 | ||
355 | mp = efip->efi_item.li_mountp; | 352 | mp = efip->efi_item.li_mountp; |
356 | ASSERT(efip->efi_next_extent > 0); | 353 | ASSERT(efip->efi_next_extent > 0); |
357 | ASSERT(efip->efi_flags & XFS_EFI_COMMITTED); | 354 | ASSERT(efip->efi_flags & XFS_EFI_COMMITTED); |
358 | 355 | ||
359 | AIL_LOCK(mp, s); | 356 | spin_lock(&mp->m_ail_lock); |
360 | ASSERT(efip->efi_next_extent >= nextents); | 357 | ASSERT(efip->efi_next_extent >= nextents); |
361 | efip->efi_next_extent -= nextents; | 358 | efip->efi_next_extent -= nextents; |
362 | extents_left = efip->efi_next_extent; | 359 | extents_left = efip->efi_next_extent; |
@@ -364,10 +361,10 @@ xfs_efi_release(xfs_efi_log_item_t *efip, | |||
364 | /* | 361 | /* |
365 | * xfs_trans_delete_ail() drops the AIL lock. | 362 | * xfs_trans_delete_ail() drops the AIL lock. |
366 | */ | 363 | */ |
367 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); | 364 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip); |
368 | xfs_efi_item_free(efip); | 365 | xfs_efi_item_free(efip); |
369 | } else { | 366 | } else { |
370 | AIL_UNLOCK(mp, s); | 367 | spin_unlock(&mp->m_ail_lock); |
371 | } | 368 | } |
372 | } | 369 | } |
373 | 370 | ||
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 36d8f6aa11af..eb03eab5ca52 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c | |||
@@ -348,7 +348,7 @@ _xfs_filestream_update_ag( | |||
348 | } | 348 | } |
349 | 349 | ||
350 | /* xfs_fstrm_free_func(): callback for freeing cached stream items. */ | 350 | /* xfs_fstrm_free_func(): callback for freeing cached stream items. */ |
351 | void | 351 | STATIC void |
352 | xfs_fstrm_free_func( | 352 | xfs_fstrm_free_func( |
353 | unsigned long ino, | 353 | unsigned long ino, |
354 | void *data) | 354 | void *data) |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index aab966276517..3bed6433d050 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -419,9 +419,13 @@ typedef struct xfs_handle { | |||
419 | /* | 419 | /* |
420 | * ioctl commands that are used by Linux filesystems | 420 | * ioctl commands that are used by Linux filesystems |
421 | */ | 421 | */ |
422 | #define XFS_IOC_GETXFLAGS _IOR('f', 1, long) | 422 | #define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS |
423 | #define XFS_IOC_SETXFLAGS _IOW('f', 2, long) | 423 | #define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS |
424 | #define XFS_IOC_GETVERSION _IOR('v', 1, long) | 424 | #define XFS_IOC_GETVERSION FS_IOC_GETVERSION |
425 | /* 32-bit compat counterparts */ | ||
426 | #define XFS_IOC32_GETXFLAGS FS_IOC32_GETFLAGS | ||
427 | #define XFS_IOC32_SETXFLAGS FS_IOC32_SETFLAGS | ||
428 | #define XFS_IOC32_GETVERSION FS_IOC32_GETVERSION | ||
425 | 429 | ||
426 | /* | 430 | /* |
427 | * ioctl commands that replace IRIX fcntl()'s | 431 | * ioctl commands that replace IRIX fcntl()'s |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index c92d5b821029..b8de7f3cc17e 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -462,15 +462,13 @@ xfs_fs_counts( | |||
462 | xfs_mount_t *mp, | 462 | xfs_mount_t *mp, |
463 | xfs_fsop_counts_t *cnt) | 463 | xfs_fsop_counts_t *cnt) |
464 | { | 464 | { |
465 | unsigned long s; | ||
466 | |||
467 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); | 465 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); |
468 | s = XFS_SB_LOCK(mp); | 466 | spin_lock(&mp->m_sb_lock); |
469 | cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 467 | cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
470 | cnt->freertx = mp->m_sb.sb_frextents; | 468 | cnt->freertx = mp->m_sb.sb_frextents; |
471 | cnt->freeino = mp->m_sb.sb_ifree; | 469 | cnt->freeino = mp->m_sb.sb_ifree; |
472 | cnt->allocino = mp->m_sb.sb_icount; | 470 | cnt->allocino = mp->m_sb.sb_icount; |
473 | XFS_SB_UNLOCK(mp, s); | 471 | spin_unlock(&mp->m_sb_lock); |
474 | return 0; | 472 | return 0; |
475 | } | 473 | } |
476 | 474 | ||
@@ -497,7 +495,6 @@ xfs_reserve_blocks( | |||
497 | { | 495 | { |
498 | __int64_t lcounter, delta, fdblks_delta; | 496 | __int64_t lcounter, delta, fdblks_delta; |
499 | __uint64_t request; | 497 | __uint64_t request; |
500 | unsigned long s; | ||
501 | 498 | ||
502 | /* If inval is null, report current values and return */ | 499 | /* If inval is null, report current values and return */ |
503 | if (inval == (__uint64_t *)NULL) { | 500 | if (inval == (__uint64_t *)NULL) { |
@@ -515,7 +512,7 @@ xfs_reserve_blocks( | |||
515 | * problem. we needto work out if we are freeing or allocation | 512 | * problem. we needto work out if we are freeing or allocation |
516 | * blocks first, then we can do the modification as necessary. | 513 | * blocks first, then we can do the modification as necessary. |
517 | * | 514 | * |
518 | * We do this under the XFS_SB_LOCK so that if we are near | 515 | * We do this under the m_sb_lock so that if we are near |
519 | * ENOSPC, we will hold out any changes while we work out | 516 | * ENOSPC, we will hold out any changes while we work out |
520 | * what to do. This means that the amount of free space can | 517 | * what to do. This means that the amount of free space can |
521 | * change while we do this, so we need to retry if we end up | 518 | * change while we do this, so we need to retry if we end up |
@@ -526,7 +523,7 @@ xfs_reserve_blocks( | |||
526 | * enabled, disabled or even compiled in.... | 523 | * enabled, disabled or even compiled in.... |
527 | */ | 524 | */ |
528 | retry: | 525 | retry: |
529 | s = XFS_SB_LOCK(mp); | 526 | spin_lock(&mp->m_sb_lock); |
530 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_SB_LOCKED); | 527 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_SB_LOCKED); |
531 | 528 | ||
532 | /* | 529 | /* |
@@ -569,7 +566,7 @@ out: | |||
569 | outval->resblks = mp->m_resblks; | 566 | outval->resblks = mp->m_resblks; |
570 | outval->resblks_avail = mp->m_resblks_avail; | 567 | outval->resblks_avail = mp->m_resblks_avail; |
571 | } | 568 | } |
572 | XFS_SB_UNLOCK(mp, s); | 569 | spin_unlock(&mp->m_sb_lock); |
573 | 570 | ||
574 | if (fdblks_delta) { | 571 | if (fdblks_delta) { |
575 | /* | 572 | /* |
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index bf8e9aff272e..8efc4a5b8b92 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h | |||
@@ -81,8 +81,6 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t; | |||
81 | #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) | 81 | #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) |
82 | #define XFS_INOBT_IS_FREE(rp,i) \ | 82 | #define XFS_INOBT_IS_FREE(rp,i) \ |
83 | (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) | 83 | (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) |
84 | #define XFS_INOBT_IS_FREE_DISK(rp,i) \ | ||
85 | ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) | ||
86 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) | 84 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) |
87 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) | 85 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) |
88 | 86 | ||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index fb69ef180b27..f01b07687faf 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -65,7 +65,7 @@ | |||
65 | */ | 65 | */ |
66 | STATIC int | 66 | STATIC int |
67 | xfs_iget_core( | 67 | xfs_iget_core( |
68 | bhv_vnode_t *vp, | 68 | struct inode *inode, |
69 | xfs_mount_t *mp, | 69 | xfs_mount_t *mp, |
70 | xfs_trans_t *tp, | 70 | xfs_trans_t *tp, |
71 | xfs_ino_t ino, | 71 | xfs_ino_t ino, |
@@ -74,9 +74,9 @@ xfs_iget_core( | |||
74 | xfs_inode_t **ipp, | 74 | xfs_inode_t **ipp, |
75 | xfs_daddr_t bno) | 75 | xfs_daddr_t bno) |
76 | { | 76 | { |
77 | struct inode *old_inode; | ||
77 | xfs_inode_t *ip; | 78 | xfs_inode_t *ip; |
78 | xfs_inode_t *iq; | 79 | xfs_inode_t *iq; |
79 | bhv_vnode_t *inode_vp; | ||
80 | int error; | 80 | int error; |
81 | xfs_icluster_t *icl, *new_icl = NULL; | 81 | xfs_icluster_t *icl, *new_icl = NULL; |
82 | unsigned long first_index, mask; | 82 | unsigned long first_index, mask; |
@@ -111,8 +111,8 @@ again: | |||
111 | goto again; | 111 | goto again; |
112 | } | 112 | } |
113 | 113 | ||
114 | inode_vp = XFS_ITOV_NULL(ip); | 114 | old_inode = ip->i_vnode; |
115 | if (inode_vp == NULL) { | 115 | if (old_inode == NULL) { |
116 | /* | 116 | /* |
117 | * If IRECLAIM is set this inode is | 117 | * If IRECLAIM is set this inode is |
118 | * on its way out of the system, | 118 | * on its way out of the system, |
@@ -140,28 +140,9 @@ again: | |||
140 | return ENOENT; | 140 | return ENOENT; |
141 | } | 141 | } |
142 | 142 | ||
143 | /* | 143 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
144 | * There may be transactions sitting in the | ||
145 | * incore log buffers or being flushed to disk | ||
146 | * at this time. We can't clear the | ||
147 | * XFS_IRECLAIMABLE flag until these | ||
148 | * transactions have hit the disk, otherwise we | ||
149 | * will void the guarantee the flag provides | ||
150 | * xfs_iunpin() | ||
151 | */ | ||
152 | if (xfs_ipincount(ip)) { | ||
153 | read_unlock(&pag->pag_ici_lock); | ||
154 | xfs_log_force(mp, 0, | ||
155 | XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
156 | XFS_STATS_INC(xs_ig_frecycle); | ||
157 | goto again; | ||
158 | } | ||
159 | |||
160 | vn_trace_exit(ip, "xfs_iget.alloc", | ||
161 | (inst_t *)__return_address); | ||
162 | 144 | ||
163 | XFS_STATS_INC(xs_ig_found); | 145 | XFS_STATS_INC(xs_ig_found); |
164 | |||
165 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); | 146 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); |
166 | read_unlock(&pag->pag_ici_lock); | 147 | read_unlock(&pag->pag_ici_lock); |
167 | 148 | ||
@@ -171,13 +152,11 @@ again: | |||
171 | 152 | ||
172 | goto finish_inode; | 153 | goto finish_inode; |
173 | 154 | ||
174 | } else if (vp != inode_vp) { | 155 | } else if (inode != old_inode) { |
175 | struct inode *inode = vn_to_inode(inode_vp); | ||
176 | |||
177 | /* The inode is being torn down, pause and | 156 | /* The inode is being torn down, pause and |
178 | * try again. | 157 | * try again. |
179 | */ | 158 | */ |
180 | if (inode->i_state & (I_FREEING | I_CLEAR)) { | 159 | if (old_inode->i_state & (I_FREEING | I_CLEAR)) { |
181 | read_unlock(&pag->pag_ici_lock); | 160 | read_unlock(&pag->pag_ici_lock); |
182 | delay(1); | 161 | delay(1); |
183 | XFS_STATS_INC(xs_ig_frecycle); | 162 | XFS_STATS_INC(xs_ig_frecycle); |
@@ -190,7 +169,7 @@ again: | |||
190 | */ | 169 | */ |
191 | cmn_err(CE_PANIC, | 170 | cmn_err(CE_PANIC, |
192 | "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", | 171 | "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", |
193 | inode_vp, vp); | 172 | old_inode, inode); |
194 | } | 173 | } |
195 | 174 | ||
196 | /* | 175 | /* |
@@ -200,20 +179,16 @@ again: | |||
200 | XFS_STATS_INC(xs_ig_found); | 179 | XFS_STATS_INC(xs_ig_found); |
201 | 180 | ||
202 | finish_inode: | 181 | finish_inode: |
203 | if (ip->i_d.di_mode == 0) { | 182 | if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) { |
204 | if (!(flags & XFS_IGET_CREATE)) { | 183 | xfs_put_perag(mp, pag); |
205 | xfs_put_perag(mp, pag); | 184 | return ENOENT; |
206 | return ENOENT; | ||
207 | } | ||
208 | xfs_iocore_inode_reinit(ip); | ||
209 | } | 185 | } |
210 | 186 | ||
211 | if (lock_flags != 0) | 187 | if (lock_flags != 0) |
212 | xfs_ilock(ip, lock_flags); | 188 | xfs_ilock(ip, lock_flags); |
213 | 189 | ||
214 | xfs_iflags_clear(ip, XFS_ISTALE); | 190 | xfs_iflags_clear(ip, XFS_ISTALE); |
215 | vn_trace_exit(ip, "xfs_iget.found", | 191 | xfs_itrace_exit_tag(ip, "xfs_iget.found"); |
216 | (inst_t *)__return_address); | ||
217 | goto return_ip; | 192 | goto return_ip; |
218 | } | 193 | } |
219 | 194 | ||
@@ -234,10 +209,16 @@ finish_inode: | |||
234 | return error; | 209 | return error; |
235 | } | 210 | } |
236 | 211 | ||
237 | vn_trace_exit(ip, "xfs_iget.alloc", (inst_t *)__return_address); | 212 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
213 | |||
214 | |||
215 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | ||
216 | "xfsino", ip->i_ino); | ||
217 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
218 | init_waitqueue_head(&ip->i_ipin_wait); | ||
219 | atomic_set(&ip->i_pincount, 0); | ||
220 | initnsema(&ip->i_flock, 1, "xfsfino"); | ||
238 | 221 | ||
239 | xfs_inode_lock_init(ip, vp); | ||
240 | xfs_iocore_inode_init(ip); | ||
241 | if (lock_flags) | 222 | if (lock_flags) |
242 | xfs_ilock(ip, lock_flags); | 223 | xfs_ilock(ip, lock_flags); |
243 | 224 | ||
@@ -333,9 +314,6 @@ finish_inode: | |||
333 | ASSERT(ip->i_df.if_ext_max == | 314 | ASSERT(ip->i_df.if_ext_max == |
334 | XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t)); | 315 | XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t)); |
335 | 316 | ||
336 | ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) == | ||
337 | ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0)); | ||
338 | |||
339 | xfs_iflags_set(ip, XFS_IMODIFIED); | 317 | xfs_iflags_set(ip, XFS_IMODIFIED); |
340 | *ipp = ip; | 318 | *ipp = ip; |
341 | 319 | ||
@@ -343,7 +321,7 @@ finish_inode: | |||
343 | * If we have a real type for an on-disk inode, we can set ops(&unlock) | 321 | * If we have a real type for an on-disk inode, we can set ops(&unlock) |
344 | * now. If it's a new inode being created, xfs_ialloc will handle it. | 322 | * now. If it's a new inode being created, xfs_ialloc will handle it. |
345 | */ | 323 | */ |
346 | xfs_initialize_vnode(mp, vp, ip); | 324 | xfs_initialize_vnode(mp, inode, ip); |
347 | return 0; | 325 | return 0; |
348 | } | 326 | } |
349 | 327 | ||
@@ -363,69 +341,58 @@ xfs_iget( | |||
363 | xfs_daddr_t bno) | 341 | xfs_daddr_t bno) |
364 | { | 342 | { |
365 | struct inode *inode; | 343 | struct inode *inode; |
366 | bhv_vnode_t *vp = NULL; | 344 | xfs_inode_t *ip; |
367 | int error; | 345 | int error; |
368 | 346 | ||
369 | XFS_STATS_INC(xs_ig_attempts); | 347 | XFS_STATS_INC(xs_ig_attempts); |
370 | 348 | ||
371 | retry: | 349 | retry: |
372 | inode = iget_locked(mp->m_super, ino); | 350 | inode = iget_locked(mp->m_super, ino); |
373 | if (inode) { | 351 | if (!inode) |
374 | xfs_inode_t *ip; | 352 | /* If we got no inode we are out of memory */ |
375 | 353 | return ENOMEM; | |
376 | vp = vn_from_inode(inode); | 354 | |
377 | if (inode->i_state & I_NEW) { | 355 | if (inode->i_state & I_NEW) { |
378 | vn_initialize(inode); | 356 | XFS_STATS_INC(vn_active); |
379 | error = xfs_iget_core(vp, mp, tp, ino, flags, | 357 | XFS_STATS_INC(vn_alloc); |
380 | lock_flags, ipp, bno); | 358 | |
381 | if (error) { | 359 | error = xfs_iget_core(inode, mp, tp, ino, flags, |
382 | vn_mark_bad(vp); | 360 | lock_flags, ipp, bno); |
383 | if (inode->i_state & I_NEW) | 361 | if (error) { |
384 | unlock_new_inode(inode); | 362 | make_bad_inode(inode); |
385 | iput(inode); | 363 | if (inode->i_state & I_NEW) |
386 | } | 364 | unlock_new_inode(inode); |
387 | } else { | 365 | iput(inode); |
388 | /* | ||
389 | * If the inode is not fully constructed due to | ||
390 | * filehandle mismatches wait for the inode to go | ||
391 | * away and try again. | ||
392 | * | ||
393 | * iget_locked will call __wait_on_freeing_inode | ||
394 | * to wait for the inode to go away. | ||
395 | */ | ||
396 | if (is_bad_inode(inode) || | ||
397 | ((ip = xfs_vtoi(vp)) == NULL)) { | ||
398 | iput(inode); | ||
399 | delay(1); | ||
400 | goto retry; | ||
401 | } | ||
402 | |||
403 | if (lock_flags != 0) | ||
404 | xfs_ilock(ip, lock_flags); | ||
405 | XFS_STATS_INC(xs_ig_found); | ||
406 | *ipp = ip; | ||
407 | error = 0; | ||
408 | } | 366 | } |
409 | } else | 367 | return error; |
410 | error = ENOMEM; /* If we got no inode we are out of memory */ | 368 | } |
411 | 369 | ||
412 | return error; | 370 | /* |
413 | } | 371 | * If the inode is not fully constructed due to |
372 | * filehandle mismatches wait for the inode to go | ||
373 | * away and try again. | ||
374 | * | ||
375 | * iget_locked will call __wait_on_freeing_inode | ||
376 | * to wait for the inode to go away. | ||
377 | */ | ||
378 | if (is_bad_inode(inode)) { | ||
379 | iput(inode); | ||
380 | delay(1); | ||
381 | goto retry; | ||
382 | } | ||
414 | 383 | ||
415 | /* | 384 | ip = XFS_I(inode); |
416 | * Do the setup for the various locks within the incore inode. | 385 | if (!ip) { |
417 | */ | 386 | iput(inode); |
418 | void | 387 | delay(1); |
419 | xfs_inode_lock_init( | 388 | goto retry; |
420 | xfs_inode_t *ip, | 389 | } |
421 | bhv_vnode_t *vp) | 390 | |
422 | { | 391 | if (lock_flags != 0) |
423 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 392 | xfs_ilock(ip, lock_flags); |
424 | "xfsino", ip->i_ino); | 393 | XFS_STATS_INC(xs_ig_found); |
425 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | 394 | *ipp = ip; |
426 | init_waitqueue_head(&ip->i_ipin_wait); | 395 | return 0; |
427 | atomic_set(&ip->i_pincount, 0); | ||
428 | initnsema(&ip->i_flock, 1, "xfsfino"); | ||
429 | } | 396 | } |
430 | 397 | ||
431 | /* | 398 | /* |
@@ -465,11 +432,9 @@ void | |||
465 | xfs_iput(xfs_inode_t *ip, | 432 | xfs_iput(xfs_inode_t *ip, |
466 | uint lock_flags) | 433 | uint lock_flags) |
467 | { | 434 | { |
468 | bhv_vnode_t *vp = XFS_ITOV(ip); | 435 | xfs_itrace_entry(ip); |
469 | |||
470 | vn_trace_entry(ip, "xfs_iput", (inst_t *)__return_address); | ||
471 | xfs_iunlock(ip, lock_flags); | 436 | xfs_iunlock(ip, lock_flags); |
472 | VN_RELE(vp); | 437 | IRELE(ip); |
473 | } | 438 | } |
474 | 439 | ||
475 | /* | 440 | /* |
@@ -479,20 +444,19 @@ void | |||
479 | xfs_iput_new(xfs_inode_t *ip, | 444 | xfs_iput_new(xfs_inode_t *ip, |
480 | uint lock_flags) | 445 | uint lock_flags) |
481 | { | 446 | { |
482 | bhv_vnode_t *vp = XFS_ITOV(ip); | 447 | struct inode *inode = ip->i_vnode; |
483 | struct inode *inode = vn_to_inode(vp); | ||
484 | 448 | ||
485 | vn_trace_entry(ip, "xfs_iput_new", (inst_t *)__return_address); | 449 | xfs_itrace_entry(ip); |
486 | 450 | ||
487 | if ((ip->i_d.di_mode == 0)) { | 451 | if ((ip->i_d.di_mode == 0)) { |
488 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | 452 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
489 | vn_mark_bad(vp); | 453 | make_bad_inode(inode); |
490 | } | 454 | } |
491 | if (inode->i_state & I_NEW) | 455 | if (inode->i_state & I_NEW) |
492 | unlock_new_inode(inode); | 456 | unlock_new_inode(inode); |
493 | if (lock_flags) | 457 | if (lock_flags) |
494 | xfs_iunlock(ip, lock_flags); | 458 | xfs_iunlock(ip, lock_flags); |
495 | VN_RELE(vp); | 459 | IRELE(ip); |
496 | } | 460 | } |
497 | 461 | ||
498 | 462 | ||
@@ -505,8 +469,6 @@ xfs_iput_new(xfs_inode_t *ip, | |||
505 | void | 469 | void |
506 | xfs_ireclaim(xfs_inode_t *ip) | 470 | xfs_ireclaim(xfs_inode_t *ip) |
507 | { | 471 | { |
508 | bhv_vnode_t *vp; | ||
509 | |||
510 | /* | 472 | /* |
511 | * Remove from old hash list and mount list. | 473 | * Remove from old hash list and mount list. |
512 | */ | 474 | */ |
@@ -535,9 +497,8 @@ xfs_ireclaim(xfs_inode_t *ip) | |||
535 | /* | 497 | /* |
536 | * Pull our behavior descriptor from the vnode chain. | 498 | * Pull our behavior descriptor from the vnode chain. |
537 | */ | 499 | */ |
538 | vp = XFS_ITOV_NULL(ip); | 500 | if (ip->i_vnode) { |
539 | if (vp) { | 501 | ip->i_vnode->i_private = NULL; |
540 | vn_to_inode(vp)->i_private = NULL; | ||
541 | ip->i_vnode = NULL; | 502 | ip->i_vnode = NULL; |
542 | } | 503 | } |
543 | 504 | ||
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 344948082819..a550546a7083 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -15,6 +15,8 @@ | |||
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #include <linux/log2.h> | ||
19 | |||
18 | #include "xfs.h" | 20 | #include "xfs.h" |
19 | #include "xfs_fs.h" | 21 | #include "xfs_fs.h" |
20 | #include "xfs_types.h" | 22 | #include "xfs_types.h" |
@@ -826,15 +828,17 @@ xfs_ip2xflags( | |||
826 | xfs_icdinode_t *dic = &ip->i_d; | 828 | xfs_icdinode_t *dic = &ip->i_d; |
827 | 829 | ||
828 | return _xfs_dic2xflags(dic->di_flags) | | 830 | return _xfs_dic2xflags(dic->di_flags) | |
829 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); | 831 | (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0); |
830 | } | 832 | } |
831 | 833 | ||
832 | uint | 834 | uint |
833 | xfs_dic2xflags( | 835 | xfs_dic2xflags( |
834 | xfs_dinode_core_t *dic) | 836 | xfs_dinode_t *dip) |
835 | { | 837 | { |
838 | xfs_dinode_core_t *dic = &dip->di_core; | ||
839 | |||
836 | return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) | | 840 | return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) | |
837 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); | 841 | (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); |
838 | } | 842 | } |
839 | 843 | ||
840 | /* | 844 | /* |
@@ -884,8 +888,8 @@ xfs_iread( | |||
884 | * Initialize inode's trace buffers. | 888 | * Initialize inode's trace buffers. |
885 | * Do this before xfs_iformat in case it adds entries. | 889 | * Do this before xfs_iformat in case it adds entries. |
886 | */ | 890 | */ |
887 | #ifdef XFS_VNODE_TRACE | 891 | #ifdef XFS_INODE_TRACE |
888 | ip->i_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); | 892 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_SLEEP); |
889 | #endif | 893 | #endif |
890 | #ifdef XFS_BMAP_TRACE | 894 | #ifdef XFS_BMAP_TRACE |
891 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); | 895 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); |
@@ -1220,10 +1224,8 @@ xfs_ialloc( | |||
1220 | ip->i_d.di_extsize = pip->i_d.di_extsize; | 1224 | ip->i_d.di_extsize = pip->i_d.di_extsize; |
1221 | } | 1225 | } |
1222 | } else if ((mode & S_IFMT) == S_IFREG) { | 1226 | } else if ((mode & S_IFMT) == S_IFREG) { |
1223 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | 1227 | if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) |
1224 | di_flags |= XFS_DIFLAG_REALTIME; | 1228 | di_flags |= XFS_DIFLAG_REALTIME; |
1225 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; | ||
1226 | } | ||
1227 | if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { | 1229 | if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { |
1228 | di_flags |= XFS_DIFLAG_EXTSIZE; | 1230 | di_flags |= XFS_DIFLAG_EXTSIZE; |
1229 | ip->i_d.di_extsize = pip->i_d.di_extsize; | 1231 | ip->i_d.di_extsize = pip->i_d.di_extsize; |
@@ -1298,7 +1300,10 @@ xfs_isize_check( | |||
1298 | if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) | 1300 | if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) |
1299 | return; | 1301 | return; |
1300 | 1302 | ||
1301 | if (ip->i_d.di_flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_EXTSIZE)) | 1303 | if (XFS_IS_REALTIME_INODE(ip)) |
1304 | return; | ||
1305 | |||
1306 | if (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
1302 | return; | 1307 | return; |
1303 | 1308 | ||
1304 | nimaps = 2; | 1309 | nimaps = 2; |
@@ -1711,7 +1716,7 @@ xfs_itruncate_finish( | |||
1711 | * runs. | 1716 | * runs. |
1712 | */ | 1717 | */ |
1713 | XFS_BMAP_INIT(&free_list, &first_block); | 1718 | XFS_BMAP_INIT(&free_list, &first_block); |
1714 | error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore, | 1719 | error = xfs_bunmapi(ntp, ip, |
1715 | first_unmap_block, unmap_len, | 1720 | first_unmap_block, unmap_len, |
1716 | XFS_BMAPI_AFLAG(fork) | | 1721 | XFS_BMAPI_AFLAG(fork) | |
1717 | (sync ? 0 : XFS_BMAPI_ASYNC), | 1722 | (sync ? 0 : XFS_BMAPI_ASYNC), |
@@ -1844,8 +1849,6 @@ xfs_igrow_start( | |||
1844 | xfs_fsize_t new_size, | 1849 | xfs_fsize_t new_size, |
1845 | cred_t *credp) | 1850 | cred_t *credp) |
1846 | { | 1851 | { |
1847 | int error; | ||
1848 | |||
1849 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1852 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); |
1850 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | 1853 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); |
1851 | ASSERT(new_size > ip->i_size); | 1854 | ASSERT(new_size > ip->i_size); |
@@ -1855,9 +1858,7 @@ xfs_igrow_start( | |||
1855 | * xfs_write_file() beyond the end of the file | 1858 | * xfs_write_file() beyond the end of the file |
1856 | * and any blocks between the old and new file sizes. | 1859 | * and any blocks between the old and new file sizes. |
1857 | */ | 1860 | */ |
1858 | error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, | 1861 | return xfs_zero_eof(ip, new_size, ip->i_size); |
1859 | ip->i_size); | ||
1860 | return error; | ||
1861 | } | 1862 | } |
1862 | 1863 | ||
1863 | /* | 1864 | /* |
@@ -1959,24 +1960,6 @@ xfs_iunlink( | |||
1959 | ASSERT(agi->agi_unlinked[bucket_index]); | 1960 | ASSERT(agi->agi_unlinked[bucket_index]); |
1960 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); | 1961 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); |
1961 | 1962 | ||
1962 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | ||
1963 | if (error) | ||
1964 | return error; | ||
1965 | |||
1966 | /* | ||
1967 | * Clear the on-disk di_nlink. This is to prevent xfs_bulkstat | ||
1968 | * from picking up this inode when it is reclaimed (its incore state | ||
1969 | * initialzed but not flushed to disk yet). The in-core di_nlink is | ||
1970 | * already cleared in xfs_droplink() and a corresponding transaction | ||
1971 | * logged. The hack here just synchronizes the in-core to on-disk | ||
1972 | * di_nlink value in advance before the actual inode sync to disk. | ||
1973 | * This is OK because the inode is already unlinked and would never | ||
1974 | * change its di_nlink again for this inode generation. | ||
1975 | * This is a temporary hack that would require a proper fix | ||
1976 | * in the future. | ||
1977 | */ | ||
1978 | dip->di_core.di_nlink = 0; | ||
1979 | |||
1980 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { | 1963 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { |
1981 | /* | 1964 | /* |
1982 | * There is already another inode in the bucket we need | 1965 | * There is already another inode in the bucket we need |
@@ -1984,6 +1967,10 @@ xfs_iunlink( | |||
1984 | * Here we put the head pointer into our next pointer, | 1967 | * Here we put the head pointer into our next pointer, |
1985 | * and then we fall through to point the head at us. | 1968 | * and then we fall through to point the head at us. |
1986 | */ | 1969 | */ |
1970 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | ||
1971 | if (error) | ||
1972 | return error; | ||
1973 | |||
1987 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); | 1974 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); |
1988 | /* both on-disk, don't endian flip twice */ | 1975 | /* both on-disk, don't endian flip twice */ |
1989 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; | 1976 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; |
@@ -2209,7 +2196,6 @@ xfs_ifree_cluster( | |||
2209 | xfs_inode_log_item_t *iip; | 2196 | xfs_inode_log_item_t *iip; |
2210 | xfs_log_item_t *lip; | 2197 | xfs_log_item_t *lip; |
2211 | xfs_perag_t *pag = xfs_get_perag(mp, inum); | 2198 | xfs_perag_t *pag = xfs_get_perag(mp, inum); |
2212 | SPLDECL(s); | ||
2213 | 2199 | ||
2214 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { | 2200 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { |
2215 | blks_per_cluster = 1; | 2201 | blks_per_cluster = 1; |
@@ -2311,9 +2297,9 @@ xfs_ifree_cluster( | |||
2311 | iip = (xfs_inode_log_item_t *)lip; | 2297 | iip = (xfs_inode_log_item_t *)lip; |
2312 | ASSERT(iip->ili_logged == 1); | 2298 | ASSERT(iip->ili_logged == 1); |
2313 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; | 2299 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; |
2314 | AIL_LOCK(mp,s); | 2300 | spin_lock(&mp->m_ail_lock); |
2315 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2301 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
2316 | AIL_UNLOCK(mp, s); | 2302 | spin_unlock(&mp->m_ail_lock); |
2317 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | 2303 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
2318 | pre_flushed++; | 2304 | pre_flushed++; |
2319 | } | 2305 | } |
@@ -2334,9 +2320,9 @@ xfs_ifree_cluster( | |||
2334 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2320 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2335 | iip->ili_format.ilf_fields = 0; | 2321 | iip->ili_format.ilf_fields = 0; |
2336 | iip->ili_logged = 1; | 2322 | iip->ili_logged = 1; |
2337 | AIL_LOCK(mp,s); | 2323 | spin_lock(&mp->m_ail_lock); |
2338 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2324 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
2339 | AIL_UNLOCK(mp, s); | 2325 | spin_unlock(&mp->m_ail_lock); |
2340 | 2326 | ||
2341 | xfs_buf_attach_iodone(bp, | 2327 | xfs_buf_attach_iodone(bp, |
2342 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) | 2328 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) |
@@ -2374,6 +2360,8 @@ xfs_ifree( | |||
2374 | int error; | 2360 | int error; |
2375 | int delete; | 2361 | int delete; |
2376 | xfs_ino_t first_ino; | 2362 | xfs_ino_t first_ino; |
2363 | xfs_dinode_t *dip; | ||
2364 | xfs_buf_t *ibp; | ||
2377 | 2365 | ||
2378 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 2366 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); |
2379 | ASSERT(ip->i_transp == tp); | 2367 | ASSERT(ip->i_transp == tp); |
@@ -2409,8 +2397,27 @@ xfs_ifree( | |||
2409 | * by reincarnations of this inode. | 2397 | * by reincarnations of this inode. |
2410 | */ | 2398 | */ |
2411 | ip->i_d.di_gen++; | 2399 | ip->i_d.di_gen++; |
2400 | |||
2412 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 2401 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
2413 | 2402 | ||
2403 | error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, 0, 0); | ||
2404 | if (error) | ||
2405 | return error; | ||
2406 | |||
2407 | /* | ||
2408 | * Clear the on-disk di_mode. This is to prevent xfs_bulkstat | ||
2409 | * from picking up this inode when it is reclaimed (its incore state | ||
2410 | * initialzed but not flushed to disk yet). The in-core di_mode is | ||
2411 | * already cleared and a corresponding transaction logged. | ||
2412 | * The hack here just synchronizes the in-core to on-disk | ||
2413 | * di_mode value in advance before the actual inode sync to disk. | ||
2414 | * This is OK because the inode is already unlinked and would never | ||
2415 | * change its di_mode again for this inode generation. | ||
2416 | * This is a temporary hack that would require a proper fix | ||
2417 | * in the future. | ||
2418 | */ | ||
2419 | dip->di_core.di_mode = 0; | ||
2420 | |||
2414 | if (delete) { | 2421 | if (delete) { |
2415 | xfs_ifree_cluster(ip, tp, first_ino); | 2422 | xfs_ifree_cluster(ip, tp, first_ino); |
2416 | } | 2423 | } |
@@ -2735,7 +2742,6 @@ void | |||
2735 | xfs_idestroy( | 2742 | xfs_idestroy( |
2736 | xfs_inode_t *ip) | 2743 | xfs_inode_t *ip) |
2737 | { | 2744 | { |
2738 | |||
2739 | switch (ip->i_d.di_mode & S_IFMT) { | 2745 | switch (ip->i_d.di_mode & S_IFMT) { |
2740 | case S_IFREG: | 2746 | case S_IFREG: |
2741 | case S_IFDIR: | 2747 | case S_IFDIR: |
@@ -2749,7 +2755,7 @@ xfs_idestroy( | |||
2749 | mrfree(&ip->i_iolock); | 2755 | mrfree(&ip->i_iolock); |
2750 | freesema(&ip->i_flock); | 2756 | freesema(&ip->i_flock); |
2751 | 2757 | ||
2752 | #ifdef XFS_VNODE_TRACE | 2758 | #ifdef XFS_INODE_TRACE |
2753 | ktrace_free(ip->i_trace); | 2759 | ktrace_free(ip->i_trace); |
2754 | #endif | 2760 | #endif |
2755 | #ifdef XFS_BMAP_TRACE | 2761 | #ifdef XFS_BMAP_TRACE |
@@ -2775,16 +2781,15 @@ xfs_idestroy( | |||
2775 | */ | 2781 | */ |
2776 | xfs_mount_t *mp = ip->i_mount; | 2782 | xfs_mount_t *mp = ip->i_mount; |
2777 | xfs_log_item_t *lip = &ip->i_itemp->ili_item; | 2783 | xfs_log_item_t *lip = &ip->i_itemp->ili_item; |
2778 | int s; | ||
2779 | 2784 | ||
2780 | ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || | 2785 | ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || |
2781 | XFS_FORCED_SHUTDOWN(ip->i_mount)); | 2786 | XFS_FORCED_SHUTDOWN(ip->i_mount)); |
2782 | if (lip->li_flags & XFS_LI_IN_AIL) { | 2787 | if (lip->li_flags & XFS_LI_IN_AIL) { |
2783 | AIL_LOCK(mp, s); | 2788 | spin_lock(&mp->m_ail_lock); |
2784 | if (lip->li_flags & XFS_LI_IN_AIL) | 2789 | if (lip->li_flags & XFS_LI_IN_AIL) |
2785 | xfs_trans_delete_ail(mp, lip, s); | 2790 | xfs_trans_delete_ail(mp, lip); |
2786 | else | 2791 | else |
2787 | AIL_UNLOCK(mp, s); | 2792 | spin_unlock(&mp->m_ail_lock); |
2788 | } | 2793 | } |
2789 | xfs_inode_item_destroy(ip); | 2794 | xfs_inode_item_destroy(ip); |
2790 | } | 2795 | } |
@@ -2816,40 +2821,8 @@ xfs_iunpin( | |||
2816 | { | 2821 | { |
2817 | ASSERT(atomic_read(&ip->i_pincount) > 0); | 2822 | ASSERT(atomic_read(&ip->i_pincount) > 0); |
2818 | 2823 | ||
2819 | if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) { | 2824 | if (atomic_dec_and_test(&ip->i_pincount)) |
2820 | |||
2821 | /* | ||
2822 | * If the inode is currently being reclaimed, the link between | ||
2823 | * the bhv_vnode and the xfs_inode will be broken after the | ||
2824 | * XFS_IRECLAIM* flag is set. Hence, if these flags are not | ||
2825 | * set, then we can move forward and mark the linux inode dirty | ||
2826 | * knowing that it is still valid as it won't freed until after | ||
2827 | * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The | ||
2828 | * i_flags_lock is used to synchronise the setting of the | ||
2829 | * XFS_IRECLAIM* flags and the breaking of the link, and so we | ||
2830 | * can execute atomically w.r.t to reclaim by holding this lock | ||
2831 | * here. | ||
2832 | * | ||
2833 | * However, we still need to issue the unpin wakeup call as the | ||
2834 | * inode reclaim may be blocked waiting for the inode to become | ||
2835 | * unpinned. | ||
2836 | */ | ||
2837 | |||
2838 | if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) { | ||
2839 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | ||
2840 | struct inode *inode = NULL; | ||
2841 | |||
2842 | BUG_ON(vp == NULL); | ||
2843 | inode = vn_to_inode(vp); | ||
2844 | BUG_ON(inode->i_state & I_CLEAR); | ||
2845 | |||
2846 | /* make sync come back and flush this inode */ | ||
2847 | if (!(inode->i_state & (I_NEW|I_FREEING))) | ||
2848 | mark_inode_dirty_sync(inode); | ||
2849 | } | ||
2850 | spin_unlock(&ip->i_flags_lock); | ||
2851 | wake_up(&ip->i_ipin_wait); | 2825 | wake_up(&ip->i_ipin_wait); |
2852 | } | ||
2853 | } | 2826 | } |
2854 | 2827 | ||
2855 | /* | 2828 | /* |
@@ -3338,7 +3311,6 @@ xfs_iflush_int( | |||
3338 | #ifdef XFS_TRANS_DEBUG | 3311 | #ifdef XFS_TRANS_DEBUG |
3339 | int first; | 3312 | int first; |
3340 | #endif | 3313 | #endif |
3341 | SPLDECL(s); | ||
3342 | 3314 | ||
3343 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 3315 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); |
3344 | ASSERT(issemalocked(&(ip->i_flock))); | 3316 | ASSERT(issemalocked(&(ip->i_flock))); |
@@ -3533,9 +3505,9 @@ xfs_iflush_int( | |||
3533 | iip->ili_logged = 1; | 3505 | iip->ili_logged = 1; |
3534 | 3506 | ||
3535 | ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */ | 3507 | ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */ |
3536 | AIL_LOCK(mp,s); | 3508 | spin_lock(&mp->m_ail_lock); |
3537 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 3509 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
3538 | AIL_UNLOCK(mp, s); | 3510 | spin_unlock(&mp->m_ail_lock); |
3539 | 3511 | ||
3540 | /* | 3512 | /* |
3541 | * Attach the function xfs_iflush_done to the inode's | 3513 | * Attach the function xfs_iflush_done to the inode's |
@@ -3611,95 +3583,6 @@ xfs_iflush_all( | |||
3611 | XFS_MOUNT_IUNLOCK(mp); | 3583 | XFS_MOUNT_IUNLOCK(mp); |
3612 | } | 3584 | } |
3613 | 3585 | ||
3614 | /* | ||
3615 | * xfs_iaccess: check accessibility of inode for mode. | ||
3616 | */ | ||
3617 | int | ||
3618 | xfs_iaccess( | ||
3619 | xfs_inode_t *ip, | ||
3620 | mode_t mode, | ||
3621 | cred_t *cr) | ||
3622 | { | ||
3623 | int error; | ||
3624 | mode_t orgmode = mode; | ||
3625 | struct inode *inode = vn_to_inode(XFS_ITOV(ip)); | ||
3626 | |||
3627 | if (mode & S_IWUSR) { | ||
3628 | umode_t imode = inode->i_mode; | ||
3629 | |||
3630 | if (IS_RDONLY(inode) && | ||
3631 | (S_ISREG(imode) || S_ISDIR(imode) || S_ISLNK(imode))) | ||
3632 | return XFS_ERROR(EROFS); | ||
3633 | |||
3634 | if (IS_IMMUTABLE(inode)) | ||
3635 | return XFS_ERROR(EACCES); | ||
3636 | } | ||
3637 | |||
3638 | /* | ||
3639 | * If there's an Access Control List it's used instead of | ||
3640 | * the mode bits. | ||
3641 | */ | ||
3642 | if ((error = _ACL_XFS_IACCESS(ip, mode, cr)) != -1) | ||
3643 | return error ? XFS_ERROR(error) : 0; | ||
3644 | |||
3645 | if (current_fsuid(cr) != ip->i_d.di_uid) { | ||
3646 | mode >>= 3; | ||
3647 | if (!in_group_p((gid_t)ip->i_d.di_gid)) | ||
3648 | mode >>= 3; | ||
3649 | } | ||
3650 | |||
3651 | /* | ||
3652 | * If the DACs are ok we don't need any capability check. | ||
3653 | */ | ||
3654 | if ((ip->i_d.di_mode & mode) == mode) | ||
3655 | return 0; | ||
3656 | /* | ||
3657 | * Read/write DACs are always overridable. | ||
3658 | * Executable DACs are overridable if at least one exec bit is set. | ||
3659 | */ | ||
3660 | if (!(orgmode & S_IXUSR) || | ||
3661 | (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) | ||
3662 | if (capable_cred(cr, CAP_DAC_OVERRIDE)) | ||
3663 | return 0; | ||
3664 | |||
3665 | if ((orgmode == S_IRUSR) || | ||
3666 | (S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) { | ||
3667 | if (capable_cred(cr, CAP_DAC_READ_SEARCH)) | ||
3668 | return 0; | ||
3669 | #ifdef NOISE | ||
3670 | cmn_err(CE_NOTE, "Ick: mode=%o, orgmode=%o", mode, orgmode); | ||
3671 | #endif /* NOISE */ | ||
3672 | return XFS_ERROR(EACCES); | ||
3673 | } | ||
3674 | return XFS_ERROR(EACCES); | ||
3675 | } | ||
3676 | |||
3677 | /* | ||
3678 | * xfs_iroundup: round up argument to next power of two | ||
3679 | */ | ||
3680 | uint | ||
3681 | xfs_iroundup( | ||
3682 | uint v) | ||
3683 | { | ||
3684 | int i; | ||
3685 | uint m; | ||
3686 | |||
3687 | if ((v & (v - 1)) == 0) | ||
3688 | return v; | ||
3689 | ASSERT((v & 0x80000000) == 0); | ||
3690 | if ((v & (v + 1)) == 0) | ||
3691 | return v + 1; | ||
3692 | for (i = 0, m = 1; i < 31; i++, m <<= 1) { | ||
3693 | if (v & m) | ||
3694 | continue; | ||
3695 | v |= m; | ||
3696 | if ((v & (v + 1)) == 0) | ||
3697 | return v + 1; | ||
3698 | } | ||
3699 | ASSERT(0); | ||
3700 | return( 0 ); | ||
3701 | } | ||
3702 | |||
3703 | #ifdef XFS_ILOCK_TRACE | 3586 | #ifdef XFS_ILOCK_TRACE |
3704 | ktrace_t *xfs_ilock_trace_buf; | 3587 | ktrace_t *xfs_ilock_trace_buf; |
3705 | 3588 | ||
@@ -4206,7 +4089,7 @@ xfs_iext_realloc_direct( | |||
4206 | return; | 4089 | return; |
4207 | } | 4090 | } |
4208 | if (!is_power_of_2(new_size)){ | 4091 | if (!is_power_of_2(new_size)){ |
4209 | rnew_size = xfs_iroundup(new_size); | 4092 | rnew_size = roundup_pow_of_two(new_size); |
4210 | } | 4093 | } |
4211 | if (rnew_size != ifp->if_real_bytes) { | 4094 | if (rnew_size != ifp->if_real_bytes) { |
4212 | ifp->if_u1.if_extents = | 4095 | ifp->if_u1.if_extents = |
@@ -4229,7 +4112,7 @@ xfs_iext_realloc_direct( | |||
4229 | else { | 4112 | else { |
4230 | new_size += ifp->if_bytes; | 4113 | new_size += ifp->if_bytes; |
4231 | if (!is_power_of_2(new_size)) { | 4114 | if (!is_power_of_2(new_size)) { |
4232 | rnew_size = xfs_iroundup(new_size); | 4115 | rnew_size = roundup_pow_of_two(new_size); |
4233 | } | 4116 | } |
4234 | xfs_iext_inline_to_direct(ifp, rnew_size); | 4117 | xfs_iext_inline_to_direct(ifp, rnew_size); |
4235 | } | 4118 | } |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index e5aff929cc65..bfcd72cbaeea 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -132,45 +132,6 @@ typedef struct dm_attrs_s { | |||
132 | __uint16_t da_pad; /* DMIG extra padding */ | 132 | __uint16_t da_pad; /* DMIG extra padding */ |
133 | } dm_attrs_t; | 133 | } dm_attrs_t; |
134 | 134 | ||
135 | typedef struct xfs_iocore { | ||
136 | void *io_obj; /* pointer to container | ||
137 | * inode or dcxvn structure */ | ||
138 | struct xfs_mount *io_mount; /* fs mount struct ptr */ | ||
139 | #ifdef DEBUG | ||
140 | mrlock_t *io_lock; /* inode IO lock */ | ||
141 | mrlock_t *io_iolock; /* inode IO lock */ | ||
142 | #endif | ||
143 | |||
144 | /* I/O state */ | ||
145 | xfs_fsize_t io_new_size; /* sz when write completes */ | ||
146 | |||
147 | /* Miscellaneous state. */ | ||
148 | unsigned int io_flags; /* IO related flags */ | ||
149 | |||
150 | /* DMAPI state */ | ||
151 | dm_attrs_t io_dmattrs; | ||
152 | |||
153 | } xfs_iocore_t; | ||
154 | |||
155 | #define io_dmevmask io_dmattrs.da_dmevmask | ||
156 | #define io_dmstate io_dmattrs.da_dmstate | ||
157 | |||
158 | #define XFS_IO_INODE(io) ((xfs_inode_t *) ((io)->io_obj)) | ||
159 | #define XFS_IO_DCXVN(io) ((dcxvn_t *) ((io)->io_obj)) | ||
160 | |||
161 | /* | ||
162 | * Flags in the flags field | ||
163 | */ | ||
164 | |||
165 | #define XFS_IOCORE_RT 0x1 | ||
166 | |||
167 | /* | ||
168 | * xfs_iocore prototypes | ||
169 | */ | ||
170 | |||
171 | extern void xfs_iocore_inode_init(struct xfs_inode *); | ||
172 | extern void xfs_iocore_inode_reinit(struct xfs_inode *); | ||
173 | |||
174 | /* | 135 | /* |
175 | * This is the xfs inode cluster structure. This structure is used by | 136 | * This is the xfs inode cluster structure. This structure is used by |
176 | * xfs_iflush to find inodes that share a cluster and can be flushed to disk at | 137 | * xfs_iflush to find inodes that share a cluster and can be flushed to disk at |
@@ -181,7 +142,7 @@ typedef struct xfs_icluster { | |||
181 | xfs_daddr_t icl_blkno; /* starting block number of | 142 | xfs_daddr_t icl_blkno; /* starting block number of |
182 | * the cluster */ | 143 | * the cluster */ |
183 | struct xfs_buf *icl_buf; /* the inode buffer */ | 144 | struct xfs_buf *icl_buf; /* the inode buffer */ |
184 | lock_t icl_lock; /* inode list lock */ | 145 | spinlock_t icl_lock; /* inode list lock */ |
185 | } xfs_icluster_t; | 146 | } xfs_icluster_t; |
186 | 147 | ||
187 | /* | 148 | /* |
@@ -283,9 +244,6 @@ typedef struct xfs_inode { | |||
283 | struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ | 244 | struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ |
284 | struct xfs_inode *i_release; /* inode to unref */ | 245 | struct xfs_inode *i_release; /* inode to unref */ |
285 | #endif | 246 | #endif |
286 | /* I/O state */ | ||
287 | xfs_iocore_t i_iocore; /* I/O core */ | ||
288 | |||
289 | /* Miscellaneous state. */ | 247 | /* Miscellaneous state. */ |
290 | unsigned short i_flags; /* see defined flags below */ | 248 | unsigned short i_flags; /* see defined flags below */ |
291 | unsigned char i_update_core; /* timestamps/size is dirty */ | 249 | unsigned char i_update_core; /* timestamps/size is dirty */ |
@@ -298,9 +256,10 @@ typedef struct xfs_inode { | |||
298 | struct hlist_node i_cnode; /* cluster link node */ | 256 | struct hlist_node i_cnode; /* cluster link node */ |
299 | 257 | ||
300 | xfs_fsize_t i_size; /* in-memory size */ | 258 | xfs_fsize_t i_size; /* in-memory size */ |
259 | xfs_fsize_t i_new_size; /* size when write completes */ | ||
301 | atomic_t i_iocount; /* outstanding I/O count */ | 260 | atomic_t i_iocount; /* outstanding I/O count */ |
302 | /* Trace buffers per inode. */ | 261 | /* Trace buffers per inode. */ |
303 | #ifdef XFS_VNODE_TRACE | 262 | #ifdef XFS_INODE_TRACE |
304 | struct ktrace *i_trace; /* general inode trace */ | 263 | struct ktrace *i_trace; /* general inode trace */ |
305 | #endif | 264 | #endif |
306 | #ifdef XFS_BMAP_TRACE | 265 | #ifdef XFS_BMAP_TRACE |
@@ -382,17 +341,42 @@ xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) | |||
382 | /* | 341 | /* |
383 | * Fork handling. | 342 | * Fork handling. |
384 | */ | 343 | */ |
385 | #define XFS_IFORK_PTR(ip,w) \ | ||
386 | ((w) == XFS_DATA_FORK ? &(ip)->i_df : (ip)->i_afp) | ||
387 | #define XFS_IFORK_Q(ip) XFS_CFORK_Q(&(ip)->i_d) | ||
388 | #define XFS_IFORK_DSIZE(ip) XFS_CFORK_DSIZE(&ip->i_d, ip->i_mount) | ||
389 | #define XFS_IFORK_ASIZE(ip) XFS_CFORK_ASIZE(&ip->i_d, ip->i_mount) | ||
390 | #define XFS_IFORK_SIZE(ip,w) XFS_CFORK_SIZE(&ip->i_d, ip->i_mount, w) | ||
391 | #define XFS_IFORK_FORMAT(ip,w) XFS_CFORK_FORMAT(&ip->i_d, w) | ||
392 | #define XFS_IFORK_FMT_SET(ip,w,n) XFS_CFORK_FMT_SET(&ip->i_d, w, n) | ||
393 | #define XFS_IFORK_NEXTENTS(ip,w) XFS_CFORK_NEXTENTS(&ip->i_d, w) | ||
394 | #define XFS_IFORK_NEXT_SET(ip,w,n) XFS_CFORK_NEXT_SET(&ip->i_d, w, n) | ||
395 | 344 | ||
345 | #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) | ||
346 | #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) | ||
347 | |||
348 | #define XFS_IFORK_PTR(ip,w) \ | ||
349 | ((w) == XFS_DATA_FORK ? \ | ||
350 | &(ip)->i_df : \ | ||
351 | (ip)->i_afp) | ||
352 | #define XFS_IFORK_DSIZE(ip) \ | ||
353 | (XFS_IFORK_Q(ip) ? \ | ||
354 | XFS_IFORK_BOFF(ip) : \ | ||
355 | XFS_LITINO((ip)->i_mount)) | ||
356 | #define XFS_IFORK_ASIZE(ip) \ | ||
357 | (XFS_IFORK_Q(ip) ? \ | ||
358 | XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ | ||
359 | 0) | ||
360 | #define XFS_IFORK_SIZE(ip,w) \ | ||
361 | ((w) == XFS_DATA_FORK ? \ | ||
362 | XFS_IFORK_DSIZE(ip) : \ | ||
363 | XFS_IFORK_ASIZE(ip)) | ||
364 | #define XFS_IFORK_FORMAT(ip,w) \ | ||
365 | ((w) == XFS_DATA_FORK ? \ | ||
366 | (ip)->i_d.di_format : \ | ||
367 | (ip)->i_d.di_aformat) | ||
368 | #define XFS_IFORK_FMT_SET(ip,w,n) \ | ||
369 | ((w) == XFS_DATA_FORK ? \ | ||
370 | ((ip)->i_d.di_format = (n)) : \ | ||
371 | ((ip)->i_d.di_aformat = (n))) | ||
372 | #define XFS_IFORK_NEXTENTS(ip,w) \ | ||
373 | ((w) == XFS_DATA_FORK ? \ | ||
374 | (ip)->i_d.di_nextents : \ | ||
375 | (ip)->i_d.di_anextents) | ||
376 | #define XFS_IFORK_NEXT_SET(ip,w,n) \ | ||
377 | ((w) == XFS_DATA_FORK ? \ | ||
378 | ((ip)->i_d.di_nextents = (n)) : \ | ||
379 | ((ip)->i_d.di_anextents = (n))) | ||
396 | 380 | ||
397 | #ifdef __KERNEL__ | 381 | #ifdef __KERNEL__ |
398 | 382 | ||
@@ -509,7 +493,6 @@ void xfs_ihash_init(struct xfs_mount *); | |||
509 | void xfs_ihash_free(struct xfs_mount *); | 493 | void xfs_ihash_free(struct xfs_mount *); |
510 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, | 494 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, |
511 | struct xfs_trans *); | 495 | struct xfs_trans *); |
512 | void xfs_inode_lock_init(xfs_inode_t *, bhv_vnode_t *); | ||
513 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 496 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
514 | uint, uint, xfs_inode_t **, xfs_daddr_t); | 497 | uint, uint, xfs_inode_t **, xfs_daddr_t); |
515 | void xfs_iput(xfs_inode_t *, uint); | 498 | void xfs_iput(xfs_inode_t *, uint); |
@@ -545,7 +528,7 @@ void xfs_dinode_to_disk(struct xfs_dinode_core *, | |||
545 | struct xfs_icdinode *); | 528 | struct xfs_icdinode *); |
546 | 529 | ||
547 | uint xfs_ip2xflags(struct xfs_inode *); | 530 | uint xfs_ip2xflags(struct xfs_inode *); |
548 | uint xfs_dic2xflags(struct xfs_dinode_core *); | 531 | uint xfs_dic2xflags(struct xfs_dinode *); |
549 | int xfs_ifree(struct xfs_trans *, xfs_inode_t *, | 532 | int xfs_ifree(struct xfs_trans *, xfs_inode_t *, |
550 | struct xfs_bmap_free *); | 533 | struct xfs_bmap_free *); |
551 | int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); | 534 | int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); |
@@ -567,13 +550,12 @@ void xfs_iunpin(xfs_inode_t *); | |||
567 | int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); | 550 | int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); |
568 | int xfs_iflush(xfs_inode_t *, uint); | 551 | int xfs_iflush(xfs_inode_t *, uint); |
569 | void xfs_iflush_all(struct xfs_mount *); | 552 | void xfs_iflush_all(struct xfs_mount *); |
570 | int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); | ||
571 | uint xfs_iroundup(uint); | ||
572 | void xfs_ichgtime(xfs_inode_t *, int); | 553 | void xfs_ichgtime(xfs_inode_t *, int); |
573 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 554 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
574 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 555 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
575 | 556 | ||
576 | void xfs_synchronize_atime(xfs_inode_t *); | 557 | void xfs_synchronize_atime(xfs_inode_t *); |
558 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); | ||
577 | 559 | ||
578 | xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); | 560 | xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); |
579 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, | 561 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 565d470a6b4a..034ca7202295 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -274,6 +274,11 @@ xfs_inode_item_format( | |||
274 | */ | 274 | */ |
275 | xfs_synchronize_atime(ip); | 275 | xfs_synchronize_atime(ip); |
276 | 276 | ||
277 | /* | ||
278 | * make sure the linux inode is dirty | ||
279 | */ | ||
280 | xfs_mark_inode_dirty_sync(ip); | ||
281 | |||
277 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; | 282 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
278 | vecp->i_len = sizeof(xfs_dinode_core_t); | 283 | vecp->i_len = sizeof(xfs_dinode_core_t); |
279 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); | 284 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); |
@@ -615,7 +620,7 @@ xfs_inode_item_trylock( | |||
615 | return XFS_ITEM_PUSHBUF; | 620 | return XFS_ITEM_PUSHBUF; |
616 | } else { | 621 | } else { |
617 | /* | 622 | /* |
618 | * We hold the AIL_LOCK, so we must specify the | 623 | * We hold the AIL lock, so we must specify the |
619 | * NONOTIFY flag so that we won't double trip. | 624 | * NONOTIFY flag so that we won't double trip. |
620 | */ | 625 | */ |
621 | xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY); | 626 | xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY); |
@@ -749,7 +754,7 @@ xfs_inode_item_committed( | |||
749 | * marked delayed write. If that's the case, we'll initiate a bawrite on that | 754 | * marked delayed write. If that's the case, we'll initiate a bawrite on that |
750 | * buffer to expedite the process. | 755 | * buffer to expedite the process. |
751 | * | 756 | * |
752 | * We aren't holding the AIL_LOCK (or the flush lock) when this gets called, | 757 | * We aren't holding the AIL lock (or the flush lock) when this gets called, |
753 | * so it is inherently race-y. | 758 | * so it is inherently race-y. |
754 | */ | 759 | */ |
755 | STATIC void | 760 | STATIC void |
@@ -792,7 +797,7 @@ xfs_inode_item_pushbuf( | |||
792 | if (XFS_BUF_ISDELAYWRITE(bp)) { | 797 | if (XFS_BUF_ISDELAYWRITE(bp)) { |
793 | /* | 798 | /* |
794 | * We were racing with iflush because we don't hold | 799 | * We were racing with iflush because we don't hold |
795 | * the AIL_LOCK or the flush lock. However, at this point, | 800 | * the AIL lock or the flush lock. However, at this point, |
796 | * we have the buffer, and we know that it's dirty. | 801 | * we have the buffer, and we know that it's dirty. |
797 | * So, it's possible that iflush raced with us, and | 802 | * So, it's possible that iflush raced with us, and |
798 | * this item is already taken off the AIL. | 803 | * this item is already taken off the AIL. |
@@ -968,7 +973,6 @@ xfs_iflush_done( | |||
968 | xfs_inode_log_item_t *iip) | 973 | xfs_inode_log_item_t *iip) |
969 | { | 974 | { |
970 | xfs_inode_t *ip; | 975 | xfs_inode_t *ip; |
971 | SPLDECL(s); | ||
972 | 976 | ||
973 | ip = iip->ili_inode; | 977 | ip = iip->ili_inode; |
974 | 978 | ||
@@ -983,15 +987,15 @@ xfs_iflush_done( | |||
983 | */ | 987 | */ |
984 | if (iip->ili_logged && | 988 | if (iip->ili_logged && |
985 | (iip->ili_item.li_lsn == iip->ili_flush_lsn)) { | 989 | (iip->ili_item.li_lsn == iip->ili_flush_lsn)) { |
986 | AIL_LOCK(ip->i_mount, s); | 990 | spin_lock(&ip->i_mount->m_ail_lock); |
987 | if (iip->ili_item.li_lsn == iip->ili_flush_lsn) { | 991 | if (iip->ili_item.li_lsn == iip->ili_flush_lsn) { |
988 | /* | 992 | /* |
989 | * xfs_trans_delete_ail() drops the AIL lock. | 993 | * xfs_trans_delete_ail() drops the AIL lock. |
990 | */ | 994 | */ |
991 | xfs_trans_delete_ail(ip->i_mount, | 995 | xfs_trans_delete_ail(ip->i_mount, |
992 | (xfs_log_item_t*)iip, s); | 996 | (xfs_log_item_t*)iip); |
993 | } else { | 997 | } else { |
994 | AIL_UNLOCK(ip->i_mount, s); | 998 | spin_unlock(&ip->i_mount->m_ail_lock); |
995 | } | 999 | } |
996 | } | 1000 | } |
997 | 1001 | ||
@@ -1025,21 +1029,19 @@ xfs_iflush_abort( | |||
1025 | { | 1029 | { |
1026 | xfs_inode_log_item_t *iip; | 1030 | xfs_inode_log_item_t *iip; |
1027 | xfs_mount_t *mp; | 1031 | xfs_mount_t *mp; |
1028 | SPLDECL(s); | ||
1029 | 1032 | ||
1030 | iip = ip->i_itemp; | 1033 | iip = ip->i_itemp; |
1031 | mp = ip->i_mount; | 1034 | mp = ip->i_mount; |
1032 | if (iip) { | 1035 | if (iip) { |
1033 | if (iip->ili_item.li_flags & XFS_LI_IN_AIL) { | 1036 | if (iip->ili_item.li_flags & XFS_LI_IN_AIL) { |
1034 | AIL_LOCK(mp, s); | 1037 | spin_lock(&mp->m_ail_lock); |
1035 | if (iip->ili_item.li_flags & XFS_LI_IN_AIL) { | 1038 | if (iip->ili_item.li_flags & XFS_LI_IN_AIL) { |
1036 | /* | 1039 | /* |
1037 | * xfs_trans_delete_ail() drops the AIL lock. | 1040 | * xfs_trans_delete_ail() drops the AIL lock. |
1038 | */ | 1041 | */ |
1039 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)iip, | 1042 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)iip); |
1040 | s); | ||
1041 | } else | 1043 | } else |
1042 | AIL_UNLOCK(mp, s); | 1044 | spin_unlock(&mp->m_ail_lock); |
1043 | } | 1045 | } |
1044 | iip->ili_logged = 0; | 1046 | iip->ili_logged = 0; |
1045 | /* | 1047 | /* |
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c deleted file mode 100644 index b27b5d5be841..000000000000 --- a/fs/xfs/xfs_iocore.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_bit.h" | ||
22 | #include "xfs_log.h" | ||
23 | #include "xfs_inum.h" | ||
24 | #include "xfs_trans.h" | ||
25 | #include "xfs_sb.h" | ||
26 | #include "xfs_ag.h" | ||
27 | #include "xfs_dir2.h" | ||
28 | #include "xfs_dfrag.h" | ||
29 | #include "xfs_dmapi.h" | ||
30 | #include "xfs_mount.h" | ||
31 | #include "xfs_bmap_btree.h" | ||
32 | #include "xfs_alloc_btree.h" | ||
33 | #include "xfs_ialloc_btree.h" | ||
34 | #include "xfs_dir2_sf.h" | ||
35 | #include "xfs_attr_sf.h" | ||
36 | #include "xfs_dinode.h" | ||
37 | #include "xfs_inode.h" | ||
38 | #include "xfs_inode_item.h" | ||
39 | #include "xfs_itable.h" | ||
40 | #include "xfs_btree.h" | ||
41 | #include "xfs_alloc.h" | ||
42 | #include "xfs_ialloc.h" | ||
43 | #include "xfs_bmap.h" | ||
44 | #include "xfs_error.h" | ||
45 | #include "xfs_rw.h" | ||
46 | #include "xfs_quota.h" | ||
47 | #include "xfs_trans_space.h" | ||
48 | #include "xfs_iomap.h" | ||
49 | |||
50 | |||
51 | STATIC xfs_fsize_t | ||
52 | xfs_size_fn( | ||
53 | xfs_inode_t *ip) | ||
54 | { | ||
55 | return XFS_ISIZE(ip); | ||
56 | } | ||
57 | |||
58 | STATIC int | ||
59 | xfs_ioinit( | ||
60 | struct xfs_mount *mp, | ||
61 | struct xfs_mount_args *mntargs, | ||
62 | int flags) | ||
63 | { | ||
64 | return xfs_mountfs(mp, flags); | ||
65 | } | ||
66 | |||
67 | xfs_ioops_t xfs_iocore_xfs = { | ||
68 | .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, | ||
69 | .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, | ||
70 | .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi, | ||
71 | .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, | ||
72 | .xfs_iomap_write_direct = | ||
73 | (xfs_iomap_write_direct_t) xfs_iomap_write_direct, | ||
74 | .xfs_iomap_write_delay = | ||
75 | (xfs_iomap_write_delay_t) xfs_iomap_write_delay, | ||
76 | .xfs_iomap_write_allocate = | ||
77 | (xfs_iomap_write_allocate_t) xfs_iomap_write_allocate, | ||
78 | .xfs_iomap_write_unwritten = | ||
79 | (xfs_iomap_write_unwritten_t) xfs_iomap_write_unwritten, | ||
80 | .xfs_ilock = (xfs_lock_t) xfs_ilock, | ||
81 | .xfs_lck_map_shared = (xfs_lck_map_shared_t) xfs_ilock_map_shared, | ||
82 | .xfs_ilock_demote = (xfs_lock_demote_t) xfs_ilock_demote, | ||
83 | .xfs_ilock_nowait = (xfs_lock_nowait_t) xfs_ilock_nowait, | ||
84 | .xfs_unlock = (xfs_unlk_t) xfs_iunlock, | ||
85 | .xfs_size_func = (xfs_size_t) xfs_size_fn, | ||
86 | .xfs_iodone = (xfs_iodone_t) fs_noerr, | ||
87 | .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents, | ||
88 | }; | ||
89 | |||
90 | void | ||
91 | xfs_iocore_inode_reinit( | ||
92 | xfs_inode_t *ip) | ||
93 | { | ||
94 | xfs_iocore_t *io = &ip->i_iocore; | ||
95 | |||
96 | io->io_flags = 0; | ||
97 | if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) | ||
98 | io->io_flags |= XFS_IOCORE_RT; | ||
99 | io->io_dmevmask = ip->i_d.di_dmevmask; | ||
100 | io->io_dmstate = ip->i_d.di_dmstate; | ||
101 | } | ||
102 | |||
103 | void | ||
104 | xfs_iocore_inode_init( | ||
105 | xfs_inode_t *ip) | ||
106 | { | ||
107 | xfs_iocore_t *io = &ip->i_iocore; | ||
108 | xfs_mount_t *mp = ip->i_mount; | ||
109 | |||
110 | io->io_mount = mp; | ||
111 | #ifdef DEBUG | ||
112 | io->io_lock = &ip->i_lock; | ||
113 | io->io_iolock = &ip->i_iolock; | ||
114 | #endif | ||
115 | |||
116 | io->io_obj = (void *)ip; | ||
117 | |||
118 | xfs_iocore_inode_reinit(ip); | ||
119 | } | ||
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 72786e356d56..fde37f87d52f 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -53,12 +53,10 @@ | |||
53 | void | 53 | void |
54 | xfs_iomap_enter_trace( | 54 | xfs_iomap_enter_trace( |
55 | int tag, | 55 | int tag, |
56 | xfs_iocore_t *io, | 56 | xfs_inode_t *ip, |
57 | xfs_off_t offset, | 57 | xfs_off_t offset, |
58 | ssize_t count) | 58 | ssize_t count) |
59 | { | 59 | { |
60 | xfs_inode_t *ip = XFS_IO_INODE(io); | ||
61 | |||
62 | if (!ip->i_rwtrace) | 60 | if (!ip->i_rwtrace) |
63 | return; | 61 | return; |
64 | 62 | ||
@@ -70,8 +68,8 @@ xfs_iomap_enter_trace( | |||
70 | (void *)((unsigned long)((offset >> 32) & 0xffffffff)), | 68 | (void *)((unsigned long)((offset >> 32) & 0xffffffff)), |
71 | (void *)((unsigned long)(offset & 0xffffffff)), | 69 | (void *)((unsigned long)(offset & 0xffffffff)), |
72 | (void *)((unsigned long)count), | 70 | (void *)((unsigned long)count), |
73 | (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)), | 71 | (void *)((unsigned long)((ip->i_new_size >> 32) & 0xffffffff)), |
74 | (void *)((unsigned long)(io->io_new_size & 0xffffffff)), | 72 | (void *)((unsigned long)(ip->i_new_size & 0xffffffff)), |
75 | (void *)((unsigned long)current_pid()), | 73 | (void *)((unsigned long)current_pid()), |
76 | (void *)NULL, | 74 | (void *)NULL, |
77 | (void *)NULL, | 75 | (void *)NULL, |
@@ -84,15 +82,13 @@ xfs_iomap_enter_trace( | |||
84 | void | 82 | void |
85 | xfs_iomap_map_trace( | 83 | xfs_iomap_map_trace( |
86 | int tag, | 84 | int tag, |
87 | xfs_iocore_t *io, | 85 | xfs_inode_t *ip, |
88 | xfs_off_t offset, | 86 | xfs_off_t offset, |
89 | ssize_t count, | 87 | ssize_t count, |
90 | xfs_iomap_t *iomapp, | 88 | xfs_iomap_t *iomapp, |
91 | xfs_bmbt_irec_t *imapp, | 89 | xfs_bmbt_irec_t *imapp, |
92 | int flags) | 90 | int flags) |
93 | { | 91 | { |
94 | xfs_inode_t *ip = XFS_IO_INODE(io); | ||
95 | |||
96 | if (!ip->i_rwtrace) | 92 | if (!ip->i_rwtrace) |
97 | return; | 93 | return; |
98 | 94 | ||
@@ -126,7 +122,7 @@ xfs_iomap_map_trace( | |||
126 | 122 | ||
127 | STATIC int | 123 | STATIC int |
128 | xfs_imap_to_bmap( | 124 | xfs_imap_to_bmap( |
129 | xfs_iocore_t *io, | 125 | xfs_inode_t *ip, |
130 | xfs_off_t offset, | 126 | xfs_off_t offset, |
131 | xfs_bmbt_irec_t *imap, | 127 | xfs_bmbt_irec_t *imap, |
132 | xfs_iomap_t *iomapp, | 128 | xfs_iomap_t *iomapp, |
@@ -134,11 +130,10 @@ xfs_imap_to_bmap( | |||
134 | int iomaps, /* Number of iomap entries */ | 130 | int iomaps, /* Number of iomap entries */ |
135 | int flags) | 131 | int flags) |
136 | { | 132 | { |
137 | xfs_mount_t *mp; | 133 | xfs_mount_t *mp = ip->i_mount; |
138 | int pbm; | 134 | int pbm; |
139 | xfs_fsblock_t start_block; | 135 | xfs_fsblock_t start_block; |
140 | 136 | ||
141 | mp = io->io_mount; | ||
142 | 137 | ||
143 | for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { | 138 | for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { |
144 | iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); | 139 | iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); |
@@ -146,7 +141,7 @@ xfs_imap_to_bmap( | |||
146 | iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); | 141 | iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); |
147 | iomapp->iomap_flags = flags; | 142 | iomapp->iomap_flags = flags; |
148 | 143 | ||
149 | if (io->io_flags & XFS_IOCORE_RT) { | 144 | if (XFS_IS_REALTIME_INODE(ip)) { |
150 | iomapp->iomap_flags |= IOMAP_REALTIME; | 145 | iomapp->iomap_flags |= IOMAP_REALTIME; |
151 | iomapp->iomap_target = mp->m_rtdev_targp; | 146 | iomapp->iomap_target = mp->m_rtdev_targp; |
152 | } else { | 147 | } else { |
@@ -160,7 +155,7 @@ xfs_imap_to_bmap( | |||
160 | iomapp->iomap_bn = IOMAP_DADDR_NULL; | 155 | iomapp->iomap_bn = IOMAP_DADDR_NULL; |
161 | iomapp->iomap_flags |= IOMAP_DELAY; | 156 | iomapp->iomap_flags |= IOMAP_DELAY; |
162 | } else { | 157 | } else { |
163 | iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block); | 158 | iomapp->iomap_bn = XFS_FSB_TO_DB(ip, start_block); |
164 | if (ISUNWRITTEN(imap)) | 159 | if (ISUNWRITTEN(imap)) |
165 | iomapp->iomap_flags |= IOMAP_UNWRITTEN; | 160 | iomapp->iomap_flags |= IOMAP_UNWRITTEN; |
166 | } | 161 | } |
@@ -172,14 +167,14 @@ xfs_imap_to_bmap( | |||
172 | 167 | ||
173 | int | 168 | int |
174 | xfs_iomap( | 169 | xfs_iomap( |
175 | xfs_iocore_t *io, | 170 | xfs_inode_t *ip, |
176 | xfs_off_t offset, | 171 | xfs_off_t offset, |
177 | ssize_t count, | 172 | ssize_t count, |
178 | int flags, | 173 | int flags, |
179 | xfs_iomap_t *iomapp, | 174 | xfs_iomap_t *iomapp, |
180 | int *niomaps) | 175 | int *niomaps) |
181 | { | 176 | { |
182 | xfs_mount_t *mp = io->io_mount; | 177 | xfs_mount_t *mp = ip->i_mount; |
183 | xfs_fileoff_t offset_fsb, end_fsb; | 178 | xfs_fileoff_t offset_fsb, end_fsb; |
184 | int error = 0; | 179 | int error = 0; |
185 | int lockmode = 0; | 180 | int lockmode = 0; |
@@ -188,45 +183,37 @@ xfs_iomap( | |||
188 | int bmapi_flags = 0; | 183 | int bmapi_flags = 0; |
189 | int iomap_flags = 0; | 184 | int iomap_flags = 0; |
190 | 185 | ||
186 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | ||
187 | |||
191 | if (XFS_FORCED_SHUTDOWN(mp)) | 188 | if (XFS_FORCED_SHUTDOWN(mp)) |
192 | return XFS_ERROR(EIO); | 189 | return XFS_ERROR(EIO); |
193 | 190 | ||
194 | switch (flags & | 191 | switch (flags & (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE)) { |
195 | (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE | | ||
196 | BMAPI_UNWRITTEN | BMAPI_DEVICE)) { | ||
197 | case BMAPI_READ: | 192 | case BMAPI_READ: |
198 | xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, io, offset, count); | 193 | xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, ip, offset, count); |
199 | lockmode = XFS_LCK_MAP_SHARED(mp, io); | 194 | lockmode = xfs_ilock_map_shared(ip); |
200 | bmapi_flags = XFS_BMAPI_ENTIRE; | 195 | bmapi_flags = XFS_BMAPI_ENTIRE; |
201 | break; | 196 | break; |
202 | case BMAPI_WRITE: | 197 | case BMAPI_WRITE: |
203 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, io, offset, count); | 198 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, ip, offset, count); |
204 | lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR; | 199 | lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR; |
205 | if (flags & BMAPI_IGNSTATE) | 200 | if (flags & BMAPI_IGNSTATE) |
206 | bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; | 201 | bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; |
207 | XFS_ILOCK(mp, io, lockmode); | 202 | xfs_ilock(ip, lockmode); |
208 | break; | 203 | break; |
209 | case BMAPI_ALLOCATE: | 204 | case BMAPI_ALLOCATE: |
210 | xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, io, offset, count); | 205 | xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, ip, offset, count); |
211 | lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD; | 206 | lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD; |
212 | bmapi_flags = XFS_BMAPI_ENTIRE; | 207 | bmapi_flags = XFS_BMAPI_ENTIRE; |
208 | |||
213 | /* Attempt non-blocking lock */ | 209 | /* Attempt non-blocking lock */ |
214 | if (flags & BMAPI_TRYLOCK) { | 210 | if (flags & BMAPI_TRYLOCK) { |
215 | if (!XFS_ILOCK_NOWAIT(mp, io, lockmode)) | 211 | if (!xfs_ilock_nowait(ip, lockmode)) |
216 | return XFS_ERROR(EAGAIN); | 212 | return XFS_ERROR(EAGAIN); |
217 | } else { | 213 | } else { |
218 | XFS_ILOCK(mp, io, lockmode); | 214 | xfs_ilock(ip, lockmode); |
219 | } | 215 | } |
220 | break; | 216 | break; |
221 | case BMAPI_UNWRITTEN: | ||
222 | goto phase2; | ||
223 | case BMAPI_DEVICE: | ||
224 | lockmode = XFS_LCK_MAP_SHARED(mp, io); | ||
225 | iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ? | ||
226 | mp->m_rtdev_targp : mp->m_ddev_targp; | ||
227 | error = 0; | ||
228 | *niomaps = 1; | ||
229 | goto out; | ||
230 | default: | 217 | default: |
231 | BUG(); | 218 | BUG(); |
232 | } | 219 | } |
@@ -237,7 +224,7 @@ xfs_iomap( | |||
237 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 224 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
238 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 225 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
239 | 226 | ||
240 | error = XFS_BMAPI(mp, NULL, io, offset_fsb, | 227 | error = xfs_bmapi(NULL, ip, offset_fsb, |
241 | (xfs_filblks_t)(end_fsb - offset_fsb), | 228 | (xfs_filblks_t)(end_fsb - offset_fsb), |
242 | bmapi_flags, NULL, 0, &imap, | 229 | bmapi_flags, NULL, 0, &imap, |
243 | &nimaps, NULL, NULL); | 230 | &nimaps, NULL, NULL); |
@@ -245,54 +232,48 @@ xfs_iomap( | |||
245 | if (error) | 232 | if (error) |
246 | goto out; | 233 | goto out; |
247 | 234 | ||
248 | phase2: | 235 | switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) { |
249 | switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { | ||
250 | case BMAPI_WRITE: | 236 | case BMAPI_WRITE: |
251 | /* If we found an extent, return it */ | 237 | /* If we found an extent, return it */ |
252 | if (nimaps && | 238 | if (nimaps && |
253 | (imap.br_startblock != HOLESTARTBLOCK) && | 239 | (imap.br_startblock != HOLESTARTBLOCK) && |
254 | (imap.br_startblock != DELAYSTARTBLOCK)) { | 240 | (imap.br_startblock != DELAYSTARTBLOCK)) { |
255 | xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, | 241 | xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, ip, |
256 | offset, count, iomapp, &imap, flags); | 242 | offset, count, iomapp, &imap, flags); |
257 | break; | 243 | break; |
258 | } | 244 | } |
259 | 245 | ||
260 | if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { | 246 | if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { |
261 | error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset, | 247 | error = xfs_iomap_write_direct(ip, offset, count, flags, |
262 | count, flags, &imap, &nimaps, nimaps); | 248 | &imap, &nimaps, nimaps); |
263 | } else { | 249 | } else { |
264 | error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, | 250 | error = xfs_iomap_write_delay(ip, offset, count, flags, |
265 | flags, &imap, &nimaps); | 251 | &imap, &nimaps); |
266 | } | 252 | } |
267 | if (!error) { | 253 | if (!error) { |
268 | xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, io, | 254 | xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, ip, |
269 | offset, count, iomapp, &imap, flags); | 255 | offset, count, iomapp, &imap, flags); |
270 | } | 256 | } |
271 | iomap_flags = IOMAP_NEW; | 257 | iomap_flags = IOMAP_NEW; |
272 | break; | 258 | break; |
273 | case BMAPI_ALLOCATE: | 259 | case BMAPI_ALLOCATE: |
274 | /* If we found an extent, return it */ | 260 | /* If we found an extent, return it */ |
275 | XFS_IUNLOCK(mp, io, lockmode); | 261 | xfs_iunlock(ip, lockmode); |
276 | lockmode = 0; | 262 | lockmode = 0; |
277 | 263 | ||
278 | if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) { | 264 | if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) { |
279 | xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, | 265 | xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, ip, |
280 | offset, count, iomapp, &imap, flags); | 266 | offset, count, iomapp, &imap, flags); |
281 | break; | 267 | break; |
282 | } | 268 | } |
283 | 269 | ||
284 | error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, | 270 | error = xfs_iomap_write_allocate(ip, offset, count, |
285 | &imap, &nimaps); | 271 | &imap, &nimaps); |
286 | break; | 272 | break; |
287 | case BMAPI_UNWRITTEN: | ||
288 | lockmode = 0; | ||
289 | error = XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count); | ||
290 | nimaps = 0; | ||
291 | break; | ||
292 | } | 273 | } |
293 | 274 | ||
294 | if (nimaps) { | 275 | if (nimaps) { |
295 | *niomaps = xfs_imap_to_bmap(io, offset, &imap, | 276 | *niomaps = xfs_imap_to_bmap(ip, offset, &imap, |
296 | iomapp, nimaps, *niomaps, iomap_flags); | 277 | iomapp, nimaps, *niomaps, iomap_flags); |
297 | } else if (niomaps) { | 278 | } else if (niomaps) { |
298 | *niomaps = 0; | 279 | *niomaps = 0; |
@@ -300,14 +281,15 @@ phase2: | |||
300 | 281 | ||
301 | out: | 282 | out: |
302 | if (lockmode) | 283 | if (lockmode) |
303 | XFS_IUNLOCK(mp, io, lockmode); | 284 | xfs_iunlock(ip, lockmode); |
304 | return XFS_ERROR(error); | 285 | return XFS_ERROR(error); |
305 | } | 286 | } |
306 | 287 | ||
288 | |||
307 | STATIC int | 289 | STATIC int |
308 | xfs_iomap_eof_align_last_fsb( | 290 | xfs_iomap_eof_align_last_fsb( |
309 | xfs_mount_t *mp, | 291 | xfs_mount_t *mp, |
310 | xfs_iocore_t *io, | 292 | xfs_inode_t *ip, |
311 | xfs_fsize_t isize, | 293 | xfs_fsize_t isize, |
312 | xfs_extlen_t extsize, | 294 | xfs_extlen_t extsize, |
313 | xfs_fileoff_t *last_fsb) | 295 | xfs_fileoff_t *last_fsb) |
@@ -316,7 +298,7 @@ xfs_iomap_eof_align_last_fsb( | |||
316 | xfs_extlen_t align; | 298 | xfs_extlen_t align; |
317 | int eof, error; | 299 | int eof, error; |
318 | 300 | ||
319 | if (io->io_flags & XFS_IOCORE_RT) | 301 | if (XFS_IS_REALTIME_INODE(ip)) |
320 | ; | 302 | ; |
321 | /* | 303 | /* |
322 | * If mounted with the "-o swalloc" option, roundup the allocation | 304 | * If mounted with the "-o swalloc" option, roundup the allocation |
@@ -347,7 +329,7 @@ xfs_iomap_eof_align_last_fsb( | |||
347 | } | 329 | } |
348 | 330 | ||
349 | if (new_last_fsb) { | 331 | if (new_last_fsb) { |
350 | error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof); | 332 | error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof); |
351 | if (error) | 333 | if (error) |
352 | return error; | 334 | return error; |
353 | if (eof) | 335 | if (eof) |
@@ -416,7 +398,6 @@ xfs_iomap_write_direct( | |||
416 | int found) | 398 | int found) |
417 | { | 399 | { |
418 | xfs_mount_t *mp = ip->i_mount; | 400 | xfs_mount_t *mp = ip->i_mount; |
419 | xfs_iocore_t *io = &ip->i_iocore; | ||
420 | xfs_fileoff_t offset_fsb; | 401 | xfs_fileoff_t offset_fsb; |
421 | xfs_fileoff_t last_fsb; | 402 | xfs_fileoff_t last_fsb; |
422 | xfs_filblks_t count_fsb, resaligned; | 403 | xfs_filblks_t count_fsb, resaligned; |
@@ -446,13 +427,13 @@ xfs_iomap_write_direct( | |||
446 | extsz = xfs_get_extsz_hint(ip); | 427 | extsz = xfs_get_extsz_hint(ip); |
447 | 428 | ||
448 | isize = ip->i_size; | 429 | isize = ip->i_size; |
449 | if (io->io_new_size > isize) | 430 | if (ip->i_new_size > isize) |
450 | isize = io->io_new_size; | 431 | isize = ip->i_new_size; |
451 | 432 | ||
452 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 433 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
453 | last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); | 434 | last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); |
454 | if ((offset + count) > isize) { | 435 | if ((offset + count) > isize) { |
455 | error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz, | 436 | error = xfs_iomap_eof_align_last_fsb(mp, ip, isize, extsz, |
456 | &last_fsb); | 437 | &last_fsb); |
457 | if (error) | 438 | if (error) |
458 | goto error_out; | 439 | goto error_out; |
@@ -519,7 +500,7 @@ xfs_iomap_write_direct( | |||
519 | */ | 500 | */ |
520 | XFS_BMAP_INIT(&free_list, &firstfsb); | 501 | XFS_BMAP_INIT(&free_list, &firstfsb); |
521 | nimaps = 1; | 502 | nimaps = 1; |
522 | error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag, | 503 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, |
523 | &firstfsb, 0, &imap, &nimaps, &free_list, NULL); | 504 | &firstfsb, 0, &imap, &nimaps, &free_list, NULL); |
524 | if (error) | 505 | if (error) |
525 | goto error0; | 506 | goto error0; |
@@ -542,7 +523,8 @@ xfs_iomap_write_direct( | |||
542 | goto error_out; | 523 | goto error_out; |
543 | } | 524 | } |
544 | 525 | ||
545 | if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) { | 526 | if (unlikely(!imap.br_startblock && |
527 | !(XFS_IS_REALTIME_INODE(ip)))) { | ||
546 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | 528 | error = xfs_cmn_err_fsblock_zero(ip, &imap); |
547 | goto error_out; | 529 | goto error_out; |
548 | } | 530 | } |
@@ -577,7 +559,7 @@ error_out: | |||
577 | STATIC int | 559 | STATIC int |
578 | xfs_iomap_eof_want_preallocate( | 560 | xfs_iomap_eof_want_preallocate( |
579 | xfs_mount_t *mp, | 561 | xfs_mount_t *mp, |
580 | xfs_iocore_t *io, | 562 | xfs_inode_t *ip, |
581 | xfs_fsize_t isize, | 563 | xfs_fsize_t isize, |
582 | xfs_off_t offset, | 564 | xfs_off_t offset, |
583 | size_t count, | 565 | size_t count, |
@@ -604,7 +586,7 @@ xfs_iomap_eof_want_preallocate( | |||
604 | while (count_fsb > 0) { | 586 | while (count_fsb > 0) { |
605 | imaps = nimaps; | 587 | imaps = nimaps; |
606 | firstblock = NULLFSBLOCK; | 588 | firstblock = NULLFSBLOCK; |
607 | error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0, | 589 | error = xfs_bmapi(NULL, ip, start_fsb, count_fsb, 0, |
608 | &firstblock, 0, imap, &imaps, NULL, NULL); | 590 | &firstblock, 0, imap, &imaps, NULL, NULL); |
609 | if (error) | 591 | if (error) |
610 | return error; | 592 | return error; |
@@ -630,7 +612,6 @@ xfs_iomap_write_delay( | |||
630 | int *nmaps) | 612 | int *nmaps) |
631 | { | 613 | { |
632 | xfs_mount_t *mp = ip->i_mount; | 614 | xfs_mount_t *mp = ip->i_mount; |
633 | xfs_iocore_t *io = &ip->i_iocore; | ||
634 | xfs_fileoff_t offset_fsb; | 615 | xfs_fileoff_t offset_fsb; |
635 | xfs_fileoff_t last_fsb; | 616 | xfs_fileoff_t last_fsb; |
636 | xfs_off_t aligned_offset; | 617 | xfs_off_t aligned_offset; |
@@ -658,10 +639,10 @@ xfs_iomap_write_delay( | |||
658 | 639 | ||
659 | retry: | 640 | retry: |
660 | isize = ip->i_size; | 641 | isize = ip->i_size; |
661 | if (io->io_new_size > isize) | 642 | if (ip->i_new_size > isize) |
662 | isize = io->io_new_size; | 643 | isize = ip->i_new_size; |
663 | 644 | ||
664 | error = xfs_iomap_eof_want_preallocate(mp, io, isize, offset, count, | 645 | error = xfs_iomap_eof_want_preallocate(mp, ip, isize, offset, count, |
665 | ioflag, imap, XFS_WRITE_IMAPS, &prealloc); | 646 | ioflag, imap, XFS_WRITE_IMAPS, &prealloc); |
666 | if (error) | 647 | if (error) |
667 | return error; | 648 | return error; |
@@ -675,7 +656,7 @@ retry: | |||
675 | } | 656 | } |
676 | 657 | ||
677 | if (prealloc || extsz) { | 658 | if (prealloc || extsz) { |
678 | error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz, | 659 | error = xfs_iomap_eof_align_last_fsb(mp, ip, isize, extsz, |
679 | &last_fsb); | 660 | &last_fsb); |
680 | if (error) | 661 | if (error) |
681 | return error; | 662 | return error; |
@@ -683,7 +664,7 @@ retry: | |||
683 | 664 | ||
684 | nimaps = XFS_WRITE_IMAPS; | 665 | nimaps = XFS_WRITE_IMAPS; |
685 | firstblock = NULLFSBLOCK; | 666 | firstblock = NULLFSBLOCK; |
686 | error = XFS_BMAPI(mp, NULL, io, offset_fsb, | 667 | error = xfs_bmapi(NULL, ip, offset_fsb, |
687 | (xfs_filblks_t)(last_fsb - offset_fsb), | 668 | (xfs_filblks_t)(last_fsb - offset_fsb), |
688 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | | 669 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | |
689 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, | 670 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, |
@@ -697,7 +678,7 @@ retry: | |||
697 | */ | 678 | */ |
698 | if (nimaps == 0) { | 679 | if (nimaps == 0) { |
699 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, | 680 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, |
700 | io, offset, count); | 681 | ip, offset, count); |
701 | if (xfs_flush_space(ip, &fsynced, &ioflag)) | 682 | if (xfs_flush_space(ip, &fsynced, &ioflag)) |
702 | return XFS_ERROR(ENOSPC); | 683 | return XFS_ERROR(ENOSPC); |
703 | 684 | ||
@@ -705,7 +686,8 @@ retry: | |||
705 | goto retry; | 686 | goto retry; |
706 | } | 687 | } |
707 | 688 | ||
708 | if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT))) | 689 | if (unlikely(!imap[0].br_startblock && |
690 | !(XFS_IS_REALTIME_INODE(ip)))) | ||
709 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); | 691 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); |
710 | 692 | ||
711 | *ret_imap = imap[0]; | 693 | *ret_imap = imap[0]; |
@@ -720,6 +702,9 @@ retry: | |||
720 | * the originating callers request. | 702 | * the originating callers request. |
721 | * | 703 | * |
722 | * Called without a lock on the inode. | 704 | * Called without a lock on the inode. |
705 | * | ||
706 | * We no longer bother to look at the incoming map - all we have to | ||
707 | * guarantee is that whatever we allocate fills the required range. | ||
723 | */ | 708 | */ |
724 | int | 709 | int |
725 | xfs_iomap_write_allocate( | 710 | xfs_iomap_write_allocate( |
@@ -730,15 +715,14 @@ xfs_iomap_write_allocate( | |||
730 | int *retmap) | 715 | int *retmap) |
731 | { | 716 | { |
732 | xfs_mount_t *mp = ip->i_mount; | 717 | xfs_mount_t *mp = ip->i_mount; |
733 | xfs_iocore_t *io = &ip->i_iocore; | ||
734 | xfs_fileoff_t offset_fsb, last_block; | 718 | xfs_fileoff_t offset_fsb, last_block; |
735 | xfs_fileoff_t end_fsb, map_start_fsb; | 719 | xfs_fileoff_t end_fsb, map_start_fsb; |
736 | xfs_fsblock_t first_block; | 720 | xfs_fsblock_t first_block; |
737 | xfs_bmap_free_t free_list; | 721 | xfs_bmap_free_t free_list; |
738 | xfs_filblks_t count_fsb; | 722 | xfs_filblks_t count_fsb; |
739 | xfs_bmbt_irec_t imap[XFS_STRAT_WRITE_IMAPS]; | 723 | xfs_bmbt_irec_t imap; |
740 | xfs_trans_t *tp; | 724 | xfs_trans_t *tp; |
741 | int i, nimaps, committed; | 725 | int nimaps, committed; |
742 | int error = 0; | 726 | int error = 0; |
743 | int nres; | 727 | int nres; |
744 | 728 | ||
@@ -785,13 +769,38 @@ xfs_iomap_write_allocate( | |||
785 | 769 | ||
786 | XFS_BMAP_INIT(&free_list, &first_block); | 770 | XFS_BMAP_INIT(&free_list, &first_block); |
787 | 771 | ||
788 | nimaps = XFS_STRAT_WRITE_IMAPS; | ||
789 | /* | 772 | /* |
790 | * Ensure we don't go beyond eof - it is possible | 773 | * it is possible that the extents have changed since |
791 | * the extents changed since we did the read call, | 774 | * we did the read call as we dropped the ilock for a |
792 | * we dropped the ilock in the interim. | 775 | * while. We have to be careful about truncates or hole |
776 | * punchs here - we are not allowed to allocate | ||
777 | * non-delalloc blocks here. | ||
778 | * | ||
779 | * The only protection against truncation is the pages | ||
780 | * for the range we are being asked to convert are | ||
781 | * locked and hence a truncate will block on them | ||
782 | * first. | ||
783 | * | ||
784 | * As a result, if we go beyond the range we really | ||
785 | * need and hit an delalloc extent boundary followed by | ||
786 | * a hole while we have excess blocks in the map, we | ||
787 | * will fill the hole incorrectly and overrun the | ||
788 | * transaction reservation. | ||
789 | * | ||
790 | * Using a single map prevents this as we are forced to | ||
791 | * check each map we look for overlap with the desired | ||
792 | * range and abort as soon as we find it. Also, given | ||
793 | * that we only return a single map, having one beyond | ||
794 | * what we can return is probably a bit silly. | ||
795 | * | ||
796 | * We also need to check that we don't go beyond EOF; | ||
797 | * this is a truncate optimisation as a truncate sets | ||
798 | * the new file size before block on the pages we | ||
799 | * currently have locked under writeback. Because they | ||
800 | * are about to be tossed, we don't need to write them | ||
801 | * back.... | ||
793 | */ | 802 | */ |
794 | 803 | nimaps = 1; | |
795 | end_fsb = XFS_B_TO_FSB(mp, ip->i_size); | 804 | end_fsb = XFS_B_TO_FSB(mp, ip->i_size); |
796 | xfs_bmap_last_offset(NULL, ip, &last_block, | 805 | xfs_bmap_last_offset(NULL, ip, &last_block, |
797 | XFS_DATA_FORK); | 806 | XFS_DATA_FORK); |
@@ -805,9 +814,9 @@ xfs_iomap_write_allocate( | |||
805 | } | 814 | } |
806 | 815 | ||
807 | /* Go get the actual blocks */ | 816 | /* Go get the actual blocks */ |
808 | error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb, | 817 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, |
809 | XFS_BMAPI_WRITE, &first_block, 1, | 818 | XFS_BMAPI_WRITE, &first_block, 1, |
810 | imap, &nimaps, &free_list, NULL); | 819 | &imap, &nimaps, &free_list, NULL); |
811 | if (error) | 820 | if (error) |
812 | goto trans_cancel; | 821 | goto trans_cancel; |
813 | 822 | ||
@@ -826,27 +835,24 @@ xfs_iomap_write_allocate( | |||
826 | * See if we were able to allocate an extent that | 835 | * See if we were able to allocate an extent that |
827 | * covers at least part of the callers request | 836 | * covers at least part of the callers request |
828 | */ | 837 | */ |
829 | for (i = 0; i < nimaps; i++) { | 838 | if (unlikely(!imap.br_startblock && |
830 | if (unlikely(!imap[i].br_startblock && | 839 | XFS_IS_REALTIME_INODE(ip))) |
831 | !(io->io_flags & XFS_IOCORE_RT))) | 840 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
832 | return xfs_cmn_err_fsblock_zero(ip, &imap[i]); | 841 | if ((offset_fsb >= imap.br_startoff) && |
833 | if ((offset_fsb >= imap[i].br_startoff) && | 842 | (offset_fsb < (imap.br_startoff + |
834 | (offset_fsb < (imap[i].br_startoff + | 843 | imap.br_blockcount))) { |
835 | imap[i].br_blockcount))) { | 844 | *map = imap; |
836 | *map = imap[i]; | 845 | *retmap = 1; |
837 | *retmap = 1; | 846 | XFS_STATS_INC(xs_xstrat_quick); |
838 | XFS_STATS_INC(xs_xstrat_quick); | 847 | return 0; |
839 | return 0; | ||
840 | } | ||
841 | count_fsb -= imap[i].br_blockcount; | ||
842 | } | 848 | } |
843 | 849 | ||
844 | /* So far we have not mapped the requested part of the | 850 | /* |
851 | * So far we have not mapped the requested part of the | ||
845 | * file, just surrounding data, try again. | 852 | * file, just surrounding data, try again. |
846 | */ | 853 | */ |
847 | nimaps--; | 854 | count_fsb -= imap.br_blockcount; |
848 | map_start_fsb = imap[nimaps].br_startoff + | 855 | map_start_fsb = imap.br_startoff + imap.br_blockcount; |
849 | imap[nimaps].br_blockcount; | ||
850 | } | 856 | } |
851 | 857 | ||
852 | trans_cancel: | 858 | trans_cancel: |
@@ -864,7 +870,6 @@ xfs_iomap_write_unwritten( | |||
864 | size_t count) | 870 | size_t count) |
865 | { | 871 | { |
866 | xfs_mount_t *mp = ip->i_mount; | 872 | xfs_mount_t *mp = ip->i_mount; |
867 | xfs_iocore_t *io = &ip->i_iocore; | ||
868 | xfs_fileoff_t offset_fsb; | 873 | xfs_fileoff_t offset_fsb; |
869 | xfs_filblks_t count_fsb; | 874 | xfs_filblks_t count_fsb; |
870 | xfs_filblks_t numblks_fsb; | 875 | xfs_filblks_t numblks_fsb; |
@@ -877,8 +882,7 @@ xfs_iomap_write_unwritten( | |||
877 | int committed; | 882 | int committed; |
878 | int error; | 883 | int error; |
879 | 884 | ||
880 | xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN, | 885 | xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN, ip, offset, count); |
881 | &ip->i_iocore, offset, count); | ||
882 | 886 | ||
883 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 887 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
884 | count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 888 | count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
@@ -912,7 +916,7 @@ xfs_iomap_write_unwritten( | |||
912 | */ | 916 | */ |
913 | XFS_BMAP_INIT(&free_list, &firstfsb); | 917 | XFS_BMAP_INIT(&free_list, &firstfsb); |
914 | nimaps = 1; | 918 | nimaps = 1; |
915 | error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, | 919 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, |
916 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, | 920 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, |
917 | 1, &imap, &nimaps, &free_list, NULL); | 921 | 1, &imap, &nimaps, &free_list, NULL); |
918 | if (error) | 922 | if (error) |
@@ -928,7 +932,7 @@ xfs_iomap_write_unwritten( | |||
928 | return XFS_ERROR(error); | 932 | return XFS_ERROR(error); |
929 | 933 | ||
930 | if (unlikely(!imap.br_startblock && | 934 | if (unlikely(!imap.br_startblock && |
931 | !(io->io_flags & XFS_IOCORE_RT))) | 935 | !(XFS_IS_REALTIME_INODE(ip)))) |
932 | return xfs_cmn_err_fsblock_zero(ip, &imap); | 936 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
933 | 937 | ||
934 | if ((numblks_fsb = imap.br_blockcount) == 0) { | 938 | if ((numblks_fsb = imap.br_blockcount) == 0) { |
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index f5c09887fe93..ee1a0c134cc2 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h | |||
@@ -36,14 +36,12 @@ typedef enum { | |||
36 | BMAPI_READ = (1 << 0), /* read extents */ | 36 | BMAPI_READ = (1 << 0), /* read extents */ |
37 | BMAPI_WRITE = (1 << 1), /* create extents */ | 37 | BMAPI_WRITE = (1 << 1), /* create extents */ |
38 | BMAPI_ALLOCATE = (1 << 2), /* delayed allocate to real extents */ | 38 | BMAPI_ALLOCATE = (1 << 2), /* delayed allocate to real extents */ |
39 | BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ | ||
40 | /* modifiers */ | 39 | /* modifiers */ |
41 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ | 40 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ |
42 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ | 41 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ |
43 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ | 42 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ |
44 | BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ | 43 | BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ |
45 | BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ | 44 | BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ |
46 | BMAPI_DEVICE = (1 << 9), /* we only want to know the device */ | ||
47 | } bmapi_flags_t; | 45 | } bmapi_flags_t; |
48 | 46 | ||
49 | 47 | ||
@@ -73,11 +71,10 @@ typedef struct xfs_iomap { | |||
73 | iomap_flags_t iomap_flags; | 71 | iomap_flags_t iomap_flags; |
74 | } xfs_iomap_t; | 72 | } xfs_iomap_t; |
75 | 73 | ||
76 | struct xfs_iocore; | ||
77 | struct xfs_inode; | 74 | struct xfs_inode; |
78 | struct xfs_bmbt_irec; | 75 | struct xfs_bmbt_irec; |
79 | 76 | ||
80 | extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, | 77 | extern int xfs_iomap(struct xfs_inode *, xfs_off_t, ssize_t, int, |
81 | struct xfs_iomap *, int *); | 78 | struct xfs_iomap *, int *); |
82 | extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, | 79 | extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, |
83 | int, struct xfs_bmbt_irec *, int *, int); | 80 | int, struct xfs_bmbt_irec *, int *, int); |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 9fc4c2886529..658aab6b1bbf 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -170,7 +170,7 @@ xfs_bulkstat_one_dinode( | |||
170 | buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); | 170 | buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); |
171 | buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); | 171 | buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); |
172 | buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); | 172 | buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); |
173 | buf->bs_xflags = xfs_dic2xflags(dic); | 173 | buf->bs_xflags = xfs_dic2xflags(dip); |
174 | buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; | 174 | buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; |
175 | buf->bs_extents = be32_to_cpu(dic->di_nextents); | 175 | buf->bs_extents = be32_to_cpu(dic->di_nextents); |
176 | buf->bs_gen = be32_to_cpu(dic->di_gen); | 176 | buf->bs_gen = be32_to_cpu(dic->di_gen); |
@@ -291,7 +291,7 @@ xfs_bulkstat_use_dinode( | |||
291 | dip = (xfs_dinode_t *) | 291 | dip = (xfs_dinode_t *) |
292 | xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); | 292 | xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); |
293 | /* | 293 | /* |
294 | * Check the buffer containing the on-disk inode for di_nlink == 0. | 294 | * Check the buffer containing the on-disk inode for di_mode == 0. |
295 | * This is to prevent xfs_bulkstat from picking up just reclaimed | 295 | * This is to prevent xfs_bulkstat from picking up just reclaimed |
296 | * inodes that have their in-core state initialized but not flushed | 296 | * inodes that have their in-core state initialized but not flushed |
297 | * to disk yet. This is a temporary hack that would require a proper | 297 | * to disk yet. This is a temporary hack that would require a proper |
@@ -299,7 +299,7 @@ xfs_bulkstat_use_dinode( | |||
299 | */ | 299 | */ |
300 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC || | 300 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC || |
301 | !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) || | 301 | !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) || |
302 | !dip->di_core.di_nlink) | 302 | !dip->di_core.di_mode) |
303 | return 0; | 303 | return 0; |
304 | if (flags & BULKSTAT_FG_QUICK) { | 304 | if (flags & BULKSTAT_FG_QUICK) { |
305 | *dipp = dip; | 305 | *dipp = dip; |
@@ -307,7 +307,7 @@ xfs_bulkstat_use_dinode( | |||
307 | } | 307 | } |
308 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ | 308 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ |
309 | aformat = dip->di_core.di_aformat; | 309 | aformat = dip->di_core.di_aformat; |
310 | if ((XFS_CFORK_Q(&dip->di_core) == 0) || | 310 | if ((XFS_DFORK_Q(dip) == 0) || |
311 | (aformat == XFS_DINODE_FMT_LOCAL) || | 311 | (aformat == XFS_DINODE_FMT_LOCAL) || |
312 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { | 312 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { |
313 | *dipp = dip; | 313 | *dipp = dip; |
@@ -399,7 +399,7 @@ xfs_bulkstat( | |||
399 | (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); | 399 | (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); |
400 | nimask = ~(nicluster - 1); | 400 | nimask = ~(nicluster - 1); |
401 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; | 401 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; |
402 | irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4, | 402 | irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4, |
403 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); | 403 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); |
404 | nirbuf = irbsize / sizeof(*irbuf); | 404 | nirbuf = irbsize / sizeof(*irbuf); |
405 | 405 | ||
@@ -830,7 +830,7 @@ xfs_inumbers( | |||
830 | agino = XFS_INO_TO_AGINO(mp, ino); | 830 | agino = XFS_INO_TO_AGINO(mp, ino); |
831 | left = *count; | 831 | left = *count; |
832 | *count = 0; | 832 | *count = 0; |
833 | bcount = MIN(left, (int)(NBPP / sizeof(*buffer))); | 833 | bcount = MIN(left, (int)(PAGE_SIZE / sizeof(*buffer))); |
834 | buffer = kmem_alloc(bcount * sizeof(*buffer), KM_SLEEP); | 834 | buffer = kmem_alloc(bcount * sizeof(*buffer), KM_SLEEP); |
835 | error = bufidx = 0; | 835 | error = bufidx = 0; |
836 | cur = NULL; | 836 | cur = NULL; |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 77c12715a7d0..b3ac3805d3c4 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -399,10 +399,10 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ | |||
399 | { | 399 | { |
400 | xlog_t *log = mp->m_log; | 400 | xlog_t *log = mp->m_log; |
401 | xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; | 401 | xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; |
402 | int abortflg, spl; | 402 | int abortflg; |
403 | 403 | ||
404 | cb->cb_next = NULL; | 404 | cb->cb_next = NULL; |
405 | spl = LOG_LOCK(log); | 405 | spin_lock(&log->l_icloglock); |
406 | abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); | 406 | abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); |
407 | if (!abortflg) { | 407 | if (!abortflg) { |
408 | ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) || | 408 | ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) || |
@@ -411,7 +411,7 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ | |||
411 | *(iclog->ic_callback_tail) = cb; | 411 | *(iclog->ic_callback_tail) = cb; |
412 | iclog->ic_callback_tail = &(cb->cb_next); | 412 | iclog->ic_callback_tail = &(cb->cb_next); |
413 | } | 413 | } |
414 | LOG_UNLOCK(log, spl); | 414 | spin_unlock(&log->l_icloglock); |
415 | return abortflg; | 415 | return abortflg; |
416 | } /* xfs_log_notify */ | 416 | } /* xfs_log_notify */ |
417 | 417 | ||
@@ -498,11 +498,14 @@ xfs_log_reserve(xfs_mount_t *mp, | |||
498 | * Return error or zero. | 498 | * Return error or zero. |
499 | */ | 499 | */ |
500 | int | 500 | int |
501 | xfs_log_mount(xfs_mount_t *mp, | 501 | xfs_log_mount( |
502 | xfs_buftarg_t *log_target, | 502 | xfs_mount_t *mp, |
503 | xfs_daddr_t blk_offset, | 503 | xfs_buftarg_t *log_target, |
504 | int num_bblks) | 504 | xfs_daddr_t blk_offset, |
505 | int num_bblks) | ||
505 | { | 506 | { |
507 | int error; | ||
508 | |||
506 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) | 509 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) |
507 | cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname); | 510 | cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname); |
508 | else { | 511 | else { |
@@ -515,11 +518,21 @@ xfs_log_mount(xfs_mount_t *mp, | |||
515 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); | 518 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); |
516 | 519 | ||
517 | /* | 520 | /* |
521 | * Initialize the AIL now we have a log. | ||
522 | */ | ||
523 | spin_lock_init(&mp->m_ail_lock); | ||
524 | error = xfs_trans_ail_init(mp); | ||
525 | if (error) { | ||
526 | cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error); | ||
527 | goto error; | ||
528 | } | ||
529 | |||
530 | /* | ||
518 | * skip log recovery on a norecovery mount. pretend it all | 531 | * skip log recovery on a norecovery mount. pretend it all |
519 | * just worked. | 532 | * just worked. |
520 | */ | 533 | */ |
521 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { | 534 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
522 | int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY); | 535 | int readonly = (mp->m_flags & XFS_MOUNT_RDONLY); |
523 | 536 | ||
524 | if (readonly) | 537 | if (readonly) |
525 | mp->m_flags &= ~XFS_MOUNT_RDONLY; | 538 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
@@ -530,8 +543,7 @@ xfs_log_mount(xfs_mount_t *mp, | |||
530 | mp->m_flags |= XFS_MOUNT_RDONLY; | 543 | mp->m_flags |= XFS_MOUNT_RDONLY; |
531 | if (error) { | 544 | if (error) { |
532 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); | 545 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); |
533 | xlog_dealloc_log(mp->m_log); | 546 | goto error; |
534 | return error; | ||
535 | } | 547 | } |
536 | } | 548 | } |
537 | 549 | ||
@@ -540,6 +552,9 @@ xfs_log_mount(xfs_mount_t *mp, | |||
540 | 552 | ||
541 | /* End mounting message in xfs_log_mount_finish */ | 553 | /* End mounting message in xfs_log_mount_finish */ |
542 | return 0; | 554 | return 0; |
555 | error: | ||
556 | xfs_log_unmount_dealloc(mp); | ||
557 | return error; | ||
543 | } /* xfs_log_mount */ | 558 | } /* xfs_log_mount */ |
544 | 559 | ||
545 | /* | 560 | /* |
@@ -606,7 +621,6 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
606 | xfs_log_ticket_t tic = NULL; | 621 | xfs_log_ticket_t tic = NULL; |
607 | xfs_lsn_t lsn; | 622 | xfs_lsn_t lsn; |
608 | int error; | 623 | int error; |
609 | SPLDECL(s); | ||
610 | 624 | ||
611 | /* the data section must be 32 bit size aligned */ | 625 | /* the data section must be 32 bit size aligned */ |
612 | struct { | 626 | struct { |
@@ -659,24 +673,24 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
659 | } | 673 | } |
660 | 674 | ||
661 | 675 | ||
662 | s = LOG_LOCK(log); | 676 | spin_lock(&log->l_icloglock); |
663 | iclog = log->l_iclog; | 677 | iclog = log->l_iclog; |
664 | iclog->ic_refcnt++; | 678 | iclog->ic_refcnt++; |
665 | LOG_UNLOCK(log, s); | 679 | spin_unlock(&log->l_icloglock); |
666 | xlog_state_want_sync(log, iclog); | 680 | xlog_state_want_sync(log, iclog); |
667 | (void) xlog_state_release_iclog(log, iclog); | 681 | (void) xlog_state_release_iclog(log, iclog); |
668 | 682 | ||
669 | s = LOG_LOCK(log); | 683 | spin_lock(&log->l_icloglock); |
670 | if (!(iclog->ic_state == XLOG_STATE_ACTIVE || | 684 | if (!(iclog->ic_state == XLOG_STATE_ACTIVE || |
671 | iclog->ic_state == XLOG_STATE_DIRTY)) { | 685 | iclog->ic_state == XLOG_STATE_DIRTY)) { |
672 | if (!XLOG_FORCED_SHUTDOWN(log)) { | 686 | if (!XLOG_FORCED_SHUTDOWN(log)) { |
673 | sv_wait(&iclog->ic_forcesema, PMEM, | 687 | sv_wait(&iclog->ic_forcesema, PMEM, |
674 | &log->l_icloglock, s); | 688 | &log->l_icloglock, s); |
675 | } else { | 689 | } else { |
676 | LOG_UNLOCK(log, s); | 690 | spin_unlock(&log->l_icloglock); |
677 | } | 691 | } |
678 | } else { | 692 | } else { |
679 | LOG_UNLOCK(log, s); | 693 | spin_unlock(&log->l_icloglock); |
680 | } | 694 | } |
681 | if (tic) { | 695 | if (tic) { |
682 | xlog_trace_loggrant(log, tic, "unmount rec"); | 696 | xlog_trace_loggrant(log, tic, "unmount rec"); |
@@ -697,15 +711,15 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
697 | * a file system that went into forced_shutdown as | 711 | * a file system that went into forced_shutdown as |
698 | * the result of an unmount.. | 712 | * the result of an unmount.. |
699 | */ | 713 | */ |
700 | s = LOG_LOCK(log); | 714 | spin_lock(&log->l_icloglock); |
701 | iclog = log->l_iclog; | 715 | iclog = log->l_iclog; |
702 | iclog->ic_refcnt++; | 716 | iclog->ic_refcnt++; |
703 | LOG_UNLOCK(log, s); | 717 | spin_unlock(&log->l_icloglock); |
704 | 718 | ||
705 | xlog_state_want_sync(log, iclog); | 719 | xlog_state_want_sync(log, iclog); |
706 | (void) xlog_state_release_iclog(log, iclog); | 720 | (void) xlog_state_release_iclog(log, iclog); |
707 | 721 | ||
708 | s = LOG_LOCK(log); | 722 | spin_lock(&log->l_icloglock); |
709 | 723 | ||
710 | if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE | 724 | if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE |
711 | || iclog->ic_state == XLOG_STATE_DIRTY | 725 | || iclog->ic_state == XLOG_STATE_DIRTY |
@@ -714,7 +728,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
714 | sv_wait(&iclog->ic_forcesema, PMEM, | 728 | sv_wait(&iclog->ic_forcesema, PMEM, |
715 | &log->l_icloglock, s); | 729 | &log->l_icloglock, s); |
716 | } else { | 730 | } else { |
717 | LOG_UNLOCK(log, s); | 731 | spin_unlock(&log->l_icloglock); |
718 | } | 732 | } |
719 | } | 733 | } |
720 | 734 | ||
@@ -723,10 +737,14 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
723 | 737 | ||
724 | /* | 738 | /* |
725 | * Deallocate log structures for unmount/relocation. | 739 | * Deallocate log structures for unmount/relocation. |
740 | * | ||
741 | * We need to stop the aild from running before we destroy | ||
742 | * and deallocate the log as the aild references the log. | ||
726 | */ | 743 | */ |
727 | void | 744 | void |
728 | xfs_log_unmount_dealloc(xfs_mount_t *mp) | 745 | xfs_log_unmount_dealloc(xfs_mount_t *mp) |
729 | { | 746 | { |
747 | xfs_trans_ail_destroy(mp); | ||
730 | xlog_dealloc_log(mp->m_log); | 748 | xlog_dealloc_log(mp->m_log); |
731 | } | 749 | } |
732 | 750 | ||
@@ -762,20 +780,18 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
762 | xlog_ticket_t *tic; | 780 | xlog_ticket_t *tic; |
763 | xlog_t *log = mp->m_log; | 781 | xlog_t *log = mp->m_log; |
764 | int need_bytes, free_bytes, cycle, bytes; | 782 | int need_bytes, free_bytes, cycle, bytes; |
765 | SPLDECL(s); | ||
766 | 783 | ||
767 | if (XLOG_FORCED_SHUTDOWN(log)) | 784 | if (XLOG_FORCED_SHUTDOWN(log)) |
768 | return; | 785 | return; |
769 | ASSERT(!XFS_FORCED_SHUTDOWN(mp)); | ||
770 | 786 | ||
771 | if (tail_lsn == 0) { | 787 | if (tail_lsn == 0) { |
772 | /* needed since sync_lsn is 64 bits */ | 788 | /* needed since sync_lsn is 64 bits */ |
773 | s = LOG_LOCK(log); | 789 | spin_lock(&log->l_icloglock); |
774 | tail_lsn = log->l_last_sync_lsn; | 790 | tail_lsn = log->l_last_sync_lsn; |
775 | LOG_UNLOCK(log, s); | 791 | spin_unlock(&log->l_icloglock); |
776 | } | 792 | } |
777 | 793 | ||
778 | s = GRANT_LOCK(log); | 794 | spin_lock(&log->l_grant_lock); |
779 | 795 | ||
780 | /* Also an invalid lsn. 1 implies that we aren't passing in a valid | 796 | /* Also an invalid lsn. 1 implies that we aren't passing in a valid |
781 | * tail_lsn. | 797 | * tail_lsn. |
@@ -824,7 +840,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
824 | tic = tic->t_next; | 840 | tic = tic->t_next; |
825 | } while (tic != log->l_reserve_headq); | 841 | } while (tic != log->l_reserve_headq); |
826 | } | 842 | } |
827 | GRANT_UNLOCK(log, s); | 843 | spin_unlock(&log->l_grant_lock); |
828 | } /* xfs_log_move_tail */ | 844 | } /* xfs_log_move_tail */ |
829 | 845 | ||
830 | /* | 846 | /* |
@@ -836,14 +852,13 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
836 | int | 852 | int |
837 | xfs_log_need_covered(xfs_mount_t *mp) | 853 | xfs_log_need_covered(xfs_mount_t *mp) |
838 | { | 854 | { |
839 | SPLDECL(s); | ||
840 | int needed = 0, gen; | 855 | int needed = 0, gen; |
841 | xlog_t *log = mp->m_log; | 856 | xlog_t *log = mp->m_log; |
842 | 857 | ||
843 | if (!xfs_fs_writable(mp)) | 858 | if (!xfs_fs_writable(mp)) |
844 | return 0; | 859 | return 0; |
845 | 860 | ||
846 | s = LOG_LOCK(log); | 861 | spin_lock(&log->l_icloglock); |
847 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || | 862 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || |
848 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) | 863 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) |
849 | && !xfs_trans_first_ail(mp, &gen) | 864 | && !xfs_trans_first_ail(mp, &gen) |
@@ -856,7 +871,7 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
856 | } | 871 | } |
857 | needed = 1; | 872 | needed = 1; |
858 | } | 873 | } |
859 | LOG_UNLOCK(log, s); | 874 | spin_unlock(&log->l_icloglock); |
860 | return needed; | 875 | return needed; |
861 | } | 876 | } |
862 | 877 | ||
@@ -881,17 +896,16 @@ xfs_lsn_t | |||
881 | xlog_assign_tail_lsn(xfs_mount_t *mp) | 896 | xlog_assign_tail_lsn(xfs_mount_t *mp) |
882 | { | 897 | { |
883 | xfs_lsn_t tail_lsn; | 898 | xfs_lsn_t tail_lsn; |
884 | SPLDECL(s); | ||
885 | xlog_t *log = mp->m_log; | 899 | xlog_t *log = mp->m_log; |
886 | 900 | ||
887 | tail_lsn = xfs_trans_tail_ail(mp); | 901 | tail_lsn = xfs_trans_tail_ail(mp); |
888 | s = GRANT_LOCK(log); | 902 | spin_lock(&log->l_grant_lock); |
889 | if (tail_lsn != 0) { | 903 | if (tail_lsn != 0) { |
890 | log->l_tail_lsn = tail_lsn; | 904 | log->l_tail_lsn = tail_lsn; |
891 | } else { | 905 | } else { |
892 | tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn; | 906 | tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn; |
893 | } | 907 | } |
894 | GRANT_UNLOCK(log, s); | 908 | spin_unlock(&log->l_grant_lock); |
895 | 909 | ||
896 | return tail_lsn; | 910 | return tail_lsn; |
897 | } /* xlog_assign_tail_lsn */ | 911 | } /* xlog_assign_tail_lsn */ |
@@ -911,7 +925,7 @@ xlog_assign_tail_lsn(xfs_mount_t *mp) | |||
911 | * the tail. The details of this case are described below, but the end | 925 | * the tail. The details of this case are described below, but the end |
912 | * result is that we return the size of the log as the amount of space left. | 926 | * result is that we return the size of the log as the amount of space left. |
913 | */ | 927 | */ |
914 | int | 928 | STATIC int |
915 | xlog_space_left(xlog_t *log, int cycle, int bytes) | 929 | xlog_space_left(xlog_t *log, int cycle, int bytes) |
916 | { | 930 | { |
917 | int free_bytes; | 931 | int free_bytes; |
@@ -1165,7 +1179,7 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1165 | log->l_flags |= XLOG_ACTIVE_RECOVERY; | 1179 | log->l_flags |= XLOG_ACTIVE_RECOVERY; |
1166 | 1180 | ||
1167 | log->l_prev_block = -1; | 1181 | log->l_prev_block = -1; |
1168 | ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, 1, 0); | 1182 | log->l_tail_lsn = xlog_assign_lsn(1, 0); |
1169 | /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ | 1183 | /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ |
1170 | log->l_last_sync_lsn = log->l_tail_lsn; | 1184 | log->l_last_sync_lsn = log->l_tail_lsn; |
1171 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ | 1185 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ |
@@ -1193,8 +1207,8 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1193 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); | 1207 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); |
1194 | log->l_xbuf = bp; | 1208 | log->l_xbuf = bp; |
1195 | 1209 | ||
1196 | spinlock_init(&log->l_icloglock, "iclog"); | 1210 | spin_lock_init(&log->l_icloglock); |
1197 | spinlock_init(&log->l_grant_lock, "grhead_iclog"); | 1211 | spin_lock_init(&log->l_grant_lock); |
1198 | initnsema(&log->l_flushsema, 0, "ic-flush"); | 1212 | initnsema(&log->l_flushsema, 0, "ic-flush"); |
1199 | xlog_state_ticket_alloc(log); /* wait until after icloglock inited */ | 1213 | xlog_state_ticket_alloc(log); /* wait until after icloglock inited */ |
1200 | 1214 | ||
@@ -1231,12 +1245,12 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1231 | 1245 | ||
1232 | head = &iclog->ic_header; | 1246 | head = &iclog->ic_header; |
1233 | memset(head, 0, sizeof(xlog_rec_header_t)); | 1247 | memset(head, 0, sizeof(xlog_rec_header_t)); |
1234 | INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM); | 1248 | head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
1235 | INT_SET(head->h_version, ARCH_CONVERT, | 1249 | head->h_version = cpu_to_be32( |
1236 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); | 1250 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); |
1237 | INT_SET(head->h_size, ARCH_CONVERT, log->l_iclog_size); | 1251 | head->h_size = cpu_to_be32(log->l_iclog_size); |
1238 | /* new fields */ | 1252 | /* new fields */ |
1239 | INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT); | 1253 | head->h_fmt = cpu_to_be32(XLOG_FMT); |
1240 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); | 1254 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); |
1241 | 1255 | ||
1242 | 1256 | ||
@@ -1293,7 +1307,7 @@ xlog_commit_record(xfs_mount_t *mp, | |||
1293 | * pushes on an lsn which is further along in the log once we reach the high | 1307 | * pushes on an lsn which is further along in the log once we reach the high |
1294 | * water mark. In this manner, we would be creating a low water mark. | 1308 | * water mark. In this manner, we would be creating a low water mark. |
1295 | */ | 1309 | */ |
1296 | void | 1310 | STATIC void |
1297 | xlog_grant_push_ail(xfs_mount_t *mp, | 1311 | xlog_grant_push_ail(xfs_mount_t *mp, |
1298 | int need_bytes) | 1312 | int need_bytes) |
1299 | { | 1313 | { |
@@ -1305,11 +1319,10 @@ xlog_grant_push_ail(xfs_mount_t *mp, | |||
1305 | int threshold_block; /* block in lsn we'd like to be at */ | 1319 | int threshold_block; /* block in lsn we'd like to be at */ |
1306 | int threshold_cycle; /* lsn cycle we'd like to be at */ | 1320 | int threshold_cycle; /* lsn cycle we'd like to be at */ |
1307 | int free_threshold; | 1321 | int free_threshold; |
1308 | SPLDECL(s); | ||
1309 | 1322 | ||
1310 | ASSERT(BTOBB(need_bytes) < log->l_logBBsize); | 1323 | ASSERT(BTOBB(need_bytes) < log->l_logBBsize); |
1311 | 1324 | ||
1312 | s = GRANT_LOCK(log); | 1325 | spin_lock(&log->l_grant_lock); |
1313 | free_bytes = xlog_space_left(log, | 1326 | free_bytes = xlog_space_left(log, |
1314 | log->l_grant_reserve_cycle, | 1327 | log->l_grant_reserve_cycle, |
1315 | log->l_grant_reserve_bytes); | 1328 | log->l_grant_reserve_bytes); |
@@ -1331,8 +1344,7 @@ xlog_grant_push_ail(xfs_mount_t *mp, | |||
1331 | threshold_block -= log->l_logBBsize; | 1344 | threshold_block -= log->l_logBBsize; |
1332 | threshold_cycle += 1; | 1345 | threshold_cycle += 1; |
1333 | } | 1346 | } |
1334 | ASSIGN_ANY_LSN_HOST(threshold_lsn, threshold_cycle, | 1347 | threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block); |
1335 | threshold_block); | ||
1336 | 1348 | ||
1337 | /* Don't pass in an lsn greater than the lsn of the last | 1349 | /* Don't pass in an lsn greater than the lsn of the last |
1338 | * log record known to be on disk. | 1350 | * log record known to be on disk. |
@@ -1340,7 +1352,7 @@ xlog_grant_push_ail(xfs_mount_t *mp, | |||
1340 | if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0) | 1352 | if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0) |
1341 | threshold_lsn = log->l_last_sync_lsn; | 1353 | threshold_lsn = log->l_last_sync_lsn; |
1342 | } | 1354 | } |
1343 | GRANT_UNLOCK(log, s); | 1355 | spin_unlock(&log->l_grant_lock); |
1344 | 1356 | ||
1345 | /* | 1357 | /* |
1346 | * Get the transaction layer to kick the dirty buffers out to | 1358 | * Get the transaction layer to kick the dirty buffers out to |
@@ -1378,19 +1390,18 @@ xlog_grant_push_ail(xfs_mount_t *mp, | |||
1378 | * is added immediately before calling bwrite(). | 1390 | * is added immediately before calling bwrite(). |
1379 | */ | 1391 | */ |
1380 | 1392 | ||
1381 | int | 1393 | STATIC int |
1382 | xlog_sync(xlog_t *log, | 1394 | xlog_sync(xlog_t *log, |
1383 | xlog_in_core_t *iclog) | 1395 | xlog_in_core_t *iclog) |
1384 | { | 1396 | { |
1385 | xfs_caddr_t dptr; /* pointer to byte sized element */ | 1397 | xfs_caddr_t dptr; /* pointer to byte sized element */ |
1386 | xfs_buf_t *bp; | 1398 | xfs_buf_t *bp; |
1387 | int i, ops; | 1399 | int i; |
1388 | uint count; /* byte count of bwrite */ | 1400 | uint count; /* byte count of bwrite */ |
1389 | uint count_init; /* initial count before roundup */ | 1401 | uint count_init; /* initial count before roundup */ |
1390 | int roundoff; /* roundoff to BB or stripe */ | 1402 | int roundoff; /* roundoff to BB or stripe */ |
1391 | int split = 0; /* split write into two regions */ | 1403 | int split = 0; /* split write into two regions */ |
1392 | int error; | 1404 | int error; |
1393 | SPLDECL(s); | ||
1394 | int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb); | 1405 | int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb); |
1395 | 1406 | ||
1396 | XFS_STATS_INC(xs_log_writes); | 1407 | XFS_STATS_INC(xs_log_writes); |
@@ -1415,30 +1426,26 @@ xlog_sync(xlog_t *log, | |||
1415 | roundoff < BBTOB(1))); | 1426 | roundoff < BBTOB(1))); |
1416 | 1427 | ||
1417 | /* move grant heads by roundoff in sync */ | 1428 | /* move grant heads by roundoff in sync */ |
1418 | s = GRANT_LOCK(log); | 1429 | spin_lock(&log->l_grant_lock); |
1419 | xlog_grant_add_space(log, roundoff); | 1430 | xlog_grant_add_space(log, roundoff); |
1420 | GRANT_UNLOCK(log, s); | 1431 | spin_unlock(&log->l_grant_lock); |
1421 | 1432 | ||
1422 | /* put cycle number in every block */ | 1433 | /* put cycle number in every block */ |
1423 | xlog_pack_data(log, iclog, roundoff); | 1434 | xlog_pack_data(log, iclog, roundoff); |
1424 | 1435 | ||
1425 | /* real byte length */ | 1436 | /* real byte length */ |
1426 | if (v2) { | 1437 | if (v2) { |
1427 | INT_SET(iclog->ic_header.h_len, | 1438 | iclog->ic_header.h_len = |
1428 | ARCH_CONVERT, | 1439 | cpu_to_be32(iclog->ic_offset + roundoff); |
1429 | iclog->ic_offset + roundoff); | ||
1430 | } else { | 1440 | } else { |
1431 | INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset); | 1441 | iclog->ic_header.h_len = |
1442 | cpu_to_be32(iclog->ic_offset); | ||
1432 | } | 1443 | } |
1433 | 1444 | ||
1434 | /* put ops count in correct order */ | ||
1435 | ops = iclog->ic_header.h_num_logops; | ||
1436 | INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops); | ||
1437 | |||
1438 | bp = iclog->ic_bp; | 1445 | bp = iclog->ic_bp; |
1439 | ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1); | 1446 | ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1); |
1440 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2); | 1447 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2); |
1441 | XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT))); | 1448 | XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn))); |
1442 | 1449 | ||
1443 | XFS_STATS_ADD(xs_log_blocks, BTOBB(count)); | 1450 | XFS_STATS_ADD(xs_log_blocks, BTOBB(count)); |
1444 | 1451 | ||
@@ -1501,10 +1508,10 @@ xlog_sync(xlog_t *log, | |||
1501 | * a new cycle. Watch out for the header magic number | 1508 | * a new cycle. Watch out for the header magic number |
1502 | * case, though. | 1509 | * case, though. |
1503 | */ | 1510 | */ |
1504 | for (i=0; i<split; i += BBSIZE) { | 1511 | for (i = 0; i < split; i += BBSIZE) { |
1505 | INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1); | 1512 | be32_add((__be32 *)dptr, 1); |
1506 | if (INT_GET(*(uint *)dptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM) | 1513 | if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM) |
1507 | INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1); | 1514 | be32_add((__be32 *)dptr, 1); |
1508 | dptr += BBSIZE; | 1515 | dptr += BBSIZE; |
1509 | } | 1516 | } |
1510 | 1517 | ||
@@ -1527,14 +1534,13 @@ xlog_sync(xlog_t *log, | |||
1527 | /* | 1534 | /* |
1528 | * Deallocate a log structure | 1535 | * Deallocate a log structure |
1529 | */ | 1536 | */ |
1530 | void | 1537 | STATIC void |
1531 | xlog_dealloc_log(xlog_t *log) | 1538 | xlog_dealloc_log(xlog_t *log) |
1532 | { | 1539 | { |
1533 | xlog_in_core_t *iclog, *next_iclog; | 1540 | xlog_in_core_t *iclog, *next_iclog; |
1534 | xlog_ticket_t *tic, *next_tic; | 1541 | xlog_ticket_t *tic, *next_tic; |
1535 | int i; | 1542 | int i; |
1536 | 1543 | ||
1537 | |||
1538 | iclog = log->l_iclog; | 1544 | iclog = log->l_iclog; |
1539 | for (i=0; i<log->l_iclog_bufs; i++) { | 1545 | for (i=0; i<log->l_iclog_bufs; i++) { |
1540 | sv_destroy(&iclog->ic_forcesema); | 1546 | sv_destroy(&iclog->ic_forcesema); |
@@ -1565,7 +1571,7 @@ xlog_dealloc_log(xlog_t *log) | |||
1565 | tic = log->l_unmount_free; | 1571 | tic = log->l_unmount_free; |
1566 | while (tic) { | 1572 | while (tic) { |
1567 | next_tic = tic->t_next; | 1573 | next_tic = tic->t_next; |
1568 | kmem_free(tic, NBPP); | 1574 | kmem_free(tic, PAGE_SIZE); |
1569 | tic = next_tic; | 1575 | tic = next_tic; |
1570 | } | 1576 | } |
1571 | } | 1577 | } |
@@ -1592,14 +1598,12 @@ xlog_state_finish_copy(xlog_t *log, | |||
1592 | int record_cnt, | 1598 | int record_cnt, |
1593 | int copy_bytes) | 1599 | int copy_bytes) |
1594 | { | 1600 | { |
1595 | SPLDECL(s); | 1601 | spin_lock(&log->l_icloglock); |
1596 | 1602 | ||
1597 | s = LOG_LOCK(log); | 1603 | be32_add(&iclog->ic_header.h_num_logops, record_cnt); |
1598 | |||
1599 | iclog->ic_header.h_num_logops += record_cnt; | ||
1600 | iclog->ic_offset += copy_bytes; | 1604 | iclog->ic_offset += copy_bytes; |
1601 | 1605 | ||
1602 | LOG_UNLOCK(log, s); | 1606 | spin_unlock(&log->l_icloglock); |
1603 | } /* xlog_state_finish_copy */ | 1607 | } /* xlog_state_finish_copy */ |
1604 | 1608 | ||
1605 | 1609 | ||
@@ -1752,7 +1756,7 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | |||
1752 | * we don't update ic_offset until the end when we know exactly how many | 1756 | * we don't update ic_offset until the end when we know exactly how many |
1753 | * bytes have been written out. | 1757 | * bytes have been written out. |
1754 | */ | 1758 | */ |
1755 | int | 1759 | STATIC int |
1756 | xlog_write(xfs_mount_t * mp, | 1760 | xlog_write(xfs_mount_t * mp, |
1757 | xfs_log_iovec_t reg[], | 1761 | xfs_log_iovec_t reg[], |
1758 | int nentries, | 1762 | int nentries, |
@@ -1823,7 +1827,7 @@ xlog_write(xfs_mount_t * mp, | |||
1823 | 1827 | ||
1824 | /* start_lsn is the first lsn written to. That's all we need. */ | 1828 | /* start_lsn is the first lsn written to. That's all we need. */ |
1825 | if (! *start_lsn) | 1829 | if (! *start_lsn) |
1826 | *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT); | 1830 | *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn); |
1827 | 1831 | ||
1828 | /* This loop writes out as many regions as can fit in the amount | 1832 | /* This loop writes out as many regions as can fit in the amount |
1829 | * of space which was allocated by xlog_state_get_iclog_space(). | 1833 | * of space which was allocated by xlog_state_get_iclog_space(). |
@@ -1839,7 +1843,7 @@ xlog_write(xfs_mount_t * mp, | |||
1839 | */ | 1843 | */ |
1840 | if (ticket->t_flags & XLOG_TIC_INITED) { | 1844 | if (ticket->t_flags & XLOG_TIC_INITED) { |
1841 | logop_head = (xlog_op_header_t *)ptr; | 1845 | logop_head = (xlog_op_header_t *)ptr; |
1842 | INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid); | 1846 | logop_head->oh_tid = cpu_to_be32(ticket->t_tid); |
1843 | logop_head->oh_clientid = ticket->t_clientid; | 1847 | logop_head->oh_clientid = ticket->t_clientid; |
1844 | logop_head->oh_len = 0; | 1848 | logop_head->oh_len = 0; |
1845 | logop_head->oh_flags = XLOG_START_TRANS; | 1849 | logop_head->oh_flags = XLOG_START_TRANS; |
@@ -1853,7 +1857,7 @@ xlog_write(xfs_mount_t * mp, | |||
1853 | 1857 | ||
1854 | /* Copy log operation header directly into data section */ | 1858 | /* Copy log operation header directly into data section */ |
1855 | logop_head = (xlog_op_header_t *)ptr; | 1859 | logop_head = (xlog_op_header_t *)ptr; |
1856 | INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid); | 1860 | logop_head->oh_tid = cpu_to_be32(ticket->t_tid); |
1857 | logop_head->oh_clientid = ticket->t_clientid; | 1861 | logop_head->oh_clientid = ticket->t_clientid; |
1858 | logop_head->oh_res2 = 0; | 1862 | logop_head->oh_res2 = 0; |
1859 | 1863 | ||
@@ -1888,13 +1892,14 @@ xlog_write(xfs_mount_t * mp, | |||
1888 | 1892 | ||
1889 | copy_off = partial_copy_len; | 1893 | copy_off = partial_copy_len; |
1890 | if (need_copy <= iclog->ic_size - log_offset) { /*complete write */ | 1894 | if (need_copy <= iclog->ic_size - log_offset) { /*complete write */ |
1891 | INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy); | 1895 | copy_len = need_copy; |
1896 | logop_head->oh_len = cpu_to_be32(copy_len); | ||
1892 | if (partial_copy) | 1897 | if (partial_copy) |
1893 | logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS); | 1898 | logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS); |
1894 | partial_copy_len = partial_copy = 0; | 1899 | partial_copy_len = partial_copy = 0; |
1895 | } else { /* partial write */ | 1900 | } else { /* partial write */ |
1896 | copy_len = iclog->ic_size - log_offset; | 1901 | copy_len = iclog->ic_size - log_offset; |
1897 | INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len); | 1902 | logop_head->oh_len = cpu_to_be32(copy_len); |
1898 | logop_head->oh_flags |= XLOG_CONTINUE_TRANS; | 1903 | logop_head->oh_flags |= XLOG_CONTINUE_TRANS; |
1899 | if (partial_copy) | 1904 | if (partial_copy) |
1900 | logop_head->oh_flags |= XLOG_WAS_CONT_TRANS; | 1905 | logop_head->oh_flags |= XLOG_WAS_CONT_TRANS; |
@@ -1992,7 +1997,8 @@ xlog_state_clean_log(xlog_t *log) | |||
1992 | * We don't need to cover the dummy. | 1997 | * We don't need to cover the dummy. |
1993 | */ | 1998 | */ |
1994 | if (!changed && | 1999 | if (!changed && |
1995 | (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) { | 2000 | (be32_to_cpu(iclog->ic_header.h_num_logops) == |
2001 | XLOG_COVER_OPS)) { | ||
1996 | changed = 1; | 2002 | changed = 1; |
1997 | } else { | 2003 | } else { |
1998 | /* | 2004 | /* |
@@ -2060,7 +2066,7 @@ xlog_get_lowest_lsn( | |||
2060 | lowest_lsn = 0; | 2066 | lowest_lsn = 0; |
2061 | do { | 2067 | do { |
2062 | if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) { | 2068 | if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) { |
2063 | lsn = INT_GET(lsn_log->ic_header.h_lsn, ARCH_CONVERT); | 2069 | lsn = be64_to_cpu(lsn_log->ic_header.h_lsn); |
2064 | if ((lsn && !lowest_lsn) || | 2070 | if ((lsn && !lowest_lsn) || |
2065 | (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) { | 2071 | (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) { |
2066 | lowest_lsn = lsn; | 2072 | lowest_lsn = lsn; |
@@ -2089,9 +2095,8 @@ xlog_state_do_callback( | |||
2089 | int funcdidcallbacks; /* flag: function did callbacks */ | 2095 | int funcdidcallbacks; /* flag: function did callbacks */ |
2090 | int repeats; /* for issuing console warnings if | 2096 | int repeats; /* for issuing console warnings if |
2091 | * looping too many times */ | 2097 | * looping too many times */ |
2092 | SPLDECL(s); | ||
2093 | 2098 | ||
2094 | s = LOG_LOCK(log); | 2099 | spin_lock(&log->l_icloglock); |
2095 | first_iclog = iclog = log->l_iclog; | 2100 | first_iclog = iclog = log->l_iclog; |
2096 | ioerrors = 0; | 2101 | ioerrors = 0; |
2097 | funcdidcallbacks = 0; | 2102 | funcdidcallbacks = 0; |
@@ -2136,7 +2141,7 @@ xlog_state_do_callback( | |||
2136 | * to DO_CALLBACK, we will not process it when | 2141 | * to DO_CALLBACK, we will not process it when |
2137 | * we retry since a previous iclog is in the | 2142 | * we retry since a previous iclog is in the |
2138 | * CALLBACK and the state cannot change since | 2143 | * CALLBACK and the state cannot change since |
2139 | * we are holding the LOG_LOCK. | 2144 | * we are holding the l_icloglock. |
2140 | */ | 2145 | */ |
2141 | if (!(iclog->ic_state & | 2146 | if (!(iclog->ic_state & |
2142 | (XLOG_STATE_DONE_SYNC | | 2147 | (XLOG_STATE_DONE_SYNC | |
@@ -2162,11 +2167,9 @@ xlog_state_do_callback( | |||
2162 | */ | 2167 | */ |
2163 | 2168 | ||
2164 | lowest_lsn = xlog_get_lowest_lsn(log); | 2169 | lowest_lsn = xlog_get_lowest_lsn(log); |
2165 | if (lowest_lsn && ( | 2170 | if (lowest_lsn && |
2166 | XFS_LSN_CMP( | 2171 | XFS_LSN_CMP(lowest_lsn, |
2167 | lowest_lsn, | 2172 | be64_to_cpu(iclog->ic_header.h_lsn)) < 0) { |
2168 | INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) | ||
2169 | )<0)) { | ||
2170 | iclog = iclog->ic_next; | 2173 | iclog = iclog->ic_next; |
2171 | continue; /* Leave this iclog for | 2174 | continue; /* Leave this iclog for |
2172 | * another thread */ | 2175 | * another thread */ |
@@ -2174,19 +2177,18 @@ xlog_state_do_callback( | |||
2174 | 2177 | ||
2175 | iclog->ic_state = XLOG_STATE_CALLBACK; | 2178 | iclog->ic_state = XLOG_STATE_CALLBACK; |
2176 | 2179 | ||
2177 | LOG_UNLOCK(log, s); | 2180 | spin_unlock(&log->l_icloglock); |
2178 | 2181 | ||
2179 | /* l_last_sync_lsn field protected by | 2182 | /* l_last_sync_lsn field protected by |
2180 | * GRANT_LOCK. Don't worry about iclog's lsn. | 2183 | * l_grant_lock. Don't worry about iclog's lsn. |
2181 | * No one else can be here except us. | 2184 | * No one else can be here except us. |
2182 | */ | 2185 | */ |
2183 | s = GRANT_LOCK(log); | 2186 | spin_lock(&log->l_grant_lock); |
2184 | ASSERT(XFS_LSN_CMP( | 2187 | ASSERT(XFS_LSN_CMP(log->l_last_sync_lsn, |
2185 | log->l_last_sync_lsn, | 2188 | be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); |
2186 | INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) | 2189 | log->l_last_sync_lsn = |
2187 | )<=0); | 2190 | be64_to_cpu(iclog->ic_header.h_lsn); |
2188 | log->l_last_sync_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT); | 2191 | spin_unlock(&log->l_grant_lock); |
2189 | GRANT_UNLOCK(log, s); | ||
2190 | 2192 | ||
2191 | /* | 2193 | /* |
2192 | * Keep processing entries in the callback list | 2194 | * Keep processing entries in the callback list |
@@ -2195,7 +2197,7 @@ xlog_state_do_callback( | |||
2195 | * empty and change the state to DIRTY so that | 2197 | * empty and change the state to DIRTY so that |
2196 | * we don't miss any more callbacks being added. | 2198 | * we don't miss any more callbacks being added. |
2197 | */ | 2199 | */ |
2198 | s = LOG_LOCK(log); | 2200 | spin_lock(&log->l_icloglock); |
2199 | } else { | 2201 | } else { |
2200 | ioerrors++; | 2202 | ioerrors++; |
2201 | } | 2203 | } |
@@ -2204,14 +2206,14 @@ xlog_state_do_callback( | |||
2204 | while (cb) { | 2206 | while (cb) { |
2205 | iclog->ic_callback_tail = &(iclog->ic_callback); | 2207 | iclog->ic_callback_tail = &(iclog->ic_callback); |
2206 | iclog->ic_callback = NULL; | 2208 | iclog->ic_callback = NULL; |
2207 | LOG_UNLOCK(log, s); | 2209 | spin_unlock(&log->l_icloglock); |
2208 | 2210 | ||
2209 | /* perform callbacks in the order given */ | 2211 | /* perform callbacks in the order given */ |
2210 | for (; cb; cb = cb_next) { | 2212 | for (; cb; cb = cb_next) { |
2211 | cb_next = cb->cb_next; | 2213 | cb_next = cb->cb_next; |
2212 | cb->cb_func(cb->cb_arg, aborted); | 2214 | cb->cb_func(cb->cb_arg, aborted); |
2213 | } | 2215 | } |
2214 | s = LOG_LOCK(log); | 2216 | spin_lock(&log->l_icloglock); |
2215 | cb = iclog->ic_callback; | 2217 | cb = iclog->ic_callback; |
2216 | } | 2218 | } |
2217 | 2219 | ||
@@ -2258,7 +2260,7 @@ xlog_state_do_callback( | |||
2258 | * | 2260 | * |
2259 | * SYNCING - i/o completion will go through logs | 2261 | * SYNCING - i/o completion will go through logs |
2260 | * DONE_SYNC - interrupt thread should be waiting for | 2262 | * DONE_SYNC - interrupt thread should be waiting for |
2261 | * LOG_LOCK | 2263 | * l_icloglock |
2262 | * IOERROR - give up hope all ye who enter here | 2264 | * IOERROR - give up hope all ye who enter here |
2263 | */ | 2265 | */ |
2264 | if (iclog->ic_state == XLOG_STATE_WANT_SYNC || | 2266 | if (iclog->ic_state == XLOG_STATE_WANT_SYNC || |
@@ -2276,7 +2278,7 @@ xlog_state_do_callback( | |||
2276 | flushcnt = log->l_flushcnt; | 2278 | flushcnt = log->l_flushcnt; |
2277 | log->l_flushcnt = 0; | 2279 | log->l_flushcnt = 0; |
2278 | } | 2280 | } |
2279 | LOG_UNLOCK(log, s); | 2281 | spin_unlock(&log->l_icloglock); |
2280 | while (flushcnt--) | 2282 | while (flushcnt--) |
2281 | vsema(&log->l_flushsema); | 2283 | vsema(&log->l_flushsema); |
2282 | } /* xlog_state_do_callback */ | 2284 | } /* xlog_state_do_callback */ |
@@ -2296,15 +2298,14 @@ xlog_state_do_callback( | |||
2296 | * global state machine log lock. Assume that the calls to cvsema won't | 2298 | * global state machine log lock. Assume that the calls to cvsema won't |
2297 | * take a long time. At least we know it won't sleep. | 2299 | * take a long time. At least we know it won't sleep. |
2298 | */ | 2300 | */ |
2299 | void | 2301 | STATIC void |
2300 | xlog_state_done_syncing( | 2302 | xlog_state_done_syncing( |
2301 | xlog_in_core_t *iclog, | 2303 | xlog_in_core_t *iclog, |
2302 | int aborted) | 2304 | int aborted) |
2303 | { | 2305 | { |
2304 | xlog_t *log = iclog->ic_log; | 2306 | xlog_t *log = iclog->ic_log; |
2305 | SPLDECL(s); | ||
2306 | 2307 | ||
2307 | s = LOG_LOCK(log); | 2308 | spin_lock(&log->l_icloglock); |
2308 | 2309 | ||
2309 | ASSERT(iclog->ic_state == XLOG_STATE_SYNCING || | 2310 | ASSERT(iclog->ic_state == XLOG_STATE_SYNCING || |
2310 | iclog->ic_state == XLOG_STATE_IOERROR); | 2311 | iclog->ic_state == XLOG_STATE_IOERROR); |
@@ -2320,7 +2321,7 @@ xlog_state_done_syncing( | |||
2320 | */ | 2321 | */ |
2321 | if (iclog->ic_state != XLOG_STATE_IOERROR) { | 2322 | if (iclog->ic_state != XLOG_STATE_IOERROR) { |
2322 | if (--iclog->ic_bwritecnt == 1) { | 2323 | if (--iclog->ic_bwritecnt == 1) { |
2323 | LOG_UNLOCK(log, s); | 2324 | spin_unlock(&log->l_icloglock); |
2324 | return; | 2325 | return; |
2325 | } | 2326 | } |
2326 | iclog->ic_state = XLOG_STATE_DONE_SYNC; | 2327 | iclog->ic_state = XLOG_STATE_DONE_SYNC; |
@@ -2332,7 +2333,7 @@ xlog_state_done_syncing( | |||
2332 | * I/O, the others get to wait for the result. | 2333 | * I/O, the others get to wait for the result. |
2333 | */ | 2334 | */ |
2334 | sv_broadcast(&iclog->ic_writesema); | 2335 | sv_broadcast(&iclog->ic_writesema); |
2335 | LOG_UNLOCK(log, s); | 2336 | spin_unlock(&log->l_icloglock); |
2336 | xlog_state_do_callback(log, aborted, iclog); /* also cleans log */ | 2337 | xlog_state_do_callback(log, aborted, iclog); /* also cleans log */ |
2337 | } /* xlog_state_done_syncing */ | 2338 | } /* xlog_state_done_syncing */ |
2338 | 2339 | ||
@@ -2357,7 +2358,7 @@ xlog_state_done_syncing( | |||
2357 | * needs to be incremented, depending on the amount of data which | 2358 | * needs to be incremented, depending on the amount of data which |
2358 | * is copied. | 2359 | * is copied. |
2359 | */ | 2360 | */ |
2360 | int | 2361 | STATIC int |
2361 | xlog_state_get_iclog_space(xlog_t *log, | 2362 | xlog_state_get_iclog_space(xlog_t *log, |
2362 | int len, | 2363 | int len, |
2363 | xlog_in_core_t **iclogp, | 2364 | xlog_in_core_t **iclogp, |
@@ -2365,23 +2366,22 @@ xlog_state_get_iclog_space(xlog_t *log, | |||
2365 | int *continued_write, | 2366 | int *continued_write, |
2366 | int *logoffsetp) | 2367 | int *logoffsetp) |
2367 | { | 2368 | { |
2368 | SPLDECL(s); | ||
2369 | int log_offset; | 2369 | int log_offset; |
2370 | xlog_rec_header_t *head; | 2370 | xlog_rec_header_t *head; |
2371 | xlog_in_core_t *iclog; | 2371 | xlog_in_core_t *iclog; |
2372 | int error; | 2372 | int error; |
2373 | 2373 | ||
2374 | restart: | 2374 | restart: |
2375 | s = LOG_LOCK(log); | 2375 | spin_lock(&log->l_icloglock); |
2376 | if (XLOG_FORCED_SHUTDOWN(log)) { | 2376 | if (XLOG_FORCED_SHUTDOWN(log)) { |
2377 | LOG_UNLOCK(log, s); | 2377 | spin_unlock(&log->l_icloglock); |
2378 | return XFS_ERROR(EIO); | 2378 | return XFS_ERROR(EIO); |
2379 | } | 2379 | } |
2380 | 2380 | ||
2381 | iclog = log->l_iclog; | 2381 | iclog = log->l_iclog; |
2382 | if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) { | 2382 | if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) { |
2383 | log->l_flushcnt++; | 2383 | log->l_flushcnt++; |
2384 | LOG_UNLOCK(log, s); | 2384 | spin_unlock(&log->l_icloglock); |
2385 | xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH); | 2385 | xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH); |
2386 | XFS_STATS_INC(xs_log_noiclogs); | 2386 | XFS_STATS_INC(xs_log_noiclogs); |
2387 | /* Ensure that log writes happen */ | 2387 | /* Ensure that log writes happen */ |
@@ -2404,8 +2404,9 @@ restart: | |||
2404 | xlog_tic_add_region(ticket, | 2404 | xlog_tic_add_region(ticket, |
2405 | log->l_iclog_hsize, | 2405 | log->l_iclog_hsize, |
2406 | XLOG_REG_TYPE_LRHEADER); | 2406 | XLOG_REG_TYPE_LRHEADER); |
2407 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); | 2407 | head->h_cycle = cpu_to_be32(log->l_curr_cycle); |
2408 | ASSIGN_LSN(head->h_lsn, log); | 2408 | head->h_lsn = cpu_to_be64( |
2409 | xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block)); | ||
2409 | ASSERT(log->l_curr_block >= 0); | 2410 | ASSERT(log->l_curr_block >= 0); |
2410 | } | 2411 | } |
2411 | 2412 | ||
@@ -2423,12 +2424,12 @@ restart: | |||
2423 | 2424 | ||
2424 | /* If I'm the only one writing to this iclog, sync it to disk */ | 2425 | /* If I'm the only one writing to this iclog, sync it to disk */ |
2425 | if (iclog->ic_refcnt == 1) { | 2426 | if (iclog->ic_refcnt == 1) { |
2426 | LOG_UNLOCK(log, s); | 2427 | spin_unlock(&log->l_icloglock); |
2427 | if ((error = xlog_state_release_iclog(log, iclog))) | 2428 | if ((error = xlog_state_release_iclog(log, iclog))) |
2428 | return error; | 2429 | return error; |
2429 | } else { | 2430 | } else { |
2430 | iclog->ic_refcnt--; | 2431 | iclog->ic_refcnt--; |
2431 | LOG_UNLOCK(log, s); | 2432 | spin_unlock(&log->l_icloglock); |
2432 | } | 2433 | } |
2433 | goto restart; | 2434 | goto restart; |
2434 | } | 2435 | } |
@@ -2449,7 +2450,7 @@ restart: | |||
2449 | *iclogp = iclog; | 2450 | *iclogp = iclog; |
2450 | 2451 | ||
2451 | ASSERT(iclog->ic_offset <= iclog->ic_size); | 2452 | ASSERT(iclog->ic_offset <= iclog->ic_size); |
2452 | LOG_UNLOCK(log, s); | 2453 | spin_unlock(&log->l_icloglock); |
2453 | 2454 | ||
2454 | *logoffsetp = log_offset; | 2455 | *logoffsetp = log_offset; |
2455 | return 0; | 2456 | return 0; |
@@ -2467,7 +2468,6 @@ xlog_grant_log_space(xlog_t *log, | |||
2467 | { | 2468 | { |
2468 | int free_bytes; | 2469 | int free_bytes; |
2469 | int need_bytes; | 2470 | int need_bytes; |
2470 | SPLDECL(s); | ||
2471 | #ifdef DEBUG | 2471 | #ifdef DEBUG |
2472 | xfs_lsn_t tail_lsn; | 2472 | xfs_lsn_t tail_lsn; |
2473 | #endif | 2473 | #endif |
@@ -2479,7 +2479,7 @@ xlog_grant_log_space(xlog_t *log, | |||
2479 | #endif | 2479 | #endif |
2480 | 2480 | ||
2481 | /* Is there space or do we need to sleep? */ | 2481 | /* Is there space or do we need to sleep? */ |
2482 | s = GRANT_LOCK(log); | 2482 | spin_lock(&log->l_grant_lock); |
2483 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter"); | 2483 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter"); |
2484 | 2484 | ||
2485 | /* something is already sleeping; insert new transaction at end */ | 2485 | /* something is already sleeping; insert new transaction at end */ |
@@ -2502,7 +2502,7 @@ xlog_grant_log_space(xlog_t *log, | |||
2502 | */ | 2502 | */ |
2503 | xlog_trace_loggrant(log, tic, | 2503 | xlog_trace_loggrant(log, tic, |
2504 | "xlog_grant_log_space: wake 1"); | 2504 | "xlog_grant_log_space: wake 1"); |
2505 | s = GRANT_LOCK(log); | 2505 | spin_lock(&log->l_grant_lock); |
2506 | } | 2506 | } |
2507 | if (tic->t_flags & XFS_LOG_PERM_RESERV) | 2507 | if (tic->t_flags & XFS_LOG_PERM_RESERV) |
2508 | need_bytes = tic->t_unit_res*tic->t_ocnt; | 2508 | need_bytes = tic->t_unit_res*tic->t_ocnt; |
@@ -2524,14 +2524,14 @@ redo: | |||
2524 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); | 2524 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); |
2525 | 2525 | ||
2526 | if (XLOG_FORCED_SHUTDOWN(log)) { | 2526 | if (XLOG_FORCED_SHUTDOWN(log)) { |
2527 | s = GRANT_LOCK(log); | 2527 | spin_lock(&log->l_grant_lock); |
2528 | goto error_return; | 2528 | goto error_return; |
2529 | } | 2529 | } |
2530 | 2530 | ||
2531 | xlog_trace_loggrant(log, tic, | 2531 | xlog_trace_loggrant(log, tic, |
2532 | "xlog_grant_log_space: wake 2"); | 2532 | "xlog_grant_log_space: wake 2"); |
2533 | xlog_grant_push_ail(log->l_mp, need_bytes); | 2533 | xlog_grant_push_ail(log->l_mp, need_bytes); |
2534 | s = GRANT_LOCK(log); | 2534 | spin_lock(&log->l_grant_lock); |
2535 | goto redo; | 2535 | goto redo; |
2536 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2536 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2537 | xlog_del_ticketq(&log->l_reserve_headq, tic); | 2537 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
@@ -2553,7 +2553,7 @@ redo: | |||
2553 | #endif | 2553 | #endif |
2554 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit"); | 2554 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit"); |
2555 | xlog_verify_grant_head(log, 1); | 2555 | xlog_verify_grant_head(log, 1); |
2556 | GRANT_UNLOCK(log, s); | 2556 | spin_unlock(&log->l_grant_lock); |
2557 | return 0; | 2557 | return 0; |
2558 | 2558 | ||
2559 | error_return: | 2559 | error_return: |
@@ -2567,7 +2567,7 @@ redo: | |||
2567 | */ | 2567 | */ |
2568 | tic->t_curr_res = 0; | 2568 | tic->t_curr_res = 0; |
2569 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | 2569 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ |
2570 | GRANT_UNLOCK(log, s); | 2570 | spin_unlock(&log->l_grant_lock); |
2571 | return XFS_ERROR(EIO); | 2571 | return XFS_ERROR(EIO); |
2572 | } /* xlog_grant_log_space */ | 2572 | } /* xlog_grant_log_space */ |
2573 | 2573 | ||
@@ -2581,7 +2581,6 @@ STATIC int | |||
2581 | xlog_regrant_write_log_space(xlog_t *log, | 2581 | xlog_regrant_write_log_space(xlog_t *log, |
2582 | xlog_ticket_t *tic) | 2582 | xlog_ticket_t *tic) |
2583 | { | 2583 | { |
2584 | SPLDECL(s); | ||
2585 | int free_bytes, need_bytes; | 2584 | int free_bytes, need_bytes; |
2586 | xlog_ticket_t *ntic; | 2585 | xlog_ticket_t *ntic; |
2587 | #ifdef DEBUG | 2586 | #ifdef DEBUG |
@@ -2599,7 +2598,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2599 | panic("regrant Recovery problem"); | 2598 | panic("regrant Recovery problem"); |
2600 | #endif | 2599 | #endif |
2601 | 2600 | ||
2602 | s = GRANT_LOCK(log); | 2601 | spin_lock(&log->l_grant_lock); |
2603 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter"); | 2602 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter"); |
2604 | 2603 | ||
2605 | if (XLOG_FORCED_SHUTDOWN(log)) | 2604 | if (XLOG_FORCED_SHUTDOWN(log)) |
@@ -2638,14 +2637,14 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2638 | /* If we're shutting down, this tic is already | 2637 | /* If we're shutting down, this tic is already |
2639 | * off the queue */ | 2638 | * off the queue */ |
2640 | if (XLOG_FORCED_SHUTDOWN(log)) { | 2639 | if (XLOG_FORCED_SHUTDOWN(log)) { |
2641 | s = GRANT_LOCK(log); | 2640 | spin_lock(&log->l_grant_lock); |
2642 | goto error_return; | 2641 | goto error_return; |
2643 | } | 2642 | } |
2644 | 2643 | ||
2645 | xlog_trace_loggrant(log, tic, | 2644 | xlog_trace_loggrant(log, tic, |
2646 | "xlog_regrant_write_log_space: wake 1"); | 2645 | "xlog_regrant_write_log_space: wake 1"); |
2647 | xlog_grant_push_ail(log->l_mp, tic->t_unit_res); | 2646 | xlog_grant_push_ail(log->l_mp, tic->t_unit_res); |
2648 | s = GRANT_LOCK(log); | 2647 | spin_lock(&log->l_grant_lock); |
2649 | } | 2648 | } |
2650 | } | 2649 | } |
2651 | 2650 | ||
@@ -2665,14 +2664,14 @@ redo: | |||
2665 | 2664 | ||
2666 | /* If we're shutting down, this tic is already off the queue */ | 2665 | /* If we're shutting down, this tic is already off the queue */ |
2667 | if (XLOG_FORCED_SHUTDOWN(log)) { | 2666 | if (XLOG_FORCED_SHUTDOWN(log)) { |
2668 | s = GRANT_LOCK(log); | 2667 | spin_lock(&log->l_grant_lock); |
2669 | goto error_return; | 2668 | goto error_return; |
2670 | } | 2669 | } |
2671 | 2670 | ||
2672 | xlog_trace_loggrant(log, tic, | 2671 | xlog_trace_loggrant(log, tic, |
2673 | "xlog_regrant_write_log_space: wake 2"); | 2672 | "xlog_regrant_write_log_space: wake 2"); |
2674 | xlog_grant_push_ail(log->l_mp, need_bytes); | 2673 | xlog_grant_push_ail(log->l_mp, need_bytes); |
2675 | s = GRANT_LOCK(log); | 2674 | spin_lock(&log->l_grant_lock); |
2676 | goto redo; | 2675 | goto redo; |
2677 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2676 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2678 | xlog_del_ticketq(&log->l_write_headq, tic); | 2677 | xlog_del_ticketq(&log->l_write_headq, tic); |
@@ -2689,7 +2688,7 @@ redo: | |||
2689 | 2688 | ||
2690 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit"); | 2689 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit"); |
2691 | xlog_verify_grant_head(log, 1); | 2690 | xlog_verify_grant_head(log, 1); |
2692 | GRANT_UNLOCK(log, s); | 2691 | spin_unlock(&log->l_grant_lock); |
2693 | return 0; | 2692 | return 0; |
2694 | 2693 | ||
2695 | 2694 | ||
@@ -2704,7 +2703,7 @@ redo: | |||
2704 | */ | 2703 | */ |
2705 | tic->t_curr_res = 0; | 2704 | tic->t_curr_res = 0; |
2706 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | 2705 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ |
2707 | GRANT_UNLOCK(log, s); | 2706 | spin_unlock(&log->l_grant_lock); |
2708 | return XFS_ERROR(EIO); | 2707 | return XFS_ERROR(EIO); |
2709 | } /* xlog_regrant_write_log_space */ | 2708 | } /* xlog_regrant_write_log_space */ |
2710 | 2709 | ||
@@ -2720,14 +2719,12 @@ STATIC void | |||
2720 | xlog_regrant_reserve_log_space(xlog_t *log, | 2719 | xlog_regrant_reserve_log_space(xlog_t *log, |
2721 | xlog_ticket_t *ticket) | 2720 | xlog_ticket_t *ticket) |
2722 | { | 2721 | { |
2723 | SPLDECL(s); | ||
2724 | |||
2725 | xlog_trace_loggrant(log, ticket, | 2722 | xlog_trace_loggrant(log, ticket, |
2726 | "xlog_regrant_reserve_log_space: enter"); | 2723 | "xlog_regrant_reserve_log_space: enter"); |
2727 | if (ticket->t_cnt > 0) | 2724 | if (ticket->t_cnt > 0) |
2728 | ticket->t_cnt--; | 2725 | ticket->t_cnt--; |
2729 | 2726 | ||
2730 | s = GRANT_LOCK(log); | 2727 | spin_lock(&log->l_grant_lock); |
2731 | xlog_grant_sub_space(log, ticket->t_curr_res); | 2728 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2732 | ticket->t_curr_res = ticket->t_unit_res; | 2729 | ticket->t_curr_res = ticket->t_unit_res; |
2733 | xlog_tic_reset_res(ticket); | 2730 | xlog_tic_reset_res(ticket); |
@@ -2737,7 +2734,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2737 | 2734 | ||
2738 | /* just return if we still have some of the pre-reserved space */ | 2735 | /* just return if we still have some of the pre-reserved space */ |
2739 | if (ticket->t_cnt > 0) { | 2736 | if (ticket->t_cnt > 0) { |
2740 | GRANT_UNLOCK(log, s); | 2737 | spin_unlock(&log->l_grant_lock); |
2741 | return; | 2738 | return; |
2742 | } | 2739 | } |
2743 | 2740 | ||
@@ -2745,7 +2742,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2745 | xlog_trace_loggrant(log, ticket, | 2742 | xlog_trace_loggrant(log, ticket, |
2746 | "xlog_regrant_reserve_log_space: exit"); | 2743 | "xlog_regrant_reserve_log_space: exit"); |
2747 | xlog_verify_grant_head(log, 0); | 2744 | xlog_verify_grant_head(log, 0); |
2748 | GRANT_UNLOCK(log, s); | 2745 | spin_unlock(&log->l_grant_lock); |
2749 | ticket->t_curr_res = ticket->t_unit_res; | 2746 | ticket->t_curr_res = ticket->t_unit_res; |
2750 | xlog_tic_reset_res(ticket); | 2747 | xlog_tic_reset_res(ticket); |
2751 | } /* xlog_regrant_reserve_log_space */ | 2748 | } /* xlog_regrant_reserve_log_space */ |
@@ -2769,12 +2766,10 @@ STATIC void | |||
2769 | xlog_ungrant_log_space(xlog_t *log, | 2766 | xlog_ungrant_log_space(xlog_t *log, |
2770 | xlog_ticket_t *ticket) | 2767 | xlog_ticket_t *ticket) |
2771 | { | 2768 | { |
2772 | SPLDECL(s); | ||
2773 | |||
2774 | if (ticket->t_cnt > 0) | 2769 | if (ticket->t_cnt > 0) |
2775 | ticket->t_cnt--; | 2770 | ticket->t_cnt--; |
2776 | 2771 | ||
2777 | s = GRANT_LOCK(log); | 2772 | spin_lock(&log->l_grant_lock); |
2778 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); | 2773 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); |
2779 | 2774 | ||
2780 | xlog_grant_sub_space(log, ticket->t_curr_res); | 2775 | xlog_grant_sub_space(log, ticket->t_curr_res); |
@@ -2791,7 +2786,7 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2791 | 2786 | ||
2792 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); | 2787 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); |
2793 | xlog_verify_grant_head(log, 1); | 2788 | xlog_verify_grant_head(log, 1); |
2794 | GRANT_UNLOCK(log, s); | 2789 | spin_unlock(&log->l_grant_lock); |
2795 | xfs_log_move_tail(log->l_mp, 1); | 2790 | xfs_log_move_tail(log->l_mp, 1); |
2796 | } /* xlog_ungrant_log_space */ | 2791 | } /* xlog_ungrant_log_space */ |
2797 | 2792 | ||
@@ -2799,15 +2794,13 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2799 | /* | 2794 | /* |
2800 | * Atomically put back used ticket. | 2795 | * Atomically put back used ticket. |
2801 | */ | 2796 | */ |
2802 | void | 2797 | STATIC void |
2803 | xlog_state_put_ticket(xlog_t *log, | 2798 | xlog_state_put_ticket(xlog_t *log, |
2804 | xlog_ticket_t *tic) | 2799 | xlog_ticket_t *tic) |
2805 | { | 2800 | { |
2806 | unsigned long s; | 2801 | spin_lock(&log->l_icloglock); |
2807 | |||
2808 | s = LOG_LOCK(log); | ||
2809 | xlog_ticket_put(log, tic); | 2802 | xlog_ticket_put(log, tic); |
2810 | LOG_UNLOCK(log, s); | 2803 | spin_unlock(&log->l_icloglock); |
2811 | } /* xlog_state_put_ticket */ | 2804 | } /* xlog_state_put_ticket */ |
2812 | 2805 | ||
2813 | /* | 2806 | /* |
@@ -2819,19 +2812,18 @@ xlog_state_put_ticket(xlog_t *log, | |||
2819 | * | 2812 | * |
2820 | * | 2813 | * |
2821 | */ | 2814 | */ |
2822 | int | 2815 | STATIC int |
2823 | xlog_state_release_iclog(xlog_t *log, | 2816 | xlog_state_release_iclog(xlog_t *log, |
2824 | xlog_in_core_t *iclog) | 2817 | xlog_in_core_t *iclog) |
2825 | { | 2818 | { |
2826 | SPLDECL(s); | ||
2827 | int sync = 0; /* do we sync? */ | 2819 | int sync = 0; /* do we sync? */ |
2828 | 2820 | ||
2829 | xlog_assign_tail_lsn(log->l_mp); | 2821 | xlog_assign_tail_lsn(log->l_mp); |
2830 | 2822 | ||
2831 | s = LOG_LOCK(log); | 2823 | spin_lock(&log->l_icloglock); |
2832 | 2824 | ||
2833 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 2825 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
2834 | LOG_UNLOCK(log, s); | 2826 | spin_unlock(&log->l_icloglock); |
2835 | return XFS_ERROR(EIO); | 2827 | return XFS_ERROR(EIO); |
2836 | } | 2828 | } |
2837 | 2829 | ||
@@ -2843,12 +2835,12 @@ xlog_state_release_iclog(xlog_t *log, | |||
2843 | iclog->ic_state == XLOG_STATE_WANT_SYNC) { | 2835 | iclog->ic_state == XLOG_STATE_WANT_SYNC) { |
2844 | sync++; | 2836 | sync++; |
2845 | iclog->ic_state = XLOG_STATE_SYNCING; | 2837 | iclog->ic_state = XLOG_STATE_SYNCING; |
2846 | INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, log->l_tail_lsn); | 2838 | iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn); |
2847 | xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn); | 2839 | xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn); |
2848 | /* cycle incremented when incrementing curr_block */ | 2840 | /* cycle incremented when incrementing curr_block */ |
2849 | } | 2841 | } |
2850 | 2842 | ||
2851 | LOG_UNLOCK(log, s); | 2843 | spin_unlock(&log->l_icloglock); |
2852 | 2844 | ||
2853 | /* | 2845 | /* |
2854 | * We let the log lock go, so it's possible that we hit a log I/O | 2846 | * We let the log lock go, so it's possible that we hit a log I/O |
@@ -2881,7 +2873,7 @@ xlog_state_switch_iclogs(xlog_t *log, | |||
2881 | if (!eventual_size) | 2873 | if (!eventual_size) |
2882 | eventual_size = iclog->ic_offset; | 2874 | eventual_size = iclog->ic_offset; |
2883 | iclog->ic_state = XLOG_STATE_WANT_SYNC; | 2875 | iclog->ic_state = XLOG_STATE_WANT_SYNC; |
2884 | INT_SET(iclog->ic_header.h_prev_block, ARCH_CONVERT, log->l_prev_block); | 2876 | iclog->ic_header.h_prev_block = cpu_to_be32(log->l_prev_block); |
2885 | log->l_prev_block = log->l_curr_block; | 2877 | log->l_prev_block = log->l_curr_block; |
2886 | log->l_prev_cycle = log->l_curr_cycle; | 2878 | log->l_prev_cycle = log->l_curr_cycle; |
2887 | 2879 | ||
@@ -2939,13 +2931,12 @@ xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed) | |||
2939 | { | 2931 | { |
2940 | xlog_in_core_t *iclog; | 2932 | xlog_in_core_t *iclog; |
2941 | xfs_lsn_t lsn; | 2933 | xfs_lsn_t lsn; |
2942 | SPLDECL(s); | ||
2943 | 2934 | ||
2944 | s = LOG_LOCK(log); | 2935 | spin_lock(&log->l_icloglock); |
2945 | 2936 | ||
2946 | iclog = log->l_iclog; | 2937 | iclog = log->l_iclog; |
2947 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 2938 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
2948 | LOG_UNLOCK(log, s); | 2939 | spin_unlock(&log->l_icloglock); |
2949 | return XFS_ERROR(EIO); | 2940 | return XFS_ERROR(EIO); |
2950 | } | 2941 | } |
2951 | 2942 | ||
@@ -2978,15 +2969,15 @@ xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed) | |||
2978 | * the previous sync. | 2969 | * the previous sync. |
2979 | */ | 2970 | */ |
2980 | iclog->ic_refcnt++; | 2971 | iclog->ic_refcnt++; |
2981 | lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT); | 2972 | lsn = be64_to_cpu(iclog->ic_header.h_lsn); |
2982 | xlog_state_switch_iclogs(log, iclog, 0); | 2973 | xlog_state_switch_iclogs(log, iclog, 0); |
2983 | LOG_UNLOCK(log, s); | 2974 | spin_unlock(&log->l_icloglock); |
2984 | 2975 | ||
2985 | if (xlog_state_release_iclog(log, iclog)) | 2976 | if (xlog_state_release_iclog(log, iclog)) |
2986 | return XFS_ERROR(EIO); | 2977 | return XFS_ERROR(EIO); |
2987 | *log_flushed = 1; | 2978 | *log_flushed = 1; |
2988 | s = LOG_LOCK(log); | 2979 | spin_lock(&log->l_icloglock); |
2989 | if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn && | 2980 | if (be64_to_cpu(iclog->ic_header.h_lsn) == lsn && |
2990 | iclog->ic_state != XLOG_STATE_DIRTY) | 2981 | iclog->ic_state != XLOG_STATE_DIRTY) |
2991 | goto maybe_sleep; | 2982 | goto maybe_sleep; |
2992 | else | 2983 | else |
@@ -3011,12 +3002,12 @@ maybe_sleep: | |||
3011 | if (flags & XFS_LOG_SYNC) { | 3002 | if (flags & XFS_LOG_SYNC) { |
3012 | /* | 3003 | /* |
3013 | * We must check if we're shutting down here, before | 3004 | * We must check if we're shutting down here, before |
3014 | * we wait, while we're holding the LOG_LOCK. | 3005 | * we wait, while we're holding the l_icloglock. |
3015 | * Then we check again after waking up, in case our | 3006 | * Then we check again after waking up, in case our |
3016 | * sleep was disturbed by a bad news. | 3007 | * sleep was disturbed by a bad news. |
3017 | */ | 3008 | */ |
3018 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 3009 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
3019 | LOG_UNLOCK(log, s); | 3010 | spin_unlock(&log->l_icloglock); |
3020 | return XFS_ERROR(EIO); | 3011 | return XFS_ERROR(EIO); |
3021 | } | 3012 | } |
3022 | XFS_STATS_INC(xs_log_force_sleep); | 3013 | XFS_STATS_INC(xs_log_force_sleep); |
@@ -3033,7 +3024,7 @@ maybe_sleep: | |||
3033 | } else { | 3024 | } else { |
3034 | 3025 | ||
3035 | no_sleep: | 3026 | no_sleep: |
3036 | LOG_UNLOCK(log, s); | 3027 | spin_unlock(&log->l_icloglock); |
3037 | } | 3028 | } |
3038 | return 0; | 3029 | return 0; |
3039 | } /* xlog_state_sync_all */ | 3030 | } /* xlog_state_sync_all */ |
@@ -3051,7 +3042,7 @@ no_sleep: | |||
3051 | * If filesystem activity goes to zero, the iclog will get flushed only by | 3042 | * If filesystem activity goes to zero, the iclog will get flushed only by |
3052 | * bdflush(). | 3043 | * bdflush(). |
3053 | */ | 3044 | */ |
3054 | int | 3045 | STATIC int |
3055 | xlog_state_sync(xlog_t *log, | 3046 | xlog_state_sync(xlog_t *log, |
3056 | xfs_lsn_t lsn, | 3047 | xfs_lsn_t lsn, |
3057 | uint flags, | 3048 | uint flags, |
@@ -3059,26 +3050,24 @@ xlog_state_sync(xlog_t *log, | |||
3059 | { | 3050 | { |
3060 | xlog_in_core_t *iclog; | 3051 | xlog_in_core_t *iclog; |
3061 | int already_slept = 0; | 3052 | int already_slept = 0; |
3062 | SPLDECL(s); | ||
3063 | |||
3064 | 3053 | ||
3065 | try_again: | 3054 | try_again: |
3066 | s = LOG_LOCK(log); | 3055 | spin_lock(&log->l_icloglock); |
3067 | iclog = log->l_iclog; | 3056 | iclog = log->l_iclog; |
3068 | 3057 | ||
3069 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 3058 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
3070 | LOG_UNLOCK(log, s); | 3059 | spin_unlock(&log->l_icloglock); |
3071 | return XFS_ERROR(EIO); | 3060 | return XFS_ERROR(EIO); |
3072 | } | 3061 | } |
3073 | 3062 | ||
3074 | do { | 3063 | do { |
3075 | if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) { | 3064 | if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) { |
3076 | iclog = iclog->ic_next; | 3065 | iclog = iclog->ic_next; |
3077 | continue; | 3066 | continue; |
3078 | } | 3067 | } |
3079 | 3068 | ||
3080 | if (iclog->ic_state == XLOG_STATE_DIRTY) { | 3069 | if (iclog->ic_state == XLOG_STATE_DIRTY) { |
3081 | LOG_UNLOCK(log, s); | 3070 | spin_unlock(&log->l_icloglock); |
3082 | return 0; | 3071 | return 0; |
3083 | } | 3072 | } |
3084 | 3073 | ||
@@ -3113,11 +3102,11 @@ try_again: | |||
3113 | } else { | 3102 | } else { |
3114 | iclog->ic_refcnt++; | 3103 | iclog->ic_refcnt++; |
3115 | xlog_state_switch_iclogs(log, iclog, 0); | 3104 | xlog_state_switch_iclogs(log, iclog, 0); |
3116 | LOG_UNLOCK(log, s); | 3105 | spin_unlock(&log->l_icloglock); |
3117 | if (xlog_state_release_iclog(log, iclog)) | 3106 | if (xlog_state_release_iclog(log, iclog)) |
3118 | return XFS_ERROR(EIO); | 3107 | return XFS_ERROR(EIO); |
3119 | *log_flushed = 1; | 3108 | *log_flushed = 1; |
3120 | s = LOG_LOCK(log); | 3109 | spin_lock(&log->l_icloglock); |
3121 | } | 3110 | } |
3122 | } | 3111 | } |
3123 | 3112 | ||
@@ -3129,7 +3118,7 @@ try_again: | |||
3129 | * gotten a log write error. | 3118 | * gotten a log write error. |
3130 | */ | 3119 | */ |
3131 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 3120 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
3132 | LOG_UNLOCK(log, s); | 3121 | spin_unlock(&log->l_icloglock); |
3133 | return XFS_ERROR(EIO); | 3122 | return XFS_ERROR(EIO); |
3134 | } | 3123 | } |
3135 | XFS_STATS_INC(xs_log_force_sleep); | 3124 | XFS_STATS_INC(xs_log_force_sleep); |
@@ -3143,13 +3132,13 @@ try_again: | |||
3143 | return XFS_ERROR(EIO); | 3132 | return XFS_ERROR(EIO); |
3144 | *log_flushed = 1; | 3133 | *log_flushed = 1; |
3145 | } else { /* just return */ | 3134 | } else { /* just return */ |
3146 | LOG_UNLOCK(log, s); | 3135 | spin_unlock(&log->l_icloglock); |
3147 | } | 3136 | } |
3148 | return 0; | 3137 | return 0; |
3149 | 3138 | ||
3150 | } while (iclog != log->l_iclog); | 3139 | } while (iclog != log->l_iclog); |
3151 | 3140 | ||
3152 | LOG_UNLOCK(log, s); | 3141 | spin_unlock(&log->l_icloglock); |
3153 | return 0; | 3142 | return 0; |
3154 | } /* xlog_state_sync */ | 3143 | } /* xlog_state_sync */ |
3155 | 3144 | ||
@@ -3158,12 +3147,10 @@ try_again: | |||
3158 | * Called when we want to mark the current iclog as being ready to sync to | 3147 | * Called when we want to mark the current iclog as being ready to sync to |
3159 | * disk. | 3148 | * disk. |
3160 | */ | 3149 | */ |
3161 | void | 3150 | STATIC void |
3162 | xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) | 3151 | xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) |
3163 | { | 3152 | { |
3164 | SPLDECL(s); | 3153 | spin_lock(&log->l_icloglock); |
3165 | |||
3166 | s = LOG_LOCK(log); | ||
3167 | 3154 | ||
3168 | if (iclog->ic_state == XLOG_STATE_ACTIVE) { | 3155 | if (iclog->ic_state == XLOG_STATE_ACTIVE) { |
3169 | xlog_state_switch_iclogs(log, iclog, 0); | 3156 | xlog_state_switch_iclogs(log, iclog, 0); |
@@ -3172,7 +3159,7 @@ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) | |||
3172 | (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR)); | 3159 | (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR)); |
3173 | } | 3160 | } |
3174 | 3161 | ||
3175 | LOG_UNLOCK(log, s); | 3162 | spin_unlock(&log->l_icloglock); |
3176 | } /* xlog_state_want_sync */ | 3163 | } /* xlog_state_want_sync */ |
3177 | 3164 | ||
3178 | 3165 | ||
@@ -3193,16 +3180,15 @@ xlog_state_ticket_alloc(xlog_t *log) | |||
3193 | xlog_ticket_t *t_list; | 3180 | xlog_ticket_t *t_list; |
3194 | xlog_ticket_t *next; | 3181 | xlog_ticket_t *next; |
3195 | xfs_caddr_t buf; | 3182 | xfs_caddr_t buf; |
3196 | uint i = (NBPP / sizeof(xlog_ticket_t)) - 2; | 3183 | uint i = (PAGE_SIZE / sizeof(xlog_ticket_t)) - 2; |
3197 | SPLDECL(s); | ||
3198 | 3184 | ||
3199 | /* | 3185 | /* |
3200 | * The kmem_zalloc may sleep, so we shouldn't be holding the | 3186 | * The kmem_zalloc may sleep, so we shouldn't be holding the |
3201 | * global lock. XXXmiken: may want to use zone allocator. | 3187 | * global lock. XXXmiken: may want to use zone allocator. |
3202 | */ | 3188 | */ |
3203 | buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP); | 3189 | buf = (xfs_caddr_t) kmem_zalloc(PAGE_SIZE, KM_SLEEP); |
3204 | 3190 | ||
3205 | s = LOG_LOCK(log); | 3191 | spin_lock(&log->l_icloglock); |
3206 | 3192 | ||
3207 | /* Attach 1st ticket to Q, so we can keep track of allocated memory */ | 3193 | /* Attach 1st ticket to Q, so we can keep track of allocated memory */ |
3208 | t_list = (xlog_ticket_t *)buf; | 3194 | t_list = (xlog_ticket_t *)buf; |
@@ -3231,7 +3217,7 @@ xlog_state_ticket_alloc(xlog_t *log) | |||
3231 | } | 3217 | } |
3232 | t_list->t_next = NULL; | 3218 | t_list->t_next = NULL; |
3233 | log->l_tail = t_list; | 3219 | log->l_tail = t_list; |
3234 | LOG_UNLOCK(log, s); | 3220 | spin_unlock(&log->l_icloglock); |
3235 | } /* xlog_state_ticket_alloc */ | 3221 | } /* xlog_state_ticket_alloc */ |
3236 | 3222 | ||
3237 | 3223 | ||
@@ -3273,7 +3259,7 @@ xlog_ticket_put(xlog_t *log, | |||
3273 | /* | 3259 | /* |
3274 | * Grab ticket off freelist or allocation some more | 3260 | * Grab ticket off freelist or allocation some more |
3275 | */ | 3261 | */ |
3276 | xlog_ticket_t * | 3262 | STATIC xlog_ticket_t * |
3277 | xlog_ticket_get(xlog_t *log, | 3263 | xlog_ticket_get(xlog_t *log, |
3278 | int unit_bytes, | 3264 | int unit_bytes, |
3279 | int cnt, | 3265 | int cnt, |
@@ -3282,15 +3268,14 @@ xlog_ticket_get(xlog_t *log, | |||
3282 | { | 3268 | { |
3283 | xlog_ticket_t *tic; | 3269 | xlog_ticket_t *tic; |
3284 | uint num_headers; | 3270 | uint num_headers; |
3285 | SPLDECL(s); | ||
3286 | 3271 | ||
3287 | alloc: | 3272 | alloc: |
3288 | if (log->l_freelist == NULL) | 3273 | if (log->l_freelist == NULL) |
3289 | xlog_state_ticket_alloc(log); /* potentially sleep */ | 3274 | xlog_state_ticket_alloc(log); /* potentially sleep */ |
3290 | 3275 | ||
3291 | s = LOG_LOCK(log); | 3276 | spin_lock(&log->l_icloglock); |
3292 | if (log->l_freelist == NULL) { | 3277 | if (log->l_freelist == NULL) { |
3293 | LOG_UNLOCK(log, s); | 3278 | spin_unlock(&log->l_icloglock); |
3294 | goto alloc; | 3279 | goto alloc; |
3295 | } | 3280 | } |
3296 | tic = log->l_freelist; | 3281 | tic = log->l_freelist; |
@@ -3298,7 +3283,7 @@ xlog_ticket_get(xlog_t *log, | |||
3298 | if (log->l_freelist == NULL) | 3283 | if (log->l_freelist == NULL) |
3299 | log->l_tail = NULL; | 3284 | log->l_tail = NULL; |
3300 | log->l_ticket_cnt--; | 3285 | log->l_ticket_cnt--; |
3301 | LOG_UNLOCK(log, s); | 3286 | spin_unlock(&log->l_icloglock); |
3302 | 3287 | ||
3303 | /* | 3288 | /* |
3304 | * Permanent reservations have up to 'cnt'-1 active log operations | 3289 | * Permanent reservations have up to 'cnt'-1 active log operations |
@@ -3473,10 +3458,9 @@ xlog_verify_iclog(xlog_t *log, | |||
3473 | __uint8_t clientid; | 3458 | __uint8_t clientid; |
3474 | int len, i, j, k, op_len; | 3459 | int len, i, j, k, op_len; |
3475 | int idx; | 3460 | int idx; |
3476 | SPLDECL(s); | ||
3477 | 3461 | ||
3478 | /* check validity of iclog pointers */ | 3462 | /* check validity of iclog pointers */ |
3479 | s = LOG_LOCK(log); | 3463 | spin_lock(&log->l_icloglock); |
3480 | icptr = log->l_iclog; | 3464 | icptr = log->l_iclog; |
3481 | for (i=0; i < log->l_iclog_bufs; i++) { | 3465 | for (i=0; i < log->l_iclog_bufs; i++) { |
3482 | if (icptr == NULL) | 3466 | if (icptr == NULL) |
@@ -3485,21 +3469,21 @@ xlog_verify_iclog(xlog_t *log, | |||
3485 | } | 3469 | } |
3486 | if (icptr != log->l_iclog) | 3470 | if (icptr != log->l_iclog) |
3487 | xlog_panic("xlog_verify_iclog: corrupt iclog ring"); | 3471 | xlog_panic("xlog_verify_iclog: corrupt iclog ring"); |
3488 | LOG_UNLOCK(log, s); | 3472 | spin_unlock(&log->l_icloglock); |
3489 | 3473 | ||
3490 | /* check log magic numbers */ | 3474 | /* check log magic numbers */ |
3491 | ptr = (xfs_caddr_t) &(iclog->ic_header); | 3475 | if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM) |
3492 | if (INT_GET(*(uint *)ptr, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) | ||
3493 | xlog_panic("xlog_verify_iclog: invalid magic num"); | 3476 | xlog_panic("xlog_verify_iclog: invalid magic num"); |
3494 | 3477 | ||
3495 | for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&(iclog->ic_header))+count; | 3478 | ptr = (xfs_caddr_t) &iclog->ic_header; |
3479 | for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&iclog->ic_header) + count; | ||
3496 | ptr += BBSIZE) { | 3480 | ptr += BBSIZE) { |
3497 | if (INT_GET(*(uint *)ptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM) | 3481 | if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) |
3498 | xlog_panic("xlog_verify_iclog: unexpected magic num"); | 3482 | xlog_panic("xlog_verify_iclog: unexpected magic num"); |
3499 | } | 3483 | } |
3500 | 3484 | ||
3501 | /* check fields */ | 3485 | /* check fields */ |
3502 | len = INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT); | 3486 | len = be32_to_cpu(iclog->ic_header.h_num_logops); |
3503 | ptr = iclog->ic_datap; | 3487 | ptr = iclog->ic_datap; |
3504 | base_ptr = ptr; | 3488 | base_ptr = ptr; |
3505 | ophead = (xlog_op_header_t *)ptr; | 3489 | ophead = (xlog_op_header_t *)ptr; |
@@ -3517,9 +3501,11 @@ xlog_verify_iclog(xlog_t *log, | |||
3517 | if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) { | 3501 | if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) { |
3518 | j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3502 | j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3519 | k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3503 | k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3520 | clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT); | 3504 | clientid = xlog_get_client_id( |
3505 | xhdr[j].hic_xheader.xh_cycle_data[k]); | ||
3521 | } else { | 3506 | } else { |
3522 | clientid = GET_CLIENT_ID(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT); | 3507 | clientid = xlog_get_client_id( |
3508 | iclog->ic_header.h_cycle_data[idx]); | ||
3523 | } | 3509 | } |
3524 | } | 3510 | } |
3525 | if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) | 3511 | if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) |
@@ -3531,16 +3517,16 @@ xlog_verify_iclog(xlog_t *log, | |||
3531 | field_offset = (__psint_t) | 3517 | field_offset = (__psint_t) |
3532 | ((xfs_caddr_t)&(ophead->oh_len) - base_ptr); | 3518 | ((xfs_caddr_t)&(ophead->oh_len) - base_ptr); |
3533 | if (syncing == B_FALSE || (field_offset & 0x1ff)) { | 3519 | if (syncing == B_FALSE || (field_offset & 0x1ff)) { |
3534 | op_len = INT_GET(ophead->oh_len, ARCH_CONVERT); | 3520 | op_len = be32_to_cpu(ophead->oh_len); |
3535 | } else { | 3521 | } else { |
3536 | idx = BTOBBT((__psint_t)&ophead->oh_len - | 3522 | idx = BTOBBT((__psint_t)&ophead->oh_len - |
3537 | (__psint_t)iclog->ic_datap); | 3523 | (__psint_t)iclog->ic_datap); |
3538 | if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) { | 3524 | if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) { |
3539 | j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3525 | j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3540 | k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3526 | k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3541 | op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT); | 3527 | op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]); |
3542 | } else { | 3528 | } else { |
3543 | op_len = INT_GET(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT); | 3529 | op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]); |
3544 | } | 3530 | } |
3545 | } | 3531 | } |
3546 | ptr += sizeof(xlog_op_header_t) + op_len; | 3532 | ptr += sizeof(xlog_op_header_t) + op_len; |
@@ -3549,7 +3535,7 @@ xlog_verify_iclog(xlog_t *log, | |||
3549 | #endif | 3535 | #endif |
3550 | 3536 | ||
3551 | /* | 3537 | /* |
3552 | * Mark all iclogs IOERROR. LOG_LOCK is held by the caller. | 3538 | * Mark all iclogs IOERROR. l_icloglock is held by the caller. |
3553 | */ | 3539 | */ |
3554 | STATIC int | 3540 | STATIC int |
3555 | xlog_state_ioerror( | 3541 | xlog_state_ioerror( |
@@ -3597,8 +3583,6 @@ xfs_log_force_umount( | |||
3597 | xlog_t *log; | 3583 | xlog_t *log; |
3598 | int retval; | 3584 | int retval; |
3599 | int dummy; | 3585 | int dummy; |
3600 | SPLDECL(s); | ||
3601 | SPLDECL(s2); | ||
3602 | 3586 | ||
3603 | log = mp->m_log; | 3587 | log = mp->m_log; |
3604 | 3588 | ||
@@ -3627,8 +3611,8 @@ xfs_log_force_umount( | |||
3627 | * before we mark the filesystem SHUTDOWN and wake | 3611 | * before we mark the filesystem SHUTDOWN and wake |
3628 | * everybody up to tell the bad news. | 3612 | * everybody up to tell the bad news. |
3629 | */ | 3613 | */ |
3630 | s = GRANT_LOCK(log); | 3614 | spin_lock(&log->l_grant_lock); |
3631 | s2 = LOG_LOCK(log); | 3615 | spin_lock(&log->l_icloglock); |
3632 | mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; | 3616 | mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; |
3633 | XFS_BUF_DONE(mp->m_sb_bp); | 3617 | XFS_BUF_DONE(mp->m_sb_bp); |
3634 | /* | 3618 | /* |
@@ -3644,7 +3628,7 @@ xfs_log_force_umount( | |||
3644 | */ | 3628 | */ |
3645 | if (logerror) | 3629 | if (logerror) |
3646 | retval = xlog_state_ioerror(log); | 3630 | retval = xlog_state_ioerror(log); |
3647 | LOG_UNLOCK(log, s2); | 3631 | spin_unlock(&log->l_icloglock); |
3648 | 3632 | ||
3649 | /* | 3633 | /* |
3650 | * We don't want anybody waiting for log reservations | 3634 | * We don't want anybody waiting for log reservations |
@@ -3667,7 +3651,7 @@ xfs_log_force_umount( | |||
3667 | tic = tic->t_next; | 3651 | tic = tic->t_next; |
3668 | } while (tic != log->l_write_headq); | 3652 | } while (tic != log->l_write_headq); |
3669 | } | 3653 | } |
3670 | GRANT_UNLOCK(log, s); | 3654 | spin_unlock(&log->l_grant_lock); |
3671 | 3655 | ||
3672 | if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { | 3656 | if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { |
3673 | ASSERT(!logerror); | 3657 | ASSERT(!logerror); |
@@ -3676,9 +3660,9 @@ xfs_log_force_umount( | |||
3676 | * log down completely. | 3660 | * log down completely. |
3677 | */ | 3661 | */ |
3678 | xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy); | 3662 | xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy); |
3679 | s2 = LOG_LOCK(log); | 3663 | spin_lock(&log->l_icloglock); |
3680 | retval = xlog_state_ioerror(log); | 3664 | retval = xlog_state_ioerror(log); |
3681 | LOG_UNLOCK(log, s2); | 3665 | spin_unlock(&log->l_icloglock); |
3682 | } | 3666 | } |
3683 | /* | 3667 | /* |
3684 | * Wake up everybody waiting on xfs_log_force. | 3668 | * Wake up everybody waiting on xfs_log_force. |
@@ -3691,13 +3675,13 @@ xfs_log_force_umount( | |||
3691 | { | 3675 | { |
3692 | xlog_in_core_t *iclog; | 3676 | xlog_in_core_t *iclog; |
3693 | 3677 | ||
3694 | s = LOG_LOCK(log); | 3678 | spin_lock(&log->l_icloglock); |
3695 | iclog = log->l_iclog; | 3679 | iclog = log->l_iclog; |
3696 | do { | 3680 | do { |
3697 | ASSERT(iclog->ic_callback == 0); | 3681 | ASSERT(iclog->ic_callback == 0); |
3698 | iclog = iclog->ic_next; | 3682 | iclog = iclog->ic_next; |
3699 | } while (iclog != log->l_iclog); | 3683 | } while (iclog != log->l_iclog); |
3700 | LOG_UNLOCK(log, s); | 3684 | spin_unlock(&log->l_icloglock); |
3701 | } | 3685 | } |
3702 | #endif | 3686 | #endif |
3703 | /* return non-zero if log IOERROR transition had already happened */ | 3687 | /* return non-zero if log IOERROR transition had already happened */ |
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index ebbe93f4f97b..4cdac048df5e 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
@@ -22,8 +22,9 @@ | |||
22 | 22 | ||
23 | #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) | 23 | #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) |
24 | #define BLOCK_LSN(lsn) ((uint)(lsn)) | 24 | #define BLOCK_LSN(lsn) ((uint)(lsn)) |
25 | |||
25 | /* this is used in a spot where we might otherwise double-endian-flip */ | 26 | /* this is used in a spot where we might otherwise double-endian-flip */ |
26 | #define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0]) | 27 | #define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) |
27 | 28 | ||
28 | #ifdef __KERNEL__ | 29 | #ifdef __KERNEL__ |
29 | /* | 30 | /* |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 752f964b3699..e008233ee249 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -55,32 +55,21 @@ struct xfs_mount; | |||
55 | BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ | 55 | BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ |
56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) | 56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) |
57 | 57 | ||
58 | /* | ||
59 | * set lsns | ||
60 | */ | ||
61 | 58 | ||
62 | #define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \ | 59 | static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) |
63 | { \ | 60 | { |
64 | (lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \ | 61 | return ((xfs_lsn_t)cycle << 32) | block; |
65 | } | 62 | } |
66 | #define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \ | ||
67 | { \ | ||
68 | INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \ | ||
69 | INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \ | ||
70 | } | ||
71 | #define ASSIGN_LSN(lsn,log) \ | ||
72 | ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block); | ||
73 | |||
74 | #define XLOG_SET(f,b) (((f) & (b)) == (b)) | ||
75 | |||
76 | #define GET_CYCLE(ptr, arch) \ | ||
77 | (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \ | ||
78 | INT_GET(*((uint *)(ptr)+1), arch) : \ | ||
79 | INT_GET(*(uint *)(ptr), arch) \ | ||
80 | ) | ||
81 | 63 | ||
82 | #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) | 64 | static inline uint xlog_get_cycle(char *ptr) |
65 | { | ||
66 | if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) | ||
67 | return be32_to_cpu(*((__be32 *)ptr + 1)); | ||
68 | else | ||
69 | return be32_to_cpu(*(__be32 *)ptr); | ||
70 | } | ||
83 | 71 | ||
72 | #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) | ||
84 | 73 | ||
85 | #ifdef __KERNEL__ | 74 | #ifdef __KERNEL__ |
86 | 75 | ||
@@ -96,19 +85,10 @@ struct xfs_mount; | |||
96 | * | 85 | * |
97 | * this has endian issues, of course. | 86 | * this has endian issues, of course. |
98 | */ | 87 | */ |
99 | 88 | static inline uint xlog_get_client_id(__be32 i) | |
100 | #ifndef XFS_NATIVE_HOST | 89 | { |
101 | #define GET_CLIENT_ID(i,arch) \ | 90 | return be32_to_cpu(i) >> 24; |
102 | ((i) & 0xff) | 91 | } |
103 | #else | ||
104 | #define GET_CLIENT_ID(i,arch) \ | ||
105 | ((i) >> 24) | ||
106 | #endif | ||
107 | |||
108 | #define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock) | ||
109 | #define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s) | ||
110 | #define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock) | ||
111 | #define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s) | ||
112 | 92 | ||
113 | #define xlog_panic(args...) cmn_err(CE_PANIC, ## args) | 93 | #define xlog_panic(args...) cmn_err(CE_PANIC, ## args) |
114 | #define xlog_exit(args...) cmn_err(CE_PANIC, ## args) | 94 | #define xlog_exit(args...) cmn_err(CE_PANIC, ## args) |
@@ -285,11 +265,11 @@ typedef struct xlog_ticket { | |||
285 | 265 | ||
286 | 266 | ||
287 | typedef struct xlog_op_header { | 267 | typedef struct xlog_op_header { |
288 | xlog_tid_t oh_tid; /* transaction id of operation : 4 b */ | 268 | __be32 oh_tid; /* transaction id of operation : 4 b */ |
289 | int oh_len; /* bytes in data region : 4 b */ | 269 | __be32 oh_len; /* bytes in data region : 4 b */ |
290 | __uint8_t oh_clientid; /* who sent me this : 1 b */ | 270 | __u8 oh_clientid; /* who sent me this : 1 b */ |
291 | __uint8_t oh_flags; /* : 1 b */ | 271 | __u8 oh_flags; /* : 1 b */ |
292 | ushort oh_res2; /* 32 bit align : 2 b */ | 272 | __u16 oh_res2; /* 32 bit align : 2 b */ |
293 | } xlog_op_header_t; | 273 | } xlog_op_header_t; |
294 | 274 | ||
295 | 275 | ||
@@ -307,25 +287,25 @@ typedef struct xlog_op_header { | |||
307 | #endif | 287 | #endif |
308 | 288 | ||
309 | typedef struct xlog_rec_header { | 289 | typedef struct xlog_rec_header { |
310 | uint h_magicno; /* log record (LR) identifier : 4 */ | 290 | __be32 h_magicno; /* log record (LR) identifier : 4 */ |
311 | uint h_cycle; /* write cycle of log : 4 */ | 291 | __be32 h_cycle; /* write cycle of log : 4 */ |
312 | int h_version; /* LR version : 4 */ | 292 | __be32 h_version; /* LR version : 4 */ |
313 | int h_len; /* len in bytes; should be 64-bit aligned: 4 */ | 293 | __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */ |
314 | xfs_lsn_t h_lsn; /* lsn of this LR : 8 */ | 294 | __be64 h_lsn; /* lsn of this LR : 8 */ |
315 | xfs_lsn_t h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ | 295 | __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */ |
316 | uint h_chksum; /* may not be used; non-zero if used : 4 */ | 296 | __be32 h_chksum; /* may not be used; non-zero if used : 4 */ |
317 | int h_prev_block; /* block number to previous LR : 4 */ | 297 | __be32 h_prev_block; /* block number to previous LR : 4 */ |
318 | int h_num_logops; /* number of log operations in this LR : 4 */ | 298 | __be32 h_num_logops; /* number of log operations in this LR : 4 */ |
319 | uint h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; | 299 | __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; |
320 | /* new fields */ | 300 | /* new fields */ |
321 | int h_fmt; /* format of log record : 4 */ | 301 | __be32 h_fmt; /* format of log record : 4 */ |
322 | uuid_t h_fs_uuid; /* uuid of FS : 16 */ | 302 | uuid_t h_fs_uuid; /* uuid of FS : 16 */ |
323 | int h_size; /* iclog size : 4 */ | 303 | __be32 h_size; /* iclog size : 4 */ |
324 | } xlog_rec_header_t; | 304 | } xlog_rec_header_t; |
325 | 305 | ||
326 | typedef struct xlog_rec_ext_header { | 306 | typedef struct xlog_rec_ext_header { |
327 | uint xh_cycle; /* write cycle of log : 4 */ | 307 | __be32 xh_cycle; /* write cycle of log : 4 */ |
328 | uint xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ | 308 | __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */ |
329 | } xlog_rec_ext_header_t; | 309 | } xlog_rec_ext_header_t; |
330 | 310 | ||
331 | #ifdef __KERNEL__ | 311 | #ifdef __KERNEL__ |
@@ -415,7 +395,7 @@ typedef struct log { | |||
415 | xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */ | 395 | xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */ |
416 | xlog_ticket_t *l_tail; /* free list of tickets */ | 396 | xlog_ticket_t *l_tail; /* free list of tickets */ |
417 | xlog_in_core_t *l_iclog; /* head log queue */ | 397 | xlog_in_core_t *l_iclog; /* head log queue */ |
418 | lock_t l_icloglock; /* grab to change iclog state */ | 398 | spinlock_t l_icloglock; /* grab to change iclog state */ |
419 | xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed | 399 | xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed |
420 | * buffers */ | 400 | * buffers */ |
421 | xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ | 401 | xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ |
@@ -439,7 +419,7 @@ typedef struct log { | |||
439 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; | 419 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; |
440 | 420 | ||
441 | /* The following block of fields are changed while holding grant_lock */ | 421 | /* The following block of fields are changed while holding grant_lock */ |
442 | lock_t l_grant_lock; | 422 | spinlock_t l_grant_lock; |
443 | xlog_ticket_t *l_reserve_headq; | 423 | xlog_ticket_t *l_reserve_headq; |
444 | xlog_ticket_t *l_write_headq; | 424 | xlog_ticket_t *l_write_headq; |
445 | int l_grant_reserve_cycle; | 425 | int l_grant_reserve_cycle; |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 851eca8a7150..b82d5d4d2462 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -198,7 +198,7 @@ xlog_header_check_dump( | |||
198 | cmn_err(CE_DEBUG, " log : uuid = "); | 198 | cmn_err(CE_DEBUG, " log : uuid = "); |
199 | for (b = 0; b < 16; b++) | 199 | for (b = 0; b < 16; b++) |
200 | cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]); | 200 | cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]); |
201 | cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); | 201 | cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt)); |
202 | } | 202 | } |
203 | #else | 203 | #else |
204 | #define xlog_header_check_dump(mp, head) | 204 | #define xlog_header_check_dump(mp, head) |
@@ -212,14 +212,14 @@ xlog_header_check_recover( | |||
212 | xfs_mount_t *mp, | 212 | xfs_mount_t *mp, |
213 | xlog_rec_header_t *head) | 213 | xlog_rec_header_t *head) |
214 | { | 214 | { |
215 | ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM); | 215 | ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM); |
216 | 216 | ||
217 | /* | 217 | /* |
218 | * IRIX doesn't write the h_fmt field and leaves it zeroed | 218 | * IRIX doesn't write the h_fmt field and leaves it zeroed |
219 | * (XLOG_FMT_UNKNOWN). This stops us from trying to recover | 219 | * (XLOG_FMT_UNKNOWN). This stops us from trying to recover |
220 | * a dirty log created in IRIX. | 220 | * a dirty log created in IRIX. |
221 | */ | 221 | */ |
222 | if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) { | 222 | if (unlikely(be32_to_cpu(head->h_fmt) != XLOG_FMT)) { |
223 | xlog_warn( | 223 | xlog_warn( |
224 | "XFS: dirty log written in incompatible format - can't recover"); | 224 | "XFS: dirty log written in incompatible format - can't recover"); |
225 | xlog_header_check_dump(mp, head); | 225 | xlog_header_check_dump(mp, head); |
@@ -245,7 +245,7 @@ xlog_header_check_mount( | |||
245 | xfs_mount_t *mp, | 245 | xfs_mount_t *mp, |
246 | xlog_rec_header_t *head) | 246 | xlog_rec_header_t *head) |
247 | { | 247 | { |
248 | ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM); | 248 | ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM); |
249 | 249 | ||
250 | if (uuid_is_nil(&head->h_fs_uuid)) { | 250 | if (uuid_is_nil(&head->h_fs_uuid)) { |
251 | /* | 251 | /* |
@@ -293,7 +293,7 @@ xlog_recover_iodone( | |||
293 | * Note that the algorithm can not be perfect because the disk will not | 293 | * Note that the algorithm can not be perfect because the disk will not |
294 | * necessarily be perfect. | 294 | * necessarily be perfect. |
295 | */ | 295 | */ |
296 | int | 296 | STATIC int |
297 | xlog_find_cycle_start( | 297 | xlog_find_cycle_start( |
298 | xlog_t *log, | 298 | xlog_t *log, |
299 | xfs_buf_t *bp, | 299 | xfs_buf_t *bp, |
@@ -311,7 +311,7 @@ xlog_find_cycle_start( | |||
311 | if ((error = xlog_bread(log, mid_blk, 1, bp))) | 311 | if ((error = xlog_bread(log, mid_blk, 1, bp))) |
312 | return error; | 312 | return error; |
313 | offset = xlog_align(log, mid_blk, 1, bp); | 313 | offset = xlog_align(log, mid_blk, 1, bp); |
314 | mid_cycle = GET_CYCLE(offset, ARCH_CONVERT); | 314 | mid_cycle = xlog_get_cycle(offset); |
315 | if (mid_cycle == cycle) { | 315 | if (mid_cycle == cycle) { |
316 | *last_blk = mid_blk; | 316 | *last_blk = mid_blk; |
317 | /* last_half_cycle == mid_cycle */ | 317 | /* last_half_cycle == mid_cycle */ |
@@ -371,7 +371,7 @@ xlog_find_verify_cycle( | |||
371 | 371 | ||
372 | buf = xlog_align(log, i, bcount, bp); | 372 | buf = xlog_align(log, i, bcount, bp); |
373 | for (j = 0; j < bcount; j++) { | 373 | for (j = 0; j < bcount; j++) { |
374 | cycle = GET_CYCLE(buf, ARCH_CONVERT); | 374 | cycle = xlog_get_cycle(buf); |
375 | if (cycle == stop_on_cycle_no) { | 375 | if (cycle == stop_on_cycle_no) { |
376 | *new_blk = i+j; | 376 | *new_blk = i+j; |
377 | goto out; | 377 | goto out; |
@@ -447,8 +447,7 @@ xlog_find_verify_log_record( | |||
447 | 447 | ||
448 | head = (xlog_rec_header_t *)offset; | 448 | head = (xlog_rec_header_t *)offset; |
449 | 449 | ||
450 | if (XLOG_HEADER_MAGIC_NUM == | 450 | if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) |
451 | INT_GET(head->h_magicno, ARCH_CONVERT)) | ||
452 | break; | 451 | break; |
453 | 452 | ||
454 | if (!smallmem) | 453 | if (!smallmem) |
@@ -480,7 +479,7 @@ xlog_find_verify_log_record( | |||
480 | * record do we update last_blk. | 479 | * record do we update last_blk. |
481 | */ | 480 | */ |
482 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 481 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { |
483 | uint h_size = INT_GET(head->h_size, ARCH_CONVERT); | 482 | uint h_size = be32_to_cpu(head->h_size); |
484 | 483 | ||
485 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; | 484 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; |
486 | if (h_size % XLOG_HEADER_CYCLE_SIZE) | 485 | if (h_size % XLOG_HEADER_CYCLE_SIZE) |
@@ -489,8 +488,8 @@ xlog_find_verify_log_record( | |||
489 | xhdrs = 1; | 488 | xhdrs = 1; |
490 | } | 489 | } |
491 | 490 | ||
492 | if (*last_blk - i + extra_bblks | 491 | if (*last_blk - i + extra_bblks != |
493 | != BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs) | 492 | BTOBB(be32_to_cpu(head->h_len)) + xhdrs) |
494 | *last_blk = i; | 493 | *last_blk = i; |
495 | 494 | ||
496 | out: | 495 | out: |
@@ -550,13 +549,13 @@ xlog_find_head( | |||
550 | if ((error = xlog_bread(log, 0, 1, bp))) | 549 | if ((error = xlog_bread(log, 0, 1, bp))) |
551 | goto bp_err; | 550 | goto bp_err; |
552 | offset = xlog_align(log, 0, 1, bp); | 551 | offset = xlog_align(log, 0, 1, bp); |
553 | first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT); | 552 | first_half_cycle = xlog_get_cycle(offset); |
554 | 553 | ||
555 | last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */ | 554 | last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */ |
556 | if ((error = xlog_bread(log, last_blk, 1, bp))) | 555 | if ((error = xlog_bread(log, last_blk, 1, bp))) |
557 | goto bp_err; | 556 | goto bp_err; |
558 | offset = xlog_align(log, last_blk, 1, bp); | 557 | offset = xlog_align(log, last_blk, 1, bp); |
559 | last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT); | 558 | last_half_cycle = xlog_get_cycle(offset); |
560 | ASSERT(last_half_cycle != 0); | 559 | ASSERT(last_half_cycle != 0); |
561 | 560 | ||
562 | /* | 561 | /* |
@@ -808,7 +807,7 @@ xlog_find_tail( | |||
808 | if ((error = xlog_bread(log, 0, 1, bp))) | 807 | if ((error = xlog_bread(log, 0, 1, bp))) |
809 | goto bread_err; | 808 | goto bread_err; |
810 | offset = xlog_align(log, 0, 1, bp); | 809 | offset = xlog_align(log, 0, 1, bp); |
811 | if (GET_CYCLE(offset, ARCH_CONVERT) == 0) { | 810 | if (xlog_get_cycle(offset) == 0) { |
812 | *tail_blk = 0; | 811 | *tail_blk = 0; |
813 | /* leave all other log inited values alone */ | 812 | /* leave all other log inited values alone */ |
814 | goto exit; | 813 | goto exit; |
@@ -823,8 +822,7 @@ xlog_find_tail( | |||
823 | if ((error = xlog_bread(log, i, 1, bp))) | 822 | if ((error = xlog_bread(log, i, 1, bp))) |
824 | goto bread_err; | 823 | goto bread_err; |
825 | offset = xlog_align(log, i, 1, bp); | 824 | offset = xlog_align(log, i, 1, bp); |
826 | if (XLOG_HEADER_MAGIC_NUM == | 825 | if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { |
827 | INT_GET(*(uint *)offset, ARCH_CONVERT)) { | ||
828 | found = 1; | 826 | found = 1; |
829 | break; | 827 | break; |
830 | } | 828 | } |
@@ -841,7 +839,7 @@ xlog_find_tail( | |||
841 | goto bread_err; | 839 | goto bread_err; |
842 | offset = xlog_align(log, i, 1, bp); | 840 | offset = xlog_align(log, i, 1, bp); |
843 | if (XLOG_HEADER_MAGIC_NUM == | 841 | if (XLOG_HEADER_MAGIC_NUM == |
844 | INT_GET(*(uint*)offset, ARCH_CONVERT)) { | 842 | be32_to_cpu(*(__be32 *)offset)) { |
845 | found = 2; | 843 | found = 2; |
846 | break; | 844 | break; |
847 | } | 845 | } |
@@ -855,7 +853,7 @@ xlog_find_tail( | |||
855 | 853 | ||
856 | /* find blk_no of tail of log */ | 854 | /* find blk_no of tail of log */ |
857 | rhead = (xlog_rec_header_t *)offset; | 855 | rhead = (xlog_rec_header_t *)offset; |
858 | *tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT)); | 856 | *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); |
859 | 857 | ||
860 | /* | 858 | /* |
861 | * Reset log values according to the state of the log when we | 859 | * Reset log values according to the state of the log when we |
@@ -869,11 +867,11 @@ xlog_find_tail( | |||
869 | */ | 867 | */ |
870 | log->l_prev_block = i; | 868 | log->l_prev_block = i; |
871 | log->l_curr_block = (int)*head_blk; | 869 | log->l_curr_block = (int)*head_blk; |
872 | log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT); | 870 | log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); |
873 | if (found == 2) | 871 | if (found == 2) |
874 | log->l_curr_cycle++; | 872 | log->l_curr_cycle++; |
875 | log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT); | 873 | log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); |
876 | log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT); | 874 | log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); |
877 | log->l_grant_reserve_cycle = log->l_curr_cycle; | 875 | log->l_grant_reserve_cycle = log->l_curr_cycle; |
878 | log->l_grant_reserve_bytes = BBTOB(log->l_curr_block); | 876 | log->l_grant_reserve_bytes = BBTOB(log->l_curr_block); |
879 | log->l_grant_write_cycle = log->l_curr_cycle; | 877 | log->l_grant_write_cycle = log->l_curr_cycle; |
@@ -891,8 +889,8 @@ xlog_find_tail( | |||
891 | * unmount record rather than the block after it. | 889 | * unmount record rather than the block after it. |
892 | */ | 890 | */ |
893 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 891 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { |
894 | int h_size = INT_GET(rhead->h_size, ARCH_CONVERT); | 892 | int h_size = be32_to_cpu(rhead->h_size); |
895 | int h_version = INT_GET(rhead->h_version, ARCH_CONVERT); | 893 | int h_version = be32_to_cpu(rhead->h_version); |
896 | 894 | ||
897 | if ((h_version & XLOG_VERSION_2) && | 895 | if ((h_version & XLOG_VERSION_2) && |
898 | (h_size > XLOG_HEADER_CYCLE_SIZE)) { | 896 | (h_size > XLOG_HEADER_CYCLE_SIZE)) { |
@@ -906,10 +904,10 @@ xlog_find_tail( | |||
906 | hblks = 1; | 904 | hblks = 1; |
907 | } | 905 | } |
908 | after_umount_blk = (i + hblks + (int) | 906 | after_umount_blk = (i + hblks + (int) |
909 | BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize; | 907 | BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; |
910 | tail_lsn = log->l_tail_lsn; | 908 | tail_lsn = log->l_tail_lsn; |
911 | if (*head_blk == after_umount_blk && | 909 | if (*head_blk == after_umount_blk && |
912 | INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) { | 910 | be32_to_cpu(rhead->h_num_logops) == 1) { |
913 | umount_data_blk = (i + hblks) % log->l_logBBsize; | 911 | umount_data_blk = (i + hblks) % log->l_logBBsize; |
914 | if ((error = xlog_bread(log, umount_data_blk, 1, bp))) { | 912 | if ((error = xlog_bread(log, umount_data_blk, 1, bp))) { |
915 | goto bread_err; | 913 | goto bread_err; |
@@ -922,10 +920,12 @@ xlog_find_tail( | |||
922 | * log records will point recovery to after the | 920 | * log records will point recovery to after the |
923 | * current unmount record. | 921 | * current unmount record. |
924 | */ | 922 | */ |
925 | ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle, | 923 | log->l_tail_lsn = |
926 | after_umount_blk); | 924 | xlog_assign_lsn(log->l_curr_cycle, |
927 | ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle, | 925 | after_umount_blk); |
928 | after_umount_blk); | 926 | log->l_last_sync_lsn = |
927 | xlog_assign_lsn(log->l_curr_cycle, | ||
928 | after_umount_blk); | ||
929 | *tail_blk = after_umount_blk; | 929 | *tail_blk = after_umount_blk; |
930 | 930 | ||
931 | /* | 931 | /* |
@@ -986,7 +986,7 @@ exit: | |||
986 | * -1 => use *blk_no as the first block of the log | 986 | * -1 => use *blk_no as the first block of the log |
987 | * >0 => error has occurred | 987 | * >0 => error has occurred |
988 | */ | 988 | */ |
989 | int | 989 | STATIC int |
990 | xlog_find_zeroed( | 990 | xlog_find_zeroed( |
991 | xlog_t *log, | 991 | xlog_t *log, |
992 | xfs_daddr_t *blk_no) | 992 | xfs_daddr_t *blk_no) |
@@ -1007,7 +1007,7 @@ xlog_find_zeroed( | |||
1007 | if ((error = xlog_bread(log, 0, 1, bp))) | 1007 | if ((error = xlog_bread(log, 0, 1, bp))) |
1008 | goto bp_err; | 1008 | goto bp_err; |
1009 | offset = xlog_align(log, 0, 1, bp); | 1009 | offset = xlog_align(log, 0, 1, bp); |
1010 | first_cycle = GET_CYCLE(offset, ARCH_CONVERT); | 1010 | first_cycle = xlog_get_cycle(offset); |
1011 | if (first_cycle == 0) { /* completely zeroed log */ | 1011 | if (first_cycle == 0) { /* completely zeroed log */ |
1012 | *blk_no = 0; | 1012 | *blk_no = 0; |
1013 | xlog_put_bp(bp); | 1013 | xlog_put_bp(bp); |
@@ -1018,7 +1018,7 @@ xlog_find_zeroed( | |||
1018 | if ((error = xlog_bread(log, log_bbnum-1, 1, bp))) | 1018 | if ((error = xlog_bread(log, log_bbnum-1, 1, bp))) |
1019 | goto bp_err; | 1019 | goto bp_err; |
1020 | offset = xlog_align(log, log_bbnum-1, 1, bp); | 1020 | offset = xlog_align(log, log_bbnum-1, 1, bp); |
1021 | last_cycle = GET_CYCLE(offset, ARCH_CONVERT); | 1021 | last_cycle = xlog_get_cycle(offset); |
1022 | if (last_cycle != 0) { /* log completely written to */ | 1022 | if (last_cycle != 0) { /* log completely written to */ |
1023 | xlog_put_bp(bp); | 1023 | xlog_put_bp(bp); |
1024 | return 0; | 1024 | return 0; |
@@ -1098,13 +1098,13 @@ xlog_add_record( | |||
1098 | xlog_rec_header_t *recp = (xlog_rec_header_t *)buf; | 1098 | xlog_rec_header_t *recp = (xlog_rec_header_t *)buf; |
1099 | 1099 | ||
1100 | memset(buf, 0, BBSIZE); | 1100 | memset(buf, 0, BBSIZE); |
1101 | INT_SET(recp->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM); | 1101 | recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
1102 | INT_SET(recp->h_cycle, ARCH_CONVERT, cycle); | 1102 | recp->h_cycle = cpu_to_be32(cycle); |
1103 | INT_SET(recp->h_version, ARCH_CONVERT, | 1103 | recp->h_version = cpu_to_be32( |
1104 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); | 1104 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); |
1105 | ASSIGN_ANY_LSN_DISK(recp->h_lsn, cycle, block); | 1105 | recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block)); |
1106 | ASSIGN_ANY_LSN_DISK(recp->h_tail_lsn, tail_cycle, tail_block); | 1106 | recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block)); |
1107 | INT_SET(recp->h_fmt, ARCH_CONVERT, XLOG_FMT); | 1107 | recp->h_fmt = cpu_to_be32(XLOG_FMT); |
1108 | memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t)); | 1108 | memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t)); |
1109 | } | 1109 | } |
1110 | 1110 | ||
@@ -2211,7 +2211,7 @@ xlog_recover_do_buffer_trans( | |||
2211 | * overlap with future reads of those inodes. | 2211 | * overlap with future reads of those inodes. |
2212 | */ | 2212 | */ |
2213 | if (XFS_DINODE_MAGIC == | 2213 | if (XFS_DINODE_MAGIC == |
2214 | INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) && | 2214 | be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) && |
2215 | (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize, | 2215 | (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize, |
2216 | (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) { | 2216 | (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) { |
2217 | XFS_BUF_STALE(bp); | 2217 | XFS_BUF_STALE(bp); |
@@ -2581,8 +2581,7 @@ xlog_recover_do_dquot_trans( | |||
2581 | /* | 2581 | /* |
2582 | * This type of quotas was turned off, so ignore this record. | 2582 | * This type of quotas was turned off, so ignore this record. |
2583 | */ | 2583 | */ |
2584 | type = INT_GET(recddq->d_flags, ARCH_CONVERT) & | 2584 | type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP); |
2585 | (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP); | ||
2586 | ASSERT(type); | 2585 | ASSERT(type); |
2587 | if (log->l_quotaoffs_flag & type) | 2586 | if (log->l_quotaoffs_flag & type) |
2588 | return (0); | 2587 | return (0); |
@@ -2660,7 +2659,6 @@ xlog_recover_do_efi_trans( | |||
2660 | xfs_mount_t *mp; | 2659 | xfs_mount_t *mp; |
2661 | xfs_efi_log_item_t *efip; | 2660 | xfs_efi_log_item_t *efip; |
2662 | xfs_efi_log_format_t *efi_formatp; | 2661 | xfs_efi_log_format_t *efi_formatp; |
2663 | SPLDECL(s); | ||
2664 | 2662 | ||
2665 | if (pass == XLOG_RECOVER_PASS1) { | 2663 | if (pass == XLOG_RECOVER_PASS1) { |
2666 | return 0; | 2664 | return 0; |
@@ -2678,11 +2676,11 @@ xlog_recover_do_efi_trans( | |||
2678 | efip->efi_next_extent = efi_formatp->efi_nextents; | 2676 | efip->efi_next_extent = efi_formatp->efi_nextents; |
2679 | efip->efi_flags |= XFS_EFI_COMMITTED; | 2677 | efip->efi_flags |= XFS_EFI_COMMITTED; |
2680 | 2678 | ||
2681 | AIL_LOCK(mp,s); | 2679 | spin_lock(&mp->m_ail_lock); |
2682 | /* | 2680 | /* |
2683 | * xfs_trans_update_ail() drops the AIL lock. | 2681 | * xfs_trans_update_ail() drops the AIL lock. |
2684 | */ | 2682 | */ |
2685 | xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); | 2683 | xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn); |
2686 | return 0; | 2684 | return 0; |
2687 | } | 2685 | } |
2688 | 2686 | ||
@@ -2707,7 +2705,6 @@ xlog_recover_do_efd_trans( | |||
2707 | xfs_log_item_t *lip; | 2705 | xfs_log_item_t *lip; |
2708 | int gen; | 2706 | int gen; |
2709 | __uint64_t efi_id; | 2707 | __uint64_t efi_id; |
2710 | SPLDECL(s); | ||
2711 | 2708 | ||
2712 | if (pass == XLOG_RECOVER_PASS1) { | 2709 | if (pass == XLOG_RECOVER_PASS1) { |
2713 | return; | 2710 | return; |
@@ -2725,7 +2722,7 @@ xlog_recover_do_efd_trans( | |||
2725 | * in the AIL. | 2722 | * in the AIL. |
2726 | */ | 2723 | */ |
2727 | mp = log->l_mp; | 2724 | mp = log->l_mp; |
2728 | AIL_LOCK(mp,s); | 2725 | spin_lock(&mp->m_ail_lock); |
2729 | lip = xfs_trans_first_ail(mp, &gen); | 2726 | lip = xfs_trans_first_ail(mp, &gen); |
2730 | while (lip != NULL) { | 2727 | while (lip != NULL) { |
2731 | if (lip->li_type == XFS_LI_EFI) { | 2728 | if (lip->li_type == XFS_LI_EFI) { |
@@ -2735,22 +2732,14 @@ xlog_recover_do_efd_trans( | |||
2735 | * xfs_trans_delete_ail() drops the | 2732 | * xfs_trans_delete_ail() drops the |
2736 | * AIL lock. | 2733 | * AIL lock. |
2737 | */ | 2734 | */ |
2738 | xfs_trans_delete_ail(mp, lip, s); | 2735 | xfs_trans_delete_ail(mp, lip); |
2739 | break; | 2736 | xfs_efi_item_free(efip); |
2737 | return; | ||
2740 | } | 2738 | } |
2741 | } | 2739 | } |
2742 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | 2740 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); |
2743 | } | 2741 | } |
2744 | 2742 | spin_unlock(&mp->m_ail_lock); | |
2745 | /* | ||
2746 | * If we found it, then free it up. If it wasn't there, it | ||
2747 | * must have been overwritten in the log. Oh well. | ||
2748 | */ | ||
2749 | if (lip != NULL) { | ||
2750 | xfs_efi_item_free(efip); | ||
2751 | } else { | ||
2752 | AIL_UNLOCK(mp, s); | ||
2753 | } | ||
2754 | } | 2743 | } |
2755 | 2744 | ||
2756 | /* | 2745 | /* |
@@ -2897,8 +2886,8 @@ xlog_recover_process_data( | |||
2897 | unsigned long hash; | 2886 | unsigned long hash; |
2898 | uint flags; | 2887 | uint flags; |
2899 | 2888 | ||
2900 | lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT); | 2889 | lp = dp + be32_to_cpu(rhead->h_len); |
2901 | num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT); | 2890 | num_logops = be32_to_cpu(rhead->h_num_logops); |
2902 | 2891 | ||
2903 | /* check the log format matches our own - else we can't recover */ | 2892 | /* check the log format matches our own - else we can't recover */ |
2904 | if (xlog_header_check_recover(log->l_mp, rhead)) | 2893 | if (xlog_header_check_recover(log->l_mp, rhead)) |
@@ -2915,15 +2904,20 @@ xlog_recover_process_data( | |||
2915 | ASSERT(0); | 2904 | ASSERT(0); |
2916 | return (XFS_ERROR(EIO)); | 2905 | return (XFS_ERROR(EIO)); |
2917 | } | 2906 | } |
2918 | tid = INT_GET(ohead->oh_tid, ARCH_CONVERT); | 2907 | tid = be32_to_cpu(ohead->oh_tid); |
2919 | hash = XLOG_RHASH(tid); | 2908 | hash = XLOG_RHASH(tid); |
2920 | trans = xlog_recover_find_tid(rhash[hash], tid); | 2909 | trans = xlog_recover_find_tid(rhash[hash], tid); |
2921 | if (trans == NULL) { /* not found; add new tid */ | 2910 | if (trans == NULL) { /* not found; add new tid */ |
2922 | if (ohead->oh_flags & XLOG_START_TRANS) | 2911 | if (ohead->oh_flags & XLOG_START_TRANS) |
2923 | xlog_recover_new_tid(&rhash[hash], tid, | 2912 | xlog_recover_new_tid(&rhash[hash], tid, |
2924 | INT_GET(rhead->h_lsn, ARCH_CONVERT)); | 2913 | be64_to_cpu(rhead->h_lsn)); |
2925 | } else { | 2914 | } else { |
2926 | ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp); | 2915 | if (dp + be32_to_cpu(ohead->oh_len) > lp) { |
2916 | xlog_warn( | ||
2917 | "XFS: xlog_recover_process_data: bad length"); | ||
2918 | WARN_ON(1); | ||
2919 | return (XFS_ERROR(EIO)); | ||
2920 | } | ||
2927 | flags = ohead->oh_flags & ~XLOG_END_TRANS; | 2921 | flags = ohead->oh_flags & ~XLOG_END_TRANS; |
2928 | if (flags & XLOG_WAS_CONT_TRANS) | 2922 | if (flags & XLOG_WAS_CONT_TRANS) |
2929 | flags &= ~XLOG_CONTINUE_TRANS; | 2923 | flags &= ~XLOG_CONTINUE_TRANS; |
@@ -2937,8 +2931,7 @@ xlog_recover_process_data( | |||
2937 | break; | 2931 | break; |
2938 | case XLOG_WAS_CONT_TRANS: | 2932 | case XLOG_WAS_CONT_TRANS: |
2939 | error = xlog_recover_add_to_cont_trans(trans, | 2933 | error = xlog_recover_add_to_cont_trans(trans, |
2940 | dp, INT_GET(ohead->oh_len, | 2934 | dp, be32_to_cpu(ohead->oh_len)); |
2941 | ARCH_CONVERT)); | ||
2942 | break; | 2935 | break; |
2943 | case XLOG_START_TRANS: | 2936 | case XLOG_START_TRANS: |
2944 | xlog_warn( | 2937 | xlog_warn( |
@@ -2949,8 +2942,7 @@ xlog_recover_process_data( | |||
2949 | case 0: | 2942 | case 0: |
2950 | case XLOG_CONTINUE_TRANS: | 2943 | case XLOG_CONTINUE_TRANS: |
2951 | error = xlog_recover_add_to_trans(trans, | 2944 | error = xlog_recover_add_to_trans(trans, |
2952 | dp, INT_GET(ohead->oh_len, | 2945 | dp, be32_to_cpu(ohead->oh_len)); |
2953 | ARCH_CONVERT)); | ||
2954 | break; | 2946 | break; |
2955 | default: | 2947 | default: |
2956 | xlog_warn( | 2948 | xlog_warn( |
@@ -2962,7 +2954,7 @@ xlog_recover_process_data( | |||
2962 | if (error) | 2954 | if (error) |
2963 | return error; | 2955 | return error; |
2964 | } | 2956 | } |
2965 | dp += INT_GET(ohead->oh_len, ARCH_CONVERT); | 2957 | dp += be32_to_cpu(ohead->oh_len); |
2966 | num_logops--; | 2958 | num_logops--; |
2967 | } | 2959 | } |
2968 | return 0; | 2960 | return 0; |
@@ -3075,10 +3067,9 @@ xlog_recover_process_efis( | |||
3075 | xfs_efi_log_item_t *efip; | 3067 | xfs_efi_log_item_t *efip; |
3076 | int gen; | 3068 | int gen; |
3077 | xfs_mount_t *mp; | 3069 | xfs_mount_t *mp; |
3078 | SPLDECL(s); | ||
3079 | 3070 | ||
3080 | mp = log->l_mp; | 3071 | mp = log->l_mp; |
3081 | AIL_LOCK(mp,s); | 3072 | spin_lock(&mp->m_ail_lock); |
3082 | 3073 | ||
3083 | lip = xfs_trans_first_ail(mp, &gen); | 3074 | lip = xfs_trans_first_ail(mp, &gen); |
3084 | while (lip != NULL) { | 3075 | while (lip != NULL) { |
@@ -3099,12 +3090,12 @@ xlog_recover_process_efis( | |||
3099 | continue; | 3090 | continue; |
3100 | } | 3091 | } |
3101 | 3092 | ||
3102 | AIL_UNLOCK(mp, s); | 3093 | spin_unlock(&mp->m_ail_lock); |
3103 | xlog_recover_process_efi(mp, efip); | 3094 | xlog_recover_process_efi(mp, efip); |
3104 | AIL_LOCK(mp,s); | 3095 | spin_lock(&mp->m_ail_lock); |
3105 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | 3096 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); |
3106 | } | 3097 | } |
3107 | AIL_UNLOCK(mp, s); | 3098 | spin_unlock(&mp->m_ail_lock); |
3108 | } | 3099 | } |
3109 | 3100 | ||
3110 | /* | 3101 | /* |
@@ -3315,16 +3306,16 @@ xlog_pack_data_checksum( | |||
3315 | int size) | 3306 | int size) |
3316 | { | 3307 | { |
3317 | int i; | 3308 | int i; |
3318 | uint *up; | 3309 | __be32 *up; |
3319 | uint chksum = 0; | 3310 | uint chksum = 0; |
3320 | 3311 | ||
3321 | up = (uint *)iclog->ic_datap; | 3312 | up = (__be32 *)iclog->ic_datap; |
3322 | /* divide length by 4 to get # words */ | 3313 | /* divide length by 4 to get # words */ |
3323 | for (i = 0; i < (size >> 2); i++) { | 3314 | for (i = 0; i < (size >> 2); i++) { |
3324 | chksum ^= INT_GET(*up, ARCH_CONVERT); | 3315 | chksum ^= be32_to_cpu(*up); |
3325 | up++; | 3316 | up++; |
3326 | } | 3317 | } |
3327 | INT_SET(iclog->ic_header.h_chksum, ARCH_CONVERT, chksum); | 3318 | iclog->ic_header.h_chksum = cpu_to_be32(chksum); |
3328 | } | 3319 | } |
3329 | #else | 3320 | #else |
3330 | #define xlog_pack_data_checksum(log, iclog, size) | 3321 | #define xlog_pack_data_checksum(log, iclog, size) |
@@ -3341,7 +3332,7 @@ xlog_pack_data( | |||
3341 | { | 3332 | { |
3342 | int i, j, k; | 3333 | int i, j, k; |
3343 | int size = iclog->ic_offset + roundoff; | 3334 | int size = iclog->ic_offset + roundoff; |
3344 | uint cycle_lsn; | 3335 | __be32 cycle_lsn; |
3345 | xfs_caddr_t dp; | 3336 | xfs_caddr_t dp; |
3346 | xlog_in_core_2_t *xhdr; | 3337 | xlog_in_core_2_t *xhdr; |
3347 | 3338 | ||
@@ -3352,8 +3343,8 @@ xlog_pack_data( | |||
3352 | dp = iclog->ic_datap; | 3343 | dp = iclog->ic_datap; |
3353 | for (i = 0; i < BTOBB(size) && | 3344 | for (i = 0; i < BTOBB(size) && |
3354 | i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { | 3345 | i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { |
3355 | iclog->ic_header.h_cycle_data[i] = *(uint *)dp; | 3346 | iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp; |
3356 | *(uint *)dp = cycle_lsn; | 3347 | *(__be32 *)dp = cycle_lsn; |
3357 | dp += BBSIZE; | 3348 | dp += BBSIZE; |
3358 | } | 3349 | } |
3359 | 3350 | ||
@@ -3362,8 +3353,8 @@ xlog_pack_data( | |||
3362 | for ( ; i < BTOBB(size); i++) { | 3353 | for ( ; i < BTOBB(size); i++) { |
3363 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3354 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3364 | k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3355 | k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3365 | xhdr[j].hic_xheader.xh_cycle_data[k] = *(uint *)dp; | 3356 | xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp; |
3366 | *(uint *)dp = cycle_lsn; | 3357 | *(__be32 *)dp = cycle_lsn; |
3367 | dp += BBSIZE; | 3358 | dp += BBSIZE; |
3368 | } | 3359 | } |
3369 | 3360 | ||
@@ -3380,21 +3371,21 @@ xlog_unpack_data_checksum( | |||
3380 | xfs_caddr_t dp, | 3371 | xfs_caddr_t dp, |
3381 | xlog_t *log) | 3372 | xlog_t *log) |
3382 | { | 3373 | { |
3383 | uint *up = (uint *)dp; | 3374 | __be32 *up = (__be32 *)dp; |
3384 | uint chksum = 0; | 3375 | uint chksum = 0; |
3385 | int i; | 3376 | int i; |
3386 | 3377 | ||
3387 | /* divide length by 4 to get # words */ | 3378 | /* divide length by 4 to get # words */ |
3388 | for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) { | 3379 | for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) { |
3389 | chksum ^= INT_GET(*up, ARCH_CONVERT); | 3380 | chksum ^= be32_to_cpu(*up); |
3390 | up++; | 3381 | up++; |
3391 | } | 3382 | } |
3392 | if (chksum != INT_GET(rhead->h_chksum, ARCH_CONVERT)) { | 3383 | if (chksum != be32_to_cpu(rhead->h_chksum)) { |
3393 | if (rhead->h_chksum || | 3384 | if (rhead->h_chksum || |
3394 | ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { | 3385 | ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { |
3395 | cmn_err(CE_DEBUG, | 3386 | cmn_err(CE_DEBUG, |
3396 | "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n", | 3387 | "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n", |
3397 | INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); | 3388 | be32_to_cpu(rhead->h_chksum), chksum); |
3398 | cmn_err(CE_DEBUG, | 3389 | cmn_err(CE_DEBUG, |
3399 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); | 3390 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); |
3400 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3391 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { |
@@ -3418,18 +3409,18 @@ xlog_unpack_data( | |||
3418 | int i, j, k; | 3409 | int i, j, k; |
3419 | xlog_in_core_2_t *xhdr; | 3410 | xlog_in_core_2_t *xhdr; |
3420 | 3411 | ||
3421 | for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) && | 3412 | for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && |
3422 | i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { | 3413 | i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { |
3423 | *(uint *)dp = *(uint *)&rhead->h_cycle_data[i]; | 3414 | *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i]; |
3424 | dp += BBSIZE; | 3415 | dp += BBSIZE; |
3425 | } | 3416 | } |
3426 | 3417 | ||
3427 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3418 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { |
3428 | xhdr = (xlog_in_core_2_t *)rhead; | 3419 | xhdr = (xlog_in_core_2_t *)rhead; |
3429 | for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) { | 3420 | for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { |
3430 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3421 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3431 | k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3422 | k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
3432 | *(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k]; | 3423 | *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k]; |
3433 | dp += BBSIZE; | 3424 | dp += BBSIZE; |
3434 | } | 3425 | } |
3435 | } | 3426 | } |
@@ -3445,24 +3436,21 @@ xlog_valid_rec_header( | |||
3445 | { | 3436 | { |
3446 | int hlen; | 3437 | int hlen; |
3447 | 3438 | ||
3448 | if (unlikely( | 3439 | if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { |
3449 | (INT_GET(rhead->h_magicno, ARCH_CONVERT) != | ||
3450 | XLOG_HEADER_MAGIC_NUM))) { | ||
3451 | XFS_ERROR_REPORT("xlog_valid_rec_header(1)", | 3440 | XFS_ERROR_REPORT("xlog_valid_rec_header(1)", |
3452 | XFS_ERRLEVEL_LOW, log->l_mp); | 3441 | XFS_ERRLEVEL_LOW, log->l_mp); |
3453 | return XFS_ERROR(EFSCORRUPTED); | 3442 | return XFS_ERROR(EFSCORRUPTED); |
3454 | } | 3443 | } |
3455 | if (unlikely( | 3444 | if (unlikely( |
3456 | (!rhead->h_version || | 3445 | (!rhead->h_version || |
3457 | (INT_GET(rhead->h_version, ARCH_CONVERT) & | 3446 | (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { |
3458 | (~XLOG_VERSION_OKBITS)) != 0))) { | ||
3459 | xlog_warn("XFS: %s: unrecognised log version (%d).", | 3447 | xlog_warn("XFS: %s: unrecognised log version (%d).", |
3460 | __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT)); | 3448 | __FUNCTION__, be32_to_cpu(rhead->h_version)); |
3461 | return XFS_ERROR(EIO); | 3449 | return XFS_ERROR(EIO); |
3462 | } | 3450 | } |
3463 | 3451 | ||
3464 | /* LR body must have data or it wouldn't have been written */ | 3452 | /* LR body must have data or it wouldn't have been written */ |
3465 | hlen = INT_GET(rhead->h_len, ARCH_CONVERT); | 3453 | hlen = be32_to_cpu(rhead->h_len); |
3466 | if (unlikely( hlen <= 0 || hlen > INT_MAX )) { | 3454 | if (unlikely( hlen <= 0 || hlen > INT_MAX )) { |
3467 | XFS_ERROR_REPORT("xlog_valid_rec_header(2)", | 3455 | XFS_ERROR_REPORT("xlog_valid_rec_header(2)", |
3468 | XFS_ERRLEVEL_LOW, log->l_mp); | 3456 | XFS_ERRLEVEL_LOW, log->l_mp); |
@@ -3522,9 +3510,8 @@ xlog_do_recovery_pass( | |||
3522 | error = xlog_valid_rec_header(log, rhead, tail_blk); | 3510 | error = xlog_valid_rec_header(log, rhead, tail_blk); |
3523 | if (error) | 3511 | if (error) |
3524 | goto bread_err1; | 3512 | goto bread_err1; |
3525 | h_size = INT_GET(rhead->h_size, ARCH_CONVERT); | 3513 | h_size = be32_to_cpu(rhead->h_size); |
3526 | if ((INT_GET(rhead->h_version, ARCH_CONVERT) | 3514 | if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && |
3527 | & XLOG_VERSION_2) && | ||
3528 | (h_size > XLOG_HEADER_CYCLE_SIZE)) { | 3515 | (h_size > XLOG_HEADER_CYCLE_SIZE)) { |
3529 | hblks = h_size / XLOG_HEADER_CYCLE_SIZE; | 3516 | hblks = h_size / XLOG_HEADER_CYCLE_SIZE; |
3530 | if (h_size % XLOG_HEADER_CYCLE_SIZE) | 3517 | if (h_size % XLOG_HEADER_CYCLE_SIZE) |
@@ -3561,7 +3548,7 @@ xlog_do_recovery_pass( | |||
3561 | goto bread_err2; | 3548 | goto bread_err2; |
3562 | 3549 | ||
3563 | /* blocks in data section */ | 3550 | /* blocks in data section */ |
3564 | bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); | 3551 | bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); |
3565 | error = xlog_bread(log, blk_no + hblks, bblks, dbp); | 3552 | error = xlog_bread(log, blk_no + hblks, bblks, dbp); |
3566 | if (error) | 3553 | if (error) |
3567 | goto bread_err2; | 3554 | goto bread_err2; |
@@ -3636,7 +3623,7 @@ xlog_do_recovery_pass( | |||
3636 | if (error) | 3623 | if (error) |
3637 | goto bread_err2; | 3624 | goto bread_err2; |
3638 | 3625 | ||
3639 | bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); | 3626 | bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); |
3640 | blk_no += hblks; | 3627 | blk_no += hblks; |
3641 | 3628 | ||
3642 | /* Read in data for log record */ | 3629 | /* Read in data for log record */ |
@@ -3707,7 +3694,7 @@ xlog_do_recovery_pass( | |||
3707 | error = xlog_valid_rec_header(log, rhead, blk_no); | 3694 | error = xlog_valid_rec_header(log, rhead, blk_no); |
3708 | if (error) | 3695 | if (error) |
3709 | goto bread_err2; | 3696 | goto bread_err2; |
3710 | bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); | 3697 | bblks = (int)BTOBB(be32_to_cpu(rhead->h_len)); |
3711 | if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp))) | 3698 | if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp))) |
3712 | goto bread_err2; | 3699 | goto bread_err2; |
3713 | offset = xlog_align(log, blk_no+hblks, bblks, dbp); | 3700 | offset = xlog_align(log, blk_no+hblks, bblks, dbp); |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index ebdb76da527c..6409b3762995 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -136,15 +136,9 @@ xfs_mount_init(void) | |||
136 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; | 136 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; |
137 | } | 137 | } |
138 | 138 | ||
139 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); | 139 | spin_lock_init(&mp->m_sb_lock); |
140 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); | ||
141 | mutex_init(&mp->m_ilock); | 140 | mutex_init(&mp->m_ilock); |
142 | mutex_init(&mp->m_growlock); | 141 | mutex_init(&mp->m_growlock); |
143 | /* | ||
144 | * Initialize the AIL. | ||
145 | */ | ||
146 | xfs_trans_ail_init(mp); | ||
147 | |||
148 | atomic_set(&mp->m_active_trans, 0); | 142 | atomic_set(&mp->m_active_trans, 0); |
149 | 143 | ||
150 | return mp; | 144 | return mp; |
@@ -171,7 +165,7 @@ xfs_mount_free( | |||
171 | sizeof(xfs_perag_t) * mp->m_sb.sb_agcount); | 165 | sizeof(xfs_perag_t) * mp->m_sb.sb_agcount); |
172 | } | 166 | } |
173 | 167 | ||
174 | AIL_LOCK_DESTROY(&mp->m_ail_lock); | 168 | spinlock_destroy(&mp->m_ail_lock); |
175 | spinlock_destroy(&mp->m_sb_lock); | 169 | spinlock_destroy(&mp->m_sb_lock); |
176 | mutex_destroy(&mp->m_ilock); | 170 | mutex_destroy(&mp->m_ilock); |
177 | mutex_destroy(&mp->m_growlock); | 171 | mutex_destroy(&mp->m_growlock); |
@@ -616,7 +610,7 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) | |||
616 | int i; | 610 | int i; |
617 | 611 | ||
618 | mp->m_agfrotor = mp->m_agirotor = 0; | 612 | mp->m_agfrotor = mp->m_agirotor = 0; |
619 | spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock"); | 613 | spin_lock_init(&mp->m_agirotor_lock); |
620 | mp->m_maxagi = mp->m_sb.sb_agcount; | 614 | mp->m_maxagi = mp->m_sb.sb_agcount; |
621 | mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; | 615 | mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; |
622 | mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; | 616 | mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; |
@@ -696,7 +690,6 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
696 | uint64_t bfreelst = 0; | 690 | uint64_t bfreelst = 0; |
697 | uint64_t btree = 0; | 691 | uint64_t btree = 0; |
698 | int error; | 692 | int error; |
699 | int s; | ||
700 | 693 | ||
701 | for (index = 0; index < agcount; index++) { | 694 | for (index = 0; index < agcount; index++) { |
702 | /* | 695 | /* |
@@ -721,11 +714,11 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
721 | /* | 714 | /* |
722 | * Overwrite incore superblock counters with just-read data | 715 | * Overwrite incore superblock counters with just-read data |
723 | */ | 716 | */ |
724 | s = XFS_SB_LOCK(mp); | 717 | spin_lock(&mp->m_sb_lock); |
725 | sbp->sb_ifree = ifree; | 718 | sbp->sb_ifree = ifree; |
726 | sbp->sb_icount = ialloc; | 719 | sbp->sb_icount = ialloc; |
727 | sbp->sb_fdblocks = bfree + bfreelst + btree; | 720 | sbp->sb_fdblocks = bfree + bfreelst + btree; |
728 | XFS_SB_UNLOCK(mp, s); | 721 | spin_unlock(&mp->m_sb_lock); |
729 | 722 | ||
730 | /* Fixup the per-cpu counters as well. */ | 723 | /* Fixup the per-cpu counters as well. */ |
731 | xfs_icsb_reinit_counters(mp); | 724 | xfs_icsb_reinit_counters(mp); |
@@ -734,49 +727,13 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
734 | } | 727 | } |
735 | 728 | ||
736 | /* | 729 | /* |
737 | * xfs_mountfs | 730 | * Update alignment values based on mount options and sb values |
738 | * | ||
739 | * This function does the following on an initial mount of a file system: | ||
740 | * - reads the superblock from disk and init the mount struct | ||
741 | * - if we're a 32-bit kernel, do a size check on the superblock | ||
742 | * so we don't mount terabyte filesystems | ||
743 | * - init mount struct realtime fields | ||
744 | * - allocate inode hash table for fs | ||
745 | * - init directory manager | ||
746 | * - perform recovery and init the log manager | ||
747 | */ | 731 | */ |
748 | int | 732 | STATIC int |
749 | xfs_mountfs( | 733 | xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags) |
750 | xfs_mount_t *mp, | ||
751 | int mfsi_flags) | ||
752 | { | 734 | { |
753 | xfs_buf_t *bp; | ||
754 | xfs_sb_t *sbp = &(mp->m_sb); | 735 | xfs_sb_t *sbp = &(mp->m_sb); |
755 | xfs_inode_t *rip; | ||
756 | bhv_vnode_t *rvp = NULL; | ||
757 | int readio_log, writeio_log; | ||
758 | xfs_daddr_t d; | ||
759 | __uint64_t resblks; | ||
760 | __int64_t update_flags; | ||
761 | uint quotamount, quotaflags; | ||
762 | int agno; | ||
763 | int uuid_mounted = 0; | ||
764 | int error = 0; | ||
765 | 736 | ||
766 | if (mp->m_sb_bp == NULL) { | ||
767 | if ((error = xfs_readsb(mp, mfsi_flags))) { | ||
768 | return error; | ||
769 | } | ||
770 | } | ||
771 | xfs_mount_common(mp, sbp); | ||
772 | |||
773 | /* | ||
774 | * Check if sb_agblocks is aligned at stripe boundary | ||
775 | * If sb_agblocks is NOT aligned turn off m_dalign since | ||
776 | * allocator alignment is within an ag, therefore ag has | ||
777 | * to be aligned at stripe boundary. | ||
778 | */ | ||
779 | update_flags = 0LL; | ||
780 | if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) { | 737 | if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) { |
781 | /* | 738 | /* |
782 | * If stripe unit and stripe width are not multiples | 739 | * If stripe unit and stripe width are not multiples |
@@ -787,8 +744,7 @@ xfs_mountfs( | |||
787 | if (mp->m_flags & XFS_MOUNT_RETERR) { | 744 | if (mp->m_flags & XFS_MOUNT_RETERR) { |
788 | cmn_err(CE_WARN, | 745 | cmn_err(CE_WARN, |
789 | "XFS: alignment check 1 failed"); | 746 | "XFS: alignment check 1 failed"); |
790 | error = XFS_ERROR(EINVAL); | 747 | return XFS_ERROR(EINVAL); |
791 | goto error1; | ||
792 | } | 748 | } |
793 | mp->m_dalign = mp->m_swidth = 0; | 749 | mp->m_dalign = mp->m_swidth = 0; |
794 | } else { | 750 | } else { |
@@ -798,8 +754,7 @@ xfs_mountfs( | |||
798 | mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); | 754 | mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); |
799 | if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { | 755 | if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { |
800 | if (mp->m_flags & XFS_MOUNT_RETERR) { | 756 | if (mp->m_flags & XFS_MOUNT_RETERR) { |
801 | error = XFS_ERROR(EINVAL); | 757 | return XFS_ERROR(EINVAL); |
802 | goto error1; | ||
803 | } | 758 | } |
804 | xfs_fs_cmn_err(CE_WARN, mp, | 759 | xfs_fs_cmn_err(CE_WARN, mp, |
805 | "stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)", | 760 | "stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)", |
@@ -816,8 +771,7 @@ xfs_mountfs( | |||
816 | "stripe alignment turned off: sunit(%d) less than bsize(%d)", | 771 | "stripe alignment turned off: sunit(%d) less than bsize(%d)", |
817 | mp->m_dalign, | 772 | mp->m_dalign, |
818 | mp->m_blockmask +1); | 773 | mp->m_blockmask +1); |
819 | error = XFS_ERROR(EINVAL); | 774 | return XFS_ERROR(EINVAL); |
820 | goto error1; | ||
821 | } | 775 | } |
822 | mp->m_swidth = 0; | 776 | mp->m_swidth = 0; |
823 | } | 777 | } |
@@ -830,11 +784,11 @@ xfs_mountfs( | |||
830 | if (XFS_SB_VERSION_HASDALIGN(sbp)) { | 784 | if (XFS_SB_VERSION_HASDALIGN(sbp)) { |
831 | if (sbp->sb_unit != mp->m_dalign) { | 785 | if (sbp->sb_unit != mp->m_dalign) { |
832 | sbp->sb_unit = mp->m_dalign; | 786 | sbp->sb_unit = mp->m_dalign; |
833 | update_flags |= XFS_SB_UNIT; | 787 | *update_flags |= XFS_SB_UNIT; |
834 | } | 788 | } |
835 | if (sbp->sb_width != mp->m_swidth) { | 789 | if (sbp->sb_width != mp->m_swidth) { |
836 | sbp->sb_width = mp->m_swidth; | 790 | sbp->sb_width = mp->m_swidth; |
837 | update_flags |= XFS_SB_WIDTH; | 791 | *update_flags |= XFS_SB_WIDTH; |
838 | } | 792 | } |
839 | } | 793 | } |
840 | } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && | 794 | } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && |
@@ -843,49 +797,45 @@ xfs_mountfs( | |||
843 | mp->m_swidth = sbp->sb_width; | 797 | mp->m_swidth = sbp->sb_width; |
844 | } | 798 | } |
845 | 799 | ||
846 | xfs_alloc_compute_maxlevels(mp); | 800 | return 0; |
847 | xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); | 801 | } |
848 | xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); | ||
849 | xfs_ialloc_compute_maxlevels(mp); | ||
850 | 802 | ||
851 | if (sbp->sb_imax_pct) { | 803 | /* |
852 | __uint64_t icount; | 804 | * Set the maximum inode count for this filesystem |
805 | */ | ||
806 | STATIC void | ||
807 | xfs_set_maxicount(xfs_mount_t *mp) | ||
808 | { | ||
809 | xfs_sb_t *sbp = &(mp->m_sb); | ||
810 | __uint64_t icount; | ||
853 | 811 | ||
854 | /* Make sure the maximum inode count is a multiple of the | 812 | if (sbp->sb_imax_pct) { |
855 | * units we allocate inodes in. | 813 | /* |
814 | * Make sure the maximum inode count is a multiple | ||
815 | * of the units we allocate inodes in. | ||
856 | */ | 816 | */ |
857 | |||
858 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; | 817 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; |
859 | do_div(icount, 100); | 818 | do_div(icount, 100); |
860 | do_div(icount, mp->m_ialloc_blks); | 819 | do_div(icount, mp->m_ialloc_blks); |
861 | mp->m_maxicount = (icount * mp->m_ialloc_blks) << | 820 | mp->m_maxicount = (icount * mp->m_ialloc_blks) << |
862 | sbp->sb_inopblog; | 821 | sbp->sb_inopblog; |
863 | } else | 822 | } else { |
864 | mp->m_maxicount = 0; | 823 | mp->m_maxicount = 0; |
865 | |||
866 | mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); | ||
867 | |||
868 | /* | ||
869 | * XFS uses the uuid from the superblock as the unique | ||
870 | * identifier for fsid. We can not use the uuid from the volume | ||
871 | * since a single partition filesystem is identical to a single | ||
872 | * partition volume/filesystem. | ||
873 | */ | ||
874 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | ||
875 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | ||
876 | if (xfs_uuid_mount(mp)) { | ||
877 | error = XFS_ERROR(EINVAL); | ||
878 | goto error1; | ||
879 | } | ||
880 | uuid_mounted=1; | ||
881 | } | 824 | } |
825 | } | ||
826 | |||
827 | /* | ||
828 | * Set the default minimum read and write sizes unless | ||
829 | * already specified in a mount option. | ||
830 | * We use smaller I/O sizes when the file system | ||
831 | * is being used for NFS service (wsync mount option). | ||
832 | */ | ||
833 | STATIC void | ||
834 | xfs_set_rw_sizes(xfs_mount_t *mp) | ||
835 | { | ||
836 | xfs_sb_t *sbp = &(mp->m_sb); | ||
837 | int readio_log, writeio_log; | ||
882 | 838 | ||
883 | /* | ||
884 | * Set the default minimum read and write sizes unless | ||
885 | * already specified in a mount option. | ||
886 | * We use smaller I/O sizes when the file system | ||
887 | * is being used for NFS service (wsync mount option). | ||
888 | */ | ||
889 | if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) { | 839 | if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) { |
890 | if (mp->m_flags & XFS_MOUNT_WSYNC) { | 840 | if (mp->m_flags & XFS_MOUNT_WSYNC) { |
891 | readio_log = XFS_WSYNC_READIO_LOG; | 841 | readio_log = XFS_WSYNC_READIO_LOG; |
@@ -911,17 +861,14 @@ xfs_mountfs( | |||
911 | mp->m_writeio_log = writeio_log; | 861 | mp->m_writeio_log = writeio_log; |
912 | } | 862 | } |
913 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); | 863 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); |
864 | } | ||
914 | 865 | ||
915 | /* | 866 | /* |
916 | * Set the inode cluster size. | 867 | * Set whether we're using inode alignment. |
917 | * This may still be overridden by the file system | 868 | */ |
918 | * block size if it is larger than the chosen cluster size. | 869 | STATIC void |
919 | */ | 870 | xfs_set_inoalignment(xfs_mount_t *mp) |
920 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; | 871 | { |
921 | |||
922 | /* | ||
923 | * Set whether we're using inode alignment. | ||
924 | */ | ||
925 | if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && | 872 | if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && |
926 | mp->m_sb.sb_inoalignmt >= | 873 | mp->m_sb.sb_inoalignmt >= |
927 | XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) | 874 | XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) |
@@ -937,14 +884,22 @@ xfs_mountfs( | |||
937 | mp->m_sinoalign = mp->m_dalign; | 884 | mp->m_sinoalign = mp->m_dalign; |
938 | else | 885 | else |
939 | mp->m_sinoalign = 0; | 886 | mp->m_sinoalign = 0; |
940 | /* | 887 | } |
941 | * Check that the data (and log if separate) are an ok size. | 888 | |
942 | */ | 889 | /* |
890 | * Check that the data (and log if separate) are an ok size. | ||
891 | */ | ||
892 | STATIC int | ||
893 | xfs_check_sizes(xfs_mount_t *mp, int mfsi_flags) | ||
894 | { | ||
895 | xfs_buf_t *bp; | ||
896 | xfs_daddr_t d; | ||
897 | int error; | ||
898 | |||
943 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); | 899 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); |
944 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { | 900 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { |
945 | cmn_err(CE_WARN, "XFS: size check 1 failed"); | 901 | cmn_err(CE_WARN, "XFS: size check 1 failed"); |
946 | error = XFS_ERROR(E2BIG); | 902 | return XFS_ERROR(E2BIG); |
947 | goto error1; | ||
948 | } | 903 | } |
949 | error = xfs_read_buf(mp, mp->m_ddev_targp, | 904 | error = xfs_read_buf(mp, mp->m_ddev_targp, |
950 | d - XFS_FSS_TO_BB(mp, 1), | 905 | d - XFS_FSS_TO_BB(mp, 1), |
@@ -953,10 +908,9 @@ xfs_mountfs( | |||
953 | xfs_buf_relse(bp); | 908 | xfs_buf_relse(bp); |
954 | } else { | 909 | } else { |
955 | cmn_err(CE_WARN, "XFS: size check 2 failed"); | 910 | cmn_err(CE_WARN, "XFS: size check 2 failed"); |
956 | if (error == ENOSPC) { | 911 | if (error == ENOSPC) |
957 | error = XFS_ERROR(E2BIG); | 912 | error = XFS_ERROR(E2BIG); |
958 | } | 913 | return error; |
959 | goto error1; | ||
960 | } | 914 | } |
961 | 915 | ||
962 | if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) && | 916 | if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) && |
@@ -964,8 +918,7 @@ xfs_mountfs( | |||
964 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); | 918 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); |
965 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { | 919 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { |
966 | cmn_err(CE_WARN, "XFS: size check 3 failed"); | 920 | cmn_err(CE_WARN, "XFS: size check 3 failed"); |
967 | error = XFS_ERROR(E2BIG); | 921 | return XFS_ERROR(E2BIG); |
968 | goto error1; | ||
969 | } | 922 | } |
970 | error = xfs_read_buf(mp, mp->m_logdev_targp, | 923 | error = xfs_read_buf(mp, mp->m_logdev_targp, |
971 | d - XFS_FSB_TO_BB(mp, 1), | 924 | d - XFS_FSB_TO_BB(mp, 1), |
@@ -974,17 +927,111 @@ xfs_mountfs( | |||
974 | xfs_buf_relse(bp); | 927 | xfs_buf_relse(bp); |
975 | } else { | 928 | } else { |
976 | cmn_err(CE_WARN, "XFS: size check 3 failed"); | 929 | cmn_err(CE_WARN, "XFS: size check 3 failed"); |
977 | if (error == ENOSPC) { | 930 | if (error == ENOSPC) |
978 | error = XFS_ERROR(E2BIG); | 931 | error = XFS_ERROR(E2BIG); |
979 | } | 932 | return error; |
933 | } | ||
934 | } | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * xfs_mountfs | ||
940 | * | ||
941 | * This function does the following on an initial mount of a file system: | ||
942 | * - reads the superblock from disk and init the mount struct | ||
943 | * - if we're a 32-bit kernel, do a size check on the superblock | ||
944 | * so we don't mount terabyte filesystems | ||
945 | * - init mount struct realtime fields | ||
946 | * - allocate inode hash table for fs | ||
947 | * - init directory manager | ||
948 | * - perform recovery and init the log manager | ||
949 | */ | ||
950 | int | ||
951 | xfs_mountfs( | ||
952 | xfs_mount_t *mp, | ||
953 | int mfsi_flags) | ||
954 | { | ||
955 | xfs_sb_t *sbp = &(mp->m_sb); | ||
956 | xfs_inode_t *rip; | ||
957 | bhv_vnode_t *rvp = NULL; | ||
958 | __uint64_t resblks; | ||
959 | __int64_t update_flags = 0LL; | ||
960 | uint quotamount, quotaflags; | ||
961 | int agno; | ||
962 | int uuid_mounted = 0; | ||
963 | int error = 0; | ||
964 | |||
965 | if (mp->m_sb_bp == NULL) { | ||
966 | error = xfs_readsb(mp, mfsi_flags); | ||
967 | if (error) | ||
968 | return error; | ||
969 | } | ||
970 | xfs_mount_common(mp, sbp); | ||
971 | |||
972 | /* | ||
973 | * Check if sb_agblocks is aligned at stripe boundary | ||
974 | * If sb_agblocks is NOT aligned turn off m_dalign since | ||
975 | * allocator alignment is within an ag, therefore ag has | ||
976 | * to be aligned at stripe boundary. | ||
977 | */ | ||
978 | error = xfs_update_alignment(mp, mfsi_flags, &update_flags); | ||
979 | if (error) | ||
980 | goto error1; | ||
981 | |||
982 | xfs_alloc_compute_maxlevels(mp); | ||
983 | xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); | ||
984 | xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); | ||
985 | xfs_ialloc_compute_maxlevels(mp); | ||
986 | |||
987 | xfs_set_maxicount(mp); | ||
988 | |||
989 | mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); | ||
990 | |||
991 | /* | ||
992 | * XFS uses the uuid from the superblock as the unique | ||
993 | * identifier for fsid. We can not use the uuid from the volume | ||
994 | * since a single partition filesystem is identical to a single | ||
995 | * partition volume/filesystem. | ||
996 | */ | ||
997 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | ||
998 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | ||
999 | if (xfs_uuid_mount(mp)) { | ||
1000 | error = XFS_ERROR(EINVAL); | ||
980 | goto error1; | 1001 | goto error1; |
981 | } | 1002 | } |
1003 | uuid_mounted=1; | ||
982 | } | 1004 | } |
983 | 1005 | ||
984 | /* | 1006 | /* |
1007 | * Set the minimum read and write sizes | ||
1008 | */ | ||
1009 | xfs_set_rw_sizes(mp); | ||
1010 | |||
1011 | /* | ||
1012 | * Set the inode cluster size. | ||
1013 | * This may still be overridden by the file system | ||
1014 | * block size if it is larger than the chosen cluster size. | ||
1015 | */ | ||
1016 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; | ||
1017 | |||
1018 | /* | ||
1019 | * Set inode alignment fields | ||
1020 | */ | ||
1021 | xfs_set_inoalignment(mp); | ||
1022 | |||
1023 | /* | ||
1024 | * Check that the data (and log if separate) are an ok size. | ||
1025 | */ | ||
1026 | error = xfs_check_sizes(mp, mfsi_flags); | ||
1027 | if (error) | ||
1028 | goto error1; | ||
1029 | |||
1030 | /* | ||
985 | * Initialize realtime fields in the mount structure | 1031 | * Initialize realtime fields in the mount structure |
986 | */ | 1032 | */ |
987 | if ((error = xfs_rtmount_init(mp))) { | 1033 | error = xfs_rtmount_init(mp); |
1034 | if (error) { | ||
988 | cmn_err(CE_WARN, "XFS: RT mount failed"); | 1035 | cmn_err(CE_WARN, "XFS: RT mount failed"); |
989 | goto error1; | 1036 | goto error1; |
990 | } | 1037 | } |
@@ -1102,7 +1149,8 @@ xfs_mountfs( | |||
1102 | /* | 1149 | /* |
1103 | * Initialize realtime inode pointers in the mount structure | 1150 | * Initialize realtime inode pointers in the mount structure |
1104 | */ | 1151 | */ |
1105 | if ((error = xfs_rtmount_inodes(mp))) { | 1152 | error = xfs_rtmount_inodes(mp); |
1153 | if (error) { | ||
1106 | /* | 1154 | /* |
1107 | * Free up the root inode. | 1155 | * Free up the root inode. |
1108 | */ | 1156 | */ |
@@ -1120,7 +1168,8 @@ xfs_mountfs( | |||
1120 | /* | 1168 | /* |
1121 | * Initialise the XFS quota management subsystem for this mount | 1169 | * Initialise the XFS quota management subsystem for this mount |
1122 | */ | 1170 | */ |
1123 | if ((error = XFS_QM_INIT(mp, "amount, "aflags))) | 1171 | error = XFS_QM_INIT(mp, "amount, "aflags); |
1172 | if (error) | ||
1124 | goto error4; | 1173 | goto error4; |
1125 | 1174 | ||
1126 | /* | 1175 | /* |
@@ -1137,7 +1186,8 @@ xfs_mountfs( | |||
1137 | /* | 1186 | /* |
1138 | * Complete the quota initialisation, post-log-replay component. | 1187 | * Complete the quota initialisation, post-log-replay component. |
1139 | */ | 1188 | */ |
1140 | if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags))) | 1189 | error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags); |
1190 | if (error) | ||
1141 | goto error4; | 1191 | goto error4; |
1142 | 1192 | ||
1143 | /* | 1193 | /* |
@@ -1255,7 +1305,6 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1255 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1305 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1256 | xfs_errortag_clearall(mp, 0); | 1306 | xfs_errortag_clearall(mp, 0); |
1257 | #endif | 1307 | #endif |
1258 | XFS_IODONE(mp); | ||
1259 | xfs_mount_free(mp); | 1308 | xfs_mount_free(mp); |
1260 | return 0; | 1309 | return 0; |
1261 | } | 1310 | } |
@@ -1441,7 +1490,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1441 | * Fields are not allowed to dip below zero, so if the delta would | 1490 | * Fields are not allowed to dip below zero, so if the delta would |
1442 | * do this do not apply it and return EINVAL. | 1491 | * do this do not apply it and return EINVAL. |
1443 | * | 1492 | * |
1444 | * The SB_LOCK must be held when this routine is called. | 1493 | * The m_sb_lock must be held when this routine is called. |
1445 | */ | 1494 | */ |
1446 | int | 1495 | int |
1447 | xfs_mod_incore_sb_unlocked( | 1496 | xfs_mod_incore_sb_unlocked( |
@@ -1606,7 +1655,7 @@ xfs_mod_incore_sb_unlocked( | |||
1606 | /* | 1655 | /* |
1607 | * xfs_mod_incore_sb() is used to change a field in the in-core | 1656 | * xfs_mod_incore_sb() is used to change a field in the in-core |
1608 | * superblock structure by the specified delta. This modification | 1657 | * superblock structure by the specified delta. This modification |
1609 | * is protected by the SB_LOCK. Just use the xfs_mod_incore_sb_unlocked() | 1658 | * is protected by the m_sb_lock. Just use the xfs_mod_incore_sb_unlocked() |
1610 | * routine to do the work. | 1659 | * routine to do the work. |
1611 | */ | 1660 | */ |
1612 | int | 1661 | int |
@@ -1616,7 +1665,6 @@ xfs_mod_incore_sb( | |||
1616 | int64_t delta, | 1665 | int64_t delta, |
1617 | int rsvd) | 1666 | int rsvd) |
1618 | { | 1667 | { |
1619 | unsigned long s; | ||
1620 | int status; | 1668 | int status; |
1621 | 1669 | ||
1622 | /* check for per-cpu counters */ | 1670 | /* check for per-cpu counters */ |
@@ -1633,9 +1681,9 @@ xfs_mod_incore_sb( | |||
1633 | /* FALLTHROUGH */ | 1681 | /* FALLTHROUGH */ |
1634 | #endif | 1682 | #endif |
1635 | default: | 1683 | default: |
1636 | s = XFS_SB_LOCK(mp); | 1684 | spin_lock(&mp->m_sb_lock); |
1637 | status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); | 1685 | status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); |
1638 | XFS_SB_UNLOCK(mp, s); | 1686 | spin_unlock(&mp->m_sb_lock); |
1639 | break; | 1687 | break; |
1640 | } | 1688 | } |
1641 | 1689 | ||
@@ -1656,7 +1704,6 @@ xfs_mod_incore_sb( | |||
1656 | int | 1704 | int |
1657 | xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | 1705 | xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) |
1658 | { | 1706 | { |
1659 | unsigned long s; | ||
1660 | int status=0; | 1707 | int status=0; |
1661 | xfs_mod_sb_t *msbp; | 1708 | xfs_mod_sb_t *msbp; |
1662 | 1709 | ||
@@ -1664,10 +1711,10 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1664 | * Loop through the array of mod structures and apply each | 1711 | * Loop through the array of mod structures and apply each |
1665 | * individually. If any fail, then back out all those | 1712 | * individually. If any fail, then back out all those |
1666 | * which have already been applied. Do all of this within | 1713 | * which have already been applied. Do all of this within |
1667 | * the scope of the SB_LOCK so that all of the changes will | 1714 | * the scope of the m_sb_lock so that all of the changes will |
1668 | * be atomic. | 1715 | * be atomic. |
1669 | */ | 1716 | */ |
1670 | s = XFS_SB_LOCK(mp); | 1717 | spin_lock(&mp->m_sb_lock); |
1671 | msbp = &msb[0]; | 1718 | msbp = &msb[0]; |
1672 | for (msbp = &msbp[0]; msbp < (msb + nmsb); msbp++) { | 1719 | for (msbp = &msbp[0]; msbp < (msb + nmsb); msbp++) { |
1673 | /* | 1720 | /* |
@@ -1681,11 +1728,11 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1681 | case XFS_SBS_IFREE: | 1728 | case XFS_SBS_IFREE: |
1682 | case XFS_SBS_FDBLOCKS: | 1729 | case XFS_SBS_FDBLOCKS: |
1683 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { | 1730 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { |
1684 | XFS_SB_UNLOCK(mp, s); | 1731 | spin_unlock(&mp->m_sb_lock); |
1685 | status = xfs_icsb_modify_counters(mp, | 1732 | status = xfs_icsb_modify_counters(mp, |
1686 | msbp->msb_field, | 1733 | msbp->msb_field, |
1687 | msbp->msb_delta, rsvd); | 1734 | msbp->msb_delta, rsvd); |
1688 | s = XFS_SB_LOCK(mp); | 1735 | spin_lock(&mp->m_sb_lock); |
1689 | break; | 1736 | break; |
1690 | } | 1737 | } |
1691 | /* FALLTHROUGH */ | 1738 | /* FALLTHROUGH */ |
@@ -1719,12 +1766,12 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1719 | case XFS_SBS_IFREE: | 1766 | case XFS_SBS_IFREE: |
1720 | case XFS_SBS_FDBLOCKS: | 1767 | case XFS_SBS_FDBLOCKS: |
1721 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { | 1768 | if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) { |
1722 | XFS_SB_UNLOCK(mp, s); | 1769 | spin_unlock(&mp->m_sb_lock); |
1723 | status = xfs_icsb_modify_counters(mp, | 1770 | status = xfs_icsb_modify_counters(mp, |
1724 | msbp->msb_field, | 1771 | msbp->msb_field, |
1725 | -(msbp->msb_delta), | 1772 | -(msbp->msb_delta), |
1726 | rsvd); | 1773 | rsvd); |
1727 | s = XFS_SB_LOCK(mp); | 1774 | spin_lock(&mp->m_sb_lock); |
1728 | break; | 1775 | break; |
1729 | } | 1776 | } |
1730 | /* FALLTHROUGH */ | 1777 | /* FALLTHROUGH */ |
@@ -1740,7 +1787,7 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) | |||
1740 | msbp--; | 1787 | msbp--; |
1741 | } | 1788 | } |
1742 | } | 1789 | } |
1743 | XFS_SB_UNLOCK(mp, s); | 1790 | spin_unlock(&mp->m_sb_lock); |
1744 | return status; | 1791 | return status; |
1745 | } | 1792 | } |
1746 | 1793 | ||
@@ -1888,12 +1935,12 @@ xfs_mount_log_sbunit( | |||
1888 | * | 1935 | * |
1889 | * Locking rules: | 1936 | * Locking rules: |
1890 | * | 1937 | * |
1891 | * 1. XFS_SB_LOCK() before picking up per-cpu locks | 1938 | * 1. m_sb_lock before picking up per-cpu locks |
1892 | * 2. per-cpu locks always picked up via for_each_online_cpu() order | 1939 | * 2. per-cpu locks always picked up via for_each_online_cpu() order |
1893 | * 3. accurate counter sync requires XFS_SB_LOCK + per cpu locks | 1940 | * 3. accurate counter sync requires m_sb_lock + per cpu locks |
1894 | * 4. modifying per-cpu counters requires holding per-cpu lock | 1941 | * 4. modifying per-cpu counters requires holding per-cpu lock |
1895 | * 5. modifying global counters requires holding XFS_SB_LOCK | 1942 | * 5. modifying global counters requires holding m_sb_lock |
1896 | * 6. enabling or disabling a counter requires holding the XFS_SB_LOCK | 1943 | * 6. enabling or disabling a counter requires holding the m_sb_lock |
1897 | * and _none_ of the per-cpu locks. | 1944 | * and _none_ of the per-cpu locks. |
1898 | * | 1945 | * |
1899 | * Disabled counters are only ever re-enabled by a balance operation | 1946 | * Disabled counters are only ever re-enabled by a balance operation |
@@ -1920,7 +1967,6 @@ xfs_icsb_cpu_notify( | |||
1920 | { | 1967 | { |
1921 | xfs_icsb_cnts_t *cntp; | 1968 | xfs_icsb_cnts_t *cntp; |
1922 | xfs_mount_t *mp; | 1969 | xfs_mount_t *mp; |
1923 | int s; | ||
1924 | 1970 | ||
1925 | mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier); | 1971 | mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier); |
1926 | cntp = (xfs_icsb_cnts_t *) | 1972 | cntp = (xfs_icsb_cnts_t *) |
@@ -1946,7 +1992,7 @@ xfs_icsb_cpu_notify( | |||
1946 | * count into the total on the global superblock and | 1992 | * count into the total on the global superblock and |
1947 | * re-enable the counters. */ | 1993 | * re-enable the counters. */ |
1948 | xfs_icsb_lock(mp); | 1994 | xfs_icsb_lock(mp); |
1949 | s = XFS_SB_LOCK(mp); | 1995 | spin_lock(&mp->m_sb_lock); |
1950 | xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT); | 1996 | xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT); |
1951 | xfs_icsb_disable_counter(mp, XFS_SBS_IFREE); | 1997 | xfs_icsb_disable_counter(mp, XFS_SBS_IFREE); |
1952 | xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS); | 1998 | xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS); |
@@ -1963,7 +2009,7 @@ xfs_icsb_cpu_notify( | |||
1963 | XFS_ICSB_SB_LOCKED, 0); | 2009 | XFS_ICSB_SB_LOCKED, 0); |
1964 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, | 2010 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, |
1965 | XFS_ICSB_SB_LOCKED, 0); | 2011 | XFS_ICSB_SB_LOCKED, 0); |
1966 | XFS_SB_UNLOCK(mp, s); | 2012 | spin_unlock(&mp->m_sb_lock); |
1967 | xfs_icsb_unlock(mp); | 2013 | xfs_icsb_unlock(mp); |
1968 | break; | 2014 | break; |
1969 | } | 2015 | } |
@@ -2194,11 +2240,10 @@ xfs_icsb_sync_counters_flags( | |||
2194 | int flags) | 2240 | int flags) |
2195 | { | 2241 | { |
2196 | xfs_icsb_cnts_t cnt; | 2242 | xfs_icsb_cnts_t cnt; |
2197 | int s; | ||
2198 | 2243 | ||
2199 | /* Pass 1: lock all counters */ | 2244 | /* Pass 1: lock all counters */ |
2200 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | 2245 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) |
2201 | s = XFS_SB_LOCK(mp); | 2246 | spin_lock(&mp->m_sb_lock); |
2202 | 2247 | ||
2203 | xfs_icsb_count(mp, &cnt, flags); | 2248 | xfs_icsb_count(mp, &cnt, flags); |
2204 | 2249 | ||
@@ -2211,7 +2256,7 @@ xfs_icsb_sync_counters_flags( | |||
2211 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; | 2256 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; |
2212 | 2257 | ||
2213 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | 2258 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) |
2214 | XFS_SB_UNLOCK(mp, s); | 2259 | spin_unlock(&mp->m_sb_lock); |
2215 | } | 2260 | } |
2216 | 2261 | ||
2217 | /* | 2262 | /* |
@@ -2252,11 +2297,10 @@ xfs_icsb_balance_counter( | |||
2252 | { | 2297 | { |
2253 | uint64_t count, resid; | 2298 | uint64_t count, resid; |
2254 | int weight = num_online_cpus(); | 2299 | int weight = num_online_cpus(); |
2255 | int s; | ||
2256 | uint64_t min = (uint64_t)min_per_cpu; | 2300 | uint64_t min = (uint64_t)min_per_cpu; |
2257 | 2301 | ||
2258 | if (!(flags & XFS_ICSB_SB_LOCKED)) | 2302 | if (!(flags & XFS_ICSB_SB_LOCKED)) |
2259 | s = XFS_SB_LOCK(mp); | 2303 | spin_lock(&mp->m_sb_lock); |
2260 | 2304 | ||
2261 | /* disable counter and sync counter */ | 2305 | /* disable counter and sync counter */ |
2262 | xfs_icsb_disable_counter(mp, field); | 2306 | xfs_icsb_disable_counter(mp, field); |
@@ -2290,10 +2334,10 @@ xfs_icsb_balance_counter( | |||
2290 | xfs_icsb_enable_counter(mp, field, count, resid); | 2334 | xfs_icsb_enable_counter(mp, field, count, resid); |
2291 | out: | 2335 | out: |
2292 | if (!(flags & XFS_ICSB_SB_LOCKED)) | 2336 | if (!(flags & XFS_ICSB_SB_LOCKED)) |
2293 | XFS_SB_UNLOCK(mp, s); | 2337 | spin_unlock(&mp->m_sb_lock); |
2294 | } | 2338 | } |
2295 | 2339 | ||
2296 | int | 2340 | STATIC int |
2297 | xfs_icsb_modify_counters( | 2341 | xfs_icsb_modify_counters( |
2298 | xfs_mount_t *mp, | 2342 | xfs_mount_t *mp, |
2299 | xfs_sb_field_t field, | 2343 | xfs_sb_field_t field, |
@@ -2302,7 +2346,7 @@ xfs_icsb_modify_counters( | |||
2302 | { | 2346 | { |
2303 | xfs_icsb_cnts_t *icsbp; | 2347 | xfs_icsb_cnts_t *icsbp; |
2304 | long long lcounter; /* long counter for 64 bit fields */ | 2348 | long long lcounter; /* long counter for 64 bit fields */ |
2305 | int cpu, ret = 0, s; | 2349 | int cpu, ret = 0; |
2306 | 2350 | ||
2307 | might_sleep(); | 2351 | might_sleep(); |
2308 | again: | 2352 | again: |
@@ -2380,15 +2424,15 @@ slow_path: | |||
2380 | * running atomically here, we know a rebalance cannot | 2424 | * running atomically here, we know a rebalance cannot |
2381 | * be in progress. Hence we can go straight to operating | 2425 | * be in progress. Hence we can go straight to operating |
2382 | * on the global superblock. We do not call xfs_mod_incore_sb() | 2426 | * on the global superblock. We do not call xfs_mod_incore_sb() |
2383 | * here even though we need to get the SB_LOCK. Doing so | 2427 | * here even though we need to get the m_sb_lock. Doing so |
2384 | * will cause us to re-enter this function and deadlock. | 2428 | * will cause us to re-enter this function and deadlock. |
2385 | * Hence we get the SB_LOCK ourselves and then call | 2429 | * Hence we get the m_sb_lock ourselves and then call |
2386 | * xfs_mod_incore_sb_unlocked() as the unlocked path operates | 2430 | * xfs_mod_incore_sb_unlocked() as the unlocked path operates |
2387 | * directly on the global counters. | 2431 | * directly on the global counters. |
2388 | */ | 2432 | */ |
2389 | s = XFS_SB_LOCK(mp); | 2433 | spin_lock(&mp->m_sb_lock); |
2390 | ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); | 2434 | ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd); |
2391 | XFS_SB_UNLOCK(mp, s); | 2435 | spin_unlock(&mp->m_sb_lock); |
2392 | 2436 | ||
2393 | /* | 2437 | /* |
2394 | * Now that we've modified the global superblock, we | 2438 | * Now that we've modified the global superblock, we |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index c618f7cb5f0e..f7c620ec6e69 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -56,20 +56,12 @@ struct cred; | |||
56 | struct log; | 56 | struct log; |
57 | struct xfs_mount_args; | 57 | struct xfs_mount_args; |
58 | struct xfs_inode; | 58 | struct xfs_inode; |
59 | struct xfs_iocore; | ||
60 | struct xfs_bmbt_irec; | 59 | struct xfs_bmbt_irec; |
61 | struct xfs_bmap_free; | 60 | struct xfs_bmap_free; |
62 | struct xfs_extdelta; | 61 | struct xfs_extdelta; |
63 | struct xfs_swapext; | 62 | struct xfs_swapext; |
64 | struct xfs_mru_cache; | 63 | struct xfs_mru_cache; |
65 | 64 | ||
66 | #define AIL_LOCK_T lock_t | ||
67 | #define AIL_LOCKINIT(x,y) spinlock_init(x,y) | ||
68 | #define AIL_LOCK_DESTROY(x) spinlock_destroy(x) | ||
69 | #define AIL_LOCK(mp,s) s=mutex_spinlock(&(mp)->m_ail_lock) | ||
70 | #define AIL_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_ail_lock, s) | ||
71 | |||
72 | |||
73 | /* | 65 | /* |
74 | * Prototypes and functions for the Data Migration subsystem. | 66 | * Prototypes and functions for the Data Migration subsystem. |
75 | */ | 67 | */ |
@@ -196,105 +188,6 @@ typedef struct xfs_qmops { | |||
196 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ | 188 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ |
197 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) | 189 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) |
198 | 190 | ||
199 | |||
200 | /* | ||
201 | * Prototypes and functions for I/O core modularization. | ||
202 | */ | ||
203 | |||
204 | typedef int (*xfs_ioinit_t)(struct xfs_mount *, | ||
205 | struct xfs_mount_args *, int); | ||
206 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, | ||
207 | xfs_fileoff_t, xfs_filblks_t, int, | ||
208 | xfs_fsblock_t *, xfs_extlen_t, | ||
209 | struct xfs_bmbt_irec *, int *, | ||
210 | struct xfs_bmap_free *, struct xfs_extdelta *); | ||
211 | typedef int (*xfs_bunmapi_t)(struct xfs_trans *, | ||
212 | void *, xfs_fileoff_t, | ||
213 | xfs_filblks_t, int, xfs_extnum_t, | ||
214 | xfs_fsblock_t *, struct xfs_bmap_free *, | ||
215 | struct xfs_extdelta *, int *); | ||
216 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); | ||
217 | typedef int (*xfs_iomap_write_direct_t)( | ||
218 | void *, xfs_off_t, size_t, int, | ||
219 | struct xfs_bmbt_irec *, int *, int); | ||
220 | typedef int (*xfs_iomap_write_delay_t)( | ||
221 | void *, xfs_off_t, size_t, int, | ||
222 | struct xfs_bmbt_irec *, int *); | ||
223 | typedef int (*xfs_iomap_write_allocate_t)( | ||
224 | void *, xfs_off_t, size_t, | ||
225 | struct xfs_bmbt_irec *, int *); | ||
226 | typedef int (*xfs_iomap_write_unwritten_t)( | ||
227 | void *, xfs_off_t, size_t); | ||
228 | typedef uint (*xfs_lck_map_shared_t)(void *); | ||
229 | typedef void (*xfs_lock_t)(void *, uint); | ||
230 | typedef void (*xfs_lock_demote_t)(void *, uint); | ||
231 | typedef int (*xfs_lock_nowait_t)(void *, uint); | ||
232 | typedef void (*xfs_unlk_t)(void *, unsigned int); | ||
233 | typedef xfs_fsize_t (*xfs_size_t)(void *); | ||
234 | typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_mount *); | ||
235 | typedef int (*xfs_swap_extents_t)(void *, void *, | ||
236 | struct xfs_swapext*); | ||
237 | |||
238 | typedef struct xfs_ioops { | ||
239 | xfs_ioinit_t xfs_ioinit; | ||
240 | xfs_bmapi_t xfs_bmapi_func; | ||
241 | xfs_bunmapi_t xfs_bunmapi_func; | ||
242 | xfs_bmap_eof_t xfs_bmap_eof_func; | ||
243 | xfs_iomap_write_direct_t xfs_iomap_write_direct; | ||
244 | xfs_iomap_write_delay_t xfs_iomap_write_delay; | ||
245 | xfs_iomap_write_allocate_t xfs_iomap_write_allocate; | ||
246 | xfs_iomap_write_unwritten_t xfs_iomap_write_unwritten; | ||
247 | xfs_lock_t xfs_ilock; | ||
248 | xfs_lck_map_shared_t xfs_lck_map_shared; | ||
249 | xfs_lock_demote_t xfs_ilock_demote; | ||
250 | xfs_lock_nowait_t xfs_ilock_nowait; | ||
251 | xfs_unlk_t xfs_unlock; | ||
252 | xfs_size_t xfs_size_func; | ||
253 | xfs_iodone_t xfs_iodone; | ||
254 | xfs_swap_extents_t xfs_swap_extents_func; | ||
255 | } xfs_ioops_t; | ||
256 | |||
257 | #define XFS_IOINIT(mp, args, flags) \ | ||
258 | (*(mp)->m_io_ops.xfs_ioinit)(mp, args, flags) | ||
259 | #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \ | ||
260 | (*(mp)->m_io_ops.xfs_bmapi_func) \ | ||
261 | (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) | ||
262 | #define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \ | ||
263 | (*(mp)->m_io_ops.xfs_bunmapi_func) \ | ||
264 | (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done) | ||
265 | #define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ | ||
266 | (*(mp)->m_io_ops.xfs_bmap_eof_func) \ | ||
267 | ((io)->io_obj, endoff, whichfork, eof) | ||
268 | #define XFS_IOMAP_WRITE_DIRECT(mp, io, offset, count, flags, mval, nmap, found)\ | ||
269 | (*(mp)->m_io_ops.xfs_iomap_write_direct) \ | ||
270 | ((io)->io_obj, offset, count, flags, mval, nmap, found) | ||
271 | #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ | ||
272 | (*(mp)->m_io_ops.xfs_iomap_write_delay) \ | ||
273 | ((io)->io_obj, offset, count, flags, mval, nmap) | ||
274 | #define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \ | ||
275 | (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ | ||
276 | ((io)->io_obj, offset, count, mval, nmap) | ||
277 | #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ | ||
278 | (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ | ||
279 | ((io)->io_obj, offset, count) | ||
280 | #define XFS_LCK_MAP_SHARED(mp, io) \ | ||
281 | (*(mp)->m_io_ops.xfs_lck_map_shared)((io)->io_obj) | ||
282 | #define XFS_ILOCK(mp, io, mode) \ | ||
283 | (*(mp)->m_io_ops.xfs_ilock)((io)->io_obj, mode) | ||
284 | #define XFS_ILOCK_NOWAIT(mp, io, mode) \ | ||
285 | (*(mp)->m_io_ops.xfs_ilock_nowait)((io)->io_obj, mode) | ||
286 | #define XFS_IUNLOCK(mp, io, mode) \ | ||
287 | (*(mp)->m_io_ops.xfs_unlock)((io)->io_obj, mode) | ||
288 | #define XFS_ILOCK_DEMOTE(mp, io, mode) \ | ||
289 | (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode) | ||
290 | #define XFS_SIZE(mp, io) \ | ||
291 | (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) | ||
292 | #define XFS_IODONE(mp) \ | ||
293 | (*(mp)->m_io_ops.xfs_iodone)(mp) | ||
294 | #define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ | ||
295 | (*(mp)->m_io_ops.xfs_swap_extents_func) \ | ||
296 | ((io)->io_obj, (tio)->io_obj, sxp) | ||
297 | |||
298 | #ifdef HAVE_PERCPU_SB | 191 | #ifdef HAVE_PERCPU_SB |
299 | 192 | ||
300 | /* | 193 | /* |
@@ -326,14 +219,20 @@ extern void xfs_icsb_sync_counters_flags(struct xfs_mount *, int); | |||
326 | #define xfs_icsb_sync_counters_flags(mp, flags) do { } while (0) | 219 | #define xfs_icsb_sync_counters_flags(mp, flags) do { } while (0) |
327 | #endif | 220 | #endif |
328 | 221 | ||
222 | typedef struct xfs_ail { | ||
223 | xfs_ail_entry_t xa_ail; | ||
224 | uint xa_gen; | ||
225 | struct task_struct *xa_task; | ||
226 | xfs_lsn_t xa_target; | ||
227 | } xfs_ail_t; | ||
228 | |||
329 | typedef struct xfs_mount { | 229 | typedef struct xfs_mount { |
330 | struct super_block *m_super; | 230 | struct super_block *m_super; |
331 | xfs_tid_t m_tid; /* next unused tid for fs */ | 231 | xfs_tid_t m_tid; /* next unused tid for fs */ |
332 | AIL_LOCK_T m_ail_lock; /* fs AIL mutex */ | 232 | spinlock_t m_ail_lock; /* fs AIL mutex */ |
333 | xfs_ail_entry_t m_ail; /* fs active log item list */ | 233 | xfs_ail_t m_ail; /* fs active log item list */ |
334 | uint m_ail_gen; /* fs AIL generation count */ | ||
335 | xfs_sb_t m_sb; /* copy of fs superblock */ | 234 | xfs_sb_t m_sb; /* copy of fs superblock */ |
336 | lock_t m_sb_lock; /* sb counter mutex */ | 235 | spinlock_t m_sb_lock; /* sb counter lock */ |
337 | struct xfs_buf *m_sb_bp; /* buffer for superblock */ | 236 | struct xfs_buf *m_sb_bp; /* buffer for superblock */ |
338 | char *m_fsname; /* filesystem name */ | 237 | char *m_fsname; /* filesystem name */ |
339 | int m_fsname_len; /* strlen of fs name */ | 238 | int m_fsname_len; /* strlen of fs name */ |
@@ -342,7 +241,7 @@ typedef struct xfs_mount { | |||
342 | int m_bsize; /* fs logical block size */ | 241 | int m_bsize; /* fs logical block size */ |
343 | xfs_agnumber_t m_agfrotor; /* last ag where space found */ | 242 | xfs_agnumber_t m_agfrotor; /* last ag where space found */ |
344 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ | 243 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ |
345 | lock_t m_agirotor_lock;/* .. and lock protecting it */ | 244 | spinlock_t m_agirotor_lock;/* .. and lock protecting it */ |
346 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ | 245 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ |
347 | struct xfs_inode *m_inodes; /* active inode list */ | 246 | struct xfs_inode *m_inodes; /* active inode list */ |
348 | struct list_head m_del_inodes; /* inodes to reclaim */ | 247 | struct list_head m_del_inodes; /* inodes to reclaim */ |
@@ -423,7 +322,6 @@ typedef struct xfs_mount { | |||
423 | * hash table */ | 322 | * hash table */ |
424 | struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ | 323 | struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ |
425 | struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ | 324 | struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ |
426 | struct xfs_ioops m_io_ops; /* vector of I/O ops */ | ||
427 | atomic_t m_active_trans; /* number trans frozen */ | 325 | atomic_t m_active_trans; /* number trans frozen */ |
428 | #ifdef HAVE_PERCPU_SB | 326 | #ifdef HAVE_PERCPU_SB |
429 | xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ | 327 | xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ |
@@ -610,8 +508,6 @@ typedef struct xfs_mod_sb { | |||
610 | 508 | ||
611 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) | 509 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) |
612 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) | 510 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) |
613 | #define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock) | ||
614 | #define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s)) | ||
615 | 511 | ||
616 | extern xfs_mount_t *xfs_mount_init(void); | 512 | extern xfs_mount_t *xfs_mount_init(void); |
617 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 513 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
@@ -646,7 +542,6 @@ extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); | |||
646 | extern void xfs_qmops_put(struct xfs_mount *); | 542 | extern void xfs_qmops_put(struct xfs_mount *); |
647 | 543 | ||
648 | extern struct xfs_dmops xfs_dmcore_xfs; | 544 | extern struct xfs_dmops xfs_dmcore_xfs; |
649 | extern struct xfs_ioops xfs_iocore_xfs; | ||
650 | 545 | ||
651 | extern int xfs_init(void); | 546 | extern int xfs_init(void); |
652 | extern void xfs_cleanup(void); | 547 | extern void xfs_cleanup(void); |
diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index e0b358c1c533..a0b2c0a2589a 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c | |||
@@ -225,10 +225,14 @@ _xfs_mru_cache_list_insert( | |||
225 | * list need to be deleted. For each element this involves removing it from the | 225 | * list need to be deleted. For each element this involves removing it from the |
226 | * data store, removing it from the reap list, calling the client's free | 226 | * data store, removing it from the reap list, calling the client's free |
227 | * function and deleting the element from the element zone. | 227 | * function and deleting the element from the element zone. |
228 | * | ||
229 | * We get called holding the mru->lock, which we drop and then reacquire. | ||
230 | * Sparse need special help with this to tell it we know what we are doing. | ||
228 | */ | 231 | */ |
229 | STATIC void | 232 | STATIC void |
230 | _xfs_mru_cache_clear_reap_list( | 233 | _xfs_mru_cache_clear_reap_list( |
231 | xfs_mru_cache_t *mru) | 234 | xfs_mru_cache_t *mru) __releases(mru->lock) __acquires(mru->lock) |
235 | |||
232 | { | 236 | { |
233 | xfs_mru_cache_elem_t *elem, *next; | 237 | xfs_mru_cache_elem_t *elem, *next; |
234 | struct list_head tmp; | 238 | struct list_head tmp; |
@@ -245,7 +249,7 @@ _xfs_mru_cache_clear_reap_list( | |||
245 | */ | 249 | */ |
246 | list_move(&elem->list_node, &tmp); | 250 | list_move(&elem->list_node, &tmp); |
247 | } | 251 | } |
248 | mutex_spinunlock(&mru->lock, 0); | 252 | spin_unlock(&mru->lock); |
249 | 253 | ||
250 | list_for_each_entry_safe(elem, next, &tmp, list_node) { | 254 | list_for_each_entry_safe(elem, next, &tmp, list_node) { |
251 | 255 | ||
@@ -259,7 +263,7 @@ _xfs_mru_cache_clear_reap_list( | |||
259 | kmem_zone_free(xfs_mru_elem_zone, elem); | 263 | kmem_zone_free(xfs_mru_elem_zone, elem); |
260 | } | 264 | } |
261 | 265 | ||
262 | mutex_spinlock(&mru->lock); | 266 | spin_lock(&mru->lock); |
263 | } | 267 | } |
264 | 268 | ||
265 | /* | 269 | /* |
@@ -280,7 +284,7 @@ _xfs_mru_cache_reap( | |||
280 | if (!mru || !mru->lists) | 284 | if (!mru || !mru->lists) |
281 | return; | 285 | return; |
282 | 286 | ||
283 | mutex_spinlock(&mru->lock); | 287 | spin_lock(&mru->lock); |
284 | next = _xfs_mru_cache_migrate(mru, jiffies); | 288 | next = _xfs_mru_cache_migrate(mru, jiffies); |
285 | _xfs_mru_cache_clear_reap_list(mru); | 289 | _xfs_mru_cache_clear_reap_list(mru); |
286 | 290 | ||
@@ -294,7 +298,7 @@ _xfs_mru_cache_reap( | |||
294 | queue_delayed_work(xfs_mru_reap_wq, &mru->work, next); | 298 | queue_delayed_work(xfs_mru_reap_wq, &mru->work, next); |
295 | } | 299 | } |
296 | 300 | ||
297 | mutex_spinunlock(&mru->lock, 0); | 301 | spin_unlock(&mru->lock); |
298 | } | 302 | } |
299 | 303 | ||
300 | int | 304 | int |
@@ -368,7 +372,7 @@ xfs_mru_cache_create( | |||
368 | */ | 372 | */ |
369 | INIT_RADIX_TREE(&mru->store, GFP_ATOMIC); | 373 | INIT_RADIX_TREE(&mru->store, GFP_ATOMIC); |
370 | INIT_LIST_HEAD(&mru->reap_list); | 374 | INIT_LIST_HEAD(&mru->reap_list); |
371 | spinlock_init(&mru->lock, "xfs_mru_cache"); | 375 | spin_lock_init(&mru->lock); |
372 | INIT_DELAYED_WORK(&mru->work, _xfs_mru_cache_reap); | 376 | INIT_DELAYED_WORK(&mru->work, _xfs_mru_cache_reap); |
373 | 377 | ||
374 | mru->grp_time = grp_time; | 378 | mru->grp_time = grp_time; |
@@ -398,17 +402,17 @@ xfs_mru_cache_flush( | |||
398 | if (!mru || !mru->lists) | 402 | if (!mru || !mru->lists) |
399 | return; | 403 | return; |
400 | 404 | ||
401 | mutex_spinlock(&mru->lock); | 405 | spin_lock(&mru->lock); |
402 | if (mru->queued) { | 406 | if (mru->queued) { |
403 | mutex_spinunlock(&mru->lock, 0); | 407 | spin_unlock(&mru->lock); |
404 | cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); | 408 | cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); |
405 | mutex_spinlock(&mru->lock); | 409 | spin_lock(&mru->lock); |
406 | } | 410 | } |
407 | 411 | ||
408 | _xfs_mru_cache_migrate(mru, jiffies + mru->grp_count * mru->grp_time); | 412 | _xfs_mru_cache_migrate(mru, jiffies + mru->grp_count * mru->grp_time); |
409 | _xfs_mru_cache_clear_reap_list(mru); | 413 | _xfs_mru_cache_clear_reap_list(mru); |
410 | 414 | ||
411 | mutex_spinunlock(&mru->lock, 0); | 415 | spin_unlock(&mru->lock); |
412 | } | 416 | } |
413 | 417 | ||
414 | void | 418 | void |
@@ -454,13 +458,13 @@ xfs_mru_cache_insert( | |||
454 | elem->key = key; | 458 | elem->key = key; |
455 | elem->value = value; | 459 | elem->value = value; |
456 | 460 | ||
457 | mutex_spinlock(&mru->lock); | 461 | spin_lock(&mru->lock); |
458 | 462 | ||
459 | radix_tree_insert(&mru->store, key, elem); | 463 | radix_tree_insert(&mru->store, key, elem); |
460 | radix_tree_preload_end(); | 464 | radix_tree_preload_end(); |
461 | _xfs_mru_cache_list_insert(mru, elem); | 465 | _xfs_mru_cache_list_insert(mru, elem); |
462 | 466 | ||
463 | mutex_spinunlock(&mru->lock, 0); | 467 | spin_unlock(&mru->lock); |
464 | 468 | ||
465 | return 0; | 469 | return 0; |
466 | } | 470 | } |
@@ -483,14 +487,14 @@ xfs_mru_cache_remove( | |||
483 | if (!mru || !mru->lists) | 487 | if (!mru || !mru->lists) |
484 | return NULL; | 488 | return NULL; |
485 | 489 | ||
486 | mutex_spinlock(&mru->lock); | 490 | spin_lock(&mru->lock); |
487 | elem = radix_tree_delete(&mru->store, key); | 491 | elem = radix_tree_delete(&mru->store, key); |
488 | if (elem) { | 492 | if (elem) { |
489 | value = elem->value; | 493 | value = elem->value; |
490 | list_del(&elem->list_node); | 494 | list_del(&elem->list_node); |
491 | } | 495 | } |
492 | 496 | ||
493 | mutex_spinunlock(&mru->lock, 0); | 497 | spin_unlock(&mru->lock); |
494 | 498 | ||
495 | if (elem) | 499 | if (elem) |
496 | kmem_zone_free(xfs_mru_elem_zone, elem); | 500 | kmem_zone_free(xfs_mru_elem_zone, elem); |
@@ -528,6 +532,10 @@ xfs_mru_cache_delete( | |||
528 | * | 532 | * |
529 | * If the element isn't found, this function returns NULL and the spinlock is | 533 | * If the element isn't found, this function returns NULL and the spinlock is |
530 | * released. xfs_mru_cache_done() should NOT be called when this occurs. | 534 | * released. xfs_mru_cache_done() should NOT be called when this occurs. |
535 | * | ||
536 | * Because sparse isn't smart enough to know about conditional lock return | ||
537 | * status, we need to help it get it right by annotating the path that does | ||
538 | * not release the lock. | ||
531 | */ | 539 | */ |
532 | void * | 540 | void * |
533 | xfs_mru_cache_lookup( | 541 | xfs_mru_cache_lookup( |
@@ -540,14 +548,14 @@ xfs_mru_cache_lookup( | |||
540 | if (!mru || !mru->lists) | 548 | if (!mru || !mru->lists) |
541 | return NULL; | 549 | return NULL; |
542 | 550 | ||
543 | mutex_spinlock(&mru->lock); | 551 | spin_lock(&mru->lock); |
544 | elem = radix_tree_lookup(&mru->store, key); | 552 | elem = radix_tree_lookup(&mru->store, key); |
545 | if (elem) { | 553 | if (elem) { |
546 | list_del(&elem->list_node); | 554 | list_del(&elem->list_node); |
547 | _xfs_mru_cache_list_insert(mru, elem); | 555 | _xfs_mru_cache_list_insert(mru, elem); |
548 | } | 556 | __release(mru_lock); /* help sparse not be stupid */ |
549 | else | 557 | } else |
550 | mutex_spinunlock(&mru->lock, 0); | 558 | spin_unlock(&mru->lock); |
551 | 559 | ||
552 | return elem ? elem->value : NULL; | 560 | return elem ? elem->value : NULL; |
553 | } | 561 | } |
@@ -571,10 +579,12 @@ xfs_mru_cache_peek( | |||
571 | if (!mru || !mru->lists) | 579 | if (!mru || !mru->lists) |
572 | return NULL; | 580 | return NULL; |
573 | 581 | ||
574 | mutex_spinlock(&mru->lock); | 582 | spin_lock(&mru->lock); |
575 | elem = radix_tree_lookup(&mru->store, key); | 583 | elem = radix_tree_lookup(&mru->store, key); |
576 | if (!elem) | 584 | if (!elem) |
577 | mutex_spinunlock(&mru->lock, 0); | 585 | spin_unlock(&mru->lock); |
586 | else | ||
587 | __release(mru_lock); /* help sparse not be stupid */ | ||
578 | 588 | ||
579 | return elem ? elem->value : NULL; | 589 | return elem ? elem->value : NULL; |
580 | } | 590 | } |
@@ -586,7 +596,7 @@ xfs_mru_cache_peek( | |||
586 | */ | 596 | */ |
587 | void | 597 | void |
588 | xfs_mru_cache_done( | 598 | xfs_mru_cache_done( |
589 | xfs_mru_cache_t *mru) | 599 | xfs_mru_cache_t *mru) __releases(mru->lock) |
590 | { | 600 | { |
591 | mutex_spinunlock(&mru->lock, 0); | 601 | spin_unlock(&mru->lock); |
592 | } | 602 | } |
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 2ec1d8a27352..a294e58db8dd 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
@@ -49,18 +49,17 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp) | |||
49 | { | 49 | { |
50 | int error; | 50 | int error; |
51 | xfs_trans_t *tp; | 51 | xfs_trans_t *tp; |
52 | unsigned long s; | ||
53 | 52 | ||
54 | mp->m_qflags = 0; | 53 | mp->m_qflags = 0; |
55 | /* | 54 | /* |
56 | * It is OK to look at sb_qflags here in mount path, | 55 | * It is OK to look at sb_qflags here in mount path, |
57 | * without SB_LOCK. | 56 | * without m_sb_lock. |
58 | */ | 57 | */ |
59 | if (mp->m_sb.sb_qflags == 0) | 58 | if (mp->m_sb.sb_qflags == 0) |
60 | return 0; | 59 | return 0; |
61 | s = XFS_SB_LOCK(mp); | 60 | spin_lock(&mp->m_sb_lock); |
62 | mp->m_sb.sb_qflags = 0; | 61 | mp->m_sb.sb_qflags = 0; |
63 | XFS_SB_UNLOCK(mp, s); | 62 | spin_unlock(&mp->m_sb_lock); |
64 | 63 | ||
65 | /* | 64 | /* |
66 | * if the fs is readonly, let the incore superblock run | 65 | * if the fs is readonly, let the incore superblock run |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 44ea0ba36476..7eb157a59f9e 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "xfs_refcache.h" | 39 | #include "xfs_refcache.h" |
40 | #include "xfs_utils.h" | 40 | #include "xfs_utils.h" |
41 | #include "xfs_trans_space.h" | 41 | #include "xfs_trans_space.h" |
42 | #include "xfs_vnodeops.h" | ||
42 | 43 | ||
43 | 44 | ||
44 | /* | 45 | /* |
@@ -118,7 +119,7 @@ xfs_lock_for_rename( | |||
118 | inum1 = ip1->i_ino; | 119 | inum1 = ip1->i_ino; |
119 | 120 | ||
120 | ASSERT(ip1); | 121 | ASSERT(ip1); |
121 | ITRACE(ip1); | 122 | xfs_itrace_ref(ip1); |
122 | 123 | ||
123 | /* | 124 | /* |
124 | * Unlock dp1 and lock dp2 if they are different. | 125 | * Unlock dp1 and lock dp2 if they are different. |
@@ -141,7 +142,7 @@ xfs_lock_for_rename( | |||
141 | IRELE (ip1); | 142 | IRELE (ip1); |
142 | return error; | 143 | return error; |
143 | } else { | 144 | } else { |
144 | ITRACE(ip2); | 145 | xfs_itrace_ref(ip2); |
145 | } | 146 | } |
146 | 147 | ||
147 | /* | 148 | /* |
@@ -247,8 +248,8 @@ xfs_rename( | |||
247 | int src_namelen = VNAMELEN(src_vname); | 248 | int src_namelen = VNAMELEN(src_vname); |
248 | int target_namelen = VNAMELEN(target_vname); | 249 | int target_namelen = VNAMELEN(target_vname); |
249 | 250 | ||
250 | vn_trace_entry(src_dp, "xfs_rename", (inst_t *)__return_address); | 251 | xfs_itrace_entry(src_dp); |
251 | vn_trace_entry(xfs_vtoi(target_dir_vp), "xfs_rename", (inst_t *)__return_address); | 252 | xfs_itrace_entry(xfs_vtoi(target_dir_vp)); |
252 | 253 | ||
253 | /* | 254 | /* |
254 | * Find the XFS behavior descriptor for the target directory | 255 | * Find the XFS behavior descriptor for the target directory |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 47082c01872d..ca83ddf72af4 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -73,18 +73,6 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, | |||
73 | */ | 73 | */ |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. | ||
77 | */ | ||
78 | STATIC int | ||
79 | xfs_lowbit32( | ||
80 | __uint32_t v) | ||
81 | { | ||
82 | if (v) | ||
83 | return ffs(v) - 1; | ||
84 | return -1; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Allocate space to the bitmap or summary file, and zero it, for growfs. | 76 | * Allocate space to the bitmap or summary file, and zero it, for growfs. |
89 | */ | 77 | */ |
90 | STATIC int /* error */ | 78 | STATIC int /* error */ |
@@ -444,6 +432,7 @@ xfs_rtallocate_extent_near( | |||
444 | } | 432 | } |
445 | bbno = XFS_BITTOBLOCK(mp, bno); | 433 | bbno = XFS_BITTOBLOCK(mp, bno); |
446 | i = 0; | 434 | i = 0; |
435 | ASSERT(minlen != 0); | ||
447 | log2len = xfs_highbit32(minlen); | 436 | log2len = xfs_highbit32(minlen); |
448 | /* | 437 | /* |
449 | * Loop over all bitmap blocks (bbno + i is current block). | 438 | * Loop over all bitmap blocks (bbno + i is current block). |
@@ -612,6 +601,8 @@ xfs_rtallocate_extent_size( | |||
612 | xfs_suminfo_t sum; /* summary information for extents */ | 601 | xfs_suminfo_t sum; /* summary information for extents */ |
613 | 602 | ||
614 | ASSERT(minlen % prod == 0 && maxlen % prod == 0); | 603 | ASSERT(minlen % prod == 0 && maxlen % prod == 0); |
604 | ASSERT(maxlen != 0); | ||
605 | |||
615 | /* | 606 | /* |
616 | * Loop over all the levels starting with maxlen. | 607 | * Loop over all the levels starting with maxlen. |
617 | * At each level, look at all the bitmap blocks, to see if there | 608 | * At each level, look at all the bitmap blocks, to see if there |
@@ -669,6 +660,9 @@ xfs_rtallocate_extent_size( | |||
669 | *rtblock = NULLRTBLOCK; | 660 | *rtblock = NULLRTBLOCK; |
670 | return 0; | 661 | return 0; |
671 | } | 662 | } |
663 | ASSERT(minlen != 0); | ||
664 | ASSERT(maxlen != 0); | ||
665 | |||
672 | /* | 666 | /* |
673 | * Loop over sizes, from maxlen down to minlen. | 667 | * Loop over sizes, from maxlen down to minlen. |
674 | * This time, when we do the allocations, allow smaller ones | 668 | * This time, when we do the allocations, allow smaller ones |
@@ -1954,6 +1948,7 @@ xfs_growfs_rt( | |||
1954 | nsbp->sb_blocksize * nsbp->sb_rextsize); | 1948 | nsbp->sb_blocksize * nsbp->sb_rextsize); |
1955 | nsbp->sb_rextents = nsbp->sb_rblocks; | 1949 | nsbp->sb_rextents = nsbp->sb_rblocks; |
1956 | do_div(nsbp->sb_rextents, nsbp->sb_rextsize); | 1950 | do_div(nsbp->sb_rextents, nsbp->sb_rextsize); |
1951 | ASSERT(nsbp->sb_rextents != 0); | ||
1957 | nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); | 1952 | nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); |
1958 | nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; | 1953 | nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; |
1959 | nrsumsize = | 1954 | nrsumsize = |
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 799c1f871263..8d8dcd215716 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h | |||
@@ -21,8 +21,6 @@ | |||
21 | struct xfs_mount; | 21 | struct xfs_mount; |
22 | struct xfs_trans; | 22 | struct xfs_trans; |
23 | 23 | ||
24 | #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) | ||
25 | |||
26 | /* Min and max rt extent sizes, specified in bytes */ | 24 | /* Min and max rt extent sizes, specified in bytes */ |
27 | #define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ | 25 | #define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ |
28 | #define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */ | 26 | #define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */ |
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index 49875e1d129f..f87db5344ce6 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
@@ -32,18 +32,10 @@ struct xfs_mount; | |||
32 | static inline xfs_daddr_t | 32 | static inline xfs_daddr_t |
33 | xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) | 33 | xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) |
34 | { | 34 | { |
35 | return (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \ | 35 | return (XFS_IS_REALTIME_INODE(ip) ? \ |
36 | (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \ | 36 | (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \ |
37 | XFS_FSB_TO_DADDR((ip)->i_mount, (fsb))); | 37 | XFS_FSB_TO_DADDR((ip)->i_mount, (fsb))); |
38 | } | 38 | } |
39 | #define XFS_FSB_TO_DB_IO(io,fsb) xfs_fsb_to_db_io(io,fsb) | ||
40 | static inline xfs_daddr_t | ||
41 | xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb) | ||
42 | { | ||
43 | return (((io)->io_flags & XFS_IOCORE_RT) ? \ | ||
44 | XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \ | ||
45 | XFS_FSB_TO_DADDR((io)->io_mount, (fsb))); | ||
46 | } | ||
47 | 39 | ||
48 | /* | 40 | /* |
49 | * Flags for xfs_free_eofblocks | 41 | * Flags for xfs_free_eofblocks |
@@ -61,7 +53,7 @@ xfs_get_extsz_hint( | |||
61 | { | 53 | { |
62 | xfs_extlen_t extsz; | 54 | xfs_extlen_t extsz; |
63 | 55 | ||
64 | if (unlikely(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | 56 | if (unlikely(XFS_IS_REALTIME_INODE(ip))) { |
65 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | 57 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) |
66 | ? ip->i_d.di_extsize | 58 | ? ip->i_d.di_extsize |
67 | : ip->i_mount->m_sb.sb_rextsize; | 59 | : ip->i_mount->m_sb.sb_rextsize; |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 8878322ee793..71e4c8dcc69b 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1322,7 +1322,6 @@ xfs_trans_chunk_committed( | |||
1322 | xfs_lsn_t item_lsn; | 1322 | xfs_lsn_t item_lsn; |
1323 | struct xfs_mount *mp; | 1323 | struct xfs_mount *mp; |
1324 | int i; | 1324 | int i; |
1325 | SPLDECL(s); | ||
1326 | 1325 | ||
1327 | lidp = licp->lic_descs; | 1326 | lidp = licp->lic_descs; |
1328 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | 1327 | for (i = 0; i < licp->lic_unused; i++, lidp++) { |
@@ -1363,7 +1362,7 @@ xfs_trans_chunk_committed( | |||
1363 | * the test below. | 1362 | * the test below. |
1364 | */ | 1363 | */ |
1365 | mp = lip->li_mountp; | 1364 | mp = lip->li_mountp; |
1366 | AIL_LOCK(mp,s); | 1365 | spin_lock(&mp->m_ail_lock); |
1367 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) { | 1366 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) { |
1368 | /* | 1367 | /* |
1369 | * This will set the item's lsn to item_lsn | 1368 | * This will set the item's lsn to item_lsn |
@@ -1372,9 +1371,9 @@ xfs_trans_chunk_committed( | |||
1372 | * | 1371 | * |
1373 | * xfs_trans_update_ail() drops the AIL lock. | 1372 | * xfs_trans_update_ail() drops the AIL lock. |
1374 | */ | 1373 | */ |
1375 | xfs_trans_update_ail(mp, lip, item_lsn, s); | 1374 | xfs_trans_update_ail(mp, lip, item_lsn); |
1376 | } else { | 1375 | } else { |
1377 | AIL_UNLOCK(mp, s); | 1376 | spin_unlock(&mp->m_ail_lock); |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | /* | 1379 | /* |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 0e26e729023e..7f40628d85c7 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -992,8 +992,9 @@ int _xfs_trans_commit(xfs_trans_t *, | |||
992 | int *); | 992 | int *); |
993 | #define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) | 993 | #define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) |
994 | void xfs_trans_cancel(xfs_trans_t *, int); | 994 | void xfs_trans_cancel(xfs_trans_t *, int); |
995 | void xfs_trans_ail_init(struct xfs_mount *); | 995 | int xfs_trans_ail_init(struct xfs_mount *); |
996 | xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); | 996 | void xfs_trans_ail_destroy(struct xfs_mount *); |
997 | void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); | ||
997 | xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *); | 998 | xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *); |
998 | void xfs_trans_unlocked_item(struct xfs_mount *, | 999 | void xfs_trans_unlocked_item(struct xfs_mount *, |
999 | xfs_log_item_t *); | 1000 | xfs_log_item_t *); |
@@ -1001,6 +1002,8 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, | |||
1001 | xfs_agnumber_t ag, | 1002 | xfs_agnumber_t ag, |
1002 | xfs_extlen_t idx); | 1003 | xfs_extlen_t idx); |
1003 | 1004 | ||
1005 | extern kmem_zone_t *xfs_trans_zone; | ||
1006 | |||
1004 | #endif /* __KERNEL__ */ | 1007 | #endif /* __KERNEL__ */ |
1005 | 1008 | ||
1006 | #endif /* __XFS_TRANS_H__ */ | 1009 | #endif /* __XFS_TRANS_H__ */ |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 5b2ff59f19cf..4d6330eddc8d 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -34,9 +34,9 @@ STATIC xfs_log_item_t * xfs_ail_min(xfs_ail_entry_t *); | |||
34 | STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *); | 34 | STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *); |
35 | 35 | ||
36 | #ifdef DEBUG | 36 | #ifdef DEBUG |
37 | STATIC void xfs_ail_check(xfs_ail_entry_t *); | 37 | STATIC void xfs_ail_check(xfs_ail_entry_t *, xfs_log_item_t *); |
38 | #else | 38 | #else |
39 | #define xfs_ail_check(a) | 39 | #define xfs_ail_check(a,l) |
40 | #endif /* DEBUG */ | 40 | #endif /* DEBUG */ |
41 | 41 | ||
42 | 42 | ||
@@ -55,16 +55,15 @@ xfs_trans_tail_ail( | |||
55 | { | 55 | { |
56 | xfs_lsn_t lsn; | 56 | xfs_lsn_t lsn; |
57 | xfs_log_item_t *lip; | 57 | xfs_log_item_t *lip; |
58 | SPLDECL(s); | ||
59 | 58 | ||
60 | AIL_LOCK(mp,s); | 59 | spin_lock(&mp->m_ail_lock); |
61 | lip = xfs_ail_min(&(mp->m_ail)); | 60 | lip = xfs_ail_min(&(mp->m_ail.xa_ail)); |
62 | if (lip == NULL) { | 61 | if (lip == NULL) { |
63 | lsn = (xfs_lsn_t)0; | 62 | lsn = (xfs_lsn_t)0; |
64 | } else { | 63 | } else { |
65 | lsn = lip->li_lsn; | 64 | lsn = lip->li_lsn; |
66 | } | 65 | } |
67 | AIL_UNLOCK(mp, s); | 66 | spin_unlock(&mp->m_ail_lock); |
68 | 67 | ||
69 | return lsn; | 68 | return lsn; |
70 | } | 69 | } |
@@ -72,120 +71,185 @@ xfs_trans_tail_ail( | |||
72 | /* | 71 | /* |
73 | * xfs_trans_push_ail | 72 | * xfs_trans_push_ail |
74 | * | 73 | * |
75 | * This routine is called to move the tail of the AIL | 74 | * This routine is called to move the tail of the AIL forward. It does this by |
76 | * forward. It does this by trying to flush items in the AIL | 75 | * trying to flush items in the AIL whose lsns are below the given |
77 | * whose lsns are below the given threshold_lsn. | 76 | * threshold_lsn. |
78 | * | 77 | * |
79 | * The routine returns the lsn of the tail of the log. | 78 | * the push is run asynchronously in a separate thread, so we return the tail |
79 | * of the log right now instead of the tail after the push. This means we will | ||
80 | * either continue right away, or we will sleep waiting on the async thread to | ||
81 | * do it's work. | ||
82 | * | ||
83 | * We do this unlocked - we only need to know whether there is anything in the | ||
84 | * AIL at the time we are called. We don't need to access the contents of | ||
85 | * any of the objects, so the lock is not needed. | ||
80 | */ | 86 | */ |
81 | xfs_lsn_t | 87 | void |
82 | xfs_trans_push_ail( | 88 | xfs_trans_push_ail( |
83 | xfs_mount_t *mp, | 89 | xfs_mount_t *mp, |
84 | xfs_lsn_t threshold_lsn) | 90 | xfs_lsn_t threshold_lsn) |
85 | { | 91 | { |
86 | xfs_lsn_t lsn; | ||
87 | xfs_log_item_t *lip; | 92 | xfs_log_item_t *lip; |
88 | int gen; | ||
89 | int restarts; | ||
90 | int lock_result; | ||
91 | int flush_log; | ||
92 | SPLDECL(s); | ||
93 | 93 | ||
94 | #define XFS_TRANS_PUSH_AIL_RESTARTS 1000 | 94 | lip = xfs_ail_min(&mp->m_ail.xa_ail); |
95 | if (lip && !XFS_FORCED_SHUTDOWN(mp)) { | ||
96 | if (XFS_LSN_CMP(threshold_lsn, mp->m_ail.xa_target) > 0) | ||
97 | xfsaild_wakeup(mp, threshold_lsn); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Return the item in the AIL with the current lsn. | ||
103 | * Return the current tree generation number for use | ||
104 | * in calls to xfs_trans_next_ail(). | ||
105 | */ | ||
106 | STATIC xfs_log_item_t * | ||
107 | xfs_trans_first_push_ail( | ||
108 | xfs_mount_t *mp, | ||
109 | int *gen, | ||
110 | xfs_lsn_t lsn) | ||
111 | { | ||
112 | xfs_log_item_t *lip; | ||
113 | |||
114 | lip = xfs_ail_min(&(mp->m_ail.xa_ail)); | ||
115 | *gen = (int)mp->m_ail.xa_gen; | ||
116 | if (lsn == 0) | ||
117 | return lip; | ||
118 | |||
119 | while (lip && (XFS_LSN_CMP(lip->li_lsn, lsn) < 0)) | ||
120 | lip = lip->li_ail.ail_forw; | ||
95 | 121 | ||
96 | AIL_LOCK(mp,s); | 122 | return lip; |
97 | lip = xfs_trans_first_ail(mp, &gen); | 123 | } |
98 | if (lip == NULL || XFS_FORCED_SHUTDOWN(mp)) { | 124 | |
125 | /* | ||
126 | * Function that does the work of pushing on the AIL | ||
127 | */ | ||
128 | long | ||
129 | xfsaild_push( | ||
130 | xfs_mount_t *mp, | ||
131 | xfs_lsn_t *last_lsn) | ||
132 | { | ||
133 | long tout = 1000; /* milliseconds */ | ||
134 | xfs_lsn_t last_pushed_lsn = *last_lsn; | ||
135 | xfs_lsn_t target = mp->m_ail.xa_target; | ||
136 | xfs_lsn_t lsn; | ||
137 | xfs_log_item_t *lip; | ||
138 | int gen; | ||
139 | int restarts; | ||
140 | int flush_log, count, stuck; | ||
141 | |||
142 | #define XFS_TRANS_PUSH_AIL_RESTARTS 10 | ||
143 | |||
144 | spin_lock(&mp->m_ail_lock); | ||
145 | lip = xfs_trans_first_push_ail(mp, &gen, *last_lsn); | ||
146 | if (!lip || XFS_FORCED_SHUTDOWN(mp)) { | ||
99 | /* | 147 | /* |
100 | * Just return if the AIL is empty. | 148 | * AIL is empty or our push has reached the end. |
101 | */ | 149 | */ |
102 | AIL_UNLOCK(mp, s); | 150 | spin_unlock(&mp->m_ail_lock); |
103 | return (xfs_lsn_t)0; | 151 | last_pushed_lsn = 0; |
152 | goto out; | ||
104 | } | 153 | } |
105 | 154 | ||
106 | XFS_STATS_INC(xs_push_ail); | 155 | XFS_STATS_INC(xs_push_ail); |
107 | 156 | ||
108 | /* | 157 | /* |
109 | * While the item we are looking at is below the given threshold | 158 | * While the item we are looking at is below the given threshold |
110 | * try to flush it out. Make sure to limit the number of times | 159 | * try to flush it out. We'd like not to stop until we've at least |
111 | * we allow xfs_trans_next_ail() to restart scanning from the | ||
112 | * beginning of the list. We'd like not to stop until we've at least | ||
113 | * tried to push on everything in the AIL with an LSN less than | 160 | * tried to push on everything in the AIL with an LSN less than |
114 | * the given threshold. However, we may give up before that if | 161 | * the given threshold. |
115 | * we realize that we've been holding the AIL_LOCK for 'too long', | 162 | * |
116 | * blocking interrupts. Currently, too long is < 500us roughly. | 163 | * However, we will stop after a certain number of pushes and wait |
164 | * for a reduced timeout to fire before pushing further. This | ||
165 | * prevents use from spinning when we can't do anything or there is | ||
166 | * lots of contention on the AIL lists. | ||
117 | */ | 167 | */ |
118 | flush_log = 0; | 168 | tout = 10; |
119 | restarts = 0; | 169 | lsn = lip->li_lsn; |
120 | while (((restarts < XFS_TRANS_PUSH_AIL_RESTARTS) && | 170 | flush_log = stuck = count = restarts = 0; |
121 | (XFS_LSN_CMP(lip->li_lsn, threshold_lsn) < 0))) { | 171 | while ((XFS_LSN_CMP(lip->li_lsn, target) < 0)) { |
172 | int lock_result; | ||
122 | /* | 173 | /* |
123 | * If we can lock the item without sleeping, unlock | 174 | * If we can lock the item without sleeping, unlock the AIL |
124 | * the AIL lock and flush the item. Then re-grab the | 175 | * lock and flush the item. Then re-grab the AIL lock so we |
125 | * AIL lock so we can look for the next item on the | 176 | * can look for the next item on the AIL. List changes are |
126 | * AIL. Since we unlock the AIL while we flush the | 177 | * handled by the AIL lookup functions internally |
127 | * item, the next routine may start over again at the | ||
128 | * the beginning of the list if anything has changed. | ||
129 | * That is what the generation count is for. | ||
130 | * | 178 | * |
131 | * If we can't lock the item, either its holder will flush | 179 | * If we can't lock the item, either its holder will flush it |
132 | * it or it is already being flushed or it is being relogged. | 180 | * or it is already being flushed or it is being relogged. In |
133 | * In any of these case it is being taken care of and we | 181 | * any of these case it is being taken care of and we can just |
134 | * can just skip to the next item in the list. | 182 | * skip to the next item in the list. |
135 | */ | 183 | */ |
136 | lock_result = IOP_TRYLOCK(lip); | 184 | lock_result = IOP_TRYLOCK(lip); |
185 | spin_unlock(&mp->m_ail_lock); | ||
137 | switch (lock_result) { | 186 | switch (lock_result) { |
138 | case XFS_ITEM_SUCCESS: | 187 | case XFS_ITEM_SUCCESS: |
139 | AIL_UNLOCK(mp, s); | ||
140 | XFS_STATS_INC(xs_push_ail_success); | 188 | XFS_STATS_INC(xs_push_ail_success); |
141 | IOP_PUSH(lip); | 189 | IOP_PUSH(lip); |
142 | AIL_LOCK(mp,s); | 190 | last_pushed_lsn = lsn; |
143 | break; | 191 | break; |
144 | 192 | ||
145 | case XFS_ITEM_PUSHBUF: | 193 | case XFS_ITEM_PUSHBUF: |
146 | AIL_UNLOCK(mp, s); | ||
147 | XFS_STATS_INC(xs_push_ail_pushbuf); | 194 | XFS_STATS_INC(xs_push_ail_pushbuf); |
148 | #ifdef XFSRACEDEBUG | ||
149 | delay_for_intr(); | ||
150 | delay(300); | ||
151 | #endif | ||
152 | ASSERT(lip->li_ops->iop_pushbuf); | ||
153 | ASSERT(lip); | ||
154 | IOP_PUSHBUF(lip); | 195 | IOP_PUSHBUF(lip); |
155 | AIL_LOCK(mp,s); | 196 | last_pushed_lsn = lsn; |
156 | break; | 197 | break; |
157 | 198 | ||
158 | case XFS_ITEM_PINNED: | 199 | case XFS_ITEM_PINNED: |
159 | XFS_STATS_INC(xs_push_ail_pinned); | 200 | XFS_STATS_INC(xs_push_ail_pinned); |
201 | stuck++; | ||
160 | flush_log = 1; | 202 | flush_log = 1; |
161 | break; | 203 | break; |
162 | 204 | ||
163 | case XFS_ITEM_LOCKED: | 205 | case XFS_ITEM_LOCKED: |
164 | XFS_STATS_INC(xs_push_ail_locked); | 206 | XFS_STATS_INC(xs_push_ail_locked); |
207 | last_pushed_lsn = lsn; | ||
208 | stuck++; | ||
165 | break; | 209 | break; |
166 | 210 | ||
167 | case XFS_ITEM_FLUSHING: | 211 | case XFS_ITEM_FLUSHING: |
168 | XFS_STATS_INC(xs_push_ail_flushing); | 212 | XFS_STATS_INC(xs_push_ail_flushing); |
213 | last_pushed_lsn = lsn; | ||
214 | stuck++; | ||
169 | break; | 215 | break; |
170 | 216 | ||
171 | default: | 217 | default: |
172 | ASSERT(0); | 218 | ASSERT(0); |
173 | break; | 219 | break; |
174 | } | 220 | } |
175 | 221 | ||
176 | lip = xfs_trans_next_ail(mp, lip, &gen, &restarts); | 222 | spin_lock(&mp->m_ail_lock); |
177 | if (lip == NULL) { | 223 | /* should we bother continuing? */ |
224 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
225 | break; | ||
226 | ASSERT(mp->m_log); | ||
227 | |||
228 | count++; | ||
229 | |||
230 | /* | ||
231 | * Are there too many items we can't do anything with? | ||
232 | * If we we are skipping too many items because we can't flush | ||
233 | * them or they are already being flushed, we back off and | ||
234 | * given them time to complete whatever operation is being | ||
235 | * done. i.e. remove pressure from the AIL while we can't make | ||
236 | * progress so traversals don't slow down further inserts and | ||
237 | * removals to/from the AIL. | ||
238 | * | ||
239 | * The value of 100 is an arbitrary magic number based on | ||
240 | * observation. | ||
241 | */ | ||
242 | if (stuck > 100) | ||
178 | break; | 243 | break; |
179 | } | ||
180 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
181 | /* | ||
182 | * Just return if we shut down during the last try. | ||
183 | */ | ||
184 | AIL_UNLOCK(mp, s); | ||
185 | return (xfs_lsn_t)0; | ||
186 | } | ||
187 | 244 | ||
245 | lip = xfs_trans_next_ail(mp, lip, &gen, &restarts); | ||
246 | if (lip == NULL) | ||
247 | break; | ||
248 | if (restarts > XFS_TRANS_PUSH_AIL_RESTARTS) | ||
249 | break; | ||
250 | lsn = lip->li_lsn; | ||
188 | } | 251 | } |
252 | spin_unlock(&mp->m_ail_lock); | ||
189 | 253 | ||
190 | if (flush_log) { | 254 | if (flush_log) { |
191 | /* | 255 | /* |
@@ -193,22 +257,35 @@ xfs_trans_push_ail( | |||
193 | * push out the log so it will become unpinned and | 257 | * push out the log so it will become unpinned and |
194 | * move forward in the AIL. | 258 | * move forward in the AIL. |
195 | */ | 259 | */ |
196 | AIL_UNLOCK(mp, s); | ||
197 | XFS_STATS_INC(xs_push_ail_flush); | 260 | XFS_STATS_INC(xs_push_ail_flush); |
198 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); | 261 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); |
199 | AIL_LOCK(mp, s); | ||
200 | } | 262 | } |
201 | 263 | ||
202 | lip = xfs_ail_min(&(mp->m_ail)); | 264 | /* |
203 | if (lip == NULL) { | 265 | * We reached the target so wait a bit longer for I/O to complete and |
204 | lsn = (xfs_lsn_t)0; | 266 | * remove pushed items from the AIL before we start the next scan from |
205 | } else { | 267 | * the start of the AIL. |
206 | lsn = lip->li_lsn; | 268 | */ |
269 | if ((XFS_LSN_CMP(lsn, target) >= 0)) { | ||
270 | tout += 20; | ||
271 | last_pushed_lsn = 0; | ||
272 | } else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) || | ||
273 | (count && ((stuck * 100) / count > 90))) { | ||
274 | /* | ||
275 | * Either there is a lot of contention on the AIL or we | ||
276 | * are stuck due to operations in progress. "Stuck" in this | ||
277 | * case is defined as >90% of the items we tried to push | ||
278 | * were stuck. | ||
279 | * | ||
280 | * Backoff a bit more to allow some I/O to complete before | ||
281 | * continuing from where we were. | ||
282 | */ | ||
283 | tout += 10; | ||
207 | } | 284 | } |
208 | 285 | out: | |
209 | AIL_UNLOCK(mp, s); | 286 | *last_lsn = last_pushed_lsn; |
210 | return lsn; | 287 | return tout; |
211 | } /* xfs_trans_push_ail */ | 288 | } /* xfsaild_push */ |
212 | 289 | ||
213 | 290 | ||
214 | /* | 291 | /* |
@@ -249,7 +326,7 @@ xfs_trans_unlocked_item( | |||
249 | * the call to xfs_log_move_tail() doesn't do anything if there's | 326 | * the call to xfs_log_move_tail() doesn't do anything if there's |
250 | * not enough free space to wake people up so we're safe calling it. | 327 | * not enough free space to wake people up so we're safe calling it. |
251 | */ | 328 | */ |
252 | min_lip = xfs_ail_min(&mp->m_ail); | 329 | min_lip = xfs_ail_min(&mp->m_ail.xa_ail); |
253 | 330 | ||
254 | if (min_lip == lip) | 331 | if (min_lip == lip) |
255 | xfs_log_move_tail(mp, 1); | 332 | xfs_log_move_tail(mp, 1); |
@@ -269,21 +346,19 @@ xfs_trans_unlocked_item( | |||
269 | * has changed. | 346 | * has changed. |
270 | * | 347 | * |
271 | * This function must be called with the AIL lock held. The lock | 348 | * This function must be called with the AIL lock held. The lock |
272 | * is dropped before returning, so the caller must pass in the | 349 | * is dropped before returning. |
273 | * cookie returned by AIL_LOCK. | ||
274 | */ | 350 | */ |
275 | void | 351 | void |
276 | xfs_trans_update_ail( | 352 | xfs_trans_update_ail( |
277 | xfs_mount_t *mp, | 353 | xfs_mount_t *mp, |
278 | xfs_log_item_t *lip, | 354 | xfs_log_item_t *lip, |
279 | xfs_lsn_t lsn, | 355 | xfs_lsn_t lsn) __releases(mp->m_ail_lock) |
280 | unsigned long s) __releases(mp->m_ail_lock) | ||
281 | { | 356 | { |
282 | xfs_ail_entry_t *ailp; | 357 | xfs_ail_entry_t *ailp; |
283 | xfs_log_item_t *dlip=NULL; | 358 | xfs_log_item_t *dlip=NULL; |
284 | xfs_log_item_t *mlip; /* ptr to minimum lip */ | 359 | xfs_log_item_t *mlip; /* ptr to minimum lip */ |
285 | 360 | ||
286 | ailp = &(mp->m_ail); | 361 | ailp = &(mp->m_ail.xa_ail); |
287 | mlip = xfs_ail_min(ailp); | 362 | mlip = xfs_ail_min(ailp); |
288 | 363 | ||
289 | if (lip->li_flags & XFS_LI_IN_AIL) { | 364 | if (lip->li_flags & XFS_LI_IN_AIL) { |
@@ -296,14 +371,14 @@ xfs_trans_update_ail( | |||
296 | lip->li_lsn = lsn; | 371 | lip->li_lsn = lsn; |
297 | 372 | ||
298 | xfs_ail_insert(ailp, lip); | 373 | xfs_ail_insert(ailp, lip); |
299 | mp->m_ail_gen++; | 374 | mp->m_ail.xa_gen++; |
300 | 375 | ||
301 | if (mlip == dlip) { | 376 | if (mlip == dlip) { |
302 | mlip = xfs_ail_min(&(mp->m_ail)); | 377 | mlip = xfs_ail_min(&(mp->m_ail.xa_ail)); |
303 | AIL_UNLOCK(mp, s); | 378 | spin_unlock(&mp->m_ail_lock); |
304 | xfs_log_move_tail(mp, mlip->li_lsn); | 379 | xfs_log_move_tail(mp, mlip->li_lsn); |
305 | } else { | 380 | } else { |
306 | AIL_UNLOCK(mp, s); | 381 | spin_unlock(&mp->m_ail_lock); |
307 | } | 382 | } |
308 | 383 | ||
309 | 384 | ||
@@ -322,21 +397,19 @@ xfs_trans_update_ail( | |||
322 | * has changed. | 397 | * has changed. |
323 | * | 398 | * |
324 | * This function must be called with the AIL lock held. The lock | 399 | * This function must be called with the AIL lock held. The lock |
325 | * is dropped before returning, so the caller must pass in the | 400 | * is dropped before returning. |
326 | * cookie returned by AIL_LOCK. | ||
327 | */ | 401 | */ |
328 | void | 402 | void |
329 | xfs_trans_delete_ail( | 403 | xfs_trans_delete_ail( |
330 | xfs_mount_t *mp, | 404 | xfs_mount_t *mp, |
331 | xfs_log_item_t *lip, | 405 | xfs_log_item_t *lip) __releases(mp->m_ail_lock) |
332 | unsigned long s) __releases(mp->m_ail_lock) | ||
333 | { | 406 | { |
334 | xfs_ail_entry_t *ailp; | 407 | xfs_ail_entry_t *ailp; |
335 | xfs_log_item_t *dlip; | 408 | xfs_log_item_t *dlip; |
336 | xfs_log_item_t *mlip; | 409 | xfs_log_item_t *mlip; |
337 | 410 | ||
338 | if (lip->li_flags & XFS_LI_IN_AIL) { | 411 | if (lip->li_flags & XFS_LI_IN_AIL) { |
339 | ailp = &(mp->m_ail); | 412 | ailp = &(mp->m_ail.xa_ail); |
340 | mlip = xfs_ail_min(ailp); | 413 | mlip = xfs_ail_min(ailp); |
341 | dlip = xfs_ail_delete(ailp, lip); | 414 | dlip = xfs_ail_delete(ailp, lip); |
342 | ASSERT(dlip == lip); | 415 | ASSERT(dlip == lip); |
@@ -344,14 +417,14 @@ xfs_trans_delete_ail( | |||
344 | 417 | ||
345 | lip->li_flags &= ~XFS_LI_IN_AIL; | 418 | lip->li_flags &= ~XFS_LI_IN_AIL; |
346 | lip->li_lsn = 0; | 419 | lip->li_lsn = 0; |
347 | mp->m_ail_gen++; | 420 | mp->m_ail.xa_gen++; |
348 | 421 | ||
349 | if (mlip == dlip) { | 422 | if (mlip == dlip) { |
350 | mlip = xfs_ail_min(&(mp->m_ail)); | 423 | mlip = xfs_ail_min(&(mp->m_ail.xa_ail)); |
351 | AIL_UNLOCK(mp, s); | 424 | spin_unlock(&mp->m_ail_lock); |
352 | xfs_log_move_tail(mp, (mlip ? mlip->li_lsn : 0)); | 425 | xfs_log_move_tail(mp, (mlip ? mlip->li_lsn : 0)); |
353 | } else { | 426 | } else { |
354 | AIL_UNLOCK(mp, s); | 427 | spin_unlock(&mp->m_ail_lock); |
355 | } | 428 | } |
356 | } | 429 | } |
357 | else { | 430 | else { |
@@ -360,12 +433,12 @@ xfs_trans_delete_ail( | |||
360 | * serious trouble if we get to this stage. | 433 | * serious trouble if we get to this stage. |
361 | */ | 434 | */ |
362 | if (XFS_FORCED_SHUTDOWN(mp)) | 435 | if (XFS_FORCED_SHUTDOWN(mp)) |
363 | AIL_UNLOCK(mp, s); | 436 | spin_unlock(&mp->m_ail_lock); |
364 | else { | 437 | else { |
365 | xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, | 438 | xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, |
366 | "%s: attempting to delete a log item that is not in the AIL", | 439 | "%s: attempting to delete a log item that is not in the AIL", |
367 | __FUNCTION__); | 440 | __FUNCTION__); |
368 | AIL_UNLOCK(mp, s); | 441 | spin_unlock(&mp->m_ail_lock); |
369 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 442 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
370 | } | 443 | } |
371 | } | 444 | } |
@@ -385,10 +458,10 @@ xfs_trans_first_ail( | |||
385 | { | 458 | { |
386 | xfs_log_item_t *lip; | 459 | xfs_log_item_t *lip; |
387 | 460 | ||
388 | lip = xfs_ail_min(&(mp->m_ail)); | 461 | lip = xfs_ail_min(&(mp->m_ail.xa_ail)); |
389 | *gen = (int)mp->m_ail_gen; | 462 | *gen = (int)mp->m_ail.xa_gen; |
390 | 463 | ||
391 | return (lip); | 464 | return lip; |
392 | } | 465 | } |
393 | 466 | ||
394 | /* | 467 | /* |
@@ -408,11 +481,11 @@ xfs_trans_next_ail( | |||
408 | xfs_log_item_t *nlip; | 481 | xfs_log_item_t *nlip; |
409 | 482 | ||
410 | ASSERT(mp && lip && gen); | 483 | ASSERT(mp && lip && gen); |
411 | if (mp->m_ail_gen == *gen) { | 484 | if (mp->m_ail.xa_gen == *gen) { |
412 | nlip = xfs_ail_next(&(mp->m_ail), lip); | 485 | nlip = xfs_ail_next(&(mp->m_ail.xa_ail), lip); |
413 | } else { | 486 | } else { |
414 | nlip = xfs_ail_min(&(mp->m_ail)); | 487 | nlip = xfs_ail_min(&(mp->m_ail).xa_ail); |
415 | *gen = (int)mp->m_ail_gen; | 488 | *gen = (int)mp->m_ail.xa_gen; |
416 | if (restarts != NULL) { | 489 | if (restarts != NULL) { |
417 | XFS_STATS_INC(xs_push_ail_restarts); | 490 | XFS_STATS_INC(xs_push_ail_restarts); |
418 | (*restarts)++; | 491 | (*restarts)++; |
@@ -437,12 +510,20 @@ xfs_trans_next_ail( | |||
437 | /* | 510 | /* |
438 | * Initialize the doubly linked list to point only to itself. | 511 | * Initialize the doubly linked list to point only to itself. |
439 | */ | 512 | */ |
440 | void | 513 | int |
441 | xfs_trans_ail_init( | 514 | xfs_trans_ail_init( |
442 | xfs_mount_t *mp) | 515 | xfs_mount_t *mp) |
443 | { | 516 | { |
444 | mp->m_ail.ail_forw = (xfs_log_item_t*)&(mp->m_ail); | 517 | mp->m_ail.xa_ail.ail_forw = (xfs_log_item_t*)&mp->m_ail.xa_ail; |
445 | mp->m_ail.ail_back = (xfs_log_item_t*)&(mp->m_ail); | 518 | mp->m_ail.xa_ail.ail_back = (xfs_log_item_t*)&mp->m_ail.xa_ail; |
519 | return xfsaild_start(mp); | ||
520 | } | ||
521 | |||
522 | void | ||
523 | xfs_trans_ail_destroy( | ||
524 | xfs_mount_t *mp) | ||
525 | { | ||
526 | xfsaild_stop(mp); | ||
446 | } | 527 | } |
447 | 528 | ||
448 | /* | 529 | /* |
@@ -482,7 +563,7 @@ xfs_ail_insert( | |||
482 | next_lip->li_ail.ail_forw = lip; | 563 | next_lip->li_ail.ail_forw = lip; |
483 | lip->li_ail.ail_forw->li_ail.ail_back = lip; | 564 | lip->li_ail.ail_forw->li_ail.ail_back = lip; |
484 | 565 | ||
485 | xfs_ail_check(base); | 566 | xfs_ail_check(base, lip); |
486 | return; | 567 | return; |
487 | } | 568 | } |
488 | 569 | ||
@@ -496,12 +577,12 @@ xfs_ail_delete( | |||
496 | xfs_log_item_t *lip) | 577 | xfs_log_item_t *lip) |
497 | /* ARGSUSED */ | 578 | /* ARGSUSED */ |
498 | { | 579 | { |
580 | xfs_ail_check(base, lip); | ||
499 | lip->li_ail.ail_forw->li_ail.ail_back = lip->li_ail.ail_back; | 581 | lip->li_ail.ail_forw->li_ail.ail_back = lip->li_ail.ail_back; |
500 | lip->li_ail.ail_back->li_ail.ail_forw = lip->li_ail.ail_forw; | 582 | lip->li_ail.ail_back->li_ail.ail_forw = lip->li_ail.ail_forw; |
501 | lip->li_ail.ail_forw = NULL; | 583 | lip->li_ail.ail_forw = NULL; |
502 | lip->li_ail.ail_back = NULL; | 584 | lip->li_ail.ail_back = NULL; |
503 | 585 | ||
504 | xfs_ail_check(base); | ||
505 | return lip; | 586 | return lip; |
506 | } | 587 | } |
507 | 588 | ||
@@ -545,13 +626,13 @@ xfs_ail_next( | |||
545 | */ | 626 | */ |
546 | STATIC void | 627 | STATIC void |
547 | xfs_ail_check( | 628 | xfs_ail_check( |
548 | xfs_ail_entry_t *base) | 629 | xfs_ail_entry_t *base, |
630 | xfs_log_item_t *lip) | ||
549 | { | 631 | { |
550 | xfs_log_item_t *lip; | ||
551 | xfs_log_item_t *prev_lip; | 632 | xfs_log_item_t *prev_lip; |
552 | 633 | ||
553 | lip = base->ail_forw; | 634 | prev_lip = base->ail_forw; |
554 | if (lip == (xfs_log_item_t*)base) { | 635 | if (prev_lip == (xfs_log_item_t*)base) { |
555 | /* | 636 | /* |
556 | * Make sure the pointers are correct when the list | 637 | * Make sure the pointers are correct when the list |
557 | * is empty. | 638 | * is empty. |
@@ -561,9 +642,27 @@ xfs_ail_check( | |||
561 | } | 642 | } |
562 | 643 | ||
563 | /* | 644 | /* |
645 | * Check the next and previous entries are valid. | ||
646 | */ | ||
647 | ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0); | ||
648 | prev_lip = lip->li_ail.ail_back; | ||
649 | if (prev_lip != (xfs_log_item_t*)base) { | ||
650 | ASSERT(prev_lip->li_ail.ail_forw == lip); | ||
651 | ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0); | ||
652 | } | ||
653 | prev_lip = lip->li_ail.ail_forw; | ||
654 | if (prev_lip != (xfs_log_item_t*)base) { | ||
655 | ASSERT(prev_lip->li_ail.ail_back == lip); | ||
656 | ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) >= 0); | ||
657 | } | ||
658 | |||
659 | |||
660 | #ifdef XFS_TRANS_DEBUG | ||
661 | /* | ||
564 | * Walk the list checking forward and backward pointers, | 662 | * Walk the list checking forward and backward pointers, |
565 | * lsn ordering, and that every entry has the XFS_LI_IN_AIL | 663 | * lsn ordering, and that every entry has the XFS_LI_IN_AIL |
566 | * flag set. | 664 | * flag set. This is really expensive, so only do it when |
665 | * specifically debugging the transaction subsystem. | ||
567 | */ | 666 | */ |
568 | prev_lip = (xfs_log_item_t*)base; | 667 | prev_lip = (xfs_log_item_t*)base; |
569 | while (lip != (xfs_log_item_t*)base) { | 668 | while (lip != (xfs_log_item_t*)base) { |
@@ -578,5 +677,6 @@ xfs_ail_check( | |||
578 | } | 677 | } |
579 | ASSERT(lip == (xfs_log_item_t*)base); | 678 | ASSERT(lip == (xfs_log_item_t*)base); |
580 | ASSERT(base->ail_back == prev_lip); | 679 | ASSERT(base->ail_back == prev_lip); |
680 | #endif /* XFS_TRANS_DEBUG */ | ||
581 | } | 681 | } |
582 | #endif /* DEBUG */ | 682 | #endif /* DEBUG */ |
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c index 2912aac07c7b..66a09f0d894b 100644 --- a/fs/xfs/xfs_trans_item.c +++ b/fs/xfs/xfs_trans_item.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "xfs_log.h" | 21 | #include "xfs_log.h" |
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_trans_priv.h" | ||
24 | 25 | ||
25 | STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *, | 26 | STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *, |
26 | int, int, xfs_lsn_t); | 27 | int, int, xfs_lsn_t); |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 447ac4308c91..3c748c456ed4 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -47,15 +47,22 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, | |||
47 | * From xfs_trans_ail.c | 47 | * From xfs_trans_ail.c |
48 | */ | 48 | */ |
49 | void xfs_trans_update_ail(struct xfs_mount *mp, | 49 | void xfs_trans_update_ail(struct xfs_mount *mp, |
50 | struct xfs_log_item *lip, xfs_lsn_t lsn, | 50 | struct xfs_log_item *lip, xfs_lsn_t lsn) |
51 | unsigned long s) | ||
52 | __releases(mp->m_ail_lock); | 51 | __releases(mp->m_ail_lock); |
53 | void xfs_trans_delete_ail(struct xfs_mount *mp, | 52 | void xfs_trans_delete_ail(struct xfs_mount *mp, |
54 | struct xfs_log_item *lip, unsigned long s) | 53 | struct xfs_log_item *lip) |
55 | __releases(mp->m_ail_lock); | 54 | __releases(mp->m_ail_lock); |
56 | struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); | 55 | struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); |
57 | struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, | 56 | struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, |
58 | struct xfs_log_item *, int *, int *); | 57 | struct xfs_log_item *, int *, int *); |
59 | 58 | ||
60 | 59 | ||
60 | /* | ||
61 | * AIL push thread support | ||
62 | */ | ||
63 | long xfsaild_push(struct xfs_mount *, xfs_lsn_t *); | ||
64 | void xfsaild_wakeup(struct xfs_mount *, xfs_lsn_t); | ||
65 | int xfsaild_start(struct xfs_mount *); | ||
66 | void xfsaild_stop(struct xfs_mount *); | ||
67 | |||
61 | #endif /* __XFS_TRANS_PRIV_H__ */ | 68 | #endif /* __XFS_TRANS_PRIV_H__ */ |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 673b405eaa31..45d740df53b7 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -73,7 +73,7 @@ xfs_dir_lookup_int( | |||
73 | { | 73 | { |
74 | int error; | 74 | int error; |
75 | 75 | ||
76 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 76 | xfs_itrace_entry(dp); |
77 | 77 | ||
78 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); | 78 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); |
79 | if (!error) { | 79 | if (!error) { |
@@ -302,6 +302,7 @@ xfs_droplink( | |||
302 | 302 | ||
303 | ASSERT (ip->i_d.di_nlink > 0); | 303 | ASSERT (ip->i_d.di_nlink > 0); |
304 | ip->i_d.di_nlink--; | 304 | ip->i_d.di_nlink--; |
305 | drop_nlink(ip->i_vnode); | ||
305 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 306 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
306 | 307 | ||
307 | error = 0; | 308 | error = 0; |
@@ -330,7 +331,6 @@ xfs_bump_ino_vers2( | |||
330 | xfs_inode_t *ip) | 331 | xfs_inode_t *ip) |
331 | { | 332 | { |
332 | xfs_mount_t *mp; | 333 | xfs_mount_t *mp; |
333 | unsigned long s; | ||
334 | 334 | ||
335 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 335 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); |
336 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1); | 336 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1); |
@@ -340,13 +340,13 @@ xfs_bump_ino_vers2( | |||
340 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 340 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
341 | mp = tp->t_mountp; | 341 | mp = tp->t_mountp; |
342 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 342 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { |
343 | s = XFS_SB_LOCK(mp); | 343 | spin_lock(&mp->m_sb_lock); |
344 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 344 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { |
345 | XFS_SB_VERSION_ADDNLINK(&mp->m_sb); | 345 | XFS_SB_VERSION_ADDNLINK(&mp->m_sb); |
346 | XFS_SB_UNLOCK(mp, s); | 346 | spin_unlock(&mp->m_sb_lock); |
347 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM); | 347 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM); |
348 | } else { | 348 | } else { |
349 | XFS_SB_UNLOCK(mp, s); | 349 | spin_unlock(&mp->m_sb_lock); |
350 | } | 350 | } |
351 | } | 351 | } |
352 | /* Caller must log the inode */ | 352 | /* Caller must log the inode */ |
@@ -366,6 +366,7 @@ xfs_bumplink( | |||
366 | 366 | ||
367 | ASSERT(ip->i_d.di_nlink > 0); | 367 | ASSERT(ip->i_d.di_nlink > 0); |
368 | ip->i_d.di_nlink++; | 368 | ip->i_d.di_nlink++; |
369 | inc_nlink(ip->i_vnode); | ||
369 | if ((ip->i_d.di_version == XFS_DINODE_VERSION_1) && | 370 | if ((ip->i_d.di_version == XFS_DINODE_VERSION_1) && |
370 | (ip->i_d.di_nlink > XFS_MAXLINK_1)) { | 371 | (ip->i_d.di_nlink > XFS_MAXLINK_1)) { |
371 | /* | 372 | /* |
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index a00b26d8840e..f857fcccb723 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h | |||
@@ -20,8 +20,6 @@ | |||
20 | 20 | ||
21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) | 21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) |
22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) | 22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) |
23 | #define ITRACE(ip) vn_trace_ref(ip, __FILE__, __LINE__, \ | ||
24 | (inst_t *)__return_address) | ||
25 | 23 | ||
26 | extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); | 24 | extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); |
27 | extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *, | 25 | extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *, |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index a1544597bcd3..413587f02155 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -58,17 +58,12 @@ | |||
58 | #include "xfs_vfsops.h" | 58 | #include "xfs_vfsops.h" |
59 | 59 | ||
60 | 60 | ||
61 | int | 61 | int __init |
62 | xfs_init(void) | 62 | xfs_init(void) |
63 | { | 63 | { |
64 | extern kmem_zone_t *xfs_bmap_free_item_zone; | ||
65 | extern kmem_zone_t *xfs_btree_cur_zone; | ||
66 | extern kmem_zone_t *xfs_trans_zone; | ||
67 | extern kmem_zone_t *xfs_buf_item_zone; | ||
68 | extern kmem_zone_t *xfs_dabuf_zone; | ||
69 | #ifdef XFS_DABUF_DEBUG | 64 | #ifdef XFS_DABUF_DEBUG |
70 | extern lock_t xfs_dabuf_global_lock; | 65 | extern spinlock_t xfs_dabuf_global_lock; |
71 | spinlock_init(&xfs_dabuf_global_lock, "xfsda"); | 66 | spin_lock_init(&xfs_dabuf_global_lock); |
72 | #endif | 67 | #endif |
73 | 68 | ||
74 | /* | 69 | /* |
@@ -152,18 +147,12 @@ xfs_init(void) | |||
152 | return 0; | 147 | return 0; |
153 | } | 148 | } |
154 | 149 | ||
155 | void | 150 | void __exit |
156 | xfs_cleanup(void) | 151 | xfs_cleanup(void) |
157 | { | 152 | { |
158 | extern kmem_zone_t *xfs_bmap_free_item_zone; | ||
159 | extern kmem_zone_t *xfs_btree_cur_zone; | ||
160 | extern kmem_zone_t *xfs_inode_zone; | 153 | extern kmem_zone_t *xfs_inode_zone; |
161 | extern kmem_zone_t *xfs_trans_zone; | ||
162 | extern kmem_zone_t *xfs_da_state_zone; | ||
163 | extern kmem_zone_t *xfs_dabuf_zone; | ||
164 | extern kmem_zone_t *xfs_efd_zone; | 154 | extern kmem_zone_t *xfs_efd_zone; |
165 | extern kmem_zone_t *xfs_efi_zone; | 155 | extern kmem_zone_t *xfs_efi_zone; |
166 | extern kmem_zone_t *xfs_buf_item_zone; | ||
167 | extern kmem_zone_t *xfs_icluster_zone; | 156 | extern kmem_zone_t *xfs_icluster_zone; |
168 | 157 | ||
169 | xfs_cleanup_procfs(); | 158 | xfs_cleanup_procfs(); |
@@ -449,8 +438,6 @@ xfs_mount( | |||
449 | if (error) | 438 | if (error) |
450 | return error; | 439 | return error; |
451 | 440 | ||
452 | mp->m_io_ops = xfs_iocore_xfs; | ||
453 | |||
454 | if (args->flags & XFSMNT_QUIET) | 441 | if (args->flags & XFSMNT_QUIET) |
455 | flags |= XFS_MFSI_QUIET; | 442 | flags |= XFS_MFSI_QUIET; |
456 | 443 | ||
@@ -544,7 +531,7 @@ xfs_mount( | |||
544 | if ((error = xfs_filestream_mount(mp))) | 531 | if ((error = xfs_filestream_mount(mp))) |
545 | goto error2; | 532 | goto error2; |
546 | 533 | ||
547 | error = XFS_IOINIT(mp, args, flags); | 534 | error = xfs_mountfs(mp, flags); |
548 | if (error) | 535 | if (error) |
549 | goto error2; | 536 | goto error2; |
550 | 537 | ||
@@ -694,7 +681,7 @@ xfs_quiesce_fs( | |||
694 | * care of the metadata. New transactions are already blocked, so we need to | 681 | * care of the metadata. New transactions are already blocked, so we need to |
695 | * wait for any remaining transactions to drain out before proceding. | 682 | * wait for any remaining transactions to drain out before proceding. |
696 | */ | 683 | */ |
697 | STATIC void | 684 | void |
698 | xfs_attr_quiesce( | 685 | xfs_attr_quiesce( |
699 | xfs_mount_t *mp) | 686 | xfs_mount_t *mp) |
700 | { | 687 | { |
@@ -821,80 +808,6 @@ fscorrupt_out2: | |||
821 | } | 808 | } |
822 | 809 | ||
823 | /* | 810 | /* |
824 | * xfs_root extracts the root vnode from a vfs. | ||
825 | * | ||
826 | * vfsp -- the vfs struct for the desired file system | ||
827 | * vpp -- address of the caller's vnode pointer which should be | ||
828 | * set to the desired fs root vnode | ||
829 | */ | ||
830 | int | ||
831 | xfs_root( | ||
832 | xfs_mount_t *mp, | ||
833 | bhv_vnode_t **vpp) | ||
834 | { | ||
835 | bhv_vnode_t *vp; | ||
836 | |||
837 | vp = XFS_ITOV(mp->m_rootip); | ||
838 | VN_HOLD(vp); | ||
839 | *vpp = vp; | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | /* | ||
844 | * xfs_statvfs | ||
845 | * | ||
846 | * Fill in the statvfs structure for the given file system. We use | ||
847 | * the superblock lock in the mount structure to ensure a consistent | ||
848 | * snapshot of the counters returned. | ||
849 | */ | ||
850 | int | ||
851 | xfs_statvfs( | ||
852 | xfs_mount_t *mp, | ||
853 | bhv_statvfs_t *statp, | ||
854 | bhv_vnode_t *vp) | ||
855 | { | ||
856 | __uint64_t fakeinos; | ||
857 | xfs_extlen_t lsize; | ||
858 | xfs_sb_t *sbp; | ||
859 | unsigned long s; | ||
860 | |||
861 | sbp = &(mp->m_sb); | ||
862 | |||
863 | statp->f_type = XFS_SB_MAGIC; | ||
864 | |||
865 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); | ||
866 | s = XFS_SB_LOCK(mp); | ||
867 | statp->f_bsize = sbp->sb_blocksize; | ||
868 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | ||
869 | statp->f_blocks = sbp->sb_dblocks - lsize; | ||
870 | statp->f_bfree = statp->f_bavail = | ||
871 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | ||
872 | fakeinos = statp->f_bfree << sbp->sb_inopblog; | ||
873 | #if XFS_BIG_INUMS | ||
874 | fakeinos += mp->m_inoadd; | ||
875 | #endif | ||
876 | statp->f_files = | ||
877 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); | ||
878 | if (mp->m_maxicount) | ||
879 | #if XFS_BIG_INUMS | ||
880 | if (!mp->m_inoadd) | ||
881 | #endif | ||
882 | statp->f_files = min_t(typeof(statp->f_files), | ||
883 | statp->f_files, | ||
884 | mp->m_maxicount); | ||
885 | statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | ||
886 | XFS_SB_UNLOCK(mp, s); | ||
887 | |||
888 | xfs_statvfs_fsid(statp, mp); | ||
889 | statp->f_namelen = MAXNAMELEN - 1; | ||
890 | |||
891 | if (vp) | ||
892 | XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp); | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | |||
897 | /* | ||
898 | * xfs_sync flushes any pending I/O to file system vfsp. | 811 | * xfs_sync flushes any pending I/O to file system vfsp. |
899 | * | 812 | * |
900 | * This routine is called by vfs_sync() to make sure that things make it | 813 | * This routine is called by vfs_sync() to make sure that things make it |
@@ -981,8 +894,6 @@ xfs_sync_inodes( | |||
981 | int *bypassed) | 894 | int *bypassed) |
982 | { | 895 | { |
983 | xfs_inode_t *ip = NULL; | 896 | xfs_inode_t *ip = NULL; |
984 | xfs_inode_t *ip_next; | ||
985 | xfs_buf_t *bp; | ||
986 | bhv_vnode_t *vp = NULL; | 897 | bhv_vnode_t *vp = NULL; |
987 | int error; | 898 | int error; |
988 | int last_error; | 899 | int last_error; |
@@ -992,7 +903,6 @@ xfs_sync_inodes( | |||
992 | boolean_t mount_locked; | 903 | boolean_t mount_locked; |
993 | boolean_t vnode_refed; | 904 | boolean_t vnode_refed; |
994 | int preempt; | 905 | int preempt; |
995 | xfs_dinode_t *dip; | ||
996 | xfs_iptr_t *ipointer; | 906 | xfs_iptr_t *ipointer; |
997 | #ifdef DEBUG | 907 | #ifdef DEBUG |
998 | boolean_t ipointer_in = B_FALSE; | 908 | boolean_t ipointer_in = B_FALSE; |
@@ -1045,6 +955,8 @@ xfs_sync_inodes( | |||
1045 | 955 | ||
1046 | #define XFS_PREEMPT_MASK 0x7f | 956 | #define XFS_PREEMPT_MASK 0x7f |
1047 | 957 | ||
958 | ASSERT(!(flags & SYNC_BDFLUSH)); | ||
959 | |||
1048 | if (bypassed) | 960 | if (bypassed) |
1049 | *bypassed = 0; | 961 | *bypassed = 0; |
1050 | if (mp->m_flags & XFS_MOUNT_RDONLY) | 962 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
@@ -1057,7 +969,7 @@ xfs_sync_inodes( | |||
1057 | ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP); | 969 | ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP); |
1058 | 970 | ||
1059 | fflag = XFS_B_ASYNC; /* default is don't wait */ | 971 | fflag = XFS_B_ASYNC; /* default is don't wait */ |
1060 | if (flags & (SYNC_BDFLUSH | SYNC_DELWRI)) | 972 | if (flags & SYNC_DELWRI) |
1061 | fflag = XFS_B_DELWRI; | 973 | fflag = XFS_B_DELWRI; |
1062 | if (flags & SYNC_WAIT) | 974 | if (flags & SYNC_WAIT) |
1063 | fflag = 0; /* synchronous overrides all */ | 975 | fflag = 0; /* synchronous overrides all */ |
@@ -1147,24 +1059,6 @@ xfs_sync_inodes( | |||
1147 | } | 1059 | } |
1148 | 1060 | ||
1149 | /* | 1061 | /* |
1150 | * If this is just vfs_sync() or pflushd() calling | ||
1151 | * then we can skip inodes for which it looks like | ||
1152 | * there is nothing to do. Since we don't have the | ||
1153 | * inode locked this is racy, but these are periodic | ||
1154 | * calls so it doesn't matter. For the others we want | ||
1155 | * to know for sure, so we at least try to lock them. | ||
1156 | */ | ||
1157 | if (flags & SYNC_BDFLUSH) { | ||
1158 | if (((ip->i_itemp == NULL) || | ||
1159 | !(ip->i_itemp->ili_format.ilf_fields & | ||
1160 | XFS_ILOG_ALL)) && | ||
1161 | (ip->i_update_core == 0)) { | ||
1162 | ip = ip->i_mnext; | ||
1163 | continue; | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * Try to lock without sleeping. We're out of order with | 1062 | * Try to lock without sleeping. We're out of order with |
1169 | * the inode list lock here, so if we fail we need to drop | 1063 | * the inode list lock here, so if we fail we need to drop |
1170 | * the mount lock and try again. If we're called from | 1064 | * the mount lock and try again. If we're called from |
@@ -1181,7 +1075,7 @@ xfs_sync_inodes( | |||
1181 | * it. | 1075 | * it. |
1182 | */ | 1076 | */ |
1183 | if (xfs_ilock_nowait(ip, lock_flags) == 0) { | 1077 | if (xfs_ilock_nowait(ip, lock_flags) == 0) { |
1184 | if ((flags & SYNC_BDFLUSH) || (vp == NULL)) { | 1078 | if (vp == NULL) { |
1185 | ip = ip->i_mnext; | 1079 | ip = ip->i_mnext; |
1186 | continue; | 1080 | continue; |
1187 | } | 1081 | } |
@@ -1242,160 +1136,27 @@ xfs_sync_inodes( | |||
1242 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1136 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1243 | } | 1137 | } |
1244 | 1138 | ||
1245 | if (flags & SYNC_BDFLUSH) { | 1139 | if ((flags & SYNC_ATTR) && |
1246 | if ((flags & SYNC_ATTR) && | 1140 | (ip->i_update_core || |
1247 | ((ip->i_update_core) || | 1141 | (ip->i_itemp && ip->i_itemp->ili_format.ilf_fields))) { |
1248 | ((ip->i_itemp != NULL) && | 1142 | if (mount_locked) |
1249 | (ip->i_itemp->ili_format.ilf_fields != 0)))) { | 1143 | IPOINTER_INSERT(ip, mp); |
1250 | |||
1251 | /* Insert marker and drop lock if not already | ||
1252 | * done. | ||
1253 | */ | ||
1254 | if (mount_locked) { | ||
1255 | IPOINTER_INSERT(ip, mp); | ||
1256 | } | ||
1257 | |||
1258 | /* | ||
1259 | * We don't want the periodic flushing of the | ||
1260 | * inodes by vfs_sync() to interfere with | ||
1261 | * I/O to the file, especially read I/O | ||
1262 | * where it is only the access time stamp | ||
1263 | * that is being flushed out. To prevent | ||
1264 | * long periods where we have both inode | ||
1265 | * locks held shared here while reading the | ||
1266 | * inode's buffer in from disk, we drop the | ||
1267 | * inode lock while reading in the inode | ||
1268 | * buffer. We have to release the buffer | ||
1269 | * and reacquire the inode lock so that they | ||
1270 | * are acquired in the proper order (inode | ||
1271 | * locks first). The buffer will go at the | ||
1272 | * end of the lru chain, though, so we can | ||
1273 | * expect it to still be there when we go | ||
1274 | * for it again in xfs_iflush(). | ||
1275 | */ | ||
1276 | if ((xfs_ipincount(ip) == 0) && | ||
1277 | xfs_iflock_nowait(ip)) { | ||
1278 | |||
1279 | xfs_ifunlock(ip); | ||
1280 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1281 | |||
1282 | error = xfs_itobp(mp, NULL, ip, | ||
1283 | &dip, &bp, 0, 0); | ||
1284 | if (!error) { | ||
1285 | xfs_buf_relse(bp); | ||
1286 | } else { | ||
1287 | /* Bailing out, remove the | ||
1288 | * marker and free it. | ||
1289 | */ | ||
1290 | XFS_MOUNT_ILOCK(mp); | ||
1291 | IPOINTER_REMOVE(ip, mp); | ||
1292 | XFS_MOUNT_IUNLOCK(mp); | ||
1293 | |||
1294 | ASSERT(!(lock_flags & | ||
1295 | XFS_IOLOCK_SHARED)); | ||
1296 | |||
1297 | kmem_free(ipointer, | ||
1298 | sizeof(xfs_iptr_t)); | ||
1299 | return (0); | ||
1300 | } | ||
1301 | |||
1302 | /* | ||
1303 | * Since we dropped the inode lock, | ||
1304 | * the inode may have been reclaimed. | ||
1305 | * Therefore, we reacquire the mount | ||
1306 | * lock and check to see if we were the | ||
1307 | * inode reclaimed. If this happened | ||
1308 | * then the ipointer marker will no | ||
1309 | * longer point back at us. In this | ||
1310 | * case, move ip along to the inode | ||
1311 | * after the marker, remove the marker | ||
1312 | * and continue. | ||
1313 | */ | ||
1314 | XFS_MOUNT_ILOCK(mp); | ||
1315 | mount_locked = B_TRUE; | ||
1316 | |||
1317 | if (ip != ipointer->ip_mprev) { | ||
1318 | IPOINTER_REMOVE(ip, mp); | ||
1319 | |||
1320 | ASSERT(!vnode_refed); | ||
1321 | ASSERT(!(lock_flags & | ||
1322 | XFS_IOLOCK_SHARED)); | ||
1323 | continue; | ||
1324 | } | ||
1325 | |||
1326 | ASSERT(ip->i_mount == mp); | ||
1327 | |||
1328 | if (xfs_ilock_nowait(ip, | ||
1329 | XFS_ILOCK_SHARED) == 0) { | ||
1330 | ASSERT(ip->i_mount == mp); | ||
1331 | /* | ||
1332 | * We failed to reacquire | ||
1333 | * the inode lock without | ||
1334 | * sleeping, so just skip | ||
1335 | * the inode for now. We | ||
1336 | * clear the ILOCK bit from | ||
1337 | * the lock_flags so that we | ||
1338 | * won't try to drop a lock | ||
1339 | * we don't hold below. | ||
1340 | */ | ||
1341 | lock_flags &= ~XFS_ILOCK_SHARED; | ||
1342 | IPOINTER_REMOVE(ip_next, mp); | ||
1343 | } else if ((xfs_ipincount(ip) == 0) && | ||
1344 | xfs_iflock_nowait(ip)) { | ||
1345 | ASSERT(ip->i_mount == mp); | ||
1346 | /* | ||
1347 | * Since this is vfs_sync() | ||
1348 | * calling we only flush the | ||
1349 | * inode out if we can lock | ||
1350 | * it without sleeping and | ||
1351 | * it is not pinned. Drop | ||
1352 | * the mount lock here so | ||
1353 | * that we don't hold it for | ||
1354 | * too long. We already have | ||
1355 | * a marker in the list here. | ||
1356 | */ | ||
1357 | XFS_MOUNT_IUNLOCK(mp); | ||
1358 | mount_locked = B_FALSE; | ||
1359 | error = xfs_iflush(ip, | ||
1360 | XFS_IFLUSH_DELWRI); | ||
1361 | } else { | ||
1362 | ASSERT(ip->i_mount == mp); | ||
1363 | IPOINTER_REMOVE(ip_next, mp); | ||
1364 | } | ||
1365 | } | ||
1366 | |||
1367 | } | ||
1368 | 1144 | ||
1369 | } else { | 1145 | if (flags & SYNC_WAIT) { |
1370 | if ((flags & SYNC_ATTR) && | 1146 | xfs_iflock(ip); |
1371 | ((ip->i_update_core) || | 1147 | error = xfs_iflush(ip, XFS_IFLUSH_SYNC); |
1372 | ((ip->i_itemp != NULL) && | ||
1373 | (ip->i_itemp->ili_format.ilf_fields != 0)))) { | ||
1374 | if (mount_locked) { | ||
1375 | IPOINTER_INSERT(ip, mp); | ||
1376 | } | ||
1377 | 1148 | ||
1378 | if (flags & SYNC_WAIT) { | 1149 | /* |
1379 | xfs_iflock(ip); | 1150 | * If we can't acquire the flush lock, then the inode |
1380 | error = xfs_iflush(ip, | 1151 | * is already being flushed so don't bother waiting. |
1381 | XFS_IFLUSH_SYNC); | 1152 | * |
1382 | } else { | 1153 | * If we can lock it then do a delwri flush so we can |
1383 | /* | 1154 | * combine multiple inode flushes in each disk write. |
1384 | * If we can't acquire the flush | 1155 | */ |
1385 | * lock, then the inode is already | 1156 | } else if (xfs_iflock_nowait(ip)) { |
1386 | * being flushed so don't bother | 1157 | error = xfs_iflush(ip, XFS_IFLUSH_DELWRI); |
1387 | * waiting. If we can lock it then | 1158 | } else if (bypassed) { |
1388 | * do a delwri flush so we can | 1159 | (*bypassed)++; |
1389 | * combine multiple inode flushes | ||
1390 | * in each disk write. | ||
1391 | */ | ||
1392 | if (xfs_iflock_nowait(ip)) { | ||
1393 | error = xfs_iflush(ip, | ||
1394 | XFS_IFLUSH_DELWRI); | ||
1395 | } | ||
1396 | else if (bypassed) | ||
1397 | (*bypassed)++; | ||
1398 | } | ||
1399 | } | 1160 | } |
1400 | } | 1161 | } |
1401 | 1162 | ||
@@ -1627,499 +1388,3 @@ xfs_syncsub( | |||
1627 | 1388 | ||
1628 | return XFS_ERROR(last_error); | 1389 | return XFS_ERROR(last_error); |
1629 | } | 1390 | } |
1630 | |||
1631 | /* | ||
1632 | * xfs_vget - called by DMAPI and NFSD to get vnode from file handle | ||
1633 | */ | ||
1634 | int | ||
1635 | xfs_vget( | ||
1636 | xfs_mount_t *mp, | ||
1637 | bhv_vnode_t **vpp, | ||
1638 | xfs_fid_t *xfid) | ||
1639 | { | ||
1640 | xfs_inode_t *ip; | ||
1641 | int error; | ||
1642 | xfs_ino_t ino; | ||
1643 | unsigned int igen; | ||
1644 | |||
1645 | /* | ||
1646 | * Invalid. Since handles can be created in user space and passed in | ||
1647 | * via gethandle(), this is not cause for a panic. | ||
1648 | */ | ||
1649 | if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len)) | ||
1650 | return XFS_ERROR(EINVAL); | ||
1651 | |||
1652 | ino = xfid->fid_ino; | ||
1653 | igen = xfid->fid_gen; | ||
1654 | |||
1655 | /* | ||
1656 | * NFS can sometimes send requests for ino 0. Fail them gracefully. | ||
1657 | */ | ||
1658 | if (ino == 0) | ||
1659 | return XFS_ERROR(ESTALE); | ||
1660 | |||
1661 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); | ||
1662 | if (error) { | ||
1663 | *vpp = NULL; | ||
1664 | return error; | ||
1665 | } | ||
1666 | |||
1667 | if (ip == NULL) { | ||
1668 | *vpp = NULL; | ||
1669 | return XFS_ERROR(EIO); | ||
1670 | } | ||
1671 | |||
1672 | if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) { | ||
1673 | xfs_iput_new(ip, XFS_ILOCK_SHARED); | ||
1674 | *vpp = NULL; | ||
1675 | return XFS_ERROR(ENOENT); | ||
1676 | } | ||
1677 | |||
1678 | *vpp = XFS_ITOV(ip); | ||
1679 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | |||
1684 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | ||
1685 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | ||
1686 | #define MNTOPT_LOGDEV "logdev" /* log device */ | ||
1687 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ | ||
1688 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ | ||
1689 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ | ||
1690 | #define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */ | ||
1691 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ | ||
1692 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ | ||
1693 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ | ||
1694 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | ||
1695 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | ||
1696 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | ||
1697 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ | ||
1698 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ | ||
1699 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | ||
1700 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | ||
1701 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | ||
1702 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | ||
1703 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | ||
1704 | * unwritten extent conversion */ | ||
1705 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | ||
1706 | #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ | ||
1707 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | ||
1708 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | ||
1709 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | ||
1710 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ | ||
1711 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes | ||
1712 | * in stat(). */ | ||
1713 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | ||
1714 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | ||
1715 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | ||
1716 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | ||
1717 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | ||
1718 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | ||
1719 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | ||
1720 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
1721 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | ||
1722 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | ||
1723 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
1724 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | ||
1725 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | ||
1726 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
1727 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | ||
1728 | #define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ | ||
1729 | #define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ | ||
1730 | #define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ | ||
1731 | |||
1732 | STATIC unsigned long | ||
1733 | suffix_strtoul(char *s, char **endp, unsigned int base) | ||
1734 | { | ||
1735 | int last, shift_left_factor = 0; | ||
1736 | char *value = s; | ||
1737 | |||
1738 | last = strlen(value) - 1; | ||
1739 | if (value[last] == 'K' || value[last] == 'k') { | ||
1740 | shift_left_factor = 10; | ||
1741 | value[last] = '\0'; | ||
1742 | } | ||
1743 | if (value[last] == 'M' || value[last] == 'm') { | ||
1744 | shift_left_factor = 20; | ||
1745 | value[last] = '\0'; | ||
1746 | } | ||
1747 | if (value[last] == 'G' || value[last] == 'g') { | ||
1748 | shift_left_factor = 30; | ||
1749 | value[last] = '\0'; | ||
1750 | } | ||
1751 | |||
1752 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; | ||
1753 | } | ||
1754 | |||
1755 | int | ||
1756 | xfs_parseargs( | ||
1757 | struct xfs_mount *mp, | ||
1758 | char *options, | ||
1759 | struct xfs_mount_args *args, | ||
1760 | int update) | ||
1761 | { | ||
1762 | char *this_char, *value, *eov; | ||
1763 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | ||
1764 | int iosize; | ||
1765 | int ikeep = 0; | ||
1766 | |||
1767 | args->flags |= XFSMNT_BARRIER; | ||
1768 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | ||
1769 | |||
1770 | if (!options) | ||
1771 | goto done; | ||
1772 | |||
1773 | iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0; | ||
1774 | |||
1775 | while ((this_char = strsep(&options, ",")) != NULL) { | ||
1776 | if (!*this_char) | ||
1777 | continue; | ||
1778 | if ((value = strchr(this_char, '=')) != NULL) | ||
1779 | *value++ = 0; | ||
1780 | |||
1781 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | ||
1782 | if (!value || !*value) { | ||
1783 | cmn_err(CE_WARN, | ||
1784 | "XFS: %s option requires an argument", | ||
1785 | this_char); | ||
1786 | return EINVAL; | ||
1787 | } | ||
1788 | args->logbufs = simple_strtoul(value, &eov, 10); | ||
1789 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | ||
1790 | if (!value || !*value) { | ||
1791 | cmn_err(CE_WARN, | ||
1792 | "XFS: %s option requires an argument", | ||
1793 | this_char); | ||
1794 | return EINVAL; | ||
1795 | } | ||
1796 | args->logbufsize = suffix_strtoul(value, &eov, 10); | ||
1797 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | ||
1798 | if (!value || !*value) { | ||
1799 | cmn_err(CE_WARN, | ||
1800 | "XFS: %s option requires an argument", | ||
1801 | this_char); | ||
1802 | return EINVAL; | ||
1803 | } | ||
1804 | strncpy(args->logname, value, MAXNAMELEN); | ||
1805 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | ||
1806 | if (!value || !*value) { | ||
1807 | cmn_err(CE_WARN, | ||
1808 | "XFS: %s option requires an argument", | ||
1809 | this_char); | ||
1810 | return EINVAL; | ||
1811 | } | ||
1812 | strncpy(args->mtpt, value, MAXNAMELEN); | ||
1813 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | ||
1814 | if (!value || !*value) { | ||
1815 | cmn_err(CE_WARN, | ||
1816 | "XFS: %s option requires an argument", | ||
1817 | this_char); | ||
1818 | return EINVAL; | ||
1819 | } | ||
1820 | strncpy(args->rtname, value, MAXNAMELEN); | ||
1821 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | ||
1822 | if (!value || !*value) { | ||
1823 | cmn_err(CE_WARN, | ||
1824 | "XFS: %s option requires an argument", | ||
1825 | this_char); | ||
1826 | return EINVAL; | ||
1827 | } | ||
1828 | iosize = simple_strtoul(value, &eov, 10); | ||
1829 | args->flags |= XFSMNT_IOSIZE; | ||
1830 | args->iosizelog = (uint8_t) iosize; | ||
1831 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | ||
1832 | if (!value || !*value) { | ||
1833 | cmn_err(CE_WARN, | ||
1834 | "XFS: %s option requires an argument", | ||
1835 | this_char); | ||
1836 | return EINVAL; | ||
1837 | } | ||
1838 | iosize = suffix_strtoul(value, &eov, 10); | ||
1839 | args->flags |= XFSMNT_IOSIZE; | ||
1840 | args->iosizelog = ffs(iosize) - 1; | ||
1841 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | ||
1842 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | ||
1843 | mp->m_flags |= XFS_MOUNT_GRPID; | ||
1844 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | ||
1845 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | ||
1846 | mp->m_flags &= ~XFS_MOUNT_GRPID; | ||
1847 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | ||
1848 | args->flags |= XFSMNT_WSYNC; | ||
1849 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { | ||
1850 | args->flags |= XFSMNT_OSYNCISOSYNC; | ||
1851 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | ||
1852 | args->flags |= XFSMNT_NORECOVERY; | ||
1853 | } else if (!strcmp(this_char, MNTOPT_INO64)) { | ||
1854 | args->flags |= XFSMNT_INO64; | ||
1855 | #if !XFS_BIG_INUMS | ||
1856 | cmn_err(CE_WARN, | ||
1857 | "XFS: %s option not allowed on this system", | ||
1858 | this_char); | ||
1859 | return EINVAL; | ||
1860 | #endif | ||
1861 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | ||
1862 | args->flags |= XFSMNT_NOALIGN; | ||
1863 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | ||
1864 | args->flags |= XFSMNT_SWALLOC; | ||
1865 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | ||
1866 | if (!value || !*value) { | ||
1867 | cmn_err(CE_WARN, | ||
1868 | "XFS: %s option requires an argument", | ||
1869 | this_char); | ||
1870 | return EINVAL; | ||
1871 | } | ||
1872 | dsunit = simple_strtoul(value, &eov, 10); | ||
1873 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | ||
1874 | if (!value || !*value) { | ||
1875 | cmn_err(CE_WARN, | ||
1876 | "XFS: %s option requires an argument", | ||
1877 | this_char); | ||
1878 | return EINVAL; | ||
1879 | } | ||
1880 | dswidth = simple_strtoul(value, &eov, 10); | ||
1881 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | ||
1882 | args->flags &= ~XFSMNT_32BITINODES; | ||
1883 | #if !XFS_BIG_INUMS | ||
1884 | cmn_err(CE_WARN, | ||
1885 | "XFS: %s option not allowed on this system", | ||
1886 | this_char); | ||
1887 | return EINVAL; | ||
1888 | #endif | ||
1889 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | ||
1890 | args->flags |= XFSMNT_NOUUID; | ||
1891 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | ||
1892 | args->flags |= XFSMNT_BARRIER; | ||
1893 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | ||
1894 | args->flags &= ~XFSMNT_BARRIER; | ||
1895 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | ||
1896 | ikeep = 1; | ||
1897 | args->flags &= ~XFSMNT_IDELETE; | ||
1898 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | ||
1899 | args->flags |= XFSMNT_IDELETE; | ||
1900 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | ||
1901 | args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; | ||
1902 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | ||
1903 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | ||
1904 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | ||
1905 | args->flags |= XFSMNT_ATTR2; | ||
1906 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | ||
1907 | args->flags &= ~XFSMNT_ATTR2; | ||
1908 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | ||
1909 | args->flags2 |= XFSMNT2_FILESTREAMS; | ||
1910 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | ||
1911 | args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); | ||
1912 | args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); | ||
1913 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | ||
1914 | !strcmp(this_char, MNTOPT_UQUOTA) || | ||
1915 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | ||
1916 | args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; | ||
1917 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | ||
1918 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | ||
1919 | args->flags |= XFSMNT_UQUOTA; | ||
1920 | args->flags &= ~XFSMNT_UQUOTAENF; | ||
1921 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
1922 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
1923 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
1924 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
1925 | args->flags |= XFSMNT_PQUOTA; | ||
1926 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
1927 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | ||
1928 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | ||
1929 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | ||
1930 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | ||
1931 | args->flags |= XFSMNT_GQUOTA; | ||
1932 | args->flags &= ~XFSMNT_GQUOTAENF; | ||
1933 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { | ||
1934 | args->flags |= XFSMNT_DMAPI; | ||
1935 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { | ||
1936 | args->flags |= XFSMNT_DMAPI; | ||
1937 | } else if (!strcmp(this_char, MNTOPT_DMI)) { | ||
1938 | args->flags |= XFSMNT_DMAPI; | ||
1939 | } else if (!strcmp(this_char, "ihashsize")) { | ||
1940 | cmn_err(CE_WARN, | ||
1941 | "XFS: ihashsize no longer used, option is deprecated."); | ||
1942 | } else if (!strcmp(this_char, "osyncisdsync")) { | ||
1943 | /* no-op, this is now the default */ | ||
1944 | cmn_err(CE_WARN, | ||
1945 | "XFS: osyncisdsync is now the default, option is deprecated."); | ||
1946 | } else if (!strcmp(this_char, "irixsgid")) { | ||
1947 | cmn_err(CE_WARN, | ||
1948 | "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); | ||
1949 | } else { | ||
1950 | cmn_err(CE_WARN, | ||
1951 | "XFS: unknown mount option [%s].", this_char); | ||
1952 | return EINVAL; | ||
1953 | } | ||
1954 | } | ||
1955 | |||
1956 | if (args->flags & XFSMNT_NORECOVERY) { | ||
1957 | if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) { | ||
1958 | cmn_err(CE_WARN, | ||
1959 | "XFS: no-recovery mounts must be read-only."); | ||
1960 | return EINVAL; | ||
1961 | } | ||
1962 | } | ||
1963 | |||
1964 | if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { | ||
1965 | cmn_err(CE_WARN, | ||
1966 | "XFS: sunit and swidth options incompatible with the noalign option"); | ||
1967 | return EINVAL; | ||
1968 | } | ||
1969 | |||
1970 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
1971 | cmn_err(CE_WARN, | ||
1972 | "XFS: cannot mount with both project and group quota"); | ||
1973 | return EINVAL; | ||
1974 | } | ||
1975 | |||
1976 | if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { | ||
1977 | printk("XFS: %s option needs the mount point option as well\n", | ||
1978 | MNTOPT_DMAPI); | ||
1979 | return EINVAL; | ||
1980 | } | ||
1981 | |||
1982 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | ||
1983 | cmn_err(CE_WARN, | ||
1984 | "XFS: sunit and swidth must be specified together"); | ||
1985 | return EINVAL; | ||
1986 | } | ||
1987 | |||
1988 | if (dsunit && (dswidth % dsunit != 0)) { | ||
1989 | cmn_err(CE_WARN, | ||
1990 | "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)", | ||
1991 | dswidth, dsunit); | ||
1992 | return EINVAL; | ||
1993 | } | ||
1994 | |||
1995 | /* | ||
1996 | * Applications using DMI filesystems often expect the | ||
1997 | * inode generation number to be monotonically increasing. | ||
1998 | * If we delete inode chunks we break this assumption, so | ||
1999 | * keep unused inode chunks on disk for DMI filesystems | ||
2000 | * until we come up with a better solution. | ||
2001 | * Note that if "ikeep" or "noikeep" mount options are | ||
2002 | * supplied, then they are honored. | ||
2003 | */ | ||
2004 | if (!(args->flags & XFSMNT_DMAPI) && !ikeep) | ||
2005 | args->flags |= XFSMNT_IDELETE; | ||
2006 | |||
2007 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
2008 | if (dsunit) { | ||
2009 | args->sunit = dsunit; | ||
2010 | args->flags |= XFSMNT_RETERR; | ||
2011 | } else { | ||
2012 | args->sunit = vol_dsunit; | ||
2013 | } | ||
2014 | dswidth ? (args->swidth = dswidth) : | ||
2015 | (args->swidth = vol_dswidth); | ||
2016 | } else { | ||
2017 | args->sunit = args->swidth = 0; | ||
2018 | } | ||
2019 | |||
2020 | done: | ||
2021 | if (args->flags & XFSMNT_32BITINODES) | ||
2022 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | ||
2023 | if (args->flags2) | ||
2024 | args->flags |= XFSMNT_FLAGS2; | ||
2025 | return 0; | ||
2026 | } | ||
2027 | |||
2028 | int | ||
2029 | xfs_showargs( | ||
2030 | struct xfs_mount *mp, | ||
2031 | struct seq_file *m) | ||
2032 | { | ||
2033 | static struct proc_xfs_info { | ||
2034 | int flag; | ||
2035 | char *str; | ||
2036 | } xfs_info[] = { | ||
2037 | /* the few simple ones we can get from the mount struct */ | ||
2038 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | ||
2039 | { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, | ||
2040 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | ||
2041 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | ||
2042 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | ||
2043 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | ||
2044 | { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC }, | ||
2045 | { 0, NULL } | ||
2046 | }; | ||
2047 | struct proc_xfs_info *xfs_infop; | ||
2048 | |||
2049 | for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { | ||
2050 | if (mp->m_flags & xfs_infop->flag) | ||
2051 | seq_puts(m, xfs_infop->str); | ||
2052 | } | ||
2053 | |||
2054 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | ||
2055 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | ||
2056 | (int)(1 << mp->m_writeio_log) >> 10); | ||
2057 | |||
2058 | if (mp->m_logbufs > 0) | ||
2059 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | ||
2060 | if (mp->m_logbsize > 0) | ||
2061 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); | ||
2062 | |||
2063 | if (mp->m_logname) | ||
2064 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); | ||
2065 | if (mp->m_rtname) | ||
2066 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); | ||
2067 | |||
2068 | if (mp->m_dalign > 0) | ||
2069 | seq_printf(m, "," MNTOPT_SUNIT "=%d", | ||
2070 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); | ||
2071 | if (mp->m_swidth > 0) | ||
2072 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", | ||
2073 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); | ||
2074 | |||
2075 | if (!(mp->m_flags & XFS_MOUNT_IDELETE)) | ||
2076 | seq_printf(m, "," MNTOPT_IKEEP); | ||
2077 | if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) | ||
2078 | seq_printf(m, "," MNTOPT_LARGEIO); | ||
2079 | |||
2080 | if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS)) | ||
2081 | seq_printf(m, "," MNTOPT_64BITINODE); | ||
2082 | if (mp->m_flags & XFS_MOUNT_GRPID) | ||
2083 | seq_printf(m, "," MNTOPT_GRPID); | ||
2084 | |||
2085 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { | ||
2086 | if (mp->m_qflags & XFS_UQUOTA_ENFD) | ||
2087 | seq_puts(m, "," MNTOPT_USRQUOTA); | ||
2088 | else | ||
2089 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | ||
2090 | } | ||
2091 | |||
2092 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | ||
2093 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | ||
2094 | seq_puts(m, "," MNTOPT_PRJQUOTA); | ||
2095 | else | ||
2096 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
2097 | } | ||
2098 | |||
2099 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | ||
2100 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | ||
2101 | seq_puts(m, "," MNTOPT_GRPQUOTA); | ||
2102 | else | ||
2103 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | ||
2104 | } | ||
2105 | |||
2106 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | ||
2107 | seq_puts(m, "," MNTOPT_NOQUOTA); | ||
2108 | |||
2109 | if (mp->m_flags & XFS_MOUNT_DMAPI) | ||
2110 | seq_puts(m, "," MNTOPT_DMAPI); | ||
2111 | return 0; | ||
2112 | } | ||
2113 | |||
2114 | /* | ||
2115 | * Second stage of a freeze. The data is already frozen so we only | ||
2116 | * need to take care of themetadata. Once that's done write a dummy | ||
2117 | * record to dirty the log in case of a crash while frozen. | ||
2118 | */ | ||
2119 | void | ||
2120 | xfs_freeze( | ||
2121 | xfs_mount_t *mp) | ||
2122 | { | ||
2123 | xfs_attr_quiesce(mp); | ||
2124 | xfs_fs_log_dummy(mp); | ||
2125 | } | ||
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h index a592fe02a339..1688817c55ed 100644 --- a/fs/xfs/xfs_vfsops.h +++ b/fs/xfs/xfs_vfsops.h | |||
@@ -13,16 +13,9 @@ int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, | |||
13 | int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp); | 13 | int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp); |
14 | int xfs_mntupdate(struct xfs_mount *mp, int *flags, | 14 | int xfs_mntupdate(struct xfs_mount *mp, int *flags, |
15 | struct xfs_mount_args *args); | 15 | struct xfs_mount_args *args); |
16 | int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp); | ||
17 | int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp, | ||
18 | bhv_vnode_t *vp); | ||
19 | int xfs_sync(struct xfs_mount *mp, int flags); | 16 | int xfs_sync(struct xfs_mount *mp, int flags); |
20 | int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid); | ||
21 | int xfs_parseargs(struct xfs_mount *mp, char *options, | ||
22 | struct xfs_mount_args *args, int update); | ||
23 | int xfs_showargs(struct xfs_mount *mp, struct seq_file *m); | ||
24 | void xfs_freeze(struct xfs_mount *mp); | ||
25 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | 17 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, |
26 | int lnnum); | 18 | int lnnum); |
19 | void xfs_attr_quiesce(struct xfs_mount *mp); | ||
27 | 20 | ||
28 | #endif /* _XFS_VFSOPS_H */ | 21 | #endif /* _XFS_VFSOPS_H */ |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index efd5aff9eaf6..51305242ff8c 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -88,7 +88,7 @@ xfs_getattr( | |||
88 | bhv_vnode_t *vp = XFS_ITOV(ip); | 88 | bhv_vnode_t *vp = XFS_ITOV(ip); |
89 | xfs_mount_t *mp = ip->i_mount; | 89 | xfs_mount_t *mp = ip->i_mount; |
90 | 90 | ||
91 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 91 | xfs_itrace_entry(ip); |
92 | 92 | ||
93 | if (XFS_FORCED_SHUTDOWN(mp)) | 93 | if (XFS_FORCED_SHUTDOWN(mp)) |
94 | return XFS_ERROR(EIO); | 94 | return XFS_ERROR(EIO); |
@@ -136,7 +136,7 @@ xfs_getattr( | |||
136 | default: | 136 | default: |
137 | vap->va_rdev = 0; | 137 | vap->va_rdev = 0; |
138 | 138 | ||
139 | if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | 139 | if (!(XFS_IS_REALTIME_INODE(ip))) { |
140 | vap->va_blocksize = xfs_preferred_iosize(mp); | 140 | vap->va_blocksize = xfs_preferred_iosize(mp); |
141 | } else { | 141 | } else { |
142 | 142 | ||
@@ -228,7 +228,7 @@ xfs_setattr( | |||
228 | int file_owner; | 228 | int file_owner; |
229 | int need_iolock = 1; | 229 | int need_iolock = 1; |
230 | 230 | ||
231 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 231 | xfs_itrace_entry(ip); |
232 | 232 | ||
233 | if (mp->m_flags & XFS_MOUNT_RDONLY) | 233 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
234 | return XFS_ERROR(EROFS); | 234 | return XFS_ERROR(EROFS); |
@@ -508,7 +508,7 @@ xfs_setattr( | |||
508 | */ | 508 | */ |
509 | if ((ip->i_d.di_nextents || ip->i_delayed_blks) && | 509 | if ((ip->i_d.di_nextents || ip->i_delayed_blks) && |
510 | (mask & XFS_AT_XFLAGS) && | 510 | (mask & XFS_AT_XFLAGS) && |
511 | (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != | 511 | (XFS_IS_REALTIME_INODE(ip)) != |
512 | (vap->va_xflags & XFS_XFLAG_REALTIME)) { | 512 | (vap->va_xflags & XFS_XFLAG_REALTIME)) { |
513 | code = XFS_ERROR(EINVAL); /* EFBIG? */ | 513 | code = XFS_ERROR(EINVAL); /* EFBIG? */ |
514 | goto error_return; | 514 | goto error_return; |
@@ -520,7 +520,7 @@ xfs_setattr( | |||
520 | if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) { | 520 | if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) { |
521 | xfs_extlen_t size; | 521 | xfs_extlen_t size; |
522 | 522 | ||
523 | if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) || | 523 | if (XFS_IS_REALTIME_INODE(ip) || |
524 | ((mask & XFS_AT_XFLAGS) && | 524 | ((mask & XFS_AT_XFLAGS) && |
525 | (vap->va_xflags & XFS_XFLAG_REALTIME))) { | 525 | (vap->va_xflags & XFS_XFLAG_REALTIME))) { |
526 | size = mp->m_sb.sb_rextsize << | 526 | size = mp->m_sb.sb_rextsize << |
@@ -804,12 +804,8 @@ xfs_setattr( | |||
804 | if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT) | 804 | if (vap->va_xflags & XFS_XFLAG_EXTSZINHERIT) |
805 | di_flags |= XFS_DIFLAG_EXTSZINHERIT; | 805 | di_flags |= XFS_DIFLAG_EXTSZINHERIT; |
806 | } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { | 806 | } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { |
807 | if (vap->va_xflags & XFS_XFLAG_REALTIME) { | 807 | if (vap->va_xflags & XFS_XFLAG_REALTIME) |
808 | di_flags |= XFS_DIFLAG_REALTIME; | 808 | di_flags |= XFS_DIFLAG_REALTIME; |
809 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; | ||
810 | } else { | ||
811 | ip->i_iocore.io_flags &= ~XFS_IOCORE_RT; | ||
812 | } | ||
813 | if (vap->va_xflags & XFS_XFLAG_EXTSIZE) | 809 | if (vap->va_xflags & XFS_XFLAG_EXTSIZE) |
814 | di_flags |= XFS_DIFLAG_EXTSIZE; | 810 | di_flags |= XFS_DIFLAG_EXTSIZE; |
815 | } | 811 | } |
@@ -902,28 +898,6 @@ xfs_setattr( | |||
902 | return code; | 898 | return code; |
903 | } | 899 | } |
904 | 900 | ||
905 | |||
906 | /* | ||
907 | * xfs_access | ||
908 | * Null conversion from vnode mode bits to inode mode bits, as in efs. | ||
909 | */ | ||
910 | int | ||
911 | xfs_access( | ||
912 | xfs_inode_t *ip, | ||
913 | int mode, | ||
914 | cred_t *credp) | ||
915 | { | ||
916 | int error; | ||
917 | |||
918 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | ||
919 | |||
920 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
921 | error = xfs_iaccess(ip, mode, credp); | ||
922 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
923 | return error; | ||
924 | } | ||
925 | |||
926 | |||
927 | /* | 901 | /* |
928 | * The maximum pathlen is 1024 bytes. Since the minimum file system | 902 | * The maximum pathlen is 1024 bytes. Since the minimum file system |
929 | * blocksize is 512 bytes, we can get a max of 2 extents back from | 903 | * blocksize is 512 bytes, we can get a max of 2 extents back from |
@@ -987,7 +961,7 @@ xfs_readlink( | |||
987 | int pathlen; | 961 | int pathlen; |
988 | int error = 0; | 962 | int error = 0; |
989 | 963 | ||
990 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 964 | xfs_itrace_entry(ip); |
991 | 965 | ||
992 | if (XFS_FORCED_SHUTDOWN(mp)) | 966 | if (XFS_FORCED_SHUTDOWN(mp)) |
993 | return XFS_ERROR(EIO); | 967 | return XFS_ERROR(EIO); |
@@ -1033,7 +1007,7 @@ xfs_fsync( | |||
1033 | int error; | 1007 | int error; |
1034 | int log_flushed = 0, changed = 1; | 1008 | int log_flushed = 0, changed = 1; |
1035 | 1009 | ||
1036 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 1010 | xfs_itrace_entry(ip); |
1037 | 1011 | ||
1038 | ASSERT(start >= 0 && stop >= -1); | 1012 | ASSERT(start >= 0 && stop >= -1); |
1039 | 1013 | ||
@@ -1149,7 +1123,7 @@ xfs_fsync( | |||
1149 | * If this inode is on the RT dev we need to flush that | 1123 | * If this inode is on the RT dev we need to flush that |
1150 | * cache as well. | 1124 | * cache as well. |
1151 | */ | 1125 | */ |
1152 | if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) | 1126 | if (XFS_IS_REALTIME_INODE(ip)) |
1153 | xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); | 1127 | xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); |
1154 | } | 1128 | } |
1155 | 1129 | ||
@@ -1188,7 +1162,7 @@ xfs_free_eofblocks( | |||
1188 | 1162 | ||
1189 | nimaps = 1; | 1163 | nimaps = 1; |
1190 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1164 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1191 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0, | 1165 | error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, |
1192 | NULL, 0, &imap, &nimaps, NULL, NULL); | 1166 | NULL, 0, &imap, &nimaps, NULL, NULL); |
1193 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1167 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1194 | 1168 | ||
@@ -1562,9 +1536,6 @@ xfs_release( | |||
1562 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1536 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); |
1563 | if (error) | 1537 | if (error) |
1564 | return error; | 1538 | return error; |
1565 | /* Update linux inode block count after free above */ | ||
1566 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, | ||
1567 | ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
1568 | } | 1539 | } |
1569 | } | 1540 | } |
1570 | 1541 | ||
@@ -1592,7 +1563,7 @@ xfs_inactive( | |||
1592 | int error; | 1563 | int error; |
1593 | int truncate; | 1564 | int truncate; |
1594 | 1565 | ||
1595 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 1566 | xfs_itrace_entry(ip); |
1596 | 1567 | ||
1597 | /* | 1568 | /* |
1598 | * If the inode is already free, then there can be nothing | 1569 | * If the inode is already free, then there can be nothing |
@@ -1638,9 +1609,6 @@ xfs_inactive( | |||
1638 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1609 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); |
1639 | if (error) | 1610 | if (error) |
1640 | return VN_INACTIVE_CACHE; | 1611 | return VN_INACTIVE_CACHE; |
1641 | /* Update linux inode block count after free above */ | ||
1642 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, | ||
1643 | ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
1644 | } | 1612 | } |
1645 | goto out; | 1613 | goto out; |
1646 | } | 1614 | } |
@@ -1805,7 +1773,7 @@ xfs_lookup( | |||
1805 | int error; | 1773 | int error; |
1806 | uint lock_mode; | 1774 | uint lock_mode; |
1807 | 1775 | ||
1808 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 1776 | xfs_itrace_entry(dp); |
1809 | 1777 | ||
1810 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 1778 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
1811 | return XFS_ERROR(EIO); | 1779 | return XFS_ERROR(EIO); |
@@ -1814,7 +1782,7 @@ xfs_lookup( | |||
1814 | error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); | 1782 | error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); |
1815 | if (!error) { | 1783 | if (!error) { |
1816 | *vpp = XFS_ITOV(ip); | 1784 | *vpp = XFS_ITOV(ip); |
1817 | ITRACE(ip); | 1785 | xfs_itrace_ref(ip); |
1818 | } | 1786 | } |
1819 | xfs_iunlock_map_shared(dp, lock_mode); | 1787 | xfs_iunlock_map_shared(dp, lock_mode); |
1820 | return error; | 1788 | return error; |
@@ -1848,7 +1816,7 @@ xfs_create( | |||
1848 | int namelen; | 1816 | int namelen; |
1849 | 1817 | ||
1850 | ASSERT(!*vpp); | 1818 | ASSERT(!*vpp); |
1851 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 1819 | xfs_itrace_entry(dp); |
1852 | 1820 | ||
1853 | namelen = VNAMELEN(dentry); | 1821 | namelen = VNAMELEN(dentry); |
1854 | 1822 | ||
@@ -1930,7 +1898,7 @@ xfs_create( | |||
1930 | goto error_return; | 1898 | goto error_return; |
1931 | goto abort_return; | 1899 | goto abort_return; |
1932 | } | 1900 | } |
1933 | ITRACE(ip); | 1901 | xfs_itrace_ref(ip); |
1934 | 1902 | ||
1935 | /* | 1903 | /* |
1936 | * At this point, we've gotten a newly allocated inode. | 1904 | * At this point, we've gotten a newly allocated inode. |
@@ -2098,7 +2066,7 @@ again: | |||
2098 | 2066 | ||
2099 | e_inum = ip->i_ino; | 2067 | e_inum = ip->i_ino; |
2100 | 2068 | ||
2101 | ITRACE(ip); | 2069 | xfs_itrace_ref(ip); |
2102 | 2070 | ||
2103 | /* | 2071 | /* |
2104 | * We want to lock in increasing inum. Since we've already | 2072 | * We want to lock in increasing inum. Since we've already |
@@ -2321,7 +2289,7 @@ xfs_remove( | |||
2321 | uint resblks; | 2289 | uint resblks; |
2322 | int namelen; | 2290 | int namelen; |
2323 | 2291 | ||
2324 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 2292 | xfs_itrace_entry(dp); |
2325 | 2293 | ||
2326 | if (XFS_FORCED_SHUTDOWN(mp)) | 2294 | if (XFS_FORCED_SHUTDOWN(mp)) |
2327 | return XFS_ERROR(EIO); | 2295 | return XFS_ERROR(EIO); |
@@ -2364,9 +2332,8 @@ xfs_remove( | |||
2364 | 2332 | ||
2365 | dm_di_mode = ip->i_d.di_mode; | 2333 | dm_di_mode = ip->i_d.di_mode; |
2366 | 2334 | ||
2367 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 2335 | xfs_itrace_entry(ip); |
2368 | 2336 | xfs_itrace_ref(ip); | |
2369 | ITRACE(ip); | ||
2370 | 2337 | ||
2371 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2338 | error = XFS_QM_DQATTACH(mp, dp, 0); |
2372 | if (!error && dp != ip) | 2339 | if (!error && dp != ip) |
@@ -2498,8 +2465,7 @@ xfs_remove( | |||
2498 | if (link_zero && xfs_inode_is_filestream(ip)) | 2465 | if (link_zero && xfs_inode_is_filestream(ip)) |
2499 | xfs_filestream_deassociate(ip); | 2466 | xfs_filestream_deassociate(ip); |
2500 | 2467 | ||
2501 | vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address); | 2468 | xfs_itrace_exit(ip); |
2502 | |||
2503 | IRELE(ip); | 2469 | IRELE(ip); |
2504 | 2470 | ||
2505 | /* Fall through to std_return with error = 0 */ | 2471 | /* Fall through to std_return with error = 0 */ |
@@ -2562,8 +2528,8 @@ xfs_link( | |||
2562 | char *target_name = VNAME(dentry); | 2528 | char *target_name = VNAME(dentry); |
2563 | int target_namelen; | 2529 | int target_namelen; |
2564 | 2530 | ||
2565 | vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address); | 2531 | xfs_itrace_entry(tdp); |
2566 | vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address); | 2532 | xfs_itrace_entry(xfs_vtoi(src_vp)); |
2567 | 2533 | ||
2568 | target_namelen = VNAMELEN(dentry); | 2534 | target_namelen = VNAMELEN(dentry); |
2569 | ASSERT(!VN_ISDIR(src_vp)); | 2535 | ASSERT(!VN_ISDIR(src_vp)); |
@@ -2744,7 +2710,7 @@ xfs_mkdir( | |||
2744 | 2710 | ||
2745 | /* Return through std_return after this point. */ | 2711 | /* Return through std_return after this point. */ |
2746 | 2712 | ||
2747 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 2713 | xfs_itrace_entry(dp); |
2748 | 2714 | ||
2749 | mp = dp->i_mount; | 2715 | mp = dp->i_mount; |
2750 | udqp = gdqp = NULL; | 2716 | udqp = gdqp = NULL; |
@@ -2810,7 +2776,7 @@ xfs_mkdir( | |||
2810 | goto error_return; | 2776 | goto error_return; |
2811 | goto abort_return; | 2777 | goto abort_return; |
2812 | } | 2778 | } |
2813 | ITRACE(cdp); | 2779 | xfs_itrace_ref(cdp); |
2814 | 2780 | ||
2815 | /* | 2781 | /* |
2816 | * Now we add the directory inode to the transaction. | 2782 | * Now we add the directory inode to the transaction. |
@@ -2936,7 +2902,7 @@ xfs_rmdir( | |||
2936 | int last_cdp_link; | 2902 | int last_cdp_link; |
2937 | uint resblks; | 2903 | uint resblks; |
2938 | 2904 | ||
2939 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 2905 | xfs_itrace_entry(dp); |
2940 | 2906 | ||
2941 | if (XFS_FORCED_SHUTDOWN(mp)) | 2907 | if (XFS_FORCED_SHUTDOWN(mp)) |
2942 | return XFS_ERROR(EIO); | 2908 | return XFS_ERROR(EIO); |
@@ -3041,7 +3007,7 @@ xfs_rmdir( | |||
3041 | VN_HOLD(dir_vp); | 3007 | VN_HOLD(dir_vp); |
3042 | } | 3008 | } |
3043 | 3009 | ||
3044 | ITRACE(cdp); | 3010 | xfs_itrace_ref(cdp); |
3045 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); | 3011 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); |
3046 | 3012 | ||
3047 | ASSERT(cdp->i_d.di_nlink >= 2); | 3013 | ASSERT(cdp->i_d.di_nlink >= 2); |
@@ -3189,8 +3155,7 @@ xfs_symlink( | |||
3189 | ip = NULL; | 3155 | ip = NULL; |
3190 | tp = NULL; | 3156 | tp = NULL; |
3191 | 3157 | ||
3192 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | 3158 | xfs_itrace_entry(dp); |
3193 | |||
3194 | 3159 | ||
3195 | if (XFS_FORCED_SHUTDOWN(mp)) | 3160 | if (XFS_FORCED_SHUTDOWN(mp)) |
3196 | return XFS_ERROR(EIO); | 3161 | return XFS_ERROR(EIO); |
@@ -3317,7 +3282,7 @@ xfs_symlink( | |||
3317 | goto error_return; | 3282 | goto error_return; |
3318 | goto error1; | 3283 | goto error1; |
3319 | } | 3284 | } |
3320 | ITRACE(ip); | 3285 | xfs_itrace_ref(ip); |
3321 | 3286 | ||
3322 | /* | 3287 | /* |
3323 | * An error after we've joined dp to the transaction will result in the | 3288 | * An error after we've joined dp to the transaction will result in the |
@@ -3465,27 +3430,6 @@ std_return: | |||
3465 | goto std_return; | 3430 | goto std_return; |
3466 | } | 3431 | } |
3467 | 3432 | ||
3468 | |||
3469 | int | ||
3470 | xfs_fid2( | ||
3471 | xfs_inode_t *ip, | ||
3472 | xfs_fid_t *xfid) | ||
3473 | { | ||
3474 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | ||
3475 | |||
3476 | xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len); | ||
3477 | xfid->fid_pad = 0; | ||
3478 | /* | ||
3479 | * use memcpy because the inode is a long long and there's no | ||
3480 | * assurance that xfid->fid_ino is properly aligned. | ||
3481 | */ | ||
3482 | memcpy(&xfid->fid_ino, &ip->i_ino, sizeof(xfid->fid_ino)); | ||
3483 | xfid->fid_gen = ip->i_d.di_gen; | ||
3484 | |||
3485 | return 0; | ||
3486 | } | ||
3487 | |||
3488 | |||
3489 | int | 3433 | int |
3490 | xfs_rwlock( | 3434 | xfs_rwlock( |
3491 | xfs_inode_t *ip, | 3435 | xfs_inode_t *ip, |
@@ -3558,11 +3502,11 @@ xfs_inode_flush( | |||
3558 | if (iip && iip->ili_last_lsn) { | 3502 | if (iip && iip->ili_last_lsn) { |
3559 | xlog_t *log = mp->m_log; | 3503 | xlog_t *log = mp->m_log; |
3560 | xfs_lsn_t sync_lsn; | 3504 | xfs_lsn_t sync_lsn; |
3561 | int s, log_flags = XFS_LOG_FORCE; | 3505 | int log_flags = XFS_LOG_FORCE; |
3562 | 3506 | ||
3563 | s = GRANT_LOCK(log); | 3507 | spin_lock(&log->l_grant_lock); |
3564 | sync_lsn = log->l_last_sync_lsn; | 3508 | sync_lsn = log->l_last_sync_lsn; |
3565 | GRANT_UNLOCK(log, s); | 3509 | spin_unlock(&log->l_grant_lock); |
3566 | 3510 | ||
3567 | if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) { | 3511 | if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) { |
3568 | if (flags & FLUSH_SYNC) | 3512 | if (flags & FLUSH_SYNC) |
@@ -3637,8 +3581,8 @@ xfs_set_dmattrs( | |||
3637 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 3581 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
3638 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 3582 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
3639 | 3583 | ||
3640 | ip->i_iocore.io_dmevmask = ip->i_d.di_dmevmask = evmask; | 3584 | ip->i_d.di_dmevmask = evmask; |
3641 | ip->i_iocore.io_dmstate = ip->i_d.di_dmstate = state; | 3585 | ip->i_d.di_dmstate = state; |
3642 | 3586 | ||
3643 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 3587 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
3644 | IHOLD(ip); | 3588 | IHOLD(ip); |
@@ -3653,7 +3597,7 @@ xfs_reclaim( | |||
3653 | { | 3597 | { |
3654 | bhv_vnode_t *vp = XFS_ITOV(ip); | 3598 | bhv_vnode_t *vp = XFS_ITOV(ip); |
3655 | 3599 | ||
3656 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 3600 | xfs_itrace_entry(ip); |
3657 | 3601 | ||
3658 | ASSERT(!VN_MAPPED(vp)); | 3602 | ASSERT(!VN_MAPPED(vp)); |
3659 | 3603 | ||
@@ -3871,7 +3815,7 @@ xfs_alloc_file_space( | |||
3871 | int committed; | 3815 | int committed; |
3872 | int error; | 3816 | int error; |
3873 | 3817 | ||
3874 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 3818 | xfs_itrace_entry(ip); |
3875 | 3819 | ||
3876 | if (XFS_FORCED_SHUTDOWN(mp)) | 3820 | if (XFS_FORCED_SHUTDOWN(mp)) |
3877 | return XFS_ERROR(EIO); | 3821 | return XFS_ERROR(EIO); |
@@ -3976,7 +3920,7 @@ retry: | |||
3976 | * Issue the xfs_bmapi() call to allocate the blocks | 3920 | * Issue the xfs_bmapi() call to allocate the blocks |
3977 | */ | 3921 | */ |
3978 | XFS_BMAP_INIT(&free_list, &firstfsb); | 3922 | XFS_BMAP_INIT(&free_list, &firstfsb); |
3979 | error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, | 3923 | error = xfs_bmapi(tp, ip, startoffset_fsb, |
3980 | allocatesize_fsb, bmapi_flag, | 3924 | allocatesize_fsb, bmapi_flag, |
3981 | &firstfsb, 0, imapp, &nimaps, | 3925 | &firstfsb, 0, imapp, &nimaps, |
3982 | &free_list, NULL); | 3926 | &free_list, NULL); |
@@ -4052,13 +3996,13 @@ xfs_zero_remaining_bytes( | |||
4052 | int error = 0; | 3996 | int error = 0; |
4053 | 3997 | ||
4054 | bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize, | 3998 | bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize, |
4055 | ip->i_d.di_flags & XFS_DIFLAG_REALTIME ? | 3999 | XFS_IS_REALTIME_INODE(ip) ? |
4056 | mp->m_rtdev_targp : mp->m_ddev_targp); | 4000 | mp->m_rtdev_targp : mp->m_ddev_targp); |
4057 | 4001 | ||
4058 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { | 4002 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { |
4059 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 4003 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
4060 | nimap = 1; | 4004 | nimap = 1; |
4061 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0, | 4005 | error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, |
4062 | NULL, 0, &imap, &nimap, NULL, NULL); | 4006 | NULL, 0, &imap, &nimap, NULL, NULL); |
4063 | if (error || nimap < 1) | 4007 | if (error || nimap < 1) |
4064 | break; | 4008 | break; |
@@ -4141,7 +4085,7 @@ xfs_free_file_space( | |||
4141 | vp = XFS_ITOV(ip); | 4085 | vp = XFS_ITOV(ip); |
4142 | mp = ip->i_mount; | 4086 | mp = ip->i_mount; |
4143 | 4087 | ||
4144 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 4088 | xfs_itrace_entry(ip); |
4145 | 4089 | ||
4146 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 4090 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) |
4147 | return error; | 4091 | return error; |
@@ -4149,7 +4093,7 @@ xfs_free_file_space( | |||
4149 | error = 0; | 4093 | error = 0; |
4150 | if (len <= 0) /* if nothing being freed */ | 4094 | if (len <= 0) /* if nothing being freed */ |
4151 | return error; | 4095 | return error; |
4152 | rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME); | 4096 | rt = XFS_IS_REALTIME_INODE(ip); |
4153 | startoffset_fsb = XFS_B_TO_FSB(mp, offset); | 4097 | startoffset_fsb = XFS_B_TO_FSB(mp, offset); |
4154 | end_dmi_offset = offset + len; | 4098 | end_dmi_offset = offset + len; |
4155 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); | 4099 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); |
@@ -4172,15 +4116,12 @@ xfs_free_file_space( | |||
4172 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ | 4116 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ |
4173 | } | 4117 | } |
4174 | 4118 | ||
4175 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); | 4119 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); |
4176 | ioffset = offset & ~(rounding - 1); | 4120 | ioffset = offset & ~(rounding - 1); |
4177 | 4121 | ||
4178 | if (VN_CACHED(vp) != 0) { | 4122 | if (VN_CACHED(vp) != 0) { |
4179 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, | 4123 | xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); |
4180 | ctooff(offtoct(ioffset)), -1); | 4124 | error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); |
4181 | error = xfs_flushinval_pages(ip, | ||
4182 | ctooff(offtoct(ioffset)), | ||
4183 | -1, FI_REMAPF_LOCKED); | ||
4184 | if (error) | 4125 | if (error) |
4185 | goto out_unlock_iolock; | 4126 | goto out_unlock_iolock; |
4186 | } | 4127 | } |
@@ -4193,7 +4134,7 @@ xfs_free_file_space( | |||
4193 | */ | 4134 | */ |
4194 | if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 4135 | if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { |
4195 | nimap = 1; | 4136 | nimap = 1; |
4196 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb, | 4137 | error = xfs_bmapi(NULL, ip, startoffset_fsb, |
4197 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); | 4138 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); |
4198 | if (error) | 4139 | if (error) |
4199 | goto out_unlock_iolock; | 4140 | goto out_unlock_iolock; |
@@ -4208,7 +4149,7 @@ xfs_free_file_space( | |||
4208 | startoffset_fsb += mp->m_sb.sb_rextsize - mod; | 4149 | startoffset_fsb += mp->m_sb.sb_rextsize - mod; |
4209 | } | 4150 | } |
4210 | nimap = 1; | 4151 | nimap = 1; |
4211 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1, | 4152 | error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, |
4212 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); | 4153 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); |
4213 | if (error) | 4154 | if (error) |
4214 | goto out_unlock_iolock; | 4155 | goto out_unlock_iolock; |
@@ -4284,7 +4225,7 @@ xfs_free_file_space( | |||
4284 | * issue the bunmapi() call to free the blocks | 4225 | * issue the bunmapi() call to free the blocks |
4285 | */ | 4226 | */ |
4286 | XFS_BMAP_INIT(&free_list, &firstfsb); | 4227 | XFS_BMAP_INIT(&free_list, &firstfsb); |
4287 | error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, | 4228 | error = xfs_bunmapi(tp, ip, startoffset_fsb, |
4288 | endoffset_fsb - startoffset_fsb, | 4229 | endoffset_fsb - startoffset_fsb, |
4289 | 0, 2, &firstfsb, &free_list, NULL, &done); | 4230 | 0, 2, &firstfsb, &free_list, NULL, &done); |
4290 | if (error) { | 4231 | if (error) { |
@@ -4347,23 +4288,11 @@ xfs_change_file_space( | |||
4347 | xfs_trans_t *tp; | 4288 | xfs_trans_t *tp; |
4348 | bhv_vattr_t va; | 4289 | bhv_vattr_t va; |
4349 | 4290 | ||
4350 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 4291 | xfs_itrace_entry(ip); |
4351 | 4292 | ||
4352 | /* | ||
4353 | * must be a regular file and have write permission | ||
4354 | */ | ||
4355 | if (!S_ISREG(ip->i_d.di_mode)) | 4293 | if (!S_ISREG(ip->i_d.di_mode)) |
4356 | return XFS_ERROR(EINVAL); | 4294 | return XFS_ERROR(EINVAL); |
4357 | 4295 | ||
4358 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
4359 | |||
4360 | if ((error = xfs_iaccess(ip, S_IWUSR, credp))) { | ||
4361 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
4362 | return error; | ||
4363 | } | ||
4364 | |||
4365 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
4366 | |||
4367 | switch (bf->l_whence) { | 4296 | switch (bf->l_whence) { |
4368 | case 0: /*SEEK_SET*/ | 4297 | case 0: /*SEEK_SET*/ |
4369 | break; | 4298 | break; |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index b7e461c40cfb..4e3970f0e5e3 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -18,7 +18,6 @@ int xfs_open(struct xfs_inode *ip); | |||
18 | int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags); | 18 | int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags); |
19 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, | 19 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, |
20 | struct cred *credp); | 20 | struct cred *credp); |
21 | int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp); | ||
22 | int xfs_readlink(struct xfs_inode *ip, char *link); | 21 | int xfs_readlink(struct xfs_inode *ip, char *link); |
23 | int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, | 22 | int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, |
24 | xfs_off_t stop); | 23 | xfs_off_t stop); |
@@ -39,7 +38,6 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, | |||
39 | int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, | 38 | int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, |
40 | char *target_path, mode_t mode, bhv_vnode_t **vpp, | 39 | char *target_path, mode_t mode, bhv_vnode_t **vpp, |
41 | struct cred *credp); | 40 | struct cred *credp); |
42 | int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid); | ||
43 | int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | 41 | int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); |
44 | void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | 42 | void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); |
45 | int xfs_inode_flush(struct xfs_inode *ip, int flags); | 43 | int xfs_inode_flush(struct xfs_inode *ip, int flags); |