⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namei.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * *  Copyright (c) 2002, 2003 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 <linux/fs.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/smp_lock.h>#include <linux/quotaops.h>#include <linux/highmem.h>#include <linux/pagemap.h>#define DEBUG_SUBSYSTEM S_LLITE#include <obd_support.h>#include <lustre_lite.h>#include <lustre_dlm.h>#include <linux/lustre_version.h>#include "llite_internal.h"/* methods *//* called from iget{4,5_locked}->find_inode() under inode_lock spinlock */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static int ll_test_inode(struct inode *inode, unsigned long ino, void *opaque)#elsestatic int ll_test_inode(struct inode *inode, void *opaque)#endif{        static int last_ino, last_gen, last_count;        struct lustre_md *md = opaque;        if (!(md->body->valid & (OBD_MD_FLGENER | OBD_MD_FLID))) {                CERROR("MDS body missing inum or generation\n");                return 0;        }        if (last_ino == md->body->ino && last_gen == md->body->generation &&            last_count < 500) {                last_count++;        } else {                if (last_count > 1)                        CDEBUG(D_VFSTRACE, "compared %u/%u %u times\n",                               last_ino, last_gen, last_count);                last_count = 0;                last_ino = md->body->ino;                last_gen = md->body->generation;                CDEBUG(D_VFSTRACE,                       "comparing inode %p ino %lu/%u to body "LPU64"/%u\n",                       inode, inode->i_ino, inode->i_generation,                       md->body->ino, md->body->generation);        }#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))        if (inode->i_ino != md->body->ino)                return 0;#endif        if (inode->i_generation != md->body->generation) {#ifdef HAVE_EXPORT___IGET                if (inode->i_state & (I_FREEING | I_CLEAR))                        return 0;                if (inode->i_nlink == 0)                        return 0;                /* add "duplicate" inode into deathrow for destroy */                spin_lock(&ll_i2sbi(inode)->ll_deathrow_lock);                if (list_empty(&ll_i2info(inode)->lli_dead_list)) {                        __iget(inode);                        list_add(&ll_i2info(inode)->lli_dead_list,                                 &ll_i2sbi(inode)->ll_deathrow);                }                spin_unlock(&ll_i2sbi(inode)->ll_deathrow_lock);#endif                return 0;        }        /* Apply the attributes in 'opaque' to this inode */        if (!(inode->i_state & (I_FREEING | I_CLEAR)))                ll_update_inode(inode, md);        return 1;}int ll_unlock(__u32 mode, struct lustre_handle *lockh){        ENTRY;        ldlm_lock_decref(lockh, mode);        RETURN(0);}/* Get an inode by inode number (already instantiated by the intent lookup). * Returns inode or NULL */#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))int ll_set_inode(struct inode *inode, void *opaque){        ll_read_inode2(inode, opaque);        return 0;}struct inode *ll_iget(struct super_block *sb, ino_t hash,                      struct lustre_md *md){        struct inode *inode;        LASSERT(hash != 0);        inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);        if (inode) {                if (inode->i_state & I_NEW)                        unlock_new_inode(inode);                CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,                       inode->i_generation, inode);        }        return inode;}#elsestruct inode *ll_iget(struct super_block *sb, ino_t hash,                      struct lustre_md *md){        struct inode *inode;        LASSERT(hash != 0);        inode = iget4(sb, hash, ll_test_inode, md);        if (inode)                CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,                       inode->i_generation, inode);        return inode;}#endifstatic void ll_drop_negative_dentry(struct inode *dir){         struct dentry *dentry, *tmp_alias, *tmp_subdir;        spin_lock(&dcache_lock);restart:        list_for_each_entry_safe(dentry, tmp_alias,                                 &dir->i_dentry,d_alias) {                if (!list_empty(&dentry->d_subdirs)) {                        struct dentry *child;                        list_for_each_entry_safe(child, tmp_subdir,                                                 &dentry->d_subdirs,                                                 d_child) {                                /* XXX Print some debug here? */                                if (!child->d_inode)                                /* Negative dentry. If we were                                   dropping dcache lock, go                                   throught the list again */                                        if (ll_drop_dentry(child))                                                goto restart;                        }                }        }        spin_unlock(&dcache_lock);}int ll_mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,                        void *data, int flag){        int rc;        struct lustre_handle lockh;        ENTRY;        switch (flag) {        case LDLM_CB_BLOCKING:                ldlm_lock2handle(lock, &lockh);                rc = ldlm_cli_cancel(&lockh);                if (rc < 0) {                        CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc);                        RETURN(rc);                }                break;        case LDLM_CB_CANCELING: {                struct inode *inode = ll_inode_from_lock(lock);                __u64 bits = lock->l_policy_data.l_inodebits.bits;                /* Invalidate all dentries associated with this inode */                if (inode == NULL)                        break;                LASSERT(lock->l_flags & LDLM_FL_CANCELING);                if ((bits & MDS_INODELOCK_LOOKUP) &&                    ll_have_md_lock(inode, MDS_INODELOCK_LOOKUP))                        bits &= ~MDS_INODELOCK_LOOKUP;                if ((bits & MDS_INODELOCK_UPDATE) &&                    ll_have_md_lock(inode, MDS_INODELOCK_UPDATE))                        bits &= ~MDS_INODELOCK_UPDATE;                if ((bits & MDS_INODELOCK_OPEN) &&                    ll_have_md_lock(inode, MDS_INODELOCK_OPEN))                        bits &= ~MDS_INODELOCK_OPEN;                                if (lock->l_resource->lr_name.name[0] != inode->i_ino ||                    lock->l_resource->lr_name.name[1] != inode->i_generation) {                        LDLM_ERROR(lock, "data mismatch with ino %lu/%u (%p)",                                   inode->i_ino, inode->i_generation, inode);                }                if (bits & MDS_INODELOCK_OPEN) {                        int flags = 0;                        switch (lock->l_req_mode) {                        case LCK_CW:                                flags = FMODE_WRITE;                                break;                        case LCK_PR:                                flags = FMODE_EXEC;                                if (!FMODE_EXEC)                                        CERROR("open PR lock without FMODE_EXEC\n");                                break;                        case LCK_CR:                                flags = FMODE_READ;                                break;                        default:                                CERROR("Unexpected lock mode for OPEN lock "                                       "%d, inode %ld\n", lock->l_req_mode,                                       inode->i_ino);                        }                        ll_mdc_real_close(inode, flags);                }                if (bits & MDS_INODELOCK_UPDATE)                        clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK,                                  &(ll_i2info(inode)->lli_flags));                if (S_ISDIR(inode->i_mode) &&                     (bits & MDS_INODELOCK_UPDATE)) {                        CDEBUG(D_INODE, "invalidating inode %lu\n",                               inode->i_ino);                        truncate_inode_pages(inode->i_mapping, 0);                        ll_drop_negative_dentry(inode);                        inode->i_version++; /* XXX: remove with inode version*/                }                if (inode->i_sb->s_root &&                    inode != inode->i_sb->s_root->d_inode &&                    (bits & MDS_INODELOCK_LOOKUP))                        ll_unhash_aliases(inode);                iput(inode);                break;        }        default:                LBUG();        }        RETURN(0);}int ll_mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode,                         int flags, void *opaque){        struct ldlm_res_id res_id =                { .name = {inode->i_ino, inode->i_generation} };        struct obd_device *obddev = class_conn2obd(conn);        ENTRY;        RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, &res_id, flags,                                      opaque));}/* Pack the required supplementary groups into the supplied groups array. * If we don't need to use the groups from the target inode(s) then we * instead pack one or more groups from the user's supplementary group * array in case it might be useful.  Not needed if doing an MDS-side upcall. */void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2){        int i;        LASSERT(i1 != NULL);        LASSERT(suppgids != NULL);        if (in_group_p(i1->i_gid))                suppgids[0] = i1->i_gid;        else                suppgids[0] = -1;        if (i2) {                if (in_group_p(i2->i_gid))                        suppgids[1] = i2->i_gid;                else                        suppgids[1] = -1;        } else {                suppgids[1] = -1;        }        for (i = 0; i < current_ngroups; i++) {                if (suppgids[0] == -1) {                        if (current_groups[i] != suppgids[1])                                suppgids[0] = current_groups[i];                        continue;                }                if (suppgids[1] == -1) {                        if (current_groups[i] != suppgids[0])                                suppgids[1] = current_groups[i];                        continue;                }                break;        }}int ll_prepare_mdc_op_data(struct mdc_op_data *op_data, struct inode *i1,                            struct inode *i2, const char *name, int namelen,                            int mode, void *data){        LASSERT(i1);        if (namelen > ll_i2sbi(i1)->ll_namelen)                return -ENAMETOOLONG;        ll_i2gids(op_data->suppgids, i1, i2);        ll_inode2fid(&op_data->fid1, i1);        if (i2)                ll_inode2fid(&op_data->fid2, i2);        else                memset(&op_data->fid2, 0, sizeof(op_data->fid2));        op_data->name = name;        op_data->namelen = namelen;        op_data->create_mode = mode;        op_data->mod_time = CURRENT_SECONDS;        op_data->data = data;        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -