forked from Minki/linux
9aa05000f2
We don't do any data writeback from XFS any more - the VFS is completely responsible for that, including for freeze. We can replace the remaining caller with a VFS level function that achieves the same thing, but without conflicting with current writeback work. This means we can remove the flush_work and xfs_flush_inodes() - the VFS functionality completely replaces the internal flush queue for doing this writeback work in a separate context to avoid stack overruns. This does have one complication - it cannot be called with page locks held. Hence move the flushing of delalloc space when ENOSPC occurs back up into xfs_file_aio_buffered_write when we don't hold any locks that will stall writeback. Unfortunately, writeback_inodes_sb_if_idle() is not sufficient to trigger delalloc conversion fast enough to prevent spurious ENOSPC whent here are hundreds of writers, thousands of small files and GBs of free RAM. Hence we need to use sync_sb_inodes() to block callers while we wait for writeback like the previous xfs_flush_inodes implementation did. That means we have to hold the s_umount lock here, but because this call can nest inside i_mutex (the parent directory in the create case, held by the VFS), we have to use down_read_trylock() to avoid potential deadlocks. In practice, this trylock will succeed on almost every attempt as unmount/remount type operations are exceedingly rare. Note: we always need to pass a count of zero to generic_file_buffered_write() as the previously written byte count. We only do this by accident before this patch by the virtue of ret always being zero when there are no errors. Make this explicit rather than needing to specifically zero ret in the ENOSPC retry case. Signed-off-by: Dave Chinner <dchinner@redhat.com> Tested-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
89 lines
2.4 KiB
C
89 lines
2.4 KiB
C
/*
|
|
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it would be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#ifndef __XFS_SUPER_H__
|
|
#define __XFS_SUPER_H__
|
|
|
|
#include <linux/exportfs.h>
|
|
|
|
#ifdef CONFIG_XFS_QUOTA
|
|
extern int xfs_qm_init(void);
|
|
extern void xfs_qm_exit(void);
|
|
#else
|
|
# define xfs_qm_init() (0)
|
|
# define xfs_qm_exit() do { } while (0)
|
|
#endif
|
|
|
|
#ifdef CONFIG_XFS_POSIX_ACL
|
|
# define XFS_ACL_STRING "ACLs, "
|
|
# define set_posix_acl_flag(sb) ((sb)->s_flags |= MS_POSIXACL)
|
|
#else
|
|
# define XFS_ACL_STRING
|
|
# define set_posix_acl_flag(sb) do { } while (0)
|
|
#endif
|
|
|
|
#define XFS_SECURITY_STRING "security attributes, "
|
|
|
|
#ifdef CONFIG_XFS_RT
|
|
# define XFS_REALTIME_STRING "realtime, "
|
|
#else
|
|
# define XFS_REALTIME_STRING
|
|
#endif
|
|
|
|
#if XFS_BIG_BLKNOS
|
|
# if XFS_BIG_INUMS
|
|
# define XFS_BIGFS_STRING "large block/inode numbers, "
|
|
# else
|
|
# define XFS_BIGFS_STRING "large block numbers, "
|
|
# endif
|
|
#else
|
|
# define XFS_BIGFS_STRING
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
# define XFS_DBG_STRING "debug"
|
|
#else
|
|
# define XFS_DBG_STRING "no debug"
|
|
#endif
|
|
|
|
#define XFS_VERSION_STRING "SGI XFS"
|
|
#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
|
|
XFS_SECURITY_STRING \
|
|
XFS_REALTIME_STRING \
|
|
XFS_BIGFS_STRING \
|
|
XFS_DBG_STRING /* DBG must be last */
|
|
|
|
struct xfs_inode;
|
|
struct xfs_mount;
|
|
struct xfs_buftarg;
|
|
struct block_device;
|
|
|
|
extern __uint64_t xfs_max_file_offset(unsigned int);
|
|
|
|
extern void xfs_flush_inodes(struct xfs_mount *mp);
|
|
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
|
|
extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
|
|
extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
|
|
|
|
extern const struct export_operations xfs_export_operations;
|
|
extern const struct xattr_handler *xfs_xattr_handlers[];
|
|
extern const struct quotactl_ops xfs_quotactl_operations;
|
|
|
|
#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
|
|
|
|
#endif /* __XFS_SUPER_H__ */
|