Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f956d08

Browse files
committedJun 4, 2018
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "Misc bits and pieces not fitting into anything more specific" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: delete unnecessary assignment in vfs_listxattr Documentation: filesystems: update filesystem locking documentation vfs: namei: use path_equal() in follow_dotdot() fs.h: fix outdated comment about file flags __inode_security_revalidate() never gets NULL opt_dentry make xattr_getsecurity() static vfat: simplify checks in vfat_lookup() get rid of dead code in d_find_alias() it's SB_BORN, not MS_BORN... msdos_rmdir(): kill BS comment remove rpc_rmdir() fs: avoid fdput() after failed fdget() in vfs_dedupe_file_range()
2 parents cf626b0 + eb91537 commit f956d08

File tree

13 files changed

+69
-118
lines changed

13 files changed

+69
-118
lines changed
 

‎Documentation/filesystems/Locking‎

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,31 @@ prototypes:
6969

7070
locking rules:
7171
all may block
72-
i_mutex(inode)
73-
lookup: yes
74-
create: yes
75-
link: yes (both)
76-
mknod: yes
77-
symlink: yes
78-
mkdir: yes
79-
unlink: yes (both)
80-
rmdir: yes (both) (see below)
81-
rename: yes (all) (see below)
72+
i_rwsem(inode)
73+
lookup: shared
74+
create: exclusive
75+
link: exclusive (both)
76+
mknod: exclusive
77+
symlink: exclusive
78+
mkdir: exclusive
79+
unlink: exclusive (both)
80+
rmdir: exclusive (both)(see below)
81+
rename: exclusive (all) (see below)
8282
readlink: no
8383
get_link: no
84-
setattr: yes
84+
setattr: exclusive
8585
permission: no (may not block if called in rcu-walk mode)
8686
get_acl: no
8787
getattr: no
8888
listxattr: no
8989
fiemap: no
9090
update_time: no
91-
atomic_open: yes
91+
atomic_open: exclusive
9292
tmpfile: no
9393

9494

95-
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
96-
victim.
95+
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem
96+
exclusive on victim.
9797
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
9898

9999
See Documentation/filesystems/directory-locking for more detailed discussion
@@ -111,10 +111,10 @@ prototypes:
111111

112112
locking rules:
113113
all may block
114-
i_mutex(inode)
114+
i_rwsem(inode)
115115
list: no
116116
get: no
117-
set: yes
117+
set: exclusive
118118

119119
--------------------------- super_operations ---------------------------
120120
prototypes:
@@ -217,14 +217,14 @@ prototypes:
217217
locking rules:
218218
All except set_page_dirty and freepage may block
219219

220-
PageLocked(page) i_mutex
220+
PageLocked(page) i_rwsem
221221
writepage: yes, unlocks (see below)
222222
readpage: yes, unlocks
223223
writepages:
224224
set_page_dirty no
225225
readpages:
226-
write_begin: locks the page yes
227-
write_end: yes, unlocks yes
226+
write_begin: locks the page exclusive
227+
write_end: yes, unlocks exclusive
228228
bmap:
229229
invalidatepage: yes
230230
releasepage: yes
@@ -439,6 +439,7 @@ prototypes:
439439
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
440440
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
441441
int (*iterate) (struct file *, struct dir_context *);
442+
int (*iterate_shared) (struct file *, struct dir_context *);
442443
unsigned int (*poll) (struct file *, struct poll_table_struct *);
443444
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
444445
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
@@ -480,6 +481,10 @@ mutex or just to use i_size_read() instead.
480481
Note: this does not protect the file->f_pos against concurrent modifications
481482
since this is something the userspace has to take care about.
482483

484+
->iterate() is called with i_rwsem exclusive.
485+
486+
->iterate_shared() is called with i_rwsem at least shared.
487+
483488
->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags.
484489
Most instances call fasync_helper(), which does that maintenance, so it's
485490
not normally something one needs to worry about. Return values > 0 will be

‎fs/dcache.c‎

Lines changed: 34 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,35 @@ struct dentry *dget_parent(struct dentry *dentry)
902902
}
903903
EXPORT_SYMBOL(dget_parent);
904904

905+
static 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+
*/
923+
struct 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+
}
932+
EXPORT_SYMBOL(d_find_any_alias);
933+
905934
/**
906935
* d_find_alias - grab a hashed alias of inode
907936
* @inode: inode in question
@@ -918,34 +947,19 @@ EXPORT_SYMBOL(dget_parent);
918947
*/
919948
static struct dentry *__d_find_alias(struct inode *inode)
920949
{
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);
922954

923-
again:
924-
discon_alias = NULL;
925955
hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
926956
spin_lock(&alias->d_lock);
927-
if (S_ISDIR(inode->i_mode) || !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)) {
957+
if (!d_unhashed(alias)) {
943958
__dget_dlock(alias);
944959
spin_unlock(&alias->d_lock);
945960
return alias;
946961
}
947962
spin_unlock(&alias->d_lock);
948-
goto again;
949963
}
950964
return NULL;
951965
}
@@ -1927,35 +1941,6 @@ struct dentry *d_make_root(struct inode *root_inode)
19271941
}
19281942
EXPORT_SYMBOL(d_make_root);
19291943

1930-
static 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-
*/
1948-
struct 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-
}
1957-
EXPORT_SYMBOL(d_find_any_alias);
1958-
19591944
static struct dentry *__d_instantiate_anon(struct dentry *dentry,
19601945
struct inode *inode,
19611946
bool disconnected)

‎fs/fat/namei_msdos.c‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,6 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
314314
int err;
315315

316316
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-
*/
321317
err = fat_dir_empty(inode);
322318
if (err)
323319
goto out;

