callback_proc.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * linux/fs/nfs/callback_proc.c
  3. *
  4. * Copyright (C) 2004 Trond Myklebust
  5. *
  6. * NFSv4 callback procedures
  7. */
  8. #include <linux/nfs4.h>
  9. #include <linux/nfs_fs.h>
  10. #include "nfs4_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 = delegation->change_attr;
  35. if (nfsi->npages != 0)
  36. res->change_attr++;
  37. res->ctime = inode->i_ctime;
  38. res->mtime = inode->i_mtime;
  39. res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
  40. args->bitmap[0];
  41. res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
  42. args->bitmap[1];
  43. res->status = 0;
  44. out_iput:
  45. up_read(&nfsi->rwsem);
  46. iput(inode);
  47. out_putclient:
  48. nfs4_put_client(clp);
  49. out:
  50. dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status));
  51. return res->status;
  52. }
  53. unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
  54. {
  55. struct nfs4_client *clp;
  56. struct inode *inode;
  57. unsigned res;
  58. res = htonl(NFS4ERR_BADHANDLE);
  59. clp = nfs4_find_client(&args->addr->sin_addr);
  60. if (clp == NULL)
  61. goto out;
  62. inode = nfs_delegation_find_inode(clp, &args->fh);
  63. if (inode == NULL)
  64. goto out_putclient;
  65. /* Set up a helper thread to actually return the delegation */
  66. switch(nfs_async_inode_return_delegation(inode, &args->stateid)) {
  67. case 0:
  68. res = 0;
  69. break;
  70. case -ENOENT:
  71. res = htonl(NFS4ERR_BAD_STATEID);
  72. break;
  73. default:
  74. res = htonl(NFS4ERR_RESOURCE);
  75. }
  76. iput(inode);
  77. out_putclient:
  78. nfs4_put_client(clp);
  79. out:
  80. dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res));
  81. return res;
  82. }