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

📄 namei.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 4 页
字号:
                        it = ll_convert_intent(&nd->intent.open, nd->flags);                        if (IS_ERR(it))                                RETURN((struct dentry *)it);                }                de = ll_lookup_it(parent, dentry, it, nd->flags);                if (de)                        dentry = de;                if ((nd->flags & LOOKUP_OPEN) && !IS_ERR(dentry)) { /* Open */                        if (dentry->d_inode &&                            it_disposition(it, DISP_OPEN_OPEN)) { /* nocreate */#ifdef HAVE_FILE_IN_STRUCT_INTENT                                if (S_ISFIFO(dentry->d_inode->i_mode)) {                                        // We cannot call open here as it would                                        // deadlock.                                        ptlrpc_req_finished(                                                       (struct ptlrpc_request *)                                                          it->d.lustre.it_data);                                } else {                                        struct file *filp;                                        nd->intent.open.file->private_data = it;                                        filp =lookup_instantiate_filp(nd,dentry,                                                                      NULL);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))/* 2.6.1[456] have a bug in open_namei() that forgets to check * nd->intent.open.file for error, so we need to return it as lookup's result * instead */                                        if (IS_ERR(filp)) {                                                if (de)                                                        dput(de);                                                de = (struct dentry *) filp;                                        }#endif                                }#else /* HAVE_FILE_IN_STRUCT_INTENT */                                /* Release open handle as we have no way to                                 * pass it to ll_file_open */                                ll_release_openhandle(dentry, it);#endif /* HAVE_FILE_IN_STRUCT_INTENT */                        } else if (it_disposition(it, DISP_OPEN_CREATE)) {                                // XXX This can only reliably work on assumption                                // that there are NO hashed negative dentries.                                ll_d2d(dentry)->lld_it = it;                                it = NULL; /* Will be freed in ll_create_nd */                                /* We absolutely depend on ll_create_nd to be                                 * called to not leak this intent and possible                                 * data attached to it */                        }                }                if (it) {                        ll_intent_release(it);                        OBD_FREE(it, sizeof(*it));                }        } else {                de = ll_lookup_it(parent, dentry, NULL, 0);        }        RETURN(de);}#endif#endif/* We depend on "mode" being set with the proper file type/umask by now */static struct inode *ll_create_node(struct inode *dir, const char *name,                                    int namelen, const void *data, int datalen,                                    int mode, __u64 extra,                                    struct lookup_intent *it){        struct inode *inode = NULL;        struct ptlrpc_request *request = NULL;        struct ll_sb_info *sbi = ll_i2sbi(dir);        int rc;        ENTRY;        LASSERT(it && it->d.lustre.it_disposition);        LASSERT(it_disposition(it, DISP_ENQ_CREATE_REF));        request = it->d.lustre.it_data;        it_clear_disposition(it, DISP_ENQ_CREATE_REF);        rc = ll_prep_inode(sbi->ll_osc_exp, &inode, request, DLM_REPLY_REC_OFF,                           dir->i_sb);        if (rc)                GOTO(out, inode = ERR_PTR(rc));        LASSERT(list_empty(&inode->i_dentry));        /* We asked for a lock on the directory, but were granted a         * lock on the inode.  Since we finally have an inode pointer,         * stuff it in the lock. */        CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",               inode, inode->i_ino, inode->i_generation);        mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);        EXIT; out:        ptlrpc_req_finished(request);        return inode;}/* * By the time this is called, we already have created the directory cache * entry for the new file, but it is so far negative - it has no inode. * * We defer creating the OBD object(s) until open, to keep the intent and * non-intent code paths similar, and also because we do not have the MDS * inode number before calling ll_create_node() (which is needed for LOV), * so we would need to do yet another RPC to the MDS to store the LOV EA * data on the MDS.  If needed, we would pass the PACKED lmm as data and * lmm_size in datalen (the MDS still has code which will handle that). * * If the create succeeds, we fill in the inode information * with d_instantiate(). */static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,                        struct lookup_intent *it){        struct inode *inode;        struct ptlrpc_request *request = it->d.lustre.it_data;        int rc = 0;        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n",               dentry->d_name.len, dentry->d_name.name, dir->i_ino,               dir->i_generation, dir, LL_IT2STR(it));        rc = it_open_error(DISP_OPEN_CREATE, it);        if (rc)                RETURN(rc);        mdc_store_inode_generation(request, DLM_INTENT_REC_OFF,                                   DLM_REPLY_REC_OFF);        inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,                               NULL, 0, mode, 0, it);        if (IS_ERR(inode)) {                RETURN(PTR_ERR(inode));        }        d_instantiate(dentry, inode);        /* Negative dentry may be unhashed if parent does not have UPDATE lock,         * but some callers, e.g. do_coredump, expect dentry to be hashed after         * successful create. Hash it here. */        spin_lock(&dcache_lock);        if (d_unhashed(dentry))                d_rehash_cond(dentry, 0);        spin_unlock(&dcache_lock);        RETURN(0);}static void ll_update_times(struct ptlrpc_request *request, int offset,                            struct inode *inode){        struct mds_body *body = lustre_msg_buf(request->rq_repmsg, offset,                                               sizeof(*body));        LASSERT(body);        /* mtime is always updated with ctime, but can be set in past.           As write and utime(2) may happen within 1 second, and utime's           mtime has a priority over write's one, so take mtime from mds           for the same ctimes. */        if (body->valid & OBD_MD_FLCTIME &&            body->ctime >= LTIME_S(inode->i_ctime)) {                LTIME_S(inode->i_ctime) = body->ctime;                if (body->valid & OBD_MD_FLMTIME) {                        CDEBUG(D_INODE, "setting ino %lu mtime from %lu "                               "to "LPU64"\n", inode->i_ino,                               LTIME_S(inode->i_mtime), body->mtime);                        LTIME_S(inode->i_mtime) = body->mtime;                }        }}static int ll_new_node(struct inode *dir, struct qstr *name,                       const char *tgt, int mode,                       int rdev, struct dentry *dchild){        struct ptlrpc_request *request = NULL;        struct inode *inode = NULL;        struct ll_sb_info *sbi = ll_i2sbi(dir);        struct mdc_op_data op_data;        int tgt_len = 0;        int err;        ENTRY;        if (unlikely(tgt != NULL))                tgt_len = strlen(tgt)+1;        err = ll_prepare_mdc_op_data(&op_data, dir, NULL, name->name,                                     name->len, 0, NULL);        if (err)                GOTO(err_exit, err);        err = mdc_create(sbi->ll_mdc_exp, &op_data, tgt, tgt_len,                         mode, current->fsuid, current->fsgid,                         current->cap_effective, rdev, &request);        if (err)                GOTO(err_exit, err);        ll_update_times(request, REPLY_REC_OFF, dir);        if (dchild) {                err = ll_prep_inode(sbi->ll_osc_exp, &inode, request,                                    REPLY_REC_OFF, dchild->d_sb);                if (err)                     GOTO(err_exit, err);                d_drop(dchild);                d_instantiate(dchild, inode);                EXIT;        }err_exit:        ptlrpc_req_finished(request);        return err;}static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode,                            unsigned rdev, struct dentry *dchild){        int err;        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p) mode %o dev %x\n",               name->len, name->name, dir->i_ino, dir->i_generation, dir,               mode, rdev);        mode &= ~current->fs->umask;        switch (mode & S_IFMT) {        case 0:                mode |= S_IFREG; /* for mode = 0 case, fallthrough */        case S_IFREG:        case S_IFCHR:        case S_IFBLK:        case S_IFIFO:        case S_IFSOCK:                err = ll_new_node(dir, name, NULL, mode, rdev, dchild);                break;        case S_IFDIR:                err = -EPERM;                break;        default:                err = -EINVAL;        }        RETURN(err);}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))#ifndef HAVE_VFS_INTENT_PATCHESstatic int ll_create_nd(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd){        struct lookup_intent *it = ll_d2d(dentry)->lld_it;        int rc;        if (!it)                return ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry);        ll_d2d(dentry)->lld_it = NULL;        /* Was there an error? Propagate it! */        if (it->d.lustre.it_status) {                rc = it->d.lustre.it_status;                goto out;        }        rc = ll_create_it(dir, dentry, mode, it);#ifdef HAVE_FILE_IN_STRUCT_INTENT        if (nd && (nd->flags & LOOKUP_OPEN) && dentry->d_inode) { /* Open */                nd->intent.open.file->private_data = it;                lookup_instantiate_filp(nd, dentry, NULL);        }#else        ll_release_openhandle(dentry,it);#endifout:        ll_intent_release(it);        OBD_FREE(it, sizeof(*it));        return rc;}#elsestatic int ll_create_nd(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd){        if (!nd || !nd->intent.d.lustre.it_disposition)                /* No saved request? Just mknod the file */                return ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry);        return ll_create_it(dir, dentry, mode, &nd->intent);}#endif#endifstatic int ll_symlink_generic(struct inode *dir, struct qstr *name,                              const char *tgt, struct dentry *dchild){        int err;        ENTRY;        CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),target=%.*s\n",               name->len, name->name, dir->i_ino, dir->i_generation,               dir, 3000, tgt);        err = ll_new_node(dir, name, (char *)tgt, S_IFLNK | S_IRWXUGO,                          0, dchild);        RETURN(err);}static int ll_link_generic(struct inode *src,  struct inode *dir,                           struct qstr *name, struct dentry *dchild){        struct ptlrpc_request *request = NULL;        struct mdc_op_data op_data;        int err;        struct ll_sb_info *sbi = ll_i2sbi(dir);        ENTRY;        CDEBUG(D_VFSTRACE,               "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%.*s\n",               src->i_ino, src->i_generation, src, dir->i_ino,               dir->i_generation, dir, name->len, name->name);        err = ll_prepare_mdc_op_data(&op_data, src, dir, name->name,                                     name->len, 0, NULL);        if (err)                GOTO(out, err);        err = mdc_link(sbi->ll_mdc_exp, &op_data, &request);        if (err)               GOTO(out, err);        if (dchild) {                d_drop(dchild);        }        ll_update_times(request, REPLY_REC_OFF, dir);        EXIT;out:        ptlrpc_req_finished(request);        RETURN(err);}

⌨️ 快捷键说明

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