X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fdcache.c;h=fe983195e252e119253a70db11b3c844f831f600;hb=150feb3613d2b2bbe9014ccb6a2727fd8f1cc2ce;hp=a0274d689e4b175763203f1c373bdce4bbd0c42e;hpb=e679a64ba3e622da4b4ea10df0baebe0b88e61af;p=fs%2Flustre-release.git diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index a0274d6..fe98319 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -1,15 +1,27 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution + * Copyright (c) 2001, 2002 Cluster File Systems, Inc. * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. + * This file is part of Lustre, http://www.lustre.org. * + * 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. + * + * 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. + * + * 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. */ #include -#include +#include +#include #include #define DEBUG_SUBSYSTEM S_LLITE @@ -20,27 +32,41 @@ extern struct address_space_operations ll_aops; +void ll_release(struct dentry *de) +{ + ENTRY; + + OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data)); + EXIT; +} + void ll_intent_release(struct dentry *de) { + struct lookup_intent *it; struct lustre_handle *handle; ENTRY; - if (de->d_it == NULL) { + it = de->d_it; + if (it == NULL) { EXIT; return; } - if (de->d_it->it_lock_mode) { - handle = (struct lustre_handle *)de->d_it->it_lock_handle; - if (de->d_it->it_op == IT_SETATTR) { + + LASSERT(ll_d2d(de) != NULL); + + if (it->it_lock_mode) { + handle = (struct lustre_handle *)it->it_lock_handle; + if (it->it_op == IT_SETATTR) { int rc; - ldlm_lock_decref(handle, de->d_it->it_lock_mode); + ldlm_lock_decref(handle, it->it_lock_mode); rc = ldlm_cli_cancel(handle); if (rc < 0) CERROR("ldlm_cli_cancel: %d\n", rc); } else - ldlm_lock_decref(handle, de->d_it->it_lock_mode); + ldlm_lock_decref(handle, it->it_lock_mode); } de->d_it = NULL; + //up(&ll_d2d(de)->lld_it_sem); EXIT; } @@ -50,13 +76,18 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) struct lustre_handle lockh; __u64 res_id[RES_NAME_SIZE] = {0}; struct obd_device *obddev; + int rc = 0; ENTRY; - if (it) - RETURN(0); /* lookups will have NULL it */ + if (it) { + CDEBUG(D_INFO, "name: %*s, intent: %s\n", de->d_name.len, + de->d_name.name, ldlm_it2str(it->it_op)); + if (it->it_op == IT_RENAME) + it->it_data = de; + } if (!de->d_inode) - RETURN(0); + GOTO(out, rc = 0); obddev = class_conn2obd(&sbi->ll_mdc_conn); res_id[0] = de->d_inode->i_ino; @@ -66,19 +97,60 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_MDSINTENT, NULL, 0, LCK_PR, &lockh)) { ldlm_lock_decref(&lockh, LCK_PR); - RETURN(1); + GOTO(out, rc = 1); } if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_MDSINTENT, NULL, 0, LCK_PW, &lockh)) { ldlm_lock_decref(&lockh, LCK_PW); - RETURN(1); + GOTO(out, rc = 1); + } + + /* If the dentry is busy, we won't get called in lookup2 if we + * return 0, so return 1. + * + * This is a temporary fix for bug 618962, but is one of the causes of + * 619078. */ + CDEBUG(D_INFO, "d_count: %d\n", atomic_read(&de->d_count)); + if (it && atomic_read(&de->d_count) > 0) { + CERROR("returning 1 for %*s during %s because d_count is %d\n", + de->d_name.len, de->d_name.name, ldlm_it2str(it->it_op), + atomic_read(&de->d_count)); + GOTO(out, rc = 1); + } + + out: + if (ll_d2d(de) == NULL) { + CERROR("allocating fsdata\n"); + ll_set_dd(de); + } + //down(&ll_d2d(de)->lld_it_sem); + // de->d_it = it; + + RETURN(rc); +} + +int ll_set_dd(struct dentry *de) +{ + ENTRY; + LASSERT(de != NULL); + + lock_kernel(); + + if (de->d_fsdata != NULL) { + CERROR("dentry %p already has d_fsdata set\n", de); + } else { + OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); + sema_init(&ll_d2d(de)->lld_it_sem, 1); } + unlock_kernel(); + RETURN(0); } struct dentry_operations ll_d_ops = { - d_revalidate2: ll_revalidate2, - d_intent_release: ll_intent_release + .d_revalidate2 = ll_revalidate2, + .d_intent_release = ll_intent_release, + .d_release = ll_release, };