Merge tag 'nfs-for-4.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: Stable fixes: - Fix a regression in the SunRPC socket polling code - Fix the attribute cache revalidation code - Fix race in __update_open_stateid() - Fix an lo->plh_block_lgets imbalance in layoutreturn - Fix an Oopsable typo in ff_mirror_match_fh() Features: - pNFS layout recall performance improvements. - pNFS/flexfiles: Support server-supplied layoutstats sampling period Bugfixes + cleanups: - NFSv4: Don't perform cached access checks before we've OPENed the file - Fix starvation issues with background flushes - Reclaim writes should be flushed as unstable writes if there are already entries in the commit lists - Various bugfixes from Chuck to fix NFS/RDMA send queue ordering problems - Ensure that we propagate fatal layoutget errors back to the application - Fixes for sundry flexfiles layoutstats bugs - Fix files/flexfiles to not cache invalidated layouts in the DS commit buckets" * tag 'nfs-for-4.5-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (68 commits) NFS: Fix a compile warning about unused variable in nfs_generic_pg_pgios() NFSv4: Fix a compile warning about no prototype for nfs4_ioctl() NFS: Use wait_on_atomic_t() for unlock after readahead SUNRPC: Fixup socket wait for memory NFSv4.1/pNFS: Cleanup constify struct pnfs_layout_range arguments NFSv4.1/pnfs: Cleanup copying of pnfs_layout_range structures NFSv4.1/pNFS: Cleanup pnfs_mark_matching_lsegs_invalid() NFSv4.1/pNFS: Fix a race in initiate_file_draining() NFSv4.1/pNFS: pnfs_error_mark_layout_for_return() must always return layout NFSv4.1/pNFS: pnfs_mark_matching_lsegs_return() should set the iomode NFSv4.1/pNFS: Use nfs4_stateid_copy for copying stateids NFSv4.1/pNFS: Don't pass stateids by value to pnfs_send_layoutreturn() NFS: Relax requirements in nfs_flush_incompatible NFSv4.1/pNFS: Don't queue up a new commit if the layout segment is invalid NFS: Allow multiple commit requests in flight per file NFS/pNFS: Fix up pNFS write reschedule layering violations and bugs SUNRPC: Fix a missing break in rpc_anyaddr() pNFS/flexfiles: Fix an Oopsable typo in ff_mirror_match_fh() NFS: Fix attribute cache revalidation NFS: Ensure we revalidate attributes before using execute_ok() ...
This commit is contained in:
@@ -71,19 +71,25 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
|
||||
return nfs_fileid_to_ino_t(fattr->fileid);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_wait_bit_killable - helper for functions that are sleeping on bit locks
|
||||
* @word: long word containing the bit lock
|
||||
*/
|
||||
int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
|
||||
static int nfs_wait_killable(int mode)
|
||||
{
|
||||
freezable_schedule_unsafe();
|
||||
if (signal_pending_state(mode, current))
|
||||
return -ERESTARTSYS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
|
||||
{
|
||||
return nfs_wait_killable(mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
|
||||
|
||||
int nfs_wait_atomic_killable(atomic_t *p)
|
||||
{
|
||||
return nfs_wait_killable(TASK_KILLABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_compat_user_ino64 - returns the user-visible inode number
|
||||
* @fileid: 64-bit fileid
|
||||
@@ -700,7 +706,7 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
|
||||
l_ctx->lockowner.l_owner = current->files;
|
||||
l_ctx->lockowner.l_pid = current->tgid;
|
||||
INIT_LIST_HEAD(&l_ctx->list);
|
||||
nfs_iocounter_init(&l_ctx->io_count);
|
||||
atomic_set(&l_ctx->io_count, 0);
|
||||
}
|
||||
|
||||
static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
|
||||
@@ -913,6 +919,12 @@ void nfs_file_clear_open_context(struct file *filp)
|
||||
if (ctx) {
|
||||
struct inode *inode = d_inode(ctx->dentry);
|
||||
|
||||
/*
|
||||
* We fatal error on write before. Try to writeback
|
||||
* every page again.
|
||||
*/
|
||||
if (ctx->error < 0)
|
||||
invalidate_inode_pages2(inode->i_mapping);
|
||||
filp->private_data = NULL;
|
||||
spin_lock(&inode->i_lock);
|
||||
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
|
||||
@@ -1663,6 +1675,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
unsigned long invalid = 0;
|
||||
unsigned long now = jiffies;
|
||||
unsigned long save_cache_validity;
|
||||
bool cache_revalidated = true;
|
||||
|
||||
dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
|
||||
__func__, inode->i_sb->s_id, inode->i_ino,
|
||||
@@ -1724,22 +1737,28 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
nfs_force_lookup_revalidate(inode);
|
||||
inode->i_version = fattr->change_attr;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
nfsi->cache_validity |= save_cache_validity;
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
|
||||
memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
|
||||
} else if (server->caps & NFS_CAP_MTIME)
|
||||
} else if (server->caps & NFS_CAP_MTIME) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
|
||||
memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
|
||||
} else if (server->caps & NFS_CAP_CTIME)
|
||||
} else if (server->caps & NFS_CAP_CTIME) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
/* Check if our cached file size is stale */
|
||||
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
||||
@@ -1759,19 +1778,23 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
(long long)cur_isize,
|
||||
(long long)new_isize);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_REVAL_PAGECACHE
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_ATIME)
|
||||
memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
|
||||
else if (server->caps & NFS_CAP_ATIME)
|
||||
else if (server->caps & NFS_CAP_ATIME) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATIME
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_MODE) {
|
||||
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
|
||||
@@ -1780,36 +1803,42 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
inode->i_mode = newmode;
|
||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||
}
|
||||
} else if (server->caps & NFS_CAP_MODE)
|
||||
} else if (server->caps & NFS_CAP_MODE) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_INVALID_ACCESS
|
||||
| NFS_INO_INVALID_ACL
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
|
||||
if (!uid_eq(inode->i_uid, fattr->uid)) {
|
||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||
inode->i_uid = fattr->uid;
|
||||
}
|
||||
} else if (server->caps & NFS_CAP_OWNER)
|
||||
} else if (server->caps & NFS_CAP_OWNER) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_INVALID_ACCESS
|
||||
| NFS_INO_INVALID_ACL
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
|
||||
if (!gid_eq(inode->i_gid, fattr->gid)) {
|
||||
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||
inode->i_gid = fattr->gid;
|
||||
}
|
||||
} else if (server->caps & NFS_CAP_OWNER_GROUP)
|
||||
} else if (server->caps & NFS_CAP_OWNER_GROUP) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_INVALID_ACCESS
|
||||
| NFS_INO_INVALID_ACL
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
|
||||
if (inode->i_nlink != fattr->nlink) {
|
||||
@@ -1818,19 +1847,22 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
invalid |= NFS_INO_INVALID_DATA;
|
||||
set_nlink(inode, fattr->nlink);
|
||||
}
|
||||
} else if (server->caps & NFS_CAP_NLINK)
|
||||
} else if (server->caps & NFS_CAP_NLINK) {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
|
||||
/*
|
||||
* report the blocks in 512byte units
|
||||
*/
|
||||
inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
|
||||
}
|
||||
if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
|
||||
} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
|
||||
inode->i_blocks = fattr->du.nfs2.blocks;
|
||||
else
|
||||
cache_revalidated = false;
|
||||
|
||||
/* Update attrtimeo value if we're out of the unstable period */
|
||||
if (invalid & NFS_INO_INVALID_ATTR) {
|
||||
@@ -1840,9 +1872,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
/* Set barrier to be more recent than all outstanding updates */
|
||||
nfsi->attr_gencount = nfs_inc_attr_generation_counter();
|
||||
} else {
|
||||
if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
|
||||
if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
|
||||
nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
|
||||
if (cache_revalidated) {
|
||||
if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
|
||||
nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
|
||||
nfsi->attrtimeo <<= 1;
|
||||
if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
|
||||
nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
|
||||
}
|
||||
nfsi->attrtimeo_timestamp = now;
|
||||
}
|
||||
/* Set the barrier to be more recent than this fattr */
|
||||
@@ -1851,7 +1887,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
}
|
||||
|
||||
/* Don't declare attrcache up to date if there were no attrs! */
|
||||
if (fattr->valid != 0)
|
||||
if (cache_revalidated)
|
||||
invalid &= ~NFS_INO_INVALID_ATTR;
|
||||
|
||||
/* Don't invalidate the data if we were to blame */
|
||||
|
Reference in New Issue
Block a user