7a932516f5
This is a late set of changes from Deepa Dinamani doing an automated treewide conversion of the inode and iattr structures from 'timespec' to 'timespec64', to push the conversion from the VFS layer into the individual file systems. There were no conflicts between this and the contents of linux-next until just before the merge window, when we saw multiple problems: - A minor conflict with my own y2038 fixes, which I could address by adding another patch on top here. - One semantic conflict with late changes to the NFS tree. I addressed this by merging Deepa's original branch on top of the changes that now got merged into mainline and making sure the merge commit includes the necessary changes as produced by coccinelle. - A trivial conflict against the removal of staging/lustre. - Multiple conflicts against the VFS changes in the overlayfs tree. These are still part of linux-next, but apparently this is no longer intended for 4.18 [1], so I am ignoring that part. As Deepa writes: The series aims to switch vfs timestamps to use struct timespec64. Currently vfs uses struct timespec, which is not y2038 safe. The series involves the following: 1. Add vfs helper functions for supporting struct timepec64 timestamps. 2. Cast prints of vfs timestamps to avoid warnings after the switch. 3. Simplify code using vfs timestamps so that the actual replacement becomes easy. 4. Convert vfs timestamps to use struct timespec64 using a script. This is a flag day patch. Next steps: 1. Convert APIs that can handle timespec64, instead of converting timestamps at the boundaries. 2. Update internal data structures to avoid timestamp conversions. Thomas Gleixner adds: I think there is no point to drag that out for the next merge window. The whole thing needs to be done in one go for the core changes which means that you're going to play that catchup game forever. Let's get over with it towards the end of the merge window. [1] https://www.spinics.net/lists/linux-fsdevel/msg128294.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJbInZAAAoJEGCrR//JCVInReoQAIlVIIMt5ZX6wmaKbrjy9Itf MfgbFihQ/djLnuSPVQ3nztcxF0d66BKHZ9puVjz6+mIHqfDvJTRwZs9nU+sOF/T1 g78fRkM1cxq6ZCkGYAbzyjyo5aC4PnSMP/NQLmwqvi0MXqqrbDoq5ZdP9DHJw39h L9lD8FM/P7T29Fgp9tq/pT5l9X8VU8+s5KQG1uhB5hii4VL6pD6JyLElDita7rg+ Z7/V7jkxIGEUWF7vGaiR1QTFzEtpUA/exDf9cnsf51OGtK/LJfQ0oiZPPuq3oA/E LSbt8YQQObc+dvfnGxwgxEg1k5WP5ekj/Wdibv/+rQKgGyLOTz6Q4xK6r8F2ahxs nyZQBdXqHhJYyKr1H1reUH3mrSgQbE5U5R1i3My0xV2dSn+vtK5vgF21v2Ku3A1G wJratdtF/kVBzSEQUhsYTw14Un+xhBLRWzcq0cELonqxaKvRQK9r92KHLIWNE7/v c0TmhFbkZA+zR8HdsaL3iYf1+0W/eYy8PcvepyldKNeW2pVk3CyvdTfY2Z87G2XK tIkK+BUWbG3drEGG3hxZ3757Ln3a9qWyC5ruD3mBVkuug/wekbI8PykYJS7Mx4s/ WNXl0dAL0Eeu1M8uEJejRAe1Q3eXoMWZbvCYZc+wAm92pATfHVcKwPOh8P7NHlfy A3HkjIBrKW5AgQDxfgvm =CZX2 -----END PGP SIGNATURE----- Merge tag 'vfs-timespec64' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground Pull inode timestamps conversion to timespec64 from Arnd Bergmann: "This is a late set of changes from Deepa Dinamani doing an automated treewide conversion of the inode and iattr structures from 'timespec' to 'timespec64', to push the conversion from the VFS layer into the individual file systems. As Deepa writes: 'The series aims to switch vfs timestamps to use struct timespec64. Currently vfs uses struct timespec, which is not y2038 safe. The series involves the following: 1. Add vfs helper functions for supporting struct timepec64 timestamps. 2. Cast prints of vfs timestamps to avoid warnings after the switch. 3. Simplify code using vfs timestamps so that the actual replacement becomes easy. 4. Convert vfs timestamps to use struct timespec64 using a script. This is a flag day patch. Next steps: 1. Convert APIs that can handle timespec64, instead of converting timestamps at the boundaries. 2. Update internal data structures to avoid timestamp conversions' Thomas Gleixner adds: 'I think there is no point to drag that out for the next merge window. The whole thing needs to be done in one go for the core changes which means that you're going to play that catchup game forever. Let's get over with it towards the end of the merge window'" * tag 'vfs-timespec64' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground: pstore: Remove bogus format string definition vfs: change inode times to use struct timespec64 pstore: Convert internal records to timespec64 udf: Simplify calls to udf_disk_stamp_to_time fs: nfs: get rid of memcpys for inode times ceph: make inode time prints to be long long lustre: Use long long type to print inode time fs: add timespec64_truncate()
155 lines
4.2 KiB
C
155 lines
4.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2000,2005 Silicon Graphics, Inc.
|
|
* All Rights Reserved.
|
|
*/
|
|
#include "xfs.h"
|
|
#include "xfs_fs.h"
|
|
#include "xfs_shared.h"
|
|
#include "xfs_format.h"
|
|
#include "xfs_log_format.h"
|
|
#include "xfs_trans_resv.h"
|
|
#include "xfs_mount.h"
|
|
#include "xfs_inode.h"
|
|
#include "xfs_trans.h"
|
|
#include "xfs_trans_priv.h"
|
|
#include "xfs_inode_item.h"
|
|
#include "xfs_trace.h"
|
|
|
|
#include <linux/iversion.h>
|
|
|
|
/*
|
|
* Add a locked inode to the transaction.
|
|
*
|
|
* The inode must be locked, and it cannot be associated with any transaction.
|
|
* If lock_flags is non-zero the inode will be unlocked on transaction commit.
|
|
*/
|
|
void
|
|
xfs_trans_ijoin(
|
|
struct xfs_trans *tp,
|
|
struct xfs_inode *ip,
|
|
uint lock_flags)
|
|
{
|
|
xfs_inode_log_item_t *iip;
|
|
|
|
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
if (ip->i_itemp == NULL)
|
|
xfs_inode_item_init(ip, ip->i_mount);
|
|
iip = ip->i_itemp;
|
|
|
|
ASSERT(iip->ili_lock_flags == 0);
|
|
iip->ili_lock_flags = lock_flags;
|
|
|
|
/*
|
|
* Get a log_item_desc to point at the new item.
|
|
*/
|
|
xfs_trans_add_item(tp, &iip->ili_item);
|
|
}
|
|
|
|
/*
|
|
* Transactional inode timestamp update. Requires the inode to be locked and
|
|
* joined to the transaction supplied. Relies on the transaction subsystem to
|
|
* track dirty state and update/writeback the inode accordingly.
|
|
*/
|
|
void
|
|
xfs_trans_ichgtime(
|
|
struct xfs_trans *tp,
|
|
struct xfs_inode *ip,
|
|
int flags)
|
|
{
|
|
struct inode *inode = VFS_I(ip);
|
|
struct timespec64 tv;
|
|
|
|
ASSERT(tp);
|
|
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
|
|
tv = current_time(inode);
|
|
|
|
if (flags & XFS_ICHGTIME_MOD)
|
|
inode->i_mtime = tv;
|
|
if (flags & XFS_ICHGTIME_CHG)
|
|
inode->i_ctime = tv;
|
|
}
|
|
|
|
/*
|
|
* This is called to mark the fields indicated in fieldmask as needing
|
|
* to be logged when the transaction is committed. The inode must
|
|
* already be associated with the given transaction.
|
|
*
|
|
* The values for fieldmask are defined in xfs_inode_item.h. We always
|
|
* log all of the core inode if any of it has changed, and we always log
|
|
* all of the inline data/extents/b-tree root if any of them has changed.
|
|
*/
|
|
void
|
|
xfs_trans_log_inode(
|
|
xfs_trans_t *tp,
|
|
xfs_inode_t *ip,
|
|
uint flags)
|
|
{
|
|
struct inode *inode = VFS_I(ip);
|
|
|
|
ASSERT(ip->i_itemp != NULL);
|
|
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
|
|
/*
|
|
* Don't bother with i_lock for the I_DIRTY_TIME check here, as races
|
|
* don't matter - we either will need an extra transaction in 24 hours
|
|
* to log the timestamps, or will clear already cleared fields in the
|
|
* worst case.
|
|
*/
|
|
if (inode->i_state & (I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED)) {
|
|
spin_lock(&inode->i_lock);
|
|
inode->i_state &= ~(I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED);
|
|
spin_unlock(&inode->i_lock);
|
|
}
|
|
|
|
/*
|
|
* Record the specific change for fdatasync optimisation. This
|
|
* allows fdatasync to skip log forces for inodes that are only
|
|
* timestamp dirty. We do this before the change count so that
|
|
* the core being logged in this case does not impact on fdatasync
|
|
* behaviour.
|
|
*/
|
|
ip->i_itemp->ili_fsync_fields |= flags;
|
|
|
|
/*
|
|
* First time we log the inode in a transaction, bump the inode change
|
|
* counter if it is configured for this to occur. While we have the
|
|
* inode locked exclusively for metadata modification, we can usually
|
|
* avoid setting XFS_ILOG_CORE if no one has queried the value since
|
|
* the last time it was incremented. If we have XFS_ILOG_CORE already
|
|
* set however, then go ahead and bump the i_version counter
|
|
* unconditionally.
|
|
*/
|
|
if (!test_and_set_bit(XFS_LI_DIRTY, &ip->i_itemp->ili_item.li_flags) &&
|
|
IS_I_VERSION(VFS_I(ip))) {
|
|
if (inode_maybe_inc_iversion(VFS_I(ip), flags & XFS_ILOG_CORE))
|
|
flags |= XFS_ILOG_CORE;
|
|
}
|
|
|
|
tp->t_flags |= XFS_TRANS_DIRTY;
|
|
|
|
/*
|
|
* Always OR in the bits from the ili_last_fields field.
|
|
* This is to coordinate with the xfs_iflush() and xfs_iflush_done()
|
|
* routines in the eventual clearing of the ili_fields bits.
|
|
* See the big comment in xfs_iflush() for an explanation of
|
|
* this coordination mechanism.
|
|
*/
|
|
flags |= ip->i_itemp->ili_last_fields;
|
|
ip->i_itemp->ili_fields |= flags;
|
|
}
|
|
|
|
int
|
|
xfs_trans_roll_inode(
|
|
struct xfs_trans **tpp,
|
|
struct xfs_inode *ip)
|
|
{
|
|
int error;
|
|
|
|
xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
|
|
error = xfs_trans_roll(tpp);
|
|
if (!error)
|
|
xfs_trans_ijoin(*tpp, ip, 0);
|
|
return error;
|
|
}
|