.. | .. |
---|
110 | 110 | .rpc_resp = fattr, |
---|
111 | 111 | }; |
---|
112 | 112 | int status; |
---|
| 113 | + unsigned short task_flags = 0; |
---|
| 114 | + |
---|
| 115 | + /* Is this is an attribute revalidation, subject to softreval? */ |
---|
| 116 | + if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) |
---|
| 117 | + task_flags |= RPC_TASK_TIMEOUT; |
---|
113 | 118 | |
---|
114 | 119 | dprintk("NFS call getattr\n"); |
---|
115 | 120 | nfs_fattr_init(fattr); |
---|
116 | | - status = rpc_call_sync(server->client, &msg, 0); |
---|
| 121 | + status = rpc_call_sync(server->client, &msg, task_flags); |
---|
117 | 122 | dprintk("NFS reply getattr: %d\n", status); |
---|
118 | 123 | return status; |
---|
119 | 124 | } |
---|
.. | .. |
---|
140 | 145 | nfs_fattr_init(fattr); |
---|
141 | 146 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
---|
142 | 147 | if (status == 0) { |
---|
| 148 | + nfs_setattr_update_inode(inode, sattr, fattr); |
---|
143 | 149 | if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) |
---|
144 | 150 | nfs_zap_acl_cache(inode); |
---|
145 | | - nfs_setattr_update_inode(inode, sattr, fattr); |
---|
146 | 151 | } |
---|
147 | 152 | dprintk("NFS reply setattr: %d\n", status); |
---|
148 | 153 | return status; |
---|
149 | 154 | } |
---|
150 | 155 | |
---|
151 | 156 | static int |
---|
152 | | -nfs3_proc_lookup(struct inode *dir, const struct qstr *name, |
---|
| 157 | +nfs3_proc_lookup(struct inode *dir, struct dentry *dentry, |
---|
153 | 158 | struct nfs_fh *fhandle, struct nfs_fattr *fattr, |
---|
154 | 159 | struct nfs4_label *label) |
---|
155 | 160 | { |
---|
156 | 161 | struct nfs3_diropargs arg = { |
---|
157 | 162 | .fh = NFS_FH(dir), |
---|
158 | | - .name = name->name, |
---|
159 | | - .len = name->len |
---|
| 163 | + .name = dentry->d_name.name, |
---|
| 164 | + .len = dentry->d_name.len |
---|
160 | 165 | }; |
---|
161 | 166 | struct nfs3_diropres res = { |
---|
162 | 167 | .fh = fhandle, |
---|
.. | .. |
---|
168 | 173 | .rpc_resp = &res, |
---|
169 | 174 | }; |
---|
170 | 175 | int status; |
---|
| 176 | + unsigned short task_flags = 0; |
---|
171 | 177 | |
---|
172 | | - dprintk("NFS call lookup %s\n", name->name); |
---|
| 178 | + /* Is this is an attribute revalidation, subject to softreval? */ |
---|
| 179 | + if (nfs_lookup_is_soft_revalidate(dentry)) |
---|
| 180 | + task_flags |= RPC_TASK_TIMEOUT; |
---|
| 181 | + |
---|
173 | 182 | res.dir_attr = nfs_alloc_fattr(); |
---|
174 | 183 | if (res.dir_attr == NULL) |
---|
175 | 184 | return -ENOMEM; |
---|
176 | 185 | |
---|
| 186 | + dprintk("NFS call lookup %pd2\n", dentry); |
---|
177 | 187 | nfs_fattr_init(fattr); |
---|
178 | | - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
---|
| 188 | + status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags); |
---|
179 | 189 | nfs_refresh_inode(dir, res.dir_attr); |
---|
180 | 190 | if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { |
---|
181 | 191 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; |
---|
182 | 192 | msg.rpc_argp = fhandle; |
---|
183 | 193 | msg.rpc_resp = fattr; |
---|
184 | | - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
---|
| 194 | + status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags); |
---|
185 | 195 | } |
---|
186 | 196 | nfs_free_fattr(res.dir_attr); |
---|
187 | 197 | dprintk("NFS reply lookup: %d\n", status); |
---|
.. | .. |
---|
279 | 289 | return data; |
---|
280 | 290 | } |
---|
281 | 291 | |
---|
282 | | -static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data) |
---|
| 292 | +static struct dentry * |
---|
| 293 | +nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data) |
---|
283 | 294 | { |
---|
284 | 295 | int status; |
---|
285 | 296 | |
---|
286 | 297 | status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); |
---|
287 | 298 | nfs_post_op_update_inode(dir, data->res.dir_attr); |
---|
288 | | - if (status == 0) |
---|
289 | | - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); |
---|
290 | | - return status; |
---|
| 299 | + if (status != 0) |
---|
| 300 | + return ERR_PTR(status); |
---|
| 301 | + |
---|
| 302 | + return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr, NULL); |
---|
291 | 303 | } |
---|
292 | 304 | |
---|
293 | 305 | static void nfs3_free_createdata(struct nfs3_createdata *data) |
---|
.. | .. |
---|
304 | 316 | { |
---|
305 | 317 | struct posix_acl *default_acl, *acl; |
---|
306 | 318 | struct nfs3_createdata *data; |
---|
| 319 | + struct dentry *d_alias; |
---|
307 | 320 | int status = -ENOMEM; |
---|
308 | 321 | |
---|
309 | 322 | dprintk("NFS call create %pd\n", dentry); |
---|
.. | .. |
---|
330 | 343 | goto out; |
---|
331 | 344 | |
---|
332 | 345 | for (;;) { |
---|
333 | | - status = nfs3_do_create(dir, dentry, data); |
---|
| 346 | + d_alias = nfs3_do_create(dir, dentry, data); |
---|
| 347 | + status = PTR_ERR_OR_ZERO(d_alias); |
---|
334 | 348 | |
---|
335 | 349 | if (status != -ENOTSUPP) |
---|
336 | 350 | break; |
---|
.. | .. |
---|
355 | 369 | if (status != 0) |
---|
356 | 370 | goto out_release_acls; |
---|
357 | 371 | |
---|
| 372 | + if (d_alias) |
---|
| 373 | + dentry = d_alias; |
---|
| 374 | + |
---|
358 | 375 | /* When we created the file with exclusive semantics, make |
---|
359 | 376 | * sure we set the attributes afterwards. */ |
---|
360 | 377 | if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) { |
---|
.. | .. |
---|
372 | 389 | nfs_post_op_update_inode(d_inode(dentry), data->res.fattr); |
---|
373 | 390 | dprintk("NFS reply setattr (post-create): %d\n", status); |
---|
374 | 391 | if (status != 0) |
---|
375 | | - goto out_release_acls; |
---|
| 392 | + goto out_dput; |
---|
376 | 393 | } |
---|
377 | 394 | |
---|
378 | 395 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
---|
379 | 396 | |
---|
| 397 | +out_dput: |
---|
| 398 | + dput(d_alias); |
---|
380 | 399 | out_release_acls: |
---|
381 | 400 | posix_acl_release(acl); |
---|
382 | 401 | posix_acl_release(default_acl); |
---|
.. | .. |
---|
504 | 523 | unsigned int len, struct iattr *sattr) |
---|
505 | 524 | { |
---|
506 | 525 | struct nfs3_createdata *data; |
---|
| 526 | + struct dentry *d_alias; |
---|
507 | 527 | int status = -ENOMEM; |
---|
508 | 528 | |
---|
509 | 529 | if (len > NFS3_MAXPATHLEN) |
---|
.. | .. |
---|
522 | 542 | data->arg.symlink.pathlen = len; |
---|
523 | 543 | data->arg.symlink.sattr = sattr; |
---|
524 | 544 | |
---|
525 | | - status = nfs3_do_create(dir, dentry, data); |
---|
| 545 | + d_alias = nfs3_do_create(dir, dentry, data); |
---|
| 546 | + status = PTR_ERR_OR_ZERO(d_alias); |
---|
| 547 | + |
---|
| 548 | + if (status == 0) |
---|
| 549 | + dput(d_alias); |
---|
526 | 550 | |
---|
527 | 551 | nfs3_free_createdata(data); |
---|
528 | 552 | out: |
---|
.. | .. |
---|
535 | 559 | { |
---|
536 | 560 | struct posix_acl *default_acl, *acl; |
---|
537 | 561 | struct nfs3_createdata *data; |
---|
| 562 | + struct dentry *d_alias; |
---|
538 | 563 | int status = -ENOMEM; |
---|
539 | 564 | |
---|
540 | 565 | dprintk("NFS call mkdir %pd\n", dentry); |
---|
.. | .. |
---|
553 | 578 | data->arg.mkdir.len = dentry->d_name.len; |
---|
554 | 579 | data->arg.mkdir.sattr = sattr; |
---|
555 | 580 | |
---|
556 | | - status = nfs3_do_create(dir, dentry, data); |
---|
| 581 | + d_alias = nfs3_do_create(dir, dentry, data); |
---|
| 582 | + status = PTR_ERR_OR_ZERO(d_alias); |
---|
| 583 | + |
---|
557 | 584 | if (status != 0) |
---|
558 | 585 | goto out_release_acls; |
---|
559 | 586 | |
---|
| 587 | + if (d_alias) |
---|
| 588 | + dentry = d_alias; |
---|
| 589 | + |
---|
560 | 590 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
---|
561 | 591 | |
---|
| 592 | + dput(d_alias); |
---|
562 | 593 | out_release_acls: |
---|
563 | 594 | posix_acl_release(acl); |
---|
564 | 595 | posix_acl_release(default_acl); |
---|
.. | .. |
---|
607 | 638 | * readdirplus. |
---|
608 | 639 | */ |
---|
609 | 640 | static int |
---|
610 | | -nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, |
---|
| 641 | +nfs3_proc_readdir(struct dentry *dentry, const struct cred *cred, |
---|
611 | 642 | u64 cookie, struct page **pages, unsigned int count, bool plus) |
---|
612 | 643 | { |
---|
613 | 644 | struct inode *dir = d_inode(dentry); |
---|
.. | .. |
---|
628 | 659 | .rpc_proc = &nfs3_procedures[NFS3PROC_READDIR], |
---|
629 | 660 | .rpc_argp = &arg, |
---|
630 | 661 | .rpc_resp = &res, |
---|
631 | | - .rpc_cred = cred |
---|
| 662 | + .rpc_cred = cred, |
---|
632 | 663 | }; |
---|
633 | 664 | int status = -ENOMEM; |
---|
634 | 665 | |
---|
.. | .. |
---|
660 | 691 | { |
---|
661 | 692 | struct posix_acl *default_acl, *acl; |
---|
662 | 693 | struct nfs3_createdata *data; |
---|
| 694 | + struct dentry *d_alias; |
---|
663 | 695 | int status = -ENOMEM; |
---|
664 | 696 | |
---|
665 | 697 | dprintk("NFS call mknod %pd %u:%u\n", dentry, |
---|
.. | .. |
---|
698 | 730 | goto out_release_acls; |
---|
699 | 731 | } |
---|
700 | 732 | |
---|
701 | | - status = nfs3_do_create(dir, dentry, data); |
---|
| 733 | + d_alias = nfs3_do_create(dir, dentry, data); |
---|
| 734 | + status = PTR_ERR_OR_ZERO(d_alias); |
---|
702 | 735 | if (status != 0) |
---|
703 | 736 | goto out_release_acls; |
---|
704 | 737 | |
---|
| 738 | + if (d_alias) |
---|
| 739 | + dentry = d_alias; |
---|
| 740 | + |
---|
705 | 741 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
---|
706 | 742 | |
---|
| 743 | + dput(d_alias); |
---|
707 | 744 | out_release_acls: |
---|
708 | 745 | posix_acl_release(acl); |
---|
709 | 746 | posix_acl_release(default_acl); |
---|
.. | .. |
---|
786 | 823 | static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) |
---|
787 | 824 | { |
---|
788 | 825 | struct inode *inode = hdr->inode; |
---|
| 826 | + struct nfs_server *server = NFS_SERVER(inode); |
---|
789 | 827 | |
---|
790 | 828 | if (hdr->pgio_done_cb != NULL) |
---|
791 | 829 | return hdr->pgio_done_cb(task, hdr); |
---|
792 | 830 | |
---|
793 | 831 | if (nfs3_async_handle_jukebox(task, inode)) |
---|
794 | 832 | return -EAGAIN; |
---|
| 833 | + |
---|
| 834 | + if (task->tk_status >= 0 && !server->read_hdrsize) |
---|
| 835 | + cmpxchg(&server->read_hdrsize, 0, hdr->res.replen); |
---|
795 | 836 | |
---|
796 | 837 | nfs_invalidate_atime(inode); |
---|
797 | 838 | nfs_refresh_inode(inode, &hdr->fattr); |
---|
.. | .. |
---|
802 | 843 | struct rpc_message *msg) |
---|
803 | 844 | { |
---|
804 | 845 | msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ]; |
---|
| 846 | + hdr->args.replen = NFS_SERVER(hdr->inode)->read_hdrsize; |
---|
805 | 847 | } |
---|
806 | 848 | |
---|
807 | 849 | static int nfs3_proc_pgio_rpc_prepare(struct rpc_task *task, |
---|
.. | .. |
---|
958 | 1000 | .nlmclnt_ops = &nlmclnt_fl_close_lock_ops, |
---|
959 | 1001 | .getroot = nfs3_proc_get_root, |
---|
960 | 1002 | .submount = nfs_submount, |
---|
961 | | - .try_mount = nfs_try_mount, |
---|
| 1003 | + .try_get_tree = nfs_try_get_tree, |
---|
962 | 1004 | .getattr = nfs3_proc_getattr, |
---|
963 | 1005 | .setattr = nfs3_proc_setattr, |
---|
964 | 1006 | .lookup = nfs3_proc_lookup, |
---|