📄 namei.c
字号:
static int ll_mkdir_generic(struct inode *dir, struct qstr *name, int mode, struct dentry *dchild){ int err; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", name->len, name->name, dir->i_ino, dir->i_generation, dir); mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR; err = ll_new_node(dir, name, NULL, mode, 0, dchild); RETURN(err);}/* Try to find the child dentry by its name. If found, put the result fid into @fid. */static void ll_get_child_fid(struct inode * dir, struct qstr *name, struct ll_fid *fid){ struct dentry *parent, *child; parent = list_entry(dir->i_dentry.next, struct dentry, d_alias); child = d_lookup(parent, name); if (child) { if (child->d_inode) ll_inode2fid(fid, child->d_inode); dput(child); }}static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent, struct qstr *name){ struct ptlrpc_request *request = NULL; struct mdc_op_data op_data = {{0}}; struct dentry *dentry; int rc; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", name->len, name->name, dir->i_ino, dir->i_generation, dir); /* Check if we have something mounted at the dir we are going to delete * In such a case there would always be dentry present. */ if (dparent) { dentry = d_lookup(dparent, name); if (dentry) { int mounted = d_mountpoint(dentry); dput(dentry); if (mounted) GOTO(out, rc = -EBUSY); } } rc = ll_prepare_mdc_op_data(&op_data, dir, NULL, name->name, name->len, S_IFDIR, NULL); if (rc) GOTO(out, rc); ll_get_child_fid(dir, name, &op_data.fid3); rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request); if (rc) GOTO(out, rc); ll_update_times(request, REPLY_REC_OFF, dir); EXIT;out: ptlrpc_req_finished(request); return(rc);}int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir){ struct mds_body *body; struct lov_mds_md *eadata; struct lov_stripe_md *lsm = NULL; struct obd_trans_info oti = { 0 }; struct obdo *oa; int rc; ENTRY; /* req is swabbed so this is safe */ body = lustre_msg_buf(request->rq_repmsg, REPLY_REC_OFF, sizeof(*body)); if (!(body->valid & OBD_MD_FLEASIZE)) RETURN(0); if (body->eadatasize == 0) { CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n"); GOTO(out, rc = -EPROTO); } /* The MDS sent back the EA because we unlinked the last reference * to this file. Use this EA to unlink the objects on the OST. * It's opaque so we don't swab here; we leave it to obd_unpackmd() to * check it is complete and sensible. */ eadata = lustre_swab_repbuf(request, REPLY_REC_OFF + 1, body->eadatasize, NULL); LASSERT(eadata != NULL); if (eadata == NULL) { CERROR("Can't unpack MDS EA data\n"); GOTO(out, rc = -EPROTO); } rc = obd_unpackmd(ll_i2obdexp(dir), &lsm, eadata, body->eadatasize); if (rc < 0) { CERROR("obd_unpackmd: %d\n", rc); GOTO(out, rc); } LASSERT(rc >= sizeof(*lsm)); rc = obd_checkmd(ll_i2obdexp(dir), ll_i2mdcexp(dir), lsm); if (rc) GOTO(out_free_memmd, rc); OBDO_ALLOC(oa); if (oa == NULL) GOTO(out_free_memmd, rc = -ENOMEM); oa->o_id = lsm->lsm_object_id; oa->o_mode = body->mode & S_IFMT; oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE; if (body->valid & OBD_MD_FLCOOKIE) { oa->o_valid |= OBD_MD_FLCOOKIE; oti.oti_logcookies = lustre_msg_buf(request->rq_repmsg, REPLY_REC_OFF + 2, sizeof(struct llog_cookie) * lsm->lsm_stripe_count); if (oti.oti_logcookies == NULL) { oa->o_valid &= ~OBD_MD_FLCOOKIE; body->valid &= ~OBD_MD_FLCOOKIE; } } rc = obd_destroy(ll_i2obdexp(dir), oa, lsm, &oti, ll_i2mdcexp(dir)); OBDO_FREE(oa); if (rc) CERROR("obd destroy objid "LPX64" error %d\n", lsm->lsm_object_id, rc); out_free_memmd: obd_free_memmd(ll_i2obdexp(dir), &lsm); out: return rc;}static int ll_unlink_generic(struct inode * dir, struct qstr *name){ struct ptlrpc_request *request = NULL; struct mdc_op_data op_data = {{0}}; int rc; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", name->len, name->name, dir->i_ino, dir->i_generation, dir); rc = ll_prepare_mdc_op_data(&op_data, dir, NULL, name->name, name->len, 0, NULL); if (rc) GOTO(out, rc); ll_get_child_fid(dir, name, &op_data.fid3); rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request); if (rc) GOTO(out, rc); ll_update_times(request, REPLY_REC_OFF, dir); rc = ll_objects_destroy(request, dir); if (rc) GOTO(out, rc); EXIT; out: ptlrpc_req_finished(request); return(rc);}static int ll_rename_generic(struct inode *src, struct qstr *src_name, struct inode *tgt, struct qstr *tgt_name){ struct ptlrpc_request *request = NULL; struct ll_sb_info *sbi = ll_i2sbi(src); struct mdc_op_data op_data = {{0}}; int err; ENTRY; CDEBUG(D_VFSTRACE,"VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s," "tgt_dir=%lu/%u(%p)\n", src_name->len, src_name->name, src->i_ino, src->i_generation, src, tgt_name->len, tgt_name->name, tgt->i_ino, tgt->i_generation, tgt); err = ll_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0, NULL); if (err) GOTO(out, err); ll_get_child_fid(src, src_name, &op_data.fid3); ll_get_child_fid(tgt, tgt_name, &op_data.fid4); err = mdc_rename(sbi->ll_mdc_exp, &op_data, src_name->name, src_name->len, tgt_name->name, tgt_name->len, &request); if (err) GOTO(out, err); ll_update_times(request, REPLY_REC_OFF, src); ll_update_times(request, REPLY_REC_OFF, tgt); err = ll_objects_destroy(request, src); if (err) GOTO(out, err); EXIT;out: ptlrpc_req_finished(request); return(err);}#ifdef HAVE_VFS_INTENT_PATCHESstatic int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev){ return ll_mknod_generic(nd->dentry->d_inode, &nd->last, mode,rdev,NULL);}static int ll_rename_raw(struct nameidata *srcnd, struct nameidata *tgtnd){ return ll_rename_generic(srcnd->dentry->d_inode, &srcnd->last, tgtnd->dentry->d_inode, &tgtnd->last);}static int ll_link_raw(struct nameidata *srcnd, struct nameidata *tgtnd){ return ll_link_generic(srcnd->dentry->d_inode, tgtnd->dentry->d_inode, &tgtnd->last, NULL);}static int ll_symlink_raw(struct nameidata *nd, const char *tgt){ return ll_symlink_generic(nd->dentry->d_inode, &nd->last, tgt, NULL);}static int ll_rmdir_raw(struct nameidata *nd){ return ll_rmdir_generic(nd->dentry->d_inode, nd->dentry, &nd->last);}static int ll_mkdir_raw(struct nameidata *nd, int mode){ return ll_mkdir_generic(nd->dentry->d_inode, &nd->last, mode, NULL);}static int ll_unlink_raw(struct nameidata *nd){ return ll_unlink_generic(nd->dentry->d_inode, &nd->last);}#endifstatic int ll_mknod(struct inode *dir, struct dentry *dchild, int mode, ll_dev_t rdev){ return ll_mknod_generic(dir, &dchild->d_name, mode, old_encode_dev(rdev), dchild);}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))static int ll_unlink(struct inode * dir, struct dentry *dentry){ return ll_unlink_generic(dir, &dentry->d_name);}static int ll_mkdir(struct inode *dir, struct dentry *dentry, int mode){ return ll_mkdir_generic(dir, &dentry->d_name, mode, dentry);}static int ll_rmdir(struct inode *dir, struct dentry *dentry){ return ll_rmdir_generic(dir, NULL, &dentry->d_name);}static int ll_symlink(struct inode *dir, struct dentry *dentry, const char *oldname){ return ll_symlink_generic(dir, &dentry->d_name, oldname, dentry);}static int ll_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry){ return ll_link_generic(old_dentry->d_inode, dir, &new_dentry->d_name, new_dentry);}static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry){ return ll_rename_generic(old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name);}#endifstruct inode_operations ll_dir_inode_operations = {#ifdef HAVE_VFS_INTENT_PATCHES .link_raw = ll_link_raw, .unlink_raw = ll_unlink_raw, .symlink_raw = ll_symlink_raw, .mkdir_raw = ll_mkdir_raw, .rmdir_raw = ll_rmdir_raw, .mknod_raw = ll_mknod_raw, .rename_raw = ll_rename_raw, .setattr = ll_setattr, .setattr_raw = ll_setattr_raw,#endif .mknod = ll_mknod,#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) .create_it = ll_create_it, .lookup_it = ll_lookup_it, .revalidate_it = ll_inode_revalidate_it,#else .lookup = ll_lookup_nd, .create = ll_create_nd, /* We need all these non-raw things for NFSD, to not patch it. */ .unlink = ll_unlink, .mkdir = ll_mkdir, .rmdir = ll_rmdir, .symlink = ll_symlink, .link = ll_link, .rename = ll_rename, .setattr = ll_setattr, .getattr = ll_getattr,#endif .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, .removexattr = ll_removexattr,};struct inode_operations ll_special_inode_operations = {#ifdef HAVE_VFS_INTENT_PATCHES .setattr_raw = ll_setattr_raw,#endif .setattr = ll_setattr,#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) .getattr = ll_getattr,#else .revalidate_it = ll_inode_revalidate_it,#endif .permission = ll_inode_permission, .setxattr = ll_setxattr, .getxattr = ll_getxattr, .listxattr = ll_listxattr, .removexattr = ll_removexattr,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -