summaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 22:03:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 22:03:48 -0500
commitefd52b5d363e3e3b6224ad39949219c0df117c91 (patch)
tree2d885d2f431a324af58d8f267755240bff3e32da /fs/nfs/inode.c
parent1ed2d76e0213751c82e3a242b61b0883daf330df (diff)
parente231c6879cfd44e4fffd384bb6dd7d313249a523 (diff)
Merge tag 'nfs-for-4.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: Stable bugfixes: - Fix breakages in the nfsstat utility due to the inclusion of the NFSv4 LOOKUPP operation - Fix a NULL pointer dereference in nfs_idmap_prepare_pipe_upcall() due to nfs_idmap_legacy_upcall() being called without an 'aux' parameter - Fix a refcount leak in the standard O_DIRECT error path - Fix a refcount leak in the pNFS O_DIRECT fallback to MDS path - Fix CPU latency issues with nfs_commit_release_pages() - Fix the LAYOUTUNAVAILABLE error case in the file layout type - NFS: Fix a race between mmap() and O_DIRECT Features: - Support the statx() mask and query flags to enable optimisations when the user is requesting only attributes that are already up to date in the inode cache, or is specifying the AT_STATX_DONT_SYNC flag - Add a module alias for the SCSI pNFS layout type Bugfixes: - Automounting when resolving a NFSv4 referral should preserve the RDMA transport protocol settings - Various other RDMA bugfixes from Chuck - pNFS block layout fixes - Always set NFS_LOCK_LOST when a lock is lost" * tag 'nfs-for-4.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (69 commits) NFS: Fix a race between mmap() and O_DIRECT NFS: Remove a redundant call to unmap_mapping_range() pnfs/blocklayout: Ensure disk address in block device map pnfs/blocklayout: pnfs_block_dev_map uses bytes, not sectors lockd: Fix server refcounting SUNRPC: Fix null rpc_clnt dereference in rpc_task_queued tracepoint SUNRPC: Micro-optimize __rpc_execute SUNRPC: task_run_action should display tk_callback sunrpc: Format RPC events consistently for display SUNRPC: Trace xprt_timer events xprtrdma: Correct some documenting comments xprtrdma: Fix "bytes registered" accounting xprtrdma: Instrument allocation/release of rpcrdma_req/rep objects xprtrdma: Add trace points to instrument QP and CQ access upcalls xprtrdma: Add trace points in the client-side backchannel code paths xprtrdma: Add trace points for connect events xprtrdma: Add trace points to instrument MR allocation and recovery xprtrdma: Add trace points to instrument memory invalidation xprtrdma: Add trace points in reply decoder path xprtrdma: Add trace points to instrument memory registration ..
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 93552c482992..ceeaf0fb6657 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -735,12 +735,20 @@ int nfs_getattr(const struct path *path, struct kstat *stat,
735 u32 request_mask, unsigned int query_flags) 735 u32 request_mask, unsigned int query_flags)
736{ 736{
737 struct inode *inode = d_inode(path->dentry); 737 struct inode *inode = d_inode(path->dentry);
738 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; 738 struct nfs_server *server = NFS_SERVER(inode);
739 unsigned long cache_validity;
739 int err = 0; 740 int err = 0;
741 bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
742 bool do_update = false;
740 743
741 trace_nfs_getattr_enter(inode); 744 trace_nfs_getattr_enter(inode);
745
746 if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync)
747 goto out_no_update;
748
742 /* Flush out writes to the server in order to update c/mtime. */ 749 /* Flush out writes to the server in order to update c/mtime. */
743 if (S_ISREG(inode->i_mode)) { 750 if ((request_mask & (STATX_CTIME|STATX_MTIME)) &&
751 S_ISREG(inode->i_mode)) {
744 err = filemap_write_and_wait(inode->i_mapping); 752 err = filemap_write_and_wait(inode->i_mapping);
745 if (err) 753 if (err)
746 goto out; 754 goto out;
@@ -757,24 +765,42 @@ int nfs_getattr(const struct path *path, struct kstat *stat,
757 */ 765 */
758 if ((path->mnt->mnt_flags & MNT_NOATIME) || 766 if ((path->mnt->mnt_flags & MNT_NOATIME) ||
759 ((path->mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) 767 ((path->mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
760 need_atime = 0; 768 request_mask &= ~STATX_ATIME;
761 769
762 if (need_atime || nfs_need_revalidate_inode(inode)) { 770 /* Is the user requesting attributes that might need revalidation? */
763 struct nfs_server *server = NFS_SERVER(inode); 771 if (!(request_mask & (STATX_MODE|STATX_NLINK|STATX_ATIME|STATX_CTIME|
764 772 STATX_MTIME|STATX_UID|STATX_GID|
773 STATX_SIZE|STATX_BLOCKS)))
774 goto out_no_revalidate;
775
776 /* Check whether the cached attributes are stale */
777 do_update |= force_sync || nfs_attribute_cache_expired(inode);
778 cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
779 do_update |= cache_validity &
780 (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL);
781 if (request_mask & STATX_ATIME)
782 do_update |= cache_validity & NFS_INO_INVALID_ATIME;
783 if (request_mask & (STATX_CTIME|STATX_MTIME))
784 do_update |= cache_validity & NFS_INO_REVAL_PAGECACHE;
785 if (do_update) {
786 /* Update the attribute cache */
765 if (!(server->flags & NFS_MOUNT_NOAC)) 787 if (!(server->flags & NFS_MOUNT_NOAC))
766 nfs_readdirplus_parent_cache_miss(path->dentry); 788 nfs_readdirplus_parent_cache_miss(path->dentry);
767 else 789 else
768 nfs_readdirplus_parent_cache_hit(path->dentry); 790 nfs_readdirplus_parent_cache_hit(path->dentry);
769 err = __nfs_revalidate_inode(server, inode); 791 err = __nfs_revalidate_inode(server, inode);
792 if (err)
793 goto out;
770 } else 794 } else
771 nfs_readdirplus_parent_cache_hit(path->dentry); 795 nfs_readdirplus_parent_cache_hit(path->dentry);
772 if (!err) { 796out_no_revalidate:
773 generic_fillattr(inode, stat); 797 /* Only return attributes that were revalidated. */
774 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); 798 stat->result_mask &= request_mask;
775 if (S_ISDIR(inode->i_mode)) 799out_no_update:
776 stat->blksize = NFS_SERVER(inode)->dtsize; 800 generic_fillattr(inode, stat);
777 } 801 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
802 if (S_ISDIR(inode->i_mode))
803 stat->blksize = NFS_SERVER(inode)->dtsize;
778out: 804out:
779 trace_nfs_getattr_exit(inode, err); 805 trace_nfs_getattr_exit(inode, err);
780 return err; 806 return err;
@@ -1144,7 +1170,6 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
1144 1170
1145 if (mapping->nrpages != 0) { 1171 if (mapping->nrpages != 0) {
1146 if (S_ISREG(inode->i_mode)) { 1172 if (S_ISREG(inode->i_mode)) {
1147 unmap_mapping_range(mapping, 0, 0, 0);
1148 ret = nfs_sync_mapping(mapping); 1173 ret = nfs_sync_mapping(mapping);
1149 if (ret < 0) 1174 if (ret < 0)
1150 return ret; 1175 return ret;