diff options
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r-- | fs/autofs4/inode.c | 88 |
1 files changed, 22 insertions, 66 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 9e1a9dad23e1..180fa2425e49 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -22,65 +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->dentry = NULL; | ||
49 | ino->size = 0; | ||
50 | INIT_LIST_HEAD(&ino->active); | 29 | INIT_LIST_HEAD(&ino->active); |
51 | ino->active_count = 0; | ||
52 | INIT_LIST_HEAD(&ino->expiring); | 30 | INIT_LIST_HEAD(&ino->expiring); |
53 | atomic_set(&ino->count, 0); | 31 | ino->last_used = jiffies; |
32 | ino->sbi = sbi; | ||
54 | } | 33 | } |
34 | return ino; | ||
35 | } | ||
55 | 36 | ||
37 | void autofs4_clean_ino(struct autofs_info *ino) | ||
38 | { | ||
56 | ino->uid = 0; | 39 | ino->uid = 0; |
57 | ino->gid = 0; | 40 | ino->gid = 0; |
58 | ino->mode = mode; | ||
59 | ino->last_used = jiffies; | 41 | ino->last_used = jiffies; |
60 | |||
61 | ino->sbi = sbi; | ||
62 | |||
63 | if (reinit && ino->free) | ||
64 | (ino->free)(ino); | ||
65 | |||
66 | memset(&ino->u, 0, sizeof(ino->u)); | ||
67 | |||
68 | ino->free = NULL; | ||
69 | |||
70 | if (S_ISLNK(mode)) | ||
71 | ino->free = ino_lnkfree; | ||
72 | |||
73 | return ino; | ||
74 | } | 42 | } |
75 | 43 | ||
76 | void autofs4_free_ino(struct autofs_info *ino) | 44 | void autofs4_free_ino(struct autofs_info *ino) |
77 | { | 45 | { |
78 | if (ino->dentry) { | ||
79 | ino->dentry->d_fsdata = NULL; | ||
80 | ino->dentry = NULL; | ||
81 | } | ||
82 | if (ino->free) | ||
83 | (ino->free)(ino); | ||
84 | kfree(ino); | 46 | kfree(ino); |
85 | } | 47 | } |
86 | 48 | ||
@@ -136,9 +98,16 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
136 | return 0; | 98 | return 0; |
137 | } | 99 | } |
138 | 100 | ||
101 | static void autofs4_evict_inode(struct inode *inode) | ||
102 | { | ||
103 | end_writeback(inode); | ||
104 | kfree(inode->i_private); | ||
105 | } | ||
106 | |||
139 | static const struct super_operations autofs4_sops = { | 107 | static const struct super_operations autofs4_sops = { |
140 | .statfs = simple_statfs, | 108 | .statfs = simple_statfs, |
141 | .show_options = autofs4_show_options, | 109 | .show_options = autofs4_show_options, |
110 | .evict_inode = autofs4_evict_inode, | ||
142 | }; | 111 | }; |
143 | 112 | ||
144 | 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, |
@@ -228,17 +197,6 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
228 | return (*pipefd < 0); | 197 | return (*pipefd < 0); |
229 | } | 198 | } |
230 | 199 | ||
231 | static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) | ||
232 | { | ||
233 | struct autofs_info *ino; | ||
234 | |||
235 | ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755); | ||
236 | if (!ino) | ||
237 | return NULL; | ||
238 | |||
239 | return ino; | ||
240 | } | ||
241 | |||
242 | 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) |
243 | { | 201 | { |
244 | struct inode * root_inode; | 202 | struct inode * root_inode; |
@@ -282,10 +240,10 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
282 | /* | 240 | /* |
283 | * Get the root inode and dentry, but defer checking for errors. | 241 | * Get the root inode and dentry, but defer checking for errors. |
284 | */ | 242 | */ |
285 | ino = autofs4_mkroot(sbi); | 243 | ino = autofs4_new_ino(sbi); |
286 | if (!ino) | 244 | if (!ino) |
287 | goto fail_free; | 245 | goto fail_free; |
288 | root_inode = autofs4_get_inode(s, ino); | 246 | root_inode = autofs4_get_inode(s, S_IFDIR | 0755); |
289 | if (!root_inode) | 247 | if (!root_inode) |
290 | goto fail_ino; | 248 | goto fail_ino; |
291 | 249 | ||
@@ -368,15 +326,14 @@ fail_unlock: | |||
368 | return -EINVAL; | 326 | return -EINVAL; |
369 | } | 327 | } |
370 | 328 | ||
371 | struct inode *autofs4_get_inode(struct super_block *sb, | 329 | struct inode *autofs4_get_inode(struct super_block *sb, mode_t mode) |
372 | struct autofs_info *inf) | ||
373 | { | 330 | { |
374 | struct inode *inode = new_inode(sb); | 331 | struct inode *inode = new_inode(sb); |
375 | 332 | ||
376 | if (inode == NULL) | 333 | if (inode == NULL) |
377 | return NULL; | 334 | return NULL; |
378 | 335 | ||
379 | inode->i_mode = inf->mode; | 336 | inode->i_mode = mode; |
380 | if (sb->s_root) { | 337 | if (sb->s_root) { |
381 | inode->i_uid = sb->s_root->d_inode->i_uid; | 338 | inode->i_uid = sb->s_root->d_inode->i_uid; |
382 | inode->i_gid = sb->s_root->d_inode->i_gid; | 339 | inode->i_gid = sb->s_root->d_inode->i_gid; |
@@ -384,12 +341,11 @@ struct inode *autofs4_get_inode(struct super_block *sb, | |||
384 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 341 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
385 | inode->i_ino = get_next_ino(); | 342 | inode->i_ino = get_next_ino(); |
386 | 343 | ||
387 | if (S_ISDIR(inf->mode)) { | 344 | if (S_ISDIR(mode)) { |
388 | inode->i_nlink = 2; | 345 | inode->i_nlink = 2; |
389 | inode->i_op = &autofs4_dir_inode_operations; | 346 | inode->i_op = &autofs4_dir_inode_operations; |
390 | inode->i_fop = &autofs4_dir_operations; | 347 | inode->i_fop = &autofs4_dir_operations; |
391 | } else if (S_ISLNK(inf->mode)) { | 348 | } else if (S_ISLNK(mode)) { |
392 | inode->i_size = inf->size; | ||
393 | inode->i_op = &autofs4_symlink_inode_operations; | 349 | inode->i_op = &autofs4_symlink_inode_operations; |
394 | } | 350 | } |
395 | 351 | ||