aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2014-03-10 09:54:15 -0400
committerJeff Layton <jlayton@redhat.com>2014-03-31 08:24:43 -0400
commitd7a06983a01a33605191c0766857b832ac32a2b6 (patch)
treed6a0f83579e0d7a20a235ddb568d935fe54b24fb /include/linux
parent90478939dce096ed5b239cad16237dca0a59d66f (diff)
locks: fix locks_mandatory_locked to respect file-private locks
As Trond pointed out, you can currently deadlock yourself by setting a file-private lock on a file that requires mandatory locking and then trying to do I/O on it. Avoid this problem by plumbing some knowledge of file-private locks into the mandatory locking code. In order to do this, we must pass down information about the struct file that's being used to locks_verify_locked. Reported-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Acked-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fs.h22
1 files changed, 11 insertions, 11 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ae91dce8a547..4aa81e6ae067 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1912,6 +1912,11 @@ extern int current_umask(void);
1912extern void ihold(struct inode * inode); 1912extern void ihold(struct inode * inode);
1913extern void iput(struct inode *); 1913extern void iput(struct inode *);
1914 1914
1915static inline struct inode *file_inode(struct file *f)
1916{
1917 return f->f_inode;
1918}
1919
1915/* /sys/fs */ 1920/* /sys/fs */
1916extern struct kobject *fs_kobj; 1921extern struct kobject *fs_kobj;
1917 1922
@@ -1921,7 +1926,7 @@ extern struct kobject *fs_kobj;
1921#define FLOCK_VERIFY_WRITE 2 1926#define FLOCK_VERIFY_WRITE 2
1922 1927
1923#ifdef CONFIG_FILE_LOCKING 1928#ifdef CONFIG_FILE_LOCKING
1924extern int locks_mandatory_locked(struct inode *); 1929extern int locks_mandatory_locked(struct file *);
1925extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t); 1930extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
1926 1931
1927/* 1932/*
@@ -1944,10 +1949,10 @@ static inline int mandatory_lock(struct inode *ino)
1944 return IS_MANDLOCK(ino) && __mandatory_lock(ino); 1949 return IS_MANDLOCK(ino) && __mandatory_lock(ino);
1945} 1950}
1946 1951
1947static inline int locks_verify_locked(struct inode *inode) 1952static inline int locks_verify_locked(struct file *file)
1948{ 1953{
1949 if (mandatory_lock(inode)) 1954 if (mandatory_lock(file_inode(file)))
1950 return locks_mandatory_locked(inode); 1955 return locks_mandatory_locked(file);
1951 return 0; 1956 return 0;
1952} 1957}
1953 1958
@@ -2008,7 +2013,7 @@ static inline int break_deleg_wait(struct inode **delegated_inode)
2008} 2013}
2009 2014
2010#else /* !CONFIG_FILE_LOCKING */ 2015#else /* !CONFIG_FILE_LOCKING */
2011static inline int locks_mandatory_locked(struct inode *inode) 2016static inline int locks_mandatory_locked(struct file *file)
2012{ 2017{
2013 return 0; 2018 return 0;
2014} 2019}
@@ -2030,7 +2035,7 @@ static inline int mandatory_lock(struct inode *inode)
2030 return 0; 2035 return 0;
2031} 2036}
2032 2037
2033static inline int locks_verify_locked(struct inode *inode) 2038static inline int locks_verify_locked(struct file *file)
2034{ 2039{
2035 return 0; 2040 return 0;
2036} 2041}
@@ -2297,11 +2302,6 @@ static inline bool execute_ok(struct inode *inode)
2297 return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode); 2302 return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
2298} 2303}
2299 2304
2300static inline struct inode *file_inode(struct file *f)
2301{
2302 return f->f_inode;
2303}
2304
2305static inline void file_start_write(struct file *file) 2305static inline void file_start_write(struct file *file)
2306{ 2306{
2307 if (!S_ISREG(file_inode(file)->i_mode)) 2307 if (!S_ISREG(file_inode(file)->i_mode))