aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6')
-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
16 files changed, 904 insertions, 461 deletions
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__ */