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

Network File System (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 (2003). All Rights Reserved.

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

Abstract

摘要

The Network File System (NFS) version 4 is a distributed filesystem protocol which owes heritage to NFS protocol version 2, RFC 1094, and version 3, RFC 1813. 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 RFC 1094和版本3 RFC 1813。与早期版本不同,NFS版本4协议支持传统的文件访问,同时集成了对文件锁定和装载协议的支持。此外,还添加了对强安全性(及其协商)、复合操作、客户端缓存和国际化的支持。当然,人们已经注意到使NFS版本4在Internet环境中运行良好。

This document replaces RFC 3010 as the definition of the NFS version 4 protocol.

本文档取代RFC 3010作为NFS版本4协议的定义。

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 [RFC2119].

本文件中的关键词“必须”、“不得”、“必需”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照[RFC2119]中所述进行解释。

Table of Contents

目录

   1.   Introduction . . . . . . . . . . . . . . . . . . . . . . .    8
        1.1.  Changes since RFC 3010 . . . . . . . . . . . . . . .    8
        1.2.  NFS version 4 Goals. . . . . . . . . . . . . . . . .    9
        1.3.  Inconsistencies of this Document with Section 18 . .    9
        1.4.  Overview of NFS version 4 Features . . . . . . . . .   10
              1.4.1.  RPC and Security . . . . . . . . . . . . . .   10
              1.4.2.  Procedure and Operation Structure. . . . . .   10
              1.4.3.  Filesystem Mode. . . . . . . . . . . . . . .   11
                      1.4.3.1.  Filehandle Types . . . . . . . . .   11
                      1.4.3.2.  Attribute Types. . . . . . . . . .   12
                      1.4.3.3.  Filesystem Replication and
                                Migration. . . . . . . . . . . . .   13
              1.4.4.  OPEN and CLOSE . . . . . . . . . . . . . . .   13
              1.4.5.  File locking . . . . . . . . . . . . . . . .   13
              1.4.6.  Client Caching and Delegation. . . . . . . .   13
        1.5.  General Definitions. . . . . . . . . . . . . . . . .   14
   2.   Protocol Data Types. . . . . . . . . . . . . . . . . . . .   16
        2.1.  Basic Data Types . . . . . . . . . . . . . . . . . .   16
        2.2.  Structured Data Types. . . . . . . . . . . . . . . .   18
   3.   RPC and Security Flavor. . . . . . . . . . . . . . . . . .   23
        3.1.  Ports and Transports . . . . . . . . . . . . . . . .   23
              3.1.1.  Client Retransmission Behavior . . . . . . .   24
        3.2.  Security Flavors . . . . . . . . . . . . . . . . . .   25
              3.2.1.  Security mechanisms for NFS version 4. . . .   25
                      3.2.1.1.  Kerberos V5 as a security triple .   25
                      3.2.1.2.  LIPKEY as a security triple. . . .   26
                      3.2.1.3.  SPKM-3 as a security triple. . . .   27
        3.3.  Security Negotiation . . . . . . . . . . . . . . . .   27
              3.3.1.  SECINFO. . . . . . . . . . . . . . . . . . .   28
              3.3.2.  Security Error . . . . . . . . . . . . . . .   28
        3.4.  Callback RPC Authentication. . . . . . . . . . . . .   28
   4.  Filehandles . . . . . . . . . . . . . . . . . . . . . . . .   30
        4.1.  Obtaining the First Filehandle . . . . . . . . . . .   30
              4.1.1.  Root Filehandle. . . . . . . . . . . . . . .   31
              4.1.2.  Public Filehandle. . . . . . . . . . . . . .   31
        4.2.  Filehandle Types . . . . . . . . . . . . . . . . . .   31
              4.2.1.  General Properties of a Filehandle . . . . .   32
              4.2.2.  Persistent Filehandle. . . . . . . . . . . .   32
              4.2.3.  Volatile Filehandle. . . . . . . . . . . . .   33
              4.2.4.  One Method of Constructing a
                      Volatile Filehandle. . . . . . . . . . . . .   34
        4.3.  Client Recovery from Filehandle Expiration . . . . .   35
   5.   File Attributes. . . . . . . . . . . . . . . . . . . . . .   35
        5.1.  Mandatory Attributes . . . . . . . . . . . . . . . .   37
        5.2.  Recommended Attributes . . . . . . . . . . . . . . .   37
        5.3.  Named Attributes . . . . . . . . . . . . . . . . . .   37
        
   1.   Introduction . . . . . . . . . . . . . . . . . . . . . . .    8
        1.1.  Changes since RFC 3010 . . . . . . . . . . . . . . .    8
        1.2.  NFS version 4 Goals. . . . . . . . . . . . . . . . .    9
        1.3.  Inconsistencies of this Document with Section 18 . .    9
        1.4.  Overview of NFS version 4 Features . . . . . . . . .   10
              1.4.1.  RPC and Security . . . . . . . . . . . . . .   10
              1.4.2.  Procedure and Operation Structure. . . . . .   10
              1.4.3.  Filesystem Mode. . . . . . . . . . . . . . .   11
                      1.4.3.1.  Filehandle Types . . . . . . . . .   11
                      1.4.3.2.  Attribute Types. . . . . . . . . .   12
                      1.4.3.3.  Filesystem Replication and
                                Migration. . . . . . . . . . . . .   13
              1.4.4.  OPEN and CLOSE . . . . . . . . . . . . . . .   13
              1.4.5.  File locking . . . . . . . . . . . . . . . .   13
              1.4.6.  Client Caching and Delegation. . . . . . . .   13
        1.5.  General Definitions. . . . . . . . . . . . . . . . .   14
   2.   Protocol Data Types. . . . . . . . . . . . . . . . . . . .   16
        2.1.  Basic Data Types . . . . . . . . . . . . . . . . . .   16
        2.2.  Structured Data Types. . . . . . . . . . . . . . . .   18
   3.   RPC and Security Flavor. . . . . . . . . . . . . . . . . .   23
        3.1.  Ports and Transports . . . . . . . . . . . . . . . .   23
              3.1.1.  Client Retransmission Behavior . . . . . . .   24
        3.2.  Security Flavors . . . . . . . . . . . . . . . . . .   25
              3.2.1.  Security mechanisms for NFS version 4. . . .   25
                      3.2.1.1.  Kerberos V5 as a security triple .   25
                      3.2.1.2.  LIPKEY as a security triple. . . .   26
                      3.2.1.3.  SPKM-3 as a security triple. . . .   27
        3.3.  Security Negotiation . . . . . . . . . . . . . . . .   27
              3.3.1.  SECINFO. . . . . . . . . . . . . . . . . . .   28
              3.3.2.  Security Error . . . . . . . . . . . . . . .   28
        3.4.  Callback RPC Authentication. . . . . . . . . . . . .   28
   4.  Filehandles . . . . . . . . . . . . . . . . . . . . . . . .   30
        4.1.  Obtaining the First Filehandle . . . . . . . . . . .   30
              4.1.1.  Root Filehandle. . . . . . . . . . . . . . .   31
              4.1.2.  Public Filehandle. . . . . . . . . . . . . .   31
        4.2.  Filehandle Types . . . . . . . . . . . . . . . . . .   31
              4.2.1.  General Properties of a Filehandle . . . . .   32
              4.2.2.  Persistent Filehandle. . . . . . . . . . . .   32
              4.2.3.  Volatile Filehandle. . . . . . . . . . . . .   33
              4.2.4.  One Method of Constructing a
                      Volatile Filehandle. . . . . . . . . . . . .   34
        4.3.  Client Recovery from Filehandle Expiration . . . . .   35
   5.   File Attributes. . . . . . . . . . . . . . . . . . . . . .   35
        5.1.  Mandatory Attributes . . . . . . . . . . . . . . . .   37
        5.2.  Recommended Attributes . . . . . . . . . . . . . . .   37
        5.3.  Named Attributes . . . . . . . . . . . . . . . . . .   37
        
        5.4.  Classification of Attributes . . . . . . . . . . . .   38
        5.5.  Mandatory Attributes - Definitions . . . . . . . . .   39
        5.6.  Recommended Attributes - Definitions . . . . . . . .   41
        5.7.  Time Access. . . . . . . . . . . . . . . . . . . . .   46
        5.8.  Interpreting owner and owner_group . . . . . . . . .   47
        5.9.  Character Case Attributes. . . . . . . . . . . . . .   49
        5.10. Quota Attributes . . . . . . . . . . . . . . . . . .   49
        5.11. Access Control Lists . . . . . . . . . . . . . . . .   50
               5.11.1.  ACE type . . . . . . . . . . . . . . . . .   51
               5.11.2.  ACE Access Mask. . . . . . . . . . . . . .   52
               5.11.3.  ACE flag . . . . . . . . . . . . . . . . .   54
               5.11.4.  ACE who  . . . . . . . . . . . . . . . . .   55
               5.11.5.  Mode Attribute . . . . . . . . . . . . . .   56
               5.11.6.  Mode and ACL Attribute . . . . . . . . . .   57
               5.11.7.  mounted_on_fileid. . . . . . . . . . . . .   57
   6.  Filesystem Migration and Replication  . . . . . . . . . . .   58
        6.1.  Replication. . . . . . . . . . . . . . . . . . . . .   58
        6.2.  Migration. . . . . . . . . . . . . . . . . . . . . .   59
        6.3.  Interpretation of the fs_locations Attribute . . . .   60
        6.4.  Filehandle Recovery for Migration or Replication . .   61
   7.  NFS Server Name Space . . . . . . . . . . . . . . . . . . .   61
        7.1.  Server Exports . . . . . . . . . . . . . . . . . . .   61
        7.2.  Browsing Exports . . . . . . . . . . . . . . . . . .   62
        7.3.  Server Pseudo Filesystem . . . . . . . . . . . . . .   62
        7.4.  Multiple Roots . . . . . . . . . . . . . . . . . . .   63
        7.5.  Filehandle Volatility. . . . . . . . . . . . . . . .   63
        7.6.  Exported Root. . . . . . . . . . . . . . . . . . . .   63
        7.7.  Mount Point Crossing . . . . . . . . . . . . . . . .   63
        7.8.  Security Policy and Name Space Presentation. . . . .   64
   8.   File Locking and Share Reservations. . . . . . . . . . . .   65
        8.1.  Locking. . . . . . . . . . . . . . . . . . . . . . .   65
              8.1.1.    Client ID. . . . . . . . . . . . . . . . .   66
              8.1.2.    Server Release of Clientid . . . . . . . .   69
              8.1.3.    lock_owner and stateid Definition. . . . .   69
              8.1.4.    Use of the stateid and Locking . . . . . .   71
              8.1.5.    Sequencing of Lock Requests. . . . . . . .   73
              8.1.6.    Recovery from Replayed Requests. . . . . .   74
              8.1.7.    Releasing lock_owner State . . . . . . . .   74
              8.1.8.    Use of Open Confirmation . . . . . . . . .   75
        8.2.  Lock Ranges. . . . . . . . . . . . . . . . . . . . .   76
        8.3.  Upgrading and Downgrading Locks. . . . . . . . . . .   76
        8.4.  Blocking Locks . . . . . . . . . . . . . . . . . . .   77
        8.5.  Lease Renewal. . . . . . . . . . . . . . . . . . . .   77
        8.6.  Crash Recovery . . . . . . . . . . . . . . . . . . .   78
               8.6.1.   Client Failure and Recovery. . . . . . . .   79
               8.6.2.   Server Failure and Recovery. . . . . . . .   79
               8.6.3.   Network Partitions and Recovery. . . . . .   81
        8.7.   Recovery from a Lock Request Timeout or Abort . . .   85
        
        5.4.  Classification of Attributes . . . . . . . . . . . .   38
        5.5.  Mandatory Attributes - Definitions . . . . . . . . .   39
        5.6.  Recommended Attributes - Definitions . . . . . . . .   41
        5.7.  Time Access. . . . . . . . . . . . . . . . . . . . .   46
        5.8.  Interpreting owner and owner_group . . . . . . . . .   47
        5.9.  Character Case Attributes. . . . . . . . . . . . . .   49
        5.10. Quota Attributes . . . . . . . . . . . . . . . . . .   49
        5.11. Access Control Lists . . . . . . . . . . . . . . . .   50
               5.11.1.  ACE type . . . . . . . . . . . . . . . . .   51
               5.11.2.  ACE Access Mask. . . . . . . . . . . . . .   52
               5.11.3.  ACE flag . . . . . . . . . . . . . . . . .   54
               5.11.4.  ACE who  . . . . . . . . . . . . . . . . .   55
               5.11.5.  Mode Attribute . . . . . . . . . . . . . .   56
               5.11.6.  Mode and ACL Attribute . . . . . . . . . .   57
               5.11.7.  mounted_on_fileid. . . . . . . . . . . . .   57
   6.  Filesystem Migration and Replication  . . . . . . . . . . .   58
        6.1.  Replication. . . . . . . . . . . . . . . . . . . . .   58
        6.2.  Migration. . . . . . . . . . . . . . . . . . . . . .   59
        6.3.  Interpretation of the fs_locations Attribute . . . .   60
        6.4.  Filehandle Recovery for Migration or Replication . .   61
   7.  NFS Server Name Space . . . . . . . . . . . . . . . . . . .   61
        7.1.  Server Exports . . . . . . . . . . . . . . . . . . .   61
        7.2.  Browsing Exports . . . . . . . . . . . . . . . . . .   62
        7.3.  Server Pseudo Filesystem . . . . . . . . . . . . . .   62
        7.4.  Multiple Roots . . . . . . . . . . . . . . . . . . .   63
        7.5.  Filehandle Volatility. . . . . . . . . . . . . . . .   63
        7.6.  Exported Root. . . . . . . . . . . . . . . . . . . .   63
        7.7.  Mount Point Crossing . . . . . . . . . . . . . . . .   63
        7.8.  Security Policy and Name Space Presentation. . . . .   64
   8.   File Locking and Share Reservations. . . . . . . . . . . .   65
        8.1.  Locking. . . . . . . . . . . . . . . . . . . . . . .   65
              8.1.1.    Client ID. . . . . . . . . . . . . . . . .   66
              8.1.2.    Server Release of Clientid . . . . . . . .   69
              8.1.3.    lock_owner and stateid Definition. . . . .   69
              8.1.4.    Use of the stateid and Locking . . . . . .   71
              8.1.5.    Sequencing of Lock Requests. . . . . . . .   73
              8.1.6.    Recovery from Replayed Requests. . . . . .   74
              8.1.7.    Releasing lock_owner State . . . . . . . .   74
              8.1.8.    Use of Open Confirmation . . . . . . . . .   75
        8.2.  Lock Ranges. . . . . . . . . . . . . . . . . . . . .   76
        8.3.  Upgrading and Downgrading Locks. . . . . . . . . . .   76
        8.4.  Blocking Locks . . . . . . . . . . . . . . . . . . .   77
        8.5.  Lease Renewal. . . . . . . . . . . . . . . . . . . .   77
        8.6.  Crash Recovery . . . . . . . . . . . . . . . . . . .   78
               8.6.1.   Client Failure and Recovery. . . . . . . .   79
               8.6.2.   Server Failure and Recovery. . . . . . . .   79
               8.6.3.   Network Partitions and Recovery. . . . . .   81
        8.7.   Recovery from a Lock Request Timeout or Abort . . .   85
        
        8.8.   Server Revocation of Locks. . . . . . . . . . . . .   85
        8.9.   Share Reservations. . . . . . . . . . . . . . . . .   86
        8.10.  OPEN/CLOSE Operations . . . . . . . . . . . . . . .   87
               8.10.1.  Close and Retention of State
                        Information. . . . . . . . . . . . . . . .   88
        8.11.  Open Upgrade and Downgrade. . . . . . . . . . . . .   88
        8.12.  Short and Long Leases . . . . . . . . . . . . . . .   89
        8.13.  Clocks, Propagation Delay, and Calculating Lease
               Expiration. . . . . . . . . . . . . . . . . . . . .   89
        8.14.  Migration, Replication and State. . . . . . . . . .   90
               8.14.1.  Migration and State. . . . . . . . . . . .   90
               8.14.2.  Replication and State. . . . . . . . . . .   91
               8.14.3.  Notification of Migrated Lease . . . . . .   92
               8.14.4.  Migration and the Lease_time Attribute . .   92
   9.  Client-Side Caching . . . . . . . . . . . . . . . . . . . .   93
        9.1.   Performance Challenges for Client-Side Caching. . .   93
        9.2.   Delegation and Callbacks. . . . . . . . . . . . . .   94
               9.2.1.  Delegation Recovery . . . . . . . . . . . .   96
        9.3.   Data Caching. . . . . . . . . . . . . . . . . . . .   98
               9.3.1.   Data Caching and OPENs . . . . . . . . . .   98
               9.3.2.   Data Caching and File Locking. . . . . . .   99
               9.3.3.   Data Caching and Mandatory File Locking. .  101
               9.3.4.   Data Caching and File Identity . . . . . .  101
        9.4.   Open Delegation . . . . . . . . . . . . . . . . . .  102
               9.4.1.   Open Delegation and Data Caching . . . . .  104
               9.4.2.   Open Delegation and File Locks . . . . . .  106
               9.4.3.   Handling of CB_GETATTR . . . . . . . . . .  106
               9.4.4.   Recall of Open Delegation. . . . . . . . .  109
               9.4.5.   Clients that Fail to Honor
                        Delegation Recalls . . . . . . . . . . . .  111
               9.4.6.   Delegation Revocation. . . . . . . . . . .  112
        9.5.   Data Caching and Revocation . . . . . . . . . . . .  112
               9.5.1.   Revocation Recovery for Write Open
                        Delegation . . . . . . . . . . . . . . . .  113
        9.6.   Attribute Caching . . . . . . . . . . . . . . . . .  113
        9.7.   Data and Metadata Caching and Memory Mapped Files .  115
        9.8.   Name Caching  . . . . . . . . . . . . . . . . . . .  118
        9.9.   Directory Caching . . . . . . . . . . . . . . . . .  119
   10.  Minor Versioning . . . . . . . . . . . . . . . . . . . . .  120
   11.  Internationalization . . . . . . . . . . . . . . . . . . .  122
        11.1.  Stringprep profile for the utf8str_cs type. . . . .  123
               11.1.1.  Intended applicability of the
                        nfs4_cs_prep profile . . . . . . . . . . .  123
               11.1.2.  Character repertoire of nfs4_cs_prep . . .  124
               11.1.3.  Mapping used by nfs4_cs_prep . . . . . . .  124
               11.1.4.  Normalization used by nfs4_cs_prep . . . .  124
               11.1.5.  Prohibited output for nfs4_cs_prep . . . .  125
               11.1.6.  Bidirectional output for nfs4_cs_prep. . .  125
        
        8.8.   Server Revocation of Locks. . . . . . . . . . . . .   85
        8.9.   Share Reservations. . . . . . . . . . . . . . . . .   86
        8.10.  OPEN/CLOSE Operations . . . . . . . . . . . . . . .   87
               8.10.1.  Close and Retention of State
                        Information. . . . . . . . . . . . . . . .   88
        8.11.  Open Upgrade and Downgrade. . . . . . . . . . . . .   88
        8.12.  Short and Long Leases . . . . . . . . . . . . . . .   89
        8.13.  Clocks, Propagation Delay, and Calculating Lease
               Expiration. . . . . . . . . . . . . . . . . . . . .   89
        8.14.  Migration, Replication and State. . . . . . . . . .   90
               8.14.1.  Migration and State. . . . . . . . . . . .   90
               8.14.2.  Replication and State. . . . . . . . . . .   91
               8.14.3.  Notification of Migrated Lease . . . . . .   92
               8.14.4.  Migration and the Lease_time Attribute . .   92
   9.  Client-Side Caching . . . . . . . . . . . . . . . . . . . .   93
        9.1.   Performance Challenges for Client-Side Caching. . .   93
        9.2.   Delegation and Callbacks. . . . . . . . . . . . . .   94
               9.2.1.  Delegation Recovery . . . . . . . . . . . .   96
        9.3.   Data Caching. . . . . . . . . . . . . . . . . . . .   98
               9.3.1.   Data Caching and OPENs . . . . . . . . . .   98
               9.3.2.   Data Caching and File Locking. . . . . . .   99
               9.3.3.   Data Caching and Mandatory File Locking. .  101
               9.3.4.   Data Caching and File Identity . . . . . .  101
        9.4.   Open Delegation . . . . . . . . . . . . . . . . . .  102
               9.4.1.   Open Delegation and Data Caching . . . . .  104
               9.4.2.   Open Delegation and File Locks . . . . . .  106
               9.4.3.   Handling of CB_GETATTR . . . . . . . . . .  106
               9.4.4.   Recall of Open Delegation. . . . . . . . .  109
               9.4.5.   Clients that Fail to Honor
                        Delegation Recalls . . . . . . . . . . . .  111
               9.4.6.   Delegation Revocation. . . . . . . . . . .  112
        9.5.   Data Caching and Revocation . . . . . . . . . . . .  112
               9.5.1.   Revocation Recovery for Write Open
                        Delegation . . . . . . . . . . . . . . . .  113
        9.6.   Attribute Caching . . . . . . . . . . . . . . . . .  113
        9.7.   Data and Metadata Caching and Memory Mapped Files .  115
        9.8.   Name Caching  . . . . . . . . . . . . . . . . . . .  118
        9.9.   Directory Caching . . . . . . . . . . . . . . . . .  119
   10.  Minor Versioning . . . . . . . . . . . . . . . . . . . . .  120
   11.  Internationalization . . . . . . . . . . . . . . . . . . .  122
        11.1.  Stringprep profile for the utf8str_cs type. . . . .  123
               11.1.1.  Intended applicability of the
                        nfs4_cs_prep profile . . . . . . . . . . .  123
               11.1.2.  Character repertoire of nfs4_cs_prep . . .  124
               11.1.3.  Mapping used by nfs4_cs_prep . . . . . . .  124
               11.1.4.  Normalization used by nfs4_cs_prep . . . .  124
               11.1.5.  Prohibited output for nfs4_cs_prep . . . .  125
               11.1.6.  Bidirectional output for nfs4_cs_prep. . .  125
        
        11.2.  Stringprep profile for the utf8str_cis type . . . .  125
               11.2.1.  Intended applicability of the
                        nfs4_cis_prep profile. . . . . . . . . . .  125
               11.2.2.  Character repertoire of nfs4_cis_prep  . .  125
               11.2.3.  Mapping used by nfs4_cis_prep  . . . . . .  125
               11.2.4.  Normalization used by nfs4_cis_prep  . . .  125
               11.2.5.  Prohibited output for nfs4_cis_prep  . . .  126
               11.2.6.  Bidirectional output for nfs4_cis_prep . .  126
        11.3.  Stringprep profile for the utf8str_mixed type . . .  126
               11.3.1.  Intended applicability of the
                        nfs4_mixed_prep profile. . . . . . . . . .  126
               11.3.2.  Character repertoire of nfs4_mixed_prep  .  126
               11.3.3.  Mapping used by nfs4_cis_prep  . . . . . .  126
               11.3.4.  Normalization used by nfs4_mixed_prep  . .  127
               11.3.5.  Prohibited output for nfs4_mixed_prep  . .  127
               11.3.6.  Bidirectional output for nfs4_mixed_prep .  127
        11.4.  UTF-8 Related Errors. . . . . . . . . . . . . . . .  127
   12.  Error Definitions  . . . . . . . . . . . . . . . . . . . .  128
   13.  NFS version 4 Requests . . . . . . . . . . . . . . . . . .  134
        13.1.  Compound Procedure. . . . . . . . . . . . . . . . .  134
        13.2.  Evaluation of a Compound Request. . . . . . . . . .  135
        13.3.  Synchronous Modifying Operations. . . . . . . . . .  136
        13.4.  Operation Values. . . . . . . . . . . . . . . . . .  136
   14.  NFS version 4 Procedures . . . . . . . . . . . . . . . . .  136
        14.1.  Procedure 0: NULL - No Operation. . . . . . . . . .  136
        14.2.  Procedure 1: COMPOUND - Compound Operations . . . .  137
               14.2.1.   Operation 3: ACCESS - Check Access
                         Rights. . . . . . . . . . . . . . . . . .  140
               14.2.2.   Operation 4: CLOSE - Close File . . . . .  142
               14.2.3.   Operation 5: COMMIT - Commit
                         Cached Data . . . . . . . . . . . . . . .  144
               14.2.4.   Operation 6: CREATE - Create a
                         Non-Regular File Object . . . . . . . . .  147
               14.2.5.   Operation 7: DELEGPURGE -
                         Purge Delegations Awaiting Recovery . . .  150
               14.2.6.   Operation 8: DELEGRETURN - Return
                         Delegation. . . . . . . . . . . . . . . .  151
               14.2.7.   Operation 9: GETATTR - Get Attributes . .  152
               14.2.8.   Operation 10: GETFH - Get Current
                         Filehandle. . . . . . . . . . . . . . . .  153
               14.2.9.   Operation 11: LINK - Create Link to a
                         File. . . . . . . . . . . . . . . . . . .  154
               14.2.10.  Operation 12: LOCK - Create Lock  . . . .  156
               14.2.11.  Operation 13: LOCKT - Test For Lock . . .  160
               14.2.12.  Operation 14: LOCKU - Unlock File . . . .  162
               14.2.13.  Operation 15: LOOKUP - Lookup Filename. .  163
               14.2.14.  Operation 16: LOOKUPP - Lookup
                         Parent Directory. . . . . . . . . . . . .  165
        
        11.2.  Stringprep profile for the utf8str_cis type . . . .  125
               11.2.1.  Intended applicability of the
                        nfs4_cis_prep profile. . . . . . . . . . .  125
               11.2.2.  Character repertoire of nfs4_cis_prep  . .  125
               11.2.3.  Mapping used by nfs4_cis_prep  . . . . . .  125
               11.2.4.  Normalization used by nfs4_cis_prep  . . .  125
               11.2.5.  Prohibited output for nfs4_cis_prep  . . .  126
               11.2.6.  Bidirectional output for nfs4_cis_prep . .  126
        11.3.  Stringprep profile for the utf8str_mixed type . . .  126
               11.3.1.  Intended applicability of the
                        nfs4_mixed_prep profile. . . . . . . . . .  126
               11.3.2.  Character repertoire of nfs4_mixed_prep  .  126
               11.3.3.  Mapping used by nfs4_cis_prep  . . . . . .  126
               11.3.4.  Normalization used by nfs4_mixed_prep  . .  127
               11.3.5.  Prohibited output for nfs4_mixed_prep  . .  127
               11.3.6.  Bidirectional output for nfs4_mixed_prep .  127
        11.4.  UTF-8 Related Errors. . . . . . . . . . . . . . . .  127
   12.  Error Definitions  . . . . . . . . . . . . . . . . . . . .  128
   13.  NFS version 4 Requests . . . . . . . . . . . . . . . . . .  134
        13.1.  Compound Procedure. . . . . . . . . . . . . . . . .  134
        13.2.  Evaluation of a Compound Request. . . . . . . . . .  135
        13.3.  Synchronous Modifying Operations. . . . . . . . . .  136
        13.4.  Operation Values. . . . . . . . . . . . . . . . . .  136
   14.  NFS version 4 Procedures . . . . . . . . . . . . . . . . .  136
        14.1.  Procedure 0: NULL - No Operation. . . . . . . . . .  136
        14.2.  Procedure 1: COMPOUND - Compound Operations . . . .  137
               14.2.1.   Operation 3: ACCESS - Check Access
                         Rights. . . . . . . . . . . . . . . . . .  140
               14.2.2.   Operation 4: CLOSE - Close File . . . . .  142
               14.2.3.   Operation 5: COMMIT - Commit
                         Cached Data . . . . . . . . . . . . . . .  144
               14.2.4.   Operation 6: CREATE - Create a
                         Non-Regular File Object . . . . . . . . .  147
               14.2.5.   Operation 7: DELEGPURGE -
                         Purge Delegations Awaiting Recovery . . .  150
               14.2.6.   Operation 8: DELEGRETURN - Return
                         Delegation. . . . . . . . . . . . . . . .  151
               14.2.7.   Operation 9: GETATTR - Get Attributes . .  152
               14.2.8.   Operation 10: GETFH - Get Current
                         Filehandle. . . . . . . . . . . . . . . .  153
               14.2.9.   Operation 11: LINK - Create Link to a
                         File. . . . . . . . . . . . . . . . . . .  154
               14.2.10.  Operation 12: LOCK - Create Lock  . . . .  156
               14.2.11.  Operation 13: LOCKT - Test For Lock . . .  160
               14.2.12.  Operation 14: LOCKU - Unlock File . . . .  162
               14.2.13.  Operation 15: LOOKUP - Lookup Filename. .  163
               14.2.14.  Operation 16: LOOKUPP - Lookup
                         Parent Directory. . . . . . . . . . . . .  165
        
               14.2.15.  Operation 17: NVERIFY - Verify
                         Difference in Attributes  . . . . . . . .  166
               14.2.16.  Operation 18: OPEN - Open a Regular
                         File. . . . . . . . . . . . . . . . . . .  168
               14.2.17.  Operation 19: OPENATTR - Open Named
                         Attribute Directory . . . . . . . . . . .  178
               14.2.18.  Operation 20: OPEN_CONFIRM -
                         Confirm Open . . . . . . . . . . . . . .   180
               14.2.19.  Operation 21: OPEN_DOWNGRADE -
                         Reduce Open File Access . . . . . . . . .  182
               14.2.20.  Operation 22: PUTFH - Set
                         Current Filehandle. . . . . . . . . . . .  184
               14.2.21.  Operation 23: PUTPUBFH -
                         Set Public Filehandle . . . . . . . . . .  185
               14.2.22.  Operation 24: PUTROOTFH -
                         Set Root Filehandle . . . . . . . . . . .  186
               14.2.23.  Operation 25: READ - Read from File . . .  187
               14.2.24.  Operation 26: READDIR -
                         Read Directory. . . . . . . . . . . . . .  190
               14.2.25.  Operation 27: READLINK -
                         Read Symbolic Link. . . . . . . . . . . .  193
               14.2.26.  Operation 28: REMOVE -
                         Remove Filesystem Object. . . . . . . . .  195
               14.2.27.  Operation 29: RENAME -
                         Rename Directory Entry. . . . . . . . . .  197
               14.2.28.  Operation 30: RENEW - Renew a Lease . . .  200
               14.2.29.  Operation 31: RESTOREFH -
                         Restore Saved Filehandle. . . . . . . . .  201
               14.2.30.  Operation 32: SAVEFH - Save
                         Current Filehandle. . . . . . . . . . . .  202
               14.2.31.  Operation 33: SECINFO - Obtain
                         Available Security. . . . . . . . . . . .  203
               14.2.32.  Operation 34: SETATTR - Set Attributes. .  206
               14.2.33.  Operation 35: SETCLIENTID -
                         Negotiate Clientid. . . . . . . . . . . .  209
               14.2.34.  Operation 36: SETCLIENTID_CONFIRM -
                         Confirm Clientid. . . . . . . . . . . . .  213
               14.2.35.  Operation 37: VERIFY -
                         Verify Same Attributes. . . . . . . . . .  217
               14.2.36.  Operation 38: WRITE - Write to File . . .  218
               14.2.37.  Operation 39: RELEASE_LOCKOWNER -
                         Release Lockowner State . . . . . . . . .  223
               14.2.38.  Operation 10044: ILLEGAL -
                         Illegal operation . . . . . . . . . . . .  224
   15.  NFS version 4 Callback Procedures  . . . . . . . . . . . .  225
        15.1.  Procedure 0: CB_NULL - No Operation . . . . . . . .  225
        15.2.  Procedure 1: CB_COMPOUND - Compound
               Operations. . . . . . . . . . . . . . . . . . . . .  226
        
               14.2.15.  Operation 17: NVERIFY - Verify
                         Difference in Attributes  . . . . . . . .  166
               14.2.16.  Operation 18: OPEN - Open a Regular
                         File. . . . . . . . . . . . . . . . . . .  168
               14.2.17.  Operation 19: OPENATTR - Open Named
                         Attribute Directory . . . . . . . . . . .  178
               14.2.18.  Operation 20: OPEN_CONFIRM -
                         Confirm Open . . . . . . . . . . . . . .   180
               14.2.19.  Operation 21: OPEN_DOWNGRADE -
                         Reduce Open File Access . . . . . . . . .  182
               14.2.20.  Operation 22: PUTFH - Set
                         Current Filehandle. . . . . . . . . . . .  184
               14.2.21.  Operation 23: PUTPUBFH -
                         Set Public Filehandle . . . . . . . . . .  185
               14.2.22.  Operation 24: PUTROOTFH -
                         Set Root Filehandle . . . . . . . . . . .  186
               14.2.23.  Operation 25: READ - Read from File . . .  187
               14.2.24.  Operation 26: READDIR -
                         Read Directory. . . . . . . . . . . . . .  190
               14.2.25.  Operation 27: READLINK -
                         Read Symbolic Link. . . . . . . . . . . .  193
               14.2.26.  Operation 28: REMOVE -
                         Remove Filesystem Object. . . . . . . . .  195
               14.2.27.  Operation 29: RENAME -
                         Rename Directory Entry. . . . . . . . . .  197
               14.2.28.  Operation 30: RENEW - Renew a Lease . . .  200
               14.2.29.  Operation 31: RESTOREFH -
                         Restore Saved Filehandle. . . . . . . . .  201
               14.2.30.  Operation 32: SAVEFH - Save
                         Current Filehandle. . . . . . . . . . . .  202
               14.2.31.  Operation 33: SECINFO - Obtain
                         Available Security. . . . . . . . . . . .  203
               14.2.32.  Operation 34: SETATTR - Set Attributes. .  206
               14.2.33.  Operation 35: SETCLIENTID -
                         Negotiate Clientid. . . . . . . . . . . .  209
               14.2.34.  Operation 36: SETCLIENTID_CONFIRM -
                         Confirm Clientid. . . . . . . . . . . . .  213
               14.2.35.  Operation 37: VERIFY -
                         Verify Same Attributes. . . . . . . . . .  217
               14.2.36.  Operation 38: WRITE - Write to File . . .  218
               14.2.37.  Operation 39: RELEASE_LOCKOWNER -
                         Release Lockowner State . . . . . . . . .  223
               14.2.38.  Operation 10044: ILLEGAL -
                         Illegal operation . . . . . . . . . . . .  224
   15.  NFS version 4 Callback Procedures  . . . . . . . . . . . .  225
        15.1.  Procedure 0: CB_NULL - No Operation . . . . . . . .  225
        15.2.  Procedure 1: CB_COMPOUND - Compound
               Operations. . . . . . . . . . . . . . . . . . . . .  226
        
               15.2.1.  Operation 3: CB_GETATTR - Get
                        Attributes . . . . . . . . . . . . . . . .  228
               15.2.2.  Operation 4: CB_RECALL -
                        Recall an Open Delegation. . . . . . . . .  229
               15.2.3.  Operation 10044: CB_ILLEGAL -
                        Illegal Callback Operation . . . . . . . .  230
   16.  Security Considerations  . . . . . . . . . . . . . . . . .  231
   17.  IANA Considerations  . . . . . . . . . . . . . . . . . . .  232
        17.1.  Named Attribute Definition. . . . . . . . . . . . .  232
        17.2.  ONC RPC Network Identifiers (netids). . . . . . . .  232
   18.  RPC definition file  . . . . . . . . . . . . . . . . . . .  234
   19.  Acknowledgements . . . . . . . . . . . . . . . . . . . . .  268
   20.  Normative References . . . . . . . . . . . . . . . . . . .  268
   21.  Informative References . . . . . . . . . . . . . . . . . .  270
   22.  Authors' Information . . . . . . . . . . . . . . . . . . .  273
        22.1.  Editor's Address. . . . . . . . . . . . . . . . . .  273
        22.2.  Authors' Addresses. . . . . . . . . . . . . . . . .  274
   23.  Full Copyright Statement . . . . . . . . . . . . . . . . .  275
        
               15.2.1.  Operation 3: CB_GETATTR - Get
                        Attributes . . . . . . . . . . . . . . . .  228
               15.2.2.  Operation 4: CB_RECALL -
                        Recall an Open Delegation. . . . . . . . .  229
               15.2.3.  Operation 10044: CB_ILLEGAL -
                        Illegal Callback Operation . . . . . . . .  230
   16.  Security Considerations  . . . . . . . . . . . . . . . . .  231
   17.  IANA Considerations  . . . . . . . . . . . . . . . . . . .  232
        17.1.  Named Attribute Definition. . . . . . . . . . . . .  232
        17.2.  ONC RPC Network Identifiers (netids). . . . . . . .  232
   18.  RPC definition file  . . . . . . . . . . . . . . . . . . .  234
   19.  Acknowledgements . . . . . . . . . . . . . . . . . . . . .  268
   20.  Normative References . . . . . . . . . . . . . . . . . . .  268
   21.  Informative References . . . . . . . . . . . . . . . . . .  270
   22.  Authors' Information . . . . . . . . . . . . . . . . . . .  273
        22.1.  Editor's Address. . . . . . . . . . . . . . . . . .  273
        22.2.  Authors' Addresses. . . . . . . . . . . . . . . . .  274
   23.  Full Copyright Statement . . . . . . . . . . . . . . . . .  275
        
1. Introduction
1. 介绍
1.1. Changes since RFC 3010
1.1. 自RFC 3010以来的变化

This definition of the NFS version 4 protocol replaces or obsoletes the definition present in [RFC3010]. While portions of the two documents have remained the same, there have been substantive changes in others. The changes made between [RFC3010] and this document represent implementation experience and further review of the protocol. While some modifications were made for ease of implementation or clarification, most updates represent errors or situations where the [RFC3010] definition were untenable.

NFS版本4协议的此定义取代或废弃了[RFC3010]中的定义。虽然这两份文件的某些部分保持不变,但其他部分有实质性变化。[RFC3010]与本文件之间的变更代表了实施经验和对协议的进一步审查。虽然为了便于实施或澄清而进行了一些修改,但大多数更新表示错误或[RFC3010]定义不成立的情况。

The following list is not all inclusive of all changes but presents some of the most notable changes or additions made:

以下列表不包括所有更改,但列出了一些最显著的更改或添加:

o The state model has added an open_owner4 identifier. This was done to accommodate Posix based clients and the model they use for file locking. For Posix clients, an open_owner4 would correspond to a file descriptor potentially shared amongst a set of processes and the lock_owner4 identifier would correspond to a process that is locking a file.

o 状态模型添加了一个open_owner4标识符。这样做是为了适应基于Posix的客户端及其用于文件锁定的模型。对于Posix客户端,open_owner4将对应于一组进程之间可能共享的文件描述符,lock_owner4标识符将对应于锁定文件的进程。

o Clarifications and error conditions were added for the handling of the owner and group attributes. Since these attributes are string based (as opposed to the numeric uid/gid of previous versions of NFS), translations may not be available and hence the changes made.

o 为处理所有者和组属性添加了澄清和错误条件。由于这些属性是基于字符串的(与以前版本的NFS的数字uid/gid相反),翻译可能不可用,因此会进行更改。

o Clarifications for the ACL and mode attributes to address evaluation and partial support.

o 对ACL和模式属性的澄清,以解决评估和部分支持问题。

o For identifiers that are defined as XDR opaque, limits were set on their size.

o 对于定义为XDR不透明的标识符,对其大小设置了限制。

o Added the mounted_on_filed attribute to allow Posix clients to correctly construct local mounts.

o 添加了mounted_on_field属性,以允许Posix客户端正确构造本地装载。

o Modified the SETCLIENTID/SETCLIENTID_CONFIRM operations to deal correctly with confirmation details along with adding the ability to specify new client callback information. Also added clarification of the callback information itself.

o 修改了SETCLIENTID/SETCLIENTID_确认操作,以正确处理确认详细信息,并添加了指定新客户端回调信息的功能。还添加了回调信息本身的澄清。

o Added a new operation LOCKOWNER_RELEASE to enable notifying the server that a lock_owner4 will no longer be used by the client.

o 添加了一个新的操作LOCKOWNER\u RELEASE,以允许通知服务器客户端将不再使用锁所有者4。

o RENEW operation changes to identify the client correctly and allow for additional error returns.

o 更新操作更改以正确识别客户端并允许其他错误返回。

o Verify error return possibilities for all operations.

o 验证所有操作的错误返回可能性。

o Remove use of the pathname4 data type from LOOKUP and OPEN in favor of having the client construct a sequence of LOOKUP operations to achieive the same effect.

o 从查找中删除pathname4数据类型的使用并打开,以便让客户端构造一系列查找操作来实现相同的效果。

o Clarification of the internationalization issues and adoption of the new stringprep profile framework.

o 澄清国际化问题并采用新的stringprep概要文件框架。

1.2. NFS Version 4 Goals
1.2. NFS版本4目标

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 filesystem model that provides a useful, common set of features that does not unduly favor one filesystem 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.3. Inconsistencies of this Document with Section 18
1.3. 本文件与第18节不一致

Section 18, RPC Definition File, contains the definitions in XDR description language of the constructs used by the protocol. Prior to Section 18, several of the constructs are reproduced for purposes

第18节,RPC定义文件,包含协议使用的构造的XDR描述语言定义。在第18节之前,出于以下目的复制了一些构造

of explanation. The reader is warned of the possibility of errors in the reproduced constructs outside of Section 18. For any part of the document that is inconsistent with Section 18, Section 18 is to be considered authoritative.

需要解释。读者应注意第18节以外的复制结构可能出现错误。对于文件中与第18节不一致的任何部分,第18节应视为具有权威性。

1.4. Overview of NFS version 4 Features
1.4. 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 filesystems and distributed filesystems is expected as well.

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

1.4.1. RPC and Security
1.4.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 [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.

与以前版本的NFS一样,NFS版本4协议使用的外部数据表示(XDR)和远程过程调用(RPC)机制是[RFC1831]和[RFC1832]中定义的机制。为了满足端到端安全性要求,将使用RPCSEC_GSS框架[RFC2203]扩展基本RPC安全性。通过使用RPCSEC_GSS,可以提供各种机制来为NFS版本4协议提供身份验证、完整性和隐私。Kerberos V5将按[RFC1964]中所述使用,以提供一个安全框架。[RFC2847]中描述的LIPKEY GSS-API机制将用于通过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 filesystem resources. With this, the client can securely match the security mechanism that meets the policies specified at both the client and server.

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

1.4.2. Procedure and Operation Structure
1.4.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.

与以前版本的NFS协议不同的一个重要区别是引入了复合过程。对于NFS版本4协议,有两个RPC过程:NULL和component。复合过程是根据操作定义的,这些操作与传统的NFS过程更接近。

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 filesystem 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.

通过使用复合过程,客户机能够构建简单或复杂的请求。这些复合请求允许减少逻辑文件系统操作所需的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 filesystem 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.4.3. Filesystem Model
1.4.3. 文件系统模型

The general filesystem model used for the NFS version 4 protocol is the same as previous versions. The server filesystem 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 filesystem tree provided by the server. The server provides multiple filesystems by gluing them together with pseudo filesystems. These pseudo filesystems provide for potential gaps in the path names between real filesystems.

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

1.4.3.1. Filehandle Types
1.4.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 filesystem object to which it referred. For some server implementations, this persistence requirement has been difficult to

在NFS协议的早期版本中,服务器提供的文件句柄保证在其引用的文件系统对象的生命周期内有效或持久。对于某些服务器实现,很难满足这种持久性需求

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 filesystem 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版本4协议,通过引入另一种类型的文件句柄volatile,这一要求得到了放宽。对于持久性和易失性文件句柄类型,服务器实现可以与服务器上的文件系统的能力以及操作环境相匹配。客户机将了解服务器提供的文件句柄类型,并准备好处理每个文件句柄的语义。

1.4.3.2. Attribute Types
1.4.3.2. 属性类型

The NFS version 4 protocol introduces three classes of filesystem 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 filesystem 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 filesystem attributes that must be provided by the server and must be properly represented by the server. Recommended attributes represent different filesystem 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 filesystem 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.4.3.3. Filesystem Replication and Migration
1.4.3.3. 文件系统复制和迁移

With the use of a special file attribute, the ability to migrate or replicate server filesystems is enabled within the protocol. The filesystem locations attribute provides a method for the client to probe the server about the location of a filesystem. In the event of a migration of a filesystem, the client will receive an error when operating on the filesystem 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 filesystem. From this information, the client can use its own policies to access the appropriate filesystem location.

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

1.4.4. OPEN and CLOSE
1.4.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.4.5. File locking
1.4.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 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版本4协议,对字节范围文件锁定的支持是NFS协议的一部分。文件锁定支持的结构不需要RPC回调机制。这与以前版本的NFS文件锁定协议Network Lock Manager(NLM)不同。与文件锁关联的状态在基于租约的模型下在服务器上维护。服务器为NFS客户端持有的所有状态定义一个租用期。如果客户端未在定义的期限内续订其租约,则服务器可能会释放与客户端租约关联的所有状态。客户可以通过使用“续订”操作或通过使用其他操作(主要是READ)来间接续订其租约。

1.4.6. Client Caching and Delegation
1.4.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 filesystem 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.5. General Definitions
1.5. 一般定义

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 filesystem 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 share reservations unless specifically stated otherwise.

锁定术语“锁定”用于指记录(字节范围)锁定以及共享保留,除非另有特别说明。

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

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

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 128-bit quantity returned by a server that uniquely defines the open and locking state provided by the server for a specific open or lock owner for a specific file.

Stateid服务器返回的128位数量,它唯一地定义了服务器为特定文件的特定打开或锁定所有者提供的打开和锁定状态。

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 utf8str_cs component4; Represents path name components

组件4类型定义utf8str_cs组件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 utf8str_cs linktext4; Symbolic link contents

linktext4类型定义utf8str_cs 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 [RFC2743] for details.

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

seqid4 typedef uint32_t seqid4; Sequence identifier used for file locking

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

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

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

utf8str_cis typedef opaque utf8str_cis; Case-insensitive UTF-8 string

utf8str_cis类型定义不透明utf8str_cis;不区分大小写的UTF-8字符串

utf8str_cs typedef opaque utf8str_cs; Case-sensitive UTF-8 string

utf8str_cs类型定义不透明utf8str_cs;区分大小写的UTF-8字符串

utf8str_mixed typedef opaque utf8str_mixed; UTF-8 strings with a case sensitive prefix and a case insensitive suffix.

utf8str_混合型DEF不透明utf8str_混合型;带有区分大小写前缀和不区分大小写后缀的UTF-8字符串。

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

验证器4类型定义不透明验证器4[NFS4_验证器大小];用于各种操作(提交、创建、打开、READDIR、SETCLIENTID、SETCLIENTID\u确认、写入)的验证程序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 filesystem 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; /* major device number */
                          uint32_t specdata2; /* minor device number */
                  };
        
                  struct specdata4 {
                          uint32_t specdata1; /* major device number */
                          uint32_t specdata2; /* minor device number */
                  };
        

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 filesystem identifier that is used as a mandatory attribute.

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

fs_location4

fs_位置4

                  struct fs_location4 {
                          utf8str_cis    server<>;
                          pathname4     rootpath;
                  };
        
                  struct fs_location4 {
                          utf8str_cis    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 know the value of the change attribute for the directory in which the target filesystem object resides.

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

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 SETCLIENTID operation to either specify the address of the client that is using a clientid or as part of the callback registration. The

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

r_netid and r_addr fields are specified in [RFC1833], but they are underspecified in [RFC1833] as far as what they should look like for specific protocols.

[RFC1833]中指定了r_netid和r_addr字段,但[RFC1833]中未对它们进行详细说明,因为它们与特定协议的外观不符。

For TCP over IPv4 and for UDP over IPv4, the format of r_addr is the US-ASCII string:

对于IPv4上的TCP和IPv4上的UDP,r_addr的格式为US-ASCII字符串:

h1.h2.h3.h4.p1.p2

h1.h2.h3.h4.p1.p2

The prefix, "h1.h2.h3.h4", is the standard textual form for representing an IPv4 address, which is always four octets long. Assuming big-endian ordering, h1, h2, h3, and h4, are respectively, the first through fourth octets each converted to ASCII-decimal. Assuming big-endian ordering, p1 and p2 are, respectively, the first and second octets each converted to ASCII-decimal. For example, if a host, in big-endian order, has an address of 0x0A010307 and there is a service listening on, in big endian order, port 0x020F (decimal 527), then the complete universal address is "10.1.3.7.2.15".

前缀“h1.h2.h3.h4”是表示IPv4地址的标准文本形式,其长度始终为四个八位字节。假设大端排序h1、h2、h3和h4分别是第一个到第四个八位字节,每个八位字节都转换为ASCII十进制。假设大端排序,p1和p2分别是第一个和第二个八位字节,每个八位字节转换为ASCII十进制。例如,如果主机的大端顺序为地址0x0A010307,并且有服务以大端顺序侦听端口0x020F(十进制527),则完整的通用地址为“10.1.3.7.2.15”。

For TCP over IPv4 the value of r_netid is the string "tcp". For UDP over IPv4 the value of r_netid is the string "udp".

对于IPv4上的TCP,r_netid的值是字符串“TCP”。对于IPv4上的UDP,r_netid的值是字符串“UDP”。

For TCP over IPv6 and for UDP over IPv6, the format of r_addr is the US-ASCII string:

对于IPv6上的TCP和IPv6上的UDP,r_addr的格式为US-ASCII字符串:

         x1:x2:x3:x4:x5:x6:x7:x8.p1.p2
        
         x1:x2:x3:x4:x5:x6:x7:x8.p1.p2
        

The suffix "p1.p2" is the service port, and is computed the same way as with universal addresses for TCP and UDP over IPv4. The prefix, "x1:x2:x3:x4:x5:x6:x7:x8", is the standard textual form for representing an IPv6 address as defined in Section 2.2 of [RFC2373]. Additionally, the two alternative forms specified in Section 2.2 of [RFC2373] are also acceptable.

后缀“p1.p2”是服务端口,其计算方式与IPv4上TCP和UDP的通用地址相同。前缀“x1:x2:x3:x4:x5:x6:x7:x8”是表示[RFC2373]第2.2节中定义的IPv6地址的标准文本形式。此外,也可接受[RFC2373]第2.2节中规定的两种替代形式。

For TCP over IPv6 the value of r_netid is the string "tcp6". For UDP over IPv6 the value of r_netid is the string "udp6".

对于IPv6上的TCP,r_netid的值是字符串“tcp6”。对于IPv6上的UDP,r_netid的值是字符串“udp6”。

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<NFS4_OPAQUE_LIMIT>;
                  };
        
                  struct nfs_client_id4 {
                          verifier4     verifier;
                          opaque        id<NFS4_OPAQUE_LIMIT>;
                  };
        

This structure is part of the arguments to the SETCLIENTID operation. NFS4_OPAQUE_LIMIT is defined as 1024.

此结构是SETCLIENTID操作参数的一部分。NFS4\u不透明\u限制定义为1024。

open_owner4

开放式所有者4

                  struct open_owner4 {
                          clientid4     clientid;
                          opaque        owner<NFS4_OPAQUE_LIMIT>;
                  };
        
                  struct open_owner4 {
                          clientid4     clientid;
                          opaque        owner<NFS4_OPAQUE_LIMIT>;
                  };
        

This structure is used to identify the owner of open state. NFS4_OPAQUE_LIMIT is defined as 1024.

此结构用于标识打开状态的所有者。NFS4\u不透明\u限制定义为1024。

lock_owner4

锁定所有者4

                  struct lock_owner4 {
                          clientid4     clientid;
                          opaque        owner<NFS4_OPAQUE_LIMIT>;
                  };
        
                  struct lock_owner4 {
                          clientid4     clientid;
                          opaque        owner<NFS4_OPAQUE_LIMIT>;
                  };
        

This structure is used to identify the owner of file locking state. NFS4_OPAQUE_LIMIT is defined as 1024.

此结构用于标识文件锁定状态的所有者。NFS4\u不透明\u限制定义为1024。

open_to_lock_owner4

打开至锁定所有者4

                  struct open_to_lock_owner4 {
                          seqid4          open_seqid;
                          stateid4        open_stateid;
                          seqid4          lock_seqid;
                          lock_owner4     lock_owner;
                  };
        
                  struct open_to_lock_owner4 {
                          seqid4          open_seqid;
                          stateid4        open_stateid;
                          seqid4          lock_seqid;
                          lock_owner4     lock_owner;
                  };
        

This structure is used for the first LOCK operation done for an open_owner4. It provides both the open_stateid and lock_owner such that the transition is made from a valid open_stateid sequence to that of the new lock_stateid sequence. Using this mechanism avoids the confirmation of the lock_owner/lock_seqid pair since it is tied to established state in the form of the open_stateid/open_seqid.

此结构用于为开放式所有者完成的第一次锁定操作4。它同时提供open_stateid和lock_owner,以便从有效的open_stateid序列转换为新的lock_stateid序列。使用此机制可以避免确认lock_owner/lock_seqid对,因为它以open_stateid/open_seqid的形式绑定到已建立的状态。

stateid4

州4

                  struct stateid4 {
                    uint32_t        seqid;
                    opaque          other[12];
                  };
        
                  struct stateid4 {
                    uint32_t        seqid;
                    opaque          other[12];
                  };
        

This structure is used for the various state sharing mechanisms between the client and server. For the client, this data structure is read-only. The starting value of the seqid field is undefined. The server is required to increment the seqid field monotonically at each transition of the stateid. This is important since the client will inspect the seqid in OPEN stateids to determine the order of OPEN processing done by the server.

此结构用于客户端和服务器之间的各种状态共享机制。对于客户端,此数据结构是只读的。seqid字段的起始值未定义。服务器需要在stateid的每次转换时单调递增seqid字段。这一点很重要,因为客户端将检查OPEN StateID中的seqid,以确定服务器完成的打开处理顺序。

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 [RFC3232] 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[RFC3232]应为默认配置。使用NFS服务的注册端口意味着NFS客户端不需要使用[RFC1833]中所述的RPC绑定协议;这将允许NFS传输防火墙。

Where an NFS version 4 implementation supports operation over the IP network protocol, the supported transports between NFS and IP MUST be among the IETF-approved congestion control transport protocols, which include TCP and SCTP. To enhance the possibilities for interoperability, an NFS version 4 implementation MUST support operation over the TCP transport protocol, at least until such time as a standards track RFC revises this requirement to use a different IETF-approved congestion control transport protocol.

如果NFS版本4实现支持通过IP网络协议进行操作,则NFS和IP之间受支持的传输必须在IETF批准的拥塞控制传输协议中,包括TCP和SCTP。为了增强互操作性的可能性,NFS版本4的实现必须支持TCP传输协议上的操作,至少在标准跟踪RFC修改此要求以使用不同的IETF批准的拥塞控制传输协议之前。

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环境的性能。

As noted in the Security Considerations section, the authentication model for NFS version 4 has moved from machine-based to principal-based. However, this modification of the authentication model does not imply a technical requirement to move the TCP connection management model from whole machine-based to one based on a per user model. In particular, NFS over TCP client implementations have traditionally multiplexed traffic for multiple users over a common TCP connection between an NFS client and server. This has been true, regardless whether the NFS client is using AUTH_SYS, AUTH_DH, RPCSEC_GSS or any other flavor. Similarly, NFS over TCP server implementations have assumed such a model and thus scale the implementation of TCP connection management in proportion to the number of expected client machines. It is intended that NFS version 4 will not modify this connection management model. NFS version 4 clients that violate this assumption can expect scaling issues on the server and hence reduced service.

如安全注意事项部分所述,NFS版本4的身份验证模型已从基于机器的模式转变为基于主体的模式。然而,这种对身份验证模型的修改并不意味着将TCP连接管理模型从基于整台机器的移动到基于每用户模型的移动的技术要求。特别是,NFS over TCP客户端实现传统上通过NFS客户端和服务器之间的公共TCP连接为多个用户多路传输流量。无论NFS客户端使用的是AUTH_SYS、AUTH_DH、RPCSEC_GSS还是任何其他风格,这都是正确的。类似地,NFS over TCP服务器实现也采用了这样的模型,因此TCP连接管理的实现与预期客户端计算机的数量成比例。NFS版本4不会修改此连接管理模型。违反此假设的NFS版本4客户端可能会在服务器上出现扩展问题,从而减少服务。

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.1.1. Client Retransmission Behavior
3.1.1. 客户端重传行为

When processing a request received over a reliable transport such as TCP, the NFS version 4 server MUST NOT silently drop the request, except if the transport connection has been broken. Given such a contract between NFS version 4 clients and servers, clients MUST NOT retry a request unless one or both of the following are true:

在处理通过可靠传输(如TCP)接收的请求时,NFS版本4服务器不得自动删除该请求,除非传输连接已断开。如果NFS版本4客户端和服务器之间存在此类约定,则客户端不得重试请求,除非以下一项或两项均为真:

o The transport connection has been broken

o 传输连接已断开

o The procedure being retried is the NULL procedure

o 正在重试的过程为空过程

Since reliable transports, such as TCP, do not always synchronously inform a peer when the other peer has broken the connection (for example, when an NFS server reboots), the NFS version 4 client may want to actively "probe" the connection to see if has been broken. Use of the NULL procedure is one recommended way to do so. So, when a client experiences a remote procedure call timeout (of some arbitrary implementation specific amount), rather than retrying the remote procedure call, it could instead issue a NULL procedure call to the server. If the server has died, the transport connection break will eventually be indicated to the NFS version 4 client. The client can then reconnect, and then retry the original request. If the NULL procedure call gets a response, the connection has not broken. The client can decide to wait longer for the original request's response, or it can break the transport connection and reconnect before re-sending the original request.

由于可靠的传输(如TCP)并不总是在另一个对等方断开连接时(例如,当NFS服务器重新启动时)同步通知另一个对等方,因此NFS版本4客户端可能希望主动“探测”连接以查看是否断开。使用NULL过程是一种推荐的方法。因此,当客户机遇到远程过程调用超时(某种特定于实现的任意数量)时,它不会重试远程过程调用,而是可以向服务器发出NULL过程调用。如果服务器死机,传输连接中断最终将指示NFS版本4客户端。然后,客户端可以重新连接,然后重试原始请求。如果NULL过程调用得到响应,则表示连接没有中断。客户端可以决定等待原始请求的响应更长时间,也可以在重新发送原始请求之前中断传输连接并重新连接。

For callbacks from the server to the client, the same rules apply, but the server doing the callback becomes the client, and the client receiving the callback becomes the server.

对于从服务器到客户机的回调,同样的规则也适用,但执行回调的服务器成为客户机,接收回调的客户机成为服务器。

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 [RFC2743]. This allows for the use of various 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 enable the mandatory security mechanism. Other flavors, such as, AUTH_NONE, AUTH_SYS, and AUTH_DH MAY be implemented as well.

传统的RPC实现包括AUTH_NONE、AUTH_SYS、AUTH_DH和AUTH_KRB4作为安全特性。[RFC2203]引入了RPCSEC_GSS的额外安全特性,它使用GSS-API[RFC2743]的功能。这允许RPC层使用各种安全机制,而无需添加RPC安全特性的额外实现开销。对于NFS版本4,必须使用RPCSEC_GSS安全特性来启用强制安全机制。还可以实现其他风格,例如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 a security triple
3.2.1.1. kerberosv5作为三重安全机制

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

请注意,伪风格在这里作为映射辅助工具提供给实现者。由于此NFS协议包含协商安全性的方法,并且它了解GSS-API机制,因此

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版本3需要伪风格,因为安全协商是通过装载协议完成的。

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

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

Users and implementors are warned that 56 bit DES is no longer considered state of the art in terms of resistance to brute force attacks. Once a revision to [RFC1964] is available that adds support for AES, implementors are urged to incorporate AES into their NFSv4 over Kerberos V5 protocol stacks, and users are similarly urged to migrate to the use of AES.

用户和实现者被警告,就抵抗暴力攻击而言,56位DES不再被认为是最先进的。一旦[RFC1964]的修订版增加了对AES的支持,就敦促实现者将AES合并到他们的NFSv4 over Kerberos V5协议栈中,并同样敦促用户迁移到AES的使用。

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 server. 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 filesystem 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. See the section "Security Considerations" for further discussion.

客户机和服务器之间的安全协商必须通过安全通道进行,以消除第三方截获协商序列并迫使客户机和服务器选择低于要求或期望的安全级别的可能性。有关进一步的讨论,请参阅“安全注意事项”一节。

3.3.1. SECINFO
3.3.1. 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 operation 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.3.2. Security Error
3.3.2. 安全错误

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 filesystem 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. See the section for the "SECINFO" operation for further discussion of how the client will respond to the NFS4ERR_WRONGSEC error and use SECINFO.

基于以下假设,即每个NFS版本4客户端和服务器必须支持一组最低安全性(即,在RPCSEC_GSS下的LIPKEY、SPKM-3和Kerberos-V5),NFS客户端将使用其中一个最低安全性三元组启动与服务器的通信。在与服务器通信期间,客户端可能会收到NFS4ERR_错误秒的NFS错误。此错误允许服务器通知客户端当前使用的安全性三元组不适合访问服务器的文件系统资源。然后,客户机负责确定服务器上有哪些安全三元组可用,并选择一个适合客户机的安全三元组。有关客户端如何响应NFS4ERR_ErrorSec错误和使用SECINFO的进一步讨论,请参阅“SECINFO”操作部分。

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

Except as noted elsewhere in this section, the callback RPC (described later) MUST mutually authenticate the NFS server to the principal that acquired the clientid (also described later), using the security flavor the original SETCLIENTID operation used.

除本节其他地方所述外,回调RPC(稍后描述)必须使用原始SETCLIENTID操作所使用的安全特性,向获取clientid(稍后描述)的主体相互验证NFS服务器。

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

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

AUTH_SYS has no notions of mutual authentication or a server principal, so the callback from the server simply uses the AUTH_SYS credential that the user used when he 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域)的名称相对应的变量。

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.

由于LIPKEY是在SPKM-3上分层的,因此允许服务器对回调使用SPKM-3而不是LIPKEY,即使客户端对SETCLIENTID使用了LIPKEY。

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. This is the same principal the client acquired a GSS-API context for when it issued the SETCLIENTID operation, therefore, the realm name for the server principal must be the same for the callback as it was for the SETCLIENTID.

对于Kerberos V5,nfs/主机名将是Kerberos密钥分发中心数据库中的服务器主体。这与客户端在发出SETCLIENTID操作时获取GSS-API上下文的主体相同,因此,回调服务器主体的领域名称必须与SETCLIENTID相同。

For LIPKEY, this would be the username passed to the target (the NFS version 4 client that receives the callback).

对于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 pair, and if the user that the NFS server is authenticating to has a public key certificate, then it works.

应该注意的是,LIPKEY可能不适用于回调,因为LIPKEY客户端使用用户id/密码。如果接收回调的NFS客户机可以对NFS服务器的用户名/密码对进行身份验证,并且NFS服务器要进行身份验证的用户具有公钥证书,则它可以工作。

In situations where the 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操作使用每主机主体,而不是为SETCLIENTID使用LIPKEY,建议使用具有相互身份验证的SPKM-3。这实际上意味着客户端将使用证书对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

o 当服务器执行回调时,它必须向SETCLIENTID中使用的主体进行身份验证。即使使用了LIPKEY,因为LIPKEY是在SPKM-3上分层的,NFS客户端也需要

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.

具有与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 filesystem 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 filesystem object.

NFS协议中的filehandle是文件系统对象的每服务器唯一标识符。文件句柄的内容对客户端是不透明的。因此,服务器负责将文件句柄转换为文件系统对象的内部表示形式。

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 filesystem path name to a filehandle which can then be used by the NFS protocols.

NFS协议的操作是根据一个或多个文件句柄定义的。因此,客户端需要一个文件句柄来启动与服务器的通信。对于NFS版本2协议[RFC1094]和NFS版本3协议[RFC1813],存在一个辅助协议来获取第一个文件句柄。MOUNT协议(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 operation 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 filesystem 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 operation. 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 filesystem 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 filesystem 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 filesystem object. The client may not make any assumptions about this binding. The client uses the PUBLIC filehandle via the PUTPUBFH operation.

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

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. This type of filehandle is termed "persistent" in NFS Version 4. The semantics of a persistent filehandle remain the same as before. A new type of filehandle introduced in NFS Version 4 is the "volatile" filehandle, which attempts to accommodate certain server environments.

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

The volatile filehandle type was introduced to address server functionality or implementation issues which make correct implementation of a persistent filehandle infeasible. Some server environments do not provide a filesystem level invariant that can be used to construct a persistent filehandle. The underlying server filesystem may not provide the invariant or the server's filesystem 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 filesystem reorganization or migration. However, the volatile filehandle increases the implementation burden for the client.

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

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

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

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. 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. Further discussion of filehandle and attribute comparison in the context of data caching is presented in the section "Data Caching and File Identity".

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

As an example, in the case that two different path names when traversed at the server terminate at the same filesystem 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 filesystem object to which it refers. Once the server creates the filehandle for a filesystem 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 filesystem is migrated, the new NFS server must honor the same filehandle as the old NFS server.

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

The persistent filehandle will be become stale or invalid when the filesystem 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 filesystem containing the object is no longer available. The file

删除文件系统对象时,持久化文件句柄将变得陈旧或无效。当服务器显示引用已删除对象的持久化文件句柄时,它必须返回NFS4ERR_STALE错误。当包含对象的文件系统不再可用时,文件句柄可能会过时。档案

system may become unavailable if it exists on removable media and the media is no longer available at the server or the filesystem in whole has been destroyed or the filesystem has simply been removed from the server's name space (i.e., unmounted in a UNIX environment).

如果系统存在于可移动介质上,并且该介质在服务器上不再可用,或者整个文件系统已被破坏,或者该文件系统已从服务器的名称空间中删除(即在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 filesystem. 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 filesystem. 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_VOLATILE_ANY The filehandle may expire at any time, except as specifically excluded (i.e., FH4_NO_EXPIRE_WITH_OPEN).

FH4\u VOLATILE\u任何文件句柄可能随时过期,除非明确排除(即FH4\u NO\u expire\u与\u OPEN)。

FH4_NOEXPIRE_WITH_OPEN May only be set when FH4_VOLATILE_ANY is set. If this bit is set, then the meaning of FH4_VOLATILE_ANY is qualified to exclude any expiration of the filehandle when it is open.

只有在设置了FH4\u VOLATILE\u ANY时,才能设置FH4\u NOEXPIRE\u WITH\u OPEN。如果设置了该位,则FH4_VOLATILE_ANY的含义有资格排除文件句柄打开时的任何过期。

FH4_VOL_MIGRATION The filehandle will expire as a result of migration. If FH4_VOL_ANY is set, FH4_VOL_MIGRATION is redundant.

FH4_VOL_迁移文件句柄将因迁移而过期。如果设置了FH4_VOL_ANY,则FH4_VOL_迁移是冗余的。

FH4_VOL_RENAME The filehandle will expire during rename. This includes a rename by the requesting client or a rename by any other client. If FH4_VOL_ANY is set, FH4_VOL_RENAME is redundant.

FH4_VOL_RENAME文件句柄将在重命名期间过期。这包括请求客户端的重命名或任何其他客户端的重命名。如果设置了FH4_VOL_ANY,则FH4_VOL_RENAME是冗余的。

Servers which provide volatile filehandles that may expire while open (i.e., if FH4_VOL_MIGRATION or FH4_VOL_RENAME is set or if FH4_VOLATILE_ANY is set and FH4_NOEXPIRE_WITH_OPEN not set), should deny a RENAME or REMOVE that would affect an OPEN file of any of the components leading to the OPEN file. In addition, the server should deny all RENAME or REMOVE requests during the grace period upon server restart.

提供易失性文件句柄的服务器在打开时可能会过期(即,如果设置了FH4_VOL_MIGRATION或FH4_VOL_RENAME,或者如果设置了FH4_volatile_ANY,并且未设置FH4_NOEXPIRE_WITH_open),则应拒绝重命名或删除会影响导致打开文件的任何组件的打开文件。此外,在服务器重新启动的宽限期内,服务器应拒绝所有重命名或删除请求。

Note that the bits FH4_VOL_MIGRATION and FH4_VOL_RENAME allow the client to determine that expiration has occurred whenever a specific event occurs, without an explicit filehandle expiration error from the server. FH4_VOL_ANY does not provide this form of information. In situations where the server will expire many, but not all filehandles upon migration (e.g., all but those that are open), FH4_VOLATILE_ANY (in this case with FH4_NOEXPIRE_WITH_OPEN) is a better choice since the client may not assume that all filehandles will expire when migration occurs, and it is likely that additional expirations will occur (as a result of file CLOSE) that are separated in time from the migration event itself.

请注意,位FH4_VOL_MIGRATION和FH4_VOL_RENAME允许客户机在发生特定事件时确定是否已发生过期,而不会出现来自服务器的显式filehandle过期错误。FH4_VOL_ANY不提供这种形式的信息。如果服务器在迁移时会使许多文件句柄过期,但不是所有文件句柄都过期(例如,除了那些打开的文件之外),那么FH4_VOLATILE_ANY(在这种情况下,FH4_NOEXPIRE_与_open一起)是一个更好的选择,因为客户端可能不会假定在迁移时所有文件句柄都会过期,并且很可能会发生其他过期(由于文件关闭)在时间上与迁移事件本身分离。

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

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是表项/插槽的生成编号

When the client presents a volatile filehandle, the server makes the following checks, which assume that the check for the volatile bit has passed. 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 filesystem 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 filesystem name space.

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

If the expired filehandle refers to an object that has been removed from the filesystem, obviously the client will not be able to recover from the expired 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 LOOKUP B GETFH

Note that the COMPOUND procedure does not provide atomicity. This example only reduces the overhead of recovering from an expired filehandle.

注意,复合过程不提供原子性。此示例仅减少了从过期文件句柄恢复的开销。

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 is able query what attributes the server supports and construct requests with only those supported attributes (or a subset thereof).

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

To this end, attributes are 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 or READDIR and contains files whose names represent the named attributes and whose data bytes are the value of the attribute. For example:

命名属性由新的OPENATTR操作访问,该操作访问与文件系统对象关联的属性的隐藏目录。OPENATTR获取对象的文件句柄,并返回属性层次结构的文件句柄。命名属性的filehandle是可由LOOKUP或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. A server should support as many of the recommended attributes as possible but by their definition, the server is not required to support all of them. 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.

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

Note that the hidden directory returned by OPENATTR is a convenience for protocol processing. The client should not make any assumptions about the server's implementation of named attributes and whether the underlying filesystem at the server has a named attribute directory or not. Therefore, operations such as SETATTR and GETATTR on the named attribute directory are undefined.

请注意,OPENATTR返回的隐藏目录便于协议处理。客户机不应该对服务器的命名属性实现以及服务器上的底层文件系统是否具有命名属性目录做出任何假设。因此,命名属性目录上的SETATTR和GETATTR等操作是未定义的。

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 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 the client is better positioned decide whether and how to fabricate or construct an attribute or whether to do without the attribute.

对这些属性的理解足以保证NFS版本4协议中的支持。但是,并非所有客户端和服务器都支持它们。客户机可以通过在GETATTR请求中设置一个位来请求返回这些属性中的任何一个,但必须处理服务器不返回这些属性的情况。客户端可能要求服务器支持的属性集,但不应要求服务器不支持的属性集。服务器应该能够容忍对不受支持的属性的请求,并且不返回它们,而不是将请求视为错误。预计服务器将支持其能够轻松支持的所有属性,并且只支持在其操作环境中难以支持的属性。只要服务器不必向客户端“撒谎”,就应该提供属性。例如,文件修改时间应该是准确的时间,或者服务器不支持。这对客户来说并不总是舒适的,但是客户可以更好地决定是否以及如何制作或构造属性,或者是否不使用属性。

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 filesystem 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 filesystem. 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. Classification of Attributes
5.4. 属性分类

Each of the Mandatory and Recommended attributes can be classified in one of three categories: per server, per filesystem, or per filesystem object. Note that it is possible that some per filesystem attributes may vary within the filesystem. See the "homogeneous" attribute for its definition. Note that the attributes time_access_set and time_modify_set are not listed in this section because they are write-only attributes corresponding to time_access and time_modify, and are used in a special instance of SETATTR.

每个强制属性和推荐属性都可以分为三类:每服务器、每文件系统或每文件系统对象。请注意,在文件系统中,每个文件系统的某些属性可能会有所不同。有关其定义,请参见“同质”属性。请注意,属性time_access_set和time_modify_set未在本节中列出,因为它们是与time_access和time_modify相对应的仅写属性,并且在SETATTR的特殊实例中使用。

o The per server attribute is:

o 每服务器属性为:

lease_time

租赁时间

o The per filesystem attributes are:

o 每个文件系统的属性是:

supp_attr, fh_expire_type, link_support, symlink_support, unique_handles, aclsupport, cansettime, case_insensitive, case_preserving, chown_restricted, files_avail, files_free, files_total, fs_locations, homogeneous, maxfilesize, maxname, maxread, maxwrite, no_trunc, space_avail, space_free, space_total, time_delta

supp_attr、fh_expire_type、link_support、symlink_support、unique_handles、aclsupport、cansettime、大小写不敏感、大小写保留、chown_restricted、文件可用、文件可用、文件总数、fs_位置、同构、maxfilesize、maxname、maxread、maxwrite、no_trunc、space_avail、space_free、space_total、time_delta

o The per filesystem object attributes are:

o 每个文件系统对象属性包括:

type, change, size, named_attr, fsid, rdattr_error, filehandle, ACL, archive, fileid, hidden, maxlink, mimetype, mode, numlinks, owner, owner_group, rawdev, space_used, system, time_access, time_backup, time_create, time_metadata, time_modify, mounted_on_fileid

类型、更改、大小、命名属性、fsid、rdattr错误、文件句柄、ACL、存档、文件ID、隐藏、maxlink、mimetype、模式、numlinks、所有者、所有者组、rawdev、使用的空间、系统、时间访问、时间备份、时间创建、时间元数据、时间修改、装载在文件ID上

For quota_avail_hard, quota_avail_soft, and quota_used see their definitions below for the appropriate classification.

有关配额\可用\硬、配额\可用\软和使用的配额\请参见下面的定义以了解相应的分类。

5.5. Mandatory Attributes - Definitions
5.5. 强制性属性-定义
   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.  The
                                                scope of this
                                                attribute applies to
                                                all objects with a
                                                matching fsid.
        
   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.  The
                                                scope of this
                                                attribute applies to
                                                all objects with a
                                                matching fsid.
        

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

类型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_metadata attribute for this attribute's value but only if the filesystem object can not be updated more frequently than the resolution of time_metadata.

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

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

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

link_support 5 bool READ True, if the object's filesystem supports hard links.

如果对象的文件系统支持硬链接,则link_支持5 bool READ True。

symlink_support 6 bool READ True, if the object's filesystem supports symbolic links.

如果对象的文件系统支持符号链接,则symlink_支持6 bool READ True。

named_attr 7 bool READ True, if this object has named attributes. In other words, object has a non-empty named attribute directory.

如果此对象具有命名属性,则命名为\u attr 7 bool READ True。换句话说,对象有一个非空的命名属性目录。

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

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

unique_handles 9 bool READ True, if two distinct filehandles guaranteed to refer to two different filesystem objects.

如果两个不同的文件句柄保证引用两个不同的文件系统对象,则unique_handles 9 bool READ True。

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返回的枚举读取错误。

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

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

5.6. Recommended Attributes - Definitions
5.6. 推荐属性-定义
   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 filesystem.

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

archive 14 bool R/W True, if this file has been archived since the time of last modification (deprecated in favor of time_backup).

存档14 bool R/W True,如果此文件自上次修改后已存档(不推荐使用时间备份)。

cansettime 15 bool READ True, if the server is able to change the times for a filesystem object as specified in a SETATTR operation.

如果服务器能够按照SETATTR操作中的指定更改文件系统对象的时间,则cansettime 15 bool READ True。

case_insensitive 16 bool READ True, if filename comparisons on this filesystem are case insensitive.

如果此文件系统上的文件名比较不区分大小写,则不区分大小写16 bool READ True。

case_preserving 17 bool READ True, if filename case on this filesystem are preserved.

如果保留此文件系统上的文件名大小写,则大小写保留17 bool READ True。

chown_restricted 18 bool 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 Windows 2000 the

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

"Take Ownership" privilege).

“取得所有权”特权)。

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

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

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

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

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

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

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

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

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

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

hidden 25 bool R/W True, if the file is considered hidden with respect to the Windows API.

hidden 25 bool R/W True,如果文件相对于Windows API被认为是隐藏的。

homogeneous 26 bool READ True, if this object's filesystem is homogeneous, i.e., are per filesystem attributes the same

同构26 bool READ True,如果此对象的文件系统是同构的,即每个文件系统的属性是否相同

for all filesystem's objects?

对于所有文件系统的对象?

maxfilesize 27 uint64 READ Maximum supported file size for the filesystem 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 bandwidth or not receiving the best performance.

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

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 mode and permission bits for this object.

模式33模式4 R/W UNIX样式模式和此对象的权限位。

no_trunc 34 bool READ True, if a name longer than name_max is used, an error be returned and name is not truncated.

no_trunc 34 bool READ True,如果使用的名称长于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. If the value of type is not NF4BLK or NF4CHR, the value return SHOULD NOT be considered useful.

rawdev 41 SPECDATA读取原始设备标识符。UNIX设备主要/次要节点信息。如果type的值不是NF4BLK或NF4CHR,则返回的值不应视为有用。

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

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

space_free 43 uint64 READ Free disk space in bytes on the filesystem containing this object - this should

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

be the smallest relevant limit.

是最小的相关限制。

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

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

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

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

system 46 bool R/W True, if this file is a "system" file with respect to the Windows API.

system 46 bool R/W True,如果此文件是Windows API的“系统”文件。

time_access 47 nfstime4 READ The time of last access to the object by a read that was satisfied by the server.

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 READ The time of last meta-data modification of the object.

time_metadata 52 nfstime4读取上次修改对象元数据的时间。

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仅用于。

mounted_on_fileid 55 uint64 READ Like fileid, but if the target filehandle is the root of a filesystem return the fileid of the underlying directory.

在\u fileid 55 uint64上装入的\u读起来像fileid,但如果目标filehandle是文件系统的根,则返回基础目录的fileid。

5.7. Time Access
5.7. 时间访问

As defined above, the time_access attribute represents the time of last access to the object by a read that was satisfied by the server. The notion of what is an "access" depends on server's operating environment and/or the server's filesystem semantics. For example, for servers obeying POSIX semantics, time_access would be updated only by the READLINK, READ, and READDIR operations and not any of the operations that modify the content of the object. Of course, setting the corresponding time_access_set attribute is another way to modify the time_access attribute.

如上所述,time_access属性表示服务器满足的读取上次访问对象的时间。什么是“访问”的概念取决于服务器的操作环境和/或服务器的文件系统语义。例如,对于遵循POSIX语义的服务器,time_访问将仅由READLINK、READ和READDIR操作更新,而不是任何修改对象内容的操作。当然,设置相应的time\u access\u set属性是修改time\u access属性的另一种方法。

Whenever the file object resides on a writable filesystem, the server should make best efforts to record time_access into stable storage. However, to mitigate the performance effects of doing so, and most especially whenever the server is satisfying the read of the object's content from its cache, the server MAY cache access time updates and lazily write them to stable storage. It is also acceptable to give administrators of the server the option to disable time_access updates.

每当文件对象驻留在可写文件系统上时,服务器应尽最大努力记录访问稳定存储的时间。但是,为了减轻这样做对性能的影响,尤其是当服务器满足从其缓存读取对象内容的要求时,服务器可能会缓存访问时间更新,并将其惰性地写入稳定存储器。允许服务器管理员选择禁用时间访问更新也是可以接受的。

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

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

Similarly, security principals may be represented in different ways by different security mechanisms. Servers normally translate these representations into a common format, generally that used by local storage, to serve as a means of identifying the users corresponding to these security principals. When these local identifiers are translated to the form of the owner attribute, associated with files created by such principals they identify, in a common format, the users associated with each corresponding set of security principals.

类似地,安全主体可以通过不同的安全机制以不同的方式表示。服务器通常将这些表示转换为通用格式(通常由本地存储使用),作为识别与这些安全主体相对应的用户的手段。当这些本地标识符被转换为所有者属性的形式,并与这些主体创建的文件相关联时,它们以公共格式标识与每个对应的安全主体集相关联的用户。

The translation used to interpret owner and group strings 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. A server may provide a more general service, not limited by any particular translation (which would only translate a limited set of possible strings) by storing the owner and owner_group attributes in local storage without any translation or it may augment a translation method by storing the entire string for attributes for which no translation is available while using the local representation for those cases in which a translation is available.

用于解释所有者和组字符串的转换未指定为协议的一部分。这允许采用各种解决方案。例如,可以参考本地转换表,该表将数字id映射到user@dns_domain语法。名称服务也可用于完成翻译。服务器可以提供更一般的服务,不受任何特定翻译的限制(只翻译有限的一组可能字符串)通过将所有者和所有者组属性存储在本地存储中而不进行任何转换,或者可以通过存储没有转换的属性的整个字符串来扩充转换方法,同时对有转换的情况使用本地表示。

Servers that do not provide support for all possible values of the owner and owner_group attributes, should return an error (NFS4ERR_BADOWNER) when a string is presented that has no translation, as the value to be set for a SETATTR of the owner, owner_group, or acl attributes. When a server does accept an owner or owner_group value as valid on a SETATTR (and similarly for the owner and group strings in an acl), it is promising to return that same string when a corresponding GETATTR is done. Configuration changes and ill-constructed name translations (those that contain

如果服务器不支持所有者和所有者组属性的所有可能值,则在显示没有翻译的字符串时,应返回一个错误(NFS4ERR\U BADOWNER),作为要为所有者、所有者组或acl属性的SETATTR设置的值。当服务器确实接受在SETATTR上有效的owner或owner\u group值(对于acl中的owner和group字符串也是如此)时,它承诺在完成相应的GETATTR时返回相同的字符串。配置更改和构造错误的名称转换(包含

aliasing) may make that promise impossible to honor. Servers should make appropriate efforts to avoid a situation in which these attributes have their values changed when no real change to ownership has occurred.

(化名)可能使该承诺无法兑现。服务器应该做出适当的努力,避免在所有权没有发生实际变化的情况下,这些属性的值发生变化。

The "dns_domain" portion of the owner string is meant to be a DNS domain name. For example, user@ietf.org. Servers should accept as valid a set of users for at least one domain. A server may treat other domains as having no valid translations. A more general service is provided when a server is capable of accepting users for multiple domains, or for all domains, subject to security constraints.

所有者字符串的“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 at the sender and that the receiver of the attribute should not use that string as a basis for translation into its own internal format. 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.

如果客户端或服务器没有可用的转换,则必须构造属性值,而不带“@”。因此,如果owner或owner_group属性中没有@,则表示发送方没有可用的翻译,并且该属性的接收方不应使用该字符串作为将其转换为自身内部格式的基础。即使无法转换属性值,它仍然可能有用。对于客户端,属性字符串可用于本地显示所有权。

To provide a greater degree of compatibility with previous versions of NFS (i.e., v2 and v3), which identified users and groups by 32-bit unsigned uid's and gid's, owner and group strings that consist of decimal numeric values with no leading zeros can be given a special interpretation by clients and servers which choose to provide such support. The receiver may treat such a user or group string as representing the same user as would be represented by a v2/v3 uid or gid having the corresponding numeric value. A server is not obligated to accept such a string, but may return an NFS4ERR_BADOWNER instead. To avoid this mechanism being used to subvert user and group translation, so that a client might pass all of the owners and groups in numeric form, a server SHOULD return an NFS4ERR_BADOWNER error when there is a valid translation for the user or owner designated in this way. In that case, the client must use the appropriate name@domain string and not the special form for compatibility.

为了与以前版本的NFS(即v2和v3)提供更大程度的兼容性(NFS通过32位无符号uid和gid标识用户和组),选择提供此类支持的客户机和服务器可以对由十进制数值组成的所有者和组字符串(无前导零)进行特殊解释。接收方可以将这样的用户或组字符串视为表示将由具有相应数值的v2/v3 uid或gid表示的相同用户。服务器没有义务接受这样的字符串,但可以返回NFS4ERR_BADOWNER。为了避免使用此机制来破坏用户和组转换,以便客户端可以以数字形式传递所有所有者和组,当存在以这种方式指定的用户或所有者的有效转换时,服务器应返回NFS4ERR_BADOWNER错误。在这种情况下,客户必须使用适当的name@domain字符串,而不是兼容的特殊形式。

The owner string "nobody" may be used to designate an anonymous user, which will be associated with a file created by a security principal that cannot be mapped through normal means to the owner attribute.

所有者字符串“nobody”可用于指定匿名用户,该用户将与安全主体创建的文件关联,该文件无法通过正常方式映射到所有者属性。

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

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.10. Quota Attributes
5.10. 配额属性

For the attributes related to filesystem 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.11. Access Control Lists
5.11. 访问控制列表

The NFS version 4 ACL attribute is an array of access control entries (ACE). Although, the client can read and write the ACL attribute, the NFSv4 model is the server does all access control based on the server's interpretation of the ACL. If at any point the client wants to check access without issuing an operation that modifies or reads data or metadata, the client can use the OPEN and ACCESS operations to do so. There are various access control entry types, as defined in the Section "ACE type". The server is able to communicate which ACE types are supported by returning the appropriate value within the aclsupport attribute. Each ACE covers one or more operations on a file or directory as described in the Section "ACE Access Mask". It may also contain one or more flags that modify the semantics of the ACE as defined in the Section "ACE flag".

NFS version 4 ACL属性是访问控制项(ACE)的数组。尽管客户端可以读取和写入ACL属性,但NFSv4模型是服务器根据服务器对ACL的解释执行所有访问控制。如果客户端希望在任何时候检查访问,而不发出修改或读取数据或元数据的操作,则客户端可以使用OPEN和access操作来执行此操作。根据“ACE类型”一节中的定义,有各种访问控制条目类型。服务器可以通过在aclsupport属性中返回适当的值来通信支持哪些ACE类型。如“ACE访问掩码”一节所述,每个ACE都包含一个或多个文件或目录上的操作。它还可能包含一个或多个标志,用于修改“ACE标志”一节中定义的ACE语义。

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;
                 utf8str_mixed   who;
         };
        
         struct nfsace4 {
                 acetype4        type;
                 aceflag4        flag;
                 acemask4        access_mask;
                 utf8str_mixed   who;
         };
        

To determine if a 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 is no longer considered in the processing of later ACEs. If an ACCESS_DENIED_ACE is encountered where the requester's access still has unALLOWED bits in common with the "access_mask" of the ACE, the request is denied. However, unlike the ALLOWED and DENIED ACE types, the ALARM and AUDIT ACE types do not affect a requester's access, and instead are for triggering events as a result of a requester's access attempt.

为了确定请求是否成功,服务器将按顺序处理每个nfsace4条目。仅考虑具有与请求者匹配的“谁”的ACE。处理每个ACE,直到请求者访问的所有位都被允许。一旦一个位(见下文)被一个允许访问的ACE允许,它就不再被考虑在以后的ACE处理中。如果在请求者的访问仍然具有与ACE的“访问掩码”相同的未允许位的情况下遇到访问被拒绝ACE,则请求被拒绝。但是,与允许和拒绝ACE类型不同,报警和审核ACE类型不会影响请求者的访问,而是用于触发请求者访问尝试导致的事件。

Therefore, all AUDIT and ALARM ACEs are processed until end of the ACL. When the ACL is fully processed, if there are bits in requester's mask that have not been considered whether the server allows or denies the access is undefined. If there is a mode attribute on the file, then this cannot happen, since the mode's MODE4_*OTH bits will map to EVERYONE@ ACEs that unambiguously specify the requester's access.

因此,在ACL结束之前,将处理所有审核和报警ACE。当ACL被完全处理时,如果请求者掩码中有未被考虑的位,则服务器是否允许访问是未定义的。如果文件上有mode属性,则不会发生这种情况,因为mode的MODE4_*OTH位将映射到EVERYONE@ACEs,它明确指定了请求者的访问权限。

The NFS version 4 ACL model is quite rich. Some server platforms may provide access control functionality that goes beyond the UNIX-style mode attribute, but which is not as rich as the NFS ACL model. So that users can take advantage of this more limited functionality, the server may indicate that it supports ACLs as long as it follows the guidelines for mapping between its ACL model and the NFS version 4 ACL model.

NFS版本4 ACL模型非常丰富。某些服务器平台可能提供的访问控制功能超出了UNIX样式模式属性的范围,但不如NFS ACL模型丰富。为了使用户能够利用这一更有限的功能,服务器可能会指示它支持ACL,只要它遵循其ACL模型和NFS版本4 ACL模型之间映射的指导原则。

The situation is complicated by the fact that a server may have multiple modules that enforce ACLs. For example, the enforcement for NFS version 4 access may be different from the enforcement for local access, and both may be different from the enforcement for access through other protocols such as SMB. So it may be useful for a server to accept an ACL even if not all of its modules are able to support it.

服务器可能有多个强制ACL的模块,这一事实使情况变得复杂。例如,NFS版本4访问的强制执行可能不同于本地访问的强制执行,并且两者都可能不同于通过其他协议(如SMB)进行访问的强制执行。因此,即使不是所有的模块都能支持ACL,服务器接受ACL也是很有用的。

The guiding principle in all cases is that the server must not accept ACLs that appear to make the file more secure than it really is.

在所有情况下,指导原则都是服务器不能接受似乎使文件比实际更安全的ACL。

5.11.1. ACE type
5.11.1. 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中指定的访问方法的文件或目录时,生成系统报警(取决于系统)。

A server need not support all of the above ACE types. The bitmask constants used to represent the above definitions within the

服务器不需要支持上述所有ACE类型。用于在中表示上述定义的位掩码常量

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;
        

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

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

The constants used for the type field (acetype4) are as follows:

类型字段(acetype4)使用的常量如下所示:

      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;
        

Clients should not attempt to set an ACE unless the server claims support for that ACE type. If the server receives a request to set an ACE that it cannot store, it MUST reject the request with NFS4ERR_ATTRNOTSUPP. If the server receives a request to set an ACE that it can store but cannot enforce, the server SHOULD reject the request with NFS4ERR_ATTRNOTSUPP.

客户端不应尝试设置ACE,除非服务器声明支持该ACE类型。如果服务器收到设置其无法存储的ACE的请求,则必须使用NFS4ERR_ATTRNOTSUPP拒绝该请求。如果服务器收到一个请求,要求设置一个它可以存储但无法执行的ACE,则服务器应使用NFS4ERR_ATTRNOTSUPP拒绝该请求。

Example: suppose a server can enforce NFS ACLs for NFS access but cannot enforce ACLs for local access. If arbitrary processes can run on the server, then the server SHOULD NOT indicate ACL support. On the other hand, if only trusted administrative programs run locally, then the server may indicate ACL support.

示例:假设服务器可以强制NFS访问的NFS ACL,但不能强制本地访问的ACL。如果服务器上可以运行任意进程,则服务器不应指示ACL支持。另一方面,如果只有受信任的管理程序在本地运行,则服务器可能指示ACL支持。

5.11.2. ACE Access Mask
5.11.2. 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
        
   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

(非ACL)删除文件的权限删除文件的权限读取ACL的权限读取ACL的权限写入ACL的权限写入ACL的权限更改所有者的权限在服务器上通过同步读取和写入本地访问文件的同步权限

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_DELETE               = 0x00010000;
   const ACE4_READ_ACL             = 0x00020000;
   const ACE4_WRITE_ACL            = 0x00040000;
   const ACE4_WRITE_OWNER          = 0x00080000;
   const ACE4_SYNCHRONIZE          = 0x00100000;
        
   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;
        

Server implementations need not provide the granularity of control that is implied by this list of masks. For example, POSIX-based systems might not distinguish APPEND_DATA (the ability to append to a file) from WRITE_DATA (the ability to modify existing contents); both masks would be tied to a single "write" permission. When such a server returns attributes to the client, it would show both APPEND_DATA and WRITE_DATA if and only if the write permission is enabled.

服务器实现不需要提供此掩码列表所暗示的控制粒度。例如,基于POSIX的系统可能无法区分APPEND_数据(附加到文件的能力)和WRITE_数据(修改现有内容的能力);两个掩码都将绑定到一个“写入”权限。当这样的服务器向客户机返回属性时,如果且仅当启用了写入权限时,它将同时显示APPEND_数据和WRITE_数据。

If a server receives a SETATTR request that it cannot accurately implement, it should error in the direction of more restricted access. For example, suppose a server cannot distinguish overwriting data from appending new data, as described in the previous paragraph. If a client submits an ACE where APPEND_DATA is set but WRITE_DATA is not (or vice versa), the server should reject the request with NFS4ERR_ATTRNOTSUPP. Nonetheless, if the ACE has type DENY, the server may silently turn on the other bit, so that both APPEND_DATA and WRITE_DATA are denied.

如果服务器接收到无法准确实现的SETATTR请求,则应该向更受限的访问方向出错。例如,假设服务器无法区分覆盖数据和追加新数据,如前一段所述。如果客户端提交了一个ACE,其中设置了APPEND_数据,但未设置WRITE_数据(反之亦然),则服务器应使用NFS4ERR_ATTRNOTSUPP拒绝该请求。尽管如此,如果ACE的类型为DENY,服务器可能会自动打开另一位,这样APPEND_数据和WRITE_数据都会被拒绝。

5.11.3. ACE flag
5.11.3. 王牌旗

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

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

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

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

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

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

ACE4_INHERIT_ONLY_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_INHERIT_ONLY_ACE可放置在目录上,但不适用于该目录,仅适用于上述两个标志指定的新创建的文件/目录。

ACE4_NO_PROPAGATE_INHERIT_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.

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

ACE4_SUCCESSFUL_ACCESS_ACE_FLAG

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

ACL4_FAILED_ACCESS_ACE_FLAG The ACE4_SUCCESSFUL_ACCESS_ACE_FLAG (SUCCESS) and ACE4_FAILED_ACCESS_ACE_FLAG (FAILED) flag bits relate only to ACE4_SYSTEM_AUDIT_ACE_TYPE (AUDIT) and ACE4_SYSTEM_ALARM_ACE_TYPE (ALARM) ACE types. If during the processing of the file's ACL, the server encounters an AUDIT or ALARM ACE that matches the principal attempting the OPEN, the server notes that fact, and the presence, if any, of the SUCCESS and FAILED flags encountered in the AUDIT or ALARM ACE. Once the server completes the ACL processing, and the share reservation processing, and the OPEN call, it then notes if the OPEN succeeded or failed. If the OPEN succeeded, and if the SUCCESS flag was set for a matching AUDIT or ALARM, then the appropriate AUDIT or ALARM event occurs. If the OPEN failed, and if the FAILED flag was set for the matching AUDIT or ALARM, then the appropriate AUDIT or ALARM event occurs. Clearly either or both of the SUCCESS or FAILED can be set, but if neither is set, the AUDIT or ALARM ACE is not useful.

ACL4\u失败访问\u ACE\u标志ACE4\u成功访问\u ACE\u标志(成功)和ACE4\u失败访问\u ACE\u标志(失败)位仅与ACE4\u系统审计\u ACE\u类型(审计)和ACE4\u系统报警\u类型(报警)ACE类型相关。如果在处理文件的ACL期间,服务器遇到与尝试打开的主体匹配的审核或报警ACE,则服务器会注意到该事实以及审核或报警ACE中遇到的成功和失败标志(如果有)。服务器完成ACL处理、共享保留处理和打开调用后,会记录打开是成功还是失败。如果打开成功,并且为匹配的审核或报警设置了成功标志,则会发生相应的审核或报警事件。如果打开失败,并且如果为匹配的审核或报警设置了失败标志,则会发生相应的审核或报警事件。显然,可以设置成功或失败中的一个或两个,但如果两个都未设置,则审计或报警ACE将无效。

The previously described processing applies to that of the ACCESS operation as well. The difference being that "success" or "failure" does not mean whether ACCESS returns NFS4_OK or not. Success means whether ACCESS returns all requested and supported bits. Failure means whether ACCESS failed to return a bit that was requested and supported.

前面描述的处理也适用于访问操作的处理。区别在于“成功”或“失败”并不意味着访问是否返回NFS4_OK。成功意味着访问是否返回所有请求和支持的位。失败意味着访问是否未能返回请求和支持的位。

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

ACE4_IDENTIFIER_GROUP表示“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;
        

A server need not support any of these flags. If the server supports flags that are similar to, but not exactly the same as, these flags, the implementation may define a mapping between the protocol-defined flags and the implementation-defined flags. Again, the guiding principle is that the file not appear to be more secure than it really is.

服务器不需要支持这些标志中的任何一个。如果服务器支持与这些标志相似但不完全相同的标志,则实现可以定义协议定义标志和实现定义标志之间的映射。同样,指导原则是,文件看起来并不比实际更安全。

For example, suppose a client tries to set an ACE with ACE4_FILE_INHERIT_ACE set but not ACE4_DIRECTORY_INHERIT_ACE. If the server does not support any form of ACL inheritance, the server should reject the request with NFS4ERR_ATTRNOTSUPP. If the server supports a single "inherit ACE" flag that applies to both files and directories, the server may reject the request (i.e., requiring the client to set both the file and directory inheritance flags). The server may also accept the request and silently turn on the ACE4_DIRECTORY_INHERIT_ACE flag.

例如,假设客户机尝试使用ACE4\u文件\u继承\u ACE集设置ACE,但不使用ACE4\u目录\u继承\u ACE。如果服务器不支持任何形式的ACL继承,则服务器应使用NFS4ERR_ATTRNOTSUPP拒绝请求。如果服务器支持应用于文件和目录的单个“继承ACE”标志,则服务器可能会拒绝该请求(即,要求客户端同时设置文件和目录继承标志)。服务器也可以接受请求并静默地打开ACE4\u目录\u继承\u ACE标志。

5.11.4. ACE who
5.11.4. 王牌谁

There are several special identifiers ("who") which need to be understood universally, rather than in the context of a particular DNS domain. 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, even if none of the access methods on the server understands the identifiers.

有几个特殊标识符(“who”)需要普遍理解,而不是在特定DNS域的上下文中。其中一些标识符在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@.

5.11.5. Mode Attribute
5.11.5. 模式属性

The NFS version 4 mode attribute is based on the UNIX mode bits. The following bits are defined:

NFS版本4模式属性基于UNIX模式位。定义了以下位:

      const MODE4_SUID = 0x800;  /* set user id on execution */
      const MODE4_SGID = 0x400;  /* set group id on execution */
      const MODE4_SVTX = 0x200;  /* save text even after use */
      const MODE4_RUSR = 0x100;  /* read permission: owner */
      const MODE4_WUSR = 0x080;  /* write permission: owner */
      const MODE4_XUSR = 0x040;  /* execute permission: owner */
      const MODE4_RGRP = 0x020;  /* read permission: group */
      const MODE4_WGRP = 0x010;  /* write permission: group */
      const MODE4_XGRP = 0x008;  /* execute permission: group */
      const MODE4_ROTH = 0x004;  /* read permission: other */
      const MODE4_WOTH = 0x002;  /* write permission: other */
      const MODE4_XOTH = 0x001;  /* execute permission: other */
        
      const MODE4_SUID = 0x800;  /* set user id on execution */
      const MODE4_SGID = 0x400;  /* set group id on execution */
      const MODE4_SVTX = 0x200;  /* save text even after use */
      const MODE4_RUSR = 0x100;  /* read permission: owner */
      const MODE4_WUSR = 0x080;  /* write permission: owner */
      const MODE4_XUSR = 0x040;  /* execute permission: owner */
      const MODE4_RGRP = 0x020;  /* read permission: group */
      const MODE4_WGRP = 0x010;  /* write permission: group */
      const MODE4_XGRP = 0x008;  /* execute permission: group */
      const MODE4_ROTH = 0x004;  /* read permission: other */
      const MODE4_WOTH = 0x002;  /* write permission: other */
      const MODE4_XOTH = 0x001;  /* execute permission: other */
        

Bits MODE4_RUSR, MODE4_WUSR, and MODE4_XUSR apply to the principal identified in the owner attribute. Bits MODE4_RGRP, MODE4_WGRP, and

位MODE4_RUSR、MODE4_WUSR和MODE4_XUSR应用于所有者属性中标识的主体。位模式4_RGRP、模式4_WGRP和

MODE4_XGRP apply to the principals identified in the owner_group attribute. Bits MODE4_ROTH, MODE4_WOTH, MODE4_XOTH apply to any principal that does not match that in the owner group, and does not have a group matching that of the owner_group attribute.

模式4_XGRP适用于所有者_组属性中标识的主体。Bits MODE4_ROTH、MODE4_WOTH、MODE4_XOTH适用于与所有者组中的主体不匹配的任何主体,并且没有与所有者组属性的主体匹配的组。

The remaining bits are not defined by this protocol and MUST NOT be used. The minor version mechanism must be used to define further bit usage.

其余位不由本协议定义,不得使用。次要版本机制必须用于定义进一步的位使用。

Note that in UNIX, if a file has the MODE4_SGID bit set and no MODE4_XGRP bit set, then READ and WRITE must use mandatory file locking.

请注意,在UNIX中,如果文件设置了MODE4_SGID位而未设置MODE4_XGRP位,则读写必须使用强制文件锁定。

5.11.6. Mode and ACL Attribute
5.11.6. 模式和ACL属性

The server that supports both mode and ACL must take care to synchronize the MODE4_*USR, MODE4_*GRP, and MODE4_*OTH bits with the ACEs which have respective who fields of "OWNER@", "GROUP@", and "EVERYONE@" so that the client can see semantically equivalent access permissions exist whether the client asks for owner, owner_group and mode attributes, or for just the ACL.

同时支持mode和ACL的服务器必须注意将MODE4_*USR、MODE4_*GRP和MODE4_*OTH位与ACE同步,ACE具有各自的who字段“OWNER@”、“GROUP@”和“EVERYONE@”,以便无论客户端是否请求OWNER、OWNER_GROUP和mode属性,客户端都可以看到语义上等价的访问权限存在,或者仅针对ACL。

Because the mode attribute includes bits (e.g., MODE4_SVTX) that have nothing to do with ACL semantics, it is permitted for clients to specify both the ACL attribute and mode in the same SETATTR operation. However, because there is no prescribed order for processing the attributes in a SETATTR, the client must ensure that ACL attribute, if specified without mode, would produce the desired mode bits, and conversely, the mode attribute if specified without ACL, would produce the desired "OWNER@", "GROUP@", and "EVERYONE@" ACEs.

由于mode属性包含与ACL语义无关的位(例如mode4svtx),因此允许客户端在同一SETATTR操作中同时指定ACL属性和mode。但是,由于没有规定处理SETATTR中属性的顺序,因此客户端必须确保ACL属性(如果在没有模式的情况下指定)将生成所需的模式位,反之,如果在没有ACL的情况下指定模式属性(如果在没有ACL的情况下指定),将生成所需的“所有者”、“组”和“所有人”ACE。

5.11.7. mounted_on_fileid
5.11.7. 已在\u文件ID上装入\u

UNIX-based operating environments connect a filesystem into the namespace by connecting (mounting) the filesystem onto the existing file object (the mount point, usually a directory) of an existing filesystem. When the mount point's parent directory is read via an API like readdir(), the return results are directory entries, each with a component name and a fileid. The fileid of the mount point's directory entry will be different from the fileid that the stat() system call returns. The stat() system call is returning the fileid of the root of the mounted filesystem, whereas readdir() is returning the fileid stat() would have returned before any filesystems were mounted on the mount point.

基于UNIX的操作环境通过将文件系统连接(装载)到现有文件系统的现有文件对象(装载点,通常是目录)上,将文件系统连接到名称空间。当通过readdir()之类的API读取装载点的父目录时,返回的结果是目录项,每个目录项都有一个组件名和一个文件ID。装载点目录项的fileid将不同于stat()系统调用返回的fileid。stat()系统调用返回已装入文件系统根目录的fileid,而readdir()返回的fileid stat()在装入点上装入任何文件系统之前都会返回。

Unlike NFS version 3, NFS version 4 allows a client's LOOKUP request to cross other filesystems. The client detects the filesystem crossing whenever the filehandle argument of LOOKUP has an fsid attribute different from that of the filehandle returned by LOOKUP. A UNIX-based client will consider this a "mount point crossing". UNIX has a legacy scheme for allowing a process to determine its current working directory. This relies on readdir() of a mount point's parent and stat() of the mount point returning fileids as previously described. The mounted_on_fileid attribute corresponds to the fileid that readdir() would have returned as described previously.

与NFS版本3不同,NFS版本4允许客户端的查找请求跨其他文件系统。只要LOOKUP的filehandle参数具有与LOOKUP返回的filehandle不同的fsid属性,客户机就会检测文件系统交叉。一个基于UNIX的客户端将考虑这是一个“挂载点交叉”。UNIX有一个遗留方案,允许进程确定其当前工作目录。这依赖于装载点的父级的readdir()和装载点的stat(),如前所述返回fileid。mounted_on_fileid属性对应于readdir()将返回的fileid,如前所述。

While the NFS version 4 client could simply fabricate a fileid corresponding to what mounted_on_fileid provides (and if the server does not support mounted_on_fileid, the client has no choice), there is a risk that the client will generate a fileid that conflicts with one that is already assigned to another object in the filesystem. Instead, if the server can provide the mounted_on_fileid, the potential for client operational problems in this area is eliminated.

虽然NFS版本4客户端可以简单地创建一个与mounted_on_fileid提供的内容相对应的fileid(如果服务器不支持mounted_on_fileid,则客户端别无选择),但客户端生成的fileid可能与已分配给文件系统中另一个对象的fileid冲突。相反,如果服务器可以提供挂载的\u on_文件ID,则可以消除此区域中客户端操作问题的可能性。

If the server detects that there is no mounted point at the target file object, then the value for mounted_on_fileid that it returns is the same as that of the fileid attribute.

如果服务器检测到目标文件对象上没有挂载点,那么它返回的\u fileid上挂载的\u的值与fileid属性的值相同。

The mounted_on_fileid attribute is RECOMMENDED, so the server SHOULD provide it if possible, and for a UNIX-based server, this is straightforward. Usually, mounted_on_fileid will be requested during a READDIR operation, in which case it is trivial (at least for UNIX-based servers) to return mounted_on_fileid since it is equal to the fileid of a directory entry returned by readdir(). If mounted_on_fileid is requested in a GETATTR operation, the server should obey an invariant that has it returning a value that is equal to the file object's entry in the object's parent directory, i.e., what readdir() would have returned. Some operating environments allow a series of two or more filesystems to be mounted onto a single mount point. In this case, for the server to obey the aforementioned invariant, it will need to find the base mount point, and not the intermediate mount points.

建议使用mounted_on_fileid属性,因此如果可能,服务器应该提供它,对于基于UNIX的服务器,这是很简单的。通常,在READDIR操作期间会请求在\u fileid上挂载的\u,在这种情况下,返回在\u fileid上挂载的\u很简单(至少对于基于UNIX的服务器而言),因为它等于READDIR()返回的目录项的fileid。如果在GETATTR操作中请求挂载在文件ID上的文件,则服务器应遵循一个不变量,该不变量使其返回一个值,该值等于对象父目录中文件对象的条目,即readdir()将返回的值。某些操作环境允许将一系列两个或多个文件系统装载到单个装载点上。在这种情况下,为了使服务器遵守上述不变量,它需要找到基本装载点,而不是中间装载点。

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

With the use of the recommended attribute "fs_locations", the NFS version 4 server has a method of providing filesystem migration or replication services. For the purposes of migration and replication, a filesystem 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 filesystem 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 filesystem. Depending on the type of service being provided, the list will provide a new location or a set of alternate locations for the filesystem. 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 filesystem replication will be used in the case of read-only data. Typically, the filesystem will be replicated on two or more servers. The fs_locations attribute will provide the

对于只读数据,预计将使用文件系统复制。通常,文件系统将在两个或多个服务器上复制。fs_locations属性将提供

list of these locations to the client. On first access of the filesystem, 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_位置指定的另一台服务器。

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. 迁移

Filesystem migration is used to move a filesystem from one server to another. Migration is typically used for a filesystem 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 filesystem 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 filesystem, 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 PUTFH and 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。除PUTFH和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 filesystem 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 {
           utf8str_cis     server<>;
           pathname4       rootpath;
   };
        
   struct fs_location {
           utf8str_cis     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 filesystem by providing a server name and the path to the root of the filesystem. 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 filesystem 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 filesystem at the various servers listed.

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

   As an example, there is a replicated filesystem located at two
   servers (servA and servB).  At servA the filesystem is located at
   path "/a/b/c".  At servB the filesystem is located at path "/x/y/z".
   In this example the client accesses the filesystem 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 filesystem'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
        
   As an example, there is a replicated filesystem located at two
   servers (servA and servB).  At servA the filesystem is located at
   path "/a/b/c".  At servB the filesystem is located at path "/x/y/z".
   In this example the client accesses the filesystem 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 filesystem'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.

“x/y/z”的路径。有了这些信息,客户端可以在其访问路径的开头用“/x/y/z”替换“/a/b/c”,并构造“/x/y/z/d”以用于新服务器。

See the section "Security Considerations" for a discussion on the recommendations for the security flavor to be used by any GETATTR operation that requests the "fs_locations" attribute.

有关请求“fs_locations”属性的任何GETATTR操作所使用的安全风格的建议的讨论,请参阅“安全注意事项”一节。

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

Filehandles for filesystems that are replicated or migrated generally have the same semantics as for filesystems that are not replicated or migrated. For example, if a filesystem has persistent filehandles and it is migrated to another server, the filehandle values for the filesystem 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 filehandle 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 filesystem 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 filesystem. 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 filesystem" that allows the user to browse from one mounted filesystem 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 Filesystem
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 filesystem" that provides a view of exported directories only. A pseudo filesystem has a unique fsid and behaves like a normal, read only filesystem.

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

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

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

   /a         pseudo filesystem
   /a/b       real filesystem
   /a/b/c     pseudo filesystem
   /a/b/c/d   real filesystem
        
   /a         pseudo filesystem
   /a/b       real filesystem
   /a/b/c     pseudo filesystem
   /a/b/c/d   real filesystem
        

Each of the pseudo filesystems are considered 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". Filesystems are commonly represented as disk letters. MacOS represents filesystems 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 filesystem is that it is a logical representation of filesystem(s) available from the server. Therefore, the pseudo filesystem is most likely constructed dynamically when the server is first instantiated. It is expected that the pseudo filesystem 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 filesystem, 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 filesystem is exported, one might conclude that a pseudo-filesystem is not needed. This would be wrong. Assume the following filesystems 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-filesystem.

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

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

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

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

         /a/b            (filesystem 1)
         /a/b/c/d        (filesystem 2)
        
         /a/b            (filesystem 1)
         /a/b/c/d        (filesystem 2)
        

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

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

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

It is the server's responsibility to present the pseudo filesystem 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 filesystem "/a/b/c/d". In previous versions of the NFS protocol, the server would respond with the filehandle of directory "/a/b/c/d" within the filesystem "/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 filesystem 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 filesystem, the server may effectively hide filesystems from a client that may otherwise have legitimate access.

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

As suggested practice, the server should apply the security policy of a shared resource in the server's namespace to the components of the resource's ancestors. For example:

按照建议的做法,服务器应将服务器命名空间中共享资源的安全策略应用于资源祖先的组件。例如:

         /
         /a/b
         /a/b/c
        
         /
         /a/b
         /a/b/c
        

The /a/b/c directory is a real filesystem and is the shared resource. The security policy for /a/b/c is Kerberos with integrity. The server should apply the same security policy to /, /a, and /a/b. This allows for the extension of the protection of the server's namespace to the ancestors of the real shared resource.

/a/b/c目录是一个真正的文件系统,是共享资源。/a/b/c的安全策略是具有完整性的Kerberos。服务器应将相同的安全策略应用于/、/a和/a/b。这允许将服务器名称空间的保护扩展到实际共享资源的祖先。

For the case of the use of multiple, disjoint security mechanisms in the server's resources, the security for a particular object in the server's namespace should be the union of all security mechanisms of all direct descendants.

对于在服务器资源中使用多个不相交的安全机制的情况,服务器命名空间中特定对象的安全性应该是所有直接子体的所有安全机制的联合。

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

Integrating locking into the NFS protocol necessarily causes it to be stateful. With the inclusion of share reservations 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 reservations 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 NFS version 3 methodology 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协议有一个开放操作,包含NFS版本3的查找、创建和访问方法。但是,由于许多操作需要文件句柄,因此保留了传统的查找方法,以便将文件名映射到文件句柄,而无需在服务器上建立状态。授予访问权限或修改文件的策略由服务器根据客户端的状态进行管理。这些机制可以实现从仅建议锁定到完全强制锁定的策略。

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. A sequence of a SETCLIENTID operation followed by a SETCLIENTID_CONFIRM operation is required to establish the identification onto the server. Establishment of identification by a new incarnation of the client also has the effect of immediately breaking any leased state that a previous incarnation of the client might have had on the server, as opposed to forcing the new client incarnation to wait for the leases to expire. Breaking the lease state amounts to the server removing all lock, share reservation, and, where the server is not supporting the CLAIM_DELEGATE_PREV claim type, all delegation state associated with same client with the same identity. For discussion of delegation state recovery, see the section "Delegation Recovery".

这是以允许正确识别锁和碰撞恢复的方式进行的。要在服务器上建立标识,需要先执行SETCLIENTID操作,然后执行SETCLIENTID_确认操作。通过客户机的新版本建立标识还具有立即中断客户机的前一版本可能在服务器上具有的任何租用状态的效果,而不是强制新客户机版本等待租用到期。破坏租约状态相当于服务器删除所有锁、共享保留,如果服务器不支持CLAIM_DELEGATE_PREV CLAIM类型,则删除与具有相同标识的同一客户端关联的所有委派状态。有关委派状态恢复的讨论,请参阅“委派恢复”一节。

Client identification is encapsulated in the following structure:

客户标识封装在以下结构中:

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

The first field, verifier is a client incarnation verifier that is used to detect client reboots. Only if the verifier is different from that which the server has previously recorded the client (as identified by the second field of the structure, id) does the server start the process of canceling the client's leased state.

第一个字段,verifier是用于检测客户端重新启动的客户端化身验证器。只有当验证器与服务器先前记录客户机的验证器不同(由结构的第二个字段id标识),服务器才会启动取消客户机租用状态的过程。

The second field, id is a variable length string that uniquely defines the client.

第二个字段id是唯一定义客户机的可变长度字符串。

There are several considerations for how the client generates the id string:

对于客户端如何生成id字符串,有几个注意事项:

o The string should be unique so that multiple clients do not present the same string. The consequences of two clients presenting the same string range from one client getting an error to one client having its leased state abruptly and unexpectedly canceled.

o 该字符串应该是唯一的,以便多个客户端不显示相同的字符串。两个客户端呈现相同字符串的后果从一个客户端出错到一个客户端的租用状态突然意外取消。

o The string should be selected so the subsequent incarnations (e.g., reboots) of the same client cause the client to present the same string. The implementor is cautioned against an approach that requires the string to be recorded in a local file because this precludes the use of the implementation in an environment where there is no local disk and all file access is from an NFS version 4 server.

o 应选择该字符串,以便同一客户端的后续化身(例如,重新启动)使客户端呈现相同的字符串。提醒实现者不要使用要求将字符串记录在本地文件中的方法,因为这会妨碍在没有本地磁盘且所有文件访问都来自NFS版本4服务器的环境中使用实现。

o The string should be different for each server network address that the client accesses, rather than common to all server network addresses. The reason is that it may not be possible for the client to tell if the same server is listening on multiple network addresses. If the client issues SETCLIENTID with the same id string to each network address of such a server, the server will think it is the same client, and each successive SETCLIENTID will cause the server to begin the process of removing the client's previous leased state.

o 对于客户端访问的每个服务器网络地址,字符串应该是不同的,而不是所有服务器网络地址的公共字符串。原因是客户端可能无法判断同一服务器是否正在侦听多个网络地址。如果客户机向此类服务器的每个网络地址发出具有相同id字符串的SETCLIENTID,则服务器将认为它是同一个客户机,并且每个连续的SETCLIENTID将导致服务器开始删除客户机以前的租用状态。

o The algorithm for generating the string should not assume that the client's network address won't change. This includes changes between client incarnations and even changes while the client is stilling running in its current incarnation. This means that if the client includes just the client's and server's network address in the id string, there is a real risk, after the client gives up the network address, that another client, using a similar algorithm for generating the id string, will generate a conflicting id string.

o 生成字符串的算法不应假定客户端的网络地址不会改变。这包括客户端化身之间的更改,甚至在客户端仍在当前化身中运行时的更改。这意味着,如果客户机在id字符串中仅包含客户机和服务器的网络地址,则在客户机放弃网络地址后,另一个客户机将使用类似的算法生成id字符串,从而产生冲突的id字符串。

Given the above considerations, an example of a well generated id string is one that includes:

鉴于上述考虑,生成良好的id字符串示例包括:

o The server's network address.

o 服务器的网络地址。

o The client's network address.

o 客户端的网络地址。

o For a user level NFS version 4 client, it should contain additional information to distinguish the client from other user level clients running on the same host, such as a process id or other unique sequence.

o 对于用户级NFS版本4客户端,它应该包含其他信息,以便将客户端与运行在同一主机上的其他用户级客户端区分开来,例如进程id或其他唯一序列。

o Additional information that tends to be unique, such as one or more of:

o 倾向于唯一的附加信息,例如一个或多个:

- The client machine's serial number (for privacy reasons, it is best to perform some one way function on the serial number).

- 客户端计算机的序列号(出于隐私原因,最好对序列号执行某种单向功能)。

- A MAC address.

- MAC地址。

- The timestamp of when the NFS version 4 software was first installed on the client (though this is subject to the previously mentioned caution about using information that is stored in a file, because the file might only be accessible over NFS version 4).

- 首次在客户端上安装NFS版本4软件时的时间戳(尽管这取决于前面提到的关于使用存储在文件中的信息的注意事项,因为该文件可能只能通过NFS版本4访问)。

- A true random number. However since this number ought to be the same between client incarnations, this shares the same problem as that of the using the timestamp of the software installation.

- 真随机数。然而,由于这个数字在客户端化身之间应该是相同的,所以这和使用软件安装的时间戳有着相同的问题。

As a security measure, the server MUST NOT cancel a client's leased state if the principal established the state for a given id string is not the same as the principal issuing the SETCLIENTID.

作为安全措施,如果为给定id字符串建立状态的主体与发出SETCLIENTID的主体不同,则服务器不得取消客户端的租用状态。

Note that SETCLIENTID and SETCLIENTID_CONFIRM has a secondary purpose of establishing the information the server needs to make callbacks to the client for purpose of supporting delegations. It is permitted to change this information via SETCLIENTID and SETCLIENTID_CONFIRM within the same incarnation of the client without removing the client's leased state.

请注意,SETCLIENTID和SETCLIENTID_CONFIRM的第二个目的是建立服务器回调客户端以支持委托所需的信息。允许在客户端的同一版本中通过SETCLIENTID和SETCLIENTID_CONFIRM更改此信息,而无需删除客户端的已租用状态。

Once a SETCLIENTID and SETCLIENTID_CONFIRM sequence has successfully completed, the client uses the shorthand client identifier, of type clientid4, instead of the longer and less compact nfs_client_id4 structure. This shorthand client identifier (a clientid) is assigned by the server and 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").

成功完成SETCLIENTID和SETCLIENTID_确认序列后,客户端将使用ClientD4类型的速记客户端标识符,而不是较长且不太紧凑的nfs_client_id4结构。此速记客户端标识符(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 "lock_owner and stateid Definition" for details).

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

See the detailed descriptions of SETCLIENTID and SETCLIENTID_CONFIRM for a complete specification of the operations.

有关操作的完整规范,请参阅SETCLIENTID和SETCLIENTID_CONFIRM的详细说明。

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,除非该客户机在几分钟内没有任何活动。

Note that if the id string in a SETCLIENTID request is properly constructed, and if the client takes care to use the same principal for each successive use of SETCLIENTID, then, barring an active denial of service attack, NFS4ERR_CLID_INUSE should never be returned.

请注意,如果SETCLIENTID请求中的id字符串构造正确,并且如果客户端注意在每次连续使用SETCLIENTID时使用相同的主体,则除非发生主动拒绝服务攻击,否则不应返回NFS4ERR_CLID_INUSE。

However, client bugs, server bugs, or perhaps a deliberate change of the principal owner of the id string (such as the case of a client that changes security flavors, and under the new flavor, there is no mapping to the previous owner) will in rare cases result in NFS4ERR_CLID_INUSE.

但是,客户端错误、服务器错误,或者故意更改id字符串的主要所有者(例如更改安全风格的客户端,在新风格下,没有映射到以前的所有者)在极少数情况下会导致NFS4ERR_CLID_使用。

In that event, when the server gets a SETCLIENTID for a client id that currently has no state, or it has state, but the lease has expired, rather than returning NFS4ERR_CLID_INUSE, the server MUST allow the SETCLIENTID, and confirm the new clientid if followed by the appropriate SETCLIENTID_CONFIRM.

在这种情况下,当服务器为当前没有状态或有状态但租约已过期的客户端id获取SETCLIENTID时,而不是返回NFS4ERR_CLID_INUSE,服务器必须允许SETCLIENTID,并确认新的clientid(如果后跟相应的SETCLIENTID_confirm)。

8.1.3. lock_owner and stateid Definition
8.1.3. 锁所有者和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 lock_owner and the definition of those fields are:

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

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 stateid. The stateid is used as a shorthand reference to the lock_owner, since the server will be maintaining the correspondence between them.

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

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,

可用于满足这些要求的一种机制是服务器,

o divide the "other" field of each stateid into two fields:

o 将每个stateid的“其他”字段分为两个字段:

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

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

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

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

o utilize the "seqid" field of each stateid, such that seqid is monotonically incremented for each stateid that is associated with the same index into the locking-state table.

o 利用每个stateid的“seqid”字段,使得与锁状态表中的相同索引关联的每个stateid的seqid单调递增。

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 and Locking
8.1.4. stateid和锁定的使用

All READ, WRITE and SETATTR operations contain a stateid. For the purposes of this section, SETATTR operations which change the size attribute of a file are treated as if they are writing the area between the old and new size (i.e., the range truncated or added to the file by means of the SETATTR), even where SETATTR is not explicitly mentioned in the text.

所有读、写和SETATTR操作都包含stateid。在本节中,更改文件大小属性的SETATTR操作被视为写入新旧大小之间的区域(即通过SETATTR截断或添加到文件中的范围),即使文本中未明确提及SETATTR。

If the lock_owner performs a READ or WRITE in a situation in which it has established a lock or share reservation on the server (any OPEN constitutes a share reservation) the stateid (previously returned by the server) must be used to indicate what locks, including both record locks and share reservations, are held by the lockowner. If no state is established by the client, either record lock or share reservation, a stateid of all bits 0 is used. Regardless whether a stateid of all bits 0, or a stateid returned by the server is used, if there is a conflicting share reservation or mandatory record lock held on the file, the server MUST refuse to service the READ or WRITE operation.

如果锁所有者在其已在服务器上建立锁或共享保留的情况下执行读或写操作(任何打开的都构成共享保留),则必须使用stateid(以前由服务器返回)来指示锁所有者持有哪些锁,包括记录锁和共享保留。如果客户端未建立状态(记录锁定或共享保留),则使用所有位0的stateid。无论使用的是所有位为0的stateid还是服务器返回的stateid,如果文件上存在冲突的共享保留或强制记录锁定,服务器必须拒绝为读或写操作提供服务。

Share reservations are established by OPEN operations and by their nature are mandatory in that when the OPEN denies READ or WRITE operations, that denial results in such operations being rejected with error NFS4ERR_LOCKED. Record locks may be implemented by the server as either mandatory or advisory, or the choice of mandatory or advisory behavior may be determined by the server on the basis of the file being accessed (for example, some UNIX-based servers support a "mandatory lock bit" on the mode attribute such that if set, record locks are required on the file before I/O is possible). When record locks are advisory, they only prevent the granting of conflicting lock requests and have no effect on READs or WRITEs. Mandatory record locks, however, prevent conflicting I/O operations. When they are attempted, they are rejected with NFS4ERR_LOCKED. When the client gets NFS4ERR_LOCKED on a file it knows it has the proper share reservation for, it will need to issue a LOCK request on the region

共享保留是由开放操作建立的,其性质是强制性的,因为当开放操作拒绝读或写操作时,该拒绝会导致此类操作被拒绝,并出现错误NFS4ERR_LOCKED。服务器可以将记录锁实现为强制或建议,也可以根据所访问的文件决定强制或建议行为的选择(例如,一些基于UNIX的服务器支持“强制锁位”在mode属性上,如果设置了,则需要在文件上设置记录锁,然后才能进行I/O)。当记录锁是建议性的时,它们只会阻止授予冲突的锁请求,对读或写没有影响。但是,强制记录锁可以防止I/O操作冲突。尝试这些操作时,会被拒绝并锁定NFS4ERR_。当客户端在其知道其具有适当的共享保留的文件上锁定NFS4ERR_时,它将需要对该区域发出锁定请求

of the file that includes the region the I/O was to be performed on, with an appropriate locktype (i.e., READ*_LT for a READ operation, WRITE*_LT for a WRITE operation).

包含要在其上执行I/O的区域的文件的,具有适当的锁类型(即,对于读取操作为READ*\u LT,对于写入操作为WRITE*\u LT)。

With NFS version 3, there was no notion of a stateid so there was no way to tell if the application process of the client sending the READ or WRITE operation had also acquired the appropriate record lock on the file. Thus there was no way to implement mandatory locking. With the stateid construct, this barrier has been removed.

对于NFS版本3,没有stateid的概念,因此无法判断发送读或写操作的客户端的应用程序进程是否也获得了文件上的相应记录锁。因此,无法实现强制锁定。通过stateid构造,该障碍已被移除。

Note that for UNIX environments that support mandatory file locking, the distinction between advisory and mandatory locking is subtle. In fact, advisory and mandatory record locks are exactly the same in so far as the APIs and requirements on implementation. If the mandatory lock attribute is set on the file, the server checks to see if the lockowner has an appropriate shared (read) or exclusive (write) record lock on the region it wishes to read or write to. If there is no appropriate lock, the server checks if there is a conflicting lock (which can be done by attempting to acquire the conflicting lock on the behalf of the lockowner, and if successful, release the lock after the READ or WRITE is done), and if there is, the server returns NFS4ERR_LOCKED.

请注意,对于支持强制文件锁定的UNIX环境,建议锁定和强制锁定之间的区别很微妙。事实上,就API和实现要求而言,咨询锁和强制记录锁是完全相同的。如果在文件上设置了强制锁定属性,服务器将检查lockowner在其希望读取或写入的区域上是否具有适当的共享(读取)或独占(写入)记录锁定。如果没有合适的锁,服务器将检查是否存在冲突锁(可以通过代表锁所有者尝试获取冲突锁来实现,如果成功,则在读取或写入完成后释放锁),如果存在冲突锁,服务器将返回NFS4ERR_LOCKED。

For Windows environments, there are no advisory record locks, so the server always checks for record locks during I/O requests.

对于Windows环境,没有建议记录锁,因此服务器在I/O请求期间始终检查记录锁。

Thus, the NFS version 4 LOCK operation does not need to distinguish between advisory and mandatory record locks. It is the NFS version 4 server's processing of the READ and WRITE operations that introduces the distinction.

因此,NFS版本4锁定操作不需要区分建议锁定和强制记录锁定。正是NFS版本4服务器对读写操作的处理引入了这种区别。

Every stateid other than the special stateid values noted in this section, whether returned by an OPEN-type operation (i.e., OPEN, OPEN_DOWNGRADE), or by a LOCK-type operation (i.e., LOCK or LOCKU), defines an access mode for the file (i.e., READ, WRITE, or READ-WRITE) as established by the original OPEN which began the stateid sequence, and as modified by subsequent OPENs and OPEN_DOWNGRADEs within that stateid sequence. When a READ, WRITE, or SETATTR which specifies the size attribute, is done, the operation is subject to checking against the access mode to verify that the operation is appropriate given the OPEN with which the operation is associated.

除本节中注明的特殊stateid值之外的每个stateid,无论是由开放式操作(即OPEN、OPEN_降级)返回,还是由锁式操作(即LOCK或LOCKU)返回,都定义了文件的访问模式(即读、写或读写),该模式由开始stateid序列的原始OPEN建立,并在该stateid序列中通过后续OPEN和OPEN_降级进行修改。当完成指定大小属性的读取、写入或SETATTR时,该操作将根据访问模式进行检查,以验证该操作是否适合与该操作关联的打开项。

In the case of WRITE-type operations (i.e., WRITEs and SETATTRs which set size), the server must verify that the access mode allows writing and return an NFS4ERR_OPENMODE error if it does not. In the case, of READ, the server may perform the corresponding check on the access mode, or it may choose to allow READ on opens for WRITE only, to accommodate clients whose write implementation may unavoidably do

对于写入类型操作(即设置大小的写入和设置属性),服务器必须验证访问模式是否允许写入,如果不允许,则返回NFS4ERR_OPENMODE错误。在读取的情况下,服务器可以在访问模式上执行相应的检查,或者可以选择允许仅为写入而打开的读取,以容纳写入实现可能不可避免地执行的客户端

reads (e.g., due to buffer cache constraints). However, even if READs are allowed in these circumstances, the server MUST still check for locks that conflict with the READ (e.g., another open specify denial of READs). Note that a server which does enforce the access mode check on READs need not explicitly check for conflicting share reservations since the existence of OPEN for read access guarantees that no conflicting share reservation can exist.

读取(例如,由于缓冲区缓存限制)。但是,即使在这些情况下允许读取,服务器仍必须检查与读取冲突的锁(例如,另一个打开的指定拒绝读取)。请注意,对读取执行访问模式检查的服务器不需要显式检查冲突的共享保留,因为开放式读取访问的存在保证不存在冲突的共享保留。

A stateid of all bits 1 (one) MAY allow READ operations to bypass locking checks at the server. However, WRITE operations with a stateid with bits all 1 (one) MUST NOT bypass locking checks and are treated exactly the same as if a stateid of all bits 0 were used.

所有位1(1)的stateid可允许读取操作绕过服务器上的锁定检查。但是,使用位为all 1(一)的stateid的写操作不能绕过锁定检查,并且处理方式与使用位为0的stateid时完全相同。

A lock may not be granted while a READ or WRITE operation using one of the special stateids is being performed and the range of the lock request conflicts with the range of the READ or WRITE operation. For the purposes of this paragraph, a conflict occurs when a shared lock is requested and a WRITE operation is being performed, or an exclusive lock is requested and either a READ or a WRITE operation is being performed. A SETATTR that sets size is treated similarly to a WRITE as discussed above.

在执行使用一个特殊StateID的读或写操作时,可能不会授予锁,并且锁请求的范围与读或写操作的范围冲突。在本段中,当请求共享锁并执行写入操作时,或请求独占锁并执行读取或写入操作时,会发生冲突。设置大小的SETATTR与上面讨论的写入类似。

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 lock_owners have different sequences. The server maintains the last sequence number (L) received and the response that was returned. The first request issued for any given lock_owner is issued with a sequence number of zero.

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

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

请注意,对于包含序列号的请求,对于每个锁所有者,不应该有多个未完成的请求。

If a request (r) 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 SETCLIENTID/SETCLIENTID_CONFIRM sequence changes the client verifier.

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

Since the sequence number is represented with an unsigned 32-bit integer, the arithmetic involved with the sequence number is mod 2^32. For an example of modulo arithmetic involving sequence numbers see [RFC793].

由于序列号用无符号32位整数表示,因此与序列号相关的算术为mod 2^32。有关涉及序列号的模运算示例,请参见[RFC793]。

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 lock_owner must be cached as long as the lock state exists on the server.

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

The client MUST monotonically increment the sequence number for the CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE operations. This is true even in the event that the previous operation that used the sequence number received an error. The only exception to this rule is if the previous operation received one of the following errors: NFS4ERR_STALE_CLIENTID, NFS4ERR_STALE_STATEID, NFS4ERR_BAD_STATEID, NFS4ERR_BAD_SEQID, NFS4ERR_BADXDR, NFS4ERR_RESOURCE, NFS4ERR_NOFILEHANDLE.

客户端必须单调递增关闭、锁定、锁定、打开、打开确认和打开降级操作的序列号。即使在使用序列号的前一个操作收到错误的情况下也是如此。此规则的唯一例外是,如果上一个操作收到以下错误之一:NFS4ERR_STALE_CLIENTID、NFS4ERR_STALE_STATEID、NFS4ERR_BAD_STATEID、NFS4ERR_BAD_SEQID、NFS4ERR_BADXDR、NFS4ERR_资源、NFS4ERR_NOFILEHANDLE。

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

As described above, the sequence number is per lock_owner. 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 (lock_owner, sequence number) state as long as there are open files or closed files with locks outstanding.

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

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 lock_owner state.

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

8.1.7. Releasing lock_owner State
8.1.7. 正在释放所有者状态的锁

When a particular lock_owner no longer holds open or file locking state at the server, the server may choose to release the sequence number state associated with the lock_owner. 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 lock_owner no longer is being utilized by the client. The server may choose to hold the lock_owner state in the event that retransmitted requests are received. However, the period to hold this state is implementation specific.

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

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

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

8.1.8. Use of Open Confirmation
8.1.8. 公开确认的使用

In the case that an OPEN is retransmitted and the lock_owner is being used for the first time or the lock_owner 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 lock_owner 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 lock_owner and associated sequence number. Since the OPEN_CONFIRM sequence connects a new open_owner on the server with an existing open_owner on a client, the sequence number may have any value. The OPEN_CONFIRM step assures the server that the value received is the correct one. See the section "OPEN_CONFIRM - Confirm Open" for further details.

在重新传输OPEN且首次使用lock_所有者或服务器先前已释放lock_所有者状态的情况下,使用OPEN_确认操作将防止错误行为。当服务器第一次观察到锁所有者的使用时,它将指示客户端对相应的打开执行打开确认。该序列确定了锁所有者和相关序列号的使用。由于OPEN_CONFIRM序列将服务器上的新OPEN_所有者与客户端上的现有OPEN_所有者连接起来,因此序列号可以有任何值。打开确认步骤可确保服务器收到的值是正确的。有关更多详细信息,请参阅“打开\确认-确认打开”一节。

There are a number of situations in which the requirement to confirm an OPEN would pose difficulties for the client and server, in that they would be prevented from acting in a timely fashion on information received, because that information would be provisional, subject to deletion upon non-confirmation. Fortunately, these are situations in which the server can avoid the need for confirmation when responding to open requests. The two constraints are:

在许多情况下,确认开放的要求会给客户机和服务器带来困难,因为它们无法及时处理收到的信息,因为这些信息是临时性的,在未确认时会被删除。幸运的是,在这些情况下,服务器可以避免在响应打开的请求时进行确认。这两个限制是:

o The server must not bestow a delegation for any open which would require confirmation.

o 服务器不得为任何需要确认的打开授予委派。

o The server MUST NOT require confirmation on a reclaim-type open (i.e., one specifying claim type CLAIM_PREVIOUS or CLAIM_DELEGATE_PREV).

o 服务器不得要求确认打开的回收类型(即指定索赔类型claim_PREVIOUS或claim_DELEGATE_PREV的类型)。

These constraints are related in that reclaim-type opens are the only ones in which the server may be required to send a delegation. For CLAIM_NULL, sending the delegation is optional while for CLAIM_DELEGATE_CUR, no delegation is sent.

这些约束是相关的,因为回收类型是服务器可能需要发送委派的唯一约束。对于CLAIM_NULL,发送委派是可选的,而对于CLAIM_DELEGATE_CUR,不发送委派。

Delegations being sent with an open requiring confirmation are troublesome because recovering from non-confirmation adds undue complexity to the protocol while requiring confirmation on reclaim-type opens poses difficulties in that the inability to resolve

发送带有需要确认的开放式委托的委托很麻烦,因为从未确认中恢复会给协议增加不必要的复杂性,而要求对回收类型的开放式委托进行确认会带来困难,因为无法解决此问题

the status of the reclaim until lease expiration may make it difficult to have timely determination of the set of locks being reclaimed (since the grace period may expire).

租约到期前的回收状态可能会导致很难及时确定要回收的锁集(因为宽限期可能会到期)。

Requiring open confirmation on reclaim-type opens is avoidable because of the nature of the environments in which such opens are done. For CLAIM_PREVIOUS opens, this is immediately after server reboot, so there should be no time for lockowners to be created, found to be unused, and recycled. For CLAIM_DELEGATE_PREV opens, we are dealing with a client reboot situation. A server which supports delegation can be sure that no lockowners for that client have been recycled since client initialization and thus can ensure that confirmation will not be required.

由于执行此类打开的环境的性质,可以避免要求对回收类型打开进行打开确认。对于之前打开的CLAIM_,这是在服务器重新启动后立即打开的,因此应该没有时间创建、发现未使用和回收锁所有者。对于CLAIM_DELEGATE_PREV打开,我们正在处理客户端重新启动的情况。支持委托的服务器可以确保自客户端初始化以来没有回收该客户端的锁所有者,因此可以确保不需要确认。

8.2. Lock Ranges
8.2. 锁定范围

The protocol allows a lock owner to request a lock with a 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 filesystems 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. Upgrading and Downgrading Locks
8.3. 升级和降级锁

If a client has a write lock on a record, it can request an atomic downgrade of the lock to a read lock via the LOCK request, by setting the type to READ_LT. If the server supports atomic downgrade, the request will succeed. If not, it will return NFS4ERR_LOCK_NOTSUPP. The client should be prepared to receive this error, and if appropriate, report the error to the requesting application.

如果客户机在记录上有写锁,它可以通过锁请求请求将锁的原子降级为读锁,方法是将类型设置为read\LT。如果服务器支持原子降级,则请求将成功。否则,它将返回NFS4ERR\u LOCK\u NOTSUPP。客户机应该准备好接收此错误,如果合适,将错误报告给请求的应用程序。

If a client has a read lock on a record, it can request an atomic upgrade of the lock to a write lock via the LOCK request by setting the type to WRITE_LT or WRITEW_LT. If the server does not support atomic upgrade, it will return NFS4ERR_LOCK_NOTSUPP. If the upgrade can be achieved without an existing conflict, the request will succeed. Otherwise, the server will return either NFS4ERR_DENIED or NFS4ERR_DEADLOCK. The error NFS4ERR_DEADLOCK is returned if the client issued the LOCK request with the type set to WRITEW_LT and the server has detected a deadlock. The client should be prepared to receive such errors and if appropriate, report the error to the requesting application.

如果客户机对记录具有读锁,则可以通过将类型设置为write_LT或WRITEW_LT,通过锁请求将锁的原子升级为写锁。如果服务器不支持原子升级,它将返回NFS4ERR_lock_NOTSUPP。如果可以在不存在冲突的情况下实现升级,则请求将成功。否则,服务器将返回NFS4ERR_DENIED或NFS4ERR_DEADLOCK。如果客户端发出类型设置为WRITEW_LT的锁请求,并且服务器检测到死锁,则返回错误NFS4ERR_DEADLOCK。客户应做好接收此类错误的准备,并在适当的情况下向请求的应用程序报告错误。

8.4. Blocking Locks
8.4. 闭锁

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.5. Lease Renewal
8.5. 续租

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 that the associated state held at the server, for the client, is still valid.

以下事件会导致对给定客户(即共享给定客户ID的所有客户)的所有租约进行隐式续订。每一个都是一个积极的迹象,表明客户端仍然处于活动状态,并且服务器上为客户端保留的关联状态仍然有效。

o An OPEN with a valid clientid.

o 具有有效clientid的打开的。

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

o 使用有效stateid进行的任何操作(CLOSE、DELEGPURGE、DELEGRETURN、LOCK、LOCKU、OPEN、OPEN\u CONFIRM、OPEN\u Degrade、READ、RENEW、SETATTR、WRITE)。这不包括所有位0或所有位1的特殊StateID。

Note that if the client had restarted or rebooted, the client would not be making these requests without issuing the SETCLIENTID/SETCLIENTID_CONFIRM sequence. The use of the SETCLIENTID/SETCLIENTID_CONFIRM sequence (one that changes the client verifier) notifies the server to drop the locking state associated with the client. SETCLIENTID/SETCLIENTID_CONFIRM never renews a lease.

请注意,如果客户端已重新启动或重新启动,则在未发出SETCLIENTID/SETCLIENTID_确认序列的情况下,客户端不会发出这些请求。使用SETCLIENTID/SETCLIENTID_确认序列(更改客户端验证器的序列)通知服务器放弃与客户端关联的锁定状态。SETCLIENTID/SETCLIENTID\u确认从不续订租约。

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.6. Crash Recovery
8.6. 事故恢复

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.6.1. Client Failure and Recovery
8.6.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 clientid 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 CONFIRM确认clientid的使用。然后,客户端将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相关联的所有锁。

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

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

8.6.2. Server Failure and Recovery
8.6.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

当客户端收到两个错误中的一个错误时,它可以确定服务器发生故障(从而失去锁定状态)。NFS4ERR\u STALE\u STATEID错误表示STATEID因重新启动或重新启动而无效。NFS4ERR_STALE_CLIENTID错误表示

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.

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 issue is included in [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请求的NFS4ERR_GRACE错误。在这种情况下,客户端应该对请求采用重试机制。重试之间应使用延迟(大约几秒钟),以避免服务器无法正常工作。关于一般性问题的进一步讨论载于[Floyd]。客户机必须说明能够在宽限期内执行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请求的情况下,服务器宽限期之外的回收类型锁定请求才能成功。

A server may, upon restart, establish a new value for the lease period. Therefore, clients should, once a new clientid is established, refetch the lease_time attribute and use it as the basis for lease renewal for the lease associated with that server. However, the server must establish, for this restart event, a grace period at least as long as the lease period for the previous server instantiation. This allows the client state obtained during the previous server instance to be reliably re-established.

服务器可以在重新启动时为租赁期建立新值。因此,一旦建立了新的clientid,客户端应重新蚀刻lease_time属性,并将其用作与该服务器关联的租约的租约续订基础。但是,对于此重新启动事件,服务器必须建立一个宽限期,该宽限期至少与上一个服务器实例化的租用期一样长。这允许可靠地重新建立在上一个服务器实例期间获得的客户端状态。

8.6.3. Network Partitions and Recovery
8.6.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请求,则服务器必须释放门控锁并批准新请求。

When a network partition is combined with a server reboot, there are edge conditions that place requirements on the server in order to avoid silent data corruption following the server reboot. Two of these edge conditions are known, and are discussed below.

当网络分区与服务器重新启动相结合时,存在一些边缘条件,这些条件会对服务器提出要求,以避免服务器重新启动后出现无提示数据损坏。已知其中两个边缘条件,将在下面讨论。

The first edge condition has the following scenario:

第一条边条件具有以下情况:

1. Client A acquires a lock.

1. 客户端A获得一个锁。

2. Client A and server experience mutual network partition, such that client A is unable to renew its lease.

2. 客户端A和服务器经历了相互的网络分区,因此客户端A无法续订其租约。

3. Client A's lease expires, so server releases lock.

3. 客户端A的租约到期,所以服务器释放锁。

4. Client B acquires a lock that would have conflicted with that of Client A.

4. 客户端B获取的锁可能与客户端a的锁冲突。

5. Client B releases the lock

5. 客户端B释放锁

6. Server reboots

6. 服务器重新启动

7. Network partition between client A and server heals.

7. 客户端A和服务器之间的网络分区修复。

8. Client A issues a RENEW operation, and gets back a NFS4ERR_STALE_CLIENTID.

8. 客户端A发出续订操作,并返回NFS4ERR_STALE_CLIENTID。

9. Client A reclaims its lock within the server's grace period.

9. 客户端A在服务器的宽限期内收回其锁。

Thus, at the final step, the server has erroneously granted client A's lock reclaim. If client B modified the object the lock was protecting, client A will experience object corruption.

因此,在最后一步,服务器错误地授予客户端A的锁回收。如果客户端B修改了锁所保护的对象,客户端A将经历对象损坏。

The second known edge condition follows:

第二个已知边条件如下所示:

1. Client A acquires a lock.

1. 客户端A获得一个锁。

2. Server reboots.

2. 服务器重新启动。

3. Client A and server experience mutual network partition, such that client A is unable to reclaim its lock within the grace period.

3. 客户端A和服务器经历相互的网络分区,因此客户端A无法在宽限期内收回其锁。

4. Server's reclaim grace period ends. Client A has no locks recorded on server.

4. 服务器的回收宽限期结束。客户端A在服务器上没有记录锁。

5. Client B acquires a lock that would have conflicted with that of Client A.

5. 客户端B获取的锁可能与客户端a的锁冲突。

6. Client B releases the lock.

6. 客户端B释放锁。

7. Server reboots a second time.

7. 服务器再次重新启动。

8. Network partition between client A and server heals.

8. 客户端A和服务器之间的网络分区修复。

9. Client A issues a RENEW operation, and gets back a NFS4ERR_STALE_CLIENTID.

9. 客户端A发出续订操作,并返回NFS4ERR_STALE_CLIENTID。

10. Client A reclaims its lock within the server's grace period.

10. 客户端A在服务器的宽限期内收回其锁。

As with the first edge condition, the final step of the scenario of the second edge condition has the server erroneously granting client A's lock reclaim.

与第一个边缘条件一样,第二个边缘条件场景的最后一步是服务器错误地授予客户端A的锁回收。

Solving the first and second edge conditions requires that the server either assume after it reboots that edge condition occurs, and thus return NFS4ERR_NO_GRACE for all reclaim attempts, or that the server record some information stable storage. The amount of information the server records in stable storage is in inverse proportion to how harsh the server wants to be whenever the edge conditions occur. The server that is completely tolerant of all edge conditions will record in stable storage every lock that is acquired, removing the lock record from stable storage only when the lock is unlocked by the client and the lock's lockowner advances the sequence number such that the lock release is not the last stateful event for the lockowner's sequence. For the two aforementioned edge conditions, the harshest a server can be, and still support a grace period for reclaims, requires that the server record in stable storage information some minimal information. For example, a server implementation could, for each client, save in stable storage a record containing:

解决第一个和第二个边缘条件要求服务器在重新启动后假设边缘条件发生,从而为所有回收尝试返回NFS4ERR_NO_GRACE,或者服务器记录一些信息。服务器在稳定存储中记录的信息量与每当出现边缘条件时服务器希望达到的苛刻程度成反比。完全容忍所有边缘条件的服务器将在稳定存储器中记录获取的每个锁,只有当客户机解锁了锁并且锁的锁所有者提前了序列号,使得锁释放不是锁所有者序列的最后一个有状态事件时,才从稳定存储中删除锁记录。对于前面提到的两种边缘条件,服务器可能是最苛刻的,并且仍然支持回收的宽限期,要求服务器在稳定的存储信息中记录一些最小的信息。例如,服务器实现可以为每个客户机在稳定存储中保存一条记录,其中包含:

o the client's id string

o 客户端的id字符串

o a boolean that indicates if the client's lease expired or if there was administrative intervention (see the section, Server Revocation of Locks) to revoke a record lock, share reservation, or delegation

o 一个布尔值,指示客户端的租约是否过期,或者是否有管理干预(请参阅“服务器撤销锁定”一节)来撤销记录锁定、共享保留或委派

o a timestamp that is updated the first time after a server boot or reboot the client acquires record locking, share reservation, or delegation state on the server. The timestamp need not be updated on subsequent lock requests until the server reboots.

o 服务器启动或重新启动后,客户端在服务器上获取记录锁定、共享保留或委派状态时第一次更新的时间戳。在服务器重新启动之前,不需要在后续锁定请求中更新时间戳。

The server implementation would also record in the stable storage the timestamps from the two most recent server reboots.

服务器实现还将在稳定存储中记录最近两次服务器重新启动的时间戳。

Assuming the above record keeping, for the first edge condition, after the server reboots, the record that client A's lease expired means that another client could have acquired a conflicting record lock, share reservation, or delegation. Hence the server must reject a reclaim from client A with the error NFS4ERR_NO_GRACE.

假设上述记录保留,对于第一个边缘条件,在服务器重新启动后,客户机A的租约过期的记录意味着另一个客户机可能获得了冲突的记录锁、共享保留或委派。因此,服务器必须拒绝来自客户端a的回收,错误为NFS4ERR\u NO\u。

For the second edge condition, after the server reboots for a second time, the record that the client had an unexpired record lock, share reservation, or delegation established before the server's previous incarnation means that the server must reject a reclaim from client A with the error NFS4ERR_NO_GRACE.

对于第二个边缘条件,在服务器第二次重新启动后,在服务器上一次运行之前,客户端已建立未过期的记录锁定、共享保留或委派,这意味着服务器必须拒绝客户端a的回收,错误为NFS4ERR_NO_GRACE。

Regardless of the level and approach to record keeping, the server MUST implement one of the following strategies (which apply to reclaims of share reservations, record locks, and delegations):

无论记录保存的级别和方法如何,服务器都必须实施以下策略之一(适用于回收共享保留、记录锁定和委派):

1. Reject all reclaims with NFS4ERR_NO_GRACE. This is superharsh, but necessary if the server does not want to record lock state in stable storage.

1. 使用NFS4ERR_NO_GRACE拒绝所有回收。这是非常愚蠢的,但如果服务器不想在稳定的存储中记录锁定状态,则必须这样做。

2. Record sufficient state in stable storage such that all known edge conditions involving server reboot, including the two noted in this section, are detected. False positives are acceptable. Note that at this time, it is not known if there are other edge conditions.

2. 在稳定存储中记录足够的状态,以便检测到所有涉及服务器重新启动的已知边缘条件,包括本节中提到的两种情况。假阳性是可以接受的。请注意,此时不知道是否存在其他边缘条件。

In the event, after a server reboot, the server determines that there is unrecoverable damage or corruption to the the stable storage, then for all clients and/or locks affected, the server MUST return NFS4ERR_NO_GRACE.

在这种情况下,在服务器重新启动后,服务器确定稳定存储存在无法恢复的损坏或损坏,然后对于所有受影响的客户端和/或锁,服务器必须返回NFS4ERR_NO_GRACE。

A mandate for the client's handling of the NFS4ERR_NO_GRACE error is outside the scope of this specification, since the strategies for such handling are very dependent on the client's operating environment. However, one potential approach is described below.

客户处理NFS4ERR_NO_GRACE错误的授权不在本规范的范围内,因为此类处理的策略非常依赖于客户的操作环境。然而,下文描述了一种可能的方法。

When the client receives NFS4ERR_NO_GRACE, it could examine the change attribute of the objects the client is trying to reclaim state for, and use that to determine whether to re-establish the state via normal OPEN or LOCK requests. This is acceptable provided the client's operating environment allows it. In otherwords, the client implementor is advised to document for his users the behavior. The client could also inform the application that its record lock or share reservations (whether they were delegated or not) have been lost, such as via a UNIX signal, a GUI pop-up window, etc. See the section, "Data Caching and Revocation" for a discussion of what the client should do for dealing with unreclaimed delegations on client state.

当客户端接收到NFS4ERR_NO_GRACE时,它可以检查客户端尝试为其回收状态的对象的更改属性,并使用该属性确定是否通过正常打开或锁定请求重新建立状态。只要客户的操作环境允许,这是可以接受的。换句话说,建议客户机实现者为其用户记录行为。客户机还可以通知应用程序其记录锁或共享保留(无论是否已委派)已丢失,例如通过UNIX信号、GUI弹出窗口等。有关如何处理客户机状态下未委派的委派的讨论,请参阅“数据缓存和吊销”一节。

For further discussion of revocation of locks see the section "Server Revocation of Locks".

有关撤销锁的进一步讨论,请参阅“服务器撤销锁”一节。

8.7. Recovery from a Lock Request Timeout or Abort
8.7. 从锁定请求超时或中止中恢复

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 lock_owner. This is straightforward to do without a special re-synchronize operation.

如果锁定请求超时,客户端可能会决定不重试该请求。当为其发出请求的进程终止时(例如,在UNIX中,由于信号),客户端也可能中止请求。但也有可能是服务器收到了请求并对其采取了行动。这将在客户端不知道更改的情况下更改服务器上的状态。最重要的是,客户机在尝试任何其他使用相同锁所有者的seqid和/或stateid的操作之前,必须与服务器重新同步状态。这很简单,无需特殊的重新同步操作。

Since the server maintains the last lock request and response received on the lock_owner, for each lock_owner, 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 lock_owner, 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 server will return the cached result or if never saw the request, perform it. 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 lock_owner will re-synchronize and in turn the lock state will re-synchronize.

由于服务器维护在锁所有者上接收的最后一个锁请求和响应,因此对于每个锁所有者,客户端应该缓存它发送的最后一个锁请求,以便锁请求不会收到响应。因此,下次客户端为锁所有者执行锁操作时,它可以发送缓存请求(如果有),如果请求是建立状态的请求(例如,锁或打开操作),服务器将返回缓存结果,或者如果从未看到请求,则执行该请求。客户端可以通过请求来删除状态(例如,锁定或关闭操作)。使用这种方法,客户机和服务器上给定锁所有者的序列和stateid信息将重新同步,而锁状态将重新同步。

8.8. Server Revocation of Locks
8.8. 服务器撤销锁

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 before expiration. 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_ADMIN_REVOKED. In this instance the client may assume that only the lock_owner'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_ADMIN_reversed错误。在这种情况下,客户端可能认为只有锁所有者的锁丢失了。客户端会适当地通知锁持有者。客户可能不会认为由于操作失败而延长了租赁期。

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.

当客户确定租赁期可能已到期时,客户必须将为相关租赁持有的所有锁标记为“未验证”。这意味着客户端无法与服务器重新建立或确认适当的锁定状态。如前一节关于崩溃恢复的描述,在某些情况下,服务器可能会在客户端的租约期到期后授予冲突锁。当租赁期可能已过期时,客户端必须验证当前持有的每个锁,以确保未授予冲突的锁。客户机可以通过发出I/O请求来完成此任务,I/O请求可以是挂起的I/O请求,也可以是零长度读取请求,并指定与所讨论的锁关联的stateid。如果对请求的响应是成功的,则客户端已经验证了由该stateid管理的所有锁,并在其自身和服务器之间重新建立了适当的状态。

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请求未成功,则服务器将撤销与stateid关联的一个或多个锁,客户端必须通知所有者。

8.9. Share Reservations
8.9. 共享预订

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 == 0) return (NFS4ERR_INVAL)

if(request.access==0)返回(NFS4ERR_INVAL)

else if ((request.access & file_state.deny)) || (request.deny & file_state.access)) return (NFS4ERR_DENIED)

else if((request.access&file_state.deny))| |(request.deny&file_state.access))返回(NFS4ERR_DENIED)

This checking of share reservations on OPEN is done with no exception for an existing OPEN for the same open_owner.

对于同一OPEN_所有者的现有OPEN,OPEN上的共享预订检查毫无例外。

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.10. OPEN/CLOSE Operations
8.10. 打开/关闭操作

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 reservations held by the lock_owner 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, NFS4ERR_LOCKS_HELD, if any locks would exist after the CLOSE.

关闭操作将删除锁所有者对该文件持有的所有共享保留。如果记录锁被持有,客户端应在发出关闭之前释放所有锁。服务器可能会在关闭时释放所有未完成的锁,但某些服务器可能不支持关闭仍保留记录锁的文件。如果关闭后存在任何锁,服务器必须返回failure,NFS4ERR_LOCKS_hold。

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

查找操作将返回文件句柄,而不会在服务器上建立任何锁定状态。如果没有有效的stateid,服务器将假定客户端具有最少的访问权限。例如,一个文件

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).

无法使用通过查找获得的文件句柄访问以deny READ/WRITE打开的文件,因为它没有有效的stateid(即,使用所有位0或所有位1的stateid)。

8.10.1. Close and Retention of State Information
8.10.1. 关闭和保留状态信息

Since a CLOSE operation requests deallocation of a stateid, dealing with retransmission of the CLOSE, may pose special difficulties, since the state information, which normally would be used to determine the state of the open file being designated, might be deallocated, resulting in an NFS4ERR_BAD_STATEID error.

由于关闭操作请求释放stateid,处理关闭的重新传输可能会带来特殊困难,因为通常用于确定指定的打开文件的状态的状态信息可能会被释放,从而导致NFS4ERR_BAD_stateid错误。

Servers may deal with this problem in a number of ways. To provide the greatest degree assurance that the protocol is being used properly, a server should, rather than deallocate the stateid, mark it as close-pending, and retain the stateid with this status, until later deallocation. In this way, a retransmitted CLOSE can be recognized since the stateid points to state information with this distinctive status, so that it can be handled without error.

服务器可以通过多种方式处理此问题。为了最大程度地保证协议的正确使用,服务器应该将stateid标记为close pending,而不是解除分配,并将stateid保留为此状态,直到以后解除分配。通过这种方式,可以识别重新传输的关闭,因为stateid指向具有此独特状态的状态信息,因此可以无误地处理它。

When adopting this strategy, a server should retain the state information until the earliest of:

采用此策略时,服务器应保留状态信息,直到以下时间最早:

o Another validly sequenced request for the same lockowner, that is not a retransmission.

o 对同一锁所有者的另一个有效排序的请求,这不是重传。

o The time that a lockowner is freed by the server due to period with no activity.

o 由于没有活动的时间段,服务器释放锁所有者的时间。

o All locks for the client are freed as a result of a SETCLIENTID.

o 由于SETCLIENTID,客户端的所有锁都被释放。

Servers may avoid this complexity, at the cost of less complete protocol error checking, by simply responding NFS4_OK in the event of a CLOSE for a deallocated stateid, on the assumption that this case must be caused by a retransmitted close. When adopting this approach, it is desirable to at least log an error when returning a no-error indication in this situation. If the server maintains a reply-cache mechanism, it can verify the CLOSE is indeed a retransmission and avoid error logging in most cases.

服务器可以避免这种复杂性,但代价是协议错误检查不太完整,只要在释放的stateid关闭时响应NFS4_OK即可,前提是这种情况必须由重新传输的关闭引起。当采用这种方法时,希望在这种情况下返回无错误指示时至少记录错误。如果服务器维护应答缓存机制,它可以验证关闭是否确实是一次重新传输,并在大多数情况下避免错误日志记录。

8.11. Open Upgrade and Downgrade
8.11. 开放式升级和降级

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 OPENs. 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 OPENs result in the OPENed object being designated by the same filehandle.

已完成的所有打开请求的拒绝位。只有一次关闭才能重置两次打开的效果。请注意,客户端在发出OPEN命令时,可能不知道实际上正在打开同一个文件。仅当两次打开都导致打开的对象由同一个filehandle指定时,上述内容才适用。

When the server chooses to export multiple filehandles corresponding to the same file object and returns different filehandles on two different OPENs 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 OPENs with separate stateids and will require separate CLOSEs to free them.

当服务器选择导出对应于同一文件对象的多个文件句柄,并在同一文件对象的两个不同打开上返回不同的文件句柄时,服务器不得将访问和拒绝位“或”组合在一起,并合并两个打开的文件。相反,服务器必须使用单独的stateID维护单独的打开,并且需要单独的关闭来释放它们。

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 opens 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.12. Short and Long Leases
8.12. 短期和长期租赁

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 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 (the server must wait for the leases to expire and the grace period to elapse 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 would not be an issue.

如果服务器能够在非易失性内存中存储租约状态,则长租约是可用的。恢复后,服务器可以从其非易失性内存重建租约状态,并继续与其客户端一起操作,因此长租约不会成为问题。

8.13. Clocks, Propagation Delay, and Calculating Lease Expiration
8.13. 时钟、传播延迟和计算租约到期

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毫秒向服务器发送锁续订或写回数据。

The server's lease period configuration should take into account the network distance of the clients that will be accessing the server's resources. It is expected that the lease period will take into account the network propagation delays and other network delay factors for the client population. Since the protocol does not allow for an automatic method to determine an appropriate lease period, the server's administrator may have to tune the lease period.

服务器的租用期配置应考虑将要访问服务器资源的客户端的网络距离。预计租赁期将考虑网络传播延迟和客户群的其他网络延迟因素。由于协议不允许使用自动方法来确定适当的租赁期,服务器管理员可能必须调整租赁期。

8.14. Migration, Replication and State
8.14. 迁移、复制和状态

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, stateids, and clientids) 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)如下所述。迁移和复制的处理方式不同。有关文件服务器状态和恢复的相关讨论,请参阅“文件锁定和共享保留”下的部分。

If server replica or a server immigrating a filesystem agrees to, or is expected to, accept opaque values from the client that originated from another server, then it is a wise implementation practice for the servers to encode the "opaque" values in network byte order. This way, servers acting as replicas or immigrating filesystems will be able to parse values like stateids, directory cookies, filehandles, etc. even if their native byte order is different from other servers cooperating in the replication and migration of the filesystem.

如果服务器副本或迁移文件系统的服务器同意或预期接受来自另一台服务器的客户端的不透明值,那么服务器以网络字节顺序编码“不透明”值是明智的实现实践。这样,充当副本或迁移文件系统的服务器将能够解析stateID、目录cookie、文件句柄等值,即使它们的本机字节顺序不同于在文件系统的复制和迁移中协作的其他服务器。

8.14.1. Migration and State
8.14.1. 移民与国家

In the case of migration, the servers involved in the migration of a filesystem 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

在迁移的情况下,文件系统迁移所涉及的服务器应将所有服务器状态从原始服务器转移到新服务器。这必须以对客户端透明的方式完成。此状态转移将简化客户端在以下情况下的转换:

filesystem migration occurs. If the servers are successful in transferring all state, the client will continue to use stateids assigned by the original server. Therefore the new server must recognize these stateids as valid. This holds true for the clientid as well. Since responsibility for an entire filesystem 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。因此,新服务器必须将这些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 old 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.14.2. Replication and State
8.14.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, stateids and clientids 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.14.3. Notification of Migrated Lease
8.14.3. 迁移租约的通知

In the case of lease renewal, the client may not be submitting requests for a filesystem that has been migrated to another server. This can occur because of the implicit lease renewal mechanism. The client renews leases for all filesystems when submitting a request to any one filesystem 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 filesystem 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 an operation on each filesystem 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, the client will receive either NFS4ERR_STALE_CLIENTID or NFS4ERR_STALE_STATEID from the new server, as described above, and the client 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,如上所述,然后客户端可以恢复状态信息,就像服务器发生故障时一样。

8.14.4. Migration and the Lease_time Attribute
8.14.4. 迁移和租赁时间属性

In order that the client may appropriately manage its leases in the case of migration, the destination server must establish proper values for the lease_time attribute.

为了在迁移的情况下客户端可以适当地管理其租约,目标服务器必须为租约时间属性建立适当的值。

When state is transferred transparently, that state should include the correct value of the lease_time attribute. The lease_time attribute on the destination server must never be less than that on the source since this would result in premature expiration of leases granted by the source server. Upon migration in which state is transferred transparently, the client is under no obligation to re-fetch the lease_time attribute and may continue to use the value previously fetched (on the source server).

当状态以透明方式传输时,该状态应包含lease_time属性的正确值。目标服务器上的租约时间属性不得小于源服务器上的租约时间属性,因为这将导致源服务器授予的租约提前到期。在以透明方式传输状态的迁移时,客户端没有义务重新获取lease_time属性,并且可以继续使用以前获取的值(在源服务器上)。

If state has not been transferred transparently (i.e., the client sees a real or simulated server reboot), the client should fetch the value of lease_time on the new (i.e., destination) server, and use it

如果状态未被透明地传输(即,客户端看到真实或模拟的服务器重新启动),则客户端应获取新(即,目标)服务器上的租约时间值,并使用它

for subsequent locking requests. However the server must respect a grace period at least as long as the lease_time on the source server, in order to ensure that clients have ample time to reclaim their locks before potentially conflicting non-reclaimed locks are granted. The means by which the new server obtains the value of lease_time on the old server is left to the server implementations. It is not specified by the NFS version 4 protocol.

用于后续锁定请求。但是,服务器必须遵守至少与源服务器上的租约时间一样长的宽限期,以确保在授予潜在冲突的未回收锁之前,客户端有足够的时间回收其锁。新服务器获取旧服务器上的租赁时间值的方法留给服务器实现。它不是由NFS版本4协议指定的。

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

委托从服务器传递到客户端,指定委托对象和委托类型。有不同类型的委托,但每种类型都包含一个stateid,用于在执行依赖于委托的操作时表示委托。此stateid类似于与锁和共享保留关联的stateid,但不同之处在于委托的stateid与clientid关联,并且可能是

used on behalf of all the open_owners 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.

代表给定客户端的所有OpenU所有者使用。委托是作为一个整体委托给客户机的,而不是委托给客户机中的任何特定进程或控制线程。

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:开放”部分)。

A server MAY support a claim type of CLAIM_DELEGATE_PREV, but if it does, it MUST NOT remove delegations upon SETCLIENTID_CONFIRM, and instead MUST, for a period of time no less than that of the value of the lease_time attribute, maintain the client's delegations to allow time for the client to issue CLAIM_DELEGATE_PREV requests. The server that supports CLAIM_DELEGATE_PREV MUST support the DELEGPURGE operation.

服务器可能支持claim_DELEGATE_PREV的声明类型,但如果支持,则在SETCLIENTID_CONFIRM时不得删除委托,而是必须在不小于lease_time属性值的时间段内维护客户端的委托,以便客户端有时间发出claim_DELEGATE_PREV请求。支持CLAIM_DELEGATE_PREV的服务器必须支持DELEGPURGE操作。

When the server reboots or restarts, delegations are reclaimed (using the OPEN operation with CLAIM_PREVIOUS) 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_PREVIOUS的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. Revalidating means that the client fetches the change attribute from the server, compares it with the cached change attribute, and if different, declares the cached data (as well as the cached attributes) as invalid. 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 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.

o 首先,客户端上存在的缓存数据必须在执行打开后重新验证。重新验证意味着客户端从服务器获取更改属性,将其与缓存的更改属性进行比较,如果不同,则将缓存数据(以及缓存的属性)声明为无效。这是为了确保已打开文件的数据仍然正确地反映在客户端缓存中。至少当客户端的打开操作包含DENY=WRITE或两者同时包含时,必须进行此验证,从而终止其他客户端可能有机会使用写访问权限打开文件的时间段。客户端可能会选择更频繁地执行重新验证(即,在指定DENY=NONE的打开时),以并行NFS版本3协议的实践,从而使用户能够假定这种程度的缓存重新验证。

Since the change attribute is updated for data and metadata modifications, some client implementors may be tempted to use the time_modify attribute and not change to validate cached data, so that metadata changes do not spuriously invalidate clean data. The implementor is cautioned in this approach. The change attribute is guaranteed to change for each update to the file,

由于更改属性是为数据和元数据修改而更新的,因此一些客户机实现人员可能会尝试使用time_modify属性而不是change来验证缓存的数据,以便元数据更改不会错误地使干净的数据无效。在这种方法中,实现者会受到警告。对于文件的每次更新,“更改”属性都保证更改,

whereas time_modify is guaranteed to change only at the granularity of the time_delta attribute. Use by the client's data cache validation logic of time_modify and not change runs the risk of the client incorrectly marking stale data as valid.

而time_modify保证仅在time_delta属性的粒度上更改。客户机的数据缓存使用time_modify和not change的验证逻辑可能会导致客户机错误地将过时数据标记为有效数据。

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 filesystem. 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 cached 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 prerequisite 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 when the client gets back NFS4ERR_LOCKED from a READ or WRITE on a file it has an appropriate share reservation for. 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.

客户端数据缓存在生效时需要遵守强制文件锁定。当客户端从其具有适当共享保留的文件的读或写操作中恢复NFS4ERR_LOCKED时,将指示给定文件是否存在强制文件锁定。当强制锁定对文件生效时,客户端必须为正在读取或写入的数据检查适当的文件锁定。如果正在读取或写入的范围存在锁,则客户端可以使用客户端的已验证缓存满足请求。如果没有为读或写的范围保留适当的文件锁,则客户端缓存不能满足读或写请求,并且必须将请求发送到服务器进行处理。当读或写请求与锁定区域部分重叠时,应将请求细分为多个部分,并适当处理每个区域(锁定或未锁定)。

9.3.4. Data Caching and File Identity
9.3.4. 数据缓存和文件标识

When clients cache data, the file data needs to be organized according to the filesystem 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 filesystem 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 filesystem 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 returns different values of the fsid attribute, then the filehandles represent distinct objects.

o 如果指向两个filehandles的GETATTR返回不同的fsid属性值,则filehandles表示不同的对象。

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 both of the handles, then 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: 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 delegation stateid is separate and distinct from the stateid for the OPEN proper. The standard stateid, unlike the delegation stateid, is associated with a particular lock_owner and will continue to be valid after the delegation is recalled and the file remains open.

委托stateid是独立的,并且与开放数据库的stateid不同。与委托stateid不同,标准stateid与特定的锁所有者关联,并且在调用委托并且文件保持打开状态后将继续有效。

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 file close system call 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 filesystem 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 filesystem space and any applicable quotas. The server can recall delegations as a result of managing the available filesystem 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 filesystem 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 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 may be 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.

当客户端持有写开放委托时,可以在本地执行锁定操作。这包括强制文件锁定所需的文件。这是可以做到的,因为委托意味着不可能有冲突的锁。类似地,通常与获取锁相关的所有重新验证以及与释放锁相关的数据刷新都不需要完成。

When a client holds a read open delegation, lock operations are not performed locally. All lock operations, including those requesting non-exclusive locks, are sent to the server for resolution.

当客户端持有读打开委托时,不会在本地执行锁定操作。所有锁操作(包括请求非独占锁的操作)都将发送到服务器进行解析。

9.4.3. Handling of CB_GETATTR
9.4.3. CB_GETATTR的处理

The server needs to employ special handling for a GETATTR where the target is a file that has a write open delegation in effect. The reason for this is that the client holding the write delegation may have modified the data and the server needs to reflect this change to the second client that submitted the GETATTR. Therefore, the client holding the write delegation needs to be interrogated. The server will use the CB_GETATTR operation. The only attributes that the server can reliably query via CB_GETATTR are size and change.

服务器需要对GETATTR进行特殊处理,其中目标是具有有效的写开放委派的文件。原因是持有写委派的客户端可能修改了数据,服务器需要将此更改反映到提交GETATTR的第二个客户端。因此,需要询问持有写委托的客户机。服务器将使用CB_GETATTR操作。服务器可以通过CB_GETATTR可靠查询的唯一属性是大小和更改。

Since CB_GETATTR is being used to satisfy another client's GETATTR request, the server only needs to know if the client holding the delegation has a modified version of the file. If the client's copy of the delegated file is not modified (data or size), the server can satisfy the second client's GETATTR request from the attributes stored locally at the server. If the file is modified, the server only needs to know about this modified state. If the server determines that the file is currently modified, it will respond to the second client's GETATTR as if the file had been modified locally at the server.

由于CB_GETATTR用于满足另一个客户机的GETATTR请求,因此服务器只需要知道持有委托的客户机是否具有文件的修改版本。如果委托文件的客户端副本未被修改(数据或大小),则服务器可以从服务器本地存储的属性满足第二个客户端的GETATTR请求。如果文件被修改,服务器只需要知道此修改状态。如果服务器确定该文件当前已修改,它将响应第二个客户端的GETATTR,就像该文件已在服务器本地修改一样。

Since the form of the change attribute is determined by the server and is opaque to the client, the client and server need to agree on a method of communicating the modified state of the file. For the size attribute, the client will report its current view of the file size.

由于更改属性的形式由服务器决定,并且对客户机来说是不透明的,因此客户机和服务器需要就传递文件修改状态的方法达成一致。对于“大小”属性,客户端将报告其文件大小的当前视图。

For the change attribute, the handling is more involved.

对于change属性,处理更为复杂。

For the client, the following steps will be taken when receiving a write delegation:

对于客户端,在接收写委派时将采取以下步骤:

o The value of the change attribute will be obtained from the server and cached. Let this value be represented by c.

o 更改属性的值将从服务器获取并缓存。让这个值用c表示。

o The client will create a value greater than c that will be used for communicating modified data is held at the client. Let this value be represented by d.

o 客户端将创建一个大于c的值,用于通信客户端保存的修改数据。让这个值用d表示。

o When the client is queried via CB_GETATTR for the change attribute, it checks to see if it holds modified data. If the file is modified, the value d is returned for the change attribute value. If this file is not currently modified, the client returns the value c for the change attribute.

o 当通过CB_GETATTR查询客户机的change属性时,它会检查客户机是否保存修改后的数据。如果文件被修改,则会为更改属性值返回值d。如果当前未修改此文件,则客户端将返回change属性的值c。

For simplicity of implementation, the client MAY for each CB_GETATTR return the same value d. This is true even if, between successive CB_GETATTR operations, the client again modifies in the file's data or metadata in its cache. The client can return the same value because the only requirement is that the client be able to indicate to the server that the client holds modified data. Therefore, the value of d may always be c + 1.

为简化实现,客户机可能会为每个CB_GETATTR返回相同的值d。即使在连续的CB_GETATTR操作之间,客户端再次修改其缓存中文件的数据或元数据,这也是正确的。客户机可以返回相同的值,因为唯一的要求是客户机能够向服务器指示客户机持有修改后的数据。因此,d的值可能总是c+1。

While the change attribute is opaque to the client in the sense that it has no idea what units of time, if any, the server is counting change with, it is not opaque in that the client has to treat it as an unsigned integer, and the server has to be able to see the results of the client's changes to that integer. Therefore, the server MUST encode the change attribute in network order when sending it to the client. The client MUST decode it from network order to its native order when receiving it and the client MUST encode it network order when sending it to the server. For this reason, change is defined as an unsigned integer rather than an opaque array of octets.

虽然change属性对客户端来说是不透明的,因为它不知道服务器使用什么时间单位(如果有的话)计算更改,但它不是不透明的,因为客户端必须将其视为无符号整数,服务器必须能够看到客户端对该整数所做更改的结果。因此,服务器在将更改属性发送到客户端时,必须按照网络顺序对其进行编码。客户端在接收时必须将其从网络顺序解码为本机顺序,并且在将其发送到服务器时必须对其进行网络顺序编码。因此,change被定义为无符号整数,而不是不透明的八位字节数组。

For the server, the following steps will be taken when providing a write delegation:

对于服务器,在提供写委派时将采取以下步骤:

o Upon providing a write delegation, the server will cache a copy of the change attribute in the data structure it uses to record the delegation. Let this value be represented by sc.

o 提供写委派后,服务器将在用于记录委派的数据结构中缓存change属性的副本。让这个值用sc表示。

o When a second client sends a GETATTR operation on the same file to the server, the server obtains the change attribute from the first client. Let this value be cc.

o 当第二个客户机向服务器发送同一文件上的GETATTR操作时,服务器从第一个客户机获取change属性。将此值设为cc。

o If the value cc is equal to sc, the file is not modified and the server returns the current values for change, time_metadata, and time_modify (for example) to the second client.

o 如果值cc等于sc,则不会修改文件,服务器会将更改、时间\元数据和时间\修改(例如)的当前值返回给第二个客户端。

o If the value cc is NOT equal to sc, the file is currently modified at the first client and most likely will be modified at the server at a future time. The server then uses its current time to construct attribute values for time_metadata and time_modify. A new value of sc, which we will call nsc, is computed by the server, such that nsc >= sc + 1. The server then returns the constructed time_metadata, time_modify, and nsc values to the requester. The server replaces sc in the delegation record with nsc. To prevent the possibility of time_modify, time_metadata, and change from appearing to go backward (which would happen if the client holding the delegation fails to write its modified data to the server before the delegation is revoked or returned), the server SHOULD update the file's metadata record with the constructed attribute values. For reasons of reasonable performance, committing the constructed attribute values to stable storage is OPTIONAL.

o 如果值cc不等于sc,则文件当前在第一个客户端修改,并且很可能在将来在服务器上修改。然后,服务器使用其当前时间为time\u元数据和time\u modify构造属性值。服务器会计算一个新的sc值,我们称之为nsc,这样nsc>=sc+1。然后,服务器将构造的time_元数据、time_modify和nsc值返回给请求者。服务器用nsc替换委派记录中的sc。为了防止时间\修改、时间\元数据和更改出现倒退的可能性(如果持有委托的客户端在撤销或返回委托之前未能将其修改的数据写入服务器,则会发生这种情况),服务器应使用构造的属性值更新文件的元数据记录。出于合理性能的考虑,将构造的属性值提交到稳定存储是可选的。

As discussed earlier in this section, the client MAY return the same cc value on subsequent CB_GETATTR calls, even if the file was modified in the client's cache yet again between successive CB_GETATTR calls. Therefore, the server must assume that the file has been modified yet again, and MUST take care to ensure that the new nsc it constructs and returns is greater than the previous nsc it returned. An example implementation's delegation record would satisfy this mandate by including a boolean field (let us call it "modified") that is set to false when the delegation is granted, and an sc value set at the time of grant to the change attribute value. The modified field would be set to true the first time cc != sc, and would stay true until the delegation is returned or revoked. The processing for constructing nsc, time_modify, and time_metadata would use this pseudo code:

如本节前面所述,客户机可能会在后续CB_GETATTR调用中返回相同的cc值,即使在连续CB_GETATTR调用之间再次在客户机缓存中修改了文件。因此,服务器必须假设文件再次被修改,并且必须注意确保它构造和返回的新nsc大于它返回的前一个nsc。一个示例实现的委托记录将通过包含一个布尔字段(我们称之为“修改”)来满足这一要求,该布尔字段在授予委托时设置为false,以及在授予更改属性值时设置的sc值。修改后的字段将在第一次抄送时设置为true!=sc,并将保持为真,直到委托被返回或撤销。用于构造nsc、time\u modify和time\u元数据的处理将使用以下伪代码:

      if (!modified) {
          do CB_GETATTR for change and size;
        
      if (!modified) {
          do CB_GETATTR for change and size;
        
             if (cc != sc)
                 modified = TRUE;
         } else {
                 do CB_GETATTR for size;
         }
        
             if (cc != sc)
                 modified = TRUE;
         } else {
                 do CB_GETATTR for size;
         }
        
         if (modified) {
             sc = sc + 1;
          time_modify = time_metadata = current_time;
        
         if (modified) {
             sc = sc + 1;
          time_modify = time_metadata = current_time;
        
          update sc, time_modify, time_metadata into file's metadata;
      }
        
          update sc, time_modify, time_metadata into file's metadata;
      }
        

return to client (that sent GETATTR) the attributes it requested, but make sure size comes from what CB_GETATTR returned. Do not update the file's metadata with the client's modified size.

将请求的属性返回给客户端(发送GETATTR的客户端),但确保大小来自CB_GETATTR返回的属性。不要使用客户端修改的大小更新文件的元数据。

o In the case that the file attribute size is different than the server's current value, the server treats this as a modification regardless of the value of the change attribute retrieved via CB_GETATTR and responds to the second client as in the last step.

o 如果文件属性大小不同于服务器的当前值,则服务器将此视为修改,而不管通过CB_GETATTR检索的更改属性的值如何,并像上一步一样响应第二个客户端。

This methodology resolves issues of clock differences between client and server and other scenarios where the use of CB_GETATTR break down.

这种方法解决了客户机和服务器之间的时钟差异问题,以及使用CB_GETATTR出现故障的其他场景。

It should be noted that the server is under no obligation to use CB_GETATTR and therefore the server MAY simply recall the delegation to avoid its use.

应该注意的是,服务器没有义务使用CB_GETATTR,因此服务器可以简单地调用委托以避免使用它。

9.4.4. Recall of Open Delegation
9.4.4. 召回公开代表团

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 filesystem. If that filesystem 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.

除上述情况外,如果资源限制允许,服务器可以随时选择召回开放的委托。客户应随时做好召回的准备。

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 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. To precisely maintain the associated invariant, it is required to flush any modified data in any region for which a write lock was released while the write delegation was in effect. However, because the write open delegation implies no other locking by other clients, a simpler implementation 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.

在写开放委托的情况下,文件锁定带来了一些额外的要求。为了精确地维护关联的不变量,需要刷新任何区域中的任何修改数据,在写入委派生效时,为该区域释放了写入锁。但是,由于写开放委托不意味着其他客户端进行其他锁定,因此更简单的实现是,如果在写开放委托生效时释放了任何写锁定,则刷新文件的所有修改数据(如上所述)。

An implementation need not wait until delegation recall (or deciding to voluntarily return a delegation) to perform any of the above actions, if implementation considerations (e.g., resource availability constraints) make that desirable. Generally, however, the fact that the actual open state of the file may continue to change makes it not worthwhile to send information about opens and closes to the server, except as part of delegation return. Only in the case of closing the open that resulted in obtaining the delegation would clients be likely to do this early, since, in that case, the close once done will not be undone. Regardless of the client's choices on scheduling these actions, all must be performed before the delegation is returned, including (when applicable) the close that corresponds to the open that resulted in the delegation. These actions can be performed either in previous requests or in previous operations in the same COMPOUND request.

如果实现考虑(例如,资源可用性约束)使执行上述任何操作成为可取的,则实现无需等到委托召回(或决定自愿返回委托)后再执行。但是,通常情况下,文件的实际打开状态可能会继续更改,因此不值得向服务器发送有关打开和关闭的信息,除非作为委托返回的一部分。只有在关闭导致获得委托的未结项的情况下,客户才可能提前这样做,因为在这种情况下,一旦完成,关闭将不会撤消。无论客户选择如何安排这些操作,都必须在返回委派之前执行所有操作,包括(如果适用)与导致委派的打开对应的关闭。这些操作可以在以前的请求中执行,也可以在同一复合请求中的以前操作中执行。

9.4.5. Clients that Fail to Honor Delegation Recalls
9.4.5. 未能履行委托关系的客户召回

A client may fail to respond to a recall for various reasons, such as a failure of the callback path from server to the client. The client may be unaware of a failure in the callback path. This lack of awareness could result in the client finding out long after the failure that its delegation has been revoked, and another client has modified the data for which the client had a delegation. This is especially a problem for the client that held a write delegation.

客户端可能由于各种原因无法响应回调,例如从服务器到客户端的回调路径失败。客户端可能不知道回调路径中有故障。这种缺乏意识的情况可能会导致客户机在失败很久之后发现其委托已被撤销,而另一个客户机已修改了该客户机具有委托的数据。对于持有写委托的客户机来说,这尤其是一个问题。

The server also has a dilemma in that the client that fails to respond to the recall might also be sending other NFS requests, including those that renew the lease before the lease expires. Without returning an error for those lease renewing operations, the server leads the client to believe that the delegation it has is in force.

服务器还面临一个难题,即未能响应召回的客户端可能还发送其他NFS请求,包括那些在租约到期之前续订租约的请求。在不为这些租约续订操作返回错误的情况下,服务器会引导客户机相信它所拥有的委托已生效。

This difficulty is solved by the following rules:

此困难可通过以下规则解决:

o When the callback path is down, the server MUST NOT revoke the delegation if one of the following occurs:

o 当回调路径关闭时,如果发生以下情况之一,服务器不得撤消委派:

- The client has issued a RENEW operation and the server has returned an NFS4ERR_CB_PATH_DOWN error. The server MUST renew the lease for any record locks and share reservations the client has that the server has known about (as opposed to those locks and share reservations the client has established but not yet sent to the server, due to the delegation). The server SHOULD give the client a reasonable time to return its delegations to the server before revoking the client's delegations.

- 客户端已发出续订操作,服务器已返回NFS4ERR_CB_PATH_DOWN错误。服务器必须续订客户机已知的任何记录锁和共享保留的租约(与客户机已建立但由于委派尚未发送给服务器的锁和共享保留相反)。在撤销客户机的委托之前,服务器应该给客户机一段合理的时间将其委托返回给服务器。

- The client has not issued a RENEW operation for some period of time after the server attempted to recall the delegation. This period of time MUST NOT be less than the value of the lease_time attribute.

- 在服务器尝试调用委派后,客户端有一段时间未发出续订操作。此时间段不得小于lease_time属性的值。

o When the client holds a delegation, it can not rely on operations, except for RENEW, that take a stateid, to renew delegation leases across callback path failures. The client that wants to keep delegations in force across callback path failures must use RENEW to do so.

o 当客户机持有委派时,它不能依赖除RENEW(采用stateid)以外的操作跨回调路径故障续订委派租约。希望在回调路径失败时保持委托有效的客户端必须使用“续订”来执行此操作。

9.4.6. Delegation Revocation
9.4.6. 委托撤销

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. For any locks or share reservations that have been revoked, the corresponding owner 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 filesystem name space to ease recovery. Note that when the client can determine that the file has not been modified by any other client, or when the client has a complete cached copy of file in question, such a saved copy of the client's view of the file may be of particular value for recovery. In other case, recovery using a copy of the file based partially on the client's cached data and partially on the server copy as modified by other clients, will be anything but straightforward, so clients may avoid saving file contents in these situations or mark the results specially to warn users of possible problems.

如果客户端上有修改过的数据,则不能将其正常刷新到服务器。客户机可能会尝试在文件系统名称空间中以不同的名称提供在委派期间修改的文件数据副本,以便于恢复。请注意,当客户端可以确定文件未被任何其他客户端修改时,或者当客户端具有所讨论的文件的完整缓存副本时,这种保存的客户端文件视图副本对于恢复可能具有特定价值。在另一种情况下,使用部分基于客户端缓存数据的文件副本和部分基于由其他客户端修改的服务器副本进行恢复并不简单,因此客户端可能会避免在这些情况下保存文件内容,或者专门标记结果以警告用户可能出现的问题。

Saving of such modified data in delegation revocation situations may be limited to files of a certain size or might be used only when sufficient disk space is available within the target filesystem. Such saving may also be restricted to situations when the client has sufficient buffering resources to keep the cached copy available until it is properly stored to the target filesystem.

在委托撤销情况下保存此类修改后的数据可能仅限于特定大小的文件,或者可能仅在目标文件系统中有足够的可用磁盘空间时使用。这种保存也可能局限于客户端有足够的缓冲资源来保持缓存副本可用,直到它正确存储到目标文件系统。

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 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 filesystem 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 just both the change and time_access attributes and assuming that if the change attribute has the same value as it did when the attributes were cached, then no attributes other than time_access have changed. The reason why time_access is also fetched is because many servers operate in environments where the operation that updates change does not update time_access. For example, POSIX file semantics do not update access time when a file is modified by the write system call. Therefore, the client that wants a current time_access value should fetch it with change during the attribute cache validation processing and update its cached time_access.

客户端可以通过仅获取更改和时间访问属性,并假设如果更改属性具有与缓存属性时相同的值,则除了时间访问之外,没有其他属性发生更改,从而验证文件属性的缓存版本。同时获取时间访问的原因是,许多服务器在更新更改的操作不更新时间访问的环境中运行。例如,当写入系统调用修改文件时,POSIX文件语义不会更新访问时间。因此,需要当前时间访问值的客户端应在属性缓存验证处理期间获取该值,并更新其缓存的时间访问。

The client may maintain a cache of modified attributes for those attributes intimately connected with data of modified regular files (size, time_modify, and change). Other than those three attributes, the client MUST NOT maintain a cache of modified attributes. Instead, attribute changes are immediately sent to the server.

客户端可以为那些与修改的常规文件(大小、修改时间和更改)的数据密切相关的属性维护修改属性的缓存。除这三个属性外,客户端不得维护已修改属性的缓存。相反,属性更改会立即发送到服务器。

In some operating environments, the equivalent to time_access is expected to be implicitly updated by each read of the content of the file object. If an NFS client is caching the content of a file object, whether it is a regular file, directory, or symbolic link, the client SHOULD NOT update the time_access attribute (via SETATTR or a small READ or READDIR request) on the server with each read that is satisfied from cache. The reason is that this can defeat the performance benefits of caching content, especially since an explicit SETATTR of time_access may alter the change attribute on the server. If the change attribute changes, clients that are caching the content will think the content has changed, and will re-read unmodified data from the server. Nor is the client encouraged to maintain a modified version of time_access in its cache, since this would mean that the client will either eventually have to write the access time to the server with bad performance effects, or it would never update the server's time_access, thereby resulting in a situation where an application that caches access time between a close and open of the same file observes the access time oscillating between the past and present. The time_access attribute always means the time of last access to a file by a read that was satisfied by the server. This way clients will tend to see only time_access changes that go forward in time.

在某些操作环境中,每次读取文件对象的内容时,都会隐式地更新相当于time_访问的值。如果NFS客户端正在缓存文件对象的内容(无论是常规文件、目录还是符号链接),则客户端不应使用缓存满足的每次读取更新服务器上的time_access属性(通过SETATTR或小型读取或READDIR请求)。原因是,这可能会破坏缓存内容的性能优势,特别是因为时间访问的显式SETATTR可能会改变服务器上的change属性。如果更改属性更改,缓存内容的客户端将认为内容已更改,并将从服务器重新读取未修改的数据。也不鼓励客户机在其缓存中维护修改后的time_access版本,因为这意味着客户机最终将不得不将访问时间写入服务器,从而对性能造成不良影响,或者它将永远不会更新服务器的time_access,从而导致在相同文件的关闭和打开之间缓存访问时间的应用程序观察到访问时间在过去和现在之间振荡的情况。time_access属性始终表示服务器满足的读取上次访问文件的时间。这样,客户端将倾向于只看到随时间推移的时间访问更改。

9.7. Data and Metadata Caching and Memory Mapped Files
9.7. 数据和元数据缓存以及内存映射文件

Some operating environments include the capability for an application to map a file's content into the application's address space. Each time the application accesses a memory location that corresponds to a block that has not been loaded into the address space, a page fault occurs and the file is read (or if the block does not exist in the

一些操作环境包括应用程序将文件内容映射到应用程序地址空间的功能。每次应用程序访问与未加载到地址空间的块相对应的内存位置时,都会发生页面错误并读取文件(或者如果该块不存在于地址空间中)

file, the block is allocated and then instantiated in the application's address space).

文件中,块被分配,然后在应用程序的地址空间中实例化)。

As long as each memory mapped access to the file requires a page fault, the relevant attributes of the file that are used to detect access and modification (time_access, time_metadata, time_modify, and change) will be updated. However, in many operating environments, when page faults are not required these attributes will not be updated on reads or updates to the file via memory access (regardless whether the file is local file or is being access remotely). A client or server MAY fail to update attributes of a file that is being accessed via memory mapped I/O. This has several implications:

只要对文件的每个内存映射访问都需要一个页面错误,用于检测访问和修改的文件的相关属性(时间访问、时间元数据、时间修改和更改)就会更新。但是,在许多操作环境中,当不需要页面错误时,这些属性不会在读取或通过内存访问更新文件时更新(无论文件是本地文件还是远程访问)。客户机或服务器可能无法更新通过内存映射I/O访问的文件的属性。这有几个含义:

o If there is an application on the server that has memory mapped a file that a client is also accessing, the client may not be able to get a consistent value of the change attribute to determine whether its cache is stale or not. A server that knows that the file is memory mapped could always pessimistically return updated values for change so as to force the application to always get the most up to date data and metadata for the file. However, due to the negative performance implications of this, such behavior is OPTIONAL.

o 如果服务器上的应用程序内存映射了客户端也正在访问的文件,则客户端可能无法获取更改属性的一致值以确定其缓存是否过时。知道文件是内存映射的服务器可能总是悲观地返回更新的值以进行更改,从而强制应用程序始终获取文件的最新数据和元数据。但是,由于这会对性能产生负面影响,此类行为是可选的。

o If the memory mapped file is not being modified on the server, and instead is just being read by an application via the memory mapped interface, the client will not see an updated time_access attribute. However, in many operating environments, neither will any process running on the server. Thus NFS clients are at no disadvantage with respect to local processes.

o 如果服务器上没有修改内存映射文件,而只是由应用程序通过内存映射接口读取,则客户端将看不到更新的时间访问属性。但是,在许多操作环境中,服务器上运行的任何进程都不会。因此,NFS客户端在本地进程方面并不处于劣势。

o If there is another client that is memory mapping the file, and if that client is holding a write delegation, the same set of issues as discussed in the previous two bullet items apply. So, when a server does a CB_GETATTR to a file that the client has modified in its cache, the response from CB_GETATTR will not necessarily be accurate. As discussed earlier, the client's obligation is to report that the file has been modified since the delegation was granted, not whether it has been modified again between successive CB_GETATTR calls, and the server MUST assume that any file the client has modified in cache has been modified again between successive CB_GETATTR calls. Depending on the nature of the client's memory management system, this weak obligation may not be possible. A client MAY return stale information in CB_GETATTR whenever the file is memory mapped.

o 如果有另一个客户机正在映射该文件的内存,并且该客户机持有一个写委派,那么前面两个项目符号中讨论的问题集同样适用。因此,当服务器对客户端在其缓存中修改的文件执行CB_GETATTR时,CB_GETATTR的响应不一定准确。如前所述,客户机的义务是报告自授予委派以来文件已被修改,而不是在连续的CB_GETATTR调用之间是否再次修改,并且服务器必须假设客户机在缓存中修改的任何文件在连续的CB_GETATTR调用之间再次被修改。根据客户机内存管理系统的性质,这种弱义务可能是不可能的。每当文件被内存映射时,客户端可能会在CB_GETATTR中返回过时信息。

o The mixture of memory mapping and file locking on the same file is problematic. Consider the following scenario, where the page size on each client is 8192 bytes.

o 在同一个文件上混合使用内存映射和文件锁定是有问题的。考虑下面的场景,其中每个客户机上的页面大小是8192字节。

- Client A memory maps first page (8192 bytes) of file X

- 客户端A内存映射文件X的第一页(8192字节)

- Client B memory maps first page (8192 bytes) of file X

- 客户端B内存映射文件X的第一页(8192字节)

- Client A write locks first 4096 bytes

- 客户端A写锁定前4096个字节

- Client B write locks second 4096 bytes

- 客户端B写锁定第二个4096字节

- Client A, via a STORE instruction modifies part of its locked region.

- 客户端A通过存储指令修改其锁定区域的一部分。

- Simultaneous to client A, client B issues a STORE on part of its locked region.

- 与客户端A同时,客户端B在其锁定区域的一部分上发布存储。

Here the challenge is for each client to resynchronize to get a correct view of the first page. In many operating environments, the virtual memory management systems on each client only know a page is modified, not that a subset of the page corresponding to the respective lock regions has been modified. So it is not possible for each client to do the right thing, which is to only write to the server that portion of the page that is locked. For example, if client A simply writes out the page, and then client B writes out the page, client A's data is lost.

这里的挑战是让每个客户端重新同步以获得第一页的正确视图。在许多操作环境中,每个客户机上的虚拟内存管理系统只知道修改了一个页面,而不知道修改了对应于各个锁定区域的页面子集。因此,不可能每个客户机都做正确的事情,也就是只向服务器写入页面中被锁定的部分。例如,如果客户机A只是写出页面,然后客户机B写出页面,则客户机A的数据将丢失。

Moreover, if mandatory locking is enabled on the file, then we have a different problem. When clients A and B issue the STORE instructions, the resulting page faults require a record lock on the entire page. Each client then tries to extend their locked range to the entire page, which results in a deadlock.

此外,如果对文件启用了强制锁定,则会出现另一个问题。当客户端A和B发出存储指令时,产生的页面错误需要在整个页面上锁定记录。然后,每个客户机尝试将其锁定范围扩展到整个页面,从而导致死锁。

Communicating the NFS4ERR_DEADLOCK error to a STORE instruction is difficult at best.

将NFS4ERR_死锁错误传送到存储指令充其量是困难的。

If a client is locking the entire memory mapped file, there is no problem with advisory or mandatory record locking, at least until the client unlocks a region in the middle of the file.

如果客户端锁定整个内存映射文件,则至少在客户端解锁文件中间区域之前,咨询或强制记录锁定没有问题。

Given the above issues the following are permitted:

鉴于上述问题,允许以下情况:

- Clients and servers MAY deny memory mapping a file they know there are record locks for.

- 客户端和服务器可能会拒绝内存映射他们知道有记录锁的文件。

- Clients and servers MAY deny a record lock on a file they know is memory mapped.

- 客户端和服务器可能会拒绝他们知道是内存映射的文件上的记录锁。

- A client MAY deny memory mapping a file that it knows requires mandatory locking for I/O. If mandatory locking is enabled after the file is opened and mapped, the client MAY deny the application further access to its mapped file.

- 客户端可能会拒绝内存映射它知道需要强制锁定I/O的文件。如果在打开和映射文件后启用强制锁定,客户端可能会拒绝应用程序对其映射文件的进一步访问。

9.8. Name Caching
9.8. 名称高速缓存

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 filesystem APIs, 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.

查找和READDIR操作的结果可以缓存,以避免后续查找操作的开销。与属性缓存一样,不同的客户端缓存之间可能会出现不一致。为了减轻这些不一致的影响,并考虑到典型文件系统API的上下文,在不验证另一个客户端执行的目录更改操作是否使该项无效的情况下,对客户端名称缓存项可以保留的时间上限进行了维护。

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

如上面的场景所示,名称缓存要求客户端通过在缓存名称缓存项时检查目录的change属性来重新验证名称缓存数据。这要求服务器在修改相应目录的内容时更新目录的change属性。为了让客户端正确地使用change_info4信息,服务器必须以原子方式报告操作前和操作后的change属性值。当服务器运行时

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.

无法以原子方式报告与目录操作相关的before和after值,服务器必须在change_info4返回值中指出这一事实。当信息未按原子方式报告时,客户端不应假定其他客户端未更改目录。

9.9. Directory Caching
9.9. 目录缓存

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. To mitigate the effects of these inconsistencies, and given the context of typical filesystem APIs, the following rules should be followed:

READDIR操作的结果可用于避免后续的READDIR操作。与属性和名称缓存的情况一样,不同的客户端缓存之间可能会出现不一致。为了减轻这些不一致的影响,并考虑到典型文件系统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 version 4 protocol is represented by this RFC. The COMPOUND procedure will support the encoding of the minor version being requested by the client.

关于次要版本控制的基本假设是,任何未来接受的次要版本必须遵循IETF流程,并记录在标准跟踪RFC中。因此,每个次要版本号将对应一个RFC。NFS版本4协议的次要版本0由此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 to 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, filehandle, 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、filehandle或类似返回对象用于次要版本为Y的另一个复合过程,其中X!=Y

11. Internationalization
11. 国际化

The primary issue in which NFS version 4 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].

NFS版本4需要处理国际化或I18N的主要问题是协议中使用的文件名和其他字符串。字符串表示的选择必须允许对使用各种语言的客户端进行合理的名称/字符串访问。[ISO10646]定义的UCS UTF-8编码允许这种类型的访问,并遵循“关于字符集和语言的IETF政策”[RFC2277]中描述的政策。

[RFC3454], otherwise know as "stringprep", documents a framework for using Unicode/UTF-8 in networking protocols, so as "to increase the likelihood that string input and string comparison work in ways that make sense for typical users throughout the world." A protocol must define a profile of stringprep "in order to fully specify the processing options." The remainder of this Internationalization section defines the NFS version 4 stringprep profiles. Much of terminology used for the remainder of this section comes from stringprep.

[RFC3454],也称为“stringprep”,记录了在网络协议中使用Unicode/UTF-8的框架,以便“增加字符串输入和字符串比较以对全世界典型用户有意义的方式工作的可能性”。协议必须定义stringprep的配置文件“为了完全指定处理选项。”本节其余部分定义了NFS版本4 stringprep配置文件。本节其余部分使用的许多术语来自stringprep。

There are three UTF-8 string types defined for NFS version 4: utf8str_cs, utf8str_cis, and utf8str_mixed. Separate profiles are defined for each. Each profile defines the following, as required by stringprep:

NFS版本4定义了三种UTF-8字符串类型:utf8str_cs、utf8str_cis和utf8str_mixed。为每个配置文件定义了单独的配置文件。根据stringprep的要求,每个配置文件定义了以下内容:

o The intended applicability of the profile

o 概要文件的预期适用性

o The character repertoire that is the input and output to stringprep (which is Unicode 3.2 for referenced version of stringprep)

o 作为stringprep的输入和输出的字符集(对于stringprep的引用版本为Unicode 3.2)

o The mapping tables from stringprep used (as described in section 3 of stringprep)

o 使用stringprep的映射表(如stringprep第3节所述)

o Any additional mapping tables specific to the profile

o 特定于配置文件的任何其他映射表

o The Unicode normalization used, if any (as described in section 4 of stringprep)

o 使用的Unicode规范化(如有)(如stringprep第4节所述)

o The tables from stringprep listing of characters that are prohibited as output (as described in section 5 of stringprep)

o stringprep中的表格列出了禁止作为输出的字符(如stringprep第5节所述)

o The bidirectional string testing used, if any (as described in section 6 of stringprep)

o 使用的双向字符串测试(如有)(如stringprep第6节所述)

o Any additional characters that are prohibited as output specific to the profile

o 禁止作为配置文件特定输出的任何附加字符

Stringprep discusses Unicode characters, whereas NFS version 4 renders UTF-8 characters. Since there is a one to one mapping from UTF-8 to Unicode, where ever the remainder of this document refers to to Unicode, the reader should assume UTF-8.

Stringprep讨论Unicode字符,而NFS版本4呈现UTF-8字符。由于存在从UTF-8到Unicode的一对一映射,因此本文档的其余部分都引用Unicode,读者应该假设UTF-8。

Much of the text for the profiles comes from [RFC3454].

配置文件的大部分文本来自[RFC3454]。

11.1. Stringprep profile for the utf8str_cs type
11.1. utf8str_cs类型的Stringprep配置文件

Every use of the utf8str_cs type definition in the NFS version 4 protocol specification follows the profile named nfs4_cs_prep.

NFS版本4协议规范中utf8str_cs类型定义的每次使用都遵循名为nfs4_cs_prep的配置文件。

11.1.1. Intended applicability of the nfs4_cs_prep profile
11.1.1. nfs4\U cs\U准备概要的预期适用性

The utf8str_cs type is a case sensitive string of UTF-8 characters. Its primary use in NFS Version 4 is for naming components and pathnames. Components and pathnames are stored on the server's filesystem. Two valid distinct UTF-8 strings might be the same after processing via the utf8str_cs profile. If the strings are two names inside a directory, the NFS version 4 server will need to either:

utf8str_cs类型是一个区分大小写的UTF-8字符字符串。它在NFS版本4中的主要用途是命名组件和路径名。组件和路径名存储在服务器的文件系统中。通过utf8str_cs配置文件处理后,两个有效的不同UTF-8字符串可能相同。如果字符串是目录中的两个名称,NFS版本4服务器将需要:

o disallow the creation of a second name if it's post processed form collides with that of an existing name, or

o 如果后处理表单与现有名称冲突,则不允许创建第二个名称,或者

o allow the creation of the second name, but arrange so that after post processing, the second name is different than the post processed form of the first name.

o 允许创建第二个名称,但进行安排,以便在后处理后,第二个名称与第一个名称的后处理形式不同。

11.1.2. Character repertoire of nfs4_cs_prep
11.1.2. nfs4\U cs\U prep人物剧目

The nfs4_cs_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1

nfs4_cs_prep配置文件使用Unicode 3.2,如stringprep附录A.1中所定义

11.1.3. Mapping used by nfs4_cs_prep
11.1.3. nfs4\U cs\U准备使用的映射

The nfs4_cs_prep profile specifies mapping using the following tables from stringprep:

nfs4_cs_prep配置文件使用stringprep中的下表指定映射:

Table B.1

表B.1

Table B.2 is normally not part of the nfs4_cs_prep profile as it is primarily for dealing with case-insensitive comparisons. However, if the NFS version 4 file server supports the case_insensitive filesystem attribute, and if case_insensitive is true, the NFS version 4 server MUST use Table B.2 (in addition to Table B1) when processing utf8str_cs strings, and the NFS version 4 client MUST assume Table B.2 (in addition to Table B.1) are being used.

表B.2通常不是nfs4_cs_prep概要的一部分,因为它主要用于处理不区分大小写的比较。但是,如果NFS版本4文件服务器支持不区分大小写的文件系统属性,并且不区分大小写为true,则NFS版本4服务器在处理utf8str_cs字符串时必须使用表B.2(除表B1外),并且NFS版本4客户端必须假定正在使用表B.2(除表B.1外)。

If the case_preserving attribute is present and set to false, then the NFS version 4 server MUST use table B.2 to map case when processing utf8str_cs strings. Whether the server maps from lower to upper case or the upper to lower case is an implementation dependency.

如果case_preserving属性存在并设置为false,则NFS版本4服务器在处理utf8str_cs字符串时必须使用表B.2映射case。服务器是从小写字母映射到大写字母还是从大写字母映射到小写字母是一个实现依赖项。

11.1.4. Normalization used by nfs4_cs_prep
11.1.4. nfs4\U cs\U准备使用的标准化

The nfs4_cs_prep profile does not specify a normalization form. 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 utf8str_cs strings within the protocol before presenting the information to an application (at the client) or local filesystem (at the server).

nfs4_cs_prep配置文件未指定规范化表单。本规范的后续版本可能会指定特定的规范化形式。因此,服务器和客户机可能会在协议请求和响应中接收到非规范化字符。如果操作环境需要规范化,那么在将信息呈现给应用程序(客户端)或本地文件系统(服务器)之前,实现必须规范化协议中的utf8str_cs字符串。

11.1.5. Prohibited output for nfs4_cs_prep
11.1.5. nfs4\U cs\U准备的禁止输出

The nfs4_cs_prep profile specifies prohibiting using the following tables from stringprep:

nfs4_cs_prep配置文件规定禁止从stringprep使用下表:

Table C.3 Table C.4 Table C.5 Table C.6 Table C.7 Table C.8 Table C.9

表C.3表C.4表C.5表C.6表C.7表C.8表C.9

11.1.6. Bidirectional output for nfs4_cs_prep
11.1.6. nfs4\U cs\U准备的双向输出

The nfs4_cs_prep profile does not specify any checking of bidirectional strings.

nfs4_cs_prep配置文件未指定对双向字符串的任何检查。

11.2. Stringprep profile for the utf8str_cis type
11.2. utf8str_cis类型的Stringprep配置文件

Every use of the utf8str_cis type definition in the NFS version 4 protocol specification follows the profile named nfs4_cis_prep.

NFS版本4协议规范中utf8str_cis类型定义的每次使用都遵循名为nfs4_cis_prep的配置文件。

11.2.1. Intended applicability of the nfs4_cis_prep profile
11.2.1. nfs4\U cis\U准备概要的预期适用性

The utf8str_cis type is a case insensitive string of UTF-8 characters. Its primary use in NFS Version 4 is for naming NFS servers.

utf8str_cis类型是一个不区分大小写的UTF-8字符字符串。它在NFS版本4中的主要用途是命名NFS服务器。

11.2.2. Character repertoire of nfs4_cis_prep
11.2.2. nfs4_cis_prep人物剧目

The nfs4_cis_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1

nfs4_cis_prep配置文件使用Unicode 3.2,如stringprep附录A.1中所定义

11.2.3. Mapping used by nfs4_cis_prep
11.2.3. nfs4_cis_prep使用的映射

The nfs4_cis_prep profile specifies mapping using the following tables from stringprep:

nfs4_cis_prep配置文件使用stringprep中的下表指定映射:

Table B.1 Table B.2

表B.1表B.2

11.2.4. Normalization used by nfs4_cis_prep
11.2.4. nfs4_cis_prep使用的标准化

The nfs4_cis_prep profile specifies using Unicode normalization form KC, as described in stringprep.

nfs4_cis_prep配置文件使用Unicode规范化形式KC进行指定,如stringprep中所述。

11.2.5. Prohibited output for nfs4_cis_prep
11.2.5. nfs4\U cis\U准备的禁止输出

The nfs4_cis_prep profile specifies prohibiting using the following tables from stringprep:

nfs4_cis_prep配置文件指定禁止从stringprep使用下表:

Table C.1.2 Table C.2.2 Table C.3 Table C.4 Table C.5 Table C.6 Table C.7 Table C.8 Table C.9

表C.1.2表C.2.2表C.3表C.4表C.5表C.6表C.7表C.8表C.9

11.2.6. Bidirectional output for nfs4_cis_prep
11.2.6. nfs4\U cis\U准备的双向输出

The nfs4_cis_prep profile specifies checking bidirectional strings as described in stringprep's section 6.

nfs4_cis_prep配置文件指定检查双向字符串,如stringprep第6节所述。

11.3. Stringprep profile for the utf8str_mixed type
11.3. utf8str_混合类型的Stringprep配置文件

Every use of the utf8str_mixed type definition in the NFS version 4 protocol specification follows the profile named nfs4_mixed_prep.

NFS版本4协议规范中utf8str_混合类型定义的每次使用都遵循名为nfs4_mixed_prep的概要文件。

11.3.1. Intended applicability of the nfs4_mixed_prep profile
11.3.1. nfs4_混合_制备配置文件的预期适用性

The utf8str_mixed type is a string of UTF-8 characters, with a prefix that is case sensitive, a separator equal to '@', and a suffix that is fully qualified domain name. Its primary use in NFS Version 4 is for naming principals identified in an Access Control Entry.

utf8str_混合类型是一个UTF-8字符字符串,前缀区分大小写,分隔符等于“@”,后缀为完全限定域名。它在NFS版本4中的主要用途是命名访问控制条目中标识的主体。

11.3.2. Character repertoire of nfs4_mixed_prep
11.3.2. nfs4_mixed_prep的角色曲目

The nfs4_mixed_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1

nfs4_mixed_prep配置文件使用Unicode 3.2,定义见stringprep的附录A.1

11.3.3. Mapping used by nfs4_cis_prep
11.3.3. nfs4_cis_prep使用的映射

For the prefix and the separator of a utf8str_mixed string, the nfs4_mixed_prep profile specifies mapping using the following table from stringprep:

对于utf8str_混合字符串的前缀和分隔符,nfs4_混合_准备配置文件使用stringprep中的下表指定映射:

Table B.1

表B.1

For the suffix of a utf8str_mixed string, the nfs4_mixed_prep profile specifies mapping using the following tables from stringprep:

对于utf8str_混合字符串的后缀,nfs4_混合_prep配置文件使用stringprep中的下表指定映射:

Table B.1 Table B.2

表B.1表B.2

11.3.4. Normalization used by nfs4_mixed_prep
11.3.4. nfs4\u mixed\u prep使用的标准化

The nfs4_mixed_prep profile specifies using Unicode normalization form KC, as described in stringprep.

nfs4_mixed_prep配置文件使用Unicode规范化形式KC进行指定,如stringprep中所述。

11.3.5. Prohibited output for nfs4_mixed_prep
11.3.5. nfs4_混合_准备的禁止输出

The nfs4_mixed_prep profile specifies prohibiting using the following tables from stringprep:

nfs4_mixed_prep配置文件指定禁止从stringprep使用下表:

Table C.1.2 Table C.2.2 Table C.3 Table C.4 Table C.5 Table C.6 Table C.7 Table C.8 Table C.9

表C.1.2表C.2.2表C.3表C.4表C.5表C.6表C.7表C.8表C.9

11.3.6. Bidirectional output for nfs4_mixed_prep
11.3.6. nfs4_混合_准备的双向输出

The nfs4_mixed_prep profile specifies checking bidirectional strings as described in stringprep's section 6.

nfs4_mixed_prep配置文件指定检查stringprep第6节中所述的双向字符串。

11.4. UTF-8 Related Errors
11.4. UTF-8相关错误

Where the client sends an invalid UTF-8 string, the server should return an NFS4ERR_INVAL error. This includes cases in which inappropriate prefixes are detected and where the count includes trailing bytes that do not constitute a full UCS character.

当客户端发送无效的UTF-8字符串时,服务器应返回NFS4ERR_INVAL错误。这包括检测到不适当前缀的情况,以及计数包括不构成完整UCS字符的尾随字节的情况。

Where the client supplied string is valid UTF-8 but contains characters that are not supported by the server as a value for that string (e.g., names containing characters that have more than two octets on a filesystem that supports Unicode characters only), the server should return an NFS4ERR_BADCHAR error.

如果客户端提供的字符串是有效的UTF-8,但包含服务器不支持作为该字符串值的字符(例如,在仅支持Unicode字符的文件系统中,包含两个以上八位字节的字符的名称),则服务器应返回NFS4ERR_BADCHAR错误。

Where a UTF-8 string is used as a file name, and the filesystem, while supporting all of the characters within the name, does not allow that particular name to be used, the server should return the error NFS4ERR_BADNAME. This includes situations in which the server filesystem imposes a normalization constraint on name strings, but

如果使用UTF-8字符串作为文件名,并且文件系统支持名称中的所有字符,但不允许使用该特定名称,则服务器应返回错误NFS4ERR_BADNAME。这包括服务器文件系统对名称字符串施加规范化约束的情况,但是

will also include such situations as filesystem prohibitions of "." and ".." as file names for certain operations, and other such constraints.

还包括文件系统禁止将“.”和“.”作为某些操作的文件名,以及其他此类限制。

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_ACCESS 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_ATTRNOTSUPP An attribute specified is not supported by the server. Does not apply to the GETATTR operation.

NFS4ERR_ATTRNOTSUPP服务器不支持指定的属性。不适用于GETATTR操作。

NFS4ERR_ADMIN_REVOKED Due to administrator intervention, the lockowner's record locks, share reservations, and delegations have been revoked by the server.

NFS4ERR_ADMIN_由于管理员干预而被撤销,服务器已撤销锁所有者的记录锁、共享保留和委派。

NFS4ERR_BADCHAR A UTF-8 string contains a character which is not supported by the server in the context in which it being used.

NFS4ERR_BADCHAR UTF-8字符串包含服务器在其使用上下文中不支持的字符。

NFS4ERR_BAD_COOKIE READDIR cookie is stale.

NFS4ERR_BAD_COOKIE READDIR COOKIE已过期。

NFS4ERR_BADHANDLE Illegal NFS filehandle. The filehandle failed internal consistency checks.

NFS4ERR_baddhandle非法的NFS文件句柄。filehandle未通过内部一致性检查。

NFS4ERR_BADNAME A name string in a request consists of valid UTF-8 characters supported by the server but the name is not supported by the server as a valid name for current operation.

NFS4ERR_BADNAME请求中的名称字符串由服务器支持的有效UTF-8字符组成,但服务器不支持该名称作为当前操作的有效名称。

NFS4ERR_BADOWNER An owner, owner_group, or ACL attribute value can not be translated to local representation.

NFS4ERR_BADOWNER无法将所有者、所有者组或ACL属性值转换为本地表示形式。

NFS4ERR_BADTYPE An attempt was made to create an object of a type not supported by the server.

NFS4ERR_BADTYPE试图创建服务器不支持的类型的对象。

NFS4ERR_BAD_RANGE The range for a LOCK, LOCKT, or LOCKU operation is not appropriate to the allowable range of offsets for the server.

NFS4ERR_BAD_RANGE锁定、锁定或锁定操作的范围不适合服务器允许的偏移范围。

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_BADXDR The server encountered an XDR decoding error while processing an operation.

NFS4ERR_BADXDR服务器在处理操作时遇到XDR解码错误。

NFS4ERR_CLID_INUSE The SETCLIENTID operation has found that a client id is already in use by another client.

NFS4ERR_CLID_使用SETCLIENTID操作发现一个客户端id已被另一个客户端使用。

NFS4ERR_DEADLOCK The server has been able to determine a file locking deadlock condition for a blocking lock request.

NFS4ERR_DEADLOCK服务器能够确定阻塞锁定请求的文件锁定死锁条件。

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 operation.

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 filehandle provided is volatile and has expired at the server.

NFS4errfhu提供的文件句柄是易失性的,已在服务器上过期。

NFS4ERR_FILE_OPEN The operation can not be successfully processed because a file involved in the operation is currently open.

NFS4ERR_FILE_OPEN无法成功处理该操作,因为该操作涉及的文件当前处于打开状态。

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 specifying a value for an enum field that is not defined in the protocol (e.g., nfs_ftype4).

NFS4ERR_INVAL操作的参数无效或不支持的参数。两个示例是尝试在非符号链接的对象上进行READLINK,或为协议中未定义的枚举字段(例如nfs_ftype4)指定值。

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 filesystem 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_NOTSUPP Server does not support atomic upgrade or downgrade of locks.

NFS4ERR_LOCK_NOTSUPP服务器不支持锁的原子升级或降级。

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_LOCKS_HELD A CLOSE was attempted and file locks would exist after the CLOSE.

NFS4ERR_LOCKS_尝试关闭,关闭后将存在文件锁。

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_NOENT No such file or directory. The file or directory name specified does not exist.

NFS4ERR\n没有这样的文件或目录。指定的文件或目录名不存在。

NFS4ERR_NOFILEHANDLE The logical current filehandle value (or, in the case of RESTOREFH, the saved filehandle 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 filehandle be set).

NFS4ERR_NOFILEHANDLE未正确设置逻辑当前文件句柄值(如果是RESTOREFH,则为保存的文件句柄值)。这可能是由于复合操作的格式错误(即,在需要设置当前文件句柄的操作之前没有PUTFH或PUTROOTFH)。

NFS4ERR_NO_GRACE A reclaim of client state has fallen outside of the grace period of the server. As a result, the server can not guarantee that conflicting state has not been provided to another client.

NFS4ERR_NO_GRACE客户端状态的恢复已超出服务器的宽限期。因此,服务器无法保证冲突状态未提供给其他客户端。

NFS4ERR_NOSPC No space left on device. The operation would have caused the server's filesystem 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_OPENMODE The client attempted a READ, WRITE, LOCK or SETATTR operation not sanctioned by the stateid passed (e.g., writing to a file opened only for read).

NFS4ERR_OPENMODE客户端尝试了未经传递的stateid批准的读、写、锁或SETATTR操作(例如,写入仅为读取而打开的文件)。

NFS4ERR_OP_ILLEGAL An illegal operation value has been specified in the argop field of a COMPOUND or CB_COMPOUND procedure.

NFS4ERR_OP_非法在复合过程或CB_复合过程的argop字段中指定了非法操作值。

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_RECLAIM_BAD The reclaim provided by the client does not match any of the server's state consistency checks and is bad.

NFS4ERR_reclain_BAD客户端提供的回收与服务器的任何状态一致性检查都不匹配,因此无效。

NFS4ERR_RECLAIM_CONFLICT The reclaim provided by the client has encountered a conflict and can not be provided. Potentially indicates a misbehaving client.

NFS4ERR_Reclain_冲突客户端提供的回收遇到冲突,无法提供。可能表示客户端行为不正常。

NFS4ERR_RESOURCE For the processing of the COMPOUND procedure, the server may exhaust available resources and can not continue processing operations within the COMPOUND procedure. This error will be returned from the server in those instances of resource exhaustion related to the processing of the COMPOUND procedure.

NFS4ERR_资源对于复合过程的处理,服务器可能会耗尽可用资源,并且无法继续复合过程内的处理操作。在与复合过程处理相关的资源耗尽实例中,服务器将返回此错误。

NFS4ERR_RESTOREFH The RESTOREFH operation does not have a saved filehandle (identified by SAVEFH) to operate upon.

NFS4ERR_RESTOREFH RESTOREFH操作没有可操作的已保存文件句柄(由SAVEFH标识)。

NFS4ERR_ROFS Read-only filesystem. A modifying operation was attempted on a read-only filesystem.

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 filehandle. The filehandle given in the arguments was invalid. The file referred to by that filehandle 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 filehandle 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 The encoded response to a READDIR request exceeds the size limit set by the initial request.

NFS4ERR_Toosall对READDIR请求的编码响应超过初始请求设置的大小限制。

NFS4ERR_WRONGSEC The security mechanism being used by the client for the operation 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 an operation between different fsids.

NFS4ERR_XDEV尝试在不同的FSID之间执行操作。

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 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 RPC程序,有两个传统的RPC过程:NULL和component。所有其他功能都被定义为一组操作,这些操作是在正常的XDR/RPC语法和语义中定义的。但是,这些操作被封装在复合过程中。这要求客户端将一个或多个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/SETCLIENTID_CONFIRM sequence. The program and port can be changed by another SETCLIENTID/SETCLIENTID_CONFIRM sequence, and it is possible to use the sequence to change them within a client incarnation without removing relevant leased client state.

NFS4_回调程序用于提供服务器到客户端的信令,其构造方式与NFS版本4程序类似。CB_NULL和CB_component过程的定义方式与NFS程序中的NULL和component过程相同。CB_复合请求还封装了NFS4_回调程序的其余操作。NFS4_回调程序没有预定义的RPC程序编号。由客户机在“瞬态”程序范围内指定程序编号。NFS4_回调程序的程序和端口号由客户端作为SETCLIENTID/SETCLIENTID_确认序列的一部分提供。程序和端口可以由另一个SETCLIENTID/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 basic structure of the COMPOUND procedure is:

复合程序的基本结构是:

   +-----+--------------+--------+-----------+-----------+-----------+--
   | tag | minorversion | numops | op + args | op + args | op + args |
   +-----+--------------+--------+-----------+-----------+-----------+--
        
   +-----+--------------+--------+-----------+-----------+-----------+--
   | tag | minorversion | numops | op + args | op + args | op + args |
   +-----+--------------+--------+-----------+-----------+-----------+--
        

and the reply's structure is:

答覆的结构如下:

      +------------+-----+--------+-----------------------+--
      |last status | tag | numres | status + op + results |
      +------------+-----+--------+-----------------------+--
        
      +------------+-----+--------+-----------------------+--
      |last status | tag | numres | status + op + results |
      +------------+-----+--------+-----------------------+--
        

The numops and numres fields, used in the depiction above, represent the count for the counted array encoding use to signify the number of arguments or results encoded in the request and response. As per the XDR encoding, these counts must match exactly the number of operation arguments or results encoded.

上面描述中使用的numops和numres字段表示计数数组编码的计数,用于表示请求和响应中编码的参数或结果的数量。根据XDR编码,这些计数必须与编码的操作参数或结果的数量完全匹配。

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 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.

服务器将通过按顺序评估复合过程中的每个操作来处理复合过程。每个组件操作由一个32位操作代码组成,后跟由操作类型确定的长度参数。每个操作的结果按顺序编码到应答缓冲区中。每个操作的结果前面都有操作码和状态码(通常为零)。如果操作导致非零状态代码,则状态将被编码,复合序列的评估将停止,并返回应答。请注意,即使在出现“非错误”条件(如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_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_资源和NFS4ERR_延迟等错误,部分完成的复合过程可能在任何时候发生。即使给定有效的操作字符串,也可能发生这种情况。此外,在处理复合过程的过程中发生的服务器重启可能会使客户端难以确定复合处理已经进行了多远。因此,如果程序中的操作失败,客户应避免过于复杂的复合程序。

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 filesystem 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 {
             utf8str_cs      tag;
             uint32_t        minorversion;
             nfs_argop4      argarray<>;
     };
        
     struct COMPOUND4args {
             utf8str_cs      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;
             utf8str_cs      tag;
             nfs_resop4      resarray<>;
     };
        
     struct COMPOUND4res {
             nfsstat4        status;
             utf8str_cs      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 server will generally choose between two methods of decoding the client's request. The first would be the traditional one-pass XDR decode, in which decoding of the entire COMPOUND precedes execution of any operation within it. If there is an XDR decoding error in this case, an RPC XDR decode error would be returned. The second method would be to make an initial pass to decode the basic COMPOUND request and then to XDR decode each of the individual operations, as the server is ready to execute it. In this case, the server may encounter an XDR decode error during such an operation decode, after previous operations within the COMPOUND have been executed. In this case, the server would return the error NFS4ERR_BADXDR to signify the decode error.

服务器通常会在两种解码客户端请求的方法之间进行选择。第一种是传统的单通XDR解码,在这种解码中,整个化合物的解码先于其中任何操作的执行。如果在这种情况下存在XDR解码错误,将返回RPC XDR解码错误。第二种方法是在服务器准备执行基本复合请求时,进行初始传递以解码基本复合请求,然后对每个单独的操作进行XDR解码。在这种情况下,在执行了化合物内的先前操作之后,服务器可能在这样的解码操作期间遇到XDR解码错误。在这种情况下,服务器将返回错误NFS4ERR_BADXDR以表示解码错误。

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. 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”字段。此字段的初始值和默认值为0(零)。此字段将由将来的次要版本使用,以便客户端可以与服务器通信请求的次要版本。如果服务器接收到一个复合过程,其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. 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_OP_ILLEGAL, as described in the next paragraph, is returned to the client. 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(一)。操作2未定义,但保留用于将来的定义,并与次要版本控制一起使用。如果服务器接收到包含操作2的操作数组,并且minorversion字段的值为0(零),则会将NFS4ERR_OP_非法错误返回给客户端,如下一段所述。如果操作数组包含操作2且minorversion字段为非零且服务器不支持次要版本,则服务器返回错误NFS4ERR_minor_VERS_MISMATCH。因此,NFS4ERR_MINOR_VERS_失配错误优先于所有其他错误。

It is possible that the server receives a request that contains an operation that is less than the first legal operation (OP_ACCESS) or greater than the last legal operation (OP_RELEASE_LOCKOWNER).

服务器接收到的请求可能包含小于第一个合法操作(OP_访问)或大于最后一个合法操作(OP_释放锁定所有者)的操作。

In this case, the server's response will encode the opcode OP_ILLEGAL rather than the illegal opcode of the request. The status field in the ILLEGAL return results will set to NFS4ERR_OP_ILLEGAL. The COMPOUND procedure's return results will also be NFS4ERR_OP_ILLEGAL.

在这种情况下,服务器的响应将把操作码OP_编码为非法,而不是请求的非法操作码。非法返回结果中的状态字段将设置为NFS4ERR_OP_非法。复合过程的返回结果也将是NFS4ERR_OP_非法的。

The definition of the "tag" in the request is 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. However, the value of "tag" in the response SHOULD be the same value as provided in the request. This applies to the tag field of the CB_COMPOUND procedure as well.

请求中“标记”的定义留给实现者。它可以用来总结复合请求的内容,以便包嗅探器和工程师调试实现。但是,响应中“tag”的值应该与请求中提供的值相同。这也适用于CB_复合过程的标记字段。

IMPLEMENTATION

实施

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 were 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.

ACCESS4\u删除现有目录项。

ACCESS4_EXECUTE Execute file (no meaning for a directory).

ACCESS4\u执行文件(对目录没有意义)。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

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 operation 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

在NFS版本2协议中,确定是否允许操作的唯一可靠方法是尝试操作并查看操作是否成功。使用NFS版本4协议中的访问操作,客户机可以要求服务器指示是否允许一个或多个操作类。提供访问操作是为了允许客户端在执行一系列操作之前进行检查,这些操作将导致访问失败。公开的

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.

操作提供了一个点,服务器可以在该点上验证对文件对象和方法的访问,以将该信息返回给客户端。访问操作对于目录操作或在客户端使用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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO 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, open_stateid -> open_stateid

(cfh),seqid,open_stateid->open_stateid

ARGUMENT

论点

     struct CLOSE4args {
             /* CURRENT_FH: object */
             seqid4          seqid
             stateid4        open_stateid;
     };
        
     struct CLOSE4args {
             /* CURRENT_FH: object */
             seqid4          seqid
             stateid4        open_stateid;
     };
        

RESULT

后果

     union CLOSE4res switch (nfsstat4 status) {
      case NFS4_OK:
              stateid4       open_stateid;
      default:
              void;
     };
        
     union CLOSE4res switch (nfsstat4 status) {
      case NFS4_OK:
              stateid4       open_stateid;
      default:
              void;
     };
        

DESCRIPTION

描述

The CLOSE operation releases share reservations for the regular or named attribute 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

实施

Even though CLOSE returns a stateid, this stateid is not useful to the client and should be treated as deprecated. CLOSE "shuts down" the state associated with all OPENs for the file by a single open_owner. As noted above, CLOSE will either release all file locking state or return an error. Therefore, the stateid returned by CLOSE is not useful for operations that follow.

即使CLOSE返回stateid,该stateid对客户端也没有用处,应视为已弃用。CLOSE“关闭”与单个open_所有者为文件打开的所有文件关联的状态。如上所述,CLOSE将释放所有文件锁定状态或返回错误。因此,CLOSE返回的stateid对于后面的操作没有用处。

ERRORS

错误

NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID

NFS4ERR\u ADMIN\u吊销的NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u SEQID

NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCKS_HELD NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u BAD\u STATEID NFS4ERR\u BADXDR NFS4ERR\u DELAY NFS4ERR\u过期NFS4ERR\u Fhs4Err\u Invalir NFS4ERR\u租约NFS4ERR\u移动的NFS4ERR\u移动的NFS4ERR\u文件句柄NFS4ERR\u旧的NFS4ERR\u状态资源NFS4ERR\u服务器故障NFS4ERR\u过时的NFS4ERR\u状态

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 filehandle. The flushed data is that which was previously written with a WRITE operation which had the stable field set to UNSTABLE4.

提交操作强制或刷新数据到由当前filehandle指定的文件的稳定存储中。刷新的数据是以前使用写入操作写入的数据,该操作的稳定字段设置为不稳定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 operation. 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 operation 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

提交的服务器实现相当简单。如果服务器接收到一个完整的文件提交请求,即从偏移量0和计数0开始,它应该执行与fsync()相同的操作。否则,它应该将缓存的数据安排在

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.

由要刷新到稳定存储的偏移量和计数指定的范围。在这两种情况下,在返回之前,必须将与文件关联的任何元数据刷新到稳定存储中。服务器上没有要刷新的内容不是错误。这意味着需要刷新的数据和元数据在上次服务器故障期间已被刷新或丢失。

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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏句柄NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u ISDIR NFS4ERR\u移动的NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u ROFS NFS4ERR\u服务器故障NFS4ERR\u过时

14.2.4. Operation 6: CREATE - Create a Non-Regular File Object
14.2.4. 操作6:创建-创建非常规文件对象

SYNOPSIS

提要

(cfh), name, type, attrs -> (cfh), change_info, attrs_set

(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 */
             createtype4     objtype;
             component4      objname;
             fattr4          createattrs;
     };
        
     struct CREATE4args {
             /* CURRENT_FH: directory for creation */
             createtype4     objtype;
             component4      objname;
             fattr4          createattrs;
     };
        

RESULT

后果

     struct CREATE4resok {
             change_info4    cinfo;
             bitmap4         attrset;        /* attributes set */
        
     struct CREATE4resok {
             change_info4    cinfo;
             bitmap4         attrset;        /* attributes set */
        

};

};

     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 operation MUST be used to create a regular file.

创建操作在具有给定名称的目录中创建一个非常规文件对象。必须使用“打开”操作创建常规文件。

The objname specifies the name for the new object. The objtype determines the type of object to be created: directory, symlink, etc.

objname指定新对象的名称。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.

当前文件句柄将替换为新对象的文件句柄。

The createattrs specifies the initial set of attributes for the object. The set of attributes may include any writable attribute valid for the object type. When the operation is successful, the server will return to the client an attribute mask signifying which attributes were successfully set for the object.

createattrs指定对象的初始属性集。属性集可以包括对对象类型有效的任何可写属性。操作成功后,服务器将向客户端返回一个属性掩码,表示已成功为对象设置了哪些属性。

If createattrs includes neither the owner attribute nor an ACL with an ACE for the owner, and if the server's filesystem both supports and requires an owner attribute (or an owner ACE) then the server MUST derive the owner (or the owner ACE). This would typically be from the principal indicated in the RPC credentials of the call, but the server's operating environment or filesystem semantics may dictate other methods of derivation. Similarly, if createattrs includes neither the group attribute nor a group ACE, and if the server's filesystem both supports and requires the notion of a group attribute (or group ACE), the server MUST derive the group attribute

如果createattrs既不包含所有者属性,也不包含具有所有者ACE的ACL,并且如果服务器的文件系统既支持也需要所有者属性(或所有者ACE),则服务器必须派生所有者(或所有者ACE)。这通常来自调用的RPC凭据中指示的主体,但服务器的操作环境或文件系统语义可能会指定其他派生方法。类似地,如果createattrs既不包括group属性也不包括group ACE,并且如果服务器的文件系统既支持也需要group属性(或group ACE)的概念,则服务器必须派生group属性

(or the corresponding owner ACE) for the file. This could be from the RPC call's credentials, such as the group principal if the credentials include it (such as with AUTH_SYS), from the group identifier associated with the principal in the credentials (for e.g., POSIX systems have a passwd database that has the group identifier for every user identifier), inherited from directory the object is created in, or whatever else the server's operating environment or filesystem semantics dictate. This applies to the OPEN operation too.

(或相应的所有者ACE)的文件。这可能来自RPC调用的凭据,例如,如果凭据包括组主体(例如使用AUTH_SYS),则来自与凭据中的主体关联的组标识符(例如,POSIX系统有一个passwd数据库,该数据库具有每个用户标识符的组标识符),继承自创建对象的目录,或服务器的操作环境或文件系统语义规定的任何其他内容。这也适用于打开操作。

Conversely, it is possible the client will specify in createattrs an owner attribute or group attribute or ACL that the principal indicated the RPC call's credentials does not have permissions to create files for. The error to be returned in this instance is NFS4ERR_PERM. This applies to the OPEN operation too.

相反,客户端可能会在createattrs中指定所有者属性、组属性或ACL,主体指示RPC调用的凭据没有为其创建文件的权限。此实例中返回的错误是NFS4ERR\u PERM。这也适用于打开操作。

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_ACCESS NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADOWNER NFS4ERR_BADTYPE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_PERM NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE

中文意思意思是“错误”的意思意思是“错误”的意思意思是“错误”的意思意思是“错误”的意思是“名字”的意思是“错误”的意思是“身份”的意思是“错误”的意思是“错误”的意思意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“错误”的意思是“处理处理处理处理处理”的处理。或者是“错误”的处理处理。或者是“错误”的意思是“错误”的意思是“错误”的。或者是“无效的。或者是,或者是,或者是,或者是,或者是,或者是“无效的。或者是,或者是。S4Err_ROFSNFS4ERR_服务器故障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 known 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。这样做将通知服务器,不会恢复客户端的其他委派,从而允许其释放资源,并避免延迟发出与未恢复委派冲突的请求的其他客户端。服务器和客户端已知的委托集可能不同。原因是,客户机可能在发出导致委派的请求后,但在收到结果并将其提交到客户机的稳定存储之前失败。

The server MAY support DELEGPURGE, but if it does not, it MUST NOT support CLAIM_DELEGATE_PREV.

服务器可能支持DELEGPURGE,但如果不支持,则不能支持CLAIM_DELEGATE_PREV。

ERRORS

错误

NFS4ERR_BADXDR NFS4ERR_NOTSUPP NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_RESOURCE

NFS4ERR\u BADXDR NFS4ERR\u NOTSUPP NFS4ERR\u租约\u移动的NFS4ERR\u移动的NFS4ERR\u资源

NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR_服务器故障NFS4ERR_过时客户端ID

14.2.6. Operation 8: DELEGRETURN - Return Delegation
14.2.6. 操作8:DELEGRETURN-返回委派

SYNOPSIS

提要

(cfh), stateid ->

(cfh),stateid->

ARGUMENT

论点

     struct DELEGRETURN4args {
             /* CURRENT_FH: delegated file */
             stateid4        stateid;
     };
        
     struct DELEGRETURN4args {
             /* CURRENT_FH: delegated file */
             stateid4        stateid;
     };
        

RESULT

后果

     struct DELEGRETURN4res {
             nfsstat4        status;
     };
        
     struct DELEGRETURN4res {
             nfsstat4        status;
     };
        

DESCRIPTION

描述

Returns the delegation represented by the current filehandle and stateid.

返回由当前filehandle和stateid表示的委托。

Delegations may be returned when recalled or voluntarily (i.e., before the server has recalled them). In either case the client must properly propagate state changed under the context of the delegation to the server before returning the delegation.

可以在撤回或自愿(即,在服务器撤回委托之前)返回委托。在任何一种情况下,客户机都必须在返回委托之前将委托上下文中更改的状态正确地传播到服务器。

ERRORS

错误

NFS4ERR_ADMIN_REVOKED NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_EXPIRED NFS4ERR_INVAL NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u ADMIN\u撤销NFS4ERR\u BAD\u STATEID NFS4ERR\u BADXDR NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u租约\u移动NFS4ERR\u移动NFS4ERR\u NOFILEHANDLE NFS4ERR\u不支持NFS4ERR\u旧NFS4ERR\u STATEID NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u陈旧NFS4ERR\u STATEID

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 filesystem 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操作将获取由当前文件句柄指定的文件系统对象的属性。客户端在位图参数中为希望服务器返回的每个属性值设置一位。服务器返回一个属性位图,该位图指示它能够返回的属性值,然后是按顺序排列的属性值,该属性值首先是最低的属性号。

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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u坏句柄NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时

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_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u坏句柄NFS4ERR\u FH过期NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时

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 filesystem on the server. On success, the current filehandle will continue to be the target directory. If an object exists in the target directory with the same name as newname, the server must return NFS4ERR_EXIST.

链接操作在当前文件句柄表示的目录中为保存的文件句柄表示的文件创建一个额外的新名称,如SAVEFH操作所设置的。现有文件和目标目录必须位于服务器上的同一文件系统中。成功后,当前文件句柄将继续作为目标目录。如果目标目录中存在与newname同名的对象,则服务器必须返回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结构的原子字段,服务器将指示是否以原子方式获得了与链接创建相关的更改前后属性。

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 statement "file and the target directory must reside within the same filesystem on the server" means that the fsid fields in the attributes for the objects are the same. If they reside on different filesystems, the error, NFS4ERR_XDEV, is returned. On some servers, the filenames, "." and "..", are illegal as newname.

语句“文件和目标目录必须位于服务器上的同一文件系统中”意味着对象属性中的fsid字段是相同的。如果它们驻留在不同的文件系统上,则返回错误NFS4ERR_XDEV。在某些服务器上,文件名“.”和“.”作为新名称是非法的。

In the case that newname is already linked to the file represented by the saved filehandle, the server will return NFS4ERR_EXIST.

如果newname已经链接到保存的文件句柄表示的文件,服务器将返回NFS4ERR_EXIST。

Note that symbolic links are created with the CREATE operation.

请注意,符号链接是通过创建操作创建的。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_FILE_OPEN

NFS4ERR\u访问NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADNAME NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u DQUOT NFS4ERR\u存在NFS4ERR\u过期NFS4ERR\u文件打开

NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_MLINK NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC NFS4ERR_XDEV

NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u ISDIR NFS4ERR\u链接NFS4ERR\u将NFS4ERR\u名称工具移动到NFS4ERR\u NOENT NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOSPC NFS4ERR\u NOTDIR NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u错误NFS4ERR\u

14.2.10. Operation 12: LOCK - Create Lock
14.2.10. 操作12:锁定-创建锁定

SYNOPSIS

提要

(cfh) locktype, reclaim, offset, length, locker -> stateid

(cfh)锁类型、回收、偏移、长度、锁->状态ID

ARGUMENT

论点

     struct open_to_lock_owner4 {
             seqid4          open_seqid;
             stateid4        open_stateid;
             seqid4          lock_seqid;
             lock_owner4     lock_owner;
     };
        
     struct open_to_lock_owner4 {
             seqid4          open_seqid;
             stateid4        open_stateid;
             seqid4          lock_seqid;
             lock_owner4     lock_owner;
     };
        
     struct exist_lock_owner4 {
             stateid4        lock_stateid;
             seqid4          lock_seqid;
     };
        
     struct exist_lock_owner4 {
             stateid4        lock_stateid;
             seqid4          lock_seqid;
     };
        
     union locker4 switch (bool new_lock_owner) {
      case TRUE:
             open_to_lock_owner4     open_owner;
      case FALSE:
             exist_lock_owner4       lock_owner;
     };
        
     union locker4 switch (bool new_lock_owner) {
      case TRUE:
             open_to_lock_owner4     open_owner;
      case FALSE:
             exist_lock_owner4       lock_owner;
     };
        

enum nfs_lock_type4 { READ_LT = 1, WRITE_LT = 2,

枚举nfs\u lock\u type4{READ\u LT=1,WRITE\u LT=2,

             READW_LT        = 3,    /* blocking read */
             WRITEW_LT       = 4     /* blocking write */
     };
        
             READW_LT        = 3,    /* blocking read */
             WRITEW_LT       = 4     /* blocking write */
     };
        
     struct LOCK4args {
             /* CURRENT_FH: file */
             nfs_lock_type4  locktype;
             bool            reclaim;
             offset4         offset;
             length4         length;
             locker4         locker;
     };
        
     struct LOCK4args {
             /* CURRENT_FH: file */
             nfs_lock_type4  locktype;
             bool            reclaim;
             offset4         offset;
             length4         length;
             locker4         locker;
     };
        

RESULT

后果

     struct LOCK4denied {
             offset4         offset;
             length4         length;
             nfs_lock_type4  locktype;
             lock_owner4     owner;
     };
        
     struct LOCK4denied {
             offset4         offset;
             length4         length;
             nfs_lock_type4  locktype;
             lock_owner4     owner;
     };
        
     struct LOCK4resok {
             stateid4        lock_stateid;
     };
        
     struct LOCK4resok {
             stateid4        lock_stateid;
     };
        
     union LOCK4res switch (nfsstat4 status) {
      case NFS4_OK:
              LOCK4resok     resok4;
      case NFS4ERR_DENIED:
              LOCK4denied    denied;
      default:
              void;
     };
        
     union LOCK4res switch (nfsstat4 status) {
      case NFS4_OK:
              LOCK4resok     resok4;
      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 nfs_lock_type4s. If this is a reclaim request, the reclaim parameter will be TRUE;

锁定操作请求对偏移量和长度参数指定的字节范围进行记录锁定。锁类型也指定为nfs_lock_类型4s之一。如果这是一个回收请求,回收参数将为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). If the length is zero,

文件中的字节可能会被锁定,即使这些字节当前未分配给该文件。要从特定偏移量到文件结尾(无论文件实际有多长)锁定文件,请使用所有位均设置为1(一)的长度字段。如果长度为零,

or if a length which is not all bits set to one is specified, and length when added to the offset exceeds the maximum 64-bit unsigned integer value, the error NFS4ERR_INVAL will result.

或者,如果指定了并非所有位都设置为1的长度,并且添加到偏移量时的长度超过了最大64位无符号整数值,则将导致错误NFS4ERR_INVAL。

Some servers may only support locking for byte offsets that fit within 32 bits. If the client specifies a range that includes a byte beyond the last byte offset of the 32-bit range, but does not include the last byte offset of the 32-bit and all of the byte offsets beyond it, up to the end of the valid 64-bit range, such a 32-bit server MUST return the error NFS4ERR_BAD_RANGE.

某些服务器可能只支持锁定32位以内的字节偏移量。如果客户机指定的范围包括超出32位范围最后一个字节偏移量的字节,但不包括32位的最后一个字节偏移量及其以外的所有字节偏移量,直到有效64位范围结束,则此类32位服务器必须返回错误NFS4ERR_BAD_范围。

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.

如果服务器无法确定冲突锁的确切偏移量和长度,则应在拒绝结果中返回参数中提供的相同偏移量和长度。“文件锁定”部分包含此操作和其他文件锁定操作的完整说明。

LOCK operations are subject to permission checks and to checks against the access type of the associated file. However, the specific right and modes required for various type of locks, reflect the semantics of the server-exported filesystem, and are not specified by the protocol. For example, Windows 2000 allows a write lock of a file open for READ, while a POSIX-compliant system does not.

锁定操作需要进行权限检查,并根据相关文件的访问类型进行检查。但是,各种类型的锁所需的特定权限和模式反映了服务器导出的文件系统的语义,并且没有由协议指定。例如,Windows 2000允许对打开读取的文件进行写锁定,而POSIX兼容系统则不允许。

When the client makes a lock request that corresponds to a range that the lockowner has locked already (with the same or different lock type), or to a sub-region of such a range, or to a region which includes multiple locks already granted to that lockowner, in whole or in part, and the server does not support such locking operations (i.e., does not support POSIX locking semantics), the server will return the error NFS4ERR_LOCK_RANGE. In that case, the client may return an error, or it may emulate the required operations, using only LOCK for ranges that do not include any bytes already locked by that lock_owner and LOCKU of locks held by that lock_owner (specifying an exactly-matching range and type). Similarly, when the client makes a lock request that amounts to upgrading (changing from a read lock to a write lock) or downgrading (changing from write lock to a read lock) an existing record lock, and the server does not

当客户端发出一个锁请求,该锁请求对应于锁所有者已经锁定的范围(使用相同或不同的锁类型),或者对应于该范围的子区域,或者对应于包含已全部或部分授予该锁所有者的多个锁的区域,并且服务器不支持此类锁定操作时(即,不支持POSIX锁定语义),服务器将返回错误NFS4ERR_LOCK_RANGE。在这种情况下,客户端可能会返回错误,或者它可能会模拟所需的操作,仅对不包括该锁所有者已锁定的任何字节和该锁所有者持有的锁的锁的锁的范围使用锁(指定完全匹配的范围和类型)。类似地,当客户端发出相当于升级(从读锁更改为写锁)或降级(从写锁更改为读锁)现有记录锁的锁请求时,服务器不会执行此操作

support such a lock, the server will return NFS4ERR_LOCK_NOTSUPP. Such operations may not perfectly reflect the required semantics in the face of conflicting lock requests from other clients.

如果支持这种锁定,服务器将返回NFS4ERR_lock_NOTSUPP。面对来自其他客户端的冲突锁请求,此类操作可能无法完美地反映所需的语义。

The locker argument specifies the lock_owner that is associated with the LOCK request. The locker4 structure is a switched union that indicates whether the lock_owner is known to the server or if the lock_owner is new to the server. In the case that the lock_owner is known to the server and has an established lock_seqid, the argument is just the lock_owner and lock_seqid. In the case that the lock_owner is not known to the server, the argument contains not only the lock_owner and lock_seqid but also the open_stateid and open_seqid. The new lock_owner case covers the very first lock done by the lock_owner and offers a method to use the established state of the open_stateid to transition to the use of the lock_owner.

locker参数指定与锁请求关联的锁所有者。locker4结构是一个交换的并集,它指示服务器是否知道锁的所有者,或者锁的所有者是否是服务器的新所有者。如果服务器知道锁的所有者并且有一个已建立的锁seqid,那么参数就是锁的所有者和锁seqid。如果服务器不知道lock_所有者,则参数不仅包含lock_所有者和lock_seqid,还包含open_stateid和open_seqid。新的lock_owner案例涵盖了lock_所有者完成的第一个锁,并提供了一种使用open_stateid的已建立状态转换为lock_所有者使用的方法。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_RANGE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DEADLOCK NFS4ERR_DELAY NFS4ERR_DENIED NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCK_NOTSUPP NFS4ERR_LOCK_RANGE NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NO_GRACE NFS4ERR_OLD_STATEID NFS4ERR_OPENMODE NFS4ERR_RECLAIM_BAD NFS4ERR_RECLAIM_CONFLICT NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_CLIENTID NFS4ERR_STALE_STATEID

本书中的两个词的词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词类,词NOFILEHANDLENFS4ERR\u NO\u GRACE NFS4ERR\u OLD\u STATEID NFS4ERR\u OPENMODE NFS4ERR\u Reclain\u BAD NFS4ERR\u Reclain\u CONFLICT NFS4ERR\u RESOURCE NFS4ERR\u SERVERFAULT NFS4ERR\u STALE NFS4ERR\u STALE\u CLIENTID NFS4ERR\u STALE\u STATEID

14.2.11. Operation 13: LOCKT - Test For Lock
14.2.11. 操作13:锁定-锁定测试

SYNOPSIS

提要

     (cfh) locktype, offset, length owner -> {void, NFS4ERR_DENIED ->
     owner}
        
     (cfh) locktype, offset, length owner -> {void, NFS4ERR_DENIED ->
     owner}
        

ARGUMENT

论点

     struct LOCKT4args {
             /* CURRENT_FH: file */
             nfs_lock_type4  locktype;
             offset4         offset;
             length4         length;
             lock_owner4     owner;
     };
        
     struct LOCKT4args {
             /* CURRENT_FH: file */
             nfs_lock_type4  locktype;
             offset4         offset;
             length4         length;
             lock_owner4     owner;
     };
        

RESULT

后果

     struct LOCK4denied {
             offset4         offset;
             length4         length;
             nfs_lock_type4  locktype;
             lock_owner4     owner;
     };
        
     struct LOCK4denied {
             offset4         offset;
             length4         length;
             nfs_lock_type4  locktype;
             lock_owner4     owner;
     };
        
     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, length, and type of the conflicting lock are returned; if no lock is held, nothing other than NFS4_OK is returned. Lock types READ_LT and READW_LT are processed in the same way in that a conflicting lock test is done without regard to blocking or non-blocking. The same is true for WRITE_LT and WRITEW_LT.

LOCKT操作按照参数中的指定测试锁。如果存在冲突锁,则返回冲突锁的所有者、偏移量、长度和类型;如果没有锁定,则只返回NFS4_OK。锁类型READ_LT和READW_LT的处理方式与执行冲突锁测试的方式相同,不考虑阻塞或非阻塞。WRITE_LT和WRITEW_LT也是如此。

The ranges are specified as for LOCK. The NFS4ERR_INVAL and NFS4ERR_BAD_RANGE errors are returned under the same circumstances as for LOCK.

这些范围指定为“锁定”。NFS4ERR_INVAL和NFS4ERR_BAD_范围错误在与LOCK相同的情况下返回。

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 a lock_owner4 rather a stateid4, as is used in LOCK to identify the owner. This is because the client does not have to open the file to test for the existence of a lock, so a stateid may not be available.

LOCKT使用lock_owner4而不是stateid4,就像在lock中用来标识所有者一样。这是因为客户端不必打开文件来测试是否存在锁,因此stateid可能不可用。

The test for conflicting locks should exclude locks for the current lockowner. Note that since such locks are not examined the possible existence of overlapping ranges may not affect the results of LOCKT. If the server does examine locks that match the lockowner for the purpose of range checking, NFS4ERR_LOCK_RANGE may be returned.. In the event that it returns NFS4_OK, clients may do a LOCK and receive NFS4ERR_LOCK_RANGE on the LOCK request because of the flexibility provided to the server.

冲突锁的测试应排除当前锁所有者的锁。注意,由于未检查此类锁,重叠范围的可能存在可能不会影响锁的结果。如果服务器出于范围检查的目的检查与锁所有者匹配的锁,则可能会返回NFS4ERR_LOCK_range。。在返回NFS4_OK的情况下,由于服务器提供的灵活性,客户端可能会执行锁定并在锁定请求上接收NFS4ERR_LOCK_范围。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BAD_RANGE NFS4ERR_BADXDR 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\u访问NFS4ERR\u坏句柄NFS4ERR\u坏范围NFS4ERR\u坏XDR 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:
              stateid4       stateid;
      default:
              void;
     };
        
     union LOCKU4res switch (nfsstat4 status) {
      case   NFS4_OK:
              stateid4       stateid;
      default:
              void;
     };
        

DESCRIPTION

描述

The LOCKU operation unlocks the record lock specified by the parameters. The client may set the locktype field to any value that is legal for the nfs_lock_type4 enumerated type, and the server MUST accept any legal value for locktype. Any legal value for locktype has no effect on the success or failure of the LOCKU operation.

LOCKU操作解锁参数指定的记录锁。客户端可以将locktype字段设置为nfs_lock_type4枚举类型的任何合法值,服务器必须接受locktype的任何合法值。locktype的任何法律价值对LOCKU操作的成功或失败没有影响。

The ranges are specified as for LOCK. The NFS4ERR_INVAL and NFS4ERR_BAD_RANGE errors are returned under the same circumstances as for LOCK.

这些范围指定为“锁定”。NFS4ERR_INVAL和NFS4ERR_BAD_范围错误在与LOCK相同的情况下返回。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

If the area to be unlocked does not correspond exactly to a lock actually held by the lockowner the server may return the error NFS4ERR_LOCK_RANGE. This includes the case in which the area is not locked, where the area is a sub-range of the area locked, where it overlaps the area locked without matching exactly or the area specified includes multiple locks held by the lockowner. In all of

如果要解锁的区域与锁所有者实际持有的锁不完全对应,服务器可能返回错误NFS4ERR_lock_RANGE。这包括区域未锁定的情况,其中该区域是锁定区域的子范围,与锁定区域重叠而不完全匹配,或者指定的区域包括锁所有者持有的多个锁。总之

these cases, allowed by POSIX locking semantics, a client receiving this error, should if it desires support for such operations, simulate the operation using LOCKU on ranges corresponding to locks it actually holds, possibly followed by LOCK requests for the sub-ranges not being unlocked.

POSIX locking semantics(接收此错误的客户端)允许这些情况,如果希望支持此类操作,则应在与实际持有的锁相对应的范围上使用LOCKU模拟操作,随后可能会对未解锁的子范围发出锁请求。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_RANGE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_BADXDR 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_STATEID

词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词_STALENFS4ERR_STALE_STATEID

14.2.13. Operation 15: LOOKUP - Lookup Filename
14.2.13. 操作15:查找-查找文件名

SYNOPSIS

提要

(cfh), component -> (cfh)

(cfh),组件->(cfh)

ARGUMENT

论点

     struct LOOKUP4args {
             /* CURRENT_FH: directory */
             component4      objname;
     };
        
     struct LOOKUP4args {
             /* CURRENT_FH: directory */
             component4      objname;
     };
        

RESULT

后果

     struct LOOKUP4res {
             /* CURRENT_FH: object */
             nfsstat4        status;
     };
        
     struct LOOKUP4res {
             /* CURRENT_FH: object */
             nfsstat4        status;
     };
        

DESCRIPTION

描述

This operation LOOKUPs or finds a filesystem object using the directory specified by the current filehandle. LOOKUP evaluates the component and if the object exists the current filehandle is replaced with the component's filehandle.

此操作使用当前文件句柄指定的目录查找或查找文件系统对象。查找计算组件,如果对象存在,则当前文件句柄将替换为组件的文件句柄。

If the component cannot be evaluated either because it does not exist or because the client does not have permission to evaluate the component, then an error will be returned and the current filehandle will be unchanged.

如果由于组件不存在或客户端没有评估组件的权限而无法评估该组件,则将返回一个错误,并且当前文件句柄将保持不变。

If the component is a zero length string or if any component does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果组件为零长度字符串,或者如果任何组件不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

IMPLEMENTATION

实施

If the client wants to achieve the effect of a multi-component lookup, it may construct a COMPOUND request such as (and obtain each filehandle):

如果客户端希望实现多组件查找的效果,它可以构造一个复合请求,例如(并获取每个文件句柄):

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 operation 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 filehandle 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_ACCESS NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADXDR 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 BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADNAME NFS4ERR\u BADXDR NFS4ERR\u过期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链路错误

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_NOENT error must be returned. Therefore, NFS4ERR_NOENT will be returned by the server when the current filehandle is at the root or top of the server's file tree.

假定当前文件句柄引用常规目录或命名属性目录。LOOKUPP将其父目录的文件句柄指定为当前文件句柄。如果没有父目录,则必须返回NFS4ERR\u NOENT错误。因此,当当前文件句柄位于服务器文件树的根或顶部时,服务器将返回NFS4ERR_NOENT。

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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u坏句柄NFS4ERR\u过期NFS4ERR\u IO NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u NOTDIR NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时

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 "foobar" NVERIFY attrbits attrs READ 0 32767

PUTFH(公共)查找“foobar”n验证属性位属性读取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 filesystem object, the error NFS4ERR_ATTRNOTSUPP is returned to the client.

如果在NVERIFY操作中指定了推荐的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_ATTRNOTSUPP返回给客户端。

When the attribute rdattr_error or any write-only attribute (e.g., time_modify_set) is specified, the error NFS4ERR_INVAL is returned to the client.

当指定属性rdattr_error或任何只写属性(例如,time_modify_set)时,错误NFS4ERR_INVAL将返回给客户端。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_RESOURCE NFS4ERR_SAME NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u属性支持NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO 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), seqid, share_access, share_deny, owner, openhow, claim -> (cfh), stateid, cinfo, rflags, open_confirm, attrset delegation

(cfh)、seqid、共享访问、共享拒绝、所有者、openhow、索赔->(cfh)、stateid、cinfo、rflags、开放确认、属性集委派

ARGUMENT

论点

     struct OPEN4args {
             seqid4          seqid;
             uint32_t        share_access;
             uint32_t        share_deny;
             open_owner4     owner;
             openflag4       openhow;
             open_claim4     claim;
     };
        
     struct OPEN4args {
             seqid4          seqid;
             uint32_t        share_access;
             uint32_t        share_deny;
             open_owner4     owner;
             openflag4       openhow;
             open_claim4     claim;
     };
        
     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 {
             stateid4        delegate_stateid;
             component4      file;
     };
        
     struct open_claim_delegate_cur4 {
             stateid4        delegate_stateid;
             component4      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 */
              component4     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 */
              component4     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 */
              open_delegation_type4   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 */
              open_delegation_type4   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 */
              component4     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 */
              component4     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
        
   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 */
   };
        
                                              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_CONFIRM      = 0x00000002;
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;
        
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;
        
   struct OPEN4resok {
           stateid4        stateid;        /* Stateid for open */
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           bitmap4         attrset;        /* attributes on create */
           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 */
           bitmap4         attrset;        /* attributes on create */
           open_delegation4 delegation;    /* Info on any open
                                              delegation */
   };
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
        
           void;
   };
        
           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参数将提供创建方法的规范。客户端可以选择三种创建方法:未选中、保护或独占。

If the current filehandle is a named attribute directory, OPEN will then create or open a named attribute file. Note that exclusive create of a named attribute is not supported. If the createmode is EXCLUSIVE4 and the current filehandle is a named attribute directory, the server will return EINVAL.

如果当前文件句柄是命名属性目录,则OPEN将创建或打开命名属性文件。请注意,不支持以独占方式创建命名属性。如果createmode是EXCLUSIVE4且当前文件句柄是命名属性目录,则服务器将返回EINVAL。

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 include any writable attribute valid for regular files. When an UNCHECKED create encounters an existing file, the attributes specified by createattrs are not used, except that when an 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. For

未选中表示如果该名称的文件不存在并且遇到该名称的现有常规文件不是错误,则应创建该文件。对于这种类型的创建,createattrs指定文件的初始属性集。属性集可以包括对常规文件有效的任何可写属性。当未选中的创建遇到现有文件时,将不使用createattrs指定的属性,除非指定了零大小,否则现有文件将被截断。如果指定了GUARDED,服务器将在执行创建之前按名称检查是否存在重复对象。如果存在重复项,则返回NFS4ERR_EXIST错误作为状态。如果对象不存在,则按照未选中的说明执行请求。对于

each of these cases (UNCHECKED and GUARDED) where the operation is successful, the server will return to the client an attribute mask signifying which attributes were successfully set for the object.

在这些情况下(未选中和受保护),如果操作成功,服务器将向客户端返回一个属性掩码,表示已成功为对象设置了哪些属性。

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. If the server uses an attribute to store the exclusive create verifier, it will signify which attribute by setting the appropriate bit in the attribute mask that is returned in the results.

独占指定服务器遵循独占创建语义,使用验证器确保以独占方式创建目标。服务器应按名称检查是否存在重复的对象。如果对象不存在,服务器将创建该对象并将验证器与该对象一起存储。如果对象确实存在并且存储的验证器与客户端提供的验证器匹配,则服务器将现有对象用作新创建的对象。如果存储的验证器不匹配,则返回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 operation provides for Windows share reservation capability with the use of the share_access and share_deny fields of the OPEN arguments. The client specifies at OPEN the required share_access and share_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_SHARE_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'.

“打开”操作使用打开参数的“共享访问”和“共享拒绝”字段提供Windows共享保留功能。客户端在打开时指定所需的共享访问和共享拒绝模式。对于不直接支持共享(即UNIX)的客户端,预期的拒绝值为deny_NONE。如果存在与打开请求冲突的现有共享保留,服务器将返回错误NFS4ERR_SHARE_DENIED。对于完整的共享请求,客户端必须为OPEN参数提供owner和seqid字段的值。有关共享语义的更多讨论,请参阅“共享保留”部分。

In the case that the client is recovering state from a server failure, the claim field of the OPEN argument is used to signify that the request is meant to reclaim state previously held.

在客户机正在从服务器故障恢复状态的情况下,OPEN参数的claim字段用于表示该请求旨在恢复先前持有的状态。

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 filehandles; 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. The server MAY support CLAIM_DELEGATE_PREV. If it does support CLAIM_DELEGATE_PREV, SETCLIENTID_CONFIRM MUST NOT remove the client's delegation state, and the server MUST support the DELEGPURGE operation.

CLAIM_DELEGATE_PREV客户端正在声明授予以前的客户端实例的委托;在客户端重新启动后使用。服务器可能支持CLAIM_DELEGATE_PREV。如果它确实支持CLAIM_DELEGATE_PREV,则SETCLIENTID_CONFIRM不能删除客户端的委派状态,并且服务器必须支持DELEGPURGE操作。

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.

成功打开所返回的RFLAG允许服务器返回控制如何处理打开的文件的信息。

OPEN4_RESULT_CONFIRM indicates that the client MUST execute an OPEN_CONFIRM operation before using the open file. OPEN4_RESULT_LOCKTYPE_POSIX indicates the server's file locking behavior supports the complete set of Posix locking techniques. From this the client can choose to manage file locking state in a way to handle a mis-match of file locking management.

OPEN4_RESULT_CONFIRM表示客户端在使用打开的文件之前必须执行打开确认操作。OPEN4_RESULT_LOCKTYPE_POSIX表示服务器的文件锁定行为支持整套POSIX锁定技术。从中,客户机可以选择以处理文件锁定管理不匹配的方式来管理文件锁定状态。

If the component is of zero length, NFS4ERR_INVAL will be returned. The component is also subject to the normal UTF-8, character support, and name checks. See the section "UTF-8 Related Errors" for further discussion.

如果组件长度为零,将返回NFS4ERR_INVAL。该组件还需要进行常规UTF-8、字符支持和名称检查。有关进一步的讨论,请参阅“UTF-8相关错误”一节。

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 OPENs were completed. When such an OPEN is done, checking of share reservations for the new OPEN proceeds normally, with no exception for the existing OPEN held by the same lockowner.

当打开完成并且指定的lockowner已经打开了结果文件句柄时,结果是将新共享和拒绝状态与现有状态一起“或”。在这种情况下,即使多个打开已完成,也只需完成一次关闭。当这样的公开完成后,对新公开的股份保留的检查将正常进行,同一个锁所有人持有的现有公开的情况也不例外。

If the underlying filesystem at the server is only accessible in a read-only mode and the OPEN request has specified ACCESS_WRITE or ACCESS_BOTH, the server will return NFS4ERR_ROFS to indicate a read-only filesystem.

如果服务器上的底层文件系统只能以只读模式访问,并且OPEN请求同时指定了ACCESS\u WRITE或ACCESS\u,则服务器将返回NFS4ERR\u ROFS以指示只读文件系统。

As with the CREATE operation, the server MUST derive the owner, owner ACE, group, or group ACE if any of the four attributes are required and supported by the server's filesystem. For an OPEN with the EXCLUSIVE4 createmode, the server has no choice, since such OPEN calls do not include the createattrs field. Conversely, if createattrs is specified, and includes owner or group (or corresponding ACEs) that the principal in the RPC call's credentials does not have authorization to create files for, then the server may return NFS4ERR_PERM.

与创建操作一样,如果服务器的文件系统需要并支持这四个属性中的任何一个,则服务器必须派生所有者、所有者ACE、组或组ACE。对于具有EXCLUSIVE4 createmode的OPEN,服务器没有选择,因为此类OPEN调用不包括createattrs字段。相反,如果指定了createattrs,并且包含RPC调用凭据中的主体无权为其创建文件的所有者或组(或相应的ACE),则服务器可能会返回NFS4ERR_PERM。

In the case of a OPEN which specifies a size of zero (e.g., truncation) and the file has named attributes, the named attributes are left as is. They are not removed.

对于指定大小为零(例如截断)且文件具有命名属性的打开文件,命名属性保持原样。它们没有被移除。

IMPLEMENTATION

实施

The OPEN operation 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

打开操作包含对独占创建的支持。该机制类似于NFS版本3[RFC1813]中的支持。与NFS版本3一样,此机制提供可靠的独占创建。当how参数为Exclusive时,将调用Exclusive create。在这种情况下,客户机提供了一个可以合理预期是唯一的验证器。客户机的组合

identifier, perhaps the client network address, and a unique number generated by the client, perhaps the RPC transaction identifier, may be appropriate.

标识符(可能是客户端网络地址)和由客户端生成的唯一编号(可能是RPC事务标识符)可能是合适的。

If the object does not exist, the server creates the object and stores the verifier in stable storage. For filesystems 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 filesystem 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, 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以设置正确的对象属性。在这样做之前,它不应该依赖任何对象属性,因为服务器实现可能需要重载对象元数据来存储验证器。后续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 operation can fail with

使用GUARDED属性并不能提供精确的一次性语义。特别是,如果应答丢失,并且服务器没有检测到请求的重新传输,则操作可能会失败

NFS4ERR_EXIST, even though the create was performed successfully. The client would use this behavior in the case that the application has not requested an exclusive create but has asked to have the file truncated when the file is opened. In the case of the client timing out and retransmitting the create request, the client can use GUARDED to prevent against a sequence like: create, write, create (retransmitted) from occurring.

NFS4ERR_存在,即使创建已成功执行。如果应用程序未请求独占创建,但在打开文件时请求截断文件,则客户端将使用此行为。在客户机超时并重新传输创建请求的情况下,客户机可以使用GUARDED来防止诸如:创建、写入、创建(重新传输)之类的序列发生。

For SHARE reservations, the client must specify a value for share_access that is one of READ, WRITE, or BOTH. For share_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.

对于共享保留,客户端必须为共享访问指定一个值,该值为读取、写入或两者兼有。对于share_deny,客户端必须指定NONE、READ、WRITE或两者中的一个。如果客户端无法执行此操作,服务器必须返回NFS4ERR_INVAL。

Based on the share_access value (READ, WRITE, or BOTH) the client should check that the requester has the proper access rights to perform the specified operation. This would generally be the results of applying the ACL access rules to the file for the current requester. However, just as with the ACCESS operation, the client should not attempt to second-guess the server's decisions, as access rights may change and may be subject to server administrative controls outside the ACL framework. If the requester is not authorized to READ or WRITE (depending on the share_access value), the server must return NFS4ERR_ACCESS. Note that since the NFS version 4 protocol does not impose any requirement that READs and WRITEs issued for an open file have the same credentials as the OPEN itself, the server still must do appropriate access checking on the READs and WRITEs themselves.

根据share_访问值(读、写或两者),客户端应检查请求者是否具有执行指定操作的适当访问权限。这通常是对当前请求者的文件应用ACL访问规则的结果。但是,与访问操作一样,客户端不应试图猜测服务器的决定,因为访问权限可能会更改,并且可能受ACL框架之外的服务器管理控制。如果请求者未被授权读取或写入(取决于share_访问值),服务器必须返回NFS4ERR_访问。请注意,由于NFS版本4协议没有强制要求为打开的文件发出的读写操作与打开的文件本身具有相同的凭据,因此服务器仍然必须对读写操作本身进行适当的访问检查。

If the component provided to OPEN is a symbolic link, the error NFS4ERR_SYMLINK will be returned to the client. If the current filehandle is not a directory, the error NFS4ERR_NOTDIR will be returned.

如果提供给OPEN的组件是符号链接,则错误NFS4ERR_SYMLINK将返回给客户端。如果当前文件句柄不是目录,将返回错误NFS4ERR_NOTDIR。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADOWNER NFS4ERR_BAD_SEQID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_EXPIRED

NFS4ERR\u访问NFS4ERR\u管理撤销NFS4ERR\u属性支持NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADNAME NFS4ERR\u BADOWNER NFS4ERR\u BAD \u序列NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u DQUOT NFS4ERR\u存在NFS4ERR\u过期

NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_IO NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTSUPP NFS4ERR_NO_GRACE NFS4ERR_PERM NFS4ERR_RECLAIM_BAD NFS4ERR_RECLAIM_CONFLICT NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_SHARE_DENIED NFS4ERR_STALE NFS4ERR_STALE_CLIENTID NFS4ERR_SYMLINK NFS4ERR_WRONGSEC

NFS4ERR\u Fhu过期的NFS4ERR\u GRACE NFS4ERR\u IO NFS4ERR\u无效的NFS4ERR\u ISDIR NFS4ERR\u租赁的NFS4ERR\u移动的NFS4ERR\u名称工具的NFS4ERR\u Nont NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOSPC NFS4ERR\u NOTDIR NFS4ERR\u NOTSUPP NFS4ERR\u NotS4Err\u PERM NFS4ERR\u回收错误的NFS4ERR\u资源NFS4ERR\u共享被拒绝NFS4ERR\u过时NFS4ERR\u过时客户端ID NFS4ERR\u符号链接NFS4ERR\u错误秒

14.2.17. Operation 19: OPENATTR - Open Named Attribute Directory
14.2.17. 操作19:OPENATTR-打开命名属性目录

SYNOPSIS

提要

(cfh) createdir -> (cfh)

(cfh)createdir->(cfh)

ARGUMENT

论点

     struct OPENATTR4args {
             /* CURRENT_FH: object */
             bool    createdir;
     };
        
     struct OPENATTR4args {
             /* CURRENT_FH: object */
             bool    createdir;
     };
        

RESULT

后果

     struct OPENATTR4res {
             /* CURRENT_FH: named attr directory*/
             nfsstat4        status;
     };
        
     struct OPENATTR4res {
             /* CURRENT_FH: named 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 operations can be used to obtain filehandles for the various named attributes associated with the original filesystem object. Filehandles returned within the named attribute directory will have a type of NF4NAMEDATTR.

OPENATTR操作用于获取与当前文件句柄关联的命名属性目录的文件句柄。OPENATTR的结果将是NF4ATTRDIR类型对象的文件句柄。从这个文件句柄中,可以使用READDIR和LOOKUP操作来获取与原始文件系统对象关联的各种命名属性的文件句柄。在命名属性目录中返回的文件句柄的类型为NF4NAMEDATTR。

The createdir argument allows the client to signify if a named attribute directory should be created as a result of the OPENATTR operation. Some clients may use the OPENATTR operation with a value of FALSE for createdir to determine if any named attributes exist for the object. If none exist, then NFS4ERR_NOENT will be returned. If createdir has a value of TRUE and no named attribute directory exists, one is created. The creation of a named attribute directory assumes that the server has implemented named attribute support in this fashion and is not required to do so by this definition.

createdir参数允许客户端指示是否应作为OPENATTR操作的结果创建命名属性目录。某些客户端可能会使用OPENATTR操作(createdir的值为FALSE)来确定对象是否存在任何命名属性。如果不存在,则将返回NFS4ERR\u NOENT。如果createdir的值为TRUE,并且不存在命名属性目录,则会创建一个。命名属性目录的创建假定服务器以这种方式实现了命名属性支持,并且此定义不要求这样做。

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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_FHEXPIRED NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u备份句柄NFS4ERR\u备份NFS4ERR\u延迟NFS4ERR\u引用NFS4ERR\u过期NFS4ERR\u IO NFS4ERR\u移动的NFS4ERR\u无NFS4ERR\u无文件句柄NFS4ERR\u无PC NFS4ERR\u不支持NFS4ERR\u资源NFS4ERR

14.2.18. Operation 20: OPEN_CONFIRM - Confirm Open
14.2.18. 操作20:打开\确认-确认打开

SYNOPSIS

提要

(cfh), seqid, stateid-> stateid

(cfh),seqid,stateid->stateid

ARGUMENT

论点

     struct OPEN_CONFIRM4args {
             /* CURRENT_FH: opened file */
             stateid4        open_stateid;
             seqid4          seqid;
     };
        
     struct OPEN_CONFIRM4args {
             /* CURRENT_FH: opened file */
             stateid4        open_stateid;
             seqid4          seqid;
     };
        

RESULT

后果

     struct OPEN_CONFIRM4resok {
             stateid4        open_stateid;
     };
        
     struct OPEN_CONFIRM4resok {
             stateid4        open_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 open_owner is used by a client. The stateid returned from the OPEN operation is used as the argument for this operation along with the next sequence id for the open_owner. 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.

此操作用于确认客户端第一次使用OpenU所有者时序列id的使用情况。从OPEN操作返回的stateid与OPEN_所有者的下一个序列id一起用作此操作的参数。传递给OPEN_确认的序列id必须比传递给OPEN操作(从中获得OPEN_确认值)的序列id大1(一)。如果服务器收到与原始打开相关的意外序列id,则服务器假定客户端不会确认原始打开,并且与原始打开相关的所有状态都由服务器释放。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

A given client might generate many open_owner4 data structures for a given clientid. The client will periodically either dispose of its open_owner4s or stop using them for indefinite periods of time. The latter situation is why the NFS version 4 protocol does not have an

给定的客户端可能会为给定的clientid生成许多open_owner4数据结构。客户将定期处置其open_Owner4或无限期停止使用。后一种情况是NFS版本4协议没有

explicit operation to exit an open_owner4: 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 open_owner4s 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 open_owner4s 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 open_owner4 data structures.

退出开放所有者的显式操作4:这种操作在这种情况下没有用处。相反,为了避免无限制的内存使用,服务器需要实施一种策略,以处理没有任何文件当前锁定、打开或委派状态且最近未使用过的open_Owner4。用于确定何时处置open_owner4s的时间段是一种实现选择。时间段当然应该不小于租赁时间加上服务器希望在租赁时间之后实施的任何宽限期。OPEN_CONFIRM操作允许服务器安全地处置未使用的OPEN_owner4数据结构。

In the case that a client issues an OPEN operation and the server no longer has a record of the open_owner4, the server needs to ensure that this is a new OPEN and not a replay or retransmission.

如果客户端发出开放操作,而服务器不再具有开放所有者的记录4,服务器需要确保这是一个新的开放操作,而不是重播或重新传输。

Servers must not require confirmation on OPENs that grant delegations or are doing reclaim operations. See section "Use of Open Confirmation" for details. The server can easily avoid this by noting whether it has disposed of one open_owner4 for the given clientid. If the server does not support delegation, it might simply maintain a single bit that notes whether any open_owner4 (for any client) has been disposed of.

服务器不得要求对授予委派或正在执行回收操作的打开进行确认。有关详细信息,请参阅“公开确认的使用”一节。服务器可以通过注意是否已为给定的clientid处理了一个open_owner4来轻松避免这种情况。如果服务器不支持委托,它可能只需维护一个位,记录是否已处理任何open_owner4(对于任何客户端)。

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 stateid within the lease period. In this case, the OPEN state on the server goes to confirmed, and the open_owner4 on the server is fully established.

服务器必须保持未确认的打开状态,直到发生三个事件之一。首先,客户机在租赁期内发送具有适当序列id和stateid的OPEN_CONFIRM请求。在这种情况下,服务器上的打开状态变为已确认,服务器上的打开所有者4已完全建立。

Second, the client sends another OPEN request with a sequence id that is incorrect for the open_owner4 (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.

其次,客户端发送另一个OPEN请求,其序列id对于OPEN_owner4不正确(顺序错误)。在这种情况下,服务器假定第二个打开请求有效,第一个是重播。服务器取消第一个打开请求的打开状态,为第二个打开请求建立未确认的打开状态,并响应第二个打开请求,指示需要打开确认。然后这个过程会重复。虽然客户机上存在拒绝服务攻击的可能性,但如果客户机和服务器需要使用基于Kerberos V5、LIPKEY或其他使用加密技术的安全模式,则可以减轻这种攻击。

What if the server is in the unconfirmed OPEN state for a given open_owner4, and it receives an operation on the open_owner4 that has a stateid but the operation is not OPEN, or it is OPEN_CONFIRM but with the wrong stateid? Then, even if the seqid is correct, the

如果服务器对于给定的OPEN_owner4处于未确认的OPEN状态,并且它在OPEN_owner4上接收到具有stateid但操作未打开的操作,或者服务器处于OPEN_CONFIRM状态但具有错误的stateid,该怎么办?然后,即使seqid是正确的

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.

服务器返回NFS4ERR_BAD_STATEID,因为服务器假定操作是重播:如果服务器没有建立的打开状态,那么就没有办法,例如,锁定操作可能是有效的。

Third, neither of the two aforementioned events occur for the open_owner4 within the lease period. In this case, the OPEN state is canceled and disposal of the open_owner4 can occur.

第三,上述两个事件均未在租赁期内发生。在这种情况下,打开状态被取消,并且可以处理打开的所有者4。

ERRORS

错误

NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u ADMIN\u撤销NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u Sequid NFS4ERR\u BADXDR NFS4ERR\u过期NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u ISDIR NFS4ERR\u移动的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        open_stateid;
             seqid4          seqid;
             uint32_t        share_access;
             uint32_t        share_deny;
     };
        
     struct OPEN_DOWNGRADE4args {
             /* CURRENT_FH: opened file */
             stateid4        open_stateid;
             seqid4          seqid;
             uint32_t        share_access;
             uint32_t        share_deny;
     };
        

RESULT

后果

     struct OPEN_DOWNGRADE4resok {
             stateid4        open_stateid;
     };
        
     struct OPEN_DOWNGRADE4resok {
             stateid4        open_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;
     };
        

DESCRIPTION

描述

This operation is used to adjust the share_access and share_deny bits for a given open. This is necessary when a given openowner opens the same file multiple times with different share_access and share_deny flags. In this situation, a close of one of the opens may change the appropriate share_access and share_deny flags to remove bits associated with opens no longer in effect.

此操作用于调整给定open的share_访问和share_拒绝位。当给定的openowner使用不同的share\u access和share\u deny标志多次打开同一文件时,这是必要的。在这种情况下,关闭一个打开可能会更改相应的share_access和share_deny标志,以删除与不再有效的打开相关的位。

The share_access and share_deny bits specified in this operation replace the current ones for the specified open file. The share_access and share_deny bits specified must be exactly equal to the union of the share_access and share_deny bits specified for some subset of the OPENs in effect for current openowner on the current file. If that constraint is not respected, the error NFS4ERR_INVAL should be returned. Since share_access and share_deny bits are subsets of those already granted, it is not possible for this request to be denied because of conflicting share reservations.

此操作中指定的共享访问和共享拒绝位将替换指定打开文件的当前位。指定的share_access和share_deny位必须完全等于为当前文件上当前openowner有效打开的某些子集指定的share_access和share_deny位的并集。如果不遵守该约束,则应返回错误NFS4ERR_INVAL。由于share_access和share_deny位是已授予的这些位的子集,因此不可能拒绝此请求,因为存在冲突的共享保留。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

ERRORS

错误

NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_SEQID NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_OLD_STATEID NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u ADMIN\u撤销NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u Sequid NFS4ERR\u BADXDR NFS4ERR\u过期NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u移动的NFS4ERR\u NOFILEHANDLE NFS4ERR\u旧的NFS4ERR\u STATEID 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 {
             nfs_fh4         object;
     };
        
     struct PUTFH4args {
             nfs_fh4         object;
     };
        

RESULT

后果

     struct PUTFH4res {
             /* CURRENT_FH: */
             nfsstat4        status;
     };
        
     struct PUTFH4res {
             /* CURRENT_FH: */
             nfsstat4        status;
     };
        

DESCRIPTION

描述

Replaces the current filehandle with the filehandle provided as an argument.

将当前文件句柄替换为作为参数提供的文件句柄。

If the security mechanism used by the requester does not meet the requirements of the filehandle provided to this operation, the server MUST return NFS4ERR_WRONGSEC.

如果请求者使用的安全机制不符合为此操作提供的filehandle的要求,则服务器必须返回NFS4ERR_-ErrorSec。

IMPLEMENTATION

实施

Commonly used as the first operator in an NFS request to set the context for following operations.

通常用作NFS请求中的第一个运算符,用于设置以下操作的上下文。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC

NFS4ERR\u BADHANDLE NFS4ERR\u BADXDR 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”文件句柄,后者可能与服务器上的其他目录相关联。

The public filehandle represents the concepts embodied in [RFC2054], [RFC2055], [RFC2224]. The intent for NFS version 4 is that the public filehandle (represented by the PUTPUBFH operation) be used as a method of providing WebNFS server compatibility with NFS versions 2 and 3.

公共文件句柄表示[RFC2054]、[RFC2055]、[RFC2224]中包含的概念。NFS版本4的目的是将公共文件句柄(由PUTPUBFH操作表示)用作提供与NFS版本2和3的WebNFS服务器兼容性的方法。

The public filehandle and the root filehandle (represented by the PUTROOTFH operation) should be equivalent. If the public and root filehandles are not equivalent, then the public filehandle MUST be a descendant of the root filehandle.

公共文件句柄和根文件句柄(由PUTROOTFH操作表示)应该是等效的。如果公共文件句柄和根文件句柄不相等,则公共文件句柄必须是根文件句柄的后代。

IMPLEMENTATION

实施

Used as the first operator in an NFS request to set the context for following operations.

用作NFS请求中的第一个运算符,用于设置以下操作的上下文。

With the NFS version 2 and 3 public filehandle, the client is able to specify whether the path name provided in the LOOKUP should be evaluated as either an absolute path relative to the server's root or relative to the public filehandle. [RFC2224] contains further discussion of the functionality. With NFS version 4, that type of specification is not directly available in the LOOKUP operation. The reason for this is because the component separators needed to specify absolute vs. relative are not allowed in NFS version 4. Therefore,

使用NFS版本2和3公共文件句柄,客户机可以指定是将查找中提供的路径名计算为相对于服务器根的绝对路径还是相对于公共文件句柄的绝对路径。[RFC2224]包含对功能的进一步讨论。对于NFS版本4,该类型的规范在查找操作中不直接可用。这是因为在NFS版本4中不允许使用指定绝对与相对所需的组件分隔符。因此

the client is responsible for constructing its request such that the use of either PUTROOTFH or PUTPUBFH are used to signify absolute or relative evaluation of an NFS URL respectively.

客户端负责构造其请求,以便使用PUTROOTFH或PUTPUBFH分别表示对NFS URL的绝对或相对评估。

Note that there are warnings mentioned in [RFC2224] with respect to the use of absolute evaluation and the restrictions the server may place on that evaluation with respect to how much of its namespace has been made available. These same warnings apply to NFS version 4. It is likely, therefore that because of server implementation details, an NFS version 3 absolute public filehandle lookup may behave differently than an NFS version 4 absolute resolution.

请注意,[RFC2224]中提到了有关绝对求值的使用的警告,以及服务器可能对该求值施加的限制,这些限制涉及其名称空间的可用性。这些警告同样适用于NFS版本4。因此,由于服务器实现的详细信息,NFS版本3绝对公共文件句柄查找可能与NFS版本4绝对解析的行为不同。

There is a form of security negotiation as described in [RFC2755] that uses the public filehandle a method of employing SNEGO. This method is not available with NFS version 4 as filehandles are not overloaded with special meaning and therefore do not provide the same framework as NFS versions 2 and 3. Clients should therefore use the security negotiation mechanisms described in this RFC.

[RFC2755]中描述了一种形式的安全协商,它使用公共文件句柄作为使用SNEGO的方法。此方法在NFS版本4中不可用,因为文件句柄没有特殊意义的重载,因此不提供与NFS版本2和3相同的框架。因此,客户端应使用本RFC中描述的安全协商机制。

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), stateid, offset, count -> 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. The stateid is used by the server to verify that the associated share reservation and any record locks are still valid and to update lease timeouts for the client.

读取请求的stateid值表示从以前的记录锁定或共享保留请求返回的值。服务器使用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。

If the current filehandle is not a regular file, an error will be returned to the client. In the case the current filehandle represents a directory, NFS4ERR_ISDIR is return; otherwise, NFS4ERR_INVAL is returned.

如果当前文件句柄不是常规文件,则会向客户端返回错误。如果当前文件句柄表示目录,则返回NFS4ERR_ISDIR;否则,将返回NFS4ERR_INVAL。

For a READ with a stateid value of all bits 0, the server MAY allow the READ to be serviced subject to mandatory file locks or the current share deny modes for the file. For a READ with a stateid value of all bits 1, the server MAY allow READ operations to bypass locking checks at the server.

对于stateid值为所有位0的读取,服务器可能允许在强制文件锁定或文件当前共享拒绝模式的情况下为读取提供服务。对于stateid值为所有位1的读取,服务器可能允许读取操作绕过服务器上的锁定检查。

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 is 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 mandatory file locking is on for the file, and if the region corresponding to the data to be read from file is write locked by an owner not associated the stateid, the server will return the NFS4ERR_LOCKED error. The client should try to get the appropriate read record lock via the LOCK operation before re-attempting the READ. When the READ completes, the client should release the record lock via LOCKU.

如果文件的强制文件锁定处于启用状态,并且与要从文件读取的数据对应的区域由与stateid不关联的所有者进行写锁定,则服务器将返回NFS4ERR_locked错误。在重新尝试读取之前,客户端应尝试通过锁定操作获取适当的读取记录锁定。读取完成后,客户端应通过LOCKU释放记录锁。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_EXPIRED NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_IO NFS4ERR_INVAL NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCKED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NXIO NFS4ERR_OLD_STATEID NFS4ERR_OPENMODE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词词U服务器故障NFS4ERR_STALE NFS4ERR_STALE_STATEID

14.2.24. Operation 26: READDIR - Read Directory
14.2.24. 操作26:READDIR-读取目录

SYNOPSIS (cfh), cookie, cookieverf, dircount, maxcount, attr_request -> cookieverf { cookie, name, attrs }

概要(cfh),cookie,cookieverf,dircount,maxcount,attr_请求->cookieverf{cookie,name,attrs}

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) {
      case NFS4_OK:
              READDIR4resok  resok4;
      default:
              void;
     };
        
     union READDIR4res switch (nfsstat4 status) {
      case NFS4_OK:
              READDIR4resok  resok4;
      default:
              void;
     };
        

DESCRIPTION

描述

The READDIR operation retrieves a variable number of entries from a filesystem 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. If the server determines that the cookieverf is no longer valid for the directory, the error NFS4ERR_NOT_SAME must be returned.

当cookie值为0(零)(第一次读取目录)时,cookieverf值应设置为0(零)。在后续请求中,它应该是服务器返回的cookieverf。cookieverf必须与获取cookie的READDIR返回的值匹配。如果服务器确定cookieverf对目录不再有效,则必须返回错误NFS4ERR_NOT_SAME。

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.

参数的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 within the READDIR4resok structure 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_TOOSMALL will be returned to the client.

参数的maxcount值是结果的最大字节数。此最大大小表示READDIR4resok结构中返回的所有数据,并包括XDR开销。服务器可能返回较少的数据。如果服务器无法返回maxcount限制内的单个目录项,则会将错误NFS4ERR_Toosall返回给客户端。

Finally, attr_request represents the list of attributes to be returned for each directory entry supplied by the server.

最后,attr_request表示要为服务器提供的每个目录项返回的属性列表。

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. The "eof" flag has a value of TRUE if there are no more entries in the directory.

成功返回后,服务器的响应将提供目录项列表。每个条目都包含目录条目的名称、该条目的cookie值以及请求的相关属性。如果目录中没有更多条目,“eof”标志的值为TRUE。

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

cookie值仅对服务器有意义,并用作目录项的“书签”。如前所述,客户端将此cookie用于后续的READDIR操作,以便它可以继续读取目录。cookie在概念上类似于

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值不应该改变,因为客户端可能正在缓存这些值。

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 filesystem 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 be returned.

对于READDIR参数,不应使用cookie值1和2,对于READDIR结果,不应返回cookie值0、1和2。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

The server's filesystem 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 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.

服务器的文件系统目录表示形式可能会有很大差异。客户端的编程接口也可能以无法很好地转换为NFS协议的方式绑定到本地操作环境。因此,提供了dircount和maxcount字段的使用,以允许客户端向服务器提供指导。如果客户机在READDIR过程中对属性收集非常积极,那么服务器就知道如何限制编码响应。dircount字段仅根据目录项的名称提供有关项数的提示。因为这是一个提示,所以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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_BAD_COOKIE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_TOOSMALL

NFS4ERR\u访问NFS4ERR\u BADHANDLE NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动的NFS4ERR\u NOFILEHANDLE NFS4ERR\u NOTDIR NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\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_ACCESS NFS4ERR_BADHANDLE NFS4ERR_DELAY

NFS4ERR_访问NFS4ERR_错误句柄NFS4ERR_延迟

NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOTSUPP NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u Fhu过期NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u ISDIR 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 filesystem 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 and REMOVE for non-directory removal. This allowed clients to skip checking the file type when being passed a non-directory delete system call (e.g., unlink() in POSIX) to remove a directory, as well as the converse (e.g., a rmdir() on a non-directory) because they knew the server would check the file type. NFS version 4 REMOVE can be used to delete any directory entry independent of its file type. The implementor of an NFS version 4 client's entry points from the unlink() and rmdir() system calls should first check the file type against the types the system call is allowed to remove before issuing a REMOVE. Alternatively, the implementor can produce a COMPOUND call that includes a LOOKUP/VERIFY sequence to verify the file type before a REMOVE operation in the same COMPOUND call.

NFS版本2和3要求使用不同的运算符RMDIR进行目录删除,而REMOVE进行非目录删除。这允许客户端在传递非目录删除系统调用(如POSIX中的unlink())以删除目录时跳过检查文件类型,也允许客户端在传递相反的调用(如非目录中的rmdir())时跳过检查文件类型,因为他们知道服务器将检查文件类型。NFS版本4 REMOVE可用于删除任何与其文件类型无关的目录项。NFS版本4客户端的unlink()和rmdir()系统调用入口点的实现者应首先根据系统调用允许删除的类型检查文件类型,然后再发出删除命令。或者,实现者可以生成包含查找/验证序列的复合调用,以在同一复合调用中的删除操作之前验证文件类型。

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 filehandle. 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删除文件后需要能够继续访问该文件,则客户机应采取步骤确保该文件仍然可以访问。通常使用的机制是将文件从旧名称重命名为新的隐藏名称。

If the server finds that the file is still open when the REMOVE arrives:

如果服务器在删除到达时发现文件仍处于打开状态:

o The server SHOULD NOT delete the file's directory entry if the file was opened with OPEN4_SHARE_DENY_WRITE or OPEN4_SHARE_DENY_BOTH.

o 如果文件是用OPEN4_SHARE_DENY_WRITE或OPEN4_SHARE_DENY_WRITE打开的,则服务器不应删除文件的目录项。

o If the file was not opened with OPEN4_SHARE_DENY_WRITE or OPEN4_SHARE_DENY_BOTH, the server SHOULD delete the file's directory entry. However, until last CLOSE of the file, the server MAY continue to allow access to the file via its filehandle.

o 如果文件不是用OPEN4_SHARE_DENY_WRITE或OPEN4_SHARE_DENY_两者打开的,服务器应该删除文件的目录条目。但是,在文件最后关闭之前,服务器可能会继续允许通过其文件句柄访问文件。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_FILE_OPEN NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_NOTEMPTY NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADNAME NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u文件打开NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动的NFS4ERR\u名称工具NFS4ERR\u无NFS4ERR\u无文件句柄NFS4ERR\u NOTDIR NFS4ERR\u NOTDIR NFS4ERR\u资源失效NFS4ERR\u

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 filesystem 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 removed before the rename occurs (See the IMPLEMENTATION subsection of the section "Operation 28: REMOVE - Remove Filesystem Object" for client and server actions whenever a target is removed). If they are not compatible or if the target is a directory but not empty, the server will return the error, NFS4ERR_EXIST.

如果目标目录已包含名为newname的条目,则源对象必须与目标兼容:要么都是非目录,要么都是目录,目标必须为空。如果兼容,则在重命名之前删除现有目标(请参阅“操作28:删除-删除文件系统对象”一节的实现小节,了解删除目标时的客户端和服务器操作)。如果它们不兼容,或者如果目标是目录但不是空的,服务器将返回错误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 refers to a named attribute and the saved and current filehandles refer to different filesystem objects, the server will return NFS4ERR_XDEV just as if the saved and current filehandles represented directories on different filesystems.

如果oldname引用一个命名属性,而保存的和当前的文件句柄引用不同的文件系统对象,则服务器将返回NFS4ERR_XDEV,就像保存的和当前的文件句柄表示不同文件系统上的目录一样。

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 filesystem on the server" means that the fsid fields in the attributes for the directories are the same. If they reside on different filesystems, the error, NFS4ERR_XDEV, is returned.

重命名操作必须是客户端的原子操作。语句“源目录和目标目录必须位于服务器上的同一文件系统”表示目录属性中的fsid字段相同。如果它们驻留在不同的文件系统上,则返回错误NFS4ERR_XDEV。

Based on the value of the fh_expire_type attribute for the object, the filehandle may or may not expire on a RENAME. However, server implementors are strongly encouraged to attempt to keep filehandles from expiring in this fashion.

根据对象的fh_expire_type属性的值,文件句柄可能会在重命名时过期,也可能不会过期。但是,强烈建议服务器实现人员尝试以这种方式防止文件句柄过期。

On some servers, the file names "." and ".." are illegal as either oldname or newname, and will result in the error NFS4ERR_BADNAME. In addition, on many servers the case of oldname or newname being an alias for the source directory will be checked for. Such servers will return the error NFS4ERR_INVAL in these cases.

在某些服务器上,文件名“.”和“.”作为oldname或newname都是非法的,将导致错误NFS4ERR_BADNAME。此外,在许多服务器上,将检查oldname或newname作为源目录别名的情况。在这些情况下,此类服务器将返回错误NFS4ERR_INVAL。

If either of the source or target filehandles are not directories, the server will return NFS4ERR_NOTDIR.

如果源或目标文件句柄中的任何一个不是目录,服务器将返回NFS4ERR\u NOTDIR。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXIST NFS4ERR_FHEXPIRED NFS4ERR_FILE_OPEN NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NOTDIR NFS4ERR_NOTEMPTY NFS4ERR_RESOURCE

NFS4ERR\u访问NFS4ERR\u备份字符NFS4ERR\u备份句柄NFS4ERR\u备份名称NFS4ERR\u备份NFS4ERR\u延迟NFS4ERR\u引用NFS4ERR\u存在NFS4ERR\u过期的NFS4ERR\u文件打开NFS4ERR\u无效NFS4ERR\u IO NFS4ERR\u移动的NFS4ERR\u名称工具使用NFS4ERR\u新的NFS4ERR\u文件句柄NFS4ERR\n不使用NFS4ERR\u noterr\u资源

NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_WRONGSEC NFS4ERR_XDEV

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

提要

clientid -> ()

clientid->()

ARGUMENT

论点

     struct RENEW4args {
             clientid4       clientid;
     };
        
     struct RENEW4args {
             clientid4       clientid;
     };
        

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 clientid provided via the SETCLIENTID operation.

续订操作由客户端用于续订其当前在服务器上持有的租约。在处理续订请求时,服务器续订与客户端关联的所有租约。关联的租约由通过SETCLIENTID操作提供的clientid确定。

IMPLEMENTATION

实施

When the client holds delegations, it needs to use RENEW to detect when the server has determined that the callback path is down. When the server has made such a determination, only the RENEW operation will renew the lease on delegations. If the server determines the callback path is down, it returns NFS4ERR_CB_PATH_DOWN. Even though it returns NFS4ERR_CB_PATH_DOWN, the server MUST renew the lease on the record locks and share reservations that the client has established on the server. If for some reason the lock and share reservation lease cannot be renewed, then the server MUST return an error other than NFS4ERR_CB_PATH_DOWN, even if the callback path is also down.

当客户端持有委托时,它需要使用“续订”来检测服务器何时确定回调路径已关闭。当服务器做出这样的决定时,只有续订操作将续订委托租约。如果服务器确定回调路径已关闭,则返回NFS4ERR\u CB\u path\u down。即使它返回NFS4ERR_CB_PATH_DOWN,服务器也必须续订记录锁的租约,并共享客户端在服务器上建立的保留。如果由于某种原因无法续订锁和共享保留租约,则服务器必须返回NFS4ERR_CB_PATH_DOWN以外的错误,即使回调路径也已关闭。

The client that issues RENEW MUST choose the principal, RPC security flavor, and if applicable, GSS-API mechanism and service via one of the following algorithms:

发出续订的客户端必须通过以下算法之一选择主体、RPC安全风格以及GSS-API机制和服务(如果适用):

o The client uses the same principal, RPC security flavor -- and if the flavor was RPCSEC_GSS -- the same mechanism and service that was used when the client id was established via SETCLIENTID_CONFIRM.

o 客户端使用相同的主体RPC security flavor——如果flavor是RPCSEC_GSS——则使用与通过SETCLIENTID_CONFIRM建立客户端id时相同的机制和服务。

o The client uses any principal, RPC security flavor mechanism and service combination that currently has an OPEN file on the server. I.e., the same principal had a successful OPEN operation, the file is still open by that principal, and the flavor, mechanism, and service of RENEW match that of the previous OPEN.

o 客户端使用当前服务器上有打开文件的任何主体、RPC安全机制和服务组合。即,同一主体进行了成功的打开操作,该主体仍在打开该文件,并且续订的风格、机制和服务与先前打开的一致。

The server MUST reject a RENEW that does not use one the aforementioned algorithms, with the error NFS4ERR_ACCESS.

服务器必须拒绝不使用上述算法的续订,错误为NFS4ERR_ACCESS。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADXDR NFS4ERR_CB_PATH_DOWN NFS4ERR_EXPIRED NFS4ERR_LEASE_MOVED NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR\u访问NFS4ERR\u管理被撤销NFS4ERR\u备份NFS4ERR\u CB\u路径被关闭NFS4ERR\u过期NFS4ERR\u租约被移动NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时客户端ID

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 the error NFS4ERR_RESTOREFH.

将当前文件句柄设置为保存的文件句柄中的值。如果没有保存的文件句柄,则返回错误NFS4ERR\u RESTOREFH。

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) RESTOREFH GETATTR attrbits (post-op dir attrs)

PUTFH(目录文件句柄)SAVEFH GETATTR attrbits(操作前目录attrs)创建optbits“foo”attrs GETATTR attrbits(文件属性)RESTOREFH GETATTR attrbits(操作后目录attrs)

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_FHEXPIRED NFS4ERR_MOVED NFS4ERR_RESOURCE NFS4ERR_RESTOREFH 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_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u坏句柄NFS4ERR\u FH过期NFS4ERR\u移动NFS4ERR\u无文件句柄NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时

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: directory */
             component4     name;
     };
        
     struct SECINFO4args {
             /* CURRENT_FH: directory */
             component4     name;
     };
        

RESULT

后果

     enum rpc_gss_svc_t {/* From RFC 2203 */
             RPC_GSS_SVC_NONE        = 1,
             RPC_GSS_SVC_INTEGRITY   = 2,
             RPC_GSS_SVC_PRIVACY     = 3
     };
        
     enum rpc_gss_svc_t {/* From RFC 2203 */
             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;
     };
        
     union secinfo4 switch (uint32_t flavor) {
      case RPCSEC_GSS:
              rpcsec_gss_info        flavor_info;
      default:
              void;
     };
        
     union secinfo4 switch (uint32_t flavor) {
      case RPCSEC_GSS:
              rpcsec_gss_info        flavor_info;
      default:
              void;
     };
        
     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 directory filehandle, file name pair. SECINFO should apply the same access methodology used for LOOKUP when evaluating the name. Therefore, if the requester does not have the appropriate access to LOOKUP the name then SECINFO must behave the same way and return NFS4ERR_ACCESS.

客户端使用SECINFO操作获取特定目录文件句柄、文件名对的有效RPC身份验证样式列表。在评估名称时,SECINFO应采用与查找相同的访问方法。因此,如果请求者没有适当的权限查找名称,则SECINFO必须以相同的方式运行,并返回NFS4ERR_访问。

The result will contain an array which represents the security mechanisms available, with an order corresponding to server's preferences, the most preferred being first in the array. The client is free to pick whatever security mechanism it both desires and supports, or to pick in the server's preference order the first one it supports. 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]).

结果将包含一个表示可用安全机制的数组,其顺序与服务器的首选项相对应,最首选的是数组中的第一个。客户机可以自由选择它希望和支持的任何安全机制,或者按照服务器的首选顺序选择它支持的第一个安全机制。数组项由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 [RFC2743]), the quality of protection (as defined in [RFC2743]) 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.

对于AUTH_NONE和AUTH_SYS,不会返回其他安全信息。对于RPCSEC_GSS的返回值,将返回一个包含机制对象id(如[RFC2743]中定义)、保护质量(如[RFC2743]中定义)和服务类型(如[RFC2203]中定义)的安全三元组。SECINFO可以返回多个具有不同安全性三重值的条目,其味道等于RPCSEC_GSS。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

If the name has a length of 0 (zero), or if name does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果名称的长度为0(零),或者名称不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

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操作。这向客户端表示服务器的安全策略与客户端当前使用的不同。此时,客户机将获得可能的安全风格列表,并选择最适合其策略的。

As mentioned, the server's security policies will determine when a client request receives NFS4ERR_WRONGSEC. The operations which may receive this error are: LINK, LOOKUP, OPEN, PUTFH, PUTPUBFH, PUTROOTFH, RESTOREFH, RENAME, and indirectly READDIR. LINK and RENAME will only receive this error if the security used for the operation is inappropriate for saved filehandle. With the exception of READDIR, these operations represent the point at which the client can instantiate a filehandle into the "current filehandle" at the server. The filehandle is either provided by the client (PUTFH, PUTPUBFH, PUTROOTFH) or generated as a result of a name to filehandle translation (LOOKUP and OPEN). RESTOREFH is different because the filehandle is a result of a previous SAVEFH. Even though the filehandle, for RESTOREFH, might have previously passed the server's inspection for a security match, the server will check it again on RESTOREFH to ensure that the security policy has not changed.

如前所述,服务器的安全策略将确定客户端请求何时接收NFS4ERR_错误。可能收到此错误的操作有:链接、查找、打开、PUTFH、PUTPUBFH、PUTROOTFH、恢复FH、重命名和间接READDIR。链接和重命名仅在用于操作的安全性不适合保存的filehandle时才会收到此错误。除了READDIR之外,这些操作表示客户端可以在服务器上将文件句柄实例化为“当前文件句柄”的点。文件句柄由客户机提供(PUTFH、PUTPUBFH、PUTROOTFH),或者由名称到文件句柄的转换(查找和打开)生成。RESTOREFH不同,因为filehandle是先前SAVEFH的结果。即使RESTOREFH的文件句柄以前可能已经通过了服务器的安全匹配检查,服务器也会在RESTOREFH上再次检查它,以确保安全策略没有更改。

If the client wants to resolve an error return of NFS4ERR_WRONGSEC, the following will occur:

如果客户端希望解决NFS4ERR_ErrorSec的错误返回,将发生以下情况:

o For LOOKUP and OPEN, the client will use SECINFO with the same current filehandle and name as provided in the original LOOKUP or OPEN to enumerate the available security triples.

o 对于查找和打开,客户端将使用与原始查找或打开中提供的具有相同当前文件句柄和名称的SECINFO枚举可用的安全三元组。

o For LINK, PUTFH, RENAME, and RESTOREFH, the client will use SECINFO and provide the parent directory filehandle and object name which corresponds to the filehandle originally provided by the PUTFH RESTOREFH, or for LINK and RENAME, the SAVEFH.

o 对于LINK、PUTFH、RENAME和RESTOREFH,客户端将使用SECINFO并提供与PUTFH RESTOREFH最初提供的filehandle相对应的父目录filehandle和对象名,对于LINK和RENAME,则提供SAVEFH。

o For PUTROOTFH and PUTPUBFH, the client will be unable to use the SECINFO operation since SECINFO requires a current filehandle and none exist for these two operations. Therefore, the client must iterate through the security triples available at the client and reattempt the PUTROOTFH or PUTPUBFH operation. In the unfortunate event none of the MANDATORY security triples are supported by the

o 对于PUTROOTFH和PUTPUBFH,客户端将无法使用SECINFO操作,因为SECINFO需要当前文件句柄,并且这两个操作都不存在。因此,客户端必须遍历客户端可用的安全三元组,并重新尝试PUTROOTFH或PUTPUBFH操作。在不幸的情况下,服务器不支持任何强制安全性三元组

client and server, the client SHOULD try using others that support integrity. Failing that, the client can try using AUTH_NONE, but because such forms lack integrity checks, this puts the client at risk. Nonetheless, the server SHOULD allow the client to use whatever security form the client requests and the server supports, since the risks of doing so are on the client.

客户端和服务器,客户端应尝试使用支持完整性的其他客户端。如果做不到这一点,客户端可以尝试使用AUTH_NONE,但由于此类表单缺少完整性检查,这会使客户端面临风险。尽管如此,服务器应该允许客户机使用客户机请求和服务器支持的任何安全形式,因为这样做的风险在客户机上。

The READDIR operation will not directly return the NFS4ERR_WRONGSEC error. However, if the READDIR request included a request for attributes, it is possible that the READDIR request's security triple does not match that of a directory entry. If this is the case and the client has requested the rdattr_error attribute, the server will return the NFS4ERR_WRONGSEC error in rdattr_error for the entry.

READDIR操作不会直接返回NFS4ERR_ErrorSec错误。但是,如果READDIR请求包含属性请求,则READDIR请求的安全性三元组可能与目录项的安全性三元组不匹配。如果是这种情况,并且客户端请求了rdattr_error属性,则服务器将在rdattr_error中为条目返回NFS4ERR_errosec错误。

See the section "Security Considerations" for a discussion on the recommendations for security flavor used by SECINFO.

请参阅“安全注意事项”一节,了解有关SECINFO使用的安全风格建议的讨论。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADNAME NFS4ERR_BADXDR NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NAMETOOLONG NFS4ERR_NOENT NFS4ERR_NOFILEHANDLE NFS4ERR_NOTDIR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADNAME NFS4ERR\u BADXDR NFS4ERR\u Fhs4Err\u过期NFS4ERR\u无效NFS4ERR\u移动NFS4ERR\u名称工具NFS4ERR\u无文件句柄NFS4ERR\u NOTDIR NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过时

14.2.32. Operation 34: SETATTR - Set Attributes
14.2.32. 操作34:SETATTR-设置属性

SYNOPSIS

提要

(cfh), stateid, attrmask, attr_vals -> attrsset

(cfh)、状态ID、属性掩码、属性值->属性集

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 filesystem object. The new attributes are specified with a bitmap and the attributes that follow the bitmap in bit order.

SETATTR操作更改文件系统对象的一个或多个属性。新属性由位图和位图后面按位顺序的属性指定。

The stateid argument for SETATTR is used to provide file locking context that is necessary for SETATTR requests that set the size attribute. Since setting the size attribute modifies the file's data, it has the same locking requirements as a corresponding WRITE. Any SETATTR that sets the size attribute is incompatible with a share reservation that specifies DENY_WRITE. The area between the old end-of-file and the new end-of-file is considered to be modified just as would have been the case had the area in question been specified as the target of WRITE, for the purpose of checking conflicts with record locks, for those cases in which a server is implementing mandatory record locking behavior. A valid stateid should always be specified. When the file size attribute is not set, the special stateid consisting of all bits zero should be passed.

SETATTR的stateid参数用于提供设置size属性的SETATTR请求所需的文件锁定上下文。由于设置size属性会修改文件的数据,因此它具有与相应写入相同的锁定要求。任何设置size属性的SETATTR都与指定DENY_WRITE的共享保留不兼容。旧文件结尾和新文件结尾之间的区域被视为已被修改,就像在服务器正在实施强制记录锁定行为的情况下,为了检查与记录锁定的冲突而将该区域指定为写入目标时一样。应始终指定有效的stateid。未设置文件大小属性时,应传递包含所有位零的特殊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. The attrsset in the response is a subset of the bitmap4 that is part of the obj_attributes in the argument.

操作成功或失败时,服务器将返回attrsset位掩码,以表示成功设置了哪些属性(如果有)。响应中的属性集是作为参数中obj_属性一部分的位图4的子集。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

If the request specifies the owner attribute to be set, the server should allow the operation to succeed if the current owner of the object matches the value specified in the request. Some servers may be implemented in a way as to prohibit the setting of the owner attribute unless the requester has privilege to do so. If the server is lenient in this one case of matching owner values, the client implementation may be simplified in cases of creation of an object followed by a SETATTR.

如果请求指定要设置的所有者属性,则如果对象的当前所有者与请求中指定的值匹配,服务器应允许操作成功。某些服务器的实现方式可能会禁止设置所有者属性,除非请求者有权限这样做。如果服务器在匹配所有者值的这种情况下比较宽松,那么在创建对象后跟着SETATTR的情况下,客户端实现可能会简化。

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 size to

文件大小属性用于请求更改文件大小。值0(零)会导致文件被截断,小于文件当前大小的值会导致数据从新大小变为新大小

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更改文件大小会间接更改您修改的时间。客户端必须对此进行解释,因为大小更改可能导致数据删除。

The attributes time_access_set and time_modify_set are write-only attributes constructed as a switched union so the client can direct the server in setting the time values. If the switched union specifies SET_TO_CLIENT_TIME4, the client has provided an nfstime4 to be used for the operation. If the switch union does not specify SET_TO_CLIENT_TIME4, the server is to use its current time for the SETATTR operation.

属性time_access_set和time_modify_set是构造为交换联合的仅写属性,因此客户端可以指导服务器设置时间值。如果交换的联合指定SET_TO_CLIENT_TIME4,则客户端已提供用于该操作的nfstime4。如果交换机联合未指定SET_TO_CLIENT_TIME4,则服务器将使用其当前时间执行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.

如果服务器和客户端时间不同,则比较客户端时间和文件时间的程序可能会中断。应该使用时间维护协议来限制客户机/服务器的时间偏差。

Use of a COMPOUND containing a VERIFY operation specifying only the change attribute, immediately followed by a SETATTR, provides a means whereby a client may specify a request that emulates the functionality of the SETATTR guard mechanism of NFS version 3. Since the function of the guard mechanism is to avoid changes to the file attributes based on stale information, delays between checking of the guard condition and the setting of the attributes have the potential to compromise this function, as would the corresponding delay in the NFS version 4 emulation. Therefore, NFS version 4 servers should take care to avoid such delays, to the degree possible, when executing such a request.

使用包含仅指定更改属性的验证操作(紧接着是SETATTR)的复合词,可以提供一种方法,客户机可以通过该方法指定模拟NFS版本3的SETATTR保护机制功能的请求。由于保护机制的功能是避免基于过时信息对文件属性进行更改,因此检查保护条件和设置属性之间的延迟可能会影响此功能,NFS版本4仿真中的相应延迟也可能会影响此功能。因此,NFS版本4服务器在执行此类请求时应尽可能避免此类延迟。

If the server does not support an attribute as requested by the client, the server should return NFS4ERR_ATTRNOTSUPP.

如果服务器不支持客户端请求的属性,则服务器应返回NFS4ERR_ATTRNOTSUPP。

A mask of the attributes actually set is returned by SETATTR in all cases. That mask must not include attributes bits not requested to be set by the client, and must be equal to the mask of attributes requested to be set only if the SETATTR completes without error.

在所有情况下,SETATTR都会返回实际设置的属性的掩码。该掩码不得包含客户端未请求设置的属性位,并且必须等于仅当SETATTR无误完成时请求设置的属性掩码。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADOWNER NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXPIRED NFS4ERR_FBIG NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_LOCKED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_OLD_STATEID NFS4ERR_OPENMODE NFS4ERR_PERM NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

本书中的两个词的意思意思是:错误,错误,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,访问,fafffffffffffffffffffffffSSSSSSS4,faS4,faSNOSPCNFS4ERR\u旧的状态ID NFS4ERR\u OPENMODE NFS4ERR\u PERM NFS4ERR\u资源NFS4ERR\u ROFS NFS4ERR\u服务器故障NFS4ERR\u过时NFS4ERR\u过时的状态ID

14.2.33. Operation 35: SETCLIENTID - Negotiate Clientid
14.2.33. 操作35:SETCLIENTID-协商Clientid

SYNOPSIS

提要

client, callback, callback_ident -> clientid, setclientid_confirm

客户端,回调,回调识别->客户端ID,设置客户端ID\u确认

ARGUMENT

论点

     struct SETCLIENTID4args {
             nfs_client_id4  client;
             cb_client4      callback;
             uint32_t        callback_ident;
     };
        
     struct SETCLIENTID4args {
             nfs_client_id4  client;
             cb_client4      callback;
             uint32_t        callback_ident;
     };
        

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 client uses the SETCLIENTID operation to notify the server of its intention to use a particular client identifier, callback, and callback_ident for subsequent requests that entail creating lock, share reservation, and delegation state on the server. Upon successful completion the server will return a shorthand clientid which, if confirmed via a separate step, will be used in subsequent file locking and file open requests. Confirmation of the clientid must be done via the SETCLIENTID_CONFIRM operation to return the clientid and setclientid_confirm values, as verifiers, to the server. The reason why two verifiers are necessary is that it is possible to use SETCLIENTID and SETCLIENTID_CONFIRM to modify the callback and callback_ident information but not the shorthand clientid. In that event, the setclientid_confirm value is effectively the only verifier.

客户端使用SETCLIENTID操作通知服务器,它打算为后续请求使用特定的客户端标识符、回调和回调标识,这些请求需要在服务器上创建锁、共享保留和委派状态。成功完成后,服务器将返回一个速记clientid,如果通过单独的步骤确认,将在后续的文件锁定和文件打开请求中使用该ID。必须通过SETCLIENTID_确认操作确认clientid,以将clientid和SETCLIENTID_确认值作为验证器返回到服务器。之所以需要两个验证器,是因为可以使用SETCLIENTID和SETCLIENTID_确认来修改回调和回调标识信息,但不能修改速记clientid。在这种情况下,setclientid_确认值实际上是唯一的验证器。

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时,客户端必须正确反映回调程序的程序和端口号。

The callback_ident value is used by the server on the callback. The client can leverage the callback_ident to eliminate the need for more than one callback RPC program number, while still being able to determine which server is initiating the callback.

服务器在回调上使用回调_ident值。客户端可以利用回调标识消除对多个回调RPC程序号的需要,同时仍然能够确定哪个服务器正在启动回调。

IMPLEMENTATION

实施

To understand how to implement SETCLIENTID, make the following notations. Let:

要了解如何实现SETCLIENTID,请使用以下符号。让我们:

x be the value of the client.id subfield of the SETCLIENTID4args structure.

x是SetClientIDArgs结构的client.id子字段的值。

v be the value of the client.verifier subfield of the SETCLIENTID4args structure.

v是SetClientIDArgs结构的client.verifier子字段的值。

c be the value of the clientid field returned in the SETCLIENTID4resok structure.

c是SetClientIDResok结构中返回的clientid字段的值。

k represent the value combination of the fields callback and callback_ident fields of the SETCLIENTID4args structure.

k表示SetClientIDArgs结构的回调字段和回调标识字段的值组合。

s be the setclientid_confirm value returned in the SETCLIENTID4resok structure.

s是setclientid\u确认值,该值在SetClientD4Resok结构中返回。

{ v, x, c, k, s } be a quintuple for a client record. A client record is confirmed if there has been a SETCLIENTID_CONFIRM operation to confirm it. Otherwise it is unconfirmed. An unconfirmed record is established by a SETCLIENTID call.

{v,x,c,k,s}对于客户端记录来说是五元组。如果已通过SETCLIENTID_确认操作对客户端记录进行确认,则会确认客户端记录。否则未经证实。通过SETCLIENTID调用建立未确认的记录。

Since SETCLIENTID is a non-idempotent operation, let us assume that the server is implementing the duplicate request cache (DRC).

由于SETCLIENTID是一个非幂等操作,因此让我们假设服务器正在实现重复请求缓存(DRC)。

When the server gets a SETCLIENTID { v, x, k } request, it processes it in the following manner.

当服务器收到SETCLIENTID{v,x,k}请求时,它将按照以下方式处理它。

o It first looks up the request in the DRC. If there is a hit, it returns the result cached in the DRC. The server does NOT remove client state (locks, shares, delegations) nor does it modify any recorded callback and callback_ident information for client { x }.

o 它首先在DRC中查找请求。如果有命中,它将返回缓存在DRC中的结果。服务器不会删除客户端状态(锁、共享、委派),也不会修改客户端{x}的任何记录的回调和回调标识信息。

For any DRC miss, the server takes the client id string x, and searches for client records for x that the server may have recorded from previous SETCLIENTID calls. For any confirmed record with the same id string x, if the recorded principal does not match that of SETCLIENTID call, then the server returns a NFS4ERR_CLID_INUSE error.

对于任何DRC未命中,服务器将获取客户端id字符串x,并搜索服务器可能已从以前的SETCLIENTID调用中记录的x的客户端记录。对于具有相同id字符串x的任何已确认记录,如果记录的主体与SETCLIENTID调用的主体不匹配,则服务器返回NFS4ERR_CLID_INUSE错误。

For brevity of discussion, the remaining description of the processing assumes that there was a DRC miss, and that where the server has previously recorded a confirmed record for client x, the aforementioned principal check has successfully passed.

为了便于讨论,处理的其余描述假定存在DRC未命中,并且服务器先前已为客户端x记录了确认的记录,上述主体检查已成功通过。

o The server checks if it has recorded a confirmed record for { v, x, c, l, s }, where l may or may not equal k. If so, and since the id verifier v of the request matches that which is confirmed and recorded, the server treats this as a probable callback information update and records an unconfirmed { v, x, c, k, t } and leaves the confirmed { v, x, c, l, s } in place, such that t != s. It does not matter if k equals l or not. Any pre-existing unconfirmed { v, x, c, *, * } is removed.

o 服务器检查它是否记录了{v,x,c,l,s}的确认记录,其中l可能等于或不等于k。如果是,并且由于请求的id验证器v与确认和记录的id验证器v匹配,服务器将此视为可能的回调信息更新,并记录未确认的{v,x,c,k,t},并将确认的{v,x,c,l,s}保留在适当的位置,使得t!=sk是否等于l并不重要。任何预先存在的未确认{v,x,c,*,*}将被删除。

The server returns { c, t }. It is indeed returning the old clientid4 value c, because the client apparently only wants to update callback value k to value l. It's possible this request is one from the Byzantine router that has stale callback information, but this is not a problem. The callback information update is only confirmed if followed up by a SETCLIENTID_CONFIRM { c, t }.

服务器返回{c,t}。它确实返回了旧的client4值c,因为客户端显然只想将回调值k更新为值l。这个请求可能来自拜占庭路由器,它有过时的回调信息,但这不是问题。回调信息更新仅在随后是SETCLIENTID_CONFIRM{c,t}时确认。

The server awaits confirmation of k via SETCLIENTID_CONFIRM { c, t }.

服务器通过SETCLIENTID_CONFIRM{c,t}等待k的确认。

The server does NOT remove client (lock/share/delegation) state for x.

服务器未删除x的客户端(锁定/共享/委派)状态。

o The server has previously recorded a confirmed { u, x, c, l, s } record such that v != u, l may or may not equal k, and has not recorded any unconfirmed { *, x, *, *, * } record for x. The server records an unconfirmed { v, x, d, k, t } (d != c, t != s).

o 服务器以前记录了一个已确认的{u,x,c,l,s}记录,因此v!=u、 l可能等于或不等于k,并且没有记录x的任何未经确认的{*,x,*,*,*}记录。服务器记录一个未确认的{v,x,d,k,t}(d!=c,t!=s)。

The server returns { d, t }.

服务器返回{d,t}。

The server awaits confirmation of { d, k } via SETCLIENTID_CONFIRM { d, t }.

服务器等待通过SETCLIENTID_CONFIRM{d,t}确认{d,k}。

The server does NOT remove client (lock/share/delegation) state for x.

服务器未删除x的客户端(锁定/共享/委派)状态。

o The server has previously recorded a confirmed { u, x, c, l, s } record such that v != u, l may or may not equal k, and recorded an unconfirmed { w, x, d, m, t } record such that c != d, t != s, m may or may not equal k, m may or may not equal l, and k may or may not equal l. Whether w == v or w != v makes no difference. The server simply removes the unconfirmed { w, x, d, m, t } record and replaces it with an unconfirmed { v, x, e, k, r } record, such that e != d, e != c, r != t, r != s.

o 服务器以前记录了一个已确认的{u,x,c,l,s}记录,因此v!=u、 l可以等于k,也可以不等于k,并且记录了一个未确认的{w,x,d,m,t}记录,使得c!=d、 t!=s、 m可以等于或不等于k,m可以等于或不等于l,k可以等于或不等于l。无论w==v还是w!=v没有区别。服务器只是删除未确认的{w,x,d,m,t}记录,并将其替换为未确认的{v,x,e,k,r}记录,这样e!=d、 e!=c、 r!=t、 r!=s

The server returns { e, r }.

服务器返回{e,r}。

The server awaits confirmation of { e, k } via SETCLIENTID_CONFIRM { e, r }.

服务器等待通过SETCLIENTID_CONFIRM{e,r}确认{e,k}。

The server does NOT remove client (lock/share/delegation) state for x.

服务器未删除x的客户端(锁定/共享/委派)状态。

o The server has no confirmed { *, x, *, *, * } for x. It may or may not have recorded an unconfirmed { u, x, c, l, s }, where l may or may not equal k, and u may or may not equal v. Any unconfirmed record { u, x, c, l, * }, regardless whether u == v or l == k, is replaced with an unconfirmed record { v, x, d, k, t } where d != c, t != s.

o 服务器没有确认x的{*,x,*,*,*,*}。它可能记录了也可能没有记录了一个未确认的{u,x,c,l,s},其中l可能等于或不等于k,u可能等于或不等于v。任何未确认的记录{u,x,c,l,*},无论u==v还是l==k,都将替换为未确认的记录{v,x,d,k,t},其中d!=c、 t!=s

The server returns { d, t }.

服务器返回{d,t}。

The server awaits confirmation of { d, k } via SETCLIENTID_CONFIRM { d, t }. The server does NOT remove client (lock/share/delegation) state for x.

服务器等待通过SETCLIENTID_CONFIRM{d,t}确认{d,k}。服务器未删除x的客户端(锁定/共享/委派)状态。

The server generates the clientid and setclientid_confirm values and must take care to ensure that these values are extremely unlikely to ever be regenerated.

服务器生成clientid和setclientid_确认值,并且必须注意确保这些值不太可能重新生成。

ERRORS

错误

NFS4ERR_BADXDR NFS4ERR_CLID_INUSE NFS4ERR_INVAL NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u BADXDR 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

提要

     clientid, verifier -> -
        
     clientid, verifier -> -
        

ARGUMENT

论点

     struct SETCLIENTID_CONFIRM4args {
             clientid4       clientid;
             verifier4       setclientid_confirm;
     };
        
     struct SETCLIENTID_CONFIRM4args {
             clientid4       clientid;
             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) clientid. The server responds with a simple status of success or failure.

客户端使用此操作确认以前调用SETCLIENTID的结果。客户机提供服务器提供的(来自SETCLIENTID响应)clientid。服务器以简单的成功或失败状态进行响应。

IMPLEMENTATION

实施

The client must use the SETCLIENTID_CONFIRM operation to confirm the following two distinct cases:

客户端必须使用SETCLIENTID_确认操作来确认以下两种不同情况:

o The client's use of a new shorthand client identifier (as returned from the server in the response to SETCLIENTID), a new callback value (as specified in the arguments to SETCLIENTID) and a new callback_ident (as specified in the arguments to SETCLIENTID) value. The client's use of SETCLIENTID_CONFIRM in this case also confirms the removal of any of the client's previous relevant leased state. Relevant leased client state includes record locks, share reservations, and where the server does not support the CLAIM_DELEGATE_PREV claim type, delegations. If the server supports CLAIM_DELEGATE_PREV, then SETCLIENTID_CONFIRM MUST NOT remove delegations for this client; relevant leased client state would then just include record locks and share reservations.

o 客户端使用新的速记客户端标识符(在响应SETCLIENTID时从服务器返回)、新的回调值(在SETCLIENTID的参数中指定)和新的回调标识(在SETCLIENTID的参数中指定)值。在这种情况下,客户使用SETCLIENTID_CONFIRM也确认删除了客户以前的任何相关租赁状态。相关租用的客户端状态包括记录锁、共享保留以及服务器不支持CLAIM_DELEGATE_PREV CLAIM类型的委派。如果服务器支持CLAIM_DELEGATE_PREV,则SETCLIENTID_CONFIRM不能删除此客户端的委托;相关的租用客户机状态将只包括记录锁和共享保留。

o The client's re-use of an old, previously confirmed, shorthand client identifier, a new callback value, and a new callback_ident value. The client's use of SETCLIENTID_CONFIRM in this case MUST NOT result in the removal of any previous leased state (locks, share reservations, and delegations)

o 客户端重复使用以前确认的旧速记客户端标识符、新回调值和新回调识别值。在这种情况下,客户使用SETCLIENTID_CONFIRM不得导致删除任何以前的租赁状态(锁、共享保留和委托)

We use the same notation and definitions for v, x, c, k, s, and unconfirmed and confirmed client records as introduced in the description of the SETCLIENTID operation. The arguments to SETCLIENTID_CONFIRM are indicated by the notation { c, s }, where c is a value of type clientid4, and s is a value of type verifier4 corresponding to the setclientid_confirm field.

我们对v、x、c、k、s以及未确认和已确认的客户端记录使用与SETCLIENTID操作描述中介绍的相同的符号和定义。SETCLIENTID_CONFIRM的参数由符号{c,s}表示,其中c是clientd4类型的值,s是对应于SETCLIENTID_CONFIRM字段的verifier4类型的值。

As with SETCLIENTID, SETCLIENTID_CONFIRM is a non-idempotent operation, and we assume that the server is implementing the duplicate request cache (DRC).

与SETCLIENTID一样,SETCLIENTID_CONFIRM是一个非幂等操作,我们假设服务器正在实现重复请求缓存(DRC)。

When the server gets a SETCLIENTID_CONFIRM { c, s } request, it processes it in the following manner.

当服务器收到SETCLIENTID_CONFIRM{c,s}请求时,它将按照以下方式处理它。

o It first looks up the request in the DRC. If there is a hit, it returns the result cached in the DRC. The server does not remove any relevant leased client state nor does it modify any recorded callback and callback_ident information for client { x } as represented by the shorthand value c.

o 它首先在DRC中查找请求。如果有命中,它将返回缓存在DRC中的结果。服务器不会删除任何相关的租用客户端状态,也不会修改由速记值c表示的客户端{x}的任何记录的回调和回调标识信息。

For a DRC miss, the server checks for client records that match the shorthand value c. The processing cases are as follows:

对于DRC未命中,服务器将检查与速记值c匹配的客户端记录。处理个案如下:

o The server has recorded an unconfirmed { v, x, c, k, s } record and a confirmed { v, x, c, l, t } record, such that s != t. If the principals of the records do not match that of the SETCLIENTID_CONFIRM, the server returns NFS4ERR_CLID_INUSE, and no relevant leased client state is removed and no recorded callback and callback_ident information for client { x } is changed. Otherwise, the confirmed { v, x, c, l, t } record is removed and the unconfirmed { v, x, c, k, s } is marked as confirmed, thereby modifying recorded and confirmed callback and callback_ident information for client { x }.

o 服务器已记录未确认的{v,x,c,k,s}记录和已确认的{v,x,c,l,t}记录,因此s!=T如果记录的主体与SETCLIENTID_CONFIRM的主体不匹配,服务器将返回NFS4ERR_CLID_INUSE,并且不会删除任何相关的租用客户端状态,也不会更改客户端{x}的已记录回调和回调标识信息。否则,将删除已确认的{v,x,c,l,t}记录,并将未确认的{v,x,c,k,s}标记为已确认,从而修改客户端{x}的已记录和已确认的回调和回调标识信息。

The server does not remove any relevant leased client state.

服务器不会删除任何相关的已租用客户端状态。

The server returns NFS4_OK.

服务器返回NFS4\u OK。

o The server has not recorded an unconfirmed { v, x, c, *, * } and has recorded a confirmed { v, x, c, *, s }. If the principals of the record and of SETCLIENTID_CONFIRM do not match, the server returns NFS4ERR_CLID_INUSE without removing any relevant leased client state and without changing recorded callback and callback_ident values for client { x }.

o 服务器未记录未确认的{v,x,c,*,*},但已记录已确认的{v,x,c,*,s}。如果记录和SETCLIENTID_确认的主体不匹配,服务器将返回NFS4ERR_CLID_INUSE,而不删除任何相关的租用客户端状态,也不更改客户端{x}的已记录回调和回调标识值。

If the principals match, then what has likely happened is that the client never got the response from the SETCLIENTID_CONFIRM, and the DRC entry has been purged. Whatever the scenario, since the principals match, as well as { c, s } matching a confirmed record, the server leaves client x's relevant leased client state intact, leaves its callback and callback_ident values unmodified, and returns NFS4_OK.

如果主体匹配,那么可能发生的情况是客户端从未收到来自SETCLIENTID\u确认的响应,并且DRC条目已被清除。无论在何种情况下,由于主体匹配,以及{c,s}匹配确认的记录,服务器保持客户端x的相关租用客户端状态不变,保持其回调和回调标识值不变,并返回NFS4_OK。

o The server has not recorded a confirmed { *, *, c, *, * }, and has recorded an unconfirmed { *, x, c, k, s }. Even if this is a retry from client, nonetheless the client's first SETCLIENTID_CONFIRM attempt was not received by the server. Retry or not, the server doesn't know, but it processes it as if were a first try. If the principal of the unconfirmed { *, x, c, k, s } record mismatches that of the SETCLIENTID_CONFIRM request the server returns NFS4ERR_CLID_INUSE without removing any relevant leased client state.

o 服务器未记录已确认的{*,*,c,*,*},但已记录未确认的{*,x,c,k,s}。即使这是来自客户端的重试,但服务器未收到客户端的第一次SETCLIENTID_确认尝试。不管是否重试,服务器都不知道,但它会像第一次尝试一样进行处理。如果未确认的{*,x,c,k,s}记录的主体与SETCLIENTID_确认请求的主体不匹配,服务器将返回NFS4ERR_CLID_INUSE,而不删除任何相关的租用客户端状态。

Otherwise, the server records a confirmed { *, x, c, k, s }. If there is also a confirmed { *, x, d, *, t }, the server MUST remove the client x's relevant leased client state, and overwrite the callback state with k. The confirmed record { *, x, d, *, t } is removed.

否则,服务器将记录一个已确认的{*,x,c,k,s}。如果还有一个确认的{*,x,d,*,t},服务器必须删除客户机x的相关租用客户机状态,并用k覆盖回调状态。已确认的记录{*,x,d,*,t}被删除。

Server returns NFS4_OK.

服务器返回NFS4\u OK。

o The server has no record of a confirmed or unconfirmed { *, *, c, *, s }. The server returns NFS4ERR_STALE_CLIENTID. The server does not remove any relevant leased client state, nor does it modify any recorded callback and callback_ident information for any client.

o 服务器没有已确认或未确认{*,*,c,*,s}的记录。服务器返回NFS4ERR\u STALE\u CLIENTID。服务器不会删除任何相关的租用客户端状态,也不会修改任何客户端记录的回调和回调标识信息。

The server needs to cache unconfirmed { v, x, c, k, s } client records and await for some time their confirmation. As should be clear from the record processing discussions for SETCLIENTID and SETCLIENTID_CONFIRM, there are cases where the server does not deterministically remove unconfirmed client records. To avoid running out of resources, the server is not required to hold unconfirmed records indefinitely. One strategy the server might use is to set a limit on how many unconfirmed client records it will maintain, and then when the limit would be exceeded, remove the oldest record. Another strategy might be to remove an unconfirmed record when some amount of time has elapsed. The choice of the amount of time is fairly arbitrary but it is surely no higher than the server's lease time period. Consider that leases need to be renewed before the lease time expires via an operation from the client. If the client cannot issue a SETCLIENTID_CONFIRM after a SETCLIENTID before a period of time equal to that of a lease expires, then the client is unlikely to be able maintain state on the server during steady state operation.

服务器需要缓存未确认的{v,x,c,k,s}客户端记录,并等待它们的确认一段时间。从SETCLIENTID和SETCLIENTID_CONFIRM的记录处理讨论中可以清楚地看到,在某些情况下,服务器无法确定地删除未确认的客户端记录。为了避免资源耗尽,服务器不需要无限期地保存未确认的记录。服务器可能使用的一种策略是设置其将维护的未确认客户端记录的数量限制,然后当超过该限制时,删除最旧的记录。另一种策略可能是在经过一定时间后删除未确认的记录。时间量的选择相当随意,但肯定不会高于服务器的租用时间。考虑租约在租赁时间到期后通过客户的操作进行更新。如果在与租约到期时间相等的时间段之前,客户端无法在SETCLIENTID之后发出SETCLIENTID_确认,则客户端不太可能在稳态操作期间保持服务器上的状态。

If the client does send a SETCLIENTID_CONFIRM for an unconfirmed record that the server has already deleted, the client will get NFS4ERR_STALE_CLIENTID back. If so, the client should then start over, and send SETCLIENTID to reestablish an unconfirmed client record and get back an unconfirmed clientid and setclientid_confirm verifier. The client should then send the SETCLIENTID_CONFIRM to confirm the clientid.

如果客户端确实为服务器已删除的未确认记录发送SETCLIENTID\u确认,则客户端将返回NFS4ERR\u STALE\u CLIENTID。如果是这样,客户端应该重新开始,并发送SETCLIENTID以重新建立未确认的客户端记录,并返回未确认的clientid和SETCLIENTID\u确认验证器。然后,客户端应发送SETCLIENTID\u确认以确认clientid。

SETCLIENTID_CONFIRM does not establish or renew a lease. However, if SETCLIENTID_CONFIRM removes relevant leased client state, and that state does not include existing delegations, the server MUST allow the client a period of time no less than the value of lease_time attribute, to reclaim, (via the CLAIM_DELEGATE_PREV claim type of the OPEN operation) its delegations before removing unreclaimed delegations.

SETCLIENTID_CONFIRM不会建立或续订租约。但是,如果SETCLIENTID_CONFIRM删除了相关的租用客户端状态,并且该状态不包括现有的委托,则服务器必须允许客户端有一段不小于lease_time属性值的时间来回收(通过打开操作的CLAIM_DELEGATE_PREV CLAIM类型)在取消未申报的代表团之前,应先取消其代表团。

ERRORS

错误

NFS4ERR_BADXDR NFS4ERR_CLID_INUSE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR\u BADXDR NFS4ERR\u CLID\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 filesystem object, the error NFS4ERR_ATTRNOTSUPP is returned to the client.

如果在验证操作中指定了建议的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_ATTRNOTSUPP返回给客户端。

When the attribute rdattr_error or any write-only attribute (e.g., time_modify_set) is specified, the error NFS4ERR_INVAL is returned to the client.

当指定属性rdattr_error或任何只写属性(例如,time_modify_set)时,错误NFS4ERR_INVAL将返回给客户端。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOT_SAME NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE

NFS4ERR\u访问NFS4ERR\u属性支持NFS4ERR\u BADCHAR NFS4ERR\u BADHANDLE NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u过期NFS4ERR\u无效NFS4ERR\u移动的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), stateid, offset, stable, data -> count, committed, writeverf

(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;
        
     struct WRITE4args {
             /* CURRENT_FH: file */
             stateid4        stateid;
             offset4         offset;
        
             stable_how4     stable;
             opaque          data<>;
     };
        
             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, as encoded as part of the opaque data parameter, 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 filesystem 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

写入请求的一部分是如何执行写入的规范。客户机使用stable参数指定服务器如何处理数据的方法。如果stable是FILE_SYNC4,则服务器必须在返回结果之前将写入的数据加上所有文件系统元数据提交到stable存储。这与NFS版本2协议语义相对应。任何其他行为都构成违反协议。如果stable是DATA_SYNC4,则服务器必须将所有数据提交到稳定存储,并在返回之前提交足够的元数据以检索数据。服务器实现者可以自由地以与文件同步4相同的方式实现数据同步4,但可能会导致性能下降。如果stable是不稳定的4,则服务器可以自由地将数据和元数据的任何部分提交到稳定存储,包括全部或全部,然后再向客户端返回回复。无法保证任何未提交的数据随后是否或何时提交到稳定存储。服务器所做的唯一保证是它不会

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.

在不更改verf值的情况下销毁任何数据,并且不会以低于客户端请求的级别提交数据和元数据。

The stateid value for a WRITE request represents a value returned from a previous record lock or share reservation request. The stateid is used by the server to verify that the associated share reservation and any record locks are 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 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.

服务器还通过提交返回数据和元数据的提交级别指示。如果服务器将所有数据和元数据提交到稳定存储中,则应将提交设置为文件\u SYNC4。如果承诺级别至少与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. The write verifier is a cookie that the client can use to determine whether the server has changed instance (boot) 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.

结果的最后一部分是写验证器。写入验证器是一个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的提交响应,则客户端将在将来的某个时间执行提交操作,以将未完成的异步数据和元数据与服务器的稳定存储同步,从而避免客户端错误。由于客户端崩溃或其他错误,服务器可能无法接收后续提交。

For a WRITE with a stateid value of all bits 0, the server MAY allow the WRITE to be serviced subject to mandatory file locks or the current share deny modes for the file. For a WRITE with a stateid

对于stateid值为所有位0的写操作,服务器可能允许根据文件的强制文件锁定或当前共享拒绝模式为写操作提供服务。用于使用stateid进行写入

value of all bits 1, the server MUST NOT allow the WRITE operation to bypass locking checks at the server and are treated exactly the same as if a stateid of all bits 0 were used.

值,则服务器不得允许写操作绕过服务器上的锁定检查,并且处理方式与使用所有位0的stateid时完全相同。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

IMPLEMENTATION

实施

It is possible for the server to write fewer bytes of data than requested by the client. In this case, the server should not return an error unless no data was written at all. If the server writes less than the number of bytes specified, the client should issue another WRITE to write the remaining data.

服务器写入的数据字节数可能少于客户端请求的字节数。在这种情况下,除非根本没有写入数据,否则服务器不应返回错误。如果服务器写入的字节数小于指定的字节数,则客户端应发出另一次写入操作以写入剩余的数据。

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. In the case that the current filehandle is a directory, the server will return NFS4ERR_ISDIR. If the current filehandle is not a regular file or a directory, the server will return NFS4ERR_INVAL.

当超过用户配额时,某些实现可能返回NFS4ERR_NOSPC而不是NFS4ERR_DQUOT。如果当前文件句柄是目录,服务器将返回NFS4ERR_ISDIR。如果当前文件句柄不是常规文件或目录,服务器将返回NFS4ERR_INVAL。

If mandatory file locking is on for the file, and corresponding record of the data to be written file is read or write locked by an owner that is not associated with the stateid, the server will return NFS4ERR_LOCKED. If so, the client must check if the owner corresponding to the stateid used with the WRITE operation has a conflicting read lock that overlaps with the region that was to be written. If the stateid's owner has no conflicting read lock, then the client should try to get the appropriate write record lock via the LOCK operation before re-attempting the WRITE. When the WRITE completes, the client should release the record lock via LOCKU.

如果文件的强制文件锁定处于启用状态,并且要写入文件的数据的相应记录由与stateid不关联的所有者进行读取或写入锁定,则服务器将返回NFS4ERR_locked。如果是这样,客户端必须检查与写入操作使用的stateid对应的所有者是否具有与要写入的区域重叠的冲突读取锁。如果stateid的所有者没有冲突的读锁,那么客户端应该在重新尝试写之前,通过锁操作尝试获取适当的写记录锁。写入完成后,客户端应通过LOCKU释放记录锁。

If the stateid's owner had a conflicting read lock, then the client has no choice but to return an error to the application that attempted the WRITE. The reason is that since the stateid's owner had a read lock, the server either attempted to temporarily effectively upgrade this read lock to a write lock, or the server has no upgrade capability. If the server attempted to upgrade the read lock and failed, it is pointless for the client to re-attempt the upgrade via the LOCK operation, because there might be another client also trying to upgrade. If two clients are blocked trying upgrade the same lock, the clients deadlock. If the server has no upgrade capability, then it is pointless to try a LOCK operation to upgrade.

如果stateid的所有者具有冲突的读锁,则客户端别无选择,只能向尝试写入的应用程序返回错误。原因是由于stateid的所有者有一个读锁,服务器试图暂时有效地将该读锁升级为写锁,或者服务器没有升级功能。如果服务器尝试升级读锁但失败,则客户端通过锁定操作重新尝试升级是毫无意义的,因为可能还有另一个客户端也在尝试升级。如果两个客户端在尝试升级同一个锁时被阻止,则客户端会死锁。如果服务器没有升级功能,那么尝试锁定操作进行升级是毫无意义的。

ERRORS

错误

NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXPIRED

NFS4ERR\u访问NFS4ERR\u管理被撤销NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u状态ID NFS4ERR\u BADXDR NFS4ERR\u延迟NFS4ERR\u DQUOT NFS4ERR\u过期

NFS4ERR_FBIG NFS4ERR_FHEXPIRED NFS4ERR_GRACE NFS4ERR_INVAL NFS4ERR_IO NFS4ERR_ISDIR NFS4ERR_LEASE_MOVED NFS4ERR_LOCKED NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOSPC NFS4ERR_NXIO NFS4ERR_OLD_STATEID NFS4ERR_OPENMODE NFS4ERR_RESOURCE NFS4ERR_ROFS NFS4ERR_SERVERFAULT NFS4ERR_STALE NFS4ERR_STALE_STATEID

NFS4ERR\u FBIG NFS4ERR\u Fhu过期的NFS4ERR\u GRACE NFS4ERR\u无效的NFS4ERR\u IO NFS4ERR\u ISDIR NFS4ERR\u移动的NFS4ERR\u锁定的NFS4ERR\u移动的NFS4ERR\u无文件句柄NFS4ERR\u NOSPC NFS4ERR\u NXIO NFS4ERR\u旧的NFS4ERR\u状态ID NFS4ERR\u开放式NFS4ERR\u资源NFS4ERR\u失效的NFS4ERR\u状态

14.2.37. Operation 39: RELEASE_LOCKOWNER - Release Lockowner State
14.2.37. 操作39:释放锁所有者-释放锁所有者状态

SYNOPSIS

提要

lockowner -> ()

锁主->()

ARGUMENT

论点

     struct RELEASE_LOCKOWNER4args {
             lock_owner4     lock_owner;
     };
        
     struct RELEASE_LOCKOWNER4args {
             lock_owner4     lock_owner;
     };
        

RESULT

后果

     struct RELEASE_LOCKOWNER4res {
             nfsstat4        status;
     };
        
     struct RELEASE_LOCKOWNER4res {
             nfsstat4        status;
     };
        

DESCRIPTION

描述

This operation is used to notify the server that the lock_owner is no longer in use by the client. This allows the server to release cached state related to the specified lock_owner. If file locks, associated with the lock_owner, are held at the server, the error NFS4ERR_LOCKS_HELD will be returned and no further action will be taken.

此操作用于通知服务器客户端不再使用锁所有者。这允许服务器释放与指定锁所有者相关的缓存状态。如果与锁所有者关联的文件锁保存在服务器上,将返回错误NFS4ERR\u locks\u hold,并且不会采取进一步的操作。

IMPLEMENTATION

实施

The client may choose to use this operation to ease the amount of server state that is held. Depending on behavior of applications at the client, it may be important for the client to use this operation since the server has certain obligations with respect to holding a reference to a lock_owner as long as the associated file is open. Therefore, if the client knows for certain that the lock_owner will no longer be used under the context of the associated open_owner4, it should use RELEASE_LOCKOWNER.

客户端可以选择使用此操作来减轻服务器状态的保留量。根据客户机上应用程序的行为,客户机使用此操作可能很重要,因为只要相关文件打开,服务器就有义务保持对锁所有者的引用。因此,如果客户端确实知道锁所有者将不再在关联的open_所有者4的上下文中使用,那么它应该使用RELEASE_LOCKOWNER。

ERRORS

错误

NFS4ERR_ADMIN_REVOKED NFS4ERR_BADXDR NFS4ERR_EXPIRED NFS4ERR_LEASE_MOVED NFS4ERR_LOCKS_HELD NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID

NFS4ERR\u ADMIN\u吊销的NFS4ERR\u BADXDR NFS4ERR\u过期的NFS4ERR\u租约\u移动的NFS4ERR\u锁\u持有的NFS4ERR\u资源NFS4ERR\u服务器故障NFS4ERR\u过期的客户端ID

14.2.38. Operation 10044: ILLEGAL - Illegal operation
14.2.38. 操作10044:非法-非法操作

SYNOPSIS

提要

     <null> -> ()
        
     <null> -> ()
        

ARGUMENT

论点

void;

无效的

RESULT

后果

             struct ILLEGAL4res {
                     nfsstat4        status;
             };
        
             struct ILLEGAL4res {
                     nfsstat4        status;
             };
        

DESCRIPTION

描述

This operation is a placeholder for encoding a result to handle the case of the client sending an operation code within COMPOUND that is not supported. See the COMPOUND procedure description for more details.

此操作是一个占位符,用于对结果进行编码,以处理客户端在不支持的复合内发送操作代码的情况。有关更多详细信息,请参见复合过程说明。

The status field of ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.

ILLEGAL4res的状态字段必须设置为NFS4ERR_OP_非法。

IMPLEMENTATION

实施

A client will probably not send an operation with code OP_ILLEGAL but if it does, the response will be ILLEGAL4res just as it would be with any other invalid operation code. Note that if the server gets an illegal operation code that is not OP_ILLEGAL, and if the server checks for legal operation codes during the XDR decode phase, then the ILLEGAL4res would not be returned.

客户端可能不会发送代码为OP_非法的操作,但如果发送,响应将是非法的4res,就像发送任何其他无效操作代码一样。请注意,如果服务器获取的非法操作代码不是OP_非法的,并且如果服务器在XDR解码阶段检查合法操作代码,则不会返回非法4res。

ERRORS

错误

NFS4ERR_OP_ILLEGAL

NFS4ERR_OP_非法

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,
             OP_CB_ILLEGAL           = 10044
     };
        
     enum nfs_cb_opnum4 {
             OP_CB_GETATTR           = 3,
             OP_CB_RECALL            = 4,
             OP_CB_ILLEGAL           = 10044
     };
        
     union nfs_cb_argop4 switch (unsigned argop) {
      case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
      case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
      case OP_CB_ILLEGAL:    void            opcbillegal;
     };
        
     union nfs_cb_argop4 switch (unsigned argop) {
      case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
      case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
      case OP_CB_ILLEGAL:    void            opcbillegal;
     };
        
     struct CB_COMPOUND4args {
             utf8str_cs      tag;
             uint32_t        minorversion;
             uint32_t        callback_ident;
             nfs_cb_argop4   argarray<>;
     };
        
     struct CB_COMPOUND4args {
             utf8str_cs      tag;
             uint32_t        minorversion;
             uint32_t        callback_ident;
             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;
             utf8str_cs      tag;
             nfs_cb_resop4   resarray<>;
     };
        
     struct CB_COMPOUND4res {
             nfsstat4 status;
             utf8str_cs      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_复合过程中执行的最后一个操作的状态相同。因此,如果操作发生错误,“状态”值将与为失败的操作返回的错误值相同。

For the definition of the "tag" field, see the section "Procedure 1: COMPOUND - Compound Operations".

有关“标记”字段的定义,请参阅“过程1:复合-复合操作”一节。

The value of callback_ident is supplied by the client during SETCLIENTID. The server must use the client supplied callback_ident during the CB_COMPOUND to allow the client to properly identify the server.

callback_ident的值由客户端在SETCLIENTID期间提供。在CB_复合期间,服务器必须使用客户端提供的回调_ident,以允许客户端正确标识服务器。

Illegal operation codes are handled in the same way as they are handled for the COMPOUND procedure.

非法操作代码的处理方式与复合程序的处理方式相同。

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_BADXDR NFS4ERR_OP_ILLEGAL NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u BADHANDLE NFS4ERR\u BAD\u STATEID NFS4ERR\u BADXDR NFS4ERR\u OP\u非法NFS4ERR\u资源NFS4ERR\u服务器故障

15.2.1. Operation 3: CB_GETATTR - Get Attributes
15.2.1. 操作3:CB_GETATTR-Get属性

SYNOPSIS

提要

fh, attr_request -> attrmask, attr_vals

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 by the server to obtain the current modified state of a file that has been write delegated. The attributes size and change are the only ones guaranteed to be serviced by the client. See the section "Handling of CB_GETATTR" for a full description of how the client and server are to interact with the use of CB_GETATTR.

服务器使用CB_GETATTR操作获取已被写委派的文件的当前修改状态。属性size和change是唯一保证由客户机提供服务的属性。有关客户端和服务器如何与CB_GETATTR的使用交互的完整描述,请参阅“CB_GETATTR的处理”一节。

If the filehandle 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 attrmask bits and the associated attribute values only for the change attribute, and attributes that it may change (time_modify, and size).

客户机仅为更改属性和可能更改的属性(时间、修改和大小)返回属性掩码位和相关属性值。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u坏句柄NFS4ERR\u坏XDR NFS4ERR\u资源NFS4ERR\u服务器故障

15.2.2. Operation 4: CB_RECALL - Recall an Open Delegation
15.2.2. 操作4:CB_召回-召回公开委托

SYNOPSIS

提要

stateid, truncate, fh -> ()

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 except when an error was returned. The recall is not complete until the delegation is returned using a DELEGRETURN.

客户端应该立即回复回调。回复不会完成调用,除非返回错误。只有使用DELEGRETURN返回委托,召回才算完成。

ERRORS

错误

NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT

NFS4ERR\u坏句柄NFS4ERR\u坏\u状态ID NFS4ERR\u坏XDR NFS4ERR\u资源NFS4ERR\u服务器故障

15.2.3. Operation 10044: CB_ILLEGAL - Illegal Callback Operation
15.2.3. 操作10044:CB_非法-非法回调操作

SYNOPSIS

提要

     <null> -> ()
        
     <null> -> ()
        

ARGUMENT

论点

void;

无效的

RESULT

后果

             struct CB_ILLEGAL4res {
                     nfsstat4        status;
             };
        
             struct CB_ILLEGAL4res {
                     nfsstat4        status;
             };
        

DESCRIPTION

描述

This operation is a placeholder for encoding a result to handle the case of the client sending an operation code within COMPOUND that is not supported. See the COMPOUND procedure description for more details.

此操作是一个占位符,用于对结果进行编码,以处理客户端在不支持的复合内发送操作代码的情况。有关更多详细信息,请参见复合过程说明。

The status field of CB_ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.

CB_ILLEGAL4res的状态字段必须设置为NFS4ERR_OP_ILLEGAL。

IMPLEMENTATION

实施

A server will probably not send an operation with code OP_CB_ILLEGAL but if it does, the response will be CB_ILLEGAL4res just as it would be with any other invalid operation code. Note that if the client

服务器可能不会发送代码为OP_CB_非法的操作,但如果发送,响应将是CB_非法4res,就像发送任何其他无效操作代码一样。注意,如果客户端

gets an illegal operation code that is not OP_ILLEGAL, and if the client checks for legal operation codes during the XDR decode phase, then the CB_ILLEGAL4res would not be returned.

获取非OP_非法的非法操作代码,如果客户端在XDR解码阶段检查合法操作代码,则不会返回CB_ILLEGAL4res。

ERRORS

错误

NFS4ERR_OP_ILLEGAL

NFS4ERR_OP_非法

16. Security Considerations
16. 安全考虑

NFS has historically used a model where, from an authentication perspective, the client was the entire machine, or at least the source IP address of the machine. The NFS server relied on the NFS client to make the proper authentication of the end-user. The NFS server in turn shared its files only to specific clients, as identified by the client's source IP address. Given this model, the AUTH_SYS RPC security flavor simply identified the end-user using the client to the NFS server. When processing NFS responses, the client ensured that the responses came from the same IP address and port number that the request was sent to. While such a model is easy to implement and simple to deploy and use, it is certainly not a safe model. Thus, NFSv4 mandates that implementations support a security model that uses end to end authentication, where an end-user on a client mutually authenticates (via cryptographic schemes that do not expose passwords or keys in the clear on the network) to a principal on an NFS server. Consideration should also be given to the integrity and privacy of NFS requests and responses. The issues of end to end mutual authentication, integrity, and privacy are discussed as part of the section on "RPC and Security Flavor".

从身份验证的角度来看,NFS历史上使用的模型中,客户端是整个机器,或者至少是机器的源IP地址。NFS服务器依赖NFS客户端对最终用户进行正确的身份验证。NFS服务器反过来只将其文件共享给特定的客户端,由客户端的源IP地址标识。考虑到这个模型,AUTH_SYS RPC安全特性只识别使用NFS服务器客户端的最终用户。在处理NFS响应时,客户端确保响应来自发送请求的相同IP地址和端口号。虽然这样的模型易于实现、部署和使用简单,但它肯定不是一个安全的模型。因此,NFSv4要求实现支持使用端到端身份验证的安全模型,其中客户端上的最终用户(通过不公开网络上明文中的密码或密钥的加密方案)向NFS服务器上的主体进行相互身份验证。还应考虑NFS请求和响应的完整性和隐私性。“RPC和安全风格”一节讨论了端到端相互认证、完整性和隐私问题。

Note that while NFSv4 mandates an end to end mutual authentication model, the "classic" model of machine authentication via IP address checking and AUTH_SYS identification can still be supported with the caveat that the AUTH_SYS flavor is neither MANDATORY nor RECOMMENDED by this specification, and so interoperability via AUTH_SYS is not assured.

请注意,尽管NFSv4要求端到端的相互身份验证模型,但仍然可以支持通过IP地址检查和AUTH_SYS标识进行机器身份验证的“经典”模型,但需要注意的是,AUTH_SYS风格既不是强制性的,也不是本规范所推荐的,因此无法确保通过AUTH_SYS进行互操作。

For reasons of reduced administration overhead, better performance and/or reduction of CPU utilization, users of NFS version 4 implementations may choose to not use security mechanisms that enable integrity protection on each remote procedure call and response. The use of mechanisms without integrity leaves the customer vulnerable to an attacker in between the NFS client and server that modifies the RPC request and/or the response. While implementations are free to provide the option to use weaker security mechanisms, there are two operations in particular that warrant the implementation overriding user choices.

出于减少管理开销、提高性能和/或降低CPU利用率的原因,NFS版本4实现的用户可以选择不使用在每个远程过程调用和响应上启用完整性保护的安全机制。使用没有完整性的机制会使客户容易受到NFS客户端和服务器之间的攻击者的攻击,从而修改RPC请求和/或响应。虽然实现可以自由地提供使用较弱安全机制的选项,但有两种操作特别保证实现覆盖用户选择。

The first such operation is SECINFO. It is recommended that the client issue the SECINFO call such that it is protected with a security flavor that has integrity protection, such as RPCSEC_GSS with a security triple that uses either rpc_gss_svc_integrity or rpc_gss_svc_privacy (rpc_gss_svc_privacy includes integrity protection) service. Without integrity protection encapsulating SECINFO and therefore its results, an attacker in the middle could modify 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.

第一个这样的操作是SECINFO。建议客户端发出SECINFO调用,以便使用具有完整性保护的安全特性对其进行保护,例如使用rpc_GSS_svc_完整性或rpc_GSS_svc_隐私(rpc_GSS_svc_隐私包括完整性保护)服务的RPCSEC_GSS。如果没有完整性保护封装SECIFO,因此其结果,中间的攻击者可以修改结果,使得客户端可以在服务器允许的集合中选择较弱的算法,使得客户端和/或服务器容易受到进一步攻击。

The second operation that should definitely use integrity protection is any GETATTR for the fs_locations attribute. The attack has two steps. First the attacker modifies the unprotected results of some operation to return NFS4ERR_MOVED. Second, when the client follows up with a GETATTR for the fs_locations attribute, the attacker modifies the results to cause the client migrate its traffic to a server controlled by the attacker.

第二个肯定应该使用完整性保护的操作是fs_locations属性的任何GETATTR。攻击分为两个步骤。首先,攻击者修改某些操作的未受保护结果以返回NFS4ERR_MOVED。其次,当客户机使用fs_locations属性的GETATTR进行后续操作时,攻击者会修改结果,使客户机将其流量迁移到由攻击者控制的服务器。

Because the operations SETCLIENTID/SETCLIENTID_CONFIRM are responsible for the release of client state, it is imperative that the principal used for these operations is checked against and match the previous use of these operations. See the section "Client ID" for further discussion.

由于操作SETCLIENTID/SETCLIENTID_CONFIRM负责释放客户端状态,因此必须检查用于这些操作的主体是否与以前使用的这些操作相匹配。有关进一步的讨论,请参阅“客户端ID”一节。

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. Even though the name space is not specifically controlled to prevent collisions, an IANA registry has been created for the registration of NFS version 4 named attributes. Registration will be achieved through the publication of an Informational RFC and will require not only the name of the attribute but the syntax and semantics of the named attribute contents; the intent is to promote interoperability where common interests exist. While application developers are allowed to define and use attributes as needed, they are encouraged to register the attributes with IANA.

NFS版本4协议提供了命名属性与文件的关联。这些属性的名称空间标识符定义为字符串名称。协议没有为这些文件属性定义名称空间的特定分配。尽管没有专门控制名称空间以防止冲突,但是已经创建了一个IANA注册表来注册NFS版本4命名属性。注册将通过发布信息RFC实现,不仅需要属性名称,还需要命名属性内容的语法和语义;目的是在存在共同利益的地方促进互操作性。虽然允许应用程序开发人员根据需要定义和使用属性,但鼓励他们向IANA注册属性。

17.2. ONC RPC Network Identifiers (netids)
17.2. ONC RPC网络标识符(NetID)

The section "Structured Data Types" discussed the r_netid field and the corresponding r_addr field of a clientaddr4 structure. The NFS version 4 protocol depends on the syntax and semantics of these

“结构化数据类型”一节讨论了ClientAddress4结构的r_netid字段和相应的r_addr字段。NFS版本4协议取决于这些协议的语法和语义

fields to effectively communicate callback information between client and server. Therefore, an IANA registry has been created to include the values defined in this document and to allow for future expansion based on transport usage/availability. Additions to this ONC RPC Network Identifier registry must be done with the publication of an RFC.

用于在客户端和服务器之间有效地通信回调信息的字段。因此,已创建一个IANA注册表,以包含本文档中定义的值,并允许将来根据传输使用/可用性进行扩展。必须通过发布RFC来添加此ONC RPC网络标识符注册表。

The initial values for this registry are as follows (some of this text is replicated from section 2.2 for clarity):

该注册表的初始值如下所示(为清晰起见,部分文本从第2.2节复制):

The Network Identifier (or r_netid for short) is used to specify a transport protocol and associated universal address (or r_addr for short). The syntax of the Network Identifier is a US-ASCII string. The initial definitions for r_netid are:

网络标识符(简称r_netid)用于指定传输协议和相关的通用地址(简称r_addr)。网络标识符的语法是US-ASCII字符串。r\u netid的初始定义如下:

"tcp" - TCP over IP version 4

“tcp”-tcp over IP版本4

"udp" - UDP over IP version 4

“udp”-IP上的udp版本4

"tcp6" - TCP over IP version 6

“tcp6”-TCP over IP版本6

"udp6" - UDP over IP version 6

“udp6”-UDP over IP版本6

Note: the '"' marks are used for delimiting the strings for this document and are not part of the Network Identifier string.

注意:‘’标记用于分隔此文档的字符串,不属于网络标识符字符串的一部分。

For the "tcp" and "udp" Network Identifiers the Universal Address or r_addr (for IPv4) is a US-ASCII string and is of the form:

对于“tcp”和“udp”网络标识符,通用地址或r_addr(对于IPv4)是US-ASCII字符串,其形式如下:

h1.h2.h3.h4.p1.p2

h1.h2.h3.h4.p1.p2

The prefix, "h1.h2.h3.h4", is the standard textual form for representing an IPv4 address, which is always four octets long. Assuming big-endian ordering, h1, h2, h3, and h4, are respectively, the first through fourth octets each converted to ASCII-decimal. Assuming big-endian ordering, p1 and p2 are, respectively, the first and second octets each converted to ASCII-decimal. For example, if a host, in big-endian order, has an address of 0x0A010307 and there is a service listening on, in big endian order, port 0x020F (decimal 527), then complete universal address is "10.1.3.7.2.15".

前缀“h1.h2.h3.h4”是表示IPv4地址的标准文本形式,其长度始终为四个八位字节。假设大端排序h1、h2、h3和h4分别是第一个到第四个八位字节,每个八位字节都转换为ASCII十进制。假设大端排序,p1和p2分别是第一个和第二个八位字节,每个八位字节转换为ASCII十进制。例如,如果主机的大端顺序为地址0x0A010307,并且有一个服务正在侦听端口0x020F(十进制527),则完整的通用地址为“10.1.3.7.2.15”。

For the "tcp6" and "udp6" Network Identifiers the Universal Address or r_addr (for IPv6) is a US-ASCII string and is of the form:

对于“tcp6”和“udp6”网络标识符,通用地址或r_addr(用于IPv6)是US-ASCII字符串,其形式如下:

      x1:x2:x3:x4:x5:x6:x7:x8.p1.p2
        
      x1:x2:x3:x4:x5:x6:x7:x8.p1.p2
        

The suffix "p1.p2" is the service port, and is computed the same way as with universal addresses for "tcp" and "udp". The prefix, "x1:x2:x3:x4:x5:x6:x7:x8", is the standard textual form for representing an IPv6 address as defined in Section 2.2 of [RFC2373]. Additionally, the two alternative forms specified in Section 2.2 of [RFC2373] are also acceptable.

后缀“p1.p2”是服务端口,其计算方式与“tcp”和“udp”的通用地址相同。前缀“x1:x2:x3:x4:x5:x6:x7:x8”是表示[RFC2373]第2.2节中定义的IPv6地址的标准文本形式。此外,也可接受[RFC2373]第2.2节中规定的两种替代形式。

As mentioned, the registration of new Network Identifiers will require the publication of an Information RFC with similar detail as listed above for the Network Identifier itself and corresponding Universal Address.

如前所述,新网络标识符的注册将需要发布信息RFC,该信息RFC具有与上述网络标识符本身和相应通用地址类似的详细信息。

18. RPC definition file
18. RPC定义文件
   /*
    *  Copyright (C) The Internet Society (1998,1999,2000,2001,2002).
    *  All Rights Reserved.
    */
        
   /*
    *  Copyright (C) The Internet Society (1998,1999,2000,2001,2002).
    *  All Rights Reserved.
    */
        
   /*
    *      nfs4_prot.x
    *
    */
        
   /*
    *      nfs4_prot.x
    *
    */
        

%#pragma ident "%W%"

%#pragma标识“%W%”

   /*
    * 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;
   const NFS4_OPAQUE_LIMIT         = 1024;
        
   /*
    * Sizes
    */
   const NFS4_FHSIZE               = 128;
   const NFS4_VERIFIER_SIZE        = 8;
   const NFS4_OPAQUE_LIMIT         = 1024;
        
   /*
    * File types
    */
   enum nfs_ftype4 {
           NF4REG          = 1,    /* Regular File */
           NF4DIR          = 2,    /* Directory */
           NF4BLK          = 3,    /* Special File - block device */
        
   /*
    * 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 */
   };
        
           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,    /* everything is okay      */
           NFS4ERR_PERM            = 1,    /* caller not privileged   */
           NFS4ERR_NOENT           = 2,    /* no such file/directory  */
           NFS4ERR_IO              = 5,    /* hard I/O error          */
           NFS4ERR_NXIO            = 6,    /* no such device          */
           NFS4ERR_ACCESS          = 13,   /* access denied           */
           NFS4ERR_EXIST           = 17,   /* file already exists     */
           NFS4ERR_XDEV            = 18,   /* different filesystems   */
           /* Unused/reserved        19 */
           NFS4ERR_NOTDIR          = 20,   /* should be a directory   */
           NFS4ERR_ISDIR           = 21,   /* should not be directory */
           NFS4ERR_INVAL           = 22,   /* invalid argument        */
           NFS4ERR_FBIG            = 27,   /* file exceeds server max */
           NFS4ERR_NOSPC           = 28,   /* no space on filesystem  */
           NFS4ERR_ROFS            = 30,   /* read-only filesystem    */
           NFS4ERR_MLINK           = 31,   /* too many hard links     */
           NFS4ERR_NAMETOOLONG     = 63,   /* name exceeds server max */
           NFS4ERR_NOTEMPTY        = 66,   /* directory not empty     */
           NFS4ERR_DQUOT           = 69,   /* hard quota limit reached*/
           NFS4ERR_STALE           = 70,   /* file no longer exists   */
           NFS4ERR_BADHANDLE       = 10001,/* Illegal filehandle      */
           NFS4ERR_BAD_COOKIE      = 10003,/* READDIR cookie is stale */
           NFS4ERR_NOTSUPP         = 10004,/* operation not supported */
           NFS4ERR_TOOSMALL        = 10005,/* response limit exceeded */
           NFS4ERR_SERVERFAULT     = 10006,/* undefined server error  */
           NFS4ERR_BADTYPE         = 10007,/* type invalid for CREATE */
           NFS4ERR_DELAY           = 10008,/* file "busy" - retry     */
           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,/* filehandle expired      */
           NFS4ERR_SHARE_DENIED    = 10015,/* share reserve denied    */
           NFS4ERR_WRONGSEC        = 10016,/* wrong security flavor   */
           NFS4ERR_CLID_INUSE      = 10017,/* clientid in use         */
        
   /*
    * Error status
    */
   enum nfsstat4 {
           NFS4_OK                 = 0,    /* everything is okay      */
           NFS4ERR_PERM            = 1,    /* caller not privileged   */
           NFS4ERR_NOENT           = 2,    /* no such file/directory  */
           NFS4ERR_IO              = 5,    /* hard I/O error          */
           NFS4ERR_NXIO            = 6,    /* no such device          */
           NFS4ERR_ACCESS          = 13,   /* access denied           */
           NFS4ERR_EXIST           = 17,   /* file already exists     */
           NFS4ERR_XDEV            = 18,   /* different filesystems   */
           /* Unused/reserved        19 */
           NFS4ERR_NOTDIR          = 20,   /* should be a directory   */
           NFS4ERR_ISDIR           = 21,   /* should not be directory */
           NFS4ERR_INVAL           = 22,   /* invalid argument        */
           NFS4ERR_FBIG            = 27,   /* file exceeds server max */
           NFS4ERR_NOSPC           = 28,   /* no space on filesystem  */
           NFS4ERR_ROFS            = 30,   /* read-only filesystem    */
           NFS4ERR_MLINK           = 31,   /* too many hard links     */
           NFS4ERR_NAMETOOLONG     = 63,   /* name exceeds server max */
           NFS4ERR_NOTEMPTY        = 66,   /* directory not empty     */
           NFS4ERR_DQUOT           = 69,   /* hard quota limit reached*/
           NFS4ERR_STALE           = 70,   /* file no longer exists   */
           NFS4ERR_BADHANDLE       = 10001,/* Illegal filehandle      */
           NFS4ERR_BAD_COOKIE      = 10003,/* READDIR cookie is stale */
           NFS4ERR_NOTSUPP         = 10004,/* operation not supported */
           NFS4ERR_TOOSMALL        = 10005,/* response limit exceeded */
           NFS4ERR_SERVERFAULT     = 10006,/* undefined server error  */
           NFS4ERR_BADTYPE         = 10007,/* type invalid for CREATE */
           NFS4ERR_DELAY           = 10008,/* file "busy" - retry     */
           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,/* filehandle 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,/* server has rebooted     */
           NFS4ERR_STALE_STATEID   = 10023,/* server has rebooted     */
           NFS4ERR_OLD_STATEID     = 10024,/* state is out of sync    */
           NFS4ERR_BAD_STATEID     = 10025,/* incorrect stateid       */
           NFS4ERR_BAD_SEQID       = 10026,/* request is out of seq.  */
           NFS4ERR_NOT_SAME        = 10027,/* verify - attrs not same */
           NFS4ERR_LOCK_RANGE      = 10028,/* lock range not supported*/
           NFS4ERR_SYMLINK         = 10029,/* should be file/directory*/
           NFS4ERR_RESTOREFH       = 10030,/* no saved filehandle     */
           NFS4ERR_LEASE_MOVED     = 10031,/* some filesystem moved   */
           NFS4ERR_ATTRNOTSUPP     = 10032,/* recommended attr not sup*/
           NFS4ERR_NO_GRACE        = 10033,/* reclaim outside of grace*/
           NFS4ERR_RECLAIM_BAD     = 10034,/* reclaim error at server */
           NFS4ERR_RECLAIM_CONFLICT = 10035,/* conflict on reclaim    */
           NFS4ERR_BADXDR          = 10036,/* XDR decode failed       */
           NFS4ERR_LOCKS_HELD      = 10037,/* file locks held at CLOSE*/
           NFS4ERR_OPENMODE        = 10038,/* conflict in OPEN and I/O*/
           NFS4ERR_BADOWNER        = 10039,/* owner translation bad   */
           NFS4ERR_BADCHAR         = 10040,/* utf-8 char not supported*/
           NFS4ERR_BADNAME         = 10041,/* name not supported      */
           NFS4ERR_BAD_RANGE       = 10042,/* lock range not supported*/
           NFS4ERR_LOCK_NOTSUPP    = 10043,/* no atomic up/downgrade  */
           NFS4ERR_OP_ILLEGAL      = 10044,/* undefined operation     */
           NFS4ERR_DEADLOCK        = 10045,/* file locking deadlock   */
           NFS4ERR_FILE_OPEN       = 10046,/* open file blocks op.    */
           NFS4ERR_ADMIN_REVOKED   = 10047,/* lockowner state revoked */
           NFS4ERR_CB_PATH_DOWN    = 10048 /* callback path down      */
   };
        
           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,/* server has rebooted     */
           NFS4ERR_STALE_STATEID   = 10023,/* server has rebooted     */
           NFS4ERR_OLD_STATEID     = 10024,/* state is out of sync    */
           NFS4ERR_BAD_STATEID     = 10025,/* incorrect stateid       */
           NFS4ERR_BAD_SEQID       = 10026,/* request is out of seq.  */
           NFS4ERR_NOT_SAME        = 10027,/* verify - attrs not same */
           NFS4ERR_LOCK_RANGE      = 10028,/* lock range not supported*/
           NFS4ERR_SYMLINK         = 10029,/* should be file/directory*/
           NFS4ERR_RESTOREFH       = 10030,/* no saved filehandle     */
           NFS4ERR_LEASE_MOVED     = 10031,/* some filesystem moved   */
           NFS4ERR_ATTRNOTSUPP     = 10032,/* recommended attr not sup*/
           NFS4ERR_NO_GRACE        = 10033,/* reclaim outside of grace*/
           NFS4ERR_RECLAIM_BAD     = 10034,/* reclaim error at server */
           NFS4ERR_RECLAIM_CONFLICT = 10035,/* conflict on reclaim    */
           NFS4ERR_BADXDR          = 10036,/* XDR decode failed       */
           NFS4ERR_LOCKS_HELD      = 10037,/* file locks held at CLOSE*/
           NFS4ERR_OPENMODE        = 10038,/* conflict in OPEN and I/O*/
           NFS4ERR_BADOWNER        = 10039,/* owner translation bad   */
           NFS4ERR_BADCHAR         = 10040,/* utf-8 char not supported*/
           NFS4ERR_BADNAME         = 10041,/* name not supported      */
           NFS4ERR_BAD_RANGE       = 10042,/* lock range not supported*/
           NFS4ERR_LOCK_NOTSUPP    = 10043,/* no atomic up/downgrade  */
           NFS4ERR_OP_ILLEGAL      = 10044,/* undefined operation     */
           NFS4ERR_DEADLOCK        = 10045,/* file locking deadlock   */
           NFS4ERR_FILE_OPEN       = 10046,/* open file blocks op.    */
           NFS4ERR_ADMIN_REVOKED   = 10047,/* lockowner state revoked */
           NFS4ERR_CB_PATH_DOWN    = 10048 /* callback path down      */
   };
        
   /*
    * Basic data types
    */
   typedef uint32_t        bitmap4<>;
   typedef uint64_t        offset4;
   typedef uint32_t        count4;
   typedef uint64_t        length4;
   typedef uint64_t        clientid4;
   typedef uint32_t        seqid4;
   typedef opaque          utf8string<>;
   typedef utf8string      utf8str_cis;
   typedef utf8string      utf8str_cs;
   typedef utf8string      utf8str_mixed;
   typedef utf8str_cs      component4;
   typedef component4      pathname4<>;
        
   /*
    * Basic data types
    */
   typedef uint32_t        bitmap4<>;
   typedef uint64_t        offset4;
   typedef uint32_t        count4;
   typedef uint64_t        length4;
   typedef uint64_t        clientid4;
   typedef uint32_t        seqid4;
   typedef opaque          utf8string<>;
   typedef utf8string      utf8str_cis;
   typedef utf8string      utf8str_cs;
   typedef utf8string      utf8str_mixed;
   typedef utf8str_cs      component4;
   typedef component4      pathname4<>;
        
   typedef uint64_t        nfs_lockid4;
   typedef uint64_t        nfs_cookie4;
   typedef utf8str_cs      linktext4;
   typedef opaque          sec_oid4<>;
   typedef uint32_t        qop4;
   typedef uint32_t        mode4;
   typedef uint64_t        changeid4;
   typedef opaque          verifier4[NFS4_VERIFIER_SIZE];
        
   typedef uint64_t        nfs_lockid4;
   typedef uint64_t        nfs_cookie4;
   typedef utf8str_cs      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
    */
   typedef opaque  nfs_fh4<NFS4_FHSIZE>;
        
   /*
    * File access handle
    */
   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 {
           utf8str_cis     server<>;
           pathname4       rootpath;
   };
        
    * Filesystem locations attribute for relocation/migration
    */
   struct fs_location4 {
           utf8str_cis     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;
   /*
    * 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;
        
   typedef uint32_t        acetype4;
   /*
    * 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;
        
   /*
    * 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;
        
   /*
    * 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;
        
   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_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_APPEND_DATA |
    *      ACE4_SYNCHRONIZE
    */
   const 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;
           utf8str_mixed   who;
   };
        
   /*
    * Access Control Entry definition
    */
   struct nfsace4 {
           acetype4        type;
           aceflag4        flag;
           acemask4        access_mask;
           utf8str_mixed   who;
   };
        
   /*
    * Field definitions for the fattr4_mode attribute
    */
   const MODE4_SUID = 0x800;  /* set user id on execution */
   const MODE4_SGID = 0x400;  /* set group id on execution */
   const MODE4_SVTX = 0x200;  /* save text even after use */
   const MODE4_RUSR = 0x100;  /* read permission: owner */
   const MODE4_WUSR = 0x080;  /* write permission: owner */
   const MODE4_XUSR = 0x040;  /* execute permission: owner */
   const MODE4_RGRP = 0x020;  /* read permission: group */
   const MODE4_WGRP = 0x010;  /* write permission: group */
   const MODE4_XGRP = 0x008;  /* execute permission: group */
   const MODE4_ROTH = 0x004;  /* read permission: other */
   const MODE4_WOTH = 0x002;  /* write permission: other */
   const MODE4_XOTH = 0x001;  /* execute permission: other */
        
   /*
    * Field definitions for the fattr4_mode attribute
    */
   const MODE4_SUID = 0x800;  /* set user id on execution */
   const MODE4_SGID = 0x400;  /* set group id on execution */
   const MODE4_SVTX = 0x200;  /* save text even after use */
   const MODE4_RUSR = 0x100;  /* read permission: owner */
   const MODE4_WUSR = 0x080;  /* write permission: owner */
   const MODE4_XUSR = 0x040;  /* execute permission: owner */
   const MODE4_RGRP = 0x020;  /* read permission: group */
   const MODE4_WGRP = 0x010;  /* write permission: group */
   const MODE4_XGRP = 0x008;  /* execute permission: group */
   const MODE4_ROTH = 0x004;  /* read permission: other */
   const MODE4_WOTH = 0x002;  /* write permission: other */
   const MODE4_XOTH = 0x001;  /* execute permission: other */
        
   /*
    * Special data/attribute associated with
    * file types NF4BLK and NF4CHR.
    */
   struct specdata4 {
           uint32_t        specdata1;      /* major device number */
        
   /*
    * Special data/attribute associated with
    * file types NF4BLK and NF4CHR.
    */
   struct specdata4 {
           uint32_t        specdata1;      /* major device number */
        
           uint32_t        specdata2;      /* minor device number */
   };
        
           uint32_t        specdata2;      /* minor device number */
   };
        
   /*
    * 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 utf8str_cs      fattr4_mimetype;
   typedef mode4           fattr4_mode;
        
   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 utf8str_cs      fattr4_mimetype;
   typedef mode4           fattr4_mode;
        
   typedef uint64_t        fattr4_mounted_on_fileid;
   typedef bool            fattr4_no_trunc;
   typedef uint32_t        fattr4_numlinks;
   typedef utf8str_mixed   fattr4_owner;
   typedef utf8str_mixed   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 uint64_t        fattr4_mounted_on_fileid;
   typedef bool            fattr4_no_trunc;
   typedef uint32_t        fattr4_numlinks;
   typedef utf8str_mixed   fattr4_owner;
   typedef utf8str_mixed   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;
   const FATTR4_FILEHANDLE         = 19;
        
   /*
    * 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;
   const FATTR4_FILEHANDLE         = 19;
        
   /*
    * Recommended Attributes
    */
   const FATTR4_ACL                = 12;
   const FATTR4_ACLSUPPORT         = 13;
   const FATTR4_ARCHIVE            = 14;
   const FATTR4_CANSETTIME         = 15;
        
   /*
    * 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_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_MOUNTED_ON_FILEID  = 55;
        
   const FATTR4_CASE_INSENSITIVE   = 16;
   const FATTR4_CASE_PRESERVING    = 17;
   const FATTR4_CHOWN_RESTRICTED   = 18;
   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_MOUNTED_ON_FILEID  = 55;
        
   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 {
           uint32_t        cb_program;
           clientaddr4     cb_location;
   };
        
   /*
    * Callback program info as provided by the client
    */
   struct cb_client4 {
           uint32_t        cb_program;
           clientaddr4     cb_location;
   };
        
   /*
    * Stateid
    */
   struct stateid4 {
           uint32_t        seqid;
           opaque          other[12];
   };
        
   /*
    * Stateid
    */
   struct stateid4 {
           uint32_t        seqid;
           opaque          other[12];
   };
        
   /*
    * Client ID
    */
   struct nfs_client_id4 {
           verifier4       verifier;
           opaque          id<NFS4_OPAQUE_LIMIT>;
   };
        
   /*
    * Client ID
    */
   struct nfs_client_id4 {
           verifier4       verifier;
           opaque          id<NFS4_OPAQUE_LIMIT>;
   };
        
   struct open_owner4 {
           clientid4       clientid;
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
   struct open_owner4 {
           clientid4       clientid;
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
   struct lock_owner4 {
           clientid4       clientid;
        
   struct lock_owner4 {
           clientid4       clientid;
        
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
   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
    */
   const ACCESS4_READ      = 0x00000001;
   const ACCESS4_LOOKUP    = 0x00000002;
   const ACCESS4_MODIFY    = 0x00000004;
   const ACCESS4_EXTEND    = 0x00000008;
   const ACCESS4_DELETE    = 0x00000010;
   const ACCESS4_EXECUTE   = 0x00000020;
        
   /*
    * 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;
        
   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 reservations
    */
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        open_stateid;
   };
        
   /*
    * CLOSE: Close a file and release share reservations
    */
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        open_stateid;
   };
        

union CLOSE4res switch (nfsstat4 status) { case NFS4_OK:

union CLOSE4res开关(nfsstat4状态){情况NFS4_正常:

            stateid4       open_stateid;
    default:
            void;
   };
        
            stateid4       open_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 non-regular file
    */
   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4      linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4      devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
    default:
            void;          /* server should return NFS4ERR_BADTYPE */
   };
        
   /*
    * CREATE: Create a non-regular file
    */
   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4      linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4      devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
    default:
            void;          /* server should return NFS4ERR_BADTYPE */
   };
        
   struct CREATE4args {
           /* CURRENT_FH: directory for creation */
           createtype4     objtype;
           component4      objname;
           fattr4          createattrs;
        
   struct CREATE4args {
           /* CURRENT_FH: directory for creation */
           createtype4     objtype;
           component4      objname;
           fattr4          createattrs;
        

};

};

   struct CREATE4resok {
           change_info4    cinfo;
           bitmap4         attrset;        /* attributes set */
   };
        
   struct CREATE4resok {
           change_info4    cinfo;
           bitmap4         attrset;        /* attributes set */
   };
        
   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 {
           clientid4       clientid;
   };
        
   /*
    * DELEGPURGE: Purge Delegations Awaiting Recovery
    */
   struct DELEGPURGE4args {
           clientid4       clientid;
   };
        
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
   /*
    * DELEGRETURN: Return a delegation
    */
   struct DELEGRETURN4args {
           /* CURRENT_FH: delegated file */
           stateid4        deleg_stateid;
   };
        
   /*
    * DELEGRETURN: Return a delegation
    */
   struct DELEGRETURN4args {
           /* CURRENT_FH: delegated file */
           stateid4        deleg_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:
           void;
   };
        
   union GETFH4res switch (nfsstat4 status) {
    case NFS4_OK:
           GETFH4resok     resok4;
    default:
           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;
   };
        
   /*
    * For LOCK, transition from open_owner to new lock_owner
    */
   struct open_to_lock_owner4 {
           seqid4          open_seqid;
           stateid4        open_stateid;
           seqid4          lock_seqid;
        
   /*
    * For LOCK, transition from open_owner to new lock_owner
    */
   struct open_to_lock_owner4 {
           seqid4          open_seqid;
           stateid4        open_stateid;
           seqid4          lock_seqid;
        
           lock_owner4     lock_owner;
   };
        
           lock_owner4     lock_owner;
   };
        
   /*
    * For LOCK, existing lock_owner continues to request file locks
    */
   struct exist_lock_owner4 {
           stateid4        lock_stateid;
           seqid4          lock_seqid;
   };
        
   /*
    * For LOCK, existing lock_owner continues to request file locks
    */
   struct exist_lock_owner4 {
           stateid4        lock_stateid;
           seqid4          lock_seqid;
   };
        
   union locker4 switch (bool new_lock_owner) {
    case TRUE:
           open_to_lock_owner4     open_owner;
    case FALSE:
           exist_lock_owner4       lock_owner;
   };
        
   union locker4 switch (bool new_lock_owner) {
    case TRUE:
           open_to_lock_owner4     open_owner;
    case FALSE:
           exist_lock_owner4       lock_owner;
   };
        
   /*
    * LOCK/LOCKT/LOCKU: Record lock management
    */
   struct LOCK4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           bool            reclaim;
           offset4         offset;
           length4         length;
           locker4         locker;
   };
        
   /*
    * LOCK/LOCKT/LOCKU: Record lock management
    */
   struct LOCK4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           bool            reclaim;
           offset4         offset;
           length4         length;
           locker4         locker;
   };
        
   struct LOCK4denied {
           offset4         offset;
           length4         length;
           nfs_lock_type4  locktype;
           lock_owner4     owner;
   };
        
   struct LOCK4denied {
           offset4         offset;
           length4         length;
           nfs_lock_type4  locktype;
           lock_owner4     owner;
   };
        
   struct LOCK4resok {
           stateid4        lock_stateid;
   };
        
   struct LOCK4resok {
           stateid4        lock_stateid;
   };
        
   union LOCK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LOCK4resok     resok4;
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    default:
            void;
        
   union LOCK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LOCK4resok     resok4;
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    default:
            void;
        

};

};

   struct LOCKT4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           offset4         offset;
           length4         length;
           lock_owner4     owner;
   };
        
   struct LOCKT4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           offset4         offset;
           length4         length;
           lock_owner4     owner;
   };
        
   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        lock_stateid;
           offset4         offset;
           length4         length;
   };
        
   struct LOCKU4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           stateid4        lock_stateid;
           offset4         offset;
           length4         length;
   };
        
   union LOCKU4res switch (nfsstat4 status) {
    case   NFS4_OK:
            stateid4       lock_stateid;
    default:
            void;
   };
        
   union LOCKU4res switch (nfsstat4 status) {
    case   NFS4_OK:
            stateid4       lock_stateid;
    default:
            void;
   };
        
   /*
    * LOOKUP: Lookup filename
    */
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           component4      objname;
   };
        
   /*
    * LOOKUP: Lookup filename
    */
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           component4      objname;
   };
        
   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 {
           stateid4        delegate_stateid;
        
   struct open_claim_delegate_cur4 {
           stateid4        delegate_stateid;
        
           component4      file;
   };
        
           component4      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 */
           component4      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 */
           component4      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 */
           open_delegation_type4   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 */
           open_delegation_type4   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 */
           component4      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 */
           component4      file_delegate_prev;
   };
        
   /*
    * OPEN: Open a file, potentially receiving an open delegation
    */
   struct OPEN4args {
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
           open_owner4     owner;
           openflag4       openhow;
           open_claim4     claim;
   };
        
   /*
    * OPEN: Open a file, potentially receiving an open delegation
    */
   struct OPEN4args {
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
           open_owner4     owner;
           openflag4       openhow;
           open_claim4     claim;
   };
        
   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;
   };
   /*
    * Result flags
    */
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
   /* Type of file locking behavior at the server */
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;
        
   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
    */
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
   /* Type of file locking behavior at the server */
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;
        
   struct OPEN4resok {
           stateid4        stateid;        /* Stateid for open */
        
   struct OPEN4resok {
           stateid4        stateid;        /* Stateid for open */
        
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           bitmap4         attrset;        /* attribute set for create*/
           open_delegation4 delegation;    /* Info on any open
                                              delegation */
   };
        
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           bitmap4         attrset;        /* attribute set for create*/
           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 OPENATTR4args {
           /* CURRENT_FH: object */
           bool    createdir;
   };
        
   /*
    * OPENATTR: open named attributes directory
    */
   struct OPENATTR4args {
           /* CURRENT_FH: object */
           bool    createdir;
   };
        
   struct OPENATTR4res {
           /* CURRENT_FH: named attr directory */
           nfsstat4        status;
   };
        
   struct OPENATTR4res {
           /* CURRENT_FH: named attr directory */
           nfsstat4        status;
   };
        
   /*
    * OPEN_CONFIRM: confirm the open
    */
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
   };
        
   /*
    * OPEN_CONFIRM: confirm the open
    */
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
   };
        
   struct OPEN_CONFIRM4resok {
           stateid4        open_stateid;
   };
        
   struct OPEN_CONFIRM4resok {
           stateid4        open_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 {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   /*
    * OPEN_DOWNGRADE: downgrade the access/deny for a file
    */
   struct OPEN_DOWNGRADE4args {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };
        
   struct OPEN_DOWNGRADE4resok {
           stateid4        open_stateid;
   };
        
   struct OPEN_DOWNGRADE4resok {
           stateid4        open_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 {
        
   /*
    * PUTROOTFH: Set root filehandle
    */
   struct PUTROOTFH4res {
        
           /* CURRENT_FH: root fh */
        
           /* CURRENT_FH: root fh */
        
           nfsstat4        status;
   };
        
           nfsstat4        status;
   };
        
   /*
    * READ: Read from file
    */
   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };
        
   /*
    * READ: Read from file
    */
   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 {
           clientid4       clientid;
   };
        
   /*
    * RENEW: Renew a Lease
    */
   struct RENEW4args {
           clientid4       clientid;
   };
        
   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
    */
   struct SAVEFH4res {
           /* SAVED_FH: value of current fh */
           nfsstat4        status;
        
   /*
    * SAVEFH: Save current filehandle
    */
   struct SAVEFH4res {
           /* SAVED_FH: value of current fh */
           nfsstat4        status;
        

};

};

   /*
    * SECINFO: Obtain Available Security Mechanisms
    */
   struct SECINFO4args {
           /* CURRENT_FH: directory */
           component4      name;
   };
        
   /*
    * SECINFO: Obtain Available Security Mechanisms
    */
   struct SECINFO4args {
           /* CURRENT_FH: directory */
           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;
   };
        
   /* RPCSEC_GSS has a value of '6' - See RFC 2203 */
   union secinfo4 switch (uint32_t flavor) {
    case RPCSEC_GSS:
            rpcsec_gss_info        flavor_info;
    default:
            void;
   };
        
   /* RPCSEC_GSS has a value of '6' - See RFC 2203 */
   union secinfo4 switch (uint32_t flavor) {
    case RPCSEC_GSS:
            rpcsec_gss_info        flavor_info;
    default:
            void;
   };
        
   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 */
        
   /*
    * SETATTR: Set attributes
    */
   struct SETATTR4args {
           /* CURRENT_FH: target object */
        
           stateid4        stateid;
           fattr4          obj_attributes;
   };
        
           stateid4        stateid;
           fattr4          obj_attributes;
   };
        
   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };
        
   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };
        
   /*
    * SETCLIENTID
    */
   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
           uint32_t        callback_ident;
        
   /*
    * SETCLIENTID
    */
   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
           uint32_t        callback_ident;
        

};

};

   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 {
           clientid4       clientid;
           verifier4       setclientid_confirm;
   };
        
   struct SETCLIENTID_CONFIRM4args {
           clientid4       clientid;
           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
    */
   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };
        
   /*
    * WRITE: Write to file
    */
   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;
   };
        
   /*
    * RELEASE_LOCKOWNER: Notify server to release lockowner
    */
   struct RELEASE_LOCKOWNER4args {
           lock_owner4     lock_owner;
   };
        
   /*
    * RELEASE_LOCKOWNER: Notify server to release lockowner
    */
   struct RELEASE_LOCKOWNER4args {
           lock_owner4     lock_owner;
   };
        
   struct RELEASE_LOCKOWNER4res {
           nfsstat4        status;
   };
        
   struct RELEASE_LOCKOWNER4res {
           nfsstat4        status;
   };
        
   /*
        
   /*
        
    * ILLEGAL: Response for illegal operation numbers
    */
   struct ILLEGAL4res {
           nfsstat4        status;
   };
        
    * ILLEGAL: Response for illegal operation numbers
    */
   struct ILLEGAL4res {
           nfsstat4        status;
   };
        
   /*
    * 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, 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_RELEASE_LOCKOWNER = 39,

枚举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=20,OP_OPEN=21,OP_-putu=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=36,OP_VERIFY=37,OP_WRITE=38,OP_RELEASE\u LOCKOWNER=39,

OP_ILLEGAL = 10044 };

OP_非法=10044};

   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:      OPENATTR4args opopenattr;
    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_RELEASE_LOCKOWNER:     RELEASE_LOCKOWNER4args
                                       oprelease_lockowner;
    case OP_ILLEGAL:       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:      OPENATTR4args opopenattr;
    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_RELEASE_LOCKOWNER:     RELEASE_LOCKOWNER4args
                                       oprelease_lockowner;
    case OP_ILLEGAL:       void;
   };
        
   union nfs_resop4 switch (nfs_opnum4 resop){
    case OP_ACCESS:        ACCESS4res opaccess;
        
   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_RELEASE_LOCKOWNER:     RELEASE_LOCKOWNER4res
                                       oprelease_lockowner;
    case OP_ILLEGAL:       ILLEGAL4res opillegal;
   };
        
    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_RELEASE_LOCKOWNER:     RELEASE_LOCKOWNER4res
                                       oprelease_lockowner;
    case OP_ILLEGAL:       ILLEGAL4res opillegal;
   };
        
   struct COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        
   struct COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        

struct COMPOUND4res {

结构复合4res{

           nfsstat4 status;
           utf8str_cs      tag;
           nfs_resop4      resarray<>;
   };
        
           nfsstat4 status;
           utf8str_cs      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 {
        
   /*
    * CB_RECALL: Recall an Open Delegation
    */
   struct CB_RECALL4args {
        
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
   /*
    * CB_ILLEGAL: Response for illegal operation numbers
    */
   struct CB_ILLEGAL4res {
           nfsstat4        status;
   };
        
   /*
    * CB_ILLEGAL: Response for illegal operation numbers
    */
   struct CB_ILLEGAL4res {
           nfsstat4        status;
   };
        
   /*
    * Various definitions for CB_COMPOUND
    */
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4,
           OP_CB_ILLEGAL           = 10044
   };
        
   /*
    * Various definitions for CB_COMPOUND
    */
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4,
           OP_CB_ILLEGAL           = 10044
   };
        
   union nfs_cb_argop4 switch (unsigned argop) {
    case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
    case OP_CB_ILLEGAL:    void;
   };
        
   union nfs_cb_argop4 switch (unsigned argop) {
    case OP_CB_GETATTR:    CB_GETATTR4args opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4args  opcbrecall;
    case OP_CB_ILLEGAL:    void;
   };
        
   union nfs_cb_resop4 switch (unsigned resop){
    case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4res   opcbrecall;
    case OP_CB_ILLEGAL:    CB_ILLEGAL4res  opcbillegal;
   };
        
   union nfs_cb_resop4 switch (unsigned resop){
    case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4res   opcbrecall;
    case OP_CB_ILLEGAL:    CB_ILLEGAL4res  opcbillegal;
   };
        
   struct CB_COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           uint32_t        callback_ident;
           nfs_cb_argop4   argarray<>;
   };
        
   struct CB_COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           uint32_t        callback_ident;
           nfs_cb_argop4   argarray<>;
   };
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
           utf8str_cs      tag;
           nfs_cb_resop4   resarray<>;
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
           utf8str_cs      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;
   } = 0x40000000;
        
   /*
    * 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;
   } = 0x40000000;
        
19. Acknowledgements
19. 致谢

The authors thank and acknowledge:

作者感谢并承认:

Neil Brown for his extensive review and comments of various documents. Rick Macklem at the University of Guelph, Mike Frisch, Sergey Klyushin, and Dan Trufasiu of Hummingbird Ltd., and Andy Adamson, Bruce Fields, Jim Rees, and Kendrick Smith from the CITI organization at the University of Michigan, for their implementation efforts and feedback on the protocol specification. Mike Kupfer for his review of the file locking and ACL mechanisms. Alan Yoder for his input to ACL mechanisms. Peter Astrand for his close review of the protocol specification. Ran Atkinson for his constant reminder that users do matter.

尼尔·布朗感谢他对各种文件的广泛审查和评论。Rick Macklem,盖尔弗大学,Mike Frisch,Sergey Klyushin和Dan Trufasiu的蜂鸟有限公司,Andy Adamson,布鲁斯字段,Jim Rees,和来自CITI组织在密歇根大学,为他们的执行工作和对协议规范的反馈。Mike Kupfer感谢他对文件锁定和ACL机制的回顾。Alan Yoder感谢他对ACL机制的投入。Peter Astrand感谢他对协议规范的仔细审查。运行阿特金森为他不断提醒,用户做的事情。

20. Normative References
20. 规范性引用文件

[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.国际标准——信息技术——通用多八位编码字符集(UCS)——第1部分:体系结构和基本多语言平面。”

[RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.

[RFC793]Postel,J.,“传输控制协议”,标准7,RFC 793,1981年9月。

[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月。

[RFC2373] Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 2373, July 1998.

[RFC2373]Hinden,R.和S.Deering,“IP版本6寻址体系结构”,RFC 23731998年7月。

[RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC 1964, June 1996.

[RFC1964]Linn,J.,“Kerberos版本5 GSS-API机制”,RFC19641996年6月。

[RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", RFC 2025, October 1996.

[RFC2025]Adams,C.,“简单公钥GSS-API机制(SPKM)”,RFC 20252996年10月。

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2119]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[RFC2203] Eisler, M., Chiu, A. and L. Ling, "RPCSEC_GSS Protocol Specification", RFC 2203, September 1997.

[RFC2203]Eisler,M.,Chiu,A.和L.Ling,“RPCSEC_GSS协议规范”,RFC 2203,1997年9月。

[RFC2277] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 19, RFC 2277, January 1998.

[RFC2277]Alvestrand,H.,“IETF字符集和语言政策”,BCP 19,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月。

[RFC2743] Linn, J., "Generic Security Service Application Program Interface, Version 2, Update 1", RFC 2743, January 2000.

[RFC2743]Linn,J.,“通用安全服务应用程序接口,版本2,更新1”,RFC 2743,2000年1月。

[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月。

[RFC3010] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame, C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC 3010, December 2000.

[RFC3010]Shepler,S.,Callaghan,B.,Robinson,D.,Thurlow,R.,Beame,C.,Eisler,M.和D.Noveck,“NFS版本4协议”,RFC3010,2000年12月。

[RFC3454] Hoffman, P. and P. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002.

[RFC3454]Hoffman,P.和P.Blanchet,“国际化弦的准备(“stringprep”)”,RFC 3454,2002年12月。

[Unicode1] The Unicode Consortium, "The Unicode Standard, Version 3.0", Addison-Wesley Developers Press, Reading, MA, 2000. ISBN 0-201-61633-5.

[Unicode1]Unicode联盟,“Unicode标准,3.0版”,Addison-Wesley开发者出版社,马萨诸塞州雷丁市,2000年。ISBN 0-201-61633-5。

                             More information available at:
                             http://www.unicode.org/
        
                             More information available at:
                             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]“不支持的脚本”Unicode,Inc.,Unicode联盟,邮政信箱700519,美国加利福尼亚州圣何塞市,邮编95710-0519,1999年9月。http://www.unicode.org/unicode/standard/ 不支持的.html

21. Informative References
21. 资料性引用

[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日。

[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月。

[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月。

[RFC3232] Reynolds, J., Editor, "Assigned Numbers: RFC 1700 is Replaced by an On-line Database", RFC 3232, January 2002.

[RFC3232]Reynolds,J.,编辑,“分配号码:RFC 1700被在线数据库取代”,RFC 3232,2002年1月。

[RFC1833] Srinivasan, R., "Binding Protocols for ONC RPC Version 2", RFC 1833, August 1995.

[RFC1833]Srinivasan,R.,“ONC RPC版本2的绑定协议”,RFC 1833,1995年8月。

[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月。

[RFC2152] Goldsmith, D. and M. Davis, "UTF-7 A Mail-Safe Transformation Format of Unicode", RFC 2152, May 1997.

[RFC2152]Goldsmith,D.和M.Davis,“UTF-7 Unicode的邮件安全转换格式”,RFC 2152,1997年5月。

[RFC2224] Callaghan, B., "NFS URL Scheme", RFC 2224, October 1997.

[RFC2224]Callaghan,B.,“NFS URL方案”,RFC2224,1997年10月。

[RFC2624] Shepler, S., "NFS Version 4 Design Considerations", RFC 2624, June 1999.

[RFC2624]Shepler,S.,“NFS版本4设计注意事项”,RFC 26242999年6月。

[RFC2755] Chiu, A., Eisler, M. and B. Callaghan, "Security Negotiation for WebNFS" , RFC 2755, June 2000.

[RFC2755]Chiu,A.,Eisler,M.和B.Callaghan,“WebNFS的安全协商”,RFC 27552000年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]中介绍了有状态环境中的恢复问题。

[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.

[XNFS]开放组,互通协议:XNFS,版本3W,开放组,1010 El Camino Real Suite 380,Menlo Park,CA 94025,ISBN 1-85912-184-51998年2月。

                             HTML version available:
                             http://www.opengroup.org
        
                             HTML version available:
                             http://www.opengroup.org
        
22. Authors' Information
22. 作者信息
22.1. Editor's Address
22.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
        
22.2. Authors' Addresses
22.2. 作者地址

Carl Beame Hummingbird Ltd.

卡尔·比姆蜂鸟有限公司。

   EMail: beame@bws.com
        
   EMail: beame@bws.com
        

Brent Callaghan Sun Microsystems, Inc. 17 Network Circle Menlo Park, CA 94025

Brent Callaghan Sun Microsystems,Inc.加利福尼亚州门罗公园17号网络圈,邮编94025

   Phone: +1 650-786-5067
   EMail: brent.callaghan@sun.com
        
   Phone: +1 650-786-5067
   EMail: brent.callaghan@sun.com
        

Mike Eisler 5765 Chase Point Circle Colorado Springs, CO 80919

迈克·艾斯勒5765美国科罗拉多州科罗拉多斯普林斯蔡斯角环线,邮编: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-768-5347
   EMail: dnoveck@netapp.com
        
   Phone: +1 781-768-5347
   EMail: dnoveck@netapp.com
        

David Robinson Sun Microsystems, Inc. 5300 Riata Park Court Austin, TX 78727

David Robinson Sun Microsystems,Inc.德克萨斯州奥斯汀Riata Park Court 5300号,邮编:78727

   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. 500 Eldorado Blvd. Broomfield, CO 80021

罗伯特·瑟洛太阳微系统公司,埃尔多拉多大道500号。美国科罗拉多州布鲁姆菲尔德80021

   Phone: +1 650-786-5096
   EMail: robert.thurlow@sun.com
        
   Phone: +1 650-786-5096
   EMail: robert.thurlow@sun.com
        
23. Full Copyright Statement
23. 完整版权声明

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

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

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编辑功能的资金目前由互联网协会提供。