From 0c59ebfc9b811c60fcf808a5de33320eeeb394af Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sun, 10 Sep 2006 20:53:36 +0000 Subject: ulockmgr --- kernel/file.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'kernel/file.c') diff --git a/kernel/file.c b/kernel/file.c index 61eba56..e3a42c0 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -867,9 +867,32 @@ static int fuse_setlk(struct file *file, struct file_lock *fl) /* Unlock on close is handled by the flush method */ if (fl->fl_flags & FL_CLOSE) return 0; -#endif req = fuse_get_req(fc); +#else + /* If it's (possibly) unlock on close, don't fail the allocation */ + if (fl->fl_type == F_UNLCK && fl->fl_start == 0 && + fl->fl_end == OFFSET_MAX) + req = fuse_get_req_nofail(fc, file); + else { + /* Hack: add dummy lock, otherwise unlock on close is + optimized away */ + struct file_lock **flp; + for (flp = &inode->i_flock; + *flp && !((*flp)->fl_flags & FL_POSIX); + flp = &(*flp)->fl_next); + if (!*flp) { + struct file_lock *dummy = + kmalloc(sizeof(struct file_lock), GFP_KERNEL); + if (!dummy) + return -ENOLCK; + locks_init_lock(dummy); + dummy->fl_flags |= FL_POSIX; + *flp = dummy; + } + req = fuse_get_req(fc); + } +#endif if (IS_ERR(req)) return PTR_ERR(req); -- cgit v1.2.3