Internet Engineering Task Force (IETF)                   S. Shepler, Ed.
Request for Comments: 5661                               Storspeed, Inc.
Category: Standards Track                                 M. Eisler, Ed.
ISSN: 2070-1721                                           D. Noveck, Ed.
                                                                  NetApp
                                                            January 2010
        
Internet Engineering Task Force (IETF)                   S. Shepler, Ed.
Request for Comments: 5661                               Storspeed, Inc.
Category: Standards Track                                 M. Eisler, Ed.
ISSN: 2070-1721                                           D. Noveck, Ed.
                                                                  NetApp
                                                            January 2010
        

Network File System (NFS) Version 4 Minor Version 1 Protocol

网络文件系统(NFS)版本4次要版本1协议

Abstract

摘要

This document describes the Network File System (NFS) version 4 minor version 1, including features retained from the base protocol (NFS version 4 minor version 0, which is specified in RFC 3530) and protocol extensions made subsequently. Major extensions introduced in NFS version 4 minor version 1 include Sessions, Directory Delegations, and parallel NFS (pNFS). NFS version 4 minor version 1 has no dependencies on NFS version 4 minor version 0, and it is considered a separate protocol. Thus, this document neither updates nor obsoletes RFC 3530. NFS minor version 1 is deemed superior to NFS minor version 0 with no loss of functionality, and its use is preferred over version 0. Both NFS minor versions 0 and 1 can be used simultaneously on the same network, between the same client and server.

本文档介绍网络文件系统(NFS)版本4次要版本1,包括从基本协议(NFS版本4次要版本0,在RFC 3530中指定)保留的功能以及随后进行的协议扩展。NFS版本4次要版本1中引入的主要扩展包括会话、目录委派和并行NFS(pNFS)。NFS版本4次要版本1与NFS版本4次要版本0没有依赖关系,它被视为一个单独的协议。因此,本文件既不更新也不废弃RFC 3530。NFS次要版本1被视为优于NFS次要版本0,且不会丢失功能,并且其使用优于版本0。NFS次要版本0和1都可以在同一网络上、同一客户端和服务器之间同时使用。

Status of This Memo

关于下段备忘

This is an Internet Standards Track document.

这是一份互联网标准跟踪文件。

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.

本文件是互联网工程任务组(IETF)的产品。它代表了IETF社区的共识。它已经接受了公众审查,并已被互联网工程指导小组(IESG)批准出版。有关互联网标准的更多信息,请参见RFC 5741第2节。

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc5661.

有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问http://www.rfc-editor.org/info/rfc5661.

Copyright Notice

版权公告

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved.

版权所有(c)2010 IETF信托基金和确定为文件作者的人员。版权所有。

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(http://trustee.ietf.org/license-info)自本文件出版之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包括信托法律条款第4.e节中所述的简化BSD许可证文本,并提供简化BSD许可证中所述的无担保。

Table of Contents

目录

   1. Introduction ....................................................9
      1.1. The NFS Version 4 Minor Version 1 Protocol .................9
      1.2. Requirements Language ......................................9
      1.3. Scope of This Document .....................................9
      1.4. NFSv4 Goals ...............................................10
      1.5. NFSv4.1 Goals .............................................10
      1.6. General Definitions .......................................11
      1.7. Overview of NFSv4.1 Features ..............................13
      1.8. Differences from NFSv4.0 ..................................17
   2. Core Infrastructure ............................................18
      2.1. Introduction ..............................................18
      2.2. RPC and XDR ...............................................19
      2.3. COMPOUND and CB_COMPOUND ..................................22
      2.4. Client Identifiers and Client Owners ......................23
      2.5. Server Owners .............................................28
      2.6. Security Service Negotiation ..............................29
      2.7. Minor Versioning ..........................................34
      2.8. Non-RPC-Based Security Services ...........................37
      2.9. Transport Layers ..........................................37
      2.10. Session ..................................................40
   3. Protocol Constants and Data Types ..............................86
      3.1. Basic Constants ...........................................86
      3.2. Basic Data Types ..........................................87
      3.3. Structured Data Types .....................................89
   4. Filehandles ....................................................97
      4.1. Obtaining the First Filehandle ............................98
      4.2. Filehandle Types ..........................................99
      4.3. One Method of Constructing a Volatile Filehandle .........101
      4.4. Client Recovery from Filehandle Expiration ...............102
   5. File Attributes ...............................................103
      5.1. REQUIRED Attributes ......................................104
      5.2. RECOMMENDED Attributes ...................................104
      5.3. Named Attributes .........................................105
      5.4. Classification of Attributes .............................106
      5.5. Set-Only and Get-Only Attributes .........................107
      5.6. REQUIRED Attributes - List and Definition References .....107
      5.7. RECOMMENDED Attributes - List and Definition References ..108
      5.8. Attribute Definitions ....................................110
      5.9. Interpreting owner and owner_group .......................119
      5.10. Character Case Attributes ...............................121
      5.11. Directory Notification Attributes .......................121
      5.12. pNFS Attribute Definitions ..............................122
      5.13. Retention Attributes ....................................123
   6. Access Control Attributes .....................................126
      6.1. Goals ....................................................126
      6.2. File Attributes Discussion ...............................128
        
   1. Introduction ....................................................9
      1.1. The NFS Version 4 Minor Version 1 Protocol .................9
      1.2. Requirements Language ......................................9
      1.3. Scope of This Document .....................................9
      1.4. NFSv4 Goals ...............................................10
      1.5. NFSv4.1 Goals .............................................10
      1.6. General Definitions .......................................11
      1.7. Overview of NFSv4.1 Features ..............................13
      1.8. Differences from NFSv4.0 ..................................17
   2. Core Infrastructure ............................................18
      2.1. Introduction ..............................................18
      2.2. RPC and XDR ...............................................19
      2.3. COMPOUND and CB_COMPOUND ..................................22
      2.4. Client Identifiers and Client Owners ......................23
      2.5. Server Owners .............................................28
      2.6. Security Service Negotiation ..............................29
      2.7. Minor Versioning ..........................................34
      2.8. Non-RPC-Based Security Services ...........................37
      2.9. Transport Layers ..........................................37
      2.10. Session ..................................................40
   3. Protocol Constants and Data Types ..............................86
      3.1. Basic Constants ...........................................86
      3.2. Basic Data Types ..........................................87
      3.3. Structured Data Types .....................................89
   4. Filehandles ....................................................97
      4.1. Obtaining the First Filehandle ............................98
      4.2. Filehandle Types ..........................................99
      4.3. One Method of Constructing a Volatile Filehandle .........101
      4.4. Client Recovery from Filehandle Expiration ...............102
   5. File Attributes ...............................................103
      5.1. REQUIRED Attributes ......................................104
      5.2. RECOMMENDED Attributes ...................................104
      5.3. Named Attributes .........................................105
      5.4. Classification of Attributes .............................106
      5.5. Set-Only and Get-Only Attributes .........................107
      5.6. REQUIRED Attributes - List and Definition References .....107
      5.7. RECOMMENDED Attributes - List and Definition References ..108
      5.8. Attribute Definitions ....................................110
      5.9. Interpreting owner and owner_group .......................119
      5.10. Character Case Attributes ...............................121
      5.11. Directory Notification Attributes .......................121
      5.12. pNFS Attribute Definitions ..............................122
      5.13. Retention Attributes ....................................123
   6. Access Control Attributes .....................................126
      6.1. Goals ....................................................126
      6.2. File Attributes Discussion ...............................128
        
      6.3. Common Methods ...........................................144
      6.4. Requirements .............................................147
   7. Single-Server Namespace .......................................153
      7.1. Server Exports ...........................................153
      7.2. Browsing Exports .........................................153
      7.3. Server Pseudo File System ................................154
      7.4. Multiple Roots ...........................................155
      7.5. Filehandle Volatility ....................................155
      7.6. Exported Root ............................................155
      7.7. Mount Point Crossing .....................................156
      7.8. Security Policy and Namespace Presentation ...............156
   8. State Management ..............................................157
      8.1. Client and Session ID ....................................158
      8.2. Stateid Definition .......................................158
      8.3. Lease Renewal ............................................167
      8.4. Crash Recovery ...........................................170
      8.5. Server Revocation of Locks ...............................181
      8.6. Short and Long Leases ....................................182
      8.7. Clocks, Propagation Delay, and Calculating Lease
           Expiration ...............................................182
      8.8. Obsolete Locking Infrastructure from NFSv4.0 .............183
   9. File Locking and Share Reservations ...........................184
      9.1. Opens and Byte-Range Locks ...............................184
      9.2. Lock Ranges ..............................................188
      9.3. Upgrading and Downgrading Locks ..........................188
      9.4. Stateid Seqid Values and Byte-Range Locks ................189
      9.5. Issues with Multiple Open-Owners .........................189
      9.6. Blocking Locks ...........................................190
      9.7. Share Reservations .......................................191
      9.8. OPEN/CLOSE Operations ....................................192
      9.9. Open Upgrade and Downgrade ...............................192
      9.10. Parallel OPENs ..........................................193
      9.11. Reclaim of Open and Byte-Range Locks ....................194
   10. Client-Side Caching ..........................................194
      10.1. Performance Challenges for Client-Side Caching ..........195
      10.2. Delegation and Callbacks ................................196
      10.3. Data Caching ............................................200
      10.4. Open Delegation .........................................205
      10.5. Data Caching and Revocation .............................216
      10.6. Attribute Caching .......................................218
      10.7. Data and Metadata Caching and Memory Mapped Files .......220
      10.8. Name and Directory Caching without Directory
            Delegations .............................................222
      10.9. Directory Delegations ...................................225
   11. Multi-Server Namespace .......................................228
      11.1. Location Attributes .....................................228
      11.2. File System Presence or Absence .........................229
      11.3. Getting Attributes for an Absent File System ............230
        
      6.3. Common Methods ...........................................144
      6.4. Requirements .............................................147
   7. Single-Server Namespace .......................................153
      7.1. Server Exports ...........................................153
      7.2. Browsing Exports .........................................153
      7.3. Server Pseudo File System ................................154
      7.4. Multiple Roots ...........................................155
      7.5. Filehandle Volatility ....................................155
      7.6. Exported Root ............................................155
      7.7. Mount Point Crossing .....................................156
      7.8. Security Policy and Namespace Presentation ...............156
   8. State Management ..............................................157
      8.1. Client and Session ID ....................................158
      8.2. Stateid Definition .......................................158
      8.3. Lease Renewal ............................................167
      8.4. Crash Recovery ...........................................170
      8.5. Server Revocation of Locks ...............................181
      8.6. Short and Long Leases ....................................182
      8.7. Clocks, Propagation Delay, and Calculating Lease
           Expiration ...............................................182
      8.8. Obsolete Locking Infrastructure from NFSv4.0 .............183
   9. File Locking and Share Reservations ...........................184
      9.1. Opens and Byte-Range Locks ...............................184
      9.2. Lock Ranges ..............................................188
      9.3. Upgrading and Downgrading Locks ..........................188
      9.4. Stateid Seqid Values and Byte-Range Locks ................189
      9.5. Issues with Multiple Open-Owners .........................189
      9.6. Blocking Locks ...........................................190
      9.7. Share Reservations .......................................191
      9.8. OPEN/CLOSE Operations ....................................192
      9.9. Open Upgrade and Downgrade ...............................192
      9.10. Parallel OPENs ..........................................193
      9.11. Reclaim of Open and Byte-Range Locks ....................194
   10. Client-Side Caching ..........................................194
      10.1. Performance Challenges for Client-Side Caching ..........195
      10.2. Delegation and Callbacks ................................196
      10.3. Data Caching ............................................200
      10.4. Open Delegation .........................................205
      10.5. Data Caching and Revocation .............................216
      10.6. Attribute Caching .......................................218
      10.7. Data and Metadata Caching and Memory Mapped Files .......220
      10.8. Name and Directory Caching without Directory
            Delegations .............................................222
      10.9. Directory Delegations ...................................225
   11. Multi-Server Namespace .......................................228
      11.1. Location Attributes .....................................228
      11.2. File System Presence or Absence .........................229
      11.3. Getting Attributes for an Absent File System ............230
        
      11.4. Uses of Location Information ............................232
      11.5. Location Entries and Server Identity ....................236
      11.6. Additional Client-Side Considerations ...................237
      11.7. Effecting File System Transitions .......................238
      11.8. Effecting File System Referrals .........................251
      11.9. The Attribute fs_locations ..............................258
      11.10. The Attribute fs_locations_info ........................261
      11.11. The Attribute fs_status ................................273
   12. Parallel NFS (pNFS) ..........................................277
      12.1. Introduction ............................................277
      12.2. pNFS Definitions ........................................278
      12.3. pNFS Operations .........................................284
      12.4. pNFS Attributes .........................................285
      12.5. Layout Semantics ........................................285
      12.6. pNFS Mechanics ..........................................300
      12.7. Recovery ................................................302
      12.8. Metadata and Storage Device Roles .......................307
      12.9. Security Considerations for pNFS ........................307
   13. NFSv4.1 as a Storage Protocol in pNFS: the File Layout Type ..309
      13.1. Client ID and Session Considerations ....................309
      13.2. File Layout Definitions .................................312
      13.3. File Layout Data Types ..................................312
      13.4. Interpreting the File Layout ............................317
      13.5. Data Server Multipathing ................................324
      13.6. Operations Sent to NFSv4.1 Data Servers .................325
      13.7. COMMIT through Metadata Server ..........................327
      13.8. The Layout Iomode .......................................328
      13.9. Metadata and Data Server State Coordination .............329
      13.10. Data Server Component File Size ........................332
      13.11. Layout Revocation and Fencing ..........................333
      13.12. Security Considerations for the File Layout Type .......334
   14. Internationalization .........................................334
     14.1.  Stringprep profile for the utf8str_cs type ..............336
     14.2.  Stringprep profile for the utf8str_cis type .............337
     14.3.  Stringprep profile for the utf8str_mixed type ...........338
     14.4.  UTF-8 Capabilities ......................................340
     14.5.  UTF-8 Related Errors ....................................340
   15. Error Values .................................................341
      15.1. Error Definitions .......................................341
      15.2. Operations and Their Valid Errors .......................361
      15.3. Callback Operations and Their Valid Errors ..............376
      15.4. Errors and the Operations That Use Them .................379
   16. NFSv4.1 Procedures ...........................................391
      16.1. Procedure 0: NULL - No Operation ........................392
      16.2. Procedure 1: COMPOUND - Compound Operations .............392
   17. Operations: REQUIRED, RECOMMENDED, or OPTIONAL ...............403
   18. NFSv4.1 Operations ...........................................407
      18.1. Operation 3: ACCESS - Check Access Rights ...............407
        
      11.4. Uses of Location Information ............................232
      11.5. Location Entries and Server Identity ....................236
      11.6. Additional Client-Side Considerations ...................237
      11.7. Effecting File System Transitions .......................238
      11.8. Effecting File System Referrals .........................251
      11.9. The Attribute fs_locations ..............................258
      11.10. The Attribute fs_locations_info ........................261
      11.11. The Attribute fs_status ................................273
   12. Parallel NFS (pNFS) ..........................................277
      12.1. Introduction ............................................277
      12.2. pNFS Definitions ........................................278
      12.3. pNFS Operations .........................................284
      12.4. pNFS Attributes .........................................285
      12.5. Layout Semantics ........................................285
      12.6. pNFS Mechanics ..........................................300
      12.7. Recovery ................................................302
      12.8. Metadata and Storage Device Roles .......................307
      12.9. Security Considerations for pNFS ........................307
   13. NFSv4.1 as a Storage Protocol in pNFS: the File Layout Type ..309
      13.1. Client ID and Session Considerations ....................309
      13.2. File Layout Definitions .................................312
      13.3. File Layout Data Types ..................................312
      13.4. Interpreting the File Layout ............................317
      13.5. Data Server Multipathing ................................324
      13.6. Operations Sent to NFSv4.1 Data Servers .................325
      13.7. COMMIT through Metadata Server ..........................327
      13.8. The Layout Iomode .......................................328
      13.9. Metadata and Data Server State Coordination .............329
      13.10. Data Server Component File Size ........................332
      13.11. Layout Revocation and Fencing ..........................333
      13.12. Security Considerations for the File Layout Type .......334
   14. Internationalization .........................................334
     14.1.  Stringprep profile for the utf8str_cs type ..............336
     14.2.  Stringprep profile for the utf8str_cis type .............337
     14.3.  Stringprep profile for the utf8str_mixed type ...........338
     14.4.  UTF-8 Capabilities ......................................340
     14.5.  UTF-8 Related Errors ....................................340
   15. Error Values .................................................341
      15.1. Error Definitions .......................................341
      15.2. Operations and Their Valid Errors .......................361
      15.3. Callback Operations and Their Valid Errors ..............376
      15.4. Errors and the Operations That Use Them .................379
   16. NFSv4.1 Procedures ...........................................391
      16.1. Procedure 0: NULL - No Operation ........................392
      16.2. Procedure 1: COMPOUND - Compound Operations .............392
   17. Operations: REQUIRED, RECOMMENDED, or OPTIONAL ...............403
   18. NFSv4.1 Operations ...........................................407
      18.1. Operation 3: ACCESS - Check Access Rights ...............407
        
      18.2. Operation 4: CLOSE - Close File .........................413
      18.3. Operation 5: COMMIT - Commit Cached Data ................414
      18.4. Operation 6: CREATE - Create a Non-Regular File Object ..417
      18.5. Operation 7: DELEGPURGE - Purge Delegations
            Awaiting Recovery .......................................419
      18.6. Operation 8: DELEGRETURN - Return Delegation ............420
      18.7. Operation 9: GETATTR - Get Attributes ...................421
      18.8. Operation 10: GETFH - Get Current Filehandle ............423
      18.9. Operation 11: LINK - Create Link to a File ..............424
      18.10. Operation 12: LOCK - Create Lock .......................426
      18.11. Operation 13: LOCKT - Test for Lock ....................430
      18.12. Operation 14: LOCKU - Unlock File ......................432
      18.13. Operation 15: LOOKUP - Lookup Filename .................433
      18.14. Operation 16: LOOKUPP - Lookup Parent Directory ........435
      18.15. Operation 17: NVERIFY - Verify Difference in
             Attributes .............................................436
      18.16. Operation 18: OPEN - Open a Regular File ...............437
      18.17. Operation 19: OPENATTR - Open Named Attribute
             Directory ..............................................458
      18.18. Operation 21: OPEN_DOWNGRADE - Reduce Open File
             Access .................................................459
      18.19. Operation 22: PUTFH - Set Current Filehandle ...........461
      18.20. Operation 23: PUTPUBFH - Set Public Filehandle .........461
      18.21. Operation 24: PUTROOTFH - Set Root Filehandle ..........463
      18.22. Operation 25: READ - Read from File ....................464
      18.23. Operation 26: READDIR - Read Directory .................466
      18.24. Operation 27: READLINK - Read Symbolic Link ............469
      18.25. Operation 28: REMOVE - Remove File System Object .......470
      18.26. Operation 29: RENAME - Rename Directory Entry ..........473
      18.27. Operation 31: RESTOREFH - Restore Saved Filehandle .....477
      18.28. Operation 32: SAVEFH - Save Current Filehandle .........478
      18.29. Operation 33: SECINFO - Obtain Available Security ......479
      18.30. Operation 34: SETATTR - Set Attributes .................482
      18.31. Operation 37: VERIFY - Verify Same Attributes ..........485
      18.32. Operation 38: WRITE - Write to File ....................486
      18.33. Operation 40: BACKCHANNEL_CTL - Backchannel Control ....491
      18.34. Operation 41: BIND_CONN_TO_SESSION - Associate
             Connection with Session ................................492
      18.35. Operation 42: EXCHANGE_ID - Instantiate Client ID ......495
      18.36. Operation 43: CREATE_SESSION - Create New
             Session and Confirm Client ID ..........................513
      18.37. Operation 44: DESTROY_SESSION - Destroy a Session ......523
      18.38. Operation 45: FREE_STATEID - Free Stateid with
             No Locks ...............................................525
      18.39. Operation 46: GET_DIR_DELEGATION - Get a
             Directory Delegation ...................................526
      18.40. Operation 47: GETDEVICEINFO - Get Device Information ...530
      18.41. Operation 48: GETDEVICELIST - Get All Device
        
      18.2. Operation 4: CLOSE - Close File .........................413
      18.3. Operation 5: COMMIT - Commit Cached Data ................414
      18.4. Operation 6: CREATE - Create a Non-Regular File Object ..417
      18.5. Operation 7: DELEGPURGE - Purge Delegations
            Awaiting Recovery .......................................419
      18.6. Operation 8: DELEGRETURN - Return Delegation ............420
      18.7. Operation 9: GETATTR - Get Attributes ...................421
      18.8. Operation 10: GETFH - Get Current Filehandle ............423
      18.9. Operation 11: LINK - Create Link to a File ..............424
      18.10. Operation 12: LOCK - Create Lock .......................426
      18.11. Operation 13: LOCKT - Test for Lock ....................430
      18.12. Operation 14: LOCKU - Unlock File ......................432
      18.13. Operation 15: LOOKUP - Lookup Filename .................433
      18.14. Operation 16: LOOKUPP - Lookup Parent Directory ........435
      18.15. Operation 17: NVERIFY - Verify Difference in
             Attributes .............................................436
      18.16. Operation 18: OPEN - Open a Regular File ...............437
      18.17. Operation 19: OPENATTR - Open Named Attribute
             Directory ..............................................458
      18.18. Operation 21: OPEN_DOWNGRADE - Reduce Open File
             Access .................................................459
      18.19. Operation 22: PUTFH - Set Current Filehandle ...........461
      18.20. Operation 23: PUTPUBFH - Set Public Filehandle .........461
      18.21. Operation 24: PUTROOTFH - Set Root Filehandle ..........463
      18.22. Operation 25: READ - Read from File ....................464
      18.23. Operation 26: READDIR - Read Directory .................466
      18.24. Operation 27: READLINK - Read Symbolic Link ............469
      18.25. Operation 28: REMOVE - Remove File System Object .......470
      18.26. Operation 29: RENAME - Rename Directory Entry ..........473
      18.27. Operation 31: RESTOREFH - Restore Saved Filehandle .....477
      18.28. Operation 32: SAVEFH - Save Current Filehandle .........478
      18.29. Operation 33: SECINFO - Obtain Available Security ......479
      18.30. Operation 34: SETATTR - Set Attributes .................482
      18.31. Operation 37: VERIFY - Verify Same Attributes ..........485
      18.32. Operation 38: WRITE - Write to File ....................486
      18.33. Operation 40: BACKCHANNEL_CTL - Backchannel Control ....491
      18.34. Operation 41: BIND_CONN_TO_SESSION - Associate
             Connection with Session ................................492
      18.35. Operation 42: EXCHANGE_ID - Instantiate Client ID ......495
      18.36. Operation 43: CREATE_SESSION - Create New
             Session and Confirm Client ID ..........................513
      18.37. Operation 44: DESTROY_SESSION - Destroy a Session ......523
      18.38. Operation 45: FREE_STATEID - Free Stateid with
             No Locks ...............................................525
      18.39. Operation 46: GET_DIR_DELEGATION - Get a
             Directory Delegation ...................................526
      18.40. Operation 47: GETDEVICEINFO - Get Device Information ...530
      18.41. Operation 48: GETDEVICELIST - Get All Device
        
             Mappings for a File System .............................533
      18.42. Operation 49: LAYOUTCOMMIT - Commit Writes Made
             Using a Layout .........................................534
      18.43. Operation 50: LAYOUTGET - Get Layout Information .......538
      18.44. Operation 51: LAYOUTRETURN - Release Layout
             Information ............................................547
      18.45. Operation 52: SECINFO_NO_NAME - Get Security on
             Unnamed Object .........................................552
      18.46. Operation 53: SEQUENCE - Supply Per-Procedure
             Sequencing and Control .................................553
      18.47. Operation 54: SET_SSV - Update SSV for a Client ID .....559
      18.48. Operation 55: TEST_STATEID - Test Stateids for
             Validity ...............................................561
      18.49. Operation 56: WANT_DELEGATION - Request Delegation .....563
      18.50. Operation 57: DESTROY_CLIENTID - Destroy a Client ID ...566
      18.51. Operation 58: RECLAIM_COMPLETE - Indicates
             Reclaims Finished ......................................567
      18.52. Operation 10044: ILLEGAL - Illegal Operation ...........569
   19. NFSv4.1 Callback Procedures ..................................570
      19.1. Procedure 0: CB_NULL - No Operation .....................570
      19.2. Procedure 1: CB_COMPOUND - Compound Operations ..........571
   20. NFSv4.1 Callback Operations ..................................574
      20.1. Operation 3: CB_GETATTR - Get Attributes ................574
      20.2. Operation 4: CB_RECALL - Recall a Delegation ............575
      20.3. Operation 5: CB_LAYOUTRECALL - Recall Layout
            from Client .............................................576
      20.4. Operation 6: CB_NOTIFY - Notify Client of
            Directory Changes .......................................580
      20.5. Operation 7: CB_PUSH_DELEG - Offer Previously
            Requested Delegation to Client ..........................583
      20.6. Operation 8: CB_RECALL_ANY - Keep Any N
            Recallable Objects ......................................584
      20.7. Operation 9: CB_RECALLABLE_OBJ_AVAIL - Signal
            Resources for Recallable Objects ........................588
      20.8. Operation 10: CB_RECALL_SLOT - Change Flow
            Control Limits ..........................................588
      20.9. Operation 11: CB_SEQUENCE - Supply Backchannel
            Sequencing and Control ..................................589
      20.10. Operation 12: CB_WANTS_CANCELLED - Cancel
             Pending Delegation Wants ...............................592
      20.11. Operation 13: CB_NOTIFY_LOCK - Notify Client of
             Possible Lock Availability .............................593
      20.12. Operation 14: CB_NOTIFY_DEVICEID - Notify
             Client of Device ID Changes ............................594
      20.13. Operation 10044: CB_ILLEGAL - Illegal Callback
             Operation ..............................................596
   21. Security Considerations ......................................597
   22. IANA Considerations ..........................................598
        
             Mappings for a File System .............................533
      18.42. Operation 49: LAYOUTCOMMIT - Commit Writes Made
             Using a Layout .........................................534
      18.43. Operation 50: LAYOUTGET - Get Layout Information .......538
      18.44. Operation 51: LAYOUTRETURN - Release Layout
             Information ............................................547
      18.45. Operation 52: SECINFO_NO_NAME - Get Security on
             Unnamed Object .........................................552
      18.46. Operation 53: SEQUENCE - Supply Per-Procedure
             Sequencing and Control .................................553
      18.47. Operation 54: SET_SSV - Update SSV for a Client ID .....559
      18.48. Operation 55: TEST_STATEID - Test Stateids for
             Validity ...............................................561
      18.49. Operation 56: WANT_DELEGATION - Request Delegation .....563
      18.50. Operation 57: DESTROY_CLIENTID - Destroy a Client ID ...566
      18.51. Operation 58: RECLAIM_COMPLETE - Indicates
             Reclaims Finished ......................................567
      18.52. Operation 10044: ILLEGAL - Illegal Operation ...........569
   19. NFSv4.1 Callback Procedures ..................................570
      19.1. Procedure 0: CB_NULL - No Operation .....................570
      19.2. Procedure 1: CB_COMPOUND - Compound Operations ..........571
   20. NFSv4.1 Callback Operations ..................................574
      20.1. Operation 3: CB_GETATTR - Get Attributes ................574
      20.2. Operation 4: CB_RECALL - Recall a Delegation ............575
      20.3. Operation 5: CB_LAYOUTRECALL - Recall Layout
            from Client .............................................576
      20.4. Operation 6: CB_NOTIFY - Notify Client of
            Directory Changes .......................................580
      20.5. Operation 7: CB_PUSH_DELEG - Offer Previously
            Requested Delegation to Client ..........................583
      20.6. Operation 8: CB_RECALL_ANY - Keep Any N
            Recallable Objects ......................................584
      20.7. Operation 9: CB_RECALLABLE_OBJ_AVAIL - Signal
            Resources for Recallable Objects ........................588
      20.8. Operation 10: CB_RECALL_SLOT - Change Flow
            Control Limits ..........................................588
      20.9. Operation 11: CB_SEQUENCE - Supply Backchannel
            Sequencing and Control ..................................589
      20.10. Operation 12: CB_WANTS_CANCELLED - Cancel
             Pending Delegation Wants ...............................592
      20.11. Operation 13: CB_NOTIFY_LOCK - Notify Client of
             Possible Lock Availability .............................593
      20.12. Operation 14: CB_NOTIFY_DEVICEID - Notify
             Client of Device ID Changes ............................594
      20.13. Operation 10044: CB_ILLEGAL - Illegal Callback
             Operation ..............................................596
   21. Security Considerations ......................................597
   22. IANA Considerations ..........................................598
        
      22.1. Named Attribute Definitions .............................598
      22.2. Device ID Notifications .................................600
      22.3. Object Recall Types .....................................601
      22.4. Layout Types ............................................603
      22.5. Path Variable Definitions ...............................606
   23. References ...................................................609
      23.1. Normative References ....................................609
      23.2. Informative References ..................................612
   Appendix A.  Acknowledgments  ....................................615
        
      22.1. Named Attribute Definitions .............................598
      22.2. Device ID Notifications .................................600
      22.3. Object Recall Types .....................................601
      22.4. Layout Types ............................................603
      22.5. Path Variable Definitions ...............................606
   23. References ...................................................609
      23.1. Normative References ....................................609
      23.2. Informative References ..................................612
   Appendix A.  Acknowledgments  ....................................615
        
1. Introduction
1. 介绍
1.1. The NFS Version 4 Minor Version 1 Protocol
1.1. NFS版本4次要版本1协议

The NFS version 4 minor version 1 (NFSv4.1) protocol is the second minor version of the NFS version 4 (NFSv4) protocol. The first minor version, NFSv4.0, is described in [30]. It generally follows the guidelines for minor versioning that are listed in Section 10 of RFC 3530. However, it diverges from guidelines 11 ("a client and server that support minor version X must support minor versions 0 through X-1") and 12 ("no new features may be introduced as mandatory in a minor version"). These divergences are due to the introduction of the sessions model for managing non-idempotent operations and the RECLAIM_COMPLETE operation. These two new features are infrastructural in nature and simplify implementation of existing and other new features. Making them anything but REQUIRED would add undue complexity to protocol definition and implementation. NFSv4.1 accordingly updates the minor versioning guidelines (Section 2.7).

NFS版本4次要版本1(NFSv4.1)协议是NFS版本4(NFSv4)协议的第二次要版本。[30]中描述了第一个次要版本NFSv4.0。它通常遵循RFC 3530第10节中列出的次要版本控制指南。但是,它与准则11(“支持次要版本X的客户端和服务器必须支持次要版本0到X-1”)和准则12(“次要版本中不得强制引入新功能”)不同。这些差异是由于引入了用于管理非幂等运算的会话模型和Recreal_COMPLETE运算。这两项新功能本质上是基础设施,简化了现有功能和其他新功能的实现。如果不要求它们,就会给协议的定义和实现增加不必要的复杂性。NFSv4.1相应地更新了次要版本控制指南(第2.7节)。

As a minor version, NFSv4.1 is consistent with the overall goals for NFSv4, but extends the protocol so as to better meet those goals, based on experiences with NFSv4.0. In addition, NFSv4.1 has adopted some additional goals, which motivate some of the major extensions in NFSv4.1.

作为次要版本,NFSv4.1与NFSv4的总体目标一致,但根据NFSv4.0的经验,对协议进行了扩展,以便更好地实现这些目标。此外,NFSv4.1还采用了一些额外的目标,这些目标推动了NFSv4.1中的一些主要扩展。

1.2. Requirements Language
1.2. 需求语言

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

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

1.3. Scope of This Document
1.3. 本文件的范围

This document describes the NFSv4.1 protocol. With respect to NFSv4.0, this document does not:

本文档描述了NFSv4.1协议。关于NFSv4.0,本文件不:

o describe the NFSv4.0 protocol, except where needed to contrast with NFSv4.1.

o 描述NFSv4.0协议,除非需要与NFSv4.1进行对比。

o modify the specification of the NFSv4.0 protocol.

o 修改NFSv4.0协议的规范。

o clarify the NFSv4.0 protocol.

o 澄清NFSv4.0协议。

1.4. NFSv4 Goals
1.4. NFSv4目标

The NFSv4 protocol is a further revision of the NFS protocol defined already by NFSv3 [31]. It retains the essential characteristics of previous versions: easy recovery; independence of transport protocols, operating systems, and file systems; simplicity; and good performance. NFSv4 has the following goals:

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

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 NFSv4.1 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协议的工作为基础。此外,NFSv4.1协议提供了一种机制,允许客户端和服务器协商安全性,并要求客户端和服务器支持一组最小的安全方案。

o Good cross-platform interoperability

o 良好的跨平台互操作性

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

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

o Designed for protocol extensions

o 专为协议扩展而设计

The protocol is designed to accept standard extensions within a framework that enables and encourages backward compatibility.

该协议旨在接受框架内的标准扩展,该框架支持并鼓励向后兼容。

1.5. NFSv4.1 Goals
1.5. NFSv4.1目标

NFSv4.1 has the following goals, within the framework established by the overall NFSv4 goals.

NFSv4.1在总体NFSv4目标建立的框架内,有以下目标。

o To correct significant structural weaknesses and oversights discovered in the base protocol.

o 纠正基本协议中发现的重大结构缺陷和疏忽。

o To add clarity and specificity to areas left unaddressed or not addressed in sufficient detail in the base protocol. However, as stated in Section 1.3, it is not a goal to clarify the NFSv4.0 protocol in the NFSv4.1 specification.

o 为基础协议中未解决或未充分详细解决的区域增加清晰性和特殊性。然而,如第1.3节所述,在NFSv4.1规范中澄清NFSv4.0协议不是目的。

o To add specific features based on experience with the existing protocol and recent industry developments.

o 根据现有协议的经验和最近的行业发展添加特定功能。

o To provide protocol support to take advantage of clustered server deployments including the ability to provide scalable parallel access to files distributed among multiple servers.

o 提供协议支持,以利用群集服务器部署,包括提供对分布在多台服务器之间的文件的可扩展并行访问的能力。

1.6. General Definitions
1.6. 一般定义

The following definitions provide an appropriate context for the reader.

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

Byte: In this document, a byte is an octet, i.e., a datum exactly 8 bits in length.

字节:在本文档中,字节是八位字节,即长度正好为8位的数据。

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

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

A client is uniquely identified by a client owner.

客户端由客户端所有者唯一标识。

With reference to byte-range locking, the client is also 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 connection and multiple clients may exist on the same network node.

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

Client ID: The client ID is a 64-bit quantity used as a unique, short-hand reference to a client-supplied verifier and client owner. The server is responsible for supplying the client ID.

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

Client Owner: The client owner is a unique string, opaque to the server, that identifies a client. Multiple network connections and source network addresses originating from those connections may share a client owner. The server is expected to treat requests from connections with the same client owner as coming from the same client.

客户机所有者:客户机所有者是唯一的字符串,对服务器不透明,用于标识客户机。来自这些连接的多个网络连接和源网络地址可能共享一个客户端所有者。服务器应将来自同一客户机所有者的连接的请求视为来自同一客户机的请求。

File System: The file system is the collection of objects on a server (as identified by the major identifier of a server owner, which is defined later in this section) that share the same fsid attribute (see Section 5.8.1.9).

文件系统:文件系统是服务器上共享相同fsid属性的对象的集合(由服务器所有者的主要标识符标识,该标识符将在本节后面定义)(请参见第5.8.1.9节)。

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

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

A server grants a client a single lease for all state.

服务器向客户端授予所有状态的单一租约。

Lock: The term "lock" is used to refer to byte-range (in UNIX environments, also known as record) locks, share reservations, delegations, or layouts unless specifically stated otherwise.

锁:术语“锁”用于指字节范围(在UNIX环境中,也称为记录)锁、共享保留、委派或布局,除非另有特别说明。

Secret State Verifier (SSV): The SSV is a unique secret key shared between a client and server. The SSV serves as the secret key for an internal (that is, internal to NFSv4.1) Generic Security Services (GSS) mechanism (the SSV GSS mechanism; see Section 2.10.9). The SSV GSS mechanism uses the SSV to compute message integrity code (MIC) and Wrap tokens. See Section 2.10.8.3 for more details on how NFSv4.1 uses the SSV and the SSV GSS mechanism.

秘密状态验证器(SSV):SSV是客户端和服务器之间共享的唯一密钥。SSV用作内部(即NFSv4.1内部)通用安全服务(GSS)机制(SSV GSS机制;参见第2.10.9节)的密钥。SSV GSS机制使用SSV计算消息完整性代码(MIC)并包装令牌。有关NFSv4.1如何使用SSV和SSV GSS机制的更多详细信息,请参见第2.10.8.3节。

Server: The Server is the entity responsible for coordinating client access to a set of file systems and is identified by a server owner. A server can span multiple network addresses.

服务器:服务器是负责协调客户端对一组文件系统的访问的实体,由服务器所有者标识。服务器可以跨越多个网络地址。

Server Owner: The server owner identifies the server to the client. The server owner consists of a major identifier and a minor identifier. When the client has two connections each to a peer with the same major identifier, the client assumes that both peers are the same server (the server namespace is the same via each connection) and that lock state is sharable across both connections. When each peer has both the same major and minor identifiers, the client assumes that each connection might be associable with the same session.

服务器所有者:服务器所有者向客户端标识服务器。服务器所有者由主标识符和次标识符组成。当客户端有两个连接,每个连接到具有相同主标识符的对等方时,客户端假定两个对等方都是相同的服务器(通过每个连接,服务器名称空间是相同的),并且锁状态可在两个连接之间共享。当每个对等方都具有相同的主标识符和次标识符时,客户端会假定每个连接都可以与同一会话关联。

Stable Storage: Stable storage is storage from which data stored by an NFSv4.1 server can be recovered without data loss from multiple power failures (including cascading power failures, that is, several power failures in quick succession), operating system failures, and/or hardware failure of components other than the storage medium itself (such as disk, nonvolatile RAM, flash memory, etc.).

稳定存储:稳定存储是指NFSv4.1服务器存储的数据可以从中恢复,而不会因多个电源故障(包括级联电源故障,即多个连续电源故障)、操作系统故障和/或存储介质本身以外的组件硬件故障而丢失数据的存储(如磁盘、非易失性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 stateid is a 128-bit quantity returned by a server that uniquely defines the open and locking states provided by the server for a specific open-owner or lock-owner/open-owner pair for a specific file and type of lock.

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

Verifier: A verifier is 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位数量,服务器可以使用它来确定客户端是否已重新启动并丢失所有以前的锁定状态。

1.7. Overview of NFSv4.1 Features
1.7. NFSv4.1功能概述

The major features of the NFSv4.1 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 who is new to the NFS protocols. For the reader new to the NFS protocols, there is still a set of fundamental knowledge that is expected. The reader should be familiar with the External Data Representation (XDR) and Remote Procedure Call (RPC) protocols as described in [2] and [3]. A basic knowledge of file systems and distributed file systems is expected as well.

将简要回顾NFSv4.1协议的主要特点。这样做是为了为熟悉以前版本的NFS协议的读者和不熟悉NFS协议的读者提供适当的上下文。对于初次接触NFS协议的读者来说,仍然需要一组基本知识。读者应熟悉[2]和[3]中所述的外部数据表示(XDR)和远程过程调用(RPC)协议。具备文件系统和分布式文件系统的基本知识。

In general, this specification of NFSv4.1 will not distinguish those features added in minor version 1 from those present in the base protocol but will treat NFSv4.1 as a unified whole. See Section 1.8 for a summary of the differences between NFSv4.0 and NFSv4.1.

通常,NFSv4.1的本规范不会将次要版本1中添加的功能与基本协议中存在的功能区分开来,而是将NFSv4.1视为一个统一的整体。NFSv4.0和NFSv4.1之间的差异汇总见第1.8节。

1.7.1. RPC and Security
1.7.1. RPC与安全

As with previous versions of NFS, the External Data Representation (XDR) and Remote Procedure Call (RPC) mechanisms used for the NFSv4.1 protocol are those defined in [2] and [3]. To meet end-to-end security requirements, the RPCSEC_GSS framework [4] is used to extend the basic RPC security. With the use of RPCSEC_GSS, various mechanisms can be provided to offer authentication, integrity, and

与以前版本的NFS一样,NFSv4.1协议使用的外部数据表示(XDR)和远程过程调用(RPC)机制是[2]和[3]中定义的机制。为了满足端到端安全性要求,使用RPCSEC_GSS框架[4]扩展基本RPC安全性。通过使用RPCSEC_GSS,可以提供各种机制来提供身份验证、完整性和安全性

privacy to the NFSv4 protocol. Kerberos V5 is used as described in [5] to provide one security framework. With the use of RPCSEC_GSS, other mechanisms may also be specified and used for NFSv4.1 security.

NFSv4协议的隐私。Kerberos V5如[5]所述用于提供一个安全框架。通过使用RPCSEC_GSS,还可以指定其他机制并用于NFSv4.1安全性。

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

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

NFSv4.1 introduces parallel access (see Section 1.7.2.2), which is called pNFS. The security framework described in this section is significantly modified by the introduction of pNFS (see Section 12.9), because data access is sometimes not over RPC. The level of significance varies with the storage protocol (see Section 12.2.5) and can be as low as zero impact (see Section 13.12).

NFSv4.1引入了并行访问(见第1.7.2.2节),称为pNFS。由于pNFS的引入(参见第12.9节),本节中描述的安全框架得到了显著修改,因为数据访问有时不是通过RPC进行的。重要程度因存储协议而异(见第12.2.5节),可低至零影响(见第13.12节)。

1.7.2. Protocol Structure
1.7.2. 协议结构
1.7.2.1. Core Protocol
1.7.2.1. 核心协议

Unlike NFSv3, which used a series of ancillary protocols (e.g., NLM, NSM (Network Status Monitor), MOUNT), within all minor versions of NFSv4 a single RPC protocol is used to make requests to the server. Facilities that had been separate protocols, such as locking, are now integrated within a single unified protocol.

与使用一系列辅助协议(例如NLM、NSM(网络状态监视器)、MOUNT)的NFSv3不同,在NFSv4的所有次要版本中,使用单个RPC协议向服务器发出请求。以前是单独协议的设施,例如锁定,现在集成到单个统一协议中。

1.7.2.2. Parallel Access
1.7.2.2. 并行存取

Minor version 1 supports high-performance data access to a clustered server implementation by enabling a separation of metadata access and data access, with the latter done to multiple servers in parallel.

Minor版本1支持对集群服务器实现的高性能数据访问,实现了元数据访问和数据访问的分离,后者并行地对多个服务器进行访问。

Such parallel data access is controlled by recallable objects known as "layouts", which are integrated into the protocol locking model. Clients direct requests for data access to a set of data servers specified by the layout via a data storage protocol which may be NFSv4.1 or may be another protocol.

这种并行数据访问由称为“布局”的可重新调用对象控制,这些对象集成到协议锁定模型中。客户端通过数据存储协议(可能是NFSv4.1或其他协议)将数据访问请求直接发送到布局指定的一组数据服务器。

Because the protocols used for parallel data access are not necessarily RPC-based, the RPC-based security model (Section 1.7.1) is obviously impacted (see Section 12.9). The degree of impact varies with the storage protocol (see Section 12.2.5) used for data access, and can be as low as zero (see Section 13.12).

由于用于并行数据访问的协议不一定基于RPC,因此基于RPC的安全模型(第1.7.1节)明显受到影响(见第12.9节)。影响程度因用于数据访问的存储协议(见第12.2.5节)而异,可低至零(见第13.12节)。

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

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

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

The NFSv4.1 protocol does not require a separate protocol to provide for the initial mapping between path name and filehandle. All file systems exported by a server are presented as a tree so that all file systems are reachable from a special per-server global root filehandle. This allows LOOKUP operations to be used to perform functions previously provided by the MOUNT protocol. The server provides any necessary pseudo file systems to bridge any gaps that arise due to unexported gaps between exported file systems.

NFSv4.1协议不需要单独的协议来提供路径名和文件句柄之间的初始映射。服务器导出的所有文件系统都以树的形式显示,这样所有文件系统都可以通过特殊的每服务器全局根文件句柄访问。这允许使用查找操作来执行先前由装载协议提供的功能。服务器提供任何必要的伪文件系统,以弥补由于导出的文件系统之间未报告的间隙而产生的任何间隙。

1.7.3.1. Filehandles
1.7.3.1. 文件句柄

As in previous versions of the NFS protocol, opaque filehandles are used to identify individual files and directories. Lookup-type and create operations translate file and directory names to filehandles, which are then used to identify objects in subsequent operations.

与以前版本的NFS协议一样,不透明文件句柄用于标识单个文件和目录。“查找类型”和“创建”操作将文件名和目录名转换为文件句柄,然后用于在后续操作中标识对象。

The NFSv4.1 protocol provides support for persistent filehandles, guaranteed to be valid for the lifetime of the file system object designated. In addition, it provides support to servers to provide filehandles with more limited validity guarantees, called volatile filehandles.

NFSv4.1协议提供对持久化文件句柄的支持,保证在指定的文件系统对象的生存期内有效。此外,它还支持服务器为文件句柄提供更有限的有效性保证,称为volatile文件句柄。

1.7.3.2. File Attributes
1.7.3.2. 文件属性

The NFSv4.1 protocol has a rich and extensible file object attribute structure, which is divided into REQUIRED, RECOMMENDED, and named attributes (see Section 5).

NFSv4.1协议具有丰富且可扩展的文件对象属性结构,该结构分为必需属性、推荐属性和命名属性(参见第5节)。

Several (but not all) of the REQUIRED attributes are derived from the attributes of NFSv3 (see the definition of the fattr3 data type in [31]). An example of a REQUIRED attribute is the file object's type (Section 5.8.1.2) so that regular files can be distinguished from directories (also known as folders in some operating environments) and other types of objects. REQUIRED attributes are discussed in Section 5.1.

几个(但不是全部)必需的属性是从NFSv3的属性派生的(参见[31]中fattr3数据类型的定义)。所需属性的一个示例是文件对象的类型(第5.8.1.2节),以便将常规文件与目录(在某些操作环境中也称为文件夹)和其他类型的对象区分开来。第5.1节讨论了所需属性。

An example of three RECOMMENDED attributes are acl, sacl, and dacl. These attributes define an Access Control List (ACL) on a file object (Section 6). An ACL provides directory and file access control beyond the model used in NFSv3. The ACL definition allows for

三个推荐属性的示例是acl、sacl和dacl。这些属性定义文件对象上的访问控制列表(ACL)(第6节)。ACL提供了NFSv3中使用的模型之外的目录和文件访问控制。ACL定义允许

specification of specific sets of permissions for individual users and groups. In addition, ACL inheritance allows propagation of access permissions and restrictions down a directory tree as file system objects are created. RECOMMENDED attributes are discussed in Section 5.2.

为单个用户和组指定特定权限集。此外,ACL继承允许在创建文件系统对象时沿目录树传播访问权限和限制。第5.2节讨论了推荐属性。

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. NFSv4.1 modifies named attributes relative to NFSv4.0 by tightening the allowed operations in order to prevent the development of non-interoperable implementations. Named attributes are discussed in Section 5.3.

命名属性是与目录或文件关联并由字符串名称引用的不透明字节流。命名属性被客户机应用程序用作将特定于应用程序的数据与常规文件或目录关联的方法。NFSv4.1通过收紧允许的操作来修改相对于NFSv4.0的命名属性,以防止开发不可互操作的实现。命名属性在第5.3节中讨论。

1.7.3.3. Multi-Server Namespace
1.7.3.3. 多服务器名称空间

NFSv4.1 contains a number of features to allow implementation of namespaces that cross server boundaries and that allow and facilitate a non-disruptive transfer of support for individual file systems between servers. They are all based upon attributes that allow one file system to specify alternate or new locations for that file system.

NFSv4.1包含许多功能,允许实现跨越服务器边界的名称空间,并允许和促进在服务器之间无中断地传输对单个文件系统的支持。它们都基于允许一个文件系统为该文件系统指定备用位置或新位置的属性。

These attributes may be used together with the concept of absent file systems, which provide specifications for additional locations but no actual file system content. This allows a number of important facilities:

这些属性可以与缺席文件系统的概念一起使用,缺席文件系统为其他位置提供规范,但不提供实际的文件系统内容。这允许使用一些重要的设施:

o Location attributes may be used with absent file systems to implement referrals whereby one server may direct the client to a file system provided by another server. This allows extensive multi-server namespaces to be constructed.

o 位置属性可用于缺少的文件系统,以实现引用,其中一台服务器可将客户端指向另一台服务器提供的文件系统。这允许构造广泛的多服务器名称空间。

o Location attributes may be provided for present file systems to provide the locations of alternate file system instances or replicas to be used in the event that the current file system instance becomes unavailable.

o 可以为当前文件系统提供位置属性,以提供在当前文件系统实例不可用时使用的备用文件系统实例或副本的位置。

o Location attributes may be provided when a previously present file system becomes absent. This allows non-disruptive migration of file systems to alternate servers.

o 当以前存在的文件系统不存在时,可以提供位置属性。这允许无中断地将文件系统迁移到备用服务器。

1.7.4. Locking Facilities
1.7.4. 锁具

As mentioned previously, NFSv4.1 is a single protocol that includes locking facilities. These locking facilities include support for many types of locks including a number of sorts of recallable locks.

如前所述,NFSv4.1是一个包含锁定功能的单一协议。这些锁定设施包括支持多种类型的锁,包括多种类型的可重装锁。

Recallable locks such as delegations allow the client to be assured that certain events will not occur so long as that lock is held. When circumstances change, the lock is recalled via a callback request. The assurances provided by delegations allow more extensive caching to be done safely when circumstances allow it.

可重新调用的锁(如委托)允许客户机确信,只要保持该锁,某些事件就不会发生。当情况发生变化时,通过回调请求调用锁。各代表团提供的保证允许在情况允许时安全地进行更广泛的缓存。

The types of locks are:

锁的类型有:

o Share reservations as established by OPEN operations.

o 共享开放式运营建立的预订。

o Byte-range locks.

o 字节范围锁。

o File delegations, which are recallable locks that assure the holder that inconsistent opens and file changes cannot occur so long as the delegation is held.

o 文件委派,是一种可重新调用的锁,可确保持有者在委派保持期间不会打开不一致的文件并更改文件。

o Directory delegations, which are recallable locks that assure the holder that inconsistent directory modifications cannot occur so long as the delegation is held.

o 目录委托,这是一种可重新调用的锁,可确保持有者在保留委托的情况下不会发生不一致的目录修改。

o Layouts, which are recallable objects that assure the holder that direct access to the file data may be performed directly by the client and that no change to the data's location that is inconsistent with that access may be made so long as the layout is held.

o 布局,是可重新调用的对象,可确保持有人直接访问文件数据可由客户直接执行,并且只要保持布局,就不会对数据位置进行与该访问不一致的更改。

All locks for a given client are tied together under a single client-wide lease. All requests made on sessions associated with the client renew that lease. When the client's lease is not promptly renewed, the client's locks are subject to revocation. In the event of server restart, clients have the opportunity to safely reclaim their locks within a special grace period.

给定客户机的所有锁都在单个客户机范围的租约下绑定在一起。在与客户端关联的会话上发出的所有请求都将续订该租约。如果客户的租约未及时续约,客户的锁将被撤销。在服务器重新启动的情况下,客户端有机会在一个特殊的宽限期内安全地回收其锁。

1.8. Differences from NFSv4.0
1.8. 与NFSv4.0的区别

The following summarizes the major differences between minor version 1 and the base protocol:

以下总结了次要版本1和基本协议之间的主要差异:

o Implementation of the sessions model (Section 2.10).

o 会话模型的实施(第2.10节)。

o Parallel access to data (Section 12).

o 并行访问数据(第12节)。

o Addition of the RECLAIM_COMPLETE operation to better structure the lock reclamation process (Section 18.51).

o 添加回收完整操作,以更好地构建船闸回收流程(第18.51节)。

o Enhanced delegation support as follows.

o 加强代表团支持如下。

* Delegations on directories and other file types in addition to regular files (Section 18.39, Section 18.49).

* 除常规文件外,对目录和其他文件类型的授权(第18.39节,第18.49节)。

* Operations to optimize acquisition of recalled or denied delegations (Section 18.49, Section 20.5, Section 20.7).

* 优化收回或拒绝授权的获取的操作(第18.49节、第20.5节、第20.7节)。

* Notifications of changes to files and directories (Section 18.39, Section 20.4).

* 文件和目录更改通知(第18.39节,第20.4节)。

* A method to allow a server to indicate that it is recalling one or more delegations for resource management reasons, and thus a method to allow the client to pick which delegations to return (Section 20.6).

* 一种允许服务器指示其出于资源管理原因调用一个或多个委托的方法,以及一种允许客户端选择返回哪些委托的方法(第20.6节)。

o Attributes can be set atomically during exclusive file create via the OPEN operation (see the new EXCLUSIVE4_1 creation method in Section 18.16).

o 在通过OPEN操作创建独占文件的过程中,可以自动设置属性(请参阅第18.16节中新的EXCLUSIVE4_1创建方法)。

o Open files can be preserved if removed and the hard link count ("hard link" is defined in an Open Group [6] standard) goes to zero, thus obviating the need for clients to rename deleted files to partially hidden names -- colloquially called "silly rename" (see the new OPEN4_RESULT_PRESERVE_UNLINKED reply flag in Section 18.16).

o 如果删除打开的文件,并且硬链接计数(“硬链接”在开放组[6]标准中定义)变为零,则可以保留打开的文件,从而避免客户端需要将删除的文件重命名为部分隐藏的名称——通俗地称为“愚蠢的重命名”(请参阅第18.16节中新的OPEN4_RESULT_PRESERVE_UNLINKED reply标志)。

o Improved compatibility with Microsoft Windows for Access Control Lists (Section 6.2.3, Section 6.2.2, Section 6.4.3.2).

o 改进了与Microsoft Windows访问控制列表的兼容性(第6.2.3节、第6.2.2节、第6.4.3.2节)。

o Data retention (Section 5.13).

o 数据保留(第5.13节)。

o Identification of the implementation of the NFS client and server (Section 18.35).

o NFS客户端和服务器实现的标识(第18.35节)。

o Support for notification of the availability of byte-range locks (see the new OPEN4_RESULT_MAY_NOTIFY_LOCK reply flag in Section 18.16 and see Section 20.11).

o 支持通知字节范围锁的可用性(请参阅第18.16节中新的OPEN4_RESULT_MAY_NOTIFY_LOCK reply标志和第20.11节)。

o In NFSv4.1, LIPKEY and SPKM-3 are not required security mechanisms [32].

o 在NFSv4.1中,LIPKEY和SPKM-3不是必需的安全机制[32]。

2. Core Infrastructure
2. 核心基础设施
2.1. Introduction
2.1. 介绍

NFSv4.1 relies on core infrastructure common to nearly every operation. This core infrastructure is described in the remainder of this section.

NFSv4.1依赖于几乎所有操作都通用的核心基础设施。这一核心基础设施将在本节的其余部分介绍。

2.2. RPC and XDR
2.2. RPC和XDR

The NFSv4.1 protocol is a Remote Procedure Call (RPC) application that uses RPC version 2 and the corresponding eXternal Data Representation (XDR) as defined in [3] and [2].

NFSv4.1协议是一个远程过程调用(RPC)应用程序,它使用RPC版本2和[3]和[2]中定义的相应外部数据表示(XDR)。

2.2.1. RPC-Based Security
2.2.1. 基于RPC的安全性

Previous NFS versions have been thought of as having a host-based authentication model, where the NFS server authenticates the NFS client, and trusts the client to authenticate all users. Actually, NFS has always depended on RPC for authentication. One of the first forms of RPC authentication, AUTH_SYS, had no strong authentication and required a host-based authentication approach. NFSv4.1 also depends on RPC for basic security services and mandates RPC support for a user-based authentication model. The user-based authentication model has user principals authenticated by a server, and in turn the server authenticated by user principals. RPC provides some basic security services that are used by NFSv4.1.

以前的NFS版本被认为具有基于主机的身份验证模型,其中NFS服务器对NFS客户端进行身份验证,并信任客户端对所有用户进行身份验证。实际上,NFS一直依赖于RPC进行身份验证。RPC身份验证的最初形式之一AUTH_SYS没有强身份验证,需要基于主机的身份验证方法。NFSv4.1还依赖RPC提供基本安全服务,并强制要求RPC支持基于用户的身份验证模型。基于用户的身份验证模型具有由服务器进行身份验证的用户主体,而服务器又由用户主体进行身份验证。RPC提供NFSv4.1使用的一些基本安全服务。

2.2.1.1. RPC Security Flavors
2.2.1.1. RPC安全特性

As described in Section 7.2 ("Authentication") of [3], RPC security is encapsulated in the RPC header, via a security or authentication flavor, and information specific to the specified security flavor. Every RPC header conveys information used to identify and authenticate a client and server. As discussed in Section 2.2.1.1.1, some security flavors provide additional security services.

如[3]第7.2节(“认证”)所述,RPC安全性通过安全性或认证风格以及特定于指定安全风格的信息封装在RPC标头中。每个RPC头传递用于识别和验证客户端和服务器的信息。如第2.2.1.1.1节所述,一些安全特性提供了额外的安全服务。

NFSv4.1 clients and servers MUST implement RPCSEC_GSS. (This requirement to implement is not a requirement to use.) Other flavors, such as AUTH_NONE and AUTH_SYS, MAY be implemented as well.

NFSv4.1客户端和服务器必须实现RPCSEC_GSS。(要实现的要求不是使用的要求。)也可以实现其他风格,如AUTH_NONE和AUTH_SYS。

2.2.1.1.1. RPCSEC_GSS and Security Services
2.2.1.1.1. RPCSEC_GSS和安全服务

RPCSEC_GSS [4] uses the functionality of GSS-API [7]. This allows for the use of various security mechanisms by the RPC layer without the additional implementation overhead of adding RPC security flavors.

RPCSEC_GSS[4]使用GSS-API[7]的功能。这允许RPC层使用各种安全机制,而无需添加RPC安全特性的额外实现开销。

2.2.1.1.1.1. Identification, Authentication, Integrity, Privacy
2.2.1.1.1.1. 识别、认证、完整性、隐私

Via the GSS-API, RPCSEC_GSS can be used to identify and authenticate users on clients to servers, and servers to users. It can also perform integrity checking on the entire RPC message, including the RPC header, and on the arguments or results. Finally, privacy, usually via encryption, is a service available with RPCSEC_GSS. Privacy is performed on the arguments and results. Note that if

通过GSS-API,RPCSEC_GSS可用于识别和验证客户端到服务器的用户,以及服务器到用户的用户。它还可以对整个RPC消息(包括RPC头)以及参数或结果执行完整性检查。最后,隐私(通常通过加密)是RPCSEC_GSS提供的一项服务。对参数和结果执行隐私保护。注意,如果

privacy is selected, integrity, authentication, and identification are enabled. If privacy is not selected, but integrity is selected, authentication and identification are enabled. If integrity and privacy are not selected, but authentication is enabled, identification is enabled. RPCSEC_GSS does not provide identification as a separate service.

选择隐私,启用完整性、身份验证和标识。如果未选择隐私,但选择了完整性,则会启用身份验证和标识。如果未选择完整性和隐私,但已启用身份验证,则将启用标识。RPCSEC_GSS不作为单独服务提供标识。

Although GSS-API has an authentication service distinct from its privacy and integrity services, GSS-API's authentication service is not used for RPCSEC_GSS's authentication service. Instead, each RPC request and response header is integrity protected with the GSS-API integrity service, and this allows RPCSEC_GSS to offer per-RPC authentication and identity. See [4] for more information.

虽然GSS-API具有与其隐私和完整性服务不同的身份验证服务,但GSS-API的身份验证服务不用于RPCSEC_GSS的身份验证服务。相反,每个RPC请求和响应头都受到GSS-API完整性服务的完整性保护,这允许RPCSEC_GSS提供每个RPC身份验证和标识。有关更多信息,请参见[4]。

NFSv4.1 client and servers MUST support RPCSEC_GSS's integrity and authentication service. NFSv4.1 servers MUST support RPCSEC_GSS's privacy service. NFSv4.1 clients SHOULD support RPCSEC_GSS's privacy service.

NFSv4.1客户端和服务器必须支持RPCSEC_GSS的完整性和身份验证服务。NFSv4.1服务器必须支持RPCSEC_GSS的隐私服务。NFSv4.1客户端应支持RPCSEC_GSS的隐私服务。

2.2.1.1.1.2. Security Mechanisms for NFSv4.1
2.2.1.1.1.2. NFSv4.1的安全机制

RPCSEC_GSS, via GSS-API, normalizes access to mechanisms that provide security services. Therefore, NFSv4.1 clients and servers MUST support the Kerberos V5 security mechanism.

RPCSEC_GSS通过GSS-API规范了对提供安全服务的机制的访问。因此,NFSv4.1客户端和服务器必须支持Kerberos V5安全机制。

The use of RPCSEC_GSS requires selection of mechanism, quality of protection (QOP), and service (authentication, integrity, privacy). For the mandated security mechanisms, NFSv4.1 specifies that a QOP of zero is used, leaving it up to the mechanism or the mechanism's configuration to map QOP zero to an appropriate level of protection. Each mandated mechanism specifies a minimum set of cryptographic algorithms for implementing integrity and privacy. NFSv4.1 clients and servers MUST be implemented on operating environments that comply with the REQUIRED cryptographic algorithms of each REQUIRED mechanism.

RPCSEC_GSS的使用需要选择机制、保护质量(QOP)和服务(身份验证、完整性、隐私)。对于强制安全机制,NFSv4.1规定使用QOP为零,由机制或机制配置将QOP零映射到适当的保护级别。每个强制机制都指定了用于实现完整性和隐私性的最小加密算法集。NFSv4.1客户端和服务器必须在符合每个所需机制的所需加密算法的操作环境中实现。

2.2.1.1.1.2.1. Kerberos V5
2.2.1.1.1.2.1. Kerberos V5

The Kerberos V5 GSS-API mechanism as described in [5] MUST be implemented with the RPCSEC_GSS services as specified in the following table:

[5]中描述的Kerberos V5 GSS-API机制必须使用下表中指定的RPCSEC_GSS服务实现:

      column descriptions:
      1 == number of pseudo flavor
      2 == name of pseudo flavor
      3 == mechanism's OID
      4 == RPCSEC_GSS service
      5 == NFSv4.1 clients MUST support
      6 == NFSv4.1 servers MUST support
        
      column descriptions:
      1 == number of pseudo flavor
      2 == name of pseudo flavor
      3 == mechanism's OID
      4 == RPCSEC_GSS service
      5 == NFSv4.1 clients MUST support
      6 == NFSv4.1 servers MUST support
        
      1      2        3                    4                     5   6
      ------------------------------------------------------------------
      390003 krb5     1.2.840.113554.1.2.2 rpc_gss_svc_none      yes yes
      390004 krb5i    1.2.840.113554.1.2.2 rpc_gss_svc_integrity yes yes
      390005 krb5p    1.2.840.113554.1.2.2 rpc_gss_svc_privacy    no yes
        
      1      2        3                    4                     5   6
      ------------------------------------------------------------------
      390003 krb5     1.2.840.113554.1.2.2 rpc_gss_svc_none      yes yes
      390004 krb5i    1.2.840.113554.1.2.2 rpc_gss_svc_integrity yes yes
      390005 krb5p    1.2.840.113554.1.2.2 rpc_gss_svc_privacy    no yes
        

Note that the number and name of the pseudo flavor are presented here as a mapping aid to the implementor. Because the NFSv4.1 protocol includes a method to negotiate security and it understands the GSS-API mechanism, the pseudo flavor is not needed. The pseudo flavor is needed for the NFSv3 since the security negotiation is done via the MOUNT protocol as described in [33].

请注意,伪风格的编号和名称在这里作为映射辅助工具提供给实现者。因为NFSv4.1协议包含协商安全性的方法,并且它理解GSS-API机制,所以不需要伪风格。NFSv3需要伪风格,因为安全协商是通过[33]中描述的装载协议完成的。

At the time NFSv4.1 was specified, the Advanced Encryption Standard (AES) with HMAC-SHA1 was a REQUIRED algorithm set for Kerberos V5. In contrast, when NFSv4.0 was specified, weaker algorithm sets were REQUIRED for Kerberos V5, and were REQUIRED in the NFSv4.0 specification, because the Kerberos V5 specification at the time did not specify stronger algorithms. The NFSv4.1 specification does not specify REQUIRED algorithms for Kerberos V5, and instead, the implementor is expected to track the evolution of the Kerberos V5 standard if and when stronger algorithms are specified.

在指定NFSv4.1时,带有HMAC-SHA1的高级加密标准(AES)是Kerberos V5所需的算法集。相反,当指定NFSv4.0时,Kerberos V5需要较弱的算法集,NFSv4.0规范也需要较弱的算法集,因为当时的Kerberos V5规范没有指定更强的算法。NFSv4.1规范没有为Kerberos V5指定所需的算法,相反,如果指定了更强大的算法,则实现者应该跟踪Kerberos V5标准的发展。

2.2.1.1.1.2.1.1. Security Considerations for Cryptographic Algorithms in Kerberos V5

2.2.1.1.1.2.1.1. Kerberos V5中加密算法的安全注意事项

When deploying NFSv4.1, the strength of the security achieved depends on the existing Kerberos V5 infrastructure. The algorithms of Kerberos V5 are not directly exposed to or selectable by the client or server, so there is some due diligence required by the user of NFSv4.1 to ensure that security is acceptable where needed.

在部署NFSv4.1时,实现的安全性的强度取决于现有的Kerberos V5基础架构。Kerberos V5的算法不直接暴露于客户机或服务器,也不可由客户机或服务器选择,因此NFSv4.1的用户需要进行一些尽职调查,以确保在需要时可以接受安全性。

2.2.1.1.1.3. GSS Server Principal
2.2.1.1.1.3. GSS服务器主体

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, the following form is RECOMMENDED:

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

nfs/hostname

nfs/主机名

2.3. COMPOUND and CB_COMPOUND
2.3. 化合物和CB_化合物

A significant departure from the versions of the NFS protocol before NFSv4 is the introduction of the COMPOUND procedure. For the NFSv4 protocol, in all minor versions, there are exactly two RPC procedures, NULL and COMPOUND. The COMPOUND procedure is defined as a series of individual operations and these operations perform the sorts of functions performed by traditional NFS procedures.

与NFSv4之前的NFS协议版本相比,引入了复合过程。对于NFSv4协议,在所有次要版本中,正好有两个RPC过程:NULL和component。复合过程被定义为一系列单独的操作,这些操作执行传统NFS过程执行的各种功能。

The operations combined within a COMPOUND request are evaluated in order by the server, without any atomicity guarantees. A limited set of facilities exist to pass results from one operation to another. Once an operation returns a failing result, the evaluation ends and the results of all evaluated operations are returned to the client.

组合在复合请求中的操作由服务器按顺序进行评估,而无需任何原子性保证。存在一组有限的设施,用于将结果从一个操作传递到另一个操作。一旦操作返回失败的结果,评估将结束,所有评估操作的结果将返回给客户端。

With the use of the COMPOUND procedure, the client is able to build simple or complex requests. These COMPOUND requests allow for a reduction in the number of RPCs needed for logical file system operations. For example, multi-component look up requests can be constructed by combining multiple LOOKUP operations. Those can be further combined with operations such as GETATTR, READDIR, or OPEN plus READ to do more complicated sets of operation without incurring additional latency.

通过使用复合过程,客户机能够构建简单或复杂的请求。这些复合请求允许减少逻辑文件系统操作所需的RPC数量。例如,可以通过组合多个查找操作来构造多组件查找请求。这些可以进一步与诸如GETATTR、READDIR或OPEN plus READ之类的操作相结合,以执行更复杂的操作集,而不会产生额外的延迟。

NFSv4.1 also contains a considerable set of callback operations in which the server makes an RPC directed at the client. Callback RPCs have a similar structure to that of the normal server requests. In all minor versions of the NFSv4 protocol, there are two callback RPC procedures: CB_NULL and CB_COMPOUND. The CB_COMPOUND procedure is defined in an analogous fashion to that of COMPOUND with its own set of callback operations.

NFSv4.1还包含一组相当多的回调操作,其中服务器将RPC定向到客户端。回调RPC的结构与普通服务器请求的结构相似。在NFSv4协议的所有次要版本中,都有两个回调RPC过程:CB_NULL和CB_component。CB_复合过程的定义方式与复合过程类似,它有自己的一组回调操作。

The addition of new server and callback operations within the COMPOUND and CB_COMPOUND request framework provides a means of extending the protocol in subsequent minor versions.

在复合和CB_复合请求框架中添加新的服务器和回调操作,提供了在后续次要版本中扩展协议的方法。

Except for a small number of operations needed for session creation, server requests and callback requests are performed within the context of a session. Sessions provide a client context for every request and support robust reply protection for non-idempotent requests.

除了创建会话所需的少量操作外,服务器请求和回调请求都是在会话上下文中执行的。会话为每个请求提供客户端上下文,并支持对非幂等请求的健壮回复保护。

2.4. Client Identifiers and Client Owners
2.4. 客户端标识符和客户端所有者

For each operation that obtains or depends on locking state, the specific client needs to be identifiable by the server.

对于获得或依赖于锁定状态的每个操作,服务器需要识别特定的客户端。

Each distinct client instance is represented by a client ID. A client ID is a 64-bit identifier representing a specific client at a given time. The client ID is changed whenever the client re-initializes, and may change when the server re-initializes. Client IDs are used to support lock identification and crash recovery.

每个不同的客户端实例都由一个客户端ID表示。客户端ID是一个64位标识符,表示给定时间的特定客户端。客户机ID在客户机重新初始化时更改,并且在服务器重新初始化时可能会更改。客户端ID用于支持锁识别和崩溃恢复。

During steady state operation, the client ID associated with each operation is derived from the session (see Section 2.10) on which the operation is sent. A session is associated with a client ID when the session is created.

在稳态操作期间,与每个操作相关联的客户机ID来自发送操作的会话(参见第2.10节)。创建会话时,会话与客户端ID关联。

Unlike NFSv4.0, the only NFSv4.1 operations possible before a client ID is established are those needed to establish the client ID.

与NFSv4.0不同,在建立客户机ID之前,唯一可能的NFSv4.1操作是建立客户机ID所需的操作。

A sequence of an EXCHANGE_ID operation followed by a CREATE_SESSION operation using that client ID (eir_clientid as returned from EXCHANGE_ID) is required to establish and confirm the client ID on the server. Establishment of identification by a new incarnation of the client also has the effect of immediately releasing any locking state that a previous incarnation of that same client might have had on the server. Such released state would include all byte-range lock, share reservation, layout state, and -- where the server supports neither the CLAIM_DELEGATE_PREV nor CLAIM_DELEG_CUR_FH claim types -- all delegation state associated with the same client with the same identity. For discussion of delegation state recovery, see Section 10.2.1. For discussion of layout state recovery, see Section 12.7.1.

在服务器上建立和确认客户端ID时,需要先执行EXCHANGE\u ID操作,然后使用该客户端ID(从EXCHANGE\u ID返回的eir\u clientid)执行创建会话操作。通过客户机的新版本建立标识还可以立即释放该客户机的前一版本在服务器上可能具有的任何锁定状态。这种释放状态将包括所有字节范围锁、共享保留、布局状态,并且——如果服务器既不支持CLAIM_DELEGATE_PREV,也不支持CLAIM_DELEG_CUR_FH声明类型——与具有相同标识的同一客户机关联的所有委托状态。有关授权状态恢复的讨论,请参见第10.2.1节。有关布局状态恢复的讨论,请参见第12.7.1节。

Releasing such state requires that the server be able to determine that one client instance is the successor of another. Where this cannot be done, for any of a number of reasons, the locking state will remain for a time subject to lease expiration (see Section 8.3) and the new client will need to wait for such state to be removed, if it makes conflicting lock requests.

释放这种状态需要服务器能够确定一个客户端实例是另一个客户端实例的后续实例。如果由于多种原因无法做到这一点,锁定状态将保留一段时间,直至租约到期(见第8.3节),如果新客户端发出冲突的锁定请求,则需要等待该状态被删除。

Client identification is encapsulated in the following client owner data type:

客户端标识封装在以下客户端所有者数据类型中:

   struct client_owner4 {
           verifier4       co_verifier;
           opaque          co_ownerid<NFS4_OPAQUE_LIMIT>;
   };
        
   struct client_owner4 {
           verifier4       co_verifier;
           opaque          co_ownerid<NFS4_OPAQUE_LIMIT>;
   };
        

The first field, co_verifier, is a client incarnation verifier. The server will start the process of canceling the client's leased state if co_verifier is different than what the server has previously recorded for the identified client (as specified in the co_ownerid field).

第一个字段,co_验证器,是一个客户机化身验证器。如果co_verifier与服务器先前为已识别的客户端记录的内容不同(如co_ownerid字段中所指定),则服务器将启动取消客户端租用状态的过程。

The second field, co_ownerid, is a variable length string that uniquely defines the client so that subsequent instances of the same client bear the same co_ownerid with a different verifier.

第二个字段co_ownerid是一个可变长度的字符串,它唯一地定义了客户机,以便同一客户机的后续实例与不同的验证器具有相同的co_ownerid。

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

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

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

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

o The string should be selected so that subsequent incarnations (e.g., restarts) of the same client cause the client to present the same string. The implementor is cautioned from 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 NFSv4.1 server.

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

o The string should be the same for each server network address that the client accesses. This way, if a server has multiple interfaces, the client can trunk traffic over multiple network paths as described in Section 2.10.5. (Note: the precise opposite was advised in the NFSv4.0 specification [30].)

o 对于客户端访问的每个服务器网络地址,字符串应该相同。这样,如果服务器有多个接口,客户端可以通过多个网络路径中继流量,如第2.10.5节所述。(注:NFSv4.0规范[30]中建议的正好相反。)

o The algorithm for generating the string should not assume that the client's network address will not change, unless the client implementation knows it is using statically assigned network addresses. This includes changes between client incarnations and even changes while the client is still running in its current incarnation. Thus, with dynamic address assignment, if the client includes just the client's network address in the co_ownerid string, there is a real risk that after the client gives up the

o 生成字符串的算法不应假定客户端的网络地址不会更改,除非客户端实现知道它正在使用静态分配的网络地址。这包括客户端化身之间的更改,甚至在客户端仍在当前化身中运行时的更改。因此,使用动态地址分配,如果客户机在co_ownerid字符串中仅包含客户机的网络地址,则在客户机放弃该地址后,存在真正的风险

network address, another client, using a similar algorithm for generating the co_ownerid string, would generate a conflicting co_ownerid string.

网络地址,另一个客户端,使用类似的算法生成co_ownerid字符串,将生成冲突的co_ownerid字符串。

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

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

o If applicable, the client's statically assigned network address.

o 如果适用,客户端静态分配的网络地址。

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 Media Access Control (MAC) address (again, a one-way function should be performed).

* 媒体访问控制(MAC)地址(同样,应执行单向功能)。

* The timestamp of when the NFSv4.1 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 NFSv4.1).

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

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

* 真随机数。然而,由于此数字在客户端化身之间应该是相同的,因此这与使用软件安装的时间戳的问题相同。

o For a user-level NFSv4.1 client, it should contain additional information to distinguish the client from other user-level clients running on the same host, such as a process identifier or other unique sequence.

o 对于用户级NFSv4.1客户端,它应该包含其他信息,以将客户端与运行在同一主机上的其他用户级客户端区分开来,例如进程标识符或其他唯一序列。

The client ID is assigned by the server (the eir_clientid result from EXCHANGE_ID) and should be chosen so that it will not conflict with a client ID previously assigned by the server. This applies across server restarts.

客户端ID由服务器分配(eir_clientid来自EXCHANGE_ID),应选择该ID,以使其不会与服务器先前分配的客户端ID冲突。这适用于服务器重启。

In the event of a server restart, a client may find out that its current client ID is no longer valid when it receives an NFS4ERR_STALE_CLIENTID error. The precise circumstances depend on the characteristics of the sessions involved, specifically whether the session is persistent (see Section 2.10.6.5), but in each case the client will receive this error when it attempts to establish a new session with the existing client ID and receives the error NFS4ERR_STALE_CLIENTID, indicating that a new client ID needs to be obtained via EXCHANGE_ID and the new session established with that client ID.

在服务器重新启动的情况下,当客户端收到NFS4ERR_STALE_CLIENTID错误时,可能会发现其当前客户端ID不再有效。具体情况取决于所涉及会话的特征,特别是会话是否持久(见第2.10.6.5节),但在每种情况下,当客户端尝试使用现有客户端ID建立新会话并收到错误NFS4ERR_STALE_CLIENTID时,客户端都会收到此错误,指示需要通过EXCHANGE_ID和使用该客户端ID建立的新会话获取新的客户端ID。

When a session is not persistent, the client will find out that it needs to create a new session as a result of getting an NFS4ERR_BADSESSION, since the session in question was lost as part of a server restart. When the existing client ID is presented to a server as part of creating a session and that client ID is not recognized, as would happen after a server restart, the server will reject the request with the error NFS4ERR_STALE_CLIENTID.

当会话不是持久性的时,客户端将发现由于获得NFS4ERR_BADSESSION,它需要创建一个新会话,因为该会话在服务器重新启动时丢失。当现有客户端ID作为创建会话的一部分呈现给服务器,并且该客户端ID无法识别时(服务器重新启动后会发生这种情况),服务器将拒绝该请求,错误为NFS4ERR_STALE_CLIENTID。

In the case of the session being persistent, the client will re-establish communication using the existing session after the restart. This session will be associated with the existing client ID but may only be used to retransmit operations that the client previously transmitted and did not see replies to. Replies to operations that the server previously performed will come from the reply cache; otherwise, NFS4ERR_DEADSESSION will be returned. Hence, such a session is referred to as "dead". In this situation, in order to perform new operations, the client needs to establish a new session. If an attempt is made to establish this new session with the existing client ID, the server will reject the request with NFS4ERR_STALE_CLIENTID.

在会话持续的情况下,客户端将在重启后使用现有会话重新建立通信。此会话将与现有客户端ID相关联,但只能用于重新传输客户端以前传输但未看到回复的操作。对服务器先前执行的操作的回复将来自回复缓存;否则,将返回NFS4ERR_DEADSESSION。因此,这种会议被称为“死亡”。在这种情况下,为了执行新的操作,客户端需要建立一个新的会话。如果尝试使用现有客户端ID建立此新会话,服务器将使用NFS4ERR_STALE_CLIENTID拒绝请求。

When NFS4ERR_STALE_CLIENTID is received in either of these situations, the client needs to obtain a new client ID by use of the EXCHANGE_ID operation, then use that client ID as the basis of a new session, and then proceed to any other necessary recovery for the server restart case (see Section 8.4.2).

当在上述任一情况下收到NFS4ERR_STALE_CLIENTID时,客户端需要使用EXCHANGE_ID操作获取新的客户端ID,然后将该客户端ID用作新会话的基础,然后针对服务器重启情况进行任何其他必要的恢复(请参阅第8.4.2节)。

See the descriptions of EXCHANGE_ID (Section 18.35) and CREATE_SESSION (Section 18.36) for a complete specification of these operations.

有关这些操作的完整规范,请参阅EXCHANGE_ID(第18.35节)和CREATE_SESSION(第18.36节)的说明。

2.4.1. Upgrade from NFSv4.0 to NFSv4.1
2.4.1. 从NFSv4.0升级到NFSv4.1

To facilitate upgrade from NFSv4.0 to NFSv4.1, a server may compare a value of data type client_owner4 in an EXCHANGE_ID with a value of data type nfs_client_id4 that was established using the SETCLIENTID operation of NFSv4.0. A server that does so will allow an upgraded client to avoid waiting until the lease (i.e., the lease established by the NFSv4.0 instance client) expires. This requires that the value of data type client_owner4 be constructed the same way as the value of data type nfs_client_id4. If the latter's contents included the server's network address (per the recommendations of the NFSv4.0 specification [30]), and the NFSv4.1 client does not wish to use a client ID that prevents trunking, it should send two EXCHANGE_ID operations. The first EXCHANGE_ID will have a client_owner4 equal to the nfs_client_id4. This will clear the state created by the NFSv4.0 client. The second EXCHANGE_ID will not have the server's network

为了便于从NFSv4.0升级到NFSv4.1,服务器可以将EXCHANGE_ID中的数据类型client_owner4的值与使用NFSv4.0的SETCLIENTID操作建立的数据类型nfs_client_id4的值进行比较。这样做的服务器将允许升级的客户端避免等待租约(即NFSv4.0实例客户端建立的租约)到期。这要求数据类型client_owner4的值的构造方式与数据类型nfs_client_id4的值的构造方式相同。如果后者的内容包括服务器的网络地址(根据NFSv4.0规范[30]的建议),并且NFSv4.1客户端不希望使用阻止中继的客户端ID,则应发送两个交换ID操作。第一个EXCHANGE\u ID的客户端所有者4将等于nfs\u客户端id4。这将清除NFSv4.0客户端创建的状态。第二个EXCHANGE\u ID将没有服务器的网络

address. The state created for the second EXCHANGE_ID will not have to wait for lease expiration, because there will be no state to expire.

住址为第二个EXCHANGE\u ID创建的状态不必等待租约到期,因为没有要到期的状态。

2.4.2. Server Release of Client ID
2.4.2. 客户端ID的服务器版本

NFSv4.1 introduces a new operation called DESTROY_CLIENTID (Section 18.50), which the client SHOULD use to destroy a client ID it no longer needs. This permits graceful, bilateral release of a client ID. The operation cannot be used if there are sessions associated with the client ID, or state with an unexpired lease.

NFSv4.1引入了一个名为DESTROY_CLIENTID(第18.50节)的新操作,客户端应使用该操作销毁不再需要的客户端ID。这允许优雅、双边地释放客户端ID。如果存在与客户端ID关联的会话,或状态为未过期租约,则无法使用该操作。

If the server determines that the client holds no associated state for its client ID (associated state includes unrevoked sessions, opens, locks, delegations, layouts, and wants), the server MAY choose to unilaterally release the client ID in order to conserve resources. If the client contacts the server after this release, the server MUST ensure that the client receives the appropriate error so that it will use the EXCHANGE_ID/CREATE_SESSION sequence to establish a new client ID. The server ought to be very hesitant to release a client ID 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 client ID unless there had been no activity from that client for many minutes. As long as there are sessions, opens, locks, delegations, layouts, or wants, the server MUST NOT release the client ID. See Section 2.10.13.1.4 for discussion on releasing inactive sessions.

如果服务器确定客户端没有其客户端ID的关联状态(关联状态包括未撤销的会话、打开、锁定、委派、布局和需要),则服务器可以选择单方面释放客户端ID以节省资源。如果客户端在此版本后与服务器联系,服务器必须确保客户端接收到适当的错误,以便使用EXCHANGE\u ID/创建\u会话序列来建立新的客户端ID。服务器在释放客户端ID时应该非常犹豫,因为在客户端上从此类事件中恢复的结果工作将与服务器发生故障和重新启动。通常,服务器不会释放客户机ID,除非该客户机在几分钟内没有任何活动。只要存在会话、打开、锁定、委派、布局或需要,服务器就不得释放客户端ID。有关释放非活动会话的讨论,请参阅第2.10.13.1.4节。

2.4.3. Resolving Client Owner Conflicts
2.4.3. 解决客户机所有者冲突

When the server gets an EXCHANGE_ID for a client owner that currently has no state, or that has state but the lease has expired, the server MUST allow the EXCHANGE_ID and confirm the new client ID if followed by the appropriate CREATE_SESSION.

当服务器为当前无状态或有状态但租约已过期的客户端所有者获取EXCHANGE\u ID时,服务器必须允许EXCHANGE\u ID,并确认新客户端ID(如果后跟相应的CREATE\u会话)。

When the server gets an EXCHANGE_ID for a new incarnation of a client owner that currently has an old incarnation with state and an unexpired lease, the server is allowed to dispose of the state of the previous incarnation of the client owner if one of the following is true:

当服务器为当前具有状态的旧版本和未过期租约的客户端所有者的新版本获取EXCHANGE_ID时,如果满足以下条件之一,则允许服务器处置客户端所有者的前一版本的状态:

o The principal that created the client ID for the client owner is the same as the principal that is sending the EXCHANGE_ID operation. Note that if the client ID was created with SP4_MACH_CRED state protection (Section 18.35), the principal MUST be based on RPCSEC_GSS authentication, the RPCSEC_GSS service used

o 为客户端所有者创建客户端ID的主体与发送EXCHANGE\u ID操作的主体相同。请注意,如果客户端ID是使用SP4_MACH_CRED状态保护(第18.35节)创建的,则主体必须基于RPCSEC_GSS身份验证,即使用的RPCSEC_GSS服务

MUST be integrity or privacy, and the same GSS mechanism and principal MUST be used as that used when the client ID was created.

必须是完整性或隐私性,并且必须使用与创建客户端ID时相同的GSS机制和主体。

o The client ID was established with SP4_SSV protection (Section 18.35, Section 2.10.8.3) and the client sends the EXCHANGE_ID with the security flavor set to RPCSEC_GSS using the GSS SSV mechanism (Section 2.10.9).

o 客户端ID是通过SP4_SSV保护(第18.35节,第2.10.8.3节)建立的,客户端使用GSS SSV机制(第2.10.9节)向RPCSEC_GSS发送具有安全设置的EXCHANGE_ID。

o The client ID was established with SP4_SSV protection, and under the conditions described herein, the EXCHANGE_ID was sent with SP4_MACH_CRED state protection. Because the SSV might not persist across client and server restart, and because the first time a client sends EXCHANGE_ID to a server it does not have an SSV, the client MAY send the subsequent EXCHANGE_ID without an SSV RPCSEC_GSS handle. Instead, as with SP4_MACH_CRED protection, the principal MUST be based on RPCSEC_GSS authentication, the RPCSEC_GSS service used MUST be integrity or privacy, and the same GSS mechanism and principal MUST be used as that used when the client ID was created.

o 客户端ID由SP4_SSV保护建立,在本文描述的条件下,交换ID由SP4_MACH_CRED状态保护发送。由于SSV可能不会在客户端和服务器重新启动期间持续存在,并且由于客户端第一次向服务器发送EXCHANGE_ID时没有SSV,因此客户端可能会在没有SSV RPCSEC_GSS句柄的情况下发送后续EXCHANGE_ID。相反,与SP4_MACH_CRED保护一样,主体必须基于RPCSEC_GSS身份验证,使用的RPCSEC_GSS服务必须是完整的或隐私的,并且必须使用与创建客户端ID时相同的GSS机制和主体。

If none of the above situations apply, the server MUST return NFS4ERR_CLID_INUSE.

如果上述情况均不适用,服务器必须返回NFS4ERR\u CLID\u INUSE。

If the server accepts the principal and co_ownerid as matching that which created the client ID, and the co_verifier in the EXCHANGE_ID differs from the co_verifier used when the client ID was created, then after the server receives a CREATE_SESSION that confirms the client ID, the server deletes state. If the co_verifier values are the same (e.g., the client either is updating properties of the client ID (Section 18.35) or is attempting trunking (Section 2.10.5), the server MUST NOT delete state.

如果服务器接受主体和co_ownerid作为与创建客户端ID的匹配项,并且EXCHANGE_ID中的co_验证器与创建客户端ID时使用的co_验证器不同,则在服务器接收到确认客户端ID的CREATE_会话后,服务器将删除状态。如果co_验证器值相同(例如,客户端正在更新客户端ID的属性(第18.35节)或正在尝试中继(第2.10.5节),则服务器不得删除状态。

2.5. Server Owners
2.5. 服务器所有者

The server owner is similar to a client owner (Section 2.4), but unlike the client owner, there is no shorthand server ID. The server owner is defined in the following data type:

服务器所有者类似于客户端所有者(第2.4节),但与客户端所有者不同,没有速记服务器ID。服务器所有者在以下数据类型中定义:

   struct server_owner4 {
    uint64_t       so_minor_id;
    opaque         so_major_id<NFS4_OPAQUE_LIMIT>;
   };
        
   struct server_owner4 {
    uint64_t       so_minor_id;
    opaque         so_major_id<NFS4_OPAQUE_LIMIT>;
   };
        

The server owner is returned from EXCHANGE_ID. When the so_major_id fields are the same in two EXCHANGE_ID results, the connections that each EXCHANGE_ID were sent over can be assumed to address the same

服务器所有者从EXCHANGE\u ID返回。当两个EXCHANGE\u ID结果中的so\u MAGIR\u ID字段相同时,可以假定每个EXCHANGE\u ID发送的连接地址相同

server (as defined in Section 1.6). If the so_minor_id fields are also the same, then not only do both connections connect to the same server, but the session can be shared across both connections. The reader is cautioned that multiple servers may deliberately or accidentally claim to have the same so_major_id or so_major_id/ so_minor_id; the reader should examine Sections 2.10.5 and 18.35 in order to avoid acting on falsely matching server owner values.

服务器(定义见第1.6节)。如果so_minor_id字段也相同,则不仅两个连接都连接到同一服务器,而且会话可以在两个连接之间共享。请读者注意,多台服务器可能会故意或意外地声称具有相同的so_major_id或so_major_id/so_minor_id;读者应检查第2.10.5节和第18.35节,以避免对错误匹配的服务器所有者值采取行动。

The considerations for generating a so_major_id are similar to that for generating a co_ownerid string (see Section 2.4). The consequences of two servers generating conflicting so_major_id values are less dire than they are for co_ownerid conflicts because the client can use RPCSEC_GSS to compare the authenticity of each server (see Section 2.10.5).

生成so_主id的注意事项与生成co_所有者id字符串的注意事项类似(参见第2.4节)。由于客户端可以使用RPCSEC GSS来比较每台服务器的真实性,因此两台服务器生成冲突的so_主要_id值的后果没有共有id冲突那么严重(参见第2.10.5节)。

2.6. Security Service Negotiation
2.6. 安全服务协商

With the NFSv4.1 server potentially offering multiple security mechanisms, the client needs a method to determine or negotiate which mechanism is to be used for its communication with the server. The NFS server may have multiple points within its file system namespace that are available for use by NFS clients. These points can be considered security policy boundaries, and, in some NFS implementations, are tied to NFS export points. In turn, the NFS server may be configured such that each of these security policy boundaries may have different or multiple security mechanisms in use.

由于NFSv4.1服务器可能提供多种安全机制,客户端需要一种方法来确定或协商用于与服务器通信的机制。NFS服务器的文件系统命名空间中可能有多个点可供NFS客户端使用。这些点可以被视为安全策略边界,并且在某些NFS实现中与NFS导出点相关联。反过来,可以配置NFS服务器,以便这些安全策略边界中的每一个都可以使用不同或多个安全机制。

The security negotiation between client and server SHOULD 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 Section 21 for further discussion.

客户端和服务器之间的安全协商应使用安全通道进行,以消除第三方截获协商序列并迫使客户端和服务器选择低于要求或期望的安全级别的可能性。进一步讨论见第21节。

2.6.1. NFSv4.1 Security Tuples
2.6.1. NFSv4.1安全元组

An NFS server can assign one or more "security tuples" to each security policy boundary in its namespace. Each security tuple consists of a security flavor (see Section 2.2.1.1) and, if the flavor is RPCSEC_GSS, a GSS-API mechanism Object Identifier (OID), a GSS-API quality of protection, and an RPCSEC_GSS service.

NFS服务器可以为其命名空间中的每个安全策略边界分配一个或多个“安全元组”。每个安全元组由一个安全风格(见第2.2.1.1节)和一个GSS-API机制对象标识符(OID)、一个GSS-API保护质量和一个RPCSEC_GSS服务组成。

2.6.2. SECINFO and SECINFO_NO_NAME
2.6.2. SECINFO和SECINFO\u NO\u名称

The SECINFO and SECINFO_NO_NAME operations allow the client to determine, on a per-filehandle basis, what security tuple is to be used for server access. In general, the client will not have to use either operation except during initial communication with the server or when the client crosses security policy boundaries at the server.

SECINFO和SECINFO_NO_NAME操作允许客户端根据每个文件句柄确定用于服务器访问的安全元组。通常,客户机不必使用这两种操作,除非在与服务器的初始通信期间或客户机在服务器上跨越安全策略边界时使用。

However, the server's policies may also change at any time and force the client to negotiate a new security tuple.

但是,服务器的策略也可能随时更改,并强制客户端协商新的安全元组。

Where the use of different security tuples would affect the type of access that would be allowed if a request was sent over the same connection used for the SECINFO or SECINFO_NO_NAME operation (e.g., read-only vs. read-write) access, security tuples that allow greater access should be presented first. Where the general level of access is the same and different security flavors limit the range of principals whose privileges are recognized (e.g., allowing or disallowing root access), flavors supporting the greatest range of principals should be listed first.

如果使用不同的安全元组会影响通过用于SECINFO或SECINFO_NO_NAME操作(例如,只读与读写)访问的相同连接发送请求时允许的访问类型,则应首先显示允许更大访问的安全元组。如果访问的一般级别相同,并且不同的安全风格限制了其权限被识别的主体的范围(例如,允许或不允许根访问),则应首先列出支持最大范围主体的风格。

2.6.3. Security Error
2.6.3. 安全错误

Based on the assumption that each NFSv4.1 client and server MUST support a minimum set of security (i.e., Kerberos V5 under RPCSEC_GSS), the NFS client will initiate file access to the server with one of the minimal security tuples. 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 tuple currently being used contravenes the server's security policy. The client is then responsible for determining (see Section 2.6.3.1) what security tuples are available at the server and choosing one that is appropriate for the client.

基于每个NFSv4.1客户端和服务器必须支持一组最低安全性(即RPCSEC_GSS下的Kerberos V5)的假设,NFS客户端将使用一个最低安全元组启动对服务器的文件访问。在与服务器通信期间,客户端可能会收到NFS4ERR_错误秒的NFS错误。此错误允许服务器通知客户端当前使用的安全元组违反服务器的安全策略。然后,客户机负责确定(参见第2.6.3.1节)服务器上有哪些安全元组可用,并选择一个适合客户机的元组。

2.6.3.1. Using NFS4ERR_WRONGSEC, SECINFO, and SECINFO_NO_NAME
2.6.3.1. 使用NFS4ERR_错误秒、SECINFO和SECINFO_NO_名称

This section explains the mechanics of NFSv4.1 security negotiation.

本节解释NFSv4.1安全协商的机制。

2.6.3.1.1. Put Filehandle Operations
2.6.3.1.1. 放置文件句柄操作

The term "put filehandle operation" refers to PUTROOTFH, PUTPUBFH, PUTFH, and RESTOREFH. Each of the subsections herein describes how the server handles a subseries of operations that starts with a put filehandle operation.

术语“put filehandle操作”指PUTROOTFH、PUTPUBFH、PUTFH和RESTOREFH。本文中的每个小节都描述了服务器如何处理以put filehandle操作开始的操作子系列。

2.6.3.1.1.1. Put Filehandle Operation + SAVEFH
2.6.3.1.1.1. Put Filehandle操作+SAVEFH

The client is saving a filehandle for a future RESTOREFH, LINK, or RENAME. SAVEFH MUST NOT return NFS4ERR_WRONGSEC. To determine whether or not the put filehandle operation returns NFS4ERR_WRONGSEC, the server implementation pretends SAVEFH is not in the series of operations and examines which of the situations described in the other subsections of Section 2.6.3.1.1 apply.

客户端正在保存文件句柄,以便将来进行恢复、链接或重命名。SAVEFH不得返回NFS4ERR_错误秒。为了确定put filehandle操作是否返回NFS4ERR_错误秒,服务器实现将假定SAVEFH不在一系列操作中,并检查第2.6.3.1.1节其他小节中描述的情况适用。

2.6.3.1.1.2. Two or More Put Filehandle Operations
2.6.3.1.1.2. 两个或多个Put Filehandle操作

For a series of N put filehandle operations, the server MUST NOT return NFS4ERR_WRONGSEC to the first N-1 put filehandle operations. The Nth put filehandle operation is handled as if it is the first in a subseries of operations. For example, if the server received a COMPOUND request with this series of operations -- PUTFH, PUTROOTFH, LOOKUP -- then the PUTFH operation is ignored for NFS4ERR_WRONGSEC purposes, and the PUTROOTFH, LOOKUP subseries is processed as according to Section 2.6.3.1.1.3.

对于一系列N-1 put filehandle操作,服务器不得将NFS4ERR_错误返回到第一个N-1 put filehandle操作。第n个put filehandle操作的处理方式与操作子系列中的第一个操作相同。例如,如果服务器接收到包含这一系列操作的复合请求——PUTFH、PUTROOTFH、LOOKUP——那么出于NFS4ERR_错误的目的,PUTFH操作将被忽略,PUTROOTFH、LOOKUP子序列将按照第2.6.3.1.1.3节进行处理。

2.6.3.1.1.3. Put Filehandle Operation + LOOKUP (or OPEN of an Existing Name)

2.6.3.1.1.3. 放置文件句柄操作+查找(或打开现有名称)

This situation also applies to a put filehandle operation followed by a LOOKUP or an OPEN operation that specifies an existing component name.

这种情况也适用于put filehandle操作,然后是查找或指定现有组件名称的打开操作。

In this situation, the client is potentially crossing a security policy boundary, and the set of security tuples the parent directory supports may differ from those of the child. The server implementation may decide whether to impose any restrictions on security policy administration. There are at least three approaches (sec_policy_child is the tuple set of the child export, sec_policy_parent is that of the parent).

在这种情况下,客户端可能会跨越安全策略边界,并且父目录支持的安全元组集可能与子目录支持的安全元组集不同。服务器实现可以决定是否对安全策略管理施加任何限制。至少有三种方法(sec_policy_child是子导出的元组集,sec_policy_parent是父导出的元组集)。

(a) sec_policy_child <= sec_policy_parent (<= for subset). This means that the set of security tuples specified on the security policy of a child directory is always a subset of its parent directory.

(a) sec_策略_子项<=sec_策略_父项(<=子集)。这意味着在子目录的安全策略上指定的安全元组集始终是其父目录的子集。

   (b)  sec_policy_child ^ sec_policy_parent != {} (^ for intersection,
        {} for the empty set).  This means that the set of security
        tuples specified on the security policy of a child directory
        always has a non-empty intersection with that of the parent.
        
   (b)  sec_policy_child ^ sec_policy_parent != {} (^ for intersection,
        {} for the empty set).  This means that the set of security
        tuples specified on the security policy of a child directory
        always has a non-empty intersection with that of the parent.
        
   (c)  sec_policy_child ^ sec_policy_parent == {}.  This means that the
        set of security tuples specified on the security policy of a
        child directory may not intersect with that of the parent.  In
        other words, there are no restrictions on how the system
        administrator may set up these tuples.
        
   (c)  sec_policy_child ^ sec_policy_parent == {}.  This means that the
        set of security tuples specified on the security policy of a
        child directory may not intersect with that of the parent.  In
        other words, there are no restrictions on how the system
        administrator may set up these tuples.
        

In order for a server to support approaches (b) (for the case when a client chooses a flavor that is not a member of sec_policy_parent) and (c), the put filehandle operation cannot return NFS4ERR_WRONGSEC when there is a security tuple mismatch. Instead, it should be returned from the LOOKUP (or OPEN by existing component name) that follows.

为了使服务器支持方法(b)(对于客户端选择的味道不是sec_policy_parent的成员的情况)和(c),当存在安全元组不匹配时,put filehandle操作不能返回NFS4ERR_ErrorSec。相反,它应该从后面的查找(或按现有组件名称打开)返回。

Since the above guideline does not contradict approach (a), it should be followed in general. Even if approach (a) is implemented, it is possible for the security tuple used to be acceptable for the target of LOOKUP but not for the filehandles used in the put filehandle operation. The put filehandle operation could be a PUTROOTFH or PUTPUBFH, where the client cannot know the security tuples for the root or public filehandle. Or the security policy for the filehandle used by the put filehandle operation could have changed since the time the filehandle was obtained.

由于上述指南与方法(a)并不矛盾,因此一般应遵循。即使实现了方法(a),用于查找目标的安全元组也可能是可接受的,但对于put filehandle操作中使用的filehandles则可能不是。put filehandle操作可以是PUTROOTFH或PUTPUBFH,其中客户端无法知道根或公共filehandle的安全元组。或者,put filehandle操作使用的filehandle的安全策略可能自获取filehandle时起已更改。

Therefore, an NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC in response to the put filehandle operation if the operation is immediately followed by a LOOKUP or an OPEN by component name.

因此,如果put filehandle操作后紧接着查找或OPEN by组件名称,则NFSv4.1服务器不得返回NFS4ERR_ErrorSec以响应该操作。

2.6.3.1.1.4. Put Filehandle Operation + LOOKUPP
2.6.3.1.1.4. Put Filehandle操作+LOOKUPP

Since SECINFO only works its way down, there is no way LOOKUPP can return NFS4ERR_WRONGSEC without SECINFO_NO_NAME. SECINFO_NO_NAME solves this issue via style SECINFO_STYLE4_PARENT, which works in the opposite direction as SECINFO. As with Section 2.6.3.1.1.3, a put filehandle operation that is followed by a LOOKUPP MUST NOT return NFS4ERR_WRONGSEC. If the server does not support SECINFO_NO_NAME, the client's only recourse is to send the put filehandle operation, LOOKUPP, GETFH sequence of operations with every security tuple it supports.

由于SECINFO只能向下运行,因此如果没有SECINFO\u no\u名称,LOOKUPP无法返回NFS4ERR\u错误sec。SECINFO_NO_NAME通过样式SECINFO_STYLE4_PARENT解决了这个问题,它与SECINFO的工作方向相反。与第2.6.3.1.1.3节一样,后跟LOOKUPP的put filehandle操作不得返回NFS4ERR_错误。如果服务器不支持SECINFO_NO_NAME,那么客户端唯一的办法就是用它支持的每个安全元组发送put filehandle操作、LOOKUPP、GETFH操作序列。

Regardless of whether SECINFO_NO_NAME is supported, an NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC in response to a put filehandle operation if the operation is immediately followed by a LOOKUPP.

无论是否支持SECINFO_NO_NAME,NFSv4.1服务器都不得返回NFS4ERR_ErrorSec以响应put filehandle操作,前提是该操作后面紧跟着LOOKUPP。

2.6.3.1.1.5. Put Filehandle Operation + SECINFO/SECINFO_NO_NAME
2.6.3.1.1.5. 放置文件句柄操作+SECINFO/SECINFO\u否\u名称

A security-sensitive client is allowed to choose a strong security tuple when querying a server to determine a file object's permitted security tuples. The security tuple chosen by the client does not have to be included in the tuple list of the security policy of either the parent directory indicated in the put filehandle operation or the child file object indicated in SECINFO (or any parent directory indicated in SECINFO_NO_NAME). Of course, the server has to be configured for whatever security tuple the client selects; otherwise, the request will fail at the RPC layer with an appropriate authentication error.

当查询服务器以确定文件对象允许的安全元组时,允许安全敏感客户端选择强安全元组。客户端选择的安全元组不必包含在put filehandle操作中指示的父目录或SECINFO中指示的子文件对象(或SECINFO\u NO\u NAME中指示的任何父目录)的安全策略元组列表中。当然,服务器必须针对客户端选择的任何安全元组进行配置;否则,请求将在RPC层失败,并出现相应的身份验证错误。

In theory, there is no connection between the security flavor used by SECINFO or SECINFO_NO_NAME and those supported by the security policy. But in practice, the client may start looking for strong flavors from those supported by the security policy, followed by those in the REQUIRED set.

理论上,SECINFO或SECINFO_no_NAME使用的安全风格与安全策略支持的安全风格之间没有任何联系。但在实践中,客户机可能会开始从安全策略支持的内容中寻找强烈的风格,然后是所需的内容集中的内容。

The NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC to a put filehandle operation that is immediately followed by SECINFO or SECINFO_NO_NAME. The NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC from SECINFO or SECINFO_NO_NAME.

NFSv4.1服务器不得将NFS4ERR_errosec返回到紧跟SECINFO或SECINFO_NO_名称的put filehandle操作。NFSv4.1服务器不得从SECINFO或SECINFO\u NO\u名称返回NFS4errr\u errosec。

2.6.3.1.1.6. Put Filehandle Operation + Nothing
2.6.3.1.1.6. Put Filehandle操作+无

The NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC.

NFSv4.1服务器不得返回NFS4ERR_错误秒。

2.6.3.1.1.7. Put Filehandle Operation + Anything Else
2.6.3.1.1.7. 放置Filehandle操作+任何其他操作

"Anything Else" includes OPEN by filehandle.

“其他任何内容”包括按文件句柄打开。

The security policy enforcement applies to the filehandle specified in the put filehandle operation. Therefore, the put filehandle operation MUST return NFS4ERR_WRONGSEC when there is a security tuple mismatch. This avoids the complexity of adding NFS4ERR_WRONGSEC as an allowable error to every other operation.

安全策略强制应用于put filehandle操作中指定的filehandle。因此,当存在安全元组不匹配时,put filehandle操作必须返回NFS4ERR_errosec。这避免了将NFS4ERR_ErrorSec作为允许的错误添加到每个其他操作中的复杂性。

A COMPOUND containing the series put filehandle operation + SECINFO_NO_NAME (style SECINFO_STYLE4_CURRENT_FH) is an efficient way for the client to recover from NFS4ERR_WRONGSEC.

包含系列put filehandle操作+SECINFO_NO_名称(样式SECINFO_STYLE4_CURRENT_FH)的化合物是客户端从NFS4ERR_错误恢复的有效方法。

The NFSv4.1 server MUST NOT return NFS4ERR_WRONGSEC to any operation other than a put filehandle operation, LOOKUP, LOOKUPP, and OPEN (by component name).

NFSv4.1服务器不得将NFS4ERR_errosec返回到put filehandle操作、查找、查找和打开(按组件名称)以外的任何操作。

2.6.3.1.1.8. Operations after SECINFO and SECINFO_NO_NAME
2.6.3.1.1.8. SECINFO和SECINFO\u NO\u NAME之后的操作

Suppose a client sends a COMPOUND procedure containing the series SEQUENCE, PUTFH, SECINFO_NONAME, READ, and suppose the security tuple used does not match that required for the target file. By rule (see Section 2.6.3.1.1.5), neither PUTFH nor SECINFO_NO_NAME can return NFS4ERR_WRONGSEC. By rule (see Section 2.6.3.1.1.7), READ cannot return NFS4ERR_WRONGSEC. The issue is resolved by the fact that SECINFO and SECINFO_NO_NAME consume the current filehandle (note that this is a change from NFSv4.0). This leaves no current filehandle for READ to use, and READ returns NFS4ERR_NOFILEHANDLE.

假设客户端发送一个包含序列PUTFH、SECINFO_NONAME、READ的复合过程,并假设使用的安全元组与目标文件所需的不匹配。根据规则(见第2.6.3.1.1.5节),PUTFH和SECINFO_NO_NAME都不能返回NFS4ERR_错误SEC。根据规则(见第2.6.3.1.1.7节),READ不能返回NFS4ERR_错误秒。通过SECINFO和SECINFO_NO_NAME使用当前文件句柄(请注意,这是对NFSv4.0的一个更改),问题得以解决。这不会留下当前文件句柄供READ使用,READ返回NFS4ERR_NOFILEHANDLE。

2.6.3.1.2. LINK and RENAME
2.6.3.1.2. 链接和重命名

The LINK and RENAME operations use both the current and saved filehandles. Technically, the server MAY return NFS4ERR_WRONGSEC from LINK or RENAME if the security policy of the saved filehandle rejects the security flavor used in the COMPOUND request's credentials. If the server does so, then if there is no intersection

链接和重命名操作同时使用当前和保存的文件句柄。从技术上讲,如果保存的文件句柄的安全策略拒绝复合请求凭据中使用的安全特性,则服务器可能会从LINK或RENAME返回NFS4ERR_-errosec。如果服务器这样做,那么如果没有交叉点

between the security policies of saved and current filehandles, this means that it will be impossible for the client to perform the intended LINK or RENAME operation.

在已保存和当前文件句柄的安全策略之间,这意味着客户端将无法执行预期的链接或重命名操作。

For example, suppose the client sends this COMPOUND request: SEQUENCE, PUTFH bFH, SAVEFH, PUTFH aFH, RENAME "c" "d", where filehandles bFH and aFH refer to different directories. Suppose no common security tuple exists between the security policies of aFH and bFH. If the client sends the request using credentials acceptable to bFH's security policy but not aFH's policy, then the PUTFH aFH operation will fail with NFS4ERR_WRONGSEC. After a SECINFO_NO_NAME request, the client sends SEQUENCE, PUTFH bFH, SAVEFH, PUTFH aFH, RENAME "c" "d", using credentials acceptable to aFH's security policy but not bFH's policy. The server returns NFS4ERR_WRONGSEC on the RENAME operation.

例如,假设客户端发送这个复合请求:SEQUENCE、PUTFH-bFH、SAVEFH、PUTFH-aFH,重命名为“c”“d”,其中filehandles-bFH和aFH引用不同的目录。假设aFH和bFH的安全策略之间不存在公共安全元组。如果客户端使用bFH的安全策略可接受的凭据(而非aFH的策略)发送请求,则PUTFH aFH操作将因NFS4ERR_错误而失败。在SECINFO_NO_NAME请求之后,客户端使用aFH的安全策略(而非bFH的策略)可接受的凭据发送序列PUTFH bFH SAVEFH PUTFH aFH重命名为“c”“d”。服务器在重命名操作中返回NFS4ERR_错误秒。

To prevent a client from an endless sequence of a request containing LINK or RENAME, followed by a request containing SECINFO_NO_NAME or SECINFO, the server MUST detect when the security policies of the current and saved filehandles have no mutually acceptable security tuple, and MUST NOT return NFS4ERR_WRONGSEC from LINK or RENAME in that situation. Instead the server MUST do one of two things:

为了防止客户端出现包含链接或重命名的无休止的请求序列,然后是包含SECINFO_NO_NAME或SECINFO的请求,服务器必须检测当前和保存的文件句柄的安全策略是否没有相互可接受的安全元组,在这种情况下,不得从链接或重命名返回NFS4ERR_错误秒。相反,服务器必须执行以下两项操作之一:

o The server can return NFS4ERR_XDEV.

o 服务器可以返回nfs4errxdev。

o The server can allow the security policy of the current filehandle to override that of the saved filehandle, and so return NFS4_OK.

o 服务器可以允许当前文件句柄的安全策略覆盖已保存文件句柄的安全策略,因此返回NFS4\u OK。

2.7. Minor Versioning
2.7. 次要版本控制

To address the requirement of an NFS protocol that can evolve as the need arises, the NFSv4.1 protocol contains the rules and framework to allow for future minor changes or versioning.

为了满足NFS协议的需求,该协议可以随着需要而发展,NFSv4.1协议包含允许将来进行微小更改或版本控制的规则和框架。

The base assumption with respect to minor versioning is that any future accepted minor version will be documented in one or more Standards Track RFCs. Minor version 0 of the NFSv4 protocol is represented by [30], and minor version 1 is represented by this RFC. The COMPOUND and CB_COMPOUND procedures support the encoding of the minor version being requested by the client.

关于次要版本控制的基本假设是,任何未来接受的次要版本都将记录在一个或多个标准跟踪RFC中。NFSv4协议的次要版本0由[30]表示,次要版本1由该RFC表示。复合和CB_复合过程支持对客户端请求的次要版本进行编码。

The following items represent the basic rules for the development of minor versions. Note that a future minor version may 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, NFSv4 minor versions will not add to or delete procedures from the NFS program.

为了维护通用RPC模型,NFSv4次要版本不会在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模型。

* Minor versions may append attributes to the bitmap4 that represents sets of attributes and to the fattr4 that represents sets of attribute values.

* 次要版本可以将属性附加到表示属性集的位图4和表示属性值集的fattr4。

This allows for the expansion of the attribute model to allow for future growth or adaptation.

这允许扩展属性模型,以允许将来的增长或适应。

* Minor version X must append any new attributes after the last documented attribute.

* 次要版本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 would 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:

本规则不排除次要版本中的以下改编:

* adding bits to flag fields, such as new attributes to GETATTR's bitmap4 data type, and providing corresponding variants of opaque arrays, such as a notify4 used together with such bitmaps

* 向标志字段添加位,例如GETATTR的bitmap4数据类型的新属性,并提供不透明数组的相应变体,例如与此类位图一起使用的notify4

* adding bits to existing attributes like ACLs that have flag words

* 向现有属性(如具有标志词的ACL)添加位

* extending enumerated types (including NFS4ERR_*) with new values

* 使用新值扩展枚举类型(包括NFS4ERR_*)

* adding cases to a switched union

* 向交换的并集添加案例

4. Minor versions must not modify the structure of existing attributes.

4. 次要版本不得修改现有属性的结构。

5. Minor versions must not delete operations.

5. 次要版本不得删除操作。

This prevents the potential reuse of a particular operation "slot" in a future minor version.

这防止了在将来的次要版本中可能重用特定操作“插槽”。

6. Minor versions must not delete attributes.

6. 次要版本不得删除属性。

7. Minor versions must not delete flag bits or enumeration values.

7. 次要版本不得删除标志位或枚举值。

8. Minor versions may declare an operation MUST NOT be implemented.

8. 次要版本可能声明不得执行操作。

Specifying that an operation MUST NOT be implemented is equivalent to obsoleting an operation. For the client, it means that the operation MUST 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解码错误“删除”请求。这种方法允许在保持其结构的同时淘汰操作,以便将来的次要版本可以重新引入操作。

1. Minor versions may declare that an attribute MUST NOT be implemented.

1. 次要版本可能声明不得实现属性。

2. Minor versions may declare that a flag bit or enumeration value MUST NOT be implemented.

2. 次要版本可能声明不得实现标志位或枚举值。

9. Minor versions may downgrade features from REQUIRED to RECOMMENDED, or RECOMMENDED to OPTIONAL.

9. 次要版本可能会将功能从“必需”降级为“推荐”,或从“推荐”降级为“可选”。

10. Minor versions may upgrade features from OPTIONAL to RECOMMENDED, or RECOMMENDED to REQUIRED.

10. 次要版本可以将功能从可选升级到推荐,或从推荐升级到必需。

11. A client and server that support minor version X SHOULD support minor versions zero through X-1 as well.

11. 支持次要版本X的客户端和服务器也应该支持次要版本零到X-1。

12. Except for infrastructural changes, a minor version must not introduce REQUIRED new features.

12. 除基础设施变更外,次要版本不得引入所需的新功能。

This rule allows for the introduction of new functionality and forces the use of implementation experience before designating a feature as REQUIRED. On the other hand, some classes of features are infrastructural and have broad effects. Allowing infrastructural features to be RECOMMENDED or OPTIONAL complicates implementation of the minor version.

此规则允许引入新功能,并强制在指定所需功能之前使用实现经验。另一方面,某些类别的功能是基础设施,具有广泛的影响。允许推荐或选择基础设施功能会使次要版本的实现复杂化。

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

2.8. Non-RPC-Based Security Services
2.8. 基于非RPC的安全服务

As described in Section 2.2.1.1.1.1, NFSv4.1 relies on RPC for identification, authentication, integrity, and privacy. NFSv4.1 itself provides or enables additional security services as described in the next several subsections.

如第2.2.1.1.1.1节所述,NFSv4.1依赖RPC进行识别、认证、完整性和隐私。NFSv4.1本身提供或启用其他安全服务,如以下几个小节所述。

2.8.1. Authorization
2.8.1. 批准

Authorization to access a file object via an NFSv4.1 operation is ultimately determined by the NFSv4.1 server. A client can predetermine its access to a file object via the OPEN (Section 18.16) and the ACCESS (Section 18.1) operations.

通过NFSv4.1操作访问文件对象的授权最终由NFSv4.1服务器决定。客户机可以通过OPEN(第18.16节)和access(第18.1节)操作预先确定其对文件对象的访问。

Principals with appropriate access rights can modify the authorization on a file object via the SETATTR (Section 18.30) operation. Attributes that affect access rights include mode, owner, owner_group, acl, dacl, and sacl. See Section 5.

具有适当访问权限的主体可以通过SETATTR(第18.30节)操作修改对文件对象的授权。影响访问权限的属性包括模式、所有者、所有者组、acl、dacl和sacl。见第5节。

2.8.2. Auditing
2.8.2. 审计

NFSv4.1 provides auditing on a per-file object basis, via the acl and sacl attributes as described in Section 6. It is outside the scope of this specification to specify audit log formats or management policies.

NFSv4.1通过第6节所述的acl和sacl属性,以每个文件对象为基础提供审计。指定审核日志格式或管理策略超出了本规范的范围。

2.8.3. Intrusion Detection
2.8.3. 入侵检测

NFSv4.1 provides alarm control on a per-file object basis, via the acl and sacl attributes as described in Section 6. Alarms may serve as the basis for intrusion detection. It is outside the scope of this specification to specify heuristics for detecting intrusion via alarms.

NFSv4.1通过第6节所述的acl和sacl属性,以每个文件对象为基础提供报警控制。警报可以作为入侵检测的基础。指定通过报警检测入侵的启发式方法不在本规范的范围内。

2.9. Transport Layers
2.9. 传输层
2.9.1. REQUIRED and RECOMMENDED Properties of Transports
2.9.1. 运输工具的要求和建议属性

NFSv4.1 works over Remote Direct Memory Access (RDMA) and non-RDMA-based transports with the following attributes:

NFSv4.1通过具有以下属性的远程直接内存访问(RDMA)和非基于RDMA的传输工作:

o The transport supports reliable delivery of data, which NFSv4.1 requires but neither NFSv4.1 nor RPC has facilities for ensuring [34].

o 传输支持可靠的数据传输,这是NFSv4.1所要求的,但NFSv4.1和RPC都没有确保数据传输的设施[34]。

o The transport delivers data in the order it was sent. Ordered delivery simplifies detection of transmit errors, and simplifies the sending of arbitrary sized requests and responses via the record marking protocol [3].

o 传输按发送顺序发送数据。有序交付简化了传输错误的检测,简化了通过记录标记协议发送任意大小的请求和响应[3]。

Where an NFSv4.1 implementation supports operation over the IP network protocol, any transport used between NFS and IP MUST be among the IETF-approved congestion control transport protocols. At the time this document was written, the only two transports that had the above attributes were TCP and the Stream Control Transmission Protocol (SCTP). To enhance the possibilities for interoperability, an NFSv4.1 implementation MUST support operation over the TCP transport protocol.

如果NFSv4.1实现支持通过IP网络协议进行操作,则NFS和IP之间使用的任何传输必须在IETF批准的拥塞控制传输协议中。在编写本文档时,只有TCP和流控制传输协议(SCTP)具有上述属性。为了增强互操作性的可能性,NFSv4.1实现必须支持TCP传输协议上的操作。

Even if NFSv4.1 is used over a non-IP network protocol, it is RECOMMENDED that the transport support congestion control.

即使NFSv4.1通过非IP网络协议使用,建议传输支持拥塞控制。

It is permissible for a connectionless transport to be used under NFSv4.1; however, reliable and in-order delivery of data combined with congestion control by the connectionless transport is REQUIRED. As a consequence, UDP by itself MUST NOT be used as an NFSv4.1 transport. NFSv4.1 assumes that a client transport address and server transport address used to send data over a transport together constitute a connection, even if the underlying transport eschews the concept of a connection.

允许根据NFSv4.1使用无连接运输工具;但是,需要通过无连接传输结合拥塞控制可靠有序地传输数据。因此,UDP本身不能用作NFSv4.1传输。NFSv4.1假定用于通过传输发送数据的客户端传输地址和服务器传输地址共同构成连接,即使底层传输避开了连接的概念。

2.9.2. Client and Server Transport Behavior
2.9.2. 客户端和服务器传输行为

If a connection-oriented transport (e.g., TCP) is used, the client and server SHOULD use long-lived connections for at least three reasons:

如果使用面向连接的传输(如TCP),客户端和服务器应使用长寿命连接,原因至少有三个:

1. This will prevent the weakening of the transport's congestion control mechanisms via short-lived connections.

1. 这将防止通过短命连接削弱交通的拥塞控制机制。

2. This will improve performance for the WAN environment by eliminating the need for connection setup handshakes.

2. 这将通过消除连接设置握手的需要来提高WAN环境的性能。

3. The NFSv4.1 callback model differs from NFSv4.0, and requires the client and server to maintain a client-created backchannel (see Section 2.10.3.1) for the server to use.

3. NFSv4.1回调模型不同于NFSv4.0,需要客户端和服务器维护客户端创建的后台通道(参见第2.10.3.1节),以便服务器使用。

In order to reduce congestion, if a connection-oriented transport is used, and the request is not the NULL procedure:

为了减少拥塞,如果使用了面向连接的传输,并且请求不是空过程:

o A requester MUST NOT retry a request unless the connection the request was sent over was lost before the reply was received.

o 请求者不得重试请求,除非发送请求的连接在收到答复之前丢失。

o A replier MUST NOT silently drop a request, even if the request is a retry. (The silent drop behavior of RPCSEC_GSS [4] does not apply because this behavior happens at the RPCSEC_GSS layer, a lower layer in the request processing.) Instead, the replier SHOULD return an appropriate error (see Section 2.10.6.1), or it MAY disconnect the connection.

o 即使请求是重试请求,回复者也不能静默地删除请求。(RPCSEC_GSS[4]的静默丢弃行为不适用,因为此行为发生在RPCSEC_GSS层,即请求处理的较低层)。相反,应答器应返回适当的错误(请参阅第2.10.6.1节),否则可能会断开连接。

When sending a reply, the replier MUST send the reply to the same full network address (e.g., if using an IP-based transport, the source port of the requester is part of the full network address) from which the requester sent the request. If using a connection-oriented transport, replies MUST be sent on the same connection from which the request was received.

发送回复时,回复者必须将回复发送到请求者发送请求的相同完整网络地址(例如,如果使用基于IP的传输,请求者的源端口是完整网络地址的一部分)。如果使用面向连接的传输,则必须在接收请求的同一连接上发送回复。

If a connection is dropped after the replier receives the request but before the replier sends the reply, the replier might have a pending reply. If a connection is established with the same source and destination full network address as the dropped connection, then the replier MUST NOT send the reply until the requester retries the request. The reason for this prohibition is that the requester MAY retry a request over a different connection (provided that connection is associated with the original request's session).

如果在应答器接收到请求后但在应答器发送应答之前断开连接,则应答器可能有一个挂起的应答。如果使用与断开连接相同的源和目标完整网络地址建立连接,则应答器在请求者重试请求之前不得发送应答。此禁止的原因是请求者可以通过不同的连接重试请求(前提是该连接与原始请求的会话相关联)。

When using RDMA transports, there are other reasons for not tolerating retries over the same connection:

使用RDMA传输时,不允许在同一连接上重试还有其他原因:

o RDMA transports use "credits" to enforce flow control, where a credit is a right to a peer to transmit a message. If one peer were to retransmit a request (or reply), it would consume an additional credit. If the replier retransmitted a reply, it would certainly result in an RDMA connection loss, since the requester would typically only post a single receive buffer for each request. If the requester retransmitted a request, the additional credit consumed on the server might lead to RDMA connection failure unless the client accounted for it and decreased its available credit, leading to wasted resources.

o RDMA传输使用“信用”强制流控制,信用是对等方传输消息的权利。如果一个对等方重新传输一个请求(或回复),它将消耗额外的积分。如果应答器重新传输应答,肯定会导致RDMA连接丢失,因为请求者通常只为每个请求发布一个接收缓冲区。如果请求者重新传输了一个请求,服务器上消耗的额外信用可能会导致RDMA连接失败,除非客户端对此进行了说明并减少了其可用信用,从而导致资源浪费。

o RDMA credits present a new issue to the reply cache in NFSv4.1. The reply cache may be used when a connection within a session is lost, such as after the client reconnects. Credit information is a dynamic property of the RDMA connection, and stale values must not be replayed from the cache. This implies that the reply cache contents must not be blindly used when replies are sent from it, and credit information appropriate to the channel must be refreshed by the RPC layer.

o RDMA积分为NFSv4.1中的应答缓存提供了一个新问题。当会话中的连接丢失时,例如在客户端重新连接之后,可以使用应答缓存。信用信息是RDMA连接的动态属性,不能从缓存中重放过时的值。这意味着在从应答缓存中发送应答时,不能盲目使用应答缓存内容,并且RPC层必须刷新适合于通道的信用信息。

In addition, as described in Section 2.10.6.2, while a session is active, the NFSv4.1 requester MUST NOT stop waiting for a reply.

此外,如第2.10.6.2节所述,当会话处于活动状态时,NFSv4.1请求者不得停止等待回复。

2.9.3. Ports
2.9.3. 港口

Historically, NFSv3 servers have listened over TCP port 2049. The registered port 2049 [35] for the NFS protocol should be the default configuration. NFSv4.1 clients SHOULD NOT use the RPC binding protocols as described in [36].

过去,NFSv3服务器通过TCP端口2049侦听。NFS协议的注册端口2049[35]应为默认配置。NFSv4.1客户端不应使用[36]中所述的RPC绑定协议。

2.10. Session
2.10. 一场

NFSv4.1 clients and servers MUST support and MUST use the session feature as described in this section.

NFSv4.1客户端和服务器必须支持并使用本节所述的会话功能。

2.10.1. Motivation and Overview
2.10.1. 动机和概述

Previous versions and minor versions of NFS have suffered from the following:

NFS的早期版本和次要版本存在以下问题:

o Lack of support for Exactly Once Semantics (EOS). This includes lack of support for EOS through server failure and recovery.

o 缺少对精确一次语义(EOS)的支持。这包括通过服务器故障和恢复缺乏对EOS的支持。

o Limited callback support, including no support for sending callbacks through firewalls, and races between replies to normal requests and callbacks.

o 有限的回调支持,包括不支持通过防火墙发送回调,以及对正常请求的回复和回调之间的竞争。

o Limited trunking over multiple network paths.

o 多条网络路径上的有限中继。

o Requiring machine credentials for fully secure operation.

o 需要计算机凭据才能进行完全安全的操作。

Through the introduction of a session, NFSv4.1 addresses the above shortfalls with practical solutions:

NFSv4.1通过引入一个会话,用实用的解决方案解决了上述不足:

o EOS is enabled by a reply cache with a bounded size, making it feasible to keep the cache in persistent storage and enable EOS through server failure and recovery. One reason that previous revisions of NFS did not support EOS was because some EOS approaches often limited parallelism. As will be explained in Section 2.10.6, NFSv4.1 supports both EOS and unlimited parallelism.

o EOS由大小有限的应答缓存启用,因此可以将缓存保留在持久性存储中,并通过服务器故障和恢复启用EOS。以前的NFS版本不支持EOS的一个原因是,某些EOS方法常常限制并行性。如第2.10.6节所述,NFSv4.1支持EOS和无限并行。

o The NFSv4.1 client (defined in Section 1.6, Paragraph 2) creates transport connections and provides them to the server to use for sending callback requests, thus solving the firewall issue (Section 18.34). Races between responses from client requests and

o NFSv4.1客户端(定义见第1.6节第2段)创建传输连接,并将其提供给服务器用于发送回调请求,从而解决防火墙问题(第18.34节)。来自客户端请求的响应与来自

callbacks caused by the requests are detected via the session's sequencing properties that are a consequence of EOS (Section 2.10.6.3).

请求引起的回调通过会话的序列属性进行检测,该属性是EOS的结果(第2.10.6.3节)。

o The NFSv4.1 client can associate an arbitrary number of connections with the session, and thus provide trunking (Section 2.10.5).

o NFSv4.1客户端可以将任意数量的连接与会话相关联,从而提供中继(第2.10.5节)。

o The NFSv4.1 client and server produces a session key independent of client and server machine credentials which can be used to compute a digest for protecting critical session management operations (Section 2.10.8.3).

o NFSv4.1客户端和服务器生成独立于客户端和服务器计算机凭据的会话密钥,可用于计算摘要以保护关键会话管理操作(第2.10.8.3节)。

o The NFSv4.1 client can also create secure RPCSEC_GSS contexts for use by the session's backchannel that do not require the server to authenticate to a client machine principal (Section 2.10.8.2).

o NFSv4.1客户端还可以创建安全的RPCSEC_GSS上下文,供会话的反向通道使用,而不需要服务器向客户端计算机主体进行身份验证(第2.10.8.2节)。

A session is a dynamically created, long-lived server object created by a client and used over time from one or more transport connections. Its function is to maintain the server's state relative to the connection(s) belonging to a client instance. This state is entirely independent of the connection itself, and indeed the state exists whether or not the connection exists. A client may have one or more sessions associated with it so that client-associated state may be accessed using any of the sessions associated with that client's client ID, when connections are associated with those sessions. When no connections are associated with any of a client ID's sessions for an extended time, such objects as locks, opens, delegations, layouts, etc. are subject to expiration. The session serves as an object representing a means of access by a client to the associated client state on the server, independent of the physical means of access to that state.

会话是由客户端创建的动态创建的、长期存在的服务器对象,通过一个或多个传输连接随时间使用。它的功能是维护服务器相对于属于客户端实例的连接的状态。此状态完全独立于连接本身,并且无论连接是否存在,该状态都确实存在。客户机可以具有与其关联的一个或多个会话,以便当连接与这些会话关联时,可以使用与该客户机的客户机ID关联的任何会话来访问客户机关联状态。如果在较长时间内没有连接与任何客户端ID的会话相关联,则锁定、打开、委派、布局等对象将过期。会话用作表示客户端访问服务器上关联客户端状态的方式的对象,独立于访问该状态的物理方式。

A single client may create multiple sessions. A single session MUST NOT serve multiple clients.

一个客户端可以创建多个会话。单个会话不能服务于多个客户端。

2.10.2. NFSv4 Integration
2.10.2. NFSv4集成

Sessions are part of NFSv4.1 and not NFSv4.0. Normally, a major infrastructure change such as sessions would require a new major version number to an Open Network Computing (ONC) RPC program like NFS. However, because NFSv4 encapsulates its functionality in a single procedure, COMPOUND, and because COMPOUND can support an arbitrary number of operations, sessions have been added to NFSv4.1 with little difficulty. COMPOUND includes a minor version number field, and for NFSv4.1 this minor version is set to 1. When the NFSv4 server processes a COMPOUND with the minor version set to 1, it expects a different set of operations than it does for NFSv4.0.

会话是NFSv4.1的一部分,而不是NFSv4.0。通常情况下,诸如会话之类的主要基础结构更改需要开放网络计算(ONC)RPC程序(如NFS)的新主要版本号。然而,由于NFSv4将其功能封装在一个过程component中,并且component可以支持任意数量的操作,因此将会话添加到NFSv4.1并不困难。复合物包括一个次要版本号字段,对于NFSv4.1,该次要版本设置为1。当NFSv4服务器处理次要版本设置为1的化合物时,它需要一组与NFSv4.0不同的操作。

NFSv4.1 defines the SEQUENCE operation, which is required for every COMPOUND that operates over an established session, with the exception of some session administration operations, such as DESTROY_SESSION (Section 18.37).

NFSv4.1定义了序列操作,该操作是在已建立会话上运行的每个化合物所必需的,但某些会话管理操作除外,例如销毁会话(第18.37节)。

2.10.2.1. SEQUENCE and CB_SEQUENCE
2.10.2.1. 序列与CB_序列

In NFSv4.1, when the SEQUENCE operation is present, it MUST be the first operation in the COMPOUND procedure. The primary purpose of SEQUENCE is to carry the session identifier. The session identifier associates all other operations in the COMPOUND procedure with a particular session. SEQUENCE also contains required information for maintaining EOS (see Section 2.10.6). Session-enabled NFSv4.1 COMPOUND requests thus have the form:

在NFSv4.1中,当序列操作存在时,它必须是复合程序中的第一个操作。SEQUENCE的主要目的是携带会话标识符。会话标识符将复合过程中的所有其他操作与特定会话相关联。序列还包含维护EOS所需的信息(见第2.10.6节)。因此,启用会话的NFSv4.1复合请求的形式如下:

       +-----+--------------+-----------+------------+-----------+----
       | tag | minorversion | numops    |SEQUENCE op | op + args | ...
       |     |   (== 1)     | (limited) |  + args    |           |
       +-----+--------------+-----------+------------+-----------+----
        
       +-----+--------------+-----------+------------+-----------+----
       | tag | minorversion | numops    |SEQUENCE op | op + args | ...
       |     |   (== 1)     | (limited) |  + args    |           |
       +-----+--------------+-----------+------------+-----------+----
        

and the replies have the form:

答复的形式如下:

       +------------+-----+--------+-------------------------------+--//
       |last status | tag | numres |status + SEQUENCE op + results |  //
       +------------+-----+--------+-------------------------------+--//
               //-----------------------+----
               // status + op + results | ...
               //-----------------------+----
        
       +------------+-----+--------+-------------------------------+--//
       |last status | tag | numres |status + SEQUENCE op + results |  //
       +------------+-----+--------+-------------------------------+--//
               //-----------------------+----
               // status + op + results | ...
               //-----------------------+----
        

A CB_COMPOUND procedure request and reply has a similar form to COMPOUND, but instead of a SEQUENCE operation, there is a CB_SEQUENCE operation. CB_COMPOUND also has an additional field called "callback_ident", which is superfluous in NFSv4.1 and MUST be ignored by the client. CB_SEQUENCE has the same information as SEQUENCE, and also includes other information needed to resolve callback races (Section 2.10.6.3).

CB_复合过程request and reply的形式与component类似,但它不是序列操作,而是CB_序列操作。CB_component还有一个名为“callback_ident”的附加字段,这在NFSv4.1中是多余的,客户端必须忽略。CB_序列具有与序列相同的信息,还包括解决回调争用所需的其他信息(第2.10.6.3节)。

2.10.2.2. Client ID and Session Association
2.10.2.2. 客户端ID和会话关联

Each client ID (Section 2.4) can have zero or more active sessions. A client ID and associated session are required to perform file access in NFSv4.1. Each time a session is used (whether by a client sending a request to the server or the client replying to a callback request from the server), the state leased to its associated client ID is automatically renewed.

每个客户端ID(第2.4节)可以有零个或多个活动会话。在NFSv4.1中执行文件访问需要客户端ID和相关会话。每次使用会话时(无论是客户端向服务器发送请求,还是客户端答复服务器的回调请求),都会自动续订租给其关联客户端ID的状态。

State (which can consist of share reservations, locks, delegations, and layouts (Section 1.7.4)) is tied to the client ID. Client state is not tied to any individual session. Successive state changing operations from a given state owner MAY go over different sessions, provided the session is associated with the same client ID. A callback MAY arrive over a different session than that of the request that originally acquired the state pertaining to the callback. For example, if session A is used to acquire a delegation, a request to recall the delegation MAY arrive over session B if both sessions are associated with the same client ID. Sections 2.10.8.1 and 2.10.8.2 discuss the security considerations around callbacks.

状态(可包括共享保留、锁、委托和布局(第1.7.4节))与客户端ID绑定。客户端状态不与任何单个会话绑定。来自给定状态所有者的连续状态更改操作可能会经过不同的会话,前提是会话与相同的客户端ID相关联。回调可能会通过不同的会话到达,而不是通过最初获取回调状态的请求的会话到达。例如,如果会话A用于获取委派,则如果两个会话都与相同的客户端ID关联,则调用委派的请求可能会在会话B期间到达。第2.10.8.1节和第2.10.8.2节讨论了有关回调的安全注意事项。

2.10.3. Channels
2.10.3. 渠道

A channel is not a connection. A channel represents the direction ONC RPC requests are sent.

通道不是连接。通道表示ONC RPC请求的发送方向。

Each session has one or two channels: the fore channel and the backchannel. Because there are at most two channels per session, and because each channel has a distinct purpose, channels are not assigned identifiers.

每个会话有一个或两个通道:前通道和后通道。因为每个会话最多有两个通道,而且每个通道都有不同的用途,所以没有为通道分配标识符。

The fore channel is used for ordinary requests from the client to the server, and carries COMPOUND requests and responses. A session always has a fore channel.

前端通道用于从客户端到服务器的普通请求,并承载复合请求和响应。会话总是有一个前置通道。

The backchannel is used for callback requests from server to client, and carries CB_COMPOUND requests and responses. Whether or not there is a backchannel is a decision made by the client; however, many features of NFSv4.1 require a backchannel. NFSv4.1 servers MUST support backchannels.

反向通道用于从服务器到客户端的回调请求,并承载CB_复合请求和响应。是否存在反向通道由客户决定;但是,NFSv4.1的许多功能都需要反向通道。NFSv4.1服务器必须支持反向通道。

Each session has resources for each channel, including separate reply caches (see Section 2.10.6.1). Note that even the backchannel requires a reply cache (or, at least, a slot table in order to detect retries) because some callback operations are nonidempotent.

每个会话都有每个通道的资源,包括单独的应答缓存(见第2.10.6.1节)。请注意,由于某些回调操作是非幂等的,因此即使是反向通道也需要一个应答缓存(或者,至少是一个插槽表来检测重试)。

2.10.3.1. Association of Connections, Channels, and Sessions
2.10.3.1. 连接、通道和会话的关联

Each channel is associated with zero or more transport connections (whether of the same transport protocol or different transport protocols). A connection can be associated with one channel or both channels of a session; the client and server negotiate whether a connection will carry traffic for one channel or both channels via the CREATE_SESSION (Section 18.36) and the BIND_CONN_TO_SESSION (Section 18.34) operations. When a session is created via CREATE_SESSION, the connection that transported the CREATE_SESSION request is automatically associated with the fore channel, and

每个通道与零个或多个传输连接相关联(无论是相同的传输协议还是不同的传输协议)。连接可以与会话的一个通道或两个通道相关联;客户机和服务器通过CREATE_会话(第18.36节)和BIND_CONN_TO_会话(第18.34节)操作协商连接是为一个通道还是两个通道传输流量。当通过CREATE_会话创建会话时,传输CREATE_会话请求的连接将自动与前频道关联,并且

optionally the backchannel. If the client specifies no state protection (Section 18.35) when the session is created, then when SEQUENCE is transmitted on a different connection, the connection is automatically associated with the fore channel of the session specified in the SEQUENCE operation.

可以选择反向通道。如果创建会话时客户端未指定状态保护(第18.35节),则当在不同连接上传输序列时,该连接将自动与序列操作中指定的会话前通道相关联。

A connection's association with a session is not exclusive. A connection associated with the channel(s) of one session may be simultaneously associated with the channel(s) of other sessions including sessions associated with other client IDs.

连接与会话的关联不是独占的。与一个会话的信道相关联的连接可以同时与其他会话的信道相关联,包括与其他客户端id相关联的会话。

It is permissible for connections of multiple transport types to be associated with the same channel. For example, both TCP and RDMA connections can be associated with the fore channel. In the event an RDMA and non-RDMA connection are associated with the same channel, the maximum number of slots SHOULD be at least one more than the total number of RDMA credits (Section 2.10.6.1). This way, if all RDMA credits are used, the non-RDMA connection can have at least one outstanding request. If a server supports multiple transport types, it MUST allow a client to associate connections from each transport to a channel.

允许多个传输类型的连接与同一通道相关联。例如,TCP和RDMA连接都可以与前通道相关联。如果RDMA和非RDMA连接与同一信道相关联,则插槽的最大数量应至少比RDMA信用总数多一个(第2.10.6.1节)。这样,如果使用了所有RDMA信用,则非RDMA连接可以至少有一个未完成的请求。如果服务器支持多种传输类型,则必须允许客户端将从每个传输到通道的连接关联起来。

It is permissible for a connection of one type of transport to be associated with the fore channel, and a connection of a different type to be associated with the backchannel.

允许一种类型的运输连接与前通道相关联,另一种类型的运输连接与后通道相关联。

2.10.4. Server Scope
2.10.4. 服务器范围

Servers each specify a server scope value in the form of an opaque string eir_server_scope returned as part of the results of an EXCHANGE_ID operation. The purpose of the server scope is to allow a group of servers to indicate to clients that a set of servers sharing the same server scope value has arranged to use compatible values of otherwise opaque identifiers. Thus, the identifiers generated by one server of that set may be presented to another of that same scope.

每个服务器都以不透明字符串的形式指定服务器作用域值。eir_服务器作用域作为EXCHANGE_ID操作结果的一部分返回。服务器作用域的目的是允许一组服务器向客户端指示共享相同服务器作用域值的一组服务器已安排使用其他不透明标识符的兼容值。因此,由该集合的一个服务器生成的标识符可以呈现给该相同范围的另一个服务器。

The use of such compatible values does not imply that a value generated by one server will always be accepted by another. In most cases, it will not. However, a server will not accept a value generated by another inadvertently. When it does accept it, it will be because it is recognized as valid and carrying the same meaning as on another server of the same scope.

使用此类兼容值并不意味着一台服务器生成的值总是会被另一台服务器接受。在大多数情况下,它不会。但是,服务器不会接受其他服务器无意中生成的值。当它接受它时,这将是因为它被认为是有效的,并且与同一范围的另一台服务器上的内容相同。

When servers are of the same server scope, this compatibility of values applies to the follow identifiers:

当服务器属于相同的服务器作用域时,此值的兼容性适用于以下标识符:

o Filehandle values. A filehandle value accepted by two servers of the same server scope denotes the same object. A WRITE operation sent to one server is reflected immediately in a READ sent to the other, and locks obtained on one server conflict with those requested on the other.

o 文件句柄值。同一服务器作用域的两台服务器接受的filehandle值表示同一对象。发送到一台服务器的写操作立即反映在发送到另一台服务器的读操作中,并且在一台服务器上获得的锁与在另一台服务器上请求的锁冲突。

o Session ID values. A session ID value accepted by two servers of the same server scope denotes the same session.

o 会话ID值。相同服务器作用域的两台服务器接受的会话ID值表示相同的会话。

o Client ID values. A client ID value accepted as valid by two servers of the same server scope is associated with two clients with the same client owner and verifier.

o 客户端ID值。具有相同服务器作用域的两台服务器接受为有效的客户端ID值与具有相同客户端所有者和验证器的两台客户端相关联。

o State ID values. A state ID value is recognized as valid when the corresponding client ID is recognized as valid. If the same stateid value is accepted as valid on two servers of the same scope and the client IDs on the two servers represent the same client owner and verifier, then the two stateid values designate the same set of locks and are for the same file.

o 状态ID值。当相应的客户端ID被识别为有效时,状态ID值被识别为有效。如果相同的stateid值在相同作用域的两台服务器上被接受为有效,并且两台服务器上的客户端ID表示相同的客户端所有者和验证器,则这两个stateid值指定相同的锁集,并且用于相同的文件。

o Server owner values. When the server scope values are the same, server owner value may be validly compared. In cases where the server scope values are different, server owner values are treated as different even if they contain all identical bytes.

o 服务器所有者值。当服务器作用域值相同时,可以有效地比较服务器所有者值。在服务器作用域值不同的情况下,服务器所有者值将被视为不同的值,即使它们包含所有相同的字节。

The coordination among servers required to provide such compatibility can be quite minimal, and limited to a simple partition of the ID space. The recognition of common values requires additional implementation, but this can be tailored to the specific situations in which that recognition is desired.

提供这种兼容性所需的服务器之间的协调可能非常小,并且仅限于ID空间的简单分区。公共价值的识别需要额外的实现,但这可以根据需要识别的特定情况进行调整。

Clients will have occasion to compare the server scope values of multiple servers under a number of circumstances, each of which will be discussed under the appropriate functional section:

客户将有机会在多种情况下比较多台服务器的服务器范围值,每种情况将在适当的功能部分中讨论:

o When server owner values received in response to EXCHANGE_ID operations sent to multiple network addresses are compared for the purpose of determining the validity of various forms of trunking, as described in Section 2.10.5.

o 如第2.10.5节所述,为了确定各种中继形式的有效性,比较针对发送到多个网络地址的EXCHANGE_ID操作而收到的服务器所有者值时。

o When network or server reconfiguration causes the same network address to possibly be directed to different servers, with the necessity for the client to determine when lock reclaim should be attempted, as described in Section 8.4.2.1.

o 如第8.4.2.1节所述,当网络或服务器重新配置导致相同的网络地址可能定向到不同的服务器时,客户端需要确定何时应尝试锁回收。

o When file system migration causes the transfer of responsibility for a file system between servers and the client needs to determine whether state has been transferred with the file system

o 当文件系统迁移导致服务器之间的文件系统责任转移时,客户端需要确定状态是否已随文件系统一起转移

(as described in Section 11.7.7) or whether the client needs to reclaim state on a similar basis as in the case of server restart, as described in Section 8.4.2.

(如第11.7.7节所述)或客户端是否需要在与服务器重启类似的基础上恢复状态,如第8.4.2节所述。

When two replies from EXCHANGE_ID, each from two different server network addresses, have the same server scope, there are a number of ways a client can validate that the common server scope is due to two servers cooperating in a group.

当来自EXCHANGE_ID的两个答复(每个答复来自两个不同的服务器网络地址)具有相同的服务器作用域时,客户机可以通过多种方式验证公共服务器作用域是否是由于两台服务器在一个组中协作所致。

o If both EXCHANGE_ID requests were sent with RPCSEC_GSS authentication and the server principal is the same for both targets, the equality of server scope is validated. It is RECOMMENDED that two servers intending to share the same server scope also share the same principal name.

o 如果两个EXCHANGE_ID请求均通过RPCSEC_GSS身份验证发送,并且两个目标的服务器主体相同,则验证服务器作用域的平等性。建议打算共享相同服务器作用域的两台服务器也共享相同的主体名称。

o The client may accept the appearance of the second server in the fs_locations or fs_locations_info attribute for a relevant file system. For example, if there is a migration event for a particular file system or there are locks to be reclaimed on a particular file system, the attributes for that particular file system may be used. The client sends the GETATTR request to the first server for the fs_locations or fs_locations_info attribute with RPCSEC_GSS authentication. It may need to do this in advance of the need to verify the common server scope. If the client successfully authenticates the reply to GETATTR, and the GETATTR request and reply containing the fs_locations or fs_locations_info attribute refers to the second server, then the equality of server scope is supported. A client may choose to limit the use of this form of support to information relevant to the specific file system involved (e.g. a file system being migrated).

o 对于相关文件系统,客户端可以接受第二台服务器在fs_locations或fs_locations_info属性中的外观。例如,如果特定文件系统存在迁移事件,或者特定文件系统上存在要回收的锁,则可以使用该特定文件系统的属性。客户机向第一台服务器发送GETATTR请求,请求fs_位置或具有RPCSEC_GSS身份验证的fs_位置信息属性。它可能需要在验证公共服务器作用域之前执行此操作。如果客户端成功验证了对GETATTR的回复,并且包含fs_locations或fs_locations_info属性的GETATTR请求和回复引用了第二台服务器,则支持服务器作用域相等。客户可以选择将此支持形式的使用限制为与所涉及的特定文件系统(例如,正在迁移的文件系统)相关的信息。

2.10.5. Trunking
2.10.5. 中继线

Trunking is the use of multiple connections between a client and server in order to increase the speed of data transfer. NFSv4.1 supports two types of trunking: session trunking and client ID trunking.

中继是在客户端和服务器之间使用多个连接以提高数据传输速度。NFSv4.1支持两种类型的中继:会话中继和客户端ID中继。

NFSv4.1 servers MUST support both forms of trunking within the context of a single server network address and MUST support both forms within the context of the set of network addresses used to access a single server. NFSv4.1 servers in a clustered configuration MAY allow network addresses for different servers to use client ID trunking.

NFSv4.1服务器必须在单个服务器网络地址的上下文中支持两种形式的中继,并且必须在用于访问单个服务器的一组网络地址的上下文中支持两种形式。群集配置中的NFSv4.1服务器可能允许不同服务器的网络地址使用客户端ID中继。

Clients may use either form of trunking as long as they do not, when trunking between different server network addresses, violate the servers' mandates as to the kinds of trunking to be allowed (see

当在不同的服务器网络地址之间进行中继时,客户端可以使用任何一种中继形式,只要它们不违反服务器关于允许的中继类型的规定(请参阅

below). With regard to callback channels, the client MUST allow the server to choose among all callback channels valid for a given client ID and MUST support trunking when the connections supporting the backchannel allow session or client ID trunking to be used for callbacks.

下)。关于回调通道,客户机必须允许服务器在所有对给定客户机ID有效的回调通道中进行选择,并且当支持反向通道的连接允许会话或客户机ID中继用于回调时,必须支持中继。

Session trunking is essentially the association of multiple connections, each with potentially different target and/or source network addresses, to the same session. When the target network addresses (server addresses) of the two connections are the same, the server MUST support such session trunking. When the target network addresses are different, the server MAY indicate such support using the data returned by the EXCHANGE_ID operation (see below).

会话中继本质上是多个连接与同一会话的关联,每个连接具有可能不同的目标和/或源网络地址。当两个连接的目标网络地址(服务器地址)相同时,服务器必须支持此类会话中继。当目标网络地址不同时,服务器可以使用EXCHANGE_ID操作返回的数据指示这种支持(见下文)。

Client ID trunking is the association of multiple sessions to the same client ID. Servers MUST support client ID trunking for two target network addresses whenever they allow session trunking for those same two network addresses. In addition, a server MAY, by presenting the same major server owner ID (Section 2.5) and server scope (Section 2.10.4), allow an additional case of client ID trunking. When two servers return the same major server owner and server scope, it means that the two servers are cooperating on locking state management, which is a prerequisite for client ID trunking.

客户端ID中继是多个会话与同一客户端ID的关联。服务器必须支持两个目标网络地址的客户端ID中继,只要它们允许对这两个相同的网络地址进行会话中继。此外,通过提供相同的主要服务器所有者ID(第2.5节)和服务器作用域(第2.10.4节),服务器可以允许额外的客户端ID中继。当两台服务器返回相同的主服务器所有者和服务器作用域时,这意味着这两台服务器在锁定状态管理方面进行合作,这是客户端ID中继的先决条件。

Distinguishing when the client is allowed to use session and client ID trunking requires understanding how the results of the EXCHANGE_ID (Section 18.35) operation identify a server. Suppose a client sends EXCHANGE_IDs over two different connections, each with a possibly different target network address, but each EXCHANGE_ID operation has the same value in the eia_clientowner field. If the same NFSv4.1 server is listening over each connection, then each EXCHANGE_ID result MUST return the same values of eir_clientid, eir_server_owner.so_major_id, and eir_server_scope. The client can then treat each connection as referring to the same server (subject to verification; see Section 2.10.5.1 later in this section), and it can use each connection to trunk requests and replies. The client's choice is whether session trunking or client ID trunking applies.

区分何时允许客户端使用会话和客户端ID中继需要了解EXCHANGE_ID(第18.35节)操作的结果如何识别服务器。假设客户端通过两个不同的连接发送EXCHANGE\u ID,每个连接的目标网络地址可能不同,但每个EXCHANGE\u ID操作在eia\u clientowner字段中具有相同的值。如果相同的NFSv4.1服务器正在侦听每个连接,则每个EXCHANGE\u ID结果必须返回相同的eir\u clientid、eir\u server\u owner.so\u major\u ID和eir\u server\u scope值。然后,客户端可以将每个连接视为指向同一服务器(有待验证;请参阅本节后面的第2.10.5.1节),并且可以使用每个连接来中继请求和回复。客户端的选择是应用会话中继还是客户端ID中继。

Session Trunking. If the eia_clientowner argument is the same in two different EXCHANGE_ID requests, and the eir_clientid, eir_server_owner.so_major_id, eir_server_owner.so_minor_id, and eir_server_scope results match in both EXCHANGE_ID results, then the client is permitted to perform session trunking. If the client has no session mapping to the tuple of eir_clientid, eir_server_owner.so_major_id, eir_server_scope, and eir_server_owner.so_minor_id, then it creates the session via a CREATE_SESSION operation over one of the connections, which

会话中继。如果eia_clientowner参数在两个不同的EXCHANGE_ID请求中相同,并且eir_clientid、eir_server_owner.so_major_ID、eir_server_owner.so_minor_ID和eir_server_scope结果在两个EXCHANGE_ID结果中匹配,则允许客户端执行会话中继。如果客户端没有到eir_clientid、eir_server_owner.so_major_id、eir_server_scope和eir_server_owner.so_minor_id元组的会话映射,则它通过一个连接上的CREATE_会话操作创建会话,该操作

associates the connection to the session. If there is a session for the tuple, the client can send BIND_CONN_TO_SESSION to associate the connection to the session.

将连接与会话相关联。如果元组有会话,客户端可以发送BIND_CONN_TO_session以将连接与会话相关联。

Of course, if the client does not desire to use session trunking, it is not required to do so. It can invoke CREATE_SESSION on the connection. This will result in client ID trunking as described below. It can also decide to drop the connection if it does not choose to use trunking.

当然,如果客户端不希望使用会话中继,则不需要这样做。它可以在连接上调用CREATE_会话。这将导致客户端ID中继,如下所述。如果不选择使用中继,它还可以决定断开连接。

Client ID Trunking. If the eia_clientowner argument is the same in two different EXCHANGE_ID requests, and the eir_clientid, eir_server_owner.so_major_id, and eir_server_scope results match in both EXCHANGE_ID results, then the client is permitted to perform client ID trunking (regardless of whether the eir_server_owner.so_minor_id results match). The client can associate each connection with different sessions, where each session is associated with the same server.

客户端ID中继。如果eia_clientowner参数在两个不同的EXCHANGE_ID请求中相同,并且eir_clientid、eir_server_owner.so_major_ID和eir_server_scope结果在两个EXCHANGE_ID结果中匹配,则允许客户端执行客户端ID中继(无论eir_server_owner.so_minor_ID结果是否匹配)。客户端可以将每个连接与不同的会话相关联,其中每个会话与同一服务器相关联。

The client completes the act of client ID trunking by invoking CREATE_SESSION on each connection, using the same client ID that was returned in eir_clientid. These invocations create two sessions and also associate each connection with its respective session. The client is free to decline to use client ID trunking by simply dropping the connection at this point.

客户机通过在每个连接上调用CREATE_会话来完成客户机ID中继的操作,使用在eir_clientid中返回的相同客户机ID。这些调用创建两个会话,并将每个连接与其各自的会话相关联。客户端可以自由地拒绝使用客户端ID中继,只需在此时断开连接即可。

When doing client ID trunking, locking state is shared across sessions associated with that same client ID. This requires the server to coordinate state across sessions.

执行客户端ID中继时,锁定状态在与同一客户端ID关联的会话之间共享。这要求服务器在会话之间协调状态。

The client should be prepared for the possibility that eir_server_owner values may be different on subsequent EXCHANGE_ID requests made to the same network address, as a result of various sorts of reconfiguration events. When this happens and the changes result in the invalidation of previously valid forms of trunking, the client should cease to use those forms, either by dropping connections or by adding sessions. For a discussion of lock reclaim as it relates to such reconfiguration events, see Section 8.4.2.1.

客户端应做好准备,以防由于各种各样的重新配置事件,对同一网络地址发出的后续EXCHANGE\u ID请求可能会导致eir\u服务器\u所有者值不同。当这种情况发生并且更改导致以前有效的中继形式无效时,客户端应该停止使用这些形式,方法是断开连接或添加会话。有关与此类重新配置事件相关的锁回收的讨论,请参见第8.4.2.1节。

2.10.5.1. Verifying Claims of Matching Server Identity
2.10.5.1. 验证匹配服务器标识的声明

When two servers over two connections claim matching or partially matching eir_server_owner, eir_server_scope, and eir_clientid values, the client does not have to trust the servers' claims. The client may verify these claims before trunking traffic in the following ways:

当两个连接上的两台服务器声明匹配或部分匹配eir_服务器_所有者、eir_服务器_作用域和eir_客户端ID值时,客户端不必信任服务器的声明。客户可通过以下方式在中继流量之前验证这些声明:

o For session trunking, clients SHOULD reliably verify if connections between different network paths are in fact associated with the same NFSv4.1 server and usable on the same session, and servers MUST allow clients to perform reliable verification. When a client ID is created, the client SHOULD specify that BIND_CONN_TO_SESSION is to be verified according to the SP4_SSV or SP4_MACH_CRED (Section 18.35) state protection options. For SP4_SSV, reliable verification depends on a shared secret (the SSV) that is established via the SET_SSV (Section 18.47) operation.

o 对于会话中继,客户端应可靠地验证不同网络路径之间的连接是否与同一NFSv4.1服务器相关联并在同一会话上可用,并且服务器必须允许客户端执行可靠的验证。创建客户端ID时,客户端应指定根据SP4\U SSV或SP4\U MACH\U CRED(第18.35节)状态保护选项验证绑定连接到会话。对于SP4_SSV,可靠验证取决于通过SET_SSV(第18.47节)操作建立的共享秘密(SSV)。

When a new connection is associated with the session (via the BIND_CONN_TO_SESSION operation, see Section 18.34), if the client specified SP4_SSV state protection for the BIND_CONN_TO_SESSION operation, the client MUST send the BIND_CONN_TO_SESSION with RPCSEC_GSS protection, using integrity or privacy, and an RPCSEC_GSS handle created with the GSS SSV mechanism (Section 2.10.9).

当新连接与会话关联时(通过BIND_CONN_TO_会话操作,请参见第18.34节),如果客户端为BIND_CONN_TO_会话操作指定了SP4_SSV状态保护,则客户端必须使用完整性或隐私发送具有RPCSEC_GSS保护的BIND_CONN_TO_会话,以及使用GSS SSV机构创建的RPCSEC_GSS手柄(第2.10.9节)。

If the client mistakenly tries to associate a connection to a session of a wrong server, the server will either reject the attempt because it is not aware of the session identifier of the BIND_CONN_TO_SESSION arguments, or it will reject the attempt because the RPCSEC_GSS authentication fails. Even if the server mistakenly or maliciously accepts the connection association attempt, the RPCSEC_GSS verifier it computes in the response will not be verified by the client, so the client will know it cannot use the connection for trunking the specified session.

如果客户端错误地尝试将连接与错误服务器的会话相关联,服务器将拒绝尝试,因为它不知道BIND_CONN_to_会话参数的会话标识符,或者它将拒绝尝试,因为RPCSEC_GSS身份验证失败。即使服务器错误地或恶意地接受连接关联尝试,客户端也不会验证它在响应中计算的RPCSEC_GSS验证器,因此客户端将知道它无法使用连接中继指定的会话。

If the client specified SP4_MACH_CRED state protection, the BIND_CONN_TO_SESSION operation will use RPCSEC_GSS integrity or privacy, using the same credential that was used when the client ID was created. Mutual authentication via RPCSEC_GSS assures the client that the connection is associated with the correct session of the correct server.

如果客户端指定了SP4_MACH_CRED状态保护,则BIND_CONN_TO_会话操作将使用RPCSEC_GSS完整性或隐私,使用创建客户端ID时使用的相同凭据。通过RPCSEC_GSS的相互身份验证可确保客户端连接与正确服务器的正确会话相关联。

o For client ID trunking, the client has at least two options for verifying that the same client ID obtained from two different EXCHANGE_ID operations came from the same server. The first option is to use RPCSEC_GSS authentication when sending each EXCHANGE_ID operation. Each time an EXCHANGE_ID is sent with RPCSEC_GSS authentication, the client notes the principal name of the GSS target. If the EXCHANGE_ID results indicate that client ID trunking is possible, and the GSS targets' principal names are the same, the servers are the same and client ID trunking is allowed.

o 对于客户端ID中继,客户端至少有两个选项用于验证从两个不同EXCHANGE_ID操作获得的相同客户端ID是否来自同一服务器。第一个选项是在发送每个EXCHANGE\u ID操作时使用RPCSEC\u GSS身份验证。每次使用RPCSEC_GSS身份验证发送EXCHANGE_ID时,客户端都会记录GSS目标的主体名称。如果EXCHANGE_ID结果表明可以进行客户端ID中继,并且GSS目标的主体名称相同,则服务器相同,并且允许进行客户端ID中继。

The second option for verification is to use SP4_SSV protection. When the client sends EXCHANGE_ID, it specifies SP4_SSV protection. The first EXCHANGE_ID the client sends always has to be confirmed by a CREATE_SESSION call. The client then sends SET_SSV. Later, the client sends EXCHANGE_ID to a second destination network address different from the one the first EXCHANGE_ID was sent to. The client checks that each EXCHANGE_ID reply has the same eir_clientid, eir_server_owner.so_major_id, and eir_server_scope. If so, the client verifies the claim by sending a CREATE_SESSION operation to the second destination address, protected with RPCSEC_GSS integrity using an RPCSEC_GSS handle returned by the second EXCHANGE_ID. If the server accepts the CREATE_SESSION request, and if the client verifies the RPCSEC_GSS verifier and integrity codes, then the client has proof the second server knows the SSV, and thus the two servers are cooperating for the purposes of specifying server scope and client ID trunking.

验证的第二个选项是使用SP4_SSV保护。当客户端发送EXCHANGE\u ID时,它指定SP4\u SSV保护。客户端发送的第一个EXCHANGE\u ID必须始终通过CREATE\u会话调用进行确认。然后,客户端发送SET_SSV。之后,客户端将EXCHANGE\u ID发送到与第一个EXCHANGE\u ID发送到的目标网络地址不同的第二个目标网络地址。客户端检查每个EXCHANGE\u ID回复是否具有相同的eir\u客户端ID、eir\u服务器\u所有者、so\u主\u ID和eir\u服务器\u作用域。如果是,则客户端将通过向第二个目标地址发送CREATE_会话操作来验证声明,该地址使用第二个EXCHANGE_ID返回的RPCSEC_GSS句柄受RPCSEC_GSS完整性保护。如果服务器接受CREATE_会话请求,并且客户端验证RPCSEC_GSS验证程序和完整性代码,然后,客户机有证据证明第二台服务器知道SSV,因此这两台服务器为了指定服务器范围和客户机ID中继而进行合作。

2.10.6. Exactly Once Semantics
2.10.6. 一次语义

Via the session, NFSv4.1 offers exactly once semantics (EOS) for requests sent over a channel. EOS is supported on both the fore channel and backchannel.

通过会话,NFSv4.1为通过通道发送的请求提供了一次语义(EOS)。EOS在前通道和后通道上都受支持。

Each COMPOUND or CB_COMPOUND request that is sent with a leading SEQUENCE or CB_SEQUENCE operation MUST be executed by the receiver exactly once. This requirement holds regardless of whether the request is sent with reply caching specified (see Section 2.10.6.1.3). The requirement holds even if the requester is sending the request over a session created between a pNFS data client and pNFS data server. To understand the rationale for this requirement, divide the requests into three classifications:

与前导序列或CB_序列操作一起发送的每个复合或CB_复合请求必须由接收方执行一次。无论请求是否在指定回复缓存的情况下发送(参见第2.10.6.1.3节),此要求都适用。即使请求者通过在pNFS数据客户端和pNFS数据服务器之间创建的会话发送请求,该要求仍然有效。为了解此要求的基本原理,请将请求分为三类:

o Non-idempotent requests.

o 非幂等请求。

o Idempotent modifying requests.

o 幂等修改请求。

o Idempotent non-modifying requests.

o 幂等非修改请求。

An example of a non-idempotent request is RENAME. Obviously, if a replier executes the same RENAME request twice, and the first execution succeeds, the re-execution will fail. If the replier returns the result from the re-execution, this result is incorrect. Therefore, EOS is required for non-idempotent requests.

非幂等请求的一个例子是重命名。显然,如果应答器执行相同的重命名请求两次,并且第一次执行成功,那么重新执行将失败。如果应答器返回重新执行的结果,则此结果不正确。因此,非幂等请求需要EOS。

An example of an idempotent modifying request is a COMPOUND request containing a WRITE operation. Repeated execution of the same WRITE has the same effect as execution of that WRITE a single time. Nevertheless, enforcing EOS for WRITEs and other idempotent modifying requests is necessary to avoid data corruption.

幂等修改请求的一个示例是包含写入操作的复合请求。重复执行同一次写入与执行该次写入具有相同的效果。然而,对写入和其他幂等修改请求强制执行EOS对于避免数据损坏是必要的。

Suppose a client sends WRITE A to a noncompliant server that does not enforce EOS, and receives no response, perhaps due to a network partition. The client reconnects to the server and re-sends WRITE A. Now, the server has outstanding two instances of A. The server can be in a situation in which it executes and replies to the retry of A, while the first A is still waiting in the server's internal I/O system for some resource. Upon receiving the reply to the second attempt of WRITE A, the client believes its WRITE is done so it is free to send WRITE B, which overlaps the byte-range of A. When the original A is dispatched from the server's I/O system and executed (thus the second time A will have been written), then what has been written by B can be overwritten and thus corrupted.

假设客户机向不强制EOS的不兼容服务器发送写操作,并且没有收到响应,可能是由于网络分区。客户端重新连接到服务器并重新发送写入A。现在,服务器有两个未完成的A实例。服务器可能处于这样的情况:它执行并回复A的重试,而第一个A仍在服务器的内部I/O系统中等待某些资源。在收到对第二次尝试写入A的回复后,客户端认为其写入已完成,因此可以自由发送写入B,该写入B与A的字节范围重叠。当原始A从服务器的I/O系统调度并执行时(因此,第二次写入A),然后,B写的内容可以被覆盖,从而被破坏。

An example of an idempotent non-modifying request is a COMPOUND containing SEQUENCE, PUTFH, READLINK, and nothing else. The re-execution of such a request will not cause data corruption or produce an incorrect result. Nonetheless, to keep the implementation simple, the replier MUST enforce EOS for all requests, whether or not idempotent and non-modifying.

幂等非修改请求的一个例子是包含序列、PUTFH、READLINK等的复合词。重新执行此类请求不会导致数据损坏或产生错误结果。尽管如此,为了保持实现的简单性,应答器必须对所有请求强制执行EOS,无论请求是否为幂等和非修改请求。

Note that true and complete EOS is not possible unless the server persists the reply cache in stable storage, and unless the server is somehow implemented to never require a restart (indeed, if such a server exists, the distinction between a reply cache kept in stable storage versus one that is not is one without meaning). See Section 2.10.6.5 for a discussion of persistence in the reply cache. Regardless, even if the server does not persist the reply cache, EOS improves robustness and correctness over previous versions of NFS because the legacy duplicate request/reply caches were based on the ONC RPC transaction identifier (XID). Section 2.10.6.1 explains the shortcomings of the XID as a basis for a reply cache and describes how NFSv4.1 sessions improve upon the XID.

请注意,除非服务器将应答缓存持久化到稳定存储中,并且除非服务器以某种方式实现为不需要重新启动,否则不可能实现真正完整的EOS(事实上,如果存在这样的服务器,则保持在稳定存储中的应答缓存与不保持在稳定存储中的应答缓存之间的区别是毫无意义的)。有关回复缓存中持久性的讨论,请参见第2.10.6.5节。无论如何,即使服务器没有持久化回复缓存,EOS也比以前的NFS版本提高了健壮性和正确性,因为旧的重复请求/回复缓存基于ONC RPC事务标识符(XID)。第2.10.6.1节解释了作为应答缓存基础的XID的缺点,并描述了NFSv4.1会话如何改进XID。

2.10.6.1. Slot Identifiers and Reply Cache
2.10.6.1. 插槽标识符和应答缓存

The RPC layer provides a transaction ID (XID), which, while required to be unique, is not convenient for tracking requests for two reasons. First, the XID is only meaningful to the requester; it cannot be interpreted by the replier except to test for equality with previously sent requests. When consulting an RPC-based duplicate request cache, the opaqueness of the XID requires a computationally expensive look up (often via a hash that includes XID and source

RPC层提供了一个事务ID(XID),虽然要求它是唯一的,但由于两个原因,它不便于跟踪请求。首先,XID只对请求者有意义;应答器不能解释它,除非测试它是否与以前发送的请求相等。在查询基于RPC的重复请求缓存时,XID的不透明性要求进行计算代价高昂的查找(通常通过包含XID和源的哈希)

address). NFSv4.1 requests use a non-opaque slot ID, which is an index into a slot table, which is far more efficient. Second, because RPC requests can be executed by the replier in any order, there is no bound on the number of requests that may be outstanding at any time. To achieve perfect EOS, using ONC RPC would require storing all replies in the reply cache. XIDs are 32 bits; storing over four billion (2^32) replies in the reply cache is not practical. In practice, previous versions of NFS have chosen to store a fixed number of replies in the cache, and to use a least recently used (LRU) approach to replacing cache entries with new entries when the cache is full. In NFSv4.1, the number of outstanding requests is bounded by the size of the slot table, and a sequence ID per slot is used to tell the replier when it is safe to delete a cached reply.

地址)。NFSv4.1请求使用非不透明的插槽ID,这是插槽表的索引,效率更高。第二,由于RPC请求可以由应答器以任何顺序执行,因此在任何时候都可能未完成的请求的数量没有限制。为了实现完美的EOS,使用ONC RPC需要将所有回复存储在回复缓存中。XID为32位;在应答缓存中存储超过40亿(2^32)个应答是不切实际的。实际上,早期版本的NFS已选择在缓存中存储固定数量的回复,并在缓存已满时使用最近最少使用(LRU)方法将缓存项替换为新项。在NFSv4.1中,未完成请求的数量受插槽表大小的限制,每个插槽的序列ID用于告诉应答器何时可以安全地删除缓存的应答。

In the NFSv4.1 reply cache, when the requester sends a new request, it selects a slot ID in the range 0..N, where N is the replier's current maximum slot ID granted to the requester on the session over which the request is to be sent. The value of N starts out as equal to ca_maxrequests - 1 (Section 18.36), but can be adjusted by the response to SEQUENCE or CB_SEQUENCE as described later in this section. The slot ID must be unused by any of the requests that the requester has already active on the session. "Unused" here means the requester has no outstanding request for that slot ID.

在NFSv4.1应答缓存中,当请求者发送新请求时,它选择范围为0..N的插槽ID,其中N是应答者在发送请求的会话上授予请求者的当前最大插槽ID。N的值开始时等于ca_maxrequests-1(第18.36节),但可通过响应本节后面所述的序列或CB_序列进行调整。请求者在会话中已处于活动状态的任何请求都必须未使用插槽ID。这里的“未使用”表示请求者对该插槽ID没有未完成的请求。

A slot contains a sequence ID and the cached reply corresponding to the request sent with that sequence ID. The sequence ID is a 32-bit unsigned value, and is therefore in the range 0..0xFFFFFFFF (2^32 - 1). The first time a slot is used, the requester MUST specify a sequence ID of one (Section 18.36). Each time a slot is reused, the request MUST specify a sequence ID that is one greater than that of the previous request on the slot. If the previous sequence ID was 0xFFFFFFFF, then the next request for the slot MUST have the sequence ID set to zero (i.e., (2^32 - 1) + 1 mod 2^32).

插槽包含序列ID和与使用该序列ID发送的请求相对应的缓存回复。序列ID是32位无符号值,因此在0..0xFFFFFFFF(2^32-1)范围内。首次使用插槽时,请求者必须指定一个序列ID(第18.36节)。每次重用插槽时,请求必须指定一个序列ID,该序列ID比插槽上的前一个请求的序列ID大一个。如果上一个序列ID是0xFFFFFF,那么下一个插槽请求必须将序列ID设置为零(即,(2^32-1)+1 mod 2^32)。

The sequence ID accompanies the slot ID in each request. It is for the critical check at the replier: it used to efficiently determine whether a request using a certain slot ID is a retransmit or a new, never-before-seen request. It is not feasible for the requester to assert that it is retransmitting to implement this, because for any given request the requester cannot know whether the replier has seen it unless the replier actually replies. Of course, if the requester has seen the reply, the requester would not retransmit.

序列ID伴随着每个请求中的插槽ID。它用于应答器上的关键检查:它用于有效地确定使用特定插槽ID的请求是重传还是新的、以前从未见过的请求。请求者断言它正在重新传输以实现这一点是不可行的,因为对于任何给定的请求,请求者都无法知道应答者是否已经看到它,除非应答者确实进行了应答。当然,如果请求者看到了回复,那么请求者不会重新传输。

The replier compares each received request's sequence ID with the last one previously received for that slot ID, to see if the new request is:

应答器将每个接收到的请求的序列ID与该插槽ID之前接收到的最后一个序列ID进行比较,以查看新请求是否为:

o A new request, in which the sequence ID is one greater than that previously seen in the slot (accounting for sequence wraparound). The replier proceeds to execute the new request, and the replier MUST increase the slot's sequence ID by one.

o 一个新的请求,其中序列ID比之前在插槽中看到的序列ID大一个(考虑序列环绕)。应答器继续执行新请求,应答器必须将插槽的序列ID增加1。

o A retransmitted request, in which the sequence ID is equal to that currently recorded in the slot. If the original request has executed to completion, the replier returns the cached reply. See Section 2.10.6.2 for direction on how the replier deals with retries of requests that are still in progress.

o 一种重新传输的请求,其中序列ID等于时隙中当前记录的序列ID。如果原始请求已执行到完成,应答器将返回缓存的应答。请参阅第2.10.6.2节,了解应答器如何处理仍在进行的请求重试。

o A misordered retry, in which the sequence ID is less than (accounting for sequence wraparound) that previously seen in the slot. The replier MUST return NFS4ERR_SEQ_MISORDERED (as the result from SEQUENCE or CB_SEQUENCE).

o 顺序错误的重试,其中序列ID小于先前在插槽中看到的(考虑到序列环绕)。应答者必须返回NFS4ERR_SEQ_MISORDERED(作为序列或CB_序列的结果)。

o A misordered new request, in which the sequence ID is two or more than (accounting for sequence wraparound) that previously seen in the slot. Note that because the sequence ID MUST wrap around to zero once it reaches 0xFFFFFFFF, a misordered new request and a misordered retry cannot be distinguished. Thus, the replier MUST return NFS4ERR_SEQ_MISORDERED (as the result from SEQUENCE or CB_SEQUENCE).

o 顺序错误的新请求,其中序列ID比先前在插槽中看到的序列ID多两个或更多(考虑到序列环绕)。请注意,由于序列ID在到达0xFFFFFF后必须环绕为零,因此无法区分顺序错误的新请求和顺序错误的重试。因此,应答器必须返回错误排序的NFS4ERR_SEQ_(作为序列或CB_序列的结果)。

Unlike the XID, the slot ID is always within a specific range; this has two implications. The first implication is that for a given session, the replier need only cache the results of a limited number of COMPOUND requests. The second implication derives from the first, which is that unlike XID-indexed reply caches (also known as duplicate request caches - DRCs), the slot ID-based reply cache cannot be overflowed. Through use of the sequence ID to identify retransmitted requests, the replier does not need to actually cache the request itself, reducing the storage requirements of the reply cache further. These facilities make it practical to maintain all the required entries for an effective reply cache.

与XID不同,插槽ID始终在特定范围内;这有两个含义。第一个含义是,对于给定会话,应答器只需缓存有限数量的复合请求的结果。第二个含义源自第一个含义,即与XID索引回复缓存(也称为重复请求缓存-DRC)不同,基于插槽ID的回复缓存不能溢出。通过使用序列ID来识别重新传输的请求,应答器不需要实际缓存请求本身,从而进一步降低了应答缓存的存储需求。这些功能使维护有效回复缓存所需的所有条目变得切实可行。

The slot ID, sequence ID, and session ID therefore take over the traditional role of the XID and source network address in the replier's reply cache implementation. This approach is considerably more portable and completely robust -- it is not subject to the reassignment of ports as clients reconnect over IP networks. In addition, the RPC XID is not used in the reply cache, enhancing robustness of the cache in the face of any rapid reuse of XIDs by the requester. While the replier does not care about the XID for the purposes of reply cache management (but the replier MUST return the same XID that was in the request), nonetheless there are considerations for the XID in NFSv4.1 that are the same as all other

因此,插槽ID、序列ID和会话ID在应答器的应答缓存实现中接管了XID和源网络地址的传统角色。这种方法具有更大的可移植性和完全的健壮性——当客户端通过IP网络重新连接时,它不需要重新分配端口。此外,RPC XID不用于应答缓存中,从而增强了缓存在请求者快速重用XID时的健壮性。虽然应答器不关心用于应答缓存管理的XID(但应答器必须返回请求中的相同XID),但是NFSv4.1中的XID考虑事项与所有其他注意事项相同

previous versions of NFS. The RPC XID remains in each message and needs to be formulated in NFSv4.1 requests as in any other ONC RPC request. The reasons include:

NFS的早期版本。RPC XID保留在每条消息中,需要在NFSv4.1请求中制定,就像在任何其他ONC RPC请求中一样。原因包括:

o The RPC layer retains its existing semantics and implementation.

o RPC层保留其现有的语义和实现。

o The requester and replier must be able to interoperate at the RPC layer, prior to the NFSv4.1 decoding of the SEQUENCE or CB_SEQUENCE operation.

o 在NFSv4.1解码序列或CB_序列操作之前,请求者和应答者必须能够在RPC层进行互操作。

o If an operation is being used that does not start with SEQUENCE or CB_SEQUENCE (e.g., BIND_CONN_TO_SESSION), then the RPC XID is needed for correct operation to match the reply to the request.

o 如果正在使用的操作不是以序列或CB_序列开始的(例如,将_CONN_绑定到_会话),则需要RPC XID进行正确的操作,以匹配对请求的回复。

o The SEQUENCE or CB_SEQUENCE operation may generate an error. If so, the embedded slot ID, sequence ID, and session ID (if present) in the request will not be in the reply, and the requester has only the XID to match the reply to the request.

o 序列或CB_序列操作可能会产生错误。如果是这样,请求中嵌入的插槽ID、序列ID和会话ID(如果存在)将不在应答中,并且请求者只有与请求的应答相匹配的XID。

Given that well-formulated XIDs continue to be required, this begs the question: why do SEQUENCE and CB_SEQUENCE replies have a session ID, slot ID, and sequence ID? Having the session ID in the reply means that the requester does not have to use the XID to look up the session ID, which would be necessary if the connection were associated with multiple sessions. Having the slot ID and sequence ID in the reply means that the requester does not have to use the XID to look up the slot ID and sequence ID. Furthermore, since the XID is only 32 bits, it is too small to guarantee the re-association of a reply with its request [37]; having session ID, slot ID, and sequence ID in the reply allows the client to validate that the reply in fact belongs to the matched request.

考虑到仍然需要精心设计的XID,这就引出了一个问题:为什么序列和CB_序列回复有会话ID、插槽ID和序列ID?在回复中包含会话ID意味着请求者不必使用XID来查找会话ID,如果连接与多个会话相关联,这是必要的。在应答中具有时隙ID和序列ID意味着请求者不必使用XID来查找时隙ID和序列ID。此外,由于XID只有32位,因此它太小,无法保证应答与其请求的重新关联[37];在应答中包含会话ID、插槽ID和序列ID允许客户端验证应答实际上属于匹配的请求。

The SEQUENCE (and CB_SEQUENCE) operation also carries a "highest_slotid" value, which carries additional requester slot usage information. The requester MUST always indicate the slot ID representing the outstanding request with the highest-numbered slot value. The requester should in all cases provide the most conservative value possible, although it can be increased somewhat above the actual instantaneous usage to maintain some minimum or optimal level. This provides a way for the requester to yield unused request slots back to the replier, which in turn can use the information to reallocate resources.

SEQUENCE(和CB_SEQUENCE)操作还携带“highest_slotid”值,该值携带额外的请求程序插槽使用信息。请求者必须始终使用编号最高的插槽值指示表示未完成请求的插槽ID。在所有情况下,请求者都应该提供尽可能保守的值,尽管可以将其增加到实际瞬时使用量之上,以保持最低或最佳水平。这为请求者提供了一种将未使用的请求槽返回给应答器的方法,应答器反过来可以使用该信息重新分配资源。

The replier responds with both a new target highest_slotid and an enforced highest_slotid, described as follows:

应答器用新的目标最高\u slotid和强制执行的最高\u slotid进行响应,描述如下:

o The target highest_slotid is an indication to the requester of the highest_slotid the replier wishes the requester to be using. This permits the replier to withdraw (or add) resources from a requester that has been found to not be using them, in order to more fairly share resources among a varying level of demand from other requesters. The requester must always comply with the replier's value updates, since they indicate newly established hard limits on the requester's access to session resources. However, because of request pipelining, the requester may have active requests in flight reflecting prior values; therefore, the replier must not immediately require the requester to comply.

o 目标最高\u slotid是向请求者指示回复者希望请求者使用的最高\u slotid。这允许应答者从发现未使用资源的请求者处提取(或添加)资源,以便在来自其他请求者的不同需求水平之间更公平地共享资源。请求者必须始终遵守应答者的值更新,因为它们表示对请求者访问会话资源的新建立的硬限制。然而,由于请求管道,请求者可能在飞行中有反映先前值的活动请求;因此,回复者不得立即要求请求者遵守。

o The enforced highest_slotid indicates the highest slot ID the requester is permitted to use on a subsequent SEQUENCE or CB_SEQUENCE operation. The replier's enforced highest_slotid SHOULD be no less than the highest_slotid the requester indicated in the SEQUENCE or CB_SEQUENCE arguments.

o 强制的最高插槽ID表示允许请求者在后续序列或CB_序列操作中使用的最高插槽ID。应答器的强制最高\u slotid应不小于SEQUENCE或CB_SEQUENCE参数中指示的请求者的最高\u slotid。

A requester can be intransigent with respect to lowering its highest_slotid argument to a Sequence operation, i.e. the requester continues to ignore the target highest_slotid in the response to a Sequence operation, and continues to set its highest_slotid argument to be higher than the target highest_slotid. This can be considered particularly egregious behavior when the replier knows there are no outstanding requests with slot IDs higher than its target highest_slotid. When faced with such intransigence, the replier is free to take more forceful action, and MAY reply with a new enforced highest_slotid that is less than its previous enforced highest_slotid. Thereafter, if the requester continues to send requests with a highest_slotid that is greater than the replier's new enforced highest_slotid, the server MAY return NFS4ERR_BAD_HIGH_SLOT, unless the slot ID in the request is greater than the new enforced highest_slotid and the request is a retry.

请求者在将其最高\u slotid参数降低为序列操作时可能不妥协,即请求者在对序列操作的响应中继续忽略目标最高\u slotid,并继续将其最高\u slotid参数设置为高于目标最高\u slotid。当应答器知道没有插槽ID高于其目标slotid的未完成请求时,这可以被认为是特别恶劣的行为。当面对这种不妥协时,回复者可以自由地采取更有力的行动,并且可以使用新的强制执行的最高斯洛蒂德进行回复,该最高斯洛蒂德少于其先前强制执行的最高斯洛蒂德。此后,如果请求者继续发送最高\u slotid大于应答者新强制执行的最高\u slotid的请求,则服务器可能返回NFS4ERR\u BAD\u HIGH\u SLOT,除非请求中的SLOT ID大于新强制执行的最高\u slotid并且请求是重试。

The replier SHOULD retain the slots it wants to retire until the requester sends a request with a highest_slotid less than or equal to the replier's new enforced highest_slotid.

应答器应该保留它想要退出的插槽,直到请求者发送一个最高\u slotid小于或等于应答器新强制的最高\u slotid的请求。

The requester can also be intransigent with respect to sending non-retry requests that have a slot ID that exceeds the replier's highest_slotid. Once the replier has forcibly lowered the enforced highest_slotid, the requester is only allowed to send retries on slots that exceed the replier's highest_slotid. If a request is received with a slot ID that is higher than the new enforced highest_slotid, and the sequence ID is one higher than what is in the slot's reply cache, then the server can both retire the slot and return NFS4ERR_BADSLOT (however, the server MUST NOT

对于发送的非重试请求,如果其插槽ID超过应答者的最高\u slotid,请求者也可能不妥协。一旦应答器强制降低强制的最高\u slotid,请求者只允许在超过应答器最高\u slotid的插槽上发送重试。如果接收到的请求的插槽ID高于新强制的最高\u slotid,并且序列ID高于插槽的应答缓存中的ID,则服务器可以退出插槽并返回NFS4ERR\u BADSLOT(但是,服务器不能

do one and not the other). The reason it is safe to retire the slot is because by using the next sequence ID, the requester is indicating it has received the previous reply for the slot.

做一个而不是另一个)。退出插槽是安全的原因是,通过使用下一个序列ID,请求者表示已收到插槽的上一个回复。

o The requester SHOULD use the lowest available slot when sending a new request. This way, the replier may be able to retire slot entries faster. However, where the replier is actively adjusting its granted highest_slotid, it will not be able to use only the receipt of the slot ID and highest_slotid in the request. Neither the slot ID nor the highest_slotid used in a request may reflect the replier's current idea of the requester's session limit, because the request may have been sent from the requester before the update was received. Therefore, in the downward adjustment case, the replier may have to retain a number of reply cache entries at least as large as the old value of maximum requests outstanding, until it can infer that the requester has seen a reply containing the new granted highest_slotid. The replier can infer that the requester has seen such a reply when it receives a new request with the same slot ID as the request replied to and the next higher sequence ID.

o 请求者在发送新请求时应使用最低的可用插槽。这样,应答器可以更快地退出插槽条目。但是,如果应答器正在积极调整其已授予的最高\u slotid,则它将无法在请求中仅使用插槽ID和最高\u slotid的接收。请求中使用的插槽ID或最高\u插槽ID都不能反映应答者对请求者会话限制的当前想法,因为请求可能是在收到更新之前从请求者发送的。因此,在向下调整的情况下,应答器可能必须保留至少与最大未完成请求的旧值一样大的多个应答缓存项,直到它可以推断请求者已经看到包含新授予的最高\u slotid的应答。回复者可以推断,当请求者接收到一个新请求时,该请求者已经看到了这样一个回复,该请求具有与被回复请求相同的时隙ID和下一个更高的序列ID。

2.10.6.1.1. Caching of SEQUENCE and CB_SEQUENCE Replies
2.10.6.1.1. 序列和CB_序列回复的缓存

When a SEQUENCE or CB_SEQUENCE operation is successfully executed, its reply MUST always be cached. Specifically, session ID, sequence ID, and slot ID MUST be cached in the reply cache. The reply from SEQUENCE also includes the highest slot ID, target highest slot ID, and status flags. Instead of caching these values, the server MAY re-compute the values from the current state of the fore channel, session, and/or client ID as appropriate. Similarly, the reply from CB_SEQUENCE includes a highest slot ID and target highest slot ID. The client MAY re-compute the values from the current state of the session as appropriate.

当序列或CB_序列操作成功执行时,必须始终缓存其回复。具体来说,会话ID、序列ID和插槽ID必须缓存在应答缓存中。来自序列的应答还包括最高插槽ID、目标最高插槽ID和状态标志。服务器可以根据前端通道、会话和/或客户端ID的当前状态重新计算值,而不是缓存这些值。类似地,来自CB_序列的应答包括最高时隙ID和目标最高时隙ID。客户端可以根据会话的当前状态酌情重新计算值。

Regardless of whether or not a replier is re-computing highest slot ID, target slot ID, and status on replies to retries, the requester MUST NOT assume that the values are being re-computed whenever it receives a reply after a retry is sent, since it has no way of knowing whether the reply it has received was sent by the replier in response to the retry or is a delayed response to the original request. Therefore, it may be the case that highest slot ID, target slot ID, or status bits may reflect the state of affairs when the request was first executed. Although acting based on such delayed information is valid, it may cause the receiver of the reply to do unneeded work. Requesters MAY choose to send additional requests to get the current state of affairs or use the state of affairs reported by subsequent requests, in preference to acting immediately on data that might be out of date.

无论应答器是否正在重新计算最高插槽ID、目标插槽ID和重试应答状态,请求者都不得假设在发送重试后收到应答时正在重新计算值,因为它无法知道它收到的回复是由回复者响应重试发送的,还是对原始请求的延迟响应。因此,可能的情况是,最高时隙ID、目标时隙ID或状态位可以反映第一次执行请求时的状态。尽管根据此类延迟信息采取行动是有效的,但这可能会导致回复接收者做不必要的工作。请求者可以选择发送其他请求以获取当前的事务状态,或者使用后续请求报告的事务状态,而不是对可能过期的数据立即采取行动。

2.10.6.1.2. Errors from SEQUENCE and CB_SEQUENCE
2.10.6.1.2. 序列和CB_序列的错误

Any time SEQUENCE or CB_SEQUENCE returns an error, the sequence ID of the slot MUST NOT change. The replier MUST NOT modify the reply cache entry for the slot whenever an error is returned from SEQUENCE or CB_SEQUENCE.

任何时间序列或CB_序列返回错误,插槽的序列ID不得更改。每当从SEQUENCE或CB_SEQUENCE返回错误时,应答器不得修改插槽的应答缓存项。

2.10.6.1.3. Optional Reply Caching
2.10.6.1.3. 可选回复缓存

On a per-request basis, the requester can choose to direct the replier to cache the reply to all operations after the first operation (SEQUENCE or CB_SEQUENCE) via the sa_cachethis or csa_cachethis fields of the arguments to SEQUENCE or CB_SEQUENCE. The reason it would not direct the replier to cache the entire reply is that the request is composed of all idempotent operations [34]. Caching the reply may offer little benefit. If the reply is too large (see Section 2.10.6.4), it may not be cacheable anyway. Even if the reply to idempotent request is small enough to cache, unnecessarily caching the reply slows down the server and increases RPC latency.

在每个请求的基础上,请求者可以选择指示应答器在第一次操作(序列或CB_序列)之后通过序列或CB_序列的参数的sa_cachethis或csa_cachethis字段缓存对所有操作的应答。它不会指示应答器缓存整个应答的原因是请求由所有幂等运算组成[34]。缓存回复可能没有什么好处。如果回复太大(见第2.10.6.4节),它可能无法缓存。即使对幂等请求的应答小到足以缓存,不必要地缓存应答也会降低服务器速度并增加RPC延迟。

Whether or not the requester requests the reply to be cached has no effect on the slot processing. If the results of SEQUENCE or CB_SEQUENCE are NFS4_OK, then the slot's sequence ID MUST be incremented by one. If a requester does not direct the replier to cache the reply, the replier MUST do one of following:

请求者是否请求缓存回复对插槽处理没有影响。如果序列或CB_序列的结果为NFS4_OK,则插槽的序列ID必须增加1。如果请求者未指示回复者缓存回复,则回复者必须执行以下操作之一:

o The replier can cache the entire original reply. Even though sa_cachethis or csa_cachethis is FALSE, the replier is always free to cache. It may choose this approach in order to simplify implementation.

o 应答器可以缓存整个原始应答。即使sa_cachethis或csa_cachethis为FALSE,应答器始终可以自由缓存。它可以选择这种方法以简化实现。

o The replier enters into its reply cache a reply consisting of the original results to the SEQUENCE or CB_SEQUENCE operation, and with the next operation in COMPOUND or CB_COMPOUND having the error NFS4ERR_RETRY_UNCACHED_REP. Thus, if the requester later retries the request, it will get NFS4ERR_RETRY_UNCACHED_REP. If a replier receives a retried Sequence operation where the reply to the COMPOUND or CB_COMPOUND was not cached, then the replier,

o 应答器将包含序列或CB_序列操作的原始结果的应答输入到其应答缓存中,并且复合或CB_复合中的下一个操作具有错误NFS4ERR_RETRY_UNCACHED_REP。因此,如果请求者稍后重试请求,它将获得NFS4ERR_RETRY_UNCACHED_REP。如果应答器接收到重试序列操作,其中对复合或CB_复合的应答未缓存,则应答器,

* MAY return NFS4ERR_RETRY_UNCACHED_REP in reply to a Sequence operation if the Sequence operation is not the first operation (granted, a requester that does so is in violation of the NFSv4.1 protocol).

* 如果序列操作不是第一个操作,则可能会返回NFS4ERR\u RETRY\u UNCACHED\u REP以响应序列操作(已授予,这样做的请求者违反了NFSv4.1协议)。

* MUST NOT return NFS4ERR_RETRY_UNCACHED_REP in reply to a Sequence operation if the Sequence operation is the first operation.

* 如果序列操作是第一个操作,则不得返回NFS4ERR\u RETRY\u UNCACHED\u REP以响应序列操作。

o If the second operation is an illegal operation, or an operation that was legal in a previous minor version of NFSv4 and MUST NOT be supported in the current minor version (e.g., SETCLIENTID), the replier MUST NOT ever return NFS4ERR_RETRY_UNCACHED_REP. Instead the replier MUST return NFS4ERR_OP_ILLEGAL or NFS4ERR_BADXDR or NFS4ERR_NOTSUPP as appropriate.

o 如果第二个操作是非法操作,或者是NFSv4先前次要版本中合法的操作,并且当前次要版本(例如SETCLIENTID)中不支持该操作,应答器不得返回NFS4ERR_RETRY_UNCACHED_REP。相反,应答器必须返回NFS4ERR_OP_非法或NFS4ERR_BADXDR或NFS4ERR_NOTSUPP(视情况而定)。

o If the second operation can result in another error status, the replier MAY return a status other than NFS4ERR_RETRY_UNCACHED_REP, provided the operation is not executed in such a way that the state of the replier is changed. Examples of such an error status include: NFS4ERR_NOTSUPP returned for an operation that is legal but not REQUIRED in the current minor versions, and thus not supported by the replier; NFS4ERR_SEQUENCE_POS; and NFS4ERR_REQ_TOO_BIG.

o 如果第二个操作可能导致另一个错误状态,则应答器可能返回NFS4ERR_RETRY_UNCACHED_REP以外的状态,前提是该操作的执行方式不会改变应答器的状态。此类错误状态的示例包括:为合法但在当前次要版本中不需要的操作返回的NFS4ERR_NOTSUPP,因此应答器不支持该操作;NFS4ERR_SEQUENCE_POS;NFS4ERR\u请求太大。

The discussion above assumes that the retried request matches the original one. Section 2.10.6.1.3.1 discusses what the replier might do, and MUST do when original and retried requests do not match. Since the replier may only cache a small amount of the information that would be required to determine whether this is a case of a false retry, the replier may send to the client any of the following responses:

上面的讨论假设重试的请求与原始请求匹配。第2.10.6.1.3.1节讨论了当原始请求和重试请求不匹配时,应答器可能会做什么,以及必须做什么。由于应答器可能只缓存确定这是否为错误重试所需的少量信息,因此应答器可能会向客户端发送以下任何响应:

o The cached reply to the original request (if the replier has cached it in its entirety and the users of the original request and retry match).

o 原始请求的缓存回复(如果回复者已将其全部缓存,并且原始请求的用户已缓存,请重试匹配)。

o A reply that consists only of the Sequence operation with the error NFS4ERR_FALSE_RETRY.

o 仅由序列操作组成的回复,错误为NFS4ERR\u FALSE\u RETRY。

o A reply consisting of the response to Sequence with the status NFS4_OK, together with the second operation as it appeared in the retried request with an error of NFS4ERR_RETRY_UNCACHED_REP or other error as described above.

o 一种应答,包括对状态为NFS4_OK的序列的响应,以及出现在重试请求中的第二个操作,错误为NFS4ERR_RETRY_UNCACHED_REP或上述其他错误。

o A reply that consists of the response to Sequence with the status NFS4_OK, together with the second operation as it appeared in the original request with an error of NFS4ERR_RETRY_UNCACHED_REP or other error as described above.

o 一种应答,包括对状态为NFS4_OK的序列的响应,以及出现在原始请求中的第二个操作,错误为NFS4ERR_RETRY_UNCACHED_REP或上述其他错误。

2.10.6.1.3.1. False Retry
2.10.6.1.3.1. 错误重试

If a requester sent a Sequence operation with a slot ID and sequence ID that are in the reply cache but the replier detected that the retried request is not the same as the original request, including a retry that has different operations or different arguments in the operations from the original and a retry that uses a different

如果请求者发送了一个序列操作,其插槽ID和序列ID位于应答缓存中,但应答者检测到重试的请求与原始请求不同,包括在操作中使用与原始请求不同的操作或参数的重试,以及使用不同参数的重试

principal in the RPC request's credential field that translates to a different user, then this is a false retry. When the replier detects a false retry, it is permitted (but not always obligated) to return NFS4ERR_FALSE_RETRY in response to the Sequence operation when it detects a false retry.

RPC请求的凭据字段中的主体,转换为其他用户,则这是错误的重试。当应答器检测到错误重试时,允许(但并非总是有义务)在检测到错误重试时返回NFS4ERR_false_retry以响应序列操作。

Translations of particularly privileged user values to other users due to the lack of appropriately secure credentials, as configured on the replier, should be applied before determining whether the users are the same or different. If the replier determines the users are different between the original request and a retry, then the replier MUST return NFS4ERR_FALSE_RETRY.

在确定用户是否相同或不同之前,应应用由于缺少应答器上配置的适当安全凭据而将特定特权用户值转换为其他用户。如果应答器确定原始请求和重试之间的用户不同,则应答器必须返回NFS4ERR\u FALSE\u retry。

If an operation of the retry is an illegal operation, or an operation that was legal in a previous minor version of NFSv4 and MUST NOT be supported in the current minor version (e.g., SETCLIENTID), the replier MAY return NFS4ERR_FALSE_RETRY (and MUST do so if the users of the original request and retry differ). Otherwise, the replier MAY return NFS4ERR_OP_ILLEGAL or NFS4ERR_BADXDR or NFS4ERR_NOTSUPP as appropriate. Note that the handling is in contrast for how the replier deals with retries requests with no cached reply. The difference is due to NFS4ERR_FALSE_RETRY being a valid error for only Sequence operations, whereas NFS4ERR_RETRY_UNCACHED_REP is a valid error for all operations except illegal operations and operations that MUST NOT be supported in the current minor version of NFSv4.

如果重试操作是非法操作,或者是在NFSv4以前的次要版本中合法的操作,并且在当前次要版本(例如SETCLIENTID)中不受支持,则应答器可能返回NFS4ERR_FALSE_retry(如果原始请求和重试的用户不同,则必须返回)。否则,应答器可能会根据需要返回NFS4ERR_OP_非法或NFS4ERR_BADXDR或NFS4ERR_NOTSUPP。请注意,处理方式与应答器处理没有缓存应答的重试请求的方式相反。区别在于NFS4ERR_FALSE_RETRY仅对序列操作有效,而NFS4ERR_RETRY_UNCACHED_REP对所有操作有效,非法操作和当前次要版本NFSv4中不支持的操作除外。

2.10.6.2. Retry and Replay of Reply
2.10.6.2. 重试并重播回复

A requester MUST NOT retry a request, unless the connection it used to send the request disconnects. The requester can then reconnect and re-send the request, or it can re-send the request over a different connection that is associated with the same session.

请求者不得重试请求,除非用于发送请求的连接断开。然后,请求者可以重新连接并重新发送请求,也可以通过与同一会话关联的不同连接重新发送请求。

If the requester is a server wanting to re-send a callback operation over the backchannel of a session, the requester of course cannot reconnect because only the client can associate connections with the backchannel. The server can re-send the request over another connection that is bound to the same session's backchannel. If there is no such connection, the server MUST indicate that the session has no backchannel by setting the SEQ4_STATUS_CB_PATH_DOWN_SESSION flag bit in the response to the next SEQUENCE operation from the client. The client MUST then associate a connection with the session (or destroy the session).

如果请求者是希望通过会话的反向通道重新发送回调操作的服务器,那么请求者当然无法重新连接,因为只有客户端可以将连接与反向通道相关联。服务器可以通过绑定到同一会话的反向通道的另一个连接重新发送请求。如果没有这样的连接,服务器必须通过在对来自客户端的下一个序列操作的响应中设置SEQ4_STATUS_CB_PATH_DOWN_session flag位来指示会话没有反向通道。然后,客户端必须将连接与会话相关联(或销毁会话)。

Note that it is not fatal for a requester to retry without a disconnect between the request and retry. However, the retry does consume resources, especially with RDMA, where each request, retry or not, consumes a credit. Retries for no reason, especially retries

请注意,请求者在请求和重试之间没有断开连接的情况下重试并不是致命的。但是,重试确实会消耗资源,特别是对于RDMA,其中每个请求(无论是否重试)都会消耗一个积分。无缘无故地重试,尤指重试

sent shortly after the previous attempt, are a poor use of network bandwidth and defeat the purpose of a transport's inherent congestion control system.

在前一次尝试后不久发送的消息,是对网络带宽的不良使用,并违背了传输固有的拥塞控制系统的目的。

A requester MUST wait for a reply to a request before using the slot for another request. If it does not wait for a reply, then the requester does not know what sequence ID to use for the slot on its next request. For example, suppose a requester sends a request with sequence ID 1, and does not wait for the response. The next time it uses the slot, it sends the new request with sequence ID 2. If the replier has not seen the request with sequence ID 1, then the replier is not expecting sequence ID 2, and rejects the requester's new request with NFS4ERR_SEQ_MISORDERED (as the result from SEQUENCE or CB_SEQUENCE).

请求者必须等待对请求的答复,然后才能将插槽用于另一个请求。如果它不等待回复,那么请求者就不知道在下一个请求中为插槽使用什么序列ID。例如,假设请求者发送序列ID为1的请求,并且不等待响应。下次使用插槽时,它将发送序列ID为2的新请求。如果应答器没有看到序列ID为1的请求,则应答器不期望序列ID为2,并以NFS4ERR_SEQ_错序(由于序列或CB_序列)拒绝请求者的新请求。

RDMA fabrics do not guarantee that the memory handles (Steering Tags) within each RPC/RDMA "chunk" [8] are valid on a scope outside that of a single connection. Therefore, handles used by the direct operations become invalid after connection loss. The server must ensure that any RDMA operations that must be replayed from the reply cache use the newly provided handle(s) from the most recent request.

RDMA结构不保证每个RPC/RDMA“块”[8]中的内存句柄(转向标记)在单个连接之外的作用域上有效。因此,直接操作使用的句柄在连接丢失后将变得无效。服务器必须确保必须从应答缓存重放的任何RDMA操作都使用最近请求中新提供的句柄。

A retry might be sent while the original request is still in progress on the replier. The replier SHOULD deal with the issue by returning NFS4ERR_DELAY as the reply to SEQUENCE or CB_SEQUENCE operation, but implementations MAY return NFS4ERR_MISORDERED. Since errors from SEQUENCE and CB_SEQUENCE are never recorded in the reply cache, this approach allows the results of the execution of the original request to be properly recorded in the reply cache (assuming that the requester specified the reply to be cached).

当原始请求仍在应答器上进行时,可能会发送重试。应答器应该通过返回NFS4ERR_DELAY作为对序列的应答或CB_序列操作来处理该问题,但是实现可能会返回错误排序的NFS4ERR_。由于SEQUENCE和CB_SEQUENCE的错误从未记录在应答缓存中,因此这种方法允许原始请求的执行结果正确记录在应答缓存中(假设请求者指定要缓存的应答)。

2.10.6.3. Resolving Server Callback Races
2.10.6.3. 解决服务器回调竞争

It is possible for server callbacks to arrive at the client before the reply from related fore channel operations. For example, a client may have been granted a delegation to a file it has opened, but the reply to the OPEN (informing the client of the granting of the delegation) may be delayed in the network. If a conflicting operation arrives at the server, it will recall the delegation using the backchannel, which may be on a different transport connection, perhaps even a different network, or even a different session associated with the same client ID.

服务器回调可能在相关前端通道操作的回复之前到达客户端。例如,客户机可能已被授予对其已打开的文件的授权,但对打开文件的回复(通知客户授权)可能会在网络中延迟。如果冲突操作到达服务器,它将使用反向通道调用委派,反向通道可能位于不同的传输连接上,甚至可能位于不同的网络上,甚至可能位于与同一客户机ID关联的不同会话上。

The presence of a session between the client and server alleviates this issue. When a session is in place, each client request is uniquely identified by its { session ID, slot ID, sequence ID } triple. By the rules under which slot entries (reply cache entries) are retired, the server has knowledge whether the client has "seen"

客户端和服务器之间存在会话可以缓解此问题。当会话就位时,每个客户端请求都由其{session ID,slot ID,sequence ID}三元组唯一标识。根据插槽项(回复缓存项)失效的规则,服务器知道客户端是否“看到”

each of the server's replies. The server can therefore provide sufficient information to the client to allow it to disambiguate between an erroneous or conflicting callback race condition.

服务器的每个回复。因此,服务器可以向客户机提供足够的信息,使其能够在错误或冲突的回调竞争条件之间消除歧义。

For each client operation that might result in some sort of server callback, the server SHOULD "remember" the { session ID, slot ID, sequence ID } triple of the client request until the slot ID retirement rules allow the server to determine that the client has, in fact, seen the server's reply. Until the time the { session ID, slot ID, sequence ID } request triple can be retired, any recalls of the associated object MUST carry an array of these referring identifiers (in the CB_SEQUENCE operation's arguments), for the benefit of the client. After this time, it is not necessary for the server to provide this information in related callbacks, since it is certain that a race condition can no longer occur.

对于可能导致某种服务器回调的每个客户端操作,服务器应该“记住”客户端请求的{session ID,slot ID,sequence ID}三元组,直到slot ID失效规则允许服务器确定客户端实际上已经看到了服务器的回复。在{session ID,slot ID,sequence ID}请求三元组可以失效之前,关联对象的任何回调都必须携带这些引用标识符的数组(在CB_sequence操作的参数中),以利于客户端。在这段时间之后,服务器无需在相关回调中提供此信息,因为可以确定竞争条件不再发生。

The CB_SEQUENCE operation that begins each server callback carries a list of "referring" { session ID, slot ID, sequence ID } triples. If the client finds the request corresponding to the referring session ID, slot ID, and sequence ID to be currently outstanding (i.e., the server's reply has not been seen by the client), it can determine that the callback has raced the reply, and act accordingly. If the client does not find the request corresponding to the referring triple to be outstanding (including the case of a session ID referring to a destroyed session), then there is no race with respect to this triple. The server SHOULD limit the referring triples to requests that refer to just those that apply to the objects referred to in the CB_COMPOUND procedure.

开始每个服务器回调的CB_序列操作包含一个“引用”{session ID,slot ID,SEQUENCE ID}三元组列表。如果客户机发现与引用会话ID、插槽ID和序列ID相对应的请求当前未完成(即,客户机未看到服务器的回复),它可以确定回调已完成回复,并相应地采取行动。如果客户机未发现与引用三元组对应的请求未完成(包括会话ID引用已破坏会话的情况),则与此三元组不存在争用。服务器应将引用三元组限制为仅引用那些应用于CB_复合过程中引用的对象的请求。

The client must not simply wait forever for the expected server reply to arrive before responding to the CB_COMPOUND that won the race, because it is possible that it will be delayed indefinitely. The client should assume the likely case that the reply will arrive within the average round-trip time for COMPOUND requests to the server, and wait that period of time. If that period of time expires, it can respond to the CB_COMPOUND with NFS4ERR_DELAY. There are other scenarios under which callbacks may race replies. Among them are pNFS layout recalls as described in Section 12.5.5.2.

在响应赢得比赛的CB_化合物之前,客户端不能永远等待预期的服务器应答,因为它可能会无限期地延迟。客户机应该假设回复将在到服务器的复合请求的平均往返时间内到达,并等待该时间段。如果这段时间到期,它可以用NFS4ERR_延迟响应CB_化合物。在其他情况下,回调可能会与回复竞争。其中包括pNFS布局召回,如第12.5.5.2节所述。

2.10.6.4. COMPOUND and CB_COMPOUND Construction Issues
2.10.6.4. 大院和CB_大院建设问题

Very large requests and replies may pose both buffer management issues (especially with RDMA) and reply cache issues. When the session is created (Section 18.36), for each channel (fore and back), the client and server negotiate the maximum-sized request they will send or process (ca_maxrequestsize), the maximum-sized reply they will return or process (ca_maxresponsesize), and the maximum-sized reply they will store in the reply cache (ca_maxresponsesize_cached).

非常大的请求和回复可能会带来缓冲区管理问题(尤其是RDMA)和回复缓存问题。创建会话时(第18.36节),对于每个通道(前端和后端),客户机和服务器协商它们将发送或处理的最大大小的请求(ca_maxrequestsize),它们将返回或处理的最大大小的回复(ca_maxresponsesize),以及它们将存储在回复缓存中的最大大小的回复(ca_maxresponsesize_cached)。

If a request exceeds ca_maxrequestsize, the reply will have the status NFS4ERR_REQ_TOO_BIG. A replier MAY return NFS4ERR_REQ_TOO_BIG as the status for the first operation (SEQUENCE or CB_SEQUENCE) in the request (which means that no operations in the request executed and that the state of the slot in the reply cache is unchanged), or it MAY opt to return it on a subsequent operation in the same COMPOUND or CB_COMPOUND request (which means that at least one operation did execute and that the state of the slot in the reply cache does change). The replier SHOULD set NFS4ERR_REQ_TOO_BIG on the operation that exceeds ca_maxrequestsize.

If a request exceeds ca_maxrequestsize, the reply will have the status NFS4ERR_REQ_TOO_BIG. A replier MAY return NFS4ERR_REQ_TOO_BIG as the status for the first operation (SEQUENCE or CB_SEQUENCE) in the request (which means that no operations in the request executed and that the state of the slot in the reply cache is unchanged), or it MAY opt to return it on a subsequent operation in the same COMPOUND or CB_COMPOUND request (which means that at least one operation did execute and that the state of the slot in the reply cache does change). The replier SHOULD set NFS4ERR_REQ_TOO_BIG on the operation that exceeds ca_maxrequestsize.translate error, please retry

If a reply exceeds ca_maxresponsesize, the reply will have the status NFS4ERR_REP_TOO_BIG. A replier MAY return NFS4ERR_REP_TOO_BIG as the status for the first operation (SEQUENCE or CB_SEQUENCE) in the request, or it MAY opt to return it on a subsequent operation (in the same COMPOUND or CB_COMPOUND reply). A replier MAY return NFS4ERR_REP_TOO_BIG in the reply to SEQUENCE or CB_SEQUENCE, even if the response would still exceed ca_maxresponsesize.

如果回复超过ca_maxresponsesize,则回复的状态为NFS4ERR_REP_TOO_BIG。应答器可能返回NFS4ERR_REP_太大,作为请求中第一个操作(序列或CB_序列)的状态,也可能选择在后续操作中返回它(在相同的复合或CB_复合应答中)。应答器可能会在应答序列或CB_序列中返回NFS4ERR_REP_过大,即使响应仍将超过ca_maxresponsesize。

If sa_cachethis or csa_cachethis is TRUE, then the replier MUST cache a reply except if an error is returned by the SEQUENCE or CB_SEQUENCE operation (see Section 2.10.6.1.2). If the reply exceeds ca_maxresponsesize_cached (and sa_cachethis or csa_cachethis is TRUE), then the server MUST return NFS4ERR_REP_TOO_BIG_TO_CACHE. Even if NFS4ERR_REP_TOO_BIG_TO_CACHE (or any other error for that matter) is returned on an operation other than the first operation (SEQUENCE or CB_SEQUENCE), then the reply MUST be cached if sa_cachethis or csa_cachethis is TRUE. For example, if a COMPOUND has eleven operations, including SEQUENCE, the fifth operation is a RENAME, and the tenth operation is a READ for one million bytes, the server may return NFS4ERR_REP_TOO_BIG_TO_CACHE on the tenth operation. Since the server executed several operations, especially the non-idempotent RENAME, the client's request to cache the reply needs to be honored in order for the correct operation of exactly once semantics. If the client retries the request, the server will have cached a reply that contains results for ten of the eleven requested operations, with the tenth operation having a status of NFS4ERR_REP_TOO_BIG_TO_CACHE.

如果sa_cachethis或csa_cachethis为真,则应答器必须缓存应答,除非序列或CB_序列操作返回错误(见第2.10.6.1.2节)。如果回复超过ca_maxresponsesize_cached(并且sa_cachethis或csa_cachethis为真),则服务器必须将NFS4ERR_REP_TO_BIG_返回到_CACHE。即使NFS4ERR_REP_TOO_BIG_TO_CACHE(或任何其他相关错误)在第一个操作(序列或CB_序列)以外的操作上返回,如果sa_cachethis或csa_cachethis为真,则必须缓存回复。例如,如果一个化合物有11个操作,包括序列,第五个操作是重命名,第十个操作是读取一百万字节,则服务器可能会在第十个操作中将NFS4ERR_REP_TOO_BIG_返回给_缓存。由于服务器执行了多个操作,特别是非幂等重命名,因此需要满足客户机缓存回复的请求,以便正确操作一次。如果客户端重试请求,服务器将缓存一个应答,其中包含11个请求操作中10个操作的结果,第10个操作的状态为NFS4ERR_REP_TOO_BIG_TO_CACHE。

A client needs to take care that when sending operations that change the current filehandle (except for PUTFH, PUTPUBFH, PUTROOTFH, and RESTOREFH), it not exceed the maximum reply buffer before the GETFH operation. Otherwise, the client will have to retry the operation that changed the current filehandle, in order to obtain the desired filehandle. For the OPEN operation (see Section 18.16), retry is not always available as an option. The following guidelines for the handling of filehandle-changing operations are advised:

客户端需要注意的是,在发送更改当前文件句柄的操作时(PUTFH、PUTPUBFH、PUTROOTFH和RESTOREFH除外),它不会超过GETFH操作之前的最大回复缓冲区。否则,客户端将必须重试更改当前文件句柄的操作,以获得所需的文件句柄。对于打开操作(参见第18.16节),重试并不总是作为选项可用。建议按照以下准则处理filehandle更改操作:

o Within the same COMPOUND procedure, a client SHOULD send GETFH immediately after a current filehandle-changing operation. A client MUST send GETFH after a current filehandle-changing operation that is also non-idempotent (e.g., the OPEN operation), unless the operation is RESTOREFH. RESTOREFH is an exception, because even though it is non-idempotent, the filehandle RESTOREFH produced originated from an operation that is either idempotent (e.g., PUTFH, LOOKUP), or non-idempotent (e.g., OPEN, CREATE). If the origin is non-idempotent, then because the client MUST send GETFH after the origin operation, the client can recover if RESTOREFH returns an error.

o 在同一复合过程中,客户机应该在当前文件句柄更改操作之后立即发送GETFH。除非操作是RESTOREFH,否则客户端必须在当前文件句柄更改操作之后发送GETFH,该操作也是非幂等的(例如,OPEN操作)。RESTOREFH是一个例外,因为即使它是非幂等的,生成的filehandle RESTOREFH也源于幂等(例如PUTFH、LOOKUP)或非幂等(例如OPEN、CREATE)的操作。如果origin是非幂等的,那么由于客户机必须在origin操作之后发送GETFH,因此如果RESTOREFH返回错误,客户机可以恢复。

o A server MAY return NFS4ERR_REP_TOO_BIG or NFS4ERR_REP_TOO_BIG_TO_CACHE (if sa_cachethis is TRUE) on a filehandle-changing operation if the reply would be too large on the next operation.

o 如果在下一个操作中回复太大,服务器可能会在文件句柄更改操作中返回NFS4ERR_REP_TOO_BIG或NFS4ERR_REP_TOO_BIG TO_CACHE(如果sa_CACHE这是真的)。

o A server SHOULD return NFS4ERR_REP_TOO_BIG or NFS4ERR_REP_TOO_BIG_TO_CACHE (if sa_cachethis is TRUE) on a filehandle-changing, non-idempotent operation if the reply would be too large on the next operation, especially if the operation is OPEN.

o 如果在下一个操作(尤其是在操作打开的情况下)中回复过大,则服务器应在文件句柄更改的非幂等操作上返回NFS4ERR_REP_TOO_BIG或NFS4ERR_REP_TOO_BIG TO_CACHE(如果sa_CACHE这是真的),返回NFS4ERR_REP_TOO_BIG_TO_CACHE)。

o A server MAY return NFS4ERR_UNSAFE_COMPOUND to a non-idempotent current filehandle-changing operation, if it looks at the next operation (in the same COMPOUND procedure) and finds it is not GETFH. The server SHOULD do this if it is unable to determine in advance whether the total response size would exceed ca_maxresponsesize_cached or ca_maxresponsesize.

o 如果服务器查看下一个操作(在同一复合过程中)并发现它不是GETFH,则可能会将NFS4ERR_UNSAFE_复合返回到非幂等当前文件句柄更改操作。如果服务器无法预先确定总响应大小是否会超过ca_maxresponsesize_cached或ca_maxresponsesize,则应执行此操作。

2.10.6.5. Persistence
2.10.6.5. 坚持不懈

Since the reply cache is bounded, it is practical for the reply cache to persist across server restarts. The replier MUST persist the following information if it agreed to persist the session (when the session was created; see Section 18.36):

由于回复缓存是有界的,所以在服务器重新启动时,回复缓存可以保持不变。如果回复者同意保留会话,则回复者必须保留以下信息(会话创建时;参见第18.36节):

o The session ID.

o 会话ID为。

o The slot table including the sequence ID and cached reply for each slot.

o 插槽表,包括每个插槽的序列ID和缓存回复。

The above are sufficient for a replier to provide EOS semantics for any requests that were sent and executed before the server restarted. If the replier is a client, then there is no need for it to persist any more information, unless the client will be persisting all other state across client restart, in which case, the server will never see any NFSv4.1-level protocol manifestation of a client restart. If the

以上内容足以让应答器为服务器重新启动之前发送和执行的任何请求提供EOS语义。如果应答器是一个客户端,那么它就不需要保存更多的信息,除非客户端将在客户端重新启动期间保存所有其他状态,在这种情况下,服务器将永远不会看到客户端重新启动的任何NFSv4.1级协议表现。如果

replier is a server, with just the slot table and session ID persisting, any requests the client retries after the server restart will return the results that are cached in the reply cache, and any new requests (i.e., the sequence ID is one greater than the slot's sequence ID) MUST be rejected with NFS4ERR_DEADSESSION (returned by SEQUENCE). Such a session is considered dead. A server MAY re-animate a session after a server restart so that the session will accept new requests as well as retries. To re-animate a session, the server needs to persist additional information through server restart:

replier是一台服务器,只有插槽表和会话ID保持不变,客户端在服务器重新启动后重试的任何请求都将返回缓存在reply缓存中的结果,任何新请求(即,序列ID比插槽的序列ID大一个)都必须使用NFS4ERR_DEADSESSION(按序列返回)拒绝。这样的会议被认为是死的。服务器重新启动后,服务器可能会重新设置会话的动画,以便会话将接受新请求和重试。要重新设置会话的动画,服务器需要通过服务器重新启动来保存其他信息:

o The client ID. This is a prerequisite to let the client create more sessions associated with the same client ID as the re-animated session.

o 客户端ID。这是让客户端创建与重新设置动画的会话相同的客户端ID关联的更多会话的先决条件。

o The client ID's sequence ID that is used for creating sessions (see Sections 18.35 and 18.36). This is a prerequisite to let the client create more sessions.

o 用于创建会话的客户端ID的序列ID(参见第18.35和18.36节)。这是让客户端创建更多会话的先决条件。

o The principal that created the client ID. This allows the server to authenticate the client when it sends EXCHANGE_ID.

o 创建客户端ID的主体。这允许服务器在发送EXCHANGE\u ID时对客户端进行身份验证。

o The SSV, if SP4_SSV state protection was specified when the client ID was created (see Section 18.35). This lets the client create new sessions, and associate connections with the new and existing sessions.

o 如果在创建客户端ID时指定了SP4_SSV状态保护,则为SSV(参见第18.35节)。这允许客户端创建新会话,并将连接与新会话和现有会话相关联。

o The properties of the client ID as defined in Section 18.35.

o 第18.35节中定义的客户ID属性。

A persistent reply cache places certain demands on the server. The execution of the sequence of operations (starting with SEQUENCE) and placement of its results in the persistent cache MUST be atomic. If a client retries a sequence of operations that was previously executed on the server, the only acceptable outcomes are either the original cached reply or an indication that the client ID or session has been lost (indicating a catastrophic loss of the reply cache or a session that has been deleted because the client failed to use the session for an extended period of time).

持久回复缓存会对服务器提出某些要求。操作序列(从序列开始)的执行及其结果在持久缓存中的放置必须是原子的。如果客户端重试以前在服务器上执行的一系列操作,则唯一可接受的结果是原始缓存的回复或客户端ID或会话已丢失的指示(表示回复缓存的灾难性丢失,或由于客户端在较长时间内未能使用会话而删除的会话)。

A server could fail and restart in the middle of a COMPOUND procedure that contains one or more non-idempotent or idempotent-but-modifying operations. This creates an even higher challenge for atomic execution and placement of results in the reply cache. One way to view the problem is as a single transaction consisting of each operation in the COMPOUND followed by storing the result in persistent storage, then finally a transaction commit. If there is a failure before the transaction is committed, then the server rolls

服务器可以在包含一个或多个非幂等或幂等但修改操作的复合过程的中间失败和重新启动。这给原子执行和结果在应答缓存中的放置带来了更高的挑战。查看问题的一种方法是将其视为一个事务,该事务由复合中的每个操作组成,然后将结果存储在持久性存储中,最后是一个事务提交。如果在提交事务之前出现故障,则服务器将回滚

back the transaction. If the server itself fails, then when it restarts, its recovery logic could roll back the transaction before starting the NFSv4.1 server.

支持交易。如果服务器本身出现故障,那么当它重新启动时,其恢复逻辑可以在启动NFSv4.1服务器之前回滚事务。

While the description of the implementation for atomic execution of the request and caching of the reply is beyond the scope of this document, an example implementation for NFSv2 [38] is described in [39].

虽然请求的原子执行和回复的缓存的实现的描述超出了本文档的范围,但是[39]中描述了NFSv2[38]的示例实现。

2.10.7. RDMA Considerations
2.10.7. RDMA注意事项

A complete discussion of the operation of RPC-based protocols over RDMA transports is in [8]. A discussion of the operation of NFSv4, including NFSv4.1, over RDMA is in [9]. Where RDMA is considered, this specification assumes the use of such a layering; it addresses only the upper-layer issues relevant to making best use of RPC/RDMA.

关于基于RPC的协议在RDMA传输上的操作的完整讨论见[8]。[9]中讨论了NFSv4(包括NFSv4.1)在RDMA上的运行。在考虑RDMA的情况下,本规范假设使用这种分层;它只解决与充分利用RPC/RDMA相关的上层问题。

2.10.7.1. RDMA Connection Resources
2.10.7.1. RDMA连接资源

RDMA requires its consumers to register memory and post buffers of a specific size and number for receive operations.

RDMA要求其使用者为接收操作注册特定大小和数量的内存和post缓冲区。

Registration of memory can be a relatively high-overhead operation, since it requires pinning of buffers, assignment of attributes (e.g., readable/writable), and initialization of hardware translation. Preregistration is desirable to reduce overhead. These registrations are specific to hardware interfaces and even to RDMA connection endpoints; therefore, negotiation of their limits is desirable to manage resources effectively.

内存注册可能是一个开销相对较高的操作,因为它需要固定缓冲区、分配属性(例如,可读/写)和初始化硬件转换。预注册可以减少开销。这些注册特定于硬件接口,甚至RDMA连接端点;因此,为了有效地管理资源,需要对其限制进行协商。

Following basic registration, these buffers must be posted by the RPC layer to handle receives. These buffers remain in use by the RPC/ NFSv4.1 implementation; the size and number of them must be known to the remote peer in order to avoid RDMA errors that would cause a fatal error on the RDMA connection.

在基本注册之后,RPC层必须发布这些缓冲区来处理接收。这些缓冲区仍由RPC/NFSv4.1实现使用;远程对等方必须知道它们的大小和数量,以避免可能导致RDMA连接上致命错误的RDMA错误。

NFSv4.1 manages slots as resources on a per-session basis (see Section 2.10), while RDMA connections manage credits on a per-connection basis. This means that in order for a peer to send data over RDMA to a remote buffer, it has to have both an NFSv4.1 slot and an RDMA credit. If multiple RDMA connections are associated with a session, then if the total number of credits across all RDMA connections associated with the session is X, and the number of slots in the session is Y, then the maximum number of outstanding requests is the lesser of X and Y.

NFSv4.1在每个会话的基础上管理插槽作为资源(参见第2.10节),而RDMA连接在每个连接的基础上管理信用。这意味着,为了让对等方通过RDMA将数据发送到远程缓冲区,它必须具有NFSv4.1插槽和RDMA信用。如果多个RDMA连接与一个会话相关联,那么如果与该会话相关联的所有RDMA连接的信用总数为X,且会话中的插槽数为Y,则未完成请求的最大数量为X和Y中的较小者。

2.10.7.2. Flow Control
2.10.7.2. 流量控制

Previous versions of NFS do not provide flow control; instead, they rely on the windowing provided by transports like TCP to throttle requests. This does not work with RDMA, which provides no operation flow control and will terminate a connection in error when limits are exceeded. Limits such as maximum number of requests outstanding are therefore negotiated when a session is created (see the ca_maxrequests field in Section 18.36). These limits then provide the maxima within which each connection associated with the session's channel(s) must remain. RDMA connections are managed within these limits as described in Section 3.3 of [8]; if there are multiple RDMA connections, then the maximum number of requests for a channel will be divided among the RDMA connections. Put a different way, the onus is on the replier to ensure that the total number of RDMA credits across all connections associated with the replier's channel does exceed the channel's maximum number of outstanding requests.

NFS的早期版本不提供流控制;相反,它们依靠TCP等传输提供的窗口来限制请求。这不适用于RDMA,RDMA不提供操作流控制,并且在超出限制时会错误地终止连接。因此,在创建会话时,将协商未完成请求的最大数量等限制(请参阅第18.36节中的“ca_maxrequests”字段)。然后,这些限制提供了与会话通道关联的每个连接必须保持的最大值。RDMA连接在[8]第3.3节所述的限制范围内进行管理;如果存在多个RDMA连接,则对通道的最大请求数将在RDMA连接之间分配。换句话说,应答器有责任确保与应答器的通道相关联的所有连接上的RDMA信用总数不超过通道的最大未完成请求数。

The limits may also be modified dynamically at the replier's choosing by manipulating certain parameters present in each NFSv4.1 reply. In addition, the CB_RECALL_SLOT callback operation (see Section 20.8) can be sent by a server to a client to return RDMA credits to the server, thereby lowering the maximum number of requests a client can have outstanding to the server.

还可以通过操纵每个NFSv4.1回复中存在的某些参数,在回复者选择时动态修改限制。此外,服务器可以将CB_RECALL_插槽回调操作(参见第20.8节)发送给客户端,以将RDMA积分返回给服务器,从而降低客户端可以向服务器发出的最大未完成请求数。

2.10.7.3. Padding
2.10.7.3. 衬料

Header padding is requested by each peer at session initiation (see the ca_headerpadsize argument to CREATE_SESSION in Section 18.36), and subsequently used by the RPC RDMA layer, as described in [8]. Zero padding is permitted.

头填充由每个对等方在会话启动时请求(参见第18.36节中创建会话的ca_headerpadsize参数),随后由RPC RDMA层使用,如[8]所述。允许零填充。

Padding leverages the useful property that RDMA preserve alignment of data, even when they are placed into anonymous (untagged) buffers. If requested, client inline writes will insert appropriate pad bytes within the request header to align the data payload on the specified boundary. The client is encouraged to add sufficient padding (up to the negotiated size) so that the "data" field of the WRITE operation is aligned. Most servers can make good use of such padding, which allows them to chain receive buffers in such a way that any data carried by client requests will be placed into appropriate buffers at the server, ready for file system processing. The receiver's RPC layer encounters no overhead from skipping over pad bytes, and the RDMA layer's high performance makes the insertion and transmission of padding on the sender a significant optimization. In this way, the need for servers to perform RDMA Read to satisfy all but the largest

填充利用了RDMA保留数据对齐的有用特性,即使数据被放入匿名(未标记)缓冲区中。如果请求,客户端内联写入将在请求标头内插入适当的pad字节,以将数据有效负载与指定边界对齐。鼓励客户机添加足够的填充(直到协商的大小),以便对齐写入操作的“数据”字段。大多数服务器都可以很好地利用这种填充,这使它们能够以这样的方式链接接收缓冲区,即客户端请求携带的任何数据都将被放置到服务器上适当的缓冲区中,以便进行文件系统处理。接收方的RPC层不会因跳过pad字节而产生任何开销,RDMA层的高性能使得在发送方上插入和传输padding成为一个重要的优化。通过这种方式,服务器需要执行RDMA读取以满足除最大

client writes is obviated. An added benefit is the reduction of message round trips on the network -- a potentially good trade, where latency is present.

避免了客户端写入。另外一个好处是减少了网络上的消息往返——这是一个潜在的好交易,因为存在延迟。

The value to choose for padding is subject to a number of criteria. A primary source of variable-length data in the RPC header is the authentication information, the form of which is client-determined, possibly in response to server specification. The contents of COMPOUNDs, sizes of strings such as those passed to RENAME, etc. all go into the determination of a maximal NFSv4.1 request size and therefore minimal buffer size. The client must select its offered value carefully, so as to avoid overburdening the server, and vice versa. The benefit of an appropriate padding value is higher performance.

要为填充选择的值取决于许多条件。RPC头中可变长度数据的主要来源是身份验证信息,其形式由客户端确定,可能是响应服务器规范。化合物的内容、字符串的大小(如传递给重命名的字符串)等都将用于确定最大NFSv4.1请求大小,从而确定最小缓冲区大小。客户机必须仔细选择其提供的价值,以避免服务器负担过重,反之亦然。适当的填充值的好处是更高的性能。

                    Sender gather:
        |RPC Request|Pad  bytes|Length| -> |User data...|
        \------+----------------------/      \
                \                             \
                 \    Receiver scatter:        \-----------+- ...
            /-----+----------------\            \           \
            |RPC Request|Pad|Length|   ->  |FS buffer|->|FS buffer|->...
        
                    Sender gather:
        |RPC Request|Pad  bytes|Length| -> |User data...|
        \------+----------------------/      \
                \                             \
                 \    Receiver scatter:        \-----------+- ...
            /-----+----------------\            \           \
            |RPC Request|Pad|Length|   ->  |FS buffer|->|FS buffer|->...
        

In the above case, the server may recycle unused buffers to the next posted receive if unused by the actual received request, or may pass the now-complete buffers by reference for normal write processing. For a server that can make use of it, this removes any need for data copies of incoming data, without resorting to complicated end-to-end buffer advertisement and management. This includes most kernel-based and integrated server designs, among many others. The client may perform similar optimizations, if desired.

在上述情况下,如果实际接收到的请求未使用,服务器可以将未使用的缓冲区回收到下一次发布的接收,或者可以通过引用传递现在完成的缓冲区以进行正常的写入处理。对于可以使用它的服务器来说,这消除了对传入数据的数据副本的任何需要,而无需求助于复杂的端到端缓冲区公布和管理。这包括大多数基于内核和集成的服务器设计,以及许多其他设计。如果需要,客户端可以执行类似的优化。

2.10.7.4. Dual RDMA and Non-RDMA Transports
2.10.7.4. 双RDMA和非RDMA传输

Some RDMA transports (e.g., RFC 5040 [10]) permit a "streaming" (non-RDMA) phase, where ordinary traffic might flow before "stepping up" to RDMA mode, commencing RDMA traffic. Some RDMA transports start connections always in RDMA mode. NFSv4.1 allows, but does not assume, a streaming phase before RDMA mode. When a connection is associated with a session, the client and server negotiate whether the connection is used in RDMA or non-RDMA mode (see Sections 18.36 and 18.34).

一些RDMA传输(例如RFC 5040[10])允许“流”(非RDMA)阶段,其中普通流量可能在“升级”到RDMA模式、开始RDMA流量之前流动。一些RDMA传输总是在RDMA模式下启动连接。NFSv4.1允许但不假设RDMA模式之前的流阶段。当连接与会话关联时,客户机和服务器协商连接是在RDMA模式下使用还是在非RDMA模式下使用(请参阅第18.36和18.34节)。

2.10.8. Session Security
2.10.8. 会话安全
2.10.8.1. Session Callback Security
2.10.8.1. 会话回调安全性

Via session/connection association, NFSv4.1 improves security over that provided by NFSv4.0 for the backchannel. The connection is client-initiated (see Section 18.34) and subject to the same firewall and routing checks as the fore channel. At the client's option (see Section 18.35), connection association is fully authenticated before being activated (see Section 18.34). Traffic from the server over the backchannel is authenticated exactly as the client specifies (see Section 2.10.8.2).

通过会话/连接关联,NFSv4.1改进了NFSv4.0为反向通道提供的安全性。该连接由客户端启动(见第18.34节),并接受与前通道相同的防火墙和路由检查。根据客户的选择(参见第18.35节),连接关联在激活之前经过完全验证(参见第18.34节)。来自服务器的反向通道流量完全按照客户机的指定进行身份验证(见第2.10.8.2节)。

2.10.8.2. Backchannel RPC Security
2.10.8.2. 反向通道RPC安全

When the NFSv4.1 client establishes the backchannel, it informs the server of the security flavors and principals to use when sending requests. If the security flavor is RPCSEC_GSS, the client expresses the principal in the form of an established RPCSEC_GSS context. The server is free to use any of the flavor/principal combinations the client offers, but it MUST NOT use unoffered combinations. This way, the client need not provide a target GSS principal for the backchannel as it did with NFSv4.0, nor does the server have to implement an RPCSEC_GSS initiator as it did with NFSv4.0 [30].

当NFSv4.1客户端建立反向通道时,它会通知服务器发送请求时要使用的安全风格和主体。如果安全风格是RPCSEC_GSS,则客户机以已建立的RPCSEC_GSS上下文的形式表示主体。服务器可以自由使用客户端提供的任何风格/主体组合,但不能使用未提供的组合。这样,客户端就不必像NFSv4.0那样为后通道提供目标GSS主体,服务器也不必像NFSv4.0那样实现RPCSEC_GSS启动器[30]。

The CREATE_SESSION (Section 18.36) and BACKCHANNEL_CTL (Section 18.33) operations allow the client to specify flavor/ principal combinations.

CREATE_SESSION(第18.36节)和BACKCHANNEL_CTL(第18.33节)操作允许客户端指定风味/主体组合。

Also note that the SP4_SSV state protection mode (see Sections 18.35 and 2.10.8.3) has the side benefit of providing SSV-derived RPCSEC_GSS contexts (Section 2.10.9).

另请注意,SP4_SSV状态保护模式(见第18.35节和第2.10.8.3节)具有提供SSV派生的RPCSEC_GSS上下文(第2.10.9节)的副作用。

2.10.8.3. Protection from Unauthorized State Changes
2.10.8.3. 防止未经授权的状态更改

As described to this point in the specification, the state model of NFSv4.1 is vulnerable to an attacker that sends a SEQUENCE operation with a forged session ID and with a slot ID that it expects the legitimate client to use next. When the legitimate client uses the slot ID with the same sequence number, the server returns the attacker's result from the reply cache, which disrupts the legitimate client and thus denies service to it. Similarly, an attacker could send a CREATE_SESSION with a forged client ID to create a new session associated with the client ID. The attacker could send requests using the new session that change locking state, such as LOCKU operations to release locks the legitimate client has acquired. Setting a security policy on the file that requires RPCSEC_GSS credentials when manipulating the file's state is one potential work

正如规范中对此所述,NFSv4.1的状态模型容易受到攻击者的攻击,攻击者使用伪造的会话ID和插槽ID发送序列操作,该插槽ID预期合法客户端下一步使用。当合法客户端使用具有相同序列号的插槽ID时,服务器会从应答缓存返回攻击者的结果,这会中断合法客户端,从而拒绝向其提供服务。类似地,攻击者可以使用伪造的客户端ID发送CREATE_会话,以创建与客户端ID关联的新会话。攻击者可以使用更改锁定状态的新会话发送请求,例如释放合法客户端获得的锁的锁定操作。在操作文件状态时,对需要RPCSEC_GSS凭据的文件设置安全策略是一项潜在的工作

around, but has the disadvantage of preventing a legitimate client from releasing state when RPCSEC_GSS is required to do so, but a GSS context cannot be obtained (possibly because the user has logged off the client).

但其缺点是,当要求RPCSEC_GSS释放状态时,阻止合法客户端释放状态,但无法获得GSS上下文(可能是因为用户已注销客户端)。

NFSv4.1 provides three options to a client for state protection, which are specified when a client creates a client ID via EXCHANGE_ID (Section 18.35).

NFSv4.1为客户端提供了三种状态保护选项,当客户端通过EXCHANGE_ID创建客户端ID时指定这三种选项(第18.35节)。

The first (SP4_NONE) is to simply waive state protection.

第一个(SP4_NONE)是简单地放弃国家保护。

The other two options (SP4_MACH_CRED and SP4_SSV) share several traits:

其他两个选项(SP4_MACH_CRED和SP4_SSV)有几个共同特点:

o An RPCSEC_GSS-based credential is used to authenticate client ID and session maintenance operations, including creating and destroying a session, associating a connection with the session, and destroying the client ID.

o 基于RPCSEC_GSS的凭据用于验证客户端ID和会话维护操作,包括创建和销毁会话、将连接与会话关联以及销毁客户端ID。

o Because RPCSEC_GSS is used to authenticate client ID and session maintenance, the attacker cannot associate a rogue connection with a legitimate session, or associate a rogue session with a legitimate client ID in order to maliciously alter the client ID's lock state via CLOSE, LOCKU, DELEGRETURN, LAYOUTRETURN, etc.

o 由于RPCSEC_GSS用于验证客户端ID和会话维护,攻击者无法将恶意连接与合法会话相关联,或将恶意会话与合法客户端ID相关联,以便通过CLOSE、LOCKU、DELEGRETURN、LAYOUTRETURN等恶意更改客户端ID的锁定状态。

o In cases where the server's security policies on a portion of its namespace require RPCSEC_GSS authentication, a client may have to use an RPCSEC_GSS credential to remove per-file state (e.g., LOCKU, CLOSE, etc.). The server may require that the principal that removes the state match certain criteria (e.g., the principal might have to be the same as the one that acquired the state). However, the client might not have an RPCSEC_GSS context for such a principal, and might not be able to create such a context (perhaps because the user has logged off). When the client establishes SP4_MACH_CRED or SP4_SSV protection, it can specify a list of operations that the server MUST allow using the machine credential (if SP4_MACH_CRED is used) or the SSV credential (if SP4_SSV is used).

o 如果服务器在其命名空间的一部分上的安全策略需要RPCSEC_GSS身份验证,则客户端可能必须使用RPCSEC_GSS凭据来删除每个文件状态(例如,锁定、关闭等)。服务器可能要求删除状态的主体符合某些条件(例如,主体可能必须与获取状态的主体相同)。但是,客户端可能没有此类主体的RPCSEC_GSS上下文,并且可能无法创建此类上下文(可能是因为用户已注销)。当客户端建立SP4_MACH_CRED或SP4_SSV保护时,它可以指定服务器必须允许使用机器凭据(如果使用SP4_MACH_CRED)或SSV凭据(如果使用SP4_SSV)的操作列表。

The SP4_MACH_CRED state protection option uses a machine credential where the principal that creates the client ID MUST also be the principal that performs client ID and session maintenance operations. The security of the machine credential state protection approach depends entirely on safe guarding the per-machine credential. Assuming a proper safeguard using the per-machine credential for operations like CREATE_SESSION, BIND_CONN_TO_SESSION,

SP4_MACH_CRED状态保护选项使用机器凭据,其中创建客户端ID的主体也必须是执行客户端ID和会话维护操作的主体。机器凭证状态保护方法的安全性完全取决于对每台机器凭证的安全保护。假设在创建会话、绑定连接到会话等操作中使用每台机器凭据进行适当的保护,

DESTROY_SESSION, and DESTROY_CLIENTID will prevent an attacker from associating a rogue connection with a session, or associating a rogue session with a client ID.

DESTROY_SESSION和DESTROY_CLIENTID将防止攻击者将恶意连接与会话关联,或将恶意会话与客户端ID关联。

There are at least three scenarios for the SP4_MACH_CRED option:

SP4马赫CRED选项至少有三种情况:

1. The system administrator configures a unique, permanent per-machine credential for one of the mandated GSS mechanisms (e.g., if Kerberos V5 is used, a "keytab" containing a principal derived from a client host name could be used).

1. 系统管理员为其中一个强制GSS机制配置一个唯一的、永久的每机器凭据(例如,如果使用Kerberos V5,则可以使用包含从客户端主机名派生的主体的“keytab”)。

2. The client is used by a single user, and so the client ID and its sessions are used by just that user. If the user's credential expires, then session and client ID maintenance cannot occur, but since the client has a single user, only that user is inconvenienced.

2. 客户端由单个用户使用,因此客户端ID及其会话仅由该用户使用。如果用户的凭据过期,则无法进行会话和客户端ID维护,但由于客户端只有一个用户,因此只会给该用户带来不便。

3. The physical client has multiple users, but the client implementation has a unique client ID for each user. This is effectively the same as the second scenario, but a disadvantage is that each user needs to be allocated at least one session each, so the approach suffers from lack of economy.

3. 物理客户端有多个用户,但客户端实现对每个用户都有一个唯一的客户端ID。这实际上与第二个场景相同,但缺点是每个用户至少需要分配一个会话,因此该方法缺乏经济性。

The SP4_SSV protection option uses the SSV (Section 1.6), via RPCSEC_GSS and the SSV GSS mechanism (Section 2.10.9), to protect state from attack. The SP4_SSV protection option is intended for the situation comprised of a client that has multiple active users and a system administrator who wants to avoid the burden of installing a permanent machine credential on each client. The SSV is established and updated on the server via SET_SSV (see Section 18.47). To prevent eavesdropping, a client SHOULD send SET_SSV via RPCSEC_GSS with the privacy service. Several aspects of the SSV make it intractable for an attacker to guess the SSV, and thus associate rogue connections with a session, and rogue sessions with a client ID:

SP4_SSV保护选项通过RPCSEC_GSS和SSV GSS机制(第2.10.9节)使用SSV(第1.6节)保护状态免受攻击。SP4_SSV保护选项适用于由具有多个活动用户的客户端和希望避免在每个客户端上安装永久机器凭据的系统管理员组成的情况。SSV通过SET_SSV在服务器上建立和更新(见第18.47节)。为了防止窃听,客户端应该通过RPCSEC_GSS和隐私服务发送SET_SSV。SSV的几个方面使得攻击者难以猜测SSV,从而将恶意连接与会话关联,将恶意会话与客户端ID关联:

o The arguments to and results of SET_SSV include digests of the old and new SSV, respectively.

o SET_SSV的参数和结果分别包括旧SSV和新SSV的摘要。

o Because the initial value of the SSV is zero, therefore known, the client that opts for SP4_SSV protection and opts to apply SP4_SSV protection to BIND_CONN_TO_SESSION and CREATE_SESSION MUST send at least one SET_SSV operation before the first BIND_CONN_TO_SESSION operation or before the second CREATE_SESSION operation on a client ID. If it does not, the SSV mechanism will not generate tokens (Section 2.10.9). A client SHOULD send SET_SSV as soon as a session is created.

o 由于SSV的初始值为零,因此已知,选择SP4_SSV保护并选择应用SP4_SSV保护以绑定_CONN_to_会话和创建_会话的客户端必须在对客户端ID执行第一次绑定_CONN_to_会话操作或第二次创建_会话操作之前发送至少一个SET_SSV操作。如果未发送,SSV机制将不会生成令牌(第2.10.9节)。创建会话后,客户端应立即发送SET_SSV。

o A SET_SSV request does not replace the SSV with the argument to SET_SSV. Instead, the current SSV on the server is logically exclusive ORed (XORed) with the argument to SET_SSV. Each time a new principal uses a client ID for the first time, the client SHOULD send a SET_SSV with that principal's RPCSEC_GSS credentials, with RPCSEC_GSS service set to RPC_GSS_SVC_PRIVACY.

o SET_SSV请求不会用SET_SSV的参数替换SSV。相反,服务器上的当前SSV在逻辑上是异或的(XORed),参数为SET_SSV。每次新主体首次使用客户端ID时,客户端应发送一个带有该主体的RPCSEC_GSS凭据的SET_SSV,并将RPCSEC_GSS服务设置为RPC_GSS_SVC_PRIVACY。

Here are the types of attacks that can be attempted by an attacker named Eve on a victim named Bob, and how SP4_SSV protection foils each attack:

以下是名为Eve的攻击者可以对名为Bob的受害者尝试的攻击类型,以及SP4_SSV保护如何挫败每次攻击:

o Suppose Eve is the first user to log into a legitimate client. Eve's use of an NFSv4.1 file system will cause the legitimate client to create a client ID with SP4_SSV protection, specifying that the BIND_CONN_TO_SESSION operation MUST use the SSV credential. Eve's use of the file system also causes an SSV to be created. The SET_SSV operation that creates the SSV will be protected by the RPCSEC_GSS context created by the legitimate client, which uses Eve's GSS principal and credentials. Eve can eavesdrop on the network while her RPCSEC_GSS context is created and the SET_SSV using her context is sent. Even if the legitimate client sends the SET_SSV with RPC_GSS_SVC_PRIVACY, because Eve knows her own credentials, she can decrypt the SSV. Eve can compute an RPCSEC_GSS credential that BIND_CONN_TO_SESSION will accept, and so associate a new connection with the legitimate session. Eve can change the slot ID and sequence state of a legitimate session, and/or the SSV state, in such a way that when Bob accesses the server via the same legitimate client, the legitimate client will be unable to use the session.

o 假设Eve是第一个登录到合法客户端的用户。Eve使用NFSv4.1文件系统将导致合法客户端创建具有SP4_SSV保护的客户端ID,并指定绑定连接到会话操作必须使用SSV凭据。Eve对文件系统的使用也会导致创建SSV。创建SSV的SET_SSV操作将受到合法客户端创建的RPCSEC_GSS上下文的保护,该上下文使用Eve的GSS主体和凭据。Eve可以在创建其RPCSEC_GSS上下文并发送使用其上下文的SET_SSV时窃听网络。即使合法客户端发送带有RPC_GSS_SVC_隐私的SET_SSV,因为Eve知道自己的凭据,她也可以解密SSV。Eve可以计算一个RPCSEC_GSS凭据,该凭据将_CONN_绑定到会话将接受的会话,从而将新连接与合法会话相关联。Eve可以更改合法会话的插槽ID和序列状态,和/或SSV状态,这样当Bob通过同一合法客户端访问服务器时,合法客户端将无法使用该会话。

The client's only recourse is to create a new client ID for Bob to use, and establish a new SSV for the client ID. The client will be unable to delete the old client ID, and will let the lease on the old client ID expire.

客户唯一的办法是创建一个新的客户ID供Bob使用,并为客户ID建立一个新的SSV。客户将无法删除旧客户ID,并将让旧客户ID的租约到期。

Once the legitimate client establishes an SSV over the new session using Bob's RPCSEC_GSS context, Eve can use the new session via the legitimate client, but she cannot disrupt Bob. Moreover, because the client SHOULD have modified the SSV due to Eve using the new session, Bob cannot get revenge on Eve by associating a rogue connection with the session.

一旦合法客户端使用Bob的RPCSEC_GSS上下文在新会话上建立SSV,Eve可以通过合法客户端使用新会话,但她不能中断Bob。此外,由于Eve使用新会话,客户端本应修改SSV,因此Bob无法通过将恶意连接与会话关联来报复Eve。

The question is how did the legitimate client detect that Eve has hijacked the old session? When the client detects that a new principal, Bob, wants to use the session, it SHOULD have sent a SET_SSV, which leads to the following sub-scenarios:

问题是合法客户是如何发现Eve劫持了旧会话的?当客户端检测到新主体Bob想要使用会话时,它应该发送一个SET_SSV,这将导致以下子场景:

* Let us suppose that from the rogue connection, Eve sent a SET_SSV with the same slot ID and sequence ID that the legitimate client later uses. The server will assume the SET_SSV sent with Bob's credentials is a retry, and return to the legitimate client the reply it sent Eve. However, unless Eve can correctly guess the SSV the legitimate client will use, the digest verification checks in the SET_SSV response will fail. That is an indication to the client that the session has apparently been hijacked.

* 让我们假设Eve从rogue连接发送了一个SET_SSV,该SET_SSV具有合法客户端稍后使用的相同插槽ID和序列ID。服务器将假定使用Bob的凭据发送的SET_SSV是重试,并将其发送的回复返回给合法客户端。但是,除非Eve能够正确猜测合法客户端将使用的SSV,否则SET_SSV响应中的摘要验证检查将失败。这向客户端表明会话显然已被劫持。

* Alternatively, Eve sent a SET_SSV with a different slot ID than the legitimate client uses for its SET_SSV. Then the digest verification of the SET_SSV sent with Bob's credentials fails on the server, and the error returned to the client makes it apparent that the session has been hijacked.

* 或者,Eve发送的SET_SSV的插槽ID与合法客户端用于其SET_SSV的插槽ID不同。然后,服务器上对使用Bob凭据发送的SET_SSV的摘要验证失败,返回给客户端的错误表明会话已被劫持。

* Alternatively, Eve sent an operation other than SET_SSV, but with the same slot ID and sequence that the legitimate client uses for its SET_SSV. The server returns to the legitimate client the response it sent Eve. The client sees that the response is not at all what it expects. The client assumes either session hijacking or a server bug, and either way destroys the old session.

* 或者,Eve发送的操作不是SET_SSV,而是合法客户端用于其SET_SSV的相同插槽ID和序列。服务器将其发送的响应返回给合法客户端。客户机发现响应根本不是它所期望的。客户端假定会话劫持或服务器错误,并以任何方式破坏旧会话。

o Eve associates a rogue connection with the session as above, and then destroys the session. Again, Bob goes to use the server from the legitimate client, which sends a SET_SSV using Bob's credentials. The client receives an error that indicates that the session does not exist. When the client tries to create a new session, this will fail because the SSV it has does not match that which the server has, and now the client knows the session was hijacked. The legitimate client establishes a new client ID.

o Eve如上所述将流氓连接与会话关联,然后销毁会话。同样,Bob使用来自合法客户端的服务器,该客户端使用Bob的凭据发送一组SSV。客户端收到一个错误,指示会话不存在。当客户端尝试创建新会话时,这将失败,因为它拥有的SSV与服务器拥有的SSV不匹配,现在客户端知道会话被劫持。合法客户端建立一个新的客户端ID。

o If Eve creates a connection before the legitimate client establishes an SSV, because the initial value of the SSV is zero and therefore known, Eve can send a SET_SSV that will pass the digest verification check. However, because the new connection has not been associated with the session, the SET_SSV is rejected for that reason.

o 如果Eve在合法客户端建立SSV之前创建连接,因为SSV的初始值为零,因此已知,Eve可以发送一个SET_SSV,该SSV将通过摘要验证检查。但是,由于新连接尚未与会话关联,因此SET_SSV将因此被拒绝。

In summary, an attacker's disruption of state when SP4_SSV protection is in use is limited to the formative period of a client ID, its first session, and the establishment of the SSV. Once a non-malicious user uses the client ID, the client quickly detects any hijack and rectifies the situation. Once a non-malicious user successfully modifies the SSV, the attacker cannot use NFSv4.1 operations to disrupt the non-malicious user.

总之,当使用SP4_SSV保护时,攻击者对状态的破坏仅限于客户端ID的形成期、其第一个会话和SSV的建立。一旦非恶意用户使用客户端ID,客户端将快速检测任何劫持并纠正情况。一旦非恶意用户成功修改SSV,攻击者就无法使用NFSv4.1操作中断非恶意用户。

Note that neither the SP4_MACH_CRED nor SP4_SSV protection approaches prevent hijacking of a transport connection that has previously been associated with a session. If the goal of a counter-threat strategy is to prevent connection hijacking, the use of IPsec is RECOMMENDED.

请注意,无论是SP4_MACH_CRED还是SP4_SSV保护方法都不能防止劫持以前与会话关联的传输连接。如果反威胁策略的目标是防止连接劫持,建议使用IPsec。

If a connection hijack occurs, the hijacker could in theory change locking state and negatively impact the service to legitimate clients. However, if the server is configured to require the use of RPCSEC_GSS with integrity or privacy on the affected file objects, and if EXCHGID4_FLAG_BIND_PRINC_STATEID capability (Section 18.35) is in force, this will thwart unauthorized attempts to change locking state.

如果发生连接劫持,理论上劫持者可能会改变锁定状态,并对合法客户端的服务产生负面影响。但是,如果服务器配置为要求在受影响的文件对象上使用具有完整性或隐私性的RPCSEC\u GSS,并且如果EXCHGID4\u FLAG\u BIND\u PRINC\u STATEID功能(第18.35节)有效,这将阻止未经授权的更改锁定状态的尝试。

2.10.9. The Secret State Verifier (SSV) GSS Mechanism
2.10.9. 秘密状态验证器(SSV)GSS机制

The SSV provides the secret key for a GSS mechanism internal to NFSv4.1 that NFSv4.1 uses for state protection. Contexts for this mechanism are not established via the RPCSEC_GSS protocol. Instead, the contexts are automatically created when EXCHANGE_ID specifies SP4_SSV protection. The only tokens defined are the PerMsgToken (emitted by GSS_GetMIC) and the SealedMessage token (emitted by GSS_Wrap).

SSV为NFSv4.1内部的GSS机制提供密钥,NFSv4.1使用该机制进行状态保护。该机制的上下文不是通过RPCSEC_GSS协议建立的。相反,当EXCHANGE_ID指定SP4_SSV保护时,会自动创建上下文。唯一定义的令牌是PerMsgToken(由GSS_GetMIC发出)和SealedMessage令牌(由GSS_Wrap发出)。

The mechanism OID for the SSV mechanism is iso.org.dod.internet.private.enterprise.Michael Eisler.nfs.ssv_mech (1.3.6.1.4.1.28882.1.1). While the SSV mechanism does not define any initial context tokens, the OID can be used to let servers indicate that the SSV mechanism is acceptable whenever the client sends a SECINFO or SECINFO_NO_NAME operation (see Section 2.6).

SSV机制的机制OID是iso.org.dod.internet.private.enterprise.Michael Eisler.nfs.SSV_mech(1.3.6.1.4.1.28882.1.1)。虽然SSV机制未定义任何初始上下文令牌,但OID可用于让服务器在客户端发送SECINFO或SECINFO_NO_NAME操作时指示SSV机制是可接受的(请参阅第2.6节)。

The SSV mechanism defines four subkeys derived from the SSV value. Each time SET_SSV is invoked, the subkeys are recalculated by the client and server. The calculation of each of the four subkeys depends on each of the four respective ssv_subkey4 enumerated values. The calculation uses the HMAC [11] algorithm, using the current SSV as the key, the one-way hash algorithm as negotiated by EXCHANGE_ID, and the input text as represented by the XDR encoded enumeration value for that subkey of data type ssv_subkey4. If the length of the output of the HMAC algorithm exceeds the length of key of the encryption algorithm (which is also negotiated by EXCHANGE_ID), then the subkey MUST be truncated from the HMAC output, i.e., if the subkey is of N bytes long, then the first N bytes of the HMAC output MUST be used for the subkey. The specification of EXCHANGE_ID states that the length of the output of the HMAC algorithm MUST NOT be less than the length of subkey needed for the encryption algorithm (see Section 18.35).

SSV机制定义了从SSV值派生的四个子键。每次调用SET_SSV时,客户端和服务器都会重新计算子键。四个子键中每一个子键的计算取决于四个各自的ssv_子键4枚举值中的每一个。该计算使用HMAC[11]算法,使用当前SSV作为密钥,使用EXCHANGE_ID协商的单向哈希算法,并使用数据类型为SSV_subkey4的子密钥的XDR编码枚举值表示的输入文本。如果HMAC算法的输出长度超过加密算法的密钥长度(也由EXCHANGE_ID协商),则必须从HMAC输出中截断子密钥,即,如果子密钥长度为N字节,则必须将HMAC输出的前N字节用于子密钥。交换ID规范规定HMAC算法的输出长度不得小于加密算法所需的子密钥长度(见第18.35节)。

   /* Input for computing subkeys */
   enum ssv_subkey4 {
           SSV4_SUBKEY_MIC_I2T     = 1,
           SSV4_SUBKEY_MIC_T2I     = 2,
           SSV4_SUBKEY_SEAL_I2T    = 3,
           SSV4_SUBKEY_SEAL_T2I    = 4
   };
        
   /* Input for computing subkeys */
   enum ssv_subkey4 {
           SSV4_SUBKEY_MIC_I2T     = 1,
           SSV4_SUBKEY_MIC_T2I     = 2,
           SSV4_SUBKEY_SEAL_I2T    = 3,
           SSV4_SUBKEY_SEAL_T2I    = 4
   };
        

The subkey derived from SSV4_SUBKEY_MIC_I2T is used for calculating message integrity codes (MICs) that originate from the NFSv4.1 client, whether as part of a request over the fore channel or a response over the backchannel. The subkey derived from SSV4_SUBKEY_MIC_T2I is used for MICs originating from the NFSv4.1 server. The subkey derived from SSV4_SUBKEY_SEAL_I2T is used for encryption text originating from the NFSv4.1 client, and the subkey derived from SSV4_SUBKEY_SEAL_T2I is used for encryption text originating from the NFSv4.1 server.

从SSV4_subkey_MIC_I2T派生的子密钥用于计算源自NFSv4.1客户端的消息完整性代码(MIC),无论是作为前通道请求的一部分还是作为后通道响应的一部分。从SSV4_subkey_MIC_T2I派生的子键用于源自NFSv4.1服务器的MIC。从SSV4_subkey_SEAL_I2T派生的子密钥用于源自NFSv4.1客户端的加密文本,从SSV4_subkey_SEAL_T2I派生的子密钥用于源自NFSv4.1服务器的加密文本。

The PerMsgToken description is based on an XDR definition:

PerMsgToken描述基于XDR定义:

   /* Input for computing smt_hmac */
   struct ssv_mic_plain_tkn4 {
     uint32_t        smpt_ssv_seq;
     opaque          smpt_orig_plain<>;
   };
        
   /* Input for computing smt_hmac */
   struct ssv_mic_plain_tkn4 {
     uint32_t        smpt_ssv_seq;
     opaque          smpt_orig_plain<>;
   };
        
   /* SSV GSS PerMsgToken token */
   struct ssv_mic_tkn4 {
     uint32_t        smt_ssv_seq;
     opaque          smt_hmac<>;
   };
        
   /* SSV GSS PerMsgToken token */
   struct ssv_mic_tkn4 {
     uint32_t        smt_ssv_seq;
     opaque          smt_hmac<>;
   };
        

The field smt_hmac is an HMAC calculated by using the subkey derived from SSV4_SUBKEY_MIC_I2T or SSV4_SUBKEY_MIC_T2I as the key, the one-way hash algorithm as negotiated by EXCHANGE_ID, and the input text as represented by data of type ssv_mic_plain_tkn4. The field smpt_ssv_seq is the same as smt_ssv_seq. The field smpt_orig_plain is the "message" input passed to GSS_GetMIC() (see Section 2.3.1 of [7]). The caller of GSS_GetMIC() provides a pointer to a buffer containing the plain text. The SSV mechanism's entry point for GSS_GetMIC() encodes this into an opaque array, and the encoding will include an initial four-byte length, plus any necessary padding. Prepended to this will be the XDR encoded value of smpt_ssv_seq, thus making up an XDR encoding of a value of data type ssv_mic_plain_tkn4, which in turn is the input into the HMAC.

字段smt_hmac是通过使用从SSV4_subkey_MIC_I2T或SSV4_subkey_MIC_T2I派生的子键作为键、由交换ID协商的单向散列算法以及由ssv_MIC_plain_tkn4类型的数据表示的输入文本来计算的hmac。字段smpt_ssv_seq与smt_ssv_seq相同。字段smpt_orig_plain是传递给GSS_GetMIC()的“消息”输入(见[7]第2.3.1节)。GSS_GetMIC()的调用者提供指向包含纯文本的缓冲区的指针。SSV机制的GSS_GetMIC()入口点将其编码为不透明数组,编码将包括初始的四字节长度,以及任何必要的填充。在此之前将是smpt_ssv_seq的XDR编码值,从而构成数据类型ssv_mic_plain_tkn4的值的XDR编码,该值反过来是HMAC的输入。

The token emitted by GSS_GetMIC() is XDR encoded and of XDR data type ssv_mic_tkn4. The field smt_ssv_seq comes from the SSV sequence number, which is equal to one after SET_SSV (Section 18.47) is called the first time on a client ID. Thereafter, the SSV sequence number is incremented on each SET_SSV. Thus, smt_ssv_seq represents the version of the SSV at the time GSS_GetMIC() was called. As noted in Section 18.35, the client and server can maintain multiple concurrent versions of the SSV. This allows the SSV to be changed without serializing all RPC calls that use the SSV mechanism with SET_SSV operations. Once the HMAC is calculated, it is XDR encoded into smt_hmac, which will include an initial four-byte length, and any necessary padding. Prepended to this will be the XDR encoded value of smt_ssv_seq.

GSS_GetMIC()发出的令牌是XDR编码的,其XDR数据类型为ssv_mic_tkn4。字段smt_ssv_seq来自ssv序列号,该序列号等于在客户端ID上第一次调用SET_ssv(第18.47节)后的一个序列号。此后,ssv序列号在每个SET_ssv上递增。因此,smt_ssv_seq表示调用GSS_GetMIC()时ssv的版本。如第18.35节所述,客户端和服务器可以维护SSV的多个并发版本。这允许在不序列化所有使用SSV机制和SET_SSV操作的RPC调用的情况下更改SSV。一旦计算出HMAC,它就被XDR编码到smt_HMAC中,其中包括初始的四字节长度和任何必要的填充。在此之前将是smt_ssv_seq的XDR编码值。

The SealedMessage description is based on an XDR definition:

Sealed消息描述基于XDR定义:

   /* Input for computing ssct_encr_data and ssct_hmac */
   struct ssv_seal_plain_tkn4 {
     opaque          sspt_confounder<>;
     uint32_t        sspt_ssv_seq;
     opaque          sspt_orig_plain<>;
     opaque          sspt_pad<>;
   };
        
   /* Input for computing ssct_encr_data and ssct_hmac */
   struct ssv_seal_plain_tkn4 {
     opaque          sspt_confounder<>;
     uint32_t        sspt_ssv_seq;
     opaque          sspt_orig_plain<>;
     opaque          sspt_pad<>;
   };
        
   /* SSV GSS SealedMessage token */
   struct ssv_seal_cipher_tkn4 {
     uint32_t      ssct_ssv_seq;
     opaque        ssct_iv<>;
     opaque        ssct_encr_data<>;
     opaque        ssct_hmac<>;
   };
        
   /* SSV GSS SealedMessage token */
   struct ssv_seal_cipher_tkn4 {
     uint32_t      ssct_ssv_seq;
     opaque        ssct_iv<>;
     opaque        ssct_encr_data<>;
     opaque        ssct_hmac<>;
   };
        

The token emitted by GSS_Wrap() is XDR encoded and of XDR data type ssv_seal_cipher_tkn4.

GSS_Wrap()发出的令牌是XDR编码的,其XDR数据类型为ssv_seal_cipher_tkn4。

The ssct_ssv_seq field has the same meaning as smt_ssv_seq.

ssct_ssv_seq字段的含义与smt_ssv_seq相同。

The ssct_encr_data field is the result of encrypting a value of the XDR encoded data type ssv_seal_plain_tkn4. The encryption key is the subkey derived from SSV4_SUBKEY_SEAL_I2T or SSV4_SUBKEY_SEAL_T2I, and the encryption algorithm is that negotiated by EXCHANGE_ID.

ssct_encr_数据字段是加密XDR编码数据类型ssv_seal_plain_tkn4的值的结果。加密密钥是从SSV4\u subkey\u SEAL\u I2T或SSV4\u subkey\u SEAL\u T2I派生的子密钥,加密算法是由EXCHANGE\u ID协商的。

The ssct_iv field is the initialization vector (IV) for the encryption algorithm (if applicable) and is sent in clear text. The content and size of the IV MUST comply with the specification of the encryption algorithm. For example, the id-aes256-CBC algorithm MUST

ssct_iv字段是加密算法(如适用)的初始化向量(iv),以明文形式发送。IV的内容和大小必须符合加密算法的规范。例如,id-aes256-CBC算法必须

use a 16-byte initialization vector (IV), which MUST be unpredictable for each instance of a value of data type ssv_seal_plain_tkn4 that is encrypted with a particular SSV key.

使用16字节的初始化向量(IV),对于使用特定ssv密钥加密的数据类型ssv_seal_plain_tkn4的值的每个实例,该向量必须是不可预测的。

The ssct_hmac field is the result of computing an HMAC using the value of the XDR encoded data type ssv_seal_plain_tkn4 as the input text. The key is the subkey derived from SSV4_SUBKEY_MIC_I2T or SSV4_SUBKEY_MIC_T2I, and the one-way hash algorithm is that negotiated by EXCHANGE_ID.

ssct_hmac字段是使用XDR编码数据类型ssv_seal_plain_tkn4的值作为输入文本计算hmac的结果。密钥是从SSV4\u subkey\u MIC\u I2T或SSV4\u subkey\u MIC\u T2I派生的子密钥,单向散列算法是由EXCHANGE\u ID协商的。

The sspt_confounder field is a random value.

sspt_共聚焦字段是一个随机值。

The sspt_ssv_seq field is the same as ssvt_ssv_seq.

sspt_ssv_seq字段与ssvt_ssv_seq字段相同。

The field sspt_orig_plain field is the original plaintext and is the "input_message" input passed to GSS_Wrap() (see Section 2.3.3 of [7]). As with the handling of the plaintext by the SSV mechanism's GSS_GetMIC() entry point, the entry point for GSS_Wrap() expects a pointer to the plaintext, and will XDR encode an opaque array into sspt_orig_plain representing the plain text, along with the other fields of an instance of data type ssv_seal_plain_tkn4.

字段sspt_orig_plain字段是原始明文,是传递给GSS_Wrap()的“输入消息”输入(见[7]第2.3.3节)。与SSV机制的GSS_GetMIC()入口点对明文的处理一样,GSS_Wrap()的入口点需要一个指向明文的指针,并将XDR编码一个不透明数组到表示明文的sspt_orig_plain,以及数据类型SSV_seal_plain_tkn4实例的其他字段中。

The sspt_pad field is present to support encryption algorithms that require inputs to be in fixed-sized blocks. The content of sspt_pad is zero filled except for the length. Beware that the XDR encoding of ssv_seal_plain_tkn4 contains three variable-length arrays, and so each array consumes four bytes for an array length, and each array that follows the length is always padded to a multiple of four bytes per the XDR standard.

sspt_pad字段用于支持需要输入固定大小块的加密算法。sspt_焊盘的内容为零填充,长度除外。请注意,ssv_seal_plain_tkn4的XDR编码包含三个可变长度数组,因此每个数组的数组长度消耗四个字节,并且根据XDR标准,长度后面的每个数组始终填充为四个字节的倍数。

For example, suppose the encryption algorithm uses 16-byte blocks, and the sspt_confounder is three bytes long, and the sspt_orig_plain field is 15 bytes long. The XDR encoding of sspt_confounder uses eight bytes (4 + 3 + 1 byte pad), the XDR encoding of sspt_ssv_seq uses four bytes, the XDR encoding of sspt_orig_plain uses 20 bytes (4 + 15 + 1 byte pad), and the smallest XDR encoding of the sspt_pad field is four bytes. This totals 36 bytes. The next multiple of 16 is 48; thus, the length field of sspt_pad needs to be set to 12 bytes, or a total encoding of 16 bytes. The total number of XDR encoded bytes is thus 8 + 4 + 20 + 16 = 48.

例如,假设加密算法使用16字节块,sspt_Confour长度为3字节,sspt_orig_plain字段长度为15字节。sspt_Confour的XDR编码使用8个字节(4+3+1字节pad),sspt_ssv_seq的XDR编码使用4个字节,sspt_orig_plain的XDR编码使用20个字节(4+15+1字节pad),sspt_pad字段的最小XDR编码为4个字节。总共36个字节。16的下一个倍数是48;因此,sspt_焊盘的长度字段需要设置为12个字节,或总编码为16个字节。因此,XDR编码字节的总数为8+4+20+16=48。

GSS_Wrap() emits a token that is an XDR encoding of a value of data type ssv_seal_cipher_tkn4. Note that regardless of whether or not the caller of GSS_Wrap() requests confidentiality, the token always has confidentiality. This is because the SSV mechanism is for RPCSEC_GSS, and RPCSEC_GSS never produces GSS_wrap() tokens without confidentiality.

GSS_Wrap()发出一个令牌,该令牌是数据类型为ssv_seal_cipher_tkn4的值的XDR编码。请注意,无论GSS_Wrap()的调用方是否请求机密性,令牌始终具有机密性。这是因为SSV机制是针对RPCSEC_GSS的,并且RPCSEC_GSS从不在没有保密性的情况下生成GSS_wrap()令牌。

There is one SSV per client ID. There is a single GSS context for a client ID / SSV pair. All SSV mechanism RPCSEC_GSS handles of a client ID / SSV pair share the same GSS context. SSV GSS contexts do not expire except when the SSV is destroyed (causes would include the client ID being destroyed or a server restart). Since one purpose of context expiration is to replace keys that have been in use for "too long", hence vulnerable to compromise by brute force or accident, the client can replace the SSV key by sending periodic SET_SSV operations, which is done by cycling through different users' RPCSEC_GSS credentials. This way, the SSV is replaced without destroying the SSV's GSS contexts.

每个客户端ID有一个SSV。客户端ID/SSV对有一个GSS上下文。客户端ID/SSV对的所有SSV机制RPCSEC_GSS句柄共享相同的GSS上下文。SSV GSS上下文不会过期,除非SSV被销毁(原因包括客户端ID被销毁或服务器重新启动)。由于上下文过期的一个目的是替换已使用“太久”的密钥,因此容易受到暴力或事故的破坏,因此客户端可以通过发送定期SET_SSV操作来替换SSV密钥,这是通过循环使用不同用户的RPCSEC_GSS凭据来完成的。这样,在不破坏SSV的GSS上下文的情况下替换SSV。

SSV RPCSEC_GSS handles can be expired or deleted by the server at any time, and the EXCHANGE_ID operation can be used to create more SSV RPCSEC_GSS handles. Expiration of SSV RPCSEC_GSS handles does not imply that the SSV or its GSS context has expired.

服务器可以随时过期或删除SSV RPCSEC_GSS句柄,并且可以使用EXCHANGE_ID操作创建更多SSV RPCSEC_GSS句柄。SSV RPCSEC_GSS句柄的过期并不意味着SSV或其GSS上下文已过期。

The client MUST establish an SSV via SET_SSV before the SSV GSS context can be used to emit tokens from GSS_Wrap() and GSS_GetMIC(). If SET_SSV has not been successfully called, attempts to emit tokens MUST fail.

在SSV GSS上下文可用于从GSS_Wrap()和GSS_GetMIC()发出令牌之前,客户端必须通过SET_SSV建立SSV。如果未成功调用SET_SSV,则发射令牌的尝试必须失败。

The SSV mechanism does not support replay detection and sequencing in its tokens because RPCSEC_GSS does not use those features (See Section 5.2.2, "Context Creation Requests", in [4]). However, Section 2.10.10 discusses special considerations for the SSV mechanism when used with RPCSEC_GSS.

SSV机制不支持其令牌中的重播检测和排序,因为RPCSEC_GSS不使用这些功能(请参阅[4]中的第5.2.2节“上下文创建请求”)。但是,第2.10.10节讨论了与RPCSEC_GSS一起使用时SSV机制的特殊注意事项。

2.10.10. Security Considerations for RPCSEC_GSS When Using the SSV Mechanism

2.10.10. 使用SSV机制时RPCSEC_GSS的安全注意事项

When a client ID is created with SP4_SSV state protection (see Section 18.35), the client is permitted to associate multiple RPCSEC_GSS handles with the single SSV GSS context (see Section 2.10.9). Because of the way RPCSEC_GSS (both version 1 and version 2, see [4] and [12]) calculate the verifier of the reply, special care must be taken by the implementation of the NFSv4.1 client to prevent attacks by a man-in-the-middle. The verifier of an RPCSEC_GSS reply is the output of GSS_GetMIC() applied to the input value of the seq_num field of the RPCSEC_GSS credential (data type rpc_gss_cred_ver_1_t) (see Section 5.3.3.2 of [4]). If multiple RPCSEC_GSS handles share the same GSS context, then if one handle is used to send a request with the same seq_num value as another handle, an attacker could block the reply, and replace it with the verifier used for the other handle.

使用SP4_SSV状态保护创建客户端ID时(参见第18.35节),允许客户端将多个RPCSEC_GSS句柄与单个SSV GSS上下文关联(参见第2.10.9节)。由于RPCSEC_GSS(版本1和版本2,请参见[4]和[12])计算回复验证器的方式,NFSv4.1客户端的实现必须特别小心,以防止中间人的攻击。RPCSEC_GSS回复的验证器是GSS_GetMIC()的输出,应用于RPCSEC_GSS凭证的seq_num字段的输入值(数据类型为rpc_GSS_cred_ver_1_t)(见[4]第5.3.3.2节)。如果多个RPCSEC_GSS句柄共享相同的GSS上下文,则如果一个句柄用于发送与另一个句柄具有相同seq_num值的请求,则攻击者可以阻止回复,并将其替换为用于另一个句柄的验证器。

There are multiple ways to prevent the attack on the SSV RPCSEC_GSS verifier in the reply. The simplest is believed to be as follows.

在回复中,有多种方法可以防止对SSV RPCSEC_GSS验证器的攻击。最简单的被认为是如下。

o Each time one or more new SSV RPCSEC_GSS handles are created via EXCHANGE_ID, the client SHOULD send a SET_SSV operation to modify the SSV. By changing the SSV, the new handles will not result in the re-use of an SSV RPCSEC_GSS verifier in a reply.

o 每次通过EXCHANGE_ID创建一个或多个新SSV RPCSEC_GSS句柄时,客户端应发送一个SET_SSV操作来修改SSV。通过更改SSV,新句柄不会导致在回复中重复使用SSV RPCSEC_GSS验证器。

o When a requester decides to use N SSV RPCSEC_GSS handles, it SHOULD assign a unique and non-overlapping range of seq_nums to each SSV RPCSEC_GSS handle. The size of each range SHOULD be equal to MAXSEQ / N (see Section 5 of [4] for the definition of MAXSEQ). When an SSV RPCSEC_GSS handle reaches its maximum, it SHOULD force the replier to destroy the handle by sending a NULL RPC request with seq_num set to MAXSEQ + 1 (see Section 5.3.3.3 of [4]).

o 当请求者决定使用N个SSV RPCSEC_GSS句柄时,它应该为每个SSV RPCSEC_GSS句柄分配一个唯一且不重叠的序号范围。每个范围的大小应等于MAXSEQ/N(有关MAXSEQ的定义,请参见[4]第5节)。当SSV RPCSEC_GSS句柄达到其最大值时,它应通过发送一个将seq_num设置为MAXSEQ+1的空RPC请求(请参见[4]第5.3.3节),强制应答器销毁该句柄。

o When the requester wants to increase or decrease N, it SHOULD force the replier to destroy all N handles by sending a NULL RPC request on each handle with seq_num set to MAXSEQ + 1. If the requester is the client, it SHOULD send a SET_SSV operation before using new handles. If the requester is the server, then the client SHOULD send a SET_SSV operation when it detects that the server has forced it to destroy a backchannel's SSV RPCSEC_GSS handle. By sending a SET_SSV operation, the SSV will change, and so the attacker will be unavailable to successfully replay a previous verifier in a reply to the requester.

o 当请求者想要增加或减少N时,它应该强制应答器销毁所有N个句柄,方法是在每个句柄上发送一个NULL RPC请求,并将seq_num设置为MAXSEQ+1。如果请求者是客户机,它应该在使用新句柄之前发送SET_SSV操作。如果请求者是服务器,则当客户端检测到服务器已强制其销毁反向通道的SSV RPCSEC_GSS句柄时,应发送一个SET_SSV操作。通过发送SET_SSV操作,SSV将发生更改,因此攻击者将无法在回复请求者时成功重播以前的验证器。

Note that if the replier carefully creates the SSV RPCSEC_GSS handles, the related risk of a man-in-the-middle splicing a forged SSV RPCSEC_GSS credential with a verifier for another handle does not exist. This is because the verifier in an RPCSEC_GSS request is computed from input that includes both the RPCSEC_GSS handle and seq_num (see Section 5.3.1 of [4]). Provided the replier takes care to avoid re-using the value of an RPCSEC_GSS handle that it creates, such as by including a generation number in the handle, the man-in-the-middle will not be able to successfully replay a previous verifier in the request to a replier.

请注意,如果应答者小心创建SSV RPCSEC_GSS句柄,则中间人将伪造SSV RPCSEC_GSS凭证与另一个句柄的验证器拼接的相关风险不存在。这是因为RPCSEC_GSS请求中的验证器是根据包含RPCSEC_GSS句柄和seq_num的输入计算的(见[4]第5.3.1节)。如果应答器注意避免重复使用它创建的RPCSEC_GSS句柄的值,例如通过在句柄中包含一个生成号,则中间人将无法成功地将请求中的前一个验证器重播给应答器。

2.10.11. Session Mechanics - Steady State
2.10.11. 会话力学-稳态
2.10.11.1. Obligations of the Server
2.10.11.1. 服务器的义务

The server has the primary obligation to monitor the state of backchannel resources that the client has created for the server (RPCSEC_GSS contexts and backchannel connections). If these resources vanish, the server takes action as specified in Section 2.10.13.2.

服务器的主要职责是监视客户端为服务器创建的反向通道资源的状态(RPCSEC_GSS上下文和反向通道连接)。如果这些资源消失,服务器将按照第2.10.13.2节的规定采取行动。

2.10.11.2. Obligations of the Client
2.10.11.2. 客户的义务

The client SHOULD honor the following obligations in order to utilize the session:

客户应履行以下义务,以利用本次会议:

o Keep a necessary session from going idle on the server. A client that requires a session but nonetheless is not sending operations risks having the session be destroyed by the server. This is because sessions consume resources, and resource limitations may force the server to cull an inactive session. A server MAY consider a session to be inactive if the client has not used the session before the session inactivity timer (Section 2.10.12) has expired.

o 保持必要的会话在服务器上不空闲。需要会话但不发送操作的客户端有可能被服务器破坏会话。这是因为会话消耗资源,而资源限制可能会迫使服务器剔除非活动会话。如果客户端在会话不活动计时器(第2.1.12节)过期之前未使用会话,则服务器可以考虑会话不活动。

o Destroy the session when not needed. If a client has multiple sessions, one of which has no requests waiting for replies, and has been idle for some period of time, it SHOULD destroy the session.

o 在不需要时销毁会话。如果一个客户端有多个会话,其中一个会话没有等待答复的请求,并且已经空闲了一段时间,那么它应该销毁该会话。

o Maintain GSS contexts and RPCSEC_GSS handles for the backchannel. If the client requires the server to use the RPCSEC_GSS security flavor for callbacks, then it needs to be sure the RPCSEC_GSS handles and/or their GSS contexts that are handed to the server via BACKCHANNEL_CTL or CREATE_SESSION are unexpired.

o 维护反向通道的GSS上下文和RPCSEC_GSS句柄。如果客户端要求服务器使用RPCSEC_GSS安全风格进行回调,则需要确保RPCSEC_GSS处理和/或其通过BACKCHANNEL_CTL或CREATE_会话传递给服务器的GSS上下文未过期。

o Preserve a connection for a backchannel. The server requires a backchannel in order to gracefully recall recallable state or notify the client of certain events. Note that if the connection is not being used for the fore channel, there is no way for the client to tell if the connection is still alive (e.g., the server restarted without sending a disconnect). The onus is on the server, not the client, to determine if the backchannel's connection is alive, and to indicate in the response to a SEQUENCE operation when the last connection associated with a session's backchannel has disconnected.

o 保留反向通道的连接。服务器需要一个反向通道,以便正常地调用可重调状态或将某些事件通知客户端。请注意,如果前通道未使用该连接,则客户端无法判断该连接是否仍处于活动状态(例如,服务器在不发送断开连接的情况下重新启动)。ONU在服务器上,而不是在客户端上,以确定反向通道的连接是否处于活动状态,并在对序列操作的响应中指示与会话反向通道关联的最后一个连接何时断开。

2.10.11.3. Steps the Client Takes to Establish a Session
2.10.11.3. 客户端建立会话所采取的步骤

If the client does not have a client ID, the client sends EXCHANGE_ID to establish a client ID. If it opts for SP4_MACH_CRED or SP4_SSV protection, in the spo_must_enforce list of operations, it SHOULD at minimum specify CREATE_SESSION, DESTROY_SESSION, BIND_CONN_TO_SESSION, BACKCHANNEL_CTL, and DESTROY_CLIENTID. If it opts for SP4_SSV protection, the client needs to ask for SSV-based RPCSEC_GSS handles.

如果客户端没有客户端ID,客户端将发送EXCHANGE\u ID以建立客户端ID。如果选择SP4\u MACH\u CRED或SP4\u SSV保护,则在spo\u必须\u enforce操作列表中,客户端至少应指定创建\u会话、销毁\u会话、将\u CONN\u绑定到\u会话、反向通道\u CTL和销毁\u CLIENTID。如果选择SP4_SSV保护,客户端需要请求基于SSV的RPCSEC_GSS句柄。

The client uses the client ID to send a CREATE_SESSION on a connection to the server. The results of CREATE_SESSION indicate whether or not the server will persist the session reply cache through a server that has restarted, and the client notes this for future reference.

客户端使用客户端ID在连接上向服务器发送CREATE_会话。CREATE_SESSION的结果指示服务器是否将通过已重新启动的服务器持久化会话应答缓存,并且客户端会记录这一点以供将来参考。

If the client specified SP4_SSV state protection when the client ID was created, then it SHOULD send SET_SSV in the first COMPOUND after the session is created. Each time a new principal goes to use the client ID, it SHOULD send a SET_SSV again.

如果客户端在创建客户端ID时指定了SP4_SSV状态保护,那么它应该在创建会话后在第一个复合中发送SET_SSV。每次新主体使用客户机ID时,它都应该再次发送一个SET_SSV。

If the client wants to use delegations, layouts, directory notifications, or any other state that requires a backchannel, then it needs to add a connection to the backchannel if CREATE_SESSION did not already do so. The client creates a connection, and calls BIND_CONN_TO_SESSION to associate the connection with the session and the session's backchannel. If CREATE_SESSION did not already do so, the client MUST tell the server what security is required in order for the client to accept callbacks. The client does this via BACKCHANNEL_CTL. If the client selected SP4_MACH_CRED or SP4_SSV protection when it called EXCHANGE_ID, then the client SHOULD specify that the backchannel use RPCSEC_GSS contexts for security.

如果客户端希望使用委托、布局、目录通知或任何其他需要反向通道的状态,那么如果CREATE_会话尚未添加到反向通道的连接,则需要添加到反向通道的连接。客户端创建一个连接,并调用BIND_CONN_TO_SESSION将连接与会话和会话的反向通道相关联。如果CREATE_会话尚未执行此操作,则客户端必须告诉服务器需要什么样的安全性,以便客户端接受回调。客户端通过反向通道执行此操作。如果客户端在调用EXCHANGE_ID时选择了SP4_MACH_CRED或SP4_SSV保护,则客户端应指定反向通道使用RPCSEC_GSS上下文进行安全保护。

If the client wants to use additional connections for the backchannel, then it needs to call BIND_CONN_TO_SESSION on each connection it wants to use with the session. If the client wants to use additional connections for the fore channel, then it needs to call BIND_CONN_TO_SESSION if it specified SP4_SSV or SP4_MACH_CRED state protection when the client ID was created.

如果客户机希望为反向通道使用其他连接,则需要在要与会话一起使用的每个连接上调用BIND_CONN_to_SESSION。如果客户端希望为前通道使用其他连接,则需要调用BIND_CONN_to_SESSION(如果在创建客户端ID时指定了SP4_SSV或SP4_MACH_CRED状态保护)。

At this point, the session has reached steady state.

此时,会话已达到稳定状态。

2.10.12. Session Inactivity Timer
2.10.12. 会话不活动计时器

The server MAY maintain a session inactivity timer for each session. If the session inactivity timer expires, then the server MAY destroy the session. To avoid losing a session due to inactivity, the client MUST renew the session inactivity timer. The length of session inactivity timer MUST NOT be less than the lease_time attribute (Section 5.8.1.11). As with lease renewal (Section 8.3), when the server receives a SEQUENCE operation, it resets the session inactivity timer, and MUST NOT allow the timer to expire while the rest of the operations in the COMPOUND procedure's request are still executing. Once the last operation has finished, the server MUST set the session inactivity timer to expire no sooner than the sum of the current time and the value of the lease_time attribute.

服务器可以为每个会话维护会话非活动计时器。如果会话非活动计时器过期,则服务器可能会销毁会话。为了避免由于不活动而丢失会话,客户端必须续订会话不活动计时器。会话非活动计时器的长度不得小于租约时间属性(第5.8.1.11节)。与租约续订(第8.3节)一样,当服务器接收到序列操作时,它会重置会话非活动计时器,并且不得允许计时器在复合过程请求中的其余操作仍在执行时过期。完成最后一个操作后,服务器必须将会话非活动计时器设置为在当前时间和lease_time属性值之和之前过期。

2.10.13. Session Mechanics - Recovery
2.10.13. 会话机制-恢复
2.10.13.1. Events Requiring Client Action
2.10.13.1. 需要客户端操作的事件

The following events require client action to recover.

以下事件需要客户端操作才能恢复。

2.10.13.1.1. RPCSEC_GSS Context Loss by Callback Path
2.10.13.1.1. RPCSEC_GSS通过回调路径丢失上下文

If all RPCSEC_GSS handles granted by the client to the server for callback use have expired, the client MUST establish a new handle via BACKCHANNEL_CTL. The sr_status_flags field of the SEQUENCE results indicates when callback handles are nearly expired, or fully expired (see Section 18.46.3).

如果客户端授予服务器以供回调使用的所有RPCSEC_GSS句柄已过期,则客户端必须通过BACKCHANNEL_CTL建立新句柄。序列结果的sr_status_flags字段指示回调句柄接近到期或完全到期的时间(参见第18.46.3节)。

2.10.13.1.2. Connection Loss
2.10.13.1.2. 连接损耗

If the client loses the last connection of the session and wants to retain the session, then it needs to create a new connection, and if, when the client ID was created, BIND_CONN_TO_SESSION was specified in the spo_must_enforce list, the client MUST use BIND_CONN_TO_SESSION to associate the connection with the session.

如果客户端丢失会话的最后一个连接并希望保留会话,则需要创建新连接,并且如果在创建客户端ID时,在spo_必须_强制列表中指定了BIND_CONN_to_session,则客户端必须使用BIND_CONN_to_session将连接与会话关联。

If there was a request outstanding at the time of connection loss, then if the client wants to continue to use the session, it MUST retry the request, as described in Section 2.10.6.2. Note that it is not necessary to retry requests over a connection with the same source network address or the same destination network address as the lost connection. As long as the session ID, slot ID, and sequence ID in the retry match that of the original request, the server will recognize the request as a retry if it executed the request prior to disconnect.

如果在连接丢失时有未完成的请求,则如果客户端希望继续使用会话,则必须重试该请求,如第2.10.6.2节所述。请注意,不必通过与丢失的连接具有相同源网络地址或相同目标网络地址的连接重试请求。只要重试中的会话ID、插槽ID和序列ID与原始请求的会话ID、插槽ID和序列ID匹配,服务器将在断开连接之前执行请求时将该请求识别为重试。

If the connection that was lost was the last one associated with the backchannel, and the client wants to retain the backchannel and/or prevent revocation of recallable state, the client needs to reconnect, and if it does, it MUST associate the connection to the session and backchannel via BIND_CONN_TO_SESSION. The server SHOULD indicate when it has no callback connection via the sr_status_flags result from SEQUENCE.

如果丢失的连接是与反向通道关联的最后一个连接,并且客户端希望保留反向通道和/或防止可撤销状态的撤销,则客户端需要重新连接,如果重新连接,则必须通过BIND_CONN_to_session将连接与会话和反向通道关联。服务器应该通过序列的sr_status_标志指示何时没有回调连接。

2.10.13.1.3. Backchannel GSS Context Loss
2.10.13.1.3. 反向通道GSS上下文丢失

Via the sr_status_flags result of the SEQUENCE operation or other means, the client will learn if some or all of the RPCSEC_GSS contexts it assigned to the backchannel have been lost. If the client wants to retain the backchannel and/or not put recallable state subject to revocation, the client needs to use BACKCHANNEL_CTL to assign new contexts.

通过序列操作的sr_status_flags结果或其他方式,客户机将了解其分配给反向通道的部分或全部RPCSEC_GSS上下文是否已丢失。如果客户端希望保留反向通道和/或不将可撤销状态置于吊销状态,则客户端需要使用反向通道\u CTL来分配新上下文。

2.10.13.1.4. Loss of Session
2.10.13.1.4. 会话中断

The replier might lose a record of the session. Causes include:

应答器可能会丢失会话的记录。原因包括:

o Replier failure and restart.

o 应答器故障并重新启动。

o A catastrophe that causes the reply cache to be corrupted or lost on the media on which it was stored. This applies even if the replier indicated in the CREATE_SESSION results that it would persist the cache.

o 导致应答缓存在存储介质上损坏或丢失的灾难。即使CREATE_会话中指示的应答器将持久化缓存,这也适用。

o The server purges the session of a client that has been inactive for a very extended period of time.

o 服务器将清除已停用很长时间的客户端会话。

o As a result of configuration changes among a set of clustered servers, a network address previously connected to one server becomes connected to a different server that has no knowledge of the session in question. Such a configuration change will generally only happen when the original server ceases to function for a time.

o 由于一组群集服务器之间的配置更改,以前连接到一台服务器的网络地址将连接到不知道所讨论会话的另一台服务器。这种配置更改通常仅在原始服务器停止运行一段时间后才会发生。

Loss of reply cache is equivalent to loss of session. The replier indicates loss of session to the requester by returning NFS4ERR_BADSESSION on the next operation that uses the session ID that refers to the lost session.

回复缓存的丢失相当于会话的丢失。应答器通过在使用引用丢失会话的会话ID的下一个操作上返回NFS4ERR_BADSESSION,向请求者指示会话丢失。

After an event like a server restart, the client may have lost its connections. The client assumes for the moment that the session has not been lost. It reconnects, and if it specified connection association enforcement when the session was created, it invokes BIND_CONN_TO_SESSION using the session ID. Otherwise, it invokes SEQUENCE. If BIND_CONN_TO_SESSION or SEQUENCE returns NFS4ERR_BADSESSION, the client knows the session is not available to it when communicating with that network address. If the connection survives session loss, then the next SEQUENCE operation the client sends over the connection will get back NFS4ERR_BADSESSION. The client again knows the session was lost.

在服务器重启等事件之后,客户端可能已失去连接。客户端暂时假定会话没有丢失。它会重新连接,如果它在创建会话时指定了连接关联强制,它会使用会话ID调用BIND_CONN_TO_会话。否则,它会调用SEQUENCE。如果BIND_CONN_TO_SESSION或SEQUENCE返回NFS4ERR_BADSESSION,则客户端在与该网络地址通信时知道该会话不可用。如果连接在会话丢失后仍然存在,那么客户端通过连接发送的下一个序列操作将返回NFS4ERR_BADSESSION。客户端再次知道会话已丢失。

Here is one suggested algorithm for the client when it gets NFS4ERR_BADSESSION. It is not obligatory in that, if a client does not want to take advantage of such features as trunking, it may omit parts of it. However, it is a useful example that draws attention to various possible recovery issues:

下面是一个建议的算法,用于客户端获取NFS4ERR_BADSESSION时使用。这不是强制性的,因为如果客户机不想利用中继等功能,它可能会省略其中的一部分。但是,这是一个有用的示例,它提请注意各种可能的恢复问题:

1. If the client has other connections to other server network addresses associated with the same session, attempt a COMPOUND with a single operation, SEQUENCE, on each of the other connections.

1. 如果客户端与与同一会话关联的其他服务器网络地址有其他连接,请在每个其他连接上尝试使用单一操作SEQUENCE进行复合。

2. If the attempts succeed, the session is still alive, and this is a strong indicator that the server's network address has moved. The client might send an EXCHANGE_ID on the connection that returned NFS4ERR_BADSESSION to see if there are opportunities for client ID trunking (i.e., the same client ID and so_major are returned). The client might use DNS to see if the moved network address was replaced with another, so that the performance and availability benefits of session trunking can continue.

2. 如果尝试成功,则会话仍处于活动状态,这是服务器网络地址已移动的有力指示器。客户端可能会在返回NFS4ERR_BADSESSION的连接上发送EXCHANGE_ID,以查看是否有机会进行客户端ID中继(即,返回相同的客户端ID和so_major)。客户端可能会使用DNS来查看移动的网络地址是否被另一个网络地址替换,以便会话中继的性能和可用性优势能够继续。

3. If the SEQUENCE requests fail with NFS4ERR_BADSESSION, then the session no longer exists on any of the server network addresses for which the client has connections associated with that session ID. It is possible the session is still alive and available on other network addresses. The client sends an EXCHANGE_ID on all the connections to see if the server owner is still listening on those network addresses. If the same server owner is returned but a new client ID is returned, this is a strong indicator of a server restart. If both the same server owner and same client ID are returned, then this is a strong indication that the server did delete the session, and the client will need to send a CREATE_SESSION if it has no other sessions for that client ID. If a different server owner is returned, the client can use DNS to find other network addresses. If it does not, or if DNS does not find any other addresses for the server, then the client will be unable to provide NFSv4.1 service, and fatal errors should be returned to processes that were using the server. If the client is using a "mount" paradigm, unmounting the server is advised.

3. 如果序列请求因NFS4ERR_BADSESSION而失败,则该会话将不再存在于客户端与该会话ID关联的任何服务器网络地址上。该会话可能仍处于活动状态,并且在其他网络地址上可用。客户端在所有连接上发送一个EXCHANGE_ID,以查看服务器所有者是否仍在侦听这些网络地址。如果返回了相同的服务器所有者,但返回了新的客户机ID,则这是服务器重新启动的强烈指示。如果返回了相同的服务器所有者和相同的客户端ID,则这强烈表明服务器确实删除了会话,并且如果客户端ID没有其他会话,则客户端需要发送创建会话。如果返回了不同的服务器所有者,则客户端可以使用DNS查找其他网络地址。如果没有,或者DNS没有找到服务器的任何其他地址,则客户端将无法提供NFSv4.1服务,并且应将致命错误返回到使用服务器的进程。如果客户机使用的是“装载”范例,则建议卸载服务器。

4. If the client knows of no other connections associated with the session ID and server network addresses that are, or have been, associated with the session ID, then the client can use DNS to find other network addresses. If it does not, or if DNS does not find any other addresses for the server, then the client will be unable to provide NFSv4.1 service, and fatal errors should be returned to processes that were using the server. If the client is using a "mount" paradigm, unmounting the server is advised.

4. 如果客户端不知道与会话ID关联的其他连接以及与会话ID关联的或已经关联的服务器网络地址,则客户端可以使用DNS查找其他网络地址。如果没有,或者DNS没有找到服务器的任何其他地址,则客户端将无法提供NFSv4.1服务,并且应将致命错误返回到使用服务器的进程。如果客户机使用的是“装载”范例,则建议卸载服务器。

If there is a reconfiguration event that results in the same network address being assigned to servers where the eir_server_scope value is different, it cannot be guaranteed that a session ID generated by the first will be recognized as invalid by the first. Therefore, in managing server reconfigurations among servers with different server scope values, it is necessary to make sure that all clients have disconnected from the first server before effecting the reconfiguration. Nonetheless, clients should not assume that servers will always adhere to this requirement; clients MUST be prepared to deal with unexpected effects of server reconfigurations. Even where a session ID is inappropriately recognized as valid, it is likely

如果重新配置事件导致将相同的网络地址分配给eir_server_作用域值不同的服务器,则无法保证第一个服务器生成的会话ID将被第一个服务器识别为无效。因此,在管理具有不同服务器作用域值的服务器之间的服务器重新配置时,必须确保所有客户端在进行重新配置之前已断开与第一台服务器的连接。尽管如此,客户机不应该认为服务器将始终遵守此要求;客户端必须准备好处理服务器重新配置的意外影响。即使会话ID被不适当地识别为有效,也很可能

either that the connection will not be recognized as valid or that a sequence value for a slot will not be correct. Therefore, when a client receives results indicating such unexpected errors, the use of EXCHANGE_ID to determine the current server configuration is RECOMMENDED.

连接将无法识别为有效连接,或者插槽的序列值将不正确。因此,当客户端收到指示此类意外错误的结果时,建议使用EXCHANGE_ID确定当前服务器配置。

A variation on the above is that after a server's network address moves, there is no NFSv4.1 server listening, e.g., no listener on port 2049. In this example, one of the following occur: the NFSv4 server returns NFS4ERR_MINOR_VERS_MISMATCH, the NFS server returns a PROG_MISMATCH error, the RPC listener on 2049 returns PROG_UNVAIL, or attempts to reconnect to the network address timeout. These SHOULD be treated as equivalent to SEQUENCE returning NFS4ERR_BADSESSION for these purposes.

上面的一个变体是,在服务器的网络地址移动后,没有NFSv4.1服务器侦听,例如,端口2049上没有侦听器。在此示例中,会发生以下情况之一:NFSv4服务器返回NFS4ERR_MINOR_VERS_MISMATCH,NFS服务器返回PROG_MISMATCH错误,2049上的RPC侦听器返回PROG_UNVAIL,或尝试重新连接到网络地址超时。出于这些目的,应将其视为等同于序列返回NFS4ERR_BADSESSION。

When the client detects session loss, it needs to call CREATE_SESSION to recover. Any non-idempotent operations that were in progress might have been performed on the server at the time of session loss. The client has no general way to recover from this.

当客户端检测到会话丢失时,需要调用CREATE_session进行恢复。任何正在进行的非幂等操作都可能在会话丢失时在服务器上执行。客户端没有从中恢复的常规方法。

Note that loss of session does not imply loss of byte-range lock, open, delegation, or layout state because locks, opens, delegations, and layouts are tied to the client ID and depend on the client ID, not the session. Nor does loss of byte-range lock, open, delegation, or layout state imply loss of session state, because the session depends on the client ID; loss of client ID however does imply loss of session, byte-range lock, open, delegation, and layout state. See Section 8.4.2. A session can survive a server restart, but lock recovery may still be needed.

请注意,丢失会话并不意味着丢失字节范围锁定、打开、委派或布局状态,因为锁定、打开、委派和布局与客户端ID有关,并且取决于客户端ID,而不是会话。字节范围锁定、打开、委派或布局状态的丢失也不意味着会话状态的丢失,因为会话取决于客户端ID;然而,丢失客户端ID并不意味着丢失会话、字节范围锁、打开、委托和布局状态。见第8.4.2节。会话可以在服务器重新启动后继续运行,但仍可能需要锁恢复。

It is possible that CREATE_SESSION will fail with NFS4ERR_STALE_CLIENTID (e.g., the server restarts and does not preserve client ID state). If so, the client needs to call EXCHANGE_ID, followed by CREATE_SESSION.

CREATE_会话可能会因NFS4ERR_STALE_CLIENTID而失败(例如,服务器重新启动,不保留客户端ID状态)。如果是这样,客户端需要调用EXCHANGE\u ID,然后调用CREATE\u会话。

2.10.13.2. Events Requiring Server Action
2.10.13.2. 需要服务器操作的事件

The following events require server action to recover.

以下事件需要服务器操作才能恢复。

2.10.13.2.1. Client Crash and Restart
2.10.13.2.1. 客户端崩溃和重新启动

As described in Section 18.35, a restarted client sends EXCHANGE_ID in such a way that it causes the server to delete any sessions it had.

如第18.35节所述,重新启动的客户端发送EXCHANGE_ID的方式会导致服务器删除其拥有的任何会话。

2.10.13.2.2. Client Crash with No Restart
2.10.13.2.2. 客户端崩溃,无需重新启动

If a client crashes and never comes back, it will never send EXCHANGE_ID with its old client owner. Thus, the server has session state that will never be used again. After an extended period of time, and if the server has resource constraints, it MAY destroy the old session as well as locking state.

如果客户机崩溃并且再也没有回来,它将永远不会向其旧客户机所有者发送EXCHANGE\u ID。因此,服务器的会话状态将不再使用。经过一段较长的时间后,如果服务器有资源限制,它可能会破坏旧会话以及锁定状态。

2.10.13.2.3. Extended Network Partition
2.10.13.2.3. 扩展网络分区

To the server, the extended network partition may be no different from a client crash with no restart (see Section 2.10.13.2.2). Unless the server can discern that there is a network partition, it is free to treat the situation as if the client has crashed permanently.

对于服务器而言,扩展网络分区可能与无需重新启动的客户端崩溃无异(请参阅第2.10.13.2.2节)。除非服务器能够识别出存在网络分区,否则它可以自由地将这种情况视为客户端永久崩溃。

2.10.13.2.4. Backchannel Connection Loss
2.10.13.2.4. 反向通道连接损耗

If there were callback requests outstanding at the time of a connection loss, then the server MUST retry the requests, as described in Section 2.10.6.2. Note that it is not necessary to retry requests over a connection with the same source network address or the same destination network address as the lost connection. As long as the session ID, slot ID, and sequence ID in the retry match that of the original request, the callback target will recognize the request as a retry even if it did see the request prior to disconnect.

如果在连接丢失时有未完成的回调请求,则服务器必须重试这些请求,如第2.10.6.2节所述。请注意,不必通过与丢失的连接具有相同源网络地址或相同目标网络地址的连接重试请求。只要重试中的会话ID、插槽ID和序列ID与原始请求的会话ID、插槽ID和序列ID匹配,回调目标就会将该请求识别为重试,即使它在断开连接之前确实看到了该请求。

If the connection lost is the last one associated with the backchannel, then the server MUST indicate that in the sr_status_flags field of every SEQUENCE reply until the backchannel is re-established. There are two situations, each of which uses different status flags: no connectivity for the session's backchannel and no connectivity for any session backchannel of the client. See Section 18.46 for a description of the appropriate flags in sr_status_flags.

如果连接丢失是与反向通道关联的最后一个连接,则服务器必须在每个序列应答的sr_status_flags字段中指示,直到反向通道重新建立。有两种情况,每种情况都使用不同的状态标志:会话的反向通道没有连接,客户端的任何会话反向通道都没有连接。有关sr_状态_标志中相应标志的说明,请参见第18.46节。

2.10.13.2.5. GSS Context Loss
2.10.13.2.5. GSS上下文丢失

The server SHOULD monitor when the number of RPCSEC_GSS handles assigned to the backchannel reaches one, and when that one handle is near expiry (i.e., between one and two periods of lease time), and indicate so in the sr_status_flags field of all SEQUENCE replies. The server MUST indicate when all of the backchannel's assigned RPCSEC_GSS handles have expired via the sr_status_flags field of all SEQUENCE replies.

服务器应监控分配给反向通道的RPCSEC_GSS句柄数何时达到一个,以及该句柄何时接近到期(即,在一到两个租赁时间段之间),并在所有序列应答的sr_status_flags字段中指示。服务器必须通过所有序列应答的sr_status_flags字段指示所有分配的反向通道RPCSEC_GSS句柄何时过期。

2.10.14. Parallel NFS and Sessions
2.10.14. 并行NFS和会话

A client and server can potentially be a non-pNFS implementation, a metadata server implementation, a data server implementation, or two or three types of implementations. The EXCHGID4_FLAG_USE_NON_PNFS, EXCHGID4_FLAG_USE_PNFS_MDS, and EXCHGID4_FLAG_USE_PNFS_DS flags (not mutually exclusive) are passed in the EXCHANGE_ID arguments and results to allow the client to indicate how it wants to use sessions created under the client ID, and to allow the server to indicate how it will allow the sessions to be used. See Section 13.1 for pNFS sessions considerations.

客户机和服务器可能是非pNFS实现、元数据服务器实现、数据服务器实现或两种或三种类型的实现。EXCHGID4_标志_USE_NON_PNFS、EXCHGID4_标志_USE_PNFS_MDS和EXCHGID4_标志_USE_PNFS_DS标志(不互斥)在EXCHANGE_ID参数和结果中传递,以允许客户端指示如何使用在客户端ID下创建的会话,并允许服务器指示如何使用会话。有关pNFS会话注意事项,请参见第13.1节。

3. Protocol Constants and Data Types
3. 协议常数和数据类型

The syntax and semantics to describe the data types of the NFSv4.1 protocol are defined in the XDR RFC 4506 [2] and RPC RFC 5531 [3] documents. The next sections build upon the XDR data types to define constants, types, and structures specific to this protocol. The full list of XDR data types is in [13].

XDR RFC 4506[2]和RPC RFC 5531[3]文档中定义了用于描述NFSv4.1协议数据类型的语法和语义。下一节将基于XDR数据类型来定义特定于此协议的常量、类型和结构。XDR数据类型的完整列表见[13]。

3.1. Basic Constants
3.1. 基本常数
   const NFS4_FHSIZE               = 128;
   const NFS4_VERIFIER_SIZE        = 8;
   const NFS4_OPAQUE_LIMIT         = 1024;
   const NFS4_SESSIONID_SIZE       = 16;
        
   const NFS4_FHSIZE               = 128;
   const NFS4_VERIFIER_SIZE        = 8;
   const NFS4_OPAQUE_LIMIT         = 1024;
   const NFS4_SESSIONID_SIZE       = 16;
        
   const NFS4_INT64_MAX            = 0x7fffffffffffffff;
   const NFS4_UINT64_MAX           = 0xffffffffffffffff;
   const NFS4_INT32_MAX            = 0x7fffffff;
   const NFS4_UINT32_MAX           = 0xffffffff;
        
   const NFS4_INT64_MAX            = 0x7fffffffffffffff;
   const NFS4_UINT64_MAX           = 0xffffffffffffffff;
   const NFS4_INT32_MAX            = 0x7fffffff;
   const NFS4_UINT32_MAX           = 0xffffffff;
        
   const NFS4_MAXFILELEN           = 0xffffffffffffffff;
   const NFS4_MAXFILEOFF           = 0xfffffffffffffffe;
        
   const NFS4_MAXFILELEN           = 0xffffffffffffffff;
   const NFS4_MAXFILEOFF           = 0xfffffffffffffffe;
        

Except where noted, all these constants are defined in bytes.

除非另有说明,所有这些常量都是以字节定义的。

o NFS4_FHSIZE is the maximum size of a filehandle.

o NFS4_FHSIZE是文件句柄的最大大小。

o NFS4_VERIFIER_SIZE is the fixed size of a verifier.

o NFS4\u验证器\u大小是验证器的固定大小。

o NFS4_OPAQUE_LIMIT is the maximum size of certain opaque information.

o NFS4_不透明限制是某些不透明信息的最大大小。

o NFS4_SESSIONID_SIZE is the fixed size of a session identifier.

o NFS4_SESSIONID_SIZE是会话标识符的固定大小。

o NFS4_INT64_MAX is the maximum value of a signed 64-bit integer.

o NFS4_INT64_MAX是有符号64位整数的最大值。

o NFS4_UINT64_MAX is the maximum value of an unsigned 64-bit integer.

o NFS4_UINT64_MAX是无符号64位整数的最大值。

o NFS4_INT32_MAX is the maximum value of a signed 32-bit integer.

o NFS4_INT32_MAX是有符号32位整数的最大值。

o NFS4_UINT32_MAX is the maximum value of an unsigned 32-bit integer.

o NFS4_UINT32_MAX是无符号32位整数的最大值。

o NFS4_MAXFILELEN is the maximum length of a regular file.

o NFS4_MAXFILELEN是常规文件的最大长度。

o NFS4_MAXFILEOFF is the maximum offset into a regular file.

o NFS4_MAXFILEOFF是常规文件的最大偏移量。

3.2. Basic Data Types
3.2. 基本数据类型

These are the base NFSv4.1 data types.

这些是基本的NFSv4.1数据类型。

   +---------------+---------------------------------------------------+
   | Data Type     | Definition                                        |
   +---------------+---------------------------------------------------+
   | int32_t       | typedef int int32_t;                              |
   | uint32_t      | typedef unsigned int uint32_t;                    |
   | int64_t       | typedef hyper int64_t;                            |
   | uint64_t      | typedef unsigned hyper uint64_t;                  |
   | attrlist4     | typedef opaque attrlist4<>;                       |
   |               | Used for file/directory attributes.               |
   | bitmap4       | typedef uint32_t bitmap4<>;                       |
   |               | Used in attribute array encoding.                 |
   | changeid4     | typedef uint64_t changeid4;                       |
   |               | Used in the definition of change_info4.           |
   | clientid4     | typedef uint64_t clientid4;                       |
   |               | Shorthand reference to client identification.     |
   | count4        | typedef uint32_t count4;                          |
   |               | Various count parameters (READ, WRITE, COMMIT).   |
   | length4       | typedef uint64_t length4;                         |
   |               | The length of a byte-range within a file.         |
   | mode4         | typedef uint32_t mode4;                           |
   |               | Mode attribute data type.                         |
   | nfs_cookie4   | typedef uint64_t nfs_cookie4;                     |
   |               | Opaque cookie value for READDIR.                  |
   | nfs_fh4       | typedef opaque nfs_fh4<NFS4_FHSIZE>;              |
   |               | Filehandle definition.                            |
   | nfs_ftype4    | enum nfs_ftype4;                                  |
   |               | Various defined file types.                       |
   | nfsstat4      | enum nfsstat4;                                    |
   |               | Return value for operations.                      |
   | offset4       | typedef uint64_t offset4;                         |
   |               | Various offset designations (READ, WRITE, LOCK,   |
   |               | COMMIT).                                          |
        
   +---------------+---------------------------------------------------+
   | Data Type     | Definition                                        |
   +---------------+---------------------------------------------------+
   | int32_t       | typedef int int32_t;                              |
   | uint32_t      | typedef unsigned int uint32_t;                    |
   | int64_t       | typedef hyper int64_t;                            |
   | uint64_t      | typedef unsigned hyper uint64_t;                  |
   | attrlist4     | typedef opaque attrlist4<>;                       |
   |               | Used for file/directory attributes.               |
   | bitmap4       | typedef uint32_t bitmap4<>;                       |
   |               | Used in attribute array encoding.                 |
   | changeid4     | typedef uint64_t changeid4;                       |
   |               | Used in the definition of change_info4.           |
   | clientid4     | typedef uint64_t clientid4;                       |
   |               | Shorthand reference to client identification.     |
   | count4        | typedef uint32_t count4;                          |
   |               | Various count parameters (READ, WRITE, COMMIT).   |
   | length4       | typedef uint64_t length4;                         |
   |               | The length of a byte-range within a file.         |
   | mode4         | typedef uint32_t mode4;                           |
   |               | Mode attribute data type.                         |
   | nfs_cookie4   | typedef uint64_t nfs_cookie4;                     |
   |               | Opaque cookie value for READDIR.                  |
   | nfs_fh4       | typedef opaque nfs_fh4<NFS4_FHSIZE>;              |
   |               | Filehandle definition.                            |
   | nfs_ftype4    | enum nfs_ftype4;                                  |
   |               | Various defined file types.                       |
   | nfsstat4      | enum nfsstat4;                                    |
   |               | Return value for operations.                      |
   | offset4       | typedef uint64_t offset4;                         |
   |               | Various offset designations (READ, WRITE, LOCK,   |
   |               | COMMIT).                                          |
        
   | qop4          | typedef uint32_t qop4;                            |
   |               | Quality of protection designation in SECINFO.     |
   | sec_oid4      | typedef opaque sec_oid4<>;                        |
   |               | Security Object Identifier.  The sec_oid4 data    |
   |               | type is not really opaque.  Instead, it contains  |
   |               | an ASN.1 OBJECT IDENTIFIER as used by GSS-API in  |
   |               | the mech_type argument to GSS_Init_sec_context.   |
   |               | See [7] for details.                              |
   | sequenceid4   | typedef uint32_t sequenceid4;                     |
   |               | Sequence number used for various session          |
   |               | operations (EXCHANGE_ID, CREATE_SESSION,          |
   |               | SEQUENCE, CB_SEQUENCE).                           |
   | seqid4        | typedef uint32_t seqid4;                          |
   |               | Sequence identifier used for locking.             |
   | sessionid4    | typedef opaque sessionid4[NFS4_SESSIONID_SIZE];   |
   |               | Session identifier.                               |
   | slotid4       | typedef uint32_t slotid4;                         |
   |               | Sequencing artifact for various session           |
   |               | operations (SEQUENCE, CB_SEQUENCE).               |
   | utf8string    | typedef opaque utf8string<>;                      |
   |               | UTF-8 encoding for strings.                       |
   | utf8str_cis   | typedef utf8string utf8str_cis;                   |
   |               | Case-insensitive UTF-8 string.                    |
   | utf8str_cs    | typedef utf8string utf8str_cs;                    |
   |               | Case-sensitive UTF-8 string.                      |
   | utf8str_mixed | typedef utf8string utf8str_mixed;                 |
   |               | UTF-8 strings with a case-sensitive prefix and a  |
   |               | case-insensitive suffix.                          |
   | component4    | typedef utf8str_cs component4;                    |
   |               | Represents pathname components.                   |
   | linktext4     | typedef utf8str_cs linktext4;                     |
   |               | Symbolic link contents ("symbolic link" is        |
   |               | defined in an Open Group [14] standard).          |
   | pathname4     | typedef component4 pathname4<>;                   |
   |               | Represents pathname for fs_locations.             |
   | verifier4     | typedef opaque verifier4[NFS4_VERIFIER_SIZE];     |
   |               | Verifier used for various operations (COMMIT,     |
   |               | CREATE, EXCHANGE_ID, OPEN, READDIR, WRITE)        |
   |               | NFS4_VERIFIER_SIZE is defined as 8.               |
   +---------------+---------------------------------------------------+
        
   | qop4          | typedef uint32_t qop4;                            |
   |               | Quality of protection designation in SECINFO.     |
   | sec_oid4      | typedef opaque sec_oid4<>;                        |
   |               | Security Object Identifier.  The sec_oid4 data    |
   |               | type is not really opaque.  Instead, it contains  |
   |               | an ASN.1 OBJECT IDENTIFIER as used by GSS-API in  |
   |               | the mech_type argument to GSS_Init_sec_context.   |
   |               | See [7] for details.                              |
   | sequenceid4   | typedef uint32_t sequenceid4;                     |
   |               | Sequence number used for various session          |
   |               | operations (EXCHANGE_ID, CREATE_SESSION,          |
   |               | SEQUENCE, CB_SEQUENCE).                           |
   | seqid4        | typedef uint32_t seqid4;                          |
   |               | Sequence identifier used for locking.             |
   | sessionid4    | typedef opaque sessionid4[NFS4_SESSIONID_SIZE];   |
   |               | Session identifier.                               |
   | slotid4       | typedef uint32_t slotid4;                         |
   |               | Sequencing artifact for various session           |
   |               | operations (SEQUENCE, CB_SEQUENCE).               |
   | utf8string    | typedef opaque utf8string<>;                      |
   |               | UTF-8 encoding for strings.                       |
   | utf8str_cis   | typedef utf8string utf8str_cis;                   |
   |               | Case-insensitive UTF-8 string.                    |
   | utf8str_cs    | typedef utf8string utf8str_cs;                    |
   |               | Case-sensitive UTF-8 string.                      |
   | utf8str_mixed | typedef utf8string utf8str_mixed;                 |
   |               | UTF-8 strings with a case-sensitive prefix and a  |
   |               | case-insensitive suffix.                          |
   | component4    | typedef utf8str_cs component4;                    |
   |               | Represents pathname components.                   |
   | linktext4     | typedef utf8str_cs linktext4;                     |
   |               | Symbolic link contents ("symbolic link" is        |
   |               | defined in an Open Group [14] standard).          |
   | pathname4     | typedef component4 pathname4<>;                   |
   |               | Represents pathname for fs_locations.             |
   | verifier4     | typedef opaque verifier4[NFS4_VERIFIER_SIZE];     |
   |               | Verifier used for various operations (COMMIT,     |
   |               | CREATE, EXCHANGE_ID, OPEN, READDIR, WRITE)        |
   |               | NFS4_VERIFIER_SIZE is defined as 8.               |
   +---------------+---------------------------------------------------+
        

End of Base Data Types

基本数据类型结束

Table 1

表1

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

The nfstime4 data type gives the number of seconds and nanoseconds since midnight or zero hour January 1, 1970 Coordinated Universal Time (UTC). Values greater than zero for the seconds field denote dates after the zero hour January 1, 1970. Values less than zero for the seconds field denote dates before the zero 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 zero hour January 1, 1970, the seconds field would have a value of negative one (-1) and the nseconds field would have a value of one-half second (500000000). Values greater than 999,999,999 for nseconds are invalid.

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

This data type is used to pass time and date information. A server converts to and from its local representation of time when processing time values, preserving as much accuracy as possible. If the precision of timestamps stored for a file system object is less than defined, loss of precision can occur. An adjunct time maintenance protocol is RECOMMENDED to reduce client and server time skew.

此数据类型用于传递时间和日期信息。在处理时间值时,服务器会在本地表示的时间之间进行转换,以尽可能保持准确性。如果为文件系统对象存储的时间戳的精度小于定义的精度,则可能会发生精度损失。建议使用附加的时间维护协议来减少客户端和服务器的时间偏差。

3.3.2. time_how4
3.3.2. 时间如何
   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
   };
        
3.3.3. settime4
3.3.3. 设置时间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 time_how4 and settime4 data types are used for setting timestamps in file object attributes. If set_it is SET_TO_SERVER_TIME4, then the server uses its local representation of time for the time value.

time_how4和settime4数据类型用于在文件对象属性中设置时间戳。如果将其设置为服务器时间4,则服务器使用其本地时间表示形式作为时间值。

3.3.4. specdata4
3.3.4. 规范数据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 the device numbers for the device file types NF4CHR and NF4BLK.

此数据类型表示设备文件类型NF4CHR和NF4BLK的设备编号。

3.3.5. fsid4
3.3.5. fsid4
   struct fsid4 {
           uint64_t        major;
           uint64_t        minor;
   };
        
   struct fsid4 {
           uint64_t        major;
           uint64_t        minor;
   };
        
3.3.6. change_policy4
3.3.6. 改变政策4
   struct change_policy4 {
           uint64_t        cp_major;
           uint64_t        cp_minor;
   };
        
   struct change_policy4 {
           uint64_t        cp_major;
           uint64_t        cp_minor;
   };
        

The change_policy4 data type is used for the change_policy RECOMMENDED attribute. It provides change sequencing indication analogous to the change attribute. To enable the server to present a value valid across server re-initialization without requiring persistent storage, two 64-bit quantities are used, allowing one to be a server instance ID and the second to be incremented non-persistently, within a given server instance.

change_policy4数据类型用于change_policy RECOMMENDED属性。它提供类似于更改属性的更改顺序指示。为了使服务器能够在不需要持久存储的情况下在服务器重新初始化期间提供有效的值,使用了两个64位量,允许一个是服务器实例ID,另一个在给定的服务器实例中非持久地递增。

3.3.7. fattr4
3.3.7. 胖子4
   struct fattr4 {
           bitmap4         attrmask;
           attrlist4       attr_vals;
   };
        
   struct fattr4 {
           bitmap4         attrmask;
           attrlist4       attr_vals;
   };
        

The fattr4 data type 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 |
   +-----------+-----------+-----------+--
        
3.3.8. change_info4
3.3.8. 更改信息4
   struct change_info4 {
           bool            atomic;
           changeid4       before;
           changeid4       after;
   };
        
   struct change_info4 {
           bool            atomic;
           changeid4       before;
           changeid4       after;
   };
        

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

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

3.3.9. netaddr4
3.3.9. NetAddress4
   struct netaddr4 {
           /* see struct rpcb in RFC 1833 */
           string na_r_netid<>; /* network id */
           string na_r_addr<>;  /* universal address */
   };
        
   struct netaddr4 {
           /* see struct rpcb in RFC 1833 */
           string na_r_netid<>; /* network id */
           string na_r_addr<>;  /* universal address */
   };
        

The netaddr4 data type is used to identify network transport endpoints. The r_netid and r_addr fields respectively contain a netid and uaddr. The netid and uaddr concepts are defined in [15]. The netid and uaddr formats for TCP over IPv4 and TCP over IPv6 are defined in [15], specifically Tables 2 and 3 and Sections 5.2.3.3 and 5.2.3.4.

NetAddress4数据类型用于标识网络传输端点。r_netid和r_addr字段分别包含netid和uaddr。netid和uaddr概念定义见[15]。[15]中定义了IPv4上TCP和IPv6上TCP的netid和uaddr格式,特别是表2和表3以及第5.2.3.3和5.2.3.4节。

3.3.10. state_owner4
3.3.10. 国有企业主4
   struct state_owner4 {
           clientid4       clientid;
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
   struct state_owner4 {
           clientid4       clientid;
           opaque          owner<NFS4_OPAQUE_LIMIT>;
   };
        
   typedef state_owner4 open_owner4;
   typedef state_owner4 lock_owner4;
        
   typedef state_owner4 open_owner4;
   typedef state_owner4 lock_owner4;
        

The state_owner4 data type is the base type for the open_owner4 (Section 3.3.10.1) and lock_owner4 (Section 3.3.10.2).

state_owner4数据类型是open_owner4(第3.3.10.1节)和lock_owner4(第3.3.10.2节)的基本类型。

3.3.10.1. open_owner4
3.3.10.1. 开放式所有者4

This data type is used to identify the owner of OPEN state.

此数据类型用于标识打开状态的所有者。

3.3.10.2. lock_owner4
3.3.10.2. 锁定所有者4

This structure is used to identify the owner of byte-range locking state.

此结构用于标识字节范围锁定状态的所有者。

3.3.11. open_to_lock_owner4
3.3.11. 打开至锁定所有者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 data type 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的形式绑定到已建立的状态。

3.3.12. stateid4
3.3.12. 州4
   struct stateid4 {
           uint32_t        seqid;
           opaque          other[12];
   };
        
   struct stateid4 {
           uint32_t        seqid;
           opaque          other[12];
   };
        

This data type is used for the various state sharing mechanisms between the client and server. The client never modifies a value of data type stateid. The starting value of the "seqid" field is undefined. The server is required to increment the "seqid" field by one 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.

此数据类型用于客户端和服务器之间的各种状态共享机制。客户端从不修改stateid数据类型的值。“seqid”字段的起始值未定义。服务器需要在stateid的每次转换中将“seqid”字段增加1。这一点很重要,因为客户端将检查OPEN StateID中的seqid,以确定服务器完成的打开处理顺序。

3.3.13. layouttype4
3.3.13. 布局类型4
   enum layouttype4 {
           LAYOUT4_NFSV4_1_FILES   = 0x1,
           LAYOUT4_OSD2_OBJECTS    = 0x2,
           LAYOUT4_BLOCK_VOLUME    = 0x3
   };
        
   enum layouttype4 {
           LAYOUT4_NFSV4_1_FILES   = 0x1,
           LAYOUT4_OSD2_OBJECTS    = 0x2,
           LAYOUT4_BLOCK_VOLUME    = 0x3
   };
        

This data type indicates what type of layout is being used. The file server advertises the layout types it supports through the fs_layout_type file system attribute (Section 5.12.1). A client asks for layouts of a particular type in LAYOUTGET, and processes those layouts in its layout-type-specific logic.

此数据类型指示正在使用的布局类型。文件服务器通过fs_layout_type文件系统属性(第5.12.1节)公布其支持的布局类型。客户机在LAYOUTGET中请求特定类型的布局,并在其布局类型特定的逻辑中处理这些布局。

The layouttype4 data type is 32 bits in length. The range represented by the layout type is split into three parts. Type 0x0 is reserved. Types within the range 0x00000001-0x7FFFFFFF are globally unique and are assigned according to the description in Section 22.4; they are maintained by IANA. Types within the range 0x80000000-0xFFFFFFFF are site specific and for private use only.

layouttype4数据类型的长度为32位。布局类型表示的范围分为三部分。类型0x0是保留的。0x00000001-0x7FFFFFFF范围内的类型是全局唯一的,并根据第22.4节中的描述进行分配;它们由IANA维护。0x8000000-0xFFFFFF范围内的类型是特定于站点的,仅供私人使用。

The LAYOUT4_NFSV4_1_FILES enumeration specifies that the NFSv4.1 file layout type, as defined in Section 13, is to be used. The LAYOUT4_OSD2_OBJECTS enumeration specifies that the object layout, as defined in [40], is to be used. Similarly, the LAYOUT4_BLOCK_VOLUME enumeration specifies that the block/volume layout, as defined in [41], is to be used.

LAYOUT4_NFSV4_1_文件枚举指定使用第13节中定义的NFSV4.1文件布局类型。LAYOUT4_OSD2_对象枚举指定要使用[40]中定义的对象布局。类似地,LAYOUT4\u BLOCK\u VOLUME枚举指定使用[41]中定义的块/卷布局。

3.3.14. deviceid4
3.3.14. 设备4

const NFS4_DEVICEID4_SIZE = 16;

常数NFS4_设备4_尺寸=16;

typedef opaque deviceid4[NFS4_DEVICEID4_SIZE];

typedef不透明设备4[NFS4_设备4_尺寸];

Layout information includes device IDs that specify a storage device through a compact handle. Addressing and type information is obtained with the GETDEVICEINFO operation. Device IDs are not guaranteed to be valid across metadata server restarts. A device ID is unique per client ID and layout type. See Section 12.2.10 for more details.

布局信息包括通过紧凑句柄指定存储设备的设备ID。通过GETDEVICEINFO操作获得寻址和类型信息。不能保证设备ID在元数据服务器重新启动时有效。每个客户端ID和布局类型的设备ID都是唯一的。详见第12.2.10节。

3.3.15. device_addr4
3.3.15. 设备地址4
   struct device_addr4 {
           layouttype4             da_layout_type;
           opaque                  da_addr_body<>;
   };
        
   struct device_addr4 {
           layouttype4             da_layout_type;
           opaque                  da_addr_body<>;
   };
        

The device address is used to set up a communication channel with the storage device. Different layout types will require different data types to define how they communicate with storage devices. The opaque da_addr_body field is interpreted based on the specified da_layout_type field.

设备地址用于设置与存储设备的通信通道。不同的布局类型将需要不同的数据类型来定义它们与存储设备的通信方式。不透明的da_addr_body字段将基于指定的da_layout_type字段进行解释。

This document defines the device address for the NFSv4.1 file layout (see Section 13.3), which identifies a storage device by network IP address and port number. This is sufficient for the clients to communicate with the NFSv4.1 storage devices, and may be sufficient for other layout types as well. Device types for object-based storage devices and block storage devices (e.g., Small Computer System Interface (SCSI) volume labels) are defined by their respective layout specifications.

本文档定义了NFSv4.1文件布局的设备地址(见第13.3节),该文件通过网络IP地址和端口号标识存储设备。这对于客户端与NFSv4.1存储设备进行通信已经足够了,对于其他布局类型也可能足够了。基于对象的存储设备和块存储设备(例如小型计算机系统接口(SCSI)卷标签)的设备类型由其各自的布局规范定义。

3.3.16. layout_content4
3.3.16. 版面内容4
   struct layout_content4 {
           layouttype4 loc_type;
           opaque      loc_body<>;
   };
        
   struct layout_content4 {
           layouttype4 loc_type;
           opaque      loc_body<>;
   };
        

The loc_body field is interpreted based on the layout type (loc_type). This document defines the loc_body for the NFSv4.1 file layout type; see Section 13.3 for its definition.

loc_主体字段根据布局类型(loc_类型)进行解释。本文件定义了NFSv4.1文件布局类型的loc_主体;其定义见第13.3节。

3.3.17. layout4
3.3.17. 布局4
   struct layout4 {
           offset4                 lo_offset;
           length4                 lo_length;
           layoutiomode4           lo_iomode;
           layout_content4         lo_content;
   };
        
   struct layout4 {
           offset4                 lo_offset;
           length4                 lo_length;
           layoutiomode4           lo_iomode;
           layout_content4         lo_content;
   };
        

The layout4 data type defines a layout for a file. The layout type specific data is opaque within lo_content. Since layouts are sub-dividable, the offset and length together with the file's filehandle, the client ID, iomode, and layout type identify the layout.

layout4数据类型定义文件的布局。布局类型特定的数据在lo_内容中不透明。由于布局是可分的,因此偏移量和长度以及文件的文件句柄、客户端ID、iomode和布局类型将标识布局。

3.3.18. layoutupdate4
3.3.18. 布局更新4
   struct layoutupdate4 {
           layouttype4             lou_type;
           opaque                  lou_body<>;
   };
        
   struct layoutupdate4 {
           layouttype4             lou_type;
           opaque                  lou_body<>;
   };
        

The layoutupdate4 data type is used by the client to return updated layout information to the metadata server via the LAYOUTCOMMIT (Section 18.42) operation. This data type provides a channel to pass layout type specific information (in field lou_body) back to the metadata server. For example, for the block/volume layout type, this could include the list of reserved blocks that were written. The contents of the opaque lou_body argument are determined by the layout

客户端使用layoutupdate4数据类型通过LAYOUTCOMMIT(第18.42节)操作将更新的布局信息返回给元数据服务器。此数据类型提供了一个将布局类型特定信息(在字段lou_body中)传递回元数据服务器的通道。例如,对于块/卷布局类型,这可能包括已写入的保留块的列表。不透明lou_body参数的内容由布局决定

type. The NFSv4.1 file-based layout does not use this data type; if lou_type is LAYOUT4_NFSV4_1_FILES, the lou_body field MUST have a zero length.

类型基于NFSv4.1文件的布局不使用此数据类型;如果lou_类型为LAYOUT4_NFSV4_1_文件,则lou_正文字段的长度必须为零。

3.3.19. layouthint4
3.3.19. 布局权限4
   struct layouthint4 {
           layouttype4             loh_type;
           opaque                  loh_body<>;
   };
        
   struct layouthint4 {
           layouttype4             loh_type;
           opaque                  loh_body<>;
   };
        

The layouthint4 data type is used by the client to pass in a hint about the type of layout it would like created for a particular file. It is the data type specified by the layout_hint attribute described in Section 5.12.4. The metadata server may ignore the hint or may selectively ignore fields within the hint. This hint should be provided at create time as part of the initial attributes within OPEN. The loh_body field is specific to the type of layout (loh_type). The NFSv4.1 file-based layout uses the nfsv4_1_file_layouthint4 data type as defined in Section 13.3.

layouthint4数据类型由客户机用于传递有关它希望为特定文件创建的布局类型的提示。第5.12.4节中描述的布局提示属性指定的数据类型。元数据服务器可以忽略提示,也可以选择性地忽略提示中的字段。这个提示应该在创建时作为OPEN中初始属性的一部分提供。loh_body字段特定于布局类型(loh_类型)。基于NFSv4.1文件的布局使用第13.3节中定义的NFSv4_1_文件_LayoutInt4数据类型。

3.3.20. layoutiomode4
3.3.20. 布局模式4
   enum layoutiomode4 {
           LAYOUTIOMODE4_READ      = 1,
           LAYOUTIOMODE4_RW        = 2,
           LAYOUTIOMODE4_ANY       = 3
   };
        
   enum layoutiomode4 {
           LAYOUTIOMODE4_READ      = 1,
           LAYOUTIOMODE4_RW        = 2,
           LAYOUTIOMODE4_ANY       = 3
   };
        

The iomode specifies whether the client intends to just read or both read and write the data represented by the layout. While the LAYOUTIOMODE4_ANY iomode MUST NOT be used in the arguments to the LAYOUTGET operation, it MAY be used in the arguments to the LAYOUTRETURN and CB_LAYOUTRECALL operations. The LAYOUTIOMODE4_ANY iomode specifies that layouts pertaining to both LAYOUTIOMODE4_READ and LAYOUTIOMODE4_RW iomodes are being returned or recalled, respectively. The metadata server's use of the iomode may depend on the layout type being used. The storage devices MAY validate I/O accesses against the iomode and reject invalid accesses.

iomode指定客户端是只读取还是同时读取和写入布局所表示的数据。虽然LAYOUTIOMODE4_ANY iomode不能用于LAYOUTGET操作的参数中,但它可以用于LAYOUTRETURN和CB_LAYOUTRECALL操作的参数中。LAYOUTIOMODE4_ANY iomode指定分别返回或调用与LAYOUTIOMODE4_READ和LAYOUTIOMODE4_RW iomode相关的布局。元数据服务器对iomode的使用可能取决于所使用的布局类型。存储设备可以根据iomode验证I/O访问,并拒绝无效访问。

3.3.21. nfs_impl_id4
3.3.21. nfs_impl_id4
   struct nfs_impl_id4 {
           utf8str_cis   nii_domain;
           utf8str_cs    nii_name;
           nfstime4      nii_date;
   };
        
   struct nfs_impl_id4 {
           utf8str_cis   nii_domain;
           utf8str_cs    nii_name;
           nfstime4      nii_date;
   };
        

This data type is used to identify client and server implementation details. The nii_domain field is the DNS domain name with which the implementor is associated. The nii_name field is the product name of the implementation and is completely free form. It is RECOMMENDED that the nii_name be used to distinguish machine architecture, machine platforms, revisions, versions, and patch levels. The nii_date field is the timestamp of when the software instance was published or built.

此数据类型用于标识客户端和服务器实现详细信息。nii_域字段是与实现者关联的DNS域名。nii_名称字段是实现的产品名称,是完全自由的形式。建议使用nii_名称来区分机器体系结构、机器平台、版本、版本和修补程序级别。nii_日期字段是发布或构建软件实例的时间戳。

3.3.22. threshold_item4
3.3.22. 阈值_项4
   struct threshold_item4 {
           layouttype4     thi_layout_type;
           bitmap4         thi_hintset;
           opaque          thi_hintlist<>;
   };
        
   struct threshold_item4 {
           layouttype4     thi_layout_type;
           bitmap4         thi_hintset;
           opaque          thi_hintlist<>;
   };
        

This data type contains a list of hints specific to a layout type for helping the client determine when it should send I/O directly through the metadata server versus the storage devices. The data type consists of the layout type (thi_layout_type), a bitmap (thi_hintset) describing the set of hints supported by the server (they may differ based on the layout type), and a list of hints (thi_hintlist) whose content is determined by the hintset bitmap. See the mdsthreshold attribute for more details.

此数据类型包含特定于布局类型的提示列表,用于帮助客户端确定何时应直接通过元数据服务器而不是存储设备发送I/O。数据类型包括布局类型(thi_layout_类型)、描述服务器支持的提示集的位图(thi_hintset)(它们可能因布局类型而异)和提示列表(thi_hintlist),其内容由hintset位图确定。有关详细信息,请参见mdsthreshold属性。

The thi_hintset field is a bitmap of the following values:

thi_hintset字段是具有以下值的位图:

   +-------------------------+---+---------+---------------------------+
   | name                    | # | Data    | Description               |
   |                         |   | Type    |                           |
   +-------------------------+---+---------+---------------------------+
   | threshold4_read_size    | 0 | length4 | If a file's length is     |
   |                         |   |         | less than the value of    |
   |                         |   |         | threshold4_read_size,     |
   |                         |   |         | then it is RECOMMENDED    |
   |                         |   |         | that the client read from |
   |                         |   |         | the file via the MDS and  |
   |                         |   |         | not a storage device.     |
   | threshold4_write_size   | 1 | length4 | If a file's length is     |
   |                         |   |         | less than the value of    |
   |                         |   |         | threshold4_write_size,    |
   |                         |   |         | then it is RECOMMENDED    |
   |                         |   |         | that the client write to  |
   |                         |   |         | the file via the MDS and  |
   |                         |   |         | not a storage device.     |
   | threshold4_read_iosize  | 2 | length4 | For read I/O sizes below  |
   |                         |   |         | this threshold, it is     |
   |                         |   |         | RECOMMENDED to read data  |
   |                         |   |         | through the MDS.          |
   | threshold4_write_iosize | 3 | length4 | For write I/O sizes below |
   |                         |   |         | this threshold, it is     |
   |                         |   |         | RECOMMENDED to write data |
   |                         |   |         | through the MDS.          |
   +-------------------------+---+---------+---------------------------+
        
   +-------------------------+---+---------+---------------------------+
   | name                    | # | Data    | Description               |
   |                         |   | Type    |                           |
   +-------------------------+---+---------+---------------------------+
   | threshold4_read_size    | 0 | length4 | If a file's length is     |
   |                         |   |         | less than the value of    |
   |                         |   |         | threshold4_read_size,     |
   |                         |   |         | then it is RECOMMENDED    |
   |                         |   |         | that the client read from |
   |                         |   |         | the file via the MDS and  |
   |                         |   |         | not a storage device.     |
   | threshold4_write_size   | 1 | length4 | If a file's length is     |
   |                         |   |         | less than the value of    |
   |                         |   |         | threshold4_write_size,    |
   |                         |   |         | then it is RECOMMENDED    |
   |                         |   |         | that the client write to  |
   |                         |   |         | the file via the MDS and  |
   |                         |   |         | not a storage device.     |
   | threshold4_read_iosize  | 2 | length4 | For read I/O sizes below  |
   |                         |   |         | this threshold, it is     |
   |                         |   |         | RECOMMENDED to read data  |
   |                         |   |         | through the MDS.          |
   | threshold4_write_iosize | 3 | length4 | For write I/O sizes below |
   |                         |   |         | this threshold, it is     |
   |                         |   |         | RECOMMENDED to write data |
   |                         |   |         | through the MDS.          |
   +-------------------------+---+---------+---------------------------+
        
3.3.23. mdsthreshold4
3.3.23. mdsthreshold4
   struct mdsthreshold4 {
           threshold_item4 mth_hints<>;
   };
        
   struct mdsthreshold4 {
           threshold_item4 mth_hints<>;
   };
        

This data type holds an array of elements of data type threshold_item4, each of which is valid for a particular layout type. An array is necessary because a server can support multiple layout types for a single file.

此数据类型保存数据类型threshold_item4的元素数组,每个元素对特定布局类型有效。阵列是必需的,因为服务器可以为单个文件支持多种布局类型。

4. Filehandles
4. 文件句柄

The filehandle in the NFS protocol is a per-server unique identifier for a file system object. The contents of the filehandle are opaque to the client. Therefore, the server is responsible for translating the filehandle to an internal representation of the file system object.

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 NFSv3 protocol (RFC 1813 [31]), there exists an ancillary protocol to obtain this first filehandle. The MOUNT protocol, RPC program number 100005, provides the mechanism of translating a string-based file system pathname to a filehandle, which can then be used by the NFS protocols.

NFS协议的操作是根据一个或多个文件句柄定义的。因此,客户端需要一个文件句柄来启动与服务器的通信。对于NFSv3协议(RFC1813[31]),存在一个辅助协议来获取第一个文件句柄。装载协议(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 RFC 2054 [42] and RFC 2055 [43]. With the use of the public filehandle in combination with the LOOKUP operation in the NFSv3 protocol, it has been demonstrated that the MOUNT protocol is unnecessary for viable interaction between NFS client and server.

MOUNT协议在安全性和通过防火墙使用方面存在缺陷。这是在RFC 2054[42]和RFC 2055[43]中引入公共文件句柄的原因之一。通过将公共文件句柄与NFSv3协议中的查找操作结合使用,已经证明对于NFS客户端和服务器之间的可行交互来说,装载协议是不必要的。

Therefore, the NFSv4.1 protocol will not use an ancillary protocol for translation from string-based pathnames to a filehandle. Two special filehandles will be used as starting points for the NFS client.

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

4.1.1. Root Filehandle
4.1.1. 根文件句柄

The first of the special filehandles is the ROOT filehandle. The ROOT filehandle is the "conceptual" root of the file system namespace 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 namespace is in Section 7.

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

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

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

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

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

In the NFSv3 protocol, there was one type of filehandle with a single set of semantics. This type of filehandle is termed "persistent" in NFSv4.1. The semantics of a persistent filehandle remain the same as before. A new type of filehandle introduced in NFSv4.1 is the "volatile" filehandle, which attempts to accommodate certain server environments.

在NFSv3协议中,有一种文件句柄类型,只有一组语义。这种类型的文件句柄在NFSv4.1中称为“持久”。持久化文件句柄的语义与以前相同。NFSv4.1中引入的一种新型文件句柄是“volatile”文件句柄,它试图适应某些服务器环境。

The volatile filehandle type was introduced to address server functionality or implementation issues that make correct implementation of a persistent filehandle infeasible. Some server environments do not provide a file-system-level invariant that can be used to construct a persistent filehandle. The underlying server file system may not provide the invariant or the server's file system programming interfaces may not provide access to the needed invariant. Volatile filehandles may ease the implementation of server functionality such as hierarchical storage management or file system reorganization or migration. However, the volatile filehandle increases the implementation burden for the client.

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

Since the client will need to handle persistent and volatile filehandles differently, a file attribute is defined that 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 that might cause incorrect behavior. Further discussion of filehandle and attribute comparison in the context of data caching is presented in Section 10.3.4.

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

As an example, in the case that two different pathnames when traversed at the server terminate at the same file system object, the server SHOULD return the same filehandle for each path. This can

例如,如果在服务器上遍历两个不同的路径名时终止于同一文件系统对象,则服务器应为每个路径返回相同的filehandle。这个可以

occur if a hard link (see [6]) is used to create two file names that 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 pathnames' traversals.

如果使用硬链接(请参见[6])创建两个引用相同基础文件对象和关联数据的文件名,则会发生此错误。例如,如果路径/a/b/c和/a/d/c引用同一个文件,则服务器应为两个路径名的遍历返回相同的文件句柄。

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

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

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

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

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

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

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

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

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

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

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

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

FH4_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 a file system transition (migration or replication), in those cases in which the continuity of filehandle use is not specified by handle class information within the fs_locations_info attribute. When this bit is set, clients without access to fs_locations_info information should assume that filehandles will expire on file system transitions.

FH4_VOL_迁移文件句柄将因文件系统转换(迁移或复制)而过期,在这种情况下,文件句柄使用的连续性不是由fs_locations_info属性中的句柄类信息指定的。设置此位后,无法访问fs\u位置\u信息的客户端应假定文件句柄将在文件系统转换时过期。

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 that provide volatile filehandles that can expire while open require special care as regards handling of RENAMEs and REMOVEs. This situation can arise if FH4_VOL_MIGRATION or FH4_VOL_RENAME is set, if FH4_VOLATILE_ANY is set and FH4_NOEXPIRE_WITH_OPEN is not set, or if a non-read-only file system has a transition target in a different handle class. In these cases, the server 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, in order to make sure that reclaims of files where filehandles may have expired do not do a reclaim for the wrong file.

提供易失性文件句柄(打开时可能过期)的服务器需要特别注意重命名和删除的处理。如果设置了FH4_VOL_MIGRATION或FH4_VOL_RENAME,如果设置了FH4_VOLATILE_ANY且未设置FH4_NOEXPIRE_WITH_OPEN,或者如果非只读文件系统在不同的句柄类中具有转换目标,则会出现这种情况。在这些情况下,服务器应拒绝重命名或删除会影响导致打开文件的任何组件的打开文件的重命名或删除。此外,服务器应在宽限期内拒绝所有重命名或删除请求,以确保回收文件句柄可能已过期的文件时不会回收错误的文件。

Volatile filehandles are especially suitable for implementation of the pseudo file systems used to bridge exports. See Section 7.5 for a discussion of this.

Volatile文件句柄特别适合于用于桥接导出的伪文件系统的实现。有关这方面的讨论,请参见第7.5节。

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

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 restarts, the table is gone (it is volatile).

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

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

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

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

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

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

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

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

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

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

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

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

RENAME A B LOOKUP B GETFH

重命名A B查找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 need to be handled in a flexible manner. The NFSv3 fattr3 structure contains a fixed list of attributes that not all clients and servers are able to support or care about. The fattr3 structure cannot be extended as new needs arise and it provides no way to indicate non-support. With the NFSv4.1 protocol, the client is able to query what attributes the server supports and construct requests with only those supported attributes (or a subset thereof).

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

To this end, attributes are divided into three groups: REQUIRED, RECOMMENDED, and named. Both REQUIRED and RECOMMENDED attributes are supported in the NFSv4.1 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 REQUIRED or RECOMMENDED attributes may be added to the NFSv4 protocol as part of a new minor version by publishing a Standards Track RFC that allocates a new attribute number value and defines the encoding for the attribute. See Section 2.7 for further discussion.

为此,属性分为三组:必需、推荐和命名。NFSv4.1协议通过特定和定义良好的编码支持必需和推荐属性,并通过数字标识。通过在GETATTR请求中发送的位向量中设置位来请求它们;服务器响应包含一个位向量,用于列出响应中返回的属性。通过发布分配新属性编号值并定义属性编码的标准跟踪RFC,可以将新的必需或推荐属性作为新次要版本的一部分添加到NFSv4协议中。进一步讨论见第2.7节。

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          |
        +----------+-----------+---------------------------------+
        
        +----------+-----------+---------------------------------+
        | 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          |
        +----------+-----------+---------------------------------+
        

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 that are classified as REQUIRED is deliberately small since servers need to 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 REQUIRED 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 or not the underlying file system at the server has a named attribute directory. Therefore, operations such as SETATTR and GETATTR on the named attribute directory are undefined.

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

5.1. REQUIRED Attributes
5.1. 必需属性

These MUST be supported by every NFSv4.1 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 REQUIRED 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.

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

5.2. RECOMMENDED Attributes
5.2. 推荐属性

These attributes are understood well enough to warrant support in the NFSv4.1 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 that 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

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

supported by the server. At times this will be difficult for clients, but a client is better positioned to decide whether and how to fabricate or construct an attribute or whether to do without the attribute.

由服务器支持。有时,这对客户机来说很困难,但客户机可以更好地决定是否以及如何制作或构造属性,或者是否不使用属性。

5.3. Named Attributes
5.3. 命名属性

These attributes are not supported by direct encoding in the NFSv4 protocol but are accessed by string names rather than numbers and correspond to an uninterpreted stream of bytes that are stored with the file system object. The namespace for these attributes may be accessed by using the OPENATTR operation. The OPENATTR operation returns a filehandle for a virtual "named attribute directory", and further perusal and modification of the namespace may be done using operations that work on more typical directories. In particular, READDIR may be used to get a list of such named attributes, and LOOKUP and OPEN may select a particular attribute. Creation of a new named attribute may be the result of an OPEN specifying file creation.

NFSv4协议中的直接编码不支持这些属性,但可以通过字符串名称而不是数字来访问这些属性,并对应于与文件系统对象一起存储的未解释的字节流。可以使用OPENATTR操作访问这些属性的名称空间。OPENATTR操作返回虚拟“命名属性目录”的文件句柄,可以使用在更典型的目录上工作的操作来进一步阅读和修改名称空间。具体而言,READDIR可用于获取此类命名属性的列表,而LOOKUP和OPEN可选择特定属性。新命名属性的创建可能是打开指定文件创建的结果。

Once an OPEN is done, named attributes may be examined and changed by normal READ and WRITE operations using the filehandles and stateids returned by OPEN.

一旦打开完成,命名属性就可以通过使用OPEN返回的filehandles和stateID的正常读写操作进行检查和更改。

Named attributes and the named attribute directory may have their own (non-named) attributes. Each of these objects MUST have all of the REQUIRED attributes and may have additional RECOMMENDED attributes. However, the set of attributes for named attributes and the named attribute directory need not be, and typically will not be, as large as that for other objects in that file system.

命名属性和命名属性目录可能有自己的(非命名)属性。这些对象中的每一个都必须具有所有必需的属性,并且可能具有其他建议的属性。但是,命名属性和命名属性目录的属性集不需要也通常不会像该文件系统中其他对象的属性集那样大。

Named attributes and the named attribute directory might be the target of delegations (in the case of the named attribute directory, these will be directory delegations). However, since granting delegations is at the server's discretion, a server need not support delegations on named attributes or the named attribute directory.

命名属性和命名属性目录可能是委派的目标(对于命名属性目录,这些将是目录委派)。但是,由于授权是由服务器自行决定的,因此服务器不需要支持对命名属性或命名属性目录的授权。

It is RECOMMENDED that servers support arbitrary named attributes. A client should not depend on the ability to store any named attributes in the server's file system. If a server does support named attributes, a client that is also able to handle them should be able to copy a file's data and metadata 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.

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

In NFSv4.1, the structure of named attribute directories is restricted in a number of ways, in order to prevent the development of non-interoperable implementations in which some servers support a fully general hierarchical directory structure for named attributes while others support a limited but adequate structure for named attributes. In such an environment, clients or applications might come to depend on non-portable extensions. The restrictions are:

在NFSv4.1中,命名属性目录的结构以多种方式受到限制,以防止开发不可互操作的实现,其中一些服务器支持命名属性的完全通用层次目录结构,而另一些服务器支持有限但适当的命名属性结构。在这样的环境中,客户端或应用程序可能会依赖于不可移植的扩展。这些限制包括:

o CREATE is not allowed in a named attribute directory. Thus, such objects as symbolic links and special files are not allowed to be named attributes. Further, directories may not be created in a named attribute directory, so no hierarchical structure of named attributes for a single object is allowed.

o 不允许在命名属性目录中创建。因此,诸如符号链接和特殊文件之类的对象不允许被命名为属性。此外,可能无法在命名属性目录中创建目录,因此不允许单个对象的命名属性的层次结构。

o If OPENATTR is done on a named attribute directory or on a named attribute, the server MUST return NFS4ERR_WRONG_TYPE.

o 如果在命名属性目录或命名属性上执行OPENATTR,则服务器必须返回NFS4ERR\u错误类型。

o Doing a RENAME of a named attribute to a different named attribute directory or to an ordinary (i.e., non-named-attribute) directory is not allowed.

o 不允许将命名属性重命名为其他命名属性目录或普通(即非命名属性)目录。

o Creating hard links between named attribute directories or between named attribute directories and ordinary directories is not allowed.

o 不允许在命名属性目录之间或命名属性目录与普通目录之间创建硬链接。

Names of attributes will not be controlled by this document or other IETF Standards Track documents. See Section 22.1 for further discussion.

属性名称不受本文件或其他IETF标准跟踪文件的控制。进一步讨论见第22.1节。

5.4. Classification of Attributes
5.4. 属性分类

Each of the REQUIRED and RECOMMENDED attributes can be classified in one of three categories: per server (i.e., the value of the attribute will be the same for all file objects that share the same server owner; see Section 2.5 for a definition of server owner), per file system (i.e., the value of the attribute will be the same for some or all file objects that share the same fsid attribute (Section 5.8.1.9) and server owner), or per file system object. Note that it is possible that some per file system attributes may vary within the file system, depending on the value of the "homogeneous" (Section 5.8.2.16) attribute. 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.

每个必需的和推荐的属性可以分为三类:每个服务器(即,共享同一服务器所有者的所有文件对象的属性值都相同;有关服务器所有者的定义,请参见第2.5节)、每个文件系统(即,对于共享相同fsid属性(第5.8.1.9节)和服务器所有者的某些或所有文件对象,该属性的值将是相同的),或者对于每个文件系统对象,该属性的值将是相同的。请注意,根据“同构”(第5.8.2.16节)的值,每个文件系统中的某些属性可能会有所不同属性。请注意,属性time_access_set和time_modify_set未在本节中列出,因为它们是与time_access和time_modify相对应的仅写属性,并且在SETATTR的特殊实例中使用。

o The per-server attribute is:

o 每服务器属性为:

lease_time

租赁时间

o The per-file system attributes are:

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

supported_attrs, suppattr_exclcreat, 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, change_policy, fs_status, fs_layout_type, fs_locations_info, fs_charset_cap

受支持的属性、支持属性、exclcreat、fh过期类型、链接支持、符号链接支持、唯一句柄、aclsupport、cansettime、大小写不敏感、保留大小写、chown限制、文件可用、文件可用、文件总数、fs位置、同构、最大文件大小、最大名称、最大读取、最大写入、无特鲁NC、空间可用、空间可用、空间总数、时间增量、,更改策略、fs状态、fs布局类型、fs位置信息、fs字符集上限

o The per-file system 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, dir_notif_delay, dirent_notif_delay, dacl, sacl, layout_type, layout_hint, layout_blksize, layout_alignment, mdsthreshold, retention_get, retention_set, retentevt_get, retentevt_set, retention_hold, mode_set_masked

类型、更改、大小、命名属性、fsid、rdattr错误、文件句柄、acl、存档、文件ID、隐藏、maxlink、mimetype、模式、numlinks、所有者、所有者组、rawdev、使用的空间、系统、时间访问、时间备份、时间创建、时间元数据、时间修改、在文件ID上挂载、dir-notif-delay、dirent-notif-delay、dacl、sacl、布局类型、布局提示、,布局blksize、布局对齐、mdsthreshold、保留设置、保留设置、保留设置、保留设置、保留设置、保留保持、模式设置屏蔽

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

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

5.5. Set-Only and Get-Only Attributes
5.5. 仅设置和仅获取属性

Some REQUIRED and RECOMMENDED attributes are set-only; i.e., they can be set via SETATTR but not retrieved via GETATTR. Similarly, some REQUIRED and RECOMMENDED attributes are get-only; i.e., they can be retrieved via GETATTR but not set via SETATTR. If a client attempts to set a get-only attribute or get a set-only attributes, the server MUST return NFS4ERR_INVAL.

仅设置了一些必需和推荐的属性;i、 例如,它们可以通过SETATTR设置,但不能通过GETATTR检索。类似地,一些必需的和推荐的属性是get only;i、 例如,它们可以通过GETATTR检索,但不能通过SETATTR设置。如果客户端试图设置get-only属性或get-only属性,则服务器必须返回NFS4ERR_INVAL。

5.6. REQUIRED Attributes - List and Definition References
5.6. 所需属性-列表和定义参考

The list of REQUIRED attributes appears in Table 2. The meaning of the columns of the table are:

表2中显示了所需属性的列表。表中各列的含义如下:

o Name: The name of the attribute.

o 名称:属性的名称。

o Id: The number assigned to the attribute. In the event of conflicts between the assigned number and [13], the latter is likely authoritative, but should be resolved with Errata to this document and/or [13]. See [44] for the Errata process.

o Id:分配给属性的编号。如果分配的编号与[13]之间存在冲突,后者可能具有权威性,但应使用本文件和/或[13]的勘误表予以解决。有关勘误表过程,请参见[44]。

o Data Type: The XDR data type of the attribute.

o 数据类型:属性的XDR数据类型。

o Acc: Access allowed to the attribute. R means read-only (GETATTR may retrieve, SETATTR may not set). W means write-only (SETATTR may set, GETATTR may not retrieve). R W means read/write (GETATTR may retrieve, SETATTR may set).

o Acc:允许访问该属性。R表示只读(GETATTR可以检索,SETATTR可以不设置)。W表示仅写(SETATTR可以设置,GETATTR不能检索)。RW表示读/写(GETATTR可以检索,SETATTR可以设置)。

o Defined in: The section of this specification that describes the attribute.

o 定义于:本规范中描述属性的部分。

     +--------------------+----+------------+-----+------------------+
     | Name               | Id | Data Type  | Acc | Defined in:      |
     +--------------------+----+------------+-----+------------------+
     | supported_attrs    | 0  | bitmap4    | R   | Section 5.8.1.1  |
     | type               | 1  | nfs_ftype4 | R   | Section 5.8.1.2  |
     | fh_expire_type     | 2  | uint32_t   | R   | Section 5.8.1.3  |
     | change             | 3  | uint64_t   | R   | Section 5.8.1.4  |
     | size               | 4  | uint64_t   | R W | Section 5.8.1.5  |
     | link_support       | 5  | bool       | R   | Section 5.8.1.6  |
     | symlink_support    | 6  | bool       | R   | Section 5.8.1.7  |
     | named_attr         | 7  | bool       | R   | Section 5.8.1.8  |
     | fsid               | 8  | fsid4      | R   | Section 5.8.1.9  |
     | unique_handles     | 9  | bool       | R   | Section 5.8.1.10 |
     | lease_time         | 10 | nfs_lease4 | R   | Section 5.8.1.11 |
     | rdattr_error       | 11 | enum       | R   | Section 5.8.1.12 |
     | filehandle         | 19 | nfs_fh4    | R   | Section 5.8.1.13 |
     | suppattr_exclcreat | 75 | bitmap4    | R   | Section 5.8.1.14 |
     +--------------------+----+------------+-----+------------------+
        
     +--------------------+----+------------+-----+------------------+
     | Name               | Id | Data Type  | Acc | Defined in:      |
     +--------------------+----+------------+-----+------------------+
     | supported_attrs    | 0  | bitmap4    | R   | Section 5.8.1.1  |
     | type               | 1  | nfs_ftype4 | R   | Section 5.8.1.2  |
     | fh_expire_type     | 2  | uint32_t   | R   | Section 5.8.1.3  |
     | change             | 3  | uint64_t   | R   | Section 5.8.1.4  |
     | size               | 4  | uint64_t   | R W | Section 5.8.1.5  |
     | link_support       | 5  | bool       | R   | Section 5.8.1.6  |
     | symlink_support    | 6  | bool       | R   | Section 5.8.1.7  |
     | named_attr         | 7  | bool       | R   | Section 5.8.1.8  |
     | fsid               | 8  | fsid4      | R   | Section 5.8.1.9  |
     | unique_handles     | 9  | bool       | R   | Section 5.8.1.10 |
     | lease_time         | 10 | nfs_lease4 | R   | Section 5.8.1.11 |
     | rdattr_error       | 11 | enum       | R   | Section 5.8.1.12 |
     | filehandle         | 19 | nfs_fh4    | R   | Section 5.8.1.13 |
     | suppattr_exclcreat | 75 | bitmap4    | R   | Section 5.8.1.14 |
     +--------------------+----+------------+-----+------------------+
        

Table 2

表2

5.7. RECOMMENDED Attributes - List and Definition References
5.7. 推荐属性-列表和定义参考

The RECOMMENDED attributes are defined in Table 3. The meanings of the column headers are the same as Table 2; see Section 5.6 for the meanings.

表3中定义了推荐的属性。列标题的含义与表2相同;含义见第5.6节。

   +--------------------+----+----------------+-----+------------------+
   | Name               | Id | Data Type      | Acc | Defined in:      |
   +--------------------+----+----------------+-----+------------------+
   | acl                | 12 | nfsace4<>      | R W | Section 6.2.1    |
   | aclsupport         | 13 | uint32_t       | R   | Section 6.2.1.2  |
   | archive            | 14 | bool           | R W | Section 5.8.2.1  |
   | cansettime         | 15 | bool           | R   | Section 5.8.2.2  |
   | case_insensitive   | 16 | bool           | R   | Section 5.8.2.3  |
   | case_preserving    | 17 | bool           | R   | Section 5.8.2.4  |
   | change_policy      | 60 | chg_policy4    | R   | Section 5.8.2.5  |
   | chown_restricted   | 18 | bool           | R   | Section 5.8.2.6  |
   | dacl               | 58 | nfsacl41       | R W | Section 6.2.2    |
   | dir_notif_delay    | 56 | nfstime4       | R   | Section 5.11.1   |
   | dirent_notif_delay | 57 | nfstime4       | R   | Section 5.11.2   |
   | fileid             | 20 | uint64_t       | R   | Section 5.8.2.7  |
   | files_avail        | 21 | uint64_t       | R   | Section 5.8.2.8  |
   | files_free         | 22 | uint64_t       | R   | Section 5.8.2.9  |
   | files_total        | 23 | uint64_t       | R   | Section 5.8.2.10 |
   | fs_charset_cap     | 76 | uint32_t       | R   | Section 5.8.2.11 |
   | fs_layout_type     | 62 | layouttype4<>  | R   | Section 5.12.1   |
   | fs_locations       | 24 | fs_locations   | R   | Section 5.8.2.12 |
   | fs_locations_info  | 67 | *              | R   | Section 5.8.2.13 |
   | fs_status          | 61 | fs4_status     | R   | Section 5.8.2.14 |
   | hidden             | 25 | bool           | R W | Section 5.8.2.15 |
   | homogeneous        | 26 | bool           | R   | Section 5.8.2.16 |
   | layout_alignment   | 66 | uint32_t       | R   | Section 5.12.2   |
   | layout_blksize     | 65 | uint32_t       | R   | Section 5.12.3   |
   | layout_hint        | 63 | layouthint4    |   W | Section 5.12.4   |
   | layout_type        | 64 | layouttype4<>  | R   | Section 5.12.5   |
   | maxfilesize        | 27 | uint64_t       | R   | Section 5.8.2.17 |
   | maxlink            | 28 | uint32_t       | R   | Section 5.8.2.18 |
   | maxname            | 29 | uint32_t       | R   | Section 5.8.2.19 |
   | maxread            | 30 | uint64_t       | R   | Section 5.8.2.20 |
   | maxwrite           | 31 | uint64_t       | R   | Section 5.8.2.21 |
   | mdsthreshold       | 68 | mdsthreshold4  | R   | Section 5.12.6   |
   | mimetype           | 32 | utf8str_cs     | R W | Section 5.8.2.22 |
   | mode               | 33 | mode4          | R W | Section 6.2.4    |
   | mode_set_masked    | 74 | mode_masked4   |   W | Section 6.2.5    |
   | mounted_on_fileid  | 55 | uint64_t       | R   | Section 5.8.2.23 |
   | no_trunc           | 34 | bool           | R   | Section 5.8.2.24 |
   | numlinks           | 35 | uint32_t       | R   | Section 5.8.2.25 |
   | owner              | 36 | utf8str_mixed  | R W | Section 5.8.2.26 |
   | owner_group        | 37 | utf8str_mixed  | R W | Section 5.8.2.27 |
   | quota_avail_hard   | 38 | uint64_t       | R   | Section 5.8.2.28 |
   | quota_avail_soft   | 39 | uint64_t       | R   | Section 5.8.2.29 |
   | quota_used         | 40 | uint64_t       | R   | Section 5.8.2.30 |
   | rawdev             | 41 | specdata4      | R   | Section 5.8.2.31 |
   | retentevt_get      | 71 | retention_get4 | R   | Section 5.13.3   |
        
   +--------------------+----+----------------+-----+------------------+
   | Name               | Id | Data Type      | Acc | Defined in:      |
   +--------------------+----+----------------+-----+------------------+
   | acl                | 12 | nfsace4<>      | R W | Section 6.2.1    |
   | aclsupport         | 13 | uint32_t       | R   | Section 6.2.1.2  |
   | archive            | 14 | bool           | R W | Section 5.8.2.1  |
   | cansettime         | 15 | bool           | R   | Section 5.8.2.2  |
   | case_insensitive   | 16 | bool           | R   | Section 5.8.2.3  |
   | case_preserving    | 17 | bool           | R   | Section 5.8.2.4  |
   | change_policy      | 60 | chg_policy4    | R   | Section 5.8.2.5  |
   | chown_restricted   | 18 | bool           | R   | Section 5.8.2.6  |
   | dacl               | 58 | nfsacl41       | R W | Section 6.2.2    |
   | dir_notif_delay    | 56 | nfstime4       | R   | Section 5.11.1   |
   | dirent_notif_delay | 57 | nfstime4       | R   | Section 5.11.2   |
   | fileid             | 20 | uint64_t       | R   | Section 5.8.2.7  |
   | files_avail        | 21 | uint64_t       | R   | Section 5.8.2.8  |
   | files_free         | 22 | uint64_t       | R   | Section 5.8.2.9  |
   | files_total        | 23 | uint64_t       | R   | Section 5.8.2.10 |
   | fs_charset_cap     | 76 | uint32_t       | R   | Section 5.8.2.11 |
   | fs_layout_type     | 62 | layouttype4<>  | R   | Section 5.12.1   |
   | fs_locations       | 24 | fs_locations   | R   | Section 5.8.2.12 |
   | fs_locations_info  | 67 | *              | R   | Section 5.8.2.13 |
   | fs_status          | 61 | fs4_status     | R   | Section 5.8.2.14 |
   | hidden             | 25 | bool           | R W | Section 5.8.2.15 |
   | homogeneous        | 26 | bool           | R   | Section 5.8.2.16 |
   | layout_alignment   | 66 | uint32_t       | R   | Section 5.12.2   |
   | layout_blksize     | 65 | uint32_t       | R   | Section 5.12.3   |
   | layout_hint        | 63 | layouthint4    |   W | Section 5.12.4   |
   | layout_type        | 64 | layouttype4<>  | R   | Section 5.12.5   |
   | maxfilesize        | 27 | uint64_t       | R   | Section 5.8.2.17 |
   | maxlink            | 28 | uint32_t       | R   | Section 5.8.2.18 |
   | maxname            | 29 | uint32_t       | R   | Section 5.8.2.19 |
   | maxread            | 30 | uint64_t       | R   | Section 5.8.2.20 |
   | maxwrite           | 31 | uint64_t       | R   | Section 5.8.2.21 |
   | mdsthreshold       | 68 | mdsthreshold4  | R   | Section 5.12.6   |
   | mimetype           | 32 | utf8str_cs     | R W | Section 5.8.2.22 |
   | mode               | 33 | mode4          | R W | Section 6.2.4    |
   | mode_set_masked    | 74 | mode_masked4   |   W | Section 6.2.5    |
   | mounted_on_fileid  | 55 | uint64_t       | R   | Section 5.8.2.23 |
   | no_trunc           | 34 | bool           | R   | Section 5.8.2.24 |
   | numlinks           | 35 | uint32_t       | R   | Section 5.8.2.25 |
   | owner              | 36 | utf8str_mixed  | R W | Section 5.8.2.26 |
   | owner_group        | 37 | utf8str_mixed  | R W | Section 5.8.2.27 |
   | quota_avail_hard   | 38 | uint64_t       | R   | Section 5.8.2.28 |
   | quota_avail_soft   | 39 | uint64_t       | R   | Section 5.8.2.29 |
   | quota_used         | 40 | uint64_t       | R   | Section 5.8.2.30 |
   | rawdev             | 41 | specdata4      | R   | Section 5.8.2.31 |
   | retentevt_get      | 71 | retention_get4 | R   | Section 5.13.3   |
        
   | retentevt_set      | 72 | retention_set4 |   W | Section 5.13.4   |
   | retention_get      | 69 | retention_get4 | R   | Section 5.13.1   |
   | retention_hold     | 73 | uint64_t       | R W | Section 5.13.5   |
   | retention_set      | 70 | retention_set4 |   W | Section 5.13.2   |
   | sacl               | 59 | nfsacl41       | R W | Section 6.2.3    |
   | space_avail        | 42 | uint64_t       | R   | Section 5.8.2.32 |
   | space_free         | 43 | uint64_t       | R   | Section 5.8.2.33 |
   | space_total        | 44 | uint64_t       | R   | Section 5.8.2.34 |
   | space_used         | 45 | uint64_t       | R   | Section 5.8.2.35 |
   | system             | 46 | bool           | R W | Section 5.8.2.36 |
   | time_access        | 47 | nfstime4       | R   | Section 5.8.2.37 |
   | time_access_set    | 48 | settime4       |   W | Section 5.8.2.38 |
   | time_backup        | 49 | nfstime4       | R W | Section 5.8.2.39 |
   | time_create        | 50 | nfstime4       | R W | Section 5.8.2.40 |
   | time_delta         | 51 | nfstime4       | R   | Section 5.8.2.41 |
   | time_metadata      | 52 | nfstime4       | R   | Section 5.8.2.42 |
   | time_modify        | 53 | nfstime4       | R   | Section 5.8.2.43 |
   | time_modify_set    | 54 | settime4       |   W | Section 5.8.2.44 |
   +--------------------+----+----------------+-----+------------------+
        
   | retentevt_set      | 72 | retention_set4 |   W | Section 5.13.4   |
   | retention_get      | 69 | retention_get4 | R   | Section 5.13.1   |
   | retention_hold     | 73 | uint64_t       | R W | Section 5.13.5   |
   | retention_set      | 70 | retention_set4 |   W | Section 5.13.2   |
   | sacl               | 59 | nfsacl41       | R W | Section 6.2.3    |
   | space_avail        | 42 | uint64_t       | R   | Section 5.8.2.32 |
   | space_free         | 43 | uint64_t       | R   | Section 5.8.2.33 |
   | space_total        | 44 | uint64_t       | R   | Section 5.8.2.34 |
   | space_used         | 45 | uint64_t       | R   | Section 5.8.2.35 |
   | system             | 46 | bool           | R W | Section 5.8.2.36 |
   | time_access        | 47 | nfstime4       | R   | Section 5.8.2.37 |
   | time_access_set    | 48 | settime4       |   W | Section 5.8.2.38 |
   | time_backup        | 49 | nfstime4       | R W | Section 5.8.2.39 |
   | time_create        | 50 | nfstime4       | R W | Section 5.8.2.40 |
   | time_delta         | 51 | nfstime4       | R   | Section 5.8.2.41 |
   | time_metadata      | 52 | nfstime4       | R   | Section 5.8.2.42 |
   | time_modify        | 53 | nfstime4       | R   | Section 5.8.2.43 |
   | time_modify_set    | 54 | settime4       |   W | Section 5.8.2.44 |
   +--------------------+----+----------------+-----+------------------+
        

Table 3

表3

* fs_locations_info4

* 财政司司长(地点)资讯4

5.8. Attribute Definitions
5.8. 属性定义
5.8.1. Definitions of REQUIRED Attributes
5.8.1. 所需属性的定义
5.8.1.1. Attribute 0: supported_attrs
5.8.1.1. 属性0:受支持的属性

The bit vector that would retrieve all REQUIRED and RECOMMENDED attributes that are supported for this object. The scope of this attribute applies to all objects with a matching fsid.

将检索此对象支持的所有必需和推荐属性的位向量。此属性的范围适用于具有匹配fsid的所有对象。

5.8.1.2. Attribute 1: type
5.8.1.2. 属性1:类型

Designates the type of an object in terms of one of a number of special constants:

根据许多特殊常数中的一个指定对象的类型:

o NF4REG designates a regular file.

o NF4REG指定一个常规文件。

o NF4DIR designates a directory.

o NF4DIR指定一个目录。

o NF4BLK designates a block device special file.

o NF4BLK指定块设备专用文件。

o NF4CHR designates a character device special file.

o NF4CHR指定字符设备专用文件。

o NF4LNK designates a symbolic link.

o NF4LNK指定符号链接。

o NF4SOCK designates a named socket special file.

o NF4SOCK指定一个命名套接字特殊文件。

o NF4FIFO designates a fifo special file.

o NF4FIFO指定一个fifo特殊文件。

o NF4ATTRDIR designates a named attribute directory.

o NF4ATTRDIR指定一个命名的属性目录。

o NF4NAMEDATTR designates a named attribute.

o NF4NAMEDATTR指定一个命名属性。

Within the explanatory text and operation descriptions, the following phrases will be used with the meanings given below:

在解释性文本和操作说明中,将使用以下短语,其含义如下:

o The phrase "is a directory" means that the object's type attribute is NF4DIR or NF4ATTRDIR.

o 短语“is a directory”表示对象的type属性是NF4DIR或NF4ATTRDIR。

o The phrase "is a special file" means that the object's type attribute is NF4BLK, NF4CHR, NF4SOCK, or NF4FIFO.

o 短语“是一个特殊文件”表示对象的type属性是NF4BLK、NF4CHR、NF4SOCK或NF4FIFO。

o The phrases "is an ordinary file" and "is a regular file" mean that the object's type attribute is NF4REG or NF4NAMEDATTR.

o 短语“是普通文件”和“是常规文件”表示对象的type属性是NF4REG或NF4NAMEDATTR。

5.8.1.3. Attribute 2: fh_expire_type
5.8.1.3. 属性2:fh\u过期\u类型

Server uses this to specify filehandle expiration behavior to the client. See Section 4 for additional description.

服务器使用此选项为客户端指定文件句柄过期行为。更多说明见第4节。

5.8.1.4. Attribute 3: change
5.8.1.4. 属性3:变化

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 file system object cannot be updated more frequently than the resolution of time_metadata.

由服务器创建的值,客户端可使用该值确定对象的文件数据、目录内容或属性是否已修改。服务器可以为该属性的值返回对象的time_元数据属性,但仅当文件系统对象的更新频率不能超过time_元数据的解析频率时。

5.8.1.5. Attribute 4: size
5.8.1.5. 属性4:大小

The size of the object in bytes.

对象的大小(以字节为单位)。

5.8.1.6. Attribute 5: link_support
5.8.1.6. 属性5:链接支持

TRUE, if the object's file system supports hard links.

如果对象的文件系统支持硬链接,则为TRUE。

5.8.1.7. Attribute 6: symlink_support
5.8.1.7. 属性6:符号链接\u支持

TRUE, if the object's file system supports symbolic links.

如果对象的文件系统支持符号链接,则为TRUE。

5.8.1.8. Attribute 7: named_attr
5.8.1.8. 属性7:命名属性

TRUE, if this object has named attributes. In other words, object has a non-empty named attribute directory.

如果此对象具有命名属性,则为TRUE。换句话说,对象有一个非空的命名属性目录。

5.8.1.9. Attribute 8: fsid
5.8.1.9. 属性8:fsid

Unique file system identifier for the file system holding this object. The fsid attribute has major and minor components, each of which are of data type uint64_t.

保存此对象的文件系统的唯一文件系统标识符。fsid属性有主要和次要组件,每个组件都是数据类型uint64\u t。

5.8.1.10. Attribute 9: unique_handles
5.8.1.10. 属性9:唯一的_句柄

TRUE, if two distinct filehandles are guaranteed to refer to two different file system objects.

如果保证两个不同的文件句柄引用两个不同的文件系统对象,则为TRUE。

5.8.1.11. Attribute 10: lease_time
5.8.1.11. 属性10:租赁时间

Duration of the lease at server in seconds.

服务器上租约的持续时间(秒)。

5.8.1.12. Attribute 11: rdattr_error
5.8.1.12. 属性11:rdattr_错误

Error returned from an attempt to retrieve attributes during a READDIR operation.

在READDIR操作期间尝试检索属性时返回错误。

5.8.1.13. Attribute 19: filehandle
5.8.1.13. 属性19:文件句柄

The filehandle of this object (primarily for READDIR requests).

此对象的文件句柄(主要用于READDIR请求)。

5.8.1.14. Attribute 75: suppattr_exclcreat
5.8.1.14. 属性75:suppattr_excreat

The bit vector that would set all REQUIRED and RECOMMENDED attributes that are supported by the EXCLUSIVE4_1 method of file creation via the OPEN operation. The scope of this attribute applies to all objects with a matching fsid.

位向量,用于设置通过OPEN操作创建文件的EXCLUSIVE4_1方法所支持的所有必需和推荐属性。此属性的范围适用于具有匹配fsid的所有对象。

5.8.2. Definitions of Uncategorized RECOMMENDED Attributes
5.8.2. 未分类的推荐属性的定义

The definitions of most of the RECOMMENDED attributes follow. Collections that share a common category are defined in other sections.

大多数推荐属性的定义如下。共享公共类别的集合在其他部分中定义。

5.8.2.1. Attribute 14: archive
5.8.2.1. 属性14:存档

TRUE, if this file has been archived since the time of last modification (deprecated in favor of time_backup).

如果此文件自上次修改后已存档(不推荐使用time\u备份),则为TRUE。

5.8.2.2. Attribute 15: cansettime
5.8.2.2. 属性15:cansettime

TRUE, if the server is able to change the times for a file system object as specified in a SETATTR operation.

如果服务器能够更改SETATTR操作中指定的文件系统对象的时间,则为TRUE。

5.8.2.3. Attribute 16: case_insensitive
5.8.2.3. 属性16:不区分大小写

TRUE, if file name comparisons on this file system are case insensitive.

如果此文件系统上的文件名比较不区分大小写,则为TRUE。

5.8.2.4. Attribute 17: case_preserving
5.8.2.4. 属性17:保留大小写

TRUE, if file name case on this file system is preserved.

如果保留此文件系统上的文件名大小写,则为TRUE。

5.8.2.5. Attribute 60: change_policy
5.8.2.5. 属性60:更改策略

A value created by the server that the client can use to determine if some server policy related to the current file system has been subject to change. If the value remains the same, then the client can be sure that the values of the attributes related to fs location and the fss_type field of the fs_status attribute have not changed. On the other hand, a change in this value does necessarily imply a change in policy. It is up to the client to interrogate the server to determine if some policy relevant to it has changed. See Section 3.3.6 for details.

由服务器创建的值,客户端可使用该值确定与当前文件系统相关的某些服务器策略是否已更改。如果该值保持不变,则客户端可以确保与fs location相关的属性值和fs_status属性的fss_类型字段没有更改。另一方面,该值的变化必然意味着政策的变化。由客户机询问服务器,以确定与服务器相关的某些策略是否已更改。详见第3.3.6节。

This attribute MUST change when the value returned by the fs_locations or fs_locations_info attribute changes, when a file system goes from read-only to writable or vice versa, or when the allowable set of security flavors for the file system or any part thereof is changed.

当fs_locations或fs_locations_info属性返回的值更改时,当文件系统从只读变为可写时,或者当文件系统或其任何部分的允许安全样式集更改时,此属性必须更改。

5.8.2.6. Attribute 18: chown_restricted
5.8.2.6. 属性18:chown_受限

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 "Take Ownership" privilege).

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

5.8.2.7. Attribute 20: fileid
5.8.2.7. 属性20:fileid

A number uniquely identifying the file within the file system.

在文件系统中唯一标识文件的编号。

5.8.2.8. Attribute 21: files_avail
5.8.2.8. 属性21:文件\u可用

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

此用户在包含此对象的文件系统上可用的文件槽——这应该是最小的相关限制。

5.8.2.9. Attribute 22: files_free
5.8.2.9. 属性22:免费文件

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

包含此对象的文件系统上的可用文件插槽——这应该是最小的相关限制。

5.8.2.10. Attribute 23: files_total
5.8.2.10. 属性23:文件总数

Total file slots on the file system containing this object.

包含此对象的文件系统上的文件插槽总数。

5.8.2.11. Attribute 76: fs_charset_cap
5.8.2.11. 属性76:fs\u charset\u cap

Character set capabilities for this file system. See Section 14.4.

此文件系统的字符集功能。见第14.4节。

5.8.2.12. Attribute 24: fs_locations
5.8.2.12. 属性24:fs_位置

Locations where this file system may be found. If the server returns NFS4ERR_MOVED as an error, this attribute MUST be supported. See Section 11.9 for more details.

可以找到此文件系统的位置。如果服务器返回NFS4ERR_MOVED作为错误,则必须支持此属性。详见第11.9节。

5.8.2.13. Attribute 67: fs_locations_info
5.8.2.13. 属性67:fs\u位置\u信息

Full function file system location. See Section 11.10 for more details.

全功能文件系统位置。详见第11.10节。

5.8.2.14. Attribute 61: fs_status
5.8.2.14. 属性61:fs_状态

Generic file system type information. See Section 11.11 for more details.

通用文件系统类型信息。详见第11.11节。

5.8.2.15. Attribute 25: hidden
5.8.2.15. 属性25:隐藏

TRUE, if the file is considered hidden with respect to the Windows API.

如果文件相对于Windows API被认为是隐藏的,则为TRUE。

5.8.2.16. Attribute 26: homogeneous
5.8.2.16. 属性26:同质

TRUE, if this object's file system is homogeneous; i.e., all objects in the file system (all objects on the server with the same fsid) have common values for all per-file-system attributes.

如果此对象的文件系统是同构的,则为TRUE;i、 例如,文件系统中的所有对象(服务器上具有相同fsid的所有对象)都具有每个文件系统属性的公共值。

5.8.2.17. Attribute 27: maxfilesize
5.8.2.17. 属性27:maxfilesize

Maximum supported file size for the file system of this object.

此对象的文件系统支持的最大文件大小。

5.8.2.18. Attribute 28: maxlink
5.8.2.18. 属性28:maxlink

Maximum number of links for this object.

此对象的最大链接数。

5.8.2.19. Attribute 29: maxname
5.8.2.19. 属性29:maxname

Maximum file name size supported for this object.

此对象支持的最大文件名大小。

5.8.2.20. Attribute 30: maxread
5.8.2.20. 属性30:maxread

Maximum amount of data the READ operation will return for this object.

读取操作将为此对象返回的最大数据量。

5.8.2.21. Attribute 31: maxwrite
5.8.2.21. 属性31:maxwrite

Maximum amount of data the WRITE operation will accept 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.

写入操作将为此对象接受的最大数据量。如果文件可写,则应支持此属性。缺少此属性可能会导致客户端浪费带宽或无法获得最佳性能。

5.8.2.22. Attribute 32: mimetype
5.8.2.22. 属性32:mimetype

MIME body type/subtype of this object.

此对象的MIME主体类型/子类型。

5.8.2.23. Attribute 55: mounted_on_fileid
5.8.2.23. 属性55:在\u文件ID上装入\u

Like fileid, but if the target filehandle is the root of a file system, this attribute represents the fileid of the underlying directory.

类似于fileid,但如果目标filehandle是文件系统的根,则此属性表示基础目录的fileid。

UNIX-based operating environments connect a file system into the namespace by connecting (mounting) the file system onto the existing file object (the mount point, usually a directory) of an existing file system. 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 file system, whereas readdir() is returning the fileid that stat() would have returned before any file systems were mounted on the mount point.

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

Unlike NFSv3, NFSv4.1 allows a client's LOOKUP request to cross other file systems. The client detects the file system 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.

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

While the NFSv4.1 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 file system. Instead, if the server can provide the mounted_on_fileid, the potential for client operational problems in this area is eliminated.

虽然NFSv4.1客户端可以简单地创建一个与mounted_on_fileid提供的内容相对应的fileid(如果服务器不支持mounted_on_fileid,则客户端别无选择),但存在这样的风险,即客户端将生成一个与已分配给文件系统中另一个对象的文件id冲突的文件id。相反,如果服务器可以提供挂载的\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 file systems 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()将返回的值。某些操作环境允许将一系列两个或多个文件系统装载到单个装载点上。在这种情况下,为了使服务器遵守上述不变量,它需要找到基本装载点,而不是中间装载点。

5.8.2.24. Attribute 34: no_trunc
5.8.2.24. 属性34:不正确

If this attribute is TRUE, then if the client uses a file name longer than name_max, an error will be returned instead of the name being truncated.

如果此属性为TRUE,则如果客户端使用的文件名长于name_max,则将返回错误,而不是截断名称。

5.8.2.25. Attribute 35: numlinks
5.8.2.25. 属性35:numlinks

Number of hard links to this object.

指向此对象的硬链接数。

5.8.2.26. Attribute 36: owner
5.8.2.26. 属性36:所有者

The string name of the owner of this object.

此对象所有者的字符串名称。

5.8.2.27. Attribute 37: owner_group
5.8.2.27. 属性37:所有者组

The string name of the group ownership of this object.

此对象的组所有权的字符串名称。

5.8.2.28. Attribute 38: quota_avail_hard
5.8.2.28. 属性38:quota\u avail\u hard

The value in bytes that represents 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.

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

5.8.2.29. Attribute 39: quota_avail_soft
5.8.2.29. 属性39:quota\u avail\u soft

The value in bytes that 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.

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

5.8.2.30. Attribute 40: quota_used
5.8.2.30. 属性40:使用的配额

The value in bytes that represents the amount of disk 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.

以字节为单位的值,表示此文件或目录以及可能的许多其他类似文件或目录所使用的磁盘空间量,其中“相似”集合至少满足将空间分配给集合中的任何文件或目录将减少集合中每个其他文件或目录的“配额利用率”。

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 when providing the content of the quota_used attribute, but should do so in a repeatable way. The rule may be configured per file system or may be "choose the set with the smallest quota".

请注意,可能存在许多不同但重叠的文件或目录集,为这些文件或目录保留配额使用值,例如,“具有给定所有者的所有文件”、“具有给定组所有者的所有文件”等。在提供配额使用属性的内容时,服务器可以自由选择这些文件或目录集中的任何一个,但应该以可重复的方式这样做。规则可以按文件系统配置,也可以是“选择配额最小的集合”。

5.8.2.31. Attribute 41: rawdev
5.8.2.31. 属性41:rawdev

Raw device number of file of type NF4BLK or NF4CHR. The device number is split into major and minor numbers. If the file's type attribute is not NF4BLK or NF4CHR, the value returned SHOULD NOT be considered useful.

NF4BLK或NF4CHR类型文件的原始设备号。设备编号分为主要编号和次要编号。如果文件的type属性不是NF4BLK或NF4CHR,则返回的值不应视为有用。

5.8.2.32. Attribute 42: space_avail
5.8.2.32. 属性42:空间可用性

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

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

5.8.2.33. Attribute 43: space_free
5.8.2.33. 属性43:无空间

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

包含此对象的文件系统上的可用磁盘空间(以字节为单位)——这应该是最小的相关限制。

5.8.2.34. Attribute 44: space_total
5.8.2.34. 属性44:总空间

Total disk space in bytes on the file system containing this object.

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

5.8.2.35. Attribute 45: space_used
5.8.2.35. 属性45:使用的空间

Number of file system bytes allocated to this object.

分配给此对象的文件系统字节数。

5.8.2.36. Attribute 46: system
5.8.2.36. 属性46:系统

This attribute is TRUE if this file is a "system" file with respect to the Windows operating environment.

如果此文件是相对于Windows操作环境的“系统”文件,则此属性为TRUE。

5.8.2.37. Attribute 47: time_access
5.8.2.37. 属性47:访问时间

The time_access attribute represents the time of last access to the object by a READ operation sent to the server. The notion of what is an "access" depends on the server's operating environment and/or the server's file system semantics. For example, for servers obeying Portable Operating System Interface (POSIX) semantics, time_access would be updated only by the READ and READDIR operations and not any of the operations that modify the content of the object [16], [17], [18]. Of course, setting the corresponding time_access_set attribute is another way to modify the time_access attribute.

time_access属性表示通过发送到服务器的读取操作上次访问对象的时间。什么是“访问”的概念取决于服务器的操作环境和/或服务器的文件系统语义。例如,对于遵循可移植操作系统接口(POSIX)语义的服务器,time_访问将仅由READ和READDIR操作更新,而不是任何修改对象内容的操作[16]、[17]、[18]。当然,设置相应的time\u access\u set属性是修改time\u access属性的另一种方法。

Whenever the file object resides on a writable file system, the server should make its 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.2.38. Attribute 48: time_access_set
5.8.2.38. 属性48:时间访问集

Sets the time of last access to the object. SETATTR use only.

设置上次访问对象的时间。SETATTR仅用于。

5.8.2.39. Attribute 49: time_backup
5.8.2.39. 属性49:时间备份

The time of last backup of the object.

上次备份对象的时间。

5.8.2.40. Attribute 50: time_create
5.8.2.40. 属性50:创建时间

The time of creation of the object. This attribute does not have any relation to the traditional UNIX file attribute "ctime" or "change time".

对象的创建时间。此属性与传统的UNIX文件属性“ctime”或“更改时间”没有任何关系。

5.8.2.41. Attribute 51: time_delta
5.8.2.41. 属性51:时间增量

Smallest useful server time granularity.

最小有用的服务器时间粒度。

5.8.2.42. Attribute 52: time_metadata
5.8.2.42. 属性52:时间元数据

The time of last metadata modification of the object.

上次修改对象元数据的时间。

5.8.2.43. Attribute 53: time_modify
5.8.2.43. 属性53:时间\修改

The time of last modification to the object.

上次修改对象的时间。

5.8.2.44. Attribute 54: time_modify_set
5.8.2.44. 属性54:时间\修改\集

Sets the time of last modification to the object. SETATTR use only.

设置上次修改对象的时间。SETATTR仅用于。

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

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 RFC 2624 [45] 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, 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字符串。请注意,RFC 2624[45]第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 a numeric identifier 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.

用于解释所有者和组字符串的转换未指定为协议的一部分。这允许采用各种解决方案。例如,可以参考将数字标识符映射到本地的本地翻译表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 (including changes from the mapping of the string to the local representation) and ill-constructed name translations (those that contain 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.

当显示没有翻译的字符串时,不支持所有者和所有者组属性的所有可能值的服务器应返回一个错误(NFS4ERR\u BADOWNER),作为要为所有者、所有者组或acl属性的SETATTR设置的值。当服务器确实接受在SETATTR上有效的owner或owner\u group值(对于acl中的owner和group字符串也是如此)时,它承诺在完成相应的GETATTR时返回相同的字符串。配置更改(包括从字符串映射到本地表示的更改)和构造错误的名称转换(那些包含别名的转换)可能会使这一承诺无法兑现。服务器应该做出适当的努力,避免在所有权没有发生实际变化的情况下,这些属性的值发生变化。

The "dns_domain" portion of the owner string is meant to be a DNS domain name, for example, user@example.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@example.org. 服务器应接受至少一个域的一组用户作为有效用户。服务器可能会将其他域视为没有有效的翻译。当服务器能够接受多个域或所有域的用户时,会提供更一般的服务,但会受到安全约束。

In the case where there is no translation available to the client or server, the attribute value will 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 cannot 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 NFSv3, which identified users and groups by 32-bit unsigned user identifiers and group identifiers, owner and group strings that consist of decimal numeric values with no leading zeros can be given a special interpretation by clients and servers that 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 an NFSv3 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.

NFSv3通过32位无符号用户标识符和组标识符来标识用户和组,为了与NFSv3提供更大程度的兼容性,选择提供此类支持的客户端和服务器可以对由十进制数值组成的所有者和组字符串(不带前导零)进行特殊解释。接收方可以将这样的用户或组字符串视为表示将由具有相应数值的NFSv3 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. Users and implementations of NFSv4.1 SHOULD NOT use "nobody" to designate a real user whose access is not anonymous.

所有者字符串“nobody”可用于指定匿名用户,该用户将与安全主体创建的文件关联,该文件无法通过正常方式映射到所有者属性。NFSv4.1的用户和实现不应使用“nobody”来指定访问权限不是匿名的真实用户。

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

With respect to the case_insensitive and case_preserving attributes, each UCS-4 character (which UTF-8 encodes) can be mapped according to Appendix B.2 of RFC 3454 [19]. For general character handling and internationalization issues, see Section 14.

关于不区分大小写和保留大小写属性,每个UCS-4字符(UTF-8编码)可以根据RFC 3454[19]的附录B.2进行映射。有关一般字符处理和国际化问题,请参见第14节。

5.11. Directory Notification Attributes
5.11. 目录通知属性

As described in Section 18.39, the client can request a minimum delay for notifications of changes to attributes, but the server is free to ignore what the client requests. The client can determine in advance what notification delays the server will accept by sending a GETATTR operation for either or both of two directory notification attributes. When the client calls the GET_DIR_DELEGATION operation and asks for attribute change notifications, it should request notification delays that are no less than the values in the server-provided attributes.

如第18.39节所述,客户端可以请求属性更改通知的最小延迟,但服务器可以自由忽略客户端请求的内容。客户端可以通过为两个目录通知属性中的一个或两个属性发送GETATTR操作,预先确定服务器将接受的通知延迟。当客户端调用GET_DIR_委派操作并请求属性更改通知时,它应该请求不小于服务器提供的属性中的值的通知延迟。

5.11.1. Attribute 56: dir_notif_delay
5.11.1. 属性56:dir\u notif\u delay

The dir_notif_delay attribute is the minimum number of seconds the server will delay before notifying the client of a change to the directory's attributes.

dir_notif_delay属性是服务器在通知客户端目录属性的更改之前延迟的最小秒数。

5.11.2. Attribute 57: dirent_notif_delay
5.11.2. 属性57:dirent\u notif\u delay

The dirent_notif_delay attribute is the minimum number of seconds the server will delay before notifying the client of a change to a file object that has an entry in the directory.

dirent_notif_delay属性是服务器在通知客户端对目录中包含条目的文件对象所做的更改之前延迟的最短秒数。

5.12. pNFS Attribute Definitions
5.12. pNFS属性定义
5.12.1. Attribute 62: fs_layout_type
5.12.1. 属性62:fs_布局_类型

The fs_layout_type attribute (see Section 3.3.13) applies to a file system and indicates what layout types are supported by the file system. When the client encounters a new fsid, the client SHOULD obtain the value for the fs_layout_type attribute associated with the new file system. This attribute is used by the client to determine if the layout types supported by the server match any of the client's supported layout types.

fs_layout_type属性(参见第3.3.13节)适用于文件系统,并指示文件系统支持哪些布局类型。当客户端遇到新的fsid时,客户端应获取与新文件系统关联的fs_layout_type属性的值。客户端使用此属性确定服务器支持的布局类型是否与客户端支持的任何布局类型匹配。

5.12.2. Attribute 66: layout_alignment
5.12.2. 属性66:布局与对齐

When a client holds layouts on files of a file system, the layout_alignment attribute indicates the preferred alignment for I/O to files on that file system. Where possible, the client should send READ and WRITE operations with offsets that are whole multiples of the layout_alignment attribute.

当客户端在文件系统的文件上保存布局时,“布局对齐”属性表示I/O与该文件系统上文件的首选对齐方式。在可能的情况下,客户端应发送带有偏移量的读写操作,偏移量是布局对齐属性的整数倍。

5.12.3. Attribute 65: layout_blksize
5.12.3. 属性65:layout_blksize

When a client holds layouts on files of a file system, the layout_blksize attribute indicates the preferred block size for I/O to files on that file system. Where possible, the client should send READ operations with a count argument that is a whole multiple of layout_blksize, and WRITE operations with a data argument of size that is a whole multiple of layout_blksize.

当客户端在文件系统的文件上保存布局时,layout_blksize属性表示该文件系统上文件的I/O首选块大小。在可能的情况下,客户端应发送读取操作和写入操作,读取操作的count参数是layout_blksize的整数倍,写入操作的data参数是layout_blksize的整数倍。

5.12.4. Attribute 63: layout_hint
5.12.4. 属性63:布局提示

The layout_hint attribute (see Section 3.3.19) may be set on newly created files to influence the metadata server's choice for the file's layout. If possible, this attribute is one of those set in the initial attributes within the OPEN operation. The metadata server may choose to ignore this attribute. The layout_hint attribute is a subset of the layout structure returned by LAYOUTGET. For example, instead of specifying particular devices, this would be used to suggest the stripe width of a file. The server implementation determines which fields within the layout will be used.

布局提示属性(见第3.3.19节)可设置在新创建的文件上,以影响元数据服务器对文件布局的选择。如果可能,此属性是打开操作中初始属性中设置的属性之一。元数据服务器可以选择忽略此属性。layout_hint属性是LAYOUTGET返回的布局结构的子集。例如,这将用于建议文件的条带宽度,而不是指定特定的设备。服务器实现决定将使用布局中的哪些字段。

5.12.5. Attribute 64: layout_type
5.12.5. 属性64:布局类型

This attribute lists the layout type(s) available for a file. The value returned by the server is for informational purposes only. The client will use the LAYOUTGET operation to obtain the information needed in order to perform I/O, for example, the specific device information for the file and its layout.

此属性列出文件可用的布局类型。服务器返回的值仅供参考。客户端将使用LAYOUTGET操作获取执行I/O所需的信息,例如,文件及其布局的特定设备信息。

5.12.6. Attribute 68: mdsthreshold
5.12.6. 属性68:mdsthreshold

This attribute is a server-provided hint used to communicate to the client when it is more efficient to send READ and WRITE operations to the metadata server or the data server. The two types of thresholds described are file size thresholds and I/O size thresholds. If a file's size is smaller than the file size threshold, data accesses SHOULD be sent to the metadata server. If an I/O request has a length that is below the I/O size threshold, the I/O SHOULD be sent to the metadata server. Each threshold type is specified separately for read and write.

此属性是服务器提供的提示,用于在向元数据服务器或数据服务器发送读写操作更有效时与客户端通信。描述的两种阈值类型是文件大小阈值和I/O大小阈值。如果文件大小小于文件大小阈值,则应将数据访问发送到元数据服务器。如果I/O请求的长度低于I/O大小阈值,则应将I/O发送到元数据服务器。每个阈值类型都分别指定用于读取和写入。

The server MAY provide both types of thresholds for a file. If both file size and I/O size are provided, the client SHOULD reach or exceed both thresholds before sending its read or write requests to the data server. Alternatively, if only one of the specified thresholds is reached or exceeded, the I/O requests are sent to the metadata server.

服务器可以为文件提供两种类型的阈值。如果同时提供了文件大小和I/O大小,则客户端在向数据服务器发送读或写请求之前应达到或超过这两个阈值。或者,如果仅达到或超过一个指定的阈值,则向元数据服务器发送I/O请求。

For each threshold type, a value of zero indicates no READ or WRITE should be sent to the metadata server, while a value of all ones indicates that all READs or WRITEs should be sent to the metadata server.

对于每个阈值类型,值为零表示不应向元数据服务器发送读取或写入,而值为all表示应向元数据服务器发送所有读取或写入。

The attribute is available on a per-filehandle basis. If the current filehandle refers to a non-pNFS file or directory, the metadata server should return an attribute that is representative of the filehandle's file system. It is suggested that this attribute is queried as part of the OPEN operation. Due to dynamic system changes, the client should not assume that the attribute will remain constant for any specific time period; thus, it should be periodically refreshed.

该属性在每个文件句柄的基础上可用。如果当前文件句柄引用非pNFS文件或目录,则元数据服务器应返回代表文件句柄文件系统的属性。建议将此属性作为打开操作的一部分进行查询。由于系统动态变化,客户不应假设属性在任何特定时间段内保持不变;因此,它应该定期刷新。

5.13. Retention Attributes
5.13. 保留属性

Retention is a concept whereby a file object can be placed in an immutable, undeletable, unrenamable state for a fixed or infinite duration of time. Once in this "retained" state, the file cannot be moved out of the state until the duration of retention has been reached.

保留是一个概念,在此概念中,文件对象可以在固定或无限的时间内处于不可变、不可删除、不可更改的状态。一旦处于此“保留”状态,在达到保留期限之前,无法将文件移出该状态。

When retention is enabled, retention MUST extend to the data of the file, and the name of file. The server MAY extend retention to any other property of the file, including any subset of REQUIRED, RECOMMENDED, and named attributes, with the exceptions noted in this section.

启用保留后,保留必须扩展到文件的数据和文件名。服务器可以将保留扩展到文件的任何其他属性,包括必需、推荐和命名属性的任何子集,但本节中指出的例外情况除外。

Servers MAY support or not support retention on any file object type.

服务器可能支持或不支持对任何文件对象类型的保留。

The five retention attributes are explained in the next subsections.

下面的小节将解释这五个保留属性。

5.13.1. Attribute 69: retention_get
5.13.1. 属性69:保留时间

If retention is enabled for the associated file, this attribute's value represents the retention begin time of the file object. This attribute's value is only readable with the GETATTR operation and MUST NOT be modified by the SETATTR operation (Section 5.5). The value of the attribute consists of:

如果为关联文件启用了保留,则此属性的值表示文件对象的保留开始时间。此属性的值只能通过GETATTR操作读取,并且不能通过SETATTR操作修改(第5.5节)。该属性的值包括:

   const RET4_DURATION_INFINITE    = 0xffffffffffffffff;
   struct retention_get4 {
           uint64_t        rg_duration;
           nfstime4        rg_begin_time<1>;
   };
        
   const RET4_DURATION_INFINITE    = 0xffffffffffffffff;
   struct retention_get4 {
           uint64_t        rg_duration;
           nfstime4        rg_begin_time<1>;
   };
        

The field rg_duration is the duration in seconds indicating how long the file will be retained once retention is enabled. The field rg_begin_time is an array of up to one absolute time value. If the array is zero length, no beginning retention time has been established, and retention is not enabled. If rg_duration is equal to RET4_DURATION_INFINITE, the file, once retention is enabled, will be retained for an infinite duration.

字段rg_duration是以秒为单位的持续时间,指示启用保留后文件将保留多长时间。字段rg_begin_time是一个最多包含一个绝对时间值的数组。如果阵列长度为零,则未建立起始保留时间,并且未启用保留。如果rg_duration等于RET4_duration_INFINITE,则启用保留后,该文件将保留无限期。

If (as soon as) rg_duration is zero, then rg_begin_time will be of zero length, and again, retention is not (no longer) enabled.

如果(一旦)rg_持续时间为零,则rg_开始时间的长度为零,并且再次说明,未(不再)启用保留。

5.13.2. Attribute 70: retention_set
5.13.2. 属性70:保留集

This attribute is used to set the retention duration and optionally enable retention for the associated file object. This attribute is only modifiable via the SETATTR operation and MUST NOT be retrieved by the GETATTR operation (Section 5.5). This attribute corresponds to retention_get. The value of the attribute consists of:

此属性用于设置保留期限,并可选地启用关联文件对象的保留。此属性只能通过SETATTR操作进行修改,不能通过GETATTR操作进行检索(第5.5节)。此属性对应于保留时间。该属性的值包括:

   struct retention_set4 {
           bool            rs_enable;
           uint64_t        rs_duration<1>;
   };
        
   struct retention_set4 {
           bool            rs_enable;
           uint64_t        rs_duration<1>;
   };
        

If the client sets rs_enable to TRUE, then it is enabling retention on the file object with the begin time of retention starting from the server's current time and date. The duration of the retention can also be provided if the rs_duration array is of length one. The duration is the time in seconds from the begin time of retention, and if set to RET4_DURATION_INFINITE, the file is to be retained forever. If retention is enabled, with no duration specified in either this SETATTR or a previous SETATTR, the duration defaults to zero seconds. The server MAY restrict the enabling of retention or the duration of retention on the basis of the ACE4_WRITE_RETENTION ACL permission.

如果客户端将rs_enable设置为TRUE,则它将启用文件对象上的保留,保留开始时间从服务器的当前时间和日期开始。如果rs_duration数组的长度为1,则还可以提供保留的持续时间。持续时间是从开始保留时间算起的时间(秒),如果设置为RET4_duration_INFINITE,则文件将永久保留。如果启用了保留,并且在此SETATTR或以前的SETATTR中未指定持续时间,则持续时间默认为零秒。服务器可以根据ACE4_WRITE_retention ACL权限限制保留的启用或保留的持续时间。

The enabling of retention MUST NOT prevent the enabling of event-based retention or the modification of the retention_hold attribute.

启用保留不得阻止启用基于事件的保留或修改保留保留保留属性。

The following rules apply to both the retention_set and retentevt_set attributes.

以下规则适用于retention_集和retentevt_集属性。

o As long as retention is not enabled, the client is permitted to decrease the duration.

o 只要未启用保留,就允许客户端缩短持续时间。

o The duration can always be set to an equal or higher value, even if retention is enabled. Note that once retention is enabled, the actual duration (as returned by the retention_get or retentevt_get attributes; see Section 5.13.1 or Section 5.13.3) is constantly counting down to zero (one unit per second), unless the duration was set to RET4_DURATION_INFINITE. Thus, it will not be possible for the client to precisely extend the duration on a file that has retention enabled.

o 持续时间始终可以设置为相等或更高的值,即使启用了保留。请注意,启用保留后,实际持续时间(由retention_get或retentevt_get属性返回;请参阅第5.13.1节或第5.13.3节)将持续倒计时到零(每秒一个单位),除非持续时间设置为RET4_duration_INFINITE。因此,客户机不可能精确地延长启用了保留的文件的持续时间。

o While retention is enabled, attempts to disable retention or decrease the retention's duration MUST fail with the error NFS4ERR_INVAL.

o 启用保留时,禁用保留或缩短保留时间的尝试必须失败,错误为NFS4ERR_INVAL。

o If the principal attempting to change retention_set or retentevt_set does not have ACE4_WRITE_RETENTION permissions, the attempt MUST fail with NFS4ERR_ACCESS.

o 如果试图更改保留集或retentevt集的主体没有ACE4写入保留权限,则必须使用NFS4ERR\u访问权限失败。

5.13.3. Attribute 71: retentevt_get
5.13.3. 属性71:retentevt_get

Gets the event-based retention duration, and if enabled, the event-based retention begin time of the file object. This attribute is like retention_get, but refers to event-based retention. The event that triggers event-based retention is not defined by the NFSv4.1 specification.

获取基于事件的保留持续时间,如果启用,则获取文件对象的基于事件的保留开始时间。此属性类似于retention_get,但指基于事件的保留。NFSv4.1规范未定义触发基于事件的保留的事件。

5.13.4. Attribute 72: retentevt_set
5.13.4. 属性72:retentevt_集

Sets the event-based retention duration, and optionally enables event-based retention on the file object. This attribute corresponds to retentevt_get and is like retention_set, but refers to event-based retention. When event-based retention is set, the file MUST be retained even if non-event-based retention has been set, and the duration of non-event-based retention has been reached. Conversely, when non-event-based retention has been set, the file MUST be retained even if event-based retention has been set, and the duration of event-based retention has been reached. The server MAY restrict the enabling of event-based retention or the duration of event-based retention on the basis of the ACE4_WRITE_RETENTION ACL permission. The enabling of event-based retention MUST NOT prevent the enabling of non-event-based retention or the modification of the retention_hold attribute.

设置基于事件的保留期限,并可以选择对文件对象启用基于事件的保留。此属性对应于retentevt_get,类似于retention_set,但指基于事件的保留。设置基于事件的保留时,即使已设置非基于事件的保留,并且已达到非基于事件的保留期限,也必须保留文件。相反,如果已设置非基于事件的保留,则即使已设置基于事件的保留,并且已达到基于事件的保留期限,也必须保留文件。服务器可以基于ACE4_WRITE_retention ACL权限限制基于事件的保留的启用或基于事件的保留的持续时间。启用基于事件的保留不得阻止启用非基于事件的保留或修改保留保留保留属性。

5.13.5. Attribute 73: retention_hold
5.13.5. 属性73:保留/保留

Gets or sets administrative retention holds, one hold per bit position.

获取或设置管理保留挂起,每位位置一个挂起。

This attribute allows one to 64 administrative holds, one hold per bit on the attribute. If retention_hold is not zero, then the file MUST NOT be deleted, renamed, or modified, even if the duration on enabled event or non-event-based retention has been reached. The server MAY restrict the modification of retention_hold on the basis of the ACE4_WRITE_RETENTION_HOLD ACL permission. The enabling of administration retention holds does not prevent the enabling of event-based or non-event-based retention.

此属性允许一到64个管理保留,属性上每一位一个保留。如果保留时间不为零,则不得删除、重命名或修改文件,即使已达到启用事件或非基于事件的保留的持续时间。服务器可以基于ACE4\u写入\u保留\u保留ACL权限限制对保留\u保留的修改。启用管理保留保留不会阻止启用基于事件或非基于事件的保留。

If the principal attempting to change retention_hold does not have ACE4_WRITE_RETENTION_HOLD permissions, the attempt MUST fail with NFS4ERR_ACCESS.

如果尝试更改保留\u保持的主体没有ACE4\u写入\u保留\u保持权限,则必须通过NFS4ERR\u访问失败。

6. Access Control Attributes
6. 访问控制属性

Access Control Lists (ACLs) are file attributes that specify fine-grained access control. This section covers the "acl", "dacl", "sacl", "aclsupport", "mode", and "mode_set_masked" file attributes and their interactions. Note that file attributes may apply to any file system object.

访问控制列表(ACL)是指定细粒度访问控制的文件属性。本节介绍“acl”、“dacl”、“sacl”、“aclsupport”、“mode”和“mode\u set\u masked”文件属性及其交互。请注意,文件属性可以应用于任何文件系统对象。

6.1. Goals
6.1. 目标

ACLs and modes represent two well-established models for specifying permissions. This section specifies requirements that attempt to meet the following goals:

ACL和模式代表两种用于指定权限的成熟模型。本节规定了试图达到以下目标的要求:

o If a server supports the mode attribute, it should provide reasonable semantics to clients that only set and retrieve the mode attribute.

o 如果服务器支持mode属性,那么它应该为只设置和检索mode属性的客户端提供合理的语义。

o If a server supports ACL attributes, it should provide reasonable semantics to clients that only set and retrieve those attributes.

o 如果服务器支持ACL属性,它应该为只设置和检索这些属性的客户端提供合理的语义。

o On servers that support the mode attribute, if ACL attributes have never been set on an object, via inheritance or explicitly, the behavior should be traditional UNIX-like behavior.

o 在支持mode属性的服务器上,如果从未通过继承或显式在对象上设置过ACL属性,则该行为应为传统的类UNIX行为。

o On servers that support the mode attribute, if the ACL attributes have been previously set on an object, either explicitly or via inheritance:

o 在支持mode属性的服务器上,如果先前已显式或通过继承在对象上设置了ACL属性,请执行以下操作:

* Setting only the mode attribute should effectively control the traditional UNIX-like permissions of read, write, and execute on owner, owner_group, and other.

* 仅设置mode属性应该可以有效地控制对owner、owner\u组和其他对象的读、写和执行的传统类UNIX权限。

* Setting only the mode attribute should provide reasonable security. For example, setting a mode of 000 should be enough to ensure that future OPEN operations for OPEN4_SHARE_ACCESS_READ or OPEN4_SHARE_ACCESS_WRITE by any principal fail, regardless of a previously existing or inherited ACL.

* 仅设置mode属性应提供合理的安全性。例如,将模式设置为000应该足以确保任何主体对OPEN4_SHARE_ACCESS_READ或OPEN4_SHARE_ACCESS_WRITE的未来打开操作失败,而不考虑以前存在或继承的ACL。

o NFSv4.1 may introduce different semantics relating to the mode and ACL attributes, but it does not render invalid any previously existing implementations. Additionally, this section provides clarifications based on previous implementations and discussions around them.

o NFSv4.1可能会引入与模式和ACL属性相关的不同语义,但它不会使任何以前存在的实现无效。此外,本节还基于以前的实现和讨论提供了说明。

o On servers that support both the mode and the acl or dacl attributes, the server must keep the two consistent with each other. The value of the mode attribute (with the exception of the three high-order bits described in Section 6.2.4) must be determined entirely by the value of the ACL, so that use of the mode is never required for anything other than setting the three high-order bits. See Section 6.4.1 for exact requirements.

o 在同时支持模式和acl或dacl属性的服务器上,服务器必须使两者保持一致。模式属性的值(第6.2.4节中所述的三个高阶位除外)必须完全由ACL的值确定,因此除了设置三个高阶位外,任何事情都不需要使用模式。具体要求见第6.4.1节。

o When a mode attribute is set on an object, the ACL attributes may need to be modified in order to not conflict with the new mode. In such cases, it is desirable that the ACL keep as much information as possible. This includes information about inheritance, AUDIT and ALARM ACEs, and permissions granted and denied that do not conflict with the new mode.

o 在对象上设置模式属性时,可能需要修改ACL属性以避免与新模式冲突。在这种情况下,希望ACL保留尽可能多的信息。这包括有关继承、审核和报警ACE的信息,以及授予和拒绝的与新模式不冲突的权限。

6.2. File Attributes Discussion
6.2. 文件属性讨论
6.2.1. Attribute 12: acl
6.2.1. 属性12:acl

The NFSv4.1 ACL attribute contains an array of Access Control Entries (ACEs) that are associated with the file system object. Although the client can set and get the acl attribute, the server is responsible for using the ACL to perform access control. The client can use the OPEN or ACCESS operations to check access without modifying or reading data or metadata.

NFSv4.1 ACL属性包含与文件系统对象关联的访问控制项(ACE)数组。虽然客户端可以设置并获取acl属性,但服务器负责使用acl执行访问控制。客户端可以使用OPEN或ACCESS操作来检查访问,而无需修改或读取数据或元数据。

The NFS ACE structure is defined as follows:

NFS ACE结构定义如下:

typedef uint32_t acetype4;

typedef uint32_t acetype4;

typedef uint32_t aceflag4;

typedef uint32_t aceflag4;

typedef uint32_t acemask4;

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, the server processes each nfsace4 entry in order. Only ACEs that 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. When the ACL is fully processed, if there are bits in the requester's mask that have not been ALLOWED or DENIED, access is denied.

为了确定请求是否成功,服务器按顺序处理每个nfsace4条目。仅考虑具有与请求者匹配的“谁”的ACE。处理每个ACE,直到请求者访问的所有位都被允许。一旦一个位(见下文)被一个允许访问的ACE允许,它就不再被考虑在以后的ACE处理中。如果在请求者的访问仍然具有与ACE的“访问掩码”相同的未允许位的情况下遇到访问被拒绝ACE,则请求被拒绝。完全处理ACL时,如果请求者掩码中有未被允许或拒绝的位,则拒绝访问。

Unlike the ALLOW and DENY 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. Therefore, AUDIT and ALARM ACEs are processed only after processing ALLOW and DENY ACEs.

与ALLOW和DENY ACE类型不同,ALARM和AUDIT ACE类型不影响请求者的访问,而是作为请求者访问尝试的结果触发事件。因此,只有在处理“允许”和“拒绝”ACE之后,才会处理审核和报警ACE。

The NFSv4.1 ACL model is quite rich. Some server platforms may provide access-control functionality that goes beyond the UNIX-style mode attribute, but that is not as rich as the NFS ACL model. So

NFSv4.1 ACL模型非常丰富。某些服务器平台可能提供超越UNIX样式模式属性的访问控制功能,但这并不像NFS ACL模型那样丰富。所以

that users can take advantage of this more limited functionality, the server may support the acl attributes by mapping between its ACL model and the NFSv4.1 ACL model. Servers must ensure that the ACL they actually store or enforce is at least as strict as the NFSv4 ACL that was set. It is tempting to accomplish this by rejecting any ACL that falls outside the small set that can be represented accurately. However, such an approach can render ACLs unusable without special client-side knowledge of the server's mapping, which defeats the purpose of having a common NFSv4 ACL protocol. Therefore, servers should accept every ACL that they can without compromising security. To help accomplish this, servers may make a special exception, in the case of unsupported permission bits, to the rule that bits not ALLOWED or DENIED by an ACL must be denied. For example, a UNIX-style server might choose to silently allow read attribute permissions even though an ACL does not explicitly allow those permissions. (An ACL that explicitly denies permission to read attributes should still be rejected.)

为了使用户能够利用这一更有限的功能,服务器可以通过其acl模型和NFSv4.1 acl模型之间的映射来支持acl属性。服务器必须确保其实际存储或实施的ACL至少与设置的NFSv4 ACL一样严格。通过拒绝任何不属于可以准确表示的小集合的ACL来实现这一点是很有诱惑力的。然而,这种方法可能会使ACL在没有服务器映射的特殊客户端知识的情况下无法使用,这与使用通用NFSv4 ACL协议的目的背道而驰。因此,服务器应该在不影响安全性的情况下尽可能地接受每个ACL。为了帮助实现这一点,服务器可能会在权限位不受支持的情况下对ACL不允许或拒绝的位必须被拒绝的规则做出特殊的例外。例如,UNIX样式的服务器可能会选择以静默方式允许读取属性权限,即使ACL不显式允许这些权限。(明确拒绝读取属性权限的ACL仍应被拒绝。)

The situation is complicated by the fact that a server may have multiple modules that enforce ACLs. For example, the enforcement for NFSv4.1 access may be different from, but not weaker than, the enforcement for local access, and both may be different from the enforcement for access through other protocols such as SMB (Server Message Block). 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的模块,这一事实使情况变得复杂。例如,NFSv4.1访问的强制执行可能不同于但不弱于本地访问的强制执行,并且两者都可能不同于通过其他协议(如SMB(服务器消息块))进行访问的强制执行。因此,即使不是所有的模块都能支持ACL,服务器接受ACL也是很有用的。

The guiding principle with regard to NFSv4 access is that the server must not accept ACLs that appear to make access to the file more restrictive than it really is.

关于NFSv4访问的指导原则是,服务器不能接受ACL,因为这些ACL似乎使对文件的访问比实际限制更大。

6.2.1.1. ACE Type
6.2.1.1. ACE类型

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;
        

Only the ALLOWED and DENIED bits may be used in the dacl attribute, and only the AUDIT and ALARM bits may be used in the sacl attribute. All four are permitted in the acl attribute.

dacl属性中只能使用允许位和拒绝位,sacl属性中只能使用审核位和报警位。acl属性中允许所有四个。

   +------------------------------+--------------+---------------------+
   | Value                        | Abbreviation | Description         |
   +------------------------------+--------------+---------------------+
   | ACE4_ACCESS_ALLOWED_ACE_TYPE | ALLOW        | Explicitly grants   |
   |                              |              | the access defined  |
   |                              |              | in acemask4 to the  |
   |                              |              | file or directory.  |
   | ACE4_ACCESS_DENIED_ACE_TYPE  | DENY         | Explicitly denies   |
   |                              |              | the access defined  |
   |                              |              | in acemask4 to the  |
   |                              |              | file or directory.  |
   | ACE4_SYSTEM_AUDIT_ACE_TYPE   | AUDIT        | Log (in a           |
   |                              |              | system-dependent    |
   |                              |              | way) any access     |
   |                              |              | attempt to a file   |
   |                              |              | or directory that   |
   |                              |              | uses any of the     |
   |                              |              | access methods      |
   |                              |              | specified in        |
   |                              |              | acemask4.           |
   | ACE4_SYSTEM_ALARM_ACE_TYPE   | ALARM        | Generate an alarm   |
   |                              |              | (in a               |
   |                              |              | system-dependent    |
   |                              |              | way) when any       |
   |                              |              | access attempt is   |
   |                              |              | made to a file or   |
   |                              |              | directory for the   |
   |                              |              | access methods      |
   |                              |              | specified in        |
   |                              |              | acemask4.           |
   +------------------------------+--------------+---------------------+
        
   +------------------------------+--------------+---------------------+
   | Value                        | Abbreviation | Description         |
   +------------------------------+--------------+---------------------+
   | ACE4_ACCESS_ALLOWED_ACE_TYPE | ALLOW        | Explicitly grants   |
   |                              |              | the access defined  |
   |                              |              | in acemask4 to the  |
   |                              |              | file or directory.  |
   | ACE4_ACCESS_DENIED_ACE_TYPE  | DENY         | Explicitly denies   |
   |                              |              | the access defined  |
   |                              |              | in acemask4 to the  |
   |                              |              | file or directory.  |
   | ACE4_SYSTEM_AUDIT_ACE_TYPE   | AUDIT        | Log (in a           |
   |                              |              | system-dependent    |
   |                              |              | way) any access     |
   |                              |              | attempt to a file   |
   |                              |              | or directory that   |
   |                              |              | uses any of the     |
   |                              |              | access methods      |
   |                              |              | specified in        |
   |                              |              | acemask4.           |
   | ACE4_SYSTEM_ALARM_ACE_TYPE   | ALARM        | Generate an alarm   |
   |                              |              | (in a               |
   |                              |              | system-dependent    |
   |                              |              | way) when any       |
   |                              |              | access attempt is   |
   |                              |              | made to a file or   |
   |                              |              | directory for the   |
   |                              |              | access methods      |
   |                              |              | specified in        |
   |                              |              | acemask4.           |
   +------------------------------+--------------+---------------------+
        

The "Abbreviation" column denotes how the types will be referred to throughout the rest of this section.

“缩写”列表示在本节其余部分中如何引用这些类型。

6.2.1.2. Attribute 13: aclsupport
6.2.1.2. 属性13:ACL支持

A server need not support all of the above ACE types. This attribute indicates which ACE types are supported for the current file system. The bitmask constants used to represent the above definitions within the aclsupport attribute are as follows:

服务器不需要支持上述所有ACE类型。此属性指示当前文件系统支持哪些ACE类型。用于在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;
        

Servers that support either the ALLOW or DENY ACE type SHOULD support both ALLOW and DENY ACE types.

支持ALLOW或DENY ACE类型的服务器应同时支持ALLOW和DENY ACE类型。

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拒绝该请求。

Support for any of the ACL attributes is optional (albeit RECOMMENDED). However, a server that supports either of the new ACL attributes (dacl or sacl) MUST allow use of the new ACL attributes to access all of the ACE types that it supports. In other words, if such a server supports ALLOW or DENY ACEs, then it MUST support the dacl attribute, and if it supports AUDIT or ALARM ACEs, then it MUST support the sacl attribute.

对任何ACL属性的支持都是可选的(尽管建议如此)。但是,支持新ACL属性(dacl或sacl)的服务器必须允许使用新ACL属性访问其支持的所有ACE类型。换句话说,如果这样的服务器支持允许或拒绝ACE,那么它必须支持dacl属性,如果它支持审计或报警ACE,那么它必须支持sacl属性。

6.2.1.3. ACE Access Mask
6.2.1.3. ACE访问掩码

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_WRITE_RETENTION      = 0x00000200;
   const ACE4_WRITE_RETENTION_HOLD = 0x00000400;
        
   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_WRITE_RETENTION      = 0x00000200;
   const ACE4_WRITE_RETENTION_HOLD = 0x00000400;
        
   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;
        

Note that some masks have coincident values, for example, ACE4_READ_DATA and ACE4_LIST_DIRECTORY. The mask entries ACE4_LIST_DIRECTORY, ACE4_ADD_FILE, and ACE4_ADD_SUBDIRECTORY are

请注意,某些掩码具有重合的值,例如,ACE4_读取_数据和ACE4_列表_目录。掩码条目ACE4_LIST_目录、ACE4_ADD_文件和ACE4_ADD_子目录是

intended to be used with directory objects, while ACE4_READ_DATA, ACE4_WRITE_DATA, and ACE4_APPEND_DATA are intended to be used with non-directory objects.

用于目录对象,而ACE4_读取_数据、ACE4_写入_数据和ACE4_附加_数据用于非目录对象。

6.2.1.3.1. Discussion of Mask Attributes
6.2.1.3.1. 关于遮罩属性的讨论

ACE4_READ_DATA

ACE4_读取_数据

Operation(s) affected:

受影响的行动:

READ

阅读

OPEN

打开

Discussion:

讨论:

Permission to read the data of the file.

读取文件数据的权限。

Servers SHOULD allow a user the ability to read the data of the file when only the ACE4_EXECUTE access mask bit is allowed.

当仅允许ACE4_EXECUTE访问掩码位时,服务器应允许用户读取文件数据。

ACE4_LIST_DIRECTORY

ACE4\u列表\u目录

Operation(s) affected:

受影响的行动:

READDIR

READDIR

Discussion:

讨论:

Permission to list the contents of a directory.

列出目录内容的权限。

ACE4_WRITE_DATA

ACE4_写入_数据

Operation(s) affected:

受影响的行动:

WRITE

OPEN

打开

SETATTR of size

大小设置属性

Discussion:

讨论:

Permission to modify a file's data.

修改文件数据的权限。

ACE4_ADD_FILE

ACE4_添加_文件

Operation(s) affected:

受影响的行动:

CREATE

创造

LINK

链接

OPEN

打开

RENAME

改名

Discussion:

讨论:

Permission to add a new file in a directory. The CREATE operation is affected when nfs_ftype4 is NF4LNK, NF4BLK, NF4CHR, NF4SOCK, or NF4FIFO. (NF4DIR is not listed because it is covered by ACE4_ADD_SUBDIRECTORY.) OPEN is affected when used to create a regular file. LINK and RENAME are always affected.

在目录中添加新文件的权限。当nfs_ftype4为NF4LNK、NF4BLK、NF4CHR、NF4SOCK或NF4FIFO时,创建操作会受到影响。(NF4DIR未列出,因为它包含在ACE4_ADD_子目录中。)OPEN在用于创建常规文件时会受到影响。链接和重命名总是受到影响。

ACE4_APPEND_DATA

ACE4_追加_数据

Operation(s) affected:

受影响的行动:

WRITE

OPEN

打开

SETATTR of size

大小设置属性

Discussion:

讨论:

The ability to modify a file's data, but only starting at EOF. This allows for the notion of append-only files, by allowing ACE4_APPEND_DATA and denying ACE4_WRITE_DATA to the same user or group. If a file has an ACL such as the one described above and a WRITE request is made for somewhere other than EOF, the server SHOULD return NFS4ERR_ACCESS.

修改文件数据的能力,但仅从EOF开始。通过允许ACE4_追加_数据并拒绝ACE4_向同一用户或组写入_数据,这允许仅追加文件的概念。如果文件具有如上所述的ACL,并且对EOF以外的其他位置发出写入请求,则服务器应返回NFS4ERR_访问。

ACE4_ADD_SUBDIRECTORY

ACE4_添加_子目录

Operation(s) affected:

受影响的行动:

CREATE

创造

RENAME

改名

Discussion:

讨论:

Permission to create a subdirectory in a directory. The CREATE operation is affected when nfs_ftype4 is NF4DIR. The RENAME operation is always affected.

在目录中创建子目录的权限。当nfs_ftype4为NF4DIR时,创建操作会受到影响。重命名操作始终受到影响。

ACE4_READ_NAMED_ATTRS

ACE4\u读取\u命名\u属性

Operation(s) affected:

受影响的行动:

OPENATTR

OPENATTR

Discussion:

讨论:

Permission to read the named attributes of a file or to look up the named attribute directory. OPENATTR is affected when it is not used to create a named attribute directory. This is when 1) createdir is TRUE, but a named attribute directory already exists, or 2) createdir is FALSE.

读取文件的命名属性或查找命名属性目录的权限。OPENATTR不用于创建命名属性目录时会受到影响。这是指1)createdir为TRUE,但命名属性目录已存在,或2)createdir为FALSE。

ACE4_WRITE_NAMED_ATTRS

ACE4\u写入\u命名\u属性

Operation(s) affected:

受影响的行动:

OPENATTR

OPENATTR

Discussion:

讨论:

Permission to write the named attributes of a file or to create a named attribute directory. OPENATTR is affected when it is used to create a named attribute directory. This is when createdir is TRUE and no named attribute directory exists. The ability to check whether or not a named attribute directory exists depends on the ability to look it up; therefore, users also need the ACE4_READ_NAMED_ATTRS permission in order to create a named attribute directory.

写入文件的命名属性或创建命名属性目录的权限。OPENATTR用于创建命名属性目录时会受到影响。此时createdir为TRUE且不存在命名属性目录。检查命名属性目录是否存在的能力取决于查找它的能力;因此,用户还需要ACE4_READ_NAMED_ATTRS权限才能创建命名属性目录。

ACE4_EXECUTE

ACE4_执行

Operation(s) affected:

受影响的行动:

READ

阅读

OPEN

打开

REMOVE

去除

RENAME

改名

LINK

链接

CREATE

创造

Discussion:

讨论:

Permission to execute a file.

执行文件的权限。

Servers SHOULD allow a user the ability to read the data of the file when only the ACE4_EXECUTE access mask bit is allowed. This is because there is no way to execute a file without reading the contents. Though a server may treat ACE4_EXECUTE and ACE4_READ_DATA bits identically when deciding to permit a READ operation, it SHOULD still allow the two bits to be set independently in ACLs, and MUST distinguish between them when replying to ACCESS operations. In particular, servers SHOULD NOT silently turn on one of the two bits when the other is set, as that would make it impossible for the client to correctly enforce the distinction between read and execute permissions.

当仅允许ACE4_EXECUTE访问掩码位时,服务器应允许用户读取文件数据。这是因为在不读取内容的情况下无法执行文件。尽管在决定允许读取操作时,服务器可能会对ACE4_EXECUTE和ACE4_READ_数据位进行相同的处理,但仍应允许在ACL中独立设置这两个位,并且在答复访问操作时必须区分它们。特别是,当另一位被设置时,服务器不应该静默地打开这两位中的一位,因为这将使客户端无法正确执行读取和执行权限之间的区别。

As an example, following a SETATTR of the following ACL:

例如,在以下ACL的SETATTR之后:

nfsuser:ACE4_EXECUTE:ALLOW

nfsuser:ACE4_执行:允许

A subsequent GETATTR of ACL for that file SHOULD return:

该文件的ACL的后续GETATTR应返回:

nfsuser:ACE4_EXECUTE:ALLOW

nfsuser:ACE4_执行:允许

Rather than:

而不是:

         nfsuser:ACE4_EXECUTE/ACE4_READ_DATA:ALLOW
        
         nfsuser:ACE4_EXECUTE/ACE4_READ_DATA:ALLOW
        

ACE4_EXECUTE

ACE4_执行

Operation(s) affected:

受影响的行动:

LOOKUP

查找

Discussion:

讨论:

Permission to traverse/search a directory.

遍历/搜索目录的权限。

ACE4_DELETE_CHILD

ACE4_删除_子项

Operation(s) affected:

受影响的行动:

REMOVE

去除

RENAME

改名

Discussion:

讨论:

Permission to delete a file or directory within a directory. See Section 6.2.1.3.2 for information on ACE4_DELETE and ACE4_DELETE_CHILD interact.

删除目录中的文件或目录的权限。有关ACE4_DELETE和ACE4_DELETE_子交互的信息,请参见第6.2.1.3.2节。

ACE4_READ_ATTRIBUTES

ACE4_读取_属性

Operation(s) affected:

受影响的行动:

GETATTR of file system object attributes

文件系统对象属性的GETATTR

VERIFY

验证

NVERIFY

恩弗里

READDIR

READDIR

Discussion:

讨论:

The ability to read basic attributes (non-ACLs) of a file. On a UNIX system, basic attributes can be thought of as the stat-level attributes. Allowing this access mask bit would mean that the entity can execute "ls -l" and stat. If a READDIR operation requests attributes, this mask must be allowed for the READDIR to succeed.

能够读取文件的基本属性(非ACL)。在UNIX系统上,基本属性可以看作是stat级别的属性。允许此访问掩码位意味着实体可以执行“ls-l”和stat。如果READDIR操作请求属性,则必须允许此掩码,READDIR才能成功。

ACE4_WRITE_ATTRIBUTES

ACE4_写入_属性

Operation(s) affected:

受影响的行动:

SETATTR of time_access_set, time_backup,

设置时间属性\u访问\u设置,时间\u备份,

time_create, time_modify_set, mimetype, hidden, system

创建时间、修改时间、复制类型、隐藏、系统

Discussion:

讨论:

Permission to change the times associated with a file or directory to an arbitrary value. Also permission to change the mimetype, hidden, and system attributes. A user having ACE4_WRITE_DATA or ACE4_WRITE_ATTRIBUTES will be allowed to set the times associated with a file to the current server time.

将与文件或目录关联的时间更改为任意值的权限。还有更改mimetype、hidden和system属性的权限。允许具有ACE4_WRITE_数据或ACE4_WRITE_属性的用户将与文件关联的时间设置为当前服务器时间。

ACE4_WRITE_RETENTION

ACE4_写入_保留

Operation(s) affected:

受影响的行动:

SETATTR of retention_set, retentevt_set.

保留集的设置属性,保留集。

Discussion:

讨论:

Permission to modify the durations of event and non-event-based retention. Also permission to enable event and non-event-based retention. A server MAY behave such that setting ACE4_WRITE_ATTRIBUTES allows ACE4_WRITE_RETENTION.

修改基于事件和非基于事件的保留期限的权限。还有启用基于事件和非基于事件的保留的权限。服务器的行为可能会使设置ACE4_WRITE_属性允许ACE4_WRITE_保留。

ACE4_WRITE_RETENTION_HOLD

ACE4_写入_保留_保持

Operation(s) affected:

受影响的行动:

SETATTR of retention_hold.

设置保留的属性。

Discussion:

讨论:

Permission to modify the administration retention holds. A server MAY map ACE4_WRITE_ATTRIBUTES to ACE_WRITE_RETENTION_HOLD.

修改管理保留的权限保留。服务器可以将ACE4_WRITE_属性映射到ACE_WRITE_RETENTION_HOLD。

ACE4_DELETE

ACE4_删除

Operation(s) affected:

受影响的行动:

REMOVE

去除

Discussion:

讨论:

Permission to delete the file or directory. See Section 6.2.1.3.2 for information on ACE4_DELETE and ACE4_DELETE_CHILD interact.

删除文件或目录的权限。有关ACE4_DELETE和ACE4_DELETE_子交互的信息,请参见第6.2.1.3.2节。

ACE4_READ_ACL

ACE4\u读取\u ACL

Operation(s) affected:

受影响的行动:

GETATTR of acl, dacl, or sacl

获取acl、dacl或sacl的属性

NVERIFY

恩弗里

VERIFY

验证

Discussion:

讨论:

Permission to read the ACL.

读取ACL的权限。

ACE4_WRITE_ACL

ACE4_WRITE_ACL

Operation(s) affected:

受影响的行动:

SETATTR of acl and mode

acl和模式的SETATTR

Discussion:

讨论:

Permission to write the acl and mode attributes.

写入acl和模式属性的权限。

ACE4_WRITE_OWNER

ACE4_写入_所有者

Operation(s) affected:

受影响的行动:

SETATTR of owner and owner_group

所有者和所有者组的设置属性

Discussion:

讨论:

Permission to write the owner and owner_group attributes. On UNIX systems, this is the ability to execute chown() and chgrp().

写入所有者和所有者组属性的权限。在UNIX系统上,这是执行chown()和chgrp()的能力。

ACE4_SYNCHRONIZE

ACE4_同步

Operation(s) affected:

受影响的行动:

NONE

没有一个

Discussion:

讨论:

Permission to use the file object as a synchronization primitive for interprocess communication. This permission is not enforced or interpreted by the NFSv4.1 server on behalf of the client.

将文件对象用作进程间通信的同步原语的权限。NFSv4.1服务器不代表客户端强制或解释此权限。

Typically, the ACE4_SYNCHRONIZE permission is only meaningful on local file systems, i.e., file systems not accessed via NFSv4.1. The reason that the permission bit exists is that some operating environments, such as Windows, use ACE4_SYNCHRONIZE.

通常,ACE4_SYNCHRONIZE权限仅在本地文件系统上有意义,即未通过NFSv4.1访问的文件系统。权限位存在的原因是某些操作环境(如Windows)使用ACE4\u同步。

For example, if a client copies a file that has ACE4_SYNCHRONIZE set from a local file system to an NFSv4.1 server, and then later copies the file from the NFSv4.1 server

例如,如果客户端将设置了ACE4_SYNCHRONIZE的文件从本地文件系统复制到NFSv4.1服务器,然后再从NFSv4.1服务器复制该文件

to a local file system, it is likely that if ACE4_SYNCHRONIZE was set in the original file, the client will want it set in the second copy. The first copy will not have the permission set unless the NFSv4.1 server has the means to set the ACE4_SYNCHRONIZE bit. The second copy will not have the permission set unless the NFSv4.1 server has the means to retrieve the ACE4_SYNCHRONIZE bit.

对于本地文件系统,如果在原始文件中设置了ACE4_SYNCHRONIZE,则客户端可能希望在第二个副本中设置它。除非NFSv4.1服务器具有设置ACE4_同步位的方法,否则第一个副本将不会设置权限。除非NFSv4.1服务器具有检索ACE4_同步位的方法,否则第二个副本将不具有权限集。

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 ACE4_APPEND_DATA (the ability to append to a file) from ACE4_WRITE_DATA (the ability to modify existing contents); both masks would be tied to a single "write" permission [20]. When such a server returns attributes to the client, it would show both ACE4_APPEND_DATA and ACE4_WRITE_DATA if and only if the write permission is enabled.

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

If a server receives a SETATTR request that it cannot accurately implement, it should err in the direction of more restricted access, except in the previously discussed cases of execute and read. For example, suppose a server cannot distinguish overwriting data from appending new data, as described in the previous paragraph. If a client submits an ALLOW ACE where ACE4_APPEND_DATA is set but ACE4_WRITE_DATA is not (or vice versa), the server should either turn off ACE4_APPEND_DATA or reject the request with NFS4ERR_ATTRNOTSUPP.

如果服务器接收到无法准确实现的SETATTR请求,那么它应该在更受限的访问方向上出错,前面讨论的execute和read情况除外。例如,假设服务器无法区分覆盖数据和追加新数据,如前一段所述。如果客户端提交了一个允许ACE,其中设置了ACE4_APPEND_数据,但未设置ACE4_WRITE_数据(反之亦然),则服务器应关闭ACE4_APPEND_数据或使用NFS4ERR_ATTRNOTSUPP拒绝请求。

6.2.1.3.2. ACE4_DELETE vs. ACE4_DELETE_CHILD
6.2.1.3.2. ACE4_DELETE与ACE4_DELETE_CHILD

Two access mask bits govern the ability to delete a directory entry: ACE4_DELETE on the object itself (the "target") and ACE4_DELETE_CHILD on the containing directory (the "parent").

两个访问掩码位控制删除目录项的能力:对象本身(“目标”)上的ACE4_delete和包含目录(“父目录”)上的ACE4_delete_CHILD。

Many systems also take the "sticky bit" (MODE4_SVTX) on a directory to allow unlink only to a user that owns either the target or the parent; on some such systems the decision also depends on whether the target is writable.

许多系统还采用目录上的“粘性位”(MODE4_SVTX),只允许与拥有目标或父目录的用户解除链接;在某些这样的系统上,决策还取决于目标是否可写。

Servers SHOULD allow unlink if either ACE4_DELETE is permitted on the target, or ACE4_DELETE_CHILD is permitted on the parent. (Note that this is true even if the parent or target explicitly denies one of these permissions.)

如果目标上允许ACE4_删除,或者父级上允许ACE4_删除子级,则服务器应允许取消链接。(请注意,即使父级或目标明确拒绝这些权限之一,这也是正确的。)

If the ACLs in question neither explicitly ALLOW nor DENY either of the above, and if MODE4_SVTX is not set on the parent, then the server SHOULD allow the removal if and only if ACE4_ADD_FILE is permitted. In the case where MODE4_SVTX is set, the server may also require the remover to own either the parent or the target, or may require the target to be writable.

如果所讨论的ACL既不明确允许也不拒绝上述任何一项,并且如果父级上未设置MODE4_SVTX,则只有在允许ACE4_ADD_文件的情况下,服务器才应允许删除。在设置MODE4_SVTX的情况下,服务器还可能要求删除程序拥有父级或目标,或者可能要求目标可写。

This allows servers to support something close to traditional UNIX-like semantics, with ACE4_ADD_FILE taking the place of the write bit.

这允许服务器支持类似于传统UNIX的语义,用ACE4_ADD_文件代替写位。

6.2.1.4. ACE flag
6.2.1.4. 王牌旗

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_INHERITED_ACE                = 0x00000080;
        
   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_INHERITED_ACE                = 0x00000080;
        

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.

服务器不需要支持这些标志中的任何一个。如果服务器支持与这些标志相似但不完全相同的标志,则实现可以定义协议定义标志和实现定义标志之间的映射。

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标志。

6.2.1.4.1. Discussion of Flag Bits
6.2.1.4.1. 关于标志位的讨论

ACE4_FILE_INHERIT_ACE Any non-directory file in any sub-directory will get this ACE inherited.

ACE4\u文件\u继承\u 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. If this flag is set in an ACE in an ACL attribute to be set on a non-directory file system object, the operation attempting to set the ACL SHOULD fail with NFS4ERR_ATTRNOTSUPP.

ACE4_DIRECTORY_INHERIT_ACE可放置在目录上,并指示应将此ACE添加到创建的每个新目录中。如果在要在非目录文件系统对象上设置的ACL属性的ACE中设置了此标志,则尝试设置ACL的操作将失败,并出现NFS4ERR_ATTRNOTSUPP。

ACE4_NO_PROPAGATE_INHERIT_ACE Can be placed on a directory. This flag tells the server that inheritance of this ACE should stop at newly created child directories.

ACE4\u NO\u PROPAGATE\u INHERIT\u ACE可以放置在目录中。此标志告诉服务器,此ACE的继承应在新创建的子目录处停止。

ACE4_INHERIT_ONLY_ACE Can be placed on a directory but does not apply to the directory; ALLOW and DENY ACEs with this bit set do not affect access to the directory, and AUDIT and ALARM ACEs with this bit set do not trigger log or alarm events. Such ACEs only take effect once they are applied (with this bit cleared) to newly created files and directories as specified by the ACE4_FILE_INHERIT_ACE and ACE4_DIRECTORY_INHERIT_ACE flags.

ACE4_INHERIT_ONLY_ACE可放置在目录上,但不适用于该目录;具有此位集的允许和拒绝ACE不会影响对目录的访问,并且具有此位集的审核和报警ACE不会触发日志或报警事件。此类ACE仅在应用于(清除此位)由ACE4_文件_继承_ACE和ACE4_目录_继承_ACE标志指定的新创建的文件和目录后生效。

If this flag is present on an ACE, but neither ACE4_DIRECTORY_INHERIT_ACE nor ACE4_FILE_INHERIT_ACE is present, then an operation attempting to set such an attribute SHOULD fail with NFS4ERR_ATTRNOTSUPP.

如果ACE上存在此标志,但既不存在ACE4_目录_继承_ACE,也不存在ACE4_文件_继承_ACE,则尝试设置此类属性的操作应失败,并出现NFS4ERR_ATTRNOTSUPP。

ACE4_SUCCESSFUL_ACCESS_ACE_FLAG

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

ACE4_FAILED_ACCESS_ACE_FLAG The ACE4_SUCCESSFUL_ACCESS_ACE_FLAG (SUCCESS) and ACE4_FAILED_ACCESS_ACE_FLAG (FAILED) flag bits may be set only on 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, it then notes if the operation succeeded or failed. If the operation succeeded, and if the SUCCESS flag was set for a matching AUDIT or ALARM ACE, then the appropriate AUDIT or ALARM event occurs. If the operation failed, and if the FAILED flag was set for the matching AUDIT or ALARM ACE, then the appropriate AUDIT or ALARM event occurs. Either or both of the SUCCESS or FAILED can be set, but if neither is set, the AUDIT or ALARM ACE is not useful.

ACE4_失败访问_ACE_标志ACE4_成功访问_ACE_标志(成功)和ACE4_失败访问_ACE_标志(失败)位只能在ACE4_系统审计_ACE_类型(审计)和ACE4_系统报警_ACE类型(报警)ACE类型上设置。如果在处理文件的ACL期间,服务器遇到与尝试打开的主体匹配的审核或报警ACE,则服务器会注意到该事实以及审核或报警ACE中遇到的成功和失败标志(如果有)。服务器完成ACL处理后,会记录操作是成功还是失败。如果操作成功,并且为匹配的审核或报警ACE设置了成功标志,则会发生相应的审核或报警事件。如果操作失败,并且如果为匹配的审核或报警ACE设置了失败标志,则会发生相应的审核或报警事件。可以设置成功或失败中的一个或两个,但如果两个都未设置,则审核或报警ACE将无效。

The previously described processing applies to ACCESS operations even when they return NFS4_OK. For the purposes of AUDIT and ALARM, we consider an ACCESS operation to be a "failure" if it fails 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 or a GROUP ACCOUNT as defined under Windows. Clients and servers MUST ignore the ACE4_IDENTIFIER_GROUP flag on ACEs with a who value equal to one of the special identifiers outlined in Section 6.2.1.5.

ACE4_IDENTIFIER_GROUP表示“谁”是指UNIX下定义的组或Windows下定义的组帐户。客户机和服务器必须忽略ACEs上的ACE4_标识符_组标志,其who值等于第6.2.1.5节中概述的特殊标识符之一。

ACE4_INHERITED_ACE Indicates that this ACE is inherited from a parent directory. A server that supports automatic inheritance will place this flag on any ACEs inherited from the parent directory when creating a new object. Client applications will use this to perform automatic inheritance. Clients and servers MUST clear this bit in the acl attribute; it may only be used in the dacl and sacl attributes.

ACE4_INHERITED_ACE表示此ACE从父目录继承。当创建新对象时,支持自动继承的服务器将在从父目录继承的任何ACE上放置此标志。客户端应用程序将使用它来执行自动继承。客户端和服务器必须清除acl属性中的该位;它只能在dacl和sacl属性中使用。

6.2.1.5. ACE Who
6.2.1.5. 王牌谁

The "who" field of an ACE is an identifier that specifies the principal or principals to whom the ACE applies. It may refer to a user or a group, with the flag bit ACE4_IDENTIFIER_GROUP specifying which.

ACE的“谁”字段是一个标识符,用于指定ACE应用到的一个或多个主体。它可能指的是用户或组,标志位ACE4_IDENTIFIER_group指定用户或组。

There are several special identifiers that 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.

有几个特殊标识符需要普遍理解,而不是在特定DNS域的上下文中。其中一些标识符在NFS客户端访问服务器时无法理解,但在本地进程访问文件时具有意义。允许通过NFS显示和修改这些权限,即使服务器上的任何访问方法都不理解标识符。

   +---------------+--------------------------------------------------+
   | Who           | Description                                      |
   +---------------+--------------------------------------------------+
   | OWNER         | The owner of the file.                           |
   | GROUP         | The group associated with the file.              |
   | EVERYONE      | The world, including the owner and owning group. |
   | 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, including the owner and owning group. |
   | 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.                    |
   +---------------+--------------------------------------------------+
        

Table 4

表4

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

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

The ACE4_IDENTIFIER_GROUP flag MUST be ignored on entries with these special identifiers. When encoding entries with these special identifiers, the ACE4_IDENTIFIER_GROUP flag SHOULD be set to zero.

对于具有这些特殊标识符的条目,必须忽略ACE4_标识符_组标志。使用这些特殊标识符对条目进行编码时,ACE4_IDENTIFIER_GROUP标志应设置为零。

6.2.1.5.1. Discussion of EVERYONE@
6.2.1.5.1. 大家讨论@

It is important to note that "EVERYONE@" is not equivalent to the UNIX "other" entity. This is because, by definition, UNIX "other" does not include the owner or owning group of a file. "EVERYONE@" means literally everyone, including the owner or owning group.

需要注意的是,“EVERYONE@”并不等同于UNIX“other”实体。这是因为,根据定义,UNIX“其他”不包括文件的所有者或所有者组。“EVERYONE@”字面上是指所有人,包括所有者或所有者团体。

6.2.2. Attribute 58: dacl
6.2.2. 属性58:dacl

The dacl attribute is like the acl attribute, but dacl allows just ALLOW and DENY ACEs. The dacl attribute supports automatic inheritance (see Section 6.4.3.2).

dacl属性类似于acl属性,但dacl只允许允许和拒绝ACE。dacl属性支持自动继承(参见第6.4.3.2节)。

6.2.3. Attribute 59: sacl
6.2.3. 属性59:sacl

The sacl attribute is like the acl attribute, but sacl allows just AUDIT and ALARM ACEs. The sacl attribute supports automatic inheritance (see Section 6.4.3.2).

sacl属性与acl属性类似,但sacl只允许审核和报警ACE。sacl属性支持自动继承(参见第6.4.3.2节)。

6.2.4. Attribute 33: mode
6.2.4. 属性33:模式

The NFSv4.1 mode attribute is based on the UNIX mode bits. The following bits are defined:

NFSv4.1模式属性基于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_XGRP apply to principals identified in the owner_group attribute but who are not identified in the owner attribute. Bits MODE4_ROTH, MODE4_WOTH, and MODE4_XOTH apply to any principal that does not match that in the owner attribute and does not have a group matching that of the owner_group attribute.

位MODE4_RUSR、MODE4_WUSR和MODE4_XUSR应用于所有者属性中标识的主体。位MODE4_RGRP、MODE4_WGRP和MODE4_XGRP适用于在owner_group属性中标识但在owner属性中未标识的主体。位MODE4_ROTH、MODE4_WOTH和MODE4_XOTH适用于与owner属性中的主体不匹配且组与owner_group属性中的主体不匹配的任何主体。

Bits within a mode other than those specified above are not defined by this protocol. A server MUST NOT return bits other than those defined above in a GETATTR or READDIR operation, and it MUST return NFS4ERR_INVAL if bits other than those defined above are set in a SETATTR, CREATE, OPEN, VERIFY, or NVERIFY operation.

本协议不定义上述模式以外的模式中的位。服务器不能返回除上面在GETATTR或READDIR操作中定义的位以外的位,如果在SETATTR、CREATE、OPEN、VERIFY或NVERIFY操作中设置了除上面定义的位以外的位,则必须返回NFS4ERR_INVAL。

6.2.5. Attribute 74: mode_set_masked
6.2.5. 属性74:模式设置屏蔽

The mode_set_masked attribute is a write-only attribute that allows individual bits in the mode attribute to be set or reset, without changing others. It allows, for example, the bits MODE4_SUID, MODE4_SGID, and MODE4_SVTX to be modified while leaving unmodified any of the nine low-order mode bits devoted to permissions.

mode_set_masked属性是一个只写属性,允许设置或重置mode属性中的各个位,而不更改其他位。例如,它允许修改位MODE4_SUID、MODE4_SGID和MODE4_SVTX,同时保留用于权限的九个低阶模式位中未修改的任何一个。

In such instances that the nine low-order bits are left unmodified, then neither the acl nor the dacl attribute should be automatically modified as discussed in Section 6.4.1.

在九个低阶位未被修改的情况下,acl和dacl属性都不应自动修改,如第6.4.1节所述。

The mode_set_masked attribute consists of two words, each in the form of a mode4. The first consists of the value to be applied to the current mode value and the second is a mask. Only bits set to one in the mask word are changed (set or reset) in the file's mode. All other bits in the mode remain unchanged. Bits in the first word that correspond to bits that are zero in the mask are ignored, except that undefined bits are checked for validity and can result in NFS4ERR_INVAL as described below.

mode_set_masked属性由两个单词组成,每个单词的形式为mode4。第一个由应用于当前模式值的值组成,第二个是掩码。在文件模式下,仅更改(设置或重置)掩码字中设置为1的位。模式中的所有其他位保持不变。忽略第一个字中对应于掩码中零位的位,除非检查未定义位的有效性,并可能导致NFS4ERR_INVAL,如下所述。

The mode_set_masked attribute is only valid in a SETATTR operation. If it is used in a CREATE or OPEN operation, the server MUST return NFS4ERR_INVAL.

mode_set_masked属性仅在SETATTR操作中有效。如果在创建或打开操作中使用,服务器必须返回NFS4ERR_INVAL。

Bits not defined as valid in the mode attribute are not valid in either word of the mode_set_masked attribute. The server MUST return NFS4ERR_INVAL if any such bits are set to one in a SETATTR. If the mode and mode_set_masked attributes are both specified in the same SETATTR, the server MUST also return NFS4ERR_INVAL.

在mode属性中未定义为有效的位在mode_set_masked属性的任何一个字中都无效。如果SETATTR中的任何此类位设置为1,服务器必须返回NFS4ERR_INVAL。如果mode和mode_set_masked属性都在同一SETATTR中指定,则服务器还必须返回NFS4ERR_INVAL。

6.3. Common Methods
6.3. 常用方法

The requirements in this section will be referred to in future sections, especially Section 6.4.

本节中的要求将在以后的章节中提及,特别是第6.4节。

6.3.1. Interpreting an ACL
6.3.1. 解释ACL
6.3.1.1. Server Considerations
6.3.1.1. 服务器注意事项

The server uses the algorithm described in Section 6.2.1 to determine whether an ACL allows access to an object. However, the ACL might not be the sole determiner of access. For example:

服务器使用第6.2.1节中描述的算法来确定ACL是否允许访问对象。但是,ACL可能不是访问的唯一决定因素。例如:

o In the case of a file system exported as read-only, the server may deny write access even though an object's ACL grants it.

o 对于以只读方式导出的文件系统,即使对象的ACL授予写访问权限,服务器也可能会拒绝该权限。

o Server implementations MAY grant ACE4_WRITE_ACL and ACE4_READ_ACL permissions to prevent a situation from arising in which there is no valid way to ever modify the ACL.

o 服务器实现可能会授予ACE4_WRITE_ACL和ACE4_READ_ACL权限,以防止出现无法有效修改ACL的情况。

o All servers will allow a user the ability to read the data of the file when only the execute permission is granted (i.e., if the ACL denies the user the ACE4_READ_DATA access and allows the user ACE4_EXECUTE, the server will allow the user to read the data of the file).

o 当仅授予执行权限时,所有服务器将允许用户读取文件数据(即,如果ACL拒绝用户访问ACE4_read_数据并允许用户执行ACE4_,则服务器将允许用户读取文件数据)。

o Many servers have the notion of owner-override in which the owner of the object is allowed to override accesses that are denied by the ACL. This may be helpful, for example, to allow users continued access to open files on which the permissions have changed.

o 许多服务器具有所有者覆盖的概念,其中允许对象的所有者覆盖ACL拒绝的访问。例如,这可能有助于允许用户继续访问权限已更改的打开文件。

o Many servers have the notion of a "superuser" that has privileges beyond an ordinary user. The superuser may be able to read or write data or metadata in ways that would not be permitted by the ACL.

o 许多服务器都有“超级用户”的概念,拥有普通用户以外的特权。超级用户可能能够以ACL不允许的方式读取或写入数据或元数据。

o A retention attribute might also block access otherwise allowed by ACLs (see Section 5.13).

o 保留属性还可能阻止ACL允许的访问(请参阅第5.13节)。

6.3.1.2. Client Considerations
6.3.1.2. 客户注意事项

Clients SHOULD NOT do their own access checks based on their interpretation of the ACL, but rather use the OPEN and ACCESS operations to do access checks. This allows the client to act on the results of having the server determine whether or not access should be granted based on its interpretation of the ACL.

客户端不应该基于对ACL的解释来执行自己的访问检查,而应该使用OPEN和access操作来执行访问检查。这允许客户端根据服务器根据其对ACL的解释确定是否应授予访问权限的结果进行操作。

Clients must be aware of situations in which an object's ACL will define a certain access even though the server will not enforce it. In general, but especially in these situations, the client needs to do its part in the enforcement of access as defined by the ACL. To do this, the client MAY send the appropriate ACCESS operation prior

客户机必须知道对象的ACL将定义特定访问权限的情况,即使服务器不会强制执行该访问权限。一般来说,但特别是在这些情况下,客户机需要按照ACL的定义在访问的实施中发挥作用。要做到这一点,客户机可以在访问之前发送适当的访问操作

to servicing the request of the user or application in order to determine whether the user or application should be granted the access requested. For examples in which the ACL may define accesses that the server doesn't enforce, see Section 6.3.1.1.

为用户或应用程序的请求提供服务,以确定是否应授予用户或应用程序所请求的访问权限。有关ACL可能定义服务器不强制执行的访问的示例,请参见第6.3.1.1节。

6.3.2. Computing a Mode Attribute from an ACL
6.3.2. 从ACL计算模式属性

The following method can be used to calculate the MODE4_R*, MODE4_W*, and MODE4_X* bits of a mode attribute, based upon an ACL.

以下方法可用于基于ACL计算模式属性的MODE4_R*、MODE4_W*和MODE4_X*位。

First, for each of the special identifiers OWNER@, GROUP@, and EVERYONE@, evaluate the ACL in order, considering only ALLOW and DENY ACEs for the identifier EVERYONE@ and for the identifier under consideration. The result of the evaluation will be an NFSv4 ACL mask showing exactly which bits are permitted to that identifier.

首先,对于每个特殊标识符OWNER@、GROUP@和EVERYONE@,依次评估ACL,考虑仅允许和拒绝标识符EVERYONE@和正在考虑的标识符的ACE。评估的结果将是一个NFSv4 ACL掩码,精确显示允许该标识符使用的位。

Then translate the calculated mask for OWNER@, GROUP@, and EVERYONE@ into mode bits for, respectively, the user, group, and other, as follows:

然后将计算出的OWNER@、GROUP@和everybody@掩码分别转换为user、GROUP和other的模式位,如下所示:

1. Set the read bit (MODE4_RUSR, MODE4_RGRP, or MODE4_ROTH) if and only if ACE4_READ_DATA is set in the corresponding mask.

1. 当且仅当在相应掩码中设置了ACE4_读取数据时,设置读取位(MODE4_RUSR、MODE4_RGRP或MODE4_ROTH)。

2. Set the write bit (MODE4_WUSR, MODE4_WGRP, or MODE4_WOTH) if and only if ACE4_WRITE_DATA and ACE4_APPEND_DATA are both set in the corresponding mask.

2. 设置写入位(MODE4_WUSR、MODE4_WGRP或MODE4_WOTH),前提是且仅当ACE4_写入_数据和ACE4_附加_数据均在相应掩码中设置。

3. Set the execute bit (MODE4_XUSR, MODE4_XGRP, or MODE4_XOTH), if and only if ACE4_EXECUTE is set in the corresponding mask.

3. 设置执行位(MODE4_XUSR、MODE4_XGRP或MODE4_XOTH),前提是且仅当相应掩码中设置了ACE4_execute。

6.3.2.1. Discussion
6.3.2.1. 讨论

Some server implementations also add bits permitted to named users and groups to the group bits (MODE4_RGRP, MODE4_WGRP, and MODE4_XGRP).

一些服务器实现还将允许命名用户和组的位添加到组位(MODE4_RGRP、MODE4_WGRP和MODE4_XGRP)。

Implementations are discouraged from doing this, because it has been found to cause confusion for users who see members of a file's group denied access that the mode bits appear to allow. (The presence of DENY ACEs may also lead to such behavior, but DENY ACEs are expected to be more rarely used.)

不鼓励实现这样做,因为已经发现,如果用户看到模式位似乎允许的文件组成员被拒绝访问,则会导致混淆。(拒绝ACE的存在也可能导致此类行为,但拒绝ACE预计将很少使用。)

The same user confusion seen when fetching the mode also results if setting the mode does not effectively control permissions for the owner, group, and other users; this motivates some of the requirements that follow.

如果设置模式不能有效控制所有者、组和其他用户的权限,则在获取模式时也会出现相同的用户混淆;这激发了接下来的一些需求。

6.4. Requirements
6.4. 要求

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 that have respective who fields of "OWNER@", "GROUP@", and "EVERYONE@". This way, the client can see if semantically equivalent access permissions exist whether the client asks for the owner, owner_group, and mode attributes or for just the ACL.

同时支持mode和ACL的服务器必须注意将MODE4_*USR、MODE4_*GRP和MODE4_*OTH位与具有各自who字段“所有者”、“组”和“所有人”的ACE同步。通过这种方式,客户机可以查看是否存在语义等价的访问权限,无论客户机是请求所有者、所有者组和模式属性,还是仅请求ACL。

In this section, much is made of the methods in Section 6.3.2. Many requirements refer to this section. But note that the methods have behaviors specified with "SHOULD". This is intentional, to avoid invalidating existing implementations that compute the mode according to the withdrawn POSIX ACL draft (1003.1e draft 17), rather than by actual permissions on owner, group, and other.

本节主要介绍第6.3.2节中的方法。许多要求涉及本节。但是请注意,这些方法具有用“应该”指定的行为。这是有意的,以避免使根据撤销的POSIX ACL草案(1003.1e草案17)计算模式的现有实现无效,而不是通过所有者、组和其他用户的实际权限。

6.4.1. Setting the Mode and/or ACL Attributes
6.4.1. 设置模式和/或ACL属性

In the case where a server supports the sacl or dacl attribute, in addition to the acl attribute, the server MUST fail a request to set the acl attribute simultaneously with a dacl or sacl attribute. The error to be given is NFS4ERR_ATTRNOTSUPP.

在服务器支持sacl或dacl属性的情况下,除了acl属性外,服务器还必须使设置acl属性和dacl或sacl属性的请求失败。要给出的错误是NFS4ERR_ATTRNOTSUPP。

6.4.1.1. Setting Mode and not ACL
6.4.1.1. 设置模式而不是ACL

When any of the nine low-order mode bits are subject to change, either because the mode attribute was set or because the mode_set_masked attribute was set and the mask included one or more bits from the nine low-order mode bits, and no ACL attribute is explicitly set, the acl and dacl attributes must be modified in accordance with the updated value of those bits. This must happen even if the value of the low-order bits is the same after the mode is set as before.

当九个低阶模式位中的任何一个发生变化时,或者因为设置了模式属性,或者因为设置了模式设置屏蔽属性,并且屏蔽包括九个低阶模式位中的一个或多个位,并且没有显式设置ACL属性,acl和dacl属性必须根据这些位的更新值进行修改。即使低阶位的值在模式设置后与之前相同,也必须发生这种情况。

Note that any AUDIT or ALARM ACEs (hence any ACEs in the sacl attribute) are unaffected by changes to the mode.

请注意,任何审核或报警ACE(因此sacl属性中的任何ACE)不受模式更改的影响。

In cases in which the permissions bits are subject to change, the acl and dacl attributes MUST be modified such that the mode computed via the method in Section 6.3.2 yields the low-order nine bits (MODE4_R*, MODE4_W*, MODE4_X*) of the mode attribute as modified by the attribute change. The ACL attributes SHOULD also be modified such that:

在权限位可能发生更改的情况下,必须修改acl和dacl属性,以便通过第6.3.2节中的方法计算的模式产生由属性更改修改的模式属性的低阶九位(MODE4_R*、MODE4_W*、MODE4_X*)。还应修改ACL属性,以便:

1. If MODE4_RGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_READ_DATA.

1. 如果未设置MODE4_RGRP,则ACL中明确列出的除OWNER@和EVERYONE@之外的实体不应被授予ACE4_读取_数据。

2. If MODE4_WGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_WRITE_DATA or ACE4_APPEND_DATA.

2. 如果未设置MODE4_WGRP,则在ACL中明确列出的除OWNER@和EVERYONE@以外的实体不应被授予ACE4_WRITE_数据或ACE4_APPEND_数据。

3. If MODE4_XGRP is not set, entities explicitly listed in the ACL other than OWNER@ and EVERYONE@ SHOULD NOT be granted ACE4_EXECUTE.

3. 如果未设置MODE4_XGRP,则不应授予ACL中明确列出的除OWNER@和EVERYONE@以外的实体ACE4_EXECUTE。

Access mask bits other than those listed above, appearing in ALLOW ACEs, MAY also be disabled.

除了上面列出的访问掩码位之外,出现在允许ACEs中的访问掩码位也可能被禁用。

Note that ACEs with the flag ACE4_INHERIT_ONLY_ACE set do not affect the permissions of the ACL itself, nor do ACEs of the type AUDIT and ALARM. As such, it is desirable to leave these ACEs unmodified when modifying the ACL attributes.

请注意,带有标志ACE4_INHERIT_ONLY_ACE set的ACE不会影响ACL本身的权限,也不会影响AUDIT和ALARM类型的ACE。因此,在修改ACL属性时,最好不要修改这些ACE。

Also note that the requirement may be met by discarding the acl and dacl, in favor of an ACL that represents the mode and only the mode. This is permitted, but it is preferable for a server to preserve as much of the ACL as possible without violating the above requirements. Discarding the ACL makes it effectively impossible for a file created with a mode attribute to inherit an ACL (see Section 6.4.3).

还请注意,可以通过放弃acl和dacl来满足该要求,而使用表示模式且仅表示模式的acl。这是允许的,但服务器最好在不违反上述要求的情况下保留尽可能多的ACL。丢弃ACL实际上使使用mode属性创建的文件无法继承ACL(请参阅第6.4.3节)。

6.4.1.2. Setting ACL and Not Mode
6.4.1.2. 设置ACL和Not模式

When setting the acl or dacl and not setting the mode or mode_set_masked attributes, the permission bits of the mode need to be derived from the ACL. In this case, the ACL attribute SHOULD be set as given. The nine low-order bits of the mode attribute (MODE4_R*, MODE4_W*, MODE4_X*) MUST be modified to match the result of the method in Section 6.3.2. The three high-order bits of the mode (MODE4_SUID, MODE4_SGID, MODE4_SVTX) SHOULD remain unchanged.

当设置acl或dacl而不设置mode或mode_set_masked属性时,需要从acl派生模式的权限位。在这种情况下,ACL属性应按给定值设置。必须修改模式属性的九个低阶位(MODE4_R*、MODE4_W*、MODE4_X*),以匹配第6.3.2节中方法的结果。模式的三个高阶位(MODE4_SUID、MODE4_SGID、MODE4_SVTX)应保持不变。

6.4.1.3. Setting Both ACL and Mode
6.4.1.3. 设置ACL和模式

When setting both the mode (includes use of either the mode attribute or the mode_set_masked attribute) and the acl or dacl attributes in the same operation, the attributes MUST be applied in this order: mode (or mode_set_masked), then ACL. The mode-related attribute is set as given, then the ACL attribute is set as given, possibly changing the final mode, as described above in Section 6.4.1.2.

在同一操作中设置模式(包括使用模式属性或模式设置屏蔽属性)和acl或dacl属性时,必须按以下顺序应用属性:模式(或模式设置屏蔽),然后是acl。模式相关属性设置为给定,然后ACL属性设置为给定,可能会更改最终模式,如上文第6.4.1.2节所述。

6.4.2. Retrieving the Mode and/or ACL Attributes
6.4.2. 检索模式和/或ACL属性

This section applies only to servers that support both the mode and ACL attributes.

本节仅适用于同时支持模式和ACL属性的服务器。

Some server implementations may have a concept of "objects without ACLs", meaning that all permissions are granted and denied according to the mode attribute and that no ACL attribute is stored for that object. If an ACL attribute is requested of such a server, the server SHOULD return an ACL that does not conflict with the mode; that is to say, the ACL returned SHOULD represent the nine low-order bits of the mode attribute (MODE4_R*, MODE4_W*, MODE4_X*) as described in Section 6.3.2.

一些服务器实现可能有“没有ACL的对象”的概念,这意味着根据mode属性授予和拒绝所有权限,并且没有为该对象存储ACL属性。如果请求此类服务器的ACL属性,则服务器应返回与模式不冲突的ACL;也就是说,返回的ACL应表示第6.3.2节中描述的模式属性(MODE4_R*、MODE4_W*、MODE4_X*)的九个低阶位。

For other server implementations, the ACL attribute is always present for every object. Such servers SHOULD store at least the three high-order bits of the mode attribute (MODE4_SUID, MODE4_SGID, MODE4_SVTX). The server SHOULD return a mode attribute if one is requested, and the low-order nine bits of the mode (MODE4_R*, MODE4_W*, MODE4_X*) MUST match the result of applying the method in Section 6.3.2 to the ACL attribute.

对于其他服务器实现,ACL属性始终存在于每个对象中。此类服务器应至少存储模式属性的三个高阶位(MODE4_SUID、MODE4_SGID、MODE4_SVTX)。如果请求模式属性,服务器应返回一个模式属性,模式的低阶九位(MODE4_R*、MODE4_W*、MODE4_X*)必须与将第6.3.2节中的方法应用于ACL属性的结果相匹配。

6.4.3. Creating New Objects
6.4.3. 创建新对象

If a server supports any ACL attributes, it may use the ACL attributes on the parent directory to compute an initial ACL attribute for a newly created object. This will be referred to as the inherited ACL within this section. The act of adding one or more ACEs to the inherited ACL that are based upon ACEs in the parent directory's ACL will be referred to as inheriting an ACE within this section.

如果服务器支持任何ACL属性,它可以使用父目录上的ACL属性来计算新创建对象的初始ACL属性。这将在本节中称为继承的ACL。将基于父目录ACL中ACE的一个或多个ACE添加到继承的ACL的行为在本节中称为继承ACE。

Implementors should standardize what the behavior of CREATE and OPEN must be depending on the presence or absence of the mode and ACL attributes.

实现者应该根据mode和ACL属性的存在与否来标准化CREATE和OPEN的行为。

1. If just the mode is given in the call:

1. 如果通话中仅给出了模式:

In this case, inheritance SHOULD take place, but the mode MUST be applied to the inherited ACL as described in Section 6.4.1.1, thereby modifying the ACL.

在这种情况下,应该进行继承,但必须按照第6.4.1.1节所述将该模式应用于继承的ACL,从而修改ACL。

2. If just the ACL is given in the call:

2. 如果调用中仅给出了ACL:

In this case, inheritance SHOULD NOT take place, and the ACL as defined in the CREATE or OPEN will be set without modification, and the mode modified as in Section 6.4.1.2.

在这种情况下,不应发生继承,并且在创建或打开中定义的ACL将在不进行修改的情况下进行设置,并且模式将按照第6.4.1.2节的规定进行修改。

3. If both mode and ACL are given in the call:

3. 如果调用中同时给出了mode和ACL:

In this case, inheritance SHOULD NOT take place, and both attributes will be set as described in Section 6.4.1.3.

在这种情况下,不应发生继承,两个属性都将按照第6.4.1.3节所述进行设置。

4. If neither mode nor ACL is given in the call:

4. 如果调用中未给出模式或ACL:

In the case where an object is being created without any initial attributes at all, e.g., an OPEN operation with an opentype4 of OPEN4_CREATE and a createmode4 of EXCLUSIVE4, inheritance SHOULD NOT take place (note that EXCLUSIVE4_1 is a better choice of createmode4, since it does permit initial attributes). Instead, the server SHOULD set permissions to deny all access to the newly created object. It is expected that the appropriate client will set the desired attributes in a subsequent SETATTR operation, and the server SHOULD allow that operation to succeed, regardless of what permissions the object is created with. For example, an empty ACL denies all permissions, but the server should allow the owner's SETATTR to succeed even though WRITE_ACL is implicitly denied.

如果创建对象时根本没有任何初始属性,例如,opentype4为OPEN4_CREATE,createmode4为EXCLUSIVE4的开放操作,则不应发生继承(请注意,EXCLUSIVE4_1是createmode4的更好选择,因为它允许初始属性)。相反,服务器应该设置权限以拒绝对新创建的对象的所有访问。预期适当的客户端将在后续的SETATTR操作中设置所需的属性,并且服务器应允许该操作成功,而不管使用什么权限创建对象。例如,空ACL拒绝所有权限,但服务器应允许所有者的SETATTR成功,即使WRITE_ACL被隐式拒绝。

In other cases, inheritance SHOULD take place, and no modifications to the ACL will happen. The mode attribute, if supported, MUST be as computed in Section 6.3.2, with the MODE4_SUID, MODE4_SGID, and MODE4_SVTX bits clear. If no inheritable ACEs exist on the parent directory, the rules for creating acl, dacl, or sacl attributes are implementation defined. If either the dacl or sacl attribute is supported, then the ACL4_DEFAULTED flag SHOULD be set on the newly created attributes.

在其他情况下,应该进行继承,并且不会对ACL进行任何修改。如果支持模式属性,则必须按照第6.3.2节中的计算,清除MODE4_SUID、MODE4_SGID和MODE4_SVTX位。如果父目录上不存在可继承的ACE,则创建acl、dacl或sacl属性的规则由实现定义。如果支持dacl或sacl属性,则应在新创建的属性上设置ACL4_默认标志。

6.4.3.1. The Inherited ACL
6.4.3.1. 继承的ACL

If the object being created is not a directory, the inherited ACL SHOULD NOT inherit ACEs from the parent directory ACL unless the ACE4_FILE_INHERIT_FLAG is set.

如果要创建的对象不是目录,则继承的ACL不应从父目录ACL继承ACE,除非设置了ACE4_FILE_inherit_标志。

If the object being created is a directory, the inherited ACL should inherit all inheritable ACEs from the parent directory, that is, those that have the ACE4_FILE_INHERIT_ACE or ACE4_DIRECTORY_INHERIT_ACE flag set. If the inheritable ACE has ACE4_FILE_INHERIT_ACE set but ACE4_DIRECTORY_INHERIT_ACE is clear, the inherited ACE on the newly created directory MUST have the ACE4_INHERIT_ONLY_ACE flag set to prevent the directory from being affected by ACEs meant for non-directories.

如果要创建的对象是目录,则继承的ACL应继承父目录中的所有可继承ACE,即设置了ACE4\u文件\u继承\u ACE或ACE4\u目录\u继承\u ACE标志的ACE。如果可继承ACE设置了ACE4\u文件\u继承\u ACE,但ACE4\u目录\u继承\u ACE是清除的,则新创建目录上的继承ACE必须设置ACE4\u仅继承\u ACE标志,以防止目录受非目录的ACE影响。

When a new directory is created, the server MAY split any inherited ACE that is both inheritable and effective (in other words, that has neither ACE4_INHERIT_ONLY_ACE nor ACE4_NO_PROPAGATE_INHERIT_ACE set), into two ACEs, one with no inheritance flags and one with ACE4_INHERIT_ONLY_ACE set. (In the case of a dacl or sacl attribute, both of those ACEs SHOULD also have the ACE4_INHERITED_ACE flag set.)

创建新目录时,服务器可以将任何既可继承又有效的继承ACE(换句话说,既没有ACE4_INHERIT_ONLY_ACE,也没有ACE4_NO_PROPAGATE_INHERIT_ACE集)拆分为两个ACE,一个没有继承标志,另一个有ACE4_INHERIT_ONLY_ACE集。(对于dacl或sacl属性,这两个ACE还应设置ACE4_继承_ACE标志。)

This makes it simpler to modify the effective permissions on the directory without modifying the ACE that is to be inherited to the new directory's children.

这使得修改目录上的有效权限变得更简单,而无需修改要继承到新目录子目录的ACE。

6.4.3.2. Automatic Inheritance
6.4.3.2. 自动继承

The acl attribute consists only of an array of ACEs, but the sacl (Section 6.2.3) and dacl (Section 6.2.2) attributes also include an additional flag field.

acl属性仅由ACE数组组成,但sacl(第6.2.3节)和dacl(第6.2.2节)属性还包括一个附加的标志字段。

   struct nfsacl41 {
           aclflag4        na41_flag;
           nfsace4         na41_aces<>;
   };
        
   struct nfsacl41 {
           aclflag4        na41_flag;
           nfsace4         na41_aces<>;
   };
        

The flag field applies to the entire sacl or dacl; three flag values are defined:

标志字段适用于整个sacl或dacl;定义了三个标志值:

   const ACL4_AUTO_INHERIT         = 0x00000001;
   const ACL4_PROTECTED            = 0x00000002;
   const ACL4_DEFAULTED            = 0x00000004;
        
   const ACL4_AUTO_INHERIT         = 0x00000001;
   const ACL4_PROTECTED            = 0x00000002;
   const ACL4_DEFAULTED            = 0x00000004;
        

and all other bits must be cleared. The ACE4_INHERITED_ACE flag may be set in the ACEs of the sacl or dacl (whereas it must always be cleared in the acl).

所有其他位都必须清除。ACE4_继承的_ACE标志可以在sacl或dacl的ACE中设置(但必须始终在acl中清除)。

Together these features allow a server to support automatic inheritance, which we now explain in more detail.

这些特性一起允许服务器支持自动继承,我们现在将更详细地解释这一点。

Inheritable ACEs are normally inherited by child objects only at the time that the child objects are created; later modifications to inheritable ACEs do not result in modifications to inherited ACEs on descendants.

可继承的ACE通常仅在创建子对象时由子对象继承;以后对可继承ACE的修改不会导致对后代上继承的ACE的修改。

However, the dacl and sacl provide an OPTIONAL mechanism that allows a client application to propagate changes to inheritable ACEs to an entire directory hierarchy.

但是,dacl和sacl提供了一种可选机制,允许客户端应用程序将对可继承ACE的更改传播到整个目录层次结构。

A server that supports this performs inheritance at object creation time in the normal way, and SHOULD set the ACE4_INHERITED_ACE flag on any inherited ACEs as they are added to the new object.

支持此功能的服务器在对象创建时以正常方式执行继承,并应在将任何继承的ACE添加到新对象时在其上设置ACE4_INHERITED_ACE标志。

A client application such as an ACL editor may then propagate changes to inheritable ACEs on a directory by recursively traversing that directory's descendants and modifying each ACL encountered to remove any ACEs with the ACE4_INHERITED_ACE flag and to replace them by the new inheritable ACEs (also with the ACE4_INHERITED_ACE flag set). It uses the existing ACE inheritance flags in the obvious way to decide

然后,客户端应用程序(如ACL编辑器)可以通过递归遍历目录的子体并修改遇到的每个ACL来将更改传播到目录上的可继承ACE,以删除带有ACE4_继承的_ACE标志的任何ACE,并将其替换为新的可继承ACE(也带有ACE4_继承的_ACE标志集)。它以显而易见的方式使用现有ACE继承标志来决定

which ACEs to propagate. (Note that it may encounter further inheritable ACEs when descending the directory hierarchy and that those will also need to be taken into account when propagating inheritable ACEs to further descendants.)

它可以传播。(请注意,在降低目录层次结构时,它可能会遇到更多可继承的ACE,并且在将可继承的ACE传播到更多后代时,也需要考虑这些ACE。)

The reach of this propagation may be limited in two ways: first, automatic inheritance is not performed from any directory ACL that has the ACL4_AUTO_INHERIT flag cleared; and second, automatic inheritance stops wherever an ACL with the ACL4_PROTECTED flag is set, preventing modification of that ACL and also (if the ACL is set on a directory) of the ACL on any of the object's descendants.

此传播的范围可能受到两种方式的限制:首先,不会从清除了ACL4\u AUTO\u INHERIT标志的任何目录ACL执行自动继承;第二,只要设置了具有ACL4_PROTECTED标志的ACL,自动继承就会停止,从而防止修改该ACL以及(如果ACL设置在目录上)对象的任何子体上的ACL。

This propagation is performed independently for the sacl and the dacl attributes; thus, the ACL4_AUTO_INHERIT and ACL4_PROTECTED flags may be independently set for the sacl and the dacl, and propagation of one type of acl may continue down a hierarchy even where propagation of the other acl has stopped.

该传播针对sacl和dacl属性独立执行;因此,可以为sacl和dacl独立地设置ACL4_AUTO_INHERIT和ACL4_PROTECTED标志,并且一种类型的acl的传播可以沿着层次结构继续下去,即使在另一acl的传播已经停止的情况下。

New objects should be created with a dacl and a sacl that both have the ACL4_PROTECTED flag cleared and the ACL4_AUTO_INHERIT flag set to the same value as that on, respectively, the sacl or dacl of the parent object.

应使用dacl和sacl创建新对象,这两个dacl都清除了ACL4_受保护标志,并且ACL4_自动_继承标志分别设置为与父对象的sacl或dacl相同的值。

Both the dacl and sacl attributes are RECOMMENDED, and a server may support one without supporting the other.

建议同时使用dacl和sacl属性,并且服务器可能支持其中一个而不支持另一个。

A server that supports both the old acl attribute and one or both of the new dacl or sacl attributes must do so in such a way as to keep all three attributes consistent with each other. Thus, the ACEs reported in the acl attribute should be the union of the ACEs reported in the dacl and sacl attributes, except that the ACE4_INHERITED_ACE flag must be cleared from the ACEs in the acl. And of course a client that queries only the acl will be unable to determine the values of the sacl or dacl flag fields.

同时支持旧acl属性和一个或两个新dacl或sacl属性的服务器必须这样做,以保持所有三个属性彼此一致。因此,acl属性中报告的ACE应该是dacl和sacl属性中报告的ACE的并集,但ACE4_继承的_ACE标志必须从acl中的ACE中清除。当然,只查询acl的客户端将无法确定sacl或dacl标志字段的值。

When a client performs a SETATTR for the acl attribute, the server SHOULD set the ACL4_PROTECTED flag to true on both the sacl and the dacl. By using the acl attribute, as opposed to the dacl or sacl attributes, the client signals that it may not understand automatic inheritance, and thus cannot be trusted to set an ACL for which automatic inheritance would make sense.

当客户端对acl属性执行SETATTR时,服务器应在sacl和dacl上将ACL4\u PROTECTED标志设置为true。通过使用acl属性,而不是dacl或sacl属性,客户机发出信号,表明它可能不理解自动继承,因此无法信任它设置自动继承有意义的acl。

When a client application queries an ACL, modifies it, and sets it again, it should leave any ACEs marked with ACE4_INHERITED_ACE unchanged, in their original order, at the end of the ACL. If the application is unable to do this, it should set the ACL4_PROTECTED

当客户机应用程序查询、修改并再次设置ACL时,它应在ACL末尾保留标记为ACE4_继承_ACE的所有ACE,并保持其原始顺序不变。如果应用程序无法执行此操作,则应将ACL4\u设置为受保护

flag. This behavior is not enforced by servers, but violations of this rule may lead to unexpected results when applications perform automatic inheritance.

旗帜服务器不强制执行此行为,但当应用程序执行自动继承时,违反此规则可能会导致意外结果。

If a server also supports the mode attribute, it SHOULD set the mode in such a way that leaves inherited ACEs unchanged, in their original order, at the end of the ACL. If it is unable to do so, it SHOULD set the ACL4_PROTECTED flag on the file's dacl.

如果服务器还支持mode属性,则应设置模式,使继承的ACE在ACL末尾保持原始顺序不变。如果无法执行此操作,则应在文件的dacl上设置ACL4_PROTECTED标志。

Finally, in the case where the request that creates a new file or directory does not also set permissions for that file or directory, and there are also no ACEs to inherit from the parent's directory, then the server's choice of ACL for the new object is implementation-dependent. In this case, the server SHOULD set the ACL4_DEFAULTED flag on the ACL it chooses for the new object. An application performing automatic inheritance takes the ACL4_DEFAULTED flag as a sign that the ACL should be completely replaced by one generated using the automatic inheritance rules.

最后,如果创建新文件或目录的请求没有为该文件或目录设置权限,并且也没有要从父目录继承的ACE,那么服务器为新对象选择ACL取决于实现。在这种情况下,服务器应该在为新对象选择的ACL上设置ACL4_默认标志。执行自动继承的应用程序将ACL4_default标志作为一个标志,表明ACL应完全替换为使用自动继承规则生成的ACL。

7. Single-Server Namespace
7. 单服务器名称空间

This section describes the NFSv4 single-server namespace. Single-server namespaces may be presented directly to clients, or they may be used as a basis to form larger multi-server namespaces (e.g., site-wide or organization-wide) to be presented to clients, as described in Section 11.

本节介绍NFSv4单服务器命名空间。如第11节所述,单服务器名称空间可以直接呈现给客户端,也可以用作形成更大的多服务器名称空间(例如,站点范围或组织范围)的基础,以呈现给客户端。

7.1. Server Exports
7.1. 服务器导出

On a UNIX server, the namespace describes all the files reachable by pathnames under the root directory or "/". On a Windows server, the namespace constitutes all the files on disks named by mapped disk letters. NFS server administrators rarely make the entire server's file system namespace available to NFS clients. More often, portions of the namespace 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 sent a string that identified the export name within the namespace and the server returned the root filehandle for that export. The MOUNT protocol also provided an EXPORTS procedure that enumerated the server's exports.

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

7.2. Browsing Exports
7.2. 浏览导出

The NFSv4.1 protocol provides a root filehandle that clients can use to obtain filehandles for the exports of a particular server, via a series of LOOKUP operations within a COMPOUND, to traverse a path. A common user experience is to use a graphical user interface (perhaps

NFSv4.1协议提供了一个根文件句柄,客户机可以使用该根文件句柄,通过一系列复合内的查找操作来获取特定服务器导出的文件句柄,从而遍历路径。常见的用户体验是使用图形用户界面(可能是

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.

一个文件“打开”对话框窗口),通过逐步浏览目录树查找文件。客户端必须能够通过单个组件、渐进式查找操作从一个导出移动到另一个导出。

This style of browsing is not well supported by the NFSv3 protocol. In NFSv3, the client expects all LOOKUP operations to remain within a single server file system. For example, the device attribute will not change. This prevents a client from taking namespace paths that span exports.

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

In the case of NFSv3, an automounter on the client can obtain a snapshot of the server's namespace 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 namespace on the client. The parts of the namespace that are not exported by the server are filled in with directories that might be constructed similarly to an NFSv4.1 "pseudo file system" (see Section 7.3) that allows the user to browse from one mounted file system to another. There is a drawback to this representation of the server's namespace on the client: it is static. If the server administrator adds a new export, the client will be unaware of it.

对于NFSv3,客户机上的自动挂载程序可以使用挂载协议的导出过程获取服务器名称空间的快照。如果它理解服务器的路径名语法,就可以在客户端上创建服务器名称空间的映像。服务器未导出的命名空间部分由目录填充,这些目录的构造可能类似于NFSv4.1“伪文件系统”(参见第7.3节),允许用户从一个装入的文件系统浏览到另一个装入的文件系统。这种在客户端上表示服务器名称空间的方法有一个缺点:它是静态的。如果服务器管理员添加了一个新的导出,客户端将不知道它。

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

NFSv4.1 servers avoid this namespace inconsistency by presenting all the exports for a given server within the framework of a single namespace for that server. An NFSv4.1 client uses LOOKUP and READDIR operations to browse seamlessly from one export to another.

NFSv4.1服务器通过在给定服务器的单个名称空间框架内呈现该服务器的所有导出来避免这种名称空间不一致。NFSv4.1客户端使用查找和READDIR操作从一个导出无缝浏览到另一个导出。

Where there are portions of the server namespace that are not exported, clients require some way of traversing those portions to reach actual exported file systems. A technique that servers may use to provide for this is to bridge the unexported portion of the namespace via a "pseudo file system" that provides a view of exported directories only. A pseudo file system has a unique fsid and behaves like a normal, read-only file system.

当服务器名称空间的某些部分未导出时,客户端需要以某种方式遍历这些部分以到达实际导出的文件系统。服务器可以使用的一种技术是通过“伪文件系统”桥接名称空间的未报告部分,该系统只提供导出目录的视图。伪文件系统具有唯一的fsid,其行为类似于普通的只读文件系统。

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

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

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

Each of the pseudo file systems is considered a separate entity and therefore MUST have its own fsid, unique among all the fsids for that server.

每个伪文件系统都被视为一个单独的实体,因此必须有自己的fsid,在该服务器的所有fsid中是唯一的。

7.4. Multiple Roots
7.4. 多根

Certain operating environments are sometimes described as having "multiple roots". In such environments, individual file systems are commonly represented by disk or volume names. NFSv4 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.

某些操作环境有时被描述为具有“多根”。在这种环境中,单个文件系统通常由磁盘或卷名表示。这些平台的NFSv4服务器可以在这些根名称之上构造一个伪文件系统,以便磁盘字母或卷名称只是伪根中的目录名。

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

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

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

Because it is quite likely that servers will implement pseudo file systems using volatile filehandles, clients need to be prepared for them, rather than assuming that all filehandles will be persistent.

因为服务器很可能会使用易失性文件句柄实现伪文件系统,所以客户端需要为它们做好准备,而不是假设所有文件句柄都是持久的。

7.6. Exported Root
7.6. 导出根

If the server's root file system is exported, one might conclude that a pseudo file system is unneeded. This is not necessarily so. Assume the following file systems on a server:

如果导出服务器的根文件系统,可能会得出不需要伪文件系统的结论。事实未必如此。假设服务器上有以下文件系统:

           /       fs1  (exported)
           /a      fs2  (not exported)
           /a/b    fs3  (exported)
        
           /       fs1  (exported)
           /a      fs2  (not exported)
           /a/b    fs3  (exported)
        

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

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

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

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

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

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

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

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

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

It is the server's responsibility to present the pseudo file system that is complete to the client. If the client sends a LOOKUP request for the path /a/b/c/d, the server's response is the filehandle of the root of the file system /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 file system /a/b.

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

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

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

7.8. Security Policy and Namespace Presentation
7.8. 安全策略和命名空间表示

Because NFSv4 clients possess the ability to change the security mechanisms used, after determining what is allowed, by using SECINFO and SECINFO_NONAME, the server SHOULD NOT present a different view of the namespace based on the security mechanism being used by a client. Instead, it should present a consistent view and return NFS4ERR_WRONGSEC if an attempt is made to access data with an inappropriate security mechanism.

由于NFSv4客户端能够通过使用SECINFO和SECINFO_NONAME来更改所使用的安全机制,因此在确定允许使用的安全机制后,服务器不应基于客户端使用的安全机制呈现不同的命名空间视图。相反,如果试图使用不适当的安全机制访问数据,它应该提供一致的视图并返回NFS4ERR_-errosec。

If security considerations make it necessary to hide the existence of a particular file system, as opposed to all of the data within it, the server can apply the security policy of a shared resource in the server's namespace to components of the resource's ancestors. For example:

如果出于安全考虑,需要隐藏特定文件系统的存在,而不是其中的所有数据,则服务器可以将服务器命名空间中共享资源的安全策略应用于资源祖先的组件。例如:

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

The /a/b/MySecretProject directory is a real file system and is the shared resource. Suppose the security policy for /a/b/ MySecretProject is Kerberos with integrity and it is desired to limit knowledge of the existence of this file system. In this case, the server should apply the same security policy to /a/b. This allows for knowledge of the existence of a file system to be secured when desirable.

/a/b/MySecretProject目录是一个真正的文件系统,是共享资源。假设/a/b/MySecretProject的安全策略是具有完整性的Kerberos,需要限制对该文件系统存在的了解。在这种情况下,服务器应该对/a/b应用相同的安全策略。这允许在需要时了解要保护的文件系统的存在。

For the case of the use of multiple, disjoint security mechanisms in the server's resources, applying that sort of policy would result in the higher-level file system not being accessible using any security flavor. Therefore, that sort of configuration is not compatible with hiding the existence (as opposed to the contents) from clients using multiple disjoint sets of security flavors.

对于在服务器资源中使用多个不相交的安全机制的情况,应用这种策略将导致无法使用任何安全特性访问更高级别的文件系统。因此,这种配置与使用多个不相交的安全风格集向客户端隐藏存在(与内容相反)是不兼容的。

In other circumstances, a desirable policy is for the security of a particular object in the server's namespace to include the union of all security mechanisms of all direct descendants. A common and convenient practice, unless strong security requirements dictate otherwise, is to make the entire the pseudo file system accessible by all of the valid security mechanisms.

在其他情况下,理想的策略是服务器命名空间中特定对象的安全性,以包括所有直接子体的所有安全机制的联合。除非强烈的安全要求另有规定,否则一种常见且方便的做法是让所有有效的安全机制都可以访问整个伪文件系统。

Where there is concern about the security of data on the network, clients should use strong security mechanisms to access the pseudo file system in order to prevent man-in-the-middle attacks.

如果担心网络上数据的安全性,客户端应使用强大的安全机制访问伪文件系统,以防止中间人攻击。

8. State Management
8. 国家管理

Integrating locking into the NFS protocol necessarily causes it to be stateful. With the inclusion of such features as share reservations, file and directory delegations, recallable layouts, and support for mandatory byte-range locking, the protocol becomes substantially more dependent on proper management of state than the traditional combination of NFS and NLM (Network Lock Manager) [46]. These features include expanded locking facilities, which provide some measure of inter-client exclusion, but the state also offers features not readily providable using a stateless model. There are three components to making this state manageable:

将锁定集成到NFS协议中必然会导致它是有状态的。由于包含了共享保留、文件和目录委派、可重新调用的布局以及对强制字节范围锁定的支持等功能,与NFS和NLM(网络锁管理器)的传统组合相比,协议实质上更加依赖于正确的状态管理[46]。这些特性包括扩展的锁定功能,这些功能提供了某种程度的客户端间排除,但该州也提供了使用无状态模型不容易提供的特性。要使此状态易于管理,有三个组件:

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 requests changes in locks and the server responds with the changes made. Non-client-initiated changes in locking state are infrequent. The client receives prompt notification of such changes and can adjust its view of the locking state to reflect the server's changes.

在此模型中,服务器拥有状态信息。客户端请求更改锁,服务器响应所做的更改。锁定状态中非客户端启动的更改很少。客户机收到此类更改的提示通知,并可以调整其锁定状态视图以反映服务器的更改。

Individual pieces of state created by the server and passed to the client at its request are represented by 128-bit stateids. These stateids may represent a particular open file, a set of byte-range locks held by a particular owner, or a recallable delegation of privileges to access a file in particular ways or at a particular location.

由服务器创建并在客户机请求时传递给客户机的各个状态段由128位StateID表示。这些stateID可以表示特定打开的文件、特定所有者持有的一组字节范围锁,或者以特定方式或在特定位置访问文件的可重新分配的权限。

In all cases, there is a transition from the most general information that represents a client as a whole to the eventual lightweight stateid used for most client and server locking interactions. The details of this transition will vary with the type of object but it always starts with a client ID.

在所有情况下,都会从代表整个客户机的最一般信息过渡到用于大多数客户机和服务器锁定交互的最终轻量级stateid。此转换的详细信息将随对象的类型而变化,但它始终以客户机ID开始。

8.1. Client and Session ID
8.1. 客户端和会话ID

A client must establish a client ID (see Section 2.4) and then one or more sessionids (see Section 2.10) before performing any operations to open, byte-range lock, delegate, or obtain a layout for a file object. Each session ID is associated with a specific client ID, and thus serves as a shorthand reference to an NFSv4.1 client.

在执行任何打开、字节范围锁定、委托或获取文件对象布局的操作之前,客户端必须先建立客户端ID(请参见第2.4节),然后建立一个或多个SessionID(请参见第2.10节)。每个会话ID都与特定的客户端ID相关联,因此用作NFSv4.1客户端的速记引用。

For some types of locking interactions, the client will represent some number of internal locking entities called "owners", which normally correspond to processes internal to the client. For other types of locking-related objects, such as delegations and layouts, no such intermediate entities are provided for, and the locking-related objects are considered to be transferred directly between the server and a unitary client.

对于某些类型的锁定交互,客户机将表示一些称为“所有者”的内部锁定实体,这些实体通常对应于客户机内部的流程。对于其他类型的锁定相关对象,例如委托和布局,不提供此类中间实体,并且锁定相关对象被认为是在服务器和单一客户端之间直接传输的。

8.2. Stateid Definition
8.2. Stateid定义

When the server grants a lock of any type (including opens, byte-range locks, delegations, and layouts), it responds with a unique stateid that represents a set of locks (often a single lock) for the same file, of the same type, and sharing the same ownership characteristics. Thus, opens of the same file by different open-owners each have an identifying stateid. Similarly, each set of byte-range locks on a file owned by a specific lock-owner has its own identifying stateid. Delegations and layouts also have associated stateids by which they may be referenced. The stateid is used as a shorthand reference to a lock or set of locks, and given a stateid, the server can determine the associated state-owner or state-owners

当服务器授予任何类型的锁(包括打开、字节范围锁、委派和布局)时,它将使用唯一的stateid进行响应,该stateid表示同一文件、同一类型和共享相同所有权特征的一组锁(通常是单个锁)。因此,由不同的打开所有者打开的同一个文件都有一个标识stateid。类似地,特定锁所有者拥有的文件上的每一组字节范围锁都有自己的标识stateid。委托和布局还具有关联的stateID,可以通过它们进行引用。stateid用作一个锁或一组锁的简写引用,并且给定stateid,服务器可以确定关联的状态所有者或状态所有者

(in the case of an open-owner/lock-owner pair) and the associated filehandle. When stateids are used, the current filehandle must be the one associated with that stateid.

(对于打开的所有者/锁所有者对)和关联的文件句柄。使用stateid时,当前文件句柄必须是与该stateid关联的文件句柄。

All stateids associated with a given client ID are associated with a common lease that represents the claim of those stateids and the objects they represent to be maintained by the server. See Section 8.3 for a discussion of the lease.

与给定客户机ID关联的所有StateID都与一个公共租约关联,该租约表示这些StateID及其表示的要由服务器维护的对象的声明。有关租赁的讨论,请参见第8.3节。

The server may assign stateids independently for different clients. A stateid with the same bit pattern for one client may designate an entirely different set of locks for a different client. The stateid is always interpreted with respect to the client ID associated with the current session. Stateids apply to all sessions associated with the given client ID, and the client may use a stateid obtained from one session on another session associated with the same client ID.

服务器可以为不同的客户端独立分配StateID。一个客户端具有相同位模式的stateid可能会为不同的客户端指定一组完全不同的锁。stateid始终根据与当前会话关联的客户端ID进行解释。stateid应用于与给定客户机ID关联的所有会话,并且客户机可以在与相同客户机ID关联的另一个会话上使用从一个会话获得的stateid。

8.2.1. Stateid Types
8.2.1. Stateid类型

With the exception of special stateids (see Section 8.2.3), each stateid represents locking objects of one of a set of types defined by the NFSv4.1 protocol. Note that in all these cases, where we speak of guarantee, it is understood there are situations such as a client restart, or lock revocation, that allow the guarantee to be voided.

除特殊stateid(见第8.2.3节)外,每个stateid表示NFSv4.1协议定义的一组类型之一的锁定对象。请注意,在所有这些情况下,当我们谈到担保时,可以理解存在允许担保无效的情况,例如客户端重新启动或锁撤销。

o Stateids may represent opens of files.

o StateID可以表示打开的文件。

Each stateid in this case represents the OPEN state for a given client ID/open-owner/filehandle triple. Such stateids are subject to change (with consequent incrementing of the stateid's seqid) in response to OPENs that result in upgrade and OPEN_DOWNGRADE operations.

本例中的每个stateid表示给定客户机ID/开放所有者/filehandle三元组的开放状态。此类stateid可能会随着导致升级和OPEN\u降级操作的打开而更改(随后stateid的seqid会增加)。

o Stateids may represent sets of byte-range locks.

o StateID可以表示字节范围锁的集合。

All locks held on a particular file by a particular owner and gotten under the aegis of a particular open file are associated with a single stateid with the seqid being incremented whenever LOCK and LOCKU operations affect that set of locks.

由特定所有者在特定文件上持有并在特定打开文件的保护下获得的所有锁都与单个stateid关联,只要锁和LOCKU操作影响到该锁集,seqid就会增加。

o Stateids may represent file delegations, which are recallable guarantees by the server to the client that other clients will not reference or modify a particular file, until the delegation is returned. In NFSv4.1, file delegations may be obtained on both regular and non-regular files.

o StateID可以表示文件委托,这是服务器向客户机提供的可重新调用的保证,在委托返回之前,其他客户机不会引用或修改特定文件。在NFSv4.1中,可以在常规文件和非常规文件上获得文件授权。

A stateid represents a single delegation held by a client for a particular filehandle.

stateid表示客户端为特定文件句柄持有的单个委托。

o Stateids may represent directory delegations, which are recallable guarantees by the server to the client that other clients will not modify the directory, until the delegation is returned.

o StateID可以表示目录委托,这是服务器向客户机提供的可重新调用的保证,在委托返回之前,其他客户机不会修改目录。

A stateid represents a single delegation held by a client for a particular directory filehandle.

stateid表示客户端为特定目录文件句柄持有的单个委托。

o Stateids may represent layouts, which are recallable guarantees by the server to the client that particular files may be accessed via an alternate data access protocol at specific locations. Such access is limited to particular sets of byte-ranges and may proceed until those byte-ranges are reduced or the layout is returned.

o StateID可以表示布局,这是服务器向客户机提供的可重新调用的保证,即特定文件可以在特定位置通过备用数据访问协议访问。这种访问仅限于特定的字节范围集,并且可以继续进行,直到减少这些字节范围或返回布局。

A stateid represents the set of all layouts held by a particular client for a particular filehandle with a given layout type. The seqid is updated as the layouts of that set of byte-ranges change, via layout stateid changing operations such as LAYOUTGET and LAYOUTRETURN.

stateid表示特定客户端为具有给定布局类型的特定文件句柄保留的所有布局的集合。通过LAYOUTGET和LAYOUTRETURN等layout stateid更改操作,当该组字节范围的布局更改时,会更新seqid。

8.2.2. Stateid Structure
8.2.2. 状态结构

Stateids are divided into two fields, a 96-bit "other" field identifying the specific set of locks and a 32-bit "seqid" sequence value. Except in the case of special stateids (see Section 8.2.3), a particular value of the "other" field denotes a set of locks of the same type (for example, byte-range locks, opens, delegations, or layouts), for a specific file or directory, and sharing the same ownership characteristics. The seqid designates a specific instance of such a set of locks, and is incremented to indicate changes in such a set of locks, either by the addition or deletion of locks from the set, a change in the byte-range they apply to, or an upgrade or downgrade in the type of one or more locks.

StateID分为两个字段,一个96位的“other”字段标识特定的锁集,另一个32位的“seqid”序列值。除特殊stateID(见第8.2.3节)外,“其他”字段的特定值表示一组相同类型的锁(例如,字节范围锁、打开、委托或布局),用于特定文件或目录,并共享相同的所有权特征。seqid指定此类锁集合的特定实例,并递增以指示此类锁集合中的更改,通过从集合中添加或删除锁、更改其应用的字节范围或升级或降级一个或多个锁的类型。

When such a set of locks is first created, the server returns a stateid with seqid value of one. On subsequent operations that modify the set of locks, the server is required to increment the "seqid" field by one whenever it returns a stateid for the same state-owner/file/type combination and there is some change in the set of locks actually designated. In this case, the server will return a stateid with an "other" field the same as previously used for that state-owner/file/type combination, with an incremented "seqid" field. This pattern continues until the seqid is incremented past NFS4_UINT32_MAX, and one (not zero) is the next seqid value.

当第一次创建这样一组锁时,服务器返回一个seqid值为1的stateid。在修改锁集的后续操作中,每当服务器返回同一状态所有者/文件/类型组合的stateid并且实际指定的锁集发生一些更改时,服务器都需要将“seqid”字段增加1。在这种情况下,服务器将返回一个stateid,其中包含一个“other”字段,与之前用于该状态所有者/文件/类型组合的字段相同,并包含一个递增的“seqid”字段。此模式将持续,直到seqid的增量超过NFS4_UINT32_MAX,并且一(不是零)是下一个seqid值。

The purpose of the incrementing of the seqid is to allow the server to communicate to the client the order in which operations that modified locking state associated with a stateid have been processed and to make it possible for the client to send requests that are conditional on the set of locks not having changed since the stateid in question was returned.

增加seqid的目的是允许服务器向客户机传达处理与stateid相关联的修改锁定状态的操作的顺序,并使客户机能够发送请求,该请求以自相关stateid之后未更改的锁集为条件他回来了。

Except for layout stateids (Section 12.5.3), when a client sends a stateid to the server, it has two choices with regard to the seqid sent. It may set the seqid to zero to indicate to the server that it wishes the most up-to-date seqid for that stateid's "other" field to be used. This would be the common choice in the case of a stateid sent with a READ or WRITE operation. It also may set a non-zero value, in which case the server checks if that seqid is the correct one. In that case, the server is required to return NFS4ERR_OLD_STATEID if the seqid is lower than the most current value and NFS4ERR_BAD_STATEID if the seqid is greater than the most current value. This would be the common choice in the case of stateids sent with a CLOSE or OPEN_DOWNGRADE. Because OPENs may be sent in parallel for the same owner, a client might close a file without knowing that an OPEN upgrade had been done by the server, changing the lock in question. If CLOSE were sent with a zero seqid, the OPEN upgrade would be cancelled before the client even received an indication that an upgrade had happened.

除了布局stateid(第12.5.3节),当客户机向服务器发送stateid时,对于发送的seqid,它有两个选择。它可以将seqid设置为零,以向服务器表明它希望使用该stateid的“其他”字段的最新seqid。在通过读或写操作发送stateid的情况下,这是常见的选择。它还可以设置一个非零值,在这种情况下,服务器会检查seqid是否正确。在这种情况下,如果seqid小于最新值,服务器需要返回NFS4ERR_OLD_STATEID;如果seqid大于最新值,服务器需要返回NFS4ERR_BAD_STATEID。这是发送带有关闭或打开降级的StateID时的常见选择。由于同一所有者的打开可以并行发送,因此客户端可能会在不知道服务器已完成打开的升级的情况下关闭文件,从而更改有问题的锁。如果CLOSE发送时带有零seqid,则在客户端收到升级发生的指示之前,OPEN升级将被取消。

When a stateid is sent by the server to the client as part of a callback operation, it is not subject to checking for a current seqid and returning NFS4ERR_OLD_STATEID. This is because the client is not in a position to know the most up-to-date seqid and thus cannot verify it. Unless specially noted, the seqid value for a stateid sent by the server to the client as part of a callback is required to be zero with NFS4ERR_BAD_STATEID returned if it is not.

当服务器将stateid作为回调操作的一部分发送到客户端时,它不需要检查当前seqid并返回NFS4ERR_OLD_stateid。这是因为客户无法知道最新的seqid,因此无法对其进行验证。除非特别说明,否则服务器作为回调的一部分发送到客户端的stateid的seqid值必须为零,如果不是,则返回NFS4ERR_BAD_stateid。

In making comparisons between seqids, both by the client in determining the order of operations and by the server in determining whether the NFS4ERR_OLD_STATEID is to be returned, the possibility of the seqid being swapped around past the NFS4_UINT32_MAX value needs to be taken into account. When two seqid values are being compared, the total count of slots for all sessions associated with the current client is used to do this. When one seqid value is less than this total slot count and another seqid value is greater than NFS4_UINT32_MAX minus the total slot count, the former is to be treated as lower than the latter, despite the fact that it is numerically greater.

在通过客户端确定操作顺序和服务器确定是否返回NFS4ERR_OLD_STATEID对seqid进行比较时,需要考虑seqid交换超过NFS4_UINT32_MAX值的可能性。比较两个seqid值时,将使用与当前客户端关联的所有会话的插槽总数来执行此操作。当一个seqid值小于该总时隙计数,而另一个seqid值大于NFS4_UINT32_MAX减去总时隙计数时,前者将被视为低于后者,尽管其数值较大。

8.2.3. Special Stateids
8.2.3. 特殊州

Stateid values whose "other" field is either all zeros or all ones are reserved. They may not be assigned by the server but have special meanings defined by the protocol. The particular meaning depends on whether the "other" field is all zeros or all ones and the specific value of the "seqid" field.

“其他”字段为全零或全1的Stateid值被保留。它们可能不由服务器分配,但具有协议定义的特殊含义。具体含义取决于“其他”字段是全零还是全一以及“seqid”字段的具体值。

The following combinations of "other" and "seqid" are defined in NFSv4.1:

NFSv4.1中定义了以下“其他”和“seqid”的组合:

o When "other" and "seqid" are both zero, the stateid is treated as a special anonymous stateid, which can be used in READ, WRITE, and SETATTR requests to indicate the absence of any OPEN state associated with the request. When an anonymous stateid value is used and an existing open denies the form of access requested, then access will be denied to the request. This stateid MUST NOT be used on operations to data servers (Section 13.6).

o 当“other”和“seqid”均为零时,stateid被视为特殊的匿名stateid,可在读、写和SETATTR请求中使用,以指示不存在与请求相关的任何打开状态。当使用匿名stateid值且现有open拒绝请求的访问形式时,将拒绝对请求的访问。此stateid不得用于数据服务器的操作(第13.6节)。

o When "other" and "seqid" are both all ones, the stateid is a special READ bypass stateid. When this value is used in WRITE or SETATTR, it is treated like the anonymous value. When used in READ, the server MAY grant access, even if access would normally be denied to READ operations. This stateid MUST NOT be used on operations to data servers.

o 当“other”和“seqid”都是1时,stateid是一个特殊的读取旁路stateid。在WRITE或SETATTR中使用此值时,它将被视为匿名值。在读取中使用时,服务器可能会授予访问权限,即使通常会拒绝对读取操作的访问。此stateid不能用于数据服务器的操作。

o When "other" is zero and "seqid" is one, the stateid represents the current stateid, which is whatever value is the last stateid returned by an operation within the COMPOUND. In the case of an OPEN, the stateid returned for the open file and not the delegation is used. The stateid passed to the operation in place of the special value has its "seqid" value set to zero, except when the current stateid is used by the operation CLOSE or OPEN_DOWNGRADE. If there is no operation in the COMPOUND that has returned a stateid value, the server MUST return the error NFS4ERR_BAD_STATEID. As illustrated in Figure 6, if the value of a current stateid is a special stateid and the stateid of an operation's arguments has "other" set to zero and "seqid" set to one, then the server MUST return the error NFS4ERR_BAD_STATEID.

o 当“other”为零且“seqid”为一时,stateid表示当前stateid,即复合内操作返回的最后一个stateid的值。在打开的情况下,将使用为打开的文件返回的stateid,而不是委托。传递给操作以代替特殊值的stateid的“seqid”值设置为零,除非操作关闭或打开降级使用当前stateid。如果化合物中没有返回stateid值的操作,服务器必须返回错误NFS4ERR\u BAD\u stateid。如图6所示,如果当前stateid的值是一个特殊的stateid,并且操作参数的stateid的“other”设置为零,“seqid”设置为一,那么服务器必须返回错误NFS4ERR_BAD_stateid。

o When "other" is zero and "seqid" is NFS4_UINT32_MAX, the stateid represents a reserved stateid value defined to be invalid. When this stateid is used, the server MUST return the error NFS4ERR_BAD_STATEID.

o 当“other”为零且“seqid”为NFS4_UINT32_MAX时,stateid表示定义为无效的保留stateid值。使用此stateid时,服务器必须返回错误NFS4ERR\u BAD\u stateid。

If a stateid value is used that has all zeros or all ones in the "other" field but does not match one of the cases above, the server MUST return the error NFS4ERR_BAD_STATEID.

如果使用的stateid值在“other”字段中为全零或全一,但与上述情况之一不匹配,则服务器必须返回错误NFS4ERR_BAD_stateid。

Special stateids, unlike other stateids, are not associated with individual client IDs or filehandles and can be used with all valid client IDs and filehandles. In the case of a special stateid designating the current stateid, the current stateid value substituted for the special stateid is associated with a particular client ID and filehandle, and so, if it is used where the current filehandle does not match that associated with the current stateid, the operation to which the stateid is passed will return NFS4ERR_BAD_STATEID.

与其他StateID不同,特殊StateID与单个客户端ID或文件句柄不关联,可以与所有有效的客户端ID和文件句柄一起使用。对于指定当前stateid的特殊stateid,替换特殊stateid的当前stateid值与特定客户端ID和文件句柄相关联,因此,如果在当前文件句柄与当前stateid不匹配的情况下使用该值,向其传递stateid的操作将返回NFS4ERR\u BAD\u stateid。

8.2.4. Stateid Lifetime and Validation
8.2.4. Stateid生存期和验证

Stateids must remain valid until either a client restart or a server restart or until the client returns all of the locks associated with the stateid by means of an operation such as CLOSE or DELEGRETURN. If the locks are lost due to revocation, as long as the client ID is valid, the stateid remains a valid designation of that revoked state until the client frees it by using FREE_STATEID. Stateids associated with byte-range locks are an exception. They remain valid even if a LOCKU frees all remaining locks, so long as the open file with which they are associated remains open, unless the client frees the stateids via the FREE_STATEID operation.

stateid必须保持有效,直到客户端重新启动或服务器重新启动,或者直到客户端通过关闭或删除返回与stateid关联的所有锁。如果锁因吊销而丢失,只要客户端ID有效,stateid将保持该已吊销状态的有效指定,直到客户端使用FREE_stateid将其释放。与字节范围锁关联的StateID是一个例外。即使LOCKU释放了所有剩余的锁,它们仍然有效,只要与它们关联的打开文件保持打开状态,除非客户端通过FREE_STATEID操作释放STATEID。

It should be noted that there are situations in which the client's locks become invalid, without the client requesting they be returned. These include lease expiration and a number of forms of lock revocation within the lease period. It is important to note that in these situations, the stateid remains valid and the client can use it to determine the disposition of the associated lost locks.

应该注意的是,在某些情况下,客户机的锁变得无效,而客户机没有请求返回这些锁。这些措施包括租赁到期和租赁期内多种形式的锁撤销。需要注意的是,在这些情况下,stateid仍然有效,客户端可以使用它来确定相关丢失锁的处置。

An "other" value must never be reused for a different purpose (i.e., different filehandle, owner, or type of locks) within the context of a single client ID. A server may retain the "other" value for the same purpose beyond the point where it may otherwise be freed, but if it does so, it must maintain "seqid" continuity with previous values.

“其他”值不得在单个客户端ID的上下文中为不同目的(即不同的文件句柄、所有者或锁类型)重复使用。服务器可能会出于相同目的保留“其他”值,但如果这样做,则必须与以前的值保持“seqid”连续性。

One mechanism that may be used to satisfy the requirement that the server recognize invalid and out-of-date stateids is for the server to divide the "other" field of the stateid into two fields.

可用于满足服务器识别无效和过期stateid的要求的一种机制是,服务器将stateid的“其他”字段分为两个字段。

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

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

o a generation number that is incremented on each allocation of a table entry for a particular use.

o 一种生成编号,在为特定用途分配表项时递增。

And then store in each table entry,

然后存储在每个表条目中,

o the client ID with which the stateid is associated.

o 与stateid关联的客户端ID。

o the current generation number for the (at most one) valid stateid sharing this index value.

o 共享此索引值的有效stateid(最多一个)的当前生成号。

o the filehandle of the file on which the locks are taken.

o 对其进行锁定的文件的filehandle。

o an indication of the type of stateid (open, byte-range lock, file delegation, directory delegation, layout).

o stateid类型的指示(打开、字节范围锁定、文件委派、目录委派、布局)。

o the last "seqid" value returned corresponding to the current "other" value.

o 返回的最后一个“seqid”值与当前的“other”值相对应。

o an indication of the current status of the locks associated with this stateid, in particular, whether these have been revoked and if so, for what reason.

o 指示与此stateid关联的锁的当前状态,特别是这些锁是否已被撤销,如果已撤销,原因是什么。

With this information, an incoming stateid can be validated and the appropriate error returned when necessary. Special and non-special stateids are handled separately. (See Section 8.2.3 for a discussion of special stateids.)

有了这些信息,可以验证传入的stateid,并在必要时返回相应的错误。特殊和非特殊stateID分别处理。(有关特殊状态ID的讨论,请参见第8.2.3节。)

Note that stateids are implicitly qualified by the current client ID, as derived from the client ID associated with the current session. Note, however, that the semantics of the session will prevent stateids associated with a previous client or server instance from being analyzed by this procedure.

请注意,stateID由当前客户机ID隐式限定,该ID派生自与当前会话关联的客户机ID。但是,请注意,会话的语义将阻止此过程分析与以前的客户机或服务器实例关联的StateID。

If server restart has resulted in an invalid client ID or a session ID that is invalid, SEQUENCE will return an error and the operation that takes a stateid as an argument will never be processed.

如果服务器重新启动导致客户端ID无效或会话ID无效,SEQUENCE将返回错误,并且将永远不会处理以stateid为参数的操作。

If there has been a server restart where there is a persistent session and all leased state has been lost, then the session in question will, although valid, be marked as dead, and any operation not satisfied by means of the reply cache will receive the error NFS4ERR_DEADSESSION, and thus not be processed as indicated below.

如果在存在持久会话且所有租用状态均已丢失的情况下重新启动服务器,则所讨论的会话虽然有效,但将被标记为死会话,并且通过应答缓存未满足的任何操作将收到错误NFS4ERR_DEADSESSION,因此不会按如下所示进行处理。

When a stateid is being tested and the "other" field is all zeros or all ones, a check that the "other" and "seqid" fields match a defined combination for a special stateid is done and the results determined as follows:

当测试stateid且“其他”字段为全零或全1时,检查“其他”和“seqid”字段是否与特定stateid的定义组合匹配,结果如下所示:

o If the "other" and "seqid" fields do not match a defined combination associated with a special stateid, the error NFS4ERR_BAD_STATEID is returned.

o 如果“other”和“seqid”字段与与与特殊stateid关联的已定义组合不匹配,则返回错误NFS4ERR_BAD_stateid。

o If the special stateid is one designating the current stateid and there is a current stateid, then the current stateid is substituted for the special stateid and the checks appropriate to non-special stateids are performed.

o 如果特殊stateid是指定当前stateid的ID,并且存在当前stateid,则当前stateid将替换为特殊stateid,并执行适用于非特殊stateid的检查。

o If the combination is valid in general but is not appropriate to the context in which the stateid is used (e.g., an all-zero stateid is used when an OPEN stateid is required in a LOCK operation), the error NFS4ERR_BAD_STATEID is also returned.

o 如果组合通常有效,但不适用于使用stateid的上下文(例如,当锁操作中需要打开stateid时使用全零stateid),则还将返回错误NFS4ERR_BAD_stateid。

o Otherwise, the check is completed and the special stateid is accepted as valid.

o 否则,检查将完成,并且特殊stateid将被接受为有效。

When a stateid is being tested, and the "other" field is neither all zeros nor all ones, the following procedure could be used to validate an incoming stateid and return an appropriate error, when necessary, assuming that the "other" field would be divided into a table index and an entry generation.

当测试stateid时,“other”字段既不是全零也不是全1,可以使用以下过程验证传入的stateid并在必要时返回适当的错误,假设“other”字段将被划分为表索引和条目生成。

o If the table index field is outside the range of the associated table, return NFS4ERR_BAD_STATEID.

o 如果表索引字段不在关联表的范围内,则返回NFS4ERR\u BAD\u STATEID。

o If the selected table entry is of a different generation than that specified in the incoming stateid, return NFS4ERR_BAD_STATEID.

o 如果所选表项的生成与传入stateid中指定的不同,则返回NFS4ERR\u BAD\u stateid。

o If the selected table entry does not match the current filehandle, return NFS4ERR_BAD_STATEID.

o 如果所选表项与当前文件句柄不匹配,则返回NFS4ERR\U BAD\U STATEID。

o If the client ID in the table entry does not match the client ID associated with the current session, return NFS4ERR_BAD_STATEID.

o 如果表项中的客户端ID与当前会话关联的客户端ID不匹配,则返回NFS4ERR\u BAD\u STATEID。

o If the stateid represents revoked state, then return NFS4ERR_EXPIRED, NFS4ERR_ADMIN_REVOKED, or NFS4ERR_DELEG_REVOKED, as appropriate.

o 如果stateid表示吊销状态,则根据需要返回NFS4ERR_EXPIRED、NFS4ERR_ADMIN_reversed或NFS4ERR_DELEG_reversed。

o If the stateid type is not valid for the context in which the stateid appears, return NFS4ERR_BAD_STATEID. Note that a stateid may be valid in general, as would be reported by the TEST_STATEID operation, but be invalid for a particular operation, as, for example, when a stateid that doesn't represent byte-range locks is passed to the non-from_open case of LOCK or to LOCKU, or when a stateid that does not represent an open is passed to CLOSE or OPEN_DOWNGRADE. In such cases, the server MUST return NFS4ERR_BAD_STATEID.

o 如果stateid类型对于stateid出现的上下文无效,则返回NFS4ERR\u BAD\u stateid。请注意,stateid通常是有效的,如TEST_stateid操作所报告的,但对于特定操作无效,例如,当一个不代表字节范围锁的stateid被传递给非from_open LOCK或LOCKU时,或者当传递不代表打开的stateid以关闭或打开降级时。在这种情况下,服务器必须返回NFS4ERR_BAD_STATEID。

o If the "seqid" field is not zero and it is greater than the current sequence value corresponding to the current "other" field, return NFS4ERR_BAD_STATEID.

o 如果“seqid”字段不为零且大于当前“other”字段对应的当前序列值,则返回NFS4ERR_BAD_STATEID。

o If the "seqid" field is not zero and it is less than the current sequence value corresponding to the current "other" field, return NFS4ERR_OLD_STATEID.

o 如果“seqid”字段不为零且小于当前“other”字段对应的当前序列值,则返回NFS4ERR_OLD_STATEID。

o Otherwise, the stateid is valid and the table entry should contain any additional information about the type of stateid and information associated with that particular type of stateid, such as the associated set of locks, e.g., open-owner and lock-owner information, as well as information on the specific locks, e.g., open modes and byte-ranges.

o 否则,stateid是有效的,并且表条目应该包含关于stateid类型的任何附加信息以及与特定类型的stateid关联的信息,例如关联的锁集,例如打开所有者和锁所有者信息,以及关于特定锁的信息,例如打开模式和字节范围。

8.2.5. Stateid Use for I/O Operations
8.2.5. Stateid用于I/O操作

Clients performing I/O operations need to select an appropriate stateid based on the locks (including opens and delegations) held by the client and the various types of state-owners sending the I/O requests. SETATTR operations that change the file size are treated like I/O operations in this regard.

执行I/O操作的客户端需要根据客户端持有的锁(包括打开和委派)以及发送I/O请求的各种类型的状态所有者选择适当的stateid。在这方面,更改文件大小的SETATTR操作被视为I/O操作。

The following rules, applied in order of decreasing priority, govern the selection of the appropriate stateid. In following these rules, the client will only consider locks of which it has actually received notification by an appropriate operation response or callback. Note that the rules are slightly different in the case of I/O to data servers when file layouts are being used (see Section 13.9.1).

以下规则按优先级降低的顺序应用,用于管理适当stateid的选择。在遵循这些规则时,客户端只考虑通过实际操作响应或回调实际接收到通知的锁。请注意,当使用文件布局时,数据服务器的I/O规则略有不同(见第13.9.1节)。

o If the client holds a delegation for the file in question, the delegation stateid SHOULD be used.

o 如果客户机持有相关文件的委托,则应使用委托stateid。

o Otherwise, if the entity corresponding to the lock-owner (e.g., a process) sending the I/O has a byte-range lock stateid for the associated open file, then the byte-range lock stateid for that lock-owner and open file SHOULD be used.

o 否则,如果与发送I/O的锁所有者(例如,进程)对应的实体具有关联打开文件的字节范围lock stateid,则应使用该锁所有者和打开文件的字节范围lock stateid。

o If there is no byte-range lock stateid, then the OPEN stateid for the open file in question SHOULD be used.

o 如果没有字节范围锁定stateid,则应使用相关打开文件的打开stateid。

o Finally, if none of the above apply, then a special stateid SHOULD be used.

o 最后,如果上述任何一项都不适用,那么应该使用一个特殊的stateid。

Ignoring these rules may result in situations in which the server does not have information necessary to properly process the request. For example, when mandatory byte-range locks are in effect, if the stateid does not indicate the proper lock-owner, via a lock stateid, a request might be avoidably rejected.

忽略这些规则可能会导致服务器没有正确处理请求所需的信息。例如,当强制字节范围锁生效时,如果stateid没有通过lock stateid指示正确的锁所有者,则请求可能会被拒绝。

The server however should not try to enforce these ordering rules and should use whatever information is available to properly process I/O requests. In particular, when a client has a delegation for a given file, it SHOULD take note of this fact in processing a request, even if it is sent with a special stateid.

但是,服务器不应尝试强制执行这些排序规则,而应使用任何可用信息来正确处理I/O请求。特别是,当客户机对给定文件具有委托时,它应该在处理请求时注意这一事实,即使请求是使用特殊的stateid发送的。

8.2.6. Stateid Use for SETATTR Operations
8.2.6. Stateid用于SETATTR操作

Because each operation is associated with a session ID and from that the clientid can be determined, operations do not need to include a stateid for the server to be able to determine whether they should cause a delegation to be recalled or are to be treated as done within the scope of the delegation.

由于每个操作都与会话ID相关联,并且可以根据会话ID确定clientid,因此操作不需要包括stateid,服务器就可以确定它们是否应导致调用委派,或者是否应将委派视为在委派范围内完成。

In the case of SETATTR operations, a stateid is present. In cases other than those that set the file size, the client may send either a special stateid or, when a delegation is held for the file in question, a delegation stateid. While the server SHOULD validate the stateid and may use the stateid to optimize the determination as to whether a delegation is held, it SHOULD note the presence of a delegation even when a special stateid is sent, and MUST accept a valid delegation stateid when sent.

在SETATTR操作的情况下,存在stateid。在设置文件大小的情况之外的情况下,客户机可以发送特殊的stateid,或者在为相关文件保留委托时,发送委托stateid。虽然服务器应验证stateid,并可使用stateid优化是否保留委派的确定,但即使发送了特殊stateid,也应注意委派的存在,并且在发送时必须接受有效的委派stateid。

8.3. Lease Renewal
8.3. 续租

Each client/server pair, as represented by a client ID, has a single lease. The purpose of the lease is to allow the client to indicate to the server, in a low-overhead way, that it is active, and thus that the server is to retain the client's locks. This arrangement allows the server to remove stale locking-related objects that are held by a client that has crashed or is otherwise unreachable, once the relevant lease expires. This in turn allows other clients to obtain conflicting locks without being delayed indefinitely by inactive or unreachable clients. It is not a mechanism for cache consistency and lease renewals may not be denied if the lease interval has not expired.

每个客户机/服务器对(由客户机ID表示)都有一个租约。租约的目的是允许客户端以低开销的方式向服务器指示它处于活动状态,从而服务器将保留客户端的锁。这种安排允许服务器在相关租约到期后删除已崩溃或无法访问的客户端持有的过时锁定相关对象。这反过来又允许其他客户端获得冲突锁,而不会被非活动或无法访问的客户端无限期延迟。它不是缓存一致性的机制,如果租约间隔未过期,则租约续订可能不会被拒绝。

Since each session is associated with a specific client (identified by the client's client ID), any operation sent on that session is an indication that the associated client is reachable. When a request is sent for a given session, successful execution of a SEQUENCE operation (or successful retrieval of the result of SEQUENCE from the reply cache) on an unexpired lease will result in the lease being implicitly renewed, for the standard renewal period (equal to the lease_time attribute).

由于每个会话都与特定的客户端(由客户端的客户端ID标识)关联,因此在该会话上发送的任何操作都表示关联的客户端是可访问的。当为给定会话发送请求时,在未过期租约上成功执行序列操作(或从应答缓存中成功检索序列结果)将导致在标准续订期(等于租约时间属性)内隐式续订租约。

If the client ID's lease has not expired when the server receives a SEQUENCE operation, then the server MUST renew the lease. If the client ID's lease has expired when the server receives a SEQUENCE operation, the server MAY renew the lease; this depends on whether any state was revoked as a result of the client's failure to renew the lease before expiration.

如果服务器收到序列操作时客户端ID的租约尚未到期,则服务器必须续订租约。当服务器接收到序列操作时,如果客户端ID的租约已到期,则服务器可以续订租约;这取决于是否有任何状态因客户未能在租约到期前续订而被撤销。

Absent other activity that would renew the lease, a COMPOUND consisting of a single SEQUENCE operation will suffice. The client should also take communication-related delays into account and take steps to ensure that the renewal messages actually reach the server in good time. For example:

如果没有其他可以续租的活动,一个由单一序列操作组成的化合物就足够了。客户端还应考虑与通信相关的延迟,并采取措施确保续订消息实际及时到达服务器。例如:

o When trunking is in effect, the client should consider sending multiple requests on different connections, in order to ensure that renewal occurs, even in the event of blockage in the path used for one of those connections.

o 当集群生效时,客户端应该考虑在不同的连接上发送多个请求,以确保更新发生,即使在这些连接中使用的路径中阻塞的情况下。

o Transport retransmission delays might become so large as to approach or exceed the length of the lease period. This may be particularly likely when the server is unresponsive due to a restart; see Section 8.4.2.1. If the client implementation is not careful, transport retransmission delays can result in the client failing to detect a server restart before the grace period ends. The scenario is that the client is using a transport with exponential backoff, such that the maximum retransmission timeout exceeds both the grace period and the lease_time attribute. A network partition causes the client's connection's retransmission interval to back off, and even after the partition heals, the next transport-level retransmission is sent after the server has restarted and its grace period ends.

o 传输重新传输延迟可能变得如此之大,以至于接近或超过租赁期的长度。当服务器因重新启动而无响应时,这种情况尤其可能发生;见第8.4.2.1节。如果客户端实现不小心,传输重新传输延迟可能导致客户端无法在宽限期结束前检测到服务器重新启动。该场景是,客户端正在使用具有指数退避的传输,因此最大重新传输超时超过宽限期和lease_time属性。网络分区会导致客户端连接的重新传输间隔缩短,即使在分区恢复后,下一次传输级别的重新传输也会在服务器重新启动且宽限期结束后发送。

The client MUST either recover from the ensuing NFS4ERR_NO_GRACE errors or it MUST ensure that, despite transport-level retransmission intervals that exceed the lease_time, a SEQUENCE operation is sent that renews the lease before expiration. The client can achieve this by associating a new connection with the session, and sending a SEQUENCE operation on it. However, if the attempt to establish a new connection is delayed for some reason (e.g., exponential backoff of the connection establishment packets), the client will have to abort the connection establishment attempt before the lease expires, and attempt to reconnect.

客户端必须从随后出现的NFS4ERR_NO_GRACE错误中恢复,或者必须确保,尽管传输级别的重新传输间隔超过了租约时间,但仍会发送一个序列操作,在租约到期之前续订租约。客户机可以通过将新连接与会话关联,并在会话上发送序列操作来实现这一点。但是,如果由于某种原因(例如,连接建立数据包的指数退避)延迟了建立新连接的尝试,则客户端必须在租约到期之前中止建立连接的尝试,并尝试重新连接。

If the server renews the lease upon receiving a SEQUENCE operation, the server MUST NOT allow the lease to expire while the rest of the operations in the COMPOUND procedure's request are still executing.

如果服务器在收到序列操作后续订租约,则在复合过程请求中的其余操作仍在执行时,服务器不得允许租约过期。

Once the last operation has finished, and the response to COMPOUND has been sent, the server MUST set the lease to expire no sooner than the sum of current time and the value of the lease_time attribute.

完成最后一个操作并发送对component的响应后,服务器必须将租约设置为在当前时间和lease_time属性的值之和之前到期。

A client ID's lease can expire when it has been at least the lease interval (lease_time) since the last lease-renewing SEQUENCE operation was sent on any of the client ID's sessions and there are no active COMPOUND operations on any such sessions.

如果客户端ID的租约在任何客户端ID的会话上发送上次租约续订序列操作后至少达到租约间隔(租约时间),并且在任何此类会话上没有活动的复合操作,则客户端ID的租约可能会过期。

Because the SEQUENCE operation is the basic mechanism to renew a lease, and because it must be done at least once for each lease period, it is the natural mechanism whereby the server will inform the client of changes in the lease status that the client needs to be informed of. The client should inspect the status flags (sr_status_flags) returned by sequence and take the appropriate action (see Section 18.46.3 for details).

由于顺序操作是续订租约的基本机制,而且每个租约期必须至少执行一次,因此它是服务器通知客户端需要通知的租约状态更改的自然机制。客户应检查按顺序返回的状态标志(sr_status_flags),并采取适当的措施(详见第18.46.3节)。

o The status bits SEQ4_STATUS_CB_PATH_DOWN and SEQ4_STATUS_CB_PATH_DOWN_SESSION indicate problems with the backchannel that the client may need to address in order to receive callback requests.

o 状态位SEQ4_status_CB_PATH_DOWN和SEQ4_status_CB_PATH_DOWN_SESSION表示客户端可能需要解决的后通道问题,以便接收回调请求。

o The status bits SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING and SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED indicate problems with GSS contexts or RPCSEC_GSS handles for the backchannel that the client might have to address in order to allow callback requests to be sent.

o 状态位SEQ4_status_CB_GSS_CONTEXTS_EXPIRING和SEQ4_status_CB_GSS_CONTEXTS_EXPIRED表示客户端为了允许发送回调请求而可能必须处理的反向通道的GSS CONTEXTS或RPCSEC_GSS句柄存在问题。

o The status bits SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, SEQ4_STATUS_ADMIN_STATE_REVOKED, and SEQ4_STATUS_RECALLABLE_STATE_REVOKED notify the client of lock revocation events. When these bits are set, the client should use TEST_STATEID to find what stateids have been revoked and use FREE_STATEID to acknowledge loss of the associated state.

o 状态位SEQ4_status_EXPIRED_ALL_STATE_reversed、SEQ4_EXPIRED_SOME_STATE_reversed、SEQ4_status_ADMIN_STATE_reversed和SEQ4_status_RECALLABLE_STATE_reversed通知客户端锁撤销事件。设置这些位后,客户端应使用TEST_STATEID查找已撤销的STATEID,并使用FREE_STATEID确认关联状态的丢失。

o The status bit SEQ4_STATUS_LEASE_MOVE indicates that responsibility for lease renewal has been transferred to one or more new servers.

o 状态位SEQ4_status_LEASE_MOVE表示租约续订的责任已转移到一个或多个新服务器。

o The status bit SEQ4_STATUS_RESTART_RECLAIM_NEEDED indicates that due to server restart the client must reclaim locking state.

o 状态位SEQ4_status_RESTART_reclain_NEEDED表示由于服务器重新启动,客户端必须恢复锁定状态。

o The status bit SEQ4_STATUS_BACKCHANNEL_FAULT indicates that the server has encountered an unrecoverable fault with the backchannel (e.g., it has lost track of a sequence ID for a slot in the backchannel).

o 状态位SEQ4_status_BACKCHANNEL_FAULT表示服务器遇到了无法恢复的反向通道故障(例如,它丢失了反向通道中插槽的序列ID)。

8.4. Crash Recovery
8.4. 事故恢复

A critical 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. 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. Any that reach the server before the server can safely determine that the client has recovered enough locking state to be sure that such operations can be safely processed must be rejected. This will happen because either:

崩溃恢复中的一个关键要求是,客户端和服务器都知道另一方何时出现故障。此外,要求客户端在服务器重新启动时看到一致的数据视图。在客户端或网络缓冲区内排队的所有读写操作必须等待,直到客户端成功恢复保护读写操作的锁。必须拒绝在服务器能够安全地确定客户端已恢复足够的锁定状态以确保可以安全地处理此类操作之前到达服务器的任何操作。这将发生,因为:

o The state presented is no longer valid since it is associated with a now invalid client ID. In this case, the client will receive either an NFS4ERR_BADSESSION or NFS4ERR_DEADSESSION error, and any attempt to attach a new session to that invalid client ID will result in an NFS4ERR_STALE_CLIENTID error.

o 显示的状态不再有效,因为它与现在无效的客户端ID关联。在这种情况下,客户端将收到NFS4ERR_BADSESSION或NFS4ERR_DEADSESSION错误,任何尝试将新会话附加到该无效客户端ID的行为都将导致NFS4ERR_STALE_CLIENTID错误。

o Subsequent recovery of locks may make execution of the operation inappropriate (NFS4ERR_GRACE).

o 锁的后续恢复可能会导致操作执行不当(NFS4ERR_)。

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

In the event that a client fails, the server may release the client's locks when the associated lease has expired. Conflicting locks from another client may only be granted after this lease expiration. As discussed in Section 8.3, when a client has not failed and re-establishes its lease before expiration occurs, requests for conflicting locks will not be granted.

如果客户端出现故障,服务器可能会在相关租约到期时释放客户端的锁。来自其他客户端的冲突锁只能在此租约到期后授予。如第8.3节所述,当客户机未发生故障并在到期前重新建立其租约时,将不允许对冲突锁的请求。

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 client_owner4 sent in the initial EXCHANGE_ID call made by the client. The server returns a client ID as a result of the EXCHANGE_ID operation. The client then confirms the use of the client ID by establishing a session associated with that client ID (see Section 18.36.3 for a description of how this is done). All locks, including opens, byte-range locks, delegations, and layouts obtained by sessions using that client ID, are associated with that client ID.

为了最小化重启时的客户端延迟,锁请求由客户端提供的验证器与客户端实例相关联。此验证器是在客户端发出的初始EXCHANGE\u ID调用中发送的客户端\u所有者4的一部分。作为EXCHANGE\u ID操作的结果,服务器返回一个客户端ID。然后,客户机通过建立与该客户机ID相关联的会话来确认客户机ID的使用(有关如何进行此操作的说明,请参见第18.36.3节)。使用该客户端ID的会话获得的所有锁(包括打开、字节范围锁、委派和布局)都与该客户端ID关联。

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 (upon confirmation of the new client ID) of locking state. As a result, the server is free to release all locks held that are

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

associated with the old client ID that was derived from the old verifier. At this point, conflicting locks from other clients, kept waiting while the lease had not yet expired, can be granted. In addition, all stateids associated with the old client ID can also be freed, as they are no longer reference-able.

与从旧验证器派生的旧客户端ID关联。此时,可以授予来自其他客户端的冲突锁,这些锁在租约尚未到期时一直等待。此外,还可以释放与旧客户端ID关联的所有StateID,因为它们不再可引用。

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

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

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

If the server loses locking state (usually as a result of a restart), 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 a possibility that clients have not yet re-established their locking state for a file and that such locking state might make it invalid to perform READ or WRITE operations. For example, if mandatory locks are a possibility, the server must disallow READ and WRITE operations for that file.

如果服务器失去锁定状态(通常是由于重新启动),它必须让客户端有时间发现这一事实并重新建立失去的锁定状态。客户端必须能够重新建立锁定状态,而无需服务器拒绝有效请求,因为服务器已授予另一客户端冲突的访问权限。同样,如果客户端可能尚未重新建立其文件的锁定状态,并且这种锁定状态可能使执行读或写操作无效。例如,如果可以使用强制锁,服务器必须禁止该文件的读写操作。

A client can determine that loss of locking state has occurred via several methods.

客户端可以通过多种方法确定锁定状态的丢失。

1. When a SEQUENCE (most common) or other operation returns NFS4ERR_BADSESSION, this may mean that the session has been destroyed but the client ID is still valid. The client sends a CREATE_SESSION request with the client ID to re-establish the session. If CREATE_SESSION fails with NFS4ERR_STALE_CLIENTID, the client must establish a new client ID (see Section 8.1) and re-establish its lock state with the new client ID, after the CREATE_SESSION operation succeeds (see Section 8.4.2.1).

1. 当序列(最常见)或其他操作返回NFS4ERR_BADSESSION时,这可能意味着会话已被破坏,但客户端ID仍然有效。客户端发送带有客户端ID的CREATE_会话请求以重新建立会话。如果CREATE_会话使用NFS4ERR_STALE_CLIENTID失败,则在CREATE_会话操作成功(参见第8.4.2.1节)后,客户端必须建立新的客户端ID(参见第8.1节),并使用新的客户端ID重新建立其锁定状态。

2. When a SEQUENCE (most common) or other operation on a persistent session returns NFS4ERR_DEADSESSION, this indicates that a session is no longer usable for new, i.e., not satisfied from the reply cache, operations. Once all pending operations are determined to be either performed before the retry or not performed, the client sends a CREATE_SESSION request with the client ID to re-establish the session. If CREATE_SESSION fails with NFS4ERR_STALE_CLIENTID, the client must establish a new client ID (see Section 8.1) and re-establish its lock state after the CREATE_SESSION, with the new client ID, succeeds (Section 8.4.2.1).

2. 当持久会话上的序列(最常见)或其他操作返回NFS4ERR_DEADSESSION时,这表示会话不再可用于新的操作,即应答缓存不满足操作。一旦确定所有挂起的操作在重试之前执行或未执行,客户端将发送一个带有客户端ID的CREATE_会话请求,以重新建立会话。如果使用NFS4ERR_STALE_CLIENTID创建_会话失败,则客户端必须建立一个新的客户端ID(参见第8.1节),并在创建_会话成功后使用新的客户端ID重新建立其锁定状态(参见第8.4.2.1节)。

3. When an operation, neither SEQUENCE nor preceded by SEQUENCE (for example, CREATE_SESSION, DESTROY_SESSION), returns NFS4ERR_STALE_CLIENTID, the client MUST establish a new client ID (Section 8.1) and re-establish its lock state (Section 8.4.2.1).

3. 当一个操作(既不是序列也不是序列前的操作(例如,创建会话、销毁会话)返回NFS4ERR\U STALE\U CLIENTID时,客户端必须建立一个新的客户端ID(第8.1节)并重新建立其锁定状态(第8.4.2.1节)。

8.4.2.1. State Reclaim
8.4.2.1. 国家收回

When state information and the associated locks are lost as a result of a server restart, the protocol must provide a way to cause that state to be re-established. The approach used is to define, for most types of locking state (layouts are an exception), a request whose function is to allow the client to re-establish on the server a lock first obtained from a previous instance. Generally, these requests are variants of the requests normally used to create locks of that type and are referred to as "reclaim-type" requests, and the process of re-establishing such locks is referred to as "reclaiming" them.

当服务器重新启动导致状态信息和相关锁丢失时,协议必须提供一种方法使该状态重新建立。使用的方法是,对于大多数类型的锁定状态(布局是一个例外),定义一个请求,其功能是允许客户端在服务器上重新建立一个首先从以前的实例获得的锁。通常,这些请求是通常用于创建该类型锁的请求的变体,称为“回收类型”请求,重新建立此类锁的过程称为“回收”它们。

Because each client must have an opportunity to reclaim all of the locks that it has without the possibility that some other client will be granted a conflicting lock, a "grace period" is devoted to the reclaim process. During this period, requests creating client IDs and sessions are handled normally, but locking requests are subject to special restrictions. Only reclaim-type locking requests are allowed, unless the server can reliably determine (through state persistently maintained across restart instances) that granting any such lock cannot possibly conflict with a subsequent reclaim. When a request is made to obtain a new lock (i.e., not a reclaim-type request) during the grace period and such a determination cannot be made, the server must return the error NFS4ERR_GRACE.

由于每个客户机必须有机会回收其拥有的所有锁,而不可能向其他客户机授予冲突锁,因此回收过程将有一个“宽限期”。在此期间,创建客户端ID和会话的请求将正常处理,但锁定请求受到特殊限制。仅允许回收类型锁定请求,除非服务器能够可靠地确定(通过在重启实例之间持续维护的状态)授予任何此类锁定不可能与后续回收冲突。当在宽限期内发出请求以获取新锁(即,不是回收类型请求)且无法进行此类确定时,服务器必须返回错误NFS4ERR_grace。

Once a session is established using the new client ID, the client will use reclaim-type locking requests (e.g., LOCK operations with reclaim set to TRUE and OPEN operations with a claim type of CLAIM_PREVIOUS; see Section 9.11) to re-establish its locking state. Once this is done, or if there is no such locking state to reclaim, the client sends a global RECLAIM_COMPLETE operation, i.e., one with the rca_one_fs argument set to FALSE, to indicate that it has reclaimed all of the locking state that it will reclaim. Once a client sends such a RECLAIM_COMPLETE operation, it may attempt non-reclaim locking operations, although it might get an NFS4ERR_GRACE status result from each such operation until the period of special handling is over. See Section 11.7.7 for a discussion of the analogous handling lock reclamation in the case of file systems transitioning from server to server.

使用新的客户端ID建立会话后,客户端将使用回收类型锁定请求(例如,将回收设置为TRUE的锁定操作和索赔类型为claim_PREVIOUS的打开操作;请参见第9.11节)重新建立其锁定状态。完成此操作后,或者如果没有要回收的锁定状态,客户端将发送一个全局回收完成操作,即rca_one_fs参数设置为FALSE的操作,以指示它已回收了它将回收的所有锁定状态。一旦客户机发送了这样一个Recall_COMPLETE操作,它可能会尝试非Recall锁定操作,尽管它可能会从每个这样的操作中获得NFS4ERR_GRACE status结果,直到特殊处理结束。有关文件系统从一台服务器转换到另一台服务器时类似处理锁回收的讨论,请参见第11.7.7节。

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, unless it can guarantee that these may be done safely, as described below.

在宽限期内,服务器必须拒绝读写操作和非回收锁定请求(即其他锁定和打开操作),错误为NFS4ERR_grace,除非它能够保证这些操作可以安全完成,如下所述。

The grace period may last until all clients that are known to possibly have had locks have done a global RECLAIM_COMPLETE operation, indicating that they have finished reclaiming the locks they held before the server restart. This means that a client that has done a RECLAIM_COMPLETE must be prepared to receive an NFS4ERR_GRACE when attempting to acquire new locks. In order for the server to know that all clients with possible prior lock state have done a RECLAIM_COMPLETE, the server must maintain in stable storage a list clients that may have such locks. The server may also terminate the grace period before all clients have done a global RECLAIM_COMPLETE. The server SHOULD NOT terminate the grace period before a time equal to the lease period in order to give clients an opportunity to find out about the server restart, as a result of sending requests on associated sessions with a frequency governed by the lease time. Note that when a client does not send such requests (or they are sent by the client but not received by the server), it is possible for the grace period to expire before the client finds out that the server restart has occurred.

宽限期可能会持续到所有已知可能拥有锁的客户端都完成了全局回收完成操作,这表明它们在服务器重新启动之前已完成回收所持有的锁。这意味着在尝试获取新锁时,已完成回收_完成的客户端必须准备好接收NFS4ERR_宽限。为了让服务器知道所有具有可能的先前锁定状态的客户端都已完成回收,服务器必须在稳定存储中维护一个可能具有此类锁定的客户端列表。服务器还可以在所有客户端完成全局回收之前终止宽限期。服务器不应在与租赁期相等的时间之前终止宽限期,以便让客户端有机会了解服务器重新启动的情况,这是由于在关联会话上发送请求的频率由租赁期决定。请注意,当客户端不发送此类请求(或客户端发送但服务器未接收到这些请求)时,宽限期可能会在客户端发现服务器已重新启动之前过期。

Some additional time in order to allow a client to establish a new client ID and session and to effect lock reclaims may be added to the lease time. Note that analogous rules apply to file system-specific grace periods discussed in Section 11.7.7.

为了允许客户端建立新的客户端ID和会话以及实现锁回收,可以在租赁时间中添加一些额外的时间。请注意,类似规则适用于第11.7.7节中讨论的特定于文件系统的宽限期。

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 even within the grace period, although NFS4ERR_GRACE must always be returned to clients attempting a non-reclaim lock request before doing their own global RECLAIM_COMPLETE. 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 a potential 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_宽限期错误,尽管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 locking, READ or WRITE operation can be safely processed.

对于要在宽限期内提供简单有效的处理的服务器,最简单的方法是通过返回NFS4ERR_宽限期错误,简单地拒绝所有非回收锁定请求和读写操作。但是,服务器可能会在稳定的存储中保留有关已授予锁的信息。通过这些信息,服务器可以确定是否可以安全地处理锁定、读取或写入操作。

For example, if the server maintained on stable storage summary information on whether mandatory locks exist, either mandatory byte-range locks, or share reservations specifying deny modes, many requests could be allowed during the grace period. If it is known that no such share reservations exist, OPEN request that do not specify deny modes may be safely granted. If, in addition, it is known that no mandatory byte-range locks exist, either through information stored on stable storage or simply because the server does not support such locks, READ and WRITE operations may be safely processed during the grace period. Another important case is where it is known that no mandatory byte-range locks exist, either because the server does not provide support for them or because their absence is known from persistently recorded data. In this case, READ and WRITE operations specifying stateids derived from reclaim-type operations may be validly processed during the grace period because of the fact that the valid reclaim ensures that no lock subsequently granted can prevent the I/O.

例如,如果服务器在稳定存储上维护关于是否存在强制锁、强制字节范围锁或指定拒绝模式的共享保留的摘要信息,则在宽限期内可能允许许多请求。如果已知不存在此类共享保留,则可以安全地授予未指定拒绝模式的开放请求。此外,如果通过存储在稳定存储器上的信息或仅仅因为服务器不支持此类锁而知道不存在强制字节范围锁,则可以在宽限期内安全地处理读写操作。另一个重要的情况是,已知不存在强制字节范围锁,这可能是因为服务器不提供对它们的支持,也可能是因为从持久记录的数据中知道它们不存在。在这种情况下,可以在宽限期内有效地处理指定从回收类型操作派生的StateID的读写操作,因为有效的回收可确保随后授予的锁不会阻止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 [47]. The client must account for the server that can perform I/O and non-reclaim locking requests within the grace period as well as those that cannot do so.

客户端应准备好返回非回收锁和I/O请求的NFS4ERR_GRACE错误。在这种情况下,客户端应该对请求采用重试机制。重试之间应使用延迟(大约几秒钟),以避免服务器无法正常工作。[47]中包含了对一般问题的进一步讨论。客户机必须说明能够在宽限期内执行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 restart.

只有在服务器能够保证自重新启动后未授予任何冲突的锁或I/O请求的情况下,服务器宽限期之外的回收类型锁定请求才能成功。

A server may, upon restart, establish a new value for the lease period. Therefore, clients should, once a new client ID 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.

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

The possibility exists that, because of server configuration events, the client will be communicating with a server different than the one on which the locks were obtained, as shown by the combination of eir_server_scope and eir_server_owner. This leads to the issue of if and when the client should attempt to reclaim locks previously obtained on what is being reported as a different server. The rules to resolve this question are as follows:

存在的可能性是,由于服务器配置事件,客户端将与不同于获取锁的服务器通信,如eir_服务器范围和eir_服务器所有者的组合所示。这会导致客户机是否以及何时尝试回收以前在报告为不同服务器的服务器上获得的锁的问题。解决这一问题的规则如下:

o If the server scope is different, the client should not attempt to reclaim locks. In this situation, no lock reclaim is possible. Any attempt to re-obtain the locks with non-reclaim operations is problematic since there is no guarantee that the existing filehandles will be recognized by the new server, or that if recognized, they denote the same objects. It is best to treat the locks as having been revoked by the reconfiguration event.

o 如果服务器作用域不同,则客户端不应尝试回收锁。在这种情况下,不可能进行锁回收。使用非回收操作重新获取锁的任何尝试都是有问题的,因为不能保证新服务器会识别现有的文件句柄,或者如果识别,它们表示相同的对象。最好将锁视为已被重新配置事件撤销。

o If the server scope is the same, the client should attempt to reclaim locks, even if the eir_server_owner value is different. In this situation, it is the responsibility of the server to return NFS4ERR_NO_GRACE if it cannot provide correct support for lock reclaim operations, including the prevention of edge conditions.

o 如果服务器作用域相同,则客户端应尝试回收锁,即使eir_服务器_所有者值不同。在这种情况下,如果服务器不能为锁回收操作(包括防止边缘状况)提供正确的支持,则服务器有责任返回NFS4ERR_NO_GRACE。

The eir_server_owner field is not used in making this determination. Its function is to specify trunking possibilities for the client (see Section 2.10.5) and not to control lock reclaim.

eir_服务器_所有者字段不用于进行此确定。其功能是为客户端指定中继可能性(参见第2.10.5节),而不是控制锁回收。

8.4.2.1.1. Security Considerations for State Reclaim
8.4.2.1.1. 状态回收的安全注意事项

During the grace period, a client can reclaim state that it believes or asserts it had before the server restarted. Unless the server maintained a complete record of all the state the client had, the server has little choice but to trust the client. (Of course, if the server maintained a complete record, then it would not have to force the client to reclaim state after server restart.) While the server has to trust the client to tell the truth, such trust does not have any negative consequences for security. The fundamental rule for the server when processing reclaim requests is that it MUST NOT grant the reclaim if an equivalent non-reclaim request would not be granted during steady state due to access control or access conflict issues. For example, an OPEN request during a reclaim will be refused with NFS4ERR_ACCESS if the principal making the request does not have access to open the file according to the discretionary ACL (Section 6.2.2) on the file.

在宽限期内,客户机可以恢复其认为或断言在服务器重新启动之前的状态。除非服务器维护客户机所有状态的完整记录,否则服务器别无选择,只能信任客户机。(当然,如果服务器维护了完整的记录,则不必在服务器重新启动后强制客户端恢复状态。)虽然服务器必须信任客户端说出真相,但这种信任不会对安全性产生任何负面影响。处理回收请求时,服务器的基本规则是,如果由于访问控制或访问冲突问题,在稳定状态下无法授予等效的非回收请求,则服务器不得授予回收。例如,如果提出请求的委托人无权根据文件上的自由裁量ACL(第6.2.2节)打开文件,则回收期间的打开请求将被NFS4ERR_访问拒绝。

Nonetheless, it is possible that a client operating in error or maliciously could, during reclaim, prevent another client from reclaiming access to state. For example, an attacker could send an

尽管如此,在回收过程中,错误或恶意操作的客户端可能会阻止另一个客户端回收对状态的访问。例如,攻击者可以发送

OPEN reclaim operation with a deny mode that prevents another client from reclaiming the OPEN state it had before the server restarted. The attacker could perform the same denial of service during steady state prior to server restart, as long as the attacker had permissions. Given that the attack vectors are equivalent, the grace period does not offer any additional opportunity for denial of service, and any concerns about this attack vector, whether during grace or steady state, are addressed the same way: use RPCSEC_GSS for authentication and limit access to the file only to principals that the owner of the file trusts.

使用拒绝模式打开回收操作,该模式可防止其他客户端回收服务器重新启动前的打开状态。只要攻击者有权限,攻击者可以在服务器重启前的稳定状态下执行相同的拒绝服务。由于攻击向量是等价的,宽限期不提供任何额外的拒绝服务机会,以及任何关于该攻击向量的关注,无论是在优雅或稳定状态下,它们的地址相同:使用RPCSEC_GSS进行身份验证,并将对文件的访问权限限制为文件所有者信任的主体。

Note that if prior to restart the server had client IDs with the EXCHGID4_FLAG_BIND_PRINC_STATEID (Section 18.35) capability set, then the server SHOULD record in stable storage the client owner and the principal that established the client ID via EXCHANGE_ID. If the server does not, then there is a risk a client will be unable to reclaim state if it does not have a credential for a principal that was originally authorized to establish the state.

请注意,如果在重新启动服务器之前,服务器的客户端ID具有EXCHGID4_标志_绑定_PRINC_STATEID(第18.35节)功能集,则服务器应在稳定存储中记录客户端所有者和通过EXCHANGE_ID建立客户端ID的主体。如果服务器没有,如果客户端没有最初授权建立状态的主体的凭据,则存在无法收回状态的风险。

8.4.3. Network Partitions and Recovery
8.4.3. 网络分区和恢复

If the duration of a network partition is greater than the lease period provided by the server, the server will not have received a lease renewal from the client. If this occurs, the server may free all locks held for the client or it may allow the lock state to remain for a considerable period, subject to the constraint that if a request for a conflicting lock is made, locks associated with an expired lease do not prevent such a conflicting lock from being granted but MUST be revoked as necessary so as to avoid interfering with such conflicting requests.

如果网络分区的持续时间大于服务器提供的租约期限,则服务器将不会从客户端收到租约续订。如果发生这种情况,服务器可以释放为客户端保留的所有锁,或者允许锁状态保持相当长的一段时间,但受到以下约束:如果请求冲突的锁,与过期租约相关联的锁不会阻止授予此类冲突锁,但必须在必要时撤销,以避免干扰此类冲突请求。

If the server chooses to delay freeing of lock state until there is a conflict, it may either free all of the client's locks once there is a conflict or it may only revoke the minimum set of locks necessary to allow conflicting requests. When it adopts the finer-grained approach, it must revoke all locks associated with a given stateid, even if the conflict is with only a subset of locks.

如果服务器选择延迟释放锁状态直到发生冲突,则它可以在发生冲突时释放客户端的所有锁,也可以仅撤销允许冲突请求所需的最小锁集。当它采用更细粒度的方法时,它必须撤销与给定stateid关联的所有锁,即使冲突仅与锁的子集发生。

When the server chooses to free all of a client's lock state, either immediately upon lease expiration or as a result of the first attempt to obtain a conflicting a lock, the server may report the loss of lock state in a number of ways.

当服务器选择释放客户端的所有锁状态时,无论是在租约到期后立即释放,还是由于第一次尝试获取冲突的a锁,服务器都可以通过多种方式报告锁状态的丢失。

The server may choose to invalidate the session and the associated client ID. In this case, once the client can communicate with the server, it will receive an NFS4ERR_BADSESSION error. Upon attempting to create a new session, it would get an NFS4ERR_STALE_CLIENTID. Upon creating the new client ID and new session, the client will

服务器可以选择使会话和相关客户端ID无效。在这种情况下,一旦客户端可以与服务器通信,它将收到NFS4ERR_BADSESSION错误。在尝试创建新会话时,它将获得一个NFS4ERR\u STALE\u CLIENTID。创建新的客户端ID和新会话后,客户端将

attempt to reclaim locks. Normally, the server will not allow the client to reclaim locks, because the server will not be in its recovery grace period.

尝试回收锁。通常,服务器不允许客户端回收锁,因为服务器不在其恢复宽限期内。

Another possibility is for the server to maintain the session and client ID but for all stateids held by the client to become invalid or stale. Once the client can reach the server after such a network partition, the status returned by the SEQUENCE operation will indicate a loss of locking state; i.e., the flag SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED will be set in sr_status_flags. In addition, all I/O submitted by the client with the now invalid stateids will fail with the server returning the error NFS4ERR_EXPIRED. Once the client learns of the loss of locking state, it will suitably notify the applications that held the invalidated locks. The client should then take action to free invalidated stateids, either by establishing a new client ID using a new verifier or by doing a FREE_STATEID operation to release each of the invalidated stateids.

另一种可能是服务器维护会话和客户机ID,但客户机持有的所有StateID无效或过时。一旦客户机可以在这样的网络分区后到达服务器,序列操作返回的状态将指示锁定状态的丢失;i、 例如,将在sr_STATUS_flags中设置标志SEQ4_STATUS_EXPIRED_ALL_STATE_Reversed。此外,客户端提交的所有I/O以及现在无效的StateID都将失败,服务器将返回错误NFS4ERR_EXPIRED。一旦客户机了解到锁状态的丢失,它将适当地通知持有无效锁的应用程序。然后,客户机应采取措施释放失效的STATEID,方法是使用新的验证器建立新的客户机ID,或通过执行free_STATEID操作释放每个失效的STATEID。

When the server adopts a finer-grained approach to revocation of locks when a client's lease has expired, only a subset of stateids will normally become invalid during a network partition. When the client can communicate with the server after such a network partition heals, the status returned by the SEQUENCE operation will indicate a partial loss of locking state (SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED). In addition, operations, including I/O submitted by the client, with the now invalid stateids will fail with the server returning the error NFS4ERR_EXPIRED. Once the client learns of the loss of locking state, it will use the TEST_STATEID operation on all of its stateids to determine which locks have been lost and then suitably notify the applications that held the invalidated locks. The client can then release the invalidated locking state and acknowledge the revocation of the associated locks by doing a FREE_STATEID operation on each of the invalidated stateids.

当服务器采用更细粒度的方法在客户端租约到期时撤销锁时,在网络分区期间,通常只有stateID的子集无效。当客户端可以在这样的网络分区修复后与服务器通信时,序列操作返回的状态将指示锁定状态的部分丢失(SEQ4_status_EXPIRED_SOME_state_reversed)。此外,操作(包括客户端提交的I/O)以及现在无效的StateID将失败,服务器返回错误NFS4ERR_EXPIRED。一旦客户端了解到锁状态的丢失,它将对其所有STATEID使用TEST_STATEID操作来确定哪些锁已丢失,然后适当地通知持有无效锁的应用程序。然后,客户端可以释放无效锁定状态,并通过对每个无效STATEID执行FREE_STATEID操作来确认相关锁的撤销。

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

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

The first edge condition arises as a result of the scenarios such as the following:

第一个边缘条件是以下情况的结果:

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, and the server releases the 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 its lock.

5. 客户端B释放其锁。

6. Server restarts.

6. 服务器重新启动。

7. Network partition between client A and server heals.

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

8. Client A connects to a new server instance and finds out about server restart.

8. 客户端A连接到一个新的服务器实例,并了解有关服务器重启的信息。

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 arises in situations such as the following:

第二个已知边缘条件出现在以下情况下:

1. Client A acquires one or more locks.

1. 客户端A获取一个或多个锁。

2. Server restarts.

2. 服务器重新启动。

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

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

4. Server's reclaim grace period ends. Client A has either no locks or an incomplete set of locks known to the server.

4. 服务器的回收宽限期结束。客户端A没有锁或服务器已知的锁集不完整。

5. Client B acquires a lock that would have conflicted with a lock of client A that was not reclaimed.

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

6. Client B releases the lock.

6. 客户端B释放锁。

7. Server restarts a second time.

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

8. Network partition between client A and server heals.

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

9. Client A connects to new server instance and finds out about server restart.

9. 客户端A连接到新的服务器实例,并了解有关服务器重新启动的信息。

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 either that the server always assumes after it restarts that some edge condition occurs, and thus returns NFS4ERR_NO_GRACE for all reclaim attempts, or that the server record some information in stable storage. The amount of information the server records in stable storage is in inverse proportion to how harsh the server intends to be whenever edge conditions arise. 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 released. For the two edge conditions discussed above, the harshest a server can be, and still support a grace period for reclaims, requires that the server record in stable storage some minimal information. For example, a server implementation could, for each client, save in stable storage a record containing:

解决第一个和第二个边缘条件要求服务器在重新启动后始终假定出现某些边缘条件,并因此为所有回收尝试返回NFS4ERR_NO_GRACE,或者服务器在稳定存储中记录一些信息。服务器在稳定存储中记录的信息量与每当出现边缘条件时服务器打算达到的苛刻程度成反比。完全容忍所有边缘条件的服务器将在稳定存储中记录获取的每个锁,只有在释放锁时才从稳定存储中删除锁记录。对于上面讨论的两种边缘条件,服务器可能是最苛刻的,并且仍然支持回收的宽限期,要求服务器在稳定存储中记录一些最小的信息。例如,服务器实现可以为每个客户机在稳定存储中保存一条记录,其中包含:

o the co_ownerid field from the client_owner4 presented in the EXCHANGE_ID operation.

o EXCHANGE ID操作中显示的客户机所有者4中的co_ownerid字段。

o a boolean that indicates if the client's lease expired or if there was administrative intervention (see Section 8.5) to revoke a byte-range lock, share reservation, or delegation and there has been no acknowledgment, via FREE_STATEID, of such revocation.

o 一种布尔值,指示客户的租约是否过期,或者是否有行政干预(参见第8.5节)来撤销字节范围锁、共享保留或委派,并且没有通过FREE_STATEID确认此类撤销。

o a boolean that indicates whether the client may have locks that it believes to be reclaimable in situations in which the grace period was terminated, making the server's view of lock reclaimability suspect. The server will set this for any client record in stable storage where the client has not done a suitable RECLAIM_COMPLETE (global or file system-specific depending on the target of the lock request) before it grants any new (i.e., not reclaimed) lock to any client.

o 一个布尔值,指示客户端是否可能拥有它认为在宽限期终止的情况下可以回收的锁,从而使服务器对锁回收能力的看法受到怀疑。服务器将为稳定存储中的任何客户机记录设置此选项,如果客户机在向任何客户机授予任何新(即未回收)锁之前未完成适当的回收(全局或特定于文件系统,具体取决于锁请求的目标)。

Assuming the above record keeping, for the first edge condition, after the server restarts, the record that client A's lease expired means that another client could have acquired a conflicting byte-range 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 restarts for a second time, the indication that the client had not completed its reclaims at the time at which the grace period ended means that the server must reject a reclaim from client A with the error NFS4ERR_NO_GRACE.

对于第二个边缘条件,在服务器第二次重新启动后,表示在宽限期结束时客户端尚未完成其回收的指示意味着服务器必须拒绝来自客户端a的回收,错误为NFS4ERR_NO_grace。

When either edge condition occurs, the client's attempt to reclaim locks will result in the error NFS4ERR_NO_GRACE. When this is received, or after the client restarts with no lock state, the client will send a global RECLAIM_COMPLETE. When the RECLAIM_COMPLETE is received, the server and client are again in agreement regarding reclaimable locks and both booleans in persistent storage can be reset, to be set again only when there is a subsequent event that causes lock reclaim operations to be questionable.

当任一边缘条件发生时,客户端尝试回收锁将导致错误NFS4ERR_NO_。当收到此消息时,或在客户端重新启动且没有锁定状态后,客户端将发送一个全局回收完成。当收到Reclain_COMPLETE时,服务器和客户端再次就可回收锁达成一致,并且可以重置持久性存储中的两个布尔值,只有在发生导致锁回收操作有问题的后续事件时,才能重新设置。

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, byte-range locks, and delegations):

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

1. Reject all reclaims with NFS4ERR_NO_GRACE. This is extremely unforgiving, but necessary if the server does not 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 restart, including the two noted in this section, are detected. It is acceptable to erroneously recognize an edge condition and not allow a reclaim, when, with sufficient knowledge, it would be allowed. The error the server would return in this case is NFS4ERR_NO_GRACE. Note that it is not known if there are other edge conditions.

2. 在稳定存储器中记录足够的状态,以便检测到涉及服务器重启的所有已知边缘条件,包括本节中提到的两种情况。错误地识别边缘条件而不允许回收是可以接受的,如果有足够的知识,可以允许回收。在这种情况下,服务器将返回的错误是NFS4ERR\u NO\u GRACE。请注意,不知道是否存在其他边缘条件。

In the event that, after a server restart, the server determines there is unrecoverable damage or corruption to the information in stable storage, then for all clients and/or locks that may be 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 for which the client is trying to reclaim state, and use that to determine whether to re-establish the state via normal OPEN or LOCK operations. This is acceptable provided that the client's operating environment allows it. In other words, the client implementor is advised to document for his users the behavior. The client could also inform the application that its byte-range lock or share reservations (whether or not they were

当客户端接收到NFS4ERR_NO_GRACE时,它可以检查客户端尝试回收状态的对象的change属性,并使用该属性确定是否通过正常的打开或锁定操作重新建立状态。只要客户的操作环境允许,这是可以接受的。换句话说,建议客户机实现者为其用户记录行为。客户机还可以通知应用程序其字节范围锁定或共享保留(无论它们是否被锁定)

delegated) have been lost, such as via a UNIX signal, a Graphical User Interface (GUI) pop-up window, etc. See Section 10.5 for a discussion of what the client should do for dealing with unreclaimed delegations on client state.

委托)已丢失,例如通过UNIX信号、图形用户界面(GUI)弹出窗口等。请参阅第10.5节,以了解客户机应如何处理客户机状态下未声明的委托。

For further discussion of revocation of locks, see Section 8.5.

有关撤销锁的进一步讨论,请参见第8.5节。

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

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 occasion of lock revocation is upon server restart. Note that this includes situations in which sessions are persistent and locking state is lost. In this class of instances, the client will receive an error (NFS4ERR_STALE_CLIENTID) on an operation that takes client ID, usually as part of recovery in response to a problem with the current session), and the client will proceed with normal crash recovery as described in the Section 8.4.2.1.

第一次撤销锁是在服务器重新启动时。请注意,这包括会话是持久的并且锁定状态丢失的情况。在这类实例中,客户端将在使用客户端ID的操作上收到错误(NFS4ERR_STALE_CLIENTID),通常作为响应当前会话问题的恢复的一部分),并且客户端将按照第8.4.2.1节中的说明进行正常崩溃恢复。

The second occasion of lock revocation is the inability to renew the lease before expiration, as discussed in Section 8.4.3. While this is considered a rare or unusual event, the client must be prepared to recover. The server is responsible for determining the precise consequences of the lease expiration, informing the client of the scope of the lock revocation decided upon. The client then uses the status information provided by the server in the SEQUENCE results (field sr_status_flags, see Section 18.46.3) to synchronize its locking state with that of the server, in order to recover.

如第8.4.3节所述,撤销锁定的第二种情况是无法在到期前续约。虽然这被认为是罕见或不寻常的事件,但客户必须做好恢复的准备。服务器负责确定租约到期的确切后果,并将决定的锁撤销范围通知客户端。然后,客户端使用序列结果中服务器提供的状态信息(字段sr_status_flags,参见第18.46.3节)将其锁定状态与服务器的锁定状态同步,以便恢复。

The third occasion of lock revocation can occur as a result of revocation of locks within the lease period, either because of administrative intervention or because a recallable lock (a delegation or layout) was not returned within the lease period after having been recalled. While these are considered rare events, they are possible, and the client must be prepared to deal with them. When either of these events occurs, the client finds out about the situation through the status returned by the SEQUENCE operation. Any use of stateids associated with locks revoked during the lease period will receive the error NFS4ERR_ADMIN_REVOKED or NFS4ERR_DELEG_REVOKED, as appropriate.

第三次撤销锁可能是在租赁期内撤销锁的结果,原因可能是行政干预或可撤销锁(委托或布局)在被召回后在租赁期内未归还。虽然这些被认为是罕见的事件,但它们是可能的,客户必须做好处理这些事件的准备。当这些事件发生时,客户机通过序列操作返回的状态来了解情况。在租赁期内使用与撤销的锁相关联的StateID将收到错误NFS4ERR_ADMIN_reversed或NFS4ERR_DELEG_reversed(视情况而定)。

In all situations in which a subset of locking state may have been revoked, which include all cases in which locking state is revoked within the lease period, it is up to the client to determine which locks have been revoked and which have not. It does this by using the TEST_STATEID operation on the appropriate set of stateids. Once the set of revoked locks has been determined, the applications can be notified, and the invalidated stateids can be freed and lock revocation acknowledged by using FREE_STATEID.

在锁定状态子集可能已被撤销的所有情况下,包括锁定状态在租赁期内被撤销的所有情况,应由客户确定哪些锁已被撤销,哪些未被撤销。它通过对适当的STATEID集使用TEST_STATEID操作来实现这一点。一旦确定了一组已撤销的锁,就可以通知应用程序,并且可以释放失效的STATEID,并使用FREE_STATEID确认锁的撤销。

8.6. Short and Long Leases
8.6. 短期和长期租赁

When determining the time period for the server lease, the usual lease tradeoffs apply. A short lease is good for fast server recovery at a cost of increased operations to effect lease renewal (when there are no other operations during the period to effect lease renewal as a side effect). A long lease is certainly kinder and gentler to servers trying to handle very large numbers of clients. The number of extra requests to effect lock renewal drops in inverse proportion to the lease time. The disadvantages of a long lease include the possibility of slower recovery after certain failures. After server failure, a longer grace period may be required when some clients do not promptly reclaim their locks and do a global RECLAIM_COMPLETE. In the event of client failure, the longer period for a lease to expire will force conflicting requests to wait longer.

在确定服务器租用的时间段时,通常的租用权衡适用。短期租约有利于快速服务器恢复,但需要增加操作以实现租约续订(在此期间没有其他操作作为副作用实现租约续订)。对于试图处理大量客户机的服务器来说,长期租赁当然更友好、更温和。影响锁更新的额外请求数量与租赁时间成反比下降。长期租赁的缺点包括在某些故障后恢复较慢的可能性。服务器发生故障后,如果某些客户端没有及时回收其锁并完成全局回收,则可能需要更长的宽限期。在客户端失败的情况下,租约到期的时间越长,冲突请求的等待时间就越长。

A long lease is practical if the server can store lease state in stable storage. Upon recovery, the server can reconstruct the lease state from its stable storage and continue operation with its clients.

如果服务器可以将租约状态存储在稳定的存储中,则长租约是可行的。恢复后,服务器可以从其稳定存储中重建租约状态,并继续与其客户端一起运行。

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

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 lease. 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 milliseconds, then it can assume that the lease is already 200 milliseconds old when it gets it). In addition, it will take another 200 milliseconds to get a response back to the server. So the client must send a lease renewal or write data back to the server at least 400 milliseconds before the lease would expire. If the propagation delay varies over the life of the lease

为了将传播延迟考虑在内,客户机应该从租约时间中减去它(例如,如果客户机估计单向传播延迟为200毫秒,那么它可以假设租约在获得时已经有200毫秒了)。此外,还需要200毫秒才能将响应返回到服务器。因此,客户机必须在租约到期前至少400毫秒向服务器发送租约续订或写回数据。如果传播延迟在租赁期内发生变化

(e.g., the client is on a mobile host), the client will need to continuously subtract the increase in propagation delay from the lease times.

(例如,客户端位于移动主机上),客户端需要从租赁时间中连续减去传播延迟的增加。

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.8. Obsolete Locking Infrastructure from NFSv4.0
8.8. NFSv4.0中过时的锁定基础结构

There are a number of operations and fields within existing operations that no longer have a function in NFSv4.1. In one way or another, these changes are all due to the implementation of sessions that provide client context and exactly once semantics as a base feature of the protocol, separate from locking itself.

现有操作中有许多操作和字段不再具有NFSv4.1中的功能。在某种程度上,这些变化都是由于会话的实现,这些会话提供了客户机上下文和一次语义作为协议的基本特性,与锁定本身分离。

The following NFSv4.0 operations MUST NOT be implemented in NFSv4.1. The server MUST return NFS4ERR_NOTSUPP if these operations are found in an NFSv4.1 COMPOUND.

以下NFSv4.0操作不得在NFSv4.1中实施。如果在NFSv4.1化合物中找到这些操作,服务器必须返回NFS4ERR_NOTSUPP。

o SETCLIENTID since its function has been replaced by EXCHANGE_ID.

o SETCLIENTID,因为它的函数已被EXCHANGE\u ID替换。

o SETCLIENTID_CONFIRM since client ID confirmation now happens by means of CREATE_SESSION.

o SETCLIENTID_确认,因为客户端ID确认现在通过CREATE_会话进行。

o OPEN_CONFIRM because state-owner-based seqids have been replaced by the sequence ID in the SEQUENCE operation.

o 打开\u确认,因为在序列操作中,基于状态所有者的seqid已被序列ID替换。

o RELEASE_LOCKOWNER because lock-owners with no associated locks do not have any sequence-related state and so can be deleted by the server at will.

o 释放锁所有者,因为没有关联锁的锁所有者没有任何与序列相关的状态,因此可以由服务器随意删除。

o RENEW because every SEQUENCE operation for a session causes lease renewal, making a separate operation superfluous.

o 续订,因为会话的每个序列操作都会导致租约续订,从而使单独的操作变得多余。

Also, there are a number of fields, present in existing operations, related to locking that have no use in minor version 1. They were used in minor version 0 to perform functions now provided in a different fashion.

此外,现有操作中存在许多与锁定相关的字段,这些字段在次要版本1中没有用处。它们在次要版本0中用于执行现在以不同方式提供的功能。

o Sequence ids used to sequence requests for a given state-owner and to provide retry protection, now provided via sessions.

o 序列ID用于对给定状态所有者的请求进行排序,并提供重试保护,现在通过会话提供。

o Client IDs used to identify the client associated with a given request. Client identification is now available using the client ID associated with the current session, without needing an explicit client ID field.

o 用于标识与给定请求关联的客户端的客户端ID。现在可以使用与当前会话关联的客户机ID进行客户机标识,而不需要显式的客户机ID字段。

Such vestigial fields in existing operations have no function in NFSv4.1 and are ignored by the server. Note that client IDs in operations new to NFSv4.1 (such as CREATE_SESSION and DESTROY_CLIENTID) are not ignored.

现有操作中的此类残留字段在NFSv4.1中没有任何功能,服务器将忽略这些字段。请注意,NFSv4.1新增操作中的客户端ID(例如创建会话和销毁客户端ID)不会被忽略。

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

To support Win32 share reservations, it is necessary to provide operations that 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 NFSv4.1 protocol defines an OPEN operation that is capable of atomically looking up, creating, and locking a file on the server.

为了支持Win32共享保留,有必要提供以原子方式打开或创建文件的操作。使用单独的共享/取消共享操作将不允许Win32 OpenFile API的正确实现。为了正确实现共享语义,需要替换以前在打开或创建文件(查找、创建、访问)时使用的NFS协议机制。NFSv4.1协议定义了一个开放操作,该操作能够在服务器上自动查找、创建和锁定文件。

9.1. Opens and Byte-Range Locks
9.1. 打开和关闭字节范围锁

It is assumed that manipulating a byte-range lock is rare when compared to READ and WRITE operations. It is also assumed that server restarts 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 operation contains the heavyweight information required to establish a byte-range lock and uniquely define the owner of the lock.

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

9.1.1. State-Owner Definition
9.1.1. 国家所有人定义

When opening a file or requesting a byte-range lock, the client must specify an identifier that represents the owner of the requested lock. This identifier is in the form of a state-owner, represented in the protocol by a state_owner4, a variable-length opaque array that, when concatenated with the current client ID, uniquely defines the owner of a lock managed by the client. This may be a thread ID, process ID, or other unique value.

打开文件或请求字节范围锁时,客户端必须指定一个标识符,该标识符表示所请求锁的所有者。该标识符以状态所有者的形式存在,在协议中由状态所有者4表示,状态所有者4是一个可变长度的不透明数组,当与当前客户端ID连接时,它唯一地定义了客户端管理的锁的所有者。这可能是线程ID、进程ID或其他唯一值。

Owners of opens and owners of byte-range locks are separate entities and remain separate even if the same opaque arrays are used to designate owners of each. The protocol distinguishes between open-owners (represented by open_owner4 structures) and lock-owners (represented by lock_owner4 structures).

opens的所有者和byte range锁的所有者是独立的实体,即使使用相同的不透明数组指定每个锁的所有者,它们仍然保持独立。该协议区分开放所有者(由open_owner4结构表示)和锁所有者(由lock_owner4结构表示)。

Each open is associated with a specific open-owner while each byte-range lock is associated with a lock-owner and an open-owner, the latter being the open-owner associated with the open file under which the LOCK operation was done. Delegations and layouts, on the other hand, are not associated with a specific owner but are associated with the client as a whole (identified by a client ID).

每个打开与特定的打开所有者关联,而每个字节范围锁与一个锁所有者和一个打开所有者关联,后者是与执行锁定操作的打开文件关联的打开所有者。另一方面,委托和布局不与特定所有者关联,而是与整个客户机关联(由客户机ID标识)。

9.1.2. Use of the Stateid and Locking
9.1.2. Stateid和锁定的使用

All READ, WRITE, and SETATTR operations contain a stateid. For the purposes of this section, SETATTR operations that change the size attribute of a file are treated as if they are writing the area between the old and new sizes (i.e., the byte-range truncated or added to the file by means of the SETATTR), even where SETATTR is not explicitly mentioned in the text. The stateid passed to one of these operations must be one that represents an open, a set of byte-range locks, or a delegation, or it may be a special stateid representing anonymous access or the special bypass stateid.

所有读、写和SETATTR操作都包含stateid。在本节中,更改文件大小属性的SETATTR操作被视为写入新旧大小之间的区域(即通过SETATTR截断或添加到文件中的字节范围),即使文本中未明确提及SETATTR。传递给其中一个操作的stateid必须是表示打开的、一组字节范围锁或委派的stateid,也可以是表示匿名访问的特殊stateid或特殊旁路stateid。

If the state-owner performs a READ or WRITE operation in a situation in which it has established a byte-range 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 byte-range locks and share reservations, are held by the state-owner. If no state is established by the client, either a byte-range lock or a share reservation, a special stateid for anonymous state (zero as the value for "other" and "seqid") is used. (See Section 8.2.3 for a description of 'special' stateids in general.) Regardless of whether a stateid for anonymous state or a stateid returned by the server is used, if there is a conflicting share reservation or mandatory byte-range lock held on the file, the server MUST refuse to service the READ or WRITE operation.

如果状态所有者在服务器上建立了字节范围锁或共享保留(任何打开都构成共享保留)的情况下执行读或写操作,则必须使用stateid(以前由服务器返回)指示哪些锁,包括字节范围锁和共享保留,由国家所有人持有。如果客户端未建立任何状态(字节范围锁或共享保留),则使用匿名状态的特殊stateid(零作为“其他”和“seqid”的值)。(有关“特殊”stateid的一般说明,请参见第8.2.3节。)无论使用匿名状态的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. Byte-range 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, byte-range locks are required on the file before I/O is possible). When byte-range locks are advisory, they only prevent the granting of conflicting lock requests and have no effect on READs or WRITEs. Mandatory byte-range 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 for which it knows it has the proper share reservation, it will need to

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

send a LOCK operation on the byte-range of the file that includes the byte-range the I/O was to be performed on, with an appropriate locktype field of the LOCK operation's arguments (i.e., READ*_LT for a READ operation, WRITE*_LT for a WRITE operation).

在包含要执行I/O的字节范围的文件字节范围上发送锁操作,并使用锁操作参数的适当locktype字段(即,读操作为READ*.\LT,写操作为WRITE*.\LT)。

Note that for UNIX environments that support mandatory byte-range locking, the distinction between advisory and mandatory locking is subtle. In fact, advisory and mandatory byte-range locks are exactly the same as 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 lock-owner has an appropriate shared (READ_LT) or exclusive (WRITE_LT) byte-range lock on the byte-range it wishes to READ from 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 behalf of the lock-owner, and if successful, release the lock after the READ or WRITE operation is done), and if there is, the server returns NFS4ERR_LOCKED.

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

For Windows environments, byte-range locks are always mandatory, so the server always checks for byte-range locks during I/O requests.

对于Windows环境,字节范围锁始终是必需的,因此服务器在I/O请求期间始终检查字节范围锁。

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

因此,锁定操作不需要区分建议锁定和强制字节范围锁定。正是服务器对读写操作的处理引入了区别。

Every stateid that is validly passed to READ, WRITE, or SETATTR, with the exception of special stateid values, defines an access mode for the file (i.e., OPEN4_SHARE_ACCESS_READ, OPEN4_SHARE_ACCESS_WRITE, or OPEN4_SHARE_ACCESS_BOTH).

有效传递给读取、写入或SETATTR的每个stateid(特殊stateid值除外)都定义了文件的访问模式(即OPEN4_共享_访问_读取、OPEN4_共享_访问_写入或OPEN4_共享_访问_两者)。

o For stateids associated with opens, this is the mode defined by the original OPEN that caused the allocation of the OPEN stateid and as modified by subsequent OPENs and OPEN_DOWNGRADEs for the same open-owner/file pair.

o 对于与OPEN关联的stateid,这是由导致分配OPEN stateid的原始OPEN定义的模式,并由同一OPEN owner/文件对的后续OPEN和OPEN\U降级修改。

o For stateids returned by byte-range LOCK operations, the appropriate mode is the access mode for the OPEN stateid associated with the lock set represented by the stateid.

o 对于字节范围锁操作返回的stateid,适当的模式是与stateid表示的锁集关联的打开stateid的访问模式。

o For delegation stateids, the access mode is based on the type of delegation.

o 对于委托StateID,访问模式基于委托的类型。

When a READ, WRITE, or SETATTR (that specifies the size attribute) operation is done, the operation is subject to checking against the access mode to verify that the operation is appropriate given the stateid with which the operation is associated.

当读、写或SETATTR(指定大小属性)操作完成时,将根据访问模式检查该操作,以验证该操作是否适合与该操作关联的stateid。

In the case of WRITE-type operations (i.e., WRITEs and SETATTRs that set size), the server MUST verify that the access mode allows writing and MUST 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 OPEN4_SHARE_ACCESS_WRITE, to accommodate clients whose WRITE implementation may unavoidably do 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 specified OPEN4_SHARE_DENY_READ or OPEN4_SHARE_DENY_BOTH). Note that a server that does enforce the access mode check on READs need not explicitly check for conflicting share reservations since the existence of OPEN for OPEN4_SHARE_ACCESS_READ guarantees that no conflicting share reservation can exist.

对于写入类型操作(即设置大小的写入和设置属性),服务器必须验证访问模式是否允许写入,如果不允许,则必须返回NFS4ERR_OPENMODE错误。在读取的情况下,服务器可以对访问模式执行相应的检查,或者可以选择允许为OPEN4_SHARE_access_WRITE打开读取,以容纳写入实现可能不可避免地进行读取的客户端(例如,由于缓冲区缓存限制)。但是,即使在这些情况下允许读取,服务器仍必须检查与读取冲突的锁(例如,另一个打开的指定OPEN4_共享\u拒绝\u读取或OPEN4_共享\u拒绝\u读取)。请注意,对读取执行访问模式检查的服务器不需要显式检查冲突的共享保留,因为openforopen4_share_access_READ的存在保证了不存在冲突的共享保留。

The READ bypass special stateid (all bits of "other" and "seqid" set to one) indicates a desire to bypass locking checks. The server MAY allow READ operations to bypass locking checks at the server, when this special stateid is used. However, WRITE operations with this special stateid value MUST NOT bypass locking checks and are treated exactly the same as if a special stateid for anonymous state were used.

读取旁路特殊stateid(“其他”和“seqid”的所有位都设置为一)表示希望绕过锁定检查。使用此特殊stateid时,服务器可能允许读取操作绕过服务器上的锁定检查。但是,具有此特殊stateid值的写入操作不能绕过锁定检查,并且被视为与使用匿名状态的特殊stateid完全相同。

A lock may not be granted while a READ or WRITE operation using one of the special stateids is being performed and the scope of the lock to be granted would conflict with the READ or WRITE operation. This can occur when:

在执行使用特殊StateID之一的读或写操作时,可能不会授予锁,并且要授予的锁的范围将与读或写操作冲突。这可能发生在以下情况:

o A mandatory byte-range lock is requested with a byte-range that conflicts with the byte-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.

o 请求强制字节范围锁时,字节范围与读或写操作的字节范围冲突。在本段中,当请求共享锁并执行写入操作时,或请求独占锁并执行读取或写入操作时,会发生冲突。

o A share reservation is requested that denies reading and/or writing and the corresponding operation is being performed.

o 请求拒绝读取和/或写入的共享保留,并且正在执行相应的操作。

o A delegation is to be granted and the delegation type would prevent the I/O operation, i.e., READ and WRITE conflict with an OPEN_DELEGATE_WRITE delegation and WRITE conflicts with an OPEN_DELEGATE_READ delegation.

o 将授予委派,委派类型将阻止I/O操作,即,与OPEN_DELEGATE_WRITE委派的读写冲突以及与OPEN_DELEGATE_READ委派的写冲突。

When a client holds a delegation, it needs to ensure that the stateid sent conveys the association of operation with the delegation, to avoid the delegation from being avoidably recalled. When the delegation stateid, a stateid open associated with that delegation,

当客户机持有委托时,它需要确保发送的stateid传递操作与委托的关联,以避免不可避免地调用委托。当委托stateid打开时,与该委托关联的stateid,

or a stateid representing byte-range locks derived from such an open is used, the server knows that the READ, WRITE, or SETATTR does not conflict with the delegation but is sent under the aegis of the delegation. Even though it is possible for the server to determine from the client ID (via the session ID) that the client does in fact have a delegation, the server is not obliged to check this, so using a special stateid can result in avoidable recall of the delegation.

如果使用表示从此类打开派生的字节范围锁的stateid,则服务器知道读、写或SETATTR与委托不冲突,而是在委托的保护下发送。即使服务器可以从客户机ID(通过会话ID)确定客户机实际上具有委派,服务器也没有义务检查这一点,因此使用特殊的stateid可以避免调用委派。

9.2. Lock Ranges
9.2. 锁定范围

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

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

The client is discouraged from combining multiple independent locking ranges that happen to be adjacent into a single request since the server may not support sub-range requests for reasons related to the recovery of byte-range locking state in the event of server failure. As discussed in Section 8.4.2, 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.4.2节所述,服务器可在恢复期间采用某些优化,这些优化仅在锁定恢复期间的客户端行为与服务器故障之前的客户端锁定行为类似时有效。

9.3. Upgrading and Downgrading Locks
9.3. 升级和降级锁

If a client has a WRITE_LT lock on a byte-range, it can request an atomic downgrade of the lock to a READ_LT lock via the LOCK operation, 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.

如果客户端在某个字节范围内具有写锁,则可以通过锁操作将类型设置为读锁,请求将锁的原子降级为读锁。如果服务器支持原子降级,则请求将成功。否则,它将返回NFS4ERR\u LOCK\u NOTSUPP。客户端应准备好接收此错误,并在适当的情况下向请求的应用程序报告此错误。

If a client has a READ_LT lock on a byte-range, it can request an atomic upgrade of the lock to a WRITE_LT lock via the LOCK operation 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

如果客户端在某个字节范围内具有读锁,则可以通过将类型设置为WRITE\u LT或WRITEW\u LT,通过锁操作请求将锁的原子升级为WRITE\u LT锁。如果服务器不支持原子升级,它将返回NFS4ERR\u lock\u NOTSUPP。如果可以在不存在冲突的情况下实现升级,则请求

will succeed. Otherwise, the server will return either NFS4ERR_DENIED or NFS4ERR_DEADLOCK. The error NFS4ERR_DEADLOCK is returned if the client sent the LOCK operation 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.

我们会成功的。否则,服务器将返回NFS4ERR_DENIED或NFS4ERR_DEADLOCK。如果客户端发送了类型设置为WRITEW_LT的锁定操作,并且服务器检测到死锁,则返回错误NFS4ERR_DEADLOCK。客户机应做好接收此类错误的准备,并在适当情况下向请求的应用程序报告错误。

9.4. Stateid Seqid Values and Byte-Range Locks
9.4. Stateid Seqid值和字节范围锁

When a LOCK or LOCKU operation is performed, the stateid returned has the same "other" value as the argument's stateid, and a "seqid" value that is incremented (relative to the argument's stateid) to reflect the occurrence of the LOCK or LOCKU operation. The server MUST increment the value of the "seqid" field whenever there is any change to the locking status of any byte offset as described by any of the locks covered by the stateid. A change in locking status includes a change from locked to unlocked or the reverse or a change from being locked for READ_LT to being locked for WRITE_LT or the reverse.

执行锁定或锁定操作时,返回的stateid与参数的stateid具有相同的“其他”值,以及一个递增的“seqid”值(相对于参数的stateid),以反映锁定或锁定操作的发生。每当stateid所涵盖的任何锁所描述的任何字节偏移量的锁定状态发生任何更改时,服务器必须增加“seqid”字段的值。锁定状态的更改包括从锁定更改为解锁或反转,或从读取锁定更改为写入锁定或反转。

When there is no such change, as, for example, when a range already locked for WRITE_LT is locked again for WRITE_LT, the server MAY increment the "seqid" value.

当没有这种变化时,例如,当已经为写入锁定的范围再次为写入锁定时,服务器可以增加“seqid”值。

9.5. Issues with Multiple Open-Owners
9.5. 多个开放所有者的问题

When the same file is opened by multiple open-owners, a client will have multiple OPEN stateids for that file, each associated with a different open-owner. In that case, there can be multiple LOCK and LOCKU requests for the same lock-owner sent using the different OPEN stateids, and so a situation may arise in which there are multiple stateids, each representing byte-range locks on the same file and held by the same lock-owner but each associated with a different open-owner.

当同一个文件由多个打开的所有者打开时,客户端将为该文件拥有多个打开的stateID,每个ID都与不同的打开的所有者关联。在这种情况下,可以使用不同的打开状态ID发送针对同一锁所有者的多个锁和锁定请求,因此可能会出现多个状态ID的情况,每个状态ID表示同一文件上的字节范围锁,由同一锁所有者持有,但每个都与不同的打开状态所有者关联。

In such a situation, the locking status of each byte (i.e., whether it is locked, the READ_LT or WRITE_LT type of the lock, and the lock-owner holding the lock) MUST reflect the last LOCK or LOCKU operation done for the lock-owner in question, independent of the stateid through which the request was sent.

在这种情况下,每个字节的锁定状态(即,它是否被锁定、锁的读写类型以及持有锁的锁所有者)必须反映为相关锁所有者执行的最后一次锁定或锁定操作,与发送请求的stateid无关。

When a byte is locked by the lock-owner in question, the open-owner to which that byte-range lock is assigned SHOULD be that of the open-owner associated with the stateid through which the last LOCK of that byte was done. When there is a change in the open-owner associated with locks for the stateid through which a LOCK or LOCKU was done, the "seqid" field of the stateid MUST be incremented, even if the locking, in terms of lock-owners has not changed. When there is a

当有问题的锁所有者锁定某个字节时,分配该字节范围锁的开放所有者应该是与完成该字节最后一次锁定的stateid关联的开放所有者的开放所有者。当与锁或锁定通过的stateid的锁相关联的开放所有者发生更改时,stateid的“seqid”字段必须递增,即使锁所有者方面的锁定没有更改。当有

change to the set of locked bytes associated with a different stateid for the same lock-owner, i.e., associated with a different open-owner, the "seqid" value for that stateid MUST NOT be incremented.

如果更改为与同一锁所有者的不同stateid关联的锁定字节集,即与不同的打开所有者关联,则该stateid的“seqid”值不得增加。

9.6. Blocking Locks
9.6. 闭锁

Some clients require the support of blocking locks. While NFSv4.1 provides a callback when a previously unavailable lock becomes available, this is an OPTIONAL feature and clients cannot depend on its presence. Clients need to be prepared to continually poll for the lock. This presents a fairness problem. Two of the lock types, READW_LT and WRITEW_LT, are used to indicate to the server that the client is requesting a blocking lock. When the callback is not used, the server should maintain an ordered list of pending blocking locks. When the conflicting lock is released, the server may wait for the period of time equal to lease_time 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.

有些客户机需要阻塞锁的支持。虽然NFSv4.1在以前不可用的锁可用时提供回调,但这是一个可选功能,客户端不能依赖于它的存在。客户机需要准备好持续轮询锁。这是一个公平问题。两种锁类型READW_LT和WRITEW_LT用于向服务器指示客户端正在请求阻塞锁。当不使用回调时,服务器应该维护挂起的阻塞锁的有序列表。当冲突锁被释放时,服务器可能会等待相当于第一个等待的客户端重新请求锁的租赁时间的时间段。租赁期到期后,允许下一个等待的客户端请求锁定。客户端需要以足够小的间隔进行轮询,以便能够及时获取锁。服务器不需要维护挂起的阻塞锁列表,因为它用于增加公平性和不正确的操作。由于崩溃恢复的无序性,需要将锁状态存储到稳定存储,以保证阻塞锁的有序授予。

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 needless frequent polling for blocking locks. The server should take care in the length of delay in the event the client retransmits the request.

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

If a server receives a blocking LOCK operation, denies it, and then later receives a nonblocking request for the same lock, which is also denied, then it should remove the lock in question from its list of pending blocking locks. Clients should use such a nonblocking request to indicate to the server that this is the last time they intend to poll for the lock, as may happen when the process requesting the lock is interrupted. This is a courtesy to the server, to prevent it from unnecessarily waiting a lease period before granting other LOCK operations. However, clients are not required to perform this courtesy, and servers must not depend on them doing so. Also, clients must be prepared for the possibility that this final locking request will be accepted.

如果服务器接收到一个阻塞锁操作并拒绝它,然后又收到一个针对同一个锁的非阻塞请求(该请求也被拒绝),那么它应该从其挂起的阻塞锁列表中删除有问题的锁。客户端应该使用这样一个非阻塞请求来向服务器指示这是他们最后一次打算轮询锁,当请求锁的进程中断时可能会发生这种情况。这是对服务器的一种礼貌,以防止服务器在授予其他锁定操作之前不必要地等待一段租赁期。但是,客户机不需要执行这种礼节,服务器也不能依赖客户机这样做。此外,客户必须准备好接受最终锁定请求的可能性。

When a server indicates, via the flag OPEN4_RESULT_MAY_NOTIFY_LOCK, that CB_NOTIFY_LOCK callbacks might be done for the current open file, the client should take notice of this, but, since this is a

当服务器通过标志OPEN4\u RESULT\u MAY\u NOTIFY\u LOCK指示可以对当前打开的文件执行CB\u NOTIFY\u LOCK回调时,客户端应该注意到这一点,但是,由于这是一个

hint, cannot rely on a CB_NOTIFY_LOCK always being done. A client may reasonably reduce the frequency with which it polls for a denied lock, since the greater latency that might occur is likely to be eliminated given a prompt callback, but it still needs to poll. When it receives a CB_NOTIFY_LOCK, it should promptly try to obtain the lock, but it should be aware that other clients may be polling and that the server is under no obligation to reserve the lock for that particular client.

提示,不能依赖始终执行CB\U NOTIFY\U锁定。客户端可以合理地减少轮询被拒绝锁的频率,因为在提示回调的情况下可能会消除更大的延迟,但它仍然需要轮询。当它收到CB_NOTIFY_锁时,它应该立即尝试获取锁,但它应该知道其他客户端可能正在轮询,并且服务器没有义务为该特定客户端保留锁。

9.7. Share Reservations
9.7. 共享预订

A share reservation is a mechanism to control access to a file. It is a separate and independent mechanism from byte-range locking. When a client opens a file, it sends an OPEN operation to the server specifying the type of access required (READ, WRITE, or BOTH) and the type of access to deny others (OPEN4_SHARE_DENY_NONE, OPEN4_SHARE_DENY_READ, OPEN4_SHARE_DENY_WRITE, or OPEN4_SHARE_DENY_BOTH). If the OPEN fails, the client will fail the application's open request.

共享保留是一种控制文件访问的机制。它是一种独立于字节范围锁定的机制。当客户端打开一个文件时,它会向服务器发送一个打开操作,指定所需的访问类型(读、写或两者兼有)和拒绝其他人访问的类型(OPEN4_共享\u拒绝\u无、OPEN4_共享\u拒绝\u读、OPEN4_共享\u拒绝\u写或OPEN4_共享\u拒绝\u两者)。如果打开失败,客户端将使应用程序的打开请求失败。

Pseudo-code definition of the semantics:

语义的伪代码定义:

           if (request.access == 0) {
             return (NFS4ERR_INVAL)
           } else {
             if ((request.access & file_state.deny)) ||
                (request.deny & file_state.access)) {
               return (NFS4ERR_SHARE_DENIED)
           }
           return (NFS4ERR_OK);
        
           if (request.access == 0) {
             return (NFS4ERR_INVAL)
           } else {
             if ((request.access & file_state.deny)) ||
                (request.deny & file_state.access)) {
               return (NFS4ERR_SHARE_DENIED)
           }
           return (NFS4ERR_OK);
        

When doing this checking of share reservations on OPEN, the current file_state used in the algorithm includes bits that reflect all current opens, including those for the open-owner making the new OPEN request.

在打开时检查共享保留时,算法中使用的当前文件状态包括反映所有当前打开的位,包括发出新打开请求的打开所有者的位。

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

To provide correct share semantics, a client MUST use the OPEN operation to obtain the initial filehandle and indicate the desired access and what access, if any, to deny. Even if the client intends to use a special stateid for anonymous state or READ bypass, it must still obtain the filehandle for the regular file with the OPEN operation so the appropriate share semantics can be applied. Clients that do not have a deny mode built into their programming interfaces for opening a file should request a deny mode of OPEN4_SHARE_DENY_NONE.

为了提供正确的共享语义,客户端必须使用OPEN操作来获取初始文件句柄,并指示所需的访问以及要拒绝的访问(如果有)。即使客户机打算对匿名状态或读取旁路使用特殊的stateid,它仍然必须通过OPEN操作获取常规文件的filehandle,以便应用适当的共享语义。如果客户端的编程接口中没有内置用于打开文件的拒绝模式,则应请求OPEN4_SHARE_deny_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 open-owner on that file. If byte-range locks are held, the client SHOULD release all locks before sending a CLOSE operation. The server MAY free all outstanding locks on CLOSE, but some servers may not support the CLOSE of a file that still has byte-range 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 that the client has the least access. For example, if one client opened a file with OPEN4_SHARE_DENY_BOTH and another client accesses the file via a filehandle obtained through LOOKUP, the second client could only read the file using the special read bypass stateid. The second client could not WRITE the file at all because it would not have a valid stateid from OPEN and the special anonymous stateid would not be allowed access.

查找操作将返回文件句柄,而不会在服务器上建立任何锁定状态。如果没有有效的stateid,服务器将假定客户端具有最少的访问权限。例如,如果一个客户机同时使用OPEN4_SHARE_DENY_打开一个文件,而另一个客户机通过通过查找获得的文件句柄访问该文件,则第二个客户机只能使用特殊的读取旁路stateid读取该文件。第二个客户端根本无法写入该文件,因为它没有来自OPEN的有效stateid,并且不允许访问特殊的匿名stateid。

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

When an OPEN is done for a file and the open-owner 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. The OPEN is represented by a single stateid whose "other" value matches that of the original open, and whose "seqid" value is incremented to reflect the occurrence of the upgrade. The increment is required in cases in which the "upgrade" results in no change to the open mode (e.g., an OPEN is done for read when the existing open file is opened for

当对某个文件执行打开操作,并且正在执行打开操作的打开所有者已打开该文件时,结果是升级服务器上维护的打开文件状态,以包括新打开指定的访问和拒绝位以及现有打开指定的访问和拒绝位。结果是,就协议而言,有一个打开的文件,它包括所有已完成的打开请求的访问位和拒绝位的联合。OPEN由一个stateid表示,其“other”值与原始OPEN的值匹配,其“seqid”值递增以反映升级的发生。如果“升级”导致打开模式没有改变(例如,当打开现有打开的文件以供读取时,打开以供读取),则需要增量

OPEN4_SHARE_ACCESS_BOTH). Only a single CLOSE will be done to reset the effects of both OPENs. The client may use the stateid returned by the OPEN effecting the upgrade or with a stateid sharing the same "other" field and a seqid of zero, although care needs to be taken as far as upgrades that happen while the CLOSE is pending. Note that the client, when sending 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.

OPEN4_共享_访问_两者)。只有一次关闭才能重置两次打开的效果。客户机可以使用由执行升级的OPEN返回的stateid,也可以使用共享同一“other”字段的stateid和零的seqid,尽管在关闭挂起期间发生的升级需要小心。请注意,客户端在发送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. The stateid returned has the same "other" field as that passed to the server. The "seqid" value in the returned stateid MUST be incremented, even in situations in which there is no change to the access and deny bits for the file.

当客户端上的多个打开的文件合并到服务器上的单个打开的文件对象中时,关闭其中一个打开的文件(客户端上)可能需要更改服务器上打开的文件的访问和拒绝状态。这是因为剩余打开的访问位和拒绝位的联合可能比以前更小(即,适当的子集)。OPEN_降级操作用于进行必要的更改,客户端应使用它更新服务器,以便正确处理其他客户端的共享保留请求。返回的stateid与传递给服务器的stateid具有相同的“other”字段。即使在文件的访问和拒绝位没有更改的情况下,返回的stateid中的“seqid”值也必须递增。

9.10. Parallel OPENs
9.10. 平行开口

Unlike the case of NFSv4.0, in which OPEN operations for the same open-owner are inherently serialized because of the owner-based seqid, multiple OPENs for the same open-owner may be done in parallel. When clients do this, they may encounter situations in which, because of the existence of hard links, two OPEN operations may turn out to open the same file, with a later OPEN performed being an upgrade of the first, with this fact only visible to the client once the operations complete.

与NFSv4.0的情况不同,在NFSv4.0中,由于基于所有者的seqid,同一开放所有者的开放操作本质上是序列化的,同一开放所有者的多个开放操作可以并行完成。当客户端执行此操作时,他们可能会遇到这样的情况:由于存在硬链接,两个打开的操作可能会打开同一个文件,随后执行的打开操作是第一个打开操作的升级,只有在操作完成后,客户端才能看到这一事实。

In this situation, clients may determine the order in which the OPENs were performed by examining the stateids returned by the OPENs. Stateids that share a common value of the "other" field can be recognized as having opened the same file, with the order of the operations determinable from the order of the "seqid" fields, mod any possible wraparound of the 32-bit field.

在这种情况下,客户端可以通过检查打开返回的StateID来确定打开的顺序。共享“other”字段的公共值的StateID可以被识别为打开了同一个文件,操作顺序可以从“seqid”字段的顺序确定,修改32位字段的任何可能的环绕。

When the possibility exists that the client will send multiple OPENs for the same open-owner in parallel, it may be the case that an open upgrade may happen without the client knowing beforehand that this could happen. Because of this possibility, CLOSEs and OPEN_DOWNGRADEs should generally be sent with a non-zero seqid in the stateid, to avoid the possibility that the status change associated with an open upgrade is not inadvertently lost.

当客户机可能会并行发送同一开放所有者的多个开放时,可能会在客户机事先不知道可能发生的情况下进行开放升级。由于这种可能性,关闭和打开降级通常应在stateid中使用非零seqid发送,以避免与打开升级相关的状态更改不会意外丢失的可能性。

9.11. Reclaim of Open and Byte-Range Locks
9.11. 回收打开和字节范围锁

Special forms of the LOCK and OPEN operations are provided when it is necessary to re-establish byte-range locks or opens after a server failure.

当需要重新建立字节范围锁或在服务器故障后打开时,会提供特殊形式的锁定和打开操作。

o To reclaim existing opens, an OPEN operation is performed using a CLAIM_PREVIOUS. Because the client, in this type of situation, will have already opened the file and have the filehandle of the target file, this operation requires that the current filehandle be the target file, rather than a directory, and no file name is specified.

o 若要回收现有打开的文件,请使用CLAIM_PREVIOUS执行打开操作。因为在这种情况下,客户端将已经打开文件并拥有目标文件的filehandle,所以此操作要求当前filehandle是目标文件,而不是目录,并且不指定文件名。

o To reclaim byte-range locks, a LOCK operation with the reclaim parameter set to true is used.

o 要回收字节范围锁,将使用回收参数设置为true的锁操作。

Reclaims of opens associated with delegations are discussed in Section 10.2.1.

第10.2.1节讨论了与授权相关的开放回收。

10. Client-Side Caching
10. 客户端缓存

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 NFSv4.1 protocol uses many techniques similar to those that have been used in previous protocol versions. The NFSv4.1 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.

NFSv4.1协议使用了许多类似于先前协议版本中使用的技术。NFSv4.1协议不提供分布式缓存一致性。但是,它定义了一组更有限的缓存保证,以允许在不受客户端缓存破坏性干扰的情况下使用锁和共享保留。

In addition, the NFSv4.1 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.

此外,NFSv4.1协议引入了一种委托机制,它允许客户端在本地做出通常由服务器做出的许多决策。此机制为共享不频繁或共享为只读的常见情况提供了有效支持。

10.1. Performance Challenges for Client-Side Caching
10.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 references to the server to find that no conflicts exist are 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 byte-range locking. Sending LOCK and LOCKU operations as well as the READ and WRITE operations necessary to make data caching consistent with the locking semantics (see Section 10.3.2) 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 byte-range locking by applications.

字节范围锁定也会出现类似的情况。发送锁定和锁定操作以及使数据缓存与锁定语义一致所需的读写操作(见第10.3.2节)可能严重限制性能。如果使用锁定来防止不经常发生的冲突,则会产生很大的损失。此惩罚可能会阻止应用程序使用字节范围锁定。

The NFSv4.1 protocol provides more aggressive caching strategies with the following design goals:

NFSv4.1协议提供了更积极的缓存策略,具有以下设计目标:

o Compatibility with a large range of server semantics.

o 与大量服务器语义的兼容性。

o Providing the same caching benefits as previous versions of the NFS protocol when unable to support 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 Section 10.4).

服务器的适当要求将在后面的章节中讨论,其中将介绍特定形式的缓存(请参见第10.4节)。

10.2. Delegation and Callbacks
10.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 client ID and may be 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.

委托从服务器传递到客户端,指定委托对象和委托类型。有不同类型的委托,但每种类型都包含一个stateid,用于在执行依赖于委托的操作时表示委托。此stateid类似于与锁和共享保留关联的stateid,但不同之处在于,委托的stateid与客户端ID关联,并且可以代表给定客户端的所有开放所有者使用。委托是作为一个整体委托给客户机的,而不是委托给客户机中的任何特定进程或控制线程。

The backchannel is established by CREATE_SESSION and BIND_CONN_TO_SESSION, and the client is required to maintain it. Because the backchannel may be down, even temporarily, correct protocol operation does not depend on them. Preliminary testing of backchannel functionality by means of a CB_COMPOUND procedure with a single operation, CB_SEQUENCE, can be used to check the continuity of the backchannel. A server avoids delegating responsibilities until it has determined that the backchannel exists. 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, WANT_DELEGATIONs, and GET_DIR_DELEGATIONs to be processed without any delegations being granted.

反向通道是通过创建会话和将会话连接到会话建立的,需要客户端对其进行维护。因为反向通道可能会关闭,即使是暂时关闭,正确的协议操作也不依赖于它们。通过CB_复合程序和单个操作(CB_序列)对反向通道功能进行初步测试,可用于检查反向通道的连续性。在确定反向通道存在之前,服务器避免委派职责。由于授予委托始终以不存在冲突访问为条件,因此客户不得假设将授予委托,并且他们必须始终准备好开放、想要委托,并在不授予任何委托的情况下处理委托。

Unlike locks, an operation by a second client to a delegated file will cause the server to recall a delegation through a callback. For individual operations, we will describe, under IMPLEMENTATION, when such operations are required to effect a recall. A number of points should be noted, however.

与锁不同,第二个客户端对委托文件的操作将导致服务器通过回调调用委托。对于单个操作,我们将在实施中描述何时需要此类操作来实施召回。然而,应注意到一些要点。

o The server is free to recall a delegation whenever it feels it is desirable and may do so even if no operations requiring recall are being done.

o 服务器可以在认为需要时随时调用委派,即使没有执行需要调用的操作,也可以这样做。

o Operations done outside the NFSv4.1 protocol, due to, for example, access by other protocols, or by local access, also need to result in delegation recall when they make analogous changes to file system data. What is crucial is if the change would invalidate the guarantees provided by the delegation. When this is possible, the delegation needs to be recalled and MUST be returned or revoked before allowing the operation to proceed.

o 在NFSv4.1协议之外执行的操作(例如,由于其他协议的访问或本地访问)在对文件系统数据进行类似更改时,也需要导致委托召回。关键的是,这一改变是否会使代表团提供的保证失效。如果可能,则需要重新调用委派,并且必须在允许操作继续之前返回或撤销委派。

o The semantics of the file system are crucial in defining when delegation recall is required. If a particular change within a specific implementation causes change to a file attribute, then delegation recall is required, whether that operation has been specifically listed as requiring delegation recall. Again, what is critical is whether the guarantees provided by the delegation are being invalidated.

o 文件系统的语义对于定义何时需要调用委托至关重要。如果特定实现中的特定更改导致文件属性发生更改,则需要进行委派调用,无论该操作是否已被明确列为需要委派调用。同样,关键的是代表团提供的保证是否无效。

Despite those caveats, the implementation sections for a number of operations describe situations in which delegation recall would be required under some common circumstances:

尽管有这些警告,但许多操作的实施章节描述了在某些常见情况下需要授权召回的情况:

o For GETATTR, see Section 18.7.4.

o 有关GETATTR,请参见第18.7.4节。

o For OPEN, see Section 18.16.4.

o 关于开放式,见第18.16.4节。

o For READ, see Section 18.22.4.

o 有关READ,请参见第18.22.4节。

o For REMOVE, see Section 18.25.4.

o 有关拆卸,请参见第18.25.4节。

o For RENAME, see Section 18.26.4.

o 有关重命名,请参见第18.26.4节。

o For SETATTR, see Section 18.30.4.

o 有关SETATTR,请参见第18.30.4节。

o For WRITE, see Section 18.32.4.

o 有关写入,请参见第18.32.4节。

On recall, the client holding the delegation needs to flush modified state (such as modified data) to the server and return the delegation. The conflicting request will not be acted on until the recall is complete. The recall is considered complete when the client returns the delegation or the server times its wait for the delegation to be returned and revokes the delegation as a result of the timeout. In the interim, the server will either delay responding to conflicting requests or respond to them with NFS4ERR_DELAY. Following the resolution of the recall, the server has the information necessary to grant or deny the second client's request.

调用时,持有委托的客户端需要将修改后的状态(如修改后的数据)刷新到服务器并返回委托。在召回完成之前,不会对冲突请求采取行动。当客户端返回委派或服务器对委派返回的等待时间进行乘以,并由于超时而撤销委派时,调用被视为完成。在此期间,服务器将延迟响应冲突请求,或使用NFS4ERR_延迟响应冲突请求。在解决召回问题后,服务器具有批准或拒绝第二个客户端请求所需的信息。

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 Section 10.4). 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 states for the file allow any particular open until the delegation for the file has been returned.

这方面的一个例子是,将对给定文件进行调解的责任委托给客户(见第10.4节)。服务器将不知道在客户端上打开的是什么。如果不知道这一点,服务器将无法确定文件的访问和拒绝状态是否允许任何特定的打开,直到文件的委托被返回。

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.

客户端故障或网络分区可能导致无法响应回调。在这种情况下,服务器将撤销委托,这反过来会使客户端上的任何修改状态变得无用。

10.2.1. Delegation Recovery
10.2.1. 授权恢复

There are three situations that delegation recovery needs to deal with:

授权恢复需要处理三种情况:

o client restart

o 客户端重启

o server restart

o 服务器重启

o network partition (full or backchannel-only)

o 网络分区(仅限完整或反向通道)

In the event the client restarts, the failure to renew the lease will result in the revocation of byte-range locks and share reservations. Delegations, however, may be treated a bit differently.

如果客户端重新启动,无法续订租约将导致字节范围锁和共享保留被撤销。然而,代表团的待遇可能有所不同。

There will be situations in which delegations will need to be re-established after a client restarts. The reason for this is that the client may have file data stored locally and this data was associated with the previously held delegations. The client will need to re-establish 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 restart 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 or CLAIM_DELEG_PREV_FH (see Sections 10.5 and 18.16 for discussion of OPEN delegation and the details of OPEN, respectively).

委托,此类委托将使用OPEN回收,索赔类型为claim_DELEGATE_PREV或claim_DELEG_PREV_FH(关于公开委托的讨论和OPEN的详细信息,分别参见第10.5节和第18.16节)。

A server MAY support claim types of CLAIM_DELEGATE_PREV and CLAIM_DELEG_PREV_FH, and if it does, it MUST NOT remove delegations upon a CREATE_SESSION that confirm a client ID created by EXCHANGE_ID. Instead, the server 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 send CLAIM_DELEGATE_PREV and/or CLAIM_DELEG_PREV_FH requests. The server that supports CLAIM_DELEGATE_PREV and/or CLAIM_DELEG_PREV_FH MUST support the DELEGPURGE operation.

服务器可能支持claim_DELEGATE_PREV和claim_Delegu PREV_FH的声明类型,如果支持,则在确认由EXCHANGE_ID创建的客户端ID的创建会话上,服务器不得删除委托。相反,服务器必须在不少于lease_time属性值的时间段内,维护客户授权,以便客户有时间发送索赔委托请求和/或索赔委托请求。支持CLAIM_DELEGATE_PREV和/或CLAIM_DELEG_PREV_FH的服务器必须支持DELEGPURGE操作。

When the server restarts, delegations are reclaimed (using the OPEN operation with CLAIM_PREVIOUS) in a similar fashion to byte-range 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 NFSv4.1 protocol:

当服务器重新启动时,将以与字节范围锁和共享保留类似的方式回收委派(使用CLAIM_PREVIOUS的OPEN操作)。然而,有一点语义上的差异。在正常情况下,如果服务器决定不应授予委派,它将执行请求的操作(例如,打开),而不授予任何委派。对于回收,服务器授予委派,但应用了特殊的指定,以便客户端将委派视为已被授予但被服务器调用。因此,客户机有责任将所有修改的状态写入服务器,然后返回委托。处理委托回收的过程符合NFSv4.1协议的三个原则:

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 should not be depended upon until the client has proven its ability to receive them.

o 在客户机证明其有能力接收回调之前,不应依赖回调的使用。

When a client needs to reclaim a delegation and there is no associated open, the client may use the CLAIM_PREVIOUS variant of the WANT_DELEGATION operation. However, since the server is not required to support this operation, an alternative is to reclaim via a dummy OPEN together with the delegation using an OPEN of type CLAIM_PREVIOUS. The dummy open file can be released using a CLOSE to re-establish the original state to be reclaimed, a delegation without an associated open.

当客户机需要回收委托,并且没有关联的打开时,客户机可以使用WANT_委托操作的CLAIM_PREVIOUS变体。但是,由于服务器不需要支持此操作,另一种方法是使用CLAIM_PREVIOUS类型的OPEN通过虚拟OPEN和委托一起进行回收。可以使用关闭来释放虚拟打开文件,以重新建立要回收的原始状态,这是一个没有关联打开的委托。

When a client has more than a single open associated with a delegation, state for those additional opens can be established using OPEN operations of type CLAIM_DELEGATE_CUR. When these are used to establish opens associated with reclaimed delegations, the server MUST allow them when made within the grace period.

当客户端有多个与委托关联的打开时,可以使用CLAIM\u DELEGATE\u CUR类型的打开操作来建立这些额外打开的状态。当这些用于建立与回收的委派关联的打开时,服务器必须在宽限期内允许这些打开。

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 backchannel (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 one of the errors NFS4ERR_EXPIRED, NFS4ERR_ADMIN_REVOKED, or NFS4ERR_DELEG_REVOKED. It also may find out about delegation revocation after a client restart when it attempts to reclaim a delegation and receives that same error. Note that in the case of a revoked OPEN_DELEGATE_WRITE delegation, there are issues because data may have been modified by the client whose delegation is revoked and separately by other clients. See Section 10.5.1 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 Section 8.4.3). This is done to deal with the case in which a server restarts after revoking a delegation but before the client holding the revoked delegation is notified about the revocation.

当客户端使用与委派关联的stateid并收到以下错误之一时,通常会发现委派的吊销:NFS4ERR_EXPIRED、NFS4ERR_ADMIN_Reversed或NFS4ERR_DELEG_Reversed。当它尝试回收委托并收到相同错误时,它还可能在客户端重新启动后发现委托撤销。请注意,对于已撤销的OPEN_DELEGATE_WRITE委派,存在一些问题,因为数据可能已被其委派已撤销的客户机修改,也可能已被其他客户机单独修改。有关此类问题的讨论,请参见第10.5.1节。还请注意,当委托被撤销时,服务器将把有关被撤销委托的信息写入稳定存储器(如第8.4.3节所述)。这样做是为了处理这样的情况,即服务器在撤销委派之后,但在持有已撤销委派的客户端收到有关撤销的通知之前重新启动。

10.3. Data Caching
10.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 byte-range locks are the facilities the NFSv4.1 protocol provides to allow applications to coordinate access by using mutual exclusion facilities. The NFSv4.1 protocol's data caching must be implemented such that it does not invalidate the assumptions on which those using these facilities depend.

共享保留和字节范围锁是NFSv4.1协议提供的设施,允许应用程序通过互斥设施协调访问。NFSv4.1协议的数据缓存的实现必须确保不会使使用这些设施的人所依赖的假设失效。

10.3.1. Data Caching and OPENs
10.3.1. 数据缓存并打开

In order to avoid invalidating the sharing assumptions on which applications rely, NFSv4.1 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.

为了避免应用程序所依赖的共享假设失效,当通过读或写操作获取或修改相同数据无效时,NFSv4.1客户端不应向应用程序提供缓存数据或代表应用程序修改缓存数据。

Furthermore, in the absence of an OPEN delegation (see Section 10.4), two additional rules apply. Note that these rules are obeyed in practice by many NFSv3 clients.

此外,在没有公开授权的情况下(见第10.4节),适用另外两条规则。请注意,许多NFSv3客户端在实践中都遵守这些规则。

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 a deny of OPEN4_SHARE_DENY_WRITE or OPEN4_SHARE_DENY_BOTH, thus terminating a period in which other clients may have had the opportunity to open the file with OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_BOTH access. Clients may choose to do the revalidation more often (i.e., at OPENs specifying a deny mode of OPEN4_SHARE_DENY_NONE) to parallel the NFSv3 protocol's practice for the benefit of users assuming this degree of cache revalidation.

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

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 the change attribute 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, 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. Thus, any cache validation approach by the client MUST include the use of the change attribute.

由于更改属性是为数据和元数据修改而更新的,因此一些客户机实现人员可能会尝试使用time_modify属性而不是change属性来验证缓存的数据,以便元数据更改不会错误地使干净的数据无效。在这种方法中,实现者会受到警告。对于文件的每次更新,change属性都保证更改,而time_modify则保证仅在time_delta属性的粒度上更改。客户机的数据缓存使用time_modify和not change的验证逻辑可能会导致客户机错误地将过时数据标记为有效数据。因此,客户机的任何缓存验证方法都必须包括使用change属性。

o Second, modified data must be flushed to the server before closing a file OPENed for OPEN4_SHARE_ACCESS_WRITE. This is complementary to the first rule. If the data is not flushed at CLOSE, the revalidation done after the client OPENs a 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

o 其次,在关闭为OPEN4\u共享\u访问\u写入而打开的文件之前,必须将修改后的数据刷新到服务器。这是对第一条规则的补充。如果关闭时未刷新数据,则在客户端打开文件后进行的重新验证无法达到其目的。关闭前刷新数据的另一个方面是,在客户端请求关闭操作之前,必须将数据提交到服务器上的稳定存储中。在里面

the case of a server restart and a CLOSEd file, it may not be possible to retransmit the data to be written to the file, hence, this requirement.

在服务器重新启动和文件关闭的情况下,可能无法重新传输要写入文件的数据,因此需要满足此要求。

10.3.2. Data Caching and File Locking
10.3.2. 数据缓存和文件锁定

For those applications that choose to use byte-range 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 byte-range locking is used in a way that matches in an equivalent way the actual READ and WRITE operations executed. This is as opposed to byte-range 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 ranges and protecting access to the two byte-ranges by byte-range locks on bytes zero and one. A WRITE_LT lock on byte zero of the file would represent the right to perform READ and WRITE operations on the first byte-range. A WRITE_LT lock on byte one of the file would represent the right to perform READ and WRITE operations on the second byte-range. As long as all applications manipulating the file obey this convention, they will work on a local file system. However, they may not work with the NFSv4.1 protocol unless clients refrain from data caching.

对于那些选择使用字节范围锁定而不是共享保留来排除不一致文件访问的应用程序,有一组类似的约束适用于客户端数据缓存。这些规则只有在字节范围锁定的使用方式与实际执行的读写操作相匹配时才有效。这与基于纯约定的字节范围锁定相反。例如,可以通过将文件划分为两个1兆字节的范围,并通过字节0和1上的字节范围锁来保护对两个字节范围的访问,从而操纵一个2兆字节的文件。文件零字节上的写锁定表示对第一个字节范围执行读写操作的权限。文件的字节1上的写锁定表示对第二个字节范围执行读写操作的权限。只要操作文件的所有应用程序都遵守此约定,它们就可以在本地文件系统上工作。但是,除非客户端不进行数据缓存,否则它们可能无法与NFSv4.1协议一起工作。

The rules for data caching in the byte-range locking environment are:

字节范围锁定环境中的数据缓存规则如下:

o First, when a client obtains a byte-range lock for a particular byte-range, the data cache corresponding to that byte-range (if any cache data exists) must be revalidated. If the change attribute indicates that the file may have been updated since the cached data was obtained, the client must flush or invalidate the cached data for the newly locked byte-range. A client might choose to invalidate all of the 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 byte-range.

o 首先,当客户端获得特定字节范围的字节范围锁时,必须重新验证与该字节范围对应的数据缓存(如果存在任何缓存数据)。如果change属性指示文件可能在获取缓存数据后已更新,则客户端必须刷新或使新锁定字节范围的缓存数据无效。客户机可能会选择使文件中所有未修改的缓存数据无效,但正确操作的唯一要求是使新锁定字节范围中的所有数据无效。

o Second, before releasing a WRITE_LT lock for a byte-range, all modified data for that byte-range 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 byte-range outside the unlocked area. This, in turn, may be part of a byte-range 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 that 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 that the client possesses may not be valid.

执行与非完整块部分(初始或最终)重叠的写入操作部分。类似地,如果重新验证过程表明客户机拥有的数据可能无效,则使非整数个完整缓冲区块的锁定区域无效将需要客户机从服务器读取一个或两个部分块。

The data that is written to the server as a prerequisite to the unlocking of a byte-range 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 restart might conflict with a lock held by another client.

作为解锁字节范围的先决条件写入服务器的数据必须在服务器上写入稳定存储器。客户机可以通过同步写入或使用提交操作跟踪异步写入来完成这一点。这是必需的,因为重新启动服务器后重新传输修改后的数据可能会与另一个客户端持有的锁冲突。

A client implementation may choose to accommodate applications that use byte-range locking in non-standard ways (e.g., using a byte-range lock as a global semaphore) by flushing to the server more data upon a 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 byte-range locks that 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 LOCKU operation. 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 byte-range lock and those for which there are modifications not covered by a byte-range lock. Any writes done for the former class of files must not include areas not locked and thus not modified on the client.

客户机实现可以通过向服务器刷新锁上超过锁定范围覆盖的更多数据来选择以非标准方式(例如,使用字节范围锁作为全局信号量)使用字节范围锁定的应用程序。这可能包括文件中的修改数据,而不是正在进行解锁的文件。在这种情况下,客户端不得干扰仅在应用程序持有的字节范围锁的范围内进行读写的应用程序。例如,应用程序锁定文件的一个字节并继续写入该字节。选择通过将所有修改的数据刷新到服务器来处理锁定的客户端可以有效地写入该单个字节以响应不相关的锁定操作。但是,写入单个写入字节所在的整个块是无效的,因为它包含一个未锁定的区域,并且可能被另一个客户端锁定。客户端实现可以通过将具有修改数据的文件划分为对适当字节范围锁覆盖的区域进行所有修改的文件和未被字节范围锁覆盖的文件来避免此问题。为前一类文件执行的任何写入操作都不得包括未锁定的区域,因此也不得在客户端上修改这些区域。

10.3.3. Data Caching and Mandatory File Locking
10.3.3. 数据缓存和强制文件锁定

Client-side data caching needs to respect mandatory byte-range locking when it is in effect. The presence of mandatory byte-range locking for a given file is indicated when the client gets back NFS4ERR_LOCKED from a READ or WRITE operation on a file for which it has an appropriate share reservation. When mandatory locking is in effect for a file, the client must check for an appropriate byte-range lock for data being read or written. If a byte-range lock exists for the range being read or written, the client may satisfy the request using the client's validated cache. If an appropriate byte-range 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

客户端数据缓存在生效时需要遵守强制的字节范围锁定。当客户端从对其具有适当共享保留的文件执行的读或写操作中恢复NFS4ERR_LOCKED时,会指示给定文件是否存在强制字节范围锁定。当强制锁定对文件生效时,客户端必须为正在读取或写入的数据检查适当的字节范围锁定。如果正在读取或写入的范围存在字节范围锁,则客户端可以使用客户端的已验证缓存来满足请求。如果没有为读取或写入的范围保留适当的字节范围锁,则客户端的缓存和

the request must be sent to the server for processing. When a read or write request partially overlaps a locked byte-range, the request should be subdivided into multiple pieces with each byte-range (locked or not) treated appropriately.

必须将请求发送到服务器进行处理。当读或写请求与锁定的字节范围部分重叠时,应将请求细分为多个部分,并适当处理每个字节范围(锁定或未锁定)。

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

When clients cache data, the file data needs to be organized according to the file system object to which the data belongs. For NFSv3 clients, the typical practice has been to assume for the purpose of caching that distinct filehandles represent distinct file system objects. The client then has the choice to organize and maintain the data cache on this basis.

当客户端缓存数据时,需要根据数据所属的文件系统对象组织文件数据。对于NFSv3客户机,典型的做法是为了缓存,假定不同的文件句柄表示不同的文件系统对象。然后,客户机可以在此基础上选择组织和维护数据缓存。

In the NFSv4.1 protocol, there is now the possibility to have significant deviations from a "one filehandle per object" model because a filehandle may be constructed on the basis of the object's pathname. Therefore, clients need a reliable method to determine if two filehandles designate the same file system object. If clients were simply to assume that all distinct filehandles denote distinct objects and proceed to do data caching on this basis, caching inconsistencies would arise between the distinct client-side objects that mapped to the same server-side object.

在NFSv4.1协议中,现在可能与“每个对象一个文件句柄”模型存在重大偏差,因为文件句柄可以基于对象的路径名构建。因此,客户端需要一种可靠的方法来确定两个文件句柄是否指定相同的文件系统对象。如果客户端只是假设所有不同的文件句柄都表示不同的对象,并在此基础上继续进行数据缓存,那么映射到同一服务器端对象的不同客户端对象之间就会出现缓存不一致的情况。

By providing a method to differentiate filehandles, the NFSv4.1 protocol alleviates a potential functional regression in comparison with the NFSv3 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.

通过提供一种区分文件句柄的方法,与NFSv3协议相比,NFSv4.1协议减轻了潜在的功能回归。如果没有此方法,可能会在同一客户机中发生缓存不一致,这在以前版本的NFS协议中是不存在的。请注意,在多个客户端上执行的应用程序可能存在这种不一致,但这不是本文要解决的问题。

For the purposes of data caching, the following steps allow an NFSv4.1 client to determine whether two distinct filehandles denote the same server-side object:

出于数据缓存的目的,以下步骤允许NFSv4.1客户端确定两个不同的文件句柄是否表示相同的服务器端对象:

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 that depend on that knowledge (e.g., client-side data

o 如果指向两个FileHandle的GETATTR没有为这两个句柄返回fileid属性,则无法确定这两个对象是否相同。因此,依赖于该知识的操作(例如,客户端数据

caching) cannot be done reliably. Note that if GETATTR does not return the fileid attribute for both filehandles, it will return it for neither of the filehandles, since the fsid for both filehandles is the same.

缓存)无法可靠地完成。请注意,如果GETATTR没有为两个filehandles返回fileid属性,那么它将为两个filehandles都返回该属性,因为两个filehandles的fsid相同。

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 否则,它们是相同的对象。

10.4. Open Delegation
10.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, if the server receives 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 an OPEN should be delegated:

打开文件时,服务器可以将该文件的打开和关闭的进一步处理委托给打开的客户端。任何此类授权都是可撤销的,因为允许授权的情况可能会发生变化。特别是,如果服务器从另一个客户端接收到冲突的打开,则服务器必须在决定是否可以授予来自另一个客户端的打开之前调用委托。委托由服务器决定,客户机不应认为任何特定的开放式委托会或不会导致开放式委托。以下是一组典型的条件,服务器可能会使用这些条件来决定是否委派OPEN:

o The client must be able to respond to the server's callback requests. If a backchannel has been established, the server will send a CB_COMPOUND request, containing a single operation, CB_SEQUENCE, for a test of backchannel availability.

o 客户端必须能够响应服务器的回调请求。如果建立了反向通道,服务器将发送一个CB_复合请求,其中包含一个操作CB_序列,用于测试反向通道的可用性。

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: OPEN_DELEGATE_READ and OPEN_DELEGATE_WRITE. An OPEN_DELEGATE_READ delegation allows a client to handle, on its own, requests to open a file for reading that do not deny OPEN4_SHARE_ACCESS_READ access to others. Multiple

开放式委托有两种类型:开放式委托读取和开放式委托写入。OPEN_DELEGATE_READ delegation允许客户端自行处理打开文件进行读取的请求,而不拒绝其他客户端对OPEN4_SHARE_ACCESS_READ的访问。倍数

OPEN_DELEGATE_READ delegations may be outstanding simultaneously and do not conflict. An OPEN_DELEGATE_WRITE delegation allows the client to handle, on its own, all opens. Only OPEN_DELEGATE_WRITE delegation may exist for a given file at a given time, and it is inconsistent with any OPEN_DELEGATE_READ delegations.

开放式授权可以同时处于未完成状态且不冲突。OPEN_DELEGATE_WRITE委托允许客户端自行处理所有打开的文件。给定文件在给定时间只能存在OPEN_DELEGATE_WRITE委派,并且它与任何OPEN_DELEGATE_READ委派不一致。

When a client has an OPEN_DELEGATE_READ delegation, it is assured that neither the contents, the attributes (with the exception of time_access), nor the names of any links to the file will change without its knowledge, so long as the delegation is held. When a client has an OPEN_DELEGATE_WRITE delegation, it may modify the file data locally since no other client will be accessing the file's data. The client holding an OPEN_DELEGATE_WRITE delegation may only locally affect file attributes that are intimately connected with the file data: size, change, time_access, time_metadata, and time_modify. All other attributes must be reflected on the server.

当客户机具有OPEN_DELEGATE_READ委托时,只要委托保持不变,则可以确保内容、属性(时间访问除外)以及指向文件的任何链接的名称都不会在其不知情的情况下更改。当客户机具有OPEN_DELEGATE_WRITE委托时,它可能会在本地修改文件数据,因为没有其他客户机将访问该文件的数据。持有OPEN_DELEGATE_WRITE delegation的客户端只能在本地影响与文件数据密切相关的文件属性:大小、更改、时间访问、时间元数据和时间修改。所有其他属性必须反映在服务器上。

When a client has an OPEN delegation, it does not need to send OPENs or CLOSEs to the server. Instead, the client may update the appropriate status internally. For an OPEN_DELEGATE_READ delegation, opens that cannot be handled locally (opens that are for OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_BOTH or that deny OPEN4_SHARE_ACCESS_READ access) must be sent to the server.

当客户机具有开放式委派时,它不需要向服务器发送OPEN或CLOSE。相反,客户端可以在内部更新适当的状态。对于开放式委托\读取委托,必须将无法在本地处理的打开(用于OPEN4\共享\访问\写入/OPEN4\共享\访问\两者或拒绝OPEN4\共享\访问\读取访问的打开)发送到服务器。

When an OPEN delegation is made, the reply to the OPEN contains an OPEN delegation structure that specifies the following:

进行开放式委派时,对开放式委派的答复包含一个开放式委派结构,该结构指定以下内容:

o the type of delegation (OPEN_DELEGATE_READ or OPEN_DELEGATE_WRITE).

o 委托的类型(打开\u委托\u读取或打开\u委托\u写入)。

o space limitation information to control flushing of data on close (OPEN_DELEGATE_WRITE delegation only; see Section 10.4.1)

o 用于控制关闭时数据刷新的空间限制信息(仅开放\u委托\u写入委托;参见第10.4.1节)

o an nfsace4 specifying read and write permissions

o 指定读写权限的nfsace4

o a stateid to represent the delegation

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 an 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 the 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 Section 9.7.

o 请求和文件的访问和拒绝位,如第9.7节所述。

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" (see Section 5.9) may make it incorrect to return the actual ACL of the file in the delegation response.

服务器可能返回比文件的实际ACL更严格的nfsace4。这包括指定拒绝所有访问的nfsace4。请注意,一些常见做法,如将传统用户“root”映射到用户“nobody”(参见第5.9节),可能会导致在委派响应中返回文件的实际ACL不正确。

The use of a delegation together with various other forms of caching creates the possibility that no server authentication and authorization 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 and authorization, the client should be sure authentication and authorization 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拒绝每个打开的委托的所有访问。

10.4.1. Open Delegation and Data Caching
10.4.1. 开放委托和数据缓存

An 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 "OPEN_DELEGATE_READ delegation" provides a guarantee that no OPEN for OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_BOTH, and thus no write,

开放式委派允许消除与打开和关闭文件相关的大部分消息开销。开放委派生效时的开放委派不需要向服务器发送验证消息。“OPEN_DELEGATE_READ delegation”的持续持久性保证了OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_两者均不开放,因此不会写入,

has occurred. Similarly, when closing a file opened for OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_BOTH and if an OPEN_DELEGATE_WRITE delegation is in effect, the data written does not have to be written 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.

已经发生了。类似地,当关闭为OPEN4_共享_访问_写入/OPEN4_共享_访问_两者打开的文件时,如果打开的_委托_写入委托有效,则在调用打开的委托之前,写入的数据不必写入服务器。开放委托的持续持久性保证了另一个客户机没有进行任何开放操作,因此也没有读写操作。

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. Although a client SHOULD NOT use special stateids when an open exists, delegation handling on the server can use the client ID associated with the current session to determine if the operation has been done by the holder of the delegation (in which case, no recall is necessary) or by another client (in which case, the delegation must be recalled and I/O not proceed until the delegation is recalled or revoked).

出于开放式委托的目的,在没有开放式委托的情况下进行的读写操作被视为相应类型的开放式委托的功能等价物。尽管当存在打开时,客户端不应使用特殊的StateID,但服务器上的委派处理可以使用与当前会话关联的客户端ID来确定该操作是由委派的持有者完成的(在这种情况下,不需要回调)还是由另一个客户端完成的(在这种情况下,必须撤回委托,在撤回或撤销委托之前,I/O不得进行)。

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 file system space for the data has been exceeded (i.e., the server returns NFS4ERR_NOSPC or NFS4ERR_DQUOT). This accounting includes quotas. The introduction of delegations requires that an alternative method be in place for the same type of communication to occur between client and server.

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 file system space for the data has been exceeded (i.e., the server returns NFS4ERR_NOSPC or NFS4ERR_DQUOT). This accounting includes quotas. The introduction of delegations requires that an alternative method be in place for the same type of communication to occur between client and server.translate error, please retry

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 write modified data to the server of a size equal to that provided in the original delegation. The server must make this assurance for all outstanding delegations. Therefore, the server must be careful in its management of available space for new or modified data, taking into account available file system space and any applicable quotas. The server can recall delegations as a result of managing the available file system space. The client should abide by the server's state space limits for delegations. If the client exceeds the stated limits for the delegation, the server's behavior is undefined.

在委托响应中,服务器提供文件大小的限制或修改的块数和关联的块大小。服务器必须确保客户端能够将修改后的数据写入服务器,其大小等于原始委派中提供的数据大小。服务器必须为所有未完成的委派做出此保证。因此,服务器在管理新数据或修改数据的可用空间时必须谨慎,同时考虑可用文件系统空间和任何适用的配额。管理可用文件系统空间后,服务器可以调用委派。客户机应该遵守服务器的状态空间限制。如果客户端超过了指定的委托限制,则服务器的行为未定义。

Based on server conditions, quotas, or available file system space, the server may grant OPEN_DELEGATE_WRITE 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.

根据服务器条件、配额或可用的文件系统空间,服务器可以授予具有非常严格的空间限制的OPEN_DELEGATE_WRITE委派。这些限制的定义方式可能总是强制在关闭时将修改后的数据刷新到服务器。

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.

关于身份验证,在关闭后将修改的数据刷新到服务器可能会有问题。例如,应用程序的用户可能已注销客户端,并且未过期的身份验证凭据可能不存在。在这种情况下,客户端可能需要特别小心,以确保本地未过期的凭据实际上可用。这可以通过跟踪凭据的过期时间并在其过期之前很好地刷新数据来实现,或者通过制作凭据的私有副本来确保其在需要时的可用性。

10.4.2. Open Delegation and File Locks
10.4.2. 打开委托和文件锁

When a client holds an OPEN_DELEGATE_WRITE delegation, lock operations are performed locally. This includes those required for mandatory byte-range 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.

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

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

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

10.4.3. Handling of CB_GETATTR
10.4.3. CB_GETATTR的处理

The server needs to employ special handling for a GETATTR where the target is a file that has an OPEN_DELEGATE_WRITE delegation in effect. The reason for this is that the client holding the OPEN_DELEGATE_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 OPEN_DELEGATE_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进行特殊处理,其中目标是一个有效的OPEN_DELEGATE_WRITE委托的文件。这是因为持有OPEN_DELEGATE_WRITE委托的客户端可能修改了数据,服务器需要将此更改反映到提交GETATTR的第二个客户端。因此,需要询问持有OPEN_DELEGATE_WRITE委托的客户机。服务器将使用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 an OPEN_DELEGATE_WRITE delegation:

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

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 that 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 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 in network order when sending it to the server. For this reason, change is defined as an unsigned integer rather than an opaque array of bytes.

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

For the server, the following steps will be taken when providing an OPEN_DELEGATE_WRITE delegation:

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

o Upon providing an OPEN_DELEGATE_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 在提供OPEN_DELEGATE_WRITE委派后,服务器将在用于记录委派的数据结构中缓存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;
           update sc, time_modify, time_metadata into file's metadata;
       }
        
       if (modified) {
           sc = sc + 1;
           time_modify = time_metadata = current_time;
           update sc, time_modify, time_metadata into file's metadata;
       }
        

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

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

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.

如果文件属性大小不同于服务器的当前值,则服务器将此视为修改,而不管通过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,因此服务器可以简单地调用委托以避免使用它。

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

The following events necessitate recall of an OPEN delegation:

以下事件需要召回公开代表团:

o potentially conflicting OPEN request (or a READ or WRITE operation done with a special stateid)

o 潜在冲突的打开请求(或使用特殊stateid执行的读或写操作)

o SETATTR sent by another client

o 由另一个客户端发送的SETATTR

o REMOVE request for the file

o 删除对该文件的请求

o RENAME request for the file as either the 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's file system. If that file system denies such RENAMEs when a file is open, the recall must be performed to determine whether the file in question is, in fact, open.

对指向文件的路径中的目录进行重命名是否会导致调用打开的委托,这取决于服务器文件系统的语义。如果文件系统在文件打开时拒绝此类重命名,则必须执行回调以确定所涉及的文件实际上是否已打开。

In addition to the situations above, the server may choose to recall OPEN delegations at any time if resource constraints make it advisable to do so. Clients should always be prepared for the possibility of recall.

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

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 no 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 Section 18.16, which describes the OPEN operation, for details.)

o 如果文件在客户端具有其他打开引用,则必须将打开操作发送到服务器。服务器将提供适当的stateid供客户端后续使用,因为委托stateid将不再有效。这些打开的请求使用claim_DELEGATE_CUR的claim类型完成。这将允许呈现委托stateid,以便客户机可以建立适当的权限来执行OPEN。(有关详细信息,请参见第18.16节,其中描述了打开操作。)

o If there are granted byte-range locks, the corresponding LOCK operations need to be performed. This applies to the OPEN_DELEGATE_WRITE delegation case only.

o 如果已授予字节范围锁,则需要执行相应的锁操作。这仅适用于OPEN_DELEGATE_WRITE委派案例。

o For an OPEN_DELEGATE_WRITE delegation, if at the time of recall the file is not open for OPEN4_SHARE_ACCESS_WRITE/ OPEN4_SHARE_ACCESS_BOTH, 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 对于OPEN_DELEGATE_WRITE delegation,如果在调用时文件未打开以供OPEN4_SHARE_ACCESS_WRITE/OPEN4_SHARE_ACCESS_两者使用,则必须将文件的所有修改数据刷新到服务器。如果委托不存在,客户机将在关闭操作之前完成此数据刷新。

o For an OPEN_DELEGATE_WRITE 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 对于在调用时文件仍处于打开状态的OPEN_DELEGATE_WRITE delegation,需要将文件的任何修改数据刷新到服务器。

o With the OPEN_DELEGATE_WRITE 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

o 在OPEN_DELEGATE_WRITE委派就绪的情况下,文件可能在委派期间被截断。例如,截断可能是由于

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.

未选中打开,大小属性值为零。因此,如果发生了文件截断,并且此操作尚未传播到服务器,则必须在将任何修改的数据写入服务器之前进行截断。

In the case of OPEN_DELEGATE_WRITE delegation, byte-range locking imposes some additional requirements. To precisely maintain the associated invariant, it is required to flush any modified data in any byte-range for which a WRITE_LT lock was released while the OPEN_DELEGATE_WRITE delegation was in effect. However, because the OPEN_DELEGATE_WRITE 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_LT lock has been released while the OPEN_DELEGATE_WRITE delegation was in effect.

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

An implementation need not wait until delegation recall (or the decision 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. An exception is when the client has no more internal opens of the file. In this case, sending a CLOSE is useful because it reduces resource utilization on the client and server. 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.

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

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

A client may fail to respond to a recall for various reasons, such as a failure of the backchannel from server to the client. The client may be unaware of a failure in the backchannel. 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 an OPEN_DELEGATE_WRITE delegation.

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

Status bits returned by SEQUENCE operations help to provide an alternate way of informing the client of issues regarding the status of the backchannel and of recalled delegations. When the backchannel is not available, the server returns the status bit SEQ4_STATUS_CB_PATH_DOWN on SEQUENCE operations. The client can

序列操作返回的状态位有助于提供另一种方式,向客户机通知有关反向通道状态和召回委托的问题。当反向通道不可用时,服务器返回序列操作的状态位SEQ4_status_CB_PATH_DOWN。客户可以

react by attempting to re-establish the backchannel and by returning recallable objects if a backchannel cannot be successfully re-established.

尝试重新建立反向通道,如果无法成功重新建立反向通道,则返回可重新调用的对象。

Whether the backchannel is functioning or not, it may be that the recalled delegation is not returned. Note that the client's lease might still be renewed, even though the recalled delegation is not returned. In this situation, servers SHOULD revoke delegations that are not returned in a period of time equal to the lease period. This period of time should allow the client time to note the backchannel-down status and re-establish the backchannel.

无论反向通道是否正常工作,都可能是召回的委托未返回。请注意,客户的租约可能仍会续签,即使收回的委托书没有返回。在这种情况下,服务器应该撤销在与租赁期相等的时间段内未返回的委托。这段时间应允许客户端有时间记录反向通道关闭状态并重新建立反向通道。

When delegations are revoked, the server will return with the SEQ4_STATUS_RECALLABLE_STATE_REVOKED status bit set on subsequent SEQUENCE operations. The client should note this and then use TEST_STATEID to find which delegations have been revoked.

撤销委托时,服务器将返回在后续序列操作中设置的SEQ4_STATUS_RECALLABLE_STATE_Reversed STATUS位。客户机应注意这一点,然后使用TEST_STATEID查找哪些委托已被撤销。

10.4.6. Delegation Revocation
10.4.6. 委托撤销

At the point a delegation is revoked, if there are associated opens on the client, these opens may or may not be revoked. If no byte-range lock or open is granted that is inconsistent with the existing open, the stateid for the open may remain valid and be disconnected from the revoked delegation, just as would be the case if the delegation were returned.

在撤销委托时,如果客户端上存在关联的打开,则这些打开可能会被撤销,也可能不会被撤销。如果未授予与现有open不一致的字节范围锁定或open,则open的stateid可能仍然有效,并与已撤销的委派断开连接,就像委派被返回一样。

For example, if an OPEN for OPEN4_SHARE_ACCESS_BOTH with a deny of OPEN4_SHARE_DENY_NONE is associated with the delegation, granting of another such OPEN to a different client will revoke the delegation but need not revoke the OPEN, since the two OPENs are consistent with each other. On the other hand, if an OPEN denying write access is granted, then the existing OPEN must be revoked.

例如,如果拒绝OPEN4_SHARE_ACCESS_且拒绝OPEN4_SHARE_deny_NONE的OPEN For OPEN4_SHARE_ACCESS_与委托关联,则将另一个此类OPEN授予不同的客户端将撤销委托,但无需撤销该OPEN,因为这两个OPEN彼此一致。另一方面,如果授予开放式拒绝写入访问权限,则必须撤销现有的开放式。

When opens and/or locks are revoked, the applications holding these opens or locks 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 Section 10.5.1 for additional details.

如果在撤销委派时不存在文件的打开,则不需要通知撤销。但是,如果文件的客户端存在修改的数据,则应通知应用程序的用户。不幸的是,由于客户端可能不存在活动应用程序,因此可能无法通知用户。更多详情见第10.5.1节。

10.4.7. Delegations via WANT_DELEGATION
10.4.7. 通过WANT_代表团的代表团

In addition to providing delegations as part of the reply to OPEN operations, servers MAY provide delegations separate from open, via the OPTIONAL WANT_DELEGATION operation. This allows delegations to be obtained in advance of an OPEN that might benefit from them, for objects that are not a valid target of OPEN, or to deal with cases in which a delegation has been recalled and the client wants to make an attempt to re-establish it if the absence of use by other clients allows that.

除了作为开放操作回复的一部分提供委托外,服务器还可以通过可选的WANT_委托操作提供与开放操作分开的委托。这允许在可能受益于委托的开放之前获得委托,对于不是开放的有效目标的对象,或者处理委托已被撤回且客户希望尝试重新建立委托的情况(如果其他客户未使用该委托)。

The WANT_DELEGATION operation may be performed on any type of file object other than a directory.

WANT_委派操作可以在目录以外的任何类型的文件对象上执行。

When a delegation is obtained using WANT_DELEGATION, any open files for the same filehandle held by that client are to be treated as subordinate to the delegation, just as if they had been created using an OPEN of type CLAIM_DELEGATE_CUR. They are otherwise unchanged as to seqid, access and deny modes, and the relationship with byte-range locks. Similarly, because existing byte-range locks are subordinate to an open, those byte-range locks also become indirectly subordinate to that new delegation.

当使用WANT_delegation获得委托时,该客户机持有的同一文件句柄的任何打开文件都将被视为委托的从属文件,就像它们是使用CLAIM_DELEGATE_CUR类型的打开文件创建的一样。它们在seqid、访问和拒绝模式以及与字节范围锁的关系方面没有改变。类似地,因为现有的字节范围锁从属于打开的,所以这些字节范围锁也间接地从属于新的委托。

The WANT_DELEGATION operation provides for delivery of delegations via callbacks, when the delegations are not immediately available. When a requested delegation is available, it is delivered to the client via a CB_PUSH_DELEG operation. When this happens, open files for the same filehandle become subordinate to the new delegation at the point at which the delegation is delivered, just as if they had been created using an OPEN of type CLAIM_DELEGATE_CUR. Similarly, this occurs for existing byte-range locks subordinate to an open.

WANT_委派操作提供在委派不立即可用时通过回调传递委派。当请求的委托可用时,它通过CB_PUSH_DELEG操作传递给客户机。当发生这种情况时,同一文件句柄的打开文件在传递委托时将从属于新委托,就像它们是使用CLAIM\u DELEGATE\u CUR类型的打开文件创建的一样。类似地,对于从属于open的现有字节范围锁,也会发生这种情况。

10.5. Data Caching and Revocation
10.5. 数据缓存和撤销

When locks and delegations are revoked, the assumptions upon which successful caching depends are no longer guaranteed. For any locks or share reservations that have been revoked, the corresponding state-owner needs to be notified. This notification includes applications with a file open that has a corresponding delegation that 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 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 byte-range lock after the revocation of the byte-range 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 state-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 here is that an invariant on which an application depends 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弹出窗口)可能是合适的。

10.5.1. Revocation Recovery for Write Open Delegation
10.5.1. 写开放委派的吊销恢复

Revocation recovery for an OPEN_DELEGATE_WRITE delegation poses the special issue of modified data in the client cache while the file is not open. In this situation, any client that does not flush modified data to the server on each close must ensure that the user receives appropriate notification of the failure as a result of the revocation. Since such situations may require human action to correct problems, notification schemes in which the appropriate user or administrator is notified may be necessary. Logging and console messages are typical examples.

打开的_委托_写入委托的吊销恢复会在文件未打开时引起客户端缓存中修改数据的特殊问题。在这种情况下,每次关闭时未将修改后的数据刷新到服务器的任何客户端都必须确保用户收到由于撤销而导致的故障的适当通知。由于此类情况可能需要人为措施来纠正问题,因此可能需要通知相应用户或管理员的通知方案。日志和控制台消息是典型的例子。

If there is modified data on the client, it must not be flushed normally to the server. A client may attempt to provide a copy of the file data as modified during the delegation under a different name in the file system namespace 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 the file in question, such a saved copy of the client's view of the file may be of particular value for recovery. In another case, recovery using a copy of the file based partially on the client's cached data and partially on the server's copy as modified by other clients will be anything but straightforward, so clients may avoid saving file contents in these situations or specially mark the results 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 file system. 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 file system.

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

10.6. Attribute Caching
10.6. 属性缓存

This section pertains to the caching of a file's attributes on a client when that client does not hold a delegation on the file.

本节涉及在客户机上缓存文件属性,前提是该客户机没有对文件进行委托。

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 (as well as the directory's contents) are to be cached on the same basis as any other pathnames.

本节中讨论的属性不包括命名属性。单个命名属性类似于文件,需要像处理普通文件的数据缓存一样处理这些属性的数据缓存。类似地,来自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 should not be 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 reaction 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 another client.

属性的本地缓存的结果是,在单个客户端上维护的属性缓存将不一致。在服务器上按一个顺序所做的更改可能在一个客户端上以不同的顺序显示,在另一个客户端上以第三个顺序显示。

The typical file system application programming interfaces do not provide means to atomically modify or interrogate attributes for multiple files at the same time. The following rules provide an environment where the potential incoherencies 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 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 [18]. 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.

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

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 the client either would eventually have to write the access time to the server with bad performance effects or 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

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

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.

“始终”是指服务器满足的最后一次读取文件的时间。这样,客户端将倾向于只看到随时间推移的时间访问更改。

10.7. Data and Metadata Caching and Memory Mapped Files
10.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 of whether the file is local or is accessed 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 or not its cache is stale. 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 an OPEN_DELEGATE_WRITE delegation, the same set of issues as discussed in the previous two bullet points apply. So, when a server does a CB_GETATTR to a file that the client has modified in its cache, the reply 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

o 如果有另一个客户机正在映射该文件,并且该客户机持有OPEN_DELEGATE_WRITE委托,那么前面两个要点中讨论的问题集同样适用。因此,当服务器对客户端在其缓存中修改的文件执行CB_GETATTR时,CB_GETATTR的回复不一定准确。如前所述,客户的义务是报告自

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.

已授予委派,而不是在连续的CB_GETATTR调用之间是否再次修改委派,服务器必须假定客户端在缓存中修改的任何文件在连续的CB_GETATTR调用之间再次修改。根据客户机内存管理系统的性质,这种弱义务可能是不可能的。每当文件被内存映射时,客户端可能会在CB_GETATTR中返回过时信息。

o The mixture of memory mapping and byte-range locking on the same file is problematic. Consider the following scenario, where a page size on each client is 8192 bytes.

o 在同一个文件上混合使用内存映射和字节范围锁定是有问题的。考虑下面的场景,其中每个客户机上的页面大小是8192字节。

* Client A memory maps the first page (8192 bytes) of file X.

* 客户端A内存映射文件X的第一页(8192字节)。

* Client B memory maps the first page (8192 bytes) of file X.

* 客户端B内存映射文件X的第一页(8192字节)。

* Client A WRITE_LT locks the first 4096 bytes.

* 客户端A写入锁定前4096个字节。

* Client B WRITE_LT locks the second 4096 bytes.

* 客户端B写入锁定第二个4096字节。

* Client A, via a STORE instruction, modifies part of its locked byte-range.

* 客户机A通过存储指令修改其锁定字节范围的一部分。

* Simultaneous to client A, client B executes a STORE on part of its locked byte-range.

* 与客户端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 byte-ranges has been modified. So it is not possible for each client to do the right thing, which is to write to the server only 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 execute the STORE instructions, the resulting page faults require a byte-range lock on the entire page. Each client then tries to extend their locked range to the entire page, which results in a deadlock. Communicating the NFS4ERR_DEADLOCK error to a STORE instruction is difficult at best.

此外,如果对文件启用了强制锁定,则会出现另一个问题。当客户端A和B执行存储指令时,产生的页面错误需要在整个页面上锁定字节范围。然后,每个客户机尝试将其锁定范围扩展到整个页面,从而导致死锁。将NFS4ERR_死锁错误传送到存储指令充其量是困难的。

If a client is locking the entire memory-mapped file, there is no problem with advisory or mandatory byte-range locking, at least until the client unlocks a byte-range in the middle of the file.

如果客户端锁定整个内存映射文件,则至少在客户端在文件中间解锁字节范围之前,咨询或强制字节范围锁定是没有问题的。

Given the above issues, the following are permitted:

鉴于上述问题,允许以下情况:

o Clients and servers MAY deny memory mapping a file for which they know there are byte-range locks.

o 客户端和服务器可能会拒绝内存映射他们知道有字节范围锁的文件。

o Clients and servers MAY deny a byte-range lock on a file they know is memory-mapped.

o 客户端和服务器可能会拒绝他们知道是内存映射的文件上的字节范围锁。

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

o 客户端可能会拒绝内存映射它知道需要强制锁定I/O的文件。如果在打开和映射文件后启用强制锁定,客户端可能会拒绝应用程序对其映射文件的进一步访问。

10.8. Name and Directory Caching without Directory Delegations
10.8. 不带目录委派的名称和目录缓存

The NFSv4.1 directory delegation facility (described in Section 10.9 below) is OPTIONAL for servers to implement. Even where it is implemented, it may not always be functional because of resource availability issues or other constraints. Thus, it is important to understand how name and directory caching are done in the absence of directory delegations. These topics are discussed in the next two subsections.

NFSv4.1目录委派功能(如下文第10.9节所述)对于服务器来说是可选的。即使在实现它的地方,由于资源可用性问题或其他限制,它也可能不总是起作用。因此,了解在没有目录委托的情况下如何进行名称和目录缓存是很重要的。下面两小节将讨论这些主题。

10.8.1. Name Caching
10.8.1. 名称高速缓存

The results of LOOKUP and READDIR operations may be cached to avoid the cost of subsequent LOOKUP operations. Just as in the case of attribute caching, inconsistencies may arise among the various client caches. To mitigate the effects of these inconsistencies and given the context of typical file system APIs, an upper time boundary is maintained for 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

当客户端对给定目录进行更改时,它需要确定是否有其他客户端对该目录进行了更改。它通过使用为操作返回的关联change_info4值中目录操作前后报告的change属性来完成此操作。服务器能够与客户机通信,以确定是否以原子方式提供了与目录操作相关的更改信息4数据。如果改变

values are provided atomically, the client has a basis for determining, given proper care, whether other clients are modifying the directory in question.

值是以原子方式提供的,如果给予适当的注意,客户机有一个确定其他客户机是否正在修改相关目录的基础。

The simplest way to enable the client to make this determination is for the client to serialize all changes made to a specific directory. When this is done, and the server provides before and after values of the change attribute atomically, the client can simply compare the after value of the change attribute from one operation on a directory with the before value on the subsequent operation modifying that directory. When these are equal, the client is assured that no other client is modifying the directory in question.

使客户端能够进行此确定的最简单方法是,客户端序列化对特定目录所做的所有更改。完成此操作后,服务器以原子方式提供change属性的before和after值,客户端可以简单地将目录上一个操作的change属性的after值与修改该目录的后续操作的before值进行比较。当这些值相等时,客户机将确保没有其他客户机正在修改所讨论的目录。

When such serialization is not used, and there may be multiple simultaneous outstanding operations modifying a single directory sent from a single client, making this sort of determination can be more complicated. If two such operations complete in a different order than they were actually performed, that might give an appearance consistent with modification being made by another client. Where this appears to happen, the client needs to await the completion of all such modifications that were started previously, to see if the outstanding before and after change numbers can be sorted into a chain such that the before value of one change number matches the after value of a previous one, in a chain consistent with this client being the only one modifying the directory.

如果不使用这种序列化,并且可能有多个同时执行的未完成操作修改从单个客户机发送的单个目录,则进行这种确定可能会更加复杂。如果两个这样的操作以与实际执行顺序不同的顺序完成,则可能会出现与另一个客户端所做修改一致的外观。如果出现这种情况,客户需要等待之前开始的所有此类修改完成,以查看是否可以将未完成的变更前和变更后编号排序到一个链中,从而使一个变更编号的前值与前一个变更编号的后值相匹配,在与此客户端一致的链中,此客户端是唯一修改目录的客户端。

In either of these cases, the client is able to determine whether the directory is being modified by another client. 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 can be extended. The post-operation change value needs to be saved as the basis for future change_info4 comparisons.

在这两种情况下,客户机都能够确定目录是否正在被其他客户机修改。如果比较表明目录已由另一个客户端更新,则与修改后的目录关联的名称缓存将从客户端中清除。如果比较表明没有修改,则可以在客户端上更新名称缓存以反映目录操作,并且可以延长相关超时。需要保存操作后更改值,作为将来更改比较的基础。

As demonstrated by the scenario above, name caching requires that the client revalidate name cache data by inspecting the change attribute of a directory at the point when the name cache item was cached. This requires that the server update the change attribute for directories when the contents of the corresponding directory is modified. For a client to use the change_info4 information appropriately and correctly, the server must report the pre- and post-operation change attribute values atomically. When the server is unable to report the before and after values atomically with respect to the directory operation, the server must indicate that

如上面的场景所示,名称缓存要求客户端通过在缓存名称缓存项时检查目录的change属性来重新验证名称缓存数据。这要求服务器在修改相应目录的内容时更新目录的change属性。为了让客户端正确地使用change_info4信息,服务器必须以原子方式报告操作前和操作后的change属性值。当服务器无法以原子方式报告与目录操作相关的before和after值时,服务器必须指示

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.

更改信息4返回值中的事实。当信息未按原子方式报告时,客户端不应假定其他客户端未更改目录。

10.8.2. Directory Caching
10.8.2. 目录缓存

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 file system APIs, the following rules should be followed:

READDIR操作的结果可用于避免后续的READDIR操作。与属性和名称缓存的情况一样,不同的客户端缓存之间可能会出现不一致。为了减轻这些不一致的影响,并考虑到典型文件系统API的上下文,应遵循以下规则:

o Cached READDIR information for a directory that 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 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.9. Directory Delegations
10.9. 名录代表团
10.9.1. Introduction to Directory Delegations
10.9.1. 目录授权简介

Directory caching for the NFSv4.1 protocol, as previously described, is similar to file caching in previous versions. Clients typically cache directory information for a duration determined by the client. At the end of a predefined timeout, the client will query the server to see if the directory has been updated. By caching attributes, clients reduce the number of GETATTR calls made to the server to validate attributes. Furthermore, frequently accessed files and directories, such as the current working directory, have their attributes cached on the client so that some NFS operations can be performed without having to make an RPC call. By caching name and inode information about most recently looked up entries in a Directory Name Lookup Cache (DNLC), clients do not need to send LOOKUP calls to the server every time these files are accessed.

如前所述,NFSv4.1协议的目录缓存与以前版本中的文件缓存类似。客户机通常在客户机确定的持续时间内缓存目录信息。在预定义超时结束时,客户机将查询服务器以查看目录是否已更新。通过缓存属性,客户端减少了为验证属性而对服务器进行的GETATTR调用的数量。此外,频繁访问的文件和目录(如当前工作目录)的属性缓存在客户机上,因此无需进行RPC调用即可执行某些NFS操作。通过在目录名查找缓存(DNLC)中缓存有关最近查找的条目的名称和索引节点信息,客户端不需要在每次访问这些文件时向服务器发送查找调用。

This caching approach works reasonably well at reducing network traffic in many environments. However, it does not address environments where there are numerous queries for files that do not exist. In these cases of "misses", the client sends requests to the server in order to provide reasonable application semantics and promptly detect the creation of new directory entries. Examples of high miss activity are compilation in software development environments. The current behavior of NFS limits its potential scalability and wide-area sharing effectiveness in these types of environments. Other distributed stateful file system architectures such as AFS and DFS have proven that adding state around directory contents can greatly reduce network traffic in high-miss environments.

这种缓存方法在许多环境中都能很好地减少网络流量。但是,它不适用于存在大量对不存在的文件的查询的环境。在这些“未命中”的情况下,客户机向服务器发送请求,以便提供合理的应用程序语义并及时检测新目录项的创建。软件开发环境中的编译就是高失误活动的例子。NFS的当前行为限制了其在这些类型环境中的潜在可扩展性和广域共享效率。其他分布式有状态文件系统体系结构(如AFS和DFS)已经证明,在目录内容周围添加状态可以大大减少高失误环境中的网络流量。

Delegation of directory contents is an OPTIONAL feature of NFSv4.1. Directory delegations provide similar traffic reduction benefits as with file delegations. By allowing clients to cache directory contents (in a read-only fashion) while being notified of changes, the client can avoid making frequent requests to interrogate the contents of slowly-changing directories, reducing network traffic and improving client performance. It can also simplify the task of determining whether other clients are making changes to the directory when the client itself is making many changes to the directory and changes are not serialized.

目录内容的委派是NFSv4.1的可选功能。目录委派提供与文件委派类似的流量减少好处。通过允许客户端在收到更改通知的同时缓存目录内容(以只读方式),客户端可以避免频繁请求查询缓慢更改的目录的内容,从而减少网络流量并提高客户端性能。当客户端本身对目录进行许多更改并且更改未序列化时,它还可以简化确定其他客户端是否对目录进行更改的任务。

Directory delegations allow improved namespace cache consistency to be achieved through delegations and synchronous recalls, in the absence of notifications. In addition, if time-based consistency is

目录委派允许在没有通知的情况下,通过委派和同步回调来实现改进的命名空间缓存一致性。此外,如果基于时间的一致性

sufficient, asynchronous notifications can provide performance benefits for the client, and possibly the server, under some common operating conditions such as slowly-changing and/or very large directories.

在一些常见的操作条件下,如缓慢更改和/或非常大的目录,充分的异步通知可以为客户端(可能还有服务器)提供性能优势。

10.9.2. Directory Delegation Design
10.9.2. 目录委托设计

NFSv4.1 introduces the GET_DIR_DELEGATION (Section 18.39) operation to allow the client to ask for a directory delegation. The delegation covers directory attributes and all entries in the directory. If either of these change, the delegation will be recalled synchronously. The operation causing the recall will have to wait before the recall is complete. Any changes to directory entry attributes will not cause the delegation to be recalled.

NFSv4.1引入了GET_DIR_委派(第18.39节)操作,以允许客户端请求目录委派。委托包括目录属性和目录中的所有条目。如果其中任何一项发生变化,将同步召回委托。导致调用的操作必须等待调用完成。对目录条目属性的任何更改都不会导致撤回委派。

In addition to asking for delegations, a client can also ask for notifications for certain events. These events include changes to the directory's attributes and/or its contents. If a client asks for notification for a certain event, the server will notify the client when that event occurs. This will not result in the delegation being recalled for that client. The notifications are asynchronous and provide a way of avoiding recalls in situations where a directory is changing enough that the pure recall model may not be effective while trying to allow the client to get substantial benefit. In the absence of notifications, once the delegation is recalled the client has to refresh its directory cache; this might not be very efficient for very large directories.

除了请求授权外,客户还可以请求某些事件的通知。这些事件包括对目录属性和/或其内容的更改。如果客户机请求通知某个事件,服务器将在该事件发生时通知客户机。这不会导致为该客户召回委托。通知是异步的,并提供了一种避免在目录发生足够变化的情况下调用的方法,在试图让客户机获得实质性好处时,纯调用模型可能无效。在没有通知的情况下,一旦调用委托,客户端必须刷新其目录缓存;对于非常大的目录,这可能不是非常有效。

The delegation is read-only and the client may not make changes to the directory other than by performing NFSv4.1 operations that modify the directory or the associated file attributes so that the server has knowledge of these changes. In order to keep the client's namespace synchronized with the server, the server will notify the delegation-holding client (assuming it has requested notifications) of the changes made as a result of that client's directory-modifying operations. This is to avoid any need for that client to send subsequent GETATTR or READDIR operations to the server. If a single client is holding the delegation and that client makes any changes to the directory (i.e., the changes are made via operations sent on a session associated with the client ID holding the delegation), the delegation will not be recalled. Multiple clients may hold a delegation on the same directory, but if any such client modifies the directory, the server MUST recall the delegation from the other clients, unless those clients have made provisions to be notified of that sort of modification.

委托是只读的,客户端只能通过执行NFSv4.1操作来修改目录或相关文件属性,以便服务器知道这些更改,才能对目录进行更改。为了使客户机的命名空间与服务器保持同步,服务器将通知委托持有客户机(假设它已请求通知),该客户机的目录修改操作导致的更改。这是为了避免该客户机向服务器发送后续GETATTR或READDIR操作。如果单个客户机持有委托,并且该客户机对目录进行了任何更改(即,通过在与持有委托的客户机ID相关联的会话上发送的操作进行更改),则不会调用该委托。多个客户端可以在同一目录上持有一个委托,但是如果任何这样的客户端修改了目录,服务器必须从其他客户端调用该委托,除非这些客户端已经做出了关于该类修改的通知的规定。

Delegations can be recalled by the server at any time. Normally, the server will recall the delegation when the directory changes in a way that is not covered by the notification, or when the directory changes and notifications have not been requested. If another client removes the directory for which a delegation has been granted, the server will recall the delegation.

服务器可以随时调用委托。通常,当目录以通知未涵盖的方式更改时,或者当目录更改和通知未被请求时,服务器将调用委派。如果另一个客户机删除已授予委派的目录,服务器将调用该委派。

10.9.3. Attributes in Support of Directory Notifications
10.9.3. 支持目录通知的属性

See Section 5.11 for a description of the attributes associated with directory notifications.

有关目录通知相关属性的说明,请参见第5.11节。

10.9.4. Directory Delegation Recall
10.9.4. 目录委派召回

The server will recall the directory delegation by sending a callback to the client. It will use the same callback procedure as used for recalling file delegations. The server will recall the delegation when the directory changes in a way that is not covered by the notification. However, the server need not recall the delegation if attributes of an entry within the directory change.

服务器将通过向客户端发送回调来调用目录委派。它将使用与调用文件委托相同的回调过程。当目录以通知未涵盖的方式更改时,服务器将调用委派。但是,如果目录中某个条目的属性发生更改,服务器无需调用委派。

If the server notices that handing out a delegation for a directory is causing too many notifications to be sent out, it may decide to not hand out delegations for that directory and/or recall those already granted. If a client tries to remove the directory for which a delegation has been granted, the server will recall all associated delegations.

如果服务器注意到为某个目录分发委派会导致发送太多通知,它可能会决定不为该目录分发委派和/或收回已授予的委派。如果客户机试图删除已授予委派的目录,服务器将调用所有关联的委派。

The implementation sections for a number of operations describe situations in which notification or delegation recall would be required under some common circumstances. In this regard, a similar set of caveats to those listed in Section 10.2 apply.

许多操作的实施章节描述了在某些常见情况下需要通知或授权召回的情况。在这方面,第10.2节中列出的一组类似的警告适用。

o For CREATE, see Section 18.4.4.

o 有关创建,请参见第18.4.4节。

o For LINK, see Section 18.9.4.

o 有关链接,请参见第18.9.4节。

o For OPEN, see Section 18.16.4.

o 关于开放式,见第18.16.4节。

o For REMOVE, see Section 18.25.4.

o 有关拆卸,请参见第18.25.4节。

o For RENAME, see Section 18.26.4.

o 有关重命名,请参见第18.26.4节。

o For SETATTR, see Section 18.30.4.

o 有关SETATTR,请参见第18.30.4节。

10.9.5. Directory Delegation Recovery
10.9.5. 目录委派恢复

Recovery from client or server restart for state on regular files has two main goals: avoiding the necessity of breaking application guarantees with respect to locked files and delivery of updates cached at the client. Neither of these goals applies to directories protected by OPEN_DELEGATE_READ delegations and notifications. Thus, no provision is made for reclaiming directory delegations in the event of client or server restart. The client can simply establish a directory delegation in the same fashion as was done initially.

从客户端或服务器重新启动恢复常规文件的状态有两个主要目标:避免破坏应用程序对锁定文件的保证,以及在客户端缓存更新的交付。这些目标都不适用于受OPEN_DELEGATE_READ委派和通知保护的目录。因此,没有为在客户端或服务器重新启动时回收目录委派做任何准备。客户机可以简单地以与最初相同的方式建立目录委派。

11. Multi-Server Namespace
11. 多服务器名称空间

NFSv4.1 supports attributes that allow a namespace to extend beyond the boundaries of a single server. It is RECOMMENDED that clients and servers support construction of such multi-server namespaces. Use of such multi-server namespaces is OPTIONAL, however, and for many purposes, single-server namespaces are perfectly acceptable. Use of multi-server namespaces can provide many advantages, however, by separating a file system's logical position in a namespace from the (possibly changing) logistical and administrative considerations that result in particular file systems being located on particular servers.

NFSv4.1支持允许命名空间扩展到单个服务器边界之外的属性。建议客户端和服务器支持这种多服务器名称空间的构造。但是,使用这样的多服务器名称空间是可选的,对于许多目的,单服务器名称空间是完全可以接受的。但是,通过将文件系统在名称空间中的逻辑位置与导致特定文件系统位于特定服务器上的(可能不断变化的)后勤和管理考虑因素分开,使用多服务器名称空间可以提供许多优势。

11.1. Location Attributes
11.1. 位置属性

NFSv4.1 contains RECOMMENDED attributes that allow file systems on one server to be associated with one or more instances of that file system on other servers. These attributes specify such file system instances by specifying a server address target (either as a DNS name representing one or more IP addresses or as a literal IP address) together with the path of that file system within the associated single-server namespace.

NFSv4.1包含建议的属性,允许一台服务器上的文件系统与其他服务器上该文件系统的一个或多个实例相关联。这些属性通过指定服务器地址目标(作为表示一个或多个IP地址的DNS名称或文字IP地址)以及相关单个服务器命名空间中该文件系统的路径来指定此类文件系统实例。

The fs_locations_info RECOMMENDED attribute allows specification of one or more file system instance locations where the data corresponding to a given file system may be found. This attribute provides to the client, in addition to information about file system instance locations, significant information about the various file system instance choices (e.g., priority for use, writability, currency, etc.). It also includes information to help the client efficiently effect as seamless a transition as possible among multiple file system instances, when and if that should be necessary.

fs_locations_info RECOMMENDED属性允许指定一个或多个文件系统实例位置,其中可以找到与给定文件系统对应的数据。除了有关文件系统实例位置的信息外,此属性还向客户端提供有关各种文件系统实例选择的重要信息(例如,使用优先级、可写性、货币等)。它还包括帮助客户机在必要时尽可能无缝地在多个文件系统实例之间进行转换的信息。

The fs_locations RECOMMENDED attribute is inherited from NFSv4.0 and only allows specification of the file system locations where the data corresponding to a given file system may be found. Servers SHOULD make this attribute available whenever fs_locations_info is supported, but client use of fs_locations_info is to be preferred.

fs_locations RECOMMENDED属性继承自NFSv4.0,仅允许指定与给定文件系统对应的数据所在的文件系统位置。只要支持fs_locations_info,服务器就应该使此属性可用,但客户端最好使用fs_locations_info。

11.2. File System Presence or Absence
11.2. 文件系统存在或不存在

A given location in an NFSv4.1 namespace (typically but not necessarily a multi-server namespace) can have a number of file system instance locations associated with it (via the fs_locations or fs_locations_info attribute). There may also be an actual current file system at that location, accessible via normal namespace operations (e.g., LOOKUP). In this case, the file system is said to be "present" at that position in the namespace, and clients will typically use it, reserving use of additional locations specified via the location-related attributes to situations in which the principal location is no longer available.

NFSv4.1命名空间(通常但不一定是多服务器命名空间)中的给定位置可以有多个与之关联的文件系统实例位置(通过fs\u locations或fs\u locations\u info属性)。在该位置还可能有一个实际的当前文件系统,可以通过正常的名称空间操作(例如,查找)进行访问。在这种情况下,文件系统被称为在名称空间中的该位置“存在”,客户端通常会使用它,在主位置不再可用的情况下保留使用通过位置相关属性指定的其他位置。

When there is no actual file system at the namespace location in question, the file system is said to be "absent". An absent file system contains no files or directories other than the root. Any reference to it, except to access a small set of attributes useful in determining alternate locations, will result in an error, NFS4ERR_MOVED. Note that if the server ever returns the error NFS4ERR_MOVED, it MUST support the fs_locations attribute and SHOULD support the fs_locations_info and fs_status attributes.

当所讨论的名称空间位置没有实际的文件系统时,文件系统被称为“缺席”。缺少的文件系统不包含根目录以外的文件或目录。对它的任何引用,除了访问在确定备用位置时有用的一小组属性外,都将导致错误NFS4ERR_MOVED。请注意,如果服务器返回错误NFS4ERR_MOVED,它必须支持fs_locations属性,并且应该支持fs_locations_info和fs_status属性。

While the error name suggests that we have a case of a file system that once was present, and has only become absent later, this is only one possibility. A position in the namespace may be permanently absent with the set of file system(s) designated by the location attributes being the only realization. The name NFS4ERR_MOVED reflects an earlier, more limited conception of its function, but this error will be returned whenever the referenced file system is absent, whether it has moved or not.

虽然错误名称表明我们有一个文件系统的案例,它曾经存在,但后来才消失,但这只是一种可能性。名称空间中的位置可能永久不存在,位置属性指定的文件系统集是唯一的实现。名称NFS4ERR_MOVED反映了对其功能的更早、更有限的概念,但无论引用的文件系统是否已移动,只要不存在,都会返回此错误。

Except in the case of GETATTR-type operations (to be discussed later), when the current filehandle at the start of an operation is within an absent file system, that operation is not performed and the error NFS4ERR_MOVED is returned, to indicate that the file system is absent on the current server.

除GETATTR类型的操作(稍后讨论)外,当操作开始时的当前文件句柄位于不存在的文件系统内时,不会执行该操作,并返回错误NFS4ERR_MOVED,以指示当前服务器上不存在该文件系统。

Because a GETFH cannot succeed if the current filehandle is within an absent file system, filehandles within an absent file system cannot be transferred to the client. When a client does have filehandles

由于如果当前文件句柄位于缺少的文件系统中,则GETFH无法成功,因此无法将缺少的文件系统中的文件句柄传输到客户端。当客户端确实有文件句柄时

within an absent file system, it is the result of obtaining them when the file system was present, and having the file system become absent subsequently.

在一个不存在的文件系统中,它是当文件系统存在时获得它们,然后文件系统随后变得不存在的结果。

It should be noted that because the check for the current filehandle being within an absent file system happens at the start of every operation, operations that change the current filehandle so that it is within an absent file system will not result in an error. This allows such combinations as PUTFH-GETATTR and LOOKUP-GETATTR to be used to get attribute information, particularly location attribute information, as discussed below.

应该注意的是,由于检查当前文件句柄是否在缺少的文件系统中是在每次操作开始时进行的,因此更改当前文件句柄以使其位于缺少的文件系统中的操作不会导致错误。这允许使用PUTFH-GETATTR和LOOKUP-GETATTR等组合来获取属性信息,特别是位置属性信息,如下所述。

The RECOMMENDED file system attribute fs_status can be used to interrogate the present/absent status of a given file system.

建议的文件系统属性fs_status可用于查询给定文件系统的当前/不存在状态。

11.3. Getting Attributes for an Absent File System
11.3. 获取缺失文件系统的属性

When a file system is absent, most attributes are not available, but it is necessary to allow the client access to the small set of attributes that are available, and most particularly those that give information about the correct current locations for this file system: fs_locations and fs_locations_info.

当文件系统不存在时,大多数属性都不可用,但必须允许客户端访问可用的一小部分属性,尤其是那些提供有关此文件系统的正确当前位置的信息的属性:fs\u位置和fs\u位置\u信息。

11.3.1. GETATTR within an Absent File System
11.3.1. 缺少文件系统中的GETATTR

As mentioned above, an exception is made for GETATTR in that attributes may be obtained for a filehandle within an absent file system. This exception only applies if the attribute mask contains at least one attribute bit that indicates the client is interested in a result regarding an absent file system: fs_locations, fs_locations_info, or fs_status. If none of these attributes is requested, GETATTR will result in an NFS4ERR_MOVED error.

如上所述,GETATTR有一个例外,即可以为缺少的文件系统中的文件句柄获取属性。仅当属性掩码包含至少一个属性位时,此异常才适用,该属性位表示客户端对缺少文件系统的结果感兴趣:fs\U位置、fs\U位置信息或fs\U状态。如果未请求任何这些属性,则GETATTR将导致NFS4ERR_移动错误。

When a GETATTR is done on an absent file system, the set of supported attributes is very limited. Many attributes, including those that are normally REQUIRED, will not be available on an absent file system. In addition to the attributes mentioned above (fs_locations, fs_locations_info, fs_status), the following attributes SHOULD be available on absent file systems. In the case of RECOMMENDED attributes, they should be available at least to the same degree that they are available on present file systems.

在缺少文件系统的情况下执行GETATTR时,支持的属性集非常有限。许多属性(包括通常需要的属性)在缺少的文件系统上不可用。除了上面提到的属性(fs_位置、fs_位置、fs_信息、fs_状态)之外,在缺少的文件系统上还应该提供以下属性。对于推荐的属性,它们的可用程度应至少与当前文件系统上的可用程度相同。

change_policy: This attribute is useful for absent file systems and can be helpful in summarizing to the client when any of the location-related attributes change.

更改策略:此属性对于缺少的文件系统非常有用,并且在任何与位置相关的属性发生更改时有助于向客户端汇总。

fsid: This attribute should be provided so that the client can determine file system boundaries, including, in particular, the boundary between present and absent file systems. This value must be different from any other fsid on the current server and need have no particular relationship to fsids on any particular destination to which the client might be directed.

fsid:应提供此属性,以便客户端可以确定文件系统边界,特别是现有和不存在的文件系统之间的边界。此值必须不同于当前服务器上的任何其他fsid,并且不需要与客户端可能指向的任何特定目标上的fsid具有特定关系。

mounted_on_fileid: For objects at the top of an absent file system, this attribute needs to be available. Since the fileid is within the present parent file system, there should be no need to reference the absent file system to provide this information.

mounted_on_fileid:对于不存在的文件系统顶部的对象,此属性需要可用。由于fileid位于当前父文件系统中,因此不需要引用缺少的文件系统来提供此信息。

Other attributes SHOULD NOT be made available for absent file systems, even when it is possible to provide them. The server should not assume that more information is always better and should avoid gratuitously providing additional information.

对于缺少的文件系统,即使可以提供其他属性,也不应提供这些属性。服务器不应该认为信息越多越好,应该避免无偿提供额外信息。

When a GETATTR operation includes a bit mask for one of the attributes fs_locations, fs_locations_info, or fs_status, but where the bit mask includes attributes that are not supported, GETATTR will not return an error, but will return the mask of the actual attributes supported with the results.

当GETATTR操作包含属性fs\u locations、fs\u locations\u info或fs\u status之一的位掩码,但位掩码包含不受支持的属性时,GETATTR不会返回错误,但会返回结果支持的实际属性的掩码。

Handling of VERIFY/NVERIFY is similar to GETATTR in that if the attribute mask does not include fs_locations, fs_locations_info, or fs_status, the error NFS4ERR_MOVED will result. It differs in that any appearance in the attribute mask of an attribute not supported for an absent file system (and note that this will include some normally REQUIRED attributes) will also cause an NFS4ERR_MOVED result.

VERIFY/NVERIFY的处理与GETATTR类似,因为如果属性掩码不包括fs_位置、fs_位置信息或fs_状态,则会导致错误NFS4ERR_MOVED。它的不同之处在于,属性掩码中不受缺少的文件系统支持的属性的任何外观(请注意,这将包括一些通常需要的属性)也将导致NFS4ERR_移动结果。

11.3.2. READDIR and Absent File Systems
11.3.2. READDIR和缺席文件系统

A READDIR performed when the current filehandle is within an absent file system will result in an NFS4ERR_MOVED error, since, unlike the case of GETATTR, no such exception is made for READDIR.

当当前文件句柄位于不存在的文件系统内时执行的READDIR将导致NFS4ERR_MOVED错误,因为与GETATTR的情况不同,READDIR没有此类异常。

Attributes for an absent file system may be fetched via a READDIR for a directory in a present file system, when that directory contains the root directories of one or more absent file systems. In this case, the handling is as follows:

当当前文件系统中的目录包含一个或多个缺席文件系统的根目录时,缺席文件系统的属性可以通过READDIR获取。在这种情况下,处理如下:

o If the attribute set requested includes one of the attributes fs_locations, fs_locations_info, or fs_status, then fetching of attributes proceeds normally and no NFS4ERR_MOVED indication is returned, even when the rdattr_error attribute is requested.

o 如果请求的属性集包括属性fs_locations、fs_locations_info或fs_status中的一个,则属性的提取正常进行,并且不会返回NFS4ERR_MOVED指示,即使请求rdattr_error属性也是如此。

o If the attribute set requested does not include one of the attributes fs_locations, fs_locations_info, or fs_status, then if the rdattr_error attribute is requested, each directory entry for the root of an absent file system will report NFS4ERR_MOVED as the value of the rdattr_error attribute.

o 如果请求的属性集不包括属性fs_locations、fs_locations_info或fs_status中的一个,则如果请求rdattr_error属性,则缺失文件系统根目录的每个目录项都将报告NFS4ERR_MOVED作为rdattr_error属性的值。

o If the attribute set requested does not include any of the attributes fs_locations, fs_locations_info, fs_status, or rdattr_error, then the occurrence of the root of an absent file system within the directory will result in the READDIR failing with an NFS4ERR_MOVED error.

o 如果请求的属性集不包括任何属性fs_locations、fs_locations\u info、fs_status或rdattr_error,则目录中缺少文件系统的根目录将导致READDIR失败,并出现NFS4ERR_MOVED错误。

o The unavailability of an attribute because of a file system's absence, even one that is ordinarily REQUIRED, does not result in any error indication. The set of attributes returned for the root directory of the absent file system in that case is simply restricted to those actually available.

o 由于文件系统不存在而导致属性不可用,即使是通常需要的属性,也不会导致任何错误指示。在这种情况下,为不存在的文件系统的根目录返回的属性集仅限于那些实际可用的属性。

11.4. Uses of Location Information
11.4. 位置信息的使用

The location-bearing attributes (fs_locations and fs_locations_info), together with the possibility of absent file systems, provide a number of important facilities in providing reliable, manageable, and scalable data access.

位置承载属性(fs_locations和fs_locations_info)以及缺少文件系统的可能性,为提供可靠、可管理和可扩展的数据访问提供了许多重要功能。

When a file system is present, these attributes can provide alternative locations, to be used to access the same data, in the event of server failures, communications problems, or other difficulties that make continued access to the current file system impossible or otherwise impractical. Under some circumstances, multiple alternative locations may be used simultaneously to provide higher-performance access to the file system in question. Provision of such alternate locations is referred to as "replication" although there are cases in which replicated sets of data are not in fact present, and the replicas are instead different paths to the same data.

当存在文件系统时,这些属性可以提供备用位置,以便在出现服务器故障、通信问题或其他导致无法继续访问当前文件系统或无法继续访问当前文件系统的困难时,用于访问相同的数据。在某些情况下,可以同时使用多个备选位置,以提供对相关文件系统的更高性能访问。提供此类备用位置称为“复制”,尽管在某些情况下,复制的数据集实际上并不存在,而副本是指向相同数据的不同路径。

When a file system is present and becomes absent, clients can be given the opportunity to have continued access to their data, at an alternate location. In this case, a continued attempt to use the data in the now-absent file system will result in an NFS4ERR_MOVED error and, at that point, the successor locations (typically only one although multiple choices are possible) can be fetched and used to continue access. Transfer of the file system contents to the new location is referred to as "migration", but it should be kept in mind that there are cases in which this term can be used, like "replication", when there is no actual data migration per se.

当文件系统存在且不存在时,客户机可以有机会在其他位置继续访问其数据。在这种情况下,继续尝试使用现在不存在的文件系统中的数据将导致NFS4ERR_MOVED错误,此时,可以获取后续位置(通常只有一个位置,尽管可能有多个选择)并用于继续访问。将文件系统内容传输到新位置称为“迁移”,但应记住,在某些情况下,在没有实际数据迁移的情况下,可以使用此术语,如“复制”。

Where a file system was not previously present, specification of file system location provides a means by which file systems located on one server can be associated with a namespace defined by another server, thus allowing a general multi-server namespace facility. A designation of such a location, in place of an absent file system, is called a "referral".

当文件系统以前不存在时,文件系统位置规范提供了一种方法,通过这种方法,位于一台服务器上的文件系统可以与另一台服务器定义的名称空间相关联,从而允许使用通用的多服务器名称空间功能。指定这样一个位置来代替缺少的文件系统,称为“参考”。

Because client support for location-related attributes is OPTIONAL, a server may (but is not required to) take action to hide migration and referral events from such clients, by acting as a proxy, for example. The server can determine the presence of client support from the arguments of the EXCHANGE_ID operation (see Section 18.35.3).

由于客户机对位置相关属性的支持是可选的,因此服务器可以(但不需要)通过代理等方式对这些客户机隐藏迁移和引用事件。服务器可以根据EXCHANGE_ID操作的参数确定是否存在客户端支持(请参阅第18.35.3节)。

11.4.1. File System Replication
11.4.1. 文件系统复制

The fs_locations and fs_locations_info attributes provide alternative locations, to be used to access data in place of or in addition to the current file system instance. On first access to a file system, the client should obtain the value of the set of alternate locations by interrogating the fs_locations or fs_locations_info attribute, with the latter being preferred.

fs_locations和fs_locations_info属性提供了替代位置,用于代替当前文件系统实例或在当前文件系统实例之外访问数据。在首次访问文件系统时,客户机应通过询问fs_locations或fs_locations_info属性来获取备用位置集的值,最好是后者。

In the event that server failures, communications problems, or other difficulties make continued access to the current file system impossible or otherwise impractical, the client can use the alternate locations as a way to get continued access to its data. Depending on specific attributes of these alternate locations, as indicated within the fs_locations_info attribute, multiple locations may be used simultaneously, to provide higher performance through the exploitation of multiple paths between client and target file system.

如果服务器故障、通信问题或其他困难导致无法继续访问当前文件系统或无法继续访问当前文件系统,客户机可以使用备用位置作为继续访问其数据的方式。根据这些备用位置的特定属性(如fs_locations_info属性中所示),可以同时使用多个位置,通过利用客户端和目标文件系统之间的多条路径来提供更高的性能。

The alternate locations may be physical replicas of the (typically read-only) file system data, or they may reflect alternate paths to the same server or provide for the use of various forms of server clustering in which multiple servers provide alternate ways of accessing the same physical file system. How these different modes of file system transition are represented within the fs_locations and fs_locations_info attributes and how the client deals with file system transition issues will be discussed in detail below.

备用位置可以是(通常为只读)文件系统数据的物理副本,或者它们可以反映到同一服务器的备用路径,或者提供各种形式的服务器集群的使用,其中多个服务器提供访问同一物理文件系统的备用方式。下面将详细讨论这些不同的文件系统转换模式如何在fs_locations和fs_locations_info属性中表示,以及客户端如何处理文件系统转换问题。

Multiple server addresses, whether they are derived from a single entry with a DNS name representing a set of IP addresses or from multiple entries each with its own server address, may correspond to the same actual server. The fact that two addresses correspond to the same server is shown by a common so_major_id field within the eir_server_owner field returned by EXCHANGE_ID (see Section 18.35.3).

多个服务器地址,无论是从一个具有代表一组IP地址的DNS名称的单个条目中派生出来的,还是从多个具有各自服务器地址的条目中派生出来的,都可能对应于同一个实际服务器。EXCHANGE_id返回的eir_server_owner字段中的一个公共so_major_id字段显示了两个地址对应于同一台服务器的事实(参见第18.35.3节)。

For a detailed discussion of how server address targets interact with the determination of server identity specified by the server owner field, see Section 11.5.

有关服务器地址目标如何与服务器所有者字段指定的服务器标识的确定交互的详细讨论,请参阅第11.5节。

11.4.2. File System Migration
11.4.2. 文件系统迁移

When a file system is present and becomes absent, clients can be given the opportunity to have continued access to their data, at an alternate location, as specified by the fs_locations or fs_locations_info attribute. Typically, a client will be accessing the file system in question, get an NFS4ERR_MOVED error, and then use the fs_locations or fs_locations_info attribute to determine the new location of the data. When fs_locations_info is used, additional information will be available that will define the nature of the client's handling of the transition to a new server.

当文件系统存在且不存在时,客户机可以有机会在fs_locations或fs_locations_info属性指定的备用位置继续访问其数据。通常,客户机将访问有问题的文件系统,获取NFS4ERR_MOVED错误,然后使用fs_locations或fs_locations_info属性来确定数据的新位置。使用fs_locations_info时,将提供其他信息,这些信息将定义客户端处理到新服务器的转换的性质。

Such migration can be helpful in providing load balancing or general resource reallocation. The protocol does not specify how the file system will be moved between servers. It is anticipated that a number of different server-to-server transfer mechanisms might be used with the choice left to the server implementor. The NFSv4.1 protocol specifies the method used to communicate the migration event between client and server.

这种迁移有助于提供负载平衡或一般资源重新分配。该协议未指定文件系统在服务器之间移动的方式。可以预期,在留给服务器实现者选择的情况下,可能会使用许多不同的服务器到服务器传输机制。NFSv4.1协议指定了用于在客户端和服务器之间传递迁移事件的方法。

The new location may be an alternate communication path to the same server or, in the case of various forms of server clustering, another server providing access to the same physical file system. The client's responsibilities in dealing with this transition depend on the specific nature of the new access path as well as how and whether data was in fact migrated. These issues will be discussed in detail below.

新位置可以是到同一服务器的备用通信路径,或者在各种形式的服务器集群的情况下,可以是提供对同一物理文件系统的访问的另一服务器。客户在处理此转换时的责任取决于新访问路径的特定性质以及数据的实际迁移方式和是否迁移。下面将详细讨论这些问题。

When multiple server addresses correspond to the same actual server, as shown by a common value for the so_major_id field of the eir_server_owner field returned by EXCHANGE_ID, the location or locations may designate alternate server addresses in the form of specific server network addresses. These can be used to access the file system in question at those addresses and when it is no longer accessible at the original address.

当多个服务器地址对应于同一个实际服务器时,如EXCHANGE_id返回的eir_server_owner字段的so_major_id字段的公共值所示,一个或多个位置可以以特定服务器网络地址的形式指定备用服务器地址。这些可用于在这些地址访问有问题的文件系统,以及在原始地址无法再访问文件系统时访问文件系统。

Although a single successor location is typical, multiple locations may be provided, together with information that allows priority among the choices to be indicated, via information in the fs_locations_info attribute. Where suitable, clustering mechanisms make it possible to provide multiple identical file systems or paths to them; this allows the client the opportunity to deal with any resource or communications issues that might limit data availability.

尽管单个后续位置是典型的,但是可以通过fs_locations_info属性中的信息提供多个位置,以及允许指示选择中的优先级的信息。在适当的情况下,集群机制可以提供多个相同的文件系统或路径;这使客户端有机会处理可能限制数据可用性的任何资源或通信问题。

When an alternate location is designated as the target for migration, it must designate the same data (with metadata being the same to the degree indicated by the fs_locations_info attribute). Where file systems are writable, a change made on the original file system must be visible on all migration targets. Where a file system is not writable but represents a read-only copy (possibly periodically updated) of a writable file system, similar requirements apply to the propagation of updates. Any change visible in the original file system must already be effected on all migration targets, to avoid any possibility that a client, in effecting a transition to the migration target, will see any reversion in file system state.

当替代位置被指定为迁移目标时,它必须指定相同的数据(元数据的相同程度由fs_locations_info属性指示)。如果文件系统是可写的,则对原始文件系统所做的更改必须在所有迁移目标上可见。如果文件系统不可写,但表示可写文件系统的只读副本(可能定期更新),则类似的要求适用于更新的传播。在原始文件系统中可见的任何更改必须已经在所有迁移目标上生效,以避免客户端在执行到迁移目标的转换时看到文件系统状态的任何恢复。

11.4.3. Referrals
11.4.3. 转介

Referrals provide a way of placing a file system in a location within the namespace essentially without respect to its physical location on a given server. This allows a single server or a set of servers to present a multi-server namespace that encompasses file systems located on multiple servers. Some likely uses of this include establishment of site-wide or organization-wide namespaces, or even knitting such together into a truly global namespace.

引用提供了一种将文件系统放置在命名空间中某个位置的方法,基本上不考虑其在给定服务器上的物理位置。这允许单个服务器或一组服务器呈现包含位于多个服务器上的文件系统的多服务器命名空间。它的一些可能用途包括建立站点范围或组织范围的名称空间,甚至将这些名称空间组合成一个真正的全局名称空间。

Referrals occur when a client determines, upon first referencing a position in the current namespace, that it is part of a new file system and that the file system is absent. When this occurs, typically by receiving the error NFS4ERR_MOVED, the actual location or locations of the file system can be determined by fetching the fs_locations or fs_locations_info attribute.

当客户机在第一次引用当前名称空间中的位置时,确定该位置是新文件系统的一部分并且该文件系统不存在时,就会发生引用。发生这种情况时,通常通过接收错误NFS4ERR_MOVED,可以通过获取fs_locations或fs_locations_info属性来确定文件系统的实际位置。

The locations-related attribute may designate a single file system location or multiple file system locations, to be selected based on the needs of the client. The server, in the fs_locations_info attribute, may specify priorities to be associated with various file system location choices. The server may assign different priorities to different locations as reported to individual clients, in order to adapt to client physical location or to effect load balancing. When both read-only and read-write file systems are present, some of the read-only locations might not be absolutely up-to-date (as they would have to be in the case of replication and migration). Servers may also specify file system locations that include client-substituted variables so that different clients are referred to different file systems (with different data contents) based on client attributes such as CPU architecture.

“位置相关”属性可以指定单个文件系统位置或多个文件系统位置,以根据客户端的需要进行选择。服务器在fs_locations_info属性中可以指定与各种文件系统位置选择关联的优先级。服务器可以将不同的优先级分配给报告给各个客户端的不同位置,以便适应客户端物理位置或实现负载平衡。当同时存在只读和读写文件系统时,某些只读位置可能不是绝对最新的(在复制和迁移的情况下必须是最新的)。服务器还可以指定包含客户机替换变量的文件系统位置,以便根据客户机属性(如CPU体系结构)将不同的客户机引用到不同的文件系统(具有不同的数据内容)。

When the fs_locations_info attribute indicates that there are multiple possible targets listed, the relationships among them may be important to the client in selecting which one to use. The same rules specified in Section 11.4.1 defining the appropriate standards

当fs_locations_info属性指示列出了多个可能的目标时,它们之间的关系对于客户端选择使用哪个目标可能很重要。第11.4.1节中规定的定义适当标准的相同规则

for the data propagation apply to these multiple replicas as well. For example, the client might prefer a writable target on a server that has additional writable replicas to which it subsequently might switch. Note that, as distinguished from the case of replication, there is no need to deal with the case of propagation of updates made by the current client, since the current client has not accessed the file system in question.

对于数据传播,还应将其应用于这些多个副本。例如,客户机可能更喜欢服务器上的可写目标,该服务器具有其他可写副本,随后可能会切换到这些副本。请注意,与复制的情况不同,不需要处理由当前客户端进行的更新传播的情况,因为当前客户端尚未访问相关的文件系统。

Use of multi-server namespaces is enabled by NFSv4.1 but is not required. The use of multi-server namespaces and their scope will depend on the applications used and system administration preferences.

NFSv4.1支持使用多服务器名称空间,但不是必需的。多服务器名称空间的使用及其范围将取决于所使用的应用程序和系统管理首选项。

Multi-server namespaces can be established by a single server providing a large set of referrals to all of the included file systems. Alternatively, a single multi-server namespace may be administratively segmented with separate referral file systems (on separate servers) for each separately administered portion of the namespace. The top-level referral file system or any segment may use replicated referral file systems for higher availability.

多服务器名称空间可以由一台服务器建立,该服务器提供对所有包含的文件系统的大量引用。或者,单个多服务器名称空间可以使用单独的引用文件系统(在单独的服务器上)对名称空间的每个单独管理部分进行管理分段。顶级转诊文件系统或任何细分市场都可以使用复制的转诊文件系统以获得更高的可用性。

Generally, multi-server namespaces are for the most part uniform, in that the same data made available to one client at a given location in the namespace is made available to all clients at that location. However, there are facilities provided that allow different clients to be directed to different sets of data, so as to adapt to such client characteristics as CPU architecture.

通常,多服务器名称空间在很大程度上是统一的,因为名称空间中给定位置的一个客户端可以使用的相同数据,在该位置的所有客户端都可以使用。然而,提供的设施允许不同的客户机指向不同的数据集,以便适应CPU体系结构等客户机特性。

11.5. Location Entries and Server Identity
11.5. 位置条目和服务器标识

As mentioned above, a single location entry may have a server address target in the form of a DNS name that may represent multiple IP addresses, while multiple location entries may have their own server address targets that reference the same server. Whether two IP addresses designate the same server is indicated by the existence of a common so_major_id field within the eir_server_owner field returned by EXCHANGE_ID (see Section 18.35.3), subject to further verification (for details see Section 2.10.5).

如上所述,单个位置项可以具有DNS名称形式的服务器地址目标,该DNS名称可以表示多个IP地址,而多个位置项可以具有引用同一服务器的自己的服务器地址目标。EXCHANGE_id返回的eir_server_owner字段中存在一个公共so_major_id字段(见第18.35.3节),这表明两个IP地址是否指定了同一台服务器,但需进一步验证(详情见第2.10.5节)。

When multiple addresses for the same server exist, the client may assume that for each file system in the namespace of a given server network address, there exist file systems at corresponding namespace locations for each of the other server network addresses. It may do this even in the absence of explicit listing in fs_locations and fs_locations_info. Such corresponding file system locations can be used as alternate locations, just as those explicitly specified via the fs_locations and fs_locations_info attributes. Where these specific addresses are explicitly designated in the fs_locations_info

当同一服务器存在多个地址时,客户机可能会假定,对于给定服务器网络地址的命名空间中的每个文件系统,在其他每个服务器网络地址的相应命名空间位置都存在文件系统。即使没有在fs_位置和fs_位置信息中明确列出,它也可以这样做。这些相应的文件系统位置可以用作备用位置,就像通过fs_locations和fs_locations_info属性显式指定的位置一样。这些特定地址在fs_位置_信息中明确指定

attribute, the conditions of use specified in this attribute (e.g., priorities, specification of simultaneous use) may limit the client's use of these alternate locations.

属性中指定的使用条件(例如,优先级、同时使用规范)可能会限制客户使用这些备用位置。

If a single location entry designates multiple server IP addresses, the client cannot assume that these addresses are multiple paths to the same server. In most cases, they will be, but the client MUST verify that before acting on that assumption. When two server addresses are designated by a single location entry and they correspond to different servers, this normally indicates some sort of misconfiguration, and so the client should avoid using such location entries when alternatives are available. When they are not, clients should pick one of IP addresses and use it, without using others that are not directed to the same server.

如果单个位置条目指定多个服务器IP地址,则客户端不能假定这些地址是指向同一服务器的多条路径。在大多数情况下,它们都是,但客户必须在根据该假设采取行动之前验证。当两个服务器地址由一个位置条目指定,并且它们对应于不同的服务器时,这通常表示存在某种配置错误,因此当有其他选择时,客户端应避免使用此类位置条目。如果不是,客户端应该选择一个IP地址并使用它,而不使用其他不指向同一服务器的IP地址。

11.6. Additional Client-Side Considerations
11.6. 其他客户端注意事项

When clients make use of servers that implement referrals, replication, and migration, care should be taken that a user who mounts a given file system that includes a referral or a relocated file system continues to see a coherent picture of that user-side file system despite the fact that it contains a number of server-side file systems that may be on different servers.

当客户端使用实现转介、复制和迁移的服务器时,应注意,装载包含引用或重新定位文件系统的给定文件系统的用户继续看到该用户端文件系统的一致图片,尽管它包含许多可能位于不同服务器上的服务器端文件系统。

One important issue is upward navigation from the root of a server-side file system to its parent (specified as ".." in UNIX), in the case in which it transitions to that file system as a result of referral, migration, or a transition as a result of replication. When the client is at such a point, and it needs to ascend to the parent, it must go back to the parent as seen within the multi-server namespace rather than sending a LOOKUPP operation to the server, which would result in the parent within that server's single-server namespace. In order to do this, the client needs to remember the filehandles that represent such file system roots and use these instead of sending a LOOKUPP operation to the current server. This will allow the client to present to applications a consistent namespace, where upward navigation and downward navigation are consistent.

一个重要问题是从服务器端文件系统的根目录向上导航到其父目录(在UNIX中指定为“.”),在这种情况下,由于引用、迁移或复制而转换到该文件系统。当客户端处于这样的位置,并且需要提升到父级时,它必须返回到多服务器名称空间中看到的父级,而不是向服务器发送LOOKUPP操作,这将导致该服务器的单服务器名称空间中的父级。为了做到这一点,客户机需要记住表示这些文件系统根的文件句柄,并使用它们,而不是向当前服务器发送LOOKUPP操作。这将允许客户端向应用程序提供一致的命名空间,其中向上导航和向下导航是一致的。

Another issue concerns refresh of referral locations. When referrals are used extensively, they may change as server configurations change. It is expected that clients will cache information related to traversing referrals so that future client-side requests are resolved locally without server communication. This is usually rooted in client-side name look up caching. Clients should periodically purge this data for referral points in order to detect changes in location information. When the change_policy attribute

另一个问题涉及转诊地点的更新。广泛使用转介时,它们可能会随着服务器配置的更改而更改。预期客户端将缓存与遍历引用相关的信息,以便将来的客户端请求在本地解析,而无需服务器通信。这通常源于客户端名称查找缓存。客户应定期清除转诊点的这些数据,以便检测位置信息的变化。当更改策略属性时

changes for directories that hold referral entries or for the referral entries themselves, clients should consider any associated cached referral information to be out of date.

对于保存引用条目或推荐项目本身的目录的更改,客户端应考虑任何相关缓存的推荐信息过时。

11.7. Effecting File System Transitions
11.7. 影响文件系统转换

Transitions between file system instances, whether due to switching between replicas upon server unavailability or to server-initiated migration events, are best dealt with together. This is so even though, for the server, pragmatic considerations will normally force different implementation strategies for planned and unplanned transitions. Even though the prototypical use cases of replication and migration contain distinctive sets of features, when all possibilities for these operations are considered, there is an underlying unity of these operations, from the client's point of view, that makes treating them together desirable.

文件系统实例之间的转换,无论是由于服务器不可用时在副本之间切换,还是由于服务器启动的迁移事件,最好一起处理。即便如此,对于服务器来说,务实的考虑通常会对计划内和计划外的转换强制采用不同的实现策略。尽管复制和迁移的原型用例包含不同的特性集,但在考虑这些操作的所有可能性时,从客户的角度来看,这些操作有一个潜在的统一性,这使得将它们放在一起是可取的。

A number of methods are possible for servers to replicate data and to track client state in order to allow clients to transition between file system instances with a minimum of disruption. Such methods vary between those that use inter-server clustering techniques to limit the changes seen by the client, to those that are less aggressive, use more standard methods of replicating data, and impose a greater burden on the client to adapt to the transition.

服务器可以使用多种方法复制数据和跟踪客户机状态,以便客户机在文件系统实例之间以最小的中断进行转换。这些方法各不相同,既有使用服务器间群集技术限制客户端看到的更改的方法,也有攻击性较小的方法,使用更标准的数据复制方法,并对客户端施加更大的负担以适应转换的方法。

The NFSv4.1 protocol does not impose choices on clients and servers with regard to that spectrum of transition methods. In fact, there are many valid choices, depending on client and application requirements and their interaction with server implementation choices. The NFSv4.1 protocol does define the specific choices that can be made, how these choices are communicated to the client, and how the client is to deal with any discontinuities.

NFSv4.1协议不会对客户机和服务器施加关于该系列转换方法的选择。事实上,有许多有效的选择,这取决于客户机和应用程序的需求以及它们与服务器实现的交互选择。NFSv4.1协议确实定义了可以做出的具体选择,如何将这些选择传达给客户,以及客户如何处理任何不连续性。

In the sections below, references will be made to various possible server implementation choices as a way of illustrating the transition scenarios that clients may deal with. The intent here is not to define or limit server implementations but rather to illustrate the range of issues that clients may face.

在下面的部分中,将参考各种可能的服务器实现选择,以说明客户端可能处理的转换场景。这里的目的不是定义或限制服务器实现,而是说明客户端可能面临的一系列问题。

In the discussion below, references will be made to a file system having a particular property or to two file systems (typically the source and destination) belonging to a common class of any of several types. Two file systems that belong to such a class share some important aspects of file system behavior that clients may depend upon when present, to easily effect a seamless transition between file system instances. Conversely, where the file systems do not

在下面的讨论中,将参考具有特定属性的文件系统或属于几种类型中任何一种的公共类的两个文件系统(通常是源和目标)。属于这样一个类的两个文件系统共享文件系统行为的一些重要方面,客户机可能依赖这些方面,以便轻松实现文件系统实例之间的无缝转换。相反,如果文件系统没有

belong to such a common class, the client has to deal with various sorts of implementation discontinuities that may cause performance or other issues in effecting a transition.

属于这样一个公共类,客户机必须处理各种各样的实现不连续性,这些不连续性可能会在实现转换时导致性能或其他问题。

Where the fs_locations_info attribute is available, such file system classification data will be made directly available to the client (see Section 11.10 for details). When only fs_locations is available, default assumptions with regard to such classifications have to be inferred (see Section 11.9 for details).

如果fs_locations_info属性可用,则此类文件系统分类数据将直接提供给客户(有关详细信息,请参阅第11.10节)。当只有fs_位置可用时,必须推断此类分类的默认假设(详情见第11.9节)。

In cases in which one server is expected to accept opaque values from the client that originated from another server, the servers SHOULD encode the "opaque" values in big-endian byte order. If this is done, servers acting as replicas or immigrating file systems will be able to parse values like stateids, directory cookies, filehandles, etc., even if their native byte order is different from that of other servers cooperating in the replication and migration of the file system.

如果期望一台服务器接受来自另一台服务器的客户端的不透明值,则服务器应以大端字节顺序对“不透明”值进行编码。如果这样做,作为副本或迁移文件系统的服务器将能够解析stateID、目录cookie、文件句柄等值,即使它们的本机字节顺序不同于在文件系统的复制和迁移中协作的其他服务器的本机字节顺序。

11.7.1. File System Transitions and Simultaneous Access
11.7.1. 文件系统转换和同时访问

When a single file system may be accessed at multiple locations, either because of an indication of file system identity as reported by the fs_locations or fs_locations_info attributes or because two file system instances have corresponding locations on server addresses that connect to the same server (as indicated by a common so_major_id field in the eir_server_owner field returned by EXCHANGE_ID), the client will, depending on specific circumstances as discussed below, either:

当单个文件系统可以在多个位置访问时,可能是因为fs_locations或fs_locations_info属性报告的文件系统标识指示,或者是因为两个文件系统实例在连接到同一服务器的服务器地址上具有相应的位置(如EXCHANGE\u id返回的eir\u server\u owner字段中的公共so\u major\u id字段所示),客户端将根据以下讨论的特定情况:

o Access multiple instances simultaneously, each of which represents an alternate path to the same data and metadata.

o 同时访问多个实例,每个实例表示指向相同数据和元数据的备用路径。

o Access one instance (or set of instances) and then transition to an alternative instance (or set of instances) as a result of network issues, server unresponsiveness, or server-directed migration. The transition may involve changes in filehandles, fileids, the change attribute, and/or locking state, depending on the attributes of the source and destination file system instances, as specified in the fs_locations_info attribute.

o 由于网络问题、服务器无响应或服务器定向迁移,请访问一个实例(或一组实例),然后转换到另一个实例(或一组实例)。转换可能涉及文件句柄、文件ID、更改属性和/或锁定状态的更改,具体取决于源和目标文件系统实例的属性,如fs_locations_info属性中指定的。

Which of these choices is possible, and how a transition is effected, is governed by equivalence classes of file system instances as reported by the fs_locations_info attribute, and for file system instances in the same location within a multi-homed single-server namespace, as indicated by the value of the so_major_id field of the eir_server_owner field returned by EXCHANGE_ID.

这些选择中的哪一个是可能的,以及转换是如何影响的,由fs_locations_info属性报告的文件系统实例的等价类控制,对于多宿主单服务器命名空间中相同位置的文件系统实例,如EXCHANGE\u id返回的eir\u服务器\u所有者字段的so\u主\u id字段的值所示。

11.7.2. Simultaneous Use and Transparent Transitions
11.7.2. 同时使用和透明转换

When two file system instances have the same location within their respective single-server namespaces and those two server network addresses designate the same server (as indicated by the same value of the so_major_id field of the eir_server_owner field returned in response to EXCHANGE_ID), those file system instances can be treated as the same, and either used together simultaneously or serially with no transition activity required on the part of the client. In this case, we refer to the transition as "transparent", and the client in transferring access from one to the other is acting as it would in the event that communication is interrupted, with a new connection and possibly a new session being established to continue access to the same file system.

如果两个文件系统实例在各自的单服务器名称空间中具有相同的位置,并且这两个服务器网络地址指定了相同的服务器(如响应EXCHANGE_id返回的eir_server_owner字段的so_major_id字段的相同值所示),则可以将这些文件系统实例视为相同,并且可以同时使用,也可以连续使用,客户端不需要任何转换活动。在这种情况下,我们将转换称为“透明”,并且在将访问权从一个传输到另一个的过程中,客户端的行为与在通信中断的情况下一样,建立了新的连接,可能还建立了新的会话,以继续访问同一文件系统。

Whether simultaneous use of the two file system instances is valid is controlled by whether the fs_locations_info attribute shows the two instances as having the same simultaneous-use class. See Section 11.10.1 for information about the definition of the various use classes, including the simultaneous-use class.

同时使用两个文件系统实例是否有效,取决于fs_locations_info属性是否将两个实例显示为具有相同的同时使用类。有关各种使用类别(包括同时使用类别)定义的信息,请参见第11.10.1节。

Note that for two such file systems, any information within the fs_locations_info attribute that indicates the need for special transition activity, i.e., the appearance of the two file system instances with different handle, fileid, write-verifier, change, and readdir classes, indicates a serious problem. The client, if it allows transition to the file system instance at all, must not treat this as a transparent transition. The server SHOULD NOT indicate that these instances belong to different handle, fileid, write-verifier, change, and readdir classes, whether or not the two instances are shown belonging to the same simultaneous-use class.

请注意,对于这两个文件系统,fs_locations_info属性中表示需要特殊转换活动的任何信息,即具有不同句柄、fileid、write-verifier、change和readdir类的两个文件系统实例的外观,都表明存在严重问题。如果客户端允许转换到文件系统实例,则不能将其视为透明转换。服务器不应指示这些实例属于不同的handle、fileid、write-verifier、change和readdir类,无论这两个实例是否属于同一个并发使用类。

Where these conditions do not apply, a non-transparent file system instance transition is required with the details depending on the respective handle, fileid, write-verifier, change, and readdir classes of the two file system instances, and whether the two servers' addresses in question have the same eir_server_scope value as reported by EXCHANGE_ID.

如果这些条件不适用,则需要非透明的文件系统实例转换,其详细信息取决于两个文件系统实例的各自句柄、fileid、write-verifier、change和readdir类,以及所讨论的两台服务器的地址是否具有与EXCHANGE\u ID报告的相同的eir\u服务器\u作用域值。

11.7.2.1. Simultaneous Use of File System Instances
11.7.2.1. 同时使用文件系统实例

When the conditions in Section 11.7.2 hold, in either of the following two cases, the client may use the two file system instances simultaneously.

当第11.7.2节中的条件成立时,在以下两种情况下,客户机可以同时使用这两个文件系统实例。

o The fs_locations_info attribute does not contain separate per-network-address entries for file system instances at the distinct network addresses. This includes the case in which the

o fs_locations_info属性不包含不同网络地址处文件系统实例的单独的每个网络地址条目。这包括以下情况:

fs_locations_info attribute is unavailable. In this case, the fact that the two server addresses connect to the same server (as indicated by the two addresses sharing the same the so_major_id value and subsequently confirmed as described in Section 2.10.5) justifies simultaneous use, and there is no fs_locations_info attribute information contradicting that.

fs\u位置\u信息属性不可用。在这种情况下,两个服务器地址连接到同一个服务器(如共享相同so_major_id值的两个地址所示,随后如第2.10.5节所述进行确认)这一事实证明可以同时使用,并且没有与此相矛盾的fs_locations_info属性信息。

o The fs_locations_info attribute indicates that two file system instances belong to the same simultaneous-use class.

o fs_locations_info属性表示两个文件系统实例属于同一个并发使用类。

In this case, the client may use both file system instances simultaneously, as representations of the same file system, whether that happens because the two network addresses connect to the same physical server or because different servers connect to clustered file systems and export their data in common. When simultaneous use is in effect, any change made to one file system instance must be immediately reflected in the other file system instance(s). Locks are treated as part of a common lease, associated with a common client ID. Depending on the details of the eir_server_owner returned by EXCHANGE_ID, the two server instances may be accessed by different sessions or a single session in common.

在这种情况下,客户机可以同时使用两个文件系统实例作为同一文件系统的表示,无论这是因为两个网络地址连接到同一物理服务器,还是因为不同的服务器连接到集群文件系统并共同导出其数据。当同时使用生效时,对一个文件系统实例所做的任何更改都必须立即反映在其他文件系统实例中。锁被视为公共租约的一部分,与公共客户端ID关联。根据EXCHANGE\u ID返回的eir\u服务器\u所有者的详细信息,两个服务器实例可以由不同的会话访问,也可以由同一个会话访问。

11.7.2.2. Transparent File System Transitions
11.7.2.2. 透明文件系统转换

When the conditions in Section 11.7.2.1 hold and the fs_locations_info attribute explicitly shows the file system instances for these distinct network addresses as belonging to different simultaneous-use classes, the file system instances should not be used by the client simultaneously. Rather, they should be used serially with one being used unless and until communication difficulties, lack of responsiveness, or an explicit migration event causes another file system instance (or set of file system instances sharing a common simultaneous-use class) to be used.

当第11.7.2.1节中的条件成立且fs_locations_info属性明确显示这些不同网络地址的文件系统实例属于不同的同时使用类时,客户端不应同时使用这些文件系统实例。相反,它们应该与正在使用的文件一起串行使用,除非并且直到通信困难、缺乏响应或显式迁移事件导致使用另一个文件系统实例(或共享公共同时使用类的一组文件系统实例)。

When a change of file system instance is to be done, the client will use the same client ID already in effect. If the client already has connections to the new server address, these will be used. Otherwise, new connections to existing sessions or new sessions associated with the existing client ID are established as indicated by the eir_server_owner returned by EXCHANGE_ID.

当要更改文件系统实例时,客户端将使用已生效的相同客户端ID。如果客户端已连接到新服务器地址,则将使用这些连接。否则,将按照EXCHANGE\u ID返回的eir\u服务器\u所有者的指示,建立到现有会话的新连接或与现有客户端ID关联的新会话。

In all such transparent transition cases, the following apply:

在所有此类透明过渡情况下,以下情况适用:

o If filehandles are persistent, they stay the same. If filehandles are volatile, they either stay the same or expire, but the reason for expiration is not due to the file system transition.

o 如果文件句柄是持久的,则它们保持不变。如果文件句柄是易变的,则它们要么保持不变,要么过期,但过期的原因不是由于文件系统转换。

o Fileid values do not change across the transition.

o Fileid值在转换过程中不会更改。

o The file system will have the same fsid in both the old and new locations.

o 文件系统在新旧位置将具有相同的fsid。

o Change attribute values are consistent across the transition and do not have to be refetched. When change attributes indicate that a cached object is still valid, it can remain cached.

o 更改属性值在整个转换过程中保持一致,不必重新蚀刻。当更改属性指示缓存的对象仍然有效时,它可以保持缓存状态。

o Client and state identifiers retain their validity across the transition, except where their staleness is recognized and reported by the new server. Except where such staleness requires it, no lock reclamation is needed. Any such staleness is an indication that the server should be considered to have restarted and is reported as discussed in Section 8.4.2.

o 客户机和状态标识符在整个转换过程中保持其有效性,除非新服务器识别并报告它们的过时情况。除非这种陈旧性需要,否则不需要锁回收。任何此类过时都表明服务器应被视为已重新启动,并按照第8.4.2节的讨论报告。

o Write verifiers are presumed to retain their validity and can be used to compare with verifiers returned by COMMIT on the new server. If COMMIT on the new server returns an identical verifier, then it is expected that the new server has all of the data that was written unstably to the original server and has committed that data to stable storage as requested.

o 写入验证器被假定为保持其有效性,并可用于与新服务器上提交返回的验证器进行比较。如果新服务器上的提交返回一个相同的验证器,那么新服务器应该具有不稳定写入原始服务器的所有数据,并且已经按照请求将这些数据提交到稳定的存储中。

o Readdir cookies are presumed to retain their validity and can be presented to subsequent READDIR requests together with the readdir verifier with which they are associated. When the verifier is accepted as valid, the cookie will continue the READDIR operation so that the entire directory can be obtained by the client.

o Readdir Cookie被认为保持其有效性,并可与与其关联的Readdir验证器一起提交给后续的Readdir请求。当验证器被接受为有效时,cookie将继续READDIR操作,以便客户端可以获取整个目录。

11.7.3. Filehandles and File System Transitions
11.7.3. 文件句柄和文件系统转换

There are a number of ways in which filehandles can be handled across a file system transition. These can be divided into two broad classes depending upon whether the two file systems across which the transition happens share sufficient state to effect some sort of continuity of file system handling.

在文件系统转换过程中,可以通过多种方式处理文件句柄。根据发生转换的两个文件系统是否共享足够的状态以实现文件系统处理的某种连续性,可以将它们分为两大类。

When there is no such cooperation in filehandle assignment, the two file systems are reported as being in different handle classes. In this case, all filehandles are assumed to expire as part of the file system transition. Note that this behavior does not depend on the fh_expire_type attribute and supersedes the specification of the FH4_VOL_MIGRATION bit, which only affects behavior when fs_locations_info is not available.

当filehandle分配中没有这种协作时,两个文件系统被报告为处于不同的句柄类中。在这种情况下,所有文件句柄都假定在文件系统转换过程中过期。请注意,此行为不依赖于fh_expire_type属性,并取代FH4_VOL_迁移位的规范,该规范仅在fs_locations_info不可用时影响行为。

When there is cooperation in filehandle assignment, the two file systems are reported as being in the same handle classes. In this case, persistent filehandles remain valid after the file system

当filehandle分配中存在协作时,两个文件系统将被报告为位于相同的句柄类中。在这种情况下,持久化文件句柄在文件系统关闭后仍然有效

transition, while volatile filehandles (excluding those that are only volatile due to the FH4_VOL_MIGRATION bit) are subject to expiration on the target server.

转换,而易失性文件句柄(不包括那些仅因FH4_VOL_迁移位而易失性的文件句柄)在目标服务器上可能会过期。

11.7.4. Fileids and File System Transitions
11.7.4. 文件ID和文件系统转换

In NFSv4.0, the issue of continuity of fileids in the event of a file system transition was not addressed. The general expectation had been that in situations in which the two file system instances are created by a single vendor using some sort of file system image copy, fileids will be consistent across the transition, while in the analogous multi-vendor transitions they will not. This poses difficulties, especially for the client without special knowledge of the transition mechanisms adopted by the server. Note that although fileid is not a REQUIRED attribute, many servers support fileids and many clients provide APIs that depend on fileids.

在NFSv4.0中,没有解决文件系统转换时文件ID的连续性问题。一般的期望是,在两个文件系统实例由一个供应商使用某种文件系统映像副本创建的情况下,fileid在整个转换过程中保持一致,而在类似的多供应商转换过程中则不会保持一致。这会带来困难,特别是对于不了解服务器采用的转换机制的客户机。请注意,尽管fileid不是必需的属性,但许多服务器支持fileid,许多客户端提供依赖于fileid的api。

It is important to note that while clients themselves may have no trouble with a fileid changing as a result of a file system transition event, applications do typically have access to the fileid (e.g., via stat). The result is that an application may work perfectly well if there is no file system instance transition or if any such transition is among instances created by a single vendor, yet be unable to deal with the situation in which a multi-vendor transition occurs at the wrong time.

需要注意的是,虽然客户机本身可能不会因为文件系统转换事件而更改文件ID,但应用程序通常可以访问文件ID(例如,通过stat)。其结果是,如果没有文件系统实例转换,或者如果任何此类转换是在单个供应商创建的实例之间进行的,但却无法处理多供应商转换在错误时间发生的情况,则应用程序可能会工作得非常好。

Providing the same fileids in a multi-vendor (multiple server vendors) environment has generally been held to be quite difficult. While there is work to be done, it needs to be pointed out that this difficulty is partly self-imposed. Servers have typically identified fileid with inode number, i.e. with a quantity used to find the file in question. This identification poses special difficulties for migration of a file system between vendors where assigning the same index to a given file may not be possible. Note here that a fileid is not required to be useful to find the file in question, only that it is unique within the given file system. Servers prepared to accept a fileid as a single piece of metadata and store it apart from the value used to index the file information can relatively easily maintain a fileid value across a migration event, allowing a truly transparent migration event.

在多供应商(多个服务器供应商)环境中提供相同的fileid通常被认为是相当困难的。虽然还有工作要做,但需要指出的是,这一困难部分是自己造成的。服务器通常使用inode编号标识fileid,即使用用于查找相关文件的数量。这种标识为供应商之间的文件系统迁移带来了特殊困难,因为在供应商之间可能无法为给定文件指定相同的索引。请注意,文件ID在查找相关文件时并不一定有用,只是它在给定的文件系统中是唯一的。准备接受fileid作为单个元数据并将其与用于索引文件信息的值分开存储的服务器可以相对轻松地在迁移事件中维护fileid值,从而实现真正透明的迁移事件。

In any case, where servers can provide continuity of fileids, they should, and the client should be able to find out that such continuity is available and take appropriate action. Information about the continuity (or lack thereof) of fileids across a file system transition is represented by specifying whether the file systems in question are of the same fileid class.

在任何情况下,如果服务器可以提供文件ID的连续性,那么它们应该,并且客户机应该能够发现这种连续性是可用的,并采取适当的措施。关于文件系统转换中文件ID的连续性(或缺乏连续性)的信息通过指定所涉及的文件系统是否属于相同的文件ID类来表示。

Note that when consistent fileids do not exist across a transition (either because there is no continuity of fileids or because fileid is not a supported attribute on one of instances involved), and there are no reliable filehandles across a transition event (either because there is no filehandle continuity or because the filehandles are volatile), the client is in a position where it cannot verify that files it was accessing before the transition are the same objects. It is forced to assume that no object has been renamed, and, unless there are guarantees that provide this (e.g., the file system is read-only), problems for applications may occur. Therefore, use of such configurations should be limited to situations where the problems that this may cause can be tolerated.

请注意,如果转换过程中不存在一致的fileid(可能是因为fileid没有连续性,也可能是因为fileid不是所涉及实例之一的受支持属性),并且转换事件中没有可靠的filehandles(可能是因为没有filehandle连续性,也可能是因为filehandles不稳定),客户端处于无法验证其在转换之前访问的文件是否为相同对象的位置。它被迫假设没有对象被重命名,并且,除非有提供此保证的保证(例如,文件系统是只读的),否则应用程序可能会出现问题。因此,应将此类配置的使用限制在可以容忍其可能导致的问题的情况下。

11.7.5. Fsids and File System Transitions
11.7.5. fsid和文件系统转换

Since fsids are generally only unique within a per-server basis, it is likely that they will change during a file system transition. One exception is the case of transparent transitions, but in that case we have multiple network addresses that are defined as the same server (as specified by a common value of the so_major_id field of eir_server_owner). Clients should not make the fsids received from the server visible to applications since they may not be globally unique, and because they may change during a file system transition event. Applications are best served if they are isolated from such transitions to the extent possible.

由于FSID通常仅在每台服务器中是唯一的,因此它们很可能在文件系统转换期间发生更改。一个例外是透明转换的情况,但在这种情况下,我们有多个定义为同一服务器的网络地址(由eir_server_owner的so_major_id字段的公共值指定)。客户端不应使从服务器接收的FSID对应用程序可见,因为它们可能不是全局唯一的,并且在文件系统转换事件期间可能会更改。如果应用程序尽可能地与此类转换隔离,那么它们将得到最好的服务。

Although normally a single source file system will transition to a single target file system, there is a provision for splitting a single source file system into multiple target file systems, by specifying the FSLI4F_MULTI_FS flag.

虽然通常单个源文件系统将转换为单个目标文件系统,但通过指定FSLI4F_MULTI_FS标志,可以将单个源文件系统拆分为多个目标文件系统。

11.7.5.1. File System Splitting
11.7.5.1. 文件系统拆分

When a file system transition is made and the fs_locations_info indicates that the file system in question may be split into multiple file systems (via the FSLI4F_MULTI_FS flag), the client SHOULD do GETATTRs to determine the fsid attribute on all known objects within the file system undergoing transition to determine the new file system boundaries.

当进行文件系统转换且fs_locations_info指示相关文件系统可能拆分为多个文件系统时(通过FSLI4F_MULTI_fs标志),客户端应该执行GETATTRs来确定文件系统中所有正在转换的已知对象的fsid属性,以确定新的文件系统边界。

Clients may maintain the fsids passed to existing applications by mapping all of the fsids for the descendant file systems to the common fsid used for the original file system.

客户端可以通过将子文件系统的所有fsid映射到用于原始文件系统的公共fsid来维护传递给现有应用程序的fsid。

Splitting a file system may be done on a transition between file systems of the same fileid class, since the fact that fileids are unique within the source file system ensure they will be unique in each of the target file systems.

拆分文件系统可以在同一fileid类的文件系统之间的转换上完成,因为fileid在源文件系统中是唯一的,这确保了它们在每个目标文件系统中都是唯一的。

11.7.6. The Change Attribute and File System Transitions
11.7.6. 更改属性和文件系统转换

Since the change attribute is defined as a server-specific one, change attributes fetched from one server are normally presumed to be invalid on another server. Such a presumption is troublesome since it would invalidate all cached change attributes, requiring refetching. Even more disruptive, the absence of any assured continuity for the change attribute means that even if the same value is retrieved on refetch, no conclusions can be drawn as to whether the object in question has changed. The identical change attribute could be merely an artifact of a modified file with a different change attribute construction algorithm, with that new algorithm just happening to result in an identical change value.

由于更改属性定义为特定于服务器的属性,因此从一台服务器获取的更改属性通常被认为在另一台服务器上无效。这样的假设很麻烦,因为它会使所有缓存的更改属性无效,需要重新蚀刻。更具破坏性的是,更改属性缺少任何保证的连续性意味着,即使在重新蚀刻时检索到相同的值,也无法得出有关对象是否已更改的结论。相同的变更属性可能只是使用不同变更属性构造算法的修改文件的工件,而新算法恰好会产生相同的变更值。

When the two file systems have consistent change attribute formats, and this fact is communicated to the client by reporting in the same change class, the client may assume a continuity of change attribute construction and handle this situation just as it would be handled without any file system transition.

当两个文件系统具有一致的更改属性格式,并且这一事实通过在同一更改类别中报告而传达给客户时,客户可以假定更改属性构造的连续性,并像在没有任何文件系统转换的情况下一样处理这种情况。

11.7.7. Lock State and File System Transitions
11.7.7. 锁定状态和文件系统转换

In a file system transition, the client needs to handle cases in which the two servers have cooperated in state management and in which they have not. Cooperation by two servers in state management requires coordination of client IDs. Before the client attempts to use a client ID associated with one server in a request to the server of the other file system, it must eliminate the possibility that two non-cooperating servers have assigned the same client ID by accident. The client needs to compare the eir_server_scope values returned by each server. If the scope values do not match, then the servers have not cooperated in state management. If the scope values match, then this indicates the servers have cooperated in assigning client IDs to the point that they will reject client IDs that refer to state they do not know about. See Section 2.10.4 for more information about the use of server scope.

在文件系统转换中,客户机需要处理两台服务器在状态管理方面进行了协作而在状态管理方面没有进行协作的情况。两台服务器在状态管理中的协作需要协调客户端ID。在客户端尝试在对另一个文件系统的服务器的请求中使用与一个服务器关联的客户端ID之前,必须消除两个不合作的服务器意外分配相同客户端ID的可能性。客户端需要比较每台服务器返回的eir_服务器_范围值。如果作用域值不匹配,则表示服务器在状态管理中没有协作。如果作用域值匹配,则表示服务器已合作将客户端ID分配到某个点,它们将拒绝引用它们不知道的状态的客户端ID。有关服务器作用域使用的更多信息,请参见第2.10.4节。

In the case of migration, the servers involved in the migration of a file system SHOULD transfer all server state from the original to the new server. When this is done, it must be done in a way that is transparent to the client. With replication, such a degree of common state is typically not the case. Clients, however, should use the information provided by the eir_server_scope returned by EXCHANGE_ID (as modified by the validation procedures described in Section 2.10.4) to determine whether such sharing may be in effect, rather than making assumptions based on the reason for the transition.

在迁移的情况下,参与文件系统迁移的服务器应将所有服务器状态从原始服务器传输到新服务器。完成此操作后,必须以对客户端透明的方式完成。对于复制,这种程度的公共状态通常不是这样。但是,客户应使用EXCHANGE_ID返回的eir_服务器_范围提供的信息(经第2.10.4节所述验证程序修改)来确定此类共享是否有效,而不是根据转换原因进行假设。

This state transfer will reduce disruption to the client when a file system transition occurs. If the servers are successful in transferring all state, the client can attempt to establish sessions associated with the client ID used for the source file system instance. If the server accepts that as a valid client ID, then the client may use the existing stateids associated with that client ID for the old file system instance in connection with that same client ID in connection with the transitioned file system instance. If the client in question already had a client ID on the target system, it may interrogate the stateid values from the source system under that new client ID, with the assurance that if they are accepted as valid, then they represent validly transferred lock state for the source file system, which has been transferred to the target server.

当文件系统转换发生时,此状态传输将减少对客户端的中断。如果服务器成功传输所有状态,则客户端可以尝试建立与用于源文件系统实例的客户端ID关联的会话。如果服务器接受它作为有效的客户机ID,那么客户机可以将与旧文件系统实例的客户机ID相关联的现有stateID与转换后的文件系统实例的相同客户机ID一起使用。如果所述客户机在目标系统上已经具有客户机ID,则它可以在该新客户机ID下查询源系统的stateid值,并保证如果这些值被接受为有效值,则它们表示已传输到目标服务器的源文件系统的有效传输锁定状态。

When the two servers belong to the same server scope, it does not mean that when dealing with the transition, the client will not have to reclaim state. However, it does mean that the client may proceed using its current client ID when establishing communication with the new server, and the new server will either recognize the client ID as valid or reject it, in which case locks must be reclaimed by the client.

当两台服务器属于同一服务器作用域时,这并不意味着在处理转换时,客户端将不必回收状态。但是,这确实意味着客户端在与新服务器建立通信时可以继续使用其当前客户端ID,并且新服务器将识别该客户端ID为有效或拒绝该ID,在这种情况下,客户端必须回收锁。

File systems cooperating in state management may actually share state or simply divide the identifier space so as to recognize (and reject as stale) each other's stateids and client IDs. Servers that do share state may not do so under all conditions or at all times. If the server cannot be sure when accepting a client ID that it reflects the locks the client was given, the server must treat all associated state as stale and report it as such to the client.

在状态管理中协作的文件系统实际上可能共享状态,或者只是划分标识符空间,以便识别(并拒绝作为过时的)彼此的stateID和客户端ID。不共享状态的服务器可能不会在所有情况下或任何时候共享状态。如果服务器在接受客户机ID时无法确定它是否反映了提供给客户机的锁,则服务器必须将所有关联状态视为陈旧状态,并将其报告给客户机。

When the two file system instances are on servers that do not share a server scope value, the client must establish a new client ID on the destination, if it does not have one already, and reclaim locks if allowed by the server. In this case, old stateids and client IDs should not be presented to the new server since there is no assurance that they will not conflict with IDs valid on that server. Note that in this case, lock reclaim may be attempted even when the servers involved in the transfer have different server scope values (see Section 8.4.2.1 for the contrary case of reclaim after server reboot). Servers with different server scope values may cooperate to allow reclaim for locks associated with the transfer of a file system even if they do not cooperate sufficiently to share a server scope.

当两个文件系统实例位于不共享服务器作用域值的服务器上时,客户端必须在目标上建立新的客户端ID(如果尚未建立),并在服务器允许的情况下回收锁。在这种情况下,旧的StateID和客户端ID不应显示给新服务器,因为无法保证它们不会与该服务器上的有效ID冲突。请注意,在这种情况下,即使传输中涉及的服务器具有不同的服务器作用域值,也可以尝试锁回收(有关服务器重新启动后回收的相反情况,请参阅第8.4.2.1节)。具有不同服务器作用域值的服务器可以协作,以允许回收与文件系统传输相关联的锁,即使它们没有充分协作以共享服务器作用域。

In either case, when actual locks are not known to be maintained, the destination server may establish a grace period specific to the given file system, with non-reclaim locks being rejected for that file system, even though normal locks are being granted for other file

在这两种情况下,当不知道要维护实际锁时,目标服务器可以建立特定于给定文件系统的宽限期,拒绝该文件系统的非回收锁,即使为其他文件系统授予正常锁

systems. Clients should not infer the absence of a grace period for file systems being transitioned to a server from responses to requests for other file systems.

系统。客户端不应根据对其他文件系统请求的响应推断正在转换到服务器的文件系统没有宽限期。

In the case of lock reclamation for a given file system after a file system transition, edge conditions can arise similar to those for reclaim after server restart (although in the case of the planned state transfer associated with migration, these can be avoided by securely recording lock state as part of state migration). Unless the destination server can guarantee that locks will not be incorrectly granted, the destination server should not allow lock reclaims and should avoid establishing a grace period.

在文件系统转换后对给定文件系统进行锁回收的情况下,可能会出现与服务器重新启动后回收类似的边缘条件(尽管在与迁移相关的计划状态转移的情况下,可以通过将锁状态安全地记录为状态迁移的一部分来避免这些情况)。除非目标服务器能够保证不会错误地授予锁,否则目标服务器不应允许锁回收,并应避免建立宽限期。

Once all locks have been reclaimed, or there were no locks to reclaim, the client indicates that there are no more reclaims to be done for the file system in question by sending a RECLAIM_COMPLETE operation with the rca_one_fs parameter set to true. Once this has been done, non-reclaim locking operations may be done, and any subsequent request to do reclaims will be rejected with the error NFS4ERR_NO_GRACE.

一旦所有锁都已回收,或者没有要回收的锁,客户机将通过发送一个rca_one_fs参数设置为true的Reclain_COMPLETE操作来指示不再需要对相关文件系统进行回收。完成此操作后,可以执行非回收锁定操作,任何后续的回收请求都将被拒绝,错误为NFS4ERR_NO_。

Information about client identity may be propagated between servers in the form of client_owner4 and associated verifiers, under the assumption that the client presents the same values to all the servers with which it deals.

关于客户身份的信息可以以客户机所有者4和相关验证器的形式在服务器之间传播,前提是客户机向与其交易的所有服务器呈现相同的值。

Servers are encouraged to provide facilities to allow locks to be reclaimed on the new server after a file system transition. Often, however, in cases in which the two servers do not share a server scope value, such facilities may not be available and the client should be prepared to re-obtain locks, even though it is possible that the client may have its LOCK or OPEN request denied due to a conflicting lock.

鼓励服务器提供设施,允许在文件系统转换后在新服务器上回收锁。然而,通常,在两台服务器不共享服务器作用域值的情况下,此类设施可能不可用,并且客户端应准备重新获取锁,即使客户端可能由于锁冲突而拒绝其锁或打开请求。

The consequences of having no facilities available to reclaim locks on the new server will depend on the type of environment. In some environments, such as the transition between read-only file systems, 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 its original lock had been revoked. Note that when the lock is granted, the client cannot assume that no conflicting lock could have been granted in the interim. Where change attribute continuity is present, the client may check the change attribute to check for unwanted file modifications. Where even this is not available, and the file system is not read-only, a client may reasonably treat all pending locks as having been revoked.

在新服务器上没有可用于回收锁的设施的后果将取决于环境的类型。在某些环境中,例如只读文件系统之间的转换,这种拒绝锁定在实践中不会造成很大困难。当在新服务器上重新建立锁的尝试被拒绝时,客户端应将此情况视为其原始锁已被撤销。请注意,当授予锁时,客户端不能假定在此期间不会授予任何冲突的锁。在存在更改属性连续性的情况下,客户端可以检查更改属性以检查不需要的文件修改。即使这不可用,并且文件系统不是只读的,客户端也可以合理地将所有挂起的锁视为已被撤销。

11.7.7.1. Leases and File System Transitions
11.7.7.1. 租约和文件系统转换

In the case of lease renewal, the client may not be submitting requests for a file system that has been transferred to another server. This can occur because of the lease renewal mechanism. The client renews the lease associated with all file systems when submitting a request on an associated session, regardless of the specific file system being referenced.

在续订租约的情况下,客户端可能不会提交已传输到另一台服务器的文件系统请求。这可能是由于租约续订机制造成的。在关联会话上提交请求时,客户端将续订与所有文件系统关联的租约,而不考虑引用的特定文件系统。

In order for the client to schedule renewal of its lease where there is locking state that may have been relocated to the new server, the client must find out about lease relocation before that lease expire. To accomplish this, the SEQUENCE operation will return the status bit SEQ4_STATUS_LEASE_MOVED if responsibility for any of the renewed locking state has been transferred to a new server. This will continue until the client receives an NFS4ERR_MOVED error for each of the file systems for which there has been locking state relocation.

为了让客户端在存在可能已重新定位到新服务器的锁定状态的情况下安排其租约的续订,客户端必须在租约到期之前了解有关租约重新定位的信息。为此,如果任何更新锁定状态的责任已转移到新服务器,则序列操作将返回状态位SEQ4_status_LEASE_MOVED。这将一直持续,直到客户端接收到每个文件系统的NFS4ERR_MOVED错误,该文件系统已被锁定状态重新定位。

When a client receives an SEQ4_STATUS_LEASE_MOVED indication from a server, for each file system of the server for which the client has locking state, the client should perform an operation. For simplicity, the client may choose to reference all file systems, but what is important is that it must reference all file systems for which there was locking state where that state has moved. Once the client receives an NFS4ERR_MOVED error for each such file system, the server will clear the SEQ4_STATUS_LEASE_MOVED indication. The client can terminate the process of checking file systems once this indication is cleared (but only if the client has received a reply for all outstanding SEQUENCE requests on all sessions it has with the server), since there are no others for which locking state has moved.

当客户端从服务器接收到SEQ4_STATUS_LEASE_MOVED指示时,对于客户端具有锁定状态的服务器的每个文件系统,客户端应执行一个操作。为简单起见,客户机可以选择引用所有文件系统,但重要的是,它必须引用存在锁定状态的所有文件系统,该状态已移动到该文件系统。一旦客户端收到每个这样的文件系统的NFS4ERR_MOVED错误,服务器将清除SEQ4_STATUS_LEASE_MOVED指示。清除此指示后,客户端可以终止检查文件系统的过程(但仅当客户端在与服务器的所有会话上收到所有未完成序列请求的答复时),因为没有其他锁定状态已移动。

A client may use GETATTR of the fs_status (or fs_locations_info) attribute on all of the file systems to get absence indications in a single (or a few) request(s), since absent file systems will not cause an error in this context. However, it still must do an operation that receives NFS4ERR_MOVED on each file system, in order to clear the SEQ4_STATUS_LEASE_MOVED indication.

客户机可以在所有文件系统上使用fs_status(或fs_locations_info)属性的GETATTR来获取单个(或少数)请求中的缺勤指示,因为缺勤文件系统在这种情况下不会导致错误。但是,它仍然必须执行一个操作,在每个文件系统上接收NFS4ERR_MOVED,以便清除SEQ4_STATUS_LEASE_MOVED指示。

Once the set of file systems with transferred locking state has been determined, the client can follow the normal process to obtain the new server information (through the fs_locations and fs_locations_info attributes) and perform renewal of that lease on the new server, unless information in the fs_locations_info attribute shows that no state could have been transferred. If the server has not had state transferred to it transparently, the client will receive NFS4ERR_STALE_CLIENTID from the new server, as described above, and the client can then reclaim locks as is done in the event of server failure.

一旦确定了具有已传输锁定状态的文件系统集,客户端就可以按照正常流程获取新服务器信息(通过fs_位置和fs_位置信息属性)并在新服务器上执行租约续期,除非fs_locations_info属性中的信息显示无法传输任何状态。如果服务器没有透明地传输状态,客户端将从新服务器接收NFS4ERR_STALE_CLIENTID,如上所述,然后客户端可以像在服务器发生故障时那样回收锁。

11.7.7.2. Transitions and the Lease_time Attribute
11.7.7.2. 转换和租约时间属性

In order that the client may appropriately manage its lease in the case of a file system transition, the destination server must establish proper values for the lease_time attribute.

为了在文件系统转换的情况下客户端可以适当地管理其租约,目标服务器必须为lease_time属性建立适当的值。

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 a lease granted by the source server. Upon transitions in which state is transferred transparently, the client is under no obligation to refetch 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, either because the associated servers are shown as having different eir_server_scope strings or because the client ID is rejected when presented to the new server, 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 of at least as long as the lease_time on the source server, in order to ensure that clients have ample time to reclaim their lock before potentially conflicting non-reclaimed locks are granted.

如果由于关联服务器显示为具有不同的eir_server_作用域字符串,或者由于客户端ID在呈现给新服务器时被拒绝,因此状态未被透明传输,则客户端应获取新(即目标)服务器上的租约时间值,并将其用于后续锁定请求。但是,服务器必须遵守至少与源服务器上的租约时间一样长的宽限期,以确保在授予潜在冲突的未回收锁之前,客户端有足够的时间回收其锁。

11.7.8. Write Verifiers and File System Transitions
11.7.8. 写验证程序和文件系统转换

In a file system transition, the two file systems may be clustered in the handling of unstably written data. When this is the case, and the two file systems belong to the same write-verifier class, write verifiers returned from one system may be compared to those returned by the other and superfluous writes avoided.

在文件系统转换中,两个文件系统可能在处理不稳定写入的数据时聚集在一起。在这种情况下,如果两个文件系统属于同一个写验证程序类,则可以将一个系统返回的写验证程序与另一个系统返回的写验证程序进行比较,从而避免多余的写操作。

When two file systems belong to different write-verifier classes, any verifier generated by one must not be compared to one provided by the other. Instead, it should be treated as not equal even when the values are identical.

当两个文件系统属于不同的写验证器类时,不能将其中一个生成的任何验证器与另一个提供的验证器进行比较。相反,即使值相同,也应将其视为不相等。

11.7.9. Readdir Cookies and Verifiers and File System Transitions
11.7.9. Readdir Cookie和验证程序以及文件系统转换

In a file system transition, the two file systems may be consistent in their handling of READDIR cookies and verifiers. When this is the case, and the two file systems belong to the same readdir class, READDIR cookies and verifiers from one system may be recognized by the other and READDIR operations started on one server may be validly continued on the other, simply by presenting the cookie and verifier returned by a READDIR operation done on the first file system to the second.

在文件系统转换中,两个文件系统在处理READDIR Cookie和验证器时可能是一致的。在这种情况下,并且两个文件系统属于相同的readdir类,来自一个系统的readdir Cookie和验证器可能会被另一个系统识别,并且在一台服务器上启动的readdir操作可能会在另一台服务器上有效地继续,只需将在第一个文件系统上执行的READDIR操作返回的cookie和验证器呈现给第二个文件系统即可。

When two file systems belong to different readdir classes, any READDIR cookie and verifier generated by one is not valid on the second, and must not be presented to that server by the client. The client should act as if the verifier was rejected.

当两个文件系统属于不同的readdir类时,其中一个文件系统生成的任何readdir cookie和验证器在第二个文件系统上都无效,客户端不得将其呈现给该服务器。客户应表现得好像验证者被拒绝一样。

11.7.10. File System Data and File System Transitions
11.7.10. 文件系统数据和文件系统转换

When multiple replicas exist and are used simultaneously or in succession by a client, applications using them will normally expect that they contain either the same data or data that is consistent with the normal sorts of changes that are made by other clients updating the data of the file system (with metadata being the same to the degree indicated by the fs_locations_info attribute). However, when multiple file systems are presented as replicas of one another, the precise relationship between the data of one and the data of another is not, as a general matter, specified by the NFSv4.1 protocol. It is quite possible to present as replicas file systems where the data of those file systems is sufficiently different that some applications have problems dealing with the transition between replicas. The namespace will typically be constructed so that applications can choose an appropriate level of support, so that in one position in the namespace a varied set of replicas will be listed, while in another only those that are up-to-date may be considered replicas. The protocol does define four special cases of the relationship among replicas to be specified by the server and relied upon by clients:

当存在多个副本并由客户端同时或连续使用时,使用它们的应用程序通常希望它们包含相同的数据或与更新文件系统数据的其他客户端所做的正常更改类型一致的数据(元数据与fs_locations_info属性指示的程度相同)。但是,当多个文件系统显示为彼此的副本时,NFSv4.1协议通常不会指定一个文件系统的数据与另一个文件系统的数据之间的精确关系。如果这些文件系统的数据差异很大,某些ap应用程序在处理副本之间的转换时存在问题。命名空间的构造通常使应用程序可以选择适当的支持级别,以便在命名空间中的一个位置列出一组不同的副本,而在另一个位置,只有最新的副本才可以被视为副本。protocol确实定义了由服务器指定并由客户端依赖的副本之间关系的四种特殊情况:

o When multiple server addresses correspond to the same actual server, as indicated by a common so_major_id field within the eir_server_owner field returned by EXCHANGE_ID, the client may depend on the fact that changes to data, metadata, or locks made on one file system are immediately reflected on others.

o 当多个服务器地址对应于同一个实际服务器时,如EXCHANGE_id返回的eir_server_owner字段中的公共so_major_id字段所示,客户端可能依赖于这样一个事实:对一个文件系统上的数据、元数据或锁所做的更改会立即反映到其他文件系统上。

o When multiple replicas exist and are used simultaneously by a client (see the FSLIB4_CLSIMUL definition within fs_locations_info), they must designate the same data. Where file systems are writable, a change made on one instance must be visible on all instances, immediately upon the earlier of the return of the modifying requester or the visibility of that change on any of the associated replicas. This allows a client to use these replicas simultaneously without any special adaptation to the fact that there are multiple replicas. In this case, locks (whether share reservations or byte-range locks) and delegations obtained on one replica are immediately reflected on all replicas, even though these locks will be managed under a set of client IDs.

o 当存在多个复制副本并由客户端同时使用时(请参阅fs_locations_info中的FSLIB4_CLSIMUL定义),它们必须指定相同的数据。如果文件系统是可写的,则在修改请求者返回或在任何关联副本上显示该更改之前,在一个实例上所做的更改必须立即在所有实例上可见。这允许客户端同时使用这些副本,而无需对存在多个副本这一事实进行任何特殊调整。在这种情况下,在一个副本上获得的锁(无论是共享保留还是字节范围锁)和委派会立即反映在所有副本上,即使这些锁将在一组客户端ID下进行管理。

o When one replica is designated as the successor instance to another existing instance after return NFS4ERR_MOVED (i.e., the case of migration), the client may depend on the fact that all changes written to stable storage on the original instance are written to stable storage of the successor (uncommitted writes are dealt with in Section 11.7.8).

o 当一个副本在返回NFS4ERR_MOVED(即迁移情况)后被指定为另一个现有实例的后续实例时,客户端可能依赖于这样一个事实,即写入原始实例稳定存储的所有更改都会写入后续实例的稳定存储(未提交的写入在第11.7.8节中处理)。

o Where a file system is not writable but represents a read-only copy (possibly periodically updated) of a writable file system, clients have similar requirements with regard to the propagation of updates. They may need a guarantee that any change visible on the original file system instance must be immediately visible on any replica before the client transitions access to that replica, in order to avoid any possibility that a client, in effecting a transition to a replica, will see any reversion in file system state. The specific means of this guarantee varies based on the value of the fss_type field that is reported as part of the fs_status attribute (see Section 11.11). Since these file systems are presumed to be unsuitable for simultaneous use, there is no specification of how locking is handled; in general, locks obtained on one file system will be separate from those on others. Since these are going to be read-only file systems, this is not expected to pose an issue for clients or applications.

o 当文件系统不可写,但表示可写文件系统的只读副本(可能定期更新)时,客户端对更新的传播有类似的要求。他们可能需要保证,在客户机将访问权转移到任何副本之前,在原始文件系统实例上可见的任何更改都必须立即在该副本上可见,以避免客户机在实现到副本的转换时看到文件系统状态的任何恢复。该保证的具体方式根据作为fs_状态属性一部分报告的fss_类型字段的值而有所不同(见第11.11节)。由于这些文件系统被认为不适合同时使用,因此没有关于如何处理锁定的规范;通常,在一个文件系统上获得的锁与在其他文件系统上获得的锁是分开的。由于这些将是只读文件系统,因此这不会对客户端或应用程序造成问题。

11.8. Effecting File System Referrals
11.8. 影响文件系统引用

Referrals are effected when an absent file system is encountered and one or more alternate locations are made available by the fs_locations or fs_locations_info attributes. The client will typically get an NFS4ERR_MOVED error, fetch the appropriate location information, and proceed to access the file system on a different server, even though it retains its logical position within the original namespace. Referrals differ from migration events in that they happen only when the client has not previously referenced the file system in question (so there is nothing to transition). Referrals can only come into effect when an absent file system is encountered at its root.

当遇到不存在的文件系统,并且fs_位置或fs_位置信息属性提供了一个或多个备用位置时,将影响引用。客户机通常会收到NFS4ERR_MOVED错误,获取适当的位置信息,并继续访问不同服务器上的文件系统,即使它在原始命名空间中保留其逻辑位置。引用与迁移事件的不同之处在于,它们仅在客户端以前没有引用过相关的文件系统时发生(因此不需要转换)。只有在根目录中遇到缺少的文件系统时,引用才能生效。

The examples given in the sections below are somewhat artificial in that an actual client will not typically do a multi-component look up, but will have cached information regarding the upper levels of the name hierarchy. However, these example are chosen to make the required behavior clear and easy to put within the scope of a small number of requests, without getting unduly into details of how specific clients might choose to cache things.

下面几节中给出的示例有些人为,因为实际的客户机通常不会进行多组件查找,但会缓存有关名称层次结构上层的信息。然而,选择这些示例是为了使所需的行为清晰,并且易于放在少量请求的范围内,而不必过分详细地说明特定客户机可能如何选择缓存内容。

11.8.1. Referral Example (LOOKUP)
11.8.1. 推荐示例(查找)

Let us suppose that the following COMPOUND is sent in an environment in which /this/is/the/path is absent from the target server. This may be for a number of reasons. It may be that the file system has moved, or it may be that the target server is functioning mainly, or solely, to refer clients to the servers on which various file systems are located.

假设在目标服务器中不存在/this/is/the/path的环境中发送以下化合物。这可能有很多原因。可能是文件系统已移动,也可能是目标服务器主要或仅在将客户端引用到各种文件系统所在的服务器。

o PUTROOTFH

o PUTROOTFH

o LOOKUP "this"

o 查找“此”

o LOOKUP "is"

o 查找“是”

o LOOKUP "the"

o 查找“the”

o LOOKUP "path"

o 查找“路径”

o GETFH

o GETFH

o GETATTR (fsid, fileid, size, time_modify)

o GETATTR(fsid、fileid、大小、时间\u修改)

Under the given circumstances, the following will be the result.

在给定的情况下,结果如下。

o PUTROOTFH --> NFS_OK. The current fh is now the root of the pseudo-fs.

o PUTROOTFH-->NFS\u正常。当前fh现在是伪fs的根。

o LOOKUP "this" --> NFS_OK. The current fh is for /this and is within the pseudo-fs.

o 查找“this”->NFS\u确定。当前fh适用于/且在伪fs范围内。

o LOOKUP "is" --> NFS_OK. The current fh is for /this/is and is within the pseudo-fs.

o 查找“是”-->NFS\u正常。当前fh为/this/is,且在伪fs范围内。

o LOOKUP "the" --> NFS_OK. The current fh is for /this/is/the and is within the pseudo-fs.

o 查找“the”-->NFS\u确定。当前fh用于/this/is/The,并且在伪fs内。

o LOOKUP "path" --> NFS_OK. The current fh is for /this/is/the/path and is within a new, absent file system, but ... the client will never see the value of that fh.

o 查找“路径”-->NFS\u确定。当前fh用于/this/is/The/path,并且位于一个新的、缺少的文件系统中,但是。。。客户永远看不到fh的价值。

o GETFH --> NFS4ERR_MOVED. Fails because current fh is in an absent file system at the start of the operation, and the specification makes no exception for GETFH.

o GETFH-->NFS4ERR\u已移动。失败,因为在操作开始时,当前fh位于缺少的文件系统中,并且规范对GETFH也不例外。

o GETATTR (fsid, fileid, size, time_modify). Not executed because the failure of the GETFH stops processing of the COMPOUND.

o GETATTR(fsid、fileid、大小、时间和修改)。未执行,因为GETFH的故障停止了化合物的处理。

Given the failure of the GETFH, the client has the job of determining the root of the absent file system and where to find that file system, i.e., the server and path relative to that server's root fh. Note that in this example, the client did not obtain filehandles and attribute information (e.g., fsid) for the intermediate directories, so that it would not be sure where the absent file system starts. It could be the case, for example, that /this/is/the is the root of the moved file system and that the reason that the look up of "path" succeeded is that the file system was not absent on that operation but was moved between the last LOOKUP and the GETFH (since COMPOUND is not atomic). Even if we had the fsids for all of the intermediate directories, we could have no way of knowing that /this/is/the/path was the root of a new file system, since we don't yet have its fsid.

考虑到GETFH的失败,客户端的任务是确定缺少的文件系统的根,以及在哪里找到该文件系统,即服务器和相对于该服务器的根fh的路径。请注意,在本例中,客户端没有获取中间目录的文件句柄和属性信息(例如,fsid),因此无法确定缺少的文件系统从何处启动。例如,可能是这样的情况,/this/is/the是移动的文件系统的根,查找“path”成功的原因是该操作中没有文件系统,而是在上次查找和GETFH之间移动(因为复合物不是原子的)。即使我们拥有所有中间目录的fsid,我们也无法知道/this/is/the/path是新文件系统的根,因为我们还没有它的fsid。

In order to get the necessary information, let us re-send the chain of LOOKUPs with GETFHs and GETATTRs to at least get the fsids so we can be sure where the appropriate file system boundaries are. The client could choose to get fs_locations_info at the same time but in most cases the client will have a good guess as to where file system boundaries are (because of where NFS4ERR_MOVED was, and was not, received) making fetching of fs_locations_info unnecessary.

为了获得必要的信息,让我们使用GETFHs和GETATTRs重新发送查找链,以至少获取fsid,这样我们就可以确定适当的文件系统边界在哪里。客户机可以选择同时获取fs_位置信息,但在大多数情况下,客户机可以很好地猜测文件系统边界的位置(因为NFS4ERR_移动的位置和未接收的位置),从而不需要获取fs_位置信息。

   OP01:  PUTROOTFH --> NFS_OK
        
   OP01:  PUTROOTFH --> NFS_OK
        

- Current fh is root of pseudo-fs.

- 当前fh是伪fs的根。

   OP02:  GETATTR(fsid) --> NFS_OK
        
   OP02:  GETATTR(fsid) --> NFS_OK
        

- Just for completeness. Normally, clients will know the fsid of the pseudo-fs as soon as they establish communication with a server.

- 只是为了完整。通常,客户机在与服务器建立通信后就会知道伪fs的fsid。

   OP03:  LOOKUP "this" --> NFS_OK
        
   OP03:  LOOKUP "this" --> NFS_OK
        
   OP04:  GETATTR(fsid) --> NFS_OK
        
   OP04:  GETATTR(fsid) --> NFS_OK
        

- Get current fsid to see where file system boundaries are. The fsid will be that for the pseudo-fs in this example, so no boundary.

- 获取当前fsid以查看文件系统边界的位置。fsid将是本例中伪fs的fsid,因此没有边界。

   OP05:  GETFH --> NFS_OK
        
   OP05:  GETFH --> NFS_OK
        

- Current fh is for /this and is within pseudo-fs.

- 当前fh适用于/此,并且在伪fs范围内。

   OP06:  LOOKUP "is" --> NFS_OK
        
   OP06:  LOOKUP "is" --> NFS_OK
        

- Current fh is for /this/is and is within pseudo-fs.

- 当前fh为/this/is,在伪fs范围内。

   OP07:  GETATTR(fsid) --> NFS_OK
        
   OP07:  GETATTR(fsid) --> NFS_OK
        

- Get current fsid to see where file system boundaries are. The fsid will be that for the pseudo-fs in this example, so no boundary.

- 获取当前fsid以查看文件系统边界的位置。fsid将是本例中伪fs的fsid,因此没有边界。

   OP08:  GETFH --> NFS_OK
        
   OP08:  GETFH --> NFS_OK
        

- Current fh is for /this/is and is within pseudo-fs.

- 当前fh为/this/is,在伪fs范围内。

   OP09:  LOOKUP "the" --> NFS_OK
        
   OP09:  LOOKUP "the" --> NFS_OK
        

- Current fh is for /this/is/the and is within pseudo-fs.

- 当前fh为/this/is/the,在伪fs范围内。

   OP10:  GETATTR(fsid) --> NFS_OK
        
   OP10:  GETATTR(fsid) --> NFS_OK
        

- Get current fsid to see where file system boundaries are. The fsid will be that for the pseudo-fs in this example, so no boundary.

- 获取当前fsid以查看文件系统边界的位置。fsid将是本例中伪fs的fsid,因此没有边界。

   OP11:  GETFH --> NFS_OK
        
   OP11:  GETFH --> NFS_OK
        

- Current fh is for /this/is/the and is within pseudo-fs.

- 当前fh为/this/is/the,在伪fs范围内。

   OP12:  LOOKUP "path" --> NFS_OK
        
   OP12:  LOOKUP "path" --> NFS_OK
        

- Current fh is for /this/is/the/path and is within a new, absent file system, but ...

- 当前fh用于/this/is/the/path,并且位于一个新的、缺少的文件系统中,但是。。。

- The client will never see the value of that fh.

- 客户永远看不到fh的价值。

   OP13:  GETATTR(fsid, fs_locations_info) --> NFS_OK
        
   OP13:  GETATTR(fsid, fs_locations_info) --> NFS_OK
        

- We are getting the fsid to know where the file system boundaries are. In this operation, the fsid will be different than that of the parent directory (which in turn was retrieved in OP10). Note that the fsid we are given will not necessarily be preserved at the new location. That fsid might be different, and in fact the fsid we have for this file system might be a valid fsid of a different file system on that new server.

- 我们正在让fsid知道文件系统边界在哪里。在这个操作中,fsid将不同于父目录的fsid(父目录又在OP10中检索到)。请注意,我们获得的fsid不一定会保留在新位置。该fsid可能不同,事实上,我们为该文件系统提供的fsid可能是新服务器上不同文件系统的有效fsid。

- In this particular case, we are pretty sure anyway that what has moved is /this/is/the/path rather than /this/is/the since we have the fsid of the latter and it is that of the pseudo-fs, which presumably cannot move. However, in other examples, we might not have this kind of information to rely on (e.g., /this/is/the might be a non-pseudo file system separate from /this/is/the/path), so we need to have other reliable source information on the boundary

- 在这个特殊的例子中,我们非常确定已经移动的是/this/is/the/path而不是/this/is/the,因为我们有后者的fsid,它是伪fs的fsid,它可能无法移动。但是,在其他示例中,我们可能没有此类信息可依赖(例如,/this/is/the可能是与/this/is/the/path分离的非伪文件系统),因此我们需要在边界上有其他可靠的源信息

of the file system that is moved. If, for example, the file system /this/is had moved, we would have a case of migration rather than referral, and once the boundaries of the migrated file system was clear we could fetch fs_locations_info.

移动的文件系统的名称。例如,如果文件系统/this/is已移动,我们将遇到迁移而不是引用的情况,并且一旦迁移的文件系统的边界清晰,我们就可以获取fs_位置信息。

- We are fetching fs_locations_info because the fact that we got an NFS4ERR_MOVED at this point means that it is most likely that this is a referral and we need the destination. Even if it is the case that /this/is/the is a file system that has migrated, we will still need the location information for that file system.

- 我们正在获取fs_locations_信息,因为我们在此时移动了一个NFS4ERR_,这意味着这很可能是一个转介,我们需要目的地。即使/this/is/the是已迁移的文件系统,我们仍然需要该文件系统的位置信息。

   OP14:  GETFH --> NFS4ERR_MOVED
        
   OP14:  GETFH --> NFS4ERR_MOVED
        

- Fails because current fh is in an absent file system at the start of the operation, and the specification makes no exception for GETFH. Note that this means the server will never send the client a filehandle from within an absent file system.

- 失败,因为在操作开始时,当前fh位于缺少的文件系统中,并且规范对GETFH也不例外。请注意,这意味着服务器永远不会从缺少的文件系统中向客户端发送文件句柄。

Given the above, the client knows where the root of the absent file system is (/this/is/the/path) by noting where the change of fsid occurred (between "the" and "path"). The fs_locations_info attribute also gives the client the actual location of the absent file system, so that the referral can proceed. The server gives the client the bare minimum of information about the absent file system so that there will be very little scope for problems of conflict between information sent by the referring server and information of the file system's home. No filehandles and very few attributes are present on the referring server, and the client can treat those it receives as transient information with the function of enabling the referral.

鉴于上述情况,客户机通过注意fsid的更改发生在何处(在“the”和“path”之间),知道缺少的文件系统的根在何处(/this/is/the/path)。fs_locations_info属性还为客户端提供缺少的文件系统的实际位置,以便可以继续进行引用。服务器向客户机提供关于缺少的文件系统的最低限度的信息,这样,在引用服务器发送的信息与文件系统的主信息之间发生冲突的问题的范围将非常小。引用服务器上没有文件句柄,属性也很少,客户端可以使用启用引用的功能将接收到的文件句柄和属性视为临时信息。

11.8.2. Referral Example (READDIR)
11.8.2. 参考示例(READDIR)

Another context in which a client may encounter referrals is when it does a READDIR on a directory in which some of the sub-directories are the roots of absent file systems.

客户机可能遇到引用的另一个上下文是,当它在一个目录上执行READDIR时,其中一些子目录是不存在的文件系统的根。

Suppose such a directory is read as follows:

假设这样一个目录如下所示:

o PUTROOTFH

o PUTROOTFH

o LOOKUP "this"

o 查找“此”

o LOOKUP "is"

o 查找“是”

o LOOKUP "the"

o 查找“the”

o READDIR (fsid, size, time_modify, mounted_on_fileid)

o READDIR(fsid、大小、时间、修改、在文件ID上挂载)

In this case, because rdattr_error is not requested, fs_locations_info is not requested, and some of the attributes cannot be provided, the result will be an NFS4ERR_MOVED error on the READDIR, with the detailed results as follows:

在这种情况下,由于未请求rdattr_错误,未请求fs_位置_信息,并且无法提供某些属性,因此结果将是READDIR上的NFS4ERR_移动错误,详细结果如下:

o PUTROOTFH --> NFS_OK. The current fh is at the root of the pseudo-fs.

o PUTROOTFH-->NFS\u正常。当前fh位于伪fs的根。

o LOOKUP "this" --> NFS_OK. The current fh is for /this and is within the pseudo-fs.

o 查找“this”->NFS\u确定。当前fh适用于/且在伪fs范围内。

o LOOKUP "is" --> NFS_OK. The current fh is for /this/is and is within the pseudo-fs.

o 查找“是”-->NFS\u正常。当前fh为/this/is,且在伪fs范围内。

o LOOKUP "the" --> NFS_OK. The current fh is for /this/is/the and is within the pseudo-fs.

o 查找“the”-->NFS\u确定。当前fh用于/this/is/The,并且在伪fs内。

o READDIR (fsid, size, time_modify, mounted_on_fileid) --> NFS4ERR_MOVED. Note that the same error would have been returned if /this/is/the had migrated, but it is returned because the directory contains the root of an absent file system.

o READDIR(fsid、大小、时间、修改、在文件ID上挂载)-->NFS4ERR\u已移动。请注意,如果/this/is/the已迁移,则会返回相同的错误,但返回该错误是因为该目录包含缺少的文件系统的根。

So now suppose that we re-send with rdattr_error:

现在假设我们用rdattr_错误重新发送:

o PUTROOTFH

o PUTROOTFH

o LOOKUP "this"

o 查找“此”

o LOOKUP "is"

o 查找“是”

o LOOKUP "the"

o 查找“the”

o READDIR (rdattr_error, fsid, size, time_modify, mounted_on_fileid)

o READDIR(rdattr错误、fsid、大小、时间、修改、在文件ID上挂载)

The results will be:

结果将是:

o PUTROOTFH --> NFS_OK. The current fh is at the root of the pseudo-fs.

o PUTROOTFH-->NFS\u正常。当前fh位于伪fs的根。

o LOOKUP "this" --> NFS_OK. The current fh is for /this and is within the pseudo-fs.

o 查找“this”->NFS\u确定。当前fh适用于/且在伪fs范围内。

o LOOKUP "is" --> NFS_OK. The current fh is for /this/is and is within the pseudo-fs.

o 查找“是”-->NFS\u正常。当前fh为/this/is,且在伪fs范围内。

o LOOKUP "the" --> NFS_OK. The current fh is for /this/is/the and is within the pseudo-fs.

o 查找“the”-->NFS\u确定。当前fh用于/this/is/The,并且在伪fs内。

o READDIR (rdattr_error, fsid, size, time_modify, mounted_on_fileid) --> NFS_OK. The attributes for directory entry with the component named "path" will only contain rdattr_error with the value NFS4ERR_MOVED, together with an fsid value and a value for mounted_on_fileid.

o READDIR(rdattr\u错误、fsid、大小、时间\u修改、在\u文件ID上装载)->NFS\u正常。名为“path”的组件的目录条目属性将仅包含值为NFS4ERR_MOVED的rdattr_error,以及fsid值和fileid上mounted_的值。

So suppose we do another READDIR to get fs_locations_info (although we could have used a GETATTR directly, as in Section 11.8.1).

因此,假设我们执行另一个READDIR来获取fs_locations_info(尽管我们可以直接使用GETATTR,如第11.8.1节所示)。

o PUTROOTFH

o PUTROOTFH

o LOOKUP "this"

o 查找“此”

o LOOKUP "is"

o 查找“是”

o LOOKUP "the"

o 查找“the”

o READDIR (rdattr_error, fs_locations_info, mounted_on_fileid, fsid, size, time_modify)

o READDIR(rdattr\u错误、fs\u位置\u信息、已装入的\u文件ID、fsid、大小、时间\u修改)

The results would be:

结果将是:

o PUTROOTFH --> NFS_OK. The current fh is at the root of the pseudo-fs.

o PUTROOTFH-->NFS\u正常。当前fh位于伪fs的根。

o LOOKUP "this" --> NFS_OK. The current fh is for /this and is within the pseudo-fs.

o 查找“this”->NFS\u确定。当前fh适用于/且在伪fs范围内。

o LOOKUP "is" --> NFS_OK. The current fh is for /this/is and is within the pseudo-fs.

o 查找“是”-->NFS\u正常。当前fh为/this/is,且在伪fs范围内。

o LOOKUP "the" --> NFS_OK. The current fh is for /this/is/the and is within the pseudo-fs.

o 查找“the”-->NFS\u确定。当前fh用于/this/is/The,并且在伪fs内。

o READDIR (rdattr_error, fs_locations_info, mounted_on_fileid, fsid, size, time_modify) --> NFS_OK. The attributes will be as shown below.

o READDIR(rdattr\u错误、fs\u位置\u信息、挂载\u文件ID、fsid、大小、时间\u修改)->NFS\u正常。属性如下所示。

The attributes for the directory entry with the component named "path" will only contain:

组件名为“path”的目录项的属性将仅包含:

o rdattr_error (value: NFS_OK)

o rdattr_错误(值:NFS_OK)

o fs_locations_info

o 财政司司长(地点)(资讯)

o mounted_on_fileid (value: unique fileid within referring file system)

o 在文件ID上装入文件(值:引用文件系统中的唯一文件ID)

o fsid (value: unique value within referring server)

o fsid(值:引用服务器中的唯一值)

The attributes for entry "path" will not contain size or time_modify because these attributes are not available within an absent file system.

条目“path”的属性将不包含size或time\u modify,因为这些属性在缺少的文件系统中不可用。

11.9. The Attribute fs_locations
11.9. 属性fs_位置

The fs_locations attribute is structured in the following way:

fs_locations属性的结构如下所示:

   struct fs_location4 {
           utf8str_cis     server<>;
           pathname4       rootpath;
   };
        
   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<>;
   };
        

The fs_location4 data type is used to represent the location of a file system by providing a server name and the path to the root of the file system within that server's namespace. When a set of servers have corresponding file systems at the same path within their namespaces, an array of server names may be provided. An entry in the server array is a UTF-8 string and represents one of a traditional DNS host name, IPv4 address, IPv6 address, or a zero-length string. An IPv4 or IPv6 address is represented as a universal address (see Section 3.3.9 and [15]), minus the netid, and either with or without the trailing ".p1.p2" suffix that represents the port number. If the suffix is omitted, then the default port, 2049, SHOULD be assumed. A zero-length string SHOULD be used to indicate the current address being used for the RPC call. It is not a requirement that all servers that share the same rootpath be listed in one fs_location4 instance. The array of server names is provided for convenience. Servers that share the same rootpath may also be listed in separate fs_location4 entries in the fs_locations attribute.

fs_location4数据类型用于表示文件系统的位置,方法是提供服务器名称和指向该服务器命名空间中文件系统根目录的路径。当一组服务器在其名称空间内的同一路径上具有相应的文件系统时,可以提供服务器名称数组。服务器阵列中的条目是UTF-8字符串,表示传统DNS主机名、IPv4地址、IPv6地址或零长度字符串之一。IPv4或IPv6地址表示为通用地址(见第3.3.9节和[15]),减去netid,并带有或不带有表示端口号的后缀“.p1.p2”。如果省略后缀,则应假定默认端口2049。长度为零的字符串应用于指示用于RPC调用的当前地址。不要求共享同一根路径的所有服务器都列在一个fs_location4实例中。为方便起见,提供了服务器名称数组。共享同一根路径的服务器也可能列在fs_locations属性的单独fs_location4条目中。

The fs_locations4 data type and fs_locations attribute contain an array of such locations. Since the namespace of each server may be constructed differently, the "fs_root" field is provided. The path represented by fs_root represents the location of the file system in the current server's namespace, i.e., that of the server from which the fs_locations attribute was obtained. The fs_root path is meant to aid the client by clearly referencing the root of the file system

fs_locations4数据类型和fs_locations属性包含此类位置的数组。由于每个服务器的名称空间的构造可能不同,因此提供了“fs_root”字段。由fs_root表示的路径表示文件系统在当前服务器名称空间中的位置,即获取fs_locations属性的服务器的位置。fs_根路径旨在通过明确引用文件系统的根来帮助客户机

whose locations are being reported, no matter what object within the current file system the current filehandle designates. The fs_root is simply the pathname the client used to reach the object on the current server (i.e., the object to which the fs_locations attribute applies).

报告其位置,无论当前文件句柄指定当前文件系统中的哪个对象。fs_根只是客户端用来访问当前服务器上的对象(即fs_locations属性所应用的对象)的路径名。

When the fs_locations attribute is interrogated and there are no alternate file system locations, the server SHOULD return a zero-length array of fs_location4 structures, together with a valid fs_root.

当查询fs_locations属性且没有备用文件系统位置时,服务器应返回fs_location4结构的零长度数组以及有效的fs_根。

As an example, suppose there is a replicated file system located at two servers (servA and servB). At servA, the file system is located at path /a/b/c. At, servB the file system is located at path /x/y/z. If the client were to obtain the fs_locations value for the directory at /a/b/c/d, it might not necessarily know that the file system's root is located in servA's namespace 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 an fs_root value of /a/b/c and two entries in fs_locations. One entry in fs_locations will be for itself (servA) and the other will be for servB with a path of /x/y/z. With this information, the client is able to substitute /x/y/z for the /a/b/c at the beginning of its access path and construct /x/y/z/d to use for the new server.

例如,假设有一个复制文件系统位于两台服务器(servA和servB)上。在servA,文件系统位于路径/a/b/c。在,servB文件系统位于路径/x/y/z。如果客户端要获取/a/b/c/d目录的fs_locations值,则它可能不一定知道文件系统的根位于/a/b/c的servA命名空间中。当客户机切换到servB时,它需要确定它在servA上首先引用的目录现在由servB上的路径/x/y/z/d表示。为了便于实现这一点,servA提供的fs_locations属性的fs_根值为/a/b/c,在fs_位置中有两个条目。fs_位置中的一个条目将用于自身(servA),另一个条目将用于路径为/x/y/z的servB。有了这些信息,客户端可以在其访问路径的开始处用/x/y/z替换/a/b/c,并构造/x/y/z/d以用于新服务器。

Note that there is no requirement that the number of components in each rootpath be the same; there is no relation between the number of components in rootpath or fs_root, and none of the components in a rootpath and fs_root have to be the same. In the above example, we could have had a third element in the locations array, with server equal to "servC" and rootpath equal to "/I/II", and a fourth element in locations with server equal to "servD" and rootpath equal to "/aleph/beth/gimel/daleth/he".

注意,没有要求每个根路径中的组件数量相同;rootpath或fs_root中的组件数量之间没有关系,rootpath和fs_root中的组件都不必相同。在上面的示例中,我们可以在locations数组中有第三个元素,其中server等于“servC”,rootpath等于“/I/II”;在locations中有第四个元素,server等于“servD”,rootpath等于“/aleph/beth/gimel/daleth/he”。

The relationship between fs_root to a rootpath is that the client replaces the pathname indicated in fs_root for the current server for the substitute indicated in rootpath for the new server.

fs_root与rootpath之间的关系是,客户端将当前服务器的fs_root中指示的路径名替换为新服务器的rootpath中指示的替换项。

   For an example of a referred or migrated file system, suppose there
   is a file system located at serv1.  At serv1, the file system is
   located at /az/buky/vedi/glagoli.  The client finds that object at
   glagoli has migrated (or is a referral).  The client gets the
   fs_locations attribute, which contains an fs_root of /az/buky/vedi/
   glagoli, and one element in the locations array, with server equal to
        
   For an example of a referred or migrated file system, suppose there
   is a file system located at serv1.  At serv1, the file system is
   located at /az/buky/vedi/glagoli.  The client finds that object at
   glagoli has migrated (or is a referral).  The client gets the
   fs_locations attribute, which contains an fs_root of /az/buky/vedi/
   glagoli, and one element in the locations array, with server equal to
        

serv2, and rootpath equal to /izhitsa/fita. The client replaces /az/ buky/vedi/glagoli with /izhitsa/fita, and uses the latter pathname on serv2.

serv2,根路径等于/izhitsa/fita。客户端将/az/buky/vedi/glagoli替换为/izhitsa/fita,并在serv2上使用后者的路径名。

Thus, the server MUST return an fs_root that is equal to the path the client used to reach the object to which the fs_locations attribute applies. Otherwise, the client cannot determine the new path to use on the new server.

因此,服务器必须返回一个fs_根,该根等于客户端用来到达应用fs_locations属性的对象的路径。否则,客户端无法确定要在新服务器上使用的新路径。

Since the fs_locations attribute lacks information defining various attributes of the various file system choices presented, it SHOULD only be interrogated and used when fs_locations_info is not available. When fs_locations is used, information about the specific locations should be assumed based on the following rules.

由于fs_locations属性缺少定义所提供的各种文件系统选项的各种属性的信息,因此仅当fs_locations_信息不可用时才应查询并使用它。使用fs_位置时,应根据以下规则假定有关特定位置的信息。

The following rules are general and apply irrespective of the context.

以下规则是通用的,适用于任何上下文。

o All listed file system instances should be considered as of the same handle class, if and only if, the current fh_expire_type attribute does not include the FH4_VOL_MIGRATION bit. Note that in the case of referral, filehandle issues do not apply since there can be no filehandles known within the current file system, nor is there any access to the fh_expire_type attribute on the referring (absent) file system.

o 当且仅当当前fh_expire_type属性不包括FH4_VOL_迁移位时,所有列出的文件系统实例都应视为同一句柄类。请注意,在引用的情况下,filehandle问题不适用,因为当前文件系统中可能没有已知的filehandles,也不存在对引用(不存在)文件系统上的fh_expire_type属性的任何访问。

o All listed file system instances should be considered as of the same fileid class if and only if the fh_expire_type attribute indicates persistent filehandles and does not include the FH4_VOL_MIGRATION bit. Note that in the case of referral, fileid issues do not apply since there can be no fileids known within the referring (absent) file system, nor is there any access to the fh_expire_type attribute.

o 当且仅当fh_expire_type属性指示持久文件句柄且不包括FH4_VOL_迁移位时,所有列出的文件系统实例都应被视为同一fileid类。请注意,在引用的情况下,fileid问题不适用,因为引用(不存在)文件系统中可能没有已知的fileid,也不存在对fh_expire_type属性的任何访问。

o All file system instances servers should be considered as of different change classes.

o 应将所有文件系统实例服务器视为不同的更改类。

For other class assignments, handling of file system transitions depends on the reasons for the transition:

对于其他类分配,文件系统转换的处理取决于转换的原因:

o When the transition is due to migration, that is, the client was directed to a new file system after receiving an NFS4ERR_MOVED error, the target should be treated as being of the same write-verifier class as the source.

o 如果转换是由于迁移造成的,即客户端在收到NFS4ERR_MOVED错误后被定向到新的文件系统,则应将目标视为与源属于同一写验证程序类。

o When the transition is due to failover to another replica, that is, the client selected another replica without receiving an NFS4ERR_MOVED error, the target should be treated as being of a different write-verifier class from the source.

o 如果转换是由于故障转移到另一个副本,即客户端选择了另一个副本而未接收到NFS4ERR_MOVED错误,则应将目标视为与源不同的写入验证器类。

The specific choices reflect typical implementation patterns for failover and controlled migration, respectively. Since other choices are possible and useful, this information is better obtained by using fs_locations_info. When a server implementation needs to communicate other choices, it MUST support the fs_locations_info attribute.

具体的选择分别反映了故障转移和受控迁移的典型实现模式。由于其他选择是可能且有用的,因此使用fs_位置_信息可以更好地获取此信息。当服务器实现需要传达其他选择时,它必须支持fs\u locations\u info属性。

See Section 21 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操作所使用的安全风格建议的讨论,请参见第21节。

11.10. The Attribute fs_locations_info
11.10. 属性fs\u locations\u info

The fs_locations_info attribute is intended as a more functional replacement for fs_locations that will continue to exist and be supported. Clients can use it to get a more complete set of information about alternative file system locations. When the server does not support fs_locations_info, fs_locations can be used to get a subset of the information. A server that supports fs_locations_info MUST support fs_locations as well.

fs_locations_info属性旨在更有效地替代将继续存在并受支持的fs_位置。客户机可以使用它来获取有关其他文件系统位置的更完整的信息集。当服务器不支持fs_位置信息时,可以使用fs_位置获取信息的子集。支持fs\U位置信息的服务器也必须支持fs\U位置。

There is additional information present in fs_locations_info, that is not available in fs_locations:

在fs\U位置\U信息中有其他信息,但在fs\U位置中不可用:

o Attribute continuity information. This information will allow a client to select a location that meets the transparency requirements of the applications accessing the data and to leverage optimizations due to the server guarantees of attribute continuity (e.g., if between multiple server locations the change attribute of a file of the file system is continuous, the client does not have to invalidate the file's cache if the change attribute is the same among all locations).

o 属性连续性信息。此信息将允许客户端选择满足访问数据的应用程序透明度要求的位置,并利用服务器对属性连续性的保证而进行的优化(例如,如果在多个服务器位置之间,文件系统文件的更改属性是连续的,则如果所有位置之间的更改属性相同,则客户端不必使文件的缓存无效)。

o File system identity information that indicates when multiple replicas, from the client's point of view, correspond to the same target file system, allowing them to be used interchangeably, without disruption, as multiple paths to the same thing.

o 文件系统标识信息,从客户端的角度指示多个副本何时对应于同一目标文件系统,从而允许它们作为指向同一对象的多条路径互换使用,而不会中断。

o Information that will bear on the suitability of various replicas, depending on the use that the client intends. For example, many applications need an absolutely up-to-date copy (e.g., those that write), while others may only need access to the most up-to-date copy reasonably available.

o 与各种副本的适用性有关的信息,具体取决于客户的使用意图。例如,许多应用程序需要绝对最新的副本(例如,那些写入的应用程序),而其他应用程序可能只需要访问合理可用的最新副本。

o Server-derived preference information for replicas, which can be used to implement load-balancing while giving the client the entire file system list to be used in case the primary fails.

o 服务器派生的副本首选项信息,可用于实现负载平衡,同时为客户端提供整个文件系统列表,以便在主副本出现故障时使用。

The fs_locations_info attribute is structured similarly to the fs_locations attribute. A top-level structure (fs_locations_info4) contains the entire attribute including the root pathname of the file system and an array of lower-level structures that define replicas that share a common rootpath on their respective servers. The lower-level structure in turn (fs_locations_item4) contains a specific pathname and information on one or more individual server replicas. For that last lowest-level, fs_locations_info has an fs_locations_server4 structure that contains per-server-replica information in addition to the server name. This per-server-replica information includes a nominally opaque array, fls_info, in which specific pieces of information are located at the specific indices listed below.

fs_locations_info属性的结构类似于fs_locations属性。顶级结构(fs_locations_info4)包含整个属性,包括文件系统的根路径名和一系列较低级别的结构,这些结构定义了在各自服务器上共享公共根路径的副本。较低级别的结构(fs_locations_item4)依次包含一个特定的路径名和一个或多个单独服务器副本的信息。对于最后一个最低级别,fs_locations_info具有一个fs_locations_server4结构,该结构除了包含服务器名称外,还包含每服务器副本信息。此每服务器副本信息包括一个名义上不透明的数组fls_info,其中特定的信息片段位于下面列出的特定索引处。

The attribute will always contain at least a single fs_locations_server entry. Typically, this will be an entry with the FS4LIGF_CUR_REQ flag set, although in the case of a referral there will be no entry with that flag set.

该属性将始终至少包含一个fs\u位置\u服务器条目。通常,这将是一个设置了FS4LIGF_CUR_REQ标志的条目,尽管在引用的情况下,不会有设置了该标志的条目。

It should be noted that fs_locations_info attributes returned by servers for various replicas may differ for various reasons. One server may know about a set of replicas that are not known to other servers. Further, compatibility attributes may differ. Filehandles might be of the same class going from replica A to replica B but not going in the reverse direction. This might happen because the filehandles are the same, but replica B's server implementation might not have provision to note and report that equivalence.

应该注意的是,由于各种原因,服务器为各种副本返回的fs_locations_info属性可能会有所不同。一台服务器可能知道一组其他服务器不知道的复制副本。此外,兼容性属性可能不同。从副本A到副本B的文件句柄可能属于同一个类,但不是反向的。这可能是因为文件句柄相同,但副本B的服务器实现可能没有记录和报告这种等价性的规定。

The fs_locations_info attribute consists of a root pathname (fli_fs_root, just like fs_root in the fs_locations attribute), together with an array of fs_location_item4 structures. The fs_location_item4 structures in turn consist of a root pathname (fli_rootpath) together with an array (fli_entries) of elements of data type fs_locations_server4, all defined as follows.

fs_locations_info属性由根路径名(fli_fs_root,就像fs_locations属性中的fs_root)和fs_location_item4结构数组组成。fs_location_item4结构依次由根路径名(fli_rootpath)和数据类型fs_locations_server4的元素数组(fli_entries)组成,所有这些元素的定义如下。

   /*
    * Defines an individual server replica
    */
   struct  fs_locations_server4 {
           int32_t         fls_currency;
           opaque          fls_info<>;
           utf8str_cis     fls_server;
   };
        
   /*
    * Defines an individual server replica
    */
   struct  fs_locations_server4 {
           int32_t         fls_currency;
           opaque          fls_info<>;
           utf8str_cis     fls_server;
   };
        
   /*
    * Byte indices of items within
    * fls_info: flag fields, class numbers,
    * bytes indicating ranks and orders.
    */
   const FSLI4BX_GFLAGS            = 0;
   const FSLI4BX_TFLAGS            = 1;
   const FSLI4BX_CLSIMUL           = 2;
   const FSLI4BX_CLHANDLE          = 3;
   const FSLI4BX_CLFILEID          = 4;
   const FSLI4BX_CLWRITEVER        = 5;
   const FSLI4BX_CLCHANGE          = 6;
   const FSLI4BX_CLREADDIR         = 7;
        
   /*
    * Byte indices of items within
    * fls_info: flag fields, class numbers,
    * bytes indicating ranks and orders.
    */
   const FSLI4BX_GFLAGS            = 0;
   const FSLI4BX_TFLAGS            = 1;
   const FSLI4BX_CLSIMUL           = 2;
   const FSLI4BX_CLHANDLE          = 3;
   const FSLI4BX_CLFILEID          = 4;
   const FSLI4BX_CLWRITEVER        = 5;
   const FSLI4BX_CLCHANGE          = 6;
   const FSLI4BX_CLREADDIR         = 7;
        
   const FSLI4BX_READRANK          = 8;
   const FSLI4BX_WRITERANK         = 9;
   const FSLI4BX_READORDER         = 10;
   const FSLI4BX_WRITEORDER        = 11;
        
   const FSLI4BX_READRANK          = 8;
   const FSLI4BX_WRITERANK         = 9;
   const FSLI4BX_READORDER         = 10;
   const FSLI4BX_WRITEORDER        = 11;
        
   /*
    * Bits defined within the general flag byte.
    */
   const FSLI4GF_WRITABLE          = 0x01;
   const FSLI4GF_CUR_REQ           = 0x02;
   const FSLI4GF_ABSENT            = 0x04;
   const FSLI4GF_GOING             = 0x08;
   const FSLI4GF_SPLIT             = 0x10;
        
   /*
    * Bits defined within the general flag byte.
    */
   const FSLI4GF_WRITABLE          = 0x01;
   const FSLI4GF_CUR_REQ           = 0x02;
   const FSLI4GF_ABSENT            = 0x04;
   const FSLI4GF_GOING             = 0x08;
   const FSLI4GF_SPLIT             = 0x10;
        
   /*
    * Bits defined within the transport flag byte.
    */
   const FSLI4TF_RDMA              = 0x01;
        
   /*
    * Bits defined within the transport flag byte.
    */
   const FSLI4TF_RDMA              = 0x01;
        
   /*
    * Defines a set of replicas sharing
    * a common value of the rootpath
    * with in the corresponding
    * single-server namespaces.
    */
   struct  fs_locations_item4 {
           fs_locations_server4    fli_entries<>;
           pathname4               fli_rootpath;
   };
        
   /*
    * Defines a set of replicas sharing
    * a common value of the rootpath
    * with in the corresponding
    * single-server namespaces.
    */
   struct  fs_locations_item4 {
           fs_locations_server4    fli_entries<>;
           pathname4               fli_rootpath;
   };
        
   /*
    * Defines the overall structure of
    * the fs_locations_info attribute.
    */
   struct  fs_locations_info4 {
           uint32_t                fli_flags;
           int32_t                 fli_valid_for;
           pathname4               fli_fs_root;
           fs_locations_item4      fli_items<>;
   };
        
   /*
    * Defines the overall structure of
    * the fs_locations_info attribute.
    */
   struct  fs_locations_info4 {
           uint32_t                fli_flags;
           int32_t                 fli_valid_for;
           pathname4               fli_fs_root;
           fs_locations_item4      fli_items<>;
   };
        
   /*
    * Flag bits in fli_flags.
    */
   const FSLI4IF_VAR_SUB           = 0x00000001;
        
   /*
    * Flag bits in fli_flags.
    */
   const FSLI4IF_VAR_SUB           = 0x00000001;
        

typedef fs_locations_info4 fattr4_fs_locations_info;

typedef fs_位置信息4 fattr4 fs_位置信息;

As noted above, the fs_locations_info attribute, when supported, may be requested of absent file systems without causing NFS4ERR_MOVED to be returned. It is generally expected that it will be available for both present and absent file systems even if only a single fs_locations_server4 entry is present, designating the current (present) file system, or two fs_locations_server4 entries designating the previous location of an absent file system (the one just referenced) and its successor location. Servers are strongly urged to support this attribute on all file systems if they support it on any file system.

如上所述,当支持fs_locations_info属性时,可能会请求缺少的文件系统,而不会导致返回NFS4ERR_MOVED。一般认为,即使只有一个fs_locations_server4条目(指定当前(当前)文件系统)或两个fs_locations_server4条目(指定缺失文件系统(刚才引用的文件系统)的前一个位置)及其后续位置,它也可用于现有和缺失文件系统。强烈建议服务器在所有文件系统上支持此属性(如果它们在任何文件系统上支持此属性)。

The data presented in the fs_locations_info attribute may be obtained by the server in any number of ways, including specification by the administrator or by current protocols for transferring data among replicas and protocols not yet developed. NFSv4.1 only defines how this information is presented by the server to the client.

服务器可以通过多种方式获取fs_locations_info属性中显示的数据,包括管理员指定的方式或在副本之间传输数据的当前协议以及尚未开发的协议。NFSv4.1仅定义服务器如何向客户端呈现此信息。

11.10.1. The fs_locations_server4 Structure
11.10.1. fs_位置_服务器4结构

The fs_locations_server4 structure consists of the following items:

fs_locations_server4结构由以下项目组成:

o An indication of how up-to-date the file system is (fls_currency) in seconds. This value is relative to the master copy. A negative value indicates that the server is unable to give any reasonably useful value here. A value of zero indicates that the file system is the actual writable data or a reliably coherent and fully up-to-date copy. Positive values indicate how out-of-date this copy can normally be before it is considered for update. Such a value is not a guarantee that such updates will always be performed on the required schedule but instead serves as a hint about how far the copy of the data would be expected to be behind the most up-to-date copy.

o 以秒为单位指示文件系统的最新状态(fls_货币)。此值与主副本相关。负值表示服务器无法在此处提供任何合理有用的值。值为零表示文件系统是实际的可写数据或可靠一致且完全最新的副本。正值表示在考虑更新之前,此副本通常会过期的程度。这样的值并不能保证这些更新总是按照要求的时间表执行,而是作为数据副本在最新副本之后的预期距离的提示。

o A counted array of one-byte values (fls_info) containing information about the particular file system instance. This data includes general flags, transport capability flags, file system equivalence class information, and selection priority information. The encoding will be discussed below.

o 包含特定文件系统实例信息的单字节值(fls_info)的计数数组。这些数据包括常规标志、传输能力标志、文件系统等价类信息和选择优先级信息。下面将讨论编码。

o The server string (fls_server). For the case of the replica currently being accessed (via GETATTR), a zero-length string MAY be used to indicate the current address being used for the RPC call. The fls_server field can also be an IPv4 or IPv6 address, formatted the same way as an IPv4 or IPv6 address in the "server" field of the fs_location4 data type (see Section 11.9).

o 服务器字符串(fls_服务器)。对于当前正在访问的复制副本(通过GETATTR),可以使用零长度字符串来指示用于RPC调用的当前地址。fls_服务器字段也可以是IPv4或IPv6地址,格式与fs_location4数据类型的“服务器”字段中的IPv4或IPv6地址相同(请参阅第11.9节)。

Data within the fls_info array is in the form of 8-bit data items with constants giving the offsets within the array of various values describing this particular file system instance. This style of definition was chosen, in preference to explicit XDR structure definitions for these values, for a number of reasons.

fls_info数组中的数据以8位数据项的形式存在,这些数据项的常数表示数组中描述此特定文件系统实例的各种值的偏移量。出于多种原因,选择这种类型的定义,优先于这些值的显式XDR结构定义。

o The kinds of data in the fls_info array, representing flags, file system classes, and priorities among sets of file systems representing the same data, are such that 8 bits provide a quite acceptable range of values. Even where there might be more than 256 such file system instances, having more than 256 distinct classes or priorities is unlikely.

o fls_info数组中的数据类型表示标志、文件系统类以及表示相同数据的文件系统集合之间的优先级,因此8位提供了一个可接受的值范围。即使有超过256个这样的文件系统实例,也不可能有超过256个不同的类或优先级。

o Explicit definition of the various specific data items within XDR would limit expandability in that any extension within a subsequent minor version would require yet another attribute, leading to specification and implementation clumsiness.

o XDR中各种特定数据项的显式定义将限制可扩展性,因为后续次要版本中的任何扩展都需要另一个属性,从而导致规范和实现的笨拙。

o Such explicit definitions would also make it impossible to propose Standards Track extensions apart from a full minor version.

o 这种明确的定义也使得除了完整的次要版本之外,不可能提出标准轨道扩展。

This encoding scheme can be adapted to the specification of multi-byte numeric values, even though none are currently defined. If extensions are made via Standards Track RFCs, multi-byte quantities will be encoded as a range of bytes with a range of indices, with the byte interpreted in big-endian byte order. Further, any such index assignments are constrained so that the relevant quantities will not cross XDR word boundaries.

此编码方案可适用于多字节数值的规范,即使当前未定义任何数值。如果扩展是通过标准磁道RFC进行的,则多字节数量将被编码为一个具有一系列索引的字节范围,并以大端字节顺序解释该字节。此外,任何此类索引分配都受到约束,以便相关数量不会跨越XDR单词边界。

The set of fls_info data is subject to expansion in a future minor version, or in a Standards Track RFC, within the context of a single minor version. The server SHOULD NOT send and the client MUST NOT use indices within the fls_info array that are not defined in Standards Track RFCs.

fls_信息数据集将在未来的次要版本中进行扩展,或在单个次要版本的上下文中在标准跟踪RFC中进行扩展。服务器不应发送,客户端也不得使用fls_info数组中未在标准跟踪RFC中定义的索引。

The fls_info array contains:

fls_信息数组包含:

o Two 8-bit flag fields, one devoted to general file-system characteristics and a second reserved for transport-related capabilities.

o 两个8位标志字段,一个用于一般文件系统特性,另一个用于传输相关功能。

o Six 8-bit class values that define various file system equivalence classes as explained below.

o 六个8位类值,定义各种文件系统等价类,如下所述。

o Four 8-bit priority values that govern file system selection as explained below.

o 四个控制文件系统选择的8位优先级值,如下所述。

The general file system characteristics flag (at byte index FSLI4BX_GFLAGS) has the following bits defined within it:

通用文件系统特性标志(位于字节索引FSLI4BX_GFLAGS)中定义了以下位:

o FSLI4GF_WRITABLE indicates that this file system target is writable, allowing it to be selected by clients that may need to write on this file system. When the current file system instance is writable and is defined as of the same simultaneous use class (as specified by the value at index FSLI4BX_CLSIMUL) to which the client was previously writing, then it must incorporate within its data any committed write made on the source file system instance. See Section 11.7.8, which discusses the write-verifier class. While there is no harm in not setting this flag for a file system that turns out to be writable, turning the flag on for a read-only

o FSLI4GF_writeable表示此文件系统目标是可写的,允许可能需要在此文件系统上写入的客户端选择它。如果当前文件系统实例是可写的,并且被定义为与客户端先前写入的同步使用类(由索引FSLI4BX_CLSIMUL处的值指定)相同,则它必须将对源文件系统实例进行的任何提交写入合并到其数据中。请参阅第11.7.8节,其中讨论了写入验证器类。虽然不为可写的文件系统设置此标志没有害处,但为只读文件系统启用此标志

file system can cause problems for clients that select a migration or replication target based on the flag and then find themselves unable to write.

文件系统可能会导致客户机出现问题,这些客户机根据标志选择迁移或复制目标,然后发现自己无法写入。

o FSLI4GF_CUR_REQ indicates that this replica is the one on which the request is being made. Only a single server entry may have this flag set and, in the case of a referral, no entry will have it.

o FSLI4GF_CUR_REQ表示此复制副本是发出请求的复制副本。只有一个服务器条目可以设置此标志,在引用的情况下,任何条目都不会设置此标志。

o FSLI4GF_ABSENT indicates that this entry corresponds to an absent file system replica. It can only be set if FSLI4GF_CUR_REQ is set. When both such bits are set, it indicates that a file system instance is not usable but that the information in the entry can be used to determine the sorts of continuity available when switching from this replica to other possible replicas. Since this bit can only be true if FSLI4GF_CUR_REQ is true, the value could be determined using the fs_status attribute, but the information is also made available here for the convenience of the client. An entry with this bit, since it represents a true file system (albeit absent), does not appear in the event of a referral, but only when a file system has been accessed at this location and has subsequently been migrated.

o FSLI4GF_缺席表示此条目对应于缺席的文件系统副本。仅当设置了FSLI4GF_CUR_REQ时,才能设置该值。当设置了这两个位时,表示文件系统实例不可用,但条目中的信息可用于确定从该副本切换到其他可能副本时可用的连续性类型。由于只有当FSLI4GF_CUR_REQ为true时,该位才为true,因此可以使用fs_status属性确定该值,但为了方便客户端,此处也提供了该信息。具有此位的条目,因为它表示真实的文件系统(尽管不存在),在引用时不会出现,但仅当文件系统在此位置被访问并随后被迁移时才会出现。

o FSLI4GF_GOING indicates that a replica, while still available, should not be used further. The client, if using it, should make an orderly transfer to another file system instance as expeditiously as possible. It is expected that file systems going out of service will be announced as FSLI4GF_GOING some time before the actual loss of service. It is also expected that the fli_valid_for value will be sufficiently small to allow clients to detect and act on scheduled events, while large enough that the cost of the requests to fetch the fs_locations_info values will not be excessive. Values on the order of ten minutes seem reasonable.

o FSLI4GF_gong表示复制副本虽然仍然可用,但不应进一步使用。如果使用它,客户机应尽快有序地传输到另一个文件系统实例。预计文件系统停止服务将在实际服务丢失前的某个时间宣布为FSLI4GF_。另外,预计fli_valid_for值将足够小,以允许客户端检测预定事件并对其采取行动,而足够大,以使获取fs_locations_info值的请求成本不会过高。10分钟左右的数值似乎是合理的。

When this flag is seen as part of a transition into a new file system, a client might choose to transfer immediately to another replica, or it may reference the current file system and only transition when a migration event occurs. Similarly, when this flag appears as a replica in the referral, clients would likely avoid being referred to this instance whenever there is another choice.

当此标志被视为到新文件系统的转换的一部分时,客户端可能会选择立即传输到另一个副本,或者它可能会引用当前文件系统,并且仅在发生迁移事件时才进行转换。类似地,当此标志在引用中显示为副本时,只要有其他选择,客户机都可能避免被引用到此实例。

o FSLI4GF_SPLIT indicates that when a transition occurs from the current file system instance to this one, the replacement may consist of multiple file systems. In this case, the client has to be prepared for the possibility that objects on the same file system before migration will be on different ones after. Note

o FSLI4GF_SPLIT表示当从当前文件系统实例转换到此实例时,替换可能由多个文件系统组成。在这种情况下,客户机必须做好准备,以防在迁移之前相同文件系统上的对象在迁移之后位于不同的文件系统上。笔记

that FSLI4GF_SPLIT is not incompatible with the file systems belonging to the same fileid class since, if one has a set of fileids that are unique within a file system, each subset assigned to a smaller file system after migration would not have any conflicts internal to that file system.

FSLI4GF_拆分与属于同一fileid类的文件系统不兼容,因为如果一个文件系统中有一组唯一的fileid,则迁移后分配给较小文件系统的每个子集在该文件系统内部不会有任何冲突。

A client, in the case of a split file system, will interrogate existing files with which it has continuing connection (it is free to simply forget cached filehandles). If the client remembers the directory filehandle associated with each open file, it may proceed upward using LOOKUPP to find the new file system boundaries. Note that in the event of a referral, there will not be any such files and so these actions will not be performed. Instead, a reference to a portion of the original file system now split off into other file systems will encounter an fsid change and possibly a further referral.

在拆分文件系统的情况下,客户机将询问与其有持续连接的现有文件(可以随意忘记缓存的文件句柄)。如果客户机记住了与每个打开的文件关联的目录文件句柄,则可以使用LOOKUPP向上查找新的文件系统边界。请注意,在转介的情况下,不会有任何此类文件,因此不会执行这些操作。相反,对现在拆分为其他文件系统的原始文件系统的一部分的引用将遇到fsid更改,可能还会遇到进一步的引用。

Once the client recognizes that one file system has been split into two, it can prevent the disruption of running applications by presenting the two file systems as a single one until a convenient point to recognize the transition, such as a restart. This would require a mapping from the server's fsids to fsids as seen by the client, but this is already necessary for other reasons. As noted above, existing fileids within the two descendant file systems will not conflict. Providing non-conflicting fileids for newly created files on the split file systems is the responsibility of the server (or servers working in concert). The server can encode filehandles such that filehandles generated before the split event can be discerned from those generated after the split, allowing the server to determine when the need for emulating two file systems as one is over.

一旦客户机意识到一个文件系统已被拆分为两个,它就可以通过将两个文件系统显示为一个文件系统来防止正在运行的应用程序中断,直到一个方便的时间点来识别转换,例如重新启动。这需要从服务器的fsid映射到客户端看到的fsid,但由于其他原因,这已经是必要的了。如上所述,两个子文件系统中的现有文件ID不会冲突。为拆分文件系统上新创建的文件提供无冲突的fileid是服务器(或协同工作的服务器)的责任。服务器可以对文件句柄进行编码,以便能够区分拆分事件之前生成的文件句柄和拆分之后生成的文件句柄,从而允许服务器确定何时不再需要将两个文件系统模拟为一个文件系统。

Although it is possible for this flag to be present in the event of referral, it would generally be of little interest to the client, since the client is not expected to have information regarding the current contents of the absent file system.

尽管在转介的情况下可能会出现此标志,但客户通常对此不感兴趣,因为客户不希望获得有关缺少的文件系统的当前内容的信息。

The transport-flag field (at byte index FSLI4BX_TFLAGS) contains the following bits related to the transport capabilities of the specific file system.

传输标志字段(位于字节索引FSLI4BX_TFLAGS处)包含以下与特定文件系统的传输功能相关的位。

o FSLI4TF_RDMA indicates that this file system provides NFSv4.1 file system access using an RDMA-capable transport.

o FSLI4TF_RDMA表示此文件系统使用支持RDMA的传输提供NFSv4.1文件系统访问。

Attribute continuity and file system identity information are expressed by defining equivalence relations on the sets of file systems presented to the client. Each such relation is expressed as a set of file system equivalence classes. For each relation, a file

属性连续性和文件系统标识信息通过定义呈现给客户的文件系统集上的等价关系来表示。每个这样的关系都表示为一组文件系统等价类。对于每个关系,一个文件

system has an 8-bit class number. Two file systems belong to the same class if both have identical non-zero class numbers. Zero is treated as non-matching. Most often, the relevant question for the client will be whether a given replica is identical to / continuous with the current one in a given respect, but the information should be available also as to whether two other replicas match in that respect as well.

系统有一个8位的类号。如果两个文件系统具有相同的非零类号,则它们属于同一类。零被视为不匹配。大多数情况下,客户机的相关问题是给定副本在给定方面是否与当前副本相同/连续,但还应提供关于两个其他副本是否在该方面匹配的信息。

The following fields specify the file system's class numbers for the equivalence relations used in determining the nature of file system transitions. See Section 11.7 and its various subsections for details about how this information is to be used. Servers may assign these values as they wish, so long as file system instances that share the same value have the specified relationship to one another; conversely, file systems that have the specified relationship to one another share a common class value. As each instance entry is added, the relationships of this instance to previously entered instances can be consulted, and if one is found that bears the specified relationship, that entry's class value can be copied to the new entry. When no such previous entry exists, a new value for that byte index (not previously used) can be selected, most likely by incrementing the value of the last class value assigned for that index.

以下字段指定用于确定文件系统转换性质的等效关系的文件系统类号。有关如何使用此信息的详细信息,请参见第11.7节及其各小节。服务器可以根据自己的意愿分配这些值,只要共享相同值的文件系统实例彼此具有指定的关系;相反,彼此具有指定关系的文件系统共享一个公共类值。添加每个实例条目时,可以查看此实例与以前输入的实例的关系,如果找到具有指定关系的实例,则可以将该条目的类值复制到新条目。如果不存在此类以前的条目,则可以为该字节索引(以前未使用)选择一个新值,最有可能的方法是增加为该索引分配的最后一个类值的值。

o The field with byte index FSLI4BX_CLSIMUL defines the simultaneous-use class for the file system.

o 字节索引为FSLI4BX_CLSIMUL的字段定义文件系统的同步使用类。

o The field with byte index FSLI4BX_CLHANDLE defines the handle class for the file system.

o 具有字节索引FSLI4BX_CLHANDLE的字段定义文件系统的句柄类。

o The field with byte index FSLI4BX_CLFILEID defines the fileid class for the file system.

o 字节索引为FSLI4BX_CLFILEID的字段定义文件系统的fileid类。

o The field with byte index FSLI4BX_CLWRITEVER defines the write-verifier class for the file system.

o 字节索引为FSLI4BX_CLWRITEVER的字段定义文件系统的写验证程序类。

o The field with byte index FSLI4BX_CLCHANGE defines the change class for the file system.

o 字节索引为FSLI4BX_CLCHANGE的字段定义文件系统的更改类。

o The field with byte index FSLI4BX_CLREADDIR defines the readdir class for the file system.

o 字节索引为FSLI4BX_CLREADDIR的字段定义文件系统的readdir类。

Server-specified preference information is also provided via 8-bit values within the fls_info array. The values provide a rank and an order (see below) to be used with separate values specifiable for the cases of read-only and writable file systems. These values are compared for different file systems to establish the server-specified preference, with lower values indicating "more preferred".

服务器指定的首选项信息也通过fls_信息数组中的8位值提供。这些值提供了一个秩和一个顺序(见下文),以便与可为只读和可写文件系统指定的单独值一起使用。比较不同文件系统的这些值以确定服务器指定的首选项,较低的值表示“更首选”。

Rank is used to express a strict server-imposed ordering on clients, with lower values indicating "more preferred". Clients should attempt to use all replicas with a given rank before they use one with a higher rank. Only if all of those file systems are unavailable should the client proceed to those of a higher rank. Because specifying a rank will override client preferences, servers should be conservative about using this mechanism, particularly when the environment is one in which client communication characteristics are neither tightly controlled nor visible to the server.

秩用于表示服务器对客户端施加的严格排序,较低的值表示“更优先”。客户机应先尝试使用具有给定列组的所有副本,然后再使用具有更高列组的副本。只有当所有这些文件系统都不可用时,客户端才能转到级别更高的文件系统。因为指定排名将覆盖客户端首选项,所以服务器在使用此机制时应该谨慎,特别是在客户端通信特性既不受严格控制也不为服务器所见的环境中。

Within a rank, the order value is used to specify the server's preference to guide the client's selection when the client's own preferences are not controlling, with lower values of order indicating "more preferred". If replicas are approximately equal in all respects, clients should defer to the order specified by the server. When clients look at server latency as part of their selection, they are free to use this criterion but it is suggested that when latency differences are not significant, the server-specified order should guide selection.

在等级中,订单值用于指定服务器的首选项,以在客户端自己的首选项不受控制时指导客户端的选择,订单值越低表示“更首选”。如果复制副本在所有方面大致相等,则客户端应遵循服务器指定的顺序。当客户端将服务器延迟视为其选择的一部分时,他们可以自由使用此标准,但建议在延迟差异不显著时,服务器指定的顺序应指导选择。

o The field at byte index FSLI4BX_READRANK gives the rank value to be used for read-only access.

o 字节索引FSLI4BX_READRANK处的字段给出用于只读访问的秩值。

o The field at byte index FSLI4BX_READORDER gives the order value to be used for read-only access.

o 字节索引FSLI4BX_READORDER处的字段提供用于只读访问的顺序值。

o The field at byte index FSLI4BX_WRITERANK gives the rank value to be used for writable access.

o 字节索引FSLI4BX_WRITERANK处的字段给出用于可写访问的秩值。

o The field at byte index FSLI4BX_WRITEORDER gives the order value to be used for writable access.

o 字节索引FSLI4BX_WRITEORDER处的字段提供用于可写访问的顺序值。

Depending on the potential need for write access by a given client, one of the pairs of rank and order values is used. The read rank and order should only be used if the client knows that only reading will ever be done or if it is prepared to switch to a different replica in the event that any write access capability is required in the future.

根据给定客户机对写访问的潜在需求,使用秩和顺序值对中的一个。只有当客户端知道将只进行读取,或者准备在将来需要任何写访问能力时切换到其他副本时,才应使用读取列组和顺序。

11.10.2. The fs_locations_info4 Structure
11.10.2. fs_位置信息4结构

The fs_locations_info4 structure, encoding the fs_locations_info attribute, contains the following:

fs_locations_info4结构编码fs_locations_info属性,包含以下内容:

o The fli_flags field, which contains general flags that affect the interpretation of this fs_locations_info4 structure and all fs_locations_item4 structures within it. The only flag currently defined is FSLI4IF_VAR_SUB. All bits in the fli_flags field that are not defined should always be returned as zero.

o fli_flags字段,其中包含影响此fs_locations_info4结构及其内所有fs_locations_item4结构的解释的常规标志。当前定义的唯一标志是FSLI4IF_VAR_SUB。fli_标志字段中未定义的所有位应始终返回为零。

o The fli_fs_root field, which contains the pathname of the root of the current file system on the current server, just as it does in the fs_locations4 structure.

o fli_fs_root字段,它包含当前服务器上当前文件系统根目录的路径名,与fs_locations4结构中的相同。

o An array called fli_items of fs_locations4_item structures, which contain information about replicas of the current file system. Where the current file system is actually present, or has been present, i.e., this is not a referral situation, one of the fs_locations_item4 structures will contain an fs_locations_server4 for the current server. This structure will have FSLI4GF_ABSENT set if the current file system is absent, i.e., normal access to it will return NFS4ERR_MOVED.

o fs_locations4_项结构的名为fli_项的数组,其中包含有关当前文件系统副本的信息。如果当前文件系统实际存在或已经存在,即这不是引用情况,则其中一个fs_locations_item4结构将包含当前服务器的fs_locations_server4。如果当前文件系统不存在,则此结构将设置FSLI4GF_缺席,即,对它的正常访问将返回NFS4ERR_MOVED。

o The fli_valid_for field specifies a time in seconds for which it is reasonable for a client to use the fs_locations_info attribute without refetch. The fli_valid_for value does not provide a guarantee of validity since servers can unexpectedly go out of service or become inaccessible for any number of reasons. Clients are well-advised to refetch this information for an actively accessed file system at every fli_valid_for seconds. This is particularly important when file system replicas may go out of service in a controlled way using the FSLI4GF_GOING flag to communicate an ongoing change. The server should set fli_valid_for to a value that allows well-behaved clients to notice the FSLI4GF_GOING flag and make an orderly switch before the loss of service becomes effective. If this value is zero, then no refetch interval is appropriate and the client need not refetch this data on any particular schedule. In the event of a transition to a new file system instance, a new value of the fs_locations_info attribute will be fetched at the destination. It is to be expected that this may have a different fli_valid_for value, which the client should then use in the same fashion as the previous value.

o fli_valid_for字段指定一个时间(以秒为单位),在该时间内,客户端可以在不重新蚀刻的情况下使用fs_locations_info属性。fli_valid_for值不提供有效性保证,因为服务器可能会因各种原因意外停止服务或无法访问。我们建议客户端在每一个fli_有效时间内,为主动访问的文件系统重新蚀刻此信息几秒钟。当文件系统副本可能以受控方式停止服务时,这一点尤为重要,可以使用FSLI4GF_go标志来传达正在进行的更改。服务器应将fli_valid_for设置为一个值,该值允许行为良好的客户端注意到FSLI4GF_GOING标志,并在服务丢失生效之前进行有序切换。如果该值为零,则无需重新蚀刻间隔,客户端无需在任何特定计划中重新蚀刻该数据。在转换到新文件系统实例的情况下,将在目标位置获取fs_locations_info属性的新值。可以预期,这可能会有不同的fli_valid_for value,然后客户端应以与前一个值相同的方式使用该值。

The FSLI4IF_VAR_SUB flag within fli_flags controls whether variable substitution is to be enabled. See Section 11.10.3 for an explanation of variable substitution.

fli_标志中的FSLI4IF_VAR_子标志控制是否启用变量替换。有关变量替换的解释,请参见第11.10.3节。

11.10.3. The fs_locations_item4 Structure
11.10.3. fs_位置_item4结构

The fs_locations_item4 structure contains a pathname (in the field fli_rootpath) that encodes the path of the target file system replicas on the set of servers designated by the included fs_locations_server4 entries. The precise manner in which this target location is specified depends on the value of the FSLI4IF_VAR_SUB flag within the associated fs_locations_info4 structure.

fs_locations_item4结构包含一个路径名(在字段fli_rootpath中),该路径编码由包含的fs_locations_server4条目指定的一组服务器上的目标文件系统副本的路径。指定此目标位置的精确方式取决于相关fs_locations_info4结构中FSLI4IF_VAR_子标志的值。

If this flag is not set, then fli_rootpath simply designates the location of the target file system within each server's single-server namespace just as it does for the rootpath within the fs_location4 structure. When this bit is set, however, component entries of a certain form are subject to client-specific variable substitution so as to allow a degree of namespace non-uniformity in order to accommodate the selection of client-specific file system targets to adapt to different client architectures or other characteristics.

如果未设置此标志,则fli_rootpath将在每个服务器的单个服务器命名空间中简单地指定目标文件系统的位置,就像它在fs_location4结构中指定rootpath一样。但是,当设置此位时,特定形式的组件条目将接受特定于客户端的变量替换,以允许一定程度的命名空间不一致性,以便适应特定于客户端的文件系统目标的选择,以适应不同的客户端体系结构或其他特征。

When such substitution is in effect, a variable beginning with the string "${" and ending with the string "}" and containing a colon is to be replaced by the client-specific value associated with that variable. The string "unknown" should be used by the client when it has no value for such a variable. The pathname resulting from such substitutions is used to designate the target file system, so that different clients may have different file systems, corresponding to that location in the multi-server namespace.

当这种替换生效时,以字符串“${”开头、以字符串“}”结尾并包含冒号的变量将被与该变量关联的特定于客户端的值替换。当字符串“unknown”对于此类变量没有值时,客户端应使用该字符串。这种替换产生的路径名用于指定目标文件系统,因此不同的客户端可能具有不同的文件系统,对应于多服务器名称空间中的该位置。

As mentioned above, such substituted pathname variables contain a colon. The part before the colon is to be a DNS domain name, and the part after is to be a case-insensitive alphanumeric string.

如上所述,这样的替换路径名变量包含冒号。冒号前面的部分是DNS域名,后面的部分是不区分大小写的字母数字字符串。

Where the domain is "ietf.org", only variable names defined in this document or subsequent Standards Track RFCs are subject to such substitution. Organizations are free to use their domain names to create their own sets of client-specific variables, to be subject to such substitution. In cases where such variables are intended to be used more broadly than a single organization, publication of an Informational RFC defining such variables is RECOMMENDED.

如果域为“ietf.org”,则只有本文件或后续标准中定义的变量名可用于跟踪RFC。组织可以自由使用其域名创建自己的客户特定变量集,以进行此类替换。如果此类变量的使用范围比单个组织更广,建议发布定义此类变量的信息性RFC。

The variable ${ietf.org:CPU_ARCH} is used to denote that the CPU architecture object files are compiled. This specification does not limit the acceptable values (except that they must be valid UTF-8 strings), but such values as "x86", "x86_64", and "sparc" would be expected to be used in line with industry practice.

变量${ietf.org:CPU_ARCH}用于表示编译了CPU体系结构对象文件。本规范不限制可接受的值(除非它们必须是有效的UTF-8字符串),但“x86”、“x86_64”和“sparc”等值预计将按照行业惯例使用。

The variable ${ietf.org:OS_TYPE} is used to denote the operating system, and thus the kernel and library APIs, for which code might be compiled. This specification does not limit the acceptable values (except that they must be valid UTF-8 strings), but such values as "linux" and "freebsd" would be expected to be used in line with industry practice.

变量${ietf.org:OS_TYPE}用于表示操作系统,以及可能编译代码的内核和库API。本规范不限制可接受的值(除非它们必须是有效的UTF-8字符串),但“linux”和“freebsd”等值应按照行业惯例使用。

The variable ${ietf.org:OS_VERSION} is used to denote the operating system version, and thus the specific details of versioned interfaces, for which code might be compiled. This specification does not limit the acceptable values (except that they must be valid UTF-8 strings). However, combinations of numbers and letters with

变量${ietf.org:OS_VERSION}用于表示操作系统版本,从而表示可能编译代码的版本化接口的具体细节。本规范不限制可接受的值(除非它们必须是有效的UTF-8字符串)。但是,数字和字母的组合

interspersed dots would be expected to be used in line with industry practice, with the details of the version format depending on the specific value of the variable ${ietf.org:OS_TYPE} with which it is used.

预计将按照行业惯例使用散布的点,版本格式的细节取决于使用变量${ietf.org:OS_TYPE}的具体值。

Use of these variables could result in the direction of different clients to different file systems on the same server, as appropriate to particular clients. In cases in which the target file systems are located on different servers, a single server could serve as a referral point so that each valid combination of variable values would designate a referral hosted on a single server, with the targets of those referrals on a number of different servers.

使用这些变量可能会导致不同的客户端指向同一服务器上的不同文件系统,这对于特定的客户端是合适的。在目标文件系统位于不同服务器上的情况下,单个服务器可以用作引用点,以便每个有效的变量值组合都将指定托管在单个服务器上的引用,这些引用的目标位于多个不同的服务器上。

Because namespace administration is affected by the values selected to substitute for various variables, clients should provide convenient means of determining what variable substitutions a client will implement, as well as, where appropriate, providing means to control the substitutions to be used. The exact means by which this will be done is outside the scope of this specification.

由于名称空间管理受选择用于替换各种变量的值的影响,因此客户端应提供方便的方法来确定客户端将实现哪些变量替换,并在适当的情况下提供控制要使用的替换的方法。具体方法不在本规范范围内。

Although variable substitution is most suitable for use in the context of referrals, it may be used in the context of replication and migration. If it is used in these contexts, the server must ensure that no matter what values the client presents for the substituted variables, the result is always a valid successor file system instance to that from which a transition is occurring, i.e., that the data is identical or represents a later image of a writable file system.

尽管变量替换最适合在引用上下文中使用,但它也可以在复制和迁移上下文中使用。如果在这些上下文中使用,服务器必须确保无论客户端为替换变量提供什么值,结果始终是发生转换的文件系统实例的有效后续文件系统实例,即数据相同或表示可写文件系统的后续映像。

Note that when fli_rootpath is a null pathname (that is, one with zero components), the file system designated is at the root of the specified server, whether or not the FSLI4IF_VAR_SUB flag within the associated fs_locations_info4 structure is set.

请注意,当fli_rootpath为空路径名(即零组件的路径名)时,指定的文件系统位于指定服务器的根目录下,无论是否设置了相关联的fs_locations_info4结构中的FSLI4IF_VAR_子标志。

11.11. The Attribute fs_status
11.11. 属性fs_status

In an environment in which multiple copies of the same basic set of data are available, information regarding the particular source of such data and the relationships among different copies can be very helpful in providing consistent data to applications.

在同一基本数据集的多个副本可用的环境中,有关此类数据的特定来源以及不同副本之间的关系的信息对于向应用程序提供一致的数据非常有帮助。

   enum fs4_status_type {
           STATUS4_FIXED = 1,
           STATUS4_UPDATED = 2,
           STATUS4_VERSIONED = 3,
           STATUS4_WRITABLE = 4,
           STATUS4_REFERRAL = 5
   };
        
   enum fs4_status_type {
           STATUS4_FIXED = 1,
           STATUS4_UPDATED = 2,
           STATUS4_VERSIONED = 3,
           STATUS4_WRITABLE = 4,
           STATUS4_REFERRAL = 5
   };
        
   struct fs4_status {
           bool            fss_absent;
           fs4_status_type fss_type;
           utf8str_cs      fss_source;
           utf8str_cs      fss_current;
           int32_t         fss_age;
           nfstime4        fss_version;
   };
        
   struct fs4_status {
           bool            fss_absent;
           fs4_status_type fss_type;
           utf8str_cs      fss_source;
           utf8str_cs      fss_current;
           int32_t         fss_age;
           nfstime4        fss_version;
   };
        

The boolean fss_absent indicates whether the file system is currently absent. This value will be set if the file system was previously present and becomes absent, or if the file system has never been present and the type is STATUS4_REFERRAL. When this boolean is set and the type is not STATUS4_REFERRAL, the remaining information in the fs4_status reflects that last valid when the file system was present.

布尔值fss_缺席表示文件系统当前是否缺席。如果文件系统以前存在但现在不存在,或者文件系统从未存在且类型为STATUS4\u Reference,则将设置此值。如果设置了此布尔值且类型不是STATUS4\u REFERRAL,则fs4\u状态中的剩余信息将反映文件系统存在时的最后有效信息。

The fss_type field indicates the kind of file system image represented. This is of particular importance when using the version values to determine appropriate succession of file system images. When fss_absent is set, and the file system was previously present, the value of fss_type reflected is that when the file was last present. Five values are distinguished:

fss_type字段指示所表示的文件系统映像的类型。当使用版本值确定文件系统映像的适当顺序时,这一点尤为重要。如果设置了fss_缺席,并且文件系统以前存在,则反映的fss_类型值为文件上次存在时的值。区分了五种价值观:

o STATUS4_FIXED, which indicates a read-only image in the sense that it will never change. The possibility is allowed that, as a result of migration or switch to a different image, changed data can be accessed, but within the confines of this instance, no change is allowed. The client can use this fact to cache aggressively.

o STATUS4\u FIXED,表示只读映像永远不会更改。迁移或切换到其他映像后,可以访问更改的数据,但在此实例范围内,不允许更改。客户机可以利用这一事实进行主动缓存。

o STATUS4_VERSIONED, which indicates that the image, like the STATUS4_UPDATED case, is updated externally, but it provides a guarantee that the server will carefully update an associated version value so that the client can protect itself from a situation in which it reads data from one version of the file system and then later reads data from an earlier version of the same file system. See below for a discussion of how this can be done.

o STATUS4\u VERSIONED,表示图像像STATUS4\u更新的案例一样在外部更新,但它提供了一种保证,即服务器将小心地更新相关的版本值,以便客户机能够保护自己,避免从一个版本的文件系统中读取数据,然后再从同一文件系统的早期版本中读取数据。有关如何实现这一点的讨论,请参见下文。

o STATUS4_UPDATED, which indicates an image that cannot be updated by the user writing to it but that may be changed externally, typically because it is a periodically updated copy of another writable file system somewhere else. In this case, version information is not provided, and the client does not have the responsibility of making sure that this version only advances upon a file system instance transition. In this case, it is the responsibility of the server to make sure that the data presented

o Status 4_UPDATED,表示用户写入的映像无法更新,但可能会在外部更改,通常是因为它是其他地方另一个可写文件系统的定期更新副本。在这种情况下,不提供版本信息,并且客户机没有责任确保此版本仅在文件系统实例转换时升级。在这种情况下,服务器有责任确保提供的数据

after a file system instance transition is a proper successor image and includes all changes seen by the client and any change made before all such changes.

文件系统实例转换之后是一个正确的后续映像,它包括客户端看到的所有更改以及在所有这些更改之前所做的任何更改。

o STATUS4_WRITABLE, which indicates that the file system is an actual writable one. The client need not, of course, actually write to the file system, but once it does, it should not accept a transition to anything other than a writable instance of that same file system.

o STATUS4\u WRITABLE,表示文件系统是实际的可写系统。当然,客户机不需要实际写入文件系统,但一旦写入,它就不应该接受转换到同一文件系统的可写实例之外的任何内容。

o STATUS4_REFERRAL, which indicates that the file system in question is absent and has never been present on this server.

o STATUS4\u REFERRAL,表示该文件系统不存在,并且从未出现在该服务器上。

Note that in the STATUS4_UPDATED and STATUS4_VERSIONED cases, the server is responsible for the appropriate handling of locks that are inconsistent with external changes to delegations. If a server gives out delegations, they SHOULD be recalled before an inconsistent change is made to the data, and MUST be revoked if this is not possible. Similarly, if an OPEN is inconsistent with data that is changed (the OPEN has OPEN4_SHARE_DENY_WRITE/OPEN4_SHARE_DENY_BOTH and the data is changed), that OPEN SHOULD be considered administratively revoked.

请注意,在STATUS4_更新和STATUS4_版本化的情况下,服务器负责适当处理与委托的外部更改不一致的锁。如果服务器发出委托,则应在对数据进行不一致的更改之前调用这些委托,如果不可能,则必须撤销这些委托。类似地,如果打开与更改的数据不一致(该打开同时具有OPEN4_共享\u拒绝\u写入/OPEN4_共享\u拒绝\u,并且数据已更改),则该打开应被视为管理性撤销。

The opaque strings fss_source and fss_current provide a way of presenting information about the source of the file system image being present. It is not intended that the client do anything with this information other than make it available to administrative tools. It is intended that this information be helpful when researching possible problems with a file system image that might arise when it is unclear if the correct image is being accessed and, if not, how that image came to be made. This kind of diagnostic information will be helpful, if, as seems likely, copies of file systems are made in many different ways (e.g., simple user-level copies, file-system-level point-in-time copies, clones of the underlying storage), under a variety of administrative arrangements. In such environments, determining how a given set of data was constructed can be very helpful in resolving problems.

不透明字符串fss_source和fss_current提供了一种显示当前文件系统映像源信息的方法。客户机不打算对这些信息进行任何处理,而只是将其提供给管理工具。在研究文件系统映像可能出现的问题时,如果不清楚是否正在访问正确的映像,以及该映像是如何生成的,则这些信息将非常有用。如果在各种管理安排下以多种不同的方式(例如,简单用户级拷贝、文件系统级时间点拷贝、基础存储克隆)制作文件系统的拷贝,则此类诊断信息将非常有用。在这样的环境中,确定如何构造给定的数据集对于解决问题非常有帮助。

The opaque string fss_source is used to indicate the source of a given file system with the expectation that tools capable of creating a file system image propagate this information, when possible. It is understood that this may not always be possible since a user-level copy may be thought of as creating a new data set and the tools used may have no mechanism to propagate this data. When a file system is initially created, it is desirable to associate with it data regarding how the file system was created, where it was created, who created it, etc. Making this information available in this attribute

不透明字符串fss_source用于指示给定文件系统的源,期望能够创建文件系统映像的工具尽可能传播此信息。可以理解,这并不总是可能的,因为用户级副本可能被认为是创建新的数据集,并且所使用的工具可能没有传播该数据的机制。最初创建文件系统时,最好将有关文件系统创建方式、创建位置、创建人等的数据与之关联,以使此信息在此属性中可用

in a human-readable string will be helpful for applications and system administrators and will also serve to make it available when the original file system is used to make subsequent copies.

在一个人类可读的字符串中,它将有助于应用程序和系统管理员,并且当原始文件系统用于制作后续副本时,它也将使其可用。

The opaque string fss_current should provide whatever information is available about the source of the current copy. Such information includes the tool creating it, any relevant parameters to that tool, the time at which the copy was done, the user making the change, the server on which the change was made, etc. All information should be in a human-readable string.

不透明字符串fss_current应提供有关当前副本源的任何可用信息。此类信息包括创建该工具的工具、该工具的任何相关参数、完成复制的时间、进行更改的用户、进行更改的服务器等。所有信息均应为人类可读的字符串。

The field fss_age provides an indication of how out-of-date the file system currently is with respect to its ultimate data source (in case of cascading data updates). This complements the fls_currency field of fs_locations_server4 (see Section 11.10) in the following way: the information in fls_currency gives a bound for how out of date the data in a file system might typically get, while the value in fss_age gives a bound on how out-of-date that data actually is. Negative values imply that no information is available. A zero means that this data is known to be current. A positive value means that this data is known to be no older than that number of seconds with respect to the ultimate data source. Using this value, the client may be able to decide that a data copy is too old, so that it may search for a newer version to use.

字段fss_age指示文件系统当前相对于其最终数据源的过时程度(在级联数据更新的情况下)。这以以下方式补充了fs_locations_server4的fls_currency字段(请参见第11.10节):fls_currency中的信息给出了文件系统中数据通常可能过时的范围,而fss_age中的值给出了该数据实际过时的范围。负值表示没有可用的信息。零表示已知此数据为当前数据。正值表示已知该数据不早于最终数据源的秒数。使用此值,客户机可能能够确定数据副本太旧,以便搜索要使用的较新版本。

The fss_version field provides a version identification, in the form of a time value, such that successive versions always have later time values. When the fs_type is anything other than STATUS4_VERSIONED, the server may provide such a value, but there is no guarantee as to its validity and clients will not use it except to provide additional information to add to fss_source and fss_current.

fss_版本字段以时间值的形式提供版本标识,以便后续版本始终具有更晚的时间值。当fs_类型不是STATUS4_VERSIONED时,服务器可以提供此类值,但不能保证其有效性,客户端不会使用它,除非提供附加信息以添加到fss_source和fss_current。

When fss_type is STATUS4_VERSIONED, servers SHOULD provide a value of fss_version that progresses monotonically whenever any new version of the data is established. This allows the client, if reliable image progression is important to it, to fetch this attribute as part of each COMPOUND where data or metadata from the file system is used.

当fss_类型为STATUS4_VERSIONED时,服务器应提供一个fss_version值,该值在建立任何新版本的数据时都会单调进行。如果可靠的映像进程对客户机很重要,则这允许客户机将此属性作为使用文件系统中的数据或元数据的每个化合物的一部分来获取。

When it is important to the client to make sure that only valid successor images are accepted, it must make sure that it does not read data or metadata from the file system without updating its sense of the current state of the image. This is to avoid the possibility that the fs_status that the client holds will be one for an earlier image, which would cause the client to accept a new file system instance that is later than that but still earlier than the updated data read by the client.

当客户端必须确保只接受有效的后续映像时,它必须确保在不更新其对映像当前状态的感知的情况下,不会从文件系统读取数据或元数据。这是为了避免客户机持有的fs_状态可能是早期映像的状态,这将导致客户机接受新的文件系统实例,该实例晚于该实例,但仍早于客户机读取的更新数据。

In order to accept valid images reliably, the client must do a GETATTR of the fs_status attribute that follows any interrogation of data or metadata within the file system in question. Often this is most conveniently done by appending such a GETATTR after all other operations that reference a given file system. When errors occur between reading file system data and performing such a GETATTR, care must be exercised to make sure that the data in question is not used before obtaining the proper fs_status value. In this connection, when an OPEN is done within such a versioned file system and the associated GETATTR of fs_status is not successfully completed, the open file in question must not be accessed until that fs_status is fetched.

为了可靠地接受有效的映像,客户机必须对fs_status属性执行GETATTR,该属性跟踪所讨论的文件系统中的任何数据或元数据查询。通常,在引用给定文件系统的所有其他操作之后附加这样一个GETATTR是最方便的。当读取文件系统数据和执行此类GETATTR之间发生错误时,必须小心确保在获得正确的fs_状态值之前未使用相关数据。在这种情况下,如果在这样一个版本化的文件系统中完成了一个打开操作,并且相关联的fs_状态的GETATTR未成功完成,则在获取该fs_状态之前,不得访问该打开的文件。

The procedure above will ensure that before using any data from the file system the client has in hand a newly-fetched current version of the file system image. Multiple values for multiple requests in flight can be resolved by assembling them into the required partial order (and the elements should form a total order within the partial order) and using the last. The client may then, when switching among file system instances, decline to use an instance that does not have an fss_type of STATUS4_VERSIONED or whose fss_version field is earlier than the last one obtained from the predecessor file system instance.

上述过程将确保在使用来自文件系统的任何数据之前,客户机手中有一个新获取的文件系统映像的当前版本。飞行中的多个请求的多个值可以通过将它们组合成所需的部分顺序(元素应该在部分顺序中形成一个总顺序)并使用最后一个来解析。然后,当在文件系统实例之间切换时,客户端可能会拒绝使用没有fss_类型STATUS4_VERSIONED或其fss_version字段早于从先前文件系统实例获得的最后一个fss_字段的实例。

12. Parallel NFS (pNFS)
12. 并行NFS(pNFS)
12.1. Introduction
12.1. 介绍

pNFS is an OPTIONAL feature within NFSv4.1; the pNFS feature set allows direct client access to the storage devices containing file data. When file data for a single NFSv4 server is stored on multiple and/or higher-throughput storage devices (by comparison to the server's throughput capability), the result can be significantly better file access performance. The relationship among multiple clients, a single server, and multiple storage devices for pNFS (server and clients have access to all storage devices) is shown in Figure 1.

pNFS是NFSv4.1中的可选功能;pNFS功能集允许客户端直接访问包含文件数据的存储设备。当单个NFSv4服务器的文件数据存储在多个和/或更高吞吐量的存储设备上(与服务器的吞吐量能力相比)时,结果可能会显著提高文件访问性能。pNFS的多个客户端、单个服务器和多个存储设备之间的关系(服务器和客户端可以访问所有存储设备)如图1所示。

       +-----------+
       |+-----------+                                 +-----------+
       ||+-----------+                                |           |
       |||           |        NFSv4.1 + pNFS          |           |
       +||  Clients  |<------------------------------>|   Server  |
        +|           |                                |           |
         +-----------+                                |           |
              |||                                     +-----------+
              |||                                           |
              |||                                           |
              ||| Storage        +-----------+              |
              ||| Protocol       |+-----------+             |
              ||+----------------||+-----------+  Control   |
              |+-----------------|||           |    Protocol|
              +------------------+||  Storage  |------------+
                                  +|  Devices  |
                                   +-----------+
        
       +-----------+
       |+-----------+                                 +-----------+
       ||+-----------+                                |           |
       |||           |        NFSv4.1 + pNFS          |           |
       +||  Clients  |<------------------------------>|   Server  |
        +|           |                                |           |
         +-----------+                                |           |
              |||                                     +-----------+
              |||                                           |
              |||                                           |
              ||| Storage        +-----------+              |
              ||| Protocol       |+-----------+             |
              ||+----------------||+-----------+  Control   |
              |+-----------------|||           |    Protocol|
              +------------------+||  Storage  |------------+
                                  +|  Devices  |
                                   +-----------+
        

Figure 1

图1

In this model, the clients, server, and storage devices are responsible for managing file access. This is in contrast to NFSv4 without pNFS, where it is primarily the server's responsibility; some of this responsibility may be delegated to the client under strictly specified conditions. See Section 12.2.5 for a discussion of the Storage Protocol. See Section 12.2.6 for a discussion of the Control Protocol.

在此模型中,客户端、服务器和存储设备负责管理文件访问。这与没有pNFS的NFSv4不同,后者主要由服务器负责;在严格规定的条件下,可将部分责任委托给客户。有关存储协议的讨论,请参见第12.2.5节。关于控制协议的讨论,见第12.2.6节。

pNFS takes the form of OPTIONAL operations that manage protocol objects called 'layouts' (Section 12.2.7) that contain a byte-range and storage location information. The layout is managed in a similar fashion as NFSv4.1 data delegations. For example, the layout is leased, recallable, and revocable. However, layouts are distinct abstractions and are manipulated with new operations. When a client holds a layout, it is granted the ability to directly access the byte-range at the storage location specified in the layout.

pNFS采用可选操作的形式,管理称为“布局”(第12.2.7节)的协议对象,其中包含字节范围和存储位置信息。布局的管理方式与NFSv4.1数据委托类似。例如,布局是出租的、可撤销的和可撤销的。然而,布局是不同的抽象,并通过新的操作进行操作。当客户端持有布局时,它被授予直接访问布局中指定存储位置的字节范围的能力。

There are interactions between layouts and other NFSv4.1 abstractions such as data delegations and byte-range locking. Delegation issues are discussed in Section 12.5.5. Byte-range locking issues are discussed in Sections 12.2.9 and 12.5.1.

布局和其他NFSv4.1抽象(如数据委托和字节范围锁定)之间存在交互。第12.5.5节讨论了授权问题。第12.2.9节和第12.5.1节讨论了字节范围锁定问题。

12.2. pNFS Definitions
12.2. pNFS定义

NFSv4.1's pNFS feature provides parallel data access to a file system that stripes its content across multiple storage servers. The first instantiation of pNFS, as part of NFSv4.1, separates the file system protocol processing into two parts: metadata processing and data

NFSv4.1的pNFS功能提供了对文件系统的并行数据访问,该文件系统跨多个存储服务器对其内容进行分条。作为NFSv4.1的一部分,pNFS的第一个实例化将文件系统协议处理分为两部分:元数据处理和数据处理

processing. Data consist of the contents of regular files that are striped across storage servers. Data striping occurs in at least two ways: on a file-by-file basis and, within sufficiently large files, on a block-by-block basis. In contrast, striped access to metadata by pNFS clients is not provided in NFSv4.1, even though the file system back end of a pNFS server might stripe metadata. Metadata consist of everything else, including the contents of non-regular files (e.g., directories); see Section 12.2.1. The metadata functionality is implemented by an NFSv4.1 server that supports pNFS and the operations described in Section 18; such a server is called a metadata server (Section 12.2.2).

处理。数据由跨存储服务器条带化的常规文件的内容组成。数据条带化至少以两种方式发生:一种是逐个文件,另一种是在足够大的文件中,以块为单位。相反,NFSv4.1中不提供pNFS客户端对元数据的分条访问,即使pNFS服务器的文件系统后端可能会分条访问元数据。元数据包括所有其他内容,包括非常规文件(如目录)的内容;见第12.2.1节。元数据功能由支持pNFS和第18节所述操作的NFSv4.1服务器实现;这种服务器称为元数据服务器(第12.2.2节)。

The data functionality is implemented by one or more storage devices, each of which are accessed by the client via a storage protocol. A subset (defined in Section 13.6) of NFSv4.1 is one such storage protocol. New terms are introduced to the NFSv4.1 nomenclature and existing terms are clarified to allow for the description of the pNFS feature.

数据功能由一个或多个存储设备实现,每个存储设备都由客户端通过存储协议访问。NFSv4.1的子集(定义见第13.6节)就是这样一种存储协议。NFSv4.1术语中引入了新术语,并澄清了现有术语,以便于描述pNFS功能。

12.2.1. Metadata
12.2.1. 元数据

Information about a file system object, such as its name, location within the namespace, owner, ACL, and other attributes. Metadata may also include storage location information, and this will vary based on the underlying storage mechanism that is used.

有关文件系统对象的信息,例如其名称、命名空间中的位置、所有者、ACL和其他属性。元数据还可能包括存储位置信息,这将根据所使用的底层存储机制而有所不同。

12.2.2. Metadata Server
12.2.2. 元数据服务

An NFSv4.1 server that supports the pNFS feature. A variety of architectural choices exist for the metadata server and its use of file system information held at the server. Some servers may contain metadata only for file objects residing at the metadata server, while the file data resides on associated storage devices. Other metadata servers may hold both metadata and a varying degree of file data.

支持pNFS功能的NFSv4.1服务器。元数据服务器及其对服务器上保存的文件系统信息的使用有多种体系结构选择。某些服务器可能仅包含驻留在元数据服务器上的文件对象的元数据,而文件数据驻留在关联的存储设备上。其他元数据服务器可能同时保存元数据和不同程度的文件数据。

12.2.3. pNFS Client
12.2.3. pNFS客户端

An NFSv4.1 client that supports pNFS operations and supports at least one storage protocol for performing I/O to storage devices.

一种NFSv4.1客户端,支持pNFS操作,并至少支持一种存储协议,用于对存储设备执行I/O操作。

12.2.4. Storage Device
12.2.4. 存储设备

A storage device stores a regular file's data, but leaves metadata management to the metadata server. A storage device could be another NFSv4.1 server, an object-based storage device (OSD), a block device accessed over a System Area Network (SAN, e.g., either FiberChannel or iSCSI SAN), or some other entity.

存储设备存储常规文件的数据,但将元数据管理留给元数据服务器。存储设备可以是另一台NFSv4.1服务器、基于对象的存储设备(OSD)、通过系统局域网(SAN,例如光纤通道或iSCSI SAN)访问的块设备,或其他实体。

12.2.5. Storage Protocol
12.2.5. 存储协议

As noted in Figure 1, the storage protocol is the method used by the client to store and retrieve data directly from the storage devices.

如图1所示,存储协议是客户端用于直接从存储设备存储和检索数据的方法。

The NFSv4.1 pNFS feature has been structured to allow for a variety of storage protocols to be defined and used. One example storage protocol is NFSv4.1 itself (as documented in Section 13). Other options for the storage protocol are described elsewhere and include:

NFSv4.1 pNFS功能的结构允许定义和使用各种存储协议。一个示例存储协议是NFSv4.1本身(如第13节所述)。存储协议的其他选项在别处描述,包括:

o Block/volume protocols such as Internet SCSI (iSCSI) [48] and FCP [49]. The block/volume protocol support can be independent of the addressing structure of the block/volume protocol used, allowing more than one protocol to access the same file data and enabling extensibility to other block/volume protocols. See [41] for a layout specification that allows pNFS to use block/volume storage protocols.

o 块/卷协议,如Internet SCSI(iSCSI)[48]和FCP[49]。块/卷协议支持可以独立于所使用的块/卷协议的寻址结构,允许多个协议访问相同的文件数据,并支持对其他块/卷协议的扩展。有关允许PNF使用块/卷存储协议的布局规范,请参见[41]。

o Object protocols such as OSD over iSCSI or Fibre Channel [50]. See [40] for a layout specification that allows pNFS to use object storage protocols.

o 对象协议,如iSCSI或光纤通道上的OSD[50]。有关允许PNF使用对象存储协议的布局规范,请参见[40]。

It is possible that various storage protocols are available to both client and server and it may be possible that a client and server do not have a matching storage protocol available to them. Because of this, the pNFS server MUST support normal NFSv4.1 access to any file accessible by the pNFS feature; this will allow for continued interoperability between an NFSv4.1 client and server.

可能客户机和服务器都可以使用各种存储协议,也可能客户机和服务器没有匹配的存储协议。因此,pNFS服务器必须支持对pNFS功能可访问的任何文件的正常NFSv4.1访问;这将允许NFSv4.1客户端和服务器之间的持续互操作性。

12.2.6. Control Protocol
12.2.6. 控制协议

As noted in Figure 1, the control protocol is used by the exported file system between the metadata server and storage devices. Specification of such protocols is outside the scope of the NFSv4.1 protocol. Such control protocols would be used to control activities such as the allocation and deallocation of storage, the management of state required by the storage devices to perform client access control, and, depending on the storage protocol, the enforcement of authentication and authorization so that restrictions that would be enforced by the metadata server are also enforced by the storage device.

如图1所示,元数据服务器和存储设备之间的导出文件系统使用控制协议。此类协议的规范不在NFSv4.1协议的范围内。此类控制协议将用于控制活动,例如存储的分配和解除分配、存储设备执行客户端访问控制所需的状态管理,以及根据存储协议,身份验证和授权的实施,以便元数据服务器实施的限制也由存储设备实施。

A particular control protocol is not REQUIRED by NFSv4.1 but requirements are placed on the control protocol for maintaining attributes like modify time, the change attribute, and the end-of-file (EOF) position. Note that if pNFS is layered over a clustered,

NFSv4.1不要求特定的控制协议,但要求控制协议维护修改时间、更改属性和文件结束(EOF)位置等属性。请注意,如果pNFS是在集群上分层的,

parallel file system (e.g., PVFS [51]), the mechanisms that enable clustering and parallelism in that file system can be considered the control protocol.

并行文件系统(例如,PVFS[51]),在该文件系统中实现集群和并行的机制可以被视为控制协议。

12.2.7. Layout Types
12.2.7. 布局类型

A layout describes the mapping of a file's data to the storage devices that hold the data. A layout is said to belong to a specific layout type (data type layouttype4, see Section 3.3.13). The layout type allows for variants to handle different storage protocols, such as those associated with block/volume [41], object [40], and file (Section 13) layout types. A metadata server, along with its control protocol, MUST support at least one layout type. A private sub-range of the layout type namespace is also defined. Values from the private layout type range MAY be used for internal testing or experimentation (see Section 3.3.13).

布局描述文件数据到保存数据的存储设备的映射。布局被称为属于特定布局类型(数据类型layouttype4,见第3.3.13节)。布局类型允许变体处理不同的存储协议,例如与块/卷[41]、对象[40]和文件(第13节)布局类型关联的存储协议。元数据服务器及其控制协议必须至少支持一种布局类型。还定义了布局类型命名空间的私有子范围。私有布局类型范围的值可用于内部测试或试验(见第3.3.13节)。

As an example, the organization of the file layout type could be an array of tuples (e.g., device ID, filehandle), along with a definition of how the data is stored across the devices (e.g., striping). A block/volume layout might be an array of tuples that store <device ID, block number, block count> along with information about block size and the associated file offset of the block number. An object layout might be an array of tuples <device ID, object ID> and an additional structure (i.e., the aggregation map) that defines how the logical byte sequence of the file data is serialized into the different objects. Note that the actual layouts are typically more complex than these simple expository examples.

例如,文件布局类型的组织可以是元组数组(例如,设备ID、文件句柄),以及数据如何跨设备存储的定义(例如,条带化)。块/卷布局可能是一个元组数组,存储<设备ID、块编号、块计数>,以及有关块大小和块编号的关联文件偏移量的信息。对象布局可以是元组数组<device ID,object ID>,以及定义文件数据的逻辑字节序列如何序列化到不同对象的附加结构(即聚合映射)。请注意,实际布局通常比这些简单的说明性示例更复杂。

Requests for pNFS-related operations will often specify a layout type. Examples of such operations are GETDEVICEINFO and LAYOUTGET. The response for these operations will include structures such as a device_addr4 or a layout4, each of which includes a layout type within it. The layout type sent by the server MUST always be the same one requested by the client. When a server sends a response that includes a different layout type, the client SHOULD ignore the response and behave as if the server had returned an error response.

pNFS相关操作的请求通常会指定布局类型。此类操作的示例有GETDEVICEINFO和LAYOUTGET。这些操作的响应将包括诸如device_addr4或layout4之类的结构,其中每个结构都包含一个布局类型。服务器发送的布局类型必须始终与客户端请求的布局类型相同。当服务器发送包含不同布局类型的响应时,客户端应忽略该响应,并表现为服务器已返回错误响应。

12.2.8. Layout
12.2.8. 布局

A layout defines how a file's data is organized on one or more storage devices. There are many potential layout types; each of the layout types are differentiated by the storage protocol used to access data and by the aggregation scheme that lays out the file data on the underlying storage devices. A layout is precisely identified by the tuple <client ID, filehandle, layout type, iomode, range>, where filehandle refers to the filehandle of the file on the metadata server.

布局定义了文件数据在一个或多个存储设备上的组织方式。有许多潜在的布局类型;通过用于访问数据的存储协议和在底层存储设备上布局文件数据的聚合方案,可以区分每种布局类型。布局由元组<client ID,filehandle,layout type,iomode,range>精确标识,其中filehandle指元数据服务器上文件的filehandle。

It is important to define when layouts overlap and/or conflict with each other. For two layouts with overlapping byte-ranges to actually overlap each other, both layouts must be of the same layout type, correspond to the same filehandle, and have the same iomode. Layouts conflict when they overlap and differ in the content of the layout (i.e., the storage device/file mapping parameters differ). Note that differing iomodes do not lead to conflicting layouts. It is permissible for layouts with different iomodes, pertaining to the same byte-range, to be held by the same client. An example of this would be copy-on-write functionality for a block/volume layout type.

定义布局相互重叠和/或冲突的时间非常重要。要使两个具有重叠字节范围的布局真正彼此重叠,两个布局必须具有相同的布局类型,对应于相同的文件句柄,并且具有相同的iomode。布局重叠且布局内容不同时会发生冲突(即,存储设备/文件映射参数不同)。请注意,不同的IOMODE不会导致布局冲突。允许同一客户机持有属于同一字节范围的具有不同IOMODE的布局。例如,块/卷布局类型的写时复制功能。

12.2.9. Layout Iomode
12.2.9. 布局Iomode

The layout iomode (data type layoutiomode4, see Section 3.3.20) indicates to the metadata server the client's intent to perform either just READ operations or a mixture containing READ and WRITE operations. For certain layout types, it is useful for a client to specify this intent at the time it sends LAYOUTGET (Section 18.43). For example, for block/volume-based protocols, block allocation could occur when a LAYOUTIOMODE4_RW iomode is specified. A special LAYOUTIOMODE4_ANY iomode is defined and can only be used for LAYOUTRETURN and CB_LAYOUTRECALL, not for LAYOUTGET. It specifies that layouts pertaining to both LAYOUTIOMODE4_READ and LAYOUTIOMODE4_RW iomodes are being returned or recalled, respectively.

布局iomode(数据类型layoutiomode4,请参见第3.3.20节)向元数据服务器指示客户端执行只读操作或包含读写操作的混合操作的意图。对于某些布局类型,客户端在发送LAYOUTGET时指定此意图非常有用(第18.43节)。例如,对于基于块/卷的协议,在指定LAYOUTIOMODE4_RW iomode时可能会发生块分配。定义了一个特殊的LAYOUTIOMODE4_ANY iomode,它只能用于LAYOUTRETURN和CB_LAYOUTRECALL,不能用于LAYOUTGET。它指定分别返回或调用与LAYOUTIOMODE4_读取和LAYOUTIOMODE4_RW IOMODE相关的布局。

A storage device may validate I/O with regard to the iomode; this is dependent upon storage device implementation and layout type. Thus, if the client's layout iomode is inconsistent with the I/O being performed, the storage device may reject the client's I/O with an error indicating that a new layout with the correct iomode should be obtained via LAYOUTGET. For example, if a client gets a layout with a LAYOUTIOMODE4_READ iomode and performs a WRITE to a storage device, the storage device is allowed to reject that WRITE.

存储设备可以验证关于iomode的I/O;这取决于存储设备的实现和布局类型。因此,如果客户机的布局iomode与正在执行的I/O不一致,则存储设备可能会拒绝客户机的I/O,并出现错误,指示应通过LAYOUTGET获得具有正确iomode的新布局。例如,如果客户机获取具有LAYOUTIOMODE4_READ iomode的布局并对存储设备执行写入,则允许存储设备拒绝该写入。

The use of the layout iomode does not conflict with OPEN share modes or byte-range LOCK operations; open share mode and byte-range lock conflicts are enforced as they are without the use of pNFS and are logically separate from the pNFS layout level. Open share modes and byte-range locks are the preferred method for restricting user access to data files. For example, an OPEN of OPEN4_SHARE_ACCESS_WRITE does not conflict with a LAYOUTGET containing an iomode of LAYOUTIOMODE4_RW performed by another client. Applications that depend on writing into the same file concurrently may use byte-range locking to serialize their accesses.

布局iomode的使用与打开共享模式或字节范围锁定操作不冲突;开放共享模式和字节范围锁定冲突在不使用pNFS的情况下强制执行,并且在逻辑上与pNFS布局级别分离。开放共享模式和字节范围锁是限制用户访问数据文件的首选方法。例如,OPEN4_SHARE_ACCESS_WRITE的打开与包含由另一个客户端执行的LAYOUTIOMODE4_RW的iomode的LAYOUTGET不冲突。依赖于并发写入同一文件的应用程序可以使用字节范围锁定来序列化其访问。

12.2.10. Device IDs
12.2.10. 设备ID

The device ID (data type deviceid4, see Section 3.3.14) identifies a group of storage devices. The scope of a device ID is the pair <client ID, layout type>. In practice, a significant amount of information may be required to fully address a storage device. Rather than embedding all such information in a layout, layouts embed device IDs. The NFSv4.1 operation GETDEVICEINFO (Section 18.40) is used to retrieve the complete address information (including all device addresses for the device ID) regarding the storage device according to its layout type and device ID. For example, the address of an NFSv4.1 data server or of an object-based storage device could be an IP address and port. The address of a block storage device could be a volume label.

设备ID(数据类型deviceid4,见第3.3.14节)标识一组存储设备。设备ID的范围是对<客户端ID,布局类型>。实际上,完全寻址存储设备可能需要大量信息。布局嵌入设备ID,而不是将所有此类信息嵌入布局中。NFSv4.1操作GETDEVICEINFO(第18.40节)用于根据存储设备的布局类型和设备ID检索存储设备的完整地址信息(包括设备ID的所有设备地址)。例如,NFSv4.1数据服务器或基于对象的存储设备的地址可以是IP地址和端口。块存储设备的地址可以是卷标。

Clients cannot expect the mapping between a device ID and its storage device address(es) to persist across metadata server restart. See Section 12.7.4 for a description of how recovery works in that situation.

客户端不能期望设备ID与其存储设备地址之间的映射在元数据服务器重启期间保持不变。参见第12.7.4节,了解在这种情况下恢复工作的说明。

A device ID lives as long as there is a layout referring to the device ID. If there are no layouts referring to the device ID, the server is free to delete the device ID any time. Once a device ID is deleted by the server, the server MUST NOT reuse the device ID for the same layout type and client ID again. This requirement is feasible because the device ID is 16 bytes long, leaving sufficient room to store a generation number if the server's implementation requires most of the rest of the device ID's content to be reused. This requirement is necessary because otherwise the race conditions between asynchronous notification of device ID addition and deletion would be too difficult to sort out.

只要存在引用设备ID的布局,设备ID就会存在。如果没有引用设备ID的布局,服务器可以随时删除设备ID。一旦服务器删除设备ID,服务器不得再次将设备ID用于相同的布局类型和客户端ID。这一要求是可行的,因为设备ID是16字节长的,如果服务器的实现需要重用设备ID的其余大部分内容,那么就有足够的空间来存储生成号。这一要求是必要的,因为否则,添加和删除设备ID的异步通知之间的竞争条件将很难区分。

Device ID to device address mappings are not leased, and can be changed at any time. (Note that while device ID to device address mappings are likely to change after the metadata server restarts, the server is not required to change the mappings.) A server has two choices for changing mappings. It can recall all layouts referring to the device ID or it can use a notification mechanism.

设备ID到设备地址的映射不是租用的,可以随时更改。(请注意,虽然元数据服务器重新启动后,设备ID到设备地址的映射可能会更改,但服务器不需要更改映射。)服务器有两种更改映射的选择。它可以调用所有涉及设备ID的布局,也可以使用通知机制。

The NFSv4.1 protocol has no optimal way to recall all layouts that referred to a particular device ID (unless the server associates a single device ID with a single fsid or a single client ID; in which case, CB_LAYOUTRECALL has options for recalling all layouts associated with the fsid, client ID pair, or just the client ID).

NFSv4.1协议没有最佳方式来调用引用特定设备ID的所有布局(除非服务器将单个设备ID与单个fsid或单个客户端ID关联;在这种情况下,CB_LAYOUTRECALL具有用于调用与fsid、客户端ID对或仅客户端ID关联的所有布局的选项)。

Via a notification mechanism (see Section 20.12), device ID to device address mappings can change over the duration of server operation without recalling or revoking the layouts that refer to device ID.

通过通知机制(参见第20.12节),设备ID到设备地址的映射可以在服务器运行期间更改,而无需调用或撤销引用设备ID的布局。

The notification mechanism can also delete a device ID, but only if the client has no layouts referring to the device ID. A notification of a change to a device ID to device address mapping will immediately or eventually invalidate some or all of the device ID's mappings. The server MUST support notifications and the client must request them before they can be used. For further information about the notification types Section 20.12.

通知机制还可以删除设备ID,但前提是客户端没有引用设备ID的布局。设备ID到设备地址映射的更改通知将立即或最终使部分或全部设备ID映射无效。服务器必须支持通知,客户端必须在使用通知之前请求通知。有关通知类型的更多信息,请参见第20.12节。

12.3. pNFS Operations
12.3. pNFS操作

NFSv4.1 has several operations that are needed for pNFS servers, regardless of layout type or storage protocol. These operations are all sent to a metadata server and summarized here. While pNFS is an OPTIONAL feature, if pNFS is implemented, some operations are REQUIRED in order to comply with pNFS. See Section 17.

无论布局类型或存储协议如何,NFSv4.1都有几个pNFS服务器需要的操作。这些操作都发送到元数据服务器,并在此处进行总结。虽然pNFS是可选功能,但如果实现了pNFS,则需要执行一些操作才能符合pNFS。见第17节。

These are the fore channel pNFS operations:

这些是前通道pNFS操作:

GETDEVICEINFO (Section 18.40), as noted previously (Section 12.2.10), returns the mapping of device ID to storage device address.

如前所述(第12.2.10节),GETDEVICEINFO(第18.40节)返回设备ID到存储设备地址的映射。

GETDEVICELIST (Section 18.41) allows clients to fetch all device IDs for a specific file system.

GETDEVICELIST(第18.41节)允许客户端获取特定文件系统的所有设备ID。

LAYOUTGET (Section 18.43) is used by a client to get a layout for a file.

LAYOUTGET(第18.43节)由客户端用于获取文件的布局。

LAYOUTCOMMIT (Section 18.42) is used to inform the metadata server of the client's intent to commit data that has been written to the storage device (the storage device as originally indicated in the return value of LAYOUTGET).

LAYOUTCOMMIT(第18.42节)用于通知元数据服务器客户端提交已写入存储设备(LAYOUTGET返回值中最初指示的存储设备)的数据的意图。

LAYOUTRETURN (Section 18.44) is used to return layouts for a file, a file system ID (FSID), or a client ID.

LAYOUTRETURN(第18.44节)用于返回文件、文件系统ID(FSID)或客户端ID的布局。

These are the backchannel pNFS operations:

以下是反向通道pNFS操作:

CB_LAYOUTRECALL (Section 20.3) recalls a layout, all layouts belonging to a file system, or all layouts belonging to a client ID.

CB_LAYOUTRECALL(第20.3节)调用一个布局、属于文件系统的所有布局或属于客户端ID的所有布局。

CB_RECALL_ANY (Section 20.6) tells a client that it needs to return some number of recallable objects, including layouts, to the metadata server.

CB_RECALL_ANY(第20.6节)告诉客户机它需要将一些可重新调用的对象(包括布局)返回到元数据服务器。

CB_RECALLABLE_OBJ_AVAIL (Section 20.7) tells a client that a recallable object that it was denied (in case of pNFS, a layout denied by LAYOUTGET) due to resource exhaustion is now available.

CB_RECALLABLE_OBJ_AVAIL(第20.7节)告诉客户端,由于资源耗尽而被拒绝的可重新调用对象(在pNFS的情况下,LAYOUTGET拒绝的布局)现在可用。

CB_NOTIFY_DEVICEID (Section 20.12) notifies the client of changes to device IDs.

CB_NOTIFY_DEVICEID(第20.12节)通知客户端设备ID的更改。

12.4. pNFS Attributes
12.4. pNFS属性

A number of attributes specific to pNFS are listed and described in Section 5.12.

第5.12节列出并描述了PNF特有的许多属性。

12.5. Layout Semantics
12.5. 布局语义
12.5.1. Guarantees Provided by Layouts
12.5.1. 布局提供的保证

Layouts grant to the client the ability to access data located at a storage device with the appropriate storage protocol. The client is guaranteed the layout will be recalled when one of two things occur: either a conflicting layout is requested or the state encapsulated by the layout becomes invalid (this can happen when an event directly or indirectly modifies the layout). When a layout is recalled and returned by the client, the client continues with the ability to access file data with normal NFSv4.1 operations through the metadata server. Only the ability to access the storage devices is affected.

布局允许客户端使用适当的存储协议访问位于存储设备上的数据。当发生以下两种情况之一时,客户机将保证调用布局:请求冲突布局或布局封装的状态变为无效(当事件直接或间接修改布局时,可能会发生这种情况)。当客户端调用并返回布局时,客户端继续能够通过元数据服务器通过正常的NFSv4.1操作访问文件数据。只有访问存储设备的能力受到影响。

The requirement of NFSv4.1 that all user access rights MUST be obtained through the appropriate OPEN, LOCK, and ACCESS operations is not modified with the existence of layouts. Layouts are provided to NFSv4.1 clients, and user access still follows the rules of the protocol as if they did not exist. It is a requirement that for a client to access a storage device, a layout must be held by the client. If a storage device receives an I/O request for a byte-range for which the client does not hold a layout, the storage device SHOULD reject that I/O request. Note that the act of modifying a file for which a layout is held does not necessarily conflict with the holding of the layout that describes the file being modified. Therefore, it is the requirement of the storage protocol or layout type that determines the necessary behavior. For example, block/ volume layout types require that the layout's iomode agree with the type of I/O being performed.

NFSv4.1的要求是,所有用户访问权限必须通过适当的打开、锁定和访问操作获得,该要求不随布局的存在而修改。布局提供给NFSv4.1客户端,用户访问仍然遵循协议的规则,就好像它们不存在一样。要求客户端访问存储设备时,必须保留布局。如果存储设备接收到客户端未保存布局的字节范围的I/O请求,则存储设备应拒绝该I/O请求。请注意,修改保存布局的文件的行为不一定与保存描述所修改文件的布局冲突。因此,存储协议或布局类型的要求决定了必要的行为。例如,块/卷布局类型要求布局的iomode与正在执行的I/O类型一致。

Depending upon the layout type and storage protocol in use, storage device access permissions may be granted by LAYOUTGET and may be encoded within the type-specific layout. For an example of storage device access permissions, see an object-based protocol such as [50]. If access permissions are encoded within the layout, the metadata server SHOULD recall the layout when those permissions become invalid

根据使用的布局类型和存储协议,LAYOUTGET可以授予存储设备访问权限,并且可以在特定于类型的布局中进行编码。有关存储设备访问权限的示例,请参阅基于对象的协议,如[50]。如果访问权限在布局中编码,则元数据服务器应在这些权限无效时调用布局

for any reason -- for example, when a file becomes unwritable or inaccessible to a client. Note, clients are still required to perform the appropriate OPEN, LOCK, and ACCESS operations as described above. The degree to which it is possible for the client to circumvent these operations and the consequences of doing so must be clearly specified by the individual layout type specifications. In addition, these specifications must be clear about the requirements and non-requirements for the checking performed by the server.

出于任何原因——例如,当文件变得不可写入或客户端无法访问时。注意,客户机仍然需要执行上述适当的打开、锁定和访问操作。客户可以规避这些操作的程度以及这样做的后果必须由单独的布局类型规范明确规定。此外,这些规范必须明确服务器执行的检查的要求和非要求。

In the presence of pNFS functionality, mandatory byte-range locks MUST behave as they would without pNFS. Therefore, if mandatory file locks and layouts are provided simultaneously, the storage device MUST be able to enforce the mandatory byte-range locks. For example, if one client obtains a mandatory byte-range lock and a second client accesses the storage device, the storage device MUST appropriately restrict I/O for the range of the mandatory byte-range lock. If the storage device is incapable of providing this check in the presence of mandatory byte-range locks, then the metadata server MUST NOT grant layouts and mandatory byte-range locks simultaneously.

在有pNFS功能的情况下,强制字节范围锁的行为必须与没有pNFS时相同。因此,如果同时提供强制文件锁和布局,则存储设备必须能够强制执行强制字节范围锁。例如,如果一个客户端获得强制字节范围锁,而另一个客户端访问存储设备,则存储设备必须针对强制字节范围锁的范围适当限制I/O。如果存储设备无法在存在强制字节范围锁的情况下提供此检查,则元数据服务器不得同时授予布局和强制字节范围锁。

12.5.2. Getting a Layout
12.5.2. 获取布局

A client obtains a layout with the LAYOUTGET operation. The metadata server will grant layouts of a particular type (e.g., block/volume, object, or file). The client selects an appropriate layout type that the server supports and the client is prepared to use. The layout returned to the client might not exactly match the requested byte-range as described in Section 18.43.3. As needed a client may send multiple LAYOUTGET operations; these might result in multiple overlapping, non-conflicting layouts (see Section 12.2.8).

客户端通过LAYOUTGET操作获得布局。元数据服务器将授予特定类型的布局(例如,块/卷、对象或文件)。客户机选择服务器支持的适当布局类型,并准备使用。如第18.43.3节所述,返回给客户端的布局可能与请求的字节范围不完全匹配。根据需要,客户端可以发送多个LAYOUTGET操作;这些可能导致多个重叠、不冲突的布局(见第12.2.8节)。

In order to get a layout, the client must first have opened the file via the OPEN operation. When a client has no layout on a file, it MUST present an open stateid, a delegation stateid, or a byte-range lock stateid in the loga_stateid argument. A successful LAYOUTGET result includes a layout stateid. The first successful LAYOUTGET processed by the server using a non-layout stateid as an argument MUST have the "seqid" field of the layout stateid in the response set to one. Thereafter, the client MUST use a layout stateid (see Section 12.5.3) on future invocations of LAYOUTGET on the file, and the "seqid" MUST NOT be set to zero. Once the layout has been retrieved, it can be held across multiple OPEN and CLOSE sequences. Therefore, a client may hold a layout for a file that is not currently open by any user on the client. This allows for the caching of layouts beyond CLOSE.

为了获得布局,客户端必须首先通过OPEN操作打开文件。当客户机在文件上没有布局时,它必须在loga_stateid参数中提供open stateid、delegation stateid或byte range lock stateid。成功的LAYOUTGET结果包含布局状态ID。服务器使用非布局stateid作为参数处理的第一个成功的LAYOUTGET必须将响应中布局stateid的“seqid”字段设置为1。此后,客户机在将来调用文件上的LAYOUTGET时必须使用layout stateid(参见第12.5.3节),并且“seqid”不得设置为零。检索布局后,可以在多个打开和关闭序列中保存布局。因此,客户机可能持有当前未由客户机上的任何用户打开的文件的布局。这允许在关闭之后缓存布局。

The storage protocol used by the client to access the data on the storage device is determined by the layout's type. The client is responsible for matching the layout type with an available method to interpret and use the layout. The method for this layout type selection is outside the scope of the pNFS functionality.

客户端用于访问存储设备上的数据的存储协议由布局的类型决定。客户负责将布局类型与解释和使用布局的可用方法相匹配。此布局类型选择的方法不在pNFS功能的范围内。

Although the metadata server is in control of the layout for a file, the pNFS client can provide hints to the server when a file is opened or created about the preferred layout type and aggregation schemes. pNFS introduces a layout_hint attribute (Section 5.12.4) that the client can set at file creation time to provide a hint to the server for new files. Setting this attribute separately, after the file has been created might make it difficult, or impossible, for the server implementation to comply.

尽管元数据服务器控制文件的布局,但当打开或创建文件时,pNFS客户端可以向服务器提供有关首选布局类型和聚合方案的提示。pNFS引入了一个布局提示属性(第5.12.4节),客户端可以在文件创建时设置该属性,以向服务器提供新文件的提示。在创建文件后单独设置此属性可能会使服务器实现难以或不可能遵守。

Because the EXCLUSIVE4 createmode4 does not allow the setting of attributes at file creation time, NFSv4.1 introduces the EXCLUSIVE4_1 createmode4, which does allow attributes to be set at file creation time. In addition, if the session is created with persistent reply caches, EXCLUSIVE4_1 is neither necessary nor allowed. Instead, GUARDED4 both works better and is prescribed. Table 10 in Section 18.16.3 summarizes how a client is allowed to send an exclusive create.

由于EXCLUSIVE4 createmode4不允许在文件创建时设置属性,因此NFSv4.1引入了EXCLUSIVE4_1 createmode4,它允许在文件创建时设置属性。此外,如果会话是使用持久回复缓存创建的,那么EXCLUSIVE4_1既不必要也不允许。相反,GUARDED4效果更好,而且是处方药。第18.16.3节中的表10总结了如何允许客户端发送独占创建。

12.5.3. Layout Stateid
12.5.3. 布局状态ID

As with all other stateids, the layout stateid consists of a "seqid" and "other" field. Once a layout stateid is established, the "other" field will stay constant unless the stateid is revoked or the client returns all layouts on the file and the server disposes of the stateid. The "seqid" field is initially set to one, and is never zero on any NFSv4.1 operation that uses layout stateids, whether it is a fore channel or backchannel operation. After the layout stateid is established, the server increments by one the value of the "seqid" in each subsequent LAYOUTGET and LAYOUTRETURN response, and in each CB_LAYOUTRECALL request.

与所有其他stateid一样,布局stateid由“seqid”和“other”字段组成。一旦建立布局stateid,“其他”字段将保持不变,除非stateid被撤销,或者客户端返回文件上的所有布局,并且服务器处理stateid。“seqid”字段最初设置为1,并且在任何使用布局stateID的NFSv4.1操作上(无论是前通道操作还是后通道操作)都不会为零。建立布局stateid后,服务器在每个后续的LAYOUTGET和LAYOUTRETURN响应以及每个CB_LAYOUTRECALL请求中将“seqid”的值增加1。

Given the design goal of pNFS to provide parallelism, the layout stateid differs from other stateid types in that the client is expected to send LAYOUTGET and LAYOUTRETURN operations in parallel. The "seqid" value is used by the client to properly sort responses to LAYOUTGET and LAYOUTRETURN. The "seqid" is also used to prevent race conditions between LAYOUTGET and CB_LAYOUTRECALL. Given that the processing rules differ from layout stateids and other stateid types, only the pNFS sections of this document should be considered to determine proper layout stateid handling.

鉴于pNFS的设计目标是提供并行性,layout stateid与其他stateid类型的不同之处在于,客户端需要并行发送LAYOUTGET和LAYOUTRETURN操作。客户机使用“seqid”值对LAYOUTGET和LAYOUTRETURN的响应进行正确排序。“seqid”还用于防止LAYOUTGET和CB_LAYOUTRECALL之间的竞争条件。鉴于处理规则不同于布局stateid和其他stateid类型,因此只有本文档的pNFS部分才能确定正确的布局stateid处理。

Once the client receives a layout stateid, it MUST use the correct "seqid" for subsequent LAYOUTGET or LAYOUTRETURN operations. The correct "seqid" is defined as the highest "seqid" value from responses of fully processed LAYOUTGET or LAYOUTRETURN operations or arguments of a fully processed CB_LAYOUTRECALL operation. Since the server is incrementing the "seqid" value on each layout operation, the client may determine the order of operation processing by inspecting the "seqid" value. In the case of overlapping layout ranges, the ordering information will provide the client the knowledge of which layout ranges are held. Note that overlapping layout ranges may occur because of the client's specific requests or because the server is allowed to expand the range of a requested layout and notify the client in the LAYOUTRETURN results. Additional layout stateid sequencing requirements are provided in Section 12.5.5.2.

一旦客户端接收到布局stateid,它必须为后续的LAYOUTGET或LAYOUTRETURN操作使用正确的“seqid”。正确的“seqid”定义为完全处理的LAYOUTGET或LAYOUTRETURN操作的响应或完全处理的CB_LAYOUTRECALL操作的参数的最高“seqid”值。由于服务器在每个布局操作上递增“seqid”值,因此客户端可以通过检查“seqid”值来确定操作处理的顺序。在布局范围重叠的情况下,订购信息将向客户提供拥有哪些布局范围的知识。请注意,由于客户端的特定请求,或者由于允许服务器扩展请求布局的范围并在LAYOUTRETURN结果中通知客户端,可能会出现布局范围重叠的情况。第12.5.5.2节提供了其他布局状态ID排序要求。

The client's receipt of a "seqid" is not sufficient for subsequent use. The client must fully process the operations before the "seqid" can be used. For LAYOUTGET results, if the client is not using the forgetful model (Section 12.5.5.1), it MUST first update its record of what ranges of the file's layout it has before using the seqid. For LAYOUTRETURN results, the client MUST delete the range from its record of what ranges of the file's layout it had before using the seqid. For CB_LAYOUTRECALL arguments, the client MUST send a response to the recall before using the seqid. The fundamental requirement in client processing is that the "seqid" is used to provide the order of processing. LAYOUTGET results may be processed in parallel. LAYOUTRETURN results may be processed in parallel. LAYOUTGET and LAYOUTRETURN responses may be processed in parallel as long as the ranges do not overlap. CB_LAYOUTRECALL request processing MUST be processed in "seqid" order at all times.

客户收到的“seqid”不足以供后续使用。在使用“seqid”之前,客户必须完全处理这些操作。对于LAYOUTGET结果,如果客户机未使用遗忘模型(第12.5.5.1节),则在使用seqid之前,必须首先更新其文件布局范围的记录。对于LAYOUTRETURN结果,在使用seqid之前,客户机必须从其记录中删除该范围,该记录包含文件布局的哪些范围。对于CB_LAYOUTRECALL参数,客户端必须在使用seqid之前向调用发送响应。客户机处理的基本要求是“seqid”用于提供处理顺序。LAYOUTGET结果可以并行处理。LAYOUTRETURN结果可以并行处理。只要范围不重叠,可以并行处理LAYOUTGET和LAYOUTRETURN响应。CB_LAYOUTRECALL请求处理必须始终以“seqid”顺序处理。

Once a client has no more layouts on a file, the layout stateid is no longer valid and MUST NOT be used. Any attempt to use such a layout stateid will result in NFS4ERR_BAD_STATEID.

一旦客户端在文件上没有更多布局,布局stateid将不再有效,并且不得使用。任何使用此类布局stateid的尝试都将导致NFS4ERR_BAD_stateid。

12.5.4. Committing a Layout
12.5.4. 提交布局

Allowing for varying storage protocol capabilities, the pNFS protocol does not require the metadata server and storage devices to have a consistent view of file attributes and data location mappings. Data location mapping refers to aspects such as which offsets store data as opposed to storing holes (see Section 13.4.4 for a discussion). Related issues arise for storage protocols where a layout may hold provisionally allocated blocks where the allocation of those blocks does not survive a complete restart of both the client and server.

考虑到不同的存储协议功能,pNFS协议不要求元数据服务器和存储设备具有文件属性和数据位置映射的一致视图。数据位置映射指的是偏移存储数据而不是存储孔的方面(有关讨论,请参见第13.4.4节)。存储协议会出现相关问题,其中布局可能包含临时分配的块,而这些块的分配在客户端和服务器完全重新启动后无法继续。

Because of this inconsistency, it is necessary to resynchronize the client with the metadata server and its storage devices and make any potential changes available to other clients. This is accomplished by use of the LAYOUTCOMMIT operation.

由于这种不一致性,有必要将客户端与元数据服务器及其存储设备重新同步,并使任何潜在的更改可供其他客户端使用。这是通过使用LAYOUTCOMMIT操作完成的。

The LAYOUTCOMMIT operation is responsible for committing a modified layout to the metadata server. The data should be written and committed to the appropriate storage devices before the LAYOUTCOMMIT occurs. The scope of the LAYOUTCOMMIT operation depends on the storage protocol in use. It is important to note that the level of synchronization is from the point of view of the client that sent the LAYOUTCOMMIT. The updated state on the metadata server need only reflect the state as of the client's last operation previous to the LAYOUTCOMMIT. The metadata server is not REQUIRED to maintain a global view that accounts for other clients' I/O that may have occurred within the same time frame.

LAYOUTCOMMIT操作负责将修改后的布局提交到元数据服务器。在LAYOUTCOMMIT发生之前,应将数据写入并提交到适当的存储设备。LAYOUTCOMMIT操作的范围取决于使用的存储协议。请务必注意,同步级别是从发送LAYOUTCOMMIT的客户端的角度来确定的。元数据服务器上的更新状态只需反映LAYOUTCOMMIT之前客户端最后一次操作的状态。元数据服务器不需要维护一个全局视图来解释可能在同一时间段内发生的其他客户端的I/O。

For block/volume-based layouts, LAYOUTCOMMIT may require updating the block list that comprises the file and committing this layout to stable storage. For file-based layouts, synchronization of attributes between the metadata and storage devices, primarily the size attribute, is required.

对于基于块/卷的布局,LAYOUTCOMMIT可能需要更新包含文件的块列表,并将此布局提交到稳定存储。对于基于文件的布局,需要在元数据和存储设备之间同步属性,主要是大小属性。

The control protocol is free to synchronize the attributes before it receives a LAYOUTCOMMIT; however, upon successful completion of a LAYOUTCOMMIT, state that exists on the metadata server that describes the file MUST be synchronized with the state that exists on the storage devices that comprise that file as of the client's last sent operation. Thus, a client that queries the size of a file between a WRITE to a storage device and the LAYOUTCOMMIT might observe a size that does not reflect the actual data written.

控制协议可以在收到LAYOUTCOMMIT之前自由地同步属性;但是,成功完成LAYOUTCOMMIT后,元数据服务器上描述文件的状态必须与客户端上次发送操作时构成该文件的存储设备上的状态同步。因此,在写入存储设备和LAYOUTCOMMIT之间查询文件大小的客户端可能观察到的大小不反映写入的实际数据。

The client MUST have a layout in order to send a LAYOUTCOMMIT operation.

客户端必须具有布局才能发送LAYOUTCOMMIT操作。

12.5.4.1. LAYOUTCOMMIT and change/time_modify
12.5.4.1. 布局提交和更改/时间\u修改

The change and time_modify attributes may be updated by the server when the LAYOUTCOMMIT operation is processed. The reason for this is that some layout types do not support the update of these attributes when the storage devices process I/O operations. If a client has a layout with the LAYOUTIOMODE4_RW iomode on the file, the client MAY provide a suggested value to the server for time_modify within the arguments to LAYOUTCOMMIT. Based on the layout type, the provided value may or may not be used. The server should sanity-check the client-provided values before they are used. For example, the server

在处理LAYOUTCOMMIT操作时,服务器可能会更新change和time_modify属性。原因是某些布局类型不支持在存储设备处理I/O操作时更新这些属性。如果客户机的布局文件上有LAYOUTIOMODE4\u RW iomode,则客户机可能会在LAYOUTCOMMIT的参数中向服务器提供建议的time\u modify值。根据布局类型,可以使用或不使用提供的值。服务器应在使用客户机提供的值之前对其进行健全检查。例如,服务器

should ensure that time does not flow backwards. The client always has the option to set time_modify through an explicit SETATTR operation.

应该确保时间不会倒流。客户端始终可以通过显式SETATTR操作设置时间\修改。

For some layout protocols, the storage device is able to notify the metadata server of the occurrence of an I/O; as a result, the change and time_modify attributes may be updated at the metadata server. For a metadata server that is capable of monitoring updates to the change and time_modify attributes, LAYOUTCOMMIT processing is not required to update the change attribute. In this case, the metadata server must ensure that no further update to the data has occurred since the last update of the attributes; file-based protocols may have enough information to make this determination or may update the change attribute upon each file modification. This also applies for the time_modify attribute. If the server implementation is able to determine that the file has not been modified since the last time_modify update, the server need not update time_modify at LAYOUTCOMMIT. At LAYOUTCOMMIT completion, the updated attributes should be visible if that file was modified since the latest previous LAYOUTCOMMIT or LAYOUTGET.

对于一些布局协议,存储设备能够通知元数据服务器发生I/O;因此,可以在元数据服务器上更新更改和时间修改属性。对于能够监视更改和时间\修改属性更新的元数据服务器,更新更改属性不需要LAYOUTCOMMIT处理。在这种情况下,元数据服务器必须确保自上次更新属性以来,数据没有进一步更新;基于文件的协议可能有足够的信息来进行此确定,或者可能在每次文件修改时更新更改属性。这也适用于“时间\修改”属性。如果服务器实现能够确定自上次\u modify update以来文件未被修改,则服务器无需在LAYOUTCOMMIT时更新时间\u modify。在LAYOUTCOMMIT完成时,如果该文件是自上次LAYOUTCOMMIT或LAYOUTGET之后修改的,则更新的属性应该可见。

12.5.4.2. LAYOUTCOMMIT and size
12.5.4.2. 布局和大小

The size of a file may be updated when the LAYOUTCOMMIT operation is used by the client. One of the fields in the argument to LAYOUTCOMMIT is loca_last_write_offset; this field indicates the highest byte offset written but not yet committed with the LAYOUTCOMMIT operation. The data type of loca_last_write_offset is newoffset4 and is switched on a boolean value, no_newoffset, that indicates if a previous write occurred or not. If no_newoffset is FALSE, an offset is not given. If the client has a layout with LAYOUTIOMODE4_RW iomode on the file, with a byte-range (denoted by the values of lo_offset and lo_length) that overlaps loca_last_write_offset, then the client MAY set no_newoffset to TRUE and provide an offset that will update the file size. Keep in mind that offset is not the same as length, though they are related. For example, a loca_last_write_offset value of zero means that one byte was written at offset zero, and so the length of the file is at least one byte.

当客户端使用LAYOUTCOMMIT操作时,文件的大小可能会更新。LAYOUTCOMMIT参数中的一个字段是loca\u last\u write\u offset;此字段表示已写入但尚未通过LAYOUTCOMMIT操作提交的最高字节偏移量。loca_last_write_offset的数据类型为newoffset4,并打开一个布尔值no_newoffset,该值指示是否发生了上一次写入。如果no_newoffset为FALSE,则不提供偏移量。如果客户机在文件上具有LAYOUTIOMODE4_RW iomode布局,其字节范围(由lo_offset和lo_length的值表示)与loca_last_write_offset重叠,则客户机可以将no_newoffset设置为TRUE,并提供将更新文件大小的偏移量。请记住,偏移量与长度不同,尽管它们是相关的。例如,loca_last_write_偏移量值为零意味着在偏移量为零时写入了一个字节,因此文件长度至少为一个字节。

The metadata server may do one of the following:

元数据服务器可以执行以下操作之一:

1. Update the file's size using the last write offset provided by the client as either the true file size or as a hint of the file size. If the metadata server has a method available, any new value for file size should be sanity-checked. For example, the file must not be truncated if the client presents a last write offset less than the file's current size.

1. 使用客户端提供的上一次写入偏移量作为真实文件大小或作为文件大小的提示来更新文件大小。如果元数据服务器有可用的方法,则应检查文件大小的任何新值是否正常。例如,如果客户端提供的上次写入偏移量小于文件的当前大小,则不得截断该文件。

2. Ignore the client-provided last write offset; the metadata server must have sufficient knowledge from other sources to determine the file's size. For example, the metadata server queries the storage devices with the control protocol.

2. 忽略客户端提供的上次写入偏移量;元数据服务器必须从其他来源获得足够的知识,以确定文件的大小。例如,元数据服务器使用控制协议查询存储设备。

The method chosen to update the file's size will depend on the storage device's and/or the control protocol's capabilities. For example, if the storage devices are block devices with no knowledge of file size, the metadata server must rely on the client to set the last write offset appropriately.

选择用于更新文件大小的方法将取决于存储设备和/或控制协议的功能。例如,如果存储设备是不知道文件大小的块设备,则元数据服务器必须依靠客户端适当地设置最后一次写入偏移量。

The results of LAYOUTCOMMIT contain a new size value in the form of a newsize4 union data type. If the file's size is set as a result of LAYOUTCOMMIT, the metadata server must reply with the new size; otherwise, the new size is not provided. If the file size is updated, the metadata server SHOULD update the storage devices such that the new file size is reflected when LAYOUTCOMMIT processing is complete. For example, the client should be able to read up to the new file size.

LAYOUTCOMMIT的结果以newsize4联合数据类型的形式包含一个新的大小值。如果由于LAYOUTCOMMIT而设置了文件大小,则元数据服务器必须使用新的大小进行回复;否则,将不提供新的尺寸。如果文件大小已更新,元数据服务器应更新存储设备,以便在LAYOUTCOMMIT处理完成时反映新的文件大小。例如,客户端应该能够读取到新的文件大小。

The client can extend the length of a file or truncate a file by sending a SETATTR operation to the metadata server with the size attribute specified. If the size specified is larger than the current size of the file, the file is "zero extended", i.e., zeros are implicitly added between the file's previous EOF and the new EOF. (In many implementations, the zero-extended byte-range of the file consists of unallocated holes in the file.) When the client writes past EOF via WRITE, the SETATTR operation does not need to be used.

客户端可以通过向元数据服务器发送具有指定大小属性的SETATTR操作来扩展文件的长度或截断文件。如果指定的大小大于文件的当前大小,则文件为“零扩展”,即在文件的先前EOF和新EOF之间隐式添加零。(在许多实现中,文件的零扩展字节范围由文件中未分配的孔组成。)当客户端通过WRITE写入超过EOF时,不需要使用SETATTR操作。

12.5.4.3. LAYOUTCOMMIT and layoutupdate
12.5.4.3. LAYOUTCOMMIT和layoutupdate

The LAYOUTCOMMIT argument contains a loca_layoutupdate field (Section 18.42.1) of data type layoutupdate4 (Section 3.3.18). This argument is a layout-type-specific structure. The structure can be used to pass arbitrary layout-type-specific information from the client to the metadata server at LAYOUTCOMMIT time. For example, if using a block/volume layout, the client can indicate to the metadata server which reserved or allocated blocks the client used or did not use. The content of loca_layoutupdate (field lou_body) need not be the same layout-type-specific content returned by LAYOUTGET (Section 18.43.2) in the loc_body field of the lo_content field of the logr_layout field. The content of loca_layoutupdate is defined by the layout type specification and is opaque to LAYOUTCOMMIT.

LAYOUTCOMMIT参数包含数据类型为layoutupdate4(第3.3.18节)的loca_layoutupdate字段(第18.42.1节)。此参数是布局类型特定的结构。该结构可用于在LAYOUTCOMMIT时将特定于布局类型的任意信息从客户端传递到元数据服务器。例如,如果使用块/卷布局,客户端可以向元数据服务器指示客户端使用或未使用的保留或分配的块。本地布局更新(字段lou_body)的内容不必与logr_布局字段lou内容字段的lou_body字段中LAYOUTGET(第18.43.2节)返回的布局类型特定内容相同。loca_layoutupdate的内容由布局类型规范定义,对于LAYOUTCOMMIT是不透明的。

12.5.5. Recalling a Layout
12.5.5. 回忆布局

Since a layout protects a client's access to a file via a direct client-storage-device path, a layout need only be recalled when it is semantically unable to serve this function. Typically, this occurs when the layout no longer encapsulates the true location of the file over the byte-range it represents. Any operation or action, such as server-driven restriping or load balancing, that changes the layout will result in a recall of the layout. A layout is recalled by the CB_LAYOUTRECALL callback operation (see Section 20.3) and returned with LAYOUTRETURN (see Section 18.44). The CB_LAYOUTRECALL operation may recall a layout identified by a byte-range, all layouts associated with a file system ID (FSID), or all layouts associated with a client ID. Section 12.5.5.2 discusses sequencing issues surrounding the getting, returning, and recalling of layouts.

由于布局保护客户端通过直接客户端存储设备路径访问文件,因此仅当布局在语义上无法提供此功能时,才需要调用布局。通常,当布局不再封装文件在其表示的字节范围内的真实位置时,就会发生这种情况。任何更改布局的操作或操作(如服务器驱动的重新调整或负载平衡)都将导致重新调用布局。布局由CB_LAYOUTRECALL回调操作(参见第20.3节)调用,并与LAYOUTRETURN一起返回(参见第18.44节)。CB_LAYOUTRECALL操作可调用由字节范围标识的布局、与文件系统ID(FSID)关联的所有布局或与客户端ID关联的所有布局。第12.5.5.2节讨论了布局获取、返回和调用的顺序问题。

An iomode is also specified when recalling a layout. Generally, the iomode in the recall request must match the layout being returned; for example, a recall with an iomode of LAYOUTIOMODE4_RW should cause the client to only return LAYOUTIOMODE4_RW layouts and not LAYOUTIOMODE4_READ layouts. However, a special LAYOUTIOMODE4_ANY enumeration is defined to enable recalling a layout of any iomode; in other words, the client must return both LAYOUTIOMODE4_READ and LAYOUTIOMODE4_RW layouts.

调用布局时也会指定iomode。通常,调用请求中的iomode必须与返回的布局匹配;例如,iomode为LAYOUTIOMODE4_RW的调用应导致客户端仅返回LAYOUTIOMODE4_RW布局,而不返回LAYOUTIOMODE4_读取布局。但是,定义了一个特殊的LayoutIomode4Any枚举,以允许调用任何iomode的布局;换句话说,客户端必须同时返回LAYOUTIOMODE4_READ和LAYOUTIOMODE4_RW布局。

A REMOVE operation SHOULD cause the metadata server to recall the layout to prevent the client from accessing a non-existent file and to reclaim state stored on the client. Since a REMOVE may be delayed until the last close of the file has occurred, the recall may also be delayed until this time. After the last reference on the file has been released and the file has been removed, the client should no longer be able to perform I/O using the layout. In the case of a file-based layout, the data server SHOULD return NFS4ERR_STALE in response to any operation on the removed file.

删除操作应导致元数据服务器调用布局,以防止客户端访问不存在的文件,并回收存储在客户端上的状态。由于删除可能会延迟到文件的最后一次关闭,因此调用也可能会延迟到此时。在文件上的最后一个引用被释放并且文件被删除后,客户端应该不再能够使用布局执行I/O。对于基于文件的布局,数据服务器应返回NFS4ERR_STALE,以响应对已删除文件的任何操作。

Once a layout has been returned, the client MUST NOT send I/Os to the storage devices for the file, byte-range, and iomode represented by the returned layout. If a client does send an I/O to a storage device for which it does not hold a layout, the storage device SHOULD reject the I/O.

返回布局后,客户端不得向存储设备发送由返回布局表示的文件、字节范围和iomode的I/O。如果客户端确实向其未保存布局的存储设备发送I/O,则存储设备应拒绝该I/O。

Although pNFS does not alter the file data caching capabilities of clients, or their semantics, it recognizes that some clients may perform more aggressive write-behind caching to optimize the benefits provided by pNFS. However, write-behind caching may negatively affect the latency in returning a layout in response to a CB_LAYOUTRECALL; this is similar to file delegations and the impact that file data caching has on DELEGRETURN. Client implementations

尽管pNFS不会改变客户端的文件数据缓存功能或其语义,但它认识到一些客户端可能会执行更积极的写后缓存,以优化pNFS提供的好处。但是,写后缓存可能会对返回布局以响应CB_LAYOUTRECALL的延迟产生负面影响;这类似于文件委派以及文件数据缓存对DELEGRETURN的影响。客户端实现

SHOULD limit the amount of unwritten data they have outstanding at any one time in order to prevent excessively long responses to CB_LAYOUTRECALL. Once a layout is recalled, a server MUST wait one lease period before taking further action. As soon as a lease period has passed, the server may choose to fence the client's access to the storage devices if the server perceives the client has taken too long to return a layout. However, just as in the case of data delegation and DELEGRETURN, the server may choose to wait, given that the client is showing forward progress on its way to returning the layout. This forward progress can take the form of successful interaction with the storage devices or of sub-portions of the layout being returned by the client. The server can also limit exposure to these problems by limiting the byte-ranges initially provided in the layouts and thus the amount of outstanding modified data.

应限制他们在任何时候未完成的未写入数据量,以防止对CB_LAYOUTRECALL的响应过长。调用布局后,服务器必须等待一个租用期,然后才能采取进一步的操作。租赁期一过,服务器就可以选择限制客户机对存储设备的访问,如果服务器发现客户机花了太长时间才返回布局。但是,与数据委派和DELEGRETURN的情况一样,服务器可能会选择等待,因为客户端在返回布局的过程中显示了前进的进度。这种向前的进展可以采取与存储设备成功交互的形式,也可以是客户端返回的布局的子部分。服务器还可以通过限制布局中最初提供的字节范围,从而限制未完成的修改数据量,来限制这些问题的暴露。

12.5.5.1. Layout Recall Callback Robustness
12.5.5.1. 布局回调健壮性

It has been assumed thus far that pNFS client state (layout ranges and iomode) for a file exactly matches that of the pNFS server for that file. This assumption leads to the implication that any callback results in a LAYOUTRETURN or set of LAYOUTRETURNs that exactly match the range in the callback, since both client and server agree about the state being maintained. However, it can be useful if this assumption does not always hold. For example:

到目前为止,假定文件的pNFS客户端状态(布局范围和iomode)与该文件的pNFS服务器状态完全匹配。这一假设意味着任何回调都会产生一个LAYOUTRETURN或一组与回调中的范围完全匹配的LAYOUTRETURN,因为客户端和服务器都同意要维护的状态。然而,如果这个假设并不总是成立的话,它可能是有用的。例如:

o If conflicts that require callbacks are very rare, and a server can use a multi-file callback to recover per-client resources (e.g., via an FSID recall or a multi-file recall within a single CB_COMPOUND), the result may be significantly less client-server pNFS traffic.

o 如果需要回调的冲突非常罕见,并且服务器可以使用多文件回调来恢复每个客户端资源(例如,通过FSID回调或单个CB_组合中的多文件回调),则结果可能会大大减少客户端-服务器pNFS通信量。

o It may be useful for servers to maintain information about what ranges are held by a client on a coarse-grained basis, leading to the server's layout ranges being beyond those actually held by the client. In the extreme, a server could manage conflicts on a per-file basis, only sending whole-file callbacks even though clients may request and be granted sub-file ranges.

o 对于服务器来说,在粗粒度的基础上维护关于客户机持有的范围的信息可能很有用,这会导致服务器的布局范围超出客户机实际持有的范围。在极端情况下,服务器可以基于每个文件管理冲突,只发送整个文件回调,即使客户端可能请求并被授予子文件范围。

o It may be useful for clients to "forget" details about what layouts and ranges the client actually has, leading to the server's layout ranges being beyond those that the client "thinks" it has. As long as the client does not assume it has layouts that are beyond what the server has granted, this is a safe practice. When a client forgets what ranges and layouts it has, and it receives a CB_LAYOUTRECALL operation, the client MUST follow up with a LAYOUTRETURN for what the server recalled, or alternatively return the NFS4ERR_NOMATCHING_LAYOUT error if it has no layout to return in the recalled range.

o 客户机“忘记”客户机实际拥有的布局和范围的细节可能很有用,这会导致服务器的布局范围超出客户机“认为”它拥有的范围。只要客户机不认为其布局超出了服务器所允许的范围,这是一种安全的做法。当客户机忘记了其拥有的范围和布局,并接收到CB_LAYOUTRECALL操作时,客户机必须跟进服务器调用的LAYOUTRETURN,或者如果在调用的范围内没有要返回的布局,则返回NFS4ERR_NOMATCHING_布局错误。

o In order to avoid errors, it is vital that a client not assign itself layout permissions beyond what the server has granted, and that the server not forget layout permissions that have been granted. On the other hand, if a server believes that a client holds a layout that the client does not know about, it is useful for the client to cleanly indicate completion of the requested recall either by sending a LAYOUTRETURN operation for the entire requested range or by returning an NFS4ERR_NOMATCHING_LAYOUT error to the CB_LAYOUTRECALL.

o 为了避免错误,客户机不能为自己分配超出服务器授予的布局权限,服务器也不能忘记已授予的布局权限。另一方面,如果服务器认为客户端持有客户端不知道的布局,则客户端通过发送整个请求范围的LAYOUTRETURN操作或将NFS4ERR_NOMATCHING_布局错误返回给CB_LayoutCall来清楚地指示请求的调用完成是有用的。

Thus, in light of the above, it is useful for a server to be able to send callbacks for layout ranges it has not granted to a client, and for a client to return ranges it does not hold. A pNFS client MUST always return layouts that comprise the full range specified by the recall. Note, the full recalled layout range need not be returned as part of a single operation, but may be returned in portions. This allows the client to stage the flushing of dirty data and commits and returns of layouts. Also, it indicates to the metadata server that the client is making progress.

因此,鉴于上述情况,服务器能够为其未授予客户机的布局范围发送回调,并且客户机能够返回其未保留的范围,这是非常有用的。pNFS客户端必须始终返回包含召回指定的完整范围的布局。注意,完全调用的布局范围不需要作为单个操作的一部分返回,但可以部分返回。这允许客户端对脏数据进行阶段性刷新,并提交和返回布局。此外,它还向元数据服务器指示客户端正在取得进展。

When a layout is returned, the client MUST NOT have any outstanding I/O requests to the storage devices involved in the layout. Rephrasing, the client MUST NOT return the layout while it has outstanding I/O requests to the storage device.

返回布局时,客户端不得对布局中涉及的存储设备有任何未完成的I/O请求。换言之,当客户端对存储设备有未完成的I/O请求时,客户端不得返回布局。

Even with this requirement for the client, it is possible that I/O requests may be presented to a storage device no longer allowed to perform them. Since the server has no strict control as to when the client will return the layout, the server may later decide to unilaterally revoke the client's access to the storage devices as provided by the layout. In choosing to revoke access, the server must deal with the possibility of lingering I/O requests, i.e., I/O requests that are still in flight to storage devices identified by the revoked layout. All layout type specifications MUST define whether unilateral layout revocation by the metadata server is supported; if it is, the specification must also describe how lingering writes are processed. For example, storage devices identified by the revoked layout could be fenced off from the client that held the layout.

即使对客户端有此要求,也可能会将I/O请求呈现给不再允许执行这些请求的存储设备。由于服务器对客户端何时返回布局没有严格的控制,因此服务器稍后可能会决定单方面撤销客户端对布局提供的存储设备的访问。在选择撤销访问时,服务器必须处理延迟I/O请求的可能性,即仍在传输到由撤销布局标识的存储设备的I/O请求。所有版面类型规范必须定义是否支持元数据服务器单方面撤销版面;如果是,规范还必须描述如何处理延迟写入。例如,由已撤销布局标识的存储设备可以与保存该布局的客户端隔离。

In order to ensure client/server convergence with regard to layout state, the final LAYOUTRETURN operation in a sequence of LAYOUTRETURN operations for a particular recall MUST specify the entire range being recalled, echoing the recalled layout type, iomode, recall/ return type (FILE, FSID, or ALL), and byte-range, even if layouts pertaining to partial ranges were previously returned. In addition, if the client holds no layouts that overlap the range being recalled,

为了确保客户机/服务器在布局状态方面的一致性,特定调用的LAYOUTRETURN操作序列中的最终LAYOUTRETURN操作必须指定被调用的整个范围,响应调用的布局类型、iomode、调用/返回类型(文件、FSID或全部)和字节范围,即使之前返回了与部分范围相关的布局。此外,如果客户没有与召回范围重叠的布局,

the client should return the NFS4ERR_NOMATCHING_LAYOUT error code to CB_LAYOUTRECALL. This allows the server to update its view of the client's layout state.

客户端应将NFS4ERR_NOMATCHING_布局错误代码返回CB_LAYOUTRECALL。这允许服务器更新客户端布局状态的视图。

12.5.5.2. Sequencing of Layout Operations
12.5.5.2. 布局操作的顺序

As with other stateful operations, pNFS requires the correct sequencing of layout operations. pNFS uses the "seqid" in the layout stateid to provide the correct sequencing between regular operations and callbacks. It is the server's responsibility to avoid inconsistencies regarding the layouts provided and the client's responsibility to properly serialize its layout requests and layout returns.

与其他有状态操作一样,pNFS需要布局操作的正确顺序。pNFS使用布局stateid中的“seqid”在常规操作和回调之间提供正确的顺序。服务器负责避免提供的布局不一致,客户端负责正确序列化其布局请求和布局返回。

12.5.5.2.1. Layout Recall and Return Sequencing
12.5.5.2.1. 布局调用和返回顺序

One critical issue with regard to layout operations sequencing concerns callbacks. The protocol must defend against races between the reply to a LAYOUTGET or LAYOUTRETURN operation and a subsequent CB_LAYOUTRECALL. A client MUST NOT process a CB_LAYOUTRECALL that implies one or more outstanding LAYOUTGET or LAYOUTRETURN operations to which the client has not yet received a reply. The client detects such a CB_LAYOUTRECALL by examining the "seqid" field of the recall's layout stateid. If the "seqid" is not exactly one higher than what the client currently has recorded, and the client has at least one LAYOUTGET and/or LAYOUTRETURN operation outstanding, the client knows the server sent the CB_LAYOUTRECALL after sending a response to an outstanding LAYOUTGET or LAYOUTRETURN. The client MUST wait before processing such a CB_LAYOUTRECALL until it processes all replies for outstanding LAYOUTGET and LAYOUTRETURN operations for the corresponding file with seqid less than the seqid given by CB_LAYOUTRECALL (lor_stateid; see Section 20.3.)

关于布局操作排序的一个关键问题是回调。该协议必须防止对LAYOUTGET或LAYOUTRETURN操作的应答与随后的CB_LAYOUTRECALL之间的竞争。客户机不得处理暗示一个或多个未完成的LAYOUTGET或LAYOUTRETURN操作(客户机尚未收到回复)的CB_LayoutCall。客户端通过检查调用的布局stateid的“seqid”字段来检测这样的CB_布局调用。如果“seqid”不完全高于客户端当前记录的值,并且客户端至少有一个LAYOUTGET和/或LAYOUTRETURN操作未完成,则客户端知道服务器在发送对未完成LAYOUTGET或LAYOUTRETURN的响应后发送了CB_LayoutRetCall。在处理此类CB_LAYOUTRECALL之前,客户机必须等待,直到它处理seqid小于CB_LAYOUTRECALL给出的seqid(lor_stateid;参见第20.3节)的相应文件的所有未完成LAYOUTGET和LAYOUTRETURN操作的回复

In addition to the seqid-based mechanism, Section 2.10.6.3 describes the sessions mechanism for allowing the client to detect callback race conditions and delay processing such a CB_LAYOUTRECALL. The server MAY reference conflicting operations in the CB_SEQUENCE that precedes the CB_LAYOUTRECALL. Because the server has already sent replies for these operations before sending the callback, the replies may race with the CB_LAYOUTRECALL. The client MUST wait for all the referenced calls to complete and update its view of the layout state before processing the CB_LAYOUTRECALL.

除了基于seqid的机制外,第2.10.6.3节还描述了会话机制,该机制允许客户端检测回调竞争条件并延迟处理此类CB_LAYOUTRECALL。服务器可能引用CB_LayoutCall之前的CB_序列中的冲突操作。因为服务器在发送回调之前已经发送了这些操作的回复,所以回复可能与CB_LAYOUTRECALL竞争。在处理CB_LAYOUTRECALL之前,客户端必须等待所有引用的调用完成并更新其布局状态视图。

12.5.5.2.1.1. Get/Return Sequencing
12.5.5.2.1.1. 获取/返回序列

The protocol allows the client to send concurrent LAYOUTGET and LAYOUTRETURN operations to the server. The protocol does not provide any means for the server to process the requests in the same order in

该协议允许客户端向服务器发送并发LAYOUTGET和LAYOUTRETURN操作。该协议没有为服务器提供任何方法,以相同的顺序处理请求

which they were created. However, through the use of the "seqid" field in the layout stateid, the client can determine the order in which parallel outstanding operations were processed by the server. Thus, when a layout retrieved by an outstanding LAYOUTGET operation intersects with a layout returned by an outstanding LAYOUTRETURN on the same file, the order in which the two conflicting operations are processed determines the final state of the overlapping layout. The order is determined by the "seqid" returned in each operation: the operation with the higher seqid was executed later.

他们是被创造出来的。但是,通过使用布局stateid中的“seqid”字段,客户机可以确定服务器处理并行未完成操作的顺序。因此,当未完成LAYOUTGET操作检索的布局与未完成LAYOUTRETURN在同一文件上返回的布局相交时,两个冲突操作的处理顺序决定了重叠布局的最终状态。顺序由每个操作中返回的“seqid”确定:具有较高seqid的操作稍后执行。

It is permissible for the client to send multiple parallel LAYOUTGET operations for the same file or multiple parallel LAYOUTRETURN operations for the same file or a mix of both.

允许客户端为同一文件发送多个并行LAYOUTGET操作,或为同一文件发送多个并行LAYOUTRETURN操作,或两者的混合。

It is permissible for the client to use the current stateid (see Section 16.2.3.1.2) for LAYOUTGET operations, for example, when compounding LAYOUTGETs or compounding OPEN and LAYOUTGETs. It is also permissible to use the current stateid when compounding LAYOUTRETURNs.

允许客户端在LAYOUTGET操作中使用当前stateid(参见第16.2.3.1.2节),例如,在复合LAYOUTGETs或复合OPEN和LAYOUTGETs时。复合LAYOUTRETURNs时,还允许使用当前stateid。

It is permissible for the client to use the current stateid when combining LAYOUTRETURN and LAYOUTGET operations for the same file in the same COMPOUND request since the server MUST process these in order. However, if a client does send such COMPOUND requests, it MUST NOT have more than one outstanding for the same file at the same time, and it MUST NOT have other LAYOUTGET or LAYOUTRETURN operations outstanding at the same time for that same file.

在同一复合请求中对同一文件组合LAYOUTRETURN和LAYOUTGET操作时,允许客户端使用当前stateid,因为服务器必须按顺序处理这些操作。但是,如果客户端确实发送此类复合请求,则同一文件在同一时间不得有多个未完成的操作,并且同一文件在同一时间不得有其他未完成的LAYOUTGET或LAYOUTRETURN操作。

12.5.5.2.1.2. Client Considerations
12.5.5.2.1.2. 客户注意事项

Consider a pNFS client that has sent a LAYOUTGET, and before it receives the reply to LAYOUTGET, it receives a CB_LAYOUTRECALL for the same file with an overlapping range. There are two possibilities, which the client can distinguish via the layout stateid in the recall.

考虑发送一个LayOutGET的PNFS客户端,并在接收到LayOutGET的答复之前,它接收具有重叠范围的同一文件的CBSLayOutlook。有两种可能性,客户端可以通过调用中的布局stateid来区分。

1. The server processed the LAYOUTGET before sending the recall, so the LAYOUTGET must be waited for because it may be carrying layout information that will need to be returned to deal with the CB_LAYOUTRECALL.

1. 服务器在发送回调之前处理了LAYOUTGET,因此必须等待LAYOUTGET,因为它可能包含处理CB_LAYOUTRECALL需要返回的布局信息。

2. The server sent the callback before receiving the LAYOUTGET. The server will not respond to the LAYOUTGET until the CB_LAYOUTRECALL is processed.

2. 服务器在接收LAYOUTGET之前发送了回调。在处理CB_LAYOUTRECALL之前,服务器不会响应LAYOUTGET。

If these possibilities cannot be distinguished, a deadlock could result, as the client must wait for the LAYOUTGET response before processing the recall in the first case, but that response will not

如果无法区分这些可能性,则可能会导致死锁,因为在第一种情况下,客户端必须在处理回调之前等待LAYOUTGET响应,但该响应不会

arrive until after the recall is processed in the second case. Note that in the first case, the "seqid" in the layout stateid of the recall is two greater than what the client has recorded; in the second case, the "seqid" is one greater than what the client has recorded. This allows the client to disambiguate between the two cases. The client thus knows precisely which possibility applies.

在第二种情况下处理召回后到达。注意,在第一种情况下,调用的布局stateid中的“seqid”比客户端记录的值大两倍;在第二种情况下,“seqid”比客户端记录的值大一个。这允许客户机消除这两种情况之间的歧义。因此,客户确切地知道哪种可能性适用。

In case 1, the client knows it needs to wait for the LAYOUTGET response before processing the recall (or the client can return NFS4ERR_DELAY).

在案例1中,客户端知道在处理回调之前需要等待LAYOUTGET响应(或者客户端可以返回NFS4ERR_延迟)。

In case 2, the client will not wait for the LAYOUTGET response before processing the recall because waiting would cause deadlock. Therefore, the action at the client will only require waiting in the case that the client has not yet seen the server's earlier responses to the LAYOUTGET operation(s).

在案例2中,客户端在处理回调之前不会等待LAYOUTGET响应,因为等待会导致死锁。因此,只有在客户端尚未看到服务器对LAYOUTGET操作的早期响应的情况下,客户端的操作才需要等待。

The recall process can be considered completed when the final LAYOUTRETURN operation for the recalled range is completed. The LAYOUTRETURN uses the layout stateid (with seqid) specified in CB_LAYOUTRECALL. If the client uses multiple LAYOUTRETURNs in processing the recall, the first LAYOUTRETURN will use the layout stateid as specified in CB_LAYOUTRECALL. Subsequent LAYOUTRETURNs will use the highest seqid as is the usual case.

当召回范围的最终LAYOUTRETURN操作完成时,可以认为召回过程已完成。LAYOUTRETURN使用CB_LAYOUTRECALL中指定的布局状态ID(带seqid)。如果客户端在处理回调时使用多个LAYOUTRETURN,则第一个LAYOUTRETURN将使用CB_LAYOUTRETURN中指定的layout stateid。后续的LAYOUTRETURNs将像通常情况一样使用最高的seqid。

12.5.5.2.1.3. Server Considerations
12.5.5.2.1.3. 服务器注意事项

Consider a race from the metadata server's point of view. The metadata server has sent a CB_LAYOUTRECALL and receives an overlapping LAYOUTGET for the same file before the LAYOUTRETURN(s) that respond to the CB_LAYOUTRECALL. There are three cases:

从元数据服务器的角度考虑竞赛。元数据服务器已发送CB_LAYOUTRECALL,并在响应CB_LAYOUTRECALL的LAYOUTRETURN之前接收同一文件的重叠LAYOUTGET。有三种情况:

1. The client sent the LAYOUTGET before processing the CB_LAYOUTRECALL. The "seqid" in the layout stateid of the arguments of LAYOUTGET is one less than the "seqid" in CB_LAYOUTRECALL. The server returns NFS4ERR_RECALLCONFLICT to the client, which indicates to the client that there is a pending recall.

1. 客户端在处理CB_LAYOUTRECALL之前发送了LAYOUTGET。LAYOUTGET参数的layout stateid中的“seqid”比CB_LAYOUTRECALL中的“seqid”小一个。服务器将NFS4ERR_RECALLCONFLICT返回给客户端,这向客户端指示存在挂起的回调。

2. The client sent the LAYOUTGET after processing the CB_LAYOUTRECALL, but the LAYOUTGET arrived before the LAYOUTRETURN and the response to CB_LAYOUTRECALL that completed that processing. The "seqid" in the layout stateid of LAYOUTGET is equal to or greater than that of the "seqid" in CB_LAYOUTRECALL. The server has not received a response to the CB_LAYOUTRECALL, so it returns NFS4ERR_RECALLCONFLICT.

2. 客户端在处理CB_LAYOUTRECALL后发送LAYOUTGET,但LAYOUTGET在LAYOUTRETURN和对完成该处理的CB_LAYOUTRECALL的响应之前到达。LAYOUTGET的layout stateid中的“seqid”等于或大于CB_LAYOUTRECALL中的“seqid”。服务器尚未收到对CB_LAYOUTRECALL的响应,因此返回NFS4ERR_RECALLCONFLICT。

3. The client sent the LAYOUTGET after processing the

3. 客户端在处理后发送了LAYOUTGET

CB_LAYOUTRECALL; the server received the CB_LAYOUTRECALL response, but the LAYOUTGET arrived before the LAYOUTRETURN that completed that processing. The "seqid" in the layout stateid of LAYOUTGET is equal to that of the "seqid" in CB_LAYOUTRECALL.

CB_LAYOUTRECALL;服务器收到CB_LAYOUTRECALL响应,但LAYOUTGET在完成该处理的LAYOUTRETURN之前到达。LAYOUTGET的layout stateid中的“seqid”与CB_LAYOUTRECALL中的“seqid”相等。

The server has received a response to the CB_LAYOUTRECALL, so it returns NFS4ERR_RETURNCONFLICT.

服务器已收到对CB_LAYOUTRECALL的响应,因此返回NFS4ERR_RETURNCONFLICT。

12.5.5.2.1.4. Wraparound and Validation of Seqid
12.5.5.2.1.4. Seqid的封装与验证

The rules for layout stateid processing differ from other stateids in the protocol because the "seqid" value cannot be zero and the stateid's "seqid" value changes in a CB_LAYOUTRECALL operation. The non-zero requirement combined with the inherent parallelism of layout operations means that a set of LAYOUTGET and LAYOUTRETURN operations may contain the same value for "seqid". The server uses a slightly modified version of the modulo arithmetic as described in Section 2.10.6.1 when incrementing the layout stateid's "seqid". The difference is that zero is not a valid value for "seqid"; when the value of a "seqid" is 0xFFFFFFFF, the next valid value will be 0x00000001. The modulo arithmetic is also used for the comparisons of "seqid" values in the processing of CB_LAYOUTRECALL events as described above in Section 12.5.5.2.1.3.

布局stateid处理的规则不同于协议中的其他stateid,因为“seqid”值不能为零,并且stateid的“seqid”值在CB_LAYOUTRECALL操作中更改。非零要求与布局操作固有的并行性相结合意味着一组LAYOUTGET和LAYOUTRETURN操作可能包含相同的“seqid”值。当增加布局stateid的“seqid”时,服务器使用第2.10.6.1节中描述的稍微修改的模运算版本。区别在于零不是“seqid”的有效值;当“seqid”的值为0xFFFFFFFF时,下一个有效值将为0x00000001。模运算还用于比较上文第12.5.5.2.1.3节所述CB_LAYOUTRECALL事件处理过程中的“seqid”值。

Just as the server validates the "seqid" in the event of CB_LAYOUTRECALL usage, as described in Section 12.5.5.2.1.3, the server also validates the "seqid" value to ensure that it is within an appropriate range. This range represents the degree of parallelism the server supports for layout stateids. If the client is sending multiple layout operations to the server in parallel, by definition, the "seqid" value in the supplied stateid will not be the current "seqid" as held by the server. The range of parallelism spans from the highest or current "seqid" to a "seqid" value in the past. To assist in the discussion, the server's current "seqid" value for a layout stateid is defined as SERVER_CURRENT_SEQID. The lowest "seqid" value that is acceptable to the server is represented by PAST_SEQID. And the value for the range of valid "seqid"s or range of parallelism is VALID_SEQID_RANGE. Therefore, the following holds: VALID_SEQID_RANGE = SERVER_CURRENT_SEQID - PAST_SEQID. In the following, all arithmetic is the modulo arithmetic as described above.

正如第12.5.5.2.1.3节所述,服务器在使用CB_LAYOUTRECALL时验证“seqid”,服务器也验证“seqid”值,以确保其在适当范围内。此范围表示服务器对布局状态ID支持的并行度。如果客户端并行向服务器发送多个布局操作,根据定义,提供的stateid中的“seqid”值将不是服务器持有的当前“seqid”。并行性的范围从最高或当前的“seqid”到过去的“seqid”值。为了帮助讨论,布局stateid的服务器当前“seqid”值被定义为server_current_seqid。服务器可接受的最低“seqid”值由过去的seqid表示。有效“seqid”的范围或并行性的范围的值是有效的\u seqid\u范围。因此,以下内容适用:VALID_SEQID_RANGE=SERVER_CURRENT_SEQID-pass_SEQID。在下文中,所有算法都是如上所述的模运算。

The server MUST support a minimum VALID_SEQID_RANGE. The minimum is defined as: VALID_SEQID_RANGE = summation over 1..N of (ca_maxoperations(i) - 1), where N is the number of session fore channels and ca_maxoperations(i) is the value of the ca_maxoperations returned from CREATE_SESSION of the i'th session. The reason for "- 1" is to allow for the required SEQUENCE operation. The server MAY

服务器必须支持最小有效的\u SEQID\u范围。最小值定义为:VALID_SEQID_RANGE=1..N(ca_maxoperations(i)-1)之和,其中N是会话前通道的数量,ca_maxoperations(i)是从第i个会话的CREATE_会话返回的ca_maxoperations的值。“-1”的原因是允许进行所需的顺序操作。服务器可能会

support a VALID_SEQID_RANGE value larger than the minimum. The maximum VALID_SEQID_RANGE is (2 ^ 32 - 2) (accounting for zero not being a valid "seqid" value).

支持大于最小值的有效_SEQID_范围值。最大有效_SEQID_范围为(2^32-2)(说明零不是有效的“SEQID”值)。

If the server finds the "seqid" is zero, the NFS4ERR_BAD_STATEID error is returned to the client. The server further validates the "seqid" to ensure it is within the range of parallelism, VALID_SEQID_RANGE. If the "seqid" value is outside of that range, the error NFS4ERR_OLD_STATEID is returned to the client. Upon receipt of NFS4ERR_OLD_STATEID, the client updates the stateid in the layout request based on processing of other layout requests and re-sends the operation to the server.

如果服务器发现“seqid”为零,则NFS4ERR_BAD_STATEID错误将返回给客户端。服务器进一步验证“seqid”以确保它在并行范围内,即有效的seqid范围内。如果“seqid”值超出该范围,则将错误NFS4ERR_OLD_STATEID返回给客户端。在收到NFS4ERR_OLD_STATEID后,客户端根据对其他布局请求的处理更新布局请求中的STATEID,并将操作重新发送到服务器。

12.5.5.2.1.5. Bulk Recall and Return
12.5.5.2.1.5. 批量召回和退货

pNFS supports recalling and returning all layouts that are for files belonging to a particular fsid (LAYOUTRECALL4_FSID, LAYOUTRETURN4_FSID) or client ID (LAYOUTRECALL4_ALL, LAYOUTRETURN4_ALL). There are no "bulk" stateids, so detection of races via the seqid is not possible. The server MUST NOT initiate bulk recall while another recall is in progress, or the corresponding LAYOUTRETURN is in progress or pending. In the event the server sends a bulk recall while the client has a pending or in-progress LAYOUTRETURN, CB_LAYOUTRECALL, or LAYOUTGET, the client returns NFS4ERR_DELAY. In the event the client sends a LAYOUTGET or LAYOUTRETURN while a bulk recall is in progress, the server returns NFS4ERR_RECALLCONFLICT. If the client sends a LAYOUTGET or LAYOUTRETURN after the server receives NFS4ERR_DELAY from a bulk recall, then to ensure forward progress, the server MAY return NFS4ERR_RECALLCONFLICT.

pNFS支持调用和返回属于特定fsid(LAYOUTRECALL4_fsid、LAYOUTRETURN4_fsid)或客户端ID(LAYOUTRECALL4_all、LAYOUTRETURN4_all)的文件的所有布局。没有“批量”StateID,因此无法通过seqid检测种族。当另一个回调正在进行,或者相应的LAYOUTRETURN正在进行或挂起时,服务器不得启动批量回调。如果服务器在客户端具有挂起或正在进行的LAYOUTRETURN、CB_LAYOUTRECALL或LAYOUTGET时发送批量回调,则客户端返回NFS4ERR_延迟。如果在批量回调过程中客户端发送LAYOUTGET或LAYOUTRETURN,服务器将返回NFS4ERR_RECALLCONFLICT。如果客户端在服务器接收到来自批量回调的NFS4ERR_延迟后发送LAYOUTGET或LAYOUTRETURN,则为了确保转发进度,服务器可能会返回NFS4ERR_RECALLCONFLICT。

Once a CB_LAYOUTRECALL of LAYOUTRECALL4_ALL is sent, the server MUST NOT allow the client to use any layout stateid except for LAYOUTCOMMIT operations. Once the client receives a CB_LAYOUTRECALL of LAYOUTRECALL4_ALL, it MUST NOT use any layout stateid except for LAYOUTCOMMIT operations. Once a LAYOUTRETURN of LAYOUTRETURN4_ALL is sent, all layout stateids granted to the client ID are freed. The client MUST NOT use the layout stateids again. It MUST use LAYOUTGET to obtain new layout stateids.

发送LAYOUTRECALL4_ALL的CB_LAYOUTRECALL后,服务器不得允许客户端使用任何layout stateid,LAYOUTCOMMIT操作除外。一旦客户端接收到LAYOUTRECALL的CB_LAYOUTRECALL或LAYOUTRECALL 4_ALL,除了LAYOUTCOMMIT操作外,它不得使用任何layout stateid。发送LAYOUTRETURN的LAYOUTRETURN4_ALL后,将释放授予客户端ID的所有LayoutStateID。客户端不得再次使用布局状态ID。它必须使用LAYOUTGET来获取新的布局状态ID。

Once a CB_LAYOUTRECALL of LAYOUTRECALL4_FSID is sent, the server MUST NOT allow the client to use any layout stateid that refers to a file with the specified fsid except for LAYOUTCOMMIT operations. Once the client receives a CB_LAYOUTRECALL of LAYOUTRECALL4_ALL, it MUST NOT use any layout stateid that refers to a file with the specified fsid except for LAYOUTCOMMIT operations. Once a LAYOUTRETURN of LAYOUTRETURN4_FSID is sent, all layout stateids granted to the referenced fsid are freed. The client MUST NOT use those freed

发送LAYOUTRECALL4_FSID的CB_LAYOUTRECALL后,服务器不得允许客户端使用引用具有指定FSID的文件的任何layout stateid,LAYOUTCOMMIT操作除外。一旦客户端接收到LAYOUTRECALL的CB_LAYOUTRECALL或LAYOUTRECALL 4_ALL,除LAYOUTCOMMIT操作外,它不得使用引用具有指定fsid的文件的任何layout stateid。发送LAYOUTRETURN的LayoutReturn4FSID后,将释放授予引用FSID的所有布局StateID。客户端不能使用那些已释放的

layout stateids for files with the referenced fsid again. Subsequently, for any file with the referenced fsid, to use a layout, the client MUST first send a LAYOUTGET operation in order to obtain a new layout stateid for that file.

再次为具有引用的fsid的文件布局StateID。随后,对于具有引用的fsid的任何文件,要使用布局,客户端必须首先发送LAYOUTGET操作,以获取该文件的新布局stateid。

If the server has sent a bulk CB_LAYOUTRECALL and receives a LAYOUTGET, or a LAYOUTRETURN with a stateid, the server MUST return NFS4ERR_RECALLCONFLICT. If the server has sent a bulk CB_LAYOUTRECALL and receives a LAYOUTRETURN with an lr_returntype that is not equal to the lor_recalltype of the CB_LAYOUTRECALL, the server MUST return NFS4ERR_RECALLCONFLICT.

如果服务器已发送大容量CB_LAYOUTRECALL并收到LAYOUTGET或带有stateid的LAYOUTRETURN,则服务器必须返回NFS4ERR_RECALLCONFLICT。如果服务器已发送大容量CB_LAYOUTRECALL并接收到具有lr_returntype的LAYOUTRETURN,该lr_returntype不等于CB_LAYOUTRECALL的lor_recalltype,则服务器必须返回NFS4ERR_RECALLCONFLICT。

12.5.6. Revoking Layouts
12.5.6. 撤销布局

Parallel NFS permits servers to revoke layouts from clients that fail to respond to recalls and/or fail to renew their lease in time. Depending on the layout type, the server might revoke the layout and might take certain actions with respect to the client's I/O to data servers.

并行NFS允许服务器从未能响应召回和/或未能及时续订租约的客户端撤销布局。根据布局类型的不同,服务器可能会撤销布局,并可能会针对客户端对数据服务器的I/O执行某些操作。

12.5.7. Metadata Server Write Propagation
12.5.7. 元数据服务器写入传播

Asynchronous writes written through the metadata server may be propagated lazily to the storage devices. For data written asynchronously through the metadata server, a client performing a read at the appropriate storage device is not guaranteed to see the newly written data until a COMMIT occurs at the metadata server. While the write is pending, reads to the storage device may give out either the old data, the new data, or a mixture of new and old. Upon completion of a synchronous WRITE or COMMIT (for asynchronously written data), the metadata server MUST ensure that storage devices give out the new data and that the data has been written to stable storage. If the server implements its storage in any way such that it cannot obey these constraints, then it MUST recall the layouts to prevent reads being done that cannot be handled correctly. Note that the layouts MUST be recalled prior to the server responding to the associated WRITE operations.

通过元数据服务器写入的异步写入可能会延迟传播到存储设备。对于通过元数据服务器异步写入的数据,在元数据服务器上发生提交之前,在适当的存储设备上执行读取的客户端不能保证看到新写入的数据。当写入挂起时,对存储设备的读取可能会发出旧数据、新数据或新旧数据的混合。同步写入或提交(对于异步写入的数据)完成后,元数据服务器必须确保存储设备发出新数据,并且数据已写入稳定存储。如果服务器以任何方式实现其存储,以致无法遵守这些约束,那么它必须调用布局,以防止执行无法正确处理的读取。请注意,必须在服务器响应相关写入操作之前调用布局。

12.6. pNFS Mechanics
12.6. pNFS力学

This section describes the operations flow taken by a pNFS client to a metadata server and storage device.

本节描述pNFS客户端对元数据服务器和存储设备的操作流程。

When a pNFS client encounters a new FSID, it sends a GETATTR to the NFSv4.1 server for the fs_layout_type (Section 5.12.1) attribute. If the attribute returns at least one layout type, and the layout types returned are among the set supported by the client, the client knows that pNFS is a possibility for the file system. If, from the server

当pNFS客户端遇到新的FSID时,它会向NFSv4.1服务器发送一个GETATTR,以获取fs_布局_类型(第5.12.1节)属性。如果该属性返回至少一种布局类型,并且返回的布局类型在客户端支持的集合中,则客户端知道文件系统可能使用pNFS。如果是,则从服务器

that returned the new FSID, the client does not have a client ID that came from an EXCHANGE_ID result that returned EXCHGID4_FLAG_USE_PNFS_MDS, it MUST send an EXCHANGE_ID to the server with the EXCHGID4_FLAG_USE_PNFS_MDS bit set. If the server's response does not have EXCHGID4_FLAG_USE_PNFS_MDS, then contrary to what the fs_layout_type attribute said, the server does not support pNFS, and the client will not be able use pNFS to that server; in this case, the server MUST return NFS4ERR_NOTSUPP in response to any pNFS operation.

如果返回了新的FSID,则客户端没有来自返回EXCHGID4_标志\u使用\u PNFS\u MDS的EXCHANGE\u ID结果的客户端ID,它必须向服务器发送EXCHANGE\u ID,并设置EXCHGID4_标志\u使用\u PNFS\u MDS位。如果服务器的响应没有EXCHGID4_标志_USE_PNFS_MDS,则与fs_layout_type属性所述相反,服务器不支持PNFS,客户端将无法对该服务器使用PNFS;在这种情况下,服务器必须返回NFS4ERR_NOTSUPP以响应任何pNFS操作。

The client then creates a session, requesting a persistent session, so that exclusive creates can be done with single round trip via the createmode4 of GUARDED4. If the session ends up not being persistent, the client will use EXCLUSIVE4_1 for exclusive creates.

然后,客户端创建一个会话,请求一个持久会话,这样就可以通过GUARDED4的createmode4通过一次往返完成独占创建。如果会话最终不是持久的,客户端将使用EXCLUSIVE4_1进行独占创建。

If a file is to be created on a pNFS-enabled file system, the client uses the OPEN operation. With the normal set of attributes that may be provided upon OPEN used for creation, there is an OPTIONAL layout_hint attribute. The client's use of layout_hint allows the client to express its preference for a layout type and its associated layout details. The use of a createmode4 of UNCHECKED4, GUARDED4, or EXCLUSIVE4_1 will allow the client to provide the layout_hint attribute at create time. The client MUST NOT use EXCLUSIVE4 (see Table 10). The client is RECOMMENDED to combine a GETATTR operation after the OPEN within the same COMPOUND. The GETATTR may then retrieve the layout_type attribute for the newly created file. The client will then know what layout type the server has chosen for the file and therefore what storage protocol the client must use.

如果要在启用pNFS的文件系统上创建文件,客户端将使用OPEN操作。对于打开时提供的用于创建的常规属性集,有一个可选的布局提示属性。客户端使用layout_提示可以让客户端表达其对布局类型及其关联布局细节的偏好。使用未选中4、GUARDED4或EXCLUSIVE4\u 1的createmode4将允许客户端在创建时提供layout\u提示属性。客户不得使用排他性4(见表10)。建议客户端在同一化合物中打开后合并GETATTR操作。然后,GETATTR可以检索新创建文件的布局类型属性。然后,客户机将知道服务器为文件选择的布局类型,以及客户机必须使用的存储协议。

If the client wants to open an existing file, then it also includes a GETATTR to determine what layout type the file supports.

如果客户机想要打开现有文件,那么它还包括一个GETATTR来确定文件支持的布局类型。

The GETATTR in either the file creation or plain file open case can also include the layout_blksize and layout_alignment attributes so that the client can determine optimal offsets and lengths for I/O on the file.

文件创建或普通文件打开情况下的GETATTR还可以包括layout_blksize和layout_alignment属性,以便客户端可以确定文件上I/O的最佳偏移量和长度。

Assuming the client supports the layout type returned by GETATTR and it chooses to use pNFS for data access, it then sends LAYOUTGET using the filehandle and stateid returned by OPEN, specifying the range it wants to do I/O on. The response is a layout, which may be a subset of the range for which the client asked. It also includes device IDs and a description of how data is organized (or in the case of writing, how data is to be organized) across the devices. The device IDs and data description are encoded in a format that is specific to the layout type, but the client is expected to understand.

假设客户端支持GETATTR返回的布局类型,并选择使用pNFS进行数据访问,那么它将使用OPEN返回的filehandle和stateid发送LAYOUTGET,并指定要对其执行I/O的范围。响应是一个布局,它可能是客户要求的范围的子集。它还包括设备ID和关于如何跨设备组织数据(或在写入的情况下,如何组织数据)的描述。设备ID和数据描述以特定于布局类型的格式进行编码,但客户机应该理解。

When the client wants to send an I/O, it determines to which device ID it needs to send the I/O command by examining the data description in the layout. It then sends a GETDEVICEINFO to find the device address(es) of the device ID. The client then sends the I/O request to one of device ID's device addresses, using the storage protocol defined for the layout type. Note that if a client has multiple I/Os to send, these I/O requests may be done in parallel.

当客户端想要发送I/O时,它通过检查布局中的数据描述来确定需要向哪个设备ID发送I/O命令。然后,它发送一个GETDEVICEINFO以查找设备ID的设备地址。然后,客户端使用为布局类型定义的存储协议将I/O请求发送到设备ID的一个设备地址。请注意,如果客户机有多个I/O要发送,则这些I/O请求可以并行完成。

If the I/O was a WRITE, then at some point the client may want to use LAYOUTCOMMIT to commit the modification time and the new size of the file (if it believes it extended the file size) to the metadata server and the modified data to the file system.

如果I/O是写操作,那么在某个时候,客户机可能希望使用LAYOUTCOMMIT将修改时间和文件的新大小(如果它认为扩展了文件大小)提交给元数据服务器,并将修改后的数据提交给文件系统。

12.7. Recovery
12.7. 恢复

Recovery is complicated by the distributed nature of the pNFS protocol. In general, crash recovery for layouts is similar to crash recovery for delegations in the base NFSv4.1 protocol. However, the client's ability to perform I/O without contacting the metadata server introduces subtleties that must be handled correctly if the possibility of file system corruption is to be avoided.

pNFS协议的分布式特性使恢复变得复杂。一般来说,布局的崩溃恢复与基本NFSv4.1协议中代表团的崩溃恢复类似。但是,客户端在不联系元数据服务器的情况下执行I/O的能力引入了一些微妙之处,如果要避免文件系统损坏的可能性,就必须正确处理这些细微之处。

12.7.1. Recovery from Client Restart
12.7.1. 从客户端重新启动恢复

Client recovery for layouts is similar to client recovery for other lock and delegation state. When a pNFS client restarts, it will lose all information about the layouts that it previously owned. There are two methods by which the server can reclaim these resources and allow otherwise conflicting layouts to be provided to other clients.

布局的客户端恢复类似于其他锁定和委派状态的客户端恢复。当pNFS客户端重新启动时,它将丢失以前拥有的所有布局信息。服务器可以通过两种方法回收这些资源,并允许向其他客户端提供冲突的布局。

The first is through the expiry of the client's lease. If the client recovery time is longer than the lease period, the client's lease will expire and the server will know that state may be released. For layouts, the server may release the state immediately upon lease expiry or it may allow the layout to persist, awaiting possible lease revival, as long as no other layout conflicts.

第一种是通过客户的租约到期。如果客户端恢复时间长于租约期,则客户端租约将到期,服务器将知道该状态可能会被释放。对于布局,服务器可以在租约到期后立即释放状态,也可以允许布局保留,等待可能的租约恢复,只要没有其他布局冲突。

The second is through the client restarting in less time than it takes for the lease period to expire. In such a case, the client will contact the server through the standard EXCHANGE_ID protocol. The server will find that the client's co_ownerid matches the co_ownerid of the previous client invocation, but that the verifier is different. The server uses this as a signal to release all layout state associated with the client's previous invocation. In this scenario, the data written by the client but not covered by a successful LAYOUTCOMMIT is in an undefined state; it may have been

第二种方法是通过客户端重新启动,所需时间少于租赁期到期所需的时间。在这种情况下,客户端将通过标准的EXCHANGE\u ID协议与服务器联系。服务器将发现客户端的co_ownerid与上一次客户端调用的co_ownerid匹配,但验证器不同。服务器将此用作释放与客户端先前调用关联的所有布局状态的信号。在此场景中,由客户端写入但未被成功LAYOUTCOMMIT覆盖的数据处于未定义状态;可能是

written or it may now be lost. This is acceptable behavior and it is the client's responsibility to use LAYOUTCOMMIT to achieve the desired level of stability.

写的,否则现在可能会丢失。这是可以接受的行为,客户有责任使用LAYOUTCOMMIT实现所需的稳定性级别。

12.7.2. Dealing with Lease Expiration on the Client
12.7.2. 处理客户的租约到期问题

If a client believes its lease has expired, it MUST NOT send I/O to the storage device until it has validated its lease. The client can send a SEQUENCE operation to the metadata server. If the SEQUENCE operation is successful, but sr_status_flag has SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, or SEQ4_STATUS_ADMIN_STATE_REVOKED set, the client MUST NOT use currently held layouts. The client has two choices to recover from the lease expiration. First, for all modified but uncommitted data, the client writes it to the metadata server using the FILE_SYNC4 flag for the WRITEs, or WRITE and COMMIT. Second, the client re-establishes a client ID and session with the server and obtains new layouts and device-ID-to-device-address mappings for the modified data ranges and then writes the data to the storage devices with the newly obtained layouts.

如果客户端认为其租约已过期,则在验证租约之前,不得向存储设备发送I/O。客户端可以向元数据服务器发送序列操作。如果序列操作成功,但sr_status_标志具有SEQ4_status_EXPIRED_ALL_STATE_reversed、SEQ4_status_EXPIRED_SOME_STATE_reversed或SEQ4_status_ADMIN_STATE_reversed集,则客户端不得使用当前保留的布局。客户有两种选择可以从租约到期时恢复。首先,对于所有已修改但未提交的数据,客户机使用文件同步4标志将其写入元数据服务器。其次,客户机重新建立客户机ID和与服务器的会话,并获得修改后数据范围的新布局和设备ID到设备地址的映射,然后使用新获得的布局将数据写入存储设备。

If sr_status_flags from the metadata server has SEQ4_STATUS_RESTART_RECLAIM_NEEDED set (or SEQUENCE returns NFS4ERR_BAD_SESSION and CREATE_SESSION returns NFS4ERR_STALE_CLIENTID), then the metadata server has restarted, and the client SHOULD recover using the methods described in Section 12.7.4.

如果元数据服务器的sr_status_标志设置了SEQ4_status_RESTART_reclain_NEEDED(或SEQUENCE返回NFS4ERR_BAD_SESSION,CREATE_SESSION返回NFS4ERR_STALE_CLIENTID),则元数据服务器已重新启动,客户端应使用第12.7.4节中描述的方法进行恢复。

If sr_status_flags from the metadata server has SEQ4_STATUS_LEASE_MOVED set, then the client recovers by following the procedure described in Section 11.7.7.1. After that, the client may get an indication that the layout state was not moved with the file system. The client recovers as in the other applicable situations discussed in the first two paragraphs of this section.

如果元数据服务器的sr_status_标志设置了SEQ4_status_LEASE_MOVED,则客户端将按照第11.7.7.1节中描述的过程进行恢复。之后,客户端可能会收到布局状态未随文件系统一起移动的指示。客户恢复与本节前两段讨论的其他适用情况相同。

If sr_status_flags reports no loss of state, then the lease for the layouts that the client has are valid and renewed, and the client can once again send I/O requests to the storage devices.

如果sr_status_flags报告没有状态丢失,则客户端拥有的布局租约有效并已续订,客户端可以再次向存储设备发送I/O请求。

While clients SHOULD NOT send I/Os to storage devices that may extend past the lease expiration time period, this is not always possible, for example, an extended network partition that starts after the I/O is sent and does not heal until the I/O request is received by the storage device. Thus, the metadata server and/or storage devices are responsible for protecting themselves from I/Os that are both sent before the lease expires and arrive after the lease expires. See Section 12.7.3.

虽然客户端不应向可能超过租约到期时间的存储设备发送I/O,但这并不总是可能的,例如,在发送I/O后启动的扩展网络分区,在存储设备接收到I/O请求之前不会恢复。因此,元数据服务器和/或存储设备负责保护自己不受租约到期前发送和租约到期后到达的I/O的影响。见第12.7.3节。

12.7.3. Dealing with Loss of Layout State on the Metadata Server
12.7.3. 处理元数据服务器上布局状态的丢失

This is a description of the case where all of the following are true:

这是对以下情况的描述:

o the metadata server has not restarted

o 元数据服务器尚未重新启动

o a pNFS client's layouts have been discarded (usually because the client's lease expired) and are invalid

o pNFS客户端的布局已被丢弃(通常是因为客户端的租约过期),并且无效

o an I/O from the pNFS client arrives at the storage device

o 来自pNFS客户端的I/O到达存储设备

The metadata server and its storage devices MUST solve this by fencing the client. In other words, they MUST solve this by preventing the execution of I/O operations from the client to the storage devices after layout state loss. The details of how fencing is done are specific to the layout type. The solution for NFSv4.1 file-based layouts is described in (Section 13.11), and solutions for other layout types are in their respective external specification documents.

元数据服务器及其存储设备必须通过保护客户端来解决此问题。换句话说,它们必须通过防止在布局状态丢失后执行从客户端到存储设备的I/O操作来解决这一问题。如何设置围栏的详细信息取决于布局类型。NFSv4.1基于文件的布局的解决方案在(第13.11节)中描述,其他布局类型的解决方案在其各自的外部规范文件中描述。

12.7.4. Recovery from Metadata Server Restart
12.7.4. 从元数据服务器重新启动中恢复

The pNFS client will discover that the metadata server has restarted via the methods described in Section 8.4.2 and discussed in a pNFS-specific context in Paragraph 2, of Section 12.7.2. The client MUST stop using layouts and delete the device ID to device address mappings it previously received from the metadata server. Having done that, if the client wrote data to the storage device without committing the layouts via LAYOUTCOMMIT, then the client has additional work to do in order to have the client, metadata server, and storage device(s) all synchronized on the state of the data.

pNFS客户端将发现元数据服务器已通过第8.4.2节中描述的方法重新启动,并在第12.7.2节第2段的pNFS特定上下文中讨论。客户端必须停止使用布局,并删除以前从元数据服务器收到的设备ID到设备地址的映射。完成此操作后,如果客户端在未通过LAYOUTCOMMIT提交布局的情况下将数据写入存储设备,则客户端还有其他工作要做,以便使客户端、元数据服务器和存储设备在数据状态上都同步。

o If the client has data still modified and unwritten in the client's memory, the client has only two choices.

o 如果客户机内存中仍有修改和未写入的数据,则客户机只有两个选择。

1. The client can obtain a layout via LAYOUTGET after the server's grace period and write the data to the storage devices.

1. 在服务器的宽限期之后,客户端可以通过LAYOUTGET获得布局,并将数据写入存储设备。

2. The client can WRITE that data through the metadata server using the WRITE (Section 18.32) operation, and then obtain layouts as desired.

2. 客户端可以使用WRITE(第18.32节)操作通过元数据服务器写入数据,然后根据需要获得布局。

o If the client asynchronously wrote data to the storage device, but still has a copy of the data in its memory, then it has available to it the recovery options listed above in the previous bullet

o 如果客户端异步将数据写入存储设备,但其内存中仍有数据副本,则它可以使用上一个项目符号中列出的恢复选项

point. If the metadata server is also in its grace period, the client has available to it the options below in the next bullet point.

指向如果元数据服务器也在其宽限期内,则客户机可以在下一个要点中使用以下选项。

o The client does not have a copy of the data in its memory and the metadata server is still in its grace period. The client cannot use LAYOUTGET (within or outside the grace period) to reclaim a layout because the contents of the response from LAYOUTGET may not match what it had previously. The range might be different or the client might get the same range but the content of the layout might be different. Even if the content of the layout appears to be the same, the device IDs may map to different device addresses, and even if the device addresses are the same, the device addresses could have been assigned to a different storage device. The option of retrieving the data from the storage device and writing it to the metadata server per the recovery scenario described above is not available because, again, the mappings of range to device ID, device ID to device address, and device address to physical device are stale, and new mappings via new LAYOUTGET do not solve the problem.

o 客户端的内存中没有数据副本,元数据服务器仍在其宽限期内。客户端无法使用LAYOUTGET(在宽限期内或宽限期外)回收布局,因为来自LAYOUTGET的响应的内容可能与以前的内容不匹配。范围可能不同,或者客户端可能获得相同的范围,但布局的内容可能不同。即使布局的内容看起来相同,设备id也可能映射到不同的设备地址,即使设备地址相同,设备地址也可能被分配到不同的存储设备。根据上述恢复场景从存储设备检索数据并将其写入元数据服务器的选项不可用,因为范围到设备ID、设备ID到设备地址以及设备地址到物理设备的映射都已过时,并且通过new LAYOUTGET的新映射无法解决此问题。

The only recovery option for this scenario is to send a LAYOUTCOMMIT in reclaim mode, which the metadata server will accept as long as it is in its grace period. The use of LAYOUTCOMMIT in reclaim mode informs the metadata server that the layout has changed. It is critical that the metadata server receive this information before its grace period ends, and thus before it starts allowing updates to the file system.

此场景的唯一恢复选项是以回收模式发送LAYOUTCOMMIT,只要元数据服务器处于其宽限期,它就会接受该模式。在回收模式下使用LAYOUTCOMMIT会通知元数据服务器布局已更改。元数据服务器必须在其宽限期结束之前接收此信息,从而在其开始允许更新文件系统之前接收此信息,这一点至关重要。

To send LAYOUTCOMMIT in reclaim mode, the client sets the loca_reclaim field of the operation's arguments (Section 18.42.1) to TRUE. During the metadata server's recovery grace period (and only during the recovery grace period) the metadata server is prepared to accept LAYOUTCOMMIT requests with the loca_reclaim field set to TRUE.

要在回收模式下发送LAYOUTCOMMIT,客户端将操作参数(第18.42.1节)的loca_回收字段设置为TRUE。在元数据服务器的恢复宽限期内(并且仅在恢复宽限期内),元数据服务器准备接受loca_Reclain字段设置为TRUE的LAYOUTCOMMIT请求。

When loca_reclaim is TRUE, the client is attempting to commit changes to the layout that occurred prior to the restart of the metadata server. The metadata server applies some consistency checks on the loca_layoutupdate field of the arguments to determine whether the client can commit the data written to the storage device to the file system. The loca_layoutupdate field is of data type layoutupdate4 and contains layout-type-specific content (in the lou_body field of loca_layoutupdate). The layout-type-specific information that loca_layoutupdate might have is discussed in Section 12.5.4.3. If the metadata server's consistency checks on loca_layoutupdate succeed, then the metadata server MUST commit the data (as described by the loca_offset,

当loca_Reclain为TRUE时,客户端将尝试提交在重新启动元数据服务器之前发生的布局更改。元数据服务器对参数的loca_layoutupdate字段应用一些一致性检查,以确定客户端是否可以将写入存储设备的数据提交到文件系统。loca_layoutupdate字段的数据类型为layoutupdate4,包含特定于布局类型的内容(在loca_layoutupdate的lou_正文字段中)。第12.5.4.3节讨论了loca_layoutupdate可能具有的布局类型特定信息。如果元数据服务器对loca_layoutupdate的一致性检查成功,则元数据服务器必须提交数据(如loca_偏移所述,

loca_length, and loca_layoutupdate fields of the arguments) that was written to the storage device. If the metadata server's consistency checks on loca_layoutupdate fail, the metadata server rejects the LAYOUTCOMMIT operation and makes no changes to the file system. However, any time LAYOUTCOMMIT with loca_reclaim TRUE fails, the pNFS client has lost all the data in the range defined by <loca_offset, loca_length>. A client can defend against this risk by caching all data, whether written synchronously or asynchronously in its memory, and by not releasing the cached data until a successful LAYOUTCOMMIT. This condition does not hold true for all layout types; for example, file-based storage devices need not suffer from this limitation.

写入存储设备的loca_长度和loca_布局更新参数字段)。如果元数据服务器在loca_layoutupdate上的一致性检查失败,元数据服务器将拒绝LAYOUTCOMMIT操作,并且不对文件系统进行任何更改。但是,每当LAYOUTCOMMIT with loca\u Reclain TRUE失败时,pNFS客户端就会丢失由<loca\u offset,loca\u length>定义的范围内的所有数据。客户机可以通过缓存其内存中的所有数据(无论是同步写入还是异步写入)以及在成功LAYOUTCOMMIT之前不释放缓存的数据来防范这种风险。此条件不适用于所有布局类型;例如,基于文件的存储设备不必受此限制。

o The client does not have a copy of the data in its memory and the metadata server is no longer in its grace period; i.e., the metadata server returns NFS4ERR_NO_GRACE. As with the scenario in the above bullet point, the failure of LAYOUTCOMMIT means the data in the range <loca_offset, loca_length> lost. The defense against the risk is the same -- cache all written data on the client until a successful LAYOUTCOMMIT.

o 客户机内存中没有数据副本,元数据服务器不再处于其宽限期内;i、 例如,元数据服务器返回NFS4ERR_NO_GRACE。与上述要点中的场景一样,LAYOUTCOMMIT的失败意味着<loca_offset,loca_length>范围内的数据丢失。防范风险的方法是相同的——缓存客户端上的所有写入数据,直到成功的LAYOUTCOMMIT。

12.7.5. Operations during Metadata Server Grace Period
12.7.5. 元数据服务器宽限期内的操作

Some of the recovery scenarios thus far noted that some operations (namely, WRITE and LAYOUTGET) might be permitted during the metadata server's grace period. The metadata server may allow these operations during its grace period. For LAYOUTGET, the metadata server must reliably determine that servicing such a request will not conflict with an impending LAYOUTCOMMIT reclaim request. For WRITE, the metadata server must reliably determine that servicing the request will not conflict with an impending OPEN or with a LOCK where the file has mandatory byte-range locking enabled.

到目前为止,一些恢复场景注意到在元数据服务器的宽限期内可能允许某些操作(即写入和布局获取)。元数据服务器可以在其宽限期内允许这些操作。对于LAYOUTGET,元数据服务器必须可靠地确定为此类请求提供服务不会与即将到来的LAYOUTCOMMIT回收请求冲突。对于写入,元数据服务器必须可靠地确定为请求提供服务不会与即将打开的文件冲突,也不会与文件启用了强制字节范围锁定的锁定冲突。

As mentioned previously, for expediency, the metadata server might reject some operations (namely, WRITE and LAYOUTGET) during its grace period, because the simplest correct approach is to reject all non-reclaim pNFS requests and WRITE operations by returning the NFS4ERR_GRACE error. However, depending on the storage protocol (which is specific to the layout type) and metadata server implementation, the metadata server may be able to determine that a particular request is safe. For example, a metadata server may save provisional allocation mappings for each file to stable storage, as well as information about potentially conflicting OPEN share modes and mandatory byte-range locks that might have been in effect at the time of restart, and the metadata server may use this information during the recovery grace period to determine that a WRITE request is safe.

如前所述,为了方便起见,元数据服务器可能会在其宽限期内拒绝某些操作(即WRITE和LAYOUTGET),因为最简单的正确方法是通过返回NFS4ERR_宽限期错误来拒绝所有非回收pNFS请求和写操作。但是,根据存储协议(特定于布局类型)和元数据服务器实现,元数据服务器可能能够确定特定请求是否安全。例如,元数据服务器可以将每个文件的临时分配映射保存到稳定存储器,以及关于可能发生冲突的开放共享模式和强制字节范围锁的信息,这些锁在重启时可能已经生效,并且元数据服务器可以在恢复宽限期期间使用该信息来确定写入请求是安全的。

12.7.6. Storage Device Recovery
12.7.6. 存储设备恢复

Recovery from storage device restart is mostly dependent upon the layout type in use. However, there are a few general techniques a client can use if it discovers a storage device has crashed while holding modified, uncommitted data that was asynchronously written. First and foremost, it is important to realize that the client is the only one that has the information necessary to recover non-committed data since it holds the modified data and probably nothing else does. Second, the best solution is for the client to err on the side of caution and attempt to rewrite the modified data through another path.

从存储设备重启恢复主要取决于使用的布局类型。但是,如果客户机在保存异步写入的已修改、未提交的数据时发现存储设备已崩溃,则可以使用一些通用技术。首先也是最重要的一点是,必须认识到,客户机是唯一拥有恢复未提交数据所需信息的客户机,因为它保存了修改后的数据,而其他可能什么也没有。其次,最好的解决方案是客户机在谨慎方面出错,并尝试通过另一条路径重写修改后的数据。

The client SHOULD immediately WRITE the data to the metadata server, with the stable field in the WRITE4args set to FILE_SYNC4. Once it does this, there is no need to wait for the original storage device.

客户端应立即将数据写入元数据服务器,WRITE4args中的稳定字段设置为FILE_SYNC4。完成此操作后,无需等待原始存储设备。

12.8. Metadata and Storage Device Roles
12.8. 元数据和存储设备角色

If the same physical hardware is used to implement both a metadata server and storage device, then the same hardware entity is to be understood to be implementing two distinct roles and it is important that it be clearly understood on behalf of which role the hardware is executing at any given time.

如果使用相同的物理硬件来实现元数据服务器和存储设备,则应将相同的硬件实体理解为实现两个不同的角色,并且必须清楚地理解该硬件在任何给定时间代表哪个角色执行。

Two sub-cases can be distinguished.

可以区分两个子案例。

1. The storage device uses NFSv4.1 as the storage protocol, i.e., the same physical hardware is used to implement both a metadata and data server. See Section 13.1 for a description of how multiple roles are handled.

1. 存储设备使用NFSv4.1作为存储协议,即使用相同的物理硬件实现元数据和数据服务器。有关如何处理多个角色的说明,请参见第13.1节。

2. The storage device does not use NFSv4.1 as the storage protocol, and the same physical hardware is used to implement both a metadata and storage device. Whether distinct network addresses are used to access the metadata server and storage device is immaterial. This is because it is always clear to the pNFS client and server, from the upper-layer protocol being used (NFSv4.1 or non-NFSv4.1), to which role the request to the common server network address is directed.

2. 存储设备不使用NFSv4.1作为存储协议,使用相同的物理硬件实现元数据和存储设备。是否使用不同的网络地址访问元数据服务器和存储设备无关紧要。这是因为pNFS客户机和服务器总是很清楚所使用的上层协议(NFSv4.1或非NFSv4.1),对公共服务器网络地址的请求指向哪个角色。

12.9. Security Considerations for pNFS
12.9. pNFS的安全考虑

pNFS separates file system metadata and data and provides access to both. There are pNFS-specific operations (listed in Section 12.3) that provide access to the metadata; all existing NFSv4.1 conventional (non-pNFS) security mechanisms and features apply to accessing the metadata. The combination of components in a pNFS

pNFS分离文件系统元数据和数据,并提供对两者的访问。有一些特定于pNFS的操作(在第12.3节中列出)提供对元数据的访问;所有现有的NFSv4.1传统(非pNFS)安全机制和功能都适用于访问元数据。pNFS中组件的组合

system (see Figure 1) is required to preserve the security properties of NFSv4.1 with respect to an entity that is accessing a storage device from a client, including security countermeasures to defend against threats for which NFSv4.1 provides defenses in environments where these threats are considered significant.

对于从客户端访问存储设备的实体,系统(见图1)需要保留NFSv4.1的安全属性,包括防御威胁的安全对策,NFSv4.1在这些威胁被视为重大的环境中提供防御。

In some cases, the security countermeasures for connections to storage devices may take the form of physical isolation or a recommendation to avoid the use of pNFS in an environment. For example, it may be impractical to provide confidentiality protection for some storage protocols to protect against eavesdropping. In environments where eavesdropping on such protocols is of sufficient concern to require countermeasures, physical isolation of the communication channel (e.g., via direct connection from client(s) to storage device(s)) and/or a decision to forgo use of pNFS (e.g., and fall back to conventional NFSv4.1) may be appropriate courses of action.

在某些情况下,与存储设备连接的安全对策可能采取物理隔离的形式,或者建议避免在环境中使用PNF。例如,为某些存储协议提供保密保护以防止窃听可能是不切实际的。在对此类协议进行窃听的环境中,需要采取应对措施,通信信道的物理隔离(例如,通过从客户端到存储设备的直接连接)和/或放弃使用PNF的决定(例如,退回到传统NFSv4.1)可能是适当的行动方针。

Where communication with storage devices is subject to the same threats as client-to-metadata server communication, the protocols used for that communication need to provide security mechanisms as strong as or no weaker than those available via RPCSEC_GSS for NFSv4.1. Except for the storage protocol used for the LAYOUT4_NFSV4_1_FILES layout (see Section 13), i.e., except for NFSv4.1, it is beyond the scope of this document to specify the security mechanisms for storage access protocols.

当与存储设备的通信受到与客户端到元数据服务器通信相同的威胁时,用于该通信的协议需要提供与通过RPCSEC_GSS for NFSv4.1提供的安全机制一样强或不弱的安全机制。除了用于LAYOUT4_NFSV4_1_文件布局的存储协议(参见第13节),即除NFSV4.1之外,指定存储访问协议的安全机制超出了本文档的范围。

pNFS implementations MUST NOT remove NFSv4.1's access controls. The combination of clients, storage devices, and the metadata server are responsible for ensuring that all client-to-storage-device file data access respects NFSv4.1's ACLs and file open modes. This entails performing both of these checks on every access in the client, the storage device, or both (as applicable; when the storage device is an NFSv4.1 server, the storage device is ultimately responsible for controlling access as described in Section 13.9.2). If a pNFS configuration performs these checks only in the client, the risk of a misbehaving client obtaining unauthorized access is an important consideration in determining when it is appropriate to use such a pNFS configuration. Such layout types SHOULD NOT be used when client-only access checks do not provide sufficient assurance that NFSv4.1 access control is being applied correctly. (This is not a problem for the file layout type described in Section 13 because the storage access protocol for LAYOUT4_NFSV4_1_FILES is NFSv4.1, and thus the security model for storage device access via LAYOUT4_NFSv4_1_FILES is the same as that of the metadata server.) For handling of access control specific to a layout, the reader

pNFS实施不得删除NFSv4.1的访问控制。客户端、存储设备和元数据服务器的组合负责确保所有客户端到存储设备的文件数据访问都遵守NFSv4.1的ACL和文件打开模式。这需要对客户端、存储设备或两者中的每次访问执行这两项检查(如适用;当存储设备是NFSv4.1服务器时,存储设备最终负责控制访问,如第13.9.2节所述)。如果pNFS配置仅在客户机中执行这些检查,则行为不端的客户机获得未经授权访问的风险是确定何时使用此类pNFS配置的一个重要考虑因素。当仅客户端访问检查不能充分保证正确应用NFSv4.1访问控制时,不应使用此类布局类型。(这对于第13节中描述的文件布局类型不是问题,因为LAYOUT4_NFSV4_1_文件的存储访问协议是NFSV4.1,因此通过LAYOUT4_NFSV4_1_文件访问存储设备的安全模型与元数据服务器的安全模型相同。)对于特定于布局的访问控制的处理,读取器

should examine the layout specification, such as the NFSv4.1/ file-based layout (Section 13) of this document, the blocks layout [41], and objects layout [40].

应检查布局规范,如本文件的NFSv4.1/基于文件的布局(第13节)、块布局[41]和对象布局[40]。

13. NFSv4.1 as a Storage Protocol in pNFS: the File Layout Type
13. NFSv4.1作为pNFS中的存储协议:文件布局类型

This section describes the semantics and format of NFSv4.1 file-based layouts for pNFS. NFSv4.1 file-based layouts use the LAYOUT4_NFSV4_1_FILES layout type. The LAYOUT4_NFSV4_1_FILES type defines striping data across multiple NFSv4.1 data servers.

本节描述了PNF基于NFSv4.1文件的布局的语义和格式。基于NFSv4.1文件的布局使用LAYOUT4\u NFSv4\u 1\u文件布局类型。LAYOUT4_NFSV4_1_文件类型定义跨多个NFSV4.1数据服务器的条带化数据。

13.1. Client ID and Session Considerations
13.1. 客户端ID和会话注意事项

Sessions are a REQUIRED feature of NFSv4.1, and this extends to both the metadata server and file-based (NFSv4.1-based) data servers.

会话是NFSv4.1的一个必需功能,它扩展到元数据服务器和基于文件(基于NFSv4.1)的数据服务器。

The role a server plays in pNFS is determined by the result it returns from EXCHANGE_ID. The roles are:

服务器在pNFS中扮演的角色由其从EXCHANGE\u ID返回的结果决定。这些角色包括:

o Metadata server (EXCHGID4_FLAG_USE_PNFS_MDS is set in the result eir_flags).

o 元数据服务器(在结果eir_标志中设置EXCHGID4_标志_使用_PNFS_MDS)。

o Data server (EXCHGID4_FLAG_USE_PNFS_DS).

o 数据服务器(EXCHGID4\u标志\u使用\u PNFS\u DS)。

o Non-metadata server (EXCHGID4_FLAG_USE_NON_PNFS). This is an NFSv4.1 server that does not support operations (e.g., LAYOUTGET) or attributes that pertain to pNFS.

o 非元数据服务器(EXCHGID4\u标志\u使用\u非\u PNFS)。这是一台NFSv4.1服务器,不支持与PNF相关的操作(例如LAYOUTGET)或属性。

The client MAY request zero or more of EXCHGID4_FLAG_USE_NON_PNFS, EXCHGID4_FLAG_USE_PNFS_DS, or EXCHGID4_FLAG_USE_PNFS_MDS, even though some combinations (e.g., EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS) are contradictory. However, the server MUST only return the following acceptable combinations:

客户可能会要求零个或多个EXCHGID4_标志_使用_非_PNFS、EXCHGID4_标志_使用_PNFS_DS或EXCHGID4_标志_使用_PNFS_MDS,即使某些组合(例如EXCHGID4_标志_使用_非|PNFS | EXCHGID4_标志_使用_PNFS_MDS)相互矛盾。但是,服务器必须只返回以下可接受的组合:

        +--------------------------------------------------------+
        | Acceptable Results from EXCHANGE_ID                    |
        +--------------------------------------------------------+
        | EXCHGID4_FLAG_USE_PNFS_MDS                             |
        | EXCHGID4_FLAG_USE_PNFS_MDS | EXCHGID4_FLAG_USE_PNFS_DS |
        | EXCHGID4_FLAG_USE_PNFS_DS                              |
        | EXCHGID4_FLAG_USE_NON_PNFS                             |
        | EXCHGID4_FLAG_USE_PNFS_DS | EXCHGID4_FLAG_USE_NON_PNFS |
        +--------------------------------------------------------+
        
        +--------------------------------------------------------+
        | Acceptable Results from EXCHANGE_ID                    |
        +--------------------------------------------------------+
        | EXCHGID4_FLAG_USE_PNFS_MDS                             |
        | EXCHGID4_FLAG_USE_PNFS_MDS | EXCHGID4_FLAG_USE_PNFS_DS |
        | EXCHGID4_FLAG_USE_PNFS_DS                              |
        | EXCHGID4_FLAG_USE_NON_PNFS                             |
        | EXCHGID4_FLAG_USE_PNFS_DS | EXCHGID4_FLAG_USE_NON_PNFS |
        +--------------------------------------------------------+
        

As the above table implies, a server can have one or two roles. A server can be both a metadata server and a data server, or it can be both a data server and non-metadata server. In addition to returning two roles in the EXCHANGE_ID's results, and thus serving both roles

如上表所示,服务器可以有一个或两个角色。服务器可以同时是元数据服务器和数据服务器,也可以同时是数据服务器和非元数据服务器。除了在EXCHANGE_ID的结果中返回两个角色之外,还可以同时为这两个角色提供服务

via a common client ID, a server can serve two roles by returning a unique client ID and server owner for each role in each of two EXCHANGE_ID results, with each result indicating each role.

通过公共客户端ID,服务器可以为两个角色提供服务,方法是在两个EXCHANGE_ID结果的每个结果中为每个角色返回唯一的客户端ID和服务器所有者,每个结果表示每个角色。

In the case of a server with concurrent pNFS roles that are served by a common client ID, if the EXCHANGE_ID request from the client has zero or a combination of the bits set in eia_flags, the server result should set bits that represent the higher of the acceptable combination of the server roles, with a preference to match the roles requested by the client. Thus, if a client request has (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS | EXCHGID4_FLAG_USE_PNFS_DS) flags set, and the server is both a metadata server and a data server, serving both the roles by a common client ID, the server SHOULD return with (EXCHGID4_FLAG_USE_PNFS_MDS | EXCHGID4_FLAG_USE_PNFS_DS) set.

对于具有由公共客户端ID提供服务的并发pNFS角色的服务器,如果来自客户端的EXCHANGE_ID请求具有零或eia_标志中设置的位组合,则服务器结果应设置表示可接受的服务器角色组合中较高者的位,具有与客户端请求的角色匹配的首选项。因此,如果客户机请求设置了(EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_PNFS | MDS | EXCHGID4_FLAG_USE_PNFS_DS)标志,并且服务器既是元数据服务器又是数据服务器,通过公共客户机ID为这两个角色提供服务,那么服务器应该返回(EXCHGID4_FLAG_USE_PNFS | EXCHGID4_FLAG_USE PNFS | MDS | EXCHGID4_USE PNFS_DS)集。

In the case of a server that has multiple concurrent pNFS roles, each role served by a unique client ID, if the client specifies zero or a combination of roles in the request, the server results SHOULD return only one of the roles from the combination specified by the client request. If the role specified by the server result does not match the intended use by the client, the client should send the EXCHANGE_ID specifying just the interested pNFS role.

对于具有多个并发pNFS角色的服务器,每个角色由唯一的客户端ID提供服务,如果客户端在请求中指定零个角色或角色组合,则服务器结果应仅返回客户端请求指定组合中的一个角色。如果服务器结果指定的角色与客户端的预期用途不匹配,则客户端应发送仅指定感兴趣的pNFS角色的EXCHANGE_ID。

If a pNFS metadata client gets a layout that refers it to an NFSv4.1 data server, it needs a client ID on that data server. If it does not yet have a client ID from the server that had the EXCHGID4_FLAG_USE_PNFS_DS flag set in the EXCHANGE_ID results, then the client needs to send an EXCHANGE_ID to the data server, using the same co_ownerid as it sent to the metadata server, with the EXCHGID4_FLAG_USE_PNFS_DS flag set in the arguments. If the server's EXCHANGE_ID results have EXCHGID4_FLAG_USE_PNFS_DS set, then the client may use the client ID to create sessions that will exchange pNFS data operations. The client ID returned by the data server has no relationship with the client ID returned by a metadata server unless the client IDs are equal, and the server owners and server scopes of the data server and metadata server are equal.

如果pNFS元数据客户端获得一个将其引用到NFSv4.1数据服务器的布局,则它需要该数据服务器上的客户端ID。如果尚未从EXCHANGE\u ID结果中设置了EXCHGID4\u标志\u使用\u PNFS\u DS标志的服务器获得客户端ID,则客户端需要使用与发送到元数据服务器相同的所有者ID向数据服务器发送EXCHANGE\u ID,并在参数中设置EXCHGID4\u标志\u使用\u PNFS\DS标志。如果服务器的EXCHANGE\u ID结果设置了EXCHGID4\u标志\u使用\u PNFS\u DS,则客户端可以使用客户端ID创建将交换PNFS数据操作的会话。数据服务器返回的客户端ID与元数据服务器返回的客户端ID没有关系,除非客户端ID相等,并且数据服务器和元数据服务器的服务器所有者和服务器作用域相等。

In NFSv4.1, the session ID in the SEQUENCE operation implies the client ID, which in turn might be used by the server to map the stateid to the right client/server pair. However, when a data server is presented with a READ or WRITE operation with a stateid, because the stateid is associated with a client ID on a metadata server, and because the session ID in the preceding SEQUENCE operation is tied to the client ID of the data server, the data server has no obvious way to determine the metadata server from the COMPOUND procedure, and

在NFSv4.1中,SEQUENCE操作中的会话ID表示客户机ID,服务器可以使用该ID将stateid映射到正确的客户机/服务器对。但是,当数据服务器显示具有stateid的读或写操作时,因为stateid与元数据服务器上的客户机ID关联,并且因为前面序列操作中的会话ID与数据服务器的客户机ID绑定,数据服务器无法通过复合过程确定元数据服务器,并且

thus has no way to validate the stateid. One RECOMMENDED approach is for pNFS servers to encode metadata server routing and/or identity information in the data server filehandles as returned in the layout.

因此无法验证stateid。一种建议的方法是,pNFS服务器将元数据服务器路由和/或身份信息编码为布局中返回的数据服务器文件句柄。

If metadata server routing and/or identity information is encoded in data server filehandles, when the metadata server identity or location changes, the data server filehandles it gave out will become invalid (stale), and so the metadata server MUST first recall the layouts. Invalidating a data server filehandle does not render the NFS client's data cache invalid. The client's cache should map a data server filehandle to a metadata server filehandle, and a metadata server filehandle to cached data.

如果元数据服务器路由和/或标识信息编码在数据服务器文件句柄中,则当元数据服务器标识或位置更改时,它发出的数据服务器文件句柄将变为无效(过时),因此元数据服务器必须首先调用布局。使数据服务器文件句柄无效不会导致NFS客户端的数据缓存无效。客户端缓存应将数据服务器文件句柄映射到元数据服务器文件句柄,将元数据服务器文件句柄映射到缓存数据。

If a server is both a metadata server and a data server, the server might need to distinguish operations on files that are directed to the metadata server from those that are directed to the data server. It is RECOMMENDED that the values of the filehandles returned by the LAYOUTGET operation be different than the value of the filehandle returned by the OPEN of the same file.

如果服务器既是元数据服务器又是数据服务器,则服务器可能需要区分针对指向元数据服务器的文件和针对数据服务器的文件的操作。建议LAYOUTGET操作返回的filehandles值与打开同一文件返回的filehandle值不同。

Another scenario is for the metadata server and the storage device to be distinct from one client's point of view, and the roles reversed from another client's point of view. For example, in the cluster file system model, a metadata server to one client might be a data server to another client. If NFSv4.1 is being used as the storage protocol, then pNFS servers need to encode the values of filehandles according to their specific roles.

另一种情况是元数据服务器和存储设备与一个客户端的观点不同,角色与另一个客户端的观点相反。例如,在集群文件系统模型中,一个客户端的元数据服务器可能是另一个客户端的数据服务器。如果将NFSv4.1用作存储协议,则pNFS服务器需要根据其特定角色对文件句柄的值进行编码。

13.1.1. Sessions Considerations for Data Servers
13.1.1. 数据服务器的会话注意事项

Section 2.10.11.2 states that a client has to keep its lease renewed in order to prevent a session from being deleted by the server. If the reply to EXCHANGE_ID has just the EXCHGID4_FLAG_USE_PNFS_DS role set, then (as noted in Section 13.6) the client will not be able to determine the data server's lease_time attribute because GETATTR will not be permitted. Instead, the rule is that any time a client receives a layout referring it to a data server that returns just the EXCHGID4_FLAG_USE_PNFS_DS role, the client MAY assume that the lease_time attribute from the metadata server that returned the layout applies to the data server. Thus, the data server MUST be aware of the values of all lease_time attributes of all metadata servers for which it is providing I/O, and it MUST use the maximum of all such lease_time values as the lease interval for all client IDs and sessions established on it.

第2.10.11.2节规定,客户端必须保持其租约续订,以防止服务器删除会话。如果对EXCHANGE\u ID的回复只有EXCHGID4\u标志\u使用\u PNFS\u DS角色集,则(如第13.6节所述),客户端将无法确定数据服务器的租约时间属性,因为不允许GETATTR。相反,规则是,每当客户机接收到将其引用到仅返回EXCHGID4_标志_使用_PNFS_DS角色的数据服务器的布局时,客户机可能会假定返回布局的元数据服务器的lease_time属性适用于数据服务器。因此,数据服务器必须知道其为其提供I/O的所有元数据服务器的所有租约时间属性的值,并且必须使用所有此类租约时间值中的最大值作为在其上建立的所有客户端ID和会话的租约间隔。

For example, if one metadata server has a lease_time attribute of 20 seconds, and a second metadata server has a lease_time attribute of 10 seconds, then if both servers return layouts that refer to an

例如,如果一个元数据服务器的租约时间属性为20秒,而另一个元数据服务器的租约时间属性为10秒,那么如果两个服务器都返回引用

EXCHGID4_FLAG_USE_PNFS_DS-only data server, the data server MUST renew a client's lease if the interval between two SEQUENCE operations on different COMPOUND requests is less than 20 seconds.

EXCHGID4_FLAG_USE_PNFS_DS-only数据服务器,如果针对不同复合请求的两个序列操作之间的间隔小于20秒,则数据服务器必须续订客户端租约。

13.2. File Layout Definitions
13.2. 文件布局定义

The following definitions apply to the LAYOUT4_NFSV4_1_FILES layout type and may be applicable to other layout types.

以下定义适用于LAYOUT4\u NFSV4\u 1\u文件布局类型,也可能适用于其他布局类型。

Unit. A unit is a fixed-size quantity of data written to a data server.

单元单位是写入数据服务器的固定大小的数据量。

Pattern. A pattern is a method of distributing one or more equal sized units across a set of data servers. A pattern is iterated one or more times.

图案模式是在一组数据服务器上分布一个或多个大小相同的单元的方法。模式被迭代一次或多次。

Stripe. A stripe is a set of data distributed across a set of data servers in a pattern before that pattern repeats.

条纹条带是在模式重复之前,以一种模式分布在一组数据服务器上的一组数据。

Stripe Count. A stripe count is the number of units in a pattern.

条纹计数。条纹计数是图案中的单位数。

Stripe Width. A stripe width is the size of a stripe in bytes. The stripe width = the stripe count * the size of the stripe unit.

条纹宽度。条带宽度是条带的大小(以字节为单位)。条纹宽度=条纹计数*条纹单元的大小。

Hereafter, this document will refer to a unit that is a written in a pattern as a "stripe unit".

此后,本文档将以模式写入的单元称为“条带单元”。

A pattern may have more stripe units than data servers. If so, some data servers will have more than one stripe unit per stripe. A data server that has multiple stripe units per stripe MAY store each unit in a different data file (and depending on the implementation, will possibly assign a unique data filehandle to each data file).

模式的条带单元可能比数据服务器多。如果是这样,某些数据服务器的每个条带将有多个条带单元。每个条带具有多个条带单元的数据服务器可能会将每个单元存储在不同的数据文件中(并且可能会根据实现为每个数据文件分配唯一的数据文件句柄)。

13.3. File Layout Data Types
13.3. 文件布局数据类型

The high level NFSv4.1 layout types are nfsv4_1_file_layouthint4, nfsv4_1_file_layout_ds_addr4, and nfsv4_1_file_layout4.

高级NFSv4.1布局类型为NFSv4_1_文件_布局4、NFSv4_1_文件_布局_ds_添加4和NFSv4_1_文件_布局4。

The SETATTR operation supports a layout hint attribute (Section 5.12.4). When the client sets a layout hint (data type layouthint4) with a layout type of LAYOUT4_NFSV4_1_FILES (the loh_type field), the loh_body field contains a value of data type nfsv4_1_file_layouthint4.

SETATTR操作支持布局提示属性(第5.12.4节)。当客户端使用布局类型为LAYOUT4\u NFSV4\u 1\u文件(loh\u类型字段)设置布局提示(数据类型LayoutInt4)时,loh\u正文字段包含数据类型为NFSV4\u 1\u文件\u LayoutInt4的值。

   const NFL4_UFLG_MASK            = 0x0000003F;
   const NFL4_UFLG_DENSE           = 0x00000001;
   const NFL4_UFLG_COMMIT_THRU_MDS = 0x00000002;
   const NFL4_UFLG_STRIPE_UNIT_SIZE_MASK
                                   = 0xFFFFFFC0;
        
   const NFL4_UFLG_MASK            = 0x0000003F;
   const NFL4_UFLG_DENSE           = 0x00000001;
   const NFL4_UFLG_COMMIT_THRU_MDS = 0x00000002;
   const NFL4_UFLG_STRIPE_UNIT_SIZE_MASK
                                   = 0xFFFFFFC0;
        

typedef uint32_t nfl_util4;

类型定义uint32\u t nfl\u util4;

enum filelayout_hint_care4 { NFLH4_CARE_DENSE = NFL4_UFLG_DENSE,

enum filelayout_hint_care4{NFLH4_CARE_DENSE=NFL4_UFLG_DENSE,

NFLH4_CARE_COMMIT_THRU_MDS = NFL4_UFLG_COMMIT_THRU_MDS,

NFLH4通过MDS进行护理、提交=NFL4通过MDS进行提交,

NFLH4_CARE_STRIPE_UNIT_SIZE = 0x00000040,

NFLH4\u保护\u条带\u单元\u大小=0x00000040,

NFLH4_CARE_STRIPE_COUNT = 0x00000080 };

NFLH4_CARE_STRIPE_COUNT=0x00000080};

   /* Encoded in the loh_body field of data type layouthint4: */
        
   /* Encoded in the loh_body field of data type layouthint4: */
        
   struct nfsv4_1_file_layouthint4 {
           uint32_t        nflh_care;
           nfl_util4       nflh_util;
           count4          nflh_stripe_count;
   };
        
   struct nfsv4_1_file_layouthint4 {
           uint32_t        nflh_care;
           nfl_util4       nflh_util;
           count4          nflh_stripe_count;
   };
        

The generic layout hint structure is described in Section 3.3.19. The client uses the layout hint in the layout_hint (Section 5.12.4) attribute to indicate the preferred type of layout to be used for a newly created file. The LAYOUT4_NFSV4_1_FILES layout-type-specific content for the layout hint is composed of three fields. The first field, nflh_care, is a set of flags indicating which values of the hint the client cares about. If the NFLH4_CARE_DENSE flag is set, then the client indicates in the second field, nflh_util, a preference for how the data file is packed (Section 13.4.4), which is controlled by the value of the expression nflh_util & NFL4_UFLG_DENSE ("&" represents the bitwise AND operator). If the NFLH4_CARE_COMMIT_THRU_MDS flag is set, then the client indicates a preference for whether the client should send COMMIT operations to the metadata server or data server (Section 13.7), which is controlled by the value of nflh_util & NFL4_UFLG_COMMIT_THRU_MDS. If the NFLH4_CARE_STRIPE_UNIT_SIZE flag is set, the client indicates its preferred stripe unit size, which is indicated in nflh_util & NFL4_UFLG_STRIPE_UNIT_SIZE_MASK (thus, the stripe unit size MUST be a multiple of 64 bytes). The minimum stripe unit size is 64 bytes. If

第3.3.19节描述了通用布局提示结构。客户机使用layout_hint(第5.12.4节)属性中的layout提示来指示用于新创建文件的首选布局类型。布局提示的LAYOUT4_NFSV4_1_文件布局类型特定内容由三个字段组成。第一个字段nflh_care是一组标志,指示客户端关心的提示值。如果设置了NFLH4_CARE_DENSE标志,则客户端在第二个字段nflh_util中指示数据文件打包方式的首选项(第13.4.4节),该首选项由表达式nflh_util&NFL4_UFLG_DENSE的值控制(&)表示按位AND运算符)。如果设置了NFLH4_-CARE_-COMMIT_-THRU-MDS标志,则客户机指示客户机是否应向元数据服务器或数据服务器发送提交操作的首选项(第13.7节),这由nflh_-util和NFL4_-UFLG_-COMMIT_-THRU-MDS的值控制。如果设置了NFLH4_CARE_STRIPE_UNIT_SIZE标志,则客户端将指示其首选的条带单元大小,这在nflh_util和NFL4_UFLG_STRIPE_UNIT_SIZE_MASK中指示(因此,条带单元大小必须是64字节的倍数)。最小条带单元大小为64字节。如果

the NFLH4_CARE_STRIPE_COUNT flag is set, the client indicates in the third field, nflh_stripe_count, the stripe count. The stripe count multiplied by the stripe unit size is the stripe width.

设置NFLH4_CARE_STRIPE_COUNT标志,客户端在第三个字段中指示nflh_STRIPE_COUNT,STRIPE COUNT。条纹计数乘以条纹单位大小即为条纹宽度。

When LAYOUTGET returns a LAYOUT4_NFSV4_1_FILES layout (indicated in the loc_type field of the lo_content field), the loc_body field of the lo_content field contains a value of data type nfsv4_1_file_layout4. Among other content, nfsv4_1_file_layout4 has a storage device ID (field nfl_deviceid) of data type deviceid4. The GETDEVICEINFO operation maps a device ID to a storage device address (type device_addr4). When GETDEVICEINFO returns a device address with a layout type of LAYOUT4_NFSV4_1_FILES (the da_layout_type field), the da_addr_body field contains a value of data type nfsv4_1_file_layout_ds_addr4.

当LAYOUTGET返回LAYOUT4_NFSV4_1_文件布局(在lo_内容字段的loc_类型字段中指示)时,lo_内容字段的loc_正文字段包含数据类型NFSV4_1_文件_LAYOUT4的值。在其他内容中,nfsv4_1_文件_布局4具有数据类型为deviceid4的存储设备ID(字段nfl_deviceid)。GETDEVICEINFO操作将设备ID映射到存储设备地址(键入device_addr4)。当GETDEVICEINFO返回布局类型为LAYOUT4\u NFSV4\u 1\u文件的设备地址(da\u layout\u类型字段)时,da\u addr\u body字段包含数据类型为NFSV4\u 1\u file\u layout\u ds\u addr4的值。

   typedef netaddr4 multipath_list4<>;
        
   typedef netaddr4 multipath_list4<>;
        
   /*
    * Encoded in the da_addr_body field of
    * data type device_addr4:
    */
   struct nfsv4_1_file_layout_ds_addr4 {
           uint32_t        nflda_stripe_indices<>;
           multipath_list4 nflda_multipath_ds_list<>;
   };
        
   /*
    * Encoded in the da_addr_body field of
    * data type device_addr4:
    */
   struct nfsv4_1_file_layout_ds_addr4 {
           uint32_t        nflda_stripe_indices<>;
           multipath_list4 nflda_multipath_ds_list<>;
   };
        

The nfsv4_1_file_layout_ds_addr4 data type represents the device address. It is composed of two fields:

nfsv4_1_file_layout_ds_addr4数据类型表示设备地址。它由两个字段组成:

1. nflda_multipath_ds_list: An array of lists of data servers, where each list can be one or more elements, and each element represents a data server address that may serve equally as the target of I/O operations (see Section 13.5). The length of this array might be different than the stripe count.

1. nflda_multipath_ds_list:数据服务器列表的数组,其中每个列表可以是一个或多个元素,每个元素表示一个数据服务器地址,该地址可以作为I/O操作的目标(参见第13.5节)。此数组的长度可能不同于条带计数。

2. nflda_stripe_indices: An array of indices used to index into nflda_multipath_ds_list. The value of each element of nflda_stripe_indices MUST be less than the number of elements in nflda_multipath_ds_list. Each element of nflda_multipath_ds_list SHOULD be referred to by one or more elements of nflda_stripe_indices. The number of elements in nflda_stripe_indices is always equal to the stripe count.

2. nflda_条带索引:用于索引到nflda_多路径ds_列表的索引数组。nflda_stripe_索引的每个元素的值必须小于nflda_multipath_ds_列表中的元素数。nflda\u多路径\u ds\u列表的每个元素都应该由nflda\u条带\u索引的一个或多个元素引用。nflda_条带索引中的元素数始终等于条带计数。

   /*
    * Encoded in the loc_body field of
    * data type layout_content4:
    */
   struct nfsv4_1_file_layout4 {
            deviceid4      nfl_deviceid;
            nfl_util4      nfl_util;
            uint32_t       nfl_first_stripe_index;
            offset4        nfl_pattern_offset;
            nfs_fh4        nfl_fh_list<>;
   };
        
   /*
    * Encoded in the loc_body field of
    * data type layout_content4:
    */
   struct nfsv4_1_file_layout4 {
            deviceid4      nfl_deviceid;
            nfl_util4      nfl_util;
            uint32_t       nfl_first_stripe_index;
            offset4        nfl_pattern_offset;
            nfs_fh4        nfl_fh_list<>;
   };
        

The nfsv4_1_file_layout4 data type represents the layout. It is composed of the following fields:

nfsv4_1_file_layout4数据类型表示布局。它由以下字段组成:

1. nfl_deviceid: The device ID that maps to a value of type nfsv4_1_file_layout_ds_addr4.

1. nfl\U设备ID:映射到nfsv4\u 1\u file\u layout\u ds\u addr4类型值的设备ID。

2. nfl_util: Like the nflh_util field of data type nfsv4_1_file_layouthint4, a compact representation of how the data on a file on each data server is packed, whether the client should send COMMIT operations to the metadata server or data server, and the stripe unit size. If a server returns two or more overlapping layouts, each stripe unit size in each overlapping layout MUST be the same.

2. nfl_util:与数据类型为nfsv4_1_file_layouthint4的nflh_util字段类似,它是每个数据服务器上文件上的数据如何打包、客户端是否应向元数据服务器或数据服务器发送提交操作以及条带单元大小的紧凑表示。如果服务器返回两个或多个重叠布局,则每个重叠布局中的每个条带单元大小必须相同。

3. nfl_first_stripe_index: The index into the first element of the nflda_stripe_indices array to use.

3. nfl_first_stripe_索引:要使用的nflda_stripe_索引数组的第一个元素的索引。

4. nfl_pattern_offset: This field is the logical offset into the file where the striping pattern starts. It is required for converting the client's logical I/O offset (e.g., the current offset in a POSIX file descriptor before the read() or write() system call is sent) into the stripe unit number (see Section 13.4.1).

4. nfl_pattern_offset:该字段是条带模式开始的文件的逻辑偏移量。将客户机的逻辑I/O偏移量(例如,在发送read()或write()系统调用之前POSIX文件描述符中的当前偏移量)转换为条带单元号时需要该偏移量(参见第13.4.1节)。

If dense packing is used, then nfl_pattern_offset is also needed to convert the client's logical I/O offset to an offset on the file on the data server corresponding to the stripe unit number (see Section 13.4.4).

如果使用密集封装,则还需要nfl_pattern_offset将客户端的逻辑I/O偏移量转换为数据服务器上与条带单元号对应的文件偏移量(请参阅第13.4.4节)。

Note that nfl_pattern_offset is not always the same as lo_offset. For example, via the LAYOUTGET operation, a client might request a layout starting at offset 1000 of a file that has its striping pattern start at offset zero.

请注意,nfl_模式_偏移并不总是与lo_偏移相同。例如,通过LAYOUTGET操作,客户机可能会请求从偏移量1000开始的布局,该文件的条带模式从偏移量0开始。

5. nfl_fh_list: An array of data server filehandles for each list of data servers in each element of the nflda_multipath_ds_list array. The number of elements in nfl_fh_list depends on whether sparse or dense packing is being used.

5. nfl_fh_列表:数据服务器文件句柄数组,用于nflda_多路径_ds_列表数组的每个元素中的每个数据服务器列表。nfl_fh_列表中元素的数量取决于使用的是稀疏填料还是密集填料。

* If sparse packing is being used, the number of elements in nfl_fh_list MUST be one of three values:

* 如果使用稀疏包装,nfl\U fh\U列表中的元素数量必须为以下三个值之一:

+ Zero. This means that filehandles used for each data server are the same as the filehandle returned by the OPEN operation from the metadata server.

+ 零这意味着每个数据服务器使用的文件句柄与元数据服务器的打开操作返回的文件句柄相同。

+ One. This means that every data server uses the same filehandle: what is specified in nfl_fh_list[0].

+ 一这意味着每个数据服务器使用相同的文件句柄:nfl\U fh\U列表[0]中指定的内容。

+ The same number of elements in nflda_multipath_ds_list. Thus, in this case, when sending an I/O operation to any data server in nflda_multipath_ds_list[X], the filehandle in nfl_fh_list[X] MUST be used.

+ nflda\u多路径\u ds\u列表中的元素数相同。因此,在这种情况下,当向nflda_multipath_ds_list[X]中的任何数据服务器发送I/O操作时,必须使用nfl_fh_list[X]中的文件句柄。

See the discussion on sparse packing in Section 13.4.4.

见第13.4.4节中关于稀疏填料的讨论。

* If dense packing is being used, the number of elements in nfl_fh_list MUST be the same as the number of elements in nflda_stripe_indices. Thus, when sending an I/O operation to any data server in nflda_multipath_ds_list[nflda_stripe_indices[Y]], the filehandle in nfl_fh_list[Y] MUST be used. In addition, any time there exists i and j, (i != j), such that the intersection of nflda_multipath_ds_list[nflda_stripe_indices[i]] and nflda_multipath_ds_list[nflda_stripe_indices[j]] is not empty, then nfl_fh_list[i] MUST NOT equal nfl_fh_list[j]. In other words, when dense packing is being used, if a data server appears in two or more units of a striping pattern, each reference to the data server MUST use a different filehandle.

* 如果使用密集包装,nfl\u fh\u列表中的元素数量必须与nflda\u条带\u索引中的元素数量相同。因此,当向nflda_multipath_ds_list[nflda_stripe_index[Y]]中的任何数据服务器发送I/O操作时,必须使用nfl_fh_list[Y]中的文件句柄。此外,任何时候存在i和j,(i!=j),使得nflda_多路径_ds_列表[nflda_条带_索引[i]]和nflda_多路径_ds_列表[nflda_条带_索引[j]]的交集不为空,那么nfl_fh_列表[i]必须不等于nfl_fh_列表[j]。换句话说,当使用密集打包时,如果数据服务器以条带模式的两个或多个单元出现,则对数据服务器的每个引用必须使用不同的文件句柄。

Indeed, if there are multiple striping patterns, as indicated by the presence of multiple objects of data type layout4 (either returned in one or multiple LAYOUTGET operations), and a data server is the target of a unit of one pattern and another unit of another pattern, then each reference to each data server MUST use a different filehandle.

实际上,如果存在多个条带化模式,如存在多个数据类型为layout4的对象(在一个或多个LAYOUTGET操作中返回)所示,并且数据服务器是一个模式单元和另一个模式单元的目标,那么对每个数据服务器的每个引用都必须使用不同的文件句柄。

See the discussion on dense packing in Section 13.4.4.

见第13.4.4节中关于密实填料的讨论。

The details on the interpretation of the layout are in Section 13.4.

有关布局解释的详细信息,请参见第13.4节。

13.4. Interpreting the File Layout
13.4. 解释文件布局
13.4.1. Determining the Stripe Unit Number
13.4.1. 确定条带单元号

To find the stripe unit number that corresponds to the client's logical file offset, the pattern offset will also be used. The i'th stripe unit (SUi) is:

要查找与客户机的逻辑文件偏移量对应的条带单元号,还将使用模式偏移量。第i个条纹单元(SUi)为:

       relative_offset = file_offset - nfl_pattern_offset;
       SUi = floor(relative_offset / stripe_unit_size);
        
       relative_offset = file_offset - nfl_pattern_offset;
       SUi = floor(relative_offset / stripe_unit_size);
        
13.4.2. Interpreting the File Layout Using Sparse Packing
13.4.2. 使用稀疏打包解释文件布局

When sparse packing is used, the algorithm for determining the filehandle and set of data-server network addresses to write stripe unit i (SUi) to is:

当使用稀疏打包时,用于确定要将条带单元i(SUi)写入的文件句柄和数据服务器网络地址集的算法为:

stripe_count = number of elements in nflda_stripe_indices;

条带计数=nflda条带索引中的元素数;

      j = (SUi + nfl_first_stripe_index) % stripe_count;
        
      j = (SUi + nfl_first_stripe_index) % stripe_count;
        

idx = nflda_stripe_indices[j];

idx=nflda_条带_指数[j];

      fh_count = number of elements in nfl_fh_list;
      ds_count = number of elements in nflda_multipath_ds_list;
        
      fh_count = number of elements in nfl_fh_list;
      ds_count = number of elements in nflda_multipath_ds_list;
        
      switch (fh_count) {
        case ds_count:
          fh = nfl_fh_list[idx];
          break;
        
      switch (fh_count) {
        case ds_count:
          fh = nfl_fh_list[idx];
          break;
        
        case 1:
          fh = nfl_fh_list[0];
          break;
        
        case 1:
          fh = nfl_fh_list[0];
          break;
        
        case 0:
          fh = filehandle returned by OPEN;
          break;
        
        case 0:
          fh = filehandle returned by OPEN;
          break;
        
        default:
          throw a fatal exception;
          break;
      }
        
        default:
          throw a fatal exception;
          break;
      }
        

address_list = nflda_multipath_ds_list[idx];

地址列表=nflda\U多路径\U ds\U列表[idx];

The client would then select a data server from address_list, and send a READ or WRITE operation using the filehandle specified in fh.

然后,客户端将从地址列表中选择数据服务器,并使用fh中指定的文件句柄发送读或写操作。

Consider the following example:

考虑下面的例子:

Suppose we have a device address consisting of seven data servers, arranged in three equivalence (Section 13.5) classes:

假设我们有一个由七个数据服务器组成的设备地址,按三个等价类(第13.5节)排列:

      { A, B, C, D }, { E }, { F, G }
        
      { A, B, C, D }, { E }, { F, G }
        

where A through G are network addresses.

其中A到G是网络地址。

Then

然后

      nflda_multipath_ds_list<> = { A, B, C, D }, { E }, { F, G }
        
      nflda_multipath_ds_list<> = { A, B, C, D }, { E }, { F, G }
        

i.e.,

即。,

      nflda_multipath_ds_list[0] = { A, B, C, D }
        
      nflda_multipath_ds_list[0] = { A, B, C, D }
        
      nflda_multipath_ds_list[1] = { E }
        
      nflda_multipath_ds_list[1] = { E }
        
      nflda_multipath_ds_list[2] = { F, G }
        
      nflda_multipath_ds_list[2] = { F, G }
        

Suppose the striping index array is:

假设条带索引数组为:

      nflda_stripe_indices<> = { 2, 0, 1, 0 }
        
      nflda_stripe_indices<> = { 2, 0, 1, 0 }
        

Now suppose the client gets a layout that has a device ID that maps to the above device address. The initial index contains

现在假设客户机获得一个布局,该布局具有映射到上述设备地址的设备ID。初始索引包含

nfl_first_stripe_index = 2,

nfl第一条条纹指数=2,

and the filehandle list is

文件句柄列表是

      nfl_fh_list = { 0x36, 0x87, 0x67 }.
        
      nfl_fh_list = { 0x36, 0x87, 0x67 }.
        

If the client wants to write to SU0, the set of valid { network address, filehandle } combinations for SUi are determined by:

如果客户端希望写入SU0,SUi的有效{network address,filehandle}组合集由以下内容确定:

      nfl_first_stripe_index = 2
        
      nfl_first_stripe_index = 2
        

So

所以

      idx = nflda_stripe_indices[(0 + 2) % 4]
        
      idx = nflda_stripe_indices[(0 + 2) % 4]
        

= nflda_stripe_indices[2]

=nflda_条带_索引[2]

= 1

= 1

So

所以

      nflda_multipath_ds_list[1] = { E }
        
      nflda_multipath_ds_list[1] = { E }
        

and

      nfl_fh_list[1] = { 0x87 }
        
      nfl_fh_list[1] = { 0x87 }
        

The client can thus write SU0 to { 0x87, { E } }.

因此,客户端可以将SU0写入{0x87,{E}。

The destinations of the first 13 storage units are:

前13个存储单元的目标是:

                    +-----+------------+--------------+
                    | SUi | filehandle | data servers |
                    +-----+------------+--------------+
                    | 0   | 87         | E            |
                    | 1   | 36         | A,B,C,D      |
                    | 2   | 67         | F,G          |
                    | 3   | 36         | A,B,C,D      |
                    | 4   | 87         | E            |
                    | 5   | 36         | A,B,C,D      |
                    | 6   | 67         | F,G          |
                    | 7   | 36         | A,B,C,D      |
                    | 8   | 87         | E            |
                    | 9   | 36         | A,B,C,D      |
                    | 10  | 67         | F,G          |
                    | 11  | 36         | A,B,C,D      |
                    | 12  | 87         | E            |
                    +-----+------------+--------------+
        
                    +-----+------------+--------------+
                    | SUi | filehandle | data servers |
                    +-----+------------+--------------+
                    | 0   | 87         | E            |
                    | 1   | 36         | A,B,C,D      |
                    | 2   | 67         | F,G          |
                    | 3   | 36         | A,B,C,D      |
                    | 4   | 87         | E            |
                    | 5   | 36         | A,B,C,D      |
                    | 6   | 67         | F,G          |
                    | 7   | 36         | A,B,C,D      |
                    | 8   | 87         | E            |
                    | 9   | 36         | A,B,C,D      |
                    | 10  | 67         | F,G          |
                    | 11  | 36         | A,B,C,D      |
                    | 12  | 87         | E            |
                    +-----+------------+--------------+
        
13.4.3. Interpreting the File Layout Using Dense Packing
13.4.3. 使用密集打包解释文件布局

When dense packing is used, the algorithm for determining the filehandle and set of data server network addresses to write stripe unit i (SUi) to is:

当使用密集打包时,用于确定要将条带单元i(SUi)写入的文件句柄和数据服务器网络地址集的算法为:

stripe_count = number of elements in nflda_stripe_indices;

条带计数=nflda条带索引中的元素数;

      j = (SUi + nfl_first_stripe_index) % stripe_count;
        
      j = (SUi + nfl_first_stripe_index) % stripe_count;
        

idx = nflda_stripe_indices[j];

idx=nflda_条带_指数[j];

      fh_count = number of elements in nfl_fh_list;
      ds_count = number of elements in nflda_multipath_ds_list;
        
      fh_count = number of elements in nfl_fh_list;
      ds_count = number of elements in nflda_multipath_ds_list;
        
      switch (fh_count) {
        case stripe_count:
          fh = nfl_fh_list[j];
          break;
        
      switch (fh_count) {
        case stripe_count:
          fh = nfl_fh_list[j];
          break;
        
        default:
          throw a fatal exception;
          break;
      }
        
        default:
          throw a fatal exception;
          break;
      }
        

address_list = nflda_multipath_ds_list[idx];

地址列表=nflda\U多路径\U ds\U列表[idx];

The client would then select a data server from address_list, and send a READ or WRITE operation using the filehandle specified in fh.

然后,客户端将从地址列表中选择数据服务器,并使用fh中指定的文件句柄发送读或写操作。

Consider the following example (which is the same as the sparse packing example, except for the filehandle list):

考虑下面的示例(与稀疏包装示例相同,除了文件句柄列表):

Suppose we have a device address consisting of seven data servers, arranged in three equivalence (Section 13.5) classes:

假设我们有一个由七个数据服务器组成的设备地址,按三个等价类(第13.5节)排列:

      { A, B, C, D }, { E }, { F, G }
        
      { A, B, C, D }, { E }, { F, G }
        

where A through G are network addresses.

其中A到G是网络地址。

Then

然后

      nflda_multipath_ds_list<> = { A, B, C, D }, { E }, { F, G }
        
      nflda_multipath_ds_list<> = { A, B, C, D }, { E }, { F, G }
        

i.e.,

即。,

      nflda_multipath_ds_list[0] = { A, B, C, D }
        
      nflda_multipath_ds_list[0] = { A, B, C, D }
        
      nflda_multipath_ds_list[1] = { E }
        
      nflda_multipath_ds_list[1] = { E }
        
      nflda_multipath_ds_list[2] = { F, G }
        
      nflda_multipath_ds_list[2] = { F, G }
        

Suppose the striping index array is:

假设条带索引数组为:

      nflda_stripe_indices<> = { 2, 0, 1, 0 }
        
      nflda_stripe_indices<> = { 2, 0, 1, 0 }
        

Now suppose the client gets a layout that has a device ID that maps to the above device address. The initial index contains

现在假设客户机获得一个布局,该布局具有映射到上述设备地址的设备ID。初始索引包含

nfl_first_stripe_index = 2,

nfl第一条条纹指数=2,

and

      nfl_fh_list = { 0x67, 0x37, 0x87, 0x36 }.
        
      nfl_fh_list = { 0x67, 0x37, 0x87, 0x36 }.
        

The interesting examples for dense packing are SU1 and SU3 because each stripe unit refers to the same data server list, yet each stripe unit MUST use a different filehandle. If the client wants to write to SU1, the set of valid { network address, filehandle } combinations for SUi are determined by:

密集打包的有趣示例是SU1和SU3,因为每个条带单元引用相同的数据服务器列表,但每个条带单元必须使用不同的文件句柄。如果客户端希望写入SU1,SUi的有效{network address,filehandle}组合集由以下内容确定:

      nfl_first_stripe_index = 2
        
      nfl_first_stripe_index = 2
        

So

所以

      j = (1 + 2) % 4 = 3
        
      j = (1 + 2) % 4 = 3
        

idx = nflda_stripe_indices[j]

idx=nflda\u条带\u指数[j]

= nflda_stripe_indices[3]

=nflda_条带_索引[3]

= 0

= 0

So

所以

      nflda_multipath_ds_list[0] = { A, B, C, D }
        
      nflda_multipath_ds_list[0] = { A, B, C, D }
        

and

      nfl_fh_list[3] = { 0x36 }
        
      nfl_fh_list[3] = { 0x36 }
        

The client can thus write SU1 to { 0x36, { A, B, C, D } }.

因此,客户机可以将SU1写入{0x36,{A,B,C,D}。

   For SU3, j = (3 + 2) % 4 = 1, and nflda_stripe_indices[1] = 0.  Then
   nflda_multipath_ds_list[0] = { A, B, C, D }, and nfl_fh_list[1] =
   0x37.  The client can thus write SU3 to { 0x37, { A, B, C, D } }.
        
   For SU3, j = (3 + 2) % 4 = 1, and nflda_stripe_indices[1] = 0.  Then
   nflda_multipath_ds_list[0] = { A, B, C, D }, and nfl_fh_list[1] =
   0x37.  The client can thus write SU3 to { 0x37, { A, B, C, D } }.
        

The destinations of the first 13 storage units are:

前13个存储单元的目标是:

                    +-----+------------+--------------+
                    | SUi | filehandle | data servers |
                    +-----+------------+--------------+
                    | 0   | 87         | E            |
                    | 1   | 36         | A,B,C,D      |
                    | 2   | 67         | F,G          |
                    | 3   | 37         | A,B,C,D      |
                    | 4   | 87         | E            |
                    | 5   | 36         | A,B,C,D      |
                    | 6   | 67         | F,G          |
                    | 7   | 37         | A,B,C,D      |
                    | 8   | 87         | E            |
                    | 9   | 36         | A,B,C,D      |
                    | 10  | 67         | F,G          |
                    | 11  | 37         | A,B,C,D      |
                    | 12  | 87         | E            |
                    +-----+------------+--------------+
        
                    +-----+------------+--------------+
                    | SUi | filehandle | data servers |
                    +-----+------------+--------------+
                    | 0   | 87         | E            |
                    | 1   | 36         | A,B,C,D      |
                    | 2   | 67         | F,G          |
                    | 3   | 37         | A,B,C,D      |
                    | 4   | 87         | E            |
                    | 5   | 36         | A,B,C,D      |
                    | 6   | 67         | F,G          |
                    | 7   | 37         | A,B,C,D      |
                    | 8   | 87         | E            |
                    | 9   | 36         | A,B,C,D      |
                    | 10  | 67         | F,G          |
                    | 11  | 37         | A,B,C,D      |
                    | 12  | 87         | E            |
                    +-----+------------+--------------+
        
13.4.4. Sparse and Dense Stripe Unit Packing
13.4.4. 稀疏密条单元堆积

The flag NFL4_UFLG_DENSE of the nfl_util4 data type (field nflh_util of the data type nfsv4_1_file_layouthint4 and field nfl_util of data type nfsv4_1_file_layout_ds_addr4) specifies how the data is packed within the data file on a data server. It allows for two different data packings: sparse and dense. The packing type determines the calculation that will be made to map the client-visible file offset to the offset within the data file located on the data server.

nfl_util4数据类型的标志NFL4_UFLG_density(数据类型nfsv4_1_file_layouthint4的字段nflh_util和数据类型nfsv4_1_file_layout_ds_addr4的字段nfl_util)指定如何在数据服务器上的数据文件中打包数据。它允许两种不同的数据打包:稀疏和密集。打包类型确定将要进行的计算,以将客户端可见文件偏移量映射到位于数据服务器上的数据文件内的偏移量。

If nfl_util & NFL4_UFLG_DENSE is zero, this means that sparse packing is being used. Hence, the logical offsets of the file as viewed by a client sending READs and WRITEs directly to the metadata server are the same offsets each data server uses when storing a stripe unit. The effect then, for striping patterns consisting of at least two stripe units, is for each data server file to be sparse or "holey". So for example, suppose there is a pattern with three stripe units, the stripe unit size is 4096 bytes, and there are three data servers in the pattern. Then, the file in data server 1 will have stripe units 0, 3, 6, 9, ... filled; data server 2's file will have stripe units 1, 4, 7, 10, ... filled; and data server 3's file will have stripe units 2, 5, 8, 11, ... filled. The unfilled stripe units of each file will be holes; hence, the files in each data server are sparse.

如果nfl_util&NFL4_UFLG_density为零,则表示正在使用稀疏填充。因此,直接向元数据服务器发送读写操作的客户端查看的文件的逻辑偏移量与每个数据服务器在存储条带单元时使用的偏移量相同。因此,对于至少由两个条带单元组成的条带模式,每个数据服务器文件都是稀疏的或“多孔的”。例如,假设有一个模式有三个条带单元,条带单元大小为4096字节,模式中有三个数据服务器。然后,数据服务器1中的文件将具有条带单元0、3、6、9、。。。填满;数据服务器2的文件将具有条带单元1、4、7、10等。。。填满;数据服务器3的文件将有条带单元2,5,8,11。。。填满。每个文件的未填充条纹单元将为孔;因此,每个数据服务器中的文件都是稀疏的。

If sparse packing is being used and a client attempts I/O to one of the holes, then an error MUST be returned by the data server. Using the above example, if data server 3 received a READ or WRITE

如果正在使用稀疏打包,并且客户端尝试对其中一个孔进行I/O,则数据服务器必须返回错误。使用上述示例,如果数据服务器3接收到读取或写入

operation for block 4, the data server would return NFS4ERR_PNFS_IO_HOLE. Thus, data servers need to understand the striping pattern in order to support sparse packing.

操作块4时,数据服务器将返回NFS4ERR_PNFS_IO_洞。因此,数据服务器需要了解条带化模式以支持稀疏打包。

If nfl_util & NFL4_UFLG_DENSE is one, this means that dense packing is being used, and the data server files have no holes. Dense packing might be selected because the data server does not (efficiently) support holey files or because the data server cannot recognize read-ahead unless there are no holes. If dense packing is indicated in the layout, the data files will be packed. Using the same striping pattern and stripe unit size that were used for the sparse packing example, the corresponding dense packing example would have all stripe units of all data files filled as follows:

如果nfl_util&NFL4_UFLG_DENSE为1,则表示正在使用密集打包,并且数据服务器文件没有漏洞。选择密集打包可能是因为数据服务器不(有效地)支持有孔文件,或者因为除非没有孔,否则数据服务器无法识别预读。如果布局中指示密集包装,则数据文件将被包装。使用与稀疏打包示例相同的条带模式和条带单元大小,相应的密集打包示例将按如下方式填充所有数据文件的所有条带单元:

o Logical stripe units 0, 3, 6, ... of the file would live on stripe units 0, 1, 2, ... of the file of data server 1.

o 逻辑条带单元0、3、6、。。。该文件的所有部分将位于条带单元0、1、2、。。。数据服务器1的文件的。

o Logical stripe units 1, 4, 7, ... of the file would live on stripe units 0, 1, 2, ... of the file of data server 2.

o 逻辑条带单元1、4、7、。。。该文件的所有部分将位于条带单元0、1、2、。。。数据服务器2的文件。

o Logical stripe units 2, 5, 8, ... of the file would live on stripe units 0, 1, 2, ... of the file of data server 3.

o 逻辑条带单元2、5、8、。。。该文件的所有部分将位于条带单元0、1、2、。。。数据服务器3的文件。

Because dense packing does not leave holes on the data servers, the pNFS client is allowed to write to any offset of any data file of any data server in the stripe. Thus, the data servers need not know the file's striping pattern.

由于密集打包不会在数据服务器上留下漏洞,因此允许pNFS客户端写入条带中任何数据服务器的任何数据文件的任何偏移量。因此,数据服务器不需要知道文件的条带模式。

The calculation to determine the byte offset within the data file for dense data server layouts is:

用于确定密集数据服务器布局的数据文件中的字节偏移量的计算如下:

stripe_width = stripe_unit_size * N; where N = number of elements in nflda_stripe_indices.

条纹宽度=条纹单位大小*N;其中N=nflda_条带_索引中的元素数。

      relative_offset = file_offset - nfl_pattern_offset;
        
      relative_offset = file_offset - nfl_pattern_offset;
        
      data_file_offset = floor(relative_offset / stripe_width)
         * stripe_unit_size
         + relative_offset % stripe_unit_size
        
      data_file_offset = floor(relative_offset / stripe_width)
         * stripe_unit_size
         + relative_offset % stripe_unit_size
        

If dense packing is being used, and a data server appears more than once in a striping pattern, then to distinguish one stripe unit from another, the data server MUST use a different filehandle. Let's suppose there are two data servers. Logical stripe units 0, 3, 6 are served by data server 1; logical stripe units 1, 4, 7 are served by data server 2; and logical stripe units 2, 5, 8 are also served by data server 2. Unless data server 2 has two filehandles (each referring to a different data file), then, for example, a write to

如果正在使用密集打包,并且数据服务器在条带模式中多次出现,那么为了区分一个条带单元和另一个条带单元,数据服务器必须使用不同的文件句柄。假设有两个数据服务器。逻辑条带单元0、3、6由数据服务器1提供服务;逻辑条带单元1、4、7由数据服务器2提供服务;逻辑条带单元2、5、8也由数据服务器2提供服务。除非数据服务器2有两个文件句柄(每个都指向不同的数据文件),否则,例如,写入

logical stripe unit 1 overwrites the write to logical stripe unit 2 because both logical stripe units are located in the same stripe unit (0) of data server 2.

逻辑条带单元1覆盖对逻辑条带单元2的写入,因为两个逻辑条带单元位于数据服务器2的同一条带单元(0)中。

13.5. Data Server Multipathing
13.5. 数据服务器多路径

The NFSv4.1 file layout supports multipathing to multiple data server addresses. Data-server-level multipathing is used for bandwidth scaling via trunking (Section 2.10.5) and for higher availability of use in the case of a data-server failure. Multipathing allows the client to switch to another data server address which may be that of another data server that is exporting the same data stripe unit, without having to contact the metadata server for a new layout.

NFSv4.1文件布局支持多路径到多个数据服务器地址。数据服务器级多路径用于通过中继进行带宽扩展(第2.10.5节),并用于在数据服务器发生故障时提高可用性。多路径允许客户端切换到另一个数据服务器地址,该地址可能是正在导出相同数据条带单元的另一个数据服务器的地址,而无需联系元数据服务器以获取新布局。

To support data server multipathing, each element of the nflda_multipath_ds_list contains an array of one more data server network addresses. This array (data type multipath_list4) represents a list of data servers (each identified by a network address), with the possibility that some data servers will appear in the list multiple times.

为了支持数据服务器多路径,nflda_multipath_ds_列表的每个元素都包含一个多个数据服务器网络地址的数组。此数组(数据类型multipath_list4)表示数据服务器列表(每个服务器由网络地址标识),一些数据服务器可能会多次出现在列表中。

The client is free to use any of the network addresses as a destination to send data server requests. If some network addresses are less optimal paths to the data than others, then the MDS SHOULD NOT include those network addresses in an element of nflda_multipath_ds_list. If less optimal network addresses exist to provide failover, the RECOMMENDED method to offer the addresses is to provide them in a replacement device-ID-to-device-address mapping, or a replacement device ID. When a client finds that no data server in an element of nflda_multipath_ds_list responds, it SHOULD send a GETDEVICEINFO to attempt to replace the existing device-ID-to-device-address mappings. If the MDS detects that all data servers represented by an element of nflda_multipath_ds_list are unavailable, the MDS SHOULD send a CB_NOTIFY_DEVICEID (if the client has indicated it wants device ID notifications for changed device IDs) to change the device-ID-to-device-address mappings to the available data servers. If the device ID itself will be replaced, the MDS SHOULD recall all layouts with the device ID, and thus force the client to get new layouts and device ID mappings via LAYOUTGET and GETDEVICEINFO.

客户端可以自由使用任何网络地址作为发送数据服务器请求的目的地。如果某些网络地址不是数据的最佳路径,则MDS不应将这些网络地址包含在nflda_multipath_ds_列表的元素中。如果存在不太理想的网络地址来提供故障切换,建议在替换设备ID到设备地址映射或替换设备ID中提供这些地址。当客户端发现nflda_multipath_ds_list元素中没有数据服务器响应时,它应发送GETDEVICEINFO以尝试替换现有设备ID到设备地址的映射。如果MDS检测到nflda_multipath_ds_list元素表示的所有数据服务器都不可用,MDS应发送CB_NOTIFY_DEVICEID(如果客户端已表示希望设备ID通知更改的设备ID),以将设备ID到设备地址的映射更改为可用数据服务器。如果设备ID本身将被替换,MDS应该调用具有设备ID的所有布局,从而强制客户端通过LAYOUTGET和GETDEVICEINFO获得新的布局和设备ID映射。

Generally, if two network addresses appear in an element of nflda_multipath_ds_list, they will designate the same data server, and the two data server addresses will support the implementation of client ID or session trunking (the latter is RECOMMENDED) as defined in Section 2.10.5. The two data server addresses will share the same server owner or major ID of the server owner. It is not always

通常,如果nflda_multipath_ds_列表的一个元素中出现两个网络地址,则它们将指定相同的数据服务器,并且这两个数据服务器地址将支持实施第2.10.5节中定义的客户端ID或会话中继(建议采用后者)。这两个数据服务器地址将共享相同的服务器所有者或服务器所有者的主ID。并非总是如此

necessary for the two data server addresses to designate the same server with trunking being used. For example, the data could be read-only, and the data consist of exact replicas.

两个数据服务器地址必须指定使用中继的同一服务器。例如,数据可以是只读的,并且数据由精确的副本组成。

13.6. Operations Sent to NFSv4.1 Data Servers
13.6. 发送到NFSv4.1数据服务器的操作

Clients accessing data on an NFSv4.1 data server MUST send only the NULL procedure and COMPOUND procedures whose operations are taken only from two restricted subsets of the operations defined as valid NFSv4.1 operations. Clients MUST use the filehandle specified by the layout when accessing data on NFSv4.1 data servers.

访问NFSv4.1数据服务器上的数据的客户端必须仅发送空过程和复合过程,其操作仅来自定义为有效NFSv4.1操作的两个受限操作子集。在访问NFSv4.1数据服务器上的数据时,客户端必须使用布局指定的文件句柄。

The first of these operation subsets consists of management operations. This subset consists of the BACKCHANNEL_CTL, BIND_CONN_TO_SESSION, CREATE_SESSION, DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID, SECINFO_NO_NAME, SET_SSV, and SEQUENCE operations. The client may use these operations in order to set up and maintain the appropriate client IDs, sessions, and security contexts involved in communication with the data server. Henceforth, these will be referred to as data-server housekeeping operations.

第一个操作子集由管理操作组成。此子集由反向通道\u CTL、绑定\u连接\u到\u会话、创建\u会话、销毁\u客户端ID、销毁\u会话、交换\u ID、SECINFO\u否\u名称、设置\u SSV和序列操作组成。客户机可以使用这些操作来设置和维护与数据服务器通信所涉及的适当的客户机id、会话和安全上下文。此后,这些操作将被称为数据服务器内务管理操作。

The second subset consists of COMMIT, READ, WRITE, and PUTFH. These operations MUST be used with a current filehandle specified by the layout. In the case of PUTFH, the new current filehandle MUST be one taken from the layout. Henceforth, these will be referred to as data-server I/O operations. As described in Section 12.5.1, a client MUST NOT send an I/O to a data server for which it does not hold a valid layout; the data server MUST reject such an I/O.

第二个子集由COMMIT、READ、WRITE和PUTFH组成。这些操作必须与布局指定的当前文件句柄一起使用。对于PUTFH,新的当前文件句柄必须取自布局。此后,这些操作将被称为数据服务器I/O操作。如第12.5.1节所述,客户机不得向其未持有有效布局的数据服务器发送I/O;数据服务器必须拒绝此类I/O。

Unless the server has a concurrent non-data-server personality -- i.e., EXCHANGE_ID results returned (EXCHGID4_FLAG_USE_PNFS_DS | EXCHGID4_FLAG_USE_PNFS_MDS) or (EXCHGID4_FLAG_USE_PNFS_DS | EXCHGID4_FLAG_USE_NON_PNFS) see Section 13.1 -- any attempted use of operations against a data server other than those specified in the two subsets above MUST return NFS4ERR_NOTSUPP to the client.

除非服务器具有并发的非数据服务器特性,即返回的EXCHANGE_ID结果(EXCHGID4_标志_使用_PNFS_DS | EXCHGID4_标志_使用_PNFS_MDS)或(EXCHGID4_标志_使用_PNFS_DS | EXCHGID4_标志_使用_非_PNFS)请参阅第13.1节——任何针对数据服务器的操作尝试使用(上述两个子集中指定的操作除外)都必须将NFS4ERR_NOTSUPP返回给客户端。

When the server has concurrent data-server and non-data-server personalities, each COMPOUND sent by the client MUST be constructed so that it is appropriate to one of the two personalities, and it MUST NOT contain operations directed to a mix of those personalities. The server MUST enforce this. To understand the constraints, operations within a COMPOUND are divided into the following three classes:

当服务器具有并发的数据服务器和非数据服务器个性时,客户端发送的每个组合必须构造为适合于两个个性中的一个,并且不能包含针对这些个性的混合的操作。服务器必须强制执行此操作。为了理解这些约束,化合物内的操作分为以下三类:

1. An operation that is ambiguous regarding its personality assignment. This includes all of the data-server housekeeping operations. Additionally, if the server has assigned filehandles so that the ones defined by the layout are the same as those used

1. 关于其个性分配不明确的操作。这包括所有数据服务器内部管理操作。此外,如果服务器已分配文件句柄,则布局定义的文件句柄与使用的文件句柄相同

by the metadata server, all operations using such filehandles are within this class, with the following exception. The exception is that if the operation uses a stateid that is incompatible with a data-server personality (e.g., a special stateid or the stateid has a non-zero "seqid" field, see Section 13.9.1), the operation is in class 3, as described below. A COMPOUND containing multiple class 1 operations (and operations of no other class) MAY be sent to a server with multiple concurrent data server and non-data-server personalities.

通过元数据服务器,使用此类文件句柄的所有操作都在此类中,但以下情况除外。例外情况是,如果操作使用与数据服务器个性不兼容的stateid(例如,特殊stateid或stateid具有非零“seqid”字段,请参见第13.9.1节),则操作属于第3类,如下所述。包含多个class 1操作(以及没有其他类的操作)的复合可以发送到具有多个并发数据服务器和非数据服务器特征的服务器。

2. An operation that is unambiguously referable to the data-server personality. This includes data-server I/O operations where the filehandle is one that can only be validly directed to the data-server personality.

2. 可明确引用到数据服务器个性的操作。这包括数据服务器I/O操作,其中文件句柄只能有效地定向到数据服务器。

3. An operation that is unambiguously referable to the non-data-server personality. This includes all COMPOUND operations that are neither data-server housekeeping nor data-server I/O operations, plus data-server I/O operations where the current fh (or the one to be made the current fh in the case of PUTFH) is only valid on the metadata server or where a stateid is used that is incompatible with the data server, i.e., is a special stateid or has a non-zero seqid value.

3. 可明确引用非数据服务器个性的操作。这包括既不是数据服务器内务管理也不是数据服务器I/O操作的所有复合操作,以及当前fh(或在PUTFH情况下成为当前fh的fh)仅在元数据服务器上有效或使用与数据服务器不兼容的stateid的数据服务器I/O操作,即。,是特殊的stateid或具有非零的seqid值。

When a COMPOUND first executes an operation from class 3 above, it acts as a normal COMPOUND on any other server, and the data-server personality ceases to be relevant. There are no special restrictions on the operations in the COMPOUND to limit them to those for a data server. When a PUTFH is done, filehandles derived from the layout are not valid. If their format is not normally acceptable, then NFS4ERR_BADHANDLE MUST result. Similarly, current filehandles for other operations do not accept filehandles derived from layouts and are not normally usable on the metadata server. Using these will result in NFS4ERR_STALE.

当一个化合物第一次执行上面第3类中的操作时,它在任何其他服务器上都充当正常化合物,并且数据服务器的个性不再相关。对化合物中的操作没有特殊限制,仅限于数据服务器的操作。完成PUTFH后,从布局派生的文件句柄无效。如果其格式通常不可接受,则必须生成NFS4ERR_BADHANDLE。类似地,其他操作的当前文件句柄不接受从布局派生的文件句柄,并且在元数据服务器上通常不可用。使用这些将导致NFS4ERR_过时。

When a COMPOUND first executes an operation from class 2, which would be PUTFH where the filehandle is one from a layout, the COMPOUND henceforth is interpreted with respect to the data-server personality. Operations outside the two classes discussed above MUST result in NFS4ERR_NOTSUPP. Filehandles are validated using the rules of the data server, resulting in NFS4ERR_BADHANDLE and/or NFS4ERR_STALE even when they would not normally do so when addressed to the non-data-server personality. Stateids must obey the rules of the data server in that any use of special stateids or stateids with non-zero seqid values must result in NFS4ERR_BAD_STATEID.

当化合物首次执行来自类2的操作时,如果文件句柄是布局中的文件句柄,则该化合物将根据数据服务器个性进行解释。上述两个类之外的操作必须导致NFS4ERR_NOTSUPP。使用数据服务器的规则验证文件句柄,导致NFS4ERR_BADHANDLE和/或NFS4ERR_STALE,即使它们在寻址到非数据服务器时通常不会这样做。STATEID必须遵守数据服务器的规则,因为使用特殊STATEID或具有非零seqid值的STATEID必须导致NFS4ERR_BAD_STATEID。

Until the server first executes an operation from class 2 or class 3, the client MUST NOT depend on the operation being executed by either the data-server or the non-data-server personality. The server MUST pick one personality consistently for a given COMPOUND, with the only possible transition being a single one when the first operation from class 2 or class 3 is executed.

在服务器首次执行来自类2或类3的操作之前,客户端不得依赖于数据服务器或非数据服务器执行的操作。服务器必须始终如一地为给定的化合物选择一个个性,当执行第2类或第3类的第一个操作时,唯一可能的转换是单个个性。

Because of the complexity induced by assigning filehandles so they can be used on both a data server and a metadata server, it is RECOMMENDED that where the same server can have both personalities, the server assign separate unique filehandles to both personalities. This makes it unambiguous for which server a given request is intended.

由于分配文件句柄会导致复杂性,因此可以在数据服务器和元数据服务器上同时使用它们,因此建议在同一台服务器可以同时具有两个个性的情况下,服务器为两个个性分别分配唯一的文件句柄。这使得给定请求的目标服务器明确无误。

GETATTR and SETATTR MUST be directed to the metadata server. In the case of a SETATTR of the size attribute, the control protocol is responsible for propagating size updates/truncations to the data servers. In the case of extending WRITEs to the data servers, the new size must be visible on the metadata server once a LAYOUTCOMMIT has completed (see Section 12.5.4.2). Section 13.10 describes the mechanism by which the client is to handle data-server files that do not reflect the metadata server's size.

GETATTR和SETATTR必须定向到元数据服务器。对于size属性的SETATTR,控制协议负责将大小更新/截断传播到数据服务器。在将写入扩展到数据服务器的情况下,一旦LAYOUTCOMMIT完成,新的大小必须在元数据服务器上可见(请参阅第12.5.4.2节)。第13.10节描述了客户端处理不反映元数据服务器大小的数据服务器文件的机制。

13.7. COMMIT through Metadata Server
13.7. 通过元数据服务器提交

The file layout provides two alternate means of providing for the commit of data written through data servers. The flag NFL4_UFLG_COMMIT_THRU_MDS in the field nfl_util of the file layout (data type nfsv4_1_file_layout4) is an indication from the metadata server to the client of the REQUIRED way of performing COMMIT, either by sending the COMMIT to the data server or the metadata server. These two methods of dealing with the issue correspond to broad styles of implementation for a pNFS server supporting the file layout type.

文件布局提供了两种替代方法,用于提交通过数据服务器写入的数据。文件布局(数据类型nfsv4_1_file_layout4)字段nfl_util中的标志NFL4_UFLG_COMMIT_THRU MDS表示元数据服务器向客户端发送提交到数据服务器或元数据服务器所需的执行提交的方式。这两种处理问题的方法对应于支持文件布局类型的pNFS服务器的广泛实现风格。

o When the flag is FALSE, COMMIT operations MUST to be sent to the data server to which the corresponding WRITE operations were sent. This approach is sometimes useful when file striping is implemented within the pNFS server (instead of the file system), with the individual data servers each implementing their own file systems.

o 如果标志为FALSE,则必须将提交操作发送到发送了相应写入操作的数据服务器。当在pNFS服务器(而不是文件系统)中实现文件条带化时,这种方法有时很有用,每个数据服务器都实现自己的文件系统。

o When the flag is TRUE, COMMIT operations MUST be sent to the metadata server, rather than to the individual data servers. This approach is sometimes useful when file striping is implemented within the clustered file system that is the backend to the pNFS server. In such an implementation, each COMMIT to each data server might result in repeated writes of metadata blocks to the

o 当标志为TRUE时,提交操作必须发送到元数据服务器,而不是单个数据服务器。当在作为pNFS服务器后端的集群文件系统中实现文件条带化时,这种方法有时很有用。在这样的实现中,对每个数据服务器的每次提交都可能导致元数据块重复写入数据服务器

detriment of write performance. Sending a single COMMIT to the metadata server can be more efficient when there exists a clustered file system capable of implementing such a coordinated COMMIT.

对写入性能的损害。当存在能够实现这种协调提交的集群文件系统时,将单个提交发送到元数据服务器会更有效。

If nfl_util & NFL4_UFLG_COMMIT_THRU_MDS is TRUE, then in order to maintain the current NFSv4.1 commit and recovery model, the data servers MUST return a common writeverf verifier in all WRITE responses for a given file layout, and the metadata server's COMMIT implementation must return the same writeverf. The value of the writeverf verifier MUST be changed at the metadata server or any data server that is referenced in the layout, whenever there is a server event that can possibly lead to loss of uncommitted data. The scope of the verifier can be for a file or for the entire pNFS server. It might be more difficult for the server to maintain the verifier at the file level, but the benefit is that only events that impact a given file will require recovery action.

如果nfl_util&NFL4_UFLG_COMMIT_THRU_MDS为TRUE,则为了维护当前的NFSv4.1提交和恢复模型,数据服务器必须在给定文件布局的所有写入响应中返回公共writerf验证器,元数据服务器的提交实现必须返回相同的writerf。每当发生可能导致未提交数据丢失的服务器事件时,必须在元数据服务器或布局中引用的任何数据服务器上更改WriteEverf验证器的值。验证器的作用域可以是一个文件或整个pNFS服务器。服务器在文件级别维护验证器可能更困难,但好处是只有影响给定文件的事件才需要恢复操作。

Note that if the layout specified dense packing, then the offset used to a COMMIT to the MDS may differ than that of an offset used to a COMMIT to the data server.

请注意,如果布局指定密集打包,则用于提交到MDS的偏移量可能不同于用于提交到数据服务器的偏移量。

The single COMMIT to the metadata server will return a verifier, and the client should compare it to all the verifiers from the WRITEs and fail the COMMIT if there are any mismatched verifiers. If COMMIT to the metadata server fails, the client should re-send WRITEs for all the modified data in the file. The client should treat modified data with a mismatched verifier as a WRITE failure and try to recover by resending the WRITEs to the original data server or using another path to that data if the layout has not been recalled. Alternatively, the client can obtain a new layout or it could rewrite the data directly to the metadata server. If nfl_util & NFL4_UFLG_COMMIT_THRU_MDS is FALSE, sending a COMMIT to the metadata server might have no effect. If nfl_util & NFL4_UFLG_COMMIT_THRU_MDS is FALSE, a COMMIT sent to the metadata server should be used only to commit data that was written to the metadata server. See Section 12.7.6 for recovery options.

对元数据服务器的单个提交将返回一个验证器,客户端应将其与写入的所有验证器进行比较,如果存在任何不匹配的验证器,则提交失败。如果提交到元数据服务器失败,客户端应重新发送文件中所有修改数据的写入。客户端应将具有不匹配验证器的修改数据视为写入失败,并尝试通过将写入重新发送到原始数据服务器或在未调用布局的情况下使用该数据的其他路径来恢复。或者,客户机可以获得新的布局,也可以将数据直接重写到元数据服务器。如果nfl_util&NFL4_UFLG_COMMIT_THRU_MDS为FALSE,则向元数据服务器发送提交可能无效。如果nfl_util&NFL4_UFLG_COMMIT_THRU_MDS为FALSE,则发送到元数据服务器的提交应仅用于提交写入元数据服务器的数据。有关恢复选项,请参见第12.7.6节。

13.8. The Layout Iomode
13.8. Iomode的布局

The layout iomode need not be used by the metadata server when servicing NFSv4.1 file-based layouts, although in some circumstances it may be useful. For example, if the server implementation supports reading from read-only replicas or mirrors, it would be useful for the server to return a layout enabling the client to do so. As such, the client SHOULD set the iomode based on its intent to read or write the data. The client may default to an iomode of LAYOUTIOMODE4_RW.

在为基于NFSv4.1文件的布局提供服务时,元数据服务器不需要使用布局iomode,尽管在某些情况下它可能很有用。例如,如果服务器实现支持从只读副本或镜像读取,那么服务器返回一个布局使客户端能够执行此操作将非常有用。因此,客户机应根据其读取或写入数据的意图设置iomode。客户端可能默认为LAYOUTIOMODE4_RW的iomode。

The iomode need not be checked by the data servers when clients perform I/O. However, the data servers SHOULD still validate that the client holds a valid layout and return an error if the client does not.

当客户端执行I/O时,数据服务器无需检查iomode。但是,数据服务器仍应验证客户端是否拥有有效布局,如果客户端没有,则返回错误。

13.9. Metadata and Data Server State Coordination
13.9. 元数据和数据服务器状态协调
13.9.1. Global Stateid Requirements
13.9.1. 全球国家ID要求

When the client sends I/O to a data server, the stateid used MUST NOT be a layout stateid as returned by LAYOUTGET or sent by CB_LAYOUTRECALL. Permitted stateids are based on one of the following: an OPEN stateid (the stateid field of data type OPEN4resok as returned by OPEN), a delegation stateid (the stateid field of data types open_read_delegation4 and open_write_delegation4 as returned by OPEN or WANT_DELEGATION, or as sent by CB_PUSH_DELEG), or a stateid returned by the LOCK or LOCKU operations. The stateid sent to the data server MUST be sent with the seqid set to zero, indicating the most current version of that stateid, rather than indicating a specific non-zero seqid value. In no case is the use of special stateid values allowed.

当客户端向数据服务器发送I/O时,使用的stateid不能是LAYOUTGET返回的布局stateid或CB_LAYOUTRECALL发送的布局stateid。允许的stateid基于以下之一:OPEN stateid(由OPEN返回的数据类型为OPEN4resok的stateid字段)、delegation stateid(由OPEN或WANT_委托返回的数据类型为OPEN_read_delegation4和OPEN_write_delegation4的stateid字段,或由CB_PUSH_DELEG发送的数据类型为OPEN_read_delegation4和OPEN_write_delegation4的stateid字段),或由锁定或锁定操作返回的stateid。发送到数据服务器的stateid必须将seqid设置为零,以指示该stateid的最新版本,而不是指示特定的非零seqid值。在任何情况下都不允许使用特殊的stateid值。

The stateid used for I/O MUST have the same effect and be subject to the same validation on a data server as it would if the I/O was being performed on the metadata server itself in the absence of pNFS. This has the implication that stateids are globally valid on both the metadata and data servers. This requires the metadata server to propagate changes in LOCK and OPEN state to the data servers, so that the data servers can validate I/O accesses. This is discussed further in Section 13.9.2. Depending on when stateids are propagated, the existence of a valid stateid on the data server may act as proof of a valid layout.

用于I/O的stateid必须具有相同的效果,并在数据服务器上接受相同的验证,就像在没有PNF的情况下在元数据服务器上执行I/O一样。这意味着stateID在元数据服务器和数据服务器上都是全局有效的。这要求元数据服务器将锁定和打开状态的更改传播到数据服务器,以便数据服务器可以验证I/O访问。第13.9.2节对此进行了进一步讨论。根据传播stateid的时间,数据服务器上是否存在有效的stateid可以作为有效布局的证明。

Clients performing I/O operations need to select an appropriate stateid based on the locks (including opens and delegations) held by the client and the various types of state-owners sending the I/O requests. The rules for doing so when referencing data servers are somewhat different from those discussed in Section 8.2.5, which apply when accessing metadata servers.

执行I/O操作的客户端需要根据客户端持有的锁(包括打开和委派)以及发送I/O请求的各种类型的状态所有者选择适当的stateid。引用数据服务器时执行此操作的规则与第8.2.5节中讨论的规则有所不同,后者在访问元数据服务器时适用。

The following rules, applied in order of decreasing priority, govern the selection of the appropriate stateid:

以下规则按优先级降低的顺序应用,用于管理适当stateid的选择:

o If the client holds a delegation for the file in question, the delegation stateid should be used.

o 如果客户机持有相关文件的委托,则应使用委托stateid。

o Otherwise, there must be an OPEN stateid for the current open-owner, and that OPEN stateid for the open file in question is used, unless mandatory locking prevents that. See below.

o 否则,当前打开的所有者必须有一个OPEN stateid,并且将使用该打开的文件的OPEN stateid,除非强制锁定阻止了这一点。见下文。

o If the data server had previously responded with NFS4ERR_LOCKED to use of the OPEN stateid, then the client should use the byte-range lock stateid whenever one exists for that open file with the current lock-owner.

o 如果数据服务器先前响应NFS4ERR_LOCKED以使用OPEN stateid,则只要当前锁所有者的打开文件存在字节范围锁stateid,客户端就应该使用字节范围锁stateid。

o Special stateids should never be used. If they are used, the data server MUST reject the I/O with an NFS4ERR_BAD_STATEID error.

o 不应使用特殊的stateID。如果使用它们,数据服务器必须拒绝带有NFS4ERR_BAD_STATEID错误的I/O。

13.9.2. Data Server State Propagation
13.9.2. 数据服务器状态传播

Since the metadata server, which handles byte-range lock and open-mode state changes as well as ACLs, might not be co-located with the data servers where I/O accesses are validated, the server implementation MUST take care of propagating changes of this state to the data servers. Once the propagation to the data servers is complete, the full effect of those changes MUST be in effect at the data servers. However, some state changes need not be propagated immediately, although all changes SHOULD be propagated promptly. These state propagations have an impact on the design of the control protocol, even though the control protocol is outside of the scope of this specification. Immediate propagation refers to the synchronous propagation of state from the metadata server to the data server(s); the propagation must be complete before returning to the client.

由于元数据服务器(处理字节范围锁定和打开模式状态更改以及ACL)可能与验证I/O访问的数据服务器不在同一位置,因此服务器实现必须负责将此状态的更改传播到数据服务器。一旦向数据服务器的传播完成,这些更改的全部效果必须在数据服务器上生效。但是,有些状态更改不需要立即传播,尽管所有更改都应该立即传播。这些状态传播对控制协议的设计有影响,即使控制协议不在本规范的范围内。即时传播是指状态从元数据服务器同步传播到数据服务器;传播必须在返回到客户端之前完成。

13.9.2.1. Lock State Propagation
13.9.2.1. 锁状态传播

If the pNFS server supports mandatory byte-range locking, any mandatory byte-range locks on a file MUST be made effective at the data servers before the request that establishes them returns to the caller. The effect MUST be the same as if the mandatory byte-range lock state were synchronously propagated to the data servers, even though the details of the control protocol may avoid actual transfer of the state under certain circumstances.

如果pNFS服务器支持强制字节范围锁定,则必须在数据服务器上使文件上的任何强制字节范围锁定生效,然后才能将建立这些锁定的请求返回给调用方。其效果必须与强制字节范围锁定状态同步传播到数据服务器的效果相同,即使控制协议的细节可能会避免在某些情况下实际传输状态。

On the other hand, since advisory byte-range lock state is not used for checking I/O accesses at the data servers, there is no semantic reason for propagating advisory byte-range lock state to the data servers. Since updates to advisory locks neither confer nor remove privileges, these changes need not be propagated immediately, and may not need to be propagated promptly. The updates to advisory locks need only be propagated when the data server needs to resolve a question about a stateid. In fact, if byte-range locking is not mandatory (i.e., is advisory) the clients are advised to avoid using

另一方面,由于咨询字节范围锁定状态不用于检查数据服务器上的I/O访问,因此没有语义原因将咨询字节范围锁定状态传播到数据服务器。由于对通知锁的更新既不授予也不删除特权,因此不需要立即传播这些更改,也可能不需要立即传播。只有当数据服务器需要解决有关stateid的问题时,才需要传播对建议锁的更新。事实上,如果字节范围锁定不是强制性的(即,是建议性的),则建议客户端避免使用

the byte-range lock-based stateids for I/O. The stateids returned by OPEN are sufficient and eliminate overhead for this kind of state propagation.

I/O的基于字节范围锁的StateID。OPEN返回的StateID足够并消除了此类状态传播的开销。

If a client gets back an NFS4ERR_LOCKED error from a data server, this is an indication that mandatory byte-range locking is in force. The client recovers from this by getting a byte-range lock that covers the affected range and re-sends the I/O with the stateid of the byte-range lock.

如果客户端从数据服务器返回NFS4ERR_LOCKED错误,则表示强制字节范围锁定生效。客户端通过获取覆盖受影响范围的字节范围锁并使用字节范围锁的stateid重新发送I/O来恢复。

13.9.2.2. Open and Deny Mode Validation
13.9.2.2. 打开和拒绝模式验证

Open and deny mode validation MUST be performed against the open and deny mode(s) held by the data servers. When access is reduced or a deny mode made more restrictive (because of CLOSE or OPEN_DOWNGRADE), the data server MUST prevent any I/Os that would be denied if performed on the metadata server. When access is expanded, the data server MUST make sure that no requests are subsequently rejected because of open or deny issues that no longer apply, given the previous relaxation.

必须对数据服务器持有的打开和拒绝模式执行打开和拒绝模式验证。当访问减少或拒绝模式变得更加严格时(由于关闭或打开降级),数据服务器必须防止在元数据服务器上执行任何将被拒绝的I/O。当扩展访问权限时,数据服务器必须确保不会因为开放或拒绝问题而拒绝任何请求,而这些问题已不再适用,这是由于之前的放宽。

13.9.2.3. File Attributes
13.9.2.3. 文件属性

Since the SETATTR operation has the ability to modify state that is visible on both the metadata and data servers (e.g., the size), care must be taken to ensure that the resultant state across the set of data servers is consistent, especially when truncating or growing the file.

由于SETATTR操作能够修改元数据服务器和数据服务器上可见的状态(例如大小),因此必须注意确保数据服务器集合中的结果状态一致,尤其是在截断或增长文件时。

As described earlier, the LAYOUTCOMMIT operation is used to ensure that the metadata is synchronized with changes made to the data servers. For the NFSv4.1-based data storage protocol, it is necessary to re-synchronize state such as the size attribute, and the setting of mtime/change/atime. See Section 12.5.4 for a full description of the semantics regarding LAYOUTCOMMIT and attribute synchronization. It should be noted that by using an NFSv4.1-based layout type, it is possible to synchronize this state before LAYOUTCOMMIT occurs. For example, the control protocol can be used to query the attributes present on the data servers.

如前所述,LAYOUTCOMMIT操作用于确保元数据与对数据服务器所做的更改同步。对于基于NFSv4.1的数据存储协议,需要重新同步状态,例如大小属性和mtime/change/atime的设置。有关LAYOUTCOMMIT和属性同步的语义的完整描述,请参见第12.5.4节。应该注意,通过使用基于NFSv4.1的布局类型,可以在LAYOUTCOMMIT发生之前同步此状态。例如,控制协议可用于查询数据服务器上存在的属性。

Any changes to file attributes that control authorization or access as reflected by ACCESS calls or READs and WRITEs on the metadata server, MUST be propagated to the data servers for enforcement on READ and WRITE I/O calls. If the changes made on the metadata server result in more restrictive access permissions for any user, those changes MUST be propagated to the data servers synchronously.

元数据服务器上的访问调用或读写所反映的对控制授权或访问的文件属性的任何更改都必须传播到数据服务器,以强制执行读写I/O调用。如果在元数据服务器上所做的更改导致任何用户的访问权限受到更严格的限制,则必须将这些更改同步传播到数据服务器。

The OPEN operation (Section 18.16.4) does not impose any requirement that I/O operations on an open file have the same credentials as the OPEN itself (unless EXCHGID4_FLAG_BIND_PRINC_STATEID is set when EXCHANGE_ID creates the client ID), and so it requires the server's READ and WRITE operations to perform appropriate access checking. Changes to ACLs also require new access checking by READ and WRITE on the server. The propagation of access-right changes due to changes in ACLs may be asynchronous only if the server implementation is able to determine that the updated ACL is not more restrictive for any user specified in the old ACL. Due to the relative infrequency of ACL updates, it is suggested that all changes be propagated synchronously.

“打开”操作(第18.16.4节)不要求打开文件上的I/O操作具有与“打开”本身相同的凭据(除非EXCHANGE\U ID创建客户端ID时设置了EXCHGID4\U FLAG\U BIND\U PRINC\U STATEID),因此它要求服务器的读写操作执行适当的访问检查。对ACL的更改还需要通过服务器上的读写进行新的访问检查。只有当服务器实现能够确定更新的ACL对旧ACL中指定的任何用户没有更严格的限制时,由于ACL中的更改而导致的访问权限更改的传播才可能是异步的。由于ACL更新相对较少,建议同步传播所有更改。

13.10. Data Server Component File Size
13.10. 数据服务器组件文件大小

A potential problem exists when a component data file on a particular data server has grown past EOF; the problem exists for both dense and sparse layouts. Imagine the following scenario: a client creates a new file (size == 0) and writes to byte 131072; the client then seeks to the beginning of the file and reads byte 100. The client should receive zeroes back as a result of the READ. However, if the striping pattern directs the client to send the READ to a data server other than the one that received the client's original WRITE, the data server servicing the READ may believe that the file's size is still 0 bytes. In that event, the data server's READ response will contain zero bytes and an indication of EOF. The data server can only return zeroes if it knows that the file's size has been extended. This would require the immediate propagation of the file's size to all data servers, which is potentially very costly. Therefore, the client that has initiated the extension of the file's size MUST be prepared to deal with these EOF conditions. When the offset in the arguments to READ is less than the client's view of the file size, if the READ response indicates EOF and/or contains fewer bytes than requested, the client will interpret such a response as a hole in the file, and the NFS client will substitute zeroes for the data.

当特定数据服务器上的组件数据文件增长超过EOF时,存在潜在问题;密集布局和稀疏布局都存在此问题。设想以下场景:客户机创建一个新文件(大小==0)并写入字节131072;然后,客户端查找文件的开头并读取字节100。客户端在读取后应返回零。但是,如果条带化模式指示客户机将读取发送到接收客户机原始写入的数据服务器以外的数据服务器,则为读取提供服务的数据服务器可能认为文件大小仍然为0字节。在这种情况下,数据服务器的读取响应将包含零字节和EOF指示。如果数据服务器知道文件大小已扩展,则只能返回零。这需要立即将文件大小传播到所有数据服务器,这可能非常昂贵。因此,启动文件大小扩展的客户端必须准备好处理这些EOF条件。当要读取的参数中的偏移量小于客户端的文件大小视图时,如果读取响应指示EOF和/或包含的字节数少于请求的字节数,则客户端会将此类响应解释为文件中的孔,NFS客户端会将数据替换为零。

The NFSv4.1 protocol only provides close-to-open file data cache semantics; meaning that when the file is closed, all modified data is written to the server. When a subsequent OPEN of the file is done, the change attribute is inspected for a difference from a cached value for the change attribute. For the case above, this means that a LAYOUTCOMMIT will be done at close (along with the data WRITEs) and will update the file's size and change attribute. Access from another client after that point will result in the appropriate size being returned.

NFSv4.1协议仅提供接近开放的文件数据缓存语义;这意味着当文件关闭时,所有修改的数据都会写入服务器。当文件的后续打开完成时,将检查change属性是否与change属性的缓存值存在差异。对于上述情况,这意味着LAYOUTCOMMIT将在关闭时完成(与数据写入一起),并将更新文件的size和change属性。在该点之后从另一个客户端访问将导致返回适当的大小。

13.11. Layout Revocation and Fencing
13.11. 布局和围栏

As described in Section 12.7, the layout-type-specific storage protocol is responsible for handling the effects of I/Os that started before lease expiration and extend through lease expiration. The LAYOUT4_NFSV4_1_FILES layout type can prevent all I/Os to data servers from being executed after lease expiration (this prevention is called "fencing"), without relying on a precise client lease timer and without requiring data servers to maintain lease timers. The LAYOUT4_NFSV4_1_FILES pNFS server has the flexibility to revoke individual layouts, and thus fence I/O on a per-file basis.

如第12.7节所述,特定于布局类型的存储协议负责处理在租约到期之前开始并一直延续到租约到期的I/O的影响。LAYOUT4_NFSV4_1_文件布局类型可以防止在租约到期后执行到数据服务器的所有I/O(此预防措施称为“围栏”),而无需依赖精确的客户端租约计时器,也无需数据服务器维护租约计时器。LAYOUT4_NFSV4_1_文件pNFS服务器具有撤销单个布局的灵活性,因此可以根据每个文件限制I/O。

In addition to lease expiration, the reasons a layout can be revoked include: client fails to respond to a CB_LAYOUTRECALL, the metadata server restarts, or administrative intervention. Regardless of the reason, once a client's layout has been revoked, the pNFS server MUST prevent the client from sending I/O for the affected file from and to all data servers; in other words, it MUST fence the client from the affected file on the data servers.

除了租约到期之外,可以撤销布局的原因还包括:客户端未能响应CB_LAYOUTRECALL、元数据服务器重新启动或管理干预。无论出于何种原因,一旦撤销了客户端的布局,pNFS服务器必须阻止客户端从所有数据服务器向所有数据服务器发送受影响文件的I/O;换句话说,它必须将客户端与数据服务器上受影响的文件隔离开来。

Fencing works as follows. As described in Section 13.1, in COMPOUND procedure requests to the data server, the data filehandle provided by the PUTFH operation and the stateid in the READ or WRITE operation are used to ensure that the client has a valid layout for the I/O being performed; if it does not, the I/O is rejected with NFS4ERR_PNFS_NO_LAYOUT. The server can simply check the stateid and, additionally, make the data filehandle stale if the layout specified a data filehandle that is different from the metadata server's filehandle for the file (see the nfl_fh_list description in Section 13.3).

围栏工程如下。如第13.1节所述,在向数据服务器发出的复合过程请求中,PUTFH操作提供的数据文件句柄和读或写操作中的stateid用于确保客户端具有有效的I/O布局;如果没有,则使用NFS4ERR_PNFS_NO_布局拒绝I/O。服务器可以简单地检查stateid,此外,如果布局指定的数据文件句柄与元数据服务器的文件句柄不同,则可以使数据文件句柄过时(请参阅第13.3节中的nfl\U fh\U列表描述)。

Before the metadata server takes any action to revoke layout state given out by a previous instance, it must make sure that all layout state from that previous instance are invalidated at the data servers. This has the following implications.

在元数据服务器采取任何操作来撤销前一个实例给出的布局状态之前,它必须确保来自该前一个实例的所有布局状态在数据服务器上无效。这具有以下含义。

o The metadata server must not restripe a file until it has contacted all of the data servers to invalidate the layouts from the previous instance.

o 元数据服务器在与所有数据服务器联系以使上一个实例的布局无效之前,不得重新对文件进行管道传输。

o The metadata server must not give out mandatory locks that conflict with layouts from the previous instance without either doing a specific layout invalidation (as it would have to do anyway) or doing a global data server invalidation.

o 元数据服务器在未执行特定布局无效(无论如何都必须执行)或全局数据服务器无效的情况下,不得发出与前一个实例中的布局冲突的强制锁。

13.12. Security Considerations for the File Layout Type
13.12. 文件布局类型的安全注意事项

The NFSv4.1 file layout type MUST adhere to the security considerations outlined in Section 12.9. NFSv4.1 data servers MUST make all of the required access checks on each READ or WRITE I/O as determined by the NFSv4.1 protocol. If the metadata server would deny a READ or WRITE operation on a file due to its ACL, mode attribute, open access mode, open deny mode, mandatory byte-range lock state, or any other attributes and state, the data server MUST also deny the READ or WRITE operation. This impacts the control protocol and the propagation of state from the metadata server to the data servers; see Section 13.9.2 for more details.

NFSv4.1文件布局类型必须遵守第12.9节中概述的安全注意事项。NFSv4.1数据服务器必须对NFSv4.1协议确定的每个读或写I/O进行所有必需的访问检查。如果元数据服务器由于文件的ACL、模式属性、打开访问模式、打开拒绝模式、强制字节范围锁定状态或任何其他属性和状态而拒绝对文件执行读或写操作,则数据服务器还必须拒绝读或写操作。这会影响控制协议和状态从元数据服务器到数据服务器的传播;详见第13.9.2节。

The methods for authentication, integrity, and privacy for data servers based on the LAYOUT4_NFSV4_1_FILES layout type are the same as those used by metadata servers. Metadata and data servers use ONC RPC security flavors to authenticate, and SECINFO and SECINFO_NO_NAME to negotiate the security mechanism and services to be used. Thus, when using the LAYOUT4_NFSV4_1_FILES layout type, the impact on the RPC-based security model due to pNFS (as alluded to in Sections 1.7.1 and 1.7.2.2) is zero.

基于LAYOUT4_NFSV4_1_文件布局类型的数据服务器身份验证、完整性和隐私的方法与元数据服务器使用的方法相同。元数据和数据服务器使用ONC-RPC安全风格进行身份验证,SECINFO和SECINFO_NO_NAME协商要使用的安全机制和服务。因此,当使用LAYOUT4_NFSV4_1_文件布局类型时,pNFS(如第1.7.1节和第1.7.2.2节所述)对基于RPC的安全模型的影响为零。

For a given file object, a metadata server MAY require different security parameters (secinfo4 value) than the data server. For a given file object with multiple data servers, the secinfo4 value SHOULD be the same across all data servers. If the secinfo4 values across a metadata server and its data servers differ for a specific file, the mapping of the principal to the server's internal user identifier MUST be the same in order for the access-control checks based on ACL, mode, open and deny mode, and mandatory locking to be consistent across on the pNFS server.

对于给定的文件对象,元数据服务器可能需要与数据服务器不同的安全参数(secinfo4值)。对于具有多个数据服务器的给定文件对象,所有数据服务器的secinfo4值都应相同。如果元数据服务器及其数据服务器上的secinfo4值对于特定文件不同,则主体到服务器内部用户标识符的映射必须相同,以便在pNFS服务器上基于ACL、模式、打开和拒绝模式以及强制锁定的访问控制检查保持一致。

If an NFSv4.1 implementation supports pNFS and supports NFSv4.1 file layouts, then the implementation MUST support the SECINFO_NO_NAME operation on both the metadata and data servers.

如果NFSv4.1实现支持pNFS并支持NFSv4.1文件布局,则该实现必须在元数据服务器和数据服务器上支持SECINFO_NO_NAME操作。

14. Internationalization
14. 国际化

The primary issue in which NFSv4.1 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 that use various languages. The UTF-8 encoding of the UCS (Universal Multiple-Octet Coded Character Set) as defined by ISO10646 [21] allows for this type of access and follows the policy described in "IETF Policy on Character Sets and Languages", RFC 2277 [22].

NFSv4.1需要处理国际化或I18N的主要问题是协议中使用的文件名和其他字符串。字符串表示的选择必须允许对使用各种语言的客户端进行合理的名称/字符串访问。ISO10646[21]定义的UCS(通用多八位编码字符集)UTF-8编码允许这种访问类型,并遵循RFC 2277[22]中“关于字符集和语言的IETF策略”中描述的策略。

RFC 3454 [19], 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 section defines the NFSv4.1 stringprep profiles. Much of the terminology used for the remainder of this section comes from stringprep.

RFC 3454[19],也称为“stringprep”,记录了在网络协议中使用Unicode/UTF-8的框架,以便“增加字符串输入和字符串比较工作的可能性,使其对世界各地的典型用户都有意义”。协议必须定义stringprep的配置文件“以便完全指定处理选项”。本节其余部分定义了NFSv4.1 stringprep配置文件。本节其余部分使用的术语大多来自stringprep。

There are three UTF-8 string types defined for NFSv4.1: utf8str_cs, utf8str_cis, and utf8str_mixed. Separate profiles are defined for each. Each profile defines the following, as required by stringprep:

为NFSv4.1定义了三种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 the referenced version of stringprep). However, NFSv4.1 implementations are not limited to 3.2.

o 作为stringprep输入和输出的字符集(对于stringprep的引用版本,它是Unicode 3.2)。但是,NFSv4.1的实现并不限于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 the 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 NFSv4.1 renders UTF-8 characters. Since there is a one-to-one mapping from UTF-8 to Unicode, when the remainder of this document refers to Unicode, the reader should assume UTF-8.

Stringprep讨论Unicode字符,而NFSv4.1呈现UTF-8字符。由于存在从UTF-8到Unicode的一对一映射,因此当本文档的其余部分引用Unicode时,读者应该假设UTF-8。

Much of the text for the profiles comes from RFC 3491 [23].

配置文件的大部分文本来自RFC 3491[23]。

14.1. Stringprep Profile for the utf8str_cs Type
14.1. utf8str_cs类型的Stringprep配置文件

Every use of the utf8str_cs type definition in the NFSv4 protocol specification follows the profile named nfs4_cs_prep.

NFSv4协议规范中utf8str_cs类型定义的每次使用都遵循名为nfs4_cs_prep的概要文件。

14.1.1. Intended Applicability of the nfs4_cs_prep Profile
14.1.1. nfs4\U cs\U准备概要的预期适用性

The utf8str_cs type is a case-sensitive string of UTF-8 characters. Its primary use in NFSv4.1 is for naming components and pathnames. Components and pathnames are stored on the server's file system. 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 NFSv4.1 server will need to either:

utf8str_cs类型是一个区分大小写的UTF-8字符字符串。它在NFSv4.1中的主要用途是命名组件和路径名。组件和路径名存储在服务器的文件系统中。通过utf8str_cs配置文件处理后,两个有效的不同UTF-8字符串可能相同。如果字符串是目录中的两个名称,则NFSv4.1服务器需要:

o disallow the creation of a second name if its 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 允许创建第二个名称,但进行安排,以便在后处理后,第二个名称与第一个名称的后处理形式不同。

14.1.2. Character Repertoire of nfs4_cs_prep
14.1.2. nfs4\U cs\U prep人物剧目

The nfs4_cs_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1. However, NFSv4.1 implementations are not limited to 3.2.

nfs4_cs_prep配置文件使用Unicode 3.2,如stringprep附录A.1中所定义。但是,NFSv4.1的实现并不限于3.2。

14.1.3. Mapping Used by nfs4_cs_prep
14.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 NFSv4.1 file server supports the case_insensitive file system attribute, and if case_insensitive is TRUE, the NFSv4.1 server MUST use Table B.2 (in addition to Table B1) when processing utf8str_cs strings, and the NFSv4.1 client MUST assume Table B.2 (in addition to Table B.1) is being used.

表B.2通常不是nfs4_cs_prep概要的一部分,因为它主要用于处理不区分大小写的比较。但是,如果NFSv4.1文件服务器支持不区分大小写的文件系统属性,并且不区分大小写为TRUE,则NFSv4.1服务器在处理utf8str_cs字符串时必须使用表B.2(除表B1外),并且NFSv4.1客户端必须假定正在使用表B.2(除表B.1外)。

If the case_preserving attribute is present and set to FALSE, then the NFSv4.1 server MUST use Table B.2 to map case when processing utf8str_cs strings. Whether the server maps from lower to upper case or from upper to lower case is an implementation dependency.

如果case_preserving属性存在并设置为FALSE,则NFSv4.1服务器在处理utf8str_cs字符串时必须使用表B.2映射case。服务器是从小写映射到大写还是从大写映射到小写是一个实现依赖项。

14.1.4. Normalization used by nfs4_cs_prep
14.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 file system (at the server).

nfs4_cs_prep配置文件未指定规范化表单。本规范的后续版本可能会指定特定的规范化形式。因此,服务器和客户机可能会在协议请求和响应中接收到非规范化字符。如果操作环境需要规范化,那么在将信息呈现给应用程序(客户端)或本地文件系统(服务器)之前,实现必须规范化协议中的utf8str_cs字符串。

14.1.5. Prohibited Output for nfs4_cs_prep
14.1.5. nfs4\U cs\U准备的禁止输出

The nfs4_cs_prep profile RECOMMENDS prohibiting the use of the following tables from stringprep:

nfs4_cs_prep配置文件建议禁止在stringprep中使用下表:

Table C.5

表C.5

Table C.6

表C.6

14.1.6. Bidirectional Output for nfs4_cs_prep
14.1.6. nfs4\U cs\U准备的双向输出

The nfs4_cs_prep profile does not specify any checking of bidirectional strings.

nfs4_cs_prep配置文件未指定对双向字符串的任何检查。

14.2. Stringprep Profile for the utf8str_cis Type
14.2. utf8str_cis类型的Stringprep配置文件

Every use of the utf8str_cis type definition in the NFSv4.1 protocol specification follows the profile named nfs4_cis_prep.

NFSv4.1协议规范中utf8str_cis类型定义的每次使用都遵循名为nfs4_cis_prep的配置文件。

14.2.1. Intended Applicability of the nfs4_cis_prep Profile
14.2.1. nfs4\U cis\U准备概要的预期适用性

The utf8str_cis type is a case-insensitive string of UTF-8 characters. Its primary use in NFSv4.1 is for naming NFS servers.

utf8str_cis类型是一个不区分大小写的UTF-8字符字符串。它在NFSv4.1中的主要用途是命名NFS服务器。

14.2.2. Character Repertoire of nfs4_cis_prep
14.2.2. nfs4_cis_prep人物剧目

The nfs4_cis_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1. However, NFSv4.1 implementations are not limited to 3.2.

nfs4_cis_prep配置文件使用Unicode 3.2,如stringprep附录A.1中所定义。但是,NFSv4.1的实现并不限于3.2。

14.2.3. Mapping Used by nfs4_cis_prep
14.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

表B.1

Table B.2

表B.2

14.2.4. Normalization Used by nfs4_cis_prep
14.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中所述。

14.2.5. Prohibited Output for nfs4_cis_prep
14.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

表C.1.2

Table C.2.2

表C.2.2

Table C.3

表C.3

Table C.4

表C.4

Table C.5

表C.5

Table C.6

表C.6

Table C.7

表C.7

Table C.8

表C.8

Table C.9

表C.9

14.2.6. Bidirectional Output for nfs4_cis_prep
14.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节所述。

14.3. Stringprep Profile for the utf8str_mixed Type
14.3. utf8str_混合类型的Stringprep配置文件

Every use of the utf8str_mixed type definition in the NFSv4.1 protocol specification follows the profile named nfs4_mixed_prep.

NFSv4.1协议规范中utf8str_混合类型定义的每次使用都遵循名为nfs4_mixed_prep的配置文件。

14.3.1. Intended Applicability of the nfs4_mixed_prep Profile
14.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 a fully qualified domain name. Its primary use in NFSv4.1 is for naming principals identified in an Access Control Entry.

utf8str_混合类型是一个UTF-8字符字符串,前缀区分大小写,分隔符等于“@”,后缀为完全限定域名。它在NFSv4.1中的主要用途是命名访问控制条目中标识的主体。

14.3.2. Character Repertoire of nfs4_mixed_prep
14.3.2. nfs4_mixed_prep的角色曲目

The nfs4_mixed_prep profile uses Unicode 3.2, as defined in stringprep's Appendix A.1. However, NFSv4.1 implementations are not limited to 3.2.

nfs4_mixed_prep配置文件使用Unicode 3.2,定义见stringprep的附录A.1。但是,NFSv4.1的实现并不限于3.2。

14.3.3. Mapping Used by nfs4_cis_prep
14.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

表B.1

Table B.2

表B.2

14.3.4. Normalization Used by nfs4_mixed_prep
14.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中所述。

14.3.5. Prohibited Output for nfs4_mixed_prep
14.3.5. nfs4_混合_准备的禁止输出

The nfs4_mixed_prep profile specifies prohibiting using the following tables from stringprep:

nfs4_mixed_prep配置文件指定禁止从stringprep使用下表:

Table C.1.2

表C.1.2

Table C.2.2

表C.2.2

Table C.3

表C.3

Table C.4

表C.4

Table C.5

表C.5

Table C.6

表C.6

Table C.7

表C.7

Table C.8

表C.8

Table C.9

表C.9

14.3.6. Bidirectional Output for nfs4_mixed_prep
14.3.6. nfs4_混合_准备的双向输出

The nfs4_mixed_prep profile specifies checking bidirectional strings as described in stringprep's Section 6.

nfs4_mixed_prep配置文件指定检查stringprep第6节中所述的双向字符串。

14.4. UTF-8 Capabilities
14.4. UTF-8能力
   const FSCHARSET_CAP4_CONTAINS_NON_UTF8  = 0x1;
   const FSCHARSET_CAP4_ALLOWS_ONLY_UTF8   = 0x2;
        
   const FSCHARSET_CAP4_CONTAINS_NON_UTF8  = 0x1;
   const FSCHARSET_CAP4_ALLOWS_ONLY_UTF8   = 0x2;
        

typedef uint32_t fs_charset_cap4;

typedef uint32_t fs_charset_cap4;

Because some operating environments and file systems do not enforce character set encodings, NFSv4.1 supports the fs_charset_cap attribute (Section 5.8.2.11) that indicates to the client a file system's UTF-8 capabilities. The attribute is an integer containing a pair of flags. The first flag is FSCHARSET_CAP4_CONTAINS_NON_UTF8, which, if set to one, tells the client that the file system contains non-UTF-8 characters, and the server will not convert non-UTF characters to UTF-8 if the client reads a symlink or directory, neither will operations with component names or pathnames in the arguments convert the strings to UTF-8. The second flag is FSCHARSET_CAP4_ALLOWS_ONLY_UTF8, which, if set to one, indicates that the server will accept (and generate) only UTF-8 characters on the file system. If FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 is set to one, FSCHARSET_CAP4_CONTAINS_NON_UTF8 MUST be set to zero. FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 SHOULD always be set to one.

由于某些操作环境和文件系统不强制执行字符集编码,NFSv4.1支持fs_charset_cap属性(第5.8.2.11节),该属性向客户端指示文件系统的UTF-8功能。该属性是一个包含一对标志的整数。第一个标志是FSCHARSET_CAP4_CONTAINS_NON_UTF8,如果设置为1,则告知客户端文件系统包含非UTF-8字符,并且如果客户端读取符号链接或目录,服务器将不会将非UTF字符转换为UTF-8,参数中包含组件名或路径名的操作也不会将字符串转换为UTF-8。第二个标志是FSCHARSET_CAP4_ALLOWS_ONLY_UTF8,如果设置为1,则表示服务器将只接受(并生成)文件系统上的UTF-8字符。如果FSCHARSET_CAP4_ALLOWS_ONLY_UTF8设置为1,则FSCHARSET_CAP4_CONTAINS_NON_UTF8必须设置为零。FSCHARSET\u CAP4\u仅允许\u UTF8应始终设置为一。

14.5. UTF-8 Related Errors
14.5. UTF-8相关错误

Where the client sends an invalid UTF-8 string, the server should return NFS4ERR_INVAL (see Table 5). 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(参见表5)。这包括检测到不适当前缀的情况,以及计数包括不构成完整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 outside of Unicode plane 0

其中,客户端提供的字符串是有效的UTF-8,但包含服务器不支持作为该字符串值的字符(例如,名称包含Unicode平面0之外的字符)

on file systems that fail to support such characters despite their presence in the Unicode standard), the server should return NFS4ERR_BADCHAR.

对于无法支持此类字符(尽管Unicode标准中存在此类字符)的文件系统,服务器应返回NFS4ERR_BADCHAR。

Where a UTF-8 string is used as a file name, and the file system (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 (Table 5). This includes situations in which the server file system imposes a normalization constraint on name strings, but will also include such situations as file system prohibitions of "." and ".." as file names for certain operations, and other such constraints.

如果UTF-8字符串用作文件名,并且文件系统(支持名称中的所有字符)不允许使用该特定名称,则服务器应返回错误NFS4ERR_BADNAME(表5)。这包括服务器文件系统对名称字符串施加规范化约束的情况,但也包括文件系统禁止将“.”和“.”作为某些操作的文件名,以及其他此类约束。

15. Error Values
15. 错误值

NFS error numbers are assigned to failed operations within a Compound (COMPOUND or CB_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错误号分配给复合(复合或CB_复合)请求中的失败操作。复合请求包含许多NFS操作,这些操作的结果在复合应答中按顺序编码。成功操作的结果将包括NFS4_OK状态,然后是编码的操作结果。如果NFS操作失败,将在回复中输入错误状态,复合请求将终止。

15.1. Error Definitions
15.1. 错误定义

Protocol Error Definitions

协议错误定义

    +-----------------------------------+--------+-------------------+
    | Error                             | Number | Description       |
    +-----------------------------------+--------+-------------------+
    | NFS4_OK                           | 0      | Section 15.1.3.1  |
    | NFS4ERR_ACCESS                    | 13     | Section 15.1.6.1  |
    | NFS4ERR_ATTRNOTSUPP               | 10032  | Section 15.1.15.1 |
    | NFS4ERR_ADMIN_REVOKED             | 10047  | Section 15.1.5.1  |
    | NFS4ERR_BACK_CHAN_BUSY            | 10057  | Section 15.1.12.1 |
    | NFS4ERR_BADCHAR                   | 10040  | Section 15.1.7.1  |
    | NFS4ERR_BADHANDLE                 | 10001  | Section 15.1.2.1  |
    | NFS4ERR_BADIOMODE                 | 10049  | Section 15.1.10.1 |
    | NFS4ERR_BADLAYOUT                 | 10050  | Section 15.1.10.2 |
    | NFS4ERR_BADNAME                   | 10041  | Section 15.1.7.2  |
    | NFS4ERR_BADOWNER                  | 10039  | Section 15.1.15.2 |
    | NFS4ERR_BADSESSION                | 10052  | Section 15.1.11.1 |
    | NFS4ERR_BADSLOT                   | 10053  | Section 15.1.11.2 |
    | NFS4ERR_BADTYPE                   | 10007  | Section 15.1.4.1  |
    | NFS4ERR_BADXDR                    | 10036  | Section 15.1.1.1  |
    | NFS4ERR_BAD_COOKIE                | 10003  | Section 15.1.1.2  |
    | NFS4ERR_BAD_HIGH_SLOT             | 10077  | Section 15.1.11.3 |
    | NFS4ERR_BAD_RANGE                 | 10042  | Section 15.1.8.1  |
        
    +-----------------------------------+--------+-------------------+
    | Error                             | Number | Description       |
    +-----------------------------------+--------+-------------------+
    | NFS4_OK                           | 0      | Section 15.1.3.1  |
    | NFS4ERR_ACCESS                    | 13     | Section 15.1.6.1  |
    | NFS4ERR_ATTRNOTSUPP               | 10032  | Section 15.1.15.1 |
    | NFS4ERR_ADMIN_REVOKED             | 10047  | Section 15.1.5.1  |
    | NFS4ERR_BACK_CHAN_BUSY            | 10057  | Section 15.1.12.1 |
    | NFS4ERR_BADCHAR                   | 10040  | Section 15.1.7.1  |
    | NFS4ERR_BADHANDLE                 | 10001  | Section 15.1.2.1  |
    | NFS4ERR_BADIOMODE                 | 10049  | Section 15.1.10.1 |
    | NFS4ERR_BADLAYOUT                 | 10050  | Section 15.1.10.2 |
    | NFS4ERR_BADNAME                   | 10041  | Section 15.1.7.2  |
    | NFS4ERR_BADOWNER                  | 10039  | Section 15.1.15.2 |
    | NFS4ERR_BADSESSION                | 10052  | Section 15.1.11.1 |
    | NFS4ERR_BADSLOT                   | 10053  | Section 15.1.11.2 |
    | NFS4ERR_BADTYPE                   | 10007  | Section 15.1.4.1  |
    | NFS4ERR_BADXDR                    | 10036  | Section 15.1.1.1  |
    | NFS4ERR_BAD_COOKIE                | 10003  | Section 15.1.1.2  |
    | NFS4ERR_BAD_HIGH_SLOT             | 10077  | Section 15.1.11.3 |
    | NFS4ERR_BAD_RANGE                 | 10042  | Section 15.1.8.1  |
        
    | NFS4ERR_BAD_SEQID                 | 10026  | Section 15.1.16.1 |
    | NFS4ERR_BAD_SESSION_DIGEST        | 10051  | Section 15.1.12.2 |
    | NFS4ERR_BAD_STATEID               | 10025  | Section 15.1.5.2  |
    | NFS4ERR_CB_PATH_DOWN              | 10048  | Section 15.1.11.4 |
    | NFS4ERR_CLID_INUSE                | 10017  | Section 15.1.13.2 |
    | NFS4ERR_CLIENTID_BUSY             | 10074  | Section 15.1.13.1 |
    | NFS4ERR_COMPLETE_ALREADY          | 10054  | Section 15.1.9.1  |
    | NFS4ERR_CONN_NOT_BOUND_TO_SESSION | 10055  | Section 15.1.11.6 |
    | NFS4ERR_DEADLOCK                  | 10045  | Section 15.1.8.2  |
    | NFS4ERR_DEADSESSION               | 10078  | Section 15.1.11.5 |
    | NFS4ERR_DELAY                     | 10008  | Section 15.1.1.3  |
    | NFS4ERR_DELEG_ALREADY_WANTED      | 10056  | Section 15.1.14.1 |
    | NFS4ERR_DELEG_REVOKED             | 10087  | Section 15.1.5.3  |
    | NFS4ERR_DENIED                    | 10010  | Section 15.1.8.3  |
    | NFS4ERR_DIRDELEG_UNAVAIL          | 10084  | Section 15.1.14.2 |
    | NFS4ERR_DQUOT                     | 69     | Section 15.1.4.2  |
    | NFS4ERR_ENCR_ALG_UNSUPP           | 10079  | Section 15.1.13.3 |
    | NFS4ERR_EXIST                     | 17     | Section 15.1.4.3  |
    | NFS4ERR_EXPIRED                   | 10011  | Section 15.1.5.4  |
    | NFS4ERR_FBIG                      | 27     | Section 15.1.4.4  |
    | NFS4ERR_FHEXPIRED                 | 10014  | Section 15.1.2.2  |
    | NFS4ERR_FILE_OPEN                 | 10046  | Section 15.1.4.5  |
    | NFS4ERR_GRACE                     | 10013  | Section 15.1.9.2  |
    | NFS4ERR_HASH_ALG_UNSUPP           | 10072  | Section 15.1.13.4 |
    | NFS4ERR_INVAL                     | 22     | Section 15.1.1.4  |
    | NFS4ERR_IO                        | 5      | Section 15.1.4.6  |
    | NFS4ERR_ISDIR                     | 21     | Section 15.1.2.3  |
    | NFS4ERR_LAYOUTTRYLATER            | 10058  | Section 15.1.10.3 |
    | NFS4ERR_LAYOUTUNAVAILABLE         | 10059  | Section 15.1.10.4 |
    | NFS4ERR_LEASE_MOVED               | 10031  | Section 15.1.16.2 |
    | NFS4ERR_LOCKED                    | 10012  | Section 15.1.8.4  |
    | NFS4ERR_LOCKS_HELD                | 10037  | Section 15.1.8.5  |
    | NFS4ERR_LOCK_NOTSUPP              | 10043  | Section 15.1.8.6  |
    | NFS4ERR_LOCK_RANGE                | 10028  | Section 15.1.8.7  |
    | NFS4ERR_MINOR_VERS_MISMATCH       | 10021  | Section 15.1.3.2  |
    | NFS4ERR_MLINK                     | 31     | Section 15.1.4.7  |
    | NFS4ERR_MOVED                     | 10019  | Section 15.1.2.4  |
    | NFS4ERR_NAMETOOLONG               | 63     | Section 15.1.7.3  |
    | NFS4ERR_NOENT                     | 2      | Section 15.1.4.8  |
    | NFS4ERR_NOFILEHANDLE              | 10020  | Section 15.1.2.5  |
    | NFS4ERR_NOMATCHING_LAYOUT         | 10060  | Section 15.1.10.5 |
    | NFS4ERR_NOSPC                     | 28     | Section 15.1.4.9  |
    | NFS4ERR_NOTDIR                    | 20     | Section 15.1.2.6  |
    | NFS4ERR_NOTEMPTY                  | 66     | Section 15.1.4.10 |
    | NFS4ERR_NOTSUPP                   | 10004  | Section 15.1.1.5  |
    | NFS4ERR_NOT_ONLY_OP               | 10081  | Section 15.1.3.3  |
    | NFS4ERR_NOT_SAME                  | 10027  | Section 15.1.15.3 |
    | NFS4ERR_NO_GRACE                  | 10033  | Section 15.1.9.3  |
        
    | NFS4ERR_BAD_SEQID                 | 10026  | Section 15.1.16.1 |
    | NFS4ERR_BAD_SESSION_DIGEST        | 10051  | Section 15.1.12.2 |
    | NFS4ERR_BAD_STATEID               | 10025  | Section 15.1.5.2  |
    | NFS4ERR_CB_PATH_DOWN              | 10048  | Section 15.1.11.4 |
    | NFS4ERR_CLID_INUSE                | 10017  | Section 15.1.13.2 |
    | NFS4ERR_CLIENTID_BUSY             | 10074  | Section 15.1.13.1 |
    | NFS4ERR_COMPLETE_ALREADY          | 10054  | Section 15.1.9.1  |
    | NFS4ERR_CONN_NOT_BOUND_TO_SESSION | 10055  | Section 15.1.11.6 |
    | NFS4ERR_DEADLOCK                  | 10045  | Section 15.1.8.2  |
    | NFS4ERR_DEADSESSION               | 10078  | Section 15.1.11.5 |
    | NFS4ERR_DELAY                     | 10008  | Section 15.1.1.3  |
    | NFS4ERR_DELEG_ALREADY_WANTED      | 10056  | Section 15.1.14.1 |
    | NFS4ERR_DELEG_REVOKED             | 10087  | Section 15.1.5.3  |
    | NFS4ERR_DENIED                    | 10010  | Section 15.1.8.3  |
    | NFS4ERR_DIRDELEG_UNAVAIL          | 10084  | Section 15.1.14.2 |
    | NFS4ERR_DQUOT                     | 69     | Section 15.1.4.2  |
    | NFS4ERR_ENCR_ALG_UNSUPP           | 10079  | Section 15.1.13.3 |
    | NFS4ERR_EXIST                     | 17     | Section 15.1.4.3  |
    | NFS4ERR_EXPIRED                   | 10011  | Section 15.1.5.4  |
    | NFS4ERR_FBIG                      | 27     | Section 15.1.4.4  |
    | NFS4ERR_FHEXPIRED                 | 10014  | Section 15.1.2.2  |
    | NFS4ERR_FILE_OPEN                 | 10046  | Section 15.1.4.5  |
    | NFS4ERR_GRACE                     | 10013  | Section 15.1.9.2  |
    | NFS4ERR_HASH_ALG_UNSUPP           | 10072  | Section 15.1.13.4 |
    | NFS4ERR_INVAL                     | 22     | Section 15.1.1.4  |
    | NFS4ERR_IO                        | 5      | Section 15.1.4.6  |
    | NFS4ERR_ISDIR                     | 21     | Section 15.1.2.3  |
    | NFS4ERR_LAYOUTTRYLATER            | 10058  | Section 15.1.10.3 |
    | NFS4ERR_LAYOUTUNAVAILABLE         | 10059  | Section 15.1.10.4 |
    | NFS4ERR_LEASE_MOVED               | 10031  | Section 15.1.16.2 |
    | NFS4ERR_LOCKED                    | 10012  | Section 15.1.8.4  |
    | NFS4ERR_LOCKS_HELD                | 10037  | Section 15.1.8.5  |
    | NFS4ERR_LOCK_NOTSUPP              | 10043  | Section 15.1.8.6  |
    | NFS4ERR_LOCK_RANGE                | 10028  | Section 15.1.8.7  |
    | NFS4ERR_MINOR_VERS_MISMATCH       | 10021  | Section 15.1.3.2  |
    | NFS4ERR_MLINK                     | 31     | Section 15.1.4.7  |
    | NFS4ERR_MOVED                     | 10019  | Section 15.1.2.4  |
    | NFS4ERR_NAMETOOLONG               | 63     | Section 15.1.7.3  |
    | NFS4ERR_NOENT                     | 2      | Section 15.1.4.8  |
    | NFS4ERR_NOFILEHANDLE              | 10020  | Section 15.1.2.5  |
    | NFS4ERR_NOMATCHING_LAYOUT         | 10060  | Section 15.1.10.5 |
    | NFS4ERR_NOSPC                     | 28     | Section 15.1.4.9  |
    | NFS4ERR_NOTDIR                    | 20     | Section 15.1.2.6  |
    | NFS4ERR_NOTEMPTY                  | 66     | Section 15.1.4.10 |
    | NFS4ERR_NOTSUPP                   | 10004  | Section 15.1.1.5  |
    | NFS4ERR_NOT_ONLY_OP               | 10081  | Section 15.1.3.3  |
    | NFS4ERR_NOT_SAME                  | 10027  | Section 15.1.15.3 |
    | NFS4ERR_NO_GRACE                  | 10033  | Section 15.1.9.3  |
        
    | NFS4ERR_NXIO                      | 6      | Section 15.1.16.3 |
    | NFS4ERR_OLD_STATEID               | 10024  | Section 15.1.5.5  |
    | NFS4ERR_OPENMODE                  | 10038  | Section 15.1.8.8  |
    | NFS4ERR_OP_ILLEGAL                | 10044  | Section 15.1.3.4  |
    | NFS4ERR_OP_NOT_IN_SESSION         | 10071  | Section 15.1.3.5  |
    | NFS4ERR_PERM                      | 1      | Section 15.1.6.2  |
    | NFS4ERR_PNFS_IO_HOLE              | 10075  | Section 15.1.10.6 |
    | NFS4ERR_PNFS_NO_LAYOUT            | 10080  | Section 15.1.10.7 |
    | NFS4ERR_RECALLCONFLICT            | 10061  | Section 15.1.14.3 |
    | NFS4ERR_RECLAIM_BAD               | 10034  | Section 15.1.9.4  |
    | NFS4ERR_RECLAIM_CONFLICT          | 10035  | Section 15.1.9.5  |
    | NFS4ERR_REJECT_DELEG              | 10085  | Section 15.1.14.4 |
    | NFS4ERR_REP_TOO_BIG               | 10066  | Section 15.1.3.6  |
    | NFS4ERR_REP_TOO_BIG_TO_CACHE      | 10067  | Section 15.1.3.7  |
    | NFS4ERR_REQ_TOO_BIG               | 10065  | Section 15.1.3.8  |
    | NFS4ERR_RESTOREFH                 | 10030  | Section 15.1.16.4 |
    | NFS4ERR_RETRY_UNCACHED_REP        | 10068  | Section 15.1.3.9  |
    | NFS4ERR_RETURNCONFLICT            | 10086  | Section 15.1.10.8 |
    | NFS4ERR_ROFS                      | 30     | Section 15.1.4.11 |
    | NFS4ERR_SAME                      | 10009  | Section 15.1.15.4 |
    | NFS4ERR_SHARE_DENIED              | 10015  | Section 15.1.8.9  |
    | NFS4ERR_SEQUENCE_POS              | 10064  | Section 15.1.3.10 |
    | NFS4ERR_SEQ_FALSE_RETRY           | 10076  | Section 15.1.11.7 |
    | NFS4ERR_SEQ_MISORDERED            | 10063  | Section 15.1.11.8 |
    | NFS4ERR_SERVERFAULT               | 10006  | Section 15.1.1.6  |
    | NFS4ERR_STALE                     | 70     | Section 15.1.2.7  |
    | NFS4ERR_STALE_CLIENTID            | 10022  | Section 15.1.13.5 |
    | NFS4ERR_STALE_STATEID             | 10023  | Section 15.1.16.5 |
    | NFS4ERR_SYMLINK                   | 10029  | Section 15.1.2.8  |
    | NFS4ERR_TOOSMALL                  | 10005  | Section 15.1.1.7  |
    | NFS4ERR_TOO_MANY_OPS              | 10070  | Section 15.1.3.11 |
    | NFS4ERR_UNKNOWN_LAYOUTTYPE        | 10062  | Section 15.1.10.9 |
    | NFS4ERR_UNSAFE_COMPOUND           | 10069  | Section 15.1.3.12 |
    | NFS4ERR_WRONGSEC                  | 10016  | Section 15.1.6.3  |
    | NFS4ERR_WRONG_CRED                | 10082  | Section 15.1.6.4  |
    | NFS4ERR_WRONG_TYPE                | 10083  | Section 15.1.2.9  |
    | NFS4ERR_XDEV                      | 18     | Section 15.1.4.12 |
    +-----------------------------------+--------+-------------------+
        
    | NFS4ERR_NXIO                      | 6      | Section 15.1.16.3 |
    | NFS4ERR_OLD_STATEID               | 10024  | Section 15.1.5.5  |
    | NFS4ERR_OPENMODE                  | 10038  | Section 15.1.8.8  |
    | NFS4ERR_OP_ILLEGAL                | 10044  | Section 15.1.3.4  |
    | NFS4ERR_OP_NOT_IN_SESSION         | 10071  | Section 15.1.3.5  |
    | NFS4ERR_PERM                      | 1      | Section 15.1.6.2  |
    | NFS4ERR_PNFS_IO_HOLE              | 10075  | Section 15.1.10.6 |
    | NFS4ERR_PNFS_NO_LAYOUT            | 10080  | Section 15.1.10.7 |
    | NFS4ERR_RECALLCONFLICT            | 10061  | Section 15.1.14.3 |
    | NFS4ERR_RECLAIM_BAD               | 10034  | Section 15.1.9.4  |
    | NFS4ERR_RECLAIM_CONFLICT          | 10035  | Section 15.1.9.5  |
    | NFS4ERR_REJECT_DELEG              | 10085  | Section 15.1.14.4 |
    | NFS4ERR_REP_TOO_BIG               | 10066  | Section 15.1.3.6  |
    | NFS4ERR_REP_TOO_BIG_TO_CACHE      | 10067  | Section 15.1.3.7  |
    | NFS4ERR_REQ_TOO_BIG               | 10065  | Section 15.1.3.8  |
    | NFS4ERR_RESTOREFH                 | 10030  | Section 15.1.16.4 |
    | NFS4ERR_RETRY_UNCACHED_REP        | 10068  | Section 15.1.3.9  |
    | NFS4ERR_RETURNCONFLICT            | 10086  | Section 15.1.10.8 |
    | NFS4ERR_ROFS                      | 30     | Section 15.1.4.11 |
    | NFS4ERR_SAME                      | 10009  | Section 15.1.15.4 |
    | NFS4ERR_SHARE_DENIED              | 10015  | Section 15.1.8.9  |
    | NFS4ERR_SEQUENCE_POS              | 10064  | Section 15.1.3.10 |
    | NFS4ERR_SEQ_FALSE_RETRY           | 10076  | Section 15.1.11.7 |
    | NFS4ERR_SEQ_MISORDERED            | 10063  | Section 15.1.11.8 |
    | NFS4ERR_SERVERFAULT               | 10006  | Section 15.1.1.6  |
    | NFS4ERR_STALE                     | 70     | Section 15.1.2.7  |
    | NFS4ERR_STALE_CLIENTID            | 10022  | Section 15.1.13.5 |
    | NFS4ERR_STALE_STATEID             | 10023  | Section 15.1.16.5 |
    | NFS4ERR_SYMLINK                   | 10029  | Section 15.1.2.8  |
    | NFS4ERR_TOOSMALL                  | 10005  | Section 15.1.1.7  |
    | NFS4ERR_TOO_MANY_OPS              | 10070  | Section 15.1.3.11 |
    | NFS4ERR_UNKNOWN_LAYOUTTYPE        | 10062  | Section 15.1.10.9 |
    | NFS4ERR_UNSAFE_COMPOUND           | 10069  | Section 15.1.3.12 |
    | NFS4ERR_WRONGSEC                  | 10016  | Section 15.1.6.3  |
    | NFS4ERR_WRONG_CRED                | 10082  | Section 15.1.6.4  |
    | NFS4ERR_WRONG_TYPE                | 10083  | Section 15.1.2.9  |
    | NFS4ERR_XDEV                      | 18     | Section 15.1.4.12 |
    +-----------------------------------+--------+-------------------+
        

Table 5

表5

15.1.1. General Errors
15.1.1. 一般错误

This section deals with errors that are applicable to a broad set of different purposes.

本节讨论适用于各种不同目的的错误。

15.1.1.1. NFS4ERR_BADXDR (Error Code 10036)
15.1.1.1. NFS4ERR_BADXDR(错误代码10036)

The arguments for this operation do not match those specified in the XDR definition. This includes situations in which the request ends before all the arguments have been seen. Note that this error applies when fixed enumerations (these include booleans) have a value within the input stream that is not valid for the enum. A replier may pre-parse all operations for a Compound procedure before doing any operation execution and return RPC-level XDR errors in that case.

此操作的参数与XDR定义中指定的参数不匹配。这包括请求在看到所有参数之前结束的情况。请注意,当固定枚举(包括布尔值)在输入流中具有对枚举无效的值时,此错误适用。应答器可以在执行任何操作之前预解析复合过程的所有操作,并在这种情况下返回RPC级别的XDR错误。

15.1.1.2. NFS4ERR_BAD_COOKIE (Error Code 10003)
15.1.1.2. NFS4ERR_BAD_COOKIE(错误代码10003)

Used for operations that provide a set of information indexed by some quantity provided by the client or cookie sent by the server for an earlier invocation. Where the value cannot be used for its intended purpose, this error results.

用于提供一组信息的操作,这些信息按客户机提供的数量或服务器为早期调用发送的cookie进行索引。如果该值不能用于预期目的,则会导致此错误。

15.1.1.3. NFS4ERR_DELAY (Error Code 10008)
15.1.1.3. NFS4ERR_延迟(错误代码10008)

For any of a number of reasons, the replier could not process this operation in what was deemed a reasonable time. The client should wait and then try the request with a new slot and sequence value.

由于多种原因之一,回复人无法在合理时间内处理此操作。客户端应该等待,然后使用新的插槽和序列值尝试请求。

Some examples of scenarios that might lead to this situation:

可能导致这种情况的一些场景示例:

o A server that supports hierarchical storage receives a request to process a file that had been migrated.

o 支持分层存储的服务器接收处理已迁移文件的请求。

o An operation requires a delegation recall to proceed, and waiting for this delegation recall makes processing this request in a timely fashion impossible.

o 一个操作需要一个委派调用才能继续,而等待该委派调用使得无法及时处理该请求。

In such cases, the error NFS4ERR_DELAY allows these preparatory operations to proceed without holding up client resources such as a session slot. After delaying for period of time, the client can then re-send the operation in question (but not with the same slot ID and sequence ID; one or both MUST be different on the re-send).

在这种情况下,错误NFS4ERR_延迟允许这些准备操作继续进行,而不会占用诸如会话插槽之类的客户端资源。延迟一段时间后,客户端可以重新发送有问题的操作(但不能使用相同的插槽ID和序列ID;重新发送时必须有一个或两个不同)。

Note that without the ability to return NFS4ERR_DELAY and the client's willingness to re-send when receiving it, deadlock might result. For example, if a recall is done, and if the delegation return or operations preparatory to delegation return are held up by other operations that need the delegation to be returned, session slots might not be available. The result could be deadlock.

请注意,如果没有返回NFS4ERR_延迟的能力以及客户端在接收延迟时愿意重新发送,则可能会导致死锁。例如,如果执行了回调,并且委托返回或准备委托返回的操作被需要返回委托的其他操作阻塞,则会话时段可能不可用。结果可能是死锁。

15.1.1.4. NFS4ERR_INVAL (Error Code 22)
15.1.1.4. NFS4ERR_INVAL(错误代码22)

The arguments for this operation are not valid for some reason, even though they do match those specified in the XDR definition for the request.

由于某种原因,此操作的参数无效,即使它们与请求的XDR定义中指定的参数匹配。

15.1.1.5. NFS4ERR_NOTSUPP (Error Code 10004)
15.1.1.5. NFS4ERR_NOTSUPP(错误代码10004)

Operation not supported, either because the operation is an OPTIONAL one and is not supported by this server or because the operation MUST NOT be implemented in the current minor version.

操作不受支持,原因可能是该操作是可选操作且此服务器不支持该操作,或者该操作不能在当前次要版本中实现。

15.1.1.6. NFS4ERR_SERVERFAULT (Error Code 10006)
15.1.1.6. NFS4ERR_服务器故障(错误代码10006)

An error occurred on the server that does not map to any of the specific legal NFSv4.1 protocol error values. The client should translate this into an appropriate error. UNIX clients may choose to translate this to EIO.

服务器上发生错误,该错误未映射到任何特定的合法NFSv4.1协议错误值。客户机应将此转换为适当的错误。UNIX客户端可以选择将其转换为EIO。

15.1.1.7. NFS4ERR_TOOSMALL (Error Code 10005)
15.1.1.7. NFS4ERR_太小(错误代码10005)

Used where an operation returns a variable amount of data, with a limit specified by the client. Where the data returned cannot be fit within the limit specified by the client, this error results.

当操作返回可变数量的数据时使用,限制由客户端指定。如果返回的数据不能符合客户端指定的限制,则会导致此错误。

15.1.2. Filehandle Errors
15.1.2. 文件句柄错误

These errors deal with the situation in which the current or saved filehandle, or the filehandle passed to PUTFH intended to become the current filehandle, is invalid in some way. This includes situations in which the filehandle is a valid filehandle in general but is not of the appropriate object type for the current operation.

这些错误处理的情况是,当前或保存的文件句柄,或传递给PUTFH(打算成为当前文件句柄)的文件句柄在某种程度上无效。这包括以下情况:filehandle通常是有效的filehandle,但不是当前操作的适当对象类型。

Where the error description indicates a problem with the current or saved filehandle, it is to be understood that filehandles are only checked for the condition if they are implicit arguments of the operation in question.

如果错误描述表明当前或保存的文件句柄存在问题,则应理解,只有当文件句柄是相关操作的隐式参数时,才会检查其条件。

15.1.2.1. NFS4ERR_BADHANDLE (Error Code 10001)
15.1.2.1. NFS4ERR_BADHANDLE(错误代码10001)

Illegal NFS filehandle for the current server. The current file handle failed internal consistency checks. Once accepted as valid (by PUTFH), no subsequent status change can cause the filehandle to generate this error.

当前服务器的NFS文件句柄非法。当前文件句柄未通过内部一致性检查。一旦被(PUTFH)接受为有效,任何后续状态更改都不会导致filehandle生成此错误。

15.1.2.2. NFS4ERR_FHEXPIRED (Error Code 10014)
15.1.2.2. NFS4ERR_FHU已过期(错误代码10014)

A current or saved filehandle that is an argument to the current operation is volatile and has expired at the server.

作为当前操作参数的当前或保存的filehandle是不稳定的,并且已在服务器上过期。

15.1.2.3. NFS4ERR_ISDIR (Error Code 21)
15.1.2.3. NFS4ERR_ISDIR(错误代码21)

The current or saved filehandle designates a directory when the current operation does not allow a directory to be accepted as the target of this operation.

当当前操作不允许接受目录作为此操作的目标时,当前或保存的文件句柄将指定一个目录。

15.1.2.4. NFS4ERR_MOVED (Error Code 10019)
15.1.2.4. NFS4ERR_已移动(错误代码10019)

The file system that contains the current filehandle object is not present at the server. It may have been relocated or migrated to another server, or it may have never been present. The client may obtain the new file system location by obtaining the "fs_locations" or "fs_locations_info" attribute for the current filehandle. For further discussion, refer to Section 11.2.

服务器上不存在包含当前filehandle对象的文件系统。它可能已重新定位或迁移到另一台服务器,也可能从未出现过。客户端可以通过获取当前文件句柄的“fs\u locations”或“fs\u locations\u info”属性来获取新的文件系统位置。有关进一步讨论,请参阅第11.2节。

15.1.2.5. NFS4ERR_NOFILEHANDLE (Error Code 10020)
15.1.2.5. NFS4ERR_NOFILEHANDLE(错误代码10020)

The logical current or saved filehandle value is required by the current operation and is not set. 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).

当前操作需要逻辑当前或保存的filehandle值,未设置该值。这可能是由于复合操作的格式错误(即,在需要设置当前文件句柄的操作之前没有PUTFH或PUTROOTFH)。

15.1.2.6. NFS4ERR_NOTDIR (Error Code 20)
15.1.2.6. NFS4ERR_NOTDIR(错误代码20)

The current (or saved) filehandle designates an object that is not a directory for an operation in which a directory is required.

当前(或保存的)文件句柄指定的对象不是需要目录的操作的目录。

15.1.2.7. NFS4ERR_STALE (Error Code 70)
15.1.2.7. NFS4ERR_STALE(错误代码70)

The current or saved filehandle value designating an argument to the current operation is invalid. The file referred to by that filehandle no longer exists or access to it has been revoked.

指定当前操作参数的当前或保存的filehandle值无效。该文件句柄引用的文件不再存在,或者对该文件的访问已被撤销。

15.1.2.8. NFS4ERR_SYMLINK (Error Code 10029)
15.1.2.8. NFS4ERR_符号链接(错误代码10029)

The current filehandle designates a symbolic link when the current operation does not allow a symbolic link as the target.

当当前操作不允许将符号链接作为目标时,当前文件句柄指定符号链接。

15.1.2.9. NFS4ERR_WRONG_TYPE (Error Code 10083)
15.1.2.9. NFS4ERR_错误_类型(错误代码10083)

The current (or saved) filehandle designates an object that is of an invalid type for the current operation, and there is no more specific error (such as NFS4ERR_ISDIR or NFS4ERR_SYMLINK) that applies. Note that in NFSv4.0, such situations generally resulted in the less-specific error NFS4ERR_INVAL.

当前(或保存的)文件句柄为当前操作指定了无效类型的对象,并且没有适用的更具体错误(如NFS4ERR_ISDIR或NFS4ERR_SYMLINK)。注意,在NFSv4.0中,这种情况通常会导致不太具体的错误NFS4ERR_INVAL。

15.1.3. Compound Structure Errors
15.1.3. 复合结构错误

This section deals with errors that relate to the overall structure of a Compound request (by which we mean to include both COMPOUND and CB_COMPOUND), rather than to particular operations.

本节讨论与复合请求的整体结构(我们的意思是同时包括复合和CB_复合)相关的错误,而不是与特定操作相关的错误。

There are a number of basic constraints on the operations that may appear in a Compound request. Sessions add to these basic constraints by requiring a Sequence operation (either SEQUENCE or CB_SEQUENCE) at the start of the Compound.

复合请求中可能出现的操作有许多基本约束。会话通过在化合物的开始处要求序列操作(序列或CB_序列)来增加这些基本约束。

15.1.3.1. NFS_OK (Error code 0)
15.1.3.1. NFS\u正常(错误代码0)

Indicates the operation completed successfully, in that all of the constituent operations completed without error.

指示操作已成功完成,因为所有组成操作均已完成且无错误。

15.1.3.2. NFS4ERR_MINOR_VERS_MISMATCH (Error code 10021)
15.1.3.2. NFS4ERR_MINOR_VERS_不匹配(错误代码10021)

The minor version specified is not one that the current listener supports. This value is returned in the overall status for the Compound but is not associated with a specific operation since the results will specify a result count of zero.

指定的次要版本不是当前侦听器支持的版本。该值以化合物的整体状态返回,但与特定操作无关,因为结果将指定结果计数为零。

15.1.3.3. NFS4ERR_NOT_ONLY_OP (Error Code 10081)
15.1.3.3. NFS4ERR_NOT_ONLY_OP(错误代码10081)

Certain operations, which are allowed to be executed outside of a session, MUST be the only operation within a Compound whenever the Compound does not start with a Sequence operation. This error results when that constraint is not met.

某些允许在会话之外执行的操作必须是复合内的唯一操作,只要该复合不以序列操作开始。如果不满足该约束,则会导致此错误。

15.1.3.4. NFS4ERR_OP_ILLEGAL (Error Code 10044)
15.1.3.4. NFS4ERR_OP_非法(错误代码10044)

The operation code is not a valid one for the current Compound procedure. The opcode in the result stream matched with this error is the ILLEGAL value, although the value that appears in the request stream may be different. Where an illegal value appears and the replier pre-parses all operations for a Compound procedure before doing any operation execution, an RPC-level XDR error may be returned.

操作代码不是当前复合过程的有效代码。与此错误匹配的结果流中的操作码是非法值,尽管请求流中出现的值可能不同。如果出现非法值,并且应答器在执行任何操作之前预解析复合过程的所有操作,则可能会返回RPC级别的XDR错误。

15.1.3.5. NFS4ERR_OP_NOT_IN_SESSION (Error Code 10071)
15.1.3.5. NFS4ERR_OP_NOT_IN_SESSION(错误代码10071)

Most forward operations and all callback operations are only valid within the context of a session, so that the Compound request in question MUST begin with a Sequence operation. If an attempt is made to execute these operations outside the context of session, this error results.

大多数转发操作和所有回调操作仅在会话上下文中有效,因此所讨论的复合请求必须以序列操作开始。如果试图在会话上下文之外执行这些操作,则会导致此错误。

15.1.3.6. NFS4ERR_REP_TOO_BIG (Error Code 10066)
15.1.3.6. NFS4ERR_REP_过大(错误代码10066)

The reply to a Compound would exceed the channel's negotiated maximum response size.

对化合物的回复将超过通道协商的最大响应大小。

15.1.3.7. NFS4ERR_REP_TOO_BIG_TO_CACHE (Error Code 10067)
15.1.3.7. NFS4ERR_REP_TOO_BIG_TO_CACHE(错误代码10067)

The reply to a Compound would exceed the channel's negotiated maximum size for replies cached in the reply cache when the Sequence for the current request specifies that this request is to be cached.

当当前请求的序列指定要缓存此请求时,对复合的回复将超过通道协商的回复缓存中缓存的回复的最大大小。

15.1.3.8. NFS4ERR_REQ_TOO_BIG (Error Code 10065)
15.1.3.8. NFS4ERR_REQ_过大(错误代码10065)

The Compound request exceeds the channel's negotiated maximum size for requests.

复合请求超过了通道协商的最大请求大小。

15.1.3.9. NFS4ERR_RETRY_UNCACHED_REP (Error Code 10068)
15.1.3.9. NFS4ERR_RETRY_UNCACHED_REP(错误代码10068)

The requester has attempted a retry of a Compound that it previously requested not be placed in the reply cache.

请求者已尝试重试其先前请求的化合物,但该化合物未放置在应答缓存中。

15.1.3.10. NFS4ERR_SEQUENCE_POS (Error Code 10064)
15.1.3.10. NFS4ERR_SEQUENCE_POS(错误代码10064)

A Sequence operation appeared in a position other than the first operation of a Compound request.

序列操作出现在复合请求的第一个操作以外的位置。

15.1.3.11. NFS4ERR_TOO_MANY_OPS (Error Code 10070)
15.1.3.11. NFS4ERR\u过多操作(错误代码10070)

The Compound request has too many operations, exceeding the count negotiated when the session was created.

复合请求的操作太多,超过了创建会话时协商的计数。

15.1.3.12. NFS4ERR_UNSAFE_COMPOUND (Error Code 10068)
15.1.3.12. NFS4ERR_不安全化合物(错误代码10068)

The client has sent a COMPOUND request with an unsafe mix of operations -- specifically, with a non-idempotent operation that changes the current filehandle and that is not followed by a GETFH.

客户机发送了一个复合请求,其中包含不安全的操作组合——具体来说,是一个非幂等操作,该操作更改了当前文件句柄,并且后面没有GETFH。

15.1.4. File System Errors
15.1.4. 文件系统错误

These errors describe situations that occurred in the underlying file system implementation rather than in the protocol or any NFSv4.x feature.

这些错误描述了在底层文件系统实现中发生的情况,而不是在协议或任何NFSv4.x功能中发生的情况。

15.1.4.1. NFS4ERR_BADTYPE (Error Code 10007)
15.1.4.1. NFS4ERR_BADTYPE(错误代码10007)

An attempt was made to create an object with an inappropriate type specified to CREATE. This may be because the type is undefined, because the type is not supported by the server, or because the type is not intended to be created by CREATE (such as a regular file or named attribute, for which OPEN is used to do the file creation).

试图使用指定要创建的不适当类型创建对象。这可能是因为类型未定义,服务器不支持该类型,或者因为该类型不是由CREATE创建的(例如常规文件或命名属性,OPEN用于创建文件)。

15.1.4.2. NFS4ERR_DQUOT (Error Code 19)
15.1.4.2. NFS4ERR_DQUOT(错误代码19)

Resource (quota) hard limit exceeded. The user's resource limit on the server has been exceeded.

超出了资源(配额)硬限制。已超过服务器上用户的资源限制。

15.1.4.3. NFS4ERR_EXIST (Error Code 17)
15.1.4.3. NFS4ERR_存在(错误代码17)

A file of the specified target name (when creating, renaming, or linking) already exists.

指定目标名称的文件(在创建、重命名或链接时)已存在。

15.1.4.4. NFS4ERR_FBIG (Error Code 27)
15.1.4.4. NFS4ERR_FBIG(错误代码27)

The file is too large. The operation would have caused the file to grow beyond the server's limit.

文件太大了。该操作会导致文件增长超过服务器的限制。

15.1.4.5. NFS4ERR_FILE_OPEN (Error Code 10046)
15.1.4.5. NFS4ERR_文件_打开(错误代码10046)

The operation is not allowed because a file involved in the operation is currently open. Servers may, but are not required to, disallow linking-to, removing, or renaming open files.

不允许该操作,因为该操作涉及的文件当前处于打开状态。服务器可以(但不是必须)禁止链接、删除或重命名打开的文件。

15.1.4.6. NFS4ERR_IO (Error Code 5)
15.1.4.6. NFS4ERR_IO(错误代码5)

Indicates that an I/O error occurred for which the file system was unable to provide recovery.

指示发生I/O错误,文件系统无法为其提供恢复。

15.1.4.7. NFS4ERR_MLINK (Error Code 31)
15.1.4.7. NFS4ERR_MLINK(错误代码31)

The request would have caused the server's limit for the number of hard links a file may have to be exceeded.

该请求可能会导致服务器对文件硬链接数量的限制被超过。

15.1.4.8. NFS4ERR_NOENT (Error Code 2)
15.1.4.8. NFS4ERR\u NOENT(错误代码2)

Indicates no such file or directory. The file or directory name specified does not exist.

表示没有这样的文件或目录。指定的文件或目录名不存在。

15.1.4.9. NFS4ERR_NOSPC (Error Code 28)
15.1.4.9. NFS4ERR_NOSPC(错误代码28)

Indicates there is no space left on the device. The operation would have caused the server's file system to exceed its limit.

表示设备上没有剩余空间。该操作将导致服务器的文件系统超出其限制。

15.1.4.10. NFS4ERR_NOTEMPTY (Error Code 66)
15.1.4.10. NFS4ERR_NOTEMPTY(错误代码66)

An attempt was made to remove a directory that was not empty.

试图删除一个非空目录。

15.1.4.11. NFS4ERR_ROFS (Error Code 30)
15.1.4.11. NFS4ERR_ROFS(错误代码30)

Indicates a read-only file system. A modifying operation was attempted on a read-only file system.

表示只读文件系统。试图在只读文件系统上执行修改操作。

15.1.4.12. NFS4ERR_XDEV (Error Code 18)
15.1.4.12. NFS4ERR_XDEV(错误代码18)

Indicates an attempt to do an operation, such as linking, that inappropriately crosses a boundary. This may be due to such boundaries as:

表示试图执行不适当跨越边界的操作(如链接)。这可能是由于以下边界造成的:

o that between file systems (where the fsids are different).

o 文件系统之间的差异(其中fsid不同)。

o that between different named attribute directories or between a named attribute directory and an ordinary directory.

o 不同命名属性目录之间或命名属性目录与普通目录之间的。

o that between byte-ranges of a file system that the file system implementation treats as separate (for example, for space accounting purposes), and where cross-connection between the byte-ranges are not allowed.

o 文件系统实现视为单独的文件系统字节范围之间的连接(例如,出于空间计算目的),以及不允许字节范围之间的交叉连接。

15.1.5. State Management Errors
15.1.5. 状态管理错误

These errors indicate problems with the stateid (or one of the stateids) passed to a given operation. This includes situations in which the stateid is invalid as well as situations in which the stateid is valid but designates locking state that has been revoked. Depending on the operation, the stateid when valid may designate opens, byte-range locks, file or directory delegations, layouts, or device maps.

这些错误表示传递给给定操作的stateid(或其中一个stateid)存在问题。这包括stateid无效的情况,以及stateid有效但指定已撤销的锁定状态的情况。根据操作的不同,stateid(如果有效)可以指定打开、字节范围锁、文件或目录委派、布局或设备映射。

15.1.5.1. NFS4ERR_ADMIN_REVOKED (Error Code 10047)
15.1.5.1. NFS4ERR_ADMIN_已撤销(错误代码10047)

A stateid designates locking state of any type that has been revoked due to administrative interaction, possibly while the lease is valid.

stateid指定由于管理交互而被撤销的任何类型的锁定状态,可能是在租约有效期间。

15.1.5.2. NFS4ERR_BAD_STATEID (Error Code 10026)
15.1.5.2. NFS4ERR_BAD_STATEID(错误代码10026)

A stateid does not properly designate any valid state. See Sections 8.2.4 and 8.2.3 for a discussion of how stateids are validated.

stateid不能正确指定任何有效状态。有关如何验证StateID的讨论,请参见第8.2.4节和第8.2.3节。

15.1.5.3. NFS4ERR_DELEG_REVOKED (Error Code 10087)
15.1.5.3. NFS4ERR_DELEG_撤销(错误代码10087)

A stateid designates recallable locking state of any type (delegation or layout) that has been revoked due to the failure of the client to return the lock when it was recalled.

stateid指定任何类型(委托或布局)的可重新调用锁定状态,该状态由于客户端在调用锁时未能返回锁而被撤销。

15.1.5.4. NFS4ERR_EXPIRED (Error Code 10011)
15.1.5.4. NFS4ERR_已过期(错误代码10011)

A stateid designates locking state of any type that has been revoked due to expiration of the client's lease, either immediately upon lease expiration, or following a later request for a conflicting lock.

stateid指定任何类型的锁定状态,该锁定状态由于客户端租约到期而被撤销,可以是在租约到期后立即撤销,也可以是在稍后请求冲突的锁之后撤销。

15.1.5.5. NFS4ERR_OLD_STATEID (Error Code 10024)
15.1.5.5. NFS4ERR_OLD_STATEID(错误代码10024)

A stateid with a non-zero seqid value does match the current seqid for the state designated by the user.

seqid值非零的stateid与用户指定状态的当前seqid不匹配。

15.1.6. Security Errors
15.1.6. 安全错误

These are the various permission-related errors in NFSv4.1.

这些是NFSv4.1中与权限相关的各种错误。

15.1.6.1. NFS4ERR_ACCESS (Error Code 13)
15.1.6.1. NFS4ERR_访问(错误代码13)

Indicates permission denied. The caller does not have the correct permission to perform the requested operation. Contrast this with NFS4ERR_PERM (Section 15.1.6.2), which restricts itself to owner or privileged-user permission failures, and NFS4ERR_WRONG_CRED (Section 15.1.6.4), which deals with appropriate permission to delete or modify transient objects based on the credentials of the user that created them.

表示权限被拒绝。调用方没有执行请求的操作的正确权限。与此形成对比的是NFS4ERR_PERM(第15.1.6.2节),它将自身限制为所有者或特权用户权限失败,以及NFS4ERR_Error_CRED(第15.1.6.4节),它处理根据创建临时对象的用户的凭据删除或修改临时对象的适当权限。

15.1.6.2. NFS4ERR_PERM (Error Code 1)
15.1.6.2. NFS4ERR_PERM(错误代码1)

Indicates requester is not the owner. The operation was not allowed because the caller is neither a privileged user (root) nor the owner of the target of the operation.

指示请求者不是所有者。不允许该操作,因为调用方既不是特权用户(根用户),也不是操作目标的所有者。

15.1.6.3. NFS4ERR_WRONGSEC (Error Code 10016)
15.1.6.3. NFS4ERR_错误秒(错误代码10016)

Indicates that 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 re-send the operation (but not with the same slot ID and sequence ID; one or both MUST be different on the re-send). SECINFO and SECINFO_NO_NAME can be used to determine the appropriate mechanism.

指示客户端用于操作的安全机制与服务器的安全策略不匹配。客户端应更改正在使用的安全机制并重新发送操作(但不能使用相同的插槽ID和序列ID;在重新发送时其中一个或两个必须不同)。SECINFO和SECINFO_NO_名称可用于确定适当的机制。

15.1.6.4. NFS4ERR_WRONG_CRED (Error Code 10082)
15.1.6.4. NFS4ERR\u Error\u CRED(错误代码10082)

An operation that manipulates state was attempted by a principal that was not allowed to modify that piece of state.

主体尝试了操纵状态的操作,但该主体不允许修改该状态。

15.1.7. Name Errors
15.1.7. 名称错误

Names in NFSv4 are UTF-8 strings. When the strings are not valid UTF-8 or are of length zero, the error NFS4ERR_INVAL results. Besides this, there are a number of other errors to indicate specific problems with names.

NFSv4中的名称是UTF-8字符串。当字符串无效UTF-8或长度为零时,将产生错误NFS4ERR_INVAL。除此之外,还有许多其他错误表明名称存在特定问题。

15.1.7.1. NFS4ERR_BADCHAR (Error Code 10040)
15.1.7.1. NFS4ERR_BADCHAR(错误代码10040)

A UTF-8 string contains a character that is not supported by the server in the context in which it being used.

UTF-8字符串包含服务器在其使用的上下文中不支持的字符。

15.1.7.2. NFS4ERR_BADNAME (Error Code 10041)
15.1.7.2. NFS4ERR_BADNAME(错误代码10041)

A name string in a request consisted of valid UTF-8 characters supported by the server, but the name is not supported by the server as a valid name for the current operation. An example might be creating a file or directory named ".." on a server whose file system uses that name for links to parent directories.

请求中的名称字符串由服务器支持的有效UTF-8字符组成,但服务器不支持该名称作为当前操作的有效名称。例如,在服务器上创建名为“.”的文件或目录,其文件系统使用该名称链接到父目录。

15.1.7.3. NFS4ERR_NAMETOOLONG (Error Code 63)
15.1.7.3. NFS4ERR_NAMETOOLONG(错误代码63)

Returned when the filename in an operation exceeds the server's implementation limit.

当操作中的文件名超过服务器的实现限制时返回。

15.1.8. Locking Errors
15.1.8. 锁定错误

This section deals with errors related to locking, both as to share reservations and byte-range locking. It does not deal with errors specific to the process of reclaiming locks. Those are dealt with in Section 15.1.9.

本节讨论与锁定相关的错误,包括共享保留和字节范围锁定。它不处理特定于回收锁过程的错误。这些在第15.1.9节中讨论。

15.1.8.1. NFS4ERR_BAD_RANGE (Error Code 10042)
15.1.8.1. NFS4ERR_BAD_范围(错误代码10042)

The byte-range of a LOCK, LOCKT, or LOCKU operation is not allowed by the server. For example, this error results when a server that only supports 32-bit ranges receives a range that cannot be handled by that server. (See Section 18.10.3.)

服务器不允许锁定、锁定或锁定操作的字节范围。例如,当仅支持32位范围的服务器接收到该服务器无法处理的范围时,会出现此错误。(见第18.10.3节。)

15.1.8.2. NFS4ERR_DEADLOCK (Error Code 10045)
15.1.8.2. NFS4ERR_死锁(错误代码10045)

The server has been able to determine a byte-range locking deadlock condition for a READW_LT or WRITEW_LT LOCK operation.

服务器已经能够确定READW_LT或WRITEW_LT锁定操作的字节范围锁定死锁条件。

15.1.8.3. NFS4ERR_DENIED (Error Code 10010)
15.1.8.3. NFS4ERR_被拒绝(错误代码10010)

An attempt to lock a file is denied. Since this may be a temporary condition, the client is encouraged to re-send the lock request (but not with the same slot ID and sequence ID; one or both MUST be different on the re-send) until the lock is accepted. See Section 9.6 for a discussion of the re-send.

锁定文件的尝试被拒绝。由于这可能是一种临时情况,因此鼓励客户机重新发送锁请求(但不能使用相同的插槽ID和序列ID;在重新发送时其中一个或两个必须不同),直到锁被接受为止。有关重新发送的讨论,请参见第9.6节。

15.1.8.4. NFS4ERR_LOCKED (Error Code 10012)
15.1.8.4. NFS4ERR_锁定(错误代码10012)

A READ or WRITE operation was attempted on a file where there was a conflict between the I/O and an existing lock:

尝试对I/O和现有锁之间存在冲突的文件执行读或写操作:

o There is a share reservation inconsistent with the I/O being done.

o 存在与正在执行的I/O不一致的共享保留。

o The range to be read or written intersects an existing mandatory byte-range lock.

o 要读取或写入的范围与现有的强制字节范围锁相交。

15.1.8.5. NFS4ERR_LOCKS_HELD (Error Code 10037)
15.1.8.5. NFS4ERR_锁定保持(错误代码10037)

An operation was prevented by the unexpected presence of locks.

由于意外出现锁,操作被阻止。

15.1.8.6. NFS4ERR_LOCK_NOTSUPP (Error Code 10043)
15.1.8.6. NFS4ERR\u LOCK\u NOTSUPP(错误代码10043)

A LOCK operation was attempted that would require the upgrade or downgrade of a byte-range lock range already held by the owner, and the server does not support atomic upgrade or downgrade of locks.

尝试的锁定操作要求升级或降级所有者已持有的字节范围锁定范围,并且服务器不支持锁的原子升级或降级。

15.1.8.7. NFS4ERR_LOCK_RANGE (Error Code 10028)
15.1.8.7. NFS4ERR\U LOCK\U范围(错误代码10028)

A LOCK operation is operating on a range that overlaps in part a currently held byte-range lock for the current lock-owner and does not precisely match a single such byte-range lock where the server does not support this type of request, and thus does not implement

锁定操作在一个范围上运行,该范围与当前锁所有者当前持有的字节范围锁部分重叠,并且与服务器不支持此类请求的单个字节范围锁不精确匹配,因此无法实现

POSIX locking semantics [24]. See Sections 18.10.4, 18.11.4, and 18.12.4 for a discussion of how this applies to LOCK, LOCKT, and LOCKU respectively.

POSIX锁定语义[24]。请参见第18.10.4节、第18.11.4节和第18.12.4节,以了解这如何分别适用于LOCK、LOCKT和LOCKU。

15.1.8.8. NFS4ERR_OPENMODE (Error Code 10038)
15.1.8.8. NFS4ERR_OPENMODE(错误代码10038)

The client attempted a READ, WRITE, LOCK, or other operation not sanctioned by the stateid passed (e.g., writing to a file opened for read-only access).

客户端尝试了读取、写入、锁定或其他未经传递的stateid批准的操作(例如,写入为只读访问而打开的文件)。

15.1.8.9. NFS4ERR_SHARE_DENIED (Error Code 10015)
15.1.8.9. NFS4ERR_SHARE_被拒绝(错误代码10015)

An attempt to OPEN a file with a share reservation has failed because of a share conflict.

由于共享冲突,尝试打开具有共享保留的文件失败。

15.1.9. Reclaim Errors
15.1.9. 收回错误

These errors relate to the process of reclaiming locks after a server restart.

这些错误与服务器重新启动后回收锁的过程有关。

15.1.9.1. NFS4ERR_COMPLETE_ALREADY (Error Code 10054)
15.1.9.1. NFS4ERR_已完成(错误代码10054)

The client previously sent a successful RECLAIM_COMPLETE operation. An additional RECLAIM_COMPLETE operation is not necessary and results in this error.

客户端以前发送了一个成功的回收完成操作。不需要额外的回收完成操作,因此会导致此错误。

15.1.9.2. NFS4ERR_GRACE (Error Code 10013)
15.1.9.2. NFS4ERR_GRACE(错误代码10013)

The server was in its recovery or grace period. The locking request was not a reclaim request and so could not be granted during that period.

服务器处于恢复或宽限期。锁定请求不是回收请求,因此在此期间无法授予。

15.1.9.3. NFS4ERR_NO_GRACE (Error Code 10033)
15.1.9.3. NFS4ERR_NO_GRACE(错误代码10033)

A reclaim of client state was attempted in circumstances in which the server cannot guarantee that conflicting state has not been provided to another client. This can occur because the reclaim has been done outside of the grace period of the server, after the client has done a RECLAIM_COMPLETE operation, or because previous operations have created a situation in which the server is not able to determine that a reclaim-interfering edge condition does not exist.

在服务器无法保证未向其他客户端提供冲突状态的情况下,尝试回收客户端状态。这可能是因为在服务器的宽限期之外进行了回收,在客户端完成了回收操作之后,或者是因为以前的操作造成了服务器无法确定回收干扰边缘条件不存在的情况。

15.1.9.4. NFS4ERR_RECLAIM_BAD (Error Code 10034)
15.1.9.4. NFS4ERR_receive_BAD(错误代码10034)

The server has determined that a reclaim attempted by the client is not valid, i.e. the lock specified as being reclaimed could not possibly have existed before the server restart. A server is not obliged to make this determination and will typically rely on the

服务器已确定客户端尝试的回收无效,即在服务器重新启动之前,指定为回收的锁不可能存在。服务器没有义务做出此决定,通常会依赖

client to only reclaim locks that the client was granted prior to restart. However, when a server does have reliable information to enable it make this determination, this error indicates that the reclaim has been rejected as invalid. This is as opposed to the error NFS4ERR_RECLAIM_CONFLICT (see Section 15.1.9.5) where the server can only determine that there has been an invalid reclaim, but cannot determine which request is invalid.

客户端仅回收在重新启动之前授予客户端的锁。但是,当服务器确实有可靠信息使其能够进行此确定时,此错误表示回收已被拒绝为无效。这与错误NFS4ERR_reclain_CONFLICT(参见第15.1.9.5节)相反,在该错误中,服务器只能确定存在无效的回收,但无法确定哪个请求无效。

15.1.9.5. NFS4ERR_RECLAIM_CONFLICT (Error Code 10035)
15.1.9.5. NFS4ERR_回收_冲突(错误代码10035)

The reclaim attempted by the client has encountered a conflict and cannot be satisfied. Potentially indicates a misbehaving client, although not necessarily the one receiving the error. The misbehavior might be on the part of the client that established the lock with which this client conflicted. See also Section 15.1.9.4 for the related error, NFS4ERR_RECLAIM_BAD.

客户端尝试的回收遇到冲突,无法满足。可能表示客户端行为不正常,但不一定是接收错误的客户端。该错误行为可能是由建立与该客户端冲突的锁的客户端造成的。有关相关错误,请参见第15.1.9.4节,NFS4ERR_receive_BAD。

15.1.10. pNFS Errors
15.1.10. pNFS错误

This section deals with pNFS-related errors including those that are associated with using NFSv4.1 to communicate with a data server.

本节讨论与pNFS相关的错误,包括与使用NFSv4.1与数据服务器通信相关的错误。

15.1.10.1. NFS4ERR_BADIOMODE (Error Code 10049)
15.1.10.1. NFS4ERR_BADIOMODE(错误代码10049)

An invalid or inappropriate layout iomode was specified. For example an inappropriate layout iomode, suppose a client's LAYOUTGET operation specified an iomode of LAYOUTIOMODE4_RW, and the server is neither able nor willing to let the client send write requests to data servers; the server can reply with NFS4ERR_BADIOMODE. The client would then send another LAYOUTGET with an iomode of LAYOUTIOMODE4_READ.

指定的布局iomode无效或不正确。例如,不适当的布局iomode,假设客户端的LAYOUTGET操作指定了LAYOUTIOMODE4_RW的iomode,并且服务器既不能也不愿意让客户端向数据服务器发送写请求;服务器可以使用NFS4ERR_BADIOMODE进行回复。然后,客户端将发送另一个LAYOUTGET,其iomode为LAYOUTIOMODE4\u READ。

15.1.10.2. NFS4ERR_BADLAYOUT (Error Code 10050)
15.1.10.2. NFS4ERR_BADLAYOUT(错误代码10050)

The layout specified is invalid in some way. For LAYOUTCOMMIT, this indicates that the specified layout is not held by the client or is not of mode LAYOUTIOMODE4_RW. For LAYOUTGET, it indicates that a layout matching the client's specification as to minimum length cannot be granted.

指定的布局在某些方面无效。对于LAYOUTCOMMIT,这表示指定的布局不是由客户端持有的,或者不是LAYOUTIOMODE4\u RW模式。对于LAYOUTGET,它表示无法授予与客户端的最小长度规格匹配的布局。

15.1.10.3. NFS4ERR_LAYOUTTRYLATER (Error Code 10058)
15.1.10.3. NFS4ERR_Layouttylater(错误代码10058)

Layouts are temporarily unavailable for the file. The client should re-send later (but not with the same slot ID and sequence ID; one or both MUST be different on the re-send).

布局暂时不可用于该文件。客户端应稍后重新发送(但不能使用相同的插槽ID和序列ID;重新发送时必须有一个或两个不同)。

15.1.10.4. NFS4ERR_LAYOUTUNAVAILABLE (Error Code 10059)
15.1.10.4. NFS4ERR_布局不可用(错误代码10059)

Returned when layouts are not available for the current file system or the particular specified file.

当布局不适用于当前文件系统或特定指定文件时返回。

15.1.10.5. NFS4ERR_NOMATCHING_LAYOUT (Error Code 10060)
15.1.10.5. NFS4ERR_NOMATCHING_布局(错误代码10060)

Returned when layouts are recalled and the client has no layouts matching the specification of the layouts being recalled.

当调用布局且客户端没有与被调用布局规格匹配的布局时返回。

15.1.10.6. NFS4ERR_PNFS_IO_HOLE (Error Code 10075)
15.1.10.6. NFS4ERR_PNFS_IO_孔(错误代码10075)

The pNFS client has attempted to read from or write to an illegal hole of a file of a data server that is using sparse packing. See Section 13.4.4.

pNFS客户端试图读取或写入正在使用稀疏打包的数据服务器文件的非法漏洞。见第13.4.4节。

15.1.10.7. NFS4ERR_PNFS_NO_LAYOUT (Error Code 10080)
15.1.10.7. NFS4ERR_PNFS_NO_布局(错误代码10080)

The pNFS client has attempted to read from or write to a file (using a request to a data server) without holding a valid layout. This includes the case where the client had a layout, but the iomode does not allow a WRITE.

pNFS客户端试图读取或写入文件(使用对数据服务器的请求),但未保留有效布局。这包括客户端具有布局,但iomode不允许写入的情况。

15.1.10.8. NFS4ERR_RETURNCONFLICT (Error Code 10086)
15.1.10.8. NFS4ERR_返回冲突(错误代码10086)

A layout is unavailable due to an attempt to perform the LAYOUTGET before a pending LAYOUTRETURN on the file has been received. See Section 12.5.5.2.1.3.

由于在收到文件上挂起的LAYOUTRETURN之前尝试执行LAYOUTGET,布局不可用。见第12.5.5.2.1.3节。

15.1.10.9. NFS4ERR_UNKNOWN_LAYOUTTYPE (Error Code 10062)
15.1.10.9. NFS4ERR_未知_布局类型(错误代码10062)

The client has specified a layout type that is not supported by the server.

客户端指定了服务器不支持的布局类型。

15.1.11. Session Use Errors
15.1.11. 会话使用错误

This section deals with errors encountered when using sessions, that is, errors encountered when a request uses a Sequence (i.e., either SEQUENCE or CB_SEQUENCE) operation.

本节讨论使用会话时遇到的错误,即请求使用序列(即序列或CB_序列)操作时遇到的错误。

15.1.11.1. NFS4ERR_BADSESSION (Error Code 10052)
15.1.11.1. NFS4ERR_BADSESSION(错误代码10052)

The specified session ID is unknown to the server to which the operation is addressed.

指定的会话ID对于操作所针对的服务器是未知的。

15.1.11.2. NFS4ERR_BADSLOT (Error Code 10053)
15.1.11.2. NFS4ERR_坏插槽(错误代码10053)

The requester sent a Sequence operation that attempted to use a slot the replier does not have in its slot table. It is possible the slot may have been retired.

请求者发送了一个序列操作,该操作试图使用应答器的插槽表中没有的插槽。该插槽可能已停用。

15.1.11.3. NFS4ERR_BAD_HIGH_SLOT (Error Code 10077)
15.1.11.3. NFS4ERR\U坏\U高\U插槽(错误代码10077)

The highest_slot argument in a Sequence operation exceeds the replier's enforced highest_slotid.

序列操作中的最高\u slot参数超过了应答器强制的最高\u slotid。

15.1.11.4. NFS4ERR_CB_PATH_DOWN (Error Code 10048)
15.1.11.4. NFS4ERR_CB_PATH_DOWN(错误代码10048)

There is a problem contacting the client via the callback path. The function of this error has been mostly superseded by the use of status flags in the reply to the SEQUENCE operation (see Section 18.46).

通过回调路径与客户端联系时出现问题。此错误的功能主要已被序列操作回复中使用的状态标志所取代(见第18.46节)。

15.1.11.5. NFS4ERR_DEADSESSION (Error Code 10078)
15.1.11.5. NFS4ERR_DEADSESSION(错误代码10078)

The specified session is a persistent session that is dead and does not accept new requests or perform new operations on existing requests (in the case in which a request was partially executed before server restart).

指定的会话是一个永久性会话,它是死会话,不接受新请求或对现有请求执行新操作(在服务器重新启动之前部分执行了请求的情况下)。

15.1.11.6. NFS4ERR_CONN_NOT_BOUND_TO_SESSION (Error Code 10055)
15.1.11.6. NFS4ERR\u CONN\u未绑定到会话(错误代码10055)

A Sequence operation was sent on a connection that has not been associated with the specified session, where the client specified that connection association was to be enforced with SP4_MACH_CRED or SP4_SSV state protection.

在未与指定会话关联的连接上发送了序列操作,其中客户端指定要使用SP4_MACH_CRED或SP4_SSV状态保护强制连接关联。

15.1.11.7. NFS4ERR_SEQ_FALSE_RETRY (Error Code 10076)
15.1.11.7. NFS4ERR_SEQ_FALSE_重试(错误代码10076)

The requester sent a Sequence operation with a slot ID and sequence ID that are in the reply cache, but the replier has detected that the retried request is not the same as the original request. See Section 2.10.6.1.3.1.

请求者发送了一个序列操作,其插槽ID和序列ID位于应答缓存中,但应答者检测到重试的请求与原始请求不同。见第2.10.6.1.3.1节。

15.1.11.8. NFS4ERR_SEQ_MISORDERED (Error Code 10063)
15.1.11.8. NFS4ERR_SEQ_排序错误(错误代码10063)

The requester sent a Sequence operation with an invalid sequence ID.

请求者发送了序列ID无效的序列操作。

15.1.12. Session Management Errors
15.1.12. 会话管理错误

This section deals with errors associated with requests used in session management.

本节讨论与会话管理中使用的请求相关的错误。

15.1.12.1. NFS4ERR_BACK_CHAN_BUSY (Error Code 10057)
15.1.12.1. NFS4ERR_BACK_CHAN_BUSY(错误代码10057)

An attempt was made to destroy a session when the session cannot be destroyed because the server has callback requests outstanding.

由于服务器有未完成的回调请求,无法销毁会话时,尝试销毁会话。

15.1.12.2. NFS4ERR_BAD_SESSION_DIGEST (Error Code 10051)
15.1.12.2. NFS4ERR_BAD_SESSION_摘要(错误代码10051)

The digest used in a SET_SSV request is not valid.

SET_SSV请求中使用的摘要无效。

15.1.13. Client Management Errors
15.1.13. 客户端管理错误

This section deals with errors associated with requests used to create and manage client IDs.

本节讨论与用于创建和管理客户端ID的请求相关的错误。

15.1.13.1. NFS4ERR_CLIENTID_BUSY (Error Code 10074)
15.1.13.1. NFS4ERR_CLIENTID_BUSY(错误代码10074)

The DESTROY_CLIENTID operation has found there are sessions and/or unexpired state associated with the client ID to be destroyed.

DESTROY_CLIENTID操作发现与要销毁的客户端ID关联的会话和/或未过期状态。

15.1.13.2. NFS4ERR_CLID_INUSE (Error Code 10017)
15.1.13.2. NFS4ERR_CLID_INUSE(错误代码10017)

While processing an EXCHANGE_ID operation, the server was presented with a co_ownerid field that matches an existing client with valid leased state, but the principal sending the EXCHANGE_ID operation differs from the principal that established the existing client. This indicates a collision (most likely due to chance) between clients. The client should recover by changing the co_ownerid and re-sending EXCHANGE_ID (but not with the same slot ID and sequence ID; one or both MUST be different on the re-send).

在处理EXCHANGE\u ID操作时,向服务器提供了一个co\u ownerid字段,该字段将现有客户端与有效的租用状态相匹配,但发送EXCHANGE\u ID操作的主体与建立现有客户端的主体不同。这表示客户端之间发生冲突(很可能是偶然发生的)。客户端应通过更改co_所有者ID并重新发送EXCHANGE_ID(但不能使用相同的插槽ID和序列ID;重新发送时其中一个或两个必须不同)来恢复。

15.1.13.3. NFS4ERR_ENCR_ALG_UNSUPP (Error Code 10079)
15.1.13.3. NFS4ERR_ENCR_ALG_UNSUPP(错误代码10079)

An EXCHANGE_ID was sent that specified state protection via SSV, and where the set of encryption algorithms presented by the client did not include any supported by the server.

通过SSV发送指定状态保护的EXCHANGE_ID,其中客户端提供的加密算法集不包括服务器支持的任何加密算法。

15.1.13.4. NFS4ERR_HASH_ALG_UNSUPP (Error Code 10072)
15.1.13.4. NFS4ERR_HASH_ALG_UNSUPP(错误代码10072)

An EXCHANGE_ID was sent that specified state protection via SSV, and where the set of hashing algorithms presented by the client did not include any supported by the server.

通过SSV发送指定状态保护的EXCHANGE_ID,其中客户端提供的哈希算法集不包括服务器支持的任何哈希算法。

15.1.13.5. NFS4ERR_STALE_CLIENTID (Error Code 10022)
15.1.13.5. NFS4ERR_STALE_CLIENTID(错误代码10022)

A client ID not recognized by the server was passed to an operation. Note that unlike the case of NFSv4.0, client IDs are not passed explicitly to the server in ordinary locking operations and cannot result in this error. Instead, when there is a server restart, it is

服务器无法识别的客户端ID已传递给操作。请注意,与NFSv4.0的情况不同,在普通锁定操作中,客户端ID不会显式传递给服务器,并且不会导致此错误。相反,当服务器重新启动时,它是

first manifested through an error on the associated session, and the staleness of the client ID is detected when trying to associate a client ID with a new session.

首先通过关联会话上的错误显示,当尝试将客户端ID与新会话关联时,会检测到客户端ID的过期。

15.1.14. Delegation Errors
15.1.14. 委托错误

This section deals with errors associated with requesting and returning delegations.

本节讨论与请求和返回授权相关的错误。

15.1.14.1. NFS4ERR_DELEG_ALREADY_WANTED (Error Code 10056)
15.1.14.1. NFS4ERR_DELEG_已需要(错误代码10056)

The client has requested a delegation when it had already registered that it wants that same delegation.

当客户机已经注册它想要相同的委托时,它已经请求了一个委托。

15.1.14.2. NFS4ERR_DIRDELEG_UNAVAIL (Error Code 10084)
15.1.14.2. NFS4ERR_DIRDELEG_UNAVAIL(错误代码10084)

This error is returned when the server is unable or unwilling to provide a requested directory delegation.

当服务器无法或不愿意提供请求的目录委派时,将返回此错误。

15.1.14.3. NFS4ERR_RECALLCONFLICT (Error Code 10061)
15.1.14.3. NFS4ERR_RECALLCONFLICT(错误代码10061)

A recallable object (i.e., a layout or delegation) is unavailable due to a conflicting recall operation that is currently in progress for that object.

可重新调用的对象(即布局或委派)不可用,因为当前正在对该对象执行冲突的调用操作。

15.1.14.4. NFS4ERR_REJECT_DELEG (Error Code 10085)
15.1.14.4. NFS4ERR_REJECT_DELEG(错误代码10085)

The callback operation invoked to deal with a new delegation has rejected it.

为处理新委派而调用的回调操作已将其拒绝。

15.1.15. Attribute Handling Errors
15.1.15. 属性处理错误

This section deals with errors specific to attribute handling within NFSv4.

本节讨论NFSv4中特定于属性处理的错误。

15.1.15.1. NFS4ERR_ATTRNOTSUPP (Error Code 10032)
15.1.15.1. NFS4ERR_ATTRNOTSUPP(错误代码10032)

An attribute specified is not supported by the server. This error MUST NOT be returned by the GETATTR operation.

服务器不支持指定的属性。GETATTR操作不能返回此错误。

15.1.15.2. NFS4ERR_BADOWNER (Error Code 10039)
15.1.15.2. NFS4ERR_BADOWNER(错误代码10039)

This error is returned when an owner or owner_group attribute value or the who field of an ACE within an ACL attribute value cannot be translated to a local representation.

当无法将ACL属性值中ACE的所有者或所有者组属性值或who字段转换为本地表示形式时,将返回此错误。

15.1.15.3. NFS4ERR_NOT_SAME (Error Code 10027)
15.1.15.3. NFS4ERR_不相同(错误代码10027)

This error is returned by the VERIFY operation to signify that the attributes compared were not the same as those provided in the client's request.

验证操作返回此错误,表示比较的属性与客户端请求中提供的属性不同。

15.1.15.4. NFS4ERR_SAME (Error Code 10009)
15.1.15.4. NFS4ERR_相同(错误代码10009)

This error is returned by the NVERIFY operation to signify that the attributes compared were the same as those provided in the client's request.

NVERIFY操作返回此错误,表示比较的属性与客户端请求中提供的属性相同。

15.1.16. Obsoleted Errors
15.1.16. 过时的错误

These errors MUST NOT be generated by any NFSv4.1 operation. This can be for a number of reasons.

这些错误不得由任何NFSv4.1操作生成。这可能有很多原因。

o The function provided by the error has been superseded by one of the status bits returned by the SEQUENCE operation.

o 错误提供的函数已被序列操作返回的状态位之一所取代。

o The new session structure and associated change in locking have made the error unnecessary.

o 新的会话结构和相关的锁定更改使错误变得不必要。

o There has been a restructuring of some errors for NFSv4.1 that resulted in the elimination of certain errors.

o 对NFSv4.1的某些错误进行了重组,从而消除了某些错误。

15.1.16.1. NFS4ERR_BAD_SEQID (Error Code 10026)
15.1.16.1. NFS4ERR_BAD_SEQID(错误代码10026)

The sequence number (seqid) in a locking request is neither the next expected number or the last number processed. These seqids are ignored in NFSv4.1.

锁定请求中的序列号(seqid)既不是下一个预期的数字,也不是最后处理的数字。NFSv4.1中忽略了这些seqid。

15.1.16.2. NFS4ERR_LEASE_MOVED (Error Code 10031)
15.1.16.2. NFS4ERR_LEASE_MOVED(错误代码10031)

A lease being renewed is associated with a file system that has been migrated to a new server. The error has been superseded by the SEQ4_STATUS_LEASE_MOVED status bit (see Section 18.46).

正在续订的租约与已迁移到新服务器的文件系统相关联。错误已被SEQ4_STATUS_LEASE_MOVED STATUS位取代(见第18.46节)。

15.1.16.3. NFS4ERR_NXIO (Error Code 5)
15.1.16.3. NFS4ERR_NXIO(错误代码5)

I/O error. No such device or address. This error is for errors involving block and character device access, but because NFSv4.1 is not a device-access protocol, this error is not applicable.

I/O错误。没有这样的设备或地址。此错误适用于涉及块和字符设备访问的错误,但由于NFSv4.1不是设备访问协议,因此此错误不适用。

15.1.16.4. NFS4ERR_RESTOREFH (Error Code 10030)
15.1.16.4. NFS4ERR_RESTOREFH(错误代码10030)

The RESTOREFH operation does not have a saved filehandle (identified by SAVEFH) to operate upon. In NFSv4.1, this error has been superseded by NFS4ERR_NOFILEHANDLE.

RESTOREFH操作没有可操作的已保存文件句柄(由SAVEFH标识)。在NFSv4.1中,此错误已被NFS4ERR_NOFILEHANDLE取代。

15.1.16.5. NFS4ERR_STALE_STATEID (Error Code 10023)
15.1.16.5. NFS4ERR_STALE_STATEID(错误代码10023)

A stateid generated by an earlier server instance was used. This error is moot in NFSv4.1 because all operations that take a stateid MUST be preceded by the SEQUENCE operation, and the earlier server instance is detected by the session infrastructure that supports SEQUENCE.

使用了由早期服务器实例生成的stateid。此错误在NFSv4.1中没有意义,因为采用stateid的所有操作都必须在SEQUENCE操作之前,并且支持SEQUENCE的会话基础结构会检测到较早的服务器实例。

15.2. Operations and Their Valid Errors
15.2. 操作及其有效错误

This section contains a table that gives the valid error returns for each protocol operation. The error code NFS4_OK (indicating no error) is not listed but should be understood to be returnable by all operations with two important exceptions:

本节包含一个表,该表给出了每个协议操作的有效错误返回。错误代码NFS4_OK(表示无错误)未列出,但应理解为可由所有操作返回,但有两个重要例外:

o The operations that MUST NOT be implemented: OPEN_CONFIRM, RELEASE_LOCKOWNER, RENEW, SETCLIENTID, and SETCLIENTID_CONFIRM.

o 不能执行的操作:打开\u确认、释放\u锁所有者、续订、SETCLIENTID和SETCLIENTID\u确认。

o The invalid operation: ILLEGAL.

o 无效操作:非法。

Valid Error Returns for Each Protocol Operation

为每个协议操作返回有效的错误

   +----------------------+--------------------------------------------+
   | Operation            | Errors                                     |
   +----------------------+--------------------------------------------+
   | ACCESS               | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED,                 |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | BACKCHANNEL_CTL      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_NOENT, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | BIND_CONN_TO_SESSION | NFS4ERR_BADSESSION, NFS4ERR_BADXDR,        |
   |                      | NFS4ERR_BAD_SESSION_DIGEST,                |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_NOT_ONLY_OP,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | CLOSE                | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_LOCKS_HELD,     |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | COMMIT               | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
        
   +----------------------+--------------------------------------------+
   | Operation            | Errors                                     |
   +----------------------+--------------------------------------------+
   | ACCESS               | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED,                 |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | BACKCHANNEL_CTL      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_NOENT, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | BIND_CONN_TO_SESSION | NFS4ERR_BADSESSION, NFS4ERR_BADXDR,        |
   |                      | NFS4ERR_BAD_SESSION_DIGEST,                |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_NOT_ONLY_OP,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | CLOSE                | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_LOCKS_HELD,     |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | COMMIT               | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_IO,             |
   |                      | NFS4ERR_ISDIR, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | CREATE               | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADNAME,          |
   |                      | NFS4ERR_BADOWNER, NFS4ERR_BADTYPE,         |
   |                      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_DQUOT,              |
   |                      | NFS4ERR_EXIST, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MLINK,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_OP_NOT_IN_SESSION, |
   |                      | NFS4ERR_PERM, NFS4ERR_REP_TOO_BIG,         |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND                    |
   | CREATE_SESSION       | NFS4ERR_BADXDR, NFS4ERR_CLID_INUSE,        |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_NOENT,              |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_NOSPC,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SEQ_MISORDERED,                    |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID, NFS4ERR_TOOSMALL,  |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DELEGPURGE           | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_IO,             |
   |                      | NFS4ERR_ISDIR, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | CREATE               | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADNAME,          |
   |                      | NFS4ERR_BADOWNER, NFS4ERR_BADTYPE,         |
   |                      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_DQUOT,              |
   |                      | NFS4ERR_EXIST, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MLINK,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_OP_NOT_IN_SESSION, |
   |                      | NFS4ERR_PERM, NFS4ERR_REP_TOO_BIG,         |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND                    |
   | CREATE_SESSION       | NFS4ERR_BADXDR, NFS4ERR_CLID_INUSE,        |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_NOENT,              |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_NOSPC,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SEQ_MISORDERED,                    |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID, NFS4ERR_TOOSMALL,  |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DELEGPURGE           | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
        
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONG_CRED                         |
   | DELEGRETURN          | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DESTROY_CLIENTID     | NFS4ERR_BADXDR, NFS4ERR_CLIENTID_BUSY,     |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_REP_TOO_BIG,  |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID,                    |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DESTROY_SESSION      | NFS4ERR_BACK_CHAN_BUSY,                    |
   |                      | NFS4ERR_BADSESSION, NFS4ERR_BADXDR,        |
   |                      | NFS4ERR_CB_PATH_DOWN,                      |
   |                      | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_REP_TOO_BIG,  |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID,                    |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | EXCHANGE_ID          | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_CLID_INUSE, NFS4ERR_DEADSESSION,   |
   |                      | NFS4ERR_DELAY, NFS4ERR_ENCR_ALG_UNSUPP,    |
   |                      | NFS4ERR_HASH_ALG_UNSUPP, NFS4ERR_INVAL,    |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOT_ONLY_OP,        |
   |                      | NFS4ERR_NOT_SAME, NFS4ERR_REP_TOO_BIG,     |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | FREE_STATEID         | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
        
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONG_CRED                         |
   | DELEGRETURN          | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DESTROY_CLIENTID     | NFS4ERR_BADXDR, NFS4ERR_CLIENTID_BUSY,     |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_REP_TOO_BIG,  |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID,                    |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | DESTROY_SESSION      | NFS4ERR_BACK_CHAN_BUSY,                    |
   |                      | NFS4ERR_BADSESSION, NFS4ERR_BADXDR,        |
   |                      | NFS4ERR_CB_PATH_DOWN,                      |
   |                      | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_NOT_ONLY_OP, NFS4ERR_REP_TOO_BIG,  |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT,                       |
   |                      | NFS4ERR_STALE_CLIENTID,                    |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | EXCHANGE_ID          | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_CLID_INUSE, NFS4ERR_DEADSESSION,   |
   |                      | NFS4ERR_DELAY, NFS4ERR_ENCR_ALG_UNSUPP,    |
   |                      | NFS4ERR_HASH_ALG_UNSUPP, NFS4ERR_INVAL,    |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOT_ONLY_OP,        |
   |                      | NFS4ERR_NOT_SAME, NFS4ERR_REP_TOO_BIG,     |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | FREE_STATEID         | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_LOCKS_HELD, NFS4ERR_OLD_STATEID,   |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONG_CRED                         |
   | GET_DIR_DELEGATION   | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DIRDELEG_UNAVAIL,                  |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | GETATTR              | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | GETDEVICEINFO        | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOOSMALL,     |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE                 |
   | GETDEVICELIST        | NFS4ERR_BADXDR, NFS4ERR_BAD_COOKIE,        |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_LOCKS_HELD, NFS4ERR_OLD_STATEID,   |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONG_CRED                         |
   | GET_DIR_DELEGATION   | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DIRDELEG_UNAVAIL,                  |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | GETATTR              | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | GETDEVICEINFO        | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOOSMALL,     |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE                 |
   | GETDEVICELIST        | NFS4ERR_BADXDR, NFS4ERR_BAD_COOKIE,        |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
        
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_NOFILEHANDLE,          |
   |                      | NFS4ERR_NOTSUPP, NFS4ERR_NOT_SAME,         |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE                 |
   | GETFH                | NFS4ERR_FHEXPIRED, NFS4ERR_MOVED,          |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_STALE   |
   | ILLEGAL              | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL         |
   | LAYOUTCOMMIT         | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADIOMODE,    |
   |                      | NFS4ERR_BADLAYOUT, NFS4ERR_BADXDR,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_EXPIRED,    |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_ISDIR NFS4ERR_MOVED,               |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_CRED                         |
   | LAYOUTGET            | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADIOMODE, NFS4ERR_BADLAYOUT,      |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_DQUOT,      |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO,                 |
   |                      | NFS4ERR_LAYOUTTRYLATER,                    |
   |                      | NFS4ERR_LAYOUTUNAVAILABLE, NFS4ERR_LOCKED, |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOSPC, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OLD_STATEID, NFS4ERR_OPENMODE,     |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
        
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_NOFILEHANDLE,          |
   |                      | NFS4ERR_NOTSUPP, NFS4ERR_NOT_SAME,         |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE                 |
   | GETFH                | NFS4ERR_FHEXPIRED, NFS4ERR_MOVED,          |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_STALE   |
   | ILLEGAL              | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL         |
   | LAYOUTCOMMIT         | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADIOMODE,    |
   |                      | NFS4ERR_BADLAYOUT, NFS4ERR_BADXDR,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_EXPIRED,    |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_ISDIR NFS4ERR_MOVED,               |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_CRED                         |
   | LAYOUTGET            | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADIOMODE, NFS4ERR_BADLAYOUT,      |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_DQUOT,      |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO,                 |
   |                      | NFS4ERR_LAYOUTTRYLATER,                    |
   |                      | NFS4ERR_LAYOUTUNAVAILABLE, NFS4ERR_LOCKED, |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOSPC, NFS4ERR_NOTSUPP,            |
   |                      | NFS4ERR_OLD_STATEID, NFS4ERR_OPENMODE,     |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
        
   |                      | NFS4ERR_RECALLCONFLICT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOOSMALL, NFS4ERR_TOO_MANY_OPS,    |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | LAYOUTRETURN         | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,        |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,     |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_CRED, NFS4ERR_WRONG_TYPE     |
   | LINK                 | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXIST,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_IO, NFS4ERR_MLINK,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTSUPP,           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC, NFS4ERR_WRONG_TYPE,      |
   |                      | NFS4ERR_XDEV                               |
   | LOCK                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_RANGE,         |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADLOCK,     |
        
   |                      | NFS4ERR_RECALLCONFLICT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOOSMALL, NFS4ERR_TOO_MANY_OPS,    |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | LAYOUTRETURN         | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,        |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,     |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_CRED, NFS4ERR_WRONG_TYPE     |
   | LINK                 | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXIST,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_IO, NFS4ERR_MLINK,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTSUPP,           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC, NFS4ERR_WRONG_TYPE,      |
   |                      | NFS4ERR_XDEV                               |
   | LOCK                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_RANGE,         |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADLOCK,     |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DENIED, NFS4ERR_EXPIRED,           |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR,              |
   |                      | NFS4ERR_LOCK_NOTSUPP, NFS4ERR_LOCK_RANGE,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,     |
   |                      | NFS4ERR_OPENMODE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_CRED, NFS4ERR_WRONG_TYPE     |
   | LOCKT                | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_BAD_RANGE, NFS4ERR_DEADSESSION,    |
   |                      | NFS4ERR_DELAY, NFS4ERR_DENIED,             |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR,              |
   |                      | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,         |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_STALE, NFS4ERR_SYMLINK,            |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED,  |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | LOCKU                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_RANGE,         |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,         |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID, |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | LOOKUP               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
        
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DENIED, NFS4ERR_EXPIRED,           |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR,              |
   |                      | NFS4ERR_LOCK_NOTSUPP, NFS4ERR_LOCK_RANGE,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,     |
   |                      | NFS4ERR_OPENMODE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_CRED, NFS4ERR_WRONG_TYPE     |
   | LOCKT                | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_BAD_RANGE, NFS4ERR_DEADSESSION,    |
   |                      | NFS4ERR_DELAY, NFS4ERR_DENIED,             |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR,              |
   |                      | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,         |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_STALE, NFS4ERR_SYMLINK,            |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED,  |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | LOCKU                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_RANGE,         |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,         |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID, |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | LOOKUP               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
        
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED,                 |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC                           |
   | LOOKUPP              | NFS4ERR_ACCESS, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC                           |
   | NVERIFY              | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_SAME,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | OPEN                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,      |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADOWNER,         |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_ALREADY_WANTED,              |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_DQUOT,      |
        
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED,                 |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC                           |
   | LOOKUPP              | NFS4ERR_ACCESS, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONGSEC                           |
   | NVERIFY              | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_SAME,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | OPEN                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,      |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADOWNER,         |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_ALREADY_WANTED,              |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_DQUOT,      |
        
   |                      | NFS4ERR_EXIST, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NO_GRACE,          |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_PERM,   |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_SHARE_DENIED, |
   |                      | NFS4ERR_STALE, NFS4ERR_SYMLINK,            |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND, NFS4ERR_WRONGSEC, |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | OPEN_CONFIRM         | NFS4ERR_NOTSUPP                            |
   | OPEN_DOWNGRADE       | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | OPENATTR             | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND,                   |
        
   |                      | NFS4ERR_EXIST, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL,              |
   |                      | NFS4ERR_ISDIR, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NO_GRACE,          |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_PERM,   |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_SHARE_DENIED, |
   |                      | NFS4ERR_STALE, NFS4ERR_SYMLINK,            |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND, NFS4ERR_WRONGSEC, |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | OPEN_CONFIRM         | NFS4ERR_NOTSUPP                            |
   | OPEN_DOWNGRADE       | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADXDR,     |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OLD_STATEID,                       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED   |
   | OPENATTR             | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNSAFE_COMPOUND,                   |
        
   |                      | NFS4ERR_WRONG_TYPE                         |
   | PUTFH                | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_MOVED, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC     |
   | PUTPUBFH             | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONGSEC                           |
   | PUTROOTFH            | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONGSEC                           |
   | READ                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_EXPIRED,    |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR, NFS4ERR_IO,  |
   |                      | NFS4ERR_LOCKED, NFS4ERR_MOVED,             |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID, |
   |                      | NFS4ERR_OPENMODE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_PNFS_IO_HOLE,                      |
   |                      | NFS4ERR_PNFS_NO_LAYOUT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | READDIR              | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_BAD_COOKIE, NFS4ERR_DEADSESSION,   |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
        
   |                      | NFS4ERR_WRONG_TYPE                         |
   | PUTFH                | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_MOVED, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC     |
   | PUTPUBFH             | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONGSEC                           |
   | PUTROOTFH            | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS, |
   |                      | NFS4ERR_WRONGSEC                           |
   | READ                 | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, NFS4ERR_EXPIRED,    |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_ISDIR, NFS4ERR_IO,  |
   |                      | NFS4ERR_LOCKED, NFS4ERR_MOVED,             |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID, |
   |                      | NFS4ERR_OPENMODE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_PNFS_IO_HOLE,                      |
   |                      | NFS4ERR_PNFS_NO_LAYOUT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | READDIR              | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_BAD_COOKIE, NFS4ERR_DEADSESSION,   |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
        
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOT_SAME,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOOSMALL, NFS4ERR_TOO_MANY_OPS     |
   | READLINK             | NFS4ERR_ACCESS, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | RECLAIM_COMPLETE     | NFS4ERR_BADXDR, NFS4ERR_COMPLETE_ALREADY,  |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED,  |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | RELEASE_LOCKOWNER    | NFS4ERR_NOTSUPP                            |
   | REMOVE               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTEMPTY,          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
        
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOT_SAME,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOOSMALL, NFS4ERR_TOO_MANY_OPS     |
   | READLINK             | NFS4ERR_ACCESS, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE,                      |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | RECLAIM_COMPLETE     | NFS4ERR_BADXDR, NFS4ERR_COMPLETE_ALREADY,  |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_CRED,  |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | RELEASE_LOCKOWNER    | NFS4ERR_NOTSUPP                            |
   | REMOVE               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTEMPTY,          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
        
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | RENAME               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXIST,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_MLINK, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTEMPTY,          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC,    |
   |                      | NFS4ERR_XDEV                               |
   | RENEW                | NFS4ERR_NOTSUPP                            |
   | RESTOREFH            | NFS4ERR_DEADSESSION, NFS4ERR_FHEXPIRED,    |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC     |
   | SAVEFH               | NFS4ERR_DEADSESSION, NFS4ERR_FHEXPIRED,    |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SECINFO              | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_OP_NOT_IN_SESSION, |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
        
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | RENAME               | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXIST,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,      |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_MLINK, NFS4ERR_MOVED,              |
   |                      | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,        |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_NOTEMPTY,          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC,    |
   |                      | NFS4ERR_XDEV                               |
   | RENEW                | NFS4ERR_NOTSUPP                            |
   | RESTOREFH            | NFS4ERR_DEADSESSION, NFS4ERR_FHEXPIRED,    |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONGSEC     |
   | SAVEFH               | NFS4ERR_DEADSESSION, NFS4ERR_FHEXPIRED,    |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SECINFO              | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,           |
   |                      | NFS4ERR_BADNAME, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,        |
   |                      | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,       |
   |                      | NFS4ERR_NOTDIR, NFS4ERR_OP_NOT_IN_SESSION, |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
        
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SECINFO_NO_NAME      | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOENT,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SEQUENCE             | NFS4ERR_BADSESSION, NFS4ERR_BADSLOT,       |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,     |
   |                      | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SEQUENCE_POS,                      |
   |                      | NFS4ERR_SEQ_FALSE_RETRY,                   |
   |                      | NFS4ERR_SEQ_MISORDERED,                    |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SET_SSV              | NFS4ERR_BADXDR,                            |
   |                      | NFS4ERR_BAD_SESSION_DIGEST,                |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SETATTR              | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,      |
   |                      | NFS4ERR_BADOWNER, NFS4ERR_BADXDR,          |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_LOCKED, NFS4ERR_MOVED,             |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_OLD_STATEID, NFS4ERR_OPENMODE,     |
        
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SECINFO_NO_NAME      | NFS4ERR_ACCESS, NFS4ERR_BADXDR,            |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,          |
   |                      | NFS4ERR_MOVED, NFS4ERR_NOENT,              |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,      |
   |                      | NFS4ERR_NOTSUPP,                           |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SEQUENCE             | NFS4ERR_BADSESSION, NFS4ERR_BADSLOT,       |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,     |
   |                      | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,         |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SEQUENCE_POS,                      |
   |                      | NFS4ERR_SEQ_FALSE_RETRY,                   |
   |                      | NFS4ERR_SEQ_MISORDERED,                    |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SET_SSV              | NFS4ERR_BADXDR,                            |
   |                      | NFS4ERR_BAD_SESSION_DIGEST,                |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_INVAL, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_TOO_MANY_OPS                       |
   | SETATTR              | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,      |
   |                      | NFS4ERR_BADOWNER, NFS4ERR_BADXDR,          |
   |                      | NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION,  |
   |                      | NFS4ERR_DELAY, NFS4ERR_DELEG_REVOKED,      |
   |                      | NFS4ERR_DQUOT, NFS4ERR_EXPIRED,            |
   |                      | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,           |
   |                      | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,  |
   |                      | NFS4ERR_LOCKED, NFS4ERR_MOVED,             |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,       |
   |                      | NFS4ERR_OLD_STATEID, NFS4ERR_OPENMODE,     |
        
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_PERM,   |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | SETCLIENTID          | NFS4ERR_NOTSUPP                            |
   | SETCLIENTID_CONFIRM  | NFS4ERR_NOTSUPP                            |
   | TEST_STATEID         | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | VERIFY               | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOT_SAME,    |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | WANT_DELEGATION      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY,                             |
   |                      | NFS4ERR_DELEG_ALREADY_WANTED,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECALLCONFLICT,                    |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
        
   |                      | NFS4ERR_OP_NOT_IN_SESSION, NFS4ERR_PERM,   |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | SETCLIENTID          | NFS4ERR_NOTSUPP                            |
   | SETCLIENTID_CONFIRM  | NFS4ERR_NOTSUPP                            |
   | TEST_STATEID         | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY, NFS4ERR_OP_NOT_IN_SESSION,  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_TOO_MANY_OPS  |
   | VERIFY               | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,       |
   |                      | NFS4ERR_BADCHAR, NFS4ERR_BADXDR,           |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOT_SAME,    |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS,                      |
   |                      | NFS4ERR_UNKNOWN_LAYOUTTYPE,                |
   |                      | NFS4ERR_WRONG_TYPE                         |
   | WANT_DELEGATION      | NFS4ERR_BADXDR, NFS4ERR_DEADSESSION,       |
   |                      | NFS4ERR_DELAY,                             |
   |                      | NFS4ERR_DELEG_ALREADY_WANTED,              |
   |                      | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,          |
   |                      | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,  |
   |                      | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,     |
   |                      | NFS4ERR_NO_GRACE,                          |
   |                      | NFS4ERR_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_RECALLCONFLICT,                    |
   |                      | NFS4ERR_RECLAIM_BAD,                       |
   |                      | NFS4ERR_RECLAIM_CONFLICT,                  |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP,                |
        
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | WRITE                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, 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_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_PNFS_IO_HOLE,                      |
   |                      | NFS4ERR_PNFS_NO_LAYOUT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   +----------------------+--------------------------------------------+
        
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_TOO_MANY_OPS, NFS4ERR_WRONG_TYPE   |
   | WRITE                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,     |
   |                      | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,       |
   |                      | NFS4ERR_DEADSESSION, NFS4ERR_DELAY,        |
   |                      | NFS4ERR_DELEG_REVOKED, 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_OP_NOT_IN_SESSION,                 |
   |                      | NFS4ERR_PNFS_IO_HOLE,                      |
   |                      | NFS4ERR_PNFS_NO_LAYOUT,                    |
   |                      | NFS4ERR_REP_TOO_BIG,                       |
   |                      | NFS4ERR_REP_TOO_BIG_TO_CACHE,              |
   |                      | NFS4ERR_REQ_TOO_BIG,                       |
   |                      | NFS4ERR_RETRY_UNCACHED_REP, NFS4ERR_ROFS,  |
   |                      | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,        |
   |                      | NFS4ERR_SYMLINK, NFS4ERR_TOO_MANY_OPS,     |
   |                      | NFS4ERR_WRONG_TYPE                         |
   +----------------------+--------------------------------------------+
        

Table 6

表6

15.3. Callback Operations and Their Valid Errors
15.3. 回调操作及其有效错误

This section contains a table that gives the valid error returns for each callback operation. The error code NFS4_OK (indicating no error) is not listed but should be understood to be returnable by all callback operations with the exception of CB_ILLEGAL.

本节包含一个表,该表为每个回调操作提供有效的错误返回。错误代码NFS4_OK(表示无错误)未列出,但应理解为可由所有回调操作返回,CB_非法除外。

Valid Error Returns for Each Protocol Callback Operation

为每个协议回调操作返回有效的错误

   +-------------------------+-----------------------------------------+
   | Callback Operation      | Errors                                  |
   +-------------------------+-----------------------------------------+
   | CB_GETATTR              | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   | CB_ILLEGAL              | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL      |
        
   +-------------------------+-----------------------------------------+
   | Callback Operation      | Errors                                  |
   +-------------------------+-----------------------------------------+
   | CB_GETATTR              | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   | CB_ILLEGAL              | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL      |
        
   | CB_LAYOUTRECALL         | NFS4ERR_BADHANDLE, NFS4ERR_BADIOMODE,   |
   |                         | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,    |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_NOMATCHING_LAYOUT,              |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   |                         | NFS4ERR_UNKNOWN_LAYOUTTYPE,             |
   |                         | NFS4ERR_WRONG_TYPE                      |
   | CB_NOTIFY               | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_NOTIFY_DEVICEID      | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_NOTIFY_LOCK          | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_PUSH_DELEG           | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REJECT_DELEG,                   |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
        
   | CB_LAYOUTRECALL         | NFS4ERR_BADHANDLE, NFS4ERR_BADIOMODE,   |
   |                         | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,    |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_NOMATCHING_LAYOUT,              |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   |                         | NFS4ERR_UNKNOWN_LAYOUTTYPE,             |
   |                         | NFS4ERR_WRONG_TYPE                      |
   | CB_NOTIFY               | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_NOTIFY_DEVICEID      | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_NOTIFY_LOCK          | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_PUSH_DELEG           | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_INVAL,           |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REJECT_DELEG,                   |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
        
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   |                         | NFS4ERR_WRONG_TYPE                      |
   | CB_RECALL               | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALL_ANY           | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL,                          |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALLABLE_OBJ_AVAIL | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALL_SLOT          | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,  |
   |                         | NFS4ERR_DELAY,                          |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_SEQUENCE             | NFS4ERR_BADSESSION, NFS4ERR_BADSLOT,    |
   |                         | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,  |
   |                         | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_REP_TOO_BIG,     |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SEQUENCE_POS,                   |
        
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS,                   |
   |                         | NFS4ERR_WRONG_TYPE                      |
   | CB_RECALL               | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,      |
   |                         | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,     |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALL_ANY           | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL,                          |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALLABLE_OBJ_AVAIL | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_INVAL, NFS4ERR_NOTSUPP,         |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_RECALL_SLOT          | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,  |
   |                         | NFS4ERR_DELAY,                          |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_SEQUENCE             | NFS4ERR_BADSESSION, NFS4ERR_BADSLOT,    |
   |                         | NFS4ERR_BADXDR, NFS4ERR_BAD_HIGH_SLOT,  |
   |                         | NFS4ERR_CONN_NOT_BOUND_TO_SESSION,      |
   |                         | NFS4ERR_DELAY, NFS4ERR_REP_TOO_BIG,     |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SEQUENCE_POS,                   |
        
   |                         | NFS4ERR_SEQ_FALSE_RETRY,                |
   |                         | NFS4ERR_SEQ_MISORDERED,                 |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_WANTS_CANCELLED      | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   +-------------------------+-----------------------------------------+
        
   |                         | NFS4ERR_SEQ_FALSE_RETRY,                |
   |                         | NFS4ERR_SEQ_MISORDERED,                 |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   | CB_WANTS_CANCELLED      | NFS4ERR_BADXDR, NFS4ERR_DELAY,          |
   |                         | NFS4ERR_NOTSUPP,                        |
   |                         | NFS4ERR_OP_NOT_IN_SESSION,              |
   |                         | NFS4ERR_REP_TOO_BIG,                    |
   |                         | NFS4ERR_REP_TOO_BIG_TO_CACHE,           |
   |                         | NFS4ERR_REQ_TOO_BIG,                    |
   |                         | NFS4ERR_RETRY_UNCACHED_REP,             |
   |                         | NFS4ERR_SERVERFAULT,                    |
   |                         | NFS4ERR_TOO_MANY_OPS                    |
   +-------------------------+-----------------------------------------+
        

Table 7

表7

15.4. Errors and the Operations That Use Them
15.4. 错误和使用它们的操作
   +-----------------------------------+-------------------------------+
   | Error                             | Operations                    |
   +-----------------------------------+-------------------------------+
   | NFS4ERR_ACCESS                    | ACCESS, COMMIT, CREATE,       |
   |                                   | GETATTR, GET_DIR_DELEGATION,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LINK, LOCK, LOCKT, LOCKU,     |
   |                                   | LOOKUP, LOOKUPP, NVERIFY,     |
   |                                   | OPEN, OPENATTR, READ,         |
   |                                   | READDIR, READLINK, REMOVE,    |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WRITE                 |
   | NFS4ERR_ADMIN_REVOKED             | CLOSE, DELEGRETURN,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_ATTRNOTSUPP               | CREATE, LAYOUTCOMMIT,         |
   |                                   | NVERIFY, OPEN, SETATTR,       |
   |                                   | VERIFY                        |
   | NFS4ERR_BACK_CHAN_BUSY            | DESTROY_SESSION               |
   | NFS4ERR_BADCHAR                   | CREATE, EXCHANGE_ID, LINK,    |
   |                                   | LOOKUP, NVERIFY, OPEN,        |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SETATTR, VERIFY               |
   | NFS4ERR_BADHANDLE                 | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY, CB_NOTIFY_LOCK,    |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | PUTFH                         |
        
   +-----------------------------------+-------------------------------+
   | Error                             | Operations                    |
   +-----------------------------------+-------------------------------+
   | NFS4ERR_ACCESS                    | ACCESS, COMMIT, CREATE,       |
   |                                   | GETATTR, GET_DIR_DELEGATION,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LINK, LOCK, LOCKT, LOCKU,     |
   |                                   | LOOKUP, LOOKUPP, NVERIFY,     |
   |                                   | OPEN, OPENATTR, READ,         |
   |                                   | READDIR, READLINK, REMOVE,    |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WRITE                 |
   | NFS4ERR_ADMIN_REVOKED             | CLOSE, DELEGRETURN,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_ATTRNOTSUPP               | CREATE, LAYOUTCOMMIT,         |
   |                                   | NVERIFY, OPEN, SETATTR,       |
   |                                   | VERIFY                        |
   | NFS4ERR_BACK_CHAN_BUSY            | DESTROY_SESSION               |
   | NFS4ERR_BADCHAR                   | CREATE, EXCHANGE_ID, LINK,    |
   |                                   | LOOKUP, NVERIFY, OPEN,        |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SETATTR, VERIFY               |
   | NFS4ERR_BADHANDLE                 | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY, CB_NOTIFY_LOCK,    |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | PUTFH                         |
        
   | NFS4ERR_BADIOMODE                 | CB_LAYOUTRECALL,              |
   |                                   | LAYOUTCOMMIT, LAYOUTGET       |
   | NFS4ERR_BADLAYOUT                 | LAYOUTCOMMIT, LAYOUTGET       |
   | NFS4ERR_BADNAME                   | CREATE, LINK, LOOKUP, OPEN,   |
   |                                   | REMOVE, RENAME, SECINFO       |
   | NFS4ERR_BADOWNER                  | CREATE, OPEN, SETATTR         |
   | NFS4ERR_BADSESSION                | BIND_CONN_TO_SESSION,         |
   |                                   | CB_SEQUENCE, DESTROY_SESSION, |
   |                                   | SEQUENCE                      |
   | NFS4ERR_BADSLOT                   | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_BADTYPE                   | CREATE                        |
   | NFS4ERR_BADXDR                    | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_ILLEGAL,       |
   |                                   | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION, ILLEGAL,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | OPEN_DOWNGRADE, PUTFH, READ,  |
   |                                   | READDIR, RECLAIM_COMPLETE,    |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SECINFO_NO_NAME, SEQUENCE,    |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_BAD_COOKIE                | GETDEVICELIST, READDIR        |
   | NFS4ERR_BAD_HIGH_SLOT             | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | SEQUENCE                      |
   | NFS4ERR_BAD_RANGE                 | LOCK, LOCKT, LOCKU            |
   | NFS4ERR_BAD_SESSION_DIGEST        | BIND_CONN_TO_SESSION, SET_SSV |
   | NFS4ERR_BAD_STATEID               | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_LOCK, CB_RECALL,    |
        
   | NFS4ERR_BADIOMODE                 | CB_LAYOUTRECALL,              |
   |                                   | LAYOUTCOMMIT, LAYOUTGET       |
   | NFS4ERR_BADLAYOUT                 | LAYOUTCOMMIT, LAYOUTGET       |
   | NFS4ERR_BADNAME                   | CREATE, LINK, LOOKUP, OPEN,   |
   |                                   | REMOVE, RENAME, SECINFO       |
   | NFS4ERR_BADOWNER                  | CREATE, OPEN, SETATTR         |
   | NFS4ERR_BADSESSION                | BIND_CONN_TO_SESSION,         |
   |                                   | CB_SEQUENCE, DESTROY_SESSION, |
   |                                   | SEQUENCE                      |
   | NFS4ERR_BADSLOT                   | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_BADTYPE                   | CREATE                        |
   | NFS4ERR_BADXDR                    | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_ILLEGAL,       |
   |                                   | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION, ILLEGAL,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | OPEN_DOWNGRADE, PUTFH, READ,  |
   |                                   | READDIR, RECLAIM_COMPLETE,    |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SECINFO_NO_NAME, SEQUENCE,    |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_BAD_COOKIE                | GETDEVICELIST, READDIR        |
   | NFS4ERR_BAD_HIGH_SLOT             | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | SEQUENCE                      |
   | NFS4ERR_BAD_RANGE                 | LOCK, LOCKT, LOCKU            |
   | NFS4ERR_BAD_SESSION_DIGEST        | BIND_CONN_TO_SESSION, SET_SSV |
   | NFS4ERR_BAD_STATEID               | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_LOCK, CB_RECALL,    |
        
   |                                   | CLOSE, DELEGRETURN,           |
   |                                   | FREE_STATEID, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_CB_PATH_DOWN              | DESTROY_SESSION               |
   | NFS4ERR_CLID_INUSE                | CREATE_SESSION, EXCHANGE_ID   |
   | NFS4ERR_CLIENTID_BUSY             | DESTROY_CLIENTID              |
   | NFS4ERR_COMPLETE_ALREADY          | RECLAIM_COMPLETE              |
   | NFS4ERR_CONN_NOT_BOUND_TO_SESSION | CB_SEQUENCE, DESTROY_SESSION, |
   |                                   | SEQUENCE                      |
   | NFS4ERR_DEADLOCK                  | LOCK                          |
   | NFS4ERR_DEADSESSION               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION, CLOSE,  |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_DELAY                     | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
        
   |                                   | CLOSE, DELEGRETURN,           |
   |                                   | FREE_STATEID, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_CB_PATH_DOWN              | DESTROY_SESSION               |
   | NFS4ERR_CLID_INUSE                | CREATE_SESSION, EXCHANGE_ID   |
   | NFS4ERR_CLIENTID_BUSY             | DESTROY_CLIENTID              |
   | NFS4ERR_COMPLETE_ALREADY          | RECLAIM_COMPLETE              |
   | NFS4ERR_CONN_NOT_BOUND_TO_SESSION | CB_SEQUENCE, DESTROY_SESSION, |
   |                                   | SEQUENCE                      |
   | NFS4ERR_DEADLOCK                  | LOCK                          |
   | NFS4ERR_DEADSESSION               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION, CLOSE,  |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_DELAY                     | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
        
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SEQUENCE,    |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_DELEG_ALREADY_WANTED      | OPEN, WANT_DELEGATION         |
   | NFS4ERR_DELEG_REVOKED             | DELEGRETURN, LAYOUTCOMMIT,    |
   |                                   | LAYOUTGET, LAYOUTRETURN,      |
   |                                   | OPEN, READ, SETATTR, WRITE    |
   | NFS4ERR_DENIED                    | LOCK, LOCKT                   |
   | NFS4ERR_DIRDELEG_UNAVAIL          | GET_DIR_DELEGATION            |
   | NFS4ERR_DQUOT                     | CREATE, LAYOUTGET, LINK,      |
   |                                   | OPEN, OPENATTR, RENAME,       |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_ENCR_ALG_UNSUPP           | EXCHANGE_ID                   |
   | NFS4ERR_EXIST                     | CREATE, LINK, OPEN, RENAME    |
   | NFS4ERR_EXPIRED                   | CLOSE, DELEGRETURN,           |
   |                                   | LAYOUTCOMMIT, LAYOUTRETURN,   |
   |                                   | LOCK, LOCKU, OPEN,            |
   |                                   | OPEN_DOWNGRADE, READ,         |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_FBIG                      | LAYOUTCOMMIT, OPEN, SETATTR,  |
   |                                   | WRITE                         |
   | NFS4ERR_FHEXPIRED                 | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
        
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SEQUENCE,    |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_DELEG_ALREADY_WANTED      | OPEN, WANT_DELEGATION         |
   | NFS4ERR_DELEG_REVOKED             | DELEGRETURN, LAYOUTCOMMIT,    |
   |                                   | LAYOUTGET, LAYOUTRETURN,      |
   |                                   | OPEN, READ, SETATTR, WRITE    |
   | NFS4ERR_DENIED                    | LOCK, LOCKT                   |
   | NFS4ERR_DIRDELEG_UNAVAIL          | GET_DIR_DELEGATION            |
   | NFS4ERR_DQUOT                     | CREATE, LAYOUTGET, LINK,      |
   |                                   | OPEN, OPENATTR, RENAME,       |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_ENCR_ALG_UNSUPP           | EXCHANGE_ID                   |
   | NFS4ERR_EXIST                     | CREATE, LINK, OPEN, RENAME    |
   | NFS4ERR_EXPIRED                   | CLOSE, DELEGRETURN,           |
   |                                   | LAYOUTCOMMIT, LAYOUTRETURN,   |
   |                                   | LOCK, LOCKU, OPEN,            |
   |                                   | OPEN_DOWNGRADE, READ,         |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_FBIG                      | LAYOUTCOMMIT, OPEN, SETATTR,  |
   |                                   | WRITE                         |
   | NFS4ERR_FHEXPIRED                 | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
        
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_FILE_OPEN                 | LINK, REMOVE, RENAME          |
   | NFS4ERR_GRACE                     | GETATTR, GET_DIR_DELEGATION,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, NVERIFY, OPEN, READ,   |
   |                                   | REMOVE, RENAME, SETATTR,      |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_HASH_ALG_UNSUPP           | EXCHANGE_ID                   |
   | NFS4ERR_INVAL                     | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_PUSH_DELEG,                |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY, CREATE,        |
   |                                   | CREATE_SESSION, DELEGRETURN,  |
   |                                   | EXCHANGE_ID, GETATTR,         |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | NVERIFY, OPEN,                |
   |                                   | OPEN_DOWNGRADE, READ,         |
   |                                   | READDIR, READLINK,            |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | SET_SSV, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_IO                        | ACCESS, COMMIT, CREATE,       |
   |                                   | GETATTR, GETDEVICELIST,       |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LINK, LOOKUP, LOOKUPP,        |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | REMOVE, RENAME, SETATTR,      |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_ISDIR                     | COMMIT, LAYOUTCOMMIT,         |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
        
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_FILE_OPEN                 | LINK, REMOVE, RENAME          |
   | NFS4ERR_GRACE                     | GETATTR, GET_DIR_DELEGATION,  |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, NVERIFY, OPEN, READ,   |
   |                                   | REMOVE, RENAME, SETATTR,      |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_HASH_ALG_UNSUPP           | EXCHANGE_ID                   |
   | NFS4ERR_INVAL                     | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_PUSH_DELEG,                |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY, CREATE,        |
   |                                   | CREATE_SESSION, DELEGRETURN,  |
   |                                   | EXCHANGE_ID, GETATTR,         |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | NVERIFY, OPEN,                |
   |                                   | OPEN_DOWNGRADE, READ,         |
   |                                   | READDIR, READLINK,            |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | SET_SSV, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_IO                        | ACCESS, COMMIT, CREATE,       |
   |                                   | GETATTR, GETDEVICELIST,       |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LINK, LOOKUP, LOOKUPP,        |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | REMOVE, RENAME, SETATTR,      |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_ISDIR                     | COMMIT, LAYOUTCOMMIT,         |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
        
   |                                   | LOCKT, OPEN, READ, WRITE      |
   | NFS4ERR_LAYOUTTRYLATER            | LAYOUTGET                     |
   | NFS4ERR_LAYOUTUNAVAILABLE         | LAYOUTGET                     |
   | NFS4ERR_LOCKED                    | LAYOUTGET, READ, SETATTR,     |
   |                                   | WRITE                         |
   | NFS4ERR_LOCKS_HELD                | CLOSE, FREE_STATEID           |
   | NFS4ERR_LOCK_NOTSUPP              | LOCK                          |
   | NFS4ERR_LOCK_RANGE                | LOCK, LOCKT, LOCKU            |
   | NFS4ERR_MLINK                     | CREATE, LINK, RENAME          |
   | NFS4ERR_MOVED                     | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETFH, GET_DIR_DELEGATION,    |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, READ, READDIR,         |
   |                                   | READLINK, RECLAIM_COMPLETE,   |
   |                                   | REMOVE, RENAME, RESTOREFH,    |
   |                                   | SAVEFH, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_NAMETOOLONG               | CREATE, LINK, LOOKUP, OPEN,   |
   |                                   | REMOVE, RENAME, SECINFO       |
   | NFS4ERR_NOENT                     | BACKCHANNEL_CTL,              |
   |                                   | CREATE_SESSION, EXCHANGE_ID,  |
   |                                   | GETDEVICEINFO, LOOKUP,        |
   |                                   | LOOKUPP, OPEN, OPENATTR,      |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SECINFO_NO_NAME               |
   | NFS4ERR_NOFILEHANDLE              | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_NOMATCHING_LAYOUT         | CB_LAYOUTRECALL               |
        
   |                                   | LOCKT, OPEN, READ, WRITE      |
   | NFS4ERR_LAYOUTTRYLATER            | LAYOUTGET                     |
   | NFS4ERR_LAYOUTUNAVAILABLE         | LAYOUTGET                     |
   | NFS4ERR_LOCKED                    | LAYOUTGET, READ, SETATTR,     |
   |                                   | WRITE                         |
   | NFS4ERR_LOCKS_HELD                | CLOSE, FREE_STATEID           |
   | NFS4ERR_LOCK_NOTSUPP              | LOCK                          |
   | NFS4ERR_LOCK_RANGE                | LOCK, LOCKT, LOCKU            |
   | NFS4ERR_MLINK                     | CREATE, LINK, RENAME          |
   | NFS4ERR_MOVED                     | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETFH, GET_DIR_DELEGATION,    |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, READ, READDIR,         |
   |                                   | READLINK, RECLAIM_COMPLETE,   |
   |                                   | REMOVE, RENAME, RESTOREFH,    |
   |                                   | SAVEFH, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_NAMETOOLONG               | CREATE, LINK, LOOKUP, OPEN,   |
   |                                   | REMOVE, RENAME, SECINFO       |
   | NFS4ERR_NOENT                     | BACKCHANNEL_CTL,              |
   |                                   | CREATE_SESSION, EXCHANGE_ID,  |
   |                                   | GETDEVICEINFO, LOOKUP,        |
   |                                   | LOOKUPP, OPEN, OPENATTR,      |
   |                                   | REMOVE, RENAME, SECINFO,      |
   |                                   | SECINFO_NO_NAME               |
   | NFS4ERR_NOFILEHANDLE              | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, VERIFY,              |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_NOMATCHING_LAYOUT         | CB_LAYOUTRECALL               |
        
   | NFS4ERR_NOSPC                     | CREATE, CREATE_SESSION,       |
   |                                   | LAYOUTGET, LINK, OPEN,        |
   |                                   | OPENATTR, RENAME, SETATTR,    |
   |                                   | WRITE                         |
   | NFS4ERR_NOTDIR                    | CREATE, GET_DIR_DELEGATION,   |
   |                                   | LINK, LOOKUP, LOOKUPP, OPEN,  |
   |                                   | READDIR, REMOVE, RENAME,      |
   |                                   | SECINFO, SECINFO_NO_NAME      |
   | NFS4ERR_NOTEMPTY                  | REMOVE, RENAME                |
   | NFS4ERR_NOTSUPP                   | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG,                |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_WANTS_CANCELLED,           |
   |                                   | DELEGPURGE, DELEGRETURN,      |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, OPENATTR, |
   |                                   | OPEN_CONFIRM,                 |
   |                                   | RELEASE_LOCKOWNER, RENEW,     |
   |                                   | SECINFO_NO_NAME, SETCLIENTID, |
   |                                   | SETCLIENTID_CONFIRM,          |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_NOT_ONLY_OP               | BIND_CONN_TO_SESSION,         |
   |                                   | CREATE_SESSION,               |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID  |
   | NFS4ERR_NOT_SAME                  | EXCHANGE_ID, GETDEVICELIST,   |
   |                                   | READDIR, VERIFY               |
   | NFS4ERR_NO_GRACE                  | LAYOUTCOMMIT, LAYOUTRETURN,   |
   |                                   | LOCK, OPEN, WANT_DELEGATION   |
   | NFS4ERR_OLD_STATEID               | CLOSE, DELEGRETURN,           |
   |                                   | FREE_STATEID, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_OPENMODE                  | LAYOUTGET, LOCK, READ,        |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_OP_ILLEGAL                | CB_ILLEGAL, ILLEGAL           |
   | NFS4ERR_OP_NOT_IN_SESSION         | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
        
   | NFS4ERR_NOSPC                     | CREATE, CREATE_SESSION,       |
   |                                   | LAYOUTGET, LINK, OPEN,        |
   |                                   | OPENATTR, RENAME, SETATTR,    |
   |                                   | WRITE                         |
   | NFS4ERR_NOTDIR                    | CREATE, GET_DIR_DELEGATION,   |
   |                                   | LINK, LOOKUP, LOOKUPP, OPEN,  |
   |                                   | READDIR, REMOVE, RENAME,      |
   |                                   | SECINFO, SECINFO_NO_NAME      |
   | NFS4ERR_NOTEMPTY                  | REMOVE, RENAME                |
   | NFS4ERR_NOTSUPP                   | CB_LAYOUTRECALL, CB_NOTIFY,   |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG,                |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_WANTS_CANCELLED,           |
   |                                   | DELEGPURGE, DELEGRETURN,      |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, OPENATTR, |
   |                                   | OPEN_CONFIRM,                 |
   |                                   | RELEASE_LOCKOWNER, RENEW,     |
   |                                   | SECINFO_NO_NAME, SETCLIENTID, |
   |                                   | SETCLIENTID_CONFIRM,          |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_NOT_ONLY_OP               | BIND_CONN_TO_SESSION,         |
   |                                   | CREATE_SESSION,               |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID  |
   | NFS4ERR_NOT_SAME                  | EXCHANGE_ID, GETDEVICELIST,   |
   |                                   | READDIR, VERIFY               |
   | NFS4ERR_NO_GRACE                  | LAYOUTCOMMIT, LAYOUTRETURN,   |
   |                                   | LOCK, OPEN, WANT_DELEGATION   |
   | NFS4ERR_OLD_STATEID               | CLOSE, DELEGRETURN,           |
   |                                   | FREE_STATEID, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LOCK, LOCKU,    |
   |                                   | OPEN, OPEN_DOWNGRADE, READ,   |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_OPENMODE                  | LAYOUTGET, LOCK, READ,        |
   |                                   | SETATTR, WRITE                |
   | NFS4ERR_OP_ILLEGAL                | CB_ILLEGAL, ILLEGAL           |
   | NFS4ERR_OP_NOT_IN_SESSION         | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
        
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT,               |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE, DELEGPURGE,   |
   |                                   | DELEGRETURN, FREE_STATEID,    |
   |                                   | GETATTR, GETDEVICEINFO,       |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_PERM                      | CREATE, OPEN, SETATTR         |
   | NFS4ERR_PNFS_IO_HOLE              | READ, WRITE                   |
   | NFS4ERR_PNFS_NO_LAYOUT            | READ, WRITE                   |
   | NFS4ERR_RECALLCONFLICT            | LAYOUTGET, WANT_DELEGATION    |
   | NFS4ERR_RECLAIM_BAD               | LAYOUTCOMMIT, LOCK, OPEN,     |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_RECLAIM_CONFLICT          | LAYOUTCOMMIT, LOCK, OPEN,     |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_REJECT_DELEG              | CB_PUSH_DELEG                 |
   | NFS4ERR_REP_TOO_BIG               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
        
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT,               |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE, DELEGPURGE,   |
   |                                   | DELEGRETURN, FREE_STATEID,    |
   |                                   | GETATTR, GETDEVICEINFO,       |
   |                                   | GETDEVICELIST, GETFH,         |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SETATTR, SET_SSV,             |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_PERM                      | CREATE, OPEN, SETATTR         |
   | NFS4ERR_PNFS_IO_HOLE              | READ, WRITE                   |
   | NFS4ERR_PNFS_NO_LAYOUT            | READ, WRITE                   |
   | NFS4ERR_RECALLCONFLICT            | LAYOUTGET, WANT_DELEGATION    |
   | NFS4ERR_RECLAIM_BAD               | LAYOUTCOMMIT, LOCK, OPEN,     |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_RECLAIM_CONFLICT          | LAYOUTCOMMIT, LOCK, OPEN,     |
   |                                   | WANT_DELEGATION               |
   | NFS4ERR_REJECT_DELEG              | CB_PUSH_DELEG                 |
   | NFS4ERR_REP_TOO_BIG               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
        
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE      | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_REQ_TOO_BIG               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
        
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE      | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_REQ_TOO_BIG               | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
        
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_RETRY_UNCACHED_REP        | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
        
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_RETRY_UNCACHED_REP        | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
        
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_ROFS                      | CREATE, LINK, LOCK, LOCKT,    |
   |                                   | OPEN, OPENATTR,               |
   |                                   | OPEN_DOWNGRADE, REMOVE,       |
   |                                   | RENAME, SETATTR, WRITE        |
   | NFS4ERR_SAME                      | NVERIFY                       |
   | NFS4ERR_SEQUENCE_POS              | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_SEQ_FALSE_RETRY           | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_SEQ_MISORDERED            | CB_SEQUENCE, CREATE_SESSION,  |
   |                                   | SEQUENCE                      |
   | NFS4ERR_SERVERFAULT               | ACCESS, BIND_CONN_TO_SESSION, |
   |                                   | CB_GETATTR, CB_NOTIFY,        |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKU, LOOKUP, LOOKUPP,       |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | OPEN_DOWNGRADE, PUTFH,        |
   |                                   | PUTPUBFH, PUTROOTFH, READ,    |
   |                                   | READDIR, READLINK,            |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
        
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_ROFS                      | CREATE, LINK, LOCK, LOCKT,    |
   |                                   | OPEN, OPENATTR,               |
   |                                   | OPEN_DOWNGRADE, REMOVE,       |
   |                                   | RENAME, SETATTR, WRITE        |
   | NFS4ERR_SAME                      | NVERIFY                       |
   | NFS4ERR_SEQUENCE_POS              | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_SEQ_FALSE_RETRY           | CB_SEQUENCE, SEQUENCE         |
   | NFS4ERR_SEQ_MISORDERED            | CB_SEQUENCE, CREATE_SESSION,  |
   |                                   | SEQUENCE                      |
   | NFS4ERR_SERVERFAULT               | ACCESS, BIND_CONN_TO_SESSION, |
   |                                   | CB_GETATTR, CB_NOTIFY,        |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKU, LOOKUP, LOOKUPP,       |
   |                                   | NVERIFY, OPEN, OPENATTR,      |
   |                                   | OPEN_DOWNGRADE, PUTFH,        |
   |                                   | PUTPUBFH, PUTROOTFH, READ,    |
   |                                   | READDIR, READLINK,            |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
        
   |                                   | SETATTR, TEST_STATEID,        |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_SHARE_DENIED              | OPEN                          |
   | NFS4ERR_STALE                     | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETFH, GET_DIR_DELEGATION,    |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, READ, READDIR,         |
   |                                   | READLINK, RECLAIM_COMPLETE,   |
   |                                   | REMOVE, RENAME, RESTOREFH,    |
   |                                   | SAVEFH, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_STALE_CLIENTID            | CREATE_SESSION,               |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION               |
   | NFS4ERR_SYMLINK                   | COMMIT, LAYOUTCOMMIT, LINK,   |
   |                                   | LOCK, LOCKT, LOOKUP, LOOKUPP, |
   |                                   | OPEN, READ, WRITE             |
   | NFS4ERR_TOOSMALL                  | CREATE_SESSION,               |
   |                                   | GETDEVICEINFO, LAYOUTGET,     |
   |                                   | READDIR                       |
   | NFS4ERR_TOO_MANY_OPS              | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
        
   |                                   | SETATTR, TEST_STATEID,        |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_SHARE_DENIED              | OPEN                          |
   | NFS4ERR_STALE                     | ACCESS, CLOSE, COMMIT,        |
   |                                   | CREATE, DELEGRETURN, GETATTR, |
   |                                   | GETFH, GET_DIR_DELEGATION,    |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, READ, READDIR,         |
   |                                   | READLINK, RECLAIM_COMPLETE,   |
   |                                   | REMOVE, RENAME, RESTOREFH,    |
   |                                   | SAVEFH, SECINFO,              |
   |                                   | SECINFO_NO_NAME, SETATTR,     |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_STALE_CLIENTID            | CREATE_SESSION,               |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION               |
   | NFS4ERR_SYMLINK                   | COMMIT, LAYOUTCOMMIT, LINK,   |
   |                                   | LOCK, LOCKT, LOOKUP, LOOKUPP, |
   |                                   | OPEN, READ, WRITE             |
   | NFS4ERR_TOOSMALL                  | CREATE_SESSION,               |
   |                                   | GETDEVICEINFO, LAYOUTGET,     |
   |                                   | READDIR                       |
   | NFS4ERR_TOO_MANY_OPS              | ACCESS, BACKCHANNEL_CTL,      |
   |                                   | BIND_CONN_TO_SESSION,         |
   |                                   | CB_GETATTR, CB_LAYOUTRECALL,  |
   |                                   | CB_NOTIFY,                    |
   |                                   | CB_NOTIFY_DEVICEID,           |
   |                                   | CB_NOTIFY_LOCK,               |
   |                                   | CB_PUSH_DELEG, CB_RECALL,     |
   |                                   | CB_RECALLABLE_OBJ_AVAIL,      |
   |                                   | CB_RECALL_ANY,                |
   |                                   | CB_RECALL_SLOT, CB_SEQUENCE,  |
   |                                   | CB_WANTS_CANCELLED, CLOSE,    |
   |                                   | COMMIT, CREATE,               |
   |                                   | CREATE_SESSION, DELEGPURGE,   |
   |                                   | DELEGRETURN,                  |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION, EXCHANGE_ID, |
   |                                   | FREE_STATEID, GETATTR,        |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | GET_DIR_DELEGATION,           |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
        
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_UNKNOWN_LAYOUTTYPE        | CB_LAYOUTRECALL,              |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, NVERIFY,        |
   |                                   | SETATTR, VERIFY               |
   | NFS4ERR_UNSAFE_COMPOUND           | CREATE, OPEN, OPENATTR        |
   | NFS4ERR_WRONGSEC                  | LINK, LOOKUP, LOOKUPP, OPEN,  |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | RENAME, RESTOREFH             |
   | NFS4ERR_WRONG_CRED                | CLOSE, CREATE_SESSION,        |
   |                                   | DELEGPURGE, DELEGRETURN,      |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION,              |
   |                                   | FREE_STATEID, LAYOUTCOMMIT,   |
   |                                   | LAYOUTRETURN, LOCK, LOCKT,    |
   |                                   | LOCKU, OPEN_DOWNGRADE,        |
   |                                   | RECLAIM_COMPLETE              |
   | NFS4ERR_WRONG_TYPE                | CB_LAYOUTRECALL,              |
   |                                   | CB_PUSH_DELEG, COMMIT,        |
   |                                   | GETATTR, LAYOUTGET,           |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, NVERIFY, OPEN,         |
   |                                   | OPENATTR, READ, READLINK,     |
   |                                   | RECLAIM_COMPLETE, SETATTR,    |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_XDEV                      | LINK, RENAME                  |
   +-----------------------------------+-------------------------------+
        
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, LOCKU, LOOKUP,         |
   |                                   | LOOKUPP, NVERIFY, OPEN,       |
   |                                   | OPENATTR, OPEN_DOWNGRADE,     |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | READ, READDIR, READLINK,      |
   |                                   | RECLAIM_COMPLETE, REMOVE,     |
   |                                   | RENAME, RESTOREFH, SAVEFH,    |
   |                                   | SECINFO, SECINFO_NO_NAME,     |
   |                                   | SEQUENCE, SETATTR, SET_SSV,   |
   |                                   | TEST_STATEID, VERIFY,         |
   |                                   | WANT_DELEGATION, WRITE        |
   | NFS4ERR_UNKNOWN_LAYOUTTYPE        | CB_LAYOUTRECALL,              |
   |                                   | GETDEVICEINFO, GETDEVICELIST, |
   |                                   | LAYOUTCOMMIT, LAYOUTGET,      |
   |                                   | LAYOUTRETURN, NVERIFY,        |
   |                                   | SETATTR, VERIFY               |
   | NFS4ERR_UNSAFE_COMPOUND           | CREATE, OPEN, OPENATTR        |
   | NFS4ERR_WRONGSEC                  | LINK, LOOKUP, LOOKUPP, OPEN,  |
   |                                   | PUTFH, PUTPUBFH, PUTROOTFH,   |
   |                                   | RENAME, RESTOREFH             |
   | NFS4ERR_WRONG_CRED                | CLOSE, CREATE_SESSION,        |
   |                                   | DELEGPURGE, DELEGRETURN,      |
   |                                   | DESTROY_CLIENTID,             |
   |                                   | DESTROY_SESSION,              |
   |                                   | FREE_STATEID, LAYOUTCOMMIT,   |
   |                                   | LAYOUTRETURN, LOCK, LOCKT,    |
   |                                   | LOCKU, OPEN_DOWNGRADE,        |
   |                                   | RECLAIM_COMPLETE              |
   | NFS4ERR_WRONG_TYPE                | CB_LAYOUTRECALL,              |
   |                                   | CB_PUSH_DELEG, COMMIT,        |
   |                                   | GETATTR, LAYOUTGET,           |
   |                                   | LAYOUTRETURN, LINK, LOCK,     |
   |                                   | LOCKT, NVERIFY, OPEN,         |
   |                                   | OPENATTR, READ, READLINK,     |
   |                                   | RECLAIM_COMPLETE, SETATTR,    |
   |                                   | VERIFY, WANT_DELEGATION,      |
   |                                   | WRITE                         |
   | NFS4ERR_XDEV                      | LINK, RENAME                  |
   +-----------------------------------+-------------------------------+
        

Table 8

表8

16. NFSv4.1 Procedures
16. NFSv4.1程序

Both procedures, NULL and COMPOUND, MUST be implemented.

这两个过程,NULL和component,都必须实现。

16.1. Procedure 0: NULL - No Operation
16.1. 过程0:NULL-无操作
16.1.1. ARGUMENTS
16.1.1. 论据

void;

无效的

16.1.2. RESULTS
16.1.2. 后果

void;

无效的

16.1.3. DESCRIPTION
16.1.3. 描述

This is the standard NULL procedure with the standard void argument and 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.

这是带有标准void参数和void响应的标准NULL过程。此过程没有与之关联的功能。因此,它有时用于测量处理服务请求的开销。因此,服务器应确保在维护此过程时不会进行不必要的工作。

16.1.4. ERRORS
16.1.4. 错误

None.

没有一个

16.2. Procedure 1: COMPOUND - Compound Operations
16.2. 程序1:复合-复合操作
16.2.1. ARGUMENTS
16.2.1. 论据
   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, /* Mandatory not-to-implement */
    OP_OPEN_DOWNGRADE      = 21,
    OP_PUTFH               = 22,
        
   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, /* Mandatory not-to-implement */
    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, /* Mandatory not-to-implement */
    OP_RESTOREFH           = 31,
    OP_SAVEFH              = 32,
    OP_SECINFO             = 33,
    OP_SETATTR             = 34,
    OP_SETCLIENTID         = 35, /* Mandatory not-to-implement */
    OP_SETCLIENTID_CONFIRM = 36, /* Mandatory not-to-implement */
    OP_VERIFY              = 37,
    OP_WRITE               = 38,
    OP_RELEASE_LOCKOWNER   = 39, /* Mandatory not-to-implement */
        
    OP_PUTPUBFH            = 23,
    OP_PUTROOTFH           = 24,
    OP_READ                = 25,
    OP_READDIR             = 26,
    OP_READLINK            = 27,
    OP_REMOVE              = 28,
    OP_RENAME              = 29,
    OP_RENEW               = 30, /* Mandatory not-to-implement */
    OP_RESTOREFH           = 31,
    OP_SAVEFH              = 32,
    OP_SECINFO             = 33,
    OP_SETATTR             = 34,
    OP_SETCLIENTID         = 35, /* Mandatory not-to-implement */
    OP_SETCLIENTID_CONFIRM = 36, /* Mandatory not-to-implement */
    OP_VERIFY              = 37,
    OP_WRITE               = 38,
    OP_RELEASE_LOCKOWNER   = 39, /* Mandatory not-to-implement */
        
   /* new operations for NFSv4.1 */
    OP_BACKCHANNEL_CTL     = 40,
    OP_BIND_CONN_TO_SESSION = 41,
    OP_EXCHANGE_ID         = 42,
    OP_CREATE_SESSION      = 43,
    OP_DESTROY_SESSION     = 44,
    OP_FREE_STATEID        = 45,
    OP_GET_DIR_DELEGATION  = 46,
    OP_GETDEVICEINFO       = 47,
    OP_GETDEVICELIST       = 48,
    OP_LAYOUTCOMMIT        = 49,
    OP_LAYOUTGET           = 50,
    OP_LAYOUTRETURN        = 51,
    OP_SECINFO_NO_NAME     = 52,
    OP_SEQUENCE            = 53,
    OP_SET_SSV             = 54,
    OP_TEST_STATEID        = 55,
    OP_WANT_DELEGATION     = 56,
    OP_DESTROY_CLIENTID    = 57,
    OP_RECLAIM_COMPLETE    = 58,
    OP_ILLEGAL             = 10044
   };
        
   /* new operations for NFSv4.1 */
    OP_BACKCHANNEL_CTL     = 40,
    OP_BIND_CONN_TO_SESSION = 41,
    OP_EXCHANGE_ID         = 42,
    OP_CREATE_SESSION      = 43,
    OP_DESTROY_SESSION     = 44,
    OP_FREE_STATEID        = 45,
    OP_GET_DIR_DELEGATION  = 46,
    OP_GETDEVICEINFO       = 47,
    OP_GETDEVICELIST       = 48,
    OP_LAYOUTCOMMIT        = 49,
    OP_LAYOUTGET           = 50,
    OP_LAYOUTRETURN        = 51,
    OP_SECINFO_NO_NAME     = 52,
    OP_SEQUENCE            = 53,
    OP_SET_SSV             = 54,
    OP_TEST_STATEID        = 55,
    OP_WANT_DELEGATION     = 56,
    OP_DESTROY_CLIENTID    = 57,
    OP_RECLAIM_COMPLETE    = 58,
    OP_ILLEGAL             = 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;
        
   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;
        
    /* Not for NFSv4.1 */
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4args opopen_confirm;
        
    /* Not for NFSv4.1 */
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4args opopen_confirm;
        

case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4args opopen_downgrade;

案例OP_OPEN_降级:OPEN_降级4args OPOPOPEN_降级;

    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_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;
        
    /* Not for NFSv4.1 */
    case OP_RENEW:         RENEW4args oprenew;
        
    /* Not for NFSv4.1 */
    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_RESTOREFH:     void;
    case OP_SAVEFH:        void;
    case OP_SECINFO:       SECINFO4args opsecinfo;
    case OP_SETATTR:       SETATTR4args opsetattr;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4args opsetclientid;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4args opsetclientid;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4args
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4args
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;
        
    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4args
                           oprelease_lockowner;
        
    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4args
                           oprelease_lockowner;
        
    /* Operations new to NFSv4.1 */
    case OP_BACKCHANNEL_CTL:
                           BACKCHANNEL_CTL4args opbackchannel_ctl;
        
    /* Operations new to NFSv4.1 */
    case OP_BACKCHANNEL_CTL:
                           BACKCHANNEL_CTL4args opbackchannel_ctl;
        

case OP_BIND_CONN_TO_SESSION: BIND_CONN_TO_SESSION4args opbind_conn_to_session;

案例OP_BIND_CONN_TO_会话:BIND_CONN_TO_会话4Args opbind_CONN_TO_会话;

case OP_EXCHANGE_ID: EXCHANGE_ID4args opexchange_id;

案例OP_EXCHANGE_ID:EXCHANGE_ID4args opexchange_ID;

case OP_CREATE_SESSION: CREATE_SESSION4args opcreate_session;

案例操作创建会话:创建会话4args操作创建会话;

case OP_DESTROY_SESSION: DESTROY_SESSION4args opdestroy_session;

案例操作销毁会话:销毁会话4args操作销毁会话;

case OP_FREE_STATEID: FREE_STATEID4args opfree_stateid;

case OP_FREE_STATEID:FREE_STATEID 4args opfree_STATEID;

case OP_GET_DIR_DELEGATION: GET_DIR_DELEGATION4args opget_dir_delegation;

案例OP_GET_DIR_委派:GET_DIR_委派4Args opget_DIR_委派;

    case OP_GETDEVICEINFO: GETDEVICEINFO4args opgetdeviceinfo;
    case OP_GETDEVICELIST: GETDEVICELIST4args opgetdevicelist;
    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4args oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4args oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4args oplayoutreturn;
        
    case OP_GETDEVICEINFO: GETDEVICEINFO4args opgetdeviceinfo;
    case OP_GETDEVICELIST: GETDEVICELIST4args opgetdevicelist;
    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4args oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4args oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4args oplayoutreturn;
        

case OP_SECINFO_NO_NAME: SECINFO_NO_NAME4args opsecinfo_no_name;

案例OP_SECINFO_NO_NAME:SECINFO_NO_NAME 4args opsecinfo_NO_NAME;

    case OP_SEQUENCE:      SEQUENCE4args opsequence;
    case OP_SET_SSV:       SET_SSV4args opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4args optest_stateid;
        
    case OP_SEQUENCE:      SEQUENCE4args opsequence;
    case OP_SET_SSV:       SET_SSV4args opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4args optest_stateid;
        

case OP_WANT_DELEGATION: WANT_DELEGATION4args opwant_delegation;

案例OP_WANT_委派:WANT_委派4Args opwant_委派;

case OP_DESTROY_CLIENTID: DESTROY_CLIENTID4args opdestroy_clientid;

案例操作销毁客户端ID:销毁客户端4参数操作销毁客户端ID;

case OP_RECLAIM_COMPLETE: RECLAIM_COMPLETE4args opreclaim_complete;

案例OP_Recall_COMPLETE:Recall_COMPLETE4args opreclaim_COMPLETE;

    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       void;
   };
        
    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       void;
   };
        
   struct COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        
   struct COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };
        
16.2.2. RESULTS
16.2.2. 后果
   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;
    /* Not for NFSv4.1 */
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4res opopen_confirm;
        
   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;
    /* Not for NFSv4.1 */
    case OP_OPEN_CONFIRM:  OPEN_CONFIRM4res opopen_confirm;
        

case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4res opopen_downgrade;

案例OP_OPEN_降级:OPEN_降级4res OPOPOPEN_降级;

    case OP_PUTFH:         PUTFH4res opputfh;
    case OP_PUTPUBFH:      PUTPUBFH4res opputpubfh;
        
    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;
    /* Not for NFSv4.1 */
    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;
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4res opsetclientid;
        
    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;
    /* Not for NFSv4.1 */
    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;
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4res opsetclientid;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM:
                           SETCLIENTID_CONFIRM4res
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4res opverify;
    case OP_WRITE:         WRITE4res opwrite;
        
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM:
                           SETCLIENTID_CONFIRM4res
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4res opverify;
    case OP_WRITE:         WRITE4res opwrite;
        
    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4res
                                   oprelease_lockowner;
        
    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4res
                                   oprelease_lockowner;
        
    /* Operations new to NFSv4.1 */
        
    /* Operations new to NFSv4.1 */
        

case OP_BACKCHANNEL_CTL: BACKCHANNEL_CTL4res opbackchannel_ctl;

案例OP_BACKCHANNEL_CTL:BACKCHANNEL_CTL4res opbackchannel_CTL;

case OP_BIND_CONN_TO_SESSION: BIND_CONN_TO_SESSION4res opbind_conn_to_session;

案例OP_BIND_CONN_TO_会话:BIND_CONN_TO_会话4res opbind_CONN_TO_会话;

case OP_EXCHANGE_ID: EXCHANGE_ID4res opexchange_id;

案例OP_EXCHANGE_ID:EXCHANGE_ID4res opexchange_ID;

case OP_CREATE_SESSION: CREATE_SESSION4res opcreate_session;

案例操作创建会话:创建会话4res操作创建会话;

case OP_DESTROY_SESSION: DESTROY_SESSION4res opdestroy_session;

案例操作销毁会话:销毁会话4res操作销毁会话;

case OP_FREE_STATEID: FREE_STATEID4res opfree_stateid;

案例OP_FREE_STATEID:FREE_STATEID 4res opfree_STATEID;

case OP_GET_DIR_DELEGATION: GET_DIR_DELEGATION4res opget_dir_delegation;

案例OP_GET_DIR_委派:GET_DIR_委派4res OP_DIR_委派;

case OP_GETDEVICEINFO: GETDEVICEINFO4res opgetdeviceinfo;

案例OP_GETDEVICEINFO:GETDEVICEINFO 4Res opgetdeviceinfo;

case OP_GETDEVICELIST: GETDEVICELIST4res opgetdevicelist;

案例OP_GETDEVICELIST:GETDEVICELIST4res opgetdevicelist;

    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4res oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4res oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4res oplayoutreturn;
        
    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4res oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4res oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4res oplayoutreturn;
        

case OP_SECINFO_NO_NAME: SECINFO_NO_NAME4res opsecinfo_no_name;

案例OP_SECINFO_NO_NAME:SECINFO NO_NAME 4res opsecinfo NO_NAME;

    case OP_SEQUENCE:      SEQUENCE4res opsequence;
    case OP_SET_SSV:       SET_SSV4res opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4res optest_stateid;
        
    case OP_SEQUENCE:      SEQUENCE4res opsequence;
    case OP_SET_SSV:       SET_SSV4res opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4res optest_stateid;
        

case OP_WANT_DELEGATION: WANT_DELEGATION4res opwant_delegation;

案例OP_WANT_委派:WANT_委派4res opwant_委派;

case OP_DESTROY_CLIENTID:

案例OP_销毁客户ID:

DESTROY_CLIENTID4res opdestroy_clientid;

销毁客户4选择销毁客户ID;

case OP_RECLAIM_COMPLETE: RECLAIM_COMPLETE4res opreclaim_complete;

案例操作-收回-完成:收回-完成4个操作-完成;

    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       ILLEGAL4res opillegal;
   };
        
    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       ILLEGAL4res opillegal;
   };
        
   struct COMPOUND4res {
           nfsstat4        status;
           utf8str_cs      tag;
           nfs_resop4      resarray<>;
   };
        
   struct COMPOUND4res {
           nfsstat4        status;
           utf8str_cs      tag;
           nfs_resop4      resarray<>;
   };
        
16.2.3. DESCRIPTION
16.2.3. 描述

The COMPOUND procedure is used to combine one or more NFSv4 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 until one of the operations has a status value other than NFS4_OK.

复合过程用于将一个或多个NFSv4操作组合到单个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. See Section 2.10.6.4 for a more detailed discussion.

在复合过程的处理过程中,服务器可能会发现它没有可用的资源来执行复合序列中的任何或所有操作。有关更详细的讨论,请参见第2.10.6.4节。

The server will generally choose between two methods of decoding the client's request. The first would be the traditional one-pass XDR decode. If there is an XDR decoding error in this case, the 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 the individual operations; the most interesting is the decode of attributes. In this case, the server may encounter an XDR decode error during the second pass. If it does, 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. For NFSv4.1, the value for this field is 1. 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”字段。对于NFSv4.1,此字段的值为1。如果服务器接收到一个复合过程,其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 zero and one are not defined for the COMPOUND procedure. Operation 2 is not defined and is reserved for future definition and use with minor versioning. If the server receives an operation array that contains operation 2 and the minorversion field has a value of 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

请注意,没有为复合过程定义操作0和操作1。操作2未定义,保留供将来定义,并与次要版本控制一起使用。如果服务器接收到包含操作2的操作数组,并且minorversion字段的值为零,则会将NFS4ERR_OP_非法错误返回给客户端,如下一段所述。如果操作数组包含操作2且minorversion字段为非零且服务器不支持次要版本,则服务器返回

error of NFS4ERR_MINOR_VERS_MISMATCH. Therefore, the NFS4ERR_MINOR_VERS_MISMATCH error takes precedence over all other errors.

NFS4ERR_MINOR_VERS_失配错误。因此,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). 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 be set to NFS4ERR_OP_ILLEGAL. The COMPOUND procedure's return results will also be NFS4ERR_OP_ILLEGAL.

服务器接收到的请求可能包含小于第一个合法操作(OP_访问)或大于最后一个合法操作(OP_释放锁定所有者)的操作。在这种情况下,服务器的响应将把操作码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_复合过程的标记字段。

16.2.3.1. Current Filehandle and Stateid
16.2.3.1. 当前文件句柄和状态ID

The COMPOUND procedure offers a simple environment for the execution of the operations specified by the client. The first two relate to the filehandle while the second two relate to the current stateid.

复合过程为执行客户机指定的操作提供了一个简单的环境。前两个与filehandle相关,而后两个与当前stateid相关。

16.2.3.1.1. Current Filehandle
16.2.3.1.1. 当前文件句柄

The current and saved filehandles are used throughout the protocol. Most operations implicitly use the current filehandle as an argument, and many set the current filehandle as part of the results. The combination of client-specified sequences of operations and current and saved filehandle arguments and results allows for greater protocol flexibility. The best or easiest example of current filehandle usage is a sequence like the following:

当前和保存的文件句柄在整个协议中使用。大多数操作隐式使用当前文件句柄作为参数,许多操作将当前文件句柄设置为结果的一部分。客户端指定的操作序列与当前和保存的filehandle参数和结果的组合允许更大的协议灵活性。当前filehandle用法的最佳或最简单示例是如下所示的序列:

         PUTFH fh1              {fh1}
         LOOKUP "compA"         {fh2}
         GETATTR                {fh2}
         LOOKUP "compB"         {fh3}
         GETATTR                {fh3}
         LOOKUP "compC"         {fh4}
         GETATTR                {fh4}
         GETFH
        
         PUTFH fh1              {fh1}
         LOOKUP "compA"         {fh2}
         GETATTR                {fh2}
         LOOKUP "compB"         {fh3}
         GETATTR                {fh3}
         LOOKUP "compC"         {fh4}
         GETATTR                {fh4}
         GETFH
        

Figure 2

图2

In this example, the PUTFH (Section 18.19) operation explicitly sets the current filehandle value while the result of each LOOKUP operation sets the current filehandle value to the resultant file system object. Also, the client is able to insert GETATTR operations using the current filehandle as an argument.

在本例中,PUTFH(第18.19节)操作显式设置当前filehandle值,而每个查找操作的结果将当前filehandle值设置为结果文件系统对象。此外,客户端还可以使用当前文件句柄作为参数插入GETATTR操作。

The PUTROOTFH (Section 18.21) and PUTPUBFH (Section 18.20) operations also set the current filehandle. The above example would replace "PUTFH fh1" with PUTROOTFH or PUTPUBFH with no filehandle argument in order to achieve the same effect (on the assumption that "compA" is directly below the root of the namespace).

PUTROOTFH(第18.21节)和PUTPUBFH(第18.20节)操作也设置当前文件句柄。上面的示例将“PUTFH fh1”替换为PUTROOTFH或PUTPUBFH(不带filehandle参数),以实现相同的效果(假设“compA”位于名称空间根的正下方)。

Along with the current filehandle, there is a saved filehandle. While the current filehandle is set as the result of operations like LOOKUP, the saved filehandle must be set directly with the use of the SAVEFH operation. The SAVEFH operation copies the current filehandle value to the saved value. The saved filehandle value is used in combination with the current filehandle value for the LINK and RENAME operations. The RESTOREFH operation will copy the saved filehandle value to the current filehandle value; as a result, the saved filehandle value may be used a sort of "scratch" area for the client's series of operations.

除了当前文件句柄之外,还有一个已保存的文件句柄。虽然当前文件句柄设置为查找等操作的结果,但必须使用SAVEFH操作直接设置保存的文件句柄。SAVEFH操作将当前文件句柄值复制到保存的值。保存的filehandle值与链接和重命名操作的当前filehandle值结合使用。RESTOREFH操作将保存的filehandle值复制到当前filehandle值;因此,保存的filehandle值可能会用作客户端一系列操作的一种“暂存”区域。

16.2.3.1.2. Current Stateid
16.2.3.1.2. 当前状态ID

With NFSv4.1, additions of a current stateid and a saved stateid have been made to the COMPOUND processing environment; this allows for the passing of stateids between operations. There are no changes to the syntax of the protocol, only changes to the semantics of a few operations.

使用NFSv4.1,在复合处理环境中添加了当前stateid和保存的stateid;这允许在操作之间传递stateID。协议的语法没有变化,只有少数操作的语义变化。

A "current stateid" is the stateid that is associated with the current filehandle. The current stateid may only be changed by an operation that modifies the current filehandle or returns a stateid.

“current stateid”是与当前文件句柄关联的stateid。当前stateid只能由修改当前文件句柄或返回stateid的操作更改。

   If an operation returns a stateid, it MUST set the current stateid to
   the returned value.  If an operation sets the current filehandle but
   does not return a stateid, the current stateid MUST be set to the
   all-zeros special stateid, i.e., (seqid, other) = (0, 0).  If an
   operation uses a stateid as an argument but does not return a
   stateid, the current stateid MUST NOT be changed.  For example,
   PUTFH, PUTROOTFH, and PUTPUBFH will change the current server state
   from {ocfh, (osid)} to {cfh, (0, 0)}, while LOCK will change the
   current state from {cfh, (osid} to {cfh, (nsid)}.  Operations like
   LOOKUP that transform a current filehandle and component name into a
   new current filehandle will also change the current state to {0, 0}.
   The SAVEFH and RESTOREFH operations will save and restore both the
   current filehandle and the current stateid as a set.
        
   If an operation returns a stateid, it MUST set the current stateid to
   the returned value.  If an operation sets the current filehandle but
   does not return a stateid, the current stateid MUST be set to the
   all-zeros special stateid, i.e., (seqid, other) = (0, 0).  If an
   operation uses a stateid as an argument but does not return a
   stateid, the current stateid MUST NOT be changed.  For example,
   PUTFH, PUTROOTFH, and PUTPUBFH will change the current server state
   from {ocfh, (osid)} to {cfh, (0, 0)}, while LOCK will change the
   current state from {cfh, (osid} to {cfh, (nsid)}.  Operations like
   LOOKUP that transform a current filehandle and component name into a
   new current filehandle will also change the current state to {0, 0}.
   The SAVEFH and RESTOREFH operations will save and restore both the
   current filehandle and the current stateid as a set.
        

The following example is the common case of a simple READ operation with a normal stateid showing that the PUTFH initializes the current stateid to (0, 0). The subsequent READ with stateid (sid1) leaves the current stateid unchanged.

下面的示例是一个简单的读取操作的常见情况,该操作具有一个正常的stateid,显示PUTFH将当前stateid初始化为(0,0)。使用stateid(sid1)进行的后续读取将保持当前stateid不变。

       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (sid1), 0, 1024      {fh1, (0, 0)} -> {fh1, (0, 0)}
        
       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (sid1), 0, 1024      {fh1, (0, 0)} -> {fh1, (0, 0)}
        

Figure 3

图3

This next example performs an OPEN with the root filehandle and, as a result, generates stateid (sid1). The next operation specifies the READ with the argument stateid set such that (seqid, other) are equal to (1, 0), but the current stateid set by the previous operation is actually used when the operation is evaluated. This allows correct interaction with any existing, potentially conflicting, locks.

下一个示例使用根filehandle执行OPEN,结果生成stateid(sid1)。下一个操作使用参数stateid集指定读取,以便(seqid,other)等于(1,0),但在计算操作时实际使用上一个操作设置的当前stateid。这允许与任何现有的、潜在冲突的锁进行正确的交互。

       PUTROOTFH                             - -> {fh1, (0, 0)}
       OPEN "compA"              {fh1, (0, 0)} -> {fh2, (sid1)}
       READ (1, 0), 0, 1024      {fh2, (sid1)} -> {fh2, (sid1)}
       CLOSE (1, 0)              {fh2, (sid1)} -> {fh2, (sid2)}
        
       PUTROOTFH                             - -> {fh1, (0, 0)}
       OPEN "compA"              {fh1, (0, 0)} -> {fh2, (sid1)}
       READ (1, 0), 0, 1024      {fh2, (sid1)} -> {fh2, (sid1)}
       CLOSE (1, 0)              {fh2, (sid1)} -> {fh2, (sid2)}
        

Figure 4

图4

This next example is similar to the second in how it passes the stateid sid2 generated by the LOCK operation to the next READ operation. This allows the client to explicitly surround a single I/O operation with a lock and its appropriate stateid to guarantee correctness with other client locks. The example also shows how SAVEFH and RESTOREFH can save and later reuse a filehandle and stateid, passing them as the current filehandle and stateid to a READ operation.

下一个示例与第二个示例类似,它将锁操作生成的stateid sid2传递给下一个读取操作。这允许客户机显式地使用锁及其相应的stateid围绕单个I/O操作,以保证其他客户机锁的正确性。该示例还显示了SAVEFH和RESTOREFH如何保存和稍后重用filehandle和stateid,并将它们作为当前filehandle和stateid传递给读取操作。

       PUTFH fh1                             - -> {fh1, (0, 0)}
       LOCK 0, 1024, (sid1)      {fh1, (sid1)} -> {fh1, (sid2)}
       READ (1, 0), 0, 1024      {fh1, (sid2)} -> {fh1, (sid2)}
       LOCKU 0, 1024, (1, 0)     {fh1, (sid2)} -> {fh1, (sid3)}
       SAVEFH                    {fh1, (sid3)} -> {fh1, (sid3)}
        
       PUTFH fh1                             - -> {fh1, (0, 0)}
       LOCK 0, 1024, (sid1)      {fh1, (sid1)} -> {fh1, (sid2)}
       READ (1, 0), 0, 1024      {fh1, (sid2)} -> {fh1, (sid2)}
       LOCKU 0, 1024, (1, 0)     {fh1, (sid2)} -> {fh1, (sid3)}
       SAVEFH                    {fh1, (sid3)} -> {fh1, (sid3)}
        
       PUTFH fh2                 {fh1, (sid3)} -> {fh2, (0, 0)}
       WRITE (1, 0), 0, 1024     {fh2, (0, 0)} -> {fh2, (0, 0)}
        
       PUTFH fh2                 {fh1, (sid3)} -> {fh2, (0, 0)}
       WRITE (1, 0), 0, 1024     {fh2, (0, 0)} -> {fh2, (0, 0)}
        
       RESTOREFH                 {fh2, (0, 0)} -> {fh1, (sid3)}
       READ (1, 0), 1024, 1024   {fh1, (sid3)} -> {fh1, (sid3)}
        
       RESTOREFH                 {fh2, (0, 0)} -> {fh1, (sid3)}
       READ (1, 0), 1024, 1024   {fh1, (sid3)} -> {fh1, (sid3)}
        

Figure 5

图5

The final example shows a disallowed use of the current stateid. The client is attempting to implicitly pass an anonymous special stateid, (0,0), to the READ operation. The server MUST return NFS4ERR_BAD_STATEID in the reply to the READ operation.

最后一个示例显示不允许使用当前stateid。客户端正试图将匿名特殊stateid(0,0)隐式传递给读取操作。服务器必须在对读取操作的回复中返回NFS4ERR_BAD_STATEID。

       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (1, 0), 0, 1024      {fh1, (0, 0)} -> NFS4ERR_BAD_STATEID
        
       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (1, 0), 0, 1024      {fh1, (0, 0)} -> NFS4ERR_BAD_STATEID
        

Figure 6

图6

16.2.4. ERRORS
16.2.4. 错误

COMPOUND will of course return every error that each operation on the fore channel can return (see Table 6). However, if COMPOUND returns zero operations, obviously the error returned by COMPOUND has nothing to do with an error returned by an operation. The list of errors COMPOUND will return if it processes zero operations include:

复合当然会返回前通道上的每个操作可以返回的每个错误(见表6)。然而,如果component返回零操作,那么显然component返回的错误与操作返回的错误无关。如果处理零操作,将返回错误列表,包括:

COMPOUND Error Returns

复合错误返回

   +------------------------------+------------------------------------+
   | Error                        | Notes                              |
   +------------------------------+------------------------------------+
   | NFS4ERR_BADCHAR              | The tag argument has a character   |
   |                              | the replier does not support.      |
   | NFS4ERR_BADXDR               |                                    |
   | NFS4ERR_DELAY                |                                    |
   | NFS4ERR_INVAL                | The tag argument is not in UTF-8   |
   |                              | encoding.                          |
   | NFS4ERR_MINOR_VERS_MISMATCH  |                                    |
   | NFS4ERR_SERVERFAULT          |                                    |
   | NFS4ERR_TOO_MANY_OPS         |                                    |
   | NFS4ERR_REP_TOO_BIG          |                                    |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE |                                    |
   | NFS4ERR_REQ_TOO_BIG          |                                    |
   +------------------------------+------------------------------------+
        
   +------------------------------+------------------------------------+
   | Error                        | Notes                              |
   +------------------------------+------------------------------------+
   | NFS4ERR_BADCHAR              | The tag argument has a character   |
   |                              | the replier does not support.      |
   | NFS4ERR_BADXDR               |                                    |
   | NFS4ERR_DELAY                |                                    |
   | NFS4ERR_INVAL                | The tag argument is not in UTF-8   |
   |                              | encoding.                          |
   | NFS4ERR_MINOR_VERS_MISMATCH  |                                    |
   | NFS4ERR_SERVERFAULT          |                                    |
   | NFS4ERR_TOO_MANY_OPS         |                                    |
   | NFS4ERR_REP_TOO_BIG          |                                    |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE |                                    |
   | NFS4ERR_REQ_TOO_BIG          |                                    |
   +------------------------------+------------------------------------+
        

Table 9

表9

17. Operations: REQUIRED, RECOMMENDED, or OPTIONAL
17. 操作:必需、推荐或可选

The following tables summarize the operations of the NFSv4.1 protocol and the corresponding designation of REQUIRED, RECOMMENDED, and OPTIONAL to implement or MUST NOT implement. The designation of MUST NOT implement is reserved for those operations that were defined in NFSv4.0 and MUST NOT be implemented in NFSv4.1.

下表总结了NFSv4.1协议的操作以及需要、建议和可选实施或不得实施的相应名称。不得实施的指定保留用于NFSv4.0中定义的操作,且不得在NFSv4.1中实施。

For the most part, the REQUIRED, RECOMMENDED, or OPTIONAL designation for operations sent by the client is for the server implementation. The client is generally required to implement the operations needed for the operating environment for which it serves. For example, a read-only NFSv4.1 client would have no need to implement the WRITE operation and is not required to do so.

在大多数情况下,客户机发送的操作的必需、推荐或可选名称用于服务器实现。客户机通常需要实现其所服务的操作环境所需的操作。例如,只读NFSv4.1客户端不需要实现写操作,也不需要这样做。

The REQUIRED or OPTIONAL designation for callback operations sent by the server is for both the client and server. Generally, the client has the option of creating the backchannel and sending the operations on the fore channel that will be a catalyst for the server sending callback operations. A partial exception is CB_RECALL_SLOT; the only way the client can avoid supporting this operation is by not creating a backchannel.

由服务器发送的回调操作的必需或可选指定同时适用于客户端和服务器。通常,客户机可以选择创建后通道并在前通道上发送操作,这将成为服务器发送回调操作的催化剂。部分例外情况是CB_RECALL_插槽;客户端避免支持此操作的唯一方法是不创建反向通道。

Since this is a summary of the operations and their designation, there are subtleties that are not presented here. Therefore, if there is a question of the requirements of implementation, the operation descriptions themselves must be consulted along with other relevant explanatory text within this specification.

由于这是操作及其指定的摘要,因此这里没有介绍一些微妙之处。因此,如果存在实施要求的问题,必须参考操作说明本身以及本规范中的其他相关解释文本。

The abbreviations used in the second and third columns of the table are defined as follows.

表中第二列和第三列中使用的缩写定义如下。

REQ REQUIRED to implement

需要执行的请求

REC RECOMMEND to implement

建议实施

OPT OPTIONAL to implement

选择可选项以实现

MNI MUST NOT implement

MNI不得实施

For the NFSv4.1 features that are OPTIONAL, the operations that support those features are OPTIONAL, and the server would return NFS4ERR_NOTSUPP in response to the client's use of those operations. If an OPTIONAL feature is supported, it is possible that a set of operations related to the feature become REQUIRED to implement. The third column of the table designates the feature(s) and if the operation is REQUIRED or OPTIONAL in the presence of support for the feature.

对于可选的NFSv4.1功能,支持这些功能的操作是可选的,服务器将返回NFS4ERR_NOTSUPP以响应客户端对这些操作的使用。如果支持可选功能,则可能需要执行一组与该功能相关的操作。表格的第三列指定了功能,以及在支持该功能的情况下,该操作是必需的还是可选的。

The OPTIONAL features identified and their abbreviations are as follows:

确定的可选功能及其缩写如下:

pNFS Parallel NFS

并行NFS

FDELG File Delegations

文件委托

DDELG Directory Delegations

DDELG目录授权

Operations

操作

   +----------------------+------------+--------------+----------------+
   | Operation            | REQ, REC,  | Feature      | Definition     |
   |                      | OPT, or    | (REQ, REC,   |                |
   |                      | MNI        | or OPT)      |                |
   +----------------------+------------+--------------+----------------+
   | ACCESS               | REQ        |              | Section 18.1   |
   | BACKCHANNEL_CTL      | REQ        |              | Section 18.33  |
   | BIND_CONN_TO_SESSION | REQ        |              | Section 18.34  |
   | CLOSE                | REQ        |              | Section 18.2   |
   | COMMIT               | REQ        |              | Section 18.3   |
   | CREATE               | REQ        |              | Section 18.4   |
   | CREATE_SESSION       | REQ        |              | Section 18.36  |
   | DELEGPURGE           | OPT        | FDELG (REQ)  | Section 18.5   |
   | DELEGRETURN          | OPT        | FDELG,       | Section 18.6   |
   |                      |            | DDELG, pNFS  |                |
   |                      |            | (REQ)        |                |
   | DESTROY_CLIENTID     | REQ        |              | Section 18.50  |
   | DESTROY_SESSION      | REQ        |              | Section 18.37  |
   | EXCHANGE_ID          | REQ        |              | Section 18.35  |
   | FREE_STATEID         | REQ        |              | Section 18.38  |
   | GETATTR              | REQ        |              | Section 18.7   |
   | GETDEVICEINFO        | OPT        | pNFS (REQ)   | Section 18.40  |
   | GETDEVICELIST        | OPT        | pNFS (OPT)   | Section 18.41  |
   | GETFH                | REQ        |              | Section 18.8   |
   | GET_DIR_DELEGATION   | OPT        | DDELG (REQ)  | Section 18.39  |
   | LAYOUTCOMMIT         | OPT        | pNFS (REQ)   | Section 18.42  |
   | LAYOUTGET            | OPT        | pNFS (REQ)   | Section 18.43  |
   | LAYOUTRETURN         | OPT        | pNFS (REQ)   | Section 18.44  |
   | LINK                 | OPT        |              | Section 18.9   |
   | LOCK                 | REQ        |              | Section 18.10  |
   | LOCKT                | REQ        |              | Section 18.11  |
   | LOCKU                | REQ        |              | Section 18.12  |
   | LOOKUP               | REQ        |              | Section 18.13  |
   | LOOKUPP              | REQ        |              | Section 18.14  |
   | NVERIFY              | REQ        |              | Section 18.15  |
   | OPEN                 | REQ        |              | Section 18.16  |
   | OPENATTR             | OPT        |              | Section 18.17  |
   | OPEN_CONFIRM         | MNI        |              | N/A            |
   | OPEN_DOWNGRADE       | REQ        |              | Section 18.18  |
   | PUTFH                | REQ        |              | Section 18.19  |
   | PUTPUBFH             | REQ        |              | Section 18.20  |
   | PUTROOTFH            | REQ        |              | Section 18.21  |
   | READ                 | REQ        |              | Section 18.22  |
   | READDIR              | REQ        |              | Section 18.23  |
        
   +----------------------+------------+--------------+----------------+
   | Operation            | REQ, REC,  | Feature      | Definition     |
   |                      | OPT, or    | (REQ, REC,   |                |
   |                      | MNI        | or OPT)      |                |
   +----------------------+------------+--------------+----------------+
   | ACCESS               | REQ        |              | Section 18.1   |
   | BACKCHANNEL_CTL      | REQ        |              | Section 18.33  |
   | BIND_CONN_TO_SESSION | REQ        |              | Section 18.34  |
   | CLOSE                | REQ        |              | Section 18.2   |
   | COMMIT               | REQ        |              | Section 18.3   |
   | CREATE               | REQ        |              | Section 18.4   |
   | CREATE_SESSION       | REQ        |              | Section 18.36  |
   | DELEGPURGE           | OPT        | FDELG (REQ)  | Section 18.5   |
   | DELEGRETURN          | OPT        | FDELG,       | Section 18.6   |
   |                      |            | DDELG, pNFS  |                |
   |                      |            | (REQ)        |                |
   | DESTROY_CLIENTID     | REQ        |              | Section 18.50  |
   | DESTROY_SESSION      | REQ        |              | Section 18.37  |
   | EXCHANGE_ID          | REQ        |              | Section 18.35  |
   | FREE_STATEID         | REQ        |              | Section 18.38  |
   | GETATTR              | REQ        |              | Section 18.7   |
   | GETDEVICEINFO        | OPT        | pNFS (REQ)   | Section 18.40  |
   | GETDEVICELIST        | OPT        | pNFS (OPT)   | Section 18.41  |
   | GETFH                | REQ        |              | Section 18.8   |
   | GET_DIR_DELEGATION   | OPT        | DDELG (REQ)  | Section 18.39  |
   | LAYOUTCOMMIT         | OPT        | pNFS (REQ)   | Section 18.42  |
   | LAYOUTGET            | OPT        | pNFS (REQ)   | Section 18.43  |
   | LAYOUTRETURN         | OPT        | pNFS (REQ)   | Section 18.44  |
   | LINK                 | OPT        |              | Section 18.9   |
   | LOCK                 | REQ        |              | Section 18.10  |
   | LOCKT                | REQ        |              | Section 18.11  |
   | LOCKU                | REQ        |              | Section 18.12  |
   | LOOKUP               | REQ        |              | Section 18.13  |
   | LOOKUPP              | REQ        |              | Section 18.14  |
   | NVERIFY              | REQ        |              | Section 18.15  |
   | OPEN                 | REQ        |              | Section 18.16  |
   | OPENATTR             | OPT        |              | Section 18.17  |
   | OPEN_CONFIRM         | MNI        |              | N/A            |
   | OPEN_DOWNGRADE       | REQ        |              | Section 18.18  |
   | PUTFH                | REQ        |              | Section 18.19  |
   | PUTPUBFH             | REQ        |              | Section 18.20  |
   | PUTROOTFH            | REQ        |              | Section 18.21  |
   | READ                 | REQ        |              | Section 18.22  |
   | READDIR              | REQ        |              | Section 18.23  |
        
   | READLINK             | OPT        |              | Section 18.24  |
   | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
   | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
   | REMOVE               | REQ        |              | Section 18.25  |
   | RENAME               | REQ        |              | Section 18.26  |
   | RENEW                | MNI        |              | N/A            |
   | RESTOREFH            | REQ        |              | Section 18.27  |
   | SAVEFH               | REQ        |              | Section 18.28  |
   | SECINFO              | REQ        |              | Section 18.29  |
   | SECINFO_NO_NAME      | REC        | pNFS file    | Section 18.45, |
   |                      |            | layout (REQ) | Section 13.12  |
   | SEQUENCE             | REQ        |              | Section 18.46  |
   | SETATTR              | REQ        |              | Section 18.30  |
   | SETCLIENTID          | MNI        |              | N/A            |
   | SETCLIENTID_CONFIRM  | MNI        |              | N/A            |
   | SET_SSV              | REQ        |              | Section 18.47  |
   | TEST_STATEID         | REQ        |              | Section 18.48  |
   | VERIFY               | REQ        |              | Section 18.31  |
   | WANT_DELEGATION      | OPT        | FDELG (OPT)  | Section 18.49  |
   | WRITE                | REQ        |              | Section 18.32  |
   +----------------------+------------+--------------+----------------+
        
   | READLINK             | OPT        |              | Section 18.24  |
   | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
   | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
   | REMOVE               | REQ        |              | Section 18.25  |
   | RENAME               | REQ        |              | Section 18.26  |
   | RENEW                | MNI        |              | N/A            |
   | RESTOREFH            | REQ        |              | Section 18.27  |
   | SAVEFH               | REQ        |              | Section 18.28  |
   | SECINFO              | REQ        |              | Section 18.29  |
   | SECINFO_NO_NAME      | REC        | pNFS file    | Section 18.45, |
   |                      |            | layout (REQ) | Section 13.12  |
   | SEQUENCE             | REQ        |              | Section 18.46  |
   | SETATTR              | REQ        |              | Section 18.30  |
   | SETCLIENTID          | MNI        |              | N/A            |
   | SETCLIENTID_CONFIRM  | MNI        |              | N/A            |
   | SET_SSV              | REQ        |              | Section 18.47  |
   | TEST_STATEID         | REQ        |              | Section 18.48  |
   | VERIFY               | REQ        |              | Section 18.31  |
   | WANT_DELEGATION      | OPT        | FDELG (OPT)  | Section 18.49  |
   | WRITE                | REQ        |              | Section 18.32  |
   +----------------------+------------+--------------+----------------+
        

Callback Operations

回调操作

   +-------------------------+-----------+-------------+---------------+
   | Operation               | REQ, REC, | Feature     | Definition    |
   |                         | OPT, or   | (REQ, REC,  |               |
   |                         | MNI       | or OPT)     |               |
   +-------------------------+-----------+-------------+---------------+
   | CB_GETATTR              | OPT       | FDELG (REQ) | Section 20.1  |
   | CB_LAYOUTRECALL         | OPT       | pNFS (REQ)  | Section 20.3  |
   | CB_NOTIFY               | OPT       | DDELG (REQ) | Section 20.4  |
   | CB_NOTIFY_DEVICEID      | OPT       | pNFS (OPT)  | Section 20.12 |
   | CB_NOTIFY_LOCK          | OPT       |             | Section 20.11 |
   | CB_PUSH_DELEG           | OPT       | FDELG (OPT) | Section 20.5  |
   | CB_RECALL               | OPT       | FDELG,      | Section 20.2  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_ANY           | OPT       | FDELG,      | Section 20.6  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_SLOT          | REQ       |             | Section 20.8  |
   | CB_RECALLABLE_OBJ_AVAIL | OPT       | DDELG, pNFS | Section 20.7  |
   |                         |           | (REQ)       |               |
   | CB_SEQUENCE             | OPT       | FDELG,      | Section 20.9  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_WANTS_CANCELLED      | OPT       | FDELG,      | Section 20.10 |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   +-------------------------+-----------+-------------+---------------+
        
   +-------------------------+-----------+-------------+---------------+
   | Operation               | REQ, REC, | Feature     | Definition    |
   |                         | OPT, or   | (REQ, REC,  |               |
   |                         | MNI       | or OPT)     |               |
   +-------------------------+-----------+-------------+---------------+
   | CB_GETATTR              | OPT       | FDELG (REQ) | Section 20.1  |
   | CB_LAYOUTRECALL         | OPT       | pNFS (REQ)  | Section 20.3  |
   | CB_NOTIFY               | OPT       | DDELG (REQ) | Section 20.4  |
   | CB_NOTIFY_DEVICEID      | OPT       | pNFS (OPT)  | Section 20.12 |
   | CB_NOTIFY_LOCK          | OPT       |             | Section 20.11 |
   | CB_PUSH_DELEG           | OPT       | FDELG (OPT) | Section 20.5  |
   | CB_RECALL               | OPT       | FDELG,      | Section 20.2  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_ANY           | OPT       | FDELG,      | Section 20.6  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_SLOT          | REQ       |             | Section 20.8  |
   | CB_RECALLABLE_OBJ_AVAIL | OPT       | DDELG, pNFS | Section 20.7  |
   |                         |           | (REQ)       |               |
   | CB_SEQUENCE             | OPT       | FDELG,      | Section 20.9  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_WANTS_CANCELLED      | OPT       | FDELG,      | Section 20.10 |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   +-------------------------+-----------+-------------+---------------+
        
18. NFSv4.1 Operations
18. NFSv4.1操作
18.1. Operation 3: ACCESS - Check Access Rights
18.1. 操作3:访问-检查访问权限
18.1.1. ARGUMENTS
18.1.1. 论据
   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;
   };
        
18.1.2. RESULTS
18.1.2. 后果
   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;
   };
        
18.1.3. DESCRIPTION
18.1.3. 描述

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 reply's supported and access fields MUST NOT contain more values than originally set in the request's access field. For example, if the client sends an ACCESS operation with just the ACCESS4_READ value set and the server supports this value, the server MUST NOT set more than ACCESS4_READ in the supported field even if it could have reliably checked other values.

请注意,回复的“支持”和“访问”字段中包含的值不得超过请求的“访问”字段中最初设置的值。例如,如果客户端发送的访问操作仅设置了ACCESS4_READ值,而服务器支持此值,则服务器在supported字段中设置的ACCESS4_READ值不得超过ACCESS4_READ,即使它可以可靠地检查其他值。

The reply's access field MUST NOT contain more values than the supported field.

回复的访问字段不能包含比支持的字段更多的值。

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 do 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 a regular file (no meaning for a directory).

ACCESS4\u执行一个常规文件(对目录没有意义)。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

ACCESS4_EXECUTE is a challenging semantic to implement because NFS provides remote file access, not remote execution. This leads to the following:

ACCESS4_EXECUTE是一个很难实现的语义,因为NFS提供远程文件访问,而不是远程执行。这导致以下情况:

o Whether or not a regular file is executable ought to be the responsibility of the NFS client and not the server. And yet the ACCESS operation is specified to seemingly require a server to own that responsibility.

o 常规文件是否可执行应由NFS客户端而不是服务器负责。然而,访问操作被指定为似乎要求服务器承担该责任。

o When a client executes a regular file, it has to read the file from the server. Strictly speaking, the server should not allow the client to read a file being executed unless the user has read permissions on the file. Requiring explicit read permissions on executable files in order to access them over NFS is not going to be acceptable to some users and storage administrators. Historically, NFS servers have allowed a user to READ a file if the user has execute access to the file.

o 当客户端执行常规文件时,它必须从服务器读取该文件。严格来说,服务器不应允许客户端读取正在执行的文件,除非用户对该文件具有读取权限。某些用户和存储管理员不接受要求对可执行文件具有显式读取权限才能通过NFS访问这些文件。历史上,如果用户具有文件的执行权限,NFS服务器允许用户读取该文件。

As a practical example, the UNIX specification [52] states that an implementation claiming conformance to UNIX may indicate in the access() programming interface's result that a privileged user has execute rights, even if no execute permission bits are set on the regular file's attributes. It is possible to claim conformance to the UNIX specification and instead not indicate execute rights in that situation, which is true for some operating environments. Suppose the operating environments of the client and server are implementing the access() semantics for privileged users differently, and the ACCESS operation implementations of the client and server follow their respective access() semantics. This can cause undesired behavior:

作为一个实际示例,UNIX规范[52]指出,声称符合UNIX的实现可能会在access()编程接口的结果中表明特权用户具有执行权限,即使常规文件的属性上没有设置执行权限位。可以声明符合UNIX规范,而不是在这种情况下指明执行权限,这在某些操作环境中是正确的。假设客户端和服务器的操作环境为特权用户实现了不同的access()语义,客户端和服务器的访问操作实现遵循各自的access()语义。这可能会导致不期望的行为:

o Suppose the client's access() interface returns X_OK if the user is privileged and no execute permission bits are set on the regular file's attribute, and the server's access() interface does

o 假设客户机的access()接口返回X_OK,前提是用户具有特权,并且在常规文件的属性上没有设置执行权限位,而服务器的access()接口则返回X_OK

not return X_OK in that situation. Then the client will be unable to execute files stored on the NFS server that could be executed if stored on a non-NFS file system.

在那种情况下不返回X_OK。然后,客户端将无法执行存储在NFS服务器上的文件,如果这些文件存储在非NFS文件系统上,则可以执行这些文件。

o Suppose the client's access() interface does not return X_OK if the user is privileged, and no execute permission bits are set on the regular file's attribute, and the server's access() interface does return X_OK in that situation. Then:

o 假设如果用户具有特权,客户端的access()接口不会返回X_OK,并且在常规文件的属性上没有设置执行权限位,并且服务器的access()接口在这种情况下会返回X_OK。然后:

* The client will be able to execute files stored on the NFS server that could be executed if stored on a non-NFS file system, unless the client's execution subsystem also checks for execute permission bits.

* 客户机将能够执行存储在NFS服务器上的文件,如果存储在非NFS文件系统上,则可以执行这些文件,除非客户机的执行子系统还检查执行权限位。

* Even if the execution subsystem is checking for execute permission bits, there are more potential issues. For example, suppose the client is invoking access() to build a "path search table" of all executable files in the user's "search path", where the path is a list of directories each containing executable files. Suppose there are two files each in separate directories of the search path, such that files have the same component name. In the first directory the file has no execute permission bits set, and in the second directory the file has execute bits set. The path search table will indicate that the first directory has the executable file, but the execute subsystem will fail to execute it. The command shell might fail to try the second file in the second directory. And even if it did, this is a potential performance issue. Clearly, the desired outcome for the client is for the path search table to not contain the first file.

* 即使执行子系统正在检查执行权限位,也存在更多潜在问题。例如,假设客户端调用access()来构建用户“搜索路径”中所有可执行文件的“路径搜索表”,其中路径是每个包含可执行文件的目录列表。假设在搜索路径的不同目录中各有两个文件,这样文件就具有相同的组件名称。在第一个目录中,文件没有设置执行权限位,在第二个目录中,文件设置了执行位。路径搜索表将指示第一个目录具有可执行文件,但执行子系统将无法执行该文件。命令shell可能无法尝试第二个目录中的第二个文件。即使是这样,这也是一个潜在的性能问题。显然,客户机所期望的结果是路径搜索表不包含第一个文件。

To deal with the problems described above, the "smart client, stupid server" principle is used. The client owns overall responsibility for determining execute access and relies on the server to parse the execution permissions within the file's mode, acl, and dacl attributes. The rules for the client and server follow:

为了解决上述问题,使用了“智能客户端,愚蠢服务器”原则。客户端全权负责确定执行访问权限,并依赖服务器解析文件的mode、acl和dacl属性中的执行权限。客户端和服务器的规则如下:

o If the client is sending ACCESS in order to determine if the user can read the file, the client SHOULD set ACCESS4_READ in the request's access field.

o 如果客户端发送访问权限以确定用户是否可以读取文件,则客户端应在请求的访问字段中设置ACCESS4_read。

o If the client's operating environment only grants execution to the user if the user has execute access according to the execute permissions in the mode, acl, and dacl attributes, then if the client wants to determine execute access, the client SHOULD send an ACCESS request with ACCESS4_EXECUTE bit set in the request's access field.

o 如果客户机的操作环境仅在用户根据模式、acl和dacl属性中的执行权限具有执行权限时才向用户授予执行权限,则如果客户机希望确定执行权限,则客户机应发送一个访问请求,并在请求的访问字段中设置ACCESS4_execute位。

o If the client's operating environment grants execution to the user even if the user does not have execute access according to the execute permissions in the mode, acl, and dacl attributes, then if the client wants to determine execute access, it SHOULD send an ACCESS request with both the ACCESS4_EXECUTE and ACCESS4_READ bits set in the request's access field. This way, if any read or execute permission grants the user read or execute access (or if the server interprets the user as privileged), as indicated by the presence of ACCESS4_EXECUTE and/or ACCESS4_READ in the reply's access field, the client will be able to grant the user execute access to the file.

o 如果客户机的操作环境根据模式、acl和dacl属性中的执行权限向用户授予执行权限,即使用户没有执行权限,那么如果客户机希望确定执行权限,它应该发送一个访问请求,并在请求的访问字段中设置ACCESS4_EXECUTE和ACCESS4_READ位。这样,如果任何读取或执行权限授予用户读取或执行访问权限(或者如果服务器将用户解释为特权用户),如回复的访问字段中存在ACCESS4_execute和/或ACCESS4_read所示,则客户端将能够授予用户对文件的执行访问权限。

o If the server supports execute permission bits, or some other method for denoting executability (e.g., the suffix of the name of the file might indicate execute), it MUST check only execute permissions, not read permissions, when determining whether or not the reply will have ACCESS4_EXECUTE set in the access field. The server MUST NOT also examine read permission bits when determining whether or not the reply will have ACCESS4_EXECUTE set in the access field. Even if the server's operating environment would grant execute access to the user (e.g., the user is privileged), the server MUST NOT reply with ACCESS4_EXECUTE set in reply's access field unless there is at least one execute permission bit set in the mode, acl, or dacl attributes. In the case of acl and dacl, the "one execute permission bit" MUST be an ACE4_EXECUTE bit set in an ALLOW ACE.

o 如果服务器支持执行权限位,或其他表示可执行性的方法(例如,文件名的后缀可能表示执行),则在确定回复是否在访问字段中设置了ACCESS4_execute时,服务器必须只检查执行权限,而不检查读取权限。在确定回复是否在访问字段中设置了ACCESS4\u EXECUTE时,服务器也不得检查读取权限位。即使服务器的操作环境将向用户授予执行访问权限(例如,用户具有特权),服务器也不得在回复的访问字段中设置ACCESS4_execute,除非在模式、acl或dacl属性中至少设置了一个执行权限位。对于acl和dacl,“一个执行权限位”必须是在允许ACE中设置的ACE4_执行位。

o If the server does not support execute permission bits or some other method for denoting executability, it MUST NOT set ACCESS4_EXECUTE in the reply's supported and access fields. If the client set ACCESS4_EXECUTE in the ACCESS request's access field, and ACCESS4_EXECUTE is not set in the reply's supported field, then the client will have to send an ACCESS request with the ACCESS4_READ bit set in the request's access field.

o 如果服务器不支持执行权限位或其他表示可执行性的方法,则不得在回复的支持字段和访问字段中设置ACCESS4_execute。如果客户端在访问请求的访问字段中设置ACCESS4_EXECUTE,而在应答的支持字段中未设置ACCESS4_EXECUTE,则客户端将必须发送一个访问请求,并在请求的访问字段中设置ACCESS4_读取位。

o If the server supports read permission bits, it MUST only check for read permissions in the mode, acl, and dacl attributes when it receives an ACCESS request with ACCESS4_READ set in the access field. The server MUST NOT also examine execute permission bits when determining whether the reply will have ACCESS4_READ set in the access field or not.

o 如果服务器支持读取权限位,则只有在接收到访问字段中设置了ACCESS4_read的访问请求时,它才能在模式、acl和dacl属性中检查读取权限。在确定回复是否在访问字段中设置了ACCESS4\u READ时,服务器也不得检查执行权限位。

Note that if the ACCESS reply has ACCESS4_READ or ACCESS_EXECUTE set, then the user also has permissions to OPEN (Section 18.16) or READ (Section 18.22) the file. In other words, if the client sends an ACCESS request with the ACCESS4_READ and ACCESS_EXECUTE set in the access field (or two separate requests, one with ACCESS4_READ set and the other with ACCESS4_EXECUTE set), and the reply has just

请注意,如果访问回复设置了ACCESS4_READ或Accessu EXECUTE,则用户还具有打开(第18.16节)或读取(第18.22节)文件的权限。换句话说,如果客户端发送一个访问请求,并且在访问字段中设置了ACCESS4_READ和ACCESS_EXECUTE(或者两个单独的请求,一个带有ACCESS4_READ set,另一个带有ACCESS4_EXECUTE set),并且回复刚刚结束

ACCESS4_EXECUTE set in the access field (or just one reply has ACCESS4_EXECUTE set), then the user has authorization to OPEN or READ the file.

access字段中的ACCESS4\u执行集(或者只有一个回复具有ACCESS4\u执行集),则用户有权打开或读取文件。

18.1.4. IMPLEMENTATION
18.1.4. 实施

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 cannot reliably perform an access check with only current file attributes.

通常,客户端仅通过检查文件属性中的uid、gid和mode字段或尝试解释ACL属性的内容来推断访问权限是不够的。这是因为服务器可能会执行uid或gid映射,或者强制执行其他访问控制限制。服务器也可能与客户端不在同一ID空间中。在这些情况下(可能还有其他情况),客户机无法仅使用当前文件属性可靠地执行访问检查。

In the NFSv2 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 NFSv4.1 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 that will result in an access failure. The OPEN operation provides a point where the server can verify access to the file object and a method to return that information to the client. The ACCESS operation is still useful for directory operations or for use in the case that the UNIX interface access() is used on the client.

在NFSv2协议中,确定是否允许操作的唯一可靠方法是尝试操作并查看操作是否成功。使用NFSv4.1协议中的访问操作,客户端可以要求服务器指示是否允许一个或多个操作类。提供访问操作是为了允许客户端在执行一系列会导致访问失败的操作之前进行检查。打开操作提供了一个点,服务器可以在该点验证对文件对象的访问,并提供了将该信息返回给客户端的方法。ACCESS操作对于目录操作或在客户端上使用UNIX接口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位。

18.2. Operation 4: CLOSE - Close File
18.2. 操作4:关闭-关闭文件
18.2.1. ARGUMENTS
18.2.1. 论据
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        open_stateid;
   };
        
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        open_stateid;
   };
        
18.2.2. RESULTS
18.2.2. 后果
   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;
   };
        
18.2.3. DESCRIPTION
18.2.3. 描述

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 are only those associated with the supplied stateid. State associated with other OPENs is not affected.

关闭操作释放由当前文件句柄指定的常规或命名属性文件的共享保留。由于此关闭而在服务器上发布的共享保留和其他状态信息仅与提供的stateid关联。与其他打开关联的状态不受影响。

If byte-range locks are held, the client SHOULD release all locks before sending 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 byte-range locks held. The server MUST return failure if any locks would exist after the CLOSE.

如果持有字节范围锁,客户端应在发送关闭之前释放所有锁。服务器可能会在关闭时释放所有未完成的锁,但某些服务器可能不支持关闭仍保留字节范围锁的文件。如果关闭后存在任何锁,服务器必须返回failure。

The argument seqid MAY have any value, and the server MUST ignore seqid.

参数seqid可以有任何值,服务器必须忽略seqid。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

The server MAY require that the combination of principal, security flavor, and, if applicable, GSS mechanism that sent the OPEN request also be the one to CLOSE the file. This might not be possible if credentials for the principal are no longer available. The server MAY allow the machine credential or SSV credential (see Section 18.35) to send CLOSE.

服务器可能要求发送打开请求的主体、安全风格和GSS机制(如果适用)的组合也是关闭文件的组合。如果主体的凭据不再可用,则可能无法执行此操作。服务器可允许机器凭证或SSV凭证(参见第18.35节)发送关闭。

18.2.4. IMPLEMENTATION
18.2.4. 实施

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. To help find any uses of this stateid by clients, the server SHOULD return the invalid special stateid (the "other" value is zero and the "seqid" field is NFS4_UINT32_MAX, see Section 8.2.3).

即使CLOSE返回stateid,该stateid对客户端也没有用处,应视为已弃用。关闭“关闭”与单个打开所有者为文件打开的所有文件关联的状态。如上所述,CLOSE将释放所有文件锁定状态或返回错误。因此,CLOSE返回的stateid对于后面的操作没有用处。为了帮助客户端查找此stateid的任何用途,服务器应返回无效的特殊stateid(“其他”值为零,“seqid”字段为NFS4_UINT32_MAX,请参见第8.2.3节)。

A CLOSE operation may make delegations grantable where they were not previously. Servers may choose to respond immediately if there are pending delegation want requests or may respond to the situation at a later time.

密切合作可能会使授权在以前没有授权的地方可以授予。如果存在挂起的委派请求,服务器可能会选择立即响应,或者可能会在以后对这种情况做出响应。

18.3. Operation 5: COMMIT - Commit Cached Data
18.3. 操作5:提交-提交缓存数据
18.3.1. ARGUMENTS
18.3.1. 论据
   struct COMMIT4args {
           /* CURRENT_FH: file */
           offset4         offset;
           count4          count;
   };
        
   struct COMMIT4args {
           /* CURRENT_FH: file */
           offset4         offset;
           count4          count;
   };
        
18.3.2. RESULTS
18.3.2. 后果
   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;
   };
        
18.3.3. DESCRIPTION
18.3.3. 描述

The COMMIT operation forces or flushes uncommitted, modified data to stable storage for the file specified by the current filehandle. The flushed data is that which was previously written with one or more WRITE operations that had the "committed" field of their results field set to UNSTABLE4.

提交操作强制或刷新未提交、修改的数据到由当前filehandle指定的文件的稳定存储中。刷新的数据是以前使用一个或多个写入操作写入的数据,这些操作的结果字段的“提交”字段设置为不稳定4。

The offset specifies the position within the file where the flush is to begin. An offset value of zero means to flush data starting at the beginning of the file. The count specifies the number of bytes of data to flush. If the count is zero, a flush from the offset to the end of the file is done.

偏移量指定文件中开始刷新的位置。偏移量值为零表示从文件开头开始刷新数据。计数指定要刷新的数据字节数。如果计数为零,则完成从偏移量到文件末尾的刷新。

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 between the initial WRITE operations and the COMMIT. The client does this by comparing the write verifier returned from the initial WRITE operations 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 restarted; however, other events at the server may result in uncommitted data loss as well.

服务器在成功完成提交后返回写验证程序。客户端使用写验证程序来确定服务器是否在初始写操作和提交之间重新启动。客户端通过比较初始写入操作返回的写入验证器和提交操作返回的验证器来实现这一点。服务器必须在每个可能导致未提交数据丢失的服务器事件或实例化时更改写入验证器的值。最常见的情况是在服务器重新启动时发生;但是,服务器上的其他事件也可能导致未提交的数据丢失。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.3.4. IMPLEMENTATION
18.3.4. 实施

The COMMIT operation is similar in operation and semantics to the POSIX fsync() [25] system interface 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(), 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()[25]系统接口类似,后者将文件状态与磁盘同步(文件数据和元数据刷新到磁盘或稳定存储)。COMMIT对客户端执行相同的操作,将服务器上的任何未同步数据和元数据刷新到服务器的磁盘或指定文件的稳定存储中。与fsync()类似,可能有一些修改过的数据或没有修改过的数据需要同步。数据可能已由服务器的正常定期缓冲区同步活动同步。COMMIT应返回NFS4\u OK,除非出现意外错误。

COMMIT differs from fsync() 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 the file has been completely written).

COMMIT与fsync()的不同之处在于,客户端可以刷新文件的某个范围(很可能是在文件完全写入之前由客户端上的缓冲区回收方案触发)。

The server implementation of COMMIT is reasonably simple. If the server receives a full file COMMIT request, that is, starting at offset zero and count zero, it should do the equivalent of applying

提交的服务器实现相当简单。如果服务器收到一个完整的文件提交请求,即从偏移量0和计数0开始,它应该执行与应用相同的操作

fsync() to the entire file. Otherwise, it should arrange to have the modified data in the range specified by offset and count to be flushed to stable storage. In both cases, any metadata associated with the file must be flushed to stable storage before returning. It is not an error for there to be nothing to flush on the server. This means that the data and metadata that needed to be flushed have already been flushed or lost during the last server failure.

fsync()复制到整个文件。否则,它应该安排在偏移量和计数指定的范围内修改数据以刷新到稳定存储。在这两种情况下,在返回之前,必须将与文件关联的任何元数据刷新到稳定存储中。服务器上没有要刷新的内容不是错误。这意味着需要刷新的数据和元数据在上次服务器故障期间已被刷新或丢失。

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 modified data based on the offset and count, and flushes any modified metadata associated with the file. It then returns the status of the flush and the write verifier. The second 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 zero and count of zero, and then free all of those buffers. Any other dirty buffers would be sent to the server in the normal fashion.

提交的客户端实现稍微复杂一些。想要将客户机缓冲区提交到稳定存储有两个原因。首先,客户机希望重用缓冲区。在这种情况下,缓冲区的偏移量和计数将在提交请求中发送到服务器。然后,服务器根据偏移量和计数刷新任何修改的数据,并刷新与文件关联的任何修改的元数据。然后,它返回刷新和写入验证器的状态。客户机生成提交的第二个原因是为了进行完整的文件刷新,例如可以在关闭时完成。在这种情况下,客户端将为此文件收集包含未提交数据的所有缓冲区,使用偏移量为零、计数为零执行提交操作,然后释放所有这些缓冲区。任何其他脏缓冲区都将以正常方式发送到服务器。

After a buffer is written (via the WRITE operation) by the client with the "committed" field in the result of WRITE 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 the "committed" field in the result 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.

客户机写入缓冲区(通过写入操作)后,写入结果中的“提交”字段设置为不稳定4,在通过提交操作刷新缓冲区或通过写入操作写入“提交”缓冲区之前,必须将该缓冲区视为已被客户机修改结果集中的字段设置为文件\u SYNC4或数据\u SYNC4。这样做是为了防止在将数据刷新到服务器上的稳定存储之前释放和重用缓冲区。

When a response is returned from either a WRITE or a COMMIT operation and it contains a write verifier that differs from that previously returned by the server, the client will need to retransmit all of the buffers containing uncommitted 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 be sent in a WRITE request with the FILE_SYNC4 stable parameter. If there is more than one buffer, it might be worthwhile retransmitting all of the buffers in WRITE operations 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. However, if the server repeatably returns from COMMIT a verifier that differs from that returned by WRITE, the only way to ensure progress is to retransmit all of the buffers with WRITE requests with the FILE_SYNC4 stable parameter.

当从写操作或提交操作返回响应并且其中包含与服务器先前返回的不同的写验证程序时,客户端需要将包含未提交数据的所有缓冲区重新传输到服务器。如何做到这一点取决于实现者。如果只有一个感兴趣的缓冲区,则应使用FILE_SYNC4 stable参数在写入请求中发送该缓冲区。如果存在多个缓冲区,可能值得在写入操作中将stable参数设置为UNSTABLE4时重新传输所有缓冲区,然后重新传输提交操作以将服务器上的所有数据刷新到稳定存储。但是,如果服务器可重复地从COMMIT返回一个不同于WRITE返回的验证器,则确保进度的唯一方法是使用FILE_SYNC4 stable参数使用写请求重新传输所有缓冲区。

The above description applies to page-cache-based systems as well as buffer-cache-based systems. In the former systems, the virtual memory system will need to be modified instead of the buffer cache.

上述描述适用于基于页面缓存的系统以及基于缓冲区缓存的系统。在以前的系统中,需要修改虚拟内存系统而不是缓存。

18.4. Operation 6: CREATE - Create a Non-Regular File Object
18.4. 操作6:创建-创建非常规文件对象
18.4.1. ARGUMENTS
18.4.1. 论据
   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 */
   };
        
   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;
   };
        
18.4.2. RESULTS
18.4.2. 后果
   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:
            /* new CURRENTFH: created object */
            CREATE4resok resok4;
    default:
            void;
   };
        
   union CREATE4res switch (nfsstat4 status) {
    case NFS4_OK:
            /* new CURRENTFH: created object */
            CREATE4resok resok4;
    default:
            void;
   };
        
18.4.3. DESCRIPTION
18.4.3. 描述

The CREATE operation creates a file object other than an ordinary file in a directory with a given name. The OPEN operation MUST be used to create a regular file or a named attribute.

创建操作在具有给定名称的目录中创建一个文件对象,而不是普通文件。“打开”操作必须用于创建常规文件或命名属性。

The current filehandle must be a directory: an object of type NF4DIR. If the current filehandle is an attribute directory (type NF4ATTRDIR), the error NFS4ERR_WRONG_TYPE is returned. If the current file handle designates any other type of object, the error NFS4ERR_NOTDIR results.

当前文件句柄必须是目录:NF4DIR类型的对象。如果当前文件句柄是一个属性目录(类型为NF4ATRTDIR),则返回错误NFS4ERR\u错误类型。如果当前文件句柄指定任何其他类型的对象,则会产生错误NFS4ERR_NOTDIR。

The objname specifies the name for the new object. The objtype determines the type of object to be created: directory, symlink, etc. If the object type specified is that of an ordinary file, a named attribute, or a named attribute directory, the error NFS4ERR_BADTYPE results.

objname指定新对象的名称。objtype确定要创建的对象类型:目录、符号链接等。如果指定的对象类型是普通文件、命名属性或命名属性目录的对象类型,则会出现错误NFS4ERR_BADTYPE。

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 data type, 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 zero, or if objname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果objname的长度为零,或者如果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 file system 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 file system semantics may dictate other methods of derivation. Similarly, if createattrs includes neither the group attribute nor a group ACE, and if the server's file system 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 (e.g., POSIX systems have a user database [26] that has a group identifier for every user identifier), inherited from the directory in which the object is created, or whatever else the server's operating environment or file system semantics dictate. This applies to the OPEN operation too.

(或相应的所有者ACE)的文件。这可能来自RPC调用的凭据,例如,如果凭据包括组主体(例如使用AUTH_SYS),则来自与凭据中的主体关联的组标识符(例如,POSIX系统有一个用户数据库[26],其中每个用户标识符都有一个组标识符),继承自创建对象的目录,或服务器的操作环境或文件系统语义规定的任何其他内容。这也适用于打开操作。

Conversely, it is possible that the client will specify in createattrs an owner attribute, 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。这也适用于打开操作。

If the current filehandle designates a directory for which another client holds a directory delegation, then, unless the delegation is such that the situation can be resolved by sending a notification, the delegation MUST be recalled, and the CREATE operation MUST NOT proceed until the delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果当前filehandle指定了另一个客户端持有目录委派的目录,则除非该委派能够通过发送通知来解决问题,否则必须重新调用委派,并且在返回或撤销委派之前,创建操作不得继续。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

When the current filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, NOTIFY4_ADD_ENTRY will be generated as a result of this operation.

当当前文件句柄指定存在一个或多个目录委派的目录时,当这些委派请求此类通知时,此操作将生成NOTIFY4_ADD_条目。

If the capability FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 is set (Section 14.4), and a symbolic link is being created, then the content of the symbolic link MUST be in UTF-8 encoding.

如果设置了功能FSCHARSET\u CAP4\u ALLOWS\u ONLY\u UTF8(第14.4节),并且正在创建符号链接,则符号链接的内容必须采用UTF-8编码。

18.4.4. IMPLEMENTATION
18.4.4. 实施

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操作,以便设置适当的属性。

18.5. Operation 7: DELEGPURGE - Purge Delegations Awaiting Recovery
18.5. 操作7:删除清除-清除等待恢复的委派
18.5.1. ARGUMENTS
18.5.1. 论据
   struct DELEGPURGE4args {
           clientid4       clientid;
   };
        
   struct DELEGPURGE4args {
           clientid4       clientid;
   };
        
18.5.2. RESULTS
18.5.2. 后果
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
   struct DELEGPURGE4res {
           nfsstat4        status;
   };
        
18.5.3. DESCRIPTION
18.5.3. 描述

This operation purges all of the delegations awaiting recovery for a given client. This is useful for clients that 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.

此操作将清除给定客户端等待恢复的所有委派。这对于不将委派信息提交到稳定存储的客户机非常有用,以指示服务器不需要延迟冲突请求,等待委派信息的恢复。

The client is NOT specified by the clientid field of the request. The client SHOULD set the client field to zero, and the server MUST ignore the clientid field. Instead, the server MUST derive the client ID from the value of the session ID in the arguments of the SEQUENCE operation that precedes DELEGPURGE in the COMPOUND request.

请求的clientid字段未指定客户端。客户端应将client字段设置为零,服务器必须忽略clientid字段。相反,服务器必须从复合请求中DELEGPURGE之前的序列操作的参数中的会话ID值派生客户机ID。

The DELEGPURGE operation should be used by clients that record delegation information on stable storage on the client. In this case, after the client recovers all delegations it knows of, it should immediately send a DELEGPURGE operation. 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 which make requests that conflict with the unrecovered delegations. The set of delegations known to the server and the client might be different. The reason for this is that after sending a request that resulted in a delegation, the client might experience a failure before it both received the delegation and committed the delegation to the client's stable storage.

在客户端的稳定存储上记录委派信息的客户端应使用DELEGPURGE操作。在这种情况下,客户机恢复其知道的所有委托后,应立即发送DELEGPURGE操作。这样做将通知服务器,不会恢复客户端的其他委派,从而允许其释放资源,并避免延迟发出与未恢复委派冲突的请求的其他客户端。服务器和客户端已知的委托集可能不同。原因是,在发送导致委派的请求后,客户端可能会在收到委派并将委派提交到客户端的稳定存储之前遇到故障。

The server MAY support DELEGPURGE, but if it does not, it MUST NOT support CLAIM_DELEGATE_PREV and MUST NOT support CLAIM_DELEG_PREV_FH.

服务器可能支持DELEGPURGE,但如果不支持,则不得支持CLAIM_delege_PREV,也不得支持CLAIM_DELEG_PREV_FH。

18.6. Operation 8: DELEGRETURN - Return Delegation
18.6. 操作8:DELEGRETURN-返回委派
18.6.1. ARGUMENTS
18.6.1. 论据
   struct DELEGRETURN4args {
           /* CURRENT_FH: delegated object */
           stateid4        deleg_stateid;
   };
        
   struct DELEGRETURN4args {
           /* CURRENT_FH: delegated object */
           stateid4        deleg_stateid;
   };
        
18.6.2. RESULTS
18.6.2. 后果
   struct DELEGRETURN4res {
           nfsstat4        status;
   };
        
   struct DELEGRETURN4res {
           nfsstat4        status;
   };
        
18.6.3. DESCRIPTION
18.6.3. 描述

The DELEGRETURN operation returns the delegation represented by the current filehandle and stateid.

DELEGRETURN操作返回由当前filehandle和stateid表示的委托。

Delegations may be returned voluntarily (i.e., before the server has recalled them) or when recalled. In either case, the client must properly propagate state changed under the context of the delegation to the server before returning the delegation.

可以自愿(即,在服务器调用委托之前)或在调用时返回委托。在任何一种情况下,客户机都必须在返回委托之前将委托上下文中更改的状态正确地传播到服务器。

The server MAY require that the principal, security flavor, and if applicable, the GSS mechanism, combination that acquired the delegation also be the one to send DELEGRETURN on the file. This might not be possible if credentials for the principal are no longer available. The server MAY allow the machine credential or SSV credential (see Section 18.35) to send DELEGRETURN.

服务器可能要求获得委派的主体、安全风格以及GSS机制(如果适用)组合也是发送文件DELEGRETURN的主体。如果主体的凭据不再可用,则可能无法执行此操作。服务器可允许机器凭据或SSV凭据(参见第18.35节)发送DELEGRETURN。

18.7. Operation 9: GETATTR - Get Attributes
18.7. 操作9:GETATTR-获取属性
18.7.1. ARGUMENTS
18.7.1. 论据
   struct GETATTR4args {
           /* CURRENT_FH: object */
           bitmap4         attr_request;
   };
        
   struct GETATTR4args {
           /* CURRENT_FH: object */
           bitmap4         attr_request;
   };
        
18.7.2. RESULTS
18.7.2. 后果
   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;
   };
        
18.7.3. DESCRIPTION
18.7.3. 描述

The GETATTR operation will obtain attributes for the file system object specified by the current filehandle. The client sets a bit in the bitmap argument for each attribute value that it would like the server to return. The server returns an attribute bitmap that indicates the attribute values that it was able to return, which will include all attributes requested by the client that are attributes supported by the server for the target file system. This bitmap is followed by the attribute values ordered lowest attribute number first.

GETATTR操作将获取由当前filehandle指定的文件系统对象的属性。客户端在位图参数中为希望服务器返回的每个属性值设置一位。服务器返回一个属性位图,该位图指示它能够返回的属性值,该位图将包括客户端请求的所有属性,这些属性是服务器为目标文件系统支持的属性。该位图后面紧跟着属性值,属性值的顺序是先从最低属性号开始。

The server MUST return a value for each attribute that the client requests if the attribute is supported by the server for the target file system. If the server does not support a particular attribute on the target file system, 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 on the target but cannot obtain its value. In that case, no attribute values will be returned.

如果目标文件系统的服务器支持客户端请求的每个属性,则服务器必须为该属性返回一个值。如果服务器不支持目标文件系统上的特定属性,则它不能返回属性值,也不能在结果位图中设置属性位。如果服务器支持目标上的属性但无法获取其值,则必须返回错误。在这种情况下,不会返回任何属性值。

File systems that are absent should be treated as having support for a very small set of attributes as described in Section 11.3.1, even if previously, when the file system was present, more attributes were supported.

不存在的文件系统应被视为支持第11.3.1节中所述的一组非常小的属性,即使在此之前,当文件系统存在时,支持更多的属性。

All servers MUST support the REQUIRED attributes as specified in Section 5.6, for all file systems, with the exception of absent file systems.

所有服务器必须支持第5.6节中规定的所有文件系统所需的属性,不存在的文件系统除外。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.7.4. IMPLEMENTATION
18.7.4. 实施

Suppose there is an OPEN_DELEGATE_WRITE delegation held by another client for the file in question and size and/or change are among the set of attributes being interrogated. The server has two choices. First, the server can obtain the actual current value of these attributes from the client holding the delegation by using the CB_GETATTR callback. Second, the server, particularly when the delegated client is unresponsive, can recall the delegation in question. The GETATTR MUST NOT proceed until one of the following occurs:

假设另一个客户机为所讨论的文件持有一个OPEN_DELEGATE_WRITE委托,并且正在查询的属性集中包含大小和/或更改。服务器有两种选择。首先,服务器可以使用CB_GETATTR回调从持有委托的客户端获取这些属性的实际当前值。第二,服务器,特别是当委托的客户机没有响应时,可以调用有问题的委托。在发生以下情况之一之前,GETATTR不得继续:

o The requested attribute values are returned in the response to CB_GETATTR.

o 请求的属性值在对CB_GETATTR的响应中返回。

o The OPEN_DELEGATE_WRITE delegation is returned.

o 返回打开的委托和写入委托。

o The OPEN_DELEGATE_WRITE delegation is revoked.

o 已撤消开放委托和写入委托。

Unless one of the above happens very quickly, one or more NFS4ERR_DELAY errors will be returned while a delegation is outstanding.

除非上述任何一种情况很快发生,否则在委托未完成时将返回一个或多个NFS4ERR_延迟错误。

18.8. Operation 10: GETFH - Get Current Filehandle
18.8. 操作10:GETFH-获取当前文件句柄
18.8.1. ARGUMENTS
18.8.1. 论据
   /* CURRENT_FH: */
   void;
        
   /* CURRENT_FH: */
   void;
        
18.8.2. RESULTS
18.8.2. 后果
   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;
   };
        
18.8.3. DESCRIPTION
18.8.3. 描述

This operation returns the current filehandle value.

此操作返回当前的filehandle值。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

As described in Section 2.10.6.4, GETFH is REQUIRED or RECOMMENDED to immediately follow certain operations, and servers are free to reject such operations if the client fails to insert GETFH in the request as REQUIRED or RECOMMENDED. Section 18.16.4.1 provides additional justification for why GETFH MUST follow OPEN.

如第2.10.6.4节所述,要求或建议GETFH立即执行某些操作,如果客户端未能按照要求或建议在请求中插入GETFH,服务器可自由拒绝此类操作。第18.16.4.1节提供了GETFH必须遵循OPEN的额外理由。

18.8.4. IMPLEMENTATION
18.8.4. 实施

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 look up a directory entry and obtain its filehandle, then the following request is needed.

更改当前文件句柄(如查找或创建)的操作不会自动返回新的文件句柄。例如,如果客户机需要查找目录条目并获取其文件句柄,则需要以下请求。

PUTFH (directory filehandle) LOOKUP (entry name) GETFH

PUTFH(目录文件句柄)查找(条目名称)GETFH

18.9. Operation 11: LINK - Create Link to a File
18.9. 操作11:链接-创建指向文件的链接
18.9.1. ARGUMENTS
18.9.1. 论据
   struct LINK4args {
           /* SAVED_FH: source object */
           /* CURRENT_FH: target directory */
           component4      newname;
   };
        
   struct LINK4args {
           /* SAVED_FH: source object */
           /* CURRENT_FH: target directory */
           component4      newname;
   };
        
18.9.2. RESULTS
18.9.2. 后果
   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;
   };
        
18.9.3. DESCRIPTION
18.9.3. 描述

The LINK operation creates an additional newname for the file represented by the saved filehandle, as set by the SAVEFH operation, in the directory represented by the current filehandle. The existing file and the target directory must reside within the same file system on the server. On success, the current filehandle will continue to be the target directory. 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 data type, 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 zero, or if newname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果newname的长度为零,或者如果newname不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

18.9.4. IMPLEMENTATION
18.9.4. 实施

The server MAY impose restrictions on the LINK operation such that LINK may not be done when the file is open or when that open is done by particular protocols, or with particular options or access modes. When LINK is rejected because of such restrictions, the error NFS4ERR_FILE_OPEN is returned.

服务器可以对链接操作施加限制,使得当文件打开时,或者当该打开是通过特定协议或使用特定选项或访问模式完成时,不能进行链接。由于此类限制而拒绝链接时,将返回错误NFS4ERR_FILE_OPEN。

If a server does implement such restrictions and those restrictions include cases of NFSv4 opens preventing successful execution of a link, the server needs to recall any delegations that could hide the existence of opens relevant to that decision. The reason is that when a client holds a delegation, the server might not have an accurate account of the opens for that client, since the client may execute OPENs and CLOSEs locally. The LINK operation must be delayed only until a definitive result can be obtained. For example, suppose there are multiple delegations and one of them establishes an open whose presence would prevent the link. Given the server's semantics, NFS4ERR_FILE_OPEN may be returned to the caller as soon as that delegation is returned without waiting for other delegations to be returned. Similarly, if such opens are not associated with delegations, NFS4ERR_FILE_OPEN can be returned immediately with no delegation recall being done.

如果服务器确实实施了此类限制,并且这些限制包括NFSv4打开阻止成功执行链接的情况,则服务器需要调用可能隐藏与该决定相关的打开存在的任何委托。原因是,当客户端持有委托时,服务器可能没有该客户端打开的准确帐户,因为客户端可能在本地执行打开和关闭。链路操作只能延迟到获得最终结果为止。例如,假设有多个代表团,其中一个代表团建立了一个开放的代表团,该代表团的存在将阻止链接。考虑到服务器的语义,NFS4ERR_FILE_OPEN可以在该委托返回后立即返回给调用方,而无需等待其他委托返回。类似地,如果此类打开与委派无关,则可以立即返回NFS4ERR_FILE_OPEN,而不进行委派调用。

If the current filehandle designates a directory for which another client holds a directory delegation, then, unless the delegation is such that the situation can be resolved by sending a notification, the delegation MUST be recalled, and the operation cannot be performed successfully until the delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果当前filehandle指定了另一个客户端持有目录委派的目录,则除非该委派能够通过发送通知解决问题,否则必须重新调用委派,并且在返回或撤销委派之前,操作无法成功执行。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

When the current filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, instead of a recall, NOTIFY4_ADD_ENTRY will be generated as a result of the LINK operation.

当当前文件句柄指定存在一个或多个目录委派的目录时,当这些委派请求此类通知而不是回调时,链接操作将生成NOTIFY4\u ADD\u条目。

If the current file system supports the numlinks attribute, and other clients have delegations to the file being linked, then those delegations MUST be recalled and the LINK operation MUST NOT proceed until all delegations are returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果当前文件系统支持numlinks属性,并且其他客户端对要链接的文件具有委派,则必须调用这些委派,并且在返回或撤消所有委派之前,链接操作不得继续。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

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 file system on the server" means that the fsid fields in the attributes for the objects are the same. If they reside on different file systems, the error NFS4ERR_XDEV is returned. This error may be returned by some servers when there is an internal partitioning of a file system that the LINK operation would violate.

语句“文件和目标目录必须位于服务器上的同一文件系统中”表示对象属性中的fsid字段相同。如果它们驻留在不同的文件系统上,则返回错误NFS4ERR_XDEV。当链接操作违反文件系统的内部分区时,某些服务器可能会返回此错误。

On some servers, "." and ".." are illegal values for newname and the error NFS4ERR_BADNAME will be returned if they are specified.

在某些服务器上,“.”和“.”是newname的非法值,如果指定了它们,将返回错误NFS4ERR_BADNAME。

When the current filehandle designates a named attribute directory and the object to be linked (the saved filehandle) is not a named attribute for the same object, the error NFS4ERR_XDEV MUST be returned. When the saved filehandle designates a named attribute and the current filehandle is not the appropriate named attribute directory, the error NFS4ERR_XDEV MUST also be returned.

当当前文件句柄指定了命名属性目录,并且要链接的对象(保存的文件句柄)不是同一对象的命名属性时,必须返回错误NFS4ERR_XDEV。如果保存的filehandle指定了命名属性,而当前filehandle不是相应的命名属性目录,则还必须返回错误NFS4ERR_XDEV。

When the current filehandle designates a named attribute directory and the object to be linked (the saved filehandle) is a named attribute within that directory, the server may return the error NFS4ERR_NOTSUPP.

当当前文件句柄指定命名属性目录,并且要链接的对象(保存的文件句柄)是该目录中的命名属性时,服务器可能返回错误NFS4ERR_NOTSUPP。

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.

请注意,符号链接是通过创建操作创建的。

18.10. Operation 12: LOCK - Create Lock
18.10. 操作12:锁定-创建锁定
18.10.1. ARGUMENTS
18.10.1. 论据
   /*
    * For LOCK, transition from open_stateid and lock_owner
    * to a lock stateid.
    */
   struct open_to_lock_owner4 {
           seqid4          open_seqid;
           stateid4        open_stateid;
           seqid4          lock_seqid;
           lock_owner4     lock_owner;
   };
        
   /*
    * For LOCK, transition from open_stateid and lock_owner
    * to a lock stateid.
    */
   struct open_to_lock_owner4 {
           seqid4          open_seqid;
           stateid4        open_stateid;
           seqid4          lock_seqid;
           lock_owner4     lock_owner;
   };
        
   /*
    * For LOCK, existing lock stateid continues to request new
    * file lock for the same lock_owner and open_stateid.
    */
   struct exist_lock_owner4 {
           stateid4        lock_stateid;
           seqid4          lock_seqid;
   };
        
   /*
    * For LOCK, existing lock stateid continues to request new
    * file lock for the same lock_owner and open_stateid.
    */
   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;
   };
        
18.10.2. RESULTS
18.10.2. 后果
   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;
   };
        
18.10.3. DESCRIPTION
18.10.3. 描述

The LOCK operation requests a byte-range lock for the byte-range specified by the offset and length parameters, and lock type specified in the locktype parameter. If this is a reclaim request, the reclaim parameter will be TRUE.

锁定操作为偏移量和长度参数指定的字节范围以及locktype参数中指定的锁定类型请求字节范围锁定。如果这是回收请求,则回收参数将为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 equal to NFS4_UINT64_MAX. The server MUST return NFS4ERR_INVAL under the following combinations of length and offset:

文件中的字节可能会被锁定,即使这些字节当前未分配给该文件。要从特定偏移量到文件结尾(无论文件实际有多长)锁定文件,请使用等于NFS4_UINT64_MAX的长度字段。服务器必须在以下长度和偏移量组合下返回NFS4ERR_INVAL:

o Length is equal to zero.

o 长度等于零。

o Length is not equal to NFS4_UINT64_MAX, and the sum of length and offset exceeds NFS4_UINT64_MAX.

o 长度不等于NFS4_UINT64_MAX,且长度和偏移量之和超过NFS4_UINT64_MAX。

32-bit servers are servers that support locking for byte offsets that fit within 32 bits (i.e., less than or equal to NFS4_UINT32_MAX). If the client specifies a range that overlaps one or more bytes beyond offset NFS4_UINT32_MAX but does not end at offset NFS4_UINT64_MAX, then such a 32-bit server MUST return the error NFS4ERR_BAD_RANGE.

32位服务器是支持锁定适合32位(即小于或等于NFS4_UINT32_MAX)的字节偏移量的服务器。如果客户端指定的范围与偏移量NFS4\u UINT32\u MAX以外的一个或多个字节重叠,但不以偏移量NFS4\u UINT64\u MAX结束,则此类32位服务器必须返回错误NFS4ERR\u BAD\u range。

If the server returns NFS4ERR_DENIED, the owner, offset, and length of a conflicting lock are returned.

如果服务器返回NFS4ERR_DENIED,则返回冲突锁的所有者、偏移量和长度。

The locker argument specifies the lock-owner that is associated with the LOCK operation. The locker4 structure is a switched union that indicates whether the client has already created byte-range locking state associated with the current open file and lock-owner. In the case in which it has, the argument is just a stateid representing the set of locks associated with that open file and lock-owner, together with a lock_seqid value that MAY be any value and MUST be ignored by the server. In the case where no byte-range locking state has been established, or the client does not have the stateid available, the argument contains the stateid of the open file with which this lock is to be associated, together with the lock-owner with which the lock is to be associated. The open_to_lock_owner case covers the very first lock done by a lock-owner for a given open file and offers a method to use the established state of the open_stateid to transition to the use of a lock stateid.

locker参数指定与锁操作关联的锁所有者。locker4结构是一个交换联合,它指示客户端是否已经创建了与当前打开的文件和锁所有者关联的字节范围锁定状态。在具有的情况下,参数只是一个stateid,表示与打开的文件和锁所有者关联的锁集,以及一个lock_seqid值,该值可以是任何值,服务器必须忽略。如果未建立字节范围锁定状态,或者客户端没有可用的stateid,则参数包含与此锁关联的打开文件的stateid,以及与锁关联的锁所有者。open_to_lock_owner案例涵盖了锁所有者对给定的打开文件执行的第一个锁,并提供了一种方法来使用open_stateid的已建立状态转换为使用lock stateid。

The following fields of the locker parameter MAY be set to any value by the client and MUST be ignored by the server:

客户机可以将locker参数的以下字段设置为任何值,服务器必须忽略这些字段:

o The clientid field of the lock_owner field of the open_owner field (locker.open_owner.lock_owner.clientid). The reason the server MUST ignore the clientid field is that the server MUST derive the client ID from the session ID from the SEQUENCE operation of the COMPOUND request.

o 打开所有者字段(locker.open\u owner.lock\u owner.clientid)的lock\u owner字段的clientid字段。服务器必须忽略clientid字段的原因是,服务器必须从复合请求的序列操作的会话ID派生客户端ID。

o The open_seqid and lock_seqid fields of the open_owner field (locker.open_owner.open_seqid and locker.open_owner.lock_seqid).

o open_owner字段(locker.open_owner.open_seqid和locker.open_owner.lock_seqid)的open_seqid和lock_seqid字段。

o The lock_seqid field of the lock_owner field (locker.lock_owner.lock_seqid).

o lock_owner字段(locker.lock_owner.lock_seqid)的lock_seqid字段。

Note that the client ID appearing in a LOCK4denied structure is the actual client associated with the conflicting lock, whether this is the client ID associated with the current session or a different one. Thus, if the server returns NFS4ERR_DENIED, it MUST set the clientid field of the owner field of the denied field.

请注意,出现在LOCK4denied结构中的客户端ID是与冲突锁关联的实际客户端,无论是与当前会话关联的客户端ID还是不同的客户端ID。因此,如果服务器返回NFS4ERR_DENIED,则必须设置DENIED字段的owner字段的clientid字段。

If the current filehandle is not an ordinary file, an error will be returned to the client. In the case that the current filehandle represents an object of type NF4DIR, NFS4ERR_ISDIR is returned. If the current filehandle designates a symbolic link, NFS4ERR_SYMLINK is returned. In all other cases, NFS4ERR_WRONG_TYPE is returned.

如果当前文件句柄不是普通文件,则会向客户端返回错误。如果当前文件句柄表示NF4DIR类型的对象,则返回NFS4ERR_ISDIR。如果当前文件句柄指定符号链接,则返回NFS4ERR_SYMLINK。在所有其他情况下,将返回NFS4ERR_-Error_类型。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.10.4. IMPLEMENTATION
18.10.4. 实施

If the server is unable to determine the exact offset and length of the conflicting byte-range lock, the same offset and length that were provided in the arguments should be returned in the denied results.

如果服务器无法确定冲突字节范围锁的确切偏移量和长度,则应在拒绝结果中返回参数中提供的相同偏移量和长度。

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 types of locks reflect the semantics of the server-exported file system, and are not specified by the protocol. For example, Windows 2000 allows a write lock of a file open for read access, while a POSIX-compliant system does not.

锁定操作需要进行权限检查,并根据相关文件的访问类型进行检查。但是,各种类型的锁所需的特定权限和模式反映了服务器导出文件系统的语义,协议没有指定这些权限和模式。例如,Windows 2000允许对打开以进行读取访问的文件进行写锁定,而POSIX兼容系统则不允许。

When the client sends a LOCK operation that corresponds to a range that the lock-owner has locked already (with the same or different lock type), or to a sub-range of such a range, or to a byte-range that includes multiple locks already granted to that lock-owner, 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 sends a LOCK operation that amounts to upgrading (changing from a READ_LT lock to a WRITE_LT lock) or downgrading (changing from WRITE_LT lock to a READ_LT lock) an existing byte-range lock, and the server does not support such a

当客户端发送一个锁操作,该锁操作对应于锁所有者已锁定的范围(使用相同或不同的锁类型),或该范围的子范围,或包含已全部或部分授予该锁所有者的多个锁的字节范围,并且服务器不支持此类锁操作时(即,不支持POSIX锁定语义),服务器将返回错误NFS4ERR_LOCK_RANGE。在这种情况下,客户端可能会返回错误,或者它可能会模拟所需的操作,仅对不包括该锁所有者已锁定的任何字节的范围使用锁,并对该锁所有者持有的锁使用锁(指定完全匹配的范围和类型)。类似地,当客户端发送相当于升级(从读锁更改为写锁)或降级(从写锁更改为读锁)现有字节范围锁的锁操作时,服务器不支持这样的操作

lock, the server will return NFS4ERR_LOCK_NOTSUPP. Such operations may not perfectly reflect the required semantics in the face of conflicting LOCK operations from other clients.

锁定,服务器将返回NFS4ERR\u lock\u NOTSUPP。面对来自其他客户端的冲突锁操作,此类操作可能无法完美地反映所需的语义。

When a client holds an OPEN_DELEGATE_WRITE delegation, the client holding that delegation is assured that there are no opens by other clients. Thus, there can be no conflicting LOCK operations from such clients. Therefore, the client may be handling locking requests locally, without doing LOCK operations on the server. If it does that, it must be prepared to update the lock status on the server, by sending appropriate LOCK and LOCKU operations before returning the delegation.

当一个客户机持有一个开放的委托书时,持有该委托书的客户机将确保没有其他客户机打开该委托书。因此,这样的客户端不可能有冲突的锁操作。因此,客户端可能在本地处理锁定请求,而不在服务器上执行锁定操作。如果这样做,则必须准备好更新服务器上的锁定状态,方法是在返回委派之前发送适当的锁定和锁定操作。

When one or more clients hold OPEN_DELEGATE_READ delegations, any LOCK operation where the server is implementing mandatory locking semantics MUST result in the recall of all such delegations. The LOCK operation may not be granted until all such delegations are returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while the delegation remains outstanding.

当一个或多个客户端持有OPEN_DELEGATE_READ委托时,服务器正在实现强制锁定语义的任何锁定操作都必须导致调用所有此类委托。在返回或撤销所有此类委托之前,不得授予锁定操作。除非这种情况发生得很快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

18.11. Operation 13: LOCKT - Test for Lock
18.11. 操作13:锁定-锁定测试
18.11.1. ARGUMENTS
18.11.1. 论据
   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;
   };
        
18.11.2. RESULTS
18.11.2. 后果
   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;
   };
        
18.11.3. DESCRIPTION
18.11.3. 描述

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. The owner field in the results includes the client ID of the owner of the conflicting lock, whether this is the client ID associated with the current session or a different client ID. 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操作按照参数中的指定测试锁。如果存在冲突锁,则返回冲突锁的所有者、偏移量、长度和类型。结果中的所有者字段包括冲突锁所有者的客户端ID,无论是与当前会话关联的客户端ID还是其他客户端ID。如果未持有任何锁,则只返回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相同的情况下返回。

The clientid field of the owner MAY be set to any value by the client and MUST be ignored by the server. The reason the server MUST ignore the clientid field is that the server MUST derive the client ID from the session ID from the SEQUENCE operation of the COMPOUND request.

客户端可以将所有者的clientid字段设置为任何值,服务器必须忽略该字段。服务器必须忽略clientid字段的原因是,服务器必须从复合请求的序列操作的会话ID派生客户端ID。

If the current filehandle is not an ordinary file, an error will be returned to the client. In the case that the current filehandle represents an object of type NF4DIR, NFS4ERR_ISDIR is returned. If the current filehandle designates a symbolic link, NFS4ERR_SYMLINK is returned. In all other cases, NFS4ERR_WRONG_TYPE is returned.

如果当前文件句柄不是普通文件,则会向客户端返回错误。如果当前文件句柄表示NF4DIR类型的对象,则返回NFS4ERR_ISDIR。如果当前文件句柄指定符号链接,则返回NFS4ERR_SYMLINK。在所有其他情况下,将返回NFS4ERR_-Error_类型。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.11.4. IMPLEMENTATION
18.11.4. 实施

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.

如果服务器无法确定冲突锁的确切偏移量和长度,则应在拒绝结果中返回参数中提供的相同偏移量和长度。

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 might not be available.

LOCKT使用lock_owner4而不是stateid4,就像在lock中用来标识所有者一样。这是因为客户端不必打开文件来测试是否存在锁,因此stateid可能不可用。

As noted in Section 18.10.4, some servers may return NFS4ERR_LOCK_RANGE to certain (otherwise non-conflicting) LOCK operations that overlap ranges already granted to the current lock-owner.

如第18.10.4节所述,一些服务器可能会将NFS4ERR_LOCK_RANGE返回到某些(否则不冲突)锁操作,这些操作与已授予当前锁所有者的范围重叠。

The LOCKT operation's test for conflicting locks SHOULD exclude locks for the current lock-owner, and thus should return NFS4_OK in such cases. Note that this means that a server might return NFS4_OK to a LOCKT request even though a LOCK operation for the same range and lock-owner would fail with NFS4ERR_LOCK_RANGE.

LOCKT操作对冲突锁的测试应排除当前锁所有者的锁,因此在这种情况下应返回NFS4_OK。请注意,这意味着服务器可能会向锁定请求返回NFS4_OK,即使相同范围和锁所有者的锁定操作在NFS4ERR_LOCK_范围内失败。

When a client holds an OPEN_DELEGATE_WRITE delegation, it may choose (see Section 18.10.4) to handle LOCK requests locally. In such a case, LOCKT requests will similarly be handled locally.

当客户端持有OPEN_DELEGATE_WRITE委派时,它可以选择(参见第18.10.4节)在本地处理锁定请求。在这种情况下,LOCKT请求将类似地在本地处理。

18.12. Operation 14: LOCKU - Unlock File
18.12. 操作14:锁定-解锁文件
18.12.1. ARGUMENTS
18.12.1. 论据
   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;
   };
        
18.12.2. RESULTS
18.12.2. 后果
   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;
   };
        
18.12.3. DESCRIPTION
18.12.3. 描述

The LOCKU operation unlocks the byte-range 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相同的情况下返回。

The seqid parameter MAY be any value and the server MUST ignore it.

seqid参数可以是任何值,服务器必须忽略它。

If the current filehandle is not an ordinary file, an error will be returned to the client. In the case that the current filehandle represents an object of type NF4DIR, NFS4ERR_ISDIR is returned. If the current filehandle designates a symbolic link, NFS4ERR_SYMLINK is returned. In all other cases, NFS4ERR_WRONG_TYPE is returned.

如果当前文件句柄不是普通文件,则会向客户端返回错误。如果当前文件句柄表示NF4DIR类型的对象,则返回NFS4ERR_ISDIR。如果当前文件句柄指定符号链接,则返回NFS4ERR_SYMLINK。在所有其他情况下,将返回NFS4ERR_-Error_类型。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

The server MAY require that the principal, security flavor, and if applicable, the GSS mechanism, combination that sent a LOCK operation also be the one to send LOCKU on the file. This might not be possible if credentials for the principal are no longer available. The server MAY allow the machine credential or SSV credential (see Section 18.35) to send LOCKU.

服务器可能要求发送锁操作的主体、安全风格以及GSS机制(如果适用)组合也要发送文件上的锁。如果主体的凭据不再可用,则可能无法执行此操作。服务器可允许机器凭证或SSV凭证(见第18.35节)发送LOCKU。

18.12.4. IMPLEMENTATION
18.12.4. 实施

If the area to be unlocked does not correspond exactly to a lock actually held by the lock-owner, 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 lock-owner. In all of these cases, allowed by POSIX locking [24] 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 operations for the sub-ranges not being unlocked.

如果要解锁的区域与锁所有者实际持有的锁不完全对应,服务器可能返回错误NFS4ERR_lock_RANGE。这包括区域未锁定、区域是锁定区域的子范围、与锁定区域重叠但不完全匹配的情况,或者指定的区域包括锁所有者持有的多个锁。在所有这些情况下,POSIX locking[24]语义允许,收到此错误的客户机如果希望支持此类操作,应在其实际持有的锁对应的范围上使用LOCKU模拟该操作,随后可能会对未解锁的子范围执行锁操作。

When a client holds an OPEN_DELEGATE_WRITE delegation, it may choose (see Section 18.10.4) to handle LOCK requests locally. In such a case, LOCKU operations will similarly be handled locally.

当客户端持有OPEN_DELEGATE_WRITE委派时,它可以选择(参见第18.10.4节)在本地处理锁定请求。在这种情况下,LOCKU操作也将在本地处理。

18.13. Operation 15: LOOKUP - Lookup Filename
18.13. 操作15:查找-查找文件名
18.13.1. ARGUMENTS
18.13.1. 论据
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           component4      objname;
   };
        
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           component4      objname;
   };
        
18.13.2. RESULTS
18.13.2. 后果
   struct LOOKUP4res {
           /* New CURRENT_FH: object */
           nfsstat4        status;
   };
        
   struct LOOKUP4res {
           /* New CURRENT_FH: object */
           nfsstat4        status;
   };
        
18.13.3. DESCRIPTION
18.13.3. 描述

The LOOKUP operation looks up or finds a file system 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。

18.13.4. IMPLEMENTATION
18.13.4. 实施

If the client wants to achieve the effect of a multi-component look up, 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

Unlike NFSv3, NFSv4.1 allows 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 file system. This needs to be done to maintain the file object identity checking mechanisms common to UNIX clients.

与NFSv3不同,NFSv4.1允许查找请求跨服务器上的装入点。客户端可以通过比较目录的fsid属性和查找的目录的fsid属性来检测装入点交叉。如果FSID不同,则新目录是服务器装入点。检测到装载点交叉的UNIX客户端需要装载服务器的文件系统。需要这样做才能维护UNIX客户机通用的文件对象身份检查机制。

Servers that limit NFS access to "shared" or "exported" file systems should provide a pseudo file system into which the exported file systems can be integrated, so that clients can browse the server's namespace. The clients view of a pseudo file system will be limited to paths that lead to exported file systems.

限制NFS访问“共享”或“导出”文件系统的服务器应提供一个虚拟文件系统,将导出的文件系统集成到其中,以便客户端可以浏览服务器的命名空间。伪文件系统的“客户端”视图将限于指向导出文件系统的路径。

Note: previous versions of the protocol assigned special semantics to the names "." and "..". NFSv4.1 assigns no special semantics to these names. The LOOKUPP operator must be used to look up a parent directory.

注:协议的早期版本为名称“.”和“.”指定了特殊语义。NFSv4.1没有为这些名称指定特殊语义。必须使用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 look up 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。

18.14. Operation 16: LOOKUPP - Lookup Parent Directory
18.14. 操作16:LOOKUPP-查找父目录
18.14.1. ARGUMENTS
18.14.1. 论据
   /* CURRENT_FH: object */
   void;
        
   /* CURRENT_FH: object */
   void;
        
18.14.2. RESULTS
18.14.2. 后果
   struct LOOKUPP4res {
           /* new CURRENT_FH: parent directory */
           nfsstat4        status;
   };
        
   struct LOOKUPP4res {
           /* new CURRENT_FH: parent directory */
           nfsstat4        status;
   };
        
18.14.3. DESCRIPTION
18.14.3. 描述

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。

As is the case with 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。

If the requester's security flavor does not match that configured for the parent directory, then the server SHOULD return NFS4ERR_WRONGSEC (a future minor revision of NFSv4 may upgrade this to MUST) in the LOOKUPP response. However, if the server does so, it MUST support the SECINFO_NO_NAME operation (Section 18.45), so that the client can gracefully determine the correct security flavor.

如果请求者的安全风格与为父目录配置的不匹配,则服务器应在LOOKUPP响应中返回NFS4ERR_ErrorSec(NFSv4的未来小版本可能会将其升级为MUST)。但是,如果服务器这样做,它必须支持SECINFO_NO_NAME操作(第18.45节),以便客户端能够优雅地确定正确的安全风格。

If the current filehandle is a named attribute directory that is associated with a file system object via OPENATTR (i.e., not a sub-directory of a named attribute directory), LOOKUPP SHOULD return the filehandle of the associated file system object.

如果当前文件句柄是通过OPENATTR与文件系统对象关联的命名属性目录(即,不是命名属性目录的子目录),LOOKUPP应返回关联文件系统对象的文件句柄。

18.14.4. IMPLEMENTATION
18.14.4. 实施

An issue to note is upward navigation from named attribute directories. The named attribute directories are essentially detached from the namespace, and this property should be safely represented in the client operating environment. LOOKUPP on a named attribute directory may return the filehandle of the associated file, and conveying this to applications might be unsafe as many applications expect the parent of an object to always be a directory. Therefore, the client may want to hide the parent of named attribute directories (represented as ".." in UNIX) or represent the named attribute directory as its own parent (as is typically done for the file system root directory in UNIX).

需要注意的一个问题是从命名属性目录向上导航。命名属性目录基本上与名称空间分离,该属性应该在客户端操作环境中安全地表示。命名属性目录上的LOOKUPP可能会返回关联文件的filehandle,将其传递给应用程序可能不安全,因为许多应用程序希望对象的父对象始终是目录。因此,客户机可能希望隐藏命名属性目录的父目录(在UNIX中表示为“.”),或者将命名属性目录表示为其自己的父目录(在UNIX中通常对文件系统根目录这样做)。

18.15. Operation 17: NVERIFY - Verify Difference in Attributes
18.15. 操作17:NVERIFY-验证属性差异
18.15.1. ARGUMENTS
18.15.1. 论据
   struct NVERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   struct NVERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
18.15.2. RESULTS
18.15.2. 后果
   struct NVERIFY4res {
           nfsstat4        status;
   };
        
   struct NVERIFY4res {
           nfsstat4        status;
   };
        
18.15.3. DESCRIPTION
18.15.3. 描述

This operation is used to prefix a sequence of operations to be performed if one or more attributes have changed on some file system object. If all the attributes match, then the error NFS4ERR_SAME MUST be returned.

如果某个文件系统对象上的一个或多个属性已更改,则此操作用于为要执行的操作序列添加前缀。如果所有属性都匹配,则必须返回错误NFS4ERR_SAME。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.15.4. IMPLEMENTATION
18.15.4. 实施

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:

此操作作为缓存验证运算符很有用。如果属性所属的对象已更改,则以下操作可能会获取与该对象关联的新数据,例如,检查文件是否已更改,如果已更改,则获取新数据:

SEQUENCE PUTFH fh NVERIFY attrbits attrs READ 0 32767

序列PUTFH fh N验证属性位属性读取0 32767

Contrast this with NFSv3, which would first send a GETATTR in one request/reply round trip, and then if attributes indicated that the client's cache was stale, then send a READ in another request/reply round trip.

这与NFSv3形成对比,NFSv3首先在一个请求/应答往返中发送一个GETATTR,然后如果属性指示客户端的缓存已过时,则在另一个请求/应答往返中发送一个READ。

In the case that a RECOMMENDED attribute is specified in the NVERIFY operation and the server does not support that attribute for the file system object, the error NFS4ERR_ATTRNOTSUPP is returned to the client.

如果在NVERIFY操作中指定了建议的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_ATTRNOTSUPP返回给客户端。

When the attribute rdattr_error or any set-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将返回给客户端。

18.16. Operation 18: OPEN - Open a Regular File
18.16. 操作18:打开-打开常规文件
18.16.1. ARGUMENTS
18.16.1. 论据
   /*
    * Various definitions for OPEN
    */
   enum createmode4 {
           UNCHECKED4      = 0,
           GUARDED4        = 1,
           /* Deprecated in NFSv4.1. */
           EXCLUSIVE4      = 2,
           /*
            * New to NFSv4.1. If session is persistent,
            * GUARDED4 MUST be used.  Otherwise, use
            * EXCLUSIVE4_1 instead of EXCLUSIVE4.
            */
           EXCLUSIVE4_1    = 3
   };
        
   /*
    * Various definitions for OPEN
    */
   enum createmode4 {
           UNCHECKED4      = 0,
           GUARDED4        = 1,
           /* Deprecated in NFSv4.1. */
           EXCLUSIVE4      = 2,
           /*
            * New to NFSv4.1. If session is persistent,
            * GUARDED4 MUST be used.  Otherwise, use
            * EXCLUSIVE4_1 instead of EXCLUSIVE4.
            */
           EXCLUSIVE4_1    = 3
   };
        
   struct creatverfattr {
            verifier4      cva_verf;
            fattr4         cva_attrs;
   };
        
   struct creatverfattr {
            verifier4      cva_verf;
            fattr4         cva_attrs;
   };
        
   union createhow4 switch (createmode4 mode) {
    case UNCHECKED4:
    case GUARDED4:
            fattr4         createattrs;
    case EXCLUSIVE4:
            verifier4      createverf;
    case EXCLUSIVE4_1:
            creatverfattr  ch_createboth;
   };
        
   union createhow4 switch (createmode4 mode) {
    case UNCHECKED4:
    case GUARDED4:
            fattr4         createattrs;
    case EXCLUSIVE4:
            verifier4      createverf;
    case EXCLUSIVE4_1:
            creatverfattr  ch_createboth;
   };
        
   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;
        
   /* new flags for share_access field of OPEN4args */
   const OPEN4_SHARE_ACCESS_WANT_DELEG_MASK        = 0xFF00;
   const OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE     = 0x0000;
   const OPEN4_SHARE_ACCESS_WANT_READ_DELEG        = 0x0100;
   const OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG       = 0x0200;
   const OPEN4_SHARE_ACCESS_WANT_ANY_DELEG         = 0x0300;
   const OPEN4_SHARE_ACCESS_WANT_NO_DELEG          = 0x0400;
   const OPEN4_SHARE_ACCESS_WANT_CANCEL            = 0x0500;
        
   /* new flags for share_access field of OPEN4args */
   const OPEN4_SHARE_ACCESS_WANT_DELEG_MASK        = 0xFF00;
   const OPEN4_SHARE_ACCESS_WANT_NO_PREFERENCE     = 0x0000;
   const OPEN4_SHARE_ACCESS_WANT_READ_DELEG        = 0x0100;
   const OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG       = 0x0200;
   const OPEN4_SHARE_ACCESS_WANT_ANY_DELEG         = 0x0300;
   const OPEN4_SHARE_ACCESS_WANT_NO_DELEG          = 0x0400;
   const OPEN4_SHARE_ACCESS_WANT_CANCEL            = 0x0500;
        

const OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL = 0x10000;

const OPEN4\u SHARE\u ACCESS\u WANT\u SIGNAL\u DELEG\u当\u RESRC\u AVAIL=0x10000时;

const OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED = 0x20000;

const OPEN4\u SHARE\u ACCESS\u WANT\u PUSH\u DELEG\u当\u uncontracted=0x20000时;

   enum open_delegation_type4 {
           OPEN_DELEGATE_NONE      = 0,
           OPEN_DELEGATE_READ      = 1,
           OPEN_DELEGATE_WRITE     = 2,
           OPEN_DELEGATE_NONE_EXT  = 3 /* new to v4.1 */
   };
        
   enum open_delegation_type4 {
           OPEN_DELEGATE_NONE      = 0,
           OPEN_DELEGATE_READ      = 1,
           OPEN_DELEGATE_WRITE     = 2,
           OPEN_DELEGATE_NONE_EXT  = 3 /* new to v4.1 */
   };
        

enum open_claim_type4 { /* * Not a reclaim. */ CLAIM_NULL = 0,

enum open_claim_type4{/**不是回收。*/claim_NULL=0,

CLAIM_PREVIOUS = 1, CLAIM_DELEGATE_CUR = 2, CLAIM_DELEGATE_PREV = 3,

索赔前一项=1,索赔代表当前=2,索赔代表前一项=3,

           /*
            * Not a reclaim.
            *
            * Like CLAIM_NULL, but object identified
            * by the current filehandle.
            */
           CLAIM_FH                = 4, /* new to v4.1 */
        
           /*
            * Not a reclaim.
            *
            * Like CLAIM_NULL, but object identified
            * by the current filehandle.
            */
           CLAIM_FH                = 4, /* new to v4.1 */
        
           /*
            * Like CLAIM_DELEGATE_CUR, but object identified
            * by current filehandle.
            */
           CLAIM_DELEG_CUR_FH      = 5, /* new to v4.1 */
        
           /*
            * Like CLAIM_DELEGATE_CUR, but object identified
            * by current filehandle.
            */
           CLAIM_DELEG_CUR_FH      = 5, /* new to v4.1 */
        
           /*
            * Like CLAIM_DELEGATE_PREV, but object identified
            * by current filehandle.
            */
           CLAIM_DELEG_PREV_FH     = 6 /* new to v4.1 */
   };
        
           /*
            * Like CLAIM_DELEGATE_PREV, but object identified
            * by current filehandle.
            */
           CLAIM_DELEG_PREV_FH     = 6 /* new to v4.1 */
   };
        
   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;
    /*
     * 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;
        
   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 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;
        
    /*
     * Like CLAIM_NULL.  No special rights
     * to file.  Ordinary OPEN of the
     * specified file by current filehandle.
     */
    case CLAIM_FH: /* new to v4.1 */
           /* CURRENT_FH: regular file to open */
           void;
        
    /*
     * Like CLAIM_NULL.  No special rights
     * to file.  Ordinary OPEN of the
     * specified file by current filehandle.
     */
    case CLAIM_FH: /* new to v4.1 */
           /* CURRENT_FH: regular file to open */
           void;
        
    /*
     * Like CLAIM_DELEGATE_PREV.  Right to file based on a
     * delegation granted to a previous boot
     * instance of the client.  File is identified by
     * by filehandle.
     */
    case CLAIM_DELEG_PREV_FH: /* new to v4.1 */
           /* CURRENT_FH: file being opened */
           void;
        
    /*
     * Like CLAIM_DELEGATE_PREV.  Right to file based on a
     * delegation granted to a previous boot
     * instance of the client.  File is identified by
     * by filehandle.
     */
    case CLAIM_DELEG_PREV_FH: /* new to v4.1 */
           /* CURRENT_FH: file being opened */
           void;
        
    /*
     * Like CLAIM_DELEGATE_CUR.  Right to file based on
     * a delegation granted by the server.
     * File is identified by filehandle.
     */
    case CLAIM_DELEG_CUR_FH: /* new to v4.1 */
            /* CURRENT_FH: file being opened */
            stateid4       oc_delegate_stateid;
        
    /*
     * Like CLAIM_DELEGATE_CUR.  Right to file based on
     * a delegation granted by the server.
     * File is identified by filehandle.
     */
    case CLAIM_DELEG_CUR_FH: /* new to v4.1 */
            /* CURRENT_FH: file being opened */
            stateid4       oc_delegate_stateid;
        

};

};

   /*
    * 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;
   };
        
18.16.2. RESULTS
18.16.2. 后果
   struct open_read_delegation4 {
    stateid4 stateid;    /* Stateid for delegation*/
    bool     recall;     /* Pre-recalled flag for
                            delegations obtained
                            by reclaim (CLAIM_PREVIOUS) */
        
   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 */
   };
        
    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) */
        
   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.  */
        
    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. */
   };
        
    nfsace4   permissions; /* Defines users who don't
                              need an ACCESS call as
                              part of a delegated
                              open. */
   };
        
   enum why_no_delegation4 { /* new to v4.1 */
           WND4_NOT_WANTED         = 0,
           WND4_CONTENTION         = 1,
           WND4_RESOURCE           = 2,
           WND4_NOT_SUPP_FTYPE     = 3,
           WND4_WRITE_DELEG_NOT_SUPP_FTYPE = 4,
           WND4_NOT_SUPP_UPGRADE   = 5,
           WND4_NOT_SUPP_DOWNGRADE = 6,
           WND4_CANCELLED          = 7,
           WND4_IS_DIR             = 8
   };
        
   enum why_no_delegation4 { /* new to v4.1 */
           WND4_NOT_WANTED         = 0,
           WND4_CONTENTION         = 1,
           WND4_RESOURCE           = 2,
           WND4_NOT_SUPP_FTYPE     = 3,
           WND4_WRITE_DELEG_NOT_SUPP_FTYPE = 4,
           WND4_NOT_SUPP_UPGRADE   = 5,
           WND4_NOT_SUPP_DOWNGRADE = 6,
           WND4_CANCELLED          = 7,
           WND4_IS_DIR             = 8
   };
        
   union open_none_delegation4 /* new to v4.1 */
   switch (why_no_delegation4 ond_why) {
           case WND4_CONTENTION:
                   bool ond_server_will_push_deleg;
           case WND4_RESOURCE:
                   bool ond_server_will_signal_avail;
           default:
                   void;
   };
        
   union open_none_delegation4 /* new to v4.1 */
   switch (why_no_delegation4 ond_why) {
           case WND4_CONTENTION:
                   bool ond_server_will_push_deleg;
           case WND4_RESOURCE:
                   bool ond_server_will_signal_avail;
           default:
                   void;
   };
        
   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;
           case OPEN_DELEGATE_NONE_EXT: /* new to v4.1 */
                   open_none_delegation4 od_whynone;
   };
        
   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;
           case OPEN_DELEGATE_NONE_EXT: /* new to v4.1 */
                   open_none_delegation4 od_whynone;
   };
        
   /*
    * Result flags
    */
        
   /*
    * 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;
   /* Server will preserve file if removed while open */
   const OPEN4_RESULT_PRESERVE_UNLINKED = 0x00000008;
        
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
   /* Type of file locking behavior at the server */
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;
   /* Server will preserve file if removed while open */
   const OPEN4_RESULT_PRESERVE_UNLINKED = 0x00000008;
        
   /*
    * Server may use CB_NOTIFY_LOCK on locks
    * derived from this open
    */
   const OPEN4_RESULT_MAY_NOTIFY_LOCK = 0x00000020;
        
   /*
    * Server may use CB_NOTIFY_LOCK on locks
    * derived from this open
    */
   const OPEN4_RESULT_MAY_NOTIFY_LOCK = 0x00000020;
        
   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 */
   };
        
   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 */
   };
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* New CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
           void;
   };
        
   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* New CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
           void;
   };
        
18.16.3. DESCRIPTION
18.16.3. 描述

The OPEN operation opens a regular file in a directory with the provided name or filehandle. OPEN can also create a file if a name is provided, and the client specifies it wants to create a file. Specification of whether or not a file is to be created, and the method of creation is via the openhow parameter. The openhow parameter consists of a switched union (data type opengflag4), which switches on the value of opentype (OPEN4_NOCREATE or OPEN4_CREATE). If OPEN4_CREATE is specified, this leads to another switched union (data type createhow4) that supports four cases of creation methods: UNCHECKED4, GUARDED4, EXCLUSIVE4, or EXCLUSIVE4_1. If opentype is OPEN4_CREATE, then the claim field of the claim field MUST be one of CLAIM_NULL, CLAIM_DELEGATE_CUR, or CLAIM_DELEGATE_PREV, because these claim methods include a component of a file name.

打开操作使用提供的名称或文件句柄打开目录中的常规文件。如果提供了名称,并且客户端指定要创建文件,则OPEN还可以创建文件。是否创建文件的规范,创建方法是通过openhow参数。openhow参数由一个交换的联合(数据类型opengflag4)组成,该联合打开opentype(OPEN4_NOCREATE或OPEN4_CREATE)的值。如果指定了OPEN4_CREATE,这将导致另一个交换联合(数据类型createhow4),它支持四种创建方法:UNCHECKED4、GUARDED4、EXCLUSIVE4或EXCLUSIVE4_1。如果opentype是OPEN4\u CREATE,则索赔字段的索赔字段必须是索赔NULL、索赔委托CUR或索赔委托PREV中的一个,因为这些索赔方法包括文件名的一个组件。

Upon success (which might entail creation of a new file), the current filehandle is replaced by that of the created or existing object.

成功后(可能需要创建新文件),当前文件句柄将替换为已创建或现有对象的文件句柄。

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 or EXCLUSIVE4_1 and the current filehandle is a named attribute directory, the server will return EINVAL.

如果当前文件句柄是命名属性目录,则OPEN将创建或打开命名属性文件。请注意,不支持以独占方式创建命名属性。如果createmode为EXCLUSIVE4或EXCLUSIVE4_1,且当前文件句柄为命名属性目录,则服务器将返回EINVAL。

UNCHECKED4 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 UNCHECKED4 create encounters an existing file, the attributes specified by createattrs are not used, except that when createattrs specifies the size attribute with a size of zero, the existing file is truncated.

UNCHECKED4表示如果该名称的文件不存在,并且遇到该名称的现有常规文件不是错误,则应创建该文件。对于这种类型的创建,createattrs指定文件的初始属性集。属性集可以包括对常规文件有效的任何可写属性。当未选中的4 create遇到现有文件时,将不使用createattrs指定的属性,除非createattrs指定大小为零的size属性,否则现有文件将被截断。

If GUARDED4 is specified, the server checks for the presence of a duplicate object by name before performing the create. If a duplicate exists, NFS4ERR_EXIST is returned. If the object does not exist, the request is performed as described for UNCHECKED4.

如果指定了GUARDED4,服务器将在执行创建之前按名称检查是否存在重复的对象。如果存在重复项,则返回NFS4ERR_EXIST。如果对象不存在,则按照UNCHECKED4所述执行请求。

For the UNCHECKED4 and GUARDED4 cases, where the operation is successful, the server will return to the client an attribute mask signifying which attributes were successfully set for the object.

对于未选中的4和GUARDED4情况,如果操作成功,服务器将向客户端返回一个属性掩码,表示已成功为对象设置了哪些属性。

EXCLUSIVE4_1 and EXCLUSIVE4 specify 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.

EXCLUSIVE4_1和EXCLUSIVE4指定服务器遵循独占创建语义,使用验证器确保以独占方式创建目标。服务器应按名称检查是否存在重复的对象。如果对象不存在,服务器将创建该对象并将验证器与该对象一起存储。如果对象确实存在并且存储的验证器与客户端提供的验证器匹配,则服务器将现有对象用作新创建的对象。如果存储的验证器不匹配,则返回NFS4ERR_EXIST错误。

If using EXCLUSIVE4, and if the server uses attributes to store the exclusive create verifier, the server will signify which attributes it used by setting the appropriate bits in the attribute mask that is returned in the results. Unlike UNCHECKED4, GUARDED4, and EXCLUSIVE4_1, EXCLUSIVE4 does not support the setting of attributes at file creation, and after a successful OPEN via EXCLUSIVE4, the client MUST send a SETATTR to set attributes to a known state.

如果使用EXCLUSIVE4,并且如果服务器使用属性存储ExclusiveCreate验证器,则服务器将通过在结果中返回的属性掩码中设置适当的位来指示它使用了哪些属性。与UNCHECKED4、GUARDED4和EXCLUSIVE4_1不同,EXCLUSIVE4不支持在文件创建时设置属性,并且在通过EXCLUSIVE4成功打开后,客户端必须发送SETATTR以将属性设置为已知状态。

In NFSv4.1, EXCLUSIVE4 has been deprecated in favor of EXCLUSIVE4_1. Unlike EXCLUSIVE4, attributes may be provided in the EXCLUSIVE4_1 case, but because the server may use attributes of the target object to store the verifier, the set of allowable attributes may be fewer than the set of attributes SETATTR allows. The allowable attributes for EXCLUSIVE4_1 are indicated in the suppattr_exclcreat (Section 5.8.1.14) attribute. If the client attempts to set in cva_attrs an attribute that is not in suppattr_exclcreat, the server MUST return NFS4ERR_INVAL. The response field, attrset, indicates both which attributes the server set from cva_attrs and which attributes the server used to store the verifier. As described in

在NFSv4.1中,排他性4已被弃用,取而代之的是排他性4_1。与EXCLUSIVE4不同,在EXCLUSIVE4_1情况下可以提供属性,但是由于服务器可以使用目标对象的属性来存储验证器,所以允许的属性集可能小于SETATTR允许的属性集。EXCLUSIVE4_1的允许属性在suppattr_ExclusiveCreat(第5.8.1.14节)属性中指出。如果客户端试图在cva_attrs中设置一个不在suppattr_excreate中的属性,则服务器必须返回NFS4ERR_INVAL。响应字段attrset指示服务器从cva_attrs设置的属性以及服务器用于存储验证器的属性。如中所述

Section 18.16.4, the client can compare cva_attrs.attrmask with attrset to determine which attributes were used to store the verifier.

在第18.16.4节中,客户可以将cva_attrs.attrsmask与attrset进行比较,以确定用于存储验证器的属性。

With the addition of persistent sessions and pNFS, under some conditions EXCLUSIVE4 MUST NOT be used by the client or supported by the server. The following table summarizes the appropriate and mandated exclusive create methods for implementations of NFSv4.1:

通过添加持久会话和PNF,在某些情况下,客户机不得使用EXCLUSIVE4或服务器不支持EXCLUSIVE4。下表总结了NFSv4.1实现的适当且强制的独占创建方法:

Required methods for exclusive create

独占创建所需的方法

   +----------------+-----------+---------------+----------------------+
   | Persistent     | Server    | Server        | Client Allowed       |
   | Reply Cache    | Supports  | REQUIRED      |                      |
   | Enabled        | pNFS      |               |                      |
   +----------------+-----------+---------------+----------------------+
   | no             | no        | EXCLUSIVE4_1  | EXCLUSIVE4_1         |
   |                |           | and           | (SHOULD) or          |
   |                |           | EXCLUSIVE4    | EXCLUSIVE4 (SHOULD   |
   |                |           |               | NOT)                 |
   | no             | yes       | EXCLUSIVE4_1  | EXCLUSIVE4_1         |
   | yes            | no        | GUARDED4      | GUARDED4             |
   | yes            | yes       | GUARDED4      | GUARDED4             |
   +----------------+-----------+---------------+----------------------+
        
   +----------------+-----------+---------------+----------------------+
   | Persistent     | Server    | Server        | Client Allowed       |
   | Reply Cache    | Supports  | REQUIRED      |                      |
   | Enabled        | pNFS      |               |                      |
   +----------------+-----------+---------------+----------------------+
   | no             | no        | EXCLUSIVE4_1  | EXCLUSIVE4_1         |
   |                |           | and           | (SHOULD) or          |
   |                |           | EXCLUSIVE4    | EXCLUSIVE4 (SHOULD   |
   |                |           |               | NOT)                 |
   | no             | yes       | EXCLUSIVE4_1  | EXCLUSIVE4_1         |
   | yes            | no        | GUARDED4      | GUARDED4             |
   | yes            | yes       | GUARDED4      | GUARDED4             |
   +----------------+-----------+---------------+----------------------+
        

Table 10

表10

If CREATE_SESSION4_FLAG_PERSIST is set in the results of CREATE_SESSION, the reply cache is persistent (see Section 18.36). If the EXCHGID4_FLAG_USE_PNFS_MDS flag is set in the results from EXCHANGE_ID, the server is a pNFS server (see Section 18.35). If the client attempts to use EXCLUSIVE4 on a persistent session, or a session derived from an EXCHGID4_FLAG_USE_PNFS_MDS client ID, the server MUST return NFS4ERR_INVAL.

如果在CREATE_会话的结果中设置了CREATE_SESSION4_FLAG_PERSISTER,则应答缓存是持久的(参见第18.36节)。如果EXCHANGE ID的结果中设置了EXCHGID4_标志_使用_PNFS_MDS标志,则该服务器为PNFS服务器(请参阅第18.35节)。如果客户端尝试在持久会话上使用EXCLUSIVE4,或从EXCHGID4_标志_use_PNFS_MDS客户端ID派生的会话,则服务器必须返回NFS4ERR_INVAL。

With persistent sessions, exclusive create semantics are fully achievable via GUARDED4, and so EXCLUSIVE4 or EXCLUSIVE4_1 MUST NOT be used. When pNFS is being used, the layout_hint attribute might not be supported after the file is created. Only the EXCLUSIVE4_1 and GUARDED methods of exclusive file creation allow the atomic setting of attributes.

对于持久会话,通过GUARDED4完全可以实现独占创建语义,因此不能使用EXCLUSIVE4或EXCLUSIVE4_1。使用pNFS时,创建文件后可能不支持布局提示属性。只有独占的e4_1和独占文件创建的受保护方法才允许属性的原子设置。

For the target directory, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 data type, 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数据类型的原子字段,服务器将指示是否以原子方式获得了与链接创建相关的更改前后属性。

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 OPEN4_SHARE_DENY_NONE. In the case that there is an existing SHARE reservation that conflicts with the OPEN request, the server returns the error NFS4ERR_SHARE_DENIED. For additional discussion of SHARE semantics, see Section 9.7.

“打开”操作使用打开参数的“共享访问”和“共享拒绝”字段提供Windows共享保留功能。客户端在打开时指定所需的共享访问和共享拒绝模式。对于不直接支持共享(即UNIX)的客户端,预期的拒绝值为OPEN4_SHARE_deny_NONE。如果存在与打开请求冲突的现有共享保留,服务器将返回错误NFS4ERR_SHARE_DENIED。有关共享语义的更多讨论,请参见第9.7节。

For each OPEN, the client provides a value for the owner field of the OPEN argument. The owner field is of data type open_owner4, and contains a field called clientid and a field called owner. The client can set the clientid field to any value and the server MUST ignore it. Instead, the server MUST derive the client ID from the session ID of the SEQUENCE operation of the COMPOUND request.

对于每个OPEN,客户机都为OPEN参数的owner字段提供一个值。owner字段的数据类型为open_owner4,包含一个名为clientid的字段和一个名为owner的字段。客户端可以将clientid字段设置为任何值,服务器必须忽略它。相反,服务器必须从复合请求序列操作的会话ID派生客户机ID。

The "seqid" field of the request is not used in NFSv4.1, but it MAY be any value and the server MUST ignore it.

请求的“seqid”字段未在NFSv4.1中使用,但它可以是任何值,服务器必须忽略它。

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 that the client claims to possess. There are seven claim types as follows:

OPEN参数的“claim”字段用于指定要打开的文件以及客户端声称拥有的状态信息。有七种索赔类型,如下所示:

   +----------------------+--------------------------------------------+
   | open type            | description                                |
   +----------------------+--------------------------------------------+
   | CLAIM_NULL, CLAIM_FH | For the client, this is a new OPEN request |
   |                      | and there is no previous state associated  |
   |                      | with the file for the client.  With        |
   |                      | CLAIM_NULL, the file is identified by the  |
   |                      | current filehandle and the specified       |
   |                      | component name.  With CLAIM_FH (new to     |
   |                      | NFSv4.1), the file is identified by just   |
   |                      | the current filehandle.                    |
   | CLAIM_PREVIOUS       | The client is claiming basic OPEN state    |
   |                      | for a file that was held previous to a     |
   |                      | server restart.  Generally used when a     |
   |                      | server is returning persistent             |
   |                      | filehandles; the client may not have the   |
   |                      | file name to reclaim the OPEN.             |
   | CLAIM_DELEGATE_CUR,  | The client is claiming a delegation for    |
   | CLAIM_DELEG_CUR_FH   | OPEN as granted by the server.  Generally, |
   |                      | this is done as part of recalling a        |
   |                      | delegation.  With CLAIM_DELEGATE_CUR, the  |
   |                      | file is identified by the current          |
   |                      | filehandle and the specified component     |
   |                      | name.  With CLAIM_DELEG_CUR_FH (new to     |
   |                      | NFSv4.1), the file is identified by just   |
   |                      | the current filehandle.                    |
   | CLAIM_DELEGATE_PREV, | The client is claiming a delegation        |
   | CLAIM_DELEG_PREV_FH  | granted to a previous client instance;     |
   |                      | used after the client restarts.  The       |
   |                      | server MAY support CLAIM_DELEGATE_PREV     |
   |                      | and/or CLAIM_DELEG_PREV_FH (new to         |
   |                      | NFSv4.1).  If it does support either claim |
   |                      | type, CREATE_SESSION MUST NOT remove the   |
   |                      | client's delegation state, and the server  |
   |                      | MUST support the DELEGPURGE operation.     |
   +----------------------+--------------------------------------------+
        
   +----------------------+--------------------------------------------+
   | open type            | description                                |
   +----------------------+--------------------------------------------+
   | CLAIM_NULL, CLAIM_FH | For the client, this is a new OPEN request |
   |                      | and there is no previous state associated  |
   |                      | with the file for the client.  With        |
   |                      | CLAIM_NULL, the file is identified by the  |
   |                      | current filehandle and the specified       |
   |                      | component name.  With CLAIM_FH (new to     |
   |                      | NFSv4.1), the file is identified by just   |
   |                      | the current filehandle.                    |
   | CLAIM_PREVIOUS       | The client is claiming basic OPEN state    |
   |                      | for a file that was held previous to a     |
   |                      | server restart.  Generally used when a     |
   |                      | server is returning persistent             |
   |                      | filehandles; the client may not have the   |
   |                      | file name to reclaim the OPEN.             |
   | CLAIM_DELEGATE_CUR,  | The client is claiming a delegation for    |
   | CLAIM_DELEG_CUR_FH   | OPEN as granted by the server.  Generally, |
   |                      | this is done as part of recalling a        |
   |                      | delegation.  With CLAIM_DELEGATE_CUR, the  |
   |                      | file is identified by the current          |
   |                      | filehandle and the specified component     |
   |                      | name.  With CLAIM_DELEG_CUR_FH (new to     |
   |                      | NFSv4.1), the file is identified by just   |
   |                      | the current filehandle.                    |
   | CLAIM_DELEGATE_PREV, | The client is claiming a delegation        |
   | CLAIM_DELEG_PREV_FH  | granted to a previous client instance;     |
   |                      | used after the client restarts.  The       |
   |                      | server MAY support CLAIM_DELEGATE_PREV     |
   |                      | and/or CLAIM_DELEG_PREV_FH (new to         |
   |                      | NFSv4.1).  If it does support either claim |
   |                      | type, CREATE_SESSION MUST NOT remove the   |
   |                      | client's delegation state, and the server  |
   |                      | MUST support the DELEGPURGE operation.     |
   +----------------------+--------------------------------------------+
        

For OPEN requests that reach the server during the grace period, the server returns an error of NFS4ERR_GRACE. The following claim types are exceptions:

对于在宽限期内到达服务器的打开请求,服务器返回NFS4ERR_grace错误。以下索赔类型属于例外情况:

o OPEN requests specifying the claim type CLAIM_PREVIOUS are devoted to reclaiming opens after a server restart and are typically only valid during the grace period.

o 指定声明类型claim_PREVIOUS的打开请求用于在服务器重新启动后回收打开的文件,通常仅在宽限期内有效。

o OPEN requests specifying the claim types CLAIM_DELEGATE_CUR and CLAIM_DELEG_CUR_FH are valid both during and after the grace period. Since the granting of the delegation that they are

o 指定索赔类型claim_DELEGATE_CUR和claim_DELEG_CUR_FH的打开请求在宽限期期间和之后均有效。自代表团批准后

subordinate to assures that there is no conflict with locks to be reclaimed by other clients, the server need not return NFS4ERR_GRACE when these are received during the grace period.

为了确保与要由其他客户端回收的锁没有冲突,服务器不需要在宽限期内收到NFS4ERR_GRACE时返回NFS4ERR_GRACE。

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 Section 10.4. 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.

对于任何打开的请求,服务器可能返回一个打开的委托,这允许进一步的打开和关闭在客户端本地处理,如第10.4节所述。请注意,委派由服务器决定。客户不应假设在特定实例中会或不会授予委托。无论是哪种情况,都应该随时做好准备。部分例外情况是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允许服务器返回控制如何处理打开的文件的信息。

o OPEN4_RESULT_CONFIRM is deprecated and MUST NOT be returned by an NFSv4.1 server.

o OPEN4\u结果\u确认已弃用,NFSv4.1服务器不得返回。

o OPEN4_RESULT_LOCKTYPE_POSIX indicates that the server's byte-range locking behavior supports the complete set of POSIX locking techniques [24]. From this, the client can choose to manage byte-range locking state in a way to handle a mismatch of byte-range locking management.

o OPEN4_RESULT_LOCKTYPE_POSIX表示服务器的字节范围锁定行为支持整套POSIX锁定技术[24]。由此,客户端可以选择以处理字节范围锁定管理不匹配的方式来管理字节范围锁定状态。

o OPEN4_RESULT_PRESERVE_UNLINKED indicates that the server will preserve the open file if the client (or any other client) removes the file as long as it is open. Furthermore, the server promises to preserve the file through the grace period after server restart, thereby giving the client the opportunity to reclaim its open.

o OPEN4_RESULT_PRESERVE_UNLINKED表示如果客户端(或任何其他客户端)在文件打开时删除该文件,服务器将保留该打开的文件。此外,服务器承诺在服务器重新启动后的宽限期内保留文件,从而使客户机有机会恢复打开的文件。

o OPEN4_RESULT_MAY_NOTIFY_LOCK indicates that the server may attempt CB_NOTIFY_LOCK callbacks for locks on this file. This flag is a hint only, and may be safely ignored by the client.

o OPEN4_RESULT_MAY_NOTIFY_LOCK表示服务器可能尝试CB_NOTIFY_LOCK回调此文件上的锁。此标志只是一个提示,客户端可以安全地忽略它。

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 Section 14.5 for further discussion.

如果组件长度为零,将返回NFS4ERR_INVAL。该组件还需要进行常规UTF-8、字符支持和名称检查。进一步讨论见第14.5节。

When an OPEN is done and the specified open-owner 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 open-owner. In this case, the

当打开完成且指定的打开所有者已打开结果文件句柄时,结果是将新共享与现有状态一起“或”并拒绝状态。在这种情况下,即使多个打开已完成,也只需完成一次关闭。当此类公开交易完成后,检查新公开交易的股份预留情况将正常进行,同一公开交易所有人持有的现有公开交易也不例外。在这种情况下

stateid returned as an "other" field that matches that of the previous open while the "seqid" field is incremented to reflect the change status due to the new open.

stateid作为“其他”字段返回,该字段与以前打开的字段相匹配,“seqid”字段递增,以反映由于新打开而导致的更改状态。

If the underlying file system 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 file system.

如果服务器上的底层文件系统只能以只读模式访问,并且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 file system. 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 (UNCHECKED4 or GUARDED4) or cva_attrs (EXCLUSIVE4_1) is specified, and includes an owner, owner_group, or ACE 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(UNCHECKED4或GUARDED4)或cva_attrs(EXCLUSIVE4_1),并且包含RPC调用凭据中的主体无权为其创建文件的所有者、所有者组或ACE,则服务器可能会返回NFS4ERR_PERM。

In the case of an OPEN that specifies a size of zero (e.g., truncation) and the file has named attributes, the named attributes are left as is and are not removed.

如果打开的文件指定大小为零(例如截断),并且文件具有命名属性,则命名属性保持原样,不会删除。

NFSv4.1 gives more precise control to clients over acquisition of delegations via the following new flags for the share_access field of OPEN4args:

NFSv4.1通过OPEN4args的share_访问字段的以下新标志,为客户提供更精确的授权获取控制:

OPEN4_SHARE_ACCESS_WANT_READ_DELEG

OPEN4\u共享\u访问\u想要\u读取\u删除

OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG

OPEN4\u共享\u访问\u想要\u写入\u删除

OPEN4_SHARE_ACCESS_WANT_ANY_DELEG

OPEN4\u共享\u访问\u想要任何\u删除

OPEN4_SHARE_ACCESS_WANT_NO_DELEG

OPEN4\u共享\u访问\u想要\u不需要\u删除

OPEN4_SHARE_ACCESS_WANT_CANCEL

OPEN4\u共享\u访问\u想要\u取消

OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL

OPEN4共享访问需要信号删除可用时

OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED

OPEN4\u共享\u访问\u想要\u推送\u删除\u未竞争时

If (share_access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK) is not zero, then the client will have specified one and only one of:

如果(share\u access&OPEN4\u share\u access\u WANT\u DELEG\u MASK)不为零,则客户端将指定且仅指定以下一项:

OPEN4_SHARE_ACCESS_WANT_READ_DELEG

OPEN4\u共享\u访问\u想要\u读取\u删除

OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG

OPEN4\u共享\u访问\u想要\u写入\u删除

OPEN4_SHARE_ACCESS_WANT_ANY_DELEG

OPEN4\u共享\u访问\u想要任何\u删除

OPEN4_SHARE_ACCESS_WANT_NO_DELEG

OPEN4\u共享\u访问\u想要\u不需要\u删除

OPEN4_SHARE_ACCESS_WANT_CANCEL

OPEN4\u共享\u访问\u想要\u取消

Otherwise, the client is neither indicating a desire nor a non-desire for a delegation, and the server MAY or MAY not return a delegation in the OPEN response.

否则,客户机既不表示希望也不表示不希望进行委派,服务器可能在开放响应中返回委派,也可能不返回委派。

If the server supports the new _WANT_ flags and the client sends one or more of the new flags, then in the event the server does not return a delegation, it MUST return a delegation type of OPEN_DELEGATE_NONE_EXT. The field ond_why in the reply indicates why no delegation was returned and will be one of:

如果服务器支持新的_-WANT_uu标志,并且客户端发送一个或多个新标志,则如果服务器不返回委派,则必须返回“OPEN_DELEGATE_NONE_EXT”的委派类型。答复中的字段ond_why指示未返回委派的原因,并且将是以下字段之一:

WND4_NOT_WANTED The client specified OPEN4_SHARE_ACCESS_WANT_NO_DELEG.

WND4\u不\u想要客户端指定的OPEN4\u共享\u访问\u想要\u不\u删除。

WND4_CONTENTION There is a conflicting delegation or open on the file.

WND4_争用文件上存在冲突的委派或打开。

WND4_RESOURCE Resource limitations prevent the server from granting a delegation.

WND4_资源限制阻止服务器授予委派。

WND4_NOT_SUPP_FTYPE The server does not support delegations on this file type.

WND4_NOT_SUPP_FTYPE服务器不支持此文件类型的委派。

WND4_WRITE_DELEG_NOT_SUPP_FTYPE The server does not support OPEN_DELEGATE_WRITE delegations on this file type.

WND4_WRITE_DELEG_NOT_SUPP_FTYPE服务器不支持此文件类型的OPEN_DELEGATE_WRITE委派。

WND4_NOT_SUPP_UPGRADE The server does not support atomic upgrade of an OPEN_DELEGATE_READ delegation to an OPEN_DELEGATE_WRITE delegation.

WND4\u不支持\u支持\u升级服务器不支持将打开的\u委托读取委托原子升级为打开的\u委托写入委托。

WND4_NOT_SUPP_DOWNGRADE The server does not support atomic downgrade of an OPEN_DELEGATE_WRITE delegation to an OPEN_DELEGATE_READ delegation.

WND4_NOT_SUPP_降级服务器不支持将开放式_委托(写入委托)降级为开放式_委托(读取委托)的原子降级。

WND4_CANCELED The client specified OPEN4_SHARE_ACCESS_WANT_CANCEL and now any "want" for this file object is cancelled.

WND4\u取消了客户端指定的OPEN4\u共享\u访问\u想要\u取消,现在此文件对象的任何“想要”都被取消。

WND4_IS_DIR The specified file object is a directory, and the operation is OPEN or WANT_DELEGATION, which do not support delegations on directories.

WND4_IS_DIR指定的文件对象是一个目录,并且操作是打开的或希望\u委派,这不支持目录上的委派。

OPEN4_SHARE_ACCESS_WANT_READ_DELEG, OPEN_SHARE_ACCESS_WANT_WRITE_DELEG, or OPEN_SHARE_ACCESS_WANT_ANY_DELEG mean, respectively, the client wants an OPEN_DELEGATE_READ, OPEN_DELEGATE_WRITE, or any delegation regardless which of OPEN4_SHARE_ACCESS_READ, OPEN4_SHARE_ACCESS_WRITE, or OPEN4_SHARE_ACCESS_BOTH is set. If the client has an OPEN_DELEGATE_READ delegation on a file and requests an OPEN_DELEGATE_WRITE delegation, then the client is requesting atomic upgrade of its OPEN_DELEGATE_READ delegation to an OPEN_DELEGATE_WRITE delegation. If the client has an OPEN_DELEGATE_WRITE delegation on a file and requests an OPEN_DELEGATE_READ delegation, then the client is requesting atomic downgrade to an OPEN_DELEGATE_READ delegation. A server MAY support atomic upgrade or downgrade. If it does, then the returned delegation_type of OPEN_DELEGATE_READ or OPEN_DELEGATE_WRITE that is different from the delegation type the client currently has, indicates successful upgrade or downgrade. If the server does not support atomic delegation upgrade or downgrade, then ond_why will be set to WND4_NOT_SUPP_UPGRADE or WND4_NOT_SUPP_DOWNGRADE.

OPEN4\u共享\u访问\u想要\u读取\u删除、OPEN4\u共享\u访问\u写入\u删除或OPEN4\u共享\u访问\u想要\u任何\u删除分别表示客户端想要一个OPEN4\u读取、OPEN4\u写入或任何委托,而不管OPEN4\u读取、OPEN4\u共享\u写入或OPEN4\u共享\u访问中的哪一个都已设置。如果客户端在文件上具有OPEN_DELEGATE_READ委派,并请求OPEN_DELEGATE_WRITE委派,则客户端请求将其OPEN_DELEGATE_READ委派的原子升级为OPEN_DELEGATE_WRITE委派。如果客户端在文件上有一个OPEN_DELEGATE_WRITE委派,并请求OPEN_DELEGATE_READ委派,则客户端请求将原子降级为OPEN_DELEGATE_READ委派。服务器可能支持原子升级或降级。如果是,则返回的委托类型OPEN_DELEGATE_READ或OPEN_DELEGATE_WRITE与客户端当前的委托类型不同,表示升级或降级成功。如果服务器不支持原子委派升级或降级,则ond_why将设置为WND4_not_SUPP_upgrade或WND4_not_SUPP_Degrade。

OPEN4_SHARE_ACCESS_WANT_NO_DELEG means that the client wants no delegation.

OPEN4_SHARE_ACCESS_WANT_NO_DELEG表示客户机不需要委托。

OPEN4_SHARE_ACCESS_WANT_CANCEL means that the client wants no delegation and wants to cancel any previously registered "want" for a delegation.

OPEN4\u共享\u访问\u想要\u取消意味着客户端不想要委派,并且想要取消以前为委派注册的任何“想要”。

The client may set one or both of OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL and OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED. However, they will have no effect unless one of following is set:

客户端可以在可用时设置一个或两个OPEN4\u共享\u访问\u想要\u信号\u删除\u,在没有竞争时设置OPEN4\u共享\u访问\u想要\u推送\u删除\u。但是,除非设置了以下任一项,否则它们将无效:

o OPEN4_SHARE_ACCESS_WANT_READ_DELEG

o OPEN4\u共享\u访问\u想要\u读取\u删除

o OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG

o OPEN4\u共享\u访问\u想要\u写入\u删除

o OPEN4_SHARE_ACCESS_WANT_ANY_DELEG

o OPEN4\u共享\u访问\u想要任何\u删除

If the client specifies OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL, then it wishes to register a "want" for a delegation, in the event the OPEN results do not include a delegation. If so and the server denies the delegation due to insufficient resources, the server MAY later inform the client, via the CB_RECALLABLE_OBJ_AVAIL operation, that the resource limitation condition has eased. The server will tell the client that it intends to send a future CB_RECALLABLE_OBJ_AVAIL operation by setting delegation_type in the results to OPEN_DELEGATE_NONE_EXT, ond_why to WND4_RESOURCE, and

如果客户端在可用时指定OPEN4\u共享\u访问\u想要\u信号\u删除\u,则如果打开的结果不包括委派,则希望为委派注册“想要”。如果是这样,并且服务器由于资源不足而拒绝委派,则服务器可稍后通过CB_可调用_OBJ_AVAIL操作通知客户端资源限制条件已缓解。服务器将通过在结果中将委托类型设置为打开委托无外部、ond为什么要WND4资源和

ond_server_will_signal_avail set to TRUE. If ond_server_will_signal_avail is set to TRUE, the server MUST later send a CB_RECALLABLE_OBJ_AVAIL operation.

ond_服务器_将_signal_avail设置为TRUE。如果ond_server_will_signal_avail设置为TRUE,则服务器随后必须发送CB_RECALLABLE_OBJ_avail操作。

If the client specifies OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_UNCONTENDED, then it wishes to register a "want" for a delegation, in the event the OPEN results do not include a delegation. If so and the server denies the delegation due to contention, the server MAY later inform the client, via the CB_PUSH_DELEG operation, that the contention condition has eased. The server will tell the client that it intends to send a future CB_PUSH_DELEG operation by setting delegation_type in the results to OPEN_DELEGATE_NONE_EXT, ond_why to WND4_CONTENTION, and ond_server_will_push_deleg to TRUE. If ond_server_will_push_deleg is TRUE, the server MUST later send a CB_PUSH_DELEG operation.

如果客户端在未竞争时指定OPEN4\u共享\u访问\u想要\u信号\u删除\u,则它希望为委托注册“想要”,如果打开的结果不包括委托。如果是这样,并且服务器由于争用而拒绝委派,则服务器稍后可以通过CB_PUSH_DELEG操作通知客户端争用情况已经缓解。服务器将告诉客户端,它打算通过在结果中设置委托类型来打开委托无EXT、ond为什么WND4争用以及ond服务器将委托DELEG设置为TRUE,从而发送未来的CB\U PUSH\U DELEG操作。如果ond_server_will_push_deleg为TRUE,则服务器稍后必须发送CB_push_deleg操作。

If the client has previously registered a want for a delegation on a file, and then sends a request to register a want for a delegation on the same file, the server MUST return a new error: NFS4ERR_DELEG_ALREADY_WANTED. If the client wishes to register a different type of delegation want for the same file, it MUST cancel the existing delegation WANT.

如果客户端先前已在某个文件上注册了对委派的需要,然后发送了在同一文件上注册对委派的需要的请求,则服务器必须返回一个新错误:NFS4ERR_DELEG_ready_want。如果客户端希望为同一文件注册不同类型的委托,则必须取消现有的委托。

18.16.4. IMPLEMENTATION
18.16.4. 实施

In absence of a persistent session, the client invokes exclusive create by setting the how parameter to EXCLUSIVE4 or EXCLUSIVE4_1. In these cases, the client provides a verifier that can reasonably be expected to be unique. A combination of a client identifier, perhaps the client network address, and a unique number generated by the client, perhaps the RPC transaction identifier, may be appropriate.

在没有持久会话的情况下,客户端通过将how参数设置为EXCLUSIVE4或EXCLUSIVE4_1来调用ExclusiveCreate。在这些情况下,客户提供了一个可以合理预期是唯一的验证者。客户端标识符(可能是客户端网络地址)和由客户端生成的唯一号码(可能是RPC事务标识符)的组合可能是合适的。

If the object does not exist, the server creates the object and stores the verifier in stable storage. For file systems that do not provide a mechanism for the storage of arbitrary file attributes, the server may use one or more elements of the object's metadata 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 server's reply cache for storage of the verifier. A nonpersistent reply cache does not survive a crash and the session and reply cache may be deleted after a network partition that exceeds the lease time, thus opening failure windows.

如果对象不存在,服务器将创建该对象并将验证器存储在稳定的存储器中。对于不提供存储任意文件属性的机制的文件系统,服务器可以使用对象元数据的一个或多个元素来存储验证器。验证器必须存储在稳定的存储器中,以防止请求重新传输时出现错误故障。假定正在执行独占创建,因为独占语义对应用程序至关重要。由于预期用途,exclusive CREATE不完全依赖服务器的应答缓存来存储验证器。非持久应答缓存在崩溃后无法生存,并且会话和应答缓存可能在网络分区超过租用时间后被删除,从而打开故障窗口。

An NFSv4.1 server SHOULD NOT store the verifier in any of the file's RECOMMENDED or REQUIRED attributes. If it does, the server SHOULD use time_modify_set or time_access_set to store the verifier. The server SHOULD NOT store the verifier in the following attributes:

NFSv4.1服务器不应将验证器存储在文件的任何推荐或必需属性中。如果是这样,服务器应该使用time\u modify\u set或time\u access\u set来存储验证器。服务器不应将验证器存储在以下属性中:

acl (it is desirable for access control to be established at creation),

acl(希望在创建时建立访问控制),

dacl (ditto),

dacl(同上),

mode (ditto),

模式(同上),

owner (ditto),

业主(同上),

owner_group (ditto),

业主集团(同上),

retentevt_set (it may be desired to establish retention at creation)

retentevt_set(可能需要在创建时建立保留)

retention_hold (ditto),

保持(同上),

retention_set (ditto),

保持装置(同上),

sacl (it is desirable for auditing control to be established at creation),

sacl(最好在创建时建立审计控制),

size (on some servers, size may have a limited range of values),

大小(在某些服务器上,大小可能具有有限的值范围),

mode_set_masked (as with mode),

模式设置屏蔽(与模式相同),

and

time_creation (a meaningful file creation should be set when the file is created).

创建时间(创建文件时应设置有意义的文件创建)。

Another alternative for the server is to use a named attribute to store the verifier.

服务器的另一种选择是使用命名属性来存储验证器。

Because the EXCLUSIVE4 create method does not specify initial attributes when processing an EXCLUSIVE4 create, the server

由于Exclusive4Create方法在处理Exclusive4Create时不指定初始属性,因此服务器

o SHOULD set the owner of the file to that corresponding to the credential of request's RPC header.

o 应将文件的所有者设置为与请求的RPC头的凭据对应的所有者。

o SHOULD NOT leave the file's access control to anyone but the owner of the file.

o 不应将文件的访问控制权留给文件所有者以外的任何人。

If the server cannot support 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_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。

After the client has performed a successful exclusive create, the attrset response indicates which attributes were used to store the verifier. If EXCLUSIVE4 was used, the attributes set in attrset were used for the verifier. If EXCLUSIVE4_1 was used, the client determines the attributes used for the verifier by comparing attrset with cva_attrs.attrmask; any bits set in the former but not the latter identify the attributes used to store the verifier. The client MUST immediately send a SETATTR to set attributes used to store the verifier. Until it does so, the attributes used to store the verifier cannot be relied upon. The subsequent SETATTR MUST NOT occur in the same COMPOUND request as the OPEN.

客户端成功执行独占创建后,attrset响应将指示用于存储验证器的属性。如果使用了EXCLUSIVE4,则attrset中设置的属性将用于验证器。如果使用了EXCLUSIVE4_1,则客户端通过比较attrset和cva_attrs.attrsmask来确定用于验证器的属性;前者中设置的任何位(而非后者)标识用于存储验证器的属性。客户端必须立即发送SETATTR以设置用于存储验证器的属性。在此之前,无法依赖用于存储验证器的属性。后续SETATTR不能与OPEN在同一复合请求中发生。

Unless a persistent session is used, use of the GUARDED4 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 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 GUARDED4 to prevent against a sequence like create, write, create (retransmitted) from occurring.

除非使用持久会话,否则GUARDED4属性的使用不会提供精确的一次性语义。特别是,如果应答丢失且服务器未检测到请求的重新传输,则即使创建已成功执行,操作也可能因NFS4ERR_存在而失败。如果应用程序未请求独占创建,但在打开文件时请求截断文件,则客户端将使用此行为。在客户端超时并重新传输创建请求的情况下,客户端可以使用GUARDED4来防止发生创建、写入、创建(重新传输)等序列。

For SHARE reservations, the value of the expression (share_access & ~OPEN4_SHARE_ACCESS_WANT_DELEG_MASK) MUST be one of OPEN4_SHARE_ACCESS_READ, OPEN4_SHARE_ACCESS_WRITE, or OPEN4_SHARE_ACCESS_BOTH. If not, the server MUST return NFS4ERR_INVAL. The value of share_deny MUST be one of OPEN4_SHARE_DENY_NONE, OPEN4_SHARE_DENY_READ, OPEN4_SHARE_DENY_WRITE, or OPEN4_SHARE_DENY_BOTH. If not, the server MUST return NFS4ERR_INVAL.

对于共享保留,表达式(SHARE\u access&~OPEN4\u SHARE\u access\u WANT\u DELEG\u MASK)的值必须是OPEN4\u SHARE\u access\u READ、OPEN4\u SHARE\u access\u WRITE或OPEN4\u SHARE\u access\u两者中的一个。否则,服务器必须返回NFS4ERR_INVAL。share\u deny的值必须是OPEN4\u share\u deny\u NONE、OPEN4\u share\u deny\u READ、OPEN4\u share\u deny\u WRITE或OPEN4\u share\u deny\u两者中的一个。否则,服务器必须返回NFS4ERR_INVAL。

Based on the share_access value (OPEN4_SHARE_ACCESS_READ, OPEN4_SHARE_ACCESS_WRITE, or OPEN4_SHARE_ACCESS_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's READ or WRITE operation is not authorized (depending on the share_access value), the server MUST return NFS4ERR_ACCESS.

根据share\u访问值(OPEN4\u share\u access\u READ、OPEN4\u share\u access\u WRITE或OPEN4\u share\u access\u两者),客户端应检查请求者是否具有执行指定操作的正确访问权限。这通常是对当前请求者的文件应用ACL访问规则的结果。但是,与访问操作一样,客户端不应试图猜测服务器的决定,因为访问权限可能会更改,并且可能受ACL框架之外的服务器管理控制。如果请求者的读或写操作未经授权(取决于share_访问值),服务器必须返回NFS4ERR_访问。

Note that if the client ID was not created with the EXCHGID4_FLAG_BIND_PRINC_STATEID capability set in the reply to EXCHANGE_ID, then the server MUST NOT impose any requirement that READs and WRITEs sent for an open file have the same credentials as the OPEN itself, and the server is REQUIRED to perform access checking on the READs and WRITEs themselves. Otherwise, if the reply to EXCHANGE_ID did have EXCHGID4_FLAG_BIND_PRINC_STATEID set, then with one exception, the credentials used in the OPEN request MUST match those used in the READs and WRITEs, and the stateids in the READs and WRITEs MUST match, or be derived from the stateid from the reply to OPEN. The exception is if SP4_SSV or SP4_MACH_CRED state protection is used, and the spo_must_allow result of EXCHANGE_ID includes the READ and/or WRITE operations. In that case, the machine or SSV credential will be allowed to send READ and/or WRITE. See Section 18.35.

请注意,如果客户端ID不是使用在对EXCHANGE\u ID的回复中设置的EXCHGID4\u FLAG\u BIND\u PRINC\u STATEID功能创建的,则服务器不得强制要求为打开的文件发送的读写操作具有与打开本身相同的凭据,服务器需要对读写本身执行访问检查。否则,如果对EXCHANGE\u ID的回复确实设置了EXCHGID4\u FLAG\u BIND\u PRINC\u STATEID,则除了一个例外,打开请求中使用的凭据必须与读取和写入中使用的凭据匹配,并且读取和写入中的STATEID必须匹配,或者从要打开的回复中的STATEID派生。例外情况是,如果使用SP4_SSV或SP4_MACH_CRED状态保护,并且spo_必须允许交换ID的结果包括读和/或写操作。在这种情况下,机器或SSV凭证将被允许发送读取和/或写入。见第18.35节。

If the component provided to OPEN is a symbolic link, the error NFS4ERR_SYMLINK will be returned to the client, while if it is a directory the error NFS4ERR_ISDIR will be returned. If the component is neither of those but not an ordinary file, the error NFS4ERR_WRONG_TYPE is returned. If the current filehandle is not a directory, the error NFS4ERR_NOTDIR will be returned.

如果提供给OPEN的组件是符号链接,则会将错误NFS4ERR_SYMLINK返回给客户端,而如果是目录,则会返回错误NFS4ERR_ISDIR。如果组件既不是这些文件,也不是普通文件,则返回错误NFS4ERR_错误类型。如果当前文件句柄不是目录,将返回错误NFS4ERR_NOTDIR。

The use of the OPEN4_RESULT_PRESERVE_UNLINKED result flag allows a client to avoid the common implementation practice of renaming an open file to ".nfs<unique value>" after it removes the file. After the server returns OPEN4_RESULT_PRESERVE_UNLINKED, if a client sends a REMOVE operation that would reduce the file's link count to zero, the server SHOULD report a value of zero for the numlinks attribute on the file.

使用OPEN4_RESULT_PRESERVE_UNLINKED RESULT标志,客户端可以避免在删除文件后将打开的文件重命名为“.nfs<unique value>”的常见实现实践。在服务器返回OPEN4_RESULT_PRESERVE_UNLINKED后,如果客户端发送一个删除操作,该操作会将文件的链接计数减少到零,则服务器应报告文件的numlinks属性值为零。

If another client has a delegation of the file being opened that conflicts with open being done (sometimes depending on the share_access or share_deny value specified), the delegation(s) MUST be recalled, and the operation cannot proceed until each such delegation is returned or revoked. Except where this happens very

如果另一个客户端对正在打开的文件的委派与正在完成的打开冲突(有时取决于指定的share_access或share_deny值),则必须重新调用委派,并且在返回或撤销每个此类委派之前,操作无法继续。除非这种情况非常严重

quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding. In the case of an OPEN_DELEGATE_WRITE delegation, any open by a different client will conflict, while for an OPEN_DELEGATE_READ delegation, only opens with one of the following characteristics will be considered conflicting:

很快,一个或多个NFS4ERR_延迟错误将返回到委托未完成时发出的请求。在开放式委托-写入委托的情况下,不同客户端的任何开放式委托都会发生冲突,而对于开放式委托-读取委托,只有具有以下特征之一的开放式委托才会被视为冲突:

o The value of share_access includes the bit OPEN4_SHARE_ACCESS_WRITE.

o share\u access的值包括位OPEN4\u share\u access\u WRITE。

o The value of share_deny specifies OPEN4_SHARE_DENY_READ or OPEN4_SHARE_DENY_BOTH.

o share\u deny的值指定OPEN4\u share\u deny\u READ或OPEN4\u share\u deny\u两者。

o OPEN4_CREATE is specified together with UNCHECKED4, the size attribute is specified as zero (for truncation), and an existing file is truncated.

o OPEN4_CREATE与UNCHECKED4一起指定,size属性指定为零(用于截断),现有文件被截断。

If OPEN4_CREATE is specified and the file does not exist and the current filehandle designates a directory for which another client holds a directory delegation, then, unless the delegation is such that the situation can be resolved by sending a notification, the delegation MUST be recalled, and the operation cannot proceed until the delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果指定了OPEN4_CREATE且文件不存在,且当前文件句柄指定了另一个客户端持有目录委派的目录,则除非该委派能够通过发送通知解决问题,否则必须重新调用委派,在返回或撤消委派之前,操作无法继续。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

If OPEN4_CREATE is specified and the file does not exist and the current filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, NOTIFY4_ADD_ENTRY will be generated as a result of this operation.

如果指定了OPEN4_CREATE,但文件不存在,且当前filehandle指定了存在一个或多个目录委派的目录,则当这些委派请求此类通知时,此操作将生成NOTIFY4_ADD_条目。

18.16.4.1. Warning to Client Implementors
18.16.4.1. 对客户端实现者的警告

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.

仅仅等待文件租约到期是不够的,因为只要另一个客户端不尝试对同一文件进行冲突访问,服务器就可以无限期地保持该状态。

See also Section 2.10.6.4.

另见第2.10.6.4节。

18.17. Operation 19: OPENATTR - Open Named Attribute Directory
18.17. 操作19:OPENATTR-打开命名属性目录
18.17.1. ARGUMENTS
18.17.1. 论据
   struct OPENATTR4args {
           /* CURRENT_FH: object */
           bool    createdir;
   };
        
   struct OPENATTR4args {
           /* CURRENT_FH: object */
           bool    createdir;
   };
        
18.17.2. RESULTS
18.17.2. 后果
   struct OPENATTR4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: named attribute
            *                   directory
            */
           nfsstat4        status;
   };
        
   struct OPENATTR4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: named attribute
            *                   directory
            */
           nfsstat4        status;
   };
        
18.17.3. DESCRIPTION
18.17.3. 描述

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 file system object. Filehandles returned within the named attribute directory will designate objects of 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 and its filehandle becomes the current filehandle. On the other hand, if createdir has a value of TRUE and the named attribute directory already exists, no error results and the filehandle of the existing directory becomes the current filehandle. 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,且不存在命名属性目录,则会创建一个属性目录,其filehandle将成为当前filehandle。另一方面,如果createdir的值为TRUE,并且命名的属性目录已经存在,则不会产生错误,并且现有目录的filehandle将成为当前filehandle。命名属性目录的创建假定服务器以这种方式实现了命名属性支持,并且此定义不要求这样做。

If the current file handle designates an object of type NF4NAMEDATTR (a named attribute) or NF4ATTRDIR (a named attribute directory), an error of NFS4ERR_WRONG_TYPE is returned to the client. Named attributes or a named attribute directory MUST NOT have their own named attributes.

如果当前文件句柄指定了NF4NAMEDATTR(命名属性)或NF4ATTRDIR(命名属性目录)类型的对象,则会向客户端返回NFS4ERR_error_类型的错误。命名属性或命名属性目录不能有自己的命名属性。

18.17.4. IMPLEMENTATION
18.17.4. 实施

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错误。

18.18. Operation 21: OPEN_DOWNGRADE - Reduce Open File Access
18.18. 操作21:打开降级-减少打开的文件访问
18.18.1. ARGUMENTS
18.18.1. 论据
   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;
   };
        
18.18.2. RESULTS
18.18.2. 后果
   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;
   };
        
18.18.3. DESCRIPTION
18.18.3. 描述

This operation is used to adjust the access and deny states for a given open. This is necessary when a given open-owner opens the same file multiple times with different access and deny values. 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.

此操作用于调整给定打开状态的访问和拒绝状态。当给定的打开所有者使用不同的访问和拒绝值多次打开同一文件时,这是必需的。在这种情况下,关闭一个打开可能会更改相应的share_access和share_deny标志,以删除与不再有效的打开相关的位。

Valid values for the expression (share_access & ~OPEN4_SHARE_ACCESS_WANT_DELEG_MASK) are OPEN4_SHARE_ACCESS_READ, OPEN4_SHARE_ACCESS_WRITE, or OPEN4_SHARE_ACCESS_BOTH. If the client specifies other values, the server MUST reply with NFS4ERR_INVAL.

表达式的有效值(share\u access和~OPEN4\u share\u access\u WANT\u DELEG\u MASK)为OPEN4\u share\u access\u READ、OPEN4\u share\u access\u WRITE或OPEN4\u share\u access\u READ。如果客户端指定了其他值,服务器必须使用NFS4ERR_INVAL进行回复。

Valid values for the share_deny field are OPEN4_SHARE_DENY_NONE, OPEN4_SHARE_DENY_READ, OPEN4_SHARE_DENY_WRITE, or OPEN4_SHARE_DENY_BOTH. If the client specifies other values, the server MUST reply with NFS4ERR_INVAL.

share_deny字段的有效值为OPEN4_share_deny_NONE、OPEN4_share_deny_READ、OPEN4_share_deny_WRITE或OPEN4_share_deny_二者。如果客户端指定了其他值,服务器必须使用NFS4ERR_INVAL进行回复。

After checking for valid values of share_access and share_deny, the server replaces the current access and deny modes on the file with share_access and share_deny subject to the following constraints:

在检查share_access和share_deny的有效值后,服务器会根据以下约束将文件上的当前访问和拒绝模式替换为share_access和share_deny:

o The bits in share_access SHOULD equal the union of the share_access bits (not including OPEN4_SHARE_WANT_* bits) specified for some subset of the OPENs in effect for the current open-owner on the current file.

o share_access中的位应等于为当前文件上当前打开的所有者有效打开的某些子集指定的share_access位(不包括OPEN4_share_WANT_*位)的并集。

o The bits in share_deny SHOULD equal the union of the share_deny bits specified for some subset of the OPENs in effect for the current open-owner on the current file.

o share_deny中的位应等于为当前文件上当前打开的所有者有效打开的某些子集指定的share_deny位的并集。

If the above constraints are not respected, the server SHOULD return the error NFS4ERR_INVAL. Since share_access and share_deny bits should be subsets of those already granted, short of a defect in the client or server implementation, it is not possible for the OPEN_DOWNGRADE request to be denied because of conflicting share reservations.

如果不遵守上述约束,服务器应返回错误NFS4ERR_INVAL。由于share_access和share_deny位应该是已经授予的那些位的子集,除非客户端或服务器实现中存在缺陷,否则不可能因为共享保留冲突而拒绝OPEN_降级请求。

The seqid argument is not used in NFSv4.1, MAY be any value, and MUST be ignored by the server.

seqid参数在NFSv4.1中未使用,可以是任何值,服务器必须忽略它。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.18.4. IMPLEMENTATION
18.18.4. 实施

An OPEN_DOWNGRADE operation may make OPEN_DELEGATE_READ delegations grantable where they were not previously. Servers may choose to respond immediately if there are pending delegation want requests or may respond to the situation at a later time.

OPEN_降级操作可能会使OPEN_DELEGATE_READ delegations可授予以前未授予的授权。如果存在挂起的委派请求,服务器可能会选择立即响应,或者可能会在以后对这种情况做出响应。

18.19. Operation 22: PUTFH - Set Current Filehandle
18.19. 操作22:PUTFH-设置当前文件句柄
18.19.1. ARGUMENTS
18.19.1. 论据
   struct PUTFH4args {
           nfs_fh4         object;
   };
        
   struct PUTFH4args {
           nfs_fh4         object;
   };
        
18.19.2. RESULTS
18.19.2. 后果
   struct PUTFH4res {
           /*
            * If status is NFS4_OK,
            *    new CURRENT_FH: argument to PUTFH
            */
           nfsstat4        status;
   };
        
   struct PUTFH4res {
           /*
            * If status is NFS4_OK,
            *    new CURRENT_FH: argument to PUTFH
            */
           nfsstat4        status;
   };
        
18.19.3. DESCRIPTION
18.19.3. 描述

This operation replaces the current filehandle with the filehandle provided as an argument. It clears the current stateid.

此操作将当前文件句柄替换为作为参数提供的文件句柄。它清除当前的stateid。

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。

See Section 16.2.3.1.1 for more details on the current filehandle.

有关当前文件句柄的更多详细信息,请参见第16.2.3.1.1节。

See Section 16.2.3.1.2 for more details on the current stateid.

有关当前stateid的更多详细信息,请参见第16.2.3.1.2节。

18.19.4. IMPLEMENTATION
18.19.4. 实施

This operation is used in an NFS request to set the context for file accessing operations that follow in the same COMPOUND request.

此操作在NFS请求中用于为同一复合请求中后续的文件访问操作设置上下文。

18.20. Operation 23: PUTPUBFH - Set Public Filehandle
18.20. 操作23:PUTPUBFH-设置公共文件句柄
18.20.1. ARGUMENT
18.20.1. 论点

void;

无效的

18.20.2. RESULT
18.20.2. 后果
   struct PUTPUBFH4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: public fh
            */
           nfsstat4        status;
   };
        
   struct PUTPUBFH4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: public fh
            */
           nfsstat4        status;
   };
        
18.20.3. DESCRIPTION
18.20.3. 描述

This operation replaces the current filehandle with the filehandle that represents the public filehandle of the server's namespace. This filehandle may be different from the "root" filehandle that may be associated with some other directory on the server.

此操作将当前文件句柄替换为表示服务器命名空间的公共文件句柄的文件句柄。此文件句柄可能不同于可能与服务器上的某些其他目录关联的“根”文件句柄。

PUTPUBFH also clears the current stateid.

PUTPUBFH还清除当前状态ID。

The public filehandle represents the concepts embodied in RFC 2054 [42], RFC 2055 [43], and RFC 2224 [53]. The intent for NFSv4.1 is that the public filehandle (represented by the PUTPUBFH operation) be used as a method of providing WebNFS server compatibility with NFSv3.

公共文件句柄表示RFC 2054[42]、RFC 2055[43]和RFC 2224[53]中包含的概念。NFSv4.1的目的是将公共文件句柄(由PUTPUBFH操作表示)用作提供与NFSv3的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 directory corresponding to the public filehandle MUST be a descendant of the directory corresponding to the root filehandle.

公共文件句柄和根文件句柄(由PUTROOTFH操作表示)应该是等效的。如果public和root filehandles不相等,则与public filehandle对应的目录必须是与root filehandle对应的目录的后代。

See Section 16.2.3.1.1 for more details on the current filehandle.

有关当前文件句柄的更多详细信息,请参见第16.2.3.1.1节。

See Section 16.2.3.1.2 for more details on the current stateid.

有关当前stateid的更多详细信息,请参见第16.2.3.1.2节。

18.20.4. IMPLEMENTATION
18.20.4. 实施

This operation is used in an NFS request to set the context for file accessing operations that follow in the same COMPOUND request.

此操作在NFS请求中用于为同一复合请求中后续的文件访问操作设置上下文。

With the NFSv3 public filehandle, the client is able to specify whether the pathname provided in the LOOKUP should be evaluated as either an absolute path relative to the server's root or relative to the public filehandle. RFC 2224 [53] contains further discussion of the functionality. With NFSv4.1, 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 NFSv4. Therefore, the client is

使用NFSv3公共文件句柄,客户机可以指定是将查找中提供的路径名计算为相对于服务器根的绝对路径还是相对于公共文件句柄的绝对路径。RFC 2224[53]包含对功能的进一步讨论。对于NFSv4.1,该类型的规范在查找操作中不直接可用。这是因为NFSv4中不允许指定绝对与相对所需的组件分隔符。因此,客户机是

responsible for constructing its request such that the use of either PUTROOTFH or PUTPUBFH signifies absolute or relative evaluation of an NFS URL, respectively.

负责构造其请求,以便使用PUTROOTFH或PUTPUBFH分别表示对NFS URL的绝对或相对评估。

Note that there are warnings mentioned in RFC 2224 [53] 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 NFSv4.1. It is likely, therefore, that because of server implementation details, an NFSv3 absolute public filehandle look up may behave differently than an NFSv4.1 absolute resolution.

请注意,RFC 2224[53]中提到了有关绝对求值的使用的警告,以及服务器可能对该求值施加的限制,这些限制涉及其名称空间的可用性。这些警告同样适用于NFSv4.1。因此,由于服务器实现细节的原因,NFSv3绝对公共文件句柄查找可能与NFSv4.1绝对解析的行为不同。

There is a form of security negotiation as described in RFC 2755 [54] that uses the public filehandle and an overloading of the pathname. This method is not available with NFSv4.1 as filehandles are not overloaded with special meaning and therefore do not provide the same framework as NFSv3. Clients should therefore use the security negotiation mechanisms described in Section 2.6.

RFC 2755[54]中描述了一种使用公共文件句柄和路径名重载的安全协商形式。NFSv4.1不提供此方法,因为文件句柄没有特殊意义的重载,因此不提供与NFSv3相同的框架。因此,客户应使用第2.6节所述的安全协商机制。

18.21. Operation 24: PUTROOTFH - Set Root Filehandle
18.21. 操作24:PUTROOTFH-设置根文件句柄
18.21.1. ARGUMENTS
18.21.1. 论据

void;

无效的

18.21.2. RESULTS
18.21.2. 后果
   struct PUTROOTFH4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: root fh
            */
           nfsstat4        status;
   };
        
   struct PUTROOTFH4res {
           /*
            * If status is NFS4_OK,
            *   new CURRENT_FH: root fh
            */
           nfsstat4        status;
   };
        
18.21.3. DESCRIPTION
18.21.3. 描述

This operation replaces the current filehandle with the filehandle that represents the root of the server's namespace. From this filehandle, a LOOKUP operation can locate any other filehandle on the server. This filehandle may be different from the "public" filehandle that may be associated with some other directory on the server.

此操作将当前文件句柄替换为表示服务器命名空间根的文件句柄。通过此文件句柄,查找操作可以找到服务器上的任何其他文件句柄。此文件句柄可能不同于可能与服务器上的某些其他目录关联的“公共”文件句柄。

PUTROOTFH also clears the current stateid.

PUTROOTFH还清除当前状态ID。

See Section 16.2.3.1.1 for more details on the current filehandle.

有关当前文件句柄的更多详细信息,请参见第16.2.3.1.1节。

See Section 16.2.3.1.2 for more details on the current stateid.

有关当前stateid的更多详细信息,请参见第16.2.3.1.2节。

18.21.4. IMPLEMENTATION
18.21.4. 实施

This operation is used in an NFS request to set the context for file accessing operations that follow in the same COMPOUND request.

此操作在NFS请求中用于为同一复合请求中后续的文件访问操作设置上下文。

18.22. Operation 25: READ - Read from File
18.22. 操作25:读取-从文件读取
18.22.1. ARGUMENTS
18.22.1. 论据
   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };
        
   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };
        
18.22.2. RESULTS
18.22.2. 后果
   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;
   };
        
18.22.3. DESCRIPTION
18.22.3. 描述

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 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 zero and eof is set to TRUE. The READ is subject to access permissions checking.

客户端提供读取开始位置的偏移量和读取字节数的计数。偏移量为零表示从文件开头开始读取数据。如果偏移量大于或等于文件大小,则返回状态NFS4_OK,数据长度设置为零,eof设置为真。读取受访问权限检查的约束。

If the client specifies a count value of zero, the READ succeeds and returns 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.

如果客户端指定的计数值为零,则读取成功并返回零字节的数据,但仍需进行访问权限检查。服务器可以选择返回的字节数少于客户端指定的字节数。客户需要检查该情况并适当处理该情况。

Except when special stateids are used, the stateid value for a READ request represents a value returned from a previous byte-range lock or share reservation request or the stateid associated with a delegation. The stateid identifies the associated owners if any and is used by the server to verify that the associated locks are still valid (e.g., have not been revoked).

除非使用特殊的stateid,否则读取请求的stateid值表示从以前的字节范围锁定或共享保留请求返回的值,或者表示与委派关联的stateid。stateid标识关联的所有者(如果有),并由服务器用于验证关联的锁是否仍然有效(例如,尚未撤销)。

If the read ended at the end-of-file (formally, in a correctly formed READ operation, if offset + count is equal to the size of the file), or the READ operation 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.

如果读取在文件末尾结束(正式地说,在格式正确的读取操作中,如果offset+count等于文件的大小),或者读取操作超出了文件的大小(如果offset+count大于文件的大小),则eof返回为TRUE;否则,这是错误的。成功读取空文件将始终将eof返回为TRUE。

If the current filehandle is not an ordinary file, an error will be returned to the client. In the case that the current filehandle represents an object of type NF4DIR, NFS4ERR_ISDIR is returned. If the current filehandle designates a symbolic link, NFS4ERR_SYMLINK is returned. In all other cases, NFS4ERR_WRONG_TYPE is returned.

如果当前文件句柄不是普通文件,则会向客户端返回错误。如果当前文件句柄表示NF4DIR类型的对象,则返回NFS4ERR_ISDIR。如果当前文件句柄指定符号链接,则返回NFS4ERR_SYMLINK。在所有其他情况下,将返回NFS4ERR_-Error_类型。

For a READ with a stateid value of all bits equal to zero, the server MAY allow the READ to be serviced subject to mandatory byte-range locks or the current share deny modes for the file. For a READ with a stateid value of all bits equal to one, the server MAY allow READ operations to bypass locking checks at the server.

对于stateid值为所有位等于零的读取,服务器可能允许根据文件的强制字节范围锁或当前共享拒绝模式对读取进行服务。对于stateid值为所有位等于1的读取,服务器可能允许读取操作绕过服务器上的锁定检查。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.22.4. IMPLEMENTATION
18.22.4. 实施

If the server returns a "short read" (i.e., fewer data than requested and eof is set to FALSE), the client should send 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 reduce the transfer size and so return a short read result. Server resource exhaustion may also occur in a short read.

如果服务器返回“短读”(即数据少于请求的数据,且eof设置为FALSE),则客户端应发送另一次读取以获取剩余数据。在几种情况下,服务器返回的数据可能少于请求的数据。该文件可能已被另一个客户端或服务器本身截断,从而改变了请求客户端认为的文件大小。这将减少客户端可用的实际数据量。服务器可能会减小传输大小,从而返回一个简短的读取结果。服务器资源耗尽也可能发生在短时间读取中。

If mandatory byte-range locking is in effect for the file, and if the byte-range corresponding to the data to be read from the file is WRITE_LT locked by an owner not associated with the stateid, the server will return the NFS4ERR_LOCKED error. The client should try to get the appropriate READ_LT via the LOCK operation before re-attempting the READ. When the READ completes, the client should release the byte-range lock via LOCKU.

如果强制字节范围锁定对文件生效,并且如果与要从文件读取的数据相对应的字节范围由与stateid不关联的所有者进行写锁定,则服务器将返回NFS4ERR_锁定错误。在重新尝试读取之前,客户端应尝试通过锁定操作获取适当的读取。读取完成后,客户端应通过LOCKU释放字节范围锁。

If another client has an OPEN_DELEGATE_WRITE delegation for the file being read, the delegation must be recalled, and the operation cannot proceed until that delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while the delegation remains outstanding. Normally, delegations will not be recalled as a result of a READ operation since the recall will occur as a result of an earlier OPEN. However, since it is possible for a READ to be done with a special stateid, the server needs to check for this case even though the client should have done an OPEN previously.

如果另一个客户端对正在读取的文件具有OPEN_DELEGATE_WRITE委派,则必须重新调用该委派,并且在该委派被返回或撤销之前,操作无法继续。除非这种情况发生得很快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。通常情况下,不会因读取操作而召回代表团,因为召回将因先前的打开操作而发生。但是,由于可以使用特殊的stateid进行读取,因此服务器需要检查这种情况,即使客户机以前应该进行过打开操作。

18.23. Operation 26: READDIR - Read Directory
18.23. 操作26:READDIR-读取目录
18.23.1. ARGUMENTS
18.23.1. 论据
   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;
   };
        
18.23.2. RESULTS
18.23.2. 后果
   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;
   };
        
18.23.3. DESCRIPTION
18.23.3. 描述

The READDIR operation retrieves a variable number of entries from a file system directory and returns client-requested attributes for each entry along with information to allow the client to request additional directory entries in a subsequent READDIR.

READDIR操作从文件系统目录中检索数量可变的条目,并为每个条目返回客户端请求的属性以及允许客户端在后续READDIR中请求其他目录条目的信息。

The arguments contain a cookie value that represents where the READDIR should start within the directory. A value of 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的值为零用于开始读取目录的开头。对于后续的READDIR请求,客户端指定服务器在前一个READDIR请求中提供的cookie值。

The request's cookieverf field should be set to 0 zero) when the request's cookie field is zero (first read of the directory). On subsequent requests, the cookieverf field must match the cookieverf 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字段为零(第一次读取目录)时,请求的cookieverf字段应设置为0(零)。在后续请求中,cookieverf字段必须与获取cookie的READDIR返回的cookieverf匹配。如果服务器确定cookieverf对目录不再有效,则必须返回错误NFS4ERR_NOT_SAME。

The dircount field of the request is a hint of the maximum number of bytes of directory information that should be returned. This value represents the total 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 field of the request represents the maximum total size of 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 MUST be returned to the client.

请求的maxcount字段表示READDIR4resok结构中返回的所有数据的最大总大小,并包括XDR开销。服务器可能返回较少的数据。如果服务器无法返回maxcount限制内的单个目录项,则必须将错误NFS4ERR_Toosall返回给客户端。

Finally, the request's attr_request field represents the list of attributes to be returned for each directory entry supplied by the server.

最后,请求的attr_request字段表示要为服务器提供的每个目录项返回的属性列表。

A successful reply consists of 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 cursor for the directory entry. As mentioned, this cookie is used by the client for subsequent READDIR operations so that it may continue reading a directory. The cookie is similar in concept to a READ offset but MUST NOT be interpreted as such by the client. Ideally, the cookie value SHOULD NOT change if the directory is modified since the client may be caching these values.

cookie值仅对服务器有意义,并用作目录项的游标。如前所述,客户端将此cookie用于后续的READDIR操作,以便它可以继续读取目录。cookie在概念上类似于读取偏移量,但客户端不能将其解释为读取偏移量。理想情况下,如果目录被修改,cookie值不应该改变,因为客户端可能正在缓存这些值。

In some cases, the server may encounter an error while obtaining the attributes for a directory entry. Instead of returning an error for the entire READDIR operation, the server can instead return the attribute rdattr_error (Section 5.8.1.12). 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.

在某些情况下,服务器在获取目录项的属性时可能会遇到错误。服务器可以返回属性rdattr_error(第5.8.1.12节),而不是返回整个READDIR操作的错误。这样,服务器就能够将故障告知客户机,而不会在可能是暂时故障的情况下使整个操作失败。显然,客户端必须请求fattr4_rdattr_error属性才能使此方法正常工作。如果客户端不请求该属性,服务器别无选择,只能返回整个READDIR操作的失败。

For some file system environments, the directory entries "." and ".." have special meaning, and in other environments, they do 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 zero, 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 one and two SHOULD NOT be used, and for READDIR results, cookie values of zero, one, and two SHOULD NOT be returned.

对于READDIR参数,不应使用cookie值1和2,对于READDIR结果,不应返回cookie值0、1和2。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.23.4. IMPLEMENTATION
18.23.4. 实施

The server's file system directory representations can differ greatly. A client's programming interfaces may also be bound to the local operating environment in a way that does not translate well into the NFS protocol. Therefore, the use of the dircount and maxcount fields are provided to enable the client to provide hints 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.

服务器的文件系统目录表示形式可能会有很大差异。客户端的编程接口也可能以无法很好地转换为NFS协议的方式绑定到本地操作环境。因此,提供了dircount和maxcount字段的使用,以使客户机能够向服务器提供提示。如果客户机在READDIR过程中对属性收集非常积极,那么服务器就知道如何限制编码响应。

If dircount is zero, the server bounds the reply's size based on the request's maxcount field.

如果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 might be unable 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 might be stale. For example, if the file system has been migrated, the server might or might 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 accepts 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响应中的客户端必须创建它们。

18.24. Operation 27: READLINK - Read Symbolic Link
18.24. 操作27:读取链接-读取符号链接
18.24.1. ARGUMENTS
18.24.1. 论据
   /* CURRENT_FH: symlink */
   void;
        
   /* CURRENT_FH: symlink */
   void;
        
18.24.2. RESULTS
18.24.2. 后果
   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;
   };
        
18.24.3. DESCRIPTION
18.24.3. 描述

READLINK reads the data associated with a symbolic link. Depending on the value of the UTF-8 capability attribute (Section 14.4), the data is encoded in UTF-8. Whether created by an NFS client or created locally on the server, the data in a symbolic link is not interpreted (except possibly to check for proper UTF-8 encoding) when created, but is simply stored.

READLINK读取与符号链接关联的数据。根据UTF-8能力属性的值(第14.4节),数据以UTF-8编码。无论是由NFS客户机创建的还是在服务器上本地创建的,符号链接中的数据在创建时都不会被解释(可能是为了检查UTF-8编码是否正确),而只是存储。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.24.4. IMPLEMENTATION
18.24.4. 实施

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 pathname 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_WRONG_TYPE if the object is not of type NF4LNK.

仅允许对NF4LNK类型的对象执行READLINK操作。如果对象不是NF4LNK类型,则服务器应返回错误NFS4ERR_错误_类型。

18.25. Operation 28: REMOVE - Remove File System Object
18.25. 操作28:删除-删除文件系统对象
18.25.1. ARGUMENTS
18.25.1. 论据
   struct REMOVE4args {
           /* CURRENT_FH: directory */
           component4      target;
   };
        
   struct REMOVE4args {
           /* CURRENT_FH: directory */
           component4      target;
   };
        
18.25.2. RESULTS
18.25.2. 后果
   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;
   };
        
18.25.3. DESCRIPTION
18.25.3. 描述

The REMOVE operation removes (deletes) a directory entry named by filename from the directory corresponding to the current filehandle. If the entry in the directory was the last reference to the corresponding file system object, the object may be destroyed. The directory may be either of type NF4DIR or NF4ATTRDIR.

移除操作从与当前文件句柄对应的目录中移除(删除)以文件名命名的目录项。如果目录中的条目是对相应文件系统对象的最后一次引用,则该对象可能会被销毁。目录可以是NF4DIR或NF4ATTRDIR类型。

For the directory where the filename was removed, the server returns change_info4 information in cinfo. With the atomic field of the change_info4 data type, 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 zero, or if the target does not obey the UTF-8 definition (and the server is enforcing UTF-8 encoding; see Section 14.4), the error NFS4ERR_INVAL will be returned.

如果目标的长度为零,或者如果目标不遵守UTF-8定义(并且服务器正在实施UTF-8编码;请参见第14.4节),则将返回错误NFS4ERR_INVAL。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.25.4. IMPLEMENTATION
18.25.4. 实施

NFSv3 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() [27] 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. NFSv4.1 REMOVE can be used to delete any directory entry independent of its file type. The implementor of an NFSv4.1 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 sending a REMOVE operation. Alternatively, the implementor can produce a COMPOUND call that includes a LOOKUP/VERIFY sequence of operations to verify the file type before a REMOVE operation in the same COMPOUND call.

NFSv3需要不同的运算符RMDIR来删除目录,而REMOVE则需要不同的运算符来删除非目录。这允许客户端在传递非目录删除系统调用(例如POSIX中的unlink()[27])以删除目录时跳过检查文件类型,反之亦然(例如非目录中的rmdir()),因为他们知道服务器将检查文件类型。NFSv4.1 REMOVE可用于删除任何与其文件类型无关的目录项。NFSv4.1客户端的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

最后一个引用的概念是特定于服务器的。但是,如果对象先前属性中的numlinks字段的值为1,则客户端不应依赖于通过文件句柄引用对象。同样,客户机不应该依赖以前与服务器关联的资源(磁盘空间、目录项等)

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. While the traditional mechanism used is to RENAME the file from its old name to a new hidden name, the NFSv4.1 OPEN operation MAY return a result flag, OPEN4_RESULT_PRESERVE_UNLINKED, which indicates to the client that the file will be preserved if the file has an outstanding open (see Section 18.16).

对象立即可用。因此,如果客户机在使用REMOVE删除文件后需要能够继续访问该文件,则客户机应采取步骤确保该文件仍然可以访问。虽然使用的传统机制是将文件从旧名称重命名为新的隐藏名称,但NFSv4.1 OPEN操作可能会返回一个结果标志OPEN4_result_PRESERVE_UNLINKED,它向客户端指示,如果文件有未完成的打开,则将保留该文件(请参阅第18.16节)。

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_两者打开的,服务器应该删除文件的目录条目。但是,在文件最后关闭之前,服务器可能会继续允许通过其文件句柄访问文件。

o The server MUST NOT delete the directory entry if the reply from OPEN had the flag OPEN4_RESULT_PRESERVE_UNLINKED set.

o 如果来自OPEN的回复设置了OPEN4\u RESULT\u PRESERVE\u UNLINKED标志,则服务器不得删除目录项。

The server MAY implement its own restrictions on removal of a file while it is open. The server might disallow such a REMOVE (or a removal that occurs as part of RENAME). The conditions that influence the restrictions on removal of a file while it is still open include:

服务器可以在文件打开时对删除文件实施自己的限制。服务器可能不允许这样的删除(或作为重命名的一部分进行的删除)。影响在文件仍处于打开状态时删除文件的限制的条件包括:

o Whether certain access protocols (i.e., not just NFS) are holding the file open.

o 是否有特定的访问协议(即,不仅仅是NFS)使文件保持打开状态。

o Whether particular options, access modes, or policies on the server are enabled.

o 是否启用服务器上的特定选项、访问模式或策略。

If a file has an outstanding OPEN and this prevents the removal of the file's directory entry, the error NFS4ERR_FILE_OPEN is returned.

如果文件有未完成的打开,这会阻止删除文件的目录项,则返回错误NFS4ERR_file_OPEN。

Where the determination above cannot be made definitively because delegations are being held, they MUST be recalled to allow processing of the REMOVE to continue. When a delegation is held, the server has no reliable knowledge of the status of OPENs for that client, so unless there are files opened with the particular deny modes by clients without delegations, the determination cannot be made until

如果由于代表团被扣留而无法确定上述决定,则必须召回代表团,以便继续处理罢免事宜。当委托被持有时,服务器对该客户端的打开状态没有可靠的了解,因此,除非没有委托的客户端以特定的拒绝模式打开文件,否则直到

delegations are recalled, and the operation cannot proceed until each sufficient delegation has been returned or revoked to allow the server to make a correct determination.

将调用委派,并且在返回或撤消每个足够的委派以允许服务器做出正确的确定之前,操作无法继续。

In all cases in which delegations are recalled, the server is likely to return one or more NFS4ERR_DELAY errors while delegations remain outstanding.

在调用委托的所有情况下,当委托保持未完成时,服务器可能返回一个或多个NFS4ERR_延迟错误。

If the current filehandle designates a directory for which another client holds a directory delegation, then, unless the situation can be resolved by sending a notification, the directory delegation MUST be recalled, and the operation MUST NOT proceed until the delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果当前文件句柄指定了另一个客户端持有目录委派的目录,则除非可以通过发送通知来解决这种情况,否则必须重新调用目录委派,并且在返回或撤销委派之前,操作不得继续。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

When the current filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, NOTIFY4_REMOVE_ENTRY will be generated as a result of this operation.

当当前文件句柄指定存在一个或多个目录委派的目录时,当这些委派请求此类通知时,此操作将生成NOTIFY4_REMOVE_条目。

Note that when a remove occurs as a result of a RENAME, NOTIFY4_REMOVE_ENTRY will only be generated if the removal happens as a separate operation. In the case in which the removal is integrated and atomic with RENAME, the notification of the removal is integrated with notification for the RENAME. See the discussion of the NOTIFY4_RENAME_ENTRY notification in Section 20.4.

请注意,当重命名导致删除时,仅当删除作为单独操作进行时,才会生成NOTIFY4\u remove\u条目。在删除与重命名集成且原子化的情况下,删除通知与重命名通知集成。请参阅第20.4节中关于NOTIFY4_RENAME_条目通知的讨论。

18.26. Operation 29: RENAME - Rename Directory Entry
18.26. 操作29:重命名-重命名目录项
18.26.1. ARGUMENTS
18.26.1. 论据
   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;
   };
        
18.26.2. RESULTS
18.26.2. 后果
   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;
   };
        
18.26.3. DESCRIPTION
18.26.3. 描述

The RENAME operation renames the object identified by oldname in the source directory corresponding to the saved filehandle, as set by the SAVEFH operation, to newname in the target directory corresponding to the current filehandle. The operation is required to be atomic to the client. Source and target directories MUST reside on the same file system on the server. On success, the current filehandle will continue to be the target directory.

重命名操作将SAVEFH操作设置的与保存的文件句柄相对应的源目录中由oldname标识的对象重命名为与当前文件句柄相对应的目标目录中的newname。该操作对于客户端来说必须是原子的。源目录和目标目录必须位于服务器上的同一文件系统上。成功后,当前文件句柄将继续作为目标目录。

If the target directory already contains an entry with the name newname, the source object MUST be compatible with the target: either both are non-directories or both are directories and the target MUST be empty. If compatible, the existing target is removed before the rename occurs or, preferably, the target is removed atomically as part of the rename. See Section 18.25.4 for client and server actions whenever a target is removed. Note however that when the removal is performed atomically with the rename, certain parts of the removal described there are integrated with the rename. For example, notification of the removal will not be via a NOTIFY4_REMOVE_ENTRY but will be indicated as part of the NOTIFY4_ADD_ENTRY or NOTIFY4_RENAME_ENTRY generated by the rename.

如果目标目录已包含名为newname的条目,则源对象必须与目标兼容:要么都是非目录,要么都是目录,目标必须为空。如果兼容,则在重命名之前删除现有目标,或者,最好是作为重命名的一部分以原子方式删除目标。有关删除目标时的客户端和服务器操作,请参见第18.25.4节。但是请注意,当删除与重命名以原子方式执行时,此处描述的删除的某些部分与重命名集成。例如,删除通知将不会通过NOTIFY4\u REMOVE\u条目发出,而是作为由重命名生成的NOTIFY4\u ADD\u条目或NOTIFY4\u RENAME\u条目的一部分指示。

If the source object and the target are not compatible or if the target is a directory but not empty, the server will return the error NFS4ERR_EXIST.

如果源对象和目标不兼容,或者目标是目录但不是空的,服务器将返回错误NFS4ERR_EXIST。

If oldname and newname both refer to the same file (e.g., they might be hard links of each other), then unless the file is open (see Section 18.26.4), RENAME MUST perform no action and return NFS4_OK.

如果oldname和newname都引用同一个文件(例如,它们可能是彼此的硬链接),则除非文件处于打开状态(参见第18.26.4节),否则RENAME不得执行任何操作并返回NFS4_OK。

For both directories involved in the RENAME, the server returns change_info4 information. With the atomic field of the change_info4 data type, the server will indicate if the before and after change attributes were obtained atomically with respect to the rename.

对于重命名中涉及的两个目录,服务器返回change_info4信息。使用change_info4数据类型的原子字段,服务器将指示是否以原子方式获得了与重命名相关的更改前和更改后属性。

If oldname refers to a named attribute and the saved and current filehandles refer to different file system objects, the server will return NFS4ERR_XDEV just as if the saved and current filehandles represented directories on different file systems.

如果oldname引用一个命名属性,并且保存的和当前的文件句柄引用不同的文件系统对象,则服务器将返回NFS4ERR_XDEV,就像保存的和当前的文件句柄表示不同文件系统上的目录一样。

If oldname or newname has a length of zero, or if oldname or newname does not obey the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

如果oldname或newname的长度为零,或者oldname或newname不符合UTF-8定义,则将返回错误NFS4ERR_INVAL。

18.26.4. IMPLEMENTATION
18.26.4. 实施

The server MAY impose restrictions on the RENAME operation such that RENAME may not be done when the file being renamed is open or when that open is done by particular protocols, or with particular options or access modes. Similar restrictions may be applied when a file exists with the target name and is open. When RENAME is rejected because of such restrictions, the error NFS4ERR_FILE_OPEN is returned.

服务器可能会对重命名操作施加限制,以便在正在重命名的文件打开时,或者在通过特定协议或特定选项或访问模式打开文件时,不能进行重命名。当文件以目标名称存在且处于打开状态时,可能会应用类似的限制。由于此类限制而拒绝重命名时,将返回错误NFS4ERR_FILE_OPEN。

When oldname and rename refer to the same file and that file is open in a fashion such that RENAME would normally be rejected with NFS4ERR_FILE_OPEN if oldname and newname were different files, then RENAME SHOULD be rejected with NFS4ERR_FILE_OPEN.

当oldname和rename引用同一个文件,并且该文件以NFS4ERR_file_open的方式打开时,如果oldname和newname是不同的文件,则通常会在NFS4ERR_file_open的情况下拒绝重命名,则应在NFS4ERR_file_open的情况下拒绝重命名。

If a server does implement such restrictions and those restrictions include cases of NFSv4 opens preventing successful execution of a rename, the server needs to recall any delegations that could hide the existence of opens relevant to that decision. This is because when a client holds a delegation, the server might not have an accurate account of the opens for that client, since the client may execute OPENs and CLOSEs locally. The RENAME operation need only be delayed until a definitive result can be obtained. For example, if there are multiple delegations and one of them establishes an open whose presence would prevent the rename, given the server's semantics, NFS4ERR_FILE_OPEN may be returned to the caller as soon as that delegation is returned without waiting for other delegations to be returned. Similarly, if such opens are not associated with delegations, NFS4ERR_FILE_OPEN can be returned immediately with no delegation recall being done.

如果服务器确实实施了此类限制,并且这些限制包括NFSv4打开阻止成功执行重命名的情况,则服务器需要调用可能隐藏与该决定相关的打开的存在的任何委托。这是因为当客户机持有委托时,服务器可能没有该客户机打开的准确帐户,因为客户机可能在本地执行打开和关闭。重命名操作只需延迟到获得最终结果。例如,如果有多个委托,其中一个委托建立了一个open,该open的存在将阻止重命名,那么根据服务器的语义,NFS4ERR_FILE_open可以在该委托返回后立即返回给调用方,而不必等待其他委托返回。类似地,如果此类打开与委派无关,则可以立即返回NFS4ERR_FILE_OPEN,而不进行委派调用。

If the current filehandle or the saved filehandle designates a directory for which another client holds a directory delegation, then, unless the situation can be resolved by sending a notification, the delegation MUST be recalled, and the operation cannot proceed until the delegation is returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while delegation remains outstanding.

如果当前文件句柄或保存的文件句柄指定了另一个客户端持有目录委派的目录,则除非可以通过发送通知来解决此情况,否则必须重新调用委派,并且在返回或撤销委派之前,操作无法继续。除非这种情况发生得非常快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。

When the current and saved filehandles are the same and they designate a directory for which one or more directory delegations exist, then, when those delegations request such notifications, a notification of type NOTIFY4_RENAME_ENTRY will be generated as a result of this operation. When oldname and rename refer to the same

如果当前文件句柄和保存的文件句柄相同,并且它们指定存在一个或多个目录委派的目录,则当这些委派请求此类通知时,此操作将生成NOTIFY4_RENAME_ENTRY类型的通知。当oldname和rename引用相同的名称时

file, no notification is generated (because, as Section 18.26.3 states, the server MUST take no action). When a file is removed because it has the same name as the target, if that removal is done atomically with the rename, a NOTIFY4_REMOVE_ENTRY notification will not be generated. Instead, the deletion of the file will be reported as part of the NOTIFY4_RENAME_ENTRY notification.

文件,则不会生成通知(因为,如第18.26.3节所述,服务器不得采取任何操作)。当文件因与目标同名而被删除时,如果删除是通过重命名自动完成的,则不会生成NOTIFY4\u REMOVE\u条目通知。相反,文件的删除将作为NOTIFY4\u RENAME\u条目通知的一部分进行报告。

When the current and saved filehandles are not the same:

当前和保存的文件句柄不相同时:

o If the current filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, NOTIFY4_ADD_ENTRY will be generated as a result of this operation. When a file is removed because it has the same name as the target, if that removal is done atomically with the rename, a NOTIFY4_REMOVE_ENTRY notification will not be generated. Instead, the deletion of the file will be reported as part of the NOTIFY4_ADD_ENTRY notification.

o 如果当前文件句柄指定存在一个或多个目录委派的目录,则当这些委派请求此类通知时,此操作将生成NOTIFY4_ADD_条目。当文件因与目标同名而被删除时,如果删除是通过重命名自动完成的,则不会生成NOTIFY4\u REMOVE\u条目通知。相反,文件的删除将作为NOTIFY4\u ADD\u条目通知的一部分进行报告。

o If the saved filehandle designates a directory for which one or more directory delegations exist, then, when those delegations request such notifications, NOTIFY4_REMOVE_ENTRY will be generated as a result of this operation.

o 如果保存的文件句柄指定存在一个或多个目录委派的目录,则当这些委派请求此类通知时,此操作将生成NOTIFY4_REMOVE_条目。

If the object being renamed has file delegations held by clients other than the one doing the RENAME, the delegations MUST be recalled, and the operation cannot proceed until each such delegation is returned or revoked. Note that in the case of multiply linked files, the delegation recall requirement applies even if the delegation was obtained through a different name than the one being renamed. In all cases in which delegations are recalled, the server is likely to return one or more NFS4ERR_DELAY errors while the delegation(s) remains outstanding, although it might not do that if the delegations are returned quickly.

如果要重命名的对象的文件委派由执行重命名的客户端以外的客户端持有,则必须重新调用委派,并且在返回或撤销每个此类委派之前,操作无法继续。请注意,在多链接文件的情况下,即使委托是通过与重命名文件不同的名称获得的,委托召回要求也适用。在调用委托的所有情况下,服务器都可能返回一个或多个NFS4ERR_延迟错误,而委托仍然未完成,但如果快速返回委托,则可能不会返回。

The RENAME operation must be atomic to the client. The statement "source and target directories MUST reside on the same file system on the server" means that the fsid fields in the attributes for the directories are the same. If they reside on different file systems, the error NFS4ERR_XDEV is returned.

重命名操作必须是客户端的原子操作。语句“源目录和目标目录必须位于服务器上的同一文件系统”表示目录属性中的fsid字段相同。如果它们驻留在不同的文件系统上,则返回错误NFS4ERR_XDEV。

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。

18.27. Operation 31: RESTOREFH - Restore Saved Filehandle
18.27. 操作31:RESTOREFH-还原保存的文件句柄
18.27.1. ARGUMENTS
18.27.1. 论据
   /* SAVED_FH: */
   void;
        
   /* SAVED_FH: */
   void;
        
18.27.2. RESULTS
18.27.2. 后果
   struct RESTOREFH4res {
           /*
            * If status is NFS4_OK,
            *     new CURRENT_FH: value of saved fh
            */
           nfsstat4        status;
   };
        
   struct RESTOREFH4res {
           /*
            * If status is NFS4_OK,
            *     new CURRENT_FH: value of saved fh
            */
           nfsstat4        status;
   };
        
18.27.3. DESCRIPTION
18.27.3. 描述

The RESTOREFH operation sets the current filehandle and stateid to the values in the saved filehandle and stateid. If there is no saved filehandle, then the server will return the error NFS4ERR_NOFILEHANDLE.

RESTOREFH操作将当前filehandle和stateid设置为保存的filehandle和stateid中的值。如果没有保存的文件句柄,则服务器将返回错误NFS4ERR_NOFILEHANDLE。

See Section 16.2.3.1.1 for more details on the current filehandle.

有关当前文件句柄的更多详细信息,请参见第16.2.3.1.1节。

See Section 16.2.3.1.2 for more details on the current stateid.

有关当前stateid的更多详细信息,请参见第16.2.3.1.2节。

18.27.4. IMPLEMENTATION
18.27.4. 实施

Operations like OPEN and LOOKUP use the current filehandle to represent a directory and replace it with a new filehandle. Assuming that 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)

18.28. Operation 32: SAVEFH - Save Current Filehandle
18.28. 操作32:SAVEFH-保存当前文件句柄
18.28.1. ARGUMENTS
18.28.1. 论据
   /* CURRENT_FH: */
   void;
        
   /* CURRENT_FH: */
   void;
        
18.28.2. RESULTS
18.28.2. 后果
   struct SAVEFH4res {
           /*
            * If status is NFS4_OK,
            *    new SAVED_FH: value of current fh
            */
           nfsstat4        status;
   };
        
   struct SAVEFH4res {
           /*
            * If status is NFS4_OK,
            *    new SAVED_FH: value of current fh
            */
           nfsstat4        status;
   };
        
18.28.3. DESCRIPTION
18.28.3. 描述

The SAVEFH operation saves the current filehandle and stateid. 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.

SAVEFH操作保存当前文件句柄和stateid。如果保存了以前的文件句柄,则无法再访问它。使用RESTOREFH操作符可以将保存的文件句柄还原为当前文件句柄。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

See Section 16.2.3.1.1 for more details on the current filehandle.

有关当前文件句柄的更多详细信息,请参见第16.2.3.1.1节。

See Section 16.2.3.1.2 for more details on the current stateid.

有关当前stateid的更多详细信息,请参见第16.2.3.1.2节。

18.28.4. IMPLEMENTATION
18.28.4. 实施
18.29. Operation 33: SECINFO - Obtain Available Security
18.29. 操作33:SECINFO-获取可用的安全性
18.29.1. ARGUMENTS
18.29.1. 论据
   struct SECINFO4args {
           /* CURRENT_FH: directory */
           component4      name;
   };
        
   struct SECINFO4args {
           /* CURRENT_FH: directory */
           component4      name;
   };
        
18.29.2. RESULTS
18.29.2. 后果
   /*
    * 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:
           /* CURRENTFH: consumed */
            SECINFO4resok resok4;
    default:
            void;
   };
        
   union SECINFO4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENTFH: consumed */
            SECINFO4resok resok4;
    default:
            void;
   };
        
18.29.3. DESCRIPTION
18.29.3. 描述

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 that represents the security mechanisms available, with an order corresponding to the 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 RFC 5531 [3]), or RPCSEC_GSS (as defined in RFC 2203 [4]). The field flavor can also be any other security flavor registered with IANA.

结果将包含一个表示可用安全机制的数组,其顺序与服务器的首选项相对应,最首选的是数组中的第一个。客户机可以自由选择它希望和支持的任何安全机制,或者按照服务器的首选顺序选择它支持的第一个安全机制。数组项由secinfo4结构表示。字段“flavor”将包含AUTH_NONE、AUTH_SYS(定义见RFC 5531[3])或RPCSEC_GSS(定义见RFC 2203[4])的值。字段风格也可以是在IANA注册的任何其他安全风格。

For the flavors AUTH_NONE and AUTH_SYS, no additional security information is returned. The same is true of many (if not most) other security flavors, including AUTH_DH. For a return value of RPCSEC_GSS, a security triple is returned that contains the mechanism object identifier (OID, as defined in RFC 2743 [7]), the quality of protection (as defined in RFC 2743 [7]), and the service type (as defined in RFC 2203 [4]). It is possible for SECINFO to return multiple entries with flavor equal to RPCSEC_GSS with different security triple values.

对于AUTH_NONE和AUTH_SYS,不会返回其他安全信息。许多(如果不是大多数的话)其他安全风格也是如此,包括AUTH_DH。对于RPCSEC_GSS的返回值,返回一个包含机制对象标识符(OID,如RFC 2743[7]中定义)、保护质量(如RFC 2743[7]中定义)和服务类型(如RFC 2203[4]中定义)的安全三元组。SECINFO可以返回多个具有不同安全性三重值的条目,其味道等于RPCSEC_GSS。

On success, the current filehandle is consumed (see Section 2.6.3.1.1.8), and if the next operation after SECINFO tries to use the current filehandle, that operation will fail with the status NFS4ERR_NOFILEHANDLE.

成功后,将使用当前文件句柄(请参见第2.6.3.1.1.8节),如果SECINFO之后的下一个操作尝试使用当前文件句柄,则该操作将失败,状态为NFS4ERR_NOFILEHANDLE。

If the name has a length of zero, or if the name does not obey the UTF-8 definition (assuming UTF-8 capabilities are enabled; see Section 14.4), the error NFS4ERR_INVAL will be returned.

如果名称的长度为零,或者名称不符合UTF-8定义(假设启用了UTF-8功能;请参阅第14.4节),则将返回错误NFS4ERR_INVAL。

See Section 2.6 for additional information on the use of SECINFO.

有关使用SECINFO的更多信息,请参见第2.6节。

18.29.4. IMPLEMENTATION
18.29.4. 实施

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

当从另一个NFS操作返回NFS4ERR_errosec的错误值时,NFS客户端将使用SECINFO操作。这向客户端表示服务器的安全性

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.

策略与客户端当前使用的策略不同。此时,客户机将获得可能的安全风格列表,并选择最适合其策略的。

As mentioned, the server's security policies will determine when a client request receives NFS4ERR_WRONGSEC. See Table 8 for a list of operations that can return NFS4ERR_WRONGSEC. In addition, when READDIR returns attributes, the rdattr_error (Section 5.8.1.12) can contain NFS4ERR_WRONGSEC. Note that CREATE and REMOVE MUST NOT return NFS4ERR_WRONGSEC. The rationale for CREATE is that unless the target name exists, it cannot have a separate security policy from the parent directory, and the security policy of the parent was checked when its filehandle was injected into the COMPOUND request's operations stream (for similar reasons, an OPEN operation that creates the target MUST NOT return NFS4ERR_WRONGSEC). If the target name exists, while it might have a separate security policy, that is irrelevant because CREATE MUST return NFS4ERR_EXIST. The rationale for REMOVE is that while that target might have a separate security policy, the target is going to be removed, and so the security policy of the parent trumps that of the object being removed. RENAME and LINK MAY return NFS4ERR_WRONGSEC, but the NFS4ERR_WRONGSEC error applies only to the saved filehandle (see Section 2.6.3.1.2). Any NFS4ERR_WRONGSEC error on the current filehandle used by LINK and RENAME MUST be returned by the PUTFH, PUTPUBFH, PUTROOTFH, or RESTOREFH operation that injected the current filehandle.

如前所述,服务器的安全策略将确定客户端请求何时接收NFS4ERR_错误。有关可返回NFS4ERR_错误秒的操作列表,请参见表8。此外,当READDIR返回属性时,rdattr_错误(第5.8.1.12节)可能包含NFS4ERR_错误。注意,CREATE和REMOVE不能返回NFS4ERR_-errosec。CREATE的基本原理是,除非目标名称存在,否则它不能与父目录有单独的安全策略,并且在将父目录的filehandle注入复合请求的操作流时检查了父目录的安全策略(出于类似原因,创建目标的打开操作不得返回NFS4ERR_错误秒)。如果目标名称存在,但它可能有一个单独的安全策略,这与此无关,因为CREATE必须返回NFS4ERR_EXIST。删除的理由是,虽然该目标可能有一个单独的安全策略,但目标将被删除,因此父对象的安全策略优于被删除对象的安全策略。RENAME和LINK可能返回NFS4ERR_错误秒,但NFS4ERR_错误秒错误仅适用于保存的文件句柄(请参阅第2.6.3.1.2节)。LINK和RENAME使用的当前文件句柄上的任何NFS4ERR_错误秒错误都必须由注入当前文件句柄的PUTFH、PUTPUBFH、PUTROOTFH或RESTOREFH操作返回。

With the exception of LINK and RENAME, the set of operations that can return NFS4ERR_WRONGSEC represents the point at which the client can inject a filehandle into the "current filehandle" at the server. The filehandle is either provided by the client (PUTFH, PUTPUBFH, PUTROOTFH), generated as a result of a name-to-filehandle translation (LOOKUP and OPEN), or generated from the saved filehandle via RESTOREFH. As Section 2.6.3.1.1.1 states, a put filehandle operation followed by SAVEFH MUST NOT return NFS4ERR_WRONGSEC. Thus, the RESTOREFH operation, under certain conditions (see Section 2.6.3.1.1), is permitted to return NFS4ERR_WRONGSEC so that security policies can be honored.

除了LINK和RENAME之外,可以返回NFS4ERR_errosec的操作集表示客户端可以将文件句柄插入服务器上的“当前文件句柄”的点。文件句柄由客户端(PUTFH、PUTPUBFH、PUTROOTFH)提供,通过名称到文件句柄的转换(查找和打开)生成,或者通过RESTOREFH从保存的文件句柄生成。正如第2.6.3.1.1.1节所述,后跟SAVEFH的put filehandle操作不得返回NFS4ERR_错误秒。因此,在某些条件下(参见第2.6.3.1.1节),允许RESTOREFH操作返回NFS4ERR_ErrorSec,以便遵守安全策略。

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 did 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错误。

To resolve an error return of NFS4ERR_WRONGSEC, the client does the following:

要解决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 the rdattr_error, the client will use SECINFO with the same current filehandle as provided in the original READDIR. The name passed to SECINFO will be that of the directory entry (as returned from READDIR) that had the NFS4ERR_WRONGSEC error in the rdattr_error attribute.

o 对于rdattr_错误,客户端将使用与原始READDIR中提供的相同当前文件句柄的SECINFO。传递给SECINFO的名称将是目录项的名称(从READDIR返回),该目录项在rdattr_error属性中有NFS4ERR_errosec错误。

o For PUTFH, PUTROOTFH, PUTPUBFH, RESTOREFH, LINK, and RENAME, the client will use SECINFO_NO_NAME { style = SECINFO_STYLE4_CURRENT_FH }. The client will prefix the SECINFO_NO_NAME operation with the appropriate PUTFH, PUTPUBFH, or PUTROOTFH operation that provides the filehandle originally provided by the PUTFH, PUTPUBFH, PUTROOTFH, or RESTOREFH operation.

o 对于PUTFH、PUTROOTFH、PUTPUBFH、RESTOREFH、LINK和RENAME,客户端将使用SECINFO_NO_NAME{style=SECINFO_STYLE4_CURRENT_FH}。客户机将在SECINFO_NO_NAME操作前面加上适当的PUTFH、PUTPUBFH或PUTROOTFH操作,该操作提供最初由PUTFH、PUTPUBFH、PUTROOTFH或RESTOREFH操作提供的文件句柄。

NOTE: In NFSv4.0, the client was required to use SECINFO, and had to reconstruct the parent of the original filehandle and the component name of the original filehandle. The introduction in NFSv4.1 of SECINFO_NO_NAME obviates the need for reconstruction.

注意:在NFSv4.0中,客户端需要使用SECINFO,并且必须重建原始文件句柄的父级和原始文件句柄的组件名称。NFSv4.1中引入了SECINFO_NO_名称,消除了重建的需要。

o For LOOKUPP, the client will use SECINFO_NO_NAME { style = SECINFO_STYLE4_PARENT } and provide the filehandle that equals the filehandle originally provided to LOOKUPP.

o 对于LOOKUPP,客户端将使用SECINFO_NO_NAME{style=SECINFO_STYLE4_PARENT},并提供与最初提供给LOOKUPP的filehandle相等的filehandle。

See Section 21 for a discussion on the recommendations for the security flavor used by SECINFO and SECINFO_NO_NAME.

关于SECINFO和SECINFO_NO_NAME使用的安全风格建议的讨论,请参见第21节。

18.30. Operation 34: SETATTR - Set Attributes
18.30. 操作34:SETATTR-设置属性
18.30.1. ARGUMENTS
18.30.1. 论据
   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;
   };
        
   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;
   };
        
18.30.2. RESULTS
18.30.2. 后果
   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };
        
   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };
        
18.30.3. DESCRIPTION
18.30.3. 描述

The SETATTR operation changes one or more of the attributes of a file system object. The new attributes are specified with a bitmap and the attributes that follow the bitmap in bit order.

SETATTR操作更改文件系统对象的一个或多个属性。新属性由位图和位图后面按位顺序的属性指定。

The stateid argument for SETATTR is used to provide byte-range 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 OPEN4_SHARE_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 byte-range locks, for those cases in which a server is implementing mandatory byte-range locking behavior. A valid stateid SHOULD always be specified. When the file size attribute is not set, the special stateid consisting of all bits equal to zero MAY be passed.

SETATTR的stateid参数用于提供设置size属性的SETATTR请求所需的字节范围锁定上下文。由于设置size属性会修改文件的数据,因此它具有与相应写入相同的锁定要求。任何设置size属性的SETATTR都与指定OPEN4\u share\u DENY\u 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 attrmask field of the obj_attributes field in the argument.

操作成功或失败时,服务器将返回attrsset位掩码,以表示成功设置了哪些属性(如果有)。响应中的attrsset是参数中obj_attributes字段的attrsmask字段的子集。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.30.4. IMPLEMENTATION
18.30.4. 实施

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 (e.g., an exclusive create via OPEN) followed by a SETATTR.

如果请求指定要设置的所有者属性,则如果对象的当前所有者与请求中指定的值匹配,服务器应允许操作成功。某些服务器的实现方式可能会禁止设置所有者属性,除非请求者有权限这样做。如果服务器在匹配所有者值的这种情况下比较宽松,那么在创建对象(例如,通过OPEN创建独占的create)然后创建SETATTR的情况下,可以简化客户端实现。

The file size attribute is used to request changes to the size of a file. A value of zero causes the file to be truncated, a value less than the current size of the file causes data from new size to the end of the file to be discarded, and a size greater than the current size of the file causes logically zeroed data bytes to be added to the end of the file. Servers are free to implement this using unallocated bytes (holes) or allocated data bytes set to zero. Clients should not make any assumptions regarding a server's

文件大小属性用于请求更改文件大小。值为零会导致文件被截断,小于文件当前大小的值会导致从新大小到文件结尾的数据被丢弃,大于文件当前大小的值会导致逻辑上归零的数据字节被添加到文件结尾。服务器可以使用未分配的字节(孔)或设置为零的已分配数据字节自由地实现这一点。客户端不应该对服务器的

implementation of this feature, beyond that the bytes in the affected byte-range returned by READ will be zeroed. Servers MUST support extending the file size via SETATTR.

实现此功能后,读取返回的受影响字节范围内的字节将归零。服务器必须支持通过SETATTR扩展文件大小。

SETATTR is not guaranteed to be atomic. A failed SETATTR may partially change a file's attributes, hence the reason why the reply always includes the status and the list of attributes that were set.

SETATTR不能保证是原子的。失败的SETATTR可能会部分更改文件的属性,因此回复中始终包含已设置的状态和属性列表的原因。

If the object whose attributes are being changed has a file delegation that is held by a client other than the one doing the SETATTR, the delegation(s) must be recalled, and the operation cannot proceed to actually change an attribute until each such delegation is returned or revoked. In all cases in which delegations are recalled, the server is likely to return one or more NFS4ERR_DELAY errors while the delegation(s) remains outstanding, although it might not do that if the delegations are returned quickly.

如果属性正在更改的对象具有由执行SETATTR的客户机以外的客户机持有的文件委派,则必须调用委派,并且在返回或撤销每个此类委派之前,操作无法继续实际更改属性。在调用委托的所有情况下,服务器都可能返回一个或多个NFS4ERR_延迟错误,而委托仍然未完成,但如果快速返回委托,则可能不会返回。

If the object whose attributes are being set is a directory and another client holds a directory delegation for that directory, then if enabled, asynchronous notifications will be generated when the set of attributes changed has a non-null intersection with the set of attributes for which notification is requested. Notifications of type NOTIFY4_CHANGE_DIR_ATTRS will be sent to the appropriate client(s), but the SETATTR is not delayed by waiting for these notifications to be sent.

如果正在设置其属性的对象是一个目录,而另一个客户端持有该目录的目录委派,则如果启用,则当更改的属性集与请求通知的属性集具有非空交叉点时,将生成异步通知。NOTIFY4\u CHANGE\u DIR\u ATTR类型的通知将发送到相应的客户端,但SETATTR不会因等待发送这些通知而延迟。

If the object whose attributes are being set is a member of the directory for which another client holds a directory delegation, then asynchronous notifications will be generated when the set of attributes changed has a non-null intersection with the set of attributes for which notification is requested. Notifications of type NOTIFY4_CHANGE_CHILD_ATTRS will be sent to the appropriate clients, but the SETATTR is not delayed by waiting for these notifications to be sent.

如果正在设置其属性的对象是另一个客户端持有目录委派的目录的成员,则当更改的属性集与请求通知的属性集具有非空交叉点时,将生成异步通知。NOTIFY4\u CHANGE\u CHILD\u ATTR类型的通知将发送到相应的客户端,但SETATTR不会因等待发送这些通知而延迟。

Changing the size of a file with SETATTR indirectly changes the time_modify and change attributes. 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 synchronization 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 NFSv3. 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 NFSv4 emulation. Therefore, NFSv4.1 servers SHOULD take care to avoid such delays, to the degree possible, when executing such a request.

使用包含仅指定更改属性的验证操作的复合,紧接着是SETATTR,这提供了一种方法,客户机可以通过该方法指定模拟NFSv3的SETATTR保护机制功能的请求。由于保护机制的功能是避免基于过时信息对文件属性进行更改,因此检查保护条件和设置属性之间的延迟可能会影响此功能,NFSv4仿真中的相应延迟也可能会影响此功能。因此,在执行此类请求时,NFSv4.1服务器应尽可能避免此类延迟。

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 attribute bits not requested to be set by the client. If the attribute masks in the request and reply are equal, the status field in the reply MUST be NFS4_OK.

在所有情况下,SETATTR都会返回实际设置的属性的掩码。该掩码不得包含客户端未请求设置的属性位。如果请求和回复中的属性掩码相等,则回复中的状态字段必须为NFS4_OK。

18.31. Operation 37: VERIFY - Verify Same Attributes
18.31. 操作37:验证-验证相同的属性
18.31.1. ARGUMENTS
18.31.1. 论据
   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };
        
18.31.2. RESULTS
18.31.2. 后果
   struct VERIFY4res {
           nfsstat4        status;
   };
        
   struct VERIFY4res {
           nfsstat4        status;
   };
        
18.31.3. DESCRIPTION
18.31.3. 描述

The VERIFY operation is used to verify that attributes have the value assumed by the client before proceeding with the 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。成功完成操作后,当前文件句柄将保留其值。

18.31.4. IMPLEMENTATION
18.31.4. 实施

One possible use of the VERIFY operation is the following series of operations. With this, the client is attempting to verify that the file being removed will match what the client expects to be removed. This series 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 series does not prevent a second client from removing and creating a new file in the middle of this sequence, but it does help avoid the unintended result.

这个系列不会阻止第二个客户端在这个序列中间移除和创建一个新文件,但是它确实有助于避免意外的结果。

In the case that a RECOMMENDED attribute is specified in the VERIFY operation and the server does not support that attribute for the file system object, the error NFS4ERR_ATTRNOTSUPP is returned to the client.

如果在验证操作中指定了推荐的属性,并且服务器不支持文件系统对象的该属性,则会将错误NFS4ERR_ATTRNOTSUPP返回给客户端。

When the attribute rdattr_error or any set-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将返回给客户端。

18.32. Operation 38: WRITE - Write to File
18.32. 操作38:写入-写入文件
18.32.1. ARGUMENTS
18.32.1. 论据
   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };
        
   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };
        
   struct WRITE4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           stable_how4     stable;
           opaque          data<>;
   };
        
   struct WRITE4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           stable_how4     stable;
           opaque          data<>;
   };
        
18.32.2. RESULTS
18.32.2. 后果
   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;
   };
        
18.32.3. DESCRIPTION
18.32.3. 描述

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 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 zero, the WRITE will succeed and return a count of zero subject to permissions checking. The server MAY write fewer bytes than requested by the client.

写入操作用于将数据写入常规文件。目标文件由当前文件句柄指定。偏移量指定写入数据的偏移量。偏移量为零指定写入应从文件的开头开始。作为不透明数据参数的一部分编码的计数表示要写入的数据字节数。如果计数为零,则写入将成功,并在权限检查的情况下返回零计数。服务器写入的字节数可能少于客户端请求的字节数。

The client specifies with the stable parameter the method of how the data is to be processed by the server. If stable is FILE_SYNC4, the server MUST commit the data written plus all file system metadata to stable storage before returning results. This corresponds to the NFSv2 protocol semantics. Any other behavior constitutes a protocol violation. If stable is DATA_SYNC4, then the server MUST commit all of the data to stable storage and enough of the metadata to retrieve the data before returning. The server implementor is free to implement DATA_SYNC4 in the same fashion as FILE_SYNC4, but with a possible performance drop. If stable is UNSTABLE4, the server is free to commit any part of the data and the metadata to stable storage, including all or none, before returning a reply to the client. There is no guarantee whether or when any uncommitted data will subsequently be committed to stable storage. The only guarantees made by the server are that it will not destroy any data without changing the value of writeverf and that it will not commit the data and metadata at a level less than that requested by the client.

客户机使用stable参数指定服务器如何处理数据的方法。如果stable是FILE_SYNC4,则服务器必须在返回结果之前将写入的数据加上所有文件系统元数据提交到stable存储。这与NFSv2协议语义相对应。任何其他行为都构成违反协议。如果stable是DATA_SYNC4,则服务器必须将所有数据提交到稳定存储,并在返回之前提交足够的元数据以检索数据。服务器实现者可以自由地以与文件同步4相同的方式实现数据同步4,但可能会导致性能下降。如果stable是不稳定的4,则服务器可以自由地将数据和元数据的任何部分提交到稳定存储,包括全部或全部,然后再向客户端返回回复。无法保证任何未提交的数据随后是否或何时提交到稳定存储。服务器所做的唯一保证是在不更改writerf的值的情况下不会销毁任何数据,并且不会以低于客户端请求的级别提交数据和元数据。

Except when special stateids are used, the stateid value for a WRITE request represents a value returned from a previous byte-range LOCK or OPEN request or the stateid associated with a delegation. The stateid identifies the associated owners if any and is used by the server to verify that the associated locks are still valid (e.g., have not been revoked).

除非使用特殊的stateid,否则写入请求的stateid值表示从上一个字节范围锁定或打开请求返回的值或与委派关联的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. Per Table 11,

服务器还通过提交返回数据和元数据的提交级别指示。根据表11,

o The server MAY commit the data at a stronger level than requested.

o 服务器提交数据的级别可能比请求的级别更高。

o The server MUST commit the data at a level at least as high as that committed.

o 服务器提交数据的级别必须至少与提交的级别相同。

Valid combinations of the fields stable in the request and committed in the reply.

请求中稳定的字段和答复中提交的字段的有效组合。

            +------------+-----------------------------------+
            | stable     | committed                         |
            +------------+-----------------------------------+
            | UNSTABLE4  | FILE_SYNC4, DATA_SYNC4, UNSTABLE4 |
            | DATA_SYNC4 | FILE_SYNC4, DATA_SYNC4            |
            | FILE_SYNC4 | FILE_SYNC4                        |
            +------------+-----------------------------------+
        
            +------------+-----------------------------------+
            | stable     | committed                         |
            +------------+-----------------------------------+
            | UNSTABLE4  | FILE_SYNC4, DATA_SYNC4, UNSTABLE4 |
            | DATA_SYNC4 | FILE_SYNC4, DATA_SYNC4            |
            | FILE_SYNC4 | FILE_SYNC4                        |
            +------------+-----------------------------------+
        

Table 11

表11

The final portion of the result is the field writeverf. This field is the write verifier and is a cookie that the client can use to determine whether a server has changed instance state (e.g., server restart) between a call to WRITE and a subsequent call to either WRITE or COMMIT. This cookie MUST be unchanged during a single instance of the NFSv4.1 server and MUST be unique between instances of the NFSv4.1 server. If the cookie changes, then the client MUST assume that any data written with an UNSTABLE4 value for committed and an old writeverf in the reply has been lost and will need to be recovered.

结果的最后一部分是字段writerf。此字段是写入验证器,并且是一个cookie,客户端可以使用它来确定服务器是否已在写入调用和后续写入或提交调用之间更改了实例状态(例如,服务器重新启动)。此cookie在NFSv4.1服务器的单个实例期间必须保持不变,并且在NFSv4.1服务器的实例之间必须是唯一的。如果cookie发生更改,则客户端必须假定在回复中使用“已提交”和“旧写入”的UNSTABLE4值写入的任何数据都已丢失,需要恢复。

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

如果客户端将stable参数设置为UNSTABLE4时将数据写入服务器,并且回复产生data_SYNC4或UNSTABLE4的提交响应,则客户端将在将来的某个时间执行提交操作,以同步未完成的异步数据和数据

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.

元数据与服务器的稳定存储,防止客户端错误。由于客户端崩溃或其他错误,服务器可能无法接收后续提交。

For a WRITE with a stateid value of all bits equal to zero, the server MAY allow the WRITE to be serviced subject to mandatory byte-range locks or the current share deny modes for the file. For a WRITE with a stateid value of all bits equal to 1, the server MUST NOT allow the WRITE operation to bypass locking checks at the server and otherwise is treated as if a stateid of all bits equal to zero were used.

对于stateid值为所有位等于零的写操作,服务器可能允许根据强制字节范围锁或文件的当前共享拒绝模式为写操作提供服务。对于stateid值为所有位等于1的写入,服务器不得允许写入操作绕过服务器上的锁定检查,否则将被视为使用了所有位等于零的stateid。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

18.32.4. IMPLEMENTATION
18.32.4. 实施

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 will need to send another WRITE to write the remaining data.

服务器写入的数据字节数可能少于客户端请求的字节数。在这种情况下,除非根本没有写入数据,否则服务器不应返回错误。如果服务器写入的字节数小于指定的字节数,则客户端将需要发送另一次写入来写入剩余的数据。

It is assumed that the act of writing data to a file will cause the time_modified and change attributes of the file to be updated. However, these attributes SHOULD NOT be changed unless the contents of the file are changed. Thus, a WRITE request with count set to zero SHOULD NOT cause the time_modified and change attributes of the file to be updated.

假设将数据写入文件的行为将导致文件的时间_修改和更改属性更新。但是,除非更改文件的内容,否则不应更改这些属性。因此,计数设置为零的写入请求不应导致文件的修改时间和更改属性被更新。

Stable storage is persistent storage that survives:

稳定存储是一种持久性存储,可在以下情况下生存:

1. Repeated power failures.

1. 反复停电。

2. Hardware failures (of any board, power supply, etc.).

2. 硬件故障(任何板、电源等)。

3. Repeated software crashes and restarts.

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 NFSv4.1 protocol server over which cached, uncommitted data may be lost. In the most likely case, the verifier allows the client to detect server restarts. 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

验证器被定义为允许客户端检测NFSv4.1协议服务器的不同实例,在这些实例上缓存的未提交数据可能会丢失。在最可能的情况下,验证器允许客户端检测服务器重新启动。需要此信息,以便客户端可以安全地确定服务器是否可能丢失了缓存数据。如果服务器意外失败,并且客户机具有来自以前写入请求的未提交数据(在将stable参数设置为UNSTABLE4的情况下完成,并且结果

committed was returned as UNSTABLE4 as well), the server might 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.

提交的数据返回为不稳定(4),服务器可能没有将缓存数据刷新到稳定存储。恢复的负担由客户端承担,客户端需要将数据重新传输到服务器。

A suggested verifier would be to use the time that the server was last started (if restarting the server results in lost buffers).

建议的验证器是使用服务器上次启动的时间(如果重新启动服务器导致缓冲区丢失)。

The reply's committed field 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.

reply的committed字段允许客户端进行更有效的缓存。如果服务器正在将所有写请求提交到稳定存储,则无论参数中稳定字段的值是多少,它都应返回并将提交集设置为FILE_SYNC4。使用NVRAM加速器的服务器可以选择实施此策略。客户机可以通过丢弃已在服务器上提交的缓存数据来提高缓存的有效性。

Some implementations may return NFS4ERR_NOSPC instead of NFS4ERR_DQUOT when a user's quota is exceeded.

当超过用户配额时,某些实现可能返回NFS4ERR_NOSPC而不是NFS4ERR_DQUOT。

In the case that the current filehandle is of type NF4DIR, the server will return NFS4ERR_ISDIR. If the current file is a symbolic link, the error NFS4ERR_SYMLINK will be returned. Otherwise, if the current filehandle does not designate an ordinary file, the server will return NFS4ERR_WRONG_TYPE.

如果当前文件句柄的类型为NF4DIR,服务器将返回NFS4ERR_ISDIR。如果当前文件是符号链接,将返回错误NFS4ERR_SYMLINK。否则,如果当前文件句柄未指定普通文件,服务器将返回NFS4ERR_错误类型。

If mandatory byte-range locking is in effect for the file, and the corresponding byte-range of the data to be written to the file is READ_LT or WRITE_LT locked by an owner that is not associated with the stateid, the server MUST 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_LT lock that overlaps with the byte-range that was to be written. If the stateid's owner has no conflicting READ_LT lock, then the client SHOULD try to get the appropriate write byte-range lock via the LOCK operation before re-attempting the WRITE. When the WRITE completes, the client SHOULD release the byte-range lock via LOCKU.

如果强制字节范围锁定对文件生效,并且要写入文件的数据的相应字节范围由与stateid不关联的所有者进行读取或写入锁定,则服务器必须返回NFS4ERR\u locked。如果是这样,客户端必须检查与写入操作使用的stateid对应的所有者是否具有与要写入的字节范围重叠的冲突读锁。如果stateid的所有者没有冲突的读锁定,则客户端应在重新尝试写入之前,通过锁定操作尝试获取适当的写入字节范围锁定。写入完成后,客户端应通过LOCKU释放字节范围锁。

If the stateid's owner had a conflicting READ_LT 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_LT lock, either the server attempted to temporarily effectively upgrade this READ_LT lock to a WRITE_LT lock or the server has no upgrade capability. If the server attempted to upgrade the READ_LT 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

如果stateid的所有者具有冲突的读锁,则客户端别无选择,只能向尝试写入的应用程序返回错误。原因是由于stateid的所有者有一个读锁,服务器试图暂时有效地将该读锁升级为写锁,或者服务器没有升级功能。如果服务器尝试升级读取锁但失败,则客户端通过锁定操作重新尝试升级是毫无意义的,因为可能还有另一个客户端也在尝试升级。如果两个客户端被阻止

trying to 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.

尝试升级同一个锁时,客户端会死锁。如果服务器没有升级功能,那么尝试锁定操作进行升级是毫无意义的。

If one or more other clients have delegations for the file being written, those delegations MUST be recalled, and the operation cannot proceed until those delegations are returned or revoked. Except where this happens very quickly, one or more NFS4ERR_DELAY errors will be returned to requests made while the delegation remains outstanding. Normally, delegations will not be recalled as a result of a WRITE operation since the recall will occur as a result of an earlier OPEN. However, since it is possible for a WRITE to be done with a special stateid, the server needs to check for this case even though the client should have done an OPEN previously.

如果一个或多个其他客户端对正在写入的文件具有委托,则必须撤回这些委托,并且在返回或撤销这些委托之前,操作无法继续。除非这种情况发生得很快,否则在委托仍然未完成的情况下,一个或多个NFS4ERR_延迟错误将返回到请求。通常情况下,不会因写入操作而召回代表团,因为召回将因先前的打开操作而发生。但是,由于可以使用特殊的stateid进行写操作,因此服务器需要检查这种情况,即使客户端以前应该进行过打开操作。

18.33. Operation 40: BACKCHANNEL_CTL - Backchannel Control
18.33. 操作40:反向通道控制-反向通道控制
18.33.1. ARGUMENT
18.33.1. 论点
   typedef opaque gsshandle4_t<>;
        
   typedef opaque gsshandle4_t<>;
        
   struct gss_cb_handles4 {
           rpc_gss_svc_t           gcbp_service; /* RFC 2203 */
           gsshandle4_t            gcbp_handle_from_server;
           gsshandle4_t            gcbp_handle_from_client;
   };
        
   struct gss_cb_handles4 {
           rpc_gss_svc_t           gcbp_service; /* RFC 2203 */
           gsshandle4_t            gcbp_handle_from_server;
           gsshandle4_t            gcbp_handle_from_client;
   };
        
   union callback_sec_parms4 switch (uint32_t cb_secflavor) {
   case AUTH_NONE:
           void;
   case AUTH_SYS:
           authsys_parms   cbsp_sys_cred; /* RFC 1831 */
   case RPCSEC_GSS:
           gss_cb_handles4 cbsp_gss_handles;
   };
        
   union callback_sec_parms4 switch (uint32_t cb_secflavor) {
   case AUTH_NONE:
           void;
   case AUTH_SYS:
           authsys_parms   cbsp_sys_cred; /* RFC 1831 */
   case RPCSEC_GSS:
           gss_cb_handles4 cbsp_gss_handles;
   };
        
   struct BACKCHANNEL_CTL4args {
           uint32_t                bca_cb_program;
           callback_sec_parms4     bca_sec_parms<>;
   };
        
   struct BACKCHANNEL_CTL4args {
           uint32_t                bca_cb_program;
           callback_sec_parms4     bca_sec_parms<>;
   };
        
18.33.2. RESULT
18.33.2. 后果
   struct BACKCHANNEL_CTL4res {
           nfsstat4                bcr_status;
   };
        
   struct BACKCHANNEL_CTL4res {
           nfsstat4                bcr_status;
   };
        
18.33.3. DESCRIPTION
18.33.3. 描述

The BACKCHANNEL_CTL operation replaces the backchannel's callback program number and adds (not replaces) RPCSEC_GSS handles for use by the backchannel.

BACKCHANNEL_CTL操作将替换BACKCHANNEL的回调程序号,并添加(而不是替换)RPCSEC_GSS句柄以供BACKCHANNEL使用。

The arguments of the BACKCHANNEL_CTL call are a subset of the CREATE_SESSION parameters. In the arguments of BACKCHANNEL_CTL, the bca_cb_program field and bca_sec_parms fields correspond respectively to the csa_cb_program and csa_sec_parms fields of the arguments of CREATE_SESSION (Section 18.36).

BACKCHANNEL_CTL调用的参数是CREATE_会话参数的子集。在BACKCHANNEL_CTL的参数中,bca_cb_program字段和bca_secu parms字段分别对应于CREATE_SESSION参数的csa_cb_program和csa_secu parms字段(第18.36节)。

BACKCHANNEL_CTL MUST appear in a COMPOUND that starts with SEQUENCE.

反向通道CTL必须出现在以序列开头的化合物中。

If the RPCSEC_GSS handle identified by gcbp_handle_from_server does not exist on the server, the server MUST return NFS4ERR_NOENT.

如果服务器上不存在由来自\u服务器的gcbp\u handle\u标识的RPCSEC\u GSS句柄,则服务器必须返回NFS4ERR\u NOENT。

If an RPCSEC_GSS handle is using the SSV context (see Section 2.10.9), then because each SSV RPCSEC_GSS handle shares a common SSV GSS context, there are security considerations specific to this situation discussed in Section 2.10.10.

如果RPCSEC_GSS句柄正在使用SSV上下文(请参阅第2.10.9节),则由于每个SSV RPCSEC_GSS句柄共享一个公共SSV GSS上下文,因此在第2.10.10节中讨论了特定于这种情况的安全注意事项。

18.34. Operation 41: BIND_CONN_TO_SESSION - Associate Connection with Session

18.34. 操作41:将连接绑定到会话-将连接与会话关联

18.34.1. ARGUMENT
18.34.1. 论点
   enum channel_dir_from_client4 {
    CDFC4_FORE             = 0x1,
    CDFC4_BACK             = 0x2,
    CDFC4_FORE_OR_BOTH     = 0x3,
    CDFC4_BACK_OR_BOTH     = 0x7
   };
        
   enum channel_dir_from_client4 {
    CDFC4_FORE             = 0x1,
    CDFC4_BACK             = 0x2,
    CDFC4_FORE_OR_BOTH     = 0x3,
    CDFC4_BACK_OR_BOTH     = 0x7
   };
        
   struct BIND_CONN_TO_SESSION4args {
    sessionid4     bctsa_sessid;
        
   struct BIND_CONN_TO_SESSION4args {
    sessionid4     bctsa_sessid;
        

channel_dir_from_client4 bctsa_dir;

来自客户4 bctsa dir的频道;

    bool           bctsa_use_conn_in_rdma_mode;
   };
        
    bool           bctsa_use_conn_in_rdma_mode;
   };
        
18.34.2. RESULT
18.34.2. 后果
   enum channel_dir_from_server4 {
    CDFS4_FORE     = 0x1,
    CDFS4_BACK     = 0x2,
    CDFS4_BOTH     = 0x3
   };
        
   enum channel_dir_from_server4 {
    CDFS4_FORE     = 0x1,
    CDFS4_BACK     = 0x2,
    CDFS4_BOTH     = 0x3
   };
        
   struct BIND_CONN_TO_SESSION4resok {
    sessionid4     bctsr_sessid;
        
   struct BIND_CONN_TO_SESSION4resok {
    sessionid4     bctsr_sessid;
        

channel_dir_from_server4 bctsr_dir;

来自服务器4 bctsr目录的频道目录;

    bool           bctsr_use_conn_in_rdma_mode;
   };
        
    bool           bctsr_use_conn_in_rdma_mode;
   };
        

union BIND_CONN_TO_SESSION4res switch (nfsstat4 bctsr_status) {

联合绑定连接到会话4RES交换机(nfsstat4 bctsr状态){

case NFS4_OK: BIND_CONN_TO_SESSION4resok bctsr_resok4;

案例NFS4确定:将连接件绑定到会话4决议bctsr决议4;

    default:       void;
   };
        
    default:       void;
   };
        
18.34.3. DESCRIPTION
18.34.3. 描述

BIND_CONN_TO_SESSION is used to associate additional connections with a session. It MUST be used on the connection being associated with the session. It MUST be the only operation in the COMPOUND procedure. If SP4_NONE (Section 18.35) state protection is used, any principal, security flavor, or RPCSEC_GSS context MAY be used to invoke the operation. If SP4_MACH_CRED is used, RPCSEC_GSS MUST be used with the integrity or privacy services, using the principal that created the client ID. If SP4_SSV is used, RPCSEC_GSS with the SSV GSS mechanism (Section 2.10.9) and integrity or privacy MUST be used.

BIND_CONN_TO_会话用于将其他连接与会话关联。它必须在与会话关联的连接上使用。它必须是复合过程中的唯一操作。如果使用SP4_NONE(第18.35节)状态保护,则可以使用任何主体、安全风格或RPCSEC_GSS上下文来调用该操作。如果使用SP4_MACH_CRED,则必须使用创建客户ID的委托人,将RPCSEC_GSS与完整性或隐私服务一起使用。如果使用SP4_SSV,则必须使用带有SSV GSS机制(第2.10.9节)和完整性或隐私的RPCSEC_GSS。

If, when the client ID was created, the client opted for SP4_NONE state protection, the client is not required to use BIND_CONN_TO_SESSION to associate the connection with the session, unless the client wishes to associate the connection with the backchannel. When SP4_NONE protection is used, simply sending a COMPOUND request with a SEQUENCE operation is sufficient to associate the connection with the session specified in SEQUENCE.

如果在创建客户端ID时,客户端选择了SP4_NONE状态保护,则不要求客户端使用BIND_CONN_to_会话将连接与会话关联,除非客户端希望将连接与反向通道关联。使用SP4_NONE保护时,仅发送带有序列操作的复合请求就足以将连接与序列中指定的会话相关联。

The field bctsa_dir indicates whether the client wants to associate the connection with the fore channel or the backchannel or both channels. The value CDFC4_FORE_OR_BOTH indicates that the client wants to associate the connection with both the fore channel and backchannel, but will accept the connection being associated to just the fore channel. The value CDFC4_BACK_OR_BOTH indicates that the client wants to associate with both the fore channel and backchannel, but will accept the connection being associated with just the backchannel. The server replies in bctsr_dir which channel(s) the connection is associated with. If the client specified CDFC4_FORE, the server MUST return CDFS4_FORE. If the client specified CDFC4_BACK, the server MUST return CDFS4_BACK. If the client specified CDFC4_FORE_OR_BOTH, the server MUST return CDFS4_FORE or CDFS4_BOTH. If the client specified CDFC4_BACK_OR_BOTH, the server MUST return CDFS4_BACK or CDFS4_BOTH.

字段bctsa_dir指示客户机是否要将连接与前通道或后通道或两个通道关联。值CDFC4_FORE_或_BOTH表示客户端希望将连接与前向通道和后向通道关联,但将接受仅与前向通道关联的连接。值CDFC4_BACK_或_all表示客户端希望同时与前通道和后通道关联,但将接受仅与后通道关联的连接。服务器在bctsr_dir中答复连接与哪个通道关联。如果客户端指定了CDFC4\u-FORE,则服务器必须返回CDFS4\u-FORE。如果客户端指定了CDFC4\u,则服务器必须返回CDFS4\u。如果客户端指定了CDFC4\u FORE\u或两者,则服务器必须同时返回CDFS4\u FORE或CDFS4\u。如果客户端指定了CDFC4\u BACK\u或两者,则服务器必须同时返回CDFS4\u BACK或CDFS4\u。

See the CREATE_SESSION operation (Section 18.36), and the description of the argument csa_use_conn_in_rdma_mode to understand bctsa_use_conn_in_rdma_mode, and the description of csr_use_conn_in_rdma_mode to understand bctsr_use_conn_in_rdma_mode.

请参阅创建会话操作(第18.36节),以及参数csa_use_conn_in_rdma_模式的说明,以了解bctsa_use_conn_in_rdma_模式,以及csr_use_conn_in_rdma_模式的说明,以了解bctsr_use_conn_in_rdma_模式。

Invoking BIND_CONN_TO_SESSION on a connection already associated with the specified session has no effect, and the server MUST respond with NFS4_OK, unless the client is demanding changes to the set of channels the connection is associated with. If so, the server MUST return NFS4ERR_INVAL.

在已与指定会话关联的连接上调用BIND_CONN_TO_会话无效,服务器必须使用NFS4_OK进行响应,除非客户端要求更改与该连接关联的通道集。如果是这样,服务器必须返回NFS4ERR_INVAL。

18.34.4. IMPLEMENTATION
18.34.4. 实施

If a session's channel loses all connections, depending on the client ID's state protection and type of channel, the client might need to use BIND_CONN_TO_SESSION to associate a new connection. If the server restarted and does not keep the reply cache in stable storage, the server will not recognize the session ID. The client will ultimately have to invoke EXCHANGE_ID to create a new client ID and session.

如果会话的通道丢失所有连接,则根据客户端ID的状态保护和通道类型,客户端可能需要使用BIND_CONN_to_session来关联新连接。如果服务器重新启动并且没有将应答缓存保持在稳定的存储中,服务器将无法识别会话ID。客户端最终必须调用EXCHANGE_ID来创建新的客户端ID和会话。

Suppose SP4_SSV state protection is being used, and BIND_CONN_TO_SESSION is among the operations included in the spo_must_enforce set when the client ID was created (Section 18.35). If so, there is an issue if SET_SSV is sent, no response is returned, and the last connection associated with the client ID drops. The client, per the sessions model, MUST retry the SET_SSV. But it needs a new connection to do so, and MUST associate that connection with the session via a BIND_CONN_TO_SESSION authenticated with the SSV GSS mechanism. The problem is that the RPCSEC_GSS message integrity

假设正在使用SP4_SSV状态保护,并且在创建客户端ID时,绑定连接到会话是spo_必须执行集中包含的操作之一(第18.35节)。如果是这样,那么如果发送SET_SSV,不返回响应,并且与客户端ID关联的最后一个连接断开,则会出现问题。根据会话模型,客户端必须重试设置SSV。但它需要一个新的连接来实现这一点,并且必须通过一个通过SSV GSS机制验证的BIND_CONN_to_会话将该连接与会话相关联。问题在于RPCSEC_GSS消息的完整性

codes use a subkey derived from the SSV as the key and the SSV may have changed. While there are multiple recovery strategies, a single, general strategy is described here.

代码使用从SSV派生的子密钥作为密钥,SSV可能已更改。虽然有多种恢复策略,但这里描述的是一种单一的通用策略。

o The client reconnects.

o 客户端将重新连接。

o The client assumes that the SET_SSV was executed, and so sends BIND_CONN_TO_SESSION with the subkey (derived from the new SSV, i.e., what SET_SSV would have set the SSV to) used as the key for the RPCSEC_GSS credential message integrity codes.

o 客户端假定已执行SET_SSV,因此使用子密钥(从新SSV派生,即SET_SSV将SSV设置为的对象)发送BIND_CONN_TO_会话,该子密钥用作RPCSEC_GSS凭据消息完整性代码的密钥。

o If the request succeeds, this means that the original attempted SET_SSV did execute successfully. The client re-sends the original SET_SSV, which the server will reply to via the reply cache.

o 如果请求成功,这意味着原始尝试的SET_SSV已成功执行。客户端重新发送原始的SET_SSV,服务器将通过应答缓存对其进行应答。

o If the server returns an RPC authentication error, this means that the server's current SSV was not changed (and the SET_SSV was likely not executed). The client then tries BIND_CONN_TO_SESSION with the subkey derived from the old SSV as the key for the RPCSEC_GSS message integrity codes.

o 如果服务器返回RPC身份验证错误,这意味着服务器的当前SSV没有更改(并且SET_SSV可能没有执行)。然后,客户端尝试使用从旧SSV派生的子密钥作为RPCSEC_GSS消息完整性代码的密钥,将_CONN_绑定到_会话。

o The attempted BIND_CONN_TO_SESSION with the old SSV should succeed. If so, the client re-sends the original SET_SSV. If the original SET_SSV was not executed, then the server executes it. If the original SET_SSV was executed but failed, the server will return the SET_SSV from the reply cache.

o 尝试与旧SSV绑定连接到会话应成功。如果是这样,客户端将重新发送原始的SET_SSV。如果未执行原始的SET_SSV,则服务器将执行它。如果原始SET_SSV已执行但失败,服务器将从应答缓存返回SET_SSV。

18.35. Operation 42: EXCHANGE_ID - Instantiate Client ID
18.35. 操作42:EXCHANGE\u ID-实例化客户端ID

The EXCHANGE_ID exchanges long-hand client and server identifiers (owners), and creates a client ID.

EXCHANGE\u ID交换长期客户端和服务器标识符(所有者),并创建客户端ID。

18.35.1. ARGUMENT
18.35.1. 论点
   const EXCHGID4_FLAG_SUPP_MOVED_REFER    = 0x00000001;
   const EXCHGID4_FLAG_SUPP_MOVED_MIGR     = 0x00000002;
        
   const EXCHGID4_FLAG_SUPP_MOVED_REFER    = 0x00000001;
   const EXCHGID4_FLAG_SUPP_MOVED_MIGR     = 0x00000002;
        

const EXCHGID4_FLAG_BIND_PRINC_STATEID = 0x00000100;

const EXCHGID4\u FLAG\u BIND\u PRINC\u STATEID=0x00000100;

   const EXCHGID4_FLAG_USE_NON_PNFS        = 0x00010000;
   const EXCHGID4_FLAG_USE_PNFS_MDS        = 0x00020000;
   const EXCHGID4_FLAG_USE_PNFS_DS         = 0x00040000;
        
   const EXCHGID4_FLAG_USE_NON_PNFS        = 0x00010000;
   const EXCHGID4_FLAG_USE_PNFS_MDS        = 0x00020000;
   const EXCHGID4_FLAG_USE_PNFS_DS         = 0x00040000;
        

const EXCHGID4_FLAG_MASK_PNFS = 0x00070000;

const EXCHGID4_FLAG_MASK_PNFS=0x00070000;

   const EXCHGID4_FLAG_UPD_CONFIRMED_REC_A = 0x40000000;
   const EXCHGID4_FLAG_CONFIRMED_R         = 0x80000000;
        
   const EXCHGID4_FLAG_UPD_CONFIRMED_REC_A = 0x40000000;
   const EXCHGID4_FLAG_CONFIRMED_R         = 0x80000000;
        
   struct state_protect_ops4 {
           bitmap4 spo_must_enforce;
           bitmap4 spo_must_allow;
   };
        
   struct state_protect_ops4 {
           bitmap4 spo_must_enforce;
           bitmap4 spo_must_allow;
   };
        
   struct ssv_sp_parms4 {
           state_protect_ops4      ssp_ops;
           sec_oid4                ssp_hash_algs<>;
           sec_oid4                ssp_encr_algs<>;
           uint32_t                ssp_window;
           uint32_t                ssp_num_gss_handles;
   };
        
   struct ssv_sp_parms4 {
           state_protect_ops4      ssp_ops;
           sec_oid4                ssp_hash_algs<>;
           sec_oid4                ssp_encr_algs<>;
           uint32_t                ssp_window;
           uint32_t                ssp_num_gss_handles;
   };
        
   enum state_protect_how4 {
           SP4_NONE = 0,
           SP4_MACH_CRED = 1,
           SP4_SSV = 2
   };
        
   enum state_protect_how4 {
           SP4_NONE = 0,
           SP4_MACH_CRED = 1,
           SP4_SSV = 2
   };
        
   union state_protect4_a switch(state_protect_how4 spa_how) {
           case SP4_NONE:
                   void;
           case SP4_MACH_CRED:
                   state_protect_ops4      spa_mach_ops;
           case SP4_SSV:
                   ssv_sp_parms4           spa_ssv_parms;
   };
        
   union state_protect4_a switch(state_protect_how4 spa_how) {
           case SP4_NONE:
                   void;
           case SP4_MACH_CRED:
                   state_protect_ops4      spa_mach_ops;
           case SP4_SSV:
                   ssv_sp_parms4           spa_ssv_parms;
   };
        
   struct EXCHANGE_ID4args {
           client_owner4           eia_clientowner;
           uint32_t                eia_flags;
           state_protect4_a        eia_state_protect;
           nfs_impl_id4            eia_client_impl_id<1>;
   };
        
   struct EXCHANGE_ID4args {
           client_owner4           eia_clientowner;
           uint32_t                eia_flags;
           state_protect4_a        eia_state_protect;
           nfs_impl_id4            eia_client_impl_id<1>;
   };
        
18.35.2. RESULT
18.35.2. 后果
   struct ssv_prot_info4 {
    state_protect_ops4     spi_ops;
    uint32_t               spi_hash_alg;
    uint32_t               spi_encr_alg;
    uint32_t               spi_ssv_len;
    uint32_t               spi_window;
    gsshandle4_t           spi_handles<>;
   };
        
   struct ssv_prot_info4 {
    state_protect_ops4     spi_ops;
    uint32_t               spi_hash_alg;
    uint32_t               spi_encr_alg;
    uint32_t               spi_ssv_len;
    uint32_t               spi_window;
    gsshandle4_t           spi_handles<>;
   };
        
   union state_protect4_r switch(state_protect_how4 spr_how) {
    case SP4_NONE:
            void;
    case SP4_MACH_CRED:
            state_protect_ops4     spr_mach_ops;
    case SP4_SSV:
            ssv_prot_info4         spr_ssv_info;
   };
        
   union state_protect4_r switch(state_protect_how4 spr_how) {
    case SP4_NONE:
            void;
    case SP4_MACH_CRED:
            state_protect_ops4     spr_mach_ops;
    case SP4_SSV:
            ssv_prot_info4         spr_ssv_info;
   };
        
   struct EXCHANGE_ID4resok {
    clientid4        eir_clientid;
    sequenceid4      eir_sequenceid;
    uint32_t         eir_flags;
    state_protect4_r eir_state_protect;
    server_owner4    eir_server_owner;
    opaque           eir_server_scope<NFS4_OPAQUE_LIMIT>;
    nfs_impl_id4     eir_server_impl_id<1>;
   };
        
   struct EXCHANGE_ID4resok {
    clientid4        eir_clientid;
    sequenceid4      eir_sequenceid;
    uint32_t         eir_flags;
    state_protect4_r eir_state_protect;
    server_owner4    eir_server_owner;
    opaque           eir_server_scope<NFS4_OPAQUE_LIMIT>;
    nfs_impl_id4     eir_server_impl_id<1>;
   };
        
   union EXCHANGE_ID4res switch (nfsstat4 eir_status) {
   case NFS4_OK:
    EXCHANGE_ID4resok      eir_resok4;
        
   union EXCHANGE_ID4res switch (nfsstat4 eir_status) {
   case NFS4_OK:
    EXCHANGE_ID4resok      eir_resok4;
        
   default:
    void;
   };
        
   default:
    void;
   };
        
18.35.3. DESCRIPTION
18.35.3. 描述

The client uses the EXCHANGE_ID operation to register a particular client owner with the server. The client ID returned from this operation will be necessary for requests that create state on the server and will serve as a parent object to sessions created by the client. In order to confirm the client ID it must first be used, along with the returned eir_sequenceid, as arguments to CREATE_SESSION. If the flag EXCHGID4_FLAG_CONFIRMED_R is set in the result, eir_flags, then eir_sequenceid MUST be ignored, as it has no relevancy.

客户端使用EXCHANGE\u ID操作向服务器注册特定的客户端所有者。此操作返回的客户端ID对于在服务器上创建状态的请求是必需的,并且将用作客户端创建的会话的父对象。为了确认客户机ID,必须首先将其与返回的eir_sequenceid一起用作参数来创建_会话。如果在结果中设置了标志EXCHGID4\u flag\u CONFIFIENT\R,则必须忽略eir\u sequenceid,因为它没有相关性。

EXCHANGE_ID MAY be sent in a COMPOUND procedure that starts with SEQUENCE. However, when a client communicates with a server for the first time, it will not have a session, so using SEQUENCE will not be possible. If EXCHANGE_ID is sent without a preceding SEQUENCE, then it MUST be the only operation in the COMPOUND procedure's request. If it is not, the server MUST return NFS4ERR_NOT_ONLY_OP.

交换ID可以在以顺序开始的复合过程中发送。但是,当客户机第一次与服务器通信时,它将没有会话,因此无法使用SEQUENCE。如果发送EXCHANGE_ID时没有前面的序列,则它必须是复合过程请求中的唯一操作。如果不是,服务器必须返回NFS4ERR\u not\u ONLY\u OP。

The eia_clientowner field is composed of a co_verifier field and a co_ownerid string. As noted in Section 2.4, the co_ownerid describes the client, and the co_verifier is the incarnation of the client. An EXCHANGE_ID sent with a new incarnation of the client will lead to the server removing lock state of the old incarnation. Whereas an EXCHANGE_ID sent with the current incarnation and co_ownerid will result in an error or an update of the client ID's properties, depending on the arguments to EXCHANGE_ID.

eia_clientowner字段由co_验证程序字段和co_ownerid字符串组成。如第2.4节所述,共同所有者ID描述了客户,共同验证者是客户的化身。与客户机的新版本一起发送的EXCHANGE_ID将导致服务器删除旧版本的锁定状态。而与当前化身和共同所有者ID一起发送的EXCHANGE\u ID将导致错误或客户端ID属性的更新,具体取决于EXCHANGE\u ID的参数。

A server MUST NOT use the same client ID for two different incarnations of an eir_clientowner.

服务器不得对eir_客户端所有者的两个不同版本使用相同的客户端ID。

In addition to the client ID and sequence ID, the server returns a server owner (eir_server_owner) and server scope (eir_server_scope). The former field is used for network trunking as described in Section 2.10.5. The latter field is used to allow clients to determine when client IDs sent by one server may be recognized by another in the event of file system migration (see Section 11.7.7).

除了客户机ID和序列ID之外,服务器还返回服务器所有者(eir_服务器所有者)和服务器作用域(eir_服务器作用域)。前一个字段用于第2.10.5节所述的网络中继。后一个字段用于允许客户端确定在文件系统迁移时,一台服务器发送的客户端ID何时可被另一台服务器识别(请参阅第11.7.7节)。

The client ID returned by EXCHANGE_ID is only unique relative to the combination of eir_server_owner.so_major_id and eir_server_scope. Thus, if two servers return the same client ID, the onus is on the client to distinguish the client IDs on the basis of eir_server_owner.so_major_id and eir_server_scope. In the event two different servers claim matching server_owner.so_major_id and eir_server_scope, the client can use the verification techniques discussed in Section 2.10.5 to determine if the servers are distinct. If they are distinct, then the client will need to note the destination network addresses of the connections used with each server, and use the network address as the final discriminator.

EXCHANGE\u ID返回的客户端ID仅相对于eir\u服务器\u所有者。so\u主\u ID和eir\u服务器\u作用域的组合是唯一的。因此,如果两台服务器返回相同的客户机ID,则客户机有责任根据eir_server_owner.so_major_ID和eir_server_作用域来区分客户机ID。如果两台不同的服务器声称匹配服务器所有者。so_主要_id和eir_服务器范围,客户可以使用第2.10.5节中讨论的验证技术来确定服务器是否不同。如果它们是不同的,那么客户端将需要记录每个服务器使用的连接的目标网络地址,并使用该网络地址作为最终的鉴别器。

The server, as defined by the unique identity expressed in the so_major_id of the server owner and the server scope, needs to track several properties of each client ID it hands out. The properties apply to the client ID and all sessions associated with the client ID. The properties are derived from the arguments and results of EXCHANGE_ID. The client ID properties include:

根据服务器所有者的so_major_id和服务器作用域中表示的唯一标识的定义,服务器需要跟踪它分发的每个客户机id的多个属性。这些属性适用于客户端ID以及与客户端ID关联的所有会话。这些属性源自EXCHANGE_ID的参数和结果。客户端ID属性包括:

o The capabilities expressed by the following bits, which come from the results of EXCHANGE_ID:

o 由以下位表示的能力,这些位来自交换ID的结果:

* EXCHGID4_FLAG_SUPP_MOVED_REFER

* EXCHGID4\u标志\u支持\u移动\u参考

* EXCHGID4_FLAG_SUPP_MOVED_MIGR

* EXCHGID4标志支持移动

* EXCHGID4_FLAG_BIND_PRINC_STATEID

* EXCHGID4\u标志\u绑定\u原则\u状态ID

* EXCHGID4_FLAG_USE_NON_PNFS

* EXCHGID4\u标志\u使用\u非PNF

* EXCHGID4_FLAG_USE_PNFS_MDS

* EXCHGID4\u标志\u使用\u PNFS\u MDS

* EXCHGID4_FLAG_USE_PNFS_DS

* EXCHGID4\u标志\u使用\u PNFS\u DS

These properties may be updated by subsequent EXCHANGE_ID requests on confirmed client IDs though the server MAY refuse to change them.

虽然服务器可能拒绝更改这些属性,但这些属性可能会通过对已确认的客户端ID的后续EXCHANGE_ID请求进行更新。

o The state protection method used, one of SP4_NONE, SP4_MACH_CRED, or SP4_SSV, as set by the spa_how field of the arguments to EXCHANGE_ID. Once the client ID is confirmed, this property cannot be updated by subsequent EXCHANGE_ID requests.

o 所使用的状态保护方法,SP4_NONE、SP4_MACH_CRED或SP4_SSV中的一种,由EXCHANGE_ID参数的spa_how字段设置。一旦确认客户端ID,此属性将无法由后续EXCHANGE_ID请求更新。

o For SP4_MACH_CRED or SP4_SSV state protection:

o 对于SP4马赫数CRED或SP4 SSV状态保护:

* The list of operations (spo_must_enforce) that MUST use the specified state protection. This list comes from the results of EXCHANGE_ID.

* 必须使用指定状态保护的操作列表(spo_必须_强制)。此列表来自EXCHANGE\u ID的结果。

* The list of operations (spo_must_allow) that MAY use the specified state protection. This list comes from the results of EXCHANGE_ID.

* 可能使用指定状态保护的操作列表(spo_必须_允许)。此列表来自EXCHANGE\u ID的结果。

Once the client ID is confirmed, these properties cannot be updated by subsequent EXCHANGE_ID requests.

确认客户端ID后,后续EXCHANGE\u ID请求将无法更新这些属性。

o For SP4_SSV protection:

o 对于SP4_SSV保护:

* The OID of the hash algorithm. This property is represented by one of the algorithms in the ssp_hash_algs field of the EXCHANGE_ID arguments. Once the client ID is confirmed, this property cannot be updated by subsequent EXCHANGE_ID requests.

* 哈希算法的OID。此属性由EXCHANGE_ID参数的ssp_hash_algs字段中的算法之一表示。确认客户端ID后,后续EXCHANGE\u ID请求将无法更新此属性。

* The OID of the encryption algorithm. This property is represented by one of the algorithms in the ssp_encr_algs field of the EXCHANGE_ID arguments. Once the client ID is confirmed, this property cannot be updated by subsequent EXCHANGE_ID requests.

* 加密算法的OID。此属性由EXCHANGE ID参数的ssp_encr_algs字段中的算法之一表示。确认客户端ID后,后续EXCHANGE\u ID请求将无法更新此属性。

* The length of the SSV. This property is represented by the spi_ssv_len field in the EXCHANGE_ID results. Once the client ID is confirmed, this property cannot be updated by subsequent EXCHANGE_ID requests.

* SSV的长度。此属性由交换ID结果中的spi_ssv_len字段表示。确认客户端ID后,后续EXCHANGE\u ID请求将无法更新此属性。

There are REQUIRED and RECOMMENDED relationships among the length of the key of the encryption algorithm ("key length"), the length of the output of hash algorithm ("hash length"), and the length of the SSV ("SSV length").

加密算法密钥的长度(“密钥长度”)、哈希算法输出的长度(“哈希长度”)和SSV的长度(“SSV长度”)之间存在必需的和推荐的关系。

+ key length MUST be <= hash length. This is because the keys used for the encryption algorithm are actually subkeys derived from the SSV, and the derivation is via the hash algorithm. The selection of an encryption algorithm with a key length that exceeded the length of the output of the hash algorithm would require padding, and thus weaken the use of the encryption algorithm.

+ 密钥长度必须小于等于哈希长度。这是因为用于加密算法的密钥实际上是从SSV派生的子密钥,并且派生是通过哈希算法进行的。选择密钥长度超过哈希算法输出长度的加密算法将需要填充,从而削弱加密算法的使用。

+ hash length SHOULD be <= SSV length. This is because the SSV is a key used to derive subkeys via an HMAC, and it is recommended that the key used as input to an HMAC be at least as long as the length of the HMAC's hash algorithm's output (see Section 3 of RFC2104 [11]).

+ 哈希长度应小于等于SSV长度。这是因为SSV是用于通过HMAC派生子密钥的密钥,建议用作HMAC输入的密钥至少与HMAC哈希算法输出的长度相同(参见RFC2104[11]第3节)。

+ key length SHOULD be <= SSV length. This is a transitive result of the above two invariants.

+ 密钥长度应小于等于SSV长度。这是上述两个不变量的传递结果。

+ key length SHOULD be >= hash length / 2. This is because the subkey derivation is via an HMAC and it is recommended that if the HMAC has to be truncated, it should not be truncated to less than half the hash length (see Section 4 of RFC2104 [11]).

+ 密钥长度应>=哈希长度/2。这是因为子密钥派生是通过HMAC进行的,建议如果必须截断HMAC,则不应将其截断到哈希长度的一半以下(参见RFC2104[11]第4节)。

* Number of concurrent versions of the SSV the client and server will support (Section 2.10.9). This property is represented by spi_window in the EXCHANGE_ID results. The property may be updated by subsequent EXCHANGE_ID requests.

* 客户端和服务器将支持的SSV并发版本数(第2.10.9节)。此属性由EXCHANGE\u ID结果中的spi\u窗口表示。该属性可能会通过后续的EXCHANGE\u ID请求进行更新。

o The client's implementation ID as represented by the eia_client_impl_id field of the arguments. The property may be updated by subsequent EXCHANGE_ID requests.

o 客户端的实现ID,由参数的eia_client_impl_ID字段表示。该属性可能会通过后续的EXCHANGE\u ID请求进行更新。

o The server's implementation ID as represented by the eir_server_impl_id field of the reply. The property may be updated by replies to subsequent EXCHANGE_ID requests.

o 由回复的eir_server_impl_ID字段表示的服务器的实现ID。可通过对后续EXCHANGE\u ID请求的答复来更新该属性。

The eia_flags passed as part of the arguments and the eir_flags results allow the client and server to inform each other of their capabilities as well as indicate how the client ID will be used. Whether a bit is set or cleared on the arguments' flags does not force the server to set or clear the same bit on the results' side. Bits not defined above cannot be set in the eia_flags field. If they are, the server MUST reject the operation with NFS4ERR_INVAL.

作为参数的一部分传递的eia_标志和eir_标志结果允许客户端和服务器相互通知其功能,并指示如何使用客户端ID。在参数标志上设置或清除位不会强制服务器在结果端设置或清除相同的位。上面未定义的位不能在eia_标志字段中设置。如果是,服务器必须使用NFS4ERR_INVAL拒绝该操作。

The EXCHGID4_FLAG_UPD_CONFIRMED_REC_A bit can only be set in eia_flags; it is always off in eir_flags. The EXCHGID4_FLAG_CONFIRMED_R bit can only be set in eir_flags; it is always off in eia_flags. If the server recognizes the co_ownerid and

EXCHGID4_标志\u UPD_确认\u REC_位只能在eia_标志中设置;它总是挂在国旗上。EXCHGID4_标志_确认_R位只能在eir_标志中设置;它总是在eia_旗下关闭。如果服务器识别出共同所有者ID,并且

co_verifier as mapping to a confirmed client ID, it sets EXCHGID4_FLAG_CONFIRMED_R in eir_flags. The EXCHGID4_FLAG_CONFIRMED_R flag allows a client to tell if the client ID it is trying to create already exists and is confirmed.

协同验证器作为到已确认客户端ID的映射,它在eir_标志中设置EXCHGID4_标志\u已确认\R。EXCHGID4\u标志\u确认\R标志允许客户机告知其尝试创建的客户机ID是否已存在并已确认。

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set in eia_flags, this means that the client is attempting to update properties of an existing confirmed client ID (if the client wants to update properties of an unconfirmed client ID, it MUST NOT set EXCHGID4_FLAG_UPD_CONFIRMED_REC_A). If so, it is RECOMMENDED that the client send the update EXCHANGE_ID operation in the same COMPOUND as a SEQUENCE so that the EXCHANGE_ID is executed exactly once. Whether the client can update the properties of client ID depends on the state protection it selected when the client ID was created, and the principal and security flavor it uses when sending the EXCHANGE_ID request. The situations described in items 6, 7, 8, or 9 of the second numbered list of Section 18.35.4 will apply. Note that if the operation succeeds and returns a client ID that is already confirmed, the server MUST set the EXCHGID4_FLAG_CONFIRMED_R bit in eir_flags.

如果在eia_标志中设置了EXCHGID4_标志_UPD_确认_REC_A,这意味着客户端正在尝试更新现有确认客户端ID的属性(如果客户端希望更新未确认客户端ID的属性,则不得设置EXCHGID4_标志_UPD_确认_REC_A)。如果是这样的话,建议客户端以与序列相同的组合发送更新EXCHANGE\u ID操作,以便EXCHANGE\u ID只执行一次。客户端是否可以更新客户端ID的属性取决于它在创建客户端ID时选择的状态保护,以及它在发送EXCHANGE_ID请求时使用的主体和安全风格。第18.35.4节第二个编号清单第6、7、8或9项所述情况适用。请注意,如果操作成功并返回已确认的客户端ID,则服务器必须在eir_标志中设置EXCHGID4_标志_确认_位。

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set in eia_flags, this means that the client is trying to establish a new client ID; it is attempting to trunk data communication to the server (Section 2.10.5); or it is attempting to update properties of an unconfirmed client ID. The situations described in items 1, 2, 3, 4, or 5 of the second numbered list of Section 18.35.4 will apply. Note that if the operation succeeds and returns a client ID that was previously confirmed, the server MUST set the EXCHGID4_FLAG_CONFIRMED_R bit in eir_flags.

如果eia_标志中未设置EXCHGID4_标志_UPD_确认_REC_A,则表示客户正在尝试建立新的客户ID;它试图将数据通信中继到服务器(第2.10.5节);或者试图更新未经确认的客户ID的属性。第18.35.4节第二编号列表第1、2、3、4或5项中描述的情况将适用。请注意,如果操作成功并返回先前确认的客户端ID,则服务器必须在eir_标志中设置EXCHGID4_标志_确认_位。

When the EXCHGID4_FLAG_SUPP_MOVED_REFER flag bit is set, the client indicates that it is capable of dealing with an NFS4ERR_MOVED error as part of a referral sequence. When this bit is not set, it is still legal for the server to perform a referral sequence. However, a server may use the fact that the client is incapable of correctly responding to a referral, by avoiding it for that particular client. It may, for instance, act as a proxy for that particular file system, at some cost in performance, although it is not obligated to do so. If the server will potentially perform a referral, it MUST set EXCHGID4_FLAG_SUPP_MOVED_REFER in eir_flags.

当设置EXCHGID4_标志_支持_移动_参考标志位时,客户端指示它能够作为参考序列的一部分处理NFS4ERR_移动错误。未设置此位时,服务器执行引用序列仍然是合法的。然而,服务器可能会利用客户机无法正确响应引用的事实,通过避免该特定客户机的引用。例如,它可以作为该特定文件系统的代理,但在性能上要付出一定的代价,尽管它没有义务这样做。如果服务器可能会执行引用,则必须在eir\U标志中设置EXCHGID4\u标志\u支持\u移动\u引用。

When the EXCHGID4_FLAG_SUPP_MOVED_MIGR is set, the client indicates that it is capable of dealing with an NFS4ERR_MOVED error as part of a file system migration sequence. When this bit is not set, it is still legal for the server to indicate that a file system has moved, when this in fact happens. However, a server may use the fact that the client is incapable of correctly responding to a migration in its

当设置EXCHGID4_标志_SUPP_MOVED_MIGR时,客户端指示它能够处理文件系统迁移序列中的NFS4ERR_MOVED错误。如果未设置此位,则服务器仍可以合法地指示文件系统已移动,而实际上发生了这种情况。但是,服务器可能会利用这样一个事实,即客户端无法正确响应其服务器中的迁移

scheduling of file systems to migrate so as to avoid migration of file systems being actively used. It may also hide actual migrations from clients unable to deal with them by acting as a proxy for a migrated file system for particular clients, at some cost in performance, although it is not obligated to do so. If the server will potentially perform a migration, it MUST set EXCHGID4_FLAG_SUPP_MOVED_MIGR in eir_flags.

安排要迁移的文件系统,以避免迁移正在使用的文件系统。它还可以通过充当特定客户机的已迁移文件系统的代理来隐藏无法处理的客户机的实际迁移,但在性能上要付出一定的代价,尽管它没有义务这样做。如果服务器可能会执行迁移,则必须在eir_标志中设置EXCHGID4_标志_支持_移动_标志。

When EXCHGID4_FLAG_BIND_PRINC_STATEID is set, the client indicates that it wants the server to bind the stateid to the principal. This means that when a principal creates a stateid, it has to be the one to use the stateid. If the server will perform binding, it will return EXCHGID4_FLAG_BIND_PRINC_STATEID. The server MAY return EXCHGID4_FLAG_BIND_PRINC_STATEID even if the client does not request it. If an update to the client ID changes the value of EXCHGID4_FLAG_BIND_PRINC_STATEID's client ID property, the effect applies only to new stateids. Existing stateids (and all stateids with the same "other" field) that were created with stateid to principal binding in force will continue to have binding in force. Existing stateids (and all stateids with the same "other" field) that were created with stateid to principal not in force will continue to have binding not in force.

When EXCHGID4_FLAG_BIND_PRINC_STATEID is set, the client indicates that it wants the server to bind the stateid to the principal. This means that when a principal creates a stateid, it has to be the one to use the stateid. If the server will perform binding, it will return EXCHGID4_FLAG_BIND_PRINC_STATEID. The server MAY return EXCHGID4_FLAG_BIND_PRINC_STATEID even if the client does not request it. If an update to the client ID changes the value of EXCHGID4_FLAG_BIND_PRINC_STATEID's client ID property, the effect applies only to new stateids. Existing stateids (and all stateids with the same "other" field) that were created with stateid to principal binding in force will continue to have binding in force. Existing stateids (and all stateids with the same "other" field) that were created with stateid to principal not in force will continue to have binding not in force.translate error, please retry

The EXCHGID4_FLAG_USE_NON_PNFS, EXCHGID4_FLAG_USE_PNFS_MDS, and EXCHGID4_FLAG_USE_PNFS_DS bits are described in Section 13.1 and convey roles the client ID is to be used for in a pNFS environment. The server MUST set one of the acceptable combinations of these bits (roles) in eir_flags, as specified in Section 13.1. Note that the same client owner/server owner pair can have multiple roles. Multiple roles can be associated with the same client ID or with different client IDs. Thus, if a client sends EXCHANGE_ID from the same client owner to the same server owner multiple times, but specifies different pNFS roles each time, the server might return different client IDs. Given that different pNFS roles might have different client IDs, the client may ask for different properties for each role/client ID.

EXCHGID4_标志_使用_非_PNFS、EXCHGID4_标志_使用_PNFS_MDS和EXCHGID4_标志_使用_PNFS_DS位在第13.1节中描述,并传达客户端ID在PNFS环境中要用于的角色。按照第13.1节的规定,服务器必须在eir_标志中设置这些位(角色)的可接受组合之一。请注意,同一客户机所有者/服务器所有者对可以有多个角色。多个角色可以与同一个客户端ID或不同的客户端ID相关联。因此,如果客户机多次从同一客户机所有者向同一服务器所有者发送EXCHANGE_ID,但每次指定不同的pNFS角色,则服务器可能返回不同的客户机ID。鉴于不同的pNFS角色可能具有不同的客户端ID,客户端可能会要求每个角色/客户端ID具有不同的属性。

The spa_how field of the eia_state_protect field specifies how the client wants to protect its client, locking, and session states from unauthorized changes (Section 2.10.8.3):

eia_state_protect字段的spa_how字段指定了客户希望如何保护其客户机、锁定和会话状态免受未经授权的更改(第2.10.8.3节):

o SP4_NONE. The client does not request the NFSv4.1 server to enforce state protection. The NFSv4.1 server MUST NOT enforce state protection for the returned client ID.

o 没有。客户端不请求NFSv4.1服务器实施状态保护。NFSv4.1服务器不得对返回的客户端ID实施状态保护。

o SP4_MACH_CRED. If spa_how is SP4_MACH_CRED, then the client MUST send the EXCHANGE_ID request with RPCSEC_GSS as the security flavor, and with a service of RPC_GSS_SVC_INTEGRITY or

o SP4马赫数。如果spa_how是SP4_MACH_CRED,则客户机必须发送交换ID请求,以RPCSEC_GSS作为安全标志,并使用RPC_GSS_SVC_INTEGRITY或

RPC_GSS_SVC_PRIVACY. If SP4_MACH_CRED is specified, then the client wants to use an RPCSEC_GSS-based machine credential to protect its state. The server MUST note the principal the EXCHANGE_ID operation was sent with, and the GSS mechanism used. These notes collectively comprise the machine credential.

RPC_GSS_SVC_隐私。如果指定了SP4_MACH_CRED,则客户端希望使用基于RPCSEC_GSS的机器凭据来保护其状态。服务器必须注意发送EXCHANGE_ID操作的主体以及使用的GSS机制。这些注释共同构成机器凭证。

After the client ID is confirmed, as long as the lease associated with the client ID is unexpired, a subsequent EXCHANGE_ID operation that uses the same eia_clientowner.co_owner as the first EXCHANGE_ID MUST also use the same machine credential as the first EXCHANGE_ID. The server returns the same client ID for the subsequent EXCHANGE_ID as that returned from the first EXCHANGE_ID.

确认客户ID后,只要与客户ID关联的租约未到期,使用与第一个EXCHANGE\u ID相同的eia\u clientowner.co\u所有者的后续EXCHANGE\u ID操作还必须使用与第一个EXCHANGE\u ID相同的计算机凭据。服务器为后续EXCHANGE\u ID返回与第一个EXCHANGE\u ID返回的客户端ID相同的客户端ID。

o SP4_SSV. If spa_how is SP4_SSV, then the client MUST send the EXCHANGE_ID request with RPCSEC_GSS as the security flavor, and with a service of RPC_GSS_SVC_INTEGRITY or RPC_GSS_SVC_PRIVACY. If SP4_SSV is specified, then the client wants to use the SSV to protect its state. The server records the credential used in the request as the machine credential (as defined above) for the eia_clientowner.co_owner. The CREATE_SESSION operation that confirms the client ID MUST use the same machine credential.

o SP4_SSV。如果spa_how是SP4_SSV,则客户端必须发送交换ID请求,将RPCSEC_GSS作为安全标志,并使用RPC_GSS_SVC_完整性或RPC_GSS_SVC_隐私服务。如果指定了SP4_SSV,则客户端希望使用SSV保护其状态。服务器将请求中使用的凭据记录为eia_clientowner.co_所有者的机器凭据(如上所述)。确认客户端ID的创建会话操作必须使用相同的计算机凭据。

When a client specifies SP4_MACH_CRED or SP4_SSV, it also provides two lists of operations (each expressed as a bitmap). The first list is spo_must_enforce and consists of those operations the client MUST send (subject to the server confirming the list of operations in the result of EXCHANGE_ID) with the machine credential (if SP4_MACH_CRED protection is specified) or the SSV-based credential (if SP4_SSV protection is used). The client MUST send the operations with RPCSEC_GSS credentials that specify the RPC_GSS_SVC_INTEGRITY or RPC_GSS_SVC_PRIVACY security service. Typically, the first list of operations includes EXCHANGE_ID, CREATE_SESSION, DELEGPURGE, DESTROY_SESSION, BIND_CONN_TO_SESSION, and DESTROY_CLIENTID. The client SHOULD NOT specify in this list any operations that require a filehandle because the server's access policies MAY conflict with the client's choice, and thus the client would then be unable to access a subset of the server's namespace.

当客户机指定SP4_MACH_CRED或SP4_SSV时,它还提供两个操作列表(每个操作都表示为位图)。第一个列表是spo_必须__强制执行,包括客户端必须使用机器凭据(如果指定了SP4_MACH_CRED protection)或基于SSV的凭据(如果使用SP4_SSV protection)发送的操作(取决于服务器确认交换ID结果中的操作列表)。客户端必须使用RPCSEC_GSS凭据发送操作,这些凭据指定RPC_GSS_SVC_完整性或RPC_GSS_SVC_隐私安全服务。通常,第一个操作列表包括交换\u ID、创建\u会话、删除敦促、销毁\u会话、将\u连接\u绑定到\u会话和销毁\u客户端ID。客户端不应在此列表中指定任何需要文件句柄的操作,因为服务器的访问策略可能与客户端的选择冲突,因此客户端将无法访问服务器命名空间的子集。

Note that if SP4_SSV protection is specified, and the client indicates that CREATE_SESSION must be protected with SP4_SSV, because the SSV cannot exist without a confirmed client ID, the first CREATE_SESSION MUST instead be sent using the machine credential, and the server MUST accept the machine credential.

请注意,如果指定了SP4_SSV保护,并且客户端指示必须使用SP4_SSV保护创建_会话,因为没有确认的客户端ID,SSV无法存在,因此必须使用机器凭据发送第一个创建_会话,服务器必须接受机器凭据。

There is a corresponding result, also called spo_must_enforce, of the operations for which the server will require SP4_MACH_CRED or SP4_SSV protection. Normally, the server's result equals the client's

对于服务器将需要SP4\u MACH\u CRED或SP4\u SSV保护的操作,有一个相应的结果,也称为spo\u必须执行。通常,服务器的结果等于客户端的结果

argument, but the result MAY be different. If the client requests one or more operations in the set { EXCHANGE_ID, CREATE_SESSION, DELEGPURGE, DESTROY_SESSION, BIND_CONN_TO_SESSION, DESTROY_CLIENTID }, then the result spo_must_enforce MUST include the operations the client requested from that set.

参数,但结果可能不同。如果客户端请求集合{EXCHANGE\u ID、CREATE\u SESSION、delegpush、DESTROY\u SESSION、BIND\u CONN\u TO\u SESSION、DESTROY\u CLIENTID}中的一个或多个操作,则结果spo\u must\u exforce必须包含客户端从该集合请求的操作。

If spo_must_enforce in the results has BIND_CONN_TO_SESSION set, then connection binding enforcement is enabled, and the client MUST use the machine (if SP4_MACH_CRED protection is used) or SSV (if SP4_SSV protection is used) credential on calls to BIND_CONN_TO_SESSION.

如果结果中的spo_必须_强制设置了BIND_CONN_TO_会话,则启用连接绑定强制,并且客户端必须在调用时使用机器(如果使用SP4_MACH_CRED保护)或SSV(如果使用SP4_SSV保护)凭据来绑定_CONN_TO_会话。

The second list is spo_must_allow and consists of those operations the client wants to have the option of sending with the machine credential or the SSV-based credential, even if the object the operations are performed on is not owned by the machine or SSV credential.

第二个列表是spo_必须_允许的,包括客户端希望使用机器凭据或基于SSV的凭据发送的操作,即使对其执行操作的对象不属于机器或SSV凭据。

The corresponding result, also called spo_must_allow, consists of the operations the server will allow the client to use SP4_SSV or SP4_MACH_CRED credentials with. Normally, the server's result equals the client's argument, but the result MAY be different.

相应的结果(也称为spo_must_allow)包含服务器将允许客户端使用SP4_SSV或SP4_MACH_CRED凭据的操作。通常,服务器的结果等于客户端的参数,但结果可能不同。

The purpose of spo_must_allow is to allow clients to solve the following conundrum. Suppose the client ID is confirmed with EXCHGID4_FLAG_BIND_PRINC_STATEID, and it calls OPEN with the RPCSEC_GSS credentials of a normal user. Now suppose the user's credentials expire, and cannot be renewed (e.g., a Kerberos ticket granting ticket expires, and the user has logged off and will not be acquiring a new ticket granting ticket). The client will be unable to send CLOSE without the user's credentials, which is to say the client has to either leave the state on the server or re-send EXCHANGE_ID with a new verifier to clear all state, that is, unless the client includes CLOSE on the list of operations in spo_must_allow and the server agrees.

spo必须允许的目的是让客户解决以下难题。假设客户端ID已通过EXCHGID4_FLAG_BIND_PRINC_STATEID确认,并使用普通用户的RPCSEC_GSS凭据调用OPEN。现在假设用户的凭据过期,并且无法续订(例如,Kerberos票证授予票证过期,并且用户已注销,并且将不会获取新的票证授予票证)。如果没有用户凭据,客户端将无法发送CLOSE,也就是说,客户端必须离开服务器上的状态,或者使用新的验证器重新发送EXCHANGE\u ID以清除所有状态,也就是说,除非客户端在spo\u必须允许的操作列表中包含CLOSE,并且服务器同意。

The SP4_SSV protection parameters also have:

SP4_SSV保护参数还具有:

ssp_hash_algs:

ssp_hash_algs:

This is the set of algorithms the client supports for the purpose of computing the digests needed for the internal SSV GSS mechanism and for the SET_SSV operation. Each algorithm is specified as an object identifier (OID). The REQUIRED algorithms for a server are id-sha1, id-sha224, id-sha256, id-sha384, and id-sha512 [28]. The algorithm the server selects among the set is indicated in spi_hash_alg, a field of spr_ssv_prot_info. The field spi_hash_alg is an index into the array ssp_hash_algs. If the

这是客户端支持的一组算法,用于计算内部SSV GSS机制和set_SSV操作所需的摘要。每个算法都指定为对象标识符(OID)。服务器所需的算法是id-sha1、id-sha224、id-sha256、id-sha384和id-sha512[28]。服务器在集合中选择的算法在spi_hash_alg(spr_ssv_prot_info)字段中指示。字段spi_hash_alg是数组ssp_hash_algs的索引。如果

server does not support any of the offered algorithms, it returns NFS4ERR_HASH_ALG_UNSUPP. If ssp_hash_algs is empty, the server MUST return NFS4ERR_INVAL.

服务器不支持任何提供的算法,它返回NFS4ERR_HASH_ALG_unapp。如果ssp_hash_algs为空,服务器必须返回NFS4ERR_INVAL。

ssp_encr_algs:

ssp_encr_algs:

This is the set of algorithms the client supports for the purpose of providing privacy protection for the internal SSV GSS mechanism. Each algorithm is specified as an OID. The REQUIRED algorithm for a server is id-aes256-CBC. The RECOMMENDED algorithms are id-aes192-CBC and id-aes128-CBC [29]. The selected algorithm is returned in spi_encr_alg, an index into ssp_encr_algs. If the server does not support any of the offered algorithms, it returns NFS4ERR_ENCR_ALG_UNSUPP. If ssp_encr_algs is empty, the server MUST return NFS4ERR_INVAL. Note that due to previously stated requirements and recommendations on the relationships between key length and hash length, some combinations of RECOMMENDED and REQUIRED encryption algorithm and hash algorithm either SHOULD NOT or MUST NOT be used. Table 12 summarizes the illegal and discouraged combinations.

这是客户端支持的一组算法,用于为内部SSV GSS机制提供隐私保护。每个算法都指定为OID。服务器所需的算法是id-aes256-CBC。推荐的算法为id-aes192-CBC和id-aes128-CBC[29]。选择的算法以spi_encr_alg返回,这是ssp_encr_alg的索引。如果服务器不支持任何提供的算法,它将返回NFS4ERR_ENCR_ALG_unapp。如果ssp_encr_algs为空,服务器必须返回NFS4ERR_INVAL。请注意,由于之前对密钥长度和哈希长度之间的关系提出了要求和建议,因此不应或不得使用建议和要求的加密算法和哈希算法的某些组合。表12总结了非法和不鼓励的组合。

ssp_window:

ssp_窗口:

This is the number of SSV versions the client wants the server to maintain (i.e., each successful call to SET_SSV produces a new version of the SSV). If ssp_window is zero, the server MUST return NFS4ERR_INVAL. The server responds with spi_window, which MUST NOT exceed ssp_window, and MUST be at least one. Any requests on the backchannel or fore channel that are using a version of the SSV that is outside the window will fail with an ONC RPC authentication error, and the requester will have to retry them with the same slot ID and sequence ID.

这是客户端希望服务器维护的SSV版本数(即,每次成功调用SET_SSV都会生成一个新版本的SSV)。如果ssp_窗口为零,服务器必须返回NFS4ERR_INVAL。服务器使用spi_窗口响应,该窗口不得超过ssp_窗口,并且必须至少为一个。后通道或前通道上使用窗口外SSV版本的任何请求都将失败,并出现ONC RPC身份验证错误,请求者必须使用相同的插槽ID和序列ID重试这些请求。

ssp_num_gss_handles:

ssp_num_gss_句柄:

This is the number of RPCSEC_GSS handles the server should create that are based on the GSS SSV mechanism (Section 2.10.9). It is not the total number of RPCSEC_GSS handles for the client ID. Indeed, subsequent calls to EXCHANGE_ID will add RPCSEC_GSS handles. The server responds with a list of handles in spi_handles. If the client asks for at least one handle and the server cannot create it, the server MUST return an error. The handles in spi_handles are not available for use until the client ID is confirmed, which could be immediately if EXCHANGE_ID returns EXCHGID4_FLAG_CONFIRMED_R, or upon successful confirmation from CREATE_SESSION.

这是服务器应基于GSS SSV机制创建的RPCSEC_GSS句柄数(第2.10.9节)。它不是客户端ID的RPCSEC_GSS句柄总数。实际上,对EXCHANGE_ID的后续调用将添加RPCSEC_GSS句柄。服务器用spi_句柄中的句柄列表进行响应。如果客户端要求至少一个句柄,而服务器无法创建它,则服务器必须返回一个错误。在确认客户端ID之前,spi_句柄中的句柄不可用。如果EXCHANGE_ID返回EXCHGID4_FLAG_confirmed_R,或者从CREATE_会话成功确认,则可以立即确认客户端ID。

While a client ID can span all the connections that are connected to a server sharing the same eir_server_owner.so_major_id, the RPCSEC_GSS handles returned in spi_handles can only be used on connections connected to a server that returns the same the eir_server_owner.so_major_id and eir_server_owner.so_minor_id on each connection. It is permissible for the client to set ssp_num_gss_handles to zero; the client can create more handles with another EXCHANGE_ID call.

虽然客户端ID可以跨越连接到共享同一eir_server_owner.so_major_ID的服务器的所有连接,但spi_handles中返回的RPCSEC_GSS句柄只能用于连接到返回相同eir_server_owner.so_major_ID和eir_server_owner.so_minor_ID的服务器的连接。允许客户端将ssp_num_gss_句柄设置为零;客户端可以通过另一个EXCHANGE\u ID调用创建更多句柄。

Because each SSV RPCSEC_GSS handle shares a common SSV GSS context, there are security considerations specific to this situation discussed in Section 2.10.10.

由于每个SSV RPCSEC_GSS句柄共享一个通用的SSV GSS上下文,因此在第2.10.10节中讨论了特定于这种情况的安全注意事项。

The seq_window (see Section 5.2.3.1 of RFC2203 [4]) of each RPCSEC_GSS handle in spi_handle MUST be the same as the seq_window of the RPCSEC_GSS handle used for the credential of the RPC request that the EXCHANGE_ID request was sent with.

spi_句柄中每个RPCSEC_GSS句柄的seq_窗口(见RFC2203[4]第5.2.3.1节)必须与发送交换ID请求的RPC请求凭证所用的RPCSEC_GSS句柄的seq_窗口相同。

   +-------------------+----------------------+------------------------+
   | Encryption        | MUST NOT be combined | SHOULD NOT be combined |
   | Algorithm         | with                 | with                   |
   +-------------------+----------------------+------------------------+
   | id-aes128-CBC     |                      | id-sha384, id-sha512   |
   | id-aes192-CBC     | id-sha1              | id-sha512              |
   | id-aes256-CBC     | id-sha1, id-sha224   |                        |
   +-------------------+----------------------+------------------------+
        
   +-------------------+----------------------+------------------------+
   | Encryption        | MUST NOT be combined | SHOULD NOT be combined |
   | Algorithm         | with                 | with                   |
   +-------------------+----------------------+------------------------+
   | id-aes128-CBC     |                      | id-sha384, id-sha512   |
   | id-aes192-CBC     | id-sha1              | id-sha512              |
   | id-aes256-CBC     | id-sha1, id-sha224   |                        |
   +-------------------+----------------------+------------------------+
        

Table 12

表12

The arguments include an array of up to one element in length called eia_client_impl_id. If eia_client_impl_id is present, it contains the information identifying the implementation of the client. Similarly, the results include an array of up to one element in length called eir_server_impl_id that identifies the implementation of the server. Servers MUST accept a zero-length eia_client_impl_id array, and clients MUST accept a zero-length eir_server_impl_id array.

参数包括一个长度最多为一个元素的数组,称为eia_client_impl_id。如果存在eia_client_impl_id,则它包含标识客户端实现的信息。类似地,结果包括一个长度最多为一个元素的数组,称为eir_server_impl_id,用于标识服务器的实现。服务器必须接受零长度eia\U客户端\U impl\u id数组,客户端必须接受零长度eir\U服务器\U impl\u id数组。

An example use for implementation identifiers would be diagnostic software that extracts this information in an attempt to identify interoperability problems, performance workload behaviors, or general usage statistics. Since the intent of having access to this information is for planning or general diagnosis only, the client and server MUST NOT interpret this implementation identity information in a way that affects interoperational behavior of the implementation. The reason is that if clients and servers did such a thing, they might use fewer capabilities of the protocol than the peer can support, or the client and server might refuse to interoperate.

实现标识符的一个示例是诊断软件,它提取这些信息,试图识别互操作性问题、性能工作负载行为或一般使用统计信息。由于访问此信息的目的仅用于规划或一般诊断,因此客户端和服务器不得以影响实现互操作行为的方式解释此实现标识信息。原因是,如果客户端和服务器做了这样的事情,它们可能会使用比对等方所能支持的更少的协议功能,或者客户端和服务器可能会拒绝互操作。

Because it is possible that some implementations will violate the protocol specification and interpret the identity information, implementations MUST allow the users of the NFSv4 client and server to set the contents of the sent nfs_impl_id structure to any value.

由于某些实现可能会违反协议规范并解释身份信息,因此实现必须允许NFSv4客户端和服务器的用户将发送的nfs_impl_id结构的内容设置为任何值。

18.35.4. IMPLEMENTATION
18.35.4. 实施

A server's client record is a 5-tuple:

服务器的客户端记录是一个5元组:

1. co_ownerid

1. 共有人

The client identifier string, from the eia_clientowner structure of the EXCHANGE_ID4args structure.

来自EXCHANGE_ID4args结构的eia_clientowner结构的客户端标识符字符串。

2. co_verifier:

2. 联合核查员:

A client-specific value used to indicate incarnations (where a client restart represents a new incarnation), from the eia_clientowner structure of the EXCHANGE_ID4args structure.

一个特定于客户端的值,用于指示EXCHANGE_ID4args结构的eia_clientowner结构中的具体化(其中客户端重新启动表示新的具体化)。

3. principal:

3. 负责人:

The principal that was defined in the RPC header's credential and/or verifier at the time the client record was established.

在建立客户端记录时在RPC标头的凭据和/或验证器中定义的主体。

4. client ID:

4. 客户端ID:

The shorthand client identifier, generated by the server and returned via the eir_clientid field in the EXCHANGE_ID4resok structure.

由服务器生成并通过EXCHANGE_ID4resok结构中的eir_clientid字段返回的速记客户端标识符。

5. confirmed:

5. 确认:

A private field on the server indicating whether or not a client record has been confirmed. A client record is confirmed if there has been a successful CREATE_SESSION operation to confirm it. Otherwise, it is unconfirmed. An unconfirmed record is established by an EXCHANGE_ID call. Any unconfirmed record that is not confirmed within a lease period SHOULD be removed.

服务器上的专用字段,指示是否已确认客户端记录。如果已成功执行创建会话操作以确认客户端记录,则会确认客户端记录。否则,这是未确认的。通过交换ID调用建立未确认的记录。任何未在租赁期内确认的未确认记录都应删除。

The following identifiers represent special values for the fields in the records.

以下标识符表示记录中字段的特殊值。

ownerid_arg:

所有者ID_参数:

The value of the eia_clientowner.co_ownerid subfield of the EXCHANGE_ID4args structure of the current request.

当前请求的EXCHANGE ID4args结构的eia_clientowner.co_ownerid子字段的值。

verifier_arg:

验证器参数:

The value of the eia_clientowner.co_verifier subfield of the EXCHANGE_ID4args structure of the current request.

当前请求的EXCHANGE ID4args结构的eia_clientowner.co_verifier子字段的值。

old_verifier_arg:

旧验证程序参数:

A value of the eia_clientowner.co_verifier field of a client record received in a previous request; this is distinct from verifier_arg.

在先前请求中收到的客户记录的eia_clientowner.co_verifier字段的值;这与验证器参数不同。

principal_arg:

主要参数:

The value of the RPCSEC_GSS principal for the current request.

当前请求的RPCSEC_GSS主体的值。

old_principal_arg:

旧主参数:

A value of the principal of a client record as defined by the RPC header's credential or verifier of a previous request. This is distinct from principal_arg.

客户端记录主体的值,由RPC头的凭据或前一个请求的验证器定义。这与主体参数不同。

clientid_ret:

客户信息:

The value of the eir_clientid field the server will return in the EXCHANGE_ID4resok structure for the current request.

服务器将在EXCHANGE\u ID4resok结构中为当前请求返回的eir\u clientid字段的值。

old_clientid_ret:

老客户检索:

The value of the eir_clientid field the server returned in the EXCHANGE_ID4resok structure for a previous request. This is distinct from clientid_ret.

服务器在EXCHANGE\u ID4resok结构中为上一个请求返回的eir\u clientid字段的值。这与clientid_ret不同。

confirmed:

确认:

The client ID has been confirmed.

客户端ID已确认。

unconfirmed:

未确认:

The client ID has not been confirmed.

客户端ID尚未确认。

Since EXCHANGE_ID is a non-idempotent operation, we must consider the possibility that retries occur as a result of a client restart, network partition, malfunctioning router, etc. Retries are identified by the value of the eia_clientowner field of EXCHANGE_ID4args, and the method for dealing with them is outlined in the scenarios below.

由于Exchange EID是非幂等操作,所以我们必须考虑重试发生的可能性,因为客户端重新启动、网络分区、故障路由器等。重试由Exchange EID4ARGS的EIAYclient所有者字段的值来标识,并且在下面的场景中概述了处理它们的方法。

The scenarios are described in terms of the client record(s) a server has for a given co_ownerid. Note that if the client ID was created specifying SP4_SSV state protection and EXCHANGE_ID as the one of the operations in spo_must_allow, then the server MUST authorize EXCHANGE_IDs with the SSV principal in addition to the principal that created the client ID.

这些场景是根据服务器对给定所有者ID的客户端记录来描述的。请注意,如果创建的客户端ID将SP4_SSV状态保护和EXCHANGE_ID指定为spo_必须允许的操作之一,则服务器必须使用SSV主体以及创建客户端ID的主体来授权EXCHANGE_ID。

1. New Owner ID

1. 新所有者ID

If the server has no client records with eia_clientowner.co_ownerid matching ownerid_arg, and EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set in the EXCHANGE_ID, then a new shorthand client ID (let us call it clientid_ret) is generated, and the following unconfirmed record is added to the server's state.

如果服务器没有eia_clientowner.co_ownerid与ownerid_参数匹配的客户端记录,并且EXCHANGE_ID中未设置EXCHGID4_标志_UPD_确认_REC_A,则会生成一个新的速记客户端ID(我们称之为clientid_ret),并将以下未确认的记录添加到服务器的状态。

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, unconfirmed }

{所有者ID_-arg、验证者_-arg、委托人_-arg、客户ID_-ret、未确认}

Subsequently, the server returns clientid_ret.

随后,服务器返回clientid_ret。

2. Non-Update on Existing Client ID

2. 未更新现有客户端ID

If the server has the following confirmed record, and the request does not have EXCHGID4_FLAG_UPD_CONFIRMED_REC_A set, then the request is the result of a retried request due to a faulty router or lost connection, or the client is trying to determine if it can perform trunking.

如果服务器具有以下已确认记录,并且请求没有EXCHGID4_FLAG_UPD_confirm_REC_A set,则该请求是由于路由器故障或连接丢失而重试请求的结果,或者客户端正在尝试确定是否可以执行中继。

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, confirmed }

{ownerid_arg,验证者_arg,委托人_arg,客户ID_ret,已确认}

Since the record has been confirmed, the client must have received the server's reply from the initial EXCHANGE_ID request. Since the server has a confirmed record, and since EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, with the possible exception of eir_server_owner.so_minor_id, the server returns the same result it did when the client ID's properties were last updated (or if never updated, the result when the client ID was created). The confirmed record is unchanged.

由于记录已被确认,客户端必须已从初始EXCHANGE_ID请求收到服务器的答复。由于服务器具有已确认的记录,并且未设置EXCHGID4_FLAG_UPD_confirmed_REC_a,除了eir_server_owner.so_minor_id之外,服务器返回与上次更新客户端id属性时相同的结果(如果从未更新,则返回创建客户端id时的结果)。确认记录不变。

3. Client Collision

3. 客户端冲突

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, and if the server has the following confirmed record, then this request is likely the result of a chance collision between the values of the eia_clientowner.co_ownerid subfield of EXCHANGE_ID4args for two different clients.

如果未设置EXCHGID4_FLAG_UPD_confirm_REC_A,并且如果服务器具有以下已确认记录,则此请求可能是由于两个不同客户端的EXCHANGE_id4; args的eia_clientowner.co_ownerid子字段的值之间的偶然冲突造成的。

{ ownerid_arg, *, old_principal_arg, old_clientid_ret, confirmed }

{ownerid_arg,*,old_principal_arg,old_clientid_ret,已确认}

If there is currently no state associated with old_clientid_ret, or if there is state but the lease has expired, then this case is effectively equivalent to the New Owner ID case of Paragraph 1. The confirmed record is deleted, the old_clientid_ret and its lock state are deleted, a new shorthand client ID is generated, and the following unconfirmed record is added to the server's state.

如果当前没有与旧客户ID ret关联的状态,或者如果存在状态但租约已到期,则该情况实际上等同于第1款的新所有者ID情况。已确认的记录将被删除,旧的\u clientid_ret及其锁定状态将被删除,新的速记客户端ID将生成,以下未确认的记录将添加到服务器的状态。

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, unconfirmed }

{所有者ID_-arg、验证者_-arg、委托人_-arg、客户ID_-ret、未确认}

Subsequently, the server returns clientid_ret.

随后,服务器返回clientid_ret。

If old_clientid_ret has an unexpired lease with state, then no state of old_clientid_ret is changed or deleted. The server returns NFS4ERR_CLID_INUSE to indicate that the client should retry with a different value for the eia_clientowner.co_ownerid subfield of EXCHANGE_ID4args. The client record is not changed.

如果old_clientid_ret具有状态为的未到期租约,则不会更改或删除old_clientid_ret的状态。服务器返回NFS4ERR_CLID_INUSE以指示客户端应使用EXCHANGE_ID4args的eia_clientowner.co_ownerid子字段的不同值重试。客户端记录未更改。

4. Replacement of Unconfirmed Record

4. 未确认记录的替换

If the EXCHGID4_FLAG_UPD_CONFIRMED_REC_A flag is not set, and the server has the following unconfirmed record, then the client is attempting EXCHANGE_ID again on an unconfirmed client ID, perhaps due to a retry, a client restart before client ID confirmation (i.e., before CREATE_SESSION was called), or some other reason.

如果未设置EXCHGID4_标志\u UPD_confirm_REC_A标志,并且服务器具有以下未确认的记录,则客户机正尝试再次在未确认的客户机ID上交换ID,可能是由于重试、在客户机ID确认之前重新启动客户机(即,在调用CREATE_会话之前)或其他原因。

          { ownerid_arg, *, *, old_clientid_ret, unconfirmed }
        
          { ownerid_arg, *, *, old_clientid_ret, unconfirmed }
        

It is possible that the properties of old_clientid_ret are different than those specified in the current EXCHANGE_ID. Whether or not the properties are being updated, to eliminate ambiguity, the server deletes the unconfirmed record, generates a new client ID (clientid_ret), and establishes the following unconfirmed record:

旧客户端ID_ret的属性可能与当前EXCHANGE ID中指定的属性不同。无论是否更新属性,为了消除歧义,服务器都会删除未确认的记录,生成新的客户端ID(客户端ID_ret),并建立以下未确认记录:

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, unconfirmed }

{所有者ID_-arg、验证者_-arg、委托人_-arg、客户ID_-ret、未确认}

5. Client Restart

5. 客户端重启

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is not set, and if the server has the following confirmed client record, then this request is likely from a previously confirmed client that has restarted.

如果未设置EXCHGID4_标志_UPD_confirm_REC_A,并且如果服务器具有以下已确认的客户端记录,则此请求可能来自先前已重新启动的已确认客户端。

{ ownerid_arg, old_verifier_arg, principal_arg, old_clientid_ret, confirmed }

{ownerid_arg,old_verifier_arg,principal_arg,old_clientid_ret,Confirmative}

Since the previous incarnation of the same client will no longer be making requests, once the new client ID is confirmed by CREATE_SESSION, byte-range locks and share reservations should be released immediately rather than forcing the new incarnation to wait for the lease time on the previous incarnation to expire. Furthermore, session state should be removed since if the client had maintained that information across restart, this request would not have been sent. If the server supports neither the CLAIM_DELEGATE_PREV nor CLAIM_DELEG_PREV_FH claim types, associated delegations should be purged as well; otherwise, delegations are retained and recovery proceeds according to Section 10.2.1.

由于同一客户机的前一个版本将不再发出请求,一旦CREATE_SESSION确认了新的客户机ID,字节范围锁和共享保留应立即释放,而不是强制新版本等待前一个版本的租赁时间到期。此外,应该删除会话状态,因为如果客户端在重启期间维护了该信息,则不会发送该请求。如果服务器既不支持CLAIM_DELEGATE_PREV,也不支持CLAIM_DELEG_PREV_FH CLAIM类型,则还应清除关联的委托;否则,根据第10.2.1节的规定保留委托和收回收益。

After processing, clientid_ret is returned to the client and this client record is added:

处理后,clientid_ret返回给客户端,并添加此客户端记录:

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, unconfirmed }

{所有者ID_-arg、验证者_-arg、委托人_-arg、客户ID_-ret、未确认}

The previously described confirmed record continues to exist, and thus the same ownerid_arg exists in both a confirmed and unconfirmed state at the same time. The number of states can collapse to one once the server receives an applicable CREATE_SESSION or EXCHANGE_ID.

前面描述的已确认记录继续存在,因此相同的所有者ID_arg同时以已确认和未确认状态存在。一旦服务器接收到适用的CREATE_会话或EXCHANGE_ID,状态数可以折叠为一。

+ If the server subsequently receives a successful CREATE_SESSION that confirms clientid_ret, then the server atomically destroys the confirmed record and makes the unconfirmed record confirmed as described in Section 18.36.4.

+ 如果服务器随后收到一个成功的CREATE_会话以确认客户端ID_ret,则服务器会自动销毁已确认的记录,并按照第18.36.4节中的说明确认未确认的记录。

+ If the server instead subsequently receives an EXCHANGE_ID with the client owner equal to ownerid_arg, one strategy is to simply delete the unconfirmed record, and process the EXCHANGE_ID as described in the entirety of Section 18.35.4.

+ 如果服务器随后接收到与客户端所有者相等的交换ID,则一种策略是删除未确认的记录,并按照第18.35.4节所述处理交换ID。

6. Update

6. 使现代化

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server has the following confirmed record, then this request is an attempt at an update.

如果设置了EXCHGID4_标志_UPD_confirm_REC_A,并且服务器具有以下确认记录,则此请求是一次更新尝试。

{ ownerid_arg, verifier_arg, principal_arg, clientid_ret, confirmed }

{ownerid_arg,验证者_arg,委托人_arg,客户ID_ret,已确认}

Since the record has been confirmed, the client must have received the server's reply from the initial EXCHANGE_ID request. The server allows the update, and the client record is left intact.

由于记录已被确认,客户端必须已从初始EXCHANGE_ID请求收到服务器的答复。服务器允许更新,客户端记录保持不变。

7. Update but No Confirmed Record

7. 更新但没有确认的记录

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server has no confirmed record corresponding ownerid_arg, then the server returns NFS4ERR_NOENT and leaves any unconfirmed record intact.

如果设置了EXCHGID4_标志_UPD_confirm_REC_A,并且服务器没有与ownerid_arg对应的已确认记录,则服务器返回NFS4ERR_NOENT并保留所有未确认记录。

8. Update but Wrong Verifier

8. 更新但验证错误

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server has the following confirmed record, then this request is an illegal attempt at an update, perhaps because of a retry from a previous client incarnation.

如果设置了EXCHGID4_标志_UPD_confirm_REC_A,并且服务器具有以下已确认记录,则此请求是一次非法更新尝试,可能是因为以前的客户端版本进行了重试。

          { ownerid_arg, old_verifier_arg, *, clientid_ret, confirmed }
        
          { ownerid_arg, old_verifier_arg, *, clientid_ret, confirmed }
        

The server returns NFS4ERR_NOT_SAME and leaves the client record intact.

服务器返回NFS4ERR_NOT_SAME并保持客户端记录不变。

9. Update but Wrong Principal

9. 更新但错误的原则

If EXCHGID4_FLAG_UPD_CONFIRMED_REC_A is set, and the server has the following confirmed record, then this request is an illegal attempt at an update by an unauthorized principal.

如果设置了EXCHGID4_FLAG_UPD_confirm_REC_A,并且服务器具有以下确认记录,则此请求是未经授权的主体非法尝试更新。

{ ownerid_arg, verifier_arg, old_principal_arg, clientid_ret, confirmed }

{ownerid_arg,验证者_arg,旧委托人_arg,客户ID_ret,已确认}

The server returns NFS4ERR_PERM and leaves the client record intact.

服务器返回NFS4ERR_PERM并保持客户端记录不变。

18.36. Operation 43: CREATE_SESSION - Create New Session and Confirm Client ID

18.36. 操作43:创建会话-创建新会话并确认客户端ID

18.36.1. ARGUMENT
18.36.1. 论点
   struct channel_attrs4 {
           count4                  ca_headerpadsize;
           count4                  ca_maxrequestsize;
           count4                  ca_maxresponsesize;
           count4                  ca_maxresponsesize_cached;
           count4                  ca_maxoperations;
           count4                  ca_maxrequests;
           uint32_t                ca_rdma_ird<1>;
   };
        
   struct channel_attrs4 {
           count4                  ca_headerpadsize;
           count4                  ca_maxrequestsize;
           count4                  ca_maxresponsesize;
           count4                  ca_maxresponsesize_cached;
           count4                  ca_maxoperations;
           count4                  ca_maxrequests;
           uint32_t                ca_rdma_ird<1>;
   };
        
   const CREATE_SESSION4_FLAG_PERSIST              = 0x00000001;
   const CREATE_SESSION4_FLAG_CONN_BACK_CHAN       = 0x00000002;
   const CREATE_SESSION4_FLAG_CONN_RDMA            = 0x00000004;
        
   const CREATE_SESSION4_FLAG_PERSIST              = 0x00000001;
   const CREATE_SESSION4_FLAG_CONN_BACK_CHAN       = 0x00000002;
   const CREATE_SESSION4_FLAG_CONN_RDMA            = 0x00000004;
        
   struct CREATE_SESSION4args {
           clientid4               csa_clientid;
           sequenceid4             csa_sequence;
        
   struct CREATE_SESSION4args {
           clientid4               csa_clientid;
           sequenceid4             csa_sequence;
        

uint32_t csa_flags;

uint32_t csa_标志;

           channel_attrs4          csa_fore_chan_attrs;
           channel_attrs4          csa_back_chan_attrs;
        
           channel_attrs4          csa_fore_chan_attrs;
           channel_attrs4          csa_back_chan_attrs;
        
           uint32_t                csa_cb_program;
           callback_sec_parms4     csa_sec_parms<>;
   };
        
           uint32_t                csa_cb_program;
           callback_sec_parms4     csa_sec_parms<>;
   };
        
18.36.2. RESULT
18.36.2. 后果
   struct CREATE_SESSION4resok {
           sessionid4              csr_sessionid;
           sequenceid4             csr_sequence;
        
   struct CREATE_SESSION4resok {
           sessionid4              csr_sessionid;
           sequenceid4             csr_sequence;
        

uint32_t csr_flags;

uint32_t csr_标志;

           channel_attrs4          csr_fore_chan_attrs;
           channel_attrs4          csr_back_chan_attrs;
   };
        
           channel_attrs4          csr_fore_chan_attrs;
           channel_attrs4          csr_back_chan_attrs;
   };
        
   union CREATE_SESSION4res switch (nfsstat4 csr_status) {
   case NFS4_OK:
           CREATE_SESSION4resok    csr_resok4;
   default:
           void;
   };
        
   union CREATE_SESSION4res switch (nfsstat4 csr_status) {
   case NFS4_OK:
           CREATE_SESSION4resok    csr_resok4;
   default:
           void;
   };
        
18.36.3. DESCRIPTION
18.36.3. 描述

This operation is used by the client to create new session objects on the server.

客户端使用此操作在服务器上创建新会话对象。

CREATE_SESSION can be sent with or without a preceding SEQUENCE operation in the same COMPOUND procedure. If CREATE_SESSION is sent with a preceding SEQUENCE operation, any session created by CREATE_SESSION has no direct relation to the session specified in the SEQUENCE operation, although the two sessions might be associated with the same client ID. If CREATE_SESSION is sent without a preceding SEQUENCE, then it MUST be the only operation in the COMPOUND procedure's request. If it is not, the server MUST return NFS4ERR_NOT_ONLY_OP.

在同一复合过程中,可以发送CREATE_会话,同时发送前一个序列操作,也可以不发送前一个序列操作。如果使用前面的序列操作发送CREATE_会话,则由CREATE_会话创建的任何会话都与序列操作中指定的会话没有直接关系,尽管这两个会话可能与相同的客户端ID关联。如果在没有前面的序列的情况下发送CREATE_会话,那么它必须是复合过程请求中的唯一操作。如果不是,服务器必须返回NFS4ERR\u not\u ONLY\u OP。

In addition to creating a session, CREATE_SESSION has the following effects:

除了创建会话外,创建会话还具有以下效果:

o The first session created with a new client ID serves to confirm the creation of that client's state on the server. The server returns the parameter values for the new session.

o 使用新客户端ID创建的第一个会话用于确认在服务器上创建该客户端的状态。服务器返回新会话的参数值。

o The connection CREATE_SESSION that is sent over is associated with the session's fore channel.

o 发送的连接创建会话与会话的前通道相关联。

The arguments and results of CREATE_SESSION are described as follows:

CREATE_会话的参数和结果描述如下:

csa_clientid:

csa_客户ID:

This is the client ID with which the new session will be associated. The corresponding result is csr_sessionid, the session ID of the new session.

这是新会话将与之关联的客户端ID。相应的结果是csr_sessionid,即新会话的会话ID。

csa_sequence:

csa_序列:

Each client ID serializes CREATE_SESSION via a per-client ID sequence number (see Section 18.36.4). The corresponding result is csr_sequence, which MUST be equal to csa_sequence.

每个客户端ID通过每个客户端ID序列号序列化创建会话(见第18.36.4节)。相应的结果是csr_序列,它必须等于csa_序列。

In the next three arguments, the client offers a value that is to be a property of the session. Except where stated otherwise, it is RECOMMENDED that the server accept the value. If it is not acceptable, the server MAY use a different value. Regardless, the server MUST return the value the session will use (which will be either what the client offered, or what the server is insisting on) to the client.

在接下来的三个参数中,客户机提供了一个作为会话属性的值。除非另有说明,否则建议服务器接受该值。如果不可接受,服务器可能会使用不同的值。无论如何,服务器必须将会话将使用的值(客户机提供的值或服务器坚持的值)返回给客户机。

csa_flags:

csa_标志:

The csa_flags field contains a list of the following flag bits:

csa_标志字段包含以下标志位的列表:

CREATE_SESSION4_FLAG_PERSIST:

创建会话4\u标志\u持久化:

If CREATE_SESSION4_FLAG_PERSIST is set, the client wants the server to provide a persistent reply cache. For sessions in which only idempotent operations will be used (e.g., a read-only session), clients SHOULD NOT set CREATE_SESSION4_FLAG_PERSIST. If the server does not or cannot provide a persistent reply cache, the server MUST NOT set CREATE_SESSION4_FLAG_PERSIST in the field csr_flags.

如果设置了CREATE_SESSION4_FLAG_PERSIST,则客户端希望服务器提供一个持久应答缓存。对于只使用幂等运算的会话(例如,只读会话),客户端不应设置CREATE_SESSION4_FLAG_PERSIST。如果服务器不提供或无法提供持久回复缓存,则服务器不得在csr\U标志字段中设置CREATE\U SESSION4\U FLAG\U PERSISTER。

If the server is a pNFS metadata server, for reasons described in Section 12.5.2 it SHOULD support CREATE_SESSION4_FLAG_PERSIST if it supports the layout_hint (Section 5.12.4) attribute.

如果服务器是pNFS元数据服务器,出于第12.5.2节所述原因,如果服务器支持布局提示(第5.12.4节)属性,则应支持创建会话4\u标志\u持久化。

CREATE_SESSION4_FLAG_CONN_BACK_CHAN:

创建会话4\u标志\u连接\u背面\u通道:

If CREATE_SESSION4_FLAG_CONN_BACK_CHAN is set in csa_flags, the client is requesting that the connection over which the CREATE_SESSION operation arrived be associated with the session's backchannel in addition to its fore channel. If the server agrees, it sets CREATE_SESSION4_FLAG_CONN_BACK_CHAN in the result field csr_flags. If CREATE_SESSION4_FLAG_CONN_BACK_CHAN is not set in csa_flags, then CREATE_SESSION4_FLAG_CONN_BACK_CHAN MUST NOT be set in csr_flags.

如果在csa_标志中设置了CREATE_SESSION4_FLAG_CONN_BACK_CHAN,则客户端将请求CREATE_会话操作到达的连接除了其前通道外,还与会话的后通道相关联。如果服务器同意,它会在结果字段csr_flags中设置CREATE_SESSION4_FLAG_CONN_BACK_CHAN。如果csa_标志中未设置CREATE_SESSION4_FLAG_CONN_BACK_CHAN,则csr_标志中不得设置CREATE_SESSION4_FLAG_CONN_BACK_CHAN。

CREATE_SESSION4_FLAG_CONN_RDMA:

创建会话4标志连接RDMA:

If CREATE_SESSION4_FLAG_CONN_RDMA is set in csa_flags, and if the connection over which the CREATE_SESSION operation arrived is currently in non-RDMA mode but has the capability to operate in RDMA mode, then the client is requesting that the server "step up" to RDMA mode on the connection. If the server agrees, it sets CREATE_SESSION4_FLAG_CONN_RDMA in the result field csr_flags. If CREATE_SESSION4_FLAG_CONN_RDMA is not set

如果在csa_标志中设置了CREATE_SESSION4_FLAG_CONN_RDMA,并且CREATE_会话操作到达的连接当前处于非RDMA模式,但能够在RDMA模式下运行,则客户端请求服务器在连接上“升级”到RDMA模式。如果服务器同意,它将在结果字段csr_标志中设置CREATE_SESSION4_标志_CONN_RDMA。如果未设置CREATE_SESSION4_FLAG_CONN_RDMA

in csa_flags, then CREATE_SESSION4_FLAG_CONN_RDMA MUST NOT be set in csr_flags. Note that once the server agrees to step up, it and the client MUST exchange all future traffic on the connection with RPC RDMA framing and not Record Marking ([8]).

在csa_标志中,则不能在csr_标志中设置CREATE_SESSION4_标志_CONN_RDMA。请注意,一旦服务器同意升级,它和客户端必须使用RPC RDMA帧交换连接上的所有未来流量,而不是记录标记([8])。

csa_fore_chan_attrs, csa_fore_chan_attrs:

csa\u fore\u chan\u attrs,csa\u fore\u chan\u attrs:

The csa_fore_chan_attrs and csa_back_chan_attrs fields apply to attributes of the fore channel (which conveys requests originating from the client to the server), and the backchannel (the channel that conveys callback requests originating from the server to the client), respectively. The results are in corresponding structures called csr_fore_chan_attrs and csr_back_chan_attrs. The results establish attributes for each channel, and on all subsequent use of each channel of the session. Each structure has the following fields:

csa_fore_chan_attrs和csa_back_chan_attrs字段分别应用于fore通道(将源自客户端的请求传送到服务器)和backchannel(将源自服务器的回调请求传送到客户端的通道)的属性。结果在相应的结构中称为csr_fore_chan_attrs和csr_back_chan_attrs。结果为每个通道以及会话的每个通道的所有后续使用建立属性。每个结构都有以下字段:

ca_headerpadsize:

ca_headerpadsize:

The maximum amount of padding the requester is willing to apply to ensure that write payloads are aligned on some boundary at the replier. For each channel, the server

请求者愿意应用的最大填充量,以确保写有效负载在应答器的某个边界上对齐。对于每个通道,服务器

+ will reply in ca_headerpadsize with its preferred value, or zero if padding is not in use, and

+ 将使用其首选值在ca_headerpadsize中回复,如果未使用填充,则为零,并且

+ MAY decrease this value but MUST NOT increase it.

+ 可能会降低该值,但不得增加该值。

ca_maxrequestsize:

ca_maxrequestsize:

The maximum size of a COMPOUND or CB_COMPOUND request that will be sent. This size represents the XDR encoded size of the request, including the RPC headers (including security flavor credentials and verifiers) but excludes any RPC transport framing headers. Imagine a request coming over a non-RDMA TCP/IP connection, and that it has a single Record Marking header preceding it. The maximum allowable count encoded in the header will be ca_maxrequestsize. If a requester sends a request that exceeds ca_maxrequestsize, the error NFS4ERR_REQ_TOO_BIG will be returned per the description in Section 2.10.6.4. For each channel, the server MAY decrease this value but MUST NOT increase it.

将发送的复合请求或CB_复合请求的最大大小。此大小表示请求的XDR编码大小,包括RPC头(包括安全风格凭据和验证器),但不包括任何RPC传输帧头。假设一个请求来自非RDMA TCP/IP连接,并且它前面有一个记录标记头。头中编码的最大允许计数将是ca_maxrequestsize。如果请求者发送的请求超过ca_maxrequestsize,将根据第2.10.6.4节中的说明返回错误NFS4ERR_REQ_TOO_BIG。对于每个通道,服务器都可以减小该值,但不能增加该值。

ca_maxresponsesize:

ca_maxresponsesize:

The maximum size of a COMPOUND or CB_COMPOUND reply that the requester will accept from the replier including RPC headers (see the ca_maxrequestsize definition). For each channel, the

请求者将从应答器(包括RPC头)接受的复合或CB_复合应答的最大大小(请参阅ca_maxrequestsize定义)。对于每个通道

server MAY decrease this value, but MUST NOT increase it. However, if the client selects a value for ca_maxresponsesize such that a replier on a channel could never send a response, the server SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply. After the session is created, if a requester sends a request for which the size of the reply would exceed this value, the replier will return NFS4ERR_REP_TOO_BIG, per the description in Section 2.10.6.4.

服务器可以减少此值,但不能增加它。但是,如果客户端为ca_maxresponsesize选择了一个值,使得通道上的应答器无法发送响应,则服务器应在创建会话应答中返回NFS4ERR_TOOSMALL。创建会话后,如果请求者发送的请求的回复大小将超过此值,则回复者将根据第2.10.6.4节中的描述返回NFS4ERR_REP_TOO_BIG。

ca_maxresponsesize_cached:

缓存的ca_maxresponsesize_:

Like ca_maxresponsesize, but the maximum size of a reply that will be stored in the reply cache (Section 2.10.6.1). For each channel, the server MAY decrease this value, but MUST NOT increase it. If, in the reply to CREATE_SESSION, the value of ca_maxresponsesize_cached of a channel is less than the value of ca_maxresponsesize of the same channel, then this is an indication to the requester that it needs to be selective about which replies it directs the replier to cache; for example, large replies from nonidempotent operations (e.g., COMPOUND requests with a READ operation) should not be cached. The requester decides which replies to cache via an argument to the SEQUENCE (the sa_cachethis field, see Section 18.46) or CB_SEQUENCE (the csa_cachethis field, see Section 20.9) operations. After the session is created, if a requester sends a request for which the size of the reply would exceed ca_maxresponsesize_cached, the replier will return NFS4ERR_REP_TOO_BIG_TO_CACHE, per the description in Section 2.10.6.4.

与ca_maxresponsesize类似,但将存储在回复缓存中的回复的最大大小(第2.10.6.1节)。对于每个通道,服务器可以减小该值,但不能增加该值。如果在应答创建会话中,某个通道的ca_maxresponsesize_cached值小于同一通道的ca_maxresponsesize值,则这表示请求者需要选择它指示应答者缓存的应答;例如,不应缓存来自非幂等操作(例如,具有读取操作的复合请求)的大型响应。请求者通过序列(sa_cachethis字段,参见第18.46节)或CB_序列(csa_cachethis字段,参见第20.9节)操作的参数来决定哪些响应要缓存。创建会话后,如果请求者发送的请求的回复大小将超过ca_maxresponsesize_cached,则根据第2.10.6.4节中的说明,回复者将NFS4ERR_REP_TO_BIG_TO_CACHE。

ca_maxoperations:

ca_maxoperations:

The maximum number of operations the replier will accept in a COMPOUND or CB_COMPOUND. For the backchannel, the server MUST NOT change the value the client offers. For the fore channel, the server MAY change the requested value. After the session is created, if a requester sends a COMPOUND or CB_COMPOUND with more operations than ca_maxoperations, the replier MUST return NFS4ERR_TOO_MANY_OPS.

应答器在复合或CB_复合中接受的最大操作数。对于反向通道,服务器不得更改客户端提供的值。对于前通道,服务器可以更改请求的值。创建会话后,如果请求者发送的复合或CB_复合操作多于ca_maxoperations,则应答者必须返回NFS4ERR_TOO_MANY_OPS。

ca_maxrequests:

ca_maxrequests:

The maximum number of concurrent COMPOUND or CB_COMPOUND requests the requester will send on the session. Subsequent requests will each be assigned a slot identifier by the requester within the range zero to ca_maxrequests - 1

请求者将在会话上发送的并发复合请求或CB_复合请求的最大数量。后续请求将由请求者在0到ca_maxrequests-1的范围内为每个请求分配一个插槽标识符

inclusive. For the backchannel, the server MUST NOT change the value the client offers. For the fore channel, the server MAY change the requested value.

包含全部费用对于反向通道,服务器不得更改客户端提供的值。对于前通道,服务器可以更改请求的值。

ca_rdma_ird:

税务局:

This array has a maximum of one element. If this array has one element, then the element contains the inbound RDMA read queue depth (IRD). For each channel, the server MAY decrease this value, but MUST NOT increase it.

此数组最多有一个元素。如果此数组有一个元素,则该元素包含入站RDMA读取队列深度(IRD)。对于每个通道,服务器可以减小该值,但不能增加该值。

csa_cb_program

csa_cb_计划

This is the ONC RPC program number the server MUST use in any callbacks sent through the backchannel to the client. The server MUST specify an ONC RPC program number equal to csa_cb_program and an ONC RPC version number equal to 4 in callbacks sent to the client. If a CB_COMPOUND is sent to the client, the server MUST use a minor version number of 1. There is no corresponding result.

这是服务器在通过反向通道发送到客户端的任何回调中必须使用的ONC RPC程序号。服务器必须在发送到客户端的回调中指定等于csa_cb_程序的ONC RPC程序号和等于4的ONC RPC版本号。如果将CB_化合物发送到客户端,则服务器必须使用次要版本号1。没有相应的结果。

csa_sec_parms

csa_secu_parms

The field csa_sec_parms is an array of acceptable security credentials the server can use on the session's backchannel. Three security flavors are supported: AUTH_NONE, AUTH_SYS, and RPCSEC_GSS. If AUTH_NONE is specified for a credential, then this says the client is authorizing the server to use AUTH_NONE on all callbacks for the session. If AUTH_SYS is specified, then the client is authorizing the server to use AUTH_SYS on all callbacks, using the credential specified cbsp_sys_cred. If RPCSEC_GSS is specified, then the server is allowed to use the RPCSEC_GSS context specified in cbsp_gss_parms as the RPCSEC_GSS context in the credential of the RPC header of callbacks to the client. There is no corresponding result.

字段csa_secu_parms是服务器可以在会话的后通道上使用的可接受安全凭据的数组。支持三种安全风格:AUTH_NONE、AUTH_SYS和RPCSEC_GSS。如果为凭据指定了AUTH_NONE,则表示客户端正在授权服务器在会话的所有回调上使用AUTH_NONE。如果指定了AUTH_SYS,则客户端授权服务器使用指定的cbsp_SYS_cred凭据在所有回调上使用AUTH_SYS。如果指定了RPCSEC_GSS,则允许服务器使用cbsp_GSS_parms中指定的RPCSEC_GSS上下文作为客户端回调的RPC标头凭据中的RPCSEC_GSS上下文。没有相应的结果。

The RPCSEC_GSS context for the backchannel is specified via a pair of values of data type gsshandle4_t. The data type gsshandle4_t represents an RPCSEC_GSS handle, and is precisely the same as the data type of the "handle" field of the rpc_gss_init_res data type defined in Section 5.2.3.1, "Context Creation Response - Successful Acceptance", of [4].

反向通道的RPCSEC_GSS上下文通过一对数据类型为gsshandle4_t的值指定。数据类型gsshandle4_t表示RPCSEC_GSS句柄,与[4]第5.2.3.1节“上下文创建响应-成功接受”中定义的rpc_GSS_init_res数据类型的“句柄”字段的数据类型完全相同。

The first RPCSEC_GSS handle, gcbp_handle_from_server, is the fore handle the server returned to the client (either in the handle field of data type rpc_gss_init_res or as one of the elements of the spi_handles field returned in the reply to EXCHANGE_ID) when the RPCSEC_GSS context was created on the server. The second

在服务器上创建RPCSEC_GSS上下文时,服务器返回给客户机的第一个RPCSEC_GSS句柄gcbp_handle_from_server是前句柄(在数据类型为rpc_GSS_init_res的句柄字段中,或作为回复EXCHANGE_ID中返回的spi_句柄字段的元素之一)。第二

handle, gcbp_handle_from_client, is the back handle to which the client will map the RPCSEC_GSS context. The server can immediately use the value of gcbp_handle_from_client in the RPCSEC_GSS credential in callback RPCs. That is, the value in gcbp_handle_from_client can be used as the value of the field "handle" in data type rpc_gss_cred_t (see Section 5, "Elements of the RPCSEC_GSS Security Protocol", of [4]) in callback RPCs. The server MUST use the RPCSEC_GSS security service specified in gcbp_service, i.e., it MUST set the "service" field of the rpc_gss_cred_t data type in RPCSEC_GSS credential to the value of gcbp_service (see Section 5.3.1, "RPC Request Header", of [4]).

handle,gcbp_handle_from_client,是客户端将RPCSEC_GSS上下文映射到的后句柄。服务器可以立即使用回调RPC中RPCSEC_GSS凭据中来自_客户端的gcbp_handle_值。也就是说,来自客户端的gcbp_handle_中的值可以用作回调rpc中数据类型rpc_gss_cred_t(参见第5节“RPCSEC_gss安全协议的元素”)中字段“handle”的值。服务器必须使用gcbp_服务中指定的RPCSEC_GSS安全服务,即必须将RPCSEC_GSS凭证中rpc_GSS_cred_t数据类型的“服务”字段设置为gcbp_服务的值(参见[4]第5.3.1节“rpc请求头”)。

If the RPCSEC_GSS handle identified by gcbp_handle_from_server does not exist on the server, the server will return NFS4ERR_NOENT.

如果服务器上不存在由来自\u服务器的gcbp\u handle\u标识的RPCSEC\u GSS句柄,则服务器将返回NFS4ERR\u NOENT。

Within each element of csa_sec_parms, the fore and back RPCSEC_GSS contexts MUST share the same GSS context and MUST have the same seq_window (see Section 5.2.3.1 of RFC2203 [4]). The fore and back RPCSEC_GSS context state are independent of each other as far as the RPCSEC_GSS sequence number (see the seq_num field in the rpc_gss_cred_t data type of Sections 5 and 5.3.1 of [4]).

在csa_sec_parms的每个元素中,前后RPCSEC_GSS上下文必须共享相同的GSS上下文,并且必须具有相同的seq_窗口(参见RFC2203[4]第5.2.3.1节)。就RPCSEC_GSS序列号而言,前后RPCSEC_GSS上下文状态彼此独立(参见[4]第5节和第5.3.1节rpc_GSS_cred_t数据类型中的seq_num字段)。

If an RPCSEC_GSS handle is using the SSV context (see Section 2.10.9), then because each SSV RPCSEC_GSS handle shares a common SSV GSS context, there are security considerations specific to this situation discussed in Section 2.10.10.

如果RPCSEC_GSS句柄正在使用SSV上下文(请参阅第2.10.9节),则由于每个SSV RPCSEC_GSS句柄共享一个公共SSV GSS上下文,因此在第2.10.10节中讨论了特定于这种情况的安全注意事项。

Once the session is created, the first SEQUENCE or CB_SEQUENCE received on a slot MUST have a sequence ID equal to 1; if not, the replier MUST return NFS4ERR_SEQ_MISORDERED.

创建会话后,插槽上接收的第一个序列或CB_序列的序列ID必须等于1;如果没有,应答者必须返回错误订购的NFS4ERR_SEQ_。

18.36.4. IMPLEMENTATION
18.36.4. 实施

To describe a possible implementation, the same notation for client records introduced in the description of EXCHANGE_ID is used with the following addition:

为了描述可能的实现,EXCHANGE_ID描述中引入的客户机记录的相同符号用于以下添加:

clientid_arg: The value of the csa_clientid field of the CREATE_SESSION4args structure of the current request.

clientid_arg:当前请求的CREATE_SESSION4args结构的csa_clientid字段的值。

Since CREATE_SESSION is a non-idempotent operation, we need to consider the possibility that retries may occur as a result of a client restart, network partition, malfunctioning router, etc. For each client ID created by EXCHANGE_ID, the server maintains a separate reply cache (called the CREATE_SESSION reply cache) similar to the session reply cache used for SEQUENCE operations, with two distinctions.

由于CealType会话是非幂等操作,所以我们需要考虑重启可能发生的原因,即客户端重新启动、网络分区、故障路由器等。对于由Exchange EID创建的每个客户端ID,服务器维护一个单独的应答缓存(称为CeCRATEY会话应答缓存)。与用于序列操作的会话应答缓存类似,有两个区别。

o First, this is a reply cache just for detecting and processing CREATE_SESSION requests for a given client ID.

o 首先,这是一个应答缓存,仅用于检测和处理给定客户端ID的CREATE_会话请求。

o Second, the size of the client ID reply cache is of one slot (and as a result, the CREATE_SESSION request does not carry a slot number). This means that at most one CREATE_SESSION request for a given client ID can be outstanding.

o 其次,客户端ID应答缓存的大小为一个插槽(因此,CREATE_会话请求不包含插槽号)。这意味着,对于给定的客户端ID,最多可以有一个CREATE_会话请求未完成。

As previously stated, CREATE_SESSION can be sent with or without a preceding SEQUENCE operation. Even if a SEQUENCE precedes CREATE_SESSION, the server MUST maintain the CREATE_SESSION reply cache, which is separate from the reply cache for the session associated with a SEQUENCE. If CREATE_SESSION was originally sent by itself, the client MAY send a retry of the CREATE_SESSION operation within a COMPOUND preceded by a SEQUENCE. If CREATE_SESSION was originally sent in a COMPOUND that started with a SEQUENCE, then the client SHOULD send a retry in a COMPOUND that starts with a SEQUENCE that has the same session ID as the SEQUENCE of the original request. However, the client MAY send a retry in a COMPOUND that either has no preceding SEQUENCE, or has a preceding SEQUENCE that refers to a different session than the original CREATE_SESSION. This might be necessary if the client sends a CREATE_SESSION in a COMPOUND preceded by a SEQUENCE with session ID X, and session X no longer exists. Regardless, any retry of CREATE_SESSION, with or without a preceding SEQUENCE, MUST use the same value of csa_sequence as the original.

如前所述,CREATE_会话可以通过或不通过前面的序列操作发送。即使序列在CREATE_会话之前,服务器也必须维护CREATE_会话应答缓存,该缓存与与序列关联的会话的应答缓存分离。如果CREATE_会话最初是由其自身发送的,则客户端可以在前面有序列的复合内发送CREATE_会话操作的重试。如果CREATE_会话最初是在以序列开头的复合中发送的,则客户端应在以与原始请求序列具有相同会话ID的序列开头的复合中发送重试。但是,客户端可以在没有前一个序列或前一个序列引用与原始CREATE_会话不同的会话的复合中发送重试。如果客户端在前面有会话ID为X的序列的复合中发送CREATE_会话,并且会话X不再存在,则可能需要执行此操作。无论如何,无论是否有前面的序列,对CREATE_会话的任何重试都必须使用与原始会话相同的csa_序列值。

After the client received a reply to an EXCHANGE_ID operation that contains a new, unconfirmed client ID, the server expects the client to follow with a CREATE_SESSION operation to confirm the client ID. The server expects value of csa_sequenceid in the arguments to that CREATE_SESSION to be to equal the value of the field eir_sequenceid that was returned in results of the EXCHANGE_ID that returned the unconfirmed client ID. Before the server replies to that EXCHANGE_ID operation, it initializes the client ID slot to be equal to eir_sequenceid - 1 (accounting for underflow), and records a contrived CREATE_SESSION result with a "cached" result of NFS4ERR_SEQ_MISORDERED. With the client ID slot thus initialized, the processing of the CREATE_SESSION operation is divided into four phases:

客户端收到对包含新的未确认客户端ID的EXCHANGE\u ID操作的答复后,服务器希望客户端执行CREATE_会话操作以确认客户端ID。服务器希望该CREATE_会话的参数中csa_sequenceid的值等于在返回未确认客户端ID的EXCHANGE_ID的结果中返回的字段eir_sequenceid的值。然后,服务器进行答复对于该EXCHANGE_ID操作,它将客户机ID槽初始化为等于eir_sequenceid-1(考虑下溢),并使用NFS4ERR_SEQ_排序错误的“缓存”结果记录人为创建_会话结果。这样初始化客户机ID插槽后,CREATE_会话操作的处理分为四个阶段:

1. Client record look up. The server looks up the client ID in its client record table. If the server contains no records with client ID equal to clientid_arg, then most likely the client's state has been purged during a period of inactivity, possibly due to a loss of connectivity. NFS4ERR_STALE_CLIENTID is returned, and no changes are made to any client records on the server. Otherwise, the server goes to phase 2.

1. 客户记录查询。服务器在其客户机记录表中查找客户机ID。如果服务器不包含客户端ID等于clientid_arg的记录,则很可能是由于失去连接,客户端的状态在非活动期间被清除。将返回NFS4ERR_STALE_CLIENTID,并且不会对服务器上的任何客户端记录进行任何更改。否则,服务器将进入第2阶段。

2. Sequence ID processing. If csa_sequenceid is equal to the sequence ID in the client ID's slot, then this is a replay of the previous CREATE_SESSION request, and the server returns the cached result. If csa_sequenceid is not equal to the sequence ID in the slot, and is more than one greater (accounting for wraparound), then the server returns the error NFS4ERR_SEQ_MISORDERED, and does not change the slot. If csa_sequenceid is equal to the slot's sequence ID + 1 (accounting for wraparound), then the slot's sequence ID is set to csa_sequenceid, and the CREATE_SESSION processing goes to the next phase. A subsequent new CREATE_SESSION call over the same client ID MUST use a csa_sequenceid that is one greater than the sequence ID in the slot.

2. 序列ID处理。如果csa_sequenceid等于客户机ID插槽中的序列ID,则这是上一个CREATE_会话请求的重播,服务器返回缓存结果。如果csa_sequenceid不等于插槽中的序列ID,并且大于一个(考虑到环绕),则服务器返回错误NFS4ERR_SEQ_MISSORDER,并且不更改插槽。如果csa_sequenceid等于插槽的序列ID+1(考虑环绕),则插槽的序列ID设置为csa_sequenceid,创建会话处理进入下一阶段。通过相同客户端ID进行的后续新CREATE_会话调用必须使用比插槽中的序列ID大一的csa_sequenceid。

3. Client ID confirmation. If this would be the first session for the client ID, the CREATE_SESSION operation serves to confirm the client ID. Otherwise, the client ID confirmation phase is skipped and only the session creation phase occurs. Any case in which there is more than one record with identical values for client ID represents a server implementation error. Operation in the potential valid cases is summarized as follows.

3. 客户ID确认。如果这将是客户端ID的第一个会话,则“创建会话”操作将用于确认客户端ID。否则,将跳过客户端ID确认阶段,仅发生会话创建阶段。任何情况下,如果有多条记录的客户端ID值相同,则表示服务器实现错误。潜在有效案例中的操作总结如下。

* Successful Confirmation

* 成功确认

If the server has the following unconfirmed record, then this is the expected confirmation of an unconfirmed record.

如果服务器具有以下未确认记录,则这是未确认记录的预期确认。

{ ownerid, verifier, principal_arg, clientid_arg, unconfirmed }

{所有者ID,验证人,委托人,客户ID,未确认}

As noted in Section 18.35.4, the server might also have the following confirmed record.

如第18.35.4节所述,服务器可能还具有以下已确认记录。

{ ownerid, old_verifier, principal_arg, old_clientid, confirmed }

{所有者ID,旧验证人,委托人参数,旧客户ID,已确认}

The server schedules the replacement of both records with:

服务器将两个记录的替换安排为:

{ ownerid, verifier, principal_arg, clientid_arg, confirmed }

{ownerid,验证者,委托人,客户ID,已确认}

The processing of CREATE_SESSION continues on to session creation. Once the session is successfully created, the scheduled client record replacement is committed. If the session is not successfully created, then no changes are made to any client records on the server.

创建会话的处理将继续到会话创建。成功创建会话后,将提交计划的客户端记录替换。如果会话未成功创建,则不会更改服务器上的任何客户端记录。

* Unsuccessful Confirmation

* 确认不成功

If the server has the following record, then the client has changed principals after the previous EXCHANGE_ID request, or there has been a chance collision between shorthand client identifiers.

如果服务器具有以下记录,则客户机在上一个EXCHANGE_ID请求后更改了主体,或者速记客户机标识符之间可能发生冲突。

             { *, *, old_principal_arg, clientid_arg, * }
        
             { *, *, old_principal_arg, clientid_arg, * }
        

Neither of these cases is permissible. Processing stops and NFS4ERR_CLID_INUSE is returned to the client. No changes are made to any client records on the server.

这两种情况都是不允许的。处理停止,NFS4ERR\u CLID\u INUSE返回给客户端。不会对服务器上的任何客户端记录进行任何更改。

4. Session creation. The server confirmed the client ID, either in this CREATE_SESSION operation, or a previous CREATE_SESSION operation. The server examines the remaining fields of the arguments.

4. 会话创建。服务器在此创建会话操作或以前的创建会话操作中确认了客户端ID。服务器检查参数的其余字段。

The server creates the session by recording the parameter values used (including whether the CREATE_SESSION4_FLAG_PERSIST flag is set and has been accepted by the server) and allocating space for the session reply cache (if there is not enough space, the server returns NFS4ERR_NOSPC). For each slot in the reply cache, the server sets the sequence ID to zero, and records an entry containing a COMPOUND reply with zero operations and the error NFS4ERR_SEQ_MISORDERED. This way, if the first SEQUENCE request sent has a sequence ID equal to zero, the server can simply return what is in the reply cache: NFS4ERR_SEQ_MISORDERED. The client initializes its reply cache for receiving callbacks in the same way, and similarly, the first CB_SEQUENCE operation on a slot after session creation MUST have a sequence ID of one.

服务器通过记录所使用的参数值(包括是否设置了CREATE_SESSION4_FLAG_PERSIST FLAG并已被服务器接受)和为会话应答缓存分配空间(如果没有足够的空间,服务器返回NFS4ERR_NOSPC)来创建会话。对于应答缓存中的每个插槽,服务器将序列ID设置为零,并记录一个包含复合应答的条目,其中包含零操作和错误NFS4ERR_SEQ_排序错误。这样,如果发送的第一个序列请求的序列ID等于零,服务器可以简单地返回应答缓存中的内容:NFS4ERR_SEQ_MISORDERED。客户端以相同的方式初始化其应答缓存以接收回调,同样,会话创建后插槽上的第一个CB_序列操作的序列ID必须为1。

If the session state is created successfully, the server associates the session with the client ID provided by the client.

如果会话状态创建成功,服务器将会话与客户端提供的客户端ID相关联。

When a request that had CREATE_SESSION4_FLAG_CONN_RDMA set needs to be retried, the retry MUST be done on a new connection that is in non-RDMA mode. If properties of the new connection are different enough that the arguments to CREATE_SESSION need to change, then a non-retry MUST be sent. The server will eventually dispose of any session that was created on the original connection.

当需要重试设置了CREATE_SESSION4_FLAG_CONN_RDMA的请求时,必须在非RDMA模式下的新连接上进行重试。如果新连接的属性差异很大,需要更改创建会话的参数,则必须发送非重试。服务器最终将处理在原始连接上创建的任何会话。

On the backchannel, the client and server might wish to have many slots, in some cases perhaps more that the fore channel, in order to deal with the situations where the network link has high latency and

在后通道上,客户机和服务器可能希望有许多插槽,在某些情况下可能比前通道多,以便处理网络链路具有高延迟和高可用性的情况

is the primary bottleneck for response to recalls. If so, and if the client provides too few slots to the backchannel, the server might limit the number of recallable objects it gives to the client.

是召回响应的主要瓶颈。如果是这样的话,并且如果客户机向反向通道提供的插槽太少,服务器可能会限制它提供给客户机的可重新调用对象的数量。

Implementing RPCSEC_GSS callback support requires changes to both the client and server implementations of RPCSEC_GSS. One possible set of changes includes:

实现RPCSEC_GSS回调支持需要更改RPCSEC_GSS的客户端和服务器实现。一组可能的更改包括:

o Adding a data structure that wraps the GSS-API context with a reference count.

o 添加用引用计数包装GSS-API上下文的数据结构。

o New functions to increment and decrement the reference count. If the reference count is decremented to zero, the wrapper data structure and the GSS-API context it refers to would be freed.

o 增加和减少引用计数的新函数。如果引用计数减为零,则将释放包装器数据结构及其引用的GSS-API上下文。

o Change RPCSEC_GSS to create the wrapper data structure upon receiving GSS-API context from gss_accept_sec_context() and gss_init_sec_context(). The reference count would be initialized to 1.

o 在从GSS_accept_sec_context()和GSS_init_sec_context()接收GSS-API上下文时,更改RPCSEC_GSS以创建包装器数据结构。引用计数将初始化为1。

o Adding a function to map an existing RPCSEC_GSS handle to a pointer to the wrapper data structure. The reference count would be incremented.

o 添加一个函数,将现有的RPCSEC_GSS句柄映射到指向包装器数据结构的指针。引用计数将增加。

o Adding a function to create a new RPCSEC_GSS handle from a pointer to the wrapper data structure. The reference count would be incremented.

o 添加一个函数,从指向包装器数据结构的指针创建新的RPCSEC_GSS句柄。引用计数将增加。

o Replacing calls from RPCSEC_GSS that free GSS-API contexts, with calls to decrement the reference count on the wrapper data structure.

o 将RPCSEC_GSS释放GSS-API上下文的调用替换为减少包装器数据结构上的引用计数的调用。

18.37. Operation 44: DESTROY_SESSION - Destroy a Session
18.37. 操作44:销毁会话-销毁会话
18.37.1. ARGUMENT
18.37.1. 论点
   struct DESTROY_SESSION4args {
           sessionid4      dsa_sessionid;
   };
        
   struct DESTROY_SESSION4args {
           sessionid4      dsa_sessionid;
   };
        
18.37.2. RESULT
18.37.2. 后果
   struct DESTROY_SESSION4res {
           nfsstat4        dsr_status;
   };
        
   struct DESTROY_SESSION4res {
           nfsstat4        dsr_status;
   };
        
18.37.3. DESCRIPTION
18.37.3. 描述

The DESTROY_SESSION operation closes the session and discards the session's reply cache, if any. Any remaining connections associated with the session are immediately disassociated. If the connection has no remaining associated sessions, the connection MAY be closed by the server. Locks, delegations, layouts, wants, and the lease, which are all tied to the client ID, are not affected by DESTROY_SESSION.

销毁会话操作关闭会话并丢弃会话的应答缓存(如果有)。与会话关联的所有剩余连接将立即解除关联。如果连接没有剩余的关联会话,则服务器可能会关闭连接。锁、委托、布局、需求和租约都绑定到客户端ID,不受DESTROY_会话的影响。

DESTROY_SESSION MUST be invoked on a connection that is associated with the session being destroyed. In addition, if SP4_MACH_CRED state protection was specified when the client ID was created, the RPCSEC_GSS principal that created the session MUST be the one that destroys the session, using RPCSEC_GSS privacy or integrity. If SP4_SSV state protection was specified when the client ID was created, RPCSEC_GSS using the SSV mechanism (Section 2.10.9) MUST be used, with integrity or privacy.

必须在与要销毁的会话关联的连接上调用销毁会话。此外,如果在创建客户端ID时指定了SP4_MACH_CRED state protection,则创建会话的RPCSEC_GSS主体必须是使用RPCSEC_GSS隐私或完整性销毁会话的主体。如果在创建客户端ID时指定了SP4_SSV状态保护,则必须使用使用SSV机制(第2.10.9节)的RPCSEC_GSS,且具有完整性或隐私性。

If the COMPOUND request starts with SEQUENCE, and if the sessionids specified in SEQUENCE and DESTROY_SESSION are the same, then

如果复合请求以SEQUENCE开头,并且SEQUENCE和DESTROY_SESSION中指定的sessionID相同,则

o DESTROY_SESSION MUST be the final operation in the COMPOUND request.

o 销毁会话必须是复合请求中的最后一个操作。

o It is advisable to avoid placing DESTROY_SESSION in a COMPOUND request with other state-modifying operations, because the DESTROY_SESSION will destroy the reply cache.

o 建议避免将DESTROY_会话放置在具有其他状态修改操作的复合请求中,因为DESTROY_会话将销毁应答缓存。

o Because the session and its reply cache are destroyed, a client that retries the request may receive an error in reply to the retry, even though the original request was successful.

o 由于会话及其应答缓存已销毁,因此重试请求的客户端在答复重试时可能会收到错误,即使原始请求已成功。

If the COMPOUND request starts with SEQUENCE, and if the sessionids specified in SEQUENCE and DESTROY_SESSION are different, then DESTROY_SESSION can appear in any position of the COMPOUND request (except for the first position). The two sessionids can belong to different client IDs.

如果复合请求以SEQUENCE开始,并且SEQUENCE和DESTROY_会话中指定的SessionID不同,则DESTROY_会话可以出现在复合请求的任何位置(第一个位置除外)。这两个sessionid可以属于不同的客户端id。

If the COMPOUND request does not start with SEQUENCE, and if DESTROY_SESSION is not the sole operation, then server MUST return NFS4ERR_NOT_ONLY_OP.

如果复合请求不是以顺序开始的,并且销毁会话不是唯一的操作,则服务器必须返回NFS4ERR\u not\u ONLY\u OP。

If there is a backchannel on the session and the server has outstanding CB_COMPOUND operations for the session which have not been replied to, then the server MAY refuse to destroy the session and return an error. If so, then in the event the backchannel is down, the server SHOULD return NFS4ERR_CB_PATH_DOWN to inform the client that the backchannel needs to be repaired before the server

如果会话上有一个反向通道,并且服务器对该会话有未完成的CB_复合操作,但尚未回复,则服务器可能会拒绝销毁该会话并返回错误。如果是这样,那么在反向通道关闭的情况下,服务器应返回NFS4ERR_CB_PATH_down以通知客户端需要在服务器关闭之前修复反向通道

will allow the session to be destroyed. Otherwise, the error CB_BACK_CHAN_BUSY SHOULD be returned to indicate that there are CB_COMPOUNDs that need to be replied to. The client SHOULD reply to all outstanding CB_COMPOUNDs before re-sending DESTROY_SESSION.

将允许销毁会话。否则,应返回错误CB_BACK_CHAN_BUSY,以指示存在需要回复的CB_化合物。在重新发送DESTROY_会话之前,客户端应回复所有未完成的CB_化合物。

18.38. Operation 45: FREE_STATEID - Free Stateid with No Locks
18.38. 操作45:FREE_STATEID-不带锁的FREE STATEID
18.38.1. ARGUMENT
18.38.1. 论点
   struct FREE_STATEID4args {
           stateid4        fsa_stateid;
   };
        
   struct FREE_STATEID4args {
           stateid4        fsa_stateid;
   };
        
18.38.2. RESULT
18.38.2. 后果
   struct FREE_STATEID4res {
           nfsstat4        fsr_status;
   };
        
   struct FREE_STATEID4res {
           nfsstat4        fsr_status;
   };
        
18.38.3. DESCRIPTION
18.38.3. 描述

The FREE_STATEID operation is used to free a stateid that no longer has any associated locks (including opens, byte-range locks, delegations, and layouts). This may be because of client LOCKU operations or because of server revocation. If there are valid locks (of any kind) associated with the stateid in question, the error NFS4ERR_LOCKS_HELD will be returned, and the associated stateid will not be freed.

FREE_STATEID操作用于释放不再具有任何关联锁(包括打开、字节范围锁、委派和布局)的STATEID。这可能是因为客户端锁定操作或服务器吊销。如果存在与所讨论的stateid关联的有效锁(任何类型),则将返回错误NFS4ERR_locks_hold,并且不会释放关联的stateid。

When a stateid is freed that had been associated with revoked locks, by sending the FREE_STATEID operation, the client acknowledges the loss of those locks. This allows the server, once all such revoked state is acknowledged, to allow that client again to reclaim locks, without encountering the edge conditions discussed in Section 8.4.2.

当释放与已撤销锁关联的stateid时,通过发送FREE_stateid操作,客户端确认这些锁的丢失。这允许服务器在确认所有此类撤销状态后,再次允许该客户端回收锁,而不会遇到第8.4.2节中讨论的边缘条件。

Once a successful FREE_STATEID is done for a given stateid, any subsequent use of that stateid will result in an NFS4ERR_BAD_STATEID error.

一旦为给定的STATEID成功完成了FREE_STATEID,则该STATEID的任何后续使用都将导致NFS4ERR_BAD_STATEID错误。

18.39. Operation 46: GET_DIR_DELEGATION - Get a Directory Delegation
18.39. 操作46:获取目录委派-获取目录委派
18.39.1. ARGUMENT
18.39.1. 论点

typedef nfstime4 attr_notice4;

类型定义nfstime4属性通知4;

   struct GET_DIR_DELEGATION4args {
           /* CURRENT_FH: delegated directory */
           bool            gdda_signal_deleg_avail;
           bitmap4         gdda_notification_types;
           attr_notice4    gdda_child_attr_delay;
           attr_notice4    gdda_dir_attr_delay;
           bitmap4         gdda_child_attributes;
           bitmap4         gdda_dir_attributes;
   };
        
   struct GET_DIR_DELEGATION4args {
           /* CURRENT_FH: delegated directory */
           bool            gdda_signal_deleg_avail;
           bitmap4         gdda_notification_types;
           attr_notice4    gdda_child_attr_delay;
           attr_notice4    gdda_dir_attr_delay;
           bitmap4         gdda_child_attributes;
           bitmap4         gdda_dir_attributes;
   };
        
18.39.2. RESULT
18.39.2. 后果
   struct GET_DIR_DELEGATION4resok {
           verifier4       gddr_cookieverf;
           /* Stateid for get_dir_delegation */
           stateid4        gddr_stateid;
           /* Which notifications can the server support */
           bitmap4         gddr_notification;
           bitmap4         gddr_child_attributes;
           bitmap4         gddr_dir_attributes;
   };
        
   struct GET_DIR_DELEGATION4resok {
           verifier4       gddr_cookieverf;
           /* Stateid for get_dir_delegation */
           stateid4        gddr_stateid;
           /* Which notifications can the server support */
           bitmap4         gddr_notification;
           bitmap4         gddr_child_attributes;
           bitmap4         gddr_dir_attributes;
   };
        
   enum gddrnf4_status {
           GDD4_OK         = 0,
           GDD4_UNAVAIL    = 1
   };
        
   enum gddrnf4_status {
           GDD4_OK         = 0,
           GDD4_UNAVAIL    = 1
   };
        
   union GET_DIR_DELEGATION4res_non_fatal
    switch (gddrnf4_status gddrnf_status) {
    case GDD4_OK:
     GET_DIR_DELEGATION4resok      gddrnf_resok4;
    case GDD4_UNAVAIL:
     bool                          gddrnf_will_signal_deleg_avail;
   };
        
   union GET_DIR_DELEGATION4res_non_fatal
    switch (gddrnf4_status gddrnf_status) {
    case GDD4_OK:
     GET_DIR_DELEGATION4resok      gddrnf_resok4;
    case GDD4_UNAVAIL:
     bool                          gddrnf_will_signal_deleg_avail;
   };
        
   union GET_DIR_DELEGATION4res
    switch (nfsstat4 gddr_status) {
    case NFS4_OK:
     GET_DIR_DELEGATION4res_non_fatal      gddr_res_non_fatal4;
    default:
     void;
   };
        
   union GET_DIR_DELEGATION4res
    switch (nfsstat4 gddr_status) {
    case NFS4_OK:
     GET_DIR_DELEGATION4res_non_fatal      gddr_res_non_fatal4;
    default:
     void;
   };
        
18.39.3. DESCRIPTION
18.39.3. 描述

The GET_DIR_DELEGATION operation is used by a client to request a directory delegation. The directory is represented by the current filehandle. The client also specifies whether it wants the server to notify it when the directory changes in certain ways by setting one or more bits in a bitmap. The server may refuse to grant the delegation. In that case, the server will return NFS4ERR_DIRDELEG_UNAVAIL. If the server decides to hand out the delegation, it will return a cookie verifier for that directory. If the cookie verifier changes when the client is holding the delegation, the delegation will be recalled unless the client has asked for notification for this event.

客户端使用GET_DIR_委派操作请求目录委派。目录由当前文件句柄表示。客户端还通过在位图中设置一个或多个位来指定是否希望服务器在目录以某种方式更改时通知它。服务器可能拒绝授予委派。在这种情况下,服务器将返回NFS4ERR_DIRDELEG_UNAVAIL。如果服务器决定分发委托,它将返回该目录的cookie验证器。如果cookie验证器在客户端持有委托时发生更改,则除非客户端请求通知此事件,否则将调用该委托。

The server will also return a directory delegation stateid, gddr_stateid, as a result of the GET_DIR_DELEGATION operation. This stateid will appear in callback messages related to the delegation, such as notifications and delegation recalls. The client will use this stateid to return the delegation voluntarily or upon recall. A delegation is returned by calling the DELEGRETURN operation.

作为GET_DIR_委派操作的结果,服务器还将返回目录委派stateid gddr_stateid。此stateid将出现在与委派相关的回调消息中,例如通知和委派回调。客户将使用此stateid自愿或在召回时返回委托。通过调用DELEGRETURN操作返回委派。

The server might not be able to support notifications of certain events. If the client asks for such notifications, the server MUST inform the client of its inability to do so as part of the GET_DIR_DELEGATION reply by not setting the appropriate bits in the supported notifications bitmask, gddr_notification, contained in the reply. The server MUST NOT add bits to gddr_notification that the client did not request.

服务器可能无法支持某些事件的通知。如果客户机请求此类通知,服务器必须在GET_DIR_委派回复中通知客户机其无法这样做,方法是不在回复中包含的受支持的通知位掩码gddr_notification中设置适当的位。服务器不得向gddr_通知中添加客户端未请求的位。

The GET_DIR_DELEGATION operation can be used for both normal and named attribute directories.

GET_DIR_委派操作可用于普通和命名属性目录。

If client sets gdda_signal_deleg_avail to TRUE, then it is registering with the client a "want" for a directory delegation. If the delegation is not available, and the server supports and will honor the "want", the results will have gddrnf_will_signal_deleg_avail set to TRUE and no error will be indicated on return. If so, the client should expect a future CB_RECALLABLE_OBJ_AVAIL operation to indicate that a directory delegation is available. If the server does not wish to honor the

如果客户机将gdda_signal_deleg_avail设置为TRUE,则它正在向客户机注册目录委派的“想要”。如果委托不可用,并且服务器支持并将遵守“需要”,则结果将使gddrnf_will_signal_deleg_avail设置为TRUE,并且返回时不会显示任何错误。如果是这样,客户机应该期望将来的CB_可重新调用_OBJ_AVAIL操作指示目录委派可用。如果服务器不希望遵守

"want" or is not able to do so, it returns the error NFS4ERR_DIRDELEG_UNAVAIL. If the delegation is immediately available, the server SHOULD return it with the response to the operation, rather than via a callback.

“想要”或无法执行此操作,则返回错误NFS4ERR_DIRDELEG_UNAVAIL。如果委派立即可用,服务器应将其与对操作的响应一起返回,而不是通过回调。

When a client makes a request for a directory delegation while it already holds a directory delegation for that directory (including the case where it has been recalled but not yet returned by the client or revoked by the server), the server MUST reply with the value of gddr_status set to NFS4_OK, the value of gddrnf_status set to GDD4_UNAVAIL, and the value of gddrnf_will_signal_deleg_avail set to FALSE. The delegation the client held before the request remains intact, and its state is unchanged. The current stateid is not changed (see Section 16.2.3.1.2 for a description of the current stateid).

当客户机在已持有该目录的目录委派的情况下发出目录委派请求时(包括已被召回但尚未由客户机返回或由服务器撤销的情况),服务器必须使用设置为NFS4_OK的gddr_状态值、设置为GDD4_UNAVAIL的gddrnf_状态值进行回复,gddrnf_的值将_signal_deleg_avail设置为FALSE。客户端在请求之前持有的委托保持不变,其状态不变。当前stateid未更改(有关当前stateid的说明,请参阅第16.2.3.1.2节)。

18.39.4. IMPLEMENTATION
18.39.4. 实施

Directory delegations provide the benefit of improving cache consistency of namespace information. This is done through synchronous callbacks. A server must support synchronous callbacks in order to support directory delegations. In addition to that, asynchronous notifications provide a way to reduce network traffic as well as improve client performance in certain conditions.

目录委派有助于提高命名空间信息的缓存一致性。这是通过同步回调完成的。服务器必须支持同步回调才能支持目录委派。除此之外,异步通知还提供了一种在某些情况下减少网络流量并提高客户端性能的方法。

Notifications are specified in terms of potential changes to the directory. A client can ask to be notified of events by setting one or more bits in gdda_notification_types. The client can ask for notifications on addition of entries to a directory (by setting the NOTIFY4_ADD_ENTRY in gdda_notification_types), notifications on entry removal (NOTIFY4_REMOVE_ENTRY), renames (NOTIFY4_RENAME_ENTRY), directory attribute changes (NOTIFY4_CHANGE_DIR_ATTRIBUTES), and cookie verifier changes (NOTIFY4_CHANGE_COOKIE_VERIFIER) by setting one or more corresponding bits in the gdda_notification_types field.

通知是根据目录的潜在更改来指定的。客户机可以通过在gdda_通知_类型中设置一个或多个位来请求通知事件。客户端可以请求向目录添加条目的通知(通过在gdda_通知类型中设置NOTIFY4_添加_条目)、条目删除通知(NOTIFY4_删除_条目)、重命名通知(NOTIFY4_重命名_条目)、目录属性更改(NOTIFY4_更改_目录属性)和cookie验证程序更改通知(NOTIFY4_更改_cookie验证程序)通过在gdda_通知_类型字段中设置一个或多个对应位。

The client can also ask for notifications of changes to attributes of directory entries (NOTIFY4_CHANGE_CHILD_ATTRIBUTES) in order to keep its attribute cache up to date. However, any changes made to child attributes do not cause the delegation to be recalled. If a client is interested in directory entry caching or negative name caching, it can set the gdda_notification_types appropriately to its particular need and the server will notify it of all changes that would otherwise invalidate its name cache. The kind of notification a client asks for may depend on the directory size, its rate of change, and the applications being used to access that directory. The enumeration of the conditions under which a client might ask for a notification is out of the scope of this specification.

客户端还可以请求更改目录项属性的通知(NOTIFY4\u CHANGE\u CHILD\u attributes),以使其属性缓存保持最新。但是,对子属性所做的任何更改都不会导致重新调用委托。如果客户机对目录项缓存或负名称缓存感兴趣,它可以根据其特定需要适当地设置gdda_通知_类型,服务器将通知它所有可能使其名称缓存无效的更改。客户端请求的通知类型可能取决于目录大小、更改率以及用于访问该目录的应用程序。客户机可能要求通知的条件的枚举不在本规范的范围内。

For attribute notifications, the client will set bits in the gdda_dir_attributes bitmap to indicate which attributes it wants to be notified of. If the server does not support notifications for changes to a certain attribute, it SHOULD NOT set that attribute in the supported attribute bitmap specified in the reply (gddr_dir_attributes). The client will also set in the gdda_child_attributes bitmap the attributes of directory entries it wants to be notified of, and the server will indicate in gddr_child_attributes which attributes of directory entries it will notify the client of.

对于属性通知,客户端将在gdda_dir_属性位图中设置位,以指示要通知的属性。如果服务器不支持更改某个属性的通知,则不应在回复中指定的受支持属性位图(gddr_dir_attributes)中设置该属性。客户端还将在gdda_child_属性位图中设置它希望通知的目录项的属性,服务器将在gddr_child_属性中指示它将通知客户端的目录项的哪些属性。

The client will also let the server know if it wants to get the notification as soon as the attribute change occurs or after a certain delay by setting a delay factor; gdda_child_attr_delay is for attribute changes to directory entries and gdda_dir_attr_delay is for attribute changes to the directory. If this delay factor is set to zero, that indicates to the server that the client wants to be notified of any attribute changes as soon as they occur. If the delay factor is set to N seconds, the server will make a best-effort guarantee that attribute updates are synchronized within N seconds. If the client asks for a delay factor that the server does not support or that may cause significant resource consumption on the server by causing the server to send a lot of notifications, the server should not commit to sending out notifications for attributes and therefore must not set the appropriate bit in the gddr_child_attributes and gddr_dir_attributes bitmaps in the response.

客户机还将通过设置延迟因子,让服务器知道它是否希望在属性更改发生时或在某个延迟后立即获得通知;gdda_child_attr_delay用于目录项的属性更改,gdda_dir_attr_delay用于目录的属性更改。如果此延迟因子设置为零,则表示服务器希望在发生任何属性更改时立即通知客户端。如果延迟因子设置为N秒,服务器将尽最大努力保证在N秒内同步属性更新。如果客户端要求提供服务器不支持的延迟因子,或者可能导致服务器发送大量通知,从而导致服务器上大量资源消耗,服务器不应承诺发送属性通知,因此不得在响应中的gddr_child_属性和gddr_dir_属性位图中设置适当的位。

The client MUST use a security tuple (Section 2.6.1) that the directory or its applicable ancestor (Section 2.6) is exported with. If not, the server MUST return NFS4ERR_WRONGSEC to the operation that both precedes GET_DIR_DELEGATION and sets the current filehandle (see Section 2.6.3.1).

客户端必须使用导出目录或其适用祖先(第2.6节)时使用的安全元组(第2.6.1节)。如果没有,服务器必须将NFS4ERR_errosec返回给GET_DIR_委派之前的操作,并设置当前文件句柄(请参见第2.6.3.1节)。

The directory delegation covers all the entries in the directory except the parent entry. That means if a directory and its parent both hold directory delegations, any changes to the parent will not cause a notification to be sent for the child even though the child's parent entry points to the parent directory.

目录委派覆盖目录中除父项之外的所有项。这意味着,如果目录及其父目录都持有目录委派,则对父目录的任何更改都不会导致为子目录发送通知,即使子目录的父条目指向父目录。

18.40. Operation 47: GETDEVICEINFO - Get Device Information
18.40. 操作47:GETDEVICEINFO-获取设备信息
18.40.1. ARGUMENT
18.40.1. 论点
   struct GETDEVICEINFO4args {
           deviceid4       gdia_device_id;
           layouttype4     gdia_layout_type;
           count4          gdia_maxcount;
           bitmap4         gdia_notify_types;
   };
        
   struct GETDEVICEINFO4args {
           deviceid4       gdia_device_id;
           layouttype4     gdia_layout_type;
           count4          gdia_maxcount;
           bitmap4         gdia_notify_types;
   };
        
18.40.2. RESULT
18.40.2. 后果
   struct GETDEVICEINFO4resok {
           device_addr4    gdir_device_addr;
           bitmap4         gdir_notification;
   };
        
   struct GETDEVICEINFO4resok {
           device_addr4    gdir_device_addr;
           bitmap4         gdir_notification;
   };
        
   union GETDEVICEINFO4res switch (nfsstat4 gdir_status) {
   case NFS4_OK:
           GETDEVICEINFO4resok     gdir_resok4;
   case NFS4ERR_TOOSMALL:
           count4                  gdir_mincount;
   default:
           void;
   };
        
   union GETDEVICEINFO4res switch (nfsstat4 gdir_status) {
   case NFS4_OK:
           GETDEVICEINFO4resok     gdir_resok4;
   case NFS4ERR_TOOSMALL:
           count4                  gdir_mincount;
   default:
           void;
   };
        
18.40.3. DESCRIPTION
18.40.3. 描述

The GETDEVICEINFO operation returns pNFS storage device address information for the specified device ID. The client identifies the device information to be returned by providing the gdia_device_id and gdia_layout_type that uniquely identify the device. The client provides gdia_maxcount to limit the number of bytes for the result. This maximum size represents all of the data being returned within the GETDEVICEINFO4resok structure and includes the XDR overhead. The server may return less data. If the server is unable to return any information within the gdia_maxcount limit, the error NFS4ERR_TOOSMALL will be returned. However, if gdia_maxcount is zero, NFS4ERR_TOOSMALL MUST NOT be returned.

GETDEVICEINFO操作返回指定设备ID的pNFS存储设备地址信息。客户端通过提供唯一标识设备的gdia_设备_ID和gdia_布局_类型来标识要返回的设备信息。客户端提供gdia_maxcount来限制结果的字节数。此最大大小表示GetDeviceInfo 4Resok结构中返回的所有数据,并包括XDR开销。服务器可能返回较少的数据。如果服务器无法返回gdia_maxcount限制内的任何信息,将返回错误NFS4ERR_Toosall。但是,如果gdia_maxcount为零,则不能返回NFS4ERR_TOOSMALL。

The da_layout_type field of the gdir_device_addr returned by the server MUST be equal to the gdia_layout_type specified by the client. If it is not equal, the client SHOULD ignore the response as invalid and behave as if the server returned an error, even if the client does have support for the layout type returned.

服务器返回的gdir_device_addr的da_layout_type字段必须等于客户端指定的gdia_layout_type。如果不相等,则客户端应将响应视为无效而忽略,并表现为服务器返回错误,即使客户端确实支持返回的布局类型。

The client also provides a notification bitmap, gdia_notify_types, for the device ID mapping notification for which it is interested in receiving; the server must support device ID notifications for the notification request to have affect. The notification mask is composed in the same manner as the bitmap for file attributes (Section 3.3.7). The numbers of bit positions are listed in the notify_device_type4 enumeration type (Section 20.12). Only two enumerated values of notify_device_type4 currently apply to GETDEVICEINFO: NOTIFY_DEVICEID4_CHANGE and NOTIFY_DEVICEID4_DELETE (see Section 20.12).

客户机还为其感兴趣接收的设备ID映射通知提供通知位图gdia_notify_types;服务器必须支持设备ID通知,通知请求才能生效。通知掩码的构成方式与文件属性位图相同(第3.3.7节)。位位置的数量列在notify_device_type4枚举类型中(第20.12节)。当前只有notify_device_type4的两个枚举值适用于GETDEVICEINFO:notify_DEVICEID4_CHANGE和notify_DEVICEID4_DELETE(参见第20.12节)。

The notification bitmap applies only to the specified device ID. If a client sends a GETDEVICEINFO operation on a deviceID multiple times, the last notification bitmap is used by the server for subsequent notifications. If the bitmap is zero or empty, then the device ID's notifications are turned off.

通知位图仅适用于指定的设备ID。如果客户端多次在deviceID上发送GETDEVICEINFO操作,服务器将使用最后一个通知位图进行后续通知。如果位图为零或为空,则设备ID的通知将关闭。

If the client wants to just update or turn off notifications, it MAY send a GETDEVICEINFO operation with gdia_maxcount set to zero. In that event, if the device ID is valid, the reply's da_addr_body field of the gdir_device_addr field will be of zero length.

如果客户端只想更新或关闭通知,它可能会发送一个GETDEVICEINFO操作,并将gdia_maxcount设置为零。在这种情况下,如果设备ID有效,gdir_device_addr字段的回复的da_addr_body字段长度将为零。

If an unknown device ID is given in gdia_device_id, the server returns NFS4ERR_NOENT. Otherwise, the device address information is returned in gdir_device_addr. Finally, if the server supports notifications for device ID mappings, the gdir_notification result will contain a bitmap of which notifications it will actually send to the client (via CB_NOTIFY_DEVICEID, see Section 20.12).

如果gdia_device_ID中给出了未知的设备ID,服务器将返回NFS4ERR_NOENT。否则,设备地址信息将在gdir_device_addr中返回。最后,如果服务器支持设备ID映射的通知,gdir_通知结果将包含一个位图,它将实际向客户端发送通知(通过CB_NOTIFY_DEVICEID,请参阅第20.12节)。

If NFS4ERR_TOOSMALL is returned, the results also contain gdir_mincount. The value of gdir_mincount represents the minimum size necessary to obtain the device information.

如果返回NFS4ERR_TOOSMALL,则结果还包含gdir_mincount。gdir_mincount的值表示获取设备信息所需的最小大小。

18.40.4. IMPLEMENTATION
18.40.4. 实施

Aside from updating or turning off notifications, another use case for gdia_maxcount being set to zero is to validate a device ID.

除了更新或关闭通知之外,gdia_maxcount设置为零的另一个用例是验证设备ID。

The client SHOULD request a notification for changes or deletion of a device ID to device address mapping so that the server can allow the client gracefully use a new mapping, without having pending I/O fail abruptly, or force layouts using the device ID to be recalled or revoked.

客户端应请求更改或删除设备ID到设备地址映射的通知,以便服务器可以允许客户端优雅地使用新映射,而不会出现挂起的I/O突然失败,或者强制调用或撤销使用设备ID的布局。

It is possible that GETDEVICEINFO (and GETDEVICELIST) will race with CB_NOTIFY_DEVICEID, i.e., CB_NOTIFY_DEVICEID arrives before the client gets and processes the response to GETDEVICEINFO or

GETDEVICEINFO(和GETDEVICELIST)可能会与CB_NOTIFY_DEVICEID竞争,即CB_NOTIFY_DEVICEID在客户端获取并处理对GETDEVICEINFO或的响应之前到达

GETDEVICELIST. The analysis of the race leverages the fact that the server MUST NOT delete a device ID that is referred to by a layout the client has.

魔鬼主义者。竞争分析利用了这样一个事实,即服务器不得删除客户端布局所引用的设备ID。

o CB_NOTIFY_DEVICEID deletes a device ID. If the client believes it has layouts that refer to the device ID, then it is possible that layouts referring to the deleted device ID have been revoked. The client should send a TEST_STATEID request using the stateid for each layout that might have been revoked. If TEST_STATEID indicates that any layouts have been revoked, the client must recover from layout revocation as described in Section 12.5.6. If TEST_STATEID indicates that at least one layout has not been revoked, the client should send a GETDEVICEINFO operation on the supposedly deleted device ID to verify that the device ID has been deleted.

o CB_NOTIFY_DEVICEID删除设备ID。如果客户端认为其具有引用设备ID的布局,则引用已删除设备ID的布局可能已被撤销。客户端应使用每个可能已撤销的布局的STATEID发送一个TEST_STATEID请求。如果TEST_STATEID指示任何布局已被撤销,则客户端必须按照第12.5.6节中的说明从布局撤销中恢复。如果TEST_STATEID指示至少一个布局未被撤销,则客户端应在假定已删除的设备ID上发送GETDEVICEINFO操作,以验证该设备ID是否已被删除。

If GETDEVICEINFO indicates that the device ID does not exist, then the client assumes the server is faulty and recovers by sending an EXCHANGE_ID operation. If GETDEVICEINFO indicates that the device ID does exist, then while the server is faulty for sending an erroneous device ID deletion notification, the degree to which it is faulty does not require the client to create a new client ID.

如果GETDEVICEINFO指示设备ID不存在,则客户端将假定服务器有故障,并通过发送EXCHANGE\u ID操作进行恢复。如果GETDEVICEINFO指示设备ID确实存在,则当服务器因发送错误的设备ID删除通知而出现故障时,其故障程度不要求客户端创建新的客户端ID。

If the client does not have layouts that refer to the device ID, no harm is done. The client should mark the device ID as deleted, and when GETDEVICEINFO or GETDEVICELIST results are received that indicate that the device ID has been in fact deleted, the device ID should be removed from the client's cache.

如果客户端没有引用设备ID的布局,则不会造成任何伤害。客户端应将设备ID标记为已删除,并且当接收到GETDEVICEINFO或GETDEVICELIST结果表明设备ID实际上已被删除时,应将设备ID从客户端缓存中删除。

o CB_NOTIFY_DEVICEID indicates that a device ID's device addressing mappings have changed. The client should assume that the results from the in-progress GETDEVICEINFO will be stale for the device ID once received, and so it should send another GETDEVICEINFO on the device ID.

o CB_NOTIFY_DEVICEID表示设备ID的设备寻址映射已更改。客户机应该假设从正在进行的GETDEVICEINFO中得到的结果在收到设备ID后将过时,因此它应该在设备ID上发送另一个GETDEVICEINFO。

18.41. Operation 48: GETDEVICELIST - Get All Device Mappings for a File System

18.41. 操作48:GETDEVICELIST-获取文件系统的所有设备映射

18.41.1. ARGUMENT
18.41.1. 论点
   struct GETDEVICELIST4args {
           /* CURRENT_FH: object belonging to the file system */
           layouttype4     gdla_layout_type;
        
   struct GETDEVICELIST4args {
           /* CURRENT_FH: object belonging to the file system */
           layouttype4     gdla_layout_type;
        
           /* number of deviceIDs to return */
           count4          gdla_maxdevices;
        
           /* number of deviceIDs to return */
           count4          gdla_maxdevices;
        
           nfs_cookie4     gdla_cookie;
           verifier4       gdla_cookieverf;
   };
        
           nfs_cookie4     gdla_cookie;
           verifier4       gdla_cookieverf;
   };
        
18.41.2. RESULT
18.41.2. 后果
   struct GETDEVICELIST4resok {
           nfs_cookie4             gdlr_cookie;
           verifier4               gdlr_cookieverf;
           deviceid4               gdlr_deviceid_list<>;
           bool                    gdlr_eof;
   };
        
   struct GETDEVICELIST4resok {
           nfs_cookie4             gdlr_cookie;
           verifier4               gdlr_cookieverf;
           deviceid4               gdlr_deviceid_list<>;
           bool                    gdlr_eof;
   };
        
   union GETDEVICELIST4res switch (nfsstat4 gdlr_status) {
   case NFS4_OK:
           GETDEVICELIST4resok     gdlr_resok4;
   default:
           void;
   };
        
   union GETDEVICELIST4res switch (nfsstat4 gdlr_status) {
   case NFS4_OK:
           GETDEVICELIST4resok     gdlr_resok4;
   default:
           void;
   };
        
18.41.3. DESCRIPTION
18.41.3. 描述

This operation is used by the client to enumerate all of the device IDs that a server's file system uses.

客户端使用此操作枚举服务器文件系统使用的所有设备ID。

The client provides a current filehandle of a file object that belongs to the file system (i.e., all file objects sharing the same fsid as that of the current filehandle) and the layout type in gdia_layout_type. Since this operation might require multiple calls to enumerate all the device IDs (and is thus similar to the READDIR (Section 18.23) operation), the client also provides gdia_cookie and gdia_cookieverf to specify the current cursor position in the list. When the client wants to read from the beginning of the file system's device mappings, it sets gdla_cookie to zero. The field gdla_cookieverf MUST be ignored by the server when gdla_cookie is

客户端提供属于文件系统的文件对象的当前文件句柄(即,与当前文件句柄共享相同fsid的所有文件对象)和gdia_layout_type中的布局类型。由于此操作可能需要多次调用来枚举所有设备ID(因此类似于READDIR(第18.23节)操作),因此客户端还提供gdia_cookie和gdia_cookieverf来指定列表中的当前光标位置。当客户机希望从文件系统的设备映射开始读取时,它会将gdla_cookie设置为零。启用gdla_cookie时,服务器必须忽略字段gdla_cookieverf

zero. The client provides gdla_maxdevices to limit the number of device IDs in the result. If gdla_maxdevices is zero, the server MUST return NFS4ERR_INVAL. The server MAY return fewer device IDs.

零客户端提供gdla_maxdevices来限制结果中的设备ID数量。如果gdla_maxdevices为零,服务器必须返回NFS4ERR_INVAL。服务器可能返回较少的设备ID。

The successful response to the operation will contain the cookie, gdlr_cookie, and the cookie verifier, gdlr_cookieverf, to be used on the subsequent GETDEVICELIST. A gdlr_eof value of TRUE signifies that there are no remaining entries in the server's device list. Each element of gdlr_deviceid_list contains a device ID.

对该操作的成功响应将包含cookie、gdlr_cookie和cookie验证器gdlr_cookieverf,用于后续的GETDEVICELIST。gdlr_eof值为TRUE表示服务器的设备列表中没有剩余条目。gdlr_设备ID_列表的每个元素都包含一个设备ID。

18.41.4. IMPLEMENTATION
18.41.4. 实施

An example of the use of this operation is for pNFS clients and servers that use LAYOUT4_BLOCK_VOLUME layouts. In these environments it may be helpful for a client to determine device accessibility upon first file system access.

此操作的一个示例用于使用LAYOUT4\u BLOCK\u卷布局的pNFS客户端和服务器。在这些环境中,客户机在首次访问文件系统时确定设备的可访问性可能会有所帮助。

18.42. Operation 49: LAYOUTCOMMIT - Commit Writes Made Using a Layout
18.42. 操作49:LAYOUTCOMMIT-使用布局进行提交写入
18.42.1. ARGUMENT
18.42.1. 论点
   union newtime4 switch (bool nt_timechanged) {
   case TRUE:
           nfstime4           nt_time;
   case FALSE:
           void;
   };
        
   union newtime4 switch (bool nt_timechanged) {
   case TRUE:
           nfstime4           nt_time;
   case FALSE:
           void;
   };
        
   union newoffset4 switch (bool no_newoffset) {
   case TRUE:
           offset4           no_offset;
   case FALSE:
           void;
   };
        
   union newoffset4 switch (bool no_newoffset) {
   case TRUE:
           offset4           no_offset;
   case FALSE:
           void;
   };
        
   struct LAYOUTCOMMIT4args {
           /* CURRENT_FH: file */
           offset4                 loca_offset;
           length4                 loca_length;
           bool                    loca_reclaim;
           stateid4                loca_stateid;
           newoffset4              loca_last_write_offset;
           newtime4                loca_time_modify;
           layoutupdate4           loca_layoutupdate;
   };
        
   struct LAYOUTCOMMIT4args {
           /* CURRENT_FH: file */
           offset4                 loca_offset;
           length4                 loca_length;
           bool                    loca_reclaim;
           stateid4                loca_stateid;
           newoffset4              loca_last_write_offset;
           newtime4                loca_time_modify;
           layoutupdate4           loca_layoutupdate;
   };
        
18.42.2. RESULT
18.42.2. 后果
   union newsize4 switch (bool ns_sizechanged) {
   case TRUE:
           length4         ns_size;
   case FALSE:
           void;
   };
        
   union newsize4 switch (bool ns_sizechanged) {
   case TRUE:
           length4         ns_size;
   case FALSE:
           void;
   };
        
   struct LAYOUTCOMMIT4resok {
           newsize4                locr_newsize;
   };
        
   struct LAYOUTCOMMIT4resok {
           newsize4                locr_newsize;
   };
        
   union LAYOUTCOMMIT4res switch (nfsstat4 locr_status) {
   case NFS4_OK:
           LAYOUTCOMMIT4resok      locr_resok4;
   default:
           void;
   };
        
   union LAYOUTCOMMIT4res switch (nfsstat4 locr_status) {
   case NFS4_OK:
           LAYOUTCOMMIT4resok      locr_resok4;
   default:
           void;
   };
        
18.42.3. DESCRIPTION
18.42.3. 描述

The LAYOUTCOMMIT operation commits changes in the layout represented by the current filehandle, client ID (derived from the session ID in the preceding SEQUENCE operation), byte-range, and stateid. Since layouts are sub-dividable, a smaller portion of a layout, retrieved via LAYOUTGET, can be committed. The byte-range being committed is specified through the byte-range (loca_offset and loca_length). This byte-range MUST overlap with one or more existing layouts previously granted via LAYOUTGET (Section 18.43), each with an iomode of LAYOUTIOMODE4_RW. In the case where the iomode of any held layout segment is not LAYOUTIOMODE4_RW, the server should return the error NFS4ERR_BAD_IOMODE. For the case where the client does not hold matching layout segment(s) for the defined byte-range, the server should return the error NFS4ERR_BAD_LAYOUT.

LAYOUTCOMMIT操作提交由当前文件句柄、客户端ID(源自前面序列操作中的会话ID)、字节范围和状态ID表示的布局中的更改。由于布局是可分的,因此可以提交通过LAYOUTGET检索的布局的较小部分。提交的字节范围通过字节范围(loca_偏移量和loca_长度)指定。此字节范围必须与先前通过LAYOUTGET(第18.43节)授予的一个或多个现有布局重叠,每个布局的iomode为LAYOUTIOMODE4_RW。如果任何保留的布局段的iomode不是LAYOUTIOMODE4_RW,服务器应返回错误NFS4ERR_BAD_iomode。对于客户端没有为定义的字节范围保留匹配的布局段的情况,服务器应返回错误NFS4ERR_BAD_LAYOU。

The LAYOUTCOMMIT operation indicates that the client has completed writes using a layout obtained by a previous LAYOUTGET. The client may have only written a subset of the data range it previously requested. LAYOUTCOMMIT allows it to commit or discard provisionally allocated space and to update the server with a new end-of-file. The layout referenced by LAYOUTCOMMIT is still valid after the operation completes and can be continued to be referenced by the client ID, filehandle, byte-range, layout type, and stateid.

LAYOUTCOMMIT操作表示客户端已使用上一个LAYOUTGET获得的布局完成写入。客户端可能只写入了其先前请求的数据范围的子集。LAYOUTCOMMIT允许它提交或放弃临时分配的空间,并使用新的文件结尾更新服务器。LAYOUTCOMMIT引用的布局在操作完成后仍然有效,并且可以继续由客户端ID、文件句柄、字节范围、布局类型和stateid引用。

If the loca_reclaim field is set to TRUE, this indicates that the client is attempting to commit changes to a layout after the restart of the metadata server during the metadata server's recovery grace

如果loca_Reclain字段设置为TRUE,则表示在元数据服务器恢复期间重新启动元数据服务器后,客户端正试图提交对布局的更改

period (see Section 12.7.4). This type of request may be necessary when the client has uncommitted writes to provisionally allocated byte-ranges of a file that were sent to the storage devices before the restart of the metadata server. In this case, the layout provided by the client MUST be a subset of a writable layout that the client held immediately before the restart of the metadata server. The value of the field loca_stateid MUST be a value that the metadata server returned before it restarted. The metadata server is free to accept or reject this request based on its own internal metadata consistency checks. If the metadata server finds that the layout provided by the client does not pass its consistency checks, it MUST reject the request with the status NFS4ERR_RECLAIM_BAD. The successful completion of the LAYOUTCOMMIT request with loca_reclaim set to TRUE does NOT provide the client with a layout for the file. It simply commits the changes to the layout specified in the loca_layoutupdate field. To obtain a layout for the file, the client must send a LAYOUTGET request to the server after the server's grace period has expired. If the metadata server receives a LAYOUTCOMMIT request with loca_reclaim set to TRUE when the metadata server is not in its recovery grace period, it MUST reject the request with the status NFS4ERR_NO_GRACE.

期间(见第12.7.4节)。当客户端对在元数据服务器重新启动之前发送到存储设备的文件的临时分配字节范围进行未提交写入时,可能需要这种类型的请求。在这种情况下,客户机提供的布局必须是在元数据服务器重新启动之前客户机持有的可写布局的子集。字段loca_stateid的值必须是元数据服务器重新启动前返回的值。元数据服务器可以根据自己的内部元数据一致性检查自由接受或拒绝此请求。如果元数据服务器发现客户端提供的布局未通过一致性检查,则必须拒绝状态为NFS4ERR_reclain_BAD的请求。loca_Reclain设置为TRUE时成功完成LAYOUTCOMMIT请求不会为客户端提供文件的布局。它只是将更改提交到loca_layoutupdate字段中指定的布局。要获取文件的布局,客户端必须在服务器的宽限期到期后向服务器发送LAYOUTGET请求。如果元数据服务器未处于恢复宽限期时,元数据服务器接收到loca_Recall设置为TRUE的LAYOUTCOMMIT请求,则它必须以NFS4ERR_NO_grace状态拒绝该请求。

Setting the loca_reclaim field to TRUE is required if and only if the committed layout was acquired before the metadata server restart. If the client is committing a layout that was acquired during the metadata server's grace period, it MUST set the "reclaim" field to FALSE.

如果并且仅当在元数据服务器重新启动之前获取了提交的布局时,才需要将loca_Reclain字段设置为TRUE。如果客户端正在提交在元数据服务器的宽限期内获取的布局,则必须将“回收”字段设置为FALSE。

The loca_stateid is a layout stateid value as returned by previously successful layout operations (see Section 12.5.3).

loca_stateid是先前成功布局操作返回的布局stateid值(见第12.5.3节)。

The loca_last_write_offset field specifies the offset of the last byte written by the client previous to the LAYOUTCOMMIT. Note that this value is never equal to the file's size (at most it is one byte less than the file's size) and MUST be less than or equal to NFS4_MAXFILEOFF. Also, loca_last_write_offset MUST overlap the range described by loca_offset and loca_length. The metadata server may use this information to determine whether the file's size needs to be updated. If the metadata server updates the file's size as the result of the LAYOUTCOMMIT operation, it must return the new size (locr_newsize.ns_size) as part of the results.

loca_last_write_offset字段指定LAYOUTCOMMIT之前客户端写入的最后一个字节的偏移量。请注意,此值永远不等于文件大小(最多比文件大小小一个字节),并且必须小于或等于nfs4u MAXFILEOFF。此外,loca_最后一次写入_偏移量必须与loca_偏移量和loca_长度描述的范围重叠。元数据服务器可以使用此信息确定是否需要更新文件大小。如果元数据服务器作为LAYOUTCOMMIT操作的结果更新了文件的大小,则它必须返回新的大小(locr_newsize.ns_size)作为结果的一部分。

The loca_time_modify field allows the client to suggest a modification time it would like the metadata server to set. The metadata server may use the suggestion or it may use the time of the LAYOUTCOMMIT operation to set the modification time. If the metadata server uses the client-provided modification time, it should ensure that time does not flow backwards. If the client wants to force the

loca_time_modify字段允许客户端建议它希望元数据服务器设置的修改时间。元数据服务器可以使用该建议,也可以使用LAYOUTCOMMIT操作的时间来设置修改时间。如果元数据服务器使用客户端提供的修改时间,则应确保时间不会倒流。如果客户想要强制

metadata server to set an exact time, the client should use a SETATTR operation in a COMPOUND right after LAYOUTCOMMIT. See Section 12.5.4 for more details. If the client desires the resultant modification time, it should construct the COMPOUND so that a GETATTR follows the LAYOUTCOMMIT.

元数据服务器要设置准确的时间,客户机应在LAYOUTCOMMIT之后立即在化合物中使用SETATTR操作。详见第12.5.4节。如果客户机希望得到修改时间,那么它应该构造化合物,以便GETATTR跟随LAYOUTCOMMIT。

The loca_layoutupdate argument to LAYOUTCOMMIT provides a mechanism for a client to provide layout-specific updates to the metadata server. For example, the layout update can describe what byte-ranges of the original layout have been used and what byte-ranges can be deallocated. There is no NFSv4.1 file layout-specific layoutupdate4 structure.

LAYOUTCOMMIT的loca_layoutupdate参数为客户端提供了一种向元数据服务器提供布局特定更新的机制。例如,布局更新可以描述使用了原始布局的哪些字节范围以及可以取消分配哪些字节范围。没有特定于NFSv4.1文件布局的layoutupdate4结构。

The layout information is more verbose for block devices than for objects and files because the latter two hide the details of block allocation behind their storage protocols. At the minimum, the client needs to communicate changes to the end-of-file location back to the server, and, if desired, its view of the file's modification time. For block/volume layouts, it needs to specify precisely which blocks have been used.

块设备的布局信息比对象和文件的布局信息更详细,因为后两者在其存储协议后面隐藏了块分配的细节。至少,客户机需要将文件末尾位置的更改传回服务器,如果需要,还需要将文件修改时间的视图传回服务器。对于块/体积布局,需要精确指定已使用的块。

If the layout identified in the arguments does not exist, the error NFS4ERR_BADLAYOUT is returned. The layout being committed may also be rejected if it does not correspond to an existing layout with an iomode of LAYOUTIOMODE4_RW.

如果参数中标识的布局不存在,则返回错误NFS4ERR_BADLAYOUT。如果提交的布局与iomode为LAYOUTIOMODE4_RW的现有布局不一致,也可能会被拒绝。

On success, the current filehandle retains its value and the current stateid retains its value.

成功时,当前文件句柄保留其值,当前stateid保留其值。

18.42.4. IMPLEMENTATION
18.42.4. 实施

The client MAY also use LAYOUTCOMMIT with the loca_reclaim field set to TRUE to convey hints to modified file attributes or to report layout-type specific information such as I/O errors for object-based storage layouts, as normally done during normal operation. Doing so may help the metadata server to recover files more efficiently after restart. For example, some file system implementations may require expansive recovery of file system objects if the metadata server does not get a positive indication from all clients holding a LAYOUTIOMODE4_RW layout that they have successfully completed all their writes. Sending a LAYOUTCOMMIT (if required) and then following with LAYOUTRETURN can provide such an indication and allow for graceful and efficient recovery.

客户端还可以使用LAYOUTCOMMIT,并将loca_Reclain字段设置为TRUE,以向修改的文件属性传递提示,或报告布局类型特定的信息,例如基于对象的存储布局的I/O错误,这与正常操作期间通常做的一样。这样做可以帮助元数据服务器在重新启动后更高效地恢复文件。例如,如果元数据服务器没有从持有LAYOUTIOMODE4_RW布局的所有客户端获得成功完成所有写入的肯定指示,则某些文件系统实现可能需要扩展恢复文件系统对象。发送一个LAYOUTCOMMIT(如果需要),然后使用LAYOUTRETURN可以提供这样一个指示,并允许优雅而高效的恢复。

If loca_reclaim is TRUE, the metadata server is free to either examine or ignore the value in the field loca_stateid. The metadata server implementation might or might not encode in its layout stateid information that allows the metadate server to perform a consistency check on the LAYOUTCOMMIT request.

如果loca_Reclain为TRUE,则元数据服务器可以自由检查或忽略loca_stateid字段中的值。元数据服务器实现可能在其布局stateid信息中编码,也可能不编码,该信息允许metadate服务器对LAYOUTCOMMIT请求执行一致性检查。

18.43. Operation 50: LAYOUTGET - Get Layout Information
18.43. 操作50:LAYOUTGET-获取布局信息
18.43.1. ARGUMENT
18.43.1. 论点
   struct LAYOUTGET4args {
           /* CURRENT_FH: file */
           bool                    loga_signal_layout_avail;
           layouttype4             loga_layout_type;
           layoutiomode4           loga_iomode;
           offset4                 loga_offset;
           length4                 loga_length;
           length4                 loga_minlength;
           stateid4                loga_stateid;
           count4                  loga_maxcount;
   };
        
   struct LAYOUTGET4args {
           /* CURRENT_FH: file */
           bool                    loga_signal_layout_avail;
           layouttype4             loga_layout_type;
           layoutiomode4           loga_iomode;
           offset4                 loga_offset;
           length4                 loga_length;
           length4                 loga_minlength;
           stateid4                loga_stateid;
           count4                  loga_maxcount;
   };
        
18.43.2. RESULT
18.43.2. 后果
   struct LAYOUTGET4resok {
           bool               logr_return_on_close;
           stateid4           logr_stateid;
           layout4            logr_layout<>;
   };
        
   struct LAYOUTGET4resok {
           bool               logr_return_on_close;
           stateid4           logr_stateid;
           layout4            logr_layout<>;
   };
        
   union LAYOUTGET4res switch (nfsstat4 logr_status) {
   case NFS4_OK:
           LAYOUTGET4resok     logr_resok4;
   case NFS4ERR_LAYOUTTRYLATER:
           bool                logr_will_signal_layout_avail;
   default:
           void;
   };
        
   union LAYOUTGET4res switch (nfsstat4 logr_status) {
   case NFS4_OK:
           LAYOUTGET4resok     logr_resok4;
   case NFS4ERR_LAYOUTTRYLATER:
           bool                logr_will_signal_layout_avail;
   default:
           void;
   };
        
18.43.3. DESCRIPTION
18.43.3. 描述

The LAYOUTGET operation requests a layout from the metadata server for reading or writing the file given by the filehandle at the byte-range specified by offset and length. Layouts are identified by the client ID (derived from the session ID in the preceding SEQUENCE operation), current filehandle, layout type (loga_layout_type), and

LAYOUTGET操作从元数据服务器请求一个布局,以便在偏移量和长度指定的字节范围内读取或写入filehandle给定的文件。布局由客户端ID(从前面序列操作中的会话ID派生)、当前文件句柄、布局类型(loga_layout_type)和

the layout stateid (loga_stateid). The use of the loga_iomode field depends upon the layout type, but should reflect the client's data access intent.

布局stateid(loga_stateid)。loga_iomode字段的使用取决于布局类型,但应反映客户端的数据访问意图。

If the metadata server is in a grace period, and does not persist layouts and device ID to device address mappings, then it MUST return NFS4ERR_GRACE (see Section 8.4.2.1).

如果元数据服务器处于宽限期,并且没有持久化布局和设备ID到设备地址的映射,那么它必须返回NFS4ERR_宽限期(参见第8.4.2.1节)。

The LAYOUTGET operation returns layout information for the specified byte-range: a layout. The client actually specifies two ranges, both starting at the offset in the loga_offset field. The first range is between loga_offset and loga_offset + loga_length - 1 inclusive. This range indicates the desired range the client wants the layout to cover. The second range is between loga_offset and loga_offset + loga_minlength - 1 inclusive. This range indicates the required range the client needs the layout to cover. Thus, loga_minlength MUST be less than or equal to loga_length.

LAYOUTGET操作返回指定字节范围的布局信息:布局。客户机实际上指定了两个范围,都从loga_offset字段中的偏移量开始。第一个范围介于loga_偏移量和loga_偏移量+loga_长度-1之间(含1)。此范围表示客户端希望布局覆盖的所需范围。第二个范围介于loga_offset和loga_offset+loga_minlength-1之间(包括loga_offset和loga_minlength-1)。此范围表示客户端需要布局覆盖的所需范围。因此,loga_minlength必须小于或等于loga_length。

When a length field is set to NFS4_UINT64_MAX, this indicates a desire (when loga_length is NFS4_UINT64_MAX) or requirement (when loga_minlength is NFS4_UINT64_MAX) to get a layout from loga_offset through the end-of-file, regardless of the file's length.

当长度字段设置为NFS4_UINT64_MAX时,这表示希望(当loga_长度为NFS4_UINT64_MAX时)或要求(当loga_minlength为NFS4_UINT64_MAX时)从loga_偏移量到文件末尾获得布局,而不管文件的长度如何。

The following rules govern the relationships among, and the minima of, loga_length, loga_minlength, and loga_offset.

以下规则控制loga_length、loga_minlength和loga_offset之间的关系和最小值。

o If loga_length is less than loga_minlength, the metadata server MUST return NFS4ERR_INVAL.

o 如果loga_length小于loga_minlength,元数据服务器必须返回NFS4ERR_INVAL。

o If loga_minlength is zero, this is an indication to the metadata server that the client desires any layout at offset loga_offset or less that the metadata server has "readily available". Readily is subjective, and depends on the layout type and the pNFS server implementation. For example, some metadata servers might have to pre-allocate stable storage when they receive a request for a range of a file that goes beyond the file's current length. If loga_minlength is zero and loga_length is greater than zero, this tells the metadata server what range of the layout the client would prefer to have. If loga_length and loga_minlength are both zero, then the client is indicating that it desires a layout of any length with the ending offset of the range no less than the value specified loga_offset, and the starting offset at or below loga_offset. If the metadata server does not have a layout that is readily available, then it MUST return NFS4ERR_LAYOUTTRYLATER.

o 如果loga_minlength为零,则这向元数据服务器表示客户端希望在偏移量loga_offset或更小的位置进行任何布局,即元数据服务器“随时可用”。这是主观的,取决于布局类型和pNFS服务器实现。例如,某些元数据服务器在收到超出文件当前长度的文件范围的请求时,可能必须预先分配稳定存储。如果loga_minlength为零且loga_length大于零,则会告诉元数据服务器客户端希望具有的布局范围。如果loga_length和loga_minlength均为零,则客户机表示希望布局为任意长度,其范围的结束偏移量不小于指定的loga_offset值,且起始偏移量等于或低于loga_offset。如果元数据服务器没有现成可用的布局,则必须返回NFS4ERR_layouttylater。

o If the sum of loga_offset and loga_minlength exceeds NFS4_UINT64_MAX, and loga_minlength is not NFS4_UINT64_MAX, the error NFS4ERR_INVAL MUST result.

o 如果loga_偏移量和loga_最小长度之和超过NFS4_UINT64_MAX,且loga_最小长度不是NFS4_UINT64_MAX,则必须产生错误NFS4ERR_INVAL。

o If the sum of loga_offset and loga_length exceeds NFS4_UINT64_MAX, and loga_length is not NFS4_UINT64_MAX, the error NFS4ERR_INVAL MUST result.

o 如果loga_偏移量和loga_长度之和超过NFS4_UINT64_MAX,且loga_长度不是NFS4_UINT64_MAX,则必须产生错误NFS4ERR_INVAL。

After the metadata server has performed the above checks on loga_offset, loga_minlength, and loga_offset, the metadata server MUST return a layout according to the rules in Table 13.

元数据服务器对loga_offset、loga_minlength和loga_offset执行上述检查后,元数据服务器必须根据表13中的规则返回布局。

Acceptable layouts based on loga_minlength. Note: u64m = NFS4_UINT64_MAX; a_off = loga_offset; a_minlen = loga_minlength.

基于loga_minlength的可接受布局。注:u64m=NFS4\u UINT64\u最大值;a_off=loga_偏移量;a_minlen=loga_minlength。

   +-----------+-----------+----------+----------+---------------------+
   | Layout    | Layout    | Layout   | Layout   | Layout length of    |
   | iomode of | a_minlen  | iomode   | offset   | reply               |
   | request   | of        | of reply | of reply |                     |
   |           | request   |          |          |                     |
   +-----------+-----------+----------+----------+---------------------+
   | _READ     | u64m      | MAY be   | MUST be  | MUST be >= file     |
   |           |           | _READ    | <= a_off | length - layout     |
   |           |           |          |          | offset              |
   | _READ     | u64m      | MAY be   | MUST be  | MUST be u64m        |
   |           |           | _RW      | <= a_off |                     |
   | _READ     | > 0 and < | MAY be   | MUST be  | MUST be >= MIN(file |
   |           | u64m      | _READ    | <= a_off | length, a_minlen +  |
   |           |           |          |          | a_off) - layout     |
   |           |           |          |          | offset              |
   | _READ     | > 0 and < | MAY be   | MUST be  | MUST be >= a_off -  |
   |           | u64m      | _RW      | <= a_off | layout offset +     |
   |           |           |          |          | a_minlen            |
   | _READ     | 0         | MAY be   | MUST be  | MUST be > 0         |
   |           |           | _READ    | <= a_off |                     |
   | _READ     | 0         | MAY be   | MUST be  | MUST be > 0         |
   |           |           | _RW      | <= a_off |                     |
   | _RW       | u64m      | MUST be  | MUST be  | MUST be u64m        |
   |           |           | _RW      | <= a_off |                     |
   | _RW       | > 0 and < | MUST be  | MUST be  | MUST be >= a_off -  |
   |           | u64m      | _RW      | <= a_off | layout offset +     |
   |           |           |          |          | a_minlen            |
   | _RW       | 0         | MUST be  | MUST be  | MUST be > 0         |
   |           |           | _RW      | <= a_off |                     |
   +-----------+-----------+----------+----------+---------------------+
        
   +-----------+-----------+----------+----------+---------------------+
   | Layout    | Layout    | Layout   | Layout   | Layout length of    |
   | iomode of | a_minlen  | iomode   | offset   | reply               |
   | request   | of        | of reply | of reply |                     |
   |           | request   |          |          |                     |
   +-----------+-----------+----------+----------+---------------------+
   | _READ     | u64m      | MAY be   | MUST be  | MUST be >= file     |
   |           |           | _READ    | <= a_off | length - layout     |
   |           |           |          |          | offset              |
   | _READ     | u64m      | MAY be   | MUST be  | MUST be u64m        |
   |           |           | _RW      | <= a_off |                     |
   | _READ     | > 0 and < | MAY be   | MUST be  | MUST be >= MIN(file |
   |           | u64m      | _READ    | <= a_off | length, a_minlen +  |
   |           |           |          |          | a_off) - layout     |
   |           |           |          |          | offset              |
   | _READ     | > 0 and < | MAY be   | MUST be  | MUST be >= a_off -  |
   |           | u64m      | _RW      | <= a_off | layout offset +     |
   |           |           |          |          | a_minlen            |
   | _READ     | 0         | MAY be   | MUST be  | MUST be > 0         |
   |           |           | _READ    | <= a_off |                     |
   | _READ     | 0         | MAY be   | MUST be  | MUST be > 0         |
   |           |           | _RW      | <= a_off |                     |
   | _RW       | u64m      | MUST be  | MUST be  | MUST be u64m        |
   |           |           | _RW      | <= a_off |                     |
   | _RW       | > 0 and < | MUST be  | MUST be  | MUST be >= a_off -  |
   |           | u64m      | _RW      | <= a_off | layout offset +     |
   |           |           |          |          | a_minlen            |
   | _RW       | 0         | MUST be  | MUST be  | MUST be > 0         |
   |           |           | _RW      | <= a_off |                     |
   +-----------+-----------+----------+----------+---------------------+
        

Table 13

表13

If loga_minlength is not zero and the metadata server cannot return a layout according to the rules in Table 13, then the metadata server MUST return the error NFS4ERR_BADLAYOUT. If loga_minlength is zero and the metadata server cannot or will not return a layout according

如果loga_minlength不为零,并且元数据服务器无法根据表13中的规则返回布局,那么元数据服务器必须返回错误NFS4ERR_BADLAYOUT。如果loga_minlength为零,元数据服务器无法或不会根据

to the rules in Table 13, then the metadata server MUST return the error NFS4ERR_LAYOUTTRYLATER. Assuming that loga_length is greater than loga_minlength or equal to zero, the metadata server SHOULD return a layout according to the rules in Table 14.

对于表13中的规则,元数据服务器必须返回错误NFS4ERR_layouttylater。假设loga_length大于loga_minlength或等于零,元数据服务器应该根据表14中的规则返回布局。

Desired layouts based on loga_length. The rules of Table 13 MUST be applied first. Note: u64m = NFS4_UINT64_MAX; a_off = loga_offset; a_len = loga_length.

基于loga_长度的所需布局。必须首先应用表13中的规则。注:u64m=NFS4\u UINT64\u最大值;a_off=loga_偏移量;a_len=loga_长度。

   +------------+------------+-----------+-----------+-----------------+
   | Layout     | Layout     | Layout    | Layout    | Layout length   |
   | iomode of  | a_len of   | iomode of | offset of | of reply        |
   | request    | request    | reply     | reply     |                 |
   +------------+------------+-----------+-----------+-----------------+
   | _READ      | u64m       | MAY be    | MUST be   | SHOULD be u64m  |
   |            |            | _READ     | <= a_off  |                 |
   | _READ      | u64m       | MAY be    | MUST be   | SHOULD be u64m  |
   |            |            | _RW       | <= a_off  |                 |
   | _READ      | > 0 and <  | MAY be    | MUST be   | SHOULD be >=    |
   |            | u64m       | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _READ      | > 0 and <  | MAY be    | MUST be   | SHOULD be >=    |
   |            | u64m       | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _READ      | 0          | MAY be    | MUST be   | SHOULD be >     |
   |            |            | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   | _READ      | 0          | MAY be    | MUST be   | SHOULD be >     |
   |            |            | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   | _RW        | u64m       | MUST be   | MUST be   | SHOULD be u64m  |
   |            |            | _RW       | <= a_off  |                 |
   | _RW        | > 0 and <  | MUST be   | MUST be   | SHOULD be >=    |
   |            | u64m       | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _RW        | 0          | MUST be   | MUST be   | SHOULD be >     |
   |            |            | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   +------------+------------+-----------+-----------+-----------------+
        
   +------------+------------+-----------+-----------+-----------------+
   | Layout     | Layout     | Layout    | Layout    | Layout length   |
   | iomode of  | a_len of   | iomode of | offset of | of reply        |
   | request    | request    | reply     | reply     |                 |
   +------------+------------+-----------+-----------+-----------------+
   | _READ      | u64m       | MAY be    | MUST be   | SHOULD be u64m  |
   |            |            | _READ     | <= a_off  |                 |
   | _READ      | u64m       | MAY be    | MUST be   | SHOULD be u64m  |
   |            |            | _RW       | <= a_off  |                 |
   | _READ      | > 0 and <  | MAY be    | MUST be   | SHOULD be >=    |
   |            | u64m       | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _READ      | > 0 and <  | MAY be    | MUST be   | SHOULD be >=    |
   |            | u64m       | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _READ      | 0          | MAY be    | MUST be   | SHOULD be >     |
   |            |            | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   | _READ      | 0          | MAY be    | MUST be   | SHOULD be >     |
   |            |            | _READ     | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   | _RW        | u64m       | MUST be   | MUST be   | SHOULD be u64m  |
   |            |            | _RW       | <= a_off  |                 |
   | _RW        | > 0 and <  | MUST be   | MUST be   | SHOULD be >=    |
   |            | u64m       | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset + a_len  |
   | _RW        | 0          | MUST be   | MUST be   | SHOULD be >     |
   |            |            | _RW       | <= a_off  | a_off - layout  |
   |            |            |           |           | offset          |
   +------------+------------+-----------+-----------+-----------------+
        

Table 14

表14

The loga_stateid field specifies a valid stateid. If a layout is not currently held by the client, the loga_stateid field represents a stateid reflecting the correspondingly valid open, byte-range lock, or delegation stateid. Once a layout is held on the file by the

loga_stateid字段指定有效的stateid。如果客户端当前未持有布局,则loga_stateid字段表示反映相应有效打开、字节范围锁或委托stateid的stateid。一旦布局被

client, the loga_stateid field MUST be a stateid as returned from a previous LAYOUTGET or LAYOUTRETURN operation or provided by a CB_LAYOUTRECALL operation (see Section 12.5.3).

在客户端,loga_stateid字段必须是从以前的LAYOUTGET或LAYOUTRETURN操作返回的stateid,或由CB_LayoutRetCall操作提供的stateid(见第12.5.3节)。

The loga_maxcount field specifies the maximum layout size (in bytes) that the client can handle. If the size of the layout structure exceeds the size specified by maxcount, the metadata server will return the NFS4ERR_TOOSMALL error.

loga_maxcount字段指定客户端可以处理的最大布局大小(以字节为单位)。如果布局结构的大小超过maxcount指定的大小,元数据服务器将返回NFS4ERR_Toosall错误。

The returned layout is expressed as an array, logr_layout, with each element of type layout4. If a file has a single striping pattern, then logr_layout SHOULD contain just one entry. Otherwise, if the requested range overlaps more than one striping pattern, logr_layout will contain the required number of entries. The elements of logr_layout MUST be sorted in ascending order of the value of the lo_offset field of each element. There MUST be no gaps or overlaps in the range between two successive elements of logr_layout. The lo_iomode field in each element of logr_layout MUST be the same.

返回的布局表示为一个数组logr_layout,每个元素的类型为layout4。如果一个文件有一个条带模式,那么logr\u布局应该只包含一个条目。否则,如果请求的范围与多个条带模式重叠,则logr_布局将包含所需数量的条目。logr_布局的元素必须按照每个元素的lou offset字段值的升序排序。logr_布局的两个连续元素之间的范围内不得有间隙或重叠。logr_布局的每个元素中的lo_iomode字段必须相同。

Table 13 and Table 14 both refer to a returned layout iomode, offset, and length. Because the returned layout is encoded in the logr_layout array, more description is required.

表13和表14都引用了返回的布局iomode、偏移量和长度。因为返回的布局编码在logr_布局数组中,所以需要更多描述。

iomode

iomode

The value of the returned layout iomode listed in Table 13 and Table 14 is equal to the value of the lo_iomode field in each element of logr_layout. As shown in Table 13 and Table 14, the metadata server MAY return a layout with an lo_iomode different from the requested iomode (field loga_iomode of the request). If it does so, it MUST ensure that the lo_iomode is more permissive than the loga_iomode requested. For example, this behavior allows an implementation to upgrade LAYOUTIOMODE4_READ requests to LAYOUTIOMODE4_RW requests at its discretion, within the limits of the layout type specific protocol. A lo_iomode of either LAYOUTIOMODE4_READ or LAYOUTIOMODE4_RW MUST be returned.

表13和表14中列出的返回布局iomode的值等于logr_布局的每个元素中lo_iomode字段的值。如表13和表14所示,元数据服务器可能返回一个布局,其中lo_iomode与请求的iomode不同(请求的loga_iomode字段)。如果这样做,则必须确保lo_iomode比请求的loga_iomode更具许可性。例如,此行为允许实现在布局类型特定协议的限制范围内,自行将LAYOUTIOMODE4_读取请求升级为LAYOUTIOMODE4_RW请求。必须返回LAYOUTIOMODE4_READ或LAYOUTIOMODE4_RW的lo_iomode。

offset

抵消

The value of the returned layout offset listed in Table 13 and Table 14 is always equal to the lo_offset field of the first element logr_layout.

表13和表14中列出的返回布局偏移值始终等于第一个元素logr_布局的lo_偏移字段。

length

When setting the value of the returned layout length, the situation is complicated by the possibility that the special layout length value NFS4_UINT64_MAX is involved. For a

设置返回的布局长度值时,由于可能涉及特殊布局长度值NFS4_UINT64_MAX,情况变得复杂。暂时

logr_layout array of N elements, the lo_length field in the first N-1 elements MUST NOT be NFS4_UINT64_MAX. The lo_length field of the last element of logr_layout can be NFS4_UINT64_MAX under some conditions as described in the following list.

logr_布局N个元素的数组,前N-1个元素中的lo_长度字段不能是NFS4_UINT64_MAX。在下列列表中描述的某些条件下,logr_布局的最后一个元素的lo_长度字段可以是NFS4_UINT64_MAX。

* If an applicable rule of Table 13 states that the metadata server MUST return a layout of length NFS4_UINT64_MAX, then the lo_length field of the last element of logr_layout MUST be NFS4_UINT64_MAX.

* 如果表13中的适用规则规定元数据服务器必须返回长度为NFS4_UINT64_MAX的布局,则logr_布局的最后一个元素的lou length字段必须为NFS4_UINT64_MAX。

* If an applicable rule of Table 13 states that the metadata server MUST NOT return a layout of length NFS4_UINT64_MAX, then the lo_length field of the last element of logr_layout MUST NOT be NFS4_UINT64_MAX.

* 如果表13中的适用规则规定元数据服务器不得返回长度为NFS4_UINT64_MAX的布局,则logr_布局的最后一个元素的lou length字段不得为NFS4_UINT64_MAX。

* If an applicable rule of Table 14 states that the metadata server SHOULD return a layout of length NFS4_UINT64_MAX, then the lo_length field of the last element of logr_layout SHOULD be NFS4_UINT64_MAX.

* 如果表14中的适用规则规定元数据服务器应返回长度为NFS4_UINT64_MAX的布局,则logr_布局的最后一个元素的lou length字段应为NFS4_UINT64_MAX。

* When the value of the returned layout length of Table 13 and Table 14 is not NFS4_UINT64_MAX, then the returned layout length is equal to the sum of the lo_length fields of each element of logr_layout.

* 当表13和表14返回的布局长度值不是NFS4_UINT64_MAX时,则返回的布局长度等于logr_布局的每个元素的lo_长度字段的总和。

The logr_return_on_close result field is a directive to return the layout before closing the file. When the metadata server sets this return value to TRUE, it MUST be prepared to recall the layout in the case in which the client fails to return the layout before close. For the metadata server that knows a layout must be returned before a close of the file, this return value can be used to communicate the desired behavior to the client and thus remove one extra step from the client's and metadata server's interaction.

logr_return_on_close result字段是在关闭文件之前返回布局的指令。当元数据服务器将此返回值设置为TRUE时,如果客户端在关闭前未能返回布局,则必须准备调用布局。对于知道必须在关闭文件之前返回布局的元数据服务器,此返回值可用于将所需行为传达给客户端,从而从客户端和元数据服务器的交互中删除一个额外步骤。

The logr_stateid stateid is returned to the client for use in subsequent layout related operations. See Sections 8.2, 12.5.3, and 12.5.5.2 for a further discussion and requirements.

logr_stateid stateid将返回给客户端,以便在后续与布局相关的操作中使用。有关进一步的讨论和要求,请参见第8.2节、第12.5.3节和第12.5.5.2节。

The format of the returned layout (lo_content) is specific to the layout type. The value of the layout type (lo_content.loc_type) for each of the elements of the array of layouts returned by the metadata server (logr_layout) MUST be equal to the loga_layout_type specified by the client. If it is not equal, the client SHOULD ignore the response as invalid and behave as if the metadata server returned an error, even if the client does have support for the layout type returned.

返回布局(LOU内容)的格式特定于布局类型。元数据服务器(logr_布局)返回的布局数组的每个元素的布局类型(lo_content.loc_type)的值必须等于客户端指定的loga_布局类型。如果不相等,则客户端应忽略响应,认为响应无效,并表现为元数据服务器返回错误,即使客户端确实支持返回的布局类型。

If neither the requested file nor its containing file system support layouts, the metadata server MUST return NFS4ERR_LAYOUTUNAVAILABLE. If the layout type is not supported, the metadata server MUST return NFS4ERR_UNKNOWN_LAYOUTTYPE. If layouts are supported but no layout matches the client provided layout identification, the metadata server MUST return NFS4ERR_BADLAYOUT. If an invalid loga_iomode is specified, or a loga_iomode of LAYOUTIOMODE4_ANY is specified, the metadata server MUST return NFS4ERR_BADIOMODE.

如果请求的文件及其包含的文件系统都不支持布局,则元数据服务器必须返回NFS4ERR_LAYOUTUNAVAILABLE。如果不支持布局类型,元数据服务器必须返回NFS4ERR_UNKNOWN_LAYOUTTYPE。如果支持布局,但没有与客户端提供的布局标识匹配的布局,则元数据服务器必须返回NFS4ERR_BADLAYOUT。如果指定了无效的loga_iomode,或者指定了LAYOUTIOMODE4_ANY的loga_iomode,元数据服务器必须返回NFS4ERR_BADIOMODE。

If the layout for the file is unavailable due to transient conditions, e.g., file sharing prohibits layouts, the metadata server MUST return NFS4ERR_LAYOUTTRYLATER.

如果文件的布局由于临时条件(例如,文件共享禁止布局)而不可用,则元数据服务器必须返回NFS4ERR_layouttylater。

If the layout request is rejected due to an overlapping layout recall, the metadata server MUST return NFS4ERR_RECALLCONFLICT. See Section 12.5.5.2 for details.

如果布局请求由于重叠的布局调用而被拒绝,则元数据服务器必须返回NFS4ERR_RECALLCONFLICT。详见第12.5.5.2节。

If the layout conflicts with a mandatory byte-range lock held on the file, and if the storage devices have no method of enforcing mandatory locks, other than through the restriction of layouts, the metadata server SHOULD return NFS4ERR_LOCKED.

如果布局与文件上的强制字节范围锁冲突,并且如果存储设备没有强制锁定的方法(通过布局限制除外),则元数据服务器应返回NFS4ERR_LOCKED。

If client sets loga_signal_layout_avail to TRUE, then it is registering with the client a "want" for a layout in the event the layout cannot be obtained due to resource exhaustion. If the metadata server supports and will honor the "want", the results will have logr_will_signal_layout_avail set to TRUE. If so, the client should expect a CB_RECALLABLE_OBJ_AVAIL operation to indicate that a layout is available.

如果客户端将loga_signal_layout_avail设置为TRUE,则在由于资源耗尽而无法获得布局的情况下,它正在向客户端注册布局的“想要”。如果元数据服务器支持并将遵守“want”,则结果将把logr\u will\u signal\u layout\u avail设置为TRUE。如果是这样的话,客户端应该期望一个CB_可重调_OBJ_AVAIL操作来指示布局可用。

On success, the current filehandle retains its value and the current stateid is updated to match the value as returned in the results.

成功后,当前filehandle将保留其值,并更新当前stateid以匹配结果中返回的值。

18.43.4. IMPLEMENTATION
18.43.4. 实施

Typically, LAYOUTGET will be called as part of a COMPOUND request after an OPEN operation and results in the client having location information for the file. This requires that loga_stateid be set to the special stateid that tells the metadata server to use the current stateid, which is set by OPEN (see Section 16.2.3.1.2). A client may also hold a layout across multiple OPENs. The client specifies a layout type that limits what kind of layout the metadata server will return. This prevents metadata servers from granting layouts that are unusable by the client.

通常,在打开操作后,LAYOUTGET将作为复合请求的一部分被调用,并导致客户端具有文件的位置信息。这要求将loga_stateid设置为特殊的stateid,告知元数据服务器使用当前的stateid,该stateid由OPEN设置(请参见第16.2.3.1.2节)。客户端还可以跨多个打开保存布局。客户端指定一种布局类型,该类型限制元数据服务器将返回的布局类型。这可以防止元数据服务器授予客户端无法使用的布局。

As indicated by Table 13 and Table 14, the specification of LAYOUTGET allows a pNFS client and server considerable flexibility. A pNFS client can take several strategies for sending LAYOUTGET. Some examples are as follows.

如表13和表14所示,LAYOUTGET的规范允许pNFS客户端和服务器具有相当大的灵活性。pNFS客户端可以采取多种策略发送LAYOUTGET。下面是一些例子。

o If LAYOUTGET is preceded by OPEN in the same COMPOUND request and the OPEN requests OPEN4_SHARE_ACCESS_READ access, the client might opt to request a _READ layout with loga_offset set to zero, loga_minlength set to zero, and loga_length set to NFS4_UINT64_MAX. If the file has space allocated to it, that space is striped over one or more storage devices, and there is either no conflicting layout or the concept of a conflicting layout does not apply to the pNFS server's layout type or implementation, then the metadata server might return a layout with a starting offset of zero, and a length equal to the length of the file, if not NFS4_UINT64_MAX. If the length of the file is not a multiple of the pNFS server's stripe width (see Section 13.2 for a formal definition), the metadata server might round up the returned layout's length.

o 如果LAYOUTGET在同一复合请求中以OPEN开头,且OPEN请求OPEN4_SHARE_ACCESS_READ ACCESS,则客户端可能选择请求loga_offset设置为零、loga_minlength设置为零、loga_length设置为NFS4_UINT64_MAX的_READ布局。如果文件已分配空间,该空间在一个或多个存储设备上分条,并且不存在冲突布局,或者冲突布局的概念不适用于pNFS服务器的布局类型或实现,那么元数据服务器可能返回一个起始偏移量为零、长度等于文件长度的布局,如果不是NFS4_UINT64_MAX。如果文件长度不是pNFS服务器条带宽度的倍数(有关正式定义,请参阅第13.2节),则元数据服务器可能会将返回的布局长度四舍五入。

o If LAYOUTGET is preceded by OPEN in the same COMPOUND request, and the OPEN requests OPEN4_SHARE_ACCESS_WRITE access and does not truncate the file, the client might opt to request a _RW layout with loga_offset set to zero, loga_minlength set to zero, and loga_length set to the file's current length (if known), or NFS4_UINT64_MAX. As with the previous case, under some conditions the metadata server might return a layout that covers the entire length of the file or beyond.

o 如果LAYOUTGET在同一复合请求中以OPEN开头,且OPEN请求OPEN4_SHARE_ACCESS_WRITE ACCESS且未截断文件,则客户端可能选择请求loga_offset设置为零、loga_minlength设置为零、loga_length设置为文件当前长度(如果已知)的_RW布局,或NFS4_UINT64_MAX。与前一种情况一样,在某些情况下,元数据服务器可能返回覆盖整个文件长度或更长的布局。

o This strategy is as above, but the OPEN truncates the file. In this case, the client might anticipate it will be writing to the file from offset zero, and so loga_offset and loga_minlength are set to zero, and loga_length is set to the value of threshold4_write_iosize. The metadata server might return a layout from offset zero with a length at least as long as threshold4_write_iosize.

o 此策略如上所述,但OPEN会截断文件。在这种情况下,客户端可能预期它将从偏移量0写入文件,因此loga_offset和loga_minlength设置为0,loga_length设置为threshold4_write_iosize的值。元数据服务器可能会从偏移量0返回长度至少与threshold4_write_iosize相同的布局。

o A process on the client invokes a request to read from offset 10000 for length 50000. The client is using buffered I/O, and has buffer sizes of 4096 bytes. The client intends to map the request of the process into a series of READ requests starting at offset 8192. The end offset needs to be higher than 10000 + 50000 = 60000, and the next offset that is a multiple of 4096 is 61440. The difference between 61440 and that starting offset of the layout is 53248 (which is the product of 4096 and 15). The value of threshold4_read_iosize is less than 53248, so the client sends a LAYOUTGET request with loga_offset set to 8192, loga_minlength set to 53248, and loga_length set to the file's length (if known)

o 客户端上的进程调用从偏移量10000读取长度为50000的请求。客户端使用缓冲I/O,缓冲区大小为4096字节。客户机打算将进程的请求映射为从偏移量8192开始的一系列读取请求。末端偏移量需要大于10000+50000=60000,下一个偏移量是4096的倍数是61440。61440和布局的起始偏移量之间的差值为53248(是4096和15的乘积)。threshold4_read_iosize的值小于53248,因此客户端发送一个LAYOUTGET请求,loga_offset设置为8192,loga_minlength设置为53248,loga_length设置为文件长度(如果已知)

minus 8192 or NFS4_UINT64_MAX (if the file's length is not known). Since this LAYOUTGET request exceeds the metadata server's threshold, it grants the layout, possibly with an initial offset of zero, with an end offset of at least 8192 + 53248 - 1 = 61439, but preferably a layout with an offset aligned on the stripe width and a length that is a multiple of the stripe width.

减去8192或NFS4_UINT64_MAX(如果文件长度未知)。由于此LAYOUTGET请求超过了元数据服务器的阈值,因此它授予布局(初始偏移量可能为零)端偏移量至少为8192+53248-1=61439,但最好是偏移量与条带宽度对齐且长度为条带宽度的倍数的布局。

o This strategy is as above, but the client is not using buffered I/O, and instead all internal I/O requests are sent directly to the server. The LAYOUTGET request has loga_offset equal to 10000 and loga_minlength set to 50000. The value of loga_length is set to the length of the file. The metadata server is free to return a layout that fully overlaps the requested range, with a starting offset and length aligned on the stripe width.

o 此策略如上所述,但客户端不使用缓冲I/O,而是将所有内部I/O请求直接发送到服务器。LAYOUTGET请求的loga_偏移量等于10000,loga_minlength设置为50000。loga_length的值设置为文件的长度。元数据服务器可以自由返回与请求范围完全重叠的布局,起始偏移量和长度与条带宽度对齐。

o Again, a process on the client invokes a request to read from offset 10000 for length 50000 (i.e. a range with a starting offset of 10000 and an ending offset of 69999), and buffered I/O is in use. The client is expecting that the server might not be able to return the layout for the full I/O range. The client intends to map the request of the process into a series of thirteen READ requests starting at offset 8192, each with length 4096, with a total length of 53248 (which equals 13 * 4096), which fully contains the range that client's process wants to read. Because the value of threshold4_read_iosize is equal to 4096, it is practical and reasonable for the client to use several LAYOUTGET operations to complete the series of READs. The client sends a LAYOUTGET request with loga_offset set to 8192, loga_minlength set to 4096, and loga_length set to 53248 or higher. The server will grant a layout possibly with an initial offset of zero, with an end offset of at least 8192 + 4096 - 1 = 12287, but preferably a layout with an offset aligned on the stripe width and a length that is a multiple of the stripe width. This will allow the client to make forward progress, possibly sending more LAYOUTGET operations for the remainder of the range.

o 同样,客户端上的进程调用从偏移量10000读取长度为50000的请求(即,起始偏移量为10000,结束偏移量为69999的范围),并且缓冲i/O正在使用中。客户端希望服务器可能无法返回完整I/O范围的布局。客户端打算将进程的请求映射为一系列13个读取请求,从偏移量8192开始,每个请求的长度为4096,总长度为53248(等于13*4096),其中完全包含客户端进程想要读取的范围。由于threshold4_read_iosize的值等于4096,因此客户端使用几个LAYOUTGET操作来完成一系列读取是实用和合理的。客户端发送一个LAYOUTGET请求,loga_offset设置为8192,loga_minlength设置为4096,loga_length设置为53248或更高。服务器将授予初始偏移量可能为零的布局,末端偏移量至少为8192+4096-1=12287,但最好是偏移量与条带宽度对齐且长度为条带宽度的倍数的布局。这将允许客户端向前推进,可能会在剩余范围内发送更多的LAYOUTGET操作。

o An NFS client detects a sequential read pattern, and so sends a LAYOUTGET operation that goes well beyond any current or pending read requests to the server. The server might likewise detect this pattern, and grant the LAYOUTGET request. Once the client reads from an offset of the file that represents 50% of the way through the range of the last layout it received, in order to avoid stalling I/O that would wait for a layout, the client sends more operations from an offset of the file that represents 50% of the way through the last layout it received. The client continues to request layouts with byte-ranges that are well in advance of the byte-ranges of recent and/or read requests of processes running on the client.

o NFS客户机检测到顺序读取模式,因此向服务器发送的LAYOUTGET操作远远超出任何当前或挂起的读取请求。服务器也可能检测到此模式,并授予LAYOUTGET请求。一旦客户机从文件的偏移量中读取数据,该偏移量表示其接收到的最后一个布局的50%,为了避免暂停等待布局的I/O,客户机将从文件的偏移量中发送更多操作,该偏移量表示其接收到的最后一个布局的50%。客户端继续请求具有字节范围的布局,这些字节范围远远超过客户端上运行的进程的最近和/或读取请求的字节范围。

o This strategy is as above, but the client fails to detect the pattern, but the server does. The next time the metadata server gets a LAYOUTGET, it returns a layout with a length that is well beyond loga_minlength.

o 此策略如上所述,但客户端无法检测模式,但服务器可以检测。下次元数据服务器获取LAYOUTGET时,它将返回一个长度远远超过loga_minlength的布局。

o A client is using buffered I/O, and has a long queue of write-behinds to process and also detects a sequential write pattern. It sends a LAYOUTGET for a layout that spans the range of the queued write-behinds and well beyond, including ranges beyond the filer's current length. The client continues to send LAYOUTGET operations once the write-behind queue reaches 50% of the maximum queue length.

o 客户机正在使用缓冲I/O,并且有一个很长的写入队列要处理,并且还检测到顺序写入模式。它为一个布局发送一个LAYOUTGET,该布局跨越排队写操作的滞后范围和远远超出的范围,包括超出文件服务器当前长度的范围。一旦写后队列达到最大队列长度的50%,客户端将继续发送LAYOUTGET操作。

Once the client has obtained a layout referring to a particular device ID, the metadata server MUST NOT delete the device ID until the layout is returned or revoked.

一旦客户端获得了引用特定设备ID的布局,元数据服务器就不能删除该设备ID,直到该布局被返回或撤销。

CB_NOTIFY_DEVICEID can race with LAYOUTGET. One race scenario is that LAYOUTGET returns a device ID for which the client does not have device address mappings, and the metadata server sends a CB_NOTIFY_DEVICEID to add the device ID to the client's awareness and meanwhile the client sends GETDEVICEINFO on the device ID. This scenario is discussed in Section 18.40.4. Another scenario is that the CB_NOTIFY_DEVICEID is processed by the client before it processes the results from LAYOUTGET. The client will send a GETDEVICEINFO on the device ID. If the results from GETDEVICEINFO are received before the client gets results from LAYOUTGET, then there is no longer a race. If the results from LAYOUTGET are received before the results from GETDEVICEINFO, the client can either wait for results of GETDEVICEINFO or send another one to get possibly more up-to-date device address mappings for the device ID.

CB_NOTIFY_DEVICEID可以与LAYOUTGET竞争。一种竞争场景是LAYOUTGET返回客户端没有设备地址映射的设备ID,元数据服务器发送CB_NOTIFY_DEVICEID将设备ID添加到客户端的感知中,同时客户端发送设备ID上的GETDEVICEINFO。此场景在第18.40.4节中讨论。另一种情况是,CB_NOTIFY_DEVICEID在处理LAYOUTGET的结果之前由客户端进行处理。客户端将在设备ID上发送GETDEVICEINFO。如果在客户端从LAYOUTGET获得结果之前收到GETDEVICEINFO的结果,则不再存在竞争。如果在GETDEVICEINFO的结果之前收到LAYOUTGET的结果,则客户端可以等待GETDEVICEINFO的结果,或者发送另一个结果,以获取设备ID的可能更多最新设备地址映射。

18.44. Operation 51: LAYOUTRETURN - Release Layout Information
18.44. 操作51:LAYOUTRETURN-发布布局信息
18.44.1. ARGUMENT
18.44.1. 论点
   /* Constants used for LAYOUTRETURN and CB_LAYOUTRECALL */
   const LAYOUT4_RET_REC_FILE      = 1;
   const LAYOUT4_RET_REC_FSID      = 2;
   const LAYOUT4_RET_REC_ALL       = 3;
        
   /* Constants used for LAYOUTRETURN and CB_LAYOUTRECALL */
   const LAYOUT4_RET_REC_FILE      = 1;
   const LAYOUT4_RET_REC_FSID      = 2;
   const LAYOUT4_RET_REC_ALL       = 3;
        
   enum layoutreturn_type4 {
           LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE,
           LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID,
           LAYOUTRETURN4_ALL  = LAYOUT4_RET_REC_ALL
   };
        
   enum layoutreturn_type4 {
           LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE,
           LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID,
           LAYOUTRETURN4_ALL  = LAYOUT4_RET_REC_ALL
   };
        
   struct layoutreturn_file4 {
           offset4         lrf_offset;
           length4         lrf_length;
           stateid4        lrf_stateid;
           /* layouttype4 specific data */
           opaque          lrf_body<>;
   };
        
   struct layoutreturn_file4 {
           offset4         lrf_offset;
           length4         lrf_length;
           stateid4        lrf_stateid;
           /* layouttype4 specific data */
           opaque          lrf_body<>;
   };
        
   union layoutreturn4 switch(layoutreturn_type4 lr_returntype) {
           case LAYOUTRETURN4_FILE:
                   layoutreturn_file4      lr_layout;
           default:
                   void;
   };
        
   union layoutreturn4 switch(layoutreturn_type4 lr_returntype) {
           case LAYOUTRETURN4_FILE:
                   layoutreturn_file4      lr_layout;
           default:
                   void;
   };
        
   struct LAYOUTRETURN4args {
           /* CURRENT_FH: file */
           bool                    lora_reclaim;
           layouttype4             lora_layout_type;
           layoutiomode4           lora_iomode;
           layoutreturn4           lora_layoutreturn;
   };
        
   struct LAYOUTRETURN4args {
           /* CURRENT_FH: file */
           bool                    lora_reclaim;
           layouttype4             lora_layout_type;
           layoutiomode4           lora_iomode;
           layoutreturn4           lora_layoutreturn;
   };
        
18.44.2. RESULT
18.44.2. 后果
   union layoutreturn_stateid switch (bool lrs_present) {
   case TRUE:
           stateid4                lrs_stateid;
   case FALSE:
           void;
   };
        
   union layoutreturn_stateid switch (bool lrs_present) {
   case TRUE:
           stateid4                lrs_stateid;
   case FALSE:
           void;
   };
        
   union LAYOUTRETURN4res switch (nfsstat4 lorr_status) {
   case NFS4_OK:
           layoutreturn_stateid    lorr_stateid;
   default:
           void;
   };
        
   union LAYOUTRETURN4res switch (nfsstat4 lorr_status) {
   case NFS4_OK:
           layoutreturn_stateid    lorr_stateid;
   default:
           void;
   };
        
18.44.3. DESCRIPTION
18.44.3. 描述

This operation returns from the client to the server one or more layouts represented by the client ID (derived from the session ID in the preceding SEQUENCE operation), lora_layout_type, and lora_iomode. When lr_returntype is LAYOUTRETURN4_FILE, the returned layout is further identified by the current filehandle, lrf_offset, lrf_length, and lrf_stateid. If the lrf_length field is NFS4_UINT64_MAX, all

此操作从客户机向服务器返回一个或多个布局,这些布局由客户机ID(源自前面序列操作中的会话ID)、lora_布局类型和lora_iomode表示。当lr_returntype为LAYOUTRETURN4_文件时,返回的布局由当前文件句柄、lrf_偏移量、lrf_长度和lrf_状态ID进一步标识。如果lrf_长度字段为NFS4_UINT64_MAX,则所有

bytes of the layout, starting at lrf_offset, are returned. When lr_returntype is LAYOUTRETURN4_FSID, the current filehandle is used to identify the file system and all layouts matching the client ID, the fsid of the file system, lora_layout_type, and lora_iomode are returned. When lr_returntype is LAYOUTRETURN4_ALL, all layouts matching the client ID, lora_layout_type, and lora_iomode are returned and the current filehandle is not used. After this call, the client MUST NOT use the returned layout(s) and the associated storage protocol to access the file data.

返回从lrf_偏移开始的布局字节。当lr_returntype为LAYOUTRETURN4_FSID时,当前文件句柄用于标识文件系统,并返回与客户端ID、文件系统的FSID、lora_layout_type和lora_iomode匹配的所有布局。当lr_returntype为LAYOUTRETURN4_ALL时,将返回与客户端ID、lora_layout_type和lora_iomode匹配的所有布局,并且不使用当前文件句柄。此调用后,客户端不得使用返回的布局和关联的存储协议访问文件数据。

If the set of layouts designated in the case of LAYOUTRETURN4_FSID or LAYOUTRETURN4_ALL is empty, then no error results. In the case of LAYOUTRETURN4_FILE, the byte-range specified is returned even if it is a subdivision of a layout previously obtained with LAYOUTGET, a combination of multiple layouts previously obtained with LAYOUTGET, or a combination including some layouts previously obtained with LAYOUTGET, and one or more subdivisions of such layouts. When the byte-range does not designate any bytes for which a layout is held for the specified file, client ID, layout type and mode, no error results. See Section 12.5.5.2.1.5 for considerations with "bulk" return of layouts.

如果在LAYOUTRETURN4_FSID或LAYOUTRETURN4_ALL的情况下指定的布局集为空,则不会产生错误。在LAYOUTRETURN4_文件的情况下,即使指定的字节范围是以前使用LAYOUTGET获得的布局的细分、以前使用LAYOUTGET获得的多个布局的组合,或者包括以前使用LAYOUTGET获得的一些布局的组合,以及此类布局的一个或多个细分,也会返回指定的字节范围。当字节范围未指定为指定文件、客户端ID、布局类型和模式保留布局的任何字节时,不会产生错误结果。有关“批量”返回布局的注意事项,请参见第12.5.5.2.1.5节。

The layout being returned may be a subset or superset of a layout specified by CB_LAYOUTRECALL. However, if it is a subset, the recall is not complete until the full recalled scope has been returned. Recalled scope refers to the byte-range in the case of LAYOUTRETURN4_FILE, the use of LAYOUTRETURN4_FSID, or the use of LAYOUTRETURN4_ALL. There must be a LAYOUTRETURN with a matching scope to complete the return even if all current layout ranges have been previously individually returned.

返回的布局可以是CB_LAYOUTRECALL指定的布局的子集或超集。但是,如果它是一个子集,则在返回完整的调用范围之前,调用是不完整的。调用的范围是指LAYOUTRETURN4_文件、使用LAYOUTRETURN4_FSID或使用LAYOUTRETURN4_ALL情况下的字节范围。必须有一个具有匹配作用域的LAYOUTRETURN才能完成返回,即使之前已单独返回了所有当前布局范围。

For all lr_returntype values, an iomode of LAYOUTIOMODE4_ANY specifies that all layouts that match the other arguments to LAYOUTRETURN (i.e., client ID, lora_layout_type, and one of current filehandle and range; fsid derived from current filehandle; or LAYOUTRETURN4_ALL) are being returned.

对于所有lr_returntype值,LAYOUTIOMODE4_ANY的iomode指定返回与LAYOUTRETURN的其他参数匹配的所有布局(即,客户端ID、lora_LAYOU_类型以及当前文件句柄和范围之一;从当前文件句柄派生的fsid;或LAYOUTRETURN4_all)。

In the case that lr_returntype is LAYOUTRETURN4_FILE, the lrf_stateid provided by the client is a layout stateid as returned from previous layout operations. Note that the "seqid" field of lrf_stateid MUST NOT be zero. See Sections 8.2, 12.5.3, and 12.5.5.2 for a further discussion and requirements.

如果lr_returntype是LAYOUTRETURN4_文件,则客户端提供的lrf_stateid是从以前的布局操作返回的布局stateid。请注意,lrf_stateid的“seqid”字段不能为零。有关进一步的讨论和要求,请参见第8.2节、第12.5.3节和第12.5.5.2节。

Return of a layout or all layouts does not invalidate the mapping of storage device ID to a storage device address. The mapping remains in effect until specifically changed or deleted via device ID notification callbacks. Of course if there are no remaining layouts

返回布局或所有布局不会使存储设备ID到存储设备地址的映射无效。映射保持有效,直到通过设备ID通知回调专门更改或删除。当然,如果没有剩余的布局

that refer to a previously used device ID, the server is free to delete a device ID without a notification callback, which will be the case when notifications are not in effect.

如果引用以前使用的设备ID,则服务器可以自由删除设备ID,而无需通知回调,这在通知无效时会发生。

If the lora_reclaim field is set to TRUE, the client is attempting to return a layout that was acquired before the restart of the metadata server during the metadata server's grace period. When returning layouts that were acquired during the metadata server's grace period, the client MUST set the lora_reclaim field to FALSE. The lora_reclaim field MUST be set to FALSE also when lr_layoutreturn is LAYOUTRETURN4_FSID or LAYOUTRETURN4_ALL. See LAYOUTCOMMIT (Section 18.42) for more details.

如果lora_Reclain字段设置为TRUE,则客户端试图返回在元数据服务器宽限期内重新启动元数据服务器之前获取的布局。返回元数据服务器宽限期内获取的布局时,客户端必须将lora_Reclain字段设置为FALSE。当lr_layoutreturn为LAYOUTRETURN4_FSID或LAYOUTRETURN4_ALL时,lora_回收字段也必须设置为FALSE。有关更多详细信息,请参阅LAYOUTCOMMIT(第18.42节)。

Layouts 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 layout to the storage device(s) or to the metadata server before returning the layout.

可在调用或自愿(即,在服务器调用布局之前)返回布局。在任何一种情况下,客户端都必须在返回布局之前将布局上下文下更改的状态正确传播到存储设备或元数据服务器。

If the client returns the layout in response to a CB_LAYOUTRECALL where the lor_recalltype field of the clora_recall field was LAYOUTRECALL4_FILE, the client should use the lor_stateid value from CB_LAYOUTRECALL as the value for lrf_stateid. Otherwise, it should use logr_stateid (from a previous LAYOUTGET result) or lorr_stateid (from a previous LAYRETURN result). This is done to indicate the point in time (in terms of layout stateid transitions) when the recall was sent. The client uses the precise lora_recallstateid value and MUST NOT set the stateid's seqid to zero; otherwise, NFS4ERR_BAD_STATEID MUST be returned. NFS4ERR_OLD_STATEID can be returned if the client is using an old seqid, and the server knows the client should not be using the old seqid. For example, the client uses the seqid on slot 1 of the session, receives the response with the new seqid, and uses the slot to send another request with the old seqid.

如果客户端返回布局以响应CB_LayoutCall,其中clora_recall字段的lor_recalltype字段为LayoutCall4_文件,则客户端应使用CB_LayoutCall中的lor_stateid值作为lrf_stateid的值。否则,它应该使用logr_stateid(来自上一个LAYOUTGET结果)或lorr_stateid(来自上一个LAYRETURN结果)。这样做是为了指示调用发送时的时间点(就布局状态ID转换而言)。客户端使用精确的lora_recallstateid值,并且不得将stateid的seqid设置为零;否则,必须返回NFS4ERR_BAD_STATEID。如果客户端使用旧的seqid,并且服务器知道客户端不应该使用旧的seqid,则可以返回NFS4ERR_OLD_STATEID。例如,客户端在会话的插槽1上使用seqid,接收带有新seqid的响应,并使用该插槽发送带有旧seqid的另一个请求。

If a client fails to return a layout in a timely manner, then the metadata server SHOULD use its control protocol with the storage devices to fence the client from accessing the data referenced by the layout. See Section 12.5.5 for more details.

如果客户端未能及时返回布局,则元数据服务器应使用其与存储设备的控制协议来阻止客户端访问布局引用的数据。详见第12.5.5节。

If the LAYOUTRETURN request sets the lora_reclaim field to TRUE after the metadata server's grace period, NFS4ERR_NO_GRACE is returned.

如果LAYOUTRETURN请求在元数据服务器的宽限期之后将lora_回收字段设置为TRUE,则返回NFS4ERR_NO_宽限期。

If the LAYOUTRETURN request sets the lora_reclaim field to TRUE and lr_returntype is set to LAYOUTRETURN4_FSID or LAYOUTRETURN4_ALL, NFS4ERR_INVAL is returned.

如果LAYOUTRETURN请求将lora_回收字段设置为TRUE,并且lr_返回类型设置为LAYOUTRETURN4_FSID或LAYOUTRETURN4_ALL,则返回NFS4ERR_INVAL。

If the client sets the lr_returntype field to LAYOUTRETURN4_FILE, then the lrs_stateid field will represent the layout stateid as updated for this operation's processing; the current stateid will also be updated to match the returned value. If the last byte of any layout for the current file, client ID, and layout type is being returned and there are no remaining pending CB_LAYOUTRECALL operations for which a LAYOUTRETURN operation must be done, lrs_present MUST be FALSE, and no stateid will be returned. In addition, the COMPOUND request's current stateid will be set to the all-zeroes special stateid (see Section 16.2.3.1.2). The server MUST reject with NFS4ERR_BAD_STATEID any further use of the current stateid in that COMPOUND until the current stateid is re-established by a later stateid-returning operation.

如果客户端将lr_returntype字段设置为LAYOUTRETURN4_文件,则lrs_stateid字段将表示为该操作处理而更新的布局stateid;还将更新当前stateid以匹配返回值。如果正在返回当前文件、客户端ID和布局类型的任何布局的最后一个字节,并且没有剩余的挂起CB_LAYOUTRECALL操作必须执行LAYOUTRETURN操作,则lrs_present必须为FALSE,并且不会返回stateid。此外,复合请求的当前stateid将设置为全零特殊stateid(参见第16.2.3.1.2节)。服务器必须使用NFS4ERR_BAD_STATEID拒绝在该化合物中进一步使用当前STATEID,直到通过稍后的STATEID返回操作重新建立当前STATEID。

On success, the current filehandle retains its value.

成功后,当前文件句柄将保留其值。

If the EXCHGID4_FLAG_BIND_PRINC_STATEID capability is set on the client ID (see Section 18.35), the server will require that the principal, security flavor, and if applicable, the GSS mechanism, combination that acquired the layout also be the one to send LAYOUTRETURN. This might not be possible if credentials for the principal are no longer available. The server will allow the machine credential or SSV credential (see Section 18.35) to send LAYOUTRETURN if LAYOUTRETURN's operation code was set in the spo_must_allow result of EXCHANGE_ID.

如果在客户端ID上设置了EXCHGID4_FLAG_BIND_PRINC_STATEID功能(请参见第18.35节),则服务器将要求获取布局的主体、安全特性以及GSS机制(如果适用)组合也是发送LAYOUTRETURN的组合。如果主体的凭据不再可用,则可能无法执行此操作。如果在交换ID的spo\u必须\u允许结果中设置了LAYOUTRETURN的操作代码,服务器将允许机器凭据或SSV凭据(参见第18.35节)发送LAYOUTRETURN。

18.44.4. IMPLEMENTATION
18.44.4. 实施

The final LAYOUTRETURN operation in response to a CB_LAYOUTRECALL callback MUST be serialized with any outstanding, intersecting LAYOUTRETURN operations. Note that it is possible that while a client is returning the layout for some recalled range, the server may recall a superset of that range (e.g., LAYOUTRECALL4_ALL); the final return operation for the latter must block until the former layout recall is done.

响应CB_LAYOUTRECALL回调的最终LAYOUTRETURN操作必须使用任何未完成的交叉LAYOUTRETURN操作序列化。注意,当客户端返回某个调用范围的布局时,服务器可能会调用该范围的超集(例如,LAYOUTRECALL4_ALL);后者的最终返回操作必须阻塞,直到前一个布局调用完成。

Returning all layouts in a file system using LAYOUTRETURN4_FSID is typically done in response to a CB_LAYOUTRECALL for that file system as the final return operation. Similarly, LAYOUTRETURN4_ALL is used in response to a recall callback for all layouts. It is possible that the client already returned some outstanding layouts via individual LAYOUTRETURN calls and the call for LAYOUTRETURN4_FSID or LAYOUTRETURN4_ALL marks the end of the LAYOUTRETURN sequence. See Section 12.5.5.1 for more details.

使用LAYOUTRETURN4_FSID返回文件系统中的所有布局通常是为了响应作为最终返回操作的该文件系统的CB_LAYOUTRECALL。类似地,LAYOUTRETURN4_ALL用于响应所有布局的回调。客户端可能已经通过单独的LAYOUTRETURN调用返回了一些未完成的布局,而对LAYOUTRETURN4_FSID或LAYOUTRETURN4_的调用都标志着LAYOUTRETURN序列的结束。更多详情见第12.5.5.1节。

Once the client has returned all layouts referring to a particular device ID, the server MAY delete the device ID.

一旦客户端返回了引用特定设备ID的所有布局,服务器就可以删除该设备ID。

18.45. Operation 52: SECINFO_NO_NAME - Get Security on Unnamed Object
18.45. 操作52:SECINFO_NO_NAME-获取未命名对象的安全性
18.45.1. ARGUMENT
18.45.1. 论点
   enum secinfo_style4 {
           SECINFO_STYLE4_CURRENT_FH       = 0,
           SECINFO_STYLE4_PARENT           = 1
   };
        
   enum secinfo_style4 {
           SECINFO_STYLE4_CURRENT_FH       = 0,
           SECINFO_STYLE4_PARENT           = 1
   };
        
   /* CURRENT_FH: object or child directory */
   typedef secinfo_style4 SECINFO_NO_NAME4args;
        
   /* CURRENT_FH: object or child directory */
   typedef secinfo_style4 SECINFO_NO_NAME4args;
        
18.45.2. RESULT
18.45.2. 后果
   /* CURRENTFH: consumed if status is NFS4_OK */
   typedef SECINFO4res SECINFO_NO_NAME4res;
        
   /* CURRENTFH: consumed if status is NFS4_OK */
   typedef SECINFO4res SECINFO_NO_NAME4res;
        
18.45.3. DESCRIPTION
18.45.3. 描述

Like the SECINFO operation, SECINFO_NO_NAME is used by the client to obtain a list of valid RPC authentication flavors for a specific file object. Unlike SECINFO, SECINFO_NO_NAME only works with objects that are accessed by filehandle.

与SECINFO操作一样,客户端使用SECINFO_NO_NAME获取特定文件对象的有效RPC身份验证样式列表。与SECINFO不同,SECINFO_NO_NAME仅适用于filehandle访问的对象。

There are two styles of SECINFO_NO_NAME, as determined by the value of the secinfo_style4 enumeration. If SECINFO_STYLE4_CURRENT_FH is passed, then SECINFO_NO_NAME is querying for the required security for the current filehandle. If SECINFO_STYLE4_PARENT is passed, then SECINFO_NO_NAME is querying for the required security of the current filehandle's parent. If the style selected is SECINFO_STYLE4_PARENT, then SECINFO should apply the same access methodology used for LOOKUPP when evaluating the traversal to the parent directory. Therefore, if the requester does not have the appropriate access to LOOKUPP the parent, then SECINFO_NO_NAME must behave the same way and return NFS4ERR_ACCESS.

SECINFO_NO_NAME有两种样式,由SECINFO_style4枚举的值决定。如果传递了SECINFO_STYLE4_CURRENT_FH,则SECINFO_NO_NAME正在查询当前文件句柄所需的安全性。如果传递了SECINFO_STYLE4_父级,则SECINFO_NO_NAME正在查询当前文件句柄的父级所需的安全性。如果选择的样式是SECINFO_STYLE4_PARENT,则SECINFO在评估对父目录的遍历时应应用LOOKUPP使用的相同访问方法。因此,如果请求者没有适当的权限查找父对象,则SECINFO_NO_NAME必须以相同的方式运行并返回NFS4ERR_访问。

If PUTFH, PUTPUBFH, PUTROOTFH, or RESTOREFH returns NFS4ERR_WRONGSEC, then the client resolves the situation by sending a COMPOUND request that consists of PUTFH, PUTPUBFH, or PUTROOTFH immediately followed by SECINFO_NO_NAME, style SECINFO_STYLE4_CURRENT_FH. See Section 2.6 for instructions on dealing with NFS4ERR_WRONGSEC error returns from PUTFH, PUTROOTFH, PUTPUBFH, or RESTOREFH.

如果PUTFH、PUTPUBFH、PUTROOTFH或RESTOREFH返回NFS4ERR_ErrorSec,则客户端通过发送一个复合请求来解决这种情况,该请求由PUTFH、PUTPUBFH或PUTROOTFH组成,后跟SECINFO_NO_NAME、style SECINFO_style 4_CURRENT_FH。有关如何处理来自PUTFH、PUTROOTFH、PUTPUBFH或RESTOREFH的NFS4ERR_错误SEC错误返回的说明,请参见第2.6节。

If SECINFO_STYLE4_PARENT is specified and there is no parent directory, SECINFO_NO_NAME MUST return NFS4ERR_NOENT.

如果指定了SECINFO_STYLE4_PARENT并且没有父目录,则SECINFO_no_NAME必须返回NFS4ERR_NOENT。

On success, the current filehandle is consumed (see Section 2.6.3.1.1.8), and if the next operation after SECINFO_NO_NAME tries to use the current filehandle, that operation will fail with the status NFS4ERR_NOFILEHANDLE.

成功后,将使用当前文件句柄(请参阅第2.6.3.1.1.8节),如果SECINFO_NO_NAME之后的下一个操作尝试使用当前文件句柄,则该操作将失败,状态为NFS4ERR_NOFILEHANDLE。

Everything else about SECINFO_NO_NAME is the same as SECINFO. See the discussion on SECINFO (Section 18.29.3).

关于SECINFO_NO_NAME的所有其他信息都与SECINFO相同。请参见关于SECINFO的讨论(第18.29.3节)。

18.45.4. IMPLEMENTATION
18.45.4. 实施

See the discussion on SECINFO (Section 18.29.4).

请参见关于SECINFO的讨论(第18.29.4节)。

18.46. Operation 53: SEQUENCE - Supply Per-Procedure Sequencing and Control

18.46. 操作53:顺序-按程序供应顺序和控制

18.46.1. ARGUMENT
18.46.1. 论点
   struct SEQUENCE4args {
           sessionid4     sa_sessionid;
           sequenceid4    sa_sequenceid;
           slotid4        sa_slotid;
           slotid4        sa_highest_slotid;
           bool           sa_cachethis;
   };
        
   struct SEQUENCE4args {
           sessionid4     sa_sessionid;
           sequenceid4    sa_sequenceid;
           slotid4        sa_slotid;
           slotid4        sa_highest_slotid;
           bool           sa_cachethis;
   };
        
18.46.2. RESULT
18.46.2. 后果
   const SEQ4_STATUS_CB_PATH_DOWN                  = 0x00000001;
   const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING      = 0x00000002;
   const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED       = 0x00000004;
   const SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED     = 0x00000008;
   const SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED    = 0x00000010;
   const SEQ4_STATUS_ADMIN_STATE_REVOKED           = 0x00000020;
   const SEQ4_STATUS_RECALLABLE_STATE_REVOKED      = 0x00000040;
   const SEQ4_STATUS_LEASE_MOVED                   = 0x00000080;
   const SEQ4_STATUS_RESTART_RECLAIM_NEEDED        = 0x00000100;
   const SEQ4_STATUS_CB_PATH_DOWN_SESSION          = 0x00000200;
   const SEQ4_STATUS_BACKCHANNEL_FAULT             = 0x00000400;
   const SEQ4_STATUS_DEVID_CHANGED                 = 0x00000800;
   const SEQ4_STATUS_DEVID_DELETED                 = 0x00001000;
        
   const SEQ4_STATUS_CB_PATH_DOWN                  = 0x00000001;
   const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING      = 0x00000002;
   const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED       = 0x00000004;
   const SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED     = 0x00000008;
   const SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED    = 0x00000010;
   const SEQ4_STATUS_ADMIN_STATE_REVOKED           = 0x00000020;
   const SEQ4_STATUS_RECALLABLE_STATE_REVOKED      = 0x00000040;
   const SEQ4_STATUS_LEASE_MOVED                   = 0x00000080;
   const SEQ4_STATUS_RESTART_RECLAIM_NEEDED        = 0x00000100;
   const SEQ4_STATUS_CB_PATH_DOWN_SESSION          = 0x00000200;
   const SEQ4_STATUS_BACKCHANNEL_FAULT             = 0x00000400;
   const SEQ4_STATUS_DEVID_CHANGED                 = 0x00000800;
   const SEQ4_STATUS_DEVID_DELETED                 = 0x00001000;
        
   struct SEQUENCE4resok {
           sessionid4      sr_sessionid;
           sequenceid4     sr_sequenceid;
           slotid4         sr_slotid;
           slotid4         sr_highest_slotid;
           slotid4         sr_target_highest_slotid;
           uint32_t        sr_status_flags;
   };
        
   struct SEQUENCE4resok {
           sessionid4      sr_sessionid;
           sequenceid4     sr_sequenceid;
           slotid4         sr_slotid;
           slotid4         sr_highest_slotid;
           slotid4         sr_target_highest_slotid;
           uint32_t        sr_status_flags;
   };
        
   union SEQUENCE4res switch (nfsstat4 sr_status) {
   case NFS4_OK:
           SEQUENCE4resok  sr_resok4;
   default:
           void;
   };
        
   union SEQUENCE4res switch (nfsstat4 sr_status) {
   case NFS4_OK:
           SEQUENCE4resok  sr_resok4;
   default:
           void;
   };
        
18.46.3. DESCRIPTION
18.46.3. 描述

The SEQUENCE operation is used by the server to implement session request control and the reply cache semantics.

服务器使用序列操作来实现会话请求控制和应答缓存语义。

SEQUENCE MUST appear as the first operation of any COMPOUND in which it appears. The error NFS4ERR_SEQUENCE_POS will be returned when it is found in any position in a COMPOUND beyond the first. Operations other than SEQUENCE, BIND_CONN_TO_SESSION, EXCHANGE_ID, CREATE_SESSION, and DESTROY_SESSION, MUST NOT appear as the first operation in a COMPOUND. Such operations MUST yield the error NFS4ERR_OP_NOT_IN_SESSION if they do appear at the start of a COMPOUND.

序列必须作为其出现的任何化合物的第一个操作出现。当在化合物中第一个位置以外的任何位置发现错误NFS4ERR_SEQUENCE_POS时,将返回错误NFS4ERR_SEQUENCE_POS。除顺序、绑定连接会话、交换会话ID、创建会话和销毁会话以外的操作不得作为复合中的第一个操作出现。如果这些操作确实出现在化合物的开头,则它们必须在会话中产生错误NFS4ERR_OP_NOT_。

If SEQUENCE is received on a connection not associated with the session via CREATE_SESSION or BIND_CONN_TO_SESSION, and connection association enforcement is enabled (see Section 18.35), then the server returns NFS4ERR_CONN_NOT_BOUND_TO_SESSION.

如果通过CREATE_session或BIND_CONN_TO_session在与会话无关的连接上接收到序列,并且启用了连接关联强制(参见第18.35节),则服务器返回NFS4ERR_CONN_not_BIND_TO_session。

The sa_sessionid argument identifies the session to which this request applies. The sr_sessionid result MUST equal sa_sessionid.

sau sessionid参数标识此请求适用的会话。sr_sessionid结果必须等于sa_sessionid。

The sa_slotid argument is the index in the reply cache for the request. The sa_sequenceid field is the sequence number of the request for the reply cache entry (slot). The sr_slotid result MUST equal sa_slotid. The sr_sequenceid result MUST equal sa_sequenceid.

sau slotid参数是请求的应答缓存中的索引。sa_sequenceid字段是回复缓存项(插槽)请求的序列号。sr_slotid结果必须等于sa_slotid。sr_sequenceid结果必须等于sa_sequenceid。

The sa_highest_slotid argument is the highest slot ID for which the client has a request outstanding; it could be equal to sa_slotid. The server returns two "highest_slotid" values: sr_highest_slotid and sr_target_highest_slotid. The former is the highest slot ID the server will accept in future SEQUENCE operation, and SHOULD NOT be

sau highest_slotid参数是客户端有未完成请求的最高插槽ID;它可能等于萨乌·斯洛蒂德。服务器返回两个“最高\u slotid”值:sr\u highest\u slotid和sr\u target\u highest\u slotid。前者是服务器在未来的序列操作中将接受的最高插槽ID,不应为

less than the value of sa_highest_slotid (but see Section 2.10.6.1 for an exception). The latter is the highest slot ID the server would prefer the client use on a future SEQUENCE operation.

小于sa_highest_slotid的值(但例外情况见第2.10.6.1节)。后者是服务器希望客户端在将来的序列操作中使用的最高插槽ID。

If sa_cachethis is TRUE, then the client is requesting that the server cache the entire reply in the server's reply cache; therefore, the server MUST cache the reply (see Section 2.10.6.1.3). The server MAY cache the reply if sa_cachethis is FALSE. If the server does not cache the entire reply, it MUST still record that it executed the request at the specified slot and sequence ID.

如果sau cachethis为TRUE,则客户端请求服务器将整个应答缓存在服务器的应答缓存中;因此,服务器必须缓存回复(参见第2.10.6.1.3节)。如果sau cachethis为FALSE,服务器可能会缓存回复。如果服务器不缓存整个回复,它必须仍然记录在指定的插槽和序列ID处执行了请求。

The response to the SEQUENCE operation contains a word of status flags (sr_status_flags) that can provide to the client information related to the status of the client's lock state and communications paths. Note that any status bits relating to lock state MAY be reset when lock state is lost due to a server restart (even if the session is persistent across restarts; session persistence does not imply lock state persistence) or the establishment of a new client instance.

对序列操作的响应包含一个状态标志字(sr_status_flags),它可以向客户机提供与客户机锁状态和通信路径状态相关的信息。请注意,当由于服务器重启(即使会话在重启期间是持久的;会话持久性并不意味着锁状态持久性)或建立新的客户端实例而丢失锁状态时,与锁状态相关的任何状态位都可能被重置。

SEQ4_STATUS_CB_PATH_DOWN When set, indicates that the client has no operational backchannel path for any session associated with the client ID, making it necessary for the client to re-establish one. This bit remains set on all SEQUENCE responses on all sessions associated with the client ID until at least one backchannel is available on any session associated with the client ID. If the client fails to re-establish a backchannel for the client ID, it is subject to having recallable state revoked.

SEQ4_STATUS_CB_PATH_DOWN设置时,表示客户端没有与客户端ID关联的任何会话的可操作的反向通道路径,因此客户端有必要重新建立一个反向通道路径。在与客户端ID关联的任何会话上至少有一个反向通道可用之前,此位在与客户端ID关联的所有会话上的所有序列响应上保持设置。如果客户端无法为客户端ID重新建立反向通道,则会被撤销可重调状态。

SEQ4_STATUS_CB_PATH_DOWN_SESSION When set, indicates that the session has no operational backchannel. There are two reasons why SEQ4_STATUS_CB_PATH_DOWN_SESSION may be set and not SEQ4_STATUS_CB_PATH_DOWN. First is that a callback operation that applies specifically to the session (e.g., CB_RECALL_SLOT, see Section 20.8) needs to be sent. Second is that the server did send a callback operation, but the connection was lost before the reply. The server cannot be sure whether or not the client received the callback operation, and so, per rules on request retry, the server MUST retry the callback operation over the same session. The SEQ4_STATUS_CB_PATH_DOWN_SESSION bit is the indication to the client that it needs to associate a connection to the session's backchannel. This bit remains set on all SEQUENCE responses of the session until a connection is associated with the session's a backchannel. If the client fails to re-establish a backchannel for the session, it is subject to having recallable state revoked.

SEQ4_STATUS_CB_PATH_DOWN_SESSION设置时,表示该会话没有可操作的反向通道。设置SEQ4_STATUS_CB_PATH_DOWN_会话而不是SEQ4_STATUS_CB_PATH_DOWN会话有两个原因。首先,需要发送专门应用于会话的回调操作(例如,CB_RECALL_插槽,请参见第20.8节)。其次,服务器确实发送了一个回调操作,但是在回复之前连接就丢失了。服务器无法确定客户端是否收到了回调操作,因此,根据请求重试规则,服务器必须在同一会话上重试回调操作。SEQ4_STATUS_CB_PATH_DOWN_会话位指示客户端需要将连接与会话的反向通道相关联。该位在会话的所有序列响应上保持设置,直到连接与会话的a反向通道相关联。如果客户端无法为会话重新建立反向通道,则需要撤销可重新调用状态。

SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING When set, indicates that all GSS contexts or RPCSEC_GSS handles assigned to the session's backchannel will expire within a period equal to the lease time. This bit remains set on all SEQUENCE replies until at least one of the following are true:

SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING设置后,表示分配给会话反向通道的所有GSS上下文或RPCSEC_GSS句柄将在与租赁时间相等的时间内过期。此位在所有序列回复上保持设置,直到以下至少一项为真:

* All SSV RPCSEC_GSS handles on the session's backchannel have been destroyed and all non-SSV GSS contexts have expired.

* 会话反向通道上的所有SSV RPCSEC_GSS句柄都已销毁,所有非SSV GSS上下文都已过期。

* At least one more SSV RPCSEC_GSS handle has been added to the backchannel.

* 至少有一个SSV RPCSEC_GSS句柄已添加到反向通道。

* The expiration time of at least one non-SSV GSS context of an RPCSEC_GSS handle is beyond the lease period from the current time (relative to the time of when a SEQUENCE response was sent)

* RPCSEC_GSS句柄的至少一个非SSV GSS上下文的过期时间超过当前时间(相对于发送序列响应的时间)的租用期

SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED When set, indicates all non-SSV GSS contexts and all SSV RPCSEC_GSS handles assigned to the session's backchannel have expired or have been destroyed. This bit remains set on all SEQUENCE replies until at least one non-expired non-SSV GSS context for the session's backchannel has been established or at least one SSV RPCSEC_GSS handle has been assigned to the backchannel.

SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED当设置时,表示分配给会话反向通道的所有非SSV GSS上下文和所有SSV RPCSEC_GSS句柄已过期或已销毁。此位在所有序列应答上保持设置,直到会话的后通道至少建立了一个未过期的非SSV GSS上下文,或者至少为后通道分配了一个SSV RPCSEC_GSS句柄。

SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED When set, indicates that the lease has expired and as a result the server released all of the client's locking state. This status bit remains set on all SEQUENCE replies until the loss of all such locks has been acknowledged by use of FREE_STATEID (see Section 18.38), or by establishing a new client instance by destroying all sessions (via DESTROY_SESSION), the client ID (via DESTROY_CLIENTID), and then invoking EXCHANGE_ID and CREATE_SESSION to establish a new client ID.

SEQ4_STATUS_EXPIRED_ALL_STATE_reversed设置时,表示租约已过期,因此服务器释放了客户端的所有锁定状态。在使用FREE_STATEID(参见第18.38节)或通过销毁所有会话(通过DESTROY_SESSION)、客户端ID(通过DESTROY_CLIENTID)建立新的客户端实例确认所有此类锁的丢失之前,此状态位在所有序列回复上保持设置,然后调用EXCHANGE_ID并创建_会话以建立新的客户端ID。

SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED When set, indicates that some subset of the client's locks have been revoked due to expiration of the lease period followed by another client's conflicting LOCK operation. This status bit remains set on all SEQUENCE replies until the loss of all such locks has been acknowledged by use of FREE_STATEID.

SEQ4_STATUS_EXPIRED_SOME_STATE_reversed当设置时,表示由于租赁期到期后另一个客户端的锁操作发生冲突,客户端锁的某些子集已被撤销。在使用FREE_STATEID确认所有此类锁的丢失之前,此状态位在所有序列回复上保持设置。

SEQ4_STATUS_ADMIN_STATE_REVOKED When set, indicates that one or more locks have been revoked without expiration of the lease period, due to administrative action. This status bit remains set on all SEQUENCE replies until the loss of all such locks has been acknowledged by use of FREE_STATEID.

SEQ4_STATUS_ADMIN_STATE_reversed当设置时,表示由于管理操作,一个或多个锁在租赁期未到期的情况下被撤销。在使用FREE_STATEID确认所有此类锁的丢失之前,此状态位在所有序列回复上保持设置。

SEQ4_STATUS_RECALLABLE_STATE_REVOKED When set, indicates that one or more recallable objects have been revoked without expiration of the lease period, due to the client's failure to return them when recalled, which may be a consequence of there being no working backchannel and the client failing to re-establish a backchannel per the SEQ4_STATUS_CB_PATH_DOWN, SEQ4_STATUS_CB_PATH_DOWN_SESSION, or SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED status flags. This status bit remains set on all SEQUENCE replies until the loss of all such locks has been acknowledged by use of FREE_STATEID.

SEQ4_STATUS_RECALLABLE_STATE_reversed When set表示由于客户在召回时未能返回可收回对象,一个或多个可收回对象在租赁期未到期时已被收回,这可能是由于没有工作的反向通道,并且客户端未能根据SEQ4_STATUS_CB_PATH_DOWN、SEQ4_STATUS_CB_PATH_DOWN或SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED状态标志重新建立反向通道。在使用FREE_STATEID确认所有此类锁的丢失之前,此状态位在所有序列回复上保持设置。

SEQ4_STATUS_LEASE_MOVED When set, indicates that responsibility for lease renewal has been transferred to one or more new servers. This condition will continue until the client receives an NFS4ERR_MOVED error and the server receives the subsequent GETATTR for the fs_locations or fs_locations_info attribute for an access to each file system for which a lease has been moved to a new server. See Section 11.7.7.1.

SEQ4_STATUS_LEASE_MOVED当设置时,表示租约续订的责任已转移到一个或多个新服务器。此情况将持续,直到客户端收到NFS4ERR_MOVED错误,服务器收到fs_locations的后续GETATTR或fs_locations_info属性,以访问已将租约移动到新服务器的每个文件系统。见第11.7.7.1节。

SEQ4_STATUS_RESTART_RECLAIM_NEEDED When set, indicates that due to server restart, the client must reclaim locking state. Until the client sends a global RECLAIM_COMPLETE (Section 18.51), every SEQUENCE operation will return SEQ4_STATUS_RESTART_RECLAIM_NEEDED.

SEQ4_STATUS_RESTART_reclain_NEEDED当设置时,表示由于服务器重新启动,客户端必须恢复锁定状态。在客户端发送一个全局回收完成(第18.51节)之前,每个序列操作都将返回所需的SEQ4回收状态。

SEQ4_STATUS_BACKCHANNEL_FAULT The server has encountered an unrecoverable fault with the backchannel (e.g., it has lost track of the sequence ID for a slot in the backchannel). The client MUST stop sending more requests on the session's fore channel, wait for all outstanding requests to complete on the fore and back channel, and then destroy the session.

SEQ4_STATUS_BACKCHANNEL_FAULT服务器遇到了一个无法恢复的反向通道故障(例如,它丢失了反向通道中插槽的序列ID)。客户端必须停止在会话的前通道上发送更多请求,等待所有未完成的请求在前通道和后通道上完成,然后销毁会话。

SEQ4_STATUS_DEVID_CHANGED The client is using device ID notifications and the server has changed a device ID mapping held by the client. This flag will stay present until the client has obtained the new mapping with GETDEVICEINFO.

SEQ4_STATUS_DEVID_已更改客户端正在使用设备ID通知,并且服务器已更改客户端持有的设备ID映射。此标志将一直存在,直到客户端使用GETDEVICEINFO获得新映射。

SEQ4_STATUS_DEVID_DELETED The client is using device ID notifications and the server has deleted a device ID mapping held by the client. This flag will stay in effect until the client sends a GETDEVICEINFO on the device ID with a null value in the argument gdia_notify_types.

SEQ4_STATUS_DEVID_DELETED客户端正在使用设备ID通知,服务器已删除客户端持有的设备ID映射。此标志将一直有效,直到客户端在设备ID上发送一个GETDEVICEINFO,参数gdia_notify_types中有一个空值。

The value of the sa_sequenceid argument relative to the cached sequence ID on the slot falls into one of three cases.

sa_sequenceid参数相对于插槽上缓存的序列ID的值属于以下三种情况之一。

o If the difference between sa_sequenceid and the server's cached sequence ID at the slot ID is two (2) or more, or if sa_sequenceid is less than the cached sequence ID (accounting for wraparound of the unsigned sequence ID value), then the server MUST return NFS4ERR_SEQ_MISORDERED.

o 如果插槽ID处的sa_sequenceid与服务器缓存序列ID之间的差值为两(2)或更大,或者如果sa_sequenceid小于缓存序列ID(考虑未签名序列ID值的环绕),则服务器必须返回NFS4ERR_SEQ_MISORDERED。

o If sa_sequenceid and the cached sequence ID are the same, this is a retry, and the server replies with what is recorded in the reply cache. The lease is possibly renewed as described below.

o 如果sa_sequenceid和缓存的序列ID相同,则这是一次重试,服务器将使用应答缓存中记录的内容进行应答。如下文所述,租约可能会续期。

o If sa_sequenceid is one greater (accounting for wraparound) than the cached sequence ID, then this is a new request, and the slot's sequence ID is incremented. The operations subsequent to SEQUENCE, if any, are processed. If there are no other operations, the only other effects are to cache the SEQUENCE reply in the slot, maintain the session's activity, and possibly renew the lease.

o 如果sa_sequenceid比缓存的序列ID大一个(考虑环绕),则这是一个新请求,插槽的序列ID将递增。处理序列之后的操作(如果有)。如果没有其他操作,唯一的其他效果是将序列应答缓存在插槽中,保持会话的活动,并可能续订租约。

If the client reuses a slot ID and sequence ID for a completely different request, the server MAY treat the request as if it is a retry of what it has already executed. The server MAY however detect the client's illegal reuse and return NFS4ERR_SEQ_FALSE_RETRY.

如果客户机对完全不同的请求重用插槽ID和序列ID,则服务器可能会将该请求视为对其已执行内容的重试。然而,服务器可能检测到客户端的非法重用,并返回NFS4ERR_SEQ_FALSE_RETRY。

If SEQUENCE returns an error, then the state of the slot (sequence ID, cached reply) MUST NOT change, and the associated lease MUST NOT be renewed.

如果SEQUENCE返回错误,则插槽的状态(SEQUENCE ID、cached reply)不得更改,并且关联的租约不得续订。

If SEQUENCE returns NFS4_OK, then the associated lease MUST be renewed (see Section 8.3), except if SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED is returned in sr_status_flags.

如果序列返回NFS4_OK,则必须续订相关租约(参见第8.3节),除非序列4_STATUS_EXPIRED_ALL_STATE_reversed以sr_STATUS_标志返回。

18.46.4. IMPLEMENTATION
18.46.4. 实施

The server MUST maintain a mapping of session ID to client ID in order to validate any operations that follow SEQUENCE that take a stateid as an argument and/or result.

服务器必须维护会话ID到客户端ID的映射,以便验证遵循以stateid作为参数和/或结果的序列的任何操作。

If the client establishes a persistent session, then a SEQUENCE received after a server restart might encounter requests performed and recorded in a persistent reply cache before the server restart. In this case, SEQUENCE will be processed successfully, while requests that were not previously performed and recorded are rejected with NFS4ERR_DEADSESSION.

如果客户端建立了持久会话,那么在服务器重新启动后接收的序列可能会遇到在服务器重新启动前在持久应答缓存中执行和记录的请求。在这种情况下,序列将被成功处理,而之前未执行和记录的请求将被NFS4ERR_DEADSESSION拒绝。

Depending on which of the operations within the COMPOUND were successfully performed before the server restart, these operations will also have replies sent from the server reply cache. Note that when these operations establish locking state, it is locking state that applies to the previous server instance and to the previous client ID, even though the server restart, which logically happened after these operations, eliminated that state. In the case of a partially executed COMPOUND, processing may reach an operation not processed during the earlier server instance, making this operation a new one and not performable on the existing session. In this case, NFS4ERR_DEADSESSION will be returned from that operation.

根据在服务器重新启动之前成功执行的化合物中的哪些操作,这些操作也将从服务器应答缓存发送应答。请注意,当这些操作建立锁定状态时,应用于上一个服务器实例和上一个客户端ID的是锁定状态,即使在这些操作之后逻辑上发生的服务器重新启动消除了该状态。对于部分执行的复合操作,处理可能会到达在早期服务器实例期间未处理的操作,从而使此操作成为新操作,并且无法在现有会话上执行。在这种情况下,该操作将返回NFS4ERR_DEADSESSION。

18.47. Operation 54: SET_SSV - Update SSV for a Client ID
18.47. 操作54:设置SSV-更新客户端ID的SSV
18.47.1. ARGUMENT
18.47.1. 论点
   struct ssa_digest_input4 {
           SEQUENCE4args sdi_seqargs;
   };
        
   struct ssa_digest_input4 {
           SEQUENCE4args sdi_seqargs;
   };
        
   struct SET_SSV4args {
           opaque          ssa_ssv<>;
           opaque          ssa_digest<>;
   };
        
   struct SET_SSV4args {
           opaque          ssa_ssv<>;
           opaque          ssa_digest<>;
   };
        
18.47.2. RESULT
18.47.2. 后果
   struct ssr_digest_input4 {
           SEQUENCE4res sdi_seqres;
   };
        
   struct ssr_digest_input4 {
           SEQUENCE4res sdi_seqres;
   };
        
   struct SET_SSV4resok {
           opaque          ssr_digest<>;
   };
        
   struct SET_SSV4resok {
           opaque          ssr_digest<>;
   };
        
   union SET_SSV4res switch (nfsstat4 ssr_status) {
   case NFS4_OK:
           SET_SSV4resok   ssr_resok4;
   default:
           void;
   };
        
   union SET_SSV4res switch (nfsstat4 ssr_status) {
   case NFS4_OK:
           SET_SSV4resok   ssr_resok4;
   default:
           void;
   };
        
18.47.3. DESCRIPTION
18.47.3. 描述

This operation is used to update the SSV for a client ID. Before SET_SSV is called the first time on a client ID, the SSV is zero. The SSV is the key used for the SSV GSS mechanism (Section 2.10.9)

此操作用于更新客户端ID的SSV。在第一次对客户端ID调用SET_SSV之前,SSV为零。SSV是SSV GSS机构使用的钥匙(第2.10.9节)

SET_SSV MUST be preceded by a SEQUENCE operation in the same COMPOUND. It MUST NOT be used if the client did not opt for SP4_SSV state protection when the client ID was created (see Section 18.35); the server returns NFS4ERR_INVAL in that case.

SET_SSV必须在同一化合物中以顺序操作开头。如果客户在创建客户ID时未选择SP4_SSV状态保护,则不得使用该ID(参见第18.35节);在这种情况下,服务器返回NFS4ERR_INVAL。

The field ssa_digest is computed as the output of the HMAC (RFC 2104 [11]) using the subkey derived from the SSV4_SUBKEY_MIC_I2T and current SSV as the key (see Section 2.10.9 for a description of subkeys), and an XDR encoded value of data type ssa_digest_input4. The field sdi_seqargs is equal to the arguments of the SEQUENCE operation for the COMPOUND procedure that SET_SSV is within.

字段ssa_digest作为HMAC(RFC 2104[11])的输出进行计算,使用从SSV4_subkey_MIC_I2T和当前SSV派生的子键作为键(子键的描述见第2.10.9节),以及数据类型ssa_digest_input4的XDR编码值。字段sdi_seqargs等于SET_SSV所在的复合过程的序列操作的参数。

The argument ssa_ssv is XORed with the current SSV to produce the new SSV. The argument ssa_ssv SHOULD be generated randomly.

参数ssa_ssv与当前ssv异或生成新ssv。参数ssa_ssv应随机生成。

In the response, ssr_digest is the output of the HMAC using the subkey derived from SSV4_SUBKEY_MIC_T2I and new SSV as the key, and an XDR encoded value of data type ssr_digest_input4. The field sdi_seqres is equal to the results of the SEQUENCE operation for the COMPOUND procedure that SET_SSV is within.

在响应中,ssr_digest是HMAC的输出,使用从SSV4_subkey_MIC_T2I和新SSV派生的子键作为键,以及数据类型为ssr_digest_input4的XDR编码值。字段sdi_seqres等于设置_SSV在其中的复合程序的顺序操作结果。

As noted in Section 18.35, the client and server can maintain multiple concurrent versions of the SSV. The client and server each MUST maintain an internal SSV version number, which is set to one the first time SET_SSV executes on the server and the client receives the first SET_SSV reply. Each subsequent SET_SSV increases the internal SSV version number by one. The value of this version number corresponds to the smpt_ssv_seq, smt_ssv_seq, sspt_ssv_seq, and ssct_ssv_seq fields of the SSV GSS mechanism tokens (see Section 2.10.9).

如第18.35节所述,客户端和服务器可以维护SSV的多个并发版本。客户端和服务器必须各自维护一个内部SSV版本号,该版本号在服务器上第一次执行set_SSV并且客户端收到第一个set_SSV回复时设置为1。每个后续的SSV集都会将内部SSV版本号增加一个。该版本号的值对应于ssv GSS机制令牌的smpt_ssv_seq、smt_ssv_seq、sspt_ssv_seq和ssct_ssv_seq字段(见第2.10.9节)。

18.47.4. IMPLEMENTATION
18.47.4. 实施

When the server receives ssa_digest, it MUST verify the digest by computing the digest the same way the client did and comparing it with ssa_digest. If the server gets a different result, this is an error, NFS4ERR_BAD_SESSION_DIGEST. This error might be the result of another SET_SSV from the same client ID changing the SSV. If so, the client recovers by sending a SET_SSV operation again with a recomputed digest based on the subkey of the new SSV. If the transport connection is dropped after the SET_SSV request is sent, but before the SET_SSV reply is received, then there are special

当服务器收到ssa_摘要时,它必须通过与客户端相同的方式计算摘要并将其与ssa_摘要进行比较来验证摘要。如果服务器得到不同的结果,则这是一个错误,即NFS4ERR\u BAD\u SESSION\u DIGEST。此错误可能是来自同一客户端ID的另一个SET_SSV更改SSV的结果。如果是这样,客户端将根据新SSV的子键重新发送一个SET_SSV操作和一个重新计算的摘要,从而进行恢复。如果在发送SET_SSV请求之后,但在收到SET_SSV回复之前,传输连接断开,则会出现特殊情况

considerations for recovery if the client has no more connections associated with sessions associated with the client ID of the SSV. See Section 18.34.4.

如果客户端不再具有与SSV的客户端ID关联的会话关联的连接,则恢复注意事项。见第18.34.4节。

Clients SHOULD NOT send an ssa_ssv that is equal to a previous ssa_ssv, nor equal to a previous or current SSV (including an ssa_ssv equal to zero since the SSV is initialized to zero when the client ID is created).

客户端发送的ssa_ssv不应等于以前的ssa_ssv,也不应等于以前的或当前的ssv(包括等于零的ssa_ssv,因为创建客户端ID时ssv初始化为零)。

Clients SHOULD send SET_SSV with RPCSEC_GSS privacy. Servers MUST support RPCSEC_GSS with privacy for any COMPOUND that has { SEQUENCE, SET_SSV }.

客户端应发送带有RPCSEC_GSS隐私的SET_SSV。对于具有{SEQUENCE,SET_SSV}的任何化合物,服务器必须支持RPCSEC_GSS,并具有隐私。

A client SHOULD NOT send SET_SSV with the SSV GSS mechanism's credential because the purpose of SET_SSV is to seed the SSV from non-SSV credentials. Instead, SET_SSV SHOULD be sent with the credential of a user that is accessing the client ID for the first time (Section 2.10.8.3). However, if the client does send SET_SSV with SSV credentials, the digest protecting the arguments uses the value of the SSV before ssa_ssv is XORed in, and the digest protecting the results uses the value of the SSV after the ssa_ssv is XORed in.

客户端不应使用SSV GSS机制的凭据发送SET_SSV,因为SET_SSV的目的是从非SSV凭据中为SSV种子。相反,SET_SSV应与首次访问客户端ID的用户的凭据一起发送(第2.10.8.3节)。但是,如果客户端确实使用SSV凭据发送SET_SSV,则保护参数的摘要将在ssa_SSV XORed in之前使用SSV的值,而保护结果的摘要将在ssa_SSV XORed in之后使用SSV的值。

18.48. Operation 55: TEST_STATEID - Test Stateids for Validity
18.48. 操作55:TEST_STATEID-测试STATEID的有效性
18.48.1. ARGUMENT
18.48.1. 论点
   struct TEST_STATEID4args {
           stateid4        ts_stateids<>;
   };
        
   struct TEST_STATEID4args {
           stateid4        ts_stateids<>;
   };
        
18.48.2. RESULT
18.48.2. 后果
   struct TEST_STATEID4resok {
           nfsstat4        tsr_status_codes<>;
   };
        
   struct TEST_STATEID4resok {
           nfsstat4        tsr_status_codes<>;
   };
        
   union TEST_STATEID4res switch (nfsstat4 tsr_status) {
       case NFS4_OK:
           TEST_STATEID4resok tsr_resok4;
       default:
           void;
   };
        
   union TEST_STATEID4res switch (nfsstat4 tsr_status) {
       case NFS4_OK:
           TEST_STATEID4resok tsr_resok4;
       default:
           void;
   };
        
18.48.3. DESCRIPTION
18.48.3. 描述

The TEST_STATEID operation is used to check the validity of a set of stateids. It can be used at any time, but the client should definitely use it when it receives an indication that one or more of its stateids have been invalidated due to lock revocation. This occurs when the SEQUENCE operation returns with one of the following sr_status_flags set:

TEST_STATEID操作用于检查一组STATEID的有效性。它可以在任何时候使用,但当客户端收到一个或多个stateID由于锁撤销而无效的指示时,它肯定应该使用它。当序列操作返回并设置以下sr_status_标志之一时,会发生这种情况:

o SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED

o SEQ4\u状态\u已过期\u某些状态\u已撤销

o SEQ4_STATUS_EXPIRED_ADMIN_STATE_REVOKED

o SEQ4\状态\过期\管理\状态\撤销

o SEQ4_STATUS_EXPIRED_RECALLABLE_STATE_REVOKED

o SEQ4\u状态\u已过期\u可撤销\u状态\u已撤销

The client can use TEST_STATEID one or more times to test the validity of its stateids. Each use of TEST_STATEID allows a large set of such stateids to be tested and avoids problems with earlier stateids in a COMPOUND request from interfering with the checking of subsequent stateids, as would happen if individual stateids were tested by a series of corresponding by operations in a COMPOUND request.

客户端可以使用TEST_STATEID一次或多次来测试其STATEID的有效性。TEST_STATEID的每次使用都允许测试大量此类STATEID,并避免复合请求中早期STATEID的问题干扰后续STATEID的检查,如果单个STATEID通过复合请求中的一系列相应by操作进行测试,就会发生这种情况。

For each stateid, the server returns the status code that would be returned if that stateid were to be used in normal operation. Returning such a status indication is not an error and does not cause COMPOUND processing to terminate. Checks for the validity of the stateid proceed as they would for normal operations with a number of exceptions:

对于每个stateid,服务器返回状态代码,如果在正常操作中使用该stateid,将返回该代码。返回这样的状态指示不是错误,也不会导致复合处理终止。检查stateid的有效性,就像检查正常操作一样,但有许多例外情况:

o There is no check for the type of stateid object, as would be the case for normal use of a stateid.

o 没有检查stateid对象的类型,这与正常使用stateid的情况相同。

o There is no reference to the current filehandle.

o 没有对当前文件句柄的引用。

o Special stateids are always considered invalid (they result in the error code NFS4ERR_BAD_STATEID).

o 特殊STATEID始终被视为无效(它们会导致错误代码NFS4ERR\U BAD\U STATEID)。

All stateids are interpreted as being associated with the client for the current session. Any possible association with a previous instance of the client (as stale stateids) is not considered.

所有StateID都被解释为与当前会话的客户端关联。不考虑与以前的客户端实例(作为过时的stateID)的任何可能关联。

The valid status values in the returned status_code array are NFS4ERR_OK, NFS4ERR_BAD_STATEID, NFS4ERR_OLD_STATEID, NFS4ERR_EXPIRED, NFS4ERR_ADMIN_REVOKED, and NFS4ERR_DELEG_REVOKED.

返回的状态代码数组中的有效状态值为NFS4ERR_OK、NFS4ERR_BAD_STATEID、NFS4ERR_OLD_STATEID、NFS4ERR_EXPIRED、NFS4ERR_ADMIN_Reversed和NFS4ERR_DELEG_Reversed。

18.48.4. IMPLEMENTATION
18.48.4. 实施

See Sections 8.2.2 and 8.2.4 for a discussion of stateid structure, lifetime, and validation.

有关stateid结构、生存期和验证的讨论,请参见第8.2.2节和第8.2.4节。

18.49. Operation 56: WANT_DELEGATION - Request Delegation
18.49. 操作56:请求委派-请求委派
18.49.1. ARGUMENT
18.49.1. 论点
   union deleg_claim4 switch (open_claim_type4 dc_claim) {
   /*
    * No special rights to object.  Ordinary delegation
    * request of the specified object.  Object identified
    * by filehandle.
    */
   case CLAIM_FH: /* new to v4.1 */
           /* CURRENT_FH: object being delegated */
           void;
        
   union deleg_claim4 switch (open_claim_type4 dc_claim) {
   /*
    * No special rights to object.  Ordinary delegation
    * request of the specified object.  Object identified
    * by filehandle.
    */
   case CLAIM_FH: /* new to v4.1 */
           /* CURRENT_FH: object being delegated */
           void;
        
   /*
    * Right to file based on a delegation granted
    * to a previous boot instance of the client.
    * File is specified by filehandle.
    */
   case CLAIM_DELEG_PREV_FH: /* new to v4.1 */
           /* CURRENT_FH: object being delegated */
           void;
        
   /*
    * Right to file based on a delegation granted
    * to a previous boot instance of the client.
    * File is specified by filehandle.
    */
   case CLAIM_DELEG_PREV_FH: /* new to v4.1 */
           /* CURRENT_FH: object being delegated */
           void;
        
   /*
    * Right to the file established by an open previous
    * to server reboot.  File identified by filehandle.
    * Used during server reclaim grace period.
    */
   case CLAIM_PREVIOUS:
           /* CURRENT_FH: object being reclaimed */
           open_delegation_type4   dc_delegate_type;
   };
        
   /*
    * Right to the file established by an open previous
    * to server reboot.  File identified by filehandle.
    * Used during server reclaim grace period.
    */
   case CLAIM_PREVIOUS:
           /* CURRENT_FH: object being reclaimed */
           open_delegation_type4   dc_delegate_type;
   };
        
   struct WANT_DELEGATION4args {
           uint32_t        wda_want;
           deleg_claim4    wda_claim;
   };
        
   struct WANT_DELEGATION4args {
           uint32_t        wda_want;
           deleg_claim4    wda_claim;
   };
        
18.49.2. RESULT
18.49.2. 后果
   union WANT_DELEGATION4res switch (nfsstat4 wdr_status) {
   case NFS4_OK:
           open_delegation4 wdr_resok4;
   default:
           void;
   };
        
   union WANT_DELEGATION4res switch (nfsstat4 wdr_status) {
   case NFS4_OK:
           open_delegation4 wdr_resok4;
   default:
           void;
   };
        
18.49.3. DESCRIPTION
18.49.3. 描述

Where this description mandates the return of a specific error code for a specific condition, and where multiple conditions apply, the server MAY return any of the mandated error codes.

如果此描述强制返回特定条件的特定错误代码,并且如果多个条件适用,则服务器可以返回任何强制错误代码。

This operation allows a client to:

此操作允许客户端执行以下操作:

o Get a delegation on all types of files except directories.

o 获取除目录之外的所有文件类型的委派。

o Register a "want" for a delegation for the specified file object, and be notified via a callback when the delegation is available. The server MAY support notifications of availability via callbacks. If the server does not support registration of wants, it MUST NOT return an error to indicate that, and instead MUST return with ond_why set to WND4_CONTENTION or WND4_RESOURCE and ond_server_will_push_deleg or ond_server_will_signal_avail set to FALSE. When the server indicates that it will notify the client by means of a callback, it will either provide the delegation using a CB_PUSH_DELEG operation or cancel its promise by sending a CB_WANTS_CANCELLED operation.

o 为指定文件对象的委派注册“想要”,并在委派可用时通过回调得到通知。服务器可能支持通过回调通知可用性。如果服务器不支持注册需求,则它不得返回错误以指示该错误,而是必须返回ond_为什么设置为WND4_争用或WND4_资源,并且ond_服务器_将推送_删除或ond_服务器_将信号_有效设置为FALSE。当服务器指示它将通过回调通知客户机时,它将使用CB_PUSH_DELEG操作提供委托,或者通过发送CB_WANTS_CANCELLED操作取消其承诺。

o Cancel a want for a delegation.

o 取消对委派的请求。

The client SHOULD NOT set OPEN4_SHARE_ACCESS_READ and SHOULD NOT set OPEN4_SHARE_ACCESS_WRITE in wda_want. If it does, the server MUST ignore them.

客户端不应设置OPEN4_共享_访问_读取,也不应设置OPEN4_共享_访问_写入wda_所需。如果是这样,服务器必须忽略它们。

The meanings of the following flags in wda_want are the same as they are in OPEN, except as noted below.

wda_want中以下标志的含义与OPEN中的含义相同,除非如下所述。

o OPEN4_SHARE_ACCESS_WANT_READ_DELEG

o OPEN4\u共享\u访问\u想要\u读取\u删除

o OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG

o OPEN4\u共享\u访问\u想要\u写入\u删除

o OPEN4_SHARE_ACCESS_WANT_ANY_DELEG

o OPEN4\u共享\u访问\u想要任何\u删除

o OPEN4_SHARE_ACCESS_WANT_NO_DELEG. Unlike the OPEN operation, this flag SHOULD NOT be set by the client in the arguments to WANT_DELEGATION, and MUST be ignored by the server.

o OPEN4\u共享\u访问\u想要\u不需要\u删除。与打开操作不同,客户端不应在参数中设置此标志以进行委托,服务器必须忽略此标志。

o OPEN4_SHARE_ACCESS_WANT_CANCEL

o OPEN4\u共享\u访问\u想要\u取消

o OPEN4_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL

o OPEN4共享访问需要信号删除可用时

o OPEN4_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED

o OPEN4\u共享\u访问\u想要\u推送\u删除\u未竞争时

The handling of the above flags in WANT_DELEGATION is the same as in OPEN. Information about the delegation and/or the promises the server is making regarding future callbacks are the same as those described in the open_delegation4 structure.

WANT_DELEGATION中上述标志的处理与OPEN中相同。服务器就未来回调所做的委托和/或承诺的信息与open_delegation4结构中描述的信息相同。

The successful results of WANT_DELEGATION are of data type open_delegation4, which is the same data type as the "delegation" field in the results of the OPEN operation (see Section 18.16.3). The server constructs wdr_resok4 the same way it constructs OPEN's "delegation" with one difference: WANT_DELEGATION MUST NOT return a delegation type of OPEN_DELEGATE_NONE.

WANT_委派的成功结果为数据类型open_delegation4,该数据类型与开放操作结果中的“委派”字段的数据类型相同(见第18.16.3节)。服务器构造wdr_resok4的方式与构造OPEN的“委派”的方式相同,但有一个区别:WANT_delegation不能返回OPEN_DELEGATE_NONE的委派类型。

If ((wda_want & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK) & ~OPEN4_SHARE_ACCESS_WANT_NO_DELEG) is zero, then the client is indicating no explicit desire or non-desire for a delegation and the server MUST return NFS4ERR_INVAL.

如果((wda_want&OPEN4_SHARE_ACCESS_want_DELEG_MASK)&~OPEN4_SHARE_ACCESS_want_NO_DELEG)为零,则客户端表示不希望或不希望进行委派,服务器必须返回NFS4ERR_INVAL。

The client uses the OPEN4_SHARE_ACCESS_WANT_CANCEL flag in the WANT_DELEGATION operation to cancel a previously requested want for a delegation. Note that if the server is in the process of sending the delegation (via CB_PUSH_DELEG) at the time the client sends a cancellation of the want, the delegation might still be pushed to the client.

客户机在“希望”委派操作中使用OPEN4\u共享\u访问\u希望\u取消标志来取消先前请求的委派希望。请注意,如果在客户端发送取消请求时服务器正在发送委托(通过CB_PUSH_DELEG),则委托仍可能被推送到客户端。

If WANT_DELEGATION fails to return a delegation, and the server returns NFS4_OK, the server MUST set the delegation type to OPEN4_DELEGATE_NONE_EXT, and set od_whynone, as described in Section 18.16. Write delegations are not available for file types that are not writable. This includes file objects of types NF4BLK, NF4CHR, NF4LNK, NF4SOCK, and NF4FIFO. If the client requests OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG without OPEN4_SHARE_ACCESS_WANT_READ_DELEG on an object with one of the aforementioned file types, the server must set wdr_resok4.od_whynone.ond_why to WND4_WRITE_DELEG_NOT_SUPP_FTYPE.

如果WANT_DELEGATION未能返回委派,且服务器返回NFS4_OK,则服务器必须将委派类型设置为OPEN4_DELEGATE_NONE_EXT,并设置od_whynone,如第18.16节所述。写入委派不适用于不可写入的文件类型。这包括NF4BLK、NF4CHR、NF4LNK、NF4SOCK和NF4FIFO类型的文件对象。如果客户端在具有上述文件类型之一的对象上请求OPEN4\u共享\u访问\u想要写\u删除而没有OPEN4\u共享\u访问\u想要读\u删除,则服务器必须将wdr\u resok4.od\u whynone.ond\u why设置为WND4\u写\u删除\u不支持\u FTYPE。

18.49.4. IMPLEMENTATION
18.49.4. 实施

A request for a conflicting delegation is not normally intended to trigger the recall of the existing delegation. Servers may choose to treat some clients as having higher priority such that their wants will trigger recall of an existing delegation, although that is expected to be an unusual situation.

对冲突委托的请求通常不会触发现有委托的撤回。服务器可能会选择将某些客户机视为具有更高的优先级,这样他们的需求将触发对现有委派的调用,尽管这可能是一种不寻常的情况。

Servers will generally recall delegations assigned by WANT_DELEGATION on the same basis as those assigned by OPEN. CB_RECALL will generally be done only when other clients perform operations inconsistent with the delegation. The normal response to aging of delegations is to use CB_RECALL_ANY, in order to give the client the opportunity to keep the delegations most useful from its point of view.

服务器通常会在与OPEN相同的基础上调用WANT_DELEGATION分配的委托。CB_召回通常仅在其他客户执行与委托不一致的操作时进行。对授权老化的正常反应是使用CB_RECALL_ANY,以便客户有机会从其角度保持授权最有用。

18.50. Operation 57: DESTROY_CLIENTID - Destroy a Client ID
18.50. 操作57:销毁客户端ID-销毁客户端ID
18.50.1. ARGUMENT
18.50.1. 论点
   struct DESTROY_CLIENTID4args {
           clientid4       dca_clientid;
   };
        
   struct DESTROY_CLIENTID4args {
           clientid4       dca_clientid;
   };
        
18.50.2. RESULT
18.50.2. 后果
   struct DESTROY_CLIENTID4res {
           nfsstat4        dcr_status;
   };
        
   struct DESTROY_CLIENTID4res {
           nfsstat4        dcr_status;
   };
        
18.50.3. DESCRIPTION
18.50.3. 描述

The DESTROY_CLIENTID operation destroys the client ID. If there are sessions (both idle and non-idle), opens, locks, delegations, layouts, and/or wants (Section 18.49) associated with the unexpired lease of the client ID, the server MUST return NFS4ERR_CLIENTID_BUSY. DESTROY_CLIENTID MAY be preceded with a SEQUENCE operation as long as the client ID derived from the session ID of SEQUENCE is not the same as the client ID to be destroyed. If the client IDs are the same, then the server MUST return NFS4ERR_CLIENTID_BUSY.

销毁客户端ID操作将销毁客户端ID。如果存在与客户端ID的未到期租约相关联的会话(空闲和非空闲)、打开、锁定、委派、布局和/或需要(第18.49节),则服务器必须返回NFS4ERR\u CLIENTID\u BUSY。只要从SEQUENCE的会话ID派生的客户端ID与要销毁的客户端ID不同,DESTROY_CLIENTID前面就可以有序列操作。如果客户端ID相同,则服务器必须返回NFS4ERR\u CLIENTID\u BUSY。

If DESTROY_CLIENTID is not prefixed by SEQUENCE, it MUST be the only operation in the COMPOUND request (otherwise, the server MUST return NFS4ERR_NOT_ONLY_OP). If the operation is sent without a SEQUENCE preceding it, a client that retransmits the request may receive an error in response, because the original request might have been successfully executed.

如果DESTROY_CLIENTID没有以SEQUENCE作为前缀,则它必须是复合请求中的唯一操作(否则,服务器必须返回NFS4ERR_not_only_OP)。如果发送操作之前没有序列,则重新传输请求的客户端可能会收到错误响应,因为原始请求可能已成功执行。

18.50.4. IMPLEMENTATION
18.50.4. 实施

DESTROY_CLIENTID allows a server to immediately reclaim the resources consumed by an unused client ID, and also to forget that it ever generated the client ID. By forgetting that it ever generated the client ID, the server can safely reuse the client ID on a future EXCHANGE_ID operation.

DESTROY_CLIENTID允许服务器立即回收未使用的客户端ID消耗的资源,并忘记它曾经生成过客户端ID。通过忘记它曾经生成过客户端ID,服务器可以在将来的EXCHANGE_ID操作中安全地重用客户端ID。

18.51. Operation 58: RECLAIM_COMPLETE - Indicates Reclaims Finished
18.51. 操作58:回收完成-表示回收已完成
18.51.1. ARGUMENT
18.51.1. 论点
   struct RECLAIM_COMPLETE4args {
           /*
            * If rca_one_fs TRUE,
            *
            *    CURRENT_FH: object in
            *    file system reclaim is
            *    complete for.
            */
           bool            rca_one_fs;
   };
        
   struct RECLAIM_COMPLETE4args {
           /*
            * If rca_one_fs TRUE,
            *
            *    CURRENT_FH: object in
            *    file system reclaim is
            *    complete for.
            */
           bool            rca_one_fs;
   };
        
18.51.2. RESULTS
18.51.2. 后果
   struct RECLAIM_COMPLETE4res {
           nfsstat4        rcr_status;
   };
        
   struct RECLAIM_COMPLETE4res {
           nfsstat4        rcr_status;
   };
        
18.51.3. DESCRIPTION
18.51.3. 描述

A RECLAIM_COMPLETE operation is used to indicate that the client has reclaimed all of the locking state that it will recover, when it is recovering state due to either a server restart or the transfer of a file system to another server. There are two types of RECLAIM_COMPLETE operations:

Reclain_COMPLETE操作用于指示当客户端由于服务器重新启动或将文件系统传输到另一台服务器而恢复状态时,客户端已恢复其将恢复的所有锁定状态。有两种类型的回收完成操作:

o When rca_one_fs is FALSE, a global RECLAIM_COMPLETE is being done. This indicates that recovery of all locks that the client held on the previous server instance have been completed.

o 当rca_one_fs为FALSE时,将执行全局回收完成。这表示客户端在上一个服务器实例上持有的所有锁的恢复已完成。

o When rca_one_fs is TRUE, a file system-specific RECLAIM_COMPLETE is being done. This indicates that recovery of locks for a single fs (the one designated by the current filehandle) due to a file system transition have been completed. Presence of a current filehandle is only required when rca_one_fs is set to TRUE.

o 当rca_one_fs为TRUE时,将执行特定于文件系统的回收完成。这表示由于文件系统转换而对单个fs(由当前filehandle指定的fs)的锁的恢复已完成。只有当rca_one_fs设置为TRUE时,才需要存在当前文件句柄。

Once a RECLAIM_COMPLETE is done, there can be no further reclaim operations for locks whose scope is defined as having completed recovery. Once the client sends RECLAIM_COMPLETE, the server will not allow the client to do subsequent reclaims of locking state for that scope and, if these are attempted, will return NFS4ERR_NO_GRACE.

一旦完成回收,就不能再对范围定义为已完成恢复的锁执行回收操作。一旦客户端发送Reclain_COMPLETE,服务器将不允许客户端对该作用域执行锁定状态的后续回收,如果尝试了这些操作,将返回NFS4ERR_NO_GRACE。

Whenever a client establishes a new client ID and before it does the first non-reclaim operation that obtains a lock, it MUST send a RECLAIM_COMPLETE with rca_one_fs set to FALSE, even if there are no locks to reclaim. If non-reclaim locking operations are done before the RECLAIM_COMPLETE, an NFS4ERR_GRACE error will be returned.

每当客户机建立新的客户机ID时,在执行第一个获得锁的非回收操作之前,它必须发送一个回收_,并将rca_one_fs设置为FALSE,即使没有要回收的锁。如果在回收完成之前完成了非回收锁定操作,将返回NFS4ERR\U格雷斯错误。

Similarly, when the client accesses a file system on a new server, before it sends the first non-reclaim operation that obtains a lock on this new server, it MUST send a RECLAIM_COMPLETE with rca_one_fs set to TRUE and current filehandle within that file system, even if there are no locks to reclaim. If non-reclaim locking operations are done on that file system before the RECLAIM_COMPLETE, an NFS4ERR_GRACE error will be returned.

类似地,当客户端访问新服务器上的文件系统时,在发送第一个非回收操作以获得此新服务器上的锁之前,它必须发送一个回收操作,该文件系统中的rca_one_fs设置为TRUE和current filehandle,即使没有要回收的锁。如果在回收完成之前在该文件系统上执行了非回收锁定操作,则将返回NFS4ERR_GRACE错误。

Any locks not reclaimed at the point at which RECLAIM_COMPLETE is done become non-reclaimable. The client MUST NOT attempt to reclaim them, either during the current server instance or in any subsequent server instance, or on another server to which responsibility for that file system is transferred. If the client were to do so, it would be violating the protocol by representing itself as owning locks that it does not own, and so has no right to reclaim. See Section 8.4.3 for a discussion of edge conditions related to lock reclaim.

在完成回收时未回收的任何锁将变为不可回收。无论是在当前服务器实例中,还是在任何后续服务器实例中,或者在将文件系统的责任转移到的另一台服务器上,客户端都不得尝试回收它们。如果客户端这样做,它将自己表示为拥有它不拥有的锁,因此无权回收,从而违反了协议。有关锁回收相关边缘条件的讨论,请参见第8.4.3节。

By sending a RECLAIM_COMPLETE, the client indicates readiness to proceed to do normal non-reclaim locking operations. The client should be aware that such operations may temporarily result in NFS4ERR_GRACE errors until the server is ready to terminate its grace period.

通过发送Recall_COMPLETE,客户端表示准备好继续执行正常的非回收锁定操作。客户端应该知道,在服务器准备终止其宽限期之前,此类操作可能会暂时导致NFS4ERR_宽限期错误。

18.51.4. IMPLEMENTATION
18.51.4. 实施

Servers will typically use the information as to when reclaim activity is complete to reduce the length of the grace period. When the server maintains in persistent storage a list of clients that might have had locks, it is in a position to use the fact that all such clients have done a RECLAIM_COMPLETE to terminate the grace period and begin normal operations (i.e., grant requests for new locks) sooner than it might otherwise.

服务器通常会使用回收活动何时完成的信息来缩短宽限期的长度。当服务器在持久性存储中维护可能有锁的客户机列表时,它可以利用这样一个事实,即所有此类客户机都已完成回收,以比其他情况更快地终止宽限期并开始正常操作(即,授予新锁的请求)。

Latency can be minimized by doing a RECLAIM_COMPLETE as part of the COMPOUND request in which the last lock-reclaiming operation is done. When there are no reclaims to be done, RECLAIM_COMPLETE should be done immediately in order to allow the grace period to end as soon as possible.

通过在复合请求中完成一次回收操作(在该复合请求中完成最后一次锁回收操作),可以最大限度地减少延迟。如果没有要进行的回收,应立即完成回收,以便让宽限期尽快结束。

RECLAIM_COMPLETE should only be done once for each server instance or occasion of the transition of a file system. If it is done a second time, the error NFS4ERR_COMPLETE_ALREADY will result. Note that because of the session feature's retry protection, retries of COMPOUND requests containing RECLAIM_COMPLETE operation will not result in this error.

对于每个服务器实例或文件系统的转换,Recall_COMPLETE只能执行一次。如果第二次执行,将导致错误NFS4ERR_COMPLETE_。请注意,由于会话功能的重试保护,重试包含回收完成操作的复合请求不会导致此错误。

When a RECLAIM_COMPLETE is sent, the client effectively acknowledges any locks not yet reclaimed as lost. This allows the server to re-enable the client to recover locks if the occurrence of edge conditions, as described in Section 8.4.3, had caused the server to disable the client from recovering locks.

发送回收完成后,客户端将有效地确认所有尚未回收的锁已丢失。如果出现边缘条件(如第8.4.3节所述)导致服务器禁用客户端恢复锁,则服务器可以重新启用客户端恢复锁。

18.52. Operation 10044: ILLEGAL - Illegal Operation
18.52. 操作10044:非法-非法操作
18.52.1. ARGUMENTS
18.52.1. 论据

void;

无效的

18.52.2. RESULTS
18.52.2. 后果
   struct ILLEGAL4res {
           nfsstat4        status;
   };
        
   struct ILLEGAL4res {
           nfsstat4        status;
   };
        
18.52.3. DESCRIPTION
18.52.3. 描述

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_非法。

18.52.4. IMPLEMENTATION
18.52.4. 实施

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

客户端可能不会发送代码为OP_非法的操作,但如果发送,响应将是非法的4res,就像发送任何其他无效操作代码一样。请注意,如果服务器获得

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_非法的非法操作代码,如果服务器在XDR解码阶段检查合法操作代码,则不会返回非法4res。

19. NFSv4.1 Callback Procedures
19. NFSv4.1回调过程

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,这些术语的含义正好相反。

Both procedures, CB_NULL and CB_COMPOUND, MUST be implemented.

必须执行CB_NULL和CB_component这两个程序。

19.1. Procedure 0: CB_NULL - No Operation
19.1. 过程0:CB_NULL-无操作
19.1.1. ARGUMENTS
19.1.1. 论据

void;

无效的

19.1.2. RESULTS
19.1.2. 后果

void;

无效的

19.1.3. DESCRIPTION
19.1.3. 描述

CB_NULL is the standard ONC RPC NULL procedure, with the standard void argument and 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 the server to client.

CB_NULL是标准的ONC RPC NULL过程,具有标准的void参数和void响应。即使没有与此过程相关联的直接功能,服务器也将使用CB_NULL来确认是否存在从服务器到客户端的RPC路径。

19.1.4. ERRORS
19.1.4. 错误

None.

没有一个

19.2. Procedure 1: CB_COMPOUND - Compound Operations
19.2. 程序1:CB_复合-复合操作
19.2.1. ARGUMENTS
19.2.1. 论据
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4,
   /* Callback operations new to NFSv4.1 */
           OP_CB_LAYOUTRECALL      = 5,
           OP_CB_NOTIFY            = 6,
           OP_CB_PUSH_DELEG        = 7,
           OP_CB_RECALL_ANY        = 8,
           OP_CB_RECALLABLE_OBJ_AVAIL = 9,
           OP_CB_RECALL_SLOT       = 10,
           OP_CB_SEQUENCE          = 11,
           OP_CB_WANTS_CANCELLED   = 12,
           OP_CB_NOTIFY_LOCK       = 13,
           OP_CB_NOTIFY_DEVICEID   = 14,
        
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4,
   /* Callback operations new to NFSv4.1 */
           OP_CB_LAYOUTRECALL      = 5,
           OP_CB_NOTIFY            = 6,
           OP_CB_PUSH_DELEG        = 7,
           OP_CB_RECALL_ANY        = 8,
           OP_CB_RECALLABLE_OBJ_AVAIL = 9,
           OP_CB_RECALL_SLOT       = 10,
           OP_CB_SEQUENCE          = 11,
           OP_CB_WANTS_CANCELLED   = 12,
           OP_CB_NOTIFY_LOCK       = 13,
           OP_CB_NOTIFY_DEVICEID   = 14,
        

OP_CB_ILLEGAL = 10044 };

OP_CB_非法=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_LAYOUTRECALL:
         CB_LAYOUTRECALL4args      opcblayoutrecall;
    case OP_CB_NOTIFY:
         CB_NOTIFY4args            opcbnotify;
    case OP_CB_PUSH_DELEG:
         CB_PUSH_DELEG4args        opcbpush_deleg;
    case OP_CB_RECALL_ANY:
         CB_RECALL_ANY4args        opcbrecall_any;
    case OP_CB_RECALLABLE_OBJ_AVAIL:
         CB_RECALLABLE_OBJ_AVAIL4args opcbrecallable_obj_avail;
    case OP_CB_RECALL_SLOT:
         CB_RECALL_SLOT4args       opcbrecall_slot;
    case OP_CB_SEQUENCE:
         CB_SEQUENCE4args          opcbsequence;
    case OP_CB_WANTS_CANCELLED:
         CB_WANTS_CANCELLED4args   opcbwants_cancelled;
    case OP_CB_NOTIFY_LOCK:
         CB_NOTIFY_LOCK4args       opcbnotify_lock;
    case OP_CB_NOTIFY_DEVICEID:
         CB_NOTIFY_DEVICEID4args   opcbnotify_deviceid;
    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_LAYOUTRECALL:
         CB_LAYOUTRECALL4args      opcblayoutrecall;
    case OP_CB_NOTIFY:
         CB_NOTIFY4args            opcbnotify;
    case OP_CB_PUSH_DELEG:
         CB_PUSH_DELEG4args        opcbpush_deleg;
    case OP_CB_RECALL_ANY:
         CB_RECALL_ANY4args        opcbrecall_any;
    case OP_CB_RECALLABLE_OBJ_AVAIL:
         CB_RECALLABLE_OBJ_AVAIL4args opcbrecallable_obj_avail;
    case OP_CB_RECALL_SLOT:
         CB_RECALL_SLOT4args       opcbrecall_slot;
    case OP_CB_SEQUENCE:
         CB_SEQUENCE4args          opcbsequence;
    case OP_CB_WANTS_CANCELLED:
         CB_WANTS_CANCELLED4args   opcbwants_cancelled;
    case OP_CB_NOTIFY_LOCK:
         CB_NOTIFY_LOCK4args       opcbnotify_lock;
    case OP_CB_NOTIFY_DEVICEID:
         CB_NOTIFY_DEVICEID4args   opcbnotify_deviceid;
    case OP_CB_ILLEGAL:            void;
   };
        
   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<>;
   };
        
19.2.2. RESULTS
19.2.2. 后果
   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;
        
    /* new NFSv4.1 operations */
    case OP_CB_LAYOUTRECALL:
                           CB_LAYOUTRECALL4res
                                           opcblayoutrecall;
        
    /* new NFSv4.1 operations */
    case OP_CB_LAYOUTRECALL:
                           CB_LAYOUTRECALL4res
                                           opcblayoutrecall;
        

case OP_CB_NOTIFY: CB_NOTIFY4res opcbnotify;

案例OP_CB_NOTIFY:CB_NOTIFY4res opcbnotify;

case OP_CB_PUSH_DELEG: CB_PUSH_DELEG4res opcbpush_deleg;

案例OP_CB_PUSH_DELEG:CB_PUSH_DELEG4res opcbpush_DELEG;

case OP_CB_RECALL_ANY: CB_RECALL_ANY4res opcbrecall_any;

案例OP_CB_RECALL_ANY:CB_RECALL_ANY 4res opcbrecall_ANY;

case OP_CB_RECALLABLE_OBJ_AVAIL: CB_RECALLABLE_OBJ_AVAIL4res opcbrecallable_obj_avail;

案例OP_CB_可收回的OBJ_效用:CB_可收回的OBJ_效用L4res Opc可收回的OBJ_效用;

case OP_CB_RECALL_SLOT: CB_RECALL_SLOT4res opcbrecall_slot;

案例OP_CB_RECALL_插槽:CB_RECALL_插槽4Res OpcRecall_插槽;

case OP_CB_SEQUENCE: CB_SEQUENCE4res opcbsequence;

案例OP_CB_序列:CB_序列4res opcbsequence;

case OP_CB_WANTS_CANCELLED: CB_WANTS_CANCELLED4res opcbwants_cancelled;

案例OP_CB_WANTS_CANCELLED:CB_WANTS_CANCELLED 4res opcbwants_CANCELLED;

case OP_CB_NOTIFY_LOCK: CB_NOTIFY_LOCK4res opcbnotify_lock;

案例OP_CB_NOTIFY_LOCK:CB_NOTIFY_LOCK4res opcbnotify_LOCK;

case OP_CB_NOTIFY_DEVICEID: CB_NOTIFY_DEVICEID4res opcbnotify_deviceid;

案例OP_CB_NOTIFY_DEVICEID:CB_NOTIFY_DeviceIdRes opcbnotify_DEVICEID;

    /* Not new operation */
    case OP_CB_ILLEGAL:    CB_ILLEGAL4res  opcbillegal;
   };
        
    /* Not new operation */
    case OP_CB_ILLEGAL:    CB_ILLEGAL4res  opcbillegal;
   };
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
           utf8str_cs      tag;
           nfs_cb_resop4   resarray<>;
   };
        
   struct CB_COMPOUND4res {
           nfsstat4 status;
           utf8str_cs      tag;
           nfs_cb_resop4   resarray<>;
   };
        
19.2.3. DESCRIPTION
19.2.3. 描述

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_复合过程作为包装。

During 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. Refer to Section 2.10.6.4 for details.

在CB_复合过程的处理过程中,客户端可能会发现它没有可用的资源来执行CB_复合序列中的任何或所有操作。详见第2.10.6.4节。

The minorversion field of the arguments MUST be the same as the minorversion of the COMPOUND procedure used to create the client ID and session. For NFSv4.1, minorversion MUST be set to 1.

参数的minorversion字段必须与用于创建客户端ID和会话的复合过程的minorversion字段相同。对于NFSv4.1,minorversion必须设置为1。

Contained within the CB_COMPOUND results is a "status" field. This status MUST be equal 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_复合过程中执行的最后一个操作的状态。因此,如果操作发生错误,“状态”值将与为失败的操作返回的错误值相同。

The "tag" field is handled the same way as that of the COMPOUND procedure (see Section 16.2.3).

“标签”字段的处理方式与复合程序相同(见第16.2.3节)。

Illegal operation codes are handled in the same way as they are handled for the COMPOUND procedure.

非法操作代码的处理方式与复合程序的处理方式相同。

19.2.4. IMPLEMENTATION
19.2.4. 实施

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。

19.2.5. ERRORS
19.2.5. 错误

CB_COMPOUND will of course return every error that each operation on the backchannel can return (see Table 7). However, if CB_COMPOUND returns zero operations, obviously the error returned by COMPOUND has nothing to do with an error returned by an operation. The list of errors CB_COMPOUND will return if it processes zero operations includes:

CB_component当然会返回每个错误,而反向通道上的每个操作都会返回这些错误(见表7)。然而,如果CB_component返回零操作,那么显然component返回的错误与操作返回的错误无关。如果CB_Composite处理零操作,则返回的错误列表包括:

CB_COMPOUND error returns

CB_复合错误返回

   +------------------------------+------------------------------------+
   | Error                        | Notes                              |
   +------------------------------+------------------------------------+
   | NFS4ERR_BADCHAR              | The tag argument has a character   |
   |                              | the replier does not support.      |
   | NFS4ERR_BADXDR               |                                    |
   | NFS4ERR_DELAY                |                                    |
   | NFS4ERR_INVAL                | The tag argument is not in UTF-8   |
   |                              | encoding.                          |
   | NFS4ERR_MINOR_VERS_MISMATCH  |                                    |
   | NFS4ERR_SERVERFAULT          |                                    |
   | NFS4ERR_TOO_MANY_OPS         |                                    |
   | NFS4ERR_REP_TOO_BIG          |                                    |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE |                                    |
   | NFS4ERR_REQ_TOO_BIG          |                                    |
   +------------------------------+------------------------------------+
        
   +------------------------------+------------------------------------+
   | Error                        | Notes                              |
   +------------------------------+------------------------------------+
   | NFS4ERR_BADCHAR              | The tag argument has a character   |
   |                              | the replier does not support.      |
   | NFS4ERR_BADXDR               |                                    |
   | NFS4ERR_DELAY                |                                    |
   | NFS4ERR_INVAL                | The tag argument is not in UTF-8   |
   |                              | encoding.                          |
   | NFS4ERR_MINOR_VERS_MISMATCH  |                                    |
   | NFS4ERR_SERVERFAULT          |                                    |
   | NFS4ERR_TOO_MANY_OPS         |                                    |
   | NFS4ERR_REP_TOO_BIG          |                                    |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE |                                    |
   | NFS4ERR_REQ_TOO_BIG          |                                    |
   +------------------------------+------------------------------------+
        

Table 15

表15

20. NFSv4.1 Callback Operations
20. NFSv4.1回调操作
20.1. Operation 3: CB_GETATTR - Get Attributes
20.1. 操作3:CB_GETATTR-Get属性
20.1.1. ARGUMENT
20.1.1. 论点
   struct CB_GETATTR4args {
           nfs_fh4 fh;
           bitmap4 attr_request;
   };
        
   struct CB_GETATTR4args {
           nfs_fh4 fh;
           bitmap4 attr_request;
   };
        
20.1.2. RESULT
20.1.2. 后果
   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;
   };
        
20.1.3. DESCRIPTION
20.1.3. 描述

The CB_GETATTR operation is used by the server to obtain the current modified state of a file that has been OPEN_DELEGATE_WRITE delegated. The size and change attributes are the only ones guaranteed to be serviced by the client. See Section 10.4.3 for a full description of how the client and server are to interact with the use of CB_GETATTR.

服务器使用CB_GETATTR操作获取已打开的文件的当前修改状态。大小和更改属性是唯一保证由客户机提供服务的属性。有关客户端和服务器如何与CB_GETATTR的使用交互的完整描述,请参见第10.4.3节。

If the filehandle specified is not one for which the client holds an OPEN_DELEGATE_WRITE delegation, an NFS4ERR_BADHANDLE error is returned.

如果指定的filehandle不是客户端持有OPEN_DELEGATE_WRITE委派的文件句柄,则返回NFS4ERR_BADHANDLE错误。

20.1.4. IMPLEMENTATION
20.1.4. 实施

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

客户机仅为更改属性和可能更改的属性(时间、修改和大小)返回属性掩码位和相关属性值。

20.2. Operation 4: CB_RECALL - Recall a Delegation
20.2. 操作4:CB_召回-召回委托
20.2.1. ARGUMENT
20.2.1. 论点
   struct CB_RECALL4args {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
   struct CB_RECALL4args {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };
        
20.2.2. RESULT
20.2.2. 后果
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
   struct CB_RECALL4res {
           nfsstat4        status;
   };
        
20.2.3. DESCRIPTION
20.2.3. 描述

The CB_RECALL operation is used to begin the process of recalling a delegation and returning it to the server.

CB_回调操作用于开始回调委托并将其返回到服务器的过程。

The truncate flag is used to optimize recall for a file object that is a regular file and is about to be truncated to zero. When it is TRUE, the client is freed of the obligation to propagate modified data for the file to the server, since this data is irrelevant.

truncate标志用于优化作为常规文件且即将被截断为零的文件对象的调用。如果为TRUE,则客户机无需将修改后的文件数据传播到服务器,因为这些数据是无关的。

If the handle specified is not one for which the client holds a 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。

20.2.4. IMPLEMENTATION
20.2.4. 实施

The client SHOULD reply to the callback immediately. Replying does not complete the recall except when the value of the reply's status field is neither NFS4ERR_DELAY nor NFS4_OK. The recall is not complete until the delegation is returned using a DELEGRETURN operation.

客户端应该立即回复回调。应答不会完成调用,除非应答状态字段的值既不是NFS4ERR_DELAY也不是NFS4_OK。只有使用DELEGRETURN操作返回委派,调用才会完成。

20.3. Operation 5: CB_LAYOUTRECALL - Recall Layout from Client
20.3. 操作5:CB_布局调用-从客户端调用布局
20.3.1. ARGUMENT
20.3.1. 论点
   /*
    * NFSv4.1 callback arguments and results
    */
        
   /*
    * NFSv4.1 callback arguments and results
    */
        
   enum layoutrecall_type4 {
           LAYOUTRECALL4_FILE = LAYOUT4_RET_REC_FILE,
           LAYOUTRECALL4_FSID = LAYOUT4_RET_REC_FSID,
           LAYOUTRECALL4_ALL  = LAYOUT4_RET_REC_ALL
   };
        
   enum layoutrecall_type4 {
           LAYOUTRECALL4_FILE = LAYOUT4_RET_REC_FILE,
           LAYOUTRECALL4_FSID = LAYOUT4_RET_REC_FSID,
           LAYOUTRECALL4_ALL  = LAYOUT4_RET_REC_ALL
   };
        
   struct layoutrecall_file4 {
           nfs_fh4         lor_fh;
           offset4         lor_offset;
           length4         lor_length;
           stateid4        lor_stateid;
   };
        
   struct layoutrecall_file4 {
           nfs_fh4         lor_fh;
           offset4         lor_offset;
           length4         lor_length;
           stateid4        lor_stateid;
   };
        
   union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) {
   case LAYOUTRECALL4_FILE:
           layoutrecall_file4 lor_layout;
   case LAYOUTRECALL4_FSID:
           fsid4              lor_fsid;
   case LAYOUTRECALL4_ALL:
           void;
   };
        
   union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) {
   case LAYOUTRECALL4_FILE:
           layoutrecall_file4 lor_layout;
   case LAYOUTRECALL4_FSID:
           fsid4              lor_fsid;
   case LAYOUTRECALL4_ALL:
           void;
   };
        
   struct CB_LAYOUTRECALL4args {
           layouttype4             clora_type;
           layoutiomode4           clora_iomode;
           bool                    clora_changed;
           layoutrecall4           clora_recall;
   };
        
   struct CB_LAYOUTRECALL4args {
           layouttype4             clora_type;
           layoutiomode4           clora_iomode;
           bool                    clora_changed;
           layoutrecall4           clora_recall;
   };
        
20.3.2. RESULT
20.3.2. 后果
   struct CB_LAYOUTRECALL4res {
           nfsstat4        clorr_status;
   };
        
   struct CB_LAYOUTRECALL4res {
           nfsstat4        clorr_status;
   };
        
20.3.3. DESCRIPTION
20.3.3. 描述

The CB_LAYOUTRECALL operation is used by the server to recall layouts from the client; as a result, the client will begin the process of returning layouts via LAYOUTRETURN. The CB_LAYOUTRECALL operation specifies one of three forms of recall processing with the value of layoutrecall_type4. The recall is for one of the following: a specific layout of a specific file (LAYOUTRECALL4_FILE), an entire file system ID (LAYOUTRECALL4_FSID), or all file systems (LAYOUTRECALL4_ALL).

服务器使用CB_LAYOUTRECALL操作从客户端调用布局;因此,客户端将开始通过LAYOUTRETURN返回布局的过程。CB_LAYOUTRECALL操作使用LAYOUTRECALL_type4的值指定三种召回处理形式之一。调用是针对以下内容之一:特定文件的特定布局(LAYOUTRECALL4_文件)、整个文件系统ID(LAYOUTRECALL4_FSID)或所有文件系统(LAYOUTRECALL4_all)。

The behavior of the operation varies based on the value of the layoutrecall_type4. The value and behaviors are:

该操作的行为因layoutrecall_type4的值而异。价值和行为是:

LAYOUTRECALL4_FILE

LAYOUTRECALL4_文件

For a layout to match the recall request, the values of the following fields must match those of the layout: clora_type, clora_iomode, lor_fh, and the byte-range specified by lor_offset and lor_length. The clora_iomode field may have a special value of LAYOUTIOMODE4_ANY. The special value LAYOUTIOMODE4_ANY will match any iomode originally returned in a layout; therefore, it acts as a wild card. The other special value used is for lor_length. If lor_length has a value of NFS4_UINT64_MAX, the lor_length field means the maximum possible file size. If a matching layout is found, it MUST be returned using the

要使版面与调用请求匹配,以下字段的值必须与版面的值匹配:clora_类型、clora_iomode、lor_fh以及lor_偏移量和lor_长度指定的字节范围。clora_iomode字段可能具有LAYOUTIOMODE4_ANY的特殊值。特殊值LAYOUTIOMODE4_ANY将匹配最初在布局中返回的任何iomode;因此,它起着通配符的作用。使用的另一个特殊值是lor_长度。如果lor_length的值为NFS4_UINT64_MAX,则lor_length字段表示可能的最大文件大小。如果找到匹配的布局,则必须使用

LAYOUTRETURN operation (see Section 18.44). An example of the field's special value use is if clora_iomode is LAYOUTIOMODE4_ANY, lor_offset is zero, and lor_length is NFS4_UINT64_MAX, then the entire layout is to be returned.

LAYOUTRETURN操作(见第18.44节)。字段特殊值使用的一个示例是,如果clora_iomode为LAYOUTIOMODE4_ANY,lor_offset为零,lor_length为NFS4_UINT64_MAX,则将返回整个布局。

The NFS4ERR_NOMATCHING_LAYOUT error is only returned when the client does not hold layouts for the file or if the client does not have any overlapping layouts for the specification in the layout recall.

NFS4ERR_NOMATCHING_布局错误仅在客户端未保留文件的布局或客户端在布局调用中没有任何重叠的布局时返回。

LAYOUTRECALL4_FSID and LAYOUTRECALL4_ALL

LAYOUTRECALL4_FSID和LAYOUTRECALL4_ALL

If LAYOUTRECALL4_FSID is specified, the fsid specifies the file system for which any outstanding layouts MUST be returned. If LAYOUTRECALL4_ALL is specified, all outstanding layouts MUST be returned. In addition, LAYOUTRECALL4_FSID and LAYOUTRECALL4_ALL specify that all the storage device ID to storage device address mappings in the affected file system(s) are also recalled. The respective LAYOUTRETURN with either LAYOUTRETURN4_FSID or LAYOUTRETURN4_ALL acknowledges to the server that the client invalidated the said device mappings. See Section 12.5.5.2.1.5 for considerations with "bulk" recall of layouts.

如果指定了LAYOUTRECALL4_FSID,则FSID指定必须为其返回任何未完成布局的文件系统。如果指定了LAYOUTRECALL4_ALL,则必须返回所有未完成的布局。此外,LAYUTRECALL4_FSID和LAYUTRECALL4_ALL指定还调用受影响文件系统中所有存储设备ID到存储设备地址的映射。具有LAYUTRETURN4_FSID或LAYUTRETURN4_的相应LAYUTRETURN均向服务器确认客户端使所述设备映射无效。关于布局“批量”召回的注意事项,请参见第12.5.5.2.1.5节。

The NFS4ERR_NOMATCHING_LAYOUT error is only returned when the client does not hold layouts and does not have valid deviceid mappings.

NFS4ERR_NOMATCHING_布局错误仅在客户端不持有布局且没有有效的deviceid映射时返回。

In processing the layout recall request, the client also varies its behavior based on the value of the clora_changed field. This field is used by the server to provide additional context for the reason why the layout is being recalled. A FALSE value for clora_changed indicates that no change in the layout is expected and the client may write modified data to the storage devices involved; this must be done prior to returning the layout via LAYOUTRETURN. A TRUE value for clora_changed indicates that the server is changing the layout. Examples of layout changes and reasons for a TRUE indication are the following: the metadata server is restriping the file or a permanent error has occurred on a storage device and the metadata server would like to provide a new layout for the file. Therefore, a clora_changed value of TRUE indicates some level of change for the layout and the client SHOULD NOT write and commit modified data to the storage devices. In this case, the client writes and commits data through the metadata server.

在处理布局调用请求时,客户端还根据clora_changed字段的值改变其行为。服务器使用此字段为调用布局的原因提供附加上下文。clora_changed的假值表示预计布局不会发生变化,客户端可能会将修改后的数据写入相关存储设备;这必须在通过LAYOUTRETURN返回布局之前完成。clora_changed的真值表示服务器正在更改布局。布局更改的示例和真实指示的原因如下:元数据服务器正在重新调整文件的优先级,或者存储设备上发生了永久性错误,元数据服务器希望为文件提供新布局。因此,clora_changed值TRUE表示布局发生了一定程度的更改,客户端不应将修改后的数据写入并提交到存储设备。在这种情况下,客户机通过元数据服务器写入和提交数据。

See Section 12.5.3 for a description of how the lor_stateid field in the arguments is to be constructed. Note that the "seqid" field of lor_stateid MUST NOT be zero. See Sections 8.2, 12.5.3, and 12.5.5.2 for a further discussion and requirements.

有关如何构造参数中的lor_stateid字段的说明,请参见第12.5.3节。请注意,lor_stateid的“seqid”字段不能为零。有关进一步的讨论和要求,请参见第8.2节、第12.5.3节和第12.5.5.2节。

20.3.4. IMPLEMENTATION
20.3.4. 实施

The client's processing for CB_LAYOUTRECALL is similar to CB_RECALL (recall of file delegations) in that the client responds to the request before actually returning layouts via the LAYOUTRETURN operation. While the client responds to the CB_LAYOUTRECALL immediately, the operation is not considered complete (i.e., considered pending) until all affected layouts are returned to the server via the LAYOUTRETURN operation.

客户端对CB_LAYOUTRECALL的处理类似于CB_RECALL(调用文件委派),因为客户端在通过LAYOUTRETURN操作实际返回布局之前响应请求。当客户端立即响应CB_LAYOUTRECALL时,在所有受影响的布局通过LAYOUTRETURN操作返回到服务器之前,操作不会被视为完成(即,被视为挂起)。

Before returning the layout to the server via LAYOUTRETURN, the client should wait for the response from in-process or in-flight READ, WRITE, or COMMIT operations that use the recalled layout.

在通过LAYOUTRETURN将布局返回到服务器之前,客户端应等待使用调用布局的进程中或正在进行的读、写或提交操作的响应。

If the client is holding modified data that is affected by a recalled layout, the client has various options for writing the data to the server. As always, the client may write the data through the metadata server. In fact, the client may not have a choice other than writing to the metadata server when the clora_changed argument is TRUE and a new layout is unavailable from the server. However, the client may be able to write the modified data to the storage device if the clora_changed argument is FALSE; this needs to be done before returning the layout via LAYOUTRETURN. If the client were to obtain a new layout covering the modified data's byte-range, then writing to the storage devices is an available alternative. Note that before obtaining a new layout, the client must first return the original layout.

如果客户机保存的修改数据受调用布局的影响,则客户机具有将数据写入服务器的各种选项。与往常一样,客户机可以通过元数据服务器写入数据。事实上,当clora_changed参数为TRUE且服务器无法提供新布局时,客户端可能除了向元数据服务器写入数据之外别无选择。但是,如果clora_changed参数为FALSE,则客户端可能能够将修改后的数据写入存储设备;这需要在通过LAYOUTRETURN返回布局之前完成。如果客户机要获得一个覆盖修改后数据字节范围的新布局,则可以选择向存储设备写入。请注意,在获取新布局之前,客户端必须首先返回原始布局。

In the case of modified data being written while the layout is held, the client must use LAYOUTCOMMIT operations at the appropriate time; as required LAYOUTCOMMIT must be done before the LAYOUTRETURN. If a large amount of modified data is outstanding, the client may send LAYOUTRETURNs for portions of the recalled layout; this allows the server to monitor the client's progress and adherence to the original recall request. However, the last LAYOUTRETURN in a sequence of returns MUST specify the full range being recalled (see Section 12.5.5.1 for details).

如果在保存布局时写入修改的数据,客户端必须在适当的时间使用LAYOUTCOMMIT操作;根据需要,必须在LAYOUTRETURN之前完成LAYOUTCOMMIT。如果大量修改的数据未完成,则客户机可以发送所调用布局的部分的LAYOUTRETURNs;这允许服务器监视客户机的进度以及对原始召回请求的遵守情况。但是,返回序列中的最后一次LAYOUTRETURN必须指定召回的整个范围(详情见第12.5.5.1节)。

If a server needs to delete a device ID and there are layouts referring to the device ID, CB_LAYOUTRECALL MUST be invoked to cause the client to return all layouts referring to the device ID before the server can delete the device ID. If the client does not return the affected layouts, the server MAY revoke the layouts.

如果服务器需要删除设备ID,并且存在引用该设备ID的布局,则必须调用CB_LAYOUTRECALL以使客户端返回引用该设备ID的所有布局,然后服务器才能删除该设备ID。如果客户端未返回受影响的布局,则服务器可能会撤销该布局。

20.4. Operation 6: CB_NOTIFY - Notify Client of Directory Changes
20.4. 操作6:CB_NOTIFY-通知客户端目录更改
20.4.1. ARGUMENT
20.4.1. 论点
   /*
    * Directory notification types.
    */
   enum notify_type4 {
           NOTIFY4_CHANGE_CHILD_ATTRS = 0,
           NOTIFY4_CHANGE_DIR_ATTRS = 1,
           NOTIFY4_REMOVE_ENTRY = 2,
           NOTIFY4_ADD_ENTRY = 3,
           NOTIFY4_RENAME_ENTRY = 4,
           NOTIFY4_CHANGE_COOKIE_VERIFIER = 5
   };
        
   /*
    * Directory notification types.
    */
   enum notify_type4 {
           NOTIFY4_CHANGE_CHILD_ATTRS = 0,
           NOTIFY4_CHANGE_DIR_ATTRS = 1,
           NOTIFY4_REMOVE_ENTRY = 2,
           NOTIFY4_ADD_ENTRY = 3,
           NOTIFY4_RENAME_ENTRY = 4,
           NOTIFY4_CHANGE_COOKIE_VERIFIER = 5
   };
        
   /* Changed entry information.  */
   struct notify_entry4 {
           component4      ne_file;
           fattr4          ne_attrs;
   };
        
   /* Changed entry information.  */
   struct notify_entry4 {
           component4      ne_file;
           fattr4          ne_attrs;
   };
        
   /* Previous entry information */
   struct prev_entry4 {
           notify_entry4   pe_prev_entry;
           /* what READDIR returned for this entry */
           nfs_cookie4     pe_prev_entry_cookie;
   };
        
   /* Previous entry information */
   struct prev_entry4 {
           notify_entry4   pe_prev_entry;
           /* what READDIR returned for this entry */
           nfs_cookie4     pe_prev_entry_cookie;
   };
        
   struct notify_remove4 {
           notify_entry4   nrm_old_entry;
           nfs_cookie4     nrm_old_entry_cookie;
   };
        
   struct notify_remove4 {
           notify_entry4   nrm_old_entry;
           nfs_cookie4     nrm_old_entry_cookie;
   };
        
   struct notify_add4 {
           /*
            * Information on object
            * possibly renamed over.
            */
           notify_remove4      nad_old_entry<1>;
           notify_entry4       nad_new_entry;
           /* what READDIR would have returned for this entry */
           nfs_cookie4         nad_new_entry_cookie<1>;
           prev_entry4         nad_prev_entry<1>;
           bool                nad_last_entry;
   };
        
   struct notify_add4 {
           /*
            * Information on object
            * possibly renamed over.
            */
           notify_remove4      nad_old_entry<1>;
           notify_entry4       nad_new_entry;
           /* what READDIR would have returned for this entry */
           nfs_cookie4         nad_new_entry_cookie<1>;
           prev_entry4         nad_prev_entry<1>;
           bool                nad_last_entry;
   };
        
   struct notify_attr4 {
           notify_entry4   na_changed_entry;
   };
        
   struct notify_attr4 {
           notify_entry4   na_changed_entry;
   };
        
   struct notify_rename4 {
           notify_remove4  nrn_old_entry;
           notify_add4     nrn_new_entry;
   };
        
   struct notify_rename4 {
           notify_remove4  nrn_old_entry;
           notify_add4     nrn_new_entry;
   };
        
   struct notify_verifier4 {
           verifier4       nv_old_cookieverf;
           verifier4       nv_new_cookieverf;
   };
        
   struct notify_verifier4 {
           verifier4       nv_old_cookieverf;
           verifier4       nv_new_cookieverf;
   };
        
   /*
    * Objects of type notify_<>4 and
    * notify_device_<>4 are encoded in this.
    */
   typedef opaque notifylist4<>;
        
   /*
    * Objects of type notify_<>4 and
    * notify_device_<>4 are encoded in this.
    */
   typedef opaque notifylist4<>;
        
   struct notify4 {
           /* composed from notify_type4 or notify_deviceid_type4 */
           bitmap4         notify_mask;
           notifylist4     notify_vals;
   };
        
   struct notify4 {
           /* composed from notify_type4 or notify_deviceid_type4 */
           bitmap4         notify_mask;
           notifylist4     notify_vals;
   };
        
   struct CB_NOTIFY4args {
           stateid4    cna_stateid;
           nfs_fh4     cna_fh;
           notify4     cna_changes<>;
   };
        
   struct CB_NOTIFY4args {
           stateid4    cna_stateid;
           nfs_fh4     cna_fh;
           notify4     cna_changes<>;
   };
        
20.4.2. RESULT
20.4.2. 后果
   struct CB_NOTIFY4res {
           nfsstat4    cnr_status;
   };
        
   struct CB_NOTIFY4res {
           nfsstat4    cnr_status;
   };
        
20.4.3. DESCRIPTION
20.4.3. 描述

The CB_NOTIFY operation is used by the server to send notifications to clients about changes to delegated directories. The registration of notifications for the directories occurs when the delegation is established using GET_DIR_DELEGATION. These notifications are sent over the backchannel. The notification is sent once the original request has been processed on the server. The server will send an array of notifications for changes that might have occurred in the

服务器使用CB_NOTIFY操作向客户端发送有关委托目录更改的通知。当使用GET_DIR_delegation建立委派时,会注册目录的通知。这些通知通过反向通道发送。在服务器上处理原始请求后,将发送通知。服务器将发送一个通知数组,通知可能已在中发生的更改

directory. The notifications are sent as list of pairs of bitmaps and values. See Section 3.3.7 for a description of how NFSv4.1 bitmaps work.

目录通知以位图和值对列表的形式发送。有关NFSv4.1位图工作原理的说明,请参见第3.3.7节。

If the server has more notifications than can fit in the CB_COMPOUND request, it SHOULD send a sequence of serial CB_COMPOUND requests so that the client's view of the directory does not become confused. For example, if the server indicates that a file named "foo" is added and that the file "foo" is removed, the order in which the client receives these notifications needs to be the same as the order in which the corresponding operations occurred on the server.

如果服务器的通知数量超过了CB_复合请求所能容纳的数量,那么它应该发送一系列连续的CB_复合请求,这样客户端的目录视图就不会变得混乱。例如,如果服务器指示添加了名为“foo”的文件,并且删除了文件“foo”,则客户端接收这些通知的顺序需要与服务器上相应操作的发生顺序相同。

If the client holding the delegation makes any changes in the directory that cause files or sub-directories to be added or removed, the server will notify that client of the resulting change(s). If the client holding the delegation is making attribute or cookie verifier changes only, the server does not need to send notifications to that client. The server will send the following information for each operation:

如果持有委托的客户端在目录中进行任何更改,导致文件或子目录被添加或删除,服务器将通知该客户端结果更改。如果持有委托的客户机仅在更改属性或cookie验证器,则服务器不需要向该客户机发送通知。服务器将为每个操作发送以下信息:

NOTIFY4_ADD_ENTRY The server will send information about the new directory entry being created along with the cookie for that entry. The entry information (data type notify_add4) includes the component name of the entry and attributes. The server will send this type of entry when a file is actually being created, when an entry is being added to a directory as a result of a rename across directories (see below), and when a hard link is being created to an existing file. If this entry is added to the end of the directory, the server will set the nad_last_entry flag to TRUE. If the file is added such that there is at least one entry before it, the server will also return the previous entry information (nad_prev_entry, a variable-length array of up to one element. If the array is of zero length, there is no previous entry), along with its cookie. This is to help clients find the right location in their file name caches and directory caches where this entry should be cached. If the new entry's cookie is available, it will be in the nad_new_entry_cookie (another variable-length array of up to one element) field. If the addition of the entry causes another entry to be deleted (which can only happen in the rename case) atomically with the addition, then information on this entry is reported in nad_old_entry.

NOTIFY4\u ADD\u条目服务器将发送有关正在创建的新目录条目的信息以及该条目的cookie。条目信息(数据类型notify_add4)包括条目的组件名称和属性。当实际创建文件时,当跨目录重命名(见下文)将条目添加到目录时,以及当创建到现有文件的硬链接时,服务器将发送此类条目。如果将此条目添加到目录的末尾,服务器将把nad_last_条目标志设置为TRUE。如果添加的文件前面至少有一个条目,服务器还将返回以前的条目信息(nad_prev_entry,最多一个元素的可变长度数组。如果数组长度为零,则没有以前的条目)及其cookie。这是为了帮助客户端在文件名缓存和目录缓存中找到应该缓存此项的正确位置。如果新条目的cookie可用,它将位于nad_new_entry_cookie(另一个最多一个元素的可变长度数组)字段中。如果该条目的添加导致另一个条目在添加时原子性地被删除(这只能发生在重命名情况下),那么该条目的信息将在nad_old_条目中报告。

NOTIFY4_REMOVE_ENTRY The server will send information about the directory entry being deleted. The server will also send the cookie value for the deleted entry so that clients can get to the cached information for this entry.

NOTIFY4\u REMOVE\u条目服务器将发送有关正在删除的目录条目的信息。服务器还将发送已删除条目的cookie值,以便客户端可以访问该条目的缓存信息。

NOTIFY4_RENAME_ENTRY The server will send information about both the old entry and the new entry. This includes the name and attributes for each entry. In addition, if the rename causes the deletion of an entry (i.e., the case of a file renamed over), then this is reported in nrn_new_new_entry.nad_old_entry. This notification is only sent if both entries are in the same directory. If the rename is across directories, the server will send a remove notification to one directory and an add notification to the other directory, assuming both have a directory delegation.

NOTIFY4\u RENAME\u条目服务器将发送有关旧条目和新条目的信息。这包括每个条目的名称和属性。此外,如果重命名导致删除条目(即,文件重命名为over),则这将在nrn_new_new_entry.nad_old_entry中报告。仅当两个条目位于同一目录中时,才会发送此通知。如果重命名是跨目录的,则服务器将向一个目录发送删除通知,并向另一个目录发送添加通知,假设两者都有目录委派。

NOTIFY4_CHANGE_CHILD_ATTRS/NOTIFY4_CHANGE_DIR_ATTRS The client will use the attribute mask to inform the server of attributes for which it wants to receive notifications. This change notification can be requested for changes to the attributes of the directory as well as changes to any file's attributes in the directory by using two separate attribute masks. The client cannot ask for change attribute notification for a specific file. One attribute mask covers all the files in the directory. Upon any attribute change, the server will send back the values of changed attributes. Notifications might not make sense for some file system-wide attributes, and it is up to the server to decide which subset it wants to support. The client can negotiate the frequency of attribute notifications by letting the server know how often it wants to be notified of an attribute change. The server will return supported notification frequencies or an indication that no notification is permitted for directory or child attributes by setting the dir_notif_delay and dir_entry_notif_delay attributes, respectively.

NOTIFY4\u CHANGE\u CHILD\u ATTRS/NOTIFY4\u CHANGE\u DIR\u ATTRS客户端将使用属性掩码通知服务器它希望接收通知的属性。通过使用两个单独的属性掩码,可以请求此更改通知,以更改目录的属性以及目录中任何文件的属性。客户端无法请求特定文件的更改属性通知。一个属性掩码覆盖目录中的所有文件。任何属性更改后,服务器都会发回更改属性的值。对于某些文件系统范围的属性,通知可能没有意义,由服务器决定要支持哪个子集。客户机可以通过让服务器知道它希望收到属性更改通知的频率来协商属性通知的频率。通过分别设置dir_notif_delay和dir_entry_notif_delay属性,服务器将返回支持的通知频率或指示不允许通知目录或子属性。

NOTIFY4_CHANGE_COOKIE_VERIFIER If the cookie verifier changes while a client is holding a delegation, the server will notify the client so that it can invalidate its cookies and re-send a READDIR to get the new set of cookies.

NOTIFY4\u CHANGE\u COOKIE\u验证程序如果COOKIE验证程序在客户端持有委托时发生更改,服务器将通知客户端,以便使其COOKIE无效,并重新发送READDIR以获取新的COOKIE集。

20.5. Operation 7: CB_PUSH_DELEG - Offer Previously Requested Delegation to Client

20.5. 操作7:CB_PUSH_DELEG-提供先前请求的委托给客户

20.5.1. ARGUMENT
20.5.1. 论点
   struct CB_PUSH_DELEG4args {
           nfs_fh4          cpda_fh;
           open_delegation4 cpda_delegation;
        
   struct CB_PUSH_DELEG4args {
           nfs_fh4          cpda_fh;
           open_delegation4 cpda_delegation;
        

};

};

20.5.2. RESULT
20.5.2. 后果
   struct CB_PUSH_DELEG4res {
           nfsstat4 cpdr_status;
   };
        
   struct CB_PUSH_DELEG4res {
           nfsstat4 cpdr_status;
   };
        
20.5.3. DESCRIPTION
20.5.3. 描述

CB_PUSH_DELEG is used by the server both to signal to the client that the delegation it wants (previously indicated via a want established from an OPEN or WANT_DELEGATION operation) is available and to simultaneously offer the delegation to the client. The client has the choice of accepting the delegation by returning NFS4_OK to the server, delaying the decision to accept the offered delegation by returning NFS4ERR_DELAY, or permanently rejecting the offer of the delegation by returning NFS4ERR_REJECT_DELEG. When a delegation is rejected in this fashion, the want previously established is permanently deleted and the delegation is subject to acquisition by another client.

服务器使用CB_PUSH_DELEG向客户端发出信号,表示其想要的委托(之前通过开放或想要的委托操作建立的想要来指示)可用,并同时向客户端提供委托。客户端可以选择通过向服务器返回NFS4_OK来接受委托,通过返回NFS4ERR_DELAY来延迟接受提供的委托的决定,或者通过返回NFS4ERR_REJECT_DELEG来永久拒绝委托的提议。当以这种方式拒绝委托时,先前建立的需求将被永久删除,并且委托将由另一个客户获取。

20.5.4. IMPLEMENTATION
20.5.4. 实施

If the client does return NFS4ERR_DELAY and there is a conflicting delegation request, the server MAY process it at the expense of the client that returned NFS4ERR_DELAY. The client's want will not be cancelled, but MAY be processed behind other delegation requests or registered wants.

如果客户端确实返回NFS4ERR_延迟,并且存在冲突的委托请求,则服务器可能会以返回NFS4ERR_延迟的客户端为代价来处理该委托请求。客户的需求不会被取消,但可以在其他委托请求或注册需求之后进行处理。

When a client returns a status other than NFS4_OK, NFS4ERR_DELAY, or NFS4ERR_REJECT_DELAY, the want remains pending, although servers may decide to cancel the want by sending a CB_WANTS_CANCELLED.

当客户端返回NFS4_OK、NFS4ERR_DELAY或NFS4ERR_REJECT_DELAY以外的状态时,请求仍处于挂起状态,尽管服务器可能会通过发送CB_WANTS_CANCELLED来决定取消请求。

20.6. Operation 8: CB_RECALL_ANY - Keep Any N Recallable Objects
20.6. 操作8:CB_RECALL_ANY-保留任意N个可重调对象
20.6.1. ARGUMENT
20.6.1. 论点
   const RCA4_TYPE_MASK_RDATA_DLG          = 0;
   const RCA4_TYPE_MASK_WDATA_DLG          = 1;
   const RCA4_TYPE_MASK_DIR_DLG            = 2;
   const RCA4_TYPE_MASK_FILE_LAYOUT        = 3;
   const RCA4_TYPE_MASK_BLK_LAYOUT         = 4;
   const RCA4_TYPE_MASK_OBJ_LAYOUT_MIN     = 8;
   const RCA4_TYPE_MASK_OBJ_LAYOUT_MAX     = 9;
   const RCA4_TYPE_MASK_OTHER_LAYOUT_MIN   = 12;
   const RCA4_TYPE_MASK_OTHER_LAYOUT_MAX   = 15;
        
   const RCA4_TYPE_MASK_RDATA_DLG          = 0;
   const RCA4_TYPE_MASK_WDATA_DLG          = 1;
   const RCA4_TYPE_MASK_DIR_DLG            = 2;
   const RCA4_TYPE_MASK_FILE_LAYOUT        = 3;
   const RCA4_TYPE_MASK_BLK_LAYOUT         = 4;
   const RCA4_TYPE_MASK_OBJ_LAYOUT_MIN     = 8;
   const RCA4_TYPE_MASK_OBJ_LAYOUT_MAX     = 9;
   const RCA4_TYPE_MASK_OTHER_LAYOUT_MIN   = 12;
   const RCA4_TYPE_MASK_OTHER_LAYOUT_MAX   = 15;
        
   struct  CB_RECALL_ANY4args      {
           uint32_t        craa_objects_to_keep;
           bitmap4         craa_type_mask;
   };
        
   struct  CB_RECALL_ANY4args      {
           uint32_t        craa_objects_to_keep;
           bitmap4         craa_type_mask;
   };
        
20.6.2. RESULT
20.6.2. 后果
   struct CB_RECALL_ANY4res {
           nfsstat4        crar_status;
   };
        
   struct CB_RECALL_ANY4res {
           nfsstat4        crar_status;
   };
        
20.6.3. DESCRIPTION
20.6.3. 描述

The server may decide that it cannot hold all of the state for recallable objects, such as delegations and layouts, without running out of resources. In such a case, while not optimal, the server is free to recall individual objects to reduce the load.

服务器可能会决定,如果不耗尽资源,它无法保存可重调用对象(如委托和布局)的所有状态。在这种情况下,虽然不是最优的,但服务器可以自由地调用单个对象以减少负载。

Because the general purpose of such recallable objects as delegations is to eliminate client interaction with the server, the server cannot interpret lack of recent use as indicating that the object is no longer useful. The absence of visible use is consistent with a delegation keeping potential operations from being sent to the server. In the case of layouts, while it is true that the usefulness of a layout is indicated by the use of the layout when storage devices receive I/O requests, because there is no mandate that a storage device indicate to the metadata server any past or present use of a layout, the metadata server is not likely to know which layouts are good candidates to recall in response to low resources.

由于委托等可重新调用对象的一般目的是消除客户端与服务器的交互,因此服务器不能将最近没有使用解释为表明该对象不再有用。没有可见的使用与委托保持一致,使潜在的操作不会被发送到服务器。在布局的情况下,虽然确实通过在存储设备接收I/O请求时使用布局来指示布局的有用性,但存储设备没有向元数据服务器指示布局的任何过去或当前使用的指令,元数据服务器不太可能知道哪些布局适合在资源不足时调用。

In order to implement an effective reclaim scheme for such objects, the server's knowledge of available resources must be used to determine when objects must be recalled with the clients selecting the actual objects to be returned.

为了对这些对象实施有效的回收方案,必须使用服务器对可用资源的了解来确定何时必须在客户端选择要返回的实际对象时调用对象。

Server implementations may differ in their resource allocation requirements. For example, one server may share resources among all classes of recallable objects, whereas another may use separate resource pools for layouts and for delegations, or further separate resources by types of delegations.

服务器实现的资源分配要求可能不同。例如,一台服务器可以在所有类别的可重调用对象之间共享资源,而另一台服务器可以为布局和委派使用单独的资源池,或者按委派类型进一步分离资源。

When a given resource pool is over-utilized, the server can send a CB_RECALL_ANY to clients holding recallable objects of the types involved, allowing it to keep a certain number of such objects and return any excess. A mask specifies which types of objects are to be limited. The client chooses, based on its own knowledge of current usefulness, which of the objects in that class should be returned.

当给定的资源池被过度利用时,服务器可以向持有所涉及类型的可重调对象的客户端发送CB_RECALL_ANY,允许它保留一定数量的此类对象并返回多余的对象。遮罩指定要限制的对象类型。客户机根据自己对当前有用性的了解,选择应该返回该类中的哪些对象。

A number of bits are defined. For some of these, ranges are defined and it is up to the definition of the storage protocol to specify how these are to be used. There are ranges reserved for object-based storage protocols and for other experimental storage protocols. An RFC defining such a storage protocol needs to specify how particular bits within its range are to be used. For example, it may specify a mapping between attributes of the layout (read vs. write, size of area) and the bit to be used, or it may define a field in the layout where the associated bit position is made available by the server to the client.

定义了许多位。对于其中一些,定义了范围,并且由存储协议的定义来指定如何使用这些范围。有一些范围是为基于对象的存储协议和其他实验性存储协议保留的。定义这种存储协议的RFC需要指定如何使用其范围内的特定位。例如,它可以指定布局的属性(读与写、区域大小)和要使用的位之间的映射,或者它可以在布局中定义一个字段,在该字段中,服务器向客户端提供相关的位位置。

RCA4_TYPE_MASK_RDATA_DLG

RCA4类型屏蔽数据

The client is to return OPEN_DELEGATE_READ delegations on non-directory file objects.

客户端将返回非目录文件对象上的OPEN_DELEGATE_READ委托。

RCA4_TYPE_MASK_WDATA_DLG

RCA4类型掩码数据分组

The client is to return OPEN_DELEGATE_WRITE delegations on regular file objects.

客户端将返回常规文件对象上的OPEN_DELEGATE_WRITE委托。

RCA4_TYPE_MASK_DIR_DLG

RCA4类型屏蔽方向DLG

The client is to return directory delegations.

客户端将返回目录委派。

RCA4_TYPE_MASK_FILE_LAYOUT

RCA4类型屏蔽文件布局

The client is to return layouts of type LAYOUT4_NFSV4_1_FILES.

客户端将返回LAYOUT4\u NFSV4\u 1\u文件类型的布局。

RCA4_TYPE_MASK_BLK_LAYOUT

RCA4类型遮罩黑色布局图

See [41] for a description.

有关说明,请参见[41]。

RCA4_TYPE_MASK_OBJ_LAYOUT_MIN to RCA4_TYPE_MASK_OBJ_LAYOUT_MAX

RCA4类型屏蔽对象布局最小值至RCA4类型屏蔽对象布局最大值

See [40] for a description.

有关说明,请参见[40]。

RCA4_TYPE_MASK_OTHER_LAYOUT_MIN to RCA4_TYPE_MASK_OTHER_LAYOUT_MAX

RCA4类型屏蔽其他布局最小值至RCA4类型屏蔽其他布局最大值

This range is reserved for telling the client to recall layouts of experimental or site-specific layout types (see Section 3.3.13).

该范围用于告知客户召回实验性或现场特定布局类型的布局(见第3.3.13节)。

When a bit is set in the type mask that corresponds to an undefined type of recallable object, NFS4ERR_INVAL MUST be returned. When a bit is set that corresponds to a defined type of object but the client does not support an object of the type, NFS4ERR_INVAL MUST NOT be returned. Future minor versions of NFSv4 may expand the set of valid type mask bits.

当在类型掩码中设置与未定义的可重调对象类型相对应的位时,必须返回NFS4ERR_INVAL。当设置了与定义的对象类型相对应的位,但客户端不支持该类型的对象时,不得返回NFS4ERR_INVAL。NFSv4的未来次要版本可能会扩展有效类型掩码位集。

CB_RECALL_ANY specifies a count of objects that the client may keep as opposed to a count that the client must return. This is to avoid a potential race between a CB_RECALL_ANY that had a count of objects to free with a set of client-originated operations to return layouts or delegations. As a result of the race, the client and server would have differing ideas as to how many objects to return. Hence, the client could mistakenly free too many.

CB_RECALL_ANY指定客户端可能保留的对象计数,而不是客户端必须返回的计数。这是为了避免CB_RECALL_与一组源自客户端的返回布局或委托的操作之间可能存在的争用,这些CB_RECALL_与任何具有要释放的对象计数的CB_RECALL_之间可能存在争用。竞争的结果是,客户机和服务器对于返回多少对象会有不同的想法。因此,客户机可能会错误地释放太多。

If resource demands prompt it, the server may send another CB_RECALL_ANY with a lower count, even if it has not yet received an acknowledgment from the client for a previous CB_RECALL_ANY with the same type mask. Although the possibility exists that these will be received by the client in an order different from the order in which they were sent, any such permutation of the callback stream is harmless. It is the job of the client to bring down the size of the recallable object set in line with each CB_RECALL_ANY received, and until that obligation is met, it cannot be cancelled or modified by any subsequent CB_RECALL_ANY for the same type mask. Thus, if the server sends two CB_RECALL_ANYs, the effect will be the same as if the lower count was sent, whatever the order of recall receipt. Note that this means that a server may not cancel the effect of a CB_RECALL_ANY by sending another recall with a higher count. When a CB_RECALL_ANY is received and the count is already within the limit set or is above a limit that the client is working to get down to, that callback has no effect.

如果资源需求提示,服务器可能会发送另一个计数较低的CB_RECALL__ANY,即使它尚未收到客户端对具有相同类型掩码的前一个CB_RECALL_ANY的确认。尽管存在这样的可能性,即客户机将以不同于发送顺序的顺序接收这些消息,但回调流的任何此类排列都是无害的。客户的工作是根据接收到的每个CB_RECALL_ANY降低可重调对象集的大小,并且在该义务得到满足之前,对于相同类型的掩码,不能通过任何后续CB_RECALL_ANY取消或修改该对象集。因此,如果服务器发送两个CB_RECALL_Any,则效果将与发送较低计数时相同,无论召回接收的顺序如何。请注意,这意味着服务器可能不会通过发送另一个计数更高的调用来取消CB_RECALL_ANY的效果。当接收到CB_RECALL_ANY且计数已在设置的限制内或高于客户端正在努力达到的限制时,该回调无效。

Servers are generally free to deny recallable objects when insufficient resources are available. Note that the effect of such a policy is implicitly to give precedence to existing objects relative to requested ones, with the result that resources might not be optimally used. To prevent this, servers are well advised to make the point at which they start sending CB_RECALL_ANY callbacks somewhat below that at which they cease to give out new delegations and layouts. This allows the client to purge its less-used objects whenever appropriate and so continue to have its subsequent requests given new resources freed up by object returns.

当可用资源不足时,服务器通常可以自由拒绝可重新调用的对象。请注意,这样一个策略的效果是隐式地给予现有对象相对于请求对象的优先级,其结果是资源可能不会得到最佳利用。为了防止这种情况发生,建议服务器在开始发送CB_RECALL_任何回调的时间点稍低于停止发送新委托和布局的时间点。这允许客户机在适当的时候清除其较少使用的对象,从而在对象返回释放新资源的情况下继续执行后续请求。

20.6.4. IMPLEMENTATION
20.6.4. 实施

The client can choose to return any type of object specified by the mask. If a server wishes to limit the use of objects of a specific type, it should only specify that type in the mask it sends. Should the client fail to return requested objects, it is up to the server to handle this situation, typically by sending specific recalls (i.e., sending CB_RECALL operations) to properly limit resource usage. The server should give the client enough time to return objects before proceeding to specific recalls. This time should not be less than the lease period.

客户端可以选择返回掩码指定的任何类型的对象。如果服务器希望限制特定类型对象的使用,则只应在其发送的掩码中指定该类型。如果客户端无法返回请求的对象,则由服务器来处理这种情况,通常通过发送特定的回调(即发送CB_回调操作)来适当限制资源使用。在进行特定的回调之前,服务器应该给客户端足够的时间返回对象。此时间不得少于租赁期。

20.7. Operation 9: CB_RECALLABLE_OBJ_AVAIL - Signal Resources for Recallable Objects

20.7. 操作9:CB_可重调_OBJ_可用-可重调对象的信号资源

20.7.1. ARGUMENT
20.7.1. 论点

typedef CB_RECALL_ANY4args CB_RECALLABLE_OBJ_AVAIL4args;

typedef CB_RECALL_any4参数CB_RECALLABLE_OBJ_avail4参数;

20.7.2. RESULT
20.7.2. 后果
   struct CB_RECALLABLE_OBJ_AVAIL4res {
           nfsstat4        croa_status;
   };
        
   struct CB_RECALLABLE_OBJ_AVAIL4res {
           nfsstat4        croa_status;
   };
        
20.7.3. DESCRIPTION
20.7.3. 描述

CB_RECALLABLE_OBJ_AVAIL is used by the server to signal the client that the server has resources to grant recallable objects that might previously have been denied by OPEN, WANT_DELEGATION, GET_DIR_DELEG, or LAYOUTGET.

CB_RECALLABLE_OBJ_AVAIL由服务器用于向客户端发出信号,表示服务器有资源授予可重新调用的对象,这些对象以前可能被OPEN、WANT_DELEGATION、GET_DIR_DELEG或LAYOUTGET拒绝。

The argument craa_objects_to_keep means the total number of recallable objects of the types indicated in the argument type_mask that the server believes it can allow the client to have, including the number of such objects the client already has. A client that tries to acquire more recallable objects than the server informs it can have runs the risk of having objects recalled.

参数craa_objects_to_keep是指服务器认为可以允许客户端拥有的参数类型_掩码中指示类型的可重新调用对象的总数,包括客户端已经拥有的此类对象的数量。如果客户端试图获取比服务器通知的更多的可重新调用对象,则可能会有被调用对象的风险。

The server is not obligated to reserve the difference between the number of the objects the client currently has and the value of craa_objects_to_keep, nor does delaying the reply to CB_RECALLABLE_OBJ_AVAIL prevent the server from using the resources of the recallable objects for another purpose. Indeed, if a client responds slowly to CB_RECALLABLE_OBJ_AVAIL, the server might interpret the client as having reduced capability to manage recallable objects, and so cancel or reduce any reservation it is maintaining on behalf of the client. Thus, if the client desires to acquire more recallable objects, it needs to reply quickly to CB_RECALLABLE_OBJ_AVAIL, and then send the appropriate operations to acquire recallable objects.

服务器没有义务保留客户端当前拥有的对象数量与craa_objects_to_keep的值之间的差额,延迟回复CB_RECALLABLE_OBJ_AVAIL也不会阻止服务器将可重新调用对象的资源用于其他目的。事实上,如果客户机对CB_RECALLABLE_OBJ_AVAIL响应缓慢,服务器可能会将客户机解释为管理可重新调用对象的能力降低,从而取消或减少它代表客户机维护的任何保留。因此,如果客户机希望获取更多可重调对象,则需要快速回复CB_recallable_OBJ_AVAIL,然后发送适当的操作以获取可重调对象。

20.8. Operation 10: CB_RECALL_SLOT - Change Flow Control Limits
20.8. 操作10:CB_调用_插槽-更改流量控制限制
20.8.1. ARGUMENT
20.8.1. 论点
   struct CB_RECALL_SLOT4args {
           slotid4       rsa_target_highest_slotid;
   };
        
   struct CB_RECALL_SLOT4args {
           slotid4       rsa_target_highest_slotid;
   };
        
20.8.2. RESULT
20.8.2. 后果
   struct CB_RECALL_SLOT4res {
           nfsstat4   rsr_status;
   };
        
   struct CB_RECALL_SLOT4res {
           nfsstat4   rsr_status;
   };
        
20.8.3. DESCRIPTION
20.8.3. 描述

The CB_RECALL_SLOT operation requests the client to return session slots, and if applicable, transport credits (e.g., RDMA credits for connections associated with the operations channel) of the session's fore channel. CB_RECALL_SLOT specifies rsa_target_highest_slotid, the value of the target highest slot ID the server wants for the session. The client MUST then progress toward reducing the session's highest slot ID to the target value.

CB_RECALL_插槽操作请求客户端返回会话插槽,以及会话前通道的传输信用(如适用,与操作通道关联的连接的RDMA信用)。CB_RECALL_SLOT指定rsa_target_highest_slotid,即服务器希望用于会话的目标最高插槽ID的值。然后,客户端必须将会话的最高插槽ID降低到目标值。

If the session has only non-RDMA connections associated with its operations channel, then the client need only wait for all outstanding requests with a slot ID > rsa_target_highest_slotid to complete, then send a single COMPOUND consisting of a single SEQUENCE operation, with the sa_highestslot field set to rsa_target_highest_slotid. If there are RDMA-based connections associated with operation channel, then the client needs to also send enough zero-length "RDMA Send" messages to take the total RDMA credit count to rsa_target_highest_slotid + 1 or below.

如果会话只有与其操作通道相关联的非RDMA连接,则客户端只需等待插槽ID>rsa_target_highest_slotid的所有未完成请求完成,然后发送由单个序列操作组成的单个复合,并将sa_highest slot字段设置为rsa_target_highest_slotid。如果存在与操作通道相关联的基于RDMA的连接,则客户端还需要发送足够的零长度“RDMA发送”消息,以将RDMA总信用计数带到rsa_target_highest_slotid+1或以下。

20.8.4. IMPLEMENTATION
20.8.4. 实施

If the client fails to reduce highest slot it has on the fore channel to what the server requests, the server can force the issue by asserting flow control on the receive side of all connections bound to the fore channel, and then finish servicing all outstanding requests that are in slots greater than rsa_target_highest_slotid. Once that is done, the server can then open the flow control, and any time the client sends a new request on a slot greater than rsa_target_highest_slotid, the server can return NFS4ERR_BADSLOT.

如果客户端无法将其在前通道上的最高插槽减少到服务器请求的位置,则服务器可以通过在绑定到前通道的所有连接的接收端断言流控制来强制解决问题,然后完成对大于rsa_target_highest_slotid的插槽中的所有未完成请求的服务。完成后,服务器可以打开流控制,并且每当客户端在大于rsa_target_highest_slotid的插槽上发送新请求时,服务器都可以返回NFS4ERR_BADSLOT。

20.9. Operation 11: CB_SEQUENCE - Supply Backchannel Sequencing and Control

20.9. 操作11:CB_序列-电源反向通道序列和控制

20.9.1. ARGUMENT
20.9.1. 论点
   struct referring_call4 {
           sequenceid4     rc_sequenceid;
           slotid4         rc_slotid;
   };
        
   struct referring_call4 {
           sequenceid4     rc_sequenceid;
           slotid4         rc_slotid;
   };
        
   struct referring_call_list4 {
           sessionid4      rcl_sessionid;
           referring_call4 rcl_referring_calls<>;
   };
        
   struct referring_call_list4 {
           sessionid4      rcl_sessionid;
           referring_call4 rcl_referring_calls<>;
   };
        
   struct CB_SEQUENCE4args {
           sessionid4           csa_sessionid;
           sequenceid4          csa_sequenceid;
           slotid4              csa_slotid;
           slotid4              csa_highest_slotid;
           bool                 csa_cachethis;
           referring_call_list4 csa_referring_call_lists<>;
   };
        
   struct CB_SEQUENCE4args {
           sessionid4           csa_sessionid;
           sequenceid4          csa_sequenceid;
           slotid4              csa_slotid;
           slotid4              csa_highest_slotid;
           bool                 csa_cachethis;
           referring_call_list4 csa_referring_call_lists<>;
   };
        
20.9.2. RESULT
20.9.2. 后果
   struct CB_SEQUENCE4resok {
           sessionid4         csr_sessionid;
           sequenceid4        csr_sequenceid;
           slotid4            csr_slotid;
           slotid4            csr_highest_slotid;
           slotid4            csr_target_highest_slotid;
   };
        
   struct CB_SEQUENCE4resok {
           sessionid4         csr_sessionid;
           sequenceid4        csr_sequenceid;
           slotid4            csr_slotid;
           slotid4            csr_highest_slotid;
           slotid4            csr_target_highest_slotid;
   };
        
   union CB_SEQUENCE4res switch (nfsstat4 csr_status) {
   case NFS4_OK:
           CB_SEQUENCE4resok   csr_resok4;
   default:
           void;
   };
        
   union CB_SEQUENCE4res switch (nfsstat4 csr_status) {
   case NFS4_OK:
           CB_SEQUENCE4resok   csr_resok4;
   default:
           void;
   };
        
20.9.3. DESCRIPTION
20.9.3. 描述

The CB_SEQUENCE operation is used to manage operational accounting for the backchannel of the session on which a request is sent. The contents include the session ID to which this request belongs, the slot ID and sequence ID used by the server to implement session request control and exactly once semantics, and exchanged slot ID maxima that are used to adjust the size of the reply cache. In each CB_COMPOUND request, CB_SEQUENCE MUST appear once and MUST be the first operation. The error NFS4ERR_SEQUENCE_POS MUST be returned when CB_SEQUENCE is found in any position in a CB_COMPOUND beyond the first. If any other operation is in the first position of CB_COMPOUND, NFS4ERR_OP_NOT_IN_SESSION MUST be returned.

CB_序列操作用于管理发送请求的会话的后通道的操作记帐。内容包括此请求所属的会话ID、服务器用于实现会话请求控制和精确一次语义的插槽ID和序列ID,以及用于调整应答缓存大小的交换插槽ID最大值。在每个CB_复合请求中,CB_序列必须出现一次,并且必须是第一个操作。当在CB_化合物中第一个位置以外的任何位置发现CB_序列时,必须返回错误NFS4ERR_SEQUENCE_POS。如果任何其他操作位于CB_component的第一个位置,则必须返回NFS4ERR_OP_NOT_in_SESSION。

See Section 18.46.3 for a description of how slots are processed.

有关插槽处理方式的说明,请参见第18.46.3节。

If csa_cachethis is TRUE, then the server is requesting that the client cache the reply in the callback reply cache. The client MUST cache the reply (see Section 2.10.6.1.3).

如果csa_cachethis为TRUE,则服务器请求客户端将应答缓存在回调应答缓存中。客户端必须缓存回复(见第2.10.6.1.3节)。

The csa_referring_call_lists array is the list of COMPOUND requests, identified by session ID, slot ID, and sequence ID. These are requests that the client previously sent to the server. These previous requests created state that some operation(s) in the same CB_COMPOUND as the csa_referring_call_lists are identifying. A session ID is included because leased state is tied to a client ID, and a client ID can have multiple sessions. See Section 2.10.6.3.

csa_referenting_call_lists数组是由会话ID、插槽ID和序列ID标识的复合请求列表。这些是客户端以前发送给服务器的请求。这些先前创建的请求表明,与csa\u引用调用列表相同的CB\u化合物中的某些操作正在识别。之所以包含会话ID,是因为租用状态与客户端ID绑定,并且客户端ID可以有多个会话。见第2.10.6.3节。

The value of the csa_sequenceid argument relative to the cached sequence ID on the slot falls into one of three cases.

csa_sequenceid参数相对于插槽上缓存的序列ID的值属于以下三种情况之一。

o If the difference between csa_sequenceid and the client's cached sequence ID at the slot ID is two (2) or more, or if csa_sequenceid is less than the cached sequence ID (accounting for wraparound of the unsigned sequence ID value), then the client MUST return NFS4ERR_SEQ_MISORDERED.

o 如果csa_sequenceid与插槽ID处客户端缓存序列ID之间的差值为两(2)或更大,或者如果csa_sequenceid小于缓存序列ID(考虑未签名序列ID值的环绕),则客户端必须返回NFS4ERR_SEQ_MISORDERED。

o If csa_sequenceid and the cached sequence ID are the same, this is a retry, and the client returns the CB_COMPOUND request's cached reply.

o 如果csa_sequenceid和缓存的序列ID相同,则这是一次重试,客户端返回CB_复合请求的缓存回复。

o If csa_sequenceid is one greater (accounting for wraparound) than the cached sequence ID, then this is a new request, and the slot's sequence ID is incremented. The operations subsequent to CB_SEQUENCE, if any, are processed. If there are no other operations, the only other effects are to cache the CB_SEQUENCE reply in the slot, maintain the session's activity, and when the server receives the CB_SEQUENCE reply, renew the lease of state related to the client ID.

o 如果csa_sequenceid比缓存的序列ID大一个(考虑环绕),则这是一个新请求,插槽的序列ID将递增。处理CB_序列之后的操作(如果有)。如果没有其他操作,则唯一的其他效果是将CB_序列应答缓存在插槽中,维护会话的活动,并且当服务器接收到CB_序列应答时,续订与客户端ID相关的状态租约。

If the server reuses a slot ID and sequence ID for a completely different request, the client MAY treat the request as if it is a retry of what it has already executed. The client MAY however detect the server's illegal reuse and return NFS4ERR_SEQ_FALSE_RETRY.

如果服务器对完全不同的请求重用插槽ID和序列ID,则客户端可能会将该请求视为对其已执行内容的重试。然而,客户端可能会检测到服务器的非法重用并返回NFS4ERR_SEQ_FALSE_RETRY。

If CB_SEQUENCE returns an error, then the state of the slot (sequence ID, cached reply) MUST NOT change. See Section 2.10.6.1.3 for the conditions when the error NFS4ERR_RETRY_UNCACHED_REP might be returned.

如果CB_序列返回错误,则插槽的状态(序列ID、缓存的回复)不得更改。有关可能返回错误NFS4ERR_RETRY_UNCACHED_REP的条件,请参阅第2.10.6.1.3节。

The client returns two "highest_slotid" values: csr_highest_slotid and csr_target_highest_slotid. The former is the highest slot ID the client will accept in a future CB_SEQUENCE operation, and SHOULD NOT be less than the value of csa_highest_slotid (but see

客户端返回两个“最高\u slotid”值:csr\u highest\u slotid和csr\u target\u highest\u slotid。前者是客户端在将来的CB_序列操作中将接受的最高插槽ID,并且不应小于csa_highest_slotid的值(但请参见

Section 2.10.6.1 for an exception). The latter is the highest slot ID the client would prefer the server use on a future CB_SEQUENCE operation.

第2.10.6.1节(例外情况)。后者是客户端希望服务器在将来的CB_序列操作中使用的最高插槽ID。

20.10. Operation 12: CB_WANTS_CANCELLED - Cancel Pending Delegation Wants

20.10. 操作12:CB_想要取消-取消挂起的委派想要

20.10.1. ARGUMENT
20.10.1. 论点
   struct CB_WANTS_CANCELLED4args {
           bool cwca_contended_wants_cancelled;
           bool cwca_resourced_wants_cancelled;
   };
        
   struct CB_WANTS_CANCELLED4args {
           bool cwca_contended_wants_cancelled;
           bool cwca_resourced_wants_cancelled;
   };
        
20.10.2. RESULT
20.10.2. 后果
   struct CB_WANTS_CANCELLED4res {
           nfsstat4        cwcr_status;
   };
        
   struct CB_WANTS_CANCELLED4res {
           nfsstat4        cwcr_status;
   };
        
20.10.3. DESCRIPTION
20.10.3. 描述

The CB_WANTS_CANCELLED operation is used to notify the client that some or all of the wants it registered for recallable delegations and layouts have been cancelled.

CB_WANTS_CANCELLED操作用于通知客户端,它为可撤销的委托和布局注册的部分或全部WANTS已被取消。

If cwca_contended_wants_cancelled is TRUE, this indicates that the server will not be pushing to the client any delegations that become available after contention passes.

如果cwca_Conferred_wants_cancelled为TRUE,则表示服务器不会将争用通过后可用的任何委托推送到客户端。

If cwca_resourced_wants_cancelled is TRUE, this indicates that the server will not notify the client when there are resources on the server to grant delegations or layouts.

如果cwca_resourced_wants_cancelled为TRUE,则表示当服务器上有资源授予委派或布局时,服务器不会通知客户端。

After receiving a CB_WANTS_CANCELLED operation, the client is free to attempt to acquire the delegations or layouts it was waiting for, and possibly re-register wants.

在收到CB_WANTS_CANCELLED操作后,客户端可以自由尝试获取其等待的委托或布局,并可能重新注册WANTS。

20.10.4. IMPLEMENTATION
20.10.4. 实施

When a client has an OPEN, WANT_DELEGATION, or GET_DIR_DELEGATION request outstanding, when a CB_WANTS_CANCELLED is sent, the server may need to make clear to the client whether a promise to signal delegation availability happened before the CB_WANTS_CANCELLED and is thus covered by it, or after the CB_WANTS_CANCELLED in which case it was not covered by it. The server can make this distinction by putting the appropriate requests into the list of referring calls in the associated CB_SEQUENCE.

当客户端有未完成的OPEN、WANT_委派或GET_DIR_委派请求时,当发送CB_WANT_CANCELLED时,服务器可能需要向客户端说明,在CB_想要取消委派之前是否发生了发出委派可用性信号的承诺,并因此包含在其中,或者在CB_想要取消之后,在这种情况下,CB_不包括在内。服务器可以通过将适当的请求放入相关CB_序列中的引用调用列表中来进行区分。

20.11. Operation 13: CB_NOTIFY_LOCK - Notify Client of Possible Lock Availability

20.11. 操作13:CB_NOTIFY_LOCK-通知客户端可能的锁可用性

20.11.1. ARGUMENT
20.11.1. 论点
   struct CB_NOTIFY_LOCK4args {
       nfs_fh4     cnla_fh;
       lock_owner4 cnla_lock_owner;
   };
        
   struct CB_NOTIFY_LOCK4args {
       nfs_fh4     cnla_fh;
       lock_owner4 cnla_lock_owner;
   };
        
20.11.2. RESULT
20.11.2. 后果
   struct CB_NOTIFY_LOCK4res {
           nfsstat4        cnlr_status;
   };
        
   struct CB_NOTIFY_LOCK4res {
           nfsstat4        cnlr_status;
   };
        
20.11.3. DESCRIPTION
20.11.3. 描述

The server can use this operation to indicate that a byte-range lock for the given file and lock-owner, previously requested by the client via an unsuccessful LOCK operation, might be available.

服务器可以使用此操作指示给定文件和锁所有者的字节范围锁可能可用,该锁先前由客户端通过不成功的锁操作请求。

This callback is meant to be used by servers to help reduce the latency of blocking locks in the case where they recognize that a client that has been polling for a blocking byte-range lock may now be able to acquire the lock. If the server supports this callback for a given file, it MUST set the OPEN4_RESULT_MAY_NOTIFY_LOCK flag when responding to successful opens for that file. This does not commit the server to the use of CB_NOTIFY_LOCK, but the client may use this as a hint to decide how frequently to poll for locks derived from that open.

当服务器意识到一直轮询阻塞字节范围锁的客户端现在可能能够获取锁时,此回调用于帮助减少阻塞锁的延迟。如果服务器支持对给定文件的回调,则必须在响应该文件的成功打开时设置OPEN4_RESULT_MAY_NOTIFY_LOCK标志。这不会让服务器使用CB_NOTIFY_LOCK,但是客户端可以使用它作为一个提示来决定轮询从该打开项派生的锁的频率。

If an OPEN operation results in an upgrade, in which the stateid returned has an "other" value matching that of a stateid already allocated, with a new "seqid" indicating a change in the lock being represented, then the value of the OPEN4_RESULT_MAY_NOTIFY_LOCK flag when responding to that new OPEN controls handling from that point going forward. When parallel OPENs are done on the same file and open-owner, the ordering of the "seqid" fields of the returned stateids (subject to wraparound) are to be used to select the controlling value of the OPEN4_RESULT_MAY_NOTIFY_LOCK flag.

如果打开操作导致升级,其中返回的stateid具有与已分配的stateid匹配的“其他”值,且新的“seqid”指示所表示锁的更改,则OPEN4_RESULT_的值可能会在从该点开始响应新的打开控件处理时通知_lock标志。当在同一个文件和打开所有者上进行并行打开时,返回的StateID的“seqid”字段的顺序(以环绕为准)将用于选择OPEN4\u RESULT\u MAY\u NOTIFY\u LOCK标志的控制值。

20.11.4. IMPLEMENTATION
20.11.4. 实施

The server MUST NOT grant the byte-range lock to the client unless and until it receives a LOCK operation from the client. Similarly, the client receiving this callback cannot assume that it now has the lock or that a subsequent LOCK operation for the lock will be successful.

服务器不得向客户端授予字节范围锁,除非并直到从客户端接收到锁操作。类似地,接收此回调的客户机不能假定它现在拥有锁,或者该锁的后续锁定操作将成功。

The server is not required to implement this callback, and even if it does, it is not required to use it in any particular case. Therefore, the client must still rely on polling for blocking locks, as described in Section 9.6.

服务器不需要实现此回调,即使它实现了,也不需要在任何特定情况下使用它。因此,客户端仍然必须依赖轮询来阻止锁,如第9.6节所述。

Similarly, the client is not required to implement this callback, and even it does, is still free to ignore it. Therefore, the server MUST NOT assume that the client will act based on the callback.

类似地,客户机不需要实现这个回调,即使它实现了,也可以随意忽略它。因此,服务器不能假定客户端将根据回调进行操作。

20.12. Operation 14: CB_NOTIFY_DEVICEID - Notify Client of Device ID Changes

20.12. 操作14:CB_NOTIFY_DEVICEID-通知客户端设备ID的更改

20.12.1. ARGUMENT
20.12.1. 论点
   /*
    * Device notification types.
    */
   enum notify_deviceid_type4 {
           NOTIFY_DEVICEID4_CHANGE = 1,
           NOTIFY_DEVICEID4_DELETE = 2
   };
        
   /*
    * Device notification types.
    */
   enum notify_deviceid_type4 {
           NOTIFY_DEVICEID4_CHANGE = 1,
           NOTIFY_DEVICEID4_DELETE = 2
   };
        
   /* For NOTIFY4_DEVICEID4_DELETE */
   struct notify_deviceid_delete4 {
           layouttype4     ndd_layouttype;
           deviceid4       ndd_deviceid;
   };
        
   /* For NOTIFY4_DEVICEID4_DELETE */
   struct notify_deviceid_delete4 {
           layouttype4     ndd_layouttype;
           deviceid4       ndd_deviceid;
   };
        
   /* For NOTIFY4_DEVICEID4_CHANGE */
   struct notify_deviceid_change4 {
           layouttype4     ndc_layouttype;
           deviceid4       ndc_deviceid;
           bool            ndc_immediate;
   };
        
   /* For NOTIFY4_DEVICEID4_CHANGE */
   struct notify_deviceid_change4 {
           layouttype4     ndc_layouttype;
           deviceid4       ndc_deviceid;
           bool            ndc_immediate;
   };
        
   struct CB_NOTIFY_DEVICEID4args {
           notify4 cnda_changes<>;
   };
        
   struct CB_NOTIFY_DEVICEID4args {
           notify4 cnda_changes<>;
   };
        
20.12.2. RESULT
20.12.2. 后果
   struct CB_NOTIFY_DEVICEID4res {
           nfsstat4        cndr_status;
   };
        
   struct CB_NOTIFY_DEVICEID4res {
           nfsstat4        cndr_status;
   };
        
20.12.3. DESCRIPTION
20.12.3. 描述

The CB_NOTIFY_DEVICEID operation is used by the server to send notifications to clients about changes to pNFS device IDs. The registration of device ID notifications is optional and is done via GETDEVICEINFO. These notifications are sent over the backchannel once the original request has been processed on the server. The server will send an array of notifications, cnda_changes, as a list of pairs of bitmaps and values. See Section 3.3.7 for a description of how NFSv4.1 bitmaps work.

服务器使用CB_NOTIFY_DEVICEID操作向客户端发送有关pNFS设备ID更改的通知。设备ID通知的注册是可选的,通过GETDEVICEINFO完成。在服务器上处理原始请求后,这些通知将通过反向通道发送。服务器将发送一组通知,即cnda_更改,作为位图和值对的列表。有关NFSv4.1位图工作原理的说明,请参见第3.3.7节。

As with CB_NOTIFY (Section 20.4.3), it is possible the server has more notifications than can fit in a CB_COMPOUND, thus requiring multiple CB_COMPOUNDs. Unlike CB_NOTIFY, serialization is not an issue because unlike directory entries, device IDs cannot be re-used after being deleted (Section 12.2.10).

与CB_NOTIFY(第20.4.3节)一样,服务器的通知数量可能超过CB_化合物的数量,因此需要多个CB_化合物。与CB_NOTIFY不同,序列化不是问题,因为与目录条目不同,设备ID在删除后不能重新使用(第12.2.10节)。

All device ID notifications contain a device ID and a layout type. The layout type is necessary because two different layout types can share the same device ID, and the common device ID can have completely different mappings for each layout type.

所有设备ID通知都包含设备ID和布局类型。布局类型是必需的,因为两种不同的布局类型可以共享相同的设备ID,并且公共设备ID可以对每个布局类型具有完全不同的映射。

The server will send the following notifications:

服务器将发送以下通知:

NOTIFY_DEVICEID4_CHANGE A previously provided device-ID-to-device-address mapping has changed and the client uses GETDEVICEINFO to obtain the updated mapping. The notification is encoded in a value of data type notify_deviceid_change4. This data type also contains a boolean field, ndc_immediate, which if TRUE indicates that the change will be enforced immediately, and so the client might not be able to complete any pending I/O to the device ID. If ndc_immediate is FALSE, then for an indefinite time, the client can complete pending I/O. After pending I/O is complete, the client SHOULD get the new device-ID-to-device-address mappings before sending new I/O requests to the storage devices addressed by the device ID.

NOTIFY_DEVICEID4_CHANGE先前提供的设备ID到设备地址的映射已更改,客户端使用GETDEVICEINFO获取更新的映射。通知以数据类型notify_deviceid_change4的值进行编码。此数据类型还包含一个布尔字段ndc_immediate,如果为TRUE,则表示将立即执行更改,因此客户端可能无法完成对设备ID的任何挂起I/O。如果ndc_immediate为FALSE,则客户端可以无限期地完成挂起I/O。挂起I/O完成后,在向设备ID所寻址的存储设备发送新的I/O请求之前,客户端应先获取新的设备ID到设备地址的映射。

NOTIFY4_DEVICEID_DELETE Deletes a device ID from the mappings. This notification MUST NOT be sent if the client has a layout that refers to the device ID. In other words, if the server is sending a delete device ID notification, one of the following is true for layouts associated with the layout type:

NOTIFY4\u DEVICEID\u DELETE从映射中删除设备ID。如果客户端具有引用设备ID的布局,则不得发送此通知。换句话说,如果服务器正在发送删除设备ID通知,则对于与布局类型关联的布局,以下情况之一为真:

* The client never had a layout referring to that device ID.

* 客户端从来没有引用该设备ID的布局。

* The client has returned all layouts referring to that device ID.

* 客户端已返回引用该设备ID的所有布局。

* The server has revoked all layouts referring to that device ID.

* 服务器已撤消引用该设备ID的所有布局。

The notification is encoded in a value of data type notify_deviceid_delete4. After a server deletes a device ID, it MUST NOT reuse that device ID for the same layout type until the client ID is deleted.

通知以数据类型notify_deviceid_delete4的值进行编码。服务器删除设备ID后,在删除客户端ID之前,不得将该设备ID重新用于相同的布局类型。

20.13. Operation 10044: CB_ILLEGAL - Illegal Callback Operation
20.13. 操作10044:CB_非法-非法回调操作
20.13.1. ARGUMENT
20.13.1. 论点

void;

无效的

20.13.2. RESULT
20.13.2. 后果
   /*
    * CB_ILLEGAL: Response for illegal operation numbers
    */
   struct CB_ILLEGAL4res {
           nfsstat4        status;
   };
        
   /*
    * CB_ILLEGAL: Response for illegal operation numbers
    */
   struct CB_ILLEGAL4res {
           nfsstat4        status;
   };
        
20.13.3. DESCRIPTION
20.13.3. 描述

This operation is a placeholder for encoding a result to handle the case of the server sending an operation code within CB_COMPOUND that is not defined in the NFSv4.1 specification. See Section 19.2.3 for more details.

此操作是一个占位符,用于编码结果,以处理服务器在NFSv4.1规范中未定义的CB_复合内发送操作代码的情况。详见第19.2.3节。

The status field of CB_ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.

CB_ILLEGAL4res的状态字段必须设置为NFS4ERR_OP_ILLEGAL。

20.13.4. IMPLEMENTATION
20.13.4. 实施

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 an instance of data type CB_ILLEGAL4res will not be returned.

获取非OP_非法的非法操作代码,如果客户端在XDR解码阶段检查合法操作代码,则不会返回数据类型CB_ILLEGAL4res的实例。

21. Security Considerations
21. 安全考虑

Historically, the authentication model of NFS was based on the entire machine being the NFS client, with the NFS server trusting the NFS client to authenticate the end-user. The NFS server in turn shared its files only to specific clients, as identified by the client's source network 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 network address and port number to which the request was sent. While such a model is easy to implement and simple to deploy and use, it is unsafe. Thus, NFSv4.1 implementations are REQUIRED to 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 is also given to the integrity and privacy of NFS requests and responses. The issues of end-to-end mutual authentication, integrity, and privacy are discussed in Section 2.2.1.1.1. There are specific considerations when using Kerberos V5 as described in Section 2.2.1.1.1.2.1.1.

从历史上看,NFS的身份验证模型是基于整个机器都是NFS客户端,NFS服务器信任NFS客户端对最终用户进行身份验证。NFS服务器反过来只将其文件共享给特定的客户端,由客户端的源网络地址标识。考虑到这个模型,AUTH_SYS RPC安全特性只识别使用NFS服务器客户端的最终用户。在处理NFS响应时,客户端确保响应来自请求发送到的相同网络地址和端口号。虽然这样的模型易于实现、部署和使用简单,但它是不安全的。因此,需要NFSv4.1实现来支持使用端到端身份验证的安全模型,其中客户端上的最终用户向NFS服务器上的主体进行相互身份验证(通过不公开网络上清除的密码或密钥的加密方案)。还考虑了NFS请求和响应的完整性和隐私性。第2.2.1.1.1节讨论了端到端相互认证、完整性和隐私问题。如第2.2.1.1.1.1.2.1.1节所述,在使用Kerberos V5时有一些特定的注意事项。

Note that being REQUIRED to implement does not mean REQUIRED to use; AUTH_SYS can be used by NFSv4.1 clients and servers. However, AUTH_SYS is merely an OPTIONAL security flavor in NFSv4.1, and so interoperability via AUTH_SYS is not assured.

注意,需要实施并不意味着需要使用;NFSv4.1客户端和服务器可以使用AUTH_SYS。然而,AUTH_SYS在NFSv4.1中只是一个可选的安全特性,因此无法保证通过AUTH_SYS的互操作性。

For reasons of reduced administration overhead, better performance, and/or reduction of CPU utilization, users of NFSv4.1 implementations might decline to use security mechanisms that enable integrity protection on each remote procedure call and response. The use of mechanisms without integrity leaves the user vulnerable to a man-in-the-middle of 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 three operations in particular that warrant the implementation overriding user choices.

出于减少管理开销、提高性能和/或降低CPU利用率的原因,NFSv4.1实现的用户可能会拒绝使用在每个远程过程调用和响应上启用完整性保护的安全机制。使用没有完整性的机制会使用户容易受到NFS客户端和服务器中间修改RPC请求和/或响应的人的攻击。虽然实现可以自由提供使用较弱安全机制的选项,但有三种操作特别保证实现覆盖用户选择。

o The first two such operations are SECINFO and SECINFO_NO_NAME. It is RECOMMENDED that the client send both operations such that they are protected with a security flavor that has integrity protection, such as RPCSEC_GSS with either the rpc_gss_svc_integrity or rpc_gss_svc_privacy service. Without integrity protection encapsulating SECINFO and SECINFO_NO_NAME and

o 前两个这样的操作是SECINFO和SECINFO\u NO\u NAME。建议客户端发送这两个操作,以便它们受到具有完整性保护的安全性保护,例如带有rpc_GSS_svc_完整性或rpc_GSS_svc_隐私服务的RPCSEC_GSS。没有完整性保护封装SECINFO和SECINFO\u NO\u名称和

their results, a man-in-the-middle could modify results such that the client might select a weaker algorithm in the set allowed by the server, making the client and/or server vulnerable to further attacks.

在他们的结果中,中间人可以修改结果,以便客户端可以在服务器允许的集合中选择较弱的算法,从而使客户端和/或服务器容易受到进一步的攻击。

o The third operation that SHOULD use integrity protection is any GETATTR for the fs_locations and fs_locations_info attributes, in order to mitigate the severity of a man-in-the-middle attack. 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 or fs_locations_info attributes, the attacker modifies the results to cause the client to migrate its traffic to a server controlled by the attacker. With integrity protection, this attack is mitigated.

o 第三个应该使用完整性保护的操作是fs_位置和fs_位置信息属性的任何GETATTR,以减轻中间人攻击的严重性。攻击分为两个步骤。首先,攻击者修改某些操作的未受保护结果以返回NFS4ERR_MOVED。第二,当客户端使用fs_locations或fs_locations_info属性的GETATTR进行后续操作时,攻击者会修改结果,使客户端将其流量迁移到由攻击者控制的服务器。通过完整性保护,可以减轻此攻击。

Relative to previous NFS versions, NFSv4.1 has additional security considerations for pNFS (see Sections 12.9 and 13.12), locking and session state (see Section 2.10.8.3), and state recovery during grace period (see Section 8.4.2.1.1). With respect to locking and session state, if SP4_SSV state protection is being used, Section 2.10.10 has specific security considerations for the NFSv4.1 client and server.

相对于以前的NFS版本,NFSv4.1对PNF(请参见第12.9节和第13.12节)、锁定和会话状态(请参见第2.10.8.3节)以及宽限期内的状态恢复(请参见第8.4.2.1.1节)有额外的安全注意事项。关于锁定和会话状态,如果使用SP4_SSV状态保护,则第2.10.10节对NFSv4.1客户端和服务器有特定的安全注意事项。

22. IANA Considerations
22. IANA考虑

This section uses terms that are defined in [55].

本节使用了[55]中定义的术语。

22.1. Named Attribute Definitions
22.1. 命名属性定义

IANA created a registry called the "NFSv4 Named Attribute Definitions Registry".

IANA创建了一个名为“NFSv4命名属性定义注册表”的注册表。

The NFSv4.1 protocol supports the association of a file with zero or more named attributes. The namespace identifiers for these attributes are defined as string names. The protocol does not define the specific assignment of the namespace for these file attributes. The IANA registry promotes 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.

NFSv4.1协议支持文件与零个或多个命名属性的关联。这些属性的命名空间标识符定义为字符串名称。协议没有为这些文件属性定义命名空间的特定分配。IANA注册中心在存在共同利益的地方促进互操作性。虽然允许应用程序开发人员根据需要定义和使用属性,但鼓励他们向IANA注册属性。

Such registered named attributes are presumed to apply to all minor versions of NFSv4, including those defined subsequently to the registration. If the named attribute is intended to be limited to specific minor versions, this will be clearly stated in the registry's assignment.

此类注册的命名属性假定适用于NFSv4的所有次要版本,包括注册后定义的版本。如果指定的属性仅限于特定的次要版本,这将在注册表的分配中明确说明。

All assignments to the registry are made on a First Come First Served basis, per Section 4.1 of [55]. The policy for each assignment is Specification Required, per Section 4.1 of [55].

根据[55]第4.1节的规定,注册处的所有转让均以先到先得的方式进行。根据[55]第4.1节的规定,每个任务的政策都是必需的。

Under the NFSv4.1 specification, the name of a named attribute can in theory be up to 2^32 - 1 bytes in length, but in practice NFSv4.1 clients and servers will be unable to handle a string that long. IANA should reject any assignment request with a named attribute that exceeds 128 UTF-8 characters. To give the IESG the flexibility to set up bases of assignment of Experimental Use and Standards Action, the prefixes of "EXPE" and "STDS" are Reserved. The named attribute with a zero-length name is Reserved.

在NFSv4.1规范下,命名属性的名称在理论上可以达到2^32-1字节的长度,但在实践中,NFSv4.1客户端和服务器将无法处理这么长的字符串。IANA应拒绝任何命名属性超过128个UTF-8字符的分配请求。为了使IESG能够灵活地建立实验使用和标准行动的分配基础,保留了“EXPE”和“std”的前缀。名称长度为零的命名属性是保留的。

The prefix "PRIV" is designated for Private Use. A site that wants to make use of unregistered named attributes without risk of conflicting with an assignment in IANA's registry should use the prefix "PRIV" in all of its named attributes.

前缀“PRIV”指定为私人使用。如果站点希望使用未注册的命名属性,而不存在与IANA注册中心的分配冲突的风险,则应在其所有命名属性中使用前缀“PRIV”。

Because some NFSv4.1 clients and servers have case-insensitive semantics, the fifteen additional lower case and mixed case permutations of each of "EXPE", "PRIV", and "STDS" are Reserved (e.g., "expe", "expE", "exPe", etc. are Reserved). Similarly, IANA must not allow two assignments that would conflict if both named attributes were converted to a common case.

由于某些NFSv4.1客户端和服务器具有不区分大小写的语义,因此保留了“EXPE”、“PRIV”和“std”各自的15个额外小写和混合大小写排列(例如,“EXPE”、“EXPE”、“EXPE”等)。类似地,如果两个命名属性都转换为公共案例,IANA不得允许两个分配发生冲突。

The registry of named attributes is a list of assignments, each containing three fields for each assignment.

命名属性的注册表是一个分配列表,每个分配包含三个字段。

1. A US-ASCII string name that is the actual name of the attribute. This name must be unique. This string name can be 1 to 128 UTF-8 characters long.

1. 作为属性实际名称的US-ASCII字符串名称。此名称必须是唯一的。此字符串名称的长度可以是1到128个UTF-8字符。

2. A reference to the specification of the named attribute. The reference can consume up to 256 bytes (or more if IANA permits).

2. 对命名属性规范的引用。该引用最多可以消耗256字节(如果IANA允许,则可以消耗更多字节)。

3. The point of contact of the registrant. The point of contact can consume up to 256 bytes (or more if IANA permits).

3. 注册人的联系人。接触点最多可以消耗256个字节(如果IANA允许,可以消耗更多字节)。

22.1.1. Initial Registry
22.1.1. 初始注册表

There is no initial registry.

没有初始注册表。

22.1.2. Updating Registrations
22.1.2. 更新注册

The registrant is always permitted to update the point of contact field. Any other change will require Expert Review or IESG Approval.

注册人始终被允许更新联系人字段。任何其他变更都需要专家审查或IESG批准。

22.2. Device ID Notifications
22.2. 设备ID通知

IANA created a registry called the "NFSv4 Device ID Notifications Registry".

IANA创建了一个名为“NFSv4设备ID通知注册表”的注册表。

The potential exists for new notification types to be added to the CB_NOTIFY_DEVICEID operation (see Section 20.12). This can be done via changes to the operations that register notifications, or by adding new operations to NFSv4. This requires a new minor version of NFSv4, and requires a Standards Track document from the IETF. Another way to add a notification is to specify a new layout type (see Section 22.4).

存在向CB_NOTIFY_DEVICEID操作添加新通知类型的可能性(见第20.12节)。这可以通过更改注册通知的操作或向NFSv4添加新操作来实现。这需要NFSv4的新次要版本,并需要IETF的标准跟踪文档。添加通知的另一种方法是指定新的布局类型(参见第22.4节)。

Hence, all assignments to the registry are made on a Standards Action basis per Section 4.1 of [55], with Expert Review required.

因此,根据[55]第4.1节的规定,在标准行动的基础上对登记处进行所有分配,并要求进行专家审查。

The registry is a list of assignments, each containing five fields per assignment.

注册表是一个作业列表,每个作业包含五个字段。

1. The name of the notification type. This name must have the prefix "NOTIFY_DEVICEID4_". This name must be unique.

1. 通知类型的名称。此名称的前缀必须为“NOTIFY_DEVICEID4”。此名称必须是唯一的。

2. The value of the notification. IANA will assign this number, and the request from the registrant will use TBD1 instead of an actual value. IANA MUST use a whole number that can be no higher than 2^32-1, and should be the next available value. The value assigned must be unique. A Designated Expert must be used to ensure that when the name of the notification type and its value are added to the NFSv4.1 notify_deviceid_type4 enumerated data type in the NFSv4.1 XDR description ([13]), the result continues to be a valid XDR description.

2. 通知的值。IANA将分配此编号,注册人的请求将使用TBD1而不是实际值。IANA必须使用不大于2^32-1的整数,并且应该是下一个可用值。指定的值必须是唯一的。必须使用指定专家确保当通知类型的名称及其值添加到NFSv4.1 XDR描述([13])中的NFSv4.1 notify_deviceid_type4枚举数据类型时,结果仍然是有效的XDR描述。

3. The Standards Track RFC(s) that describe the notification. If the RFC(s) have not yet been published, the registrant will use RFCTBD2, RFCTBD3, etc. instead of an actual RFC number.

3. 这些标准跟踪描述通知的RFC。如果RFC尚未发布,注册人将使用RFCTBD2、RFCTBD3等,而不是实际的RFC编号。

4. How the RFC introduces the notification. This is indicated by a single US-ASCII value. If the value is N, it means a minor revision to the NFSv4 protocol. If the value is L, it means a new pNFS layout type. Other values can be used with IESG Approval.

4. RFC如何引入通知。这由一个US-ASCII值表示。如果该值为N,则表示对NFSv4协议进行了轻微修订。如果该值为L,则表示新的pNFS布局类型。其他值可经IESG批准使用。

5. The minor versions of NFSv4 that are allowed to use the notification. While these are numeric values, IANA will not allocate and assign them; the author of the relevant RFCs with IESG Approval assigns these numbers. Each time there is a new minor version of NFSv4 approved, a Designated Expert should review the registry to make recommended updates as needed.

5. 允许使用通知的NFSv4的次要版本。虽然这些是数值,但IANA不会分配它们;获得IESG批准的相关RFC的作者分配这些编号。每次有新的NFSv4次要版本获得批准时,指定专家应审查注册表,根据需要进行建议更新。

22.2.1. Initial Registry
22.2.1. 初始注册表

The initial registry is in Table 16. Note that the next available value is zero.

初始注册表如表16所示。请注意,下一个可用值为零。

   +-------------------------+-------+---------+-----+----------------+
   | Notification Name       | Value | RFC     | How | Minor Versions |
   +-------------------------+-------+---------+-----+----------------+
   | NOTIFY_DEVICEID4_CHANGE | 1     | RFC5661 | N   | 1              |
   | NOTIFY_DEVICEID4_DELETE | 2     | RFC5661 | N   | 1              |
   +-------------------------+-------+---------+-----+----------------+
        
   +-------------------------+-------+---------+-----+----------------+
   | Notification Name       | Value | RFC     | How | Minor Versions |
   +-------------------------+-------+---------+-----+----------------+
   | NOTIFY_DEVICEID4_CHANGE | 1     | RFC5661 | N   | 1              |
   | NOTIFY_DEVICEID4_DELETE | 2     | RFC5661 | N   | 1              |
   +-------------------------+-------+---------+-----+----------------+
        

Table 16: Initial Device ID Notification Assignments

表16:初始设备ID通知分配

22.2.2. Updating Registrations
22.2.2. 更新注册

The update of a registration will require IESG Approval on the advice of a Designated Expert.

注册的更新需要IESG根据指定专家的建议进行批准。

22.3. Object Recall Types
22.3. 对象调用类型

IANA created a registry called the "NFSv4 Recallable Object Types Registry".

IANA创建了一个名为“NFSv4可重调对象类型注册表”的注册表。

The potential exists for new object types to be added to the CB_RECALL_ANY operation (see Section 20.6). This can be done via changes to the operations that add recallable types, or by adding new operations to NFSv4. This requires a new minor version of NFSv4, and requires a Standards Track document from IETF. Another way to add a new recallable object is to specify a new layout type (see Section 22.4).

任何操作(见第20.6节)都有可能向CB_RECALL_添加新的对象类型。这可以通过更改添加可重调用类型的操作或向NFSv4添加新操作来实现。这需要NFSv4的新的次要版本,并需要IETF的标准跟踪文档。添加新的可重调对象的另一种方法是指定新的布局类型(参见第22.4节)。

All assignments to the registry are made on a Standards Action basis per Section 4.1 of [55], with Expert Review required.

根据[55]第4.1节的规定,在标准行动的基础上对登记处进行所有分配,并要求进行专家审查。

Recallable object types are 32-bit unsigned numbers. There are no Reserved values. Values in the range 12 through 15, inclusive, are designated for Private Use.

可重调对象类型是32位无符号数。没有保留值。12至15(含12至15)范围内的值指定为私人使用。

The registry is a list of assignments, each containing five fields per assignment.

注册表是一个作业列表,每个作业包含五个字段。

1. The name of the recallable object type. This name must have the prefix "RCA4_TYPE_MASK_". The name must be unique.

1. 可重调对象类型的名称。此名称必须具有前缀“RCA4\u类型\u掩码”。名称必须是唯一的。

2. The value of the recallable object type. IANA will assign this number, and the request from the registrant will use TBD1 instead of an actual value. IANA MUST use a whole number that can be no

2. 可重调对象类型的值。IANA将分配此编号,注册人的请求将使用TBD1而不是实际值。IANA必须使用一个整数,不能是no

higher than 2^32-1, and should be the next available value. The value must be unique. A Designated Expert must be used to ensure that when the name of the recallable type and its value are added to the NFSv4 XDR description [13], the result continues to be a valid XDR description.

大于2^32-1,并且应该是下一个可用值。该值必须是唯一的。必须使用指定的专家来确保将可重调类型的名称及其值添加到NFSv4 XDR描述[13]中时,结果仍然是有效的XDR描述。

3. The Standards Track RFC(s) that describe the recallable object type. If the RFC(s) have not yet been published, the registrant will use RFCTBD2, RFCTBD3, etc. instead of an actual RFC number.

3. 这些标准跟踪描述可重调对象类型的RFC。如果RFC尚未发布,注册人将使用RFCTBD2、RFCTBD3等,而不是实际的RFC编号。

4. How the RFC introduces the recallable object type. This is indicated by a single US-ASCII value. If the value is N, it means a minor revision to the NFSv4 protocol. If the value is L, it means a new pNFS layout type. Other values can be used with IESG Approval.

4. RFC如何引入可重调对象类型。这由一个US-ASCII值表示。如果该值为N,则表示对NFSv4协议进行了轻微修订。如果该值为L,则表示新的pNFS布局类型。其他值可经IESG批准使用。

5. The minor versions of NFSv4 that are allowed to use the recallable object type. While these are numeric values, IANA will not allocate and assign them; the author of the relevant RFCs with IESG Approval assigns these numbers. Each time there is a new minor version of NFSv4 approved, a Designated Expert should review the registry to make recommended updates as needed.

5. 允许使用可重调对象类型的NFSv4的次要版本。虽然这些是数值,但IANA不会分配它们;获得IESG批准的相关RFC的作者分配这些编号。每次有新的NFSv4次要版本获得批准时,指定专家应审查注册表,根据需要进行建议更新。

22.3.1. Initial Registry
22.3.1. 初始注册表

The initial registry is in Table 17. Note that the next available value is five.

初始登记册见表17。请注意,下一个可用值是5。

   +-------------------------------+-------+--------+-----+------------+
   | Recallable Object Type Name   | Value | RFC    | How | Minor      |
   |                               |       |        |     | Versions   |
   +-------------------------------+-------+--------+-----+------------+
   | RCA4_TYPE_MASK_RDATA_DLG      | 0     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_WDATA_DLG      | 1     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_DIR_DLG        | 2     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_FILE_LAYOUT    | 3     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_BLK_LAYOUT     | 4     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_OBJ_LAYOUT_MIN | 8     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_OBJ_LAYOUT_MAX | 9     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   +-------------------------------+-------+--------+-----+------------+
        
   +-------------------------------+-------+--------+-----+------------+
   | Recallable Object Type Name   | Value | RFC    | How | Minor      |
   |                               |       |        |     | Versions   |
   +-------------------------------+-------+--------+-----+------------+
   | RCA4_TYPE_MASK_RDATA_DLG      | 0     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_WDATA_DLG      | 1     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_DIR_DLG        | 2     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_FILE_LAYOUT    | 3     | RFC    | N   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_BLK_LAYOUT     | 4     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_OBJ_LAYOUT_MIN | 8     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   | RCA4_TYPE_MASK_OBJ_LAYOUT_MAX | 9     | RFC    | L   | 1          |
   |                               |       | 5661   |     |            |
   +-------------------------------+-------+--------+-----+------------+
        

Table 17: Initial Recallable Object Type Assignments

表17:初始可重调对象类型指定

22.3.2. Updating Registrations
22.3.2. 更新注册

The update of a registration will require IESG Approval on the advice of a Designated Expert.

注册的更新需要IESG根据指定专家的建议进行批准。

22.4. Layout Types
22.4. 布局类型

IANA created a registry called the "pNFS Layout Types Registry".

IANA创建了一个名为“pNFS布局类型注册表”的注册表。

All assignments to the registry are made on a Standards Action basis, with Expert Review required.

登记处的所有任务都是在标准行动的基础上进行的,需要专家审查。

Layout types are 32-bit numbers. The value zero is Reserved. Values in the range 0x80000000 to 0xFFFFFFFF inclusive are designated for Private Use. IANA will assign numbers from the range 0x00000001 to 0x7FFFFFFF inclusive.

布局类型是32位数字。保留值0。0x80000000到0xFFFFFF(含0xFFFFFF)范围内的值指定为私人使用。IANA将分配范围为0x00000001到0x7FFFFFFF(含0x7FFFFFFF)的数字。

The registry is a list of assignments, each containing five fields.

注册表是一个分配列表,每个包含五个字段。

1. The name of the layout type. This name must have the prefix "LAYOUT4_". The name must be unique.

1. 布局类型的名称。此名称必须具有前缀“LAYOUT4”。名称必须是唯一的。

2. The value of the layout type. IANA will assign this number, and the request from the registrant will use TBD1 instead of an actual value. The value assigned must be unique. A Designated Expert must be used to ensure that when the name of the layout type and its value are added to the NFSv4.1 layouttype4 enumerated data type in the NFSv4.1 XDR description ([13]), the result continues to be a valid XDR description.

2. 布局类型的值。IANA将分配此编号,注册人的请求将使用TBD1而不是实际值。指定的值必须是唯一的。必须使用指定的专家来确保当布局类型的名称及其值添加到NFSv4.1 XDR描述([13])中的NFSv4.1 layouttype4枚举数据类型时,结果仍然是有效的XDR描述。

3. The Standards Track RFC(s) that describe the notification. If the RFC(s) have not yet been published, the registrant will use RFCTBD2, RFCTBD3, etc. instead of an actual RFC number. Collectively, the RFC(s) must adhere to the guidelines listed in Section 22.4.3.

3. 这些标准跟踪描述通知的RFC。如果RFC尚未发布,注册人将使用RFCTBD2、RFCTBD3等,而不是实际的RFC编号。总的来说,RFC必须遵守第22.4.3节中列出的指南。

4. How the RFC introduces the layout type. This is indicated by a single US-ASCII value. If the value is N, it means a minor revision to the NFSv4 protocol. If the value is L, it means a new pNFS layout type. Other values can be used with IESG Approval.

4. RFC如何引入布局类型。这由一个US-ASCII值表示。如果该值为N,则表示对NFSv4协议进行了轻微修订。如果该值为L,则表示新的pNFS布局类型。其他值可经IESG批准使用。

5. The minor versions of NFSv4 that are allowed to use the notification. While these are numeric values, IANA will not allocate and assign them; the author of the relevant RFCs with IESG Approval assigns these numbers. Each time there is a new minor version of NFSv4 approved, a Designated Expert should review the registry to make recommended updates as needed.

5. 允许使用通知的NFSv4的次要版本。虽然这些是数值,但IANA不会分配它们;获得IESG批准的相关RFC的作者分配这些编号。每次有新的NFSv4次要版本获得批准时,指定专家应审查注册表,根据需要进行建议更新。

22.4.1. Initial Registry
22.4.1. 初始注册表

The initial registry is in Table 18.

初始注册表如表18所示。

    +-----------------------+-------+----------+-----+----------------+
    | Layout Type Name      | Value | RFC      | How | Minor Versions |
    +-----------------------+-------+----------+-----+----------------+
    | LAYOUT4_NFSV4_1_FILES | 0x1   | RFC 5661 | N   | 1              |
    | LAYOUT4_OSD2_OBJECTS  | 0x2   | RFC 5664 | L   | 1              |
    | LAYOUT4_BLOCK_VOLUME  | 0x3   | RFC 5663 | L   | 1              |
    +-----------------------+-------+----------+-----+----------------+
        
    +-----------------------+-------+----------+-----+----------------+
    | Layout Type Name      | Value | RFC      | How | Minor Versions |
    +-----------------------+-------+----------+-----+----------------+
    | LAYOUT4_NFSV4_1_FILES | 0x1   | RFC 5661 | N   | 1              |
    | LAYOUT4_OSD2_OBJECTS  | 0x2   | RFC 5664 | L   | 1              |
    | LAYOUT4_BLOCK_VOLUME  | 0x3   | RFC 5663 | L   | 1              |
    +-----------------------+-------+----------+-----+----------------+
        

Table 18: Initial Layout Type Assignments

表18:初始布局类型指定

22.4.2. Updating Registrations
22.4.2. 更新注册

The update of a registration will require IESG Approval on the advice of a Designated Expert.

注册的更新需要IESG根据指定专家的建议进行批准。

22.4.3. Guidelines for Writing Layout Type Specifications
22.4.3. 布局类型规范的编写指南

The author of a new pNFS layout specification must follow these steps to obtain acceptance of the layout type as a Standards Track RFC:

新pNFS布局规范的作者必须按照以下步骤获得布局类型作为标准轨道RFC的认可:

1. The author devises the new layout specification.

1. 作者设计了新的布局规范。

2. The new layout type specification MUST, at a minimum:

2. 新布局类型规范至少必须:

* Define the contents of the layout-type-specific fields of the following data types:

* 定义以下数据类型的布局类型特定字段的内容:

+ the da_addr_body field of the device_addr4 data type;

+ 设备地址4数据类型的数据地址正文字段;

+ the loh_body field of the layouthint4 data type;

+ LayoutInt4数据类型的loh_body字段;

+ the loc_body field of layout_content4 data type (which in turn is the lo_content field of the layout4 data type);

+ layout_content4数据类型的loc_body字段(这又是layout4数据类型的lo_内容字段);

+ the lou_body field of the layoutupdate4 data type;

+ layoutupdate4数据类型的lou_body字段;

* Describe or define the storage access protocol used to access the storage devices.

* 描述或定义用于访问存储设备的存储访问协议。

* Describe whether revocation of layouts is supported.

* 描述是否支持撤销布局。

* At a minimum, describe the methods of recovery from:

* 至少描述从以下方面进行恢复的方法:

1. Failure and restart for client, server, storage device.

1. 客户端、服务器、存储设备出现故障并重新启动。

2. Lease expiration from perspective of the active client, server, storage device.

2. 从活动客户端、服务器和存储设备的角度来看,租约到期。

3. Loss of layout state resulting in fencing of client access to storage devices (for an example, see Section 12.7.3).

3. 布局状态丢失,导致客户端对存储设备的访问受到限制(例如,请参见第12.7.3节)。

* Include an IANA considerations section, which will in turn include:

* 包括IANA注意事项部分,该部分将依次包括:

+ A request to IANA for a new layout type per Section 22.4.

+ 根据第22.4节要求IANA提供新布局类型。

+ A list of requests to IANA for any new recallable object types for CB_RECALL_ANY; each entry is to be presented in the form described in Section 22.3.

+ 向IANA请求CB_RECALL_any的任何新可重调对象类型的列表;每个条目应以第22.3节所述的形式呈现。

+ A list of requests to IANA for any new notification values for CB_NOTIFY_DEVICEID; each entry is to be presented in the form described in Section 22.2.

+ 向IANA请求CB_NOTIFY_DEVICEID的任何新通知值的列表;每个条目应以第22.2节所述的形式呈现。

* Include a security considerations section. This section MUST explain how the NFSv4.1 authentication, authorization, and access-control models are preserved. That is, if a metadata server would restrict a READ or WRITE operation, how would pNFS via the layout similarly restrict a corresponding input or output operation?

* 包括安全注意事项部分。本节必须解释如何保留NFSv4.1身份验证、授权和访问控制模型。也就是说,如果元数据服务器将限制读或写操作,那么通过布局的pNFS将如何类似地限制相应的输入或输出操作?

3. The author documents the new layout specification as an Internet-Draft.

3. 作者将新的布局规范记录为互联网草案。

4. The author submits the Internet-Draft for review through the IETF standards process as defined in "The Internet Standards Process-- Revision 3" (BCP 9). The new layout specification will be submitted for eventual publication as a Standards Track RFC.

4. 作者通过“互联网标准过程——第3版”(BCP 9)中定义的IETF标准过程提交互联网草案供审查。新的布局规范将作为标准轨道RFC提交最终发布。

5. The layout specification progresses through the IETF standards process.

5. 布局规范通过IETF标准流程进行。

22.5. Path Variable Definitions
22.5. 路径变量定义

This section deals with the IANA considerations associated with the variable substitution feature for location names as described in Section 11.10.3. As described there, variables subject to substitution consist of a domain name and a specific name within that domain, with the two separated by a colon. There are two sets of IANA considerations here:

本节讨论与第11.10.3节所述位置名称变量替换功能相关的IANA注意事项。如文中所述,需要替换的变量由域名和该域中的特定名称组成,两个名称之间用冒号分隔。这里有两组IANA注意事项:

1. The list of variable names.

1. 变量名的列表。

2. For each variable name, the list of possible values.

2. 对于每个变量名,列出可能的值。

Thus, there will be one registry for the list of variable names, and possibly one registry for listing the values of each variable name.

因此,将有一个注册表用于变量名列表,也可能有一个注册表用于列出每个变量名的值。

22.5.1. Path Variables Registry
22.5.1. 路径变量注册表

IANA created a registry called the "NFSv4 Path Variables Registry".

IANA创建了一个名为“NFSv4路径变量注册表”的注册表。

22.5.1.1. Path Variable Values
22.5.1.1. 路径变量值

Variable names are of the form "${", followed by a domain name, followed by a colon (":"), followed by a domain-specific portion of the variable name, followed by "}". When the domain name is "ietf.org", all variables names must be registered with IANA on a Standards Action basis, with Expert Review required. Path variables with registered domain names neither part of nor equal to ietf.org are assigned on a Hierarchical Allocation basis (delegating to the domain owner) and thus of no concern to IANA, unless the domain owner

变量名的格式为“${”,后跟域名,后跟冒号(“:”),后跟变量名的特定于域的部分,后跟“}”。当域名为“ietf.org”时,所有变量名称必须在标准行动的基础上向IANA注册,并需要专家审查。注册域名既不属于ietf.org也不等于ietf.org的路径变量是在分层分配的基础上分配的(委托给域名所有者),因此IANA不关心,除非域名所有者

chooses to register a variable name from his domain. If the domain owner chooses to do so, IANA will do so on a First Come First Serve basis. To accommodate registrants who do not have their own domain, IANA will accept requests to register variables with the prefix "${FCFS.ietf.org:" on a First Come First Served basis. Assignments on a First Come First Basis do not require Expert Review, unless the registrant also wants IANA to establish a registry for the values of the registered variable.

选择从其域注册变量名。如果域名所有者选择这样做,IANA将以先到先得的方式进行。为了适应没有自己域的注册者,IANA将接受注册前缀为“${FCFS.ietf.org:”的变量的请求先到先得。先到先得的作业不需要专家审查,除非注册人还希望IANA为注册变量的值建立一个注册表。

The registry is a list of assignments, each containing three fields.

注册表是一个分配列表,每个包含三个字段。

1. The name of the variable. The name of this variable must start with a "${" followed by a registered domain name, followed by ":", or it must start with "${FCFS.ietf.org". The name must be no more than 64 UTF-8 characters long. The name must be unique.

1. 变量的名称。此变量的名称必须以“${”开头,后跟已注册的域名,后跟“:”,或者必须以“${FCFS.ietf.org”开头。名称长度不得超过64个UTF-8字符。名称必须唯一。

2. For assignments made on Standards Action basis, the Standards Track RFC(s) that describe the variable. If the RFC(s) have not yet been published, the registrant will use RFCTBD1, RFCTBD2, etc. instead of an actual RFC number. Note that the RFCs do not have to be a part of an NFS minor version. For assignments made on a First Come First Serve basis, an explanation (consuming no more than 1024 bytes, or more if IANA permits) of the purpose of the variable. A reference to the explanation can be substituted.

2. 对于基于标准行动的分配,标准跟踪描述变量的RFC。如果RFC尚未发布,注册人将使用RFCTBD1、RFCTBD2等,而不是实际的RFC编号。请注意,RFC不必是NFS次要版本的一部分。对于按先到先得原则进行的分配,应说明变量用途(如果IANA允许,不超过1024字节或更多字节)。可以替换对解释的引用。

3. The point of contact, including an email address. The point of contact can consume up to 256 bytes (or more if IANA permits). For assignments made on a Standards Action basis, the point of contact is always IESG.

3. 联系人,包括电子邮件地址。接触点最多可以消耗256个字节(如果IANA允许,可以消耗更多字节)。对于基于标准行动的任务,联系点始终为IESG。

22.5.1.1.1. Initial Registry
22.5.1.1.1. 初始注册表

The initial registry is in Table 19.

初始注册表如表19所示。

         +------------------------+----------+------------------+
         | Variable Name          | RFC      | Point of Contact |
         +------------------------+----------+------------------+
         | ${ietf.org:CPU_ARCH}   | RFC 5661 | IESG             |
         | ${ietf.org:OS_TYPE}    | RFC 5661 | IESG             |
         | ${ietf.org:OS_VERSION} | RFC 5661 | IESG             |
         +------------------------+----------+------------------+
        
         +------------------------+----------+------------------+
         | Variable Name          | RFC      | Point of Contact |
         +------------------------+----------+------------------+
         | ${ietf.org:CPU_ARCH}   | RFC 5661 | IESG             |
         | ${ietf.org:OS_TYPE}    | RFC 5661 | IESG             |
         | ${ietf.org:OS_VERSION} | RFC 5661 | IESG             |
         +------------------------+----------+------------------+
        

Table 19: Initial List of Path Variables

表19:路径变量的初始列表

IANA has created registries for the values of the variable names ${ietf.org:CPU_ARCH} and ${ietf.org:OS_TYPE}. See Sections 22.5.2 and 22.5.3.

IANA已经为变量名${ietf.org:CPU_ARCH}和${ietf.org:OS_TYPE}的值创建了注册表。见第22.5.2节和第22.5.3节。

For the values of the variable ${ietf.org:OS_VERSION}, no registry is needed as the specifics of the values of the variable will vary with the value of ${ietf.org:OS_TYPE}. Thus, values for ${ietf.org: OS_VERSION} are on a Hierarchical Allocation basis and are of no concern to IANA.

对于变量${ietf.org:OS_VERSION}的值,不需要注册,因为变量值的细节将随${ietf.org:OS_TYPE}的值而变化。因此,${ietf.org:OS_VERSION}的值是基于分层分配的,IANA不关心。

22.5.1.1.2. Updating Registrations
22.5.1.1.2. 更新注册

The update of an assignment made on a Standards Action basis will require IESG Approval on the advice of a Designated Expert.

在标准行动基础上进行的任务更新需要IESG根据指定专家的建议进行批准。

The registrant can always update the point of contact of an assignment made on a First Come First Serve basis. Any other update will require Expert Review.

注册人始终可以按照先到先得的原则更新任务的联系人。任何其他更新都需要专家审查。

22.5.2. Values for the ${ietf.org:CPU_ARCH} Variable
22.5.2. ${ietf.org:CPU_ARCH}变量的值

IANA created a registry called the "NFSv4 ${ietf.org:CPU_ARCH} Value Registry".

IANA创建了一个名为“NFSv4${ietf.org:CPU_ARCH}值注册表”的注册表。

Assignments to the registry are made on a First Come First Serve basis. The zero-length value of ${ietf.org:CPU_ARCH} is Reserved. Values with a prefix of "PRIV" are designated for Private Use.

登记处的分配以先到先得的方式进行。${ietf.org:CPU_ARCH}的零长度值是保留的。前缀为“PRIV”的值指定为私人使用。

The registry is a list of assignments, each containing three fields.

注册表是一个分配列表,每个包含三个字段。

1. A value of the ${ietf.org:CPU_ARCH} variable. The value must be 1 to 32 UTF-8 characters long. The value must be unique.

1. ${ietf.org:CPU_ARCH}变量的值。该值的长度必须为1到32个UTF-8字符。该值必须是唯一的。

2. An explanation (consuming no more than 1024 bytes, or more if IANA permits) of what CPU architecture the value denotes. A reference to the explanation can be substituted.

2. 对该值所表示的CPU体系结构的解释(消耗不超过1024字节,如果IANA允许,消耗不超过1024字节)。可以替换对解释的引用。

3. The point of contact, including an email address. The point of contact can consume up to 256 bytes (or more if IANA permits).

3. 联系人,包括电子邮件地址。接触点最多可以消耗256个字节(如果IANA允许,可以消耗更多字节)。

22.5.2.1. Initial Registry
22.5.2.1. 初始注册表

There is no initial registry.

没有初始注册表。

22.5.2.2. Updating Registrations
22.5.2.2. 更新注册

The registrant is free to update the assignment, i.e., change the explanation and/or point-of-contact fields.

注册人可以自由更新分配,即更改解释和/或联系点字段。

22.5.3. Values for the ${ietf.org:OS_TYPE} Variable
22.5.3. ${ietf.org:OS_TYPE}变量的值

IANA created a registry called the "NFSv4 ${ietf.org:OS_TYPE} Value Registry".

IANA创建了一个名为“NFSv4${ietf.org:OS_TYPE}值注册表”的注册表。

Assignments to the registry are made on a First Come First Serve basis. The zero-length value of ${ietf.org:OS_TYPE} is Reserved. Values with a prefix of "PRIV" are designated for Private Use.

登记处的分配以先到先得的方式进行。${ietf.org:OS_TYPE}的零长度值是保留的。前缀为“PRIV”的值指定为私人使用。

The registry is a list of assignments, each containing three fields.

注册表是一个分配列表,每个包含三个字段。

1. A value of the ${ietf.org:OS_TYPE} variable. The value must be 1 to 32 UTF-8 characters long. The value must be unique.

1. ${ietf.org:OS_TYPE}变量的值。该值的长度必须为1到32个UTF-8字符。该值必须是唯一的。

2. An explanation (consuming no more than 1024 bytes, or more if IANA permits) of what CPU architecture the value denotes. A reference to the explanation can be substituted.

2. 对该值所表示的CPU体系结构的解释(消耗不超过1024字节,如果IANA允许,消耗不超过1024字节)。可以替换对解释的引用。

3. The point of contact, including an email address. The point of contact can consume up to 256 bytes (or more if IANA permits).

3. 联系人,包括电子邮件地址。接触点最多可以消耗256个字节(如果IANA允许,可以消耗更多字节)。

22.5.3.1. Initial Registry
22.5.3.1. 初始注册表

There is no initial registry.

没有初始注册表。

22.5.3.2. Updating Registrations
22.5.3.2. 更新注册

The registrant is free to update the assignment, i.e., change the explanation and/or point of contact fields.

注册人可以自由更新分配,即更改解释和/或联系点字段。

23. References
23. 工具书类
23.1. Normative References
23.1. 规范性引用文件

[1] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[1] Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[2] Eisler, M., Ed., "XDR: External Data Representation Standard", STD 67, RFC 4506, May 2006.

[2] 艾斯勒,M.,编辑,“XDR:外部数据表示标准”,STD 67,RFC 4506,2006年5月。

[3] Thurlow, R., "RPC: Remote Procedure Call Protocol Specification Version 2", RFC 5531, May 2009.

[3] 瑟洛,R.,“RPC:远程过程调用协议规范版本2”,RFC55312009年5月。

[4] Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol Specification", RFC 2203, September 1997.

[4] Eisler,M.,Chiu,A.,和L.Ling,“RPCSEC_GSS协议规范”,RFC 2203,1997年9月。

[5] Zhu, L., Jaganathan, K., and S. Hartman, "The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism Version 2", RFC 4121, July 2005.

[5] Zhu,L.,Jaganathan,K.,和S.Hartman,“Kerberos版本5通用安全服务应用程序接口(GSS-API)机制版本2”,RFC 41212005年7月。

[6] The Open Group, "Section 3.191 of Chapter 3 of Base Definitions of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[6] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232的基本定义第3章第3.191节”,2004年。

[7] Linn, J., "Generic Security Service Application Program Interface Version 2, Update 1", RFC 2743, January 2000.

[7] 林恩,J.,“通用安全服务应用程序接口版本2,更新1”,RFC 2743,2000年1月。

[8] Talpey, T. and B. Callaghan, "Remote Direct Memory Access Transport for Remote Procedure Call", RFC 5666, January 2010.

[8] Talpey,T.和B.Callaghan,“远程过程调用的远程直接内存访问传输”,RFC 5666,2010年1月。

[9] Talpey, T. and B. Callaghan, "Network File System (NFS) Direct Data Placement", RFC 5667, January 2010.

[9] Talpey,T.和B.Callaghan,“网络文件系统(NFS)直接数据放置”,RFC 5667,2010年1月。

[10] Recio, R., Metzler, B., Culley, P., Hilland, J., and D. Garcia, "A Remote Direct Memory Access Protocol Specification", RFC 5040, October 2007.

[10] Recio,R.,Metzler,B.,Culley,P.,Hilland,J.,和D.Garcia,“远程直接内存访问协议规范”,RFC 50402007年10月。

[11] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.

[11] Krawczyk,H.,Bellare,M.和R.Canetti,“HMAC:用于消息身份验证的键控哈希”,RFC 2104,1997年2月。

[12] Eisler, M., "RPCSEC_GSS Version 2", RFC 5403, February 2009.

[12] 艾斯勒,M.,“RPCSEC_GSS版本2”,RFC 5403,2009年2月。

[13] Shepler, S., Ed., Eisler, M., Ed., and D. Noveck, Ed., "Network File System (NFS) Version 4 Minor Version 1 External Data Representation Standard (XDR) Description", RFC 5662, January 2010.

[13] Shepler,S.,Ed.,Eisler,M.,Ed.,和D.Noveck,Ed.,“网络文件系统(NFS)版本4次要版本1外部数据表示标准(XDR)描述”,RFC 5662,2010年1月。

[14] The Open Group, "Section 3.372 of Chapter 3 of Base Definitions of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[14] 开放组,“开放组基本规范第6期IEEE Std 1003.1第3章基本定义第3.372节,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”,2004年。

[15] Eisler, M., "IANA Considerations for Remote Procedure Call (RPC) Network Identifiers and Universal Address Formats", RFC 5665, January 2010.

[15] Eisler,M.,“远程过程调用(RPC)网络标识符和通用地址格式的IANA注意事项”,RFC 5665,2010年1月。

[16] The Open Group, "Section 'read()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[16] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”的系统接口部分,2004年。

[17] The Open Group, "Section 'readdir()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[17] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”系统接口的“readdir()部分”,2004年。

[18] The Open Group, "Section 'write()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[18] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”的系统接口部分,2004年。

[19] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002.

[19] Hoffman,P.和M.Blanchet,“国际化弦的准备(“stringprep”)”,RFC 3454,2002年12月。

[20] The Open Group, "Section 'chmod()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[20] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232的系统接口“chmod()”部分”,2004年。

[21] International Organization for Standardization, "Information Technology - Universal Multiple-octet coded Character Set (UCS) - Part 1: Architecture and Basic Multilingual Plane", ISO Standard 10646-1, May 1993.

[21] 国际标准化组织,“信息技术-通用多八位编码字符集(UCS)-第1部分:体系结构和基本多语言平面”,ISO标准10646-11993年5月。

[22] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998.

[22] Alvestrand,H.,“IETF字符集和语言政策”,BCP 18,RFC 2277,1998年1月。

[23] Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)", RFC 3491, March 2003.

[23] Hoffman,P.和M.Blanchet,“Nameprep:国际化域名(IDN)的Stringprep配置文件”,RFC 34912003年3月。

[24] The Open Group, "Section 'fcntl()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[24] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”系统接口的“fcntl()部分”,2004年。

[25] The Open Group, "Section 'fsync()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[25] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004版,HTML版本(www.opengroup.org),ISBN 1931624232的系统接口“fsync()”部分”,2004年。

[26] The Open Group, "Section 'getpwnam()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[26] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232”系统接口的“getpwnam()”部分,2004年。

[27] The Open Group, "Section 'unlink()' of System Interfaces of The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition, HTML Version (www.opengroup.org), ISBN 1931624232", 2004.

[27] 开放组,“开放组基本规范第6期IEEE Std 1003.1,2004年版,HTML版本(www.opengroup.org),ISBN 1931624232的系统接口“unlink()”部分”,2004年。

[28] Schaad, J., Kaliski, B., and R. Housley, "Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 4055, June 2005.

[28] Schaad,J.,Kaliski,B.,和R.Housley,“互联网X.509公钥基础设施证书和证书撤销列表(CRL)配置文件中使用的RSA加密的其他算法和标识符”,RFC 4055,2005年6月。

[29] National Institute of Standards and Technology, "Cryptographic Algorithm Object Registration", URL http://csrc.nist.gov/ groups/ST/crypto_apps_infra/csor/algorithms.html, November 2007.

[29] 国家标准与技术研究所,“加密算法对象注册”,网址http://csrc.nist.gov/ groups/ST/crypto_apps_infra/csor/algorithms.html,2007年11月。

23.2. Informative References
23.2. 资料性引用

[30] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame, C., Eisler, M., and D. Noveck, "Network File System (NFS) version 4 Protocol", RFC 3530, April 2003.

[30] Shepler,S.,Callaghan,B.,Robinson,D.,Thurlow,R.,Beame,C.,Eisler,M.,和D.Noveck,“网络文件系统(NFS)版本4协议”,RFC 3530,2003年4月。

[31] Callaghan, B., Pawlowski, B., and P. Staubach, "NFS Version 3 Protocol Specification", RFC 1813, June 1995.

[31] Callaghan,B.,Pawlowski,B.,和P.Staubach,“NFS版本3协议规范”,RFC 1813,1995年6月。

[32] Eisler, M., "LIPKEY - A Low Infrastructure Public Key Mechanism Using SPKM", RFC 2847, June 2000.

[32] Eisler,M.,“LIPKEY——一种使用SPKM的低基础设施公钥机制”,RFC 28472000年6月。

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

[33] Eisler,M.,“NFS版本2和版本3的安全问题以及NFS协议对RPCSEC_GSS和Kerberos V5的使用”,RFC 2623,1999年6月。

[34] Juszczak, C., "Improving the Performance and Correctness of an NFS Server", USENIX Conference Proceedings, June 1990.

[34] Juszczak,C.,“提高NFS服务器的性能和正确性”,USENIX会议记录,1990年6月。

[35] Reynolds, J., Ed., "Assigned Numbers: RFC 1700 is Replaced by an On-line Database", RFC 3232, January 2002.

[35] Reynolds,J.,Ed.,“分配号码:RFC 1700被在线数据库取代”,RFC 3232,2002年1月。

[36] Srinivasan, R., "Binding Protocols for ONC RPC Version 2", RFC 1833, August 1995.

[36] Srinivasan,R.,“ONC RPC版本2的绑定协议”,RFC 1833,1995年8月。

[37] Werme, R., "RPC XID Issues", USENIX Conference Proceedings, February 1996.

[37] Werme,R.,“RPC XID问题”,USENIX会议记录,1996年2月。

[38] Nowicki, B., "NFS: Network File System Protocol specification", RFC 1094, March 1989.

[38] Nowicki,B.,“NFS:网络文件系统协议规范”,RFC10941989年3月。

[39] Bhide, A., Elnozahy, E., and S. Morgan, "A Highly Available Network Server", USENIX Conference Proceedings, January 1991.

[39] Bhide,A.,Elnozahy,E.,和S.Morgan,“高可用网络服务器”,USENIX会议记录,1991年1月。

[40] Halevy, B., Welch, B., and J. Zelenka, "Object-Based Parallel NFS (pNFS) Operations", RFC 5664, January 2010.

[40] Halevy,B.,Welch,B.,和J.Zelenka,“基于对象的并行NFS(pNFS)操作”,RFC 5664,2010年1月。

[41] Black, D., Glasgow, J., and S. Fridella, "Parallel NFS (pNFS) Block/Volume Layout", RFC 5663, January 2010.

[41] Black,D.,Glasgow,J.,和S.Fridella,“并行NFS(pNFS)块/卷布局”,RFC 5663,2010年1月。

[42] Callaghan, B., "WebNFS Client Specification", RFC 2054, October 1996.

[42] Callaghan,B.,“WebNFS客户端规范”,RFC2054,1996年10月。

[43] Callaghan, B., "WebNFS Server Specification", RFC 2055, October 1996.

[43] Callaghan,B.,“WebNFS服务器规范”,RFC20551996年10月。

[44] IESG, "IESG Processing of RFC Errata for the IETF Stream", July 2008.

[44] IESG,“IESG处理IETF流的RFC勘误表”,2008年7月。

[45] Shepler, S., "NFS Version 4 Design Considerations", RFC 2624, June 1999.

[45] Shepler,S.,“NFS版本4设计注意事项”,RFC 26241999年6月。

[46] The Open Group, "Protocols for Interworking: XNFS, Version 3W, ISBN 1-85912-184-5", February 1998.

[46] 开放组,“互通协议:XNFS,3W版,ISBN 1-85912-184-5”,1998年2月。

[47] Floyd, S. and V. Jacobson, "The Synchronization of Periodic Routing Messages", IEEE/ACM Transactions on Networking 2(2), pp. 122-136, April 1994.

[47] Floyd,S.和V.Jacobson,“定期路由消息的同步”,IEEE/ACM网络事务2(2),第122-136页,1994年4月。

[48] Satran, J., Meth, K., Sapuntzakis, C., Chadalapaka, M., and E. Zeidner, "Internet Small Computer Systems Interface (iSCSI)", RFC 3720, April 2004.

[48] Satran,J.,Meth,K.,Sapuntzakis,C.,Chadalapaka,M.,和E.Zeidner,“互联网小型计算机系统接口(iSCSI)”,RFC 3720,2004年4月。

[49] Snively, R., "Fibre Channel Protocol for SCSI, 2nd Version (FCP-2)", ANSI/INCITS 350-2003, Oct 2003.

[49] Snivly,R.,“SCSI光纤通道协议,第二版(FCP-2)”,ANSI/INCITS 350-2003,2003年10月。

[50] Weber, R., "Object-Based Storage Device Commands (OSD)", ANSI/ INCITS 400-2004, July 2004, <http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf>.

[50] 韦伯,R.,“基于对象的存储设备命令(OSD)”,ANSI/INCITS 400-2004,2004年7月<http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf>.

[51] Carns, P., Ligon III, W., Ross, R., and R. Thakur, "PVFS: A Parallel File System for Linux Clusters.", Proceedings of the 4th Annual Linux Showcase and Conference, 2000.

[51] Carns,P.,Ligon III,W.,Ross,R.,和R.Thakur,“PVFS:Linux集群的并行文件系统”,第四届Linux展示和会议记录,2000年。

[52] The Open Group, "The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition", 2004.

[52] 开放组,“开放组基本规范第6期,IEEE标准1003.12004版”,2004年。

[53] Callaghan, B., "NFS URL Scheme", RFC 2224, October 1997.

[53] Callaghan,B.,“NFS URL方案”,RFC2224,1997年10月。

[54] Chiu, A., Eisler, M., and B. Callaghan, "Security Negotiation for WebNFS", RFC 2755, January 2000.

[54] Chiu,A.,Eisler,M.,和B.Callaghan,“WebNFS的安全协商”,RFC 2755,2000年1月。

[55] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.

[55] Narten,T.和H.Alvestrand,“在RFCs中编写IANA注意事项部分的指南”,BCP 26,RFC 5226,2008年5月。

Appendix A. Acknowledgments
附录A.确认书

The initial text for the SECINFO extensions were edited by Mike Eisler with contributions from Peng Dai, Sergey Klyushin, and Carl Burnett.

SECINFO扩展的初始文本由Mike Eisler编辑,彭戴、Sergey Klyushin和Carl Burnett提供了意见。

The initial text for the SESSIONS extensions were edited by Tom Talpey, Spencer Shepler, Jon Bauman with contributions from Charles Antonelli, Brent Callaghan, Mike Eisler, John Howard, Chet Juszczak, Trond Myklebust, Dave Noveck, John Scott, Mike Stolarchuk, and Mark Wittle.

会话扩展的初始文本由Tom Talpey、Spencer Shepler、Jon Bauman编辑,并由Charles Antonelli、Brent Callaghan、Mike Eisler、John Howard、Chet Juszczak、Trond Mykleburt、Dave Noveck、John Scott、Mike Stolarchuk和Mark Wittle撰稿。

Initial text relating to multi-server namespace features, including the concept of referrals, were contributed by Dave Noveck, Carl Burnett, and Charles Fan with contributions from Ted Anderson, Neil Brown, and Jon Haswell.

Dave Noveck、Carl Burnett和Charles Fan在Ted Anderson、Neil Brown和Jon Haswell的贡献下提供了与多服务器名称空间功能(包括引用概念)相关的初始文本。

The initial text for the Directory Delegations support were contributed by Saadia Khan with input from Dave Noveck, Mike Eisler, Carl Burnett, Ted Anderson, and Tom Talpey.

目录代表团支持的初始文本由Saadia Khan提供,由Dave Noveck、Mike Eisler、Carl Burnett、Ted Anderson和Tom Talpey提供输入。

The initial text for the ACL explanations were contributed by Sam Falkner and Lisa Week.

ACL解释的初始文本由Sam Falkner和Lisa Week提供。

The pNFS work was inspired by the NASD and OSD work done by Garth Gibson. Gary Grider has also been a champion of high-performance parallel I/O. Garth Gibson and Peter Corbett started the pNFS effort with a problem statement document for the IETF that formed the basis for the pNFS work in NFSv4.1.

pNFS工作的灵感来自Garth Gibson完成的NASD和OSD工作。Gary Grider也是高性能并行I/O的拥护者。Garth Gibson和Peter Corbett以IETF的问题声明文档开始了pNFS工作,该文档构成了NFSv4.1中pNFS工作的基础。

The initial text for the parallel NFS support was edited by Brent Welch and Garth Goodson. Additional authors for those documents were Benny Halevy, David Black, and Andy Adamson. Additional input came from the informal group that contributed to the construction of the initial pNFS drafts; specific acknowledgment goes to Gary Grider, Peter Corbett, Dave Noveck, Peter Honeyman, and Stephen Fridella.

并行NFS支持的初始文本由Brent Welch和Garth Goodson编辑。这些文件的其他作者是Benny Halevy、David Black和Andy Adamson。其他投入来自非正式小组,该小组为初步国家森林计划草案的编制做出了贡献;特别感谢加里·格里德、彼得·科贝特、戴夫·诺维克、彼得·霍尼曼和斯蒂芬·弗里德拉。

Fredric Isaman found several errors in draft versions of the ONC RPC XDR description of the NFSv4.1 protocol.

Fredric Isaman在NFSv4.1协议的ONC RPC XDR描述的草稿版本中发现了几个错误。

Audrey Van Belleghem provided, in numerous ways, essential co-ordination and management of the process of editing the specification documents.

Audrey Van Belleghem以多种方式对规范文件的编辑过程进行了必要的协调和管理。

Richard Jernigan gave feedback on the file layout's striping pattern design.

Richard Jernigan就文件布局的条带模式设计给出了反馈。

Several formal inspection teams were formed to review various areas of the protocol. All the inspections found significant errors and room for improvement. NFSv4.1's inspection teams were:

成立了几个正式的视察队来审查议定书的各个领域。所有检查都发现了重大错误和改进空间。NFSv4.1的检查小组为:

o ACLs, with the following inspectors: Sam Falkner, Bruce Fields, Rahul Iyer, Saadia Khan, Dave Noveck, Lisa Week, Mario Wurzl, and Alan Yoder.

o ACLs,由以下检查员组成:山姆·福克纳、布鲁斯·菲尔兹、拉胡尔·艾耶、萨迪亚·汗、戴夫·诺维克、丽莎·韦克、马里奥·沃尔兹尔和艾伦·约德。

o Sessions, with the following inspectors: William Brown, Tom Doeppner, Robert Gordon, Benny Halevy, Fredric Isaman, Rick Macklem, Trond Myklebust, Dave Noveck, Karen Rochford, John Scott, and Peter Shah.

o 与以下检查员的会议:威廉·布朗、汤姆·多普纳、罗伯特·戈登、本尼·哈勒维、弗雷德里克·伊萨曼、里克·麦克莱姆、特隆·米克尔布斯特、戴夫·诺维克、卡伦·罗克福德、约翰·斯科特和彼得·沙阿。

o Initial pNFS inspection, with the following inspectors: Andy Adamson, David Black, Mike Eisler, Marc Eshel, Sam Falkner, Garth Goodson, Benny Halevy, Rahul Iyer, Trond Myklebust, Spencer Shepler, and Lisa Week.

o 初始pNFS检查,由以下检查员进行:安迪·亚当森、大卫·布莱克、迈克·艾斯勒、马克·埃舍尔、山姆·福克纳、加思·古德森、本尼·哈雷维、拉胡尔·艾耶、特隆·米克尔布斯特、斯宾塞·舍普勒和丽莎·韦克。

o Global namespace, with the following inspectors: Mike Eisler, Dan Ellard, Craig Everhart, Fredric Isaman, Trond Myklebust, Dave Noveck, Theresa Raj, Spencer Shepler, Renu Tewari, and Robert Thurlow.

o 全局命名空间,具有以下检查器:Mike Eisler、Dan Ellard、Craig Everhart、Fredric Isaman、Trond Myklebust、Dave Noveck、Theresa Raj、Spencer Shepler、Renu Tewari和Robert Thurlow。

o NFSv4.1 file layout type, with the following inspectors: Andy Adamson, Marc Eshel, Sam Falkner, Garth Goodson, Rahul Iyer, Trond Myklebust, and Lisa Week.

o NFSv4.1文件布局类型,具有以下检查人员:安迪·亚当森、马克·埃舍尔、山姆·福克纳、加斯·古德森、拉胡尔·艾耶、特隆·米克勒布斯特和丽莎·韦克。

o NFSv4.1 locking and directory delegations, with the following inspectors: Mike Eisler, Pranoop Erasani, Robert Gordon, Saadia Khan, Eric Kustarz, Dave Noveck, Spencer Shepler, and Amy Weaver.

o NFSv4.1锁定和目录委派,由以下检查员进行:迈克·艾斯勒、普拉努普·埃拉萨尼、罗伯特·戈登、萨迪亚·汗、埃里克·库斯塔兹、戴夫·诺维克、斯宾塞·谢普勒和艾米·韦弗。

o EXCHANGE_ID and DESTROY_CLIENTID, with the following inspectors: Mike Eisler, Pranoop Erasani, Robert Gordon, Benny Halevy, Fredric Isaman, Saadia Khan, Ricardo Labiaga, Rick Macklem, Trond Myklebust, Spencer Shepler, and Brent Welch.

o 与以下检查员交换身份证并销毁客户身份证:迈克·艾斯勒、普拉努普·埃拉萨尼、罗伯特·戈登、本尼·哈雷、弗雷德里克·伊萨曼、萨迪亚·汗、里卡多·拉比亚加、里克·麦克莱姆、特隆·米克勒布斯特、斯宾塞·谢普勒和布伦特·韦尔奇。

o Final pNFS inspection, with the following inspectors: Andy Adamson, Mike Eisler, Mark Eshel, Sam Falkner, Jason Glasgow, Garth Goodson, Robert Gordon, Benny Halevy, Dean Hildebrand, Rahul Iyer, Suchit Kaura, Trond Myklebust, Anatoly Pinchuk, Spencer Shepler, Renu Tewari, Lisa Week, and Brent Welch.

o 最终pNFS检查,由以下检查员进行:安迪·亚当森、迈克·艾斯勒、马克·埃谢尔、山姆·福克纳、杰森·格拉斯哥、加思·古德森、罗伯特·戈登、本尼·哈雷、迪安·希尔德布兰德、拉胡尔·艾耶、苏契特·考拉、特隆德·米克勒布斯特、安纳托利·平丘克、斯宾塞·舍普勒、雷努·特瓦里、丽莎·韦尔奇和布伦特·韦尔奇。

A review team worked together to generate the tables of assignments of error sets to operations and make sure that each such assignment had two or more people validating it. Participating in the process were Andy Adamson, Mike Eisler, Sam Falkner, Garth Goodson, Robert Gordon, Trond Myklebust, Dave Noveck, Spencer Shepler, Tom Talpey, Amy Weaver, and Lisa Week.

一个审查小组共同工作,生成操作错误集的分配表,并确保每个这样的分配都有两个或更多的人进行验证。参与这一过程的有安迪·亚当森、迈克·艾斯勒、山姆·福克纳、加思·古德森、罗伯特·戈登、特隆·米克尔布斯特、戴夫·诺维克、斯宾塞·谢普勒、汤姆·塔尔佩、艾米·韦弗和丽莎·韦克。

Jari Arkko, David Black, Scott Bradner, Lisa Dusseault, Lars Eggert, Chris Newman, and Tim Polk provided valuable review and guidance.

贾里·阿克科、大卫·布莱克、斯科特·布拉德纳、丽莎·杜肖特、拉尔斯·艾格特、克里斯·纽曼和蒂姆·波尔克提供了宝贵的评论和指导。

Olga Kornievskaia found several errors in the SSV specification.

Olga Kornievskaia在SSV规范中发现了几个错误。

Ricardo Labiaga found several places where the use of RPCSEC_GSS was underspecified.

里卡多·拉比亚加(Ricardo Labiaga)发现有几个地方未对RPCSEC_GSS的使用进行规定。

Those who provided miscellaneous comments include: Andy Adamson, Sunil Bhargo, Alex Burlyga, Pranoop Erasani, Bruce Fields, Vadim Finkelstein, Jason Goldschmidt, Vijay K. Gurbani, Sergey Klyushin, Ricardo Labiaga, James Lentini, Anshul Madan, Daniel Muntz, Daniel Picken, Archana Ramani, Jim Rees, Mahesh Siddheshwar, Tom Talpey, and Peter Varga.

提供杂项评论的人包括:安迪·亚当森、苏尼尔·巴尔戈、亚历克斯·布里加、普拉努普·埃拉萨尼、布鲁斯·菲尔兹、瓦迪姆·芬克尔斯坦、杰森·戈德施密特、维杰·古巴尼、谢尔盖·克鲁申、里卡多·拉比加、詹姆斯·兰提尼、安舒尔·马丹、丹尼尔·蒙茨、丹尼尔·皮肯、阿尔卡纳·拉马尼、吉姆·里斯、马赫什·西德赫瓦、汤姆·塔尔佩和彼得·瓦尔加。

Authors' Addresses

作者地址

Spencer Shepler (editor) Storspeed, Inc. 7808 Moonflower Drive Austin, TX 78750 USA

斯宾塞·谢普勒(编辑)美国德克萨斯州奥斯汀市月光大道7808号Storspeed公司,邮编:78750

   Phone: +1-512-402-5811 ext 8530
   EMail: shepler@storspeed.com
        
   Phone: +1-512-402-5811 ext 8530
   EMail: shepler@storspeed.com
        

Mike Eisler (editor) NetApp 5765 Chase Point Circle Colorado Springs, CO 80919 USA

迈克·艾斯勒(编辑)美国科罗拉多州科罗拉多斯普林斯市蔡斯角环线NetApp 5765邮编:80919

   Phone: +1-719-599-9026
   EMail: mike@eisler.com
   URI:   http://www.eisler.com
        
   Phone: +1-719-599-9026
   EMail: mike@eisler.com
   URI:   http://www.eisler.com
        

David Noveck (editor) NetApp 1601 Trapelo Road, Suite 16 Waltham, MA 02451 USA

David Noveck(编辑)美国马萨诸塞州沃尔瑟姆市特拉佩罗路1601号NetApp 16室02451

   Phone: +1-781-768-5347
   EMail: dnoveck@netapp.com
        
   Phone: +1-781-768-5347
   EMail: dnoveck@netapp.com