diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 589 |
1 files changed, 230 insertions, 359 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index edf5b6bddb52..bcfb2dc0a61b 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -25,25 +25,25 @@ static int autofs4_dir_rmdir(struct inode *,struct dentry *); | |||
25 | static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); | 25 | static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); |
26 | static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); | 26 | static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); |
27 | static int autofs4_dir_open(struct inode *inode, struct file *file); | 27 | static int autofs4_dir_open(struct inode *inode, struct file *file); |
28 | static int autofs4_dir_close(struct inode *inode, struct file *file); | ||
29 | static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir); | ||
30 | static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir); | ||
31 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); | 28 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); |
32 | static void *autofs4_follow_link(struct dentry *, struct nameidata *); | 29 | static void *autofs4_follow_link(struct dentry *, struct nameidata *); |
33 | 30 | ||
31 | #define TRIGGER_FLAGS (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) | ||
32 | #define TRIGGER_INTENTS (LOOKUP_OPEN | LOOKUP_CREATE) | ||
33 | |||
34 | const struct file_operations autofs4_root_operations = { | 34 | const struct file_operations autofs4_root_operations = { |
35 | .open = dcache_dir_open, | 35 | .open = dcache_dir_open, |
36 | .release = dcache_dir_close, | 36 | .release = dcache_dir_close, |
37 | .read = generic_read_dir, | 37 | .read = generic_read_dir, |
38 | .readdir = autofs4_root_readdir, | 38 | .readdir = dcache_readdir, |
39 | .ioctl = autofs4_root_ioctl, | 39 | .ioctl = autofs4_root_ioctl, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | const struct file_operations autofs4_dir_operations = { | 42 | const struct file_operations autofs4_dir_operations = { |
43 | .open = autofs4_dir_open, | 43 | .open = autofs4_dir_open, |
44 | .release = autofs4_dir_close, | 44 | .release = dcache_dir_close, |
45 | .read = generic_read_dir, | 45 | .read = generic_read_dir, |
46 | .readdir = autofs4_dir_readdir, | 46 | .readdir = dcache_readdir, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | const struct inode_operations autofs4_indirect_root_inode_operations = { | 49 | const struct inode_operations autofs4_indirect_root_inode_operations = { |
@@ -70,42 +70,10 @@ const struct inode_operations autofs4_dir_inode_operations = { | |||
70 | .rmdir = autofs4_dir_rmdir, | 70 | .rmdir = autofs4_dir_rmdir, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static int autofs4_root_readdir(struct file *file, void *dirent, | ||
74 | filldir_t filldir) | ||
75 | { | ||
76 | struct autofs_sb_info *sbi = autofs4_sbi(file->f_path.dentry->d_sb); | ||
77 | int oz_mode = autofs4_oz_mode(sbi); | ||
78 | |||
79 | DPRINTK("called, filp->f_pos = %lld", file->f_pos); | ||
80 | |||
81 | /* | ||
82 | * Don't set reghost flag if: | ||
83 | * 1) f_pos is larger than zero -- we've already been here. | ||
84 | * 2) we haven't even enabled reghosting in the 1st place. | ||
85 | * 3) this is the daemon doing a readdir | ||
86 | */ | ||
87 | if (oz_mode && file->f_pos == 0 && sbi->reghost_enabled) | ||
88 | sbi->needs_reghost = 1; | ||
89 | |||
90 | DPRINTK("needs_reghost = %d", sbi->needs_reghost); | ||
91 | |||
92 | return dcache_readdir(file, dirent, filldir); | ||
93 | } | ||
94 | |||
95 | static int autofs4_dir_open(struct inode *inode, struct file *file) | 73 | static int autofs4_dir_open(struct inode *inode, struct file *file) |
96 | { | 74 | { |
97 | struct dentry *dentry = file->f_path.dentry; | 75 | struct dentry *dentry = file->f_path.dentry; |
98 | struct vfsmount *mnt = file->f_path.mnt; | ||
99 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 76 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
100 | struct dentry *cursor; | ||
101 | int status; | ||
102 | |||
103 | status = dcache_dir_open(inode, file); | ||
104 | if (status) | ||
105 | goto out; | ||
106 | |||
107 | cursor = file->private_data; | ||
108 | cursor->d_fsdata = NULL; | ||
109 | 77 | ||
110 | DPRINTK("file=%p dentry=%p %.*s", | 78 | DPRINTK("file=%p dentry=%p %.*s", |
111 | file, dentry, dentry->d_name.len, dentry->d_name.name); | 79 | file, dentry, dentry->d_name.len, dentry->d_name.name); |
@@ -113,159 +81,32 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
113 | if (autofs4_oz_mode(sbi)) | 81 | if (autofs4_oz_mode(sbi)) |
114 | goto out; | 82 | goto out; |
115 | 83 | ||
116 | if (autofs4_ispending(dentry)) { | 84 | /* |
117 | DPRINTK("dentry busy"); | 85 | * An empty directory in an autofs file system is always a |
118 | dcache_dir_close(inode, file); | 86 | * mount point. The daemon must have failed to mount this |
119 | status = -EBUSY; | 87 | * during lookup so it doesn't exist. This can happen, for |
120 | goto out; | 88 | * example, if user space returns an incorrect status for a |
121 | } | 89 | * mount request. Otherwise we're doing a readdir on the |
122 | 90 | * autofs file system so just let the libfs routines handle | |
123 | status = -ENOENT; | 91 | * it. |
124 | if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) { | 92 | */ |
125 | struct nameidata nd; | 93 | spin_lock(&dcache_lock); |
126 | int empty, ret; | 94 | if (!d_mountpoint(dentry) && __simple_empty(dentry)) { |
127 | |||
128 | /* In case there are stale directory dentrys from a failed mount */ | ||
129 | spin_lock(&dcache_lock); | ||
130 | empty = list_empty(&dentry->d_subdirs); | ||
131 | spin_unlock(&dcache_lock); | 95 | spin_unlock(&dcache_lock); |
132 | 96 | return -ENOENT; | |
133 | if (!empty) | ||
134 | d_invalidate(dentry); | ||
135 | |||
136 | nd.flags = LOOKUP_DIRECTORY; | ||
137 | ret = (dentry->d_op->d_revalidate)(dentry, &nd); | ||
138 | |||
139 | if (ret <= 0) { | ||
140 | if (ret < 0) | ||
141 | status = ret; | ||
142 | dcache_dir_close(inode, file); | ||
143 | goto out; | ||
144 | } | ||
145 | } | 97 | } |
98 | spin_unlock(&dcache_lock); | ||
146 | 99 | ||
147 | if (d_mountpoint(dentry)) { | ||
148 | struct file *fp = NULL; | ||
149 | struct path fp_path = { .dentry = dentry, .mnt = mnt }; | ||
150 | |||
151 | path_get(&fp_path); | ||
152 | |||
153 | if (!autofs4_follow_mount(&fp_path.mnt, &fp_path.dentry)) { | ||
154 | path_put(&fp_path); | ||
155 | dcache_dir_close(inode, file); | ||
156 | goto out; | ||
157 | } | ||
158 | |||
159 | fp = dentry_open(fp_path.dentry, fp_path.mnt, file->f_flags); | ||
160 | status = PTR_ERR(fp); | ||
161 | if (IS_ERR(fp)) { | ||
162 | dcache_dir_close(inode, file); | ||
163 | goto out; | ||
164 | } | ||
165 | cursor->d_fsdata = fp; | ||
166 | } | ||
167 | return 0; | ||
168 | out: | ||
169 | return status; | ||
170 | } | ||
171 | |||
172 | static int autofs4_dir_close(struct inode *inode, struct file *file) | ||
173 | { | ||
174 | struct dentry *dentry = file->f_path.dentry; | ||
175 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
176 | struct dentry *cursor = file->private_data; | ||
177 | int status = 0; | ||
178 | |||
179 | DPRINTK("file=%p dentry=%p %.*s", | ||
180 | file, dentry, dentry->d_name.len, dentry->d_name.name); | ||
181 | |||
182 | if (autofs4_oz_mode(sbi)) | ||
183 | goto out; | ||
184 | |||
185 | if (autofs4_ispending(dentry)) { | ||
186 | DPRINTK("dentry busy"); | ||
187 | status = -EBUSY; | ||
188 | goto out; | ||
189 | } | ||
190 | |||
191 | if (d_mountpoint(dentry)) { | ||
192 | struct file *fp = cursor->d_fsdata; | ||
193 | if (!fp) { | ||
194 | status = -ENOENT; | ||
195 | goto out; | ||
196 | } | ||
197 | filp_close(fp, current->files); | ||
198 | } | ||
199 | out: | ||
200 | dcache_dir_close(inode, file); | ||
201 | return status; | ||
202 | } | ||
203 | |||
204 | static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir) | ||
205 | { | ||
206 | struct dentry *dentry = file->f_path.dentry; | ||
207 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
208 | struct dentry *cursor = file->private_data; | ||
209 | int status; | ||
210 | |||
211 | DPRINTK("file=%p dentry=%p %.*s", | ||
212 | file, dentry, dentry->d_name.len, dentry->d_name.name); | ||
213 | |||
214 | if (autofs4_oz_mode(sbi)) | ||
215 | goto out; | ||
216 | |||
217 | if (autofs4_ispending(dentry)) { | ||
218 | DPRINTK("dentry busy"); | ||
219 | return -EBUSY; | ||
220 | } | ||
221 | |||
222 | if (d_mountpoint(dentry)) { | ||
223 | struct file *fp = cursor->d_fsdata; | ||
224 | |||
225 | if (!fp) | ||
226 | return -ENOENT; | ||
227 | |||
228 | if (!fp->f_op || !fp->f_op->readdir) | ||
229 | goto out; | ||
230 | |||
231 | status = vfs_readdir(fp, filldir, dirent); | ||
232 | file->f_pos = fp->f_pos; | ||
233 | if (status) | ||
234 | autofs4_copy_atime(file, fp); | ||
235 | return status; | ||
236 | } | ||
237 | out: | 100 | out: |
238 | return dcache_readdir(file, dirent, filldir); | 101 | return dcache_dir_open(inode, file); |
239 | } | 102 | } |
240 | 103 | ||
241 | static int try_to_fill_dentry(struct dentry *dentry, int flags) | 104 | static int try_to_fill_dentry(struct dentry *dentry, int flags) |
242 | { | 105 | { |
243 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 106 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
244 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 107 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
245 | struct dentry *new; | ||
246 | int status; | 108 | int status; |
247 | 109 | ||
248 | /* Block on any pending expiry here; invalidate the dentry | ||
249 | when expiration is done to trigger mount request with a new | ||
250 | dentry */ | ||
251 | if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { | ||
252 | DPRINTK("waiting for expire %p name=%.*s", | ||
253 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
254 | |||
255 | status = autofs4_wait(sbi, dentry, NFY_NONE); | ||
256 | |||
257 | DPRINTK("expire done status=%d", status); | ||
258 | |||
259 | /* | ||
260 | * If the directory still exists the mount request must | ||
261 | * continue otherwise it can't be followed at the right | ||
262 | * time during the walk. | ||
263 | */ | ||
264 | status = d_invalidate(dentry); | ||
265 | if (status != -EBUSY) | ||
266 | return -EAGAIN; | ||
267 | } | ||
268 | |||
269 | DPRINTK("dentry=%p %.*s ino=%p", | 110 | DPRINTK("dentry=%p %.*s ino=%p", |
270 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | 111 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); |
271 | 112 | ||
@@ -292,7 +133,8 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) | |||
292 | return status; | 133 | return status; |
293 | } | 134 | } |
294 | /* Trigger mount for path component or follow link */ | 135 | /* Trigger mount for path component or follow link */ |
295 | } else if (flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) || | 136 | } else if (dentry->d_flags & DCACHE_AUTOFS_PENDING || |
137 | flags & (TRIGGER_FLAGS | TRIGGER_INTENTS) || | ||
296 | current->link_count) { | 138 | current->link_count) { |
297 | DPRINTK("waiting for mount name=%.*s", | 139 | DPRINTK("waiting for mount name=%.*s", |
298 | dentry->d_name.len, dentry->d_name.name); | 140 | dentry->d_name.len, dentry->d_name.name); |
@@ -320,26 +162,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) | |||
320 | dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; | 162 | dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; |
321 | spin_unlock(&dentry->d_lock); | 163 | spin_unlock(&dentry->d_lock); |
322 | 164 | ||
323 | /* | ||
324 | * The dentry that is passed in from lookup may not be the one | ||
325 | * we end up using, as mkdir can create a new one. If this | ||
326 | * happens, and another process tries the lookup at the same time, | ||
327 | * it will set the PENDING flag on this new dentry, but add itself | ||
328 | * to our waitq. Then, if after the lookup succeeds, the first | ||
329 | * process that requested the mount performs another lookup of the | ||
330 | * same directory, it will show up as still pending! So, we need | ||
331 | * to redo the lookup here and clear pending on that dentry. | ||
332 | */ | ||
333 | if (d_unhashed(dentry)) { | ||
334 | new = d_lookup(dentry->d_parent, &dentry->d_name); | ||
335 | if (new) { | ||
336 | spin_lock(&new->d_lock); | ||
337 | new->d_flags &= ~DCACHE_AUTOFS_PENDING; | ||
338 | spin_unlock(&new->d_lock); | ||
339 | dput(new); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | return 0; | 165 | return 0; |
344 | } | 166 | } |
345 | 167 | ||
@@ -355,51 +177,63 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
355 | DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d", | 177 | DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d", |
356 | dentry, dentry->d_name.len, dentry->d_name.name, oz_mode, | 178 | dentry, dentry->d_name.len, dentry->d_name.name, oz_mode, |
357 | nd->flags); | 179 | nd->flags); |
358 | 180 | /* | |
359 | /* If it's our master or we shouldn't trigger a mount we're done */ | 181 | * For an expire of a covered direct or offset mount we need |
360 | lookup_type = nd->flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY); | 182 | * to beeak out of follow_down() at the autofs mount trigger |
361 | if (oz_mode || !lookup_type) | 183 | * (d_mounted--), so we can see the expiring flag, and manage |
184 | * the blocking and following here until the expire is completed. | ||
185 | */ | ||
186 | if (oz_mode) { | ||
187 | spin_lock(&sbi->fs_lock); | ||
188 | if (ino->flags & AUTOFS_INF_EXPIRING) { | ||
189 | spin_unlock(&sbi->fs_lock); | ||
190 | /* Follow down to our covering mount. */ | ||
191 | if (!follow_down(&nd->path.mnt, &nd->path.dentry)) | ||
192 | goto done; | ||
193 | goto follow; | ||
194 | } | ||
195 | spin_unlock(&sbi->fs_lock); | ||
362 | goto done; | 196 | goto done; |
197 | } | ||
363 | 198 | ||
364 | /* If an expire request is pending wait for it. */ | 199 | /* If an expire request is pending everyone must wait. */ |
365 | if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { | 200 | autofs4_expire_wait(dentry); |
366 | DPRINTK("waiting for active request %p name=%.*s", | ||
367 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
368 | |||
369 | status = autofs4_wait(sbi, dentry, NFY_NONE); | ||
370 | 201 | ||
371 | DPRINTK("request done status=%d", status); | 202 | /* We trigger a mount for almost all flags */ |
372 | } | 203 | lookup_type = nd->flags & (TRIGGER_FLAGS | TRIGGER_INTENTS); |
204 | if (!(lookup_type || dentry->d_flags & DCACHE_AUTOFS_PENDING)) | ||
205 | goto follow; | ||
373 | 206 | ||
374 | /* | 207 | /* |
375 | * If the dentry contains directories then it is an | 208 | * If the dentry contains directories then it is an autofs |
376 | * autofs multi-mount with no root mount offset. So | 209 | * multi-mount with no root mount offset. So don't try to |
377 | * don't try to mount it again. | 210 | * mount it again. |
378 | */ | 211 | */ |
379 | spin_lock(&dcache_lock); | 212 | spin_lock(&dcache_lock); |
380 | if (!d_mountpoint(dentry) && __simple_empty(dentry)) { | 213 | if (dentry->d_flags & DCACHE_AUTOFS_PENDING || |
214 | (!d_mountpoint(dentry) && __simple_empty(dentry))) { | ||
381 | spin_unlock(&dcache_lock); | 215 | spin_unlock(&dcache_lock); |
382 | 216 | ||
383 | status = try_to_fill_dentry(dentry, 0); | 217 | status = try_to_fill_dentry(dentry, 0); |
384 | if (status) | 218 | if (status) |
385 | goto out_error; | 219 | goto out_error; |
386 | 220 | ||
387 | /* | 221 | goto follow; |
388 | * The mount succeeded but if there is no root mount | ||
389 | * it must be an autofs multi-mount with no root offset | ||
390 | * so we don't need to follow the mount. | ||
391 | */ | ||
392 | if (d_mountpoint(dentry)) { | ||
393 | if (!autofs4_follow_mount(&nd->path.mnt, | ||
394 | &nd->path.dentry)) { | ||
395 | status = -ENOENT; | ||
396 | goto out_error; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | goto done; | ||
401 | } | 222 | } |
402 | spin_unlock(&dcache_lock); | 223 | spin_unlock(&dcache_lock); |
224 | follow: | ||
225 | /* | ||
226 | * If there is no root mount it must be an autofs | ||
227 | * multi-mount with no root offset so we don't need | ||
228 | * to follow it. | ||
229 | */ | ||
230 | if (d_mountpoint(dentry)) { | ||
231 | if (!autofs4_follow_mount(&nd->path.mnt, | ||
232 | &nd->path.dentry)) { | ||
233 | status = -ENOENT; | ||
234 | goto out_error; | ||
235 | } | ||
236 | } | ||
403 | 237 | ||
404 | done: | 238 | done: |
405 | return NULL; | 239 | return NULL; |
@@ -424,12 +258,23 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
424 | int status = 1; | 258 | int status = 1; |
425 | 259 | ||
426 | /* Pending dentry */ | 260 | /* Pending dentry */ |
261 | spin_lock(&sbi->fs_lock); | ||
427 | if (autofs4_ispending(dentry)) { | 262 | if (autofs4_ispending(dentry)) { |
428 | /* The daemon never causes a mount to trigger */ | 263 | /* The daemon never causes a mount to trigger */ |
264 | spin_unlock(&sbi->fs_lock); | ||
265 | |||
429 | if (oz_mode) | 266 | if (oz_mode) |
430 | return 1; | 267 | return 1; |
431 | 268 | ||
432 | /* | 269 | /* |
270 | * If the directory has gone away due to an expire | ||
271 | * we have been called as ->d_revalidate() and so | ||
272 | * we need to return false and proceed to ->lookup(). | ||
273 | */ | ||
274 | if (autofs4_expire_wait(dentry) == -EAGAIN) | ||
275 | return 0; | ||
276 | |||
277 | /* | ||
433 | * A zero status is success otherwise we have a | 278 | * A zero status is success otherwise we have a |
434 | * negative error code. | 279 | * negative error code. |
435 | */ | 280 | */ |
@@ -437,17 +282,9 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
437 | if (status == 0) | 282 | if (status == 0) |
438 | return 1; | 283 | return 1; |
439 | 284 | ||
440 | /* | ||
441 | * A status of EAGAIN here means that the dentry has gone | ||
442 | * away while waiting for an expire to complete. If we are | ||
443 | * racing with expire lookup will wait for it so this must | ||
444 | * be a revalidate and we need to send it to lookup. | ||
445 | */ | ||
446 | if (status == -EAGAIN) | ||
447 | return 0; | ||
448 | |||
449 | return status; | 285 | return status; |
450 | } | 286 | } |
287 | spin_unlock(&sbi->fs_lock); | ||
451 | 288 | ||
452 | /* Negative dentry.. invalidate if "old" */ | 289 | /* Negative dentry.. invalidate if "old" */ |
453 | if (dentry->d_inode == NULL) | 290 | if (dentry->d_inode == NULL) |
@@ -461,6 +298,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
461 | DPRINTK("dentry=%p %.*s, emptydir", | 298 | DPRINTK("dentry=%p %.*s, emptydir", |
462 | dentry, dentry->d_name.len, dentry->d_name.name); | 299 | dentry, dentry->d_name.len, dentry->d_name.name); |
463 | spin_unlock(&dcache_lock); | 300 | spin_unlock(&dcache_lock); |
301 | |||
464 | /* The daemon never causes a mount to trigger */ | 302 | /* The daemon never causes a mount to trigger */ |
465 | if (oz_mode) | 303 | if (oz_mode) |
466 | return 1; | 304 | return 1; |
@@ -493,10 +331,12 @@ void autofs4_dentry_release(struct dentry *de) | |||
493 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); | 331 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); |
494 | 332 | ||
495 | if (sbi) { | 333 | if (sbi) { |
496 | spin_lock(&sbi->rehash_lock); | 334 | spin_lock(&sbi->lookup_lock); |
497 | if (!list_empty(&inf->rehash)) | 335 | if (!list_empty(&inf->active)) |
498 | list_del(&inf->rehash); | 336 | list_del(&inf->active); |
499 | spin_unlock(&sbi->rehash_lock); | 337 | if (!list_empty(&inf->expiring)) |
338 | list_del(&inf->expiring); | ||
339 | spin_unlock(&sbi->lookup_lock); | ||
500 | } | 340 | } |
501 | 341 | ||
502 | inf->dentry = NULL; | 342 | inf->dentry = NULL; |
@@ -518,7 +358,7 @@ static struct dentry_operations autofs4_dentry_operations = { | |||
518 | .d_release = autofs4_dentry_release, | 358 | .d_release = autofs4_dentry_release, |
519 | }; | 359 | }; |
520 | 360 | ||
521 | static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name) | 361 | static struct dentry *autofs4_lookup_active(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name) |
522 | { | 362 | { |
523 | unsigned int len = name->len; | 363 | unsigned int len = name->len; |
524 | unsigned int hash = name->hash; | 364 | unsigned int hash = name->hash; |
@@ -526,14 +366,66 @@ static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct | |||
526 | struct list_head *p, *head; | 366 | struct list_head *p, *head; |
527 | 367 | ||
528 | spin_lock(&dcache_lock); | 368 | spin_lock(&dcache_lock); |
529 | spin_lock(&sbi->rehash_lock); | 369 | spin_lock(&sbi->lookup_lock); |
530 | head = &sbi->rehash_list; | 370 | head = &sbi->active_list; |
531 | list_for_each(p, head) { | 371 | list_for_each(p, head) { |
532 | struct autofs_info *ino; | 372 | struct autofs_info *ino; |
533 | struct dentry *dentry; | 373 | struct dentry *dentry; |
534 | struct qstr *qstr; | 374 | struct qstr *qstr; |
535 | 375 | ||
536 | ino = list_entry(p, struct autofs_info, rehash); | 376 | ino = list_entry(p, struct autofs_info, active); |
377 | dentry = ino->dentry; | ||
378 | |||
379 | spin_lock(&dentry->d_lock); | ||
380 | |||
381 | /* Already gone? */ | ||
382 | if (atomic_read(&dentry->d_count) == 0) | ||
383 | goto next; | ||
384 | |||
385 | qstr = &dentry->d_name; | ||
386 | |||
387 | if (dentry->d_name.hash != hash) | ||
388 | goto next; | ||
389 | if (dentry->d_parent != parent) | ||
390 | goto next; | ||
391 | |||
392 | if (qstr->len != len) | ||
393 | goto next; | ||
394 | if (memcmp(qstr->name, str, len)) | ||
395 | goto next; | ||
396 | |||
397 | if (d_unhashed(dentry)) { | ||
398 | dget(dentry); | ||
399 | spin_unlock(&dentry->d_lock); | ||
400 | spin_unlock(&sbi->lookup_lock); | ||
401 | spin_unlock(&dcache_lock); | ||
402 | return dentry; | ||
403 | } | ||
404 | next: | ||
405 | spin_unlock(&dentry->d_lock); | ||
406 | } | ||
407 | spin_unlock(&sbi->lookup_lock); | ||
408 | spin_unlock(&dcache_lock); | ||
409 | |||
410 | return NULL; | ||
411 | } | ||
412 | |||
413 | static struct dentry *autofs4_lookup_expiring(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name) | ||
414 | { | ||
415 | unsigned int len = name->len; | ||
416 | unsigned int hash = name->hash; | ||
417 | const unsigned char *str = name->name; | ||
418 | struct list_head *p, *head; | ||
419 | |||
420 | spin_lock(&dcache_lock); | ||
421 | spin_lock(&sbi->lookup_lock); | ||
422 | head = &sbi->expiring_list; | ||
423 | list_for_each(p, head) { | ||
424 | struct autofs_info *ino; | ||
425 | struct dentry *dentry; | ||
426 | struct qstr *qstr; | ||
427 | |||
428 | ino = list_entry(p, struct autofs_info, expiring); | ||
537 | dentry = ino->dentry; | 429 | dentry = ino->dentry; |
538 | 430 | ||
539 | spin_lock(&dentry->d_lock); | 431 | spin_lock(&dentry->d_lock); |
@@ -555,33 +447,16 @@ static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct | |||
555 | goto next; | 447 | goto next; |
556 | 448 | ||
557 | if (d_unhashed(dentry)) { | 449 | if (d_unhashed(dentry)) { |
558 | struct inode *inode = dentry->d_inode; | ||
559 | |||
560 | ino = autofs4_dentry_ino(dentry); | ||
561 | list_del_init(&ino->rehash); | ||
562 | dget(dentry); | 450 | dget(dentry); |
563 | /* | ||
564 | * Make the rehashed dentry negative so the VFS | ||
565 | * behaves as it should. | ||
566 | */ | ||
567 | if (inode) { | ||
568 | dentry->d_inode = NULL; | ||
569 | list_del_init(&dentry->d_alias); | ||
570 | spin_unlock(&dentry->d_lock); | ||
571 | spin_unlock(&sbi->rehash_lock); | ||
572 | spin_unlock(&dcache_lock); | ||
573 | iput(inode); | ||
574 | return dentry; | ||
575 | } | ||
576 | spin_unlock(&dentry->d_lock); | 451 | spin_unlock(&dentry->d_lock); |
577 | spin_unlock(&sbi->rehash_lock); | 452 | spin_unlock(&sbi->lookup_lock); |
578 | spin_unlock(&dcache_lock); | 453 | spin_unlock(&dcache_lock); |
579 | return dentry; | 454 | return dentry; |
580 | } | 455 | } |
581 | next: | 456 | next: |
582 | spin_unlock(&dentry->d_lock); | 457 | spin_unlock(&dentry->d_lock); |
583 | } | 458 | } |
584 | spin_unlock(&sbi->rehash_lock); | 459 | spin_unlock(&sbi->lookup_lock); |
585 | spin_unlock(&dcache_lock); | 460 | spin_unlock(&dcache_lock); |
586 | 461 | ||
587 | return NULL; | 462 | return NULL; |
@@ -591,7 +466,8 @@ next: | |||
591 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 466 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
592 | { | 467 | { |
593 | struct autofs_sb_info *sbi; | 468 | struct autofs_sb_info *sbi; |
594 | struct dentry *unhashed; | 469 | struct autofs_info *ino; |
470 | struct dentry *expiring, *unhashed; | ||
595 | int oz_mode; | 471 | int oz_mode; |
596 | 472 | ||
597 | DPRINTK("name = %.*s", | 473 | DPRINTK("name = %.*s", |
@@ -607,8 +483,26 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
607 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", | 483 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", |
608 | current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); | 484 | current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); |
609 | 485 | ||
610 | unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); | 486 | expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name); |
611 | if (!unhashed) { | 487 | if (expiring) { |
488 | /* | ||
489 | * If we are racing with expire the request might not | ||
490 | * be quite complete but the directory has been removed | ||
491 | * so it must have been successful, so just wait for it. | ||
492 | */ | ||
493 | ino = autofs4_dentry_ino(expiring); | ||
494 | autofs4_expire_wait(expiring); | ||
495 | spin_lock(&sbi->lookup_lock); | ||
496 | if (!list_empty(&ino->expiring)) | ||
497 | list_del_init(&ino->expiring); | ||
498 | spin_unlock(&sbi->lookup_lock); | ||
499 | dput(expiring); | ||
500 | } | ||
501 | |||
502 | unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name); | ||
503 | if (unhashed) | ||
504 | dentry = unhashed; | ||
505 | else { | ||
612 | /* | 506 | /* |
613 | * Mark the dentry incomplete but don't hash it. We do this | 507 | * Mark the dentry incomplete but don't hash it. We do this |
614 | * to serialize our inode creation operations (symlink and | 508 | * to serialize our inode creation operations (symlink and |
@@ -622,39 +516,34 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
622 | */ | 516 | */ |
623 | dentry->d_op = &autofs4_root_dentry_operations; | 517 | dentry->d_op = &autofs4_root_dentry_operations; |
624 | 518 | ||
625 | dentry->d_fsdata = NULL; | ||
626 | d_instantiate(dentry, NULL); | ||
627 | } else { | ||
628 | struct autofs_info *ino = autofs4_dentry_ino(unhashed); | ||
629 | DPRINTK("rehash %p with %p", dentry, unhashed); | ||
630 | /* | 519 | /* |
631 | * If we are racing with expire the request might not | 520 | * And we need to ensure that the same dentry is used for |
632 | * be quite complete but the directory has been removed | 521 | * all following lookup calls until it is hashed so that |
633 | * so it must have been successful, so just wait for it. | 522 | * the dentry flags are persistent throughout the request. |
634 | * We need to ensure the AUTOFS_INF_EXPIRING flag is clear | ||
635 | * before continuing as revalidate may fail when calling | ||
636 | * try_to_fill_dentry (returning EAGAIN) if we don't. | ||
637 | */ | 523 | */ |
638 | while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { | 524 | ino = autofs4_init_ino(NULL, sbi, 0555); |
639 | DPRINTK("wait for incomplete expire %p name=%.*s", | 525 | if (!ino) |
640 | unhashed, unhashed->d_name.len, | 526 | return ERR_PTR(-ENOMEM); |
641 | unhashed->d_name.name); | 527 | |
642 | autofs4_wait(sbi, unhashed, NFY_NONE); | 528 | dentry->d_fsdata = ino; |
643 | DPRINTK("request completed"); | 529 | ino->dentry = dentry; |
644 | } | 530 | |
645 | dentry = unhashed; | 531 | spin_lock(&sbi->lookup_lock); |
532 | list_add(&ino->active, &sbi->active_list); | ||
533 | spin_unlock(&sbi->lookup_lock); | ||
534 | |||
535 | d_instantiate(dentry, NULL); | ||
646 | } | 536 | } |
647 | 537 | ||
648 | if (!oz_mode) { | 538 | if (!oz_mode) { |
649 | spin_lock(&dentry->d_lock); | 539 | spin_lock(&dentry->d_lock); |
650 | dentry->d_flags |= DCACHE_AUTOFS_PENDING; | 540 | dentry->d_flags |= DCACHE_AUTOFS_PENDING; |
651 | spin_unlock(&dentry->d_lock); | 541 | spin_unlock(&dentry->d_lock); |
652 | } | 542 | if (dentry->d_op && dentry->d_op->d_revalidate) { |
653 | 543 | mutex_unlock(&dir->i_mutex); | |
654 | if (dentry->d_op && dentry->d_op->d_revalidate) { | 544 | (dentry->d_op->d_revalidate)(dentry, nd); |
655 | mutex_unlock(&dir->i_mutex); | 545 | mutex_lock(&dir->i_mutex); |
656 | (dentry->d_op->d_revalidate)(dentry, nd); | 546 | } |
657 | mutex_lock(&dir->i_mutex); | ||
658 | } | 547 | } |
659 | 548 | ||
660 | /* | 549 | /* |
@@ -673,9 +562,11 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
673 | return ERR_PTR(-ERESTARTNOINTR); | 562 | return ERR_PTR(-ERESTARTNOINTR); |
674 | } | 563 | } |
675 | } | 564 | } |
676 | spin_lock(&dentry->d_lock); | 565 | if (!oz_mode) { |
677 | dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; | 566 | spin_lock(&dentry->d_lock); |
678 | spin_unlock(&dentry->d_lock); | 567 | dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; |
568 | spin_unlock(&dentry->d_lock); | ||
569 | } | ||
679 | } | 570 | } |
680 | 571 | ||
681 | /* | 572 | /* |
@@ -706,7 +597,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
706 | } | 597 | } |
707 | 598 | ||
708 | if (unhashed) | 599 | if (unhashed) |
709 | return dentry; | 600 | return unhashed; |
710 | 601 | ||
711 | return NULL; | 602 | return NULL; |
712 | } | 603 | } |
@@ -728,20 +619,31 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
728 | return -EACCES; | 619 | return -EACCES; |
729 | 620 | ||
730 | ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); | 621 | ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); |
731 | if (ino == NULL) | 622 | if (!ino) |
732 | return -ENOSPC; | 623 | return -ENOMEM; |
733 | 624 | ||
734 | ino->size = strlen(symname); | 625 | spin_lock(&sbi->lookup_lock); |
735 | ino->u.symlink = cp = kmalloc(ino->size + 1, GFP_KERNEL); | 626 | if (!list_empty(&ino->active)) |
627 | list_del_init(&ino->active); | ||
628 | spin_unlock(&sbi->lookup_lock); | ||
736 | 629 | ||
737 | if (cp == NULL) { | 630 | ino->size = strlen(symname); |
738 | kfree(ino); | 631 | cp = kmalloc(ino->size + 1, GFP_KERNEL); |
739 | return -ENOSPC; | 632 | if (!cp) { |
633 | if (!dentry->d_fsdata) | ||
634 | kfree(ino); | ||
635 | return -ENOMEM; | ||
740 | } | 636 | } |
741 | 637 | ||
742 | strcpy(cp, symname); | 638 | strcpy(cp, symname); |
743 | 639 | ||
744 | inode = autofs4_get_inode(dir->i_sb, ino); | 640 | inode = autofs4_get_inode(dir->i_sb, ino); |
641 | if (!inode) { | ||
642 | kfree(cp); | ||
643 | if (!dentry->d_fsdata) | ||
644 | kfree(ino); | ||
645 | return -ENOMEM; | ||
646 | } | ||
745 | d_add(dentry, inode); | 647 | d_add(dentry, inode); |
746 | 648 | ||
747 | if (dir == dir->i_sb->s_root->d_inode) | 649 | if (dir == dir->i_sb->s_root->d_inode) |
@@ -757,6 +659,7 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
757 | atomic_inc(&p_ino->count); | 659 | atomic_inc(&p_ino->count); |
758 | ino->inode = inode; | 660 | ino->inode = inode; |
759 | 661 | ||
662 | ino->u.symlink = cp; | ||
760 | dir->i_mtime = CURRENT_TIME; | 663 | dir->i_mtime = CURRENT_TIME; |
761 | 664 | ||
762 | return 0; | 665 | return 0; |
@@ -769,9 +672,8 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
769 | * that the file no longer exists. However, doing that means that the | 672 | * that the file no longer exists. However, doing that means that the |
770 | * VFS layer can turn the dentry into a negative dentry. We don't want | 673 | * VFS layer can turn the dentry into a negative dentry. We don't want |
771 | * this, because the unlink is probably the result of an expire. | 674 | * this, because the unlink is probably the result of an expire. |
772 | * We simply d_drop it and add it to a rehash candidates list in the | 675 | * We simply d_drop it and add it to a expiring list in the super block, |
773 | * super block, which allows the dentry lookup to reuse it retaining | 676 | * which allows the dentry lookup to check for an incomplete expire. |
774 | * the flags, such as expire in progress, in case we're racing with expire. | ||
775 | * | 677 | * |
776 | * If a process is blocked on the dentry waiting for the expire to finish, | 678 | * If a process is blocked on the dentry waiting for the expire to finish, |
777 | * it will invalidate the dentry and try to mount with a new one. | 679 | * it will invalidate the dentry and try to mount with a new one. |
@@ -801,9 +703,10 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
801 | dir->i_mtime = CURRENT_TIME; | 703 | dir->i_mtime = CURRENT_TIME; |
802 | 704 | ||
803 | spin_lock(&dcache_lock); | 705 | spin_lock(&dcache_lock); |
804 | spin_lock(&sbi->rehash_lock); | 706 | spin_lock(&sbi->lookup_lock); |
805 | list_add(&ino->rehash, &sbi->rehash_list); | 707 | if (list_empty(&ino->expiring)) |
806 | spin_unlock(&sbi->rehash_lock); | 708 | list_add(&ino->expiring, &sbi->expiring_list); |
709 | spin_unlock(&sbi->lookup_lock); | ||
807 | spin_lock(&dentry->d_lock); | 710 | spin_lock(&dentry->d_lock); |
808 | __d_drop(dentry); | 711 | __d_drop(dentry); |
809 | spin_unlock(&dentry->d_lock); | 712 | spin_unlock(&dentry->d_lock); |
@@ -829,9 +732,10 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
829 | spin_unlock(&dcache_lock); | 732 | spin_unlock(&dcache_lock); |
830 | return -ENOTEMPTY; | 733 | return -ENOTEMPTY; |
831 | } | 734 | } |
832 | spin_lock(&sbi->rehash_lock); | 735 | spin_lock(&sbi->lookup_lock); |
833 | list_add(&ino->rehash, &sbi->rehash_list); | 736 | if (list_empty(&ino->expiring)) |
834 | spin_unlock(&sbi->rehash_lock); | 737 | list_add(&ino->expiring, &sbi->expiring_list); |
738 | spin_unlock(&sbi->lookup_lock); | ||
835 | spin_lock(&dentry->d_lock); | 739 | spin_lock(&dentry->d_lock); |
836 | __d_drop(dentry); | 740 | __d_drop(dentry); |
837 | spin_unlock(&dentry->d_lock); | 741 | spin_unlock(&dentry->d_lock); |
@@ -866,10 +770,20 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
866 | dentry, dentry->d_name.len, dentry->d_name.name); | 770 | dentry, dentry->d_name.len, dentry->d_name.name); |
867 | 771 | ||
868 | ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); | 772 | ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); |
869 | if (ino == NULL) | 773 | if (!ino) |
870 | return -ENOSPC; | 774 | return -ENOMEM; |
775 | |||
776 | spin_lock(&sbi->lookup_lock); | ||
777 | if (!list_empty(&ino->active)) | ||
778 | list_del_init(&ino->active); | ||
779 | spin_unlock(&sbi->lookup_lock); | ||
871 | 780 | ||
872 | inode = autofs4_get_inode(dir->i_sb, ino); | 781 | inode = autofs4_get_inode(dir->i_sb, ino); |
782 | if (!inode) { | ||
783 | if (!dentry->d_fsdata) | ||
784 | kfree(ino); | ||
785 | return -ENOMEM; | ||
786 | } | ||
873 | d_add(dentry, inode); | 787 | d_add(dentry, inode); |
874 | 788 | ||
875 | if (dir == dir->i_sb->s_root->d_inode) | 789 | if (dir == dir->i_sb->s_root->d_inode) |
@@ -922,44 +836,6 @@ static inline int autofs4_get_protosubver(struct autofs_sb_info *sbi, int __user | |||
922 | } | 836 | } |
923 | 837 | ||
924 | /* | 838 | /* |
925 | * Tells the daemon whether we need to reghost or not. Also, clears | ||
926 | * the reghost_needed flag. | ||
927 | */ | ||
928 | static inline int autofs4_ask_reghost(struct autofs_sb_info *sbi, int __user *p) | ||
929 | { | ||
930 | int status; | ||
931 | |||
932 | DPRINTK("returning %d", sbi->needs_reghost); | ||
933 | |||
934 | status = put_user(sbi->needs_reghost, p); | ||
935 | if (status) | ||
936 | return status; | ||
937 | |||
938 | sbi->needs_reghost = 0; | ||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | /* | ||
943 | * Enable / Disable reghosting ioctl() operation | ||
944 | */ | ||
945 | static inline int autofs4_toggle_reghost(struct autofs_sb_info *sbi, int __user *p) | ||
946 | { | ||
947 | int status; | ||
948 | int val; | ||
949 | |||
950 | status = get_user(val, p); | ||
951 | |||
952 | DPRINTK("reghost = %d", val); | ||
953 | |||
954 | if (status) | ||
955 | return status; | ||
956 | |||
957 | /* turn on/off reghosting, with the val */ | ||
958 | sbi->reghost_enabled = val; | ||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | /* | ||
963 | * Tells the daemon whether it can umount the autofs mount. | 839 | * Tells the daemon whether it can umount the autofs mount. |
964 | */ | 840 | */ |
965 | static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p) | 841 | static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p) |
@@ -1023,11 +899,6 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, | |||
1023 | case AUTOFS_IOC_SETTIMEOUT: | 899 | case AUTOFS_IOC_SETTIMEOUT: |
1024 | return autofs4_get_set_timeout(sbi, p); | 900 | return autofs4_get_set_timeout(sbi, p); |
1025 | 901 | ||
1026 | case AUTOFS_IOC_TOGGLEREGHOST: | ||
1027 | return autofs4_toggle_reghost(sbi, p); | ||
1028 | case AUTOFS_IOC_ASKREGHOST: | ||
1029 | return autofs4_ask_reghost(sbi, p); | ||
1030 | |||
1031 | case AUTOFS_IOC_ASKUMOUNT: | 902 | case AUTOFS_IOC_ASKUMOUNT: |
1032 | return autofs4_ask_umount(filp->f_path.mnt, p); | 903 | return autofs4_ask_umount(filp->f_path.mnt, p); |
1033 | 904 | ||