STACK_WIND

STACK_WIND_COOKIE

在ec_open函数中,调用了STACK_WIND_COOKIE函数
作用:
	1、为ec xlator下层的vclnt xlator,新建一个frame
	2、给vclnt frame赋值(包括wind_from = ec_open、wind_to = vclnt_open、unwind_to = ec_open_cbk)
		  其中unwind_to用于vclnt_open_cbk调用完,调用UNWIND向上返回,继续调用ec_open_cbk
	3、向下层xlator继续下发open请求,即调用vclnt_open
STACK_WIND_COOKIE(frame, ec_open_cbk, (void *) (long) i,
               priv->child_xl_list[i],
               priv->child_xl_list[i]->fops->open,
               loc, wind_flags, fd, dict);
    
/* make a call with a cookie */
/*
**  frame       ec的frame
**  rfn         cbk函数 = ec_open_cbk
**  cky         cookie
**  obj         下次调用的xlator:priv->child_xl_list[i]
**  fn          下次调用的xlator:priv->child_xl_list[i]->fops->open = vclnt_open
**  params      loc, wind_flags, fd, dict
**
**  总体思想:
**     1、新建 frame(_new),给它赋值
**     2、调用 vclnt_open(_new, obj, params);
*/
#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params ...)         \
        do {                                                            \
                /* 创建新的frame */                                     \   
                call_frame_t *_new = NULL;                              \
                xlator_t     *old_THIS = NULL;                          \
                                                                        \
                /* 从内存池中获取call_frame_t */                        \   
                _new = call_frame_get (frame->root);                    \
                if (!_new) {                                            \
                        gf_log ("stack", GF_LOG_ERROR, "alloc failed"); \
                        break;                                          \
                }                                                       \
                /* _new的初始化 */                                      \
                typeof(fn##_cbk) tmp_cbk = rfn;                         \
                /* frame的root都是相同的 */                             \
                _new->root = frame->root;                               \
                /* 新的xlator的this指针指向obj,合情合理!*/            \
                _new->this = obj;                                       \
                /* [特殊]ret竟然存放的是cbk函数rfn */                   \
                _new->ret = (ret_fn_t) tmp_cbk;                         \
                /* _new的parent是当前的frame */                         \
                _new->parent = frame;                                   \
                _new->flag |= frame->flag;                              \
                /* cookie的作用?当UNWIND时,取出来用 */                \
                _new->cookie = cky;                                     \
                                                                        \
                /* ec_open */                                           \
                _new->wind_from = __FUNCTION__;                         \
                /* vclnt_open */                                        \
                _new->wind_to = #fn;                                    \
                /* ec_open_cbk */                                       \
                _new->unwind_to = #rfn;                                 \
                /* local_bak[?]:什么用? */                             \
                frame->local_bak = frame->local;                        \
                LOCK_INIT (&_new->lock);                                \
                LOCK(&frame->root->stack_lock);                         \
                {                                                       \
                        /* ec的frame引用计数加一 */                     \
                        frame->ref_count++;                             \
                        _new->next = frame->root->frames.next;          \
                        _new->prev = &frame->root->frames;              \
                        if (frame->root->frames.next)                   \
                                frame->root->frames.next->prev = _new;  \
                        frame->root->frames.next = _new;                \
                }                                                       \
                UNLOCK(&frame->root->stack_lock);                       \
                                                                        \
                /*  vclnt_open_cbk = ec

你可能感兴趣的:(Glusterfs)