inode.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* -*- c -*- --------------------------------------------------------------- *
  2.  *
  3.  * linux/fs/autofs/inode.c
  4.  *
  5.  *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
  6.  *
  7.  * This file is part of the Linux kernel and is made available under
  8.  * the terms of the GNU General Public License, version 2, or at your
  9.  * option, any later version, incorporated herein by reference.
  10.  *
  11.  * ------------------------------------------------------------------------- */
  12. #include <linux/kernel.h>
  13. #include <linux/slab.h>
  14. #include <linux/file.h>
  15. #include <linux/locks.h>
  16. #include <asm/bitops.h>
  17. #include "autofs_i.h"
  18. #define __NO_VERSION__
  19. #include <linux/module.h>
  20. static void ino_lnkfree(struct autofs_info *ino)
  21. {
  22. if (ino->u.symlink) {
  23. kfree(ino->u.symlink);
  24. ino->u.symlink = NULL;
  25. }
  26. }
  27. struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
  28.      struct autofs_sb_info *sbi, mode_t mode)
  29. {
  30. int reinit = 1;
  31. if (ino == NULL) {
  32. reinit = 0;
  33. ino = kmalloc(sizeof(*ino), GFP_KERNEL);
  34. }
  35. if (ino == NULL)
  36. return NULL;
  37. ino->flags = 0;
  38. ino->mode = mode;
  39. ino->inode = NULL;
  40. ino->dentry = NULL;
  41. ino->size = 0;
  42. ino->last_used = jiffies;
  43. ino->sbi = sbi;
  44. if (reinit && ino->free)
  45. (ino->free)(ino);
  46. memset(&ino->u, 0, sizeof(ino->u));
  47. ino->free = NULL;
  48. if (S_ISLNK(mode))
  49. ino->free = ino_lnkfree;
  50. return ino;
  51. }
  52. void autofs4_free_ino(struct autofs_info *ino)
  53. {
  54. if (ino->dentry) {
  55. ino->dentry->d_fsdata = NULL;
  56. if (ino->dentry->d_inode)
  57. dput(ino->dentry);
  58. ino->dentry = NULL;
  59. }
  60. if (ino->free)
  61. (ino->free)(ino);
  62. kfree(ino);
  63. }
  64. static void autofs4_put_super(struct super_block *sb)
  65. {
  66. struct autofs_sb_info *sbi = autofs4_sbi(sb);
  67. sb->u.generic_sbp = NULL;
  68. if ( !sbi->catatonic )
  69. autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
  70. kfree(sbi);
  71. DPRINTK(("autofs: shutting downn"));
  72. }
  73. static int autofs4_statfs(struct super_block *sb, struct statfs *buf);
  74. static struct super_operations autofs4_sops = {
  75. put_super: autofs4_put_super,
  76. statfs: autofs4_statfs,
  77. };
  78. static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
  79.  pid_t *pgrp, int *minproto, int *maxproto)
  80. {
  81. char *this_char, *value;
  82. *uid = current->uid;
  83. *gid = current->gid;
  84. *pgrp = current->pgrp;
  85. *minproto = AUTOFS_MIN_PROTO_VERSION;
  86. *maxproto = AUTOFS_MAX_PROTO_VERSION;
  87. *pipefd = -1;
  88. if ( !options ) return 1;
  89. for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
  90. if ((value = strchr(this_char,'=')) != NULL)
  91. *value++ = 0;
  92. if (!strcmp(this_char,"fd")) {
  93. if (!value || !*value)
  94. return 1;
  95. *pipefd = simple_strtoul(value,&value,0);
  96. if (*value)
  97. return 1;
  98. }
  99. else if (!strcmp(this_char,"uid")) {
  100. if (!value || !*value)
  101. return 1;
  102. *uid = simple_strtoul(value,&value,0);
  103. if (*value)
  104. return 1;
  105. }
  106. else if (!strcmp(this_char,"gid")) {
  107. if (!value || !*value)
  108. return 1;
  109. *gid = simple_strtoul(value,&value,0);
  110. if (*value)
  111. return 1;
  112. }
  113. else if (!strcmp(this_char,"pgrp")) {
  114. if (!value || !*value)
  115. return 1;
  116. *pgrp = simple_strtoul(value,&value,0);
  117. if (*value)
  118. return 1;
  119. }
  120. else if (!strcmp(this_char,"minproto")) {
  121. if (!value || !*value)
  122. return 1;
  123. *minproto = simple_strtoul(value,&value,0);
  124. if (*value)
  125. return 1;
  126. }
  127. else if (!strcmp(this_char,"maxproto")) {
  128. if (!value || !*value)
  129. return 1;
  130. *maxproto = simple_strtoul(value,&value,0);
  131. if (*value)
  132. return 1;
  133. }
  134. else break;
  135. }
  136. return (*pipefd < 0);
  137. }
  138. static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
  139. {
  140. struct autofs_info *ino;
  141. ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755);
  142. if (!ino)
  143. return NULL;
  144. return ino;
  145. }
  146. struct super_block *autofs4_read_super(struct super_block *s, void *data,
  147.       int silent)
  148. {
  149. struct inode * root_inode;
  150. struct dentry * root;
  151. struct file * pipe;
  152. int pipefd;
  153. struct autofs_sb_info *sbi;
  154. int minproto, maxproto;
  155. sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
  156. if ( !sbi )
  157. goto fail_unlock;
  158. DPRINTK(("autofs: starting up, sbi = %pn",sbi));
  159. memset(sbi, 0, sizeof(*sbi));
  160. s->u.generic_sbp = sbi;
  161. sbi->magic = AUTOFS_SBI_MAGIC;
  162. sbi->catatonic = 0;
  163. sbi->exp_timeout = 0;
  164. sbi->oz_pgrp = current->pgrp;
  165. sbi->sb = s;
  166. sbi->version = 0;
  167. sbi->queues = NULL;
  168. s->s_blocksize = 1024;
  169. s->s_blocksize_bits = 10;
  170. s->s_magic = AUTOFS_SUPER_MAGIC;
  171. s->s_op = &autofs4_sops;
  172. /*
  173.  * Get the root inode and dentry, but defer checking for errors.
  174.  */
  175. root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi));
  176. root_inode->i_op = &autofs4_root_inode_operations;
  177. root_inode->i_fop = &autofs4_root_operations;
  178. root = d_alloc_root(root_inode);
  179. pipe = NULL;
  180. if (!root)
  181. goto fail_iput;
  182. /* Can this call block? */
  183. if (parse_options(data, &pipefd,
  184.   &root_inode->i_uid, &root_inode->i_gid,
  185.   &sbi->oz_pgrp,
  186.   &minproto, &maxproto)) {
  187. printk("autofs: called with bogus optionsn");
  188. goto fail_dput;
  189. }
  190. /* Couldn't this be tested earlier? */
  191. if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
  192.     minproto > AUTOFS_MAX_PROTO_VERSION) {
  193. printk("autofs: kernel does not match daemon version "
  194.        "daemon (%d, %d) kernel (%d, %d)n",
  195. minproto, maxproto,
  196. AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
  197. goto fail_dput;
  198. }
  199. sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto;
  200. DPRINTK(("autofs: pipe fd = %d, pgrp = %un", pipefd, sbi->oz_pgrp));
  201. pipe = fget(pipefd);
  202. if ( !pipe ) {
  203. printk("autofs: could not open pipe file descriptorn");
  204. goto fail_dput;
  205. }
  206. if ( !pipe->f_op || !pipe->f_op->write )
  207. goto fail_fput;
  208. sbi->pipe = pipe;
  209. /*
  210.  * Success! Install the root dentry now to indicate completion.
  211.  */
  212. s->s_root = root;
  213. return s;
  214. /*
  215.  * Failure ... clean up.
  216.  */
  217. fail_fput:
  218. printk("autofs: pipe file descriptor does not contain proper opsn");
  219. /*
  220.  * fput() can block, so we clear the super block first.
  221.  */
  222. fput(pipe);
  223. /* fall through */
  224. fail_dput:
  225. /*
  226.  * dput() can block, so we clear the super block first.
  227.  */
  228. dput(root);
  229. goto fail_free;
  230. fail_iput:
  231. printk("autofs: get root dentry failedn");
  232. /*
  233.  * iput() can block, so we clear the super block first.
  234.  */
  235. iput(root_inode);
  236. fail_free:
  237. kfree(sbi);
  238. fail_unlock:
  239. return NULL;
  240. }
  241. static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
  242. {
  243. buf->f_type = AUTOFS_SUPER_MAGIC;
  244. buf->f_bsize = 1024;
  245. buf->f_namelen = NAME_MAX;
  246. return 0;
  247. }
  248. struct inode *autofs4_get_inode(struct super_block *sb,
  249. struct autofs_info *inf)
  250. {
  251. struct inode *inode = new_inode(sb);
  252. if (inode == NULL)
  253. return NULL;
  254. inf->inode = inode;
  255. inode->i_mode = inf->mode;
  256. if (sb->s_root) {
  257. inode->i_uid = sb->s_root->d_inode->i_uid;
  258. inode->i_gid = sb->s_root->d_inode->i_gid;
  259. } else {
  260. inode->i_uid = 0;
  261. inode->i_gid = 0;
  262. }
  263. inode->i_blksize = PAGE_CACHE_SIZE;
  264. inode->i_blocks = 0;
  265. inode->i_rdev = 0;
  266. inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  267. if (S_ISDIR(inf->mode)) {
  268. inode->i_nlink = 2;
  269. inode->i_op = &autofs4_dir_inode_operations;
  270. inode->i_fop = &autofs4_dir_operations;
  271. } else if (S_ISLNK(inf->mode)) {
  272. inode->i_size = inf->size;
  273. inode->i_op = &autofs4_symlink_inode_operations;
  274. }
  275. return inode;
  276. }