diff options
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index db7467782e8c..7d7c13872852 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -358,8 +358,8 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, __u32 mas | |||
358 | return mask & ~oldmask; | 358 | return mask & ~oldmask; |
359 | } | 359 | } |
360 | 360 | ||
361 | static struct fsnotify_mark *fanotify_add_vfsmount_mark(struct fsnotify_group *group, | 361 | static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, |
362 | struct vfsmount *mnt, __u32 mask) | 362 | struct vfsmount *mnt, __u32 mask) |
363 | { | 363 | { |
364 | struct fsnotify_mark *fsn_mark; | 364 | struct fsnotify_mark *fsn_mark; |
365 | __u32 added; | 365 | __u32 added; |
@@ -370,27 +370,28 @@ static struct fsnotify_mark *fanotify_add_vfsmount_mark(struct fsnotify_group *g | |||
370 | 370 | ||
371 | fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); | 371 | fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); |
372 | if (!fsn_mark) | 372 | if (!fsn_mark) |
373 | return ERR_PTR(-ENOMEM); | 373 | return -ENOMEM; |
374 | 374 | ||
375 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 375 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
376 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); | 376 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); |
377 | if (ret) { | 377 | if (ret) { |
378 | fanotify_free_mark(fsn_mark); | 378 | fanotify_free_mark(fsn_mark); |
379 | return ERR_PTR(ret); | 379 | return ret; |
380 | } | 380 | } |
381 | } | 381 | } |
382 | added = fanotify_mark_add_to_mask(fsn_mark, mask); | 382 | added = fanotify_mark_add_to_mask(fsn_mark, mask); |
383 | fsnotify_put_mark(fsn_mark); | ||
383 | if (added) { | 384 | if (added) { |
384 | if (added & ~group->mask) | 385 | if (added & ~group->mask) |
385 | fsnotify_recalc_group_mask(group); | 386 | fsnotify_recalc_group_mask(group); |
386 | if (added & ~mnt->mnt_fsnotify_mask) | 387 | if (added & ~mnt->mnt_fsnotify_mask) |
387 | fsnotify_recalc_vfsmount_mask(mnt); | 388 | fsnotify_recalc_vfsmount_mask(mnt); |
388 | } | 389 | } |
389 | return fsn_mark; | 390 | return 0; |
390 | } | 391 | } |
391 | 392 | ||
392 | static struct fsnotify_mark *fanotify_add_inode_mark(struct fsnotify_group *group, | 393 | static int fanotify_add_inode_mark(struct fsnotify_group *group, |
393 | struct inode *inode, __u32 mask) | 394 | struct inode *inode, __u32 mask) |
394 | { | 395 | { |
395 | struct fsnotify_mark *fsn_mark; | 396 | struct fsnotify_mark *fsn_mark; |
396 | __u32 added; | 397 | __u32 added; |
@@ -403,29 +404,30 @@ static struct fsnotify_mark *fanotify_add_inode_mark(struct fsnotify_group *grou | |||
403 | 404 | ||
404 | fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); | 405 | fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); |
405 | if (!fsn_mark) | 406 | if (!fsn_mark) |
406 | return ERR_PTR(-ENOMEM); | 407 | return -ENOMEM; |
407 | 408 | ||
408 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 409 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
409 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); | 410 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); |
410 | if (ret) { | 411 | if (ret) { |
411 | fanotify_free_mark(fsn_mark); | 412 | fanotify_free_mark(fsn_mark); |
412 | return ERR_PTR(ret); | 413 | return ret; |
413 | } | 414 | } |
414 | } | 415 | } |
415 | added = fanotify_mark_add_to_mask(fsn_mark, mask); | 416 | added = fanotify_mark_add_to_mask(fsn_mark, mask); |
417 | fsnotify_put_mark(fsn_mark); | ||
416 | if (added) { | 418 | if (added) { |
417 | if (added & ~group->mask) | 419 | if (added & ~group->mask) |
418 | fsnotify_recalc_group_mask(group); | 420 | fsnotify_recalc_group_mask(group); |
419 | if (added & ~inode->i_fsnotify_mask) | 421 | if (added & ~inode->i_fsnotify_mask) |
420 | fsnotify_recalc_inode_mask(inode); | 422 | fsnotify_recalc_inode_mask(inode); |
421 | } | 423 | } |
422 | return fsn_mark; | 424 | return 0; |
423 | } | 425 | } |
424 | 426 | ||
425 | static int fanotify_add_mark(struct fsnotify_group *group, struct inode *inode, | 427 | static int fanotify_add_mark(struct fsnotify_group *group, struct inode *inode, |
426 | struct vfsmount *mnt, __u32 mask) | 428 | struct vfsmount *mnt, __u32 mask) |
427 | { | 429 | { |
428 | struct fsnotify_mark *fsn_mark; | 430 | int ret; |
429 | 431 | ||
430 | pr_debug("%s: group=%p inode=%p mnt=%p mask=%x\n", | 432 | pr_debug("%s: group=%p inode=%p mnt=%p mask=%x\n", |
431 | __func__, group, inode, mnt, mask); | 433 | __func__, group, inode, mnt, mask); |
@@ -434,19 +436,13 @@ static int fanotify_add_mark(struct fsnotify_group *group, struct inode *inode, | |||
434 | BUG_ON(!inode && !mnt); | 436 | BUG_ON(!inode && !mnt); |
435 | 437 | ||
436 | if (inode) | 438 | if (inode) |
437 | fsn_mark = fanotify_add_inode_mark(group, inode, mask); | 439 | ret = fanotify_add_inode_mark(group, inode, mask); |
438 | else if (mnt) | 440 | else if (mnt) |
439 | fsn_mark = fanotify_add_vfsmount_mark(group, mnt, mask); | 441 | ret = fanotify_add_vfsmount_mark(group, mnt, mask); |
440 | else | 442 | else |
441 | BUG(); | 443 | BUG(); |
442 | 444 | ||
443 | if (IS_ERR(fsn_mark)) | 445 | return ret; |
444 | goto out; | ||
445 | |||
446 | /* match the init or the find.... */ | ||
447 | fsnotify_put_mark(fsn_mark); | ||
448 | out: | ||
449 | return PTR_ERR(fsn_mark); | ||
450 | } | 446 | } |
451 | 447 | ||
452 | static bool fanotify_mark_validate_input(int flags, | 448 | static bool fanotify_mark_validate_input(int flags, |