diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 12:10:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 12:10:19 -0400 |
commit | 790eac5640abf7a57fa3a644386df330e18c11b0 (patch) | |
tree | 08de20bde44f59e51b91ff473a71047c2957e8c9 | |
parent | 0b0585c3e192967cb2ef0ac0816eb8a8c8d99840 (diff) | |
parent | 48bde8d3620f5f3c6ae9ff599eb404055ae51664 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second set of VFS changes from Al Viro:
"Assorted f_pos race fixes, making do_splice_direct() safe to call with
i_mutex on parent, O_TMPFILE support, Jeff's locks.c series,
->d_hash/->d_compare calling conventions changes from Linus, misc
stuff all over the place."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
Document ->tmpfile()
ext4: ->tmpfile() support
vfs: export lseek_execute() to modules
lseek_execute() doesn't need an inode passed to it
block_dev: switch to fixed_size_llseek()
cpqphp_sysfs: switch to fixed_size_llseek()
tile-srom: switch to fixed_size_llseek()
proc_powerpc: switch to fixed_size_llseek()
ubi/cdev: switch to fixed_size_llseek()
pci/proc: switch to fixed_size_llseek()
isapnp: switch to fixed_size_llseek()
lpfc: switch to fixed_size_llseek()
locks: give the blocked_hash its own spinlock
locks: add a new "lm_owner_key" lock operation
locks: turn the blocked_list into a hashtable
locks: convert fl_link to a hlist_node
locks: avoid taking global lock if possible when waking up blocked waiters
locks: protect most of the file_lock handling with i_lock
locks: encapsulate the fl_link list handling
locks: make "added" in __posix_lock_file a bool
...
98 files changed, 979 insertions, 986 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 9858f337529c..fe7afe225381 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -11,10 +11,8 @@ be able to use diff(1). | |||
11 | prototypes: | 11 | prototypes: |
12 | int (*d_revalidate)(struct dentry *, unsigned int); | 12 | int (*d_revalidate)(struct dentry *, unsigned int); |
13 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 13 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
14 | int (*d_hash)(const struct dentry *, const struct inode *, | 14 | int (*d_hash)(const struct dentry *, struct qstr *); |
15 | struct qstr *); | 15 | int (*d_compare)(const struct dentry *, const struct dentry *, |
16 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
17 | const struct dentry *, const struct inode *, | ||
18 | unsigned int, const char *, const struct qstr *); | 16 | unsigned int, const char *, const struct qstr *); |
19 | int (*d_delete)(struct dentry *); | 17 | int (*d_delete)(struct dentry *); |
20 | void (*d_release)(struct dentry *); | 18 | void (*d_release)(struct dentry *); |
@@ -66,6 +64,7 @@ prototypes: | |||
66 | int (*atomic_open)(struct inode *, struct dentry *, | 64 | int (*atomic_open)(struct inode *, struct dentry *, |
67 | struct file *, unsigned open_flag, | 65 | struct file *, unsigned open_flag, |
68 | umode_t create_mode, int *opened); | 66 | umode_t create_mode, int *opened); |
67 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | ||
69 | 68 | ||
70 | locking rules: | 69 | locking rules: |
71 | all may block | 70 | all may block |
@@ -93,6 +92,7 @@ removexattr: yes | |||
93 | fiemap: no | 92 | fiemap: no |
94 | update_time: no | 93 | update_time: no |
95 | atomic_open: yes | 94 | atomic_open: yes |
95 | tmpfile: no | ||
96 | 96 | ||
97 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on | 97 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on |
98 | victim. | 98 | victim. |
@@ -344,25 +344,38 @@ prototypes: | |||
344 | 344 | ||
345 | 345 | ||
346 | locking rules: | 346 | locking rules: |
347 | file_lock_lock may block | 347 | inode->i_lock may block |
348 | fl_copy_lock: yes no | 348 | fl_copy_lock: yes no |
349 | fl_release_private: maybe no | 349 | fl_release_private: maybe no |
350 | 350 | ||
351 | ----------------------- lock_manager_operations --------------------------- | 351 | ----------------------- lock_manager_operations --------------------------- |
352 | prototypes: | 352 | prototypes: |
353 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); | 353 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); |
354 | unsigned long (*lm_owner_key)(struct file_lock *); | ||
354 | void (*lm_notify)(struct file_lock *); /* unblock callback */ | 355 | void (*lm_notify)(struct file_lock *); /* unblock callback */ |
355 | int (*lm_grant)(struct file_lock *, struct file_lock *, int); | 356 | int (*lm_grant)(struct file_lock *, struct file_lock *, int); |
356 | void (*lm_break)(struct file_lock *); /* break_lease callback */ | 357 | void (*lm_break)(struct file_lock *); /* break_lease callback */ |
357 | int (*lm_change)(struct file_lock **, int); | 358 | int (*lm_change)(struct file_lock **, int); |
358 | 359 | ||
359 | locking rules: | 360 | locking rules: |
360 | file_lock_lock may block | 361 | |
361 | lm_compare_owner: yes no | 362 | inode->i_lock blocked_lock_lock may block |
362 | lm_notify: yes no | 363 | lm_compare_owner: yes[1] maybe no |
363 | lm_grant: no no | 364 | lm_owner_key yes[1] yes no |
364 | lm_break: yes no | 365 | lm_notify: yes yes no |
365 | lm_change yes no | 366 | lm_grant: no no no |
367 | lm_break: yes no no | ||
368 | lm_change yes no no | ||
369 | |||
370 | [1]: ->lm_compare_owner and ->lm_owner_key are generally called with | ||
371 | *an* inode->i_lock held. It may not be the i_lock of the inode | ||
372 | associated with either file_lock argument! This is the case with deadlock | ||
373 | detection, since the code has to chase down the owners of locks that may | ||
374 | be entirely unrelated to the one on which the lock is being acquired. | ||
375 | For deadlock detection however, the blocked_lock_lock is also held. The | ||
376 | fact that these locks are held ensures that the file_locks do not | ||
377 | disappear out from under you while doing the comparison or generating an | ||
378 | owner key. | ||
366 | 379 | ||
367 | --------------------------- buffer_head ----------------------------------- | 380 | --------------------------- buffer_head ----------------------------------- |
368 | prototypes: | 381 | prototypes: |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index e6bd1ffd821e..1f0ba30ae47e 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -360,6 +360,8 @@ struct inode_operations { | |||
360 | int (*removexattr) (struct dentry *, const char *); | 360 | int (*removexattr) (struct dentry *, const char *); |
361 | void (*update_time)(struct inode *, struct timespec *, int); | 361 | void (*update_time)(struct inode *, struct timespec *, int); |
362 | int (*atomic_open)(struct inode *, struct dentry *, | 362 | int (*atomic_open)(struct inode *, struct dentry *, |
363 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | ||
364 | } ____cacheline_aligned; | ||
363 | struct file *, unsigned open_flag, | 365 | struct file *, unsigned open_flag, |
364 | umode_t create_mode, int *opened); | 366 | umode_t create_mode, int *opened); |
365 | }; | 367 | }; |
@@ -472,6 +474,9 @@ otherwise noted. | |||
472 | component is negative or needs lookup. Cached positive dentries are | 474 | component is negative or needs lookup. Cached positive dentries are |
473 | still handled by f_op->open(). | 475 | still handled by f_op->open(). |
474 | 476 | ||
477 | tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to | ||
478 | atomically creating, opening and unlinking a file in given directory. | ||
479 | |||
475 | The Address Space Object | 480 | The Address Space Object |
476 | ======================== | 481 | ======================== |
477 | 482 | ||
@@ -901,10 +906,8 @@ defined: | |||
901 | struct dentry_operations { | 906 | struct dentry_operations { |
902 | int (*d_revalidate)(struct dentry *, unsigned int); | 907 | int (*d_revalidate)(struct dentry *, unsigned int); |
903 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 908 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
904 | int (*d_hash)(const struct dentry *, const struct inode *, | 909 | int (*d_hash)(const struct dentry *, struct qstr *); |
905 | struct qstr *); | 910 | int (*d_compare)(const struct dentry *, const struct dentry *, |
906 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
907 | const struct dentry *, const struct inode *, | ||
908 | unsigned int, const char *, const struct qstr *); | 911 | unsigned int, const char *, const struct qstr *); |
909 | int (*d_delete)(const struct dentry *); | 912 | int (*d_delete)(const struct dentry *); |
910 | void (*d_release)(struct dentry *); | 913 | void (*d_release)(struct dentry *); |
@@ -949,25 +952,24 @@ struct dentry_operations { | |||
949 | 952 | ||
950 | d_hash: called when the VFS adds a dentry to the hash table. The first | 953 | d_hash: called when the VFS adds a dentry to the hash table. The first |
951 | dentry passed to d_hash is the parent directory that the name is | 954 | dentry passed to d_hash is the parent directory that the name is |
952 | to be hashed into. The inode is the dentry's inode. | 955 | to be hashed into. |
953 | 956 | ||
954 | Same locking and synchronisation rules as d_compare regarding | 957 | Same locking and synchronisation rules as d_compare regarding |
955 | what is safe to dereference etc. | 958 | what is safe to dereference etc. |
956 | 959 | ||
957 | d_compare: called to compare a dentry name with a given name. The first | 960 | d_compare: called to compare a dentry name with a given name. The first |
958 | dentry is the parent of the dentry to be compared, the second is | 961 | dentry is the parent of the dentry to be compared, the second is |
959 | the parent's inode, then the dentry and inode (may be NULL) of the | 962 | the child dentry. len and name string are properties of the dentry |
960 | child dentry. len and name string are properties of the dentry to be | 963 | to be compared. qstr is the name to compare it with. |
961 | compared. qstr is the name to compare it with. | ||
962 | 964 | ||
963 | Must be constant and idempotent, and should not take locks if | 965 | Must be constant and idempotent, and should not take locks if |
964 | possible, and should not or store into the dentry or inodes. | 966 | possible, and should not or store into the dentry. |
965 | Should not dereference pointers outside the dentry or inodes without | 967 | Should not dereference pointers outside the dentry without |
966 | lots of care (eg. d_parent, d_inode, d_name should not be used). | 968 | lots of care (eg. d_parent, d_inode, d_name should not be used). |
967 | 969 | ||
968 | However, our vfsmount is pinned, and RCU held, so the dentries and | 970 | However, our vfsmount is pinned, and RCU held, so the dentries and |
969 | inodes won't disappear, neither will our sb or filesystem module. | 971 | inodes won't disappear, neither will our sb or filesystem module. |
970 | ->i_sb and ->d_sb may be used. | 972 | ->d_sb may be used. |
971 | 973 | ||
972 | It is a tricky calling convention because it needs to be called under | 974 | It is a tricky calling convention because it needs to be called under |
973 | "rcu-walk", ie. without any locks or references on things. | 975 | "rcu-walk", ie. without any locks or references on things. |
diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h index 6d9e805f18a7..dfdadb0b4bef 100644 --- a/arch/alpha/include/uapi/asm/fcntl.h +++ b/arch/alpha/include/uapi/asm/fcntl.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define O_SYNC (__O_SYNC|O_DSYNC) | 32 | #define O_SYNC (__O_SYNC|O_DSYNC) |
33 | 33 | ||
34 | #define O_PATH 040000000 | 34 | #define O_PATH 040000000 |
35 | #define O_TMPFILE 0100000000 | ||
35 | 36 | ||
36 | #define F_GETLK 7 | 37 | #define F_GETLK 7 |
37 | #define F_SETLK 8 | 38 | #define F_SETLK 8 |
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index 11c301b81c92..a03528ecd276 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c | |||
@@ -101,7 +101,7 @@ static void show_faulting_vma(unsigned long address, char *buf) | |||
101 | if (file) { | 101 | if (file) { |
102 | struct path *path = &file->f_path; | 102 | struct path *path = &file->f_path; |
103 | nm = d_path(path, buf, PAGE_SIZE - 1); | 103 | nm = d_path(path, buf, PAGE_SIZE - 1); |
104 | inode = vma->vm_file->f_path.dentry->d_inode; | 104 | inode = file_inode(vma->vm_file); |
105 | dev = inode->i_sb->s_dev; | 105 | dev = inode->i_sb->s_dev; |
106 | ino = inode->i_ino; | 106 | ino = inode->i_ino; |
107 | } | 107 | } |
diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 0304b92ccfea..cc61c475f277 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ | 20 | #define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ |
21 | 21 | ||
22 | #define O_PATH 020000000 | 22 | #define O_PATH 020000000 |
23 | #define O_TMPFILE 040000000 | ||
23 | 24 | ||
24 | #define F_GETLK64 8 | 25 | #define F_GETLK64 8 |
25 | #define F_SETLK64 9 | 26 | #define F_SETLK64 9 |
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index feb8580fdc84..c30612aad68e 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c | |||
@@ -29,25 +29,9 @@ | |||
29 | 29 | ||
30 | #ifdef CONFIG_PPC64 | 30 | #ifdef CONFIG_PPC64 |
31 | 31 | ||
32 | static loff_t page_map_seek( struct file *file, loff_t off, int whence) | 32 | static loff_t page_map_seek(struct file *file, loff_t off, int whence) |
33 | { | 33 | { |
34 | loff_t new; | 34 | return fixed_size_llseek(file, off, whence, PAGE_SIZE); |
35 | switch(whence) { | ||
36 | case 0: | ||
37 | new = off; | ||
38 | break; | ||
39 | case 1: | ||
40 | new = file->f_pos + off; | ||
41 | break; | ||
42 | case 2: | ||
43 | new = PAGE_SIZE + off; | ||
44 | break; | ||
45 | default: | ||
46 | return -EINVAL; | ||
47 | } | ||
48 | if ( new < 0 || new > PAGE_SIZE ) | ||
49 | return -EINVAL; | ||
50 | return (file->f_pos = new); | ||
51 | } | 35 | } |
52 | 36 | ||
53 | static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, | 37 | static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, |
diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h index d0b83f66f356..d73e5e008b0d 100644 --- a/arch/sparc/include/uapi/asm/fcntl.h +++ b/arch/sparc/include/uapi/asm/fcntl.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define O_SYNC (__O_SYNC|O_DSYNC) | 35 | #define O_SYNC (__O_SYNC|O_DSYNC) |
36 | 36 | ||
37 | #define O_PATH 0x1000000 | 37 | #define O_PATH 0x1000000 |
38 | #define O_TMPFILE 0x2000000 | ||
38 | 39 | ||
39 | #define F_GETOWN 5 /* for sockets. */ | 40 | #define F_GETOWN 5 /* for sockets. */ |
40 | #define F_SETOWN 6 /* for sockets. */ | 41 | #define F_SETOWN 6 /* for sockets. */ |
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 8cafa9ccd43f..0b311fa277ef 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c | |||
@@ -98,32 +98,8 @@ static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector) | |||
98 | static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) | 98 | static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) |
99 | { | 99 | { |
100 | struct ps3_storage_device *dev = ps3flash_dev; | 100 | struct ps3_storage_device *dev = ps3flash_dev; |
101 | loff_t res; | 101 | return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, |
102 | 102 | dev->regions[dev->region_idx].size*dev->blk_size); | |
103 | mutex_lock(&file->f_mapping->host->i_mutex); | ||
104 | switch (origin) { | ||
105 | case 0: | ||
106 | break; | ||
107 | case 1: | ||
108 | offset += file->f_pos; | ||
109 | break; | ||
110 | case 2: | ||
111 | offset += dev->regions[dev->region_idx].size*dev->blk_size; | ||
112 | break; | ||
113 | default: | ||
114 | offset = -1; | ||
115 | } | ||
116 | if (offset < 0) { | ||
117 | res = -EINVAL; | ||
118 | goto out; | ||
119 | } | ||
120 | |||
121 | file->f_pos = offset; | ||
122 | res = file->f_pos; | ||
123 | |||
124 | out: | ||
125 | mutex_unlock(&file->f_mapping->host->i_mutex); | ||
126 | return res; | ||
127 | } | 103 | } |
128 | 104 | ||
129 | static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, | 105 | static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, |
diff --git a/drivers/char/tile-srom.c b/drivers/char/tile-srom.c index 2e2036e940fc..7faeb1cde97d 100644 --- a/drivers/char/tile-srom.c +++ b/drivers/char/tile-srom.c | |||
@@ -273,32 +273,10 @@ static ssize_t srom_write(struct file *filp, const char __user *buf, | |||
273 | } | 273 | } |
274 | 274 | ||
275 | /* Provide our own implementation so we can use srom->total_size. */ | 275 | /* Provide our own implementation so we can use srom->total_size. */ |
276 | loff_t srom_llseek(struct file *filp, loff_t offset, int origin) | 276 | loff_t srom_llseek(struct file *file, loff_t offset, int origin) |
277 | { | 277 | { |
278 | struct srom_dev *srom = filp->private_data; | 278 | struct srom_dev *srom = file->private_data; |
279 | 279 | return fixed_size_llseek(file, offset, origin, srom->total_size); | |
280 | if (mutex_lock_interruptible(&srom->lock)) | ||
281 | return -ERESTARTSYS; | ||
282 | |||
283 | switch (origin) { | ||
284 | case SEEK_END: | ||
285 | offset += srom->total_size; | ||
286 | break; | ||
287 | case SEEK_CUR: | ||
288 | offset += filp->f_pos; | ||
289 | break; | ||
290 | } | ||
291 | |||
292 | if (offset < 0 || offset > srom->total_size) { | ||
293 | offset = -EINVAL; | ||
294 | } else { | ||
295 | filp->f_pos = offset; | ||
296 | filp->f_version = 0; | ||
297 | } | ||
298 | |||
299 | mutex_unlock(&srom->lock); | ||
300 | |||
301 | return offset; | ||
302 | } | 280 | } |
303 | 281 | ||
304 | static ssize_t total_show(struct device *dev, | 282 | static ssize_t total_show(struct device *dev, |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index c719879284bd..684bfa39e4ee 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -55,25 +55,7 @@ struct mtd_file_info { | |||
55 | static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig) | 55 | static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig) |
56 | { | 56 | { |
57 | struct mtd_file_info *mfi = file->private_data; | 57 | struct mtd_file_info *mfi = file->private_data; |
58 | struct mtd_info *mtd = mfi->mtd; | 58 | return fixed_size_llseek(file, offset, orig, mfi->mtd->size); |
59 | |||
60 | switch (orig) { | ||
61 | case SEEK_SET: | ||
62 | break; | ||
63 | case SEEK_CUR: | ||
64 | offset += file->f_pos; | ||
65 | break; | ||
66 | case SEEK_END: | ||
67 | offset += mtd->size; | ||
68 | break; | ||
69 | default: | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | if (offset >= 0 && offset <= mtd->size) | ||
74 | return file->f_pos = offset; | ||
75 | |||
76 | return -EINVAL; | ||
77 | } | 59 | } |
78 | 60 | ||
79 | static int count; | 61 | static int count; |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 4f02848bb2bc..8ca49f2043e4 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -155,7 +155,6 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) | |||
155 | { | 155 | { |
156 | struct ubi_volume_desc *desc = file->private_data; | 156 | struct ubi_volume_desc *desc = file->private_data; |
157 | struct ubi_volume *vol = desc->vol; | 157 | struct ubi_volume *vol = desc->vol; |
158 | loff_t new_offset; | ||
159 | 158 | ||
160 | if (vol->updating) { | 159 | if (vol->updating) { |
161 | /* Update is in progress, seeking is prohibited */ | 160 | /* Update is in progress, seeking is prohibited */ |
@@ -163,30 +162,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) | |||
163 | return -EBUSY; | 162 | return -EBUSY; |
164 | } | 163 | } |
165 | 164 | ||
166 | switch (origin) { | 165 | return fixed_size_llseek(file, offset, origin, vol->used_bytes); |
167 | case 0: /* SEEK_SET */ | ||
168 | new_offset = offset; | ||
169 | break; | ||
170 | case 1: /* SEEK_CUR */ | ||
171 | new_offset = file->f_pos + offset; | ||
172 | break; | ||
173 | case 2: /* SEEK_END */ | ||
174 | new_offset = vol->used_bytes + offset; | ||
175 | break; | ||
176 | default: | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | if (new_offset < 0 || new_offset > vol->used_bytes) { | ||
181 | ubi_err("bad seek %lld", new_offset); | ||
182 | return -EINVAL; | ||
183 | } | ||
184 | |||
185 | dbg_gen("seek volume %d, offset %lld, origin %d, new offset %lld", | ||
186 | vol->vol_id, offset, origin, new_offset); | ||
187 | |||
188 | file->f_pos = new_offset; | ||
189 | return new_offset; | ||
190 | } | 166 | } |
191 | 167 | ||
192 | static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, | 168 | static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 94d957d203a6..7d6aa8c87df8 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c | |||
@@ -230,32 +230,12 @@ bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file) | |||
230 | static loff_t | 230 | static loff_t |
231 | bnad_debugfs_lseek(struct file *file, loff_t offset, int orig) | 231 | bnad_debugfs_lseek(struct file *file, loff_t offset, int orig) |
232 | { | 232 | { |
233 | loff_t pos = file->f_pos; | ||
234 | struct bnad_debug_info *debug = file->private_data; | 233 | struct bnad_debug_info *debug = file->private_data; |
235 | 234 | ||
236 | if (!debug) | 235 | if (!debug) |
237 | return -EINVAL; | 236 | return -EINVAL; |
238 | 237 | ||
239 | switch (orig) { | 238 | return fixed_size_llseek(file, offset, orig, debug->buffer_len); |
240 | case 0: | ||
241 | file->f_pos = offset; | ||
242 | break; | ||
243 | case 1: | ||
244 | file->f_pos += offset; | ||
245 | break; | ||
246 | case 2: | ||
247 | file->f_pos = debug->buffer_len + offset; | ||
248 | break; | ||
249 | default: | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | if (file->f_pos < 0 || file->f_pos > debug->buffer_len) { | ||
254 | file->f_pos = pos; | ||
255 | return -EINVAL; | ||
256 | } | ||
257 | |||
258 | return file->f_pos; | ||
259 | } | 239 | } |
260 | 240 | ||
261 | static ssize_t | 241 | static ssize_t |
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index c3e1f79c7856..e17630c2a849 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c | |||
@@ -1056,7 +1056,7 @@ static ssize_t dev_mem_read(struct file *file, | |||
1056 | return -EINVAL; | 1056 | return -EINVAL; |
1057 | 1057 | ||
1058 | memset(&part, 0, sizeof(part)); | 1058 | memset(&part, 0, sizeof(part)); |
1059 | part.mem.start = file->f_pos; | 1059 | part.mem.start = *ppos; |
1060 | part.mem.size = bytes; | 1060 | part.mem.size = bytes; |
1061 | 1061 | ||
1062 | buf = kmalloc(bytes, GFP_KERNEL); | 1062 | buf = kmalloc(bytes, GFP_KERNEL); |
@@ -1137,7 +1137,7 @@ static ssize_t dev_mem_write(struct file *file, const char __user *user_buf, | |||
1137 | return -EINVAL; | 1137 | return -EINVAL; |
1138 | 1138 | ||
1139 | memset(&part, 0, sizeof(part)); | 1139 | memset(&part, 0, sizeof(part)); |
1140 | part.mem.start = file->f_pos; | 1140 | part.mem.start = *ppos; |
1141 | part.mem.size = bytes; | 1141 | part.mem.size = bytes; |
1142 | 1142 | ||
1143 | buf = kmalloc(bytes, GFP_KERNEL); | 1143 | buf = kmalloc(bytes, GFP_KERNEL); |
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c index af212c6a6158..783906fe659a 100644 --- a/drivers/parisc/eisa_eeprom.c +++ b/drivers/parisc/eisa_eeprom.c | |||
@@ -31,20 +31,9 @@ | |||
31 | 31 | ||
32 | #define EISA_EEPROM_MINOR 241 | 32 | #define EISA_EEPROM_MINOR 241 |
33 | 33 | ||
34 | static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin ) | 34 | static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin) |
35 | { | 35 | { |
36 | switch (origin) { | 36 | return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH); |
37 | case 0: | ||
38 | /* nothing to do */ | ||
39 | break; | ||
40 | case 1: | ||
41 | offset += file->f_pos; | ||
42 | break; | ||
43 | case 2: | ||
44 | offset += HPEE_MAX_LENGTH; | ||
45 | break; | ||
46 | } | ||
47 | return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL; | ||
48 | } | 37 | } |
49 | 38 | ||
50 | static ssize_t eisa_eeprom_read(struct file * file, | 39 | static ssize_t eisa_eeprom_read(struct file * file, |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 4cb30447a486..17c1f36315d1 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -167,26 +167,8 @@ exit: | |||
167 | 167 | ||
168 | static loff_t lseek(struct file *file, loff_t off, int whence) | 168 | static loff_t lseek(struct file *file, loff_t off, int whence) |
169 | { | 169 | { |
170 | struct ctrl_dbg *dbg; | 170 | struct ctrl_dbg *dbg = file->private_data; |
171 | loff_t new = -1; | 171 | return fixed_size_llseek(file, off, whence, dbg->size); |
172 | |||
173 | mutex_lock(&cpqphp_mutex); | ||
174 | dbg = file->private_data; | ||
175 | |||
176 | switch (whence) { | ||
177 | case 0: | ||
178 | new = off; | ||
179 | break; | ||
180 | case 1: | ||
181 | new = file->f_pos + off; | ||
182 | break; | ||
183 | } | ||
184 | if (new < 0 || new > dbg->size) { | ||
185 | mutex_unlock(&cpqphp_mutex); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | mutex_unlock(&cpqphp_mutex); | ||
189 | return (file->f_pos = new); | ||
190 | } | 172 | } |
191 | 173 | ||
192 | static ssize_t read(struct file *file, char __user *buf, | 174 | static ssize_t read(struct file *file, char __user *buf, |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 08126087ec31..cdc7836d7e3d 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -20,27 +20,8 @@ static int proc_initialized; /* = 0 */ | |||
20 | static loff_t | 20 | static loff_t |
21 | proc_bus_pci_lseek(struct file *file, loff_t off, int whence) | 21 | proc_bus_pci_lseek(struct file *file, loff_t off, int whence) |
22 | { | 22 | { |
23 | loff_t new = -1; | 23 | struct pci_dev *dev = PDE_DATA(file_inode(file)); |
24 | struct inode *inode = file_inode(file); | 24 | return fixed_size_llseek(file, off, whence, dev->cfg_size); |
25 | |||
26 | mutex_lock(&inode->i_mutex); | ||
27 | switch (whence) { | ||
28 | case 0: | ||
29 | new = off; | ||
30 | break; | ||
31 | case 1: | ||
32 | new = file->f_pos + off; | ||
33 | break; | ||
34 | case 2: | ||
35 | new = inode->i_size + off; | ||
36 | break; | ||
37 | } | ||
38 | if (new < 0 || new > inode->i_size) | ||
39 | new = -EINVAL; | ||
40 | else | ||
41 | file->f_pos = new; | ||
42 | mutex_unlock(&inode->i_mutex); | ||
43 | return new; | ||
44 | } | 25 | } |
45 | 26 | ||
46 | static ssize_t | 27 | static ssize_t |
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c index 2365ef37ae24..5edee645d890 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c | |||
@@ -29,27 +29,7 @@ static struct proc_dir_entry *isapnp_proc_bus_dir = NULL; | |||
29 | 29 | ||
30 | static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) | 30 | static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) |
31 | { | 31 | { |
32 | loff_t new = -1; | 32 | return fixed_size_llseek(file, off, whence, 256); |
33 | struct inode *inode = file_inode(file); | ||
34 | |||
35 | mutex_lock(&inode->i_mutex); | ||
36 | switch (whence) { | ||
37 | case 0: | ||
38 | new = off; | ||
39 | break; | ||
40 | case 1: | ||
41 | new = file->f_pos + off; | ||
42 | break; | ||
43 | case 2: | ||
44 | new = 256 + off; | ||
45 | break; | ||
46 | } | ||
47 | if (new < 0 || new > 256) | ||
48 | new = -EINVAL; | ||
49 | else | ||
50 | file->f_pos = new; | ||
51 | mutex_unlock(&inode->i_mutex); | ||
52 | return new; | ||
53 | } | 33 | } |
54 | 34 | ||
55 | static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf, | 35 | static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf, |
diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index b63d534192e3..8e83d0474fe7 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c | |||
@@ -173,31 +173,9 @@ bfad_debugfs_open_reg(struct inode *inode, struct file *file) | |||
173 | static loff_t | 173 | static loff_t |
174 | bfad_debugfs_lseek(struct file *file, loff_t offset, int orig) | 174 | bfad_debugfs_lseek(struct file *file, loff_t offset, int orig) |
175 | { | 175 | { |
176 | struct bfad_debug_info *debug; | 176 | struct bfad_debug_info *debug = file->private_data; |
177 | loff_t pos = file->f_pos; | 177 | return fixed_size_llseek(file, offset, orig, |
178 | 178 | debug->buffer_len); | |
179 | debug = file->private_data; | ||
180 | |||
181 | switch (orig) { | ||
182 | case 0: | ||
183 | file->f_pos = offset; | ||
184 | break; | ||
185 | case 1: | ||
186 | file->f_pos += offset; | ||
187 | break; | ||
188 | case 2: | ||
189 | file->f_pos = debug->buffer_len + offset; | ||
190 | break; | ||
191 | default: | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | if (file->f_pos < 0 || file->f_pos > debug->buffer_len) { | ||
196 | file->f_pos = pos; | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
200 | return file->f_pos; | ||
201 | } | 179 | } |
202 | 180 | ||
203 | static ssize_t | 181 | static ssize_t |
diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index 85e1ffd0e5c5..cbcb0121c84d 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c | |||
@@ -164,20 +164,8 @@ static loff_t fnic_trace_debugfs_lseek(struct file *file, | |||
164 | int howto) | 164 | int howto) |
165 | { | 165 | { |
166 | fnic_dbgfs_t *fnic_dbg_prt = file->private_data; | 166 | fnic_dbgfs_t *fnic_dbg_prt = file->private_data; |
167 | loff_t pos = -1; | 167 | return fixed_size_llseek(file, offset, howto, |
168 | 168 | fnic_dbg_prt->buffer_len); | |
169 | switch (howto) { | ||
170 | case 0: | ||
171 | pos = offset; | ||
172 | break; | ||
173 | case 1: | ||
174 | pos = file->f_pos + offset; | ||
175 | break; | ||
176 | case 2: | ||
177 | pos = fnic_dbg_prt->buffer_len + offset; | ||
178 | } | ||
179 | return (pos < 0 || pos > fnic_dbg_prt->buffer_len) ? | ||
180 | -EINVAL : (file->f_pos = pos); | ||
181 | } | 169 | } |
182 | 170 | ||
183 | /* | 171 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index f525ecb7a9c6..60084e6ad2f2 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -1165,22 +1165,8 @@ out: | |||
1165 | static loff_t | 1165 | static loff_t |
1166 | lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) | 1166 | lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) |
1167 | { | 1167 | { |
1168 | struct lpfc_debug *debug; | 1168 | struct lpfc_debug *debug = file->private_data; |
1169 | loff_t pos = -1; | 1169 | return fixed_size_llseek(file, off, whence, debug->len); |
1170 | |||
1171 | debug = file->private_data; | ||
1172 | |||
1173 | switch (whence) { | ||
1174 | case 0: | ||
1175 | pos = off; | ||
1176 | break; | ||
1177 | case 1: | ||
1178 | pos = file->f_pos + off; | ||
1179 | break; | ||
1180 | case 2: | ||
1181 | pos = debug->len + off; | ||
1182 | } | ||
1183 | return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); | ||
1184 | } | 1170 | } |
1185 | 1171 | ||
1186 | /** | 1172 | /** |
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 9bd874789ce5..080abf2faf97 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c | |||
@@ -696,7 +696,7 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
696 | ret = -EBADF; | 696 | ret = -EBADF; |
697 | break; | 697 | break; |
698 | } | 698 | } |
699 | if (!(in_egroup_p(file->f_dentry->d_inode->i_gid) || | 699 | if (!(in_egroup_p(file_inode(file)->i_gid) || |
700 | capable(CAP_SYSLOG))) { | 700 | capable(CAP_SYSLOG))) { |
701 | ret = -EPERM; | 701 | ret = -EPERM; |
702 | break; | 702 | break; |
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 0794aacc928a..8647518259f6 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
@@ -2329,9 +2329,6 @@ static int comedi_close(struct inode *inode, struct file *file) | |||
2329 | 2329 | ||
2330 | mutex_unlock(&dev->mutex); | 2330 | mutex_unlock(&dev->mutex); |
2331 | 2331 | ||
2332 | if (file->f_flags & FASYNC) | ||
2333 | comedi_fasync(-1, file, 0); | ||
2334 | |||
2335 | return 0; | 2332 | return 0; |
2336 | } | 2333 | } |
2337 | 2334 | ||
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index d7799deacb21..14a2b5f11bca 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c | |||
@@ -188,22 +188,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
188 | console_unlock(); | 188 | console_unlock(); |
189 | if (size < 0) | 189 | if (size < 0) |
190 | return size; | 190 | return size; |
191 | switch (orig) { | 191 | return fixed_size_llseek(file, offset, orig, size); |
192 | default: | ||
193 | return -EINVAL; | ||
194 | case 2: | ||
195 | offset += size; | ||
196 | break; | ||
197 | case 1: | ||
198 | offset += file->f_pos; | ||
199 | case 0: | ||
200 | break; | ||
201 | } | ||
202 | if (offset < 0 || offset > size) { | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | file->f_pos = offset; | ||
206 | return file->f_pos; | ||
207 | } | 192 | } |
208 | 193 | ||
209 | 194 | ||
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c index 1c15ee7456b6..ea1ce822a8e0 100644 --- a/drivers/zorro/proc.c +++ b/drivers/zorro/proc.c | |||
@@ -21,27 +21,7 @@ | |||
21 | static loff_t | 21 | static loff_t |
22 | proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) | 22 | proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) |
23 | { | 23 | { |
24 | loff_t new = -1; | 24 | return fixed_size_llseek(file, off, whence, sizeof(struct ConfigDev)); |
25 | struct inode *inode = file_inode(file); | ||
26 | |||
27 | mutex_lock(&inode->i_mutex); | ||
28 | switch (whence) { | ||
29 | case 0: | ||
30 | new = off; | ||
31 | break; | ||
32 | case 1: | ||
33 | new = file->f_pos + off; | ||
34 | break; | ||
35 | case 2: | ||
36 | new = sizeof(struct ConfigDev) + off; | ||
37 | break; | ||
38 | } | ||
39 | if (new < 0 || new > sizeof(struct ConfigDev)) | ||
40 | new = -EINVAL; | ||
41 | else | ||
42 | file->f_pos = new; | ||
43 | mutex_unlock(&inode->i_mutex); | ||
44 | return new; | ||
45 | } | 25 | } |
46 | 26 | ||
47 | static ssize_t | 27 | static ssize_t |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index ade28bb058e3..0d138c0de293 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -191,8 +191,7 @@ const struct file_operations adfs_dir_operations = { | |||
191 | }; | 191 | }; |
192 | 192 | ||
193 | static int | 193 | static int |
194 | adfs_hash(const struct dentry *parent, const struct inode *inode, | 194 | adfs_hash(const struct dentry *parent, struct qstr *qstr) |
195 | struct qstr *qstr) | ||
196 | { | 195 | { |
197 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; | 196 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; |
198 | const unsigned char *name; | 197 | const unsigned char *name; |
@@ -228,8 +227,7 @@ adfs_hash(const struct dentry *parent, const struct inode *inode, | |||
228 | * requirements of the underlying filesystem. | 227 | * requirements of the underlying filesystem. |
229 | */ | 228 | */ |
230 | static int | 229 | static int |
231 | adfs_compare(const struct dentry *parent, const struct inode *pinode, | 230 | adfs_compare(const struct dentry *parent, const struct dentry *dentry, |
232 | const struct dentry *dentry, const struct inode *inode, | ||
233 | unsigned int len, const char *str, const struct qstr *name) | 231 | unsigned int len, const char *str, const struct qstr *name) |
234 | { | 232 | { |
235 | int i; | 233 | int i; |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index ff65884a7839..c36cbb4537a2 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -13,18 +13,12 @@ | |||
13 | typedef int (*toupper_t)(int); | 13 | typedef int (*toupper_t)(int); |
14 | 14 | ||
15 | static int affs_toupper(int ch); | 15 | static int affs_toupper(int ch); |
16 | static int affs_hash_dentry(const struct dentry *, | 16 | static int affs_hash_dentry(const struct dentry *, struct qstr *); |
17 | const struct inode *, struct qstr *); | 17 | static int affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
18 | static int affs_compare_dentry(const struct dentry *parent, | ||
19 | const struct inode *pinode, | ||
20 | const struct dentry *dentry, const struct inode *inode, | ||
21 | unsigned int len, const char *str, const struct qstr *name); | 18 | unsigned int len, const char *str, const struct qstr *name); |
22 | static int affs_intl_toupper(int ch); | 19 | static int affs_intl_toupper(int ch); |
23 | static int affs_intl_hash_dentry(const struct dentry *, | 20 | static int affs_intl_hash_dentry(const struct dentry *, struct qstr *); |
24 | const struct inode *, struct qstr *); | 21 | static int affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
25 | static int affs_intl_compare_dentry(const struct dentry *parent, | ||
26 | const struct inode *pinode, | ||
27 | const struct dentry *dentry, const struct inode *inode, | ||
28 | unsigned int len, const char *str, const struct qstr *name); | 22 | unsigned int len, const char *str, const struct qstr *name); |
29 | 23 | ||
30 | const struct dentry_operations affs_dentry_operations = { | 24 | const struct dentry_operations affs_dentry_operations = { |
@@ -86,14 +80,12 @@ __affs_hash_dentry(struct qstr *qstr, toupper_t toupper) | |||
86 | } | 80 | } |
87 | 81 | ||
88 | static int | 82 | static int |
89 | affs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 83 | affs_hash_dentry(const struct dentry *dentry, struct qstr *qstr) |
90 | struct qstr *qstr) | ||
91 | { | 84 | { |
92 | return __affs_hash_dentry(qstr, affs_toupper); | 85 | return __affs_hash_dentry(qstr, affs_toupper); |
93 | } | 86 | } |
94 | static int | 87 | static int |
95 | affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 88 | affs_intl_hash_dentry(const struct dentry *dentry, struct qstr *qstr) |
96 | struct qstr *qstr) | ||
97 | { | 89 | { |
98 | return __affs_hash_dentry(qstr, affs_intl_toupper); | 90 | return __affs_hash_dentry(qstr, affs_intl_toupper); |
99 | } | 91 | } |
@@ -131,15 +123,13 @@ static inline int __affs_compare_dentry(unsigned int len, | |||
131 | } | 123 | } |
132 | 124 | ||
133 | static int | 125 | static int |
134 | affs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 126 | affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
135 | const struct dentry *dentry, const struct inode *inode, | ||
136 | unsigned int len, const char *str, const struct qstr *name) | 127 | unsigned int len, const char *str, const struct qstr *name) |
137 | { | 128 | { |
138 | return __affs_compare_dentry(len, str, name, affs_toupper); | 129 | return __affs_compare_dentry(len, str, name, affs_toupper); |
139 | } | 130 | } |
140 | static int | 131 | static int |
141 | affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode, | 132 | affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
142 | const struct dentry *dentry, const struct inode *inode, | ||
143 | unsigned int len, const char *str, const struct qstr *name) | 133 | unsigned int len, const char *str, const struct qstr *name) |
144 | { | 134 | { |
145 | return __affs_compare_dentry(len, str, name, affs_intl_toupper); | 135 | return __affs_compare_dentry(len, str, name, affs_intl_toupper); |
diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 2497bf306c70..a8cf2cff836c 100644 --- a/fs/afs/flock.c +++ b/fs/afs/flock.c | |||
@@ -252,7 +252,8 @@ static void afs_defer_unlock(struct afs_vnode *vnode, struct key *key) | |||
252 | */ | 252 | */ |
253 | static int afs_do_setlk(struct file *file, struct file_lock *fl) | 253 | static int afs_do_setlk(struct file *file, struct file_lock *fl) |
254 | { | 254 | { |
255 | struct afs_vnode *vnode = AFS_FS_I(file->f_mapping->host); | 255 | struct inode *inode = file_inode(file); |
256 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
256 | afs_lock_type_t type; | 257 | afs_lock_type_t type; |
257 | struct key *key = file->private_data; | 258 | struct key *key = file->private_data; |
258 | int ret; | 259 | int ret; |
@@ -273,7 +274,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl) | |||
273 | 274 | ||
274 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | 275 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; |
275 | 276 | ||
276 | lock_flocks(); | 277 | spin_lock(&inode->i_lock); |
277 | 278 | ||
278 | /* make sure we've got a callback on this file and that our view of the | 279 | /* make sure we've got a callback on this file and that our view of the |
279 | * data version is up to date */ | 280 | * data version is up to date */ |
@@ -420,7 +421,7 @@ given_lock: | |||
420 | afs_vnode_fetch_status(vnode, NULL, key); | 421 | afs_vnode_fetch_status(vnode, NULL, key); |
421 | 422 | ||
422 | error: | 423 | error: |
423 | unlock_flocks(); | 424 | spin_unlock(&inode->i_lock); |
424 | _leave(" = %d", ret); | 425 | _leave(" = %d", ret); |
425 | return ret; | 426 | return ret; |
426 | 427 | ||
@@ -39,6 +39,8 @@ | |||
39 | #include <asm/kmap_types.h> | 39 | #include <asm/kmap_types.h> |
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | 41 | ||
42 | #include "internal.h" | ||
43 | |||
42 | #define AIO_RING_MAGIC 0xa10a10a1 | 44 | #define AIO_RING_MAGIC 0xa10a10a1 |
43 | #define AIO_RING_COMPAT_FEATURES 1 | 45 | #define AIO_RING_COMPAT_FEATURES 1 |
44 | #define AIO_RING_INCOMPAT_FEATURES 0 | 46 | #define AIO_RING_INCOMPAT_FEATURES 0 |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 2091db8cdd78..431b6a04ebfd 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -325,31 +325,10 @@ static int blkdev_write_end(struct file *file, struct address_space *mapping, | |||
325 | static loff_t block_llseek(struct file *file, loff_t offset, int whence) | 325 | static loff_t block_llseek(struct file *file, loff_t offset, int whence) |
326 | { | 326 | { |
327 | struct inode *bd_inode = file->f_mapping->host; | 327 | struct inode *bd_inode = file->f_mapping->host; |
328 | loff_t size; | ||
329 | loff_t retval; | 328 | loff_t retval; |
330 | 329 | ||
331 | mutex_lock(&bd_inode->i_mutex); | 330 | mutex_lock(&bd_inode->i_mutex); |
332 | size = i_size_read(bd_inode); | 331 | retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode)); |
333 | |||
334 | retval = -EINVAL; | ||
335 | switch (whence) { | ||
336 | case SEEK_END: | ||
337 | offset += size; | ||
338 | break; | ||
339 | case SEEK_CUR: | ||
340 | offset += file->f_pos; | ||
341 | case SEEK_SET: | ||
342 | break; | ||
343 | default: | ||
344 | goto out; | ||
345 | } | ||
346 | if (offset >= 0 && offset <= size) { | ||
347 | if (offset != file->f_pos) { | ||
348 | file->f_pos = offset; | ||
349 | } | ||
350 | retval = offset; | ||
351 | } | ||
352 | out: | ||
353 | mutex_unlock(&bd_inode->i_mutex); | 332 | mutex_unlock(&bd_inode->i_mutex); |
354 | return retval; | 333 | return retval; |
355 | } | 334 | } |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4205ba752d40..89da56a58b63 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2425,20 +2425,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence) | |||
2425 | } | 2425 | } |
2426 | } | 2426 | } |
2427 | 2427 | ||
2428 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { | 2428 | offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); |
2429 | offset = -EINVAL; | ||
2430 | goto out; | ||
2431 | } | ||
2432 | if (offset > inode->i_sb->s_maxbytes) { | ||
2433 | offset = -EINVAL; | ||
2434 | goto out; | ||
2435 | } | ||
2436 | |||
2437 | /* Special lock needed here? */ | ||
2438 | if (offset != file->f_pos) { | ||
2439 | file->f_pos = offset; | ||
2440 | file->f_version = 0; | ||
2441 | } | ||
2442 | out: | 2429 | out: |
2443 | mutex_unlock(&inode->i_mutex); | 2430 | mutex_unlock(&inode->i_mutex); |
2444 | return offset; | 2431 | return offset; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0f81d67cdc8d..cd7e96c73cb7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3881,7 +3881,7 @@ drop_write: | |||
3881 | 3881 | ||
3882 | static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) | 3882 | static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) |
3883 | { | 3883 | { |
3884 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 3884 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
3885 | struct btrfs_ioctl_quota_rescan_args *qsa; | 3885 | struct btrfs_ioctl_quota_rescan_args *qsa; |
3886 | int ret; | 3886 | int ret; |
3887 | 3887 | ||
@@ -3914,7 +3914,7 @@ drop_write: | |||
3914 | 3914 | ||
3915 | static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | 3915 | static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) |
3916 | { | 3916 | { |
3917 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 3917 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
3918 | struct btrfs_ioctl_quota_rescan_args *qsa; | 3918 | struct btrfs_ioctl_quota_rescan_args *qsa; |
3919 | int ret = 0; | 3919 | int ret = 0; |
3920 | 3920 | ||
@@ -4020,7 +4020,7 @@ out: | |||
4020 | 4020 | ||
4021 | static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) | 4021 | static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) |
4022 | { | 4022 | { |
4023 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4023 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
4024 | const char *label = root->fs_info->super_copy->label; | 4024 | const char *label = root->fs_info->super_copy->label; |
4025 | size_t len = strnlen(label, BTRFS_LABEL_SIZE); | 4025 | size_t len = strnlen(label, BTRFS_LABEL_SIZE); |
4026 | int ret; | 4026 | int ret; |
@@ -4039,7 +4039,7 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) | |||
4039 | 4039 | ||
4040 | static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) | 4040 | static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) |
4041 | { | 4041 | { |
4042 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4042 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
4043 | struct btrfs_super_block *super_block = root->fs_info->super_copy; | 4043 | struct btrfs_super_block *super_block = root->fs_info->super_copy; |
4044 | struct btrfs_trans_handle *trans; | 4044 | struct btrfs_trans_handle *trans; |
4045 | char label[BTRFS_LABEL_SIZE]; | 4045 | char label[BTRFS_LABEL_SIZE]; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 656e16907430..16c989d3e23c 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -866,16 +866,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence) | |||
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | 868 | ||
869 | if (offset < 0 || offset > inode->i_sb->s_maxbytes) { | 869 | offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); |
870 | offset = -EINVAL; | ||
871 | goto out; | ||
872 | } | ||
873 | |||
874 | /* Special lock needed here? */ | ||
875 | if (offset != file->f_pos) { | ||
876 | file->f_pos = offset; | ||
877 | file->f_version = 0; | ||
878 | } | ||
879 | 870 | ||
880 | out: | 871 | out: |
881 | mutex_unlock(&inode->i_mutex); | 872 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ebbf680378e2..690f73f42425 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -192,7 +192,7 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
192 | 192 | ||
193 | /** | 193 | /** |
194 | * Encode the flock and fcntl locks for the given inode into the ceph_filelock | 194 | * Encode the flock and fcntl locks for the given inode into the ceph_filelock |
195 | * array. Must be called with lock_flocks() already held. | 195 | * array. Must be called with inode->i_lock already held. |
196 | * If we encounter more of a specific lock type than expected, return -ENOSPC. | 196 | * If we encounter more of a specific lock type than expected, return -ENOSPC. |
197 | */ | 197 | */ |
198 | int ceph_encode_locks_to_buffer(struct inode *inode, | 198 | int ceph_encode_locks_to_buffer(struct inode *inode, |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4d2920304be8..74fd2898b2ab 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2481,20 +2481,20 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2481 | struct ceph_filelock *flocks; | 2481 | struct ceph_filelock *flocks; |
2482 | 2482 | ||
2483 | encode_again: | 2483 | encode_again: |
2484 | lock_flocks(); | 2484 | spin_lock(&inode->i_lock); |
2485 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); | 2485 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); |
2486 | unlock_flocks(); | 2486 | spin_unlock(&inode->i_lock); |
2487 | flocks = kmalloc((num_fcntl_locks+num_flock_locks) * | 2487 | flocks = kmalloc((num_fcntl_locks+num_flock_locks) * |
2488 | sizeof(struct ceph_filelock), GFP_NOFS); | 2488 | sizeof(struct ceph_filelock), GFP_NOFS); |
2489 | if (!flocks) { | 2489 | if (!flocks) { |
2490 | err = -ENOMEM; | 2490 | err = -ENOMEM; |
2491 | goto out_free; | 2491 | goto out_free; |
2492 | } | 2492 | } |
2493 | lock_flocks(); | 2493 | spin_lock(&inode->i_lock); |
2494 | err = ceph_encode_locks_to_buffer(inode, flocks, | 2494 | err = ceph_encode_locks_to_buffer(inode, flocks, |
2495 | num_fcntl_locks, | 2495 | num_fcntl_locks, |
2496 | num_flock_locks); | 2496 | num_flock_locks); |
2497 | unlock_flocks(); | 2497 | spin_unlock(&inode->i_lock); |
2498 | if (err) { | 2498 | if (err) { |
2499 | kfree(flocks); | 2499 | kfree(flocks); |
2500 | if (err == -ENOSPC) | 2500 | if (err == -ENOSPC) |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 540c1ccfcdb2..a445e71746fa 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -765,7 +765,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | |||
765 | 765 | ||
766 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | 766 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) |
767 | { | 767 | { |
768 | /* note that this is called by vfs setlease with lock_flocks held | 768 | /* note that this is called by vfs setlease with i_lock held |
769 | to protect *lease from going away */ | 769 | to protect *lease from going away */ |
770 | struct inode *inode = file_inode(file); | 770 | struct inode *inode = file_inode(file); |
771 | struct cifsFileInfo *cfile = file->private_data; | 771 | struct cifsFileInfo *cfile = file->private_data; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 5699b5036ed8..5175aebf6737 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -822,8 +822,7 @@ const struct dentry_operations cifs_dentry_ops = { | |||
822 | /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ | 822 | /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ |
823 | }; | 823 | }; |
824 | 824 | ||
825 | static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode, | 825 | static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q) |
826 | struct qstr *q) | ||
827 | { | 826 | { |
828 | struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; | 827 | struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; |
829 | unsigned long hash; | 828 | unsigned long hash; |
@@ -838,12 +837,10 @@ static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode, | |||
838 | return 0; | 837 | return 0; |
839 | } | 838 | } |
840 | 839 | ||
841 | static int cifs_ci_compare(const struct dentry *parent, | 840 | static int cifs_ci_compare(const struct dentry *parent, const struct dentry *dentry, |
842 | const struct inode *pinode, | ||
843 | const struct dentry *dentry, const struct inode *inode, | ||
844 | unsigned int len, const char *str, const struct qstr *name) | 841 | unsigned int len, const char *str, const struct qstr *name) |
845 | { | 842 | { |
846 | struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls; | 843 | struct nls_table *codepage = CIFS_SB(parent->d_sb)->local_nls; |
847 | 844 | ||
848 | if ((name->len == len) && | 845 | if ((name->len == len) && |
849 | (nls_strnicmp(codepage, name->name, str, len) == 0)) | 846 | (nls_strnicmp(codepage, name->name, str, len) == 0)) |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4d8ba8d491e5..91d8629e69a2 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -999,7 +999,7 @@ try_again: | |||
999 | rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); | 999 | rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); |
1000 | if (!rc) | 1000 | if (!rc) |
1001 | goto try_again; | 1001 | goto try_again; |
1002 | locks_delete_block(flock); | 1002 | posix_unblock_lock(flock); |
1003 | } | 1003 | } |
1004 | return rc; | 1004 | return rc; |
1005 | } | 1005 | } |
@@ -1092,6 +1092,7 @@ struct lock_to_push { | |||
1092 | static int | 1092 | static int |
1093 | cifs_push_posix_locks(struct cifsFileInfo *cfile) | 1093 | cifs_push_posix_locks(struct cifsFileInfo *cfile) |
1094 | { | 1094 | { |
1095 | struct inode *inode = cfile->dentry->d_inode; | ||
1095 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1096 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1096 | struct file_lock *flock, **before; | 1097 | struct file_lock *flock, **before; |
1097 | unsigned int count = 0, i = 0; | 1098 | unsigned int count = 0, i = 0; |
@@ -1102,12 +1103,12 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1102 | 1103 | ||
1103 | xid = get_xid(); | 1104 | xid = get_xid(); |
1104 | 1105 | ||
1105 | lock_flocks(); | 1106 | spin_lock(&inode->i_lock); |
1106 | cifs_for_each_lock(cfile->dentry->d_inode, before) { | 1107 | cifs_for_each_lock(inode, before) { |
1107 | if ((*before)->fl_flags & FL_POSIX) | 1108 | if ((*before)->fl_flags & FL_POSIX) |
1108 | count++; | 1109 | count++; |
1109 | } | 1110 | } |
1110 | unlock_flocks(); | 1111 | spin_unlock(&inode->i_lock); |
1111 | 1112 | ||
1112 | INIT_LIST_HEAD(&locks_to_send); | 1113 | INIT_LIST_HEAD(&locks_to_send); |
1113 | 1114 | ||
@@ -1126,8 +1127,8 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1126 | } | 1127 | } |
1127 | 1128 | ||
1128 | el = locks_to_send.next; | 1129 | el = locks_to_send.next; |
1129 | lock_flocks(); | 1130 | spin_lock(&inode->i_lock); |
1130 | cifs_for_each_lock(cfile->dentry->d_inode, before) { | 1131 | cifs_for_each_lock(inode, before) { |
1131 | flock = *before; | 1132 | flock = *before; |
1132 | if ((flock->fl_flags & FL_POSIX) == 0) | 1133 | if ((flock->fl_flags & FL_POSIX) == 0) |
1133 | continue; | 1134 | continue; |
@@ -1152,7 +1153,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1152 | lck->offset = flock->fl_start; | 1153 | lck->offset = flock->fl_start; |
1153 | el = el->next; | 1154 | el = el->next; |
1154 | } | 1155 | } |
1155 | unlock_flocks(); | 1156 | spin_unlock(&inode->i_lock); |
1156 | 1157 | ||
1157 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { | 1158 | list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { |
1158 | int stored_rc; | 1159 | int stored_rc; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 87e0ee9f4465..14a14808320c 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -487,13 +487,7 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) | |||
487 | 487 | ||
488 | /* skip null entries */ | 488 | /* skip null entries */ |
489 | if (vdir->d_fileno && name.len) { | 489 | if (vdir->d_fileno && name.len) { |
490 | /* try to look up this entry in the dcache, that way | 490 | ino = vdir->d_fileno; |
491 | * userspace doesn't have to worry about breaking | ||
492 | * getcwd by having mismatched inode numbers for | ||
493 | * internal volume mountpoints. */ | ||
494 | ino = find_inode_number(de, &name); | ||
495 | if (!ino) ino = vdir->d_fileno; | ||
496 | |||
497 | type = CDT2DT(vdir->d_type); | 491 | type = CDT2DT(vdir->d_type); |
498 | if (!dir_emit(ctx, name.name, name.len, ino, type)) | 492 | if (!dir_emit(ctx, name.name, name.len, ino, type)) |
499 | break; | 493 | break; |
diff --git a/fs/dcache.c b/fs/dcache.c index 5a23073138df..87bdb5329c3c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1730,7 +1730,7 @@ EXPORT_SYMBOL(d_add_ci); | |||
1730 | * Do the slow-case of the dentry name compare. | 1730 | * Do the slow-case of the dentry name compare. |
1731 | * | 1731 | * |
1732 | * Unlike the dentry_cmp() function, we need to atomically | 1732 | * Unlike the dentry_cmp() function, we need to atomically |
1733 | * load the name, length and inode information, so that the | 1733 | * load the name and length information, so that the |
1734 | * filesystem can rely on them, and can use the 'name' and | 1734 | * filesystem can rely on them, and can use the 'name' and |
1735 | * 'len' information without worrying about walking off the | 1735 | * 'len' information without worrying about walking off the |
1736 | * end of memory etc. | 1736 | * end of memory etc. |
@@ -1748,22 +1748,18 @@ enum slow_d_compare { | |||
1748 | 1748 | ||
1749 | static noinline enum slow_d_compare slow_dentry_cmp( | 1749 | static noinline enum slow_d_compare slow_dentry_cmp( |
1750 | const struct dentry *parent, | 1750 | const struct dentry *parent, |
1751 | struct inode *inode, | ||
1752 | struct dentry *dentry, | 1751 | struct dentry *dentry, |
1753 | unsigned int seq, | 1752 | unsigned int seq, |
1754 | const struct qstr *name) | 1753 | const struct qstr *name) |
1755 | { | 1754 | { |
1756 | int tlen = dentry->d_name.len; | 1755 | int tlen = dentry->d_name.len; |
1757 | const char *tname = dentry->d_name.name; | 1756 | const char *tname = dentry->d_name.name; |
1758 | struct inode *i = dentry->d_inode; | ||
1759 | 1757 | ||
1760 | if (read_seqcount_retry(&dentry->d_seq, seq)) { | 1758 | if (read_seqcount_retry(&dentry->d_seq, seq)) { |
1761 | cpu_relax(); | 1759 | cpu_relax(); |
1762 | return D_COMP_SEQRETRY; | 1760 | return D_COMP_SEQRETRY; |
1763 | } | 1761 | } |
1764 | if (parent->d_op->d_compare(parent, inode, | 1762 | if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) |
1765 | dentry, i, | ||
1766 | tlen, tname, name)) | ||
1767 | return D_COMP_NOMATCH; | 1763 | return D_COMP_NOMATCH; |
1768 | return D_COMP_OK; | 1764 | return D_COMP_OK; |
1769 | } | 1765 | } |
@@ -1773,7 +1769,6 @@ static noinline enum slow_d_compare slow_dentry_cmp( | |||
1773 | * @parent: parent dentry | 1769 | * @parent: parent dentry |
1774 | * @name: qstr of name we wish to find | 1770 | * @name: qstr of name we wish to find |
1775 | * @seqp: returns d_seq value at the point where the dentry was found | 1771 | * @seqp: returns d_seq value at the point where the dentry was found |
1776 | * @inode: returns dentry->d_inode when the inode was found valid. | ||
1777 | * Returns: dentry, or NULL | 1772 | * Returns: dentry, or NULL |
1778 | * | 1773 | * |
1779 | * __d_lookup_rcu is the dcache lookup function for rcu-walk name | 1774 | * __d_lookup_rcu is the dcache lookup function for rcu-walk name |
@@ -1800,7 +1795,7 @@ static noinline enum slow_d_compare slow_dentry_cmp( | |||
1800 | */ | 1795 | */ |
1801 | struct dentry *__d_lookup_rcu(const struct dentry *parent, | 1796 | struct dentry *__d_lookup_rcu(const struct dentry *parent, |
1802 | const struct qstr *name, | 1797 | const struct qstr *name, |
1803 | unsigned *seqp, struct inode *inode) | 1798 | unsigned *seqp) |
1804 | { | 1799 | { |
1805 | u64 hashlen = name->hash_len; | 1800 | u64 hashlen = name->hash_len; |
1806 | const unsigned char *str = name->name; | 1801 | const unsigned char *str = name->name; |
@@ -1834,11 +1829,10 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent, | |||
1834 | seqretry: | 1829 | seqretry: |
1835 | /* | 1830 | /* |
1836 | * The dentry sequence count protects us from concurrent | 1831 | * The dentry sequence count protects us from concurrent |
1837 | * renames, and thus protects inode, parent and name fields. | 1832 | * renames, and thus protects parent and name fields. |
1838 | * | 1833 | * |
1839 | * The caller must perform a seqcount check in order | 1834 | * The caller must perform a seqcount check in order |
1840 | * to do anything useful with the returned dentry, | 1835 | * to do anything useful with the returned dentry. |
1841 | * including using the 'd_inode' pointer. | ||
1842 | * | 1836 | * |
1843 | * NOTE! We do a "raw" seqcount_begin here. That means that | 1837 | * NOTE! We do a "raw" seqcount_begin here. That means that |
1844 | * we don't wait for the sequence count to stabilize if it | 1838 | * we don't wait for the sequence count to stabilize if it |
@@ -1852,12 +1846,12 @@ seqretry: | |||
1852 | continue; | 1846 | continue; |
1853 | if (d_unhashed(dentry)) | 1847 | if (d_unhashed(dentry)) |
1854 | continue; | 1848 | continue; |
1855 | *seqp = seq; | ||
1856 | 1849 | ||
1857 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { | 1850 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { |
1858 | if (dentry->d_name.hash != hashlen_hash(hashlen)) | 1851 | if (dentry->d_name.hash != hashlen_hash(hashlen)) |
1859 | continue; | 1852 | continue; |
1860 | switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) { | 1853 | *seqp = seq; |
1854 | switch (slow_dentry_cmp(parent, dentry, seq, name)) { | ||
1861 | case D_COMP_OK: | 1855 | case D_COMP_OK: |
1862 | return dentry; | 1856 | return dentry; |
1863 | case D_COMP_NOMATCH: | 1857 | case D_COMP_NOMATCH: |
@@ -1869,6 +1863,7 @@ seqretry: | |||
1869 | 1863 | ||
1870 | if (dentry->d_name.hash_len != hashlen) | 1864 | if (dentry->d_name.hash_len != hashlen) |
1871 | continue; | 1865 | continue; |
1866 | *seqp = seq; | ||
1872 | if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) | 1867 | if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) |
1873 | return dentry; | 1868 | return dentry; |
1874 | } | 1869 | } |
@@ -1966,9 +1961,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) | |||
1966 | if (parent->d_flags & DCACHE_OP_COMPARE) { | 1961 | if (parent->d_flags & DCACHE_OP_COMPARE) { |
1967 | int tlen = dentry->d_name.len; | 1962 | int tlen = dentry->d_name.len; |
1968 | const char *tname = dentry->d_name.name; | 1963 | const char *tname = dentry->d_name.name; |
1969 | if (parent->d_op->d_compare(parent, parent->d_inode, | 1964 | if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) |
1970 | dentry, dentry->d_inode, | ||
1971 | tlen, tname, name)) | ||
1972 | goto next; | 1965 | goto next; |
1973 | } else { | 1966 | } else { |
1974 | if (dentry->d_name.len != len) | 1967 | if (dentry->d_name.len != len) |
@@ -2005,7 +1998,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) | |||
2005 | */ | 1998 | */ |
2006 | name->hash = full_name_hash(name->name, name->len); | 1999 | name->hash = full_name_hash(name->name, name->len); |
2007 | if (dir->d_flags & DCACHE_OP_HASH) { | 2000 | if (dir->d_flags & DCACHE_OP_HASH) { |
2008 | int err = dir->d_op->d_hash(dir, dir->d_inode, name); | 2001 | int err = dir->d_op->d_hash(dir, name); |
2009 | if (unlikely(err < 0)) | 2002 | if (unlikely(err < 0)) |
2010 | return ERR_PTR(err); | 2003 | return ERR_PTR(err); |
2011 | } | 2004 | } |
@@ -2975,34 +2968,21 @@ rename_retry: | |||
2975 | goto again; | 2968 | goto again; |
2976 | } | 2969 | } |
2977 | 2970 | ||
2978 | /** | 2971 | void d_tmpfile(struct dentry *dentry, struct inode *inode) |
2979 | * find_inode_number - check for dentry with name | ||
2980 | * @dir: directory to check | ||
2981 | * @name: Name to find. | ||
2982 | * | ||
2983 | * Check whether a dentry already exists for the given name, | ||
2984 | * and return the inode number if it has an inode. Otherwise | ||
2985 | * 0 is returned. | ||
2986 | * | ||
2987 | * This routine is used to post-process directory listings for | ||
2988 | * filesystems using synthetic inode numbers, and is necessary | ||
2989 | * to keep getcwd() working. | ||
2990 | */ | ||
2991 | |||
2992 | ino_t find_inode_number(struct dentry *dir, struct qstr *name) | ||
2993 | { | 2972 | { |
2994 | struct dentry * dentry; | 2973 | inode_dec_link_count(inode); |
2995 | ino_t ino = 0; | 2974 | BUG_ON(dentry->d_name.name != dentry->d_iname || |
2996 | 2975 | !hlist_unhashed(&dentry->d_alias) || | |
2997 | dentry = d_hash_and_lookup(dir, name); | 2976 | !d_unlinked(dentry)); |
2998 | if (!IS_ERR_OR_NULL(dentry)) { | 2977 | spin_lock(&dentry->d_parent->d_lock); |
2999 | if (dentry->d_inode) | 2978 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
3000 | ino = dentry->d_inode->i_ino; | 2979 | dentry->d_name.len = sprintf(dentry->d_iname, "#%llu", |
3001 | dput(dentry); | 2980 | (unsigned long long)inode->i_ino); |
3002 | } | 2981 | spin_unlock(&dentry->d_lock); |
3003 | return ino; | 2982 | spin_unlock(&dentry->d_parent->d_lock); |
2983 | d_instantiate(dentry, inode); | ||
3004 | } | 2984 | } |
3005 | EXPORT_SYMBOL(find_inode_number); | 2985 | EXPORT_SYMBOL(d_tmpfile); |
3006 | 2986 | ||
3007 | static __initdata unsigned long dhash_entries; | 2987 | static __initdata unsigned long dhash_entries; |
3008 | static int __init set_dhash_entries(char *str) | 2988 | static int __init set_dhash_entries(char *str) |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f71ec125290d..cfa109a4d5a2 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -2243,12 +2243,11 @@ out: | |||
2243 | */ | 2243 | */ |
2244 | int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, | 2244 | int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, |
2245 | size_t *plaintext_name_size, | 2245 | size_t *plaintext_name_size, |
2246 | struct dentry *ecryptfs_dir_dentry, | 2246 | struct super_block *sb, |
2247 | const char *name, size_t name_size) | 2247 | const char *name, size_t name_size) |
2248 | { | 2248 | { |
2249 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 2249 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
2250 | &ecryptfs_superblock_to_private( | 2250 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; |
2251 | ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; | ||
2252 | char *decoded_name; | 2251 | char *decoded_name; |
2253 | size_t decoded_name_size; | 2252 | size_t decoded_name_size; |
2254 | size_t packet_size; | 2253 | size_t packet_size; |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index f622a733f7ad..df19d34a033b 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -575,7 +575,7 @@ int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | |||
575 | struct inode *ecryptfs_inode); | 575 | struct inode *ecryptfs_inode); |
576 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 576 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
577 | size_t *decrypted_name_size, | 577 | size_t *decrypted_name_size, |
578 | struct dentry *ecryptfs_dentry, | 578 | struct super_block *sb, |
579 | const char *name, size_t name_size); | 579 | const char *name, size_t name_size); |
580 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | 580 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); |
581 | int ecryptfs_encrypt_and_encode_filename( | 581 | int ecryptfs_encrypt_and_encode_filename( |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 9aa05e08060b..24f1105fda3a 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -70,7 +70,7 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
70 | struct ecryptfs_getdents_callback { | 70 | struct ecryptfs_getdents_callback { |
71 | struct dir_context ctx; | 71 | struct dir_context ctx; |
72 | struct dir_context *caller; | 72 | struct dir_context *caller; |
73 | struct dentry *dentry; | 73 | struct super_block *sb; |
74 | int filldir_called; | 74 | int filldir_called; |
75 | int entries_written; | 75 | int entries_written; |
76 | }; | 76 | }; |
@@ -88,7 +88,7 @@ ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, | |||
88 | 88 | ||
89 | buf->filldir_called++; | 89 | buf->filldir_called++; |
90 | rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, | 90 | rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, |
91 | buf->dentry, lower_name, | 91 | buf->sb, lower_name, |
92 | lower_namelen); | 92 | lower_namelen); |
93 | if (rc) { | 93 | if (rc) { |
94 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " | 94 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " |
@@ -114,15 +114,14 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx) | |||
114 | { | 114 | { |
115 | int rc; | 115 | int rc; |
116 | struct file *lower_file; | 116 | struct file *lower_file; |
117 | struct inode *inode; | 117 | struct inode *inode = file_inode(file); |
118 | struct ecryptfs_getdents_callback buf = { | 118 | struct ecryptfs_getdents_callback buf = { |
119 | .ctx.actor = ecryptfs_filldir, | 119 | .ctx.actor = ecryptfs_filldir, |
120 | .caller = ctx, | 120 | .caller = ctx, |
121 | .dentry = file->f_path.dentry | 121 | .sb = inode->i_sb, |
122 | }; | 122 | }; |
123 | lower_file = ecryptfs_file_to_lower(file); | 123 | lower_file = ecryptfs_file_to_lower(file); |
124 | lower_file->f_pos = ctx->pos; | 124 | lower_file->f_pos = ctx->pos; |
125 | inode = file_inode(file); | ||
126 | rc = iterate_dir(lower_file, &buf.ctx); | 125 | rc = iterate_dir(lower_file, &buf.ctx); |
127 | ctx->pos = buf.ctx.pos; | 126 | ctx->pos = buf.ctx.pos; |
128 | if (rc < 0) | 127 | if (rc < 0) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5eab400e2590..a2f2bb2c256d 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -679,7 +679,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, | |||
679 | set_fs(old_fs); | 679 | set_fs(old_fs); |
680 | if (rc < 0) | 680 | if (rc < 0) |
681 | goto out; | 681 | goto out; |
682 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, | 682 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry->d_sb, |
683 | lower_buf, rc); | 683 | lower_buf, rc); |
684 | out: | 684 | out: |
685 | kfree(lower_buf); | 685 | kfree(lower_buf); |
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 141aee31884f..a8766b880c07 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c | |||
@@ -45,8 +45,8 @@ static struct super_block *efivarfs_sb; | |||
45 | * So we need to perform a case-sensitive match on part 1 and a | 45 | * So we need to perform a case-sensitive match on part 1 and a |
46 | * case-insensitive match on part 2. | 46 | * case-insensitive match on part 2. |
47 | */ | 47 | */ |
48 | static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode, | 48 | static int efivarfs_d_compare(const struct dentry *parent, |
49 | const struct dentry *dentry, const struct inode *inode, | 49 | const struct dentry *dentry, |
50 | unsigned int len, const char *str, | 50 | unsigned int len, const char *str, |
51 | const struct qstr *name) | 51 | const struct qstr *name) |
52 | { | 52 | { |
@@ -63,8 +63,7 @@ static int efivarfs_d_compare(const struct dentry *parent, const struct inode *p | |||
63 | return strncasecmp(name->name + guid, str + guid, EFI_VARIABLE_GUID_LEN); | 63 | return strncasecmp(name->name + guid, str + guid, EFI_VARIABLE_GUID_LEN); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int efivarfs_d_hash(const struct dentry *dentry, | 66 | static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr) |
67 | const struct inode *inode, struct qstr *qstr) | ||
68 | { | 67 | { |
69 | unsigned long hash = init_name_hash(); | 68 | unsigned long hash = init_name_hash(); |
70 | const unsigned char *s = qstr->name; | 69 | const unsigned char *s = qstr->name; |
@@ -108,7 +107,7 @@ static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) | |||
108 | q.name = name; | 107 | q.name = name; |
109 | q.len = strlen(name); | 108 | q.len = strlen(name); |
110 | 109 | ||
111 | err = efivarfs_d_hash(NULL, NULL, &q); | 110 | err = efivarfs_d_hash(NULL, &q); |
112 | if (err) | 111 | if (err) |
113 | return ERR_PTR(err); | 112 | return ERR_PTR(err); |
114 | 113 | ||
@@ -110,13 +110,14 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) | |||
110 | static const struct open_flags uselib_flags = { | 110 | static const struct open_flags uselib_flags = { |
111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
112 | .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN, | 112 | .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN, |
113 | .intent = LOOKUP_OPEN | 113 | .intent = LOOKUP_OPEN, |
114 | .lookup_flags = LOOKUP_FOLLOW, | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | if (IS_ERR(tmp)) | 117 | if (IS_ERR(tmp)) |
117 | goto out; | 118 | goto out; |
118 | 119 | ||
119 | file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW); | 120 | file = do_filp_open(AT_FDCWD, tmp, &uselib_flags); |
120 | putname(tmp); | 121 | putname(tmp); |
121 | error = PTR_ERR(file); | 122 | error = PTR_ERR(file); |
122 | if (IS_ERR(file)) | 123 | if (IS_ERR(file)) |
@@ -756,10 +757,11 @@ struct file *open_exec(const char *name) | |||
756 | static const struct open_flags open_exec_flags = { | 757 | static const struct open_flags open_exec_flags = { |
757 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 758 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
758 | .acc_mode = MAY_EXEC | MAY_OPEN, | 759 | .acc_mode = MAY_EXEC | MAY_OPEN, |
759 | .intent = LOOKUP_OPEN | 760 | .intent = LOOKUP_OPEN, |
761 | .lookup_flags = LOOKUP_FOLLOW, | ||
760 | }; | 762 | }; |
761 | 763 | ||
762 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW); | 764 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags); |
763 | if (IS_ERR(file)) | 765 | if (IS_ERR(file)) |
764 | goto out; | 766 | goto out; |
765 | 767 | ||
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 73b0d9519836..256dd5f4c1c4 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -119,6 +119,29 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode | |||
119 | return ext2_add_nondir(dentry, inode); | 119 | return ext2_add_nondir(dentry, inode); |
120 | } | 120 | } |
121 | 121 | ||
122 | static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
123 | { | ||
124 | struct inode *inode = ext2_new_inode(dir, mode, NULL); | ||
125 | if (IS_ERR(inode)) | ||
126 | return PTR_ERR(inode); | ||
127 | |||
128 | inode->i_op = &ext2_file_inode_operations; | ||
129 | if (ext2_use_xip(inode->i_sb)) { | ||
130 | inode->i_mapping->a_ops = &ext2_aops_xip; | ||
131 | inode->i_fop = &ext2_xip_file_operations; | ||
132 | } else if (test_opt(inode->i_sb, NOBH)) { | ||
133 | inode->i_mapping->a_ops = &ext2_nobh_aops; | ||
134 | inode->i_fop = &ext2_file_operations; | ||
135 | } else { | ||
136 | inode->i_mapping->a_ops = &ext2_aops; | ||
137 | inode->i_fop = &ext2_file_operations; | ||
138 | } | ||
139 | mark_inode_dirty(inode); | ||
140 | d_tmpfile(dentry, inode); | ||
141 | unlock_new_inode(inode); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
122 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) | 145 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
123 | { | 146 | { |
124 | struct inode * inode; | 147 | struct inode * inode; |
@@ -398,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = { | |||
398 | #endif | 421 | #endif |
399 | .setattr = ext2_setattr, | 422 | .setattr = ext2_setattr, |
400 | .get_acl = ext2_get_acl, | 423 | .get_acl = ext2_get_acl, |
424 | .tmpfile = ext2_tmpfile, | ||
401 | }; | 425 | }; |
402 | 426 | ||
403 | const struct inode_operations ext2_special_inode_operations = { | 427 | const struct inode_operations ext2_special_inode_operations = { |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index cea8ecf3e76e..998ea111e537 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1759,6 +1759,45 @@ retry: | |||
1759 | return err; | 1759 | return err; |
1760 | } | 1760 | } |
1761 | 1761 | ||
1762 | static int ext3_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
1763 | { | ||
1764 | handle_t *handle; | ||
1765 | struct inode *inode; | ||
1766 | int err, retries = 0; | ||
1767 | |||
1768 | dquot_initialize(dir); | ||
1769 | |||
1770 | retry: | ||
1771 | handle = ext3_journal_start(dir, EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + | ||
1772 | 4 + EXT3_XATTR_TRANS_BLOCKS); | ||
1773 | |||
1774 | if (IS_ERR(handle)) | ||
1775 | return PTR_ERR(handle); | ||
1776 | |||
1777 | inode = ext3_new_inode (handle, dir, NULL, mode); | ||
1778 | err = PTR_ERR(inode); | ||
1779 | if (!IS_ERR(inode)) { | ||
1780 | inode->i_op = &ext3_file_inode_operations; | ||
1781 | inode->i_fop = &ext3_file_operations; | ||
1782 | ext3_set_aops(inode); | ||
1783 | err = ext3_orphan_add(handle, inode); | ||
1784 | if (err) | ||
1785 | goto err_drop_inode; | ||
1786 | mark_inode_dirty(inode); | ||
1787 | d_tmpfile(dentry, inode); | ||
1788 | unlock_new_inode(inode); | ||
1789 | } | ||
1790 | ext3_journal_stop(handle); | ||
1791 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | ||
1792 | goto retry; | ||
1793 | return err; | ||
1794 | err_drop_inode: | ||
1795 | ext3_journal_stop(handle); | ||
1796 | unlock_new_inode(inode); | ||
1797 | iput(inode); | ||
1798 | return err; | ||
1799 | } | ||
1800 | |||
1762 | static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | 1801 | static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) |
1763 | { | 1802 | { |
1764 | handle_t *handle; | 1803 | handle_t *handle; |
@@ -2300,7 +2339,7 @@ static int ext3_link (struct dentry * old_dentry, | |||
2300 | 2339 | ||
2301 | retry: | 2340 | retry: |
2302 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 2341 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
2303 | EXT3_INDEX_EXTRA_TRANS_BLOCKS); | 2342 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1); |
2304 | if (IS_ERR(handle)) | 2343 | if (IS_ERR(handle)) |
2305 | return PTR_ERR(handle); | 2344 | return PTR_ERR(handle); |
2306 | 2345 | ||
@@ -2314,6 +2353,11 @@ retry: | |||
2314 | err = ext3_add_entry(handle, dentry, inode); | 2353 | err = ext3_add_entry(handle, dentry, inode); |
2315 | if (!err) { | 2354 | if (!err) { |
2316 | ext3_mark_inode_dirty(handle, inode); | 2355 | ext3_mark_inode_dirty(handle, inode); |
2356 | /* this can happen only for tmpfile being | ||
2357 | * linked the first time | ||
2358 | */ | ||
2359 | if (inode->i_nlink == 1) | ||
2360 | ext3_orphan_del(handle, inode); | ||
2317 | d_instantiate(dentry, inode); | 2361 | d_instantiate(dentry, inode); |
2318 | } else { | 2362 | } else { |
2319 | drop_nlink(inode); | 2363 | drop_nlink(inode); |
@@ -2516,6 +2560,7 @@ const struct inode_operations ext3_dir_inode_operations = { | |||
2516 | .mkdir = ext3_mkdir, | 2560 | .mkdir = ext3_mkdir, |
2517 | .rmdir = ext3_rmdir, | 2561 | .rmdir = ext3_rmdir, |
2518 | .mknod = ext3_mknod, | 2562 | .mknod = ext3_mknod, |
2563 | .tmpfile = ext3_tmpfile, | ||
2519 | .rename = ext3_rename, | 2564 | .rename = ext3_rename, |
2520 | .setattr = ext3_setattr, | 2565 | .setattr = ext3_setattr, |
2521 | #ifdef CONFIG_EXT3_FS_XATTR | 2566 | #ifdef CONFIG_EXT3_FS_XATTR |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index b19f0a457f32..6f4cc567c382 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -494,17 +494,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) | |||
494 | if (dataoff > isize) | 494 | if (dataoff > isize) |
495 | return -ENXIO; | 495 | return -ENXIO; |
496 | 496 | ||
497 | if (dataoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 497 | return vfs_setpos(file, dataoff, maxsize); |
498 | return -EINVAL; | ||
499 | if (dataoff > maxsize) | ||
500 | return -EINVAL; | ||
501 | |||
502 | if (dataoff != file->f_pos) { | ||
503 | file->f_pos = dataoff; | ||
504 | file->f_version = 0; | ||
505 | } | ||
506 | |||
507 | return dataoff; | ||
508 | } | 498 | } |
509 | 499 | ||
510 | /* | 500 | /* |
@@ -580,17 +570,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) | |||
580 | if (holeoff > isize) | 570 | if (holeoff > isize) |
581 | holeoff = isize; | 571 | holeoff = isize; |
582 | 572 | ||
583 | if (holeoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 573 | return vfs_setpos(file, holeoff, maxsize); |
584 | return -EINVAL; | ||
585 | if (holeoff > maxsize) | ||
586 | return -EINVAL; | ||
587 | |||
588 | if (holeoff != file->f_pos) { | ||
589 | file->f_pos = holeoff; | ||
590 | file->f_version = 0; | ||
591 | } | ||
592 | |||
593 | return holeoff; | ||
594 | } | 574 | } |
595 | 575 | ||
596 | /* | 576 | /* |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index ab2f6dc44b3a..234b834d5a97 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -2296,6 +2296,45 @@ retry: | |||
2296 | return err; | 2296 | return err; |
2297 | } | 2297 | } |
2298 | 2298 | ||
2299 | static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
2300 | { | ||
2301 | handle_t *handle; | ||
2302 | struct inode *inode; | ||
2303 | int err, retries = 0; | ||
2304 | |||
2305 | dquot_initialize(dir); | ||
2306 | |||
2307 | retry: | ||
2308 | inode = ext4_new_inode_start_handle(dir, mode, | ||
2309 | NULL, 0, NULL, | ||
2310 | EXT4_HT_DIR, | ||
2311 | EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + | ||
2312 | 4 + EXT4_XATTR_TRANS_BLOCKS); | ||
2313 | handle = ext4_journal_current_handle(); | ||
2314 | err = PTR_ERR(inode); | ||
2315 | if (!IS_ERR(inode)) { | ||
2316 | inode->i_op = &ext4_file_inode_operations; | ||
2317 | inode->i_fop = &ext4_file_operations; | ||
2318 | ext4_set_aops(inode); | ||
2319 | err = ext4_orphan_add(handle, inode); | ||
2320 | if (err) | ||
2321 | goto err_drop_inode; | ||
2322 | mark_inode_dirty(inode); | ||
2323 | d_tmpfile(dentry, inode); | ||
2324 | unlock_new_inode(inode); | ||
2325 | } | ||
2326 | if (handle) | ||
2327 | ext4_journal_stop(handle); | ||
2328 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | ||
2329 | goto retry; | ||
2330 | return err; | ||
2331 | err_drop_inode: | ||
2332 | ext4_journal_stop(handle); | ||
2333 | unlock_new_inode(inode); | ||
2334 | iput(inode); | ||
2335 | return err; | ||
2336 | } | ||
2337 | |||
2299 | struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, | 2338 | struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, |
2300 | struct ext4_dir_entry_2 *de, | 2339 | struct ext4_dir_entry_2 *de, |
2301 | int blocksize, int csum_size, | 2340 | int blocksize, int csum_size, |
@@ -2903,7 +2942,7 @@ static int ext4_link(struct dentry *old_dentry, | |||
2903 | retry: | 2942 | retry: |
2904 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | 2943 | handle = ext4_journal_start(dir, EXT4_HT_DIR, |
2905 | (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + | 2944 | (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + |
2906 | EXT4_INDEX_EXTRA_TRANS_BLOCKS)); | 2945 | EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1); |
2907 | if (IS_ERR(handle)) | 2946 | if (IS_ERR(handle)) |
2908 | return PTR_ERR(handle); | 2947 | return PTR_ERR(handle); |
2909 | 2948 | ||
@@ -2917,6 +2956,11 @@ retry: | |||
2917 | err = ext4_add_entry(handle, dentry, inode); | 2956 | err = ext4_add_entry(handle, dentry, inode); |
2918 | if (!err) { | 2957 | if (!err) { |
2919 | ext4_mark_inode_dirty(handle, inode); | 2958 | ext4_mark_inode_dirty(handle, inode); |
2959 | /* this can happen only for tmpfile being | ||
2960 | * linked the first time | ||
2961 | */ | ||
2962 | if (inode->i_nlink == 1) | ||
2963 | ext4_orphan_del(handle, inode); | ||
2920 | d_instantiate(dentry, inode); | 2964 | d_instantiate(dentry, inode); |
2921 | } else { | 2965 | } else { |
2922 | drop_nlink(inode); | 2966 | drop_nlink(inode); |
@@ -3169,6 +3213,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
3169 | .mkdir = ext4_mkdir, | 3213 | .mkdir = ext4_mkdir, |
3170 | .rmdir = ext4_rmdir, | 3214 | .rmdir = ext4_rmdir, |
3171 | .mknod = ext4_mknod, | 3215 | .mknod = ext4_mknod, |
3216 | .tmpfile = ext4_tmpfile, | ||
3172 | .rename = ext4_rename, | 3217 | .rename = ext4_rename, |
3173 | .setattr = ext4_setattr, | 3218 | .setattr = ext4_setattr, |
3174 | .setxattr = generic_setxattr, | 3219 | .setxattr = generic_setxattr, |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 081b759cff83..a783b0e1272a 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -148,8 +148,7 @@ static int msdos_find(struct inode *dir, const unsigned char *name, int len, | |||
148 | * that the existing dentry can be used. The msdos fs routines will | 148 | * that the existing dentry can be used. The msdos fs routines will |
149 | * return ENOENT or EINVAL as appropriate. | 149 | * return ENOENT or EINVAL as appropriate. |
150 | */ | 150 | */ |
151 | static int msdos_hash(const struct dentry *dentry, const struct inode *inode, | 151 | static int msdos_hash(const struct dentry *dentry, struct qstr *qstr) |
152 | struct qstr *qstr) | ||
153 | { | 152 | { |
154 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; | 153 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; |
155 | unsigned char msdos_name[MSDOS_NAME]; | 154 | unsigned char msdos_name[MSDOS_NAME]; |
@@ -165,8 +164,7 @@ static int msdos_hash(const struct dentry *dentry, const struct inode *inode, | |||
165 | * Compare two msdos names. If either of the names are invalid, | 164 | * Compare two msdos names. If either of the names are invalid, |
166 | * we fall back to doing the standard name comparison. | 165 | * we fall back to doing the standard name comparison. |
167 | */ | 166 | */ |
168 | static int msdos_cmp(const struct dentry *parent, const struct inode *pinode, | 167 | static int msdos_cmp(const struct dentry *parent, const struct dentry *dentry, |
169 | const struct dentry *dentry, const struct inode *inode, | ||
170 | unsigned int len, const char *str, const struct qstr *name) | 168 | unsigned int len, const char *str, const struct qstr *name) |
171 | { | 169 | { |
172 | struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options; | 170 | struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 2da952036a3d..6df8d3d885e5 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -107,8 +107,7 @@ static unsigned int vfat_striptail_len(const struct qstr *qstr) | |||
107 | * that the existing dentry can be used. The vfat fs routines will | 107 | * that the existing dentry can be used. The vfat fs routines will |
108 | * return ENOENT or EINVAL as appropriate. | 108 | * return ENOENT or EINVAL as appropriate. |
109 | */ | 109 | */ |
110 | static int vfat_hash(const struct dentry *dentry, const struct inode *inode, | 110 | static int vfat_hash(const struct dentry *dentry, struct qstr *qstr) |
111 | struct qstr *qstr) | ||
112 | { | 111 | { |
113 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); | 112 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); |
114 | return 0; | 113 | return 0; |
@@ -120,8 +119,7 @@ static int vfat_hash(const struct dentry *dentry, const struct inode *inode, | |||
120 | * that the existing dentry can be used. The vfat fs routines will | 119 | * that the existing dentry can be used. The vfat fs routines will |
121 | * return ENOENT or EINVAL as appropriate. | 120 | * return ENOENT or EINVAL as appropriate. |
122 | */ | 121 | */ |
123 | static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, | 122 | static int vfat_hashi(const struct dentry *dentry, struct qstr *qstr) |
124 | struct qstr *qstr) | ||
125 | { | 123 | { |
126 | struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; | 124 | struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; |
127 | const unsigned char *name; | 125 | const unsigned char *name; |
@@ -142,8 +140,7 @@ static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, | |||
142 | /* | 140 | /* |
143 | * Case insensitive compare of two vfat names. | 141 | * Case insensitive compare of two vfat names. |
144 | */ | 142 | */ |
145 | static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode, | 143 | static int vfat_cmpi(const struct dentry *parent, const struct dentry *dentry, |
146 | const struct dentry *dentry, const struct inode *inode, | ||
147 | unsigned int len, const char *str, const struct qstr *name) | 144 | unsigned int len, const char *str, const struct qstr *name) |
148 | { | 145 | { |
149 | struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io; | 146 | struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io; |
@@ -162,8 +159,7 @@ static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode, | |||
162 | /* | 159 | /* |
163 | * Case sensitive compare of two vfat names. | 160 | * Case sensitive compare of two vfat names. |
164 | */ | 161 | */ |
165 | static int vfat_cmp(const struct dentry *parent, const struct inode *pinode, | 162 | static int vfat_cmp(const struct dentry *parent, const struct dentry *dentry, |
166 | const struct dentry *dentry, const struct inode *inode, | ||
167 | unsigned int len, const char *str, const struct qstr *name) | 163 | unsigned int len, const char *str, const struct qstr *name) |
168 | { | 164 | { |
169 | unsigned int alen, blen; | 165 | unsigned int alen, blen; |
diff --git a/fs/file_table.c b/fs/file_table.c index 485dc0eddd67..08e719b884ca 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -227,7 +227,7 @@ static void __fput(struct file *file) | |||
227 | { | 227 | { |
228 | struct dentry *dentry = file->f_path.dentry; | 228 | struct dentry *dentry = file->f_path.dentry; |
229 | struct vfsmount *mnt = file->f_path.mnt; | 229 | struct vfsmount *mnt = file->f_path.mnt; |
230 | struct inode *inode = dentry->d_inode; | 230 | struct inode *inode = file->f_inode; |
231 | 231 | ||
232 | might_sleep(); | 232 | might_sleep(); |
233 | 233 | ||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 35f281033142..5c121fe19c5f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -548,8 +548,7 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos) | |||
548 | res = io->bytes < 0 ? io->size : io->bytes; | 548 | res = io->bytes < 0 ? io->size : io->bytes; |
549 | 549 | ||
550 | if (!is_sync_kiocb(io->iocb)) { | 550 | if (!is_sync_kiocb(io->iocb)) { |
551 | struct path *path = &io->iocb->ki_filp->f_path; | 551 | struct inode *inode = file_inode(io->iocb->ki_filp); |
552 | struct inode *inode = path->dentry->d_inode; | ||
553 | struct fuse_conn *fc = get_fuse_conn(inode); | 552 | struct fuse_conn *fc = get_fuse_conn(inode); |
554 | struct fuse_inode *fi = get_fuse_inode(inode); | 553 | struct fuse_inode *fi = get_fuse_inode(inode); |
555 | 554 | ||
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index 4fddb3c22d25..f2448ab2aac5 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -109,8 +109,7 @@ fail: | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode, | 112 | static int gfs2_dhash(const struct dentry *dentry, struct qstr *str) |
113 | struct qstr *str) | ||
114 | { | 113 | { |
115 | str->hash = gfs2_disk_hash(str->name, str->len); | 114 | str->hash = gfs2_disk_hash(str->name, str->len); |
116 | return 0; | 115 | return 0; |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index f99f9e8a325f..72c3866a7320 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -912,7 +912,7 @@ out_uninit: | |||
912 | * cluster; until we do, disable leases (by just returning -EINVAL), | 912 | * cluster; until we do, disable leases (by just returning -EINVAL), |
913 | * unless the administrator has requested purely local locking. | 913 | * unless the administrator has requested purely local locking. |
914 | * | 914 | * |
915 | * Locking: called under lock_flocks | 915 | * Locking: called under i_lock |
916 | * | 916 | * |
917 | * Returns: errno | 917 | * Returns: errno |
918 | */ | 918 | */ |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index a73b11839a41..0524cda47a6e 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -229,13 +229,10 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); | |||
229 | /* string.c */ | 229 | /* string.c */ |
230 | extern const struct dentry_operations hfs_dentry_operations; | 230 | extern const struct dentry_operations hfs_dentry_operations; |
231 | 231 | ||
232 | extern int hfs_hash_dentry(const struct dentry *, const struct inode *, | 232 | extern int hfs_hash_dentry(const struct dentry *, struct qstr *); |
233 | struct qstr *); | ||
234 | extern int hfs_strcmp(const unsigned char *, unsigned int, | 233 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
235 | const unsigned char *, unsigned int); | 234 | const unsigned char *, unsigned int); |
236 | extern int hfs_compare_dentry(const struct dentry *parent, | 235 | extern int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
237 | const struct inode *pinode, | ||
238 | const struct dentry *dentry, const struct inode *inode, | ||
239 | unsigned int len, const char *str, const struct qstr *name); | 236 | unsigned int len, const char *str, const struct qstr *name); |
240 | 237 | ||
241 | /* trans.c */ | 238 | /* trans.c */ |
diff --git a/fs/hfs/string.c b/fs/hfs/string.c index 495a976a3cc9..85b610c3909f 100644 --- a/fs/hfs/string.c +++ b/fs/hfs/string.c | |||
@@ -51,8 +51,7 @@ static unsigned char caseorder[256] = { | |||
51 | /* | 51 | /* |
52 | * Hash a string to an integer in a case-independent way | 52 | * Hash a string to an integer in a case-independent way |
53 | */ | 53 | */ |
54 | int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 54 | int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this) |
55 | struct qstr *this) | ||
56 | { | 55 | { |
57 | const unsigned char *name = this->name; | 56 | const unsigned char *name = this->name; |
58 | unsigned int hash, len = this->len; | 57 | unsigned int hash, len = this->len; |
@@ -93,8 +92,7 @@ int hfs_strcmp(const unsigned char *s1, unsigned int len1, | |||
93 | * Test for equality of two strings in the HFS filename character ordering. | 92 | * Test for equality of two strings in the HFS filename character ordering. |
94 | * return 1 on failure and 0 on success | 93 | * return 1 on failure and 0 on success |
95 | */ | 94 | */ |
96 | int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 95 | int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
97 | const struct dentry *dentry, const struct inode *inode, | ||
98 | unsigned int len, const char *str, const struct qstr *name) | 96 | unsigned int len, const char *str, const struct qstr *name) |
99 | { | 97 | { |
100 | const unsigned char *n1, *n2; | 98 | const unsigned char *n1, *n2; |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 60b0a3388b26..ede79317cfb8 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -495,11 +495,8 @@ int hfsplus_uni2asc(struct super_block *, | |||
495 | const struct hfsplus_unistr *, char *, int *); | 495 | const struct hfsplus_unistr *, char *, int *); |
496 | int hfsplus_asc2uni(struct super_block *, | 496 | int hfsplus_asc2uni(struct super_block *, |
497 | struct hfsplus_unistr *, int, const char *, int); | 497 | struct hfsplus_unistr *, int, const char *, int); |
498 | int hfsplus_hash_dentry(const struct dentry *dentry, | 498 | int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); |
499 | const struct inode *inode, struct qstr *str); | 499 | int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
500 | int hfsplus_compare_dentry(const struct dentry *parent, | ||
501 | const struct inode *pinode, | ||
502 | const struct dentry *dentry, const struct inode *inode, | ||
503 | unsigned int len, const char *str, const struct qstr *name); | 500 | unsigned int len, const char *str, const struct qstr *name); |
504 | 501 | ||
505 | /* wrapper.c */ | 502 | /* wrapper.c */ |
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 2c2e47dcfdd8..e8ef121a4d8b 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c | |||
@@ -334,8 +334,7 @@ int hfsplus_asc2uni(struct super_block *sb, | |||
334 | * Composed unicode characters are decomposed and case-folding is performed | 334 | * Composed unicode characters are decomposed and case-folding is performed |
335 | * if the appropriate bits are (un)set on the superblock. | 335 | * if the appropriate bits are (un)set on the superblock. |
336 | */ | 336 | */ |
337 | int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 337 | int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str) |
338 | struct qstr *str) | ||
339 | { | 338 | { |
340 | struct super_block *sb = dentry->d_sb; | 339 | struct super_block *sb = dentry->d_sb; |
341 | const char *astr; | 340 | const char *astr; |
@@ -386,9 +385,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |||
386 | * Composed unicode characters are decomposed and case-folding is performed | 385 | * Composed unicode characters are decomposed and case-folding is performed |
387 | * if the appropriate bits are (un)set on the superblock. | 386 | * if the appropriate bits are (un)set on the superblock. |
388 | */ | 387 | */ |
389 | int hfsplus_compare_dentry(const struct dentry *parent, | 388 | int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
390 | const struct inode *pinode, | ||
391 | const struct dentry *dentry, const struct inode *inode, | ||
392 | unsigned int len, const char *str, const struct qstr *name) | 389 | unsigned int len, const char *str, const struct qstr *name) |
393 | { | 390 | { |
394 | struct super_block *sb = parent->d_sb; | 391 | struct super_block *sb = parent->d_sb; |
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c index 05d4816e4e77..fa27980f2229 100644 --- a/fs/hpfs/dentry.c +++ b/fs/hpfs/dentry.c | |||
@@ -12,8 +12,7 @@ | |||
12 | * Note: the dentry argument is the parent dentry. | 12 | * Note: the dentry argument is the parent dentry. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 15 | static int hpfs_hash_dentry(const struct dentry *dentry, struct qstr *qstr) |
16 | struct qstr *qstr) | ||
17 | { | 16 | { |
18 | unsigned long hash; | 17 | unsigned long hash; |
19 | int i; | 18 | int i; |
@@ -35,9 +34,7 @@ static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *ino | |||
35 | return 0; | 34 | return 0; |
36 | } | 35 | } |
37 | 36 | ||
38 | static int hpfs_compare_dentry(const struct dentry *parent, | 37 | static int hpfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
39 | const struct inode *pinode, | ||
40 | const struct dentry *dentry, const struct inode *inode, | ||
41 | unsigned int len, const char *str, const struct qstr *name) | 38 | unsigned int len, const char *str, const struct qstr *name) |
42 | { | 39 | { |
43 | unsigned al = len; | 40 | unsigned al = len; |
diff --git a/fs/inode.c b/fs/inode.c index 00d5fc3b86e1..d6dfb09c8280 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -333,8 +333,10 @@ EXPORT_SYMBOL(set_nlink); | |||
333 | */ | 333 | */ |
334 | void inc_nlink(struct inode *inode) | 334 | void inc_nlink(struct inode *inode) |
335 | { | 335 | { |
336 | if (WARN_ON(inode->i_nlink == 0)) | 336 | if (unlikely(inode->i_nlink == 0)) { |
337 | WARN_ON(!(inode->i_state & I_LINKABLE)); | ||
337 | atomic_long_dec(&inode->i_sb->s_remove_count); | 338 | atomic_long_dec(&inode->i_sb->s_remove_count); |
339 | } | ||
338 | 340 | ||
339 | inode->__i_nlink++; | 341 | inode->__i_nlink++; |
340 | } | 342 | } |
diff --git a/fs/internal.h b/fs/internal.h index 68121584ae37..7c5f01cf619d 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -96,11 +96,12 @@ struct open_flags { | |||
96 | umode_t mode; | 96 | umode_t mode; |
97 | int acc_mode; | 97 | int acc_mode; |
98 | int intent; | 98 | int intent; |
99 | int lookup_flags; | ||
99 | }; | 100 | }; |
100 | extern struct file *do_filp_open(int dfd, struct filename *pathname, | 101 | extern struct file *do_filp_open(int dfd, struct filename *pathname, |
101 | const struct open_flags *op, int flags); | 102 | const struct open_flags *op); |
102 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, | 103 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, |
103 | const char *, const struct open_flags *, int lookup_flags); | 104 | const char *, const struct open_flags *); |
104 | 105 | ||
105 | extern long do_handle_open(int mountdirfd, | 106 | extern long do_handle_open(int mountdirfd, |
106 | struct file_handle __user *ufh, int open_flag); | 107 | struct file_handle __user *ufh, int open_flag); |
@@ -130,6 +131,7 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); | |||
130 | * read_write.c | 131 | * read_write.c |
131 | */ | 132 | */ |
132 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); | 133 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); |
134 | extern int rw_verify_area(int, struct file *, const loff_t *, size_t); | ||
133 | 135 | ||
134 | /* | 136 | /* |
135 | * splice.c | 137 | * splice.c |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index d9b8aebdeb22..c348d6d88624 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -28,31 +28,23 @@ | |||
28 | 28 | ||
29 | #define BEQUIET | 29 | #define BEQUIET |
30 | 30 | ||
31 | static int isofs_hashi(const struct dentry *parent, const struct inode *inode, | 31 | static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); |
32 | struct qstr *qstr); | 32 | static int isofs_hash(const struct dentry *parent, struct qstr *qstr); |
33 | static int isofs_hash(const struct dentry *parent, const struct inode *inode, | ||
34 | struct qstr *qstr); | ||
35 | static int isofs_dentry_cmpi(const struct dentry *parent, | 33 | static int isofs_dentry_cmpi(const struct dentry *parent, |
36 | const struct inode *pinode, | 34 | const struct dentry *dentry, |
37 | const struct dentry *dentry, const struct inode *inode, | ||
38 | unsigned int len, const char *str, const struct qstr *name); | 35 | unsigned int len, const char *str, const struct qstr *name); |
39 | static int isofs_dentry_cmp(const struct dentry *parent, | 36 | static int isofs_dentry_cmp(const struct dentry *parent, |
40 | const struct inode *pinode, | 37 | const struct dentry *dentry, |
41 | const struct dentry *dentry, const struct inode *inode, | ||
42 | unsigned int len, const char *str, const struct qstr *name); | 38 | unsigned int len, const char *str, const struct qstr *name); |
43 | 39 | ||
44 | #ifdef CONFIG_JOLIET | 40 | #ifdef CONFIG_JOLIET |
45 | static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, | 41 | static int isofs_hashi_ms(const struct dentry *parent, struct qstr *qstr); |
46 | struct qstr *qstr); | 42 | static int isofs_hash_ms(const struct dentry *parent, struct qstr *qstr); |
47 | static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, | ||
48 | struct qstr *qstr); | ||
49 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, | 43 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, |
50 | const struct inode *pinode, | 44 | const struct dentry *dentry, |
51 | const struct dentry *dentry, const struct inode *inode, | ||
52 | unsigned int len, const char *str, const struct qstr *name); | 45 | unsigned int len, const char *str, const struct qstr *name); |
53 | static int isofs_dentry_cmp_ms(const struct dentry *parent, | 46 | static int isofs_dentry_cmp_ms(const struct dentry *parent, |
54 | const struct inode *pinode, | 47 | const struct dentry *dentry, |
55 | const struct dentry *dentry, const struct inode *inode, | ||
56 | unsigned int len, const char *str, const struct qstr *name); | 48 | unsigned int len, const char *str, const struct qstr *name); |
57 | #endif | 49 | #endif |
58 | 50 | ||
@@ -265,30 +257,26 @@ static int isofs_dentry_cmp_common( | |||
265 | } | 257 | } |
266 | 258 | ||
267 | static int | 259 | static int |
268 | isofs_hash(const struct dentry *dentry, const struct inode *inode, | 260 | isofs_hash(const struct dentry *dentry, struct qstr *qstr) |
269 | struct qstr *qstr) | ||
270 | { | 261 | { |
271 | return isofs_hash_common(dentry, qstr, 0); | 262 | return isofs_hash_common(dentry, qstr, 0); |
272 | } | 263 | } |
273 | 264 | ||
274 | static int | 265 | static int |
275 | isofs_hashi(const struct dentry *dentry, const struct inode *inode, | 266 | isofs_hashi(const struct dentry *dentry, struct qstr *qstr) |
276 | struct qstr *qstr) | ||
277 | { | 267 | { |
278 | return isofs_hashi_common(dentry, qstr, 0); | 268 | return isofs_hashi_common(dentry, qstr, 0); |
279 | } | 269 | } |
280 | 270 | ||
281 | static int | 271 | static int |
282 | isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode, | 272 | isofs_dentry_cmp(const struct dentry *parent, const struct dentry *dentry, |
283 | const struct dentry *dentry, const struct inode *inode, | ||
284 | unsigned int len, const char *str, const struct qstr *name) | 273 | unsigned int len, const char *str, const struct qstr *name) |
285 | { | 274 | { |
286 | return isofs_dentry_cmp_common(len, str, name, 0, 0); | 275 | return isofs_dentry_cmp_common(len, str, name, 0, 0); |
287 | } | 276 | } |
288 | 277 | ||
289 | static int | 278 | static int |
290 | isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, | 279 | isofs_dentry_cmpi(const struct dentry *parent, const struct dentry *dentry, |
291 | const struct dentry *dentry, const struct inode *inode, | ||
292 | unsigned int len, const char *str, const struct qstr *name) | 280 | unsigned int len, const char *str, const struct qstr *name) |
293 | { | 281 | { |
294 | return isofs_dentry_cmp_common(len, str, name, 0, 1); | 282 | return isofs_dentry_cmp_common(len, str, name, 0, 1); |
@@ -296,30 +284,26 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, | |||
296 | 284 | ||
297 | #ifdef CONFIG_JOLIET | 285 | #ifdef CONFIG_JOLIET |
298 | static int | 286 | static int |
299 | isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, | 287 | isofs_hash_ms(const struct dentry *dentry, struct qstr *qstr) |
300 | struct qstr *qstr) | ||
301 | { | 288 | { |
302 | return isofs_hash_common(dentry, qstr, 1); | 289 | return isofs_hash_common(dentry, qstr, 1); |
303 | } | 290 | } |
304 | 291 | ||
305 | static int | 292 | static int |
306 | isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, | 293 | isofs_hashi_ms(const struct dentry *dentry, struct qstr *qstr) |
307 | struct qstr *qstr) | ||
308 | { | 294 | { |
309 | return isofs_hashi_common(dentry, qstr, 1); | 295 | return isofs_hashi_common(dentry, qstr, 1); |
310 | } | 296 | } |
311 | 297 | ||
312 | static int | 298 | static int |
313 | isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode, | 299 | isofs_dentry_cmp_ms(const struct dentry *parent, const struct dentry *dentry, |
314 | const struct dentry *dentry, const struct inode *inode, | ||
315 | unsigned int len, const char *str, const struct qstr *name) | 300 | unsigned int len, const char *str, const struct qstr *name) |
316 | { | 301 | { |
317 | return isofs_dentry_cmp_common(len, str, name, 1, 0); | 302 | return isofs_dentry_cmp_common(len, str, name, 1, 0); |
318 | } | 303 | } |
319 | 304 | ||
320 | static int | 305 | static int |
321 | isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode, | 306 | isofs_dentry_cmpi_ms(const struct dentry *parent, const struct dentry *dentry, |
322 | const struct dentry *dentry, const struct inode *inode, | ||
323 | unsigned int len, const char *str, const struct qstr *name) | 307 | unsigned int len, const char *str, const struct qstr *name) |
324 | { | 308 | { |
325 | return isofs_dentry_cmp_common(len, str, name, 1, 1); | 309 | return isofs_dentry_cmp_common(len, str, name, 1, 1); |
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index c167028844ed..95295640d9c8 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c | |||
@@ -37,8 +37,7 @@ isofs_cmp(struct dentry *dentry, const char *compare, int dlen) | |||
37 | 37 | ||
38 | qstr.name = compare; | 38 | qstr.name = compare; |
39 | qstr.len = dlen; | 39 | qstr.len = dlen; |
40 | return dentry->d_op->d_compare(NULL, NULL, NULL, NULL, | 40 | return dentry->d_op->d_compare(NULL, NULL, dentry->d_name.len, dentry->d_name.name, &qstr); |
41 | dentry->d_name.len, dentry->d_name.name, &qstr); | ||
42 | } | 41 | } |
43 | 42 | ||
44 | /* | 43 | /* |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 89186b7b9002..8b19027291d6 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1538,8 +1538,7 @@ const struct file_operations jfs_dir_operations = { | |||
1538 | .llseek = generic_file_llseek, | 1538 | .llseek = generic_file_llseek, |
1539 | }; | 1539 | }; |
1540 | 1540 | ||
1541 | static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, | 1541 | static int jfs_ci_hash(const struct dentry *dir, struct qstr *this) |
1542 | struct qstr *this) | ||
1543 | { | 1542 | { |
1544 | unsigned long hash; | 1543 | unsigned long hash; |
1545 | int i; | 1544 | int i; |
@@ -1552,9 +1551,7 @@ static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, | |||
1552 | return 0; | 1551 | return 0; |
1553 | } | 1552 | } |
1554 | 1553 | ||
1555 | static int jfs_ci_compare(const struct dentry *parent, | 1554 | static int jfs_ci_compare(const struct dentry *parent, const struct dentry *dentry, |
1556 | const struct inode *pinode, | ||
1557 | const struct dentry *dentry, const struct inode *inode, | ||
1558 | unsigned int len, const char *str, const struct qstr *name) | 1555 | unsigned int len, const char *str, const struct qstr *name) |
1559 | { | 1556 | { |
1560 | int i, result = 1; | 1557 | int i, result = 1; |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index e703318c41df..067778b0ccc9 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -276,7 +276,7 @@ static int nlmsvc_unlink_block(struct nlm_block *block) | |||
276 | dprintk("lockd: unlinking block %p...\n", block); | 276 | dprintk("lockd: unlinking block %p...\n", block); |
277 | 277 | ||
278 | /* Remove block from list */ | 278 | /* Remove block from list */ |
279 | status = posix_unblock_lock(block->b_file->f_file, &block->b_call->a_args.lock.fl); | 279 | status = posix_unblock_lock(&block->b_call->a_args.lock.fl); |
280 | nlmsvc_remove_block(block); | 280 | nlmsvc_remove_block(block); |
281 | return status; | 281 | return status; |
282 | } | 282 | } |
@@ -744,8 +744,20 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2) | |||
744 | return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; | 744 | return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; |
745 | } | 745 | } |
746 | 746 | ||
747 | /* | ||
748 | * Since NLM uses two "keys" for tracking locks, we need to hash them down | ||
749 | * to one for the blocked_hash. Here, we're just xor'ing the host address | ||
750 | * with the pid in order to create a key value for picking a hash bucket. | ||
751 | */ | ||
752 | static unsigned long | ||
753 | nlmsvc_owner_key(struct file_lock *fl) | ||
754 | { | ||
755 | return (unsigned long)fl->fl_owner ^ (unsigned long)fl->fl_pid; | ||
756 | } | ||
757 | |||
747 | const struct lock_manager_operations nlmsvc_lock_operations = { | 758 | const struct lock_manager_operations nlmsvc_lock_operations = { |
748 | .lm_compare_owner = nlmsvc_same_owner, | 759 | .lm_compare_owner = nlmsvc_same_owner, |
760 | .lm_owner_key = nlmsvc_owner_key, | ||
749 | .lm_notify = nlmsvc_notify_blocked, | 761 | .lm_notify = nlmsvc_notify_blocked, |
750 | .lm_grant = nlmsvc_grant_deferred, | 762 | .lm_grant = nlmsvc_grant_deferred, |
751 | }; | 763 | }; |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 97e87415b145..dc5c75930f0f 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -169,7 +169,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, | |||
169 | 169 | ||
170 | again: | 170 | again: |
171 | file->f_locks = 0; | 171 | file->f_locks = 0; |
172 | lock_flocks(); /* protects i_flock list */ | 172 | spin_lock(&inode->i_lock); |
173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
174 | if (fl->fl_lmops != &nlmsvc_lock_operations) | 174 | if (fl->fl_lmops != &nlmsvc_lock_operations) |
175 | continue; | 175 | continue; |
@@ -181,7 +181,7 @@ again: | |||
181 | if (match(lockhost, host)) { | 181 | if (match(lockhost, host)) { |
182 | struct file_lock lock = *fl; | 182 | struct file_lock lock = *fl; |
183 | 183 | ||
184 | unlock_flocks(); | 184 | spin_unlock(&inode->i_lock); |
185 | lock.fl_type = F_UNLCK; | 185 | lock.fl_type = F_UNLCK; |
186 | lock.fl_start = 0; | 186 | lock.fl_start = 0; |
187 | lock.fl_end = OFFSET_MAX; | 187 | lock.fl_end = OFFSET_MAX; |
@@ -193,7 +193,7 @@ again: | |||
193 | goto again; | 193 | goto again; |
194 | } | 194 | } |
195 | } | 195 | } |
196 | unlock_flocks(); | 196 | spin_unlock(&inode->i_lock); |
197 | 197 | ||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
@@ -228,14 +228,14 @@ nlm_file_inuse(struct nlm_file *file) | |||
228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) | 228 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) |
229 | return 1; | 229 | return 1; |
230 | 230 | ||
231 | lock_flocks(); | 231 | spin_lock(&inode->i_lock); |
232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 232 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { | 233 | if (fl->fl_lmops == &nlmsvc_lock_operations) { |
234 | unlock_flocks(); | 234 | spin_unlock(&inode->i_lock); |
235 | return 1; | 235 | return 1; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | unlock_flocks(); | 238 | spin_unlock(&inode->i_lock); |
239 | file->f_locks = 0; | 239 | file->f_locks = 0; |
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
diff --git a/fs/locks.c b/fs/locks.c index cb424a4fed71..04e2c1fdb157 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -126,6 +126,7 @@ | |||
126 | #include <linux/time.h> | 126 | #include <linux/time.h> |
127 | #include <linux/rcupdate.h> | 127 | #include <linux/rcupdate.h> |
128 | #include <linux/pid_namespace.h> | 128 | #include <linux/pid_namespace.h> |
129 | #include <linux/hashtable.h> | ||
129 | 130 | ||
130 | #include <asm/uaccess.h> | 131 | #include <asm/uaccess.h> |
131 | 132 | ||
@@ -153,30 +154,51 @@ int lease_break_time = 45; | |||
153 | #define for_each_lock(inode, lockp) \ | 154 | #define for_each_lock(inode, lockp) \ |
154 | for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next) | 155 | for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next) |
155 | 156 | ||
156 | static LIST_HEAD(file_lock_list); | 157 | /* |
157 | static LIST_HEAD(blocked_list); | 158 | * The global file_lock_list is only used for displaying /proc/locks. Protected |
159 | * by the file_lock_lock. | ||
160 | */ | ||
161 | static HLIST_HEAD(file_lock_list); | ||
158 | static DEFINE_SPINLOCK(file_lock_lock); | 162 | static DEFINE_SPINLOCK(file_lock_lock); |
159 | 163 | ||
160 | /* | 164 | /* |
161 | * Protects the two list heads above, plus the inode->i_flock list | 165 | * The blocked_hash is used to find POSIX lock loops for deadlock detection. |
166 | * It is protected by blocked_lock_lock. | ||
167 | * | ||
168 | * We hash locks by lockowner in order to optimize searching for the lock a | ||
169 | * particular lockowner is waiting on. | ||
170 | * | ||
171 | * FIXME: make this value scale via some heuristic? We generally will want more | ||
172 | * buckets when we have more lockowners holding locks, but that's a little | ||
173 | * difficult to determine without knowing what the workload will look like. | ||
162 | */ | 174 | */ |
163 | void lock_flocks(void) | 175 | #define BLOCKED_HASH_BITS 7 |
164 | { | 176 | static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS); |
165 | spin_lock(&file_lock_lock); | ||
166 | } | ||
167 | EXPORT_SYMBOL_GPL(lock_flocks); | ||
168 | 177 | ||
169 | void unlock_flocks(void) | 178 | /* |
170 | { | 179 | * This lock protects the blocked_hash. Generally, if you're accessing it, you |
171 | spin_unlock(&file_lock_lock); | 180 | * want to be holding this lock. |
172 | } | 181 | * |
173 | EXPORT_SYMBOL_GPL(unlock_flocks); | 182 | * In addition, it also protects the fl->fl_block list, and the fl->fl_next |
183 | * pointer for file_lock structures that are acting as lock requests (in | ||
184 | * contrast to those that are acting as records of acquired locks). | ||
185 | * | ||
186 | * Note that when we acquire this lock in order to change the above fields, | ||
187 | * we often hold the i_lock as well. In certain cases, when reading the fields | ||
188 | * protected by this lock, we can skip acquiring it iff we already hold the | ||
189 | * i_lock. | ||
190 | * | ||
191 | * In particular, adding an entry to the fl_block list requires that you hold | ||
192 | * both the i_lock and the blocked_lock_lock (acquired in that order). Deleting | ||
193 | * an entry from the list however only requires the file_lock_lock. | ||
194 | */ | ||
195 | static DEFINE_SPINLOCK(blocked_lock_lock); | ||
174 | 196 | ||
175 | static struct kmem_cache *filelock_cache __read_mostly; | 197 | static struct kmem_cache *filelock_cache __read_mostly; |
176 | 198 | ||
177 | static void locks_init_lock_heads(struct file_lock *fl) | 199 | static void locks_init_lock_heads(struct file_lock *fl) |
178 | { | 200 | { |
179 | INIT_LIST_HEAD(&fl->fl_link); | 201 | INIT_HLIST_NODE(&fl->fl_link); |
180 | INIT_LIST_HEAD(&fl->fl_block); | 202 | INIT_LIST_HEAD(&fl->fl_block); |
181 | init_waitqueue_head(&fl->fl_wait); | 203 | init_waitqueue_head(&fl->fl_wait); |
182 | } | 204 | } |
@@ -210,7 +232,7 @@ void locks_free_lock(struct file_lock *fl) | |||
210 | { | 232 | { |
211 | BUG_ON(waitqueue_active(&fl->fl_wait)); | 233 | BUG_ON(waitqueue_active(&fl->fl_wait)); |
212 | BUG_ON(!list_empty(&fl->fl_block)); | 234 | BUG_ON(!list_empty(&fl->fl_block)); |
213 | BUG_ON(!list_empty(&fl->fl_link)); | 235 | BUG_ON(!hlist_unhashed(&fl->fl_link)); |
214 | 236 | ||
215 | locks_release_private(fl); | 237 | locks_release_private(fl); |
216 | kmem_cache_free(filelock_cache, fl); | 238 | kmem_cache_free(filelock_cache, fl); |
@@ -484,47 +506,108 @@ static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2) | |||
484 | return fl1->fl_owner == fl2->fl_owner; | 506 | return fl1->fl_owner == fl2->fl_owner; |
485 | } | 507 | } |
486 | 508 | ||
509 | static inline void | ||
510 | locks_insert_global_locks(struct file_lock *fl) | ||
511 | { | ||
512 | spin_lock(&file_lock_lock); | ||
513 | hlist_add_head(&fl->fl_link, &file_lock_list); | ||
514 | spin_unlock(&file_lock_lock); | ||
515 | } | ||
516 | |||
517 | static inline void | ||
518 | locks_delete_global_locks(struct file_lock *fl) | ||
519 | { | ||
520 | spin_lock(&file_lock_lock); | ||
521 | hlist_del_init(&fl->fl_link); | ||
522 | spin_unlock(&file_lock_lock); | ||
523 | } | ||
524 | |||
525 | static unsigned long | ||
526 | posix_owner_key(struct file_lock *fl) | ||
527 | { | ||
528 | if (fl->fl_lmops && fl->fl_lmops->lm_owner_key) | ||
529 | return fl->fl_lmops->lm_owner_key(fl); | ||
530 | return (unsigned long)fl->fl_owner; | ||
531 | } | ||
532 | |||
533 | static inline void | ||
534 | locks_insert_global_blocked(struct file_lock *waiter) | ||
535 | { | ||
536 | hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter)); | ||
537 | } | ||
538 | |||
539 | static inline void | ||
540 | locks_delete_global_blocked(struct file_lock *waiter) | ||
541 | { | ||
542 | hash_del(&waiter->fl_link); | ||
543 | } | ||
544 | |||
487 | /* Remove waiter from blocker's block list. | 545 | /* Remove waiter from blocker's block list. |
488 | * When blocker ends up pointing to itself then the list is empty. | 546 | * When blocker ends up pointing to itself then the list is empty. |
547 | * | ||
548 | * Must be called with blocked_lock_lock held. | ||
489 | */ | 549 | */ |
490 | static void __locks_delete_block(struct file_lock *waiter) | 550 | static void __locks_delete_block(struct file_lock *waiter) |
491 | { | 551 | { |
552 | locks_delete_global_blocked(waiter); | ||
492 | list_del_init(&waiter->fl_block); | 553 | list_del_init(&waiter->fl_block); |
493 | list_del_init(&waiter->fl_link); | ||
494 | waiter->fl_next = NULL; | 554 | waiter->fl_next = NULL; |
495 | } | 555 | } |
496 | 556 | ||
497 | /* | 557 | static void locks_delete_block(struct file_lock *waiter) |
498 | */ | ||
499 | void locks_delete_block(struct file_lock *waiter) | ||
500 | { | 558 | { |
501 | lock_flocks(); | 559 | spin_lock(&blocked_lock_lock); |
502 | __locks_delete_block(waiter); | 560 | __locks_delete_block(waiter); |
503 | unlock_flocks(); | 561 | spin_unlock(&blocked_lock_lock); |
504 | } | 562 | } |
505 | EXPORT_SYMBOL(locks_delete_block); | ||
506 | 563 | ||
507 | /* Insert waiter into blocker's block list. | 564 | /* Insert waiter into blocker's block list. |
508 | * We use a circular list so that processes can be easily woken up in | 565 | * We use a circular list so that processes can be easily woken up in |
509 | * the order they blocked. The documentation doesn't require this but | 566 | * the order they blocked. The documentation doesn't require this but |
510 | * it seems like the reasonable thing to do. | 567 | * it seems like the reasonable thing to do. |
568 | * | ||
569 | * Must be called with both the i_lock and blocked_lock_lock held. The fl_block | ||
570 | * list itself is protected by the file_lock_list, but by ensuring that the | ||
571 | * i_lock is also held on insertions we can avoid taking the blocked_lock_lock | ||
572 | * in some cases when we see that the fl_block list is empty. | ||
511 | */ | 573 | */ |
512 | static void locks_insert_block(struct file_lock *blocker, | 574 | static void __locks_insert_block(struct file_lock *blocker, |
513 | struct file_lock *waiter) | 575 | struct file_lock *waiter) |
514 | { | 576 | { |
515 | BUG_ON(!list_empty(&waiter->fl_block)); | 577 | BUG_ON(!list_empty(&waiter->fl_block)); |
516 | list_add_tail(&waiter->fl_block, &blocker->fl_block); | ||
517 | waiter->fl_next = blocker; | 578 | waiter->fl_next = blocker; |
579 | list_add_tail(&waiter->fl_block, &blocker->fl_block); | ||
518 | if (IS_POSIX(blocker)) | 580 | if (IS_POSIX(blocker)) |
519 | list_add(&waiter->fl_link, &blocked_list); | 581 | locks_insert_global_blocked(waiter); |
520 | } | 582 | } |
521 | 583 | ||
522 | /* Wake up processes blocked waiting for blocker. | 584 | /* Must be called with i_lock held. */ |
523 | * If told to wait then schedule the processes until the block list | 585 | static void locks_insert_block(struct file_lock *blocker, |
524 | * is empty, otherwise empty the block list ourselves. | 586 | struct file_lock *waiter) |
587 | { | ||
588 | spin_lock(&blocked_lock_lock); | ||
589 | __locks_insert_block(blocker, waiter); | ||
590 | spin_unlock(&blocked_lock_lock); | ||
591 | } | ||
592 | |||
593 | /* | ||
594 | * Wake up processes blocked waiting for blocker. | ||
595 | * | ||
596 | * Must be called with the inode->i_lock held! | ||
525 | */ | 597 | */ |
526 | static void locks_wake_up_blocks(struct file_lock *blocker) | 598 | static void locks_wake_up_blocks(struct file_lock *blocker) |
527 | { | 599 | { |
600 | /* | ||
601 | * Avoid taking global lock if list is empty. This is safe since new | ||
602 | * blocked requests are only added to the list under the i_lock, and | ||
603 | * the i_lock is always held here. Note that removal from the fl_block | ||
604 | * list does not require the i_lock, so we must recheck list_empty() | ||
605 | * after acquiring the blocked_lock_lock. | ||
606 | */ | ||
607 | if (list_empty(&blocker->fl_block)) | ||
608 | return; | ||
609 | |||
610 | spin_lock(&blocked_lock_lock); | ||
528 | while (!list_empty(&blocker->fl_block)) { | 611 | while (!list_empty(&blocker->fl_block)) { |
529 | struct file_lock *waiter; | 612 | struct file_lock *waiter; |
530 | 613 | ||
@@ -536,20 +619,23 @@ static void locks_wake_up_blocks(struct file_lock *blocker) | |||
536 | else | 619 | else |
537 | wake_up(&waiter->fl_wait); | 620 | wake_up(&waiter->fl_wait); |
538 | } | 621 | } |
622 | spin_unlock(&blocked_lock_lock); | ||
539 | } | 623 | } |
540 | 624 | ||
541 | /* Insert file lock fl into an inode's lock list at the position indicated | 625 | /* Insert file lock fl into an inode's lock list at the position indicated |
542 | * by pos. At the same time add the lock to the global file lock list. | 626 | * by pos. At the same time add the lock to the global file lock list. |
627 | * | ||
628 | * Must be called with the i_lock held! | ||
543 | */ | 629 | */ |
544 | static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) | 630 | static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) |
545 | { | 631 | { |
546 | list_add(&fl->fl_link, &file_lock_list); | ||
547 | |||
548 | fl->fl_nspid = get_pid(task_tgid(current)); | 632 | fl->fl_nspid = get_pid(task_tgid(current)); |
549 | 633 | ||
550 | /* insert into file's list */ | 634 | /* insert into file's list */ |
551 | fl->fl_next = *pos; | 635 | fl->fl_next = *pos; |
552 | *pos = fl; | 636 | *pos = fl; |
637 | |||
638 | locks_insert_global_locks(fl); | ||
553 | } | 639 | } |
554 | 640 | ||
555 | /* | 641 | /* |
@@ -557,14 +643,17 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) | |||
557 | * Wake up processes that are blocked waiting for this lock, | 643 | * Wake up processes that are blocked waiting for this lock, |
558 | * notify the FS that the lock has been cleared and | 644 | * notify the FS that the lock has been cleared and |
559 | * finally free the lock. | 645 | * finally free the lock. |
646 | * | ||
647 | * Must be called with the i_lock held! | ||
560 | */ | 648 | */ |
561 | static void locks_delete_lock(struct file_lock **thisfl_p) | 649 | static void locks_delete_lock(struct file_lock **thisfl_p) |
562 | { | 650 | { |
563 | struct file_lock *fl = *thisfl_p; | 651 | struct file_lock *fl = *thisfl_p; |
564 | 652 | ||
653 | locks_delete_global_locks(fl); | ||
654 | |||
565 | *thisfl_p = fl->fl_next; | 655 | *thisfl_p = fl->fl_next; |
566 | fl->fl_next = NULL; | 656 | fl->fl_next = NULL; |
567 | list_del_init(&fl->fl_link); | ||
568 | 657 | ||
569 | if (fl->fl_nspid) { | 658 | if (fl->fl_nspid) { |
570 | put_pid(fl->fl_nspid); | 659 | put_pid(fl->fl_nspid); |
@@ -625,8 +714,9 @@ void | |||
625 | posix_test_lock(struct file *filp, struct file_lock *fl) | 714 | posix_test_lock(struct file *filp, struct file_lock *fl) |
626 | { | 715 | { |
627 | struct file_lock *cfl; | 716 | struct file_lock *cfl; |
717 | struct inode *inode = file_inode(filp); | ||
628 | 718 | ||
629 | lock_flocks(); | 719 | spin_lock(&inode->i_lock); |
630 | for (cfl = file_inode(filp)->i_flock; cfl; cfl = cfl->fl_next) { | 720 | for (cfl = file_inode(filp)->i_flock; cfl; cfl = cfl->fl_next) { |
631 | if (!IS_POSIX(cfl)) | 721 | if (!IS_POSIX(cfl)) |
632 | continue; | 722 | continue; |
@@ -639,7 +729,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl) | |||
639 | fl->fl_pid = pid_vnr(cfl->fl_nspid); | 729 | fl->fl_pid = pid_vnr(cfl->fl_nspid); |
640 | } else | 730 | } else |
641 | fl->fl_type = F_UNLCK; | 731 | fl->fl_type = F_UNLCK; |
642 | unlock_flocks(); | 732 | spin_unlock(&inode->i_lock); |
643 | return; | 733 | return; |
644 | } | 734 | } |
645 | EXPORT_SYMBOL(posix_test_lock); | 735 | EXPORT_SYMBOL(posix_test_lock); |
@@ -676,13 +766,14 @@ static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl) | |||
676 | { | 766 | { |
677 | struct file_lock *fl; | 767 | struct file_lock *fl; |
678 | 768 | ||
679 | list_for_each_entry(fl, &blocked_list, fl_link) { | 769 | hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) { |
680 | if (posix_same_owner(fl, block_fl)) | 770 | if (posix_same_owner(fl, block_fl)) |
681 | return fl->fl_next; | 771 | return fl->fl_next; |
682 | } | 772 | } |
683 | return NULL; | 773 | return NULL; |
684 | } | 774 | } |
685 | 775 | ||
776 | /* Must be called with the blocked_lock_lock held! */ | ||
686 | static int posix_locks_deadlock(struct file_lock *caller_fl, | 777 | static int posix_locks_deadlock(struct file_lock *caller_fl, |
687 | struct file_lock *block_fl) | 778 | struct file_lock *block_fl) |
688 | { | 779 | { |
@@ -718,7 +809,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
718 | return -ENOMEM; | 809 | return -ENOMEM; |
719 | } | 810 | } |
720 | 811 | ||
721 | lock_flocks(); | 812 | spin_lock(&inode->i_lock); |
722 | if (request->fl_flags & FL_ACCESS) | 813 | if (request->fl_flags & FL_ACCESS) |
723 | goto find_conflict; | 814 | goto find_conflict; |
724 | 815 | ||
@@ -748,9 +839,9 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
748 | * give it the opportunity to lock the file. | 839 | * give it the opportunity to lock the file. |
749 | */ | 840 | */ |
750 | if (found) { | 841 | if (found) { |
751 | unlock_flocks(); | 842 | spin_unlock(&inode->i_lock); |
752 | cond_resched(); | 843 | cond_resched(); |
753 | lock_flocks(); | 844 | spin_lock(&inode->i_lock); |
754 | } | 845 | } |
755 | 846 | ||
756 | find_conflict: | 847 | find_conflict: |
@@ -777,7 +868,7 @@ find_conflict: | |||
777 | error = 0; | 868 | error = 0; |
778 | 869 | ||
779 | out: | 870 | out: |
780 | unlock_flocks(); | 871 | spin_unlock(&inode->i_lock); |
781 | if (new_fl) | 872 | if (new_fl) |
782 | locks_free_lock(new_fl); | 873 | locks_free_lock(new_fl); |
783 | return error; | 874 | return error; |
@@ -791,7 +882,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
791 | struct file_lock *left = NULL; | 882 | struct file_lock *left = NULL; |
792 | struct file_lock *right = NULL; | 883 | struct file_lock *right = NULL; |
793 | struct file_lock **before; | 884 | struct file_lock **before; |
794 | int error, added = 0; | 885 | int error; |
886 | bool added = false; | ||
795 | 887 | ||
796 | /* | 888 | /* |
797 | * We may need two file_lock structures for this operation, | 889 | * We may need two file_lock structures for this operation, |
@@ -806,7 +898,12 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
806 | new_fl2 = locks_alloc_lock(); | 898 | new_fl2 = locks_alloc_lock(); |
807 | } | 899 | } |
808 | 900 | ||
809 | lock_flocks(); | 901 | spin_lock(&inode->i_lock); |
902 | /* | ||
903 | * New lock request. Walk all POSIX locks and look for conflicts. If | ||
904 | * there are any, either return error or put the request on the | ||
905 | * blocker's list of waiters and the global blocked_hash. | ||
906 | */ | ||
810 | if (request->fl_type != F_UNLCK) { | 907 | if (request->fl_type != F_UNLCK) { |
811 | for_each_lock(inode, before) { | 908 | for_each_lock(inode, before) { |
812 | fl = *before; | 909 | fl = *before; |
@@ -819,11 +916,17 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
819 | error = -EAGAIN; | 916 | error = -EAGAIN; |
820 | if (!(request->fl_flags & FL_SLEEP)) | 917 | if (!(request->fl_flags & FL_SLEEP)) |
821 | goto out; | 918 | goto out; |
919 | /* | ||
920 | * Deadlock detection and insertion into the blocked | ||
921 | * locks list must be done while holding the same lock! | ||
922 | */ | ||
822 | error = -EDEADLK; | 923 | error = -EDEADLK; |
823 | if (posix_locks_deadlock(request, fl)) | 924 | spin_lock(&blocked_lock_lock); |
824 | goto out; | 925 | if (likely(!posix_locks_deadlock(request, fl))) { |
825 | error = FILE_LOCK_DEFERRED; | 926 | error = FILE_LOCK_DEFERRED; |
826 | locks_insert_block(fl, request); | 927 | __locks_insert_block(fl, request); |
928 | } | ||
929 | spin_unlock(&blocked_lock_lock); | ||
827 | goto out; | 930 | goto out; |
828 | } | 931 | } |
829 | } | 932 | } |
@@ -845,7 +948,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
845 | before = &fl->fl_next; | 948 | before = &fl->fl_next; |
846 | } | 949 | } |
847 | 950 | ||
848 | /* Process locks with this owner. */ | 951 | /* Process locks with this owner. */ |
849 | while ((fl = *before) && posix_same_owner(request, fl)) { | 952 | while ((fl = *before) && posix_same_owner(request, fl)) { |
850 | /* Detect adjacent or overlapping regions (if same lock type) | 953 | /* Detect adjacent or overlapping regions (if same lock type) |
851 | */ | 954 | */ |
@@ -880,7 +983,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
880 | continue; | 983 | continue; |
881 | } | 984 | } |
882 | request = fl; | 985 | request = fl; |
883 | added = 1; | 986 | added = true; |
884 | } | 987 | } |
885 | else { | 988 | else { |
886 | /* Processing for different lock types is a bit | 989 | /* Processing for different lock types is a bit |
@@ -891,7 +994,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
891 | if (fl->fl_start > request->fl_end) | 994 | if (fl->fl_start > request->fl_end) |
892 | break; | 995 | break; |
893 | if (request->fl_type == F_UNLCK) | 996 | if (request->fl_type == F_UNLCK) |
894 | added = 1; | 997 | added = true; |
895 | if (fl->fl_start < request->fl_start) | 998 | if (fl->fl_start < request->fl_start) |
896 | left = fl; | 999 | left = fl; |
897 | /* If the next lock in the list has a higher end | 1000 | /* If the next lock in the list has a higher end |
@@ -921,7 +1024,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
921 | locks_release_private(fl); | 1024 | locks_release_private(fl); |
922 | locks_copy_private(fl, request); | 1025 | locks_copy_private(fl, request); |
923 | request = fl; | 1026 | request = fl; |
924 | added = 1; | 1027 | added = true; |
925 | } | 1028 | } |
926 | } | 1029 | } |
927 | /* Go on to next lock. | 1030 | /* Go on to next lock. |
@@ -931,10 +1034,9 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
931 | } | 1034 | } |
932 | 1035 | ||
933 | /* | 1036 | /* |
934 | * The above code only modifies existing locks in case of | 1037 | * The above code only modifies existing locks in case of merging or |
935 | * merging or replacing. If new lock(s) need to be inserted | 1038 | * replacing. If new lock(s) need to be inserted all modifications are |
936 | * all modifications are done bellow this, so it's safe yet to | 1039 | * done below this, so it's safe yet to bail out. |
937 | * bail out. | ||
938 | */ | 1040 | */ |
939 | error = -ENOLCK; /* "no luck" */ | 1041 | error = -ENOLCK; /* "no luck" */ |
940 | if (right && left == right && !new_fl2) | 1042 | if (right && left == right && !new_fl2) |
@@ -974,7 +1076,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
974 | locks_wake_up_blocks(left); | 1076 | locks_wake_up_blocks(left); |
975 | } | 1077 | } |
976 | out: | 1078 | out: |
977 | unlock_flocks(); | 1079 | spin_unlock(&inode->i_lock); |
978 | /* | 1080 | /* |
979 | * Free any unused locks. | 1081 | * Free any unused locks. |
980 | */ | 1082 | */ |
@@ -1049,14 +1151,14 @@ int locks_mandatory_locked(struct inode *inode) | |||
1049 | /* | 1151 | /* |
1050 | * Search the lock list for this inode for any POSIX locks. | 1152 | * Search the lock list for this inode for any POSIX locks. |
1051 | */ | 1153 | */ |
1052 | lock_flocks(); | 1154 | spin_lock(&inode->i_lock); |
1053 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 1155 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
1054 | if (!IS_POSIX(fl)) | 1156 | if (!IS_POSIX(fl)) |
1055 | continue; | 1157 | continue; |
1056 | if (fl->fl_owner != owner) | 1158 | if (fl->fl_owner != owner) |
1057 | break; | 1159 | break; |
1058 | } | 1160 | } |
1059 | unlock_flocks(); | 1161 | spin_unlock(&inode->i_lock); |
1060 | return fl ? -EAGAIN : 0; | 1162 | return fl ? -EAGAIN : 0; |
1061 | } | 1163 | } |
1062 | 1164 | ||
@@ -1199,7 +1301,7 @@ int __break_lease(struct inode *inode, unsigned int mode) | |||
1199 | if (IS_ERR(new_fl)) | 1301 | if (IS_ERR(new_fl)) |
1200 | return PTR_ERR(new_fl); | 1302 | return PTR_ERR(new_fl); |
1201 | 1303 | ||
1202 | lock_flocks(); | 1304 | spin_lock(&inode->i_lock); |
1203 | 1305 | ||
1204 | time_out_leases(inode); | 1306 | time_out_leases(inode); |
1205 | 1307 | ||
@@ -1249,11 +1351,11 @@ restart: | |||
1249 | break_time++; | 1351 | break_time++; |
1250 | } | 1352 | } |
1251 | locks_insert_block(flock, new_fl); | 1353 | locks_insert_block(flock, new_fl); |
1252 | unlock_flocks(); | 1354 | spin_unlock(&inode->i_lock); |
1253 | error = wait_event_interruptible_timeout(new_fl->fl_wait, | 1355 | error = wait_event_interruptible_timeout(new_fl->fl_wait, |
1254 | !new_fl->fl_next, break_time); | 1356 | !new_fl->fl_next, break_time); |
1255 | lock_flocks(); | 1357 | spin_lock(&inode->i_lock); |
1256 | __locks_delete_block(new_fl); | 1358 | locks_delete_block(new_fl); |
1257 | if (error >= 0) { | 1359 | if (error >= 0) { |
1258 | if (error == 0) | 1360 | if (error == 0) |
1259 | time_out_leases(inode); | 1361 | time_out_leases(inode); |
@@ -1270,7 +1372,7 @@ restart: | |||
1270 | } | 1372 | } |
1271 | 1373 | ||
1272 | out: | 1374 | out: |
1273 | unlock_flocks(); | 1375 | spin_unlock(&inode->i_lock); |
1274 | locks_free_lock(new_fl); | 1376 | locks_free_lock(new_fl); |
1275 | return error; | 1377 | return error; |
1276 | } | 1378 | } |
@@ -1323,9 +1425,10 @@ EXPORT_SYMBOL(lease_get_mtime); | |||
1323 | int fcntl_getlease(struct file *filp) | 1425 | int fcntl_getlease(struct file *filp) |
1324 | { | 1426 | { |
1325 | struct file_lock *fl; | 1427 | struct file_lock *fl; |
1428 | struct inode *inode = file_inode(filp); | ||
1326 | int type = F_UNLCK; | 1429 | int type = F_UNLCK; |
1327 | 1430 | ||
1328 | lock_flocks(); | 1431 | spin_lock(&inode->i_lock); |
1329 | time_out_leases(file_inode(filp)); | 1432 | time_out_leases(file_inode(filp)); |
1330 | for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl); | 1433 | for (fl = file_inode(filp)->i_flock; fl && IS_LEASE(fl); |
1331 | fl = fl->fl_next) { | 1434 | fl = fl->fl_next) { |
@@ -1334,11 +1437,11 @@ int fcntl_getlease(struct file *filp) | |||
1334 | break; | 1437 | break; |
1335 | } | 1438 | } |
1336 | } | 1439 | } |
1337 | unlock_flocks(); | 1440 | spin_unlock(&inode->i_lock); |
1338 | return type; | 1441 | return type; |
1339 | } | 1442 | } |
1340 | 1443 | ||
1341 | int generic_add_lease(struct file *filp, long arg, struct file_lock **flp) | 1444 | static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp) |
1342 | { | 1445 | { |
1343 | struct file_lock *fl, **before, **my_before = NULL, *lease; | 1446 | struct file_lock *fl, **before, **my_before = NULL, *lease; |
1344 | struct dentry *dentry = filp->f_path.dentry; | 1447 | struct dentry *dentry = filp->f_path.dentry; |
@@ -1403,7 +1506,7 @@ out: | |||
1403 | return error; | 1506 | return error; |
1404 | } | 1507 | } |
1405 | 1508 | ||
1406 | int generic_delete_lease(struct file *filp, struct file_lock **flp) | 1509 | static int generic_delete_lease(struct file *filp, struct file_lock **flp) |
1407 | { | 1510 | { |
1408 | struct file_lock *fl, **before; | 1511 | struct file_lock *fl, **before; |
1409 | struct dentry *dentry = filp->f_path.dentry; | 1512 | struct dentry *dentry = filp->f_path.dentry; |
@@ -1428,7 +1531,7 @@ int generic_delete_lease(struct file *filp, struct file_lock **flp) | |||
1428 | * The (input) flp->fl_lmops->lm_break function is required | 1531 | * The (input) flp->fl_lmops->lm_break function is required |
1429 | * by break_lease(). | 1532 | * by break_lease(). |
1430 | * | 1533 | * |
1431 | * Called with file_lock_lock held. | 1534 | * Called with inode->i_lock held. |
1432 | */ | 1535 | */ |
1433 | int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | 1536 | int generic_setlease(struct file *filp, long arg, struct file_lock **flp) |
1434 | { | 1537 | { |
@@ -1497,11 +1600,12 @@ static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease) | |||
1497 | 1600 | ||
1498 | int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) | 1601 | int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) |
1499 | { | 1602 | { |
1603 | struct inode *inode = file_inode(filp); | ||
1500 | int error; | 1604 | int error; |
1501 | 1605 | ||
1502 | lock_flocks(); | 1606 | spin_lock(&inode->i_lock); |
1503 | error = __vfs_setlease(filp, arg, lease); | 1607 | error = __vfs_setlease(filp, arg, lease); |
1504 | unlock_flocks(); | 1608 | spin_unlock(&inode->i_lock); |
1505 | 1609 | ||
1506 | return error; | 1610 | return error; |
1507 | } | 1611 | } |
@@ -1519,6 +1623,7 @@ static int do_fcntl_delete_lease(struct file *filp) | |||
1519 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | 1623 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) |
1520 | { | 1624 | { |
1521 | struct file_lock *fl, *ret; | 1625 | struct file_lock *fl, *ret; |
1626 | struct inode *inode = file_inode(filp); | ||
1522 | struct fasync_struct *new; | 1627 | struct fasync_struct *new; |
1523 | int error; | 1628 | int error; |
1524 | 1629 | ||
@@ -1532,10 +1637,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1532 | return -ENOMEM; | 1637 | return -ENOMEM; |
1533 | } | 1638 | } |
1534 | ret = fl; | 1639 | ret = fl; |
1535 | lock_flocks(); | 1640 | spin_lock(&inode->i_lock); |
1536 | error = __vfs_setlease(filp, arg, &ret); | 1641 | error = __vfs_setlease(filp, arg, &ret); |
1537 | if (error) { | 1642 | if (error) { |
1538 | unlock_flocks(); | 1643 | spin_unlock(&inode->i_lock); |
1539 | locks_free_lock(fl); | 1644 | locks_free_lock(fl); |
1540 | goto out_free_fasync; | 1645 | goto out_free_fasync; |
1541 | } | 1646 | } |
@@ -1552,7 +1657,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | |||
1552 | new = NULL; | 1657 | new = NULL; |
1553 | 1658 | ||
1554 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); | 1659 | error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); |
1555 | unlock_flocks(); | 1660 | spin_unlock(&inode->i_lock); |
1556 | 1661 | ||
1557 | out_free_fasync: | 1662 | out_free_fasync: |
1558 | if (new) | 1663 | if (new) |
@@ -2076,7 +2181,7 @@ void locks_remove_flock(struct file *filp) | |||
2076 | fl.fl_ops->fl_release_private(&fl); | 2181 | fl.fl_ops->fl_release_private(&fl); |
2077 | } | 2182 | } |
2078 | 2183 | ||
2079 | lock_flocks(); | 2184 | spin_lock(&inode->i_lock); |
2080 | before = &inode->i_flock; | 2185 | before = &inode->i_flock; |
2081 | 2186 | ||
2082 | while ((fl = *before) != NULL) { | 2187 | while ((fl = *before) != NULL) { |
@@ -2094,30 +2199,28 @@ void locks_remove_flock(struct file *filp) | |||
2094 | } | 2199 | } |
2095 | before = &fl->fl_next; | 2200 | before = &fl->fl_next; |
2096 | } | 2201 | } |
2097 | unlock_flocks(); | 2202 | spin_unlock(&inode->i_lock); |
2098 | } | 2203 | } |
2099 | 2204 | ||
2100 | /** | 2205 | /** |
2101 | * posix_unblock_lock - stop waiting for a file lock | 2206 | * posix_unblock_lock - stop waiting for a file lock |
2102 | * @filp: how the file was opened | ||
2103 | * @waiter: the lock which was waiting | 2207 | * @waiter: the lock which was waiting |
2104 | * | 2208 | * |
2105 | * lockd needs to block waiting for locks. | 2209 | * lockd needs to block waiting for locks. |
2106 | */ | 2210 | */ |
2107 | int | 2211 | int |
2108 | posix_unblock_lock(struct file *filp, struct file_lock *waiter) | 2212 | posix_unblock_lock(struct file_lock *waiter) |
2109 | { | 2213 | { |
2110 | int status = 0; | 2214 | int status = 0; |
2111 | 2215 | ||
2112 | lock_flocks(); | 2216 | spin_lock(&blocked_lock_lock); |
2113 | if (waiter->fl_next) | 2217 | if (waiter->fl_next) |
2114 | __locks_delete_block(waiter); | 2218 | __locks_delete_block(waiter); |
2115 | else | 2219 | else |
2116 | status = -ENOENT; | 2220 | status = -ENOENT; |
2117 | unlock_flocks(); | 2221 | spin_unlock(&blocked_lock_lock); |
2118 | return status; | 2222 | return status; |
2119 | } | 2223 | } |
2120 | |||
2121 | EXPORT_SYMBOL(posix_unblock_lock); | 2224 | EXPORT_SYMBOL(posix_unblock_lock); |
2122 | 2225 | ||
2123 | /** | 2226 | /** |
@@ -2215,7 +2318,7 @@ static int locks_show(struct seq_file *f, void *v) | |||
2215 | { | 2318 | { |
2216 | struct file_lock *fl, *bfl; | 2319 | struct file_lock *fl, *bfl; |
2217 | 2320 | ||
2218 | fl = list_entry(v, struct file_lock, fl_link); | 2321 | fl = hlist_entry(v, struct file_lock, fl_link); |
2219 | 2322 | ||
2220 | lock_get_status(f, fl, *((loff_t *)f->private), ""); | 2323 | lock_get_status(f, fl, *((loff_t *)f->private), ""); |
2221 | 2324 | ||
@@ -2229,21 +2332,23 @@ static void *locks_start(struct seq_file *f, loff_t *pos) | |||
2229 | { | 2332 | { |
2230 | loff_t *p = f->private; | 2333 | loff_t *p = f->private; |
2231 | 2334 | ||
2232 | lock_flocks(); | 2335 | spin_lock(&file_lock_lock); |
2336 | spin_lock(&blocked_lock_lock); | ||
2233 | *p = (*pos + 1); | 2337 | *p = (*pos + 1); |
2234 | return seq_list_start(&file_lock_list, *pos); | 2338 | return seq_hlist_start(&file_lock_list, *pos); |
2235 | } | 2339 | } |
2236 | 2340 | ||
2237 | static void *locks_next(struct seq_file *f, void *v, loff_t *pos) | 2341 | static void *locks_next(struct seq_file *f, void *v, loff_t *pos) |
2238 | { | 2342 | { |
2239 | loff_t *p = f->private; | 2343 | loff_t *p = f->private; |
2240 | ++*p; | 2344 | ++*p; |
2241 | return seq_list_next(v, &file_lock_list, pos); | 2345 | return seq_hlist_next(v, &file_lock_list, pos); |
2242 | } | 2346 | } |
2243 | 2347 | ||
2244 | static void locks_stop(struct seq_file *f, void *v) | 2348 | static void locks_stop(struct seq_file *f, void *v) |
2245 | { | 2349 | { |
2246 | unlock_flocks(); | 2350 | spin_unlock(&blocked_lock_lock); |
2351 | spin_unlock(&file_lock_lock); | ||
2247 | } | 2352 | } |
2248 | 2353 | ||
2249 | static const struct seq_operations locks_seq_operations = { | 2354 | static const struct seq_operations locks_seq_operations = { |
@@ -2290,7 +2395,8 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len) | |||
2290 | { | 2395 | { |
2291 | struct file_lock *fl; | 2396 | struct file_lock *fl; |
2292 | int result = 1; | 2397 | int result = 1; |
2293 | lock_flocks(); | 2398 | |
2399 | spin_lock(&inode->i_lock); | ||
2294 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 2400 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
2295 | if (IS_POSIX(fl)) { | 2401 | if (IS_POSIX(fl)) { |
2296 | if (fl->fl_type == F_RDLCK) | 2402 | if (fl->fl_type == F_RDLCK) |
@@ -2307,7 +2413,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len) | |||
2307 | result = 0; | 2413 | result = 0; |
2308 | break; | 2414 | break; |
2309 | } | 2415 | } |
2310 | unlock_flocks(); | 2416 | spin_unlock(&inode->i_lock); |
2311 | return result; | 2417 | return result; |
2312 | } | 2418 | } |
2313 | 2419 | ||
@@ -2330,7 +2436,8 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len) | |||
2330 | { | 2436 | { |
2331 | struct file_lock *fl; | 2437 | struct file_lock *fl; |
2332 | int result = 1; | 2438 | int result = 1; |
2333 | lock_flocks(); | 2439 | |
2440 | spin_lock(&inode->i_lock); | ||
2334 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 2441 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
2335 | if (IS_POSIX(fl)) { | 2442 | if (IS_POSIX(fl)) { |
2336 | if ((fl->fl_end < start) || (fl->fl_start > (start + len))) | 2443 | if ((fl->fl_end < start) || (fl->fl_start > (start + len))) |
@@ -2345,7 +2452,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len) | |||
2345 | result = 0; | 2452 | result = 0; |
2346 | break; | 2453 | break; |
2347 | } | 2454 | } |
2348 | unlock_flocks(); | 2455 | spin_unlock(&inode->i_lock); |
2349 | return result; | 2456 | return result; |
2350 | } | 2457 | } |
2351 | 2458 | ||
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 08c442902fcd..dfaf6fa9b7b5 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -93,7 +93,7 @@ static int minix_readdir(struct file *file, struct dir_context *ctx) | |||
93 | unsigned offset; | 93 | unsigned offset; |
94 | unsigned long n; | 94 | unsigned long n; |
95 | 95 | ||
96 | ctx->pos = pos = (pos + chunk_size-1) & ~(chunk_size-1); | 96 | ctx->pos = pos = ALIGN(pos, chunk_size); |
97 | if (pos >= inode->i_size) | 97 | if (pos >= inode->i_size) |
98 | return 0; | 98 | return 0; |
99 | 99 | ||
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 0db73d9dd668..cd950e2331b6 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -54,6 +54,18 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, umode_t mode, | |||
54 | return error; | 54 | return error; |
55 | } | 55 | } |
56 | 56 | ||
57 | static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
58 | { | ||
59 | int error; | ||
60 | struct inode *inode = minix_new_inode(dir, mode, &error); | ||
61 | if (inode) { | ||
62 | minix_set_inode(inode, 0); | ||
63 | mark_inode_dirty(inode); | ||
64 | d_tmpfile(dentry, inode); | ||
65 | } | ||
66 | return error; | ||
67 | } | ||
68 | |||
57 | static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 69 | static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
58 | bool excl) | 70 | bool excl) |
59 | { | 71 | { |
@@ -254,4 +266,5 @@ const struct inode_operations minix_dir_inode_operations = { | |||
254 | .mknod = minix_mknod, | 266 | .mknod = minix_mknod, |
255 | .rename = minix_rename, | 267 | .rename = minix_rename, |
256 | .getattr = minix_getattr, | 268 | .getattr = minix_getattr, |
269 | .tmpfile = minix_tmpfile, | ||
257 | }; | 270 | }; |
diff --git a/fs/namei.c b/fs/namei.c index 9ed9361223c0..b2beee7a733f 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1352,7 +1352,7 @@ static int lookup_fast(struct nameidata *nd, | |||
1352 | */ | 1352 | */ |
1353 | if (nd->flags & LOOKUP_RCU) { | 1353 | if (nd->flags & LOOKUP_RCU) { |
1354 | unsigned seq; | 1354 | unsigned seq; |
1355 | dentry = __d_lookup_rcu(parent, &nd->last, &seq, nd->inode); | 1355 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); |
1356 | if (!dentry) | 1356 | if (!dentry) |
1357 | goto unlazy; | 1357 | goto unlazy; |
1358 | 1358 | ||
@@ -1787,8 +1787,7 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1787 | struct dentry *parent = nd->path.dentry; | 1787 | struct dentry *parent = nd->path.dentry; |
1788 | nd->flags &= ~LOOKUP_JUMPED; | 1788 | nd->flags &= ~LOOKUP_JUMPED; |
1789 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { | 1789 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { |
1790 | err = parent->d_op->d_hash(parent, nd->inode, | 1790 | err = parent->d_op->d_hash(parent, &this); |
1791 | &this); | ||
1792 | if (err < 0) | 1791 | if (err < 0) |
1793 | break; | 1792 | break; |
1794 | } | 1793 | } |
@@ -2121,7 +2120,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | |||
2121 | * to use its own hash.. | 2120 | * to use its own hash.. |
2122 | */ | 2121 | */ |
2123 | if (base->d_flags & DCACHE_OP_HASH) { | 2122 | if (base->d_flags & DCACHE_OP_HASH) { |
2124 | int err = base->d_op->d_hash(base, base->d_inode, &this); | 2123 | int err = base->d_op->d_hash(base, &this); |
2125 | if (err < 0) | 2124 | if (err < 0) |
2126 | return ERR_PTR(err); | 2125 | return ERR_PTR(err); |
2127 | } | 2126 | } |
@@ -2690,28 +2689,10 @@ static int do_last(struct nameidata *nd, struct path *path, | |||
2690 | nd->flags &= ~LOOKUP_PARENT; | 2689 | nd->flags &= ~LOOKUP_PARENT; |
2691 | nd->flags |= op->intent; | 2690 | nd->flags |= op->intent; |
2692 | 2691 | ||
2693 | switch (nd->last_type) { | 2692 | if (nd->last_type != LAST_NORM) { |
2694 | case LAST_DOTDOT: | ||
2695 | case LAST_DOT: | ||
2696 | error = handle_dots(nd, nd->last_type); | 2693 | error = handle_dots(nd, nd->last_type); |
2697 | if (error) | 2694 | if (error) |
2698 | return error; | 2695 | return error; |
2699 | /* fallthrough */ | ||
2700 | case LAST_ROOT: | ||
2701 | error = complete_walk(nd); | ||
2702 | if (error) | ||
2703 | return error; | ||
2704 | audit_inode(name, nd->path.dentry, 0); | ||
2705 | if (open_flag & O_CREAT) { | ||
2706 | error = -EISDIR; | ||
2707 | goto out; | ||
2708 | } | ||
2709 | goto finish_open; | ||
2710 | case LAST_BIND: | ||
2711 | error = complete_walk(nd); | ||
2712 | if (error) | ||
2713 | return error; | ||
2714 | audit_inode(name, dir, 0); | ||
2715 | goto finish_open; | 2696 | goto finish_open; |
2716 | } | 2697 | } |
2717 | 2698 | ||
@@ -2841,19 +2822,19 @@ finish_lookup: | |||
2841 | } | 2822 | } |
2842 | nd->inode = inode; | 2823 | nd->inode = inode; |
2843 | /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ | 2824 | /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ |
2825 | finish_open: | ||
2844 | error = complete_walk(nd); | 2826 | error = complete_walk(nd); |
2845 | if (error) { | 2827 | if (error) { |
2846 | path_put(&save_parent); | 2828 | path_put(&save_parent); |
2847 | return error; | 2829 | return error; |
2848 | } | 2830 | } |
2831 | audit_inode(name, nd->path.dentry, 0); | ||
2849 | error = -EISDIR; | 2832 | error = -EISDIR; |
2850 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) | 2833 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) |
2851 | goto out; | 2834 | goto out; |
2852 | error = -ENOTDIR; | 2835 | error = -ENOTDIR; |
2853 | if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) | 2836 | if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) |
2854 | goto out; | 2837 | goto out; |
2855 | audit_inode(name, nd->path.dentry, 0); | ||
2856 | finish_open: | ||
2857 | if (!S_ISREG(nd->inode->i_mode)) | 2838 | if (!S_ISREG(nd->inode->i_mode)) |
2858 | will_truncate = false; | 2839 | will_truncate = false; |
2859 | 2840 | ||
@@ -2920,6 +2901,67 @@ stale_open: | |||
2920 | goto retry_lookup; | 2901 | goto retry_lookup; |
2921 | } | 2902 | } |
2922 | 2903 | ||
2904 | static int do_tmpfile(int dfd, struct filename *pathname, | ||
2905 | struct nameidata *nd, int flags, | ||
2906 | const struct open_flags *op, | ||
2907 | struct file *file, int *opened) | ||
2908 | { | ||
2909 | static const struct qstr name = QSTR_INIT("/", 1); | ||
2910 | struct dentry *dentry, *child; | ||
2911 | struct inode *dir; | ||
2912 | int error = path_lookupat(dfd, pathname->name, | ||
2913 | flags | LOOKUP_DIRECTORY, nd); | ||
2914 | if (unlikely(error)) | ||
2915 | return error; | ||
2916 | error = mnt_want_write(nd->path.mnt); | ||
2917 | if (unlikely(error)) | ||
2918 | goto out; | ||
2919 | /* we want directory to be writable */ | ||
2920 | error = inode_permission(nd->inode, MAY_WRITE | MAY_EXEC); | ||
2921 | if (error) | ||
2922 | goto out2; | ||
2923 | dentry = nd->path.dentry; | ||
2924 | dir = dentry->d_inode; | ||
2925 | if (!dir->i_op->tmpfile) { | ||
2926 | error = -EOPNOTSUPP; | ||
2927 | goto out2; | ||
2928 | } | ||
2929 | child = d_alloc(dentry, &name); | ||
2930 | if (unlikely(!child)) { | ||
2931 | error = -ENOMEM; | ||
2932 | goto out2; | ||
2933 | } | ||
2934 | nd->flags &= ~LOOKUP_DIRECTORY; | ||
2935 | nd->flags |= op->intent; | ||
2936 | dput(nd->path.dentry); | ||
2937 | nd->path.dentry = child; | ||
2938 | error = dir->i_op->tmpfile(dir, nd->path.dentry, op->mode); | ||
2939 | if (error) | ||
2940 | goto out2; | ||
2941 | audit_inode(pathname, nd->path.dentry, 0); | ||
2942 | error = may_open(&nd->path, op->acc_mode, op->open_flag); | ||
2943 | if (error) | ||
2944 | goto out2; | ||
2945 | file->f_path.mnt = nd->path.mnt; | ||
2946 | error = finish_open(file, nd->path.dentry, NULL, opened); | ||
2947 | if (error) | ||
2948 | goto out2; | ||
2949 | error = open_check_o_direct(file); | ||
2950 | if (error) { | ||
2951 | fput(file); | ||
2952 | } else if (!(op->open_flag & O_EXCL)) { | ||
2953 | struct inode *inode = file_inode(file); | ||
2954 | spin_lock(&inode->i_lock); | ||
2955 | inode->i_state |= I_LINKABLE; | ||
2956 | spin_unlock(&inode->i_lock); | ||
2957 | } | ||
2958 | out2: | ||
2959 | mnt_drop_write(nd->path.mnt); | ||
2960 | out: | ||
2961 | path_put(&nd->path); | ||
2962 | return error; | ||
2963 | } | ||
2964 | |||
2923 | static struct file *path_openat(int dfd, struct filename *pathname, | 2965 | static struct file *path_openat(int dfd, struct filename *pathname, |
2924 | struct nameidata *nd, const struct open_flags *op, int flags) | 2966 | struct nameidata *nd, const struct open_flags *op, int flags) |
2925 | { | 2967 | { |
@@ -2935,6 +2977,11 @@ static struct file *path_openat(int dfd, struct filename *pathname, | |||
2935 | 2977 | ||
2936 | file->f_flags = op->open_flag; | 2978 | file->f_flags = op->open_flag; |
2937 | 2979 | ||
2980 | if (unlikely(file->f_flags & O_TMPFILE)) { | ||
2981 | error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); | ||
2982 | goto out; | ||
2983 | } | ||
2984 | |||
2938 | error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); | 2985 | error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); |
2939 | if (unlikely(error)) | 2986 | if (unlikely(error)) |
2940 | goto out; | 2987 | goto out; |
@@ -2987,9 +3034,10 @@ out: | |||
2987 | } | 3034 | } |
2988 | 3035 | ||
2989 | struct file *do_filp_open(int dfd, struct filename *pathname, | 3036 | struct file *do_filp_open(int dfd, struct filename *pathname, |
2990 | const struct open_flags *op, int flags) | 3037 | const struct open_flags *op) |
2991 | { | 3038 | { |
2992 | struct nameidata nd; | 3039 | struct nameidata nd; |
3040 | int flags = op->lookup_flags; | ||
2993 | struct file *filp; | 3041 | struct file *filp; |
2994 | 3042 | ||
2995 | filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU); | 3043 | filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU); |
@@ -3001,17 +3049,16 @@ struct file *do_filp_open(int dfd, struct filename *pathname, | |||
3001 | } | 3049 | } |
3002 | 3050 | ||
3003 | struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | 3051 | struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, |
3004 | const char *name, const struct open_flags *op, int flags) | 3052 | const char *name, const struct open_flags *op) |
3005 | { | 3053 | { |
3006 | struct nameidata nd; | 3054 | struct nameidata nd; |
3007 | struct file *file; | 3055 | struct file *file; |
3008 | struct filename filename = { .name = name }; | 3056 | struct filename filename = { .name = name }; |
3057 | int flags = op->lookup_flags | LOOKUP_ROOT; | ||
3009 | 3058 | ||
3010 | nd.root.mnt = mnt; | 3059 | nd.root.mnt = mnt; |
3011 | nd.root.dentry = dentry; | 3060 | nd.root.dentry = dentry; |
3012 | 3061 | ||
3013 | flags |= LOOKUP_ROOT; | ||
3014 | |||
3015 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) | 3062 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) |
3016 | return ERR_PTR(-ELOOP); | 3063 | return ERR_PTR(-ELOOP); |
3017 | 3064 | ||
@@ -3586,12 +3633,18 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
3586 | 3633 | ||
3587 | mutex_lock(&inode->i_mutex); | 3634 | mutex_lock(&inode->i_mutex); |
3588 | /* Make sure we don't allow creating hardlink to an unlinked file */ | 3635 | /* Make sure we don't allow creating hardlink to an unlinked file */ |
3589 | if (inode->i_nlink == 0) | 3636 | if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE)) |
3590 | error = -ENOENT; | 3637 | error = -ENOENT; |
3591 | else if (max_links && inode->i_nlink >= max_links) | 3638 | else if (max_links && inode->i_nlink >= max_links) |
3592 | error = -EMLINK; | 3639 | error = -EMLINK; |
3593 | else | 3640 | else |
3594 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 3641 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
3642 | |||
3643 | if (!error && (inode->i_state & I_LINKABLE)) { | ||
3644 | spin_lock(&inode->i_lock); | ||
3645 | inode->i_state &= ~I_LINKABLE; | ||
3646 | spin_unlock(&inode->i_lock); | ||
3647 | } | ||
3595 | mutex_unlock(&inode->i_mutex); | 3648 | mutex_unlock(&inode->i_mutex); |
3596 | if (!error) | 3649 | if (!error) |
3597 | fsnotify_link(dir, inode, new_dentry); | 3650 | fsnotify_link(dir, inode, new_dentry); |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 0e7f00298213..3be047474bfc 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -73,10 +73,8 @@ const struct inode_operations ncp_dir_inode_operations = | |||
73 | * Dentry operations routines | 73 | * Dentry operations routines |
74 | */ | 74 | */ |
75 | static int ncp_lookup_validate(struct dentry *, unsigned int); | 75 | static int ncp_lookup_validate(struct dentry *, unsigned int); |
76 | static int ncp_hash_dentry(const struct dentry *, const struct inode *, | 76 | static int ncp_hash_dentry(const struct dentry *, struct qstr *); |
77 | struct qstr *); | 77 | static int ncp_compare_dentry(const struct dentry *, const struct dentry *, |
78 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, | ||
79 | const struct dentry *, const struct inode *, | ||
80 | unsigned int, const char *, const struct qstr *); | 78 | unsigned int, const char *, const struct qstr *); |
81 | static int ncp_delete_dentry(const struct dentry *); | 79 | static int ncp_delete_dentry(const struct dentry *); |
82 | 80 | ||
@@ -119,11 +117,19 @@ static inline int ncp_case_sensitive(const struct inode *i) | |||
119 | /* | 117 | /* |
120 | * Note: leave the hash unchanged if the directory | 118 | * Note: leave the hash unchanged if the directory |
121 | * is case-sensitive. | 119 | * is case-sensitive. |
120 | * | ||
121 | * Accessing the parent inode can be racy under RCU pathwalking. | ||
122 | * Use ACCESS_ONCE() to make sure we use _one_ particular inode, | ||
123 | * the callers will handle races. | ||
122 | */ | 124 | */ |
123 | static int | 125 | static int |
124 | ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 126 | ncp_hash_dentry(const struct dentry *dentry, struct qstr *this) |
125 | struct qstr *this) | ||
126 | { | 127 | { |
128 | struct inode *inode = ACCESS_ONCE(dentry->d_inode); | ||
129 | |||
130 | if (!inode) | ||
131 | return 0; | ||
132 | |||
127 | if (!ncp_case_sensitive(inode)) { | 133 | if (!ncp_case_sensitive(inode)) { |
128 | struct super_block *sb = dentry->d_sb; | 134 | struct super_block *sb = dentry->d_sb; |
129 | struct nls_table *t; | 135 | struct nls_table *t; |
@@ -140,14 +146,24 @@ ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |||
140 | return 0; | 146 | return 0; |
141 | } | 147 | } |
142 | 148 | ||
149 | /* | ||
150 | * Accessing the parent inode can be racy under RCU pathwalking. | ||
151 | * Use ACCESS_ONCE() to make sure we use _one_ particular inode, | ||
152 | * the callers will handle races. | ||
153 | */ | ||
143 | static int | 154 | static int |
144 | ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 155 | ncp_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
145 | const struct dentry *dentry, const struct inode *inode, | ||
146 | unsigned int len, const char *str, const struct qstr *name) | 156 | unsigned int len, const char *str, const struct qstr *name) |
147 | { | 157 | { |
158 | struct inode *pinode; | ||
159 | |||
148 | if (len != name->len) | 160 | if (len != name->len) |
149 | return 1; | 161 | return 1; |
150 | 162 | ||
163 | pinode = ACCESS_ONCE(parent->d_inode); | ||
164 | if (!pinode) | ||
165 | return 1; | ||
166 | |||
151 | if (ncp_case_sensitive(pinode)) | 167 | if (ncp_case_sensitive(pinode)) |
152 | return strncmp(str, name->name, len); | 168 | return strncmp(str, name->name, len); |
153 | 169 | ||
@@ -660,8 +676,6 @@ end_advance: | |||
660 | ctl.valid = 0; | 676 | ctl.valid = 0; |
661 | if (!ctl.filled && (ctl.fpos == ctx->pos)) { | 677 | if (!ctl.filled && (ctl.fpos == ctx->pos)) { |
662 | if (!ino) | 678 | if (!ino) |
663 | ino = find_inode_number(dentry, &qname); | ||
664 | if (!ino) | ||
665 | ino = iunique(dir->i_sb, 2); | 679 | ino = iunique(dir->i_sb, 2); |
666 | ctl.filled = !dir_emit(ctx, qname.name, qname.len, | 680 | ctl.filled = !dir_emit(ctx, qname.name, qname.len, |
667 | ino, DT_UNKNOWN); | 681 | ino, DT_UNKNOWN); |
@@ -1123,17 +1137,6 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1123 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1137 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1124 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); | 1138 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
1125 | 1139 | ||
1126 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) { | ||
1127 | /* | ||
1128 | * fail with EBUSY if there are still references to this | ||
1129 | * directory. | ||
1130 | */ | ||
1131 | dentry_unhash(new_dentry); | ||
1132 | error = -EBUSY; | ||
1133 | if (!d_unhashed(new_dentry)) | ||
1134 | goto out; | ||
1135 | } | ||
1136 | |||
1137 | ncp_age_dentry(server, old_dentry); | 1140 | ncp_age_dentry(server, old_dentry); |
1138 | ncp_age_dentry(server, new_dentry); | 1141 | ncp_age_dentry(server, new_dentry); |
1139 | 1142 | ||
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 26910c8154da..0765ad12c382 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -891,6 +891,10 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) | |||
891 | if (!server) /* How this could happen? */ | 891 | if (!server) /* How this could happen? */ |
892 | goto out; | 892 | goto out; |
893 | 893 | ||
894 | result = -EPERM; | ||
895 | if (IS_DEADDIR(dentry->d_inode)) | ||
896 | goto out; | ||
897 | |||
894 | /* ageing the dentry to force validation */ | 898 | /* ageing the dentry to force validation */ |
895 | ncp_age_dentry(server, dentry); | 899 | ncp_age_dentry(server, dentry); |
896 | 900 | ||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 57db3244f4d9..7ec4814e298d 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -73,20 +73,20 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ | |||
73 | if (inode->i_flock == NULL) | 73 | if (inode->i_flock == NULL) |
74 | goto out; | 74 | goto out; |
75 | 75 | ||
76 | /* Protect inode->i_flock using the file locks lock */ | 76 | /* Protect inode->i_flock using the i_lock */ |
77 | lock_flocks(); | 77 | spin_lock(&inode->i_lock); |
78 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 78 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
79 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 79 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
80 | continue; | 80 | continue; |
81 | if (nfs_file_open_context(fl->fl_file) != ctx) | 81 | if (nfs_file_open_context(fl->fl_file) != ctx) |
82 | continue; | 82 | continue; |
83 | unlock_flocks(); | 83 | spin_unlock(&inode->i_lock); |
84 | status = nfs4_lock_delegation_recall(fl, state, stateid); | 84 | status = nfs4_lock_delegation_recall(fl, state, stateid); |
85 | if (status < 0) | 85 | if (status < 0) |
86 | goto out; | 86 | goto out; |
87 | lock_flocks(); | 87 | spin_lock(&inode->i_lock); |
88 | } | 88 | } |
89 | unlock_flocks(); | 89 | spin_unlock(&inode->i_lock); |
90 | out: | 90 | out: |
91 | return status; | 91 | return status; |
92 | } | 92 | } |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 1fab140764c4..ff10b4aa534c 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1373,13 +1373,13 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ | |||
1373 | /* Guard against delegation returns and new lock/unlock calls */ | 1373 | /* Guard against delegation returns and new lock/unlock calls */ |
1374 | down_write(&nfsi->rwsem); | 1374 | down_write(&nfsi->rwsem); |
1375 | /* Protect inode->i_flock using the BKL */ | 1375 | /* Protect inode->i_flock using the BKL */ |
1376 | lock_flocks(); | 1376 | spin_lock(&inode->i_lock); |
1377 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { | 1377 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
1378 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 1378 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
1379 | continue; | 1379 | continue; |
1380 | if (nfs_file_open_context(fl->fl_file)->state != state) | 1380 | if (nfs_file_open_context(fl->fl_file)->state != state) |
1381 | continue; | 1381 | continue; |
1382 | unlock_flocks(); | 1382 | spin_unlock(&inode->i_lock); |
1383 | status = ops->recover_lock(state, fl); | 1383 | status = ops->recover_lock(state, fl); |
1384 | switch (status) { | 1384 | switch (status) { |
1385 | case 0: | 1385 | case 0: |
@@ -1406,9 +1406,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_ | |||
1406 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | 1406 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ |
1407 | status = 0; | 1407 | status = 0; |
1408 | } | 1408 | } |
1409 | lock_flocks(); | 1409 | spin_lock(&inode->i_lock); |
1410 | } | 1410 | } |
1411 | unlock_flocks(); | 1411 | spin_unlock(&inode->i_lock); |
1412 | out: | 1412 | out: |
1413 | up_write(&nfsi->rwsem); | 1413 | up_write(&nfsi->rwsem); |
1414 | return status; | 1414 | return status; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 316ec843dec2..f17051838b41 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2645,13 +2645,13 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp) | |||
2645 | 2645 | ||
2646 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); | 2646 | list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); |
2647 | 2647 | ||
2648 | /* only place dl_time is set. protected by lock_flocks*/ | 2648 | /* Only place dl_time is set; protected by i_lock: */ |
2649 | dp->dl_time = get_seconds(); | 2649 | dp->dl_time = get_seconds(); |
2650 | 2650 | ||
2651 | nfsd4_cb_recall(dp); | 2651 | nfsd4_cb_recall(dp); |
2652 | } | 2652 | } |
2653 | 2653 | ||
2654 | /* Called from break_lease() with lock_flocks() held. */ | 2654 | /* Called from break_lease() with i_lock held. */ |
2655 | static void nfsd_break_deleg_cb(struct file_lock *fl) | 2655 | static void nfsd_break_deleg_cb(struct file_lock *fl) |
2656 | { | 2656 | { |
2657 | struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; | 2657 | struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; |
@@ -4520,7 +4520,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) | |||
4520 | struct inode *inode = filp->fi_inode; | 4520 | struct inode *inode = filp->fi_inode; |
4521 | int status = 0; | 4521 | int status = 0; |
4522 | 4522 | ||
4523 | lock_flocks(); | 4523 | spin_lock(&inode->i_lock); |
4524 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { | 4524 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { |
4525 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) { | 4525 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) { |
4526 | status = 1; | 4526 | status = 1; |
@@ -4528,7 +4528,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) | |||
4528 | } | 4528 | } |
4529 | } | 4529 | } |
4530 | out: | 4530 | out: |
4531 | unlock_flocks(); | 4531 | spin_unlock(&inode->i_lock); |
4532 | return status; | 4532 | return status; |
4533 | } | 4533 | } |
4534 | 4534 | ||
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 6c80083a984f..1ea52f7c031f 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -399,9 +399,6 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
399 | wake_up(&group->fanotify_data.access_waitq); | 399 | wake_up(&group->fanotify_data.access_waitq); |
400 | #endif | 400 | #endif |
401 | 401 | ||
402 | if (file->f_flags & FASYNC) | ||
403 | fsnotify_fasync(-1, file, 0); | ||
404 | |||
405 | /* matches the fanotify_init->fsnotify_alloc_group */ | 402 | /* matches the fanotify_init->fsnotify_alloc_group */ |
406 | fsnotify_destroy_group(group); | 403 | fsnotify_destroy_group(group); |
407 | 404 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8a38714f1d92..41000f223ca4 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2646,17 +2646,7 @@ static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int whence) | |||
2646 | goto out; | 2646 | goto out; |
2647 | } | 2647 | } |
2648 | 2648 | ||
2649 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 2649 | offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); |
2650 | ret = -EINVAL; | ||
2651 | if (!ret && offset > inode->i_sb->s_maxbytes) | ||
2652 | ret = -EINVAL; | ||
2653 | if (ret) | ||
2654 | goto out; | ||
2655 | |||
2656 | if (offset != file->f_pos) { | ||
2657 | file->f_pos = offset; | ||
2658 | file->f_version = 0; | ||
2659 | } | ||
2660 | 2650 | ||
2661 | out: | 2651 | out: |
2662 | mutex_unlock(&inode->i_mutex); | 2652 | mutex_unlock(&inode->i_mutex); |
@@ -840,11 +840,15 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
840 | if (flags & __O_SYNC) | 840 | if (flags & __O_SYNC) |
841 | flags |= O_DSYNC; | 841 | flags |= O_DSYNC; |
842 | 842 | ||
843 | /* | 843 | if (flags & O_TMPFILE) { |
844 | * If we have O_PATH in the open flag. Then we | 844 | if (!(flags & O_CREAT)) |
845 | * cannot have anything other than the below set of flags | 845 | return -EINVAL; |
846 | */ | 846 | acc_mode = MAY_OPEN | ACC_MODE(flags); |
847 | if (flags & O_PATH) { | 847 | } else if (flags & O_PATH) { |
848 | /* | ||
849 | * If we have O_PATH in the open flag. Then we | ||
850 | * cannot have anything other than the below set of flags | ||
851 | */ | ||
848 | flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; | 852 | flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; |
849 | acc_mode = 0; | 853 | acc_mode = 0; |
850 | } else { | 854 | } else { |
@@ -876,7 +880,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
876 | lookup_flags |= LOOKUP_DIRECTORY; | 880 | lookup_flags |= LOOKUP_DIRECTORY; |
877 | if (!(flags & O_NOFOLLOW)) | 881 | if (!(flags & O_NOFOLLOW)) |
878 | lookup_flags |= LOOKUP_FOLLOW; | 882 | lookup_flags |= LOOKUP_FOLLOW; |
879 | return lookup_flags; | 883 | op->lookup_flags = lookup_flags; |
884 | return 0; | ||
880 | } | 885 | } |
881 | 886 | ||
882 | /** | 887 | /** |
@@ -893,8 +898,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
893 | struct file *file_open_name(struct filename *name, int flags, umode_t mode) | 898 | struct file *file_open_name(struct filename *name, int flags, umode_t mode) |
894 | { | 899 | { |
895 | struct open_flags op; | 900 | struct open_flags op; |
896 | int lookup = build_open_flags(flags, mode, &op); | 901 | int err = build_open_flags(flags, mode, &op); |
897 | return do_filp_open(AT_FDCWD, name, &op, lookup); | 902 | return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op); |
898 | } | 903 | } |
899 | 904 | ||
900 | /** | 905 | /** |
@@ -919,37 +924,43 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
919 | const char *filename, int flags) | 924 | const char *filename, int flags) |
920 | { | 925 | { |
921 | struct open_flags op; | 926 | struct open_flags op; |
922 | int lookup = build_open_flags(flags, 0, &op); | 927 | int err = build_open_flags(flags, 0, &op); |
928 | if (err) | ||
929 | return ERR_PTR(err); | ||
923 | if (flags & O_CREAT) | 930 | if (flags & O_CREAT) |
924 | return ERR_PTR(-EINVAL); | 931 | return ERR_PTR(-EINVAL); |
925 | if (!filename && (flags & O_DIRECTORY)) | 932 | if (!filename && (flags & O_DIRECTORY)) |
926 | if (!dentry->d_inode->i_op->lookup) | 933 | if (!dentry->d_inode->i_op->lookup) |
927 | return ERR_PTR(-ENOTDIR); | 934 | return ERR_PTR(-ENOTDIR); |
928 | return do_file_open_root(dentry, mnt, filename, &op, lookup); | 935 | return do_file_open_root(dentry, mnt, filename, &op); |
929 | } | 936 | } |
930 | EXPORT_SYMBOL(file_open_root); | 937 | EXPORT_SYMBOL(file_open_root); |
931 | 938 | ||
932 | long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | 939 | long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) |
933 | { | 940 | { |
934 | struct open_flags op; | 941 | struct open_flags op; |
935 | int lookup = build_open_flags(flags, mode, &op); | 942 | int fd = build_open_flags(flags, mode, &op); |
936 | struct filename *tmp = getname(filename); | 943 | struct filename *tmp; |
937 | int fd = PTR_ERR(tmp); | 944 | |
938 | 945 | if (fd) | |
939 | if (!IS_ERR(tmp)) { | 946 | return fd; |
940 | fd = get_unused_fd_flags(flags); | 947 | |
941 | if (fd >= 0) { | 948 | tmp = getname(filename); |
942 | struct file *f = do_filp_open(dfd, tmp, &op, lookup); | 949 | if (IS_ERR(tmp)) |
943 | if (IS_ERR(f)) { | 950 | return PTR_ERR(tmp); |
944 | put_unused_fd(fd); | 951 | |
945 | fd = PTR_ERR(f); | 952 | fd = get_unused_fd_flags(flags); |
946 | } else { | 953 | if (fd >= 0) { |
947 | fsnotify_open(f); | 954 | struct file *f = do_filp_open(dfd, tmp, &op); |
948 | fd_install(fd, f); | 955 | if (IS_ERR(f)) { |
949 | } | 956 | put_unused_fd(fd); |
957 | fd = PTR_ERR(f); | ||
958 | } else { | ||
959 | fsnotify_open(f); | ||
960 | fd_install(fd, f); | ||
950 | } | 961 | } |
951 | putname(tmp); | ||
952 | } | 962 | } |
963 | putname(tmp); | ||
953 | return fd; | 964 | return fd; |
954 | } | 965 | } |
955 | 966 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index 0016350ad95e..1485e38daaa3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1686,41 +1686,29 @@ bool proc_fill_cache(struct file *file, struct dir_context *ctx, | |||
1686 | instantiate_t instantiate, struct task_struct *task, const void *ptr) | 1686 | instantiate_t instantiate, struct task_struct *task, const void *ptr) |
1687 | { | 1687 | { |
1688 | struct dentry *child, *dir = file->f_path.dentry; | 1688 | struct dentry *child, *dir = file->f_path.dentry; |
1689 | struct qstr qname = QSTR_INIT(name, len); | ||
1689 | struct inode *inode; | 1690 | struct inode *inode; |
1690 | struct qstr qname; | 1691 | unsigned type; |
1691 | ino_t ino = 0; | 1692 | ino_t ino; |
1692 | unsigned type = DT_UNKNOWN; | ||
1693 | 1693 | ||
1694 | qname.name = name; | 1694 | child = d_hash_and_lookup(dir, &qname); |
1695 | qname.len = len; | ||
1696 | qname.hash = full_name_hash(name, len); | ||
1697 | |||
1698 | child = d_lookup(dir, &qname); | ||
1699 | if (!child) { | 1695 | if (!child) { |
1700 | struct dentry *new; | 1696 | child = d_alloc(dir, &qname); |
1701 | new = d_alloc(dir, &qname); | 1697 | if (!child) |
1702 | if (new) { | 1698 | goto end_instantiate; |
1703 | child = instantiate(dir->d_inode, new, task, ptr); | 1699 | if (instantiate(dir->d_inode, child, task, ptr) < 0) { |
1704 | if (child) | 1700 | dput(child); |
1705 | dput(new); | 1701 | goto end_instantiate; |
1706 | else | ||
1707 | child = new; | ||
1708 | } | 1702 | } |
1709 | } | 1703 | } |
1710 | if (!child || IS_ERR(child) || !child->d_inode) | ||
1711 | goto end_instantiate; | ||
1712 | inode = child->d_inode; | 1704 | inode = child->d_inode; |
1713 | if (inode) { | 1705 | ino = inode->i_ino; |
1714 | ino = inode->i_ino; | 1706 | type = inode->i_mode >> 12; |
1715 | type = inode->i_mode >> 12; | ||
1716 | } | ||
1717 | dput(child); | 1707 | dput(child); |
1718 | end_instantiate: | ||
1719 | if (!ino) | ||
1720 | ino = find_inode_number(dir, &qname); | ||
1721 | if (!ino) | ||
1722 | ino = 1; | ||
1723 | return dir_emit(ctx, name, len, ino, type); | 1708 | return dir_emit(ctx, name, len, ino, type); |
1709 | |||
1710 | end_instantiate: | ||
1711 | return dir_emit(ctx, name, len, 1, DT_UNKNOWN); | ||
1724 | } | 1712 | } |
1725 | 1713 | ||
1726 | #ifdef CONFIG_CHECKPOINT_RESTORE | 1714 | #ifdef CONFIG_CHECKPOINT_RESTORE |
@@ -1846,7 +1834,7 @@ struct map_files_info { | |||
1846 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ | 1834 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ |
1847 | }; | 1835 | }; |
1848 | 1836 | ||
1849 | static struct dentry * | 1837 | static int |
1850 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | 1838 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, |
1851 | struct task_struct *task, const void *ptr) | 1839 | struct task_struct *task, const void *ptr) |
1852 | { | 1840 | { |
@@ -1856,7 +1844,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1856 | 1844 | ||
1857 | inode = proc_pid_make_inode(dir->i_sb, task); | 1845 | inode = proc_pid_make_inode(dir->i_sb, task); |
1858 | if (!inode) | 1846 | if (!inode) |
1859 | return ERR_PTR(-ENOENT); | 1847 | return -ENOENT; |
1860 | 1848 | ||
1861 | ei = PROC_I(inode); | 1849 | ei = PROC_I(inode); |
1862 | ei->op.proc_get_link = proc_map_files_get_link; | 1850 | ei->op.proc_get_link = proc_map_files_get_link; |
@@ -1873,7 +1861,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1873 | d_set_d_op(dentry, &tid_map_files_dentry_operations); | 1861 | d_set_d_op(dentry, &tid_map_files_dentry_operations); |
1874 | d_add(dentry, inode); | 1862 | d_add(dentry, inode); |
1875 | 1863 | ||
1876 | return NULL; | 1864 | return 0; |
1877 | } | 1865 | } |
1878 | 1866 | ||
1879 | static struct dentry *proc_map_files_lookup(struct inode *dir, | 1867 | static struct dentry *proc_map_files_lookup(struct inode *dir, |
@@ -1882,23 +1870,23 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, | |||
1882 | unsigned long vm_start, vm_end; | 1870 | unsigned long vm_start, vm_end; |
1883 | struct vm_area_struct *vma; | 1871 | struct vm_area_struct *vma; |
1884 | struct task_struct *task; | 1872 | struct task_struct *task; |
1885 | struct dentry *result; | 1873 | int result; |
1886 | struct mm_struct *mm; | 1874 | struct mm_struct *mm; |
1887 | 1875 | ||
1888 | result = ERR_PTR(-EPERM); | 1876 | result = -EPERM; |
1889 | if (!capable(CAP_SYS_ADMIN)) | 1877 | if (!capable(CAP_SYS_ADMIN)) |
1890 | goto out; | 1878 | goto out; |
1891 | 1879 | ||
1892 | result = ERR_PTR(-ENOENT); | 1880 | result = -ENOENT; |
1893 | task = get_proc_task(dir); | 1881 | task = get_proc_task(dir); |
1894 | if (!task) | 1882 | if (!task) |
1895 | goto out; | 1883 | goto out; |
1896 | 1884 | ||
1897 | result = ERR_PTR(-EACCES); | 1885 | result = -EACCES; |
1898 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | 1886 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
1899 | goto out_put_task; | 1887 | goto out_put_task; |
1900 | 1888 | ||
1901 | result = ERR_PTR(-ENOENT); | 1889 | result = -ENOENT; |
1902 | if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) | 1890 | if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) |
1903 | goto out_put_task; | 1891 | goto out_put_task; |
1904 | 1892 | ||
@@ -1921,7 +1909,7 @@ out_no_vma: | |||
1921 | out_put_task: | 1909 | out_put_task: |
1922 | put_task_struct(task); | 1910 | put_task_struct(task); |
1923 | out: | 1911 | out: |
1924 | return result; | 1912 | return ERR_PTR(result); |
1925 | } | 1913 | } |
1926 | 1914 | ||
1927 | static const struct inode_operations proc_map_files_inode_operations = { | 1915 | static const struct inode_operations proc_map_files_inode_operations = { |
@@ -2135,13 +2123,12 @@ static const struct file_operations proc_timers_operations = { | |||
2135 | }; | 2123 | }; |
2136 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | 2124 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
2137 | 2125 | ||
2138 | static struct dentry *proc_pident_instantiate(struct inode *dir, | 2126 | static int proc_pident_instantiate(struct inode *dir, |
2139 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 2127 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
2140 | { | 2128 | { |
2141 | const struct pid_entry *p = ptr; | 2129 | const struct pid_entry *p = ptr; |
2142 | struct inode *inode; | 2130 | struct inode *inode; |
2143 | struct proc_inode *ei; | 2131 | struct proc_inode *ei; |
2144 | struct dentry *error = ERR_PTR(-ENOENT); | ||
2145 | 2132 | ||
2146 | inode = proc_pid_make_inode(dir->i_sb, task); | 2133 | inode = proc_pid_make_inode(dir->i_sb, task); |
2147 | if (!inode) | 2134 | if (!inode) |
@@ -2160,9 +2147,9 @@ static struct dentry *proc_pident_instantiate(struct inode *dir, | |||
2160 | d_add(dentry, inode); | 2147 | d_add(dentry, inode); |
2161 | /* Close the race of the process dying before we return the dentry */ | 2148 | /* Close the race of the process dying before we return the dentry */ |
2162 | if (pid_revalidate(dentry, 0)) | 2149 | if (pid_revalidate(dentry, 0)) |
2163 | error = NULL; | 2150 | return 0; |
2164 | out: | 2151 | out: |
2165 | return error; | 2152 | return -ENOENT; |
2166 | } | 2153 | } |
2167 | 2154 | ||
2168 | static struct dentry *proc_pident_lookup(struct inode *dir, | 2155 | static struct dentry *proc_pident_lookup(struct inode *dir, |
@@ -2170,11 +2157,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
2170 | const struct pid_entry *ents, | 2157 | const struct pid_entry *ents, |
2171 | unsigned int nents) | 2158 | unsigned int nents) |
2172 | { | 2159 | { |
2173 | struct dentry *error; | 2160 | int error; |
2174 | struct task_struct *task = get_proc_task(dir); | 2161 | struct task_struct *task = get_proc_task(dir); |
2175 | const struct pid_entry *p, *last; | 2162 | const struct pid_entry *p, *last; |
2176 | 2163 | ||
2177 | error = ERR_PTR(-ENOENT); | 2164 | error = -ENOENT; |
2178 | 2165 | ||
2179 | if (!task) | 2166 | if (!task) |
2180 | goto out_no_task; | 2167 | goto out_no_task; |
@@ -2197,7 +2184,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
2197 | out: | 2184 | out: |
2198 | put_task_struct(task); | 2185 | put_task_struct(task); |
2199 | out_no_task: | 2186 | out_no_task: |
2200 | return error; | 2187 | return ERR_PTR(error); |
2201 | } | 2188 | } |
2202 | 2189 | ||
2203 | static int proc_pident_readdir(struct file *file, struct dir_context *ctx, | 2190 | static int proc_pident_readdir(struct file *file, struct dir_context *ctx, |
@@ -2780,11 +2767,10 @@ void proc_flush_task(struct task_struct *task) | |||
2780 | } | 2767 | } |
2781 | } | 2768 | } |
2782 | 2769 | ||
2783 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2770 | static int proc_pid_instantiate(struct inode *dir, |
2784 | struct dentry * dentry, | 2771 | struct dentry * dentry, |
2785 | struct task_struct *task, const void *ptr) | 2772 | struct task_struct *task, const void *ptr) |
2786 | { | 2773 | { |
2787 | struct dentry *error = ERR_PTR(-ENOENT); | ||
2788 | struct inode *inode; | 2774 | struct inode *inode; |
2789 | 2775 | ||
2790 | inode = proc_pid_make_inode(dir->i_sb, task); | 2776 | inode = proc_pid_make_inode(dir->i_sb, task); |
@@ -2804,14 +2790,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, | |||
2804 | d_add(dentry, inode); | 2790 | d_add(dentry, inode); |
2805 | /* Close the race of the process dying before we return the dentry */ | 2791 | /* Close the race of the process dying before we return the dentry */ |
2806 | if (pid_revalidate(dentry, 0)) | 2792 | if (pid_revalidate(dentry, 0)) |
2807 | error = NULL; | 2793 | return 0; |
2808 | out: | 2794 | out: |
2809 | return error; | 2795 | return -ENOENT; |
2810 | } | 2796 | } |
2811 | 2797 | ||
2812 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 2798 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
2813 | { | 2799 | { |
2814 | struct dentry *result = NULL; | 2800 | int result = 0; |
2815 | struct task_struct *task; | 2801 | struct task_struct *task; |
2816 | unsigned tgid; | 2802 | unsigned tgid; |
2817 | struct pid_namespace *ns; | 2803 | struct pid_namespace *ns; |
@@ -2832,7 +2818,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign | |||
2832 | result = proc_pid_instantiate(dir, dentry, task, NULL); | 2818 | result = proc_pid_instantiate(dir, dentry, task, NULL); |
2833 | put_task_struct(task); | 2819 | put_task_struct(task); |
2834 | out: | 2820 | out: |
2835 | return result; | 2821 | return ERR_PTR(result); |
2836 | } | 2822 | } |
2837 | 2823 | ||
2838 | /* | 2824 | /* |
@@ -2884,21 +2870,21 @@ retry: | |||
2884 | int proc_pid_readdir(struct file *file, struct dir_context *ctx) | 2870 | int proc_pid_readdir(struct file *file, struct dir_context *ctx) |
2885 | { | 2871 | { |
2886 | struct tgid_iter iter; | 2872 | struct tgid_iter iter; |
2887 | struct pid_namespace *ns; | 2873 | struct pid_namespace *ns = file->f_dentry->d_sb->s_fs_info; |
2888 | loff_t pos = ctx->pos; | 2874 | loff_t pos = ctx->pos; |
2889 | 2875 | ||
2890 | if (pos >= PID_MAX_LIMIT + TGID_OFFSET) | 2876 | if (pos >= PID_MAX_LIMIT + TGID_OFFSET) |
2891 | return 0; | 2877 | return 0; |
2892 | 2878 | ||
2893 | if (pos == TGID_OFFSET - 1) { | 2879 | if (pos == TGID_OFFSET - 1) { |
2894 | if (!proc_fill_cache(file, ctx, "self", 4, NULL, NULL, NULL)) | 2880 | struct inode *inode = ns->proc_self->d_inode; |
2881 | if (!dir_emit(ctx, "self", 4, inode->i_ino, DT_LNK)) | ||
2895 | return 0; | 2882 | return 0; |
2896 | iter.tgid = 0; | 2883 | iter.tgid = 0; |
2897 | } else { | 2884 | } else { |
2898 | iter.tgid = pos - TGID_OFFSET; | 2885 | iter.tgid = pos - TGID_OFFSET; |
2899 | } | 2886 | } |
2900 | iter.task = NULL; | 2887 | iter.task = NULL; |
2901 | ns = file->f_dentry->d_sb->s_fs_info; | ||
2902 | for (iter = next_tgid(ns, iter); | 2888 | for (iter = next_tgid(ns, iter); |
2903 | iter.task; | 2889 | iter.task; |
2904 | iter.tgid += 1, iter = next_tgid(ns, iter)) { | 2890 | iter.tgid += 1, iter = next_tgid(ns, iter)) { |
@@ -3027,10 +3013,9 @@ static const struct inode_operations proc_tid_base_inode_operations = { | |||
3027 | .setattr = proc_setattr, | 3013 | .setattr = proc_setattr, |
3028 | }; | 3014 | }; |
3029 | 3015 | ||
3030 | static struct dentry *proc_task_instantiate(struct inode *dir, | 3016 | static int proc_task_instantiate(struct inode *dir, |
3031 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 3017 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
3032 | { | 3018 | { |
3033 | struct dentry *error = ERR_PTR(-ENOENT); | ||
3034 | struct inode *inode; | 3019 | struct inode *inode; |
3035 | inode = proc_pid_make_inode(dir->i_sb, task); | 3020 | inode = proc_pid_make_inode(dir->i_sb, task); |
3036 | 3021 | ||
@@ -3049,14 +3034,14 @@ static struct dentry *proc_task_instantiate(struct inode *dir, | |||
3049 | d_add(dentry, inode); | 3034 | d_add(dentry, inode); |
3050 | /* Close the race of the process dying before we return the dentry */ | 3035 | /* Close the race of the process dying before we return the dentry */ |
3051 | if (pid_revalidate(dentry, 0)) | 3036 | if (pid_revalidate(dentry, 0)) |
3052 | error = NULL; | 3037 | return 0; |
3053 | out: | 3038 | out: |
3054 | return error; | 3039 | return -ENOENT; |
3055 | } | 3040 | } |
3056 | 3041 | ||
3057 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 3042 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
3058 | { | 3043 | { |
3059 | struct dentry *result = ERR_PTR(-ENOENT); | 3044 | int result = -ENOENT; |
3060 | struct task_struct *task; | 3045 | struct task_struct *task; |
3061 | struct task_struct *leader = get_proc_task(dir); | 3046 | struct task_struct *leader = get_proc_task(dir); |
3062 | unsigned tid; | 3047 | unsigned tid; |
@@ -3086,7 +3071,7 @@ out_drop_task: | |||
3086 | out: | 3071 | out: |
3087 | put_task_struct(leader); | 3072 | put_task_struct(leader); |
3088 | out_no_task: | 3073 | out_no_task: |
3089 | return result; | 3074 | return ERR_PTR(result); |
3090 | } | 3075 | } |
3091 | 3076 | ||
3092 | /* | 3077 | /* |
diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 1441f143c43b..75f2890abbd8 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c | |||
@@ -167,11 +167,10 @@ static int proc_fd_link(struct dentry *dentry, struct path *path) | |||
167 | return ret; | 167 | return ret; |
168 | } | 168 | } |
169 | 169 | ||
170 | static struct dentry * | 170 | static int |
171 | proc_fd_instantiate(struct inode *dir, struct dentry *dentry, | 171 | proc_fd_instantiate(struct inode *dir, struct dentry *dentry, |
172 | struct task_struct *task, const void *ptr) | 172 | struct task_struct *task, const void *ptr) |
173 | { | 173 | { |
174 | struct dentry *error = ERR_PTR(-ENOENT); | ||
175 | unsigned fd = (unsigned long)ptr; | 174 | unsigned fd = (unsigned long)ptr; |
176 | struct proc_inode *ei; | 175 | struct proc_inode *ei; |
177 | struct inode *inode; | 176 | struct inode *inode; |
@@ -194,9 +193,9 @@ proc_fd_instantiate(struct inode *dir, struct dentry *dentry, | |||
194 | 193 | ||
195 | /* Close the race of the process dying before we return the dentry */ | 194 | /* Close the race of the process dying before we return the dentry */ |
196 | if (tid_fd_revalidate(dentry, 0)) | 195 | if (tid_fd_revalidate(dentry, 0)) |
197 | error = NULL; | 196 | return 0; |
198 | out: | 197 | out: |
199 | return error; | 198 | return -ENOENT; |
200 | } | 199 | } |
201 | 200 | ||
202 | static struct dentry *proc_lookupfd_common(struct inode *dir, | 201 | static struct dentry *proc_lookupfd_common(struct inode *dir, |
@@ -204,7 +203,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir, | |||
204 | instantiate_t instantiate) | 203 | instantiate_t instantiate) |
205 | { | 204 | { |
206 | struct task_struct *task = get_proc_task(dir); | 205 | struct task_struct *task = get_proc_task(dir); |
207 | struct dentry *result = ERR_PTR(-ENOENT); | 206 | int result = -ENOENT; |
208 | unsigned fd = name_to_int(dentry); | 207 | unsigned fd = name_to_int(dentry); |
209 | 208 | ||
210 | if (!task) | 209 | if (!task) |
@@ -216,7 +215,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir, | |||
216 | out: | 215 | out: |
217 | put_task_struct(task); | 216 | put_task_struct(task); |
218 | out_no_task: | 217 | out_no_task: |
219 | return result; | 218 | return ERR_PTR(result); |
220 | } | 219 | } |
221 | 220 | ||
222 | static int proc_readfd_common(struct file *file, struct dir_context *ctx, | 221 | static int proc_readfd_common(struct file *file, struct dir_context *ctx, |
@@ -300,11 +299,10 @@ const struct inode_operations proc_fd_inode_operations = { | |||
300 | .setattr = proc_setattr, | 299 | .setattr = proc_setattr, |
301 | }; | 300 | }; |
302 | 301 | ||
303 | static struct dentry * | 302 | static int |
304 | proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, | 303 | proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, |
305 | struct task_struct *task, const void *ptr) | 304 | struct task_struct *task, const void *ptr) |
306 | { | 305 | { |
307 | struct dentry *error = ERR_PTR(-ENOENT); | ||
308 | unsigned fd = (unsigned long)ptr; | 306 | unsigned fd = (unsigned long)ptr; |
309 | struct proc_inode *ei; | 307 | struct proc_inode *ei; |
310 | struct inode *inode; | 308 | struct inode *inode; |
@@ -324,9 +322,9 @@ proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, | |||
324 | 322 | ||
325 | /* Close the race of the process dying before we return the dentry */ | 323 | /* Close the race of the process dying before we return the dentry */ |
326 | if (tid_fd_revalidate(dentry, 0)) | 324 | if (tid_fd_revalidate(dentry, 0)) |
327 | error = NULL; | 325 | return 0; |
328 | out: | 326 | out: |
329 | return error; | 327 | return -ENOENT; |
330 | } | 328 | } |
331 | 329 | ||
332 | static struct dentry * | 330 | static struct dentry * |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 4eae2e149f31..651d09a11dde 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -170,7 +170,7 @@ extern struct dentry *proc_pid_lookup(struct inode *, struct dentry *, unsigned | |||
170 | extern loff_t mem_lseek(struct file *, loff_t, int); | 170 | extern loff_t mem_lseek(struct file *, loff_t, int); |
171 | 171 | ||
172 | /* Lookups */ | 172 | /* Lookups */ |
173 | typedef struct dentry *instantiate_t(struct inode *, struct dentry *, | 173 | typedef int instantiate_t(struct inode *, struct dentry *, |
174 | struct task_struct *, const void *); | 174 | struct task_struct *, const void *); |
175 | extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, int, | 175 | extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, int, |
176 | instantiate_t, struct task_struct *, const void *); | 176 | instantiate_t, struct task_struct *, const void *); |
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index f6abbbbfad8a..49a7fff2e83a 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c | |||
@@ -187,13 +187,12 @@ static const struct inode_operations proc_ns_link_inode_operations = { | |||
187 | .setattr = proc_setattr, | 187 | .setattr = proc_setattr, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static struct dentry *proc_ns_instantiate(struct inode *dir, | 190 | static int proc_ns_instantiate(struct inode *dir, |
191 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 191 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
192 | { | 192 | { |
193 | const struct proc_ns_operations *ns_ops = ptr; | 193 | const struct proc_ns_operations *ns_ops = ptr; |
194 | struct inode *inode; | 194 | struct inode *inode; |
195 | struct proc_inode *ei; | 195 | struct proc_inode *ei; |
196 | struct dentry *error = ERR_PTR(-ENOENT); | ||
197 | 196 | ||
198 | inode = proc_pid_make_inode(dir->i_sb, task); | 197 | inode = proc_pid_make_inode(dir->i_sb, task); |
199 | if (!inode) | 198 | if (!inode) |
@@ -208,9 +207,9 @@ static struct dentry *proc_ns_instantiate(struct inode *dir, | |||
208 | d_add(dentry, inode); | 207 | d_add(dentry, inode); |
209 | /* Close the race of the process dying before we return the dentry */ | 208 | /* Close the race of the process dying before we return the dentry */ |
210 | if (pid_revalidate(dentry, 0)) | 209 | if (pid_revalidate(dentry, 0)) |
211 | error = NULL; | 210 | return 0; |
212 | out: | 211 | out: |
213 | return error; | 212 | return -ENOENT; |
214 | } | 213 | } |
215 | 214 | ||
216 | static int proc_ns_dir_readdir(struct file *file, struct dir_context *ctx) | 215 | static int proc_ns_dir_readdir(struct file *file, struct dir_context *ctx) |
@@ -248,12 +247,12 @@ const struct file_operations proc_ns_dir_operations = { | |||
248 | static struct dentry *proc_ns_dir_lookup(struct inode *dir, | 247 | static struct dentry *proc_ns_dir_lookup(struct inode *dir, |
249 | struct dentry *dentry, unsigned int flags) | 248 | struct dentry *dentry, unsigned int flags) |
250 | { | 249 | { |
251 | struct dentry *error; | 250 | int error; |
252 | struct task_struct *task = get_proc_task(dir); | 251 | struct task_struct *task = get_proc_task(dir); |
253 | const struct proc_ns_operations **entry, **last; | 252 | const struct proc_ns_operations **entry, **last; |
254 | unsigned int len = dentry->d_name.len; | 253 | unsigned int len = dentry->d_name.len; |
255 | 254 | ||
256 | error = ERR_PTR(-ENOENT); | 255 | error = -ENOENT; |
257 | 256 | ||
258 | if (!task) | 257 | if (!task) |
259 | goto out_no_task; | 258 | goto out_no_task; |
@@ -272,7 +271,7 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir, | |||
272 | out: | 271 | out: |
273 | put_task_struct(task); | 272 | put_task_struct(task); |
274 | out_no_task: | 273 | out_no_task: |
275 | return error; | 274 | return ERR_PTR(error); |
276 | } | 275 | } |
277 | 276 | ||
278 | const struct inode_operations proc_ns_dir_inode_operations = { | 277 | const struct inode_operations proc_ns_dir_inode_operations = { |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index f3a570e7c257..71290463a1d3 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -796,15 +796,16 @@ static int sysctl_is_seen(struct ctl_table_header *p) | |||
796 | return res; | 796 | return res; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int proc_sys_compare(const struct dentry *parent, | 799 | static int proc_sys_compare(const struct dentry *parent, const struct dentry *dentry, |
800 | const struct inode *pinode, | ||
801 | const struct dentry *dentry, const struct inode *inode, | ||
802 | unsigned int len, const char *str, const struct qstr *name) | 800 | unsigned int len, const char *str, const struct qstr *name) |
803 | { | 801 | { |
804 | struct ctl_table_header *head; | 802 | struct ctl_table_header *head; |
803 | struct inode *inode; | ||
804 | |||
805 | /* Although proc doesn't have negative dentries, rcu-walk means | 805 | /* Although proc doesn't have negative dentries, rcu-walk means |
806 | * that inode here can be NULL */ | 806 | * that inode here can be NULL */ |
807 | /* AV: can it, indeed? */ | 807 | /* AV: can it, indeed? */ |
808 | inode = ACCESS_ONCE(dentry->d_inode); | ||
808 | if (!inode) | 809 | if (!inode) |
809 | return 1; | 810 | return 1; |
810 | if (name->len != len) | 811 | if (name->len != len) |
diff --git a/fs/read_write.c b/fs/read_write.c index 2cefa417be34..122a3846d9e1 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -41,8 +41,19 @@ static inline int unsigned_offsets(struct file *file) | |||
41 | return file->f_mode & FMODE_UNSIGNED_OFFSET; | 41 | return file->f_mode & FMODE_UNSIGNED_OFFSET; |
42 | } | 42 | } |
43 | 43 | ||
44 | static loff_t lseek_execute(struct file *file, struct inode *inode, | 44 | /** |
45 | loff_t offset, loff_t maxsize) | 45 | * vfs_setpos - update the file offset for lseek |
46 | * @file: file structure in question | ||
47 | * @offset: file offset to seek to | ||
48 | * @maxsize: maximum file size | ||
49 | * | ||
50 | * This is a low-level filesystem helper for updating the file offset to | ||
51 | * the value specified by @offset if the given offset is valid and it is | ||
52 | * not equal to the current file offset. | ||
53 | * | ||
54 | * Return the specified offset on success and -EINVAL on invalid offset. | ||
55 | */ | ||
56 | loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize) | ||
46 | { | 57 | { |
47 | if (offset < 0 && !unsigned_offsets(file)) | 58 | if (offset < 0 && !unsigned_offsets(file)) |
48 | return -EINVAL; | 59 | return -EINVAL; |
@@ -55,6 +66,7 @@ static loff_t lseek_execute(struct file *file, struct inode *inode, | |||
55 | } | 66 | } |
56 | return offset; | 67 | return offset; |
57 | } | 68 | } |
69 | EXPORT_SYMBOL(vfs_setpos); | ||
58 | 70 | ||
59 | /** | 71 | /** |
60 | * generic_file_llseek_size - generic llseek implementation for regular files | 72 | * generic_file_llseek_size - generic llseek implementation for regular files |
@@ -76,8 +88,6 @@ loff_t | |||
76 | generic_file_llseek_size(struct file *file, loff_t offset, int whence, | 88 | generic_file_llseek_size(struct file *file, loff_t offset, int whence, |
77 | loff_t maxsize, loff_t eof) | 89 | loff_t maxsize, loff_t eof) |
78 | { | 90 | { |
79 | struct inode *inode = file->f_mapping->host; | ||
80 | |||
81 | switch (whence) { | 91 | switch (whence) { |
82 | case SEEK_END: | 92 | case SEEK_END: |
83 | offset += eof; | 93 | offset += eof; |
@@ -97,8 +107,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence, | |||
97 | * like SEEK_SET. | 107 | * like SEEK_SET. |
98 | */ | 108 | */ |
99 | spin_lock(&file->f_lock); | 109 | spin_lock(&file->f_lock); |
100 | offset = lseek_execute(file, inode, file->f_pos + offset, | 110 | offset = vfs_setpos(file, file->f_pos + offset, maxsize); |
101 | maxsize); | ||
102 | spin_unlock(&file->f_lock); | 111 | spin_unlock(&file->f_lock); |
103 | return offset; | 112 | return offset; |
104 | case SEEK_DATA: | 113 | case SEEK_DATA: |
@@ -120,7 +129,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int whence, | |||
120 | break; | 129 | break; |
121 | } | 130 | } |
122 | 131 | ||
123 | return lseek_execute(file, inode, offset, maxsize); | 132 | return vfs_setpos(file, offset, maxsize); |
124 | } | 133 | } |
125 | EXPORT_SYMBOL(generic_file_llseek_size); | 134 | EXPORT_SYMBOL(generic_file_llseek_size); |
126 | 135 | ||
@@ -145,6 +154,26 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int whence) | |||
145 | EXPORT_SYMBOL(generic_file_llseek); | 154 | EXPORT_SYMBOL(generic_file_llseek); |
146 | 155 | ||
147 | /** | 156 | /** |
157 | * fixed_size_llseek - llseek implementation for fixed-sized devices | ||
158 | * @file: file structure to seek on | ||
159 | * @offset: file offset to seek to | ||
160 | * @whence: type of seek | ||
161 | * @size: size of the file | ||
162 | * | ||
163 | */ | ||
164 | loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t size) | ||
165 | { | ||
166 | switch (whence) { | ||
167 | case SEEK_SET: case SEEK_CUR: case SEEK_END: | ||
168 | return generic_file_llseek_size(file, offset, whence, | ||
169 | size, size); | ||
170 | default: | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | } | ||
174 | EXPORT_SYMBOL(fixed_size_llseek); | ||
175 | |||
176 | /** | ||
148 | * noop_llseek - No Operation Performed llseek implementation | 177 | * noop_llseek - No Operation Performed llseek implementation |
149 | * @file: file structure to seek on | 178 | * @file: file structure to seek on |
150 | * @offset: file offset to seek to | 179 | * @offset: file offset to seek to |
@@ -296,7 +325,7 @@ out_putf: | |||
296 | * them to something that fits in "int" so that others | 325 | * them to something that fits in "int" so that others |
297 | * won't have to do range checks all the time. | 326 | * won't have to do range checks all the time. |
298 | */ | 327 | */ |
299 | int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) | 328 | int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) |
300 | { | 329 | { |
301 | struct inode *inode; | 330 | struct inode *inode; |
302 | loff_t pos; | 331 | loff_t pos; |
@@ -477,7 +506,8 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) | |||
477 | if (f.file) { | 506 | if (f.file) { |
478 | loff_t pos = file_pos_read(f.file); | 507 | loff_t pos = file_pos_read(f.file); |
479 | ret = vfs_read(f.file, buf, count, &pos); | 508 | ret = vfs_read(f.file, buf, count, &pos); |
480 | file_pos_write(f.file, pos); | 509 | if (ret >= 0) |
510 | file_pos_write(f.file, pos); | ||
481 | fdput(f); | 511 | fdput(f); |
482 | } | 512 | } |
483 | return ret; | 513 | return ret; |
@@ -492,7 +522,8 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | |||
492 | if (f.file) { | 522 | if (f.file) { |
493 | loff_t pos = file_pos_read(f.file); | 523 | loff_t pos = file_pos_read(f.file); |
494 | ret = vfs_write(f.file, buf, count, &pos); | 524 | ret = vfs_write(f.file, buf, count, &pos); |
495 | file_pos_write(f.file, pos); | 525 | if (ret >= 0) |
526 | file_pos_write(f.file, pos); | ||
496 | fdput(f); | 527 | fdput(f); |
497 | } | 528 | } |
498 | 529 | ||
@@ -780,7 +811,8 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
780 | if (f.file) { | 811 | if (f.file) { |
781 | loff_t pos = file_pos_read(f.file); | 812 | loff_t pos = file_pos_read(f.file); |
782 | ret = vfs_readv(f.file, vec, vlen, &pos); | 813 | ret = vfs_readv(f.file, vec, vlen, &pos); |
783 | file_pos_write(f.file, pos); | 814 | if (ret >= 0) |
815 | file_pos_write(f.file, pos); | ||
784 | fdput(f); | 816 | fdput(f); |
785 | } | 817 | } |
786 | 818 | ||
@@ -799,7 +831,8 @@ SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | |||
799 | if (f.file) { | 831 | if (f.file) { |
800 | loff_t pos = file_pos_read(f.file); | 832 | loff_t pos = file_pos_read(f.file); |
801 | ret = vfs_writev(f.file, vec, vlen, &pos); | 833 | ret = vfs_writev(f.file, vec, vlen, &pos); |
802 | file_pos_write(f.file, pos); | 834 | if (ret >= 0) |
835 | file_pos_write(f.file, pos); | ||
803 | fdput(f); | 836 | fdput(f); |
804 | } | 837 | } |
805 | 838 | ||
@@ -959,7 +992,8 @@ COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd, | |||
959 | return -EBADF; | 992 | return -EBADF; |
960 | pos = f.file->f_pos; | 993 | pos = f.file->f_pos; |
961 | ret = compat_readv(f.file, vec, vlen, &pos); | 994 | ret = compat_readv(f.file, vec, vlen, &pos); |
962 | f.file->f_pos = pos; | 995 | if (ret >= 0) |
996 | f.file->f_pos = pos; | ||
963 | fdput(f); | 997 | fdput(f); |
964 | return ret; | 998 | return ret; |
965 | } | 999 | } |
@@ -1025,7 +1059,8 @@ COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd, | |||
1025 | return -EBADF; | 1059 | return -EBADF; |
1026 | pos = f.file->f_pos; | 1060 | pos = f.file->f_pos; |
1027 | ret = compat_writev(f.file, vec, vlen, &pos); | 1061 | ret = compat_writev(f.file, vec, vlen, &pos); |
1028 | f.file->f_pos = pos; | 1062 | if (ret >= 0) |
1063 | f.file->f_pos = pos; | ||
1029 | fdput(f); | 1064 | fdput(f); |
1030 | return ret; | 1065 | return ret; |
1031 | } | 1066 | } |
@@ -1129,7 +1164,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1129 | if (in.file->f_flags & O_NONBLOCK) | 1164 | if (in.file->f_flags & O_NONBLOCK) |
1130 | fl = SPLICE_F_NONBLOCK; | 1165 | fl = SPLICE_F_NONBLOCK; |
1131 | #endif | 1166 | #endif |
1167 | file_start_write(out.file); | ||
1132 | retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); | 1168 | retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); |
1169 | file_end_write(out.file); | ||
1133 | 1170 | ||
1134 | if (retval > 0) { | 1171 | if (retval > 0) { |
1135 | add_rchar(current, retval); | 1172 | add_rchar(current, retval); |
diff --git a/fs/splice.c b/fs/splice.c index d37431dd60a1..3b7ee656f3aa 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -1098,27 +1098,13 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | |||
1098 | { | 1098 | { |
1099 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, | 1099 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, |
1100 | loff_t *, size_t, unsigned int); | 1100 | loff_t *, size_t, unsigned int); |
1101 | int ret; | ||
1102 | |||
1103 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
1104 | return -EBADF; | ||
1105 | |||
1106 | if (unlikely(out->f_flags & O_APPEND)) | ||
1107 | return -EINVAL; | ||
1108 | |||
1109 | ret = rw_verify_area(WRITE, out, ppos, len); | ||
1110 | if (unlikely(ret < 0)) | ||
1111 | return ret; | ||
1112 | 1101 | ||
1113 | if (out->f_op && out->f_op->splice_write) | 1102 | if (out->f_op && out->f_op->splice_write) |
1114 | splice_write = out->f_op->splice_write; | 1103 | splice_write = out->f_op->splice_write; |
1115 | else | 1104 | else |
1116 | splice_write = default_file_splice_write; | 1105 | splice_write = default_file_splice_write; |
1117 | 1106 | ||
1118 | file_start_write(out); | 1107 | return splice_write(pipe, out, ppos, len, flags); |
1119 | ret = splice_write(pipe, out, ppos, len, flags); | ||
1120 | file_end_write(out); | ||
1121 | return ret; | ||
1122 | } | 1108 | } |
1123 | 1109 | ||
1124 | /* | 1110 | /* |
@@ -1307,6 +1293,16 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
1307 | }; | 1293 | }; |
1308 | long ret; | 1294 | long ret; |
1309 | 1295 | ||
1296 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
1297 | return -EBADF; | ||
1298 | |||
1299 | if (unlikely(out->f_flags & O_APPEND)) | ||
1300 | return -EINVAL; | ||
1301 | |||
1302 | ret = rw_verify_area(WRITE, out, opos, len); | ||
1303 | if (unlikely(ret < 0)) | ||
1304 | return ret; | ||
1305 | |||
1310 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); | 1306 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); |
1311 | if (ret > 0) | 1307 | if (ret > 0) |
1312 | *ppos = sd.pos; | 1308 | *ppos = sd.pos; |
@@ -1362,7 +1358,19 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1362 | offset = out->f_pos; | 1358 | offset = out->f_pos; |
1363 | } | 1359 | } |
1364 | 1360 | ||
1361 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
1362 | return -EBADF; | ||
1363 | |||
1364 | if (unlikely(out->f_flags & O_APPEND)) | ||
1365 | return -EINVAL; | ||
1366 | |||
1367 | ret = rw_verify_area(WRITE, out, &offset, len); | ||
1368 | if (unlikely(ret < 0)) | ||
1369 | return ret; | ||
1370 | |||
1371 | file_start_write(out); | ||
1365 | ret = do_splice_from(ipipe, out, &offset, len, flags); | 1372 | ret = do_splice_from(ipipe, out, &offset, len, flags); |
1373 | file_end_write(out); | ||
1366 | 1374 | ||
1367 | if (!off_out) | 1375 | if (!off_out) |
1368 | out->f_pos = offset; | 1376 | out->f_pos = offset; |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 1c0d5f264767..731b2bbcaab3 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -27,8 +27,7 @@ static int add_nondir(struct dentry *dentry, struct inode *inode) | |||
27 | return err; | 27 | return err; |
28 | } | 28 | } |
29 | 29 | ||
30 | static int sysv_hash(const struct dentry *dentry, const struct inode *inode, | 30 | static int sysv_hash(const struct dentry *dentry, struct qstr *qstr) |
31 | struct qstr *qstr) | ||
32 | { | 31 | { |
33 | /* Truncate the name in place, avoids having to define a compare | 32 | /* Truncate the name in place, avoids having to define a compare |
34 | function. */ | 33 | function. */ |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 102c072c6bbf..5f6fc17d6bc5 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -594,6 +594,29 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
594 | return 0; | 594 | return 0; |
595 | } | 595 | } |
596 | 596 | ||
597 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
598 | { | ||
599 | struct inode *inode; | ||
600 | struct udf_inode_info *iinfo; | ||
601 | int err; | ||
602 | |||
603 | inode = udf_new_inode(dir, mode, &err); | ||
604 | if (!inode) | ||
605 | return err; | ||
606 | |||
607 | iinfo = UDF_I(inode); | ||
608 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
609 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
610 | else | ||
611 | inode->i_data.a_ops = &udf_aops; | ||
612 | inode->i_op = &udf_file_inode_operations; | ||
613 | inode->i_fop = &udf_file_operations; | ||
614 | mark_inode_dirty(inode); | ||
615 | |||
616 | d_tmpfile(dentry, inode); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
597 | static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | 620 | static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, |
598 | dev_t rdev) | 621 | dev_t rdev) |
599 | { | 622 | { |
@@ -1311,6 +1334,7 @@ const struct inode_operations udf_dir_inode_operations = { | |||
1311 | .rmdir = udf_rmdir, | 1334 | .rmdir = udf_rmdir, |
1312 | .mknod = udf_mknod, | 1335 | .mknod = udf_mknod, |
1313 | .rename = udf_rename, | 1336 | .rename = udf_rename, |
1337 | .tmpfile = udf_tmpfile, | ||
1314 | }; | 1338 | }; |
1315 | const struct inode_operations udf_symlink_inode_operations = { | 1339 | const struct inode_operations udf_symlink_inode_operations = { |
1316 | .readlink = generic_readlink, | 1340 | .readlink = generic_readlink, |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 0ad2b95fca12..de3dc98f4e8f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -1268,8 +1268,7 @@ xfs_seek_data( | |||
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | out: | 1270 | out: |
1271 | if (offset != file->f_pos) | 1271 | offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); |
1272 | file->f_pos = offset; | ||
1273 | 1272 | ||
1274 | out_unlock: | 1273 | out_unlock: |
1275 | xfs_iunlock_map_shared(ip, lock); | 1274 | xfs_iunlock_map_shared(ip, lock); |
@@ -1377,8 +1376,7 @@ out: | |||
1377 | * situation in particular. | 1376 | * situation in particular. |
1378 | */ | 1377 | */ |
1379 | offset = min_t(loff_t, offset, isize); | 1378 | offset = min_t(loff_t, offset, isize); |
1380 | if (offset != file->f_pos) | 1379 | offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); |
1381 | file->f_pos = offset; | ||
1382 | 1380 | ||
1383 | out_unlock: | 1381 | out_unlock: |
1384 | xfs_iunlock_map_shared(ip, lock); | 1382 | xfs_iunlock_map_shared(ip, lock); |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 1a6bb81f0fe5..f42dbe145479 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -146,10 +146,8 @@ enum dentry_d_lock_class | |||
146 | struct dentry_operations { | 146 | struct dentry_operations { |
147 | int (*d_revalidate)(struct dentry *, unsigned int); | 147 | int (*d_revalidate)(struct dentry *, unsigned int); |
148 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 148 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
149 | int (*d_hash)(const struct dentry *, const struct inode *, | 149 | int (*d_hash)(const struct dentry *, struct qstr *); |
150 | struct qstr *); | 150 | int (*d_compare)(const struct dentry *, const struct dentry *, |
151 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
152 | const struct dentry *, const struct inode *, | ||
153 | unsigned int, const char *, const struct qstr *); | 151 | unsigned int, const char *, const struct qstr *); |
154 | int (*d_delete)(const struct dentry *); | 152 | int (*d_delete)(const struct dentry *); |
155 | void (*d_release)(struct dentry *); | 153 | void (*d_release)(struct dentry *); |
@@ -246,6 +244,8 @@ extern struct dentry * d_make_root(struct inode *); | |||
246 | /* <clickety>-<click> the ramfs-type tree */ | 244 | /* <clickety>-<click> the ramfs-type tree */ |
247 | extern void d_genocide(struct dentry *); | 245 | extern void d_genocide(struct dentry *); |
248 | 246 | ||
247 | extern void d_tmpfile(struct dentry *, struct inode *); | ||
248 | |||
249 | extern struct dentry *d_find_alias(struct inode *); | 249 | extern struct dentry *d_find_alias(struct inode *); |
250 | extern void d_prune_aliases(struct inode *); | 250 | extern void d_prune_aliases(struct inode *); |
251 | 251 | ||
@@ -300,8 +300,7 @@ extern struct dentry *d_lookup(const struct dentry *, const struct qstr *); | |||
300 | extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); | 300 | extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); |
301 | extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); | 301 | extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); |
302 | extern struct dentry *__d_lookup_rcu(const struct dentry *parent, | 302 | extern struct dentry *__d_lookup_rcu(const struct dentry *parent, |
303 | const struct qstr *name, | 303 | const struct qstr *name, unsigned *seq); |
304 | unsigned *seq, struct inode *inode); | ||
305 | 304 | ||
306 | /** | 305 | /** |
307 | * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok | 306 | * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok |
diff --git a/include/linux/fs.h b/include/linux/fs.h index f8a5240541b7..2b82c8041490 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -908,6 +908,7 @@ struct file_lock_operations { | |||
908 | 908 | ||
909 | struct lock_manager_operations { | 909 | struct lock_manager_operations { |
910 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); | 910 | int (*lm_compare_owner)(struct file_lock *, struct file_lock *); |
911 | unsigned long (*lm_owner_key)(struct file_lock *); | ||
911 | void (*lm_notify)(struct file_lock *); /* unblock callback */ | 912 | void (*lm_notify)(struct file_lock *); /* unblock callback */ |
912 | int (*lm_grant)(struct file_lock *, struct file_lock *, int); | 913 | int (*lm_grant)(struct file_lock *, struct file_lock *, int); |
913 | void (*lm_break)(struct file_lock *); | 914 | void (*lm_break)(struct file_lock *); |
@@ -926,9 +927,27 @@ int locks_in_grace(struct net *); | |||
926 | /* that will die - we need it for nfs_lock_info */ | 927 | /* that will die - we need it for nfs_lock_info */ |
927 | #include <linux/nfs_fs_i.h> | 928 | #include <linux/nfs_fs_i.h> |
928 | 929 | ||
930 | /* | ||
931 | * struct file_lock represents a generic "file lock". It's used to represent | ||
932 | * POSIX byte range locks, BSD (flock) locks, and leases. It's important to | ||
933 | * note that the same struct is used to represent both a request for a lock and | ||
934 | * the lock itself, but the same object is never used for both. | ||
935 | * | ||
936 | * FIXME: should we create a separate "struct lock_request" to help distinguish | ||
937 | * these two uses? | ||
938 | * | ||
939 | * The i_flock list is ordered by: | ||
940 | * | ||
941 | * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX | ||
942 | * 2) lock owner | ||
943 | * 3) lock range start | ||
944 | * 4) lock range end | ||
945 | * | ||
946 | * Obviously, the last two criteria only matter for POSIX locks. | ||
947 | */ | ||
929 | struct file_lock { | 948 | struct file_lock { |
930 | struct file_lock *fl_next; /* singly linked list for this inode */ | 949 | struct file_lock *fl_next; /* singly linked list for this inode */ |
931 | struct list_head fl_link; /* doubly linked list of all locks */ | 950 | struct hlist_node fl_link; /* node in global lists */ |
932 | struct list_head fl_block; /* circular list of blocked processes */ | 951 | struct list_head fl_block; /* circular list of blocked processes */ |
933 | fl_owner_t fl_owner; | 952 | fl_owner_t fl_owner; |
934 | unsigned int fl_flags; | 953 | unsigned int fl_flags; |
@@ -994,7 +1013,7 @@ extern void locks_release_private(struct file_lock *); | |||
994 | extern void posix_test_lock(struct file *, struct file_lock *); | 1013 | extern void posix_test_lock(struct file *, struct file_lock *); |
995 | extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); | 1014 | extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); |
996 | extern int posix_lock_file_wait(struct file *, struct file_lock *); | 1015 | extern int posix_lock_file_wait(struct file *, struct file_lock *); |
997 | extern int posix_unblock_lock(struct file *, struct file_lock *); | 1016 | extern int posix_unblock_lock(struct file_lock *); |
998 | extern int vfs_test_lock(struct file *, struct file_lock *); | 1017 | extern int vfs_test_lock(struct file *, struct file_lock *); |
999 | extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); | 1018 | extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); |
1000 | extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); | 1019 | extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); |
@@ -1006,9 +1025,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **); | |||
1006 | extern int lease_modify(struct file_lock **, int); | 1025 | extern int lease_modify(struct file_lock **, int); |
1007 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); | 1026 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); |
1008 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); | 1027 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); |
1009 | extern void locks_delete_block(struct file_lock *waiter); | ||
1010 | extern void lock_flocks(void); | ||
1011 | extern void unlock_flocks(void); | ||
1012 | #else /* !CONFIG_FILE_LOCKING */ | 1028 | #else /* !CONFIG_FILE_LOCKING */ |
1013 | static inline int fcntl_getlk(struct file *file, struct flock __user *user) | 1029 | static inline int fcntl_getlk(struct file *file, struct flock __user *user) |
1014 | { | 1030 | { |
@@ -1084,8 +1100,7 @@ static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl) | |||
1084 | return -ENOLCK; | 1100 | return -ENOLCK; |
1085 | } | 1101 | } |
1086 | 1102 | ||
1087 | static inline int posix_unblock_lock(struct file *filp, | 1103 | static inline int posix_unblock_lock(struct file_lock *waiter) |
1088 | struct file_lock *waiter) | ||
1089 | { | 1104 | { |
1090 | return -ENOENT; | 1105 | return -ENOENT; |
1091 | } | 1106 | } |
@@ -1150,19 +1165,6 @@ static inline int lock_may_write(struct inode *inode, loff_t start, | |||
1150 | { | 1165 | { |
1151 | return 1; | 1166 | return 1; |
1152 | } | 1167 | } |
1153 | |||
1154 | static inline void locks_delete_block(struct file_lock *waiter) | ||
1155 | { | ||
1156 | } | ||
1157 | |||
1158 | static inline void lock_flocks(void) | ||
1159 | { | ||
1160 | } | ||
1161 | |||
1162 | static inline void unlock_flocks(void) | ||
1163 | { | ||
1164 | } | ||
1165 | |||
1166 | #endif /* !CONFIG_FILE_LOCKING */ | 1168 | #endif /* !CONFIG_FILE_LOCKING */ |
1167 | 1169 | ||
1168 | 1170 | ||
@@ -1580,6 +1582,7 @@ struct inode_operations { | |||
1580 | int (*atomic_open)(struct inode *, struct dentry *, | 1582 | int (*atomic_open)(struct inode *, struct dentry *, |
1581 | struct file *, unsigned open_flag, | 1583 | struct file *, unsigned open_flag, |
1582 | umode_t create_mode, int *opened); | 1584 | umode_t create_mode, int *opened); |
1585 | int (*tmpfile) (struct inode *, struct dentry *, umode_t); | ||
1583 | } ____cacheline_aligned; | 1586 | } ____cacheline_aligned; |
1584 | 1587 | ||
1585 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, | 1588 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, |
@@ -1743,6 +1746,7 @@ struct super_operations { | |||
1743 | #define I_REFERENCED (1 << 8) | 1746 | #define I_REFERENCED (1 << 8) |
1744 | #define __I_DIO_WAKEUP 9 | 1747 | #define __I_DIO_WAKEUP 9 |
1745 | #define I_DIO_WAKEUP (1 << I_DIO_WAKEUP) | 1748 | #define I_DIO_WAKEUP (1 << I_DIO_WAKEUP) |
1749 | #define I_LINKABLE (1 << 10) | ||
1746 | 1750 | ||
1747 | #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) | 1751 | #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) |
1748 | 1752 | ||
@@ -1896,7 +1900,6 @@ extern int current_umask(void); | |||
1896 | extern struct kobject *fs_kobj; | 1900 | extern struct kobject *fs_kobj; |
1897 | 1901 | ||
1898 | #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) | 1902 | #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) |
1899 | extern int rw_verify_area(int, struct file *, loff_t *, size_t); | ||
1900 | 1903 | ||
1901 | #define FLOCK_VERIFY_READ 1 | 1904 | #define FLOCK_VERIFY_READ 1 |
1902 | #define FLOCK_VERIFY_WRITE 2 | 1905 | #define FLOCK_VERIFY_WRITE 2 |
@@ -2309,7 +2312,6 @@ extern struct file * open_exec(const char *); | |||
2309 | /* fs/dcache.c -- generic fs support functions */ | 2312 | /* fs/dcache.c -- generic fs support functions */ |
2310 | extern int is_subdir(struct dentry *, struct dentry *); | 2313 | extern int is_subdir(struct dentry *, struct dentry *); |
2311 | extern int path_is_under(struct path *, struct path *); | 2314 | extern int path_is_under(struct path *, struct path *); |
2312 | extern ino_t find_inode_number(struct dentry *, struct qstr *); | ||
2313 | 2315 | ||
2314 | #include <linux/err.h> | 2316 | #include <linux/err.h> |
2315 | 2317 | ||
@@ -2424,9 +2426,12 @@ extern void | |||
2424 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); | 2426 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); |
2425 | extern loff_t noop_llseek(struct file *file, loff_t offset, int whence); | 2427 | extern loff_t noop_llseek(struct file *file, loff_t offset, int whence); |
2426 | extern loff_t no_llseek(struct file *file, loff_t offset, int whence); | 2428 | extern loff_t no_llseek(struct file *file, loff_t offset, int whence); |
2429 | extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize); | ||
2427 | extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence); | 2430 | extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence); |
2428 | extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, | 2431 | extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, |
2429 | int whence, loff_t maxsize, loff_t eof); | 2432 | int whence, loff_t maxsize, loff_t eof); |
2433 | extern loff_t fixed_size_llseek(struct file *file, loff_t offset, | ||
2434 | int whence, loff_t size); | ||
2430 | extern int generic_file_open(struct inode * inode, struct file * filp); | 2435 | extern int generic_file_open(struct inode * inode, struct file * filp); |
2431 | extern int nonseekable_open(struct inode * inode, struct file * filp); | 2436 | extern int nonseekable_open(struct inode * inode, struct file * filp); |
2432 | 2437 | ||
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a78680a92dba..1c804b057fb1 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -38,7 +38,7 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3 | |||
38 | static inline int fsnotify_perm(struct file *file, int mask) | 38 | static inline int fsnotify_perm(struct file *file, int mask) |
39 | { | 39 | { |
40 | struct path *path = &file->f_path; | 40 | struct path *path = &file->f_path; |
41 | struct inode *inode = path->dentry->d_inode; | 41 | struct inode *inode = file_inode(file); |
42 | __u32 fsnotify_mask = 0; | 42 | __u32 fsnotify_mask = 0; |
43 | int ret; | 43 | int ret; |
44 | 44 | ||
@@ -192,7 +192,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
192 | static inline void fsnotify_access(struct file *file) | 192 | static inline void fsnotify_access(struct file *file) |
193 | { | 193 | { |
194 | struct path *path = &file->f_path; | 194 | struct path *path = &file->f_path; |
195 | struct inode *inode = path->dentry->d_inode; | 195 | struct inode *inode = file_inode(file); |
196 | __u32 mask = FS_ACCESS; | 196 | __u32 mask = FS_ACCESS; |
197 | 197 | ||
198 | if (S_ISDIR(inode->i_mode)) | 198 | if (S_ISDIR(inode->i_mode)) |
@@ -210,7 +210,7 @@ static inline void fsnotify_access(struct file *file) | |||
210 | static inline void fsnotify_modify(struct file *file) | 210 | static inline void fsnotify_modify(struct file *file) |
211 | { | 211 | { |
212 | struct path *path = &file->f_path; | 212 | struct path *path = &file->f_path; |
213 | struct inode *inode = path->dentry->d_inode; | 213 | struct inode *inode = file_inode(file); |
214 | __u32 mask = FS_MODIFY; | 214 | __u32 mask = FS_MODIFY; |
215 | 215 | ||
216 | if (S_ISDIR(inode->i_mode)) | 216 | if (S_ISDIR(inode->i_mode)) |
@@ -228,7 +228,7 @@ static inline void fsnotify_modify(struct file *file) | |||
228 | static inline void fsnotify_open(struct file *file) | 228 | static inline void fsnotify_open(struct file *file) |
229 | { | 229 | { |
230 | struct path *path = &file->f_path; | 230 | struct path *path = &file->f_path; |
231 | struct inode *inode = path->dentry->d_inode; | 231 | struct inode *inode = file_inode(file); |
232 | __u32 mask = FS_OPEN; | 232 | __u32 mask = FS_OPEN; |
233 | 233 | ||
234 | if (S_ISDIR(inode->i_mode)) | 234 | if (S_ISDIR(inode->i_mode)) |
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index a48937d4a5ea..06632beaa6d5 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h | |||
@@ -84,6 +84,10 @@ | |||
84 | #define O_PATH 010000000 | 84 | #define O_PATH 010000000 |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | #ifndef O_TMPFILE | ||
88 | #define O_TMPFILE 020000000 | ||
89 | #endif | ||
90 | |||
87 | #ifndef O_NDELAY | 91 | #ifndef O_NDELAY |
88 | #define O_NDELAY O_NONBLOCK | 92 | #define O_NDELAY O_NONBLOCK |
89 | #endif | 93 | #endif |
diff --git a/mm/shmem.c b/mm/shmem.c index 5e6a8422658b..118dfa4952f4 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1798,10 +1798,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence) | |||
1798 | } | 1798 | } |
1799 | } | 1799 | } |
1800 | 1800 | ||
1801 | if (offset >= 0 && offset != file->f_pos) { | 1801 | offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE); |
1802 | file->f_pos = offset; | ||
1803 | file->f_version = 0; | ||
1804 | } | ||
1805 | mutex_unlock(&inode->i_mutex); | 1802 | mutex_unlock(&inode->i_mutex); |
1806 | return offset; | 1803 | return offset; |
1807 | } | 1804 | } |
@@ -1965,6 +1962,37 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) | |||
1965 | return error; | 1962 | return error; |
1966 | } | 1963 | } |
1967 | 1964 | ||
1965 | static int | ||
1966 | shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
1967 | { | ||
1968 | struct inode *inode; | ||
1969 | int error = -ENOSPC; | ||
1970 | |||
1971 | inode = shmem_get_inode(dir->i_sb, dir, mode, 0, VM_NORESERVE); | ||
1972 | if (inode) { | ||
1973 | error = security_inode_init_security(inode, dir, | ||
1974 | NULL, | ||
1975 | shmem_initxattrs, NULL); | ||
1976 | if (error) { | ||
1977 | if (error != -EOPNOTSUPP) { | ||
1978 | iput(inode); | ||
1979 | return error; | ||
1980 | } | ||
1981 | } | ||
1982 | #ifdef CONFIG_TMPFS_POSIX_ACL | ||
1983 | error = generic_acl_init(inode, dir); | ||
1984 | if (error) { | ||
1985 | iput(inode); | ||
1986 | return error; | ||
1987 | } | ||
1988 | #else | ||
1989 | error = 0; | ||
1990 | #endif | ||
1991 | d_tmpfile(dentry, inode); | ||
1992 | } | ||
1993 | return error; | ||
1994 | } | ||
1995 | |||
1968 | static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1996 | static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1969 | { | 1997 | { |
1970 | int error; | 1998 | int error; |
@@ -2723,6 +2751,7 @@ static const struct inode_operations shmem_dir_inode_operations = { | |||
2723 | .rmdir = shmem_rmdir, | 2751 | .rmdir = shmem_rmdir, |
2724 | .mknod = shmem_mknod, | 2752 | .mknod = shmem_mknod, |
2725 | .rename = shmem_rename, | 2753 | .rename = shmem_rename, |
2754 | .tmpfile = shmem_tmpfile, | ||
2726 | #endif | 2755 | #endif |
2727 | #ifdef CONFIG_TMPFS_XATTR | 2756 | #ifdef CONFIG_TMPFS_XATTR |
2728 | .setxattr = shmem_setxattr, | 2757 | .setxattr = shmem_setxattr, |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 29b4ba93ab3c..b05ace4c5f12 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -1330,7 +1330,7 @@ static int wait_for_gss_proxy(struct net *net, struct file *file) | |||
1330 | static ssize_t write_gssp(struct file *file, const char __user *buf, | 1330 | static ssize_t write_gssp(struct file *file, const char __user *buf, |
1331 | size_t count, loff_t *ppos) | 1331 | size_t count, loff_t *ppos) |
1332 | { | 1332 | { |
1333 | struct net *net = PDE_DATA(file->f_path.dentry->d_inode); | 1333 | struct net *net = PDE_DATA(file_inode(file)); |
1334 | char tbuf[20]; | 1334 | char tbuf[20]; |
1335 | unsigned long i; | 1335 | unsigned long i; |
1336 | int res; | 1336 | int res; |
@@ -1358,7 +1358,7 @@ static ssize_t write_gssp(struct file *file, const char __user *buf, | |||
1358 | static ssize_t read_gssp(struct file *file, char __user *buf, | 1358 | static ssize_t read_gssp(struct file *file, char __user *buf, |
1359 | size_t count, loff_t *ppos) | 1359 | size_t count, loff_t *ppos) |
1360 | { | 1360 | { |
1361 | struct net *net = PDE_DATA(file->f_path.dentry->d_inode); | 1361 | struct net *net = PDE_DATA(file_inode(file)); |
1362 | unsigned long p = *ppos; | 1362 | unsigned long p = *ppos; |
1363 | char tbuf[10]; | 1363 | char tbuf[10]; |
1364 | size_t len; | 1364 | size_t len; |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6c491a63128e..e9508d5bbfcf 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -57,7 +57,7 @@ __setup("ima_hash=", hash_setup); | |||
57 | static void ima_rdwr_violation_check(struct file *file) | 57 | static void ima_rdwr_violation_check(struct file *file) |
58 | { | 58 | { |
59 | struct dentry *dentry = file->f_path.dentry; | 59 | struct dentry *dentry = file->f_path.dentry; |
60 | struct inode *inode = dentry->d_inode; | 60 | struct inode *inode = file_inode(file); |
61 | fmode_t mode = file->f_mode; | 61 | fmode_t mode = file->f_mode; |
62 | int must_measure; | 62 | int must_measure; |
63 | bool send_tomtou = false, send_writers = false; | 63 | bool send_tomtou = false, send_writers = false; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5c6f2cd2d095..db1fca990a24 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1547,6 +1547,18 @@ static inline int path_has_perm(const struct cred *cred, | |||
1547 | return inode_has_perm(cred, inode, av, &ad, 0); | 1547 | return inode_has_perm(cred, inode, av, &ad, 0); |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | /* Same as path_has_perm, but uses the inode from the file struct. */ | ||
1551 | static inline int file_path_has_perm(const struct cred *cred, | ||
1552 | struct file *file, | ||
1553 | u32 av) | ||
1554 | { | ||
1555 | struct common_audit_data ad; | ||
1556 | |||
1557 | ad.type = LSM_AUDIT_DATA_PATH; | ||
1558 | ad.u.path = file->f_path; | ||
1559 | return inode_has_perm(cred, file_inode(file), av, &ad, 0); | ||
1560 | } | ||
1561 | |||
1550 | /* Check whether a task can use an open file descriptor to | 1562 | /* Check whether a task can use an open file descriptor to |
1551 | access an inode in a given way. Check access to the | 1563 | access an inode in a given way. Check access to the |
1552 | descriptor itself, and then use dentry_has_perm to | 1564 | descriptor itself, and then use dentry_has_perm to |
@@ -2141,14 +2153,14 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2141 | struct tty_file_private *file_priv; | 2153 | struct tty_file_private *file_priv; |
2142 | 2154 | ||
2143 | /* Revalidate access to controlling tty. | 2155 | /* Revalidate access to controlling tty. |
2144 | Use path_has_perm on the tty path directly rather | 2156 | Use file_path_has_perm on the tty path directly |
2145 | than using file_has_perm, as this particular open | 2157 | rather than using file_has_perm, as this particular |
2146 | file may belong to another process and we are only | 2158 | open file may belong to another process and we are |
2147 | interested in the inode-based check here. */ | 2159 | only interested in the inode-based check here. */ |
2148 | file_priv = list_first_entry(&tty->tty_files, | 2160 | file_priv = list_first_entry(&tty->tty_files, |
2149 | struct tty_file_private, list); | 2161 | struct tty_file_private, list); |
2150 | file = file_priv->file; | 2162 | file = file_priv->file; |
2151 | if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE)) | 2163 | if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE)) |
2152 | drop_tty = 1; | 2164 | drop_tty = 1; |
2153 | } | 2165 | } |
2154 | spin_unlock(&tty_files_lock); | 2166 | spin_unlock(&tty_files_lock); |
@@ -3259,7 +3271,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) | |||
3259 | * new inode label or new policy. | 3271 | * new inode label or new policy. |
3260 | * This check is not redundant - do not remove. | 3272 | * This check is not redundant - do not remove. |
3261 | */ | 3273 | */ |
3262 | return path_has_perm(cred, &file->f_path, open_file_to_av(file)); | 3274 | return file_path_has_perm(cred, file, open_file_to_av(file)); |
3263 | } | 3275 | } |
3264 | 3276 | ||
3265 | /* task security operations */ | 3277 | /* task security operations */ |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f92818155958..a68d4c6d702c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1589,29 +1589,16 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) | |||
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | 1591 | ||
1592 | /* WARNING: Don't forget to fput back the file */ | 1592 | static bool is_pcm_file(struct file *file) |
1593 | static struct file *snd_pcm_file_fd(int fd, int *fput_needed) | ||
1594 | { | 1593 | { |
1595 | struct file *file; | 1594 | struct inode *inode = file_inode(file); |
1596 | struct inode *inode; | ||
1597 | unsigned int minor; | 1595 | unsigned int minor; |
1598 | 1596 | ||
1599 | file = fget_light(fd, fput_needed); | 1597 | if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major) |
1600 | if (!file) | 1598 | return false; |
1601 | return NULL; | ||
1602 | inode = file_inode(file); | ||
1603 | if (!S_ISCHR(inode->i_mode) || | ||
1604 | imajor(inode) != snd_major) { | ||
1605 | fput_light(file, *fput_needed); | ||
1606 | return NULL; | ||
1607 | } | ||
1608 | minor = iminor(inode); | 1599 | minor = iminor(inode); |
1609 | if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) && | 1600 | return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) || |
1610 | !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) { | 1601 | snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE); |
1611 | fput_light(file, *fput_needed); | ||
1612 | return NULL; | ||
1613 | } | ||
1614 | return file; | ||
1615 | } | 1602 | } |
1616 | 1603 | ||
1617 | /* | 1604 | /* |
@@ -1620,16 +1607,18 @@ static struct file *snd_pcm_file_fd(int fd, int *fput_needed) | |||
1620 | static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | 1607 | static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) |
1621 | { | 1608 | { |
1622 | int res = 0; | 1609 | int res = 0; |
1623 | struct file *file; | ||
1624 | struct snd_pcm_file *pcm_file; | 1610 | struct snd_pcm_file *pcm_file; |
1625 | struct snd_pcm_substream *substream1; | 1611 | struct snd_pcm_substream *substream1; |
1626 | struct snd_pcm_group *group; | 1612 | struct snd_pcm_group *group; |
1627 | int fput_needed; | 1613 | struct fd f = fdget(fd); |
1628 | 1614 | ||
1629 | file = snd_pcm_file_fd(fd, &fput_needed); | 1615 | if (!f.file) |
1630 | if (!file) | ||
1631 | return -EBADFD; | 1616 | return -EBADFD; |
1632 | pcm_file = file->private_data; | 1617 | if (!is_pcm_file(f.file)) { |
1618 | res = -EBADFD; | ||
1619 | goto _badf; | ||
1620 | } | ||
1621 | pcm_file = f.file->private_data; | ||
1633 | substream1 = pcm_file->substream; | 1622 | substream1 = pcm_file->substream; |
1634 | group = kmalloc(sizeof(*group), GFP_KERNEL); | 1623 | group = kmalloc(sizeof(*group), GFP_KERNEL); |
1635 | if (!group) { | 1624 | if (!group) { |
@@ -1663,8 +1652,9 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1663 | up_write(&snd_pcm_link_rwsem); | 1652 | up_write(&snd_pcm_link_rwsem); |
1664 | _nolock: | 1653 | _nolock: |
1665 | snd_card_unref(substream1->pcm->card); | 1654 | snd_card_unref(substream1->pcm->card); |
1666 | fput_light(file, fput_needed); | ||
1667 | kfree(group); | 1655 | kfree(group); |
1656 | _badf: | ||
1657 | fdput(f); | ||
1668 | return res; | 1658 | return res; |
1669 | } | 1659 | } |
1670 | 1660 | ||