Roll the carpet

Charcoal, 15 bytes

FS«F¬℅§KV⁰⟲⁶→Pι

Try it online! Link is to verbose version of code. Explanation:

FS«

Loop over the carpet.

F¬℅§KV⁰

Check whether there's anything above the cursor.

⟲⁶

If not then roll the carpet.

→Pι

Move right and output the current character.

Example: For the input 0123456789, the following actions occur:

0

0 is printed.

01

The cursor moves right and 1 is printed.

0
1

Since there is nothing above the 1, the canvas is rotated.

0
12

The cursor moves right and the 2 is printed.

10
2

Since there is nothing above the 2, the canvas is rotated.

10
23

The cursor moves right and the 3 is printed.

10
234

The cursor moves right and the 4 is printed.

21
30
4

Since there is nothing above the 4, the canvas is rotated.

21
30
45

The cursor moves right and the 5 is printed.

21
30
456

The cursor moves right and the 6 is printed.

432
501
6

Since there is nothing above the 6, the canvas is rotated.

432
501
67

The cursor moves right and the 7 is printed.

432
501
678

The cursor moves right and the 8 is printed.

432
501
6789

The cursor moves right and the 9 is printed.


Pyth, 37 bytes

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt

Try it online here, or verify all the test cases at once here.

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQtQ   Implicit: Q=eval(input())
                                         Trailing Q inferred
                                 ]hQ     First character of Q, wrapped in an array
                                    tQ   All but the first character of Q
                                ,        2-element array of the two previous results
                                           This yields array with rolled carpet (as array of strings) followed by the tail
       .W                                While condition function is truthy, execute inner function, with initial value of the above:
         gleHJlhH                          Condition function, input H
             JlhH                            Number of layers in the current rolled carpet, store in J
          leH                                Lenth of the tail
         g   J                               Is the above greater than or equal to J?
                 ,+_MChZ<eZJ>eZJ           Inner function, input Z
                   _MChZ                     Rotate the current rolled carpet (transpose, then reverse each row)
                  +     <eZJ                 Append the first J characters of the tail as a new row
                 ,                           Pair the above with...
                            >eZJ             ... all but the first J characters of the tail - this is the new tail
.U+j;bZ                                  Join the carpet roll on newlines and append the tail, implicit print

Husk, 24 bytes

►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N

Try it online!

Explanation

Implicit input, say s="carpets"

CṘ2N  Break s into chunks:
   N   Natural numbers: [1,2,3,4,..
 Ṙ2    Repeat each twice: [1,1,2,2,3,3,4,4,..
C      Break s into chunks of these lengths: ["c","a","rp","et","s"]
       The last chunk is shorter if we run out of characters.

§z:oΘḣĠ+  Attempt to merge suffix of chunks:
      Ġ    Cumulative reduce chunk list from right
       +   by concatenation: ["carpets","arpets","rpets","ets","s"]
   oΘḣ     Prefixes of chunk list (empty and nonempty): [[],["c"],..,["c","a","rp","et","s"]]
§z         Zip these by
  :        appending: [["carpets"],["c","arpets"],..,["c","a","rp","et","s"]]
           These are all versions of the chunk list where some suffix has been merged.

mFȯ:T↔ø  Roll each list:
m         Map
 F        reduce from left
      ø   starting from empty character matrix
  ȯ:T↔    by this function:
    T↔     Reverse and transpose (rotating by 90 degrees)
  ȯ:       then append next chunk as new row.
         Result: [["carpets"],["c","arpets"],..,["epr","tca","s"]]

►S=ÖL  Select the matrix rolled by the correct amount:
►       Find element that maximizes
 S=     being equal to
   ÖL   sort by length.
        This selects a matrix whose rows have non-decreasing lengths.
        Ties are broken by choosing the rightmost one.
       Result: ["ra","pc","ets"]

Implicitly print each row separated by newlines.