callback_proc.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * linux/fs/nfs/callback_proc.c
  3. *
  4. * Copyright (C) 2004 Trond Myklebust
  5. *
  6. * NFSv4 callback procedures
  7. */
  8. #include <linux/config.h>
  9. #include <linux/nfs4.h>
  10. #include <linux/nfs_fs.h>
  11. #include "callback.h"
  12. #include "delegation.h"
  13. #define NFSDBG_FACILITY NFSDBG_CALLBACK
  14. unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res)
  15. {
  16. struct nfs4_client *clp;
  17. struct nfs_delegation *delegation;
  18. struct nfs_inode *nfsi;
  19. struct inode *inode;
  20. res->bitmap[0] = res->bitmap[1] = 0;
  21. res->status = htonl(NFS4ERR_BADHANDLE);
  22. clp = nfs4_find_client(&args->addr->sin_addr);
  23. if (clp == NULL)
  24. goto out;
  25. inode = nfs_delegation_find_inode(clp, &args->fh);
  26. if (inode == NULL)
  27. goto out_putclient;
  28. nfsi = NFS_I(inode);
  29. down_read(&nfsi->rwsem);
  30. delegation = nfsi->delegation;
  31. if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
  32. goto out_iput;
  33. res->size = i_size_read(inode);
  34. res->change_attr = NFS_CHANGE_ATTR(inode);
  35. res->ctime = inode->i_ctime;
  36. res->mtime = inode->i_mtime;
  37. res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
  38. args->bitmap[0];
  39. res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
  40. args->bitmap[1];
  41. res->status = 0;
  42. out_iput:
  43. up_read(&nfsi->rwsem);
  44. iput(inode);
  45. out_putclient:
  46. nfs4_put_client(clp);
  47. out:
  48. dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status));
  49. return res->status;
  50. }
  51. unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
  52. {
  53. struct nfs4_client *clp;
  54. struct inode *inode;
  55. unsigned res;
  56. res = htonl(NFS4ERR_BADHANDLE);
  57. clp = nfs4_find_client(&args->addr->sin_addr);
  58. if (clp == NULL)
  59. goto out;
  60. inode = nfs_delegation_find_inode(clp, &args->fh);
  61. if (inode == NULL)
  62. goto out_putclient;
  63. /* Set up a helper thread to actually return the delegation */
  64. switch(nfs_async_inode_return_delegation(inode, &args->stateid)) {
  65. case 0:
  66. res = 0;
  67. break;
  68. case -ENOENT:
  69. res = htonl(NFS4ERR_BAD_STATEID);
  70. break;
  71. default:
  72. res = htonl(NFS4ERR_RESOURCE);
  73. }
  74. iput(inode);
  75. out_putclient:
  76. nfs4_put_client(clp);
  77. out:
  78. dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res));
  79. return res;
  80. }