On Sun, 17 Nov 2013, Noah Watkins wrote: > The ObjectOperation interface in librados is great for performing compound > atomic operations. However, it doesn?t seem to be capable of expressing more > complex flows. Consider the following set of operations that I one might want > to run atomically to optionally initialize an xattr: > > int ret = getxattr(?foo?) > if (ret < 0 && ret != -ENODATA) > return ret; > > if (ret == -ENODATA) > /* do some initialization */ > else > /* do something else */ > > As it stands, one would need to build a cls_xyz to do this. Alternatively, > something like cls_lua could be used, but there is a lot of downsides to > that. However, after building several cls_xyz modules, it is clear that the > majority of the time is spent doing basic logic, moving some data around, and > occasionally doing something like incrementing some counters. > > I?ve put a prototype solution up in github > > `github.com/ceph/ceph.git obj_op_virt_machine` > > that adds control instructions into the ObjectOperation interface. Using the > interface I can express the above logic as follows: > > ObjectReadOperation op;
Hmm.. I still have a hard time remembering what ObjectReadOperation vs ObjectWriteOperation actually mean/enforce. Especially for these types of requests, which could be either (return useful data on read, or if checks pass do a mutation). > // foo doesn?t exist. the return value > // will be placed into a named register ?ret" > op.getxattr(?foo?, bl, NULL); IIRC there is a per-op flag to ignore the return value (or rather, not return immediately if it is <0). This looks pretty handy! I think we should be careful about extending this interface until we have a pretty good picture of the use-cases, though, and at least one user. sage > > // jump to label if ?ret? register >= 0 > op.ois_jge(?ret?, 0, ?has_attr?); > > // jump to label if ?ret? register == 0 > op.ois_jeq(?ret?, -ENODATA, ?no_attr?); > > // fall through to return any error in the > // ?ret? register. returns immediately > op.ois_ret(?ret?); > > // define a label target > op.ois_label(?has_attr?); > /* ? do some stuff ? */ > op.ois_ret(0); > > // defines a label target > op.ois_label(?no_attr?); > /* ? do initialization ? */ > op.ois_ret(0); > > ioctx.operate(?obj?, &op); > > Using only a few instructions, we can get pretty good building blocks. Adding > a few to examine some data in primitive ways would add another level of > usefulness, too (e.g. atomic counter increment). And, this can also be made > safe by ensuring that jumps are always forward, removing any problems like > infinite loops. > > - Noah-- > To unsubscribe from this list: send the line "unsubscribe ceph-devel" in > the body of a message to [email protected] > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
