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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.linux-nfs.org/pub/linux/nfs-2.6

* git://git.linux-nfs.org/pub/linux/nfs-2.6:
NLM,NFSv4: Wait on local locks before we put RPC calls on the wire
VFS: Add support for the FL_ACCESS flag to flock_lock_file()
NFSv4: Ensure nfs4_lock_expired() caches delegated locks
NLM,NFSv4: Don't put UNLOCK requests on the wire unless we hold a lock
VFS: Allow caller to determine if BSD or posix locks were actually freed
NFS: Optimise away an excessive GETATTR call when a file is symlinked
This fixes a panic doing the first READDIR or READDIRPLUS call when:
NFS: Fix NFS page_state usage
Revert "Merge branch 'odirect'"

+304 -284
+17 -9
fs/lockd/clntproc.c
··· 454 454 fl->fl_ops = &nlmclnt_lock_ops; 455 455 } 456 456 457 - static void do_vfs_lock(struct file_lock *fl) 457 + static int do_vfs_lock(struct file_lock *fl) 458 458 { 459 459 int res = 0; 460 460 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { ··· 467 467 default: 468 468 BUG(); 469 469 } 470 - if (res < 0) 471 - printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", 472 - __FUNCTION__); 470 + return res; 473 471 } 474 472 475 473 /* ··· 496 498 struct nlm_host *host = req->a_host; 497 499 struct nlm_res *resp = &req->a_res; 498 500 struct nlm_wait *block = NULL; 501 + unsigned char fl_flags = fl->fl_flags; 499 502 int status = -ENOLCK; 500 503 501 504 if (!host->h_monitored && nsm_monitor(host) < 0) { ··· 504 505 host->h_name); 505 506 goto out; 506 507 } 508 + fl->fl_flags |= FL_ACCESS; 509 + status = do_vfs_lock(fl); 510 + if (status < 0) 511 + goto out; 507 512 508 513 block = nlmclnt_prepare_block(host, fl); 509 514 again: ··· 542 539 up_read(&host->h_rwsem); 543 540 goto again; 544 541 } 545 - fl->fl_flags |= FL_SLEEP; 546 542 /* Ensure the resulting lock will get added to granted list */ 547 - do_vfs_lock(fl); 543 + fl->fl_flags = fl_flags | FL_SLEEP; 544 + if (do_vfs_lock(fl) < 0) 545 + printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); 548 546 up_read(&host->h_rwsem); 549 547 } 550 548 status = nlm_stat_to_errno(resp->status); ··· 556 552 nlmclnt_cancel(host, req->a_args.block, fl); 557 553 out: 558 554 nlm_release_call(req); 555 + fl->fl_flags = fl_flags; 559 556 return status; 560 557 } 561 558 ··· 611 606 { 612 607 struct nlm_host *host = req->a_host; 613 608 struct nlm_res *resp = &req->a_res; 614 - int status; 609 + int status = 0; 615 610 616 611 /* 617 612 * Note: the server is supposed to either grant us the unlock 618 613 * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either 619 614 * case, we want to unlock. 620 615 */ 616 + fl->fl_flags |= FL_EXISTS; 621 617 down_read(&host->h_rwsem); 622 - do_vfs_lock(fl); 618 + if (do_vfs_lock(fl) == -ENOENT) { 619 + up_read(&host->h_rwsem); 620 + goto out; 621 + } 623 622 up_read(&host->h_rwsem); 624 623 625 624 if (req->a_flags & RPC_TASK_ASYNC) ··· 633 624 if (status < 0) 634 625 goto out; 635 626 636 - status = 0; 637 627 if (resp->status == NLM_LCK_GRANTED) 638 628 goto out; 639 629
+21 -2
fs/locks.c
··· 725 725 /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 726 726 * at the head of the list, but that's secret knowledge known only to 727 727 * flock_lock_file and posix_lock_file. 728 + * 729 + * Note that if called with an FL_EXISTS argument, the caller may determine 730 + * whether or not a lock was successfully freed by testing the return 731 + * value for -ENOENT. 728 732 */ 729 733 static int flock_lock_file(struct file *filp, struct file_lock *request) 730 734 { ··· 739 735 int found = 0; 740 736 741 737 lock_kernel(); 738 + if (request->fl_flags & FL_ACCESS) 739 + goto find_conflict; 742 740 for_each_lock(inode, before) { 743 741 struct file_lock *fl = *before; 744 742 if (IS_POSIX(fl)) ··· 756 750 break; 757 751 } 758 752 759 - if (request->fl_type == F_UNLCK) 753 + if (request->fl_type == F_UNLCK) { 754 + if ((request->fl_flags & FL_EXISTS) && !found) 755 + error = -ENOENT; 760 756 goto out; 757 + } 761 758 762 759 error = -ENOMEM; 763 760 new_fl = locks_alloc_lock(); ··· 773 764 if (found) 774 765 cond_resched(); 775 766 767 + find_conflict: 776 768 for_each_lock(inode, before) { 777 769 struct file_lock *fl = *before; 778 770 if (IS_POSIX(fl)) ··· 787 777 locks_insert_block(fl, request); 788 778 goto out; 789 779 } 780 + if (request->fl_flags & FL_ACCESS) 781 + goto out; 790 782 locks_copy_lock(new_fl, request); 791 783 locks_insert_lock(&inode->i_flock, new_fl); 792 784 new_fl = NULL; ··· 960 948 961 949 error = 0; 962 950 if (!added) { 963 - if (request->fl_type == F_UNLCK) 951 + if (request->fl_type == F_UNLCK) { 952 + if (request->fl_flags & FL_EXISTS) 953 + error = -ENOENT; 964 954 goto out; 955 + } 965 956 966 957 if (!new_fl) { 967 958 error = -ENOLCK; ··· 1011 996 * Add a POSIX style lock to a file. 1012 997 * We merge adjacent & overlapping locks whenever possible. 1013 998 * POSIX locks are sorted by owner task, then by starting address 999 + * 1000 + * Note that if called with an FL_EXISTS argument, the caller may determine 1001 + * whether or not a lock was successfully freed by testing the return 1002 + * value for -ENOENT. 1014 1003 */ 1015 1004 int posix_lock_file(struct file *filp, struct file_lock *fl) 1016 1005 {
+3 -1
fs/nfs/dir.c
··· 690 690 goto out_force; 691 691 /* This is an open(2) */ 692 692 if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && 693 - !(server->flags & NFS_MOUNT_NOCTO)) 693 + !(server->flags & NFS_MOUNT_NOCTO) && 694 + (S_ISREG(inode->i_mode) || 695 + S_ISDIR(inode->i_mode))) 694 696 goto out_force; 695 697 } 696 698 return nfs_revalidate_inode(server, inode);
+201 -234
fs/nfs/direct.c
··· 67 67 struct kref kref; /* release manager */ 68 68 69 69 /* I/O parameters */ 70 - struct list_head list, /* nfs_read/write_data structs */ 71 - rewrite_list; /* saved nfs_write_data structs */ 72 70 struct nfs_open_context *ctx; /* file open context info */ 73 71 struct kiocb * iocb; /* controlling i/o request */ 74 72 struct inode * inode; /* target file of i/o */ 75 - unsigned long user_addr; /* location of user's buffer */ 76 - size_t user_count; /* total bytes to move */ 77 - loff_t pos; /* starting offset in file */ 78 - struct page ** pages; /* pages in our buffer */ 79 - unsigned int npages; /* count of pages */ 80 73 81 74 /* completion state */ 75 + atomic_t io_count; /* i/os we're waiting for */ 82 76 spinlock_t lock; /* protect completion state */ 83 - int outstanding; /* i/os we're waiting for */ 84 77 ssize_t count, /* bytes actually processed */ 85 78 error; /* any reported error */ 86 79 struct completion completion; /* wait for i/o completion */ 87 80 88 81 /* commit state */ 82 + struct list_head rewrite_list; /* saved nfs_write_data structs */ 89 83 struct nfs_write_data * commit_data; /* special write_data for commits */ 90 84 int flags; 91 85 #define NFS_ODIRECT_DO_COMMIT (1) /* an unstable reply was received */ ··· 87 93 struct nfs_writeverf verf; /* unstable write verifier */ 88 94 }; 89 95 90 - static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, int sync); 91 96 static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode); 97 + static const struct rpc_call_ops nfs_write_direct_ops; 98 + 99 + static inline void get_dreq(struct nfs_direct_req *dreq) 100 + { 101 + atomic_inc(&dreq->io_count); 102 + } 103 + 104 + static inline int put_dreq(struct nfs_direct_req *dreq) 105 + { 106 + return atomic_dec_and_test(&dreq->io_count); 107 + } 108 + 109 + /* 110 + * "size" is never larger than rsize or wsize. 111 + */ 112 + static inline int nfs_direct_count_pages(unsigned long user_addr, size_t size) 113 + { 114 + int page_count; 115 + 116 + page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT; 117 + page_count -= user_addr >> PAGE_SHIFT; 118 + BUG_ON(page_count < 0); 119 + 120 + return page_count; 121 + } 122 + 123 + static inline unsigned int nfs_max_pages(unsigned int size) 124 + { 125 + return (size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 126 + } 92 127 93 128 /** 94 129 * nfs_direct_IO - NFS address space operation for direct I/O ··· 141 118 return -EINVAL; 142 119 } 143 120 144 - static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty) 121 + static void nfs_direct_dirty_pages(struct page **pages, int npages) 145 122 { 146 123 int i; 147 124 for (i = 0; i < npages; i++) { 148 125 struct page *page = pages[i]; 149 - if (do_dirty && !PageCompound(page)) 126 + if (!PageCompound(page)) 150 127 set_page_dirty_lock(page); 151 - page_cache_release(page); 152 128 } 153 - kfree(pages); 154 129 } 155 130 156 - static inline int nfs_get_user_pages(int rw, unsigned long user_addr, size_t size, struct page ***pages) 131 + static void nfs_direct_release_pages(struct page **pages, int npages) 157 132 { 158 - int result = -ENOMEM; 159 - unsigned long page_count; 160 - size_t array_size; 161 - 162 - page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT; 163 - page_count -= user_addr >> PAGE_SHIFT; 164 - 165 - array_size = (page_count * sizeof(struct page *)); 166 - *pages = kmalloc(array_size, GFP_KERNEL); 167 - if (*pages) { 168 - down_read(&current->mm->mmap_sem); 169 - result = get_user_pages(current, current->mm, user_addr, 170 - page_count, (rw == READ), 0, 171 - *pages, NULL); 172 - up_read(&current->mm->mmap_sem); 173 - if (result != page_count) { 174 - /* 175 - * If we got fewer pages than expected from 176 - * get_user_pages(), the user buffer runs off the 177 - * end of a mapping; return EFAULT. 178 - */ 179 - if (result >= 0) { 180 - nfs_free_user_pages(*pages, result, 0); 181 - result = -EFAULT; 182 - } else 183 - kfree(*pages); 184 - *pages = NULL; 185 - } 186 - } 187 - return result; 133 + int i; 134 + for (i = 0; i < npages; i++) 135 + page_cache_release(pages[i]); 188 136 } 189 137 190 138 static inline struct nfs_direct_req *nfs_direct_req_alloc(void) ··· 167 173 return NULL; 168 174 169 175 kref_init(&dreq->kref); 176 + kref_get(&dreq->kref); 170 177 init_completion(&dreq->completion); 171 - INIT_LIST_HEAD(&dreq->list); 172 178 INIT_LIST_HEAD(&dreq->rewrite_list); 173 179 dreq->iocb = NULL; 174 180 dreq->ctx = NULL; 175 181 spin_lock_init(&dreq->lock); 176 - dreq->outstanding = 0; 182 + atomic_set(&dreq->io_count, 0); 177 183 dreq->count = 0; 178 184 dreq->error = 0; 179 185 dreq->flags = 0; ··· 214 220 } 215 221 216 222 /* 217 - * We must hold a reference to all the pages in this direct read request 218 - * until the RPCs complete. This could be long *after* we are woken up in 219 - * nfs_direct_wait (for instance, if someone hits ^C on a slow server). 220 - * 221 - * In addition, synchronous I/O uses a stack-allocated iocb. Thus we 222 - * can't trust the iocb is still valid here if this is a synchronous 223 - * request. If the waiter is woken prematurely, the iocb is long gone. 223 + * Synchronous I/O uses a stack-allocated iocb. Thus we can't trust 224 + * the iocb is still valid here if this is a synchronous request. 224 225 */ 225 226 static void nfs_direct_complete(struct nfs_direct_req *dreq) 226 227 { 227 - nfs_free_user_pages(dreq->pages, dreq->npages, 1); 228 - 229 228 if (dreq->iocb) { 230 229 long res = (long) dreq->error; 231 230 if (!res) ··· 231 244 } 232 245 233 246 /* 234 - * Note we also set the number of requests we have in the dreq when we are 235 - * done. This prevents races with I/O completion so we will always wait 236 - * until all requests have been dispatched and completed. 247 + * We must hold a reference to all the pages in this direct read request 248 + * until the RPCs complete. This could be long *after* we are woken up in 249 + * nfs_direct_wait (for instance, if someone hits ^C on a slow server). 237 250 */ 238 - static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, size_t rsize) 239 - { 240 - struct list_head *list; 241 - struct nfs_direct_req *dreq; 242 - unsigned int rpages = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 243 - 244 - dreq = nfs_direct_req_alloc(); 245 - if (!dreq) 246 - return NULL; 247 - 248 - list = &dreq->list; 249 - for(;;) { 250 - struct nfs_read_data *data = nfs_readdata_alloc(rpages); 251 - 252 - if (unlikely(!data)) { 253 - while (!list_empty(list)) { 254 - data = list_entry(list->next, 255 - struct nfs_read_data, pages); 256 - list_del(&data->pages); 257 - nfs_readdata_free(data); 258 - } 259 - kref_put(&dreq->kref, nfs_direct_req_release); 260 - return NULL; 261 - } 262 - 263 - INIT_LIST_HEAD(&data->pages); 264 - list_add(&data->pages, list); 265 - 266 - data->req = (struct nfs_page *) dreq; 267 - dreq->outstanding++; 268 - if (nbytes <= rsize) 269 - break; 270 - nbytes -= rsize; 271 - } 272 - kref_get(&dreq->kref); 273 - return dreq; 274 - } 275 - 276 251 static void nfs_direct_read_result(struct rpc_task *task, void *calldata) 277 252 { 278 253 struct nfs_read_data *data = calldata; ··· 243 294 if (nfs_readpage_result(task, data) != 0) 244 295 return; 245 296 297 + nfs_direct_dirty_pages(data->pagevec, data->npages); 298 + nfs_direct_release_pages(data->pagevec, data->npages); 299 + 246 300 spin_lock(&dreq->lock); 247 301 248 302 if (likely(task->tk_status >= 0)) ··· 253 301 else 254 302 dreq->error = task->tk_status; 255 303 256 - if (--dreq->outstanding) { 257 - spin_unlock(&dreq->lock); 258 - return; 259 - } 260 - 261 304 spin_unlock(&dreq->lock); 262 - nfs_direct_complete(dreq); 305 + 306 + if (put_dreq(dreq)) 307 + nfs_direct_complete(dreq); 263 308 } 264 309 265 310 static const struct rpc_call_ops nfs_read_direct_ops = { ··· 265 316 }; 266 317 267 318 /* 268 - * For each nfs_read_data struct that was allocated on the list, dispatch 269 - * an NFS READ operation 319 + * For each rsize'd chunk of the user's buffer, dispatch an NFS READ 320 + * operation. If nfs_readdata_alloc() or get_user_pages() fails, 321 + * bail and stop sending more reads. Read length accounting is 322 + * handled automatically by nfs_direct_read_result(). Otherwise, if 323 + * no requests have been sent, just return an error. 270 324 */ 271 - static void nfs_direct_read_schedule(struct nfs_direct_req *dreq) 325 + static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos) 272 326 { 273 327 struct nfs_open_context *ctx = dreq->ctx; 274 328 struct inode *inode = ctx->dentry->d_inode; 275 - struct list_head *list = &dreq->list; 276 - struct page **pages = dreq->pages; 277 - size_t count = dreq->user_count; 278 - loff_t pos = dreq->pos; 279 329 size_t rsize = NFS_SERVER(inode)->rsize; 280 - unsigned int curpage, pgbase; 330 + unsigned int rpages = nfs_max_pages(rsize); 331 + unsigned int pgbase; 332 + int result; 333 + ssize_t started = 0; 281 334 282 - curpage = 0; 283 - pgbase = dreq->user_addr & ~PAGE_MASK; 335 + get_dreq(dreq); 336 + 337 + pgbase = user_addr & ~PAGE_MASK; 284 338 do { 285 339 struct nfs_read_data *data; 286 340 size_t bytes; 341 + 342 + result = -ENOMEM; 343 + data = nfs_readdata_alloc(rpages); 344 + if (unlikely(!data)) 345 + break; 287 346 288 347 bytes = rsize; 289 348 if (count < rsize) 290 349 bytes = count; 291 350 292 - BUG_ON(list_empty(list)); 293 - data = list_entry(list->next, struct nfs_read_data, pages); 294 - list_del_init(&data->pages); 351 + data->npages = nfs_direct_count_pages(user_addr, bytes); 352 + down_read(&current->mm->mmap_sem); 353 + result = get_user_pages(current, current->mm, user_addr, 354 + data->npages, 1, 0, data->pagevec, NULL); 355 + up_read(&current->mm->mmap_sem); 356 + if (unlikely(result < data->npages)) { 357 + if (result > 0) 358 + nfs_direct_release_pages(data->pagevec, result); 359 + nfs_readdata_release(data); 360 + break; 361 + } 295 362 363 + get_dreq(dreq); 364 + 365 + data->req = (struct nfs_page *) dreq; 296 366 data->inode = inode; 297 367 data->cred = ctx->cred; 298 368 data->args.fh = NFS_FH(inode); 299 369 data->args.context = ctx; 300 370 data->args.offset = pos; 301 371 data->args.pgbase = pgbase; 302 - data->args.pages = &pages[curpage]; 372 + data->args.pages = data->pagevec; 303 373 data->args.count = bytes; 304 374 data->res.fattr = &data->fattr; 305 375 data->res.eof = 0; ··· 341 373 bytes, 342 374 (unsigned long long)data->args.offset); 343 375 376 + started += bytes; 377 + user_addr += bytes; 344 378 pos += bytes; 345 379 pgbase += bytes; 346 - curpage += pgbase >> PAGE_SHIFT; 347 380 pgbase &= ~PAGE_MASK; 348 381 349 382 count -= bytes; 350 383 } while (count != 0); 351 - BUG_ON(!list_empty(list)); 384 + 385 + if (put_dreq(dreq)) 386 + nfs_direct_complete(dreq); 387 + 388 + if (started) 389 + return 0; 390 + return result < 0 ? (ssize_t) result : -EFAULT; 352 391 } 353 392 354 - static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos, struct page **pages, unsigned int nr_pages) 393 + static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) 355 394 { 356 - ssize_t result; 395 + ssize_t result = 0; 357 396 sigset_t oldset; 358 397 struct inode *inode = iocb->ki_filp->f_mapping->host; 359 398 struct rpc_clnt *clnt = NFS_CLIENT(inode); 360 399 struct nfs_direct_req *dreq; 361 400 362 - dreq = nfs_direct_read_alloc(count, NFS_SERVER(inode)->rsize); 401 + dreq = nfs_direct_req_alloc(); 363 402 if (!dreq) 364 403 return -ENOMEM; 365 404 366 - dreq->user_addr = user_addr; 367 - dreq->user_count = count; 368 - dreq->pos = pos; 369 - dreq->pages = pages; 370 - dreq->npages = nr_pages; 371 405 dreq->inode = inode; 372 406 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data); 373 407 if (!is_sync_kiocb(iocb)) ··· 377 407 378 408 nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); 379 409 rpc_clnt_sigmask(clnt, &oldset); 380 - nfs_direct_read_schedule(dreq); 381 - result = nfs_direct_wait(dreq); 410 + result = nfs_direct_read_schedule(dreq, user_addr, count, pos); 411 + if (!result) 412 + result = nfs_direct_wait(dreq); 382 413 rpc_clnt_sigunmask(clnt, &oldset); 383 414 384 415 return result; ··· 387 416 388 417 static void nfs_direct_free_writedata(struct nfs_direct_req *dreq) 389 418 { 390 - list_splice_init(&dreq->rewrite_list, &dreq->list); 391 - while (!list_empty(&dreq->list)) { 392 - struct nfs_write_data *data = list_entry(dreq->list.next, struct nfs_write_data, pages); 419 + while (!list_empty(&dreq->rewrite_list)) { 420 + struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages); 393 421 list_del(&data->pages); 422 + nfs_direct_release_pages(data->pagevec, data->npages); 394 423 nfs_writedata_release(data); 395 424 } 396 425 } ··· 398 427 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 399 428 static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 400 429 { 401 - struct list_head *pos; 430 + struct inode *inode = dreq->inode; 431 + struct list_head *p; 432 + struct nfs_write_data *data; 402 433 403 - list_splice_init(&dreq->rewrite_list, &dreq->list); 404 - list_for_each(pos, &dreq->list) 405 - dreq->outstanding++; 406 434 dreq->count = 0; 435 + get_dreq(dreq); 407 436 408 - nfs_direct_write_schedule(dreq, FLUSH_STABLE); 437 + list_for_each(p, &dreq->rewrite_list) { 438 + data = list_entry(p, struct nfs_write_data, pages); 439 + 440 + get_dreq(dreq); 441 + 442 + /* 443 + * Reset data->res. 444 + */ 445 + nfs_fattr_init(&data->fattr); 446 + data->res.count = data->args.count; 447 + memset(&data->verf, 0, sizeof(data->verf)); 448 + 449 + /* 450 + * Reuse data->task; data->args should not have changed 451 + * since the original request was sent. 452 + */ 453 + rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 454 + &nfs_write_direct_ops, data); 455 + NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); 456 + 457 + data->task.tk_priority = RPC_PRIORITY_NORMAL; 458 + data->task.tk_cookie = (unsigned long) inode; 459 + 460 + /* 461 + * We're called via an RPC callback, so BKL is already held. 462 + */ 463 + rpc_execute(&data->task); 464 + 465 + dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n", 466 + data->task.tk_pid, 467 + inode->i_sb->s_id, 468 + (long long)NFS_FILEID(inode), 469 + data->args.count, 470 + (unsigned long long)data->args.offset); 471 + } 472 + 473 + if (put_dreq(dreq)) 474 + nfs_direct_write_complete(dreq, inode); 409 475 } 410 476 411 477 static void nfs_direct_commit_result(struct rpc_task *task, void *calldata) ··· 479 471 data->cred = dreq->ctx->cred; 480 472 481 473 data->args.fh = NFS_FH(data->inode); 482 - data->args.offset = dreq->pos; 483 - data->args.count = dreq->user_count; 474 + data->args.offset = 0; 475 + data->args.count = 0; 484 476 data->res.count = 0; 485 477 data->res.fattr = &data->fattr; 486 478 data->res.verf = &data->verf; ··· 542 534 } 543 535 #endif 544 536 545 - static struct nfs_direct_req *nfs_direct_write_alloc(size_t nbytes, size_t wsize) 546 - { 547 - struct list_head *list; 548 - struct nfs_direct_req *dreq; 549 - unsigned int wpages = (wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 550 - 551 - dreq = nfs_direct_req_alloc(); 552 - if (!dreq) 553 - return NULL; 554 - 555 - list = &dreq->list; 556 - for(;;) { 557 - struct nfs_write_data *data = nfs_writedata_alloc(wpages); 558 - 559 - if (unlikely(!data)) { 560 - while (!list_empty(list)) { 561 - data = list_entry(list->next, 562 - struct nfs_write_data, pages); 563 - list_del(&data->pages); 564 - nfs_writedata_free(data); 565 - } 566 - kref_put(&dreq->kref, nfs_direct_req_release); 567 - return NULL; 568 - } 569 - 570 - INIT_LIST_HEAD(&data->pages); 571 - list_add(&data->pages, list); 572 - 573 - data->req = (struct nfs_page *) dreq; 574 - dreq->outstanding++; 575 - if (nbytes <= wsize) 576 - break; 577 - nbytes -= wsize; 578 - } 579 - 580 - nfs_alloc_commit_data(dreq); 581 - 582 - kref_get(&dreq->kref); 583 - return dreq; 584 - } 585 - 586 537 static void nfs_direct_write_result(struct rpc_task *task, void *calldata) 587 538 { 588 539 struct nfs_write_data *data = calldata; ··· 571 604 } 572 605 } 573 606 } 574 - /* In case we have to resend */ 575 - data->args.stable = NFS_FILE_SYNC; 576 607 577 608 spin_unlock(&dreq->lock); 578 609 } ··· 584 619 struct nfs_write_data *data = calldata; 585 620 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req; 586 621 587 - spin_lock(&dreq->lock); 588 - if (--dreq->outstanding) { 589 - spin_unlock(&dreq->lock); 590 - return; 591 - } 592 - spin_unlock(&dreq->lock); 593 - 594 - nfs_direct_write_complete(dreq, data->inode); 622 + if (put_dreq(dreq)) 623 + nfs_direct_write_complete(dreq, data->inode); 595 624 } 596 625 597 626 static const struct rpc_call_ops nfs_write_direct_ops = { ··· 594 635 }; 595 636 596 637 /* 597 - * For each nfs_write_data struct that was allocated on the list, dispatch 598 - * an NFS WRITE operation 638 + * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE 639 + * operation. If nfs_writedata_alloc() or get_user_pages() fails, 640 + * bail and stop sending more writes. Write length accounting is 641 + * handled automatically by nfs_direct_write_result(). Otherwise, if 642 + * no requests have been sent, just return an error. 599 643 */ 600 - static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, int sync) 644 + static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync) 601 645 { 602 646 struct nfs_open_context *ctx = dreq->ctx; 603 647 struct inode *inode = ctx->dentry->d_inode; 604 - struct list_head *list = &dreq->list; 605 - struct page **pages = dreq->pages; 606 - size_t count = dreq->user_count; 607 - loff_t pos = dreq->pos; 608 648 size_t wsize = NFS_SERVER(inode)->wsize; 609 - unsigned int curpage, pgbase; 649 + unsigned int wpages = nfs_max_pages(wsize); 650 + unsigned int pgbase; 651 + int result; 652 + ssize_t started = 0; 610 653 611 - curpage = 0; 612 - pgbase = dreq->user_addr & ~PAGE_MASK; 654 + get_dreq(dreq); 655 + 656 + pgbase = user_addr & ~PAGE_MASK; 613 657 do { 614 658 struct nfs_write_data *data; 615 659 size_t bytes; 660 + 661 + result = -ENOMEM; 662 + data = nfs_writedata_alloc(wpages); 663 + if (unlikely(!data)) 664 + break; 616 665 617 666 bytes = wsize; 618 667 if (count < wsize) 619 668 bytes = count; 620 669 621 - BUG_ON(list_empty(list)); 622 - data = list_entry(list->next, struct nfs_write_data, pages); 670 + data->npages = nfs_direct_count_pages(user_addr, bytes); 671 + down_read(&current->mm->mmap_sem); 672 + result = get_user_pages(current, current->mm, user_addr, 673 + data->npages, 0, 0, data->pagevec, NULL); 674 + up_read(&current->mm->mmap_sem); 675 + if (unlikely(result < data->npages)) { 676 + if (result > 0) 677 + nfs_direct_release_pages(data->pagevec, result); 678 + nfs_writedata_release(data); 679 + break; 680 + } 681 + 682 + get_dreq(dreq); 683 + 623 684 list_move_tail(&data->pages, &dreq->rewrite_list); 624 685 686 + data->req = (struct nfs_page *) dreq; 625 687 data->inode = inode; 626 688 data->cred = ctx->cred; 627 689 data->args.fh = NFS_FH(inode); 628 690 data->args.context = ctx; 629 691 data->args.offset = pos; 630 692 data->args.pgbase = pgbase; 631 - data->args.pages = &pages[curpage]; 693 + data->args.pages = data->pagevec; 632 694 data->args.count = bytes; 633 695 data->res.fattr = &data->fattr; 634 696 data->res.count = bytes; ··· 673 693 bytes, 674 694 (unsigned long long)data->args.offset); 675 695 696 + started += bytes; 697 + user_addr += bytes; 676 698 pos += bytes; 677 699 pgbase += bytes; 678 - curpage += pgbase >> PAGE_SHIFT; 679 700 pgbase &= ~PAGE_MASK; 680 701 681 702 count -= bytes; 682 703 } while (count != 0); 683 - BUG_ON(!list_empty(list)); 704 + 705 + if (put_dreq(dreq)) 706 + nfs_direct_write_complete(dreq, inode); 707 + 708 + if (started) 709 + return 0; 710 + return result < 0 ? (ssize_t) result : -EFAULT; 684 711 } 685 712 686 - static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos, struct page **pages, int nr_pages) 713 + static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) 687 714 { 688 - ssize_t result; 715 + ssize_t result = 0; 689 716 sigset_t oldset; 690 717 struct inode *inode = iocb->ki_filp->f_mapping->host; 691 718 struct rpc_clnt *clnt = NFS_CLIENT(inode); ··· 700 713 size_t wsize = NFS_SERVER(inode)->wsize; 701 714 int sync = 0; 702 715 703 - dreq = nfs_direct_write_alloc(count, wsize); 716 + dreq = nfs_direct_req_alloc(); 704 717 if (!dreq) 705 718 return -ENOMEM; 719 + nfs_alloc_commit_data(dreq); 720 + 706 721 if (dreq->commit_data == NULL || count < wsize) 707 722 sync = FLUSH_STABLE; 708 723 709 - dreq->user_addr = user_addr; 710 - dreq->user_count = count; 711 - dreq->pos = pos; 712 - dreq->pages = pages; 713 - dreq->npages = nr_pages; 714 724 dreq->inode = inode; 715 725 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data); 716 726 if (!is_sync_kiocb(iocb)) ··· 718 734 nfs_begin_data_update(inode); 719 735 720 736 rpc_clnt_sigmask(clnt, &oldset); 721 - nfs_direct_write_schedule(dreq, sync); 722 - result = nfs_direct_wait(dreq); 737 + result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync); 738 + if (!result) 739 + result = nfs_direct_wait(dreq); 723 740 rpc_clnt_sigunmask(clnt, &oldset); 724 741 725 742 return result; ··· 750 765 ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) 751 766 { 752 767 ssize_t retval = -EINVAL; 753 - int page_count; 754 - struct page **pages; 755 768 struct file *file = iocb->ki_filp; 756 769 struct address_space *mapping = file->f_mapping; 757 770 ··· 771 788 if (retval) 772 789 goto out; 773 790 774 - retval = nfs_get_user_pages(READ, (unsigned long) buf, 775 - count, &pages); 776 - if (retval < 0) 777 - goto out; 778 - page_count = retval; 779 - 780 - retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos, 781 - pages, page_count); 791 + retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos); 782 792 if (retval > 0) 783 793 iocb->ki_pos = pos + retval; 784 794 ··· 807 831 ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) 808 832 { 809 833 ssize_t retval; 810 - int page_count; 811 - struct page **pages; 812 834 struct file *file = iocb->ki_filp; 813 835 struct address_space *mapping = file->f_mapping; 814 836 ··· 834 860 if (retval) 835 861 goto out; 836 862 837 - retval = nfs_get_user_pages(WRITE, (unsigned long) buf, 838 - count, &pages); 839 - if (retval < 0) 840 - goto out; 841 - page_count = retval; 842 - 843 - retval = nfs_direct_write(iocb, (unsigned long) buf, count, 844 - pos, pages, page_count); 863 + retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos); 845 864 846 865 /* 847 866 * XXX: nfs_end_data_update() already ensures this file's
+41 -33
fs/nfs/nfs4proc.c
··· 3144 3144 default: 3145 3145 BUG(); 3146 3146 } 3147 - if (res < 0) 3148 - printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", 3149 - __FUNCTION__); 3150 3147 return res; 3151 3148 } 3152 3149 ··· 3255 3258 return ERR_PTR(-ENOMEM); 3256 3259 } 3257 3260 3258 - /* Unlock _before_ we do the RPC call */ 3259 - do_vfs_lock(fl->fl_file, fl); 3260 3261 return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); 3261 3262 } 3262 3263 ··· 3265 3270 struct rpc_task *task; 3266 3271 int status = 0; 3267 3272 3273 + status = nfs4_set_lock_state(state, request); 3274 + /* Unlock _before_ we do the RPC call */ 3275 + request->fl_flags |= FL_EXISTS; 3276 + if (do_vfs_lock(request->fl_file, request) == -ENOENT) 3277 + goto out; 3278 + if (status != 0) 3279 + goto out; 3268 3280 /* Is this a delegated lock? */ 3269 3281 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) 3270 - goto out_unlock; 3271 - /* Is this open_owner holding any locks on the server? */ 3272 - if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) 3273 - goto out_unlock; 3274 - 3275 - status = nfs4_set_lock_state(state, request); 3276 - if (status != 0) 3277 - goto out_unlock; 3282 + goto out; 3278 3283 lsp = request->fl_u.nfs4_fl.owner; 3279 - status = -ENOMEM; 3280 3284 seqid = nfs_alloc_seqid(&lsp->ls_seqid); 3285 + status = -ENOMEM; 3281 3286 if (seqid == NULL) 3282 - goto out_unlock; 3287 + goto out; 3283 3288 task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid); 3284 3289 status = PTR_ERR(task); 3285 3290 if (IS_ERR(task)) 3286 - goto out_unlock; 3291 + goto out; 3287 3292 status = nfs4_wait_for_completion_rpc_task(task); 3288 3293 rpc_release_task(task); 3289 - return status; 3290 - out_unlock: 3291 - do_vfs_lock(request->fl_file, request); 3294 + out: 3292 3295 return status; 3293 3296 } 3294 3297 ··· 3454 3461 struct nfs4_exception exception = { }; 3455 3462 int err; 3456 3463 3457 - /* Cache the lock if possible... */ 3458 - if (test_bit(NFS_DELEGATED_STATE, &state->flags)) 3459 - return 0; 3460 3464 do { 3465 + /* Cache the lock if possible... */ 3466 + if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 3467 + return 0; 3461 3468 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 3462 3469 if (err != -NFS4ERR_DELAY) 3463 3470 break; ··· 3476 3483 if (err != 0) 3477 3484 return err; 3478 3485 do { 3486 + if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 3487 + return 0; 3479 3488 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 3480 3489 if (err != -NFS4ERR_DELAY) 3481 3490 break; ··· 3489 3494 static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3490 3495 { 3491 3496 struct nfs4_client *clp = state->owner->so_client; 3497 + unsigned char fl_flags = request->fl_flags; 3492 3498 int status; 3493 3499 3494 3500 /* Is this a delegated open? */ 3495 - if (NFS_I(state->inode)->delegation_state != 0) { 3496 - /* Yes: cache locks! */ 3497 - status = do_vfs_lock(request->fl_file, request); 3498 - /* ...but avoid races with delegation recall... */ 3499 - if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags)) 3500 - return status; 3501 - } 3502 - down_read(&clp->cl_sem); 3503 3501 status = nfs4_set_lock_state(state, request); 3504 3502 if (status != 0) 3505 3503 goto out; 3504 + request->fl_flags |= FL_ACCESS; 3505 + status = do_vfs_lock(request->fl_file, request); 3506 + if (status < 0) 3507 + goto out; 3508 + down_read(&clp->cl_sem); 3509 + if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { 3510 + struct nfs_inode *nfsi = NFS_I(state->inode); 3511 + /* Yes: cache locks! */ 3512 + down_read(&nfsi->rwsem); 3513 + /* ...but avoid races with delegation recall... */ 3514 + if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { 3515 + request->fl_flags = fl_flags & ~FL_SLEEP; 3516 + status = do_vfs_lock(request->fl_file, request); 3517 + up_read(&nfsi->rwsem); 3518 + goto out_unlock; 3519 + } 3520 + up_read(&nfsi->rwsem); 3521 + } 3506 3522 status = _nfs4_do_setlk(state, cmd, request, 0); 3507 3523 if (status != 0) 3508 - goto out; 3524 + goto out_unlock; 3509 3525 /* Note: we always want to sleep here! */ 3510 - request->fl_flags |= FL_SLEEP; 3526 + request->fl_flags = fl_flags | FL_SLEEP; 3511 3527 if (do_vfs_lock(request->fl_file, request) < 0) 3512 3528 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); 3513 - out: 3529 + out_unlock: 3514 3530 up_read(&clp->cl_sem); 3531 + out: 3532 + request->fl_flags = fl_flags; 3515 3533 return status; 3516 3534 } 3517 3535
+17 -3
fs/nfs/write.c
··· 578 578 return ret; 579 579 } 580 580 581 - static void nfs_cancel_requests(struct list_head *head) 581 + static void nfs_cancel_dirty_list(struct list_head *head) 582 582 { 583 583 struct nfs_page *req; 584 584 while(!list_empty(head)) { ··· 586 586 nfs_list_remove_request(req); 587 587 nfs_inode_remove_request(req); 588 588 nfs_clear_page_writeback(req); 589 + } 590 + } 591 + 592 + static void nfs_cancel_commit_list(struct list_head *head) 593 + { 594 + struct nfs_page *req; 595 + 596 + while(!list_empty(head)) { 597 + req = nfs_list_entry(head->next); 598 + nfs_list_remove_request(req); 599 + nfs_inode_remove_request(req); 600 + nfs_clear_page_writeback(req); 601 + dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 589 602 } 590 603 } 591 604 ··· 1394 1381 nfs_list_remove_request(req); 1395 1382 nfs_mark_request_commit(req); 1396 1383 nfs_clear_page_writeback(req); 1384 + dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1397 1385 } 1398 1386 return -ENOMEM; 1399 1387 } ··· 1513 1499 if (pages != 0) { 1514 1500 spin_unlock(&nfsi->req_lock); 1515 1501 if (how & FLUSH_INVALIDATE) 1516 - nfs_cancel_requests(&head); 1502 + nfs_cancel_dirty_list(&head); 1517 1503 else 1518 1504 ret = nfs_flush_list(inode, &head, pages, how); 1519 1505 spin_lock(&nfsi->req_lock); ··· 1526 1512 break; 1527 1513 if (how & FLUSH_INVALIDATE) { 1528 1514 spin_unlock(&nfsi->req_lock); 1529 - nfs_cancel_requests(&head); 1515 + nfs_cancel_commit_list(&head); 1530 1516 spin_lock(&nfsi->req_lock); 1531 1517 continue; 1532 1518 }
+1
include/linux/fs.h
··· 716 716 #define FL_POSIX 1 717 717 #define FL_FLOCK 2 718 718 #define FL_ACCESS 8 /* not trying to lock, just looking */ 719 + #define FL_EXISTS 16 /* when unlocking, test for existence */ 719 720 #define FL_LEASE 32 /* lease held on this file */ 720 721 #define FL_CLOSE 64 /* unlock on close */ 721 722 #define FL_SLEEP 128 /* A blocking lock */
+2
include/linux/nfs_xdr.h
··· 729 729 struct list_head pages; /* Coalesced read requests */ 730 730 struct nfs_page *req; /* multi ops per nfs_page */ 731 731 struct page **pagevec; 732 + unsigned int npages; /* active pages in pagevec */ 732 733 struct nfs_readargs args; 733 734 struct nfs_readres res; 734 735 #ifdef CONFIG_NFS_V4 ··· 748 747 struct list_head pages; /* Coalesced requests we wish to flush */ 749 748 struct nfs_page *req; /* multi ops per nfs_page */ 750 749 struct page **pagevec; 750 + unsigned int npages; /* active pages in pagevec */ 751 751 struct nfs_writeargs args; /* argument struct */ 752 752 struct nfs_writeres res; /* result struct */ 753 753 #ifdef CONFIG_NFS_V4
+1 -2
net/sunrpc/xdr.c
··· 191 191 do { 192 192 /* Are any pointers crossing a page boundary? */ 193 193 if (pgto_base == 0) { 194 - flush_dcache_page(*pgto); 195 194 pgto_base = PAGE_CACHE_SIZE; 196 195 pgto--; 197 196 } ··· 210 211 vto = kmap_atomic(*pgto, KM_USER0); 211 212 vfrom = kmap_atomic(*pgfrom, KM_USER1); 212 213 memmove(vto + pgto_base, vfrom + pgfrom_base, copy); 214 + flush_dcache_page(*pgto); 213 215 kunmap_atomic(vfrom, KM_USER1); 214 216 kunmap_atomic(vto, KM_USER0); 215 217 216 218 } while ((len -= copy) != 0); 217 - flush_dcache_page(*pgto); 218 219 } 219 220 220 221 /*