History

Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc vfs updates from Al Viro: "Assorted patches from previous cycle(s)..." * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fix hostfs_open() use of ->f_path.dentry Make sure that make_create_in_sticky() never sees uninitialized value of dir_mode fs: Kill DCACHE_DONTCACHE dentry even if DCACHE_REFERENCED is set fs: Handle I_DONTCACHE in iput_final() instead of generic_drop_inode() fs/namespace.c: WARN if mnt_count has become negative

Linus Torvalds committed 5 years ago

Commit 7bb52262 parents 71c5f03 2e2cbaf7 files · +23 −10Browse files

Unified · Split

7 files
  1. fs/dcache.c +8 −1
  2. fs/hostfs/hostfs_kern.c +1 −1
  3. fs/inode.c +3 −1
  4. fs/namei.c +3 −1
  5. fs/namespace.c +6 −3
  6. fs/pnode.h +1 −1
  7. include/linux/fs.h +1 −2
fs/dcache.c+8−1
@@ -793,10 +793,17 @@ static inline bool fast_dput(struct dentry *dentry) · 792 unmodified lines
793793 * a reference to the dentry and change that, but
794794 * our work is done - we can leave the dentry
795795 * around with a zero refcount.
796+ *
797+ * Nevertheless, there are two cases that we should kill
798+ * the dentry anyway.
799+ * 1. free disconnected dentries as soon as their refcount
800+ * reached zero.
801+ * 2. free dentries if they should not be cached.
796802 */
797803 smp_rmb();
798804 d_flags = READ_ONCE(dentry->d_flags);
799− d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_DISCONNECTED;
805+ d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST |
806+ DCACHE_DISCONNECTED | DCACHE_DONTCACHE;
800807
801808 /* Nothing to do? Dropping the reference was all we needed? */
802809 if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
fs/hostfs/hostfs_kern.c+1−1
@@ -315,7 +315,7 @@ retry: · 314 unmodified lines
315315 if (mode & FMODE_WRITE)
316316 r = w = 1;
317317
318− name = dentry_name(file->f_path.dentry);
318+ name = dentry_name(d_real(file->f_path.dentry, file->f_inode));
319319 if (name == NULL)
320320 return -ENOMEM;
321321
fs/inode.c+3−1
@@ -1624,7 +1624,9 @@ static void iput_final(struct inode *inode) · 1623 unmodified lines
16241624 else
16251625 drop = generic_drop_inode(inode);
16261626
1627− if (!drop && (sb->s_flags & SB_ACTIVE)) {
1627+ if (!drop &&
1628+ !(inode->i_state & I_DONTCACHE) &&
1629+ (sb->s_flags & SB_ACTIVE)) {
16281630 inode_add_lru(inode);
16291631 spin_unlock(&inode->i_lock);
16301632 return;
fs/namei.c+3−1
@@ -2114,8 +2114,10 @@ static int link_path_walk(const char *name, struct nameidata *nd) · 2113 unmodified lines
21142114 return PTR_ERR(name);
21152115 while (*name=='/')
21162116 name++;
2117− if (!*name)
2117+ if (!*name) {
2118+ nd->dir_mode = 0; // short-circuit the 'hardening' idiocy
21182119 return 0;
2120+ }
21192121
21202122 /* At this point we know we have a real path component. */
21212123 for(;;) {
fs/namespace.c+6−3
@@ -156,10 +156,10 @@ static inline void mnt_add_count(struct mount *mnt, int n) · 155 unmodified lines
156156 /*
157157 * vfsmount lock must be held for write
158158 */
159−unsigned int mnt_get_count(struct mount *mnt)
159+int mnt_get_count(struct mount *mnt)
160160 {
161161 #ifdef CONFIG_SMP
162− unsigned int count = 0;
162+ int count = 0;
163163 int cpu;
164164
165165 for_each_possible_cpu(cpu) {
@@ -1139,6 +1139,7 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput); · 973 unmodified lines
11391139 static void mntput_no_expire(struct mount *mnt)
11401140 {
11411141 LIST_HEAD(list);
1142+ int count;
11421143
11431144 rcu_read_lock();
11441145 if (likely(READ_ONCE(mnt->mnt_ns))) {
@@ -1162,7 +1163,9 @@ static void mntput_no_expire(struct mount *mnt) · 17 unmodified lines
11621163 */
11631164 smp_mb();
11641165 mnt_add_count(mnt, -1);
1165− if (mnt_get_count(mnt)) {
1166+ count = mnt_get_count(mnt);
1167+ if (count != 0) {
1168+ WARN_ON(count < 0);
11661169 rcu_read_unlock();
11671170 unlock_mount_hash();
11681171 return;
fs/pnode.h+1−1
@@ -44,7 +44,7 @@ int propagate_mount_busy(struct mount *, int); · 43 unmodified lines
4444 void propagate_mount_unlock(struct mount *);
4545 void mnt_release_group_id(struct mount *);
4646 int get_dominating_id(struct mount *mnt, const struct path *root);
47−unsigned int mnt_get_count(struct mount *mnt);
47+int mnt_get_count(struct mount *mnt);
4848 void mnt_set_mountpoint(struct mount *, struct mountpoint *,
4949 struct mount *);
5050 void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
include/linux/fs.h+1−2
@@ -2876,8 +2876,7 @@ extern int inode_needs_sync(struct inode *inode); · 2875 unmodified lines
28762876 extern int generic_delete_inode(struct inode *inode);
28772877 static inline int generic_drop_inode(struct inode *inode)
28782878 {
2879− return !inode->i_nlink || inode_unhashed(inode) ||
2880− (inode->i_state & I_DONTCACHE);
2879+ return !inode->i_nlink || inode_unhashed(inode);
28812880 }
28822881 extern void d_mark_dontcache(struct inode *inode);
28832882

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t