aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaliy Gusev <vgusev@openvz.org>2008-01-16 19:07:08 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-03 17:51:36 -0500
commitab1f16116527e42dec8aee176d673a41a881b809 (patch)
tree0d20fa10151e43f9f104986a2b89ec88ca0135af
parent4321e01e7dce8042758349ffa2929c723b0d4107 (diff)
pid-namespaces-vs-locks-interaction
fcntl(F_GETLK,..) can return pid of process for not current pid namespace (if process is belonged to the several namespaces). It is true also for pids in /proc/locks. So correct behavior is saving pointer to the struct pid of the process lock owner. Signed-off-by: Vitaliy Gusev <vgusev@openvz.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/locks.c29
-rw-r--r--include/linux/fs.h1
2 files changed, 24 insertions, 6 deletions
diff --git a/fs/locks.c b/fs/locks.c
index faddccb6336a..49354b9c7dc1 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -125,6 +125,7 @@
125#include <linux/syscalls.h> 125#include <linux/syscalls.h>
126#include <linux/time.h> 126#include <linux/time.h>
127#include <linux/rcupdate.h> 127#include <linux/rcupdate.h>
128#include <linux/pid_namespace.h>
128 129
129#include <asm/semaphore.h> 130#include <asm/semaphore.h>
130#include <asm/uaccess.h> 131#include <asm/uaccess.h>
@@ -185,6 +186,7 @@ void locks_init_lock(struct file_lock *fl)
185 fl->fl_fasync = NULL; 186 fl->fl_fasync = NULL;
186 fl->fl_owner = NULL; 187 fl->fl_owner = NULL;
187 fl->fl_pid = 0; 188 fl->fl_pid = 0;
189 fl->fl_nspid = NULL;
188 fl->fl_file = NULL; 190 fl->fl_file = NULL;
189 fl->fl_flags = 0; 191 fl->fl_flags = 0;
190 fl->fl_type = 0; 192 fl->fl_type = 0;
@@ -553,6 +555,8 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
553{ 555{
554 list_add(&fl->fl_link, &file_lock_list); 556 list_add(&fl->fl_link, &file_lock_list);
555 557
558 fl->fl_nspid = get_pid(task_tgid(current));
559
556 /* insert into file's list */ 560 /* insert into file's list */
557 fl->fl_next = *pos; 561 fl->fl_next = *pos;
558 *pos = fl; 562 *pos = fl;
@@ -584,6 +588,11 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
584 if (fl->fl_ops && fl->fl_ops->fl_remove) 588 if (fl->fl_ops && fl->fl_ops->fl_remove)
585 fl->fl_ops->fl_remove(fl); 589 fl->fl_ops->fl_remove(fl);
586 590
591 if (fl->fl_nspid) {
592 put_pid(fl->fl_nspid);
593 fl->fl_nspid = NULL;
594 }
595
587 locks_wake_up_blocks(fl); 596 locks_wake_up_blocks(fl);
588 locks_free_lock(fl); 597 locks_free_lock(fl);
589} 598}
@@ -646,14 +655,16 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
646 if (posix_locks_conflict(fl, cfl)) 655 if (posix_locks_conflict(fl, cfl))
647 break; 656 break;
648 } 657 }
649 if (cfl) 658 if (cfl) {
650 __locks_copy_lock(fl, cfl); 659 __locks_copy_lock(fl, cfl);
651 else 660 if (cfl->fl_nspid)
661 fl->fl_pid = pid_nr_ns(cfl->fl_nspid,
662 task_active_pid_ns(current));
663 } else
652 fl->fl_type = F_UNLCK; 664 fl->fl_type = F_UNLCK;
653 unlock_kernel(); 665 unlock_kernel();
654 return; 666 return;
655} 667}
656
657EXPORT_SYMBOL(posix_test_lock); 668EXPORT_SYMBOL(posix_test_lock);
658 669
659/* 670/*
@@ -2070,6 +2081,12 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2070 int id, char *pfx) 2081 int id, char *pfx)
2071{ 2082{
2072 struct inode *inode = NULL; 2083 struct inode *inode = NULL;
2084 unsigned int fl_pid;
2085
2086 if (fl->fl_nspid)
2087 fl_pid = pid_nr_ns(fl->fl_nspid, task_active_pid_ns(current));
2088 else
2089 fl_pid = fl->fl_pid;
2073 2090
2074 if (fl->fl_file != NULL) 2091 if (fl->fl_file != NULL)
2075 inode = fl->fl_file->f_path.dentry->d_inode; 2092 inode = fl->fl_file->f_path.dentry->d_inode;
@@ -2110,16 +2127,16 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2110 } 2127 }
2111 if (inode) { 2128 if (inode) {
2112#ifdef WE_CAN_BREAK_LSLK_NOW 2129#ifdef WE_CAN_BREAK_LSLK_NOW
2113 seq_printf(f, "%d %s:%ld ", fl->fl_pid, 2130 seq_printf(f, "%d %s:%ld ", fl_pid,
2114 inode->i_sb->s_id, inode->i_ino); 2131 inode->i_sb->s_id, inode->i_ino);
2115#else 2132#else
2116 /* userspace relies on this representation of dev_t ;-( */ 2133 /* userspace relies on this representation of dev_t ;-( */
2117 seq_printf(f, "%d %02x:%02x:%ld ", fl->fl_pid, 2134 seq_printf(f, "%d %02x:%02x:%ld ", fl_pid,
2118 MAJOR(inode->i_sb->s_dev), 2135 MAJOR(inode->i_sb->s_dev),
2119 MINOR(inode->i_sb->s_dev), inode->i_ino); 2136 MINOR(inode->i_sb->s_dev), inode->i_ino);
2120#endif 2137#endif
2121 } else { 2138 } else {
2122 seq_printf(f, "%d <none>:0 ", fl->fl_pid); 2139 seq_printf(f, "%d <none>:0 ", fl_pid);
2123 } 2140 }
2124 if (IS_POSIX(fl)) { 2141 if (IS_POSIX(fl)) {
2125 if (fl->fl_end == OFFSET_MAX) 2142 if (fl->fl_end == OFFSET_MAX)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a516b6716870..b7736ab8bb5e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -872,6 +872,7 @@ struct file_lock {
872 struct list_head fl_block; /* circular list of blocked processes */ 872 struct list_head fl_block; /* circular list of blocked processes */
873 fl_owner_t fl_owner; 873 fl_owner_t fl_owner;
874 unsigned int fl_pid; 874 unsigned int fl_pid;
875 struct pid *fl_nspid;
875 wait_queue_head_t fl_wait; 876 wait_queue_head_t fl_wait;
876 struct file *fl_file; 877 struct file *fl_file;
877 unsigned char fl_flags; 878 unsigned char fl_flags;