diff options
Diffstat (limited to 'fs/notify/inotify/inotify_user.c')
| -rw-r--r-- | fs/notify/inotify/inotify_user.c | 16 | 
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 472cdf29ef8..e46ca685b9b 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -546,21 +546,24 @@ retry:  	if (unlikely(!idr_pre_get(&group->inotify_data.idr, GFP_KERNEL)))  		goto out_err; +	/* we are putting the mark on the idr, take a reference */ +	fsnotify_get_mark(&tmp_ientry->fsn_entry); +  	spin_lock(&group->inotify_data.idr_lock);  	ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,  				group->inotify_data.last_wd+1,  				&tmp_ientry->wd);  	spin_unlock(&group->inotify_data.idr_lock);  	if (ret) { +		/* we didn't get on the idr, drop the idr reference */ +		fsnotify_put_mark(&tmp_ientry->fsn_entry); +  		/* idr was out of memory allocate and try again */  		if (ret == -EAGAIN)  			goto retry;  		goto out_err;  	} -	/* we put the mark on the idr, take a reference */ -	fsnotify_get_mark(&tmp_ientry->fsn_entry); -  	/* we are on the idr, now get on the inode */  	ret = fsnotify_add_mark(&tmp_ientry->fsn_entry, group, inode);  	if (ret) { @@ -578,16 +581,13 @@ retry:  	/* return the watch descriptor for this new entry */  	ret = tmp_ientry->wd; -	/* match the ref from fsnotify_init_markentry() */ -	fsnotify_put_mark(&tmp_ientry->fsn_entry); -  	/* if this mark added a new event update the group mask */  	if (mask & ~group->mask)  		fsnotify_recalc_group_mask(group);  out_err: -	if (ret < 0) -		kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry); +	/* match the ref from fsnotify_init_markentry() */ +	fsnotify_put_mark(&tmp_ientry->fsn_entry);  	return ret;  }  |