diff options
author | Jeff Layton <jlayton@redhat.com> | 2014-03-04 16:30:23 +0100 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2014-03-31 14:24:43 +0200 |
commit | 90478939dce096ed5b239cad16237dca0a59d66f (patch) | |
tree | 743b3d825bc56bd1c0ab4d9487abba7b6883af86 | |
parent | locks: add new fcntl cmd values for handling file private locks (diff) | |
download | linux-90478939dce096ed5b239cad16237dca0a59d66f.tar.xz linux-90478939dce096ed5b239cad16237dca0a59d66f.zip |
locks: require that flock->l_pid be set to 0 for file-private locks
Neil Brown suggested potentially overloading the l_pid value as a "lock
context" field for file-private locks. While I don't think we will
probably want to do that here, it's probably a good idea to ensure that
in the future we could extend this API without breaking existing
callers.
Typically the l_pid value is ignored for incoming struct flock
arguments, serving mainly as a place to return the pid of the owner if
there is a conflicting lock. For file-private locks, require that it
currently be set to 0 and return EINVAL if it isn't. If we eventually
want to make a non-zero l_pid mean something, then this will help ensure
that we don't break legacy programs that are using file-private locks.
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
-rw-r--r-- | fs/locks.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/locks.c b/fs/locks.c index 3b54b98236ee..09d6c8c33c81 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1931,6 +1931,10 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) goto out; if (cmd == F_GETLKP) { + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_GETLK; file_lock.fl_flags |= FL_FILE_PVT; file_lock.fl_owner = (fl_owner_t)filp; @@ -2062,11 +2066,19 @@ again: */ switch (cmd) { case F_SETLKP: + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_SETLK; file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; break; case F_SETLKPW: + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_SETLKW; file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; @@ -2121,6 +2133,10 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) goto out; if (cmd == F_GETLKP) { + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_GETLK64; file_lock.fl_flags |= FL_FILE_PVT; file_lock.fl_owner = (fl_owner_t)filp; @@ -2185,11 +2201,19 @@ again: */ switch (cmd) { case F_SETLKP: + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_SETLK64; file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; break; case F_SETLKPW: + error = -EINVAL; + if (flock.l_pid != 0) + goto out; + cmd = F_SETLKW64; file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; |