aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d2c4b59c896d..5879b23e0c99 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2265,12 +2265,14 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
2265 return nfs4_map_errors(status); 2265 return nfs4_map_errors(status);
2266} 2266}
2267 2267
2268static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
2268/* 2269/*
2269 * Get locations and (maybe) other attributes of a referral. 2270 * Get locations and (maybe) other attributes of a referral.
2270 * Note that we'll actually follow the referral later when 2271 * Note that we'll actually follow the referral later when
2271 * we detect fsid mismatch in inode revalidation 2272 * we detect fsid mismatch in inode revalidation
2272 */ 2273 */
2273static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) 2274static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
2275 struct nfs_fattr *fattr, struct nfs_fh *fhandle)
2274{ 2276{
2275 int status = -ENOMEM; 2277 int status = -ENOMEM;
2276 struct page *page = NULL; 2278 struct page *page = NULL;
@@ -2288,15 +2290,16 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
2288 goto out; 2290 goto out;
2289 /* Make sure server returned a different fsid for the referral */ 2291 /* Make sure server returned a different fsid for the referral */
2290 if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { 2292 if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
2291 dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name); 2293 dprintk("%s: server did not return a different fsid for"
2294 " a referral at %s\n", __func__, name->name);
2292 status = -EIO; 2295 status = -EIO;
2293 goto out; 2296 goto out;
2294 } 2297 }
2298 /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
2299 nfs_fixup_referral_attributes(&locations->fattr);
2295 2300
2301 /* replace the lookup nfs_fattr with the locations nfs_fattr */
2296 memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); 2302 memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr));
2297 fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL;
2298 if (!fattr->mode)
2299 fattr->mode = S_IFDIR;
2300 memset(fhandle, 0, sizeof(struct nfs_fh)); 2303 memset(fhandle, 0, sizeof(struct nfs_fh));
2301out: 2304out:
2302 if (page) 2305 if (page)
@@ -4667,11 +4670,15 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
4667 return len; 4670 return len;
4668} 4671}
4669 4672
4673/*
4674 * nfs_fhget will use either the mounted_on_fileid or the fileid
4675 */
4670static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) 4676static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
4671{ 4677{
4672 if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) && 4678 if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) ||
4673 (fattr->valid & NFS_ATTR_FATTR_FSID) && 4679 (fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
4674 (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) 4680 (fattr->valid & NFS_ATTR_FATTR_FSID) &&
4681 (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
4675 return; 4682 return;
4676 4683
4677 fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | 4684 fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
@@ -4686,7 +4693,6 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4686 struct nfs_server *server = NFS_SERVER(dir); 4693 struct nfs_server *server = NFS_SERVER(dir);
4687 u32 bitmask[2] = { 4694 u32 bitmask[2] = {
4688 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 4695 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
4689 [1] = FATTR4_WORD1_MOUNTED_ON_FILEID,
4690 }; 4696 };
4691 struct nfs4_fs_locations_arg args = { 4697 struct nfs4_fs_locations_arg args = {
4692 .dir_fh = NFS_FH(dir), 4698 .dir_fh = NFS_FH(dir),
@@ -4705,11 +4711,18 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4705 int status; 4711 int status;
4706 4712
4707 dprintk("%s: start\n", __func__); 4713 dprintk("%s: start\n", __func__);
4714
4715 /* Ask for the fileid of the absent filesystem if mounted_on_fileid
4716 * is not supported */
4717 if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
4718 bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
4719 else
4720 bitmask[0] |= FATTR4_WORD0_FILEID;
4721
4708 nfs_fattr_init(&fs_locations->fattr); 4722 nfs_fattr_init(&fs_locations->fattr);
4709 fs_locations->server = server; 4723 fs_locations->server = server;
4710 fs_locations->nlocations = 0; 4724 fs_locations->nlocations = 0;
4711 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 4725 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
4712 nfs_fixup_referral_attributes(&fs_locations->fattr);
4713 dprintk("%s: returned status = %d\n", __func__, status); 4726 dprintk("%s: returned status = %d\n", __func__, status);
4714 return status; 4727 return status;
4715} 4728}
@@ -5098,7 +5111,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
5098 if (mxresp_sz == 0) 5111 if (mxresp_sz == 0)
5099 mxresp_sz = NFS_MAX_FILE_IO_SIZE; 5112 mxresp_sz = NFS_MAX_FILE_IO_SIZE;
5100 /* Fore channel attributes */ 5113 /* Fore channel attributes */
5101 args->fc_attrs.headerpadsz = 0;
5102 args->fc_attrs.max_rqst_sz = mxrqst_sz; 5114 args->fc_attrs.max_rqst_sz = mxrqst_sz;
5103 args->fc_attrs.max_resp_sz = mxresp_sz; 5115 args->fc_attrs.max_resp_sz = mxresp_sz;
5104 args->fc_attrs.max_ops = NFS4_MAX_OPS; 5116 args->fc_attrs.max_ops = NFS4_MAX_OPS;
@@ -5111,7 +5123,6 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
5111 args->fc_attrs.max_ops, args->fc_attrs.max_reqs); 5123 args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
5112 5124
5113 /* Back channel attributes */ 5125 /* Back channel attributes */
5114 args->bc_attrs.headerpadsz = 0;
5115 args->bc_attrs.max_rqst_sz = PAGE_SIZE; 5126 args->bc_attrs.max_rqst_sz = PAGE_SIZE;
5116 args->bc_attrs.max_resp_sz = PAGE_SIZE; 5127 args->bc_attrs.max_resp_sz = PAGE_SIZE;
5117 args->bc_attrs.max_resp_sz_cached = 0; 5128 args->bc_attrs.max_resp_sz_cached = 0;
@@ -5131,8 +5142,6 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args
5131 struct nfs4_channel_attrs *sent = &args->fc_attrs; 5142 struct nfs4_channel_attrs *sent = &args->fc_attrs;
5132 struct nfs4_channel_attrs *rcvd = &session->fc_attrs; 5143 struct nfs4_channel_attrs *rcvd = &session->fc_attrs;
5133 5144
5134 if (rcvd->headerpadsz > sent->headerpadsz)
5135 return -EINVAL;
5136 if (rcvd->max_resp_sz > sent->max_resp_sz) 5145 if (rcvd->max_resp_sz > sent->max_resp_sz)
5137 return -EINVAL; 5146 return -EINVAL;
5138 /* 5147 /*
@@ -5697,6 +5706,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
5697{ 5706{
5698 struct nfs4_layoutreturn *lrp = calldata; 5707 struct nfs4_layoutreturn *lrp = calldata;
5699 struct nfs_server *server; 5708 struct nfs_server *server;
5709 struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
5700 5710
5701 dprintk("--> %s\n", __func__); 5711 dprintk("--> %s\n", __func__);
5702 5712
@@ -5708,16 +5718,15 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
5708 nfs_restart_rpc(task, lrp->clp); 5718 nfs_restart_rpc(task, lrp->clp);
5709 return; 5719 return;
5710 } 5720 }
5721 spin_lock(&lo->plh_inode->i_lock);
5711 if (task->tk_status == 0) { 5722 if (task->tk_status == 0) {
5712 struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
5713
5714 if (lrp->res.lrs_present) { 5723 if (lrp->res.lrs_present) {
5715 spin_lock(&lo->plh_inode->i_lock);
5716 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); 5724 pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
5717 spin_unlock(&lo->plh_inode->i_lock);
5718 } else 5725 } else
5719 BUG_ON(!list_empty(&lo->plh_segs)); 5726 BUG_ON(!list_empty(&lo->plh_segs));
5720 } 5727 }
5728 lo->plh_block_lgets--;
5729 spin_unlock(&lo->plh_inode->i_lock);
5721 dprintk("<-- %s\n", __func__); 5730 dprintk("<-- %s\n", __func__);
5722} 5731}
5723 5732