aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 22:12:12 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 22:12:12 -0500
commit0b61a2ba5dfd1620731e717d686e6ade657fd975 (patch)
treedea84efd43934a7d6139048f87c4ba86d68d4b6d /fs
parenta13ff0bb3feda8b1fcffc69951320277ed7c4101 (diff)
parentde2eeea609b55e8c3994133a565b39edeaaaaf69 (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')
-rw-r--r--fs/xfs/Makefile-linux-2.61
-rw-r--r--fs/xfs/linux-2.6/spin.h45
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c43
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c57
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c25
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c86
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c170
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h34
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c122
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h16
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c572
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c117
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h62
-rw-r--r--fs/xfs/quota/xfs_dquot.c12
-rw-r--r--fs/xfs/quota/xfs_dquot.h5
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c27
-rw-r--r--fs/xfs/quota/xfs_qm.c14
-rw-r--r--fs/xfs/quota/xfs_qm.h6
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c19
-rw-r--r--fs/xfs/support/debug.c7
-rw-r--r--fs/xfs/support/ktrace.c8
-rw-r--r--fs/xfs/support/ktrace.h3
-rw-r--r--fs/xfs/support/uuid.c2
-rw-r--r--fs/xfs/xfs.h2
-rw-r--r--fs/xfs/xfs_acl.c30
-rw-r--r--fs/xfs/xfs_acl.h2
-rw-r--r--fs/xfs/xfs_ag.h2
-rw-r--r--fs/xfs/xfs_alloc.c19
-rw-r--r--fs/xfs/xfs_attr.c2
-rw-r--r--fs/xfs/xfs_attr_leaf.c8
-rw-r--r--fs/xfs/xfs_bit.c103
-rw-r--r--fs/xfs/xfs_bit.h27
-rw-r--r--fs/xfs/xfs_bmap.c22
-rw-r--r--fs/xfs/xfs_bmap.h2
-rw-r--r--fs/xfs/xfs_bmap_btree.c3
-rw-r--r--fs/xfs/xfs_btree.h2
-rw-r--r--fs/xfs/xfs_buf_item.c10
-rw-r--r--fs/xfs/xfs_buf_item.h2
-rw-r--r--fs/xfs/xfs_da_btree.c13
-rw-r--r--fs/xfs/xfs_da_btree.h1
-rw-r--r--fs/xfs/xfs_dfrag.c84
-rw-r--r--fs/xfs/xfs_dinode.h82
-rw-r--r--fs/xfs/xfs_dir2.c3
-rw-r--r--fs/xfs/xfs_error.c31
-rw-r--r--fs/xfs/xfs_error.h2
-rw-r--r--fs/xfs/xfs_extfree_item.c21
-rw-r--r--fs/xfs/xfs_filestream.c2
-rw-r--r--fs/xfs/xfs_fs.h10
-rw-r--r--fs/xfs/xfs_fsops.c13
-rw-r--r--fs/xfs/xfs_ialloc_btree.h2
-rw-r--r--fs/xfs/xfs_iget.c185
-rw-r--r--fs/xfs/xfs_inode.c225
-rw-r--r--fs/xfs/xfs_inode.h98
-rw-r--r--fs/xfs/xfs_inode_item.c26
-rw-r--r--fs/xfs/xfs_iocore.c119
-rw-r--r--fs/xfs/xfs_iomap.c212
-rw-r--r--fs/xfs/xfs_iomap.h5
-rw-r--r--fs/xfs/xfs_itable.c12
-rw-r--r--fs/xfs/xfs_log.c416
-rw-r--r--fs/xfs/xfs_log.h3
-rw-r--r--fs/xfs/xfs_log_priv.h96
-rw-r--r--fs/xfs/xfs_log_recover.c197
-rw-r--r--fs/xfs/xfs_mount.c344
-rw-r--r--fs/xfs/xfs_mount.h127
-rw-r--r--fs/xfs/xfs_mru_cache.c54
-rw-r--r--fs/xfs/xfs_qmops.c7
-rw-r--r--fs/xfs/xfs_rename.c9
-rw-r--r--fs/xfs/xfs_rtalloc.c19
-rw-r--r--fs/xfs/xfs_rtalloc.h2
-rw-r--r--fs/xfs/xfs_rw.h12
-rw-r--r--fs/xfs/xfs_trans.c7
-rw-r--r--fs/xfs/xfs_trans.h7
-rw-r--r--fs/xfs/xfs_trans_ail.c340
-rw-r--r--fs/xfs/xfs_trans_item.c1
-rw-r--r--fs/xfs/xfs_trans_priv.h13
-rw-r--r--fs/xfs/xfs_utils.c11
-rw-r--r--fs/xfs/xfs_utils.h2
-rw-r--r--fs/xfs/xfs_vfsops.c793
-rw-r--r--fs/xfs/xfs_vfsops.h9
-rw-r--r--fs/xfs/xfs_vnodeops.c165
-rw-r--r--fs/xfs/xfs_vnodeops.h2
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
31typedef 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
110STATIC struct block_device *
111xfs_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
1101STATIC_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
1111STATIC_INLINE void 1091STATIC_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
1122STATIC void 1100STATIC 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
1228next_chunk: 1183next_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
137STATIC struct dentry * 146STATIC 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 */
50cred_t sys_cred_val, *sys_cred = &sys_cred_val; 50static cred_t sys_cred_val;
51cred_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 */
188STATIC int 181STATIC int
189xfs_vget_fsop_handlereq( 182xfs_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
471STATIC int 454STATIC 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
703STATIC int 683STATIC int
704xfs_ioc_xattr( 684xfs_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
1204STATIC int 1181STATIC int
1205xfs_ioc_xattr( 1182xfs_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 */
79void
80xfs_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
544STATIC int 557STATIC int
558xfs_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
576STATIC int
545xfs_vn_permission( 577xfs_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
556STATIC int 588STATIC int
557xfs_vn_getattr( 589xfs_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
587STATIC int 647STATIC 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
813STATIC long
814xfs_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);
851out_error:
852 return error;
853}
753 854
754const struct inode_operations xfs_inode_operations = { 855const 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
765const struct inode_operations xfs_dir_inode_operations = { 867const 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 @@
58void 58void
59xfs_rw_enter_trace( 59xfs_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
90void 88void
91xfs_inval_cached_trace( 89xfs_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 */
132STATIC int 129STATIC int
133xfs_iozero( 130xfs_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 */
390STATIC int /* error (positive) */ 385STATIC int /* error (positive) */
391xfs_zero_last_block( 386xfs_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
459int /* error (positive) */ 453int /* error (positive) */
460xfs_zero_eof( 454xfs_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
566out_lock: 558out_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
898int
899xfs_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
21struct xfs_mount; 21struct xfs_mount;
22struct xfs_iocore;
23struct xfs_inode; 22struct xfs_inode;
24struct xfs_bmbt_irec; 23struct xfs_bmbt_irec;
25struct xfs_buf; 24struct 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
63extern void xfs_rw_enter_trace(int, struct xfs_iocore *, 62extern void xfs_rw_enter_trace(int, struct xfs_inode *,
64 void *, size_t, loff_t, int); 63 void *, size_t, loff_t, int);
65extern void xfs_inval_cached_trace(struct xfs_iocore *, 64extern 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
72extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); 71extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
73extern int xfs_bdstrat_cb(struct xfs_buf *); 72extern int xfs_bdstrat_cb(struct xfs_buf *);
74extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 73extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
75 74
76extern int xfs_zero_eof(struct inode *, struct xfs_iocore *, xfs_off_t, 75extern 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
141STATIC unsigned long
142suffix_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
164STATIC int
165xfs_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
429done:
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
437struct proc_xfs_info {
438 int flag;
439 char *str;
440};
441
442STATIC int
443xfs_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
91xfs_max_file_offset( 523xfs_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 */
770void
771xfsaild_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
779int
780xfsaild(
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
805int
806xfsaild_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
816void
817xfsaild_stop(
818 xfs_mount_t *mp)
819{
820 kthread_stop(mp->m_ail.xa_task);
821}
822
823
824
337STATIC struct inode * 825STATIC struct inode *
338xfs_fs_alloc_inode( 826xfs_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
364STATIC int 852STATIC int __init
365xfs_init_zones(void) 853xfs_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
690STATIC int 1212STATIC 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 */
707STATIC void 1234STATIC void
708xfs_fs_lockfs( 1235xfs_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
714STATIC int 1244STATIC 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])
41static wait_queue_head_t vsync[NVSYNC]; 41static wait_queue_head_t vsync[NVSYNC];
42 42
43void 43void __init
44vn_init(void) 44vn_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
85bhv_vnode_t *
86vn_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 */
104void 90int
105vn_revalidate_core( 91vn_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 */
139int
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
156int
157vn_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 */
213void 184void
214vn_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
219void 190void
220vn_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
225void 196void
226vn_trace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra) 197xfs_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
231void 202void
232vn_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
237void 208void
238vn_trace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra) 209xfs_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
189extern void vn_init(void); 189extern void vn_init(void);
190extern bhv_vnode_t *vn_initialize(struct inode *);
191extern int vn_revalidate(bhv_vnode_t *); 190extern int vn_revalidate(bhv_vnode_t *);
192extern int __vn_revalidate(bhv_vnode_t *, bhv_vattr_t *);
193extern 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 */
211extern bhv_vnode_t *vn_hold(bhv_vnode_t *); 208extern 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 */
241static inline void vn_mark_bad(bhv_vnode_t *vp)
242{
243 make_bad_inode(vn_to_inode(vp));
244}
245
246static inline int VN_BAD(bhv_vnode_t *vp) 238static 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
308extern void vn_trace_entry(struct xfs_inode *, const char *, inst_t *); 300extern void _xfs_itrace_entry(struct xfs_inode *, const char *, inst_t *);
309extern void vn_trace_exit(struct xfs_inode *, const char *, inst_t *); 301extern void _xfs_itrace_exit(struct xfs_inode *, const char *, inst_t *);
310extern void vn_trace_hold(struct xfs_inode *, char *, int, inst_t *); 302extern void xfs_itrace_hold(struct xfs_inode *, char *, int, inst_t *);
311extern void vn_trace_ref(struct xfs_inode *, char *, int, inst_t *); 303extern void _xfs_itrace_ref(struct xfs_inode *, char *, int, inst_t *);
312extern void vn_trace_rele(struct xfs_inode *, char *, int, inst_t *); 304extern 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
94xfs_qm_dquot_logitem_pin( 94xfs_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
189xfs_qm_dqunpin_wait( 187xfs_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 */
223STATIC void 219STATIC 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 {
106typedef struct xfs_quotainfo { 106typedef 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
22static char message[1024]; /* keep it off the stack */ 21static char message[1024]; /* keep it off the stack */
23static DEFINE_SPINLOCK(xfs_err_lock); 22static 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
84void
85xfs_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;
21static kmem_zone_t *ktrace_ent_zone; 21static kmem_zone_t *ktrace_ent_zone;
22static int ktrace_zentries; 22static int ktrace_zentries;
23 23
24void 24void __init
25ktrace_init(int zentries) 25ktrace_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
39void 39void __exit
40ktrace_uninit(void) 40ktrace_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 */
33typedef struct ktrace { 31typedef 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
136void 136void __init
137uuid_init(void) 137uuid_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 */
405STATIC int
406xfs_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
2539void 2538void
@@ -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 */
932int 932STATIC int
933xfs_attr_leaf_addname(xfs_da_args_t *args) 933xfs_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)
226STATIC void 226STATIC void
227xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) 227xfs_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 */
32static 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 */
71inline int
72xfs_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 */
99int
100xfs_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 */
119int
120xfs_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 */
50extern int xfs_highbit32(__uint32_t v); 50static 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;
53extern 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 */
56extern int xfs_highbit64(__uint64_t); 56static 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 */
62static 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 */
69static 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) */
59extern int xfs_bitmap_empty(uint *map, uint size); 76extern 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
2969xfs_bmap_alloc( 2969xfs_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 */
6397int /* error */ 6395STATIC int /* error */
6398xfs_bmap_count_tree( 6396xfs_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 */
6473int 6471STATIC int
6474xfs_bmap_count_leaves( 6472xfs_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 */
6493int 6491STATIC int
6494xfs_bmap_disk_count_leaves( 6492xfs_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;
25struct xfs_mount; 25struct xfs_mount;
26struct xfs_trans; 26struct xfs_trans;
27 27
28extern 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;
24struct xfs_mount; 24struct xfs_mount;
25struct xfs_trans; 25struct xfs_trans;
26 26
27extern 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
21extern 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
2220xfs_dabuf_t *xfs_dabuf_global_list; 2220xfs_dabuf_t *xfs_dabuf_global_list;
2221lock_t xfs_dabuf_global_lock; 2221spinlock_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);
260xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); 260xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf);
261 261
262extern struct kmem_zone *xfs_da_state_zone; 262extern struct kmem_zone *xfs_da_state_zone;
263extern 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
47void 48void
@@ -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
233STATIC void
234xfs_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
264void 233void
265xfs_corruption_error( 234xfs_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 */
175extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...); 175extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
176 176
177extern 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
110xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) 110xfs_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. */
351void 351STATIC void
352xfs_fstrm_free_func( 352xfs_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 */
528retry: 525retry:
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 */
66STATIC int 66STATIC int
67xfs_iget_core( 67xfs_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
202finish_inode: 181finish_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
371retry: 349retry:
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);
418void 387 delay(1);
419xfs_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
465xfs_iput(xfs_inode_t *ip, 432xfs_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
479xfs_iput_new(xfs_inode_t *ip, 444xfs_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,
505void 469void
506xfs_ireclaim(xfs_inode_t *ip) 470xfs_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
832uint 834uint
833xfs_dic2xflags( 835xfs_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
2735xfs_idestroy( 2742xfs_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 */
3617int
3618xfs_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 */
3680uint
3681xfs_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
3704ktrace_t *xfs_ilock_trace_buf; 3587ktrace_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
135typedef 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
171extern void xfs_iocore_inode_init(struct xfs_inode *);
172extern 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 *);
509void xfs_ihash_free(struct xfs_mount *); 493void xfs_ihash_free(struct xfs_mount *);
510xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 494xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
511 struct xfs_trans *); 495 struct xfs_trans *);
512void xfs_inode_lock_init(xfs_inode_t *, bhv_vnode_t *);
513int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 496int 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);
515void xfs_iput(xfs_inode_t *, uint); 498void 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
547uint xfs_ip2xflags(struct xfs_inode *); 530uint xfs_ip2xflags(struct xfs_inode *);
548uint xfs_dic2xflags(struct xfs_dinode_core *); 531uint xfs_dic2xflags(struct xfs_dinode *);
549int xfs_ifree(struct xfs_trans *, xfs_inode_t *, 532int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
550 struct xfs_bmap_free *); 533 struct xfs_bmap_free *);
551int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); 534int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
@@ -567,13 +550,12 @@ void xfs_iunpin(xfs_inode_t *);
567int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); 550int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
568int xfs_iflush(xfs_inode_t *, uint); 551int xfs_iflush(xfs_inode_t *, uint);
569void xfs_iflush_all(struct xfs_mount *); 552void xfs_iflush_all(struct xfs_mount *);
570int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
571uint xfs_iroundup(uint);
572void xfs_ichgtime(xfs_inode_t *, int); 553void xfs_ichgtime(xfs_inode_t *, int);
573xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 554xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
574void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 555void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
575 556
576void xfs_synchronize_atime(xfs_inode_t *); 557void xfs_synchronize_atime(xfs_inode_t *);
558void xfs_mark_inode_dirty_sync(xfs_inode_t *);
577 559
578xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); 560xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
579void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, 561void 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 */
755STATIC void 760STATIC 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
51STATIC xfs_fsize_t
52xfs_size_fn(
53 xfs_inode_t *ip)
54{
55 return XFS_ISIZE(ip);
56}
57
58STATIC int
59xfs_ioinit(
60 struct xfs_mount *mp,
61 struct xfs_mount_args *mntargs,
62 int flags)
63{
64 return xfs_mountfs(mp, flags);
65}
66
67xfs_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
90void
91xfs_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
103void
104xfs_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 @@
53void 53void
54xfs_iomap_enter_trace( 54xfs_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(
84void 82void
85xfs_iomap_map_trace( 83xfs_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
127STATIC int 123STATIC int
128xfs_imap_to_bmap( 124xfs_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
173int 168int
174xfs_iomap( 169xfs_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
248phase2: 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
301out: 282out:
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
307STATIC int 289STATIC int
308xfs_iomap_eof_align_last_fsb( 290xfs_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:
577STATIC int 559STATIC int
578xfs_iomap_eof_want_preallocate( 560xfs_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
659retry: 640retry:
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 */
724int 709int
725xfs_iomap_write_allocate( 710xfs_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
852trans_cancel: 858trans_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
76struct xfs_iocore;
77struct xfs_inode; 74struct xfs_inode;
78struct xfs_bmbt_irec; 75struct xfs_bmbt_irec;
79 76
80extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, 77extern int xfs_iomap(struct xfs_inode *, xfs_off_t, ssize_t, int,
81 struct xfs_iomap *, int *); 78 struct xfs_iomap *, int *);
82extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, 79extern 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 */
500int 500int
501xfs_log_mount(xfs_mount_t *mp, 501xfs_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;
555error:
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 */
727void 744void
728xfs_log_unmount_dealloc(xfs_mount_t *mp) 745xfs_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,
836int 852int
837xfs_log_need_covered(xfs_mount_t *mp) 853xfs_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
881xlog_assign_tail_lsn(xfs_mount_t *mp) 896xlog_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 */
914int 928STATIC int
915xlog_space_left(xlog_t *log, int cycle, int bytes) 929xlog_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 */
1296void 1310STATIC void
1297xlog_grant_push_ail(xfs_mount_t *mp, 1311xlog_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
1381int 1393STATIC int
1382xlog_sync(xlog_t *log, 1394xlog_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 */
1530void 1537STATIC void
1531xlog_dealloc_log(xlog_t *log) 1538xlog_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 */
1755int 1759STATIC int
1756xlog_write(xfs_mount_t * mp, 1760xlog_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 */
2299void 2301STATIC void
2300xlog_state_done_syncing( 2302xlog_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 */
2360int 2361STATIC int
2361xlog_state_get_iclog_space(xlog_t *log, 2362xlog_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
2374restart: 2374restart:
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
2581xlog_regrant_write_log_space(xlog_t *log, 2581xlog_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
2720xlog_regrant_reserve_log_space(xlog_t *log, 2719xlog_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
2769xlog_ungrant_log_space(xlog_t *log, 2766xlog_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 */
2802void 2797STATIC void
2803xlog_state_put_ticket(xlog_t *log, 2798xlog_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 */
2822int 2815STATIC int
2823xlog_state_release_iclog(xlog_t *log, 2816xlog_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
3035no_sleep: 3026no_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 */
3054int 3045STATIC int
3055xlog_state_sync(xlog_t *log, 3046xlog_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
3065try_again: 3054try_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 */
3161void 3150STATIC void
3162xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) 3151xlog_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 */
3276xlog_ticket_t * 3262STATIC xlog_ticket_t *
3277xlog_ticket_get(xlog_t *log, 3263xlog_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 */
3554STATIC int 3540STATIC int
3555xlog_state_ioerror( 3541xlog_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) \ 59static 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) 64static 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 88static 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
287typedef struct xlog_op_header { 267typedef 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
309typedef struct xlog_rec_header { 289typedef 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
326typedef struct xlog_rec_ext_header { 306typedef 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 */
296int 296STATIC int
297xlog_find_cycle_start( 297xlog_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
496out: 495out:
@@ -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 */
989int 989STATIC int
990xlog_find_zeroed( 990xlog_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 */
748int 732STATIC int
749xfs_mountfs( 733xfs_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 */
806STATIC void
807xfs_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 */
833STATIC void
834xfs_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. 869STATIC void
919 */ 870xfs_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 */
892STATIC int
893xfs_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 */
950int
951xfs_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, &quotamount, &quotaflags))) 1171 error = XFS_QM_INIT(mp, &quotamount, &quotaflags);
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 */
1446int 1495int
1447xfs_mod_incore_sb_unlocked( 1496xfs_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 */
1612int 1661int
@@ -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(
1656int 1704int
1657xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) 1705xfs_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);
2291out: 2335out:
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
2296int 2340STATIC int
2297xfs_icsb_modify_counters( 2341xfs_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();
2308again: 2352again:
@@ -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;
56struct log; 56struct log;
57struct xfs_mount_args; 57struct xfs_mount_args;
58struct xfs_inode; 58struct xfs_inode;
59struct xfs_iocore;
60struct xfs_bmbt_irec; 59struct xfs_bmbt_irec;
61struct xfs_bmap_free; 60struct xfs_bmap_free;
62struct xfs_extdelta; 61struct xfs_extdelta;
63struct xfs_swapext; 62struct xfs_swapext;
64struct xfs_mru_cache; 63struct 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
204typedef int (*xfs_ioinit_t)(struct xfs_mount *,
205 struct xfs_mount_args *, int);
206typedef 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 *);
211typedef 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 *);
216typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
217typedef int (*xfs_iomap_write_direct_t)(
218 void *, xfs_off_t, size_t, int,
219 struct xfs_bmbt_irec *, int *, int);
220typedef int (*xfs_iomap_write_delay_t)(
221 void *, xfs_off_t, size_t, int,
222 struct xfs_bmbt_irec *, int *);
223typedef int (*xfs_iomap_write_allocate_t)(
224 void *, xfs_off_t, size_t,
225 struct xfs_bmbt_irec *, int *);
226typedef int (*xfs_iomap_write_unwritten_t)(
227 void *, xfs_off_t, size_t);
228typedef uint (*xfs_lck_map_shared_t)(void *);
229typedef void (*xfs_lock_t)(void *, uint);
230typedef void (*xfs_lock_demote_t)(void *, uint);
231typedef int (*xfs_lock_nowait_t)(void *, uint);
232typedef void (*xfs_unlk_t)(void *, unsigned int);
233typedef xfs_fsize_t (*xfs_size_t)(void *);
234typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_mount *);
235typedef int (*xfs_swap_extents_t)(void *, void *,
236 struct xfs_swapext*);
237
238typedef 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
222typedef 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
329typedef struct xfs_mount { 229typedef 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
616extern xfs_mount_t *xfs_mount_init(void); 512extern xfs_mount_t *xfs_mount_init(void);
617extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 513extern 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 *);
646extern void xfs_qmops_put(struct xfs_mount *); 542extern void xfs_qmops_put(struct xfs_mount *);
647 543
648extern struct xfs_dmops xfs_dmcore_xfs; 544extern struct xfs_dmops xfs_dmcore_xfs;
649extern struct xfs_ioops xfs_iocore_xfs;
650 545
651extern int xfs_init(void); 546extern int xfs_init(void);
652extern void xfs_cleanup(void); 547extern 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 */
229STATIC void 232STATIC 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
300int 304int
@@ -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
414void 418void
@@ -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 */
532void * 540void *
533xfs_mru_cache_lookup( 541xfs_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 */
587void 597void
588xfs_mru_cache_done( 598xfs_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 */
78STATIC int
79xfs_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 */
90STATIC int /* error */ 78STATIC 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 @@
21struct xfs_mount; 21struct xfs_mount;
22struct xfs_trans; 22struct 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;
32static inline xfs_daddr_t 32static inline xfs_daddr_t
33xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) 33xfs_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)
40static inline xfs_daddr_t
41xfs_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)
994void xfs_trans_cancel(xfs_trans_t *, int); 994void xfs_trans_cancel(xfs_trans_t *, int);
995void xfs_trans_ail_init(struct xfs_mount *); 995int xfs_trans_ail_init(struct xfs_mount *);
996xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); 996void xfs_trans_ail_destroy(struct xfs_mount *);
997void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
997xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *); 998xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *);
998void xfs_trans_unlocked_item(struct xfs_mount *, 999void 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
1005extern 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 *);
34STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *); 34STATIC xfs_log_item_t * xfs_ail_next(xfs_ail_entry_t *, xfs_log_item_t *);
35 35
36#ifdef DEBUG 36#ifdef DEBUG
37STATIC void xfs_ail_check(xfs_ail_entry_t *); 37STATIC 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 */
81xfs_lsn_t 87void
82xfs_trans_push_ail( 88xfs_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 */
106STATIC xfs_log_item_t *
107xfs_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 */
128long
129xfsaild_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 285out:
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 */
275void 351void
276xfs_trans_update_ail( 352xfs_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 */
328void 402void
329xfs_trans_delete_ail( 403xfs_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 */
440void 513int
441xfs_trans_ail_init( 514xfs_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
522void
523xfs_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 */
546STATIC void 627STATIC void
547xfs_ail_check( 628xfs_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
25STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *, 26STATIC 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 */
49void xfs_trans_update_ail(struct xfs_mount *mp, 49void 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);
53void xfs_trans_delete_ail(struct xfs_mount *mp, 52void 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);
56struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); 55struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *);
57struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, 56struct 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 */
63long xfsaild_push(struct xfs_mount *, xfs_lsn_t *);
64void xfsaild_wakeup(struct xfs_mount *, xfs_lsn_t);
65int xfsaild_start(struct xfs_mount *);
66void 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
26extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); 24extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **);
27extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *, 25extern 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
61int 61int __init
62xfs_init(void) 62xfs_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
155void 150void __exit
156xfs_cleanup(void) 151xfs_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 */
697STATIC void 684void
698xfs_attr_quiesce( 685xfs_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 */
830int
831xfs_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 */
850int
851xfs_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 */
1634int
1635xfs_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
1732STATIC unsigned long
1733suffix_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
1755int
1756xfs_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
2020done:
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
2028int
2029xfs_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 */
2119void
2120xfs_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,
13int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp); 13int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp);
14int xfs_mntupdate(struct xfs_mount *mp, int *flags, 14int xfs_mntupdate(struct xfs_mount *mp, int *flags,
15 struct xfs_mount_args *args); 15 struct xfs_mount_args *args);
16int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp);
17int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp,
18 bhv_vnode_t *vp);
19int xfs_sync(struct xfs_mount *mp, int flags); 16int xfs_sync(struct xfs_mount *mp, int flags);
20int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid);
21int xfs_parseargs(struct xfs_mount *mp, char *options,
22 struct xfs_mount_args *args, int update);
23int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
24void xfs_freeze(struct xfs_mount *mp);
25void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, 17void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
26 int lnnum); 18 int lnnum);
19void 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 */
910int
911xfs_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
3469int
3470xfs_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
3489int 3433int
3490xfs_rwlock( 3434xfs_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);
18int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags); 18int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags);
19int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, 19int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags,
20 struct cred *credp); 20 struct cred *credp);
21int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp);
22int xfs_readlink(struct xfs_inode *ip, char *link); 21int xfs_readlink(struct xfs_inode *ip, char *link);
23int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, 22int 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,
39int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, 38int 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);
42int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid);
43int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); 41int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
44void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); 42void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
45int xfs_inode_flush(struct xfs_inode *ip, int flags); 43int xfs_inode_flush(struct xfs_inode *ip, int flags);