Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b4d40a5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 79ecb043 fd45e478
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
	}
+597 −544

File changed.

Preview size limit exceeded, changes collapsed.

+21 −23
Original line number Diff line number Diff line
@@ -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++) {

	/*
		 * (start1,length1) within (start2, length2)
	 * 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.
	 */
		if (bsy->busy_tp != NULL) {
	for (cnt = 0; cnt < mp->m_perag[agno].pagb_count; cnt++) {
		bsy = &mp->m_perag[agno].pagb_list[cnt];
		if (!bsy->busy_tp)
			continue;

		bend = bsy->busy_start + bsy->busy_length - 1;
			if ((bno > bend) || (uend < bsy->busy_start)) {
				cnt--;
			} else {
				break;
			}
		}
	}
		if (bno > bend || uend < bsy->busy_start)
			continue;

	trace_xfs_alloc_busysearch(mp, agno, bno, len, !!cnt);
		/* (start1,length1) within (start2, length2) */
		if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0)
			lsn = bsy->busy_tp->t_commit_lsn;
	}
	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);
	}
}
+7 −3
Original line number Diff line number Diff line
@@ -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 (xfs_inode_clean(ip)) {
	 * 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) || xfs_iflags_test(ip, XFS_ISTALE)) {
		xfs_ifunlock(ip);
		return 0;
	}
+39 −54
Original line number Diff line number Diff line
@@ -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,17 +134,14 @@ 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))) {
		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) &&
		    !(flags & XFS_ATTR_DMI)) {
@@ -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_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;
	}
	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);
	}

	/*
	 * 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)) {
		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;
	}

	/*
	 * 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);

	code = xfs_trans_commit(tp, commit_flags);
	}

	xfs_iunlock(ip, lock_flags);