diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7a79fbe9f539..f1df2c8d9259 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 | ||
@@ -48,7 +49,7 @@ static int nfs_check_flags(int flags); | |||
48 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 49 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
49 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | 50 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); |
50 | 51 | ||
51 | struct file_operations nfs_file_operations = { | 52 | const struct file_operations nfs_file_operations = { |
52 | .llseek = nfs_file_llseek, | 53 | .llseek = nfs_file_llseek, |
53 | .read = do_sync_read, | 54 | .read = do_sync_read, |
54 | .write = do_sync_write, | 55 | .write = do_sync_write, |
@@ -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,16 @@ 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 void nfs_invalidate_page(struct page *page, unsigned long offset) | ||
322 | { | ||
323 | /* FIXME: we really should cancel any unstarted writes on this page */ | ||
324 | } | ||
325 | |||
326 | static int nfs_release_page(struct page *page, gfp_t gfp) | ||
327 | { | ||
328 | return !nfs_wb_page(page->mapping->host, page); | ||
329 | } | ||
330 | |||
319 | struct address_space_operations nfs_file_aops = { | 331 | struct address_space_operations nfs_file_aops = { |
320 | .readpage = nfs_readpage, | 332 | .readpage = nfs_readpage, |
321 | .readpages = nfs_readpages, | 333 | .readpages = nfs_readpages, |
@@ -324,6 +336,8 @@ struct address_space_operations nfs_file_aops = { | |||
324 | .writepages = nfs_writepages, | 336 | .writepages = nfs_writepages, |
325 | .prepare_write = nfs_prepare_write, | 337 | .prepare_write = nfs_prepare_write, |
326 | .commit_write = nfs_commit_write, | 338 | .commit_write = nfs_commit_write, |
339 | .invalidatepage = nfs_invalidate_page, | ||
340 | .releasepage = nfs_release_page, | ||
327 | #ifdef CONFIG_NFS_DIRECTIO | 341 | #ifdef CONFIG_NFS_DIRECTIO |
328 | .direct_IO = nfs_direct_IO, | 342 | .direct_IO = nfs_direct_IO, |
329 | #endif | 343 | #endif |
@@ -365,6 +379,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t | |||
365 | if (!count) | 379 | if (!count) |
366 | goto out; | 380 | goto out; |
367 | 381 | ||
382 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); | ||
368 | result = generic_file_aio_write(iocb, buf, count, pos); | 383 | result = generic_file_aio_write(iocb, buf, count, pos); |
369 | out: | 384 | out: |
370 | return result; | 385 | return result; |
@@ -376,15 +391,17 @@ out_swapfile: | |||
376 | 391 | ||
377 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) | 392 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) |
378 | { | 393 | { |
379 | struct file_lock *cfl; | 394 | struct file_lock cfl; |
380 | struct inode *inode = filp->f_mapping->host; | 395 | struct inode *inode = filp->f_mapping->host; |
381 | int status = 0; | 396 | int status = 0; |
382 | 397 | ||
383 | lock_kernel(); | 398 | lock_kernel(); |
384 | /* Try local locking first */ | 399 | /* Try local locking first */ |
385 | cfl = posix_test_lock(filp, fl); | 400 | if (posix_test_lock(filp, fl, &cfl)) { |
386 | if (cfl != NULL) { | 401 | fl->fl_start = cfl.fl_start; |
387 | locks_copy_lock(fl, cfl); | 402 | fl->fl_end = cfl.fl_end; |
403 | fl->fl_type = cfl.fl_type; | ||
404 | fl->fl_pid = cfl.fl_pid; | ||
388 | goto out; | 405 | goto out; |
389 | } | 406 | } |
390 | 407 | ||
@@ -425,10 +442,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) | 442 | static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) |
426 | { | 443 | { |
427 | struct inode *inode = filp->f_mapping->host; | 444 | struct inode *inode = filp->f_mapping->host; |
428 | sigset_t oldset; | ||
429 | int status; | 445 | int status; |
430 | 446 | ||
431 | rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); | ||
432 | /* | 447 | /* |
433 | * Flush all pending writes before doing anything | 448 | * Flush all pending writes before doing anything |
434 | * with locks.. | 449 | * with locks.. |
@@ -446,17 +461,14 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) | |||
446 | else | 461 | else |
447 | status = do_vfs_lock(filp, fl); | 462 | status = do_vfs_lock(filp, fl); |
448 | unlock_kernel(); | 463 | unlock_kernel(); |
449 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); | ||
450 | return status; | 464 | return status; |
451 | } | 465 | } |
452 | 466 | ||
453 | static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | 467 | static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) |
454 | { | 468 | { |
455 | struct inode *inode = filp->f_mapping->host; | 469 | struct inode *inode = filp->f_mapping->host; |
456 | sigset_t oldset; | ||
457 | int status; | 470 | int status; |
458 | 471 | ||
459 | rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); | ||
460 | /* | 472 | /* |
461 | * Flush all pending writes before doing anything | 473 | * Flush all pending writes before doing anything |
462 | * with locks.. | 474 | * with locks.. |
@@ -489,7 +501,6 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | |||
489 | nfs_sync_mapping(filp->f_mapping); | 501 | nfs_sync_mapping(filp->f_mapping); |
490 | nfs_zap_caches(inode); | 502 | nfs_zap_caches(inode); |
491 | out: | 503 | out: |
492 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); | ||
493 | return status; | 504 | return status; |
494 | } | 505 | } |
495 | 506 | ||
@@ -504,9 +515,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
504 | inode->i_sb->s_id, inode->i_ino, | 515 | inode->i_sb->s_id, inode->i_ino, |
505 | fl->fl_type, fl->fl_flags, | 516 | fl->fl_type, fl->fl_flags, |
506 | (long long)fl->fl_start, (long long)fl->fl_end); | 517 | (long long)fl->fl_start, (long long)fl->fl_end); |
507 | 518 | nfs_inc_stats(inode, NFSIOS_VFSLOCK); | |
508 | if (!inode) | ||
509 | return -EINVAL; | ||
510 | 519 | ||
511 | /* No mandatory locks over NFS */ | 520 | /* No mandatory locks over NFS */ |
512 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && | 521 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && |
@@ -531,9 +540,6 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | |||
531 | inode->i_sb->s_id, inode->i_ino, | 540 | inode->i_sb->s_id, inode->i_ino, |
532 | fl->fl_type, fl->fl_flags); | 541 | fl->fl_type, fl->fl_flags); |
533 | 542 | ||
534 | if (!inode) | ||
535 | return -EINVAL; | ||
536 | |||
537 | /* | 543 | /* |
538 | * No BSD flocks over NFS allowed. | 544 | * No BSD flocks over NFS allowed. |
539 | * Note: we could try to fake a POSIX lock request here by | 545 | * Note: we could try to fake a POSIX lock request here by |