diff options
author | Andy Adamson <andros@netapp.com> | 2012-05-23 05:02:35 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-24 16:15:48 -0400 |
commit | 82be417aa37c05116e310b0f2171187ea389f89b (patch) | |
tree | 901d8fc702d6aef425c4b17cdf62e4fdd8c81833 /fs/nfs/nfs4proc.c | |
parent | 88034c3d88c2c48b215f2cc5eb22e564aa817f9c (diff) |
NFSv4.1 cache mdsthreshold values on OPEN
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8f39bb3ca1b3..e725736ff288 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1782,7 +1782,14 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct | |||
1782 | /* | 1782 | /* |
1783 | * Returns a referenced nfs4_state | 1783 | * Returns a referenced nfs4_state |
1784 | */ | 1784 | */ |
1785 | static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) | 1785 | static int _nfs4_do_open(struct inode *dir, |
1786 | struct dentry *dentry, | ||
1787 | fmode_t fmode, | ||
1788 | int flags, | ||
1789 | struct iattr *sattr, | ||
1790 | struct rpc_cred *cred, | ||
1791 | struct nfs4_state **res, | ||
1792 | struct nfs4_threshold **ctx_th) | ||
1786 | { | 1793 | { |
1787 | struct nfs4_state_owner *sp; | 1794 | struct nfs4_state_owner *sp; |
1788 | struct nfs4_state *state = NULL; | 1795 | struct nfs4_state *state = NULL; |
@@ -1807,6 +1814,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode | |||
1807 | if (opendata == NULL) | 1814 | if (opendata == NULL) |
1808 | goto err_put_state_owner; | 1815 | goto err_put_state_owner; |
1809 | 1816 | ||
1817 | if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { | ||
1818 | opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); | ||
1819 | if (!opendata->f_attr.mdsthreshold) | ||
1820 | goto err_opendata_put; | ||
1821 | } | ||
1810 | if (dentry->d_inode != NULL) | 1822 | if (dentry->d_inode != NULL) |
1811 | opendata->state = nfs4_get_open_state(dentry->d_inode, sp); | 1823 | opendata->state = nfs4_get_open_state(dentry->d_inode, sp); |
1812 | 1824 | ||
@@ -1832,11 +1844,19 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode | |||
1832 | nfs_setattr_update_inode(state->inode, sattr); | 1844 | nfs_setattr_update_inode(state->inode, sattr); |
1833 | nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); | 1845 | nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); |
1834 | } | 1846 | } |
1847 | |||
1848 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) | ||
1849 | *ctx_th = opendata->f_attr.mdsthreshold; | ||
1850 | else | ||
1851 | kfree(opendata->f_attr.mdsthreshold); | ||
1852 | opendata->f_attr.mdsthreshold = NULL; | ||
1853 | |||
1835 | nfs4_opendata_put(opendata); | 1854 | nfs4_opendata_put(opendata); |
1836 | nfs4_put_state_owner(sp); | 1855 | nfs4_put_state_owner(sp); |
1837 | *res = state; | 1856 | *res = state; |
1838 | return 0; | 1857 | return 0; |
1839 | err_opendata_put: | 1858 | err_opendata_put: |
1859 | kfree(opendata->f_attr.mdsthreshold); | ||
1840 | nfs4_opendata_put(opendata); | 1860 | nfs4_opendata_put(opendata); |
1841 | err_put_state_owner: | 1861 | err_put_state_owner: |
1842 | nfs4_put_state_owner(sp); | 1862 | nfs4_put_state_owner(sp); |
@@ -1846,14 +1866,21 @@ out_err: | |||
1846 | } | 1866 | } |
1847 | 1867 | ||
1848 | 1868 | ||
1849 | static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) | 1869 | static struct nfs4_state *nfs4_do_open(struct inode *dir, |
1870 | struct dentry *dentry, | ||
1871 | fmode_t fmode, | ||
1872 | int flags, | ||
1873 | struct iattr *sattr, | ||
1874 | struct rpc_cred *cred, | ||
1875 | struct nfs4_threshold **ctx_th) | ||
1850 | { | 1876 | { |
1851 | struct nfs4_exception exception = { }; | 1877 | struct nfs4_exception exception = { }; |
1852 | struct nfs4_state *res; | 1878 | struct nfs4_state *res; |
1853 | int status; | 1879 | int status; |
1854 | 1880 | ||
1855 | do { | 1881 | do { |
1856 | status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res); | 1882 | status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, |
1883 | &res, ctx_th); | ||
1857 | if (status == 0) | 1884 | if (status == 0) |
1858 | break; | 1885 | break; |
1859 | /* NOTE: BAD_SEQID means the server and client disagree about the | 1886 | /* NOTE: BAD_SEQID means the server and client disagree about the |
@@ -2177,7 +2204,8 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags | |||
2177 | struct nfs4_state *state; | 2204 | struct nfs4_state *state; |
2178 | 2205 | ||
2179 | /* Protect against concurrent sillydeletes */ | 2206 | /* Protect against concurrent sillydeletes */ |
2180 | state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred); | 2207 | state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, |
2208 | ctx->cred, &ctx->mdsthreshold); | ||
2181 | if (IS_ERR(state)) | 2209 | if (IS_ERR(state)) |
2182 | return ERR_CAST(state); | 2210 | return ERR_CAST(state); |
2183 | ctx->state = state; | 2211 | ctx->state = state; |
@@ -2779,7 +2807,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
2779 | fmode = ctx->mode; | 2807 | fmode = ctx->mode; |
2780 | } | 2808 | } |
2781 | sattr->ia_mode &= ~current_umask(); | 2809 | sattr->ia_mode &= ~current_umask(); |
2782 | state = nfs4_do_open(dir, de, fmode, flags, sattr, cred); | 2810 | state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL); |
2783 | d_drop(dentry); | 2811 | d_drop(dentry); |
2784 | if (IS_ERR(state)) { | 2812 | if (IS_ERR(state)) { |
2785 | status = PTR_ERR(state); | 2813 | status = PTR_ERR(state); |