1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004, 2005 Cluster File Systems, Inc.
6 * Author: Lai Siyao <lsy@clusterfs.com>
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Lustre; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DEBUG_SUBSYSTEM S_LLITE
27 #include <linux/version.h>
28 #include <asm/uaccess.h>
29 #include <linux/file.h>
30 #include <linux/kmod.h>
32 #include <linux/lustre_lite.h>
33 #include "llite_internal.h"
35 static struct list_head *ll_capa_list = &capa_list[CLIENT_CAPA];
36 static struct ptlrpc_thread capa_thread;
38 static struct thread_ctl {
39 struct completion ctl_starting;
40 struct completion ctl_finishing;
43 static inline int have_expired_capa(void)
45 struct obd_capa *ocapa;
46 struct lustre_capa *capa;
54 spin_lock(&capa_lock);
55 if (!list_empty(ll_capa_list)) {
56 ocapa = list_entry(ll_capa_list->next, struct obd_capa, c_list);
57 expired = __capa_is_to_expire(ocapa, &tv);
59 capa = &ocapa->c_capa;
60 expiry = expiry_to_jiffies(capa->lc_expiry -
61 capa_pre_expiry(capa));
62 if (time_before(expiry, ll_capa_timer.expires) ||
63 !timer_pending(&ll_capa_timer)) {
64 mod_timer(&ll_capa_timer, expiry);
65 CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
70 spin_unlock(&capa_lock);
75 static int inline ll_capa_check_stop(void)
77 return (capa_thread.t_flags & SVC_STOPPING) ? 1: 0;
80 static int ll_renew_capa(struct obd_capa *ocapa)
82 struct ptlrpc_request *req = NULL;
83 /* no need to lock, no one else will touch it */
84 struct inode *inode = ocapa->c_inode;
85 struct obd_export *md_exp = ll_i2mdexp(inode);
86 struct ll_inode_info *lli = ll_i2info(inode);
87 __u64 valid = OBD_MD_CAPA;
91 rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0,
96 static int ll_capa_thread(void *arg)
98 struct thread_ctl *ctl = arg;
104 char name[sizeof(current->comm)];
105 snprintf(name, sizeof(name) - 1, "ll_capa");
106 kportal_daemonize(name);
109 SIGNAL_MASK_LOCK(current, flags);
110 sigfillset(¤t->blocked);
112 SIGNAL_MASK_UNLOCK(current, flags);
115 * letting starting function know, that we are ready and control may be
118 capa_thread.t_flags = SVC_RUNNING;
119 complete(&ctl->ctl_starting);
122 struct l_wait_info lwi = { 0 };
123 struct obd_capa *ocapa, tcapa, *tmp, *next = NULL;
124 unsigned long expiry, sleep = CAPA_PRE_EXPIRY;
128 l_wait_event(capa_thread.t_ctl_waitq,
129 (have_expired_capa() || ll_capa_check_stop()),
132 if (ll_capa_check_stop())
135 do_gettimeofday(&tv);
136 spin_lock(&capa_lock);
137 list_for_each_entry_safe(ocapa, tmp, ll_capa_list, c_list) {
138 if (ocapa->c_capa.lc_flags & CAPA_FL_SHORT)
139 sleep = CAPA_PRE_EXPIRY_SHORT;
141 if (ocapa->c_capa.lc_op == CAPA_TRUNC)
144 if (capa_expired(&ocapa->c_capa)) {
145 capa_put_nolock(ocapa);
149 if (__capa_is_to_expire(ocapa, &tv)) {
150 inode = igrab(ocapa->c_inode);
152 DEBUG_CAPA(D_ERROR, &ocapa->c_capa,
158 spin_unlock(&capa_lock);
160 rc = ll_renew_capa(&tcapa);
163 spin_lock(&capa_lock);
171 struct lustre_capa *capa = &next->c_capa;
173 expiry = expiry_to_jiffies(capa->lc_expiry -
174 capa_pre_expiry(capa));
175 if (time_before(expiry, ll_capa_timer.expires) ||
176 !timer_pending(&ll_capa_timer)) {
177 mod_timer(&ll_capa_timer, expiry);
178 CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
182 spin_unlock(&capa_lock);
184 /* wait ll_renew_capa finish */
185 set_current_state(TASK_INTERRUPTIBLE);
186 schedule_timeout(sleep * HZ);
189 capa_thread.t_flags = SVC_STOPPED;
191 /* this is SMP-safe way to finish thread. */
192 complete_and_exit(&ctl->ctl_finishing, 0);
196 /* just wake up, others are handled by ll_capa_thread */
197 void ll_capa_timer_callback(unsigned long unused)
200 wake_up(&capa_thread.t_ctl_waitq);
204 int ll_capa_thread_start(void)
209 LASSERT(capa_thread.t_flags == 0);
210 init_completion(&ll_capa_ctl.ctl_starting);
211 init_completion(&ll_capa_ctl.ctl_finishing);
212 init_waitqueue_head(&capa_thread.t_ctl_waitq);
214 rc = kernel_thread(ll_capa_thread, &ll_capa_ctl,
215 (CLONE_VM | CLONE_FILES));
217 CERROR("cannot start expired capa thread, "
221 wait_for_completion(&ll_capa_ctl.ctl_starting);
222 LASSERT(capa_thread.t_flags == SVC_RUNNING);
226 void ll_capa_thread_stop(void)
230 capa_thread.t_flags = SVC_STOPPING;
231 wake_up(&capa_thread.t_ctl_waitq);
232 wait_for_completion(&ll_capa_ctl.ctl_finishing);
233 LASSERT(capa_thread.t_flags == SVC_STOPPED);
234 capa_thread.t_flags = 0;
239 int ll_set_capa(struct inode *inode, struct lookup_intent *it,
240 struct obd_client_handle *och)
242 struct ptlrpc_request *req = LUSTRE_IT(it)->it_data;
243 struct mds_body *body;
244 struct lustre_capa *capa;
245 struct obd_capa *ocapa;
246 struct ll_inode_info *lli = ll_i2info(inode);
247 unsigned long expiry;
249 if (!S_ISREG(inode->i_mode))
252 /* GNS code path will have no req */
256 body = lustre_msg_buf(req->rq_repmsg, 1, sizeof (*body));
257 LASSERT(body != NULL); /* reply already checked out */
258 LASSERT_REPSWABBED(req, 1); /* and swabbed down */
260 if (!(body->valid & OBD_MD_CAPA))
265 capa = lustre_msg_buf(req->rq_repmsg, 7, sizeof (*capa));
266 LASSERT(capa != NULL); /* reply already checked out */
267 LASSERT_REPSWABBED(req, 7); /* and swabbed down */
269 ocapa = capa_renew(capa, CLIENT_CAPA);
273 spin_lock(&capa_lock);
274 ocapa->c_inode = inode;
275 ocapa->c_handle = och->och_fh;
276 spin_unlock(&capa_lock);
278 spin_lock(&lli->lli_lock);
279 /* in case it was linked to lli_capas already */
280 if (list_empty(&ocapa->c_lli_list))
281 list_add(&ocapa->c_lli_list, &lli->lli_capas);
282 spin_unlock(&lli->lli_lock);
284 expiry = expiry_to_jiffies(capa->lc_expiry - capa_pre_expiry(capa));
286 spin_lock(&capa_lock);
287 if (time_before(expiry, ll_capa_timer.expires) ||
288 !timer_pending(&ll_capa_timer)) {
289 mod_timer(&ll_capa_timer, expiry);
290 CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
292 spin_unlock(&capa_lock);
297 int ll_set_trunc_capa(struct ptlrpc_request *req, int offset, struct inode *inode)
299 struct mds_body *body;
300 struct obd_capa *ocapa;
301 struct lustre_capa *capa;
302 struct ll_inode_info *lli = ll_i2info(inode);
304 body = lustre_msg_buf(req->rq_repmsg, offset, sizeof(*body));
308 if (!(body->valid & OBD_MD_CAPA))
312 capa = (struct lustre_capa *)lustre_swab_repbuf(req, offset + 1,
313 sizeof(*capa), lustre_swab_lustre_capa);
317 ocapa = capa_renew(capa, CLIENT_CAPA);
321 spin_lock(&lli->lli_lock);
322 /* in case it was linked to lli_capas already */
323 if (list_empty(&ocapa->c_lli_list))
324 list_add(&ocapa->c_lli_list, &lli->lli_capas);
325 spin_unlock(&lli->lli_lock);
330 struct obd_capa *ll_get_capa(struct inode *inode, uid_t uid, int op)
332 struct ll_inode_info *lli = ll_i2info(inode);
333 struct obd_capa *ocapa, *tmp;
336 list_for_each_entry_safe(ocapa, tmp, &lli->lli_capas, c_lli_list) {
337 if (ocapa->c_capa.lc_ruid != uid)
339 if (ocapa->c_capa.lc_op != op)
345 if (atomic_read(&ll_capa_stat)) {
346 CDEBUG(D_ERROR, "can't find capa for (uid %u, op %d, mdsid "
347 LPU64", ino %u igen %u) failed.\n",
348 (unsigned)uid, op, id_group(&lli->lli_id),
349 (unsigned)id_ino(&lli->lli_id), id_gen(&lli->lli_id));
350 atomic_set(&ll_capa_stat, 0);