diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 74 |
1 files changed, 35 insertions, 39 deletions
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) |