Whamcloud - gitweb
LUDOC-297 protocol: Update protocol document
[doc/protocol.git] / setattr.txt
1 Setattr
2 ~~~~~~~
3
4 The 'setattr' VFS method is used to modify the attributes associated
5 with a resource (it is an inode operation). The attributes are the
6 same ones returned by a 'stat' operation: mode, uid, guid, size,
7 atime, ctime, and mtime.
8
9 Changing the File Mode Attribute
10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11
12 If only the file 'mode' is being modified (a 'chmod' command, for
13 instance) then the interaction is relatively simple as shown in
14 <<chmod-rpcs>>.
15
16 .Setattr RPCs for Changing the Resource's Mode
17 [[chmod-rpcs]]
18 image::chmod_rpcs.png["setattr RPCs for changing mode",height=100]
19
20 //////////////////////////////////////////////////////////////////////
21 The chmod_rpcs.png diagram resembles this text art:
22
23 Time
24 Step Client         MDT          OST
25      -------        -------      -------
26 1    MDS_REINT------->
27 2            <-------MDS_REINT
28 //////////////////////////////////////////////////////////////////////
29
30 *1 - Client1 issues an MDS_REINT with the REINT_SETATTR sub-operation.*
31
32 In addition to the 'ptlrpc_body' (Lustre RPC descriptor), the MDS_REINT
33 request RPC from the client has the REINT structure 'mdt_rec_setattr', and a
34 lock request 'ldlm_request'. For a detailed discussion of all the fields in
35 the 'mdt_rec_setattr' and 'ldlm_request' refer to <<struct-mdt-rec-setattr>>
36 and <<struct-ldlm-request>>.
37
38 .MDS_REINT:REINT_SETATTR Request Packet Structure
39 image::mds-reint-setattr-request.png["MDS_REINT:REINT_SETATTR Request Packet Structure",height=50]
40
41 //////////////////////////////////////////////////////////////////////
42 The mds-reint-setattr-request.png diagram resembles this text art:
43
44         MDS_REINT:
45       --REINT_SETATTR-request-------------------------
46       | ptlrpc_body | mdt_rec_setattr | ldlm_request |
47       ------------------------------------------------
48 //////////////////////////////////////////////////////////////////////
49
50 See <<mds-reint-rpc>>.
51
52 In this case the 'setattr' wants to set the mode attribute on
53 the resource. The 'mdt_rec_setattr' identifies the resource with the
54 'sa_fid' field, and the 'sa_valid' field is set to 0x2041:
55
56 .Flags for 'sa_valid' field of 'struct mdt_rec_setattr'
57 [options="header"]
58 |====
59 | Flag                | Meaning
60 | MDS_ATTR_MODE       | mode attribute
61 | MDS_ATTR_CTIME      | ctime attribute
62 | MDS_ATTR_CTIME_SET  | ctime is being set
63 |====
64
65 So the 'ctime' is also updated on the MDT. The mode and time values
66 are put in the corresponding fields of the 'mdt_rec_setattr', and the
67 other attribute fields will be ignored.
68
69 The 'ldlm_request' structure encompasses an early lock cancellation
70 (see <<early-lock-cancellation>>) on the lock that the client had
71 previously acquired for the target resource. The lock handle
72 identifies this lock. Only lock_count and lock_handle are used, and
73 the rest of the ldlm_request is cleared, i.e. all fields set to zero.
74
75 *2 - The MDS_REINT reply acknowledges the updated attributes.*
76
77 In addition to the 'ptlrpc_body' (Lustre RPC descriptor), the MDS_REINT
78 reply RPC to the client has the 'mdt_body' structure. For a detailed
79 discussion of the fields in the 'mdt_body' refer to <<struct-mdt-body>>.
80
81 .MDS_REINT:REINT_SETATTR Reply Packet Structure
82 image::mds-reint-setattr-reply.png["MDS_REINT:REINT_SETATTR Reply Packet Structure",height=50]
83
84 //////////////////////////////////////////////////////////////////////
85 The mds-reint-setattr-reply.png diagram resembles this text art:
86
87       --REINT_SETATTR-reply-----
88       | ptlrpc_body | mdt_body |
89       --------------------------
90 //////////////////////////////////////////////////////////////////////
91
92 The reply from the MDT after the setattr operation has these valid
93 'mdt_body' fields:
94
95 .Flags for 'mbo_valid' field of 'struct mdt_body'
96 [options="header"]
97 |====
98 | Flag            | Meaning
99 | OBD_MD_FLID     | FID
100 | OBD_MD_FLMTIME  | mtime attribute
101 | OBD_MD_FLSIZE   | size attribute
102 | OBD_MD_FLBLOCKS | blocks attribute
103 | OBD_MD_BLKSZ    | block size attribute
104 | OBD_MD_FLTYPE   | type attribute
105 | OBD_MD_FLNLINK  | number of links attribute
106 | OBD_MD_FLRDEV   | device attribute
107 |====
108
109 So the client is updated with any other information the MDT has after
110 the attributes were set at the client's request.
111
112 Changing the File Time Attributes
113 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114
115 The RPC(s) that get sent for the 'setattr' depend on specifically what
116 values are being set. If the time values are being set (as in a
117 "touch" command) then there are RPCs in addition to the MDS_REINT,
118 with the REINT_SETATTR sub-operation, that update the time values on
119 the MDT. That operation is followed by an OST_SETATTR that sets the
120 time values on the OST (or OSTs if there are several). But in order to
121 know what OSTs to contact the client must first get the layout of the
122 resource. Then it can send the OST_SETATTR RPC to the appropriate OSTs
123 and update the time attributes.
124
125 .Setattr RPCs for Changing the Resource's Time Attributes
126 [[touch-rpcs]]
127 image::touch_rpcs.png["setattr RPCs for the time attributes",height=200]
128
129 //////////////////////////////////////////////////////////////////////
130 The touch_rpcs.png diagram resembles this text art:
131
132 Time
133 Step Client         MDT           OST
134      -------         -------      -------
135 1    MDS_REINT------->
136 2            <-------MDS_REINT
137 3    LDLM_ENQUEUE---->
138 4            <-------LDLM_ENQUEUE
139 5    OST_SETATTR------------------>
140 6            <--------------------OST_SETATTR
141 //////////////////////////////////////////////////////////////////////
142
143
144 *1 - The client issues an MDS_REINT with the REINT_SETATTR
145  sub-operation.*
146
147 See <<mds-reint-rpc>>.
148
149 The MDS_REINT request RPC closely resembles the one described above,
150 but in this case the 'setattr' wants to set the time attributes on the
151 resource. The 'mdt_rec_setattr' again identifies the resource with the
152 'sa_fid' field, and the 'sa_valid' field is set to 0x21f0:
153
154 .Flags for 'sa_valid' field of 'struct mdt_rec_setattr'
155 [options="header"]
156 |====
157 | Flag                | Meaning
158 | MDS_ATTR_ATIME      | atime attribute
159 | MDS_ATTR_MTIME      | mtime attribute
160 | MDS_ATTR_CTIME      | ctime attribute
161 | MDS_ATTR_ATIME_SET  | atime is being set
162 | MDS_ATTR_MTIME_SET  | mtime is being set
163 | MDS_ATTR_CTIME_SET  | ctime is being set
164 |====
165
166 The time values are put in the corresponding fields of the
167 'mdt_rec_setattr', and the other attribute fields will be ignored.
168
169 There is again an early lock cancellation, since the client knows it
170 no longer need to have a lock on the MDT resource attributes.
171
172 *2 - The MDS_REINT reply acknowledges the updated times.*
173
174 The MDS_REINT reply is identical to the previous case in every way,
175 including which valid attributes it echoes back.
176
177 *3 - The client asks for a intent lock on the layout data for the
178 resource.*
179
180 Before communicating with the OSTs the client needs to know which ones
181 are involved with this resource, and before it can ask for that
182 'layout' information it must acquire a 'layout lock'. The
183 LDLM_ENQUEUE RPC in this case has (in addition to the 'ptlrpc_body'
184 structure) an 'ldlm_request', an 'ldlm_intent', and a 'layout_intent'.
185
186 .LDLM_ENQUEUE Intent:Layout Request Packet Structure
187 image::ldlm-enqueue-intent-layout-request.png["LDLM_ENQUEUE Intent:Layout request Packet Structure",height=50]
188
189 //////////////////////////////////////////////////////////////////////
190 The ldlm-enqueue-intent-layout-request.png diagram resembles this text
191 art:
192
193        LDLM_ENQUEUE:
194       --intent:layout request------------------------------------
195       | ptlrpc_body | ldlm_request |ldlm_intent | layout_intent |
196       -----------------------------------------------------------
197 //////////////////////////////////////////////////////////////////////
198
199 See <<ldlm-enqueue-rpc>>.
200
201 The 'ldlm_request' asks for a read lock on the resource and has its
202 intent flag set. The 'ldlm_intent' has the intent opcode is 0x800:
203 IT_LAYOUT. The 'layout_intent' has the 'li_opc' value 0:
204 LAYOUT_INTENT_ACCESS.
205
206 *4 - The MDS replies with a read lock on the layout.*
207
208 The LDLM_ENQUEUE reply that the MDS sends back grants the read lock on
209 the layout and provides a Lock Value Block (LVB) describing the
210 layout of the resource. That layout is from the extended attribute
211 'trusted.lov' and has the structure 'lov_mds_md'.
212
213 .LDLM_ENQUEUE Intent:Layout Reply Packet Structure
214 image::ldlm-enqueue-intent-layout-reply.png["LDLM_ENQUEUE Intent:Layout reply Packet Structure",height=50]
215
216 //////////////////////////////////////////////////////////////////////
217 The ldlm-enqueue-intent-layout-reply.png diagram resembles this text
218 art:
219
220        LDLM_ENQUEUE:
221       --intent:layout reply--------------------
222       | ptlrpc_body | ldlm_reply | lov_mds_md |
223       -----------------------------------------
224 //////////////////////////////////////////////////////////////////////
225
226 *5 - The client issues an OST_SETATTR with the updated times, which
227 are maintained on the OST.*
228
229 At last the client can send an update to the OST. The OST_SETATTR RPC
230 has an 'ost_body' structure.
231
232 .OST_SETATTR Request Packet Structure
233 image::ost-setattr-request.png["OST_SETATTR Request Packet Structure",height=50]
234
235 //////////////////////////////////////////////////////////////////////
236 The ost-setattr-request.png diagram resembles this text art:
237
238        OST_SETATTR:
239       --request-----------------
240       | ptlrpc_body | ost_body |
241       --------------------------
242 //////////////////////////////////////////////////////////////////////
243
244 See <<ost-setattr-rpc>>.
245
246 The 'ost_body' structure is documented in the <<struct-ost-body>>
247 section.  In this case the 'o_valid' field is 0x300400f, so the valid
248 fields are given by:
249
250 .Flags for 'o_valid' field of 'struct os_body'
251 [options="header"]
252 |====
253 | Flag                | Meaning
254 | OBD_MD_FLID         | FID
255 | OBD_MD_FLATIME      | atime attribute
256 | OBD_MD_FLMTIME      | mtime attribute
257 | OBD_MD_FLCTIME      | ctime attribute
258 | OBD_MD_FLGENER      | generation
259 | OBD_MD_FLGROUP      | group
260 | OBD_MD_FLFID        |
261 |====
262
263 *6 - The OST acknowledges the update.*
264
265 The reply RPC for the OST_SETATTR operation has the same form as the
266 request.
267
268 .OST_SETATTR Reply Packet Structure
269 image::ost-setattr-reply.png["OST_SETATTR Reply Packet Structure",height=50]
270
271 //////////////////////////////////////////////////////////////////////
272 The ost-setattr-reply.png diagram resembles this text art:
273
274        OST_SETATTR:
275       --reply-------------------
276       | ptlrpc_body | ost_body |
277       --------------------------
278 //////////////////////////////////////////////////////////////////////
279
280 The OST_SETATTR reply acknowledges the update and sends back an
281 'o_valid' of 0x10007bf, which indicates the fields:
282
283 .Flags for 'o_valid' field of 'struct os_body'
284 [options="header"]
285 |====
286 | Flag                | Meaning
287 | OBD_MD_FLID         | OST ID
288 | OBD_MD_FLATIME      | atime attribute
289 | OBD_MD_FLMTIME      | mtime attribute
290 | OBD_MD_FLCTIME      | ctime attribute
291 | OBD_MD_FLSIZE       | size attribute
292 | OBD_MD_FLBLOCKS     | blocks attribute
293 | OBD_MD_FLMODE       | mode attribute
294 | OBD_MD_FLTYPE       | type attribute
295 | OBD_MD_FLUID        | UID attribute
296 | OBD_MD_FLGID        | GID attribute
297 | OBD_MD_FLGROUP      | group
298 |====
299
300 Changing the Size Attribute
301 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
302
303 If the size is being set (as in a "truncate" command) then the client
304 (Client1) will issue an LDLM_ENQUEUE to the OST for a write lock on
305 the extent attributes of the resource. If another client (Client2) had
306 a lock on the resource, then before the OST can grant the lock to
307 Client1 it has to interact with Client2. The OST sends an
308 LDLM_BL_CALLBACK request to Client2 asking Client 2 to finish up with
309 the lock it has. Client2 replies with a simple acknowledgment. When
310 Client2 is no longer using the lock it will send an LDLM_CANEL RPC to
311 the OST. At that point the OST grants the original request sending an
312 LDLM_CP_CALLBACK request to Client1 to notify it. With that taken care
313 of Client1 is finally able to issue the OST_PUNCH request that
314 actually modifies the size attribute of the affected
315 resources. Meanwhile, the OST also replies to Client2 acknowledging
316 its LDLM_CANCEL.
317
318 .Setattr RPCs for Changing the Resource's Size Attribute
319 [[truncate-rpcs]]
320 image::truncate_rpcs.png["setattr RPCs for the size attribute",height=250]
321
322 //////////////////////////////////////////////////////////////////////
323 The truncate_rpcs.png diagram resembles this text art:
324
325 Time
326 Step Client1         MDT           OST             Client2
327      -------         -------      -------          -------
328 1    MDS_REINT------->
329 2            <-------MDS_REINT
330 3    LDLM_ENQUEUE----------------->
331 4                               LDLM_BL_CALLBACK---->
332 5                                              <----LDLM_BL_CALLBACK
333 6               <-----------------LDLM_ENQUEUE
334 7                                          <--------LDLM_CANCEL
335 8                   <-----------LDLM_CP_CALLBACK
336 9    LDLM_CP_CALLBACK----------->
337 10   OST_PUNCH-------------------->
338 11                                LDLM_CANCEL------>
339 12           <--------------------OST_PUNCH
340 //////////////////////////////////////////////////////////////////////
341
342 *1 - The client issues an MDS_REINT with the REINT_SETATTR
343 sub-operation.*
344
345 See <<mds-reint-rpc>>.
346
347 The MDS_REINT request RPC closely resembles the one described above,
348 but in this case the 'setattr' wants to modify the size attribute on the
349 resource. The 'mdt_rec_setattr' again identifies the resource with the
350 'sa_fid' field, and the 'sa_valid' field is set to 0x2002168:
351
352 .Flags for 'sa_valid' field of 'struct mdt_rec_setattr'
353 [options="header"]
354 |====
355 | Flag                | Meaning
356 | MDS_ATTR_SIZE       | size attribute
357 | MDS_ATTR_MTIME      | mtime attribute
358 | MDS_ATTR_CTIME      | ctime attribute
359 | MDS_ATTR_MTIME_SET  | mtime being set
360 | MDS_ATTR_CTIME_SET  | ctime being set
361 |====
362
363 The size and time values are put in the corresponding fields of the
364 'mdt_rec_setattr', and the other attribute fields will be ignored.
365
366 There is again an 'ldlm_request' structure in the RPC, but in this
367 case it is empty (all fields set to zero), so no early lock
368 cancellation.
369
370 *2 - The MDS_REINT reply acknowledges the updated times.*
371
372 The MDS_REINT reply is identical to the previous cases in every way,
373 including which valid attributes it echoes back.
374
375 *3 - The client asks the OST for a write lock of type LDLM_EXTENT.*
376
377 See <<ldlm-enqueue-rpc>>.
378
379 The 'ldlm_request' asks for a write lock with the lock descriptor
380 resource's type set to LDLM_EXTENT, the policy data covering the whole
381 file, and the lock handle set to identify this request. The rest of
382 the lock request is blank (zeroes). The RPC resembles the simplest
383 request form in <<ldlm-enqueue-rpc>>.
384
385 *4 - The OST contacts Client2 to ask for the return of the lock.*
386
387 The LDLM_BL_CALLBACK is initiated by the OST and sent to the client,
388 identifying the resource in question. The content of the ldlm_request
389 is otherwise identical to the one sent from Client1 to the OST
390 ('l_req_mode' == LCK_PW, 'l_granted_mode' == LCK_MINMODE).
391
392 .LDLM_BL_CALLBACK Request Packet Structure
393 image::ldlm-bl-callback-request.png["LDLM_BL_CALLBACK Request Packet Structure", height=50]
394
395 //////////////////////////////////////////////////////////////////////
396 The ldlm-bl-callback-request.png diagram resembles this text
397 art:
398
399        LDLM_BL_CALLBACK:
400       --request---------------------
401       | ptlrpc_body | ldlm_request |
402       ------------------------------
403 //////////////////////////////////////////////////////////////////////
404
405 See <<ldlm-bl-callback-rpc>>.
406
407 *5 - Client2 acknowledges the request and returns the lock.*
408
409 The LDLM_BL_CALLBACK is an "empty" RPC in that it only has the
410 LDLM_BL_CALLBACK opcode and no other content beyond the
411 'ptlrpc_body'.
412
413 .LDLM_BL_CALLBACK Reply Packet Structure
414 image::ldlm-bl-callback-reply.png["LDLM_BL_CALLBACK Reply Packet Structure",height=50]
415
416 //////////////////////////////////////////////////////////////////////
417 The ldlm-bl-callback-reply.png diagram resembles this text
418 art:
419
420        LDLM_BL_CALLBACK:
421       --reply--------
422       | ptlrpc_body |
423       ---------------
424 //////////////////////////////////////////////////////////////////////
425
426 Its effect is to notify the OST that the lock has been returned.
427
428 *6 - The OST replies acknowleging the lock request.*
429
430 The ldlm_reply's lock descriptor acknowledges the request for an
431 extent write lock without granting it ('l_req_mode' == LCK_PW,
432 'l_granted_mode' == LCK_MINMODE, 'lock_flags' == 0x2 ==
433 LDLM_FL_BLOCK_GRANTED, it is not granted because it is
434 blocked). Additional attribute data accompanies the LDLM_ENQUEUE reply
435 to tell the client about the resource attributes on the OST.
436
437 .LDLM_ENQUEUE Extent LVB Reply Packet Structure
438 image::ldlm-enqueue-extent-lvb-reply.png["LDLM_ENQUEUE Extent LVB reply Packet Structure",height=50]
439
440 //////////////////////////////////////////////////////////////////////
441 The ldlm-enqueue-intent-lvb-reply.png diagram resembles this text
442 art:
443
444        LDLM_ENQUEUE:
445       --extent lvb reply--------------------
446       | ptlrpc_body | ldlm_reply | ost_lvb |
447       --------------------------------------
448 //////////////////////////////////////////////////////////////////////
449
450 *7 - Client2 cancels its lock*
451
452 Having received an LDLM_BL_CALLBACK Client2 must finish up with its
453 lock.  Once it does it sends an LDLM_CANCEL request to the OST to
454 signal that it is done.
455
456 .LDLM_CANCEL Request Packet Structure
457 image::ldlm-cancel-request.png["LDLM_CANCEL Request Packet Structure",height=50]
458
459 //////////////////////////////////////////////////////////////////////
460 The ldlm-cancel-request.png diagram resembles this text art:
461
462        LDLM_CANCEL:
463       --request---------------------
464       | ptlrpc_body | ldlm_request |
465       ------------------------------
466 //////////////////////////////////////////////////////////////////////
467
468 See <<ldlm-cancel-rpc>>.
469
470 The 'ldlm_request' indicates which lock is being canceled in its
471 (first) 'lock_handle' field. The OST then looks for anyone else
472 waiting on that lock, which it finds is Client1. It waits to reply to
473 Client2 with an LDLM_CANCEL reply until after it has notified Client1.
474
475 *8 - The OST notifies Client1 that it now has the lock.*
476
477 The 'ldlm_request' structure now has the granted mode set to protected
478 write. It also sends along any updated attributes as, for example, if
479 Client1 had flushed its dirty write cache.
480
481 .LDLM_CP_CALLBACK Request Packet Structure
482 image::ldlm-cp-callback-request.png["LDLM_CP_CALLBACK Request Packet Structure",height=50]
483
484 //////////////////////////////////////////////////////////////////////
485 The ldlm-cp-callback-request.png diagram resembles this text
486 art:
487
488        LDLM_CP_CALLBACK:
489       --request-------------------------------
490       | ptlrpc_body | ldlm_request | ost_lvb |
491       ----------------------------------------
492 //////////////////////////////////////////////////////////////////////
493
494 See <<ldlm-cp-callback-rpc>>.
495
496 *9 - Client1 acknowledges the lock update.*
497
498 The reply is "empty" in this case as well. The opcode in the
499 'ptlrpc_body' is sufficient to inform the OST that Client1 got its
500 lock update.
501
502 .LDLM_CP_CALLBACK Reply Packet Structure
503 image::ldlm-cp-callback-reply.png["LDLM_CP_CALLBACK Reply Packet Structure",height=50]
504
505 //////////////////////////////////////////////////////////////////////
506 The ldlm-cp-callback-reply.png diagram resembles this text
507 art:
508
509        LDLM_CP_CALLBACK:
510       --reply--------
511       | ptlrpc_body |
512       ---------------
513 //////////////////////////////////////////////////////////////////////
514
515 *10 - Client1 issues an OST_PUNCH request.*
516
517 As with the OST_SETATTR RPC there is an 'ost_body' structure.
518
519 .OST_PUNCH Request Packet Structure
520 image::ost-punch-request.png["OST_PUNCH Request Packet Structure",height=50]
521
522 //////////////////////////////////////////////////////////////////////
523 The ost-punch-request.png diagram resembles this text art:
524
525        OST_PUNCH:
526       --request-----------------
527       | ptlrpc_body | ost_body |
528       --------------------------
529 //////////////////////////////////////////////////////////////////////
530
531 See <<ost-punch-rpc>>.
532
533 In this case the 'o_valid' field is 0x30403d:
534
535 .Flags for 'o_valid' field of 'struct os_body'
536 [options="header"]
537 |====
538 | Flag                | Meaning
539 | OBD_MD_FLID         | OST ID
540 | OBD_MD_FLMTIME      | mtime attribute
541 | OBD_MD_FLCTIME      | ctime attribute
542 | OBD_MD_FLSIZE       | size attribute
543 | OBD_MD_FLBLOCKS     | blocks attribute
544 | OBD_MD_FLGENER      | generation
545 | OBD_MD_FLCKSUM      | checksukm
546 | OBD_MD_FLQOS        | quality of service
547 |====
548
549 *11 - The OST acknowledges the LDLM_CANCEL (step 7) from Client2*
550
551 The OST finishes up with the lock cancel (after having notified
552 Client1) by replying to Clietn2. This happens asynchronously with the
553 arrival of the OST_PUNCH request, and in <<truncate-rpcs>> it is shown
554 occuring after the OST_PUNCH, but that is not required.
555
556 .LDLM_CANCEL Reply Packet Structure
557 image::ldlm-cancel-reply.png["LDLM_CANCEL Reply Packet Structure",height=50]
558
559 //////////////////////////////////////////////////////////////////////
560 The ldlm-cancel-reply.png diagram resembles this text art:
561
562        LDLM_CANCEL:
563       --reply--------
564       | ptlrpc_body |
565       ---------------
566 //////////////////////////////////////////////////////////////////////
567
568 The LDLM_CANCEL reply is a so-called "empty" RPC. Its only purpose is
569 to acknowldge receipt of the LDLM_CANCEL request.
570
571 *12 - The OST an OST_PUNCH reply.*
572
573 The OST_PUNCH reply also resembles the OST_SETATTR reply:
574
575 .OST_PUNCH Reply Packet Structure
576 image::ost-punch-reply.png["OST_PUNCH Reply Packet Structure",height=50]
577
578 //////////////////////////////////////////////////////////////////////
579 The ost-punch-reply.png diagram resembles this text art:
580
581        OST_PUNCH:
582       --reply-------------------
583       | ptlrpc_body | ost_body |
584       --------------------------
585 //////////////////////////////////////////////////////////////////////
586
587 The 'o_valid' field is 0x1, so only the 'o_id' field is
588 interpreted. It just acknowledges the requested change has been
589 made.
590