aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-02-15 04:44:48 -0500
committerAlex Elder <aelder@sgi.com>2010-03-01 17:34:38 -0500
commitfd3200bef7d66ed3924f72c79a465fb7ff85478a (patch)
treef10c210269fc59854dd8f8b247b63454d772a574 /fs
parent00258e36b2d33b1b5cef7b489e06c5e0a9df58b5 (diff)
xfs: remove wrapper for the fsync file operation
Currently the fsync file operation is divided into a low-level routine doing all the work and one that implements the Linux file operation and does minimal argument wrapping. This is a leftover from the days of the vnode operations layer and can be removed to simplify the code a bit, as well as preparing for the implementation of an optimized fdatasync which needs to look at the Linux inode state. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c140
-rw-r--r--fs/xfs/xfs_vnodeops.c107
-rw-r--r--fs/xfs/xfs_vnodeops.h1
3 files changed, 117 insertions, 131 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 1eb561a10e26..6c283b7be8ab 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -35,6 +35,7 @@
35#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
36#include "xfs_dinode.h" 36#include "xfs_dinode.h"
37#include "xfs_inode.h" 37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
38#include "xfs_bmap.h" 39#include "xfs_bmap.h"
39#include "xfs_error.h" 40#include "xfs_error.h"
40#include "xfs_rw.h" 41#include "xfs_rw.h"
@@ -96,6 +97,120 @@ xfs_iozero(
96 return (-status); 97 return (-status);
97} 98}
98 99
100/*
101 * We ignore the datasync flag here because a datasync is effectively
102 * identical to an fsync. That is, datasync implies that we need to write
103 * only the metadata needed to be able to access the data that is written
104 * if we crash after the call completes. Hence if we are writing beyond
105 * EOF we have to log the inode size change as well, which makes it a
106 * full fsync. If we don't write beyond EOF, the inode core will be
107 * clean in memory and so we don't need to log the inode, just like
108 * fsync.
109 */
110STATIC int
111xfs_file_fsync(
112 struct file *file,
113 struct dentry *dentry,
114 int datasync)
115{
116 struct xfs_inode *ip = XFS_I(dentry->d_inode);
117 struct xfs_trans *tp;
118 int error = 0;
119 int log_flushed = 0;
120
121 xfs_itrace_entry(ip);
122
123 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
124 return -XFS_ERROR(EIO);
125
126 xfs_iflags_clear(ip, XFS_ITRUNCATED);
127
128 /*
129 * We always need to make sure that the required inode state is safe on
130 * disk. The inode might be clean but we still might need to force the
131 * log because of committed transactions that haven't hit the disk yet.
132 * Likewise, there could be unflushed non-transactional changes to the
133 * inode core that have to go to disk and this requires us to issue
134 * a synchronous transaction to capture these changes correctly.
135 *
136 * This code relies on the assumption that if the i_update_core field
137 * of the inode is clear and the inode is unpinned then it is clean
138 * and no action is required.
139 */
140 xfs_ilock(ip, XFS_ILOCK_SHARED);
141
142 if (ip->i_update_core) {
143 /*
144 * Kick off a transaction to log the inode core to get the
145 * updates. The sync transaction will also force the log.
146 */
147 xfs_iunlock(ip, XFS_ILOCK_SHARED);
148 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
149 error = xfs_trans_reserve(tp, 0,
150 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
151 if (error) {
152 xfs_trans_cancel(tp, 0);
153 return -error;
154 }
155 xfs_ilock(ip, XFS_ILOCK_EXCL);
156
157 /*
158 * Note - it's possible that we might have pushed ourselves out
159 * of the way during trans_reserve which would flush the inode.
160 * But there's no guarantee that the inode buffer has actually
161 * gone out yet (it's delwri). Plus the buffer could be pinned
162 * anyway if it's part of an inode in another recent
163 * transaction. So we play it safe and fire off the
164 * transaction anyway.
165 */
166 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
167 xfs_trans_ihold(tp, ip);
168 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
169 xfs_trans_set_sync(tp);
170 error = _xfs_trans_commit(tp, 0, &log_flushed);
171
172 xfs_iunlock(ip, XFS_ILOCK_EXCL);
173 } else {
174 /*
175 * Timestamps/size haven't changed since last inode flush or
176 * inode transaction commit. That means either nothing got
177 * written or a transaction committed which caught the updates.
178 * If the latter happened and the transaction hasn't hit the
179 * disk yet, the inode will be still be pinned. If it is,
180 * force the log.
181 */
182 xfs_iunlock(ip, XFS_ILOCK_SHARED);
183 if (xfs_ipincount(ip)) {
184 if (ip->i_itemp->ili_last_lsn) {
185 error = _xfs_log_force_lsn(ip->i_mount,
186 ip->i_itemp->ili_last_lsn,
187 XFS_LOG_SYNC, &log_flushed);
188 } else {
189 error = _xfs_log_force(ip->i_mount,
190 XFS_LOG_SYNC, &log_flushed);
191 }
192 }
193 }
194
195 if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
196 /*
197 * If the log write didn't issue an ordered tag we need
198 * to flush the disk cache for the data device now.
199 */
200 if (!log_flushed)
201 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
202
203 /*
204 * If this inode is on the RT dev we need to flush that
205 * cache as well.
206 */
207 if (XFS_IS_REALTIME_INODE(ip))
208 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
209 }
210
211 return -error;
212}
213
99STATIC ssize_t 214STATIC ssize_t
100xfs_file_aio_read( 215xfs_file_aio_read(
101 struct kiocb *iocb, 216 struct kiocb *iocb,
@@ -755,7 +870,8 @@ write_retry:
755 mutex_lock(&inode->i_mutex); 870 mutex_lock(&inode->i_mutex);
756 xfs_ilock(ip, iolock); 871 xfs_ilock(ip, iolock);
757 872
758 error2 = xfs_fsync(ip); 873 error2 = -xfs_file_fsync(file, file->f_path.dentry,
874 (file->f_flags & __O_SYNC) ? 0 : 1);
759 if (!error) 875 if (!error)
760 error = error2; 876 error = error2;
761 } 877 }
@@ -826,28 +942,6 @@ xfs_file_release(
826 return -xfs_release(XFS_I(inode)); 942 return -xfs_release(XFS_I(inode));
827} 943}
828 944
829/*
830 * We ignore the datasync flag here because a datasync is effectively
831 * identical to an fsync. That is, datasync implies that we need to write
832 * only the metadata needed to be able to access the data that is written
833 * if we crash after the call completes. Hence if we are writing beyond
834 * EOF we have to log the inode size change as well, which makes it a
835 * full fsync. If we don't write beyond EOF, the inode core will be
836 * clean in memory and so we don't need to log the inode, just like
837 * fsync.
838 */
839STATIC int
840xfs_file_fsync(
841 struct file *file,
842 struct dentry *dentry,
843 int datasync)
844{
845 struct xfs_inode *ip = XFS_I(dentry->d_inode);
846
847 xfs_iflags_clear(ip, XFS_ITRUNCATED);
848 return -xfs_fsync(ip);
849}
850
851STATIC int 945STATIC int
852xfs_file_readdir( 946xfs_file_readdir(
853 struct file *filp, 947 struct file *filp,
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index ddd2c5d1b854..9d376be0ea38 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -584,113 +584,6 @@ xfs_readlink(
584} 584}
585 585
586/* 586/*
587 * xfs_fsync
588 *
589 * This is called to sync the inode and its data out to disk. We need to hold
590 * the I/O lock while flushing the data, and the inode lock while flushing the
591 * inode. The inode lock CANNOT be held while flushing the data, so acquire
592 * after we're done with that.
593 */
594int
595xfs_fsync(
596 xfs_inode_t *ip)
597{
598 xfs_trans_t *tp;
599 int error = 0;
600 int log_flushed = 0;
601
602 xfs_itrace_entry(ip);
603
604 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
605 return XFS_ERROR(EIO);
606
607 /*
608 * We always need to make sure that the required inode state is safe on
609 * disk. The inode might be clean but we still might need to force the
610 * log because of committed transactions that haven't hit the disk yet.
611 * Likewise, there could be unflushed non-transactional changes to the
612 * inode core that have to go to disk and this requires us to issue
613 * a synchronous transaction to capture these changes correctly.
614 *
615 * This code relies on the assumption that if the update_* fields
616 * of the inode are clear and the inode is unpinned then it is clean
617 * and no action is required.
618 */
619 xfs_ilock(ip, XFS_ILOCK_SHARED);
620
621 if (!ip->i_update_core) {
622 /*
623 * Timestamps/size haven't changed since last inode flush or
624 * inode transaction commit. That means either nothing got
625 * written or a transaction committed which caught the updates.
626 * If the latter happened and the transaction hasn't hit the
627 * disk yet, the inode will be still be pinned. If it is,
628 * force the log.
629 */
630 xfs_iunlock(ip, XFS_ILOCK_SHARED);
631 if (xfs_ipincount(ip)) {
632 if (ip->i_itemp->ili_last_lsn) {
633 error = _xfs_log_force_lsn(ip->i_mount,
634 ip->i_itemp->ili_last_lsn,
635 XFS_LOG_SYNC, &log_flushed);
636 } else {
637 error = _xfs_log_force(ip->i_mount,
638 XFS_LOG_SYNC, &log_flushed);
639 }
640 }
641 } else {
642 /*
643 * Kick off a transaction to log the inode core to get the
644 * updates. The sync transaction will also force the log.
645 */
646 xfs_iunlock(ip, XFS_ILOCK_SHARED);
647 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
648 error = xfs_trans_reserve(tp, 0,
649 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
650 if (error) {
651 xfs_trans_cancel(tp, 0);
652 return error;
653 }
654 xfs_ilock(ip, XFS_ILOCK_EXCL);
655
656 /*
657 * Note - it's possible that we might have pushed ourselves out
658 * of the way during trans_reserve which would flush the inode.
659 * But there's no guarantee that the inode buffer has actually
660 * gone out yet (it's delwri). Plus the buffer could be pinned
661 * anyway if it's part of an inode in another recent
662 * transaction. So we play it safe and fire off the
663 * transaction anyway.
664 */
665 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
666 xfs_trans_ihold(tp, ip);
667 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
668 xfs_trans_set_sync(tp);
669 error = _xfs_trans_commit(tp, 0, &log_flushed);
670
671 xfs_iunlock(ip, XFS_ILOCK_EXCL);
672 }
673
674 if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
675 /*
676 * If the log write didn't issue an ordered tag we need
677 * to flush the disk cache for the data device now.
678 */
679 if (!log_flushed)
680 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
681
682 /*
683 * If this inode is on the RT dev we need to flush that
684 * cache as well.
685 */
686 if (XFS_IS_REALTIME_INODE(ip))
687 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
688 }
689
690 return error;
691}
692
693/*
694 * Flags for xfs_free_eofblocks 587 * Flags for xfs_free_eofblocks
695 */ 588 */
696#define XFS_FREE_EOF_TRYLOCK (1<<0) 589#define XFS_FREE_EOF_TRYLOCK (1<<0)
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index ee33e11d9872..36f3858736f6 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -21,7 +21,6 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
21#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */ 21#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */
22 22
23int xfs_readlink(struct xfs_inode *ip, char *link); 23int xfs_readlink(struct xfs_inode *ip, char *link);
24int xfs_fsync(struct xfs_inode *ip);
25int xfs_release(struct xfs_inode *ip); 24int xfs_release(struct xfs_inode *ip);
26int xfs_inactive(struct xfs_inode *ip); 25int xfs_inactive(struct xfs_inode *ip);
27int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, 26int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,