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 ptlrpc_thread ll_capa_thread;
36 static struct list_head *ll_capa_list = &capa_list[CLIENT_CAPA];
37 static struct thread_ctl {
38 struct completion ctl_starting;
39 struct completion ctl_finishing;
42 static inline int have_expired_capa(void)
44 struct obd_capa *ocapa;
49 spin_lock(&capa_lock);
50 if (!list_empty(ll_capa_list)) {
51 ocapa = list_entry(ll_capa_list->next, struct obd_capa, c_list);
53 expired = __capa_is_to_expire(ocapa);
54 if (!expired && !timer_pending(&ll_capa_timer)) {
55 /* the expired capa has been put, so set the timer to
56 * the expired of the next capa */
57 expiry = expiry_to_jiffies(ocapa->c_capa.lc_expiry);
58 mod_timer(&ll_capa_timer, expiry);
59 CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
62 spin_unlock(&capa_lock);
67 static int inline ll_capa_check_stop(void)
69 return (ll_capa_thread.t_flags & SVC_STOPPING) ? 1: 0;
72 static int ll_renew_capa(struct obd_capa *ocapa)
74 struct ptlrpc_request *req = NULL;
75 /* no need to lock, no one else will touch it */
76 struct inode *inode = ocapa->c_inode;
77 struct obd_export *md_exp = ll_i2mdexp(inode);
78 struct ll_inode_info *lli = ll_i2info(inode);
85 rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0,
88 CDEBUG(D_INFO, "md_getattr failed: rc = %d\n", rc);
92 static int ll_capa_thread_main(void *arg)
94 struct thread_ctl *ctl = arg;
99 char name[sizeof(current->comm)];
100 snprintf(name, sizeof(name) - 1, "ll_capa");
101 kportal_daemonize(name);
104 SIGNAL_MASK_LOCK(current, flags);
105 sigfillset(¤t->blocked);
107 SIGNAL_MASK_UNLOCK(current, flags);
110 * letting starting function know, that we are ready and control may be
113 ll_capa_thread.t_flags = SVC_RUNNING;
114 complete(&ctl->ctl_starting);
117 struct l_wait_info lwi = { 0 };
118 struct obd_capa *ocapa, *next = NULL;
119 unsigned long expiry, sleep = CAPA_PRE_EXPIRY;
121 l_wait_event(ll_capa_thread.t_ctl_waitq,
122 (have_expired_capa() || ll_capa_check_stop()),
125 spin_lock(&capa_lock);
126 list_for_each_entry(ocapa, ll_capa_list, c_list) {
127 if (__capa_is_to_expire(ocapa)) {
128 /* get capa in case it's deleted */
131 spin_unlock(&capa_lock);
132 ll_renew_capa(ocapa);
133 capa_put(ocapa, CLIENT_CAPA);
134 spin_lock(&capa_lock);
141 expiry = expiry_to_jiffies(next->c_capa.lc_expiry);
142 mod_timer(&ll_capa_timer, expiry);
143 CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
144 if (next->c_capa.lc_flags & CAPA_FL_NOROUND)
145 sleep = CAPA_PRE_EXPIRY_NOROUND;
147 spin_unlock(&capa_lock);
149 if (ll_capa_check_stop())
152 /* wait ll_renew_capa finish */
153 set_current_state(TASK_INTERRUPTIBLE);
154 schedule_timeout(sleep * HZ);
157 ll_capa_thread.t_flags = SVC_STOPPED;
159 /* this is SMP-safe way to finish thread. */
160 complete_and_exit(&ctl->ctl_finishing, 0);
164 /* just wake up, others are handled by ll_capa_thread */
165 void ll_capa_timer_callback(unsigned long unused)
168 wake_up(&ll_capa_thread.t_ctl_waitq);
172 int ll_capa_start_thread(void)
177 LASSERT(ll_capa_thread.t_flags == 0);
178 init_completion(&ll_capa_ctl.ctl_starting);
179 init_completion(&ll_capa_ctl.ctl_finishing);
180 init_waitqueue_head(&ll_capa_thread.t_ctl_waitq);
182 rc = kernel_thread(ll_capa_thread_main, &ll_capa_ctl,
183 (CLONE_VM | CLONE_FILES));
185 CERROR("cannot start expired capa thread, "
189 wait_for_completion(&ll_capa_ctl.ctl_starting);
190 LASSERT(ll_capa_thread.t_flags == SVC_RUNNING);
194 void ll_capa_stop_thread(void)
198 ll_capa_thread.t_flags = SVC_STOPPING;
199 wake_up(&ll_capa_thread.t_ctl_waitq);
200 wait_for_completion(&ll_capa_ctl.ctl_finishing);
201 LASSERT(ll_capa_thread.t_flags == SVC_STOPPED);
202 ll_capa_thread.t_flags = 0;
207 int ll_set_och_capa(struct inode *inode, struct lookup_intent *it,
208 struct obd_client_handle *och)
210 struct ptlrpc_request *req = LUSTRE_IT(it)->it_data;
211 struct ll_inode_info *lli = ll_i2info(inode);
212 struct mds_body *body;
213 struct lustre_capa *capa;
214 __u64 mdsid = lli->lli_id.li_fid.lf_group;
215 unsigned long ino = lli->lli_id.li_stc.u.e3s.l3s_ino;
216 int capa_op = (it->it_flags & MAY_WRITE) ? MAY_WRITE : MAY_READ;
217 unsigned long expiry;
221 body = lustre_msg_buf(req->rq_repmsg, 1, sizeof (*body));
222 LASSERT(body != NULL); /* reply already checked out */
223 LASSERT_REPSWABBED(req, 1); /* and swabbed down */
225 capa = lustre_msg_buf(req->rq_repmsg, 7, sizeof (*capa));
226 LASSERT(capa != NULL); /* reply already checked out */
227 LASSERT_REPSWABBED(req, 7); /* and swabbed down */
229 och->och_capa = capa_get(current->uid, capa_op, mdsid, ino,
230 CLIENT_CAPA, capa, inode, &body->handle);
234 DEBUG_CAPA(D_INFO, capa, "ll_set_och_capa");
236 expiry = expiry_to_jiffies(capa->lc_expiry - capa_pre_expiry(capa));
238 spin_lock(&capa_lock);
239 if (time_before(expiry, ll_capa_timer.expires) ||
240 !timer_pending(&ll_capa_timer)) {
241 mod_timer(&ll_capa_timer, expiry);
242 CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
244 spin_unlock(&capa_lock);