diff options
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r-- | fs/autofs4/inode.c | 115 |
1 files changed, 28 insertions, 87 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 821b2b955dac..180fa2425e49 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -22,77 +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->inode = NULL; | ||
49 | ino->dentry = NULL; | ||
50 | ino->size = 0; | ||
51 | INIT_LIST_HEAD(&ino->active); | 29 | INIT_LIST_HEAD(&ino->active); |
52 | ino->active_count = 0; | ||
53 | INIT_LIST_HEAD(&ino->expiring); | 30 | INIT_LIST_HEAD(&ino->expiring); |
54 | atomic_set(&ino->count, 0); | 31 | ino->last_used = jiffies; |
32 | ino->sbi = sbi; | ||
55 | } | 33 | } |
34 | return ino; | ||
35 | } | ||
56 | 36 | ||
37 | void autofs4_clean_ino(struct autofs_info *ino) | ||
38 | { | ||
57 | ino->uid = 0; | 39 | ino->uid = 0; |
58 | ino->gid = 0; | 40 | ino->gid = 0; |
59 | ino->mode = mode; | ||
60 | ino->last_used = jiffies; | 41 | ino->last_used = jiffies; |
61 | |||
62 | ino->sbi = sbi; | ||
63 | |||
64 | if (reinit && ino->free) | ||
65 | (ino->free)(ino); | ||
66 | |||
67 | memset(&ino->u, 0, sizeof(ino->u)); | ||
68 | |||
69 | ino->free = NULL; | ||
70 | |||
71 | if (S_ISLNK(mode)) | ||
72 | ino->free = ino_lnkfree; | ||
73 | |||
74 | return ino; | ||
75 | } | 42 | } |
76 | 43 | ||
77 | void autofs4_free_ino(struct autofs_info *ino) | 44 | void autofs4_free_ino(struct autofs_info *ino) |
78 | { | 45 | { |
79 | struct autofs_info *p_ino; | ||
80 | |||
81 | if (ino->dentry) { | ||
82 | ino->dentry->d_fsdata = NULL; | ||
83 | if (ino->dentry->d_inode) { | ||
84 | struct dentry *parent = ino->dentry->d_parent; | ||
85 | if (atomic_dec_and_test(&ino->count)) { | ||
86 | p_ino = autofs4_dentry_ino(parent); | ||
87 | if (p_ino && parent != ino->dentry) | ||
88 | atomic_dec(&p_ino->count); | ||
89 | } | ||
90 | dput(ino->dentry); | ||
91 | } | ||
92 | ino->dentry = NULL; | ||
93 | } | ||
94 | if (ino->free) | ||
95 | (ino->free)(ino); | ||
96 | kfree(ino); | 46 | kfree(ino); |
97 | } | 47 | } |
98 | 48 | ||
@@ -148,9 +98,16 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
148 | return 0; | 98 | return 0; |
149 | } | 99 | } |
150 | 100 | ||
101 | static void autofs4_evict_inode(struct inode *inode) | ||
102 | { | ||
103 | end_writeback(inode); | ||
104 | kfree(inode->i_private); | ||
105 | } | ||
106 | |||
151 | static const struct super_operations autofs4_sops = { | 107 | static const struct super_operations autofs4_sops = { |
152 | .statfs = simple_statfs, | 108 | .statfs = simple_statfs, |
153 | .show_options = autofs4_show_options, | 109 | .show_options = autofs4_show_options, |
110 | .evict_inode = autofs4_evict_inode, | ||
154 | }; | 111 | }; |
155 | 112 | ||
156 | 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, |
@@ -240,21 +197,6 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
240 | return (*pipefd < 0); | 197 | return (*pipefd < 0); |
241 | } | 198 | } |
242 | 199 | ||
243 | static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) | ||
244 | { | ||
245 | struct autofs_info *ino; | ||
246 | |||
247 | ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755); | ||
248 | if (!ino) | ||
249 | return NULL; | ||
250 | |||
251 | return ino; | ||
252 | } | ||
253 | |||
254 | static const struct dentry_operations autofs4_sb_dentry_operations = { | ||
255 | .d_release = autofs4_dentry_release, | ||
256 | }; | ||
257 | |||
258 | 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) |
259 | { | 201 | { |
260 | struct inode * root_inode; | 202 | struct inode * root_inode; |
@@ -292,15 +234,16 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
292 | s->s_blocksize_bits = 10; | 234 | s->s_blocksize_bits = 10; |
293 | s->s_magic = AUTOFS_SUPER_MAGIC; | 235 | s->s_magic = AUTOFS_SUPER_MAGIC; |
294 | s->s_op = &autofs4_sops; | 236 | s->s_op = &autofs4_sops; |
237 | s->s_d_op = &autofs4_dentry_operations; | ||
295 | s->s_time_gran = 1; | 238 | s->s_time_gran = 1; |
296 | 239 | ||
297 | /* | 240 | /* |
298 | * Get the root inode and dentry, but defer checking for errors. | 241 | * Get the root inode and dentry, but defer checking for errors. |
299 | */ | 242 | */ |
300 | ino = autofs4_mkroot(sbi); | 243 | ino = autofs4_new_ino(sbi); |
301 | if (!ino) | 244 | if (!ino) |
302 | goto fail_free; | 245 | goto fail_free; |
303 | root_inode = autofs4_get_inode(s, ino); | 246 | root_inode = autofs4_get_inode(s, S_IFDIR | 0755); |
304 | if (!root_inode) | 247 | if (!root_inode) |
305 | goto fail_ino; | 248 | goto fail_ino; |
306 | 249 | ||
@@ -309,7 +252,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
309 | goto fail_iput; | 252 | goto fail_iput; |
310 | pipe = NULL; | 253 | pipe = NULL; |
311 | 254 | ||
312 | root->d_op = &autofs4_sb_dentry_operations; | ||
313 | root->d_fsdata = ino; | 255 | root->d_fsdata = ino; |
314 | 256 | ||
315 | /* Can this call block? */ | 257 | /* Can this call block? */ |
@@ -320,10 +262,11 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
320 | goto fail_dput; | 262 | goto fail_dput; |
321 | } | 263 | } |
322 | 264 | ||
265 | if (autofs_type_trigger(sbi->type)) | ||
266 | __managed_dentry_set_managed(root); | ||
267 | |||
323 | root_inode->i_fop = &autofs4_root_operations; | 268 | root_inode->i_fop = &autofs4_root_operations; |
324 | root_inode->i_op = autofs_type_trigger(sbi->type) ? | 269 | root_inode->i_op = &autofs4_dir_inode_operations; |
325 | &autofs4_direct_root_inode_operations : | ||
326 | &autofs4_indirect_root_inode_operations; | ||
327 | 270 | ||
328 | /* Couldn't this be tested earlier? */ | 271 | /* Couldn't this be tested earlier? */ |
329 | if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION || | 272 | if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION || |
@@ -383,28 +326,26 @@ fail_unlock: | |||
383 | return -EINVAL; | 326 | return -EINVAL; |
384 | } | 327 | } |
385 | 328 | ||
386 | struct inode *autofs4_get_inode(struct super_block *sb, | 329 | struct inode *autofs4_get_inode(struct super_block *sb, mode_t mode) |
387 | struct autofs_info *inf) | ||
388 | { | 330 | { |
389 | struct inode *inode = new_inode(sb); | 331 | struct inode *inode = new_inode(sb); |
390 | 332 | ||
391 | if (inode == NULL) | 333 | if (inode == NULL) |
392 | return NULL; | 334 | return NULL; |
393 | 335 | ||
394 | inf->inode = inode; | 336 | inode->i_mode = mode; |
395 | inode->i_mode = inf->mode; | ||
396 | if (sb->s_root) { | 337 | if (sb->s_root) { |
397 | inode->i_uid = sb->s_root->d_inode->i_uid; | 338 | inode->i_uid = sb->s_root->d_inode->i_uid; |
398 | inode->i_gid = sb->s_root->d_inode->i_gid; | 339 | inode->i_gid = sb->s_root->d_inode->i_gid; |
399 | } | 340 | } |
400 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 341 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
342 | inode->i_ino = get_next_ino(); | ||
401 | 343 | ||
402 | if (S_ISDIR(inf->mode)) { | 344 | if (S_ISDIR(mode)) { |
403 | inode->i_nlink = 2; | 345 | inode->i_nlink = 2; |
404 | inode->i_op = &autofs4_dir_inode_operations; | 346 | inode->i_op = &autofs4_dir_inode_operations; |
405 | inode->i_fop = &autofs4_dir_operations; | 347 | inode->i_fop = &autofs4_dir_operations; |
406 | } else if (S_ISLNK(inf->mode)) { | 348 | } else if (S_ISLNK(mode)) { |
407 | inode->i_size = inf->size; | ||
408 | inode->i_op = &autofs4_symlink_inode_operations; | 349 | inode->i_op = &autofs4_symlink_inode_operations; |
409 | } | 350 | } |
410 | 351 | ||