1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	
4    	#ifndef CEPH_CLS_LOCK_TYPES_H
5    	#define CEPH_CLS_LOCK_TYPES_H
6    	
7    	#include "include/encoding.h"
8    	#include "include/types.h"
9    	#include "include/utime.h"
10   	#include "msg/msg_types.h"
11   	
12   	/* lock flags */
13   	#define LOCK_FLAG_MAY_RENEW 0x1    /* idempotent lock acquire */
14   	#define LOCK_FLAG_MUST_RENEW 0x2   /* lock must already be acquired */
15   	
16   	enum ClsLockType {
17   	  LOCK_NONE                = 0,
18   	  LOCK_EXCLUSIVE           = 1,
19   	  LOCK_SHARED              = 2,
20   	  LOCK_EXCLUSIVE_EPHEMERAL = 3, /* lock object is removed @ unlock */
21   	};
22   	
23   	inline const char *cls_lock_type_str(ClsLockType type)
24   	{
25   	    switch (type) {
26   	      case LOCK_NONE:
27   		return "none";
28   	      case LOCK_EXCLUSIVE:
29   		return "exclusive";
30   	      case LOCK_SHARED:
31   		return "shared";
32   	      case LOCK_EXCLUSIVE_EPHEMERAL:
33   		return "exclusive-ephemeral";
34   	      default:
35   		return "<unknown>";
36   	    }
37   	}
38   	
39   	inline bool cls_lock_is_exclusive(ClsLockType type) {
40   	  return LOCK_EXCLUSIVE == type || LOCK_EXCLUSIVE_EPHEMERAL == type;
41   	}
42   	
43   	inline bool cls_lock_is_ephemeral(ClsLockType type) {
44   	  return LOCK_EXCLUSIVE_EPHEMERAL == type;
45   	}
46   	
47   	inline bool cls_lock_is_valid(ClsLockType type) {
48   	  return LOCK_SHARED == type ||
49   	    LOCK_EXCLUSIVE == type ||
50   	    LOCK_EXCLUSIVE_EPHEMERAL == type;
51   	}
52   	
53   	namespace rados {
54   	  namespace cls {
55   	    namespace lock {
56   	
57   	      /*
58   	       * locker_id_t: the locker id, needs to be unique in a single lock
59   	       */
60   	      struct locker_id_t {
61   	        entity_name_t locker;   // locker's client name
62   		std::string cookie;          // locker's cookie.
63   	
64   	        locker_id_t() {}
65   	        locker_id_t(entity_name_t& _n, const std::string& _c) : locker(_n), cookie(_c) {}
66   	
67   	        void encode(ceph::buffer::list &bl) const {
68   	          ENCODE_START(1, 1, bl);
69   	          encode(locker, bl);
70   	          encode(cookie, bl);
71   	          ENCODE_FINISH(bl);
72   	        }
73   	        void decode(ceph::buffer::list::const_iterator &bl) {
74   	          DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl);
75   	          decode(locker, bl);
76   	          decode(cookie, bl);
77   	          DECODE_FINISH(bl);
78   	        }
79   	
80   	        bool operator<(const locker_id_t& rhs) const {
81   	          if (locker == rhs.locker)
82   	            return cookie.compare(rhs.cookie) < 0;
83   	          if (locker < rhs.locker)
84   	            return true;
85   	          return false;
86   	        }
87   	        void dump(Formatter *f) const;
88   		friend std::ostream& operator<<(std::ostream& out,
89   						const locker_id_t& data) {
90   		  out << data.locker;
91   		  return out;
92   		}
93   	        static void generate_test_instances(list<locker_id_t*>& o);
94   	      };
95   	      WRITE_CLASS_ENCODER(locker_id_t)
96   	
97   	      struct locker_info_t
98   	      {
99   	        utime_t expiration;  // expiration: non-zero means epoch of locker expiration
100  	        entity_addr_t addr;  // addr: locker address
101  		std::string description;  // description: locker description, may be empty
102  	
103  	        locker_info_t() {}
104  	        locker_info_t(const utime_t& _e, const entity_addr_t& _a,
105  	                      const std::string& _d) :  expiration(_e), addr(_a), description(_d) {}
106  	
107  	        void encode(ceph::buffer::list &bl, uint64_t features) const {
108  	          ENCODE_START(1, 1, bl);
109  	          encode(expiration, bl);
110  	          encode(addr, bl, features);
111  	          encode(description, bl);
112  	          ENCODE_FINISH(bl);
113  	        }
114  	        void decode(ceph::buffer::list::const_iterator &bl) {
115  	          DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl);
116  	          decode(expiration, bl);
117  	          decode(addr, bl);
118  	          decode(description, bl);
119  	          DECODE_FINISH(bl);
120  	        }
121  	        void dump(Formatter *f) const;
122  		friend std::ostream& operator<<(std::ostream& out,
123  						const locker_info_t& data) {
124  		  out << "{addr:" << data.addr << ", exp:";
125  	
126  		  const auto& exp = data.expiration;
127  		  if (exp.is_zero()) {
128  		    out << "never}";
129  		  } else {
130  		    out << exp.to_real_time() << "}";
131  		  }
132  	
133  		  return out;
134  		}
135  	        static void generate_test_instances(list<locker_info_t *>& o);
136  	      };
137  	      WRITE_CLASS_ENCODER_FEATURES(locker_info_t)
138  	
139  	      struct lock_info_t {
140  	        map<locker_id_t, locker_info_t> lockers; // map of lockers
141  	        ClsLockType lock_type;                   // lock type (exclusive / shared)
142  		std::string tag;                              // tag: operations on lock can only succeed with this tag
143  	                                                 //      as long as set of non expired lockers
144  	                                                 //      is bigger than 0.
145  	
146  	        void encode(ceph::buffer::list &bl, uint64_t features) const {
147  	          ENCODE_START(1, 1, bl);
148  	          encode(lockers, bl, features);
(1) Event assignment: Assigning: "t" = "(uint8_t)this->lock_type".
Also see events: [overrun-buffer-val]
149  	          uint8_t t = (uint8_t)lock_type;
(2) Event overrun-buffer-val: Overrunning buffer pointed to by "t" of 1 bytes by passing it to a function which accesses it at byte offset 7. [details]
Also see events: [assignment]
150  	          encode(t, bl);
151  	          encode(tag, bl);
152  	          ENCODE_FINISH(bl);
153  	        }
154  	        void decode(ceph::buffer::list::const_iterator &bl) {
155  	          DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl);
156  	          decode(lockers, bl);
157  	          uint8_t t;
158  	          decode(t, bl);
159  	          lock_type = (ClsLockType)t;
160  	          decode(tag, bl);
161  	          DECODE_FINISH(bl);
162  	        }
163  	        lock_info_t() : lock_type(LOCK_NONE) {}
164  	        void dump(Formatter *f) const;
165  	        static void generate_test_instances(list<lock_info_t *>& o);
166  	      };
167  	      WRITE_CLASS_ENCODER_FEATURES(lock_info_t);
168  	    }
169  	  }
170  	}
171  	
172  	#endif
173