--- /dev/null
+LDLM Request
+^^^^^^^^^^^^
+[[struct-ldlm-request]]
+
+The 'ldlm_request' structure is a description of the lock being
+requested. Which resource is the target, what lock is current, and
+what lock desired.
+
+[source,c]
+----
+struct ldlm_request {
+ __u32 lock_flags;
+ __u32 lock_count;
+ struct ldlm_lock_desc lock_desc;
+ struct lustre_handle lock_handle[2];
+};
+----
+
+The 'lock_flags' field governs how the lock request is to be
+interpreted. The flags are:
+
+[source,c]
+----
+#define LDLM_FL_LOCK_CHANGED 0x0000000000000001ULL // bit 0
+#define LDLM_FL_BLOCK_GRANTED 0x0000000000000002ULL // bit 1
+#define LDLM_FL_BLOCK_CONV 0x0000000000000004ULL // bit 2
+#define LDLM_FL_BLOCK_WAIT 0x0000000000000008ULL // bit 3
+#define LDLM_FL_AST_SENT 0x0000000000000020ULL // bit 5
+#define LDLM_FL_REPLAY 0x0000000000000100ULL // bit 8
+#define LDLM_FL_INTENT_ONLY 0x0000000000000200ULL // bit 9
+#define LDLM_FL_HAS_INTENT 0x0000000000001000ULL // bit 12
+#define LDLM_FL_FLOCK_DEADLOCK 0x0000000000008000ULL // bit 15
+#define LDLM_FL_DISCARD_DATA 0x0000000000010000ULL // bit 16
+#define LDLM_FL_NO_TIMEOUT 0x0000000000020000ULL // bit 17
+#define LDLM_FL_BLOCK_NOWAIT 0x0000000000040000ULL // bit 18
+#define LDLM_FL_TEST_LOCK 0x0000000000080000ULL // bit 19
+#define LDLM_FL_CANCEL_ON_BLOCK 0x0000000000800000ULL // bit 23
+#define LDLM_FL_DENY_ON_CONTENTION 0x0000000040000000ULL // bit 30
+#define LDLM_FL_AST_DISCARD_DATA 0x0000000080000000ULL // bit 31
+#define LDLM_FL_FAIL_LOC 0x0000000100000000ULL // bit 32
+#define LDLM_FL_SKIPPED 0x0000000200000000ULL // bit 33
+#define LDLM_FL_CBPENDING 0x0000000400000000ULL // bit 34
+#define LDLM_FL_WAIT_NOREPROC 0x0000000800000000ULL // bit 35
+#define LDLM_FL_CANCEL 0x0000001000000000ULL // bit 36
+#define LDLM_FL_LOCAL_ONLY 0x0000002000000000ULL // bit 37
+#define LDLM_FL_FAILED 0x0000004000000000ULL // bit 38
+#define LDLM_FL_CANCELING 0x0000008000000000ULL // bit 39
+#define LDLM_FL_LOCAL 0x0000010000000000ULL // bit 40
+#define LDLM_FL_LVB_READY 0x0000020000000000ULL // bit 41
+#define LDLM_FL_KMS_IGNORE 0x0000040000000000ULL // bit 42
+#define LDLM_FL_CP_REQD 0x0000080000000000ULL // bit 43
+#define LDLM_FL_CLEANED 0x0000100000000000ULL // bit 44
+#define LDLM_FL_ATOMIC_CB 0x0000200000000000ULL // bit 45
+#define LDLM_FL_BL_AST 0x0000400000000000ULL // bit 46
+#define LDLM_FL_BL_DONE 0x0000800000000000ULL // bit 47
+#define LDLM_FL_NO_LRU 0x0001000000000000ULL // bit 48
+#define LDLM_FL_FAIL_NOTIFIED 0x0002000000000000ULL // bit 49
+#define LDLM_FL_DESTROYED 0x0004000000000000ULL // bit 50
+#define LDLM_FL_SERVER_LOCK 0x0008000000000000ULL // bit 51
+#define LDLM_FL_RES_LOCKED 0x0010000000000000ULL // bit 52
+#define LDLM_FL_WAITED 0x0020000000000000ULL // bit 53
+#define LDLM_FL_NS_SRV 0x0040000000000000ULL // bit 54
+#define LDLM_FL_EXCL 0x0080000000000000ULL // bit 55
+----
+
+The 'lock_count' field represents how many requests are queued on this
+resource.
+
+[[struct-ldlm-lock-desc]]
+
+The lock descriptor conveys the specific details about a particular
+lock being requested or granted. It appears in
+<<struct-ldlm-request>>.
+
+[source,c]
+----
+struct ldlm_lock_desc {
+ struct ldlm_resource_desc l_resource;
+ ldlm_mode_t l_req_mode;
+ ldlm_mode_t l_granted_mode;
+ ldlm_wire_policy_data_t l_policy_data;
+};
+----
+
+[[struct-ldlm-resource-desc]]
+
+The resource descriptor identifies the individual resource that is
+being locked, along with what sort of thing it is.
+
+[source,c]
+----
+struct ldlm_resource_desc {
+ ldlm_type_t lr_type;
+ __u32 lr_padding; /* also fix lustre_swab_ldlm_resource_desc */
+ struct ldlm_res_id lr_name;
+};
+----
+
+[[ldlm-type-t]]
+The 'lr_type' field identifies one of the four types of lock that
+might be placed on a resource. A "plain" lock type just locks a
+particular resource. An "extent" lock type only locks a contiguous
+sequence of byte offsets within a regular file. An "flock" lock type
+represents an application layer advisory lock from the 'flock()'
+system call. While Lustre manages "flock" types locks on behalf of the
+application, they do not affect Lustre operation. An "ibits" lock
+type allows fine grained locking of different parts of a single
+resource. A single lock request or cancellation may operate on one or
+more lock bits, or individual lock bits may be granted on the same
+resource separately. See also <<ldlm-wire-policy-data-t>>. A lock
+descriptor may also have no type at all, in which case the 'lr_type'
+field is 0, meaning "no lock".
+
+[source,c]
+----
+enum {
+ LDLM_PLAIN = 10,
+ LDLM_EXTENT = 11,
+ LDLM_FLOCK = 12,
+ LDLM_IBITS = 13,
+} ldlm_type_t;
+----
+
+[[struct-ldlm-res-id]]
+The 'lr_name' field identifies (by name) the resource(s) that are the
+objects of the locking operation.
+
+[source,c]
+----
+struct ldlm_res_id {
+ __u64 name[4];
+};
+----
+
+The 'name' array holds identifiers for the resource in question. Those
+identifiers may be the elements of a 'struct lu_fid' file ID, or they
+may be other uniquely identifying values for the resource. See
+<<struct-lu-fid>>.
+
+[[ldlm-mode-t]]
+The 'l_req_mode' and 'l_granted_mode' fields give the kind of lock
+being requested and the kind of lock that has been granted. The field
+values are:
+
+[source,c]
+----
+enum {
+ LCK_EX = 1, /* exclusive */
+ LCK_PW = 2, /* privileged write */
+ LCK_PR = 4, /* privileged read */
+ LCK_CW = 8, /* concurrent write */
+ LCK_CR = 16, /* concurrent read */
+ LCK_NL = 32, /* */
+ LCK_GROUP = 64, /* */
+ LCK_COS = 128, /* */
+} ldlm_mode_t;
+----
+
+Despite the fact that the lock modes are not overlapping, these lock
+modes are exclusive. In addition the mode value 0 is the MINMODE,
+i.e. no lock at all.
+
+In a request 'l_req_mode' is the value actually being requested and
+'l_granted_mode' is the value that currently is in place on for the
+requester. In a reply the 'l_req_mode' may be modified if more or
+fewer privileges were granted than requested, and the
+'l_granted_mode' is what has, in fact, been granted.
+
+[[ldlm-wire-policy-data-t]]
+The 'l_policy_data' field gives the kind of resource being
+requested/granted. It is a union of these struct definitions:
+
+[source,c]
+----
+typedef union {
+ struct ldlm_extent l_extent;
+ struct ldlm_flock_wire l_flock;
+ struct ldlm_inodebits l_inodebits;
+} ldlm_wire_policy_data_t;
+----
+
+[[struct-ldlm-extent]]
+[source,c]
+----
+struct ldlm_extent {
+ __u64 start;
+ __u64 end;
+ __u64 gid;
+};
+----
+
+[[struct-ldlm-flock-wire]]
+[source,c]
+----
+struct ldlm_flock_wire {
+ __u64 lfw_start;
+ __u64 lfw_end;
+ __u64 lfw_owner;
+ __u32 lfw_padding;
+ __u32 lfw_pid;
+};
+----
+
+[[struct-ldlm-inodebits]]
+[source,c]
+----
+struct ldlm_inodebits {
+ __u64 bits;
+};
+----
+
+Thus the lock may be on an 'extent', a contiguous sequence of bytes
+in a regular file; an 'flock wire', whatever to heck that is; or a
+portion of an inode. For a "plain" lock (or one with no type at all)
+the 'l_policy_data' field has zero length.
+
+The 'lock_handle' array's first element holds the handle for the lock
+manager (see the description of <<struct-lustre-handle>>) involved in
+the operation. There is only one lock manager involved in any given
+RPC. The second handle is set to zero except in the rare case that
+there is also an early lock cancellation. The latter case will be
+discussed elsewhere.
+