diff options
Diffstat (limited to 'Documentation/filesystems')
-rw-r--r-- | Documentation/filesystems/configfs/configfs.txt | 57 | ||||
-rw-r--r-- | Documentation/filesystems/configfs/configfs_example.c | 2 |
2 files changed, 49 insertions, 10 deletions
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt index b34cdb50eab4..d1b98257d000 100644 --- a/Documentation/filesystems/configfs/configfs.txt +++ b/Documentation/filesystems/configfs/configfs.txt | |||
@@ -238,6 +238,8 @@ config_item_type. | |||
238 | struct config_group *(*make_group)(struct config_group *group, | 238 | struct config_group *(*make_group)(struct config_group *group, |
239 | const char *name); | 239 | const char *name); |
240 | int (*commit_item)(struct config_item *item); | 240 | int (*commit_item)(struct config_item *item); |
241 | void (*disconnect_notify)(struct config_group *group, | ||
242 | struct config_item *item); | ||
241 | void (*drop_item)(struct config_group *group, | 243 | void (*drop_item)(struct config_group *group, |
242 | struct config_item *item); | 244 | struct config_item *item); |
243 | }; | 245 | }; |
@@ -268,6 +270,16 @@ the item in other threads, the memory is safe. It may take some time | |||
268 | for the item to actually disappear from the subsystem's usage. But it | 270 | for the item to actually disappear from the subsystem's usage. But it |
269 | is gone from configfs. | 271 | is gone from configfs. |
270 | 272 | ||
273 | When drop_item() is called, the item's linkage has already been torn | ||
274 | down. It no longer has a reference on its parent and has no place in | ||
275 | the item hierarchy. If a client needs to do some cleanup before this | ||
276 | teardown happens, the subsystem can implement the | ||
277 | ct_group_ops->disconnect_notify() method. The method is called after | ||
278 | configfs has removed the item from the filesystem view but before the | ||
279 | item is removed from its parent group. Like drop_item(), | ||
280 | disconnect_notify() is void and cannot fail. Client subsystems should | ||
281 | not drop any references here, as they still must do it in drop_item(). | ||
282 | |||
271 | A config_group cannot be removed while it still has child items. This | 283 | A config_group cannot be removed while it still has child items. This |
272 | is implemented in the configfs rmdir(2) code. ->drop_item() will not be | 284 | is implemented in the configfs rmdir(2) code. ->drop_item() will not be |
273 | called, as the item has not been dropped. rmdir(2) will fail, as the | 285 | called, as the item has not been dropped. rmdir(2) will fail, as the |
@@ -280,18 +292,18 @@ tells configfs to make the subsystem appear in the file tree. | |||
280 | 292 | ||
281 | struct configfs_subsystem { | 293 | struct configfs_subsystem { |
282 | struct config_group su_group; | 294 | struct config_group su_group; |
283 | struct semaphore su_sem; | 295 | struct mutex su_mutex; |
284 | }; | 296 | }; |
285 | 297 | ||
286 | int configfs_register_subsystem(struct configfs_subsystem *subsys); | 298 | int configfs_register_subsystem(struct configfs_subsystem *subsys); |
287 | void configfs_unregister_subsystem(struct configfs_subsystem *subsys); | 299 | void configfs_unregister_subsystem(struct configfs_subsystem *subsys); |
288 | 300 | ||
289 | A subsystem consists of a toplevel config_group and a semaphore. | 301 | A subsystem consists of a toplevel config_group and a mutex. |
290 | The group is where child config_items are created. For a subsystem, | 302 | The group is where child config_items are created. For a subsystem, |
291 | this group is usually defined statically. Before calling | 303 | this group is usually defined statically. Before calling |
292 | configfs_register_subsystem(), the subsystem must have initialized the | 304 | configfs_register_subsystem(), the subsystem must have initialized the |
293 | group via the usual group _init() functions, and it must also have | 305 | group via the usual group _init() functions, and it must also have |
294 | initialized the semaphore. | 306 | initialized the mutex. |
295 | When the register call returns, the subsystem is live, and it | 307 | When the register call returns, the subsystem is live, and it |
296 | will be visible via configfs. At that point, mkdir(2) can be called and | 308 | will be visible via configfs. At that point, mkdir(2) can be called and |
297 | the subsystem must be ready for it. | 309 | the subsystem must be ready for it. |
@@ -303,7 +315,7 @@ subsystem/group and the simple_child item in configfs_example.c It | |||
303 | shows a trivial object displaying and storing an attribute, and a simple | 315 | shows a trivial object displaying and storing an attribute, and a simple |
304 | group creating and destroying these children. | 316 | group creating and destroying these children. |
305 | 317 | ||
306 | [Hierarchy Navigation and the Subsystem Semaphore] | 318 | [Hierarchy Navigation and the Subsystem Mutex] |
307 | 319 | ||
308 | There is an extra bonus that configfs provides. The config_groups and | 320 | There is an extra bonus that configfs provides. The config_groups and |
309 | config_items are arranged in a hierarchy due to the fact that they | 321 | config_items are arranged in a hierarchy due to the fact that they |
@@ -314,19 +326,19 @@ and config_item->ci_parent structure members. | |||
314 | 326 | ||
315 | A subsystem can navigate the cg_children list and the ci_parent pointer | 327 | A subsystem can navigate the cg_children list and the ci_parent pointer |
316 | to see the tree created by the subsystem. This can race with configfs' | 328 | to see the tree created by the subsystem. This can race with configfs' |
317 | management of the hierarchy, so configfs uses the subsystem semaphore to | 329 | management of the hierarchy, so configfs uses the subsystem mutex to |
318 | protect modifications. Whenever a subsystem wants to navigate the | 330 | protect modifications. Whenever a subsystem wants to navigate the |
319 | hierarchy, it must do so under the protection of the subsystem | 331 | hierarchy, it must do so under the protection of the subsystem |
320 | semaphore. | 332 | mutex. |
321 | 333 | ||
322 | A subsystem will be prevented from acquiring the semaphore while a newly | 334 | A subsystem will be prevented from acquiring the mutex while a newly |
323 | allocated item has not been linked into this hierarchy. Similarly, it | 335 | allocated item has not been linked into this hierarchy. Similarly, it |
324 | will not be able to acquire the semaphore while a dropping item has not | 336 | will not be able to acquire the mutex while a dropping item has not |
325 | yet been unlinked. This means that an item's ci_parent pointer will | 337 | yet been unlinked. This means that an item's ci_parent pointer will |
326 | never be NULL while the item is in configfs, and that an item will only | 338 | never be NULL while the item is in configfs, and that an item will only |
327 | be in its parent's cg_children list for the same duration. This allows | 339 | be in its parent's cg_children list for the same duration. This allows |
328 | a subsystem to trust ci_parent and cg_children while they hold the | 340 | a subsystem to trust ci_parent and cg_children while they hold the |
329 | semaphore. | 341 | mutex. |
330 | 342 | ||
331 | [Item Aggregation Via symlink(2)] | 343 | [Item Aggregation Via symlink(2)] |
332 | 344 | ||
@@ -386,6 +398,33 @@ As a consequence of this, default_groups cannot be removed directly via | |||
386 | rmdir(2). They also are not considered when rmdir(2) on the parent | 398 | rmdir(2). They also are not considered when rmdir(2) on the parent |
387 | group is checking for children. | 399 | group is checking for children. |
388 | 400 | ||
401 | [Dependant Subsystems] | ||
402 | |||
403 | Sometimes other drivers depend on particular configfs items. For | ||
404 | example, ocfs2 mounts depend on a heartbeat region item. If that | ||
405 | region item is removed with rmdir(2), the ocfs2 mount must BUG or go | ||
406 | readonly. Not happy. | ||
407 | |||
408 | configfs provides two additional API calls: configfs_depend_item() and | ||
409 | configfs_undepend_item(). A client driver can call | ||
410 | configfs_depend_item() on an existing item to tell configfs that it is | ||
411 | depended on. configfs will then return -EBUSY from rmdir(2) for that | ||
412 | item. When the item is no longer depended on, the client driver calls | ||
413 | configfs_undepend_item() on it. | ||
414 | |||
415 | These API cannot be called underneath any configfs callbacks, as | ||
416 | they will conflict. They can block and allocate. A client driver | ||
417 | probably shouldn't calling them of its own gumption. Rather it should | ||
418 | be providing an API that external subsystems call. | ||
419 | |||
420 | How does this work? Imagine the ocfs2 mount process. When it mounts, | ||
421 | it asks for a heartbeat region item. This is done via a call into the | ||
422 | heartbeat code. Inside the heartbeat code, the region item is looked | ||
423 | up. Here, the heartbeat code calls configfs_depend_item(). If it | ||
424 | succeeds, then heartbeat knows the region is safe to give to ocfs2. | ||
425 | If it fails, it was being torn down anyway, and heartbeat can gracefully | ||
426 | pass up an error. | ||
427 | |||
389 | [Committable Items] | 428 | [Committable Items] |
390 | 429 | ||
391 | NOTE: Committable items are currently unimplemented. | 430 | NOTE: Committable items are currently unimplemented. |
diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c index 2d6a14a463e0..e56d49264b39 100644 --- a/Documentation/filesystems/configfs/configfs_example.c +++ b/Documentation/filesystems/configfs/configfs_example.c | |||
@@ -453,7 +453,7 @@ static int __init configfs_example_init(void) | |||
453 | subsys = example_subsys[i]; | 453 | subsys = example_subsys[i]; |
454 | 454 | ||
455 | config_group_init(&subsys->su_group); | 455 | config_group_init(&subsys->su_group); |
456 | init_MUTEX(&subsys->su_sem); | 456 | mutex_init(&subsys->su_mutex); |
457 | ret = configfs_register_subsystem(subsys); | 457 | ret = configfs_register_subsystem(subsys); |
458 | if (ret) { | 458 | if (ret) { |
459 | printk(KERN_ERR "Error %d while registering subsystem %s\n", | 459 | printk(KERN_ERR "Error %d while registering subsystem %s\n", |