.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved |
---|
3 | 4 | * Copyright 2005-2006 Ian Kent <raven@themaw.net> |
---|
4 | | - * |
---|
5 | | - * This file is part of the Linux kernel and is made available under |
---|
6 | | - * the terms of the GNU General Public License, version 2, or at your |
---|
7 | | - * option, any later version, incorporated herein by reference. |
---|
8 | 5 | */ |
---|
9 | 6 | |
---|
10 | 7 | #include <linux/seq_file.h> |
---|
.. | .. |
---|
36 | 33 | |
---|
37 | 34 | void autofs_free_ino(struct autofs_info *ino) |
---|
38 | 35 | { |
---|
39 | | - kfree(ino); |
---|
| 36 | + kfree_rcu(ino, rcu); |
---|
40 | 37 | } |
---|
41 | 38 | |
---|
42 | 39 | void autofs_kill_sb(struct super_block *sb) |
---|
.. | .. |
---|
82 | 79 | seq_printf(m, ",maxproto=%d", sbi->max_proto); |
---|
83 | 80 | |
---|
84 | 81 | if (autofs_type_offset(sbi->type)) |
---|
85 | | - seq_printf(m, ",offset"); |
---|
| 82 | + seq_puts(m, ",offset"); |
---|
86 | 83 | else if (autofs_type_direct(sbi->type)) |
---|
87 | | - seq_printf(m, ",direct"); |
---|
| 84 | + seq_puts(m, ",direct"); |
---|
88 | 85 | else |
---|
89 | | - seq_printf(m, ",indirect"); |
---|
| 86 | + seq_puts(m, ",indirect"); |
---|
| 87 | + if (sbi->flags & AUTOFS_SBI_STRICTEXPIRE) |
---|
| 88 | + seq_puts(m, ",strictexpire"); |
---|
| 89 | + if (sbi->flags & AUTOFS_SBI_IGNORE) |
---|
| 90 | + seq_puts(m, ",ignore"); |
---|
90 | 91 | #ifdef CONFIG_CHECKPOINT_RESTORE |
---|
91 | 92 | if (sbi->pipe) |
---|
92 | 93 | seq_printf(m, ",pipe_ino=%ld", file_inode(sbi->pipe)->i_ino); |
---|
93 | 94 | else |
---|
94 | | - seq_printf(m, ",pipe_ino=-1"); |
---|
| 95 | + seq_puts(m, ",pipe_ino=-1"); |
---|
95 | 96 | #endif |
---|
96 | 97 | return 0; |
---|
97 | 98 | } |
---|
.. | .. |
---|
109 | 110 | }; |
---|
110 | 111 | |
---|
111 | 112 | enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto, |
---|
112 | | - Opt_indirect, Opt_direct, Opt_offset}; |
---|
| 113 | + Opt_indirect, Opt_direct, Opt_offset, Opt_strictexpire, |
---|
| 114 | + Opt_ignore}; |
---|
113 | 115 | |
---|
114 | 116 | static const match_table_t tokens = { |
---|
115 | 117 | {Opt_fd, "fd=%u"}, |
---|
.. | .. |
---|
121 | 123 | {Opt_indirect, "indirect"}, |
---|
122 | 124 | {Opt_direct, "direct"}, |
---|
123 | 125 | {Opt_offset, "offset"}, |
---|
| 126 | + {Opt_strictexpire, "strictexpire"}, |
---|
| 127 | + {Opt_ignore, "ignore"}, |
---|
124 | 128 | {Opt_err, NULL} |
---|
125 | 129 | }; |
---|
126 | 130 | |
---|
127 | | -static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid, |
---|
128 | | - int *pgrp, bool *pgrp_set, unsigned int *type, |
---|
129 | | - int *minproto, int *maxproto) |
---|
| 131 | +static int parse_options(char *options, |
---|
| 132 | + struct inode *root, int *pgrp, bool *pgrp_set, |
---|
| 133 | + struct autofs_sb_info *sbi) |
---|
130 | 134 | { |
---|
131 | 135 | char *p; |
---|
132 | 136 | substring_t args[MAX_OPT_ARGS]; |
---|
133 | 137 | int option; |
---|
| 138 | + int pipefd = -1; |
---|
| 139 | + kuid_t uid; |
---|
| 140 | + kgid_t gid; |
---|
134 | 141 | |
---|
135 | | - *uid = current_uid(); |
---|
136 | | - *gid = current_gid(); |
---|
| 142 | + root->i_uid = current_uid(); |
---|
| 143 | + root->i_gid = current_gid(); |
---|
137 | 144 | |
---|
138 | | - *minproto = AUTOFS_MIN_PROTO_VERSION; |
---|
139 | | - *maxproto = AUTOFS_MAX_PROTO_VERSION; |
---|
| 145 | + sbi->min_proto = AUTOFS_MIN_PROTO_VERSION; |
---|
| 146 | + sbi->max_proto = AUTOFS_MAX_PROTO_VERSION; |
---|
140 | 147 | |
---|
141 | | - *pipefd = -1; |
---|
| 148 | + sbi->pipefd = -1; |
---|
142 | 149 | |
---|
143 | 150 | if (!options) |
---|
144 | 151 | return 1; |
---|
.. | .. |
---|
152 | 159 | token = match_token(p, tokens, args); |
---|
153 | 160 | switch (token) { |
---|
154 | 161 | case Opt_fd: |
---|
155 | | - if (match_int(args, pipefd)) |
---|
| 162 | + if (match_int(args, &pipefd)) |
---|
156 | 163 | return 1; |
---|
| 164 | + sbi->pipefd = pipefd; |
---|
157 | 165 | break; |
---|
158 | 166 | case Opt_uid: |
---|
159 | 167 | if (match_int(args, &option)) |
---|
160 | 168 | return 1; |
---|
161 | | - *uid = make_kuid(current_user_ns(), option); |
---|
162 | | - if (!uid_valid(*uid)) |
---|
| 169 | + uid = make_kuid(current_user_ns(), option); |
---|
| 170 | + if (!uid_valid(uid)) |
---|
163 | 171 | return 1; |
---|
| 172 | + root->i_uid = uid; |
---|
164 | 173 | break; |
---|
165 | 174 | case Opt_gid: |
---|
166 | 175 | if (match_int(args, &option)) |
---|
167 | 176 | return 1; |
---|
168 | | - *gid = make_kgid(current_user_ns(), option); |
---|
169 | | - if (!gid_valid(*gid)) |
---|
| 177 | + gid = make_kgid(current_user_ns(), option); |
---|
| 178 | + if (!gid_valid(gid)) |
---|
170 | 179 | return 1; |
---|
| 180 | + root->i_gid = gid; |
---|
171 | 181 | break; |
---|
172 | 182 | case Opt_pgrp: |
---|
173 | 183 | if (match_int(args, &option)) |
---|
.. | .. |
---|
178 | 188 | case Opt_minproto: |
---|
179 | 189 | if (match_int(args, &option)) |
---|
180 | 190 | return 1; |
---|
181 | | - *minproto = option; |
---|
| 191 | + sbi->min_proto = option; |
---|
182 | 192 | break; |
---|
183 | 193 | case Opt_maxproto: |
---|
184 | 194 | if (match_int(args, &option)) |
---|
185 | 195 | return 1; |
---|
186 | | - *maxproto = option; |
---|
| 196 | + sbi->max_proto = option; |
---|
187 | 197 | break; |
---|
188 | 198 | case Opt_indirect: |
---|
189 | | - set_autofs_type_indirect(type); |
---|
| 199 | + set_autofs_type_indirect(&sbi->type); |
---|
190 | 200 | break; |
---|
191 | 201 | case Opt_direct: |
---|
192 | | - set_autofs_type_direct(type); |
---|
| 202 | + set_autofs_type_direct(&sbi->type); |
---|
193 | 203 | break; |
---|
194 | 204 | case Opt_offset: |
---|
195 | | - set_autofs_type_offset(type); |
---|
| 205 | + set_autofs_type_offset(&sbi->type); |
---|
| 206 | + break; |
---|
| 207 | + case Opt_strictexpire: |
---|
| 208 | + sbi->flags |= AUTOFS_SBI_STRICTEXPIRE; |
---|
| 209 | + break; |
---|
| 210 | + case Opt_ignore: |
---|
| 211 | + sbi->flags |= AUTOFS_SBI_IGNORE; |
---|
196 | 212 | break; |
---|
197 | 213 | default: |
---|
198 | 214 | return 1; |
---|
199 | 215 | } |
---|
200 | 216 | } |
---|
201 | | - return (*pipefd < 0); |
---|
| 217 | + return (sbi->pipefd < 0); |
---|
202 | 218 | } |
---|
203 | 219 | |
---|
204 | 220 | int autofs_fill_super(struct super_block *s, void *data, int silent) |
---|
.. | .. |
---|
206 | 222 | struct inode *root_inode; |
---|
207 | 223 | struct dentry *root; |
---|
208 | 224 | struct file *pipe; |
---|
209 | | - int pipefd; |
---|
210 | 225 | struct autofs_sb_info *sbi; |
---|
211 | 226 | struct autofs_info *ino; |
---|
212 | 227 | int pgrp = 0; |
---|
.. | .. |
---|
222 | 237 | sbi->magic = AUTOFS_SBI_MAGIC; |
---|
223 | 238 | sbi->pipefd = -1; |
---|
224 | 239 | sbi->pipe = NULL; |
---|
225 | | - sbi->catatonic = 1; |
---|
226 | 240 | sbi->exp_timeout = 0; |
---|
227 | 241 | sbi->oz_pgrp = NULL; |
---|
228 | 242 | sbi->sb = s; |
---|
229 | 243 | sbi->version = 0; |
---|
230 | 244 | sbi->sub_version = 0; |
---|
| 245 | + sbi->flags = AUTOFS_SBI_CATATONIC; |
---|
231 | 246 | set_autofs_type_indirect(&sbi->type); |
---|
232 | 247 | sbi->min_proto = 0; |
---|
233 | 248 | sbi->max_proto = 0; |
---|
.. | .. |
---|
264 | 279 | root->d_fsdata = ino; |
---|
265 | 280 | |
---|
266 | 281 | /* Can this call block? */ |
---|
267 | | - if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid, |
---|
268 | | - &pgrp, &pgrp_set, &sbi->type, &sbi->min_proto, |
---|
269 | | - &sbi->max_proto)) { |
---|
| 282 | + if (parse_options(data, root_inode, &pgrp, &pgrp_set, sbi)) { |
---|
270 | 283 | pr_err("called with bogus options\n"); |
---|
271 | 284 | goto fail_dput; |
---|
272 | 285 | } |
---|
.. | .. |
---|
305 | 318 | root_inode->i_fop = &autofs_root_operations; |
---|
306 | 319 | root_inode->i_op = &autofs_dir_inode_operations; |
---|
307 | 320 | |
---|
308 | | - pr_debug("pipe fd = %d, pgrp = %u\n", pipefd, pid_nr(sbi->oz_pgrp)); |
---|
309 | | - pipe = fget(pipefd); |
---|
| 321 | + pr_debug("pipe fd = %d, pgrp = %u\n", |
---|
| 322 | + sbi->pipefd, pid_nr(sbi->oz_pgrp)); |
---|
| 323 | + pipe = fget(sbi->pipefd); |
---|
310 | 324 | |
---|
311 | 325 | if (!pipe) { |
---|
312 | 326 | pr_err("could not open pipe file descriptor\n"); |
---|
.. | .. |
---|
316 | 330 | if (ret < 0) |
---|
317 | 331 | goto fail_fput; |
---|
318 | 332 | sbi->pipe = pipe; |
---|
319 | | - sbi->pipefd = pipefd; |
---|
320 | | - sbi->catatonic = 0; |
---|
| 333 | + sbi->flags &= ~AUTOFS_SBI_CATATONIC; |
---|
321 | 334 | |
---|
322 | 335 | /* |
---|
323 | 336 | * Success! Install the root dentry now to indicate completion. |
---|