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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/nfs/proc.c
  3.  *
  4.  *  Copyright (C) 1992, 1993, 1994  Rick Sladkey
  5.  *
  6.  *  OS-independent nfs remote procedure call functions
  7.  *
  8.  *  Tuned by Alan Cox <A.Cox@swansea.ac.uk> for >3K buffers
  9.  *  so at last we can have decent(ish) throughput off a 
  10.  *  Sun server.
  11.  *
  12.  *  Coding optimized and cleaned up by Florian La Roche.
  13.  *  Note: Error returns are optimized for NFS_OK, which isn't translated via
  14.  *  nfs_stat_to_errno(), but happens to be already the right return code.
  15.  *
  16.  *  Also, the code currently doesn't check the size of the packet, when
  17.  *  it decodes the packet.
  18.  *
  19.  *  Feel free to fix it and mail me the diffs if it worries you.
  20.  *
  21.  *  Completely rewritten to support the new RPC call interface;
  22.  *  rewrote and moved the entire XDR stuff to xdr.c
  23.  *  --Olaf Kirch June 1996
  24.  *
  25.  *  The code below initializes all auto variables explicitly, otherwise
  26.  *  it will fail to work as a module (gcc generates a memset call for an
  27.  *  incomplete struct).
  28.  */
  29. #include <linux/types.h>
  30. #include <linux/param.h>
  31. #include <linux/slab.h>
  32. #include <linux/sched.h>
  33. #include <linux/mm.h>
  34. #include <linux/utsname.h>
  35. #include <linux/errno.h>
  36. #include <linux/string.h>
  37. #include <linux/in.h>
  38. #include <linux/pagemap.h>
  39. #include <linux/sunrpc/clnt.h>
  40. #include <linux/nfs.h>
  41. #include <linux/nfs2.h>
  42. #include <linux/nfs_fs.h>
  43. #define NFSDBG_FACILITY NFSDBG_PROC
  44. /*
  45.  * Bare-bones access to getattr: this is for nfs_read_super.
  46.  */
  47. static int
  48. nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  49.   struct nfs_fattr *fattr)
  50. {
  51. int status;
  52. dprintk("NFS call  getrootn");
  53. fattr->valid = 0;
  54. status = rpc_call(server->client, NFSPROC_GETATTR, fhandle, fattr, 0);
  55. dprintk("NFS reply getrootn");
  56. return status;
  57. }
  58. /*
  59.  * One function for each procedure in the NFS protocol.
  60.  */
  61. static int
  62. nfs_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
  63. {
  64. int status;
  65. dprintk("NFS call  getattrn");
  66. fattr->valid = 0;
  67. status = rpc_call(NFS_CLIENT(inode), NFSPROC_GETATTR,
  68. NFS_FH(inode), fattr, 0);
  69. dprintk("NFS reply getattrn");
  70. return status;
  71. }
  72. static int
  73. nfs_proc_setattr(struct inode *inode, struct nfs_fattr *fattr,
  74.  struct iattr *sattr)
  75. {
  76. struct nfs_sattrargs arg = { NFS_FH(inode), sattr };
  77. int status;
  78. dprintk("NFS call  setattrn");
  79. fattr->valid = 0;
  80. status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
  81. dprintk("NFS reply setattrn");
  82. return status;
  83. }
  84. static int
  85. nfs_proc_lookup(struct inode *dir, struct qstr *name,
  86. struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  87. {
  88. struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len };
  89. struct nfs_diropok res = { fhandle, fattr };
  90. int status;
  91. dprintk("NFS call  lookup %sn", name->name);
  92. fattr->valid = 0;
  93. status = rpc_call(NFS_CLIENT(dir), NFSPROC_LOOKUP, &arg, &res, 0);
  94. dprintk("NFS reply lookup: %dn", status);
  95. return status;
  96. }
  97. static int
  98. nfs_proc_readlink(struct inode *inode, void *buffer, unsigned int bufsiz)
  99. {
  100. struct nfs_readlinkargs args = { NFS_FH(inode), buffer, bufsiz };
  101. struct nfs_readlinkres res = { buffer, bufsiz };
  102. int status;
  103. dprintk("NFS call  readlinkn");
  104. status = rpc_call(NFS_CLIENT(inode), NFSPROC_READLINK,
  105. &args, &res, 0);
  106. dprintk("NFS reply readlink: %dn", status);
  107. return status;
  108. }
  109. static int
  110. nfs_proc_read(struct inode *inode, struct rpc_cred *cred,
  111.       struct nfs_fattr *fattr, int flags,
  112.       loff_t offset, unsigned int count, void *buffer, int *eofp)
  113. {
  114. struct nfs_readargs arg = { NFS_FH(inode), offset, count, 1,
  115.        {{ buffer, count }, {0,0}, {0,0}, {0,0},
  116. {0,0}, {0,0}, {0,0}, {0,0}} };
  117. struct nfs_readres res = { fattr, count, 0};
  118. struct rpc_message msg = { NFSPROC_READ, &arg, &res, cred };
  119. int status;
  120. dprintk("NFS call  read %d @ %Ldn", count, (long long)offset);
  121. fattr->valid = 0;
  122. status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
  123. dprintk("NFS reply read: %dn", status);
  124. *eofp = res.eof;
  125. return status;
  126. }
  127. static int
  128. nfs_proc_write(struct inode *inode, struct rpc_cred *cred,
  129.        struct nfs_fattr *fattr, int how,
  130.        loff_t offset, unsigned int count,
  131.        void *buffer, struct nfs_writeverf *verf)
  132. {
  133. struct nfs_writeargs arg = {NFS_FH(inode), offset, count,
  134. NFS_FILE_SYNC, 1,
  135. {{buffer, count}, {0,0}, {0,0}, {0,0},
  136.  {0,0}, {0,0}, {0,0}, {0,0}}};
  137. struct nfs_writeres     res = {fattr, verf, count};
  138. struct rpc_message msg = { NFSPROC_WRITE, &arg, &res, cred };
  139. int status, flags = 0;
  140. dprintk("NFS call  write %d @ %Ldn", count, (long long)offset);
  141. fattr->valid = 0;
  142. if (how & NFS_RW_SWAP)
  143. flags |= NFS_RPC_SWAPFLAGS;
  144. status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
  145. dprintk("NFS reply write: %dn", status);
  146. verf->committed = NFS_FILE_SYNC;      /* NFSv2 always syncs data */
  147. return status < 0? status : count;
  148. }
  149. static int
  150. nfs_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
  151. int flags, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  152. {
  153. struct nfs_createargs arg = { NFS_FH(dir), name->name,
  154. name->len, sattr };
  155. struct nfs_diropok res = { fhandle, fattr };
  156. int status;
  157. fattr->valid = 0;
  158. dprintk("NFS call  create %sn", name->name);
  159. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  160. dprintk("NFS reply create: %dn", status);
  161. return status;
  162. }
  163. /*
  164.  * In NFSv2, mknod is grafted onto the create call.
  165.  */
  166. static int
  167. nfs_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
  168.        dev_t rdev, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  169. {
  170. struct nfs_createargs arg = { NFS_FH(dir), name->name,
  171.      name->len, sattr };
  172. struct nfs_diropok res = { fhandle, fattr };
  173. int status, mode;
  174. dprintk("NFS call  mknod %sn", name->name);
  175. mode = sattr->ia_mode;
  176. if (S_ISFIFO(mode)) {
  177. sattr->ia_mode = (mode & ~S_IFMT) | S_IFCHR;
  178. sattr->ia_valid &= ~ATTR_SIZE;
  179. } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
  180. sattr->ia_valid |= ATTR_SIZE;
  181. sattr->ia_size   = rdev; /* get out your barf bag */
  182. }
  183. fattr->valid = 0;
  184. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  185. if (status == -EINVAL && S_ISFIFO(mode)) {
  186. sattr->ia_mode = mode;
  187. fattr->valid = 0;
  188. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  189. }
  190. dprintk("NFS reply mknod: %dn", status);
  191. return status;
  192. }
  193.   
  194. static int
  195. nfs_proc_remove(struct inode *dir, struct qstr *name)
  196. {
  197. struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len };
  198. struct rpc_message msg = { NFSPROC_REMOVE, &arg, NULL, NULL };
  199. int status;
  200. dprintk("NFS call  remove %sn", name->name);
  201. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  202. dprintk("NFS reply remove: %dn", status);
  203. return status;
  204. }
  205. static int
  206. nfs_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
  207. {
  208. struct nfs_diropargs *arg;
  209. arg = (struct nfs_diropargs *)kmalloc(sizeof(*arg), GFP_KERNEL);
  210. if (!arg)
  211. return -ENOMEM;
  212. arg->fh = NFS_FH(dir->d_inode);
  213. arg->name = name->name;
  214. arg->len = name->len;
  215. msg->rpc_proc = NFSPROC_REMOVE;
  216. msg->rpc_argp = arg;
  217. return 0;
  218. }
  219. static void
  220. nfs_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
  221. {
  222. if (msg->rpc_argp) {
  223. NFS_CACHEINV(dir->d_inode);
  224. kfree(msg->rpc_argp);
  225. }
  226. }
  227. static int
  228. nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
  229. struct inode *new_dir, struct qstr *new_name)
  230. {
  231. struct nfs_renameargs arg = { NFS_FH(old_dir), old_name->name,
  232. old_name->len,
  233. NFS_FH(new_dir), new_name->name,
  234. new_name->len};
  235. int status;
  236. dprintk("NFS call  rename %s -> %sn", old_name->name, new_name->name);
  237. status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
  238. dprintk("NFS reply rename: %dn", status);
  239. return status;
  240. }
  241. static int
  242. nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
  243. {
  244. struct nfs_linkargs arg = { NFS_FH(inode), NFS_FH(dir),
  245. name->name, name->len };
  246. int status;
  247. dprintk("NFS call  link %sn", name->name);
  248. status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
  249. dprintk("NFS reply link: %dn", status);
  250. return status;
  251. }
  252. static int
  253. nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
  254.  struct iattr *sattr, struct nfs_fh *fhandle,
  255.  struct nfs_fattr *fattr)
  256. {
  257. struct nfs_symlinkargs arg = { NFS_FH(dir), name->name, name->len,
  258. path->name, path->len, sattr };
  259. int status;
  260. dprintk("NFS call  symlink %s -> %sn", name->name, path->name);
  261. fattr->valid = 0;
  262. status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
  263. dprintk("NFS reply symlink: %dn", status);
  264. return status;
  265. }
  266. static int
  267. nfs_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
  268.        struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  269. {
  270. struct nfs_createargs arg = { NFS_FH(dir), name->name, name->len,
  271. sattr };
  272. struct nfs_diropok res = { fhandle, fattr };
  273. int status;
  274. dprintk("NFS call  mkdir %sn", name->name);
  275. fattr->valid = 0;
  276. status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
  277. dprintk("NFS reply mkdir: %dn", status);
  278. return status;
  279. }
  280. static int
  281. nfs_proc_rmdir(struct inode *dir, struct qstr *name)
  282. {
  283. struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len };
  284. int status;
  285. dprintk("NFS call  rmdir %sn", name->name);
  286. status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
  287. dprintk("NFS reply rmdir: %dn", status);
  288. return status;
  289. }
  290. /*
  291.  * The READDIR implementation is somewhat hackish - we pass a temporary
  292.  * buffer to the encode function, which installs it in the receive
  293.  * the receive iovec. The decode function just parses the reply to make
  294.  * sure it is syntactically correct; the entries itself are decoded
  295.  * from nfs_readdir by calling the decode_entry function directly.
  296.  */
  297. static int
  298. nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
  299.  __u64 cookie, void *entry, 
  300.  unsigned int size, int plus)
  301. {
  302. struct nfs_readdirargs arg;
  303. struct nfs_readdirres res;
  304. struct rpc_message msg = { NFSPROC_READDIR, &arg, &res, cred };
  305. int status;
  306. arg.fh = NFS_FH(dir);
  307. arg.cookie = cookie;
  308. arg.buffer = entry;
  309. arg.bufsiz = size;
  310. res.buffer = entry;
  311. res.bufsiz = size;
  312. dprintk("NFS call  readdir %dn", (unsigned int)cookie);
  313. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  314. dprintk("NFS reply readdir: %dn", status);
  315. return status;
  316. }
  317. static int
  318. nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  319. struct nfs_fsinfo *info)
  320. {
  321. int status;
  322. dprintk("NFS call  statfsn");
  323. memset((char *)info, 0, sizeof(*info));
  324. status = rpc_call(server->client, NFSPROC_STATFS, fhandle, info, 0);
  325. dprintk("NFS reply statfs: %dn", status);
  326. return status;
  327. }
  328. extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
  329. struct nfs_rpc_ops     nfs_v2_clientops = {
  330.        2,        /* protocol version */
  331.        nfs_proc_get_root,
  332.        nfs_proc_getattr,
  333.        nfs_proc_setattr,
  334.        nfs_proc_lookup,
  335.        NULL,        /* access */
  336.        nfs_proc_readlink,
  337.        nfs_proc_read,
  338.        nfs_proc_write,
  339.        NULL,        /* commit */
  340.        nfs_proc_create,
  341.        nfs_proc_remove,
  342.        nfs_proc_unlink_setup,
  343.        nfs_proc_unlink_done,
  344.        nfs_proc_rename,
  345.        nfs_proc_link,
  346.        nfs_proc_symlink,
  347.        nfs_proc_mkdir,
  348.        nfs_proc_rmdir,
  349.        nfs_proc_readdir,
  350.        nfs_proc_mknod,
  351.        nfs_proc_statfs,
  352.        nfs_decode_dirent,
  353. };