aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/Locking43
-rw-r--r--fs/dcache.c83
-rw-r--r--fs/fat/namei_msdos.c4
-rw-r--r--fs/fat/namei_vfat.c13
-rw-r--r--fs/namei.c4
-rw-r--r--fs/read_write.c6
-rw-r--r--fs/super.c2
-rw-r--r--fs/xattr.c4
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h2
-rw-r--r--include/linux/xattr.h1
-rw-r--r--net/sunrpc/rpc_pipe.c16
-rw-r--r--security/selinux/hooks.c7
13 files changed, 69 insertions, 118 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75d2d57e2c44..15853d522941 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -69,31 +69,31 @@ prototypes:
69 69
70locking rules: 70locking rules:
71 all may block 71 all may block
72 i_mutex(inode) 72 i_rwsem(inode)
73lookup: yes 73lookup: shared
74create: yes 74create: exclusive
75link: yes (both) 75link: exclusive (both)
76mknod: yes 76mknod: exclusive
77symlink: yes 77symlink: exclusive
78mkdir: yes 78mkdir: exclusive
79unlink: yes (both) 79unlink: exclusive (both)
80rmdir: yes (both) (see below) 80rmdir: exclusive (both)(see below)
81rename: yes (all) (see below) 81rename: exclusive (all) (see below)
82readlink: no 82readlink: no
83get_link: no 83get_link: no
84setattr: yes 84setattr: exclusive
85permission: no (may not block if called in rcu-walk mode) 85permission: no (may not block if called in rcu-walk mode)
86get_acl: no 86get_acl: no
87getattr: no 87getattr: no
88listxattr: no 88listxattr: no
89fiemap: no 89fiemap: no
90update_time: no 90update_time: no
91atomic_open: yes 91atomic_open: exclusive
92tmpfile: no 92tmpfile: no
93 93
94 94
95 Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on 95 Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem
96victim. 96 exclusive on victim.
97 cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. 97 cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
98 98
99See Documentation/filesystems/directory-locking for more detailed discussion 99See Documentation/filesystems/directory-locking for more detailed discussion
@@ -111,10 +111,10 @@ prototypes:
111 111
112locking rules: 112locking rules:
113 all may block 113 all may block
114 i_mutex(inode) 114 i_rwsem(inode)
115list: no 115list: no
116get: no 116get: no
117set: yes 117set: exclusive
118 118
119--------------------------- super_operations --------------------------- 119--------------------------- super_operations ---------------------------
120prototypes: 120prototypes:
@@ -217,14 +217,14 @@ prototypes:
217locking rules: 217locking rules:
218 All except set_page_dirty and freepage may block 218 All except set_page_dirty and freepage may block
219 219
220 PageLocked(page) i_mutex 220 PageLocked(page) i_rwsem
221writepage: yes, unlocks (see below) 221writepage: yes, unlocks (see below)
222readpage: yes, unlocks 222readpage: yes, unlocks
223writepages: 223writepages:
224set_page_dirty no 224set_page_dirty no
225readpages: 225readpages:
226write_begin: locks the page yes 226write_begin: locks the page exclusive
227write_end: yes, unlocks yes 227write_end: yes, unlocks exclusive
228bmap: 228bmap:
229invalidatepage: yes 229invalidatepage: yes
230releasepage: yes 230releasepage: yes
@@ -439,6 +439,7 @@ prototypes:
439 ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); 439 ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
440 ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); 440 ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
441 int (*iterate) (struct file *, struct dir_context *); 441 int (*iterate) (struct file *, struct dir_context *);
442 int (*iterate_shared) (struct file *, struct dir_context *);
442 unsigned int (*poll) (struct file *, struct poll_table_struct *); 443 unsigned int (*poll) (struct file *, struct poll_table_struct *);
443 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 444 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
444 long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 445 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
@@ -480,6 +481,10 @@ mutex or just to use i_size_read() instead.
480Note: this does not protect the file->f_pos against concurrent modifications 481Note: this does not protect the file->f_pos against concurrent modifications
481since this is something the userspace has to take care about. 482since this is something the userspace has to take care about.
482 483
484->iterate() is called with i_rwsem exclusive.
485
486->iterate_shared() is called with i_rwsem at least shared.
487
483->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags. 488->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags.
484Most instances call fasync_helper(), which does that maintenance, so it's 489Most instances call fasync_helper(), which does that maintenance, so it's
485not normally something one needs to worry about. Return values > 0 will be 490not normally something one needs to worry about. Return values > 0 will be
diff --git a/fs/dcache.c b/fs/dcache.c
index 1d40d8b3ad34..0e8e5de3c48a 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -902,6 +902,35 @@ repeat:
902} 902}
903EXPORT_SYMBOL(dget_parent); 903EXPORT_SYMBOL(dget_parent);
904 904
905static struct dentry * __d_find_any_alias(struct inode *inode)
906{
907 struct dentry *alias;
908
909 if (hlist_empty(&inode->i_dentry))
910 return NULL;
911 alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
912 __dget(alias);
913 return alias;
914}
915
916/**
917 * d_find_any_alias - find any alias for a given inode
918 * @inode: inode to find an alias for
919 *
920 * If any aliases exist for the given inode, take and return a
921 * reference for one of them. If no aliases exist, return %NULL.
922 */
923struct dentry *d_find_any_alias(struct inode *inode)
924{
925 struct dentry *de;
926
927 spin_lock(&inode->i_lock);
928 de = __d_find_any_alias(inode);
929 spin_unlock(&inode->i_lock);
930 return de;
931}
932EXPORT_SYMBOL(d_find_any_alias);
933
905/** 934/**
906 * d_find_alias - grab a hashed alias of inode 935 * d_find_alias - grab a hashed alias of inode
907 * @inode: inode in question 936 * @inode: inode in question
@@ -918,34 +947,19 @@ EXPORT_SYMBOL(dget_parent);
918 */ 947 */
919static struct dentry *__d_find_alias(struct inode *inode) 948static struct dentry *__d_find_alias(struct inode *inode)
920{ 949{
921 struct dentry *alias, *discon_alias; 950 struct dentry *alias;
951
952 if (S_ISDIR(inode->i_mode))
953 return __d_find_any_alias(inode);
922 954
923again:
924 discon_alias = NULL;
925 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { 955 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
926 spin_lock(&alias->d_lock); 956 spin_lock(&alias->d_lock);
927 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { 957 if (!d_unhashed(alias)) {
928 if (IS_ROOT(alias) &&
929 (alias->d_flags & DCACHE_DISCONNECTED)) {
930 discon_alias = alias;
931 } else {
932 __dget_dlock(alias);
933 spin_unlock(&alias->d_lock);
934 return alias;
935 }
936 }
937 spin_unlock(&alias->d_lock);
938 }
939 if (discon_alias) {
940 alias = discon_alias;
941 spin_lock(&alias->d_lock);
942 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
943 __dget_dlock(alias); 958 __dget_dlock(alias);
944 spin_unlock(&alias->d_lock); 959 spin_unlock(&alias->d_lock);
945 return alias; 960 return alias;
946 } 961 }
947 spin_unlock(&alias->d_lock); 962 spin_unlock(&alias->d_lock);
948 goto again;
949 } 963 }
950 return NULL; 964 return NULL;
951} 965}
@@ -1927,35 +1941,6 @@ struct dentry *d_make_root(struct inode *root_inode)
1927} 1941}
1928EXPORT_SYMBOL(d_make_root); 1942EXPORT_SYMBOL(d_make_root);
1929 1943
1930static struct dentry * __d_find_any_alias(struct inode *inode)
1931{
1932 struct dentry *alias;
1933
1934 if (hlist_empty(&inode->i_dentry))
1935 return NULL;
1936 alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
1937 __dget(alias);
1938 return alias;
1939}
1940
1941/**
1942 * d_find_any_alias - find any alias for a given inode
1943 * @inode: inode to find an alias for
1944 *
1945 * If any aliases exist for the given inode, take and return a
1946 * reference for one of them. If no aliases exist, return %NULL.
1947 */
1948struct dentry *d_find_any_alias(struct inode *inode)
1949{
1950 struct dentry *de;
1951
1952 spin_lock(&inode->i_lock);
1953 de = __d_find_any_alias(inode);
1954 spin_unlock(&inode->i_lock);
1955 return de;
1956}
1957EXPORT_SYMBOL(d_find_any_alias);
1958
1959static struct dentry *__d_instantiate_anon(struct dentry *dentry, 1944static struct dentry *__d_instantiate_anon(struct dentry *dentry,
1960 struct inode *inode, 1945 struct inode *inode,
1961 bool disconnected) 1946 bool disconnected)
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 582ca731a6c9..484ce674e0cd 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -314,10 +314,6 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
314 int err; 314 int err;
315 315
316 mutex_lock(&MSDOS_SB(sb)->s_lock); 316 mutex_lock(&MSDOS_SB(sb)->s_lock);
317 /*
318 * Check whether the directory is not in use, then check
319 * whether it is empty.
320 */
321 err = fat_dir_empty(inode); 317 err = fat_dir_empty(inode);
322 if (err) 318 if (err)
323 goto out; 319 goto out;
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 2649759c478a..4f4362d5a04c 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -697,15 +697,6 @@ static int vfat_find(struct inode *dir, const struct qstr *qname,
697 return fat_search_long(dir, qname->name, len, sinfo); 697 return fat_search_long(dir, qname->name, len, sinfo);
698} 698}
699 699
700/*
701 * (nfsd's) anonymous disconnected dentry?
702 * NOTE: !IS_ROOT() is not anonymous (I.e. d_splice_alias() did the job).
703 */
704static int vfat_d_anon_disconn(struct dentry *dentry)
705{
706 return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
707}
708
709static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, 700static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
710 unsigned int flags) 701 unsigned int flags)
711{ 702{
@@ -738,8 +729,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
738 * Checking "alias->d_parent == dentry->d_parent" to make sure 729 * Checking "alias->d_parent == dentry->d_parent" to make sure
739 * FS is not corrupted (especially double linked dir). 730 * FS is not corrupted (especially double linked dir).
740 */ 731 */
741 if (alias && alias->d_parent == dentry->d_parent && 732 if (alias && alias->d_parent == dentry->d_parent) {
742 !vfat_d_anon_disconn(alias)) {
743 /* 733 /*
744 * This inode has non anonymous-DCACHE_DISCONNECTED 734 * This inode has non anonymous-DCACHE_DISCONNECTED
745 * dentry. This means, the user did ->lookup() by an 735 * dentry. This means, the user did ->lookup() by an
@@ -747,7 +737,6 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
747 * 737 *
748 * Switch to new one for reason of locality if possible. 738 * Switch to new one for reason of locality if possible.
749 */ 739 */
750 BUG_ON(d_unhashed(alias));
751 if (!S_ISDIR(inode->i_mode)) 740 if (!S_ISDIR(inode->i_mode))
752 d_move(alias, dentry); 741 d_move(alias, dentry);
753 iput(inode); 742 iput(inode);
diff --git a/fs/namei.c b/fs/namei.c
index 9666e5e118dc..a59968de1636 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1438,10 +1438,8 @@ static int path_parent_directory(struct path *path)
1438static int follow_dotdot(struct nameidata *nd) 1438static int follow_dotdot(struct nameidata *nd)
1439{ 1439{
1440 while(1) { 1440 while(1) {
1441 if (nd->path.dentry == nd->root.dentry && 1441 if (path_equal(&nd->path, &nd->root))
1442 nd->path.mnt == nd->root.mnt) {
1443 break; 1442 break;
1444 }
1445 if (nd->path.dentry != nd->path.mnt->mnt_root) { 1443 if (nd->path.dentry != nd->path.mnt->mnt_root) {
1446 int ret = path_parent_directory(&nd->path); 1444 int ret = path_parent_directory(&nd->path);
1447 if (ret) 1445 if (ret)
diff --git a/fs/read_write.c b/fs/read_write.c
index c4eabbfc90df..e83bd9744b5d 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -2023,7 +2023,7 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
2023 ret = mnt_want_write_file(dst_file); 2023 ret = mnt_want_write_file(dst_file);
2024 if (ret) { 2024 if (ret) {
2025 info->status = ret; 2025 info->status = ret;
2026 goto next_loop; 2026 goto next_fdput;
2027 } 2027 }
2028 2028
2029 dst_off = info->dest_offset; 2029 dst_off = info->dest_offset;
@@ -2058,9 +2058,9 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
2058 2058
2059next_file: 2059next_file:
2060 mnt_drop_write_file(dst_file); 2060 mnt_drop_write_file(dst_file);
2061next_loop: 2061next_fdput:
2062 fdput(dst_fd); 2062 fdput(dst_fd);
2063 2063next_loop:
2064 if (fatal_signal_pending(current)) 2064 if (fatal_signal_pending(current))
2065 goto out; 2065 goto out;
2066 } 2066 }
diff --git a/fs/super.c b/fs/super.c
index 4b5b562176d0..50728d9c1a05 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -947,7 +947,7 @@ void emergency_remount(void)
947static void do_thaw_all_callback(struct super_block *sb) 947static void do_thaw_all_callback(struct super_block *sb)
948{ 948{
949 down_write(&sb->s_umount); 949 down_write(&sb->s_umount);
950 if (sb->s_root && sb->s_flags & MS_BORN) { 950 if (sb->s_root && sb->s_flags & SB_BORN) {
951 emergency_thaw_bdev(sb); 951 emergency_thaw_bdev(sb);
952 thaw_super_locked(sb); 952 thaw_super_locked(sb);
953 } else { 953 } else {
diff --git a/fs/xattr.c b/fs/xattr.c
index 61cd28ba25f3..f9cb1db187b7 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -229,7 +229,7 @@ out:
229} 229}
230EXPORT_SYMBOL_GPL(vfs_setxattr); 230EXPORT_SYMBOL_GPL(vfs_setxattr);
231 231
232ssize_t 232static ssize_t
233xattr_getsecurity(struct inode *inode, const char *name, void *value, 233xattr_getsecurity(struct inode *inode, const char *name, void *value,
234 size_t size) 234 size_t size)
235{ 235{
@@ -254,7 +254,6 @@ out:
254out_noalloc: 254out_noalloc:
255 return len; 255 return len;
256} 256}
257EXPORT_SYMBOL_GPL(xattr_getsecurity);
258 257
259/* 258/*
260 * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr 259 * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
@@ -354,7 +353,6 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
354 if (error) 353 if (error)
355 return error; 354 return error;
356 if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) { 355 if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
357 error = -EOPNOTSUPP;
358 error = inode->i_op->listxattr(dentry, list, size); 356 error = inode->i_op->listxattr(dentry, list, size);
359 } else { 357 } else {
360 error = security_inode_listsecurity(inode, list, size); 358 error = security_inode_listsecurity(inode, list, size);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d8d4831af9ff..5d306028f0a2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -94,7 +94,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
94 94
95/* 95/*
96 * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond 96 * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond
97 * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() 97 * to O_WRONLY and O_RDWR via the strange trick in do_dentry_open()
98 */ 98 */
99 99
100/* file is open for reading */ 100/* file is open for reading */
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index a5704daf5df9..e90b9bd99ded 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -122,8 +122,6 @@ extern struct dentry *rpc_create_cache_dir(struct dentry *,
122 struct cache_detail *); 122 struct cache_detail *);
123extern void rpc_remove_cache_dir(struct dentry *); 123extern void rpc_remove_cache_dir(struct dentry *);
124 124
125extern int rpc_rmdir(struct dentry *dentry);
126
127struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags); 125struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags);
128void rpc_destroy_pipe_data(struct rpc_pipe *pipe); 126void rpc_destroy_pipe_data(struct rpc_pipe *pipe);
129extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *, 127extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *,
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index d70f77a4b62a..6dad031be3c2 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -46,7 +46,6 @@ struct xattr {
46 size_t value_len; 46 size_t value_len;
47}; 47};
48 48
49ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
50ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); 49ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
51ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); 50ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
52ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); 51ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index c81ef5e6c981..4fda18d47e2c 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -609,22 +609,6 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry)
609 return ret; 609 return ret;
610} 610}
611 611
612int rpc_rmdir(struct dentry *dentry)
613{
614 struct dentry *parent;
615 struct inode *dir;
616 int error;
617
618 parent = dget_parent(dentry);
619 dir = d_inode(parent);
620 inode_lock_nested(dir, I_MUTEX_PARENT);
621 error = __rpc_rmdir(dir, dentry);
622 inode_unlock(dir);
623 dput(parent);
624 return error;
625}
626EXPORT_SYMBOL_GPL(rpc_rmdir);
627
628static int __rpc_unlink(struct inode *dir, struct dentry *dentry) 612static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
629{ 613{
630 int ret; 614 int ret;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 179dd20bec0a..99c4675952f7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -274,11 +274,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
274 * Try reloading inode security labels that have been marked as invalid. The 274 * Try reloading inode security labels that have been marked as invalid. The
275 * @may_sleep parameter indicates when sleeping and thus reloading labels is 275 * @may_sleep parameter indicates when sleeping and thus reloading labels is
276 * allowed; when set to false, returns -ECHILD when the label is 276 * allowed; when set to false, returns -ECHILD when the label is
277 * invalid. The @opt_dentry parameter should be set to a dentry of the inode; 277 * invalid. The @dentry parameter should be set to a dentry of the inode.
278 * when no dentry is available, set it to NULL instead.
279 */ 278 */
280static int __inode_security_revalidate(struct inode *inode, 279static int __inode_security_revalidate(struct inode *inode,
281 struct dentry *opt_dentry, 280 struct dentry *dentry,
282 bool may_sleep) 281 bool may_sleep)
283{ 282{
284 struct inode_security_struct *isec = inode->i_security; 283 struct inode_security_struct *isec = inode->i_security;
@@ -295,7 +294,7 @@ static int __inode_security_revalidate(struct inode *inode,
295 * @opt_dentry is NULL and no dentry for this inode can be 294 * @opt_dentry is NULL and no dentry for this inode can be
296 * found; in that case, continue using the old label. 295 * found; in that case, continue using the old label.
297 */ 296 */
298 inode_doinit_with_dentry(inode, opt_dentry); 297 inode_doinit_with_dentry(inode, dentry);
299 } 298 }
300 return 0; 299 return 0;
301} 300}