Whamcloud - gitweb
LU-8998 llapi: add LLAPI_LAYOUT_COMP_USE_PREV 84/26484/4
authorAndreas Dilger <andreas.dilger@intel.com>
Mon, 10 Apr 2017 21:22:06 +0000 (15:22 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 9 May 2017 03:45:35 +0000 (03:45 +0000)
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 <andreas.dilger@intel.com>
Change-Id: I21f78e575c2429ef927c8c2fc50bf150f59cab07
Reviewed-on: https://review.whamcloud.com/26484
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/doc/llapi_layout_comp_id_get.3
lustre/doc/llapi_layout_comp_use.3
lustre/include/lustre/lustreapi.h
lustre/tests/llapi_layout_test.c
lustre/utils/liblustreapi_layout.c

index 945f048..f199685 100644 (file)
@@ -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 <lustre/lustreapi.h>
 .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)
index 32ac428..fedf3e9 100644 (file)
@@ -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
index dc21d1a..397abf6 100644 (file)
@@ -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,
 };
 
 /**
index 805d235..a86dc5b 100644 (file)
@@ -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 */
index af54943..15627ea 100644 (file)
@@ -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;
        }