diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 36 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 2 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 1 |
3 files changed, 30 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 16c9a43218c3..0f6119714c8c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1709,14 +1709,30 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
1709 | int status, flag = 0; | 1709 | int status, flag = 0; |
1710 | 1710 | ||
1711 | flag = NFS4_OPEN_DELEGATE_NONE; | 1711 | flag = NFS4_OPEN_DELEGATE_NONE; |
1712 | if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL | 1712 | open->op_recall = 0; |
1713 | || !atomic_read(&cb->cb_set) || !sop->so_confirmed) | 1713 | switch (open->op_claim_type) { |
1714 | goto out; | 1714 | case NFS4_OPEN_CLAIM_PREVIOUS: |
1715 | 1715 | if (!atomic_read(&cb->cb_set)) | |
1716 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | 1716 | open->op_recall = 1; |
1717 | flag = NFS4_OPEN_DELEGATE_WRITE; | 1717 | flag = open->op_delegate_type; |
1718 | else | 1718 | if (flag == NFS4_OPEN_DELEGATE_NONE) |
1719 | flag = NFS4_OPEN_DELEGATE_READ; | 1719 | goto out; |
1720 | break; | ||
1721 | case NFS4_OPEN_CLAIM_NULL: | ||
1722 | /* Let's not give out any delegations till everyone's | ||
1723 | * had the chance to reclaim theirs.... */ | ||
1724 | if (nfs4_in_grace()) | ||
1725 | goto out; | ||
1726 | if (!atomic_read(&cb->cb_set) || !sop->so_confirmed) | ||
1727 | goto out; | ||
1728 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | ||
1729 | flag = NFS4_OPEN_DELEGATE_WRITE; | ||
1730 | else | ||
1731 | flag = NFS4_OPEN_DELEGATE_READ; | ||
1732 | break; | ||
1733 | default: | ||
1734 | goto out; | ||
1735 | } | ||
1720 | 1736 | ||
1721 | dp = alloc_init_deleg(sop->so_client, stp, fh, flag); | 1737 | dp = alloc_init_deleg(sop->so_client, stp, fh, flag); |
1722 | if (dp == NULL) { | 1738 | if (dp == NULL) { |
@@ -1750,6 +1766,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
1750 | dp->dl_stateid.si_fileid, | 1766 | dp->dl_stateid.si_fileid, |
1751 | dp->dl_stateid.si_generation); | 1767 | dp->dl_stateid.si_generation); |
1752 | out: | 1768 | out: |
1769 | if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS | ||
1770 | && flag == NFS4_OPEN_DELEGATE_NONE | ||
1771 | && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) | ||
1772 | printk("NFSD: WARNING: refusing delegation reclaim\n"); | ||
1753 | open->op_delegate_type = flag; | 1773 | open->op_delegate_type = flag; |
1754 | } | 1774 | } |
1755 | 1775 | ||
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0ae1467c3bc3..cfe978a72cea 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1972,7 +1972,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open | |||
1972 | case NFS4_OPEN_DELEGATE_READ: | 1972 | case NFS4_OPEN_DELEGATE_READ: |
1973 | RESERVE_SPACE(20 + sizeof(stateid_t)); | 1973 | RESERVE_SPACE(20 + sizeof(stateid_t)); |
1974 | WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t)); | 1974 | WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t)); |
1975 | WRITE32(0); | 1975 | WRITE32(open->op_recall); |
1976 | 1976 | ||
1977 | /* | 1977 | /* |
1978 | * TODO: ACE's in delegations | 1978 | * TODO: ACE's in delegations |
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index a1f5ad0be1bf..4d24d65c0e88 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h | |||
@@ -210,6 +210,7 @@ struct nfsd4_open { | |||
210 | u32 op_share_access; /* request */ | 210 | u32 op_share_access; /* request */ |
211 | u32 op_share_deny; /* request */ | 211 | u32 op_share_deny; /* request */ |
212 | stateid_t op_stateid; /* response */ | 212 | stateid_t op_stateid; /* response */ |
213 | u32 op_recall; /* recall */ | ||
213 | struct nfsd4_change_info op_cinfo; /* response */ | 214 | struct nfsd4_change_info op_cinfo; /* response */ |
214 | u32 op_rflags; /* response */ | 215 | u32 op_rflags; /* response */ |
215 | int op_truncate; /* used during processing */ | 216 | int op_truncate; /* used during processing */ |