proc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
源码类别:

Linux/Unix编程

开发平台:

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, struct page *page)
  99. {
  100. struct nfs_readlinkargs args = { NFS_FH(inode), PAGE_CACHE_SIZE, &page };
  101. int status;
  102. dprintk("NFS call  readlinkn");
  103. status = rpc_call(NFS_CLIENT(inode), NFSPROC_READLINK, &args, NULL, 0);
  104. dprintk("NFS reply readlink: %dn", status);
  105. return status;
  106. }
  107. static int
  108. nfs_proc_read(struct inode *inode, struct rpc_cred *cred,
  109.       struct nfs_fattr *fattr, int flags,
  110.       unsigned int base, unsigned int count,
  111.       struct page *page, int *eofp)
  112. {
  113. u64 offset = page_offset(page) + base;
  114. struct nfs_readargs arg = { NFS_FH(inode), offset, count,
  115. base, &page };
  116. struct nfs_readres res = { fattr, count, 0};
  117. struct rpc_message msg = { NFSPROC_READ, &arg, &res, cred };
  118. int status;
  119. dprintk("NFS call  read %d @ %Ldn", count, (long long)offset);
  120. fattr->valid = 0;
  121. status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
  122. dprintk("NFS reply read: %dn", status);
  123. *eofp = res.eof;
  124. return status;
  125. }
  126. static int
  127. nfs_proc_write(struct inode *inode, struct rpc_cred *cred,
  128.        struct nfs_fattr *fattr, int how,
  129.        unsigned int base, unsigned int count,
  130.        struct page *page, struct nfs_writeverf *verf)
  131. {
  132. u64 offset = page_offset(page) + base;
  133. struct nfs_writeargs arg = { NFS_FH(inode), offset, count,
  134. NFS_FILE_SYNC, base, &page };
  135. struct nfs_writeres     res = {fattr, verf, count};
  136. struct rpc_message msg = { NFSPROC_WRITE, &arg, &res, cred };
  137. int status, flags = 0;
  138. dprintk("NFS call  write %d @ %Ldn", count, (long long)offset);
  139. fattr->valid = 0;
  140. if (how & NFS_RW_SWAP)
  141. flags |= NFS_RPC_SWAPFLAGS;
  142. status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
  143. dprintk("NFS reply write: %dn", status);
  144. verf->committed = NFS_FILE_SYNC;      /* NFSv2 always syncs data */
  145. return status < 0? status : count;
  146. }
  147. static int
  148. nfs_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
  149. int flags, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  150. {
  151. struct nfs_createargs arg = { NFS_FH(dir), name->name,
  152. name->len, sattr };
  153. struct nfs_diropok res = { fhandle, fattr };
  154. int status;
  155. fattr->valid = 0;
  156. dprintk("NFS call  create %sn", name->name);
  157. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  158. dprintk("NFS reply create: %dn", status);
  159. return status;
  160. }
  161. /*
  162.  * In NFSv2, mknod is grafted onto the create call.
  163.  */
  164. static int
  165. nfs_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
  166.        dev_t rdev, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  167. {
  168. struct nfs_createargs arg = { NFS_FH(dir), name->name,
  169.      name->len, sattr };
  170. struct nfs_diropok res = { fhandle, fattr };
  171. int status, mode;
  172. dprintk("NFS call  mknod %sn", name->name);
  173. mode = sattr->ia_mode;
  174. if (S_ISFIFO(mode)) {
  175. sattr->ia_mode = (mode & ~S_IFMT) | S_IFCHR;
  176. sattr->ia_valid &= ~ATTR_SIZE;
  177. } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
  178. sattr->ia_valid |= ATTR_SIZE;
  179. sattr->ia_size   = rdev; /* get out your barf bag */
  180. }
  181. fattr->valid = 0;
  182. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  183. if (status == -EINVAL && S_ISFIFO(mode)) {
  184. sattr->ia_mode = mode;
  185. fattr->valid = 0;
  186. status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
  187. }
  188. dprintk("NFS reply mknod: %dn", status);
  189. return status;
  190. }
  191.   
  192. static int
  193. nfs_proc_remove(struct inode *dir, struct qstr *name)
  194. {
  195. struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len };
  196. struct rpc_message msg = { NFSPROC_REMOVE, &arg, NULL, NULL };
  197. int status;
  198. dprintk("NFS call  remove %sn", name->name);
  199. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  200. dprintk("NFS reply remove: %dn", status);
  201. return status;
  202. }
  203. static int
  204. nfs_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
  205. {
  206. struct nfs_diropargs *arg;
  207. arg = (struct nfs_diropargs *)kmalloc(sizeof(*arg), GFP_KERNEL);
  208. if (!arg)
  209. return -ENOMEM;
  210. arg->fh = NFS_FH(dir->d_inode);
  211. arg->name = name->name;
  212. arg->len = name->len;
  213. msg->rpc_proc = NFSPROC_REMOVE;
  214. msg->rpc_argp = arg;
  215. return 0;
  216. }
  217. static void
  218. nfs_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
  219. {
  220. if (msg->rpc_argp) {
  221. NFS_CACHEINV(dir->d_inode);
  222. kfree(msg->rpc_argp);
  223. }
  224. }
  225. static int
  226. nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
  227. struct inode *new_dir, struct qstr *new_name)
  228. {
  229. struct nfs_renameargs arg = { NFS_FH(old_dir), old_name->name,
  230. old_name->len,
  231. NFS_FH(new_dir), new_name->name,
  232. new_name->len};
  233. int status;
  234. dprintk("NFS call  rename %s -> %sn", old_name->name, new_name->name);
  235. status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0);
  236. dprintk("NFS reply rename: %dn", status);
  237. return status;
  238. }
  239. static int
  240. nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
  241. {
  242. struct nfs_linkargs arg = { NFS_FH(inode), NFS_FH(dir),
  243. name->name, name->len };
  244. int status;
  245. dprintk("NFS call  link %sn", name->name);
  246. status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
  247. dprintk("NFS reply link: %dn", status);
  248. return status;
  249. }
  250. static int
  251. nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
  252.  struct iattr *sattr, struct nfs_fh *fhandle,
  253.  struct nfs_fattr *fattr)
  254. {
  255. struct nfs_symlinkargs arg = { NFS_FH(dir), name->name, name->len,
  256. path->name, path->len, sattr };
  257. int status;
  258. dprintk("NFS call  symlink %s -> %sn", name->name, path->name);
  259. fattr->valid = 0;
  260. status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0);
  261. dprintk("NFS reply symlink: %dn", status);
  262. return status;
  263. }
  264. static int
  265. nfs_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
  266.        struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  267. {
  268. struct nfs_createargs arg = { NFS_FH(dir), name->name, name->len,
  269. sattr };
  270. struct nfs_diropok res = { fhandle, fattr };
  271. int status;
  272. dprintk("NFS call  mkdir %sn", name->name);
  273. fattr->valid = 0;
  274. status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
  275. dprintk("NFS reply mkdir: %dn", status);
  276. return status;
  277. }
  278. static int
  279. nfs_proc_rmdir(struct inode *dir, struct qstr *name)
  280. {
  281. struct nfs_diropargs arg = { NFS_FH(dir), name->name, name->len };
  282. int status;
  283. dprintk("NFS call  rmdir %sn", name->name);
  284. status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0);
  285. dprintk("NFS reply rmdir: %dn", status);
  286. return status;
  287. }
  288. /*
  289.  * The READDIR implementation is somewhat hackish - we pass a temporary
  290.  * buffer to the encode function, which installs it in the receive
  291.  * the receive iovec. The decode function just parses the reply to make
  292.  * sure it is syntactically correct; the entries itself are decoded
  293.  * from nfs_readdir by calling the decode_entry function directly.
  294.  */
  295. static int
  296. nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
  297.  __u64 cookie, struct page *page, 
  298.  unsigned int count, int plus)
  299. {
  300. struct nfs_readdirargs arg = { NFS_FH(dir), cookie, count, &page };
  301. struct rpc_message msg = { NFSPROC_READDIR, &arg, NULL, cred };
  302. int status;
  303. dprintk("NFS call  readdir %dn", (unsigned int)cookie);
  304. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  305. dprintk("NFS reply readdir: %dn", status);
  306. return status;
  307. }
  308. static int
  309. nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  310. struct nfs_fsinfo *info)
  311. {
  312. int status;
  313. dprintk("NFS call  statfsn");
  314. memset((char *)info, 0, sizeof(*info));
  315. status = rpc_call(server->client, NFSPROC_STATFS, fhandle, info, 0);
  316. dprintk("NFS reply statfs: %dn", status);
  317. return status;
  318. }
  319. extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
  320. struct nfs_rpc_ops     nfs_v2_clientops = {
  321.        2,        /* protocol version */
  322.        nfs_proc_get_root,
  323.        nfs_proc_getattr,
  324.        nfs_proc_setattr,
  325.        nfs_proc_lookup,
  326.        NULL,        /* access */
  327.        nfs_proc_readlink,
  328.        nfs_proc_read,
  329.        nfs_proc_write,
  330.        NULL,        /* commit */
  331.        nfs_proc_create,
  332.        nfs_proc_remove,
  333.        nfs_proc_unlink_setup,
  334.        nfs_proc_unlink_done,
  335.        nfs_proc_rename,
  336.        nfs_proc_link,
  337.        nfs_proc_symlink,
  338.        nfs_proc_mkdir,
  339.        nfs_proc_rmdir,
  340.        nfs_proc_readdir,
  341.        nfs_proc_mknod,
  342.        nfs_proc_statfs,
  343.        nfs_decode_dirent,
  344. };