diff options
author | Nathan Scott <nathans@sgi.com> | 2006-06-18 18:39:53 -0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-06-18 18:39:53 -0400 |
commit | 1e69dd0eb354d6f1a77098a3946b5ba57d4e3109 (patch) | |
tree | f97ce9c94f72cf142831ad12a701fc6378dc279f /fs/xfs/linux-2.6/xfs_lrw.c | |
parent | 1d47bec290a6f1f366192946840efef5076d9fc7 (diff) |
[XFS] Push some common code out of write path into core XFS code for
sharing.
SGI-PV: 904196
SGI-Modid: xfs-linux-melb:xfs-kern:26248a
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 76 |
1 files changed, 3 insertions, 73 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 3e76c5c9dda1..8e5468704816 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -892,79 +892,9 @@ retry: | |||
892 | 892 | ||
893 | /* Handle various SYNC-type writes */ | 893 | /* Handle various SYNC-type writes */ |
894 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { | 894 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { |
895 | /* | 895 | error = xfs_write_sync_logforce(mp, xip); |
896 | * If we're treating this as O_DSYNC and we have not updated the | 896 | if (error) |
897 | * size, force the log. | 897 | goto out_unlock_internal; |
898 | */ | ||
899 | if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) && | ||
900 | !(xip->i_update_size)) { | ||
901 | xfs_inode_log_item_t *iip = xip->i_itemp; | ||
902 | |||
903 | /* | ||
904 | * If an allocation transaction occurred | ||
905 | * without extending the size, then we have to force | ||
906 | * the log up the proper point to ensure that the | ||
907 | * allocation is permanent. We can't count on | ||
908 | * the fact that buffered writes lock out direct I/O | ||
909 | * writes - the direct I/O write could have extended | ||
910 | * the size nontransactionally, then finished before | ||
911 | * we started. xfs_write_file will think that the file | ||
912 | * didn't grow but the update isn't safe unless the | ||
913 | * size change is logged. | ||
914 | * | ||
915 | * Force the log if we've committed a transaction | ||
916 | * against the inode or if someone else has and | ||
917 | * the commit record hasn't gone to disk (e.g. | ||
918 | * the inode is pinned). This guarantees that | ||
919 | * all changes affecting the inode are permanent | ||
920 | * when we return. | ||
921 | */ | ||
922 | if (iip && iip->ili_last_lsn) { | ||
923 | xfs_log_force(mp, iip->ili_last_lsn, | ||
924 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
925 | } else if (xfs_ipincount(xip) > 0) { | ||
926 | xfs_log_force(mp, (xfs_lsn_t)0, | ||
927 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
928 | } | ||
929 | |||
930 | } else { | ||
931 | xfs_trans_t *tp; | ||
932 | |||
933 | /* | ||
934 | * O_SYNC or O_DSYNC _with_ a size update are handled | ||
935 | * the same way. | ||
936 | * | ||
937 | * If the write was synchronous then we need to make | ||
938 | * sure that the inode modification time is permanent. | ||
939 | * We'll have updated the timestamp above, so here | ||
940 | * we use a synchronous transaction to log the inode. | ||
941 | * It's not fast, but it's necessary. | ||
942 | * | ||
943 | * If this a dsync write and the size got changed | ||
944 | * non-transactionally, then we need to ensure that | ||
945 | * the size change gets logged in a synchronous | ||
946 | * transaction. | ||
947 | */ | ||
948 | |||
949 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC); | ||
950 | if ((error = xfs_trans_reserve(tp, 0, | ||
951 | XFS_SWRITE_LOG_RES(mp), | ||
952 | 0, 0, 0))) { | ||
953 | /* Transaction reserve failed */ | ||
954 | xfs_trans_cancel(tp, 0); | ||
955 | } else { | ||
956 | /* Transaction reserve successful */ | ||
957 | xfs_ilock(xip, XFS_ILOCK_EXCL); | ||
958 | xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL); | ||
959 | xfs_trans_ihold(tp, xip); | ||
960 | xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE); | ||
961 | xfs_trans_set_sync(tp); | ||
962 | error = xfs_trans_commit(tp, 0, NULL); | ||
963 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | ||
964 | } | ||
965 | if (error) | ||
966 | goto out_unlock_internal; | ||
967 | } | ||
968 | 898 | ||
969 | xfs_rwunlock(bdp, locktype); | 899 | xfs_rwunlock(bdp, locktype); |
970 | if (need_i_mutex) | 900 | if (need_i_mutex) |