diff options
Diffstat (limited to 'fs/nfs/file.c')
| -rw-r--r-- | fs/nfs/file.c | 155 |
1 files changed, 116 insertions, 39 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 4e98a56a1777..78460657f5cb 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -50,7 +50,7 @@ static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, | |||
| 50 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, | 50 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, |
| 51 | unsigned long nr_segs, loff_t pos); | 51 | unsigned long nr_segs, loff_t pos); |
| 52 | static int nfs_file_flush(struct file *, fl_owner_t id); | 52 | static int nfs_file_flush(struct file *, fl_owner_t id); |
| 53 | static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); | 53 | static int nfs_file_fsync(struct file *, struct dentry *dentry, int datasync); |
| 54 | static int nfs_check_flags(int flags); | 54 | static int nfs_check_flags(int flags); |
| 55 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 55 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
| 56 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | 56 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); |
| @@ -72,7 +72,7 @@ const struct file_operations nfs_file_operations = { | |||
| 72 | .open = nfs_file_open, | 72 | .open = nfs_file_open, |
| 73 | .flush = nfs_file_flush, | 73 | .flush = nfs_file_flush, |
| 74 | .release = nfs_file_release, | 74 | .release = nfs_file_release, |
| 75 | .fsync = nfs_fsync, | 75 | .fsync = nfs_file_fsync, |
| 76 | .lock = nfs_lock, | 76 | .lock = nfs_lock, |
| 77 | .flock = nfs_flock, | 77 | .flock = nfs_flock, |
| 78 | .splice_read = nfs_file_splice_read, | 78 | .splice_read = nfs_file_splice_read, |
| @@ -119,25 +119,33 @@ nfs_file_open(struct inode *inode, struct file *filp) | |||
| 119 | { | 119 | { |
| 120 | int res; | 120 | int res; |
| 121 | 121 | ||
| 122 | dprintk("NFS: open file(%s/%s)\n", | ||
| 123 | filp->f_path.dentry->d_parent->d_name.name, | ||
| 124 | filp->f_path.dentry->d_name.name); | ||
| 125 | |||
| 122 | res = nfs_check_flags(filp->f_flags); | 126 | res = nfs_check_flags(filp->f_flags); |
| 123 | if (res) | 127 | if (res) |
| 124 | return res; | 128 | return res; |
| 125 | 129 | ||
| 126 | nfs_inc_stats(inode, NFSIOS_VFSOPEN); | 130 | nfs_inc_stats(inode, NFSIOS_VFSOPEN); |
| 127 | lock_kernel(); | 131 | res = nfs_open(inode, filp); |
| 128 | res = NFS_PROTO(inode)->file_open(inode, filp); | ||
| 129 | unlock_kernel(); | ||
| 130 | return res; | 132 | return res; |
| 131 | } | 133 | } |
| 132 | 134 | ||
| 133 | static int | 135 | static int |
| 134 | nfs_file_release(struct inode *inode, struct file *filp) | 136 | nfs_file_release(struct inode *inode, struct file *filp) |
| 135 | { | 137 | { |
| 138 | struct dentry *dentry = filp->f_path.dentry; | ||
| 139 | |||
| 140 | dprintk("NFS: release(%s/%s)\n", | ||
| 141 | dentry->d_parent->d_name.name, | ||
| 142 | dentry->d_name.name); | ||
| 143 | |||
| 136 | /* Ensure that dirty pages are flushed out with the right creds */ | 144 | /* Ensure that dirty pages are flushed out with the right creds */ |
| 137 | if (filp->f_mode & FMODE_WRITE) | 145 | if (filp->f_mode & FMODE_WRITE) |
| 138 | nfs_wb_all(filp->f_path.dentry->d_inode); | 146 | nfs_wb_all(dentry->d_inode); |
| 139 | nfs_inc_stats(inode, NFSIOS_VFSRELEASE); | 147 | nfs_inc_stats(inode, NFSIOS_VFSRELEASE); |
| 140 | return NFS_PROTO(inode)->file_release(inode, filp); | 148 | return nfs_release(inode, filp); |
| 141 | } | 149 | } |
| 142 | 150 | ||
| 143 | /** | 151 | /** |
| @@ -171,6 +179,12 @@ force_reval: | |||
| 171 | static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) | 179 | static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) |
| 172 | { | 180 | { |
| 173 | loff_t loff; | 181 | loff_t loff; |
| 182 | |||
| 183 | dprintk("NFS: llseek file(%s/%s, %lld, %d)\n", | ||
| 184 | filp->f_path.dentry->d_parent->d_name.name, | ||
| 185 | filp->f_path.dentry->d_name.name, | ||
| 186 | offset, origin); | ||
| 187 | |||
| 174 | /* origin == SEEK_END => we must revalidate the cached file length */ | 188 | /* origin == SEEK_END => we must revalidate the cached file length */ |
| 175 | if (origin == SEEK_END) { | 189 | if (origin == SEEK_END) { |
| 176 | struct inode *inode = filp->f_mapping->host; | 190 | struct inode *inode = filp->f_mapping->host; |
| @@ -185,7 +199,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) | |||
| 185 | } | 199 | } |
| 186 | 200 | ||
| 187 | /* | 201 | /* |
| 188 | * Helper for nfs_file_flush() and nfs_fsync() | 202 | * Helper for nfs_file_flush() and nfs_file_fsync() |
| 189 | * | 203 | * |
| 190 | * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to | 204 | * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to |
| 191 | * disk, but it retrieves and clears ctx->error after synching, despite | 205 | * disk, but it retrieves and clears ctx->error after synching, despite |
| @@ -211,16 +225,18 @@ static int nfs_do_fsync(struct nfs_open_context *ctx, struct inode *inode) | |||
| 211 | 225 | ||
| 212 | /* | 226 | /* |
| 213 | * Flush all dirty pages, and check for write errors. | 227 | * Flush all dirty pages, and check for write errors. |
| 214 | * | ||
| 215 | */ | 228 | */ |
| 216 | static int | 229 | static int |
| 217 | nfs_file_flush(struct file *file, fl_owner_t id) | 230 | nfs_file_flush(struct file *file, fl_owner_t id) |
| 218 | { | 231 | { |
| 219 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 232 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
| 220 | struct inode *inode = file->f_path.dentry->d_inode; | 233 | struct dentry *dentry = file->f_path.dentry; |
| 234 | struct inode *inode = dentry->d_inode; | ||
| 221 | int status; | 235 | int status; |
| 222 | 236 | ||
| 223 | dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); | 237 | dprintk("NFS: flush(%s/%s)\n", |
| 238 | dentry->d_parent->d_name.name, | ||
| 239 | dentry->d_name.name); | ||
| 224 | 240 | ||
| 225 | if ((file->f_mode & FMODE_WRITE) == 0) | 241 | if ((file->f_mode & FMODE_WRITE) == 0) |
| 226 | return 0; | 242 | return 0; |
| @@ -245,7 +261,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 245 | if (iocb->ki_filp->f_flags & O_DIRECT) | 261 | if (iocb->ki_filp->f_flags & O_DIRECT) |
| 246 | return nfs_file_direct_read(iocb, iov, nr_segs, pos); | 262 | return nfs_file_direct_read(iocb, iov, nr_segs, pos); |
| 247 | 263 | ||
| 248 | dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", | 264 | dprintk("NFS: read(%s/%s, %lu@%lu)\n", |
| 249 | dentry->d_parent->d_name.name, dentry->d_name.name, | 265 | dentry->d_parent->d_name.name, dentry->d_name.name, |
| 250 | (unsigned long) count, (unsigned long) pos); | 266 | (unsigned long) count, (unsigned long) pos); |
| 251 | 267 | ||
| @@ -265,7 +281,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos, | |||
| 265 | struct inode *inode = dentry->d_inode; | 281 | struct inode *inode = dentry->d_inode; |
| 266 | ssize_t res; | 282 | ssize_t res; |
| 267 | 283 | ||
| 268 | dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n", | 284 | dprintk("NFS: splice_read(%s/%s, %lu@%Lu)\n", |
| 269 | dentry->d_parent->d_name.name, dentry->d_name.name, | 285 | dentry->d_parent->d_name.name, dentry->d_name.name, |
| 270 | (unsigned long) count, (unsigned long long) *ppos); | 286 | (unsigned long) count, (unsigned long long) *ppos); |
| 271 | 287 | ||
| @@ -282,7 +298,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | |||
| 282 | struct inode *inode = dentry->d_inode; | 298 | struct inode *inode = dentry->d_inode; |
| 283 | int status; | 299 | int status; |
| 284 | 300 | ||
| 285 | dfprintk(VFS, "nfs: mmap(%s/%s)\n", | 301 | dprintk("NFS: mmap(%s/%s)\n", |
| 286 | dentry->d_parent->d_name.name, dentry->d_name.name); | 302 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 287 | 303 | ||
| 288 | status = nfs_revalidate_mapping(inode, file->f_mapping); | 304 | status = nfs_revalidate_mapping(inode, file->f_mapping); |
| @@ -300,12 +316,14 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | |||
| 300 | * whether any write errors occurred for this process. | 316 | * whether any write errors occurred for this process. |
| 301 | */ | 317 | */ |
| 302 | static int | 318 | static int |
| 303 | nfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 319 | nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) |
| 304 | { | 320 | { |
| 305 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 321 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
| 306 | struct inode *inode = dentry->d_inode; | 322 | struct inode *inode = dentry->d_inode; |
| 307 | 323 | ||
| 308 | dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); | 324 | dprintk("NFS: fsync file(%s/%s) datasync %d\n", |
| 325 | dentry->d_parent->d_name.name, dentry->d_name.name, | ||
| 326 | datasync); | ||
| 309 | 327 | ||
| 310 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); | 328 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); |
| 311 | return nfs_do_fsync(ctx, inode); | 329 | return nfs_do_fsync(ctx, inode); |
| @@ -328,6 +346,11 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping, | |||
| 328 | struct page *page; | 346 | struct page *page; |
| 329 | index = pos >> PAGE_CACHE_SHIFT; | 347 | index = pos >> PAGE_CACHE_SHIFT; |
| 330 | 348 | ||
| 349 | dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n", | ||
| 350 | file->f_path.dentry->d_parent->d_name.name, | ||
| 351 | file->f_path.dentry->d_name.name, | ||
| 352 | mapping->host->i_ino, len, (long long) pos); | ||
| 353 | |||
| 331 | page = __grab_cache_page(mapping, index); | 354 | page = __grab_cache_page(mapping, index); |
| 332 | if (!page) | 355 | if (!page) |
| 333 | return -ENOMEM; | 356 | return -ENOMEM; |
| @@ -348,9 +371,32 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, | |||
| 348 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); | 371 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); |
| 349 | int status; | 372 | int status; |
| 350 | 373 | ||
| 351 | lock_kernel(); | 374 | dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n", |
| 375 | file->f_path.dentry->d_parent->d_name.name, | ||
| 376 | file->f_path.dentry->d_name.name, | ||
| 377 | mapping->host->i_ino, len, (long long) pos); | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Zero any uninitialised parts of the page, and then mark the page | ||
| 381 | * as up to date if it turns out that we're extending the file. | ||
| 382 | */ | ||
| 383 | if (!PageUptodate(page)) { | ||
| 384 | unsigned pglen = nfs_page_length(page); | ||
| 385 | unsigned end = offset + len; | ||
| 386 | |||
| 387 | if (pglen == 0) { | ||
| 388 | zero_user_segments(page, 0, offset, | ||
| 389 | end, PAGE_CACHE_SIZE); | ||
| 390 | SetPageUptodate(page); | ||
| 391 | } else if (end >= pglen) { | ||
| 392 | zero_user_segment(page, end, PAGE_CACHE_SIZE); | ||
| 393 | if (offset == 0) | ||
| 394 | SetPageUptodate(page); | ||
| 395 | } else | ||
| 396 | zero_user_segment(page, pglen, PAGE_CACHE_SIZE); | ||
| 397 | } | ||
| 398 | |||
| 352 | status = nfs_updatepage(file, page, offset, copied); | 399 | status = nfs_updatepage(file, page, offset, copied); |
| 353 | unlock_kernel(); | ||
| 354 | 400 | ||
| 355 | unlock_page(page); | 401 | unlock_page(page); |
| 356 | page_cache_release(page); | 402 | page_cache_release(page); |
| @@ -362,6 +408,8 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, | |||
| 362 | 408 | ||
| 363 | static void nfs_invalidate_page(struct page *page, unsigned long offset) | 409 | static void nfs_invalidate_page(struct page *page, unsigned long offset) |
| 364 | { | 410 | { |
| 411 | dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset); | ||
| 412 | |||
| 365 | if (offset != 0) | 413 | if (offset != 0) |
| 366 | return; | 414 | return; |
| 367 | /* Cancel any unstarted writes on this page */ | 415 | /* Cancel any unstarted writes on this page */ |
| @@ -370,13 +418,20 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset) | |||
| 370 | 418 | ||
| 371 | static int nfs_release_page(struct page *page, gfp_t gfp) | 419 | static int nfs_release_page(struct page *page, gfp_t gfp) |
| 372 | { | 420 | { |
| 421 | dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); | ||
| 422 | |||
| 373 | /* If PagePrivate() is set, then the page is not freeable */ | 423 | /* If PagePrivate() is set, then the page is not freeable */ |
| 374 | return 0; | 424 | return 0; |
| 375 | } | 425 | } |
| 376 | 426 | ||
| 377 | static int nfs_launder_page(struct page *page) | 427 | static int nfs_launder_page(struct page *page) |
| 378 | { | 428 | { |
| 379 | return nfs_wb_page(page->mapping->host, page); | 429 | struct inode *inode = page->mapping->host; |
| 430 | |||
| 431 | dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n", | ||
| 432 | inode->i_ino, (long long)page_offset(page)); | ||
| 433 | |||
| 434 | return nfs_wb_page(inode, page); | ||
| 380 | } | 435 | } |
| 381 | 436 | ||
| 382 | const struct address_space_operations nfs_file_aops = { | 437 | const struct address_space_operations nfs_file_aops = { |
| @@ -396,13 +451,19 @@ const struct address_space_operations nfs_file_aops = { | |||
| 396 | static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | 451 | static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) |
| 397 | { | 452 | { |
| 398 | struct file *filp = vma->vm_file; | 453 | struct file *filp = vma->vm_file; |
| 454 | struct dentry *dentry = filp->f_path.dentry; | ||
| 399 | unsigned pagelen; | 455 | unsigned pagelen; |
| 400 | int ret = -EINVAL; | 456 | int ret = -EINVAL; |
| 401 | struct address_space *mapping; | 457 | struct address_space *mapping; |
| 402 | 458 | ||
| 459 | dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", | ||
| 460 | dentry->d_parent->d_name.name, dentry->d_name.name, | ||
| 461 | filp->f_mapping->host->i_ino, | ||
| 462 | (long long)page_offset(page)); | ||
| 463 | |||
| 403 | lock_page(page); | 464 | lock_page(page); |
| 404 | mapping = page->mapping; | 465 | mapping = page->mapping; |
| 405 | if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) | 466 | if (mapping != dentry->d_inode->i_mapping) |
| 406 | goto out_unlock; | 467 | goto out_unlock; |
| 407 | 468 | ||
| 408 | ret = 0; | 469 | ret = 0; |
| @@ -450,9 +511,9 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 450 | if (iocb->ki_filp->f_flags & O_DIRECT) | 511 | if (iocb->ki_filp->f_flags & O_DIRECT) |
| 451 | return nfs_file_direct_write(iocb, iov, nr_segs, pos); | 512 | return nfs_file_direct_write(iocb, iov, nr_segs, pos); |
| 452 | 513 | ||
| 453 | dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n", | 514 | dprintk("NFS: write(%s/%s, %lu@%Ld)\n", |
| 454 | dentry->d_parent->d_name.name, dentry->d_name.name, | 515 | dentry->d_parent->d_name.name, dentry->d_name.name, |
| 455 | inode->i_ino, (unsigned long) count, (long long) pos); | 516 | (unsigned long) count, (long long) pos); |
| 456 | 517 | ||
| 457 | result = -EBUSY; | 518 | result = -EBUSY; |
| 458 | if (IS_SWAPFILE(inode)) | 519 | if (IS_SWAPFILE(inode)) |
| @@ -586,7 +647,8 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | |||
| 586 | * This makes locking act as a cache coherency point. | 647 | * This makes locking act as a cache coherency point. |
| 587 | */ | 648 | */ |
| 588 | nfs_sync_mapping(filp->f_mapping); | 649 | nfs_sync_mapping(filp->f_mapping); |
| 589 | nfs_zap_caches(inode); | 650 | if (!nfs_have_delegation(inode, FMODE_READ)) |
| 651 | nfs_zap_caches(inode); | ||
| 590 | out: | 652 | out: |
| 591 | return status; | 653 | return status; |
| 592 | } | 654 | } |
| @@ -596,23 +658,35 @@ out: | |||
| 596 | */ | 658 | */ |
| 597 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | 659 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) |
| 598 | { | 660 | { |
| 599 | struct inode * inode = filp->f_mapping->host; | 661 | struct inode *inode = filp->f_mapping->host; |
| 662 | int ret = -ENOLCK; | ||
| 600 | 663 | ||
| 601 | dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", | 664 | dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n", |
| 602 | inode->i_sb->s_id, inode->i_ino, | 665 | filp->f_path.dentry->d_parent->d_name.name, |
| 666 | filp->f_path.dentry->d_name.name, | ||
| 603 | fl->fl_type, fl->fl_flags, | 667 | fl->fl_type, fl->fl_flags, |
| 604 | (long long)fl->fl_start, (long long)fl->fl_end); | 668 | (long long)fl->fl_start, (long long)fl->fl_end); |
| 669 | |||
| 605 | nfs_inc_stats(inode, NFSIOS_VFSLOCK); | 670 | nfs_inc_stats(inode, NFSIOS_VFSLOCK); |
| 606 | 671 | ||
| 607 | /* No mandatory locks over NFS */ | 672 | /* No mandatory locks over NFS */ |
| 608 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) | 673 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) |
| 609 | return -ENOLCK; | 674 | goto out_err; |
| 675 | |||
| 676 | if (NFS_PROTO(inode)->lock_check_bounds != NULL) { | ||
| 677 | ret = NFS_PROTO(inode)->lock_check_bounds(fl); | ||
| 678 | if (ret < 0) | ||
| 679 | goto out_err; | ||
| 680 | } | ||
| 610 | 681 | ||
| 611 | if (IS_GETLK(cmd)) | 682 | if (IS_GETLK(cmd)) |
| 612 | return do_getlk(filp, cmd, fl); | 683 | ret = do_getlk(filp, cmd, fl); |
| 613 | if (fl->fl_type == F_UNLCK) | 684 | else if (fl->fl_type == F_UNLCK) |
| 614 | return do_unlk(filp, cmd, fl); | 685 | ret = do_unlk(filp, cmd, fl); |
| 615 | return do_setlk(filp, cmd, fl); | 686 | else |
| 687 | ret = do_setlk(filp, cmd, fl); | ||
| 688 | out_err: | ||
| 689 | return ret; | ||
| 616 | } | 690 | } |
| 617 | 691 | ||
| 618 | /* | 692 | /* |
| @@ -620,9 +694,9 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
| 620 | */ | 694 | */ |
| 621 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | 695 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) |
| 622 | { | 696 | { |
| 623 | dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", | 697 | dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n", |
| 624 | filp->f_path.dentry->d_inode->i_sb->s_id, | 698 | filp->f_path.dentry->d_parent->d_name.name, |
| 625 | filp->f_path.dentry->d_inode->i_ino, | 699 | filp->f_path.dentry->d_name.name, |
| 626 | fl->fl_type, fl->fl_flags); | 700 | fl->fl_type, fl->fl_flags); |
| 627 | 701 | ||
| 628 | /* | 702 | /* |
| @@ -645,12 +719,15 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | |||
| 645 | return do_setlk(filp, cmd, fl); | 719 | return do_setlk(filp, cmd, fl); |
| 646 | } | 720 | } |
| 647 | 721 | ||
| 722 | /* | ||
| 723 | * There is no protocol support for leases, so we have no way to implement | ||
| 724 | * them correctly in the face of opens by other clients. | ||
| 725 | */ | ||
| 648 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) | 726 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) |
| 649 | { | 727 | { |
| 650 | /* | 728 | dprintk("NFS: setlease(%s/%s, arg=%ld)\n", |
| 651 | * There is no protocol support for leases, so we have no way | 729 | file->f_path.dentry->d_parent->d_name.name, |
| 652 | * to implement them correctly in the face of opens by other | 730 | file->f_path.dentry->d_name.name, arg); |
| 653 | * clients. | 731 | |
| 654 | */ | ||
| 655 | return -EINVAL; | 732 | return -EINVAL; |
| 656 | } | 733 | } |
