aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/nfs4proc.c38
-rw-r--r--fs/nfs/pnfs.c12
-rw-r--r--fs/nfs/pnfs.h21
-rw-r--r--include/linux/nfs_fs.h1
5 files changed, 69 insertions, 5 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 9ad81ce0c40f..889f7e5e92e1 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -641,6 +641,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
641 nfs_init_lock_context(&ctx->lock_context); 641 nfs_init_lock_context(&ctx->lock_context);
642 ctx->lock_context.open_context = ctx; 642 ctx->lock_context.open_context = ctx;
643 INIT_LIST_HEAD(&ctx->list); 643 INIT_LIST_HEAD(&ctx->list);
644 ctx->mdsthreshold = NULL;
644 return ctx; 645 return ctx;
645} 646}
646 647
@@ -669,6 +670,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
669 put_rpccred(ctx->cred); 670 put_rpccred(ctx->cred);
670 dput(ctx->dentry); 671 dput(ctx->dentry);
671 nfs_sb_deactive(sb); 672 nfs_sb_deactive(sb);
673 kfree(ctx->mdsthreshold);
672 kfree(ctx); 674 kfree(ctx);
673} 675}
674 676
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 */
1785static 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) 1785static 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;
1839err_opendata_put: 1858err_opendata_put:
1859 kfree(opendata->f_attr.mdsthreshold);
1840 nfs4_opendata_put(opendata); 1860 nfs4_opendata_put(opendata);
1841err_put_state_owner: 1861err_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
1849static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) 1869static 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);
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 5d09a36b2cd8..cbcb6aea58a3 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1630,3 +1630,15 @@ out_free:
1630 kfree(data); 1630 kfree(data);
1631 goto out; 1631 goto out;
1632} 1632}
1633
1634struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
1635{
1636 struct nfs4_threshold *thp;
1637
1638 thp = kzalloc(sizeof(*thp), GFP_NOFS);
1639 if (!thp) {
1640 dprintk("%s mdsthreshold allocation failed\n", __func__);
1641 return NULL;
1642 }
1643 return thp;
1644}
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 7980756b2f57..29fd23c0efdc 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -227,6 +227,7 @@ int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head,
227 const struct nfs_pgio_completion_ops *compl_ops); 227 const struct nfs_pgio_completion_ops *compl_ops);
228int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head, 228int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
229 const struct nfs_pgio_completion_ops *compl_ops); 229 const struct nfs_pgio_completion_ops *compl_ops);
230struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
230 231
231/* nfs4_deviceid_flags */ 232/* nfs4_deviceid_flags */
232enum { 233enum {
@@ -360,6 +361,14 @@ static inline int pnfs_return_layout(struct inode *ino)
360 return 0; 361 return 0;
361} 362}
362 363
364static inline bool
365pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
366 struct nfs_server *nfss)
367{
368 return (dst && src && src->bm != 0 &&
369 nfss->pnfs_curr_ld->id == src->l_type);
370}
371
363#ifdef NFS_DEBUG 372#ifdef NFS_DEBUG
364void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id); 373void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
365#else 374#else
@@ -485,6 +494,18 @@ static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync)
485 return 0; 494 return 0;
486} 495}
487 496
497static inline bool
498pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src,
499 struct nfs_server *nfss)
500{
501 return false;
502}
503
504static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
505{
506 return NULL;
507}
508
488#endif /* CONFIG_NFS_V4_1 */ 509#endif /* CONFIG_NFS_V4_1 */
489 510
490#endif /* FS_NFS_PNFS_H */ 511#endif /* FS_NFS_PNFS_H */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 80a9385b88ab..ce910cb7d761 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -102,6 +102,7 @@ struct nfs_open_context {
102 int error; 102 int error;
103 103
104 struct list_head list; 104 struct list_head list;
105 struct nfs4_threshold *mdsthreshold;
105}; 106};
106 107
107struct nfs_open_dir_context { 108struct nfs_open_dir_context {