aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKinglong Mee <kinglongmee@gmail.com>2014-08-22 10:18:43 -0400
committerJeff Layton <jlayton@primarydata.com>2014-09-09 16:01:09 -0400
commitf328296e27414394f25cebaef4a111a82ce0df32 (patch)
tree2263381bcef86e21e5d20dbfdd72c1f248382daa
parent5c97d7b1479982a48cf2129062b880c2555049ac (diff)
locks: Copy fl_lmops information for conflock in locks_copy_conflock()
Commit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner. But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock always be NULL. Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock always be NULL too. Make sure copy the private information by fl_copy_lock() in struct file_lock_operations, merge __locks_copy_lock() to fl_copy_lock(). Jeff advice, "Set fl_lmops on conflocks, but don't set fl_ops. fl_ops are superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by the fl_lmops. So you really do want to copy the fl_lmops for conflocks I think." v5: add missing calling of locks_release_private() in nlmsvc_testlock() v4: only copy fl_lmops for conflock, don't copy fl_ops Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
-rw-r--r--fs/lockd/svclock.c1
-rw-r--r--fs/locks.c36
2 files changed, 17 insertions, 20 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 2a6170133c1d..acfa94d5b489 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -586,6 +586,7 @@ conf_lock:
586 conflock->fl.fl_type = lock->fl.fl_type; 586 conflock->fl.fl_type = lock->fl.fl_type;
587 conflock->fl.fl_start = lock->fl.fl_start; 587 conflock->fl.fl_start = lock->fl.fl_start;
588 conflock->fl.fl_end = lock->fl.fl_end; 588 conflock->fl.fl_end = lock->fl.fl_end;
589 locks_release_private(&lock->fl);
589 ret = nlm_lck_denied; 590 ret = nlm_lck_denied;
590out: 591out:
591 if (block) 592 if (block)
diff --git a/fs/locks.c b/fs/locks.c
index 5e83f3a99377..c3991dc80137 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -271,21 +271,6 @@ void locks_init_lock(struct file_lock *fl)
271 271
272EXPORT_SYMBOL(locks_init_lock); 272EXPORT_SYMBOL(locks_init_lock);
273 273
274static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
275{
276 if (fl->fl_ops) {
277 if (fl->fl_ops->fl_copy_lock)
278 fl->fl_ops->fl_copy_lock(new, fl);
279 new->fl_ops = fl->fl_ops;
280 }
281
282 if (fl->fl_lmops) {
283 if (fl->fl_lmops->lm_get_owner)
284 fl->fl_lmops->lm_get_owner(new, fl);
285 new->fl_lmops = fl->fl_lmops;
286 }
287}
288
289/* 274/*
290 * Initialize a new lock from an existing file_lock structure. 275 * Initialize a new lock from an existing file_lock structure.
291 */ 276 */
@@ -298,8 +283,13 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
298 new->fl_type = fl->fl_type; 283 new->fl_type = fl->fl_type;
299 new->fl_start = fl->fl_start; 284 new->fl_start = fl->fl_start;
300 new->fl_end = fl->fl_end; 285 new->fl_end = fl->fl_end;
286 new->fl_lmops = fl->fl_lmops;
301 new->fl_ops = NULL; 287 new->fl_ops = NULL;
302 new->fl_lmops = NULL; 288
289 if (fl->fl_lmops) {
290 if (fl->fl_lmops->lm_get_owner)
291 fl->fl_lmops->lm_get_owner(new, fl);
292 }
303} 293}
304EXPORT_SYMBOL(locks_copy_conflock); 294EXPORT_SYMBOL(locks_copy_conflock);
305 295
@@ -309,11 +299,14 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
309 WARN_ON_ONCE(new->fl_ops); 299 WARN_ON_ONCE(new->fl_ops);
310 300
311 locks_copy_conflock(new, fl); 301 locks_copy_conflock(new, fl);
302
312 new->fl_file = fl->fl_file; 303 new->fl_file = fl->fl_file;
313 new->fl_ops = fl->fl_ops; 304 new->fl_ops = fl->fl_ops;
314 new->fl_lmops = fl->fl_lmops;
315 305
316 locks_copy_private(new, fl); 306 if (fl->fl_ops) {
307 if (fl->fl_ops->fl_copy_lock)
308 fl->fl_ops->fl_copy_lock(new, fl);
309 }
317} 310}
318 311
319EXPORT_SYMBOL(locks_copy_lock); 312EXPORT_SYMBOL(locks_copy_lock);
@@ -1989,11 +1982,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
1989 if (file_lock.fl_type != F_UNLCK) { 1982 if (file_lock.fl_type != F_UNLCK) {
1990 error = posix_lock_to_flock(&flock, &file_lock); 1983 error = posix_lock_to_flock(&flock, &file_lock);
1991 if (error) 1984 if (error)
1992 goto out; 1985 goto rel_priv;
1993 } 1986 }
1994 error = -EFAULT; 1987 error = -EFAULT;
1995 if (!copy_to_user(l, &flock, sizeof(flock))) 1988 if (!copy_to_user(l, &flock, sizeof(flock)))
1996 error = 0; 1989 error = 0;
1990rel_priv:
1991 locks_release_private(&file_lock);
1997out: 1992out:
1998 return error; 1993 return error;
1999} 1994}
@@ -2214,7 +2209,8 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
2214 error = -EFAULT; 2209 error = -EFAULT;
2215 if (!copy_to_user(l, &flock, sizeof(flock))) 2210 if (!copy_to_user(l, &flock, sizeof(flock)))
2216 error = 0; 2211 error = 0;
2217 2212
2213 locks_release_private(&file_lock);
2218out: 2214out:
2219 return error; 2215 return error;
2220} 2216}