Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207628
b: refs/heads/master
c: cac69da
h: refs/heads/master
v: v3
  • Loading branch information
Eric Paris committed Jul 28, 2010
1 parent 02eddbd commit 1802cd8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1201a5361b9bd6512ae01e6f2b7aa79d458cafb1
refs/heads/master: cac69dad32899c6f4c66bb4f9baf69b0d3c7d3d1
41 changes: 13 additions & 28 deletions trunk/fs/notify/notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,43 +289,28 @@ static void initialize_event(struct fsnotify_event *event)

/*
* Caller damn well better be holding whatever mutex is protecting the
* old_holder->event_list.
* old_holder->event_list and the new_event must be a clean event which
* cannot be found anywhere else in the kernel.
*/
int fsnotify_replace_event(struct fsnotify_event_holder *old_holder,
struct fsnotify_event *new_event)
{
struct fsnotify_event *old_event = old_holder->event;
struct fsnotify_event_holder *new_holder = NULL;
struct fsnotify_event_holder *new_holder = &new_event->holder;

enum event_spinlock_class {
SPINLOCK_OLD,
SPINLOCK_NEW,
};

/*
* There is one fsnotify_event_holder embedded inside each fsnotify_event.
* Check if we expect to be able to use that holder. If not alloc a new
* holder.
* For the overflow event it's possible that something will use the in
* event holder before we get the lock so we may need to jump back and
* alloc a new holder, this can't happen for most events...
* if the new_event's embedded holder is in use someone
* screwed up and didn't give us a clean new event.
*/
if (!list_empty(&new_event->holder.event_list)) {
alloc_holder:
new_holder = fsnotify_alloc_event_holder();
if (!new_holder)
return -ENOMEM;
}
BUG_ON(!list_empty(&new_holder->event_list));

spin_lock(&old_event->lock);
spin_lock(&new_event->lock);

if (list_empty(&new_event->holder.event_list)) {
if (unlikely(new_holder))
fsnotify_destroy_event_holder(new_holder);
new_holder = &new_event->holder;
} else if (unlikely(!new_holder)) {
/* between the time we checked above and got the lock the in
* event holder was used, go back and get a new one */
spin_unlock(&new_event->lock);
spin_unlock(&old_event->lock);
goto alloc_holder;
}
spin_lock_nested(&old_event->lock, SPINLOCK_OLD);
spin_lock_nested(&new_event->lock, SPINLOCK_NEW);

new_holder->event = new_event;
list_replace_init(&old_holder->event_list, &new_holder->event_list);
Expand Down

0 comments on commit 1802cd8

Please sign in to comment.