diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7a79fbe9f539..5263b2864a44 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
33 | 33 | ||
34 | #include "delegation.h" | 34 | #include "delegation.h" |
35 | #include "iostat.h" | ||
35 | 36 | ||
36 | #define NFSDBG_FACILITY NFSDBG_FILE | 37 | #define NFSDBG_FACILITY NFSDBG_FILE |
37 | 38 | ||
@@ -102,18 +103,15 @@ static int nfs_check_flags(int flags) | |||
102 | static int | 103 | static int |
103 | nfs_file_open(struct inode *inode, struct file *filp) | 104 | nfs_file_open(struct inode *inode, struct file *filp) |
104 | { | 105 | { |
105 | struct nfs_server *server = NFS_SERVER(inode); | ||
106 | int (*open)(struct inode *, struct file *); | ||
107 | int res; | 106 | int res; |
108 | 107 | ||
109 | res = nfs_check_flags(filp->f_flags); | 108 | res = nfs_check_flags(filp->f_flags); |
110 | if (res) | 109 | if (res) |
111 | return res; | 110 | return res; |
112 | 111 | ||
112 | nfs_inc_stats(inode, NFSIOS_VFSOPEN); | ||
113 | lock_kernel(); | 113 | lock_kernel(); |
114 | /* Do NFSv4 open() call */ | 114 | res = NFS_SERVER(inode)->rpc_ops->file_open(inode, filp); |
115 | if ((open = server->rpc_ops->file_open) != NULL) | ||
116 | res = open(inode, filp); | ||
117 | unlock_kernel(); | 115 | unlock_kernel(); |
118 | return res; | 116 | return res; |
119 | } | 117 | } |
@@ -124,6 +122,7 @@ nfs_file_release(struct inode *inode, struct file *filp) | |||
124 | /* Ensure that dirty pages are flushed out with the right creds */ | 122 | /* Ensure that dirty pages are flushed out with the right creds */ |
125 | if (filp->f_mode & FMODE_WRITE) | 123 | if (filp->f_mode & FMODE_WRITE) |
126 | filemap_fdatawrite(filp->f_mapping); | 124 | filemap_fdatawrite(filp->f_mapping); |
125 | nfs_inc_stats(inode, NFSIOS_VFSRELEASE); | ||
127 | return NFS_PROTO(inode)->file_release(inode, filp); | 126 | return NFS_PROTO(inode)->file_release(inode, filp); |
128 | } | 127 | } |
129 | 128 | ||
@@ -199,6 +198,7 @@ nfs_file_flush(struct file *file) | |||
199 | 198 | ||
200 | if ((file->f_mode & FMODE_WRITE) == 0) | 199 | if ((file->f_mode & FMODE_WRITE) == 0) |
201 | return 0; | 200 | return 0; |
201 | nfs_inc_stats(inode, NFSIOS_VFSFLUSH); | ||
202 | lock_kernel(); | 202 | lock_kernel(); |
203 | /* Ensure that data+attribute caches are up to date after close() */ | 203 | /* Ensure that data+attribute caches are up to date after close() */ |
204 | status = nfs_wb_all(inode); | 204 | status = nfs_wb_all(inode); |
@@ -229,6 +229,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) | |||
229 | (unsigned long) count, (unsigned long) pos); | 229 | (unsigned long) count, (unsigned long) pos); |
230 | 230 | ||
231 | result = nfs_revalidate_file(inode, iocb->ki_filp); | 231 | result = nfs_revalidate_file(inode, iocb->ki_filp); |
232 | nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); | ||
232 | if (!result) | 233 | if (!result) |
233 | result = generic_file_aio_read(iocb, buf, count, pos); | 234 | result = generic_file_aio_read(iocb, buf, count, pos); |
234 | return result; | 235 | return result; |
@@ -282,6 +283,7 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
282 | 283 | ||
283 | dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); | 284 | dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); |
284 | 285 | ||
286 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); | ||
285 | lock_kernel(); | 287 | lock_kernel(); |
286 | status = nfs_wb_all(inode); | 288 | status = nfs_wb_all(inode); |
287 | if (!status) { | 289 | if (!status) { |
@@ -316,6 +318,17 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse | |||
316 | return status; | 318 | return status; |
317 | } | 319 | } |
318 | 320 | ||
321 | static int nfs_invalidate_page(struct page *page, unsigned long offset) | ||
322 | { | ||
323 | /* FIXME: we really should cancel any unstarted writes on this page */ | ||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | static int nfs_release_page(struct page *page, gfp_t gfp) | ||
328 | { | ||
329 | return !nfs_wb_page(page->mapping->host, page); | ||
330 | } | ||
331 | |||
319 | struct address_space_operations nfs_file_aops = { | 332 | struct address_space_operations nfs_file_aops = { |
320 | .readpage = nfs_readpage, | 333 | .readpage = nfs_readpage, |
321 | .readpages = nfs_readpages, | 334 | .readpages = nfs_readpages, |
@@ -324,6 +337,8 @@ struct address_space_operations nfs_file_aops = { | |||
324 | .writepages = nfs_writepages, | 337 | .writepages = nfs_writepages, |
325 | .prepare_write = nfs_prepare_write, | 338 | .prepare_write = nfs_prepare_write, |
326 | .commit_write = nfs_commit_write, | 339 | .commit_write = nfs_commit_write, |
340 | .invalidatepage = nfs_invalidate_page, | ||
341 | .releasepage = nfs_release_page, | ||
327 | #ifdef CONFIG_NFS_DIRECTIO | 342 | #ifdef CONFIG_NFS_DIRECTIO |
328 | .direct_IO = nfs_direct_IO, | 343 | .direct_IO = nfs_direct_IO, |
329 | #endif | 344 | #endif |
@@ -365,6 +380,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t | |||
365 | if (!count) | 380 | if (!count) |
366 | goto out; | 381 | goto out; |
367 | 382 | ||
383 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); | ||
368 | result = generic_file_aio_write(iocb, buf, count, pos); | 384 | result = generic_file_aio_write(iocb, buf, count, pos); |
369 | out: | 385 | out: |
370 | return result; | 386 | return result; |
@@ -376,15 +392,17 @@ out_swapfile: | |||
376 | 392 | ||
377 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) | 393 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) |
378 | { | 394 | { |
379 | struct file_lock *cfl; | 395 | struct file_lock cfl; |
380 | struct inode *inode = filp->f_mapping->host; | 396 | struct inode *inode = filp->f_mapping->host; |
381 | int status = 0; | 397 | int status = 0; |
382 | 398 | ||
383 | lock_kernel(); | 399 | lock_kernel(); |
384 | /* Try local locking first */ | 400 | /* Try local locking first */ |
385 | cfl = posix_test_lock(filp, fl); | 401 | if (posix_test_lock(filp, fl, &cfl)) { |
386 | if (cfl != NULL) { | 402 | fl->fl_start = cfl.fl_start; |
387 | locks_copy_lock(fl, cfl); | 403 | fl->fl_end = cfl.fl_end; |
404 | fl->fl_type = cfl.fl_type; | ||
405 | fl->fl_pid = cfl.fl_pid; | ||
388 | goto out; | 406 | goto out; |
389 | } | 407 | } |
390 | 408 | ||
@@ -425,10 +443,8 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) | |||
425 | static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) | 443 | static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) |
426 | { | 444 | { |
427 | struct inode *inode = filp->f_mapping->host; | 445 | struct inode *inode = filp->f_mapping->host; |
428 | sigset_t oldset; | ||
429 | int status; | 446 | int status; |
430 | 447 | ||
431 | rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); | ||
432 | /* | 448 | /* |
433 | * Flush all pending writes before doing anything | 449 | * Flush all pending writes before doing anything |
434 | * with locks.. | 450 | * with locks.. |
@@ -446,17 +462,14 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) | |||
446 | else | 462 | else |
447 | status = do_vfs_lock(filp, fl); | 463 | status = do_vfs_lock(filp, fl); |
448 | unlock_kernel(); | 464 | unlock_kernel(); |
449 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); | ||
450 | return status; | 465 | return status; |
451 | } | 466 | } |
452 | 467 | ||
453 | static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | 468 | static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) |
454 | { | 469 | { |
455 | struct inode *inode = filp->f_mapping->host; | 470 | struct inode *inode = filp->f_mapping->host; |
456 | sigset_t oldset; | ||
457 | int status; | 471 | int status; |
458 | 472 | ||
459 | rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); | ||
460 | /* | 473 | /* |
461 | * Flush all pending writes before doing anything | 474 | * Flush all pending writes before doing anything |
462 | * with locks.. | 475 | * with locks.. |
@@ -489,7 +502,6 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | |||
489 | nfs_sync_mapping(filp->f_mapping); | 502 | nfs_sync_mapping(filp->f_mapping); |
490 | nfs_zap_caches(inode); | 503 | nfs_zap_caches(inode); |
491 | out: | 504 | out: |
492 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); | ||
493 | return status; | 505 | return status; |
494 | } | 506 | } |
495 | 507 | ||
@@ -504,9 +516,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
504 | inode->i_sb->s_id, inode->i_ino, | 516 | inode->i_sb->s_id, inode->i_ino, |
505 | fl->fl_type, fl->fl_flags, | 517 | fl->fl_type, fl->fl_flags, |
506 | (long long)fl->fl_start, (long long)fl->fl_end); | 518 | (long long)fl->fl_start, (long long)fl->fl_end); |
507 | 519 | nfs_inc_stats(inode, NFSIOS_VFSLOCK); | |
508 | if (!inode) | ||
509 | return -EINVAL; | ||
510 | 520 | ||
511 | /* No mandatory locks over NFS */ | 521 | /* No mandatory locks over NFS */ |
512 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && | 522 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && |
@@ -531,9 +541,6 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | |||
531 | inode->i_sb->s_id, inode->i_ino, | 541 | inode->i_sb->s_id, inode->i_ino, |
532 | fl->fl_type, fl->fl_flags); | 542 | fl->fl_type, fl->fl_flags); |
533 | 543 | ||
534 | if (!inode) | ||
535 | return -EINVAL; | ||
536 | |||
537 | /* | 544 | /* |
538 | * No BSD flocks over NFS allowed. | 545 | * No BSD flocks over NFS allowed. |
539 | * Note: we could try to fake a POSIX lock request here by | 546 | * Note: we could try to fake a POSIX lock request here by |