diff options
| -rw-r--r-- | fs/autofs4/autofs_i.h | 14 | ||||
| -rw-r--r-- | fs/autofs4/expire.c | 4 | ||||
| -rw-r--r-- | fs/autofs4/inode.c | 88 | ||||
| -rw-r--r-- | fs/autofs4/root.c | 74 | ||||
| -rw-r--r-- | fs/autofs4/symlink.c | 3 | ||||
| -rw-r--r-- | fs/namei.c | 4 |
6 files changed, 66 insertions, 121 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 1f016bfb42d5..54f923792728 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
| @@ -88,14 +88,6 @@ struct autofs_info { | |||
| 88 | 88 | ||
| 89 | uid_t uid; | 89 | uid_t uid; |
| 90 | gid_t gid; | 90 | gid_t gid; |
| 91 | |||
| 92 | mode_t mode; | ||
| 93 | size_t size; | ||
| 94 | |||
| 95 | void (*free)(struct autofs_info *); | ||
| 96 | union { | ||
| 97 | const char *symlink; | ||
| 98 | } u; | ||
| 99 | }; | 91 | }; |
| 100 | 92 | ||
| 101 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ | 93 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ |
| @@ -175,7 +167,7 @@ static inline int autofs4_ispending(struct dentry *dentry) | |||
| 175 | return 0; | 167 | return 0; |
| 176 | } | 168 | } |
| 177 | 169 | ||
| 178 | struct inode *autofs4_get_inode(struct super_block *, struct autofs_info *); | 170 | struct inode *autofs4_get_inode(struct super_block *, mode_t); |
| 179 | void autofs4_free_ino(struct autofs_info *); | 171 | void autofs4_free_ino(struct autofs_info *); |
| 180 | 172 | ||
| 181 | /* Expiration */ | 173 | /* Expiration */ |
| @@ -285,7 +277,8 @@ static inline void managed_dentry_clear_managed(struct dentry *dentry) | |||
| 285 | /* Initializing function */ | 277 | /* Initializing function */ |
| 286 | 278 | ||
| 287 | int autofs4_fill_super(struct super_block *, void *, int); | 279 | int autofs4_fill_super(struct super_block *, void *, int); |
| 288 | struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode); | 280 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *); |
| 281 | void autofs4_clean_ino(struct autofs_info *); | ||
| 289 | 282 | ||
| 290 | /* Queue management functions */ | 283 | /* Queue management functions */ |
| 291 | 284 | ||
| @@ -345,5 +338,4 @@ static inline void autofs4_del_expiring(struct dentry *dentry) | |||
| 345 | return; | 338 | return; |
| 346 | } | 339 | } |
| 347 | 340 | ||
| 348 | void autofs4_dentry_release(struct dentry *); | ||
| 349 | extern void autofs4_kill_sb(struct super_block *); | 341 | extern void autofs4_kill_sb(struct super_block *); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 3ed79d76c233..f43100b9662b 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
| @@ -96,7 +96,7 @@ static struct dentry *get_next_positive_dentry(struct dentry *prev, | |||
| 96 | struct dentry *p, *ret; | 96 | struct dentry *p, *ret; |
| 97 | 97 | ||
| 98 | if (prev == NULL) | 98 | if (prev == NULL) |
| 99 | return dget(prev); | 99 | return dget(root); |
| 100 | 100 | ||
| 101 | spin_lock(&autofs4_lock); | 101 | spin_lock(&autofs4_lock); |
| 102 | relock: | 102 | relock: |
| @@ -133,7 +133,7 @@ again: | |||
| 133 | spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED); | 133 | spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED); |
| 134 | /* Negative dentry - try next */ | 134 | /* Negative dentry - try next */ |
| 135 | if (!simple_positive(ret)) { | 135 | if (!simple_positive(ret)) { |
| 136 | spin_unlock(&ret->d_lock); | 136 | spin_unlock(&p->d_lock); |
| 137 | p = ret; | 137 | p = ret; |
| 138 | goto again; | 138 | goto again; |
| 139 | } | 139 | } |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 9e1a9dad23e1..180fa2425e49 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
| @@ -22,65 +22,27 @@ | |||
| 22 | #include "autofs_i.h" | 22 | #include "autofs_i.h" |
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | 24 | ||
| 25 | static void ino_lnkfree(struct autofs_info *ino) | 25 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *sbi) |
| 26 | { | 26 | { |
| 27 | if (ino->u.symlink) { | 27 | struct autofs_info *ino = kzalloc(sizeof(*ino), GFP_KERNEL); |
| 28 | kfree(ino->u.symlink); | 28 | if (ino) { |
| 29 | ino->u.symlink = NULL; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | struct autofs_info *autofs4_init_ino(struct autofs_info *ino, | ||
| 34 | struct autofs_sb_info *sbi, mode_t mode) | ||
| 35 | { | ||
| 36 | int reinit = 1; | ||
| 37 | |||
| 38 | if (ino == NULL) { | ||
| 39 | reinit = 0; | ||
| 40 | ino = kmalloc(sizeof(*ino), GFP_KERNEL); | ||
| 41 | } | ||
| 42 | |||
| 43 | if (ino == NULL) | ||
| 44 | return NULL; | ||
| 45 | |||
| 46 | if (!reinit) { | ||
| 47 | ino->flags = 0; | ||
| 48 | ino->dentry = NULL; | ||
| 49 | ino->size = 0; | ||
| 50 | INIT_LIST_HEAD(&ino->active); | 29 | INIT_LIST_HEAD(&ino->active); |
| 51 | ino->active_count = 0; | ||
| 52 | INIT_LIST_HEAD(&ino->expiring); | 30 | INIT_LIST_HEAD(&ino->expiring); |
| 53 | atomic_set(&ino->count, 0); | 31 | ino->last_used = jiffies; |
| 32 | ino->sbi = sbi; | ||
| 54 | } | 33 | } |
| 34 | return ino; | ||
| 35 | } | ||
| 55 | 36 | ||
| 37 | void autofs4_clean_ino(struct autofs_info *ino) | ||
| 38 | { | ||
| 56 | ino->uid = 0; | 39 | ino->uid = 0; |
| 57 | ino->gid = 0; | 40 | ino->gid = 0; |
| 58 | ino->mode = mode; | ||
| 59 | ino->last_used = jiffies; | 41 | ino->last_used = jiffies; |
| 60 | |||
| 61 | ino->sbi = sbi; | ||
| 62 | |||
| 63 | if (reinit && ino->free) | ||
| 64 | (ino->free)(ino); | ||
| 65 | |||
| 66 | memset(&ino->u, 0, sizeof(ino->u)); | ||
| 67 | |||
| 68 | ino->free = NULL; | ||
| 69 | |||
| 70 | if (S_ISLNK(mode)) | ||
| 71 | ino->free = ino_lnkfree; | ||
| 72 | |||
| 73 | return ino; | ||
| 74 | } | 42 | } |
| 75 | 43 | ||
| 76 | void autofs4_free_ino(struct autofs_info *ino) | 44 | void autofs4_free_ino(struct autofs_info *ino) |
| 77 | { | 45 | { |
| 78 | if (ino->dentry) { | ||
| 79 | ino->dentry->d_fsdata = NULL; | ||
| 80 | ino->dentry = NULL; | ||
| 81 | } | ||
| 82 | if (ino->free) | ||
| 83 | (ino->free)(ino); | ||
| 84 | kfree(ino); | 46 | kfree(ino); |
| 85 | } | 47 | } |
| 86 | 48 | ||
| @@ -136,9 +98,16 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
| 136 | return 0; | 98 | return 0; |
| 137 | } | 99 | } |
| 138 | 100 | ||
| 101 | static void autofs4_evict_inode(struct inode *inode) | ||
| 102 | { | ||
| 103 | end_writeback(inode); | ||
| 104 | kfree(inode->i_private); | ||
| 105 | } | ||
| 106 | |||
| 139 | static const struct super_operations autofs4_sops = { | 107 | static const struct super_operations autofs4_sops = { |
| 140 | .statfs = simple_statfs, | 108 | .statfs = simple_statfs, |
| 141 | .show_options = autofs4_show_options, | 109 | .show_options = autofs4_show_options, |
| 110 | .evict_inode = autofs4_evict_inode, | ||
| 142 | }; | 111 | }; |
| 143 | 112 | ||
| 144 | enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto, | 113 | enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto, |
| @@ -228,17 +197,6 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
| 228 | return (*pipefd < 0); | 197 | return (*pipefd < 0); |
| 229 | } | 198 | } |
| 230 | 199 | ||
| 231 | static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) | ||
| 232 | { | ||
| 233 | struct autofs_info *ino; | ||
| 234 | |||
| 235 | ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755); | ||
| 236 | if (!ino) | ||
| 237 | return NULL; | ||
| 238 | |||
| 239 | return ino; | ||
| 240 | } | ||
| 241 | |||
| 242 | int autofs4_fill_super(struct super_block *s, void *data, int silent) | 200 | int autofs4_fill_super(struct super_block *s, void *data, int silent) |
| 243 | { | 201 | { |
| 244 | struct inode * root_inode; | 202 | struct inode * root_inode; |
| @@ -282,10 +240,10 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
| 282 | /* | 240 | /* |
| 283 | * Get the root inode and dentry, but defer checking for errors. | 241 | * Get the root inode and dentry, but defer checking for errors. |
| 284 | */ | 242 | */ |
| 285 | ino = autofs4_mkroot(sbi); | 243 | ino = autofs4_new_ino(sbi); |
| 286 | if (!ino) | 244 | if (!ino) |
| 287 | goto fail_free; | 245 | goto fail_free; |
| 288 | root_inode = autofs4_get_inode(s, ino); | 246 | root_inode = autofs4_get_inode(s, S_IFDIR | 0755); |
| 289 | if (!root_inode) | 247 | if (!root_inode) |
| 290 | goto fail_ino; | 248 | goto fail_ino; |
| 291 | 249 | ||
| @@ -368,15 +326,14 @@ fail_unlock: | |||
| 368 | return -EINVAL; | 326 | return -EINVAL; |
| 369 | } | 327 | } |
| 370 | 328 | ||
| 371 | struct inode *autofs4_get_inode(struct super_block *sb, | 329 | struct inode *autofs4_get_inode(struct super_block *sb, mode_t mode) |
| 372 | struct autofs_info *inf) | ||
| 373 | { | 330 | { |
| 374 | struct inode *inode = new_inode(sb); | 331 | struct inode *inode = new_inode(sb); |
| 375 | 332 | ||
| 376 | if (inode == NULL) | 333 | if (inode == NULL) |
| 377 | return NULL; | 334 | return NULL; |
| 378 | 335 | ||
| 379 | inode->i_mode = inf->mode; | 336 | inode->i_mode = mode; |
| 380 | if (sb->s_root) { | 337 | if (sb->s_root) { |
| 381 | inode->i_uid = sb->s_root->d_inode->i_uid; | 338 | inode->i_uid = sb->s_root->d_inode->i_uid; |
| 382 | inode->i_gid = sb->s_root->d_inode->i_gid; | 339 | inode->i_gid = sb->s_root->d_inode->i_gid; |
| @@ -384,12 +341,11 @@ struct inode *autofs4_get_inode(struct super_block *sb, | |||
| 384 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 341 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 385 | inode->i_ino = get_next_ino(); | 342 | inode->i_ino = get_next_ino(); |
| 386 | 343 | ||
| 387 | if (S_ISDIR(inf->mode)) { | 344 | if (S_ISDIR(mode)) { |
| 388 | inode->i_nlink = 2; | 345 | inode->i_nlink = 2; |
| 389 | inode->i_op = &autofs4_dir_inode_operations; | 346 | inode->i_op = &autofs4_dir_inode_operations; |
| 390 | inode->i_fop = &autofs4_dir_operations; | 347 | inode->i_fop = &autofs4_dir_operations; |
| 391 | } else if (S_ISLNK(inf->mode)) { | 348 | } else if (S_ISLNK(mode)) { |
| 392 | inode->i_size = inf->size; | ||
| 393 | inode->i_op = &autofs4_symlink_inode_operations; | 349 | inode->i_op = &autofs4_symlink_inode_operations; |
| 394 | } | 350 | } |
| 395 | 351 | ||
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 1dba035fc376..014e7aba3b08 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -37,6 +37,7 @@ static int autofs4_dir_open(struct inode *inode, struct file *file); | |||
| 37 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); | 37 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); |
| 38 | static struct vfsmount *autofs4_d_automount(struct path *); | 38 | static struct vfsmount *autofs4_d_automount(struct path *); |
| 39 | static int autofs4_d_manage(struct dentry *, bool, bool); | 39 | static int autofs4_d_manage(struct dentry *, bool, bool); |
| 40 | static void autofs4_dentry_release(struct dentry *); | ||
| 40 | 41 | ||
| 41 | const struct file_operations autofs4_root_operations = { | 42 | const struct file_operations autofs4_root_operations = { |
| 42 | .open = dcache_dir_open, | 43 | .open = dcache_dir_open, |
| @@ -138,25 +139,26 @@ out: | |||
| 138 | return dcache_dir_open(inode, file); | 139 | return dcache_dir_open(inode, file); |
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | void autofs4_dentry_release(struct dentry *de) | 142 | static void autofs4_dentry_release(struct dentry *de) |
| 142 | { | 143 | { |
| 143 | struct autofs_info *inf; | 144 | struct autofs_info *ino = autofs4_dentry_ino(de); |
| 145 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); | ||
| 144 | 146 | ||
| 145 | DPRINTK("releasing %p", de); | 147 | DPRINTK("releasing %p", de); |
| 146 | 148 | ||
| 147 | inf = autofs4_dentry_ino(de); | 149 | if (!ino) |
| 148 | if (inf) { | 150 | return; |
| 149 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); | 151 | |
| 150 | if (sbi) { | 152 | if (sbi) { |
| 151 | spin_lock(&sbi->lookup_lock); | 153 | spin_lock(&sbi->lookup_lock); |
| 152 | if (!list_empty(&inf->active)) | 154 | if (!list_empty(&ino->active)) |
| 153 | list_del(&inf->active); | 155 | list_del(&ino->active); |
| 154 | if (!list_empty(&inf->expiring)) | 156 | if (!list_empty(&ino->expiring)) |
| 155 | list_del(&inf->expiring); | 157 | list_del(&ino->expiring); |
| 156 | spin_unlock(&sbi->lookup_lock); | 158 | spin_unlock(&sbi->lookup_lock); |
| 157 | } | ||
| 158 | autofs4_free_ino(inf); | ||
| 159 | } | 159 | } |
| 160 | |||
| 161 | autofs4_free_ino(ino); | ||
| 160 | } | 162 | } |
| 161 | 163 | ||
| 162 | static struct dentry *autofs4_lookup_active(struct dentry *dentry) | 164 | static struct dentry *autofs4_lookup_active(struct dentry *dentry) |
| @@ -488,7 +490,8 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 488 | sbi = autofs4_sbi(dir->i_sb); | 490 | sbi = autofs4_sbi(dir->i_sb); |
| 489 | 491 | ||
| 490 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", | 492 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", |
| 491 | current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); | 493 | current->pid, task_pgrp_nr(current), sbi->catatonic, |
| 494 | autofs4_oz_mode(sbi)); | ||
| 492 | 495 | ||
| 493 | active = autofs4_lookup_active(dentry); | 496 | active = autofs4_lookup_active(dentry); |
| 494 | if (active) { | 497 | if (active) { |
| @@ -507,7 +510,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 507 | if (autofs_type_indirect(sbi->type) && IS_ROOT(dentry->d_parent)) | 510 | if (autofs_type_indirect(sbi->type) && IS_ROOT(dentry->d_parent)) |
| 508 | __managed_dentry_set_managed(dentry); | 511 | __managed_dentry_set_managed(dentry); |
| 509 | 512 | ||
| 510 | ino = autofs4_init_ino(NULL, sbi, 0555); | 513 | ino = autofs4_new_ino(sbi); |
| 511 | if (!ino) | 514 | if (!ino) |
| 512 | return ERR_PTR(-ENOMEM); | 515 | return ERR_PTR(-ENOMEM); |
| 513 | 516 | ||
| @@ -529,6 +532,7 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
| 529 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 532 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
| 530 | struct autofs_info *p_ino; | 533 | struct autofs_info *p_ino; |
| 531 | struct inode *inode; | 534 | struct inode *inode; |
| 535 | size_t size = strlen(symname); | ||
| 532 | char *cp; | 536 | char *cp; |
| 533 | 537 | ||
| 534 | DPRINTK("%s <- %.*s", symname, | 538 | DPRINTK("%s <- %.*s", symname, |
| @@ -537,39 +541,35 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
| 537 | if (!autofs4_oz_mode(sbi)) | 541 | if (!autofs4_oz_mode(sbi)) |
| 538 | return -EACCES; | 542 | return -EACCES; |
| 539 | 543 | ||
| 540 | ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); | 544 | BUG_ON(!ino); |
| 541 | if (!ino) | 545 | |
| 542 | return -ENOMEM; | 546 | autofs4_clean_ino(ino); |
| 543 | 547 | ||
| 544 | autofs4_del_active(dentry); | 548 | autofs4_del_active(dentry); |
| 545 | 549 | ||
| 546 | ino->size = strlen(symname); | 550 | cp = kmalloc(size + 1, GFP_KERNEL); |
| 547 | cp = kmalloc(ino->size + 1, GFP_KERNEL); | 551 | if (!cp) |
| 548 | if (!cp) { | ||
| 549 | if (!dentry->d_fsdata) | ||
| 550 | kfree(ino); | ||
| 551 | return -ENOMEM; | 552 | return -ENOMEM; |
| 552 | } | ||
| 553 | 553 | ||
| 554 | strcpy(cp, symname); | 554 | strcpy(cp, symname); |
| 555 | 555 | ||
| 556 | inode = autofs4_get_inode(dir->i_sb, ino); | 556 | inode = autofs4_get_inode(dir->i_sb, S_IFLNK | 0555); |
| 557 | if (!inode) { | 557 | if (!inode) { |
| 558 | kfree(cp); | 558 | kfree(cp); |
| 559 | if (!dentry->d_fsdata) | 559 | if (!dentry->d_fsdata) |
| 560 | kfree(ino); | 560 | kfree(ino); |
| 561 | return -ENOMEM; | 561 | return -ENOMEM; |
| 562 | } | 562 | } |
| 563 | inode->i_private = cp; | ||
| 564 | inode->i_size = size; | ||
| 563 | d_add(dentry, inode); | 565 | d_add(dentry, inode); |
| 564 | 566 | ||
| 565 | dentry->d_fsdata = ino; | 567 | dget(dentry); |
| 566 | ino->dentry = dget(dentry); | ||
| 567 | atomic_inc(&ino->count); | 568 | atomic_inc(&ino->count); |
| 568 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 569 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
| 569 | if (p_ino && dentry->d_parent != dentry) | 570 | if (p_ino && dentry->d_parent != dentry) |
| 570 | atomic_inc(&p_ino->count); | 571 | atomic_inc(&p_ino->count); |
| 571 | 572 | ||
| 572 | ino->u.symlink = cp; | ||
| 573 | dir->i_mtime = CURRENT_TIME; | 573 | dir->i_mtime = CURRENT_TIME; |
| 574 | 574 | ||
| 575 | return 0; | 575 | return 0; |
| @@ -732,25 +732,21 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 732 | DPRINTK("dentry %p, creating %.*s", | 732 | DPRINTK("dentry %p, creating %.*s", |
| 733 | dentry, dentry->d_name.len, dentry->d_name.name); | 733 | dentry, dentry->d_name.len, dentry->d_name.name); |
| 734 | 734 | ||
| 735 | ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); | 735 | BUG_ON(!ino); |
| 736 | if (!ino) | 736 | |
| 737 | return -ENOMEM; | 737 | autofs4_clean_ino(ino); |
| 738 | 738 | ||
| 739 | autofs4_del_active(dentry); | 739 | autofs4_del_active(dentry); |
| 740 | 740 | ||
| 741 | inode = autofs4_get_inode(dir->i_sb, ino); | 741 | inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); |
| 742 | if (!inode) { | 742 | if (!inode) |
| 743 | if (!dentry->d_fsdata) | ||
| 744 | kfree(ino); | ||
| 745 | return -ENOMEM; | 743 | return -ENOMEM; |
| 746 | } | ||
| 747 | d_add(dentry, inode); | 744 | d_add(dentry, inode); |
| 748 | 745 | ||
| 749 | if (sbi->version < 5) | 746 | if (sbi->version < 5) |
| 750 | autofs_set_leaf_automount_flags(dentry); | 747 | autofs_set_leaf_automount_flags(dentry); |
| 751 | 748 | ||
| 752 | dentry->d_fsdata = ino; | 749 | dget(dentry); |
| 753 | ino->dentry = dget(dentry); | ||
| 754 | atomic_inc(&ino->count); | 750 | atomic_inc(&ino->count); |
| 755 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 751 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
| 756 | if (p_ino && dentry->d_parent != dentry) | 752 | if (p_ino && dentry->d_parent != dentry) |
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c index b4ea82934d2e..f27c094a1919 100644 --- a/fs/autofs4/symlink.c +++ b/fs/autofs4/symlink.c | |||
| @@ -14,8 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | 15 | static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) |
| 16 | { | 16 | { |
| 17 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 17 | nd_set_link(nd, dentry->d_inode->i_private); |
| 18 | nd_set_link(nd, (char *)ino->u.symlink); | ||
| 19 | return NULL; | 18 | return NULL; |
| 20 | } | 19 | } |
| 21 | 20 | ||
diff --git a/fs/namei.c b/fs/namei.c index b753192d8c3f..7d77f24d32a9 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1272,8 +1272,10 @@ done: | |||
| 1272 | path->mnt = mnt; | 1272 | path->mnt = mnt; |
| 1273 | path->dentry = dentry; | 1273 | path->dentry = dentry; |
| 1274 | err = follow_managed(path, nd->flags); | 1274 | err = follow_managed(path, nd->flags); |
| 1275 | if (unlikely(err < 0)) | 1275 | if (unlikely(err < 0)) { |
| 1276 | path_put_conditional(path, nd); | ||
| 1276 | return err; | 1277 | return err; |
| 1278 | } | ||
| 1277 | *inode = path->dentry->d_inode; | 1279 | *inode = path->dentry->d_inode; |
| 1278 | return 0; | 1280 | return 0; |
| 1279 | 1281 | ||
