mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: xfs: Ensure we force all busy extents in range to disk xfs: Don't flush stale inodes xfs: fix timestamp handling in xfs_setattr xfs: use DECLARE_EVENT_CLASS
This commit is contained in:
commit
1b4d40a517
@ -251,8 +251,9 @@ xfs_set_mode(struct inode *inode, mode_t mode)
|
||||
if (mode != inode->i_mode) {
|
||||
struct iattr iattr;
|
||||
|
||||
iattr.ia_valid = ATTR_MODE;
|
||||
iattr.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
iattr.ia_mode = mode;
|
||||
iattr.ia_ctime = current_fs_time(inode->i_sb);
|
||||
|
||||
error = -xfs_setattr(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2563,43 +2563,41 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
|
||||
xfs_mount_t *mp;
|
||||
xfs_perag_busy_t *bsy;
|
||||
xfs_agblock_t uend, bend;
|
||||
xfs_lsn_t lsn;
|
||||
xfs_lsn_t lsn = 0;
|
||||
int cnt;
|
||||
|
||||
mp = tp->t_mountp;
|
||||
|
||||
spin_lock(&mp->m_perag[agno].pagb_lock);
|
||||
cnt = mp->m_perag[agno].pagb_count;
|
||||
|
||||
uend = bno + len - 1;
|
||||
|
||||
/* search pagb_list for this slot, skipping open slots */
|
||||
for (bsy = mp->m_perag[agno].pagb_list; cnt; bsy++) {
|
||||
/*
|
||||
* search pagb_list for this slot, skipping open slots. We have to
|
||||
* search the entire array as there may be multiple overlaps and
|
||||
* we have to get the most recent LSN for the log force to push out
|
||||
* all the transactions that span the range.
|
||||
*/
|
||||
for (cnt = 0; cnt < mp->m_perag[agno].pagb_count; cnt++) {
|
||||
bsy = &mp->m_perag[agno].pagb_list[cnt];
|
||||
if (!bsy->busy_tp)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* (start1,length1) within (start2, length2)
|
||||
*/
|
||||
if (bsy->busy_tp != NULL) {
|
||||
bend = bsy->busy_start + bsy->busy_length - 1;
|
||||
if ((bno > bend) || (uend < bsy->busy_start)) {
|
||||
cnt--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bend = bsy->busy_start + bsy->busy_length - 1;
|
||||
if (bno > bend || uend < bsy->busy_start)
|
||||
continue;
|
||||
|
||||
/* (start1,length1) within (start2, length2) */
|
||||
if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0)
|
||||
lsn = bsy->busy_tp->t_commit_lsn;
|
||||
}
|
||||
|
||||
trace_xfs_alloc_busysearch(mp, agno, bno, len, !!cnt);
|
||||
spin_unlock(&mp->m_perag[agno].pagb_lock);
|
||||
trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn);
|
||||
|
||||
/*
|
||||
* If a block was found, force the log through the LSN of the
|
||||
* transaction that freed the block
|
||||
*/
|
||||
if (cnt) {
|
||||
lsn = bsy->busy_tp->t_commit_lsn;
|
||||
spin_unlock(&mp->m_perag[agno].pagb_lock);
|
||||
if (lsn)
|
||||
xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC);
|
||||
} else {
|
||||
spin_unlock(&mp->m_perag[agno].pagb_lock);
|
||||
}
|
||||
}
|
||||
|
@ -2841,10 +2841,14 @@ xfs_iflush(
|
||||
mp = ip->i_mount;
|
||||
|
||||
/*
|
||||
* If the inode isn't dirty, then just release the inode
|
||||
* flush lock and do nothing.
|
||||
* If the inode isn't dirty, then just release the inode flush lock and
|
||||
* do nothing. Treat stale inodes the same; we cannot rely on the
|
||||
* backing buffer remaining stale in cache for the remaining life of
|
||||
* the stale inode and so xfs_itobp() below may give us a buffer that
|
||||
* no longer contains inodes below. Doing this stale check here also
|
||||
* avoids forcing the log on pinned, stale inodes.
|
||||
*/
|
||||
if (xfs_inode_clean(ip)) {
|
||||
if (xfs_inode_clean(ip) || xfs_iflags_test(ip, XFS_ISTALE)) {
|
||||
xfs_ifunlock(ip);
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ xfs_setattr(
|
||||
uint commit_flags=0;
|
||||
uid_t uid=0, iuid=0;
|
||||
gid_t gid=0, igid=0;
|
||||
int timeflags = 0;
|
||||
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
|
||||
int need_iolock = 1;
|
||||
|
||||
@ -135,16 +134,13 @@ xfs_setattr(
|
||||
if (flags & XFS_ATTR_NOLOCK)
|
||||
need_iolock = 0;
|
||||
if (!(mask & ATTR_SIZE)) {
|
||||
if ((mask != (ATTR_CTIME|ATTR_ATIME|ATTR_MTIME)) ||
|
||||
(mp->m_flags & XFS_MOUNT_WSYNC)) {
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
|
||||
commit_flags = 0;
|
||||
if ((code = xfs_trans_reserve(tp, 0,
|
||||
XFS_ICHANGE_LOG_RES(mp), 0,
|
||||
0, 0))) {
|
||||
lock_flags = 0;
|
||||
goto error_return;
|
||||
}
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
|
||||
commit_flags = 0;
|
||||
code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp),
|
||||
0, 0, 0);
|
||||
if (code) {
|
||||
lock_flags = 0;
|
||||
goto error_return;
|
||||
}
|
||||
} else {
|
||||
if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
|
||||
@ -295,15 +291,23 @@ xfs_setattr(
|
||||
* or we are explicitly asked to change it. This handles
|
||||
* the semantic difference between truncate() and ftruncate()
|
||||
* as implemented in the VFS.
|
||||
*
|
||||
* The regular truncate() case without ATTR_CTIME and ATTR_MTIME
|
||||
* is a special case where we need to update the times despite
|
||||
* not having these flags set. For all other operations the
|
||||
* VFS set these flags explicitly if it wants a timestamp
|
||||
* update.
|
||||
*/
|
||||
if (iattr->ia_size != ip->i_size || (mask & ATTR_CTIME))
|
||||
timeflags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
|
||||
if (iattr->ia_size != ip->i_size &&
|
||||
(!(mask & (ATTR_CTIME | ATTR_MTIME)))) {
|
||||
iattr->ia_ctime = iattr->ia_mtime =
|
||||
current_fs_time(inode->i_sb);
|
||||
mask |= ATTR_CTIME | ATTR_MTIME;
|
||||
}
|
||||
|
||||
if (iattr->ia_size > ip->i_size) {
|
||||
ip->i_d.di_size = iattr->ia_size;
|
||||
ip->i_size = iattr->ia_size;
|
||||
if (!(flags & XFS_ATTR_DMI))
|
||||
xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
} else if (iattr->ia_size <= ip->i_size ||
|
||||
(iattr->ia_size == 0 && ip->i_d.di_nextents)) {
|
||||
@ -374,9 +378,6 @@ xfs_setattr(
|
||||
ip->i_d.di_gid = gid;
|
||||
inode->i_gid = gid;
|
||||
}
|
||||
|
||||
xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
|
||||
timeflags |= XFS_ICHGTIME_CHG;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -393,51 +394,37 @@ xfs_setattr(
|
||||
|
||||
inode->i_mode &= S_IFMT;
|
||||
inode->i_mode |= mode & ~S_IFMT;
|
||||
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
timeflags |= XFS_ICHGTIME_CHG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change file access or modified times.
|
||||
*/
|
||||
if (mask & (ATTR_ATIME|ATTR_MTIME)) {
|
||||
if (mask & ATTR_ATIME) {
|
||||
inode->i_atime = iattr->ia_atime;
|
||||
ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
|
||||
ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
|
||||
ip->i_update_core = 1;
|
||||
}
|
||||
if (mask & ATTR_MTIME) {
|
||||
inode->i_mtime = iattr->ia_mtime;
|
||||
ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
|
||||
timeflags &= ~XFS_ICHGTIME_MOD;
|
||||
timeflags |= XFS_ICHGTIME_CHG;
|
||||
}
|
||||
if (tp && (mask & (ATTR_MTIME_SET|ATTR_ATIME_SET)))
|
||||
xfs_trans_log_inode (tp, ip, XFS_ILOG_CORE);
|
||||
if (mask & ATTR_ATIME) {
|
||||
inode->i_atime = iattr->ia_atime;
|
||||
ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
|
||||
ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
|
||||
ip->i_update_core = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change file inode change time only if ATTR_CTIME set
|
||||
* AND we have been called by a DMI function.
|
||||
*/
|
||||
|
||||
if ((flags & XFS_ATTR_DMI) && (mask & ATTR_CTIME)) {
|
||||
if (mask & ATTR_CTIME) {
|
||||
inode->i_ctime = iattr->ia_ctime;
|
||||
ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
|
||||
ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
|
||||
ip->i_update_core = 1;
|
||||
timeflags &= ~XFS_ICHGTIME_CHG;
|
||||
}
|
||||
if (mask & ATTR_MTIME) {
|
||||
inode->i_mtime = iattr->ia_mtime;
|
||||
ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
|
||||
ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
|
||||
ip->i_update_core = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send out timestamp changes that need to be set to the
|
||||
* current time. Not done when called by a DMI function.
|
||||
* And finally, log the inode core if any attribute in it
|
||||
* has been changed.
|
||||
*/
|
||||
if (timeflags && !(flags & XFS_ATTR_DMI))
|
||||
xfs_ichgtime(ip, timeflags);
|
||||
if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE|
|
||||
ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
|
||||
XFS_STATS_INC(xs_ig_attrchg);
|
||||
|
||||
@ -452,12 +439,10 @@ xfs_setattr(
|
||||
* mix so this probably isn't worth the trouble to optimize.
|
||||
*/
|
||||
code = 0;
|
||||
if (tp) {
|
||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||
xfs_trans_set_sync(tp);
|
||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||
xfs_trans_set_sync(tp);
|
||||
|
||||
code = xfs_trans_commit(tp, commit_flags);
|
||||
}
|
||||
code = xfs_trans_commit(tp, commit_flags);
|
||||
|
||||
xfs_iunlock(ip, lock_flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user