]>
Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
18 | * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | */ | |
30 | /* | |
31 | * Copyright (c) 2011, 2012, Intel Corporation. | |
32 | */ | |
33 | /* | |
34 | * This file is part of Lustre, http://www.lustre.org/ | |
35 | * Lustre is a trademark of Sun Microsystems, Inc. | |
36 | * | |
37 | * lustre/include/lustre_mdc.h | |
38 | * | |
39 | * MDS data structures. | |
40 | * See also lustre_idl.h for wire formats of requests. | |
41 | */ | |
42 | ||
43 | #ifndef _LUSTRE_MDC_H | |
44 | #define _LUSTRE_MDC_H | |
45 | ||
46 | /** \defgroup mdc mdc | |
47 | * | |
48 | * @{ | |
49 | */ | |
50 | ||
04eb2b7f PT |
51 | #include <linux/fs.h> |
52 | #include <linux/dcache.h> | |
00d65ec8 | 53 | #include "lustre_intent.h" |
1accaadf | 54 | #include "lustre_handles.h" |
9fdaf8c0 | 55 | #include "../../include/linux/libcfs/libcfs.h" |
1accaadf GKH |
56 | #include "obd_class.h" |
57 | #include "lustre/lustre_idl.h" | |
58 | #include "lustre_lib.h" | |
59 | #include "lustre_dlm.h" | |
60 | #include "lustre_export.h" | |
d7e09d03 PT |
61 | |
62 | struct ptlrpc_client; | |
63 | struct obd_export; | |
64 | struct ptlrpc_request; | |
65 | struct obd_device; | |
66 | ||
67 | struct mdc_rpc_lock { | |
68 | struct mutex rpcl_mutex; | |
69 | struct lookup_intent *rpcl_it; | |
70 | int rpcl_fakes; | |
71 | }; | |
72 | ||
73 | #define MDC_FAKE_RPCL_IT ((void *)0x2c0012bfUL) | |
74 | ||
75 | static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck) | |
76 | { | |
77 | mutex_init(&lck->rpcl_mutex); | |
78 | lck->rpcl_it = NULL; | |
79 | } | |
80 | ||
81 | static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, | |
82 | struct lookup_intent *it) | |
83 | { | |
d2a13989 OD |
84 | if (it && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP || |
85 | it->it_op == IT_LAYOUT)) | |
d7e09d03 PT |
86 | return; |
87 | ||
88 | /* This would normally block until the existing request finishes. | |
89 | * If fail_loc is set it will block until the regular request is | |
90 | * done, then set rpcl_it to MDC_FAKE_RPCL_IT. Once that is set | |
91 | * it will only be cleared when all fake requests are finished. | |
92 | * Only when all fake requests are finished can normal requests | |
c56e256d OD |
93 | * be sent, to ensure they are recoverable again. |
94 | */ | |
d7e09d03 PT |
95 | again: |
96 | mutex_lock(&lck->rpcl_mutex); | |
97 | ||
98 | if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM)) { | |
99 | lck->rpcl_it = MDC_FAKE_RPCL_IT; | |
100 | lck->rpcl_fakes++; | |
101 | mutex_unlock(&lck->rpcl_mutex); | |
102 | return; | |
103 | } | |
104 | ||
105 | /* This will only happen when the CFS_FAIL_CHECK() was | |
106 | * just turned off but there are still requests in progress. | |
107 | * Wait until they finish. It doesn't need to be efficient | |
108 | * in this extremely rare case, just have low overhead in | |
c56e256d OD |
109 | * the common case when it isn't true. |
110 | */ | |
d7e09d03 PT |
111 | while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) { |
112 | mutex_unlock(&lck->rpcl_mutex); | |
113 | schedule_timeout(cfs_time_seconds(1) / 4); | |
114 | goto again; | |
115 | } | |
116 | ||
d2a13989 | 117 | LASSERT(!lck->rpcl_it); |
d7e09d03 PT |
118 | lck->rpcl_it = it; |
119 | } | |
120 | ||
121 | static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, | |
122 | struct lookup_intent *it) | |
123 | { | |
d2a13989 OD |
124 | if (it && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP || |
125 | it->it_op == IT_LAYOUT)) | |
23f14e79 | 126 | return; |
d7e09d03 PT |
127 | |
128 | if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */ | |
129 | mutex_lock(&lck->rpcl_mutex); | |
130 | ||
131 | LASSERTF(lck->rpcl_fakes > 0, "%d\n", lck->rpcl_fakes); | |
132 | lck->rpcl_fakes--; | |
133 | ||
134 | if (lck->rpcl_fakes == 0) | |
135 | lck->rpcl_it = NULL; | |
136 | ||
137 | } else { | |
138 | LASSERTF(it == lck->rpcl_it, "%p != %p\n", it, lck->rpcl_it); | |
139 | lck->rpcl_it = NULL; | |
140 | } | |
141 | ||
142 | mutex_unlock(&lck->rpcl_mutex); | |
d7e09d03 PT |
143 | } |
144 | ||
44779340 BB |
145 | /* Update the maximum observed easize and cookiesize. The default easize |
146 | * and cookiesize is initialized to the minimum value but allowed to grow | |
147 | * up to a single page in size if required to handle the common case. | |
148 | */ | |
d7e09d03 PT |
149 | static inline void mdc_update_max_ea_from_body(struct obd_export *exp, |
150 | struct mdt_body *body) | |
151 | { | |
152 | if (body->valid & OBD_MD_FLMODEASIZE) { | |
44779340 BB |
153 | struct client_obd *cli = &exp->exp_obd->u.cli; |
154 | ||
155 | if (cli->cl_max_mds_easize < body->max_mdsize) { | |
156 | cli->cl_max_mds_easize = body->max_mdsize; | |
157 | cli->cl_default_mds_easize = | |
09cbfeaf | 158 | min_t(__u32, body->max_mdsize, PAGE_SIZE); |
44779340 BB |
159 | } |
160 | if (cli->cl_max_mds_cookiesize < body->max_cookiesize) { | |
161 | cli->cl_max_mds_cookiesize = body->max_cookiesize; | |
162 | cli->cl_default_mds_cookiesize = | |
09cbfeaf | 163 | min_t(__u32, body->max_cookiesize, PAGE_SIZE); |
44779340 | 164 | } |
d7e09d03 PT |
165 | } |
166 | } | |
167 | ||
d7e09d03 PT |
168 | struct mdc_cache_waiter { |
169 | struct list_head mcw_entry; | |
170 | wait_queue_head_t mcw_waitq; | |
171 | }; | |
172 | ||
173 | /* mdc/mdc_locks.c */ | |
174 | int it_disposition(struct lookup_intent *it, int flag); | |
175 | void it_clear_disposition(struct lookup_intent *it, int flag); | |
176 | void it_set_disposition(struct lookup_intent *it, int flag); | |
177 | int it_open_error(int phase, struct lookup_intent *it); | |
178 | ||
38585ccc AD |
179 | static inline bool cl_is_lov_delay_create(unsigned int flags) |
180 | { | |
181 | return (flags & O_LOV_DELAY_CREATE) == O_LOV_DELAY_CREATE; | |
182 | } | |
183 | ||
184 | static inline void cl_lov_delay_create_clear(unsigned int *flags) | |
185 | { | |
186 | if ((*flags & O_LOV_DELAY_CREATE) == O_LOV_DELAY_CREATE) | |
187 | *flags &= ~O_LOV_DELAY_CREATE; | |
188 | } | |
189 | ||
d7e09d03 PT |
190 | /** @} mdc */ |
191 | ||
192 | #endif |