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 | ||
