@@ -920,16 +920,26 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
920
920
for (lockp = &inode->i_flock; *lockp != NULL; \
921
921
lockp = &(*lockp)->fl_next)
922
922
923
+ struct lock_to_push {
924
+ struct list_head llist ;
925
+ __u64 offset ;
926
+ __u64 length ;
927
+ __u32 pid ;
928
+ __u16 netfid ;
929
+ __u8 type ;
930
+ };
931
+
923
932
static int
924
933
cifs_push_posix_locks (struct cifsFileInfo * cfile )
925
934
{
926
935
struct cifsInodeInfo * cinode = CIFS_I (cfile -> dentry -> d_inode );
927
936
struct cifs_tcon * tcon = tlink_tcon (cfile -> tlink );
928
937
struct file_lock * flock , * * before ;
929
- struct cifsLockInfo * lck , * tmp ;
938
+ unsigned int count = 0 , i = 0 ;
930
939
int rc = 0 , xid , type ;
940
+ struct list_head locks_to_send , * el ;
941
+ struct lock_to_push * lck , * tmp ;
931
942
__u64 length ;
932
- struct list_head locks_to_send ;
933
943
934
944
xid = GetXid ();
935
945
@@ -940,29 +950,55 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
940
950
return rc ;
941
951
}
942
952
953
+ lock_flocks ();
954
+ cifs_for_each_lock (cfile -> dentry -> d_inode , before ) {
955
+ if ((* before )-> fl_flags & FL_POSIX )
956
+ count ++ ;
957
+ }
958
+ unlock_flocks ();
959
+
943
960
INIT_LIST_HEAD (& locks_to_send );
944
961
962
+ /*
963
+ * Allocating count locks is enough because no locks can be added to
964
+ * the list while we are holding cinode->lock_mutex that protects
965
+ * locking operations of this inode.
966
+ */
967
+ for (; i < count ; i ++ ) {
968
+ lck = kmalloc (sizeof (struct lock_to_push ), GFP_KERNEL );
969
+ if (!lck ) {
970
+ rc = - ENOMEM ;
971
+ goto err_out ;
972
+ }
973
+ list_add_tail (& lck -> llist , & locks_to_send );
974
+ }
975
+
976
+ i = 0 ;
977
+ el = locks_to_send .next ;
945
978
lock_flocks ();
946
979
cifs_for_each_lock (cfile -> dentry -> d_inode , before ) {
980
+ if (el == & locks_to_send ) {
981
+ /* something is really wrong */
982
+ cERROR (1 , "Can't push all brlocks!" );
983
+ break ;
984
+ }
947
985
flock = * before ;
986
+ if ((flock -> fl_flags & FL_POSIX ) == 0 )
987
+ continue ;
948
988
length = 1 + flock -> fl_end - flock -> fl_start ;
949
989
if (flock -> fl_type == F_RDLCK || flock -> fl_type == F_SHLCK )
950
990
type = CIFS_RDLCK ;
951
991
else
952
992
type = CIFS_WRLCK ;
953
-
954
- lck = cifs_lock_init (flock -> fl_start , length , type ,
955
- cfile -> netfid );
956
- if (!lck ) {
957
- rc = - ENOMEM ;
958
- goto send_locks ;
959
- }
993
+ lck = list_entry (el , struct lock_to_push , llist );
960
994
lck -> pid = flock -> fl_pid ;
961
-
962
- list_add_tail (& lck -> llist , & locks_to_send );
995
+ lck -> netfid = cfile -> netfid ;
996
+ lck -> length = length ;
997
+ lck -> type = type ;
998
+ lck -> offset = flock -> fl_start ;
999
+ i ++ ;
1000
+ el = el -> next ;
963
1001
}
964
-
965
- send_locks :
966
1002
unlock_flocks ();
967
1003
968
1004
list_for_each_entry_safe (lck , tmp , & locks_to_send , llist ) {
@@ -979,11 +1015,18 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
979
1015
kfree (lck );
980
1016
}
981
1017
1018
+ out :
982
1019
cinode -> can_cache_brlcks = false;
983
1020
mutex_unlock (& cinode -> lock_mutex );
984
1021
985
1022
FreeXid (xid );
986
1023
return rc ;
1024
+ err_out :
1025
+ list_for_each_entry_safe (lck , tmp , & locks_to_send , llist ) {
1026
+ list_del (& lck -> llist );
1027
+ kfree (lck );
1028
+ }
1029
+ goto out ;
987
1030
}
988
1031
989
1032
static int
0 commit comments