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

kill ->dir_notify()

Remove the hopelessly misguided ->dir_notify(). The only instance (cifs)
has been broken by design from the very beginning; the objects it creates
are never destroyed, keep references to struct file they can outlive, nothing
that could possibly evict them exists on close(2) path *and* no locking
whatsoever is done to prevent races with close(), should the previous, er,
deficiencies someday be dealt with.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 6badd79b b6b3fdea

+1 -142
-2
Documentation/filesystems/Locking
··· 394 394 unsigned long (*get_unmapped_area)(struct file *, unsigned long, 395 395 unsigned long, unsigned long, unsigned long); 396 396 int (*check_flags)(int); 397 - int (*dir_notify)(struct file *, unsigned long); 398 397 }; 399 398 400 399 locking rules: ··· 423 424 sendpage: no 424 425 get_unmapped_area: no 425 426 check_flags: no 426 - dir_notify: no 427 427 428 428 ->llseek() locking has moved from llseek to the individual llseek 429 429 implementations. If your fs is not using generic_file_llseek, you
-3
Documentation/filesystems/vfs.txt
··· 733 733 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 734 734 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 735 735 int (*check_flags)(int); 736 - int (*dir_notify)(struct file *filp, unsigned long arg); 737 736 int (*flock) (struct file *, int, struct file_lock *); 738 737 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); 739 738 ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); ··· 798 799 get_unmapped_area: called by the mmap(2) system call 799 800 800 801 check_flags: called by the fcntl(2) system call for F_SETFL command 801 - 802 - dir_notify: called by the fcntl(2) system call for F_NOTIFY command 803 802 804 803 flock: called by the flock(2) system call 805 804
-6
fs/bad_inode.c
··· 132 132 return -EIO; 133 133 } 134 134 135 - static int bad_file_dir_notify(struct file *file, unsigned long arg) 136 - { 137 - return -EIO; 138 - } 139 - 140 135 static int bad_file_flock(struct file *filp, int cmd, struct file_lock *fl) 141 136 { 142 137 return -EIO; ··· 174 179 .sendpage = bad_file_sendpage, 175 180 .get_unmapped_area = bad_file_get_unmapped_area, 176 181 .check_flags = bad_file_check_flags, 177 - .dir_notify = bad_file_dir_notify, 178 182 .flock = bad_file_flock, 179 183 .splice_write = bad_file_splice_write, 180 184 .splice_read = bad_file_splice_read,
+1 -1
fs/cifs/Makefile
··· 5 5 6 6 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 7 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 8 - md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o \ 8 + md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 9 9 readdir.o ioctl.o sess.o export.o cifsacl.o 10 10 11 11 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
-7
fs/cifs/cifsfs.c
··· 747 747 #endif /* CONFIG_CIFS_POSIX */ 748 748 749 749 #ifdef CONFIG_CIFS_EXPERIMENTAL 750 - .dir_notify = cifs_dir_notify, 751 750 .setlease = cifs_setlease, 752 751 #endif /* CONFIG_CIFS_EXPERIMENTAL */ 753 752 }; ··· 767 768 #endif /* CONFIG_CIFS_POSIX */ 768 769 .llseek = cifs_llseek, 769 770 #ifdef CONFIG_CIFS_EXPERIMENTAL 770 - .dir_notify = cifs_dir_notify, 771 771 .setlease = cifs_setlease, 772 772 #endif /* CONFIG_CIFS_EXPERIMENTAL */ 773 773 }; ··· 787 789 #endif /* CONFIG_CIFS_POSIX */ 788 790 789 791 #ifdef CONFIG_CIFS_EXPERIMENTAL 790 - .dir_notify = cifs_dir_notify, 791 792 .setlease = cifs_setlease, 792 793 #endif /* CONFIG_CIFS_EXPERIMENTAL */ 793 794 }; ··· 806 809 #endif /* CONFIG_CIFS_POSIX */ 807 810 .llseek = cifs_llseek, 808 811 #ifdef CONFIG_CIFS_EXPERIMENTAL 809 - .dir_notify = cifs_dir_notify, 810 812 .setlease = cifs_setlease, 811 813 #endif /* CONFIG_CIFS_EXPERIMENTAL */ 812 814 }; ··· 814 818 .readdir = cifs_readdir, 815 819 .release = cifs_closedir, 816 820 .read = generic_read_dir, 817 - #ifdef CONFIG_CIFS_EXPERIMENTAL 818 - .dir_notify = cifs_dir_notify, 819 - #endif /* CONFIG_CIFS_EXPERIMENTAL */ 820 821 .unlocked_ioctl = cifs_ioctl, 821 822 .llseek = generic_file_llseek, 822 823 };
-1
fs/cifs/cifsfs.h
··· 76 76 extern const struct file_operations cifs_dir_ops; 77 77 extern int cifs_dir_open(struct inode *inode, struct file *file); 78 78 extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir); 79 - extern int cifs_dir_notify(struct file *, unsigned long arg); 80 79 81 80 /* Functions related to dir entries */ 82 81 extern struct dentry_operations cifs_dentry_ops;
-118
fs/cifs/fcntl.c
··· 1 - /* 2 - * fs/cifs/fcntl.c 3 - * 4 - * vfs operations that deal with the file control API 5 - * 6 - * Copyright (C) International Business Machines Corp., 2003,2004 7 - * Author(s): Steve French (sfrench@us.ibm.com) 8 - * 9 - * This library is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU Lesser General Public License as published 11 - * by the Free Software Foundation; either version 2.1 of the License, or 12 - * (at your option) any later version. 13 - * 14 - * This library is distributed in the hope that it will be useful, 15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 - * the GNU Lesser General Public License for more details. 18 - * 19 - * You should have received a copy of the GNU Lesser General Public License 20 - * along with this library; if not, write to the Free Software 21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 - */ 23 - #include <linux/fs.h> 24 - #include <linux/stat.h> 25 - #include <linux/fcntl.h> 26 - #include "cifsglob.h" 27 - #include "cifsproto.h" 28 - #include "cifs_unicode.h" 29 - #include "cifs_debug.h" 30 - #include "cifsfs.h" 31 - 32 - static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) 33 - { 34 - __u32 cifs_ntfy_flags = 0; 35 - 36 - /* No way on Linux VFS to ask to monitor xattr 37 - changes (and no stream support either */ 38 - if (fcntl_notify_flags & DN_ACCESS) 39 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; 40 - if (fcntl_notify_flags & DN_MODIFY) { 41 - /* What does this mean on directories? */ 42 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | 43 - FILE_NOTIFY_CHANGE_SIZE; 44 - } 45 - if (fcntl_notify_flags & DN_CREATE) { 46 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | 47 - FILE_NOTIFY_CHANGE_LAST_WRITE; 48 - } 49 - if (fcntl_notify_flags & DN_DELETE) 50 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; 51 - if (fcntl_notify_flags & DN_RENAME) { 52 - /* BB review this - checking various server behaviors */ 53 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | 54 - FILE_NOTIFY_CHANGE_FILE_NAME; 55 - } 56 - if (fcntl_notify_flags & DN_ATTRIB) { 57 - cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY | 58 - FILE_NOTIFY_CHANGE_ATTRIBUTES; 59 - } 60 - /* if (fcntl_notify_flags & DN_MULTISHOT) { 61 - cifs_ntfy_flags |= ; 62 - } */ /* BB fixme - not sure how to handle this with CIFS yet */ 63 - 64 - return cifs_ntfy_flags; 65 - } 66 - 67 - int cifs_dir_notify(struct file *file, unsigned long arg) 68 - { 69 - int xid; 70 - int rc = -EINVAL; 71 - int oplock = 0; 72 - struct cifs_sb_info *cifs_sb; 73 - struct cifsTconInfo *pTcon; 74 - char *full_path = NULL; 75 - __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; 76 - __u16 netfid; 77 - 78 - if (experimEnabled == 0) 79 - return 0; 80 - 81 - xid = GetXid(); 82 - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 83 - pTcon = cifs_sb->tcon; 84 - 85 - full_path = build_path_from_dentry(file->f_path.dentry); 86 - 87 - if (full_path == NULL) { 88 - rc = -ENOMEM; 89 - } else { 90 - cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg)); 91 - rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 92 - GENERIC_READ | SYNCHRONIZE, 0 /* create options */, 93 - &netfid, &oplock, NULL, cifs_sb->local_nls, 94 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 95 - /* BB fixme - add this handle to a notify handle list */ 96 - if (rc) { 97 - cFYI(1, ("Could not open directory for notify")); 98 - } else { 99 - filter = convert_to_cifs_notify_flags(arg); 100 - if (filter != 0) { 101 - rc = CIFSSMBNotify(xid, pTcon, 102 - 0 /* no subdirs */, netfid, 103 - filter, file, arg & DN_MULTISHOT, 104 - cifs_sb->local_nls); 105 - } else { 106 - rc = -EINVAL; 107 - } 108 - /* BB add code to close file eventually (at unmount 109 - it would close automatically but may be a way 110 - to do it easily when inode freed or when 111 - notify info is cleared/changed */ 112 - cFYI(1, ("notify rc %d", rc)); 113 - } 114 - } 115 - 116 - FreeXid(xid); 117 - return rc; 118 - }
-3
fs/dnotify.c
··· 115 115 dn->dn_next = inode->i_dnotify; 116 116 inode->i_dnotify = dn; 117 117 spin_unlock(&inode->i_lock); 118 - 119 - if (filp->f_op && filp->f_op->dir_notify) 120 - return filp->f_op->dir_notify(filp, arg); 121 118 return 0; 122 119 123 120 out_free:
-1
include/linux/fs.h
··· 1309 1309 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1310 1310 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1311 1311 int (*check_flags)(int); 1312 - int (*dir_notify)(struct file *filp, unsigned long arg); 1313 1312 int (*flock) (struct file *, int, struct file_lock *); 1314 1313 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 1315 1314 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);