📄 llite_lib.c
字号:
err = mdc_getstatus(sbi->ll_mdc_exp, &rootfid); if (err) { CERROR("cannot mds_connect: rc = %d\n", err); GOTO(out_lock_cn_cb, err); } CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id); sbi->ll_rootino = rootfid.id; sb->s_op = &lustre_super_operations;#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) sb->s_export_op = &lustre_export_operations;#endif /* make root inode * XXX: move this to after cbd setup? */ err = mdc_getattr(sbi->ll_mdc_exp, &rootfid, OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | (sbi->ll_flags & LL_SBI_ACL ? OBD_MD_FLACL : 0), 0, &request); if (err) { CERROR("mdc_getattr failed for root: rc = %d\n", err); GOTO(out_lock_cn_cb, err); } err = mdc_req2lustre_md(request, REPLY_REC_OFF, sbi->ll_osc_exp, &md); if (err) { CERROR("failed to understand root inode md: rc = %d\n",err); ptlrpc_req_finished (request); GOTO(out_lock_cn_cb, err); } LASSERT(sbi->ll_rootino != 0); root = ll_iget(sb, sbi->ll_rootino, &md); ptlrpc_req_finished(request); if (root == NULL || is_bad_inode(root)) { mdc_free_lustre_md(sbi->ll_osc_exp, &md); CERROR("lustre_lite: bad iget4 for root\n"); GOTO(out_root, err = -EBADF); } err = ll_close_thread_start(&sbi->ll_lcq); if (err) { CERROR("cannot start close thread: rc %d\n", err); GOTO(out_root, err); } checksum = sbi->ll_flags & LL_SBI_DATA_CHECKSUM; err = obd_set_info_async(sbi->ll_osc_exp, strlen("checksum"), "checksum", sizeof(checksum), &checksum, NULL); /* making vm readahead 0 for 2.4.x. In the case of 2.6.x, backing dev info assigned to inode mapping is used for determining maximal readahead. */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ !defined(KERNEL_HAS_AS_MAX_READAHEAD) /* bug 2805 - set VM readahead to zero */ vm_max_readahead = vm_min_readahead = 0;#endif sb->s_root = d_alloc_root(root); if (data != NULL) OBD_FREE(data, sizeof(*data)); sb->s_root->d_op = &ll_d_root_ops; RETURN(err);out_root: if (root) iput(root);out_lock_cn_cb: obd_unregister_lock_cancel_cb(sbi->ll_osc_exp, ll_extent_lock_cancel_cb);out_page_rm_cb: obd_unregister_page_removal_cb(sbi->ll_osc_exp, ll_page_removal_cb);out_osc: obd_disconnect(sbi->ll_osc_exp); sbi->ll_osc_exp = NULL;out_mdc: obd_disconnect(sbi->ll_mdc_exp); sbi->ll_mdc_exp = NULL;out: if (data != NULL) OBD_FREE(data, sizeof(*data)); lprocfs_unregister_mountpoint(sbi); RETURN(err);}int ll_get_max_mdsize(struct ll_sb_info *sbi, int *lmmsize){ int size, rc; *lmmsize = obd_size_diskmd(sbi->ll_osc_exp, NULL); size = sizeof(int); rc = obd_get_info(sbi->ll_mdc_exp, strlen("max_easize"), "max_easize", &size, lmmsize); if (rc) CERROR("Get max mdsize error rc %d \n", rc); RETURN(rc);}void ll_dump_inode(struct inode *inode){ struct list_head *tmp; int dentry_count = 0; LASSERT(inode != NULL); list_for_each(tmp, &inode->i_dentry) dentry_count++; CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n", inode, ll_i2mdcexp(inode)->exp_obd->obd_name, inode->i_ino, inode->i_mode, atomic_read(&inode->i_count), dentry_count);}void lustre_dump_dentry(struct dentry *dentry, int recur){ struct list_head *tmp; int subdirs = 0; LASSERT(dentry != NULL); list_for_each(tmp, &dentry->d_subdirs) subdirs++; CERROR("dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u," " flags=0x%x, fsdata=%p, %d subdirs\n", dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, dentry->d_parent, dentry->d_inode, atomic_read(&dentry->d_count), dentry->d_flags, dentry->d_fsdata, subdirs); if (dentry->d_inode != NULL) ll_dump_inode(dentry->d_inode); if (recur == 0) return; list_for_each(tmp, &dentry->d_subdirs) { struct dentry *d = list_entry(tmp, struct dentry, d_child); lustre_dump_dentry(d, recur - 1); }}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))void lustre_throw_orphan_dentries(struct super_block *sb){ struct dentry *dentry, *next; struct ll_sb_info *sbi = ll_s2sbi(sb); /* Do this to get rid of orphaned dentries. That is not really trw. */ list_for_each_entry_safe(dentry, next, &sbi->ll_orphan_dentry_list, d_hash) { CWARN("found orphan dentry %.*s (%p->%p) at unmount, dumping " "before and after shrink_dcache_parent\n", dentry->d_name.len, dentry->d_name.name, dentry, next); lustre_dump_dentry(dentry, 1); shrink_dcache_parent(dentry); lustre_dump_dentry(dentry, 1); }}#else#define lustre_throw_orphan_dentries(sb)#endif#ifdef HAVE_EXPORT___IGETstatic void prune_dir_dentries(struct inode *inode){ struct dentry *dentry, *prev = NULL; /* due to lustre specific logic, a directory * can have few dentries - a bug from VFS POV */restart: spin_lock(&dcache_lock); if (!list_empty(&inode->i_dentry)) { dentry = list_entry(inode->i_dentry.prev, struct dentry, d_alias); /* in order to prevent infinite loops we * break if previous dentry is busy */ if (dentry != prev) { prev = dentry; dget_locked(dentry); spin_unlock(&dcache_lock); /* try to kill all child dentries */ shrink_dcache_parent(dentry); dput(dentry); /* now try to get rid of current dentry */ d_prune_aliases(inode); goto restart; } } spin_unlock(&dcache_lock);}static void prune_deathrow_one(struct ll_inode_info *lli){ struct inode *inode = ll_info2i(lli); /* first, try to drop any dentries - they hold a ref on the inode */ if (S_ISDIR(inode->i_mode)) prune_dir_dentries(inode); else d_prune_aliases(inode); /* if somebody still uses it, leave it */ LASSERT(atomic_read(&inode->i_count) > 0); if (atomic_read(&inode->i_count) > 1) goto out; CDEBUG(D_INODE, "inode %lu/%u(%d) looks a good candidate for prune\n", inode->i_ino,inode->i_generation, atomic_read(&inode->i_count)); /* seems nobody uses it anymore */ inode->i_nlink = 0;out: iput(inode); return;}static void prune_deathrow(struct ll_sb_info *sbi, int try){ struct ll_inode_info *lli; int empty; do { if (need_resched() && try) break; if (try) { if (!spin_trylock(&sbi->ll_deathrow_lock)) break; } else { spin_lock(&sbi->ll_deathrow_lock); } empty = 1; lli = NULL; if (!list_empty(&sbi->ll_deathrow)) { lli = list_entry(sbi->ll_deathrow.next, struct ll_inode_info, lli_dead_list); list_del_init(&lli->lli_dead_list); if (!list_empty(&sbi->ll_deathrow)) empty = 0; } spin_unlock(&sbi->ll_deathrow_lock); if (lli) prune_deathrow_one(lli); } while (empty == 0);}#else /* !HAVE_EXPORT___IGET */#define prune_deathrow(sbi, try) do {} while (0)#endif /* HAVE_EXPORT___IGET */void client_common_put_super(struct super_block *sb){ struct ll_sb_info *sbi = ll_s2sbi(sb); ENTRY; ll_close_thread_shutdown(sbi->ll_lcq); lprocfs_unregister_mountpoint(sbi); /* destroy inodes in deathrow */ prune_deathrow(sbi, 0); list_del(&sbi->ll_conn_chain); /* callbacks is cleared after disconnect each target */ obd_disconnect(sbi->ll_osc_exp); sbi->ll_osc_exp = NULL; obd_disconnect(sbi->ll_mdc_exp); sbi->ll_mdc_exp = NULL; lustre_throw_orphan_dentries(sb); EXIT;}void ll_kill_super(struct super_block *sb){ struct ll_sb_info *sbi; ENTRY; /* not init sb ?*/ if (!(sb->s_flags & MS_ACTIVE)) return; sbi = ll_s2sbi(sb); /* we need restore s_dev from changed for clustred NFS before put_super * because new kernels have cached s_dev and change sb->s_dev in * put_super not affected real removing devices */ if (sbi) sb->s_dev = sbi->ll_sdev_orig; EXIT;}char *ll_read_opt(const char *opt, char *data){ char *value; char *retval; ENTRY; CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); if (strncmp(opt, data, strlen(opt))) RETURN(NULL); if ((value = strchr(data, '=')) == NULL) RETURN(NULL); value++; OBD_ALLOC(retval, strlen(value) + 1); if (!retval) { CERROR("out of memory!\n"); RETURN(NULL); } memcpy(retval, value, strlen(value)+1); CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); RETURN(retval);}static inline int ll_set_opt(const char *opt, char *data, int fl){ if (strncmp(opt, data, strlen(opt)) != 0) return(0); else return(fl);}/* non-client-specific mount options are parsed in lmd_parse */static int ll_options(char *options, int *flags){ int tmp; char *s1 = options, *s2; ENTRY; if (!options) RETURN(0); CDEBUG(D_CONFIG, "Parsing opts %s\n", options); while (*s1) { CDEBUG(D_SUPER, "next opt=%s\n", s1); tmp = ll_set_opt("nolock", s1, LL_SBI_NOLCK); if (tmp) { *flags |= tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -