1    	/*
2    	 * This program is free software; you can redistribute it and/or
3    	 * modify it under the terms of the GNU Lesser General Public License
4    	 * as published by the Free Software Foundation; either version 3 of
5    	 * the License, or (at your option) any later version.
6    	 *
7    	 * This program is distributed in the hope that it will be useful, but
8    	 * WITHOUT ANY WARRANTY; without even the implied warranty of
9    	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
10   	 * Lesser General Public License for more details.
11   	 *
12   	 * You should have received a copy of the GNU Lesser General Public
13   	 * License along with this library; if not, write to the Free Software
14   	 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15   	 * 02110-1301 USA
16   	 *
17   	 *---------------------------------------
18   	 */
19   	
20   	/**
21   	 * @defgroup fsal_up Upcalls for the FSAL
22   	 * @{
23   	 *
24   	 * These functions allow a filesystem realization to modify the cache
25   	 * and trigger recalls without it having to gain personal, intimate
26   	 * knowledge of the rest of Ganesha.
27   	 *
28   	 * These calls are *synchronous*, meaning they immediately do whatever
29   	 * they're going to do and return to the caller.  They are intended to
30   	 * be called from a notification or other thread.  Specifically, this
31   	 * means that you *must not* call layoutrecall from within layoutget.
32   	 *
33   	 * If you need to call one of these methods from within an FSAL
34   	 * method, use the delayed executor interface in delayed_exec.h with a
35   	 * delay of 0.	If you don't want to share, you could have the FSAL
36   	 * spawn a thread fridge of its own.
37   	 *
38   	 * If people find themselves needing it, generally, I'll rebuild the
39   	 * asynchronous upcall interface on top of this synchronous one.
40   	 */
41   	
42   	/**
43   	 * @file fsal_up.h
44   	 * @brief Definitions for FSAL upcalls
45   	 */
46   	
47   	#ifndef FSAL_UP_H
48   	#define FSAL_UP_H
49   	
50   	#include "gsh_status.h"
(1) Event include_recursion: #include file "/home/staticanalysis/src/git/2019-05-18/cov-ganesha/nfs-ganesha/src/include/fsal_api.h" includes itself: fsal_api.h -> fsal_up.h -> fsal_api.h
(2) Event caretline: ^
51   	#include "fsal_api.h"
52   	#include "sal_data.h"
53   	
54   	enum {
55   		/* empty flags */
56   		fsal_up_update_null = 0x0000,
57   	
58   		/* Update the filesize only if the new size is greater
59   		 * than that currently set */
60   		fsal_up_update_filesize_inc = 0x0001,
61   	
62   		/* Update the atime only if the new time is later than
63   		 * the currently set time. */
64   		fsal_up_update_atime_inc = 0x0002,
65   	
66   		/* Update the creation time only if the new time is
67   		 * later than the currently set time. */
68   		fsal_up_update_creation_inc = 0x0004,
69   	
70   		/* Update the ctime only if the new time is later
71   		 * than that currently * set */
72   		fsal_up_update_ctime_inc = 0x0008,
73   	
74   		/* Update the mtime only if the new time is later
75   		 * than that currently set. */
76   		fsal_up_update_mtime_inc = 0x0010,
77   	
78   		/* Update the spaceused only if the new size is greater
79   		 * than that currently set. */
80   		fsal_up_update_spaceused_inc = 0x0040,
81   	
82   		/* The file link count is zero. */
83   		fsal_up_nlink = 0x0080,
84   	};
85   	
86   	/**
87   	 * @brief Optional stuff for layoutreturn
88   	 * @{
89   	 */
90   	enum layoutrecall_howspec {
91   		layoutrecall_howspec_exactly,
92   		layoutrecall_howspec_complement,
93   		layoutrecall_not_specced
94   	};
95   	
96   	struct layoutrecall_spec {
97   		enum layoutrecall_howspec how;
98   		union {
99   			clientid4 client;
100  		} u;
101  	};
102  	
103  	/** @} */
104  	
105  	static const uint32_t FSAL_UP_INVALIDATE_ATTRS = 0x01;
106  	static const uint32_t FSAL_UP_INVALIDATE_ACL = 0x02;
107  	static const uint32_t FSAL_UP_INVALIDATE_CONTENT = 0x04;
108  	static const uint32_t FSAL_UP_INVALIDATE_DIR_POPULATED = 0x08;
109  	static const uint32_t FSAL_UP_INVALIDATE_DIR_CHUNKS = 0x10;
110  	static const uint32_t FSAL_UP_INVALIDATE_CLOSE = 0x100;
111  	static const uint32_t FSAL_UP_INVALIDATE_FS_LOCATIONS = 0x200;
112  	static const uint32_t FSAL_UP_INVALIDATE_SEC_LABEL = 0x400;
113  	static const uint32_t FSAL_UP_INVALIDATE_PARENT = 0x800;
114  	#define FSAL_UP_INVALIDATE_CACHE ( \
115  		FSAL_UP_INVALIDATE_ATTRS | \
116  		FSAL_UP_INVALIDATE_ACL | \
117  		FSAL_UP_INVALIDATE_CONTENT | \
118  		FSAL_UP_INVALIDATE_DIR_POPULATED | \
119  		FSAL_UP_INVALIDATE_DIR_CHUNKS | \
120  		FSAL_UP_INVALIDATE_FS_LOCATIONS | \
121  		FSAL_UP_INVALIDATE_SEC_LABEL | \
122  		FSAL_UP_INVALIDATE_PARENT)
123  	
124  	/**
125  	 * @brief Possible upcall functions
126  	 *
127  	 * This structure holds pointers to upcall functions.  Each FSAL
128  	 * should call through the vector in its export.
129  	 *
130  	 * For FSAL stacking, the 'higher' FSAL should copy its vector,
131  	 * over-ride whatever methods it wishes, and pass the new vector to
132  	 * the lower FSAL.  It may then pass through, surround, or override as
133  	 * it wishes.
134  	 *
135  	 * Note that all these functions take keys, not fsal object handles.
136  	 * This is because the FSAL will always, by definition, be able to
137  	 * know the key by which it identifies an object, but cannot know the
138  	 * address of the handle stored in the cache.
139  	 */
140  	
141  	struct fsal_up_vector {
142  		/** The gsh_export this vector lives in */
143  		struct gsh_export *up_gsh_export;
144  		/** The fsal_export this vector lives in */
145  		struct fsal_export *up_fsal_export;
146  	
147  		/** ready to take upcalls condition */
148  		bool up_ready;
149  		bool up_cancel;
150  		pthread_mutex_t up_mutex;
151  		pthread_cond_t up_cond;
152  	
153  		/** Invalidate some or all of a cache entry
154  		 *
155  		 * @param[in] vec	Up ops vector
156  		 * @param[in] obj	The file to invalidate
157  		 * @param[in] flags	FSAL_UP_INVALIDATE_*
158  		 *
159  		 * @return FSAL status
160  		 *
161  		 */
162  		fsal_status_t (*invalidate)(const struct fsal_up_vector *vec,
163  					    struct gsh_buffdesc *obj,
164  					    uint32_t flags);
165  	
166  		/** Update cached attributes
167  		 *
168  		 * @param[in] vec    Up ops vector
169  		 * @param[in] obj    The file to update
170  		 * @param[in] attr   List of attributes to update.  Note that the
171  		 *                   @c type, @c fsid, @c fileid, @c rawdev, and
172  		 *                   @c generation fields must not be updated and
173  		 *                   the corresponding bits in the mask must not
174  		 *                   be set, nor may the ATTR_RDATA_ERR bit be set.
175  		 * @param[in] flags  Flags requesting special update handling
176  		 *
177  		 */
178  		fsal_status_t (*update)(const struct fsal_up_vector *vec,
179  					struct gsh_buffdesc *obj,
180  					struct attrlist *attr,
181  					uint32_t flags);
182  	
183  		/** Grant a lock to a client
184  		 *
185  		 * @param[in] vec	   Up ops vector
186  		 * @param[in] file         The file in question
187  		 * @param[in] owner        The lock owner
188  		 * @param[in] lock_param   A description of the lock
189  		 *
190  		 */
191  		state_status_t (*lock_grant)(const struct fsal_up_vector *vec,
192  					     struct gsh_buffdesc *file,
193  					     void *owner,
194  					     fsal_lock_param_t *lock_param);
195  	
196  		/** Signal lock availability
197  		 *
198  		 * @param[in] vec	   Up ops vector
199  		 * @param[in] file         The file in question
200  		 * @param[in] owner        The lock owner
201  		 * @param[in] lock_param   A description of the lock
202  		 *
203  		 */
204  		state_status_t (*lock_avail)(const struct fsal_up_vector *vec,
205  					     struct gsh_buffdesc *file,
206  					     void *owner,
207  					     fsal_lock_param_t *lock_param);
208  	
209  		/** Perform a layoutrecall on a single file
210  		 *
211  		 * @param[in] vec	   Up ops vector
212  		 * @param[in] handle       Handle on which the layout is held
213  		 * @param[in] layout_type  The type of layout to recall
214  		 * @param[in] changed      Whether the layout has changed and the
215  		 *                         client ought to finish writes through MDS
216  		 * @param[in] segment      Segment to recall
217  		 * @param[in] cookie       A cookie returned with the return that
218  		 *                         completely satisfies a recall
219  		 * @param[in] spec         Lets us be fussy about what clients we send
220  		 *                         to. May be NULL.
221  		 *
222  		 */
223  		state_status_t (*layoutrecall)(const struct fsal_up_vector *vec,
224  					       struct gsh_buffdesc *handle,
225  					       layouttype4 layout_type,
226  					       bool changed,
227  					       const struct pnfs_segment *segment,
228  					       void *cookie,
229  					       struct layoutrecall_spec *spec);
230  	
231  		/** Remove or change a deviceid
232  		 *
233  		 * @param[in] notify_type  Change or remove
234  		 * @param[in] layout_type  The layout type affected
235  		 * @param[in] devid        The deviceid
236  		 * @param[in] immediate    Whether the change is immediate
237  		 *
238  		 */
239  		state_status_t (*notify_device)(notify_deviceid_type4 notify_type,
240  						layouttype4 layout_type,
241  						struct pnfs_deviceid devid,
242  						bool immediate);
243  	
244  		/** Recall a delegation
245  		 *
246  		 * @param[in] vec	Up ops vector
247  		 * @param[in] handle	Handle on which the delegation is held
248  		 */
249  		state_status_t (*delegrecall)(const struct fsal_up_vector *vec,
250  					      struct gsh_buffdesc *handle);
251  	
252  		/** Invalidate some or all of a cache entry and close if open
253  		 *
254  		 * This version should NOT be used if an FSAL supports extended
255  		 * operations, instead, the FSAL may directly close the file as
256  		 * necessary.
257  		 *
258  		 * @param[in] vec	Up ops vector
259  		 * @param[in] obj	The file to invalidate
260  		 * @param[in] flags	Flags governing invalidation
261  		 *
262  		 * @return FSAL status
263  		 *
264  		 */
265  		fsal_status_t (*invalidate_close)(const struct fsal_up_vector *vec,
266  						  struct gsh_buffdesc *obj,
267  						  uint32_t flags);
268  	};
269  	
270  	extern struct fsal_up_vector fsal_up_top;
271  	
272  	/**
273  	 * @{
274  	 * @brief Asynchronous upcall wrappers
275  	 */
276  	
277  	fsal_status_t up_async_invalidate(struct fridgethr *fr,
278  					  const struct fsal_up_vector *vec,
279  					  struct gsh_buffdesc *obj, uint32_t flags,
280  					  void (*cb)(void *, fsal_status_t),
281  					  void *cb_arg);
282  	fsal_status_t up_async_update(struct fridgethr *fr,
283  				      const struct fsal_up_vector *vec,
284  				      struct gsh_buffdesc *obj, struct attrlist *attr,
285  				      uint32_t flags,
286  				      void (*cb)(void *, fsal_status_t),
287  				      void *cb_arg);
288  	fsal_status_t up_async_lock_grant(struct fridgethr *fr,
289  					  const struct fsal_up_vector *vec,
290  					  struct gsh_buffdesc *file, void *owner,
291  					  fsal_lock_param_t *lock_param,
292  					  void (*cb)(void *, state_status_t),
293  					  void *cb_arg);
294  	fsal_status_t up_async_lock_avail(struct fridgethr *fr,
295  					  const struct fsal_up_vector *vec,
296  					  struct gsh_buffdesc *file, void *owner,
297  					  fsal_lock_param_t *lock_param,
298  					  void (*cb)(void *, state_status_t),
299  					  void *cb_arg);
300  	fsal_status_t up_async_layoutrecall(struct fridgethr *fr,
301  					    const struct fsal_up_vector *vec,
302  					    struct gsh_buffdesc *handle,
303  					    layouttype4 layout_type, bool changed,
304  					    const struct pnfs_segment *segment,
305  					    void *cookie,
306  					    struct layoutrecall_spec *spec,
307  					    void (*cb)(void *, state_status_t),
308  					    void *cb_arg);
309  	fsal_status_t up_async_notify_device(struct fridgethr *fr,
310  					     const struct fsal_up_vector *vec,
311  					     notify_deviceid_type4 notify_type,
312  					     layouttype4 layout_type,
313  					     struct pnfs_deviceid *devid,
314  					     bool immediate,
315  					     void (*cb)(void *, state_status_t),
316  					     void *cb_arg);
317  	fsal_status_t up_async_delegrecall(struct fridgethr *fr,
318  					   const struct fsal_up_vector *vec,
319  					   struct gsh_buffdesc *handle,
320  					   void (*cb)(void *, state_status_t),
321  					   void *cb_arg);
322  	
323  	/** @} */
324  	int async_delegrecall(struct fridgethr *fr, struct fsal_obj_handle *obj);
325  	
326  	int async_cbgetattr(struct fridgethr *fr, struct fsal_obj_handle *obj,
327  			    nfs_client_id_t *client);
328  	
329  	void up_ready_init(struct fsal_up_vector *up_ops);
330  	void up_ready_set(struct fsal_up_vector *up_ops);
331  	void up_ready_wait(struct fsal_up_vector *up_ops);
332  	void up_ready_cancel(struct fsal_up_vector *up_ops);
333  	
334  	#endif /* FSAL_UP_H */
335  	/** @} */
336