aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r--fs/autofs4/root.c74
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);
37static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); 37static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
38static struct vfsmount *autofs4_d_automount(struct path *); 38static struct vfsmount *autofs4_d_automount(struct path *);
39static int autofs4_d_manage(struct dentry *, bool, bool); 39static int autofs4_d_manage(struct dentry *, bool, bool);
40static void autofs4_dentry_release(struct dentry *);
40 41
41const struct file_operations autofs4_root_operations = { 42const 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
141void autofs4_dentry_release(struct dentry *de) 142static 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
162static struct dentry *autofs4_lookup_active(struct dentry *dentry) 164static 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)