diff options
Diffstat (limited to 'fs/autofs4')
-rw-r--r-- | fs/autofs4/autofs_i.h | 13 | ||||
-rw-r--r-- | fs/autofs4/expire.c | 5 | ||||
-rw-r--r-- | fs/autofs4/root.c | 15 | ||||
-rw-r--r-- | fs/autofs4/waitq.c | 7 |
4 files changed, 34 insertions, 6 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index c7b2b8890188..9c09641ce907 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -185,6 +185,19 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); | |||
185 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); | 185 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); |
186 | void autofs4_catatonic_mode(struct autofs_sb_info *); | 186 | void autofs4_catatonic_mode(struct autofs_sb_info *); |
187 | 187 | ||
188 | static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry) | ||
189 | { | ||
190 | int res = 0; | ||
191 | |||
192 | while (d_mountpoint(*dentry)) { | ||
193 | int followed = follow_down(mnt, dentry); | ||
194 | if (!followed) | ||
195 | break; | ||
196 | res = 1; | ||
197 | } | ||
198 | return res; | ||
199 | } | ||
200 | |||
188 | static inline int simple_positive(struct dentry *dentry) | 201 | static inline int simple_positive(struct dentry *dentry) |
189 | { | 202 | { |
190 | return dentry->d_inode && !d_unhashed(dentry); | 203 | return dentry->d_inode && !d_unhashed(dentry); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 500425e24fba..feb6ac427d05 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry) | |||
56 | mntget(mnt); | 56 | mntget(mnt); |
57 | dget(dentry); | 57 | dget(dentry); |
58 | 58 | ||
59 | if (!follow_down(&mnt, &dentry)) | 59 | if (!autofs4_follow_mount(&mnt, &dentry)) |
60 | goto done; | 60 | goto done; |
61 | 61 | ||
62 | while (d_mountpoint(dentry) && follow_down(&mnt, &dentry)) | ||
63 | ; | ||
64 | |||
65 | /* This is an autofs submount, we can't expire it */ | 62 | /* This is an autofs submount, we can't expire it */ |
66 | if (is_autofs4_dentry(dentry)) | 63 | if (is_autofs4_dentry(dentry)) |
67 | goto done; | 64 | goto done; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 3765c047f157..2a771ec66956 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
205 | struct vfsmount *fp_mnt = mntget(mnt); | 205 | struct vfsmount *fp_mnt = mntget(mnt); |
206 | struct dentry *fp_dentry = dget(dentry); | 206 | struct dentry *fp_dentry = dget(dentry); |
207 | 207 | ||
208 | while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry)); | 208 | if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) { |
209 | dput(fp_dentry); | ||
210 | mntput(fp_mnt); | ||
211 | return -ENOENT; | ||
212 | } | ||
209 | 213 | ||
210 | fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); | 214 | fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); |
211 | status = PTR_ERR(fp); | 215 | status = PTR_ERR(fp); |
@@ -302,7 +306,14 @@ static int try_to_fill_dentry(struct dentry *dentry, | |||
302 | 306 | ||
303 | DPRINTK("expire done status=%d", status); | 307 | DPRINTK("expire done status=%d", status); |
304 | 308 | ||
305 | return 0; | 309 | /* |
310 | * If the directory still exists the mount request must | ||
311 | * continue otherwise it can't be followed at the right | ||
312 | * time during the walk. | ||
313 | */ | ||
314 | status = d_invalidate(dentry); | ||
315 | if (status != -EBUSY) | ||
316 | return 0; | ||
306 | } | 317 | } |
307 | 318 | ||
308 | DPRINTK("dentry=%p %.*s ino=%p", | 319 | DPRINTK("dentry=%p %.*s ino=%p", |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 5a40d36e5a51..fa2348dcd671 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -191,6 +191,13 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
191 | } | 191 | } |
192 | 192 | ||
193 | if ( !wq ) { | 193 | if ( !wq ) { |
194 | /* Can't wait for an expire if there's no mount */ | ||
195 | if (notify == NFY_NONE && !d_mountpoint(dentry)) { | ||
196 | kfree(name); | ||
197 | up(&sbi->wq_sem); | ||
198 | return -ENOENT; | ||
199 | } | ||
200 | |||
194 | /* Create a new wait queue */ | 201 | /* Create a new wait queue */ |
195 | wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); | 202 | wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); |
196 | if ( !wq ) { | 203 | if ( !wq ) { |