aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c144
1 files changed, 62 insertions, 82 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 58bfe629b933..7c1f74531463 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,40 +1,26 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or
5 * under the terms of version 2 of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
7 * 8 *
8 * This program is distributed in the hope that it would be useful, but 9 * This program is distributed in the hope that it would be useful,
9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
11 * 13 *
12 * Further, this software is distributed without any warranty that it is 14 * You should have received a copy of the GNU General Public License
13 * free of the rightful claim of any third person regarding infringement 15 * along with this program; if not, write the Free Software Foundation,
14 * or the like. Any license provided herein, whether implied or 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 17 */
32
33#include "xfs.h" 18#include "xfs.h"
34#include "xfs_macros.h" 19#include "xfs_fs.h"
35#include "xfs_types.h" 20#include "xfs_types.h"
36#include "xfs_inum.h" 21#include "xfs_bit.h"
37#include "xfs_log.h" 22#include "xfs_log.h"
23#include "xfs_inum.h"
38#include "xfs_trans.h" 24#include "xfs_trans.h"
39#include "xfs_sb.h" 25#include "xfs_sb.h"
40#include "xfs_ag.h" 26#include "xfs_ag.h"
@@ -42,33 +28,32 @@
42#include "xfs_dir2.h" 28#include "xfs_dir2.h"
43#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
44#include "xfs_mount.h" 30#include "xfs_mount.h"
45#include "xfs_alloc_btree.h" 31#include "xfs_da_btree.h"
46#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h"
47#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
48#include "xfs_itable.h"
49#include "xfs_btree.h"
50#include "xfs_ialloc.h"
51#include "xfs_alloc.h"
52#include "xfs_attr_sf.h"
53#include "xfs_dir_sf.h" 35#include "xfs_dir_sf.h"
54#include "xfs_dir2_sf.h" 36#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h"
55#include "xfs_dinode.h" 38#include "xfs_dinode.h"
56#include "xfs_inode_item.h"
57#include "xfs_inode.h" 39#include "xfs_inode.h"
40#include "xfs_inode_item.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_itable.h"
43#include "xfs_btree.h"
44#include "xfs_ialloc.h"
45#include "xfs_alloc.h"
58#include "xfs_bmap.h" 46#include "xfs_bmap.h"
59#include "xfs_da_btree.h"
60#include "xfs_attr.h" 47#include "xfs_attr.h"
61#include "xfs_rw.h" 48#include "xfs_rw.h"
62#include "xfs_refcache.h"
63#include "xfs_error.h" 49#include "xfs_error.h"
64#include "xfs_bit.h"
65#include "xfs_rtalloc.h"
66#include "xfs_quota.h" 50#include "xfs_quota.h"
67#include "xfs_utils.h" 51#include "xfs_utils.h"
52#include "xfs_rtalloc.h"
53#include "xfs_refcache.h"
68#include "xfs_trans_space.h" 54#include "xfs_trans_space.h"
69#include "xfs_dir_leaf.h"
70#include "xfs_mac.h"
71#include "xfs_log_priv.h" 55#include "xfs_log_priv.h"
56#include "xfs_mac.h"
72 57
73 58
74/* 59/*
@@ -181,40 +166,7 @@ xfs_getattr(
181 vap->va_rdev = 0; 166 vap->va_rdev = 0;
182 167
183 if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { 168 if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
184 169 vap->va_blocksize = xfs_preferred_iosize(mp);
185#if 0
186 /* Large block sizes confuse various
187 * user space programs, so letting the
188 * stripe size through is not a good
189 * idea for now.
190 */
191 vap->va_blocksize = mp->m_swidth ?
192 /*
193 * If the underlying volume is a stripe, then
194 * return the stripe width in bytes as the
195 * recommended I/O size.
196 */
197 (mp->m_swidth << mp->m_sb.sb_blocklog) :
198 /*
199 * Return the largest of the preferred buffer
200 * sizes since doing small I/Os into larger
201 * buffers causes buffers to be decommissioned.
202 * The value returned is in bytes.
203 */
204 (1 << (int)MAX(mp->m_readio_log,
205 mp->m_writeio_log));
206
207#else
208 vap->va_blocksize =
209 /*
210 * Return the largest of the preferred buffer
211 * sizes since doing small I/Os into larger
212 * buffers causes buffers to be decommissioned.
213 * The value returned is in bytes.
214 */
215 1 << (int)MAX(mp->m_readio_log,
216 mp->m_writeio_log);
217#endif
218 } else { 170 } else {
219 171
220 /* 172 /*
@@ -581,8 +533,7 @@ xfs_setattr(
581 /* 533 /*
582 * Can't change extent size if any extents are allocated. 534 * Can't change extent size if any extents are allocated.
583 */ 535 */
584 if ((ip->i_d.di_nextents || ip->i_delayed_blks) && 536 if (ip->i_d.di_nextents && (mask & XFS_AT_EXTSIZE) &&
585 (mask & XFS_AT_EXTSIZE) &&
586 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != 537 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
587 vap->va_extsize) ) { 538 vap->va_extsize) ) {
588 code = XFS_ERROR(EINVAL); /* EFBIG? */ 539 code = XFS_ERROR(EINVAL); /* EFBIG? */
@@ -610,7 +561,8 @@ xfs_setattr(
610 /* 561 /*
611 * Can't change realtime flag if any extents are allocated. 562 * Can't change realtime flag if any extents are allocated.
612 */ 563 */
613 if (ip->i_d.di_nextents && (mask & XFS_AT_XFLAGS) && 564 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
565 (mask & XFS_AT_XFLAGS) &&
614 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 566 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
615 (vap->va_xflags & XFS_XFLAG_REALTIME)) { 567 (vap->va_xflags & XFS_XFLAG_REALTIME)) {
616 code = XFS_ERROR(EINVAL); /* EFBIG? */ 568 code = XFS_ERROR(EINVAL); /* EFBIG? */
@@ -674,8 +626,10 @@ xfs_setattr(
674 */ 626 */
675 if (mask & XFS_AT_SIZE) { 627 if (mask & XFS_AT_SIZE) {
676 code = 0; 628 code = 0;
677 if (vap->va_size > ip->i_d.di_size) 629 if ((vap->va_size > ip->i_d.di_size) &&
630 (flags & ATTR_NOSIZETOK) == 0) {
678 code = xfs_igrow_start(ip, vap->va_size, credp); 631 code = xfs_igrow_start(ip, vap->va_size, credp);
632 }
679 xfs_iunlock(ip, XFS_ILOCK_EXCL); 633 xfs_iunlock(ip, XFS_ILOCK_EXCL);
680 if (!code) 634 if (!code)
681 code = xfs_itruncate_data(ip, vap->va_size); 635 code = xfs_itruncate_data(ip, vap->va_size);
@@ -1118,6 +1072,7 @@ xfs_fsync(
1118 xfs_inode_t *ip; 1072 xfs_inode_t *ip;
1119 xfs_trans_t *tp; 1073 xfs_trans_t *tp;
1120 int error; 1074 int error;
1075 int log_flushed = 0, changed = 1;
1121 1076
1122 vn_trace_entry(BHV_TO_VNODE(bdp), 1077 vn_trace_entry(BHV_TO_VNODE(bdp),
1123 __FUNCTION__, (inst_t *)__return_address); 1078 __FUNCTION__, (inst_t *)__return_address);
@@ -1171,10 +1126,18 @@ xfs_fsync(
1171 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1126 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1172 1127
1173 if (xfs_ipincount(ip)) { 1128 if (xfs_ipincount(ip)) {
1174 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, 1129 _xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
1175 XFS_LOG_FORCE | 1130 XFS_LOG_FORCE |
1176 ((flag & FSYNC_WAIT) 1131 ((flag & FSYNC_WAIT)
1177 ? XFS_LOG_SYNC : 0)); 1132 ? XFS_LOG_SYNC : 0),
1133 &log_flushed);
1134 } else {
1135 /*
1136 * If the inode is not pinned and nothing
1137 * has changed we don't need to flush the
1138 * cache.
1139 */
1140 changed = 0;
1178 } 1141 }
1179 error = 0; 1142 error = 0;
1180 } else { 1143 } else {
@@ -1210,10 +1173,27 @@ xfs_fsync(
1210 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1173 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1211 if (flag & FSYNC_WAIT) 1174 if (flag & FSYNC_WAIT)
1212 xfs_trans_set_sync(tp); 1175 xfs_trans_set_sync(tp);
1213 error = xfs_trans_commit(tp, 0, NULL); 1176 error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
1214 1177
1215 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1178 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1216 } 1179 }
1180
1181 if ((ip->i_mount->m_flags & XFS_MOUNT_BARRIER) && changed) {
1182 /*
1183 * If the log write didn't issue an ordered tag we need
1184 * to flush the disk cache for the data device now.
1185 */
1186 if (!log_flushed)
1187 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
1188
1189 /*
1190 * If this inode is on the RT dev we need to flush that
1191 * cache aswell.
1192 */
1193 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
1194 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
1195 }
1196
1217 return error; 1197 return error;
1218} 1198}
1219 1199