Commit baa40671d3e3b590a33b2c0e022db61cbebf5c00
1 parent
2d1d9b5b5c
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
autofs4: make freeing sbi rcu-delayed
makes ->d_managed() safety in RCU mode independent from vfsmount_lock Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 2 changed files with 5 additions and 9 deletions Inline Diff
fs/autofs4/autofs_i.h
1 | /* -*- c -*- ------------------------------------------------------------- * | 1 | /* -*- c -*- ------------------------------------------------------------- * |
2 | * | 2 | * |
3 | * linux/fs/autofs/autofs_i.h | 3 | * linux/fs/autofs/autofs_i.h |
4 | * | 4 | * |
5 | * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved | 5 | * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved |
6 | * Copyright 2005-2006 Ian Kent <raven@themaw.net> | 6 | * Copyright 2005-2006 Ian Kent <raven@themaw.net> |
7 | * | 7 | * |
8 | * This file is part of the Linux kernel and is made available under | 8 | * This file is part of the Linux kernel and is made available under |
9 | * the terms of the GNU General Public License, version 2, or at your | 9 | * the terms of the GNU General Public License, version 2, or at your |
10 | * option, any later version, incorporated herein by reference. | 10 | * option, any later version, incorporated herein by reference. |
11 | * | 11 | * |
12 | * ----------------------------------------------------------------------- */ | 12 | * ----------------------------------------------------------------------- */ |
13 | 13 | ||
14 | /* Internal header file for autofs */ | 14 | /* Internal header file for autofs */ |
15 | 15 | ||
16 | #include <linux/auto_fs4.h> | 16 | #include <linux/auto_fs4.h> |
17 | #include <linux/auto_dev-ioctl.h> | 17 | #include <linux/auto_dev-ioctl.h> |
18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | 21 | ||
22 | /* This is the range of ioctl() numbers we claim as ours */ | 22 | /* This is the range of ioctl() numbers we claim as ours */ |
23 | #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY | 23 | #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY |
24 | #define AUTOFS_IOC_COUNT 32 | 24 | #define AUTOFS_IOC_COUNT 32 |
25 | 25 | ||
26 | #define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION) | 26 | #define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION) |
27 | #define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11) | 27 | #define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11) |
28 | 28 | ||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/time.h> | 31 | #include <linux/time.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/mount.h> | 35 | #include <linux/mount.h> |
36 | #include <linux/namei.h> | 36 | #include <linux/namei.h> |
37 | #include <asm/current.h> | 37 | #include <asm/current.h> |
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | 39 | ||
40 | /* #define DEBUG */ | 40 | /* #define DEBUG */ |
41 | 41 | ||
42 | #define DPRINTK(fmt, ...) \ | 42 | #define DPRINTK(fmt, ...) \ |
43 | pr_debug("pid %d: %s: " fmt "\n", \ | 43 | pr_debug("pid %d: %s: " fmt "\n", \ |
44 | current->pid, __func__, ##__VA_ARGS__) | 44 | current->pid, __func__, ##__VA_ARGS__) |
45 | 45 | ||
46 | #define AUTOFS_WARN(fmt, ...) \ | 46 | #define AUTOFS_WARN(fmt, ...) \ |
47 | printk(KERN_WARNING "pid %d: %s: " fmt "\n", \ | 47 | printk(KERN_WARNING "pid %d: %s: " fmt "\n", \ |
48 | current->pid, __func__, ##__VA_ARGS__) | 48 | current->pid, __func__, ##__VA_ARGS__) |
49 | 49 | ||
50 | #define AUTOFS_ERROR(fmt, ...) \ | 50 | #define AUTOFS_ERROR(fmt, ...) \ |
51 | printk(KERN_ERR "pid %d: %s: " fmt "\n", \ | 51 | printk(KERN_ERR "pid %d: %s: " fmt "\n", \ |
52 | current->pid, __func__, ##__VA_ARGS__) | 52 | current->pid, __func__, ##__VA_ARGS__) |
53 | 53 | ||
54 | /* Unified info structure. This is pointed to by both the dentry and | 54 | /* Unified info structure. This is pointed to by both the dentry and |
55 | inode structures. Each file in the filesystem has an instance of this | 55 | inode structures. Each file in the filesystem has an instance of this |
56 | structure. It holds a reference to the dentry, so dentries are never | 56 | structure. It holds a reference to the dentry, so dentries are never |
57 | flushed while the file exists. All name lookups are dealt with at the | 57 | flushed while the file exists. All name lookups are dealt with at the |
58 | dentry level, although the filesystem can interfere in the validation | 58 | dentry level, although the filesystem can interfere in the validation |
59 | process. Readdir is implemented by traversing the dentry lists. */ | 59 | process. Readdir is implemented by traversing the dentry lists. */ |
60 | struct autofs_info { | 60 | struct autofs_info { |
61 | struct dentry *dentry; | 61 | struct dentry *dentry; |
62 | struct inode *inode; | 62 | struct inode *inode; |
63 | 63 | ||
64 | int flags; | 64 | int flags; |
65 | 65 | ||
66 | struct completion expire_complete; | 66 | struct completion expire_complete; |
67 | 67 | ||
68 | struct list_head active; | 68 | struct list_head active; |
69 | int active_count; | 69 | int active_count; |
70 | 70 | ||
71 | struct list_head expiring; | 71 | struct list_head expiring; |
72 | 72 | ||
73 | struct autofs_sb_info *sbi; | 73 | struct autofs_sb_info *sbi; |
74 | unsigned long last_used; | 74 | unsigned long last_used; |
75 | atomic_t count; | 75 | atomic_t count; |
76 | 76 | ||
77 | kuid_t uid; | 77 | kuid_t uid; |
78 | kgid_t gid; | 78 | kgid_t gid; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ | 81 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ |
82 | #define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */ | 82 | #define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */ |
83 | 83 | ||
84 | struct autofs_wait_queue { | 84 | struct autofs_wait_queue { |
85 | wait_queue_head_t queue; | 85 | wait_queue_head_t queue; |
86 | struct autofs_wait_queue *next; | 86 | struct autofs_wait_queue *next; |
87 | autofs_wqt_t wait_queue_token; | 87 | autofs_wqt_t wait_queue_token; |
88 | /* We use the following to see what we are waiting for */ | 88 | /* We use the following to see what we are waiting for */ |
89 | struct qstr name; | 89 | struct qstr name; |
90 | u32 dev; | 90 | u32 dev; |
91 | u64 ino; | 91 | u64 ino; |
92 | kuid_t uid; | 92 | kuid_t uid; |
93 | kgid_t gid; | 93 | kgid_t gid; |
94 | pid_t pid; | 94 | pid_t pid; |
95 | pid_t tgid; | 95 | pid_t tgid; |
96 | /* This is for status reporting upon return */ | 96 | /* This is for status reporting upon return */ |
97 | int status; | 97 | int status; |
98 | unsigned int wait_ctr; | 98 | unsigned int wait_ctr; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | #define AUTOFS_SBI_MAGIC 0x6d4a556d | 101 | #define AUTOFS_SBI_MAGIC 0x6d4a556d |
102 | 102 | ||
103 | struct autofs_sb_info { | 103 | struct autofs_sb_info { |
104 | u32 magic; | 104 | u32 magic; |
105 | int pipefd; | 105 | int pipefd; |
106 | struct file *pipe; | 106 | struct file *pipe; |
107 | pid_t oz_pgrp; | 107 | pid_t oz_pgrp; |
108 | int catatonic; | 108 | int catatonic; |
109 | int version; | 109 | int version; |
110 | int sub_version; | 110 | int sub_version; |
111 | int min_proto; | 111 | int min_proto; |
112 | int max_proto; | 112 | int max_proto; |
113 | unsigned long exp_timeout; | 113 | unsigned long exp_timeout; |
114 | unsigned int type; | 114 | unsigned int type; |
115 | int reghost_enabled; | 115 | int reghost_enabled; |
116 | int needs_reghost; | 116 | int needs_reghost; |
117 | struct super_block *sb; | 117 | struct super_block *sb; |
118 | struct mutex wq_mutex; | 118 | struct mutex wq_mutex; |
119 | struct mutex pipe_mutex; | 119 | struct mutex pipe_mutex; |
120 | spinlock_t fs_lock; | 120 | spinlock_t fs_lock; |
121 | struct autofs_wait_queue *queues; /* Wait queue pointer */ | 121 | struct autofs_wait_queue *queues; /* Wait queue pointer */ |
122 | spinlock_t lookup_lock; | 122 | spinlock_t lookup_lock; |
123 | struct list_head active_list; | 123 | struct list_head active_list; |
124 | struct list_head expiring_list; | 124 | struct list_head expiring_list; |
125 | struct rcu_head rcu; | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb) | 128 | static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb) |
128 | { | 129 | { |
129 | return (struct autofs_sb_info *)(sb->s_fs_info); | 130 | return (struct autofs_sb_info *)(sb->s_fs_info); |
130 | } | 131 | } |
131 | 132 | ||
132 | static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry) | 133 | static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry) |
133 | { | 134 | { |
134 | return (struct autofs_info *)(dentry->d_fsdata); | 135 | return (struct autofs_info *)(dentry->d_fsdata); |
135 | } | 136 | } |
136 | 137 | ||
137 | /* autofs4_oz_mode(): do we see the man behind the curtain? (The | 138 | /* autofs4_oz_mode(): do we see the man behind the curtain? (The |
138 | processes which do manipulations for us in user space sees the raw | 139 | processes which do manipulations for us in user space sees the raw |
139 | filesystem without "magic".) */ | 140 | filesystem without "magic".) */ |
140 | 141 | ||
141 | static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { | 142 | static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { |
142 | return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp; | 143 | return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp; |
143 | } | 144 | } |
144 | 145 | ||
145 | /* Does a dentry have some pending activity? */ | 146 | /* Does a dentry have some pending activity? */ |
146 | static inline int autofs4_ispending(struct dentry *dentry) | 147 | static inline int autofs4_ispending(struct dentry *dentry) |
147 | { | 148 | { |
148 | struct autofs_info *inf = autofs4_dentry_ino(dentry); | 149 | struct autofs_info *inf = autofs4_dentry_ino(dentry); |
149 | 150 | ||
150 | if (inf->flags & AUTOFS_INF_PENDING) | 151 | if (inf->flags & AUTOFS_INF_PENDING) |
151 | return 1; | 152 | return 1; |
152 | 153 | ||
153 | if (inf->flags & AUTOFS_INF_EXPIRING) | 154 | if (inf->flags & AUTOFS_INF_EXPIRING) |
154 | return 1; | 155 | return 1; |
155 | 156 | ||
156 | return 0; | 157 | return 0; |
157 | } | 158 | } |
158 | 159 | ||
159 | struct inode *autofs4_get_inode(struct super_block *, umode_t); | 160 | struct inode *autofs4_get_inode(struct super_block *, umode_t); |
160 | void autofs4_free_ino(struct autofs_info *); | 161 | void autofs4_free_ino(struct autofs_info *); |
161 | 162 | ||
162 | /* Expiration */ | 163 | /* Expiration */ |
163 | int is_autofs4_dentry(struct dentry *); | 164 | int is_autofs4_dentry(struct dentry *); |
164 | int autofs4_expire_wait(struct dentry *dentry); | 165 | int autofs4_expire_wait(struct dentry *dentry); |
165 | int autofs4_expire_run(struct super_block *, struct vfsmount *, | 166 | int autofs4_expire_run(struct super_block *, struct vfsmount *, |
166 | struct autofs_sb_info *, | 167 | struct autofs_sb_info *, |
167 | struct autofs_packet_expire __user *); | 168 | struct autofs_packet_expire __user *); |
168 | int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, | 169 | int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, |
169 | struct autofs_sb_info *sbi, int when); | 170 | struct autofs_sb_info *sbi, int when); |
170 | int autofs4_expire_multi(struct super_block *, struct vfsmount *, | 171 | int autofs4_expire_multi(struct super_block *, struct vfsmount *, |
171 | struct autofs_sb_info *, int __user *); | 172 | struct autofs_sb_info *, int __user *); |
172 | struct dentry *autofs4_expire_direct(struct super_block *sb, | 173 | struct dentry *autofs4_expire_direct(struct super_block *sb, |
173 | struct vfsmount *mnt, | 174 | struct vfsmount *mnt, |
174 | struct autofs_sb_info *sbi, int how); | 175 | struct autofs_sb_info *sbi, int how); |
175 | struct dentry *autofs4_expire_indirect(struct super_block *sb, | 176 | struct dentry *autofs4_expire_indirect(struct super_block *sb, |
176 | struct vfsmount *mnt, | 177 | struct vfsmount *mnt, |
177 | struct autofs_sb_info *sbi, int how); | 178 | struct autofs_sb_info *sbi, int how); |
178 | 179 | ||
179 | /* Device node initialization */ | 180 | /* Device node initialization */ |
180 | 181 | ||
181 | int autofs_dev_ioctl_init(void); | 182 | int autofs_dev_ioctl_init(void); |
182 | void autofs_dev_ioctl_exit(void); | 183 | void autofs_dev_ioctl_exit(void); |
183 | 184 | ||
184 | /* Operations structures */ | 185 | /* Operations structures */ |
185 | 186 | ||
186 | extern const struct inode_operations autofs4_symlink_inode_operations; | 187 | extern const struct inode_operations autofs4_symlink_inode_operations; |
187 | extern const struct inode_operations autofs4_dir_inode_operations; | 188 | extern const struct inode_operations autofs4_dir_inode_operations; |
188 | extern const struct file_operations autofs4_dir_operations; | 189 | extern const struct file_operations autofs4_dir_operations; |
189 | extern const struct file_operations autofs4_root_operations; | 190 | extern const struct file_operations autofs4_root_operations; |
190 | extern const struct dentry_operations autofs4_dentry_operations; | 191 | extern const struct dentry_operations autofs4_dentry_operations; |
191 | 192 | ||
192 | /* VFS automount flags management functions */ | 193 | /* VFS automount flags management functions */ |
193 | 194 | ||
194 | static inline void __managed_dentry_set_automount(struct dentry *dentry) | 195 | static inline void __managed_dentry_set_automount(struct dentry *dentry) |
195 | { | 196 | { |
196 | dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; | 197 | dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; |
197 | } | 198 | } |
198 | 199 | ||
199 | static inline void managed_dentry_set_automount(struct dentry *dentry) | 200 | static inline void managed_dentry_set_automount(struct dentry *dentry) |
200 | { | 201 | { |
201 | spin_lock(&dentry->d_lock); | 202 | spin_lock(&dentry->d_lock); |
202 | __managed_dentry_set_automount(dentry); | 203 | __managed_dentry_set_automount(dentry); |
203 | spin_unlock(&dentry->d_lock); | 204 | spin_unlock(&dentry->d_lock); |
204 | } | 205 | } |
205 | 206 | ||
206 | static inline void __managed_dentry_clear_automount(struct dentry *dentry) | 207 | static inline void __managed_dentry_clear_automount(struct dentry *dentry) |
207 | { | 208 | { |
208 | dentry->d_flags &= ~DCACHE_NEED_AUTOMOUNT; | 209 | dentry->d_flags &= ~DCACHE_NEED_AUTOMOUNT; |
209 | } | 210 | } |
210 | 211 | ||
211 | static inline void managed_dentry_clear_automount(struct dentry *dentry) | 212 | static inline void managed_dentry_clear_automount(struct dentry *dentry) |
212 | { | 213 | { |
213 | spin_lock(&dentry->d_lock); | 214 | spin_lock(&dentry->d_lock); |
214 | __managed_dentry_clear_automount(dentry); | 215 | __managed_dentry_clear_automount(dentry); |
215 | spin_unlock(&dentry->d_lock); | 216 | spin_unlock(&dentry->d_lock); |
216 | } | 217 | } |
217 | 218 | ||
218 | static inline void __managed_dentry_set_transit(struct dentry *dentry) | 219 | static inline void __managed_dentry_set_transit(struct dentry *dentry) |
219 | { | 220 | { |
220 | dentry->d_flags |= DCACHE_MANAGE_TRANSIT; | 221 | dentry->d_flags |= DCACHE_MANAGE_TRANSIT; |
221 | } | 222 | } |
222 | 223 | ||
223 | static inline void managed_dentry_set_transit(struct dentry *dentry) | 224 | static inline void managed_dentry_set_transit(struct dentry *dentry) |
224 | { | 225 | { |
225 | spin_lock(&dentry->d_lock); | 226 | spin_lock(&dentry->d_lock); |
226 | __managed_dentry_set_transit(dentry); | 227 | __managed_dentry_set_transit(dentry); |
227 | spin_unlock(&dentry->d_lock); | 228 | spin_unlock(&dentry->d_lock); |
228 | } | 229 | } |
229 | 230 | ||
230 | static inline void __managed_dentry_clear_transit(struct dentry *dentry) | 231 | static inline void __managed_dentry_clear_transit(struct dentry *dentry) |
231 | { | 232 | { |
232 | dentry->d_flags &= ~DCACHE_MANAGE_TRANSIT; | 233 | dentry->d_flags &= ~DCACHE_MANAGE_TRANSIT; |
233 | } | 234 | } |
234 | 235 | ||
235 | static inline void managed_dentry_clear_transit(struct dentry *dentry) | 236 | static inline void managed_dentry_clear_transit(struct dentry *dentry) |
236 | { | 237 | { |
237 | spin_lock(&dentry->d_lock); | 238 | spin_lock(&dentry->d_lock); |
238 | __managed_dentry_clear_transit(dentry); | 239 | __managed_dentry_clear_transit(dentry); |
239 | spin_unlock(&dentry->d_lock); | 240 | spin_unlock(&dentry->d_lock); |
240 | } | 241 | } |
241 | 242 | ||
242 | static inline void __managed_dentry_set_managed(struct dentry *dentry) | 243 | static inline void __managed_dentry_set_managed(struct dentry *dentry) |
243 | { | 244 | { |
244 | dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); | 245 | dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); |
245 | } | 246 | } |
246 | 247 | ||
247 | static inline void managed_dentry_set_managed(struct dentry *dentry) | 248 | static inline void managed_dentry_set_managed(struct dentry *dentry) |
248 | { | 249 | { |
249 | spin_lock(&dentry->d_lock); | 250 | spin_lock(&dentry->d_lock); |
250 | __managed_dentry_set_managed(dentry); | 251 | __managed_dentry_set_managed(dentry); |
251 | spin_unlock(&dentry->d_lock); | 252 | spin_unlock(&dentry->d_lock); |
252 | } | 253 | } |
253 | 254 | ||
254 | static inline void __managed_dentry_clear_managed(struct dentry *dentry) | 255 | static inline void __managed_dentry_clear_managed(struct dentry *dentry) |
255 | { | 256 | { |
256 | dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); | 257 | dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); |
257 | } | 258 | } |
258 | 259 | ||
259 | static inline void managed_dentry_clear_managed(struct dentry *dentry) | 260 | static inline void managed_dentry_clear_managed(struct dentry *dentry) |
260 | { | 261 | { |
261 | spin_lock(&dentry->d_lock); | 262 | spin_lock(&dentry->d_lock); |
262 | __managed_dentry_clear_managed(dentry); | 263 | __managed_dentry_clear_managed(dentry); |
263 | spin_unlock(&dentry->d_lock); | 264 | spin_unlock(&dentry->d_lock); |
264 | } | 265 | } |
265 | 266 | ||
266 | /* Initializing function */ | 267 | /* Initializing function */ |
267 | 268 | ||
268 | int autofs4_fill_super(struct super_block *, void *, int); | 269 | int autofs4_fill_super(struct super_block *, void *, int); |
269 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *); | 270 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *); |
270 | void autofs4_clean_ino(struct autofs_info *); | 271 | void autofs4_clean_ino(struct autofs_info *); |
271 | 272 | ||
272 | static inline int autofs_prepare_pipe(struct file *pipe) | 273 | static inline int autofs_prepare_pipe(struct file *pipe) |
273 | { | 274 | { |
274 | if (!pipe->f_op->write) | 275 | if (!pipe->f_op->write) |
275 | return -EINVAL; | 276 | return -EINVAL; |
276 | if (!S_ISFIFO(file_inode(pipe)->i_mode)) | 277 | if (!S_ISFIFO(file_inode(pipe)->i_mode)) |
277 | return -EINVAL; | 278 | return -EINVAL; |
278 | /* We want a packet pipe */ | 279 | /* We want a packet pipe */ |
279 | pipe->f_flags |= O_DIRECT; | 280 | pipe->f_flags |= O_DIRECT; |
280 | return 0; | 281 | return 0; |
281 | } | 282 | } |
282 | 283 | ||
283 | /* Queue management functions */ | 284 | /* Queue management functions */ |
284 | 285 | ||
285 | int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); | 286 | int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); |
286 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); | 287 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); |
287 | void autofs4_catatonic_mode(struct autofs_sb_info *); | 288 | void autofs4_catatonic_mode(struct autofs_sb_info *); |
288 | 289 | ||
289 | static inline u32 autofs4_get_dev(struct autofs_sb_info *sbi) | 290 | static inline u32 autofs4_get_dev(struct autofs_sb_info *sbi) |
290 | { | 291 | { |
291 | return new_encode_dev(sbi->sb->s_dev); | 292 | return new_encode_dev(sbi->sb->s_dev); |
292 | } | 293 | } |
293 | 294 | ||
294 | static inline u64 autofs4_get_ino(struct autofs_sb_info *sbi) | 295 | static inline u64 autofs4_get_ino(struct autofs_sb_info *sbi) |
295 | { | 296 | { |
296 | return sbi->sb->s_root->d_inode->i_ino; | 297 | return sbi->sb->s_root->d_inode->i_ino; |
297 | } | 298 | } |
298 | 299 | ||
299 | static inline int simple_positive(struct dentry *dentry) | 300 | static inline int simple_positive(struct dentry *dentry) |
300 | { | 301 | { |
301 | return dentry->d_inode && !d_unhashed(dentry); | 302 | return dentry->d_inode && !d_unhashed(dentry); |
302 | } | 303 | } |
303 | 304 | ||
304 | static inline void __autofs4_add_expiring(struct dentry *dentry) | 305 | static inline void __autofs4_add_expiring(struct dentry *dentry) |
305 | { | 306 | { |
306 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 307 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
307 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 308 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
308 | if (ino) { | 309 | if (ino) { |
309 | if (list_empty(&ino->expiring)) | 310 | if (list_empty(&ino->expiring)) |
310 | list_add(&ino->expiring, &sbi->expiring_list); | 311 | list_add(&ino->expiring, &sbi->expiring_list); |
311 | } | 312 | } |
312 | return; | 313 | return; |
313 | } | 314 | } |
314 | 315 | ||
315 | static inline void autofs4_add_expiring(struct dentry *dentry) | 316 | static inline void autofs4_add_expiring(struct dentry *dentry) |
316 | { | 317 | { |
317 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 318 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
318 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 319 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
319 | if (ino) { | 320 | if (ino) { |
320 | spin_lock(&sbi->lookup_lock); | 321 | spin_lock(&sbi->lookup_lock); |
321 | if (list_empty(&ino->expiring)) | 322 | if (list_empty(&ino->expiring)) |
322 | list_add(&ino->expiring, &sbi->expiring_list); | 323 | list_add(&ino->expiring, &sbi->expiring_list); |
323 | spin_unlock(&sbi->lookup_lock); | 324 | spin_unlock(&sbi->lookup_lock); |
324 | } | 325 | } |
325 | return; | 326 | return; |
326 | } | 327 | } |
327 | 328 | ||
328 | static inline void autofs4_del_expiring(struct dentry *dentry) | 329 | static inline void autofs4_del_expiring(struct dentry *dentry) |
329 | { | 330 | { |
330 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 331 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
331 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 332 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
332 | if (ino) { | 333 | if (ino) { |
333 | spin_lock(&sbi->lookup_lock); | 334 | spin_lock(&sbi->lookup_lock); |
334 | if (!list_empty(&ino->expiring)) | 335 | if (!list_empty(&ino->expiring)) |
335 | list_del_init(&ino->expiring); | 336 | list_del_init(&ino->expiring); |
336 | spin_unlock(&sbi->lookup_lock); | 337 | spin_unlock(&sbi->lookup_lock); |
337 | } | 338 | } |
338 | return; | 339 | return; |
339 | } | 340 | } |
340 | 341 | ||
341 | extern void autofs4_kill_sb(struct super_block *); | 342 | extern void autofs4_kill_sb(struct super_block *); |
342 | 343 |
fs/autofs4/inode.c
1 | /* -*- c -*- --------------------------------------------------------------- * | 1 | /* -*- c -*- --------------------------------------------------------------- * |
2 | * | 2 | * |
3 | * linux/fs/autofs/inode.c | 3 | * linux/fs/autofs/inode.c |
4 | * | 4 | * |
5 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved | 5 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved |
6 | * Copyright 2005-2006 Ian Kent <raven@themaw.net> | 6 | * Copyright 2005-2006 Ian Kent <raven@themaw.net> |
7 | * | 7 | * |
8 | * This file is part of the Linux kernel and is made available under | 8 | * This file is part of the Linux kernel and is made available under |
9 | * the terms of the GNU General Public License, version 2, or at your | 9 | * the terms of the GNU General Public License, version 2, or at your |
10 | * option, any later version, incorporated herein by reference. | 10 | * option, any later version, incorporated herein by reference. |
11 | * | 11 | * |
12 | * ------------------------------------------------------------------------- */ | 12 | * ------------------------------------------------------------------------- */ |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/file.h> | 16 | #include <linux/file.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/parser.h> | 19 | #include <linux/parser.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
22 | #include "autofs_i.h" | 22 | #include "autofs_i.h" |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | 24 | ||
25 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *sbi) | 25 | struct autofs_info *autofs4_new_ino(struct autofs_sb_info *sbi) |
26 | { | 26 | { |
27 | struct autofs_info *ino = kzalloc(sizeof(*ino), GFP_KERNEL); | 27 | struct autofs_info *ino = kzalloc(sizeof(*ino), GFP_KERNEL); |
28 | if (ino) { | 28 | if (ino) { |
29 | INIT_LIST_HEAD(&ino->active); | 29 | INIT_LIST_HEAD(&ino->active); |
30 | INIT_LIST_HEAD(&ino->expiring); | 30 | INIT_LIST_HEAD(&ino->expiring); |
31 | ino->last_used = jiffies; | 31 | ino->last_used = jiffies; |
32 | ino->sbi = sbi; | 32 | ino->sbi = sbi; |
33 | } | 33 | } |
34 | return ino; | 34 | return ino; |
35 | } | 35 | } |
36 | 36 | ||
37 | void autofs4_clean_ino(struct autofs_info *ino) | 37 | void autofs4_clean_ino(struct autofs_info *ino) |
38 | { | 38 | { |
39 | ino->uid = GLOBAL_ROOT_UID; | 39 | ino->uid = GLOBAL_ROOT_UID; |
40 | ino->gid = GLOBAL_ROOT_GID; | 40 | ino->gid = GLOBAL_ROOT_GID; |
41 | ino->last_used = jiffies; | 41 | ino->last_used = jiffies; |
42 | } | 42 | } |
43 | 43 | ||
44 | void autofs4_free_ino(struct autofs_info *ino) | 44 | void autofs4_free_ino(struct autofs_info *ino) |
45 | { | 45 | { |
46 | kfree(ino); | 46 | kfree(ino); |
47 | } | 47 | } |
48 | 48 | ||
49 | void autofs4_kill_sb(struct super_block *sb) | 49 | void autofs4_kill_sb(struct super_block *sb) |
50 | { | 50 | { |
51 | struct autofs_sb_info *sbi = autofs4_sbi(sb); | 51 | struct autofs_sb_info *sbi = autofs4_sbi(sb); |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * In the event of a failure in get_sb_nodev the superblock | 54 | * In the event of a failure in get_sb_nodev the superblock |
55 | * info is not present so nothing else has been setup, so | 55 | * info is not present so nothing else has been setup, so |
56 | * just call kill_anon_super when we are called from | 56 | * just call kill_anon_super when we are called from |
57 | * deactivate_super. | 57 | * deactivate_super. |
58 | */ | 58 | */ |
59 | if (!sbi) | 59 | if (sbi) /* Free wait queues, close pipe */ |
60 | goto out_kill_sb; | 60 | autofs4_catatonic_mode(sbi); |
61 | 61 | ||
62 | /* Free wait queues, close pipe */ | ||
63 | autofs4_catatonic_mode(sbi); | ||
64 | |||
65 | sb->s_fs_info = NULL; | ||
66 | kfree(sbi); | ||
67 | |||
68 | out_kill_sb: | ||
69 | DPRINTK("shutting down"); | 62 | DPRINTK("shutting down"); |
70 | kill_litter_super(sb); | 63 | kill_litter_super(sb); |
64 | if (sbi) | ||
65 | kfree_rcu(sbi, rcu); | ||
71 | } | 66 | } |
72 | 67 | ||
73 | static int autofs4_show_options(struct seq_file *m, struct dentry *root) | 68 | static int autofs4_show_options(struct seq_file *m, struct dentry *root) |
74 | { | 69 | { |
75 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | 70 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); |
76 | struct inode *root_inode = root->d_sb->s_root->d_inode; | 71 | struct inode *root_inode = root->d_sb->s_root->d_inode; |
77 | 72 | ||
78 | if (!sbi) | 73 | if (!sbi) |
79 | return 0; | 74 | return 0; |
80 | 75 | ||
81 | seq_printf(m, ",fd=%d", sbi->pipefd); | 76 | seq_printf(m, ",fd=%d", sbi->pipefd); |
82 | if (!uid_eq(root_inode->i_uid, GLOBAL_ROOT_UID)) | 77 | if (!uid_eq(root_inode->i_uid, GLOBAL_ROOT_UID)) |
83 | seq_printf(m, ",uid=%u", | 78 | seq_printf(m, ",uid=%u", |
84 | from_kuid_munged(&init_user_ns, root_inode->i_uid)); | 79 | from_kuid_munged(&init_user_ns, root_inode->i_uid)); |
85 | if (!gid_eq(root_inode->i_gid, GLOBAL_ROOT_GID)) | 80 | if (!gid_eq(root_inode->i_gid, GLOBAL_ROOT_GID)) |
86 | seq_printf(m, ",gid=%u", | 81 | seq_printf(m, ",gid=%u", |
87 | from_kgid_munged(&init_user_ns, root_inode->i_gid)); | 82 | from_kgid_munged(&init_user_ns, root_inode->i_gid)); |
88 | seq_printf(m, ",pgrp=%d", sbi->oz_pgrp); | 83 | seq_printf(m, ",pgrp=%d", sbi->oz_pgrp); |
89 | seq_printf(m, ",timeout=%lu", sbi->exp_timeout/HZ); | 84 | seq_printf(m, ",timeout=%lu", sbi->exp_timeout/HZ); |
90 | seq_printf(m, ",minproto=%d", sbi->min_proto); | 85 | seq_printf(m, ",minproto=%d", sbi->min_proto); |
91 | seq_printf(m, ",maxproto=%d", sbi->max_proto); | 86 | seq_printf(m, ",maxproto=%d", sbi->max_proto); |
92 | 87 | ||
93 | if (autofs_type_offset(sbi->type)) | 88 | if (autofs_type_offset(sbi->type)) |
94 | seq_printf(m, ",offset"); | 89 | seq_printf(m, ",offset"); |
95 | else if (autofs_type_direct(sbi->type)) | 90 | else if (autofs_type_direct(sbi->type)) |
96 | seq_printf(m, ",direct"); | 91 | seq_printf(m, ",direct"); |
97 | else | 92 | else |
98 | seq_printf(m, ",indirect"); | 93 | seq_printf(m, ",indirect"); |
99 | 94 | ||
100 | return 0; | 95 | return 0; |
101 | } | 96 | } |
102 | 97 | ||
103 | static void autofs4_evict_inode(struct inode *inode) | 98 | static void autofs4_evict_inode(struct inode *inode) |
104 | { | 99 | { |
105 | clear_inode(inode); | 100 | clear_inode(inode); |
106 | kfree(inode->i_private); | 101 | kfree(inode->i_private); |
107 | } | 102 | } |
108 | 103 | ||
109 | static const struct super_operations autofs4_sops = { | 104 | static const struct super_operations autofs4_sops = { |
110 | .statfs = simple_statfs, | 105 | .statfs = simple_statfs, |
111 | .show_options = autofs4_show_options, | 106 | .show_options = autofs4_show_options, |
112 | .evict_inode = autofs4_evict_inode, | 107 | .evict_inode = autofs4_evict_inode, |
113 | }; | 108 | }; |
114 | 109 | ||
115 | enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto, | 110 | enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto, |
116 | Opt_indirect, Opt_direct, Opt_offset}; | 111 | Opt_indirect, Opt_direct, Opt_offset}; |
117 | 112 | ||
118 | static const match_table_t tokens = { | 113 | static const match_table_t tokens = { |
119 | {Opt_fd, "fd=%u"}, | 114 | {Opt_fd, "fd=%u"}, |
120 | {Opt_uid, "uid=%u"}, | 115 | {Opt_uid, "uid=%u"}, |
121 | {Opt_gid, "gid=%u"}, | 116 | {Opt_gid, "gid=%u"}, |
122 | {Opt_pgrp, "pgrp=%u"}, | 117 | {Opt_pgrp, "pgrp=%u"}, |
123 | {Opt_minproto, "minproto=%u"}, | 118 | {Opt_minproto, "minproto=%u"}, |
124 | {Opt_maxproto, "maxproto=%u"}, | 119 | {Opt_maxproto, "maxproto=%u"}, |
125 | {Opt_indirect, "indirect"}, | 120 | {Opt_indirect, "indirect"}, |
126 | {Opt_direct, "direct"}, | 121 | {Opt_direct, "direct"}, |
127 | {Opt_offset, "offset"}, | 122 | {Opt_offset, "offset"}, |
128 | {Opt_err, NULL} | 123 | {Opt_err, NULL} |
129 | }; | 124 | }; |
130 | 125 | ||
131 | static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid, | 126 | static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid, |
132 | pid_t *pgrp, unsigned int *type, int *minproto, int *maxproto) | 127 | pid_t *pgrp, unsigned int *type, int *minproto, int *maxproto) |
133 | { | 128 | { |
134 | char *p; | 129 | char *p; |
135 | substring_t args[MAX_OPT_ARGS]; | 130 | substring_t args[MAX_OPT_ARGS]; |
136 | int option; | 131 | int option; |
137 | 132 | ||
138 | *uid = current_uid(); | 133 | *uid = current_uid(); |
139 | *gid = current_gid(); | 134 | *gid = current_gid(); |
140 | *pgrp = task_pgrp_nr(current); | 135 | *pgrp = task_pgrp_nr(current); |
141 | 136 | ||
142 | *minproto = AUTOFS_MIN_PROTO_VERSION; | 137 | *minproto = AUTOFS_MIN_PROTO_VERSION; |
143 | *maxproto = AUTOFS_MAX_PROTO_VERSION; | 138 | *maxproto = AUTOFS_MAX_PROTO_VERSION; |
144 | 139 | ||
145 | *pipefd = -1; | 140 | *pipefd = -1; |
146 | 141 | ||
147 | if (!options) | 142 | if (!options) |
148 | return 1; | 143 | return 1; |
149 | 144 | ||
150 | while ((p = strsep(&options, ",")) != NULL) { | 145 | while ((p = strsep(&options, ",")) != NULL) { |
151 | int token; | 146 | int token; |
152 | if (!*p) | 147 | if (!*p) |
153 | continue; | 148 | continue; |
154 | 149 | ||
155 | token = match_token(p, tokens, args); | 150 | token = match_token(p, tokens, args); |
156 | switch (token) { | 151 | switch (token) { |
157 | case Opt_fd: | 152 | case Opt_fd: |
158 | if (match_int(args, pipefd)) | 153 | if (match_int(args, pipefd)) |
159 | return 1; | 154 | return 1; |
160 | break; | 155 | break; |
161 | case Opt_uid: | 156 | case Opt_uid: |
162 | if (match_int(args, &option)) | 157 | if (match_int(args, &option)) |
163 | return 1; | 158 | return 1; |
164 | *uid = make_kuid(current_user_ns(), option); | 159 | *uid = make_kuid(current_user_ns(), option); |
165 | if (!uid_valid(*uid)) | 160 | if (!uid_valid(*uid)) |
166 | return 1; | 161 | return 1; |
167 | break; | 162 | break; |
168 | case Opt_gid: | 163 | case Opt_gid: |
169 | if (match_int(args, &option)) | 164 | if (match_int(args, &option)) |
170 | return 1; | 165 | return 1; |
171 | *gid = make_kgid(current_user_ns(), option); | 166 | *gid = make_kgid(current_user_ns(), option); |
172 | if (!gid_valid(*gid)) | 167 | if (!gid_valid(*gid)) |
173 | return 1; | 168 | return 1; |
174 | break; | 169 | break; |
175 | case Opt_pgrp: | 170 | case Opt_pgrp: |
176 | if (match_int(args, &option)) | 171 | if (match_int(args, &option)) |
177 | return 1; | 172 | return 1; |
178 | *pgrp = option; | 173 | *pgrp = option; |
179 | break; | 174 | break; |
180 | case Opt_minproto: | 175 | case Opt_minproto: |
181 | if (match_int(args, &option)) | 176 | if (match_int(args, &option)) |
182 | return 1; | 177 | return 1; |
183 | *minproto = option; | 178 | *minproto = option; |
184 | break; | 179 | break; |
185 | case Opt_maxproto: | 180 | case Opt_maxproto: |
186 | if (match_int(args, &option)) | 181 | if (match_int(args, &option)) |
187 | return 1; | 182 | return 1; |
188 | *maxproto = option; | 183 | *maxproto = option; |
189 | break; | 184 | break; |
190 | case Opt_indirect: | 185 | case Opt_indirect: |
191 | set_autofs_type_indirect(type); | 186 | set_autofs_type_indirect(type); |
192 | break; | 187 | break; |
193 | case Opt_direct: | 188 | case Opt_direct: |
194 | set_autofs_type_direct(type); | 189 | set_autofs_type_direct(type); |
195 | break; | 190 | break; |
196 | case Opt_offset: | 191 | case Opt_offset: |
197 | set_autofs_type_offset(type); | 192 | set_autofs_type_offset(type); |
198 | break; | 193 | break; |
199 | default: | 194 | default: |
200 | return 1; | 195 | return 1; |
201 | } | 196 | } |
202 | } | 197 | } |
203 | return (*pipefd < 0); | 198 | return (*pipefd < 0); |
204 | } | 199 | } |
205 | 200 | ||
206 | int autofs4_fill_super(struct super_block *s, void *data, int silent) | 201 | int autofs4_fill_super(struct super_block *s, void *data, int silent) |
207 | { | 202 | { |
208 | struct inode * root_inode; | 203 | struct inode * root_inode; |
209 | struct dentry * root; | 204 | struct dentry * root; |
210 | struct file * pipe; | 205 | struct file * pipe; |
211 | int pipefd; | 206 | int pipefd; |
212 | struct autofs_sb_info *sbi; | 207 | struct autofs_sb_info *sbi; |
213 | struct autofs_info *ino; | 208 | struct autofs_info *ino; |
214 | 209 | ||
215 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 210 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
216 | if (!sbi) | 211 | if (!sbi) |
217 | goto fail_unlock; | 212 | goto fail_unlock; |
218 | DPRINTK("starting up, sbi = %p",sbi); | 213 | DPRINTK("starting up, sbi = %p",sbi); |
219 | 214 | ||
220 | s->s_fs_info = sbi; | 215 | s->s_fs_info = sbi; |
221 | sbi->magic = AUTOFS_SBI_MAGIC; | 216 | sbi->magic = AUTOFS_SBI_MAGIC; |
222 | sbi->pipefd = -1; | 217 | sbi->pipefd = -1; |
223 | sbi->pipe = NULL; | 218 | sbi->pipe = NULL; |
224 | sbi->catatonic = 1; | 219 | sbi->catatonic = 1; |
225 | sbi->exp_timeout = 0; | 220 | sbi->exp_timeout = 0; |
226 | sbi->oz_pgrp = task_pgrp_nr(current); | 221 | sbi->oz_pgrp = task_pgrp_nr(current); |
227 | sbi->sb = s; | 222 | sbi->sb = s; |
228 | sbi->version = 0; | 223 | sbi->version = 0; |
229 | sbi->sub_version = 0; | 224 | sbi->sub_version = 0; |
230 | set_autofs_type_indirect(&sbi->type); | 225 | set_autofs_type_indirect(&sbi->type); |
231 | sbi->min_proto = 0; | 226 | sbi->min_proto = 0; |
232 | sbi->max_proto = 0; | 227 | sbi->max_proto = 0; |
233 | mutex_init(&sbi->wq_mutex); | 228 | mutex_init(&sbi->wq_mutex); |
234 | mutex_init(&sbi->pipe_mutex); | 229 | mutex_init(&sbi->pipe_mutex); |
235 | spin_lock_init(&sbi->fs_lock); | 230 | spin_lock_init(&sbi->fs_lock); |
236 | sbi->queues = NULL; | 231 | sbi->queues = NULL; |
237 | spin_lock_init(&sbi->lookup_lock); | 232 | spin_lock_init(&sbi->lookup_lock); |
238 | INIT_LIST_HEAD(&sbi->active_list); | 233 | INIT_LIST_HEAD(&sbi->active_list); |
239 | INIT_LIST_HEAD(&sbi->expiring_list); | 234 | INIT_LIST_HEAD(&sbi->expiring_list); |
240 | s->s_blocksize = 1024; | 235 | s->s_blocksize = 1024; |
241 | s->s_blocksize_bits = 10; | 236 | s->s_blocksize_bits = 10; |
242 | s->s_magic = AUTOFS_SUPER_MAGIC; | 237 | s->s_magic = AUTOFS_SUPER_MAGIC; |
243 | s->s_op = &autofs4_sops; | 238 | s->s_op = &autofs4_sops; |
244 | s->s_d_op = &autofs4_dentry_operations; | 239 | s->s_d_op = &autofs4_dentry_operations; |
245 | s->s_time_gran = 1; | 240 | s->s_time_gran = 1; |
246 | 241 | ||
247 | /* | 242 | /* |
248 | * Get the root inode and dentry, but defer checking for errors. | 243 | * Get the root inode and dentry, but defer checking for errors. |
249 | */ | 244 | */ |
250 | ino = autofs4_new_ino(sbi); | 245 | ino = autofs4_new_ino(sbi); |
251 | if (!ino) | 246 | if (!ino) |
252 | goto fail_free; | 247 | goto fail_free; |
253 | root_inode = autofs4_get_inode(s, S_IFDIR | 0755); | 248 | root_inode = autofs4_get_inode(s, S_IFDIR | 0755); |
254 | root = d_make_root(root_inode); | 249 | root = d_make_root(root_inode); |
255 | if (!root) | 250 | if (!root) |
256 | goto fail_ino; | 251 | goto fail_ino; |
257 | pipe = NULL; | 252 | pipe = NULL; |
258 | 253 | ||
259 | root->d_fsdata = ino; | 254 | root->d_fsdata = ino; |
260 | 255 | ||
261 | /* Can this call block? */ | 256 | /* Can this call block? */ |
262 | if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid, | 257 | if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid, |
263 | &sbi->oz_pgrp, &sbi->type, &sbi->min_proto, | 258 | &sbi->oz_pgrp, &sbi->type, &sbi->min_proto, |
264 | &sbi->max_proto)) { | 259 | &sbi->max_proto)) { |
265 | printk("autofs: called with bogus options\n"); | 260 | printk("autofs: called with bogus options\n"); |
266 | goto fail_dput; | 261 | goto fail_dput; |
267 | } | 262 | } |
268 | 263 | ||
269 | if (autofs_type_trigger(sbi->type)) | 264 | if (autofs_type_trigger(sbi->type)) |
270 | __managed_dentry_set_managed(root); | 265 | __managed_dentry_set_managed(root); |
271 | 266 | ||
272 | root_inode->i_fop = &autofs4_root_operations; | 267 | root_inode->i_fop = &autofs4_root_operations; |
273 | root_inode->i_op = &autofs4_dir_inode_operations; | 268 | root_inode->i_op = &autofs4_dir_inode_operations; |
274 | 269 | ||
275 | /* Couldn't this be tested earlier? */ | 270 | /* Couldn't this be tested earlier? */ |
276 | if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION || | 271 | if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION || |
277 | sbi->min_proto > AUTOFS_MAX_PROTO_VERSION) { | 272 | sbi->min_proto > AUTOFS_MAX_PROTO_VERSION) { |
278 | printk("autofs: kernel does not match daemon version " | 273 | printk("autofs: kernel does not match daemon version " |
279 | "daemon (%d, %d) kernel (%d, %d)\n", | 274 | "daemon (%d, %d) kernel (%d, %d)\n", |
280 | sbi->min_proto, sbi->max_proto, | 275 | sbi->min_proto, sbi->max_proto, |
281 | AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION); | 276 | AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION); |
282 | goto fail_dput; | 277 | goto fail_dput; |
283 | } | 278 | } |
284 | 279 | ||
285 | /* Establish highest kernel protocol version */ | 280 | /* Establish highest kernel protocol version */ |
286 | if (sbi->max_proto > AUTOFS_MAX_PROTO_VERSION) | 281 | if (sbi->max_proto > AUTOFS_MAX_PROTO_VERSION) |
287 | sbi->version = AUTOFS_MAX_PROTO_VERSION; | 282 | sbi->version = AUTOFS_MAX_PROTO_VERSION; |
288 | else | 283 | else |
289 | sbi->version = sbi->max_proto; | 284 | sbi->version = sbi->max_proto; |
290 | sbi->sub_version = AUTOFS_PROTO_SUBVERSION; | 285 | sbi->sub_version = AUTOFS_PROTO_SUBVERSION; |
291 | 286 | ||
292 | DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp); | 287 | DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp); |
293 | pipe = fget(pipefd); | 288 | pipe = fget(pipefd); |
294 | 289 | ||
295 | if (!pipe) { | 290 | if (!pipe) { |
296 | printk("autofs: could not open pipe file descriptor\n"); | 291 | printk("autofs: could not open pipe file descriptor\n"); |
297 | goto fail_dput; | 292 | goto fail_dput; |
298 | } | 293 | } |
299 | if (autofs_prepare_pipe(pipe) < 0) | 294 | if (autofs_prepare_pipe(pipe) < 0) |
300 | goto fail_fput; | 295 | goto fail_fput; |
301 | sbi->pipe = pipe; | 296 | sbi->pipe = pipe; |
302 | sbi->pipefd = pipefd; | 297 | sbi->pipefd = pipefd; |
303 | sbi->catatonic = 0; | 298 | sbi->catatonic = 0; |
304 | 299 | ||
305 | /* | 300 | /* |
306 | * Success! Install the root dentry now to indicate completion. | 301 | * Success! Install the root dentry now to indicate completion. |
307 | */ | 302 | */ |
308 | s->s_root = root; | 303 | s->s_root = root; |
309 | return 0; | 304 | return 0; |
310 | 305 | ||
311 | /* | 306 | /* |
312 | * Failure ... clean up. | 307 | * Failure ... clean up. |
313 | */ | 308 | */ |
314 | fail_fput: | 309 | fail_fput: |
315 | printk("autofs: pipe file descriptor does not contain proper ops\n"); | 310 | printk("autofs: pipe file descriptor does not contain proper ops\n"); |
316 | fput(pipe); | 311 | fput(pipe); |
317 | /* fall through */ | 312 | /* fall through */ |
318 | fail_dput: | 313 | fail_dput: |
319 | dput(root); | 314 | dput(root); |
320 | goto fail_free; | 315 | goto fail_free; |
321 | fail_ino: | 316 | fail_ino: |
322 | kfree(ino); | 317 | kfree(ino); |
323 | fail_free: | 318 | fail_free: |
324 | kfree(sbi); | 319 | kfree(sbi); |
325 | s->s_fs_info = NULL; | 320 | s->s_fs_info = NULL; |
326 | fail_unlock: | 321 | fail_unlock: |
327 | return -EINVAL; | 322 | return -EINVAL; |
328 | } | 323 | } |
329 | 324 | ||
330 | struct inode *autofs4_get_inode(struct super_block *sb, umode_t mode) | 325 | struct inode *autofs4_get_inode(struct super_block *sb, umode_t mode) |
331 | { | 326 | { |
332 | struct inode *inode = new_inode(sb); | 327 | struct inode *inode = new_inode(sb); |
333 | 328 | ||
334 | if (inode == NULL) | 329 | if (inode == NULL) |
335 | return NULL; | 330 | return NULL; |
336 | 331 | ||
337 | inode->i_mode = mode; | 332 | inode->i_mode = mode; |
338 | if (sb->s_root) { | 333 | if (sb->s_root) { |
339 | inode->i_uid = sb->s_root->d_inode->i_uid; | 334 | inode->i_uid = sb->s_root->d_inode->i_uid; |
340 | inode->i_gid = sb->s_root->d_inode->i_gid; | 335 | inode->i_gid = sb->s_root->d_inode->i_gid; |
341 | } | 336 | } |
342 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 337 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
343 | inode->i_ino = get_next_ino(); | 338 | inode->i_ino = get_next_ino(); |
344 | 339 | ||
345 | if (S_ISDIR(mode)) { | 340 | if (S_ISDIR(mode)) { |
346 | set_nlink(inode, 2); | 341 | set_nlink(inode, 2); |
347 | inode->i_op = &autofs4_dir_inode_operations; | 342 | inode->i_op = &autofs4_dir_inode_operations; |
348 | inode->i_fop = &autofs4_dir_operations; | 343 | inode->i_fop = &autofs4_dir_operations; |
349 | } else if (S_ISLNK(mode)) { | 344 | } else if (S_ISLNK(mode)) { |
350 | inode->i_op = &autofs4_symlink_inode_operations; | 345 | inode->i_op = &autofs4_symlink_inode_operations; |
351 | } | 346 | } |
352 | 347 | ||
353 | return inode; | 348 | return inode; |