diff options
| author | Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> | 2009-03-07 13:12:32 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-03-27 14:44:04 -0400 |
| commit | 1bd7903560f1f713e85188a5aaf4d2428b6c8b50 (patch) | |
| tree | 0b6faa6cb51effe327dfecbd6a05e7a3b50debfe /fs/devpts | |
| parent | 289f00e225a6f60056644e0fd7e4081cb140c631 (diff) | |
Merge code for single and multiple-instance mounts
new_pts_mount() (including the get_sb_nodev()), shares a lot of code
with init_pts_mount(). The only difference between them is the 'test-super'
function passed into sget().
Move all common code into devpts_get_sb() and remove the new_pts_mount() and
init_pts_mount() functions,
Changelog[v3]:
[Serge Hallyn]: Remove unnecessary printk()s
Changelog[v2]:
(Christoph Hellwig): Merge code in 'do_pts_mount()' into devpts_get_sb()
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Tested-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/devpts')
| -rw-r--r-- | fs/devpts/inode.c | 113 |
1 files changed, 40 insertions, 73 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 9c775fa4130f..63a4a59e4148 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
| @@ -322,85 +322,38 @@ static int compare_init_pts_sb(struct super_block *s, void *p) | |||
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | /* | 324 | /* |
| 325 | * Mount a new (private) instance of devpts. PTYs created in this | 325 | * devpts_get_sb() |
| 326 | * instance are independent of the PTYs in other devpts instances. | 326 | * |
| 327 | */ | 327 | * If the '-o newinstance' mount option was specified, mount a new |
| 328 | static int new_pts_mount(struct file_system_type *fs_type, int flags, | 328 | * (private) instance of devpts. PTYs created in this instance are |
| 329 | void *data, struct pts_mount_opts *opts, struct vfsmount *mnt) | 329 | * independent of the PTYs in other devpts instances. |
| 330 | { | 330 | * |
| 331 | int err; | 331 | * If the '-o newinstance' option was not specified, mount/remount the |
| 332 | struct pts_fs_info *fsi; | 332 | * initial kernel mount of devpts. This type of mount gives the |
| 333 | 333 | * legacy, single-instance semantics. | |
| 334 | err = get_sb_nodev(fs_type, flags, data, devpts_fill_super, mnt); | ||
| 335 | if (err) | ||
| 336 | return err; | ||
| 337 | |||
| 338 | fsi = DEVPTS_SB(mnt->mnt_sb); | ||
| 339 | memcpy(&fsi->mount_opts, opts, sizeof(opts)); | ||
| 340 | |||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 345 | * init_pts_mount() | ||
| 346 | * | 334 | * |
| 347 | * Mount or remount the initial kernel mount of devpts. This type of | 335 | * The 'newinstance' option is needed to support multiple namespace |
| 348 | * mount maintains the legacy, single-instance semantics, while the | 336 | * semantics in devpts while preserving backward compatibility of the |
| 349 | * kernel still allows multiple-instances. | 337 | * current 'single-namespace' semantics. i.e all mounts of devpts |
| 338 | * without the 'newinstance' mount option should bind to the initial | ||
| 339 | * kernel mount, like get_sb_single(). | ||
| 350 | * | 340 | * |
| 351 | * This interface is needed to support multiple namespace semantics in | 341 | * Mounts with 'newinstance' option create a new, private namespace. |
| 352 | * devpts while preserving backward compatibility of the current 'single- | ||
| 353 | * namespace' semantics. i.e all mounts of devpts without the 'newinstance' | ||
| 354 | * mount option should bind to the initial kernel mount, like | ||
| 355 | * get_sb_single(). | ||
| 356 | * | 342 | * |
| 357 | * Mounts with 'newinstance' option create a new private namespace. | 343 | * NOTE: |
| 358 | * | 344 | * |
| 359 | * But for single-mount semantics, devpts cannot use get_sb_single(), | 345 | * For single-mount semantics, devpts cannot use get_sb_single(), |
| 360 | * because get_sb_single()/sget() find and use the super-block from | 346 | * because get_sb_single()/sget() find and use the super-block from |
| 361 | * the most recent mount of devpts. But that recent mount may be a | 347 | * the most recent mount of devpts. But that recent mount may be a |
| 362 | * 'newinstance' mount and get_sb_single() would pick the newinstance | 348 | * 'newinstance' mount and get_sb_single() would pick the newinstance |
| 363 | * super-block instead of the initial super-block. | 349 | * super-block instead of the initial super-block. |
| 364 | * | ||
| 365 | * This interface is identical to get_sb_single() except that it | ||
| 366 | * consistently selects the 'single-namespace' superblock even in the | ||
| 367 | * presence of the private namespace (i.e 'newinstance') super-blocks. | ||
| 368 | */ | 350 | */ |
| 369 | static int init_pts_mount(struct file_system_type *fs_type, int flags, | ||
| 370 | void *data, struct pts_mount_opts *opts, struct vfsmount *mnt) | ||
| 371 | { | ||
| 372 | struct super_block *s; | ||
| 373 | struct pts_fs_info *fsi; | ||
| 374 | int error; | ||
| 375 | |||
| 376 | s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); | ||
| 377 | if (IS_ERR(s)) | ||
| 378 | return PTR_ERR(s); | ||
| 379 | |||
| 380 | if (!s->s_root) { | ||
| 381 | s->s_flags = flags; | ||
| 382 | error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0); | ||
| 383 | if (error) { | ||
| 384 | up_write(&s->s_umount); | ||
| 385 | deactivate_super(s); | ||
| 386 | return error; | ||
| 387 | } | ||
| 388 | s->s_flags |= MS_ACTIVE; | ||
| 389 | } | ||
| 390 | |||
| 391 | simple_set_mnt(mnt, s); | ||
| 392 | |||
| 393 | fsi = DEVPTS_SB(mnt->mnt_sb); | ||
| 394 | memcpy(&fsi->mount_opts, opts, sizeof(opts)); | ||
| 395 | |||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | static int devpts_get_sb(struct file_system_type *fs_type, | 351 | static int devpts_get_sb(struct file_system_type *fs_type, |
| 400 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 352 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
| 401 | { | 353 | { |
| 402 | int error; | 354 | int error; |
| 403 | struct pts_mount_opts opts; | 355 | struct pts_mount_opts opts; |
| 356 | struct super_block *s; | ||
| 404 | 357 | ||
| 405 | memset(&opts, 0, sizeof(opts)); | 358 | memset(&opts, 0, sizeof(opts)); |
| 406 | if (data) { | 359 | if (data) { |
| @@ -410,23 +363,37 @@ static int devpts_get_sb(struct file_system_type *fs_type, | |||
| 410 | } | 363 | } |
| 411 | 364 | ||
| 412 | if (opts.newinstance) | 365 | if (opts.newinstance) |
| 413 | error = new_pts_mount(fs_type, flags, data, &opts, mnt); | 366 | s = sget(fs_type, NULL, set_anon_super, NULL); |
| 414 | else | 367 | else |
| 415 | error = init_pts_mount(fs_type, flags, data, &opts, mnt); | 368 | s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL); |
| 416 | 369 | ||
| 417 | if (error) | 370 | if (IS_ERR(s)) |
| 418 | return error; | 371 | return PTR_ERR(s); |
| 372 | |||
| 373 | if (!s->s_root) { | ||
| 374 | s->s_flags = flags; | ||
| 375 | error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0); | ||
| 376 | if (error) | ||
| 377 | goto out_undo_sget; | ||
| 378 | s->s_flags |= MS_ACTIVE; | ||
| 379 | } | ||
| 380 | |||
| 381 | simple_set_mnt(mnt, s); | ||
| 382 | |||
| 383 | memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); | ||
| 419 | 384 | ||
| 420 | error = mknod_ptmx(mnt->mnt_sb); | 385 | error = mknod_ptmx(s); |
| 421 | if (error) | 386 | if (error) |
| 422 | goto out_dput; | 387 | goto out_dput; |
| 423 | 388 | ||
| 424 | return 0; | 389 | return 0; |
| 425 | 390 | ||
| 426 | out_dput: | 391 | out_dput: |
| 427 | dput(mnt->mnt_sb->s_root); | 392 | dput(s->s_root); |
| 428 | up_write(&mnt->mnt_sb->s_umount); | 393 | |
| 429 | deactivate_super(mnt->mnt_sb); | 394 | out_undo_sget: |
| 395 | up_write(&s->s_umount); | ||
| 396 | deactivate_super(s); | ||
| 430 | return error; | 397 | return error; |
| 431 | } | 398 | } |
| 432 | 399 | ||
