nfs3proc.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. /*
  2. * linux/fs/nfs/nfs3proc.c
  3. *
  4. * Client-side NFSv3 procedures stubs.
  5. *
  6. * Copyright (C) 1997, Olaf Kirch
  7. */
  8. #include <linux/mm.h>
  9. #include <linux/utsname.h>
  10. #include <linux/errno.h>
  11. #include <linux/string.h>
  12. #include <linux/sunrpc/clnt.h>
  13. #include <linux/nfs.h>
  14. #include <linux/nfs3.h>
  15. #include <linux/nfs_fs.h>
  16. #include <linux/nfs_page.h>
  17. #include <linux/lockd/bind.h>
  18. #include <linux/smp_lock.h>
  19. #define NFSDBG_FACILITY NFSDBG_PROC
  20. extern struct rpc_procinfo nfs3_procedures[];
  21. /* A wrapper to handle the EJUKEBOX error message */
  22. static int
  23. nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
  24. {
  25. sigset_t oldset;
  26. int res;
  27. rpc_clnt_sigmask(clnt, &oldset);
  28. do {
  29. res = rpc_call_sync(clnt, msg, flags);
  30. if (res != -EJUKEBOX)
  31. break;
  32. set_current_state(TASK_INTERRUPTIBLE);
  33. schedule_timeout(NFS_JUKEBOX_RETRY_TIME);
  34. res = -ERESTARTSYS;
  35. } while (!signalled());
  36. rpc_clnt_sigunmask(clnt, &oldset);
  37. return res;
  38. }
  39. static inline int
  40. nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
  41. {
  42. struct rpc_message msg = {
  43. .rpc_proc = &nfs3_procedures[proc],
  44. .rpc_argp = argp,
  45. .rpc_resp = resp,
  46. };
  47. return nfs3_rpc_wrapper(clnt, &msg, flags);
  48. }
  49. #define rpc_call(clnt, proc, argp, resp, flags) \
  50. nfs3_rpc_call_wrapper(clnt, proc, argp, resp, flags)
  51. #define rpc_call_sync(clnt, msg, flags) \
  52. nfs3_rpc_wrapper(clnt, msg, flags)
  53. static int
  54. nfs3_async_handle_jukebox(struct rpc_task *task)
  55. {
  56. if (task->tk_status != -EJUKEBOX)
  57. return 0;
  58. task->tk_status = 0;
  59. rpc_restart_call(task);
  60. rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
  61. return 1;
  62. }
  63. /*
  64. * Bare-bones access to getattr: this is for nfs_read_super.
  65. */
  66. static int
  67. nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  68. struct nfs_fsinfo *info)
  69. {
  70. int status;
  71. dprintk("%s: call fsinfo\n", __FUNCTION__);
  72. info->fattr->valid = 0;
  73. status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
  74. dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
  75. if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
  76. status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0);
  77. dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
  78. }
  79. return status;
  80. }
  81. /*
  82. * One function for each procedure in the NFS protocol.
  83. */
  84. static int
  85. nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
  86. struct nfs_fattr *fattr)
  87. {
  88. int status;
  89. dprintk("NFS call getattr\n");
  90. fattr->valid = 0;
  91. status = rpc_call(server->client, NFS3PROC_GETATTR,
  92. fhandle, fattr, 0);
  93. dprintk("NFS reply getattr: %d\n", status);
  94. return status;
  95. }
  96. static int
  97. nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
  98. struct iattr *sattr)
  99. {
  100. struct inode *inode = dentry->d_inode;
  101. struct nfs3_sattrargs arg = {
  102. .fh = NFS_FH(inode),
  103. .sattr = sattr,
  104. };
  105. int status;
  106. dprintk("NFS call setattr\n");
  107. fattr->valid = 0;
  108. status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
  109. dprintk("NFS reply setattr: %d\n", status);
  110. return status;
  111. }
  112. static int
  113. nfs3_proc_lookup(struct inode *dir, struct qstr *name,
  114. struct nfs_fh *fhandle, struct nfs_fattr *fattr)
  115. {
  116. struct nfs_fattr dir_attr;
  117. struct nfs3_diropargs arg = {
  118. .fh = NFS_FH(dir),
  119. .name = name->name,
  120. .len = name->len
  121. };
  122. struct nfs3_diropres res = {
  123. .dir_attr = &dir_attr,
  124. .fh = fhandle,
  125. .fattr = fattr
  126. };
  127. int status;
  128. dprintk("NFS call lookup %s\n", name->name);
  129. dir_attr.valid = 0;
  130. fattr->valid = 0;
  131. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
  132. if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
  133. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
  134. fhandle, fattr, 0);
  135. dprintk("NFS reply lookup: %d\n", status);
  136. if (status >= 0)
  137. status = nfs_refresh_inode(dir, &dir_attr);
  138. return status;
  139. }
  140. static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
  141. {
  142. struct nfs_fattr fattr;
  143. struct nfs3_accessargs arg = {
  144. .fh = NFS_FH(inode),
  145. };
  146. struct nfs3_accessres res = {
  147. .fattr = &fattr,
  148. };
  149. struct rpc_message msg = {
  150. .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
  151. .rpc_argp = &arg,
  152. .rpc_resp = &res,
  153. .rpc_cred = entry->cred
  154. };
  155. int mode = entry->mask;
  156. int status;
  157. dprintk("NFS call access\n");
  158. fattr.valid = 0;
  159. if (mode & MAY_READ)
  160. arg.access |= NFS3_ACCESS_READ;
  161. if (S_ISDIR(inode->i_mode)) {
  162. if (mode & MAY_WRITE)
  163. arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
  164. if (mode & MAY_EXEC)
  165. arg.access |= NFS3_ACCESS_LOOKUP;
  166. } else {
  167. if (mode & MAY_WRITE)
  168. arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
  169. if (mode & MAY_EXEC)
  170. arg.access |= NFS3_ACCESS_EXECUTE;
  171. }
  172. status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
  173. nfs_refresh_inode(inode, &fattr);
  174. if (status == 0) {
  175. entry->mask = 0;
  176. if (res.access & NFS3_ACCESS_READ)
  177. entry->mask |= MAY_READ;
  178. if (res.access & (NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE))
  179. entry->mask |= MAY_WRITE;
  180. if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
  181. entry->mask |= MAY_EXEC;
  182. }
  183. dprintk("NFS reply access: %d\n", status);
  184. return status;
  185. }
  186. static int nfs3_proc_readlink(struct inode *inode, struct page *page,
  187. unsigned int pgbase, unsigned int pglen)
  188. {
  189. struct nfs_fattr fattr;
  190. struct nfs3_readlinkargs args = {
  191. .fh = NFS_FH(inode),
  192. .pgbase = pgbase,
  193. .pglen = pglen,
  194. .pages = &page
  195. };
  196. int status;
  197. dprintk("NFS call readlink\n");
  198. fattr.valid = 0;
  199. status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
  200. &args, &fattr, 0);
  201. nfs_refresh_inode(inode, &fattr);
  202. dprintk("NFS reply readlink: %d\n", status);
  203. return status;
  204. }
  205. static int nfs3_proc_read(struct nfs_read_data *rdata)
  206. {
  207. int flags = rdata->flags;
  208. struct inode * inode = rdata->inode;
  209. struct nfs_fattr * fattr = rdata->res.fattr;
  210. struct rpc_message msg = {
  211. .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
  212. .rpc_argp = &rdata->args,
  213. .rpc_resp = &rdata->res,
  214. .rpc_cred = rdata->cred,
  215. };
  216. int status;
  217. dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
  218. (long long) rdata->args.offset);
  219. fattr->valid = 0;
  220. status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
  221. if (status >= 0)
  222. nfs_refresh_inode(inode, fattr);
  223. dprintk("NFS reply read: %d\n", status);
  224. return status;
  225. }
  226. static int nfs3_proc_write(struct nfs_write_data *wdata)
  227. {
  228. int rpcflags = wdata->flags;
  229. struct inode * inode = wdata->inode;
  230. struct nfs_fattr * fattr = wdata->res.fattr;
  231. struct rpc_message msg = {
  232. .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
  233. .rpc_argp = &wdata->args,
  234. .rpc_resp = &wdata->res,
  235. .rpc_cred = wdata->cred,
  236. };
  237. int status;
  238. dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
  239. (long long) wdata->args.offset);
  240. fattr->valid = 0;
  241. status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
  242. if (status >= 0)
  243. nfs_refresh_inode(inode, fattr);
  244. dprintk("NFS reply write: %d\n", status);
  245. return status < 0? status : wdata->res.count;
  246. }
  247. static int nfs3_proc_commit(struct nfs_write_data *cdata)
  248. {
  249. struct inode * inode = cdata->inode;
  250. struct nfs_fattr * fattr = cdata->res.fattr;
  251. struct rpc_message msg = {
  252. .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
  253. .rpc_argp = &cdata->args,
  254. .rpc_resp = &cdata->res,
  255. .rpc_cred = cdata->cred,
  256. };
  257. int status;
  258. dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
  259. (long long) cdata->args.offset);
  260. fattr->valid = 0;
  261. status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
  262. if (status >= 0)
  263. nfs_refresh_inode(inode, fattr);
  264. dprintk("NFS reply commit: %d\n", status);
  265. return status;
  266. }
  267. /*
  268. * Create a regular file.
  269. * For now, we don't implement O_EXCL.
  270. */
  271. static int
  272. nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
  273. int flags)
  274. {
  275. struct nfs_fh fhandle;
  276. struct nfs_fattr fattr;
  277. struct nfs_fattr dir_attr;
  278. struct nfs3_createargs arg = {
  279. .fh = NFS_FH(dir),
  280. .name = dentry->d_name.name,
  281. .len = dentry->d_name.len,
  282. .sattr = sattr,
  283. };
  284. struct nfs3_diropres res = {
  285. .dir_attr = &dir_attr,
  286. .fh = &fhandle,
  287. .fattr = &fattr
  288. };
  289. int status;
  290. dprintk("NFS call create %s\n", dentry->d_name.name);
  291. arg.createmode = NFS3_CREATE_UNCHECKED;
  292. if (flags & O_EXCL) {
  293. arg.createmode = NFS3_CREATE_EXCLUSIVE;
  294. arg.verifier[0] = jiffies;
  295. arg.verifier[1] = current->pid;
  296. }
  297. again:
  298. dir_attr.valid = 0;
  299. fattr.valid = 0;
  300. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
  301. nfs_refresh_inode(dir, &dir_attr);
  302. /* If the server doesn't support the exclusive creation semantics,
  303. * try again with simple 'guarded' mode. */
  304. if (status == NFSERR_NOTSUPP) {
  305. switch (arg.createmode) {
  306. case NFS3_CREATE_EXCLUSIVE:
  307. arg.createmode = NFS3_CREATE_GUARDED;
  308. break;
  309. case NFS3_CREATE_GUARDED:
  310. arg.createmode = NFS3_CREATE_UNCHECKED;
  311. break;
  312. case NFS3_CREATE_UNCHECKED:
  313. goto out;
  314. }
  315. goto again;
  316. }
  317. if (status == 0)
  318. status = nfs_instantiate(dentry, &fhandle, &fattr);
  319. if (status != 0)
  320. goto out;
  321. /* When we created the file with exclusive semantics, make
  322. * sure we set the attributes afterwards. */
  323. if (arg.createmode == NFS3_CREATE_EXCLUSIVE) {
  324. dprintk("NFS call setattr (post-create)\n");
  325. if (!(sattr->ia_valid & ATTR_ATIME_SET))
  326. sattr->ia_valid |= ATTR_ATIME;
  327. if (!(sattr->ia_valid & ATTR_MTIME_SET))
  328. sattr->ia_valid |= ATTR_MTIME;
  329. /* Note: we could use a guarded setattr here, but I'm
  330. * not sure this buys us anything (and I'd have
  331. * to revamp the NFSv3 XDR code) */
  332. status = nfs3_proc_setattr(dentry, &fattr, sattr);
  333. nfs_refresh_inode(dentry->d_inode, &fattr);
  334. dprintk("NFS reply setattr (post-create): %d\n", status);
  335. }
  336. out:
  337. dprintk("NFS reply create: %d\n", status);
  338. return status;
  339. }
  340. static int
  341. nfs3_proc_remove(struct inode *dir, struct qstr *name)
  342. {
  343. struct nfs_fattr dir_attr;
  344. struct nfs3_diropargs arg = {
  345. .fh = NFS_FH(dir),
  346. .name = name->name,
  347. .len = name->len
  348. };
  349. struct rpc_message msg = {
  350. .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
  351. .rpc_argp = &arg,
  352. .rpc_resp = &dir_attr,
  353. };
  354. int status;
  355. dprintk("NFS call remove %s\n", name->name);
  356. dir_attr.valid = 0;
  357. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  358. nfs_refresh_inode(dir, &dir_attr);
  359. dprintk("NFS reply remove: %d\n", status);
  360. return status;
  361. }
  362. static int
  363. nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
  364. {
  365. struct unlinkxdr {
  366. struct nfs3_diropargs arg;
  367. struct nfs_fattr res;
  368. } *ptr;
  369. ptr = (struct unlinkxdr *)kmalloc(sizeof(*ptr), GFP_KERNEL);
  370. if (!ptr)
  371. return -ENOMEM;
  372. ptr->arg.fh = NFS_FH(dir->d_inode);
  373. ptr->arg.name = name->name;
  374. ptr->arg.len = name->len;
  375. ptr->res.valid = 0;
  376. msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
  377. msg->rpc_argp = &ptr->arg;
  378. msg->rpc_resp = &ptr->res;
  379. return 0;
  380. }
  381. static int
  382. nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
  383. {
  384. struct rpc_message *msg = &task->tk_msg;
  385. struct nfs_fattr *dir_attr;
  386. if (nfs3_async_handle_jukebox(task))
  387. return 1;
  388. if (msg->rpc_argp) {
  389. dir_attr = (struct nfs_fattr*)msg->rpc_resp;
  390. nfs_refresh_inode(dir->d_inode, dir_attr);
  391. kfree(msg->rpc_argp);
  392. }
  393. return 0;
  394. }
  395. static int
  396. nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
  397. struct inode *new_dir, struct qstr *new_name)
  398. {
  399. struct nfs_fattr old_dir_attr, new_dir_attr;
  400. struct nfs3_renameargs arg = {
  401. .fromfh = NFS_FH(old_dir),
  402. .fromname = old_name->name,
  403. .fromlen = old_name->len,
  404. .tofh = NFS_FH(new_dir),
  405. .toname = new_name->name,
  406. .tolen = new_name->len
  407. };
  408. struct nfs3_renameres res = {
  409. .fromattr = &old_dir_attr,
  410. .toattr = &new_dir_attr
  411. };
  412. int status;
  413. dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
  414. old_dir_attr.valid = 0;
  415. new_dir_attr.valid = 0;
  416. status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
  417. nfs_refresh_inode(old_dir, &old_dir_attr);
  418. nfs_refresh_inode(new_dir, &new_dir_attr);
  419. dprintk("NFS reply rename: %d\n", status);
  420. return status;
  421. }
  422. static int
  423. nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
  424. {
  425. struct nfs_fattr dir_attr, fattr;
  426. struct nfs3_linkargs arg = {
  427. .fromfh = NFS_FH(inode),
  428. .tofh = NFS_FH(dir),
  429. .toname = name->name,
  430. .tolen = name->len
  431. };
  432. struct nfs3_linkres res = {
  433. .dir_attr = &dir_attr,
  434. .fattr = &fattr
  435. };
  436. int status;
  437. dprintk("NFS call link %s\n", name->name);
  438. dir_attr.valid = 0;
  439. fattr.valid = 0;
  440. status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
  441. nfs_refresh_inode(dir, &dir_attr);
  442. nfs_refresh_inode(inode, &fattr);
  443. dprintk("NFS reply link: %d\n", status);
  444. return status;
  445. }
  446. static int
  447. nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
  448. struct iattr *sattr, struct nfs_fh *fhandle,
  449. struct nfs_fattr *fattr)
  450. {
  451. struct nfs_fattr dir_attr;
  452. struct nfs3_symlinkargs arg = {
  453. .fromfh = NFS_FH(dir),
  454. .fromname = name->name,
  455. .fromlen = name->len,
  456. .topath = path->name,
  457. .tolen = path->len,
  458. .sattr = sattr
  459. };
  460. struct nfs3_diropres res = {
  461. .dir_attr = &dir_attr,
  462. .fh = fhandle,
  463. .fattr = fattr
  464. };
  465. int status;
  466. if (path->len > NFS3_MAXPATHLEN)
  467. return -ENAMETOOLONG;
  468. dprintk("NFS call symlink %s -> %s\n", name->name, path->name);
  469. dir_attr.valid = 0;
  470. fattr->valid = 0;
  471. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
  472. nfs_refresh_inode(dir, &dir_attr);
  473. dprintk("NFS reply symlink: %d\n", status);
  474. return status;
  475. }
  476. static int
  477. nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
  478. {
  479. struct nfs_fh fhandle;
  480. struct nfs_fattr fattr, dir_attr;
  481. struct nfs3_mkdirargs arg = {
  482. .fh = NFS_FH(dir),
  483. .name = dentry->d_name.name,
  484. .len = dentry->d_name.len,
  485. .sattr = sattr
  486. };
  487. struct nfs3_diropres res = {
  488. .dir_attr = &dir_attr,
  489. .fh = &fhandle,
  490. .fattr = &fattr
  491. };
  492. int status;
  493. dprintk("NFS call mkdir %s\n", dentry->d_name.name);
  494. dir_attr.valid = 0;
  495. fattr.valid = 0;
  496. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
  497. nfs_refresh_inode(dir, &dir_attr);
  498. if (status == 0)
  499. status = nfs_instantiate(dentry, &fhandle, &fattr);
  500. dprintk("NFS reply mkdir: %d\n", status);
  501. return status;
  502. }
  503. static int
  504. nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
  505. {
  506. struct nfs_fattr dir_attr;
  507. struct nfs3_diropargs arg = {
  508. .fh = NFS_FH(dir),
  509. .name = name->name,
  510. .len = name->len
  511. };
  512. int status;
  513. dprintk("NFS call rmdir %s\n", name->name);
  514. dir_attr.valid = 0;
  515. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
  516. nfs_refresh_inode(dir, &dir_attr);
  517. dprintk("NFS reply rmdir: %d\n", status);
  518. return status;
  519. }
  520. /*
  521. * The READDIR implementation is somewhat hackish - we pass the user buffer
  522. * to the encode function, which installs it in the receive iovec.
  523. * The decode function itself doesn't perform any decoding, it just makes
  524. * sure the reply is syntactically correct.
  525. *
  526. * Also note that this implementation handles both plain readdir and
  527. * readdirplus.
  528. */
  529. static int
  530. nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
  531. u64 cookie, struct page *page, unsigned int count, int plus)
  532. {
  533. struct inode *dir = dentry->d_inode;
  534. struct nfs_fattr dir_attr;
  535. u32 *verf = NFS_COOKIEVERF(dir);
  536. struct nfs3_readdirargs arg = {
  537. .fh = NFS_FH(dir),
  538. .cookie = cookie,
  539. .verf = {verf[0], verf[1]},
  540. .plus = plus,
  541. .count = count,
  542. .pages = &page
  543. };
  544. struct nfs3_readdirres res = {
  545. .dir_attr = &dir_attr,
  546. .verf = verf,
  547. .plus = plus
  548. };
  549. struct rpc_message msg = {
  550. .rpc_proc = &nfs3_procedures[NFS3PROC_READDIR],
  551. .rpc_argp = &arg,
  552. .rpc_resp = &res,
  553. .rpc_cred = cred
  554. };
  555. int status;
  556. lock_kernel();
  557. if (plus)
  558. msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
  559. dprintk("NFS call readdir%s %d\n",
  560. plus? "plus" : "", (unsigned int) cookie);
  561. dir_attr.valid = 0;
  562. status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
  563. nfs_refresh_inode(dir, &dir_attr);
  564. dprintk("NFS reply readdir: %d\n", status);
  565. unlock_kernel();
  566. return status;
  567. }
  568. static int
  569. nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
  570. dev_t rdev)
  571. {
  572. struct nfs_fh fh;
  573. struct nfs_fattr fattr, dir_attr;
  574. struct nfs3_mknodargs arg = {
  575. .fh = NFS_FH(dir),
  576. .name = dentry->d_name.name,
  577. .len = dentry->d_name.len,
  578. .sattr = sattr,
  579. .rdev = rdev
  580. };
  581. struct nfs3_diropres res = {
  582. .dir_attr = &dir_attr,
  583. .fh = &fh,
  584. .fattr = &fattr
  585. };
  586. int status;
  587. switch (sattr->ia_mode & S_IFMT) {
  588. case S_IFBLK: arg.type = NF3BLK; break;
  589. case S_IFCHR: arg.type = NF3CHR; break;
  590. case S_IFIFO: arg.type = NF3FIFO; break;
  591. case S_IFSOCK: arg.type = NF3SOCK; break;
  592. default: return -EINVAL;
  593. }
  594. dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name,
  595. MAJOR(rdev), MINOR(rdev));
  596. dir_attr.valid = 0;
  597. fattr.valid = 0;
  598. status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
  599. nfs_refresh_inode(dir, &dir_attr);
  600. if (status == 0)
  601. status = nfs_instantiate(dentry, &fh, &fattr);
  602. dprintk("NFS reply mknod: %d\n", status);
  603. return status;
  604. }
  605. static int
  606. nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
  607. struct nfs_fsstat *stat)
  608. {
  609. int status;
  610. dprintk("NFS call fsstat\n");
  611. stat->fattr->valid = 0;
  612. status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, stat, 0);
  613. dprintk("NFS reply statfs: %d\n", status);
  614. return status;
  615. }
  616. static int
  617. nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
  618. struct nfs_fsinfo *info)
  619. {
  620. int status;
  621. dprintk("NFS call fsinfo\n");
  622. info->fattr->valid = 0;
  623. status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
  624. dprintk("NFS reply fsinfo: %d\n", status);
  625. return status;
  626. }
  627. static int
  628. nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
  629. struct nfs_pathconf *info)
  630. {
  631. int status;
  632. dprintk("NFS call pathconf\n");
  633. info->fattr->valid = 0;
  634. status = rpc_call(server->client, NFS3PROC_PATHCONF, fhandle, info, 0);
  635. dprintk("NFS reply pathconf: %d\n", status);
  636. return status;
  637. }
  638. extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
  639. static void
  640. nfs3_read_done(struct rpc_task *task)
  641. {
  642. struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
  643. if (nfs3_async_handle_jukebox(task))
  644. return;
  645. /* Call back common NFS readpage processing */
  646. if (task->tk_status >= 0)
  647. nfs_refresh_inode(data->inode, &data->fattr);
  648. nfs_readpage_result(task);
  649. }
  650. static void
  651. nfs3_proc_read_setup(struct nfs_read_data *data)
  652. {
  653. struct rpc_task *task = &data->task;
  654. struct inode *inode = data->inode;
  655. int flags;
  656. struct rpc_message msg = {
  657. .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
  658. .rpc_argp = &data->args,
  659. .rpc_resp = &data->res,
  660. .rpc_cred = data->cred,
  661. };
  662. /* N.B. Do we need to test? Never called for swapfile inode */
  663. flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
  664. /* Finalize the task. */
  665. rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags);
  666. rpc_call_setup(task, &msg, 0);
  667. }
  668. static void
  669. nfs3_write_done(struct rpc_task *task)
  670. {
  671. struct nfs_write_data *data;
  672. if (nfs3_async_handle_jukebox(task))
  673. return;
  674. data = (struct nfs_write_data *)task->tk_calldata;
  675. if (task->tk_status >= 0)
  676. nfs_refresh_inode(data->inode, data->res.fattr);
  677. nfs_writeback_done(task);
  678. }
  679. static void
  680. nfs3_proc_write_setup(struct nfs_write_data *data, int how)
  681. {
  682. struct rpc_task *task = &data->task;
  683. struct inode *inode = data->inode;
  684. int stable;
  685. int flags;
  686. struct rpc_message msg = {
  687. .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
  688. .rpc_argp = &data->args,
  689. .rpc_resp = &data->res,
  690. .rpc_cred = data->cred,
  691. };
  692. if (how & FLUSH_STABLE) {
  693. if (!NFS_I(inode)->ncommit)
  694. stable = NFS_FILE_SYNC;
  695. else
  696. stable = NFS_DATA_SYNC;
  697. } else
  698. stable = NFS_UNSTABLE;
  699. data->args.stable = stable;
  700. /* Set the initial flags for the task. */
  701. flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
  702. /* Finalize the task. */
  703. rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags);
  704. rpc_call_setup(task, &msg, 0);
  705. }
  706. static void
  707. nfs3_commit_done(struct rpc_task *task)
  708. {
  709. struct nfs_write_data *data;
  710. if (nfs3_async_handle_jukebox(task))
  711. return;
  712. data = (struct nfs_write_data *)task->tk_calldata;
  713. if (task->tk_status >= 0)
  714. nfs_refresh_inode(data->inode, data->res.fattr);
  715. nfs_commit_done(task);
  716. }
  717. static void
  718. nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
  719. {
  720. struct rpc_task *task = &data->task;
  721. struct inode *inode = data->inode;
  722. int flags;
  723. struct rpc_message msg = {
  724. .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
  725. .rpc_argp = &data->args,
  726. .rpc_resp = &data->res,
  727. .rpc_cred = data->cred,
  728. };
  729. /* Set the initial flags for the task. */
  730. flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
  731. /* Finalize the task. */
  732. rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags);
  733. rpc_call_setup(task, &msg, 0);
  734. }
  735. static int
  736. nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
  737. {
  738. return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl);
  739. }
  740. struct nfs_rpc_ops nfs_v3_clientops = {
  741. .version = 3, /* protocol version */
  742. .dentry_ops = &nfs_dentry_operations,
  743. .dir_inode_ops = &nfs_dir_inode_operations,
  744. .file_inode_ops = &nfs_file_inode_operations,
  745. .getroot = nfs3_proc_get_root,
  746. .getattr = nfs3_proc_getattr,
  747. .setattr = nfs3_proc_setattr,
  748. .lookup = nfs3_proc_lookup,
  749. .access = nfs3_proc_access,
  750. .readlink = nfs3_proc_readlink,
  751. .read = nfs3_proc_read,
  752. .write = nfs3_proc_write,
  753. .commit = nfs3_proc_commit,
  754. .create = nfs3_proc_create,
  755. .remove = nfs3_proc_remove,
  756. .unlink_setup = nfs3_proc_unlink_setup,
  757. .unlink_done = nfs3_proc_unlink_done,
  758. .rename = nfs3_proc_rename,
  759. .link = nfs3_proc_link,
  760. .symlink = nfs3_proc_symlink,
  761. .mkdir = nfs3_proc_mkdir,
  762. .rmdir = nfs3_proc_rmdir,
  763. .readdir = nfs3_proc_readdir,
  764. .mknod = nfs3_proc_mknod,
  765. .statfs = nfs3_proc_statfs,
  766. .fsinfo = nfs3_proc_fsinfo,
  767. .pathconf = nfs3_proc_pathconf,
  768. .decode_dirent = nfs3_decode_dirent,
  769. .read_setup = nfs3_proc_read_setup,
  770. .write_setup = nfs3_proc_write_setup,
  771. .commit_setup = nfs3_proc_commit_setup,
  772. .file_open = nfs_open,
  773. .file_release = nfs_release,
  774. .lock = nfs3_proc_lock,
  775. };