- 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 (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));
- atomic_set(&ll_capa_stat, 0);
+ if (!old) {
+ ocapa->u.cli.inode = inode;
+ lli->lli_mds_capa = ocapa;
+ capa_count[CAPA_SITE_CLIENT]++;
+
+ DEBUG_CAPA(D_SEC, capa, "add MDS");
+ } else {
+ cfs_spin_lock(&old->c_lock);
+ old->c_capa = *capa;
+ cfs_spin_unlock(&old->c_lock);
+
+ DEBUG_CAPA(D_SEC, capa, "update MDS");
+
+ capa_put(ocapa);
+ ocapa = old;
+ }
+ return ocapa;
+}
+
+static struct obd_capa *do_lookup_oss_capa(struct inode *inode, int opc)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_capa *ocapa;
+
+ /* inside capa_lock */
+ cfs_list_for_each_entry(ocapa, &lli->lli_oss_capas, u.cli.lli_list) {
+ if ((capa_opc(&ocapa->c_capa) & opc) != opc)
+ continue;
+
+ LASSERT(lu_fid_eq(capa_fid(&ocapa->c_capa),
+ ll_inode2fid(inode)));
+ LASSERT(ocapa->c_site == CAPA_SITE_CLIENT);
+
+ DEBUG_CAPA(D_SEC, &ocapa->c_capa, "found client");
+ return ocapa;
+ }
+
+ return NULL;
+}
+
+static inline void inode_add_oss_capa(struct inode *inode,
+ struct obd_capa *ocapa)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_capa *tmp;
+ cfs_list_t *next = NULL;
+
+ /* capa is sorted in lli_oss_capas so lookup can always find the
+ * latest one */
+ cfs_list_for_each_entry(tmp, &lli->lli_oss_capas, u.cli.lli_list) {
+ if (cfs_time_after(ocapa->c_expiry, tmp->c_expiry)) {
+ next = &tmp->u.cli.lli_list;
+ break;