Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / notify / mark.c
index e14587d..54f36db 100644 (file)
@@ -112,6 +112,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
        if (atomic_dec_and_test(&mark->refcnt))
                mark->free_mark(mark);
 }
+EXPORT_SYMBOL(fsnotify_put_mark);
 
 /*
  * Any time a mark is getting freed we end up here.
@@ -135,9 +136,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
 
        mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
 
-       /* 1 from caller and 1 for being on i_list/g_list */
-       BUG_ON(atomic_read(&mark->refcnt) < 2);
-
        spin_lock(&group->mark_lock);
 
        if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
@@ -181,6 +179,11 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
        if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED))
                iput(inode);
 
+       /*
+        * We don't necessarily have a ref on mark from caller so the above iput
+        * may have already destroyed it.  Don't touch from now on.
+        */
+
        /*
         * it's possible that this group tried to destroy itself, but this
         * this mark was simultaneously being freed by inode.  If that's the
@@ -189,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
        if (unlikely(atomic_dec_and_test(&group->num_marks)))
                fsnotify_final_destroy_group(group);
 }
+EXPORT_SYMBOL(fsnotify_destroy_mark);
 
 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
 {
@@ -276,6 +280,7 @@ err:
 
        return ret;
 }
+EXPORT_SYMBOL(fsnotify_add_mark);
 
 /*
  * clear any marks in a group in which mark->flags & flags is true
@@ -331,6 +336,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
        atomic_set(&mark->refcnt, 1);
        mark->free_mark = free_mark;
 }
+EXPORT_SYMBOL(fsnotify_init_mark);
 
 static int fsnotify_mark_destroy(void *ignored)
 {