aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c13
-rw-r--r--include/linux/fs.h39
2 files changed, 40 insertions, 12 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 67ce331a3ed8..cfaeaae0f2db 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3650,14 +3650,9 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate
3650 else { 3650 else {
3651 error = security_inode_unlink(dir, dentry); 3651 error = security_inode_unlink(dir, dentry);
3652 if (!error) { 3652 if (!error) {
3653 error = break_deleg(target, O_WRONLY|O_NONBLOCK); 3653 error = try_break_deleg(target, delegated_inode);
3654 if (error) { 3654 if (error)
3655 if (error == -EWOULDBLOCK && delegated_inode) {
3656 *delegated_inode = target;
3657 ihold(target);
3658 }
3659 goto out; 3655 goto out;
3660 }
3661 error = dir->i_op->unlink(dir, dentry); 3656 error = dir->i_op->unlink(dir, dentry);
3662 if (!error) 3657 if (!error)
3663 dont_mount(dentry); 3658 dont_mount(dentry);
@@ -3727,9 +3722,7 @@ exit2:
3727 iput(inode); /* truncate the inode here */ 3722 iput(inode); /* truncate the inode here */
3728 inode = NULL; 3723 inode = NULL;
3729 if (delegated_inode) { 3724 if (delegated_inode) {
3730 error = break_deleg(delegated_inode, O_WRONLY); 3725 error = break_deleg_wait(&delegated_inode);
3731 iput(delegated_inode);
3732 delegated_inode = NULL;
3733 if (!error) 3726 if (!error)
3734 goto retry_deleg; 3727 goto retry_deleg;
3735 } 3728 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a5799233142a..931f919f44e1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1905,6 +1905,9 @@ extern bool fs_fully_visible(struct file_system_type *);
1905 1905
1906extern int current_umask(void); 1906extern int current_umask(void);
1907 1907
1908extern void ihold(struct inode * inode);
1909extern void iput(struct inode *);
1910
1908/* /sys/fs */ 1911/* /sys/fs */
1909extern struct kobject *fs_kobj; 1912extern struct kobject *fs_kobj;
1910 1913
@@ -1972,6 +1975,28 @@ static inline int break_deleg(struct inode *inode, unsigned int mode)
1972 return 0; 1975 return 0;
1973} 1976}
1974 1977
1978static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode)
1979{
1980 int ret;
1981
1982 ret = break_deleg(inode, O_WRONLY|O_NONBLOCK);
1983 if (ret == -EWOULDBLOCK && delegated_inode) {
1984 *delegated_inode = inode;
1985 ihold(inode);
1986 }
1987 return ret;
1988}
1989
1990static inline int break_deleg_wait(struct inode **delegated_inode)
1991{
1992 int ret;
1993
1994 ret = break_deleg(*delegated_inode, O_WRONLY);
1995 iput(*delegated_inode);
1996 *delegated_inode = NULL;
1997 return ret;
1998}
1999
1975#else /* !CONFIG_FILE_LOCKING */ 2000#else /* !CONFIG_FILE_LOCKING */
1976static inline int locks_mandatory_locked(struct inode *inode) 2001static inline int locks_mandatory_locked(struct inode *inode)
1977{ 2002{
@@ -2015,6 +2040,18 @@ static inline int break_deleg(struct inode *inode, unsigned int mode)
2015{ 2040{
2016 return 0; 2041 return 0;
2017} 2042}
2043
2044static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode)
2045{
2046 return 0;
2047}
2048
2049static inline int break_deleg_wait(struct inode **delegated_inode)
2050{
2051 BUG();
2052 return 0;
2053}
2054
2018#endif /* CONFIG_FILE_LOCKING */ 2055#endif /* CONFIG_FILE_LOCKING */
2019 2056
2020/* fs/open.c */ 2057/* fs/open.c */
@@ -2350,8 +2387,6 @@ extern loff_t vfs_llseek(struct file *file, loff_t offset, int whence);
2350extern int inode_init_always(struct super_block *, struct inode *); 2387extern int inode_init_always(struct super_block *, struct inode *);
2351extern void inode_init_once(struct inode *); 2388extern void inode_init_once(struct inode *);
2352extern void address_space_init_once(struct address_space *mapping); 2389extern void address_space_init_once(struct address_space *mapping);
2353extern void ihold(struct inode * inode);
2354extern void iput(struct inode *);
2355extern struct inode * igrab(struct inode *); 2390extern struct inode * igrab(struct inode *);
2356extern ino_t iunique(struct super_block *, ino_t); 2391extern ino_t iunique(struct super_block *, ino_t);
2357extern int inode_needs_sync(struct inode *inode); 2392extern int inode_needs_sync(struct inode *inode);