static inline int have_expired_capa(void)
{
struct obd_capa *ocapa;
+ struct lustre_capa *capa;
int expired = 0;
unsigned long expiry;
+ struct timeval tv;
+
ENTRY;
+ do_gettimeofday(&tv);
spin_lock(&capa_lock);
if (!list_empty(ll_capa_list)) {
ocapa = list_entry(ll_capa_list->next, struct obd_capa, c_list);
-
- expired = __capa_is_to_expire(ocapa);
- if (!expired && !timer_pending(&ll_capa_timer)) {
- /* the expired capa has been put, so set the timer to
- * the expired of the next capa */
- expiry = expiry_to_jiffies(ocapa->c_capa.lc_expiry);
- mod_timer(&ll_capa_timer, expiry);
- CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
+ expired = __capa_is_to_expire(ocapa, &tv);
+ if (!expired) {
+ capa = &ocapa->c_capa;
+ expiry = expiry_to_jiffies(capa->lc_expiry -
+ capa_pre_expiry(capa));
+ if (time_before(expiry, ll_capa_timer.expires) ||
+ !timer_pending(&ll_capa_timer)) {
+ mod_timer(&ll_capa_timer, expiry);
+ CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
+ expiry);
+ }
}
}
spin_unlock(&capa_lock);
int rc;
ENTRY;
- if (capa_expired(&ocapa->c_capa)) {
- /* this is the second time try to renew since the last
- * renewal failed, it means on one is openning it and
- * should be put now. */
- capa_put(ocapa);
- RETURN(0);
- }
-
rc = md_getattr(md_exp, &lli->lli_id, valid, NULL, NULL, 0,
0, ocapa, &req);
RETURN(rc);
{
struct thread_ctl *ctl = arg;
unsigned long flags;
+ int rc;
ENTRY;
{
while (1) {
struct l_wait_info lwi = { 0 };
- struct obd_capa *ocapa, *next = NULL, tcapa;
+ struct obd_capa *ocapa, tcapa, *tmp, *next = NULL;
unsigned long expiry, sleep = CAPA_PRE_EXPIRY;
+ struct inode *inode;
+ struct timeval tv;
l_wait_event(capa_thread.t_ctl_waitq,
(have_expired_capa() || ll_capa_check_stop()),
if (ll_capa_check_stop())
break;
+ do_gettimeofday(&tv);
spin_lock(&capa_lock);
- list_for_each_entry(ocapa, ll_capa_list, c_list) {
+ list_for_each_entry_safe(ocapa, tmp, ll_capa_list, c_list) {
+ if (ocapa->c_capa.lc_flags & CAPA_FL_SHORT)
+ sleep = CAPA_PRE_EXPIRY_SHORT;
+
if (ocapa->c_capa.lc_op == CAPA_TRUNC)
continue;
- if (__capa_is_to_expire(ocapa)) {
- /* copy capa in case it's deleted */
+ if (capa_expired(&ocapa->c_capa)) {
+ capa_put_nolock(ocapa);
+ continue;
+ }
+
+ if (__capa_is_to_expire(ocapa, &tv)) {
+ inode = igrab(ocapa->c_inode);
+ if (inode == NULL) {
+ DEBUG_CAPA(D_ERROR, &ocapa->c_capa,
+ "igrab failed for");
+ continue;
+ }
+
tcapa = *ocapa;
spin_unlock(&capa_lock);
- ll_renew_capa(&tcapa);
+ rc = ll_renew_capa(&tcapa);
+ iput(inode);
spin_lock(&capa_lock);
} else {
break;
}
}
+
if (next) {
- expiry = expiry_to_jiffies(next->c_capa.lc_expiry);
- mod_timer(&ll_capa_timer, expiry);
- CDEBUG(D_INFO, "ll_capa_timer new expiry: %lu\n", expiry);
- if (next->c_capa.lc_flags & CAPA_FL_NOROUND)
- sleep = CAPA_PRE_EXPIRY_NOROUND;
+ struct lustre_capa *capa = &next->c_capa;
+
+ expiry = expiry_to_jiffies(capa->lc_expiry -
+ capa_pre_expiry(capa));
+ if (time_before(expiry, ll_capa_timer.expires) ||
+ !timer_pending(&ll_capa_timer)) {
+ mod_timer(&ll_capa_timer, expiry);
+ CDEBUG(D_INFO,"ll_capa_timer new expiry: %lu\n",
+ expiry);
+ }
}
spin_unlock(&capa_lock);
EXIT;
}
-int ll_set_capa(struct inode *inode, struct lookup_intent *it)
+int ll_set_capa(struct inode *inode, struct lookup_intent *it,
+ struct obd_client_handle *och)
{
struct ptlrpc_request *req = LUSTRE_IT(it)->it_data;
struct mds_body *body;
if (!S_ISREG(inode->i_mode))
return 0;
+ /* GNS code path will have no req */
+ if (!req)
+ return 0;
+
body = lustre_msg_buf(req->rq_repmsg, 1, sizeof (*body));
LASSERT(body != NULL); /* reply already checked out */
LASSERT_REPSWABBED(req, 1); /* and swabbed down */
- if (!(body->valid & OBD_MD_CAPA))
+ if (!(body->valid & OBD_MD_CAPA)) {
+ if (atomic_read(&ll_capa_stat))
+ DEBUG_REQ(D_ERROR, req,
+ "no capa for (uid %u, op %d, "DLID4"\n",
+ (unsigned)current->uid, it->it_flags,
+ OLID4(&lli->lli_id));
+
return 0;
+ }
ENTRY;
spin_lock(&capa_lock);
ocapa->c_inode = inode;
- ocapa->c_handle = body->handle;
+ ocapa->c_handle = och->och_fh;
spin_unlock(&capa_lock);
spin_lock(&lli->lli_lock);
RETURN(ocapa);
}
+
+ if (atomic_read(&ll_capa_stat)) {
+ CDEBUG(D_ERROR, "can't find capa for (uid %u, op %d, mdsid "
+ LPU64", ino %u igen %u) failed.\n",
+ (unsigned)uid, op, id_group(&lli->lli_id),
+ (unsigned)id_ino(&lli->lli_id), id_gen(&lli->lli_id));
+ atomic_set(&ll_capa_stat, 0);
+ }
RETURN(NULL);
}