@@ -25,6 +25,15 @@ struct plock_op {
2525 struct gdlm_plock_info info ;
2626};
2727
28+ struct plock_xop {
29+ struct plock_op xop ;
30+ void * callback ;
31+ void * fl ;
32+ void * file ;
33+ struct file_lock flc ;
34+ };
35+
36+
2837static inline void set_version (struct gdlm_plock_info * info )
2938{
3039 info -> version [0 ] = GDLM_PLOCK_VERSION_MAJOR ;
@@ -64,12 +73,14 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
6473{
6574 struct gdlm_ls * ls = lockspace ;
6675 struct plock_op * op ;
76+ struct plock_xop * xop ;
6777 int rv ;
6878
69- op = kzalloc (sizeof (* op ), GFP_KERNEL );
70- if (!op )
79+ xop = kzalloc (sizeof (* xop ), GFP_KERNEL );
80+ if (!xop )
7181 return - ENOMEM ;
7282
83+ op = & xop -> xop ;
7384 op -> info .optype = GDLM_PLOCK_OP_LOCK ;
7485 op -> info .pid = fl -> fl_pid ;
7586 op -> info .ex = (fl -> fl_type == F_WRLCK );
@@ -79,9 +90,21 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
7990 op -> info .start = fl -> fl_start ;
8091 op -> info .end = fl -> fl_end ;
8192 op -> info .owner = (__u64 )(long ) fl -> fl_owner ;
93+ if (fl -> fl_lmops && fl -> fl_lmops -> fl_grant ) {
94+ xop -> callback = fl -> fl_lmops -> fl_grant ;
95+ locks_init_lock (& xop -> flc );
96+ locks_copy_lock (& xop -> flc , fl );
97+ xop -> fl = fl ;
98+ xop -> file = file ;
99+ } else
100+ xop -> callback = NULL ;
82101
83102 send_op (op );
84- wait_event (recv_wq , (op -> done != 0 ));
103+
104+ if (xop -> callback == NULL )
105+ wait_event (recv_wq , (op -> done != 0 ));
106+ else
107+ return - EINPROGRESS ;
85108
86109 spin_lock (& ops_lock );
87110 if (!list_empty (& op -> list )) {
@@ -99,7 +122,63 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
99122 (unsigned long long )name -> ln_number );
100123 }
101124
102- kfree (op );
125+ kfree (xop );
126+ return rv ;
127+ }
128+
129+ /* Returns failure iff a succesful lock operation should be canceled */
130+ static int gdlm_plock_callback (struct plock_op * op )
131+ {
132+ struct file * file ;
133+ struct file_lock * fl ;
134+ struct file_lock * flc ;
135+ int (* notify )(void * , void * , int ) = NULL ;
136+ struct plock_xop * xop = (struct plock_xop * )op ;
137+ int rv = 0 ;
138+
139+ spin_lock (& ops_lock );
140+ if (!list_empty (& op -> list )) {
141+ printk (KERN_INFO "plock op on list\n" );
142+ list_del (& op -> list );
143+ }
144+ spin_unlock (& ops_lock );
145+
146+ /* check if the following 2 are still valid or make a copy */
147+ file = xop -> file ;
148+ flc = & xop -> flc ;
149+ fl = xop -> fl ;
150+ notify = xop -> callback ;
151+
152+ if (op -> info .rv ) {
153+ notify (flc , NULL , op -> info .rv );
154+ goto out ;
155+ }
156+
157+ /* got fs lock; bookkeep locally as well: */
158+ flc -> fl_flags &= ~FL_SLEEP ;
159+ if (posix_lock_file (file , flc , NULL )) {
160+ /*
161+ * This can only happen in the case of kmalloc() failure.
162+ * The filesystem's own lock is the authoritative lock,
163+ * so a failure to get the lock locally is not a disaster.
164+ * As long as GFS cannot reliably cancel locks (especially
165+ * in a low-memory situation), we're better off ignoring
166+ * this failure than trying to recover.
167+ */
168+ log_error ("gdlm_plock: vfs lock error file %p fl %p" ,
169+ file , fl );
170+ }
171+
172+ rv = notify (flc , NULL , 0 );
173+ if (rv ) {
174+ /* XXX: We need to cancel the fs lock here: */
175+ printk ("gfs2 lock granted after lock request failed;"
176+ " dangling lock!\n" );
177+ goto out ;
178+ }
179+
180+ out :
181+ kfree (xop );
103182 return rv ;
104183}
105184
@@ -138,6 +217,9 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
138217
139218 rv = op -> info .rv ;
140219
220+ if (rv == - ENOENT )
221+ rv = 0 ;
222+
141223 kfree (op );
142224 return rv ;
143225}
@@ -161,6 +243,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
161243 op -> info .start = fl -> fl_start ;
162244 op -> info .end = fl -> fl_end ;
163245
246+
164247 send_op (op );
165248 wait_event (recv_wq , (op -> done != 0 ));
166249
@@ -173,9 +256,10 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
173256
174257 rv = op -> info .rv ;
175258
176- if (rv == 0 )
177- fl -> fl_type = F_UNLCK ;
178- else if (rv > 0 ) {
259+ fl -> fl_type = F_UNLCK ;
260+ if (rv == - ENOENT )
261+ rv = 0 ;
262+ else if (rv == 0 && op -> info .pid != fl -> fl_pid ) {
179263 fl -> fl_type = (op -> info .ex ) ? F_WRLCK : F_RDLCK ;
180264 fl -> fl_pid = op -> info .pid ;
181265 fl -> fl_start = op -> info .start ;
@@ -243,9 +327,14 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
243327 }
244328 spin_unlock (& ops_lock );
245329
246- if (found )
247- wake_up (& recv_wq );
248- else
330+ if (found ) {
331+ struct plock_xop * xop ;
332+ xop = (struct plock_xop * )op ;
333+ if (xop -> callback )
334+ count = gdlm_plock_callback (op );
335+ else
336+ wake_up (& recv_wq );
337+ } else
249338 printk (KERN_INFO "gdlm dev_write no op %x %llx\n" , info .fsid ,
250339 (unsigned long long )info .number );
251340 return count ;
0 commit comments