Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSv4.1 cache mdsthreshold values on OPEN

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Andy Adamson and committed by
Trond Myklebust
82be417a 88034c3d

+69 -5
+2
fs/nfs/inode.c
··· 641 641 nfs_init_lock_context(&ctx->lock_context); 642 642 ctx->lock_context.open_context = ctx; 643 643 INIT_LIST_HEAD(&ctx->list); 644 + ctx->mdsthreshold = NULL; 644 645 return ctx; 645 646 } 646 647 ··· 670 669 put_rpccred(ctx->cred); 671 670 dput(ctx->dentry); 672 671 nfs_sb_deactive(sb); 672 + kfree(ctx->mdsthreshold); 673 673 kfree(ctx); 674 674 } 675 675
+33 -5
fs/nfs/nfs4proc.c
··· 1782 1782 /* 1783 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 1794 struct nfs4_state_owner *sp; 1788 1795 struct nfs4_state *state = NULL; ··· 1814 1807 if (opendata == NULL) 1815 1808 goto err_put_state_owner; 1816 1809 1810 + if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { 1811 + opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 1812 + if (!opendata->f_attr.mdsthreshold) 1813 + goto err_opendata_put; 1814 + } 1817 1815 if (dentry->d_inode != NULL) 1818 1816 opendata->state = nfs4_get_open_state(dentry->d_inode, sp); 1819 1817 ··· 1844 1832 nfs_setattr_update_inode(state->inode, sattr); 1845 1833 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 1846 1834 } 1835 + 1836 + if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) 1837 + *ctx_th = opendata->f_attr.mdsthreshold; 1838 + else 1839 + kfree(opendata->f_attr.mdsthreshold); 1840 + opendata->f_attr.mdsthreshold = NULL; 1841 + 1847 1842 nfs4_opendata_put(opendata); 1848 1843 nfs4_put_state_owner(sp); 1849 1844 *res = state; 1850 1845 return 0; 1851 1846 err_opendata_put: 1847 + kfree(opendata->f_attr.mdsthreshold); 1852 1848 nfs4_opendata_put(opendata); 1853 1849 err_put_state_owner: 1854 1850 nfs4_put_state_owner(sp); ··· 1866 1846 } 1867 1847 1868 1848 1869 - 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) 1849 + static struct nfs4_state *nfs4_do_open(struct inode *dir, 1850 + struct dentry *dentry, 1851 + fmode_t fmode, 1852 + int flags, 1853 + struct iattr *sattr, 1854 + struct rpc_cred *cred, 1855 + struct nfs4_threshold **ctx_th) 1870 1856 { 1871 1857 struct nfs4_exception exception = { }; 1872 1858 struct nfs4_state *res; 1873 1859 int status; 1874 1860 1875 1861 do { 1876 - status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res); 1862 + status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, 1863 + &res, ctx_th); 1877 1864 if (status == 0) 1878 1865 break; 1879 1866 /* NOTE: BAD_SEQID means the server and client disagree about the ··· 2204 2177 struct nfs4_state *state; 2205 2178 2206 2179 /* Protect against concurrent sillydeletes */ 2207 - state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred); 2180 + state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, 2181 + ctx->cred, &ctx->mdsthreshold); 2208 2182 if (IS_ERR(state)) 2209 2183 return ERR_CAST(state); 2210 2184 ctx->state = state; ··· 2807 2779 fmode = ctx->mode; 2808 2780 } 2809 2781 sattr->ia_mode &= ~current_umask(); 2810 - state = nfs4_do_open(dir, de, fmode, flags, sattr, cred); 2782 + state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL); 2811 2783 d_drop(dentry); 2812 2784 if (IS_ERR(state)) { 2813 2785 status = PTR_ERR(state);
+12
fs/nfs/pnfs.c
··· 1630 1630 kfree(data); 1631 1631 goto out; 1632 1632 } 1633 + 1634 + struct 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 + }
+21
fs/nfs/pnfs.h
··· 227 227 const struct nfs_pgio_completion_ops *compl_ops); 228 228 int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head, 229 229 const struct nfs_pgio_completion_ops *compl_ops); 230 + struct nfs4_threshold *pnfs_mdsthreshold_alloc(void); 230 231 231 232 /* nfs4_deviceid_flags */ 232 233 enum { ··· 361 360 return 0; 362 361 } 363 362 363 + static inline bool 364 + pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src, 365 + struct nfs_server *nfss) 366 + { 367 + return (dst && src && src->bm != 0 && 368 + nfss->pnfs_curr_ld->id == src->l_type); 369 + } 370 + 364 371 #ifdef NFS_DEBUG 365 372 void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id); 366 373 #else ··· 492 483 static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync) 493 484 { 494 485 return 0; 486 + } 487 + 488 + static inline bool 489 + pnfs_use_threshold(struct nfs4_threshold **dst, struct nfs4_threshold *src, 490 + struct nfs_server *nfss) 491 + { 492 + return false; 493 + } 494 + 495 + static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void) 496 + { 497 + return NULL; 495 498 } 496 499 497 500 #endif /* CONFIG_NFS_V4_1 */
+1
include/linux/nfs_fs.h
··· 102 102 int error; 103 103 104 104 struct list_head list; 105 + struct nfs4_threshold *mdsthreshold; 105 106 }; 106 107 107 108 struct nfs_open_dir_context {