aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs3proc.c')
-rw-r--r--fs/nfs/nfs3proc.c128
1 files changed, 78 insertions, 50 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index e701002694e5..fabb4f2849a1 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -144,14 +144,12 @@ static int
144nfs3_proc_lookup(struct inode *dir, struct qstr *name, 144nfs3_proc_lookup(struct inode *dir, struct qstr *name,
145 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 145 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
146{ 146{
147 struct nfs_fattr dir_attr;
148 struct nfs3_diropargs arg = { 147 struct nfs3_diropargs arg = {
149 .fh = NFS_FH(dir), 148 .fh = NFS_FH(dir),
150 .name = name->name, 149 .name = name->name,
151 .len = name->len 150 .len = name->len
152 }; 151 };
153 struct nfs3_diropres res = { 152 struct nfs3_diropres res = {
154 .dir_attr = &dir_attr,
155 .fh = fhandle, 153 .fh = fhandle,
156 .fattr = fattr 154 .fattr = fattr
157 }; 155 };
@@ -163,29 +161,30 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
163 int status; 161 int status;
164 162
165 dprintk("NFS call lookup %s\n", name->name); 163 dprintk("NFS call lookup %s\n", name->name);
166 nfs_fattr_init(&dir_attr); 164 res.dir_attr = nfs_alloc_fattr();
165 if (res.dir_attr == NULL)
166 return -ENOMEM;
167
167 nfs_fattr_init(fattr); 168 nfs_fattr_init(fattr);
168 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 169 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
169 nfs_refresh_inode(dir, &dir_attr); 170 nfs_refresh_inode(dir, res.dir_attr);
170 if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { 171 if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
171 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; 172 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
172 msg.rpc_argp = fhandle; 173 msg.rpc_argp = fhandle;
173 msg.rpc_resp = fattr; 174 msg.rpc_resp = fattr;
174 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 175 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
175 } 176 }
177 nfs_free_fattr(res.dir_attr);
176 dprintk("NFS reply lookup: %d\n", status); 178 dprintk("NFS reply lookup: %d\n", status);
177 return status; 179 return status;
178} 180}
179 181
180static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) 182static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
181{ 183{
182 struct nfs_fattr fattr;
183 struct nfs3_accessargs arg = { 184 struct nfs3_accessargs arg = {
184 .fh = NFS_FH(inode), 185 .fh = NFS_FH(inode),
185 }; 186 };
186 struct nfs3_accessres res = { 187 struct nfs3_accessres res;
187 .fattr = &fattr,
188 };
189 struct rpc_message msg = { 188 struct rpc_message msg = {
190 .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], 189 .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
191 .rpc_argp = &arg, 190 .rpc_argp = &arg,
@@ -193,7 +192,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
193 .rpc_cred = entry->cred, 192 .rpc_cred = entry->cred,
194 }; 193 };
195 int mode = entry->mask; 194 int mode = entry->mask;
196 int status; 195 int status = -ENOMEM;
197 196
198 dprintk("NFS call access\n"); 197 dprintk("NFS call access\n");
199 198
@@ -210,9 +209,13 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
210 if (mode & MAY_EXEC) 209 if (mode & MAY_EXEC)
211 arg.access |= NFS3_ACCESS_EXECUTE; 210 arg.access |= NFS3_ACCESS_EXECUTE;
212 } 211 }
213 nfs_fattr_init(&fattr); 212
213 res.fattr = nfs_alloc_fattr();
214 if (res.fattr == NULL)
215 goto out;
216
214 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 217 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
215 nfs_refresh_inode(inode, &fattr); 218 nfs_refresh_inode(inode, res.fattr);
216 if (status == 0) { 219 if (status == 0) {
217 entry->mask = 0; 220 entry->mask = 0;
218 if (res.access & NFS3_ACCESS_READ) 221 if (res.access & NFS3_ACCESS_READ)
@@ -222,6 +225,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
222 if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE)) 225 if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
223 entry->mask |= MAY_EXEC; 226 entry->mask |= MAY_EXEC;
224 } 227 }
228 nfs_free_fattr(res.fattr);
229out:
225 dprintk("NFS reply access: %d\n", status); 230 dprintk("NFS reply access: %d\n", status);
226 return status; 231 return status;
227} 232}
@@ -229,7 +234,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
229static int nfs3_proc_readlink(struct inode *inode, struct page *page, 234static int nfs3_proc_readlink(struct inode *inode, struct page *page,
230 unsigned int pgbase, unsigned int pglen) 235 unsigned int pgbase, unsigned int pglen)
231{ 236{
232 struct nfs_fattr fattr; 237 struct nfs_fattr *fattr;
233 struct nfs3_readlinkargs args = { 238 struct nfs3_readlinkargs args = {
234 .fh = NFS_FH(inode), 239 .fh = NFS_FH(inode),
235 .pgbase = pgbase, 240 .pgbase = pgbase,
@@ -239,14 +244,19 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
239 struct rpc_message msg = { 244 struct rpc_message msg = {
240 .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK], 245 .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK],
241 .rpc_argp = &args, 246 .rpc_argp = &args,
242 .rpc_resp = &fattr,
243 }; 247 };
244 int status; 248 int status = -ENOMEM;
245 249
246 dprintk("NFS call readlink\n"); 250 dprintk("NFS call readlink\n");
247 nfs_fattr_init(&fattr); 251 fattr = nfs_alloc_fattr();
252 if (fattr == NULL)
253 goto out;
254 msg.rpc_resp = fattr;
255
248 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 256 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
249 nfs_refresh_inode(inode, &fattr); 257 nfs_refresh_inode(inode, fattr);
258 nfs_free_fattr(fattr);
259out:
250 dprintk("NFS reply readlink: %d\n", status); 260 dprintk("NFS reply readlink: %d\n", status);
251 return status; 261 return status;
252} 262}
@@ -396,12 +406,17 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
396 .rpc_argp = &arg, 406 .rpc_argp = &arg,
397 .rpc_resp = &res, 407 .rpc_resp = &res,
398 }; 408 };
399 int status; 409 int status = -ENOMEM;
400 410
401 dprintk("NFS call remove %s\n", name->name); 411 dprintk("NFS call remove %s\n", name->name);
402 nfs_fattr_init(&res.dir_attr); 412 res.dir_attr = nfs_alloc_fattr();
413 if (res.dir_attr == NULL)
414 goto out;
415
403 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 416 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
404 nfs_post_op_update_inode(dir, &res.dir_attr); 417 nfs_post_op_update_inode(dir, res.dir_attr);
418 nfs_free_fattr(res.dir_attr);
419out:
405 dprintk("NFS reply remove: %d\n", status); 420 dprintk("NFS reply remove: %d\n", status);
406 return status; 421 return status;
407} 422}
@@ -419,7 +434,7 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
419 if (nfs3_async_handle_jukebox(task, dir)) 434 if (nfs3_async_handle_jukebox(task, dir))
420 return 0; 435 return 0;
421 res = task->tk_msg.rpc_resp; 436 res = task->tk_msg.rpc_resp;
422 nfs_post_op_update_inode(dir, &res->dir_attr); 437 nfs_post_op_update_inode(dir, res->dir_attr);
423 return 1; 438 return 1;
424} 439}
425 440
@@ -427,7 +442,6 @@ static int
427nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, 442nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
428 struct inode *new_dir, struct qstr *new_name) 443 struct inode *new_dir, struct qstr *new_name)
429{ 444{
430 struct nfs_fattr old_dir_attr, new_dir_attr;
431 struct nfs3_renameargs arg = { 445 struct nfs3_renameargs arg = {
432 .fromfh = NFS_FH(old_dir), 446 .fromfh = NFS_FH(old_dir),
433 .fromname = old_name->name, 447 .fromname = old_name->name,
@@ -436,23 +450,27 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
436 .toname = new_name->name, 450 .toname = new_name->name,
437 .tolen = new_name->len 451 .tolen = new_name->len
438 }; 452 };
439 struct nfs3_renameres res = { 453 struct nfs3_renameres res;
440 .fromattr = &old_dir_attr,
441 .toattr = &new_dir_attr
442 };
443 struct rpc_message msg = { 454 struct rpc_message msg = {
444 .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], 455 .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME],
445 .rpc_argp = &arg, 456 .rpc_argp = &arg,
446 .rpc_resp = &res, 457 .rpc_resp = &res,
447 }; 458 };
448 int status; 459 int status = -ENOMEM;
449 460
450 dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); 461 dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
451 nfs_fattr_init(&old_dir_attr); 462
452 nfs_fattr_init(&new_dir_attr); 463 res.fromattr = nfs_alloc_fattr();
464 res.toattr = nfs_alloc_fattr();
465 if (res.fromattr == NULL || res.toattr == NULL)
466 goto out;
467
453 status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); 468 status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
454 nfs_post_op_update_inode(old_dir, &old_dir_attr); 469 nfs_post_op_update_inode(old_dir, res.fromattr);
455 nfs_post_op_update_inode(new_dir, &new_dir_attr); 470 nfs_post_op_update_inode(new_dir, res.toattr);
471out:
472 nfs_free_fattr(res.toattr);
473 nfs_free_fattr(res.fromattr);
456 dprintk("NFS reply rename: %d\n", status); 474 dprintk("NFS reply rename: %d\n", status);
457 return status; 475 return status;
458} 476}
@@ -460,30 +478,32 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
460static int 478static int
461nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) 479nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
462{ 480{
463 struct nfs_fattr dir_attr, fattr;
464 struct nfs3_linkargs arg = { 481 struct nfs3_linkargs arg = {
465 .fromfh = NFS_FH(inode), 482 .fromfh = NFS_FH(inode),
466 .tofh = NFS_FH(dir), 483 .tofh = NFS_FH(dir),
467 .toname = name->name, 484 .toname = name->name,
468 .tolen = name->len 485 .tolen = name->len
469 }; 486 };
470 struct nfs3_linkres res = { 487 struct nfs3_linkres res;
471 .dir_attr = &dir_attr,
472 .fattr = &fattr
473 };
474 struct rpc_message msg = { 488 struct rpc_message msg = {
475 .rpc_proc = &nfs3_procedures[NFS3PROC_LINK], 489 .rpc_proc = &nfs3_procedures[NFS3PROC_LINK],
476 .rpc_argp = &arg, 490 .rpc_argp = &arg,
477 .rpc_resp = &res, 491 .rpc_resp = &res,
478 }; 492 };
479 int status; 493 int status = -ENOMEM;
480 494
481 dprintk("NFS call link %s\n", name->name); 495 dprintk("NFS call link %s\n", name->name);
482 nfs_fattr_init(&dir_attr); 496 res.fattr = nfs_alloc_fattr();
483 nfs_fattr_init(&fattr); 497 res.dir_attr = nfs_alloc_fattr();
498 if (res.fattr == NULL || res.dir_attr == NULL)
499 goto out;
500
484 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 501 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
485 nfs_post_op_update_inode(dir, &dir_attr); 502 nfs_post_op_update_inode(dir, res.dir_attr);
486 nfs_post_op_update_inode(inode, &fattr); 503 nfs_post_op_update_inode(inode, res.fattr);
504out:
505 nfs_free_fattr(res.dir_attr);
506 nfs_free_fattr(res.fattr);
487 dprintk("NFS reply link: %d\n", status); 507 dprintk("NFS reply link: %d\n", status);
488 return status; 508 return status;
489} 509}
@@ -554,7 +574,7 @@ out:
554static int 574static int
555nfs3_proc_rmdir(struct inode *dir, struct qstr *name) 575nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
556{ 576{
557 struct nfs_fattr dir_attr; 577 struct nfs_fattr *dir_attr;
558 struct nfs3_diropargs arg = { 578 struct nfs3_diropargs arg = {
559 .fh = NFS_FH(dir), 579 .fh = NFS_FH(dir),
560 .name = name->name, 580 .name = name->name,
@@ -563,14 +583,19 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
563 struct rpc_message msg = { 583 struct rpc_message msg = {
564 .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR], 584 .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR],
565 .rpc_argp = &arg, 585 .rpc_argp = &arg,
566 .rpc_resp = &dir_attr,
567 }; 586 };
568 int status; 587 int status = -ENOMEM;
569 588
570 dprintk("NFS call rmdir %s\n", name->name); 589 dprintk("NFS call rmdir %s\n", name->name);
571 nfs_fattr_init(&dir_attr); 590 dir_attr = nfs_alloc_fattr();
591 if (dir_attr == NULL)
592 goto out;
593
594 msg.rpc_resp = dir_attr;
572 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 595 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
573 nfs_post_op_update_inode(dir, &dir_attr); 596 nfs_post_op_update_inode(dir, dir_attr);
597 nfs_free_fattr(dir_attr);
598out:
574 dprintk("NFS reply rmdir: %d\n", status); 599 dprintk("NFS reply rmdir: %d\n", status);
575 return status; 600 return status;
576} 601}
@@ -589,7 +614,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
589 u64 cookie, struct page *page, unsigned int count, int plus) 614 u64 cookie, struct page *page, unsigned int count, int plus)
590{ 615{
591 struct inode *dir = dentry->d_inode; 616 struct inode *dir = dentry->d_inode;
592 struct nfs_fattr dir_attr;
593 __be32 *verf = NFS_COOKIEVERF(dir); 617 __be32 *verf = NFS_COOKIEVERF(dir);
594 struct nfs3_readdirargs arg = { 618 struct nfs3_readdirargs arg = {
595 .fh = NFS_FH(dir), 619 .fh = NFS_FH(dir),
@@ -600,7 +624,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
600 .pages = &page 624 .pages = &page
601 }; 625 };
602 struct nfs3_readdirres res = { 626 struct nfs3_readdirres res = {
603 .dir_attr = &dir_attr,
604 .verf = verf, 627 .verf = verf,
605 .plus = plus 628 .plus = plus
606 }; 629 };
@@ -610,7 +633,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
610 .rpc_resp = &res, 633 .rpc_resp = &res,
611 .rpc_cred = cred 634 .rpc_cred = cred
612 }; 635 };
613 int status; 636 int status = -ENOMEM;
614 637
615 if (plus) 638 if (plus)
616 msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; 639 msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
@@ -618,12 +641,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
618 dprintk("NFS call readdir%s %d\n", 641 dprintk("NFS call readdir%s %d\n",
619 plus? "plus" : "", (unsigned int) cookie); 642 plus? "plus" : "", (unsigned int) cookie);
620 643
621 nfs_fattr_init(&dir_attr); 644 res.dir_attr = nfs_alloc_fattr();
645 if (res.dir_attr == NULL)
646 goto out;
647
622 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 648 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
623 649
624 nfs_invalidate_atime(dir); 650 nfs_invalidate_atime(dir);
651 nfs_refresh_inode(dir, res.dir_attr);
625 652
626 nfs_refresh_inode(dir, &dir_attr); 653 nfs_free_fattr(res.dir_attr);
654out:
627 dprintk("NFS reply readdir: %d\n", status); 655 dprintk("NFS reply readdir: %d\n", status);
628 return status; 656 return status;
629} 657}