diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-31 18:57:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-31 18:57:56 -0500 |
commit | b58602a4bac012b5f4fc12fe6b46ab237b610d5d (patch) | |
tree | 38929e210a723f67fe2b945f37264bf3aae3c2c4 /fs | |
parent | db200df0b3530f673d8e9f5bd535e9e10305842a (diff) | |
parent | 1f3403fa640f9f7b135dee79f2d39d01c8ad4a08 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (34 commits)
nfsd race fixes: jfs
nfsd race fixes: reiserfs
nfsd race fixes: ext4
nfsd race fixes: ext3
nfsd race fixes: ext2
nfsd/create race fixes, infrastructure
filesystem notification: create fs/notify to contain all fs notification
fs/block_dev.c: __read_mostly improvement and sb_is_blkdev_sb utilization
kill ->dir_notify()
filp_cachep can be static in fs/file_table.c
fix f_count description in Documentation/filesystems/files.txt
make INIT_FS use the __RW_LOCK_UNLOCKED initialization
take init_fs to saner place
kill vfs_permission
pass a struct path * to may_open
kill walk_init_root
remove incorrect comment in inode_permission
expand some comments (d_path / seq_path)
correct wrong function name of d_put in kernel document and source comment
fix switch_names() breakage in short-to-short case
...
Diffstat (limited to 'fs')
44 files changed, 385 insertions, 292 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 522469a7eca3..ff0e81980207 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -270,44 +270,7 @@ config OCFS2_COMPAT_JBD | |||
270 | 270 | ||
271 | endif # BLOCK | 271 | endif # BLOCK |
272 | 272 | ||
273 | config DNOTIFY | 273 | source "fs/notify/Kconfig" |
274 | bool "Dnotify support" | ||
275 | default y | ||
276 | help | ||
277 | Dnotify is a directory-based per-fd file change notification system | ||
278 | that uses signals to communicate events to user-space. There exist | ||
279 | superior alternatives, but some applications may still rely on | ||
280 | dnotify. | ||
281 | |||
282 | If unsure, say Y. | ||
283 | |||
284 | config INOTIFY | ||
285 | bool "Inotify file change notification support" | ||
286 | default y | ||
287 | ---help--- | ||
288 | Say Y here to enable inotify support. Inotify is a file change | ||
289 | notification system and a replacement for dnotify. Inotify fixes | ||
290 | numerous shortcomings in dnotify and introduces several new features | ||
291 | including multiple file events, one-shot support, and unmount | ||
292 | notification. | ||
293 | |||
294 | For more information, see <file:Documentation/filesystems/inotify.txt> | ||
295 | |||
296 | If unsure, say Y. | ||
297 | |||
298 | config INOTIFY_USER | ||
299 | bool "Inotify support for userspace" | ||
300 | depends on INOTIFY | ||
301 | default y | ||
302 | ---help--- | ||
303 | Say Y here to enable inotify support for userspace, including the | ||
304 | associated system calls. Inotify allows monitoring of both files and | ||
305 | directories via a single open fd. Events are read from the file | ||
306 | descriptor, which is also select()- and poll()-able. | ||
307 | |||
308 | For more information, see <file:Documentation/filesystems/inotify.txt> | ||
309 | |||
310 | If unsure, say Y. | ||
311 | 274 | ||
312 | config QUOTA | 275 | config QUOTA |
313 | bool "Quota support" | 276 | bool "Quota support" |
diff --git a/fs/Makefile b/fs/Makefile index d9f8afe6f0c4..e6f423d1d228 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -20,8 +20,7 @@ obj-y += no-block.o | |||
20 | endif | 20 | endif |
21 | 21 | ||
22 | obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o | 22 | obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o |
23 | obj-$(CONFIG_INOTIFY) += inotify.o | 23 | obj-y += notify/ |
24 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o | ||
25 | obj-$(CONFIG_EPOLL) += eventpoll.o | 24 | obj-$(CONFIG_EPOLL) += eventpoll.o |
26 | obj-$(CONFIG_ANON_INODES) += anon_inodes.o | 25 | obj-$(CONFIG_ANON_INODES) += anon_inodes.o |
27 | obj-$(CONFIG_SIGNALFD) += signalfd.o | 26 | obj-$(CONFIG_SIGNALFD) += signalfd.o |
@@ -57,8 +56,6 @@ obj-$(CONFIG_QFMT_V1) += quota_v1.o | |||
57 | obj-$(CONFIG_QFMT_V2) += quota_v2.o | 56 | obj-$(CONFIG_QFMT_V2) += quota_v2.o |
58 | obj-$(CONFIG_QUOTACTL) += quota.o | 57 | obj-$(CONFIG_QUOTACTL) += quota.o |
59 | 58 | ||
60 | obj-$(CONFIG_DNOTIFY) += dnotify.o | ||
61 | |||
62 | obj-$(CONFIG_PROC_FS) += proc/ | 59 | obj-$(CONFIG_PROC_FS) += proc/ |
63 | obj-y += partitions/ | 60 | obj-y += partitions/ |
64 | obj-$(CONFIG_SYSFS) += sysfs/ | 61 | obj-$(CONFIG_SYSFS) += sysfs/ |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 5f1538c03b1b..a05287a23f62 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -132,11 +132,6 @@ static int bad_file_check_flags(int flags) | |||
132 | return -EIO; | 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 | static int bad_file_flock(struct file *filp, int cmd, struct file_lock *fl) | 135 | static int bad_file_flock(struct file *filp, int cmd, struct file_lock *fl) |
141 | { | 136 | { |
142 | return -EIO; | 137 | return -EIO; |
@@ -179,7 +174,6 @@ static const struct file_operations bad_file_ops = | |||
179 | .sendpage = bad_file_sendpage, | 174 | .sendpage = bad_file_sendpage, |
180 | .get_unmapped_area = bad_file_get_unmapped_area, | 175 | .get_unmapped_area = bad_file_get_unmapped_area, |
181 | .check_flags = bad_file_check_flags, | 176 | .check_flags = bad_file_check_flags, |
182 | .dir_notify = bad_file_dir_notify, | ||
183 | .flock = bad_file_flock, | 177 | .flock = bad_file_flock, |
184 | .splice_write = bad_file_splice_write, | 178 | .splice_write = bad_file_splice_write, |
185 | .splice_read = bad_file_splice_read, | 179 | .splice_read = bad_file_splice_read, |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index b6dfee37c7b7..d06cb023ad02 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -378,7 +378,8 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
378 | inode->i_size = 0; | 378 | inode->i_size = 0; |
379 | inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE; | 379 | inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE; |
380 | strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink, | 380 | strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink, |
381 | BEFS_SYMLINK_LEN); | 381 | BEFS_SYMLINK_LEN - 1); |
382 | befs_ino->i_data.symlink[BEFS_SYMLINK_LEN - 1] = '\0'; | ||
382 | } else { | 383 | } else { |
383 | int num_blks; | 384 | int num_blks; |
384 | 385 | ||
@@ -477,6 +478,8 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
477 | kfree(link); | 478 | kfree(link); |
478 | befs_error(sb, "Failed to read entire long symlink"); | 479 | befs_error(sb, "Failed to read entire long symlink"); |
479 | link = ERR_PTR(-EIO); | 480 | link = ERR_PTR(-EIO); |
481 | } else { | ||
482 | link[len - 1] = '\0'; | ||
480 | } | 483 | } |
481 | } else { | 484 | } else { |
482 | link = befs_ino->i_data.symlink; | 485 | link = befs_ino->i_data.symlink; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 99e0ae1a4c78..349a26c10001 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -326,12 +326,13 @@ static struct file_system_type bd_type = { | |||
326 | .kill_sb = kill_anon_super, | 326 | .kill_sb = kill_anon_super, |
327 | }; | 327 | }; |
328 | 328 | ||
329 | static struct vfsmount *bd_mnt __read_mostly; | 329 | struct super_block *blockdev_superblock __read_mostly; |
330 | struct super_block *blockdev_superblock; | ||
331 | 330 | ||
332 | void __init bdev_cache_init(void) | 331 | void __init bdev_cache_init(void) |
333 | { | 332 | { |
334 | int err; | 333 | int err; |
334 | struct vfsmount *bd_mnt; | ||
335 | |||
335 | bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), | 336 | bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode), |
336 | 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| | 337 | 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| |
337 | SLAB_MEM_SPREAD|SLAB_PANIC), | 338 | SLAB_MEM_SPREAD|SLAB_PANIC), |
@@ -373,7 +374,7 @@ struct block_device *bdget(dev_t dev) | |||
373 | struct block_device *bdev; | 374 | struct block_device *bdev; |
374 | struct inode *inode; | 375 | struct inode *inode; |
375 | 376 | ||
376 | inode = iget5_locked(bd_mnt->mnt_sb, hash(dev), | 377 | inode = iget5_locked(blockdev_superblock, hash(dev), |
377 | bdev_test, bdev_set, &dev); | 378 | bdev_test, bdev_set, &dev); |
378 | 379 | ||
379 | if (!inode) | 380 | if (!inode) |
@@ -463,7 +464,7 @@ void bd_forget(struct inode *inode) | |||
463 | 464 | ||
464 | spin_lock(&bdev_lock); | 465 | spin_lock(&bdev_lock); |
465 | if (inode->i_bdev) { | 466 | if (inode->i_bdev) { |
466 | if (inode->i_sb != blockdev_superblock) | 467 | if (!sb_is_blkdev_sb(inode->i_sb)) |
467 | bdev = inode->i_bdev; | 468 | bdev = inode->i_bdev; |
468 | __bd_forget(inode); | 469 | __bd_forget(inode); |
469 | } | 470 | } |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index 6ba43fb346fb..9948c0030e86 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -5,7 +5,7 @@ obj-$(CONFIG_CIFS) += cifs.o | |||
5 | 5 | ||
6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ | 6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ |
7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ | 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 | readdir.o ioctl.o sess.o export.o cifsacl.o | 9 | readdir.o ioctl.o sess.o export.o cifsacl.o |
10 | 10 | ||
11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | 11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0005a194a75c..13ea53251dcf 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -747,7 +747,6 @@ const struct file_operations cifs_file_ops = { | |||
747 | #endif /* CONFIG_CIFS_POSIX */ | 747 | #endif /* CONFIG_CIFS_POSIX */ |
748 | 748 | ||
749 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 749 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
750 | .dir_notify = cifs_dir_notify, | ||
751 | .setlease = cifs_setlease, | 750 | .setlease = cifs_setlease, |
752 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 751 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
753 | }; | 752 | }; |
@@ -768,7 +767,6 @@ const struct file_operations cifs_file_direct_ops = { | |||
768 | #endif /* CONFIG_CIFS_POSIX */ | 767 | #endif /* CONFIG_CIFS_POSIX */ |
769 | .llseek = cifs_llseek, | 768 | .llseek = cifs_llseek, |
770 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 769 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
771 | .dir_notify = cifs_dir_notify, | ||
772 | .setlease = cifs_setlease, | 770 | .setlease = cifs_setlease, |
773 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 771 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
774 | }; | 772 | }; |
@@ -789,7 +787,6 @@ const struct file_operations cifs_file_nobrl_ops = { | |||
789 | #endif /* CONFIG_CIFS_POSIX */ | 787 | #endif /* CONFIG_CIFS_POSIX */ |
790 | 788 | ||
791 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 789 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
792 | .dir_notify = cifs_dir_notify, | ||
793 | .setlease = cifs_setlease, | 790 | .setlease = cifs_setlease, |
794 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 791 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
795 | }; | 792 | }; |
@@ -809,7 +806,6 @@ const struct file_operations cifs_file_direct_nobrl_ops = { | |||
809 | #endif /* CONFIG_CIFS_POSIX */ | 806 | #endif /* CONFIG_CIFS_POSIX */ |
810 | .llseek = cifs_llseek, | 807 | .llseek = cifs_llseek, |
811 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 808 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
812 | .dir_notify = cifs_dir_notify, | ||
813 | .setlease = cifs_setlease, | 809 | .setlease = cifs_setlease, |
814 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 810 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
815 | }; | 811 | }; |
@@ -818,9 +814,6 @@ const struct file_operations cifs_dir_ops = { | |||
818 | .readdir = cifs_readdir, | 814 | .readdir = cifs_readdir, |
819 | .release = cifs_closedir, | 815 | .release = cifs_closedir, |
820 | .read = generic_read_dir, | 816 | .read = generic_read_dir, |
821 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
822 | .dir_notify = cifs_dir_notify, | ||
823 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
824 | .unlocked_ioctl = cifs_ioctl, | 817 | .unlocked_ioctl = cifs_ioctl, |
825 | .llseek = generic_file_llseek, | 818 | .llseek = generic_file_llseek, |
826 | }; | 819 | }; |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 2ce04c73d74e..7ac481841f87 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -76,7 +76,6 @@ extern int cifs_file_mmap(struct file * , struct vm_area_struct *); | |||
76 | extern const struct file_operations cifs_dir_ops; | 76 | extern const struct file_operations cifs_dir_ops; |
77 | extern int cifs_dir_open(struct inode *inode, struct file *file); | 77 | extern int cifs_dir_open(struct inode *inode, struct file *file); |
78 | extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir); | 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 | /* Functions related to dir entries */ | 80 | /* Functions related to dir entries */ |
82 | extern struct dentry_operations cifs_dentry_ops; | 81 | extern struct dentry_operations cifs_dentry_ops; |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c deleted file mode 100644 index 5a57581eb4b2..000000000000 --- a/fs/cifs/fcntl.c +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
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 | } | ||
diff --git a/fs/dcache.c b/fs/dcache.c index a1d86c7f3e66..e88c23b85a32 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/bootmem.h> | 34 | #include <linux/bootmem.h> |
35 | #include "internal.h" | 35 | #include "internal.h" |
36 | 36 | ||
37 | |||
38 | int sysctl_vfs_cache_pressure __read_mostly = 100; | 37 | int sysctl_vfs_cache_pressure __read_mostly = 100; |
39 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | 38 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); |
40 | 39 | ||
@@ -948,9 +947,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
948 | dentry->d_op = NULL; | 947 | dentry->d_op = NULL; |
949 | dentry->d_fsdata = NULL; | 948 | dentry->d_fsdata = NULL; |
950 | dentry->d_mounted = 0; | 949 | dentry->d_mounted = 0; |
951 | #ifdef CONFIG_PROFILING | ||
952 | dentry->d_cookie = NULL; | ||
953 | #endif | ||
954 | INIT_HLIST_NODE(&dentry->d_hash); | 950 | INIT_HLIST_NODE(&dentry->d_hash); |
955 | INIT_LIST_HEAD(&dentry->d_lru); | 951 | INIT_LIST_HEAD(&dentry->d_lru); |
956 | INIT_LIST_HEAD(&dentry->d_subdirs); | 952 | INIT_LIST_HEAD(&dentry->d_subdirs); |
@@ -1336,7 +1332,7 @@ err_out: | |||
1336 | * | 1332 | * |
1337 | * Searches the children of the parent dentry for the name in question. If | 1333 | * Searches the children of the parent dentry for the name in question. If |
1338 | * the dentry is found its reference count is incremented and the dentry | 1334 | * the dentry is found its reference count is incremented and the dentry |
1339 | * is returned. The caller must use d_put to free the entry when it has | 1335 | * is returned. The caller must use dput to free the entry when it has |
1340 | * finished using it. %NULL is returned on failure. | 1336 | * finished using it. %NULL is returned on failure. |
1341 | * | 1337 | * |
1342 | * __d_lookup is dcache_lock free. The hash list is protected using RCU. | 1338 | * __d_lookup is dcache_lock free. The hash list is protected using RCU. |
@@ -1620,8 +1616,11 @@ static void switch_names(struct dentry *dentry, struct dentry *target) | |||
1620 | */ | 1616 | */ |
1621 | memcpy(dentry->d_iname, target->d_name.name, | 1617 | memcpy(dentry->d_iname, target->d_name.name, |
1622 | target->d_name.len + 1); | 1618 | target->d_name.len + 1); |
1619 | dentry->d_name.len = target->d_name.len; | ||
1620 | return; | ||
1623 | } | 1621 | } |
1624 | } | 1622 | } |
1623 | do_switch(dentry->d_name.len, target->d_name.len); | ||
1625 | } | 1624 | } |
1626 | 1625 | ||
1627 | /* | 1626 | /* |
@@ -1681,7 +1680,6 @@ already_unhashed: | |||
1681 | 1680 | ||
1682 | /* Switch the names.. */ | 1681 | /* Switch the names.. */ |
1683 | switch_names(dentry, target); | 1682 | switch_names(dentry, target); |
1684 | do_switch(dentry->d_name.len, target->d_name.len); | ||
1685 | do_switch(dentry->d_name.hash, target->d_name.hash); | 1683 | do_switch(dentry->d_name.hash, target->d_name.hash); |
1686 | 1684 | ||
1687 | /* ... and switch the parents */ | 1685 | /* ... and switch the parents */ |
@@ -1791,7 +1789,6 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) | |||
1791 | struct dentry *dparent, *aparent; | 1789 | struct dentry *dparent, *aparent; |
1792 | 1790 | ||
1793 | switch_names(dentry, anon); | 1791 | switch_names(dentry, anon); |
1794 | do_switch(dentry->d_name.len, anon->d_name.len); | ||
1795 | do_switch(dentry->d_name.hash, anon->d_name.hash); | 1792 | do_switch(dentry->d_name.hash, anon->d_name.hash); |
1796 | 1793 | ||
1797 | dparent = dentry->d_parent; | 1794 | dparent = dentry->d_parent; |
@@ -1911,7 +1908,8 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
1911 | * Convert a dentry into an ASCII path name. If the entry has been deleted | 1908 | * Convert a dentry into an ASCII path name. If the entry has been deleted |
1912 | * the string " (deleted)" is appended. Note that this is ambiguous. | 1909 | * the string " (deleted)" is appended. Note that this is ambiguous. |
1913 | * | 1910 | * |
1914 | * Returns the buffer or an error code if the path was too long. | 1911 | * Returns a pointer into the buffer or an error code if the |
1912 | * path was too long. | ||
1915 | * | 1913 | * |
1916 | * "buflen" should be positive. Caller holds the dcache_lock. | 1914 | * "buflen" should be positive. Caller holds the dcache_lock. |
1917 | * | 1915 | * |
@@ -1987,7 +1985,10 @@ Elong: | |||
1987 | * Convert a dentry into an ASCII path name. If the entry has been deleted | 1985 | * Convert a dentry into an ASCII path name. If the entry has been deleted |
1988 | * the string " (deleted)" is appended. Note that this is ambiguous. | 1986 | * the string " (deleted)" is appended. Note that this is ambiguous. |
1989 | * | 1987 | * |
1990 | * Returns the buffer or an error code if the path was too long. | 1988 | * Returns a pointer into the buffer or an error code if the path was |
1989 | * too long. Note: Callers should use the returned pointer, not the passed | ||
1990 | * in buffer, to use the name! The implementation often starts at an offset | ||
1991 | * into the buffer, and may leave 0 bytes at the start. | ||
1991 | * | 1992 | * |
1992 | * "buflen" should be positive. | 1993 | * "buflen" should be positive. |
1993 | */ | 1994 | */ |
@@ -2313,9 +2314,6 @@ static void __init dcache_init(void) | |||
2313 | /* SLAB cache for __getname() consumers */ | 2314 | /* SLAB cache for __getname() consumers */ |
2314 | struct kmem_cache *names_cachep __read_mostly; | 2315 | struct kmem_cache *names_cachep __read_mostly; |
2315 | 2316 | ||
2316 | /* SLAB cache for file structures */ | ||
2317 | struct kmem_cache *filp_cachep __read_mostly; | ||
2318 | |||
2319 | EXPORT_SYMBOL(d_genocide); | 2317 | EXPORT_SYMBOL(d_genocide); |
2320 | 2318 | ||
2321 | void __init vfs_caches_init_early(void) | 2319 | void __init vfs_caches_init_early(void) |
@@ -2337,9 +2335,6 @@ void __init vfs_caches_init(unsigned long mempages) | |||
2337 | names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, | 2335 | names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, |
2338 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 2336 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
2339 | 2337 | ||
2340 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, | ||
2341 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | ||
2342 | |||
2343 | dcache_init(); | 2338 | dcache_init(); |
2344 | inode_init(); | 2339 | inode_init(); |
2345 | files_init(mempages); | 2340 | files_init(mempages); |
diff --git a/fs/dcookies.c b/fs/dcookies.c index 855d4b1d619a..180e9fec4ad8 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c | |||
@@ -93,10 +93,15 @@ static struct dcookie_struct *alloc_dcookie(struct path *path) | |||
93 | { | 93 | { |
94 | struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache, | 94 | struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache, |
95 | GFP_KERNEL); | 95 | GFP_KERNEL); |
96 | struct dentry *d; | ||
96 | if (!dcs) | 97 | if (!dcs) |
97 | return NULL; | 98 | return NULL; |
98 | 99 | ||
99 | path->dentry->d_cookie = dcs; | 100 | d = path->dentry; |
101 | spin_lock(&d->d_lock); | ||
102 | d->d_flags |= DCACHE_COOKIE; | ||
103 | spin_unlock(&d->d_lock); | ||
104 | |||
100 | dcs->path = *path; | 105 | dcs->path = *path; |
101 | path_get(path); | 106 | path_get(path); |
102 | hash_dcookie(dcs); | 107 | hash_dcookie(dcs); |
@@ -119,14 +124,14 @@ int get_dcookie(struct path *path, unsigned long *cookie) | |||
119 | goto out; | 124 | goto out; |
120 | } | 125 | } |
121 | 126 | ||
122 | dcs = path->dentry->d_cookie; | 127 | if (path->dentry->d_flags & DCACHE_COOKIE) { |
123 | 128 | dcs = find_dcookie((unsigned long)path->dentry); | |
124 | if (!dcs) | 129 | } else { |
125 | dcs = alloc_dcookie(path); | 130 | dcs = alloc_dcookie(path); |
126 | 131 | if (!dcs) { | |
127 | if (!dcs) { | 132 | err = -ENOMEM; |
128 | err = -ENOMEM; | 133 | goto out; |
129 | goto out; | 134 | } |
130 | } | 135 | } |
131 | 136 | ||
132 | *cookie = dcookie_value(dcs); | 137 | *cookie = dcookie_value(dcs); |
@@ -251,7 +256,12 @@ out_kmem: | |||
251 | 256 | ||
252 | static void free_dcookie(struct dcookie_struct * dcs) | 257 | static void free_dcookie(struct dcookie_struct * dcs) |
253 | { | 258 | { |
254 | dcs->path.dentry->d_cookie = NULL; | 259 | struct dentry *d = dcs->path.dentry; |
260 | |||
261 | spin_lock(&d->d_lock); | ||
262 | d->d_flags &= ~DCACHE_COOKIE; | ||
263 | spin_unlock(&d->d_lock); | ||
264 | |||
255 | path_put(&dcs->path); | 265 | path_put(&dcs->path); |
256 | kmem_cache_free(dcookie_cache, dcs); | 266 | kmem_cache_free(dcookie_cache, dcs); |
257 | } | 267 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 89209f00f9c7..5e78fc179886 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -673,10 +673,11 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
673 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " | 673 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " |
674 | "dentry->d_name.name = [%s]\n", dentry->d_name.name); | 674 | "dentry->d_name.name = [%s]\n", dentry->d_name.name); |
675 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); | 675 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); |
676 | buf[rc] = '\0'; | ||
677 | set_fs(old_fs); | 676 | set_fs(old_fs); |
678 | if (rc < 0) | 677 | if (rc < 0) |
679 | goto out_free; | 678 | goto out_free; |
679 | else | ||
680 | buf[rc] = '\0'; | ||
680 | rc = 0; | 681 | rc = 0; |
681 | nd_set_link(nd, buf); | 682 | nd_set_link(nd, buf); |
682 | goto out; | 683 | goto out; |
@@ -127,7 +127,8 @@ asmlinkage long sys_uselib(const char __user * library) | |||
127 | if (nd.path.mnt->mnt_flags & MNT_NOEXEC) | 127 | if (nd.path.mnt->mnt_flags & MNT_NOEXEC) |
128 | goto exit; | 128 | goto exit; |
129 | 129 | ||
130 | error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); | 130 | error = inode_permission(nd.path.dentry->d_inode, |
131 | MAY_READ | MAY_EXEC | MAY_OPEN); | ||
131 | if (error) | 132 | if (error) |
132 | goto exit; | 133 | goto exit; |
133 | 134 | ||
@@ -680,7 +681,7 @@ struct file *open_exec(const char *name) | |||
680 | if (nd.path.mnt->mnt_flags & MNT_NOEXEC) | 681 | if (nd.path.mnt->mnt_flags & MNT_NOEXEC) |
681 | goto out_path_put; | 682 | goto out_path_put; |
682 | 683 | ||
683 | err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); | 684 | err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN); |
684 | if (err) | 685 | if (err) |
685 | goto out_path_put; | 686 | goto out_path_put; |
686 | 687 | ||
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 8d0add625870..c454d5db28a5 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -585,7 +585,10 @@ got: | |||
585 | spin_lock(&sbi->s_next_gen_lock); | 585 | spin_lock(&sbi->s_next_gen_lock); |
586 | inode->i_generation = sbi->s_next_generation++; | 586 | inode->i_generation = sbi->s_next_generation++; |
587 | spin_unlock(&sbi->s_next_gen_lock); | 587 | spin_unlock(&sbi->s_next_gen_lock); |
588 | insert_inode_hash(inode); | 588 | if (insert_inode_locked(inode) < 0) { |
589 | err = -EINVAL; | ||
590 | goto fail_drop; | ||
591 | } | ||
589 | 592 | ||
590 | if (DQUOT_ALLOC_INODE(inode)) { | 593 | if (DQUOT_ALLOC_INODE(inode)) { |
591 | err = -EDQUOT; | 594 | err = -EDQUOT; |
@@ -612,6 +615,7 @@ fail_drop: | |||
612 | DQUOT_DROP(inode); | 615 | DQUOT_DROP(inode); |
613 | inode->i_flags |= S_NOQUOTA; | 616 | inode->i_flags |= S_NOQUOTA; |
614 | inode->i_nlink = 0; | 617 | inode->i_nlink = 0; |
618 | unlock_new_inode(inode); | ||
615 | iput(inode); | 619 | iput(inode); |
616 | return ERR_PTR(err); | 620 | return ERR_PTR(err); |
617 | 621 | ||
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 7658b33e2653..02b39a5deb74 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/buffer_head.h> | 32 | #include <linux/buffer_head.h> |
33 | #include <linux/mpage.h> | 33 | #include <linux/mpage.h> |
34 | #include <linux/fiemap.h> | 34 | #include <linux/fiemap.h> |
35 | #include <linux/namei.h> | ||
35 | #include "ext2.h" | 36 | #include "ext2.h" |
36 | #include "acl.h" | 37 | #include "acl.h" |
37 | #include "xip.h" | 38 | #include "xip.h" |
@@ -1286,9 +1287,11 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino) | |||
1286 | else | 1287 | else |
1287 | inode->i_mapping->a_ops = &ext2_aops; | 1288 | inode->i_mapping->a_ops = &ext2_aops; |
1288 | } else if (S_ISLNK(inode->i_mode)) { | 1289 | } else if (S_ISLNK(inode->i_mode)) { |
1289 | if (ext2_inode_is_fast_symlink(inode)) | 1290 | if (ext2_inode_is_fast_symlink(inode)) { |
1290 | inode->i_op = &ext2_fast_symlink_inode_operations; | 1291 | inode->i_op = &ext2_fast_symlink_inode_operations; |
1291 | else { | 1292 | nd_terminate_link(ei->i_data, inode->i_size, |
1293 | sizeof(ei->i_data) - 1); | ||
1294 | } else { | ||
1292 | inode->i_op = &ext2_symlink_inode_operations; | 1295 | inode->i_op = &ext2_symlink_inode_operations; |
1293 | if (test_opt(inode->i_sb, NOBH)) | 1296 | if (test_opt(inode->i_sb, NOBH)) |
1294 | inode->i_mapping->a_ops = &ext2_nobh_aops; | 1297 | inode->i_mapping->a_ops = &ext2_nobh_aops; |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 2a747252ec12..90ea17998a73 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -41,9 +41,11 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) | |||
41 | int err = ext2_add_link(dentry, inode); | 41 | int err = ext2_add_link(dentry, inode); |
42 | if (!err) { | 42 | if (!err) { |
43 | d_instantiate(dentry, inode); | 43 | d_instantiate(dentry, inode); |
44 | unlock_new_inode(inode); | ||
44 | return 0; | 45 | return 0; |
45 | } | 46 | } |
46 | inode_dec_link_count(inode); | 47 | inode_dec_link_count(inode); |
48 | unlock_new_inode(inode); | ||
47 | iput(inode); | 49 | iput(inode); |
48 | return err; | 50 | return err; |
49 | } | 51 | } |
@@ -170,6 +172,7 @@ out: | |||
170 | 172 | ||
171 | out_fail: | 173 | out_fail: |
172 | inode_dec_link_count(inode); | 174 | inode_dec_link_count(inode); |
175 | unlock_new_inode(inode); | ||
173 | iput (inode); | 176 | iput (inode); |
174 | goto out; | 177 | goto out; |
175 | } | 178 | } |
@@ -178,6 +181,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
178 | struct dentry *dentry) | 181 | struct dentry *dentry) |
179 | { | 182 | { |
180 | struct inode *inode = old_dentry->d_inode; | 183 | struct inode *inode = old_dentry->d_inode; |
184 | int err; | ||
181 | 185 | ||
182 | if (inode->i_nlink >= EXT2_LINK_MAX) | 186 | if (inode->i_nlink >= EXT2_LINK_MAX) |
183 | return -EMLINK; | 187 | return -EMLINK; |
@@ -186,7 +190,14 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
186 | inode_inc_link_count(inode); | 190 | inode_inc_link_count(inode); |
187 | atomic_inc(&inode->i_count); | 191 | atomic_inc(&inode->i_count); |
188 | 192 | ||
189 | return ext2_add_nondir(dentry, inode); | 193 | err = ext2_add_link(dentry, inode); |
194 | if (!err) { | ||
195 | d_instantiate(dentry, inode); | ||
196 | return 0; | ||
197 | } | ||
198 | inode_dec_link_count(inode); | ||
199 | iput(inode); | ||
200 | return err; | ||
190 | } | 201 | } |
191 | 202 | ||
192 | static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) | 203 | static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) |
@@ -222,12 +233,14 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
222 | goto out_fail; | 233 | goto out_fail; |
223 | 234 | ||
224 | d_instantiate(dentry, inode); | 235 | d_instantiate(dentry, inode); |
236 | unlock_new_inode(inode); | ||
225 | out: | 237 | out: |
226 | return err; | 238 | return err; |
227 | 239 | ||
228 | out_fail: | 240 | out_fail: |
229 | inode_dec_link_count(inode); | 241 | inode_dec_link_count(inode); |
230 | inode_dec_link_count(inode); | 242 | inode_dec_link_count(inode); |
243 | unlock_new_inode(inode); | ||
231 | iput(inode); | 244 | iput(inode); |
232 | out_dir: | 245 | out_dir: |
233 | inode_dec_link_count(dir); | 246 | inode_dec_link_count(dir); |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 490bd0ed7896..5655fbcbd11f 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -579,7 +579,10 @@ got: | |||
579 | ext3_set_inode_flags(inode); | 579 | ext3_set_inode_flags(inode); |
580 | if (IS_DIRSYNC(inode)) | 580 | if (IS_DIRSYNC(inode)) |
581 | handle->h_sync = 1; | 581 | handle->h_sync = 1; |
582 | insert_inode_hash(inode); | 582 | if (insert_inode_locked(inode) < 0) { |
583 | err = -EINVAL; | ||
584 | goto fail_drop; | ||
585 | } | ||
583 | spin_lock(&sbi->s_next_gen_lock); | 586 | spin_lock(&sbi->s_next_gen_lock); |
584 | inode->i_generation = sbi->s_next_generation++; | 587 | inode->i_generation = sbi->s_next_generation++; |
585 | spin_unlock(&sbi->s_next_gen_lock); | 588 | spin_unlock(&sbi->s_next_gen_lock); |
@@ -627,6 +630,7 @@ fail_drop: | |||
627 | DQUOT_DROP(inode); | 630 | DQUOT_DROP(inode); |
628 | inode->i_flags |= S_NOQUOTA; | 631 | inode->i_flags |= S_NOQUOTA; |
629 | inode->i_nlink = 0; | 632 | inode->i_nlink = 0; |
633 | unlock_new_inode(inode); | ||
630 | iput(inode); | 634 | iput(inode); |
631 | brelse(bitmap_bh); | 635 | brelse(bitmap_bh); |
632 | return ERR_PTR(err); | 636 | return ERR_PTR(err); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index f8424ad89971..c4bdccf976b5 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/uio.h> | 37 | #include <linux/uio.h> |
38 | #include <linux/bio.h> | 38 | #include <linux/bio.h> |
39 | #include <linux/fiemap.h> | 39 | #include <linux/fiemap.h> |
40 | #include <linux/namei.h> | ||
40 | #include "xattr.h" | 41 | #include "xattr.h" |
41 | #include "acl.h" | 42 | #include "acl.h" |
42 | 43 | ||
@@ -2817,9 +2818,11 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) | |||
2817 | inode->i_op = &ext3_dir_inode_operations; | 2818 | inode->i_op = &ext3_dir_inode_operations; |
2818 | inode->i_fop = &ext3_dir_operations; | 2819 | inode->i_fop = &ext3_dir_operations; |
2819 | } else if (S_ISLNK(inode->i_mode)) { | 2820 | } else if (S_ISLNK(inode->i_mode)) { |
2820 | if (ext3_inode_is_fast_symlink(inode)) | 2821 | if (ext3_inode_is_fast_symlink(inode)) { |
2821 | inode->i_op = &ext3_fast_symlink_inode_operations; | 2822 | inode->i_op = &ext3_fast_symlink_inode_operations; |
2822 | else { | 2823 | nd_terminate_link(ei->i_data, inode->i_size, |
2824 | sizeof(ei->i_data) - 1); | ||
2825 | } else { | ||
2823 | inode->i_op = &ext3_symlink_inode_operations; | 2826 | inode->i_op = &ext3_symlink_inode_operations; |
2824 | ext3_set_aops(inode); | 2827 | ext3_set_aops(inode); |
2825 | } | 2828 | } |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 3e5edc92aa0b..297ea8dfac7c 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1652,9 +1652,11 @@ static int ext3_add_nondir(handle_t *handle, | |||
1652 | if (!err) { | 1652 | if (!err) { |
1653 | ext3_mark_inode_dirty(handle, inode); | 1653 | ext3_mark_inode_dirty(handle, inode); |
1654 | d_instantiate(dentry, inode); | 1654 | d_instantiate(dentry, inode); |
1655 | unlock_new_inode(inode); | ||
1655 | return 0; | 1656 | return 0; |
1656 | } | 1657 | } |
1657 | drop_nlink(inode); | 1658 | drop_nlink(inode); |
1659 | unlock_new_inode(inode); | ||
1658 | iput(inode); | 1660 | iput(inode); |
1659 | return err; | 1661 | return err; |
1660 | } | 1662 | } |
@@ -1765,6 +1767,7 @@ retry: | |||
1765 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1767 | dir_block = ext3_bread (handle, inode, 0, 1, &err); |
1766 | if (!dir_block) { | 1768 | if (!dir_block) { |
1767 | drop_nlink(inode); /* is this nlink == 0? */ | 1769 | drop_nlink(inode); /* is this nlink == 0? */ |
1770 | unlock_new_inode(inode); | ||
1768 | ext3_mark_inode_dirty(handle, inode); | 1771 | ext3_mark_inode_dirty(handle, inode); |
1769 | iput (inode); | 1772 | iput (inode); |
1770 | goto out_stop; | 1773 | goto out_stop; |
@@ -1792,6 +1795,7 @@ retry: | |||
1792 | err = ext3_add_entry (handle, dentry, inode); | 1795 | err = ext3_add_entry (handle, dentry, inode); |
1793 | if (err) { | 1796 | if (err) { |
1794 | inode->i_nlink = 0; | 1797 | inode->i_nlink = 0; |
1798 | unlock_new_inode(inode); | ||
1795 | ext3_mark_inode_dirty(handle, inode); | 1799 | ext3_mark_inode_dirty(handle, inode); |
1796 | iput (inode); | 1800 | iput (inode); |
1797 | goto out_stop; | 1801 | goto out_stop; |
@@ -1800,6 +1804,7 @@ retry: | |||
1800 | ext3_update_dx_flag(dir); | 1804 | ext3_update_dx_flag(dir); |
1801 | ext3_mark_inode_dirty(handle, dir); | 1805 | ext3_mark_inode_dirty(handle, dir); |
1802 | d_instantiate(dentry, inode); | 1806 | d_instantiate(dentry, inode); |
1807 | unlock_new_inode(inode); | ||
1803 | out_stop: | 1808 | out_stop: |
1804 | ext3_journal_stop(handle); | 1809 | ext3_journal_stop(handle); |
1805 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 1810 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
@@ -2174,6 +2179,7 @@ retry: | |||
2174 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 2179 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
2175 | if (err) { | 2180 | if (err) { |
2176 | drop_nlink(inode); | 2181 | drop_nlink(inode); |
2182 | unlock_new_inode(inode); | ||
2177 | ext3_mark_inode_dirty(handle, inode); | 2183 | ext3_mark_inode_dirty(handle, inode); |
2178 | iput (inode); | 2184 | iput (inode); |
2179 | goto out_stop; | 2185 | goto out_stop; |
@@ -2221,7 +2227,14 @@ retry: | |||
2221 | inc_nlink(inode); | 2227 | inc_nlink(inode); |
2222 | atomic_inc(&inode->i_count); | 2228 | atomic_inc(&inode->i_count); |
2223 | 2229 | ||
2224 | err = ext3_add_nondir(handle, dentry, inode); | 2230 | err = ext3_add_entry(handle, dentry, inode); |
2231 | if (!err) { | ||
2232 | ext3_mark_inode_dirty(handle, inode); | ||
2233 | d_instantiate(dentry, inode); | ||
2234 | } else { | ||
2235 | drop_nlink(inode); | ||
2236 | iput(inode); | ||
2237 | } | ||
2225 | ext3_journal_stop(handle); | 2238 | ext3_journal_stop(handle); |
2226 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 2239 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
2227 | goto retry; | 2240 | goto retry; |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 08cac9fcace2..6e6052879aa2 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -826,7 +826,10 @@ got: | |||
826 | ext4_set_inode_flags(inode); | 826 | ext4_set_inode_flags(inode); |
827 | if (IS_DIRSYNC(inode)) | 827 | if (IS_DIRSYNC(inode)) |
828 | handle->h_sync = 1; | 828 | handle->h_sync = 1; |
829 | insert_inode_hash(inode); | 829 | if (insert_inode_locked(inode) < 0) { |
830 | err = -EINVAL; | ||
831 | goto fail_drop; | ||
832 | } | ||
830 | spin_lock(&sbi->s_next_gen_lock); | 833 | spin_lock(&sbi->s_next_gen_lock); |
831 | inode->i_generation = sbi->s_next_generation++; | 834 | inode->i_generation = sbi->s_next_generation++; |
832 | spin_unlock(&sbi->s_next_gen_lock); | 835 | spin_unlock(&sbi->s_next_gen_lock); |
@@ -881,6 +884,7 @@ fail_drop: | |||
881 | DQUOT_DROP(inode); | 884 | DQUOT_DROP(inode); |
882 | inode->i_flags |= S_NOQUOTA; | 885 | inode->i_flags |= S_NOQUOTA; |
883 | inode->i_nlink = 0; | 886 | inode->i_nlink = 0; |
887 | unlock_new_inode(inode); | ||
884 | iput(inode); | 888 | iput(inode); |
885 | brelse(bitmap_bh); | 889 | brelse(bitmap_bh); |
886 | return ERR_PTR(err); | 890 | return ERR_PTR(err); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index be21a5ae33cb..7c3325e0b005 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/writeback.h> | 34 | #include <linux/writeback.h> |
35 | #include <linux/pagevec.h> | 35 | #include <linux/pagevec.h> |
36 | #include <linux/mpage.h> | 36 | #include <linux/mpage.h> |
37 | #include <linux/namei.h> | ||
37 | #include <linux/uio.h> | 38 | #include <linux/uio.h> |
38 | #include <linux/bio.h> | 39 | #include <linux/bio.h> |
39 | #include "ext4_jbd2.h" | 40 | #include "ext4_jbd2.h" |
@@ -4164,9 +4165,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4164 | inode->i_op = &ext4_dir_inode_operations; | 4165 | inode->i_op = &ext4_dir_inode_operations; |
4165 | inode->i_fop = &ext4_dir_operations; | 4166 | inode->i_fop = &ext4_dir_operations; |
4166 | } else if (S_ISLNK(inode->i_mode)) { | 4167 | } else if (S_ISLNK(inode->i_mode)) { |
4167 | if (ext4_inode_is_fast_symlink(inode)) | 4168 | if (ext4_inode_is_fast_symlink(inode)) { |
4168 | inode->i_op = &ext4_fast_symlink_inode_operations; | 4169 | inode->i_op = &ext4_fast_symlink_inode_operations; |
4169 | else { | 4170 | nd_terminate_link(ei->i_data, inode->i_size, |
4171 | sizeof(ei->i_data) - 1); | ||
4172 | } else { | ||
4170 | inode->i_op = &ext4_symlink_inode_operations; | 4173 | inode->i_op = &ext4_symlink_inode_operations; |
4171 | ext4_set_aops(inode); | 4174 | ext4_set_aops(inode); |
4172 | } | 4175 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 63adcb792988..da98a9012fa5 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1693,9 +1693,11 @@ static int ext4_add_nondir(handle_t *handle, | |||
1693 | if (!err) { | 1693 | if (!err) { |
1694 | ext4_mark_inode_dirty(handle, inode); | 1694 | ext4_mark_inode_dirty(handle, inode); |
1695 | d_instantiate(dentry, inode); | 1695 | d_instantiate(dentry, inode); |
1696 | unlock_new_inode(inode); | ||
1696 | return 0; | 1697 | return 0; |
1697 | } | 1698 | } |
1698 | drop_nlink(inode); | 1699 | drop_nlink(inode); |
1700 | unlock_new_inode(inode); | ||
1699 | iput(inode); | 1701 | iput(inode); |
1700 | return err; | 1702 | return err; |
1701 | } | 1703 | } |
@@ -1830,6 +1832,7 @@ retry: | |||
1830 | if (err) { | 1832 | if (err) { |
1831 | out_clear_inode: | 1833 | out_clear_inode: |
1832 | clear_nlink(inode); | 1834 | clear_nlink(inode); |
1835 | unlock_new_inode(inode); | ||
1833 | ext4_mark_inode_dirty(handle, inode); | 1836 | ext4_mark_inode_dirty(handle, inode); |
1834 | iput(inode); | 1837 | iput(inode); |
1835 | goto out_stop; | 1838 | goto out_stop; |
@@ -1838,6 +1841,7 @@ out_clear_inode: | |||
1838 | ext4_update_dx_flag(dir); | 1841 | ext4_update_dx_flag(dir); |
1839 | ext4_mark_inode_dirty(handle, dir); | 1842 | ext4_mark_inode_dirty(handle, dir); |
1840 | d_instantiate(dentry, inode); | 1843 | d_instantiate(dentry, inode); |
1844 | unlock_new_inode(inode); | ||
1841 | out_stop: | 1845 | out_stop: |
1842 | ext4_journal_stop(handle); | 1846 | ext4_journal_stop(handle); |
1843 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | 1847 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) |
@@ -2212,6 +2216,7 @@ retry: | |||
2212 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 2216 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
2213 | if (err) { | 2217 | if (err) { |
2214 | clear_nlink(inode); | 2218 | clear_nlink(inode); |
2219 | unlock_new_inode(inode); | ||
2215 | ext4_mark_inode_dirty(handle, inode); | 2220 | ext4_mark_inode_dirty(handle, inode); |
2216 | iput(inode); | 2221 | iput(inode); |
2217 | goto out_stop; | 2222 | goto out_stop; |
@@ -2262,7 +2267,14 @@ retry: | |||
2262 | ext4_inc_count(handle, inode); | 2267 | ext4_inc_count(handle, inode); |
2263 | atomic_inc(&inode->i_count); | 2268 | atomic_inc(&inode->i_count); |
2264 | 2269 | ||
2265 | err = ext4_add_nondir(handle, dentry, inode); | 2270 | err = ext4_add_entry(handle, dentry, inode); |
2271 | if (!err) { | ||
2272 | ext4_mark_inode_dirty(handle, inode); | ||
2273 | d_instantiate(dentry, inode); | ||
2274 | } else { | ||
2275 | drop_nlink(inode); | ||
2276 | iput(inode); | ||
2277 | } | ||
2266 | ext4_journal_stop(handle); | 2278 | ext4_journal_stop(handle); |
2267 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | 2279 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) |
2268 | goto retry; | 2280 | goto retry; |
diff --git a/fs/file_table.c b/fs/file_table.c index 0fbcacc3ea75..bbeeac6efa1a 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -32,6 +32,9 @@ struct files_stat_struct files_stat = { | |||
32 | /* public. Not pretty! */ | 32 | /* public. Not pretty! */ |
33 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); | 33 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); |
34 | 34 | ||
35 | /* SLAB cache for file structures */ | ||
36 | static struct kmem_cache *filp_cachep __read_mostly; | ||
37 | |||
35 | static struct percpu_counter nr_files __cacheline_aligned_in_smp; | 38 | static struct percpu_counter nr_files __cacheline_aligned_in_smp; |
36 | 39 | ||
37 | static inline void file_free_rcu(struct rcu_head *head) | 40 | static inline void file_free_rcu(struct rcu_head *head) |
@@ -397,7 +400,12 @@ too_bad: | |||
397 | void __init files_init(unsigned long mempages) | 400 | void __init files_init(unsigned long mempages) |
398 | { | 401 | { |
399 | int n; | 402 | int n; |
400 | /* One file with associated inode and dcache is very roughly 1K. | 403 | |
404 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, | ||
405 | SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); | ||
406 | |||
407 | /* | ||
408 | * One file with associated inode and dcache is very roughly 1K. | ||
401 | * Per default don't use more than 10% of our memory for files. | 409 | * Per default don't use more than 10% of our memory for files. |
402 | */ | 410 | */ |
403 | 411 | ||
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 9f3f2ceb73f0..03a6ea5e99f7 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -325,8 +325,10 @@ vxfs_iget(struct super_block *sbp, ino_t ino) | |||
325 | if (!VXFS_ISIMMED(vip)) { | 325 | if (!VXFS_ISIMMED(vip)) { |
326 | ip->i_op = &page_symlink_inode_operations; | 326 | ip->i_op = &page_symlink_inode_operations; |
327 | ip->i_mapping->a_ops = &vxfs_aops; | 327 | ip->i_mapping->a_ops = &vxfs_aops; |
328 | } else | 328 | } else { |
329 | ip->i_op = &vxfs_immed_symlink_iops; | 329 | ip->i_op = &vxfs_immed_symlink_iops; |
330 | vip->vii_immed.vi_immed[ip->i_size] = '\0'; | ||
331 | } | ||
330 | } else | 332 | } else |
331 | init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev)); | 333 | init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev)); |
332 | 334 | ||
diff --git a/fs/inode.c b/fs/inode.c index 098a2443196f..7de1cda92489 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1032,6 +1032,65 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) | |||
1032 | 1032 | ||
1033 | EXPORT_SYMBOL(iget_locked); | 1033 | EXPORT_SYMBOL(iget_locked); |
1034 | 1034 | ||
1035 | int insert_inode_locked(struct inode *inode) | ||
1036 | { | ||
1037 | struct super_block *sb = inode->i_sb; | ||
1038 | ino_t ino = inode->i_ino; | ||
1039 | struct hlist_head *head = inode_hashtable + hash(sb, ino); | ||
1040 | struct inode *old; | ||
1041 | |||
1042 | inode->i_state |= I_LOCK|I_NEW; | ||
1043 | while (1) { | ||
1044 | spin_lock(&inode_lock); | ||
1045 | old = find_inode_fast(sb, head, ino); | ||
1046 | if (likely(!old)) { | ||
1047 | hlist_add_head(&inode->i_hash, head); | ||
1048 | spin_unlock(&inode_lock); | ||
1049 | return 0; | ||
1050 | } | ||
1051 | __iget(old); | ||
1052 | spin_unlock(&inode_lock); | ||
1053 | wait_on_inode(old); | ||
1054 | if (unlikely(!hlist_unhashed(&old->i_hash))) { | ||
1055 | iput(old); | ||
1056 | return -EBUSY; | ||
1057 | } | ||
1058 | iput(old); | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | EXPORT_SYMBOL(insert_inode_locked); | ||
1063 | |||
1064 | int insert_inode_locked4(struct inode *inode, unsigned long hashval, | ||
1065 | int (*test)(struct inode *, void *), void *data) | ||
1066 | { | ||
1067 | struct super_block *sb = inode->i_sb; | ||
1068 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); | ||
1069 | struct inode *old; | ||
1070 | |||
1071 | inode->i_state |= I_LOCK|I_NEW; | ||
1072 | |||
1073 | while (1) { | ||
1074 | spin_lock(&inode_lock); | ||
1075 | old = find_inode(sb, head, test, data); | ||
1076 | if (likely(!old)) { | ||
1077 | hlist_add_head(&inode->i_hash, head); | ||
1078 | spin_unlock(&inode_lock); | ||
1079 | return 0; | ||
1080 | } | ||
1081 | __iget(old); | ||
1082 | spin_unlock(&inode_lock); | ||
1083 | wait_on_inode(old); | ||
1084 | if (unlikely(!hlist_unhashed(&old->i_hash))) { | ||
1085 | iput(old); | ||
1086 | return -EBUSY; | ||
1087 | } | ||
1088 | iput(old); | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | EXPORT_SYMBOL(insert_inode_locked4); | ||
1093 | |||
1035 | /** | 1094 | /** |
1036 | * __insert_inode_hash - hash an inode | 1095 | * __insert_inode_hash - hash an inode |
1037 | * @inode: unhashed inode | 1096 | * @inode: unhashed inode |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 70022fd1c539..d4d142c2edd4 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
@@ -79,7 +79,8 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
79 | inode = new_inode(sb); | 79 | inode = new_inode(sb); |
80 | if (!inode) { | 80 | if (!inode) { |
81 | jfs_warn("ialloc: new_inode returned NULL!"); | 81 | jfs_warn("ialloc: new_inode returned NULL!"); |
82 | return ERR_PTR(-ENOMEM); | 82 | rc = -ENOMEM; |
83 | goto fail; | ||
83 | } | 84 | } |
84 | 85 | ||
85 | jfs_inode = JFS_IP(inode); | 86 | jfs_inode = JFS_IP(inode); |
@@ -89,8 +90,12 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
89 | jfs_warn("ialloc: diAlloc returned %d!", rc); | 90 | jfs_warn("ialloc: diAlloc returned %d!", rc); |
90 | if (rc == -EIO) | 91 | if (rc == -EIO) |
91 | make_bad_inode(inode); | 92 | make_bad_inode(inode); |
92 | iput(inode); | 93 | goto fail_put; |
93 | return ERR_PTR(rc); | 94 | } |
95 | |||
96 | if (insert_inode_locked(inode) < 0) { | ||
97 | rc = -EINVAL; | ||
98 | goto fail_unlock; | ||
94 | } | 99 | } |
95 | 100 | ||
96 | inode->i_uid = current_fsuid(); | 101 | inode->i_uid = current_fsuid(); |
@@ -112,11 +117,8 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
112 | * Allocate inode to quota. | 117 | * Allocate inode to quota. |
113 | */ | 118 | */ |
114 | if (DQUOT_ALLOC_INODE(inode)) { | 119 | if (DQUOT_ALLOC_INODE(inode)) { |
115 | DQUOT_DROP(inode); | 120 | rc = -EDQUOT; |
116 | inode->i_flags |= S_NOQUOTA; | 121 | goto fail_drop; |
117 | inode->i_nlink = 0; | ||
118 | iput(inode); | ||
119 | return ERR_PTR(-EDQUOT); | ||
120 | } | 122 | } |
121 | 123 | ||
122 | inode->i_mode = mode; | 124 | inode->i_mode = mode; |
@@ -158,4 +160,15 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
158 | jfs_info("ialloc returns inode = 0x%p\n", inode); | 160 | jfs_info("ialloc returns inode = 0x%p\n", inode); |
159 | 161 | ||
160 | return inode; | 162 | return inode; |
163 | |||
164 | fail_drop: | ||
165 | DQUOT_DROP(inode); | ||
166 | inode->i_flags |= S_NOQUOTA; | ||
167 | fail_unlock: | ||
168 | inode->i_nlink = 0; | ||
169 | unlock_new_inode(inode); | ||
170 | fail_put: | ||
171 | iput(inode); | ||
172 | fail: | ||
173 | return ERR_PTR(rc); | ||
161 | } | 174 | } |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index cc3cedffbfa1..b4de56b851e4 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -155,7 +155,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
155 | ip->i_fop = &jfs_file_operations; | 155 | ip->i_fop = &jfs_file_operations; |
156 | ip->i_mapping->a_ops = &jfs_aops; | 156 | ip->i_mapping->a_ops = &jfs_aops; |
157 | 157 | ||
158 | insert_inode_hash(ip); | ||
159 | mark_inode_dirty(ip); | 158 | mark_inode_dirty(ip); |
160 | 159 | ||
161 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; | 160 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; |
@@ -171,9 +170,12 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
171 | if (rc) { | 170 | if (rc) { |
172 | free_ea_wmap(ip); | 171 | free_ea_wmap(ip); |
173 | ip->i_nlink = 0; | 172 | ip->i_nlink = 0; |
173 | unlock_new_inode(ip); | ||
174 | iput(ip); | 174 | iput(ip); |
175 | } else | 175 | } else { |
176 | d_instantiate(dentry, ip); | 176 | d_instantiate(dentry, ip); |
177 | unlock_new_inode(ip); | ||
178 | } | ||
177 | 179 | ||
178 | out2: | 180 | out2: |
179 | free_UCSname(&dname); | 181 | free_UCSname(&dname); |
@@ -289,7 +291,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
289 | ip->i_op = &jfs_dir_inode_operations; | 291 | ip->i_op = &jfs_dir_inode_operations; |
290 | ip->i_fop = &jfs_dir_operations; | 292 | ip->i_fop = &jfs_dir_operations; |
291 | 293 | ||
292 | insert_inode_hash(ip); | ||
293 | mark_inode_dirty(ip); | 294 | mark_inode_dirty(ip); |
294 | 295 | ||
295 | /* update parent directory inode */ | 296 | /* update parent directory inode */ |
@@ -306,9 +307,12 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
306 | if (rc) { | 307 | if (rc) { |
307 | free_ea_wmap(ip); | 308 | free_ea_wmap(ip); |
308 | ip->i_nlink = 0; | 309 | ip->i_nlink = 0; |
310 | unlock_new_inode(ip); | ||
309 | iput(ip); | 311 | iput(ip); |
310 | } else | 312 | } else { |
311 | d_instantiate(dentry, ip); | 313 | d_instantiate(dentry, ip); |
314 | unlock_new_inode(ip); | ||
315 | } | ||
312 | 316 | ||
313 | out2: | 317 | out2: |
314 | free_UCSname(&dname); | 318 | free_UCSname(&dname); |
@@ -1019,7 +1023,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1019 | goto out3; | 1023 | goto out3; |
1020 | } | 1024 | } |
1021 | 1025 | ||
1022 | insert_inode_hash(ip); | ||
1023 | mark_inode_dirty(ip); | 1026 | mark_inode_dirty(ip); |
1024 | 1027 | ||
1025 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; | 1028 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; |
@@ -1039,9 +1042,12 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1039 | if (rc) { | 1042 | if (rc) { |
1040 | free_ea_wmap(ip); | 1043 | free_ea_wmap(ip); |
1041 | ip->i_nlink = 0; | 1044 | ip->i_nlink = 0; |
1045 | unlock_new_inode(ip); | ||
1042 | iput(ip); | 1046 | iput(ip); |
1043 | } else | 1047 | } else { |
1044 | d_instantiate(dentry, ip); | 1048 | d_instantiate(dentry, ip); |
1049 | unlock_new_inode(ip); | ||
1050 | } | ||
1045 | 1051 | ||
1046 | out2: | 1052 | out2: |
1047 | free_UCSname(&dname); | 1053 | free_UCSname(&dname); |
@@ -1399,7 +1405,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1399 | jfs_ip->dev = new_encode_dev(rdev); | 1405 | jfs_ip->dev = new_encode_dev(rdev); |
1400 | init_special_inode(ip, ip->i_mode, rdev); | 1406 | init_special_inode(ip, ip->i_mode, rdev); |
1401 | 1407 | ||
1402 | insert_inode_hash(ip); | ||
1403 | mark_inode_dirty(ip); | 1408 | mark_inode_dirty(ip); |
1404 | 1409 | ||
1405 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1410 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
@@ -1417,9 +1422,12 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1417 | if (rc) { | 1422 | if (rc) { |
1418 | free_ea_wmap(ip); | 1423 | free_ea_wmap(ip); |
1419 | ip->i_nlink = 0; | 1424 | ip->i_nlink = 0; |
1425 | unlock_new_inode(ip); | ||
1420 | iput(ip); | 1426 | iput(ip); |
1421 | } else | 1427 | } else { |
1422 | d_instantiate(dentry, ip); | 1428 | d_instantiate(dentry, ip); |
1429 | unlock_new_inode(ip); | ||
1430 | } | ||
1423 | 1431 | ||
1424 | out1: | 1432 | out1: |
1425 | free_UCSname(&dname); | 1433 | free_UCSname(&dname); |
diff --git a/fs/namei.c b/fs/namei.c index af3783fff1de..dd5c9f0bf829 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -226,6 +226,16 @@ int generic_permission(struct inode *inode, int mask, | |||
226 | return -EACCES; | 226 | return -EACCES; |
227 | } | 227 | } |
228 | 228 | ||
229 | /** | ||
230 | * inode_permission - check for access rights to a given inode | ||
231 | * @inode: inode to check permission on | ||
232 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | ||
233 | * | ||
234 | * Used to check for read/write/execute permissions on an inode. | ||
235 | * We use "fsuid" for this, letting us set arbitrary permissions | ||
236 | * for filesystem access without changing the "normal" uids which | ||
237 | * are used for other things. | ||
238 | */ | ||
229 | int inode_permission(struct inode *inode, int mask) | 239 | int inode_permission(struct inode *inode, int mask) |
230 | { | 240 | { |
231 | int retval; | 241 | int retval; |
@@ -247,7 +257,6 @@ int inode_permission(struct inode *inode, int mask) | |||
247 | return -EACCES; | 257 | return -EACCES; |
248 | } | 258 | } |
249 | 259 | ||
250 | /* Ordinary permission routines do not understand MAY_APPEND. */ | ||
251 | if (inode->i_op && inode->i_op->permission) | 260 | if (inode->i_op && inode->i_op->permission) |
252 | retval = inode->i_op->permission(inode, mask); | 261 | retval = inode->i_op->permission(inode, mask); |
253 | else | 262 | else |
@@ -265,21 +274,6 @@ int inode_permission(struct inode *inode, int mask) | |||
265 | } | 274 | } |
266 | 275 | ||
267 | /** | 276 | /** |
268 | * vfs_permission - check for access rights to a given path | ||
269 | * @nd: lookup result that describes the path | ||
270 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | ||
271 | * | ||
272 | * Used to check for read/write/execute permissions on a path. | ||
273 | * We use "fsuid" for this, letting us set arbitrary permissions | ||
274 | * for filesystem access without changing the "normal" uids which | ||
275 | * are used for other things. | ||
276 | */ | ||
277 | int vfs_permission(struct nameidata *nd, int mask) | ||
278 | { | ||
279 | return inode_permission(nd->path.dentry->d_inode, mask); | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * file_permission - check for additional access rights to a given file | 277 | * file_permission - check for additional access rights to a given file |
284 | * @file: file to check access rights for | 278 | * @file: file to check access rights for |
285 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | 279 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) |
@@ -289,7 +283,7 @@ int vfs_permission(struct nameidata *nd, int mask) | |||
289 | * | 283 | * |
290 | * Note: | 284 | * Note: |
291 | * Do not use this function in new code. All access checks should | 285 | * Do not use this function in new code. All access checks should |
292 | * be done using vfs_permission(). | 286 | * be done using inode_permission(). |
293 | */ | 287 | */ |
294 | int file_permission(struct file *file, int mask) | 288 | int file_permission(struct file *file, int mask) |
295 | { | 289 | { |
@@ -527,18 +521,6 @@ out_unlock: | |||
527 | return result; | 521 | return result; |
528 | } | 522 | } |
529 | 523 | ||
530 | /* SMP-safe */ | ||
531 | static __always_inline void | ||
532 | walk_init_root(const char *name, struct nameidata *nd) | ||
533 | { | ||
534 | struct fs_struct *fs = current->fs; | ||
535 | |||
536 | read_lock(&fs->lock); | ||
537 | nd->path = fs->root; | ||
538 | path_get(&fs->root); | ||
539 | read_unlock(&fs->lock); | ||
540 | } | ||
541 | |||
542 | /* | 524 | /* |
543 | * Wrapper to retry pathname resolution whenever the underlying | 525 | * Wrapper to retry pathname resolution whenever the underlying |
544 | * file system returns an ESTALE. | 526 | * file system returns an ESTALE. |
@@ -576,9 +558,16 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l | |||
576 | goto fail; | 558 | goto fail; |
577 | 559 | ||
578 | if (*link == '/') { | 560 | if (*link == '/') { |
561 | struct fs_struct *fs = current->fs; | ||
562 | |||
579 | path_put(&nd->path); | 563 | path_put(&nd->path); |
580 | walk_init_root(link, nd); | 564 | |
565 | read_lock(&fs->lock); | ||
566 | nd->path = fs->root; | ||
567 | path_get(&fs->root); | ||
568 | read_unlock(&fs->lock); | ||
581 | } | 569 | } |
570 | |||
582 | res = link_path_walk(link, nd); | 571 | res = link_path_walk(link, nd); |
583 | if (nd->depth || res || nd->last_type!=LAST_NORM) | 572 | if (nd->depth || res || nd->last_type!=LAST_NORM) |
584 | return res; | 573 | return res; |
@@ -859,7 +848,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
859 | nd->flags |= LOOKUP_CONTINUE; | 848 | nd->flags |= LOOKUP_CONTINUE; |
860 | err = exec_permission_lite(inode); | 849 | err = exec_permission_lite(inode); |
861 | if (err == -EAGAIN) | 850 | if (err == -EAGAIN) |
862 | err = vfs_permission(nd, MAY_EXEC); | 851 | err = inode_permission(nd->path.dentry->d_inode, |
852 | MAY_EXEC); | ||
863 | if (err) | 853 | if (err) |
864 | break; | 854 | break; |
865 | 855 | ||
@@ -1493,9 +1483,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1493 | return error; | 1483 | return error; |
1494 | } | 1484 | } |
1495 | 1485 | ||
1496 | int may_open(struct nameidata *nd, int acc_mode, int flag) | 1486 | int may_open(struct path *path, int acc_mode, int flag) |
1497 | { | 1487 | { |
1498 | struct dentry *dentry = nd->path.dentry; | 1488 | struct dentry *dentry = path->dentry; |
1499 | struct inode *inode = dentry->d_inode; | 1489 | struct inode *inode = dentry->d_inode; |
1500 | int error; | 1490 | int error; |
1501 | 1491 | ||
@@ -1516,13 +1506,13 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1516 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | 1506 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { |
1517 | flag &= ~O_TRUNC; | 1507 | flag &= ~O_TRUNC; |
1518 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | 1508 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { |
1519 | if (nd->path.mnt->mnt_flags & MNT_NODEV) | 1509 | if (path->mnt->mnt_flags & MNT_NODEV) |
1520 | return -EACCES; | 1510 | return -EACCES; |
1521 | 1511 | ||
1522 | flag &= ~O_TRUNC; | 1512 | flag &= ~O_TRUNC; |
1523 | } | 1513 | } |
1524 | 1514 | ||
1525 | error = vfs_permission(nd, acc_mode); | 1515 | error = inode_permission(inode, acc_mode); |
1526 | if (error) | 1516 | if (error) |
1527 | return error; | 1517 | return error; |
1528 | /* | 1518 | /* |
@@ -1556,6 +1546,9 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1556 | * Refuse to truncate files with mandatory locks held on them. | 1546 | * Refuse to truncate files with mandatory locks held on them. |
1557 | */ | 1547 | */ |
1558 | error = locks_verify_locked(inode); | 1548 | error = locks_verify_locked(inode); |
1549 | if (!error) | ||
1550 | error = security_path_truncate(path, 0, | ||
1551 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); | ||
1559 | if (!error) { | 1552 | if (!error) { |
1560 | DQUOT_INIT(inode); | 1553 | DQUOT_INIT(inode); |
1561 | 1554 | ||
@@ -1586,14 +1579,18 @@ static int __open_namei_create(struct nameidata *nd, struct path *path, | |||
1586 | 1579 | ||
1587 | if (!IS_POSIXACL(dir->d_inode)) | 1580 | if (!IS_POSIXACL(dir->d_inode)) |
1588 | mode &= ~current->fs->umask; | 1581 | mode &= ~current->fs->umask; |
1582 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); | ||
1583 | if (error) | ||
1584 | goto out_unlock; | ||
1589 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); | 1585 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
1586 | out_unlock: | ||
1590 | mutex_unlock(&dir->d_inode->i_mutex); | 1587 | mutex_unlock(&dir->d_inode->i_mutex); |
1591 | dput(nd->path.dentry); | 1588 | dput(nd->path.dentry); |
1592 | nd->path.dentry = path->dentry; | 1589 | nd->path.dentry = path->dentry; |
1593 | if (error) | 1590 | if (error) |
1594 | return error; | 1591 | return error; |
1595 | /* Don't check for write permission, don't truncate */ | 1592 | /* Don't check for write permission, don't truncate */ |
1596 | return may_open(nd, 0, flag & ~O_TRUNC); | 1593 | return may_open(&nd->path, 0, flag & ~O_TRUNC); |
1597 | } | 1594 | } |
1598 | 1595 | ||
1599 | /* | 1596 | /* |
@@ -1779,7 +1776,7 @@ ok: | |||
1779 | if (error) | 1776 | if (error) |
1780 | goto exit; | 1777 | goto exit; |
1781 | } | 1778 | } |
1782 | error = may_open(&nd, acc_mode, flag); | 1779 | error = may_open(&nd.path, acc_mode, flag); |
1783 | if (error) { | 1780 | if (error) { |
1784 | if (will_write) | 1781 | if (will_write) |
1785 | mnt_drop_write(nd.path.mnt); | 1782 | mnt_drop_write(nd.path.mnt); |
@@ -1999,6 +1996,9 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1999 | error = mnt_want_write(nd.path.mnt); | 1996 | error = mnt_want_write(nd.path.mnt); |
2000 | if (error) | 1997 | if (error) |
2001 | goto out_dput; | 1998 | goto out_dput; |
1999 | error = security_path_mknod(&nd.path, dentry, mode, dev); | ||
2000 | if (error) | ||
2001 | goto out_drop_write; | ||
2002 | switch (mode & S_IFMT) { | 2002 | switch (mode & S_IFMT) { |
2003 | case 0: case S_IFREG: | 2003 | case 0: case S_IFREG: |
2004 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); | 2004 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); |
@@ -2011,6 +2011,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
2011 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); | 2011 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); |
2012 | break; | 2012 | break; |
2013 | } | 2013 | } |
2014 | out_drop_write: | ||
2014 | mnt_drop_write(nd.path.mnt); | 2015 | mnt_drop_write(nd.path.mnt); |
2015 | out_dput: | 2016 | out_dput: |
2016 | dput(dentry); | 2017 | dput(dentry); |
@@ -2070,7 +2071,11 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2070 | error = mnt_want_write(nd.path.mnt); | 2071 | error = mnt_want_write(nd.path.mnt); |
2071 | if (error) | 2072 | if (error) |
2072 | goto out_dput; | 2073 | goto out_dput; |
2074 | error = security_path_mkdir(&nd.path, dentry, mode); | ||
2075 | if (error) | ||
2076 | goto out_drop_write; | ||
2073 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 2077 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
2078 | out_drop_write: | ||
2074 | mnt_drop_write(nd.path.mnt); | 2079 | mnt_drop_write(nd.path.mnt); |
2075 | out_dput: | 2080 | out_dput: |
2076 | dput(dentry); | 2081 | dput(dentry); |
@@ -2180,7 +2185,11 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2180 | error = mnt_want_write(nd.path.mnt); | 2185 | error = mnt_want_write(nd.path.mnt); |
2181 | if (error) | 2186 | if (error) |
2182 | goto exit3; | 2187 | goto exit3; |
2188 | error = security_path_rmdir(&nd.path, dentry); | ||
2189 | if (error) | ||
2190 | goto exit4; | ||
2183 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 2191 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); |
2192 | exit4: | ||
2184 | mnt_drop_write(nd.path.mnt); | 2193 | mnt_drop_write(nd.path.mnt); |
2185 | exit3: | 2194 | exit3: |
2186 | dput(dentry); | 2195 | dput(dentry); |
@@ -2265,7 +2274,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2265 | error = mnt_want_write(nd.path.mnt); | 2274 | error = mnt_want_write(nd.path.mnt); |
2266 | if (error) | 2275 | if (error) |
2267 | goto exit2; | 2276 | goto exit2; |
2277 | error = security_path_unlink(&nd.path, dentry); | ||
2278 | if (error) | ||
2279 | goto exit3; | ||
2268 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); | 2280 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); |
2281 | exit3: | ||
2269 | mnt_drop_write(nd.path.mnt); | 2282 | mnt_drop_write(nd.path.mnt); |
2270 | exit2: | 2283 | exit2: |
2271 | dput(dentry); | 2284 | dput(dentry); |
@@ -2346,7 +2359,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2346 | error = mnt_want_write(nd.path.mnt); | 2359 | error = mnt_want_write(nd.path.mnt); |
2347 | if (error) | 2360 | if (error) |
2348 | goto out_dput; | 2361 | goto out_dput; |
2362 | error = security_path_symlink(&nd.path, dentry, from); | ||
2363 | if (error) | ||
2364 | goto out_drop_write; | ||
2349 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); | 2365 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); |
2366 | out_drop_write: | ||
2350 | mnt_drop_write(nd.path.mnt); | 2367 | mnt_drop_write(nd.path.mnt); |
2351 | out_dput: | 2368 | out_dput: |
2352 | dput(dentry); | 2369 | dput(dentry); |
@@ -2443,7 +2460,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2443 | error = mnt_want_write(nd.path.mnt); | 2460 | error = mnt_want_write(nd.path.mnt); |
2444 | if (error) | 2461 | if (error) |
2445 | goto out_dput; | 2462 | goto out_dput; |
2463 | error = security_path_link(old_path.dentry, &nd.path, new_dentry); | ||
2464 | if (error) | ||
2465 | goto out_drop_write; | ||
2446 | error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); | 2466 | error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); |
2467 | out_drop_write: | ||
2447 | mnt_drop_write(nd.path.mnt); | 2468 | mnt_drop_write(nd.path.mnt); |
2448 | out_dput: | 2469 | out_dput: |
2449 | dput(new_dentry); | 2470 | dput(new_dentry); |
@@ -2679,8 +2700,13 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname, | |||
2679 | error = mnt_want_write(oldnd.path.mnt); | 2700 | error = mnt_want_write(oldnd.path.mnt); |
2680 | if (error) | 2701 | if (error) |
2681 | goto exit5; | 2702 | goto exit5; |
2703 | error = security_path_rename(&oldnd.path, old_dentry, | ||
2704 | &newnd.path, new_dentry); | ||
2705 | if (error) | ||
2706 | goto exit6; | ||
2682 | error = vfs_rename(old_dir->d_inode, old_dentry, | 2707 | error = vfs_rename(old_dir->d_inode, old_dentry, |
2683 | new_dir->d_inode, new_dentry); | 2708 | new_dir->d_inode, new_dentry); |
2709 | exit6: | ||
2684 | mnt_drop_write(oldnd.path.mnt); | 2710 | mnt_drop_write(oldnd.path.mnt); |
2685 | exit5: | 2711 | exit5: |
2686 | dput(new_dentry); | 2712 | dput(new_dentry); |
@@ -2750,13 +2776,16 @@ int vfs_follow_link(struct nameidata *nd, const char *link) | |||
2750 | /* get the link contents into pagecache */ | 2776 | /* get the link contents into pagecache */ |
2751 | static char *page_getlink(struct dentry * dentry, struct page **ppage) | 2777 | static char *page_getlink(struct dentry * dentry, struct page **ppage) |
2752 | { | 2778 | { |
2753 | struct page * page; | 2779 | char *kaddr; |
2780 | struct page *page; | ||
2754 | struct address_space *mapping = dentry->d_inode->i_mapping; | 2781 | struct address_space *mapping = dentry->d_inode->i_mapping; |
2755 | page = read_mapping_page(mapping, 0, NULL); | 2782 | page = read_mapping_page(mapping, 0, NULL); |
2756 | if (IS_ERR(page)) | 2783 | if (IS_ERR(page)) |
2757 | return (char*)page; | 2784 | return (char*)page; |
2758 | *ppage = page; | 2785 | *ppage = page; |
2759 | return kmap(page); | 2786 | kaddr = kmap(page); |
2787 | nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1); | ||
2788 | return kaddr; | ||
2760 | } | 2789 | } |
2761 | 2790 | ||
2762 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 2791 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
@@ -2849,7 +2878,6 @@ EXPORT_SYMBOL(path_lookup); | |||
2849 | EXPORT_SYMBOL(kern_path); | 2878 | EXPORT_SYMBOL(kern_path); |
2850 | EXPORT_SYMBOL(vfs_path_lookup); | 2879 | EXPORT_SYMBOL(vfs_path_lookup); |
2851 | EXPORT_SYMBOL(inode_permission); | 2880 | EXPORT_SYMBOL(inode_permission); |
2852 | EXPORT_SYMBOL(vfs_permission); | ||
2853 | EXPORT_SYMBOL(file_permission); | 2881 | EXPORT_SYMBOL(file_permission); |
2854 | EXPORT_SYMBOL(unlock_rename); | 2882 | EXPORT_SYMBOL(unlock_rename); |
2855 | EXPORT_SYMBOL(vfs_create); | 2883 | EXPORT_SYMBOL(vfs_create); |
@@ -2865,3 +2893,10 @@ EXPORT_SYMBOL(vfs_symlink); | |||
2865 | EXPORT_SYMBOL(vfs_unlink); | 2893 | EXPORT_SYMBOL(vfs_unlink); |
2866 | EXPORT_SYMBOL(dentry_unhash); | 2894 | EXPORT_SYMBOL(dentry_unhash); |
2867 | EXPORT_SYMBOL(generic_readlink); | 2895 | EXPORT_SYMBOL(generic_readlink); |
2896 | |||
2897 | /* to be mentioned only in INIT_TASK */ | ||
2898 | struct fs_struct init_fs = { | ||
2899 | .count = ATOMIC_INIT(1), | ||
2900 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | ||
2901 | .umask = 0022, | ||
2902 | }; | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 1c09cab8f7cf..a40685d800a8 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1990,7 +1990,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
1990 | if (!new_ns->root) { | 1990 | if (!new_ns->root) { |
1991 | up_write(&namespace_sem); | 1991 | up_write(&namespace_sem); |
1992 | kfree(new_ns); | 1992 | kfree(new_ns); |
1993 | return ERR_PTR(-ENOMEM);; | 1993 | return ERR_PTR(-ENOMEM); |
1994 | } | 1994 | } |
1995 | spin_lock(&vfsmount_lock); | 1995 | spin_lock(&vfsmount_lock); |
1996 | list_add_tail(&new_ns->list, &new_ns->root->mnt_list); | 1996 | list_add_tail(&new_ns->list, &new_ns->root->mnt_list); |
diff --git a/fs/nfsctl.c b/fs/nfsctl.c index b1acbd6ab6fb..b27451909dff 100644 --- a/fs/nfsctl.c +++ b/fs/nfsctl.c | |||
@@ -38,9 +38,10 @@ static struct file *do_open(char *name, int flags) | |||
38 | return ERR_PTR(error); | 38 | return ERR_PTR(error); |
39 | 39 | ||
40 | if (flags == O_RDWR) | 40 | if (flags == O_RDWR) |
41 | error = may_open(&nd,MAY_READ|MAY_WRITE,FMODE_READ|FMODE_WRITE); | 41 | error = may_open(&nd.path, MAY_READ|MAY_WRITE, |
42 | FMODE_READ|FMODE_WRITE); | ||
42 | else | 43 | else |
43 | error = may_open(&nd, MAY_WRITE, FMODE_WRITE); | 44 | error = may_open(&nd.path, MAY_WRITE, FMODE_WRITE); |
44 | 45 | ||
45 | if (!error) | 46 | if (!error) |
46 | return dentry_open(nd.path.dentry, nd.path.mnt, flags, | 47 | return dentry_open(nd.path.dentry, nd.path.mnt, flags, |
diff --git a/fs/notify/Kconfig b/fs/notify/Kconfig new file mode 100644 index 000000000000..50914d7303c6 --- /dev/null +++ b/fs/notify/Kconfig | |||
@@ -0,0 +1,2 @@ | |||
1 | source "fs/notify/dnotify/Kconfig" | ||
2 | source "fs/notify/inotify/Kconfig" | ||
diff --git a/fs/notify/Makefile b/fs/notify/Makefile new file mode 100644 index 000000000000..5a95b6010ce7 --- /dev/null +++ b/fs/notify/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-y += dnotify/ | ||
2 | obj-y += inotify/ | ||
diff --git a/fs/notify/dnotify/Kconfig b/fs/notify/dnotify/Kconfig new file mode 100644 index 000000000000..26adf5dfa646 --- /dev/null +++ b/fs/notify/dnotify/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | config DNOTIFY | ||
2 | bool "Dnotify support" | ||
3 | default y | ||
4 | help | ||
5 | Dnotify is a directory-based per-fd file change notification system | ||
6 | that uses signals to communicate events to user-space. There exist | ||
7 | superior alternatives, but some applications may still rely on | ||
8 | dnotify. | ||
9 | |||
10 | If unsure, say Y. | ||
diff --git a/fs/notify/dnotify/Makefile b/fs/notify/dnotify/Makefile new file mode 100644 index 000000000000..f145251dcadb --- /dev/null +++ b/fs/notify/dnotify/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_DNOTIFY) += dnotify.o | |||
diff --git a/fs/dnotify.c b/fs/notify/dnotify/dnotify.c index 676073b8dda5..b0aa2cde80bd 100644 --- a/fs/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -115,9 +115,6 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
115 | dn->dn_next = inode->i_dnotify; | 115 | dn->dn_next = inode->i_dnotify; |
116 | inode->i_dnotify = dn; | 116 | inode->i_dnotify = dn; |
117 | spin_unlock(&inode->i_lock); | 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 | return 0; | 118 | return 0; |
122 | 119 | ||
123 | out_free: | 120 | out_free: |
diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig new file mode 100644 index 000000000000..446792841023 --- /dev/null +++ b/fs/notify/inotify/Kconfig | |||
@@ -0,0 +1,27 @@ | |||
1 | config INOTIFY | ||
2 | bool "Inotify file change notification support" | ||
3 | default y | ||
4 | ---help--- | ||
5 | Say Y here to enable inotify support. Inotify is a file change | ||
6 | notification system and a replacement for dnotify. Inotify fixes | ||
7 | numerous shortcomings in dnotify and introduces several new features | ||
8 | including multiple file events, one-shot support, and unmount | ||
9 | notification. | ||
10 | |||
11 | For more information, see <file:Documentation/filesystems/inotify.txt> | ||
12 | |||
13 | If unsure, say Y. | ||
14 | |||
15 | config INOTIFY_USER | ||
16 | bool "Inotify support for userspace" | ||
17 | depends on INOTIFY | ||
18 | default y | ||
19 | ---help--- | ||
20 | Say Y here to enable inotify support for userspace, including the | ||
21 | associated system calls. Inotify allows monitoring of both files and | ||
22 | directories via a single open fd. Events are read from the file | ||
23 | descriptor, which is also select()- and poll()-able. | ||
24 | |||
25 | For more information, see <file:Documentation/filesystems/inotify.txt> | ||
26 | |||
27 | If unsure, say Y. | ||
diff --git a/fs/notify/inotify/Makefile b/fs/notify/inotify/Makefile new file mode 100644 index 000000000000..e290f3bb9d8d --- /dev/null +++ b/fs/notify/inotify/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_INOTIFY) += inotify.o | ||
2 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o | ||
diff --git a/fs/inotify.c b/fs/notify/inotify/inotify.c index dae3f28f30d4..dae3f28f30d4 100644 --- a/fs/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
diff --git a/fs/inotify_user.c b/fs/notify/inotify/inotify_user.c index e2425bbd871f..400f8064a548 100644 --- a/fs/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -76,10 +76,10 @@ struct inotify_device { | |||
76 | struct mutex ev_mutex; /* protects event queue */ | 76 | struct mutex ev_mutex; /* protects event queue */ |
77 | struct mutex up_mutex; /* synchronizes watch updates */ | 77 | struct mutex up_mutex; /* synchronizes watch updates */ |
78 | struct list_head events; /* list of queued events */ | 78 | struct list_head events; /* list of queued events */ |
79 | atomic_t count; /* reference count */ | ||
80 | struct user_struct *user; /* user who opened this dev */ | 79 | struct user_struct *user; /* user who opened this dev */ |
81 | struct inotify_handle *ih; /* inotify handle */ | 80 | struct inotify_handle *ih; /* inotify handle */ |
82 | struct fasync_struct *fa; /* async notification */ | 81 | struct fasync_struct *fa; /* async notification */ |
82 | atomic_t count; /* reference count */ | ||
83 | unsigned int queue_size; /* size of the queue (bytes) */ | 83 | unsigned int queue_size; /* size of the queue (bytes) */ |
84 | unsigned int event_count; /* number of pending events */ | 84 | unsigned int event_count; /* number of pending events */ |
85 | unsigned int max_events; /* maximum number of events */ | 85 | unsigned int max_events; /* maximum number of events */ |
@@ -272,6 +272,8 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) | |||
272 | goto put_write_and_out; | 272 | goto put_write_and_out; |
273 | 273 | ||
274 | error = locks_verify_truncate(inode, NULL, length); | 274 | error = locks_verify_truncate(inode, NULL, length); |
275 | if (!error) | ||
276 | error = security_path_truncate(&path, length, 0); | ||
275 | if (!error) { | 277 | if (!error) { |
276 | DQUOT_INIT(inode); | 278 | DQUOT_INIT(inode); |
277 | error = do_truncate(path.dentry, length, 0, NULL); | 279 | error = do_truncate(path.dentry, length, 0, NULL); |
@@ -329,6 +331,9 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
329 | 331 | ||
330 | error = locks_verify_truncate(inode, file, length); | 332 | error = locks_verify_truncate(inode, file, length); |
331 | if (!error) | 333 | if (!error) |
334 | error = security_path_truncate(&file->f_path, length, | ||
335 | ATTR_MTIME|ATTR_CTIME); | ||
336 | if (!error) | ||
332 | error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); | 337 | error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); |
333 | out_putf: | 338 | out_putf: |
334 | fput(file); | 339 | fput(file); |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 6c4c2c69449f..145c2d3e5e01 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1753,6 +1753,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1753 | struct inode *inode) | 1753 | struct inode *inode) |
1754 | { | 1754 | { |
1755 | struct super_block *sb; | 1755 | struct super_block *sb; |
1756 | struct reiserfs_iget_args args; | ||
1756 | INITIALIZE_PATH(path_to_key); | 1757 | INITIALIZE_PATH(path_to_key); |
1757 | struct cpu_key key; | 1758 | struct cpu_key key; |
1758 | struct item_head ih; | 1759 | struct item_head ih; |
@@ -1780,6 +1781,14 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1780 | err = -ENOMEM; | 1781 | err = -ENOMEM; |
1781 | goto out_bad_inode; | 1782 | goto out_bad_inode; |
1782 | } | 1783 | } |
1784 | args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); | ||
1785 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); | ||
1786 | args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); | ||
1787 | if (insert_inode_locked4(inode, args.objectid, | ||
1788 | reiserfs_find_actor, &args) < 0) { | ||
1789 | err = -EINVAL; | ||
1790 | goto out_bad_inode; | ||
1791 | } | ||
1783 | if (old_format_only(sb)) | 1792 | if (old_format_only(sb)) |
1784 | /* not a perfect generation count, as object ids can be reused, but | 1793 | /* not a perfect generation count, as object ids can be reused, but |
1785 | ** this is as good as reiserfs can do right now. | 1794 | ** this is as good as reiserfs can do right now. |
@@ -1859,13 +1868,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1859 | } else { | 1868 | } else { |
1860 | inode2sd(&sd, inode, inode->i_size); | 1869 | inode2sd(&sd, inode, inode->i_size); |
1861 | } | 1870 | } |
1862 | // these do not go to on-disk stat data | ||
1863 | inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); | ||
1864 | |||
1865 | // store in in-core inode the key of stat data and version all | 1871 | // store in in-core inode the key of stat data and version all |
1866 | // object items will have (directory items will have old offset | 1872 | // object items will have (directory items will have old offset |
1867 | // format, other new objects will consist of new items) | 1873 | // format, other new objects will consist of new items) |
1868 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); | ||
1869 | if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) | 1874 | if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) |
1870 | set_inode_item_key_version(inode, KEY_FORMAT_3_5); | 1875 | set_inode_item_key_version(inode, KEY_FORMAT_3_5); |
1871 | else | 1876 | else |
@@ -1929,7 +1934,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1929 | reiserfs_mark_inode_private(inode); | 1934 | reiserfs_mark_inode_private(inode); |
1930 | } | 1935 | } |
1931 | 1936 | ||
1932 | insert_inode_hash(inode); | ||
1933 | reiserfs_update_sd(th, inode); | 1937 | reiserfs_update_sd(th, inode); |
1934 | reiserfs_check_path(&path_to_key); | 1938 | reiserfs_check_path(&path_to_key); |
1935 | 1939 | ||
@@ -1956,6 +1960,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1956 | out_inserted_sd: | 1960 | out_inserted_sd: |
1957 | inode->i_nlink = 0; | 1961 | inode->i_nlink = 0; |
1958 | th->t_trans_id = 0; /* so the caller can't use this handle later */ | 1962 | th->t_trans_id = 0; /* so the caller can't use this handle later */ |
1963 | unlock_new_inode(inode); /* OK to do even if we hadn't locked it */ | ||
1959 | 1964 | ||
1960 | /* If we were inheriting an ACL, we need to release the lock so that | 1965 | /* If we were inheriting an ACL, we need to release the lock so that |
1961 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking | 1966 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 4f322e5ed840..738967f6c8ee 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -646,6 +646,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
646 | err = journal_end(&th, dir->i_sb, jbegin_count); | 646 | err = journal_end(&th, dir->i_sb, jbegin_count); |
647 | if (err) | 647 | if (err) |
648 | retval = err; | 648 | retval = err; |
649 | unlock_new_inode(inode); | ||
649 | iput(inode); | 650 | iput(inode); |
650 | goto out_failed; | 651 | goto out_failed; |
651 | } | 652 | } |
@@ -653,6 +654,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
653 | reiserfs_update_inode_transaction(dir); | 654 | reiserfs_update_inode_transaction(dir); |
654 | 655 | ||
655 | d_instantiate(dentry, inode); | 656 | d_instantiate(dentry, inode); |
657 | unlock_new_inode(inode); | ||
656 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 658 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
657 | 659 | ||
658 | out_failed: | 660 | out_failed: |
@@ -727,11 +729,13 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
727 | err = journal_end(&th, dir->i_sb, jbegin_count); | 729 | err = journal_end(&th, dir->i_sb, jbegin_count); |
728 | if (err) | 730 | if (err) |
729 | retval = err; | 731 | retval = err; |
732 | unlock_new_inode(inode); | ||
730 | iput(inode); | 733 | iput(inode); |
731 | goto out_failed; | 734 | goto out_failed; |
732 | } | 735 | } |
733 | 736 | ||
734 | d_instantiate(dentry, inode); | 737 | d_instantiate(dentry, inode); |
738 | unlock_new_inode(inode); | ||
735 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 739 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
736 | 740 | ||
737 | out_failed: | 741 | out_failed: |
@@ -812,6 +816,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
812 | err = journal_end(&th, dir->i_sb, jbegin_count); | 816 | err = journal_end(&th, dir->i_sb, jbegin_count); |
813 | if (err) | 817 | if (err) |
814 | retval = err; | 818 | retval = err; |
819 | unlock_new_inode(inode); | ||
815 | iput(inode); | 820 | iput(inode); |
816 | goto out_failed; | 821 | goto out_failed; |
817 | } | 822 | } |
@@ -819,6 +824,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
819 | reiserfs_update_sd(&th, dir); | 824 | reiserfs_update_sd(&th, dir); |
820 | 825 | ||
821 | d_instantiate(dentry, inode); | 826 | d_instantiate(dentry, inode); |
827 | unlock_new_inode(inode); | ||
822 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 828 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
823 | out_failed: | 829 | out_failed: |
824 | if (locked) | 830 | if (locked) |
@@ -1096,11 +1102,13 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1096 | err = journal_end(&th, parent_dir->i_sb, jbegin_count); | 1102 | err = journal_end(&th, parent_dir->i_sb, jbegin_count); |
1097 | if (err) | 1103 | if (err) |
1098 | retval = err; | 1104 | retval = err; |
1105 | unlock_new_inode(inode); | ||
1099 | iput(inode); | 1106 | iput(inode); |
1100 | goto out_failed; | 1107 | goto out_failed; |
1101 | } | 1108 | } |
1102 | 1109 | ||
1103 | d_instantiate(dentry, inode); | 1110 | d_instantiate(dentry, inode); |
1111 | unlock_new_inode(inode); | ||
1104 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count); | 1112 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count); |
1105 | out_failed: | 1113 | out_failed: |
1106 | reiserfs_write_unlock(parent_dir->i_sb); | 1114 | reiserfs_write_unlock(parent_dir->i_sb); |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 16c211558c22..99d8b8cfc9b7 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -389,8 +389,14 @@ char *mangle_path(char *s, char *p, char *esc) | |||
389 | } | 389 | } |
390 | EXPORT_SYMBOL(mangle_path); | 390 | EXPORT_SYMBOL(mangle_path); |
391 | 391 | ||
392 | /* | 392 | /** |
393 | * return the absolute path of 'dentry' residing in mount 'mnt'. | 393 | * seq_path - seq_file interface to print a pathname |
394 | * @m: the seq_file handle | ||
395 | * @path: the struct path to print | ||
396 | * @esc: set of characters to escape in the output | ||
397 | * | ||
398 | * return the absolute path of 'path', as represented by the | ||
399 | * dentry / mnt pair in the path parameter. | ||
394 | */ | 400 | */ |
395 | int seq_path(struct seq_file *m, struct path *path, char *esc) | 401 | int seq_path(struct seq_file *m, struct path *path, char *esc) |
396 | { | 402 | { |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index df0d435baa48..3d81bf58dae2 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/buffer_head.h> | 28 | #include <linux/buffer_head.h> |
29 | #include <linux/vfs.h> | 29 | #include <linux/vfs.h> |
30 | #include <linux/namei.h> | ||
30 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |
31 | #include "sysv.h" | 32 | #include "sysv.h" |
32 | 33 | ||
@@ -163,8 +164,11 @@ void sysv_set_inode(struct inode *inode, dev_t rdev) | |||
163 | if (inode->i_blocks) { | 164 | if (inode->i_blocks) { |
164 | inode->i_op = &sysv_symlink_inode_operations; | 165 | inode->i_op = &sysv_symlink_inode_operations; |
165 | inode->i_mapping->a_ops = &sysv_aops; | 166 | inode->i_mapping->a_ops = &sysv_aops; |
166 | } else | 167 | } else { |
167 | inode->i_op = &sysv_fast_symlink_inode_operations; | 168 | inode->i_op = &sysv_fast_symlink_inode_operations; |
169 | nd_terminate_link(SYSV_I(inode)->i_data, inode->i_size, | ||
170 | sizeof(SYSV_I(inode)->i_data) - 1); | ||
171 | } | ||
168 | } else | 172 | } else |
169 | init_special_inode(inode, inode->i_mode, rdev); | 173 | init_special_inode(inode, inode->i_mode, rdev); |
170 | } | 174 | } |