aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/mrlock.h12
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c89
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c21
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c163
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/quota/xfs_dquot.c3
-rw-r--r--fs/xfs/quota/xfs_qm.c16
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c19
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c4
-rw-r--r--fs/xfs/support/debug.c17
-rw-r--r--fs/xfs/support/debug.h2
-rw-r--r--fs/xfs/xfs_alloc.c2
-rw-r--r--fs/xfs/xfs_attr.c12
-rw-r--r--fs/xfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/xfs_bmap.c28
-rw-r--r--fs/xfs/xfs_dfrag.c6
-rw-r--r--fs/xfs/xfs_dir2_block.c14
-rw-r--r--fs/xfs/xfs_dir2_data.c7
-rw-r--r--fs/xfs/xfs_dir2_data.h2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c7
-rw-r--r--fs/xfs/xfs_dir2_node.c4
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_fsops.c4
-rw-r--r--fs/xfs/xfs_iget.c15
-rw-r--r--fs/xfs/xfs_inode.c58
-rw-r--r--fs/xfs/xfs_inode.h65
-rw-r--r--fs/xfs/xfs_iocore.c2
-rw-r--r--fs/xfs/xfs_iomap.c15
-rw-r--r--fs/xfs/xfs_iomap.h1
-rw-r--r--fs/xfs/xfs_log_recover.c15
-rw-r--r--fs/xfs/xfs_mount.c2
-rw-r--r--fs/xfs/xfs_qmops.c2
-rw-r--r--fs/xfs/xfs_quota.h3
-rw-r--r--fs/xfs/xfs_rename.c2
-rw-r--r--fs/xfs/xfs_rtalloc.c6
-rw-r--r--fs/xfs/xfs_rw.c4
-rw-r--r--fs/xfs/xfs_trans.c6
-rw-r--r--fs/xfs/xfs_trans.h4
-rw-r--r--fs/xfs/xfs_utils.c11
-rw-r--r--fs/xfs/xfs_vfsops.c6
-rw-r--r--fs/xfs/xfs_vnodeops.c125
44 files changed, 491 insertions, 304 deletions
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index af168a1a98c1..c110bb002665 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -43,6 +43,18 @@ static inline void mrupdate(mrlock_t *mrp)
43 mrp->mr_writer = 1; 43 mrp->mr_writer = 1;
44} 44}
45 45
46static inline void mraccess_nested(mrlock_t *mrp, int subclass)
47{
48 down_read_nested(&mrp->mr_lock, subclass);
49}
50
51static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
52{
53 down_write_nested(&mrp->mr_lock, subclass);
54 mrp->mr_writer = 1;
55}
56
57
46static inline int mrtryaccess(mrlock_t *mrp) 58static inline int mrtryaccess(mrlock_t *mrp)
47{ 59{
48 return down_read_trylock(&mrp->mr_lock); 60 return down_read_trylock(&mrp->mr_lock);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 143ffc851c9d..4475588e973a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -141,9 +141,46 @@ xfs_destroy_ioend(
141} 141}
142 142
143/* 143/*
144 * Update on-disk file size now that data has been written to disk.
145 * The current in-memory file size is i_size. If a write is beyond
146 * eof io_new_size will be the intended file size until i_size is
147 * updated. If this write does not extend all the way to the valid
148 * file size then restrict this update to the end of the write.
149 */
150STATIC void
151xfs_setfilesize(
152 xfs_ioend_t *ioend)
153{
154 xfs_inode_t *ip;
155 xfs_fsize_t isize;
156 xfs_fsize_t bsize;
157
158 ip = xfs_vtoi(ioend->io_vnode);
159
160 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
161 ASSERT(ioend->io_type != IOMAP_READ);
162
163 if (unlikely(ioend->io_error))
164 return;
165
166 bsize = ioend->io_offset + ioend->io_size;
167
168 xfs_ilock(ip, XFS_ILOCK_EXCL);
169
170 isize = MAX(ip->i_size, ip->i_iocore.io_new_size);
171 isize = MIN(isize, bsize);
172
173 if (ip->i_d.di_size < isize) {
174 ip->i_d.di_size = isize;
175 ip->i_update_core = 1;
176 ip->i_update_size = 1;
177 }
178
179 xfs_iunlock(ip, XFS_ILOCK_EXCL);
180}
181
182/*
144 * Buffered IO write completion for delayed allocate extents. 183 * Buffered IO write completion for delayed allocate extents.
145 * TODO: Update ondisk isize now that we know the file data
146 * has been flushed (i.e. the notorious "NULL file" problem).
147 */ 184 */
148STATIC void 185STATIC void
149xfs_end_bio_delalloc( 186xfs_end_bio_delalloc(
@@ -152,6 +189,7 @@ xfs_end_bio_delalloc(
152 xfs_ioend_t *ioend = 189 xfs_ioend_t *ioend =
153 container_of(work, xfs_ioend_t, io_work); 190 container_of(work, xfs_ioend_t, io_work);
154 191
192 xfs_setfilesize(ioend);
155 xfs_destroy_ioend(ioend); 193 xfs_destroy_ioend(ioend);
156} 194}
157 195
@@ -165,6 +203,7 @@ xfs_end_bio_written(
165 xfs_ioend_t *ioend = 203 xfs_ioend_t *ioend =
166 container_of(work, xfs_ioend_t, io_work); 204 container_of(work, xfs_ioend_t, io_work);
167 205
206 xfs_setfilesize(ioend);
168 xfs_destroy_ioend(ioend); 207 xfs_destroy_ioend(ioend);
169} 208}
170 209
@@ -184,8 +223,23 @@ xfs_end_bio_unwritten(
184 xfs_off_t offset = ioend->io_offset; 223 xfs_off_t offset = ioend->io_offset;
185 size_t size = ioend->io_size; 224 size_t size = ioend->io_size;
186 225
187 if (likely(!ioend->io_error)) 226 if (likely(!ioend->io_error)) {
188 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); 227 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
228 xfs_setfilesize(ioend);
229 }
230 xfs_destroy_ioend(ioend);
231}
232
233/*
234 * IO read completion for regular, written extents.
235 */
236STATIC void
237xfs_end_bio_read(
238 struct work_struct *work)
239{
240 xfs_ioend_t *ioend =
241 container_of(work, xfs_ioend_t, io_work);
242
189 xfs_destroy_ioend(ioend); 243 xfs_destroy_ioend(ioend);
190} 244}
191 245
@@ -224,6 +278,8 @@ xfs_alloc_ioend(
224 INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); 278 INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten);
225 else if (type == IOMAP_DELAY) 279 else if (type == IOMAP_DELAY)
226 INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); 280 INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc);
281 else if (type == IOMAP_READ)
282 INIT_WORK(&ioend->io_work, xfs_end_bio_read);
227 else 283 else
228 INIT_WORK(&ioend->io_work, xfs_end_bio_written); 284 INIT_WORK(&ioend->io_work, xfs_end_bio_written);
229 285
@@ -913,7 +969,7 @@ xfs_page_state_convert(
913 bh = head = page_buffers(page); 969 bh = head = page_buffers(page);
914 offset = page_offset(page); 970 offset = page_offset(page);
915 flags = -1; 971 flags = -1;
916 type = 0; 972 type = IOMAP_READ;
917 973
918 /* TODO: cleanup count and page_dirty */ 974 /* TODO: cleanup count and page_dirty */
919 975
@@ -999,7 +1055,7 @@ xfs_page_state_convert(
999 * That means it must already have extents allocated 1055 * That means it must already have extents allocated
1000 * underneath it. Map the extent by reading it. 1056 * underneath it. Map the extent by reading it.
1001 */ 1057 */
1002 if (!iomap_valid || type != 0) { 1058 if (!iomap_valid || type != IOMAP_READ) {
1003 flags = BMAPI_READ; 1059 flags = BMAPI_READ;
1004 size = xfs_probe_cluster(inode, page, bh, 1060 size = xfs_probe_cluster(inode, page, bh,
1005 head, 1); 1061 head, 1);
@@ -1010,7 +1066,7 @@ xfs_page_state_convert(
1010 iomap_valid = xfs_iomap_valid(&iomap, offset); 1066 iomap_valid = xfs_iomap_valid(&iomap, offset);
1011 } 1067 }
1012 1068
1013 type = 0; 1069 type = IOMAP_READ;
1014 if (!test_and_set_bit(BH_Lock, &bh->b_state)) { 1070 if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
1015 ASSERT(buffer_mapped(bh)); 1071 ASSERT(buffer_mapped(bh));
1016 if (iomap_valid) 1072 if (iomap_valid)
@@ -1356,12 +1412,21 @@ xfs_end_io_direct(
1356 * completion handler in the future, in which case all this can 1412 * completion handler in the future, in which case all this can
1357 * go away. 1413 * go away.
1358 */ 1414 */
1359 if (private && size > 0) { 1415 ioend->io_offset = offset;
1360 ioend->io_offset = offset; 1416 ioend->io_size = size;
1361 ioend->io_size = size; 1417 if (ioend->io_type == IOMAP_READ) {
1418 xfs_finish_ioend(ioend);
1419 } else if (private && size > 0) {
1362 xfs_finish_ioend(ioend); 1420 xfs_finish_ioend(ioend);
1363 } else { 1421 } else {
1364 xfs_destroy_ioend(ioend); 1422 /*
1423 * A direct I/O write ioend starts it's life in unwritten
1424 * state in case they map an unwritten extent. This write
1425 * didn't map an unwritten extent so switch it's completion
1426 * handler.
1427 */
1428 INIT_WORK(&ioend->io_work, xfs_end_bio_written);
1429 xfs_finish_ioend(ioend);
1365 } 1430 }
1366 1431
1367 /* 1432 /*
@@ -1392,15 +1457,15 @@ xfs_vm_direct_IO(
1392 if (error) 1457 if (error)
1393 return -error; 1458 return -error;
1394 1459
1395 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
1396
1397 if (rw == WRITE) { 1460 if (rw == WRITE) {
1461 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
1398 ret = blockdev_direct_IO_own_locking(rw, iocb, inode, 1462 ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
1399 iomap.iomap_target->bt_bdev, 1463 iomap.iomap_target->bt_bdev,
1400 iov, offset, nr_segs, 1464 iov, offset, nr_segs,
1401 xfs_get_blocks_direct, 1465 xfs_get_blocks_direct,
1402 xfs_end_io_direct); 1466 xfs_end_io_direct);
1403 } else { 1467 } else {
1468 iocb->private = xfs_alloc_ioend(inode, IOMAP_READ);
1404 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, 1469 ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
1405 iomap.iomap_target->bt_bdev, 1470 iomap.iomap_target->bt_bdev,
1406 iov, offset, nr_segs, 1471 iov, offset, nr_segs,
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 69e9e80735d2..fe4f66a5af14 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1426,7 +1426,7 @@ xfs_free_bufhash(
1426/* 1426/*
1427 * buftarg list for delwrite queue processing 1427 * buftarg list for delwrite queue processing
1428 */ 1428 */
1429LIST_HEAD(xfs_buftarg_list); 1429static LIST_HEAD(xfs_buftarg_list);
1430static DEFINE_SPINLOCK(xfs_buftarg_lock); 1430static DEFINE_SPINLOCK(xfs_buftarg_lock);
1431 1431
1432STATIC void 1432STATIC void
@@ -1867,3 +1867,11 @@ xfs_buf_terminate(void)
1867 ktrace_free(xfs_buf_trace_buf); 1867 ktrace_free(xfs_buf_trace_buf);
1868#endif 1868#endif
1869} 1869}
1870
1871#ifdef CONFIG_KDB_MODULES
1872struct list_head *
1873xfs_get_buftarg_list(void)
1874{
1875 return &xfs_buftarg_list;
1876}
1877#endif
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 9e8ef8fef39f..b6241f6201a5 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -411,6 +411,9 @@ extern void xfs_free_buftarg(xfs_buftarg_t *, int);
411extern void xfs_wait_buftarg(xfs_buftarg_t *); 411extern void xfs_wait_buftarg(xfs_buftarg_t *);
412extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); 412extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
413extern int xfs_flush_buftarg(xfs_buftarg_t *, int); 413extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
414#ifdef CONFIG_KDB_MODULES
415extern struct list_head *xfs_get_buftarg_list(void);
416#endif
414 417
415#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) 418#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
416#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) 419#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index dc0562828e76..2eb87cd082af 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -35,7 +35,7 @@ fs_tosspages(
35 truncate_inode_pages(ip->i_mapping, first); 35 truncate_inode_pages(ip->i_mapping, first);
36} 36}
37 37
38void 38int
39fs_flushinval_pages( 39fs_flushinval_pages(
40 bhv_desc_t *bdp, 40 bhv_desc_t *bdp,
41 xfs_off_t first, 41 xfs_off_t first,
@@ -44,13 +44,16 @@ fs_flushinval_pages(
44{ 44{
45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp); 45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
46 struct inode *ip = vn_to_inode(vp); 46 struct inode *ip = vn_to_inode(vp);
47 int ret = 0;
47 48
48 if (VN_CACHED(vp)) { 49 if (VN_CACHED(vp)) {
49 if (VN_TRUNC(vp)) 50 if (VN_TRUNC(vp))
50 VUNTRUNCATE(vp); 51 VUNTRUNCATE(vp);
51 filemap_write_and_wait(ip->i_mapping); 52 ret = filemap_write_and_wait(ip->i_mapping);
52 truncate_inode_pages(ip->i_mapping, first); 53 if (!ret)
54 truncate_inode_pages(ip->i_mapping, first);
53 } 55 }
56 return ret;
54} 57}
55 58
56int 59int
@@ -63,14 +66,18 @@ fs_flush_pages(
63{ 66{
64 bhv_vnode_t *vp = BHV_TO_VNODE(bdp); 67 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
65 struct inode *ip = vn_to_inode(vp); 68 struct inode *ip = vn_to_inode(vp);
69 int ret = 0;
70 int ret2;
66 71
67 if (VN_DIRTY(vp)) { 72 if (VN_DIRTY(vp)) {
68 if (VN_TRUNC(vp)) 73 if (VN_TRUNC(vp))
69 VUNTRUNCATE(vp); 74 VUNTRUNCATE(vp);
70 filemap_fdatawrite(ip->i_mapping); 75 ret = filemap_fdatawrite(ip->i_mapping);
71 if (flags & XFS_B_ASYNC) 76 if (flags & XFS_B_ASYNC)
72 return 0; 77 return ret;
73 filemap_fdatawait(ip->i_mapping); 78 ret2 = filemap_fdatawait(ip->i_mapping);
79 if (!ret)
80 ret = ret2;
74 } 81 }
75 return 0; 82 return ret;
76} 83}
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
index aee9ccdd18f7..c1b53118a303 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.h
@@ -23,7 +23,7 @@ extern int fs_noerr(void);
23extern int fs_nosys(void); 23extern int fs_nosys(void);
24extern void fs_noval(void); 24extern void fs_noval(void);
25extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 25extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
26extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 26extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
27extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int); 27extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
28 28
29#endif /* __XFS_FS_SUBR_H__ */ 29#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 558076dd0752..86fb671a8bcc 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -191,7 +191,7 @@ xfs_read(
191 struct file *file = iocb->ki_filp; 191 struct file *file = iocb->ki_filp;
192 struct inode *inode = file->f_mapping->host; 192 struct inode *inode = file->f_mapping->host;
193 size_t size = 0; 193 size_t size = 0;
194 ssize_t ret; 194 ssize_t ret = 0;
195 xfs_fsize_t n; 195 xfs_fsize_t n;
196 xfs_inode_t *ip; 196 xfs_inode_t *ip;
197 xfs_mount_t *mp; 197 xfs_mount_t *mp;
@@ -224,7 +224,7 @@ xfs_read(
224 mp->m_rtdev_targp : mp->m_ddev_targp; 224 mp->m_rtdev_targp : mp->m_ddev_targp;
225 if ((*offset & target->bt_smask) || 225 if ((*offset & target->bt_smask) ||
226 (size & target->bt_smask)) { 226 (size & target->bt_smask)) {
227 if (*offset == ip->i_d.di_size) { 227 if (*offset == ip->i_size) {
228 return (0); 228 return (0);
229 } 229 }
230 return -XFS_ERROR(EINVAL); 230 return -XFS_ERROR(EINVAL);
@@ -263,9 +263,13 @@ xfs_read(
263 263
264 if (unlikely(ioflags & IO_ISDIRECT)) { 264 if (unlikely(ioflags & IO_ISDIRECT)) {
265 if (VN_CACHED(vp)) 265 if (VN_CACHED(vp))
266 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), 266 ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
267 -1, FI_REMAPF_LOCKED); 267 -1, FI_REMAPF_LOCKED);
268 mutex_unlock(&inode->i_mutex); 268 mutex_unlock(&inode->i_mutex);
269 if (ret) {
270 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
271 return ret;
272 }
269 } 273 }
270 274
271 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 275 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -383,9 +387,10 @@ xfs_splice_write(
383{ 387{
384 xfs_inode_t *ip = XFS_BHVTOI(bdp); 388 xfs_inode_t *ip = XFS_BHVTOI(bdp);
385 xfs_mount_t *mp = ip->i_mount; 389 xfs_mount_t *mp = ip->i_mount;
390 xfs_iocore_t *io = &ip->i_iocore;
386 ssize_t ret; 391 ssize_t ret;
387 struct inode *inode = outfilp->f_mapping->host; 392 struct inode *inode = outfilp->f_mapping->host;
388 xfs_fsize_t isize; 393 xfs_fsize_t isize, new_size;
389 394
390 XFS_STATS_INC(xs_write_calls); 395 XFS_STATS_INC(xs_write_calls);
391 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 396 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -406,6 +411,14 @@ xfs_splice_write(
406 return -error; 411 return -error;
407 } 412 }
408 } 413 }
414
415 new_size = *ppos + count;
416
417 xfs_ilock(ip, XFS_ILOCK_EXCL);
418 if (new_size > ip->i_size)
419 io->io_new_size = new_size;
420 xfs_iunlock(ip, XFS_ILOCK_EXCL);
421
409 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, 422 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
410 pipe, count, *ppos, ioflags); 423 pipe, count, *ppos, ioflags);
411 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); 424 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
@@ -416,14 +429,18 @@ xfs_splice_write(
416 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) 429 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
417 *ppos = isize; 430 *ppos = isize;
418 431
419 if (*ppos > ip->i_d.di_size) { 432 if (*ppos > ip->i_size) {
420 xfs_ilock(ip, XFS_ILOCK_EXCL); 433 xfs_ilock(ip, XFS_ILOCK_EXCL);
421 if (*ppos > ip->i_d.di_size) { 434 if (*ppos > ip->i_size)
422 ip->i_d.di_size = *ppos; 435 ip->i_size = *ppos;
423 i_size_write(inode, *ppos); 436 xfs_iunlock(ip, XFS_ILOCK_EXCL);
424 ip->i_update_core = 1; 437 }
425 ip->i_update_size = 1; 438
426 } 439 if (io->io_new_size) {
440 xfs_ilock(ip, XFS_ILOCK_EXCL);
441 io->io_new_size = 0;
442 if (ip->i_d.di_size > ip->i_size)
443 ip->i_d.di_size = ip->i_size;
427 xfs_iunlock(ip, XFS_ILOCK_EXCL); 444 xfs_iunlock(ip, XFS_ILOCK_EXCL);
428 } 445 }
429 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 446 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -644,7 +661,7 @@ xfs_write(
644 bhv_vrwlock_t locktype; 661 bhv_vrwlock_t locktype;
645 size_t ocount = 0, count; 662 size_t ocount = 0, count;
646 loff_t pos; 663 loff_t pos;
647 int need_i_mutex = 1, need_flush = 0; 664 int need_i_mutex;
648 665
649 XFS_STATS_INC(xs_write_calls); 666 XFS_STATS_INC(xs_write_calls);
650 667
@@ -669,39 +686,20 @@ xfs_write(
669 if (XFS_FORCED_SHUTDOWN(mp)) 686 if (XFS_FORCED_SHUTDOWN(mp))
670 return -EIO; 687 return -EIO;
671 688
672 if (ioflags & IO_ISDIRECT) {
673 xfs_buftarg_t *target =
674 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
675 mp->m_rtdev_targp : mp->m_ddev_targp;
676
677 if ((pos & target->bt_smask) || (count & target->bt_smask))
678 return XFS_ERROR(-EINVAL);
679
680 if (!VN_CACHED(vp) && pos < i_size_read(inode))
681 need_i_mutex = 0;
682
683 if (VN_CACHED(vp))
684 need_flush = 1;
685 }
686
687relock: 689relock:
688 if (need_i_mutex) { 690 if (ioflags & IO_ISDIRECT) {
691 iolock = XFS_IOLOCK_SHARED;
692 locktype = VRWLOCK_WRITE_DIRECT;
693 need_i_mutex = 0;
694 } else {
689 iolock = XFS_IOLOCK_EXCL; 695 iolock = XFS_IOLOCK_EXCL;
690 locktype = VRWLOCK_WRITE; 696 locktype = VRWLOCK_WRITE;
691 697 need_i_mutex = 1;
692 mutex_lock(&inode->i_mutex); 698 mutex_lock(&inode->i_mutex);
693 } else {
694 iolock = XFS_IOLOCK_SHARED;
695 locktype = VRWLOCK_WRITE_DIRECT;
696 } 699 }
697 700
698 xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); 701 xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
699 702
700 isize = i_size_read(inode);
701
702 if (file->f_flags & O_APPEND)
703 *offset = isize;
704
705start: 703start:
706 error = -generic_write_checks(file, &pos, &count, 704 error = -generic_write_checks(file, &pos, &count,
707 S_ISBLK(inode->i_mode)); 705 S_ISBLK(inode->i_mode));
@@ -710,13 +708,8 @@ start:
710 goto out_unlock_mutex; 708 goto out_unlock_mutex;
711 } 709 }
712 710
713 new_size = pos + count;
714 if (new_size > isize)
715 io->io_new_size = new_size;
716
717 if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && 711 if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
718 !(ioflags & IO_INVIS) && !eventsent)) { 712 !(ioflags & IO_INVIS) && !eventsent)) {
719 loff_t savedsize = pos;
720 int dmflags = FILP_DELAY_FLAG(file); 713 int dmflags = FILP_DELAY_FLAG(file);
721 714
722 if (need_i_mutex) 715 if (need_i_mutex)
@@ -727,8 +720,7 @@ start:
727 pos, count, 720 pos, count,
728 dmflags, &locktype); 721 dmflags, &locktype);
729 if (error) { 722 if (error) {
730 xfs_iunlock(xip, iolock); 723 goto out_unlock_internal;
731 goto out_unlock_mutex;
732 } 724 }
733 xfs_ilock(xip, XFS_ILOCK_EXCL); 725 xfs_ilock(xip, XFS_ILOCK_EXCL);
734 eventsent = 1; 726 eventsent = 1;
@@ -740,12 +732,35 @@ start:
740 * event prevents another call to XFS_SEND_DATA, which is 732 * event prevents another call to XFS_SEND_DATA, which is
741 * what allows the size to change in the first place. 733 * what allows the size to change in the first place.
742 */ 734 */
743 if ((file->f_flags & O_APPEND) && savedsize != isize) { 735 if ((file->f_flags & O_APPEND) && pos != xip->i_size)
744 pos = isize = xip->i_d.di_size; 736 goto start;
737 }
738
739 if (ioflags & IO_ISDIRECT) {
740 xfs_buftarg_t *target =
741 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
742 mp->m_rtdev_targp : mp->m_ddev_targp;
743
744 if ((pos & target->bt_smask) || (count & target->bt_smask)) {
745 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
746 return XFS_ERROR(-EINVAL);
747 }
748
749 if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
750 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
751 iolock = XFS_IOLOCK_EXCL;
752 locktype = VRWLOCK_WRITE;
753 need_i_mutex = 1;
754 mutex_lock(&inode->i_mutex);
755 xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
745 goto start; 756 goto start;
746 } 757 }
747 } 758 }
748 759
760 new_size = pos + count;
761 if (new_size > xip->i_size)
762 io->io_new_size = new_size;
763
749 if (likely(!(ioflags & IO_INVIS))) { 764 if (likely(!(ioflags & IO_INVIS))) {
750 file_update_time(file); 765 file_update_time(file);
751 xfs_ichgtime_fast(xip, inode, 766 xfs_ichgtime_fast(xip, inode,
@@ -761,11 +776,11 @@ start:
761 * to zero it out up to the new size. 776 * to zero it out up to the new size.
762 */ 777 */
763 778
764 if (pos > isize) { 779 if (pos > xip->i_size) {
765 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize); 780 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size);
766 if (error) { 781 if (error) {
767 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); 782 xfs_iunlock(xip, XFS_ILOCK_EXCL);
768 goto out_unlock_mutex; 783 goto out_unlock_internal;
769 } 784 }
770 } 785 }
771 xfs_iunlock(xip, XFS_ILOCK_EXCL); 786 xfs_iunlock(xip, XFS_ILOCK_EXCL);
@@ -785,8 +800,7 @@ start:
785 if (likely(!error)) 800 if (likely(!error))
786 error = -remove_suid(file->f_path.dentry); 801 error = -remove_suid(file->f_path.dentry);
787 if (unlikely(error)) { 802 if (unlikely(error)) {
788 xfs_iunlock(xip, iolock); 803 goto out_unlock_internal;
789 goto out_unlock_mutex;
790 } 804 }
791 } 805 }
792 806
@@ -795,11 +809,14 @@ retry:
795 current->backing_dev_info = mapping->backing_dev_info; 809 current->backing_dev_info = mapping->backing_dev_info;
796 810
797 if ((ioflags & IO_ISDIRECT)) { 811 if ((ioflags & IO_ISDIRECT)) {
798 if (need_flush) { 812 if (VN_CACHED(vp)) {
813 WARN_ON(need_i_mutex == 0);
799 xfs_inval_cached_trace(io, pos, -1, 814 xfs_inval_cached_trace(io, pos, -1,
800 ctooff(offtoct(pos)), -1); 815 ctooff(offtoct(pos)), -1);
801 bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)), 816 error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
802 -1, FI_REMAPF_LOCKED); 817 -1, FI_REMAPF_LOCKED);
818 if (error)
819 goto out_unlock_internal;
803 } 820 }
804 821
805 if (need_i_mutex) { 822 if (need_i_mutex) {
@@ -827,7 +844,6 @@ retry:
827 pos += ret; 844 pos += ret;
828 count -= ret; 845 count -= ret;
829 846
830 need_i_mutex = 1;
831 ioflags &= ~IO_ISDIRECT; 847 ioflags &= ~IO_ISDIRECT;
832 xfs_iunlock(xip, iolock); 848 xfs_iunlock(xip, iolock);
833 goto relock; 849 goto relock;
@@ -854,12 +870,12 @@ retry:
854 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, 870 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
855 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, 871 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
856 0, 0, 0); /* Delay flag intentionally unused */ 872 0, 0, 0); /* Delay flag intentionally unused */
857 if (error)
858 goto out_nounlocks;
859 if (need_i_mutex) 873 if (need_i_mutex)
860 mutex_lock(&inode->i_mutex); 874 mutex_lock(&inode->i_mutex);
861 xfs_rwlock(bdp, locktype); 875 xfs_rwlock(bdp, locktype);
862 pos = xip->i_d.di_size; 876 if (error)
877 goto out_unlock_internal;
878 pos = xip->i_size;
863 ret = 0; 879 ret = 0;
864 goto retry; 880 goto retry;
865 } 881 }
@@ -868,14 +884,10 @@ retry:
868 if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) 884 if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
869 *offset = isize; 885 *offset = isize;
870 886
871 if (*offset > xip->i_d.di_size) { 887 if (*offset > xip->i_size) {
872 xfs_ilock(xip, XFS_ILOCK_EXCL); 888 xfs_ilock(xip, XFS_ILOCK_EXCL);
873 if (*offset > xip->i_d.di_size) { 889 if (*offset > xip->i_size)
874 xip->i_d.di_size = *offset; 890 xip->i_size = *offset;
875 i_size_write(inode, *offset);
876 xip->i_update_core = 1;
877 xip->i_update_size = 1;
878 }
879 xfs_iunlock(xip, XFS_ILOCK_EXCL); 891 xfs_iunlock(xip, XFS_ILOCK_EXCL);
880 } 892 }
881 893
@@ -897,16 +909,31 @@ retry:
897 909
898 error = sync_page_range(inode, mapping, pos, ret); 910 error = sync_page_range(inode, mapping, pos, ret);
899 if (!error) 911 if (!error)
900 error = ret; 912 error = -ret;
901 return error; 913 if (need_i_mutex)
914 mutex_lock(&inode->i_mutex);
915 xfs_rwlock(bdp, locktype);
902 } 916 }
903 917
904 out_unlock_internal: 918 out_unlock_internal:
919 if (io->io_new_size) {
920 xfs_ilock(xip, XFS_ILOCK_EXCL);
921 io->io_new_size = 0;
922 /*
923 * If this was a direct or synchronous I/O that failed (such
924 * as ENOSPC) then part of the I/O may have been written to
925 * disk before the error occured. In this case the on-disk
926 * file size may have been adjusted beyond the in-memory file
927 * size and now needs to be truncated back.
928 */
929 if (xip->i_d.di_size > xip->i_size)
930 xip->i_d.di_size = xip->i_size;
931 xfs_iunlock(xip, XFS_ILOCK_EXCL);
932 }
905 xfs_rwunlock(bdp, locktype); 933 xfs_rwunlock(bdp, locktype);
906 out_unlock_mutex: 934 out_unlock_mutex:
907 if (need_i_mutex) 935 if (need_i_mutex)
908 mutex_unlock(&inode->i_mutex); 936 mutex_unlock(&inode->i_mutex);
909 out_nounlocks:
910 return -error; 937 return -error;
911} 938}
912 939
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index b76118cf4897..d1b2d01843d1 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -194,7 +194,7 @@ typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
194typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int); 194typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
195typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t); 195typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
196typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 196typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
197typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 197typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
198typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, 198typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
199 uint64_t, int); 199 uint64_t, int);
200typedef int (*vop_iflush_t)(bhv_desc_t *, int); 200typedef int (*vop_iflush_t)(bhv_desc_t *, int);
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 4adaf13aac6f..cfdd35ee9f7a 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -753,8 +753,7 @@ xfs_qm_idtodq(
753 goto error0; 753 goto error0;
754 } 754 }
755 if (tp) { 755 if (tp) {
756 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, 756 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES)))
757 NULL)))
758 goto error1; 757 goto error1;
759 } 758 }
760 759
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 1de2acdc7f70..3e4a8ad8a34c 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -388,6 +388,17 @@ xfs_qm_mount_quotas(
388 return XFS_ERROR(error); 388 return XFS_ERROR(error);
389 } 389 }
390 } 390 }
391 /*
392 * If one type of quotas is off, then it will lose its
393 * quotachecked status, since we won't be doing accounting for
394 * that type anymore.
395 */
396 if (!XFS_IS_UQUOTA_ON(mp)) {
397 mp->m_qflags &= ~XFS_UQUOTA_CHKD;
398 }
399 if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) {
400 mp->m_qflags &= ~XFS_OQUOTA_CHKD;
401 }
391 402
392 write_changes: 403 write_changes:
393 /* 404 /*
@@ -1453,8 +1464,7 @@ xfs_qm_qino_alloc(
1453 XFS_SB_UNLOCK(mp, s); 1464 XFS_SB_UNLOCK(mp, s);
1454 xfs_mod_sb(tp, sbfields); 1465 xfs_mod_sb(tp, sbfields);
1455 1466
1456 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, 1467 if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
1457 NULL))) {
1458 xfs_fs_cmn_err(CE_ALERT, mp, "XFS qino_alloc failed!"); 1468 xfs_fs_cmn_err(CE_ALERT, mp, "XFS qino_alloc failed!");
1459 return error; 1469 return error;
1460 } 1470 }
@@ -2405,7 +2415,7 @@ xfs_qm_write_sb_changes(
2405 } 2415 }
2406 2416
2407 xfs_mod_sb(tp, flags); 2417 xfs_mod_sb(tp, flags);
2408 (void) xfs_trans_commit(tp, 0, NULL); 2418 (void) xfs_trans_commit(tp, 0);
2409 2419
2410 return 0; 2420 return 0;
2411} 2421}
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 716f562aa8b2..2df67fd913e5 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -456,9 +456,7 @@ xfs_qm_scall_quotaon(
456 || 456 ||
457 ((flags & XFS_PQUOTA_ACCT) == 0 && 457 ((flags & XFS_PQUOTA_ACCT) == 0 &&
458 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && 458 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
459 (flags & XFS_OQUOTA_ENFD)) 459 (flags & XFS_GQUOTA_ACCT) == 0 &&
460 ||
461 ((flags & XFS_GQUOTA_ACCT) == 0 &&
462 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && 460 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
463 (flags & XFS_OQUOTA_ENFD))) { 461 (flags & XFS_OQUOTA_ENFD))) {
464 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", 462 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
@@ -735,7 +733,7 @@ xfs_qm_scall_setqlim(
735 xfs_trans_log_dquot(tp, dqp); 733 xfs_trans_log_dquot(tp, dqp);
736 734
737 xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); 735 xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT");
738 xfs_trans_commit(tp, 0, NULL); 736 xfs_trans_commit(tp, 0);
739 xfs_qm_dqprint(dqp); 737 xfs_qm_dqprint(dqp);
740 xfs_qm_dqrele(dqp); 738 xfs_qm_dqrele(dqp);
741 mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); 739 mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
@@ -809,7 +807,7 @@ xfs_qm_log_quotaoff_end(
809 * We don't care about quotoff's performance. 807 * We don't care about quotoff's performance.
810 */ 808 */
811 xfs_trans_set_sync(tp); 809 xfs_trans_set_sync(tp);
812 error = xfs_trans_commit(tp, 0, NULL); 810 error = xfs_trans_commit(tp, 0);
813 return (error); 811 return (error);
814} 812}
815 813
@@ -852,7 +850,7 @@ xfs_qm_log_quotaoff(
852 * We don't care about quotoff's performance. 850 * We don't care about quotoff's performance.
853 */ 851 */
854 xfs_trans_set_sync(tp); 852 xfs_trans_set_sync(tp);
855 error = xfs_trans_commit(tp, 0, NULL); 853 error = xfs_trans_commit(tp, 0);
856 854
857error0: 855error0:
858 if (error) { 856 if (error) {
@@ -911,14 +909,19 @@ xfs_qm_export_dquot(
911 * gets turned off. No need to confuse the user level code, 909 * gets turned off. No need to confuse the user level code,
912 * so return zeroes in that case. 910 * so return zeroes in that case.
913 */ 911 */
914 if (! XFS_IS_QUOTA_ENFORCED(mp)) { 912 if ((!XFS_IS_UQUOTA_ENFORCED(mp) && src->d_flags == XFS_DQ_USER) ||
913 (!XFS_IS_OQUOTA_ENFORCED(mp) &&
914 (src->d_flags & (XFS_DQ_PROJ | XFS_DQ_GROUP)))) {
915 dst->d_btimer = 0; 915 dst->d_btimer = 0;
916 dst->d_itimer = 0; 916 dst->d_itimer = 0;
917 dst->d_rtbtimer = 0; 917 dst->d_rtbtimer = 0;
918 } 918 }
919 919
920#ifdef DEBUG 920#ifdef DEBUG
921 if (XFS_IS_QUOTA_ENFORCED(mp) && dst->d_id != 0) { 921 if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) ||
922 (XFS_IS_OQUOTA_ENFORCED(mp) &&
923 (dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) &&
924 dst->d_id != 0) {
922 if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) && 925 if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
923 (dst->d_blk_softlimit > 0)) { 926 (dst->d_blk_softlimit > 0)) {
924 ASSERT(dst->d_btimer != 0); 927 ASSERT(dst->d_btimer != 0);
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index d7491e7b1f3b..7de6874bf1b8 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -656,7 +656,9 @@ xfs_trans_dqresv(
656 656
657 if ((flags & XFS_QMOPT_FORCE_RES) == 0 && 657 if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
658 dqp->q_core.d_id && 658 dqp->q_core.d_id &&
659 XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) { 659 ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
660 (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
661 (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
660#ifdef QUOTADEBUG 662#ifdef QUOTADEBUG
661 cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld" 663 cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
662 " > hardlimit=%Ld?", nblks, *resbcountp, hardlimit); 664 " > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 08bbd3cb87ae..f45a49ffd3a3 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -81,20 +81,3 @@ assfail(char *expr, char *file, int line)
81 printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line); 81 printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line);
82 BUG(); 82 BUG();
83} 83}
84
85#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
86unsigned long random(void)
87{
88 static unsigned long RandomValue = 1;
89 /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
90 register long rv = RandomValue;
91 register long lo;
92 register long hi;
93
94 hi = rv / 127773;
95 lo = rv % 127773;
96 rv = 16807 * lo - 2836 * hi;
97 if (rv <= 0) rv += 2147483647;
98 return RandomValue = rv;
99}
100#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index 2a70cc605ae3..a27a7c8c0526 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -50,7 +50,7 @@ extern void assfail(char *expr, char *f, int l);
50#else /* DEBUG */ 50#else /* DEBUG */
51 51
52# define ASSERT(expr) ASSERT_ALWAYS(expr) 52# define ASSERT(expr) ASSERT_ALWAYS(expr)
53extern unsigned long random(void); 53# include <linux/random.h>
54 54
55#ifndef STATIC 55#ifndef STATIC
56# define STATIC noinline 56# define STATIC noinline
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index e80dda3437d1..8e9a40aa0cd3 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -764,7 +764,7 @@ xfs_alloc_ag_vextent_near(
764 */ 764 */
765 int dofirst; /* set to do first algorithm */ 765 int dofirst; /* set to do first algorithm */
766 766
767 dofirst = random() & 1; 767 dofirst = random32() & 1;
768#endif 768#endif
769 /* 769 /*
770 * Get a cursor for the by-size btree. 770 * Get a cursor for the by-size btree.
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 9d358ffce4e5..7ce44a7b88a2 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -328,8 +328,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
328 xfs_trans_set_sync(args.trans); 328 xfs_trans_set_sync(args.trans);
329 } 329 }
330 err2 = xfs_trans_commit(args.trans, 330 err2 = xfs_trans_commit(args.trans,
331 XFS_TRANS_RELEASE_LOG_RES, 331 XFS_TRANS_RELEASE_LOG_RES);
332 NULL);
333 xfs_iunlock(dp, XFS_ILOCK_EXCL); 332 xfs_iunlock(dp, XFS_ILOCK_EXCL);
334 333
335 /* 334 /*
@@ -397,8 +396,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
397 * Commit the last in the sequence of transactions. 396 * Commit the last in the sequence of transactions.
398 */ 397 */
399 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); 398 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
400 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES, 399 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
401 NULL);
402 xfs_iunlock(dp, XFS_ILOCK_EXCL); 400 xfs_iunlock(dp, XFS_ILOCK_EXCL);
403 401
404 /* 402 /*
@@ -544,8 +542,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
544 * Commit the last in the sequence of transactions. 542 * Commit the last in the sequence of transactions.
545 */ 543 */
546 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); 544 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
547 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES, 545 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
548 NULL);
549 xfs_iunlock(dp, XFS_ILOCK_EXCL); 546 xfs_iunlock(dp, XFS_ILOCK_EXCL);
550 547
551 /* 548 /*
@@ -859,8 +856,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
859 * Commit the last in the sequence of transactions. 856 * Commit the last in the sequence of transactions.
860 */ 857 */
861 xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); 858 xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
862 error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES, 859 error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
863 NULL);
864 xfs_iunlock(dp, XFS_ILOCK_EXCL); 860 xfs_iunlock(dp, XFS_ILOCK_EXCL);
865 861
866 return(error); 862 return(error);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 8eab73e8340a..81f45dae1c57 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -3053,7 +3053,7 @@ xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
3053 * is in progress. The caller takes the responsibility to cancel 3053 * is in progress. The caller takes the responsibility to cancel
3054 * the duplicate transaction that gets returned. 3054 * the duplicate transaction that gets returned.
3055 */ 3055 */
3056 if ((error = xfs_trans_commit(trans, 0, NULL))) 3056 if ((error = xfs_trans_commit(trans, 0)))
3057 return (error); 3057 return (error);
3058 3058
3059 trans = *transp; 3059 trans = *transp;
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 87795188cedf..b1ea26e40aaf 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -130,7 +130,6 @@ STATIC int /* error */
130xfs_bmap_add_extent_hole_delay( 130xfs_bmap_add_extent_hole_delay(
131 xfs_inode_t *ip, /* incore inode pointer */ 131 xfs_inode_t *ip, /* incore inode pointer */
132 xfs_extnum_t idx, /* extent number to update/insert */ 132 xfs_extnum_t idx, /* extent number to update/insert */
133 xfs_btree_cur_t *cur, /* if null, not a btree */
134 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 133 xfs_bmbt_irec_t *new, /* new data to add to file extents */
135 int *logflagsp,/* inode logging flags */ 134 int *logflagsp,/* inode logging flags */
136 xfs_extdelta_t *delta, /* Change made to incore extents */ 135 xfs_extdelta_t *delta, /* Change made to incore extents */
@@ -399,7 +398,6 @@ xfs_bmap_count_leaves(
399 398
400STATIC int 399STATIC int
401xfs_bmap_disk_count_leaves( 400xfs_bmap_disk_count_leaves(
402 xfs_ifork_t *ifp,
403 xfs_extnum_t idx, 401 xfs_extnum_t idx,
404 xfs_bmbt_block_t *block, 402 xfs_bmbt_block_t *block,
405 int numrecs, 403 int numrecs,
@@ -580,7 +578,7 @@ xfs_bmap_add_extent(
580 if (cur) 578 if (cur)
581 ASSERT((cur->bc_private.b.flags & 579 ASSERT((cur->bc_private.b.flags &
582 XFS_BTCUR_BPRV_WASDEL) == 0); 580 XFS_BTCUR_BPRV_WASDEL) == 0);
583 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 581 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
584 &logflags, delta, rsvd))) 582 &logflags, delta, rsvd)))
585 goto done; 583 goto done;
586 } 584 }
@@ -1841,7 +1839,6 @@ STATIC int /* error */
1841xfs_bmap_add_extent_hole_delay( 1839xfs_bmap_add_extent_hole_delay(
1842 xfs_inode_t *ip, /* incore inode pointer */ 1840 xfs_inode_t *ip, /* incore inode pointer */
1843 xfs_extnum_t idx, /* extent number to update/insert */ 1841 xfs_extnum_t idx, /* extent number to update/insert */
1844 xfs_btree_cur_t *cur, /* if null, not a btree */
1845 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1842 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1846 int *logflagsp, /* inode logging flags */ 1843 int *logflagsp, /* inode logging flags */
1847 xfs_extdelta_t *delta, /* Change made to incore extents */ 1844 xfs_extdelta_t *delta, /* Change made to incore extents */
@@ -4071,7 +4068,7 @@ xfs_bmap_add_attrfork(
4071 } 4068 }
4072 if ((error = xfs_bmap_finish(&tp, &flist, &committed))) 4069 if ((error = xfs_bmap_finish(&tp, &flist, &committed)))
4073 goto error2; 4070 goto error2;
4074 error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL); 4071 error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES);
4075 ASSERT(ip->i_df.if_ext_max == 4072 ASSERT(ip->i_df.if_ext_max ==
4076 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 4073 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
4077 return error; 4074 return error;
@@ -4227,7 +4224,7 @@ xfs_bmap_finish(
4227 logres = ntp->t_log_res; 4224 logres = ntp->t_log_res;
4228 logcount = ntp->t_log_count; 4225 logcount = ntp->t_log_count;
4229 ntp = xfs_trans_dup(*tp); 4226 ntp = xfs_trans_dup(*tp);
4230 error = xfs_trans_commit(*tp, 0, NULL); 4227 error = xfs_trans_commit(*tp, 0);
4231 *tp = ntp; 4228 *tp = ntp;
4232 *committed = 1; 4229 *committed = 1;
4233 /* 4230 /*
@@ -4447,8 +4444,11 @@ xfs_bmap_one_block(
4447 xfs_bmbt_irec_t s; /* internal version of extent */ 4444 xfs_bmbt_irec_t s; /* internal version of extent */
4448 4445
4449#ifndef DEBUG 4446#ifndef DEBUG
4450 if (whichfork == XFS_DATA_FORK) 4447 if (whichfork == XFS_DATA_FORK) {
4451 return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize; 4448 return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ?
4449 (ip->i_size == ip->i_mount->m_sb.sb_blocksize) :
4450 (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
4451 }
4452#endif /* !DEBUG */ 4452#endif /* !DEBUG */
4453 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) 4453 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
4454 return 0; 4454 return 0;
@@ -4460,7 +4460,7 @@ xfs_bmap_one_block(
4460 xfs_bmbt_get_all(ep, &s); 4460 xfs_bmbt_get_all(ep, &s);
4461 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4461 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4462 if (rval && whichfork == XFS_DATA_FORK) 4462 if (rval && whichfork == XFS_DATA_FORK)
4463 ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); 4463 ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize);
4464 return rval; 4464 return rval;
4465} 4465}
4466 4466
@@ -5820,7 +5820,7 @@ xfs_getbmap(
5820 fixlen = XFS_MAXIOFFSET(mp); 5820 fixlen = XFS_MAXIOFFSET(mp);
5821 } else { 5821 } else {
5822 prealloced = 0; 5822 prealloced = 0;
5823 fixlen = ip->i_d.di_size; 5823 fixlen = ip->i_size;
5824 } 5824 }
5825 } else { 5825 } else {
5826 prealloced = 0; 5826 prealloced = 0;
@@ -5844,7 +5844,8 @@ xfs_getbmap(
5844 5844
5845 xfs_ilock(ip, XFS_IOLOCK_SHARED); 5845 xfs_ilock(ip, XFS_IOLOCK_SHARED);
5846 5846
5847 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5847 if (whichfork == XFS_DATA_FORK &&
5848 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
5848 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5849 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5849 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); 5850 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5850 } 5851 }
@@ -6425,8 +6426,8 @@ xfs_bmap_count_tree(
6425 for (;;) { 6426 for (;;) {
6426 nextbno = be64_to_cpu(block->bb_rightsib); 6427 nextbno = be64_to_cpu(block->bb_rightsib);
6427 numrecs = be16_to_cpu(block->bb_numrecs); 6428 numrecs = be16_to_cpu(block->bb_numrecs);
6428 if (unlikely(xfs_bmap_disk_count_leaves(ifp, 6429 if (unlikely(xfs_bmap_disk_count_leaves(0,
6429 0, block, numrecs, count) < 0)) { 6430 block, numrecs, count) < 0)) {
6430 xfs_trans_brelse(tp, bp); 6431 xfs_trans_brelse(tp, bp);
6431 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6432 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
6432 XFS_ERRLEVEL_LOW, mp); 6433 XFS_ERRLEVEL_LOW, mp);
@@ -6472,7 +6473,6 @@ xfs_bmap_count_leaves(
6472 */ 6473 */
6473int 6474int
6474xfs_bmap_disk_count_leaves( 6475xfs_bmap_disk_count_leaves(
6475 xfs_ifork_t *ifp,
6476 xfs_extnum_t idx, 6476 xfs_extnum_t idx,
6477 xfs_bmbt_block_t *block, 6477 xfs_bmbt_block_t *block,
6478 int numrecs, 6478 int numrecs,
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index b847e6a7a3f0..de35d18cc002 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -199,7 +199,9 @@ xfs_swap_extents(
199 199
200 if (VN_CACHED(tvp) != 0) { 200 if (VN_CACHED(tvp) != 0) {
201 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); 201 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
202 bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED); 202 error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
203 if (error)
204 goto error0;
203 } 205 }
204 206
205 /* Verify O_DIRECT for ftmp */ 207 /* Verify O_DIRECT for ftmp */
@@ -382,7 +384,7 @@ xfs_swap_extents(
382 xfs_trans_set_sync(tp); 384 xfs_trans_set_sync(tp);
383 } 385 }
384 386
385 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL); 387 error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
386 locked = 0; 388 locked = 0;
387 389
388 error0: 390 error0:
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 9d7438bba30d..3accc1dcd6c9 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -282,8 +282,7 @@ xfs_dir2_block_addname(
282 * This needs to happen before the next call to use_free. 282 * This needs to happen before the next call to use_free.
283 */ 283 */
284 if (needscan) { 284 if (needscan) {
285 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 285 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
286 &needlog, NULL);
287 needscan = 0; 286 needscan = 0;
288 } 287 }
289 } 288 }
@@ -333,7 +332,7 @@ xfs_dir2_block_addname(
333 */ 332 */
334 if (needscan) { 333 if (needscan) {
335 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 334 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
336 &needlog, NULL); 335 &needlog);
337 needscan = 0; 336 needscan = 0;
338 } 337 }
339 /* 338 /*
@@ -418,8 +417,7 @@ xfs_dir2_block_addname(
418 * Clean up the bestfree array and log the header, tail, and entry. 417 * Clean up the bestfree array and log the header, tail, and entry.
419 */ 418 */
420 if (needscan) 419 if (needscan)
421 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 420 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
422 NULL);
423 if (needlog) 421 if (needlog)
424 xfs_dir2_data_log_header(tp, bp); 422 xfs_dir2_data_log_header(tp, bp);
425 xfs_dir2_block_log_tail(tp, bp); 423 xfs_dir2_block_log_tail(tp, bp);
@@ -798,8 +796,7 @@ xfs_dir2_block_removename(
798 * Fix up bestfree, log the header if necessary. 796 * Fix up bestfree, log the header if necessary.
799 */ 797 */
800 if (needscan) 798 if (needscan)
801 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 799 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
802 NULL);
803 if (needlog) 800 if (needlog)
804 xfs_dir2_data_log_header(tp, bp); 801 xfs_dir2_data_log_header(tp, bp);
805 xfs_dir2_data_check(dp, bp); 802 xfs_dir2_data_check(dp, bp);
@@ -996,8 +993,7 @@ xfs_dir2_leaf_to_block(
996 * Scan the bestfree if we need it and log the data block header. 993 * Scan the bestfree if we need it and log the data block header.
997 */ 994 */
998 if (needscan) 995 if (needscan)
999 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 996 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
1000 NULL);
1001 if (needlog) 997 if (needlog)
1002 xfs_dir2_data_log_header(tp, dbp); 998 xfs_dir2_data_log_header(tp, dbp);
1003 /* 999 /*
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index f7c799217072..c211c37ef67c 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -324,8 +324,7 @@ void
324xfs_dir2_data_freescan( 324xfs_dir2_data_freescan(
325 xfs_mount_t *mp, /* filesystem mount point */ 325 xfs_mount_t *mp, /* filesystem mount point */
326 xfs_dir2_data_t *d, /* data block pointer */ 326 xfs_dir2_data_t *d, /* data block pointer */
327 int *loghead, /* out: log data header */ 327 int *loghead) /* out: log data header */
328 char *aendp) /* in: caller's endp */
329{ 328{
330 xfs_dir2_block_tail_t *btp; /* block tail */ 329 xfs_dir2_block_tail_t *btp; /* block tail */
331 xfs_dir2_data_entry_t *dep; /* active data entry */ 330 xfs_dir2_data_entry_t *dep; /* active data entry */
@@ -346,9 +345,7 @@ xfs_dir2_data_freescan(
346 * Set up pointers. 345 * Set up pointers.
347 */ 346 */
348 p = (char *)d->u; 347 p = (char *)d->u;
349 if (aendp) 348 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
350 endp = aendp;
351 else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
352 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); 349 btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
353 endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); 350 endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
354 } else 351 } else
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index a6ae2d21c40a..c94c9099cfb1 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -166,7 +166,7 @@ extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
166extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, 166extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
167 xfs_dir2_data_unused_t *dup, int *loghead); 167 xfs_dir2_data_unused_t *dup, int *loghead);
168extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, 168extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
169 int *loghead, char *aendp); 169 int *loghead);
170extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, 170extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
171 struct xfs_dabuf **bpp); 171 struct xfs_dabuf **bpp);
172extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, 172extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index b1cf1fbf423d..db14ea71459f 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -133,8 +133,7 @@ xfs_dir2_block_to_leaf(
133 */ 133 */
134 block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 134 block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
135 if (needscan) 135 if (needscan)
136 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog, 136 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
137 NULL);
138 /* 137 /*
139 * Set up leaf tail and bests table. 138 * Set up leaf tail and bests table.
140 */ 139 */
@@ -414,7 +413,7 @@ xfs_dir2_leaf_addname(
414 * Need to scan fix up the bestfree table. 413 * Need to scan fix up the bestfree table.
415 */ 414 */
416 if (needscan) 415 if (needscan)
417 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 416 xfs_dir2_data_freescan(mp, data, &needlog);
418 /* 417 /*
419 * Need to log the data block's header. 418 * Need to log the data block's header.
420 */ 419 */
@@ -1496,7 +1495,7 @@ xfs_dir2_leaf_removename(
1496 * log the data block header if necessary. 1495 * log the data block header if necessary.
1497 */ 1496 */
1498 if (needscan) 1497 if (needscan)
1499 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 1498 xfs_dir2_data_freescan(mp, data, &needlog);
1500 if (needlog) 1499 if (needlog)
1501 xfs_dir2_data_log_header(tp, dbp); 1500 xfs_dir2_data_log_header(tp, dbp);
1502 /* 1501 /*
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 9ca71719b683..d083c3819934 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -904,7 +904,7 @@ xfs_dir2_leafn_remove(
904 * Log the data block header if needed. 904 * Log the data block header if needed.
905 */ 905 */
906 if (needscan) 906 if (needscan)
907 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 907 xfs_dir2_data_freescan(mp, data, &needlog);
908 if (needlog) 908 if (needlog)
909 xfs_dir2_data_log_header(tp, dbp); 909 xfs_dir2_data_log_header(tp, dbp);
910 xfs_dir2_data_check(dp, dbp); 910 xfs_dir2_data_check(dp, dbp);
@@ -1705,7 +1705,7 @@ xfs_dir2_node_addname_int(
1705 * Rescan the block for bestfree if needed. 1705 * Rescan the block for bestfree if needed.
1706 */ 1706 */
1707 if (needscan) 1707 if (needscan)
1708 xfs_dir2_data_freescan(mp, data, &needlog, NULL); 1708 xfs_dir2_data_freescan(mp, data, &needlog);
1709 /* 1709 /*
1710 * Log the data block header if needed. 1710 * Log the data block header if needed.
1711 */ 1711 */
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index b1af54464f00..8c4331631337 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -80,7 +80,7 @@ xfs_error_test(int error_tag, int *fsidp, char *expression,
80 int i; 80 int i;
81 int64_t fsid; 81 int64_t fsid;
82 82
83 if (random() % randfactor) 83 if (random32() % randfactor)
84 return 0; 84 return 0;
85 85
86 memcpy(&fsid, fsidp, sizeof(xfs_fsid_t)); 86 memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 32c37c1c47ab..b599e6be9ec1 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -346,7 +346,7 @@ xfs_growfs_data_private(
346 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree); 346 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
347 if (dpct) 347 if (dpct)
348 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct); 348 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
349 error = xfs_trans_commit(tp, 0, NULL); 349 error = xfs_trans_commit(tp, 0);
350 if (error) { 350 if (error) {
351 return error; 351 return error;
352 } 352 }
@@ -605,7 +605,7 @@ xfs_fs_log_dummy(
605 xfs_trans_ihold(tp, ip); 605 xfs_trans_ihold(tp, ip);
606 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 606 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
607 xfs_trans_set_sync(tp); 607 xfs_trans_set_sync(tp);
608 xfs_trans_commit(tp, 0, NULL); 608 xfs_trans_commit(tp, 0);
609 609
610 xfs_iunlock(ip, XFS_ILOCK_EXCL); 610 xfs_iunlock(ip, XFS_ILOCK_EXCL);
611} 611}
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index c1c89dac19cc..114433a22baa 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -879,17 +879,17 @@ xfs_ilock(xfs_inode_t *ip,
879 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 879 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
880 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 880 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
881 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 881 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
882 ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0); 882 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
883 883
884 if (lock_flags & XFS_IOLOCK_EXCL) { 884 if (lock_flags & XFS_IOLOCK_EXCL) {
885 mrupdate(&ip->i_iolock); 885 mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
886 } else if (lock_flags & XFS_IOLOCK_SHARED) { 886 } else if (lock_flags & XFS_IOLOCK_SHARED) {
887 mraccess(&ip->i_iolock); 887 mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
888 } 888 }
889 if (lock_flags & XFS_ILOCK_EXCL) { 889 if (lock_flags & XFS_ILOCK_EXCL) {
890 mrupdate(&ip->i_lock); 890 mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
891 } else if (lock_flags & XFS_ILOCK_SHARED) { 891 } else if (lock_flags & XFS_ILOCK_SHARED) {
892 mraccess(&ip->i_lock); 892 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
893 } 893 }
894 xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); 894 xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
895} 895}
@@ -923,7 +923,7 @@ xfs_ilock_nowait(xfs_inode_t *ip,
923 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 923 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
924 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 924 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
925 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 925 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
926 ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0); 926 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
927 927
928 iolocked = 0; 928 iolocked = 0;
929 if (lock_flags & XFS_IOLOCK_EXCL) { 929 if (lock_flags & XFS_IOLOCK_EXCL) {
@@ -983,7 +983,8 @@ xfs_iunlock(xfs_inode_t *ip,
983 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 983 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
984 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 984 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
985 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 985 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
986 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0); 986 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
987 XFS_LOCK_DEP_MASK)) == 0);
987 ASSERT(lock_flags != 0); 988 ASSERT(lock_flags != 0);
988 989
989 if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) { 990 if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 3da9829c19d5..3ca5d43b8345 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -442,6 +442,7 @@ xfs_iformat(
442 return XFS_ERROR(EFSCORRUPTED); 442 return XFS_ERROR(EFSCORRUPTED);
443 } 443 }
444 ip->i_d.di_size = 0; 444 ip->i_d.di_size = 0;
445 ip->i_size = 0;
445 ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); 446 ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
446 break; 447 break;
447 448
@@ -980,6 +981,7 @@ xfs_iread(
980 } 981 }
981 982
982 ip->i_delayed_blks = 0; 983 ip->i_delayed_blks = 0;
984 ip->i_size = ip->i_d.di_size;
983 985
984 /* 986 /*
985 * Mark the buffer containing the inode as something to keep 987 * Mark the buffer containing the inode as something to keep
@@ -1170,6 +1172,7 @@ xfs_ialloc(
1170 } 1172 }
1171 1173
1172 ip->i_d.di_size = 0; 1174 ip->i_d.di_size = 0;
1175 ip->i_size = 0;
1173 ip->i_d.di_nextents = 0; 1176 ip->i_d.di_nextents = 0;
1174 ASSERT(ip->i_d.di_nblocks == 0); 1177 ASSERT(ip->i_d.di_nblocks == 0);
1175 xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); 1178 xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD);
@@ -1340,7 +1343,7 @@ xfs_file_last_byte(
1340 } else { 1343 } else {
1341 last_block = 0; 1344 last_block = 0;
1342 } 1345 }
1343 size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size); 1346 size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size);
1344 last_block = XFS_FILEOFF_MAX(last_block, size_last_block); 1347 last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
1345 1348
1346 last_byte = XFS_FSB_TO_B(mp, last_block); 1349 last_byte = XFS_FSB_TO_B(mp, last_block);
@@ -1421,7 +1424,7 @@ xfs_itrunc_trace(
1421 * must be called again with all the same restrictions as the initial 1424 * must be called again with all the same restrictions as the initial
1422 * call. 1425 * call.
1423 */ 1426 */
1424void 1427int
1425xfs_itruncate_start( 1428xfs_itruncate_start(
1426 xfs_inode_t *ip, 1429 xfs_inode_t *ip,
1427 uint flags, 1430 uint flags,
@@ -1431,9 +1434,10 @@ xfs_itruncate_start(
1431 xfs_off_t toss_start; 1434 xfs_off_t toss_start;
1432 xfs_mount_t *mp; 1435 xfs_mount_t *mp;
1433 bhv_vnode_t *vp; 1436 bhv_vnode_t *vp;
1437 int error = 0;
1434 1438
1435 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1439 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1436 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1440 ASSERT((new_size == 0) || (new_size <= ip->i_size));
1437 ASSERT((flags == XFS_ITRUNC_DEFINITE) || 1441 ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
1438 (flags == XFS_ITRUNC_MAYBE)); 1442 (flags == XFS_ITRUNC_MAYBE));
1439 1443
@@ -1468,7 +1472,7 @@ xfs_itruncate_start(
1468 * file size, so there is no way that the data extended 1472 * file size, so there is no way that the data extended
1469 * out there. 1473 * out there.
1470 */ 1474 */
1471 return; 1475 return 0;
1472 } 1476 }
1473 last_byte = xfs_file_last_byte(ip); 1477 last_byte = xfs_file_last_byte(ip);
1474 xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start, 1478 xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start,
@@ -1477,7 +1481,7 @@ xfs_itruncate_start(
1477 if (flags & XFS_ITRUNC_DEFINITE) { 1481 if (flags & XFS_ITRUNC_DEFINITE) {
1478 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); 1482 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1479 } else { 1483 } else {
1480 bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); 1484 error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1481 } 1485 }
1482 } 1486 }
1483 1487
@@ -1486,6 +1490,7 @@ xfs_itruncate_start(
1486 ASSERT(VN_CACHED(vp) == 0); 1490 ASSERT(VN_CACHED(vp) == 0);
1487 } 1491 }
1488#endif 1492#endif
1493 return error;
1489} 1494}
1490 1495
1491/* 1496/*
@@ -1556,7 +1561,7 @@ xfs_itruncate_finish(
1556 1561
1557 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1562 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1558 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); 1563 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
1559 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1564 ASSERT((new_size == 0) || (new_size <= ip->i_size));
1560 ASSERT(*tp != NULL); 1565 ASSERT(*tp != NULL);
1561 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); 1566 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
1562 ASSERT(ip->i_transp == *tp); 1567 ASSERT(ip->i_transp == *tp);
@@ -1630,8 +1635,20 @@ xfs_itruncate_finish(
1630 */ 1635 */
1631 if (fork == XFS_DATA_FORK) { 1636 if (fork == XFS_DATA_FORK) {
1632 if (ip->i_d.di_nextents > 0) { 1637 if (ip->i_d.di_nextents > 0) {
1633 ip->i_d.di_size = new_size; 1638 /*
1634 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1639 * If we are not changing the file size then do
1640 * not update the on-disk file size - we may be
1641 * called from xfs_inactive_free_eofblocks(). If we
1642 * update the on-disk file size and then the system
1643 * crashes before the contents of the file are
1644 * flushed to disk then the files may be full of
1645 * holes (ie NULL files bug).
1646 */
1647 if (ip->i_size != new_size) {
1648 ip->i_d.di_size = new_size;
1649 ip->i_size = new_size;
1650 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1651 }
1635 } 1652 }
1636 } else if (sync) { 1653 } else if (sync) {
1637 ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC)); 1654 ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
@@ -1746,7 +1763,7 @@ xfs_itruncate_finish(
1746 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1763 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1747 } 1764 }
1748 ntp = xfs_trans_dup(ntp); 1765 ntp = xfs_trans_dup(ntp);
1749 (void) xfs_trans_commit(*tp, 0, NULL); 1766 (void) xfs_trans_commit(*tp, 0);
1750 *tp = ntp; 1767 *tp = ntp;
1751 error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 1768 error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
1752 XFS_TRANS_PERM_LOG_RES, 1769 XFS_TRANS_PERM_LOG_RES,
@@ -1767,7 +1784,19 @@ xfs_itruncate_finish(
1767 */ 1784 */
1768 if (fork == XFS_DATA_FORK) { 1785 if (fork == XFS_DATA_FORK) {
1769 xfs_isize_check(mp, ip, new_size); 1786 xfs_isize_check(mp, ip, new_size);
1770 ip->i_d.di_size = new_size; 1787 /*
1788 * If we are not changing the file size then do
1789 * not update the on-disk file size - we may be
1790 * called from xfs_inactive_free_eofblocks(). If we
1791 * update the on-disk file size and then the system
1792 * crashes before the contents of the file are
1793 * flushed to disk then the files may be full of
1794 * holes (ie NULL files bug).
1795 */
1796 if (ip->i_size != new_size) {
1797 ip->i_d.di_size = new_size;
1798 ip->i_size = new_size;
1799 }
1771 } 1800 }
1772 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1801 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1773 ASSERT((new_size != 0) || 1802 ASSERT((new_size != 0) ||
@@ -1800,7 +1829,7 @@ xfs_igrow_start(
1800 1829
1801 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); 1830 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
1802 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); 1831 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
1803 ASSERT(new_size > ip->i_d.di_size); 1832 ASSERT(new_size > ip->i_size);
1804 1833
1805 /* 1834 /*
1806 * Zero any pages that may have been created by 1835 * Zero any pages that may have been created by
@@ -1808,7 +1837,7 @@ xfs_igrow_start(
1808 * and any blocks between the old and new file sizes. 1837 * and any blocks between the old and new file sizes.
1809 */ 1838 */
1810 error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, 1839 error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
1811 ip->i_d.di_size); 1840 ip->i_size);
1812 return error; 1841 return error;
1813} 1842}
1814 1843
@@ -1832,13 +1861,14 @@ xfs_igrow_finish(
1832 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); 1861 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
1833 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); 1862 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
1834 ASSERT(ip->i_transp == tp); 1863 ASSERT(ip->i_transp == tp);
1835 ASSERT(new_size > ip->i_d.di_size); 1864 ASSERT(new_size > ip->i_size);
1836 1865
1837 /* 1866 /*
1838 * Update the file size. Update the inode change timestamp 1867 * Update the file size. Update the inode change timestamp
1839 * if change_flag set. 1868 * if change_flag set.
1840 */ 1869 */
1841 ip->i_d.di_size = new_size; 1870 ip->i_d.di_size = new_size;
1871 ip->i_size = new_size;
1842 if (change_flag) 1872 if (change_flag)
1843 xfs_ichgtime(ip, XFS_ICHGTIME_CHG); 1873 xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
1844 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1874 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
@@ -2321,7 +2351,7 @@ xfs_ifree(
2321 ASSERT(ip->i_d.di_nlink == 0); 2351 ASSERT(ip->i_d.di_nlink == 0);
2322 ASSERT(ip->i_d.di_nextents == 0); 2352 ASSERT(ip->i_d.di_nextents == 0);
2323 ASSERT(ip->i_d.di_anextents == 0); 2353 ASSERT(ip->i_d.di_anextents == 0);
2324 ASSERT((ip->i_d.di_size == 0) || 2354 ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) ||
2325 ((ip->i_d.di_mode & S_IFMT) != S_IFREG)); 2355 ((ip->i_d.di_mode & S_IFMT) != S_IFREG));
2326 ASSERT(ip->i_d.di_nblocks == 0); 2356 ASSERT(ip->i_d.di_nblocks == 0);
2327 2357
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index bc823720d88f..f75afecef8e7 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -287,6 +287,7 @@ typedef struct xfs_inode {
287 struct xfs_inode *i_cnext; /* cluster hash link forward */ 287 struct xfs_inode *i_cnext; /* cluster hash link forward */
288 struct xfs_inode *i_cprev; /* cluster hash link backward */ 288 struct xfs_inode *i_cprev; /* cluster hash link backward */
289 289
290 xfs_fsize_t i_size; /* in-memory size */
290 /* Trace buffers per inode. */ 291 /* Trace buffers per inode. */
291#ifdef XFS_BMAP_TRACE 292#ifdef XFS_BMAP_TRACE
292 struct ktrace *i_xtrace; /* inode extent list trace */ 293 struct ktrace *i_xtrace; /* inode extent list trace */
@@ -305,6 +306,8 @@ typedef struct xfs_inode {
305#endif 306#endif
306} xfs_inode_t; 307} xfs_inode_t;
307 308
309#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \
310 (ip)->i_size : (ip)->i_d.di_size;
308 311
309/* 312/*
310 * i_flags helper functions 313 * i_flags helper functions
@@ -379,26 +382,58 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
379 382
380/* 383/*
381 * Flags for inode locking. 384 * Flags for inode locking.
385 * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
386 * 1<<16 - 1<<32-1 -- lockdep annotation (integers)
382 */ 387 */
383#define XFS_IOLOCK_EXCL 0x001 388#define XFS_IOLOCK_EXCL (1<<0)
384#define XFS_IOLOCK_SHARED 0x002 389#define XFS_IOLOCK_SHARED (1<<1)
385#define XFS_ILOCK_EXCL 0x004 390#define XFS_ILOCK_EXCL (1<<2)
386#define XFS_ILOCK_SHARED 0x008 391#define XFS_ILOCK_SHARED (1<<3)
387#define XFS_IUNLOCK_NONOTIFY 0x010 392#define XFS_IUNLOCK_NONOTIFY (1<<4)
388/* XFS_IOLOCK_NESTED 0x020 */ 393/* #define XFS_IOLOCK_NESTED (1<<5) */
389#define XFS_EXTENT_TOKEN_RD 0x040 394#define XFS_EXTENT_TOKEN_RD (1<<6)
390#define XFS_SIZE_TOKEN_RD 0x080 395#define XFS_SIZE_TOKEN_RD (1<<7)
391#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD) 396#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
392#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */ 397#define XFS_WILLLEND (1<<8) /* Always acquire tokens for lending */
393#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND) 398#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
394#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND) 399#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
395#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND) 400#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
396/* XFS_SIZE_TOKEN_WANT 0x200 */ 401/* TODO:XFS_SIZE_TOKEN_WANT (1<<9) */
397 402
398#define XFS_LOCK_MASK \ 403#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
399 (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \ 404 | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
400 XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \ 405 | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \
401 XFS_WILLLEND) 406 | XFS_WILLLEND)
407
408/*
409 * Flags for lockdep annotations.
410 *
411 * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes
412 * (ie directory operations that require locking a directory inode and
413 * an entry inode). The first inode gets locked with this flag so it
414 * gets a lockdep subclass of 1 and the second lock will have a lockdep
415 * subclass of 0.
416 *
417 * XFS_I[O]LOCK_INUMORDER - for locking several inodes at the some time
418 * with xfs_lock_inodes(). This flag is used as the starting subclass
419 * and each subsequent lock acquired will increment the subclass by one.
420 * So the first lock acquired will have a lockdep subclass of 2, the
421 * second lock will have a lockdep subclass of 3, and so on.
422 */
423#define XFS_IOLOCK_SHIFT 16
424#define XFS_IOLOCK_PARENT (1 << XFS_IOLOCK_SHIFT)
425#define XFS_IOLOCK_INUMORDER (2 << XFS_IOLOCK_SHIFT)
426
427#define XFS_ILOCK_SHIFT 24
428#define XFS_ILOCK_PARENT (1 << XFS_ILOCK_SHIFT)
429#define XFS_ILOCK_INUMORDER (2 << XFS_ILOCK_SHIFT)
430
431#define XFS_IOLOCK_DEP_MASK 0x00ff0000
432#define XFS_ILOCK_DEP_MASK 0xff000000
433#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
434
435#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
436#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
402 437
403/* 438/*
404 * Flags for xfs_iflush() 439 * Flags for xfs_iflush()
@@ -481,7 +516,7 @@ uint xfs_ip2xflags(struct xfs_inode *);
481uint xfs_dic2xflags(struct xfs_dinode_core *); 516uint xfs_dic2xflags(struct xfs_dinode_core *);
482int xfs_ifree(struct xfs_trans *, xfs_inode_t *, 517int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
483 struct xfs_bmap_free *); 518 struct xfs_bmap_free *);
484void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); 519int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
485int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, 520int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
486 xfs_fsize_t, int, int); 521 xfs_fsize_t, int, int);
487int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); 522int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 06d710c9ce4b..81548ec72ba6 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -52,7 +52,7 @@ STATIC xfs_fsize_t
52xfs_size_fn( 52xfs_size_fn(
53 xfs_inode_t *ip) 53 xfs_inode_t *ip)
54{ 54{
55 return (ip->i_d.di_size); 55 return XFS_ISIZE(ip);
56} 56}
57 57
58STATIC int 58STATIC int
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index cc6a7b5a9912..3f2b9f2a7b94 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -458,7 +458,7 @@ xfs_iomap_write_direct(
458 extsz = ip->i_d.di_extsize; 458 extsz = ip->i_d.di_extsize;
459 } 459 }
460 460
461 isize = ip->i_d.di_size; 461 isize = ip->i_size;
462 if (io->io_new_size > isize) 462 if (io->io_new_size > isize)
463 isize = io->io_new_size; 463 isize = io->io_new_size;
464 464
@@ -524,7 +524,7 @@ xfs_iomap_write_direct(
524 xfs_trans_ihold(tp, ip); 524 xfs_trans_ihold(tp, ip);
525 525
526 bmapi_flag = XFS_BMAPI_WRITE; 526 bmapi_flag = XFS_BMAPI_WRITE;
527 if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz)) 527 if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
528 bmapi_flag |= XFS_BMAPI_PREALLOC; 528 bmapi_flag |= XFS_BMAPI_PREALLOC;
529 529
530 /* 530 /*
@@ -543,7 +543,7 @@ xfs_iomap_write_direct(
543 error = xfs_bmap_finish(&tp, &free_list, &committed); 543 error = xfs_bmap_finish(&tp, &free_list, &committed);
544 if (error) 544 if (error)
545 goto error0; 545 goto error0;
546 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 546 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
547 if (error) 547 if (error)
548 goto error_out; 548 goto error_out;
549 549
@@ -676,7 +676,7 @@ xfs_iomap_write_delay(
676 offset_fsb = XFS_B_TO_FSBT(mp, offset); 676 offset_fsb = XFS_B_TO_FSBT(mp, offset);
677 677
678retry: 678retry:
679 isize = ip->i_d.di_size; 679 isize = ip->i_size;
680 if (io->io_new_size > isize) 680 if (io->io_new_size > isize)
681 isize = io->io_new_size; 681 isize = io->io_new_size;
682 682
@@ -817,7 +817,7 @@ xfs_iomap_write_allocate(
817 * we dropped the ilock in the interim. 817 * we dropped the ilock in the interim.
818 */ 818 */
819 819
820 end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size); 820 end_fsb = XFS_B_TO_FSB(mp, ip->i_size);
821 xfs_bmap_last_offset(NULL, ip, &last_block, 821 xfs_bmap_last_offset(NULL, ip, &last_block,
822 XFS_DATA_FORK); 822 XFS_DATA_FORK);
823 last_block = XFS_FILEOFF_MAX(last_block, end_fsb); 823 last_block = XFS_FILEOFF_MAX(last_block, end_fsb);
@@ -840,8 +840,7 @@ xfs_iomap_write_allocate(
840 if (error) 840 if (error)
841 goto trans_cancel; 841 goto trans_cancel;
842 842
843 error = xfs_trans_commit(tp, 843 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
844 XFS_TRANS_RELEASE_LOG_RES, NULL);
845 if (error) 844 if (error)
846 goto error0; 845 goto error0;
847 846
@@ -948,7 +947,7 @@ xfs_iomap_write_unwritten(
948 if (error) 947 if (error)
949 goto error_on_bmapi_transaction; 948 goto error_on_bmapi_transaction;
950 949
951 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 950 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
952 xfs_iunlock(ip, XFS_ILOCK_EXCL); 951 xfs_iunlock(ip, XFS_ILOCK_EXCL);
953 if (error) 952 if (error)
954 return XFS_ERROR(error); 953 return XFS_ERROR(error);
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 3ce204a524b0..df441ee936b2 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -22,6 +22,7 @@
22 22
23 23
24typedef enum { /* iomap_flags values */ 24typedef enum { /* iomap_flags values */
25 IOMAP_READ = 0, /* mapping for a read */
25 IOMAP_EOF = 0x01, /* mapping contains EOF */ 26 IOMAP_EOF = 0x01, /* mapping contains EOF */
26 IOMAP_HOLE = 0x02, /* mapping covers a hole */ 27 IOMAP_HOLE = 0x02, /* mapping covers a hole */
27 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ 28 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index ca74d3f5910e..080fabf61c92 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1509,7 +1509,6 @@ xlog_recover_insert_item_frontq(
1509 1509
1510STATIC int 1510STATIC int
1511xlog_recover_reorder_trans( 1511xlog_recover_reorder_trans(
1512 xlog_t *log,
1513 xlog_recover_t *trans) 1512 xlog_recover_t *trans)
1514{ 1513{
1515 xlog_recover_item_t *first_item, *itemq, *itemq_next; 1514 xlog_recover_item_t *first_item, *itemq, *itemq_next;
@@ -1867,7 +1866,6 @@ xlog_recover_do_inode_buffer(
1867/*ARGSUSED*/ 1866/*ARGSUSED*/
1868STATIC void 1867STATIC void
1869xlog_recover_do_reg_buffer( 1868xlog_recover_do_reg_buffer(
1870 xfs_mount_t *mp,
1871 xlog_recover_item_t *item, 1869 xlog_recover_item_t *item,
1872 xfs_buf_t *bp, 1870 xfs_buf_t *bp,
1873 xfs_buf_log_format_t *buf_f) 1871 xfs_buf_log_format_t *buf_f)
@@ -2083,7 +2081,7 @@ xlog_recover_do_dquot_buffer(
2083 if (log->l_quotaoffs_flag & type) 2081 if (log->l_quotaoffs_flag & type)
2084 return; 2082 return;
2085 2083
2086 xlog_recover_do_reg_buffer(mp, item, bp, buf_f); 2084 xlog_recover_do_reg_buffer(item, bp, buf_f);
2087} 2085}
2088 2086
2089/* 2087/*
@@ -2184,7 +2182,7 @@ xlog_recover_do_buffer_trans(
2184 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { 2182 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
2185 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); 2183 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2186 } else { 2184 } else {
2187 xlog_recover_do_reg_buffer(mp, item, bp, buf_f); 2185 xlog_recover_do_reg_buffer(item, bp, buf_f);
2188 } 2186 }
2189 if (error) 2187 if (error)
2190 return XFS_ERROR(error); 2188 return XFS_ERROR(error);
@@ -2765,7 +2763,7 @@ xlog_recover_do_trans(
2765 int error = 0; 2763 int error = 0;
2766 xlog_recover_item_t *item, *first_item; 2764 xlog_recover_item_t *item, *first_item;
2767 2765
2768 if ((error = xlog_recover_reorder_trans(log, trans))) 2766 if ((error = xlog_recover_reorder_trans(trans)))
2769 return error; 2767 return error;
2770 first_item = item = trans->r_itemq; 2768 first_item = item = trans->r_itemq;
2771 do { 2769 do {
@@ -3016,7 +3014,7 @@ xlog_recover_process_efi(
3016 } 3014 }
3017 3015
3018 efip->efi_flags |= XFS_EFI_RECOVERED; 3016 efip->efi_flags |= XFS_EFI_RECOVERED;
3019 xfs_trans_commit(tp, 0, NULL); 3017 xfs_trans_commit(tp, 0);
3020} 3018}
3021 3019
3022/* 3020/*
@@ -3143,7 +3141,7 @@ xlog_recover_clear_agi_bucket(
3143 xfs_trans_log_buf(tp, agibp, offset, 3141 xfs_trans_log_buf(tp, agibp, offset,
3144 (offset + sizeof(xfs_agino_t) - 1)); 3142 (offset + sizeof(xfs_agino_t) - 1));
3145 3143
3146 (void) xfs_trans_commit(tp, 0, NULL); 3144 (void) xfs_trans_commit(tp, 0);
3147} 3145}
3148 3146
3149/* 3147/*
@@ -3886,8 +3884,7 @@ xlog_recover(
3886 * under the vfs layer, so we can get away with it unless 3884 * under the vfs layer, so we can get away with it unless
3887 * the device itself is read-only, in which case we fail. 3885 * the device itself is read-only, in which case we fail.
3888 */ 3886 */
3889 if ((error = xfs_dev_is_read_only(log->l_mp, 3887 if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
3890 "recovery required"))) {
3891 return error; 3888 return error;
3892 } 3889 }
3893 3890
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 3bed0cf0d8af..f5aa3ef855fb 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1653,7 +1653,7 @@ xfs_mount_log_sbunit(
1653 return; 1653 return;
1654 } 1654 }
1655 xfs_mod_sb(tp, fields); 1655 xfs_mod_sb(tp, fields);
1656 xfs_trans_commit(tp, 0, NULL); 1656 xfs_trans_commit(tp, 0);
1657} 1657}
1658 1658
1659 1659
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 320d63ff9ca2..0d594ed7efef 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -78,7 +78,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp)
78 return error; 78 return error;
79 } 79 }
80 xfs_mod_sb(tp, XFS_SB_QFLAGS); 80 xfs_mod_sb(tp, XFS_SB_QFLAGS);
81 error = xfs_trans_commit(tp, 0, NULL); 81 error = xfs_trans_commit(tp, 0);
82 return error; 82 return error;
83} 83}
84 84
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 9dcb32aa4e2e..6f14df976f73 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -154,10 +154,11 @@ typedef struct xfs_qoff_logformat {
154#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) 154#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
155 155
156#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) 156#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
157#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
158#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) 157#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
159#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) 158#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
160#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) 159#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
160#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
161#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD)
161 162
162/* 163/*
163 * Incore only flags for quotaoff - these bits get cleared when quota(s) 164 * Incore only flags for quotaoff - these bits get cleared when quota(s)
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 4c6573d784cd..7679d7a7022d 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -584,7 +584,7 @@ xfs_rename(
584 * trans_commit will unlock src_ip, target_ip & decrement 584 * trans_commit will unlock src_ip, target_ip & decrement
585 * the vnode references. 585 * the vnode references.
586 */ 586 */
587 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 587 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
588 if (target_ip != NULL) { 588 if (target_ip != NULL) {
589 xfs_refcache_purge_ip(target_ip); 589 xfs_refcache_purge_ip(target_ip);
590 IRELE(target_ip); 590 IRELE(target_ip);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 6fff19dc3cf9..b3a5f07bd073 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -150,7 +150,7 @@ xfs_growfs_rt_alloc(
150 error = xfs_bmap_finish(&tp, &flist, &committed); 150 error = xfs_bmap_finish(&tp, &flist, &committed);
151 if (error) 151 if (error)
152 goto error_exit; 152 goto error_exit;
153 xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 153 xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
154 /* 154 /*
155 * Now we need to clear the allocated blocks. 155 * Now we need to clear the allocated blocks.
156 * Do this one block per transaction, to keep it simple. 156 * Do this one block per transaction, to keep it simple.
@@ -187,7 +187,7 @@ xfs_growfs_rt_alloc(
187 /* 187 /*
188 * Commit the transaction. 188 * Commit the transaction.
189 */ 189 */
190 xfs_trans_commit(tp, 0, NULL); 190 xfs_trans_commit(tp, 0);
191 } 191 }
192 /* 192 /*
193 * Go on to the next extent, if any. 193 * Go on to the next extent, if any.
@@ -2042,7 +2042,7 @@ xfs_growfs_rt(
2042 /* 2042 /*
2043 * Commit the transaction. 2043 * Commit the transaction.
2044 */ 2044 */
2045 xfs_trans_commit(tp, 0, NULL); 2045 xfs_trans_commit(tp, 0);
2046 } 2046 }
2047 2047
2048 if (error) 2048 if (error)
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 1ea7c0ca6ae0..905d1c008be7 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -83,7 +83,7 @@ xfs_write_clear_setuid(
83 } 83 }
84 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 84 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
85 xfs_trans_set_sync(tp); 85 xfs_trans_set_sync(tp);
86 error = xfs_trans_commit(tp, 0, NULL); 86 error = xfs_trans_commit(tp, 0);
87 xfs_iunlock(ip, XFS_ILOCK_EXCL); 87 xfs_iunlock(ip, XFS_ILOCK_EXCL);
88 return 0; 88 return 0;
89} 89}
@@ -164,7 +164,7 @@ xfs_write_sync_logforce(
164 xfs_trans_ihold(tp, ip); 164 xfs_trans_ihold(tp, ip);
165 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 165 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
166 xfs_trans_set_sync(tp); 166 xfs_trans_set_sync(tp);
167 error = xfs_trans_commit(tp, 0, NULL); 167 error = xfs_trans_commit(tp, 0);
168 xfs_iunlock(ip, XFS_ILOCK_EXCL); 168 xfs_iunlock(ip, XFS_ILOCK_EXCL);
169 } 169 }
170 } 170 }
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 301ff9445b6f..cc2d60951e21 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -753,7 +753,6 @@ int
753_xfs_trans_commit( 753_xfs_trans_commit(
754 xfs_trans_t *tp, 754 xfs_trans_t *tp,
755 uint flags, 755 uint flags,
756 xfs_lsn_t *commit_lsn_p,
757 int *log_flushed) 756 int *log_flushed)
758{ 757{
759 xfs_log_iovec_t *log_vector; 758 xfs_log_iovec_t *log_vector;
@@ -812,8 +811,6 @@ shut_us_down:
812 xfs_trans_free_busy(tp); 811 xfs_trans_free_busy(tp);
813 xfs_trans_free(tp); 812 xfs_trans_free(tp);
814 XFS_STATS_INC(xs_trans_empty); 813 XFS_STATS_INC(xs_trans_empty);
815 if (commit_lsn_p)
816 *commit_lsn_p = commit_lsn;
817 return (shutdown); 814 return (shutdown);
818 } 815 }
819 ASSERT(tp->t_ticket != NULL); 816 ASSERT(tp->t_ticket != NULL);
@@ -864,9 +861,6 @@ shut_us_down:
864 kmem_free(log_vector, nvec * sizeof(xfs_log_iovec_t)); 861 kmem_free(log_vector, nvec * sizeof(xfs_log_iovec_t));
865 } 862 }
866 863
867 if (commit_lsn_p)
868 *commit_lsn_p = commit_lsn;
869
870 /* 864 /*
871 * If we got a log write error. Unpin the logitems that we 865 * If we got a log write error. Unpin the logitems that we
872 * had pinned, clean up, free trans structure, and return error. 866 * had pinned, clean up, free trans structure, and return error.
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index f1d7ab236726..7dfcc450366f 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -988,10 +988,8 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
988 xfs_extlen_t); 988 xfs_extlen_t);
989int _xfs_trans_commit(xfs_trans_t *, 989int _xfs_trans_commit(xfs_trans_t *,
990 uint flags, 990 uint flags,
991 xfs_lsn_t *,
992 int *); 991 int *);
993#define xfs_trans_commit(tp, flags, lsn) \ 992#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL)
994 _xfs_trans_commit(tp, flags, lsn, NULL)
995void xfs_trans_cancel(xfs_trans_t *, int); 993void xfs_trans_cancel(xfs_trans_t *, int);
996void xfs_trans_ail_init(struct xfs_mount *); 994void xfs_trans_ail_init(struct xfs_mount *);
997xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); 995xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 9014d7e44488..20ffec308e1e 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -222,7 +222,7 @@ xfs_dir_ialloc(
222 } 222 }
223 223
224 ntp = xfs_trans_dup(tp); 224 ntp = xfs_trans_dup(tp);
225 code = xfs_trans_commit(tp, 0, NULL); 225 code = xfs_trans_commit(tp, 0);
226 tp = ntp; 226 tp = ntp;
227 if (committed != NULL) { 227 if (committed != NULL) {
228 *committed = 1; 228 *committed = 1;
@@ -420,7 +420,11 @@ xfs_truncate_file(
420 * in a transaction. 420 * in a transaction.
421 */ 421 */
422 xfs_ilock(ip, XFS_IOLOCK_EXCL); 422 xfs_ilock(ip, XFS_IOLOCK_EXCL);
423 xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0); 423 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
424 if (error) {
425 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
426 return error;
427 }
424 428
425 tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE); 429 tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
426 if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 430 if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
@@ -460,8 +464,7 @@ xfs_truncate_file(
460 XFS_TRANS_ABORT); 464 XFS_TRANS_ABORT);
461 } else { 465 } else {
462 xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 466 xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
463 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, 467 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
464 NULL);
465 } 468 }
466 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 469 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
467 470
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 29f72f613782..65c561201cb8 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -696,7 +696,7 @@ xfs_unmount_flush(
696 bhv_vnode_t *rvp = XFS_ITOV(rip); 696 bhv_vnode_t *rvp = XFS_ITOV(rip);
697 int error; 697 int error;
698 698
699 xfs_ilock(rip, XFS_ILOCK_EXCL); 699 xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
700 xfs_iflock(rip); 700 xfs_iflock(rip);
701 701
702 /* 702 /*
@@ -1147,7 +1147,7 @@ xfs_sync_inodes(
1147 if (XFS_FORCED_SHUTDOWN(mp)) { 1147 if (XFS_FORCED_SHUTDOWN(mp)) {
1148 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); 1148 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
1149 } else { 1149 } else {
1150 bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF); 1150 error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
1151 } 1151 }
1152 1152
1153 xfs_ilock(ip, XFS_ILOCK_SHARED); 1153 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1539,7 +1539,7 @@ xfs_syncsub(
1539 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1539 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1540 xfs_trans_ihold(tp, ip); 1540 xfs_trans_ihold(tp, ip);
1541 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1541 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1542 error = xfs_trans_commit(tp, 0, NULL); 1542 error = xfs_trans_commit(tp, 0);
1543 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1543 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1544 xfs_log_force(mp, (xfs_lsn_t)0, log_flags); 1544 xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
1545 } 1545 }
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 52c41714ec54..de17aed578f0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -133,7 +133,7 @@ xfs_getattr(
133 if (!(flags & ATTR_LAZY)) 133 if (!(flags & ATTR_LAZY))
134 xfs_ilock(ip, XFS_ILOCK_SHARED); 134 xfs_ilock(ip, XFS_ILOCK_SHARED);
135 135
136 vap->va_size = ip->i_d.di_size; 136 vap->va_size = XFS_ISIZE(ip);
137 if (vap->va_mask == XFS_AT_SIZE) 137 if (vap->va_mask == XFS_AT_SIZE)
138 goto all_done; 138 goto all_done;
139 139
@@ -496,7 +496,7 @@ xfs_setattr(
496 if (mask & XFS_AT_SIZE) { 496 if (mask & XFS_AT_SIZE) {
497 /* Short circuit the truncate case for zero length files */ 497 /* Short circuit the truncate case for zero length files */
498 if ((vap->va_size == 0) && 498 if ((vap->va_size == 0) &&
499 (ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) { 499 (ip->i_size == 0) && (ip->i_d.di_nextents == 0)) {
500 xfs_iunlock(ip, XFS_ILOCK_EXCL); 500 xfs_iunlock(ip, XFS_ILOCK_EXCL);
501 lock_flags &= ~XFS_ILOCK_EXCL; 501 lock_flags &= ~XFS_ILOCK_EXCL;
502 if (mask & XFS_AT_CTIME) 502 if (mask & XFS_AT_CTIME)
@@ -614,7 +614,7 @@ xfs_setattr(
614 */ 614 */
615 if (mask & XFS_AT_SIZE) { 615 if (mask & XFS_AT_SIZE) {
616 code = 0; 616 code = 0;
617 if ((vap->va_size > ip->i_d.di_size) && 617 if ((vap->va_size > ip->i_size) &&
618 (flags & ATTR_NOSIZETOK) == 0) { 618 (flags & ATTR_NOSIZETOK) == 0) {
619 code = xfs_igrow_start(ip, vap->va_size, credp); 619 code = xfs_igrow_start(ip, vap->va_size, credp);
620 } 620 }
@@ -654,10 +654,10 @@ xfs_setattr(
654 * Truncate file. Must have write permission and not be a directory. 654 * Truncate file. Must have write permission and not be a directory.
655 */ 655 */
656 if (mask & XFS_AT_SIZE) { 656 if (mask & XFS_AT_SIZE) {
657 if (vap->va_size > ip->i_d.di_size) { 657 if (vap->va_size > ip->i_size) {
658 xfs_igrow_finish(tp, ip, vap->va_size, 658 xfs_igrow_finish(tp, ip, vap->va_size,
659 !(flags & ATTR_DMI)); 659 !(flags & ATTR_DMI));
660 } else if ((vap->va_size <= ip->i_d.di_size) || 660 } else if ((vap->va_size <= ip->i_size) ||
661 ((vap->va_size == 0) && ip->i_d.di_nextents)) { 661 ((vap->va_size == 0) && ip->i_d.di_nextents)) {
662 /* 662 /*
663 * signal a sync transaction unless 663 * signal a sync transaction unless
@@ -873,7 +873,7 @@ xfs_setattr(
873 if (mp->m_flags & XFS_MOUNT_WSYNC) 873 if (mp->m_flags & XFS_MOUNT_WSYNC)
874 xfs_trans_set_sync(tp); 874 xfs_trans_set_sync(tp);
875 875
876 code = xfs_trans_commit(tp, commit_flags, NULL); 876 code = xfs_trans_commit(tp, commit_flags);
877 } 877 }
878 878
879 /* 879 /*
@@ -1176,7 +1176,7 @@ xfs_fsync(
1176 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1176 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1177 if (flag & FSYNC_WAIT) 1177 if (flag & FSYNC_WAIT)
1178 xfs_trans_set_sync(tp); 1178 xfs_trans_set_sync(tp);
1179 error = _xfs_trans_commit(tp, 0, NULL, &log_flushed); 1179 error = _xfs_trans_commit(tp, 0, &log_flushed);
1180 1180
1181 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1181 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1182 } 1182 }
@@ -1221,7 +1221,7 @@ xfs_inactive_free_eofblocks(
1221 * Figure out if there are any blocks beyond the end 1221 * Figure out if there are any blocks beyond the end
1222 * of the file. If not, then there is nothing to do. 1222 * of the file. If not, then there is nothing to do.
1223 */ 1223 */
1224 end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size)); 1224 end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_size));
1225 last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); 1225 last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
1226 map_len = last_fsb - end_fsb; 1226 map_len = last_fsb - end_fsb;
1227 if (map_len <= 0) 1227 if (map_len <= 0)
@@ -1257,8 +1257,12 @@ xfs_inactive_free_eofblocks(
1257 * do that within a transaction. 1257 * do that within a transaction.
1258 */ 1258 */
1259 xfs_ilock(ip, XFS_IOLOCK_EXCL); 1259 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1260 xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 1260 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
1261 ip->i_d.di_size); 1261 ip->i_size);
1262 if (error) {
1263 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1264 return error;
1265 }
1262 1266
1263 error = xfs_trans_reserve(tp, 0, 1267 error = xfs_trans_reserve(tp, 0,
1264 XFS_ITRUNCATE_LOG_RES(mp), 1268 XFS_ITRUNCATE_LOG_RES(mp),
@@ -1278,7 +1282,7 @@ xfs_inactive_free_eofblocks(
1278 xfs_trans_ihold(tp, ip); 1282 xfs_trans_ihold(tp, ip);
1279 1283
1280 error = xfs_itruncate_finish(&tp, ip, 1284 error = xfs_itruncate_finish(&tp, ip,
1281 ip->i_d.di_size, 1285 ip->i_size,
1282 XFS_DATA_FORK, 1286 XFS_DATA_FORK,
1283 0); 1287 0);
1284 /* 1288 /*
@@ -1291,8 +1295,7 @@ xfs_inactive_free_eofblocks(
1291 XFS_TRANS_ABORT)); 1295 XFS_TRANS_ABORT));
1292 } else { 1296 } else {
1293 error = xfs_trans_commit(tp, 1297 error = xfs_trans_commit(tp,
1294 XFS_TRANS_RELEASE_LOG_RES, 1298 XFS_TRANS_RELEASE_LOG_RES);
1295 NULL);
1296 } 1299 }
1297 xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); 1300 xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
1298 } 1301 }
@@ -1406,7 +1409,7 @@ xfs_inactive_symlink_rmt(
1406 * we need to unlock the inode since the new transaction doesn't 1409 * we need to unlock the inode since the new transaction doesn't
1407 * have the inode attached. 1410 * have the inode attached.
1408 */ 1411 */
1409 error = xfs_trans_commit(tp, 0, NULL); 1412 error = xfs_trans_commit(tp, 0);
1410 tp = ntp; 1413 tp = ntp;
1411 if (error) { 1414 if (error) {
1412 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1415 ASSERT(XFS_FORCED_SHUTDOWN(mp));
@@ -1503,7 +1506,7 @@ xfs_inactive_attrs(
1503 tp = *tpp; 1506 tp = *tpp;
1504 mp = ip->i_mount; 1507 mp = ip->i_mount;
1505 ASSERT(ip->i_d.di_forkoff != 0); 1508 ASSERT(ip->i_d.di_forkoff != 0);
1506 xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 1509 xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1507 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1510 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1508 1511
1509 error = xfs_attr_inactive(ip); 1512 error = xfs_attr_inactive(ip);
@@ -1565,7 +1568,7 @@ xfs_release(
1565 1568
1566 if (ip->i_d.di_nlink != 0) { 1569 if (ip->i_d.di_nlink != 0) {
1567 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1570 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1568 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1571 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
1569 ip->i_delayed_blks > 0)) && 1572 ip->i_delayed_blks > 0)) &&
1570 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 1573 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
1571 (!(ip->i_d.di_flags & 1574 (!(ip->i_d.di_flags &
@@ -1626,8 +1629,8 @@ xfs_inactive(
1626 * only one with a reference to the inode. 1629 * only one with a reference to the inode.
1627 */ 1630 */
1628 truncate = ((ip->i_d.di_nlink == 0) && 1631 truncate = ((ip->i_d.di_nlink == 0) &&
1629 ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) || 1632 ((ip->i_d.di_size != 0) || (ip->i_size != 0) ||
1630 (ip->i_delayed_blks > 0)) && 1633 (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) &&
1631 ((ip->i_d.di_mode & S_IFMT) == S_IFREG)); 1634 ((ip->i_d.di_mode & S_IFMT) == S_IFREG));
1632 1635
1633 mp = ip->i_mount; 1636 mp = ip->i_mount;
@@ -1645,7 +1648,7 @@ xfs_inactive(
1645 1648
1646 if (ip->i_d.di_nlink != 0) { 1649 if (ip->i_d.di_nlink != 0) {
1647 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1650 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1648 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1651 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
1649 ip->i_delayed_blks > 0)) && 1652 ip->i_delayed_blks > 0)) &&
1650 (ip->i_df.if_flags & XFS_IFEXTENTS) && 1653 (ip->i_df.if_flags & XFS_IFEXTENTS) &&
1651 (!(ip->i_d.di_flags & 1654 (!(ip->i_d.di_flags &
@@ -1675,7 +1678,11 @@ xfs_inactive(
1675 */ 1678 */
1676 xfs_ilock(ip, XFS_IOLOCK_EXCL); 1679 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1677 1680
1678 xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); 1681 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
1682 if (error) {
1683 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1684 return VN_INACTIVE_CACHE;
1685 }
1679 1686
1680 error = xfs_trans_reserve(tp, 0, 1687 error = xfs_trans_reserve(tp, 0,
1681 XFS_ITRUNCATE_LOG_RES(mp), 1688 XFS_ITRUNCATE_LOG_RES(mp),
@@ -1790,7 +1797,7 @@ xfs_inactive(
1790 * nothing we can do except to try to keep going. 1797 * nothing we can do except to try to keep going.
1791 */ 1798 */
1792 (void) xfs_bmap_finish(&tp, &free_list, &committed); 1799 (void) xfs_bmap_finish(&tp, &free_list, &committed);
1793 (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 1800 (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1794 } 1801 }
1795 /* 1802 /*
1796 * Release the dquots held by inode, if any. 1803 * Release the dquots held by inode, if any.
@@ -1940,7 +1947,7 @@ xfs_create(
1940 goto error_return; 1947 goto error_return;
1941 } 1948 }
1942 1949
1943 xfs_ilock(dp, XFS_ILOCK_EXCL); 1950 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
1944 1951
1945 XFS_BMAP_INIT(&free_list, &first_block); 1952 XFS_BMAP_INIT(&free_list, &first_block);
1946 1953
@@ -2026,7 +2033,7 @@ xfs_create(
2026 goto abort_rele; 2033 goto abort_rele;
2027 } 2034 }
2028 2035
2029 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 2036 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2030 if (error) { 2037 if (error) {
2031 IRELE(ip); 2038 IRELE(ip);
2032 tp = NULL; 2039 tp = NULL;
@@ -2121,7 +2128,6 @@ int xfs_rm_attempts;
2121STATIC int 2128STATIC int
2122xfs_lock_dir_and_entry( 2129xfs_lock_dir_and_entry(
2123 xfs_inode_t *dp, 2130 xfs_inode_t *dp,
2124 bhv_vname_t *dentry,
2125 xfs_inode_t *ip) /* inode of entry 'name' */ 2131 xfs_inode_t *ip) /* inode of entry 'name' */
2126{ 2132{
2127 int attempts; 2133 int attempts;
@@ -2135,7 +2141,7 @@ xfs_lock_dir_and_entry(
2135 attempts = 0; 2141 attempts = 0;
2136 2142
2137again: 2143again:
2138 xfs_ilock(dp, XFS_ILOCK_EXCL); 2144 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
2139 2145
2140 e_inum = ip->i_ino; 2146 e_inum = ip->i_ino;
2141 2147
@@ -2204,6 +2210,21 @@ int xfs_lock_delays;
2204#endif 2210#endif
2205 2211
2206/* 2212/*
2213 * Bump the subclass so xfs_lock_inodes() acquires each lock with
2214 * a different value
2215 */
2216static inline int
2217xfs_lock_inumorder(int lock_mode, int subclass)
2218{
2219 if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
2220 lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
2221 if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
2222 lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
2223
2224 return lock_mode;
2225}
2226
2227/*
2207 * The following routine will lock n inodes in exclusive mode. 2228 * The following routine will lock n inodes in exclusive mode.
2208 * We assume the caller calls us with the inodes in i_ino order. 2229 * We assume the caller calls us with the inodes in i_ino order.
2209 * 2230 *
@@ -2270,7 +2291,7 @@ again:
2270 * that is in the AIL. 2291 * that is in the AIL.
2271 */ 2292 */
2272 ASSERT(i != 0); 2293 ASSERT(i != 0);
2273 if (!xfs_ilock_nowait(ips[i], lock_mode)) { 2294 if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
2274 attempts++; 2295 attempts++;
2275 2296
2276 /* 2297 /*
@@ -2305,7 +2326,7 @@ again:
2305 goto again; 2326 goto again;
2306 } 2327 }
2307 } else { 2328 } else {
2308 xfs_ilock(ips[i], lock_mode); 2329 xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
2309 } 2330 }
2310 } 2331 }
2311 2332
@@ -2440,7 +2461,7 @@ xfs_remove(
2440 return error; 2461 return error;
2441 } 2462 }
2442 2463
2443 error = xfs_lock_dir_and_entry(dp, dentry, ip); 2464 error = xfs_lock_dir_and_entry(dp, ip);
2444 if (error) { 2465 if (error) {
2445 REMOVE_DEBUG_TRACE(__LINE__); 2466 REMOVE_DEBUG_TRACE(__LINE__);
2446 xfs_trans_cancel(tp, cancel_flags); 2467 xfs_trans_cancel(tp, cancel_flags);
@@ -2511,7 +2532,7 @@ xfs_remove(
2511 goto error_rele; 2532 goto error_rele;
2512 } 2533 }
2513 2534
2514 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 2535 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2515 if (error) { 2536 if (error) {
2516 IRELE(ip); 2537 IRELE(ip);
2517 goto std_return; 2538 goto std_return;
@@ -2719,7 +2740,7 @@ xfs_link(
2719 goto abort_return; 2740 goto abort_return;
2720 } 2741 }
2721 2742
2722 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 2743 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2723 if (error) 2744 if (error)
2724 goto std_return; 2745 goto std_return;
2725 2746
@@ -2839,7 +2860,7 @@ xfs_mkdir(
2839 goto error_return; 2860 goto error_return;
2840 } 2861 }
2841 2862
2842 xfs_ilock(dp, XFS_ILOCK_EXCL); 2863 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
2843 2864
2844 /* 2865 /*
2845 * Check for directory link count overflow. 2866 * Check for directory link count overflow.
@@ -2936,7 +2957,7 @@ xfs_mkdir(
2936 goto error2; 2957 goto error2;
2937 } 2958 }
2938 2959
2939 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 2960 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2940 XFS_QM_DQRELE(mp, udqp); 2961 XFS_QM_DQRELE(mp, udqp);
2941 XFS_QM_DQRELE(mp, gdqp); 2962 XFS_QM_DQRELE(mp, gdqp);
2942 if (error) { 2963 if (error) {
@@ -3096,7 +3117,7 @@ xfs_rmdir(
3096 * that the directory entry for the child directory inode has 3117 * that the directory entry for the child directory inode has
3097 * not changed while we were obtaining a log reservation. 3118 * not changed while we were obtaining a log reservation.
3098 */ 3119 */
3099 error = xfs_lock_dir_and_entry(dp, dentry, cdp); 3120 error = xfs_lock_dir_and_entry(dp, cdp);
3100 if (error) { 3121 if (error) {
3101 xfs_trans_cancel(tp, cancel_flags); 3122 xfs_trans_cancel(tp, cancel_flags);
3102 IRELE(cdp); 3123 IRELE(cdp);
@@ -3190,7 +3211,7 @@ xfs_rmdir(
3190 goto std_return; 3211 goto std_return;
3191 } 3212 }
3192 3213
3193 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 3214 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
3194 if (error) { 3215 if (error) {
3195 IRELE(cdp); 3216 IRELE(cdp);
3196 goto std_return; 3217 goto std_return;
@@ -3393,7 +3414,7 @@ xfs_symlink(
3393 goto error_return; 3414 goto error_return;
3394 } 3415 }
3395 3416
3396 xfs_ilock(dp, XFS_ILOCK_EXCL); 3417 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
3397 3418
3398 /* 3419 /*
3399 * Check whether the directory allows new symlinks or not. 3420 * Check whether the directory allows new symlinks or not.
@@ -3535,7 +3556,7 @@ xfs_symlink(
3535 if (error) { 3556 if (error) {
3536 goto error2; 3557 goto error2;
3537 } 3558 }
3538 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 3559 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
3539 XFS_QM_DQRELE(mp, udqp); 3560 XFS_QM_DQRELE(mp, udqp);
3540 XFS_QM_DQRELE(mp, gdqp); 3561 XFS_QM_DQRELE(mp, gdqp);
3541 3562
@@ -3790,7 +3811,7 @@ xfs_set_dmattrs (
3790 3811
3791 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 3812 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
3792 IHOLD(ip); 3813 IHOLD(ip);
3793 error = xfs_trans_commit(tp, 0, NULL); 3814 error = xfs_trans_commit(tp, 0);
3794 3815
3795 return error; 3816 return error;
3796} 3817}
@@ -4049,14 +4070,14 @@ xfs_alloc_file_space(
4049 allocatesize_fsb = XFS_B_TO_FSB(mp, count); 4070 allocatesize_fsb = XFS_B_TO_FSB(mp, count);
4050 4071
4051 /* Generate a DMAPI event if needed. */ 4072 /* Generate a DMAPI event if needed. */
4052 if (alloc_type != 0 && offset < ip->i_d.di_size && 4073 if (alloc_type != 0 && offset < ip->i_size &&
4053 (attr_flags&ATTR_DMI) == 0 && 4074 (attr_flags&ATTR_DMI) == 0 &&
4054 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4075 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4055 xfs_off_t end_dmi_offset; 4076 xfs_off_t end_dmi_offset;
4056 4077
4057 end_dmi_offset = offset+len; 4078 end_dmi_offset = offset+len;
4058 if (end_dmi_offset > ip->i_d.di_size) 4079 if (end_dmi_offset > ip->i_size)
4059 end_dmi_offset = ip->i_d.di_size; 4080 end_dmi_offset = ip->i_size;
4060 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 4081 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
4061 offset, end_dmi_offset - offset, 4082 offset, end_dmi_offset - offset,
4062 0, NULL); 4083 0, NULL);
@@ -4148,7 +4169,7 @@ retry:
4148 goto error0; 4169 goto error0;
4149 } 4170 }
4150 4171
4151 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 4172 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
4152 xfs_iunlock(ip, XFS_ILOCK_EXCL); 4173 xfs_iunlock(ip, XFS_ILOCK_EXCL);
4153 if (error) { 4174 if (error) {
4154 break; 4175 break;
@@ -4283,7 +4304,6 @@ xfs_free_file_space(
4283 int error; 4304 int error;
4284 xfs_fsblock_t firstfsb; 4305 xfs_fsblock_t firstfsb;
4285 xfs_bmap_free_t free_list; 4306 xfs_bmap_free_t free_list;
4286 xfs_off_t ilen;
4287 xfs_bmbt_irec_t imap; 4307 xfs_bmbt_irec_t imap;
4288 xfs_off_t ioffset; 4308 xfs_off_t ioffset;
4289 xfs_extlen_t mod=0; 4309 xfs_extlen_t mod=0;
@@ -4312,11 +4332,11 @@ xfs_free_file_space(
4312 end_dmi_offset = offset + len; 4332 end_dmi_offset = offset + len;
4313 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); 4333 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
4314 4334
4315 if (offset < ip->i_d.di_size && 4335 if (offset < ip->i_size &&
4316 (attr_flags & ATTR_DMI) == 0 && 4336 (attr_flags & ATTR_DMI) == 0 &&
4317 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4337 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4318 if (end_dmi_offset > ip->i_d.di_size) 4338 if (end_dmi_offset > ip->i_size)
4319 end_dmi_offset = ip->i_d.di_size; 4339 end_dmi_offset = ip->i_size;
4320 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, 4340 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
4321 offset, end_dmi_offset - offset, 4341 offset, end_dmi_offset - offset,
4322 AT_DELAY_FLAG(attr_flags), NULL); 4342 AT_DELAY_FLAG(attr_flags), NULL);
@@ -4332,16 +4352,15 @@ xfs_free_file_space(
4332 } 4352 }
4333 4353
4334 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); 4354 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
4335 ilen = len + (offset & (rounding - 1));
4336 ioffset = offset & ~(rounding - 1); 4355 ioffset = offset & ~(rounding - 1);
4337 if (ilen & (rounding - 1))
4338 ilen = (ilen + rounding) & ~(rounding - 1);
4339 4356
4340 if (VN_CACHED(vp) != 0) { 4357 if (VN_CACHED(vp) != 0) {
4341 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, 4358 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4342 ctooff(offtoct(ioffset)), -1); 4359 ctooff(offtoct(ioffset)), -1);
4343 bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), 4360 error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
4344 -1, FI_REMAPF_LOCKED); 4361 -1, FI_REMAPF_LOCKED);
4362 if (error)
4363 goto out_unlock_iolock;
4345 } 4364 }
4346 4365
4347 /* 4366 /*
@@ -4455,7 +4474,7 @@ xfs_free_file_space(
4455 goto error0; 4474 goto error0;
4456 } 4475 }
4457 4476
4458 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 4477 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
4459 xfs_iunlock(ip, XFS_ILOCK_EXCL); 4478 xfs_iunlock(ip, XFS_ILOCK_EXCL);
4460 } 4479 }
4461 4480
@@ -4533,7 +4552,7 @@ xfs_change_file_space(
4533 bf->l_start += offset; 4552 bf->l_start += offset;
4534 break; 4553 break;
4535 case 2: /*SEEK_END*/ 4554 case 2: /*SEEK_END*/
4536 bf->l_start += ip->i_d.di_size; 4555 bf->l_start += ip->i_size;
4537 break; 4556 break;
4538 default: 4557 default:
4539 return XFS_ERROR(EINVAL); 4558 return XFS_ERROR(EINVAL);
@@ -4550,7 +4569,7 @@ xfs_change_file_space(
4550 bf->l_whence = 0; 4569 bf->l_whence = 0;
4551 4570
4552 startoffset = bf->l_start; 4571 startoffset = bf->l_start;
4553 fsize = ip->i_d.di_size; 4572 fsize = ip->i_size;
4554 4573
4555 /* 4574 /*
4556 * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve 4575 * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve
@@ -4649,7 +4668,7 @@ xfs_change_file_space(
4649 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 4668 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
4650 xfs_trans_set_sync(tp); 4669 xfs_trans_set_sync(tp);
4651 4670
4652 error = xfs_trans_commit(tp, 0, NULL); 4671 error = xfs_trans_commit(tp, 0);
4653 4672
4654 xfs_iunlock(ip, XFS_ILOCK_EXCL); 4673 xfs_iunlock(ip, XFS_ILOCK_EXCL);
4655 4674