X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fllite_capa.c;h=1a7bd1f5839751f1c03557876c11e34766a560b1;hb=792e414c69f3888506882abedce5e06bba93f8fd;hp=536644d94705291cdcdb32e2a5a7d2a315ccaf84;hpb=d2d56f38da01001c92a09afc6b52b5acbd9bc13c;p=fs%2Flustre-release.git diff --git a/lustre/llite/llite_capa.c b/lustre/llite/llite_capa.c index 536644d..1a7bd1f 100644 --- a/lustre/llite/llite_capa.c +++ b/lustre/llite/llite_capa.c @@ -1,24 +1,41 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Copyright (C) 2005 Cluster File Systems, Inc. + * GPL HEADER START * - * Author: Lai Siyao + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * This file is part of Lustre, http://www.lustre.org. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * GPL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/llite/llite_capa.c + * + * Author: Lai Siyao */ #define DEBUG_SUBSYSTEM S_LLITE @@ -140,9 +157,10 @@ static void ll_delete_capa(struct obd_capa *ocapa) } DEBUG_CAPA(D_SEC, &ocapa->c_capa, "free client"); - list_del(&ocapa->c_list); + list_del_init(&ocapa->c_list); capa_count[CAPA_SITE_CLIENT]--; - free_capa(ocapa); + /* release the ref when alloc */ + capa_put(ocapa); } /* three places where client capa is deleted: @@ -221,7 +239,6 @@ static int capa_thread_main(void *unused) capa_get(ocapa); ll_capa_renewed++; spin_unlock(&capa_lock); - rc = md_renew_capa(ll_i2mdexp(inode), ocapa, ll_update_capa); spin_lock(&capa_lock); @@ -242,7 +259,7 @@ static int capa_thread_main(void *unused) break; } - if (atomic_read(&ocapa->c_refc)) { + if (atomic_read(&ocapa->c_refc) > 1) { DEBUG_CAPA(D_SEC, &ocapa->c_capa, "expired(c_refc %d), don't release", atomic_read(&ocapa->c_refc)); @@ -295,41 +312,17 @@ void ll_capa_thread_stop(void) ll_capa_thread.t_flags & SVC_STOPPED); } -static struct obd_capa *do_lookup_oss_capa(struct inode *inode, uid_t uid, - int opc) -{ - struct ll_inode_info *lli = ll_i2info(inode); - struct obd_capa *ocapa; - - /* inside capa_lock */ - list_for_each_entry(ocapa, &lli->lli_oss_capas, u.cli.lli_list) { - if (uid != capa_uid(&ocapa->c_capa)) - continue; - 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; -} - -/* FIXME: once uid is 0, this is mmaped IO, or fsync, truncate. */ -struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t uid, __u64 opc) +struct obd_capa *ll_osscapa_get(struct inode *inode, __u64 opc) { struct ll_inode_info *lli = ll_i2info(inode); struct obd_capa *ocapa; int found = 0; - if ((ll_i2sbi(inode)->ll_flags & LL_SBI_OSS_CAPA) == 0) - return NULL; ENTRY; + if ((ll_i2sbi(inode)->ll_flags & LL_SBI_OSS_CAPA) == 0) + RETURN(NULL); + LASSERT(opc == CAPA_OPC_OSS_WRITE || opc == CAPA_OPC_OSS_RW || opc == CAPA_OPC_OSS_TRUNC); @@ -337,18 +330,19 @@ struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t uid, __u64 opc) list_for_each_entry(ocapa, &lli->lli_oss_capas, u.cli.lli_list) { if (capa_is_expired(ocapa)) continue; - if (uid != 0 && uid != capa_uid(&ocapa->c_capa)) - continue; if ((opc & CAPA_OPC_OSS_WRITE) && capa_opc_supported(&ocapa->c_capa, CAPA_OPC_OSS_WRITE)) { - found = 1; break; + found = 1; + break; } else if ((opc & CAPA_OPC_OSS_READ) && capa_opc_supported(&ocapa->c_capa, CAPA_OPC_OSS_READ)) { - found = 1; break; + found = 1; + break; } else if ((opc & CAPA_OPC_OSS_TRUNC) && capa_opc_supported(&ocapa->c_capa, opc)) { - found = 1; break; + found = 1; + break; } } @@ -373,6 +367,7 @@ struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t uid, __u64 opc) RETURN(ocapa); } +EXPORT_SYMBOL(ll_osscapa_get); struct obd_capa *ll_mdscapa_get(struct inode *inode) { @@ -381,7 +376,7 @@ struct obd_capa *ll_mdscapa_get(struct inode *inode) ENTRY; LASSERT(inode != NULL); - + if ((ll_i2sbi(inode)->ll_flags & LL_SBI_MDS_CAPA) == 0) RETURN(NULL); @@ -416,12 +411,33 @@ static struct obd_capa *do_add_mds_capa(struct inode *inode, DEBUG_CAPA(D_SEC, capa, "update MDS"); - free_capa(ocapa); + 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 */ + 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) { @@ -452,8 +468,7 @@ static struct obd_capa *do_add_oss_capa(struct inode *inode, inode->i_mode); /* FIXME: can't replace it so easily with fine-grained opc */ - old = do_lookup_oss_capa(inode, capa_uid(capa), - capa_opc(capa) & CAPA_OPC_OSS_ONLY); + old = do_lookup_oss_capa(inode, capa_opc(capa) & CAPA_OPC_OSS_ONLY); if (!old) { ocapa->u.cli.inode = inode; INIT_LIST_HEAD(&ocapa->u.cli.lli_list); @@ -467,7 +482,7 @@ static struct obd_capa *do_add_oss_capa(struct inode *inode, DEBUG_CAPA(D_SEC, capa, "update OSS"); - free_capa(ocapa); + capa_put(ocapa); ocapa = old; } @@ -484,7 +499,7 @@ struct obd_capa *ll_add_capa(struct inode *inode, struct obd_capa *ocapa) /* truncate capa won't renew */ if (ocapa->c_capa.lc_opc != CAPA_OPC_OSS_TRUNC) { set_capa_expiry(ocapa); - list_del(&ocapa->c_list); + list_del_init(&ocapa->c_list); sort_add_capa(ocapa, ll_capa_list); update_capa_timer(ocapa, capa_renewal_time(ocapa)); @@ -535,18 +550,18 @@ int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa) } } - list_del(&ocapa->c_list); + list_del_init(&ocapa->c_list); sort_add_capa(ocapa, &ll_idle_capas); spin_unlock(&capa_lock); capa_put(ocapa); iput(inode); - return rc; + RETURN(rc); } spin_lock(&ocapa->c_lock); LASSERT(!memcmp(&ocapa->c_capa, capa, - offsetof(struct lustre_capa, lc_flags))); + offsetof(struct lustre_capa, lc_opc))); ocapa->c_capa = *capa; set_capa_expiry(ocapa); spin_unlock(&ocapa->c_lock); @@ -604,10 +619,13 @@ void ll_truncate_free_capa(struct obd_capa *ocapa) LASSERT(ocapa->c_capa.lc_opc & CAPA_OPC_OSS_TRUNC); DEBUG_CAPA(D_SEC, &ocapa->c_capa, "free truncate"); + /* release ref when find */ capa_put(ocapa); - spin_lock(&capa_lock); - ll_delete_capa(ocapa); - spin_unlock(&capa_lock); + if (likely(ocapa->c_capa.lc_opc == CAPA_OPC_OSS_TRUNC)) { + spin_lock(&capa_lock); + ll_delete_capa(ocapa); + spin_unlock(&capa_lock); + } } void ll_clear_inode_capas(struct inode *inode) @@ -619,7 +637,7 @@ void ll_clear_inode_capas(struct inode *inode) ocapa = lli->lli_mds_capa; if (ocapa) ll_delete_capa(ocapa); - + list_for_each_entry_safe(ocapa, tmp, &lli->lli_oss_capas, u.cli.lli_list) ll_delete_capa(ocapa);