aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/inode_mark.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-12-17 21:24:33 -0500
committerEric Paris <eparis@redhat.com>2010-07-28 09:58:59 -0400
commit90b1e7a57880fb66437ab7db39e1e65ca0372822 (patch)
tree61b7195c84d9dfd057ed3dcb07c5fc831db6a3a9 /fs/notify/inode_mark.c
parent33d3dfff451a2ab6fe2f6aaabed9b24e91aad109 (diff)
fsnotify: allow marks to not pin inodes in core
inotify marks must pin inodes in core. dnotify doesn't technically need to since they are closed when the directory is closed. fanotify also need to pin inodes in core as it works today. But the next step is to introduce the concept of 'ignored masks' which is actually a mask of events for an inode of no interest. I claim that these should be liberally sent to the kernel and should not pin the inode in core. If the inode is brought back in the listener will get an event it may have thought excluded, but this is not a serious situation and one any listener should deal with. This patch lays the ground work for non-pinning inode marks by using lazy inode pinning. We do not pin a mark until it has a non-zero mask entry. If a listener new sets a mask we never pin the inode. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify/inode_mark.c')
-rw-r--r--fs/notify/inode_mark.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index c925579ba011..4292f9e23ae8 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -141,7 +141,32 @@ struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group,
141} 141}
142 142
143/* 143/*
144 * Attach an initialized mark mark to a given group and inode. 144 * If we are setting a mark mask on an inode mark we should pin the inode
145 * in memory.
146 */
147void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *mark,
148 __u32 mask)
149{
150 struct inode *inode;
151
152 assert_spin_locked(&mark->lock);
153
154 if (mask &&
155 mark->i.inode &&
156 !(mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) {
157 mark->flags |= FSNOTIFY_MARK_FLAG_OBJECT_PINNED;
158 inode = igrab(mark->i.inode);
159 /*
160 * we shouldn't be able to get here if the inode wasn't
161 * already safely held in memory. But bug in case it
162 * ever is wrong.
163 */
164 BUG_ON(!inode);
165 }
166}
167
168/*
169 * Attach an initialized mark to a given group and inode.
145 * These marks may be used for the fsnotify backend to determine which 170 * These marks may be used for the fsnotify backend to determine which
146 * event types should be delivered to which group and for which inodes. 171 * event types should be delivered to which group and for which inodes.
147 */ 172 */
@@ -152,10 +177,6 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
152 struct fsnotify_mark *lmark = NULL; 177 struct fsnotify_mark *lmark = NULL;
153 int ret = 0; 178 int ret = 0;
154 179
155 inode = igrab(inode);
156 if (unlikely(!inode))
157 return -EINVAL;
158
159 mark->flags = FSNOTIFY_MARK_FLAG_INODE; 180 mark->flags = FSNOTIFY_MARK_FLAG_INODE;
160 181
161 assert_spin_locked(&mark->lock); 182 assert_spin_locked(&mark->lock);
@@ -175,10 +196,8 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
175 196
176 spin_unlock(&inode->i_lock); 197 spin_unlock(&inode->i_lock);
177 198
178 if (lmark) { 199 if (lmark)
179 ret = -EEXIST; 200 ret = -EEXIST;
180 iput(inode);
181 }
182 201
183 return ret; 202 return ret;
184} 203}