Network Working Group                                         S. Shepler
Request for Comments: 3010                                  B. Callaghan
Obsoletes: 1813, 1094                                        D. Robinson
Category: Standards Track                                     R. Thurlow
                                                   Sun Microsystems Inc.
                                                                C. Beame
                                                        Hummingbird Ltd.
                                                               M. Eisler
                                                           Zambeel, Inc.
                                                               D. Noveck
                                                 Network Appliance, Inc.
                                                           December 2000
        
Network Working Group                                         S. Shepler
Request for Comments: 3010                                  B. Callaghan
Obsoletes: 1813, 1094                                        D. Robinson
Category: Standards Track                                     R. Thurlow
                                                   Sun Microsystems Inc.
                                                                C. Beame
                                                        Hummingbird Ltd.
                                                               M. Eisler
                                                           Zambeel, Inc.
                                                               D. Noveck
                                                 Network Appliance, Inc.
                                                           December 2000
        

NFS version 4 Protocol

NFS版本4协议

Status of this Memo

本备忘录的状况

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

本文件规定了互联网社区的互联网标准跟踪协议,并要求进行讨论和提出改进建议。有关本协议的标准化状态和状态,请参考当前版本的“互联网官方协议标准”(STD 1)。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

Abstract

摘要

NFS (Network File System) version 4 is a distributed file system protocol which owes heritage to NFS protocol versions 2 [RFC1094] and 3 [RFC1813]. Unlike earlier versions, the NFS version 4 protocol supports traditional file access while integrating support for file locking and the mount protocol. In addition, support for strong security (and its negotiation), compound operations, client caching, and internationalization have been added. Of course, attention has been applied to making NFS version 4 operate well in an Internet environment.

NFS(网络文件系统)版本4是一种分布式文件系统协议,其继承了NFS协议版本2[RFC1094]和3[RFC1813]的传统。与早期版本不同,NFS版本4协议支持传统的文件访问,同时集成了对文件锁定和装载协议的支持。此外,还添加了对强安全性(及其协商)、复合操作、客户端缓存和国际化的支持。当然,人们已经注意到使NFS版本4在Internet环境中运行良好。

Key Words

关键词

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

本文件中的关键词“必须”、“不得”、“要求”、“应”、“不得”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC 2119中的说明进行解释。

Table of Contents

目录

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . .   5
   1.1.  Overview of NFS Version 4 Features . . . . . . . . . . . .   6
   1.1.1.  RPC and Security . . . . . . . . . . . . . . . . . . . .   6
   1.1.2.  Procedure and Operation Structure  . . . . . . . . . . .   7
   1.1.3.  File System Model  . . . . . . . . . . . . . . . . . . .   8
   1.1.3.1.  Filehandle Types . . . . . . . . . . . . . . . . . . .   8
   1.1.3.2.  Attribute Types  . . . . . . . . . . . . . . . . . . .   8
   1.1.3.3.  File System Replication and Migration  . . . . . . . .   9
   1.1.4.  OPEN and CLOSE . . . . . . . . . . . . . . . . . . . . .   9
   1.1.5.  File locking . . . . . . . . . . . . . . . . . . . . . .   9
   1.1.6.  Client Caching and Delegation  . . . . . . . . . . . . .  10
   1.2.  General Definitions  . . . . . . . . . . . . . . . . . . .  11
   2.  Protocol Data Types  . . . . . . . . . . . . . . . . . . . .  12
   2.1.  Basic Data Types . . . . . . . . . . . . . . . . . . . . .  12
   2.2.  Structured Data Types  . . . . . . . . . . . . . . . . . .  14
   3.  RPC and Security Flavor  . . . . . . . . . . . . . . . . . .  18
   3.1.  Ports and Transports . . . . . . . . . . . . . . . . . . .  18
   3.2.  Security Flavors . . . . . . . . . . . . . . . . . . . . .  18
   3.2.1.  Security mechanisms for NFS version 4  . . . . . . . . .  19
   3.2.1.1.  Kerberos V5 as security triple . . . . . . . . . . . .  19
   3.2.1.2.  LIPKEY as a security triple  . . . . . . . . . . . . .  19
   3.2.1.3.  SPKM-3 as a security triple  . . . . . . . . . . . . .  20
   3.3.  Security Negotiation . . . . . . . . . . . . . . . . . . .  21
   3.3.1.  Security Error . . . . . . . . . . . . . . . . . . . . .  21
   3.3.2.  SECINFO  . . . . . . . . . . . . . . . . . . . . . . . .  21
   3.4.  Callback RPC Authentication  . . . . . . . . . . . . . . .  22
   4.  Filehandles  . . . . . . . . . . . . . . . . . . . . . . . .  23
   4.1.  Obtaining the First Filehandle . . . . . . . . . . . . . .  24
   4.1.1.  Root Filehandle  . . . . . . . . . . . . . . . . . . . .  24
   4.1.2.  Public Filehandle  . . . . . . . . . . . . . . . . . . .  24
   4.2.  Filehandle Types . . . . . . . . . . . . . . . . . . . . .  25
   4.2.1.  General Properties of a Filehandle . . . . . . . . . . .  25
   4.2.2.  Persistent Filehandle  . . . . . . . . . . . . . . . . .  26
   4.2.3.  Volatile Filehandle  . . . . . . . . . . . . . . . . . .  26
   4.2.4.  One Method of Constructing a Volatile Filehandle . . . .  28
   4.3.  Client Recovery from Filehandle Expiration . . . . . . . .  28
   5.  File Attributes  . . . . . . . . . . . . . . . . . . . . . .  29
   5.1.  Mandatory Attributes . . . . . . . . . . . . . . . . . . .  30
   5.2.  Recommended Attributes . . . . . . . . . . . . . . . . . .  30
   5.3.  Named Attributes . . . . . . . . . . . . . . . . . . . . .  31
   5.4.  Mandatory Attributes - Definitions . . . . . . . . . . . .  31
   5.5.  Recommended Attributes - Definitions . . . . . . . . . . .  33
   5.6.  Interpreting owner and owner_group . . . . . . . . . . . .  38
   5.7.  Character Case Attributes  . . . . . . . . . . . . . . . .  39
   5.8.  Quota Attributes . . . . . . . . . . . . . . . . . . . . .  39
   5.9.  Access Control Lists . . . . . . . . . . . . . . . . . . .  40
        
   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . .   5
   1.1.  Overview of NFS Version 4 Features . . . . . . . . . . . .   6
   1.1.1.  RPC and Security . . . . . . . . . . . . . . . . . . . .   6
   1.1.2.  Procedure and Operation Structure  . . . . . . . . . . .   7
   1.1.3.  File System Model  . . . . . . . . . . . . . . . . . . .   8
   1.1.3.1.  Filehandle Types . . . . . . . . . . . . . . . . . . .   8
   1.1.3.2.  Attribute Types  . . . . . . . . . . . . . . . . . . .   8
   1.1.3.3.  File System Replication and Migration  . . . . . . . .   9
   1.1.4.  OPEN and CLOSE . . . . . . . . . . . . . . . . . . . . .   9
   1.1.5.  File locking . . . . . . . . . . . . . . . . . . . . . .   9
   1.1.6.  Client Caching and Delegation  . . . . . . . . . . . . .  10
   1.2.  General Definitions  . . . . . . . . . . . . . . . . . . .  11
   2.  Protocol Data Types  . . . . . . . . . . . . . . . . . . . .  12
   2.1.  Basic Data Types . . . . . . . . . . . . . . . . . . . . .  12
   2.2.  Structured Data Types  . . . . . . . . . . . . . . . . . .  14
   3.  RPC and Security Flavor  . . . . . . . . . . . . . . . . . .  18
   3.1.  Ports and Transports . . . . . . . . . . . . . . . . . . .  18
   3.2.  Security Flavors . . . . . . . . . . . . . . . . . . . . .  18
   3.2.1.  Security mechanisms for NFS version 4  . . . . . . . . .  19
   3.2.1.1.  Kerberos V5 as security triple . . . . . . . . . . . .  19
   3.2.1.2.  LIPKEY as a security triple  . . . . . . . . . . . . .  19
   3.2.1.3.  SPKM-3 as a security triple  . . . . . . . . . . . . .  20
   3.3.  Security Negotiation . . . . . . . . . . . . . . . . . . .  21
   3.3.1.  Security Error . . . . . . . . . . . . . . . . . . . . .  21
   3.3.2.  SECINFO  . . . . . . . . . . . . . . . . . . . . . . . .  21
   3.4.  Callback RPC Authentication  . . . . . . . . . . . . . . .  22
   4.  Filehandles  . . . . . . . . . . . . . . . . . . . . . . . .  23
   4.1.  Obtaining the First Filehandle . . . . . . . . . . . . . .  24
   4.1.1.  Root Filehandle  . . . . . . . . . . . . . . . . . . . .  24
   4.1.2.  Public Filehandle  . . . . . . . . . . . . . . . . . . .  24
   4.2.  Filehandle Types . . . . . . . . . . . . . . . . . . . . .  25
   4.2.1.  General Properties of a Filehandle . . . . . . . . . . .  25
   4.2.2.  Persistent Filehandle  . . . . . . . . . . . . . . . . .  26
   4.2.3.  Volatile Filehandle  . . . . . . . . . . . . . . . . . .  26
   4.2.4.  One Method of Constructing a Volatile Filehandle . . . .  28
   4.3.  Client Recovery from Filehandle Expiration . . . . . . . .  28
   5.  File Attributes  . . . . . . . . . . . . . . . . . . . . . .  29
   5.1.  Mandatory Attributes . . . . . . . . . . . . . . . . . . .  30
   5.2.  Recommended Attributes . . . . . . . . . . . . . . . . . .  30
   5.3.  Named Attributes . . . . . . . . . . . . . . . . . . . . .  31
   5.4.  Mandatory Attributes - Definitions . . . . . . . . . . . .  31
   5.5.  Recommended Attributes - Definitions . . . . . . . . . . .  33
   5.6.  Interpreting owner and owner_group . . . . . . . . . . . .  38
   5.7.  Character Case Attributes  . . . . . . . . . . . . . . . .  39
   5.8.  Quota Attributes . . . . . . . . . . . . . . . . . . . . .  39
   5.9.  Access Control Lists . . . . . . . . . . . . . . . . . . .  40
        
   5.9.1.  ACE type . . . . . . . . . . . . . . . . . . . . . . . .  41
   5.9.2.  ACE flag . . . . . . . . . . . . . . . . . . . . . . . .  41
   5.9.3.  ACE Access Mask  . . . . . . . . . . . . . . . . . . . .  43
   5.9.4.  ACE who  . . . . . . . . . . . . . . . . . . . . . . . .  44
   6.  File System Migration and Replication  . . . . . . . . . . .  44
   6.1.  Replication  . . . . . . . . . . . . . . . . . . . . . . .  45
   6.2.  Migration  . . . . . . . . . . . . . . . . . . . . . . . .  45
   6.3.  Interpretation of the fs_locations Attribute . . . . . . .  46
   6.4.  Filehandle Recovery for Migration or Replication . . . . .  47
   7.  NFS Server Name Space  . . . . . . . . . . . . . . . . . . .  47
   7.1.  Server Exports . . . . . . . . . . . . . . . . . . . . . .  47
   7.2.  Browsing Exports . . . . . . . . . . . . . . . . . . . . .  48
   7.3.  Server Pseudo File System  . . . . . . . . . . . . . . . .  48
   7.4.  Multiple Roots . . . . . . . . . . . . . . . . . . . . . .  49
   7.5.  Filehandle Volatility  . . . . . . . . . . . . . . . . . .  49
   7.6.  Exported Root  . . . . . . . . . . . . . . . . . . . . . .  49
   7.7.  Mount Point Crossing . . . . . . . . . . . . . . . . . . .  49
   7.8.  Security Policy and Name Space Presentation  . . . . . . .  50
   8.  File Locking and Share Reservations  . . . . . . . . . . . .  50
   8.1.  Locking  . . . . . . . . . . . . . . . . . . . . . . . . .  51
   8.1.1.  Client ID  . . . . . . . . . . . . . . . . . . . . . . .  51
   8.1.2.  Server Release of Clientid . . . . . . . . . . . . . . .  53
   8.1.3.  nfs_lockowner and stateid Definition . . . . . . . . . .  54
   8.1.4.  Use of the stateid . . . . . . . . . . . . . . . . . . .  55
   8.1.5.  Sequencing of Lock Requests  . . . . . . . . . . . . . .  56
   8.1.6.  Recovery from Replayed Requests  . . . . . . . . . . . .  56
   8.1.7.  Releasing nfs_lockowner State  . . . . . . . . . . . . .  57
   8.2.  Lock Ranges  . . . . . . . . . . . . . . . . . . . . . . .  57
   8.3.  Blocking Locks . . . . . . . . . . . . . . . . . . . . . .  58
   8.4.  Lease Renewal  . . . . . . . . . . . . . . . . . . . . . .  58
   8.5.  Crash Recovery . . . . . . . . . . . . . . . . . . . . . .  59
   8.5.1.  Client Failure and Recovery  . . . . . . . . . . . . . .  59
   8.5.2.  Server Failure and Recovery  . . . . . . . . . . . . . .  60
   8.5.3.  Network Partitions and Recovery  . . . . . . . . . . . .  62
   8.6.  Recovery from a Lock Request Timeout or Abort  . . . . . .  63
   8.7.  Server Revocation of Locks . . . . . . . . . . . . . . . .  63
   8.8.  Share Reservations . . . . . . . . . . . . . . . . . . . .  65
   8.9.  OPEN/CLOSE Operations  . . . . . . . . . . . . . . . . . .  65
   8.10.  Open Upgrade and Downgrade  . . . . . . . . . . . . . . .  66
   8.11.  Short and Long Leases . . . . . . . . . . . . . . . . . .  66
   8.12.  Clocks and Calculating Lease Expiration . . . . . . . . .  67
   8.13.  Migration, Replication and State  . . . . . . . . . . . .  67
   8.13.1.  Migration and State . . . . . . . . . . . . . . . . . .  67
   8.13.2.  Replication and State . . . . . . . . . . . . . . . . .  68
   8.13.3.  Notification of Migrated Lease  . . . . . . . . . . . .  69
   9.  Client-Side Caching  . . . . . . . . . . . . . . . . . . . .  69
   9.1.  Performance Challenges for Client-Side Caching . . . . . .  70
   9.2.  Delegation and Callbacks . . . . . . . . . . . . . . . . .  71
        
   5.9.1.  ACE type . . . . . . . . . . . . . . . . . . . . . . . .  41
   5.9.2.  ACE flag . . . . . . . . . . . . . . . . . . . . . . . .  41
   5.9.3.  ACE Access Mask  . . . . . . . . . . . . . . . . . . . .  43
   5.9.4.  ACE who  . . . . . . . . . . . . . . . . . . . . . . . .  44
   6.  File System Migration and Replication  . . . . . . . . . . .  44
   6.1.  Replication  . . . . . . . . . . . . . . . . . . . . . . .  45
   6.2.  Migration  . . . . . . . . . . . . . . . . . . . . . . . .  45
   6.3.  Interpretation of the fs_locations Attribute . . . . . . .  46
   6.4.  Filehandle Recovery for Migration or Replication . . . . .  47
   7.  NFS Server Name Space  . . . . . . . . . . . . . . . . . . .  47
   7.1.  Server Exports . . . . . . . . . . . . . . . . . . . . . .  47
   7.2.  Browsing Exports . . . . . . . . . . . . . . . . . . . . .  48
   7.3.  Server Pseudo File System  . . . . . . . . . . . . . . . .  48
   7.4.  Multiple Roots . . . . . . . . . . . . . . . . . . . . . .  49
   7.5.  Filehandle Volatility  . . . . . . . . . . . . . . . . . .  49
   7.6.  Exported Root  . . . . . . . . . . . . . . . . . . . . . .  49
   7.7.  Mount Point Crossing . . . . . . . . . . . . . . . . . . .  49
   7.8.  Security Policy and Name Space Presentation  . . . . . . .  50
   8.  File Locking and Share Reservations  . . . . . . . . . . . .  50
   8.1.  Locking  . . . . . . . . . . . . . . . . . . . . . . . . .  51
   8.1.1.  Client ID  . . . . . . . . . . . . . . . . . . . . . . .  51
   8.1.2.  Server Release of Clientid . . . . . . . . . . . . . . .  53
   8.1.3.  nfs_lockowner and stateid Definition . . . . . . . . . .  54
   8.1.4.  Use of the stateid . . . . . . . . . . . . . . . . . . .  55
   8.1.5.  Sequencing of Lock Requests  . . . . . . . . . . . . . .  56
   8.1.6.  Recovery from Replayed Requests  . . . . . . . . . . . .  56
   8.1.7.  Releasing nfs_lockowner State  . . . . . . . . . . . . .  57
   8.2.  Lock Ranges  . . . . . . . . . . . . . . . . . . . . . . .  57
   8.3.  Blocking Locks . . . . . . . . . . . . . . . . . . . . . .  58
   8.4.  Lease Renewal  . . . . . . . . . . . . . . . . . . . . . .  58
   8.5.  Crash Recovery . . . . . . . . . . . . . . . . . . . . . .  59
   8.5.1.  Client Failure and Recovery  . . . . . . . . . . . . . .  59
   8.5.2.  Server Failure and Recovery  . . . . . . . . . . . . . .  60
   8.5.3.  Network Partitions and Recovery  . . . . . . . . . . . .  62
   8.6.  Recovery from a Lock Request Timeout or Abort  . . . . . .  63
   8.7.  Server Revocation of Locks . . . . . . . . . . . . . . . .  63
   8.8.  Share Reservations . . . . . . . . . . . . . . . . . . . .  65
   8.9.  OPEN/CLOSE Operations  . . . . . . . . . . . . . . . . . .  65
   8.10.  Open Upgrade and Downgrade  . . . . . . . . . . . . . . .  66
   8.11.  Short and Long Leases . . . . . . . . . . . . . . . . . .  66
   8.12.  Clocks and Calculating Lease Expiration . . . . . . . . .  67
   8.13.  Migration, Replication and State  . . . . . . . . . . . .  67
   8.13.1.  Migration and State . . . . . . . . . . . . . . . . . .  67
   8.13.2.  Replication and State . . . . . . . . . . . . . . . . .  68
   8.13.3.  Notification of Migrated Lease  . . . . . . . . . . . .  69
   9.  Client-Side Caching  . . . . . . . . . . . . . . . . . . . .  69
   9.1.  Performance Challenges for Client-Side Caching . . . . . .  70
   9.2.  Delegation and Callbacks . . . . . . . . . . . . . . . . .  71
        
   9.2.1.  Delegation Recovery  . . . . . . . . . . . . . . . . . .  72
   9.3.  Data Caching . . . . . . . . . . . . . . . . . . . . . . .  74
   9.3.1.  Data Caching and OPENs . . . . . . . . . . . . . . . . .  74
   9.3.2.  Data Caching and File Locking  . . . . . . . . . . . . .  75
   9.3.3.  Data Caching and Mandatory File Locking  . . . . . . . .  77
   9.3.4.  Data Caching and File Identity . . . . . . . . . . . . .  77
   9.4.  Open Delegation  . . . . . . . . . . . . . . . . . . . . .  78
   9.4.1.  Open Delegation and Data Caching . . . . . . . . . . . .  80
   9.4.2.  Open Delegation and File Locks . . . . . . . . . . . . .  82
   9.4.3.  Recall of Open Delegation  . . . . . . . . . . . . . . .  82
   9.4.4.  Delegation Revocation  . . . . . . . . . . . . . . . . .  84
   9.5.  Data Caching and Revocation  . . . . . . . . . . . . . . .  84
   9.5.1.  Revocation Recovery for Write Open Delegation  . . . . .  85
   9.6.  Attribute Caching  . . . . . . . . . . . . . . . . . . . .  85
   9.7.  Name Caching . . . . . . . . . . . . . . . . . . . . . . .  86
   9.8.  Directory Caching  . . . . . . . . . . . . . . . . . . . .  87
   10.  Minor Versioning  . . . . . . . . . . . . . . . . . . . . .  88
   11.  Internationalization  . . . . . . . . . . . . . . . . . . .  91
   11.1.  Universal Versus Local Character Sets . . . . . . . . . .  91
   11.2.  Overview of Universal Character Set Standards . . . . . .  92
   11.3.  Difficulties with UCS-4, UCS-2, Unicode . . . . . . . . .  93
   11.4.  UTF-8 and its solutions . . . . . . . . . . . . . . . . .  94
   11.5.  Normalization . . . . . . . . . . . . . . . . . . . . . .  94
   12.  Error Definitions . . . . . . . . . . . . . . . . . . . . .  95
   13.  NFS Version 4 Requests  . . . . . . . . . . . . . . . . . .  99
   13.1.  Compound Procedure  . . . . . . . . . . . . . . . . . . . 100
   13.2.  Evaluation of a Compound Request  . . . . . . . . . . . . 100
   13.3.  Synchronous Modifying Operations  . . . . . . . . . . . . 101
   13.4.  Operation Values  . . . . . . . . . . . . . . . . . . . . 102
   14.  NFS Version 4 Procedures  . . . . . . . . . . . . . . . . . 102
   14.1.  Procedure 0: NULL - No Operation  . . . . . . . . . . . . 102
   14.2.  Procedure 1: COMPOUND - Compound Operations . . . . . . . 102
   14.2.1.  Operation 3: ACCESS - Check Access Rights . . . . . . . 105
   14.2.2.  Operation 4: CLOSE - Close File . . . . . . . . . . . . 108
   14.2.3.  Operation 5: COMMIT - Commit Cached Data  . . . . . . . 109
   14.2.4.  Operation 6: CREATE - Create a Non-Regular File Object. 112
   14.2.5.  Operation 7: DELEGPURGE - Purge Delegations Awaiting
            Recovery  . . . . . . . . . . . . . . . . . . . . . . . 114
   14.2.6.  Operation 8: DELEGRETURN - Return Delegation  . . . . . 115
   14.2.7.  Operation 9: GETATTR - Get Attributes . . . . . . . . . 115
   14.2.8.  Operation 10: GETFH - Get Current Filehandle  . . . . . 117
   14.2.9.  Operation 11: LINK - Create Link to a File  . . . . . . 118
   14.2.10.  Operation 12: LOCK - Create Lock . . . . . . . . . . . 119
   14.2.11.  Operation 13: LOCKT - Test For Lock  . . . . . . . . . 121
   14.2.12.  Operation 14: LOCKU - Unlock File  . . . . . . . . . . 122
   14.2.13.  Operation 15: LOOKUP - Lookup Filename . . . . . . . . 123
   14.2.14.  Operation 16: LOOKUPP - Lookup Parent Directory  . . . 126
        
   9.2.1.  Delegation Recovery  . . . . . . . . . . . . . . . . . .  72
   9.3.  Data Caching . . . . . . . . . . . . . . . . . . . . . . .  74
   9.3.1.  Data Caching and OPENs . . . . . . . . . . . . . . . . .  74
   9.3.2.  Data Caching and File Locking  . . . . . . . . . . . . .  75
   9.3.3.  Data Caching and Mandatory File Locking  . . . . . . . .  77
   9.3.4.  Data Caching and File Identity . . . . . . . . . . . . .  77
   9.4.  Open Delegation  . . . . . . . . . . . . . . . . . . . . .  78
   9.4.1.  Open Delegation and Data Caching . . . . . . . . . . . .  80
   9.4.2.  Open Delegation and File Locks . . . . . . . . . . . . .  82
   9.4.3.  Recall of Open Delegation  . . . . . . . . . . . . . . .  82
   9.4.4.  Delegation Revocation  . . . . . . . . . . . . . . . . .  84
   9.5.  Data Caching and Revocation  . . . . . . . . . . . . . . .  84
   9.5.1.  Revocation Recovery for Write Open Delegation  . . . . .  85
   9.6.  Attribute Caching  . . . . . . . . . . . . . . . . . . . .  85
   9.7.  Name Caching . . . . . . . . . . . . . . . . . . . . . . .  86
   9.8.  Directory Caching  . . . . . . . . . . . . . . . . . . . .  87
   10.  Minor Versioning  . . . . . . . . . . . . . . . . . . . . .  88
   11.  Internationalization  . . . . . . . . . . . . . . . . . . .  91
   11.1.  Universal Versus Local Character Sets . . . . . . . . . .  91
   11.2.  Overview of Universal Character Set Standards . . . . . .  92
   11.3.  Difficulties with UCS-4, UCS-2, Unicode . . . . . . . . .  93
   11.4.  UTF-8 and its solutions . . . . . . . . . . . . . . . . .  94
   11.5.  Normalization . . . . . . . . . . . . . . . . . . . . . .  94
   12.  Error Definitions . . . . . . . . . . . . . . . . . . . . .  95
   13.  NFS Version 4 Requests  . . . . . . . . . . . . . . . . . .  99
   13.1.  Compound Procedure  . . . . . . . . . . . . . . . . . . . 100
   13.2.  Evaluation of a Compound Request  . . . . . . . . . . . . 100
   13.3.  Synchronous Modifying Operations  . . . . . . . . . . . . 101
   13.4.  Operation Values  . . . . . . . . . . . . . . . . . . . . 102
   14.  NFS Version 4 Procedures  . . . . . . . . . . . . . . . . . 102
   14.1.  Procedure 0: NULL - No Operation  . . . . . . . . . . . . 102
   14.2.  Procedure 1: COMPOUND - Compound Operations . . . . . . . 102
   14.2.1.  Operation 3: ACCESS - Check Access Rights . . . . . . . 105
   14.2.2.  Operation 4: CLOSE - Close File . . . . . . . . . . . . 108
   14.2.3.  Operation 5: COMMIT - Commit Cached Data  . . . . . . . 109
   14.2.4.  Operation 6: CREATE - Create a Non-Regular File Object. 112
   14.2.5.  Operation 7: DELEGPURGE - Purge Delegations Awaiting
            Recovery  . . . . . . . . . . . . . . . . . . . . . . . 114
   14.2.6.  Operation 8: DELEGRETURN - Return Delegation  . . . . . 115
   14.2.7.  Operation 9: GETATTR - Get Attributes . . . . . . . . . 115
   14.2.8.  Operation 10: GETFH - Get Current Filehandle  . . . . . 117
   14.2.9.  Operation 11: LINK - Create Link to a File  . . . . . . 118
   14.2.10.  Operation 12: LOCK - Create Lock . . . . . . . . . . . 119
   14.2.11.  Operation 13: LOCKT - Test For Lock  . . . . . . . . . 121
   14.2.12.  Operation 14: LOCKU - Unlock File  . . . . . . . . . . 122
   14.2.13.  Operation 15: LOOKUP - Lookup Filename . . . . . . . . 123
   14.2.14.  Operation 16: LOOKUPP - Lookup Parent Directory  . . . 126
        
   14.2.15.  Operation 17: NVERIFY - Verify Difference in
             Attributes . . . . . . . . . . . . . . . . . . . . . . 127
   14.2.16.  Operation 18: OPEN - Open a Regular File . . . . . . . 128
   14.2.17.  Operation 19: OPENATTR - Open Named Attribute
             Directory  . . . . . . . . . . . . . . . . . . . . . . 137
   14.2.18.  Operation 20: OPEN_CONFIRM - Confirm Open  . . . . . . 138
   14.2.19.  Operation 21: OPEN_DOWNGRADE - Reduce Open File Access 140
   14.2.20.  Operation 22: PUTFH - Set Current Filehandle . . . . . 141
   14.2.21.  Operation 23: PUTPUBFH - Set Public Filehandle . . . . 142
   14.2.22.  Operation 24: PUTROOTFH - Set Root Filehandle  . . . . 143
   14.2.23.  Operation 25: READ - Read from File  . . . . . . . . . 144
   14.2.24.  Operation 26: READDIR - Read Directory . . . . . . . . 146
   14.2.25.  Operation 27: READLINK - Read Symbolic Link  . . . . . 150
   14.2.26.  Operation 28: REMOVE - Remove Filesystem Object  . . . 151
   14.2.27.  Operation 29: RENAME - Rename Directory Entry  . . . . 153
   14.2.28.  Operation 30: RENEW - Renew a Lease  . . . . . . . . . 155
   14.2.29.  Operation 31: RESTOREFH - Restore Saved Filehandle . . 156
   14.2.30.  Operation 32: SAVEFH - Save Current Filehandle . . . . 157
   14.2.31.  Operation 33: SECINFO - Obtain Available Security  . . 158
   14.2.32.  Operation 34: SETATTR - Set Attributes . . . . . . . . 160
   14.2.33.  Operation 35: SETCLIENTID - Negotiate Clientid . . . . 162
   14.2.34.  Operation 36: SETCLIENTID_CONFIRM - Confirm Clientid . 163
   14.2.35.  Operation 37: VERIFY - Verify Same Attributes  . . . . 164
   14.2.36.  Operation 38: WRITE - Write to File  . . . . . . . . . 166
   15.  NFS Version 4 Callback Procedures . . . . . . . . . . . . . 170
   15.1.  Procedure 0: CB_NULL - No Operation . . . . . . . . . . . 170
   15.2.  Procedure 1: CB_COMPOUND - Compound Operations  . . . . . 171
   15.2.1.  Operation 3: CB_GETATTR - Get Attributes  . . . . . . . 172
   15.2.2.  Operation 4: CB_RECALL - Recall an Open Delegation  . . 173
   16.  Security Considerations . . . . . . . . . . . . . . . . . . 174
   17.  IANA Considerations . . . . . . . . . . . . . . . . . . . . 174
   17.1.  Named Attribute Definition  . . . . . . . . . . . . . . . 174
   18.  RPC definition file . . . . . . . . . . . . . . . . . . . . 175
   19.  Bibliography  . . . . . . . . . . . . . . . . . . . . . . . 206
   20.  Authors . . . . . . . . . . . . . . . . . . . . . . . . . . 210
   20.1.  Editor's Address  . . . . . . . . . . . . . . . . . . . . 210
   20.2.  Authors' Addresses  . . . . . . . . . . . . . . . . . . . 210
   20.3.  Acknowledgements  . . . . . . . . . . . . . . . . . . . . 211
   21.  Full Copyright Statement  . . . . . . . . . . . . . . . . . 212
        
   14.2.15.  Operation 17: NVERIFY - Verify Difference in
             Attributes . . . . . . . . . . . . . . . . . . . . . . 127
   14.2.16.  Operation 18: OPEN - Open a Regular File . . . . . . . 128
   14.2.17.  Operation 19: OPENATTR - Open Named Attribute
             Directory  . . . . . . . . . . . . . . . . . . . . . . 137
   14.2.18.  Operation 20: OPEN_CONFIRM - Confirm Open  . . . . . . 138
   14.2.19.  Operation 21: OPEN_DOWNGRADE - Reduce Open File Access 140
   14.2.20.  Operation 22: PUTFH - Set Current Filehandle . . . . . 141
   14.2.21.  Operation 23: PUTPUBFH - Set Public Filehandle . . . . 142
   14.2.22.  Operation 24: PUTROOTFH - Set Root Filehandle  . . . . 143
   14.2.23.  Operation 25: READ - Read from File  . . . . . . . . . 144
   14.2.24.  Operation 26: READDIR - Read Directory . . . . . . . . 146
   14.2.25.  Operation 27: READLINK - Read Symbolic Link  . . . . . 150
   14.2.26.  Operation 28: REMOVE - Remove Filesystem Object  . . . 151
   14.2.27.  Operation 29: RENAME - Rename Directory Entry  . . . . 153
   14.2.28.  Operation 30: RENEW - Renew a Lease  . . . . . . . . . 155
   14.2.29.  Operation 31: RESTOREFH - Restore Saved Filehandle . . 156
   14.2.30.  Operation 32: SAVEFH - Save Current Filehandle . . . . 157
   14.2.31.  Operation 33: SECINFO - Obtain Available Security  . . 158
   14.2.32.  Operation 34: SETATTR - Set Attributes . . . . . . . . 160
   14.2.33.  Operation 35: SETCLIENTID - Negotiate Clientid . . . . 162
   14.2.34.  Operation 36: SETCLIENTID_CONFIRM - Confirm Clientid . 163
   14.2.35.  Operation 37: VERIFY - Verify Same Attributes  . . . . 164
   14.2.36.  Operation 38: WRITE - Write to File  . . . . . . . . . 166
   15.  NFS Version 4 Callback Procedures . . . . . . . . . . . . . 170
   15.1.  Procedure 0: CB_NULL - No Operation . . . . . . . . . . . 170
   15.2.  Procedure 1: CB_COMPOUND - Compound Operations  . . . . . 171
   15.2.1.  Operation 3: CB_GETATTR - Get Attributes  . . . . . . . 172
   15.2.2.  Operation 4: CB_RECALL - Recall an Open Delegation  . . 173
   16.  Security Considerations . . . . . . . . . . . . . . . . . . 174
   17.  IANA Considerations . . . . . . . . . . . . . . . . . . . . 174
   17.1.  Named Attribute Definition  . . . . . . . . . . . . . . . 174
   18.  RPC definition file . . . . . . . . . . . . . . . . . . . . 175
   19.  Bibliography  . . . . . . . . . . . . . . . . . . . . . . . 206
   20.  Authors . . . . . . . . . . . . . . . . . . . . . . . . . . 210
   20.1.  Editor's Address  . . . . . . . . . . . . . . . . . . . . 210
   20.2.  Authors' Addresses  . . . . . . . . . . . . . . . . . . . 210
   20.3.  Acknowledgements  . . . . . . . . . . . . . . . . . . . . 211
   21.  Full Copyright Statement  . . . . . . . . . . . . . . . . . 212
        
1. Introduction
1. 介绍

The NFS version 4 protocol is a further revision of the NFS protocol defined already by versions 2 [RFC1094] and 3 [RFC1813]. It retains the essential characteristics of previous versions: design for easy recovery, independent of transport protocols, operating systems and filesystems, simplicity, and good performance. The NFS version 4 revision has the following goals:

NFS版本4协议是版本2[RFC1094]和版本3[RFC1813]已经定义的NFS协议的进一步修订版。它保留了以前版本的基本特征:易于恢复的设计、独立于传输协议、操作系统和文件系统、简单性和良好的性能。NFS版本4修订版具有以下目标:

o Improved access and good performance on the Internet.

o 改进了Internet上的访问和良好性能。

The protocol is designed to transit firewalls easily, perform well where latency is high and bandwidth is low, and scale to very large numbers of clients per server.

该协议设计用于轻松传输防火墙,在延迟高、带宽低的情况下性能良好,并可扩展到每台服务器上的大量客户端。

o Strong security with negotiation built into the protocol.

o 协议内置协商功能,安全性强。

The protocol builds on the work of the ONCRPC working group in supporting the RPCSEC_GSS protocol. Additionally, the NFS version 4 protocol provides a mechanism to allow clients and servers the ability to negotiate security and require clients and servers to support a minimal set of security schemes.

该协议以ONCRPC工作组支持RPCSEC_GSS协议的工作为基础。此外,NFS版本4协议提供了一种机制,允许客户端和服务器协商安全性,并要求客户端和服务器支持一组最小的安全方案。

o Good cross-platform interoperability.

o 良好的跨平台互操作性。

The protocol features a file system model that provides a useful, common set of features that does not unduly favor one file system or operating system over another.

该协议以一个文件系统模型为特色,该模型提供了一组有用的、通用的特性,这些特性不会过分偏向于一个文件系统或操作系统而不是另一个文件系统或操作系统。

o Designed for protocol extensions.

o 专为协议扩展而设计。

The protocol is designed to accept standard extensions that do not compromise backward compatibility.

该协议旨在接受不损害向后兼容性的标准扩展。

1.1. Overview of NFS Version 4 Features
1.1. NFS版本4功能概述

To provide a reasonable context for the reader, the major features of NFS version 4 protocol will be reviewed in brief. This will be done to provide an appropriate context for both the reader who is familiar with the previous versions of the NFS protocol and the reader that is new to the NFS protocols. For the reader new to the NFS protocols, there is still a fundamental knowledge that is expected. The reader should be familiar with the XDR and RPC protocols as described in [RFC1831] and [RFC1832]. A basic knowledge of file systems and distributed file systems is expected as well.

为了给读者提供一个合理的上下文,我们将简要回顾NFS版本4协议的主要功能。这样做是为了为熟悉以前版本的NFS协议的读者和新加入NFS协议的读者提供适当的上下文。对于初次接触NFS协议的读者来说,仍然需要了解一些基本知识。读者应熟悉[RFC1831]和[RFC1832]中所述的XDR和RPC协议。具备文件系统和分布式文件系统的基本知识。

1.1.1. RPC and Security
1.1.1. RPC与安全

As with previous versions of NFS, the External Data Representation (XDR) and Remote Procedure Call (RPC) mechanisms used for the NFS version 4 protocol are those defined in [RFC1831] and [RFC1832]. To meet end to end security requirements, the RPCSEC_GSS framework [RFC2203] will be used to extend the basic RPC security. With the use of RPCSEC_GSS, various mechanisms can be provided to offer authentication, integrity, and privacy to the NFS version 4 protocol. Kerberos V5 will be used as described in [RFC1964] to provide one security framework. The LIPKEY GSS-API mechanism described in

与以前版本的NFS一样,NFS版本4协议使用的外部数据表示(XDR)和远程过程调用(RPC)机制是[RFC1831]和[RFC1832]中定义的机制。为了满足端到端安全性要求,将使用RPCSEC_GSS框架[RFC2203]扩展基本RPC安全性。通过使用RPCSEC_GSS,可以提供各种机制来为NFS版本4协议提供身份验证、完整性和隐私。Kerberos V5将按[RFC1964]中所述使用,以提供一个安全框架。中描述的LIPKEY GSS-API机制

[RFC2847] will be used to provide for the use of user password and server public key by the NFS version 4 protocol. With the use of RPCSEC_GSS, other mechanisms may also be specified and used for NFS version 4 security.

[RFC2847]将用于通过NFS版本4协议提供用户密码和服务器公钥的使用。通过使用RPCSEC_GSS,还可以为NFS版本4安全性指定和使用其他机制。

To enable in-band security negotiation, the NFS version 4 protocol has added a new operation which provides the client a method of querying the server about its policies regarding which security mechanisms must be used for access to the server's file system resources. With this, the client can securely match the security mechanism that meets the policies specified at both the client and server.

为了启用带内安全协商,NFS version 4协议添加了一个新的操作,该操作为客户端提供了一种方法,用于查询服务器关于访问服务器文件系统资源必须使用哪些安全机制的策略。这样,客户机就可以安全地匹配满足客户机和服务器上指定的策略的安全机制。

1.1.2. Procedure and Operation Structure
1.1.2. 程序及运作架构

A significant departure from the previous versions of the NFS protocol is the introduction of the COMPOUND procedure. For the NFS version 4 protocol, there are two RPC procedures, NULL and COMPOUND. The COMPOUND procedure is defined in terms of operations and these operations correspond more closely to the traditional NFS procedures. With the use of the COMPOUND procedure, the client is able to build simple or complex requests. These COMPOUND requests allow for a reduction in the number of RPCs needed for logical file system operations. For example, without previous contact with a server a client will be able to read data from a file in one request by combining LOOKUP, OPEN, and READ operations in a single COMPOUND RPC. With previous versions of the NFS protocol, this type of single request was not possible.

与以前版本的NFS协议不同的一个重要区别是引入了复合过程。对于NFS版本4协议,有两个RPC过程:NULL和component。复合过程是根据操作定义的,这些操作与传统的NFS过程更接近。通过使用复合过程,客户机能够构建简单或复杂的请求。这些复合请求允许减少逻辑文件系统操作所需的RPC数量。例如,如果以前没有与服务器联系,客户端将能够通过在单个复合RPC中组合查找、打开和读取操作,在一个请求中从文件读取数据。对于以前版本的NFS协议,这种类型的单一请求是不可能的。

The model used for COMPOUND is very simple. There is no logical OR or ANDing of operations. The operations combined within a COMPOUND request are evaluated in order by the server. Once an operation returns a failing result, the evaluation ends and the results of all evaluated operations are returned to the client.

用于化合物的模型非常简单。操作之间没有逻辑或AND。复合请求中组合的操作由服务器按顺序进行评估。一旦操作返回失败的结果,评估将结束,所有评估操作的结果将返回给客户端。

The NFS version 4 protocol continues to have the client refer to a file or directory at the server by a "filehandle". The COMPOUND procedure has a method of passing a filehandle from one operation to another within the sequence of operations. There is a concept of a "current filehandle" and "saved filehandle". Most operations use the "current filehandle" as the file system object to operate upon. The "saved filehandle" is used as temporary filehandle storage within a COMPOUND procedure as well as an additional operand for certain operations.

NFS版本4协议继续让客户端通过“文件句柄”引用服务器上的文件或目录。复合过程有一种在操作序列中将文件句柄从一个操作传递到另一个操作的方法。有一个“当前文件句柄”和“保存的文件句柄”的概念。大多数操作使用“当前文件句柄”作为要操作的文件系统对象。“保存的文件句柄”用作复合过程中的临时文件句柄存储以及某些操作的附加操作数。

1.1.3. File System Model
1.1.3. 文件系统模型

The general file system model used for the NFS version 4 protocol is the same as previous versions. The server file system is hierarchical with the regular files contained within being treated as opaque byte streams. In a slight departure, file and directory names are encoded with UTF-8 to deal with the basics of internationalization.

NFS版本4协议使用的通用文件系统模型与以前的版本相同。服务器文件系统是分层的,其中包含的常规文件被视为不透明字节流。稍微不同的是,文件名和目录名用UTF-8编码,以处理国际化的基础知识。

The NFS version 4 protocol does not require a separate protocol to provide for the initial mapping between path name and filehandle. Instead of using the older MOUNT protocol for this mapping, the server provides a ROOT filehandle that represents the logical root or top of the file system tree provided by the server. The server provides multiple file systems by gluing them together with pseudo file systems. These pseudo file systems provide for potential gaps in the path names between real file systems.

NFS版本4协议不需要单独的协议来提供路径名和文件句柄之间的初始映射。服务器提供了一个根文件句柄,表示服务器提供的文件系统树的逻辑根或顶部,而不是使用较旧的装载协议进行此映射。服务器通过将多个文件系统与伪文件系统粘合在一起来提供多个文件系统。这些伪文件系统为实际文件系统之间的路径名提供了潜在的间隙。

1.1.3.1. Filehandle Types
1.1.3.1. 文件句柄类型

In previous versions of the NFS protocol, the filehandle provided by the server was guaranteed to be valid or persistent for the lifetime of the file system object to which it referred. For some server implementations, this persistence requirement has been difficult to meet. For the NFS version 4 protocol, this requirement has been relaxed by introducing another type of filehandle, volatile. With persistent and volatile filehandle types, the server implementation can match the abilities of the file system at the server along with the operating environment. The client will have knowledge of the type of filehandle being provided by the server and can be prepared to deal with the semantics of each.

在NFS协议的早期版本中,服务器提供的filehandle保证在其引用的文件系统对象的生命周期内有效或持久。对于某些服务器实现,这种持久性需求一直难以满足。对于NFS版本4协议,通过引入另一种类型的文件句柄volatile,这一要求得到了放宽。对于持久性和易失性文件句柄类型,服务器实现可以与服务器上的文件系统的能力以及操作环境相匹配。客户机将了解服务器提供的文件句柄类型,并准备好处理每个文件句柄的语义。

1.1.3.2. Attribute Types
1.1.3.2. 属性类型

The NFS version 4 protocol introduces three classes of file system or file attributes. Like the additional filehandle type, the classification of file attributes has been done to ease server implementations along with extending the overall functionality of the NFS protocol. This attribute model is structured to be extensible such that new attributes can be introduced in minor revisions of the protocol without requiring significant rework.

NFS版本4协议引入了三类文件系统或文件属性。与附加的filehandle类型一样,文件属性的分类已经完成,以便在扩展NFS协议的总体功能的同时简化服务器实现。该属性模型的结构是可扩展的,因此可以在协议的较小修订中引入新属性,而无需进行大量返工。

The three classifications are: mandatory, recommended and named attributes. This is a significant departure from the previous attribute model used in the NFS protocol. Previously, the attributes for the file system and file objects were a fixed set of mainly Unix attributes. If the server or client did not support a particular attribute, it would have to simulate the attribute the best it could.

这三种分类是:强制、推荐和命名属性。这与以前在NFS协议中使用的属性模型有很大的不同。以前,文件系统和文件对象的属性是一组固定的,主要是Unix属性。如果服务器或客户端不支持特定属性,则必须尽可能地模拟该属性。

Mandatory attributes are the minimal set of file or file system attributes that must be provided by the server and must be properly represented by the server. Recommended attributes represent different file system types and operating environments. The recommended attributes will allow for better interoperability and the inclusion of more operating environments. The mandatory and recommended attribute sets are traditional file or file system attributes. The third type of attribute is the named attribute. A named attribute is an opaque byte stream that is associated with a directory or file and referred to by a string name. Named attributes are meant to be used by client applications as a method to associate application specific data with a regular file or directory.

强制属性是服务器必须提供且必须由服务器正确表示的文件或文件系统属性的最小集合。推荐的属性表示不同的文件系统类型和操作环境。推荐的属性将允许更好的互操作性,并包含更多的操作环境。强制属性集和推荐属性集是传统的文件或文件系统属性。第三种类型的属性是命名属性。命名属性是与目录或文件关联并由字符串名称引用的不透明字节流。命名属性被客户机应用程序用作将特定于应用程序的数据与常规文件或目录关联的方法。

One significant addition to the recommended set of file attributes is the Access Control List (ACL) attribute. This attribute provides for directory and file access control beyond the model used in previous versions of the NFS protocol. The ACL definition allows for specification of user and group level access control.

对推荐的文件属性集的一个重要补充是访问控制列表(ACL)属性。此属性提供了NFS协议早期版本中使用的模型之外的目录和文件访问控制。ACL定义允许指定用户和组级别的访问控制。

1.1.3.3. File System Replication and Migration
1.1.3.3. 文件系统复制和迁移

With the use of a special file attribute, the ability to migrate or replicate server file systems is enabled within the protocol. The file system locations attribute provides a method for the client to probe the server about the location of a file system. In the event of a migration of a file system, the client will receive an error when operating on the file system and it can then query as to the new file system location. Similar steps are used for replication, the client is able to query the server for the multiple available locations of a particular file system. From this information, the client can use its own policies to access the appropriate file system location.

通过使用特殊的文件属性,可以在协议中迁移或复制服务器文件系统。“文件系统位置”属性为客户端提供了一种方法,用于向服务器探测文件系统的位置。在文件系统迁移的情况下,客户端在文件系统上操作时将收到错误,然后可以查询新文件系统的位置。复制也使用类似的步骤,客户机可以向服务器查询特定文件系统的多个可用位置。根据这些信息,客户机可以使用自己的策略访问适当的文件系统位置。

1.1.4. OPEN and CLOSE
1.1.4. 开合

The NFS version 4 protocol introduces OPEN and CLOSE operations. The OPEN operation provides a single point where file lookup, creation, and share semantics can be combined. The CLOSE operation also provides for the release of state accumulated by OPEN.

NFS版本4协议引入了打开和关闭操作。OPEN操作提供了一个点,在这里可以组合文件查找、创建和共享语义。关闭操作还可释放打开累积的状态。

1.1.5. File locking
1.1.5. 文件锁定

With the NFS version 4 protocol, the support for byte range file locking is part of the NFS protocol. The file locking support is structured so that an RPC callback mechanism is not required. This is a departure from the previous versions of the NFS file locking protocol, Network Lock Manager (NLM). The state associated with file locks is maintained at the server under a lease-based model. The

对于NFS版本4协议,对字节范围文件锁定的支持是NFS协议的一部分。文件锁定支持的结构不需要RPC回调机制。这与以前版本的NFS文件锁定协议Network Lock Manager(NLM)不同。与文件锁关联的状态在基于租约的模型下在服务器上维护。这个

server defines a single lease period for all state held by a NFS client. If the client does not renew its lease within the defined period, all state associated with the client's lease may be released by the server. The client may renew its lease with use of the RENEW operation or implicitly by use of other operations (primarily READ).

服务器为NFS客户端持有的所有状态定义一个租用期。如果客户端未在定义的期限内续订其租约,则服务器可能会释放与客户端租约关联的所有状态。客户可以通过使用“续订”操作或通过使用其他操作(主要是READ)来间接续订其租约。

1.1.6. Client Caching and Delegation
1.1.6. 客户端缓存和委托

The file, attribute, and directory caching for the NFS version 4 protocol is similar to previous versions. Attributes and directory information are cached for a duration determined by the client. At the end of a predefined timeout, the client will query the server to see if the related file system object has been updated.

NFS版本4协议的文件、属性和目录缓存与以前的版本类似。属性和目录信息的缓存时间由客户端确定。在预定义超时结束时,客户端将查询服务器,查看相关文件系统对象是否已更新。

For file data, the client checks its cache validity when the file is opened. A query is sent to the server to determine if the file has been changed. Based on this information, the client determines if the data cache for the file should kept or released. Also, when the file is closed, any modified data is written to the server.

对于文件数据,客户端在打开文件时检查其缓存有效性。将向服务器发送查询,以确定文件是否已更改。根据此信息,客户机确定是保留还是释放文件的数据缓存。此外,当文件关闭时,任何修改的数据都会写入服务器。

If an application wants to serialize access to file data, file locking of the file data ranges in question should be used.

若应用程序想要序列化对文件数据的访问,那个么应该使用有问题的文件数据范围的文件锁定。

The major addition to NFS version 4 in the area of caching is the ability of the server to delegate certain responsibilities to the client. When the server grants a delegation for a file to a client, the client is guaranteed certain semantics with respect to the sharing of that file with other clients. At OPEN, the server may provide the client either a read or write delegation for the file. If the client is granted a read delegation, it is assured that no other client has the ability to write to the file for the duration of the delegation. If the client is granted a write delegation, the client is assured that no other client has read or write access to the file.

NFS版本4在缓存方面的主要新增功能是服务器能够将某些职责委托给客户端。当服务器向客户机授予文件的委托时,客户机可以保证与其他客户机共享该文件时具有一定的语义。打开时,服务器可以为客户端提供文件的读或写委派。如果客户机被授予读委派,则可以确保在委派期间没有其他客户机能够写入文件。如果客户机被授予写授权,则客户机将确保没有其他客户机具有对该文件的读或写访问权限。

Delegations can be recalled by the server. If another client requests access to the file in such a way that the access conflicts with the granted delegation, the server is able to notify the initial client and recall the delegation. This requires that a callback path exist between the server and client. If this callback path does not exist, then delegations can not be granted. The essence of a delegation is that it allows the client to locally service operations such as OPEN, CLOSE, LOCK, LOCKU, READ, WRITE without immediate interaction with the server.

服务器可以调用委托。如果另一个客户端请求访问该文件,并且访问与授予的委托冲突,则服务器能够通知初始客户端并重新调用该委托。这要求在服务器和客户端之间存在回调路径。如果此回调路径不存在,则无法授予委派。委托的本质是,它允许客户端在本地服务操作,如打开、关闭、锁定、锁定、读取、写入,而无需立即与服务器交互。

1.2. General Definitions
1.2. 一般定义

The following definitions are provided for the purpose of providing an appropriate context for the reader.

以下定义旨在为读者提供适当的上下文。

Client The "client" is the entity that accesses the NFS server's resources. The client may be an application which contains the logic to access the NFS server directly. The client may also be the traditional operating system client remote file system services for a set of applications.

客户端“客户端”是访问NFS服务器资源的实体。客户端可能是包含直接访问NFS服务器的逻辑的应用程序。客户端也可以是一组应用程序的传统操作系统客户端远程文件系统服务。

In the case of file locking the client is the entity that maintains a set of locks on behalf of one or more applications. This client is responsible for crash or failure recovery for those locks it manages.

在文件锁定的情况下,客户端是代表一个或多个应用程序维护一组锁的实体。此客户端负责其管理的锁的崩溃或故障恢复。

Note that multiple clients may share the same transport and multiple clients may exist on the same network node.

请注意,多个客户端可能共享同一传输,并且同一网络节点上可能存在多个客户端。

Clientid A 64-bit quantity used as a unique, short-hand reference to a client supplied Verifier and ID. The server is responsible for supplying the Clientid.

Clientid是一个64位的数量,用作对客户端提供的验证器和ID的唯一、简短的引用。服务器负责提供Clientid。

Lease An interval of time defined by the server for which the client is irrevocably granted a lock. At the end of a lease period the lock may be revoked if the lease has not been extended. The lock must be revoked if a conflicting lock has been granted after the lease interval.

租用一段由服务器定义的时间间隔,客户机不可撤销地被授予该时间间隔的锁。在租赁期结束时,如果租赁期未延长,则可撤销锁定。如果在租约间隔后授予了冲突的锁,则必须撤销该锁。

All leases granted by a server have the same fixed interval. Note that the fixed interval was chosen to alleviate the expense a server would have in maintaining state about variable length leases across server failures.

服务器授予的所有租约具有相同的固定时间间隔。请注意,选择固定时间间隔是为了减轻服务器在维护跨服务器故障的可变长度租约状态时的开销。

Lock The term "lock" is used to refer to both record (byte-range) locks as well as file (share) locks unless specifically stated otherwise.

锁术语“锁”用于指记录(字节范围)锁和文件(共享)锁,除非另有特别说明。

Server The "Server" is the entity responsible for coordinating client access to a set of file systems.

服务器“服务器”是负责协调客户端对一组文件系统的访问的实体。

Stable Storage NFS version 4 servers must be able to recover without data loss from multiple power failures (including cascading power failures, that is, several power failures in quick succession), operating system failures, and hardware failure of components other than the storage medium itself (for example, disk, nonvolatile RAM).

稳定存储NFS版本4服务器必须能够从多个电源故障(包括级联电源故障,即连续几次电源故障)、操作系统故障和存储介质本身以外的组件(例如,磁盘、非易失性RAM)的硬件故障中恢复而不丢失数据。

Some examples of stable storage that are allowable for an NFS server include:

NFS服务器允许的一些稳定存储示例包括:

1. Media commit of data, that is, the modified data has been successfully written to the disk media, for example, the disk platter.

1. 数据的介质提交,即修改后的数据已成功写入磁盘介质,例如磁盘盘片。

2. An immediate reply disk drive with battery-backed on-drive intermediate storage or uninterruptible power system (UPS).

2. 立即回复磁盘驱动器,在驱动器中间存储器或不间断电源系统(UPS)上备有电池。

3. Server commit of data with battery-backed intermediate storage and recovery software.

3. 使用电池备份的中间存储和恢复软件进行服务器数据提交。

4. Cache commit with uninterruptible power system (UPS) and recovery software.

4. 使用不间断电源系统(UPS)和恢复软件进行缓存提交。

Stateid A 64-bit quantity returned by a server that uniquely defines the locking state granted by the server for a specific lock owner for a specific file.

Stateid服务器返回的64位数量,它唯一地定义了服务器为特定文件的特定锁所有者授予的锁定状态。

Stateids composed of all bits 0 or all bits 1 have special meaning and are reserved values.

由所有位0或所有位1组成的StateID具有特殊含义,是保留值。

Verifier A 64-bit quantity generated by the client that the server can use to determine if the client has restarted and lost all previous lock state.

验证器客户端生成的64位数量,服务器可使用该数量确定客户端是否已重新启动并丢失所有以前的锁定状态。

2. Protocol Data Types
2. 协议数据类型

The syntax and semantics to describe the data types of the NFS version 4 protocol are defined in the XDR [RFC1832] and RPC [RFC1831] documents. The next sections build upon the XDR data types to define types and structures specific to this protocol.

XDR[RFC1832]和RPC[RFC1831]文档中定义了用于描述NFS版本4协议的数据类型的语法和语义。下一节将基于XDR数据类型来定义特定于此协议的类型和结构。

2.1. Basic Data Types
2.1. 基本数据类型
   Data Type     Definition
   _____________________________________________________________________
   int32_t       typedef int             int32_t;
        
   Data Type     Definition
   _____________________________________________________________________
   int32_t       typedef int             int32_t;
        

uint32_t typedef unsigned int uint32_t;

uint32_t类型定义无符号整数uint32_t;

int64_t typedef hyper int64_t;

int64_t类型定义超int64_t;

uint64_t typedef unsigned hyper uint64_t;

uint64_t类型定义无符号超uint64_t;

   attrlist4     typedef opaque        attrlist4<>;
                 Used for file/directory attributes
        
   attrlist4     typedef opaque        attrlist4<>;
                 Used for file/directory attributes
        

bitmap4 typedef uint32_t bitmap4<>; Used in attribute array encoding.

bitmap4类型定义uint32_t bitmap4<>;用于属性数组编码。

changeid4 typedef uint64_t changeid4; Used in definition of change_info

changeid4 typedef uint64\u t changeid4;用于变更信息的定义

clientid4 typedef uint64_t clientid4; Shorthand reference to client identification

client4 typedef uint64_t client4;客户身份的速记参考

component4 typedef utf8string component4; Represents path name components

组件4类型定义utf8string组件4;表示组件的路径名

count4 typedef uint32_t count4; Various count parameters (READ, WRITE, COMMIT)

count4 typedef uint32\u t count4;各种计数参数(读、写、提交)

length4 typedef uint64_t length4; Describes LOCK lengths

长度4类型定义uint64_t长度4;描述锁的长度

linktext4 typedef utf8string linktext4; Symbolic link contents

linktext4类型定义utf8string linktext4;符号链接内容

mode4 typedef uint32_t mode4; Mode attribute data type

模式4 typedef uint32_t模式4;模式属性数据类型

nfs_cookie4 typedef uint64_t nfs_cookie4; Opaque cookie value for READDIR

nfs_cookie4类型定义uint64_t nfs_cookie4;READDIR的不透明cookie值

   nfs_fh4       typedef opaque          nfs_fh4<NFS4_FHSIZE>;
                 Filehandle definition; NFS4_FHSIZE is defined as 128
        
   nfs_fh4       typedef opaque          nfs_fh4<NFS4_FHSIZE>;
                 Filehandle definition; NFS4_FHSIZE is defined as 128
        

nfs_ftype4 enum nfs_ftype4; Various defined file types

nfs_ftype4枚举nfs_ftype4;各种定义的文件类型

nfsstat4 enum nfsstat4; Return value for operations

nfsstat4枚举nfsstat4;操作的返回值

offset4 typedef uint64_t offset4; Various offset designations (READ, WRITE, LOCK, COMMIT)

抵销4类型定义uint64\u t抵销4;各种偏移量指定(读、写、锁、提交)

pathname4 typedef component4 pathname4<>; Represents path name for LOOKUP, OPEN and others

路径名4类型定义组件4路径名4<>;表示查找、打开和其他的路径名

qop4 typedef uint32_t qop4; Quality of protection designation in SECINFO

qop4类型定义uint32_t qop4;SECINFO中的保护标志质量

sec_oid4 typedef opaque sec_oid4<>; Security Object Identifier The sec_oid4 data type is not really opaque. Instead contains an ASN.1 OBJECT IDENTIFIER as used by GSS-API in the mech_type argument to GSS_Init_sec_context. See [RFC2078] for details.

第4节类型定义不透明第4节;安全对象标识符sec_oid4数据类型并非真正不透明。而是包含GSS-API在GSS_Init_sec_上下文的mech_type参数中使用的ASN.1对象标识符。详见[RFC2078]。

seqid4 typedef uint32_t seqid4; Sequence identifier used for file locking

Sequid4类型定义单元32\u t Sequid4;用于文件锁定的序列标识符

stateid4 typedef uint64_t stateid4; State identifier used for file locking and delegation

stateid4类型定义uint64\u t stateid4;用于文件锁定和委派的状态标识符

utf8string typedef opaque utf8string<>; UTF-8 encoding for strings

utf8string类型定义不透明utf8string<>;字符串的UTF-8编码

verifier4 typedef opaque verifier4[NFS4_VERIFIER_SIZE]; Verifier used for various operations (COMMIT, CREATE, OPEN, READDIR, SETCLIENTID, WRITE) NFS4_VERIFIER_SIZE is defined as 8

验证器4类型定义不透明验证器4[NFS4_验证器大小];用于各种操作(提交、创建、打开、READDIR、SETCLIENTID、写入)的验证程序NFS4\u验证程序大小定义为8

2.2. Structured Data Types
2.2. 结构化数据类型
   nfstime4
                  struct nfstime4 {
                          int64_t seconds;
                          uint32_t nseconds;
                  }
        
   nfstime4
                  struct nfstime4 {
                          int64_t seconds;
                          uint32_t nseconds;
                  }
        

The nfstime4 structure gives the number of seconds and nanoseconds since midnight or 0 hour January 1, 1970 Coordinated Universal Time (UTC). Values greater than zero for the seconds field denote dates after the 0 hour January 1, 1970. Values less than zero for the seconds field denote dates before the 0 hour January 1, 1970. In both cases, the nseconds field is to be added to the seconds field for the final time representation. For example, if the time to be represented is one-half second before 0 hour January 1, 1970, the seconds field would have a value of negative one (-1) and the nseconds fields would have a value of one-half second (500000000). Values greater than 999,999,999 for nseconds are considered invalid.

nfstime4结构给出了自1970年1月1日协调世界时(UTC)午夜或0小时后的秒数和纳秒数。秒字段大于零的值表示1970年1月1日0小时后的日期。秒字段小于零的值表示1970年1月1日0小时之前的日期。在这两种情况下,N秒字段将添加到秒字段中,作为最终时间表示。例如,如果要表示的时间是1970年1月1日0小时之前的半秒,则秒字段的值为负1(-1),而秒字段的值为半秒(500000000)。对于N秒,大于9999999的值被视为无效。

This data type is used to pass time and date information. A server converts to and from its local representation of time when processing time values, preserving as much accuracy as possible. If the precision of timestamps stored for a file system object is

此数据类型用于传递时间和日期信息。在处理时间值时,服务器会在本地表示的时间之间进行转换,以尽可能保持准确性。如果为文件系统对象存储的时间戳的精度为

less than defined, loss of precision can occur. An adjunct time maintenance protocol is recommended to reduce client and server time skew.

小于定义值时,可能会发生精度损失。建议使用附加的时间维护协议来减少客户端和服务器的时间偏差。

time_how4

时间如何

                  enum time_how4 {
                          SET_TO_SERVER_TIME4 = 0,
                          SET_TO_CLIENT_TIME4 = 1
                  };
        
                  enum time_how4 {
                          SET_TO_SERVER_TIME4 = 0,
                          SET_TO_CLIENT_TIME4 = 1
                  };
        

settime4

设置时间4

                  union settime4 switch (time_how4 set_it) {
                   case SET_TO_CLIENT_TIME4:
                           nfstime4       time;
                   default:
                           void;
                  };
        
                  union settime4 switch (time_how4 set_it) {
                   case SET_TO_CLIENT_TIME4:
                           nfstime4       time;
                   default:
                           void;
                  };
        

The above definitions are used as the attribute definitions to set time values. If set_it is SET_TO_SERVER_TIME4, then the server uses its local representation of time for the time value.

以上定义用作设置时间值的属性定义。如果将其设置为服务器时间4,则服务器使用其本地时间表示形式作为时间值。

specdata4

规范数据4

                  struct specdata4 {
                          uint32_t specdata1;
                          uint32_t specdata2;
                  };
        
                  struct specdata4 {
                          uint32_t specdata1;
                          uint32_t specdata2;
                  };
        

This data type represents additional information for the device file types NF4CHR and NF4BLK.

此数据类型表示设备文件类型NF4CHR和NF4BLK的附加信息。

fsid4

fsid4

                  struct fsid4 {
                    uint64_t        major;
                    uint64_t        minor;
                  };
        
                  struct fsid4 {
                    uint64_t        major;
                    uint64_t        minor;
                  };
        

This type is the file system identifier that is used as a mandatory attribute.

此类型是用作强制属性的文件系统标识符。

fs_location4

fs_位置4

                  struct fs_location4 {
                          utf8string    server<>;
                          pathname4     rootpath;
                  };
        
                  struct fs_location4 {
                          utf8string    server<>;
                          pathname4     rootpath;
                  };
        

fs_locations4

fs_位置4

                  struct fs_locations4 {
                          pathname4     fs_root;
                          fs_location4  locations<>;
                  };
        
                  struct fs_locations4 {
                          pathname4     fs_root;
                          fs_location4  locations<>;
                  };
        

The fs_location4 and fs_locations4 data types are used for the fs_locations recommended attribute which is used for migration and replication support.

fs_location4和fs_locations4数据类型用于fs_locations recommended属性,该属性用于迁移和复制支持。

fattr4

胖子4

                  struct fattr4 {
                          bitmap4       attrmask;
                          attrlist4     attr_vals;
                  };
        
                  struct fattr4 {
                          bitmap4       attrmask;
                          attrlist4     attr_vals;
                  };
        

The fattr4 structure is used to represent file and directory attributes.

fattr4结构用于表示文件和目录属性。

The bitmap is a counted array of 32 bit integers used to contain bit values. The position of the integer in the array that contains bit n can be computed from the expression (n / 32) and its bit within that integer is (n mod 32).

位图是一个32位整数的计数数组,用于包含位值。整数在包含位n的数组中的位置可以通过表达式(n/32)计算得出,其在该整数中的位为(n mod 32)。

                                      0            1
                    +-----------+-----------+-----------+--
                    |  count    | 31  ..  0 | 63  .. 32 |
                    +-----------+-----------+-----------+--
        
                                      0            1
                    +-----------+-----------+-----------+--
                    |  count    | 31  ..  0 | 63  .. 32 |
                    +-----------+-----------+-----------+--
        

change_info4

更改信息4

                  struct change_info4 {
                          bool          atomic;
                          changeid4     before;
                          changeid4     after;
                  };
        
                  struct change_info4 {
                          bool          atomic;
                          changeid4     before;
                          changeid4     after;
                  };
        

This structure is used with the CREATE, LINK, REMOVE, RENAME operations to let the client the know value of the change attribute for the directory in which the target file system object resides.

此结构与创建、链接、删除和重命名操作一起使用,以让客户端知道目标文件系统对象所在目录的更改属性的值。

clientaddr4

客户地址4

                  struct clientaddr4 {
                          /* see struct rpcb in RFC 1833 */
                          string r_netid<>;    /* network id */
                          string r_addr<>;     /* universal address */
                  };
        
                  struct clientaddr4 {
                          /* see struct rpcb in RFC 1833 */
                          string r_netid<>;    /* network id */
                          string r_addr<>;     /* universal address */
                  };
        

The clientaddr4 structure is used as part of the SETCLIENT operation to either specify the address of the client that is using a clientid or as part of the call back registration.

ClientAddress4结构用作SETCLIENT操作的一部分,用于指定正在使用clientid的客户端的地址或作为回调注册的一部分。

cb_client4

cb_客户4

                  struct cb_client4 {
                          unsigned int  cb_program;
                          clientaddr4   cb_location;
                  };
        
                  struct cb_client4 {
                          unsigned int  cb_program;
                          clientaddr4   cb_location;
                  };
        

This structure is used by the client to inform the server of its call back address; includes the program number and client address.

客户端使用此结构通知服务器其回拨地址;包括程序编号和客户端地址。

nfs_client_id4

nfs_客户端_id4

                  struct nfs_client_id4 {
                          verifier4     verifier;
                          opaque        id<>;
                  };
        
                  struct nfs_client_id4 {
                          verifier4     verifier;
                          opaque        id<>;
                  };
        

This structure is part of the arguments to the SETCLIENTID operation.

此结构是SETCLIENTID操作参数的一部分。

nfs_lockowner4

nfs_锁所有者4

                  struct nfs_lockowner4 {
                          clientid4     clientid;
                          opaque        owner<>;
                  };
        
                  struct nfs_lockowner4 {
                          clientid4     clientid;
                          opaque        owner<>;
                  };
        

This structure is used to identify the owner of a OPEN share or file lock.

此结构用于标识打开的共享或文件锁的所有者。

3. RPC and Security Flavor
3. RPC与安全风格

The NFS version 4 protocol is a Remote Procedure Call (RPC) application that uses RPC version 2 and the corresponding eXternal Data Representation (XDR) as defined in [RFC1831] and [RFC1832]. The RPCSEC_GSS security flavor as defined in [RFC2203] MUST be used as the mechanism to deliver stronger security for the NFS version 4 protocol.

NFS版本4协议是一个远程过程调用(RPC)应用程序,它使用RPC版本2和[RFC1831]和[RFC1832]中定义的相应外部数据表示(XDR)。[RFC2203]中定义的RPCSEC_GSS安全特性必须用作为NFS版本4协议提供更强安全性的机制。

3.1. Ports and Transports
3.1. 港口和运输

Historically, NFS version 2 and version 3 servers have resided on port 2049. The registered port 2049 [RFC1700] for the NFS protocol should be the default configuration. Using the registered port for NFS services means the NFS client will not need to use the RPC binding protocols as described in [RFC1833]; this will allow NFS to transit firewalls.

历史上,NFS版本2和版本3服务器都位于端口2049上。NFS协议的注册端口2049[RFC1700]应为默认配置。使用NFS服务的注册端口意味着NFS客户端不需要使用[RFC1833]中所述的RPC绑定协议;这将允许NFS传输防火墙。

The transport used by the RPC service for the NFS version 4 protocol MUST provide congestion control comparable to that defined for TCP in [RFC2581]. If the operating environment implements TCP, the NFS version 4 protocol SHOULD be supported over TCP. The NFS client and server may use other transports if they support congestion control as defined above and in those cases a mechanism may be provided to override TCP usage in favor of another transport.

NFS版本4协议的RPC服务使用的传输必须提供与[RFC2581]中为TCP定义的拥塞控制相当的拥塞控制。如果操作环境实现TCP,则应通过TCP支持NFS版本4协议。如果NFS客户端和服务器支持上面定义的拥塞控制,则它们可以使用其他传输,在这些情况下,可以提供一种机制来覆盖TCP使用,以支持其他传输。

If TCP is used as the transport, the client and server SHOULD use persistent connections. This will prevent the weakening of TCP's congestion control via short lived connections and will improve performance for the WAN environment by eliminating the need for SYN handshakes.

如果使用TCP作为传输,则客户端和服务器应使用持久连接。这将防止通过短命连接削弱TCP的拥塞控制,并通过消除SYN握手的需要来提高WAN环境的性能。

Note that for various timers, the client and server should avoid inadvertent synchronization of those timers. For further discussion of the general issue refer to [Floyd].

请注意,对于各种计时器,客户端和服务器应避免无意中同步这些计时器。关于一般性问题的进一步讨论,请参考[Floyd]。

3.2. Security Flavors
3.2. 安全口味

Traditional RPC implementations have included AUTH_NONE, AUTH_SYS, AUTH_DH, and AUTH_KRB4 as security flavors. With [RFC2203] an additional security flavor of RPCSEC_GSS has been introduced which uses the functionality of GSS-API [RFC2078]. This allows for the use of varying security mechanisms by the RPC layer without the additional implementation overhead of adding RPC security flavors. For NFS version 4, the RPCSEC_GSS security flavor MUST be used to

传统的RPC实现包括AUTH_NONE、AUTH_SYS、AUTH_DH和AUTH_KRB4作为安全特性。[RFC2203]引入了RPCSEC_GSS的额外安全特性,它使用GSS-API[RFC2078]的功能。这允许RPC层使用不同的安全机制,而无需增加RPC安全特性的额外实现开销。对于NFS版本4,必须使用RPCSEC_GSS安全特性

enable the mandatory security mechanism. Other flavors, such as, AUTH_NONE, AUTH_SYS, and AUTH_DH MAY be implemented as well.

启用强制安全机制。还可以实现其他风格,例如AUTH_NONE、AUTH_SYS和AUTH_DH。

3.2.1. Security mechanisms for NFS version 4
3.2.1. NFS版本4的安全机制

The use of RPCSEC_GSS requires selection of: mechanism, quality of protection, and service (authentication, integrity, privacy). The remainder of this document will refer to these three parameters of the RPCSEC_GSS security as the security triple.

使用RPCSEC_GSS需要选择:机制、保护质量和服务(身份验证、完整性、隐私)。本文件的其余部分将RPCSEC_GSS安全性的这三个参数称为安全三元组。

3.2.1.1. Kerberos V5 as security triple
3.2.1.1. Kerberos V5作为三重安全

The Kerberos V5 GSS-API mechanism as described in [RFC1964] MUST be implemented and provide the following security triples.

必须实现[RFC1964]中描述的Kerberos V5 GSS-API机制,并提供以下安全三元组。

column descriptions:

列说明:

   1 == number of pseudo flavor
   2 == name of pseudo flavor
   3 == mechanism's OID
   4 == mechanism's algorithm(s)
   5 == RPCSEC_GSS service
        
   1 == number of pseudo flavor
   2 == name of pseudo flavor
   3 == mechanism's OID
   4 == mechanism's algorithm(s)
   5 == RPCSEC_GSS service
        
1      2     3                    4              5
-----------------------------------------------------------------------
390003 krb5  1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_none
390004 krb5i 1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_integrity
390005 krb5p 1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_privacy
                                  for integrity,
                                  and 56 bit DES
                                  for privacy.
        
1      2     3                    4              5
-----------------------------------------------------------------------
390003 krb5  1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_none
390004 krb5i 1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_integrity
390005 krb5p 1.2.840.113554.1.2.2 DES MAC MD5    rpc_gss_svc_privacy
                                  for integrity,
                                  and 56 bit DES
                                  for privacy.
        

Note that the pseudo flavor is presented here as a mapping aid to the implementor. Because this NFS protocol includes a method to negotiate security and it understands the GSS-API mechanism, the pseudo flavor is not needed. The pseudo flavor is needed for NFS version 3 since the security negotiation is done via the MOUNT protocol.

请注意,伪风格在这里作为映射辅助工具提供给实现者。因为此NFS协议包含协商安全性的方法,并且它理解GSS-API机制,所以不需要伪风格。NFS版本3需要伪风格,因为安全协商是通过装载协议完成的。

For a discussion of NFS' use of RPCSEC_GSS and Kerberos V5, please see [RFC2623].

有关NFS使用RPCSEC_GSS和Kerberos V5的讨论,请参阅[RFC2623]。

3.2.1.2. LIPKEY as a security triple
3.2.1.2. LIPKEY作为一个安全三重密码

The LIPKEY GSS-API mechanism as described in [RFC2847] MUST be implemented and provide the following security triples. The definition of the columns matches the previous subsection "Kerberos V5 as security triple"

必须实现[RFC2847]中描述的LIPKEY GSS-API机制,并提供以下安全三元组。列的定义与前面的小节“Kerberos V5作为安全三元组”匹配

1      2        3                    4              5
-----------------------------------------------------------------------
390006 lipkey   1.3.6.1.5.5.9        negotiated  rpc_gss_svc_none
390007 lipkey-i 1.3.6.1.5.5.9        negotiated  rpc_gss_svc_integrity
390008 lipkey-p 1.3.6.1.5.5.9        negotiated  rpc_gss_svc_privacy
        
1      2        3                    4              5
-----------------------------------------------------------------------
390006 lipkey   1.3.6.1.5.5.9        negotiated  rpc_gss_svc_none
390007 lipkey-i 1.3.6.1.5.5.9        negotiated  rpc_gss_svc_integrity
390008 lipkey-p 1.3.6.1.5.5.9        negotiated  rpc_gss_svc_privacy
        

The mechanism algorithm is listed as "negotiated". This is because LIPKEY is layered on SPKM-3 and in SPKM-3 [RFC2847] the confidentiality and integrity algorithms are negotiated. Since SPKM-3 specifies HMAC-MD5 for integrity as MANDATORY, 128 bit cast5CBC for confidentiality for privacy as MANDATORY, and further specifies that HMAC-MD5 and cast5CBC MUST be listed first before weaker algorithms, specifying "negotiated" in column 4 does not impair interoperability. In the event an SPKM-3 peer does not support the mandatory algorithms, the other peer is free to accept or reject the GSS-API context creation.

机制算法被列为“协商”。这是因为LIPKEY是在SPKM-3上分层的,在SPKM-3[RFC2847]中,机密性和完整性算法是协商的。由于SPKM-3规定HMAC-MD5的完整性为强制性,128位cast5CBC的隐私保密性为强制性,并进一步规定HMAC-MD5和cast5CBC必须在较弱的算法之前首先列出,因此在第4列中指定“协商”不会影响互操作性。如果SPKM-3对等方不支持强制算法,则另一对等方可自由接受或拒绝GSS-API上下文创建。

Because SPKM-3 negotiates the algorithms, subsequent calls to LIPKEY's GSS_Wrap() and GSS_GetMIC() by RPCSEC_GSS will use a quality of protection value of 0 (zero). See section 5.2 of [RFC2025] for an explanation.

由于SPKM-3协商算法,RPCSEC_GSS对LIPKEY的GSS_Wrap()和GSS_GetMIC()的后续调用将使用0(零)的保护质量值。有关说明,请参见[RFC2025]第5.2节。

LIPKEY uses SPKM-3 to create a secure channel in which to pass a user name and password from the client to the user. Once the user name and password have been accepted by the server, calls to the LIPKEY context are redirected to the SPKM-3 context. See [RFC2847] for more details.

LIPKEY使用SPKM-3创建一个安全通道,在该通道中将用户名和密码从客户端传递给用户。一旦服务器接受用户名和密码,对LIPKEY上下文的调用将重定向到SPKM-3上下文。有关更多详细信息,请参阅[RFC2847]。

3.2.1.3. SPKM-3 as a security triple
3.2.1.3. SPKM-3作为安全三重系统

The SPKM-3 GSS-API mechanism as described in [RFC2847] MUST be implemented and provide the following security triples. The definition of the columns matches the previous subsection "Kerberos V5 as security triple".

必须实现[RFC2847]中所述的SPKM-3 GSS-API机制,并提供以下安全三元组。列的定义与前面的小节“Kerberos V5作为安全三元组”匹配。

1      2        3                    4              5
-----------------------------------------------------------------------
390009 spkm3    1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_none
390010 spkm3i   1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_integrity
390011 spkm3p   1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_privacy
        
1      2        3                    4              5
-----------------------------------------------------------------------
390009 spkm3    1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_none
390010 spkm3i   1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_integrity
390011 spkm3p   1.3.6.1.5.5.1.3      negotiated  rpc_gss_svc_privacy
        

For a discussion as to why the mechanism algorithm is listed as "negotiated", see the previous section "LIPKEY as a security triple."

有关机制算法为何被列为“协商”的讨论,请参阅上一节“LIPKEY作为安全三元组”

Because SPKM-3 negotiates the algorithms, subsequent calls to SPKM-3's GSS_Wrap() and GSS_GetMIC() by RPCSEC_GSS will use a quality of protection value of 0 (zero). See section 5.2 of [RFC2025] for an explanation.

由于SPKM-3协商算法,RPCSEC_GSS对SPKM-3的GSS_Wrap()和GSS_GetMIC()的后续调用将使用0(零)的保护质量值。有关说明,请参见[RFC2025]第5.2节。

Even though LIPKEY is layered over SPKM-3, SPKM-3 is specified as a mandatory set of triples to handle the situations where the initiator (the client) is anonymous or where the initiator has its own certificate. If the initiator is anonymous, there will not be a user name and password to send to the target (the server). If the initiator has its own certificate, then using passwords is superfluous.

尽管LIPKEY是在SPKM-3上分层的,但SPKM-3被指定为一组必需的三元组,以处理启动器(客户端)匿名或启动器拥有自己证书的情况。如果启动器是匿名的,则不会向目标(服务器)发送用户名和密码。如果启动器有自己的证书,那么使用密码是多余的。

3.3. Security Negotiation
3.3. 安全协商

With the NFS version 4 server potentially offering multiple security mechanisms, the client needs a method to determine or negotiate which mechanism is to be used for its communication with the server. The NFS server may have multiple points within its file system name space that are available for use by NFS clients. In turn the NFS server may be configured such that each of these entry points may have different or multiple security mechanisms in use.

由于NFS version 4服务器可能提供多种安全机制,客户端需要一种方法来确定或协商用于与服务器通信的机制。NFS服务器的文件系统名称空间中可能有多个点可供NFS客户端使用。反过来,可以配置NFS服务器,使这些入口点中的每一个都可以使用不同或多个安全机制。

The security negotiation between client and server must be done with a secure channel to eliminate the possibility of a third party intercepting the negotiation sequence and forcing the client and server to choose a lower level of security than required or desired.

客户机和服务器之间的安全协商必须通过安全通道进行,以消除第三方截获协商序列并迫使客户机和服务器选择低于要求或期望的安全级别的可能性。

3.3.1. Security Error
3.3.1. 安全错误

Based on the assumption that each NFS version 4 client and server must support a minimum set of security (i.e. LIPKEY, SPKM-3, and Kerberos-V5 all under RPCSEC_GSS), the NFS client will start its communication with the server with one of the minimal security triples. During communication with the server, the client may receive an NFS error of NFS4ERR_WRONGSEC. This error allows the server to notify the client that the security triple currently being used is not appropriate for access to the server's file system resources. The client is then responsible for determining what security triples are available at the server and choose one which is appropriate for the client.

基于以下假设,即每个NFS版本4客户端和服务器必须支持一组最小的安全性(即,在RPCSEC_GSS下的LIPKEY、SPKM-3和Kerberos-V5),NFS客户端将使用其中一个最小的安全性三元组开始与服务器的通信。在与服务器通信期间,客户端可能会收到NFS4ERR_错误秒的NFS错误。此错误允许服务器通知客户端当前使用的安全性三元组不适合访问服务器的文件系统资源。然后,客户机负责确定服务器上有哪些安全三元组可用,并选择一个适合客户机的安全三元组。

3.3.2. SECINFO
3.3.2. SECINFO

The new SECINFO operation will allow the client to determine, on a per filehandle basis, what security triple is to be used for server access. In general, the client will not have to use the SECINFO procedure except during initial communication with the server or when the client crosses policy boundaries at the server. It is possible that the server's policies change during the client's interaction therefore forcing the client to negotiate a new security triple.

新的SECINFO操作将允许客户端根据每个文件句柄确定服务器访问将使用什么样的安全性。通常,客户端不必使用SECINFO过程,除非在与服务器的初始通信期间或客户端在服务器上跨越策略边界时。在客户端的交互过程中,服务器的策略可能会发生变化,从而迫使客户端协商新的安全策略。

3.4. Callback RPC Authentication
3.4. 回调RPC身份验证

The callback RPC (described later) must mutually authenticate the NFS server to the principal that acquired the clientid (also described later), using the same security flavor the original SETCLIENTID operation used. Because LIPKEY is layered over SPKM-3, it is permissible for the server to use SPKM-3 and not LIPKEY for the callback even if the client used LIPKEY for SETCLIENTID.

回调RPC(稍后描述)必须使用与原始SETCLIENTID操作相同的安全风格,向获取clientid(稍后描述)的主体相互验证NFS服务器。由于LIPKEY是在SPKM-3上分层的,因此允许服务器对回调使用SPKM-3而不是LIPKEY,即使客户端对SETCLIENTID使用了LIPKEY。

For AUTH_NONE, there are no principals, so this is a non-issue.

对于AUTH_NONE,没有主体,因此这不是问题。

For AUTH_SYS, the server simply uses the AUTH_SYS credential that the user used when it set up the delegation.

对于AUTH_SYS,服务器只使用用户在设置委派时使用的AUTH_SYS凭据。

For AUTH_DH, one commonly used convention is that the server uses the credential corresponding to this AUTH_DH principal:

对于AUTH_DH,一个常用的约定是服务器使用与此AUTH_DH主体对应的凭据:

unix.host@domain

unix。host@domain

where host and domain are variables corresponding to the name of server host and directory services domain in which it lives such as a Network Information System domain or a DNS domain.

其中,主机和域是与其所在的服务器主机和目录服务域(如网络信息系统域或DNS域)的名称相对应的变量。

Regardless of what security mechanism under RPCSEC_GSS is being used, the NFS server, MUST identify itself in GSS-API via a GSS_C_NT_HOSTBASED_SERVICE name type. GSS_C_NT_HOSTBASED_SERVICE names are of the form:

无论使用的是RPCSEC_GSS下的何种安全机制,NFS服务器都必须通过GSS_C_NT_HOSTBASED_服务名称类型在GSS-API中标识自己。GSS_C_NT_基于主机的_服务名称的形式如下:

service@hostname

service@hostname

For NFS, the "service" element is

对于NFS,“服务”元素是

nfs

nfs

Implementations of security mechanisms will convert nfs@hostname to various different forms. For Kerberos V5 and LIPKEY, the following form is RECOMMENDED:

安全机制的实现将转换为nfs@hostname以各种不同的形式。对于Kerberos V5和LIPKEY,建议采用以下形式:

nfs/hostname

nfs/主机名

For Kerberos V5, nfs/hostname would be a server principal in the Kerberos Key Distribution Center database. For LIPKEY, this would be the username passed to the target (the NFS version 4 client that receives the callback).

对于Kerberos V5,nfs/主机名将是Kerberos密钥分发中心数据库中的服务器主体。对于LIPKEY,这将是传递给目标(接收回调的NFS版本4客户端)的用户名。

It should be noted that LIPKEY may not work for callbacks, since the LIPKEY client uses a user id/password. If the NFS client receiving the callback can authenticate the NFS server's user name/password

应该注意的是,LIPKEY可能不适用于回调,因为LIPKEY客户端使用用户id/密码。如果接收回调的NFS客户端可以验证NFS服务器的用户名/密码

pair, and if the user that the NFS server is authenticating to has a public key certificate, then it works.

配对,并且如果NFS服务器进行身份验证的用户具有公钥证书,则它可以工作。

In situations where NFS client uses LIPKEY and uses a per-host principal for the SETCLIENTID operation, instead of using LIPKEY for SETCLIENTID, it is RECOMMENDED that SPKM-3 with mutual authentication be used. This effectively means that the client will use a certificate to authenticate and identify the initiator to the target on the NFS server. Using SPKM-3 and not LIPKEY has the following advantages:

在NFS客户端使用LIPKEY并为SETCLIENTID操作使用每主机主体的情况下,建议使用具有相互身份验证的SPKM-3,而不是为SETCLIENTID使用LIPKEY。这实际上意味着客户端将使用证书对NFS服务器上的目标进行身份验证和标识启动器。使用SPKM-3而非LIPKEY具有以下优点:

o When the server does a callback, it must authenticate to the principal used in the SETCLIENTID. Even if LIPKEY is used, because LIPKEY is layered over SPKM-3, the NFS client will need to have a certificate that corresponds to the principal used in the SETCLIENTID operation. From an administrative perspective, having a user name, password, and certificate for both the client and server is redundant.

o 当服务器执行回调时,它必须向SETCLIENTID中使用的主体进行身份验证。即使使用了LIPKEY,因为LIPKEY是在SPKM-3上分层的,NFS客户端也需要有一个与SETCLIENTID操作中使用的主体相对应的证书。从管理的角度来看,为客户端和服务器同时拥有用户名、密码和证书是多余的。

o LIPKEY was intended to minimize additional infrastructure requirements beyond a certificate for the target, and the expectation is that existing password infrastructure can be leveraged for the initiator. In some environments, a per-host password does not exist yet. If certificates are used for any per-host principals, then additional password infrastructure is not needed.

o LIPKEY旨在最大限度地减少除目标证书之外的其他基础架构需求,并且期望现有密码基础架构可以用于启动器。在某些环境中,每个主机的密码尚不存在。如果证书用于任何每主机主体,则不需要额外的密码基础结构。

o In cases when a host is both an NFS client and server, it can share the same per-host certificate.

o 在主机既是NFS客户端又是服务器的情况下,它可以共享相同的每主机证书。

4. Filehandles
4. 文件句柄

The filehandle in the NFS protocol is a per server unique identifier for a file system object. The contents of the filehandle are opaque to the client. Therefore, the server is responsible for translating the filehandle to an internal representation of the file system object. Since the filehandle is the client's reference to an object and the client may cache this reference, the server SHOULD not reuse a filehandle for another file system object. If the server needs to reuse a filehandle value, the time elapsed before reuse SHOULD be large enough such that it is unlikely the client has a cached copy of the reused filehandle value. Note that a client may cache a filehandle for a very long time. For example, a client may cache NFS data to local storage as a method to expand its effective cache size and as a means to survive client restarts. Therefore, the lifetime of a cached filehandle may be extended.

NFS协议中的filehandle是文件系统对象的每服务器唯一标识符。文件句柄的内容对客户端是不透明的。因此,服务器负责将文件句柄转换为文件系统对象的内部表示形式。由于filehandle是客户端对某个对象的引用,并且客户端可能会缓存该引用,因此服务器不应为另一个文件系统对象重用filehandle。如果服务器需要重用filehandle值,则重用之前经过的时间应足够长,以便客户端不太可能拥有重用filehandle值的缓存副本。请注意,客户端可能会将文件句柄缓存很长时间。例如,客户机可以将NFS数据缓存到本地存储中,作为扩展其有效缓存大小的方法和在客户机重新启动后生存的手段。因此,缓存文件句柄的生存期可能会延长。

4.1. Obtaining the First Filehandle
4.1. 获取第一个文件句柄

The operations of the NFS protocol are defined in terms of one or more filehandles. Therefore, the client needs a filehandle to initiate communication with the server. With the NFS version 2 protocol [RFC1094] and the NFS version 3 protocol [RFC1813], there exists an ancillary protocol to obtain this first filehandle. The MOUNT protocol, RPC program number 100005, provides the mechanism of translating a string based file system path name to a filehandle which can then be used by the NFS protocols.

NFS协议的操作是根据一个或多个文件句柄定义的。因此,客户端需要一个文件句柄来启动与服务器的通信。对于NFS版本2协议[RFC1094]和NFS版本3协议[RFC1813],存在一个辅助协议来获取第一个文件句柄。装载协议(RPC程序编号100005)提供了将基于字符串的文件系统路径名转换为文件句柄的机制,然后NFS协议可以使用该文件句柄。

The MOUNT protocol has deficiencies in the area of security and use via firewalls. This is one reason that the use of the public filehandle was introduced in [RFC2054] and [RFC2055]. With the use of the public filehandle in combination with the LOOKUP procedure in the NFS version 2 and 3 protocols, it has been demonstrated that the MOUNT protocol is unnecessary for viable interaction between NFS client and server.

MOUNT协议在安全性和通过防火墙使用方面存在缺陷。这就是[RFC2054]和[RFC2055]中引入公共文件句柄的原因之一。通过将公共文件句柄与NFS版本2和3协议中的查找过程结合使用,已经证明装载协议对于NFS客户端和服务器之间的可行交互是不必要的。

Therefore, the NFS version 4 protocol will not use an ancillary protocol for translation from string based path names to a filehandle. Two special filehandles will be used as starting points for the NFS client.

因此,NFS版本4协议不会使用辅助协议将基于字符串的路径名转换为文件句柄。两个特殊的文件句柄将用作NFS客户端的起点。

4.1.1. Root Filehandle
4.1.1. 根文件句柄

The first of the special filehandles is the ROOT filehandle. The ROOT filehandle is the "conceptual" root of the file system name space at the NFS server. The client uses or starts with the ROOT filehandle by employing the PUTROOTFH operation. The PUTROOTFH operation instructs the server to set the "current" filehandle to the ROOT of the server's file tree. Once this PUTROOTFH operation is used, the client can then traverse the entirety of the server's file tree with the LOOKUP procedure. A complete discussion of the server name space is in the section "NFS Server Name Space".

第一个特殊文件句柄是根文件句柄。根文件句柄是NFS服务器上文件系统名称空间的“概念”根。客户端通过使用PUTROOTFH操作来使用或启动根文件句柄。PUTROOTFH操作指示服务器将“当前”文件句柄设置为服务器文件树的根。一旦使用了这个PUTROOTFH操作,客户端就可以通过查找过程遍历整个服务器的文件树。有关服务器名称空间的完整讨论,请参阅“NFS服务器名称空间”一节。

4.1.2. Public Filehandle
4.1.2. 公共文件句柄

The second special filehandle is the PUBLIC filehandle. Unlike the ROOT filehandle, the PUBLIC filehandle may be bound or represent an arbitrary file system object at the server. The server is responsible for this binding. It may be that the PUBLIC filehandle and the ROOT filehandle refer to the same file system object. However, it is up to the administrative software at the server and the policies of the server administrator to define the binding of the PUBLIC filehandle and server file system object. The client may not make any assumptions about this binding.

第二个特殊文件句柄是公共文件句柄。与根文件句柄不同,公共文件句柄可以绑定或表示服务器上的任意文件系统对象。服务器负责此绑定。公共文件句柄和根文件句柄可能引用同一个文件系统对象。但是,定义公共文件句柄和服务器文件系统对象的绑定取决于服务器上的管理软件和服务器管理员的策略。客户不得对此绑定做出任何假设。

4.2. Filehandle Types
4.2. 文件句柄类型

In the NFS version 2 and 3 protocols, there was one type of filehandle with a single set of semantics. The NFS version 4 protocol introduces a new type of filehandle in an attempt to accommodate certain server environments. The first type of filehandle is 'persistent'. The semantics of a persistent filehandle are the same as the filehandles of the NFS version 2 and 3 protocols. The second or new type of filehandle is the "volatile" filehandle.

在NFS版本2和3协议中,有一种类型的filehandle具有一组语义。NFS版本4协议引入了一种新类型的文件句柄,试图适应某些服务器环境。第一种类型的文件句柄是“持久的”。持久化文件句柄的语义与NFS版本2和3协议的文件句柄相同。第二种或新类型的文件句柄是“volatile”文件句柄。

The volatile filehandle type is being introduced to address server functionality or implementation issues which make correct implementation of a persistent filehandle infeasible. Some server environments do not provide a file system level invariant that can be used to construct a persistent filehandle. The underlying server file system may not provide the invariant or the server's file system programming interfaces may not provide access to the needed invariant. Volatile filehandles may ease the implementation of server functionality such as hierarchical storage management or file system reorganization or migration. However, the volatile filehandle increases the implementation burden for the client. However this increased burden is deemed acceptable based on the overall gains achieved by the protocol.

引入volatile filehandle类型是为了解决服务器功能或实现问题,这些问题使持久化filehandle的正确实现变得不可行。某些服务器环境不提供可用于构造持久化文件句柄的文件系统级不变量。底层服务器文件系统可能不提供不变量,或者服务器的文件系统编程接口可能不提供对所需不变量的访问。易失性文件句柄可以简化服务器功能的实现,如分层存储管理或文件系统重组或迁移。但是,易失性文件句柄增加了客户端的实现负担。然而,根据《议定书》取得的总体收益,这一增加的负担被认为是可以接受的。

Since the client will need to handle persistent and volatile filehandle differently, a file attribute is defined which may be used by the client to determine the filehandle types being returned by the server.

由于客户端需要以不同的方式处理持久性和易失性filehandle,因此定义了一个文件属性,客户端可以使用该属性来确定服务器返回的filehandle类型。

4.2.1. General Properties of a Filehandle
4.2.1. 文件句柄的常规属性

The filehandle contains all the information the server needs to distinguish an individual file. To the client, the filehandle is opaque. The client stores filehandles for use in a later request and can compare two filehandles from the same server for equality by doing a byte-by-byte comparison. However, the client MUST NOT otherwise interpret the contents of filehandles. If two filehandles from the same server are equal, they MUST refer to the same file. If they are not equal, the client may use information provided by the server, in the form of file attributes, to determine whether they denote the same files or different files. The client would do this as necessary for client side caching. Servers SHOULD try to maintain a one-to-one correspondence between filehandles and files but this is not required. Clients MUST use filehandle comparisons only to improve performance, not for correct behavior. All clients need to be prepared for situations in which it cannot be determined whether two filehandles denote the same object and in such cases, avoid making invalid assumptions which might cause incorrect behavior.

filehandle包含服务器区分单个文件所需的所有信息。对于客户端来说,文件句柄是不透明的。客户端存储文件句柄,以便在以后的请求中使用,并且可以通过逐字节比较来比较来自同一服务器的两个文件句柄是否相等。但是,客户端不得以其他方式解释文件句柄的内容。如果来自同一服务器的两个文件句柄相等,则它们必须引用同一文件。如果它们不相等,客户端可以使用服务器以文件属性的形式提供的信息来确定它们是表示相同的文件还是不同的文件。客户端将根据客户端缓存的需要执行此操作。服务器应尝试在文件句柄和文件之间保持一对一的对应关系,但这不是必需的。客户端必须使用filehandle比较来提高性能,而不是正确的行为。所有客户端都需要为无法确定两个文件句柄是否表示同一对象的情况做好准备,在这种情况下,避免做出可能导致错误行为的无效假设。

Further discussion of filehandle and attribute comparison in the context of data caching is presented in the section "Data Caching and File Identity".

“数据缓存和文件标识”一节将进一步讨论数据缓存环境中的文件句柄和属性比较。

As an example, in the case that two different path names when traversed at the server terminate at the same file system object, the server SHOULD return the same filehandle for each path. This can occur if a hard link is used to create two file names which refer to the same underlying file object and associated data. For example, if paths /a/b/c and /a/d/c refer to the same file, the server SHOULD return the same filehandle for both path names traversals.

例如,如果在服务器上遍历两个不同的路径名时终止于同一文件系统对象,则服务器应为每个路径返回相同的filehandle。如果使用硬链接创建两个引用同一基础文件对象和关联数据的文件名,则可能会发生这种情况。例如,如果路径/a/b/c和/a/d/c引用同一个文件,则服务器应为两个路径名遍历返回相同的文件句柄。

4.2.2. Persistent Filehandle
4.2.2. 持久文件句柄

A persistent filehandle is defined as having a fixed value for the lifetime of the file system object to which it refers. Once the server creates the filehandle for a file system object, the server MUST accept the same filehandle for the object for the lifetime of the object. If the server restarts or reboots the NFS server must honor the same filehandle value as it did in the server's previous instantiation. Similarly, if the file system is migrated, the new NFS server must honor the same file handle as the old NFS server.

持久化文件句柄定义为在其引用的文件系统对象的生存期内具有固定值。一旦服务器为文件系统对象创建了filehandle,服务器就必须在对象的生存期内为该对象接受相同的filehandle。如果服务器重新启动或重新启动,NFS服务器必须使用与服务器上一次实例化中相同的filehandle值。类似地,如果文件系统被迁移,新的NFS服务器必须与旧的NFS服务器使用相同的文件句柄。

The persistent filehandle will be become stale or invalid when the file system object is removed. When the server is presented with a persistent filehandle that refers to a deleted object, it MUST return an error of NFS4ERR_STALE. A filehandle may become stale when the file system containing the object is no longer available. The file system may become unavailable if it exists on removable media and the media is no longer available at the server or the file system in whole has been destroyed or the file system has simply been removed from the server's name space (i.e. unmounted in a Unix environment).

删除文件系统对象时,持久化文件句柄将变得陈旧或无效。当服务器显示引用已删除对象的持久化文件句柄时,它必须返回NFS4ERR_STALE错误。当包含对象的文件系统不再可用时,文件句柄可能会过时。如果文件系统存在于可移动介质上,并且该介质在服务器上不再可用,或者整个文件系统已被破坏,或者文件系统已从服务器的名称空间中删除(即在Unix环境中卸载),则该文件系统可能不可用。

4.2.3. Volatile Filehandle
4.2.3. 易失性文件句柄

A volatile filehandle does not share the same longevity characteristics of a persistent filehandle. The server may determine that a volatile filehandle is no longer valid at many different points in time. If the server can definitively determine that a volatile filehandle refers to an object that has been removed, the server should return NFS4ERR_STALE to the client (as is the case for persistent filehandles). In all other cases where the server determines that a volatile filehandle can no longer be used, it should return an error of NFS4ERR_FHEXPIRED.

易失性文件句柄与持久性文件句柄的寿命特征不同。服务器可能会确定易失性文件句柄在许多不同的时间点不再有效。如果服务器可以确定易失性文件句柄引用已删除的对象,则服务器应将NFS4ERR_STALE返回给客户端(与持久性文件句柄的情况相同)。在所有其他情况下,如果服务器确定无法再使用易失性文件句柄,则应返回一个错误NFS4ERR\fhu expired。

The mandatory attribute "fh_expire_type" is used by the client to determine what type of filehandle the server is providing for a particular file system. This attribute is a bitmask with the following values:

客户端使用强制属性“fh_expire_type”来确定服务器为特定文件系统提供的文件句柄类型。此属性是具有以下值的位掩码:

FH4_PERSISTENT The value of FH4_PERSISTENT is used to indicate a persistent filehandle, which is valid until the object is removed from the file system. The server will not return NFS4ERR_FHEXPIRED for this filehandle. FH4_PERSISTENT is defined as a value in which none of the bits specified below are set.

FH4_PERSISTENT FH4_PERSISTENT的值用于指示持久化文件句柄,该句柄在对象从文件系统中删除之前有效。服务器不会为此文件句柄返回NFS4ERR_fhu expired。FH4_PERSISTENT定义为未设置以下指定位的值。

FH4_NOEXPIRE_WITH_OPEN The filehandle will not expire while client has the file open. If this bit is set, then the values FH4_VOLATILE_ANY or FH4_VOL_RENAME do not impact expiration while the file is open. Once the file is closed or if the FH4_NOEXPIRE_WITH_OPEN bit is false, the rest of the volatile related bits apply.

FH4\u NOEXPIRE\u打开时,当客户端打开文件时,文件句柄不会过期。如果设置了该位,则文件打开时FH4_VOLATILE_ANY或FH4_VOL_RENAME的值不会影响过期。一旦文件关闭,或者如果FH4_NOEXPIRE_WITH_OPEN位为false,则其余的易失性相关位将应用。

FH4_VOLATILE_ANY The filehandle may expire at any time and will expire during system migration and rename.

FH4_VOLATILE_任何文件句柄都可能随时过期,并将在系统迁移和重命名期间过期。

FH4_VOL_MIGRATION The filehandle will expire during file system migration. May only be set if FH4_VOLATILE_ANY is not set.

FH4_VOL_迁移文件句柄将在文件系统迁移期间过期。仅当未设置FH4\u VOLATILE\u ANY时才可设置。

FH4_VOL_RENAME The filehandle may expire due to a rename. This includes a rename by the requesting client or a rename by another client. May only be set if FH4_VOLATILE_ANY is not set.

FH4_VOL_RENAME文件句柄可能因重命名而过期。这包括请求客户端的重命名或另一客户端的重命名。仅当未设置FH4\u VOLATILE\u ANY时才可设置。

Servers which provide volatile filehandles should deny a RENAME or REMOVE that would affect an OPEN file or any of the components leading to the OPEN file. In addition, the server should deny all RENAME or REMOVE requests during the grace or lease period upon server restart.

提供易失性文件句柄的服务器应拒绝重命名或删除会影响打开的文件或导致打开的文件的任何组件。此外,在服务器重新启动后的宽限期或租赁期内,服务器应拒绝所有重命名或删除请求。

The reader may be wondering why there are three FH4_VOL* bits and why FH4_VOLATILE_ANY is exclusive of FH4_VOL_MIGRATION and FH4_VOL_RENAME. If the a filehandle is normally persistent but cannot persist across a file set migration, then the presence of the FH4_VOL_MIGRATION or FH4_VOL_RENAME tells the client that it can treat the file handle as persistent for purposes of maintaining a file name to file handle cache, except for the specific event described by the bit. However, FH4_VOLATILE_ANY tells the client that it should not maintain such a cache for unopened files. A server MUST not present FH4_VOLATILE_ANY with FH4_VOL_MIGRATION or

读者可能想知道为什么有三个FH4_VOL*位,为什么FH4_VOLATILE_ANY不包括FH4_VOL_迁移和FH4_VOL_重命名。如果文件句柄通常是持久的,但不能在文件集迁移期间持久,则FH4_VOL_迁移或FH4_VOL_重命名的存在会告诉客户机,为了维护文件名到文件句柄缓存,它可以将文件句柄视为持久的,位描述的特定事件除外。然而,FH4_VOLATILE_ANY告诉客户端,它不应该为未打开的文件维护这样的缓存。服务器不得向FH4\u VOLATILE\u ANY提供FH4\u VOLATILE\u迁移或

FH4_VOL_RENAME as this will lead to confusion. FH4_VOLATILE_ANY implies that the file handle will expire upon migration or rename, in addition to other events.

FH4_VOL_重命名,因为这将导致混淆。FH4_VOLATILE_ANY意味着文件句柄将在迁移或重命名时过期,以及其他事件。

4.2.4. One Method of Constructing a Volatile Filehandle
4.2.4. 构造易失性文件句柄的一种方法

As mentioned, in some instances a filehandle is stale (no longer valid; perhaps because the file was removed from the server) or it is expired (the underlying file is valid but since the filehandle is volatile, it may have expired). Thus the server needs to be able to return NFS4ERR_STALE in the former case and NFS4ERR_FHEXPIRED in the latter case. This can be done by careful construction of the volatile filehandle. One possible implementation follows.

如前所述,在某些情况下,文件句柄已过时(不再有效;可能是因为文件已从服务器中删除)或已过期(基础文件有效,但由于文件句柄不稳定,因此可能已过期)。因此,服务器需要能够在前一种情况下返回NFS4ERR_STALE,在后一种情况下返回NFS4ERR_fhuexpired。这可以通过仔细构造volatile文件句柄来实现。下面是一个可能的实现。

A volatile filehandle, while opaque to the client could contain:

对客户端不透明的易失性文件句柄可能包含:

[volatile bit = 1 | server boot time | slot | generation number]

[volatile bit=1 |服务器启动时间|插槽|代数]

o slot is an index in the server volatile filehandle table

o slot是服务器volatile filehandle表中的索引

o generation number is the generation number for the table entry/slot

o generation number是表项/插槽的生成编号

If the server boot time is less than the current server boot time, return NFS4ERR_FHEXPIRED. If slot is out of range, return NFS4ERR_BADHANDLE. If the generation number does not match, return NFS4ERR_FHEXPIRED.

如果服务器引导时间小于当前服务器引导时间,则返回NFS4ERR\fhu expired。如果插槽超出范围,则返回NFS4ERR_BADHANDLE。如果生成编号不匹配,则返回NFS4ERR\fhu expired。

When the server reboots, the table is gone (it is volatile).

当服务器重新启动时,表就不存在了(它是不稳定的)。

If volatile bit is 0, then it is a persistent filehandle with a different structure following it.

如果volatile位为0,则它是一个具有不同结构的持久文件句柄。

4.3. Client Recovery from Filehandle Expiration
4.3. 从文件句柄过期恢复客户端

If possible, the client SHOULD recover from the receipt of an NFS4ERR_FHEXPIRED error. The client must take on additional responsibility so that it may prepare itself to recover from the expiration of a volatile filehandle. If the server returns persistent filehandles, the client does not need these additional steps.

如果可能,客户端应在收到NFS4ERR\fhu过期错误后恢复。客户机必须承担额外的责任,以便做好准备,从易失性文件句柄过期时恢复。如果服务器返回持久化文件句柄,则客户端不需要这些附加步骤。

For volatile filehandles, most commonly the client will need to store the component names leading up to and including the file system object in question. With these names, the client should be able to recover by finding a filehandle in the name space that is still available or by starting at the root of the server's file system name space.

对于易失性文件句柄,最常见的情况是,客户机需要存储指向并包括所讨论的文件系统对象的组件名称。有了这些名称,客户端应该能够通过在名称空间中找到仍然可用的文件句柄或从服务器文件系统名称空间的根开始进行恢复。

If the expired filehandle refers to an object that has been removed from the file system, obviously the client will not be able to recover from the expired filehandle.

如果过期的filehandle引用了已从文件系统中删除的对象,则客户端显然无法从过期的filehandle中恢复。

It is also possible that the expired filehandle refers to a file that has been renamed. If the file was renamed by another client, again it is possible that the original client will not be able to recover. However, in the case that the client itself is renaming the file and the file is open, it is possible that the client may be able to recover. The client can determine the new path name based on the processing of the rename request. The client can then regenerate the new filehandle based on the new path name. The client could also use the compound operation mechanism to construct a set of operations like:

过期的文件句柄也可能引用已重命名的文件。如果文件被另一个客户端重命名,则原始客户端也可能无法恢复。但是,如果客户机本身正在重命名文件并且文件已打开,则客户机可能能够恢复。客户端可以根据重命名请求的处理来确定新的路径名。然后,客户机可以基于新的路径名重新生成新的文件句柄。客户端还可以使用复合操作机制构建一组操作,如:

RENAME A B LOOKUP B GETFH

重命名A B查找B GETFH

5. File Attributes
5. 文件属性

To meet the requirements of extensibility and increased interoperability with non-Unix platforms, attributes must be handled in a flexible manner. The NFS Version 3 fattr3 structure contains a fixed list of attributes that not all clients and servers are able to support or care about. The fattr3 structure can not be extended as new needs arise and it provides no way to indicate non-support. With the NFS Version 4 protocol, the client will be able to ask what attributes the server supports and will be able to request only those attributes in which it is interested.

为了满足可扩展性和与非Unix平台增强互操作性的要求,必须以灵活的方式处理属性。NFS版本3 fattr3结构包含一个固定的属性列表,并非所有客户端和服务器都能够支持或关心这些属性。fattr3结构不能随着新需求的出现而扩展,也无法表示不支持。使用NFS Version 4协议,客户机将能够询问服务器支持哪些属性,并且只能够请求它感兴趣的那些属性。

To this end, attributes will be divided into three groups: mandatory, recommended, and named. Both mandatory and recommended attributes are supported in the NFS version 4 protocol by a specific and well-defined encoding and are identified by number. They are requested by setting a bit in the bit vector sent in the GETATTR request; the server response includes a bit vector to list what attributes were returned in the response. New mandatory or recommended attributes may be added to the NFS protocol between major revisions by publishing a standards-track RFC which allocates a new attribute number value and defines the encoding for the attribute. See the section "Minor Versioning" for further discussion.

为此,属性将分为三组:强制、推荐和命名。在NFS版本4协议中,强制属性和推荐属性都由特定的、定义良好的编码支持,并由数字标识。通过在GETATTR请求中发送的位向量中设置位来请求它们;服务器响应包含一个位向量,用于列出响应中返回的属性。在主要修订之间,可以通过发布标准跟踪RFC向NFS协议添加新的强制或推荐属性,该RFC分配新的属性编号值并定义属性的编码。有关进一步的讨论,请参阅“次要版本控制”一节。

Named attributes are accessed by the new OPENATTR operation, which accesses a hidden directory of attributes associated with a file system object. OPENATTR takes a filehandle for the object and returns the filehandle for the attribute hierarchy. The filehandle for the named attributes is a directory object accessible by LOOKUP

命名属性由新的OPENATTR操作访问,该操作访问与文件系统对象关联的属性的隐藏目录。OPENATTR获取对象的文件句柄,并返回属性层次结构的文件句柄。命名属性的文件句柄是可通过查找访问的目录对象

or READDIR and contains files whose names represent the named attributes and whose data bytes are the value of the attribute. For example:

或READDIR,并包含其名称表示命名属性且其数据字节为属性值的文件。例如:

LOOKUP "foo" ; look up file GETATTR attrbits OPENATTR ; access foo's named attributes LOOKUP "x11icon" ; look up specific attribute READ 0,4096 ; read stream of bytes

查找“foo”;查找文件GETATTR attrbits OPENATTR;访问foo的命名属性查找“x11icon”;查找特定属性读取04096;读取字节流

Named attributes are intended for data needed by applications rather than by an NFS client implementation. NFS implementors are strongly encouraged to define their new attributes as recommended attributes by bringing them to the IETF standards-track process.

命名属性用于应用程序而不是NFS客户端实现所需的数据。强烈鼓励NFS实现者通过将其引入IETF标准跟踪过程,将其新属性定义为推荐属性。

The set of attributes which are classified as mandatory is deliberately small since servers must do whatever it takes to support them. The recommended attributes may be unsupported; though a server should support as many as it can. Attributes are deemed mandatory if the data is both needed by a large number of clients and is not otherwise reasonably computable by the client when support is not provided on the server.

由于服务器必须尽一切努力来支持这些属性,因此被归类为强制的属性集故意较小。建议的属性可能不受支持;尽管服务器应该尽可能多地支持。如果大量客户机都需要这些数据,并且当服务器上没有提供支持时,客户机无法合理地计算这些数据,则这些属性被视为是必需的。

5.1. Mandatory Attributes
5.1. 强制性属性

These MUST be supported by every NFS Version 4 client and server in order to ensure a minimum level of interoperability. The server must store and return these attributes and the client must be able to function with an attribute set limited to these attributes. With just the mandatory attributes some client functionality may be impaired or limited in some ways. A client may ask for any of these attributes to be returned by setting a bit in the GETATTR request and the server must return their value.

为了确保最低级别的互操作性,每个NFS版本4客户端和服务器都必须支持这些功能。服务器必须存储并返回这些属性,客户机必须能够使用限制于这些属性的属性集运行。仅使用强制属性,某些客户端功能可能会在某些方面受到损害或限制。客户机可以通过在GETATTR请求中设置一个位来请求返回这些属性中的任何一个,服务器必须返回它们的值。

5.2. Recommended Attributes
5.2. 推荐属性

These attributes are understood well enough to warrant support in the NFS Version 4 protocol. However, they may not be supported on all clients and servers. A client may ask for any of these attributes to be returned by setting a bit in the GETATTR request but must handle the case where the server does not return them. A client may ask for the set of attributes the server supports and should not request attributes the server does not support. A server should be tolerant of requests for unsupported attributes and simply not return them rather than considering the request an error. It is expected that servers will support all attributes they comfortably can and only fail to support attributes which are difficult to support in their operating environments. A server should provide attributes whenever

对这些属性的理解足以保证NFS版本4协议中的支持。但是,并非所有客户端和服务器都支持它们。客户机可以通过在GETATTR请求中设置一个位来请求返回这些属性中的任何一个,但必须处理服务器不返回这些属性的情况。客户端可能要求服务器支持的属性集,但不应要求服务器不支持的属性集。服务器应该能够容忍对不受支持的属性的请求,并且不返回它们,而不是将请求视为错误。预计服务器将支持其能够轻松支持的所有属性,并且只支持在其操作环境中难以支持的属性。无论何时,服务器都应该提供属性

they don't have to "tell lies" to the client. For example, a file modification time should be either an accurate time or should not be supported by the server. This will not always be comfortable to clients but it seems that the client has a better ability to fabricate or construct an attribute or do without the attribute.

他们不必对客户“撒谎”。例如,文件修改时间应该是准确的时间,或者服务器不支持。这对客户来说并不总是舒适的,但似乎客户有更好的能力来制造或构造属性,或者不使用属性。

5.3. Named Attributes
5.3. 命名属性

These attributes are not supported by direct encoding in the NFS Version 4 protocol but are accessed by string names rather than numbers and correspond to an uninterpreted stream of bytes which are stored with the file system object. The name space for these attributes may be accessed by using the OPENATTR operation. The OPENATTR operation returns a filehandle for a virtual "attribute directory" and further perusal of the name space may be done using READDIR and LOOKUP operations on this filehandle. Named attributes may then be examined or changed by normal READ and WRITE and CREATE operations on the filehandles returned from READDIR and LOOKUP. Named attributes may have attributes.

NFS版本4协议中的直接编码不支持这些属性,但可以通过字符串名称而不是数字来访问这些属性,并与存储在文件系统对象中的未解释的字节流相对应。可以使用OPENATTR操作访问这些属性的名称空间。OPENATTR操作返回虚拟“属性目录”的文件句柄,可以使用READDIR和该文件句柄上的查找操作进一步阅读名称空间。然后,可以通过对从READDIR和LOOKUP返回的文件句柄执行常规读写和创建操作来检查或更改命名属性。命名属性可能具有属性。

It is recommended that servers support arbitrary named attributes. A client should not depend on the ability to store any named attributes in the server's file system. If a server does support named attributes, a client which is also able to handle them should be able to copy a file's data and meta-data with complete transparency from one location to another; this would imply that names allowed for regular directory entries are valid for named attribute names as well.

建议服务器支持任意命名属性。客户端不应依赖于在服务器的文件系统中存储任何命名属性的能力。如果服务器确实支持命名属性,那么能够处理这些属性的客户端应该能够完全透明地将文件的数据和元数据从一个位置复制到另一个位置;这意味着常规目录项允许的名称对于命名属性名称也是有效的。

Names of attributes will not be controlled by this document or other IETF standards track documents. See the section "IANA Considerations" for further discussion.

属性名称不受本文件或其他IETF标准跟踪文件的控制。有关进一步的讨论,请参见“IANA注意事项”一节。

5.4. Mandatory Attributes - Definitions
5.4. 强制性属性-定义
   Name              #    DataType     Access   Description
   ___________________________________________________________________
   supp_attr         0    bitmap       READ     The bit vector which
                                                would retrieve all
                                                mandatory and
                                                recommended attributes
                                                that are supported for
                                                this object.
        
   Name              #    DataType     Access   Description
   ___________________________________________________________________
   supp_attr         0    bitmap       READ     The bit vector which
                                                would retrieve all
                                                mandatory and
                                                recommended attributes
                                                that are supported for
                                                this object.
        

type 1 nfs4_ftype READ The type of the object (file, directory, symlink)

类型1 nfs4\u ftype读取对象的类型(文件、目录、符号链接)

fh_expire_type 2 uint32 READ Server uses this to specify filehandle expiration behavior to the client. See the section "Filehandles" for additional description.

fh_expire_类型2 uint32读取服务器使用此选项指定客户端的文件句柄过期行为。有关更多说明,请参见“文件句柄”一节。

change 3 uint64 READ A value created by the server that the client can use to determine if file data, directory contents or attributes of the object have been modified. The server may return the object's time_modify attribute for this attribute's value but only if the file system object can not be updated more frequently than the resolution of time_modify.

change 3 uint64读取服务器创建的值,客户端可使用该值确定对象的文件数据、目录内容或属性是否已修改。服务器可以为该属性的值返回对象的time\u modify属性,但前提是文件系统对象的更新频率不能超过time\u modify的分辨率。

size 4 uint64 R/W The size of the object in bytes.

大小4 uint64 R/W对象的大小(字节)。

link_support 5 boolean READ Does the object's file system supports hard links?

链接\支持5布尔读取对象的文件系统是否支持硬链接?

symlink_support 6 boolean READ Does the object's file system supports symbolic links?

符号链接\支持6布尔读取对象的文件系统是否支持符号链接?

named_attr 7 boolean READ Does this object have named attributes?

命名\u attr 7布尔读取此对象是否具有命名属性?

fsid 8 fsid4 READ Unique file system identifier for the file system holding this object. fsid contains major and minor components each of which are uint64.

fsid 8 fsid4读取包含此对象的文件系统的唯一文件系统标识符。fsid包含主要和次要组件,每个组件都是uint64。

unique_handles 9 boolean READ Are two distinct filehandles guaranteed to refer to two different file system objects?

unique_handles 9布尔读取两个不同的文件句柄是否保证引用两个不同的文件系统对象?

lease_time 10 nfs_lease4 READ Duration of leases at server in seconds.

租约时间10 nfs租约4服务器上租约的读取持续时间(秒)。

rdattr_error 11 enum READ Error returned from getattr during readdir.

rdattr_错误11 readdir期间从getattr返回的枚举读取错误。

5.5. Recommended Attributes - Definitions
5.5. 推荐属性-定义
   Name               #    Data Type      Access   Description
   _____________________________________________________________________
   ACL                12   nfsace4<>      R/W      The access control
                                                   list for the object.
        
   Name               #    Data Type      Access   Description
   _____________________________________________________________________
   ACL                12   nfsace4<>      R/W      The access control
                                                   list for the object.
        

aclsupport 13 uint32 READ Indicates what types of ACLs are supported on the current file system.

aclsupport 13 uint32 READ指示当前文件系统支持哪些类型的ACL。

archive 14 boolean R/W Whether or not this file has been archived since the time of last modification (deprecated in favor of time_backup).

存档14布尔值R/W自上次修改后是否已存档此文件(不推荐使用时间备份)。

cansettime 15 boolean READ Is the server able to change the times for a file system object as specified in a SETATTR operation?

cansettime 15布尔读取服务器是否能够更改SETATTR操作中指定的文件系统对象的时间?

case_insensitive 16 boolean READ Are filename comparisons on this file system case insensitive?

此文件系统上的文件名比较是否不区分大小写?

case_preserving 17 boolean READ Is filename case on this file system preserved?

保留大小写17布尔读取文件系统上的文件名大小写是否保留?

chown_restricted 18 boolean READ If TRUE, the server will reject any request to change either the owner or the group associated with a file if the caller is not a privileged user (for example, "root" in Unix operating environments or in NT the "Take Ownership" privilege)

chown_restricted 18 boolean READ如果为TRUE,则如果调用方不是特权用户(例如,Unix操作环境中的“root”或NT中的“Take owner”特权),服务器将拒绝任何更改与文件关联的所有者或组的请求

filehandle 19 nfs4_fh READ The filehandle of this object (primarily for readdir requests).

filehandle 19 nfs4_fh读取此对象的filehandle(主要用于readdir请求)。

fileid 20 uint64 READ A number uniquely identifying the file within the file system.

fileid 20 uint64读取文件系统中唯一标识文件的数字。

files_avail 21 uint64 READ File slots available to this user on the file system containing this object - this should be the smallest relevant limit.

在包含此对象的文件系统上,此用户可使用的文件\u avail 21 uint64读取文件插槽-这应该是最小的相关限制。

files_free 22 uint64 READ Free file slots on the file system containing this object - this should be the smallest relevant limit.

包含此对象的文件系统上的文件\u free 22 uint64只读文件插槽-这应该是最小的相关限制。

files_total 23 uint64 READ Total file slots on the file system containing this object.

文件\u total 23 uint64读取包含此对象的文件系统上的文件插槽总数。

fs_locations 24 fs_locations READ Locations where this file system may be found. If the server returns NFS4ERR_MOVED as an error, this attribute must be supported.

fs_位置24个fs_位置读取可以找到此文件系统的位置。如果服务器返回NFS4ERR_MOVED作为错误,则必须支持此属性。

hidden 25 boolean R/W Is file considered hidden with respect to the WIN32 API?

隐藏25布尔R/W文件相对于WIN32 API是否被认为是隐藏的?

homogeneous 26 boolean READ Whether or not this object's file system is homogeneous, i.e. are per file system attributes the same for all file system's objects.

同构26布尔读取此对象的文件系统是否同构,即每个文件系统的属性对于所有文件系统的对象是否相同。

maxfilesize 27 uint64 READ Maximum supported file size for the file system of this object.

maxfilesize 27 uint64读取此对象的文件系统支持的最大文件大小。

maxlink 28 uint32 READ Maximum number of links for this object.

maxlink 28 uint32读取此对象的最大链接数。

maxname 29 uint32 READ Maximum filename size supported for this object.

maxname 29 uint32读取此对象支持的最大文件名大小。

maxread 30 uint64 READ Maximum read size supported for this object.

maxread 30 uint64读取此对象支持的最大读取大小。

maxwrite 31 uint64 READ Maximum write size supported for this object. This attribute SHOULD be supported if the file is writable. Lack of this attribute can lead to the client either wasting

maxwrite 31 uint64读取此对象支持的最大写入大小。如果文件可写,则应支持此属性。缺少此属性可能会导致客户端浪费

bandwidth or not receiving the best performance.

带宽或接收不到最佳性能。

mimetype 32 utf8<> R/W MIME body type/subtype of this object.

mimetype 32 utf8<>R/W此对象的MIME主体类型/子类型。

mode 33 mode4 R/W Unix-style permission bits for this object (deprecated in favor of ACLs)

此对象的模式33 mode4 R/W Unix样式权限位(不推荐使用ACL)

no_trunc 34 boolean READ If a name longer than name_max is used, will an error be returned or will the name be truncated?

no_trunc 34 boolean READ如果使用的名称长度超过name_max,会返回错误还是会截断名称?

numlinks 35 uint32 READ Number of hard links to this object.

numlinks 35 uint32读取到此对象的硬链接数。

owner 36 utf8<> R/W The string name of the owner of this object.

owner 36 utf8<>R/W此对象所有者的字符串名称。

owner_group 37 utf8<> R/W The string name of the group ownership of this object.

owner\u group 37 utf8<>R/W此对象的组所有权的字符串名称。

quota_avail_hard 38 uint64 READ For definition see "Quota Attributes" section below.

quota\u avail\u hard 38 uint64读取定义见下文“quota Attributes”一节。

quota_avail_soft 39 uint64 READ For definition see "Quota Attributes" section below.

quota_avail_soft 39 uint64读取有关定义,请参阅下面的“配额属性”部分。

quota_used 40 uint64 READ For definition see "Quota Attributes" section below.

配额使用40 uint64读取定义见下文“配额属性”部分。

rawdev 41 specdata4 READ Raw device identifier. Unix device major/minor node information.

rawdev 41 SPECDATA读取原始设备标识符。Unix设备主要/次要节点信息。

space_avail 42 uint64 READ Disk space in bytes available to this user on the file system containing this object - this should be the smallest relevant limit.

在包含此对象的文件系统上,此用户可用的空间(以字节为单位)应为最小的相关限制。

space_free 43 uint64 READ Free disk space in bytes on the file system containing this object - this should be the smallest relevant limit.

空间\u free 43 uint64包含此对象的文件系统上的可用读取磁盘空间(字节)-这应该是最小的相关限制。

space_total 44 uint64 READ Total disk space in bytes on the file system containing this object.

space_total 44 uint64读取包含此对象的文件系统上的总磁盘空间(字节)。

space_used 45 uint64 READ Number of file system bytes allocated to this object.

空间_使用了45 uint64读取分配给此对象的文件系统字节数。

system 46 boolean R/W Is this file a system file with respect to the WIN32 API?

system 46 boolean R/W相对于WIN32 API,此文件是系统文件吗?

time_access 47 nfstime4 READ The time of last access to the object.

time_access 47 nfstime4读取上次访问对象的时间。

time_access_set 48 settime4 WRITE Set the time of last access to the object. SETATTR use only.

时间\访问\设置48 settime4写入设置上次访问对象的时间。SETATTR仅用于。

time_backup 49 nfstime4 R/W The time of last backup of the object.

时间备份49 nfstime4 R/W对象的上次备份时间。

time_create 50 nfstime4 R/W The time of creation of the object. This attribute does not have any relation to the traditional Unix file attribute "ctime" or "change time".

时间\u创建50 nfstime4 R/W对象的创建时间。此属性与传统的Unix文件属性“ctime”或“更改时间”没有任何关系。

time_delta 51 nfstime4 READ Smallest useful server time granularity.

时间增量51 nfstime4读取最小有用的服务器时间粒度。

time_metadata 52 nfstime4 R/W The time of last meta-data modification of the object.

time_metadata 52 nfstime4 R/W对象最后一次修改元数据的时间。

time_modify 53 nfstime4 READ The time of last modification to the object.

time\ U modify 53 nfstime4读取上次修改对象的时间。

time_modify_set 54 settime4 WRITE Set the time of last modification to the object. SETATTR use only.

时间\修改\设置54 settime4写入设置上次修改对象的时间。SETATTR仅用于。

5.6. Interpreting owner and owner_group
5.6. 解释所有者和所有者组

The recommended attributes "owner" and "owner_group" are represented in terms of a UTF-8 string. To avoid a representation that is tied to a particular underlying implementation at the client or server, the use of the UTF-8 string has been chosen. Note that section 6.1 of [RFC2624] provides additional rationale. It is expected that the client and server will have their own local representation of owner and owner_group that is used for local storage or presentation to the end user. Therefore, it is expected that when these attributes are transferred between the client and server that the local representation is translated to a syntax of the form "user@dns_domain". This will allow for a client and server that do not use the same local representation the ability to translate to a common syntax that can be interpreted by both.

推荐的属性“owner”和“owner\u group”用UTF-8字符串表示。为了避免在客户端或服务器上绑定到特定底层实现的表示,选择使用UTF-8字符串。请注意,[RFC2624]第6.1节提供了额外的基本原理。预期客户端和服务器将拥有自己的本地所有者和所有者组表示,用于本地存储或向最终用户演示。因此,当这些属性在客户机和服务器之间传输时,本地表示将被转换为以下形式的语法:user@dns_domain". 这将允许不使用相同本地表示的客户机和服务器能够转换为可由两者解释的公共语法。

The translation is not specified as part of the protocol. This allows various solutions to be employed. For example, a local translation table may be consulted that maps between a numeric id to the user@dns_domain syntax. A name service may also be used to accomplish the translation. The "dns_domain" portion of the owner string is meant to be a DNS domain name. For example, user@ietf.org.

翻译未指定为协议的一部分。这允许采用各种解决方案。例如,可以参考本地转换表,该表将数字id映射到user@dns_domain语法。名称服务也可用于完成翻译。所有者字符串的“dns_域”部分是指dns域名。例如user@ietf.org.

In the case where there is no translation available to the client or server, the attribute value must be constructed without the "@". Therefore, the absence of the @ from the owner or owner_group attribute signifies that no translation was available and the receiver of the attribute should not place any special meaning with

如果客户端或服务器没有可用的转换,则必须构造属性值,而不带“@”。因此,如果owner或owner_group属性中没有@,则表示没有可用的翻译,并且该属性的接收者不应将任何特殊含义置于

the attribute value. Even though the attribute value can not be translated, it may still be useful. In the case of a client, the attribute string may be used for local display of ownership.

属性值。即使无法转换属性值,它仍然可能有用。对于客户端,属性字符串可用于本地显示所有权。

5.7. Character Case Attributes
5.7. 字符大小写属性

With respect to the case_insensitive and case_preserving attributes, each UCS-4 character (which UTF-8 encodes) has a "long descriptive name" [RFC1345] which may or may not included the word "CAPITAL" or "SMALL". The presence of SMALL or CAPITAL allows an NFS server to implement unambiguous and efficient table driven mappings for case insensitive comparisons, and non-case-preserving storage. For general character handling and internationalization issues, see the section "Internationalization".

对于不区分大小写和保留大小写的属性,每个UCS-4字符(UTF-8编码)都有一个“长描述性名称”[RFC1345],其中可能包括也可能不包括单词“大写”或“小写”。小型或大型数据库的存在使NFS服务器能够实现明确且高效的表驱动映射,以进行不区分大小写的比较,并实现不区分大小写的存储。有关一般字符处理和国际化问题,请参阅“国际化”一节。

5.8. Quota Attributes
5.8. 配额属性

For the attributes related to file system quotas, the following definitions apply:

对于与文件系统配额相关的属性,以下定义适用:

quota_avail_soft The value in bytes which represents the amount of additional disk space that can be allocated to this file or directory before the user may reasonably be warned. It is understood that this space may be consumed by allocations to other files or directories though there is a rule as to which other files or directories.

quota_avail_soft以字节为单位的值,表示在合理警告用户之前可以分配给此文件或目录的额外磁盘空间量。可以理解的是,分配给其他文件或目录时可能会占用此空间,尽管有一条关于其他文件或目录的规则。

quota_avail_hard The value in bytes which represent the amount of additional disk space beyond the current allocation that can be allocated to this file or directory before further allocations will be refused. It is understood that this space may be consumed by allocations to other files or directories.

quota_avail_hard以字节为单位的值,表示在拒绝进一步分配之前,当前分配之外可分配给此文件或目录的额外磁盘空间量。可以理解的是,分配给其他文件或目录可能会占用此空间。

quota_used The value in bytes which represent the amount of disc space used by this file or directory and possibly a number of other similar files or directories, where the set of "similar" meets at least the criterion that allocating space to any file or directory in the set will reduce the "quota_avail_hard" of every other file or directory in the set.

quota_使用字节值,表示此文件或目录以及可能的许多其他类似文件或目录使用的磁盘空间量,其中“相似”集合至少满足将空间分配给集合中的任何文件或目录将减少“quota_avail_hard”的标准集合中的所有其他文件或目录。

Note that there may be a number of distinct but overlapping sets of files or directories for which a quota_used value is maintained. E.g. "all files with a given owner", "all files with a given group owner". etc.

请注意,可能存在许多不同但重叠的文件或目录集,这些文件或目录的配额值是为其保留的。例如,“具有给定所有者的所有文件”、“具有给定组所有者的所有文件”。等

The server is at liberty to choose any of those sets but should do so in a repeatable way. The rule may be configured per-filesystem or may be "choose the set with the smallest quota".

服务器可以自由选择这些集合中的任何一个,但应以可重复的方式进行选择。规则可以按文件系统配置,也可以是“选择配额最小的集合”。

5.9. Access Control Lists
5.9. 访问控制列表

The NFS ACL attribute is an array of access control entries (ACE). There are various access control entry types. The server is able to communicate which ACE types are supported by returning the appropriate value within the aclsupport attribute. The types of ACEs are defined as follows:

NFS ACL属性是访问控制项(ACE)的数组。有多种访问控制条目类型。服务器可以通过在aclsupport属性中返回适当的值来通信支持哪些ACE类型。ACE的类型定义如下:

   Type         Description
   _____________________________________________________
   ALLOW        Explicitly grants the access defined in
                acemask4 to the file or directory.
        
   Type         Description
   _____________________________________________________
   ALLOW        Explicitly grants the access defined in
                acemask4 to the file or directory.
        

DENY Explicitly denies the access defined in acemask4 to the file or directory.

DENY显式拒绝acemask4中定义的对文件或目录的访问。

AUDIT LOG (system dependent) any access attempt to a file or directory which uses any of the access methods specified in acemask4.

审核日志(取决于系统)对使用acemask4中指定的任何访问方法的文件或目录的任何访问尝试。

ALARM Generate a system ALARM (system dependent) when any access attempt is made to a file or directory for the access methods specified in acemask4.

报警在尝试访问acemask4中指定的访问方法的文件或目录时,生成系统报警(取决于系统)。

The NFS ACE attribute is defined as follows:

NFS ACE属性定义如下:

   typedef uint32_t        acetype4;
   typedef uint32_t        aceflag4;
   typedef uint32_t        acemask4;
        
   typedef uint32_t        acetype4;
   typedef uint32_t        aceflag4;
   typedef uint32_t        acemask4;
        
   struct nfsace4 {
           acetype4        type;
           aceflag4        flag;
           acemask4        access_mask;
           utf8string      who;
   };
        
   struct nfsace4 {
           acetype4        type;
           aceflag4        flag;
           acemask4        access_mask;
           utf8string      who;
   };
        

To determine if an ACCESS or OPEN request succeeds each nfsace4 entry is processed in order by the server. Only ACEs which have a "who" that matches the requester are considered. Each ACE is processed until all of the bits of the requester's access have been ALLOWED. Once a bit (see below) has been ALLOWED by an ACCESS_ALLOWED_ACE, it

要确定访问或打开请求是否成功,服务器将按顺序处理每个nfsace4条目。仅考虑具有与请求者匹配的“谁”的ACE。处理每个ACE,直到请求者访问的所有位都被允许。一旦一个位(见下文)被允许访问,它就会

is no longer considered in the processing of later ACEs. If an ACCESS_DENIED_ACE is encountered where the requester's mode still has unALLOWED bits in common with the "access_mask" of the ACE, the request is denied.

在以后的ACE处理中不再考虑。如果遇到访问被拒绝的ACE,而请求者的模式仍然具有与ACE的“访问掩码”相同的未允许位,则请求被拒绝。

The bitmask constants used to represent the above definitions within the aclsupport attribute are as follows:

用于在aclsupport属性中表示上述定义的位掩码常量如下所示:

   const ACL4_SUPPORT_ALLOW_ACL    = 0x00000001;
   const ACL4_SUPPORT_DENY_ACL     = 0x00000002;
   const ACL4_SUPPORT_AUDIT_ACL    = 0x00000004;
   const ACL4_SUPPORT_ALARM_ACL    = 0x00000008;
        
   const ACL4_SUPPORT_ALLOW_ACL    = 0x00000001;
   const ACL4_SUPPORT_DENY_ACL     = 0x00000002;
   const ACL4_SUPPORT_AUDIT_ACL    = 0x00000004;
   const ACL4_SUPPORT_ALARM_ACL    = 0x00000008;
        
5.9.1. ACE type
5.9.1. ACE类型

The semantics of the "type" field follow the descriptions provided above.

“type”字段的语义遵循上面提供的描述。

The bitmask constants used for the type field are as follows:

用于类型字段的位掩码常量如下所示:

   const ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
   const ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
   const ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
   const ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
        
   const ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
   const ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
   const ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
   const ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
        
5.9.2. ACE flag
5.9.2. 王牌旗

The "flag" field contains values based on the following descriptions.

“标志”字段包含基于以下描述的值。

ACE4_FILE_INHERIT_ACE

ACE4\u文件\u继承\u ACE

Can be placed on a directory and indicates that this ACE should be added to each new non-directory file created.

可以放置在目录上,并指示应将此ACE添加到创建的每个新非目录文件中。

ACE4_DIRECTORY_INHERIT_ACE

ACE4\u目录\u继承\u ACE

Can be placed on a directory and indicates that this ACE should be added to each new directory created.

可以放置在目录上,并指示应将此ACE添加到创建的每个新目录中。

ACE4_INHERIT_ONLY_ACE

ACE4\u仅继承\u\u ACE

Can be placed on a directory but does not apply to the directory, only to newly created files/directories as specified by the above two flags.

可以放置在目录上,但不适用于该目录,仅适用于由上述两个标志指定的新创建的文件/目录。

ACE4_NO_PROPAGATE_INHERIT_ACE

ACE4\u否\u传播\u继承\u ACE

Can be placed on a directory. Normally when a new directory is created and an ACE exists on the parent directory which is marked ACL4_DIRECTORY_INHERIT_ACE, two ACEs are placed on the new directory. One for the directory itself and one which is an inheritable ACE for newly created directories. This flag tells the server to not place an ACE on the newly created directory which is inheritable by subdirectories of the created directory.

可以放置在目录中。通常,当创建一个新目录并且父目录(标记为ACL4_directory_INHERIT_ACE)上存在一个ACE时,两个ACE将放置在新目录上。一个用于目录本身,另一个用于新创建目录的可继承ACE。此标志告诉服务器不要在新创建的目录上放置ACE,该目录可由已创建目录的子目录继承。

ACE4_SUCCESSFUL_ACCESS_ACE_FLAG

ACE4\u成功访问\u ACE\u标志

ACL4_FAILED_ACCESS_ACE_FLAG

ACL4\u访问失败\u ACE\u标志

Both indicate for AUDIT and ALARM which state to log the event. On every ACCESS or OPEN call which occurs on a file or directory which has an ACL that is of type ACE4_SYSTEM_AUDIT_ACE_TYPE or ACE4_SYSTEM_ALARM_ACE_TYPE, the attempted access is compared to the ace4mask of these ACLs. If the access is a subset of ace4mask and the identifier match, an AUDIT trail or an ALARM is generated. By default this happens regardless of the success or failure of the ACCESS or OPEN call.

两者都指示审计和报警记录事件的状态。在具有类型为ACE4\u SYSTEM\u AUDIT\u ACE\u类型或ACE4\u SYSTEM\u ALARM\u ACE\u类型的ACL的文件或目录上发生的每次访问或打开调用中,将尝试的访问与这些ACL的ace4mask进行比较。如果访问是ace4mask的子集,且标识符匹配,则会生成审核跟踪或报警。默认情况下,无论访问或打开调用是否成功,都会发生这种情况。

The flag ACE4_SUCCESSFUL_ACCESS_ACE_FLAG only produces the AUDIT or ALARM if the ACCESS or OPEN call is successful. The ACE4_FAILED_ACCESS_ACE_FLAG causes the ALARM or AUDIT if the ACCESS or OPEN call fails.

ACE4_SUCCESSFUL_ACCESS_ACE_标志仅在访问或打开调用成功时生成审核或警报。如果访问或打开调用失败,ACE4_FAILED_ACCESS_ACE_标志将导致报警或审核。

ACE4_IDENTIFIER_GROUP

ACE4_标识符_组

Indicates that the "who" refers to a GROUP as defined under Unix.

表示“who”是指在Unix下定义的组。

The bitmask constants used for the flag field are as follows:

用于标志字段的位掩码常数如下所示:

   const ACE4_FILE_INHERIT_ACE             = 0x00000001;
   const ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
   const ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
   const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
   const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
   const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
   const ACE4_IDENTIFIER_GROUP             = 0x00000040;
        
   const ACE4_FILE_INHERIT_ACE             = 0x00000001;
   const ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
   const ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
   const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
   const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
   const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
   const ACE4_IDENTIFIER_GROUP             = 0x00000040;
        
5.9.3. ACE Access Mask
5.9.3. ACE访问掩码

The access_mask field contains values based on the following:

access_mask字段包含基于以下内容的值:

   Access                 Description
   _______________________________________________________________
   READ_DATA              Permission to read the data of the file
   LIST_DIRECTORY         Permission to list the contents of a
                          directory
   WRITE_DATA             Permission to modify the file's data
   ADD_FILE               Permission to add a new file to a
                          directory
   APPEND_DATA            Permission to append data to a file
   ADD_SUBDIRECTORY       Permission to create a subdirectory to a
                          directory
   READ_NAMED_ATTRS       Permission to read the named attributes
                          of a file
   WRITE_NAMED_ATTRS      Permission to write the named attributes
                          of a file
   EXECUTE                Permission to execute a file
   DELETE_CHILD           Permission to delete a file or directory
                          within a directory
   READ_ATTRIBUTES        The ability to read basic attributes
                          (non-acls) of a file
   WRITE_ATTRIBUTES       Permission to change basic attributes
                          (non-acls) of a file
        
   Access                 Description
   _______________________________________________________________
   READ_DATA              Permission to read the data of the file
   LIST_DIRECTORY         Permission to list the contents of a
                          directory
   WRITE_DATA             Permission to modify the file's data
   ADD_FILE               Permission to add a new file to a
                          directory
   APPEND_DATA            Permission to append data to a file
   ADD_SUBDIRECTORY       Permission to create a subdirectory to a
                          directory
   READ_NAMED_ATTRS       Permission to read the named attributes
                          of a file
   WRITE_NAMED_ATTRS      Permission to write the named attributes
                          of a file
   EXECUTE                Permission to execute a file
   DELETE_CHILD           Permission to delete a file or directory
                          within a directory
   READ_ATTRIBUTES        The ability to read basic attributes
                          (non-acls) of a file
   WRITE_ATTRIBUTES       Permission to change basic attributes
                          (non-acls) of a file
        

DELETE Permission to Delete the file READ_ACL Permission to Read the ACL WRITE_ACL Permission to Write the ACL WRITE_OWNER Permission to change the owner SYNCHRONIZE Permission to access file locally at the server with synchronous reads and writes

DELETE Permission删除文件的步骤READ\u ACL Permission读取ACL WRITE\u ACL Permission写入ACL WRITE\u OWNER Permission更改OWNER SYNCHRONIZE Permission以同步读写方式在服务器本地访问文件的步骤

The bitmask constants used for the access mask field are as follows:

用于访问掩码字段的位掩码常数如下所示:

   const ACE4_READ_DATA            = 0x00000001;
   const ACE4_LIST_DIRECTORY       = 0x00000001;
   const ACE4_WRITE_DATA           = 0x00000002;
   const ACE4_ADD_FILE             = 0x00000002;
   const ACE4_APPEND_DATA          = 0x00000004;
   const ACE4_ADD_SUBDIRECTORY     = 0x00000004;
   const ACE4_READ_NAMED_ATTRS     = 0x00000008;
   const ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
   const ACE4_EXECUTE              = 0x00000020;
   const ACE4_DELETE_CHILD         = 0x00000040;
   const ACE4_READ_ATTRIBUTES      = 0x00000080;
   const ACE4_WRITE_ATTRIBUTES     = 0x00000100;
        
   const ACE4_READ_DATA            = 0x00000001;
   const ACE4_LIST_DIRECTORY       = 0x00000001;
   const ACE4_WRITE_DATA           = 0x00000002;
   const ACE4_ADD_FILE             = 0x00000002;
   const ACE4_APPEND_DATA          = 0x00000004;
   const ACE4_ADD_SUBDIRECTORY     = 0x00000004;
   const ACE4_READ_NAMED_ATTRS     = 0x00000008;
   const ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
   const ACE4_EXECUTE              = 0x00000020;
   const ACE4_DELETE_CHILD         = 0x00000040;
   const ACE4_READ_ATTRIBUTES      = 0x00000080;
   const ACE4_WRITE_ATTRIBUTES     = 0x00000100;
        
   const ACE4_DELETE               = 0x00010000;
   const ACE4_READ_ACL             = 0x00020000;
   const ACE4_WRITE_ACL            = 0x00040000;
   const ACE4_WRITE_OWNER          = 0x00080000;
   const ACE4_SYNCHRONIZE          = 0x00100000;
        
   const ACE4_DELETE               = 0x00010000;
   const ACE4_READ_ACL             = 0x00020000;
   const ACE4_WRITE_ACL            = 0x00040000;
   const ACE4_WRITE_OWNER          = 0x00080000;
   const ACE4_SYNCHRONIZE          = 0x00100000;
        
5.9.4. ACE who
5.9.4. 王牌谁

There are several special identifiers ("who") which need to be understood universally. Some of these identifiers cannot be understood when an NFS client accesses the server, but have meaning when a local process accesses the file. The ability to display and modify these permissions is permitted over NFS.

有几个特殊标识符(“世卫组织”)需要得到普遍理解。其中一些标识符在NFS客户端访问服务器时无法理解,但在本地进程访问文件时具有意义。允许通过NFS显示和修改这些权限。

   Who                    Description
   _______________________________________________________________
   "OWNER"                The owner of the file.
   "GROUP"                The group associated with the file.
   "EVERYONE"             The world.
   "INTERACTIVE"          Accessed from an interactive terminal.
   "NETWORK"              Accessed via the network.
   "DIALUP"               Accessed as a dialup user to the server.
   "BATCH"                Accessed from a batch job.
   "ANONYMOUS"            Accessed without any authentication.
   "AUTHENTICATED"        Any authenticated user (opposite of
                          ANONYMOUS)
   "SERVICE"              Access from a system service.
        
   Who                    Description
   _______________________________________________________________
   "OWNER"                The owner of the file.
   "GROUP"                The group associated with the file.
   "EVERYONE"             The world.
   "INTERACTIVE"          Accessed from an interactive terminal.
   "NETWORK"              Accessed via the network.
   "DIALUP"               Accessed as a dialup user to the server.
   "BATCH"                Accessed from a batch job.
   "ANONYMOUS"            Accessed without any authentication.
   "AUTHENTICATED"        Any authenticated user (opposite of
                          ANONYMOUS)
   "SERVICE"              Access from a system service.
        

To avoid conflict, these special identifiers are distinguish by an appended "@" and should appear in the form "xxxx@" (note: no domain name after the "@"). For example: ANONYMOUS@.

为避免冲突,这些特殊标识符通过附加的“@”加以区分,并应以“xxxx@”的形式出现(注:“@”后面没有域名)。例如:ANONYMOUS@.

6. File System Migration and Replication
6. 文件系统迁移和复制

With the use of the recommended attribute "fs_locations", the NFS version 4 server has a method of providing file system migration or replication services. For the purposes of migration and replication, a file system will be defined as all files that share a given fsid (both major and minor values are the same).

通过使用推荐的属性“fs_locations”,NFS版本4服务器可以提供文件系统迁移或复制服务。出于迁移和复制的目的,文件系统将定义为共享给定fsid的所有文件(主值和次值都相同)。

The fs_locations attribute provides a list of file system locations. These locations are specified by providing the server name (either DNS domain or IP address) and the path name representing the root of the file system. Depending on the type of service being provided, the list will provide a new location or a set of alternate locations for the file system. The client will use this information to redirect its requests to the new server.

fs_locations属性提供文件系统位置的列表。通过提供服务器名称(DNS域或IP地址)和表示文件系统根的路径名来指定这些位置。根据提供的服务类型,列表将为文件系统提供一个新位置或一组备用位置。客户端将使用此信息将其请求重定向到新服务器。

6.1. Replication
6.1. 复制

It is expected that file system replication will be used in the case of read-only data. Typically, the file system will be replicated on two or more servers. The fs_locations attribute will provide the list of these locations to the client. On first access of the file system, the client should obtain the value of the fs_locations attribute. If, in the future, the client finds the server unresponsive, the client may attempt to use another server specified by fs_locations.

对于只读数据,预计将使用文件系统复制。通常,文件系统将在两个或多个服务器上复制。fs_locations属性将向客户端提供这些位置的列表。在首次访问文件系统时,客户机应获取fs_locations属性的值。如果将来客户端发现服务器无响应,则客户端可能会尝试使用fs_位置指定的另一台服务器。

If applicable, the client must take the appropriate steps to recover valid filehandles from the new server. This is described in more detail in the following sections.

如果适用,客户端必须采取适当的步骤从新服务器恢复有效的文件句柄。以下各节将对此进行更详细的描述。

6.2. Migration
6.2. 迁移

File system migration is used to move a file system from one server to another. Migration is typically used for a file system that is writable and has a single copy. The expected use of migration is for load balancing or general resource reallocation. The protocol does not specify how the file system will be moved between servers. This server-to-server transfer mechanism is left to the server implementor. However, the method used to communicate the migration event between client and server is specified here.

文件系统迁移用于将文件系统从一台服务器移动到另一台服务器。迁移通常用于可写且具有单个副本的文件系统。迁移的预期用途是负载平衡或一般资源重新分配。该协议未指定文件系统在服务器之间移动的方式。这种服务器到服务器的传输机制留给服务器实现者。但是,此处指定了用于在客户端和服务器之间传递迁移事件的方法。

Once the servers participating in the migration have completed the move of the file system, the error NFS4ERR_MOVED will be returned for subsequent requests received by the original server. The NFS4ERR_MOVED error is returned for all operations except GETATTR. Upon receiving the NFS4ERR_MOVED error, the client will obtain the value of the fs_locations attribute. The client will then use the contents of the attribute to redirect its requests to the specified server. To facilitate the use of GETATTR, operations such as PUTFH must also be accepted by the server for the migrated file system's filehandles. Note that if the server returns NFS4ERR_MOVED, the server MUST support the fs_locations attribute.

一旦参与迁移的服务器完成了文件系统的移动,原始服务器收到的后续请求将返回错误NFS4ERR_MOVED。对于除GETATTR之外的所有操作,都会返回NFS4ERR_MOVED错误。在接收到NFS4ERR_MOVED错误后,客户端将获得fs_locations属性的值。然后,客户端将使用该属性的内容将其请求重定向到指定的服务器。为了便于使用GETATTR,服务器还必须接受迁移文件系统的文件句柄的操作,如PUTFH。请注意,如果服务器返回NFS4ERR_MOVED,则服务器必须支持fs_locations属性。

If the client requests more attributes than just fs_locations, the server may return fs_locations only. This is to be expected since the server has migrated the file system and may not have a method of obtaining additional attribute data.

如果客户端请求的属性多于fs\U位置,则服务器可能只返回fs\U位置。这是意料之中的,因为服务器已经迁移了文件系统,并且可能没有获取其他属性数据的方法。

The server implementor needs to be careful in developing a migration solution. The server must consider all of the state information clients may have outstanding at the server. This includes but is not limited to locking/share state, delegation state, and asynchronous

服务器实现者在开发迁移解决方案时需要小心。服务器必须考虑客户端在服务器上可能具有的所有状态信息。这包括但不限于锁定/共享状态、委托状态和异步状态

file writes which are represented by WRITE and COMMIT verifiers. The server should strive to minimize the impact on its clients during and after the migration process.

由写入和提交验证器表示的文件写入。在迁移过程中和迁移后,服务器应尽量减少对其客户端的影响。

6.3. Interpretation of the fs_locations Attribute
6.3. fs_位置属性的解释

The fs_location attribute is structured in the following way:

fs_位置属性的结构如下所示:

   struct fs_location {
           utf8string      server<>;
           pathname4       rootpath;
   };
        
   struct fs_location {
           utf8string      server<>;
           pathname4       rootpath;
   };
        
   struct fs_locations {
           pathname4       fs_root;
           fs_location     locations<>;
   };
        
   struct fs_locations {
           pathname4       fs_root;
           fs_location     locations<>;
   };
        

The fs_location struct is used to represent the location of a file system by providing a server name and the path to the root of the file system. For a multi-homed server or a set of servers that use the same rootpath, an array of server names may be provided. An entry in the server array is an UTF8 string and represents one of a traditional DNS host name, IPv4 address, or IPv6 address. It is not a requirement that all servers that share the same rootpath be listed in one fs_location struct. The array of server names is provided for convenience. Servers that share the same rootpath may also be listed in separate fs_location entries in the fs_locations attribute.

fs_location结构通过提供服务器名称和文件系统根目录的路径来表示文件系统的位置。对于多主机服务器或使用相同根路径的一组服务器,可以提供服务器名称数组。服务器阵列中的条目是UTF8字符串,表示传统DNS主机名、IPv4地址或IPv6地址之一。不要求共享同一根路径的所有服务器都列在一个fs_位置结构中。为方便起见,提供了服务器名称数组。共享相同根路径的服务器也可能列在“fs_位置”属性的单独fs_位置条目中。

The fs_locations struct and attribute then contains an array of locations. Since the name space of each server may be constructed differently, the "fs_root" field is provided. The path represented by fs_root represents the location of the file system in the server's name space. Therefore, the fs_root path is only associated with the server from which the fs_locations attribute was obtained. The fs_root path is meant to aid the client in locating the file system at the various servers listed.

fs_locations结构和属性随后包含一个位置数组。由于每个服务器的名称空间的构造可能不同,因此提供了“fs_root”字段。由fs_root表示的路径表示文件系统在服务器名称空间中的位置。因此,fs_根路径仅与从中获取fs_locations属性的服务器相关联。fs_根路径旨在帮助客户机在列出的各种服务器上定位文件系统。

   As an example, there is a replicated file system located at two
   servers (servA and servB).  At servA the file system is located at
   path "/a/b/c".  At servB the file system is located at path "/x/y/z".
   In this example the client accesses the file system first at servA
   with a multi-component lookup path of "/a/b/c/d".  Since the client
   used a multi-component lookup to obtain the filehandle at "/a/b/c/d",
   it is unaware that the file system's root is located in servA's name
   space at "/a/b/c".  When the client switches to servB, it will need
   to determine that the directory it first referenced at servA is now
   represented by the path "/x/y/z/d" on servB.  To facilitate this, the
        
   As an example, there is a replicated file system located at two
   servers (servA and servB).  At servA the file system is located at
   path "/a/b/c".  At servB the file system is located at path "/x/y/z".
   In this example the client accesses the file system first at servA
   with a multi-component lookup path of "/a/b/c/d".  Since the client
   used a multi-component lookup to obtain the filehandle at "/a/b/c/d",
   it is unaware that the file system's root is located in servA's name
   space at "/a/b/c".  When the client switches to servB, it will need
   to determine that the directory it first referenced at servA is now
   represented by the path "/x/y/z/d" on servB.  To facilitate this, the
        

fs_locations attribute provided by servA would have a fs_root value of "/a/b/c" and two entries in fs_location. One entry in fs_location will be for itself (servA) and the other will be for servB with a path of "/x/y/z". With this information, the client is able to substitute "/x/y/z" for the "/a/b/c" at the beginning of its access path and construct "/x/y/z/d" to use for the new server.

servA提供的fs_locations属性的fs_根值为“/a/b/c”,fs_location中有两个条目。fs_位置中的一个条目将用于自身(servA),另一个条目将用于路径为“/x/y/z”的servB。有了这些信息,客户端可以在其访问路径的开头用“/x/y/z”替换“/a/b/c”,并构造“/x/y/z/d”以用于新服务器。

6.4. Filehandle Recovery for Migration or Replication
6.4. 用于迁移或复制的Filehandle恢复

Filehandles for file systems that are replicated or migrated generally have the same semantics as for file systems that are not replicated or migrated. For example, if a file system has persistent filehandles and it is migrated to another server, the filehandle values for the file system will be valid at the new server.

已复制或迁移的文件系统的文件句柄通常与未复制或迁移的文件系统具有相同的语义。例如,如果一个文件系统具有永久文件句柄,并且该文件系统已迁移到另一台服务器,则该文件系统的文件句柄值将在新服务器上有效。

For volatile filehandles, the servers involved likely do not have a mechanism to transfer filehandle format and content between themselves. Therefore, a server may have difficulty in determining if a volatile filehandle from an old server should return an error of NFS4ERR_FHEXPIRED. Therefore, the client is informed, with the use of the fh_expire_type attribute, whether volatile filehandles will expire at the migration or replication event. If the bit FH4_VOL_MIGRATION is set in the fh_expire_type attribute, the client must treat the volatile filehandle as if the server had returned the NFS4ERR_FHEXPIRED error. At the migration or replication event in the presence of the FH4_VOL_MIGRATION bit, the client will not present the original or old volatile file handle to the new server. The client will start its communication with the new server by recovering its filehandles using the saved file names.

对于易失性文件句柄,涉及的服务器可能没有在它们之间传输文件句柄格式和内容的机制。因此,服务器可能难以确定来自旧服务器的易失性文件句柄是否应返回NFS4ERR_错误。因此,通过使用fh_expire_type属性,将通知客户端volatile filehandles是否将在迁移或复制事件时过期。如果在fh_expired_type属性中设置了位FH4_VOL_MIGRATION,则客户端必须将易失性文件句柄视为服务器已返回NFS4ERR_FHEXPIRED错误。在存在FH4_VOL_迁移位的迁移或复制事件中,客户端将不会向新服务器呈现原始或旧的易失性文件句柄。客户端将通过使用保存的文件名恢复其文件句柄来启动与新服务器的通信。

7. NFS Server Name Space
7. NFS服务器名称空间
7.1. Server Exports
7.1. 服务器导出

On a UNIX server the name space describes all the files reachable by pathnames under the root directory or "/". On a Windows NT server the name space constitutes all the files on disks named by mapped disk letters. NFS server administrators rarely make the entire server's file system name space available to NFS clients. More often portions of the name space are made available via an "export" feature. In previous versions of the NFS protocol, the root filehandle for each export is obtained through the MOUNT protocol; the client sends a string that identifies the export of name space and the server returns the root filehandle for it. The MOUNT protocol supports an EXPORTS procedure that will enumerate the server's exports.

在UNIX服务器上,名称空间描述根目录或“/”下的路径名可访问的所有文件。在Windows NT服务器上,名称空间由磁盘上以映射的磁盘字母命名的所有文件组成。NFS服务器管理员很少使整个服务器的文件系统名称空间可供NFS客户端使用。更常见的情况是,名称空间的一部分通过“导出”功能可用。在以前版本的NFS协议中,每次导出的根文件句柄都是通过MOUNT协议获得的;客户端发送标识名称空间导出的字符串,服务器返回名称空间的根文件句柄。装载协议支持导出过程,该过程将枚举服务器的导出。

7.2. Browsing Exports
7.2. 浏览导出

The NFS version 4 protocol provides a root filehandle that clients can use to obtain filehandles for these exports via a multi-component LOOKUP. A common user experience is to use a graphical user interface (perhaps a file "Open" dialog window) to find a file via progressive browsing through a directory tree. The client must be able to move from one export to another export via single-component, progressive LOOKUP operations.

NFS版本4协议提供了一个根文件句柄,客户端可以使用该根文件句柄通过多组件查找来获取这些导出的文件句柄。常见的用户体验是使用图形用户界面(可能是文件“打开”对话框窗口)通过逐步浏览目录树来查找文件。客户端必须能够通过单个组件、渐进式查找操作从一个导出移动到另一个导出。

This style of browsing is not well supported by the NFS version 2 and 3 protocols. The client expects all LOOKUP operations to remain within a single server file system. For example, the device attribute will not change. This prevents a client from taking name space paths that span exports.

NFS版本2和3协议不支持这种浏览方式。客户端希望所有查找操作都保留在单个服务器文件系统中。例如,设备属性不会更改。这将防止客户端采用跨越导出的名称空间路径。

An automounter on the client can obtain a snapshot of the server's name space using the EXPORTS procedure of the MOUNT protocol. If it understands the server's pathname syntax, it can create an image of the server's name space on the client. The parts of the name space that are not exported by the server are filled in with a "pseudo file system" that allows the user to browse from one mounted file system to another. There is a drawback to this representation of the server's name space on the client: it is static. If the server administrator adds a new export the client will be unaware of it.

客户机上的自动装载程序可以使用装载协议的导出过程获取服务器名称空间的快照。如果它理解服务器的路径名语法,就可以在客户端上创建服务器名称空间的映像。服务器未导出的名称空间部分由“伪文件系统”填充,该系统允许用户从一个已装入的文件系统浏览到另一个已装入的文件系统。这种在客户机上表示服务器名称空间的方法有一个缺点:它是静态的。如果服务器管理员添加了一个新的导出,客户端将不知道它。

7.3. Server Pseudo File System
7.3. 服务器伪文件系统

NFS version 4 servers avoid this name space inconsistency by presenting all the exports within the framework of a single server name space. An NFS version 4 client uses LOOKUP and READDIR operations to browse seamlessly from one export to another. Portions of the server name space that are not exported are bridged via a "pseudo file system" that provides a view of exported directories only. A pseudo file system has a unique fsid and behaves like a normal, read only file system.

NFS版本4服务器通过在单个服务器名称空间的框架内显示所有导出来避免这种名称空间不一致。NFS版本4客户端使用查找和READDIR操作从一个导出无缝浏览到另一个导出。未导出的服务器名称空间部分通过“伪文件系统”桥接,该系统仅提供导出目录的视图。伪文件系统具有唯一的fsid,其行为类似于普通的只读文件系统。

Based on the construction of the server's name space, it is possible that multiple pseudo file systems may exist. For example,

根据服务器名称空间的构造,可能存在多个伪文件系统。例如

   /a         pseudo file system
   /a/b       real file system
   /a/b/c     pseudo file system
   /a/b/c/d   real file system
        
   /a         pseudo file system
   /a/b       real file system
   /a/b/c     pseudo file system
   /a/b/c/d   real file system
        

Each of the pseudo file systems are consider separate entities and therefore will have a unique fsid.

每个伪文件系统都考虑单独的实体,因此将具有唯一的FSID。

7.4. Multiple Roots
7.4. 多根

The DOS and Windows operating environments are sometimes described as having "multiple roots". File systems are commonly represented as disk letters. MacOS represents file systems as top level names. NFS version 4 servers for these platforms can construct a pseudo file system above these root names so that disk letters or volume names are simply directory names in the pseudo root.

DOS和Windows操作环境有时被描述为具有“多个根”。文件系统通常表示为磁盘字母。MacOS将文件系统表示为顶级名称。这些平台的NFS version 4服务器可以在这些根名称之上构造一个伪文件系统,以便磁盘字母或卷名称只是伪根中的目录名。

7.5. Filehandle Volatility
7.5. 文件句柄波动性

The nature of the server's pseudo file system is that it is a logical representation of file system(s) available from the server. Therefore, the pseudo file system is most likely constructed dynamically when the server is first instantiated. It is expected that the pseudo file system may not have an on disk counterpart from which persistent filehandles could be constructed. Even though it is preferable that the server provide persistent filehandles for the pseudo file system, the NFS client should expect that pseudo file system filehandles are volatile. This can be confirmed by checking the associated "fh_expire_type" attribute for those filehandles in question. If the filehandles are volatile, the NFS client must be prepared to recover a filehandle value (e.g. with a multi-component LOOKUP) when receiving an error of NFS4ERR_FHEXPIRED.

服务器伪文件系统的本质是,它是服务器上可用的文件系统的逻辑表示。因此,伪文件系统最有可能在服务器第一次实例化时动态构建。预计伪文件系统可能没有可用于构造持久化文件句柄的磁盘上副本。尽管服务器最好为伪文件系统提供持久的文件句柄,但NFS客户机应该认为伪文件系统文件句柄是易变的。这可以通过检查相关文件句柄的“fh\u expire\u type”属性来确认。如果文件句柄是易失性的,则NFS客户端必须准备在接收到NFS4ERR_错误时恢复文件句柄值(例如,使用多组件查找)。

7.6. Exported Root
7.6. 导出根

If the server's root file system is exported, one might conclude that a pseudo-file system is not needed. This would be wrong. Assume the following file systems on a server:

如果导出了服务器的根文件系统,可能会得出不需要伪文件系统的结论。这是错误的。假设服务器上有以下文件系统:

            /       disk1  (exported)
            /a      disk2  (not exported)
            /a/b    disk3  (exported)
        
            /       disk1  (exported)
            /a      disk2  (not exported)
            /a/b    disk3  (exported)
        

Because disk2 is not exported, disk3 cannot be reached with simple LOOKUPs. The server must bridge the gap with a pseudo-file system.

由于未导出disk2,因此无法通过简单的查找访问disk3。服务器必须使用伪文件系统来弥补这一差距。

7.7. Mount Point Crossing
7.7. 挂载点交叉口

The server file system environment may be constructed in such a way that one file system contains a directory which is 'covered' or mounted upon by a second file system. For example:

服务器文件系统环境可以这样构造:一个文件系统包含一个被第二个文件系统“覆盖”或挂载的目录。例如:

            /a/b            (file system 1)
            /a/b/c/d        (file system 2)
        
            /a/b            (file system 1)
            /a/b/c/d        (file system 2)
        

The pseudo file system for this server may be constructed to look like:

此服务器的伪文件系统的构造如下所示:

            /               (place holder/not exported)
            /a/b            (file system 1)
            /a/b/c/d        (file system 2)
        
            /               (place holder/not exported)
            /a/b            (file system 1)
            /a/b/c/d        (file system 2)
        

It is the server's responsibility to present the pseudo file system that is complete to the client. If the client sends a lookup request for the path "/a/b/c/d", the server's response is the filehandle of the file system "/a/b/c/d". In previous versions of the NFS protocol, the server would respond with the directory "/a/b/c/d" within the file system "/a/b".

服务器负责向客户端呈现完整的伪文件系统。如果客户端发送路径“/a/b/c/d”的查找请求,则服务器的响应是文件系统“/a/b/c/d”的文件句柄。在以前版本的NFS协议中,服务器将使用文件系统“/a/b”中的目录“/a/b/c/d”进行响应。

The NFS client will be able to determine if it crosses a server mount point by a change in the value of the "fsid" attribute.

NFS客户端将能够通过更改“fsid”属性的值来确定它是否跨越服务器装载点。

7.8. Security Policy and Name Space Presentation
7.8. 安全策略和名称空间表示

The application of the server's security policy needs to be carefully considered by the implementor. One may choose to limit the viewability of portions of the pseudo file system based on the server's perception of the client's ability to authenticate itself properly. However, with the support of multiple security mechanisms and the ability to negotiate the appropriate use of these mechanisms, the server is unable to properly determine if a client will be able to authenticate itself. If, based on its policies, the server chooses to limit the contents of the pseudo file system, the server may effectively hide file systems from a client that may otherwise have legitimate access.

实现者需要仔细考虑服务器安全策略的应用。根据服务器对客户端正确验证自身的能力的感知,可以选择限制伪文件系统部分的可视性。但是,由于支持多种安全机制,并且能够协商这些机制的适当使用,服务器无法正确确定客户机是否能够对自己进行身份验证。如果基于其策略,服务器选择限制伪文件系统的内容,则服务器可以有效地向可能具有合法访问权限的客户端隐藏文件系统。

8. File Locking and Share Reservations
8. 文件锁定和共享保留

Integrating locking into the NFS protocol necessarily causes it to be state-full. With the inclusion of "share" file locks the protocol becomes substantially more dependent on state than the traditional combination of NFS and NLM [XNFS]. There are three components to making this state manageable:

将锁定集成到NFS协议中必然会导致它处于状态完全。由于包含了“共享”文件锁,与NFS和NLM[XNFS]的传统组合相比,协议实质上更加依赖于状态。要使此状态易于管理,有三个组件:

o Clear division between client and server

o 清除客户端和服务器之间的划分

o Ability to reliably detect inconsistency in state between client and server

o 能够可靠地检测客户端和服务器之间状态的不一致性

o Simple and robust recovery mechanisms

o 简单而稳健的恢复机制

In this model, the server owns the state information. The client communicates its view of this state to the server as needed. The client is also able to detect inconsistent state before modifying a file.

在此模型中,服务器拥有状态信息。客户端根据需要将其对此状态的视图传送给服务器。客户端还能够在修改文件之前检测不一致的状态。

To support Win32 "share" locks it is necessary to atomically OPEN or CREATE files. Having a separate share/unshare operation would not allow correct implementation of the Win32 OpenFile API. In order to correctly implement share semantics, the previous NFS protocol mechanisms used when a file is opened or created (LOOKUP, CREATE, ACCESS) need to be replaced. The NFS version 4 protocol has an OPEN operation that subsumes the functionality of LOOKUP, CREATE, and ACCESS. However, because many operations require a filehandle, the traditional LOOKUP is preserved to map a file name to filehandle without establishing state on the server. The policy of granting access or modifying files is managed by the server based on the client's state. These mechanisms can implement policy ranging from advisory only locking to full mandatory locking.

要支持Win32“共享”锁,必须以原子方式打开或创建文件。使用单独的共享/取消共享操作将不允许Win32 OpenFile API的正确实现。为了正确实现共享语义,需要替换以前在打开或创建文件(查找、创建、访问)时使用的NFS协议机制。NFS版本4协议有一个开放操作,包含查找、创建和访问功能。但是,由于许多操作需要文件句柄,因此保留了传统的查找方法,以便将文件名映射到文件句柄,而无需在服务器上建立状态。授予访问权限或修改文件的策略由服务器根据客户端的状态进行管理。这些机制可以实现从仅建议锁定到完全强制锁定的策略。

8.1. Locking
8.1. 锁定

It is assumed that manipulating a lock is rare when compared to READ and WRITE operations. It is also assumed that crashes and network partitions are relatively rare. Therefore it is important that the READ and WRITE operations have a lightweight mechanism to indicate if they possess a held lock. A lock request contains the heavyweight information required to establish a lock and uniquely define the lock owner.

与读写操作相比,操纵锁的情况很少。还假设崩溃和网络分区相对较少。因此,读写操作必须有一个轻量级的机制来指示它们是否拥有持有的锁。锁请求包含建立锁和唯一定义锁所有者所需的重量级信息。

The following sections describe the transition from the heavy weight information to the eventual stateid used for most client and server locking and lease interactions.

以下各节描述了大多数客户端和服务器锁定和租赁交互使用的从重量级信息到最终stateid的转换。

8.1.1. Client ID
8.1.1. 客户端ID

For each LOCK request, the client must identify itself to the server.

对于每个锁请求,客户端必须向服务器标识自己。

This is done in such a way as to allow for correct lock identification and crash recovery. Client identification is accomplished with two values.

这是以允许正确识别锁和碰撞恢复的方式进行的。客户识别由两个值完成。

o A verifier that is used to detect client reboots.

o 用于检测客户端重新启动的验证器。

o A variable length opaque array to uniquely define a client.

o 用于唯一定义客户端的可变长度不透明数组。

For an operating system this may be a fully qualified host name or IP address. For a user level NFS client it may additionally contain a process id or other unique sequence.

对于操作系统,这可能是完全限定的主机名或IP地址。对于用户级NFS客户端,它还可能包含进程id或其他唯一序列。

The data structure for the Client ID would then appear as:

然后,客户端ID的数据结构将显示为:

            struct nfs_client_id {
                    opaque verifier[4];
                    opaque id<>;
            }
        
            struct nfs_client_id {
                    opaque verifier[4];
                    opaque id<>;
            }
        

It is possible through the mis-configuration of a client or the existence of a rogue client that two clients end up using the same nfs_client_id. This situation is avoided by "negotiating" the nfs_client_id between client and server with the use of the SETCLIENTID and SETCLIENTID_CONFIRM operations. The following describes the two scenarios of negotiation.

通过错误配置客户端或存在恶意客户端,两个客户端可能最终使用相同的nfs_客户端_id。通过使用SETCLIENTID和SETCLIENTID_确认操作在客户端和服务器之间“协商”nfs_客户端_id,可以避免这种情况。下面描述了协商的两种场景。

1 Client has never connected to the server

1客户端从未连接到服务器

In this case the client generates an nfs_client_id and unless another client has the same nfs_client_id.id field, the server accepts the request. The server also records the principal (or principal to uid mapping) from the credential in the RPC request that contains the nfs_client_id negotiation request (SETCLIENTID operation).

在这种情况下,客户端将生成一个nfs_client_id,除非另一个客户端具有相同的nfs_client_id.id字段,否则服务器将接受该请求。服务器还将凭证中的主体(或主体到uid的映射)记录在包含nfs_客户端_id协商请求(SETCLIENTID操作)的RPC请求中。

Two clients might still use the same nfs_client_id.id due to perhaps configuration error. For example, a High Availability configuration where the nfs_client_id.id is derived from the ethernet controller address and both systems have the same address. In this case, the result is a switched union that returns, in addition to NFS4ERR_CLID_INUSE, the network address (the rpcbind netid and universal address) of the client that is using the id.

由于可能存在配置错误,两个客户端可能仍然使用相同的nfs_client_id.id。例如,高可用性配置,其中nfs_client_id.id来自以太网控制器地址,并且两个系统具有相同的地址。在这种情况下,结果是一个交换联合,它除了返回NFS4ERR_CLID_INUSE外,还返回使用id的客户端的网络地址(rpcbind netid和通用地址)。

2 Client is re-connecting to the server after a client reboot

2客户端重新启动后,客户端正在重新连接到服务器

In this case, the client still generates an nfs_client_id but the nfs_client_id.id field will be the same as the nfs_client_id.id generated prior to reboot. If the server finds that the principal/uid is equal to the previously "registered" nfs_client_id.id, then locks associated with the old nfs_client_id are immediately released. If the principal/uid is not equal, then this is a rogue client and the request is returned in error. For more discussion of crash recovery semantics, see the section on "Crash Recovery".

在这种情况下,客户端仍会生成nfs_client_id,但nfs_client_id.id字段将与重新启动前生成的nfs_client_id.id相同。如果服务器发现主体/uid等于以前“注册”的nfs_客户端_id.id,则立即释放与旧nfs_客户端_id关联的锁。如果主体/uid不相等,则这是一个恶意客户端,请求返回错误。有关崩溃恢复语义的更多讨论,请参阅“崩溃恢复”一节。

It is possible for a retransmission of request to be received by the server after the server has acted upon and responded to the original client request. Therefore to mitigate effects of the retransmission of the SETCLIENTID operation, the client and server

在服务器对原始客户端请求进行操作和响应之后,服务器可以接收请求的重新传输。因此,为了减轻SETCLIENTID操作的重新传输的影响,客户端和服务器

use a confirmation step. The server returns a confirmation verifier that the client then sends to the server in the SETCLIENTID_CONFIRM operation. Once the server receives the confirmation from the client, the locking state for the client is released.

使用确认步骤。服务器返回一个确认验证器,然后客户端在SETCLIENTID_确认操作中将该验证器发送给服务器。一旦服务器收到来自客户机的确认,客户机的锁定状态即被释放。

In both cases, upon success, NFS4_OK is returned. To help reduce the amount of data transferred on OPEN and LOCK, the server will also return a unique 64-bit clientid value that is a shorthand reference to the nfs_client_id values presented by the client. From this point forward, the client will use the clientid to refer to itself.

在这两种情况下,成功后返回NFS4_OK。为了帮助减少在OPEN和LOCK上传输的数据量,服务器还将返回一个唯一的64位clientid值,该值是对客户端提供的nfs_客户端_id值的简写引用。从这一点开始,客户机将使用clientid来引用自己。

The clientid assigned by the server should be chosen so that it will not conflict with a clientid previously assigned by the server. This applies across server restarts or reboots. When a clientid is presented to a server and that clientid is not recognized, as would happen after a server reboot, the server will reject the request with the error NFS4ERR_STALE_CLIENTID. When this happens, the client must obtain a new clientid by use of the SETCLIENTID operation and then proceed to any other necessary recovery for the server reboot case (See the section "Server Failure and Recovery").

应选择由服务器分配的clientid,以便它不会与以前由服务器分配的clientid冲突。这适用于服务器重新启动或重新启动。当向服务器显示clientid且该clientid无法识别时(如服务器重新启动后发生的情况),服务器将拒绝该请求,错误为NFS4ERR\u STALE\u clientid。发生这种情况时,客户端必须使用SETCLIENTID操作获取新的clientid,然后继续进行服务器重新启动情况下的任何其他必要恢复(请参阅“服务器故障和恢复”一节)。

The client must also employ the SETCLIENTID operation when it receives a NFS4ERR_STALE_STATEID error using a stateid derived from its current clientid, since this also indicates a server reboot which has invalidated the existing clientid (see the next section "nfs_lockowner and stateid Definition" for details).

当客户端使用从其当前clientid派生的STATEID接收到NFS4ERR_STALE_STATEID错误时,它还必须使用SETCLIENTID操作,因为这也表示服务器重新启动已使现有clientid无效(有关详细信息,请参阅下一节“nfs_lockowner和STATEID定义”)。

8.1.2. Server Release of Clientid
8.1.2. Clientid的服务器版本

If the server determines that the client holds no associated state for its clientid, the server may choose to release the clientid. The server may make this choice for an inactive client so that resources are not consumed by those intermittently active clients. If the client contacts the server after this release, the server must ensure the client receives the appropriate error so that it will use the SETCLIENTID/SETCLIENTID_CONFIRM sequence to establish a new identity. It should be clear that the server must be very hesitant to release a clientid since the resulting work on the client to recover from such an event will be the same burden as if the server had failed and restarted. Typically a server would not release a clientid unless there had been no activity from that client for many minutes.

如果服务器确定客户端没有其clientid的关联状态,则服务器可以选择释放clientid。服务器可以对非活动客户端进行此选择,以便资源不会被那些间歇性活动的客户端消耗。如果客户机在此版本后联系服务器,服务器必须确保客户机收到适当的错误,以便使用SETCLIENTID/SETCLIENTID_确认序列来建立新标识。应该清楚的是,服务器在释放clientid时一定会非常犹豫,因为在客户端上从此类事件中恢复的结果工作将是与服务器发生故障并重新启动时相同的负担。通常情况下,服务器不会释放clientid,除非该客户机在几分钟内没有任何活动。

8.1.3. nfs_lockowner and stateid Definition
8.1.3. nfs_lockowner和stateid定义

When requesting a lock, the client must present to the server the clientid and an identifier for the owner of the requested lock. These two fields are referred to as the nfs_lockowner and the definition of those fields are:

请求锁时,客户端必须向服务器提供客户端ID和请求锁所有者的标识符。这两个字段称为nfs_lockowner,这些字段的定义如下:

o A clientid returned by the server as part of the client's use of the SETCLIENTID operation.

o 作为客户端使用SETCLIENTID操作的一部分,服务器返回的clientid。

o A variable length opaque array used to uniquely define the owner of a lock managed by the client.

o 可变长度不透明数组,用于唯一定义由客户端管理的锁的所有者。

This may be a thread id, process id, or other unique value.

这可能是线程id、进程id或其他唯一值。

When the server grants the lock, it responds with a unique 64-bit stateid. The stateid is used as a shorthand reference to the nfs_lockowner, since the server will be maintaining the correspondence between them.

当服务器授予锁时,它将使用唯一的64位stateid进行响应。stateid用作nfs_锁所有者的简写引用,因为服务器将维护它们之间的通信。

The server is free to form the stateid in any manner that it chooses as long as it is able to recognize invalid and out-of-date stateids. This requirement includes those stateids generated by earlier instances of the server. From this, the client can be properly notified of a server restart. This notification will occur when the client presents a stateid to the server from a previous instantiation.

只要能够识别无效和过期的stateid,服务器就可以自由地以其选择的任何方式形成stateid。此要求包括服务器早期实例生成的stateID。由此,可以正确地通知客户机服务器重新启动。当客户端从以前的实例化向服务器提供stateid时,将发生此通知。

The server must be able to distinguish the following situations and return the error as specified:

服务器必须能够区分以下情况并按指定返回错误:

o The stateid was generated by an earlier server instance (i.e. before a server reboot). The error NFS4ERR_STALE_STATEID should be returned.

o stateid由早期服务器实例生成(即,在服务器重新启动之前)。应返回错误NFS4ERR\u STALE\u STATEID。

o The stateid was generated by the current server instance but the stateid no longer designates the current locking state for the lockowner-file pair in question (i.e. one or more locking operations has occurred). The error NFS4ERR_OLD_STATEID should be returned.

o stateid由当前服务器实例生成,但stateid不再为有问题的lockowner文件对指定当前锁定状态(即,发生了一个或多个锁定操作)。应返回错误NFS4ERR_OLD_STATEID。

This error condition will only occur when the client issues a locking request which changes a stateid while an I/O request that uses that stateid is outstanding.

只有当客户端发出锁定请求更改stateid,而使用该stateid的I/O请求未完成时,才会出现此错误情况。

o The stateid was generated by the current server instance but the stateid does not designate a locking state for any active lockowner-file pair. The error NFS4ERR_BAD_STATEID should be returned.

o stateid由当前服务器实例生成,但stateid未为任何活动的lockowner文件对指定锁定状态。应返回错误NFS4ERR_BAD_STATEID。

This error condition will occur when there has been a logic error on the part of the client or server. This should not happen.

当客户端或服务器出现逻辑错误时,将出现此错误情况。这不应该发生。

One mechanism that may be used to satisfy these requirements is for the server to divide stateids into three fields:

可用于满足这些要求的一种机制是服务器将StateID划分为三个字段:

o A server verifier which uniquely designates a particular server instantiation.

o 唯一指定特定服务器实例的服务器验证器。

o An index into a table of locking-state structures.

o 锁定状态结构表的索引。

o A sequence value which is incremented for each stateid that is associated with the same index into the locking-state table.

o 一个序列值,对于与锁状态表中的同一索引关联的每个stateid,该序列值递增。

By matching the incoming stateid and its field values with the state held at the server, the server is able to easily determine if a stateid is valid for its current instantiation and state. If the stateid is not valid, the appropriate error can be supplied to the client.

通过将传入的stateid及其字段值与服务器上保存的状态相匹配,服务器能够轻松确定stateid对于其当前实例化和状态是否有效。如果stateid无效,则可以向客户端提供相应的错误。

8.1.4. Use of the stateid
8.1.4. stateid的使用

All READ and WRITE operations contain a stateid. If the nfs_lockowner performs a READ or WRITE on a range of bytes within a locked range, the stateid (previously returned by the server) must be used to indicate that the appropriate lock (record or share) is held. If no state is established by the client, either record lock or share lock, a stateid of all bits 0 is used. If no conflicting locks are held on the file, the server may service the READ or WRITE operation. If a conflict with an explicit lock occurs, an error is returned for the operation (NFS4ERR_LOCKED). This allows "mandatory locking" to be implemented.

所有读写操作都包含stateid。如果nfs_lockowner对锁定范围内的某个字节范围执行读写操作,则必须使用stateid(以前由服务器返回)来指示是否持有相应的锁(记录或共享)。如果客户端未建立状态(记录锁或共享锁),则使用所有位0的stateid。如果文件上没有冲突的锁,服务器可以为读或写操作提供服务。如果与显式锁发生冲突,则返回操作错误(NFS4ERR\U LOCKED)。这允许实现“强制锁定”。

A stateid of all bits 1 (one) allows READ operations to bypass record locking checks at the server. However, WRITE operations with stateid with bits all 1 (one) do not bypass record locking checks. File locking checks are handled by the OPEN operation (see the section "OPEN/CLOSE Operations").

所有位1(1)的stateid允许读取操作绕过服务器上的记录锁定检查。但是,位为all 1(一)的stateid写操作不会绕过记录锁定检查。文件锁定检查由打开操作处理(请参阅“打开/关闭操作”一节)。

An explicit lock may not be granted while a READ or WRITE operation with conflicting implicit locking is being performed.

在执行具有冲突隐式锁定的读或写操作时,可能不会授予显式锁定。

8.1.5. Sequencing of Lock Requests
8.1.5. 锁请求的排序

Locking is different than most NFS operations as it requires "at-most-one" semantics that are not provided by ONCRPC. ONCRPC over a reliable transport is not sufficient because a sequence of locking requests may span multiple TCP connections. In the face of retransmission or reordering, lock or unlock requests must have a well defined and consistent behavior. To accomplish this, each lock request contains a sequence number that is a consecutively increasing integer. Different nfs_lockowners have different sequences. The server maintains the last sequence number (L) received and the response that was returned.

锁定与大多数NFS操作不同,因为它需要ONCRPC未提供的“至多一个”语义。通过可靠传输的ONCRPC是不够的,因为一系列锁定请求可能跨越多个TCP连接。面对重传或重新排序,锁定或解锁请求必须具有定义良好且一致的行为。为了实现这一点,每个锁请求都包含一个连续递增的整数序列号。不同的nfs\u锁所有者具有不同的序列。服务器维护接收到的最后一个序列号(L)和返回的响应。

Note that for requests that contain a sequence number, for each nfs_lockowner, there should be no more than one outstanding request.

请注意,对于包含序列号的请求,对于每个nfs_lockowner,不应存在多个未完成的请求。

If a request with a previous sequence number (r < L) is received, it is rejected with the return of error NFS4ERR_BAD_SEQID. Given a properly-functioning client, the response to (r) must have been received before the last request (L) was sent. If a duplicate of last request (r == L) is received, the stored response is returned. If a request beyond the next sequence (r == L + 2) is received, it is rejected with the return of error NFS4ERR_BAD_SEQID. Sequence history is reinitialized whenever the client verifier changes.

如果接收到具有先前序列号(r<L)的请求,则会拒绝该请求,并返回错误NFS4ERR_BAD_SEQUID。如果客户端功能正常,则必须在发送最后一个请求(L)之前收到对(r)的响应。如果接收到上一个请求(r==L)的副本,则返回存储的响应。如果接收到超过下一个序列(r==L+2)的请求,则会拒绝该请求,并返回错误NFS4ERR_BAD_SEQUID。每当客户端验证器更改时,序列历史记录都会重新初始化。

Since the sequence number is represented with an unsigned 32-bit integer, the arithmetic involved with the sequence number is mod 2^32.

由于序列号用无符号32位整数表示,因此与序列号相关的算术为mod 2^32。

It is critical the server maintain the last response sent to the client to provide a more reliable cache of duplicate non-idempotent requests than that of the traditional cache described in [Juszczak]. The traditional duplicate request cache uses a least recently used algorithm for removing unneeded requests. However, the last lock request and response on a given nfs_lockowner must be cached as long as the lock state exists on the server.

与[Juszczak]中描述的传统缓存相比,服务器维护发送给客户端的最后一个响应以提供更可靠的重复非幂等请求缓存是至关重要的。传统的重复请求缓存使用最近最少使用的算法来删除不需要的请求。但是,只要服务器上存在锁状态,就必须缓存给定nfs_lockowner上的最后一个锁请求和响应。

8.1.6. Recovery from Replayed Requests
8.1.6. 从重播请求中恢复

As described above, the sequence number is per nfs_lockowner. As long as the server maintains the last sequence number received and follows the methods described above, there are no risks of a Byzantine router re-sending old requests. The server need only maintain the nfs_lockowner, sequence number state as long as there are open files or closed files with locks outstanding.

如上所述,序列号为每个nfs_lockowner。只要服务器保持接收到的最后一个序列号并遵循上述方法,就不存在拜占庭式路由器重新发送旧请求的风险。只要存在未锁定的打开文件或关闭文件,服务器只需维护nfs_lockowner、序列号状态。

LOCK, LOCKU, OPEN, OPEN_DOWNGRADE, and CLOSE each contain a sequence number and therefore the risk of the replay of these operations resulting in undesired effects is non-existent while the server maintains the nfs_lockowner state.

LOCK、LOCKU、OPEN、OPEN_降级和CLOSE每个都包含一个序列号,因此,在服务器保持nfs_lockowner状态时,这些操作的重播导致不期望的效果的风险是不存在的。

8.1.7. Releasing nfs_lockowner State
8.1.7. 释放nfs_锁所有者状态

When a particular nfs_lockowner no longer holds open or file locking state at the server, the server may choose to release the sequence number state associated with the nfs_lockowner. The server may make this choice based on lease expiration, for the reclamation of server memory, or other implementation specific details. In any event, the server is able to do this safely only when the nfs_lockowner no longer is being utilized by the client. The server may choose to hold the nfs_lockowner state in the event that retransmitted requests are received. However, the period to hold this state is implementation specific.

当特定nfs_锁所有者不再在服务器上保持打开或文件锁定状态时,服务器可以选择释放与nfs_锁所有者关联的序列号状态。服务器可以根据租约到期、服务器内存回收或其他特定于实现的详细信息做出此选择。在任何情况下,只有当客户端不再使用nfs_锁所有者时,服务器才能安全地执行此操作。在收到重新传输的请求时,服务器可以选择保持nfs_lockowner状态。然而,保持这种状态的期限是具体实施的。

In the case that a LOCK, LOCKU, OPEN_DOWNGRADE, or CLOSE is retransmitted after the server has previously released the nfs_lockowner state, the server will find that the nfs_lockowner has no files open and an error will be returned to the client. If the nfs_lockowner does have a file open, the stateid will not match and again an error is returned to the client.

如果在服务器先前释放nfs_lockowner状态后重新传输锁、锁定、打开_降级或关闭,服务器将发现nfs_lockowner没有打开的文件,并将向客户端返回错误。如果nfs_lockowner确实打开了一个文件,则stateid将不匹配,并再次向客户端返回一个错误。

In the case that an OPEN is retransmitted and the nfs_lockowner is being used for the first time or the nfs_lockowner state has been previously released by the server, the use of the OPEN_CONFIRM operation will prevent incorrect behavior. When the server observes the use of the nfs_lockowner for the first time, it will direct the client to perform the OPEN_CONFIRM for the corresponding OPEN. This sequence establishes the use of an nfs_lockowner and associated sequence number. See the section "OPEN_CONFIRM - Confirm Open" for further details.

在重新传输OPEN并且首次使用nfs_lockowner或服务器先前已释放nfs_lockowner状态的情况下,使用OPEN_CONFIRM操作将防止错误行为。当服务器第一次观察到nfs_lockowner的使用时,它将指示客户端对相应的OPEN执行OPEN_确认。此序列确定nfs_锁所有者和相关序列号的使用。有关更多详细信息,请参阅“打开\确认-确认打开”一节。

8.2. Lock Ranges
8.2. 锁定范围

The protocol allows a lock owner to request a lock with one byte range and then either upgrade or unlock a sub-range of the initial lock. It is expected that this will be an uncommon type of request. In any case, servers or server file systems may not be able to support sub-range lock semantics. In the event that a server receives a locking request that represents a sub-range of current locking state for the lock owner, the server is allowed to return the error NFS4ERR_LOCK_RANGE to signify that it does not support sub-range lock operations. Therefore, the client should be prepared to receive this error and, if appropriate, report the error to the requesting application.

该协议允许锁所有者请求具有一个字节范围的锁,然后升级或解锁初始锁的子范围。预计这将是一种不常见的请求类型。在任何情况下,服务器或服务器文件系统都可能无法支持子范围锁语义。如果服务器接收到表示锁所有者当前锁定状态子范围的锁定请求,则允许服务器返回错误NFS4ERR_lock_range,以表示它不支持子范围锁定操作。因此,客户机应该准备好接收此错误,并在适当的情况下向请求的应用程序报告此错误。

The client is discouraged from combining multiple independent locking ranges that happen to be adjacent into a single request since the server may not support sub-range requests and for reasons related to the recovery of file locking state in the event of server failure. As discussed in the section "Server Failure and Recovery" below, the server may employ certain optimizations during recovery that work effectively only when the client's behavior during lock recovery is similar to the client's locking behavior prior to server failure.

由于服务器可能不支持子范围请求,并且由于与在服务器发生故障时恢复文件锁定状态有关的原因,因此不鼓励客户端将碰巧相邻的多个独立锁定范围合并到单个请求中。正如下面“服务器故障和恢复”一节中所讨论的,服务器可能会在恢复期间采用某些优化,这些优化只有在锁定恢复期间的客户端行为与服务器故障之前的客户端锁定行为相似时才能有效工作。

8.3. Blocking Locks
8.3. 闭锁

Some clients require the support of blocking locks. The NFS version 4 protocol must not rely on a callback mechanism and therefore is unable to notify a client when a previously denied lock has been granted. Clients have no choice but to continually poll for the lock. This presents a fairness problem. Two new lock types are added, READW and WRITEW, and are used to indicate to the server that the client is requesting a blocking lock. The server should maintain an ordered list of pending blocking locks. When the conflicting lock is released, the server may wait the lease period for the first waiting client to re-request the lock. After the lease period expires the next waiting client request is allowed the lock. Clients are required to poll at an interval sufficiently small that it is likely to acquire the lock in a timely manner. The server is not required to maintain a list of pending blocked locks as it is used to increase fairness and not correct operation. Because of the unordered nature of crash recovery, storing of lock state to stable storage would be required to guarantee ordered granting of blocking locks.

有些客户机需要阻塞锁的支持。NFS版本4协议不能依赖回调机制,因此无法在授予以前被拒绝的锁时通知客户端。客户端别无选择,只能不断轮询锁。这是一个公平问题。添加了两种新的锁类型READW和WRITEW,用于向服务器指示客户端正在请求阻塞锁。服务器应该维护挂起的阻塞锁的有序列表。当冲突锁被释放时,服务器可能会等待租约期,等待第一个等待的客户端重新请求锁。租赁期到期后,允许下一个等待的客户端请求锁定。客户端需要以足够小的间隔进行轮询,以便能够及时获取锁。服务器不需要维护挂起的阻塞锁列表,因为它用于增加公平性和不正确的操作。由于崩溃恢复的无序性,需要将锁状态存储到稳定存储,以保证阻塞锁的有序授予。

Servers may also note the lock types and delay returning denial of the request to allow extra time for a conflicting lock to be released, allowing a successful return. In this way, clients can avoid the burden of needlessly frequent polling for blocking locks. The server should take care in the length of delay in the event the client retransmits the request.

服务器还可能会注意到锁的类型,并延迟请求的返回拒绝,以允许释放冲突锁的额外时间,从而允许成功返回。这样,客户机就可以避免不必要的频繁轮询阻塞锁的负担。在客户端重新传输请求时,服务器应注意延迟的长度。

8.4. Lease Renewal
8.4. 续租

The purpose of a lease is to allow a server to remove stale locks that are held by a client that has crashed or is otherwise unreachable. It is not a mechanism for cache consistency and lease renewals may not be denied if the lease interval has not expired.

租约的目的是允许服务器删除已崩溃或无法访问的客户端持有的过时锁。它不是缓存一致性的机制,如果租约间隔未过期,则租约续订可能不会被拒绝。

The following events cause implicit renewal of all of the leases for a given client (i.e. all those sharing a given clientid). Each of these is a positive indication that the client is still active and

以下事件导致对给定客户(即共享给定客户ID的所有客户)的所有租约进行隐式续订。每一项都是一个积极的迹象,表明客户机仍然处于活动状态,并且

that the associated state held at the server, for the client, is still valid.

服务器上为客户端保留的关联状态仍然有效。

o An OPEN with a valid clientid.

o 具有有效clientid的打开的。

o Any operation made with a valid stateid (CLOSE, DELEGRETURN, LOCK, LOCKU, OPEN, OPEN_CONFIRM, READ, RENEW, SETATTR, WRITE). This does not include the special stateids of all bits 0 or all bits 1.

o 使用有效stateid进行的任何操作(关闭、删除、锁定、锁定、打开、打开、确认、读取、续订、设置属性、写入)。这不包括所有位0或所有位1的特殊StateID。

Note that if the client had restarted or rebooted, the client would not be making these requests without issuing the SETCLIENTID operation. The use of the SETCLIENTID operation (possibly with the addition of the optional SETCLIENTID_CONFIRM operation) notifies the server to drop the locking state associated with the client.

请注意,如果客户端已重新启动或重新启动,则在不发出SETCLIENTID操作的情况下,客户端不会发出这些请求。使用SETCLIENTID操作(可能添加可选的SETCLIENTID_确认操作)会通知服务器放弃与客户端关联的锁定状态。

If the server has rebooted, the stateids (NFS4ERR_STALE_STATEID error) or the clientid (NFS4ERR_STALE_CLIENTID error) will not be valid hence preventing spurious renewals.

如果服务器已重新启动,STATEID(NFS4ERR\u STALE\u STATEID错误)或clientid(NFS4ERR\u STALE\u clientid错误)将无效,从而防止虚假续订。

This approach allows for low overhead lease renewal which scales well. In the typical case no extra RPC calls are required for lease renewal and in the worst case one RPC is required every lease period (i.e. a RENEW operation). The number of locks held by the client is not a factor since all state for the client is involved with the lease renewal action.

这种方法允许低管理费用的租赁续期,并且具有良好的扩展性。在典型情况下,租约续订不需要额外的RPC调用,在最坏情况下,每个租约期都需要一个RPC(即续订操作)。客户端持有的锁的数量不是一个因素,因为客户端的所有状态都与租约续订操作有关。

Since all operations that create a new lease also renew existing leases, the server must maintain a common lease expiration time for all valid leases for a given client. This lease time can then be easily updated upon implicit lease renewal actions.

由于创建新租约的所有操作也会续订现有租约,因此服务器必须为给定客户端的所有有效租约维护一个公共租约到期时间。然后,可以根据隐式租约续订操作轻松更新此租约时间。

8.5. Crash Recovery
8.5. 事故恢复

The important requirement in crash recovery is that both the client and the server know when the other has failed. Additionally, it is required that a client sees a consistent view of data across server restarts or reboots. All READ and WRITE operations that may have been queued within the client or network buffers must wait until the client has successfully recovered the locks protecting the READ and WRITE operations.

崩溃恢复的重要要求是,客户端和服务器都知道另一方何时出现故障。此外,要求客户端在服务器重新启动或重新启动时看到一致的数据视图。在客户端或网络缓冲区内排队的所有读写操作必须等待,直到客户端成功恢复保护读写操作的锁。

8.5.1. Client Failure and Recovery
8.5.1. 客户端故障和恢复

In the event that a client fails, the server may recover the client's locks when the associated leases have expired. Conflicting locks from another client may only be granted after this lease expiration. If the client is able to restart or reinitialize within the lease

如果客户端出现故障,服务器可能会在相关租约过期时恢复客户端的锁。来自其他客户端的冲突锁只能在此租约到期后授予。如果客户端能够在租约内重新启动或重新初始化

period the client may be forced to wait the remainder of the lease period before obtaining new locks.

在获得新锁之前,客户端可能会被迫等待租赁期的剩余时间。

To minimize client delay upon restart, lock requests are associated with an instance of the client by a client supplied verifier. This verifier is part of the initial SETCLIENTID call made by the client. The server returns a clientid as a result of the SETCLIENTID operation. The client then confirms the use of the verifier with SETCLIENTID_CONFIRM. The clientid in combination with an opaque owner field is then used by the client to identify the lock owner for OPEN. This chain of associations is then used to identify all locks for a particular client.

为了最小化重启时的客户端延迟,锁请求由客户端提供的验证器与客户端实例相关联。此验证器是客户端进行的初始SETCLIENTID调用的一部分。作为SETCLIENTID操作的结果,服务器返回clientid。然后,客户端使用SETCLIENTID\u确认来确认验证器的使用。然后,客户端将clientid与不透明所有者字段结合使用,以标识OPEN的锁所有者。然后,该关联链用于标识特定客户端的所有锁。

Since the verifier will be changed by the client upon each initialization, the server can compare a new verifier to the verifier associated with currently held locks and determine that they do not match. This signifies the client's new instantiation and subsequent loss of locking state. As a result, the server is free to release all locks held which are associated with the old clientid which was derived from the old verifier.

由于客户端在每次初始化时都会更改验证器,因此服务器可以将新的验证器与与当前持有的锁关联的验证器进行比较,并确定它们不匹配。这表示客户端的新实例化和随后的锁定状态丢失。因此,服务器可以自由地释放与从旧验证器派生的旧clientid相关联的所有锁。

For secure environments, a change in the verifier must only cause the release of locks associated with the authenticated requester. This is required to prevent a rogue entity from freeing otherwise valid locks.

对于安全环境,验证器中的更改只能导致释放与经过身份验证的请求者相关联的锁。这是防止流氓实体释放其他有效锁所必需的。

Note that the verifier must have the same uniqueness properties of the verifier for the COMMIT operation.

请注意,对于提交操作,验证器必须具有与验证器相同的唯一性属性。

8.5.2. Server Failure and Recovery
8.5.2. 服务器故障和恢复

If the server loses locking state (usually as a result of a restart or reboot), it must allow clients time to discover this fact and re-establish the lost locking state. The client must be able to re-establish the locking state without having the server deny valid requests because the server has granted conflicting access to another client. Likewise, if there is the possibility that clients have not yet re-established their locking state for a file, the server must disallow READ and WRITE operations for that file. The duration of this recovery period is equal to the duration of the lease period.

如果服务器失去锁定状态(通常是由于重新启动或重新启动),它必须让客户端有时间发现这一事实并重新建立失去的锁定状态。客户端必须能够重新建立锁定状态,而无需服务器拒绝有效请求,因为服务器已授予另一客户端冲突的访问权限。同样,如果客户端可能尚未重新建立文件的锁定状态,则服务器必须禁止该文件的读写操作。此恢复期的持续时间等于租赁期的持续时间。

A client can determine that server failure (and thus loss of locking state) has occurred, when it receives one of two errors. The NFS4ERR_STALE_STATEID error indicates a stateid invalidated by a reboot or restart. The NFS4ERR_STALE_CLIENTID error indicates a clientid invalidated by reboot or restart. When either of these are received, the client must establish a new clientid (See the section "Client ID") and re-establish the locking state as discussed below.

当客户端收到两个错误中的一个错误时,它可以确定服务器发生故障(从而失去锁定状态)。NFS4ERR\u STALE\u STATEID错误表示STATEID因重新启动或重新启动而无效。NFS4ERR_STALE_CLIENTID错误表示一个CLIENTID因重新启动或重新启动而无效。当收到其中任何一个时,客户机必须建立一个新的clientid(请参阅“客户机ID”一节),并重新建立锁定状态,如下所述。

The period of special handling of locking and READs and WRITEs, equal in duration to the lease period, is referred to as the "grace period". During the grace period, clients recover locks and the associated state by reclaim-type locking requests (i.e. LOCK requests with reclaim set to true and OPEN operations with a claim type of CLAIM_PREVIOUS). During the grace period, the server must reject READ and WRITE operations and non-reclaim locking requests (i.e. other LOCK and OPEN operations) with an error of NFS4ERR_GRACE.

锁定和读写的特殊处理期限与租赁期限相等,称为“宽限期”。在宽限期内,客户端通过回收类型锁定请求(即回收设置为true的锁定请求和索赔类型为claim_PREVIOUS的打开操作)恢复锁和关联状态。在宽限期内,服务器必须拒绝读写操作和非回收锁定请求(即其他锁定和打开操作),错误为NFS4ERR_grace。

If the server can reliably determine that granting a non-reclaim request will not conflict with reclamation of locks by other clients, the NFS4ERR_GRACE error does not have to be returned and the non-reclaim client request can be serviced. For the server to be able to service READ and WRITE operations during the grace period, it must again be able to guarantee that no possible conflict could arise between an impending reclaim locking request and the READ or WRITE operation. If the server is unable to offer that guarantee, the NFS4ERR_GRACE error must be returned to the client.

如果服务器能够可靠地确定授予非回收请求不会与其他客户端的锁回收冲突,则不必返回NFS4ERR_GRACE错误,并且可以为非回收客户端请求提供服务。为了使服务器能够在宽限期内为读写操作提供服务,它必须再次能够保证即将到来的回收锁定请求与读写操作之间不会出现任何可能的冲突。如果服务器无法提供该保证,则必须将NFS4ERR_GRACE错误返回给客户端。

For a server to provide simple, valid handling during the grace period, the easiest method is to simply reject all non-reclaim locking requests and READ and WRITE operations by returning the NFS4ERR_GRACE error. However, a server may keep information about granted locks in stable storage. With this information, the server could determine if a regular lock or READ or WRITE operation can be safely processed.

对于要在宽限期内提供简单有效的处理的服务器,最简单的方法是通过返回NFS4ERR_宽限期错误,简单地拒绝所有非回收锁定请求和读写操作。但是,服务器可能会在稳定的存储中保留有关已授予锁的信息。有了这些信息,服务器可以确定是否可以安全地处理常规锁定或读写操作。

For example, if a count of locks on a given file is available in stable storage, the server can track reclaimed locks for the file and when all reclaims have been processed, non-reclaim locking requests may be processed. This way the server can ensure that non-reclaim locking requests will not conflict with potential reclaim requests. With respect to I/O requests, if the server is able to determine that there are no outstanding reclaim requests for a file by information from stable storage or another similar mechanism, the processing of I/O requests could proceed normally for the file.

例如,如果给定文件上的锁数在稳定存储中可用,则服务器可以跟踪该文件的回收锁,并且在处理完所有回收后,可以处理非回收锁定请求。这样,服务器可以确保非回收锁定请求不会与潜在的回收请求冲突。对于I/O请求,如果服务器能够通过稳定存储或其他类似机制中的信息确定没有未完成的文件回收请求,则可以正常处理该文件的I/O请求。

To reiterate, for a server that allows non-reclaim lock and I/O requests to be processed during the grace period, it MUST determine that no lock subsequently reclaimed will be rejected and that no lock subsequently reclaimed would have prevented any I/O operation processed during the grace period.

重申一下,对于允许在宽限期内处理非回收锁和I/O请求的服务器,必须确定随后回收的锁不会被拒绝,并且随后回收的锁不会阻止宽限期内处理的任何I/O操作。

Clients should be prepared for the return of NFS4ERR_GRACE errors for non-reclaim lock and I/O requests. In this case the client should employ a retry mechanism for the request. A delay (on the order of several seconds) between retries should be used to avoid overwhelming the server. Further discussion of the general is included in

客户端应准备好返回非回收锁和I/O请求的NFS4ERR_GRACE错误。在这种情况下,客户端应该对请求采用重试机制。重试之间应使用延迟(大约几秒钟),以避免服务器无法正常工作。一般性意见的进一步讨论载于

[Floyd]. The client must account for the server that is able to perform I/O and non-reclaim locking requests within the grace period as well as those that can not do so.

[弗洛伊德]。客户机必须说明能够在宽限期内执行I/O和非回收锁定请求的服务器以及不能执行这些请求的服务器。

A reclaim-type locking request outside the server's grace period can only succeed if the server can guarantee that no conflicting lock or I/O request has been granted since reboot or restart.

只有在服务器能够保证自重新启动或重新启动后未授予任何冲突的锁定或I/O请求的情况下,服务器宽限期之外的回收类型锁定请求才能成功。

8.5.3. Network Partitions and Recovery
8.5.3. 网络分区和恢复

If the duration of a network partition is greater than the lease period provided by the server, the server will have not received a lease renewal from the client. If this occurs, the server may free all locks held for the client. As a result, all stateids held by the client will become invalid or stale. Once the client is able to reach the server after such a network partition, all I/O submitted by the client with the now invalid stateids will fail with the server returning the error NFS4ERR_EXPIRED. Once this error is received, the client will suitably notify the application that held the lock.

如果网络分区的持续时间大于服务器提供的租约期限,则服务器将不会从客户端收到租约续订。如果发生这种情况,服务器可能会释放为客户端保留的所有锁。因此,客户端持有的所有StateID都将变得无效或过时。一旦客户机能够在这样一个网络分区之后到达服务器,客户机提交的所有I/O以及现在无效的StateID都将失败,服务器返回错误NFS4ERR_EXPIRED。一旦收到此错误,客户端将适当地通知持有锁的应用程序。

As a courtesy to the client or as an optimization, the server may continue to hold locks on behalf of a client for which recent communication has extended beyond the lease period. If the server receives a lock or I/O request that conflicts with one of these courtesy locks, the server must free the courtesy lock and grant the new request.

作为对客户机的礼貌或作为优化,服务器可以继续代表最近的通信已经延长到租赁期之外的客户机持有锁。如果服务器收到与这些门控锁之一冲突的锁或I/O请求,则服务器必须释放门控锁并批准新请求。

If the server continues to hold locks beyond the expiration of a client's lease, the server MUST employ a method of recording this fact in its stable storage. Conflicting locks requests from another client may be serviced after the lease expiration. There are various scenarios involving server failure after such an event that require the storage of these lease expirations or network partitions. One scenario is as follows:

如果服务器在客户端租约到期后继续持有锁,则服务器必须采用在其稳定存储中记录这一事实的方法。来自其他客户端的冲突锁请求可能在租约到期后得到服务。在发生此类事件后,存在各种涉及服务器故障的场景,需要存储这些租约到期或网络分区。一种情况如下:

A client holds a lock at the server and encounters a network partition and is unable to renew the associated lease. A second client obtains a conflicting lock and then frees the lock. After the unlock request by the second client, the server reboots or reinitializes. Once the server recovers, the network partition heals and the original client attempts to reclaim the original lock.

客户端在服务器上持有锁,遇到网络分区,无法续订相关租约。第二个客户端获得冲突的锁,然后释放该锁。在第二个客户端发出解锁请求后,服务器将重新启动或重新初始化。一旦服务器恢复,网络分区就会恢复,原始客户端将尝试回收原始锁。

In this scenario and without any state information, the server will allow the reclaim and the client will be in an inconsistent state because the server or the client has no knowledge of the conflicting lock.

在这种情况下,如果没有任何状态信息,服务器将允许回收,而客户端将处于不一致的状态,因为服务器或客户端不知道冲突的锁。

The server may choose to store this lease expiration or network partitioning state in a way that will only identify the client as a whole. Note that this may potentially lead to lock reclaims being denied unnecessarily because of a mix of conflicting and non-conflicting locks. The server may also choose to store information about each lock that has an expired lease with an associated conflicting lock. The choice of the amount and type of state information that is stored is left to the implementor. In any case, the server must have enough state information to enable correct recovery from multiple partitions and multiple server failures.

服务器可以选择存储此租约到期或网络分区状态的方式,该方式将仅识别整个客户端。请注意,这可能会导致不必要地拒绝锁回收,因为存在冲突锁和非冲突锁的混合。服务器还可以选择存储有关每个已过期租约的锁以及相关冲突锁的信息。存储的状态信息的数量和类型由实现者选择。在任何情况下,服务器必须具有足够的状态信息,以便能够从多个分区和多个服务器故障中正确恢复。

8.6. Recovery from a Lock Request Timeout or Abort
8.6. 从锁定请求超时或中止中恢复

In the event a lock request times out, a client may decide to not retry the request. The client may also abort the request when the process for which it was issued is terminated (e.g. in UNIX due to a signal. It is possible though that the server received the request and acted upon it. This would change the state on the server without the client being aware of the change. It is paramount that the client re-synchronize state with server before it attempts any other operation that takes a seqid and/or a stateid with the same nfs_lockowner. This is straightforward to do without a special re-synchronize operation.

如果锁定请求超时,客户端可能会决定不重试该请求。当为其发出请求的进程终止时,客户端也可以中止该请求(例如,在UNIX中,由于信号原因。虽然服务器可能接收到请求并对其进行了操作。这将在客户端不知道更改的情况下更改服务器上的状态。在尝试任何其他使用sam的seqid和/或stateid的操作之前,客户端必须与服务器重新同步状态e nfs_lockowner。无需特殊的重新同步操作,即可直接执行此操作。

Since the server maintains the last lock request and response received on the nfs_lockowner, for each nfs_lockowner, the client should cache the last lock request it sent such that the lock request did not receive a response. From this, the next time the client does a lock operation for the nfs_lockowner, it can send the cached request, if there is one, and if the request was one that established state (e.g. a LOCK or OPEN operation) the client can follow up with a request to remove the state (e.g. a LOCKU or CLOSE operation). With this approach, the sequencing and stateid information on the client and server for the given nfs_lockowner will re-synchronize and in turn the lock state will re-synchronize.

由于服务器维护在nfs_lockowner上接收的最后一个锁请求和响应,因此对于每个nfs_lockowner,客户端应该缓存它发送的最后一个锁请求,以便锁请求不会收到响应。因此,下次客户端为nfs_lockowner执行锁定操作时,它可以发送缓存请求(如果有),如果请求是已建立状态的请求(例如锁定或打开操作),则客户端可以随后请求删除该状态(例如锁定或关闭操作)。使用这种方法,客户机和服务器上给定nfs_lockowner的序列和stateid信息将重新同步,而锁状态将重新同步。

8.7. Server Revocation of Locks
8.7. 服务器撤销锁

At any point, the server can revoke locks held by a client and the client must be prepared for this event. When the client detects that its locks have been or may have been revoked, the client is responsible for validating the state information between itself and the server. Validating locking state for the client means that it must verify or reclaim state for each lock currently held.

在任何时候,服务器都可以撤销客户机持有的锁,客户机必须为此事件做好准备。当客户端检测到其锁已被或可能已被撤销时,客户端负责验证自身和服务器之间的状态信息。验证客户端的锁定状态意味着它必须验证或回收当前持有的每个锁的状态。

The first instance of lock revocation is upon server reboot or re-initialization. In this instance the client will receive an error (NFS4ERR_STALE_STATEID or NFS4ERR_STALE_CLIENTID) and the client will proceed with normal crash recovery as described in the previous section.

锁撤销的第一个实例是在服务器重新启动或重新初始化时。在这种情况下,客户端将收到一个错误(NFS4ERR_STALE_STATEID或NFS4ERR_STALE_CLIENTID),客户端将按照上一节中的描述继续进行正常的崩溃恢复。

The second lock revocation event is the inability to renew the lease period. While this is considered a rare or unusual event, the client must be prepared to recover. Both the server and client will be able to detect the failure to renew the lease and are capable of recovering without data corruption. For the server, it tracks the last renewal event serviced for the client and knows when the lease will expire. Similarly, the client must track operations which will renew the lease period. Using the time that each such request was sent and the time that the corresponding reply was received, the client should bound the time that the corresponding renewal could have occurred on the server and thus determine if it is possible that a lease period expiration could have occurred.

第二个锁撤销事件是无法续订租赁期。虽然这被认为是罕见或不寻常的事件,但客户必须做好恢复的准备。服务器和客户端都能够检测到续订租约失败,并且能够在不损坏数据的情况下进行恢复。对于服务器,它跟踪上次为客户端服务的续订事件,并知道租约何时到期。同样,客户必须跟踪将延长租赁期的运营情况。使用发送每个此类请求的时间和收到相应回复的时间,客户机应绑定服务器上可能发生的相应续订时间,从而确定是否可能发生租赁期到期。

The third lock revocation event can occur as a result of administrative intervention within the lease period. While this is considered a rare event, it is possible that the server's administrator has decided to release or revoke a particular lock held by the client. As a result of revocation, the client will receive an error of NFS4ERR_EXPIRED and the error is received within the lease period for the lock. In this instance the client may assume that only the nfs_lockowner's locks have been lost. The client notifies the lock holder appropriately. The client may not assume the lease period has been renewed as a result of failed operation.

第三个锁撤销事件可能是由于租赁期内的管理干预而发生的。虽然这被认为是罕见的事件,但服务器管理员可能已决定释放或撤销客户端持有的特定锁。撤销的结果是,客户端将收到NFS4ERR_EXPIRED错误,并且在锁的租赁期内收到该错误。在这种情况下,客户机可能认为只有nfs_lockowner的锁丢失了。客户端会适当地通知锁持有者。客户可能不会认为由于操作失败而延长了租赁期。

When the client determines the lease period may have expired, the client must mark all locks held for the associated lease as "unvalidated". This means the client has been unable to re-establish or confirm the appropriate lock state with the server. As described in the previous section on crash recovery, there are scenarios in which the server may grant conflicting locks after the lease period has expired for a client. When it is possible that the lease period has expired, the client must validate each lock currently held to ensure that a conflicting lock has not been granted. The client may accomplish this task by issuing an I/O request, either a pending I/O or a zero-length read, specifying the stateid associated with the lock in question. If the response to the request is success, the client has validated all of the locks governed by that stateid and re-established the appropriate state between itself and the server. If the I/O request is not successful, then one or more of the locks associated with the stateid was revoked by the server and the client must notify the owner.

当客户确定租赁期可能已到期时,客户必须将为相关租赁持有的所有锁标记为“未验证”。这意味着客户端无法与服务器重新建立或确认适当的锁定状态。如前一节关于崩溃恢复的描述,在某些情况下,服务器可能会在客户端的租约期到期后授予冲突锁。当租赁期可能已过期时,客户端必须验证当前持有的每个锁,以确保未授予冲突的锁。客户机可以通过发出I/O请求来完成此任务,I/O请求可以是挂起的I/O请求,也可以是零长度读取请求,并指定与所讨论的锁关联的stateid。如果对请求的响应是成功的,则客户端已经验证了由该stateid管理的所有锁,并在其自身和服务器之间重新建立了适当的状态。如果I/O请求未成功,则服务器将撤销与stateid关联的一个或多个锁,客户端必须通知所有者。

8.8. Share Reservations
8.8. 共享预订

A share reservation is a mechanism to control access to a file. It is a separate and independent mechanism from record locking. When a client opens a file, it issues an OPEN operation to the server specifying the type of access required (READ, WRITE, or BOTH) and the type of access to deny others (deny NONE, READ, WRITE, or BOTH). If the OPEN fails the client will fail the application's open request.

共享保留是一种控制文件访问的机制。它是一种独立于记录锁定的机制。当客户端打开文件时,它会向服务器发出一个打开操作,指定所需的访问类型(读、写或两者兼有)和拒绝其他人的访问类型(拒绝无、读、写或两者兼有)。如果打开失败,客户端将使应用程序的打开请求失败。

Pseudo-code definition of the semantics:

语义的伪代码定义:

if ((request.access & file_state.deny)) || (request.deny & file_state.access)) return (NFS4ERR_DENIED)

if((request.access和file_state.deny))|(request.deny和file_state.access))返回(NFS4ERR_DENIED)

The constants used for the OPEN and OPEN_DOWNGRADE operations for the access and deny fields are as follows:

access和deny字段的OPEN和OPEN_降级操作使用的常量如下:

   const OPEN4_SHARE_ACCESS_READ   = 0x00000001;
   const OPEN4_SHARE_ACCESS_WRITE  = 0x00000002;
   const OPEN4_SHARE_ACCESS_BOTH   = 0x00000003;
        
   const OPEN4_SHARE_ACCESS_READ   = 0x00000001;
   const OPEN4_SHARE_ACCESS_WRITE  = 0x00000002;
   const OPEN4_SHARE_ACCESS_BOTH   = 0x00000003;
        
   const OPEN4_SHARE_DENY_NONE     = 0x00000000;
   const OPEN4_SHARE_DENY_READ     = 0x00000001;
   const OPEN4_SHARE_DENY_WRITE    = 0x00000002;
   const OPEN4_SHARE_DENY_BOTH     = 0x00000003;
        
   const OPEN4_SHARE_DENY_NONE     = 0x00000000;
   const OPEN4_SHARE_DENY_READ     = 0x00000001;
   const OPEN4_SHARE_DENY_WRITE    = 0x00000002;
   const OPEN4_SHARE_DENY_BOTH     = 0x00000003;
        
8.9. OPEN/CLOSE Operations
8.9. 打开/关闭操作

To provide correct share semantics, a client MUST use the OPEN operation to obtain the initial filehandle and indicate the desired access and what if any access to deny. Even if the client intends to use a stateid of all 0's or all 1's, it must still obtain the filehandle for the regular file with the OPEN operation so the appropriate share semantics can be applied. For clients that do not have a deny mode built into their open programming interfaces, deny equal to NONE should be used.

为了提供正确的共享语义,客户机必须使用OPEN操作来获取初始文件句柄,并指示所需的访问以及拒绝任何访问。即使客户端打算使用所有0或所有1的stateid,它仍然必须通过OPEN操作获取常规文件的filehandle,以便应用适当的共享语义。对于未在其开放编程接口中内置deny模式的客户端,应使用deny equal to NONE。

The OPEN operation with the CREATE flag, also subsumes the CREATE operation for regular files as used in previous versions of the NFS protocol. This allows a create with a share to be done atomically.

带有CREATE标志的OPEN操作还包含NFS协议早期版本中使用的常规文件的CREATE操作。这允许以原子方式创建共享。

The CLOSE operation removes all share locks held by the nfs_lockowner on that file. If record locks are held, the client SHOULD release all locks before issuing a CLOSE. The server MAY free all outstanding locks on CLOSE but some servers may not support the CLOSE of a file that still has record locks held. The server MUST return failure if any locks would exist after the CLOSE.

关闭操作将删除nfs_lockowner在该文件上持有的所有共享锁。如果记录锁被持有,客户端应在发出关闭之前释放所有锁。服务器可能会在关闭时释放所有未完成的锁,但某些服务器可能不支持关闭仍保留记录锁的文件。如果关闭后存在任何锁,服务器必须返回failure。

The LOOKUP operation will return a filehandle without establishing any lock state on the server. Without a valid stateid, the server will assume the client has the least access. For example, a file opened with deny READ/WRITE cannot be accessed using a filehandle obtained through LOOKUP because it would not have a valid stateid (i.e. using a stateid of all bits 0 or all bits 1).

查找操作将返回文件句柄,而不会在服务器上建立任何锁定状态。如果没有有效的stateid,服务器将假定客户端具有最少的访问权限。例如,无法使用通过查找获得的文件句柄访问以拒绝读/写方式打开的文件,因为该文件没有有效的stateid(即使用所有位0或所有位1的stateid)。

8.10. Open Upgrade and Downgrade
8.10. 开放式升级和降级

When an OPEN is done for a file and the lockowner for which the open is being done already has the file open, the result is to upgrade the open file status maintained on the server to include the access and deny bits specified by the new OPEN as well as those for the existing OPEN. The result is that there is one open file, as far as the protocol is concerned, and it includes the union of the access and deny bits for all of the OPEN requests completed. Only a single CLOSE will be done to reset the effects of both OPEN's. Note that the client, when issuing the OPEN, may not know that the same file is in fact being opened. The above only applies if both OPEN's result in the OPEN'ed object being designated by the same filehandle.

当对文件执行打开操作并且正在执行打开操作的锁所有者已经打开了该文件时,结果是升级服务器上维护的打开文件状态,以包括新打开指定的访问和拒绝位以及现有打开指定的访问和拒绝位。结果是,就协议而言,有一个打开的文件,它包括所有已完成的打开请求的访问位和拒绝位的联合。只有一次关闭才能重置两次打开的效果。请注意,客户端在发出OPEN命令时,可能不知道实际上正在打开同一个文件。仅当两个OPEN的结果是由同一个filehandle指定打开的对象时,上述内容才适用。

When the server chooses to export multiple filehandles corresponding to the same file object and returns different filehandles on two different OPEN's of the same file object, the server MUST NOT "OR" together the access and deny bits and coalesce the two open files. Instead the server must maintain separate OPEN's with separate stateid's and will require separate CLOSE's to free them.

当服务器选择导出对应于同一文件对象的多个文件句柄,并在同一文件对象的两个不同打开项上返回不同的文件句柄时,服务器不得将访问和拒绝位“或”组合在一起,并合并两个打开的文件。相反,服务器必须使用单独的stateid维护单独的OPEN,并需要单独的CLOSE来释放它们。

When multiple open files on the client are merged into a single open file object on the server, the close of one of the open files (on the client) may necessitate change of the access and deny status of the open file on the server. This is because the union of the access and deny bits for the remaining open's may be smaller (i.e. a proper subset) than previously. The OPEN_DOWNGRADE operation is used to make the necessary change and the client should use it to update the server so that share reservation requests by other clients are handled properly.

当客户端上的多个打开的文件合并到服务器上的单个打开的文件对象中时,关闭其中一个打开的文件(客户端上)可能需要更改服务器上打开的文件的访问和拒绝状态。这是因为剩余开放的访问位和拒绝位的并集可能比以前更小(即,适当的子集)。OPEN_降级操作用于进行必要的更改,客户端应使用它更新服务器,以便正确处理其他客户端的共享保留请求。

8.11. Short and Long Leases
8.11. 短期和长期租赁

When determining the time period for the server lease, the usual lease tradeoffs apply. Short leases are good for fast server recovery at a cost of increased RENEW or READ (with zero length) requests. Longer leases are certainly kinder and gentler to large internet servers trying to handle very large numbers of clients. The number of RENEW requests drop in proportion to the lease time. The disadvantages of long leases are slower recovery after server failure (server must wait for leases to expire and grace period before

在确定服务器租用的时间段时,通常的租用权衡适用。短租约有利于快速服务器恢复,但代价是续订或读取(长度为零)请求增加。对于那些试图处理大量客户端的大型互联网服务器来说,更长的租赁期当然更友好、更温和。续订请求的数量与租赁时间成比例下降。长租约的缺点是服务器故障后恢复较慢(服务器必须等待租约到期,宽限期在到期之前)

granting new lock requests) and increased file contention (if client fails to transmit an unlock request then server must wait for lease expiration before granting new locks).

授予新锁请求)和增加的文件争用(若客户端无法传输解锁请求,则服务器必须等待租约到期后再授予新锁)。

Long leases are usable if the server is able to store lease state in non-volatile memory. Upon recovery, the server can reconstruct the lease state from its non-volatile memory and continue operation with its clients and therefore long leases are not an issue.

如果服务器能够在非易失性内存中存储租约状态,则长租约是可用的。恢复后,服务器可以从其非易失性内存重建租约状态,并继续使用其客户端进行操作,因此长租约不是问题。

8.12. Clocks and Calculating Lease Expiration
8.12. 时钟和计算租赁期限

To avoid the need for synchronized clocks, lease times are granted by the server as a time delta. However, there is a requirement that the client and server clocks do not drift excessively over the duration of the lock. There is also the issue of propagation delay across the network which could easily be several hundred milliseconds as well as the possibility that requests will be lost and need to be retransmitted.

为了避免需要同步时钟,服务器将租赁时间作为时间增量授予。但是,有一个要求,即客户机和服务器时钟在锁定期间不会过度漂移。还有一个问题是网络中的传播延迟,很容易达到几百毫秒,并且请求可能会丢失,需要重新传输。

To take propagation delay into account, the client should subtract it from lease times (e.g. if the client estimates the one-way propagation delay as 200 msec, then it can assume that the lease is already 200 msec old when it gets it). In addition, it will take another 200 msec to get a response back to the server. So the client must send a lock renewal or write data back to the server 400 msec before the lease would expire.

为了将传播延迟考虑在内,客户机应将其从租赁时间中减去(例如,如果客户机估计单向传播延迟为200毫秒,则可以假设在获得租赁时,租赁已经存在200毫秒)。此外,还需要200毫秒才能将响应返回到服务器。因此,客户端必须在租约到期前400毫秒向服务器发送锁续订或写回数据。

8.13. Migration, Replication and State
8.13. 迁移、复制和状态

When responsibility for handling a given file system is transferred to a new server (migration) or the client chooses to use an alternate server (e.g. in response to server unresponsiveness) in the context of file system replication, the appropriate handling of state shared between the client and server (i.e. locks, leases, stateid's, and clientid's) is as described below. The handling differs between migration and replication. For related discussion of file server state and recover of such see the sections under "File Locking and Share Reservations"

当处理给定文件系统的责任转移到新服务器(迁移)或客户端选择在文件系统复制上下文中使用备用服务器(例如,响应服务器无响应)时,客户端和服务器之间共享的状态的适当处理(即锁、租约、stateid和clientid)如下所述。迁移和复制的处理方式不同。有关文件服务器状态和恢复的相关讨论,请参阅“文件锁定和共享保留”下的部分

8.13.1. Migration and State
8.13.1. 移民与国家

In the case of migration, the servers involved in the migration of a file system SHOULD transfer all server state from the original to the new server. This must be done in a way that is transparent to the client. This state transfer will ease the client's transition when a file system migration occurs. If the servers are successful in transferring all state, the client will continue to use stateid's assigned by the original server. Therefore the new server must

在迁移的情况下,参与文件系统迁移的服务器应将所有服务器状态从原始服务器传输到新服务器。这必须以对客户端透明的方式完成。当发生文件系统迁移时,此状态传输将简化客户端的转换。如果服务器成功传输所有状态,客户端将继续使用原始服务器分配的stateid。因此,新服务器必须

recognize these stateid's as valid. This holds true for the clientid as well. Since responsibility for an entire file system is transferred with a migration event, there is no possibility that conflicts will arise on the new server as a result of the transfer of locks.

将这些stateid识别为有效。这也适用于客户ID。由于整个文件系统的责任是通过迁移事件转移的,因此不可能由于锁的转移而在新服务器上产生冲突。

As part of the transfer of information between servers, leases would be transferred as well. The leases being transferred to the new server will typically have a different expiration time from those for the same client, previously on the new server. To maintain the property that all leases on a given server for a given client expire at the same time, the server should advance the expiration time to the later of the leases being transferred or the leases already present. This allows the client to maintain lease renewal of both classes without special effort.

作为服务器间信息传输的一部分,租约也将进行传输。传输到新服务器的租约的到期时间通常与以前在新服务器上传输到同一客户机的租约的到期时间不同。要维护给定客户端的给定服务器上的所有租约同时到期的属性,服务器应将到期时间提前到正在传输的租约或已存在的租约中的较晚者。这允许客户无需特别努力即可维持这两个类别的租赁续期。

The servers may choose not to transfer the state information upon migration. However, this choice is discouraged. In this case, when the client presents state information from the original server, the client must be prepared to receive either NFS4ERR_STALE_CLIENTID or NFS4ERR_STALE_STATEID from the new server. The client should then recover its state information as it normally would in response to a server failure. The new server must take care to allow for the recovery of state information as it would in the event of server restart.

服务器可以选择在迁移时不传输状态信息。然而,这种选择是不可取的。在这种情况下,当客户端显示来自原始服务器的状态信息时,客户端必须准备从新服务器接收NFS4ERR_STALE_CLIENTID或NFS4ERR_STALE_STATEID。然后,客户机应恢复其状态信息,这与正常情况下响应服务器故障时一样。新服务器必须注意恢复状态信息,就像服务器重新启动时一样。

8.13.2. Replication and State
8.13.2. 复制和状态

Since client switch-over in the case of replication is not under server control, the handling of state is different. In this case, leases, stateid's and clientid's do not have validity across a transition from one server to another. The client must re-establish its locks on the new server. This can be compared to the re-establishment of locks by means of reclaim-type requests after a server reboot. The difference is that the server has no provision to distinguish requests reclaiming locks from those obtaining new locks or to defer the latter. Thus, a client re-establishing a lock on the new server (by means of a LOCK or OPEN request), may have the requests denied due to a conflicting lock. Since replication is intended for read-only use of filesystems, such denial of locks should not pose large difficulties in practice. When an attempt to re-establish a lock on a new server is denied, the client should treat the situation as if his original lock had been revoked.

由于复制情况下的客户端切换不受服务器控制,因此状态的处理是不同的。在这种情况下,租约、stateid和clientid在从一台服务器到另一台服务器的转换期间不具有有效性。客户端必须在新服务器上重新建立其锁。这可以与服务器重新启动后通过回收类型请求重新建立锁进行比较。不同之处在于,服务器没有规定区分请求回收锁和请求获得新锁或延迟后者。因此,在新服务器上重新建立锁的客户端(通过锁或打开请求)可能会由于锁冲突而拒绝请求。由于复制旨在以只读方式使用文件系统,因此这种拒绝锁定在实践中不会造成很大困难。当在新服务器上重新建立锁的尝试被拒绝时,客户端应将这种情况视为其原始锁已被撤销。

8.13.3. Notification of Migrated Lease
8.13.3. 迁移租约的通知

In the case of lease renewal, the client may not be submitting requests for a file system that has been migrated to another server. This can occur because of the implicit lease renewal mechanism. The client renews leases for all file systems when submitting a request to any one file system at the server.

在租约续订的情况下,客户端可能不会提交已迁移到另一台服务器的文件系统的请求。这可能是由于隐式租约续订机制造成的。当向服务器上的任何一个文件系统提交请求时,客户端将续订所有文件系统的租约。

In order for the client to schedule renewal of leases that may have been relocated to the new server, the client must find out about lease relocation before those leases expire. To accomplish this, all operations which implicitly renew leases for a client (i.e. OPEN, CLOSE, READ, WRITE, RENEW, LOCK, LOCKT, LOCKU), will return the error NFS4ERR_LEASE_MOVED if responsibility for any of the leases to be renewed has been transferred to a new server. This condition will continue until the client receives an NFS4ERR_MOVED error and the server receives the subsequent GETATTR(fs_locations) for an access to each file system for which a lease has been moved to a new server.

为了让客户端计划可能已重新定位到新服务器的租约的续订,客户端必须在这些租约到期之前了解租约重新定位。为此,如果要续订的任何租约的责任已转移到新服务器,则隐式续订客户端租约的所有操作(即打开、关闭、读取、写入、续订、锁定、锁定、锁定、锁定)将返回错误NFS4ERR_LEASE_MOVED。此情况将持续,直到客户端收到NFS4ERR_MOVED错误,并且服务器收到后续GETATTR(fs_位置)以访问已将租约移动到新服务器的每个文件系统。

When a client receives an NFS4ERR_LEASE_MOVED error, it should perform some operation, such as a RENEW, on each file system associated with the server in question. When the client receives an NFS4ERR_MOVED error, the client can follow the normal process to obtain the new server information (through the fs_locations attribute) and perform renewal of those leases on the new server. If the server has not had state transferred to it transparently, it will receive either NFS4ERR_STALE_CLIENTID or NFS4ERR_STALE_STATEID from the new server, as described above, and can then recover state information as it does in the event of server failure.

当客户端收到NFS4ERR_LEASE_MOVED错误时,它应该对与所述服务器关联的每个文件系统执行某些操作,例如续订。当客户端接收到NFS4ERR_MOVED错误时,客户端可以按照正常过程获取新服务器信息(通过fs_locations属性),并在新服务器上执行这些租约的续订。如果服务器没有透明地向其传输状态,它将从新服务器接收NFS4ERR_STALE_CLIENTID或NFS4ERR_STALE_STATEID,如上所述,然后可以恢复状态信息,就像在服务器发生故障时一样。

9. Client-Side Caching
9. 客户端缓存

Client-side caching of data, of file attributes, and of file names is essential to providing good performance with the NFS protocol. Providing distributed cache coherence is a difficult problem and previous versions of the NFS protocol have not attempted it. Instead, several NFS client implementation techniques have been used to reduce the problems that a lack of coherence poses for users. These techniques have not been clearly defined by earlier protocol specifications and it is often unclear what is valid or invalid client behavior.

数据、文件属性和文件名的客户端缓存对于使用NFS协议提供良好性能至关重要。提供分布式缓存一致性是一个难题,以前的NFS协议版本没有尝试过。相反,使用了几种NFS客户端实现技术来减少缺乏一致性给用户带来的问题。这些技术在早期的协议规范中没有明确定义,并且通常不清楚什么是有效的或无效的客户端行为。

The NFS version 4 protocol uses many techniques similar to those that have been used in previous protocol versions. The NFS version 4 protocol does not provide distributed cache coherence. However, it defines a more limited set of caching guarantees to allow locks and share reservations to be used without destructive interference from client side caching.

NFS版本4协议使用了许多与以前协议版本中使用的技术类似的技术。NFS版本4协议不提供分布式缓存一致性。但是,它定义了一组更有限的缓存保证,以允许在不受客户端缓存破坏性干扰的情况下使用锁和共享保留。

In addition, the NFS version 4 protocol introduces a delegation mechanism which allows many decisions normally made by the server to be made locally by clients. This mechanism provides efficient support of the common cases where sharing is infrequent or where sharing is read-only.

此外,NFS版本4协议引入了一种委托机制,它允许客户端在本地做出通常由服务器做出的许多决策。此机制为共享不频繁或共享为只读的常见情况提供了有效支持。

9.1. Performance Challenges for Client-Side Caching
9.1. 客户端缓存的性能挑战

Caching techniques used in previous versions of the NFS protocol have been successful in providing good performance. However, several scalability challenges can arise when those techniques are used with very large numbers of clients. This is particularly true when clients are geographically distributed which classically increases the latency for cache revalidation requests.

NFS协议早期版本中使用的缓存技术已经成功地提供了良好的性能。然而,当这些技术用于大量客户机时,可能会出现一些可伸缩性挑战。当客户端分布在不同的地理位置时尤其如此,这通常会增加缓存重新验证请求的延迟。

The previous versions of the NFS protocol repeat their file data cache validation requests at the time the file is opened. This behavior can have serious performance drawbacks. A common case is one in which a file is only accessed by a single client. Therefore, sharing is infrequent.

NFS协议的早期版本在打开文件时重复其文件数据缓存验证请求。这种行为可能有严重的性能缺陷。一种常见的情况是,一个文件只能由一个客户端访问。因此,共享很少。

In this case, repeated reference to the server to find that no conflicts exist is expensive. A better option with regards to performance is to allow a client that repeatedly opens a file to do so without reference to the server. This is done until potentially conflicting operations from another client actually occur.

在这种情况下,重复引用服务器以发现不存在冲突是非常昂贵的。关于性能,一个更好的选择是允许重复打开文件的客户机这样做,而无需参考服务器。这将一直执行,直到来自另一个客户端的潜在冲突操作实际发生为止。

A similar situation arises in connection with file locking. Sending file lock and unlock requests to the server as well as the read and write requests necessary to make data caching consistent with the locking semantics (see the section "Data Caching and File Locking") can severely limit performance. When locking is used to provide protection against infrequent conflicts, a large penalty is incurred. This penalty may discourage the use of file locking by applications.

在文件锁定方面也会出现类似的情况。向服务器发送文件锁定和解锁请求以及使数据缓存与锁定语义一致所需的读写请求(请参阅“数据缓存和文件锁定”一节)会严重限制性能。如果使用锁定来防止不经常发生的冲突,则会产生很大的损失。此惩罚可能会阻止应用程序使用文件锁定。

The NFS version 4 protocol provides more aggressive caching strategies with the following design goals:

NFS版本4协议提供了更积极的缓存策略,具有以下设计目标:

o Compatibility with a large range of server semantics.

o 与大量服务器语义的兼容性。

o Provide the same caching benefits as previous versions of the NFS protocol when unable to provide the more aggressive model.

o 当无法提供更具攻击性的模型时,提供与以前版本的NFS协议相同的缓存好处。

o Requirements for aggressive caching are organized so that a large portion of the benefit can be obtained even when not all of the requirements can be met.

o 对主动缓存的需求进行了组织,这样即使不能满足所有需求,也可以获得大部分好处。

The appropriate requirements for the server are discussed in later sections in which specific forms of caching are covered. (see the section "Open Delegation").

服务器的适当要求将在后面的章节中讨论,其中将介绍特定形式的缓存。(见“公开授权”一节)。

9.2. Delegation and Callbacks
9.2. 委托和回调

Recallable delegation of server responsibilities for a file to a client improves performance by avoiding repeated requests to the server in the absence of inter-client conflict. With the use of a "callback" RPC from server to client, a server recalls delegated responsibilities when another client engages in sharing of a delegated file.

在没有客户端间冲突的情况下,通过避免向服务器重复请求,将文件的服务器责任可重新分配给客户端,从而提高了性能。通过使用从服务器到客户端的“回调”RPC,当另一个客户端参与共享委托文件时,服务器会调用委托的职责。

A delegation is passed from the server to the client, specifying the object of the delegation and the type of delegation. There are different types of delegations but each type contains a stateid to be used to represent the delegation when performing operations that depend on the delegation. This stateid is similar to those associated with locks and share reservations but differs in that the stateid for a delegation is associated with a clientid and may be used on behalf of all the nfs_lockowners for the given client. A delegation is made to the client as a whole and not to any specific process or thread of control within it.

委托从服务器传递到客户端,指定委托对象和委托类型。有不同类型的委托,但每种类型都包含一个stateid,用于在执行依赖于委托的操作时表示委托。此stateid类似于与锁和共享保留关联的stateid,但不同之处在于,委派的stateid与clientid关联,并且可以代表给定客户端的所有nfs_锁所有者使用。委托是作为一个整体委托给客户机的,而不是委托给客户机中的任何特定进程或控制线程。

Because callback RPCs may not work in all environments (due to firewalls, for example), correct protocol operation does not depend on them. Preliminary testing of callback functionality by means of a CB_NULL procedure determines whether callbacks can be supported. The CB_NULL procedure checks the continuity of the callback path. A server makes a preliminary assessment of callback availability to a given client and avoids delegating responsibilities until it has determined that callbacks are supported. Because the granting of a delegation is always conditional upon the absence of conflicting access, clients must not assume that a delegation will be granted and they must always be prepared for OPENs to be processed without any delegations being granted.

由于回调RPC可能无法在所有环境中工作(例如,由于防火墙),因此正确的协议操作并不依赖于它们。通过CB_NULL过程对回调功能进行初步测试,确定是否支持回调。CB_NULL过程检查回调路径的连续性。服务器对给定客户端的回调可用性进行初步评估,并在确定回调受支持之前避免委派责任。由于授予委托始终以不存在冲突访问为条件,因此客户端不得假定将授予委托,并且必须始终准备好在未授予任何委托的情况下进行处理。

Once granted, a delegation behaves in most ways like a lock. There is an associated lease that is subject to renewal together with all of the other leases held by that client.

一旦授权,委托的行为在大多数情况下都像锁一样。存在相关租赁,该租赁须与该客户持有的所有其他租赁一起续期。

Unlike locks, an operation by a second client to a delegated file will cause the server to recall a delegation through a callback.

与锁不同,第二个客户端对委托文件的操作将导致服务器通过回调调用委托。

On recall, the client holding the delegation must flush modified state (such as modified data) to the server and return the delegation. The conflicting request will not receive a response until the recall is complete. The recall is considered complete when

调用时,持有委托的客户端必须将修改状态(如修改的数据)刷新到服务器并返回委托。在召回完成之前,冲突请求不会收到响应。在下列情况下,召回被视为完成:

the client returns the delegation or the server times out on the recall and revokes the delegation as a result of the timeout. Following the resolution of the recall, the server has the information necessary to grant or deny the second client's request.

客户端返回委派,或者服务器在调用时超时,并由于超时而撤消委派。在解决召回问题后,服务器具有批准或拒绝第二个客户端请求所需的信息。

At the time the client receives a delegation recall, it may have substantial state that needs to be flushed to the server. Therefore, the server should allow sufficient time for the delegation to be returned since it may involve numerous RPCs to the server. If the server is able to determine that the client is diligently flushing state to the server as a result of the recall, the server may extend the usual time allowed for a recall. However, the time allowed for recall completion should not be unbounded.

在客户机接收到委派回调时,它可能具有需要刷新到服务器的实质性状态。因此,服务器应该为委托返回留出足够的时间,因为它可能涉及到服务器的多个RPC。如果服务器能够确定客户机由于调用而正在向服务器刷新状态,则服务器可以延长允许调用的通常时间。然而,召回完成所允许的时间不应该是无界的。

An example of this is when responsibility to mediate opens on a given file is delegated to a client (see the section "Open Delegation"). The server will not know what opens are in effect on the client. Without this knowledge the server will be unable to determine if the access and deny state for the file allows any particular open until the delegation for the file has been returned.

这方面的一个例子是,将对给定文件进行调解的责任委托给客户机(请参阅“开放委托”一节)。服务器将不知道在客户端上打开的是什么。如果不知道这一点,服务器将无法确定文件的访问和拒绝状态是否允许任何特定的打开,直到文件的委托被返回。

A client failure or a network partition can result in failure to respond to a recall callback. In this case, the server will revoke the delegation which in turn will render useless any modified state still on the client.

客户端故障或网络分区可能导致无法响应回调。在这种情况下,服务器将撤销委托,这反过来会使客户机上的任何修改状态变得无用。

9.2.1. Delegation Recovery
9.2.1. 授权恢复

There are three situations that delegation recovery must deal with:

授权恢复必须处理三种情况:

o Client reboot or restart

o 客户端重新启动或重新启动

o Server reboot or restart

o 服务器重新启动或重新启动

o Network partition (full or callback-only)

o 网络分区(完全或仅回调)

In the event the client reboots or restarts, the failure to renew leases will result in the revocation of record locks and share reservations. Delegations, however, may be treated a bit differently.

在客户端重新启动或重新启动的情况下,未能续订租约将导致撤销记录锁和共享保留。然而,代表团的待遇可能有所不同。

There will be situations in which delegations will need to be reestablished after a client reboots or restarts. The reason for this is the client may have file data stored locally and this data was associated with the previously held delegations. The client will need to reestablish the appropriate file state on the server.

在某些情况下,客户机重新启动或重新启动后,需要重新建立委派。原因是客户机可能在本地存储了文件数据,并且该数据与以前持有的委托相关。客户端需要在服务器上重新建立适当的文件状态。

To allow for this type of client recovery, the server may extend the period for delegation recovery beyond the typical lease expiration period. This implies that requests from other clients that conflict with these delegations will need to wait. Because the normal recall process may require significant time for the client to flush changed state to the server, other clients need be prepared for delays that occur because of a conflicting delegation. This longer interval would increase the window for clients to reboot and consult stable storage so that the delegations can be reclaimed. For open delegations, such delegations are reclaimed using OPEN with a claim type of CLAIM_DELEGATE_PREV. (see the sections on "Data Caching and Revocation" and "Operation 18: OPEN" for discussion of open delegation and the details of OPEN respectively).

为了允许这种类型的客户端恢复,服务器可以将委派恢复的时间延长到典型租约到期时间之后。这意味着与这些委托冲突的其他客户机的请求将需要等待。由于正常的回调过程可能需要很长的时间,客户端才能将更改的状态刷新到服务器,因此其他客户端需要为由于委托冲突而发生的延迟做好准备。此较长的间隔将增加客户端重新启动和查阅稳定存储的窗口,以便可以回收委派。对于开放委托,使用索赔类型为claim_DELEGATE_PREV的open回收此类委托。(有关开放委托和开放的详细信息,请分别参阅“数据缓存和撤销”和“操作18:开放”部分)。

When the server reboots or restarts, delegations are reclaimed (using the OPEN operation with CLAIM_DELEGATE_PREV) in a similar fashion to record locks and share reservations. However, there is a slight semantic difference. In the normal case if the server decides that a delegation should not be granted, it performs the requested action (e.g. OPEN) without granting any delegation. For reclaim, the server grants the delegation but a special designation is applied so that the client treats the delegation as having been granted but recalled by the server. Because of this, the client has the duty to write all modified state to the server and then return the delegation. This process of handling delegation reclaim reconciles three principles of the NFS Version 4 protocol:

服务器重新启动或重新启动时,将以类似的方式回收委派(使用CLAIM_DELEGATE_PREV的OPEN操作),以记录锁定和共享保留。然而,有一点语义上的差异。在正常情况下,如果服务器决定不应授予委派,它将执行请求的操作(例如OPEN),而不授予任何委派。对于回收,服务器授予委派,但应用了特殊的指定,以便客户端将委派视为已被授予但被服务器调用。因此,客户机有责任将所有修改的状态写入服务器,然后返回委托。此处理委派回收的过程符合NFS版本4协议的三个原则:

o Upon reclaim, a client reporting resources assigned to it by an earlier server instance must be granted those resources.

o 回收时,必须向由早期服务器实例分配给它的报告资源的客户端授予这些资源。

o The server has unquestionable authority to determine whether delegations are to be granted and, once granted, whether they are to be continued.

o 服务器无疑有权决定是否授予委托,一旦授予,是否继续。

o The use of callbacks is not to be depended upon until the client has proven its ability to receive them.

o 在客户机证明其有能力接收回调之前,不能依赖回调的使用。

When a network partition occurs, delegations are subject to freeing by the server when the lease renewal period expires. This is similar to the behavior for locks and share reservations. For delegations, however, the server may extend the period in which conflicting requests are held off. Eventually the occurrence of a conflicting request from another client will cause revocation of the delegation. A loss of the callback path (e.g. by later network configuration change) will have the same effect. A recall request will fail and revocation of the delegation will result.

当发生网络分区时,当租约续订期到期时,服务器将释放委派。这类似于锁和共享保留的行为。但是,对于委托,服务器可以延长延迟冲突请求的时间。最终,来自另一个客户端的冲突请求将导致委托的撤销。回调路径的丢失(例如,由于以后的网络配置更改)也会产生相同的影响。召回请求将失败,并将导致撤销委托。

A client normally finds out about revocation of a delegation when it uses a stateid associated with a delegation and receives the error NFS4ERR_EXPIRED. It also may find out about delegation revocation after a client reboot when it attempts to reclaim a delegation and receives that same error. Note that in the case of a revoked write open delegation, there are issues because data may have been modified by the client whose delegation is revoked and separately by other clients. See the section "Revocation Recovery for Write Open Delegation" for a discussion of such issues. Note also that when delegations are revoked, information about the revoked delegation will be written by the server to stable storage (as described in the section "Crash Recovery"). This is done to deal with the case in which a server reboots after revoking a delegation but before the client holding the revoked delegation is notified about the revocation.

当客户端使用与委派关联的stateid并收到错误NFS4ERR_EXPIRED时,通常会发现委派的吊销。当它尝试回收委托并收到相同的错误时,它还可能在客户端重新启动后发现委托撤销。请注意,在撤销写开放委托的情况下,存在一些问题,因为数据可能已被其委托被撤销的客户机修改,也可能被其他客户机单独修改。有关此类问题的讨论,请参阅“写开放委派的吊销恢复”一节。还请注意,当委托被撤销时,服务器将把有关被撤销委托的信息写入稳定存储(如“崩溃恢复”一节所述)。这样做是为了处理这样的情况,即服务器在撤销委派之后,但在持有已撤销委派的客户端收到有关撤销的通知之前重新启动。

9.3. Data Caching
9.3. 数据缓存

When applications share access to a set of files, they need to be implemented so as to take account of the possibility of conflicting access by another application. This is true whether the applications in question execute on different clients or reside on the same client.

当应用程序共享对一组文件的访问时,需要实现它们,以便考虑到另一个应用程序访问冲突的可能性。无论所讨论的应用程序是在不同的客户机上执行还是驻留在同一客户机上,都是如此。

Share reservations and record locks are the facilities the NFS version 4 protocol provides to allow applications to coordinate access by providing mutual exclusion facilities. The NFS version 4 protocol's data caching must be implemented such that it does not invalidate the assumptions that those using these facilities depend upon.

共享保留和记录锁是NFS版本4协议提供的功能,允许应用程序通过提供互斥功能来协调访问。必须实现NFS版本4协议的数据缓存,以使使用这些功能的人所依赖的假设不会失效。

9.3.1. Data Caching and OPENs
9.3.1. 数据缓存并打开

In order to avoid invalidating the sharing assumptions that applications rely on, NFS version 4 clients should not provide cached data to applications or modify it on behalf of an application when it would not be valid to obtain or modify that same data via a READ or WRITE operation.

为了避免使应用程序所依赖的共享假设无效,当通过读或写操作获取或修改相同数据无效时,NFS版本4客户端不应向应用程序提供缓存数据或代表应用程序修改缓存数据。

Furthermore, in the absence of open delegation (see the section "Open Delegation") two additional rules apply. Note that these rules are obeyed in practice by many NFS version 2 and version 3 clients.

此外,在没有公开授权的情况下(见“公开授权”一节),适用两条附加规则。请注意,许多NFS版本2和版本3客户端实际上都遵守这些规则。

o First, cached data present on a client must be revalidated after doing an OPEN. This is to ensure that the data for the OPENed file is still correctly reflected in the client's cache. This validation must be done at least when the client's OPEN operation includes DENY=WRITE or BOTH thus terminating a period in which

o 首先,客户端上存在的缓存数据必须在执行打开后重新验证。这是为了确保已打开文件的数据仍然正确地反映在客户端缓存中。此验证必须至少在客户端的打开操作包含DENY=WRITE或两者同时包含时进行,从而终止

other clients may have had the opportunity to open the file with WRITE access. Clients may choose to do the revalidation more often (i.e. at OPENs specifying DENY=NONE) to parallel the NFS version 3 protocol's practice for the benefit of users assuming this degree of cache revalidation.

其他客户端可能有机会使用写访问权限打开该文件。客户端可能会选择更频繁地执行重新验证(即,在打开时指定DENY=NONE),以与NFS版本3协议的实践并行,从而使用户能够假定这种程度的缓存重新验证。

o Second, modified data must be flushed to the server before closing a file OPENed for write. This is complementary to the first rule. If the data is not flushed at CLOSE, the revalidation done after client OPENs as file is unable to achieve its purpose. The other aspect to flushing the data before close is that the data must be committed to stable storage, at the server, before the CLOSE operation is requested by the client. In the case of a server reboot or restart and a CLOSEd file, it may not be possible to retransmit the data to be written to the file. Hence, this requirement.

o 其次,在关闭为写入而打开的文件之前,必须将修改后的数据刷新到服务器。这是对第一条规则的补充。如果在关闭时未刷新数据,则在客户端以文件形式打开后进行的重新验证无法达到其目的。关闭前刷新数据的另一个方面是,在客户端请求关闭操作之前,必须将数据提交到服务器上的稳定存储中。在服务器重新启动或重新启动以及文件关闭的情况下,可能无法重新传输要写入文件的数据。因此,这是一项要求。

9.3.2. Data Caching and File Locking
9.3.2. 数据缓存和文件锁定

For those applications that choose to use file locking instead of share reservations to exclude inconsistent file access, there is an analogous set of constraints that apply to client side data caching. These rules are effective only if the file locking is used in a way that matches in an equivalent way the actual READ and WRITE operations executed. This is as opposed to file locking that is based on pure convention. For example, it is possible to manipulate a two-megabyte file by dividing the file into two one-megabyte regions and protecting access to the two regions by file locks on bytes zero and one. A lock for write on byte zero of the file would represent the right to do READ and WRITE operations on the first region. A lock for write on byte one of the file would represent the right to do READ and WRITE operations on the second region. As long as all applications manipulating the file obey this convention, they will work on a local file system. However, they may not work with the NFS version 4 protocol unless clients refrain from data caching.

对于那些选择使用文件锁定而不是共享保留来排除不一致的文件访问的应用程序,有一组类似的约束适用于客户端数据缓存。这些规则只有在文件锁定的使用方式与实际执行的读写操作相匹配时才有效。这与基于纯约定的文件锁定相反。例如,可以通过将文件划分为两个1兆字节的区域,并通过对字节0和字节1的文件锁定来保护对这两个区域的访问,从而操纵一个2兆字节的文件。文件字节0上的写锁定表示对第一个区域执行读写操作的权限。文件字节1上的写锁定表示对第二个区域执行读写操作的权限。只要操作文件的所有应用程序都遵守此约定,它们就可以在本地文件系统上工作。但是,除非客户端不进行数据缓存,否则它们可能无法使用NFS版本4协议。

The rules for data caching in the file locking environment are:

文件锁定环境中的数据缓存规则包括:

o First, when a client obtains a file lock for a particular region, the data cache corresponding to that region (if any cache data exists) must be revalidated. If the change attribute indicates that the file may have been updated since the cached data was obtained, the client must flush or invalidate the cached data for the newly locked region. A client might choose to invalidate all of non-modified cached data that it has for the file but the only requirement for correct operation is to invalidate all of the data in the newly locked region.

o 首先,当客户端获得特定区域的文件锁时,必须重新验证与该区域对应的数据缓存(如果存在任何缓存数据)。如果change属性指示文件可能在获取缓存数据后已更新,则客户端必须刷新或使新锁定区域的缓存数据无效。客户端可能会选择使其对文件拥有的所有未修改的缓存数据无效,但正确操作的唯一要求是使新锁定区域中的所有数据无效。

o Second, before releasing a write lock for a region, all modified data for that region must be flushed to the server. The modified data must also be written to stable storage.

o 其次,在释放区域的写锁之前,必须将该区域的所有修改数据刷新到服务器。修改后的数据还必须写入稳定的存储器。

Note that flushing data to the server and the invalidation of cached data must reflect the actual byte ranges locked or unlocked. Rounding these up or down to reflect client cache block boundaries will cause problems if not carefully done. For example, writing a modified block when only half of that block is within an area being unlocked may cause invalid modification to the region outside the unlocked area. This, in turn, may be part of a region locked by another client. Clients can avoid this situation by synchronously performing portions of write operations that overlap that portion (initial or final) that is not a full block. Similarly, invalidating a locked area which is not an integral number of full buffer blocks would require the client to read one or two partial blocks from the server if the revalidation procedure shows that the data which the client possesses may not be valid.

请注意,将数据刷新到服务器和缓存数据的失效必须反映锁定或解锁的实际字节范围。如果不小心,向上或向下舍入这些值以反映客户端缓存块边界将导致问题。例如,当修改后的块只有一半在解锁区域内时写入该块可能会导致对解锁区域外区域的无效修改。反过来,这可能是另一个客户端锁定的区域的一部分。客户端可以通过同步执行与非完整块部分(初始或最终)重叠的写入操作部分来避免这种情况。类似地,如果重新验证过程表明客户机拥有的数据可能无效,则使不是完整缓冲区块整数的锁定区域无效将需要客户机从服务器读取一个或两个部分块。

The data that is written to the server as a pre-requisite to the unlocking of a region must be written, at the server, to stable storage. The client may accomplish this either with synchronous writes or by following asynchronous writes with a COMMIT operation. This is required because retransmission of the modified data after a server reboot might conflict with a lock held by another client.

作为解锁区域的先决条件写入服务器的数据必须在服务器上写入稳定存储。客户机可以通过同步写入或使用提交操作跟踪异步写入来完成这一点。这是必需的,因为在服务器重新启动后重新传输修改后的数据可能会与另一个客户端持有的锁冲突。

A client implementation may choose to accommodate applications which use record locking in non-standard ways (e.g. using a record lock as a global semaphore) by flushing to the server more data upon an LOCKU than is covered by the locked range. This may include modified data within files other than the one for which the unlocks are being done. In such cases, the client must not interfere with applications whose READs and WRITEs are being done only within the bounds of record locks which the application holds. For example, an application locks a single byte of a file and proceeds to write that single byte. A client that chose to handle a LOCKU by flushing all modified data to the server could validly write that single byte in response to an unrelated unlock. However, it would not be valid to write the entire block in which that single written byte was located since it includes an area that is not locked and might be locked by another client. Client implementations can avoid this problem by dividing files with modified data into those for which all modifications are done to areas covered by an appropriate record lock and those for which there are modifications not covered by a record lock. Any writes done for the former class of files must not include areas not locked and thus not modified on the client.

客户机实现可以选择通过向服务器刷新锁上超过锁定范围的数据来适应以非标准方式使用记录锁定的应用程序(例如,使用记录锁作为全局信号量)。这可能包括文件中的修改数据,而不是正在进行解锁的文件。在这种情况下,客户机不得干扰仅在应用程序持有的记录锁的范围内进行读写的应用程序。例如,应用程序锁定文件的一个字节并继续写入该字节。选择通过将所有修改的数据刷新到服务器来处理锁定的客户端可以有效地写入该单个字节以响应不相关的解锁。但是,写入单个写入字节所在的整个块是无效的,因为它包含一个未锁定的区域,并且可能被另一个客户端锁定。客户机实现可以通过将具有修改数据的文件划分为对适当记录锁覆盖的区域进行所有修改的文件和未被记录锁覆盖的文件来避免此问题。为前一类文件执行的任何写入操作都不得包括未锁定的区域,因此也不得在客户端上修改这些区域。

9.3.3. Data Caching and Mandatory File Locking
9.3.3. 数据缓存和强制文件锁定

Client side data caching needs to respect mandatory file locking when it is in effect. The presence of mandatory file locking for a given file is indicated in the result flags for an OPEN. When mandatory locking is in effect for a file, the client must check for an appropriate file lock for data being read or written. If a lock exists for the range being read or written, the client may satisfy the request using the client's validated cache. If an appropriate file lock is not held for the range of the read or write, the read or write request must not be satisfied by the client's cache and the request must be sent to the server for processing. When a read or write request partially overlaps a locked region, the request should be subdivided into multiple pieces with each region (locked or not) treated appropriately.

客户端数据缓存在生效时需要遵守强制文件锁定。在打开文件的结果标志中指示给定文件是否存在强制文件锁定。当强制锁定对文件生效时,客户端必须为正在读取或写入的数据检查适当的文件锁定。如果正在读取或写入的范围存在锁,则客户端可以使用客户端的已验证缓存满足请求。如果没有为读或写的范围保留适当的文件锁,则客户端缓存不能满足读或写请求,并且必须将请求发送到服务器进行处理。当读或写请求与锁定区域部分重叠时,应将请求细分为多个部分,并适当处理每个区域(锁定或未锁定)。

9.3.4. Data Caching and File Identity
9.3.4. 数据缓存和文件标识

When clients cache data, the file data needs to organized according to the file system object to which the data belongs. For NFS version 3 clients, the typical practice has been to assume for the purpose of caching that distinct filehandles represent distinct file system objects. The client then has the choice to organize and maintain the data cache on this basis.

当客户端缓存数据时,需要根据数据所属的文件系统对象组织文件数据。对于NFS版本3客户端,典型的做法是为了缓存,假定不同的文件句柄表示不同的文件系统对象。然后,客户机可以在此基础上选择组织和维护数据缓存。

In the NFS version 4 protocol, there is now the possibility to have significant deviations from a "one filehandle per object" model because a filehandle may be constructed on the basis of the object's pathname. Therefore, clients need a reliable method to determine if two filehandles designate the same file system object. If clients were simply to assume that all distinct filehandles denote distinct objects and proceed to do data caching on this basis, caching inconsistencies would arise between the distinct client side objects which mapped to the same server side object.

在NFS版本4协议中,现在可能与“每个对象一个文件句柄”模型存在重大偏差,因为文件句柄可以基于对象的路径名构建。因此,客户端需要一种可靠的方法来确定两个文件句柄是否指定相同的文件系统对象。如果客户端只是假设所有不同的文件句柄都表示不同的对象,并在此基础上继续进行数据缓存,那么映射到同一服务器端对象的不同客户端对象之间就会出现缓存不一致的情况。

By providing a method to differentiate filehandles, the NFS version 4 protocol alleviates a potential functional regression in comparison with the NFS version 3 protocol. Without this method, caching inconsistencies within the same client could occur and this has not been present in previous versions of the NFS protocol. Note that it is possible to have such inconsistencies with applications executing on multiple clients but that is not the issue being addressed here.

通过提供一种区分文件句柄的方法,与NFS版本3协议相比,NFS版本4协议减轻了潜在的功能退化。如果没有此方法,可能会在同一客户机中发生缓存不一致,这在以前版本的NFS协议中是不存在的。请注意,在多个客户端上执行的应用程序可能存在这种不一致,但这不是本文要解决的问题。

For the purposes of data caching, the following steps allow an NFS version 4 client to determine whether two distinct filehandles denote the same server side object:

出于数据缓存的目的,以下步骤允许NFS版本4客户端确定两个不同的文件句柄是否表示相同的服务器端对象:

o If GETATTR directed to two filehandles have different values of the fsid attribute, then the filehandles represent distinct objects.

o 如果指向两个文件句柄的GETATTR具有不同的fsid属性值,则文件句柄表示不同的对象。

o If GETATTR for any file with an fsid that matches the fsid of the two filehandles in question returns a unique_handles attribute with a value of TRUE, then the two objects are distinct.

o 如果fsid与两个文件句柄的fsid相匹配的任何文件的GETATTR返回一个值为TRUE的唯一_handles属性,则这两个对象是不同的。

o If GETATTR directed to the two filehandles does not return the fileid attribute for one or both of the handles, then the it cannot be determined whether the two objects are the same. Therefore, operations which depend on that knowledge (e.g. client side data caching) cannot be done reliably.

o 如果指向两个FileHandle的GETATTR未返回其中一个或两个句柄的fileid属性,则无法确定这两个对象是否相同。因此,依赖于该知识的操作(例如客户端数据缓存)无法可靠地完成。

o If GETATTR directed to the two filehandles returns different values for the fileid attribute, then they are distinct objects.

o 如果指向两个FileHandle的GETATTR为fileid属性返回不同的值,则它们是不同的对象。

o Otherwise they are the same object.

o 否则,它们是同一个对象。

9.4. Open Delegation
9.4. 公开授权

When a file is being OPENed, the server may delegate further handling of opens and closes for that file to the opening client. Any such delegation is recallable, since the circumstances that allowed for the delegation are subject to change. In particular, the server may receive a conflicting OPEN from another client, the server must recall the delegation before deciding whether the OPEN from the other client may be granted. Making a delegation is up to the server and clients should not assume that any particular OPEN either will or will not result in an open delegation. The following is a typical set of conditions that servers might use in deciding whether OPEN should be delegated:

打开文件时,服务器可以将该文件的打开和关闭的进一步处理委托给打开的客户端。任何此类授权都是可撤销的,因为允许授权的情况可能会发生变化。特别是,服务器可能会从另一个客户端接收到冲突的打开,服务器必须在决定是否可以授予来自另一个客户端的打开之前调用委托。委托由服务器决定,客户机不应认为任何特定的开放式委托会或不会导致开放式委托。以下是服务器在决定是否委派OPEN时可能使用的一组典型条件:

o The client must be able to respond to the server's callback requests. The server will use the CB_NULL procedure for a test of callback ability.

o 客户端必须能够响应服务器的回调请求。服务器将使用CB_NULL过程来测试回调能力。

o The client must have responded properly to previous recalls.

o 客户必须对之前的召回做出正确响应。

o There must be no current open conflicting with the requested delegation.

o 必须没有与请求的委派冲突的当前打开。

o There should be no current delegation that conflicts with the delegation being requested.

o 当前不应存在与所请求的授权冲突的授权。

o The probability of future conflicting open requests should be low based on the recent history of the file.

o 根据文件最近的历史记录,未来发生冲突的开放请求的概率应该很低。

o The existence of any server-specific semantics of OPEN/CLOSE that would make the required handling incompatible with the prescribed handling that the delegated client would apply (see below).

o 存在任何特定于服务器的打开/关闭语义,这将使所需的处理与委托客户端将应用的指定处理不兼容(见下文)。

There are two types of open delegations, read and write. A read open delegation allows a client to handle, on its own, requests to open a file for reading that do not deny read access to others. Multiple read open delegations may be outstanding simultaneously and do not conflict. A write open delegation allows the client to handle, on its own, all opens. Only one write open delegation may exist for a given file at a given time and it is inconsistent with any read open delegations.

公开授权有两种类型,读和写。read open委派允许客户端自行处理打开文件进行读取的请求,而不会拒绝其他客户端的读取访问。多个读开放授权可能同时未完成且不冲突。写开放委托允许客户端自行处理所有打开的文件。给定文件在给定时间只能存在一个写开放委托,并且它与任何读开放委托不一致。

When a client has a read open delegation, it may not make any changes to the contents or attributes of the file but it is assured that no other client may do so. When a client has a write open delegation, it may modify the file data since no other client will be accessing the file's data. The client holding a write delegation may only affect file attributes which are intimately connected with the file data: object_size, time_modify, change.

当一个客户机有一个read open委托时,它可能不会对文件的内容或属性进行任何更改,但可以保证其他客户机不会这样做。当客户端具有写开放委托时,它可能会修改文件数据,因为没有其他客户端将访问该文件的数据。持有写委派的客户端可能只影响与文件数据密切相关的文件属性:对象大小、时间、修改、更改。

When a client has an open delegation, it does not send OPENs or CLOSEs to the server but updates the appropriate status internally. For a read open delegation, opens that cannot be handled locally (opens for write or that deny read access) must be sent to the server.

当客户机具有打开的委派时,它不会向服务器发送打开或关闭,而是在内部更新相应的状态。对于读开放委派,必须将无法在本地处理的打开(为写而打开或拒绝读访问)发送到服务器。

When an open delegation is made, the response to the OPEN contains an open delegation structure which specifies the following:

进行开放式委派时,对开放式委派的响应包含一个开放式委派结构,该结构指定以下内容:

o the type of delegation (read or write)

o 委托的类型(读或写)

o space limitation information to control flushing of data on close (write open delegation only, see the section "Open Delegation and Data Caching")

o 控制关闭时数据刷新的空间限制信息(仅写开放委派,请参阅“开放委派和数据缓存”一节)

o an nfsace4 specifying read and write permissions

o 指定读写权限的nfsace4

o a stateid to represent the delegation for READ and WRITE

o 表示读写委托的stateid

The stateid is separate and distinct from the stateid for the OPEN proper. The standard stateid, unlike the delegation stateid, is associated with a particular nfs_lockowner and will continue to be valid after the delegation is recalled and the file remains open.

stateid是独立的,并且不同于OPEN的stateid。与委托stateid不同的是,标准stateid与特定的nfs_锁所有者关联,并且在调用委托并且文件保持打开状态后将继续有效。

When a request internal to the client is made to open a file and open delegation is in effect, it will be accepted or rejected solely on the basis of the following conditions. Any requirement for other checks to be made by the delegate should result in open delegation being denied so that the checks can be made by the server itself.

当向客户发出打开文件的内部请求且“打开委托”生效时,将仅根据以下条件接受或拒绝该请求。委托进行其他检查的任何要求都应导致开放委托被拒绝,以便服务器本身可以进行检查。

o The access and deny bits for the request and the file as described in the section "Share Reservations".

o 请求和文件的访问和拒绝位,如“共享保留”部分所述。

o The read and write permissions as determined below.

o 读取和写入权限如下所示。

The nfsace4 passed with delegation can be used to avoid frequent ACCESS calls. The permission check should be as follows:

通过委派传递的nfsace4可用于避免频繁的访问调用。权限检查应如下所示:

o If the nfsace4 indicates that the open may be done, then it should be granted without reference to the server.

o 如果nfsace4指示可以完成打开,则应在不参考服务器的情况下授予打开。

o If the nfsace4 indicates that the open may not be done, then an ACCESS request must be sent to the server to obtain the definitive answer.

o 如果nfsace4指示可能无法打开,则必须向服务器发送访问请求以获得最终答案。

The server may return an nfsace4 that is more restrictive than the actual ACL of the file. This includes an nfsace4 that specifies denial of all access. Note that some common practices such as mapping the traditional user "root" to the user "nobody" may make it incorrect to return the actual ACL of the file in the delegation response.

服务器可能返回比文件的实际ACL更严格的nfsace4。这包括指定拒绝所有访问的nfsace4。请注意,一些常见做法(如将传统用户“root”映射到用户“nobody”)可能会导致在委派响应中返回文件的实际ACL不正确。

The use of delegation together with various other forms of caching creates the possibility that no server authentication will ever be performed for a given user since all of the user's requests might be satisfied locally. Where the client is depending on the server for authentication, the client should be sure authentication occurs for each user by use of the ACCESS operation. This should be the case even if an ACCESS operation would not be required otherwise. As mentioned before, the server may enforce frequent authentication by returning an nfsace4 denying all access with every open delegation.

委托的使用与各种其他形式的缓存一起产生了一种可能性,即不会对给定用户执行服务器身份验证,因为用户的所有请求都可能在本地得到满足。当客户端依赖服务器进行身份验证时,客户端应确保通过使用访问操作为每个用户进行身份验证。即使不需要访问操作,也应如此。如前所述,服务器可以通过返回一个nfsace4来强制执行频繁身份验证,该nfsace4拒绝每个打开的委托的所有访问。

9.4.1. Open Delegation and Data Caching
9.4.1. 开放委托和数据缓存

OPEN delegation allows much of the message overhead associated with the opening and closing files to be eliminated. An open when an open delegation is in effect does not require that a validation message be sent to the server. The continued endurance of the "read open delegation" provides a guarantee that no OPEN for write and thus no write has occurred. Similarly, when closing a file opened for write and if write open delegation is in effect, the data written does not have to be flushed to the server until the open delegation is

开放式委派允许消除和打开和关闭文件相关的大部分消息开销。开放委派生效时的开放委派不需要向服务器发送验证消息。“读-开委托”的持续耐力保证了不会出现写-开,因此不会发生写。类似地,在关闭为写入而打开的文件时,如果“写入打开”委派生效,则在打开委派生效之前,不必将写入的数据刷新到服务器

recalled. The continued endurance of the open delegation provides a guarantee that no open and thus no read or write has been done by another client.

回忆。开放委托的持续持久性保证了另一个客户机没有进行开放操作,因此也没有进行读写操作。

For the purposes of open delegation, READs and WRITEs done without an OPEN are treated as the functional equivalents of a corresponding type of OPEN. This refers to the READs and WRITEs that use the special stateids consisting of all zero bits or all one bits. Therefore, READs or WRITEs with a special stateid done by another client will force the server to recall a write open delegation. A WRITE with a special stateid done by another client will force a recall of read open delegations.

出于开放式委托的目的,在没有开放式委托的情况下进行的读写操作被视为相应类型的开放式委托的功能等价物。这是指使用由所有零位或所有一位组成的特殊StateID的读写操作。因此,由另一个客户机执行的具有特殊stateid的读取或写入操作将强制服务器调用写开放委托。另一个客户端使用特殊的stateid进行写操作将强制调用读打开的委托。

With delegations, a client is able to avoid writing data to the server when the CLOSE of a file is serviced. The CLOSE operation is the usual point at which the client is notified of a lack of stable storage for the modified file data generated by the application. At the CLOSE, file data is written to the server and through normal accounting the server is able to determine if the available file system space for the data has been exceeded (i.e. server returns NFS4ERR_NOSPC or NFS4ERR_DQUOT). This accounting includes quotas. The introduction of delegations requires that a alternative method be in place for the same type of communication to occur between client and server.

通过委托,客户机可以避免在文件关闭时向服务器写入数据。关闭操作是一个通常的点,在这个点上,客户端会被通知缺少对应用程序生成的修改文件数据的稳定存储。在结束时,文件数据被写入服务器,通过正常记帐,服务器能够确定是否超出了数据的可用文件系统空间(即,服务器返回NFS4ERR_NOSPC或NFS4ERR_DQUOT)。这种核算包括配额。委托的引入要求为客户机和服务器之间发生相同类型的通信提供一种替代方法。

In the delegation response, the server provides either the limit of the size of the file or the number of modified blocks and associated block size. The server must ensure that the client will be able to flush data to the server of a size equal to that provided in the original delegation. The server must make this assurance for all outstanding delegations. Therefore, the server must be careful in its management of available space for new or modified data taking into account available file system space and any applicable quotas. The server can recall delegations as a result of managing the available file system space. The client should abide by the server's state space limits for delegations. If the client exceeds the stated limits for the delegation, the server's behavior is undefined.

在委托响应中,服务器提供文件大小的限制或修改的块数和关联的块大小。服务器必须确保客户端能够将数据刷新到服务器,其大小等于原始委派中提供的大小。服务器必须为所有未完成的委派做出此保证。因此,服务器在管理新数据或修改数据的可用空间时必须谨慎,同时考虑可用的文件系统空间和任何适用的配额。管理可用文件系统空间后,服务器可以调用委派。客户机应该遵守服务器的状态空间限制。如果客户端超过了指定的委托限制,则服务器的行为未定义。

Based on server conditions, quotas or available file system space, the server may grant write open delegations with very restrictive space limitations. The limitations may be defined in a way that will always force modified data to be flushed to the server on close.

根据服务器条件、配额或可用文件系统空间,服务器可以授予具有非常严格的空间限制的写开放委派。这些限制的定义方式可能总是强制在关闭时将修改后的数据刷新到服务器。

With respect to authentication, flushing modified data to the server after a CLOSE has occurred may be problematic. For example, the user of the application may have logged off of the client and unexpired authentication credentials may not be present. In this case, the client may need to take special care to ensure that local unexpired

关于身份验证,在关闭后将修改的数据刷新到服务器可能会有问题。例如,应用程序的用户可能已注销客户端,并且未过期的认证凭证可能不存在。在这种情况下,客户可能需要特别小心,以确保本地未过期

credentials will in fact be available. This may be accomplished by tracking the expiration time of credentials and flushing data well in advance of their expiration or by making private copies of credentials to assure their availability when needed.

事实上,凭证将可用。这可以通过跟踪凭据的过期时间并在其过期之前很好地刷新数据来实现,或者通过制作凭据的私有副本来确保其在需要时的可用性。

9.4.2. Open Delegation and File Locks
9.4.2. 打开委托和文件锁

When a client holds a write open delegation, lock operations are performed locally. This includes those required for mandatory file locking. This can be done since the delegation implies that there can be no conflicting locks. Similarly, all of the revalidations that would normally be associated with obtaining locks and the flushing of data associated with the releasing of locks need not be done.

当客户端持有写开放委托时,锁定操作在本地执行。这包括强制文件锁定所需的文件。这是可以做到的,因为委托意味着不可能有冲突的锁。类似地,通常与获取锁相关的所有重新验证以及与释放锁相关的数据刷新都不需要完成。

9.4.3. Recall of Open Delegation
9.4.3. 召回公开代表团

The following events necessitate recall of an open delegation:

以下事件需要召回公开代表团:

o Potentially conflicting OPEN request (or READ/WRITE done with "special" stateid)

o 潜在冲突的开放请求(或使用“特殊”stateid完成读/写操作)

o SETATTR issued by another client

o 由另一个客户端发出的SETATTR

o REMOVE request for the file

o 删除对该文件的请求

o RENAME request for the file as either source or target of the RENAME

o 将文件重命名为重命名的源或目标的请求

Whether a RENAME of a directory in the path leading to the file results in recall of an open delegation depends on the semantics of the server file system. If that file system denies such RENAMEs when a file is open, the recall must be performed to determine whether the file in question is, in fact, open.

对指向该文件的路径中的目录进行重命名是否会导致调用打开的委托,这取决于服务器文件系统的语义。如果文件系统在文件打开时拒绝此类重命名,则必须执行回调以确定所涉及的文件实际上是否已打开。

In addition to the situations above, the server may choose to recall open delegations at any time if resource constraints make it advisable to do so. Clients should always be prepared for the possibility of recall.

除上述情况外,如果资源限制允许,服务器可以随时选择召回开放的委托。客户应随时做好召回的准备。

The server needs to employ special handling for a GETATTR where the target is a file that has a write open delegation in effect. In this case, the client holding the delegation needs to be interrogated. The server will use a CB_GETATTR callback, if the GETATTR attribute bits include any of the attributes that a write open delegate may modify (object_size, time_modify, change).

服务器需要对GETATTR进行特殊处理,其中目标是具有有效的写开放委派的文件。在这种情况下,需要询问持有委托的客户。如果GETATTR属性位包括写开放委托可能修改的任何属性(对象大小、时间、修改),则服务器将使用CB_GETATTR回调。

When a client receives a recall for an open delegation, it needs to update state on the server before returning the delegation. These same updates must be done whenever a client chooses to return a delegation voluntarily. The following items of state need to be dealt with:

当客户机收到打开的委派的回调时,它需要在返回委派之前更新服务器上的状态。每当客户机选择自愿返回委托时,必须执行这些相同的更新。需要处理下列国家事项:

o If the file associated with the delegation is no longer open and no previous CLOSE operation has been sent to the server, a CLOSE operation must be sent to the server.

o 如果与委派关联的文件不再打开,并且以前的关闭操作未发送到服务器,则必须向服务器发送关闭操作。

o If a file has other open references at the client, then OPEN operations must be sent to the server. The appropriate stateids will be provided by the server for subsequent use by the client since the delegation stateid will not longer be valid. These OPEN requests are done with the claim type of CLAIM_DELEGATE_CUR. This will allow the presentation of the delegation stateid so that the client can establish the appropriate rights to perform the OPEN. (see the section "Operation 18: OPEN" for details.)

o 如果文件在客户端具有其他打开引用,则必须将打开操作发送到服务器。服务器将提供适当的stateid供客户端后续使用,因为委托stateid将不再有效。这些打开的请求使用claim_DELEGATE_CUR的claim类型完成。这将允许呈现委托stateid,以便客户机可以建立适当的权限来执行OPEN。(有关详细信息,请参阅“操作18:打开”一节。)

o If there are granted file locks, the corresponding LOCK operations need to be performed. This applies to the write open delegation case only.

o 如果已授予文件锁,则需要执行相应的锁操作。这仅适用于写开放委托案例。

o For a write open delegation, if at the time of recall the file is not open for write, all modified data for the file must be flushed to the server. If the delegation had not existed, the client would have done this data flush before the CLOSE operation.

o 对于写开放委派,如果在调用时文件未打开进行写操作,则必须将文件的所有修改数据刷新到服务器。如果委托不存在,客户机将在关闭操作之前完成此数据刷新。

o For a write open delegation when a file is still open at the time of recall, any modified data for the file needs to be flushed to the server.

o 对于在回调时文件仍处于打开状态的写开放委派,需要将文件的任何修改数据刷新到服务器。

o With the write open delegation in place, it is possible that the file was truncated during the duration of the delegation. For example, the truncation could have occurred as a result of an OPEN UNCHECKED with a object_size attribute value of zero. Therefore, if a truncation of the file has occurred and this operation has not been propagated to the server, the truncation must occur before any modified data is written to the server.

o 使用“写打开”委派,文件可能在委派期间被截断。例如,截断可能是由于“对象大小”属性值为零的未选中“打开”导致的。因此,如果发生了文件截断,并且此操作尚未传播到服务器,则必须在将任何修改的数据写入服务器之前进行截断。

In the case of write open delegation, file locking imposes some additional requirements. The flushing of any modified data in any region for which a write lock was released while the write open delegation was in effect is what is required to precisely maintain the associated invariant. However, because the write open delegation implies no other locking by other clients, a simpler implementation

在写开放委托的情况下,文件锁定带来了一些额外的要求。在任何区域中刷新任何修改后的数据,在写开放委派生效时为其释放写锁,这是精确维护相关不变量所必需的。但是,由于write-open委托不意味着其他客户机进行其他锁定,因此更简单的实现

is to flush all modified data for the file (as described just above) if any write lock has been released while the write open delegation was in effect.

是刷新文件的所有修改数据(如上所述),如果在“写打开”委托生效时释放了任何写锁。

9.4.4. Delegation Revocation
9.4.4. 委托撤销

At the point a delegation is revoked, if there are associated opens on the client, the applications holding these opens need to be notified. This notification usually occurs by returning errors for READ/WRITE operations or when a close is attempted for the open file.

在委托被撤销时,如果客户端上存在关联的打开,则需要通知持有这些打开的应用程序。此通知通常在读/写操作返回错误或试图关闭打开的文件时发生。

If no opens exist for the file at the point the delegation is revoked, then notification of the revocation is unnecessary. However, if there is modified data present at the client for the file, the user of the application should be notified. Unfortunately, it may not be possible to notify the user since active applications may not be present at the client. See the section "Revocation Recovery for Write Open Delegation" for additional details.

如果在撤销委派时不存在文件的打开,则不需要通知撤销。但是,如果文件的客户端存在修改的数据,则应通知应用程序的用户。不幸的是,由于客户端可能不存在活动应用程序,因此可能无法通知用户。有关更多详细信息,请参阅“写开放委派的吊销恢复”一节。

9.5. Data Caching and Revocation
9.5. 数据缓存和撤销

When locks and delegations are revoked, the assumptions upon which successful caching depend are no longer guaranteed. The owner of the locks or share reservations which have been revoked needs to be notified. This notification includes applications with a file open that has a corresponding delegation which has been revoked. Cached data associated with the revocation must be removed from the client. In the case of modified data existing in the client's cache, that data must be removed from the client without it being written to the server. As mentioned, the assumptions made by the client are no longer valid at the point when a lock or delegation has been revoked. For example, another client may have been granted a conflicting lock after the revocation of the lock at the first client. Therefore, the data within the lock range may have been modified by the other client. Obviously, the first client is unable to guarantee to the application what has occurred to the file in the case of revocation.

当锁和委托被撤销时,成功缓存所依赖的假设将不再得到保证。需要通知已撤销的锁或共享保留的所有者。此通知包括打开文件的应用程序,该文件具有已撤销的相应委派。必须从客户端删除与吊销关联的缓存数据。如果客户端缓存中存在已修改的数据,则必须在不将数据写入服务器的情况下从客户端删除该数据。如前所述,当锁或委托被撤销时,客户端所做的假设不再有效。例如,在第一个客户端撤销锁后,另一个客户端可能已被授予冲突锁。因此,锁定范围内的数据可能已被其他客户端修改。显然,第一个客户端无法向应用程序保证在撤销文件的情况下该文件发生了什么。

Notification to a lock owner will in many cases consist of simply returning an error on the next and all subsequent READs/WRITEs to the open file or on the close. Where the methods available to a client make such notification impossible because errors for certain operations may not be returned, more drastic action such as signals or process termination may be appropriate. The justification for this is that an invariant for which an application depends on may be violated. Depending on how errors are typically treated for the client operating environment, further levels of notification including logging, console messages, and GUI pop-ups may be appropriate.

在许多情况下,对锁所有者的通知只包括在下一次和所有后续读/写打开的文件或关闭时返回错误。如果由于某些操作的错误可能无法返回,客户机可用的方法使得此类通知不可能,则可能需要采取更激烈的措施,如信号或进程终止。这样做的理由是可能会违反应用程序所依赖的不变量。根据客户端操作环境通常如何处理错误,进一步的通知级别(包括日志记录、控制台消息和GUI弹出窗口)可能是合适的。

9.5.1. Revocation Recovery for Write Open Delegation
9.5.1. 写开放委派的吊销恢复

Revocation recovery for a write open delegation poses the special issue of modified data in the client cache while the file is not open. In this situation, any client which does not flush modified data to the server on each close must ensure that the user receives appropriate notification of the failure as a result of the revocation. Since such situations may require human action to correct problems, notification schemes in which the appropriate user or administrator is notified may be necessary. Logging and console messages are typical examples.

写开放委派的吊销恢复会在文件未打开时引起客户端缓存中修改数据的特殊问题。在这种情况下,每次关闭时未将修改后的数据刷新到服务器的任何客户端都必须确保用户收到由于撤销而导致的故障的适当通知。由于此类情况可能需要人为措施来纠正问题,因此可能需要通知相应用户或管理员的通知方案。日志和控制台消息是典型的例子。

If there is modified data on the client, it must not be flushed normally to the server. A client may attempt to provide a copy of the file data as modified during the delegation under a different name in the file system name space to ease recovery. Unless the client can determine that the file has not modified by any other client, this technique must be limited to situations in which a client has a complete cached copy of the file in question. Use of such a technique may be limited to files under a certain size or may only be used when sufficient disk space is guaranteed to be available within the target file system and when the client has sufficient buffering resources to keep the cached copy available until it is properly stored to the target file system.

如果客户端上有修改过的数据,则不能将其正常刷新到服务器。客户端可能会尝试在文件系统名称空间中以不同的名称提供在委派过程中修改的文件数据副本,以便于恢复。除非客户机可以确定该文件没有被任何其他客户机修改,否则此技术必须限于客户机具有所讨论文件的完整缓存副本的情况。这种技术的使用可能仅限于特定大小的文件,或者仅当保证目标文件系统中有足够的磁盘空间可用时,以及当客户端有足够的缓冲资源来保持缓存副本可用时,才可使用这种技术,直到将其正确存储到目标文件系统为止。

9.6. Attribute Caching
9.6. 属性缓存

The attributes discussed in this section do not include named attributes. Individual named attributes are analogous to files and caching of the data for these needs to be handled just as data caching is for ordinary files. Similarly, LOOKUP results from an OPENATTR directory are to be cached on the same basis as any other pathnames and similarly for directory contents.

本节中讨论的属性不包括命名属性。单个命名属性类似于文件,这些属性的数据缓存需要处理,就像普通文件的数据缓存一样。类似地,来自OPENATTR目录的查找结果将与任何其他路径名一样进行缓存,对于目录内容也是如此。

Clients may cache file attributes obtained from the server and use them to avoid subsequent GETATTR requests. Such caching is write through in that modification to file attributes is always done by means of requests to the server and should not be done locally and cached. The exception to this are modifications to attributes that are intimately connected with data caching. Therefore, extending a file by writing data to the local data cache is reflected immediately in the object_size as seen on the client without this change being immediately reflected on the server. Normally such changes are not propagated directly to the server but when the modified data is flushed to the server, analogous attribute changes are made on the server. When open delegation is in effect, the modified attributes may be returned to the server in the response to a CB_RECALL call.

客户端可以缓存从服务器获得的文件属性,并使用它们来避免后续的GETATTR请求。这种缓存是直写的,因为对文件属性的修改总是通过对服务器的请求来完成的,不应该在本地完成并缓存。例外情况是修改与数据缓存密切相关的属性。因此,通过将数据写入本地数据缓存来扩展文件会立即反映在客户机上看到的对象大小中,而不会立即反映在服务器上。通常,此类更改不会直接传播到服务器,但当修改的数据刷新到服务器时,会在服务器上进行类似的属性更改。当开放委派生效时,修改的属性可能会在响应CB_调用时返回给服务器。

The result of local caching of attributes is that the attribute caches maintained on individual clients will not be coherent. Changes made in one order on the server may be seen in a different order on one client and in a third order on a different client.

属性的本地缓存的结果是,在单个客户端上维护的属性缓存将不一致。在服务器上按一个顺序所做的更改可能在一个客户端上以不同的顺序显示,在另一个客户端上以第三个顺序显示。

The typical file system application programming interfaces do not provide means to atomically modify or interrogate attributes for multiple files at the same time. The following rules provide an environment where the potential incoherences mentioned above can be reasonably managed. These rules are derived from the practice of previous NFS protocols.

典型的文件系统应用程序编程接口不提供同时原子地修改或查询多个文件属性的方法。以下规则提供了一个可以合理管理上述潜在不一致性的环境。这些规则源自以前NFS协议的实践。

o All attributes for a given file (per-fsid attributes excepted) are cached as a unit at the client so that no non-serializability can arise within the context of a single file.

o 给定文件的所有属性(每个fsid属性除外)都作为一个单元缓存在客户机上,因此在单个文件的上下文中不会出现非序列化。

o An upper time boundary is maintained on how long a client cache entry can be kept without being refreshed from the server.

o 对于客户端缓存项在不从服务器刷新的情况下可以保留多长时间,将保留一个时间上限。

o When operations are performed that change attributes at the server, the updated attribute set is requested as part of the containing RPC. This includes directory operations that update attributes indirectly. This is accomplished by following the modifying operation with a GETATTR operation and then using the results of the GETATTR to update the client's cached attributes.

o 在服务器上执行更改属性的操作时,更新的属性集将作为包含RPC的一部分被请求。这包括间接更新属性的目录操作。这是通过使用GETATTR操作执行修改操作,然后使用GETATTR的结果更新客户端的缓存属性来实现的。

Note that if the full set of attributes to be cached is requested by READDIR, the results can be cached by the client on the same basis as attributes obtained via GETATTR.

请注意,如果READDIR请求要缓存的完整属性集,则客户机可以按照与通过GETATTR获得的属性相同的基础来缓存结果。

A client may validate its cached version of attributes for a file by fetching only the change attribute and assuming that if the change attribute has the same value as it did when the attributes were cached, then no attributes have changed. The possible exception is the attribute time_access.

客户端可以通过仅获取更改属性并假设如果更改属性具有与缓存属性时相同的值,则属性没有更改,从而验证文件属性的缓存版本。可能的例外是属性time\u access。

9.7. Name Caching
9.7. 名称高速缓存

The results of LOOKUP and READDIR operations may be cached to avoid the cost of subsequent LOOKUP operations. Just as in the case of attribute caching, inconsistencies may arise among the various client caches. To mitigate the effects of these inconsistencies and given the context of typical file system APIs, the following rules should be followed:

查找和READDIR操作的结果可以缓存,以避免后续查找操作的开销。与属性缓存一样,不同的客户端缓存之间可能会出现不一致。为了减轻这些不一致的影响,并考虑到典型文件系统API的上下文,应遵循以下规则:

o The results of unsuccessful LOOKUPs should not be cached, unless they are specifically reverified at the point of use.

o 不应缓存不成功查找的结果,除非在使用点对其进行了专门的重新验证。

o An upper time boundary is maintained on how long a client name cache entry can be kept without verifying that the entry has not been made invalid by a directory change operation performed by another client.

o 在不验证另一个客户端执行的目录更改操作是否使客户端名称缓存项无效的情况下,保留客户端名称缓存项的时间上限。

When a client is not making changes to a directory for which there exist name cache entries, the client needs to periodically fetch attributes for that directory to ensure that it is not being modified. After determining that no modification has occurred, the expiration time for the associated name cache entries may be updated to be the current time plus the name cache staleness bound.

当客户端不更改存在名称缓存项的目录时,客户端需要定期获取该目录的属性,以确保该目录未被修改。在确定未发生任何修改后,关联名称缓存项的过期时间可能会更新为当前时间加上名称缓存过时界限。

When a client is making changes to a given directory, it needs to determine whether there have been changes made to the directory by other clients. It does this by using the change attribute as reported before and after the directory operation in the associated change_info4 value returned for the operation. The server is able to communicate to the client whether the change_info4 data is provided atomically with respect to the directory operation. If the change values are provided atomically, the client is then able to compare the pre-operation change value with the change value in the client's name cache. If the comparison indicates that the directory was updated by another client, the name cache associated with the modified directory is purged from the client. If the comparison indicates no modification, the name cache can be updated on the client to reflect the directory operation and the associated timeout extended. The post-operation change value needs to be saved as the basis for future change_info4 comparisons.

当客户端对给定目录进行更改时,它需要确定是否有其他客户端对该目录进行了更改。它通过使用为操作返回的关联change_info4值中目录操作前后报告的change属性来完成此操作。服务器能够与客户机通信,以确定是否以原子方式提供了与目录操作相关的更改信息4数据。如果以原子方式提供更改值,则客户端可以将操作前更改值与客户端名称缓存中的更改值进行比较。如果比较表明目录已由另一个客户端更新,则与修改后的目录关联的名称缓存将从客户端中清除。如果比较表明没有修改,则可以在客户端上更新名称缓存,以反映目录操作和相关的超时扩展。需要保存操作后更改值,作为将来更改比较的基础。

As demonstrated by the scenario above, name caching requires that the client revalidate name cache data by inspecting the change attribute of a directory at the point when the name cache item was cached. This requires that the server update the change attribute for directories when the contents of the corresponding directory is modified. For a client to use the change_info4 information appropriately and correctly, the server must report the pre and post operation change attribute values atomically. When the server is unable to report the before and after values atomically with respect to the directory operation, the server must indicate that fact in the change_info4 return value. When the information is not atomically reported, the client should not assume that other clients have not changed the directory.

如上面的场景所示,名称缓存要求客户端通过在缓存名称缓存项时检查目录的change属性来重新验证名称缓存数据。这要求服务器在修改相应目录的内容时更新目录的change属性。为了让客户端正确地使用change_info4信息,服务器必须以原子方式报告操作前和操作后的change属性值。当服务器无法原子地报告与目录操作相关的before和after值时,服务器必须在change_info4返回值中指出这一事实。当信息未按原子方式报告时,客户端不应假定其他客户端未更改目录。

9.8. Directory Caching
9.8. 目录缓存

The results of READDIR operations may be used to avoid subsequent READDIR operations. Just as in the cases of attribute and name caching, inconsistencies may arise among the various client caches.

READDIR操作的结果可用于避免后续的READDIR操作。与属性和名称缓存的情况一样,不同的客户端缓存之间可能会出现不一致。

To mitigate the effects of these inconsistencies, and given the context of typical file system APIs, the following rules should be followed:

为了减轻这些不一致的影响,并考虑到典型文件系统API的上下文,应遵循以下规则:

o Cached READDIR information for a directory which is not obtained in a single READDIR operation must always be a consistent snapshot of directory contents. This is determined by using a GETATTR before the first READDIR and after the last of READDIR that contributes to the cache.

o 未在单个READDIR操作中获得的目录的缓存READDIR信息必须始终是目录内容的一致快照。这是通过在第一个READDIR之前和最后一个参与缓存的READDIR之后使用GETATTR来确定的。

o An upper time boundary is maintained to indicate the length of time a directory cache entry is considered valid before the client must revalidate the cached information.

o 维护时间上限,以指示在客户端必须重新验证缓存信息之前,目录缓存项被视为有效的时间长度。

The revalidation technique parallels that discussed in the case of name caching. When the client is not changing the directory in question, checking the change attribute of the directory with GETATTR is adequate. The lifetime of the cache entry can be extended at these checkpoints. When a client is modifying the directory, the client needs to use the change_info4 data to determine whether there are other clients modifying the directory. If it is determined that no other client modifications are occurring, the client may update its directory cache to reflect its own changes.

重新验证技术与在名称缓存中讨论的技术类似。当客户机没有更改有问题的目录时,用GETATTR检查目录的change属性就足够了。可以在这些检查点延长缓存项的生存期。当客户端修改目录时,客户端需要使用change_info4数据来确定是否有其他客户端修改目录。如果确定没有发生其他客户端修改,则客户端可以更新其目录缓存以反映其自身的更改。

As demonstrated previously, directory caching requires that the client revalidate directory cache data by inspecting the change attribute of a directory at the point when the directory was cached. This requires that the server update the change attribute for directories when the contents of the corresponding directory is modified. For a client to use the change_info4 information appropriately and correctly, the server must report the pre and post operation change attribute values atomically. When the server is unable to report the before and after values atomically with respect to the directory operation, the server must indicate that fact in the change_info4 return value. When the information is not atomically reported, the client should not assume that other clients have not changed the directory.

如前所述,目录缓存要求客户端通过在缓存目录时检查目录的change属性来重新验证目录缓存数据。这要求服务器在修改相应目录的内容时更新目录的change属性。为了让客户端正确地使用change_info4信息,服务器必须以原子方式报告操作前和操作后的change属性值。当服务器无法原子地报告与目录操作相关的before和after值时,服务器必须在change_info4返回值中指出这一事实。当信息未按原子方式报告时,客户端不应假定其他客户端未更改目录。

10. Minor Versioning
10. 次要版本控制

To address the requirement of an NFS protocol that can evolve as the need arises, the NFS version 4 protocol contains the rules and framework to allow for future minor changes or versioning.

为了满足NFS协议的需求,NFS版本4协议包含规则和框架,以允许将来进行微小更改或版本控制。

The base assumption with respect to minor versioning is that any future accepted minor version must follow the IETF process and be documented in a standards track RFC. Therefore, each minor version number will correspond to an RFC. Minor version zero of the NFS

关于次要版本控制的基本假设是,任何未来接受的次要版本必须遵循IETF流程,并记录在标准跟踪RFC中。因此,每个次要版本号将对应一个RFC。NFS的次要版本零

version 4 protocol is represented by this RFC. The COMPOUND procedure will support the encoding of the minor version being requested by the client.

版本4协议由该RFC表示。复合过程将支持对客户端请求的次要版本进行编码。

The following items represent the basic rules for the development of minor versions. Note that a future minor version may decide to modify or add to the following rules as part of the minor version definition.

以下各项代表了开发次要版本的基本规则。请注意,将来的次要版本可能会决定修改或添加以下规则,作为次要版本定义的一部分。

1 Procedures are not added or deleted

1不添加或删除程序

To maintain the general RPC model, NFS version 4 minor versions will not add or delete procedures from the NFS program.

为了维护通用RPC模型,NFS版本4次要版本不会从NFS程序中添加或删除过程。

2 Minor versions may add operations to the COMPOUND and CB_COMPOUND procedures.

2次要版本可能会将操作添加到复合和CB_复合程序中。

The addition of operations to the COMPOUND and CB_COMPOUND procedures does not affect the RPC model.

向复合过程和CB_复合过程添加操作不会影响RPC模型。

2.1 Minor versions may append attributes to GETATTR4args, bitmap4, and GETATTR4res.

2.1 次要版本可能会将属性附加到GETATTR4args、bitmap4和GETATTR4res。

This allows for the expansion of the attribute model to allow for future growth or adaptation.

这允许扩展属性模型,以允许将来的增长或适应。

2.2 Minor version X must append any new attributes after the last documented attribute.

2.2 次要版本X必须在最后记录的属性之后附加任何新属性。

Since attribute results are specified as an opaque array of per-attribute XDR encoded results, the complexity of adding new attributes in the midst of the current definitions will be too burdensome.

由于属性结果被指定为每个属性XDR编码结果的不透明数组,因此在当前定义中添加新属性的复杂性将过于繁重。

3 Minor versions must not modify the structure of an existing operation's arguments or results.

3次要版本不得修改现有操作的参数或结果的结构。

Again the complexity of handling multiple structure definitions for a single operation is too burdensome. New operations should be added instead of modifying existing structures for a minor version.

同样,为一个操作处理多个结构定义的复杂性也过于繁重。应添加新操作,而不是修改次要版本的现有结构。

This rule does not preclude the following adaptations in a minor version.

本规则不排除次要版本中的以下改编。

o adding bits to flag fields such as new attributes to GETATTR's bitmap4 data type

o 将位添加到标记字段,例如GETATTR的bitmap4数据类型的新属性

o adding bits to existing attributes like ACLs that have flag words

o 向现有属性(如具有标志词的ACL)添加位

o extending enumerated types (including NFS4ERR_*) with new values

o 使用新值扩展枚举类型(包括NFS4ERR_*)

4 Minor versions may not modify the structure of existing attributes.

4次要版本不得修改现有属性的结构。

5 Minor versions may not delete operations.

5次要版本不能删除操作。

This prevents the potential reuse of a particular operation "slot" in a future minor version.

这防止了在将来的次要版本中可能重用特定操作“插槽”。

6 Minor versions may not delete attributes.

6次要版本不能删除属性。

7 Minor versions may not delete flag bits or enumeration values.

7次要版本不得删除标志位或枚举值。

8 Minor versions may declare an operation as mandatory to NOT implement.

8次要版本可能会将操作声明为不实施的强制操作。

Specifying an operation as "mandatory to not implement" is equivalent to obsoleting an operation. For the client, it means that the operation should not be sent to the server. For the server, an NFS error can be returned as opposed to "dropping" the request as an XDR decode error. This approach allows for the obsolescence of an operation while maintaining its structure so that a future minor version can reintroduce the operation.

将操作指定为“强制不执行”等同于淘汰操作。对于客户端,这意味着不应将操作发送到服务器。对于服务器,可以返回NFS错误,而不是作为XDR解码错误“删除”请求。这种方法允许在保持其结构的同时淘汰操作,以便将来的次要版本可以重新引入操作。

8.1 Minor versions may declare attributes mandatory to NOT implement.

8.1 次要版本可能会声明不实现的强制属性。

8.2 Minor versions may declare flag bits or enumeration values as mandatory to NOT implement.

8.2 次要版本可能会将标志位或枚举值声明为不实现的强制值。

9 Minor versions may downgrade features from mandatory to recommended, or recommended to optional.

9次要版本可能会将功能从强制降级为推荐,或从推荐降级为可选。

10 Minor versions may upgrade features from optional to recommended or recommended to mandatory.

10个次要版本可以将功能从可选升级到推荐,或从推荐升级到强制。

11 A client and server that support minor version X must support minor versions 0 (zero) through X-1 as well.

11支持次要版本X的客户端和服务器也必须支持次要版本0(零)到X-1。

12 No new features may be introduced as mandatory in a minor version.

12次要版本中不得强制引入新功能。

This rule allows for the introduction of new functionality and forces the use of implementation experience before designating a feature as mandatory.

此规则允许引入新功能,并强制在指定功能为强制性之前使用实现经验。

13 A client MUST NOT attempt to use a stateid, file handle, or similar returned object from the COMPOUND procedure with minor version X for another COMPOUND procedure with minor version Y, where X != Y.

13客户端不得尝试将次要版本为X的复合过程中的stateid、文件句柄或类似返回对象用于次要版本为Y的另一个复合过程,其中X!=Y

11. Internationalization
11. 国际化

The primary issue in which NFS needs to deal with internationalization, or I18n, is with respect to file names and other strings as used within the protocol. The choice of string representation must allow reasonable name/string access to clients which use various languages. The UTF-8 encoding of the UCS as defined by [ISO10646] allows for this type of access and follows the policy described in "IETF Policy on Character Sets and Languages", [RFC2277]. This choice is explained further in the following.

NFS需要处理国际化或I18n的主要问题是协议中使用的文件名和其他字符串。字符串表示的选择必须允许对使用各种语言的客户端进行合理的名称/字符串访问。[ISO10646]定义的UCS UTF-8编码允许这种类型的访问,并遵循“关于字符集和语言的IETF政策”[RFC2277]中描述的政策。下面将进一步解释此选择。

11.1. Universal Versus Local Character Sets
11.1. 通用与局部字符集

[RFC1345] describes a table of 16 bit characters for many different languages (the bit encodings match Unicode, though of course RFC1345 is somewhat out of date with respect to current Unicode assignments). Each character from each language has a unique 16 bit value in the 16 bit character set. Thus this table can be thought of as a universal character set. [RFC1345] then talks about groupings of subsets of the entire 16 bit character set into "Charset Tables". For example one might take all the Greek characters from the 16 bit table (which are consecutively allocated), and normalize their offsets to a table that fits in 7 bits. Thus it is determined that "lower case alpha" is in the same position as "upper case a" in the US-ASCII table, and "upper case alpha" is in the same position as "lower case a" in the US-ASCII table.

[RFC1345]描述了许多不同语言的16位字符表(位编码与Unicode匹配,当然RFC1345相对于当前的Unicode分配有些过时)。每种语言的每个字符在16位字符集中都有一个唯一的16位值。因此,可以将此表视为通用字符集。[RFC1345]然后讨论将整个16位字符集的子集分组为“字符集表”。例如,可以从16位表(连续分配)中提取所有希腊字符,并将其偏移量标准化为适合7位的表。因此,确定“小写字母”与US-ASCII表格中的“大写字母a”处于相同位置,“大写字母”与US-ASCII表格中的“小写字母a”处于相同位置。

These normalized subset character sets can be thought of as "local character sets", suitable for an operating system locale.

这些规范化的子集字符集可以被认为是“本地字符集”,适用于操作系统区域设置。

Local character sets are not suitable for the NFS protocol. Consider someone who creates a file with a name in a Swedish character set. If someone else later goes to access the file with their locale set to the Swedish language, then there are no problems. But if someone in say the US-ASCII locale goes to access the file, the file name will look very different, because the Swedish characters in the 7 bit table will now be represented in US-ASCII characters on the display. It would be preferable to give the US-ASCII user a way to display the

本地字符集不适用于NFS协议。考虑在瑞典字符集中创建具有名称的文件的人。如果其他人后来访问该文件时将其语言环境设置为瑞典语,则没有问题。但是如果有人(比如说US-ASCII语言环境中的人)访问该文件,文件名将看起来非常不同,因为7位表中的瑞典字符现在将在显示器上以US-ASCII字符表示。最好为US-ASCII用户提供一种显示

file name using Swedish glyphs. In order to do that, the NFS protocol would have to include the locale with the file name on each operation to create a file.

使用瑞典字形的文件名。为了做到这一点,NFS协议必须在创建文件的每个操作中包含带有文件名的区域设置。

But then what of the situation when there is a path name on the server like:

但是,当服务器上有一个路径名时会发生什么情况,如:

         /component-1/component-2/component-3
        
         /component-1/component-2/component-3
        

Each component could have been created with a different locale. If one issues CREATE with multi-component path name, and if some of the leading components already exist, what is to be done with the existing components? Is the current locale attribute replaced with the user's current one? These types of situations quickly become too complex when there is an alternate solution.

每个组件都可以使用不同的语言环境创建。如果使用多组件路径名创建问题,并且如果一些主要组件已经存在,那么如何处理现有组件?当前语言环境属性是否替换为用户的当前语言环境属性?当有替代解决方案时,这些类型的情况很快变得过于复杂。

If the NFS version 4 protocol used a universal 16 bit or 32 bit character set (or an encoding of a 16 bit or 32 bit character set into octets), then the server and client need not care if the locale of the user accessing the file is different than the locale of the user who created the file. The unique 16 bit or 32 bit encoding of the character allows for determination of what language the character is from and also how to display that character on the client. The server need not know what locales are used.

如果NFS版本4协议使用通用16位或32位字符集(或将16位或32位字符集编码为八位字节),则服务器和客户端无需关心访问文件的用户的语言环境是否与创建文件的用户的语言环境不同。字符的唯一16位或32位编码允许确定字符来自何种语言,以及如何在客户端显示该字符。服务器不需要知道所使用的区域设置。

11.2. Overview of Universal Character Set Standards
11.2. 通用字符集标准概述

The previous section makes a case for using a universal character set. This section makes the case for using UTF-8 as the specific universal character set for the NFS version 4 protocol.

上一节介绍了使用通用字符集的情况。本节说明如何使用UTF-8作为NFS版本4协议的特定通用字符集。

[RFC2279] discusses UTF-* (UTF-8 and other UTF-XXX encodings), Unicode, and UCS-*. There are two standards bodies managing universal code sets:

[RFC2279]讨论了UTF-*(UTF-8和其他UTF-XXX编码)、Unicode和UCS-*。有两个标准机构管理通用代码集:

o ISO/IEC which has the standard 10646-1

o ISO/IEC,其标准为10646-1

o Unicode which has the Unicode standard

o Unicode具有Unicode标准

Both standards bodies have pledged to track each other's assignments of character codes.

这两个标准机构都承诺相互跟踪字符代码的分配。

The following is a brief analysis of the various standards.

以下是对各种标准的简要分析。

UCS Universal Character Set. This is ISO/IEC 10646-1: "a multi-octet character set called the Universal Character Set (UCS), which encompasses most of the world's writing systems."

UCS通用字符集。这就是ISO/IEC 10646-1:“一种称为通用字符集(UCS)的多八位字符集,它包含了世界上大多数的书写系统。”

UCS-2 a two octet per character encoding that addresses the first 2^16 characters of UCS. Currently there are no UCS characters beyond that range.

UCS-2一种每字符两个八位字节的编码,用于处理UCS的前2^16个字符。当前没有超出该范围的UCS字符。

UCS-4 a four octet per character encoding that permits the encoding of up to 2^31 characters.

UCS-4一种每字符四个八位字节的编码,允许最多编码2^31个字符。

UTF UTF is an abbreviation of the term "UCS transformation format" and is used in the naming of various standards for encoding of UCS characters as described below.

UTF UTF是术语“UCS转换格式”的缩写,用于命名UCS字符编码的各种标准,如下所述。

UTF-1 Only historical interest; it has been removed from 10646-1

UTF-1仅具有历史价值;它已从10646-1中删除

UTF-7 Encodes the entire "repertoire" of UCS "characters using only octets with the higher order bit clear". [RFC2152] describes UTF-7. UTF-7 accomplishes this by reserving one of the 7bit US-ASCII characters as a "shift" character to indicate non-US-ASCII characters.

UTF-7编码UCS的整个“指令集”字符“仅使用具有较高阶位清除率的八位字节”。[RFC2152]描述了UTF-7。UTF-7通过将7bit US-ASCII字符中的一个保留为“移位”字符以指示非US ASCII字符来实现这一点。

UTF-8 Unlike UTF-7, uses all 8 bits of the octets. US-ASCII characters are encoded as before unchanged. Any octet with the high bit cleared can only mean a US-ASCII character. The high bit set means that a UCS character is being encoded.

与UTF-7不同,UTF-8使用八位字节的所有8位。US-ASCII字符的编码与以前相同。任何高位清除的八位字节只能表示US-ASCII字符。高位集表示正在对UCS字符进行编码。

UTF-16 Encodes UCS-4 characters into UCS-2 characters using a reserved range in UCS-2.

UTF-16使用UCS-2中的保留范围将UCS-4字符编码为UCS-2字符。

Unicode Unicode and UCS-2 are the same; [RFC2279] states:

Unicode和UCS-2是相同的;[RFC2279]声明:

Up to the present time, changes in Unicode and amendments to ISO/IEC 10646 have tracked each other, so that the character repertoires and code point assignments have remained in sync. The relevant standardization committees have committed to maintain this very useful synchronism.

到目前为止,Unicode的变化和ISO/IEC10646的修订相互跟踪,因此字符表和代码点分配保持同步。相关标准化委员会已承诺保持这种非常有用的同步性。

11.3. Difficulties with UCS-4, UCS-2, Unicode
11.3. UCS-4、UCS-2和Unicode的困难

Adapting existing applications, and file systems to multi-octet schemes like UCS and Unicode can be difficult. A significant amount of code has been written to process streams of bytes. Also there are many existing stored objects described with 7 bit or 8 bit characters. Doubling or quadrupling the bandwidth and storage requirements seems like an expensive way to accomplish I18N.

使现有的应用程序和文件系统适应诸如UCS和Unicode等多八位字节方案可能很困难。为处理字节流,已经编写了大量代码。还有许多现有的存储对象是用7位或8位字符描述的。将带宽和存储需求翻一番或翻两番似乎是实现I18N的一种昂贵方式。

UCS-2 and Unicode are "only" 16 bits long. That might seem to be enough but, according to [Unicode1], 49,194 Unicode characters are already assigned. According to [Unicode2] there are still more languages that need to be added.

UCS-2和Unicode“仅”16位长。这似乎足够了,但根据[Unicode1],已经分配了49194个Unicode字符。根据[Unicode2],还有更多的语言需要添加。

11.4. UTF-8 and its solutions
11.4. UTF-8及其解决方案

UTF-8 solves problems for NFS that exist with the use of UCS and Unicode. UTF-8 will encode 16 bit and 32 bit characters in a way that will be compact for most users. The encoding table from UCS-4 to UTF-8, as copied from [RFC2279]:

UTF-8解决了由于使用UCS和Unicode而存在的NFS问题。UTF-8编码16位和32位字符的方式对大多数用户来说是紧凑的。从[RFC2279]复制的UCS-4到UTF-8的编码表:

UCS-4 range (hex.) UTF-8 octet sequence (binary) 0000 0000-0000 007F 0xxxxxxx 0000 0080-0000 07FF 110xxxxx 10xxxxxx 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 0400 0000-7FFF FFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UCS-4范围(十六进制)UTF-8八位组序列(二进制)0000-0000 007F 0xxxxxxx 0000 0080-0000 07FF 110xxxxx 10xxxxxx 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 0020-03FF FFFF 11111 0xx 10xxxxxx 10xxxxxx 0400-7FFFF 1110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

See [RFC2279] for precise encoding and decoding rules. Note because of UTF-16, the algorithm from Unicode/UCS-2 to UTF-8 needs to account for the reserved range between D800 and DFFF.

有关精确的编码和解码规则,请参见[RFC2279]。注意:由于UTF-16,从Unicode/UCS-2到UTF-8的算法需要考虑D800和DFFF之间的保留范围。

Note that the 16 bit UCS or Unicode characters require no more than 3 octets to encode into UTF-8

请注意,16位UCS或Unicode字符需要不超过3个八位字节才能编码为UTF-8

Interestingly, UTF-8 has room to handle characters larger than 31 bits, because the leading octet of form:

有趣的是,UTF-8有空间处理大于31位的字符,因为前导八位字节的形式是:

1111111x

1111111 x

is not defined. If needed, ISO could either use that octet to indicate a sequence of an encoded 8 octet character, or perhaps use 11111110 to permit the next octet to indicate an even more expandable character set.

没有定义。如果需要,ISO可以使用该八位字节来指示编码的8个八位字节字符的序列,或者使用11111110来允许下一个八位字节指示更可扩展的字符集。

So using UTF-8 to represent character encodings means never having to run out of room.

因此,使用UTF-8来表示字符编码意味着永远不必耗尽空间。

11.5. Normalization
11.5. 规范化

The client and server operating environments may differ in their policies and operational methods with respect to character normalization (See [Unicode1] for a discussion of normalization forms). This difference may also exist between applications on the same client. This adds to the difficulty of providing a single

客户机和服务器操作环境在字符规范化方面的策略和操作方法可能有所不同(有关规范化形式的讨论,请参见[Unicode1])。同一客户端上的应用程序之间也可能存在这种差异。这增加了提供单个

normalization policy for the protocol that allows for maximal interoperability. This issue is similar to the character case issues where the server may or may not support case insensitive file name matching and may or may not preserve the character case when storing file names. The protocol does not mandate a particular behavior but allows for the various permutations.

允许最大互操作性的协议规范化策略。此问题类似于字符大小写问题,服务器可能支持或不支持不区分大小写的文件名匹配,并且在存储文件名时可能保留或不保留字符大小写。该协议不要求特定的行为,但允许各种排列。

The NFS version 4 protocol does not mandate the use of a particular normalization form at this time. A later revision of this specification may specify a particular normalization form. Therefore, the server and client can expect that they may receive unnormalized characters within protocol requests and responses. If the operating environment requires normalization, then the implementation must normalize the various UTF-8 encoded strings within the protocol before presenting the information to an application (at the client) or local file system (at the server).

NFS版本4协议目前不强制使用特定的规范化表单。本规范的后续版本可能会指定特定的规范化形式。因此,服务器和客户机可能会在协议请求和响应中接收到非规范化字符。如果操作环境需要规范化,那么在将信息呈现给应用程序(在客户端)或本地文件系统(在服务器)之前,实现必须规范化协议中的各种UTF-8编码字符串。

12. Error Definitions
12. 错误定义

NFS error numbers are assigned to failed operations within a compound request. A compound request contains a number of NFS operations that have their results encoded in sequence in a compound reply. The results of successful operations will consist of an NFS4_OK status followed by the encoded results of the operation. If an NFS operation fails, an error status will be entered in the reply and the compound request will be terminated.

NFS错误号分配给复合请求中失败的操作。复合请求包含许多NFS操作,这些操作的结果在复合应答中按顺序编码。成功操作的结果将包括NFS4_OK状态,然后是编码的操作结果。如果NFS操作失败,将在回复中输入错误状态,复合请求将终止。

A description of each defined error follows:

每个已定义错误的描述如下:

NFS4_OK Indicates the operation completed successfully.

NFS4_OK表示操作已成功完成。

NFS4ERR_ACCES Permission denied. The caller does not have the correct permission to perform the requested operation. Contrast this with NFS4ERR_PERM, which restricts itself to owner or privileged user permission failures.

NFS4ERR_访问权限被拒绝。调用方没有执行请求的操作的正确权限。这与NFS4ERR_PERM形成对比,后者将自身限制为所有者或特权用户权限失败。

NFS4ERR_BADHANDLE Illegal NFS file handle. The file handle failed internal consistency checks.

NFS4ERR_baddhandle非法的NFS文件句柄。文件句柄未通过内部一致性检查。

NFS4ERR_BADTYPE An attempt was made to create an object of a type not supported by the server.

NFS4ERR_BADTYPE试图创建服务器不支持的类型的对象。

NFS4ERR_BAD_COOKIE READDIR cookie is stale.

NFS4ERR_BAD_COOKIE READDIR COOKIE已过期。

NFS4ERR_BAD_SEQID The sequence number in a locking request is neither the next expected number or the last number processed.

NFS4ERR_BAD_SEQID锁定请求中的序列号既不是下一个预期的数字,也不是最后处理的数字。

NFS4ERR_BAD_STATEID A stateid generated by the current server instance, but which does not designate any locking state (either current or superseded) for a current lockowner-file pair, was used.

NFS4ERR_BAD_STATEID使用了当前服务器实例生成的STATEID,但未为当前lockowner文件对指定任何锁定状态(当前或已取代)。

NFS4ERR_CLID_INUSE The SETCLIENTID procedure has found that a client id is already in use by another client.

NFS4ERR_CLID_使用SETCLIENTID过程发现另一个客户端已经在使用客户端id。

NFS4ERR_DELAY The server initiated the request, but was not able to complete it in a timely fashion. The client should wait and then try the request with a new RPC transaction ID. For example, this error should be returned from a server that supports hierarchical storage and receives a request to process a file that has been migrated. In this case, the server should start the immigration process and respond to client with this error. This error may also occur when a necessary delegation recall makes processing a request in a timely fashion impossible.

NFS4ERR_延迟服务器启动请求,但无法及时完成请求。客户端应等待,然后使用新的RPC事务ID尝试该请求。例如,此错误应从支持分层存储并接收处理已迁移文件的请求的服务器返回。在这种情况下,服务器应该启动迁移过程,并用此错误响应客户端。当必要的委托召回导致无法及时处理请求时,也可能发生此错误。

NFS4ERR_DENIED An attempt to lock a file is denied. Since this may be a temporary condition, the client is encouraged to retry the lock request until the lock is accepted.

NFS4ERR_拒绝锁定文件的尝试被拒绝。由于这可能是一种临时情况,因此鼓励客户端重试锁定请求,直到锁定被接受。

NFS4ERR_DQUOT Resource (quota) hard limit exceeded. The user's resource limit on the server has been exceeded.

超出了NFS4ERR_DQUOT资源(配额)硬限制。已超过服务器上用户的资源限制。

NFS4ERR_EXIST File exists. The file specified already exists.

NFS4ERR_存在文件。指定的文件已存在。

NFS4ERR_EXPIRED A lease has expired that is being used in the current procedure.

NFS4ERR_过期当前过程中使用的租约已过期。

NFS4ERR_FBIG File too large. The operation would have caused a file to grow beyond the server's limit.

NFS4ERR_FBIG文件太大。该操作会导致文件增长超过服务器的限制。

NFS4ERR_FHEXPIRED The file handle provided is volatile and has expired at the server.

NFS4ERR_fhu提供的文件句柄不稳定,已在服务器上过期。

NFS4ERR_GRACE The server is in its recovery or grace period which should match the lease period of the server.

NFS4ERR_宽限期服务器处于恢复期或宽限期,该宽限期应与服务器的租赁期相匹配。

NFS4ERR_INVAL Invalid argument or unsupported argument for an operation. Two examples are attempting a READLINK on an object other than a symbolic link or attempting to SETATTR a time field on a server that does not support this operation.

NFS4ERR_INVAL操作的参数无效或不支持的参数。两个示例是尝试在非符号链接的对象上进行READLINK,或尝试在不支持此操作的服务器上设置ATTR时间字段。

NFS4ERR_IO I/O error. A hard error (for example, a disk error) occurred while processing the requested operation.

NFS4ERR_IO I/O错误。处理请求的操作时发生硬错误(例如,磁盘错误)。

NFS4ERR_ISDIR Is a directory. The caller specified a directory in a non-directory operation.

NFS4ERR_ISDIR是一个目录。调用方在非目录操作中指定了目录。

NFS4ERR_LEASE_MOVED A lease being renewed is associated with a file system that has been migrated to a new server.

NFS4ERR_LEASE_已移动正在续订的租约与已迁移到新服务器的文件系统相关联。

NFS4ERR_LOCKED A read or write operation was attempted on a locked file.

NFS4ERR_已锁定试图对锁定的文件执行读取或写入操作。

NFS4ERR_LOCK_RANGE A lock request is operating on a sub-range of a current lock for the lock owner and the server does not support this type of request.

NFS4ERR_LOCK_RANGE锁请求正在锁所有者的当前锁的子范围上运行,服务器不支持此类请求。

NFS4ERR_MINOR_VERS_MISMATCH The server has received a request that specifies an unsupported minor version. The server must return a COMPOUND4res with a zero length operations result array.

NFS4ERR_MINOR_VERS_不匹配服务器收到一个指定不受支持的MINOR版本的请求。服务器必须返回具有零长度操作结果数组的COMPOUND4res。

NFS4ERR_MLINK Too many hard links.

NFS4ERR_m链接太多硬链接。

NFS4ERR_MOVED The filesystem which contains the current filehandle object has been relocated or migrated to another server. The client may obtain the new filesystem location by obtaining the "fs_locations" attribute for the current filehandle. For further discussion, refer to the section "Filesystem Migration or Relocation".

NFS4ERR_移动了包含当前filehandle对象的文件系统,该文件系统已重新定位或迁移到另一台服务器。客户端可以通过获取当前文件句柄的“fs_locations”属性来获取新的文件系统位置。有关进一步的讨论,请参阅“文件系统迁移或重新定位”一节。

NFS4ERR_NAMETOOLONG The filename in an operation was too long.

NFS4ERR_NAMETOOLONG操作中的文件名太长。

NFS4ERR_NODEV No such device.

NFS4ERR_NODEV没有这样的设备。

NFS4ERR_NOENT No such file or directory. The file or directory name specified does not exist.

NFS4ERR\n没有这样的文件或目录。指定的文件或目录名不存在。

NFS4ERR_NOFILEHANDLE The logical current file handle value has not been set properly. This may be a result of a malformed COMPOUND operation (i.e. no PUTFH or PUTROOTFH before an operation that requires the current file handle be set).

NFS4ERR_NOFILEHANDLE未正确设置逻辑当前文件句柄值。这可能是由于复合操作的格式错误(即,在需要设置当前文件句柄的操作之前没有PUTFH或PUTROOTFH)。

NFS4ERR_NOSPC No space left on device. The operation would have caused the server's file system to exceed its limit.

NFS4ERR_NOSPC设备上没有剩余空间。该操作将导致服务器的文件系统超出其限制。

NFS4ERR_NOTDIR Not a directory. The caller specified a non-directory in a directory operation.

NFS4ERR_NOTDIR不是目录。调用方在目录操作中指定了非目录。

NFS4ERR_NOTEMPTY An attempt was made to remove a directory that was not empty.

NFS4ERR_NOTEMPTY试图删除一个非空目录。

NFS4ERR_NOTSUPP Operation is not supported.

不支持NFS4ERR_NOTSUPP操作。

NFS4ERR_NOT_SAME This error is returned by the VERIFY operation to signify that the attributes compared were not the same as provided in the client's request.

NFS4ERR_NOT_SAME验证操作返回此错误,表示所比较的属性与客户端请求中提供的属性不同。

NFS4ERR_NXIO I/O error. No such device or address.

NFS4ERR\u NXIO输入/输出错误。没有这样的设备或地址。

NFS4ERR_OLD_STATEID A stateid which designates the locking state for a lockowner-file at an earlier time was used.

NFS4ERR_OLD_STATEID使用了一个STATEID,用于指定先前锁所有者文件的锁定状态。

NFS4ERR_PERM Not owner. The operation was not allowed because the caller is either not a privileged user (root) or not the owner of the target of the operation.

NFS4ERR_PERM不是所有者。不允许该操作,因为调用方不是特权用户(根用户)或不是操作目标的所有者。

NFS4ERR_READDIR_NOSPC The encoded response to a READDIR request exceeds the size limit set by the initial request.

NFS4ERR_READDIR_NOSPC对READDIR请求的编码响应超过初始请求设置的大小限制。

NFS4ERR_RESOURCE For the processing of the COMPOUND procedure, the server may exhaust available resources and can not continue processing procedures within the COMPOUND operation. This error will be returned from the server in those instances of resource exhaustion related to the processing of the COMPOUND procedure.

NFS4ERR_资源对于复合过程的处理,服务器可能会耗尽可用资源,并且无法继续复合操作中的处理过程。在与复合过程处理相关的资源耗尽实例中,服务器将返回此错误。

NFS4ERR_ROFS Read-only file system. A modifying operation was attempted on a read-only file system.

NFS4ERR_ROFS只读文件系统。试图在只读文件系统上执行修改操作。

NFS4ERR_SAME This error is returned by the NVERIFY operation to signify that the attributes compared were the same as provided in the client's request.

NFS4ERR_SAME此错误由NVERIFY操作返回,表示比较的属性与客户端请求中提供的相同。

NFS4ERR_SERVERFAULT An error occurred on the server which does not map to any of the legal NFS version 4 protocol error values. The client should translate this into an appropriate error. UNIX clients may choose to translate this to EIO.

NFS4ERR_SERVERFAULT服务器上发生错误,该错误未映射到任何合法的NFS版本4协议错误值。客户机应将此转换为适当的错误。UNIX客户端可以选择将其转换为EIO。

NFS4ERR_SHARE_DENIED An attempt to OPEN a file with a share reservation has failed because of a share conflict.

NFS4ERR_SHARE_拒绝尝试打开具有共享保留的文件失败,原因是共享冲突。

NFS4ERR_STALE Invalid file handle. The file handle given in the arguments was invalid. The file referred to by that file handle no longer exists or access to it has been revoked.

NFS4ERR_过时无效的文件句柄。参数中给定的文件句柄无效。该文件句柄引用的文件不再存在,或者对该文件的访问已被撤销。

NFS4ERR_STALE_CLIENTID A clientid not recognized by the server was used in a locking or SETCLIENTID_CONFIRM request.

NFS4ERR_STALE_CLIENTID服务器无法识别的CLIENTID用于锁定或SETCLIENTID_确认请求。

NFS4ERR_STALE_STATEID A stateid generated by an earlier server instance was used.

NFS4ERR_STALE_STATEID使用了由早期服务器实例生成的STATEID。

NFS4ERR_SYMLINK The current file handle provided for a LOOKUP is not a directory but a symbolic link. Also used if the final component of the OPEN path is a symbolic link.

NFS4ERR_SYMLINK为查找提供的当前文件句柄不是目录,而是符号链接。如果开放路径的最后一个组件是符号链接,也可使用。

NFS4ERR_TOOSMALL Buffer or request is too small.

NFS4ERR\u缓冲区太小或请求太小。

NFS4ERR_WRONGSEC The security mechanism being used by the client for the procedure does not match the server's security policy. The client should change the security mechanism being used and retry the operation.

NFS4ERR_错误客户端用于过程的安全机制与服务器的安全策略不匹配。客户端应更改正在使用的安全机制,然后重试该操作。

NFS4ERR_XDEV Attempt to do a cross-device hard link.

NFS4ERR_XDEV尝试进行跨设备硬链接。

13. NFS Version 4 Requests
13. NFS版本4请求

For the NFS version 4 RPC program, there are two traditional RPC procedures: NULL and COMPOUND. All other functionality is defined as a set of operations and these operations are defined in normal XDR/RPC syntax and semantics. However, these operations are

对于NFS版本4 RPC程序,有两个传统的RPC过程:NULL和component。所有其他功能都被定义为一组操作,这些操作是在正常的XDR/RPC语法和语义中定义的。然而,这些行动是不公平的

encapsulated within the COMPOUND procedure. This requires that the client combine one or more of the NFS version 4 operations into a single request.

封装在复合程序中。这要求客户端将一个或多个NFS版本4操作合并到一个请求中。

The NFS4_CALLBACK program is used to provide server to client signaling and is constructed in a similar fashion as the NFS version 4 program. The procedures CB_NULL and CB_COMPOUND are defined in the same way as NULL and COMPOUND are within the NFS program. The CB_COMPOUND request also encapsulates the remaining operations of the NFS4_CALLBACK program. There is no predefined RPC program number for the NFS4_CALLBACK program. It is up to the client to specify a program number in the "transient" program range. The program and port number of the NFS4_CALLBACK program are provided by the client as part of the SETCLIENTID operation and therefore is fixed for the life of the client instantiation.

NFS4_回调程序用于提供服务器到客户端的信令,其构造方式与NFS版本4程序类似。CB_NULL和CB_component过程的定义方式与NFS程序中的NULL和component过程相同。CB_复合请求还封装了NFS4_回调程序的其余操作。NFS4_回调程序没有预定义的RPC程序编号。由客户机在“瞬态”程序范围内指定程序编号。NFS4_回调程序的程序和端口号由客户端作为SETCLIENTID操作的一部分提供,因此在客户端实例化的生命周期内是固定的。

13.1. Compound Procedure
13.1. 复合程序

The COMPOUND procedure provides the opportunity for better performance within high latency networks. The client can avoid cumulative latency of multiple RPCs by combining multiple dependent operations into a single COMPOUND procedure. A compound operation may provide for protocol simplification by allowing the client to combine basic procedures into a single request that is customized for the client's environment.

复合过程提供了在高延迟网络中获得更好性能的机会。客户端可以通过将多个相关操作组合到一个复合过程中来避免多个RPC的累积延迟。复合操作可通过允许客户机将基本过程组合成针对客户机环境定制的单个请求来提供协议简化。

The CB_COMPOUND procedure precisely parallels the features of COMPOUND as described above.

CB_复合程序与上述复合物的特征完全平行。

The basics of the COMPOUND procedures construction is:

复合程序构造的基础是:

                  +-----------+-----------+-----------+--
                  | op + args | op + args | op + args |
                  +-----------+-----------+-----------+--
        
                  +-----------+-----------+-----------+--
                  | op + args | op + args | op + args |
                  +-----------+-----------+-----------+--
        

and the reply looks like this:

答案是这样的:

      +------------+-----------------------+-----------------------+--
      |last status | status + op + results | status + op + results |
      +------------+-----------------------+-----------------------+--
        
      +------------+-----------------------+-----------------------+--
      |last status | status + op + results | status + op + results |
      +------------+-----------------------+-----------------------+--
        
13.2. Evaluation of a Compound Request
13.2. 对复合请求的评估

The server will process the COMPOUND procedure by evaluating each of the operations within the COMPOUND procedure in order. Each component operation consists of a 32 bit operation code, followed by the argument of length determined by the type of operation. The results of each operation are encoded in sequence into a reply

服务器将通过按顺序评估复合过程中的每个操作来处理复合过程。每个组件操作由一个32位操作代码组成,后跟由操作类型确定的长度参数。每个操作的结果按顺序编码到应答中

buffer. The results of each operation are preceded by the opcode and a status code (normally zero). If an operation results in a non-zero status code, the status will be encoded and evaluation of the compound sequence will halt and the reply will be returned. Note that evaluation stops even in the event of "non error" conditions such as NFS4ERR_SAME.

缓冲器每个操作的结果前面都有操作码和状态码(通常为零)。如果操作导致非零状态代码,则状态将被编码,复合序列的评估将停止,并返回应答。请注意,即使在出现“非错误”条件(如NFS4ERR_)时,评估也会停止。

There are no atomicity requirements for the operations contained within the COMPOUND procedure. The operations being evaluated as part of a COMPOUND request may be evaluated simultaneously with other COMPOUND requests that the server receives.

复合程序中包含的操作没有原子性要求。作为复合请求一部分评估的操作可以与服务器接收的其他复合请求同时评估。

It is the client's responsibility for recovering from any partially completed COMPOUND procedure. Partially completed COMPOUND procedures may occur at any point due to errors such as NFS4ERR_RESOURCE and NFS4ERR_LONG_DELAY. This may occur even given an otherwise valid operation string. Further, a server reboot which occurs in the middle of processing a COMPOUND procedure may leave the client with the difficult task of determining how far COMPOUND processing has proceeded. Therefore, the client should avoid overly complex COMPOUND procedures in the event of the failure of an operation within the procedure.

客户有责任从任何部分完成的复合程序中恢复。由于NFS4ERR_RESOURCE和NFS4ERR_LONG_DELAY等错误,部分完成的复合过程可能会在任何时候发生。即使给定有效的操作字符串,也可能发生这种情况。此外,在处理复合过程的过程中发生的服务器重启可能会使客户端难以确定复合处理已经进行了多远。因此,如果程序中的操作失败,客户应避免过于复杂的复合程序。

Each operation assumes a "current" and "saved" filehandle that is available as part of the execution context of the compound request. Operations may set, change, or return the current filehandle. The "saved" filehandle is used for temporary storage of a filehandle value and as operands for the RENAME and LINK operations.

每个操作都假定一个“当前”和“保存”的文件句柄,该句柄作为复合请求的执行上下文的一部分可用。操作可以设置、更改或返回当前文件句柄。“保存”文件句柄用于临时存储文件句柄值,并用作重命名和链接操作的操作数。

13.3. Synchronous Modifying Operations
13.3. 同步修改操作

NFS version 4 operations that modify the file system are synchronous. When an operation is successfully completed at the server, the client can depend that any data associated with the request is now on stable storage (the one exception is in the case of the file data in a WRITE operation with the UNSTABLE option specified).

修改文件系统的NFS版本4操作是同步的。当操作在服务器上成功完成时,客户机可以确定与请求相关联的任何数据现在都在稳定的存储中(一个例外是在指定了不稳定选项的写操作中的文件数据)。

This implies that any previous operations within the same compound request are also reflected in stable storage. This behavior enables the client's ability to recover from a partially executed compound request which may resulted from the failure of the server. For example, if a compound request contains operations A and B and the server is unable to send a response to the client, depending on the progress the server made in servicing the request the result of both operations may be reflected in stable storage or just operation A may be reflected. The server must not have just the results of operation B in stable storage.

这意味着同一复合请求中的任何先前操作也会反映在稳定存储中。此行为使客户端能够从可能由服务器故障导致的部分执行的复合请求中恢复。例如,如果一个复合请求包含操作a和B,而服务器无法向客户端发送响应,则根据服务器为请求提供服务的进度,这两个操作的结果可能会反映在稳定存储中,也可能只反映操作a。服务器不能只有稳定存储中的操作B的结果。

13.4. Operation Values
13.4. 操作值

The operations encoded in the COMPOUND procedure are identified by operation values. To avoid overlap with the RPC procedure numbers, operations 0 (zero) and 1 are not defined. Operation 2 is not defined but reserved for future use with minor versioning.

复合过程中编码的操作由操作值标识。为避免与RPC过程编号重叠,未定义操作0(零)和1。操作2未定义,但保留供将来使用,并带有次要版本控制。

14. NFS Version 4 Procedures
14. NFS版本4过程
14.1. Procedure 0: NULL - No Operation
14.1. 过程0:NULL-无操作

SYNOPSIS

提要

<null>

<null>

ARGUMENT

论点

void;

无效的

RESULT

后果

void;

无效的

DESCRIPTION

描述

Standard NULL procedure. Void argument, void response. This procedure has no functionality associated with it. Because of this it is sometimes used to measure the overhead of processing a service request. Therefore, the server should ensure that no unnecessary work is done in servicing this procedure.

标准的空过程。无效的论点,无效的回应。此过程没有与之关联的功能。因此,它有时用于测量处理服务请求的开销。因此,服务器应确保在维护此过程时不会进行不必要的工作。

ERRORS

错误

None.

没有一个

14.2. Procedure 1: COMPOUND - Compound Operations
14.2. 程序1:复合-复合操作

SYNOPSIS

提要

compoundargs -> compoundres

合成标记->合成标记

ARGUMENT

论点

      union nfs_argop4 switch (nfs_opnum4 argop) {
              case <OPCODE>: <argument>;
              ...
      };
        
      union nfs_argop4 switch (nfs_opnum4 argop) {
              case <OPCODE>: <argument>;
              ...
      };
        
      struct COMPOUND4args {
              utf8string      tag;
              uint32_t        minorversion;
              nfs_argop4      argarray<>;
      };
        
      struct COMPOUND4args {
              utf8string      tag;
              uint32_t        minorversion;
              nfs_argop4      argarray<>;
      };
        

RESULT

后果

         union nfs_resop4 switch (nfs_opnum4 resop){
                 case <OPCODE>: <result>;
                 ...
         };
        
         union nfs_resop4 switch (nfs_opnum4 resop){
                 case <OPCODE>: <result>;
                 ...
         };
        
         struct COMPOUND4res {
                 nfsstat4        status;
                 utf8string      tag;
                 nfs_resop4      resarray<>;
         };
        
         struct COMPOUND4res {
                 nfsstat4        status;
                 utf8string      tag;
                 nfs_resop4      resarray<>;
         };
        

DESCRIPTION

描述

The COMPOUND procedure is used to combine one or more of the NFS operations into a single RPC request. The main NFS RPC program has two main procedures: NULL and COMPOUND. All other operations use the COMPOUND procedure as a wrapper.

复合过程用于将一个或多个NFS操作组合到单个RPC请求中。主NFS RPC程序有两个主要过程:NULL和component。所有其他操作都将复合过程用作包装器。

The COMPOUND procedure is used to combine individual operations into a single RPC request. The server interprets each of the operations in turn. If an operation is executed by the server and the status of that operation is NFS4_OK, then the next operation in the COMPOUND procedure is executed. The server continues this process until there are no more operations to be executed or one of the operations has a status value other than NFS4_OK.

复合过程用于将单个操作合并到单个RPC请求中。服务器依次解释每个操作。如果服务器执行一个操作,且该操作的状态为NFS4_OK,则执行复合过程中的下一个操作。服务器将继续此过程,直到不再执行任何操作,或者其中一个操作的状态值不是NFS4_OK。

In the processing of the COMPOUND procedure, the server may find that it does not have the available resources to execute any or all of the operations within the COMPOUND sequence. In this case, the error NFS4ERR_RESOURCE will be returned for the particular operation within the COMPOUND procedure where the resource exhaustion occurred. This assumes that all previous operations within the COMPOUND sequence have been evaluated successfully. The results for all of the evaluated operations must be returned to the client.

在复合过程的处理过程中,服务器可能会发现它没有可用的资源来执行复合序列中的任何或所有操作。在这种情况下,对于发生资源耗尽的复合过程中的特定操作,将返回错误NFS4ERR_资源。这假设复合序列中以前的所有操作都已成功评估。必须将所有已评估操作的结果返回给客户端。

The COMPOUND arguments contain a "minorversion" field. The initial and default value for this field is 0 (zero). This field will be used by future minor versions such that the client can communicate to the server what minor version is being requested.

复合参数包含一个“minorversion”字段。此字段的初始值和默认值为0(零)。此字段将由将来的次要版本使用,以便客户端可以与服务器通信请求的次要版本。

If the server receives a COMPOUND procedure with a minorversion field value that it does not support, the server MUST return an error of NFS4ERR_MINOR_VERS_MISMATCH and a zero length resultdata array.

如果服务器接收到一个复合过程,其minorversion字段值不受支持,则服务器必须返回NFS4ERR_MINOR_VERS_MISMATCH错误和长度为零的resultdata数组。

Contained within the COMPOUND results is a "status" field. If the results array length is non-zero, this status must be equivalent to the status of the last operation that was executed within the COMPOUND procedure. Therefore, if an operation incurred an error then the "status" value will be the same error value as is being returned for the operation that failed.

复合结果中包含一个“状态”字段。如果结果数组长度非零,则此状态必须与在复合过程中执行的最后一个操作的状态相等。因此,如果操作发生错误,“状态”值将与为失败的操作返回的错误值相同。

Note that operations, 0 (zero) and 1 (one) are not defined for the COMPOUND procedure. If the server receives an operation array with either of these included, an error of NFS4ERR_NOTSUPP must be returned. Operation 2 is not defined but reserved for future definition and use with minor versioning. If the server receives a operation array that contains operation 2 and the minorversion field has a value of 0 (zero), an error of NFS4ERR_NOTSUPP is returned. If an operation array contains an operation 2 and the minorversion field is non-zero and the server does not support the minor version, the server returns an error of NFS4ERR_MINOR_VERS_MISMATCH. Therefore, the NFS4ERR_MINOR_VERS_MISMATCH error takes precedence over all other errors.

请注意,没有为复合过程定义操作0(零)和1(一)。如果服务器接收到包含其中任何一个的操作数组,则必须返回NFS4ERR_NOTSUPP错误。操作2未定义,但保留用于将来的定义,并与次要版本控制一起使用。如果服务器接收到包含操作2的操作数组,并且minorversion字段的值为0(零),则返回错误NFS4ERR_NOTSUPP。如果操作数组包含操作2且minorversion字段为非零且服务器不支持次要版本,则服务器返回错误NFS4ERR_minor_VERS_MISMATCH。因此,NFS4ERR_MINOR_VERS_失配错误优先于所有其他错误。

IMPLEMENTATION

实施

Note that the definition of the "tag" in both the request and response are left to the implementor. It may be used to summarize the content of the compound request for the benefit of packet sniffers and engineers debugging implementations.

请注意,请求和响应中“标记”的定义都留给实现者。它可以用来总结复合请求的内容,以便包嗅探器和工程师调试实现。

Since an error of any type may occur after only a portion of the operations have been evaluated, the client must be prepared to recover from any failure. If the source of an NFS4ERR_RESOURCE error was a complex or lengthy set of operations, it is likely that if the number of operations were reduced the server would be able to evaluate them successfully. Therefore, the client is responsible for dealing with this type of complexity in recovery.

由于任何类型的错误都可能在仅评估了部分操作之后发生,因此客户机必须准备好从任何故障中恢复。如果NFS4ERR_资源错误的来源是一组复杂或冗长的操作,则如果操作数量减少,服务器很可能能够成功评估这些操作。因此,客户机负责处理恢复中的此类复杂性。

ERRORS

错误

All errors defined in the protocol

协议中定义的所有错误

14.2.1. Operation 3: ACCESS - Check Access Rights
14.2.1. 操作3:访问-检查访问权限

SYNOPSIS

提要

(cfh), accessreq -> supported, accessrights

(cfh),accessreq->支持,accessrights

ARGUMENT

论点

         const ACCESS4_READ      = 0x00000001;
         const ACCESS4_LOOKUP    = 0x00000002;
         const ACCESS4_MODIFY    = 0x00000004;
         const ACCESS4_EXTEND    = 0x00000008;
         const ACCESS4_DELETE    = 0x00000010;
         const ACCESS4_EXECUTE   = 0x00000020;
        
         const ACCESS4_READ      = 0x00000001;
         const ACCESS4_LOOKUP    = 0x00000002;
         const ACCESS4_MODIFY    = 0x00000004;
         const ACCESS4_EXTEND    = 0x00000008;
         const ACCESS4_DELETE    = 0x00000010;
         const ACCESS4_EXECUTE   = 0x00000020;
        
         struct ACCESS4args {
                 /* CURRENT_FH: object */
                 uint32_t        access;
         };
        
         struct ACCESS4args {
                 /* CURRENT_FH: object */
                 uint32_t        access;
         };
        

RESULT

后果

         struct ACCESS4resok {
                 uint32_t        supported;
                 uint32_t        access;
         };
        
         struct ACCESS4resok {
                 uint32_t        supported;
                 uint32_t        access;
         };
        
         union ACCESS4res switch (nfsstat4 status) {
          case NFS4_OK:
                  ACCESS4resok   resok4;
          default:
                  void;
         };
        
         union ACCESS4res switch (nfsstat4 status) {
          case NFS4_OK:
                  ACCESS4resok   resok4;
          default:
                  void;
         };
        

DESCRIPTION

描述

ACCESS determines the access rights that a user, as identified by the credentials in the RPC request, has with respect to the file system object specified by the current filehandle. The client encodes the set of access rights that are to be checked in the bit mask "access". The server checks the permissions encoded in the bit mask. If a status of NFS4_OK is returned, two bit masks are included in the response. The first, "supported", represents the access rights for which the server can verify reliably. The second, "access", represents the access rights available to the user for the filehandle provided. On success, the current filehandle retains its value.

ACCESS确定用户(由RPC请求中的凭据标识)对当前filehandle指定的文件系统对象具有的访问权限。客户端对要在位掩码“访问”中检查的访问权限集进行编码。服务器检查位掩码中编码的权限。如果返回NFS4_OK状态,则响应中包括两位掩码。第一个“受支持”表示服务器可以可靠验证的访问权限。第二个“access”表示用户对提供的文件句柄的访问权限。成功后,当前文件句柄将保留其值。

Note that the supported field will contain only as many values as was originally sent in the arguments. For example, if the client sends an ACCESS operation with only the ACCESS4_READ value set and the server supports this value, the server will return only ACCESS4_READ even if it could have reliably checked other values.

请注意,支持的字段将只包含最初在参数中发送的值。例如,如果客户端发送的访问操作仅设置了ACCESS4\u读取值,并且服务器支持此值,则即使服务器可以可靠地检查其他值,服务器也将仅返回ACCESS4\u读取。

The results of this operation are necessarily advisory in nature. A return status of NFS4_OK and the appropriate bit set in the bit mask does not imply that such access will be allowed to the file system object in the future. This is because access rights can be revoked by the server at any time.

这一行动的结果必然具有咨询性质。NFS4_OK的返回状态和位掩码中设置的适当位并不意味着将来将允许对文件系统对象进行此类访问。这是因为服务器可以随时撤销访问权限。

The following access permissions may be requested:

可能会请求以下访问权限:

ACCESS4_READ Read data from file or read a directory.

ACCESS4\u从文件中读取数据或读取目录。

ACCESS4_LOOKUP Look up a name in a directory (no meaning for non-directory objects).

ACCESS4\u查找在目录中查找名称(对于非目录对象没有意义)。

ACCESS4_MODIFY Rewrite existing file data or modify existing directory entries.

ACCESS4\u修改重写现有文件数据或修改现有目录项。

ACCESS4_EXTEND Write new data or add directory entries.

ACCESS4\u扩展写入新数据或添加目录项。

ACCESS4_DELETE Delete an existing directory entry (no meaning for non-directory objects).

ACCESS4\u DELETE删除现有目录项(对于非目录对象没有意义)。

ACCESS4_EXECUTE Execute file (no meaning for a directory).

ACCESS4\u执行文件(对目录没有意义)。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

For the NFS version 4 protocol, the use of the ACCESS procedure when opening a regular file is deprecated in favor of using OPEN.

对于NFS版本4协议,不推荐在打开常规文件时使用ACCESS过程,而推荐使用OPEN。

In general, it is not sufficient for the client to attempt to deduce access permissions by inspecting the uid, gid, and mode fields in the file attributes or by attempting to interpret the contents of the ACL attribute. This is because the server may perform uid or gid mapping or enforce additional access control restrictions. It is also possible that the server may not be in the same ID space as the client. In these cases (and perhaps others), the client can not reliably perform an access check with only current file attributes.

通常,客户端仅通过检查文件属性中的uid、gid和mode字段或尝试解释ACL属性的内容来推断访问权限是不够的。这是因为服务器可能会执行uid或gid映射,或者强制执行其他访问控制限制。服务器也可能与客户端不在同一ID空间中。在这些情况下(可能还有其他情况),客户机无法仅使用当前文件属性可靠地执行访问检查。

In the NFS version 2 protocol, the only reliable way to determine whether an operation was allowed was to try it and see if it succeeded or failed. Using the ACCESS procedure in the NFS version 4 protocol, the client can ask the server to indicate whether or not one or more classes of operations are permitted. The ACCESS operation is provided to allow clients to check before doing a series of operations which will result in an access failure. The OPEN operation provides a point where the server can verify access to the file object and method to return that information to the client. The ACCESS operation is still useful for directory operations or for use in the case the UNIX API "access" is used on the client.

在NFS版本2协议中,确定是否允许操作的唯一可靠方法是尝试操作并查看操作是否成功。使用NFS版本4协议中的访问过程,客户机可以要求服务器指示是否允许一个或多个操作类。提供访问操作是为了允许客户端在执行一系列操作之前进行检查,这些操作将导致访问失败。打开操作提供了一个点,服务器可以在此点验证对文件对象和方法的访问,以将该信息返回给客户端。访问操作对于目录操作或在客户端使用UNIX API“ACCESS”的情况下仍然有用。

The information returned by the server in response to an ACCESS call is not permanent. It was correct at the exact time that the server performed the checks, but not necessarily afterwards. The server can revoke access permission at any time.

服务器响应访问调用返回的信息不是永久性的。服务器执行检查的确切时间是正确的,但不一定是在检查之后。服务器可以随时撤消访问权限。

The client should use the effective credentials of the user to build the authentication information in the ACCESS request used to determine access rights. It is the effective user and group credentials that are used in subsequent read and write operations.

客户端应使用用户的有效凭据在用于确定访问权限的访问请求中构建身份验证信息。在后续读写操作中使用的是有效的用户和组凭据。

Many implementations do not directly support the ACCESS4_DELETE permission. Operating systems like UNIX will ignore the ACCESS4_DELETE bit if set on an access request on a non-directory object. In these systems, delete permission on a file is determined by the access permissions on the directory in which the file resides, instead of being determined by the permissions of the file itself. Therefore, the mask returned enumerating which access rights can be determined will have the ACCESS4_DELETE value set to 0. This indicates to the client that the server was unable to check that particular access right. The ACCESS4_DELETE bit in the access mask returned will then be ignored by the client.

许多实现不直接支持ACCESS4_DELETE权限。如果在非目录对象的访问请求上设置了ACCESS4\u DELETE位,则UNIX等操作系统将忽略该位。在这些系统中,文件的删除权限由文件所在目录的访问权限决定,而不是由文件本身的权限决定。因此,返回的用于枚举可确定哪些访问权限的掩码将ACCESS4_DELETE值设置为0。这向客户端表明服务器无法检查特定的访问权限。然后,客户端将忽略返回的访问掩码中的ACCESS4_DELETE位。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误秒

14.2.2. Operation 4: CLOSE - Close File
14.2.2. 操作4:关闭-关闭文件

SYNOPSIS

提要

(cfh), seqid, stateid -> stateid

(cfh),seqid,stateid->stateid

ARGUMENT

论点

         struct CLOSE4args {
                 /* CURRENT_FH: object */
                 seqid4          seqid
                 stateid4        stateid;
         };
        
         struct CLOSE4args {
                 /* CURRENT_FH: object */
                 seqid4          seqid
                 stateid4        stateid;
         };
        

RESULT

后果

         union CLOSE4res switch (nfsstat4 status) {
          case NFS4_OK:
                  stateid4       stateid;
          default:
                  void;
         };
        
         union CLOSE4res switch (nfsstat4 status) {
          case NFS4_OK:
                  stateid4       stateid;
          default:
                  void;
         };
        

DESCRIPTION

描述

The CLOSE operation releases share reservations for the file as specified by the current filehandle. The share reservations and other state information released at the server as a result of this CLOSE is only associated with the supplied stateid. The sequence id provides for the correct ordering. State associated with other OPENs is not affected.

关闭操作释放当前文件句柄指定的文件共享保留。由于此关闭而在服务器上发布的共享保留和其他状态信息仅与提供的stateid关联。序列id提供了正确的顺序。与其他打开关联的状态不受影响。

If record locks are held, the client SHOULD release all locks before issuing a CLOSE. The server MAY free all outstanding locks on CLOSE but some servers may not support the CLOSE of a file that still has record locks held. The server MUST return failure if any locks would exist after the CLOSE.

如果记录锁被持有,客户端应在发出关闭之前释放所有锁。服务器可能会在关闭时释放所有未完成的锁,但某些服务器可能不支持关闭仍保留记录锁的文件。如果关闭后存在任何锁,服务器必须返回failure。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_DELAY

NFS4ERR_baddHandle NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_DELAY

NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u过期NFS4ERR\u Fhs4Err\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u ISDIR NFS4ERR\u租赁NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u旧的NFS4ERR\u状态ID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u旧的NFS4ERR\u状态ID

14.2.3. Operation 5: COMMIT - Commit Cached Data
14.2.3. 操作5:提交-提交缓存数据

SYNOPSIS

提要

(cfh), offset, count -> verifier

(cfh),偏移量,计数->验证器

ARGUMENT

论点

         struct COMMIT4args {
                 /* CURRENT_FH: file */
                 offset4         offset;
                 count4          count;
         };
        
         struct COMMIT4args {
                 /* CURRENT_FH: file */
                 offset4         offset;
                 count4          count;
         };
        

RESULT

后果

         struct COMMIT4resok {
                 verifier4       writeverf;
         };
        
         struct COMMIT4resok {
                 verifier4       writeverf;
         };
        
         union COMMIT4res switch (nfsstat4 status) {
          case NFS4_OK:
                  COMMIT4resok   resok4;
          default:
                  void;
         };
        
         union COMMIT4res switch (nfsstat4 status) {
          case NFS4_OK:
                  COMMIT4resok   resok4;
          default:
                  void;
         };
        

DESCRIPTION

描述

The COMMIT operation forces or flushes data to stable storage for the file specified by the current file handle. The flushed data is that which was previously written with a WRITE operation which had the stable field set to UNSTABLE4.

提交操作将数据强制或刷新到由当前文件句柄指定的文件的稳定存储中。刷新的数据是以前使用写入操作写入的数据,该操作的稳定字段设置为不稳定4。

The offset specifies the position within the file where the flush is to begin. An offset value of 0 (zero) means to flush data starting at the beginning of the file. The count specifies the number of bytes of data to flush. If count is 0 (zero), a flush from offset to the end of the file is done.

偏移量指定文件中开始刷新的位置。偏移量值为0(零)表示从文件开头开始刷新数据。计数指定要刷新的数据字节数。如果计数为0(零),则完成从偏移量到文件末尾的刷新。

The server returns a write verifier upon successful completion of the COMMIT. The write verifier is used by the client to determine if the server has restarted or rebooted between the initial WRITE(s) and the COMMIT. The client does this by comparing the write verifier returned from the initial writes and the verifier returned by the COMMIT procedure. The server must vary the value of the write verifier at each server event or instantiation that may lead to a loss of uncommitted data. Most commonly this occurs when the server is rebooted; however, other events at the server may result in uncommitted data loss as well.

服务器在成功完成提交后返回写验证程序。客户机使用写入验证器来确定服务器在初始写入和提交之间是否已重新启动或重新启动。客户端通过比较从初始写入返回的写入验证器和提交过程返回的验证器来实现这一点。服务器必须在每个可能导致未提交数据丢失的服务器事件或实例化时更改写入验证器的值。这通常发生在服务器重新启动时;但是,服务器上的其他事件也可能导致未提交的数据丢失。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The COMMIT procedure is similar in operation and semantics to the POSIX fsync(2) system call that synchronizes a file's state with the disk (file data and metadata is flushed to disk or stable storage). COMMIT performs the same operation for a client, flushing any unsynchronized data and metadata on the server to the server's disk or stable storage for the specified file. Like fsync(2), it may be that there is some modified data or no modified data to synchronize. The data may have been synchronized by the server's normal periodic buffer synchronization activity. COMMIT should return NFS4_OK, unless there has been an unexpected error.

提交过程在操作和语义上与POSIX fsync(2)系统调用类似,POSIX fsync(2)系统调用将文件状态与磁盘同步(文件数据和元数据刷新到磁盘或稳定存储)。COMMIT对客户端执行相同的操作,将服务器上的任何未同步数据和元数据刷新到服务器的磁盘或指定文件的稳定存储中。与fsync(2)一样,可能有一些修改过的数据或没有修改过的数据需要同步。数据可能已由服务器的正常定期缓冲区同步活动同步。COMMIT应返回NFS4\u OK,除非出现意外错误。

COMMIT differs from fsync(2) in that it is possible for the client to flush a range of the file (most likely triggered by a buffer-reclamation scheme on the client before file has been completely written).

COMMIT与fsync(2)的不同之处在于,客户端可以刷新文件的某个范围(很可能是在文件完全写入之前由客户端上的缓冲区回收方案触发)。

The server implementation of COMMIT is reasonably simple. If the server receives a full file COMMIT request, that is starting at offset 0 and count 0, it should do the equivalent of fsync()'ing the file. Otherwise, it should arrange to have the cached data in the range specified by offset and count to be flushed to stable storage. In both cases, any metadata associated with the file must be flushed to stable storage before returning. It is not an error for there to be nothing to flush on the server. This means that the data and metadata that needed to be flushed have already been flushed or lost during the last server failure.

提交的服务器实现相当简单。如果服务器接收到一个完整的文件提交请求,即从偏移量0和计数0开始,它应该执行与fsync()相同的操作。否则,它应该将缓存数据安排在由offset和count指定的范围内,以便刷新到稳定存储中。在这两种情况下,在返回之前,必须将与文件关联的任何元数据刷新到稳定存储中。服务器上没有要刷新的内容不是错误。这意味着需要刷新的数据和元数据在上次服务器故障期间已被刷新或丢失。

The client implementation of COMMIT is a little more complex. There are two reasons for wanting to commit a client buffer to stable storage. The first is that the client wants to reuse a buffer. In this case, the offset and count of the buffer are sent to the server in the COMMIT request. The server then flushes any cached data based on the offset and count, and flushes any metadata associated with the file. It then returns the status of the flush and the write verifier. The other reason for the client to generate a COMMIT is for a full file flush, such as may be done at close. In this case, the client would gather all of the buffers for this file that contain uncommitted data, do the COMMIT operation with an offset of 0 and count of 0, and then free all of those buffers. Any other dirty buffers would be sent to the server in the normal fashion.

提交的客户端实现稍微复杂一些。想要将客户机缓冲区提交到稳定存储有两个原因。首先,客户机希望重用缓冲区。在这种情况下,缓冲区的偏移量和计数将在提交请求中发送到服务器。然后,服务器根据偏移量和计数刷新所有缓存数据,并刷新与文件关联的所有元数据。然后,它返回刷新和写入验证器的状态。客户机生成提交的另一个原因是进行完整的文件刷新,例如在关闭时进行。在这种情况下,客户端将为此文件收集包含未提交数据的所有缓冲区,使用偏移量0和计数0执行提交操作,然后释放所有这些缓冲区。任何其他脏缓冲区都将以正常方式发送到服务器。

After a buffer is written by the client with the stable parameter set to UNSTABLE4, the buffer must be considered as modified by the client until the buffer has either been flushed via a COMMIT operation or written via a WRITE operation with stable parameter set to FILE_SYNC4 or DATA_SYNC4. This is done to prevent the buffer from being freed and reused before the data can be flushed to stable storage on the server.

客户端在将stable参数设置为UNSTABLE4的情况下写入缓冲区后,必须将该缓冲区视为已被客户端修改,直到通过提交操作刷新缓冲区,或通过将stable参数设置为FILE_SYNC4或DATA_SYNC4的写入操作写入缓冲区为止。这样做是为了防止在将数据刷新到服务器上的稳定存储之前释放和重用缓冲区。

When a response is returned from either a WRITE or a COMMIT operation and it contains a write verifier that is different than previously returned by the server, the client will need to retransmit all of the buffers containing uncommitted cached data to the server. How this is to be done is up to the implementor. If there is only one buffer of interest, then it should probably be sent back over in a WRITE request with the appropriate stable parameter. If there is more than one buffer, it might be worthwhile retransmitting all of the buffers in WRITE requests with the stable parameter set to UNSTABLE4 and then retransmitting the COMMIT operation to flush all of the data on the server to stable storage. The timing of these retransmissions is left to the implementor.

当从写操作或提交操作返回响应,并且其中包含与服务器先前返回的不同的写验证程序时,客户端需要将包含未提交缓存数据的所有缓冲区重新传输到服务器。如何做到这一点取决于实现者。如果只有一个感兴趣的缓冲区,那么可能应该在写请求中使用适当的稳定参数将其发送回。如果存在多个缓冲区,则可能值得在stable参数设置为UNSTABLE4的情况下重新传输写请求中的所有缓冲区,然后重新传输COMMIT操作以将服务器上的所有数据刷新到稳定存储。这些重传的时间留给实现者。

The above description applies to page-cache-based systems as well as buffer-cache-based systems. In those systems, the virtual memory system will need to be modified instead of the buffer cache.

上述描述适用于基于页面缓存的系统以及基于缓冲区缓存的系统。在这些系统中,需要修改虚拟内存系统,而不是缓存。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_IO

NFS4ERR_访问NFS4ERR_BADHANDLE NFS4ERR_FH过期NFS4ERR_IO

NFS4ERR_ISDIR NFS4ERR_LOCKED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_ISDIR NFS4ERR_锁定NFS4ERR_移动的NFS4ERR_NOFILEHANDLE NFS4ERR_资源NFS4ERR_ROFS NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_错误秒

14.2.4. Operation 6: CREATE - Create a Non-Regular File Object
14.2.4. 操作6:创建-创建非常规文件对象

SYNOPSIS

提要

(cfh), name, type -> (cfh), change_info

(cfh)、名称、类型->(cfh)、更改信息

ARGUMENT

论点

         union createtype4 switch (nfs_ftype4 type) {
          case NF4LNK:
                  linktext4      linkdata;
          case NF4BLK:
          case NF4CHR:
                  specdata4      devdata;
          case NF4SOCK:
          case NF4FIFO:
          case NF4DIR:
                  void;
         };
        
         union createtype4 switch (nfs_ftype4 type) {
          case NF4LNK:
                  linktext4      linkdata;
          case NF4BLK:
          case NF4CHR:
                  specdata4      devdata;
          case NF4SOCK:
          case NF4FIFO:
          case NF4DIR:
                  void;
         };
        
         struct CREATE4args {
                 /* CURRENT_FH: directory for creation */
                 component4      objname;
                 createtype4     objtype;
         };
        
         struct CREATE4args {
                 /* CURRENT_FH: directory for creation */
                 component4      objname;
                 createtype4     objtype;
         };
        

RESULT

后果

         struct CREATE4resok {
                 change_info4     cinfo;
         };
        
         struct CREATE4resok {
                 change_info4     cinfo;
         };
        
         union CREATE4res switch (nfsstat4 status) {
          case NFS4_OK:
                  CREATE4resok resok4;
          default:
                  void;
         };
        
         union CREATE4res switch (nfsstat4 status) {
          case NFS4_OK:
                  CREATE4resok resok4;
          default:
                  void;
         };
        

DESCRIPTION

描述

The CREATE operation creates a non-regular file object in a directory with a given name. The OPEN procedure MUST be used to create a regular file.

创建操作在具有给定名称的目录中创建一个非常规文件对象。必须使用“打开”过程创建常规文件。

The objname specifies the name for the new object. If the objname has a length of 0 (zero), the error NFS4ERR_INVAL will be returned. The objtype determines the type of object to be created: directory, symlink, etc.

objname指定新对象的名称。如果对象名的长度为0(零),将返回错误NFS4ERR_INVAL。objtype确定要创建的对象的类型:目录、符号链接等。

If an object of the same name already exists in the directory, the server will return the error NFS4ERR_EXIST.

如果目录中已存在同名对象,服务器将返回错误NFS4ERR_EXIST。

For the directory where the new file object was created, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 struct, the server will indicate if the before and after change attributes were obtained atomically with respect to the file object creation.

对于创建新文件对象的目录,服务器返回cinfo中的change_info4信息。使用change_info4结构的原子字段,服务器将指示是否以原子方式获得了与文件对象创建相关的更改前后属性。

If the objname has a length of 0 (zero), or if objname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果objname的长度为0(零),或者如果objname不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

The current filehandle is replaced by that of the new object.

当前文件句柄将替换为新对象的文件句柄。

IMPLEMENTATION

实施

If the client desires to set attribute values after the create, a SETATTR operation can be added to the COMPOUND request so that the appropriate attributes will be set.

如果客户端希望在创建后设置属性值,则可以向复合请求添加SETATTR操作,以便设置适当的属性。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BADTYPE NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTSUPP

NFS4ERR\u访问NFS4ERR\u BADHANDLE NFS4ERR\u BADTYPE NFS4ERR\u DQUOT NFS4ERR\u存在NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u名称工具在NFS4ERR\u无文件句柄NFS4ERR\u NOSPC NFS4ERR\u NOTSPC NFS4ERR\u NOTDIR NFS4ERR\u NOTSUPP

NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_资源NFS4ERR_ROFS NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_错误秒

14.2.5. Operation 7: DELEGPURGE - Purge Delegations Awaiting Recovery
14.2.5. 操作7:删除清除-清除等待恢复的委派

SYNOPSIS

提要

clientid ->

clientid->

ARGUMENT

论点

         struct DELEGPURGE4args {
                 clientid4       clientid;
        };
        
         struct DELEGPURGE4args {
                 clientid4       clientid;
        };
        

RESULT

后果

         struct DELEGPURGE4res {
                 nfsstat4        status;
         };
        
         struct DELEGPURGE4res {
                 nfsstat4        status;
         };
        

DESCRIPTION

描述

Purges all of the delegations awaiting recovery for a given client. This is useful for clients which do not commit delegation information to stable storage to indicate that conflicting requests need not be delayed by the server awaiting recovery of delegation information.

清除给定客户端等待恢复的所有委派。这对于不将委派信息提交到稳定存储的客户机非常有用,以表明冲突请求不需要由等待恢复委派信息的服务器延迟。

This operation should be used by clients that record delegation information on stable storage on the client. In this case, DELEGPURGE should be issued immediately after doing delegation recovery on all delegations know to the client. Doing so will notify the server that no additional delegations for the client will be recovered allowing it to free resources, and avoid delaying other clients who make requests that conflict with the unrecovered delegations. The set of delegations known to the server and the client may be different. The reason for this is that a client may fail after making a request which resulted in delegation but before it received the results and committed them to the client's stable storage.

此操作应由在客户端上的稳定存储上记录委派信息的客户端使用。在这种情况下,应在对客户知道的所有委托进行委托恢复后立即发布DELEGPURGE。这样做将通知服务器,不会恢复客户端的其他委派,从而允许其释放资源,并避免延迟发出与未恢复委派冲突的请求的其他客户端。服务器和客户端已知的委托集可能不同。原因是,客户机可能在发出导致委派的请求后,但在收到结果并将其提交到客户机的稳定存储之前失败。

ERRORS

错误

NFS4ERR_RESOURCE

NFS4ERR_资源

NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR_服务器故障NFS4ERR_过时客户端ID

14.2.6. Operation 8: DELEGRETURN - Return Delegation
14.2.6. 操作8:DELEGRETURN-返回委派

SYNOPSIS

提要

stateid ->

stateid->

ARGUMENT

论点

         struct DELEGRETURN4args {
                 stateid4        stateid;
         };
        
         struct DELEGRETURN4args {
                 stateid4        stateid;
         };
        

RESULT

后果

         struct DELEGRETURN4res {
                 nfsstat4        status;
         };
        
         struct DELEGRETURN4res {
                 nfsstat4        status;
         };
        

DESCRIPTION

描述

Returns the delegation represented by the given stateid.

返回由给定stateid表示的委托。

ERRORS

错误

NFS4ERR_BAD_STATEID NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_STATEID

NFS4ERR\u坏的\u状态ID NFS4ERR\u旧的\u状态ID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u旧的\u状态ID

14.2.7. Operation 9: GETATTR - Get Attributes
14.2.7. 操作9:GETATTR-获取属性

SYNOPSIS

提要

(cfh), attrbits -> attrbits, attrvals

(cfh),属性->属性,属性

ARGUMENT

论点

         struct GETATTR4args {
                 /* CURRENT_FH: directory or file */
                 bitmap4         attr_request;
         };
        
         struct GETATTR4args {
                 /* CURRENT_FH: directory or file */
                 bitmap4         attr_request;
         };
        

RESULT

后果

         struct GETATTR4resok {
                 fattr4          obj_attributes;
         };
        
         struct GETATTR4resok {
                 fattr4          obj_attributes;
         };
        
         union GETATTR4res switch (nfsstat4 status) {
          case NFS4_OK:
                  GETATTR4resok  resok4;
          default:
                  void;
         };
        
         union GETATTR4res switch (nfsstat4 status) {
          case NFS4_OK:
                  GETATTR4resok  resok4;
          default:
                  void;
         };
        

DESCRIPTION

描述

The GETATTR operation will obtain attributes for the file system object specified by the current filehandle. The client sets a bit in the bitmap argument for each attribute value that it would like the server to return. The server returns an attribute bitmap that indicates the attribute values for which it was able to return, followed by the attribute values ordered lowest attribute number first.

GETATTR操作将获取由当前filehandle指定的文件系统对象的属性。客户端在位图参数中为希望服务器返回的每个属性值设置一位。服务器返回一个属性位图,该位图指示它能够返回的属性值,然后是按顺序排列的属性值,该属性值首先是最低的属性号。

The server must return a value for each attribute that the client requests if the attribute is supported by the server. If the server does not support an attribute or cannot approximate a useful value then it must not return the attribute value and must not set the attribute bit in the result bitmap. The server must return an error if it supports an attribute but cannot obtain its value. In that case no attribute values will be returned.

如果服务器支持客户端请求的每个属性,则服务器必须为该属性返回一个值。如果服务器不支持某个属性或无法近似使用值,则它不得返回属性值,也不得在结果位图中设置属性位。如果服务器支持属性但无法获取其值,则必须返回错误。在这种情况下,不会返回属性值。

All servers must support the mandatory attributes as specified in the section "File Attributes".

所有服务器都必须支持“文件属性”部分中指定的强制属性。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障

NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_过时NFS4ERR_错误秒

14.2.8. Operation 10: GETFH - Get Current Filehandle
14.2.8. 操作10:GETFH-获取当前文件句柄

SYNOPSIS

提要

(cfh) -> filehandle

(cfh)->文件句柄

ARGUMENT

论点

         /* CURRENT_FH: */
         void;
        
         /* CURRENT_FH: */
         void;
        

RESULT

后果

         struct GETFH4resok {
                 nfs_fh4         object;
         };
        
         struct GETFH4resok {
                 nfs_fh4         object;
         };
        
         union GETFH4res switch (nfsstat4 status) {
          case NFS4_OK:
                 GETFH4resok     resok4;
          default:
                 void;
         };
        
         union GETFH4res switch (nfsstat4 status) {
          case NFS4_OK:
                 GETFH4resok     resok4;
          default:
                 void;
         };
        

DESCRIPTION

描述

This operation returns the current filehandle value.

此操作返回当前的filehandle值。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

Operations that change the current filehandle like LOOKUP or CREATE do not automatically return the new filehandle as a result. For instance, if a client needs to lookup a directory entry and obtain its filehandle then the following request is needed.

更改当前文件句柄(如查找或创建)的操作不会自动返回新的文件句柄。例如,如果客户机需要查找目录条目并获取其文件句柄,则需要以下请求。

PUTFH (directory filehandle) LOOKUP (entry name) GETFH

PUTFH(目录文件句柄)查找(条目名称)GETFH

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED

NFS4ERR\u坏句柄NFS4ERR\u已过期

NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_移动的NFS4ERR_NOFILEHANDLE NFS4ERR_资源NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_错误秒

14.2.9. Operation 11: LINK - Create Link to a File
14.2.9. 操作11:链接-创建指向文件的链接

SYNOPSIS

提要

(sfh), (cfh), newname -> (cfh), change_info

(sfh),(cfh),新名称->(cfh),更改信息

ARGUMENT

论点

      struct LINK4args {
              /* SAVED_FH: source object */
              /* CURRENT_FH: target directory */
              component4      newname;
      };
        
      struct LINK4args {
              /* SAVED_FH: source object */
              /* CURRENT_FH: target directory */
              component4      newname;
      };
        

RESULT

后果

      struct LINK4resok {
              change_info4    cinfo;
      };
        
      struct LINK4resok {
              change_info4    cinfo;
      };
        
      union LINK4res switch (nfsstat4 status) {
       case NFS4_OK:
               LINK4resok resok4;
       default:
               void;
      };
        
      union LINK4res switch (nfsstat4 status) {
       case NFS4_OK:
               LINK4resok resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The LINK operation creates an additional newname for the file represented by the saved filehandle, as set by the SAVEFH operation, in the directory represented by the current filehandle. The existing file and the target directory must reside within the same file system on the server. On success, the current filehandle will continue to be the target directory.

链接操作在当前文件句柄表示的目录中为保存的文件句柄表示的文件创建一个额外的新名称,如SAVEFH操作所设置的。现有文件和目标目录必须位于服务器上的同一文件系统中。成功后,当前文件句柄将继续作为目标目录。

For the target directory, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 struct, the server will indicate if the before and after change attributes were obtained atomically with respect to the link creation.

对于目标目录,服务器返回cinfo中的change_info4信息。使用change_info4结构的原子字段,服务器将指示是否以原子方式获得了与链接创建相关的更改前后属性。

If the newname has a length of 0 (zero), or if newname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果newname的长度为0(零),或者如果newname不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

IMPLEMENTATION

实施

Changes to any property of the "hard" linked files are reflected in all of the linked files. When a link is made to a file, the attributes for the file should have a value for numlinks that is one greater than the value before the LINK operation.

对“硬”链接文件的任何属性所做的更改都会反映在所有链接文件中。链接到文件时,文件的属性的numlinks值应大于链接操作之前的值。

The comments under RENAME regarding object and target residing on the same file system apply here as well. The comments regarding the target name applies as well.

“重命名”下有关驻留在同一文件系统上的对象和目标的注释也适用于此处。关于目标名称的注释也适用。

Note that symbolic links are created with the CREATE operation.

请注意,符号链接是通过创建操作创建的。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_MLINK NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC NFS4ERR_XDEV

一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,存在的,存在的,一般的,一般的,过期的,一般的,失效的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,一般的,错误的,一般的,一般的,错误4Errxdev

14.2.10. Operation 12: LOCK - Create Lock
14.2.10. 操作12:锁定-创建锁定

SYNOPSIS

提要

(cfh) type, seqid, reclaim, stateid, offset, length -> stateid, access

(cfh)类型,seqid,回收,stateid,偏移量,长度->stateid,访问

ARGUMENT

论点

      enum nfs4_lock_type {
              READ_LT         = 1,
              WRITE_LT        = 2,
              READW_LT        = 3,    /* blocking read */
              WRITEW_LT       = 4     /* blocking write */ };
        
      enum nfs4_lock_type {
              READ_LT         = 1,
              WRITE_LT        = 2,
              READW_LT        = 3,    /* blocking read */
              WRITEW_LT       = 4     /* blocking write */ };
        
      struct LOCK4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              seqid4          seqid;
              bool            reclaim;
              stateid4        stateid;
              offset4         offset;
        
      struct LOCK4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              seqid4          seqid;
              bool            reclaim;
              stateid4        stateid;
              offset4         offset;
        
              length4         length; };
        
              length4         length; };
        

RESULT

后果

      struct LOCK4denied {
              nfs_lockowner4  owner;
              offset4         offset;
              length4         length; };
        
      struct LOCK4denied {
              nfs_lockowner4  owner;
              offset4         offset;
              length4         length; };
        
      union LOCK4res switch (nfsstat4 status) {
       case NFS4_OK:
               stateid4       stateid;
       case NFS4ERR_DENIED:
               LOCK4denied    denied;
       default:
               void; };
        
      union LOCK4res switch (nfsstat4 status) {
       case NFS4_OK:
               stateid4       stateid;
       case NFS4ERR_DENIED:
               LOCK4denied    denied;
       default:
               void; };
        

DESCRIPTION

描述

The LOCK operation requests a record lock for the byte range specified by the offset and length parameters. The lock type is also specified to be one of the nfs4_lock_types. If this is a reclaim request, the reclaim parameter will be TRUE;

锁定操作请求对偏移量和长度参数指定的字节范围进行记录锁定。锁类型也指定为nfs4_锁类型之一。如果这是一个回收请求,回收参数将为TRUE;

Bytes in a file may be locked even if those bytes are not currently allocated to the file. To lock the file from a specific offset through the end-of-file (no matter how long the file actually is) use a length field with all bits set to 1 (one). To lock the entire file, use an offset of 0 (zero) and a length with all bits set to 1. A length of 0 is reserved and should not be used.

文件中的字节可能会被锁定,即使这些字节当前未分配给该文件。要从特定偏移量到文件结尾(无论文件实际有多长)锁定文件,请使用所有位均设置为1(一)的长度字段。要锁定整个文件,请使用偏移量0(零)和长度,并将所有位设置为1。保留长度0,不应使用。

In the case that the lock is denied, the owner, offset, and length of a conflicting lock are returned.

在锁被拒绝的情况下,将返回冲突锁的所有者、偏移量和长度。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

If the server is unable to determine the exact offset and length of the conflicting lock, the same offset and length that were provided in the arguments should be returned in the denied results. The File Locking section contains a full description of this and the other file locking operations.

如果服务器无法确定冲突锁的确切偏移量和长度,则应在拒绝结果中返回参数中提供的相同偏移量和长度。“文件锁定”部分包含此操作和其他文件锁定操作的完整说明。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID

NFS4ERR\u访问NFS4ERR\u错误句柄NFS4ERR\u错误\u序列ID

NFS4ERR_BAD_STATEID NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCK_RANGE NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_CLIENTID NFS4ERR_STALE_STATEID NFS4ERR_WRONGSEC

NFS4ERR\u BAD\u STATEID NFS4ERR\u DELAY NFS4ERR\u DENIED NFS4ERR\u EXPIRED NFS4ERR\u GRACE NFS4ERR\u Invalid NFS4ERR\u ISDIR NFS4ERR\u LEASE\u MOVED NFS4ERR\u LOCK\u RANGE NFS4ERR\u MOVED NFS4ERR\u NOFILEHANDLE NFS4ERR\u旧NFS4ERR\u STATEID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u陈旧客户端错误

14.2.11. Operation 13: LOCKT - Test For Lock
14.2.11. 操作13:锁定-锁定测试

SYNOPSIS

提要

      (cfh) type, owner, offset, length -> {void, NFS4ERR_DENIED ->
      owner}
        
      (cfh) type, owner, offset, length -> {void, NFS4ERR_DENIED ->
      owner}
        

ARGUMENT

论点

      struct LOCKT4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              nfs_lockowner4  owner;
              offset4         offset;
              length4         length; };
        
      struct LOCKT4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              nfs_lockowner4  owner;
              offset4         offset;
              length4         length; };
        

RESULT

后果

      union LOCKT4res switch (nfsstat4 status) {
       case NFS4ERR_DENIED:
               LOCK4denied    denied;
       case NFS4_OK:
               void;
       default:
               void; };
        
      union LOCKT4res switch (nfsstat4 status) {
       case NFS4ERR_DENIED:
               LOCK4denied    denied;
       case NFS4_OK:
               void;
       default:
               void; };
        

DESCRIPTION

描述

The LOCKT operation tests the lock as specified in the arguments. If a conflicting lock exists, the owner, offset, and length of the conflicting lock are returned; if no lock is held, nothing other than NFS4_OK is returned.

LOCKT操作按照参数中的指定测试锁。如果存在冲突锁,则返回冲突锁的所有者、偏移量和长度;如果没有锁定,则只返回NFS4_OK。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

If the server is unable to determine the exact offset and length of the conflicting lock, the same offset and length that were provided in the arguments should be returned in the denied

如果服务器无法确定冲突锁的确切偏移量和长度,则应在拒绝中返回参数中提供的相同偏移量和长度

results. The File Locking section contains further discussion of the file locking mechanisms.

后果文件锁定部分包含对文件锁定机制的进一步讨论。

LOCKT uses nfs_lockowner4 instead of a stateid4, as LOCK does, to identify the owner so that the client does not have to open the file to test for the existence of a lock.

LOCKT使用nfs_lockowner4而不是stateid4(就像LOCK一样)来标识所有者,这样客户端就不必打开文件来测试是否存在锁。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCK_RANGE NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_CLIENTID NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u拒绝NFS4ERR\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u出租NFS4ERR\u移动NFS4ERR\u锁定范围NFS4ERR\u移动NFS4ERR\u文件句柄NFS4ERR\u资源NFS4ERR\u服务器错误NFS4ERR\u过时NFS4ERR\u客户端错误NFS4ERR\u

14.2.12. Operation 14: LOCKU - Unlock File
14.2.12. 操作14:锁定-解锁文件

SYNOPSIS

提要

(cfh) type, seqid, stateid, offset, length -> stateid

(cfh)类型,序号ID,状态ID,偏移量,长度->状态ID

ARGUMENT

论点

      struct LOCKU4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              seqid4          seqid;
              stateid4        stateid;
              offset4         offset;
              length4         length;
      };
        
      struct LOCKU4args {
              /* CURRENT_FH: file */
              nfs_lock_type4  locktype;
              seqid4          seqid;
              stateid4        stateid;
              offset4         offset;
              length4         length;
      };
        

RESULT

后果

union LOCKU4res switch (nfsstat4 status) { case NFS4_OK:

union LOCKU4res开关(nfsstat4状态){情况NFS4_正常:

               stateid4       stateid;
       default:
               void;
      };
        
               stateid4       stateid;
       default:
               void;
      };
        

DESCRIPTION

描述

The LOCKU operation unlocks the record lock specified by the parameters.

LOCKU操作解锁参数指定的记录锁。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The File Locking section contains a full description of this and the other file locking procedures.

“文件锁定”部分包含此文件锁定过程和其他文件锁定过程的完整描述。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_LOCK_RANGE NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_CLIENTID NFS4ERR_STALE_STATEID

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏序NFS4ERR\u坏态NFS4ERR\u过期NFS4ERR\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u锁定范围NFS4ERR\u租赁NFS4ERR\u移动的NFS4ERR\u无文件句柄NFS4ERR\u旧态NFS4ERR\u旧态NFS4ERR\u资源服务器故障NFS4ERR\u陈旧的客户端NFS4ERR\u

14.2.13. Operation 15: LOOKUP - Lookup Filename
14.2.13. 操作15:查找-查找文件名

SYNOPSIS

提要

(cfh), filenames -> (cfh)

(cfh),文件名->(cfh)

ARGUMENT

论点

      struct LOOKUP4args {
              /* CURRENT_FH: directory */
        
      struct LOOKUP4args {
              /* CURRENT_FH: directory */
        
              pathname4       path;
      };
        
              pathname4       path;
      };
        

RESULT

后果

      struct LOOKUP4res {
              /* CURRENT_FH: object */
              nfsstat4        status;
      };
        
      struct LOOKUP4res {
              /* CURRENT_FH: object */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

This operation LOOKUPs or finds a file system object starting from the directory specified by the current filehandle. LOOKUP evaluates the pathname contained in the array of names and obtains a new current filehandle from the final name. All but the final name in the list must be the names of directories.

此操作从当前文件句柄指定的目录开始查找或查找文件系统对象。查找计算名称数组中包含的路径名,并从最终名称中获取新的当前文件句柄。除了列表中的最终名称外,所有名称都必须是目录名。

If the pathname cannot be evaluated either because a component does not exist or because the client does not have permission to evaluate a component of the path, then an error will be returned and the current filehandle will be unchanged.

如果由于组件不存在或客户端无权计算路径的组件而无法计算路径名,则将返回错误,并且当前文件句柄将保持不变。

If the path is a zero length array, if any component does not obey the UTF-8 definition, or if any component in the path is of zero length, the error NFS4ERR_INVAL will be returned.

如果路径为零长度数组,如果任何组件不符合UTF-8定义,或者如果路径中的任何组件为零长度,则将返回错误NFS4ERR_INVAL。

IMPLEMENTATION

实施

If the client prefers a partial evaluation of the path then a sequence of LOOKUP operations can be substituted e.g.

如果客户希望对路径进行部分评估,则可以替换一系列查找操作,例如。

PUTFH (directory filehandle) LOOKUP "pub" "foo" "bar" GETFH

PUTFH(目录文件句柄)查找“pub”“foo”“bar”GETFH

or, if the client wishes to obtain the intermediate filehandles

或者,如果客户端希望获得中间文件句柄

PUTFH (directory filehandle) LOOKUP "pub" GETFH LOOKUP "foo" GETFH LOOKUP "bar" GETFH

PUTFH(目录文件句柄)查找“pub”GETFH查找“foo”GETFH查找“bar”GETFH

NFS version 4 servers depart from the semantics of previous NFS versions in allowing LOOKUP requests to cross mountpoints on the server. The client can detect a mountpoint crossing by comparing the fsid attribute of the directory with the fsid attribute of the directory looked up. If the fsids are different then the new directory is a server mountpoint. Unix clients that detect a mountpoint crossing will need to mount the server's filesystem. This needs to be done to maintain the file object identity checking mechanisms common to Unix clients.

NFS版本4服务器允许查找请求跨服务器上的装入点,这与以前的NFS版本的语义不同。客户端可以通过比较目录的fsid属性和查找的目录的fsid属性来检测装入点交叉。如果FSID不同,则新目录是服务器装入点。检测到装载点交叉的Unix客户端需要装载服务器的文件系统。需要这样做才能维护Unix客户机通用的文件对象身份检查机制。

Servers that limit NFS access to "shares" or "exported" filesystems should provide a pseudo-filesystem into which the exported filesystems can be integrated, so that clients can browse the server's name space. The clients view of a pseudo filesystem will be limited to paths that lead to exported filesystems.

限制NFS访问“共享”或“导出”文件系统的服务器应该提供一个虚拟文件系统,导出的文件系统可以集成到其中,以便客户端可以浏览服务器的名称空间。伪文件系统的客户机视图将限于指向导出文件系统的路径。

Note: previous versions of the protocol assigned special semantics to the names "." and "..". NFS version 4 assigns no special semantics to these names. The LOOKUPP operator must be used to lookup a parent directory.

注:协议的早期版本为名称“.”和“.”指定了特殊语义。NFS版本4没有为这些名称分配特殊语义。LOOKUPP运算符必须用于查找父目录。

Note that this procedure does not follow symbolic links. The client is responsible for all parsing of filenames including filenames that are modified by symbolic links encountered during the lookup process.

请注意,此过程不遵循符号链接。客户端负责所有文件名的解析,包括由查找过程中遇到的符号链接修改的文件名。

If the current file handle supplied is not a directory but a symbolic link, the error NFS4ERR_SYMLINK is returned as the error. For all other non-directory file types, the error NFS4ERR_NOTDIR is returned.

如果提供的当前文件句柄不是目录而是符号链接,则返回错误NFS4ERR_SYMLINK作为错误。对于所有其他非目录文件类型,将返回错误NFS4ERR_NOTDIR。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_SYMLINK NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u BADDHANDLE NFS4ERR\u FH过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u名称工具NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u陈旧NFS4ERR\u符号链接NFS4ERR\u错误

14.2.14. Operation 16: LOOKUPP - Lookup Parent Directory
14.2.14. 操作16:LOOKUPP-查找父目录

SYNOPSIS

提要

(cfh) -> (cfh)

(cfh)->(cfh)

ARGUMENT

论点

      /* CURRENT_FH: object */
      void;
        
      /* CURRENT_FH: object */
      void;
        

RESULT

后果

      struct LOOKUPP4res {
              /* CURRENT_FH: directory */
              nfsstat4        status;
      };
        
      struct LOOKUPP4res {
              /* CURRENT_FH: directory */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

The current filehandle is assumed to refer to a regular directory or a named attribute directory. LOOKUPP assigns the filehandle for its parent directory to be the current filehandle. If there is no parent directory an NFS4ERR_ENOENT error must be returned. Therefore, NFS4ERR_ENOENT will be returned by the server when the current filehandle is at the root or top of the server's file tree.

假定当前文件句柄引用常规目录或命名属性目录。LOOKUPP将其父目录的文件句柄指定为当前文件句柄。如果没有父目录,则必须返回NFS4ERR_enoint错误。因此,当当前文件句柄位于服务器文件树的根或顶部时,服务器将返回NFS4ERR_enoint。

IMPLEMENTATION

实施

As for LOOKUP, LOOKUPP will also cross mountpoints.

至于查找,LOOKUPP还将跨装入点。

If the current filehandle is not a directory or named attribute directory, the error NFS4ERR_NOTDIR is returned.

如果当前文件句柄不是目录或命名属性目录,则返回错误NFS4ERR\u NOTDIR。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u访问NFS4ERR\u BADHANDLE NFS4ERR\u FH过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u资源NFS4ERR\u服务器故障

NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_过时NFS4ERR_错误秒

14.2.15. Operation 17: NVERIFY - Verify Difference in Attributes
14.2.15. 操作17:NVERIFY-验证属性差异

SYNOPSIS

提要

      (cfh), fattr -> -
        
      (cfh), fattr -> -
        

ARGUMENT

论点

      struct NVERIFY4args {
              /* CURRENT_FH: object */
              fattr4          obj_attributes;
      };
        
      struct NVERIFY4args {
              /* CURRENT_FH: object */
              fattr4          obj_attributes;
      };
        

RESULT

后果

      struct NVERIFY4res {
              nfsstat4        status;
      };
        
      struct NVERIFY4res {
              nfsstat4        status;
      };
        

DESCRIPTION

描述

This operation is used to prefix a sequence of operations to be performed if one or more attributes have changed on some filesystem object. If all the attributes match then the error NFS4ERR_SAME must be returned.

如果某个文件系统对象上的一个或多个属性已更改,则此操作用于为要执行的操作序列添加前缀。如果所有属性都匹配,则必须返回错误NFS4ERR_SAME。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

This operation is useful as a cache validation operator. If the object to which the attributes belong has changed then the following operations may obtain new data associated with that object. For instance, to check if a file has been changed and obtain new data if it has:

此操作作为缓存验证运算符很有用。如果属性所属的对象已更改,则以下操作可能会获取与该对象关联的新数据。例如,要检查文件是否已更改,如果已更改,则获取新数据,请执行以下操作:

PUTFH (public) LOOKUP "pub" "foo" "bar" NVERIFY attrbits attrs READ 0 32767

PUTFH(公共)查找“pub”“foo”“bar”NVERIFY属性位属性读取0 32767

In the case that a recommended attribute is specified in the NVERIFY operation and the server does not support that attribute for the file system object, the error NFS4ERR_NOTSUPP is returned to the client.

如果在NVERIFY操作中指定了推荐的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_NOTSUPP返回给客户端。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_SAME NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR\u相同NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误

14.2.16. Operation 18: OPEN - Open a Regular File
14.2.16. 操作18:打开-打开常规文件

SYNOPSIS

提要

(cfh), claim, openhow, owner, seqid, access, deny -> (cfh), stateid, cinfo, rflags, open_confirm, delegation

(cfh)、索赔、openhow、所有者、seqid、访问、拒绝->(cfh)、stateid、cinfo、rflags、开放式确认、委托

ARGUMENT

论点

  struct OPEN4args {
          open_claim4     claim;
          openflag4       openhow;
          nfs_lockowner4  owner;
          seqid4          seqid;
          uint32_t        share_access;
          uint32_t        share_deny;
  };
        
  struct OPEN4args {
          open_claim4     claim;
          openflag4       openhow;
          nfs_lockowner4  owner;
          seqid4          seqid;
          uint32_t        share_access;
          uint32_t        share_deny;
  };
        
  enum createmode4 {
          UNCHECKED4      = 0,
          GUARDED4        = 1,
          EXCLUSIVE4      = 2
  };
        
  enum createmode4 {
          UNCHECKED4      = 0,
          GUARDED4        = 1,
          EXCLUSIVE4      = 2
  };
        
  union createhow4 switch (createmode4 mode) {
   case UNCHECKED4:
   case GUARDED4:
           fattr4         createattrs;
   case EXCLUSIVE4:
           verifier4      createverf;
  };
        
  union createhow4 switch (createmode4 mode) {
   case UNCHECKED4:
   case GUARDED4:
           fattr4         createattrs;
   case EXCLUSIVE4:
           verifier4      createverf;
  };
        
  enum opentype4 {
          OPEN4_NOCREATE  = 0,
          OPEN4_CREATE    = 1
  };
        
  enum opentype4 {
          OPEN4_NOCREATE  = 0,
          OPEN4_CREATE    = 1
  };
        
  union openflag4 switch (opentype4 opentype) {
   case OPEN4_CREATE:
           createhow4     how;
   default:
           void;
  };
        
  union openflag4 switch (opentype4 opentype) {
   case OPEN4_CREATE:
           createhow4     how;
   default:
           void;
  };
        
  /* Next definitions used for OPEN delegation */
  enum limit_by4 {
          NFS_LIMIT_SIZE          = 1,
          NFS_LIMIT_BLOCKS        = 2
          /* others as needed */
  };
        
  /* Next definitions used for OPEN delegation */
  enum limit_by4 {
          NFS_LIMIT_SIZE          = 1,
          NFS_LIMIT_BLOCKS        = 2
          /* others as needed */
  };
        
  struct nfs_modified_limit4 {
          uint32_t        num_blocks;
          uint32_t        bytes_per_block;
  };
        
  struct nfs_modified_limit4 {
          uint32_t        num_blocks;
          uint32_t        bytes_per_block;
  };
        
  union nfs_space_limit4 switch (limit_by4 limitby) {
   /* limit specified as file size */
   case NFS_LIMIT_SIZE:
           uint64_t               filesize;
   /* limit specified by number of blocks */
   case NFS_LIMIT_BLOCKS:
           nfs_modified_limit4    mod_blocks;
  } ;
        
  union nfs_space_limit4 switch (limit_by4 limitby) {
   /* limit specified as file size */
   case NFS_LIMIT_SIZE:
           uint64_t               filesize;
   /* limit specified by number of blocks */
   case NFS_LIMIT_BLOCKS:
           nfs_modified_limit4    mod_blocks;
  } ;
        
  enum open_delegation_type4 {
          OPEN_DELEGATE_NONE      = 0,
          OPEN_DELEGATE_READ      = 1,
          OPEN_DELEGATE_WRITE     = 2
  };
        
  enum open_delegation_type4 {
          OPEN_DELEGATE_NONE      = 0,
          OPEN_DELEGATE_READ      = 1,
          OPEN_DELEGATE_WRITE     = 2
  };
        
  enum open_claim_type4 {
          CLAIM_NULL              = 0,
          CLAIM_PREVIOUS          = 1,
          CLAIM_DELEGATE_CUR      = 2,
          CLAIM_DELEGATE_PREV     = 3
  };
        
  enum open_claim_type4 {
          CLAIM_NULL              = 0,
          CLAIM_PREVIOUS          = 1,
          CLAIM_DELEGATE_CUR      = 2,
          CLAIM_DELEGATE_PREV     = 3
  };
        
  struct open_claim_delegate_cur4 {
          pathname4       file;
        
  struct open_claim_delegate_cur4 {
          pathname4       file;
        
          stateid4        delegate_stateid;
  };
        
          stateid4        delegate_stateid;
  };
        
  union open_claim4 switch (open_claim_type4 claim) {
   /*
    * No special rights to file. Ordinary OPEN of the specified file.
    */
   case CLAIM_NULL:
           /* CURRENT_FH: directory */
           pathname4      file;
        
  union open_claim4 switch (open_claim_type4 claim) {
   /*
    * No special rights to file. Ordinary OPEN of the specified file.
    */
   case CLAIM_NULL:
           /* CURRENT_FH: directory */
           pathname4      file;
        
   /*
    * Right to the file established by an open previous to server
    * reboot.  File identified by filehandle obtained at that time
    * rather than by name.
    */
   case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           uint32_t        delegate_type;
        
   /*
    * Right to the file established by an open previous to server
    * reboot.  File identified by filehandle obtained at that time
    * rather than by name.
    */
   case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           uint32_t        delegate_type;
        
   /*
    * Right to file based on a delegation granted by the server.
    * File is specified by name.
    */
   case CLAIM_DELEGATE_CUR:
           /* CURRENT_FH: directory */
           open_claim_delegate_cur4       delegate_cur_info;
        
   /*
    * Right to file based on a delegation granted by the server.
    * File is specified by name.
    */
   case CLAIM_DELEGATE_CUR:
           /* CURRENT_FH: directory */
           open_claim_delegate_cur4       delegate_cur_info;
        
   /* Right to file based on a delegation granted to a previous boot
    * instance of the client.  File is specified by name.
    */
   case CLAIM_DELEGATE_PREV:
           /* CURRENT_FH: directory */
           pathname4      file_delegate_prev;
  };
        
   /* Right to file based on a delegation granted to a previous boot
    * instance of the client.  File is specified by name.
    */
   case CLAIM_DELEGATE_PREV:
           /* CURRENT_FH: directory */
           pathname4      file_delegate_prev;
  };
        

RESULT

后果

  struct open_read_delegation4 {
          stateid4        stateid;        /* Stateid for delegation*/
          bool            recall;         /* Pre-recalled flag for
                                             delegations obtained
                                             by reclaim
                                             (CLAIM_PREVIOUS) */
          nfsace4         permissions;    /* Defines users who don't
                                             need an ACCESS call to
                                             open for read */
  };
        
  struct open_read_delegation4 {
          stateid4        stateid;        /* Stateid for delegation*/
          bool            recall;         /* Pre-recalled flag for
                                             delegations obtained
                                             by reclaim
                                             (CLAIM_PREVIOUS) */
          nfsace4         permissions;    /* Defines users who don't
                                             need an ACCESS call to
                                             open for read */
  };
        
  struct open_write_delegation4 {
          stateid4        stateid;        /* Stateid for delegation*/
          bool            recall;         /* Pre-recalled flag for
                                             delegations obtained
                                             by reclaim
                                             (CLAIM_PREVIOUS) */
          nfs_space_limit4 space_limit;   /* Defines condition that
                                             the client must check to
                                             determine whether the
                                             file needs to be flushed
                                             to the server on close.
                                             */
          nfsace4         permissions;    /* Defines users who don't
                                             need an ACCESS call as
                                             part of a delegated
                                             open. */
  };
        
  struct open_write_delegation4 {
          stateid4        stateid;        /* Stateid for delegation*/
          bool            recall;         /* Pre-recalled flag for
                                             delegations obtained
                                             by reclaim
                                             (CLAIM_PREVIOUS) */
          nfs_space_limit4 space_limit;   /* Defines condition that
                                             the client must check to
                                             determine whether the
                                             file needs to be flushed
                                             to the server on close.
                                             */
          nfsace4         permissions;    /* Defines users who don't
                                             need an ACCESS call as
                                             part of a delegated
                                             open. */
  };
        
  union open_delegation4
  switch (open_delegation_type4 delegation_type) {
          case OPEN_DELEGATE_NONE:
                  void;
          case OPEN_DELEGATE_READ:
                  open_read_delegation4 read;
          case OPEN_DELEGATE_WRITE:
                  open_write_delegation4 write;
  };
        
  union open_delegation4
  switch (open_delegation_type4 delegation_type) {
          case OPEN_DELEGATE_NONE:
                  void;
          case OPEN_DELEGATE_READ:
                  open_read_delegation4 read;
          case OPEN_DELEGATE_WRITE:
                  open_write_delegation4 write;
  };
        
  const OPEN4_RESULT_MLOCK        = 0x00000001;
  const OPEN4_RESULT_CONFIRM= 0x00000002;
        
  const OPEN4_RESULT_MLOCK        = 0x00000001;
  const OPEN4_RESULT_CONFIRM= 0x00000002;
        
  struct OPEN4resok {
          stateid4        stateid;        /* Stateid for open */
          change_info4    cinfo;          /* Directory Change Info */
          uint32_t        rflags;         /* Result flags */
          verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
          open_delegation4 delegation;    /* Info on any open
                                             delegation */
  };
        
  struct OPEN4resok {
          stateid4        stateid;        /* Stateid for open */
          change_info4    cinfo;          /* Directory Change Info */
          uint32_t        rflags;         /* Result flags */
          verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
          open_delegation4 delegation;    /* Info on any open
                                             delegation */
  };
        
  union OPEN4res switch (nfsstat4 status) {
   case NFS4_OK:
          /* CURRENT_FH: opened file */
          OPEN4resok      resok4;
   default:
          void;
  };
        
  union OPEN4res switch (nfsstat4 status) {
   case NFS4_OK:
          /* CURRENT_FH: opened file */
          OPEN4resok      resok4;
   default:
          void;
  };
        

WARNING TO CLIENT IMPLEMENTORS

对客户端实现者的警告

OPEN resembles LOOKUP in that it generates a filehandle for the client to use. Unlike LOOKUP though, OPEN creates server state on the filehandle. In normal circumstances, the client can only release this state with a CLOSE operation. CLOSE uses the current filehandle to determine which file to close. Therefore the client MUST follow every OPEN operation with a GETFH operation in the same COMPOUND procedure. This will supply the client with the filehandle such that CLOSE can be used appropriately.

OpenLookup类似于查找,它生成供客户端使用的文件句柄。但与查找不同,OPEN在文件句柄上创建服务器状态。在正常情况下,客户端只能通过关闭操作释放此状态。CLOSE使用当前文件句柄确定要关闭的文件。因此,客户机必须在同一复合过程中使用GETFH操作来跟踪每个打开的操作。这将为客户端提供文件句柄,以便可以适当地使用CLOSE。

Simply waiting for the lease on the file to expire is insufficient because the server may maintain the state indefinitely as long as another client does not attempt to make a conflicting access to the same file.

仅仅等待文件租约到期是不够的,因为只要另一个客户端不尝试对同一文件进行冲突访问,服务器就可以无限期地保持该状态。

DESCRIPTION

描述

The OPEN operation creates and/or opens a regular file in a directory with the provided name. If the file does not exist at the server and creation is desired, specification of the method of creation is provided by the openhow parameter. The client has the choice of three creation methods: UNCHECKED, GUARDED, or EXCLUSIVE.

“打开”操作使用提供的名称在目录中创建和/或打开常规文件。如果该文件在服务器上不存在并且需要创建,则openhow参数将提供创建方法的规范。客户端可以选择三种创建方法:未选中、保护或独占。

UNCHECKED means that the file should be created if a file of that name does not exist and encountering an existing regular file of that name is not an error. For this type of create, createattrs specifies the initial set of attributes for the file. The set of attributes may includes any writable attribute valid for regular files. When an UNCHECKED create encounters an existing file, the attributes specified by createattrs is not used, except that when an object_size of zero is specified, the existing file is truncated. If GUARDED is specified, the server checks for the presence of a duplicate object by name before performing the create. If a duplicate exists, an error of NFS4ERR_EXIST is returned as the status. If the object does not exist, the request is performed as described for UNCHECKED.

未选中表示如果该名称的文件不存在并且遇到该名称的现有常规文件不是错误,则应创建该文件。对于这种类型的创建,createattrs指定文件的初始属性集。属性集可以包括对常规文件有效的任何可写属性。当未选中的创建遇到现有文件时,将不使用createattrs指定的属性,除非指定的对象大小为零,否则现有文件将被截断。如果指定了GUARDED,服务器将在执行创建之前按名称检查是否存在重复对象。如果存在重复项,则返回NFS4ERR_EXIST错误作为状态。如果对象不存在,则按照未选中的说明执行请求。

EXCLUSIVE specifies that the server is to follow exclusive creation semantics, using the verifier to ensure exclusive creation of the target. The server should check for the presence of a duplicate object by name. If the object does not exist, the server creates the object and stores the verifier with the object. If the object does exist and the stored verifier matches the client provided verifier, the server uses the existing object as the newly created object. If the stored verifier does not match,

独占指定服务器遵循独占创建语义,使用验证器确保以独占方式创建目标。服务器应按名称检查是否存在重复的对象。如果对象不存在,服务器将创建该对象并将验证器与该对象一起存储。如果对象确实存在并且存储的验证器与客户端提供的验证器匹配,则服务器将现有对象用作新创建的对象。如果存储的验证器不匹配,

then an error of NFS4ERR_EXIST is returned. No attributes may be provided in this case, since the server may use an attribute of the target object to store the verifier.

然后返回NFS4ERR_EXIST错误。在这种情况下不能提供属性,因为服务器可以使用目标对象的属性来存储验证器。

For the target directory, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 struct, the server will indicate if the before and after change attributes were obtained atomically with respect to the link creation.

对于目标目录,服务器返回cinfo中的change_info4信息。使用change_info4结构的原子字段,服务器将指示是否以原子方式获得了与链接创建相关的更改前后属性。

Upon successful creation, the current filehandle is replaced by that of the new object.

成功创建后,当前文件句柄将替换为新对象的文件句柄。

The OPEN procedure provides for DOS SHARE capability with the use of the access and deny fields of the OPEN arguments. The client specifies at OPEN the required access and deny modes. For clients that do not directly support SHAREs (i.e. Unix), the expected deny value is DENY_NONE. In the case that there is a existing SHARE reservation that conflicts with the OPEN request, the server returns the error NFS4ERR_DENIED. For a complete SHARE request, the client must provide values for the owner and seqid fields for the OPEN argument. For additional discussion of SHARE semantics see the section on 'Share Reservations'.

OPEN过程通过使用OPEN参数的access和deny字段提供DOS共享功能。客户端在打开时指定所需的访问和拒绝模式。对于不直接支持共享(即Unix)的客户端,预期的拒绝值为deny_NONE。如果存在与打开请求冲突的现有共享保留,服务器将返回错误NFS4ERR_DENIED。对于完整的共享请求,客户端必须为OPEN参数提供owner和seqid字段的值。有关共享语义的更多讨论,请参阅“共享保留”部分。

In the case that the client is recovering state from a server failure, the reclaim field of the OPEN argument is used to signify that the request is meant to reclaim state previously held.

如果客户机正在从服务器故障中恢复状态,则OPEN参数的Reclaime字段用于表示该请求旨在恢复以前持有的状态。

The "claim" field of the OPEN argument is used to specify the file to be opened and the state information which the client claims to possess. There are four basic claim types which cover the various situations for an OPEN. They are as follows:

OPEN参数的“claim”字段用于指定要打开的文件以及客户端声称拥有的状态信息。有四种基本索赔类型,涵盖开放式索赔的各种情况。详情如下:

CLAIM_NULL For the client, this is a new OPEN request and there is no previous state associate with the file for the client.

声明对于客户端为NULL,这是一个新的打开请求,并且没有以前与客户端文件关联的状态。

CLAIM_PREVIOUS The client is claiming basic OPEN state for a file that was held previous to a server reboot. Generally used when a server is returning persistent file handles; the client may not have the file name to reclaim the OPEN.

CLAIM_PREVIOUS客户端正在声明在服务器重新启动之前保留的文件的基本打开状态。通常在服务器返回持久文件句柄时使用;客户端可能没有用于回收打开文件的文件名。

CLAIM_DELEGATE_CUR The client is claiming a delegation for OPEN as granted by the server. Generally this is done as part of recalling a delegation.

CLAIM_DELEGATE_CUR客户端正在请求服务器授予的开放委托。一般来说,这是召回代表团的一部分。

CLAIM_DELEGATE_PREV The client is claiming a delegation granted to a previous client instance; used after the client reboots.

CLAIM_DELEGATE_PREV客户端正在声明授予以前的客户端实例的委托;在客户端重新启动后使用。

For OPEN requests whose claim type is other than CLAIM_PREVIOUS (i.e. requests other than those devoted to reclaiming opens after a server reboot) that reach the server during its grace or lease expiration period, the server returns an error of NFS4ERR_GRACE.

对于声明类型不是claim_PREVIOUS(即服务器重新启动后用于回收打开的请求以外的请求)的打开请求,在其宽限期或租约到期期间到达服务器,服务器返回NFS4ERR_宽限期错误。

For any OPEN request, the server may return an open delegation, which allows further opens and closes to be handled locally on the client as described in the section Open Delegation. Note that delegation is up to the server to decide. The client should never assume that delegation will or will not be granted in a particular instance. It should always be prepared for either case. A partial exception is the reclaim (CLAIM_PREVIOUS) case, in which a delegation type is claimed. In this case, delegation will always be granted, although the server may specify an immediate recall in the delegation structure.

对于任何打开的请求,服务器可能会返回一个打开的委托,这允许在客户端上本地处理进一步的打开和关闭,如“打开委托”一节中所述。请注意,委派由服务器决定。客户不应假设在特定实例中会或不会授予委托。无论是哪种情况,都应该随时做好准备。部分例外情况是Reclain(CLAIM_PREVIOUS)案例,在该案例中声明了委托类型。在这种情况下,将始终授予委派,尽管服务器可以在委派结构中指定立即调用。

The rflags returned by a successful OPEN allow the server to return information governing how the open file is to be handled. OPEN4_RESULT_MLOCK indicates to the caller that mandatory locking is in effect for this file and the client should act appropriately with regard to data cached on the client. OPEN4_RESULT_CONFIRM indicates that the client MUST execute an OPEN_CONFIRM operation before using the open file.

成功打开所返回的RFLAG允许服务器返回控制如何处理打开的文件的信息。OPEN4_RESULT_MLOCK向调用者指示强制锁定对此文件有效,并且客户端应针对客户端上缓存的数据采取适当的行动。OPEN4_RESULT_CONFIRM表示客户端在使用打开的文件之前必须执行打开确认操作。

If the file is a zero length array, if any component does not obey the UTF-8 definition, or if any component in the path is of zero length, the error NFS4ERR_INVAL will be returned.

如果文件为零长度数组,如果任何组件不符合UTF-8定义,或者如果路径中的任何组件为零长度,则将返回错误NFS4ERR_INVAL。

When an OPEN is done and the specified lockowner already has the resulting filehandle open, the result is to "OR" together the new share and deny status together with the existing status. In this case, only a single CLOSE need be done, even though multiple OPEN's were completed.

当打开完成并且指定的lockowner已经打开了结果文件句柄时,结果是将新共享和拒绝状态与现有状态一起“或”。在这种情况下,只需完成一次关闭,即使完成了多个打开。

IMPLEMENTATION

实施

The OPEN procedure contains support for EXCLUSIVE create. The mechanism is similar to the support in NFS version 3 [RFC1813]. As in NFS version 3, this mechanism provides reliable exclusive creation. Exclusive create is invoked when the how parameter is EXCLUSIVE. In this case, the client provides a verifier that can reasonably be expected to be unique. A combination of a client identifier, perhaps the client network address, and a unique number generated by the client, perhaps the RPC transaction identifier, may be appropriate.

OPEN过程包含对独占创建的支持。该机制类似于NFS版本3[RFC1813]中的支持。与NFS版本3一样,此机制提供可靠的独占创建。当how参数为Exclusive时,将调用Exclusive create。在这种情况下,客户机提供了一个可以合理预期是唯一的验证器。客户端标识符(可能是客户端网络地址)和由客户端生成的唯一号码(可能是RPC事务标识符)的组合可能是合适的。

If the object does not exist, the server creates the object and stores the verifier in stable storage. For file systems that do not provide a mechanism for the storage of arbitrary file attributes, the server may use one or more elements of the object meta-data to store the verifier. The verifier must be stored in stable storage to prevent erroneous failure on retransmission of the request. It is assumed that an exclusive create is being performed because exclusive semantics are critical to the application. Because of the expected usage, exclusive CREATE does not rely solely on the normally volatile duplicate request cache for storage of the verifier. The duplicate request cache in volatile storage does not survive a crash and may actually flush on a long network partition, opening failure windows. In the UNIX local file system environment, the expected storage location for the verifier on creation is the meta-data (time stamps) of the object. For this reason, an exclusive object create may not include initial attributes because the server would have nowhere to store the verifier.

如果对象不存在,服务器将创建该对象并将验证器存储在稳定的存储器中。对于不提供用于存储任意文件属性的机制的文件系统,服务器可以使用对象元数据的一个或多个元素来存储验证器。验证器必须存储在稳定的存储器中,以防止请求重新传输时出现错误故障。假定正在执行独占创建,因为独占语义对应用程序至关重要。由于预期用途,exclusive CREATE不完全依赖通常易失性的复制请求缓存来存储验证器。易失性存储中的重复请求缓存在崩溃后无法生存,可能会在长网络分区上刷新,从而打开故障窗口。在UNIX本地文件系统环境中,创建时验证器的预期存储位置是对象的元数据(时间戳)。因此,独占对象创建可能不包括初始属性,因为服务器将无处存储验证器。

If the server can not support these exclusive create semantics, possibly because of the requirement to commit the verifier to stable storage, it should fail the OPEN request with the error, NFS4ERR_NOTSUPP.

如果服务器不能支持这些独占创建语义,可能是因为需要将验证器提交到稳定存储,那么它应该会导致打开请求失败,并出现错误NFS4ERR\u NOTSUPP。

During an exclusive CREATE request, if the object already exists, the server reconstructs the object's verifier and compares it with the verifier in the request. If they match, the server treats the request as a success. The request is presumed to be a duplicate of an earlier, successful request for which the reply was lost and that the server duplicate request cache mechanism did not detect. If the verifiers do not match, the request is rejected with the status, NFS4ERR_EXIST.

在独占创建请求期间,如果对象已经存在,服务器将重建对象的验证器,并将其与请求中的验证器进行比较。如果它们匹配,服务器会将请求视为成功。该请求被假定为先前成功请求的副本,该请求的答复已丢失,并且服务器重复请求缓存机制未检测到该请求。如果验证器不匹配,请求将被拒绝,状态为NFS4ERR_EXIST。

Once the client has performed a successful exclusive create, it must issue a SETATTR to set the correct object attributes. Until it does so, it should not rely upon any of the object attributes,

客户机成功执行独占创建后,必须发出SETATTR以设置正确的对象属性。在此之前,它不应依赖任何对象属性,

since the server implementation may need to overload object meta-data to store the verifier. The subsequent SETATTR must not occur in the same COMPOUND request as the OPEN. This separation will guarantee that the exclusive create mechanism will continue to function properly in the face of retransmission of the request.

因为服务器实现可能需要重载对象元数据来存储验证器。后续SETATTR不能与OPEN在同一复合请求中发生。这种分离将保证独占创建机制在重新传输请求时继续正常工作。

Use of the GUARDED attribute does not provide exactly-once semantics. In particular, if a reply is lost and the server does not detect the retransmission of the request, the procedure can fail with NFS4ERR_EXIST, even though the create was performed successfully.

使用GUARDED属性并不能提供精确的一次性语义。特别是,如果应答丢失且服务器未检测到请求的重新传输,则即使创建成功执行,该过程也可能因NFS4ERR_存在而失败。

For SHARE reservations, the client must specify a value for access that is one of READ, WRITE, or BOTH. For deny, the client must specify one of NONE, READ, WRITE, or BOTH. If the client fails to do this, the server must return NFS4ERR_INVAL.

对于共享保留,客户端必须为访问指定一个读、写或两者兼有的值。对于deny,客户端必须指定NONE、READ、WRITE或两者中的一个。如果客户端无法执行此操作,服务器必须返回NFS4ERR_INVAL。

If the final component provided to OPEN is a symbolic link, the error NFS4ERR_SYMLINK will be returned to the client. If an intermediate component of the pathname provided to OPEN is a symbolic link, the error NFS4ERR_NOTDIR will be returned to the client.

如果提供给OPEN的最后一个组件是符号链接,则错误NFS4ERR_SYMLINK将返回给客户端。如果提供给OPEN的路径名的中间组件是符号链接,则错误NFS4ERR_NOTDIR将返回给客户端。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BAD_SEQID NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_SHARE_DENIED NFS4ERR_STALE_CLIENTID NFS4ERR_SYMLINK

在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在美国,在_STALE_CLIENTIDNFS4ERR_符号链接

14.2.17. Operation 19: OPENATTR - Open Named Attribute Directory
14.2.17. 操作19:OPENATTR-打开命名属性目录

SYNOPSIS

提要

(cfh) -> (cfh)

(cfh)->(cfh)

ARGUMENT

论点

   /* CURRENT_FH: file or directory */
   void;
        
   /* CURRENT_FH: file or directory */
   void;
        

RESULT

后果

   struct OPENATTR4res {
           /* CURRENT_FH: name attr directory*/
           nfsstat4        status;
   };
        
   struct OPENATTR4res {
           /* CURRENT_FH: name attr directory*/
           nfsstat4        status;
   };
        

DESCRIPTION

描述

The OPENATTR operation is used to obtain the filehandle of the named attribute directory associated with the current filehandle. The result of the OPENATTR will be a filehandle to an object of type NF4ATTRDIR. From this filehandle, READDIR and LOOKUP procedures can be used to obtain filehandles for the various named attributes associated with the original file system object. Filehandles returned within the named attribute directory will have a type of NF4NAMEDATTR.

OPENATTR操作用于获取与当前文件句柄关联的命名属性目录的文件句柄。OPENATTR的结果将是NF4ATTRDIR类型对象的文件句柄。通过该文件句柄,可以使用READDIR和LOOKUP过程获取与原始文件系统对象关联的各种命名属性的文件句柄。在命名属性目录中返回的文件句柄的类型为NF4NAMEDATTR。

IMPLEMENTATION

实施

If the server does not support named attributes for the current filehandle, an error of NFS4ERR_NOTSUPP will be returned to the client.

如果服务器不支持当前文件句柄的命名属性,则会向客户端返回NFS4ERR_NOTSUPP错误。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_RESOURCE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无NFS4ERR\u文件句柄NFS4ERR\u不支持NFS4ERR\u资源

NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_错误秒

14.2.18. Operation 20: OPEN_CONFIRM - Confirm Open
14.2.18. 操作20:打开\确认-确认打开

SYNOPSIS

提要

(cfh), seqid, open_confirm-> stateid

(cfh),序列ID,打开\u确认->状态ID

ARGUMENT

论点

   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           seqid4          seqid;
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
   };
        
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           seqid4          seqid;
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
   };
        

RESULT

后果

   struct OPEN_CONFIRM4resok {
           stateid4        stateid;
   };
        
   struct OPEN_CONFIRM4resok {
           stateid4        stateid;
   };
        
   union OPEN_CONFIRM4res switch (nfsstat4 status) {
    case NFS4_OK:
            OPEN_CONFIRM4resok     resok4;
    default:
            void;
   };
        
   union OPEN_CONFIRM4res switch (nfsstat4 status) {
    case NFS4_OK:
            OPEN_CONFIRM4resok     resok4;
    default:
            void;
   };
        

DESCRIPTION

描述

This operation is used to confirm the sequence id usage for the first time that a nfs_lockowner is used by a client. The OPEN operation returns a opaque confirmation verifier that is then passed to this operation along with the next sequence id for the nfs_lockowner. The sequence id passed to the OPEN_CONFIRM must be 1 (one) greater than the seqid passed to the OPEN operation from which the open_confirm value was obtained. If the server receives an unexpected sequence id with respect to the original open, then the server assumes that the client will not confirm the original OPEN and all state associated with the original OPEN is released by the server.

此操作用于确认客户端第一次使用nfs_lockowner时序列id的使用情况。OPEN操作返回一个不透明的确认验证器,然后将该验证器与nfs_锁所有者的下一个序列id一起传递给此操作。传递给OPEN_确认的序列id必须比传递给OPEN操作(从中获得OPEN_确认值)的序列id大1(一)。如果服务器收到与原始打开相关的意外序列id,则服务器假定客户端不会确认原始打开,并且与原始打开相关的所有状态都由服务器释放。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

A given client might generate many nfs_lockowner data structures for a given clientid. The client will periodically either dispose of its nfs_lockowners or stop using them for indefinite periods of time. The latter situation is why the NFS version 4 protocol does not have a an explicit operation to exit an nfs_lockowner: such an operation is of no use in that situation. Instead, to avoid unbounded memory use, the server needs to implement a strategy for disposing of nfs_lockowners that have no current lock, open, or delegation state for any files and have not been used recently. The time period used to determine when to dispose of nfs_lockowners is an implementation choice. The time period should certainly be no less than the lease time plus any grace period the server wishes to implement beyond a lease time. The OPEN_CONFIRM operation allows the server to safely dispose of unused nfs_lockowner data structures.

给定的客户机可能会为给定的clientid生成许多nfs_lockowner数据结构。客户端将定期处置其nfs_锁所有者或无限期停止使用它们。后一种情况就是为什么NFS版本4协议没有明确的操作来退出NFS锁定所有者:这种操作在这种情况下没有用处。相反,为了避免无限制的内存使用,服务器需要实现一种策略,用于处理没有任何文件的当前锁定、打开或委派状态且最近未使用过的nfs_锁所有者。用于确定何时处置nfs_锁所有者的时间段是一个实现选择。时间段当然应该不小于租赁时间加上服务器希望在租赁时间之后实施的任何宽限期。OPEN_CONFIRM操作允许服务器安全地处置未使用的nfs_lockowner数据结构。

In the case that a client issues an OPEN operation and the server no longer has a record of the nfs_lockowner, the server needs ensure that this is a new OPEN and not a replay or retransmission.

如果客户端发出打开操作,而服务器不再具有nfs_lockowner的记录,则服务器需要确保这是一个新的打开,而不是重播或重新传输。

A lazy server implementation might require confirmation for every nfs_lockowner for which it has no record. However, this is not necessary until the server records the fact that it has disposed of one nfs_lockowner for the given clientid.

惰性服务器实现可能需要确认它没有记录的每个nfs_锁所有者。但是,在服务器记录它已经为给定的clientid处理了一个nfs_锁所有者之前,这是不必要的。

The server must hold unconfirmed OPEN state until one of three events occur. First, the client sends an OPEN_CONFIRM request with the appropriate sequence id and confirmation verifier within the lease period. In this case, the OPEN state on the server goes to confirmed, and the nfs_lockowner on the server is fully established.

服务器必须保持未确认的打开状态,直到发生三个事件之一。首先,客户机在租赁期内发送具有适当序列id和确认验证器的开放式确认请求。在这种情况下,服务器上的打开状态变为已确认,服务器上的nfs_lockowner已完全建立。

Second, the client sends another OPEN request with a sequence id that is incorrect for the nfs_lockowner (out of sequence). In this case, the server assumes the second OPEN request is valid and the first one is a replay. The server cancels the OPEN state of the first OPEN request, establishes an unconfirmed OPEN state for the second OPEN request, and responds to the second OPEN request with an indication that an OPEN_CONFIRM is needed. The process then repeats itself. While there is a potential for a denial of service attack on the client, it is mitigated if the client and server require the use of a security flavor based on Kerberos V5, LIPKEY, or some other flavor that uses cryptography.

其次,客户端发送另一个打开的请求,其序列id对于nfs_lockowner不正确(顺序错误)。在这种情况下,服务器假定第二个打开请求有效,第一个是重播。服务器取消第一个打开请求的打开状态,为第二个打开请求建立未确认的打开状态,并响应第二个打开请求,指示需要打开确认。然后这个过程会重复。虽然客户机上存在拒绝服务攻击的可能性,但如果客户机和服务器需要使用基于Kerberos V5、LIPKEY或其他使用加密技术的安全模式,则可以减轻这种攻击。

What if the server is in the unconfirmed OPEN state for a given nfs_lockowner, and it receives an operation on the nfs_lockowner that has a stateid but the operation is not OPEN, or it is OPEN_CONFIRM but with the wrong confirmation verifier? Then, even if the seqid is correct, the server returns NFS4ERR_BAD_STATEID, because the server assumes the operation is a replay: if the server has no established OPEN state, then there is no way, for example, a LOCK operation could be valid.

如果服务器对于给定的nfs_lockowner处于未确认的打开状态,并且它在nfs_lockowner上接收到具有stateid但操作未打开的操作,或者服务器处于打开状态但使用错误的确认验证器确认,该怎么办?然后,即使seqid是正确的,服务器也会返回NFS4ERR_BAD_STATEID,因为服务器假定该操作是一个重播:如果服务器没有建立的打开状态,那么就没有办法,例如,锁定操作可能是有效的。

Third, neither of the two aforementioned events occur for the nfs_lockowner within the lease period. In this case, the OPEN state is cancelled and disposal of the nfs_lockowner can occur.

第三,上述两个事件均未在租赁期内发生。在这种情况下,打开状态被取消,并且可以处理nfs_lockowner。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u baddHandle NFS4ERR\u BAD\u SEQID NFS4ERR\u过期NFS4ERR\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u移动NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误NFS4ERR\u

14.2.19. Operation 21: OPEN_DOWNGRADE - Reduce Open File Access
14.2.19. 操作21:打开降级-减少打开的文件访问

SYNOPSIS

提要

(cfh), stateid, seqid, access, deny -> stateid

(cfh),stateid,seqid,访问,拒绝->stateid

ARGUMENT

论点

   struct OPEN_DOWNGRADE4args {
           /* CURRENT_FH: opened file */
           stateid4        stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   struct OPEN_DOWNGRADE4args {
           /* CURRENT_FH: opened file */
           stateid4        stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        

RESULT

后果

   struct OPEN_DOWNGRADE4resok {
           stateid4        stateid;
   };
        
   struct OPEN_DOWNGRADE4resok {
           stateid4        stateid;
   };
        
   union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
    case NFS4_OK:
           OPEN_DOWNGRADE4resok    resok4;
    default:
           void;
   };
        
   union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
    case NFS4_OK:
           OPEN_DOWNGRADE4resok    resok4;
    default:
           void;
   };
        

This operation is used to adjust the access and deny bits for a given open. This is necessary when a given lockowner opens the same file multiple times with different access and deny flags. In this situation, a close of one of the open's may change the appropriate access and deny flags to remove bits associated with open's no longer in effect.

此操作用于调整给定open的访问和拒绝位。当给定的锁所有者使用不同的访问和拒绝标志多次打开同一文件时,这是必需的。在这种情况下,关闭一个open可能会更改相应的访问和拒绝标志,以删除与open不再有效相关的位。

The access and deny bits specified in this operation replace the current ones for the specified open file. If either the access or the deny mode specified includes bits not in effect for the open, the error NFS4ERR_INVAL should be returned. Since access and deny bits are subsets of those already granted, it is not possible for this request to be denied because of conflicting share reservations.

此操作中指定的访问和拒绝位将替换指定打开文件的当前位。如果指定的访问或拒绝模式包括对打开无效的位,则应返回错误NFS4ERR_INVAL。由于访问和拒绝位是已授予的访问和拒绝位的子集,因此不可能因为共享保留冲突而拒绝此请求。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u Sequid NFS4ERR\u BAD\u STATEID NFS4ERR\u过期NFS4ERR\u Fhs4Err\u无效NFS4ERR\u移动的NFS4ERR\u NOFILEHANDLE NFS4ERR\u旧的NFS4ERR\u STATEID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时的NFS4ERR\u过时的NFS4ERR\u STATEID

14.2.20. Operation 22: PUTFH - Set Current Filehandle
14.2.20. 操作22:PUTFH-设置当前文件句柄

SYNOPSIS

提要

filehandle -> (cfh)

文件句柄->(cfh)

ARGUMENT

论点

      struct PUTFH4args {
              nfs4_fh         object; };
        
      struct PUTFH4args {
              nfs4_fh         object; };
        

RESULT

后果

struct PUTFH4res {

结构PUTFH4res{

              /* CURRENT_FH: */
              nfsstat4        status; };
        
              /* CURRENT_FH: */
              nfsstat4        status; };
        

DESCRIPTION

描述

Replaces the current filehandle with the filehandle provided as an argument.

将当前文件句柄替换为作为参数提供的文件句柄。

IMPLEMENTATION

实施

Commonly used as the first operator in an NFS request to set the context for following operations.

通常用作NFS请求中的第一个运算符,用于设置以下操作的上下文。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u坏句柄NFS4ERR\u FH过期NFS4ERR\u移动NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误秒

14.2.21. Operation 23: PUTPUBFH - Set Public Filehandle
14.2.21. 操作23:PUTPUBFH-设置公共文件句柄

SYNOPSIS

提要

- -> (cfh)

- ->(cfh)

ARGUMENT

论点

void;

无效的

RESULT

后果

      struct PUTPUBFH4res {
              /* CURRENT_FH: public fh */
              nfsstat4        status;
      };
        
      struct PUTPUBFH4res {
              /* CURRENT_FH: public fh */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

Replaces the current filehandle with the filehandle that represents the public filehandle of the server's name space. This filehandle may be different from the "root" filehandle which may be associated with some other directory on the server.

将当前文件句柄替换为表示服务器名称空间的公共文件句柄的文件句柄。此文件句柄可能不同于“root”文件句柄,后者可能与服务器上的其他目录相关联。

IMPLEMENTATION

实施

Used as the first operator in an NFS request to set the context for following operations.

用作NFS请求中的第一个运算符,用于设置以下操作的上下文。

ERRORS

错误

NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_WRONGSEC

NFS4ERR_资源NFS4ERR_服务器故障NFS4ERR_错误秒

14.2.22. Operation 24: PUTROOTFH - Set Root Filehandle
14.2.22. 操作24:PUTROOTFH-设置根文件句柄

SYNOPSIS

提要

- -> (cfh)

- ->(cfh)

ARGUMENT

论点

void;

无效的

RESULT

后果

      struct PUTROOTFH4res {
              /* CURRENT_FH: root fh */
              nfsstat4        status;
      };
        
      struct PUTROOTFH4res {
              /* CURRENT_FH: root fh */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

Replaces the current filehandle with the filehandle that represents the root of the server's name space. From this filehandle a LOOKUP operation can locate any other filehandle on the server. This filehandle may be different from the "public" filehandle which may be associated with some other directory on the server.

将当前文件句柄替换为表示服务器名称空间根的文件句柄。通过此文件句柄,查找操作可以找到服务器上的任何其他文件句柄。此文件句柄可能不同于“public”文件句柄,后者可能与服务器上的其他目录相关联。

IMPLEMENTATION

实施

Commonly used as the first operator in an NFS request to set the context for following operations.

通常用作NFS请求中的第一个运算符,用于设置以下操作的上下文。

ERRORS

错误

NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_WRONGSEC

NFS4ERR_资源NFS4ERR_服务器故障NFS4ERR_错误秒

14.2.23. Operation 25: READ - Read from File
14.2.23. 操作25:读取-从文件读取

SYNOPSIS

提要

(cfh), offset, count, stateid -> eof, data

(cfh)、偏移量、计数、状态ID->eof、数据

ARGUMENT

论点

      struct READ4args {
              /* CURRENT_FH: file */
              stateid4        stateid;
              offset4         offset;
              count4          count;
      };
        
      struct READ4args {
              /* CURRENT_FH: file */
              stateid4        stateid;
              offset4         offset;
              count4          count;
      };
        

RESULT

后果

      struct READ4resok {
              bool            eof;
              opaque          data<>;
      };
        
      struct READ4resok {
              bool            eof;
              opaque          data<>;
      };
        
      union READ4res switch (nfsstat4 status) {
       case NFS4_OK:
               READ4resok     resok4;
       default:
               void;
      };
        
      union READ4res switch (nfsstat4 status) {
       case NFS4_OK:
               READ4resok     resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The READ operation reads data from the regular file identified by the current filehandle.

读取操作从由当前文件句柄标识的常规文件中读取数据。

The client provides an offset of where the READ is to start and a count of how many bytes are to be read. An offset of 0 (zero) means to read data starting at the beginning of the file. If offset is greater than or equal to the size of the file, the status, NFS4_OK, is returned with a data length set to 0 (zero) and eof is set to TRUE. The READ is subject to access permissions checking.

客户端提供读取开始位置的偏移量和读取字节数的计数。偏移量为0(零)表示从文件开头开始读取数据。如果偏移量大于或等于文件大小,则返回状态NFS4_OK,数据长度设置为0(零),eof设置为TRUE。读取受访问权限检查的约束。

If the client specifies a count value of 0 (zero), the READ succeeds and returns 0 (zero) bytes of data again subject to access permissions checking. The server may choose to return fewer bytes than specified by the client. The client needs to check for this condition and handle the condition appropriately.

如果客户端指定的计数值为0(零),则读取成功并返回0(零)字节的数据,再次进行访问权限检查。服务器可以选择返回的字节数少于客户端指定的字节数。客户需要检查该情况并适当处理该情况。

The stateid value for a READ request represents a value returned from a previous record lock or share reservation request. Used by the server to verify that the associated lock is still valid and to update lease timeouts for the client.

读取请求的stateid值表示从以前的记录锁定或共享保留请求返回的值。服务器用于验证关联的锁是否仍然有效,以及更新客户端的租约超时。

If the read ended at the end-of-file (formally, in a correctly formed READ request, if offset + count is equal to the size of the file), or the read request extends beyond the size of the file (if offset + count is greater than the size of the file), eof is returned as TRUE; otherwise it is FALSE. A successful READ of an empty file will always return eof as TRUE.

如果读取在文件末尾结束(正式地说,在格式正确的读取请求中,如果偏移量+计数等于文件的大小),或者读取请求超出了文件的大小(如果偏移量+计数大于文件的大小),则eof返回为TRUE;否则,这是错误的。成功读取空文件将始终将eof返回为TRUE。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

It is possible for the server to return fewer than count bytes of data. If the server returns less than the count requested and eof set to FALSE, the client should issue another READ to get the remaining data. A server may return less data than requested under several circumstances. The file may have been truncated by another client or perhaps on the server itself, changing the file size from what the requesting client believes to be the case. This would reduce the actual amount of data available to the client. It is possible that the server may back off the transfer size and reduce the read request return. Server resource exhaustion may also occur necessitating a smaller read return.

服务器返回的数据可能少于count字节。如果服务器返回的数据少于请求的计数,并且eof设置为FALSE,则客户端应发出另一次读取以获取剩余数据。在几种情况下,服务器返回的数据可能少于请求的数据。该文件可能已被另一个客户端或服务器本身截断,从而改变了请求客户端认为的文件大小。这将减少客户端可用的实际数据量。服务器可能会减少传输大小并减少读取请求返回。服务器资源耗尽也可能会导致较小的读取返回。

If the file is locked the server will return an NFS4ERR_LOCKED error. Since the lock may be of short duration, the client may choose to retransmit the READ request (with exponential backoff) until the operation succeeds.

如果文件被锁定,服务器将返回NFS4ERR\U锁定错误。由于锁的持续时间可能很短,因此客户端可以选择重新传输读取请求(使用指数退避),直到操作成功。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_LOCKED NFS4ERR_LEASE_MOVED NFS4ERR_MOVED

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏态ID NFS4ERR\u延迟NFS4ERR\u拒绝NFS4ERR\u过期NFS4ERR\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u锁定NFS4ERR\u租赁NFS4ERR\u移动NFS4ERR\u

NFS4ERR_NOFILEHANDLE NFS4ERR_NXIO NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID NFS4ERR_WRONGSEC

NFS4ERR\u NOFILEHANDLE NFS4ERR\u NXIO NFS4ERR\u OLD\u STATEID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u STALE NFS4ERR\u STATEID NFS4ERR\u错误秒

14.2.24. Operation 26: READDIR - Read Directory
14.2.24. 操作26:READDIR-读取目录

SYNOPSIS

提要

      (cfh), cookie, cookieverf, dircount, maxcount, attrbits ->
      cookieverf { cookie, filename, attrbits, attributes }
        
      (cfh), cookie, cookieverf, dircount, maxcount, attrbits ->
      cookieverf { cookie, filename, attrbits, attributes }
        

ARGUMENT

论点

      struct READDIR4args {
              /* CURRENT_FH: directory */
              nfs_cookie4     cookie;
              verifier4       cookieverf;
              count4          dircount;
              count4          maxcount;
              bitmap4         attr_request;
      };
        
      struct READDIR4args {
              /* CURRENT_FH: directory */
              nfs_cookie4     cookie;
              verifier4       cookieverf;
              count4          dircount;
              count4          maxcount;
              bitmap4         attr_request;
      };
        

RESULT

后果

      struct entry4 {
              nfs_cookie4     cookie;
              component4      name;
              fattr4          attrs;
              entry4          *nextentry;
      };
        
      struct entry4 {
              nfs_cookie4     cookie;
              component4      name;
              fattr4          attrs;
              entry4          *nextentry;
      };
        
      struct dirlist4 {
              entry4          *entries;
              bool            eof;
      };
        
      struct dirlist4 {
              entry4          *entries;
              bool            eof;
      };
        
      struct READDIR4resok {
              verifier4       cookieverf;
              dirlist4        reply;
      };
        
      struct READDIR4resok {
              verifier4       cookieverf;
              dirlist4        reply;
      };
        

union READDIR4res switch (nfsstat4 status) {

union READDIR4res开关(nfsstat4状态){

       case NFS4_OK:
               READDIR4resok  resok4;
       default:
               void;
      };
        
       case NFS4_OK:
               READDIR4resok  resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The READDIR operation retrieves a variable number of entries from a file system directory and returns client requested attributes for each entry along with information to allow the client to request additional directory entries in a subsequent READDIR.

READDIR操作从文件系统目录中检索数量可变的条目,并为每个条目返回客户端请求的属性以及允许客户端在后续READDIR中请求其他目录条目的信息。

The arguments contain a cookie value that represents where the READDIR should start within the directory. A value of 0 (zero) for the cookie is used to start reading at the beginning of the directory. For subsequent READDIR requests, the client specifies a cookie value that is provided by the server on a previous READDIR request.

这些参数包含一个cookie值,该值表示READDIR在目录中的起始位置。cookie的值0(零)用于开始读取目录的开头。对于后续的READDIR请求,客户端指定服务器在前一个READDIR请求中提供的cookie值。

The cookieverf value should be set to 0 (zero) when the cookie value is 0 (zero) (first directory read). On subsequent requests, it should be a cookieverf as returned by the server. The cookieverf must match that returned by the READDIR in which the cookie was acquired.

当cookie值为0(零)(第一次读取目录)时,cookieverf值应设置为0(零)。在后续请求中,它应该是服务器返回的cookieverf。cookieverf必须与获取cookie的READDIR返回的值匹配。

The dircount portion of the argument is a hint of the maximum number of bytes of directory information that should be returned. This value represents the length of the names of the directory entries and the cookie value for these entries. This length represents the XDR encoding of the data (names and cookies) and not the length in the native format of the server. The server may return less data.

参数的dircount部分是应该返回的目录信息的最大字节数的提示。此值表示目录项名称的长度以及这些项的cookie值。此长度表示数据(名称和cookie)的XDR编码,而不是服务器本机格式的长度。服务器可能返回较少的数据。

The maxcount value of the argument is the maximum number of bytes for the result. This maximum size represents all of the data being returned and includes the XDR overhead. The server may return less data. If the server is unable to return a single directory entry within the maxcount limit, the error NFS4ERR_READDIR_NOSPC will be returned to the client.

参数的maxcount值是结果的最大字节数。此最大大小表示返回的所有数据,并包括XDR开销。服务器可能返回较少的数据。如果服务器无法返回maxcount限制内的单个目录项,则会将错误NFS4ERR_READDIR_NOSPC返回给客户端。

Finally, attrbits represents the list of attributes to be returned for each directory entry supplied by the server.

最后,attrbits表示要为服务器提供的每个目录项返回的属性列表。

On successful return, the server's response will provide a list of directory entries. Each of these entries contains the name of the directory entry, a cookie value for that entry, and the associated attributes as requested.

成功返回后,服务器的响应将提供目录项列表。每个条目都包含目录条目的名称、该条目的cookie值以及请求的相关属性。

The cookie value is only meaningful to the server and is used as a "bookmark" for the directory entry. As mentioned, this cookie is used by the client for subsequent READDIR operations so that it may continue reading a directory. The cookie is similar in concept to a READ offset but should not be interpreted as such by the client. Ideally, the cookie value should not change if the directory is modified since the client may be caching these values.

cookie值仅对服务器有意义,并用作目录项的“书签”。如前所述,客户端将此cookie用于后续的READDIR操作,以便它可以继续读取目录。cookie在概念上类似于读取偏移量,但客户端不应将其解释为读取偏移量。理想情况下,如果目录被修改,cookie值不应该改变,因为客户端可能正在缓存这些值。

In some cases, the server may encounter an error while obtaining the attributes for a directory entry. Instead of returning an error for the entire READDIR operation, the server can instead return the attribute 'fattr4_rdattr_error'. With this, the server is able to communicate the failure to the client and not fail the entire operation in the instance of what might be a transient failure. Obviously, the client must request the fattr4_rdattr_error attribute for this method to work properly. If the client does not request the attribute, the server has no choice but to return failure for the entire READDIR operation.

在某些情况下,服务器在获取目录项的属性时可能会遇到错误。服务器可以返回属性“fattr4\u rdattr\u error”,而不是返回整个READDIR操作的错误。这样,服务器就能够将故障告知客户机,而不会在可能是暂时故障的情况下使整个操作失败。显然,客户端必须请求fattr4_rdattr_error属性才能使此方法正常工作。如果客户端不请求该属性,服务器别无选择,只能返回整个READDIR操作的失败。

For some file system environments, the directory entries "." and ".." have special meaning and in other environments, they may not. If the server supports these special entries within a directory, they should not be returned to the client as part of the READDIR response. To enable some client environments, the cookie values of 0, 1, and 2 are to be considered reserved. Note that the Unix client will use these values when combining the server's response and local representations to enable a fully formed Unix directory presentation to the application.

对于某些文件系统环境,目录项“.”和“.”具有特殊含义,而在其他环境中,它们可能没有特殊含义。如果服务器支持目录中的这些特殊条目,则不应将它们作为READDIR响应的一部分返回给客户端。要启用某些客户端环境,cookie值0、1和2将被视为保留。请注意,Unix客户端将在组合服务器的响应和本地表示时使用这些值,以便为应用程序启用完全格式的Unix目录表示。

For READDIR arguments, cookie values of 1 and 2 should not be used and for READDIR results cookie values of 0, 1, and 2 should not returned.

对于READDIR参数,不应使用cookie值1和2,对于READDIR结果,不应返回cookie值0、1和2。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The server's file system directory representations can differ greatly. A client's programming interfaces may also be bound to the local operating environment in a way that does not translate well into the NFS protocol. Therefore the use of the dircount and maxcount fields are provided to allow the client the ability to provide guidelines to the server. If the client is aggressive about attribute collection during a READDIR, the server has an idea of how to limit the encoded response. The dircount field provides a hint on the number of entries based solely on the names of the directory entries. Since it is a hint, it may be possible

服务器的文件系统目录表示形式可能会有很大差异。客户端的编程接口也可能以无法很好地转换为NFS协议的方式绑定到本地操作环境。因此,提供了dircount和maxcount字段的使用,以允许客户端向服务器提供指导。如果客户机在READDIR过程中对属性收集非常积极,那么服务器就知道如何限制编码响应。dircount字段仅根据目录项的名称提供有关项数的提示。因为这是一个暗示,所以这是可能的

that a dircount value is zero. In this case, the server is free to ignore the dircount value and return directory information based on the specified maxcount value.

一个dircount值是零。在这种情况下,服务器可以忽略dircount值,并根据指定的maxcount值返回目录信息。

The cookieverf may be used by the server to help manage cookie values that may become stale. It should be a rare occurrence that a server is unable to continue properly reading a directory with the provided cookie/cookieverf pair. The server should make every effort to avoid this condition since the application at the client may not be able to properly handle this type of failure.

服务器可以使用cookieverf来帮助管理可能过时的cookie值。服务器无法使用提供的cookie/cookieverf对继续正确读取目录的情况应该很少发生。服务器应尽一切努力避免这种情况,因为客户端的应用程序可能无法正确处理此类故障。

The use of the cookieverf will also protect the client from using READDIR cookie values that may be stale. For example, if the file system has been migrated, the server may or may not be able to use the same cookie values to service READDIR as the previous server used. With the client providing the cookieverf, the server is able to provide the appropriate response to the client. This prevents the case where the server may accept a cookie value but the underlying directory has changed and the response is invalid from the client's context of its previous READDIR.

cookieverf的使用还将保护客户端不使用可能过时的READDIR cookie值。例如,如果文件系统已迁移,则服务器可能无法使用与先前使用的服务器相同的cookie值为READDIR提供服务。通过客户机提供cookieverf,服务器能够向客户机提供适当的响应。这可以防止服务器可能接受cookie值,但基础目录已更改,并且响应在其先前READDIR的客户端上下文中无效的情况。

Since some servers will not be returning "." and ".." entries as has been done with previous versions of the NFS protocol, the client that requires these entries be present in READDIR responses must fabricate them.

由于某些服务器不会像以前版本的NFS协议那样返回“.”和“.”条目,因此要求这些条目出现在READDIR响应中的客户端必须创建它们。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_COOKIE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_NOTSUPP NFS4ERR_READDIR_NOSPC NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_TOOSMALL NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u COOKIE NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动的NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u NotSupport NFS4ERR\u READDIR\u NOSPC NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u Staler\u小错误

14.2.25. Operation 27: READLINK - Read Symbolic Link
14.2.25. 操作27:读取链接-读取符号链接

SYNOPSIS

提要

(cfh) -> linktext

(cfh)->链接文本

ARGUMENT

论点

      /* CURRENT_FH: symlink */
      void;
        
      /* CURRENT_FH: symlink */
      void;
        

RESULT

后果

      struct READLINK4resok {
              linktext4       link;
      };
        
      struct READLINK4resok {
              linktext4       link;
      };
        
      union READLINK4res switch (nfsstat4 status) {
       case NFS4_OK:
               READLINK4resok resok4;
       default:
               void;
      };
        
      union READLINK4res switch (nfsstat4 status) {
       case NFS4_OK:
               READLINK4resok resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

READLINK reads the data associated with a symbolic link. The data is a UTF-8 string that is opaque to the server. That is, whether created by an NFS client or created locally on the server, the data in a symbolic link is not interpreted when created, but is simply stored.

READLINK读取与符号链接关联的数据。数据是对服务器不透明的UTF-8字符串。也就是说,无论是由NFS客户端创建的还是在服务器上本地创建的,符号链接中的数据在创建时都不会被解释,而是简单地存储起来。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

A symbolic link is nominally a pointer to another file. The data is not necessarily interpreted by the server, just stored in the file. It is possible for a client implementation to store a path name that is not meaningful to the server operating system in a symbolic link. A READLINK operation returns the data to the client for interpretation. If different implementations want to share access to symbolic links, then they must agree on the interpretation of the data in the symbolic link.

符号链接名义上是指向另一个文件的指针。数据不一定由服务器解释,只是存储在文件中。客户端实现可以将对服务器操作系统没有意义的路径名存储在符号链接中。READLINK操作将数据返回给客户端进行解释。如果不同的实现想要共享对符号链接的访问,那么它们必须就符号链接中数据的解释达成一致。

The READLINK operation is only allowed on objects of type NF4LNK. The server should return the error, NFS4ERR_INVAL, if the object is not of type, NF4LNK.

仅允许对NF4LNK类型的对象执行READLINK操作。如果对象不是NF4LNK类型,服务器应返回错误NFS4ERR_INVAL。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误

14.2.26. Operation 28: REMOVE - Remove Filesystem Object
14.2.26. 操作28:删除-删除文件系统对象

SYNOPSIS

提要

(cfh), filename -> change_info

(cfh),文件名->更改信息

ARGUMENT

论点

      struct REMOVE4args {
              /* CURRENT_FH: directory */
              component4       target;
      };
        
      struct REMOVE4args {
              /* CURRENT_FH: directory */
              component4       target;
      };
        

RESULT

后果

      struct REMOVE4resok {
              change_info4    cinfo;
      }
        
      struct REMOVE4resok {
              change_info4    cinfo;
      }
        
      union REMOVE4res switch (nfsstat4 status) {
       case NFS4_OK:
               REMOVE4resok   resok4;
       default:
               void;
      }
        
      union REMOVE4res switch (nfsstat4 status) {
       case NFS4_OK:
               REMOVE4resok   resok4;
       default:
               void;
      }
        

DESCRIPTION

描述

The REMOVE operation removes (deletes) a directory entry named by filename from the directory corresponding to the current filehandle. If the entry in the directory was the last reference

移除操作从与当前文件句柄对应的目录中移除(删除)以文件名命名的目录项。如果目录中的条目是最后一个引用

to the corresponding file system object, the object may be destroyed.

对于相应的文件系统对象,该对象可能会被销毁。

For the directory where the filename was removed, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 struct, the server will indicate if the before and after change attributes were obtained atomically with respect to the removal.

对于删除文件名的目录,服务器返回cinfo中的change_info4信息。使用change_info4结构的原子字段,服务器将指示是否以原子方式获得了与删除相关的更改前后属性。

If the target has a length of 0 (zero), or if target does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果目标的长度为0(零),或者如果目标不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

NFS versions 2 and 3 required a different operator RMDIR for directory removal. NFS version 4 REMOVE can be used to delete any directory entry independent of its file type.

NFS版本2和3需要不同的运算符RMDIR来删除目录。NFS版本4 REMOVE可用于删除任何与其文件类型无关的目录项。

The concept of last reference is server specific. However, if the numlinks field in the previous attributes of the object had the value 1, the client should not rely on referring to the object via a file handle. Likewise, the client should not rely on the resources (disk space, directory entry, and so on) formerly associated with the object becoming immediately available. Thus, if a client needs to be able to continue to access a file after using REMOVE to remove it, the client should take steps to make sure that the file will still be accessible. The usual mechanism used is to RENAME the file from its old name to a new hidden name.

最后一个引用的概念是特定于服务器的。但是,如果对象先前属性中的numlinks字段的值为1,则客户端不应依赖于通过文件句柄引用对象。同样,客户机也不应该依赖于以前与对象关联的资源(磁盘空间、目录项等)立即可用。因此,如果客户机在使用REMOVE删除文件后需要能够继续访问该文件,则客户机应采取步骤确保该文件仍然可以访问。通常使用的机制是将文件从旧名称重命名为新的隐藏名称。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_NOTEMPTY NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u IO NFS4ERR\u将NFS4ERR\u名称工具移动到NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u NOTEMPTY NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR\u ROFS NFS4ERR\u服务器故障

NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_过时NFS4ERR_错误秒

14.2.27. Operation 29: RENAME - Rename Directory Entry
14.2.27. 操作29:重命名-重命名目录项

SYNOPSIS

提要

(sfh), oldname (cfh), newname -> source_change_info, target_change_info

(sfh)、旧名称(cfh)、新名称->源更改信息、目标更改信息

ARGUMENT

论点

      struct RENAME4args {
              /* SAVED_FH: source directory */
              component4      oldname;
              /* CURRENT_FH: target directory */
              component4      newname;
      };
        
      struct RENAME4args {
              /* SAVED_FH: source directory */
              component4      oldname;
              /* CURRENT_FH: target directory */
              component4      newname;
      };
        

RESULT

后果

      struct RENAME4resok {
              change_info4    source_cinfo;
              change_info4    target_cinfo;
      };
        
      struct RENAME4resok {
              change_info4    source_cinfo;
              change_info4    target_cinfo;
      };
        
      union RENAME4res switch (nfsstat4 status) {
       case NFS4_OK:
               RENAME4resok   resok4;
       default:
               void;
      };
        
      union RENAME4res switch (nfsstat4 status) {
       case NFS4_OK:
               RENAME4resok   resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The RENAME operation renames the object identified by oldname in the source directory corresponding to the saved filehandle, as set by the SAVEFH operation, to newname in the target directory corresponding to the current filehandle. The operation is required to be atomic to the client. Source and target directories must reside on the same file system on the server. On success, the current filehandle will continue to be the target directory.

重命名操作将SAVEFH操作设置的与保存的文件句柄相对应的源目录中由oldname标识的对象重命名为与当前文件句柄相对应的目标目录中的newname。该操作对于客户端来说必须是原子的。源目录和目标目录必须位于服务器上的同一文件系统上。成功后,当前文件句柄将继续作为目标目录。

If the target directory already contains an entry with the name, newname, the source object must be compatible with the target: either both are non-directories or both are directories and the target must be empty. If compatible, the existing target is

如果目标目录已包含名为newname的条目,则源对象必须与目标兼容:要么都是非目录,要么都是目录,目标必须为空。如果兼容,则现有目标是

removed before the rename occurs. If they are not compatible or if the target is a directory but not empty, the server will return the error, NFS4ERR_EXIST.

在重命名之前删除。如果它们不兼容,或者如果目标是目录但不是空的,服务器将返回错误NFS4ERR_EXIST。

If oldname and newname both refer to the same file (they might be hard links of each other), then RENAME should perform no action and return success.

如果oldname和newname都引用同一个文件(它们可能是彼此的硬链接),则RENAME不应执行任何操作并返回success。

For both directories involved in the RENAME, the server returns change_info4 information. With the atomic field of the change_info4 struct, the server will indicate if the before and after change attributes were obtained atomically with respect to the rename.

对于重命名中涉及的两个目录,服务器返回change_info4信息。使用change_info4结构的原子字段,服务器将指示是否以原子方式获得了与重命名相关的更改前后属性。

If the oldname or newname has a length of 0 (zero), or if oldname or newname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果oldname或newname的长度为0(零),或者oldname或newname不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

IMPLEMENTATION

实施

The RENAME operation must be atomic to the client. The statement "source and target directories must reside on the same file system on the server" means that the fsid fields in the attributes for the directories are the same. If they reside on different file systems, the error, NFS4ERR_XDEV, is returned.

重命名操作必须是客户端的原子操作。语句“源目录和目标目录必须位于服务器上的同一文件系统”表示目录属性中的fsid字段相同。如果它们驻留在不同的文件系统上,则返回错误NFS4ERR_XDEV。

A filehandle may or may not become stale or expire on a rename. However, server implementors are strongly encouraged to attempt to keep file handles from becoming stale or expiring in this fashion.

文件句柄可能会过时,也可能不会因重命名而过期。但是,强烈建议服务器实现人员尝试保持文件句柄不以这种方式过时或过期。

On some servers, the filenames, "." and "..", are illegal as either oldname or newname. In addition, neither oldname nor newname can be an alias for the source directory. These servers will return the error, NFS4ERR_INVAL, in these cases.

在某些服务器上,文件名“.”和“.”作为oldname或newname是非法的。此外,oldname和newname都不能作为源目录的别名。在这些情况下,这些服务器将返回错误NFS4ERR_INVAL。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_MOVED NFS4ERR_NAMETOOLONG

NFS4ERR访问NFS4ERR错误处理NFS4ERR延迟NFS4ERR存在NFS4ERR过期NFS4ERR无效NFS4ERR IO NFS4ERR是移动的NFS4ERR

NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTEMPTY NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC NFS4ERR_XDEV

NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOSPC NFS4ERR\u NOTDIR NFS4ERR\u NOTEMPTY NFS4ERR\u NOTSUPP NFS4ERR\u资源NFS4ERR\u ROFS NFS4ERR\u服务器故障NFS4ERR\u陈旧NFS4ERR\u错误安全NFS4ERR\u XDEV

14.2.28. Operation 30: RENEW - Renew a Lease
14.2.28. 操作30:续订-续订租约

SYNOPSIS

提要

stateid -> ()

stateid->()

ARGUMENT

论点

      struct RENEW4args {
              stateid4        stateid;
      };
        
      struct RENEW4args {
              stateid4        stateid;
      };
        

RESULT

后果

      struct RENEW4res {
              nfsstat4        status;
      };
        
      struct RENEW4res {
              nfsstat4        status;
      };
        

DESCRIPTION

描述

The RENEW operation is used by the client to renew leases which it currently holds at a server. In processing the RENEW request, the server renews all leases associated with the client. The associated leases are determined by the client id provided via the SETCLIENTID procedure.

续订操作由客户端用于续订其当前在服务器上持有的租约。在处理续订请求时,服务器续订与客户端关联的所有租约。关联的租约由通过SETCLIENTID过程提供的客户端id确定。

The stateid for RENEW may not be one of the special stateids consisting of all bits 0 (zero) or all bits 1.

RENEW的stateid不能是由所有位0(零)或所有位1组成的特殊stateid之一。

IMPLEMENTATION

实施

ERRORS

错误

NFS4ERR_BAD_STATEID NFS4ERR_EXPIRED

NFS4ERR\u错误\u状态ID NFS4ERR\u已过期

NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_STATEID NFS4ERR_WRONGSEC

NFS4ERR\u GRACE NFS4ERR\u INVAL NFS4ERR\u LEASE\u MOVED NFS4ERR\u OLD\u STATEID NFS4ERR\u RESOURCE NFS4ERR\u SERVERFAULT NFS4ERR\u STALE\u STATEID NFS4ERR\u Errorsec

14.2.29. Operation 31: RESTOREFH - Restore Saved Filehandle
14.2.29. 操作31:RESTOREFH-还原保存的文件句柄

SYNOPSIS

提要

(sfh) -> (cfh)

(sfh)->(cfh)

ARGUMENT

论点

      /* SAVED_FH: */
      void;
        
      /* SAVED_FH: */
      void;
        

RESULT

后果

      struct RESTOREFH4res {
              /* CURRENT_FH: value of saved fh */
              nfsstat4        status;
      };
        
      struct RESTOREFH4res {
              /* CURRENT_FH: value of saved fh */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

Set the current filehandle to the value in the saved filehandle. If there is no saved filehandle then return an error NFS4ERR_NOFILEHANDLE.

将当前文件句柄设置为保存的文件句柄中的值。如果没有保存的文件句柄,则返回错误NFS4ERR_NOFILEHANDLE。

IMPLEMENTATION

实施

Operations like OPEN and LOOKUP use the current filehandle to represent a directory and replace it with a new filehandle. Assuming the previous filehandle was saved with a SAVEFH operator, the previous filehandle can be restored as the current filehandle. This is commonly used to obtain post-operation attributes for the directory, e.g.

像OPEN和LOOKUP这样的操作使用当前文件句柄来表示目录,并用新的文件句柄替换它。假设上一个filehandle是使用SAVEFH运算符保存的,则可以将上一个filehandle还原为当前filehandle。这通常用于获取目录的操作后属性,例如。

PUTFH (directory filehandle) SAVEFH GETATTR attrbits (pre-op dir attrs) CREATE optbits "foo" attrs GETATTR attrbits (file attributes)

PUTFH(目录文件句柄)SAVEFH GETATTR attrbits(预操作目录attrs)创建optbits“foo”attrs GETATTR attrbits(文件属性)

RESTOREFH GETATTR attrbits (post-op dir attrs)

RESTOREFH GETATTR属性位(操作后目录属性)

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u坏句柄NFS4ERR\u过期NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误秒

14.2.30. Operation 32: SAVEFH - Save Current Filehandle
14.2.30. 操作32:SAVEFH-保存当前文件句柄

SYNOPSIS

提要

(cfh) -> (sfh)

(cfh)->(sfh)

ARGUMENT

论点

      /* CURRENT_FH: */
      void;
        
      /* CURRENT_FH: */
      void;
        

RESULT

后果

      struct SAVEFH4res {
              /* SAVED_FH: value of current fh */
              nfsstat4        status;
      };
        
      struct SAVEFH4res {
              /* SAVED_FH: value of current fh */
              nfsstat4        status;
      };
        

DESCRIPTION

描述

Save the current filehandle. If a previous filehandle was saved then it is no longer accessible. The saved filehandle can be restored as the current filehandle with the RESTOREFH operator.

保存当前文件句柄。如果保存了以前的文件句柄,则无法再访问它。使用RESTOREFH操作符可以将保存的文件句柄还原为当前文件句柄。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE

NFS4ERR_坏句柄NFS4ERR_FH过期NFS4ERR_移动NFS4ERR_NOFILEHANDLE

NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_资源NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_错误秒

14.2.31. Operation 33: SECINFO - Obtain Available Security
14.2.31. 操作33:SECINFO-获取可用的安全性

SYNOPSIS

提要

      (cfh), name -> { secinfo }
        
      (cfh), name -> { secinfo }
        

ARGUMENT

论点

      struct SECINFO4args {
              /* CURRENT_FH: */
              component4     name;
      };
        
      struct SECINFO4args {
              /* CURRENT_FH: */
              component4     name;
      };
        

RESULT

后果

      enum rpc_gss_svc_t {
              RPC_GSS_SVC_NONE        = 1,
              RPC_GSS_SVC_INTEGRITY   = 2,
              RPC_GSS_SVC_PRIVACY     = 3
      };
        
      enum rpc_gss_svc_t {
              RPC_GSS_SVC_NONE        = 1,
              RPC_GSS_SVC_INTEGRITY   = 2,
              RPC_GSS_SVC_PRIVACY     = 3
      };
        
      struct rpcsec_gss_info {
              sec_oid4        oid;
              qop4            qop;
              rpc_gss_svc_t   service;
      };
        
      struct rpcsec_gss_info {
              sec_oid4        oid;
              qop4            qop;
              rpc_gss_svc_t   service;
      };
        
      struct secinfo4 {
              uint32_t flavor;
              opaque flavor_info<>;   /* null for AUTH_SYS, AUTH_NONE;
                                         contains rpcsec_gss_info for
                                         RPCSEC_GSS. */
      };
        
      struct secinfo4 {
              uint32_t flavor;
              opaque flavor_info<>;   /* null for AUTH_SYS, AUTH_NONE;
                                         contains rpcsec_gss_info for
                                         RPCSEC_GSS. */
      };
        
      typedef secinfo4 SECINFO4resok<>;
        
      typedef secinfo4 SECINFO4resok<>;
        
      union SECINFO4res switch (nfsstat4 status) {
       case NFS4_OK:
               SECINFO4resok resok4;
       default:
               void;
      };
        
      union SECINFO4res switch (nfsstat4 status) {
       case NFS4_OK:
               SECINFO4resok resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The SECINFO operation is used by the client to obtain a list of valid RPC authentication flavors for a specific file handle, file name pair. The result will contain an array which represents the security mechanisms available. The array entries are represented by the secinfo4 structure. The field 'flavor' will contain a value of AUTH_NONE, AUTH_SYS (as defined in [RFC1831]), or RPCSEC_GSS (as defined in [RFC2203]).

客户端使用SECINFO操作获取特定文件句柄、文件名对的有效RPC身份验证样式列表。结果将包含一个表示可用安全机制的数组。数组项由secinfo4结构表示。字段“flavor”将包含AUTH_NONE、AUTH_SYS(定义见[RFC1831])或RPCSEC_GSS(定义见[RFC2203])的值。

For the flavors, AUTH_NONE, and AUTH_SYS no additional security information is returned. For a return value of RPCSEC_GSS, a security triple is returned that contains the mechanism object id (as defined in [RFC2078]), the quality of protection (as defined in [RFC2078]) and the service type (as defined in [RFC2203]). It is possible for SECINFO to return multiple entries with flavor equal to RPCSEC_GSS with different security triple values.

对于flavors、AUTH_NONE和AUTH_SYS,不会返回其他安全信息。对于RPCSEC_GSS的返回值,将返回一个包含机制对象id(如[RFC2078]中定义)、保护质量(如[RFC2078]中定义)和服务类型(如[RFC2203]中定义)的安全三元组。SECINFO可以返回多个具有不同安全性三重值的条目,其味道等于RPCSEC_GSS。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The SECINFO operation is expected to be used by the NFS client when the error value of NFS4ERR_WRONGSEC is returned from another NFS operation. This signifies to the client that the server's security policy is different from what the client is currently using. At this point, the client is expected to obtain a list of possible security flavors and choose what best suits its policies.

当从另一个NFS操作返回NFS4ERR_errosec的错误值时,NFS客户端将使用SECINFO操作。这向客户端表示服务器的安全策略与客户端当前使用的不同。此时,客户机将获得可能的安全风格列表,并选择最适合其策略的。

It is recommended that the client issue the SECINFO call protected by a security triple that uses either rpc_gss_svc_integrity or rpc_gss_svc_privacy service. The use of rpc_gss_svc_none would allow an attacker in the middle to modify the SECINFO results such that the client might select a weaker algorithm in the set allowed by server, making the client and/or server vulnerable to further attacks.

建议客户端发出受使用rpc_gss_svc_完整性或rpc_gss_svc_隐私服务的安全三元组保护的SECINFO调用。使用RPCIGSSYSVCKNONE将允许攻击者在中间修改SECIFO结果,使得客户端可以在服务器允许的集合中选择较弱的算法,使得客户端和/或服务器容易受到进一步攻击。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u BADHANDLE NFS4ERR\u FHEXPIRED NFS4ERR\u MOVED NFS4ERR\u NAMETOOLONG NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u RESOURCE NFS4ERR\u SERVERFAULT

NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR_过时NFS4ERR_错误秒

14.2.32. Operation 34: SETATTR - Set Attributes
14.2.32. 操作34:SETATTR-设置属性

SYNOPSIS

提要

      (cfh), attrbits, attrvals -> -
        
      (cfh), attrbits, attrvals -> -
        

ARGUMENT

论点

      struct SETATTR4args {
              /* CURRENT_FH: target object */
              stateid4        stateid;
              fattr4          obj_attributes;
      };
        
      struct SETATTR4args {
              /* CURRENT_FH: target object */
              stateid4        stateid;
              fattr4          obj_attributes;
      };
        

RESULT

后果

      struct SETATTR4res {
              nfsstat4        status;
              bitmap4         attrsset;
      };
        
      struct SETATTR4res {
              nfsstat4        status;
              bitmap4         attrsset;
      };
        

DESCRIPTION

描述

The SETATTR operation changes one or more of the attributes of a file system object. The new attributes are specified with a bitmap and the attributes that follow the bitmap in bit order.

SETATTR操作更改文件系统对象的一个或多个属性。新属性由位图和位图后面按位顺序的属性指定。

The stateid is necessary for SETATTRs that change the size of a file (modify the attribute object_size). This stateid represents a record lock, share reservation, or delegation which must be valid for the SETATTR to modify the file data. A valid stateid would always be specified. When the file size is not changed, the special stateid consisting of all bits 0 (zero) should be used.

stateid对于更改文件大小(修改属性对象大小)的setAttr是必需的。此stateid表示记录锁定、共享保留或委派,必须对SETATTR有效才能修改文件数据。将始终指定有效的stateid。当文件大小未更改时,应使用由所有位0(零)组成的特殊stateid。

On either success or failure of the operation, the server will return the attrsset bitmask to represent what (if any) attributes were successfully set.

操作成功或失败时,服务器将返回attrsset位掩码,以表示成功设置了哪些属性(如果有)。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The file size attribute is used to request changes to the size of a file. A value of 0 (zero) causes the file to be truncated, a value less than the current size of the file causes data from new

文件大小属性用于请求更改文件大小。值为0(零)会导致文件被截断,小于文件当前大小的值会导致数据来自新文件

size to the end of the file to be discarded, and a size greater than the current size of the file causes logically zeroed data bytes to be added to the end of the file. Servers are free to implement this using holes or actual zero data bytes. Clients should not make any assumptions regarding a server's implementation of this feature, beyond that the bytes returned will be zeroed. Servers must support extending the file size via SETATTR.

到要丢弃的文件结尾的大小,如果该大小大于文件的当前大小,则会将逻辑上归零的数据字节添加到文件结尾。服务器可以自由地使用洞或实际的零数据字节来实现这一点。客户端不应该对服务器实现此功能做出任何假设,超过此假设,返回的字节将归零。服务器必须支持通过SETATTR扩展文件大小。

SETATTR is not guaranteed atomic. A failed SETATTR may partially change a file's attributes.

SETATTR不保证是原子的。失败的SETATTR可能会部分更改文件的属性。

Changing the size of a file with SETATTR indirectly changes the time_modify. A client must account for this as size changes can result in data deletion.

使用SETATTR更改文件大小会间接更改您修改的时间。客户端必须对此进行解释,因为大小更改可能导致数据删除。

If server and client times differ, programs that compare client time to file times can break. A time maintenance protocol should be used to limit client/server time skew.

如果服务器和客户端时间不同,则比较客户端时间和文件时间的程序可能会中断。应该使用时间维护协议来限制客户机/服务器的时间偏差。

If the server cannot successfully set all the attributes it must return an NFS4ERR_INVAL error. If the server can only support 32 bit offsets and sizes, a SETATTR request to set the size of a file to larger than can be represented in 32 bits will be rejected with this same error.

如果服务器无法成功设置所有属性,则必须返回NFS4ERR_INVAL错误。如果服务器只能支持32位偏移量和大小,则将文件大小设置为大于32位所能表示大小的SETATTR请求将被拒绝,并出现相同错误。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_DQUOT NFS4ERR_EXPIRED NFS4ERR_FBIG NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTSUPP NFS4ERR_OLD_STATEID NFS4ERR_PERM NFS4ERR_RESOURCE NFS4ERR_ROFS

NFS4ERR\u访问NFS4ERR\u坏处理NFS4ERR\u坏状态ID NFS4ERR\u延迟NFS4ERR\u拒绝NFS4ERR\u引用NFS4ERR\u过期NFS4ERR\u FBIG NFS4ERR\u过期NFS4ERR\u宽限NFS4ERR\u无效NFS4ERR\u移动NFS4ERR\u文件句柄NFS4ERR\u NOSPC NFS4ERR\u不支持NFS4ERR资源

NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID NFS4ERR_WRONGSEC

NFS4ERR_服务器故障NFS4ERR_过时NFS4ERR_过时NFS4ERR_状态ID NFS4ERR_错误秒

14.2.33. Operation 35: SETCLIENTID - Negotiate Clientid
14.2.33. 操作35:SETCLIENTID-协商Clientid

SYNOPSIS

提要

client, callback -> clientid, setclientid_confirm

客户端,回调->客户端ID,设置客户端ID\u确认

ARGUMENT

论点

      struct SETCLIENTID4args {
              nfs_client_id4  client;
              cb_client4      callback;
      };
        
      struct SETCLIENTID4args {
              nfs_client_id4  client;
              cb_client4      callback;
      };
        

RESULT

后果

      struct SETCLIENTID4resok {
              clientid4       clientid;
              verifier4       setclientid_confirm;
      };
        
      struct SETCLIENTID4resok {
              clientid4       clientid;
              verifier4       setclientid_confirm;
      };
        
      union SETCLIENTID4res switch (nfsstat4 status) {
       case NFS4_OK:
               SETCLIENTID4resok      resok4;
       case NFS4ERR_CLID_INUSE:
               clientaddr4    client_using;
       default:
               void;
      };
        
      union SETCLIENTID4res switch (nfsstat4 status) {
       case NFS4_OK:
               SETCLIENTID4resok      resok4;
       case NFS4ERR_CLID_INUSE:
               clientaddr4    client_using;
       default:
               void;
      };
        

DESCRIPTION

描述

The SETCLIENTID operation introduces the ability of the client to notify the server of its intention to use a particular client identifier and verifier pair. Upon successful completion the server will return a clientid which is used in subsequent file locking requests and a confirmation verifier. The client will use the SETCLIENTID_CONFIRM operation to return the verifier to the server. At that point, the client may use the clientid in subsequent operations that require an nfs_lockowner.

SETCLIENTID操作引入了客户端通知服务器其打算使用特定客户端标识符和验证器对的能力。成功完成后,服务器将返回一个clientid,用于后续的文件锁定请求和确认验证器。客户端将使用SETCLIENTID_确认操作将验证器返回到服务器。此时,客户端可能会在需要nfs_锁所有者的后续操作中使用clientid。

The callback information provided in this operation will be used if the client is provided an open delegation at a future point. Therefore, the client must correctly reflect the program and port numbers for the callback program at the time SETCLIENTID is used.

如果在将来某个时间点向客户端提供了开放委托,则将使用此操作中提供的回调信息。因此,在使用SETCLIENTID时,客户端必须正确反映回调程序的程序和端口号。

IMPLEMENTATION

实施

The server takes the verifier and client identification supplied in the nfs_client_id4 and searches for a match of the client identification. If no match is found the server saves the principal/uid information along with the verifier and client identification and returns a unique clientid that is used as a shorthand reference to the supplied information.

服务器获取nfs_client_id4中提供的验证器和客户端标识,并搜索客户端标识的匹配项。如果未找到匹配项,服务器将保存主体/uid信息以及验证器和客户端标识,并返回一个唯一的clientid,该clientid用作对所提供信息的速记引用。

If the server finds matching client identification and a corresponding match in principal/uid, the server releases all locking state for the client and returns a new clientid.

如果服务器在principal/uid中找到匹配的客户端标识和相应的匹配项,则服务器将释放客户端的所有锁定状态并返回新的clientid。

The principal, or principal to user-identifier mapping is taken from the credential presented in the RPC. As mentioned, the server will use the credential and associated principal for the matching with existing clientids. If the client is a traditional host-based client like a Unix NFS client, then the credential presented may be the host credential. If the client is a user level client or lightweight client, the credential used may be the end user's credential. The client should take care in choosing an appropriate credential since denial of service attacks could be attempted by a rogue client that has access to the credential.

主体或主体到用户标识符的映射取自RPC中提供的凭据。如前所述,服务器将使用凭据和关联主体与现有ClientID进行匹配。如果客户端是传统的基于主机的客户端(如Unix NFS客户端),则提供的凭据可能是主机凭据。如果客户端是用户级客户端或轻量级客户端,则使用的凭据可能是最终用户的凭据。客户端在选择适当的凭据时应小心,因为有权访问凭据的恶意客户端可能会尝试拒绝服务攻击。

ERRORS

错误

NFS4ERR_CLID_INUSE NFS4ERR_INVAL NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u CLID\u使用NFS4ERR\u无效NFS4ERR\u资源NFS4ERR\u服务器故障

14.2.34. Operation 36: SETCLIENTID_CONFIRM - Confirm Clientid
14.2.34. 操作36:SETCLIENTID\u确认-确认Clientid

SYNOPSIS

提要

      setclientid_confirm -> -
        
      setclientid_confirm -> -
        

ARGUMENT

论点

      struct SETCLIENTID_CONFIRM4args {
              verifier4       setclientid_confirm;
      };
        
      struct SETCLIENTID_CONFIRM4args {
              verifier4       setclientid_confirm;
      };
        

RESULT

后果

      struct SETCLIENTID_CONFIRM4res {
              nfsstat4        status;
      };
        
      struct SETCLIENTID_CONFIRM4res {
              nfsstat4        status;
      };
        

DESCRIPTION

描述

This operation is used by the client to confirm the results from a previous call to SETCLIENTID. The client provides the server supplied (from a SETCLIENTID response) opaque confirmation verifier. The server responds with a simple status of success or failure.

客户端使用此操作确认以前调用SETCLIENTID的结果。客户机提供服务器提供的(来自SETCLIENTID响应)不透明确认验证器。服务器以简单的成功或失败状态进行响应。

IMPLEMENTATION

实施

The client must use the SETCLIENTID_CONFIRM operation to confirm its use of client identifier. If the server is holding state for a client which has presented a new verifier via SETCLIENTID, then the state will not be released, as described in the section "Client Failure and Recovery", until a valid SETCLIENTID_CONFIRM is received. Upon successful confirmation the server will release the previous state held on behalf of the client. The server should choose a confirmation cookie value that is reasonably unique for the client.

客户端必须使用SETCLIENTID_确认操作来确认其对客户端标识符的使用。如果服务器持有通过SETCLIENTID提供新验证器的客户端的状态,则在收到有效的SETCLIENTID_确认之前,该状态不会被释放,如“客户端故障和恢复”一节所述。成功确认后,服务器将释放代表客户端保留的先前状态。服务器应该选择一个确认cookie值,该值对于客户端来说是合理唯一的。

ERRORS

错误

NFS4ERR_CLID_INUSE NFS4ERR_INVAL NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR\u CLID\u使用NFS4ERR\u无效NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时客户端ID

14.2.35. Operation 37: VERIFY - Verify Same Attributes
14.2.35. 操作37:验证-验证相同的属性

SYNOPSIS

提要

      (cfh), fattr -> -
        
      (cfh), fattr -> -
        

ARGUMENT

论点

      struct VERIFY4args {
              /* CURRENT_FH: object */
              fattr4          obj_attributes;
      };
        
      struct VERIFY4args {
              /* CURRENT_FH: object */
              fattr4          obj_attributes;
      };
        

RESULT

后果

      struct VERIFY4res {
              nfsstat4        status;
      };
        
      struct VERIFY4res {
              nfsstat4        status;
      };
        

DESCRIPTION

描述

The VERIFY operation is used to verify that attributes have a value assumed by the client before proceeding with following operations in the compound request. If any of the attributes do not match then the error NFS4ERR_NOT_SAME must be returned. The current filehandle retains its value after successful completion of the operation.

验证操作用于在复合请求中继续执行以下操作之前,验证属性是否具有客户端假定的值。如果任何属性不匹配,则必须返回错误NFS4ERR_not_SAME。成功完成操作后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

One possible use of the VERIFY operation is the following compound sequence. With this the client is attempting to verify that the file being removed will match what the client expects to be removed. This sequence can help prevent the unintended deletion of a file.

验证操作的一个可能用途是以下复合序列。这样,客户端将尝试验证要删除的文件是否与客户端希望删除的文件匹配。此顺序有助于防止意外删除文件。

PUTFH (directory filehandle) LOOKUP (file name) VERIFY (filehandle == fh) PUTFH (directory filehandle) REMOVE (file name)

PUTFH(目录文件句柄)查找(文件名)验证(文件句柄==fh)PUTFH(目录文件句柄)删除(文件名)

This sequence does not prevent a second client from removing and creating a new file in the middle of this sequence but it does help avoid the unintended result.

这个序列不会阻止第二个客户端在这个序列中间移除和创建一个新文件,但是它确实有助于避免意外的结果。

In the case that a recommended attribute is specified in the VERIFY operation and the server does not support that attribute for the file system object, the error NFS4ERR_NOTSUPP is returned to the client.

如果在验证操作中指定了推荐的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_NOTSUPP返回给客户端。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u不支持

NFS4ERR_NOT_SAME NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u不相同NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误秒

14.2.36. Operation 38: WRITE - Write to File
14.2.36. 操作38:写入-写入文件

SYNOPSIS

提要

(cfh), offset, count, stability, stateid, data -> count, committed, verifier

(cfh)、偏移量、计数、稳定性、stateid、数据->计数、提交、验证器

ARGUMENT

论点

      enum stable_how4 {
              UNSTABLE4       = 0,
              DATA_SYNC4      = 1,
              FILE_SYNC4      = 2
      };
        
      enum stable_how4 {
              UNSTABLE4       = 0,
              DATA_SYNC4      = 1,
              FILE_SYNC4      = 2
      };
        
      struct WRITE4args {
              /* CURRENT_FH: file */
              stateid4        stateid;
              offset4         offset;
              stable_how4     stable;
              opaque          data<>;
      };
        
      struct WRITE4args {
              /* CURRENT_FH: file */
              stateid4        stateid;
              offset4         offset;
              stable_how4     stable;
              opaque          data<>;
      };
        

RESULT

后果

      struct WRITE4resok {
              count4          count;
              stable_how4     committed;
              verifier4       writeverf;
      };
        
      struct WRITE4resok {
              count4          count;
              stable_how4     committed;
              verifier4       writeverf;
      };
        
      union WRITE4res switch (nfsstat4 status) {
       case NFS4_OK:
               WRITE4resok    resok4;
       default:
               void;
      };
        
      union WRITE4res switch (nfsstat4 status) {
       case NFS4_OK:
               WRITE4resok    resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The WRITE operation is used to write data to a regular file. The target file is specified by the current filehandle. The offset specifies the offset where the data should be written. An offset of 0 (zero) specifies that the write should start at the beginning of the file. The count represents the number of bytes of data that are to be written. If the count is 0 (zero), the WRITE will succeed and return a count of 0 (zero) subject to permissions checking. The server may choose to write fewer bytes than requested by the client.

写入操作用于将数据写入常规文件。目标文件由当前文件句柄指定。偏移量指定写入数据的偏移量。偏移量为0(零)指定写入应从文件的开头开始。计数表示要写入的数据字节数。如果计数为0(零),则写入将成功,并返回0(零)的计数,然后进行权限检查。服务器可以选择写入的字节数少于客户端请求的字节数。

Part of the write request is a specification of how the write is to be performed. The client specifies with the stable parameter the method of how the data is to be processed by the server. If stable is FILE_SYNC4, the server must commit the data written plus all file system metadata to stable storage before returning results. This corresponds to the NFS version 2 protocol semantics. Any other behavior constitutes a protocol violation. If stable is DATA_SYNC4, then the server must commit all of the data to stable storage and enough of the metadata to retrieve the data before returning. The server implementor is free to implement DATA_SYNC4 in the same fashion as FILE_SYNC4, but with a possible performance drop. If stable is UNSTABLE4, the server is free to commit any part of the data and the metadata to stable storage, including all or none, before returning a reply to the client. There is no guarantee whether or when any uncommitted data will subsequently be committed to stable storage. The only guarantees made by the server are that it will not destroy any data without changing the value of verf and that it will not commit the data and metadata at a level less than that requested by the client.

写入请求的一部分是如何执行写入的规范。客户机使用stable参数指定服务器如何处理数据的方法。如果stable是FILE_SYNC4,则服务器必须在返回结果之前将写入的数据加上所有文件系统元数据提交到stable存储。这与NFS版本2协议语义相对应。任何其他行为都构成违反协议。如果stable是DATA_SYNC4,则服务器必须将所有数据提交到稳定存储,并在返回之前提交足够的元数据以检索数据。服务器实现者可以自由地以与文件同步4相同的方式实现数据同步4,但可能会导致性能下降。如果stable是不稳定的4,则服务器可以自由地将数据和元数据的任何部分提交到稳定存储,包括全部或全部,然后再向客户端返回回复。无法保证任何未提交的数据随后是否或何时提交到稳定存储。服务器所做的唯一保证是在不更改verf值的情况下不会销毁任何数据,并且不会以低于客户端请求的级别提交数据和元数据。

The stateid returned from a previous record lock or share reservation request is provided as part of the argument. The stateid is used by the server to verify that the associated lock is still valid and to update lease timeouts for the client.

从以前的记录锁定或共享保留请求返回的stateid作为参数的一部分提供。服务器使用stateid验证关联的锁是否仍然有效,并更新客户端的租约超时。

Upon successful completion, the following results are returned. The count result is the number of bytes of data written to the file. The server may write fewer bytes than requested. If so, the actual number of bytes written starting at location, offset, is returned.

成功完成后,返回以下结果。计数结果是写入文件的数据字节数。服务器写入的字节数可能少于请求的字节数。如果是,则返回从位置offset开始写入的实际字节数。

The server also returns an indication of the level of commitment of the data and metadata via committed. If the server committed all data and metadata to stable storage, committed should be set to FILE_SYNC4. If the level of commitment was at least as strong

服务器还通过提交返回数据和元数据的提交级别指示。如果服务器将所有数据和元数据提交到稳定存储中,则应将提交设置为文件\u SYNC4。如果承诺的程度至少也一样强烈

as DATA_SYNC4, then committed should be set to DATA_SYNC4. Otherwise, committed must be returned as UNSTABLE4. If stable was FILE4_SYNC, then committed must also be FILE_SYNC4: anything else constitutes a protocol violation. If stable was DATA_SYNC4, then committed may be FILE_SYNC4 or DATA_SYNC4: anything else constitutes a protocol violation. If stable was UNSTABLE4, then committed may be either FILE_SYNC4, DATA_SYNC4, or UNSTABLE4.

作为DATA_SYNC4,则应将committed设置为DATA_SYNC4。否则,committed必须作为UNSTABLE4返回。如果stable是FILE4\u SYNC,那么committed也必须是FILE\u SYNC4:任何其他内容都构成协议冲突。如果stable是DATA_SYNC4,那么提交的可能是FILE_SYNC4或DATA_SYNC4:任何其他内容都构成协议冲突。如果stable是UNSTABLE4,那么提交的可能是FILE\u SYNC4、DATA\u SYNC4或UNSTABLE4。

The final portion of the result is the write verifier, verf. The write verifier is a cookie that the client can use to determine whether the server has changed state between a call to WRITE and a subsequent call to either WRITE or COMMIT. This cookie must be consistent during a single instance of the NFS version 4 protocol service and must be unique between instances of the NFS version 4 protocol server, where uncommitted data may be lost.

结果的最后一部分是写验证器verf。写入验证器是一个cookie,客户端可以使用它来确定服务器在调用write和后续调用write或COMMIT之间是否已更改状态。此cookie在NFS版本4协议服务的单个实例期间必须一致,并且在NFS版本4协议服务器的实例之间必须唯一,未提交的数据可能会丢失。

If a client writes data to the server with the stable argument set to UNSTABLE4 and the reply yields a committed response of DATA_SYNC4 or UNSTABLE4, the client will follow up some time in the future with a COMMIT operation to synchronize outstanding asynchronous data and metadata with the server's stable storage, barring client error. It is possible that due to client crash or other error that a subsequent COMMIT will not be received by the server.

如果客户端将stable参数设置为UNSTABLE4时将数据写入服务器,并且回复产生data_SYNC4或UNSTABLE4的提交响应,则客户端将在将来的某个时间执行提交操作,以将未完成的异步数据和元数据与服务器的稳定存储同步,从而避免客户端错误。由于客户端崩溃或其他错误,服务器可能无法接收后续提交。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

It is possible for the server to write fewer than count bytes of data. In this case, the server should not return an error unless no data was written at all. If the server writes less than count bytes, the client should issue another WRITE to write the remaining data.

服务器可以写入少于计数字节的数据。在这种情况下,除非根本没有写入数据,否则服务器不应返回错误。如果服务器写入的字节数少于count字节,则客户端应发出另一次写入,以写入剩余的数据。

It is assumed that the act of writing data to a file will cause the time_modified of the file to be updated. However, the time_modified of the file should not be changed unless the contents of the file are changed. Thus, a WRITE request with count set to 0 should not cause the time_modified of the file to be updated.

假设将数据写入文件的行为将导致文件的修改时间被更新。但是,除非文件内容发生更改,否则不应更改文件的修改时间。因此,计数设置为0的写入请求不应导致更新文件的修改时间。

The definition of stable storage has been historically a point of contention. The following expected properties of stable storage may help in resolving design issues in the implementation. Stable storage is persistent storage that survives:

稳定存储的定义历来是争论的焦点。稳定存储的以下预期属性可能有助于解决实现中的设计问题。稳定存储是一种持久性存储,可在以下情况下生存:

1. Repeated power failures. 2. Hardware failures (of any board, power supply, etc.). 3. Repeated software crashes, including reboot cycle.

1. 反复停电。2.硬件故障(任何板、电源等)。3.重复的软件崩溃,包括重新启动周期。

This definition does not address failure of the stable storage module itself.

此定义不解决稳定存储模块本身的故障。

The verifier is defined to allow a client to detect different instances of an NFS version 4 protocol server over which cached, uncommitted data may be lost. In the most likely case, the verifier allows the client to detect server reboots. This information is required so that the client can safely determine whether the server could have lost cached data. If the server fails unexpectedly and the client has uncommitted data from previous WRITE requests (done with the stable argument set to UNSTABLE4 and in which the result committed was returned as UNSTABLE4 as well) it may not have flushed cached data to stable storage. The burden of recovery is on the client and the client will need to retransmit the data to the server.

验证器被定义为允许客户端检测NFS版本4协议服务器的不同实例,在这些实例上缓存的未提交数据可能会丢失。在最可能的情况下,验证器允许客户端检测服务器重新启动。需要此信息,以便客户端可以安全地确定服务器是否可能丢失了缓存数据。如果服务器意外失败,并且客户端具有来自以前写入请求的未提交数据(在将stable参数设置为UNSTABLE4的情况下完成,并且提交的结果也返回为UNSTABLE4),则它可能没有将缓存数据刷新到稳定存储中。恢复的负担由客户端承担,客户端需要将数据重新传输到服务器。

A suggested verifier would be to use the time that the server was booted or the time the server was last started (if restarting the server without a reboot results in lost buffers).

建议的验证器是使用服务器启动的时间或服务器上次启动的时间(如果在没有重新启动的情况下重新启动服务器会导致缓冲区丢失)。

The committed field in the results allows the client to do more effective caching. If the server is committing all WRITE requests to stable storage, then it should return with committed set to FILE_SYNC4, regardless of the value of the stable field in the arguments. A server that uses an NVRAM accelerator may choose to implement this policy. The client can use this to increase the effectiveness of the cache by discarding cached data that has already been committed on the server.

结果中的提交字段允许客户端执行更有效的缓存。如果服务器正在将所有写请求提交到稳定存储,则无论参数中稳定字段的值是多少,它都应返回并将提交集设置为FILE_SYNC4。使用NVRAM加速器的服务器可以选择实施此策略。客户机可以通过丢弃已在服务器上提交的缓存数据来提高缓存的有效性。

Some implementations may return NFS4ERR_NOSPC instead of NFS4ERR_DQUOT when a user's quota is exceeded.

当超过用户配额时,某些实现可能返回NFS4ERR_NOSPC而不是NFS4ERR_DQUOT。

ERRORS

错误

NFS4ERR_ACCES NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_DQUOT NFS4ERR_EXPIRED NFS4ERR_FBIG NFS4ERR_FHEXPIRED NFS4ERR_GRACE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏状态ID NFS4ERR\u延迟NFS4ERR\u拒绝NFS4ERR\u DQUOT NFS4ERR\u过期NFS4ERR\u FBIG NFS4ERR\u过期NFS4ERR\u

NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_LEASE_MOVED NFS4ERR_LOCKED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID NFS4ERR_WRONGSEC

NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u租赁NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u NOSPC NFS4ERR\u旧状态ID NFS4ERR\u资源NFS4ERR\u ROFS NFS4ERR\u服务器故障NFS4ERR\u旧状态ID NFS4ERR\u错误

15. NFS Version 4 Callback Procedures
15. NFS版本4回调过程

The procedures used for callbacks are defined in the following sections. In the interest of clarity, the terms "client" and "server" refer to NFS clients and servers, despite the fact that for an individual callback RPC, the sense of these terms would be precisely the opposite.

用于回调的过程在以下部分中定义。为了清楚起见,术语“客户机”和“服务器”指的是NFS客户机和服务器,尽管对于单个回调RPC,这些术语的含义正好相反。

15.1. Procedure 0: CB_NULL - No Operation
15.1. 过程0:CB_NULL-无操作

SYNOPSIS

提要

<null>

<null>

ARGUMENT

论点

void;

无效的

RESULT

后果

void;

无效的

DESCRIPTION

描述

Standard NULL procedure. Void argument, void response. Even though there is no direct functionality associated with this procedure, the server will use CB_NULL to confirm the existence of a path for RPCs from server to client.

标准的空过程。无效的论点,无效的回应。即使没有与此过程相关联的直接功能,服务器也将使用CB_NULL来确认存在从服务器到客户端的RPC路径。

ERRORS

错误

None.

没有一个

15.2. Procedure 1: CB_COMPOUND - Compound Operations
15.2. 程序1:CB_复合-复合操作

SYNOPSIS

提要

compoundargs -> compoundres

合成标记->合成标记

ARGUMENT

论点

      enum nfs_cb_opnum4 {
              OP_CB_GETATTR           = 3,
              OP_CB_RECALL            = 4 };
        
      enum nfs_cb_opnum4 {
              OP_CB_GETATTR           = 3,
              OP_CB_RECALL            = 4 };
        
      union nfs_cb_argop4 switch (unsigned argop) {
       case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
       case OP_CB_RECALL:     CB_RECALL4args  opcbrecall; };
        
      union nfs_cb_argop4 switch (unsigned argop) {
       case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
       case OP_CB_RECALL:     CB_RECALL4args  opcbrecall; };
        
      struct CB_COMPOUND4args {
              utf8string      tag;
              uint32_t        minorversion;
              nfs_cb_argop4   argarray<>; };
        
      struct CB_COMPOUND4args {
              utf8string      tag;
              uint32_t        minorversion;
              nfs_cb_argop4   argarray<>; };
        

RESULT

后果

      union nfs_cb_resop4 switch (unsigned resop){
       case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
       case OP_CB_RECALL:     CB_RECALL4res   opcbrecall; };
        
      union nfs_cb_resop4 switch (unsigned resop){
       case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
       case OP_CB_RECALL:     CB_RECALL4res   opcbrecall; };
        
      struct CB_COMPOUND4res {
              nfsstat4 status;
              utf8string      tag;
              nfs_cb_resop4   resarray<>; };
        
      struct CB_COMPOUND4res {
              nfsstat4 status;
              utf8string      tag;
              nfs_cb_resop4   resarray<>; };
        

DESCRIPTION

描述

The CB_COMPOUND procedure is used to combine one or more of the callback procedures into a single RPC request. The main callback RPC program has two main procedures: CB_NULL and CB_COMPOUND. All other operations use the CB_COMPOUND procedure as a wrapper.

CB_复合过程用于将一个或多个回调过程组合到单个RPC请求中。主回调RPC程序有两个主要过程:CB_NULL和CB_component。所有其他操作都使用CB_复合过程作为包装。

In the processing of the CB_COMPOUND procedure, the client may find that it does not have the available resources to execute any or all of the operations within the CB_COMPOUND sequence. In this case, the error NFS4ERR_RESOURCE will be returned for the particular operation within the CB_COMPOUND procedure where the resource exhaustion occurred. This assumes that all previous operations within the CB_COMPOUND sequence have been evaluated successfully.

在CB_复合过程的处理过程中,客户端可能会发现它没有可用的资源来执行CB_复合序列中的任何或所有操作。在这种情况下,对于发生资源耗尽的CB_复合过程中的特定操作,将返回错误NFS4ERR_资源。这假设CB_复合序列中的所有先前操作都已成功评估。

Contained within the CB_COMPOUND results is a 'status' field. This status must be equivalent to the status of the last operation that was executed within the CB_COMPOUND procedure. Therefore, if an operation incurred an error then the 'status' value will be the same error value as is being returned for the operation that failed.

CB_复合结果中包含一个“状态”字段。此状态必须与CB_复合过程中执行的最后一个操作的状态相同。因此,如果操作发生错误,“状态”值将与为失败的操作返回的错误值相同。

IMPLEMENTATION

实施

The CB_COMPOUND procedure is used to combine individual operations into a single RPC request. The client interprets each of the operations in turn. If an operation is executed by the client and the status of that operation is NFS4_OK, then the next operation in the CB_COMPOUND procedure is executed. The client continues this process until there are no more operations to be executed or one of the operations has a status value other than NFS4_OK.

CB_复合过程用于将单个操作合并到单个RPC请求中。客户机依次解释每个操作。如果客户端执行一个操作,并且该操作的状态为NFS4_OK,则执行CB_复合过程中的下一个操作。客户端将继续此过程,直到不再执行任何操作,或者其中一个操作的状态值不是NFS4_OK。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_RESOURCE

NFS4ERR\u坏句柄NFS4ERR\u坏\u状态ID NFS4ERR\u资源

15.2.1. Operation 3: CB_GETATTR - Get Attributes
15.2.1. 操作3:CB_GETATTR-Get属性

SYNOPSIS

提要

fh, attrbits -> attrbits, attrvals

fh,属性->属性,属性

ARGUMENT

论点

      struct CB_GETATTR4args {
              nfs_fh4 fh;
              bitmap4 attr_request;
      };
        
      struct CB_GETATTR4args {
              nfs_fh4 fh;
              bitmap4 attr_request;
      };
        

RESULT

后果

      struct CB_GETATTR4resok {
              fattr4  obj_attributes;
      };
        
      struct CB_GETATTR4resok {
              fattr4  obj_attributes;
      };
        
      union CB_GETATTR4res switch (nfsstat4 status) {
       case NFS4_OK:
               CB_GETATTR4resok       resok4;
       default:
               void;
      };
        
      union CB_GETATTR4res switch (nfsstat4 status) {
       case NFS4_OK:
               CB_GETATTR4resok       resok4;
       default:
               void;
      };
        

DESCRIPTION

描述

The CB_GETATTR operation is used to obtain the attributes modified by an open delegate to allow the server to respond to GETATTR requests for a file which is the subject of an open delegation.

CB_GETATTR操作用于获取由开放委托修改的属性,以允许服务器响应开放委托主题文件的GETATTR请求。

If the handle specified is not one for which the client holds a write open delegation, an NFS4ERR_BADHANDLE error is returned.

如果指定的句柄不是客户端持有写开放委托的句柄,则返回NFS4ERR_BADHANDLE错误。

IMPLEMENTATION

实施

The client returns attrbits and the associated attribute values only for attributes that it may change (change, time_modify, object_size).

客户机仅为其可能更改的属性(更改、时间\修改、对象\大小)返回属性位和相关属性值。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_RESOURCE

NFS4ERR_坏句柄NFS4ERR_资源

15.2.2. Operation 4: CB_RECALL - Recall an Open Delegation
15.2.2. 操作4:CB_召回-召回公开委托

SYNOPSIS

提要

stateid, truncate, fh -> status

stateid,截断,fh->状态

ARGUMENT

论点

      struct CB_RECALL4args {
              stateid4        stateid;
              bool            truncate;
              nfs_fh4         fh;
      };
        
      struct CB_RECALL4args {
              stateid4        stateid;
              bool            truncate;
              nfs_fh4         fh;
      };
        

RESULT

后果

      struct CB_RECALL4res {
              nfsstat4        status;
      };
        
      struct CB_RECALL4res {
              nfsstat4        status;
      };
        

DESCRIPTION

描述

The CB_RECALL operation is used to begin the process of recalling an open delegation and returning it to the server.

CB_回调操作用于开始回调打开的委托并将其返回到服务器的过程。

The truncate flag is used to optimize recall for a file which is about to be truncated to zero. When it is set, the client is freed of obligation to propagate modified data for the file to the server, since this data is irrelevant.

truncate标志用于优化即将被截断为零的文件的调用。设置后,客户机无需将修改后的文件数据传播到服务器,因为这些数据是无关的。

If the handle specified is not one for which the client holds an open delegation, an NFS4ERR_BADHANDLE error is returned.

如果指定的句柄不是客户端持有开放委托的句柄,则返回NFS4ERR_BADHANDLE错误。

If the stateid specified is not one corresponding to an open delegation for the file specified by the filehandle, an NFS4ERR_BAD_STATEID is returned.

如果指定的stateid不是与filehandle指定的文件的开放委派相对应的stateid,则返回NFS4ERR_BAD_stateid。

IMPLEMENTATION

实施

The client should reply to the callback immediately. Replying does not complete the recall. The recall is not complete until the delegation is returned using a DELEGRETURN.

客户端应该立即回复回调。回复并不能完成召回。只有使用DELEGRETURN返回委托,召回才算完成。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_RESOURCE

NFS4ERR\u坏句柄NFS4ERR\u坏\u状态ID NFS4ERR\u资源

16. Security Considerations
16. 安全考虑

The major security feature to consider is the authentication of the user making the request of NFS service. Consideration should also be given to the integrity and privacy of this NFS request. These specific issues are discussed as part of the section on "RPC and Security Flavor".

要考虑的主要安全特性是对NFS服务的请求的用户的认证。还应考虑此NFS请求的完整性和隐私性。这些具体问题将作为“RPC和安全风格”一节的一部分进行讨论。

17. IANA Considerations
17. IANA考虑
17.1. Named Attribute Definition
17.1. 命名属性定义

The NFS version 4 protocol provides for the association of named attributes to files. The name space identifiers for these attributes are defined as string names. The protocol does not define the specific assignment of the name space for these file attributes; the application developer or system vendor is allowed to define the attribute, its semantics, and the associated name. Even though this name space will not be specifically controlled to prevent collisions, the application developer or system vendor is strongly encouraged to provide the name assignment and associated semantics for attributes via an Informational RFC. This will provide for interoperability where common interests exist.

NFS版本4协议提供了命名属性与文件的关联。这些属性的名称空间标识符定义为字符串名称。协议没有为这些文件属性定义名称空间的特定分配;允许应用程序开发人员或系统供应商定义属性、其语义和关联的名称。尽管不会专门控制此名称空间以防止冲突,但强烈建议应用程序开发人员或系统供应商通过信息RFC为属性提供名称分配和相关语义。这将在存在共同利益的地方提供互操作性。

18. RPC definition file
18. RPC定义文件
   /*
    *  Copyright (C) The Internet Society (1998,1999,2000).
    *  All Rights Reserved.
    */
        
   /*
    *  Copyright (C) The Internet Society (1998,1999,2000).
    *  All Rights Reserved.
    */
        
   /*
    *      nfs4_prot.x
    *
    */
        
   /*
    *      nfs4_prot.x
    *
    */
        
   %#pragma ident  "@(#)nfs4_prot.x        1.97    00/06/12"
        
   %#pragma ident  "@(#)nfs4_prot.x        1.97    00/06/12"
        
   /*
    * Basic typedefs for RFC 1832 data type definitions
    */
   typedef int             int32_t;
   typedef unsigned int    uint32_t;
   typedef hyper           int64_t;
   typedef unsigned hyper  uint64_t;
        
   /*
    * Basic typedefs for RFC 1832 data type definitions
    */
   typedef int             int32_t;
   typedef unsigned int    uint32_t;
   typedef hyper           int64_t;
   typedef unsigned hyper  uint64_t;
        
   /*
    * Sizes
    */
   const NFS4_FHSIZE               = 128;
   const NFS4_VERIFIER_SIZE        = 8;
        
   /*
    * Sizes
    */
   const NFS4_FHSIZE               = 128;
   const NFS4_VERIFIER_SIZE        = 8;
        
   /*
    * File types
    */
   enum nfs_ftype4 {
           NF4REG          = 1,    /* Regular File */
           NF4DIR          = 2,    /* Directory */
           NF4BLK          = 3,    /* Special File - block device */
           NF4CHR          = 4,    /* Special File - character device */
           NF4LNK          = 5,    /* Symbolic Link */
           NF4SOCK         = 6,    /* Special File - socket */
           NF4FIFO         = 7,    /* Special File - fifo */
           NF4ATTRDIR      = 8,    /* Attribute Directory */
           NF4NAMEDATTR    = 9     /* Named Attribute */
   };
        
   /*
    * File types
    */
   enum nfs_ftype4 {
           NF4REG          = 1,    /* Regular File */
           NF4DIR          = 2,    /* Directory */
           NF4BLK          = 3,    /* Special File - block device */
           NF4CHR          = 4,    /* Special File - character device */
           NF4LNK          = 5,    /* Symbolic Link */
           NF4SOCK         = 6,    /* Special File - socket */
           NF4FIFO         = 7,    /* Special File - fifo */
           NF4ATTRDIR      = 8,    /* Attribute Directory */
           NF4NAMEDATTR    = 9     /* Named Attribute */
   };
        
   /*
    * Error status
    */
   enum nfsstat4 {
           NFS4_OK                 = 0,
        
   /*
    * Error status
    */
   enum nfsstat4 {
           NFS4_OK                 = 0,
        
           NFS4ERR_PERM            = 1,
           NFS4ERR_NOENT           = 2,
           NFS4ERR_IO              = 5,
           NFS4ERR_NXIO            = 6,
           NFS4ERR_ACCES           = 13,
           NFS4ERR_EXIST           = 17,
           NFS4ERR_XDEV            = 18,
           NFS4ERR_NODEV           = 19,
           NFS4ERR_NOTDIR          = 20,
           NFS4ERR_ISDIR           = 21,
           NFS4ERR_INVAL           = 22,
           NFS4ERR_FBIG            = 27,
           NFS4ERR_NOSPC           = 28,
           NFS4ERR_ROFS            = 30,
           NFS4ERR_MLINK           = 31,
           NFS4ERR_NAMETOOLONG     = 63,
           NFS4ERR_NOTEMPTY        = 66,
           NFS4ERR_DQUOT           = 69,
           NFS4ERR_STALE           = 70,
           NFS4ERR_BADHANDLE       = 10001,
           NFS4ERR_BAD_COOKIE      = 10003,
           NFS4ERR_NOTSUPP         = 10004,
           NFS4ERR_TOOSMALL        = 10005,
           NFS4ERR_SERVERFAULT     = 10006,
           NFS4ERR_BADTYPE         = 10007,
           NFS4ERR_DELAY           = 10008,
           NFS4ERR_SAME            = 10009,/* nverify says attrs same */
           NFS4ERR_DENIED          = 10010,/* lock unavailable        */
           NFS4ERR_EXPIRED         = 10011,/* lock lease expired      */
           NFS4ERR_LOCKED          = 10012,/* I/O failed due to lock  */
           NFS4ERR_GRACE           = 10013,/* in grace period         */
           NFS4ERR_FHEXPIRED       = 10014,/* file handle expired     */
           NFS4ERR_SHARE_DENIED    = 10015,/* share reserve denied    */
           NFS4ERR_WRONGSEC        = 10016,/* wrong security flavor   */
           NFS4ERR_CLID_INUSE      = 10017,/* clientid in use         */
           NFS4ERR_RESOURCE        = 10018,/* resource exhaustion     */
           NFS4ERR_MOVED           = 10019,/* filesystem relocated    */
           NFS4ERR_NOFILEHANDLE    = 10020,/* current FH is not set   */
           NFS4ERR_MINOR_VERS_MISMATCH = 10021,/* minor vers not supp */
           NFS4ERR_STALE_CLIENTID  = 10022,
           NFS4ERR_STALE_STATEID   = 10023,
           NFS4ERR_OLD_STATEID     = 10024,
           NFS4ERR_BAD_STATEID     = 10025,
           NFS4ERR_BAD_SEQID       = 10026,
           NFS4ERR_NOT_SAME        = 10027,/* verify - attrs not same */
           NFS4ERR_LOCK_RANGE      = 10028,
           NFS4ERR_SYMLINK         = 10029,
           NFS4ERR_READDIR_NOSPC   = 10030,
        
           NFS4ERR_PERM            = 1,
           NFS4ERR_NOENT           = 2,
           NFS4ERR_IO              = 5,
           NFS4ERR_NXIO            = 6,
           NFS4ERR_ACCES           = 13,
           NFS4ERR_EXIST           = 17,
           NFS4ERR_XDEV            = 18,
           NFS4ERR_NODEV           = 19,
           NFS4ERR_NOTDIR          = 20,
           NFS4ERR_ISDIR           = 21,
           NFS4ERR_INVAL           = 22,
           NFS4ERR_FBIG            = 27,
           NFS4ERR_NOSPC           = 28,
           NFS4ERR_ROFS            = 30,
           NFS4ERR_MLINK           = 31,
           NFS4ERR_NAMETOOLONG     = 63,
           NFS4ERR_NOTEMPTY        = 66,
           NFS4ERR_DQUOT           = 69,
           NFS4ERR_STALE           = 70,
           NFS4ERR_BADHANDLE       = 10001,
           NFS4ERR_BAD_COOKIE      = 10003,
           NFS4ERR_NOTSUPP         = 10004,
           NFS4ERR_TOOSMALL        = 10005,
           NFS4ERR_SERVERFAULT     = 10006,
           NFS4ERR_BADTYPE         = 10007,
           NFS4ERR_DELAY           = 10008,
           NFS4ERR_SAME            = 10009,/* nverify says attrs same */
           NFS4ERR_DENIED          = 10010,/* lock unavailable        */
           NFS4ERR_EXPIRED         = 10011,/* lock lease expired      */
           NFS4ERR_LOCKED          = 10012,/* I/O failed due to lock  */
           NFS4ERR_GRACE           = 10013,/* in grace period         */
           NFS4ERR_FHEXPIRED       = 10014,/* file handle expired     */
           NFS4ERR_SHARE_DENIED    = 10015,/* share reserve denied    */
           NFS4ERR_WRONGSEC        = 10016,/* wrong security flavor   */
           NFS4ERR_CLID_INUSE      = 10017,/* clientid in use         */
           NFS4ERR_RESOURCE        = 10018,/* resource exhaustion     */
           NFS4ERR_MOVED           = 10019,/* filesystem relocated    */
           NFS4ERR_NOFILEHANDLE    = 10020,/* current FH is not set   */
           NFS4ERR_MINOR_VERS_MISMATCH = 10021,/* minor vers not supp */
           NFS4ERR_STALE_CLIENTID  = 10022,
           NFS4ERR_STALE_STATEID   = 10023,
           NFS4ERR_OLD_STATEID     = 10024,
           NFS4ERR_BAD_STATEID     = 10025,
           NFS4ERR_BAD_SEQID       = 10026,
           NFS4ERR_NOT_SAME        = 10027,/* verify - attrs not same */
           NFS4ERR_LOCK_RANGE      = 10028,
           NFS4ERR_SYMLINK         = 10029,
           NFS4ERR_READDIR_NOSPC   = 10030,
        

NFS4ERR_LEASE_MOVED = 10031 };

NFS4ERR_LEASE_MOVED=10031};

   /*
    * Basic data types
    */
   typedef uint32_t        bitmap4<>;
   typedef uint64_t        offset4;
   typedef uint32_t        count4;
   typedef uint64_t        length4;
   typedef uint64_t        clientid4;
   typedef uint64_t        stateid4;
   typedef uint32_t        seqid4;
   typedef opaque          utf8string<>;
   typedef utf8string      component4;
   typedef component4      pathname4<>;
   typedef uint64_t        nfs_lockid4;
   typedef uint64_t        nfs_cookie4;
   typedef utf8string      linktext4;
   typedef opaque          sec_oid4<>;
   typedef uint32_t        qop4;
   typedef uint32_t        mode4;
   typedef uint64_t        changeid4;
   typedef opaque          verifier4[NFS4_VERIFIER_SIZE];
        
   /*
    * Basic data types
    */
   typedef uint32_t        bitmap4<>;
   typedef uint64_t        offset4;
   typedef uint32_t        count4;
   typedef uint64_t        length4;
   typedef uint64_t        clientid4;
   typedef uint64_t        stateid4;
   typedef uint32_t        seqid4;
   typedef opaque          utf8string<>;
   typedef utf8string      component4;
   typedef component4      pathname4<>;
   typedef uint64_t        nfs_lockid4;
   typedef uint64_t        nfs_cookie4;
   typedef utf8string      linktext4;
   typedef opaque          sec_oid4<>;
   typedef uint32_t        qop4;
   typedef uint32_t        mode4;
   typedef uint64_t        changeid4;
   typedef opaque          verifier4[NFS4_VERIFIER_SIZE];
        
   /*
    * Timeval
    */
   struct nfstime4 {
           int64_t         seconds;
           uint32_t        nseconds;
   };
        
   /*
    * Timeval
    */
   struct nfstime4 {
           int64_t         seconds;
           uint32_t        nseconds;
   };
        
   enum time_how4 {
           SET_TO_SERVER_TIME4 = 0,
           SET_TO_CLIENT_TIME4 = 1
   };
        
   enum time_how4 {
           SET_TO_SERVER_TIME4 = 0,
           SET_TO_CLIENT_TIME4 = 1
   };
        
   union settime4 switch (time_how4 set_it) {
    case SET_TO_CLIENT_TIME4:
            nfstime4       time;
    default:
            void;
   };
        
   union settime4 switch (time_how4 set_it) {
    case SET_TO_CLIENT_TIME4:
            nfstime4       time;
    default:
            void;
   };
        
   /*
    * File access handle
    */
        
   /*
    * File access handle
    */
        
   typedef opaque  nfs_fh4<NFS4_FHSIZE>;
        
   typedef opaque  nfs_fh4<NFS4_FHSIZE>;
        
   /*
    * File attribute definitions
    */
        
   /*
    * File attribute definitions
    */
        
   /*
    * FSID structure for major/minor
    */
   struct fsid4 {
           uint64_t        major;
           uint64_t        minor;
   };
        
   /*
    * FSID structure for major/minor
    */
   struct fsid4 {
           uint64_t        major;
           uint64_t        minor;
   };
        
   /*
    * Filesystem locations attribute for relocation/migration
    */
   struct fs_location4 {
           utf8string      server<>;
           pathname4       rootpath;
   };
        
   /*
    * Filesystem locations attribute for relocation/migration
    */
   struct fs_location4 {
           utf8string      server<>;
           pathname4       rootpath;
   };
        
   struct fs_locations4 {
           pathname4       fs_root;
           fs_location4    locations<>;
   };
        
   struct fs_locations4 {
           pathname4       fs_root;
           fs_location4    locations<>;
   };
        
   /*
    * Various Access Control Entry definitions
    */
        
   /*
    * Various Access Control Entry definitions
    */
        
   /*
    * Mask that indicates which Access Control Entries are supported.
    * Values for the fattr4_aclsupport attribute.
    */
   const ACL4_SUPPORT_ALLOW_ACL    = 0x00000001;
   const ACL4_SUPPORT_DENY_ACL     = 0x00000002;
   const ACL4_SUPPORT_AUDIT_ACL    = 0x00000004;
   const ACL4_SUPPORT_ALARM_ACL    = 0x00000008;
        
   /*
    * Mask that indicates which Access Control Entries are supported.
    * Values for the fattr4_aclsupport attribute.
    */
   const ACL4_SUPPORT_ALLOW_ACL    = 0x00000001;
   const ACL4_SUPPORT_DENY_ACL     = 0x00000002;
   const ACL4_SUPPORT_AUDIT_ACL    = 0x00000004;
   const ACL4_SUPPORT_ALARM_ACL    = 0x00000008;
        

typedef uint32_t acetype4;

typedef uint32_t acetype4;

   /*
    * acetype4 values, others can be added as needed.
    */
   const ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
        
   /*
    * acetype4 values, others can be added as needed.
    */
   const ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
        
   const ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
   const ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
   const ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
        
   const ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
   const ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
   const ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
        
   /*
    * ACE flag
    */
   typedef uint32_t aceflag4;
        
   /*
    * ACE flag
    */
   typedef uint32_t aceflag4;
        
   /*
    * ACE flag values
    */
   const ACE4_FILE_INHERIT_ACE             = 0x00000001;
   const ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
   const ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
   const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
   const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
   const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
   const ACE4_IDENTIFIER_GROUP             = 0x00000040;
        
   /*
    * ACE flag values
    */
   const ACE4_FILE_INHERIT_ACE             = 0x00000001;
   const ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
   const ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
   const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
   const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
   const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
   const ACE4_IDENTIFIER_GROUP             = 0x00000040;
        
   /*
    * ACE mask
    */
   typedef uint32_t        acemask4;
        
   /*
    * ACE mask
    */
   typedef uint32_t        acemask4;
        
   /*
    * ACE mask values
    */
   const ACE4_READ_DATA            = 0x00000001;
   const ACE4_LIST_DIRECTORY       = 0x00000001;
   const ACE4_WRITE_DATA           = 0x00000002;
   const ACE4_ADD_FILE             = 0x00000002;
   const ACE4_APPEND_DATA          = 0x00000004;
   const ACE4_ADD_SUBDIRECTORY     = 0x00000004;
   const ACE4_READ_NAMED_ATTRS     = 0x00000008;
   const ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
   const ACE4_EXECUTE              = 0x00000020;
   const ACE4_DELETE_CHILD         = 0x00000040;
   const ACE4_READ_ATTRIBUTES      = 0x00000080;
   const ACE4_WRITE_ATTRIBUTES     = 0x00000100;
        
   /*
    * ACE mask values
    */
   const ACE4_READ_DATA            = 0x00000001;
   const ACE4_LIST_DIRECTORY       = 0x00000001;
   const ACE4_WRITE_DATA           = 0x00000002;
   const ACE4_ADD_FILE             = 0x00000002;
   const ACE4_APPEND_DATA          = 0x00000004;
   const ACE4_ADD_SUBDIRECTORY     = 0x00000004;
   const ACE4_READ_NAMED_ATTRS     = 0x00000008;
   const ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
   const ACE4_EXECUTE              = 0x00000020;
   const ACE4_DELETE_CHILD         = 0x00000040;
   const ACE4_READ_ATTRIBUTES      = 0x00000080;
   const ACE4_WRITE_ATTRIBUTES     = 0x00000100;
        
   const ACE4_DELETE               = 0x00010000;
   const ACE4_READ_ACL             = 0x00020000;
   const ACE4_WRITE_ACL            = 0x00040000;
   const ACE4_WRITE_OWNER          = 0x00080000;
   const ACE4_SYNCHRONIZE          = 0x00100000;
        
   const ACE4_DELETE               = 0x00010000;
   const ACE4_READ_ACL             = 0x00020000;
   const ACE4_WRITE_ACL            = 0x00040000;
   const ACE4_WRITE_OWNER          = 0x00080000;
   const ACE4_SYNCHRONIZE          = 0x00100000;
        
   /*
    * ACE4_GENERIC_READ -- defined as combination of
    *      ACE4_READ_ACL |
    *      ACE4_READ_DATA |
    *      ACE4_READ_ATTRIBUTES |
    *      ACE4_SYNCHRONIZE
    */
        
   /*
    * ACE4_GENERIC_READ -- defined as combination of
    *      ACE4_READ_ACL |
    *      ACE4_READ_DATA |
    *      ACE4_READ_ATTRIBUTES |
    *      ACE4_SYNCHRONIZE
    */
        

const ACE4_GENERIC_READ = 0x00120081;

常量ACE4_GENERIC_READ=0x00120081;

   /*
    * ACE4_GENERIC_WRITE -- defined as combination of
    *      ACE4_READ_ACL |
    *      ACE4_WRITE_DATA |
    *      ACE4_WRITE_ATTRIBUTES |
    *      ACE4_WRITE_ACL |
    *      ACE4_APPEND_DATA |
    *      ACE4_SYNCHRONIZE
    */
        
   /*
    * ACE4_GENERIC_WRITE -- defined as combination of
    *      ACE4_READ_ACL |
    *      ACE4_WRITE_DATA |
    *      ACE4_WRITE_ATTRIBUTES |
    *      ACE4_WRITE_ACL |
    *      ACE4_APPEND_DATA |
    *      ACE4_SYNCHRONIZE
    */
        

const ACE4_GENERIC_WRITE = 0x00160106;

常量ACE4_GENERIC_WRITE=0x00160106;

   /*
    * ACE4_GENERIC_EXECUTE -- defined as combination of
    *      ACE4_READ_ACL
    *      ACE4_READ_ATTRIBUTES
    *      ACE4_EXECUTE
    *      ACE4_SYNCHRONIZE
    */
   const ACE4_GENERIC_EXECUTE = 0x001200A0;
        
   /*
    * ACE4_GENERIC_EXECUTE -- defined as combination of
    *      ACE4_READ_ACL
    *      ACE4_READ_ATTRIBUTES
    *      ACE4_EXECUTE
    *      ACE4_SYNCHRONIZE
    */
   const ACE4_GENERIC_EXECUTE = 0x001200A0;
        
   /*
    * Access Control Entry definition
    */
   struct nfsace4 {
           acetype4        type;
           aceflag4        flag;
           acemask4        access_mask;
           utf8string      who;
   };
        
   /*
    * Access Control Entry definition
    */
   struct nfsace4 {
           acetype4        type;
           aceflag4        flag;
           acemask4        access_mask;
           utf8string      who;
   };
        
   /*
    * Special data/attribute associated with
    * file types NF4BLK and NF4CHR.
    */
   struct specdata4 {
        
   /*
    * Special data/attribute associated with
    * file types NF4BLK and NF4CHR.
    */
   struct specdata4 {
        
           uint32_t        specdata1;
           uint32_t        specdata2;
   };
        
           uint32_t        specdata1;
           uint32_t        specdata2;
   };
        
   /*
    * Values for fattr4_fh_expire_type
    */
   const   FH4_PERSISTENT          = 0x00000000;
   const   FH4_NOEXPIRE_WITH_OPEN  = 0x00000001;
   const   FH4_VOLATILE_ANY        = 0x00000002;
   const   FH4_VOL_MIGRATION       = 0x00000004;
   const   FH4_VOL_RENAME          = 0x00000008;
        
   /*
    * Values for fattr4_fh_expire_type
    */
   const   FH4_PERSISTENT          = 0x00000000;
   const   FH4_NOEXPIRE_WITH_OPEN  = 0x00000001;
   const   FH4_VOLATILE_ANY        = 0x00000002;
   const   FH4_VOL_MIGRATION       = 0x00000004;
   const   FH4_VOL_RENAME          = 0x00000008;
        
   typedef bitmap4         fattr4_supported_attrs;
   typedef nfs_ftype4      fattr4_type;
   typedef uint32_t        fattr4_fh_expire_type;
   typedef changeid4       fattr4_change;
   typedef uint64_t        fattr4_size;
   typedef bool            fattr4_link_support;
   typedef bool            fattr4_symlink_support;
   typedef bool            fattr4_named_attr;
   typedef fsid4           fattr4_fsid;
   typedef bool            fattr4_unique_handles;
   typedef uint32_t        fattr4_lease_time;
   typedef nfsstat4        fattr4_rdattr_error;
        
   typedef bitmap4         fattr4_supported_attrs;
   typedef nfs_ftype4      fattr4_type;
   typedef uint32_t        fattr4_fh_expire_type;
   typedef changeid4       fattr4_change;
   typedef uint64_t        fattr4_size;
   typedef bool            fattr4_link_support;
   typedef bool            fattr4_symlink_support;
   typedef bool            fattr4_named_attr;
   typedef fsid4           fattr4_fsid;
   typedef bool            fattr4_unique_handles;
   typedef uint32_t        fattr4_lease_time;
   typedef nfsstat4        fattr4_rdattr_error;
        
   typedef nfsace4         fattr4_acl<>;
   typedef uint32_t        fattr4_aclsupport;
   typedef bool            fattr4_archive;
   typedef bool            fattr4_cansettime;
   typedef bool            fattr4_case_insensitive;
   typedef bool            fattr4_case_preserving;
   typedef bool            fattr4_chown_restricted;
   typedef uint64_t        fattr4_fileid;
   typedef uint64_t        fattr4_files_avail;
   typedef nfs_fh4         fattr4_filehandle;
   typedef uint64_t        fattr4_files_free;
   typedef uint64_t        fattr4_files_total;
   typedef fs_locations4   fattr4_fs_locations;
   typedef bool            fattr4_hidden;
   typedef bool            fattr4_homogeneous;
   typedef uint64_t        fattr4_maxfilesize;
   typedef uint32_t        fattr4_maxlink;
   typedef uint32_t        fattr4_maxname;
   typedef uint64_t        fattr4_maxread;
   typedef uint64_t        fattr4_maxwrite;
   typedef utf8string      fattr4_mimetype;
        
   typedef nfsace4         fattr4_acl<>;
   typedef uint32_t        fattr4_aclsupport;
   typedef bool            fattr4_archive;
   typedef bool            fattr4_cansettime;
   typedef bool            fattr4_case_insensitive;
   typedef bool            fattr4_case_preserving;
   typedef bool            fattr4_chown_restricted;
   typedef uint64_t        fattr4_fileid;
   typedef uint64_t        fattr4_files_avail;
   typedef nfs_fh4         fattr4_filehandle;
   typedef uint64_t        fattr4_files_free;
   typedef uint64_t        fattr4_files_total;
   typedef fs_locations4   fattr4_fs_locations;
   typedef bool            fattr4_hidden;
   typedef bool            fattr4_homogeneous;
   typedef uint64_t        fattr4_maxfilesize;
   typedef uint32_t        fattr4_maxlink;
   typedef uint32_t        fattr4_maxname;
   typedef uint64_t        fattr4_maxread;
   typedef uint64_t        fattr4_maxwrite;
   typedef utf8string      fattr4_mimetype;
        
   typedef mode4           fattr4_mode;
   typedef bool            fattr4_no_trunc;
   typedef uint32_t        fattr4_numlinks;
   typedef utf8string      fattr4_owner;
   typedef utf8string      fattr4_owner_group;
   typedef uint64_t        fattr4_quota_avail_hard;
   typedef uint64_t        fattr4_quota_avail_soft;
   typedef uint64_t        fattr4_quota_used;
   typedef specdata4       fattr4_rawdev;
   typedef uint64_t        fattr4_space_avail;
   typedef uint64_t        fattr4_space_free;
   typedef uint64_t        fattr4_space_total;
   typedef uint64_t        fattr4_space_used;
   typedef bool            fattr4_system;
   typedef nfstime4        fattr4_time_access;
   typedef settime4        fattr4_time_access_set;
   typedef nfstime4        fattr4_time_backup;
   typedef nfstime4        fattr4_time_create;
   typedef nfstime4        fattr4_time_delta;
   typedef nfstime4        fattr4_time_metadata;
   typedef nfstime4        fattr4_time_modify;
   typedef settime4        fattr4_time_modify_set;
        
   typedef mode4           fattr4_mode;
   typedef bool            fattr4_no_trunc;
   typedef uint32_t        fattr4_numlinks;
   typedef utf8string      fattr4_owner;
   typedef utf8string      fattr4_owner_group;
   typedef uint64_t        fattr4_quota_avail_hard;
   typedef uint64_t        fattr4_quota_avail_soft;
   typedef uint64_t        fattr4_quota_used;
   typedef specdata4       fattr4_rawdev;
   typedef uint64_t        fattr4_space_avail;
   typedef uint64_t        fattr4_space_free;
   typedef uint64_t        fattr4_space_total;
   typedef uint64_t        fattr4_space_used;
   typedef bool            fattr4_system;
   typedef nfstime4        fattr4_time_access;
   typedef settime4        fattr4_time_access_set;
   typedef nfstime4        fattr4_time_backup;
   typedef nfstime4        fattr4_time_create;
   typedef nfstime4        fattr4_time_delta;
   typedef nfstime4        fattr4_time_metadata;
   typedef nfstime4        fattr4_time_modify;
   typedef settime4        fattr4_time_modify_set;
        
   /*
    * Mandatory Attributes
    */
   const FATTR4_SUPPORTED_ATTRS    = 0;
   const FATTR4_TYPE               = 1;
   const FATTR4_FH_EXPIRE_TYPE     = 2;
   const FATTR4_CHANGE             = 3;
   const FATTR4_SIZE               = 4;
   const FATTR4_LINK_SUPPORT       = 5;
   const FATTR4_SYMLINK_SUPPORT    = 6;
   const FATTR4_NAMED_ATTR         = 7;
   const FATTR4_FSID               = 8;
   const FATTR4_UNIQUE_HANDLES     = 9;
   const FATTR4_LEASE_TIME         = 10;
   const FATTR4_RDATTR_ERROR       = 11;
        
   /*
    * Mandatory Attributes
    */
   const FATTR4_SUPPORTED_ATTRS    = 0;
   const FATTR4_TYPE               = 1;
   const FATTR4_FH_EXPIRE_TYPE     = 2;
   const FATTR4_CHANGE             = 3;
   const FATTR4_SIZE               = 4;
   const FATTR4_LINK_SUPPORT       = 5;
   const FATTR4_SYMLINK_SUPPORT    = 6;
   const FATTR4_NAMED_ATTR         = 7;
   const FATTR4_FSID               = 8;
   const FATTR4_UNIQUE_HANDLES     = 9;
   const FATTR4_LEASE_TIME         = 10;
   const FATTR4_RDATTR_ERROR       = 11;
        
   /*
    * Recommended Attributes
    */
   const FATTR4_ACL                = 12;
   const FATTR4_ACLSUPPORT         = 13;
   const FATTR4_ARCHIVE            = 14;
   const FATTR4_CANSETTIME         = 15;
   const FATTR4_CASE_INSENSITIVE   = 16;
        
   /*
    * Recommended Attributes
    */
   const FATTR4_ACL                = 12;
   const FATTR4_ACLSUPPORT         = 13;
   const FATTR4_ARCHIVE            = 14;
   const FATTR4_CANSETTIME         = 15;
   const FATTR4_CASE_INSENSITIVE   = 16;
        
   const FATTR4_CASE_PRESERVING    = 17;
   const FATTR4_CHOWN_RESTRICTED   = 18;
   const FATTR4_FILEHANDLE         = 19;
   const FATTR4_FILEID             = 20;
   const FATTR4_FILES_AVAIL        = 21;
   const FATTR4_FILES_FREE         = 22;
   const FATTR4_FILES_TOTAL        = 23;
   const FATTR4_FS_LOCATIONS       = 24;
   const FATTR4_HIDDEN             = 25;
   const FATTR4_HOMOGENEOUS        = 26;
   const FATTR4_MAXFILESIZE        = 27;
   const FATTR4_MAXLINK            = 28;
   const FATTR4_MAXNAME            = 29;
   const FATTR4_MAXREAD            = 30;
   const FATTR4_MAXWRITE           = 31;
   const FATTR4_MIMETYPE           = 32;
   const FATTR4_MODE               = 33;
   const FATTR4_NO_TRUNC           = 34;
   const FATTR4_NUMLINKS           = 35;
   const FATTR4_OWNER              = 36;
   const FATTR4_OWNER_GROUP        = 37;
   const FATTR4_QUOTA_AVAIL_HARD   = 38;
   const FATTR4_QUOTA_AVAIL_SOFT   = 39;
   const FATTR4_QUOTA_USED         = 40;
   const FATTR4_RAWDEV             = 41;
   const FATTR4_SPACE_AVAIL        = 42;
   const FATTR4_SPACE_FREE         = 43;
   const FATTR4_SPACE_TOTAL        = 44;
   const FATTR4_SPACE_USED         = 45;
   const FATTR4_SYSTEM             = 46;
   const FATTR4_TIME_ACCESS        = 47;
   const FATTR4_TIME_ACCESS_SET    = 48;
   const FATTR4_TIME_BACKUP        = 49;
   const FATTR4_TIME_CREATE        = 50;
   const FATTR4_TIME_DELTA         = 51;
   const FATTR4_TIME_METADATA      = 52;
   const FATTR4_TIME_MODIFY        = 53;
   const FATTR4_TIME_MODIFY_SET    = 54;
        
   const FATTR4_CASE_PRESERVING    = 17;
   const FATTR4_CHOWN_RESTRICTED   = 18;
   const FATTR4_FILEHANDLE         = 19;
   const FATTR4_FILEID             = 20;
   const FATTR4_FILES_AVAIL        = 21;
   const FATTR4_FILES_FREE         = 22;
   const FATTR4_FILES_TOTAL        = 23;
   const FATTR4_FS_LOCATIONS       = 24;
   const FATTR4_HIDDEN             = 25;
   const FATTR4_HOMOGENEOUS        = 26;
   const FATTR4_MAXFILESIZE        = 27;
   const FATTR4_MAXLINK            = 28;
   const FATTR4_MAXNAME            = 29;
   const FATTR4_MAXREAD            = 30;
   const FATTR4_MAXWRITE           = 31;
   const FATTR4_MIMETYPE           = 32;
   const FATTR4_MODE               = 33;
   const FATTR4_NO_TRUNC           = 34;
   const FATTR4_NUMLINKS           = 35;
   const FATTR4_OWNER              = 36;
   const FATTR4_OWNER_GROUP        = 37;
   const FATTR4_QUOTA_AVAIL_HARD   = 38;
   const FATTR4_QUOTA_AVAIL_SOFT   = 39;
   const FATTR4_QUOTA_USED         = 40;
   const FATTR4_RAWDEV             = 41;
   const FATTR4_SPACE_AVAIL        = 42;
   const FATTR4_SPACE_FREE         = 43;
   const FATTR4_SPACE_TOTAL        = 44;
   const FATTR4_SPACE_USED         = 45;
   const FATTR4_SYSTEM             = 46;
   const FATTR4_TIME_ACCESS        = 47;
   const FATTR4_TIME_ACCESS_SET    = 48;
   const FATTR4_TIME_BACKUP        = 49;
   const FATTR4_TIME_CREATE        = 50;
   const FATTR4_TIME_DELTA         = 51;
   const FATTR4_TIME_METADATA      = 52;
   const FATTR4_TIME_MODIFY        = 53;
   const FATTR4_TIME_MODIFY_SET    = 54;
        
   typedef opaque  attrlist4<>;
        
   typedef opaque  attrlist4<>;
        
   /*
    * File attribute container
    */
   struct fattr4 {
           bitmap4         attrmask;
           attrlist4       attr_vals;
        
   /*
    * File attribute container
    */
   struct fattr4 {
           bitmap4         attrmask;
           attrlist4       attr_vals;
        

};

};

   /*
    * Change info for the client
    */
   struct change_info4 {
           bool            atomic;
           changeid4       before;
           changeid4       after;
   };
        
   /*
    * Change info for the client
    */
   struct change_info4 {
           bool            atomic;
           changeid4       before;
           changeid4       after;
   };
        
   struct clientaddr4 {
           /* see struct rpcb in RFC 1833 */
           string r_netid<>;               /* network id */
           string r_addr<>;                /* universal address */
   };
        
   struct clientaddr4 {
           /* see struct rpcb in RFC 1833 */
           string r_netid<>;               /* network id */
           string r_addr<>;                /* universal address */
   };
        
   /*
    * Callback program info as provided by the client
    */
   struct cb_client4 {
           unsigned int    cb_program;
           clientaddr4     cb_location;
   };
        
   /*
    * Callback program info as provided by the client
    */
   struct cb_client4 {
           unsigned int    cb_program;
           clientaddr4     cb_location;
   };
        
   /*
    * Client ID
    */
   struct nfs_client_id4 {
           verifier4       verifier;
           opaque          id<>;
   };
        
   /*
    * Client ID
    */
   struct nfs_client_id4 {
           verifier4       verifier;
           opaque          id<>;
   };
        
   struct nfs_lockowner4 {
           clientid4       clientid;
           opaque          owner<>;
   };
        
   struct nfs_lockowner4 {
           clientid4       clientid;
           opaque          owner<>;
   };
        
   enum nfs_lock_type4 {
           READ_LT         = 1,
           WRITE_LT        = 2,
           READW_LT        = 3,    /* blocking read */
           WRITEW_LT       = 4     /* blocking write */
   };
        
   enum nfs_lock_type4 {
           READ_LT         = 1,
           WRITE_LT        = 2,
           READW_LT        = 3,    /* blocking read */
           WRITEW_LT       = 4     /* blocking write */
   };
        
   /*
    * ACCESS: Check access permission
    */
        
   /*
    * ACCESS: Check access permission
    */
        
   const ACCESS4_READ      = 0x00000001;
   const ACCESS4_LOOKUP    = 0x00000002;
   const ACCESS4_MODIFY    = 0x00000004;
   const ACCESS4_EXTEND    = 0x00000008;
   const ACCESS4_DELETE    = 0x00000010;
   const ACCESS4_EXECUTE   = 0x00000020;
        
   const ACCESS4_READ      = 0x00000001;
   const ACCESS4_LOOKUP    = 0x00000002;
   const ACCESS4_MODIFY    = 0x00000004;
   const ACCESS4_EXTEND    = 0x00000008;
   const ACCESS4_DELETE    = 0x00000010;
   const ACCESS4_EXECUTE   = 0x00000020;
        
   struct ACCESS4args {
           /* CURRENT_FH: object */
           uint32_t        access;
   };
        
   struct ACCESS4args {
           /* CURRENT_FH: object */
           uint32_t        access;
   };
        
   struct ACCESS4resok {
           uint32_t        supported;
           uint32_t        access;
   };
        
   struct ACCESS4resok {
           uint32_t        supported;
           uint32_t        access;
   };
        
   union ACCESS4res switch (nfsstat4 status) {
    case NFS4_OK:
            ACCESS4resok   resok4;
    default:
            void;
   };
        
   union ACCESS4res switch (nfsstat4 status) {
    case NFS4_OK:
            ACCESS4resok   resok4;
    default:
            void;
   };
        
   /*
    * CLOSE: Close a file and release share locks
    */
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        stateid;
   };
        
   /*
    * CLOSE: Close a file and release share locks
    */
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        stateid;
   };
        
   union CLOSE4res switch (nfsstat4 status) {
    case NFS4_OK:
            stateid4       stateid;
    default:
            void;
   };
        
   union CLOSE4res switch (nfsstat4 status) {
    case NFS4_OK:
            stateid4       stateid;
    default:
            void;
   };
        
   /*
    * COMMIT: Commit cached data on server to stable storage
    */
   struct COMMIT4args {
           /* CURRENT_FH: file */
           offset4         offset;
           count4          count;
   };
        
   /*
    * COMMIT: Commit cached data on server to stable storage
    */
   struct COMMIT4args {
           /* CURRENT_FH: file */
           offset4         offset;
           count4          count;
   };
        
   struct COMMIT4resok {
           verifier4       writeverf;
   };
        
   struct COMMIT4resok {
           verifier4       writeverf;
   };
        
   union COMMIT4res switch (nfsstat4 status) {
    case NFS4_OK:
            COMMIT4resok   resok4;
    default:
            void;
   };
        
   union COMMIT4res switch (nfsstat4 status) {
    case NFS4_OK:
            COMMIT4resok   resok4;
    default:
            void;
   };
        
   /*
    * CREATE: Create a file
    */
   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4      linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4      devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
   };
        
   /*
    * CREATE: Create a file
    */
   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4      linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4      devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
   };
        
   struct CREATE4args {
           /* CURRENT_FH: directory for creation */
           component4      objname;
           createtype4     objtype;
   };
        
   struct CREATE4args {
           /* CURRENT_FH: directory for creation */
           component4      objname;
           createtype4     objtype;
   };
        
   struct CREATE4resok {
           change_info4     cinfo;
   };
        
   struct CREATE4resok {
           change_info4     cinfo;
   };
        
   union CREATE4res switch (nfsstat4 status) {
    case NFS4_OK:
            CREATE4resok resok4;
    default:
            void;
   };
        
   union CREATE4res switch (nfsstat4 status) {
    case NFS4_OK:
            CREATE4resok resok4;
    default:
            void;
   };
        
   /*
    * DELEGPURGE: Purge Delegations Awaiting Recovery
    */
   struct DELEGPURGE4args {
        
   /*
    * DELEGPURGE: Purge Delegations Awaiting Recovery
    */
   struct DELEGPURGE4args {
        
           clientid4       clientid;
   };
        
           clientid4       clientid;
   };
        
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
   /*
    * DELEGRETURN: Return a delegation
    */
   struct DELEGRETURN4args {
           stateid4        stateid;
   };
        
   /*
    * DELEGRETURN: Return a delegation
    */
   struct DELEGRETURN4args {
           stateid4        stateid;
   };
        
   struct DELEGRETURN4res {
           nfsstat4        status;
   };
        
   struct DELEGRETURN4res {
           nfsstat4        status;
   };
        
   /*
    * GETATTR: Get file attributes
    */
   struct GETATTR4args {
           /* CURRENT_FH: directory or file */
           bitmap4         attr_request;
   };
        
   /*
    * GETATTR: Get file attributes
    */
   struct GETATTR4args {
           /* CURRENT_FH: directory or file */
           bitmap4         attr_request;
   };
        
   struct GETATTR4resok {
           fattr4          obj_attributes;
   };
        
   struct GETATTR4resok {
           fattr4          obj_attributes;
   };
        
   union GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            GETATTR4resok  resok4;
    default:
            void;
   };
        
   union GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            GETATTR4resok  resok4;
    default:
            void;
   };
        
   /*
    * GETFH: Get current filehandle
    */
   struct GETFH4resok {
           nfs_fh4         object;
   };
        
   /*
    * GETFH: Get current filehandle
    */
   struct GETFH4resok {
           nfs_fh4         object;
   };
        
   union GETFH4res switch (nfsstat4 status) {
    case NFS4_OK:
           GETFH4resok     resok4;
    default:
        
   union GETFH4res switch (nfsstat4 status) {
    case NFS4_OK:
           GETFH4resok     resok4;
    default:
        
           void;
   };
        
           void;
   };
        
   /*
    * LINK: Create link to an object
    */
   struct LINK4args {
           /* SAVED_FH: source object */
           /* CURRENT_FH: target directory */
           component4      newname;
   };
        
   /*
    * LINK: Create link to an object
    */
   struct LINK4args {
           /* SAVED_FH: source object */
           /* CURRENT_FH: target directory */
           component4      newname;
   };
        
   struct LINK4resok {
           change_info4    cinfo;
   };
        
   struct LINK4resok {
           change_info4    cinfo;
   };
        
   union LINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LINK4resok resok4;
    default:
            void;
   };
        
   union LINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LINK4resok resok4;
    default:
            void;
   };
        
   /*
    * LOCK/LOCKT/LOCKU: Record lock management
    */
   struct LOCK4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           bool            reclaim;
           stateid4        stateid;
           offset4         offset;
           length4         length;
   };
        
   /*
    * LOCK/LOCKT/LOCKU: Record lock management
    */
   struct LOCK4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           bool            reclaim;
           stateid4        stateid;
           offset4         offset;
           length4         length;
   };
        
   struct LOCK4denied {
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };
        
   struct LOCK4denied {
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };
        
   union LOCK4res switch (nfsstat4 status) {
    case NFS4_OK:
            stateid4       stateid;
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    default:
        
   union LOCK4res switch (nfsstat4 status) {
    case NFS4_OK:
            stateid4       stateid;
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    default:
        
            void;
   };
        
            void;
   };
        
   struct LOCKT4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };
        
   struct LOCKT4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };
        
   union LOCKT4res switch (nfsstat4 status) {
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    case NFS4_OK:
            void;
    default:
            void;
   };
        
   union LOCKT4res switch (nfsstat4 status) {
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    case NFS4_OK:
            void;
    default:
            void;
   };
        
   struct LOCKU4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           stateid4        stateid;
           offset4         offset;
           length4         length;
   };
        
   struct LOCKU4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           stateid4        stateid;
           offset4         offset;
           length4         length;
   };
        
   union LOCKU4res switch (nfsstat4 status) {
    case   NFS4_OK:
            stateid4       stateid;
    default:
            void;
   };
        
   union LOCKU4res switch (nfsstat4 status) {
    case   NFS4_OK:
            stateid4       stateid;
    default:
            void;
   };
        
   /*
    * LOOKUP: Lookup filename
    */
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           pathname4       path;
   };
        
   /*
    * LOOKUP: Lookup filename
    */
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           pathname4       path;
   };
        
   struct LOOKUP4res {
           /* CURRENT_FH: object */
           nfsstat4        status;
   };
        
   struct LOOKUP4res {
           /* CURRENT_FH: object */
           nfsstat4        status;
   };
        
   /*
    * LOOKUPP: Lookup parent directory
    */
   struct LOOKUPP4res {
           /* CURRENT_FH: directory */
           nfsstat4        status;
   };
        
   /*
    * LOOKUPP: Lookup parent directory
    */
   struct LOOKUPP4res {
           /* CURRENT_FH: directory */
           nfsstat4        status;
   };
        
   /*
    * NVERIFY: Verify attributes different
    */
   struct NVERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   /*
    * NVERIFY: Verify attributes different
    */
   struct NVERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   struct NVERIFY4res {
           nfsstat4        status;
   };
        
   struct NVERIFY4res {
           nfsstat4        status;
   };
        
   /*
    * Various definitions for OPEN
    */
   enum createmode4 {
           UNCHECKED4      = 0,
           GUARDED4        = 1,
           EXCLUSIVE4      = 2
   };
        
   /*
    * Various definitions for OPEN
    */
   enum createmode4 {
           UNCHECKED4      = 0,
           GUARDED4        = 1,
           EXCLUSIVE4      = 2
   };
        
   union createhow4 switch (createmode4 mode) {
    case UNCHECKED4:
    case GUARDED4:
            fattr4         createattrs;
    case EXCLUSIVE4:
            verifier4      createverf;
   };
        
   union createhow4 switch (createmode4 mode) {
    case UNCHECKED4:
    case GUARDED4:
            fattr4         createattrs;
    case EXCLUSIVE4:
            verifier4      createverf;
   };
        
   enum opentype4 {
           OPEN4_NOCREATE  = 0,
           OPEN4_CREATE    = 1
   };
        
   enum opentype4 {
           OPEN4_NOCREATE  = 0,
           OPEN4_CREATE    = 1
   };
        
   union openflag4 switch (opentype4 opentype) {
    case OPEN4_CREATE:
            createhow4     how;
    default:
            void;
   };
        
   union openflag4 switch (opentype4 opentype) {
    case OPEN4_CREATE:
            createhow4     how;
    default:
            void;
   };
        
   /* Next definitions used for OPEN delegation */
   enum limit_by4 {
           NFS_LIMIT_SIZE          = 1,
           NFS_LIMIT_BLOCKS        = 2
           /* others as needed */
   };
        
   /* Next definitions used for OPEN delegation */
   enum limit_by4 {
           NFS_LIMIT_SIZE          = 1,
           NFS_LIMIT_BLOCKS        = 2
           /* others as needed */
   };
        
   struct nfs_modified_limit4 {
           uint32_t        num_blocks;
           uint32_t        bytes_per_block;
   };
        
   struct nfs_modified_limit4 {
           uint32_t        num_blocks;
           uint32_t        bytes_per_block;
   };
        
   union nfs_space_limit4 switch (limit_by4 limitby) {
    /* limit specified as file size */
    case NFS_LIMIT_SIZE:
            uint64_t               filesize;
    /* limit specified by number of blocks */
    case NFS_LIMIT_BLOCKS:
            nfs_modified_limit4    mod_blocks;
   } ;
        
   union nfs_space_limit4 switch (limit_by4 limitby) {
    /* limit specified as file size */
    case NFS_LIMIT_SIZE:
            uint64_t               filesize;
    /* limit specified by number of blocks */
    case NFS_LIMIT_BLOCKS:
            nfs_modified_limit4    mod_blocks;
   } ;
        
   /*
    * Share Access and Deny constants for open argument
    */
   const OPEN4_SHARE_ACCESS_READ   = 0x00000001;
   const OPEN4_SHARE_ACCESS_WRITE  = 0x00000002;
   const OPEN4_SHARE_ACCESS_BOTH   = 0x00000003;
        
   /*
    * Share Access and Deny constants for open argument
    */
   const OPEN4_SHARE_ACCESS_READ   = 0x00000001;
   const OPEN4_SHARE_ACCESS_WRITE  = 0x00000002;
   const OPEN4_SHARE_ACCESS_BOTH   = 0x00000003;
        
   const OPEN4_SHARE_DENY_NONE     = 0x00000000;
   const OPEN4_SHARE_DENY_READ     = 0x00000001;
   const OPEN4_SHARE_DENY_WRITE    = 0x00000002;
   const OPEN4_SHARE_DENY_BOTH     = 0x00000003;
        
   const OPEN4_SHARE_DENY_NONE     = 0x00000000;
   const OPEN4_SHARE_DENY_READ     = 0x00000001;
   const OPEN4_SHARE_DENY_WRITE    = 0x00000002;
   const OPEN4_SHARE_DENY_BOTH     = 0x00000003;
        
   enum open_delegation_type4 {
           OPEN_DELEGATE_NONE      = 0,
           OPEN_DELEGATE_READ      = 1,
           OPEN_DELEGATE_WRITE     = 2
   };
        
   enum open_delegation_type4 {
           OPEN_DELEGATE_NONE      = 0,
           OPEN_DELEGATE_READ      = 1,
           OPEN_DELEGATE_WRITE     = 2
   };
        
   enum open_claim_type4 {
           CLAIM_NULL              = 0,
           CLAIM_PREVIOUS          = 1,
           CLAIM_DELEGATE_CUR      = 2,
           CLAIM_DELEGATE_PREV     = 3
   };
        
   enum open_claim_type4 {
           CLAIM_NULL              = 0,
           CLAIM_PREVIOUS          = 1,
           CLAIM_DELEGATE_CUR      = 2,
           CLAIM_DELEGATE_PREV     = 3
   };
        
   struct open_claim_delegate_cur4 {
           pathname4       file;
        
   struct open_claim_delegate_cur4 {
           pathname4       file;
        
           stateid4        delegate_stateid;
   };
        
           stateid4        delegate_stateid;
   };
        
   union open_claim4 switch (open_claim_type4 claim) {
    /*
     * No special rights to file. Ordinary OPEN of the specified file.
     */
    case CLAIM_NULL:
           /* CURRENT_FH: directory */
           pathname4       file;
        
   union open_claim4 switch (open_claim_type4 claim) {
    /*
     * No special rights to file. Ordinary OPEN of the specified file.
     */
    case CLAIM_NULL:
           /* CURRENT_FH: directory */
           pathname4       file;
        
    /*
     * Right to the file established by an open previous to server
     * reboot.  File identified by filehandle obtained at that time
     * rather than by name.
     */
        
    /*
     * Right to the file established by an open previous to server
     * reboot.  File identified by filehandle obtained at that time
     * rather than by name.
     */
        
    case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           uint32_t        delegate_type;
        
    case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           uint32_t        delegate_type;
        
    /*
     * Right to file based on a delegation granted by the server.
     * File is specified by name.
     */
    case CLAIM_DELEGATE_CUR:
           /* CURRENT_FH: directory */
           open_claim_delegate_cur4        delegate_cur_info;
        
    /*
     * Right to file based on a delegation granted by the server.
     * File is specified by name.
     */
    case CLAIM_DELEGATE_CUR:
           /* CURRENT_FH: directory */
           open_claim_delegate_cur4        delegate_cur_info;
        
    /* Right to file based on a delegation granted to a previous boot
     * instance of the client.  File is specified by name.
     */
    case CLAIM_DELEGATE_PREV:
            /* CURRENT_FH: directory */
           pathname4       file_delegate_prev;
   };
        
    /* Right to file based on a delegation granted to a previous boot
     * instance of the client.  File is specified by name.
     */
    case CLAIM_DELEGATE_PREV:
            /* CURRENT_FH: directory */
           pathname4       file_delegate_prev;
   };
        
   /*
    * OPEN: Open a file, potentially receiving an open delegation
    */
   struct OPEN4args {
           open_claim4     claim;
           openflag4       openhow;
           nfs_lockowner4  owner;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   /*
    * OPEN: Open a file, potentially receiving an open delegation
    */
   struct OPEN4args {
           open_claim4     claim;
           openflag4       openhow;
           nfs_lockowner4  owner;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   struct open_read_delegation4 {
           stateid4        stateid;        /* Stateid for delegation*/
           bool            recall;         /* Pre-recalled flag for
                                              delegations obtained
                                              by reclaim
                                              (CLAIM_PREVIOUS) */
           nfsace4         permissions;    /* Defines users who don't
                                              need an ACCESS call to
                                              open for read */
   };
        
   struct open_read_delegation4 {
           stateid4        stateid;        /* Stateid for delegation*/
           bool            recall;         /* Pre-recalled flag for
                                              delegations obtained
                                              by reclaim
                                              (CLAIM_PREVIOUS) */
           nfsace4         permissions;    /* Defines users who don't
                                              need an ACCESS call to
                                              open for read */
   };
        
   struct open_write_delegation4 {
           stateid4        stateid;        /* Stateid for delegation */
           bool            recall;         /* Pre-recalled flag for
                                              delegations obtained
                                              by reclaim
                                              (CLAIM_PREVIOUS) */
           nfs_space_limit4 space_limit;   /* Defines condition that
                                              the client must check to
                                              determine whether the
                                              file needs to be flushed
                                              to the server on close.
                                              */
           nfsace4         permissions;    /* Defines users who don't
                                              need an ACCESS call as
                                              part of a delegated
                                              open. */
   };
        
   struct open_write_delegation4 {
           stateid4        stateid;        /* Stateid for delegation */
           bool            recall;         /* Pre-recalled flag for
                                              delegations obtained
                                              by reclaim
                                              (CLAIM_PREVIOUS) */
           nfs_space_limit4 space_limit;   /* Defines condition that
                                              the client must check to
                                              determine whether the
                                              file needs to be flushed
                                              to the server on close.
                                              */
           nfsace4         permissions;    /* Defines users who don't
                                              need an ACCESS call as
                                              part of a delegated
                                              open. */
   };
        
   union open_delegation4
   switch (open_delegation_type4 delegation_type) {
           case OPEN_DELEGATE_NONE:
                   void;
           case OPEN_DELEGATE_READ:
                   open_read_delegation4 read;
           case OPEN_DELEGATE_WRITE:
                   open_write_delegation4 write;
   };
        
   union open_delegation4
   switch (open_delegation_type4 delegation_type) {
           case OPEN_DELEGATE_NONE:
                   void;
           case OPEN_DELEGATE_READ:
                   open_read_delegation4 read;
           case OPEN_DELEGATE_WRITE:
                   open_write_delegation4 write;
   };
        
   /*
    * Result flags
    */
   /* Mandatory locking is in effect for this file. */
   const OPEN4_RESULT_MLOCK        = 0x00000001;
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
        
   /*
    * Result flags
    */
   /* Mandatory locking is in effect for this file. */
   const OPEN4_RESULT_MLOCK        = 0x00000001;
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
        

struct OPEN4resok {

结构OPEN4resok{

           stateid4        stateid;        /* Stateid for open */
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
           open_delegation4 delegation;    /* Info on any open
                                              delegation */
   };
        
           stateid4        stateid;        /* Stateid for open */
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
           open_delegation4 delegation;    /* Info on any open
                                              delegation */
   };
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
           void;
   };
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
           void;
   };
        
   /*
    * OPENATTR: open named attributes directory
    */
   struct OPENATTR4res {
           /* CURRENT_FH: name attr directory*/
           nfsstat4        status;
   };
        
   /*
    * OPENATTR: open named attributes directory
    */
   struct OPENATTR4res {
           /* CURRENT_FH: name attr directory*/
           nfsstat4        status;
   };
        
   /*
    * OPEN_CONFIRM: confirm the open
    */
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           seqid4          seqid;
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
   };
        
   /*
    * OPEN_CONFIRM: confirm the open
    */
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           seqid4          seqid;
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
   };
        
   struct OPEN_CONFIRM4resok {
           stateid4        stateid;
   };
        
   struct OPEN_CONFIRM4resok {
           stateid4        stateid;
   };
        
   union OPEN_CONFIRM4res switch (nfsstat4 status) {
    case NFS4_OK:
            OPEN_CONFIRM4resok     resok4;
    default:
            void;
   };
        
   union OPEN_CONFIRM4res switch (nfsstat4 status) {
    case NFS4_OK:
            OPEN_CONFIRM4resok     resok4;
    default:
            void;
   };
        
   /*
    * OPEN_DOWNGRADE: downgrade the access/deny for a file
    */
   struct OPEN_DOWNGRADE4args {
        
   /*
    * OPEN_DOWNGRADE: downgrade the access/deny for a file
    */
   struct OPEN_DOWNGRADE4args {
        
           /* CURRENT_FH: opened file */
           stateid4        stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
           /* CURRENT_FH: opened file */
           stateid4        stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   struct OPEN_DOWNGRADE4resok {
              stateid4        stateid;
   };
        
   struct OPEN_DOWNGRADE4resok {
              stateid4        stateid;
   };
        
   union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
    case NFS4_OK:
           OPEN_DOWNGRADE4resok    resok4;
    default:
            void;
   };
        
   union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
    case NFS4_OK:
           OPEN_DOWNGRADE4resok    resok4;
    default:
            void;
   };
        
   /*
    * PUTFH: Set current filehandle
    */
   struct PUTFH4args {
           nfs_fh4         object;
   };
        
   /*
    * PUTFH: Set current filehandle
    */
   struct PUTFH4args {
           nfs_fh4         object;
   };
        
   struct PUTFH4res {
           /* CURRENT_FH: */
           nfsstat4        status;
   };
        
   struct PUTFH4res {
           /* CURRENT_FH: */
           nfsstat4        status;
   };
        
   /*
    * PUTPUBFH: Set public filehandle
    */
   struct PUTPUBFH4res {
           /* CURRENT_FH: public fh */
           nfsstat4        status;
   };
        
   /*
    * PUTPUBFH: Set public filehandle
    */
   struct PUTPUBFH4res {
           /* CURRENT_FH: public fh */
           nfsstat4        status;
   };
        
   /*
    * PUTROOTFH: Set root filehandle
    */
   struct PUTROOTFH4res {
           /* CURRENT_FH: root fh */
           nfsstat4        status;
   };
        
   /*
    * PUTROOTFH: Set root filehandle
    */
   struct PUTROOTFH4res {
           /* CURRENT_FH: root fh */
           nfsstat4        status;
   };
        
   /*
    * READ: Read from file
        
   /*
    * READ: Read from file
        
    */
   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };
        
    */
   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };
        
   struct READ4resok {
           bool            eof;
           opaque          data<>;
   };
        
   struct READ4resok {
           bool            eof;
           opaque          data<>;
   };
        
   union READ4res switch (nfsstat4 status) {
    case NFS4_OK:
            READ4resok     resok4;
    default:
            void;
   };
        
   union READ4res switch (nfsstat4 status) {
    case NFS4_OK:
            READ4resok     resok4;
    default:
            void;
   };
        
   /*
    * READDIR: Read directory
    */
   struct READDIR4args {
           /* CURRENT_FH: directory */
           nfs_cookie4     cookie;
           verifier4       cookieverf;
           count4          dircount;
           count4          maxcount;
           bitmap4         attr_request;
   };
        
   /*
    * READDIR: Read directory
    */
   struct READDIR4args {
           /* CURRENT_FH: directory */
           nfs_cookie4     cookie;
           verifier4       cookieverf;
           count4          dircount;
           count4          maxcount;
           bitmap4         attr_request;
   };
        
   struct entry4 {
           nfs_cookie4     cookie;
           component4      name;
           fattr4          attrs;
           entry4          *nextentry;
   };
        
   struct entry4 {
           nfs_cookie4     cookie;
           component4      name;
           fattr4          attrs;
           entry4          *nextentry;
   };
        
   struct dirlist4 {
           entry4          *entries;
           bool            eof;
   };
        
   struct dirlist4 {
           entry4          *entries;
           bool            eof;
   };
        
   struct READDIR4resok {
           verifier4       cookieverf;
           dirlist4        reply;
   };
        
   struct READDIR4resok {
           verifier4       cookieverf;
           dirlist4        reply;
   };
        
   union READDIR4res switch (nfsstat4 status) {
    case NFS4_OK:
            READDIR4resok  resok4;
    default:
            void;
   };
        
   union READDIR4res switch (nfsstat4 status) {
    case NFS4_OK:
            READDIR4resok  resok4;
    default:
            void;
   };
        
   /*
    * READLINK: Read symbolic link
    */
   struct READLINK4resok {
           linktext4       link;
   };
        
   /*
    * READLINK: Read symbolic link
    */
   struct READLINK4resok {
           linktext4       link;
   };
        
   union READLINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            READLINK4resok resok4;
    default:
            void;
   };
        
   union READLINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            READLINK4resok resok4;
    default:
            void;
   };
        
   /*
    * REMOVE: Remove filesystem object
    */
   struct REMOVE4args {
           /* CURRENT_FH: directory */
           component4      target;
   };
        
   /*
    * REMOVE: Remove filesystem object
    */
   struct REMOVE4args {
           /* CURRENT_FH: directory */
           component4      target;
   };
        
   struct REMOVE4resok {
           change_info4    cinfo;
   };
        
   struct REMOVE4resok {
           change_info4    cinfo;
   };
        
   union REMOVE4res switch (nfsstat4 status) {
    case NFS4_OK:
            REMOVE4resok   resok4;
    default:
            void;
   };
        
   union REMOVE4res switch (nfsstat4 status) {
    case NFS4_OK:
            REMOVE4resok   resok4;
    default:
            void;
   };
        
   /*
    * RENAME: Rename directory entry
    */
   struct RENAME4args {
           /* SAVED_FH: source directory */
           component4      oldname;
           /* CURRENT_FH: target directory */
        
   /*
    * RENAME: Rename directory entry
    */
   struct RENAME4args {
           /* SAVED_FH: source directory */
           component4      oldname;
           /* CURRENT_FH: target directory */
        
           component4      newname;
   };
        
           component4      newname;
   };
        
   struct RENAME4resok {
           change_info4    source_cinfo;
           change_info4    target_cinfo;
   };
        
   struct RENAME4resok {
           change_info4    source_cinfo;
           change_info4    target_cinfo;
   };
        
   union RENAME4res switch (nfsstat4 status) {
    case NFS4_OK:
           RENAME4resok    resok4;
    default:
           void;
   };
        
   union RENAME4res switch (nfsstat4 status) {
    case NFS4_OK:
           RENAME4resok    resok4;
    default:
           void;
   };
        
   /*
    * RENEW: Renew a Lease
    */
   struct RENEW4args {
           stateid4        stateid;
   };
        
   /*
    * RENEW: Renew a Lease
    */
   struct RENEW4args {
           stateid4        stateid;
   };
        
   struct RENEW4res {
           nfsstat4        status;
   };
        
   struct RENEW4res {
           nfsstat4        status;
   };
        
   /*
    * RESTOREFH: Restore saved filehandle
    */
        
   /*
    * RESTOREFH: Restore saved filehandle
    */
        
   struct RESTOREFH4res {
           /* CURRENT_FH: value of saved fh */
           nfsstat4        status;
   };
        
   struct RESTOREFH4res {
           /* CURRENT_FH: value of saved fh */
           nfsstat4        status;
   };
        
   /*
    * SAVEFH: Save current filehandle
    */
        
   /*
    * SAVEFH: Save current filehandle
    */
        
   struct SAVEFH4res {
           /* SAVED_FH: value of current fh */
           nfsstat4        status;
   };
        
   struct SAVEFH4res {
           /* SAVED_FH: value of current fh */
           nfsstat4        status;
   };
        
   /*
    * SECINFO: Obtain Available Security Mechanisms
    */
   struct SECINFO4args {
        
   /*
    * SECINFO: Obtain Available Security Mechanisms
    */
   struct SECINFO4args {
        
           /* CURRENT_FH: */
           component4      name;
   };
        
           /* CURRENT_FH: */
           component4      name;
   };
        
   /*
    * From RFC 2203
    */
   enum rpc_gss_svc_t {
           RPC_GSS_SVC_NONE        = 1,
           RPC_GSS_SVC_INTEGRITY   = 2,
           RPC_GSS_SVC_PRIVACY     = 3
   };
        
   /*
    * From RFC 2203
    */
   enum rpc_gss_svc_t {
           RPC_GSS_SVC_NONE        = 1,
           RPC_GSS_SVC_INTEGRITY   = 2,
           RPC_GSS_SVC_PRIVACY     = 3
   };
        
   struct rpcsec_gss_info {
           sec_oid4        oid;
           qop4            qop;
           rpc_gss_svc_t   service;
   };
        
   struct rpcsec_gss_info {
           sec_oid4        oid;
           qop4            qop;
           rpc_gss_svc_t   service;
   };
        
   struct secinfo4 {
           uint32_t        flavor;
           /* null for AUTH_SYS, AUTH_NONE;
              contains rpcsec_gss_info for
              RPCSEC_GSS. */
           opaque          flavor_info<>;
   };
        
   struct secinfo4 {
           uint32_t        flavor;
           /* null for AUTH_SYS, AUTH_NONE;
              contains rpcsec_gss_info for
              RPCSEC_GSS. */
           opaque          flavor_info<>;
   };
        
   typedef secinfo4 SECINFO4resok<>;
        
   typedef secinfo4 SECINFO4resok<>;
        
   union SECINFO4res switch (nfsstat4 status) {
    case NFS4_OK:
            SECINFO4resok resok4;
    default:
            void;
   };
        
   union SECINFO4res switch (nfsstat4 status) {
    case NFS4_OK:
            SECINFO4resok resok4;
    default:
            void;
   };
        
   /*
    * SETATTR: Set attributes
    */
   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;
        
   /*
    * SETATTR: Set attributes
    */
   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;
        

};

};

   struct SETATTR4res {
           nfsstat4        status;
        
   struct SETATTR4res {
           nfsstat4        status;
        
           bitmap4         attrsset;
   };
        
           bitmap4         attrsset;
   };
        
   /*
    * SETCLIENTID
    */
   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
   };
        
   /*
    * SETCLIENTID
    */
   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
   };
        
   struct SETCLIENTID4resok {
           clientid4       clientid;
           verifier4       setclientid_confirm;
   };
        
   struct SETCLIENTID4resok {
           clientid4       clientid;
           verifier4       setclientid_confirm;
   };
        
   union SETCLIENTID4res switch (nfsstat4 status) {
    case NFS4_OK:
            SETCLIENTID4resok      resok4;
    case NFS4ERR_CLID_INUSE:
            clientaddr4    client_using;
    default:
            void;
   };
        
   union SETCLIENTID4res switch (nfsstat4 status) {
    case NFS4_OK:
            SETCLIENTID4resok      resok4;
    case NFS4ERR_CLID_INUSE:
            clientaddr4    client_using;
    default:
            void;
   };
        
   struct SETCLIENTID_CONFIRM4args {
           verifier4       setclientid_confirm;
   };
        
   struct SETCLIENTID_CONFIRM4args {
           verifier4       setclientid_confirm;
   };
        
   struct SETCLIENTID_CONFIRM4res {
           nfsstat4        status;
   };
        
   struct SETCLIENTID_CONFIRM4res {
           nfsstat4        status;
   };
        
   /*
    * VERIFY: Verify attributes same
    */
   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   /*
    * VERIFY: Verify attributes same
    */
   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   struct VERIFY4res {
           nfsstat4        status;
   };
        
   struct VERIFY4res {
           nfsstat4        status;
   };
        
   /*
    * WRITE: Write to file
    */
        
   /*
    * WRITE: Write to file
    */
        
   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };
        
   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };
        
   struct WRITE4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           stable_how4     stable;
           opaque          data<>;
   };
        
   struct WRITE4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           stable_how4     stable;
           opaque          data<>;
   };
        
   struct WRITE4resok {
           count4          count;
           stable_how4     committed;
           verifier4       writeverf;
   };
        
   struct WRITE4resok {
           count4          count;
           stable_how4     committed;
           verifier4       writeverf;
   };
        
   union WRITE4res switch (nfsstat4 status) {
    case NFS4_OK:
            WRITE4resok    resok4;
    default:
            void;
   };
        
   union WRITE4res switch (nfsstat4 status) {
    case NFS4_OK:
            WRITE4resok    resok4;
    default:
            void;
   };
        
   /*
    * Operation arrays
    */
        
   /*
    * Operation arrays
    */
        

enum nfs_opnum4 { OP_ACCESS = 3, OP_CLOSE = 4, OP_COMMIT = 5, OP_CREATE = 6, OP_DELEGPURGE = 7, OP_DELEGRETURN = 8, OP_GETATTR = 9, OP_GETFH = 10, OP_LINK = 11, OP_LOCK = 12, OP_LOCKT = 13, OP_LOCKU = 14, OP_LOOKUP = 15, OP_LOOKUPP = 16, OP_NVERIFY = 17, OP_OPEN = 18,

枚举nfs_opnum4{OP_ACCESS=3,OP_CLOSE=4,OP_COMMIT=5,OP_CREATE=6,OP_delegpuse=7,OP_DELEGRETURN=8,OP_GETATTR=9,OP_GETFH=10,OP_LINK=11,OP_LOCK=12,OP_LOCK=13,OP_LOCKU=14,OP_LOOKUP=15,OP_LOOKUPP=16,OP_inverify=17,OP_OPEN=18,

OP_OPENATTR = 19, OP_OPEN_CONFIRM = 20, OP_OPEN_DOWNGRADE = 21, OP_PUTFH = 22, OP_PUTPUBFH = 23, OP_PUTROOTFH = 24, OP_READ = 25, OP_READDIR = 26, OP_READLINK = 27, OP_REMOVE = 28, OP_RENAME = 29, OP_RENEW = 30, OP_RESTOREFH = 31, OP_SAVEFH = 32, OP_SECINFO = 33, OP_SETATTR = 34, OP_SETCLIENTID = 35, OP_SETCLIENTID_CONFIRM = 36, OP_VERIFY = 37, OP_WRITE = 38 };

OP_OPENATTR=19,OP_OPEN_CONFIRM=20,OP_OPEN_降级=21,OP_PUTFH=22,OP_PUTPUBFH=23,OP_PUTROOTFH=24,OP_READ=25,OP_READDIR=26,OP_READLINK=27,OP_REMOVE=28,OP_重命名=29,OP_续订=30,OP_RESTOREFH=31,OP_SAVEFH=32,OP_SECINFO=33,OP_SETATTR=34,OP_clientid=35,OP_验证,OP_WRITE=38};

   union nfs_argop4 switch (nfs_opnum4 argop) {
    case OP_ACCESS:        ACCESS4args opaccess;
    case OP_CLOSE:         CLOSE4args opclose;
    case OP_COMMIT:        COMMIT4args opcommit;
    case OP_CREATE:        CREATE4args opcreate;
    case OP_DELEGPURGE:    DELEGPURGE4args opdelegpurge;
    case OP_DELEGRETURN:   DELEGRETURN4args opdelegreturn;
    case OP_GETATTR:       GETATTR4args opgetattr;
    case OP_GETFH:         void;
    case OP_LINK:          LINK4args oplink;
    case OP_LOCK:          LOCK4args oplock;
    case OP_LOCKT:         LOCKT4args oplockt;
    case OP_LOCKU:         LOCKU4args oplocku;
    case OP_LOOKUP:        LOOKUP4args oplookup;
    case OP_LOOKUPP:       void;
    case OP_NVERIFY:       NVERIFY4args opnverify;
    case OP_OPEN:          OPEN4args opopen;
    case OP_OPENATTR:      void;
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4args opopen_confirm;
    case OP_OPEN_DOWNGRADE:        OPEN_DOWNGRADE4args opopen_downgrade;
    case OP_PUTFH:         PUTFH4args opputfh;
    case OP_PUTPUBFH:      void;
    case OP_PUTROOTFH:     void;
    case OP_READ:          READ4args opread;
    case OP_READDIR:       READDIR4args opreaddir;
    case OP_READLINK:      void;
        
   union nfs_argop4 switch (nfs_opnum4 argop) {
    case OP_ACCESS:        ACCESS4args opaccess;
    case OP_CLOSE:         CLOSE4args opclose;
    case OP_COMMIT:        COMMIT4args opcommit;
    case OP_CREATE:        CREATE4args opcreate;
    case OP_DELEGPURGE:    DELEGPURGE4args opdelegpurge;
    case OP_DELEGRETURN:   DELEGRETURN4args opdelegreturn;
    case OP_GETATTR:       GETATTR4args opgetattr;
    case OP_GETFH:         void;
    case OP_LINK:          LINK4args oplink;
    case OP_LOCK:          LOCK4args oplock;
    case OP_LOCKT:         LOCKT4args oplockt;
    case OP_LOCKU:         LOCKU4args oplocku;
    case OP_LOOKUP:        LOOKUP4args oplookup;
    case OP_LOOKUPP:       void;
    case OP_NVERIFY:       NVERIFY4args opnverify;
    case OP_OPEN:          OPEN4args opopen;
    case OP_OPENATTR:      void;
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4args opopen_confirm;
    case OP_OPEN_DOWNGRADE:        OPEN_DOWNGRADE4args opopen_downgrade;
    case OP_PUTFH:         PUTFH4args opputfh;
    case OP_PUTPUBFH:      void;
    case OP_PUTROOTFH:     void;
    case OP_READ:          READ4args opread;
    case OP_READDIR:       READDIR4args opreaddir;
    case OP_READLINK:      void;
        
    case OP_REMOVE:        REMOVE4args opremove;
    case OP_RENAME:        RENAME4args oprename;
    case OP_RENEW:         RENEW4args oprenew;
    case OP_RESTOREFH:     void;
    case OP_SAVEFH:        void;
    case OP_SECINFO:       SECINFO4args opsecinfo;
    case OP_SETATTR:       SETATTR4args opsetattr;
    case OP_SETCLIENTID:   SETCLIENTID4args opsetclientid;
    case OP_SETCLIENTID_CONFIRM:   SETCLIENTID_CONFIRM4args
                                           opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;
   };
        
    case OP_REMOVE:        REMOVE4args opremove;
    case OP_RENAME:        RENAME4args oprename;
    case OP_RENEW:         RENEW4args oprenew;
    case OP_RESTOREFH:     void;
    case OP_SAVEFH:        void;
    case OP_SECINFO:       SECINFO4args opsecinfo;
    case OP_SETATTR:       SETATTR4args opsetattr;
    case OP_SETCLIENTID:   SETCLIENTID4args opsetclientid;
    case OP_SETCLIENTID_CONFIRM:   SETCLIENTID_CONFIRM4args
                                           opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;
   };
        
   union nfs_resop4 switch (nfs_opnum4 resop){
    case OP_ACCESS:        ACCESS4res opaccess;
    case OP_CLOSE:         CLOSE4res opclose;
    case OP_COMMIT:        COMMIT4res opcommit;
    case OP_CREATE:        CREATE4res opcreate;
    case OP_DELEGPURGE:    DELEGPURGE4res opdelegpurge;
    case OP_DELEGRETURN:   DELEGRETURN4res opdelegreturn;
    case OP_GETATTR:       GETATTR4res opgetattr;
    case OP_GETFH:         GETFH4res opgetfh;
    case OP_LINK:          LINK4res oplink;
    case OP_LOCK:          LOCK4res oplock;
    case OP_LOCKT:         LOCKT4res oplockt;
    case OP_LOCKU:         LOCKU4res oplocku;
    case OP_LOOKUP:        LOOKUP4res oplookup;
    case OP_LOOKUPP:       LOOKUPP4res oplookupp;
    case OP_NVERIFY:       NVERIFY4res opnverify;
    case OP_OPEN:          OPEN4res opopen;
    case OP_OPENATTR:      OPENATTR4res opopenattr;
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4res opopen_confirm;
    case OP_OPEN_DOWNGRADE:        OPEN_DOWNGRADE4res opopen_downgrade;
    case OP_PUTFH:         PUTFH4res opputfh;
    case OP_PUTPUBFH:      PUTPUBFH4res opputpubfh;
    case OP_PUTROOTFH:     PUTROOTFH4res opputrootfh;
    case OP_READ:          READ4res opread;
    case OP_READDIR:       READDIR4res opreaddir;
    case OP_READLINK:      READLINK4res opreadlink;
    case OP_REMOVE:        REMOVE4res opremove;
    case OP_RENAME:        RENAME4res oprename;
    case OP_RENEW:         RENEW4res oprenew;
    case OP_RESTOREFH:     RESTOREFH4res oprestorefh;
    case OP_SAVEFH:        SAVEFH4res opsavefh;
    case OP_SECINFO:       SECINFO4res opsecinfo;
    case OP_SETATTR:       SETATTR4res opsetattr;
    case OP_SETCLIENTID:   SETCLIENTID4res opsetclientid;
        
   union nfs_resop4 switch (nfs_opnum4 resop){
    case OP_ACCESS:        ACCESS4res opaccess;
    case OP_CLOSE:         CLOSE4res opclose;
    case OP_COMMIT:        COMMIT4res opcommit;
    case OP_CREATE:        CREATE4res opcreate;
    case OP_DELEGPURGE:    DELEGPURGE4res opdelegpurge;
    case OP_DELEGRETURN:   DELEGRETURN4res opdelegreturn;
    case OP_GETATTR:       GETATTR4res opgetattr;
    case OP_GETFH:         GETFH4res opgetfh;
    case OP_LINK:          LINK4res oplink;
    case OP_LOCK:          LOCK4res oplock;
    case OP_LOCKT:         LOCKT4res oplockt;
    case OP_LOCKU:         LOCKU4res oplocku;
    case OP_LOOKUP:        LOOKUP4res oplookup;
    case OP_LOOKUPP:       LOOKUPP4res oplookupp;
    case OP_NVERIFY:       NVERIFY4res opnverify;
    case OP_OPEN:          OPEN4res opopen;
    case OP_OPENATTR:      OPENATTR4res opopenattr;
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4res opopen_confirm;
    case OP_OPEN_DOWNGRADE:        OPEN_DOWNGRADE4res opopen_downgrade;
    case OP_PUTFH:         PUTFH4res opputfh;
    case OP_PUTPUBFH:      PUTPUBFH4res opputpubfh;
    case OP_PUTROOTFH:     PUTROOTFH4res opputrootfh;
    case OP_READ:          READ4res opread;
    case OP_READDIR:       READDIR4res opreaddir;
    case OP_READLINK:      READLINK4res opreadlink;
    case OP_REMOVE:        REMOVE4res opremove;
    case OP_RENAME:        RENAME4res oprename;
    case OP_RENEW:         RENEW4res oprenew;
    case OP_RESTOREFH:     RESTOREFH4res oprestorefh;
    case OP_SAVEFH:        SAVEFH4res opsavefh;
    case OP_SECINFO:       SECINFO4res opsecinfo;
    case OP_SETATTR:       SETATTR4res opsetattr;
    case OP_SETCLIENTID:   SETCLIENTID4res opsetclientid;
        
    case OP_SETCLIENTID_CONFIRM:   SETCLIENTID_CONFIRM4res
                                           opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4res opverify;
    case OP_WRITE:         WRITE4res opwrite;
   };
        
    case OP_SETCLIENTID_CONFIRM:   SETCLIENTID_CONFIRM4res
                                           opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4res opverify;
    case OP_WRITE:         WRITE4res opwrite;
   };
        
   struct COMPOUND4args {
           utf8string      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        
   struct COMPOUND4args {
           utf8string      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        
   struct COMPOUND4res {
           nfsstat4 status;
           utf8string      tag;
           nfs_resop4      resarray<>;
   };
        
   struct COMPOUND4res {
           nfsstat4 status;
           utf8string      tag;
           nfs_resop4      resarray<>;
   };
        
   /*
    * Remote file service routines
    */
   program NFS4_PROGRAM {
           version NFS_V4 {
                   void
                           NFSPROC4_NULL(void) = 0;
        
   /*
    * Remote file service routines
    */
   program NFS4_PROGRAM {
           version NFS_V4 {
                   void
                           NFSPROC4_NULL(void) = 0;
        

COMPOUND4res NFSPROC4_COMPOUND(COMPOUND4args) = 1;

化合物4RES NFSPROC4_化合物(化合物4Args)=1;

           } = 4;
   } = 100003;
        
           } = 4;
   } = 100003;
        
   /*
    * NFS4 Callback Procedure Definitions and Program
    */
        
   /*
    * NFS4 Callback Procedure Definitions and Program
    */
        
   /*
    * CB_GETATTR: Get Current Attributes
    */
   struct CB_GETATTR4args {
           nfs_fh4 fh;
           bitmap4 attr_request;
   };
        
   /*
    * CB_GETATTR: Get Current Attributes
    */
   struct CB_GETATTR4args {
           nfs_fh4 fh;
           bitmap4 attr_request;
   };
        
   struct CB_GETATTR4resok {
           fattr4  obj_attributes;
        
   struct CB_GETATTR4resok {
           fattr4  obj_attributes;
        

};

};

   union CB_GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            CB_GETATTR4resok       resok4;
    default:
            void;
   };
        
   union CB_GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            CB_GETATTR4resok       resok4;
    default:
            void;
   };
        
   /*
    * CB_RECALL: Recall an Open Delegation
    */
   struct CB_RECALL4args {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
   /*
    * CB_RECALL: Recall an Open Delegation
    */
   struct CB_RECALL4args {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
   /*
    * Various definitions for CB_COMPOUND
    */
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4
   };
        
   /*
    * Various definitions for CB_COMPOUND
    */
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4
   };
        
   union nfs_cb_argop4 switch (unsigned argop) {
    case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
   };
        
   union nfs_cb_argop4 switch (unsigned argop) {
    case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
   };
        
   union nfs_cb_resop4 switch (unsigned resop){
    case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4res   opcbrecall;
   };
        
   union nfs_cb_resop4 switch (unsigned resop){
    case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4res   opcbrecall;
   };
        
   struct CB_COMPOUND4args {
           utf8string      tag;
           uint32_t        minorversion;
           nfs_cb_argop4   argarray<>;
   };
        
   struct CB_COMPOUND4args {
           utf8string      tag;
           uint32_t        minorversion;
           nfs_cb_argop4   argarray<>;
   };
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
        
           utf8string      tag;
           nfs_cb_resop4   resarray<>;
   };
        
           utf8string      tag;
           nfs_cb_resop4   resarray<>;
   };
        
   /*
    * Program number is in the transient range since the client
    * will assign the exact transient program number and provide
    * that to the server via the SETCLIENTID operation.
    */
   program NFS4_CALLBACK {
           version NFS_CB {
                   void
                           CB_NULL(void) = 0;
                   CB_COMPOUND4res
                           CB_COMPOUND(CB_COMPOUND4args) = 1;
           } = 1;
   } = 40000000;
        
   /*
    * Program number is in the transient range since the client
    * will assign the exact transient program number and provide
    * that to the server via the SETCLIENTID operation.
    */
   program NFS4_CALLBACK {
           version NFS_CB {
                   void
                           CB_NULL(void) = 0;
                   CB_COMPOUND4res
                           CB_COMPOUND(CB_COMPOUND4args) = 1;
           } = 1;
   } = 40000000;
        
19. Bibliography
19. 参考文献

[Floyd] S. Floyd, V. Jacobson, "The Synchronization of Periodic Routing Messages," IEEE/ACM Transactions on Networking, 2(2), pp. 122-136, April 1994.

[Floyd]S.Floyd,V.Jacobson,“定期路由消息的同步”,IEEE/ACM网络事务,2(2),第122-136页,1994年4月。

[Gray] C. Gray, D. Cheriton, "Leases: An Efficient Fault-Tolerant Mechanism for Distributed File Cache Consistency," Proceedings of the Twelfth Symposium on Operating Systems Principles, p. 202-210, December 1989.

[Gray]C.Gray,D.Cheriton,“租约:分布式文件缓存一致性的有效容错机制”,第十二届操作系统原理研讨会论文集,第。1989年12月202-210日。

   [ISO10646]   "ISO/IEC 10646-1:1993. International Standard --
                Information technology -- Universal Multiple-Octet Coded
                Character Set (UCS) -- Part 1: Architecture and Basic
                Multilingual Plane."
        
   [ISO10646]   "ISO/IEC 10646-1:1993. International Standard --
                Information technology -- Universal Multiple-Octet Coded
                Character Set (UCS) -- Part 1: Architecture and Basic
                Multilingual Plane."
        

[Juszczak] Juszczak, Chet, "Improving the Performance and Correctness of an NFS Server," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, June 1990, pages 53-63. Describes reply cache implementation that avoids work in the server by handling duplicate requests. More important, though listed as a side-effect, the reply cache aids in the avoidance of destructive non-idempotent operation re-application -- improving correctness.

[Juszczak]Juszczak,Chet,“提高NFS服务器的性能和正确性”,USENIX会议记录,USENIX协会,加利福尼亚州伯克利,1990年6月,第53-63页。描述通过处理重复请求来避免在服务器中工作的应答缓存实现。更重要的是,尽管列为副作用,但应答缓存有助于避免破坏性的非幂等运算重新应用——提高正确性。

[Kazar] Kazar, Michael Leon, "Synchronization and Caching Issues in the Andrew File System," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Dallas Winter 1988, pages 27-36. A description of the cache consistency scheme in AFS. Contrasted with other distributed file systems.

[Kazar]Kazar,Michael Leon,“Andrew文件系统中的同步和缓存问题”,USENIX会议记录,USENIX协会,加利福尼亚州伯克利,达拉斯,1988年冬季,第27-36页。AFS中缓存一致性方案的描述。与其他分布式文件系统相比。

[Macklem] Macklem, Rick, "Lessons Learned Tuning the 4.3BSD Reno Implementation of the NFS Protocol," Winter USENIX Conference Proceedings, USENIX Association, Berkeley, CA, January 1991. Describes performance work in tuning the 4.3BSD Reno NFS implementation. Describes performance improvement (reduced CPU loading) through elimination of data copies.

[Macklem]Macklem,Rick,“调整NFS协议的4.3BSD Reno实现的经验教训”,Winter USENIX会议记录,USENIX协会,加利福尼亚州伯克利,1991年1月。描述在调优4.3BSD Reno NFS实现时的性能工作。描述通过消除数据拷贝来提高性能(减少CPU负载)。

[Mogul] Mogul, Jeffrey C., "A Recovery Protocol for Spritely NFS," USENIX File System Workshop Proceedings, Ann Arbor, MI, USENIX Association, Berkeley, CA, May 1992. Second paper on Spritely NFS proposes a lease-based scheme for recovering state of consistency protocol.

[Mogul]Mogul,Jeffrey C.,“Sprity NFS的恢复协议”,USENIX文件系统研讨会论文集,密歇根州安阿伯,USENIX协会,加利福尼亚州伯克利,1992年5月。第二篇关于Spritly NFS的论文提出了一种基于租约的恢复一致性协议状态的方案。

[Nowicki] Nowicki, Bill, "Transport Issues in the Network File System," ACM SIGCOMM newsletter Computer Communication Review, April 1989. A brief description of the basis for the dynamic retransmission work.

[Nowicki]Nowicki,Bill,“网络文件系统中的传输问题”,ACM SIGCOMM通讯《计算机通信评论》,1989年4月。简要说明动态重传工作的基础。

[Pawlowski] Pawlowski, Brian, Ron Hixon, Mark Stein, Joseph Tumminaro, "Network Computing in the UNIX and IBM Mainframe Environment," Uniforum `89 Conf. Proc., (1989) Description of an NFS server implementation for IBM's MVS operating system.

[Pawlowski]Pawlowski,Brian,Ron Hixon,Mark Stein,Joseph Tumminaro,“UNIX和IBM大型机环境中的网络计算”,Uniforum`89 Conf.Proc.,(1989)对IBM MVS操作系统的NFS服务器实现的描述。

[RFC1094] Sun Microsystems, Inc., "NFS: Network File System Protocol Specification", RFC 1094, March 1989.

[RFC1094]Sun Microsystems,Inc.,“NFS:网络文件系统协议规范”,RFC10941989年3月。

[RFC1345] Simonsen, K., "Character Mnemonics & Character Sets", RFC 1345, June 1992.

[RFC1345]Simonsen,K.,“字符助记符和字符集”,RFC13451992年6月。

[RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700, October 1994.

[RFC1700]Reynolds,J.和J.Postel,“分配的数字”,标准2,RFC 1700,1994年10月。

[RFC1813] Callaghan, B., Pawlowski, B. and P. Staubach, "NFS Version 3 Protocol Specification", RFC 1813, June 1995.

[RFC1813]Callaghan,B.,Pawlowski,B.和P.Staubach,“NFS版本3协议规范”,RFC 1813,1995年6月。

[RFC1831] Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification Version 2", RFC 1831, August 1995.

[RFC1831]Srinivasan,R.,“RPC:远程过程调用协议规范版本2”,RFC18311995年8月。

[RFC1832] Srinivasan, R., "XDR: External Data Representation Standard", RFC 1832, August 1995.

[RFC1832]Srinivasan,R.,“XDR:外部数据表示标准”,RFC 1832,1995年8月。

[RFC1833] Srinivasan, R., "Binding Protocols for ONC RPC Version 2", RFC 1833, August 1995.

[RFC1833]Srinivasan,R.,“ONC RPC版本2的绑定协议”,RFC 1833,1995年8月。

[RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", RFC 2025, October 1996.

[RFC2025]Adams,C.,“简单公钥GSS-API机制(SPKM)”,RFC 20252996年10月。

[RFC2054] Callaghan, B., "WebNFS Client Specification", RFC 2054, October 1996.

[RFC2054]Callaghan,B.,“WebNFS客户端规范”,RFC2054,1996年10月。

[RFC2055] Callaghan, B., "WebNFS Server Specification", RFC 2055, October 1996.

[RFC2055]Callaghan,B.,“WebNFS服务器规范”,RFC20551996年10月。

[RFC2078] Linn, J., "Generic Security Service Application Program Interface, Version 2", RFC 2078, January 1997.

[RFC2078]Linn,J.,“通用安全服务应用程序接口,第2版”,RFC 2078,1997年1月。

[RFC2152] Goldsmith, D., "UTF-7 A Mail-Safe Transformation Format of Unicode", RFC 2152, May 1997.

[RFC2152]Goldsmith,D.,“UTF-7一种Unicode的邮件安全转换格式”,RFC 2152,1997年5月。

[RFC2203] Eisler, M., Chiu, A. and L. Ling, "RPCSEC_GSS Protocol Specification", RFC 2203, August 1995.

[RFC2203]Eisler,M.,Chiu,A.和L.Ling,“RPCSEC_GSS协议规范”,RFC 2203,1995年8月。

[RFC2277] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998.

[RFC2277]Alvestrand,H.,“IETF字符集和语言政策”,BCP 18,RFC 2277,1998年1月。

[RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 2279, January 1998.

[RFC2279]Yergeau,F.,“UTF-8,ISO 10646的转换格式”,RFC 2279,1998年1月。

[RFC2623] Eisler, M., "NFS Version 2 and Version 3 Security Issues and the NFS Protocol's Use of RPCSEC_GSS and Kerberos V5", RFC 2623, June 1999.

[RFC2623]Eisler,M.,“NFS版本2和版本3的安全问题以及NFS协议对RPCSEC_GSS和Kerberos V5的使用”,RFC 2623,1999年6月。

[RFC2624] Shepler, S., "NFS Version 4 Design Considerations", RFC 2624, June 1999.

[RFC2624]Shepler,S.,“NFS版本4设计注意事项”,RFC 26242999年6月。

[RFC2847] Eisler, M., "LIPKEY - A Low Infrastructure Public Key Mechanism Using SPKM", RFC 2847, June 2000.

[RFC2847]Eisler,M.,“LIPKEY-一种使用SPKM的低基础设施公钥机制”,RFC 2847,2000年6月。

[Sandberg] Sandberg, R., D. Goldberg, S. Kleiman, D. Walsh, B. Lyon, "Design and Implementation of the Sun Network Filesystem," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Summer 1985. The basic paper describing the SunOS implementation of the NFS version 2 protocol, and discusses the goals, protocol specification and trade-offs.

[Sandberg]R.,D.Goldberg,S.Kleiman,D.Walsh,B.Lyon,“Sun网络文件系统的设计和实现”,USENIX会议记录,USENIX协会,加利福尼亚州伯克利,1985年夏季。本文描述了NFS版本2协议的SunOS实现,并讨论了目标、协议规范和权衡。

[Srinivasan] Srinivasan, V., Jeffrey C. Mogul, "Spritely NFS: Implementation and Performance of Cache Consistency Protocols", WRL Research Report 89/5, Digital Equipment Corporation Western Research Laboratory, 100 Hamilton Ave., Palo Alto, CA, 94301, May 1989. This paper analyzes the effect of applying a Sprite-like consistency protocol applied to standard NFS. The issues of recovery in a stateful environment are covered in [Mogul].

[Srinivasan]Srinivasan,V.,Jeffrey C.Mogul,“Sprity NFS:缓存一致性协议的实现和性能”,WRL研究报告89/5,数字设备公司西部研究实验室,加利福尼亚州帕洛阿尔托市汉密尔顿大道100号,94301,1989年5月。本文分析了将类似Sprite的一致性协议应用于标准NFS的效果。[Mogul]中介绍了有状态环境中的恢复问题。

[Unicode1] The Unicode Consortium, "The Unicode Standard, Version 3.0", Addison-Wesley Developers Press, Reading, MA, 2000. ISBN 0-201-61633-5. More information available at: http://www.unicode.org/

[Unicode1]Unicode联盟,“Unicode标准,3.0版”,Addison-Wesley开发者出版社,马萨诸塞州雷丁市,2000年。ISBN 0-201-61633-5。有关更多信息,请访问:http://www.unicode.org/

   [Unicode2]   "Unsupported Scripts" Unicode, Inc., The Unicode
                Consortium, P.O. Box 700519, San Jose, CA 95710-0519
                USA, September 1999
                http://www.unicode.org/unicode/standard/unsupported.html
        
   [Unicode2]   "Unsupported Scripts" Unicode, Inc., The Unicode
                Consortium, P.O. Box 700519, San Jose, CA 95710-0519
                USA, September 1999
                http://www.unicode.org/unicode/standard/unsupported.html
        

[XNFS] The Open Group, Protocols for Interworking: XNFS, Version 3W, The Open Group, 1010 El Camino Real Suite 380, Menlo Park, CA 94025, ISBN 1-85912-184-5, February 1998. HTML version available: http://www.opengroup.org

[XNFS]开放组,互通协议:XNFS,版本3W,开放组,1010 El Camino Real Suite 380,Menlo Park,CA 94025,ISBN 1-85912-184-51998年2月。可提供的HTML版本:http://www.opengroup.org

20. Authors
20. 作者
20.1. Editor's Address
20.1. 编辑地址

Spencer Shepler Sun Microsystems, Inc. 7808 Moonflower Drive Austin, Texas 78750

斯宾塞·谢普勒太阳微系统公司,德克萨斯州奥斯汀市月光大道7808号,邮编78750

   Phone: +1 512-349-9376
   EMail: spencer.shepler@sun.com
        
   Phone: +1 512-349-9376
   EMail: spencer.shepler@sun.com
        
20.2. Authors' Addresses
20.2. 作者地址

Carl Beame Hummingbird Ltd.

卡尔·比姆蜂鸟有限公司。

   EMail: beame@bws.com
        
   EMail: beame@bws.com
        

Brent Callaghan Sun Microsystems, Inc. 901 San Antonio Road Palo Alto, CA 94303

Brent Callaghan Sun Microsystems,Inc.加利福尼亚州帕洛阿尔托市圣安东尼奥路901号,邮编94303

   Phone: +1 650-786-5067
   EMail: brent.callaghan@sun.com
        
   Phone: +1 650-786-5067
   EMail: brent.callaghan@sun.com
        

Mike Eisler 5565 Wilson Road Colorado Springs, CO 80919

美国科罗拉多州科罗拉多斯普林斯威尔逊路5565号,邮编:80919

   Phone: +1 719-599-9026
   EMail: mike@eisler.com
        
   Phone: +1 719-599-9026
   EMail: mike@eisler.com
        

David Noveck Network Appliance 375 Totten Pond Road Waltham, MA 02451

David Noveck Network Appliance马萨诸塞州沃尔瑟姆托顿池塘路375号,邮编02451

   Phone: +1 781-895-4949
   E-mail: dnoveck@netapp.com
        
   Phone: +1 781-895-4949
   E-mail: dnoveck@netapp.com
        

David Robinson Sun Microsystems, Inc. 901 San Antonio Road Palo Alto, CA 94303

David Robinson Sun Microsystems,Inc.加利福尼亚州帕洛阿尔托市圣安东尼奥路901号,邮编94303

   Phone: +1 650-786-5088
   EMail: david.robinson@sun.com
        
   Phone: +1 650-786-5088
   EMail: david.robinson@sun.com
        

Robert Thurlow Sun Microsystems, Inc. 901 San Antonio Road Palo Alto, CA 94303

Robert Thurlow Sun Microsystems,Inc.加利福尼亚州帕洛阿尔托市圣安东尼奥路901号,邮编94303

   Phone: +1 650-786-5096
   EMail: robert.thurlow@sun.com
        
   Phone: +1 650-786-5096
   EMail: robert.thurlow@sun.com
        
20.3. Acknowledgements
20.3. 致谢

The author thanks and acknowledges:

作者感谢并承认:

Neil Brown for his extensive review and comments of various drafts.

尼尔·布朗对各种草案进行了广泛的审查和评论。

21. Full Copyright Statement
21. 完整版权声明

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

本文件及其译本可复制并提供给他人,对其进行评论或解释或协助其实施的衍生作品可全部或部分编制、复制、出版和分发,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文件本身,例如删除版权通知或对互联网协会或其他互联网组织的引用,除非出于制定互联网标准的需要,在这种情况下,必须遵循互联网标准过程中定义的版权程序,或根据需要将其翻译成英语以外的其他语言。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上述授予的有限许可是永久性的,互联网协会或其继承人或受让人不会撤销。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

本文件和其中包含的信息是按“原样”提供的,互联网协会和互联网工程任务组否认所有明示或暗示的保证,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。