‎fs/fat/namei_vfat.c‎

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -697,15 +697,6 @@ static int vfat_find(struct inode *dir, const struct qstr *qname,
697697
return fat_search_long(dir, qname->name, len, sinfo);
698698
}
699699

700-
/*
701-
* (nfsd's) anonymous disconnected dentry?
702-
* NOTE: !IS_ROOT() is not anonymous (I.e. d_splice_alias() did the job).
703-
*/
704-
static int vfat_d_anon_disconn(struct dentry *dentry)
705-
{
706-
return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
707-
}
708-
709700
static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
710701
unsigned int flags)
711702
{
@@ -738,16 +729,14 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
738729
* Checking "alias->d_parent == dentry->d_parent" to make sure
739730
* FS is not corrupted (especially double linked dir).
740731
*/
741-
if (alias && alias->d_parent == dentry->d_parent &&
742-
!vfat_d_anon_disconn(alias)) {
732+
if (alias && alias->d_parent == dentry->d_parent) {
743733
/*
744734
* This inode has non anonymous-DCACHE_DISCONNECTED
745735
* dentry. This means, the user did ->lookup() by an
746736
* another name (longname vs 8.3 alias of it) in past.
747737
*
748738
* Switch to new one for reason of locality if possible.
749739
*/
750-
BUG_ON(d_unhashed(alias));
751740
if (!S_ISDIR(inode->i_mode))
752741
d_move(alias, dentry);
753742
iput(inode);

‎fs/namei.c‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,10 +1438,8 @@ static int path_parent_directory(struct path *path)
14381438
static int follow_dotdot(struct nameidata *nd)
14391439
{
14401440
while(1) {
1441-
if (nd->path.dentry == nd->root.dentry &&
1442-
nd->path.mnt == nd->root.mnt) {
1441+
if (path_equal(&nd->path, &nd->root))
14431442
break;
1444-
}
14451443
if (nd->path.dentry != nd->path.mnt->mnt_root) {
14461444
int ret = path_parent_directory(&nd->path);
14471445
if (ret)

‎fs/read_write.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
20232023
ret = mnt_want_write_file(dst_file);
20242024
if (ret) {
20252025
info->status = ret;
2026-
goto next_loop;
2026+
goto next_fdput;
20272027
}
20282028

20292029
dst_off = info->dest_offset;
@@ -2058,9 +2058,9 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
20582058

20592059
next_file:
20602060
mnt_drop_write_file(dst_file);
2061-
next_loop:
2061+
next_fdput:
20622062
fdput(dst_fd);
2063-
2063+
next_loop:
20642064
if (fatal_signal_pending(current))
20652065
goto out;
20662066
}

‎fs/super.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,7 @@ void emergency_remount(void)
947947
static void do_thaw_all_callback(struct super_block *sb)
948948
{
949949
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) {
951951
emergency_thaw_bdev(sb);
952952
thaw_super_locked(sb);
953953
} else {

‎fs/xattr.c‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
229229
}
230230
EXPORT_SYMBOL_GPL(vfs_setxattr);
231231

232-
ssize_t
232+
static ssize_t
233233
xattr_getsecurity(struct inode *inode, const char *name, void *value,
234234
size_t size)
235235
{
@@ -254,7 +254,6 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value,
254254
out_noalloc:
255255
return len;
256256
}
257-
EXPORT_SYMBOL_GPL(xattr_getsecurity);
258257

259258
/*
260259
* vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
@@ -354,7 +353,6 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
354353
if (error)
355354
return error;
356355
if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
357-
error = -EOPNOTSUPP;
358356
error = inode->i_op->listxattr(dentry, list, size);
359357
} else {
360358
error = security_inode_listsecurity(inode, list, size);

‎include/linux/fs.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
9494

9595
/*
9696
* 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()
9898
*/
9999

100100
/* file is open for reading */

‎include/linux/sunrpc/rpc_pipe_fs.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ extern struct dentry *rpc_create_cache_dir(struct dentry *,
122122
struct cache_detail *);
123123
extern void rpc_remove_cache_dir(struct dentry *);
124124

125-
extern int rpc_rmdir(struct dentry *dentry);
126-
127125
struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags);
128126
void rpc_destroy_pipe_data(struct rpc_pipe *pipe);
129127
extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *,

‎include/linux/xattr.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ struct xattr {
4646
size_t value_len;
4747
};
4848

49-
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
5049
ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
5150
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
5251
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);

‎net/sunrpc/rpc_pipe.c‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -609,22 +609,6 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry)
609609
return ret;
610610
}
611611

612-
int 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-
}
626-
EXPORT_SYMBOL_GPL(rpc_rmdir);
627-
628612
static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
629613
{
630614
int ret;

‎security/selinux/hooks.c‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
274274
* Try reloading inode security labels that have been marked as invalid. The
275275
* @may_sleep parameter indicates when sleeping and thus reloading labels is
276276
* 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;
278-
* when no dentry is available, set it to NULL instead.
277+
* invalid. The @dentry parameter should be set to a dentry of the inode.
279278
*/
280279
static int __inode_security_revalidate(struct inode *inode,
281-
struct dentry *opt_dentry,
280+
struct dentry *dentry,
282281
bool may_sleep)
283282
{
284283
struct inode_security_struct *isec = inode->i_security;
@@ -295,7 +294,7 @@ static int __inode_security_revalidate(struct inode *inode,
295294
* @opt_dentry is NULL and no dentry for this inode can be
296295
* found; in that case, continue using the old label.
297296
*/
298-
inode_doinit_with_dentry(inode, opt_dentry);
297+
inode_doinit_with_dentry(inode, dentry);
299298
}
300299
return 0;
301300
}

0 commit comments

Comments
 (0)
Failed to load comments.