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. .LDLM Lock Descriptor [[struct-ldlm-lock-desc]] **** The lock descriptor conveys the specific details about a particular lock being requested or granted. It appears in <>. [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; }; ---- **** .LDLM Resource Descriptor [[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; }; ---- **** 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 <>. A lock descriptor may also have no type at all, in which case the 'lr_type' field is 0, meaning "no lock". .LDLM Type [[ldlm-type-t]] **** [source,c] ---- enum { LDLM_PLAIN = 10, LDLM_EXTENT = 11, LDLM_FLOCK = 12, LDLM_IBITS = 13, } ldlm_type_t; ---- **** The 'lr_name' field of the 'ldlm_resource_desc' (See <>) field identifies the resource that is the object of the locking operation. .LDLM Resource ID [[struct-ldlm-res-id]] **** [source,c] ---- struct ldlm_res_id { __u64 name[4]; }; ---- The 'name' identifies for the resource in question. It may be a FID (See <>), or they may be other uniquely identifying values for the resource. **** 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: .LDLM Mode [[ldlm-mode-t]] **** [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 an 'ldlm_request' structure the 'l_req_mode' field is the value actually being requested and the 'l_granted_mode' field is the value that currently is in place on for the requester. In an 'ldlm_reply' the 'l_req_mode' field may be modified if more or fewer privileges were granted than requested, and the 'l_granted_mode' is what has, in fact, been granted. The 'l_policy_data' field gives the kind of resource being requested/granted. It is a union of these struct definitions: .LDLM Wire Policy Data [[ldlm-wire-policy-data-t]] **** [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; ---- **** .LDLM Extent [[struct-ldlm-extent]] **** [source,c] ---- struct ldlm_extent { __u64 start; __u64 end; __u64 gid; }; ---- **** .LDLM Flock Wire [[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; }; ---- **** .LDLM Inodebits [[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 <>) 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.