Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull misc dcache updates from Al Viro:
"Most of this pile is putting name length into struct name_snapshot and
making use of it.

The beginning of this series ("ovl_lookup_real_one(): don't bother
with strlen()") ought to have been split in two (separate switch of
name_snapshot to struct qstr from overlayfs reaping the trivial
benefits of that), but I wanted to avoid a rebase - by the time I'd
spotted that it was (a) in -next and (b) close to 5.1-final ;-/"

* 'work.dcache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
audit_compare_dname_path(): switch to const struct qstr *
audit_update_watch(): switch to const struct qstr *
inotify_handle_event(): don't bother with strlen()
fsnotify: switch send_to_group() and ->handle_event to const struct qstr *
fsnotify(): switch to passing const struct qstr * for file_name
switch fsnotify_move() to passing const struct qstr * for old_name
ovl_lookup_real_one(): don't bother with strlen()
sysv: bury the broken "quietly truncate the long filenames" logics
nsfs: unobfuscate
unexport d_alloc_pseudo()

+62 -79
+5
Documentation/filesystems/porting
··· 668 668 DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the 669 669 default. DCACHE_NORCU opts out, and only d_alloc_pseudo() has any 670 670 business doing so. 671 + -- 672 + [mandatory] 673 + d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are 674 + very suspect (and won't work in modules). Such uses are very likely to 675 + be misspelled d_alloc_anon().
+9 -9
fs/dcache.c
··· 284 284 void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry) 285 285 { 286 286 spin_lock(&dentry->d_lock); 287 + name->name = dentry->d_name; 287 288 if (unlikely(dname_external(dentry))) { 288 - struct external_name *p = external_name(dentry); 289 - atomic_inc(&p->u.count); 290 - spin_unlock(&dentry->d_lock); 291 - name->name = p->name; 289 + atomic_inc(&external_name(dentry)->u.count); 292 290 } else { 293 291 memcpy(name->inline_name, dentry->d_iname, 294 292 dentry->d_name.len + 1); 295 - spin_unlock(&dentry->d_lock); 296 - name->name = name->inline_name; 293 + name->name.name = name->inline_name; 297 294 } 295 + spin_unlock(&dentry->d_lock); 298 296 } 299 297 EXPORT_SYMBOL(take_dentry_name_snapshot); 300 298 301 299 void release_dentry_name_snapshot(struct name_snapshot *name) 302 300 { 303 - if (unlikely(name->name != name->inline_name)) { 301 + if (unlikely(name->name.name != name->inline_name)) { 304 302 struct external_name *p; 305 - p = container_of(name->name, struct external_name, name[0]); 303 + p = container_of(name->name.name, struct external_name, name[0]); 306 304 if (unlikely(atomic_dec_and_test(&p->u.count))) 307 305 kfree_rcu(p, u.head); 308 306 } ··· 1740 1742 * never be anyone's children or parents. Unlike all other 1741 1743 * dentries, these will not have RCU delay between dropping the 1742 1744 * last reference and freeing them. 1745 + * 1746 + * The only user is alloc_file_pseudo() and that's what should 1747 + * be considered a public interface. Don't use directly. 1743 1748 */ 1744 1749 struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name) 1745 1750 { ··· 1751 1750 dentry->d_flags |= DCACHE_NORCU; 1752 1751 return dentry; 1753 1752 } 1754 - EXPORT_SYMBOL(d_alloc_pseudo); 1755 1753 1756 1754 struct dentry *d_alloc_name(struct dentry *parent, const char *name) 1757 1755 {
+1 -1
fs/debugfs/inode.c
··· 818 818 goto exit; 819 819 } 820 820 d_move(old_dentry, dentry); 821 - fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name, 821 + fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name, 822 822 d_is_dir(old_dentry), 823 823 NULL, old_dentry); 824 824 release_dentry_name_snapshot(&old_name);
+1
fs/internal.h
··· 155 155 extern int d_set_mounted(struct dentry *dentry); 156 156 extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); 157 157 extern struct dentry *d_alloc_cursor(struct dentry *); 158 + extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); 158 159 159 160 /* 160 161 * read_write.c
+4 -2
fs/kernfs/file.c
··· 885 885 list_for_each_entry(info, &kernfs_root(kn)->supers, node) { 886 886 struct kernfs_node *parent; 887 887 struct inode *inode; 888 + struct qstr name; 888 889 889 890 /* 890 891 * We want fsnotify_modify() on @kn but as the ··· 897 896 if (!inode) 898 897 continue; 899 898 899 + name = (struct qstr)QSTR_INIT(kn->name, strlen(kn->name)); 900 900 parent = kernfs_get_parent(kn); 901 901 if (parent) { 902 902 struct inode *p_inode; ··· 905 903 p_inode = ilookup(info->sb, parent->id.ino); 906 904 if (p_inode) { 907 905 fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD, 908 - inode, FSNOTIFY_EVENT_INODE, kn->name, 0); 906 + inode, FSNOTIFY_EVENT_INODE, &name, 0); 909 907 iput(p_inode); 910 908 } 911 909 ··· 913 911 } 914 912 915 913 fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, 916 - kn->name, 0); 914 + &name, 0); 917 915 iput(inode); 918 916 } 919 917
+2 -2
fs/namei.c
··· 4498 4498 inode_unlock(target); 4499 4499 dput(new_dentry); 4500 4500 if (!error) { 4501 - fsnotify_move(old_dir, new_dir, old_name.name, is_dir, 4501 + fsnotify_move(old_dir, new_dir, &old_name.name, is_dir, 4502 4502 !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry); 4503 4503 if (flags & RENAME_EXCHANGE) { 4504 - fsnotify_move(new_dir, old_dir, old_dentry->d_name.name, 4504 + fsnotify_move(new_dir, old_dir, &old_dentry->d_name, 4505 4505 new_is_dir, NULL, new_dentry); 4506 4506 } 4507 4507 }
+1 -1
fs/notify/dnotify/dnotify.c
··· 81 81 static int dnotify_handle_event(struct fsnotify_group *group, 82 82 struct inode *inode, 83 83 u32 mask, const void *data, int data_type, 84 - const unsigned char *file_name, u32 cookie, 84 + const struct qstr *file_name, u32 cookie, 85 85 struct fsnotify_iter_info *iter_info) 86 86 { 87 87 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
+1 -1
fs/notify/fanotify/fanotify.c
··· 367 367 static int fanotify_handle_event(struct fsnotify_group *group, 368 368 struct inode *inode, 369 369 u32 mask, const void *data, int data_type, 370 - const unsigned char *file_name, u32 cookie, 370 + const struct qstr *file_name, u32 cookie, 371 371 struct fsnotify_iter_info *iter_info) 372 372 { 373 373 int ret = 0;
+4 -4
fs/notify/fsnotify.c
··· 179 179 take_dentry_name_snapshot(&name, dentry); 180 180 if (path) 181 181 ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, 182 - name.name, 0); 182 + &name.name, 0); 183 183 else 184 184 ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 185 - name.name, 0); 185 + &name.name, 0); 186 186 release_dentry_name_snapshot(&name); 187 187 } 188 188 ··· 195 195 static int send_to_group(struct inode *to_tell, 196 196 __u32 mask, const void *data, 197 197 int data_is, u32 cookie, 198 - const unsigned char *file_name, 198 + const struct qstr *file_name, 199 199 struct fsnotify_iter_info *iter_info) 200 200 { 201 201 struct fsnotify_group *group = NULL; ··· 325 325 * notification event in whatever means they feel necessary. 326 326 */ 327 327 int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, 328 - const unsigned char *file_name, u32 cookie) 328 + const struct qstr *file_name, u32 cookie) 329 329 { 330 330 struct fsnotify_iter_info iter_info = {}; 331 331 struct super_block *sb = to_tell->i_sb;
+1 -1
fs/notify/inotify/inotify.h
··· 27 27 extern int inotify_handle_event(struct fsnotify_group *group, 28 28 struct inode *inode, 29 29 u32 mask, const void *data, int data_type, 30 - const unsigned char *file_name, u32 cookie, 30 + const struct qstr *file_name, u32 cookie, 31 31 struct fsnotify_iter_info *iter_info); 32 32 33 33 extern const struct fsnotify_ops inotify_fsnotify_ops;
+3 -3
fs/notify/inotify/inotify_fsnotify.c
··· 67 67 int inotify_handle_event(struct fsnotify_group *group, 68 68 struct inode *inode, 69 69 u32 mask, const void *data, int data_type, 70 - const unsigned char *file_name, u32 cookie, 70 + const struct qstr *file_name, u32 cookie, 71 71 struct fsnotify_iter_info *iter_info) 72 72 { 73 73 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); ··· 89 89 return 0; 90 90 } 91 91 if (file_name) { 92 - len = strlen(file_name); 92 + len = file_name->len; 93 93 alloc_len += len + 1; 94 94 } 95 95 ··· 129 129 event->sync_cookie = cookie; 130 130 event->name_len = len; 131 131 if (len) 132 - strcpy(event->name, file_name); 132 + strcpy(event->name, file_name->name); 133 133 134 134 ret = fsnotify_add_event(group, fsn_event, inotify_merge); 135 135 if (ret) {
+10 -13
fs/nsfs.c
··· 105 105 void *ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb, 106 106 void *private_data) 107 107 { 108 - struct ns_common *ns; 109 108 void *ret; 110 109 111 - again: 112 - ns = ns_get_cb(private_data); 113 - if (!ns) 114 - return ERR_PTR(-ENOENT); 110 + do { 111 + struct ns_common *ns = ns_get_cb(private_data); 112 + if (!ns) 113 + return ERR_PTR(-ENOENT); 115 114 116 - ret = __ns_get_path(path, ns); 117 - if (IS_ERR(ret) && PTR_ERR(ret) == -EAGAIN) 118 - goto again; 115 + ret = __ns_get_path(path, ns); 116 + } while (ret == ERR_PTR(-EAGAIN)); 117 + 119 118 return ret; 120 119 } 121 120 ··· 153 154 if (fd < 0) 154 155 return fd; 155 156 156 - while (1) { 157 + do { 157 158 struct ns_common *relative; 158 159 159 160 relative = get_ns(ns); ··· 163 164 } 164 165 165 166 err = __ns_get_path(&path, relative); 166 - if (IS_ERR(err) && PTR_ERR(err) == -EAGAIN) 167 - continue; 168 - break; 169 - } 167 + } while (err == ERR_PTR(-EAGAIN)); 168 + 170 169 if (IS_ERR(err)) { 171 170 put_unused_fd(fd); 172 171 return PTR_ERR(err);
+1 -1
fs/overlayfs/export.c
··· 398 398 * pointer because we hold no lock on the real dentry. 399 399 */ 400 400 take_dentry_name_snapshot(&name, real); 401 - this = lookup_one_len(name.name, connected, strlen(name.name)); 401 + this = lookup_one_len(name.name.name, connected, name.name.len); 402 402 err = PTR_ERR(this); 403 403 if (IS_ERR(this)) { 404 404 goto fail;
-15
fs/sysv/namei.c
··· 28 28 return err; 29 29 } 30 30 31 - static int sysv_hash(const struct dentry *dentry, struct qstr *qstr) 32 - { 33 - /* Truncate the name in place, avoids having to define a compare 34 - function. */ 35 - if (qstr->len > SYSV_NAMELEN) { 36 - qstr->len = SYSV_NAMELEN; 37 - qstr->hash = full_name_hash(dentry, qstr->name, qstr->len); 38 - } 39 - return 0; 40 - } 41 - 42 - const struct dentry_operations sysv_dentry_operations = { 43 - .d_hash = sysv_hash, 44 - }; 45 - 46 31 static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) 47 32 { 48 33 struct inode * inode = NULL;
-3
fs/sysv/super.c
··· 312 312 313 313 flavour_setup[sbi->s_type](sbi, &sb->s_max_links); 314 314 315 - sbi->s_truncate = 1; 316 315 sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; 317 316 sbi->s_inodes_per_block = bsize >> 6; 318 317 sbi->s_inodes_per_block_1 = (bsize >> 6)-1; ··· 333 334 sb->s_op = &sysv_sops; 334 335 if (sbi->s_forced_ro) 335 336 sb->s_flags |= SB_RDONLY; 336 - if (sbi->s_truncate) 337 - sb->s_d_op = &sysv_dentry_operations; 338 337 root_inode = sysv_iget(sb, SYSV_ROOT_INO); 339 338 if (IS_ERR(root_inode)) { 340 339 printk("SysV FS: get root inode failed\n");
-3
fs/sysv/sysv.h
··· 23 23 struct super_block *s_sb; /* VFS superblock */ 24 24 int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */ 25 25 char s_bytesex; /* bytesex (le/be/pdp) */ 26 - char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */ 27 - /* if 0: they are disallowed (ENAMETOOLONG) */ 28 26 unsigned int s_inodes_per_block; /* number of inodes per block */ 29 27 unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ 30 28 unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ ··· 164 166 extern const struct file_operations sysv_dir_operations; 165 167 extern const struct address_space_operations sysv_aops; 166 168 extern const struct super_operations sysv_sops; 167 - extern const struct dentry_operations sysv_dentry_operations; 168 169 169 170 170 171 enum {
+1 -2
include/linux/dcache.h
··· 235 235 /* allocate/de-allocate */ 236 236 extern struct dentry * d_alloc(struct dentry *, const struct qstr *); 237 237 extern struct dentry * d_alloc_anon(struct super_block *); 238 - extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); 239 238 extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, 240 239 wait_queue_head_t *); 241 240 extern struct dentry * d_splice_alias(struct inode *, struct dentry *); ··· 593 594 } 594 595 595 596 struct name_snapshot { 596 - const unsigned char *name; 597 + struct qstr name; 597 598 unsigned char inline_name[DNAME_INLINE_LEN]; 598 599 }; 599 600 void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
+5 -5
include/linux/fsnotify.h
··· 27 27 __u32 mask) 28 28 { 29 29 return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE, 30 - dentry->d_name.name, 0); 30 + &dentry->d_name, 0); 31 31 } 32 32 33 33 /* Notify this dentry's parent about a child's events. */ ··· 102 102 * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir 103 103 */ 104 104 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, 105 - const unsigned char *old_name, 105 + const struct qstr *old_name, 106 106 int isdir, struct inode *target, 107 107 struct dentry *moved) 108 108 { ··· 111 111 __u32 old_dir_mask = FS_MOVED_FROM; 112 112 __u32 new_dir_mask = FS_MOVED_TO; 113 113 __u32 mask = FS_MOVE_SELF; 114 - const unsigned char *new_name = moved->d_name.name; 114 + const struct qstr *new_name = &moved->d_name; 115 115 116 116 if (old_dir == new_dir) 117 117 old_dir_mask |= FS_DN_RENAME; ··· 178 178 take_dentry_name_snapshot(&name, dentry); 179 179 180 180 fsnotify(d_inode(parent), mask, d_inode(dentry), FSNOTIFY_EVENT_INODE, 181 - name.name, 0); 181 + &name.name, 0); 182 182 183 183 release_dentry_name_snapshot(&name); 184 184 dput(parent); ··· 218 218 fsnotify_link_count(inode); 219 219 audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE); 220 220 221 - fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0); 221 + fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0); 222 222 } 223 223 224 224 /*
+3 -3
include/linux/fsnotify_backend.h
··· 117 117 int (*handle_event)(struct fsnotify_group *group, 118 118 struct inode *inode, 119 119 u32 mask, const void *data, int data_type, 120 - const unsigned char *file_name, u32 cookie, 120 + const struct qstr *file_name, u32 cookie, 121 121 struct fsnotify_iter_info *iter_info); 122 122 void (*free_group_priv)(struct fsnotify_group *group); 123 123 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); ··· 350 350 351 351 /* main fsnotify call to send events */ 352 352 extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, 353 - const unsigned char *name, u32 cookie); 353 + const struct qstr *name, u32 cookie); 354 354 extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask); 355 355 extern void __fsnotify_inode_delete(struct inode *inode); 356 356 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); ··· 505 505 #else 506 506 507 507 static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, 508 - const unsigned char *name, u32 cookie) 508 + const struct qstr *name, u32 cookie) 509 509 { 510 510 return 0; 511 511 }
+1 -1
kernel/audit.h
··· 231 231 extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); 232 232 extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); 233 233 extern int parent_len(const char *path); 234 - extern int audit_compare_dname_path(const char *dname, const char *path, int plen); 234 + extern int audit_compare_dname_path(const struct qstr *dname, const char *path, int plen); 235 235 extern struct sk_buff *audit_make_reply(int seq, int type, int done, int multi, 236 236 const void *payload, int size); 237 237 extern void audit_panic(const char *message);
+1 -1
kernel/audit_fsnotify.c
··· 164 164 static int audit_mark_handle_event(struct fsnotify_group *group, 165 165 struct inode *to_tell, 166 166 u32 mask, const void *data, int data_type, 167 - const unsigned char *dname, u32 cookie, 167 + const struct qstr *dname, u32 cookie, 168 168 struct fsnotify_iter_info *iter_info) 169 169 { 170 170 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
+1 -1
kernel/audit_tree.c
··· 1040 1040 static int audit_tree_handle_event(struct fsnotify_group *group, 1041 1041 struct inode *to_tell, 1042 1042 u32 mask, const void *data, int data_type, 1043 - const unsigned char *file_name, u32 cookie, 1043 + const struct qstr *file_name, u32 cookie, 1044 1044 struct fsnotify_iter_info *iter_info) 1045 1045 { 1046 1046 return 0;
+2 -2
kernel/audit_watch.c
··· 255 255 256 256 /* Update inode info in audit rules based on filesystem event. */ 257 257 static void audit_update_watch(struct audit_parent *parent, 258 - const char *dname, dev_t dev, 258 + const struct qstr *dname, dev_t dev, 259 259 unsigned long ino, unsigned invalidating) 260 260 { 261 261 struct audit_watch *owatch, *nwatch, *nextw; ··· 482 482 static int audit_watch_handle_event(struct fsnotify_group *group, 483 483 struct inode *to_tell, 484 484 u32 mask, const void *data, int data_type, 485 - const unsigned char *dname, u32 cookie, 485 + const struct qstr *dname, u32 cookie, 486 486 struct fsnotify_iter_info *iter_info) 487 487 { 488 488 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
+3 -3
kernel/auditfilter.c
··· 1292 1292 * @parentlen: length of the parent if known. Passing in AUDIT_NAME_FULL 1293 1293 * here indicates that we must compute this value. 1294 1294 */ 1295 - int audit_compare_dname_path(const char *dname, const char *path, int parentlen) 1295 + int audit_compare_dname_path(const struct qstr *dname, const char *path, int parentlen) 1296 1296 { 1297 1297 int dlen, pathlen; 1298 1298 const char *p; 1299 1299 1300 - dlen = strlen(dname); 1300 + dlen = dname->len; 1301 1301 pathlen = strlen(path); 1302 1302 if (pathlen < dlen) 1303 1303 return 1; ··· 1308 1308 1309 1309 p = path + parentlen; 1310 1310 1311 - return strncmp(p, dname, dlen); 1311 + return strncmp(p, dname->name, dlen); 1312 1312 } 1313 1313 1314 1314 int audit_filter(int msgtype, unsigned int listtype)
+2 -2
kernel/auditsc.c
··· 2047 2047 { 2048 2048 struct audit_context *context = audit_context(); 2049 2049 struct inode *inode = d_backing_inode(dentry); 2050 - const char *dname = dentry->d_name.name; 2050 + const struct qstr *dname = &dentry->d_name; 2051 2051 struct audit_names *n, *found_parent = NULL, *found_child = NULL; 2052 2052 struct audit_entry *e; 2053 2053 struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS]; ··· 2099 2099 (n->type != type && n->type != AUDIT_TYPE_UNKNOWN)) 2100 2100 continue; 2101 2101 2102 - if (!strcmp(dname, n->name->name) || 2102 + if (!strcmp(dname->name, n->name->name) || 2103 2103 !audit_compare_dname_path(dname, n->name->name, 2104 2104 found_parent ? 2105 2105 found_parent->name_len :