From 6746484df44e456ca3df47708e7d1bc14e4404e8 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Mon, 10 Apr 2017 15:22:06 -0600 Subject: [PATCH] LU-8998 llapi: add LLAPI_LAYOUT_COMP_USE_PREV Add LLAPI_LAYOUT_COMP_USE_PREV to be able to iterate through components in reverse order. Add a test case to llapi_layout_test.c to exercise COMP_USE_LAST and COMP_USE_PREV options. Improve description of component ID in llapi_layout_comp_id_get.3 to indicate that the component ID does not imply ordering or other semantics, and is just a numeric identifier for each component. Signed-off-by: Andreas Dilger Change-Id: I21f78e575c2429ef927c8c2fc50bf150f59cab07 Reviewed-on: https://review.whamcloud.com/26484 Reviewed-by: Niu Yawei Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/doc/llapi_layout_comp_id_get.3 | 20 +++++++++++------ lustre/doc/llapi_layout_comp_use.3 | 11 ++++++---- lustre/include/lustre/lustreapi.h | 1 + lustre/tests/llapi_layout_test.c | 15 +++++++++++++ lustre/utils/liblustreapi_layout.c | 41 +++++++++++++++++++++++------------ 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/lustre/doc/llapi_layout_comp_id_get.3 b/lustre/doc/llapi_layout_comp_id_get.3 index 945f048..f199685 100644 --- a/lustre/doc/llapi_layout_comp_id_get.3 +++ b/lustre/doc/llapi_layout_comp_id_get.3 @@ -1,4 +1,4 @@ -.TH llapi_layout_comp_id_get 3 "2015 Nov 4" "Lustre User API" +.TH llapi_layout_comp_id_get 3 "2017 Apr 7" "Lustre User API" .SH NAME llapi_layout_comp_id_get \- get the ID of a layout component. .SH SYNOPSIS @@ -6,18 +6,23 @@ llapi_layout_comp_id_get \- get the ID of a layout component. .B #include .PP .BI "int llapi_layout_comp_id_get(const struct llapi_layout *" layout ", -.BI " uint32_t *" id ); +.BI " uint32_t *" comp_id ); .fi .SH DESCRIPTION .PP -Return the unique numeric -.I id -of the current component of +Return the unique numeric ID +.I comp_id +of the currently active component of .IR layout . +The ID of a component is a unique numeric identifier for the component +within the layout of each file, and no age, ordering, relative position, +or other sematics are implied by the component ID. If a file's layout +is modified a large number of times, the component ID may be re-used +but will always be unique within a single file's layout. .PP .SH RETURN VALUES -Return 0 on success, or -1 if an error occurred (in which case, errno is -set appropriately). +Return 0 on success. Return -1 if an error occurred and set errno +appropriately. .SH ERRORS .TP 15 .SM EINVAL @@ -25,5 +30,6 @@ An invalid argument was specified. .SH "SEE ALSO" .BR llapi_layout_alloc (3), .BR llapi_layout_file_open (3), +.BR llapi_layout_comp_use_id (3), .BR llapi_layout (7), .BR lustreapi (7) diff --git a/lustre/doc/llapi_layout_comp_use.3 b/lustre/doc/llapi_layout_comp_use.3 index 32ac428..fedf3e9 100644 --- a/lustre/doc/llapi_layout_comp_use.3 +++ b/lustre/doc/llapi_layout_comp_use.3 @@ -21,14 +21,17 @@ are: .BR LLAPI_LAYOUT_COMP_USE_FIRST : The first component of the layout. .PP +.BR LLAPI_LAYOUT_COMP_USE_LAST : +The last component of the layout. +.PP .BR LLAPI_LAYOUT_COMP_USE_NEXT : The next component after the current one. .PP -.BR LLAPI_LAYOUT_COMP_USE_LAST : -The last component of the layout. +.BR LLAPI_LAYOUT_COMP_USE_PREV : +The previous component before the current one. .SH RETURN VALUES -Return 0 on success, and 1 when there is no next component. Otherwise, -if an error occurred -1 is returned and +Return 0 on success, and 1 when there is no next or previous component. +Otherwise, if an error occurred -1 is returned and .I errno is set appropriately. .SH ERRORS diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index dc21d1a..397abf6 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -766,6 +766,7 @@ enum llapi_layout_comp_use { LLAPI_LAYOUT_COMP_USE_FIRST = 1, LLAPI_LAYOUT_COMP_USE_LAST = 2, LLAPI_LAYOUT_COMP_USE_NEXT = 3, + LLAPI_LAYOUT_COMP_USE_PREV = 4, }; /** diff --git a/lustre/tests/llapi_layout_test.c b/lustre/tests/llapi_layout_test.c index 805d235..a86dc5b 100644 --- a/lustre/tests/llapi_layout_test.c +++ b/lustre/tests/llapi_layout_test.c @@ -1483,6 +1483,21 @@ void test31(void) i++; } while (rc == 0); + /* Verify reverse iteration gives the same IDs as forward iteration */ + rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_LAST); + ASSERTF(rc == 0, "rc %d, errno %d", rc, errno); + do { + __u32 comp_id; + + --i; + rc = llapi_layout_comp_id_get(layout, &comp_id); + ASSERTF(rc == 0 && comp_id == id[i], + "i %d, errno %d, id[] %u/%u", i, errno, id[i], comp_id); + + rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_PREV); + ASSERTF(rc == 0 || i == 0, "i=%d rc=%d errno=%d", i, rc, errno); + } while (rc == 0); + llapi_layout_free(layout); /* delete non-tail component will fail */ diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index af54943..15627ea 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -1820,13 +1820,15 @@ int llapi_layout_comp_use_id(struct llapi_layout *layout, uint32_t comp_id) * \param[in] pos the position to be moved, it can be: * LLAPI_LAYOUT_COMP_USE_FIRST: use first component * LLAPI_LAYOUT_COMP_USE_LAST: use last component - * LLAPI_LAYOUT_COMP_USE_NEXT: use next component + * LLAPI_LAYOUT_COMP_USE_NEXT: use component after current + * LLAPI_LAYOUT_COMP_USE_PREV: use component before current * * \retval =0 : moved successfully - * \retval =1 : at last component with NEXT + * \retval =1 : at last component with NEXT, at first component with PREV * \retval <0 if error occurs */ -int llapi_layout_comp_use(struct llapi_layout *layout, uint32_t pos) +int llapi_layout_comp_use(struct llapi_layout *layout, + enum llapi_layout_comp_use pos) { struct llapi_layout_comp *comp, *head, *tail; @@ -1839,21 +1841,32 @@ int llapi_layout_comp_use(struct llapi_layout *layout, uint32_t pos) return -1; } - head = list_entry(layout->llot_comp_list.next, typeof(*head), - llc_list); - tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), - llc_list); - - if (pos == LLAPI_LAYOUT_COMP_USE_NEXT) { - if (comp == tail) + head = list_entry(layout->llot_comp_list.next, typeof(*head), llc_list); + tail = list_entry(layout->llot_comp_list.prev, typeof(*tail), llc_list); + switch (pos) { + case LLAPI_LAYOUT_COMP_USE_FIRST: + layout->llot_cur_comp = head; + break; + case LLAPI_LAYOUT_COMP_USE_NEXT: + if (comp == tail) { + errno = ENOENT; return 1; + } layout->llot_cur_comp = list_entry(comp->llc_list.next, typeof(*comp), llc_list); - } else if (pos == LLAPI_LAYOUT_COMP_USE_FIRST) { - layout->llot_cur_comp = head; - } else if (pos == LLAPI_LAYOUT_COMP_USE_LAST) { + break; + case LLAPI_LAYOUT_COMP_USE_LAST: layout->llot_cur_comp = tail; - } else { + break; + case LLAPI_LAYOUT_COMP_USE_PREV: + if (comp == head) { + errno = ENOENT; + return 1; + } + layout->llot_cur_comp = list_entry(comp->llc_list.prev, + typeof(*comp), llc_list); + break; + default: errno = EINVAL; return -1; } -- 1.8.3.1