31
31
#include <linux/lockd/nlm.h>
32
32
#include <linux/lockd/lockd.h>
33
33
#include <linux/kthread.h>
34
+ #include <linux/exportfs.h>
34
35
35
36
#define NLMDBG_FACILITY NLMDBG_SVCLOCK
36
37
@@ -395,28 +396,10 @@ nlmsvc_release_lockowner(struct nlm_lock *lock)
395
396
nlmsvc_put_lockowner (lock -> fl .fl_owner );
396
397
}
397
398
398
- static void nlmsvc_locks_copy_lock (struct file_lock * new , struct file_lock * fl )
399
- {
400
- struct nlm_lockowner * nlm_lo = (struct nlm_lockowner * )fl -> fl_owner ;
401
- new -> fl_owner = nlmsvc_get_lockowner (nlm_lo );
402
- }
403
-
404
- static void nlmsvc_locks_release_private (struct file_lock * fl )
405
- {
406
- nlmsvc_put_lockowner ((struct nlm_lockowner * )fl -> fl_owner );
407
- }
408
-
409
- static const struct file_lock_operations nlmsvc_lock_ops = {
410
- .fl_copy_lock = nlmsvc_locks_copy_lock ,
411
- .fl_release_private = nlmsvc_locks_release_private ,
412
- };
413
-
414
399
void nlmsvc_locks_init_private (struct file_lock * fl , struct nlm_host * host ,
415
400
pid_t pid )
416
401
{
417
402
fl -> fl_owner = nlmsvc_find_lockowner (host , pid );
418
- if (fl -> fl_owner != NULL )
419
- fl -> fl_ops = & nlmsvc_lock_ops ;
420
403
}
421
404
422
405
/*
@@ -488,17 +471,24 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
488
471
struct nlm_cookie * cookie , int reclaim )
489
472
{
490
473
struct nlm_block * block = NULL ;
474
+ struct inode * inode = nlmsvc_file_inode (file );
491
475
int error ;
476
+ int mode ;
477
+ int async_block = 0 ;
492
478
__be32 ret ;
493
479
494
480
dprintk ("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n" ,
495
- locks_inode (file -> f_file )-> i_sb -> s_id ,
496
- locks_inode (file -> f_file )-> i_ino ,
481
+ inode -> i_sb -> s_id , inode -> i_ino ,
497
482
lock -> fl .fl_type , lock -> fl .fl_pid ,
498
483
(long long )lock -> fl .fl_start ,
499
484
(long long )lock -> fl .fl_end ,
500
485
wait );
501
486
487
+ if (inode -> i_sb -> s_export_op -> flags & EXPORT_OP_SYNC_LOCKS ) {
488
+ async_block = wait ;
489
+ wait = 0 ;
490
+ }
491
+
502
492
/* Lock file against concurrent access */
503
493
mutex_lock (& file -> f_mutex );
504
494
/* Get existing block (in case client is busy-waiting)
@@ -542,7 +532,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
542
532
543
533
if (!wait )
544
534
lock -> fl .fl_flags &= ~FL_SLEEP ;
545
- error = vfs_lock_file (file -> f_file , F_SETLK , & lock -> fl , NULL );
535
+ mode = lock_to_openmode (& lock -> fl );
536
+ error = vfs_lock_file (file -> f_file [mode ], F_SETLK , & lock -> fl , NULL );
546
537
lock -> fl .fl_flags &= ~FL_SLEEP ;
547
538
548
539
dprintk ("lockd: vfs_lock_file returned %d\n" , error );
@@ -558,7 +549,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
558
549
*/
559
550
if (wait )
560
551
break ;
561
- ret = nlm_lck_denied ;
552
+ ret = async_block ? nlm_lck_blocked : nlm_lck_denied ;
562
553
goto out ;
563
554
case FILE_LOCK_DEFERRED :
564
555
if (wait )
@@ -595,12 +586,13 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
595
586
struct nlm_lock * conflock , struct nlm_cookie * cookie )
596
587
{
597
588
int error ;
589
+ int mode ;
598
590
__be32 ret ;
599
591
struct nlm_lockowner * test_owner ;
600
592
601
593
dprintk ("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n" ,
602
- locks_inode (file -> f_file )-> i_sb -> s_id ,
603
- locks_inode (file -> f_file )-> i_ino ,
594
+ nlmsvc_file_inode (file )-> i_sb -> s_id ,
595
+ nlmsvc_file_inode (file )-> i_ino ,
604
596
lock -> fl .fl_type ,
605
597
(long long )lock -> fl .fl_start ,
606
598
(long long )lock -> fl .fl_end );
@@ -613,7 +605,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
613
605
/* If there's a conflicting lock, remember to clean up the test lock */
614
606
test_owner = (struct nlm_lockowner * )lock -> fl .fl_owner ;
615
607
616
- error = vfs_test_lock (file -> f_file , & lock -> fl );
608
+ mode = lock_to_openmode (& lock -> fl );
609
+ error = vfs_test_lock (file -> f_file [mode ], & lock -> fl );
617
610
if (error ) {
618
611
/* We can't currently deal with deferred test requests */
619
612
if (error == FILE_LOCK_DEFERRED )
@@ -634,7 +627,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
634
627
conflock -> caller = "somehost" ; /* FIXME */
635
628
conflock -> len = strlen (conflock -> caller );
636
629
conflock -> oh .len = 0 ; /* don't return OH info */
637
- conflock -> svid = (( struct nlm_lockowner * ) lock -> fl .fl_owner ) -> pid ;
630
+ conflock -> svid = lock -> fl .fl_pid ;
638
631
conflock -> fl .fl_type = lock -> fl .fl_type ;
639
632
conflock -> fl .fl_start = lock -> fl .fl_start ;
640
633
conflock -> fl .fl_end = lock -> fl .fl_end ;
@@ -659,11 +652,11 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
659
652
__be32
660
653
nlmsvc_unlock (struct net * net , struct nlm_file * file , struct nlm_lock * lock )
661
654
{
662
- int error ;
655
+ int error = 0 ;
663
656
664
657
dprintk ("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n" ,
665
- locks_inode (file -> f_file )-> i_sb -> s_id ,
666
- locks_inode (file -> f_file )-> i_ino ,
658
+ nlmsvc_file_inode (file )-> i_sb -> s_id ,
659
+ nlmsvc_file_inode (file )-> i_ino ,
667
660
lock -> fl .fl_pid ,
668
661
(long long )lock -> fl .fl_start ,
669
662
(long long )lock -> fl .fl_end );
@@ -672,7 +665,12 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
672
665
nlmsvc_cancel_blocked (net , file , lock );
673
666
674
667
lock -> fl .fl_type = F_UNLCK ;
675
- error = vfs_lock_file (file -> f_file , F_SETLK , & lock -> fl , NULL );
668
+ if (file -> f_file [O_RDONLY ])
669
+ error = vfs_lock_file (file -> f_file [O_RDONLY ], F_SETLK ,
670
+ & lock -> fl , NULL );
671
+ if (file -> f_file [O_WRONLY ])
672
+ error = vfs_lock_file (file -> f_file [O_WRONLY ], F_SETLK ,
673
+ & lock -> fl , NULL );
676
674
677
675
return (error < 0 )? nlm_lck_denied_nolocks : nlm_granted ;
678
676
}
@@ -689,10 +687,11 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
689
687
{
690
688
struct nlm_block * block ;
691
689
int status = 0 ;
690
+ int mode ;
692
691
693
692
dprintk ("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n" ,
694
- locks_inode (file -> f_file )-> i_sb -> s_id ,
695
- locks_inode (file -> f_file )-> i_ino ,
693
+ nlmsvc_file_inode (file )-> i_sb -> s_id ,
694
+ nlmsvc_file_inode (file )-> i_ino ,
696
695
lock -> fl .fl_pid ,
697
696
(long long )lock -> fl .fl_start ,
698
697
(long long )lock -> fl .fl_end );
@@ -704,7 +703,8 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
704
703
block = nlmsvc_lookup_block (file , lock );
705
704
mutex_unlock (& file -> f_mutex );
706
705
if (block != NULL ) {
707
- vfs_cancel_lock (block -> b_file -> f_file ,
706
+ mode = lock_to_openmode (& lock -> fl );
707
+ vfs_cancel_lock (block -> b_file -> f_file [mode ],
708
708
& block -> b_call -> a_args .lock .fl );
709
709
status = nlmsvc_unlink_block (block );
710
710
nlmsvc_release_block (block );
@@ -788,9 +788,21 @@ nlmsvc_notify_blocked(struct file_lock *fl)
788
788
printk (KERN_WARNING "lockd: notification for unknown block!\n" );
789
789
}
790
790
791
+ static fl_owner_t nlmsvc_get_owner (fl_owner_t owner )
792
+ {
793
+ return nlmsvc_get_lockowner (owner );
794
+ }
795
+
796
+ static void nlmsvc_put_owner (fl_owner_t owner )
797
+ {
798
+ nlmsvc_put_lockowner (owner );
799
+ }
800
+
791
801
const struct lock_manager_operations nlmsvc_lock_operations = {
792
802
.lm_notify = nlmsvc_notify_blocked ,
793
803
.lm_grant = nlmsvc_grant_deferred ,
804
+ .lm_get_owner = nlmsvc_get_owner ,
805
+ .lm_put_owner = nlmsvc_put_owner ,
794
806
};
795
807
796
808
/*
@@ -809,6 +821,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
809
821
{
810
822
struct nlm_file * file = block -> b_file ;
811
823
struct nlm_lock * lock = & block -> b_call -> a_args .lock ;
824
+ int mode ;
812
825
int error ;
813
826
loff_t fl_start , fl_end ;
814
827
@@ -834,7 +847,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
834
847
lock -> fl .fl_flags |= FL_SLEEP ;
835
848
fl_start = lock -> fl .fl_start ;
836
849
fl_end = lock -> fl .fl_end ;
837
- error = vfs_lock_file (file -> f_file , F_SETLK , & lock -> fl , NULL );
850
+ mode = lock_to_openmode (& lock -> fl );
851
+ error = vfs_lock_file (file -> f_file [mode ], F_SETLK , & lock -> fl , NULL );
838
852
lock -> fl .fl_flags &= ~FL_SLEEP ;
839
853
lock -> fl .fl_start = fl_start ;
840
854
lock -> fl .fl_end = fl_end ;
0 commit comments