~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to fs/dlm/plock.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
        wake_up(&send_wq);
72
72
}
73
73
 
 
74
/* If a process was killed while waiting for the only plock on a file,
 
75
   locks_remove_posix will not see any lock on the file so it won't
 
76
   send an unlock-close to us to pass on to userspace to clean up the
 
77
   abandoned waiter.  So, we have to insert the unlock-close when the
 
78
   lock call is interrupted. */
 
79
 
 
80
static void do_unlock_close(struct dlm_ls *ls, u64 number,
 
81
                            struct file *file, struct file_lock *fl)
 
82
{
 
83
        struct plock_op *op;
 
84
 
 
85
        op = kzalloc(sizeof(*op), GFP_NOFS);
 
86
        if (!op)
 
87
                return;
 
88
 
 
89
        op->info.optype         = DLM_PLOCK_OP_UNLOCK;
 
90
        op->info.pid            = fl->fl_pid;
 
91
        op->info.fsid           = ls->ls_global_id;
 
92
        op->info.number         = number;
 
93
        op->info.start          = 0;
 
94
        op->info.end            = OFFSET_MAX;
 
95
        if (fl->fl_lmops && fl->fl_lmops->fl_grant)
 
96
                op->info.owner  = (__u64) fl->fl_pid;
 
97
        else
 
98
                op->info.owner  = (__u64)(long) fl->fl_owner;
 
99
 
 
100
        op->info.flags |= DLM_PLOCK_FL_CLOSE;
 
101
        send_op(op);
 
102
}
 
103
 
74
104
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
75
105
                   int cmd, struct file_lock *fl)
76
106
{
114
144
 
115
145
        send_op(op);
116
146
 
117
 
        if (xop->callback == NULL)
118
 
                wait_event(recv_wq, (op->done != 0));
119
 
        else {
 
147
        if (xop->callback == NULL) {
 
148
                rv = wait_event_killable(recv_wq, (op->done != 0));
 
149
                if (rv == -ERESTARTSYS) {
 
150
                        log_debug(ls, "dlm_posix_lock: wait killed %llx",
 
151
                                  (unsigned long long)number);
 
152
                        spin_lock(&ops_lock);
 
153
                        list_del(&op->list);
 
154
                        spin_unlock(&ops_lock);
 
155
                        kfree(xop);
 
156
                        do_unlock_close(ls, number, file, fl);
 
157
                        goto out;
 
158
                }
 
159
        } else {
120
160
                rv = FILE_LOCK_DEFERRED;
121
161
                goto out;
122
162
        }
233
273
        else
234
274
                op->info.owner  = (__u64)(long) fl->fl_owner;
235
275
 
 
276
        if (fl->fl_flags & FL_CLOSE) {
 
277
                op->info.flags |= DLM_PLOCK_FL_CLOSE;
 
278
                send_op(op);
 
279
                rv = 0;
 
280
                goto out;
 
281
        }
 
282
 
236
283
        send_op(op);
237
284
        wait_event(recv_wq, (op->done != 0));
238
285
 
334
381
        spin_lock(&ops_lock);
335
382
        if (!list_empty(&send_list)) {
336
383
                op = list_entry(send_list.next, struct plock_op, list);
337
 
                list_move(&op->list, &recv_list);
 
384
                if (op->info.flags & DLM_PLOCK_FL_CLOSE)
 
385
                        list_del(&op->list);
 
386
                else
 
387
                        list_move(&op->list, &recv_list);
338
388
                memcpy(&info, &op->info, sizeof(info));
339
389
        }
340
390
        spin_unlock(&ops_lock);
342
392
        if (!op)
343
393
                return -EAGAIN;
344
394
 
 
395
        /* there is no need to get a reply from userspace for unlocks
 
396
           that were generated by the vfs cleaning up for a close
 
397
           (the process did not make an unlock call). */
 
398
 
 
399
        if (op->info.flags & DLM_PLOCK_FL_CLOSE)
 
400
                kfree(op);
 
401
 
345
402
        if (copy_to_user(u, &info, sizeof(info)))
346
403
                return -EFAULT;
347
404
        return sizeof(info);