Hello I have started the process of learning the new OSD design and have a few questions after reading the osd-api document as well as the code. The questions center around the OSD Objects which is described by struct lu_object. Now each object is described as being represented by a header (lu_header) and slices. Also the code refers to the concept of compound objects. Now if I''m understanding this correctly then a perfect example of a compound object is struct lovsub_object which is a super class of lu_object composed of two other classes. Now in this exmaple class lso_cl would be considered one of the allocated slices in the lu_object stack. Same for lso_super. Then for lov_object lo_cl would be a slice etc until we hit the bottom of the stack at the base class lu_object. struct lovsub_object { ... struct cl_object lso_cl; struct lov_object *lso_super; ... } struct lov_object { struct cl_object lo_cl; ... strict cl_object { struct lu_object co_lu; .. } struct lu_object { struct lu_header lo_header; ... } Now let see if I''m interrupting this correctly. I noticed many of the zzz_object_init functions for lu_object_operations have a format similar to : static int zzz_object_init(const struct lu_env *env, struct lu_object *o, const struct lu_object_conf *conf) { struct zzz_device *d = lu2zzz_dev(o->lo_dev); struct lu_device *under; struct lu_object *below; int rc = 0; ENTRY; under = &d->yyy->dd_lu_dev; below = under->ld_ops->ldo_object_alloc(env, o->lo_header, under); if (below != NULL) lu_object_add(o, below); else rc = -ENOMEM; return 0; } This is not allocation the zzz_object type that would be allocated by zzz_object_alloc but is instead a lower level lu_object type object. Would it always one one slice lower or the lowest level i.e lu_object itself? Then it forms a compound object with lu_object_add. That is the easy part. The part I had a hard time making out was the lu_object_alloc() function in lu_object.c. You appear to allocate a top level lu_object with the low level ldo_object_alloc hook but its a freshly created object so I assume because you did add the top object to its own list, loh_layer, that the loop you do only contains one object but you loop as if alot of lu_objects will be in the loh_layers list with some even allocated. Where is that list being set from so the properly related objects are initialized? Which objects are being initialized? The one''s higher in the slice?
Hello I have started the process of learning the new OSD design and have a few questions after reading the osd-api document as well as the code. The questions center around the OSD Objects which is described by struct lu_object. Now each object is described as being represented by a header (lu_header) and slices. Also the code refers to the concept of compound objects. Now if I''m understanding this correctly then a perfect example of a compound object is struct lovsub_object which is a super class of lu_object composed of two other classes. Now in this exmaple class lso_cl would be considered one of the allocated slices in the lu_object stack. Same for lso_super. Then for lov_object lo_cl would be a slice etc until we hit the bottom of the stack at the base class lu_object. struct lovsub_object { ... struct cl_object lso_cl; struct lov_object *lso_super; ... } struct lov_object { struct cl_object lo_cl; ... strict cl_object { struct lu_object co_lu; .. } struct lu_object { struct lu_header lo_header; ... } Now let see if I''m interrupting this correctly. I noticed many of the zzz_object_init functions for lu_object_operations have a format similar to : static int zzz_object_init(const struct lu_env *env, struct lu_object *o, const struct lu_object_conf *conf) { struct zzz_device *d = lu2zzz_dev(o->lo_dev); struct lu_device *under; struct lu_object *below; int rc = 0; ENTRY; under = &d->yyy->dd_lu_dev; below = under->ld_ops->ldo_object_alloc(env, o->lo_header, under); if (below != NULL) lu_object_add(o, below); else rc = -ENOMEM; return 0; } This is not allocation the zzz_object type that would be allocated by zzz_object_alloc but is instead a lower level lu_object type object. Would it always one one slice lower or the lowest level i.e lu_object itself? Then it forms a compound object with lu_object_add. That is the easy part. The part I had a hard time making out was the lu_object_alloc() function in lu_object.c. You appear to allocate a top level lu_object with the low level ldo_object_alloc hook but its a freshly created object so I assume because you did add the top object to its own list, loh_layer, that the loop you do only contains one object but you loop as if alot of lu_objects will be in the loh_layers list with some even allocated. Where is that list being set from so the properly related objects are initialized? Which objects are being initialized? The one''s higher in the slice?
My understanding is that when we allocate top slice object by calling lu_object_alloc(), first it calls its corresponding device''s ldo_object_alloc() to create the top slice object, then it go into following code do { /* * Call ->loo_object_init() repeatedly, until no more new * object slices are created. */ clean = 1; cfs_list_for_each_entry(scan, layers, lo_linkage) { if (scan->lo_flags & LU_OBJECT_ALLOCATED) continue; clean = 0; scan->lo_header = top->lo_header; result = scan->lo_ops->loo_object_init(env, scan, conf); if (result != 0) { lu_object_free(env, top); RETURN(ERR_PTR(result)); } scan->lo_flags |= LU_OBJECT_ALLOCATED; } } while (!clean); In the first round, the layers list only contains the upper slice it self (scan be the top object), scan->lo_ops->loo_object_init() will go into the <top>_object_init() as you described earlier, it allocate lower slice object and add it into the layers list (by calling lu_object_add()), and scan->lo_flags is set to indicate that the top object has been allocated, this time clean is 0, we will go into the 2nd round of do_while loop. In the 2nd round, layers list contains top object(flags is set as allocated) and 2nd slice object (flags hasn''t be set allocated), clean <- 0 and scan <- 2nd_slice_obj, its loo_object_init() will alloc possible 3rd slice obj, and continue the loop. If there''s no 3rd slice, 2nd_obj->loo_object_init() will just initialise 2nd object itself and not 3rd object be allocated and linked into the layers list (as osc_object_init() shows), and 2nd_obj''s flag set to be allocated. And the loop will bail out. -- Best regards, Bobi Jam bobijam at whamcloud.com On Oct 19, 2012, at 3:15 AM, James A Simmons <uja at ornl.gov> wrote:> The part I had a hard time making out was the > lu_object_alloc() function in lu_object.c. You appear to allocate a > top level lu_object with the low level ldo_object_alloc hook but its a > freshly created object so I assume because you did add the top object to > its own list, loh_layer, that the loop you do only contains one object > but you loop as if alot of lu_objects will be in the loh_layers list > with some even allocated. Where is that list being set from so the > properly related objects are initialized? Which objects are being > initialized? The one''s higher in the slice?
On Thu, Oct 18, 2012 at 11:15 PM, James A Simmons <uja at ornl.gov> wrote:> This is not allocation the zzz_object type that would be allocated by > zzz_object_alloc but is instead a lower level lu_object type object. > Would it always one one slice lower or the lowest level i.e lu_object > itself? Then it forms a compound object with lu_object_add.In this specific case it''s not an object being allocated, it''s a slice - representation of a specific layer in this object.> That is the easy part. The part I had a hard time making out was the > lu_object_alloc() function in lu_object.c. You appear to allocate a > top level lu_object with the low level ldo_object_alloc hook but its a > freshly created object so I assume because you did add the top object to > its own list, loh_layer, that the loop you do only contains one object > but you loop as if alot of lu_objects will be in the loh_layers list > with some even allocated. Where is that list being set from so the > properly related objects are initialized? Which objects are being > initialized? The one''s higher in the slice?every layer in the stack is represented by a specific device. and that device is supposed to export ->ldo_object_alloc() method to allocate a slice of an object (see above). then in the loop we basically find not-initialized-yet slices (!(scan->lo_flags & LU_OBJECT_ALLOCATED)) and call ->loo_object_init() to initialize the slice. that method in turn is supposed to find layer below and call appropriate method to allocate a slice below. AFAIU, the reason it''s done this way is to avoid recursion and make 4K-stack kernels happy. probably Jinshan Xiong can help with a good example from CLIO. thanks, Alex
On 2012-10-18, at 13:11, James A Simmons <uja at ornl.gov> wrote:> > I have started the process of learning the new OSD design and > have a > few questions after reading the osd-api document as well as the code.James, I''d encourage you to collect your notes and update any gaps in the OSD API doc as much as you can. Often, since the people writing the doc are the experts, they don''t see where there are gaps in the explanations. Please note that the doc was originally focussed on the sever stack, in order to allow someone to write a new OSD driver, so the client IO usage and implementation that you discuss below is not necessarily covered. There were also notes from Nikita about CLIO that could also be updated and included into this docs directory. Cheers, Andreas> The questions center around the OSD Objects which is described by > struct lu_object. Now each object is described as being represented by a > header (lu_header) and slices. Also the code refers to the concept of > compound objects. Now if I''m understanding this correctly then a perfect > example of a compound object is struct lovsub_object which is a super > class of lu_object composed of two other classes. Now in this exmaple > class lso_cl would be considered one of the allocated slices in the > lu_object stack. Same for lso_super. Then for lov_object lo_cl would be > a slice etc until we hit the bottom of the stack at the base class > lu_object. > > struct lovsub_object { > ... > struct cl_object lso_cl; > struct lov_object *lso_super; > ... > } > > struct lov_object { > struct cl_object lo_cl; > ... > > > strict cl_object { > struct lu_object co_lu; > .. > } > > struct lu_object { > struct lu_header lo_header; > ... > } > > Now let see if I''m interrupting this correctly. I noticed many > of the zzz_object_init functions for lu_object_operations have > a format similar to : > > static int zzz_object_init(const struct lu_env *env, > struct lu_object *o, > const struct lu_object_conf *conf) > { > struct zzz_device *d = lu2zzz_dev(o->lo_dev); > struct lu_device *under; > struct lu_object *below; > int rc = 0; > ENTRY; > > under = &d->yyy->dd_lu_dev; > below = under->ld_ops->ldo_object_alloc(env, o->lo_header, > under); > if (below != NULL) > lu_object_add(o, below); > else > rc = -ENOMEM; > > return 0; > } > > This is not allocation the zzz_object type that would be allocated by > zzz_object_alloc but is instead a lower level lu_object type object. > Would it always one one slice lower or the lowest level i.e lu_object > itself? Then it forms a compound object with lu_object_add. > > That is the easy part. The part I had a hard time making out was the > lu_object_alloc() function in lu_object.c. You appear to allocate a > top level lu_object with the low level ldo_object_alloc hook but its a > freshly created object so I assume because you did add the top object to > its own list, loh_layer, that the loop you do only contains one object > but you loop as if alot of lu_objects will be in the loh_layers list > with some even allocated. Where is that list being set from so the > properly related objects are initialized? Which objects are being > initialized? The one''s higher in the slice? > > _______________________________________________ > Lustre-devel mailing list > Lustre-devel at lists.lustre.org > http://lists.lustre.org/mailman/listinfo/lustre-devel