summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch
new file mode 100644
index 00000000..150144c3
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0010-CIFS-Do-not-kmalloc-under-the-flocks-spinlock.patch
@@ -0,0 +1,140 @@
1From 6fc4721b47d58ae599a4bb37869d4bfd41f70511 Mon Sep 17 00:00:00 2001
2From: Pavel Shilovsky <piastry@etersoft.ru>
3Date: Mon, 5 Mar 2012 09:39:20 +0300
4Subject: [PATCH 10/42] CIFS: Do not kmalloc under the flocks spinlock
5
6commit d5751469f210d2149cc2159ffff66cbeef6da3f2 upstream.
7
8Reorganize the code to make the memory already allocated before
9spinlock'ed loop.
10
11Reviewed-by: Jeff Layton <jlayton@redhat.com>
12Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
13Signed-off-by: Steve French <sfrench@us.ibm.com>
14Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
15---
16 fs/cifs/file.c | 69 +++++++++++++++++++++++++++++++++++++++++++++-----------
17 1 file changed, 56 insertions(+), 13 deletions(-)
18
19diff --git a/fs/cifs/file.c b/fs/cifs/file.c
20index 4dd9283..5e64748 100644
21--- a/fs/cifs/file.c
22+++ b/fs/cifs/file.c
23@@ -920,16 +920,26 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
24 for (lockp = &inode->i_flock; *lockp != NULL; \
25 lockp = &(*lockp)->fl_next)
26
27+struct lock_to_push {
28+ struct list_head llist;
29+ __u64 offset;
30+ __u64 length;
31+ __u32 pid;
32+ __u16 netfid;
33+ __u8 type;
34+};
35+
36 static int
37 cifs_push_posix_locks(struct cifsFileInfo *cfile)
38 {
39 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
40 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
41 struct file_lock *flock, **before;
42- struct cifsLockInfo *lck, *tmp;
43+ unsigned int count = 0, i = 0;
44 int rc = 0, xid, type;
45+ struct list_head locks_to_send, *el;
46+ struct lock_to_push *lck, *tmp;
47 __u64 length;
48- struct list_head locks_to_send;
49
50 xid = GetXid();
51
52@@ -940,29 +950,55 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
53 return rc;
54 }
55
56+ lock_flocks();
57+ cifs_for_each_lock(cfile->dentry->d_inode, before) {
58+ if ((*before)->fl_flags & FL_POSIX)
59+ count++;
60+ }
61+ unlock_flocks();
62+
63 INIT_LIST_HEAD(&locks_to_send);
64
65+ /*
66+ * Allocating count locks is enough because no locks can be added to
67+ * the list while we are holding cinode->lock_mutex that protects
68+ * locking operations of this inode.
69+ */
70+ for (; i < count; i++) {
71+ lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
72+ if (!lck) {
73+ rc = -ENOMEM;
74+ goto err_out;
75+ }
76+ list_add_tail(&lck->llist, &locks_to_send);
77+ }
78+
79+ i = 0;
80+ el = locks_to_send.next;
81 lock_flocks();
82 cifs_for_each_lock(cfile->dentry->d_inode, before) {
83+ if (el == &locks_to_send) {
84+ /* something is really wrong */
85+ cERROR(1, "Can't push all brlocks!");
86+ break;
87+ }
88 flock = *before;
89+ if ((flock->fl_flags & FL_POSIX) == 0)
90+ continue;
91 length = 1 + flock->fl_end - flock->fl_start;
92 if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK)
93 type = CIFS_RDLCK;
94 else
95 type = CIFS_WRLCK;
96-
97- lck = cifs_lock_init(flock->fl_start, length, type,
98- cfile->netfid);
99- if (!lck) {
100- rc = -ENOMEM;
101- goto send_locks;
102- }
103+ lck = list_entry(el, struct lock_to_push, llist);
104 lck->pid = flock->fl_pid;
105-
106- list_add_tail(&lck->llist, &locks_to_send);
107+ lck->netfid = cfile->netfid;
108+ lck->length = length;
109+ lck->type = type;
110+ lck->offset = flock->fl_start;
111+ i++;
112+ el = el->next;
113 }
114-
115-send_locks:
116 unlock_flocks();
117
118 list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
119@@ -979,11 +1015,18 @@ send_locks:
120 kfree(lck);
121 }
122
123+out:
124 cinode->can_cache_brlcks = false;
125 mutex_unlock(&cinode->lock_mutex);
126
127 FreeXid(xid);
128 return rc;
129+err_out:
130+ list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
131+ list_del(&lck->llist);
132+ kfree(lck);
133+ }
134+ goto out;
135 }
136
137 static int
138--
1391.7.9.4
140