Commit dcb779fc authored by Jeff Layton's avatar Jeff Layton Committed by Chuck Lever

nfsd: allow reaping files still under writeback

On most filesystems, there is no reason to delay reaping an nfsd_file
just because its underlying inode is still under writeback. nfsd just
relies on client activity or the local flusher threads to do writeback.

The main exception is NFS, which flushes all of its dirty data on last
close. Add a new EXPORT_OP_FLUSH_ON_CLOSE flag to allow filesystems to
signal that they do this, and only skip closing files under writeback on
such filesystems.

Also, remove a redundant NULL file pointer check in
nfsd_file_check_writeback, and clean up nfs's export op flag
definitions.
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Acked-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 972cc0e0
...@@ -149,7 +149,10 @@ const struct export_operations nfs_export_ops = { ...@@ -149,7 +149,10 @@ const struct export_operations nfs_export_ops = {
.encode_fh = nfs_encode_fh, .encode_fh = nfs_encode_fh,
.fh_to_dentry = nfs_fh_to_dentry, .fh_to_dentry = nfs_fh_to_dentry,
.get_parent = nfs_get_parent, .get_parent = nfs_get_parent,
.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK| .flags = EXPORT_OP_NOWCC |
EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS| EXPORT_OP_NOSUBTREECHK |
EXPORT_OP_NOATOMIC_ATTR, EXPORT_OP_CLOSE_BEFORE_UNLINK |
EXPORT_OP_REMOTE_FS |
EXPORT_OP_NOATOMIC_ATTR |
EXPORT_OP_FLUSH_ON_CLOSE,
}; };
...@@ -402,13 +402,23 @@ nfsd_file_check_writeback(struct nfsd_file *nf) ...@@ -402,13 +402,23 @@ nfsd_file_check_writeback(struct nfsd_file *nf)
struct file *file = nf->nf_file; struct file *file = nf->nf_file;
struct address_space *mapping; struct address_space *mapping;
if (!file || !(file->f_mode & FMODE_WRITE)) /* File not open for write? */
if (!(file->f_mode & FMODE_WRITE))
return false; return false;
/*
* Some filesystems (e.g. NFS) flush all dirty data on close.
* On others, there is no need to wait for writeback.
*/
if (!(file_inode(file)->i_sb->s_export_op->flags & EXPORT_OP_FLUSH_ON_CLOSE))
return false;
mapping = file->f_mapping; mapping = file->f_mapping;
return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) || return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) ||
mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK); mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK);
} }
static bool nfsd_file_lru_add(struct nfsd_file *nf) static bool nfsd_file_lru_add(struct nfsd_file *nf)
{ {
set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
......
...@@ -220,6 +220,7 @@ struct export_operations { ...@@ -220,6 +220,7 @@ struct export_operations {
#define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply
atomic attribute updates atomic attribute updates
*/ */
#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
unsigned long flags; unsigned long flags;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment