tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/viro/vfs.git fixes head: 123a084a6b2a8c93285976f28b61bd30ea4368d9 commit: 123a084a6b2a8c93285976f28b61bd30ea4368d9 [2/2] Fix the locking in dcache_readdir() and friends config: i386-defconfig (attached as .config) compiler: gcc-7 (Debian 7.4.0-11) 7.4.0 reproduce: git checkout 123a084a6b2a8c93285976f28b61bd30ea4368d9 # save the attached .config to linux build tree make ARCH=i386 If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@xxxxxxxxx> All error/warnings (new ones prefixed by >>): In file included from include/linux/dcache.h:13:0, from include/linux/fs.h:8, from include/linux/huge_mm.h:8, from include/linux/mm.h:587, from include/linux/bvec.h:13, from include/linux/blk_types.h:10, from include/linux/genhd.h:19, from include/linux/blkdev.h:11, from fs/libfs.c:7: fs/libfs.c: In function 'scan_positives': >> include/linux/lockref.h:47:33: error: 'lock' undeclared (first use in this function); did you mean 'sock'? lockref_get(((void)(subclass),(lock))) ^ >> fs/libfs.c:113:4: note: in expansion of macro 'lockref_get_nested' lockref_get_nested(&d->d_lockref, DENTRY_D_LOCK_NESTED); ^~~~~~~~~~~~~~~~~~ include/linux/lockref.h:47:33: note: each undeclared identifier is reported only once for each function it appears in lockref_get(((void)(subclass),(lock))) ^ >> fs/libfs.c:113:4: note: in expansion of macro 'lockref_get_nested' lockref_get_nested(&d->d_lockref, DENTRY_D_LOCK_NESTED); ^~~~~~~~~~~~~~~~~~ vim +/lockref_get_nested +113 fs/libfs.c > 7 #include <linux/blkdev.h> 8 #include <linux/export.h> 9 #include <linux/pagemap.h> 10 #include <linux/slab.h> 11 #include <linux/cred.h> 12 #include <linux/mount.h> 13 #include <linux/vfs.h> 14 #include <linux/quotaops.h> 15 #include <linux/mutex.h> 16 #include <linux/namei.h> 17 #include <linux/exportfs.h> 18 #include <linux/writeback.h> 19 #include <linux/buffer_head.h> /* sync_mapping_buffers */ 20 #include <linux/fs_context.h> 21 #include <linux/pseudo_fs.h> 22 23 #include <linux/uaccess.h> 24 25 #include "internal.h" 26 27 int simple_getattr(const struct path *path, struct kstat *stat, 28 u32 request_mask, unsigned int query_flags) 29 { 30 struct inode *inode = d_inode(path->dentry); 31 generic_fillattr(inode, stat); 32 stat->blocks = inode->i_mapping->nrpages << (PAGE_SHIFT - 9); 33 return 0; 34 } 35 EXPORT_SYMBOL(simple_getattr); 36 37 int simple_statfs(struct dentry *dentry, struct kstatfs *buf) 38 { 39 buf->f_type = dentry->d_sb->s_magic; 40 buf->f_bsize = PAGE_SIZE; 41 buf->f_namelen = NAME_MAX; 42 return 0; 43 } 44 EXPORT_SYMBOL(simple_statfs); 45 46 /* 47 * Retaining negative dentries for an in-memory filesystem just wastes 48 * memory and lookup time: arrange for them to be deleted immediately. 49 */ 50 int always_delete_dentry(const struct dentry *dentry) 51 { 52 return 1; 53 } 54 EXPORT_SYMBOL(always_delete_dentry); 55 56 const struct dentry_operations simple_dentry_operations = { 57 .d_delete = always_delete_dentry, 58 }; 59 EXPORT_SYMBOL(simple_dentry_operations); 60 61 /* 62 * Lookup the data. This is trivial - if the dentry didn't already 63 * exist, we know it is negative. Set d_op to delete negative dentries. 64 */ 65 struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) 66 { 67 if (dentry->d_name.len > NAME_MAX) 68 return ERR_PTR(-ENAMETOOLONG); 69 if (!dentry->d_sb->s_d_op) 70 d_set_d_op(dentry, &simple_dentry_operations); 71 d_add(dentry, NULL); 72 return NULL; 73 } 74 EXPORT_SYMBOL(simple_lookup); 75 76 int dcache_dir_open(struct inode *inode, struct file *file) 77 { 78 file->private_data = d_alloc_cursor(file->f_path.dentry); 79 80 return file->private_data ? 0 : -ENOMEM; 81 } 82 EXPORT_SYMBOL(dcache_dir_open); 83 84 int dcache_dir_close(struct inode *inode, struct file *file) 85 { 86 dput(file->private_data); 87 return 0; 88 } 89 EXPORT_SYMBOL(dcache_dir_close); 90 91 /* parent is locked at least shared */ 92 /* 93 * Returns an element of siblings' list. 94 * We are looking for <count>th positive after <p>; if 95 * found, dentry is grabbed and passed to caller via *<res>. 96 * If no such element exists, the anchor of list is returned 97 * and *<res> is set to NULL. 98 */ 99 static struct list_head *scan_positives(struct dentry *cursor, 100 struct list_head *p, 101 loff_t count, 102 struct dentry **res) 103 { 104 struct dentry *dentry = cursor->d_parent, *found = NULL; 105 106 spin_lock(&dentry->d_lock); 107 while ((p = p->next) != &dentry->d_subdirs) { 108 struct dentry *d = list_entry(p, struct dentry, d_child); 109 // we must at least skip cursors, to avoid livelocks 110 if (d->d_flags & DCACHE_DENTRY_CURSOR) 111 continue; 112 if (simple_positive(d) && !--count) { > 113 lockref_get_nested(&d->d_lockref, DENTRY_D_LOCK_NESTED); 114 found = d; 115 break; 116 } 117 if (need_resched()) { 118 list_move(&cursor->d_child, p); 119 p = &cursor->d_child; 120 spin_unlock(&dentry->d_lock); 121 cond_resched(); 122 spin_lock(&dentry->d_lock); 123 } 124 } 125 spin_unlock(&dentry->d_lock); 126 dput(*res); 127 *res = found; 128 return p; 129 } 130 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip