diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 05:28:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 05:28:42 -0400 |
commit | 77c688ac87183537ed0fb84ec2cb8fa8ec97c458 (patch) | |
tree | d18e117e05c0d71463823536165ddd9ad75b6bc5 | |
parent | 5e40d331bd72447197f26525f21711c4a265b6a6 (diff) | |
parent | a457606a6f81cfddfc9da1ef2a8bf2c65a8eb35e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"The big thing in this pile is Eric's unmount-on-rmdir series; we
finally have everything we need for that. The final piece of prereqs
is delayed mntput() - now filesystem shutdown always happens on
shallow stack.
Other than that, we have several new primitives for iov_iter (Matt
Wilcox, culled from his XIP-related series) pushing the conversion to
->read_iter()/ ->write_iter() a bit more, a bunch of fs/dcache.c
cleanups and fixes (including the external name refcounting, which
gives consistent behaviour of d_move() wrt procfs symlinks for long
and short names alike) and assorted cleanups and fixes all over the
place.
This is just the first pile; there's a lot of stuff from various
people that ought to go in this window. Starting with
unionmount/overlayfs mess... ;-/"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (60 commits)
fs/file_table.c: Update alloc_file() comment
vfs: Deduplicate code shared by xattr system calls operating on paths
reiserfs: remove pointless forward declaration of struct nameidata
don't need that forward declaration of struct nameidata in dcache.h anymore
take dname_external() into fs/dcache.c
let path_init() failures treated the same way as subsequent link_path_walk()
fix misuses of f_count() in ppp and netlink
ncpfs: use list_for_each_entry() for d_subdirs walk
vfs: move getname() from callers to do_mount()
gfs2_atomic_open(): skip lookups on hashed dentry
[infiniband] remove pointless assignments
gadgetfs: saner API for gadgetfs_create_file()
f_fs: saner API for ffs_sb_create_file()
jfs: don't hash direct inode
[s390] remove pointless assignment of ->f_op in vmlogrdr ->open()
ecryptfs: ->f_op is never NULL
android: ->f_op is never NULL
nouveau: __iomem misannotations
missing annotation in fs/file.c
fs: namespace: suppress 'may be used uninitialized' warnings
...
74 files changed, 889 insertions, 960 deletions
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 8be1ea3bdd5a..fceff7c00a3c 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -237,7 +237,7 @@ noted. This means that most methods can block safely. All methods are | |||
237 | only called from a process context (i.e. not from an interrupt handler | 237 | only called from a process context (i.e. not from an interrupt handler |
238 | or bottom half). | 238 | or bottom half). |
239 | 239 | ||
240 | alloc_inode: this method is called by inode_alloc() to allocate memory | 240 | alloc_inode: this method is called by alloc_inode() to allocate memory |
241 | for struct inode and initialize it. If this function is not | 241 | for struct inode and initialize it. If this function is not |
242 | defined, a simple 'struct inode' is allocated. Normally | 242 | defined, a simple 'struct inode' is allocated. Normally |
243 | alloc_inode will be used to allocate a larger structure which | 243 | alloc_inode will be used to allocate a larger structure which |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 1402fcc11c2c..f9c732e18284 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -446,7 +446,8 @@ struct procfs_args { | |||
446 | * unhappy with OSF UFS. [CHECKME] | 446 | * unhappy with OSF UFS. [CHECKME] |
447 | */ | 447 | */ |
448 | static int | 448 | static int |
449 | osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) | 449 | osf_ufs_mount(const char __user *dirname, |
450 | struct ufs_args __user *args, int flags) | ||
450 | { | 451 | { |
451 | int retval; | 452 | int retval; |
452 | struct cdfs_args tmp; | 453 | struct cdfs_args tmp; |
@@ -466,7 +467,8 @@ osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) | |||
466 | } | 467 | } |
467 | 468 | ||
468 | static int | 469 | static int |
469 | osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) | 470 | osf_cdfs_mount(const char __user *dirname, |
471 | struct cdfs_args __user *args, int flags) | ||
470 | { | 472 | { |
471 | int retval; | 473 | int retval; |
472 | struct cdfs_args tmp; | 474 | struct cdfs_args tmp; |
@@ -486,7 +488,8 @@ osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) | |||
486 | } | 488 | } |
487 | 489 | ||
488 | static int | 490 | static int |
489 | osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) | 491 | osf_procfs_mount(const char __user *dirname, |
492 | struct procfs_args __user *args, int flags) | ||
490 | { | 493 | { |
491 | struct procfs_args tmp; | 494 | struct procfs_args tmp; |
492 | 495 | ||
@@ -500,28 +503,22 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path, | |||
500 | int, flag, void __user *, data) | 503 | int, flag, void __user *, data) |
501 | { | 504 | { |
502 | int retval; | 505 | int retval; |
503 | struct filename *name; | ||
504 | 506 | ||
505 | name = getname(path); | ||
506 | retval = PTR_ERR(name); | ||
507 | if (IS_ERR(name)) | ||
508 | goto out; | ||
509 | switch (typenr) { | 507 | switch (typenr) { |
510 | case 1: | 508 | case 1: |
511 | retval = osf_ufs_mount(name->name, data, flag); | 509 | retval = osf_ufs_mount(path, data, flag); |
512 | break; | 510 | break; |
513 | case 6: | 511 | case 6: |
514 | retval = osf_cdfs_mount(name->name, data, flag); | 512 | retval = osf_cdfs_mount(path, data, flag); |
515 | break; | 513 | break; |
516 | case 9: | 514 | case 9: |
517 | retval = osf_procfs_mount(name->name, data, flag); | 515 | retval = osf_procfs_mount(path, data, flag); |
518 | break; | 516 | break; |
519 | default: | 517 | default: |
520 | retval = -EINVAL; | 518 | retval = -EINVAL; |
521 | printk("osf_mount(%ld, %x)\n", typenr, flag); | 519 | printk("osf_mount(%ld, %x)\n", typenr, flag); |
522 | } | 520 | } |
523 | putname(name); | 521 | |
524 | out: | ||
525 | return retval; | 522 | return retval; |
526 | } | 523 | } |
527 | 524 | ||
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index d21ff89207cd..df91466f973d 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
@@ -308,11 +308,8 @@ static int load_aout_binary(struct linux_binprm *bprm) | |||
308 | (current->mm->start_brk = N_BSSADDR(ex)); | 308 | (current->mm->start_brk = N_BSSADDR(ex)); |
309 | 309 | ||
310 | retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT); | 310 | retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT); |
311 | if (retval < 0) { | 311 | if (retval < 0) |
312 | /* Someone check-me: is this error path enough? */ | ||
313 | send_sig(SIGKILL, current, 0); | ||
314 | return retval; | 312 | return retval; |
315 | } | ||
316 | 313 | ||
317 | install_exec_creds(bprm); | 314 | install_exec_creds(bprm); |
318 | 315 | ||
@@ -324,17 +321,13 @@ static int load_aout_binary(struct linux_binprm *bprm) | |||
324 | 321 | ||
325 | error = vm_brk(text_addr & PAGE_MASK, map_size); | 322 | error = vm_brk(text_addr & PAGE_MASK, map_size); |
326 | 323 | ||
327 | if (error != (text_addr & PAGE_MASK)) { | 324 | if (error != (text_addr & PAGE_MASK)) |
328 | send_sig(SIGKILL, current, 0); | ||
329 | return error; | 325 | return error; |
330 | } | ||
331 | 326 | ||
332 | error = read_code(bprm->file, text_addr, 32, | 327 | error = read_code(bprm->file, text_addr, 32, |
333 | ex.a_text + ex.a_data); | 328 | ex.a_text + ex.a_data); |
334 | if ((signed long)error < 0) { | 329 | if ((signed long)error < 0) |
335 | send_sig(SIGKILL, current, 0); | ||
336 | return error; | 330 | return error; |
337 | } | ||
338 | } else { | 331 | } else { |
339 | #ifdef WARN_OLD | 332 | #ifdef WARN_OLD |
340 | static unsigned long error_time, error_time2; | 333 | static unsigned long error_time, error_time2; |
@@ -368,20 +361,16 @@ static int load_aout_binary(struct linux_binprm *bprm) | |||
368 | MAP_EXECUTABLE | MAP_32BIT, | 361 | MAP_EXECUTABLE | MAP_32BIT, |
369 | fd_offset); | 362 | fd_offset); |
370 | 363 | ||
371 | if (error != N_TXTADDR(ex)) { | 364 | if (error != N_TXTADDR(ex)) |
372 | send_sig(SIGKILL, current, 0); | ||
373 | return error; | 365 | return error; |
374 | } | ||
375 | 366 | ||
376 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | 367 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
377 | PROT_READ | PROT_WRITE | PROT_EXEC, | 368 | PROT_READ | PROT_WRITE | PROT_EXEC, |
378 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | | 369 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | |
379 | MAP_EXECUTABLE | MAP_32BIT, | 370 | MAP_EXECUTABLE | MAP_32BIT, |
380 | fd_offset + ex.a_text); | 371 | fd_offset + ex.a_text); |
381 | if (error != N_DATADDR(ex)) { | 372 | if (error != N_DATADDR(ex)) |
382 | send_sig(SIGKILL, current, 0); | ||
383 | return error; | 373 | return error; |
384 | } | ||
385 | } | 374 | } |
386 | beyond_if: | 375 | beyond_if: |
387 | set_binfmt(&aout_format); | 376 | set_binfmt(&aout_format); |
diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index 820b4009d5f7..3265ce94d282 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c | |||
@@ -62,12 +62,6 @@ static DEFINE_SPINLOCK(rsxx_ida_lock); | |||
62 | 62 | ||
63 | /* --------------------Debugfs Setup ------------------- */ | 63 | /* --------------------Debugfs Setup ------------------- */ |
64 | 64 | ||
65 | struct rsxx_cram { | ||
66 | u32 f_pos; | ||
67 | u32 offset; | ||
68 | void *i_private; | ||
69 | }; | ||
70 | |||
71 | static int rsxx_attr_pci_regs_show(struct seq_file *m, void *p) | 65 | static int rsxx_attr_pci_regs_show(struct seq_file *m, void *p) |
72 | { | 66 | { |
73 | struct rsxx_cardinfo *card = m->private; | 67 | struct rsxx_cardinfo *card = m->private; |
@@ -184,93 +178,50 @@ static int rsxx_attr_pci_regs_open(struct inode *inode, struct file *file) | |||
184 | static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf, | 178 | static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf, |
185 | size_t cnt, loff_t *ppos) | 179 | size_t cnt, loff_t *ppos) |
186 | { | 180 | { |
187 | struct rsxx_cram *info = fp->private_data; | 181 | struct rsxx_cardinfo *card = file_inode(fp)->i_private; |
188 | struct rsxx_cardinfo *card = info->i_private; | ||
189 | char *buf; | 182 | char *buf; |
190 | int st; | 183 | ssize_t st; |
191 | 184 | ||
192 | buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL); | 185 | buf = kzalloc(cnt, GFP_KERNEL); |
193 | if (!buf) | 186 | if (!buf) |
194 | return -ENOMEM; | 187 | return -ENOMEM; |
195 | 188 | ||
196 | info->f_pos = (u32)*ppos + info->offset; | 189 | st = rsxx_creg_read(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1); |
197 | 190 | if (!st) | |
198 | st = rsxx_creg_read(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1); | 191 | st = copy_to_user(ubuf, buf, cnt); |
199 | if (st) | 192 | kfree(buf); |
200 | return st; | ||
201 | |||
202 | st = copy_to_user(ubuf, buf, cnt); | ||
203 | if (st) | 193 | if (st) |
204 | return st; | 194 | return st; |
205 | 195 | *ppos += cnt; | |
206 | info->offset += cnt; | ||
207 | |||
208 | kfree(buf); | ||
209 | |||
210 | return cnt; | 196 | return cnt; |
211 | } | 197 | } |
212 | 198 | ||
213 | static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf, | 199 | static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf, |
214 | size_t cnt, loff_t *ppos) | 200 | size_t cnt, loff_t *ppos) |
215 | { | 201 | { |
216 | struct rsxx_cram *info = fp->private_data; | 202 | struct rsxx_cardinfo *card = file_inode(fp)->i_private; |
217 | struct rsxx_cardinfo *card = info->i_private; | ||
218 | char *buf; | 203 | char *buf; |
219 | int st; | 204 | ssize_t st; |
220 | 205 | ||
221 | buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL); | 206 | buf = kzalloc(cnt, GFP_KERNEL); |
222 | if (!buf) | 207 | if (!buf) |
223 | return -ENOMEM; | 208 | return -ENOMEM; |
224 | 209 | ||
225 | st = copy_from_user(buf, ubuf, cnt); | 210 | st = copy_from_user(buf, ubuf, cnt); |
211 | if (!st) | ||
212 | st = rsxx_creg_write(card, CREG_ADD_CRAM + (u32)*ppos, cnt, | ||
213 | buf, 1); | ||
214 | kfree(buf); | ||
226 | if (st) | 215 | if (st) |
227 | return st; | 216 | return st; |
228 | 217 | *ppos += cnt; | |
229 | info->f_pos = (u32)*ppos + info->offset; | ||
230 | |||
231 | st = rsxx_creg_write(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1); | ||
232 | if (st) | ||
233 | return st; | ||
234 | |||
235 | info->offset += cnt; | ||
236 | |||
237 | kfree(buf); | ||
238 | |||
239 | return cnt; | 218 | return cnt; |
240 | } | 219 | } |
241 | 220 | ||
242 | static int rsxx_cram_open(struct inode *inode, struct file *file) | ||
243 | { | ||
244 | struct rsxx_cram *info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
245 | if (!info) | ||
246 | return -ENOMEM; | ||
247 | |||
248 | info->i_private = inode->i_private; | ||
249 | info->f_pos = file->f_pos; | ||
250 | file->private_data = info; | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int rsxx_cram_release(struct inode *inode, struct file *file) | ||
256 | { | ||
257 | struct rsxx_cram *info = file->private_data; | ||
258 | |||
259 | if (!info) | ||
260 | return 0; | ||
261 | |||
262 | kfree(info); | ||
263 | file->private_data = NULL; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct file_operations debugfs_cram_fops = { | 221 | static const struct file_operations debugfs_cram_fops = { |
269 | .owner = THIS_MODULE, | 222 | .owner = THIS_MODULE, |
270 | .open = rsxx_cram_open, | ||
271 | .read = rsxx_cram_read, | 223 | .read = rsxx_cram_read, |
272 | .write = rsxx_cram_write, | 224 | .write = rsxx_cram_write, |
273 | .release = rsxx_cram_release, | ||
274 | }; | 225 | }; |
275 | 226 | ||
276 | static const struct file_operations debugfs_stats_fops = { | 227 | static const struct file_operations debugfs_stats_fops = { |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 5bb5872ffee6..6653473f2757 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -160,13 +160,11 @@ static int vhci_create_device(struct vhci_data *data, __u8 opcode) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | static inline ssize_t vhci_get_user(struct vhci_data *data, | 162 | static inline ssize_t vhci_get_user(struct vhci_data *data, |
163 | const struct iovec *iov, | 163 | struct iov_iter *from) |
164 | unsigned long count) | ||
165 | { | 164 | { |
166 | size_t len = iov_length(iov, count); | 165 | size_t len = iov_iter_count(from); |
167 | struct sk_buff *skb; | 166 | struct sk_buff *skb; |
168 | __u8 pkt_type, opcode; | 167 | __u8 pkt_type, opcode; |
169 | unsigned long i; | ||
170 | int ret; | 168 | int ret; |
171 | 169 | ||
172 | if (len < 2 || len > HCI_MAX_FRAME_SIZE) | 170 | if (len < 2 || len > HCI_MAX_FRAME_SIZE) |
@@ -176,12 +174,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, | |||
176 | if (!skb) | 174 | if (!skb) |
177 | return -ENOMEM; | 175 | return -ENOMEM; |
178 | 176 | ||
179 | for (i = 0; i < count; i++) { | 177 | if (copy_from_iter(skb_put(skb, len), len, from) != len) { |
180 | if (copy_from_user(skb_put(skb, iov[i].iov_len), | 178 | kfree_skb(skb); |
181 | iov[i].iov_base, iov[i].iov_len)) { | 179 | return -EFAULT; |
182 | kfree_skb(skb); | ||
183 | return -EFAULT; | ||
184 | } | ||
185 | } | 180 | } |
186 | 181 | ||
187 | pkt_type = *((__u8 *) skb->data); | 182 | pkt_type = *((__u8 *) skb->data); |
@@ -294,13 +289,12 @@ static ssize_t vhci_read(struct file *file, | |||
294 | return ret; | 289 | return ret; |
295 | } | 290 | } |
296 | 291 | ||
297 | static ssize_t vhci_write(struct kiocb *iocb, const struct iovec *iov, | 292 | static ssize_t vhci_write(struct kiocb *iocb, struct iov_iter *from) |
298 | unsigned long count, loff_t pos) | ||
299 | { | 293 | { |
300 | struct file *file = iocb->ki_filp; | 294 | struct file *file = iocb->ki_filp; |
301 | struct vhci_data *data = file->private_data; | 295 | struct vhci_data *data = file->private_data; |
302 | 296 | ||
303 | return vhci_get_user(data, iov, count); | 297 | return vhci_get_user(data, from); |
304 | } | 298 | } |
305 | 299 | ||
306 | static unsigned int vhci_poll(struct file *file, poll_table *wait) | 300 | static unsigned int vhci_poll(struct file *file, poll_table *wait) |
@@ -365,7 +359,7 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
365 | static const struct file_operations vhci_fops = { | 359 | static const struct file_operations vhci_fops = { |
366 | .owner = THIS_MODULE, | 360 | .owner = THIS_MODULE, |
367 | .read = vhci_read, | 361 | .read = vhci_read, |
368 | .aio_write = vhci_write, | 362 | .write_iter = vhci_write, |
369 | .poll = vhci_poll, | 363 | .poll = vhci_poll, |
370 | .open = vhci_open, | 364 | .open = vhci_open, |
371 | .release = vhci_release, | 365 | .release = vhci_release, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 917403fe10da..524b707894ef 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -622,53 +622,23 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out, | |||
622 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); | 622 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); |
623 | } | 623 | } |
624 | 624 | ||
625 | static ssize_t read_zero(struct file *file, char __user *buf, | 625 | static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter) |
626 | size_t count, loff_t *ppos) | ||
627 | { | 626 | { |
628 | size_t written; | 627 | size_t written = 0; |
629 | |||
630 | if (!count) | ||
631 | return 0; | ||
632 | |||
633 | if (!access_ok(VERIFY_WRITE, buf, count)) | ||
634 | return -EFAULT; | ||
635 | |||
636 | written = 0; | ||
637 | while (count) { | ||
638 | unsigned long unwritten; | ||
639 | size_t chunk = count; | ||
640 | 628 | ||
629 | while (iov_iter_count(iter)) { | ||
630 | size_t chunk = iov_iter_count(iter), n; | ||
641 | if (chunk > PAGE_SIZE) | 631 | if (chunk > PAGE_SIZE) |
642 | chunk = PAGE_SIZE; /* Just for latency reasons */ | 632 | chunk = PAGE_SIZE; /* Just for latency reasons */ |
643 | unwritten = __clear_user(buf, chunk); | 633 | n = iov_iter_zero(chunk, iter); |
644 | written += chunk - unwritten; | 634 | if (!n && iov_iter_count(iter)) |
645 | if (unwritten) | 635 | return written ? written : -EFAULT; |
646 | break; | 636 | written += n; |
647 | if (signal_pending(current)) | 637 | if (signal_pending(current)) |
648 | return written ? written : -ERESTARTSYS; | 638 | return written ? written : -ERESTARTSYS; |
649 | buf += chunk; | ||
650 | count -= chunk; | ||
651 | cond_resched(); | 639 | cond_resched(); |
652 | } | 640 | } |
653 | return written ? written : -EFAULT; | 641 | return written; |
654 | } | ||
655 | |||
656 | static ssize_t aio_read_zero(struct kiocb *iocb, const struct iovec *iov, | ||
657 | unsigned long nr_segs, loff_t pos) | ||
658 | { | ||
659 | size_t written = 0; | ||
660 | unsigned long i; | ||
661 | ssize_t ret; | ||
662 | |||
663 | for (i = 0; i < nr_segs; i++) { | ||
664 | ret = read_zero(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len, | ||
665 | &pos); | ||
666 | if (ret < 0) | ||
667 | break; | ||
668 | written += ret; | ||
669 | } | ||
670 | |||
671 | return written ? written : -EFAULT; | ||
672 | } | 642 | } |
673 | 643 | ||
674 | static int mmap_zero(struct file *file, struct vm_area_struct *vma) | 644 | static int mmap_zero(struct file *file, struct vm_area_struct *vma) |
@@ -738,7 +708,6 @@ static int open_port(struct inode *inode, struct file *filp) | |||
738 | #define zero_lseek null_lseek | 708 | #define zero_lseek null_lseek |
739 | #define full_lseek null_lseek | 709 | #define full_lseek null_lseek |
740 | #define write_zero write_null | 710 | #define write_zero write_null |
741 | #define read_full read_zero | ||
742 | #define aio_write_zero aio_write_null | 711 | #define aio_write_zero aio_write_null |
743 | #define open_mem open_port | 712 | #define open_mem open_port |
744 | #define open_kmem open_mem | 713 | #define open_kmem open_mem |
@@ -783,9 +752,9 @@ static const struct file_operations port_fops = { | |||
783 | 752 | ||
784 | static const struct file_operations zero_fops = { | 753 | static const struct file_operations zero_fops = { |
785 | .llseek = zero_lseek, | 754 | .llseek = zero_lseek, |
786 | .read = read_zero, | 755 | .read = new_sync_read, |
787 | .write = write_zero, | 756 | .write = write_zero, |
788 | .aio_read = aio_read_zero, | 757 | .read_iter = read_iter_zero, |
789 | .aio_write = aio_write_zero, | 758 | .aio_write = aio_write_zero, |
790 | .mmap = mmap_zero, | 759 | .mmap = mmap_zero, |
791 | }; | 760 | }; |
@@ -802,7 +771,8 @@ static struct backing_dev_info zero_bdi = { | |||
802 | 771 | ||
803 | static const struct file_operations full_fops = { | 772 | static const struct file_operations full_fops = { |
804 | .llseek = full_lseek, | 773 | .llseek = full_lseek, |
805 | .read = read_full, | 774 | .read = new_sync_read, |
775 | .read_iter = read_iter_zero, | ||
806 | .write = write_full, | 776 | .write = write_full, |
807 | }; | 777 | }; |
808 | 778 | ||
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index f3014c448e1e..5be225c2ba98 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c | |||
@@ -799,7 +799,7 @@ static int dma_buf_describe(struct seq_file *s) | |||
799 | seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", | 799 | seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", |
800 | buf_obj->size, | 800 | buf_obj->size, |
801 | buf_obj->file->f_flags, buf_obj->file->f_mode, | 801 | buf_obj->file->f_flags, buf_obj->file->f_mode, |
802 | (long)(buf_obj->file->f_count.counter), | 802 | file_count(buf_obj->file), |
803 | buf_obj->exp_name); | 803 | buf_obj->exp_name); |
804 | 804 | ||
805 | seq_puts(s, "\tAttached Devices:\n"); | 805 | seq_puts(s, "\tAttached Devices:\n"); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_nvif.c b/drivers/gpu/drm/nouveau/nouveau_nvif.c index 47ca88623753..6544b84f0303 100644 --- a/drivers/gpu/drm/nouveau/nouveau_nvif.c +++ b/drivers/gpu/drm/nouveau/nouveau_nvif.c | |||
@@ -40,12 +40,12 @@ | |||
40 | #include "nouveau_usif.h" | 40 | #include "nouveau_usif.h" |
41 | 41 | ||
42 | static void | 42 | static void |
43 | nvkm_client_unmap(void *priv, void *ptr, u32 size) | 43 | nvkm_client_unmap(void *priv, void __iomem *ptr, u32 size) |
44 | { | 44 | { |
45 | iounmap(ptr); | 45 | iounmap(ptr); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void * | 48 | static void __iomem * |
49 | nvkm_client_map(void *priv, u64 handle, u32 size) | 49 | nvkm_client_map(void *priv, u64 handle, u32 size) |
50 | { | 50 | { |
51 | return ioremap(handle, size); | 51 | return ioremap(handle, size); |
diff --git a/drivers/gpu/drm/nouveau/nvif/driver.h b/drivers/gpu/drm/nouveau/nvif/driver.h index b72a8f0c2758..ac4bdb3ea506 100644 --- a/drivers/gpu/drm/nouveau/nvif/driver.h +++ b/drivers/gpu/drm/nouveau/nvif/driver.h | |||
@@ -9,8 +9,8 @@ struct nvif_driver { | |||
9 | int (*suspend)(void *priv); | 9 | int (*suspend)(void *priv); |
10 | int (*resume)(void *priv); | 10 | int (*resume)(void *priv); |
11 | int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack); | 11 | int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack); |
12 | void *(*map)(void *priv, u64 handle, u32 size); | 12 | void __iomem *(*map)(void *priv, u64 handle, u32 size); |
13 | void (*unmap)(void *priv, void *ptr, u32 size); | 13 | void (*unmap)(void *priv, void __iomem *ptr, u32 size); |
14 | bool keep; | 14 | bool keep; |
15 | }; | 15 | }; |
16 | 16 | ||
diff --git a/drivers/gpu/drm/nouveau/nvif/object.h b/drivers/gpu/drm/nouveau/nvif/object.h index fac3a3bbec44..fe519179b76c 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.h +++ b/drivers/gpu/drm/nouveau/nvif/object.h | |||
@@ -14,7 +14,7 @@ struct nvif_object { | |||
14 | void *priv; /*XXX: hack */ | 14 | void *priv; /*XXX: hack */ |
15 | void (*dtor)(struct nvif_object *); | 15 | void (*dtor)(struct nvif_object *); |
16 | struct { | 16 | struct { |
17 | void *ptr; | 17 | void __iomem *ptr; |
18 | u32 size; | 18 | u32 size; |
19 | } map; | 19 | } map; |
20 | }; | 20 | }; |
@@ -42,7 +42,7 @@ void nvif_object_unmap(struct nvif_object *); | |||
42 | struct nvif_object *_object = nvif_object(a); \ | 42 | struct nvif_object *_object = nvif_object(a); \ |
43 | u32 _data; \ | 43 | u32 _data; \ |
44 | if (likely(_object->map.ptr)) \ | 44 | if (likely(_object->map.ptr)) \ |
45 | _data = ioread##b##_native((u8 *)_object->map.ptr + (c)); \ | 45 | _data = ioread##b##_native((u8 __iomem *)_object->map.ptr + (c)); \ |
46 | else \ | 46 | else \ |
47 | _data = nvif_object_rd(_object, (b) / 8, (c)); \ | 47 | _data = nvif_object_rd(_object, (b) / 8, (c)); \ |
48 | _data; \ | 48 | _data; \ |
@@ -50,7 +50,7 @@ void nvif_object_unmap(struct nvif_object *); | |||
50 | #define nvif_wr(a,b,c,d) ({ \ | 50 | #define nvif_wr(a,b,c,d) ({ \ |
51 | struct nvif_object *_object = nvif_object(a); \ | 51 | struct nvif_object *_object = nvif_object(a); \ |
52 | if (likely(_object->map.ptr)) \ | 52 | if (likely(_object->map.ptr)) \ |
53 | iowrite##b##_native((d), (u8 *)_object->map.ptr + (c)); \ | 53 | iowrite##b##_native((d), (u8 __iomem *)_object->map.ptr + (c)); \ |
54 | else \ | 54 | else \ |
55 | nvif_object_wr(_object, (b) / 8, (c), (d)); \ | 55 | nvif_object_wr(_object, (b) / 8, (c), (d)); \ |
56 | }) | 56 | }) |
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index e0c404bdc4a8..4977082e081f 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
@@ -82,7 +82,6 @@ static int create_file(const char *name, umode_t mode, | |||
82 | { | 82 | { |
83 | int error; | 83 | int error; |
84 | 84 | ||
85 | *dentry = NULL; | ||
86 | mutex_lock(&parent->d_inode->i_mutex); | 85 | mutex_lock(&parent->d_inode->i_mutex); |
87 | *dentry = lookup_one_len(name, parent, strlen(name)); | 86 | *dentry = lookup_one_len(name, parent, strlen(name)); |
88 | if (!IS_ERR(*dentry)) | 87 | if (!IS_ERR(*dentry)) |
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index cab610ccd50e..81854586c081 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -89,7 +89,6 @@ static int create_file(const char *name, umode_t mode, | |||
89 | { | 89 | { |
90 | int error; | 90 | int error; |
91 | 91 | ||
92 | *dentry = NULL; | ||
93 | mutex_lock(&parent->d_inode->i_mutex); | 92 | mutex_lock(&parent->d_inode->i_mutex); |
94 | *dentry = lookup_one_len(name, parent, strlen(name)); | 93 | *dentry = lookup_one_len(name, parent, strlen(name)); |
95 | if (!IS_ERR(*dentry)) | 94 | if (!IS_ERR(*dentry)) |
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index 7be89832db19..7e97e53f9ff2 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c | |||
@@ -749,13 +749,8 @@ static ssize_t fpga_read(struct file *filp, char __user *buf, size_t count, | |||
749 | loff_t *f_pos) | 749 | loff_t *f_pos) |
750 | { | 750 | { |
751 | struct fpga_dev *priv = filp->private_data; | 751 | struct fpga_dev *priv = filp->private_data; |
752 | 752 | return simple_read_from_buffer(buf, count, ppos, | |
753 | count = min_t(size_t, priv->bytes - *f_pos, count); | 753 | priv->vb.vaddr, priv->bytes); |
754 | if (copy_to_user(buf, priv->vb.vaddr + *f_pos, count)) | ||
755 | return -EFAULT; | ||
756 | |||
757 | *f_pos += count; | ||
758 | return count; | ||
759 | } | 754 | } |
760 | 755 | ||
761 | static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin) | 756 | static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin) |
@@ -767,26 +762,7 @@ static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin) | |||
767 | if ((filp->f_flags & O_ACCMODE) != O_RDONLY) | 762 | if ((filp->f_flags & O_ACCMODE) != O_RDONLY) |
768 | return -EINVAL; | 763 | return -EINVAL; |
769 | 764 | ||
770 | switch (origin) { | 765 | return fixed_size_llseek(file, offset, origin, priv->fw_size); |
771 | case SEEK_SET: /* seek relative to the beginning of the file */ | ||
772 | newpos = offset; | ||
773 | break; | ||
774 | case SEEK_CUR: /* seek relative to current position in the file */ | ||
775 | newpos = filp->f_pos + offset; | ||
776 | break; | ||
777 | case SEEK_END: /* seek relative to the end of the file */ | ||
778 | newpos = priv->fw_size - offset; | ||
779 | break; | ||
780 | default: | ||
781 | return -EINVAL; | ||
782 | } | ||
783 | |||
784 | /* check for sanity */ | ||
785 | if (newpos > priv->fw_size) | ||
786 | return -EINVAL; | ||
787 | |||
788 | filp->f_pos = newpos; | ||
789 | return newpos; | ||
790 | } | 766 | } |
791 | 767 | ||
792 | static const struct file_operations fpga_fops = { | 768 | static const struct file_operations fpga_fops = { |
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 80e6f3430f65..68c3a3f4e0ab 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
@@ -594,7 +594,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
594 | if (file == ppp->owner) | 594 | if (file == ppp->owner) |
595 | ppp_shutdown_interface(ppp); | 595 | ppp_shutdown_interface(ppp); |
596 | } | 596 | } |
597 | if (atomic_long_read(&file->f_count) <= 2) { | 597 | if (atomic_long_read(&file->f_count) < 2) { |
598 | ppp_release(NULL, file); | 598 | ppp_release(NULL, file); |
599 | err = 0; | 599 | err = 0; |
600 | } else | 600 | } else |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a8848db7b09d..9bb48d70957c 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -338,7 +338,6 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) | |||
338 | 338 | ||
339 | /* set the file options */ | 339 | /* set the file options */ |
340 | filp->private_data = logptr; | 340 | filp->private_data = logptr; |
341 | filp->f_op = &vmlogrdr_fops; | ||
342 | 341 | ||
343 | /* start recording for this service*/ | 342 | /* start recording for this service*/ |
344 | if (logptr->autorecording) { | 343 | if (logptr->autorecording) { |
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 713a97226787..ad4f5790a76f 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
@@ -339,7 +339,7 @@ static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin) | |||
339 | goto out; | 339 | goto out; |
340 | } | 340 | } |
341 | 341 | ||
342 | ret = asma->file->f_op->llseek(asma->file, offset, origin); | 342 | ret = vfs_llseek(asma->file, offset, origin); |
343 | if (ret < 0) | 343 | if (ret < 0) |
344 | goto out; | 344 | goto out; |
345 | 345 | ||
diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index ee3a7380e53b..a402fdaf54ca 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c | |||
@@ -125,7 +125,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
125 | { | 125 | { |
126 | long ret; | 126 | long ret; |
127 | 127 | ||
128 | if (!filp->f_op || !filp->f_op->unlocked_ioctl) | 128 | if (!filp->f_op->unlocked_ioctl) |
129 | return -ENOTTY; | 129 | return -ENOTTY; |
130 | 130 | ||
131 | switch (cmd) { | 131 | switch (cmd) { |
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 0bf0d24d12d5..28b93d39a94e 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c | |||
@@ -411,69 +411,18 @@ static void fix_up_readers(struct logger_log *log, size_t len) | |||
411 | } | 411 | } |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * do_write_log - writes 'len' bytes from 'buf' to 'log' | 414 | * logger_write_iter - our write method, implementing support for write(), |
415 | * | ||
416 | * The caller needs to hold log->mutex. | ||
417 | */ | ||
418 | static void do_write_log(struct logger_log *log, const void *buf, size_t count) | ||
419 | { | ||
420 | size_t len; | ||
421 | |||
422 | len = min(count, log->size - log->w_off); | ||
423 | memcpy(log->buffer + log->w_off, buf, len); | ||
424 | |||
425 | if (count != len) | ||
426 | memcpy(log->buffer, buf + len, count - len); | ||
427 | |||
428 | log->w_off = logger_offset(log, log->w_off + count); | ||
429 | |||
430 | } | ||
431 | |||
432 | /* | ||
433 | * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to | ||
434 | * the log 'log' | ||
435 | * | ||
436 | * The caller needs to hold log->mutex. | ||
437 | * | ||
438 | * Returns 'count' on success, negative error code on failure. | ||
439 | */ | ||
440 | static ssize_t do_write_log_from_user(struct logger_log *log, | ||
441 | const void __user *buf, size_t count) | ||
442 | { | ||
443 | size_t len; | ||
444 | |||
445 | len = min(count, log->size - log->w_off); | ||
446 | if (len && copy_from_user(log->buffer + log->w_off, buf, len)) | ||
447 | return -EFAULT; | ||
448 | |||
449 | if (count != len) | ||
450 | if (copy_from_user(log->buffer, buf + len, count - len)) | ||
451 | /* | ||
452 | * Note that by not updating w_off, this abandons the | ||
453 | * portion of the new entry that *was* successfully | ||
454 | * copied, just above. This is intentional to avoid | ||
455 | * message corruption from missing fragments. | ||
456 | */ | ||
457 | return -EFAULT; | ||
458 | |||
459 | log->w_off = logger_offset(log, log->w_off + count); | ||
460 | |||
461 | return count; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * logger_aio_write - our write method, implementing support for write(), | ||
466 | * writev(), and aio_write(). Writes are our fast path, and we try to optimize | 415 | * writev(), and aio_write(). Writes are our fast path, and we try to optimize |
467 | * them above all else. | 416 | * them above all else. |
468 | */ | 417 | */ |
469 | static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, | 418 | static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) |
470 | unsigned long nr_segs, loff_t ppos) | ||
471 | { | 419 | { |
472 | struct logger_log *log = file_get_log(iocb->ki_filp); | 420 | struct logger_log *log = file_get_log(iocb->ki_filp); |
473 | size_t orig; | ||
474 | struct logger_entry header; | 421 | struct logger_entry header; |
475 | struct timespec now; | 422 | struct timespec now; |
476 | ssize_t ret = 0; | 423 | size_t len, count; |
424 | |||
425 | count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); | ||
477 | 426 | ||
478 | now = current_kernel_time(); | 427 | now = current_kernel_time(); |
479 | 428 | ||
@@ -482,7 +431,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
482 | header.sec = now.tv_sec; | 431 | header.sec = now.tv_sec; |
483 | header.nsec = now.tv_nsec; | 432 | header.nsec = now.tv_nsec; |
484 | header.euid = current_euid(); | 433 | header.euid = current_euid(); |
485 | header.len = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); | 434 | header.len = count; |
486 | header.hdr_size = sizeof(struct logger_entry); | 435 | header.hdr_size = sizeof(struct logger_entry); |
487 | 436 | ||
488 | /* null writes succeed, return zero */ | 437 | /* null writes succeed, return zero */ |
@@ -491,8 +440,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
491 | 440 | ||
492 | mutex_lock(&log->mutex); | 441 | mutex_lock(&log->mutex); |
493 | 442 | ||
494 | orig = log->w_off; | ||
495 | |||
496 | /* | 443 | /* |
497 | * Fix up any readers, pulling them forward to the first readable | 444 | * Fix up any readers, pulling them forward to the first readable |
498 | * entry after (what will be) the new write offset. We do this now | 445 | * entry after (what will be) the new write offset. We do this now |
@@ -501,33 +448,35 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
501 | */ | 448 | */ |
502 | fix_up_readers(log, sizeof(struct logger_entry) + header.len); | 449 | fix_up_readers(log, sizeof(struct logger_entry) + header.len); |
503 | 450 | ||
504 | do_write_log(log, &header, sizeof(struct logger_entry)); | 451 | len = min(sizeof(header), log->size - log->w_off); |
505 | 452 | memcpy(log->buffer + log->w_off, &header, len); | |
506 | while (nr_segs-- > 0) { | 453 | memcpy(log->buffer, (char *)&header + len, sizeof(header) - len); |
507 | size_t len; | ||
508 | ssize_t nr; | ||
509 | 454 | ||
510 | /* figure out how much of this vector we can keep */ | 455 | len = min(count, log->size - log->w_off); |
511 | len = min_t(size_t, iov->iov_len, header.len - ret); | ||
512 | 456 | ||
513 | /* write out this segment's payload */ | 457 | if (copy_from_iter(log->buffer + log->w_off, len, from) != len) { |
514 | nr = do_write_log_from_user(log, iov->iov_base, len); | 458 | /* |
515 | if (unlikely(nr < 0)) { | 459 | * Note that by not updating w_off, this abandons the |
516 | log->w_off = orig; | 460 | * portion of the new entry that *was* successfully |
517 | mutex_unlock(&log->mutex); | 461 | * copied, just above. This is intentional to avoid |
518 | return nr; | 462 | * message corruption from missing fragments. |
519 | } | 463 | */ |
464 | mutex_unlock(&log->mutex); | ||
465 | return -EFAULT; | ||
466 | } | ||
520 | 467 | ||
521 | iov++; | 468 | if (copy_from_iter(log->buffer, count - len, from) != count - len) { |
522 | ret += nr; | 469 | mutex_unlock(&log->mutex); |
470 | return -EFAULT; | ||
523 | } | 471 | } |
524 | 472 | ||
473 | log->w_off = logger_offset(log, log->w_off + count); | ||
525 | mutex_unlock(&log->mutex); | 474 | mutex_unlock(&log->mutex); |
526 | 475 | ||
527 | /* wake up any blocked readers */ | 476 | /* wake up any blocked readers */ |
528 | wake_up_interruptible(&log->wq); | 477 | wake_up_interruptible(&log->wq); |
529 | 478 | ||
530 | return ret; | 479 | return len; |
531 | } | 480 | } |
532 | 481 | ||
533 | static struct logger_log *get_log_from_minor(int minor) | 482 | static struct logger_log *get_log_from_minor(int minor) |
@@ -736,7 +685,7 @@ static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
736 | static const struct file_operations logger_fops = { | 685 | static const struct file_operations logger_fops = { |
737 | .owner = THIS_MODULE, | 686 | .owner = THIS_MODULE, |
738 | .read = logger_read, | 687 | .read = logger_read, |
739 | .aio_write = logger_aio_write, | 688 | .write_iter = logger_write_iter, |
740 | .poll = logger_poll, | 689 | .poll = logger_poll, |
741 | .unlocked_ioctl = logger_ioctl, | 690 | .unlocked_ioctl = logger_ioctl, |
742 | .compat_ioctl = logger_ioctl, | 691 | .compat_ioctl = logger_ioctl, |
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 73cec14cbf56..8b1f53331433 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c | |||
@@ -410,41 +410,19 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, | |||
410 | 410 | ||
411 | static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) | 411 | static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) |
412 | { | 412 | { |
413 | loff_t absolute = -1; | ||
414 | unsigned int minor = MINOR(file_inode(file)->i_rdev); | 413 | unsigned int minor = MINOR(file_inode(file)->i_rdev); |
415 | size_t image_size; | 414 | size_t image_size; |
415 | loff_t res; | ||
416 | 416 | ||
417 | if (minor == CONTROL_MINOR) | 417 | if (minor == CONTROL_MINOR) |
418 | return -EINVAL; | 418 | return -EINVAL; |
419 | 419 | ||
420 | mutex_lock(&image[minor].mutex); | 420 | mutex_lock(&image[minor].mutex); |
421 | image_size = vme_get_size(image[minor].resource); | 421 | image_size = vme_get_size(image[minor].resource); |
422 | 422 | res = fixed_size_llseek(file, off, whence, image_size); | |
423 | switch (whence) { | ||
424 | case SEEK_SET: | ||
425 | absolute = off; | ||
426 | break; | ||
427 | case SEEK_CUR: | ||
428 | absolute = file->f_pos + off; | ||
429 | break; | ||
430 | case SEEK_END: | ||
431 | absolute = image_size + off; | ||
432 | break; | ||
433 | default: | ||
434 | mutex_unlock(&image[minor].mutex); | ||
435 | return -EINVAL; | ||
436 | } | ||
437 | |||
438 | if ((absolute < 0) || (absolute >= image_size)) { | ||
439 | mutex_unlock(&image[minor].mutex); | ||
440 | return -EINVAL; | ||
441 | } | ||
442 | |||
443 | file->f_pos = absolute; | ||
444 | |||
445 | mutex_unlock(&image[minor].mutex); | 423 | mutex_unlock(&image[minor].mutex); |
446 | 424 | ||
447 | return absolute; | 425 | return res; |
448 | } | 426 | } |
449 | 427 | ||
450 | /* | 428 | /* |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 4ad11e03cf54..7c6771d027a2 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -164,10 +164,9 @@ struct ffs_desc_helper { | |||
164 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); | 164 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); |
165 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); | 165 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); |
166 | 166 | ||
167 | static struct inode *__must_check | 167 | static struct dentry * |
168 | ffs_sb_create_file(struct super_block *sb, const char *name, void *data, | 168 | ffs_sb_create_file(struct super_block *sb, const char *name, void *data, |
169 | const struct file_operations *fops, | 169 | const struct file_operations *fops); |
170 | struct dentry **dentry_p); | ||
171 | 170 | ||
172 | /* Devices management *******************************************************/ | 171 | /* Devices management *******************************************************/ |
173 | 172 | ||
@@ -1119,10 +1118,9 @@ ffs_sb_make_inode(struct super_block *sb, void *data, | |||
1119 | } | 1118 | } |
1120 | 1119 | ||
1121 | /* Create "regular" file */ | 1120 | /* Create "regular" file */ |
1122 | static struct inode *ffs_sb_create_file(struct super_block *sb, | 1121 | static struct dentry *ffs_sb_create_file(struct super_block *sb, |
1123 | const char *name, void *data, | 1122 | const char *name, void *data, |
1124 | const struct file_operations *fops, | 1123 | const struct file_operations *fops) |
1125 | struct dentry **dentry_p) | ||
1126 | { | 1124 | { |
1127 | struct ffs_data *ffs = sb->s_fs_info; | 1125 | struct ffs_data *ffs = sb->s_fs_info; |
1128 | struct dentry *dentry; | 1126 | struct dentry *dentry; |
@@ -1141,10 +1139,7 @@ static struct inode *ffs_sb_create_file(struct super_block *sb, | |||
1141 | } | 1139 | } |
1142 | 1140 | ||
1143 | d_add(dentry, inode); | 1141 | d_add(dentry, inode); |
1144 | if (dentry_p) | 1142 | return dentry; |
1145 | *dentry_p = dentry; | ||
1146 | |||
1147 | return inode; | ||
1148 | } | 1143 | } |
1149 | 1144 | ||
1150 | /* Super block */ | 1145 | /* Super block */ |
@@ -1189,7 +1184,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | |||
1189 | 1184 | ||
1190 | /* EP0 file */ | 1185 | /* EP0 file */ |
1191 | if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, | 1186 | if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, |
1192 | &ffs_ep0_operations, NULL))) | 1187 | &ffs_ep0_operations))) |
1193 | return -ENOMEM; | 1188 | return -ENOMEM; |
1194 | 1189 | ||
1195 | return 0; | 1190 | return 0; |
@@ -1561,9 +1556,10 @@ static int ffs_epfiles_create(struct ffs_data *ffs) | |||
1561 | sprintf(epfiles->name, "ep%02x", ffs->eps_addrmap[i]); | 1556 | sprintf(epfiles->name, "ep%02x", ffs->eps_addrmap[i]); |
1562 | else | 1557 | else |
1563 | sprintf(epfiles->name, "ep%u", i); | 1558 | sprintf(epfiles->name, "ep%u", i); |
1564 | if (!unlikely(ffs_sb_create_file(ffs->sb, epfiles->name, epfile, | 1559 | epfile->dentry = ffs_sb_create_file(ffs->sb, epfiles->name, |
1565 | &ffs_epfile_operations, | 1560 | epfile, |
1566 | &epfile->dentry))) { | 1561 | &ffs_epfile_operations); |
1562 | if (unlikely(!epfile->dentry)) { | ||
1567 | ffs_epfiles_destroy(epfiles, i - 1); | 1563 | ffs_epfiles_destroy(epfiles, i - 1); |
1568 | return -ENOMEM; | 1564 | return -ENOMEM; |
1569 | } | 1565 | } |
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index edefec2cc584..c744e4975d74 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -198,7 +198,6 @@ struct ep_data { | |||
198 | struct list_head epfiles; | 198 | struct list_head epfiles; |
199 | wait_queue_head_t wait; | 199 | wait_queue_head_t wait; |
200 | struct dentry *dentry; | 200 | struct dentry *dentry; |
201 | struct inode *inode; | ||
202 | }; | 201 | }; |
203 | 202 | ||
204 | static inline void get_ep (struct ep_data *data) | 203 | static inline void get_ep (struct ep_data *data) |
@@ -1618,10 +1617,9 @@ static void destroy_ep_files (struct dev_data *dev) | |||
1618 | } | 1617 | } |
1619 | 1618 | ||
1620 | 1619 | ||
1621 | static struct inode * | 1620 | static struct dentry * |
1622 | gadgetfs_create_file (struct super_block *sb, char const *name, | 1621 | gadgetfs_create_file (struct super_block *sb, char const *name, |
1623 | void *data, const struct file_operations *fops, | 1622 | void *data, const struct file_operations *fops); |
1624 | struct dentry **dentry_p); | ||
1625 | 1623 | ||
1626 | static int activate_ep_files (struct dev_data *dev) | 1624 | static int activate_ep_files (struct dev_data *dev) |
1627 | { | 1625 | { |
@@ -1649,10 +1647,9 @@ static int activate_ep_files (struct dev_data *dev) | |||
1649 | if (!data->req) | 1647 | if (!data->req) |
1650 | goto enomem1; | 1648 | goto enomem1; |
1651 | 1649 | ||
1652 | data->inode = gadgetfs_create_file (dev->sb, data->name, | 1650 | data->dentry = gadgetfs_create_file (dev->sb, data->name, |
1653 | data, &ep_config_operations, | 1651 | data, &ep_config_operations); |
1654 | &data->dentry); | 1652 | if (!data->dentry) |
1655 | if (!data->inode) | ||
1656 | goto enomem2; | 1653 | goto enomem2; |
1657 | list_add_tail (&data->epfiles, &dev->epfiles); | 1654 | list_add_tail (&data->epfiles, &dev->epfiles); |
1658 | } | 1655 | } |
@@ -2012,10 +2009,9 @@ gadgetfs_make_inode (struct super_block *sb, | |||
2012 | /* creates in fs root directory, so non-renamable and non-linkable. | 2009 | /* creates in fs root directory, so non-renamable and non-linkable. |
2013 | * so inode and dentry are paired, until device reconfig. | 2010 | * so inode and dentry are paired, until device reconfig. |
2014 | */ | 2011 | */ |
2015 | static struct inode * | 2012 | static struct dentry * |
2016 | gadgetfs_create_file (struct super_block *sb, char const *name, | 2013 | gadgetfs_create_file (struct super_block *sb, char const *name, |
2017 | void *data, const struct file_operations *fops, | 2014 | void *data, const struct file_operations *fops) |
2018 | struct dentry **dentry_p) | ||
2019 | { | 2015 | { |
2020 | struct dentry *dentry; | 2016 | struct dentry *dentry; |
2021 | struct inode *inode; | 2017 | struct inode *inode; |
@@ -2031,8 +2027,7 @@ gadgetfs_create_file (struct super_block *sb, char const *name, | |||
2031 | return NULL; | 2027 | return NULL; |
2032 | } | 2028 | } |
2033 | d_add (dentry, inode); | 2029 | d_add (dentry, inode); |
2034 | *dentry_p = dentry; | 2030 | return dentry; |
2035 | return inode; | ||
2036 | } | 2031 | } |
2037 | 2032 | ||
2038 | static const struct super_operations gadget_fs_operations = { | 2033 | static const struct super_operations gadget_fs_operations = { |
@@ -2080,9 +2075,8 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) | |||
2080 | goto Enomem; | 2075 | goto Enomem; |
2081 | 2076 | ||
2082 | dev->sb = sb; | 2077 | dev->sb = sb; |
2083 | if (!gadgetfs_create_file (sb, CHIP, | 2078 | dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &dev_init_operations); |
2084 | dev, &dev_init_operations, | 2079 | if (!dev->dentry) { |
2085 | &dev->dentry)) { | ||
2086 | put_dev(dev); | 2080 | put_dev(dev); |
2087 | goto Enomem; | 2081 | goto Enomem; |
2088 | } | 2082 | } |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index d51ec9fafcc8..47db55aee7f2 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -65,8 +65,8 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) | |||
65 | { | 65 | { |
66 | struct p9_fid *fid, *ret; | 66 | struct p9_fid *fid, *ret; |
67 | 67 | ||
68 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", | 68 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p) uid %d any %d\n", |
69 | dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid), | 69 | dentry, dentry, from_kuid(&init_user_ns, uid), |
70 | any); | 70 | any); |
71 | ret = NULL; | 71 | ret = NULL; |
72 | /* we'll recheck under lock if there's anything to look in */ | 72 | /* we'll recheck under lock if there's anything to look in */ |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index cc1cfae726b3..eb14e055ea83 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -266,8 +266,8 @@ v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) | |||
266 | * Now that we do caching with cache mode enabled, We need | 266 | * Now that we do caching with cache mode enabled, We need |
267 | * to support direct IO | 267 | * to support direct IO |
268 | */ | 268 | */ |
269 | p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%s) off/no(%lld/%lu) EINVAL\n", | 269 | p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%pD) off/no(%lld/%lu) EINVAL\n", |
270 | iocb->ki_filp->f_path.dentry->d_name.name, | 270 | iocb->ki_filp, |
271 | (long long)pos, iter->nr_segs); | 271 | (long long)pos, iter->nr_segs); |
272 | 272 | ||
273 | return -EINVAL; | 273 | return -EINVAL; |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index b03dd23feda8..a345b2d659cc 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -49,8 +49,8 @@ | |||
49 | */ | 49 | */ |
50 | static int v9fs_cached_dentry_delete(const struct dentry *dentry) | 50 | static int v9fs_cached_dentry_delete(const struct dentry *dentry) |
51 | { | 51 | { |
52 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", | 52 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", |
53 | dentry->d_name.name, dentry); | 53 | dentry, dentry); |
54 | 54 | ||
55 | /* Don't cache negative dentries */ | 55 | /* Don't cache negative dentries */ |
56 | if (!dentry->d_inode) | 56 | if (!dentry->d_inode) |
@@ -67,8 +67,8 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry) | |||
67 | static void v9fs_dentry_release(struct dentry *dentry) | 67 | static void v9fs_dentry_release(struct dentry *dentry) |
68 | { | 68 | { |
69 | struct hlist_node *p, *n; | 69 | struct hlist_node *p, *n; |
70 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", | 70 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", |
71 | dentry->d_name.name, dentry); | 71 | dentry, dentry); |
72 | hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) | 72 | hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) |
73 | p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); | 73 | p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); |
74 | dentry->d_fsdata = NULL; | 74 | dentry->d_fsdata = NULL; |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 0b3bfa303dda..4f1151088ebe 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -116,7 +116,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) | |||
116 | int reclen = 0; | 116 | int reclen = 0; |
117 | struct p9_rdir *rdir; | 117 | struct p9_rdir *rdir; |
118 | 118 | ||
119 | p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name); | 119 | p9_debug(P9_DEBUG_VFS, "name %pD\n", file); |
120 | fid = file->private_data; | 120 | fid = file->private_data; |
121 | 121 | ||
122 | buflen = fid->clnt->msize - P9_IOHDRSZ; | 122 | buflen = fid->clnt->msize - P9_IOHDRSZ; |
@@ -172,7 +172,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx) | |||
172 | struct p9_rdir *rdir; | 172 | struct p9_rdir *rdir; |
173 | struct p9_dirent curdirent; | 173 | struct p9_dirent curdirent; |
174 | 174 | ||
175 | p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name); | 175 | p9_debug(P9_DEBUG_VFS, "name %pD\n", file); |
176 | fid = file->private_data; | 176 | fid = file->private_data; |
177 | 177 | ||
178 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; | 178 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 520c11c2dcca..5594505e6e73 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -301,8 +301,8 @@ static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) | |||
301 | struct inode *inode = file_inode(filp); | 301 | struct inode *inode = file_inode(filp); |
302 | int ret = -ENOLCK; | 302 | int ret = -ENOLCK; |
303 | 303 | ||
304 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", | 304 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", |
305 | filp, cmd, fl, filp->f_path.dentry->d_name.name); | 305 | filp, cmd, fl, filp); |
306 | 306 | ||
307 | /* No mandatory locks */ | 307 | /* No mandatory locks */ |
308 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) | 308 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) |
@@ -337,8 +337,8 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd, | |||
337 | struct inode *inode = file_inode(filp); | 337 | struct inode *inode = file_inode(filp); |
338 | int ret = -ENOLCK; | 338 | int ret = -ENOLCK; |
339 | 339 | ||
340 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", | 340 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", |
341 | filp, cmd, fl, filp->f_path.dentry->d_name.name); | 341 | filp, cmd, fl, filp); |
342 | 342 | ||
343 | /* No mandatory locks */ | 343 | /* No mandatory locks */ |
344 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) | 344 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7fa4f7a7653d..296482fc77a9 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -648,7 +648,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
648 | struct p9_fid *dfid, *ofid, *fid; | 648 | struct p9_fid *dfid, *ofid, *fid; |
649 | struct inode *inode; | 649 | struct inode *inode; |
650 | 650 | ||
651 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 651 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
652 | 652 | ||
653 | err = 0; | 653 | err = 0; |
654 | ofid = NULL; | 654 | ofid = NULL; |
@@ -755,7 +755,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode | |||
755 | struct p9_fid *fid; | 755 | struct p9_fid *fid; |
756 | struct v9fs_session_info *v9ses; | 756 | struct v9fs_session_info *v9ses; |
757 | 757 | ||
758 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 758 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
759 | err = 0; | 759 | err = 0; |
760 | v9ses = v9fs_inode2v9ses(dir); | 760 | v9ses = v9fs_inode2v9ses(dir); |
761 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 761 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
@@ -791,8 +791,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
791 | struct inode *inode; | 791 | struct inode *inode; |
792 | char *name; | 792 | char *name; |
793 | 793 | ||
794 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p flags: %x\n", | 794 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%pd) %p flags: %x\n", |
795 | dir, dentry->d_name.name, dentry, flags); | 795 | dir, dentry, dentry, flags); |
796 | 796 | ||
797 | if (dentry->d_name.len > NAME_MAX) | 797 | if (dentry->d_name.len > NAME_MAX) |
798 | return ERR_PTR(-ENAMETOOLONG); | 798 | return ERR_PTR(-ENAMETOOLONG); |
@@ -1239,7 +1239,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1239 | struct p9_fid *fid; | 1239 | struct p9_fid *fid; |
1240 | struct p9_wstat *st; | 1240 | struct p9_wstat *st; |
1241 | 1241 | ||
1242 | p9_debug(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | 1242 | p9_debug(P9_DEBUG_VFS, " %pd\n", dentry); |
1243 | retval = -EPERM; | 1243 | retval = -EPERM; |
1244 | v9ses = v9fs_dentry2v9ses(dentry); | 1244 | v9ses = v9fs_dentry2v9ses(dentry); |
1245 | fid = v9fs_fid_lookup(dentry); | 1245 | fid = v9fs_fid_lookup(dentry); |
@@ -1262,8 +1262,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1262 | retval = min(strlen(st->extension)+1, (size_t)buflen); | 1262 | retval = min(strlen(st->extension)+1, (size_t)buflen); |
1263 | memcpy(buffer, st->extension, retval); | 1263 | memcpy(buffer, st->extension, retval); |
1264 | 1264 | ||
1265 | p9_debug(P9_DEBUG_VFS, "%s -> %s (%.*s)\n", | 1265 | p9_debug(P9_DEBUG_VFS, "%pd -> %s (%.*s)\n", |
1266 | dentry->d_name.name, st->extension, buflen, buffer); | 1266 | dentry, st->extension, buflen, buffer); |
1267 | 1267 | ||
1268 | done: | 1268 | done: |
1269 | p9stat_free(st); | 1269 | p9stat_free(st); |
@@ -1283,7 +1283,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1283 | int len = 0; | 1283 | int len = 0; |
1284 | char *link = __getname(); | 1284 | char *link = __getname(); |
1285 | 1285 | ||
1286 | p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name); | 1286 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
1287 | 1287 | ||
1288 | if (!link) | 1288 | if (!link) |
1289 | link = ERR_PTR(-ENOMEM); | 1289 | link = ERR_PTR(-ENOMEM); |
@@ -1314,8 +1314,8 @@ v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | |||
1314 | { | 1314 | { |
1315 | char *s = nd_get_link(nd); | 1315 | char *s = nd_get_link(nd); |
1316 | 1316 | ||
1317 | p9_debug(P9_DEBUG_VFS, " %s %s\n", | 1317 | p9_debug(P9_DEBUG_VFS, " %pd %s\n", |
1318 | dentry->d_name.name, IS_ERR(s) ? "<error>" : s); | 1318 | dentry, IS_ERR(s) ? "<error>" : s); |
1319 | if (!IS_ERR(s)) | 1319 | if (!IS_ERR(s)) |
1320 | __putname(s); | 1320 | __putname(s); |
1321 | } | 1321 | } |
@@ -1364,8 +1364,8 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1364 | static int | 1364 | static int |
1365 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | 1365 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) |
1366 | { | 1366 | { |
1367 | p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n", | 1367 | p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n", |
1368 | dir->i_ino, dentry->d_name.name, symname); | 1368 | dir->i_ino, dentry, symname); |
1369 | 1369 | ||
1370 | return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname); | 1370 | return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname); |
1371 | } | 1371 | } |
@@ -1386,8 +1386,8 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1386 | char *name; | 1386 | char *name; |
1387 | struct p9_fid *oldfid; | 1387 | struct p9_fid *oldfid; |
1388 | 1388 | ||
1389 | p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n", | 1389 | p9_debug(P9_DEBUG_VFS, " %lu,%pd,%pd\n", |
1390 | dir->i_ino, dentry->d_name.name, old_dentry->d_name.name); | 1390 | dir->i_ino, dentry, old_dentry); |
1391 | 1391 | ||
1392 | oldfid = v9fs_fid_clone(old_dentry); | 1392 | oldfid = v9fs_fid_clone(old_dentry); |
1393 | if (IS_ERR(oldfid)) | 1393 | if (IS_ERR(oldfid)) |
@@ -1428,8 +1428,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rde | |||
1428 | char *name; | 1428 | char *name; |
1429 | u32 perm; | 1429 | u32 perm; |
1430 | 1430 | ||
1431 | p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n", | 1431 | p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n", |
1432 | dir->i_ino, dentry->d_name.name, mode, | 1432 | dir->i_ino, dentry, mode, |
1433 | MAJOR(rdev), MINOR(rdev)); | 1433 | MAJOR(rdev), MINOR(rdev)); |
1434 | 1434 | ||
1435 | if (!new_valid_dev(rdev)) | 1435 | if (!new_valid_dev(rdev)) |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 1fa85aae24df..02b64f4e576a 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -393,7 +393,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
393 | struct dentry *dir_dentry; | 393 | struct dentry *dir_dentry; |
394 | struct posix_acl *dacl = NULL, *pacl = NULL; | 394 | struct posix_acl *dacl = NULL, *pacl = NULL; |
395 | 395 | ||
396 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 396 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
397 | err = 0; | 397 | err = 0; |
398 | v9ses = v9fs_inode2v9ses(dir); | 398 | v9ses = v9fs_inode2v9ses(dir); |
399 | 399 | ||
@@ -767,8 +767,8 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, | |||
767 | struct p9_fid *dfid, *oldfid; | 767 | struct p9_fid *dfid, *oldfid; |
768 | struct v9fs_session_info *v9ses; | 768 | struct v9fs_session_info *v9ses; |
769 | 769 | ||
770 | p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", | 770 | p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n", |
771 | dir->i_ino, old_dentry->d_name.name, dentry->d_name.name); | 771 | dir->i_ino, old_dentry, dentry); |
772 | 772 | ||
773 | v9ses = v9fs_inode2v9ses(dir); | 773 | v9ses = v9fs_inode2v9ses(dir); |
774 | dir_dentry = dentry->d_parent; | 774 | dir_dentry = dentry->d_parent; |
@@ -917,7 +917,7 @@ v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd) | |||
917 | char *link = __getname(); | 917 | char *link = __getname(); |
918 | char *target; | 918 | char *target; |
919 | 919 | ||
920 | p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name); | 920 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
921 | 921 | ||
922 | if (!link) { | 922 | if (!link) { |
923 | link = ERR_PTR(-ENOMEM); | 923 | link = ERR_PTR(-ENOMEM); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 529300327f45..a1645b88fe8a 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -669,7 +669,6 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
669 | 669 | ||
670 | out_valid: | 670 | out_valid: |
671 | dentry->d_fsdata = dir_version; | 671 | dentry->d_fsdata = dir_version; |
672 | out_skip: | ||
673 | dput(parent); | 672 | dput(parent); |
674 | key_put(key); | 673 | key_put(key); |
675 | _leave(" = 1 [valid]"); | 674 | _leave(" = 1 [valid]"); |
@@ -682,10 +681,6 @@ not_found: | |||
682 | spin_unlock(&dentry->d_lock); | 681 | spin_unlock(&dentry->d_lock); |
683 | 682 | ||
684 | out_bad: | 683 | out_bad: |
685 | /* don't unhash if we have submounts */ | ||
686 | if (check_submounts_and_drop(dentry) != 0) | ||
687 | goto out_skip; | ||
688 | |||
689 | _debug("dropping dentry %s/%s", | 684 | _debug("dropping dentry %s/%s", |
690 | parent->d_name.name, dentry->d_name.name); | 685 | parent->d_name.name, dentry->d_name.name); |
691 | dput(parent); | 686 | dput(parent); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index a7be57e39be7..8fa3895cda02 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -255,12 +255,6 @@ static int autofs4_tree_busy(struct vfsmount *mnt, | |||
255 | struct autofs_info *ino = autofs4_dentry_ino(p); | 255 | struct autofs_info *ino = autofs4_dentry_ino(p); |
256 | unsigned int ino_count = atomic_read(&ino->count); | 256 | unsigned int ino_count = atomic_read(&ino->count); |
257 | 257 | ||
258 | /* | ||
259 | * Clean stale dentries below that have not been | ||
260 | * invalidated after a mount fail during lookup | ||
261 | */ | ||
262 | d_invalidate(p); | ||
263 | |||
264 | /* allow for dget above and top is already dgot */ | 258 | /* allow for dget above and top is already dgot */ |
265 | if (p == top) | 259 | if (p == top) |
266 | ino_count += 2; | 260 | ino_count += 2; |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index ca0ba15a7306..929dec08c348 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -256,11 +256,8 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
256 | (current->mm->start_brk = N_BSSADDR(ex)); | 256 | (current->mm->start_brk = N_BSSADDR(ex)); |
257 | 257 | ||
258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | 258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); |
259 | if (retval < 0) { | 259 | if (retval < 0) |
260 | /* Someone check-me: is this error path enough? */ | ||
261 | send_sig(SIGKILL, current, 0); | ||
262 | return retval; | 260 | return retval; |
263 | } | ||
264 | 261 | ||
265 | install_exec_creds(bprm); | 262 | install_exec_creds(bprm); |
266 | 263 | ||
@@ -278,17 +275,13 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
278 | map_size = ex.a_text+ex.a_data; | 275 | map_size = ex.a_text+ex.a_data; |
279 | #endif | 276 | #endif |
280 | error = vm_brk(text_addr & PAGE_MASK, map_size); | 277 | error = vm_brk(text_addr & PAGE_MASK, map_size); |
281 | if (error != (text_addr & PAGE_MASK)) { | 278 | if (error != (text_addr & PAGE_MASK)) |
282 | send_sig(SIGKILL, current, 0); | ||
283 | return error; | 279 | return error; |
284 | } | ||
285 | 280 | ||
286 | error = read_code(bprm->file, text_addr, pos, | 281 | error = read_code(bprm->file, text_addr, pos, |
287 | ex.a_text+ex.a_data); | 282 | ex.a_text+ex.a_data); |
288 | if ((signed long)error < 0) { | 283 | if ((signed long)error < 0) |
289 | send_sig(SIGKILL, current, 0); | ||
290 | return error; | 284 | return error; |
291 | } | ||
292 | } else { | 285 | } else { |
293 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && | 286 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && |
294 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) | 287 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) |
@@ -315,28 +308,22 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
315 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 308 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
316 | fd_offset); | 309 | fd_offset); |
317 | 310 | ||
318 | if (error != N_TXTADDR(ex)) { | 311 | if (error != N_TXTADDR(ex)) |
319 | send_sig(SIGKILL, current, 0); | ||
320 | return error; | 312 | return error; |
321 | } | ||
322 | 313 | ||
323 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | 314 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
324 | PROT_READ | PROT_WRITE | PROT_EXEC, | 315 | PROT_READ | PROT_WRITE | PROT_EXEC, |
325 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 316 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
326 | fd_offset + ex.a_text); | 317 | fd_offset + ex.a_text); |
327 | if (error != N_DATADDR(ex)) { | 318 | if (error != N_DATADDR(ex)) |
328 | send_sig(SIGKILL, current, 0); | ||
329 | return error; | 319 | return error; |
330 | } | ||
331 | } | 320 | } |
332 | beyond_if: | 321 | beyond_if: |
333 | set_binfmt(&aout_format); | 322 | set_binfmt(&aout_format); |
334 | 323 | ||
335 | retval = set_brk(current->mm->start_brk, current->mm->brk); | 324 | retval = set_brk(current->mm->start_brk, current->mm->brk); |
336 | if (retval < 0) { | 325 | if (retval < 0) |
337 | send_sig(SIGKILL, current, 0); | ||
338 | return retval; | 326 | return retval; |
339 | } | ||
340 | 327 | ||
341 | current->mm->start_stack = | 328 | current->mm->start_stack = |
342 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); | 329 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3892c1a23241..d8fc0605b9d2 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -738,10 +738,8 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
738 | change some of these later */ | 738 | change some of these later */ |
739 | retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), | 739 | retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), |
740 | executable_stack); | 740 | executable_stack); |
741 | if (retval < 0) { | 741 | if (retval < 0) |
742 | send_sig(SIGKILL, current, 0); | ||
743 | goto out_free_dentry; | 742 | goto out_free_dentry; |
744 | } | ||
745 | 743 | ||
746 | current->mm->start_stack = bprm->p; | 744 | current->mm->start_stack = bprm->p; |
747 | 745 | ||
@@ -763,10 +761,8 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
763 | and clear the area. */ | 761 | and clear the area. */ |
764 | retval = set_brk(elf_bss + load_bias, | 762 | retval = set_brk(elf_bss + load_bias, |
765 | elf_brk + load_bias); | 763 | elf_brk + load_bias); |
766 | if (retval) { | 764 | if (retval) |
767 | send_sig(SIGKILL, current, 0); | ||
768 | goto out_free_dentry; | 765 | goto out_free_dentry; |
769 | } | ||
770 | nbyte = ELF_PAGEOFFSET(elf_bss); | 766 | nbyte = ELF_PAGEOFFSET(elf_bss); |
771 | if (nbyte) { | 767 | if (nbyte) { |
772 | nbyte = ELF_MIN_ALIGN - nbyte; | 768 | nbyte = ELF_MIN_ALIGN - nbyte; |
@@ -820,7 +816,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
820 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, | 816 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, |
821 | elf_prot, elf_flags, 0); | 817 | elf_prot, elf_flags, 0); |
822 | if (BAD_ADDR(error)) { | 818 | if (BAD_ADDR(error)) { |
823 | send_sig(SIGKILL, current, 0); | ||
824 | retval = IS_ERR((void *)error) ? | 819 | retval = IS_ERR((void *)error) ? |
825 | PTR_ERR((void*)error) : -EINVAL; | 820 | PTR_ERR((void*)error) : -EINVAL; |
826 | goto out_free_dentry; | 821 | goto out_free_dentry; |
@@ -851,7 +846,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
851 | elf_ppnt->p_memsz > TASK_SIZE || | 846 | elf_ppnt->p_memsz > TASK_SIZE || |
852 | TASK_SIZE - elf_ppnt->p_memsz < k) { | 847 | TASK_SIZE - elf_ppnt->p_memsz < k) { |
853 | /* set_brk can never work. Avoid overflows. */ | 848 | /* set_brk can never work. Avoid overflows. */ |
854 | send_sig(SIGKILL, current, 0); | ||
855 | retval = -EINVAL; | 849 | retval = -EINVAL; |
856 | goto out_free_dentry; | 850 | goto out_free_dentry; |
857 | } | 851 | } |
@@ -883,12 +877,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
883 | * up getting placed where the bss needs to go. | 877 | * up getting placed where the bss needs to go. |
884 | */ | 878 | */ |
885 | retval = set_brk(elf_bss, elf_brk); | 879 | retval = set_brk(elf_bss, elf_brk); |
886 | if (retval) { | 880 | if (retval) |
887 | send_sig(SIGKILL, current, 0); | ||
888 | goto out_free_dentry; | 881 | goto out_free_dentry; |
889 | } | ||
890 | if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { | 882 | if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { |
891 | send_sig(SIGSEGV, current, 0); | ||
892 | retval = -EFAULT; /* Nobody gets to see this, but.. */ | 883 | retval = -EFAULT; /* Nobody gets to see this, but.. */ |
893 | goto out_free_dentry; | 884 | goto out_free_dentry; |
894 | } | 885 | } |
@@ -909,7 +900,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
909 | elf_entry += loc->interp_elf_ex.e_entry; | 900 | elf_entry += loc->interp_elf_ex.e_entry; |
910 | } | 901 | } |
911 | if (BAD_ADDR(elf_entry)) { | 902 | if (BAD_ADDR(elf_entry)) { |
912 | force_sig(SIGSEGV, current); | ||
913 | retval = IS_ERR((void *)elf_entry) ? | 903 | retval = IS_ERR((void *)elf_entry) ? |
914 | (int)elf_entry : -EINVAL; | 904 | (int)elf_entry : -EINVAL; |
915 | goto out_free_dentry; | 905 | goto out_free_dentry; |
@@ -922,7 +912,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
922 | } else { | 912 | } else { |
923 | elf_entry = loc->elf_ex.e_entry; | 913 | elf_entry = loc->elf_ex.e_entry; |
924 | if (BAD_ADDR(elf_entry)) { | 914 | if (BAD_ADDR(elf_entry)) { |
925 | force_sig(SIGSEGV, current); | ||
926 | retval = -EINVAL; | 915 | retval = -EINVAL; |
927 | goto out_free_dentry; | 916 | goto out_free_dentry; |
928 | } | 917 | } |
@@ -934,19 +923,15 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
934 | 923 | ||
935 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES | 924 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES |
936 | retval = arch_setup_additional_pages(bprm, !!elf_interpreter); | 925 | retval = arch_setup_additional_pages(bprm, !!elf_interpreter); |
937 | if (retval < 0) { | 926 | if (retval < 0) |
938 | send_sig(SIGKILL, current, 0); | ||
939 | goto out; | 927 | goto out; |
940 | } | ||
941 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ | 928 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
942 | 929 | ||
943 | install_exec_creds(bprm); | 930 | install_exec_creds(bprm); |
944 | retval = create_elf_tables(bprm, &loc->elf_ex, | 931 | retval = create_elf_tables(bprm, &loc->elf_ex, |
945 | load_addr, interp_load_addr); | 932 | load_addr, interp_load_addr); |
946 | if (retval < 0) { | 933 | if (retval < 0) |
947 | send_sig(SIGKILL, current, 0); | ||
948 | goto out; | 934 | goto out; |
949 | } | ||
950 | /* N.B. passed_fileno might not be initialized? */ | 935 | /* N.B. passed_fileno might not be initialized? */ |
951 | current->mm->end_code = end_code; | 936 | current->mm->end_code = end_code; |
952 | current->mm->start_code = start_code; | 937 | current->mm->start_code = start_code; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index fe2a643ee005..d3634bfb7fe1 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -317,8 +317,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
317 | goto error; | 317 | goto error; |
318 | 318 | ||
319 | /* there's now no turning back... the old userspace image is dead, | 319 | /* there's now no turning back... the old userspace image is dead, |
320 | * defunct, deceased, etc. after this point we have to exit via | 320 | * defunct, deceased, etc. |
321 | * error_kill */ | 321 | */ |
322 | set_personality(PER_LINUX_FDPIC); | 322 | set_personality(PER_LINUX_FDPIC); |
323 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) | 323 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) |
324 | current->personality |= READ_IMPLIES_EXEC; | 324 | current->personality |= READ_IMPLIES_EXEC; |
@@ -343,24 +343,22 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
343 | 343 | ||
344 | retval = setup_arg_pages(bprm, current->mm->start_stack, | 344 | retval = setup_arg_pages(bprm, current->mm->start_stack, |
345 | executable_stack); | 345 | executable_stack); |
346 | if (retval < 0) { | 346 | if (retval < 0) |
347 | send_sig(SIGKILL, current, 0); | 347 | goto error; |
348 | goto error_kill; | ||
349 | } | ||
350 | #endif | 348 | #endif |
351 | 349 | ||
352 | /* load the executable and interpreter into memory */ | 350 | /* load the executable and interpreter into memory */ |
353 | retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, | 351 | retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, |
354 | "executable"); | 352 | "executable"); |
355 | if (retval < 0) | 353 | if (retval < 0) |
356 | goto error_kill; | 354 | goto error; |
357 | 355 | ||
358 | if (interpreter_name) { | 356 | if (interpreter_name) { |
359 | retval = elf_fdpic_map_file(&interp_params, interpreter, | 357 | retval = elf_fdpic_map_file(&interp_params, interpreter, |
360 | current->mm, "interpreter"); | 358 | current->mm, "interpreter"); |
361 | if (retval < 0) { | 359 | if (retval < 0) { |
362 | printk(KERN_ERR "Unable to load interpreter\n"); | 360 | printk(KERN_ERR "Unable to load interpreter\n"); |
363 | goto error_kill; | 361 | goto error; |
364 | } | 362 | } |
365 | 363 | ||
366 | allow_write_access(interpreter); | 364 | allow_write_access(interpreter); |
@@ -397,7 +395,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
397 | if (IS_ERR_VALUE(current->mm->start_brk)) { | 395 | if (IS_ERR_VALUE(current->mm->start_brk)) { |
398 | retval = current->mm->start_brk; | 396 | retval = current->mm->start_brk; |
399 | current->mm->start_brk = 0; | 397 | current->mm->start_brk = 0; |
400 | goto error_kill; | 398 | goto error; |
401 | } | 399 | } |
402 | 400 | ||
403 | current->mm->brk = current->mm->start_brk; | 401 | current->mm->brk = current->mm->start_brk; |
@@ -410,7 +408,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
410 | install_exec_creds(bprm); | 408 | install_exec_creds(bprm); |
411 | if (create_elf_fdpic_tables(bprm, current->mm, | 409 | if (create_elf_fdpic_tables(bprm, current->mm, |
412 | &exec_params, &interp_params) < 0) | 410 | &exec_params, &interp_params) < 0) |
413 | goto error_kill; | 411 | goto error; |
414 | 412 | ||
415 | kdebug("- start_code %lx", current->mm->start_code); | 413 | kdebug("- start_code %lx", current->mm->start_code); |
416 | kdebug("- end_code %lx", current->mm->end_code); | 414 | kdebug("- end_code %lx", current->mm->end_code); |
@@ -449,12 +447,6 @@ error: | |||
449 | kfree(interp_params.phdrs); | 447 | kfree(interp_params.phdrs); |
450 | kfree(interp_params.loadmap); | 448 | kfree(interp_params.loadmap); |
451 | return retval; | 449 | return retval; |
452 | |||
453 | /* unrecoverable error - kill the process */ | ||
454 | error_kill: | ||
455 | send_sig(SIGSEGV, current, 0); | ||
456 | goto error; | ||
457 | |||
458 | } | 450 | } |
459 | 451 | ||
460 | /*****************************************************************************/ | 452 | /*****************************************************************************/ |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e732274f1afd..0fe1aa047f15 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2419,9 +2419,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2419 | goto out_dput; | 2419 | goto out_dput; |
2420 | } | 2420 | } |
2421 | 2421 | ||
2422 | err = d_invalidate(dentry); | 2422 | d_invalidate(dentry); |
2423 | if (err) | ||
2424 | goto out_unlock; | ||
2425 | 2423 | ||
2426 | down_write(&root->fs_info->subvol_sem); | 2424 | down_write(&root->fs_info->subvol_sem); |
2427 | 2425 | ||
@@ -2506,7 +2504,6 @@ out_release: | |||
2506 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); | 2504 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); |
2507 | out_up_write: | 2505 | out_up_write: |
2508 | up_write(&root->fs_info->subvol_sem); | 2506 | up_write(&root->fs_info->subvol_sem); |
2509 | out_unlock: | ||
2510 | if (err) { | 2507 | if (err) { |
2511 | spin_lock(&dest->root_item_lock); | 2508 | spin_lock(&dest->root_item_lock); |
2512 | root_flags = btrfs_root_flags(&dest->root_item); | 2509 | root_flags = btrfs_root_flags(&dest->root_item); |
diff --git a/fs/buffer.c b/fs/buffer.c index 44c14a87750e..d1f704806264 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2318,6 +2318,11 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, | |||
2318 | err = 0; | 2318 | err = 0; |
2319 | 2319 | ||
2320 | balance_dirty_pages_ratelimited(mapping); | 2320 | balance_dirty_pages_ratelimited(mapping); |
2321 | |||
2322 | if (unlikely(fatal_signal_pending(current))) { | ||
2323 | err = -EINTR; | ||
2324 | goto out; | ||
2325 | } | ||
2321 | } | 2326 | } |
2322 | 2327 | ||
2323 | /* page covers the boundary, find the boundary offset */ | 2328 | /* page covers the boundary, find the boundary offset */ |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 25e745b8eb1b..616db0e77b44 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -880,7 +880,6 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
880 | { | 880 | { |
881 | struct cachefiles_object *object; | 881 | struct cachefiles_object *object; |
882 | struct cachefiles_cache *cache; | 882 | struct cachefiles_cache *cache; |
883 | mm_segment_t old_fs; | ||
884 | struct file *file; | 883 | struct file *file; |
885 | struct path path; | 884 | struct path path; |
886 | loff_t pos, eof; | 885 | loff_t pos, eof; |
@@ -914,36 +913,27 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
914 | if (IS_ERR(file)) { | 913 | if (IS_ERR(file)) { |
915 | ret = PTR_ERR(file); | 914 | ret = PTR_ERR(file); |
916 | } else { | 915 | } else { |
917 | ret = -EIO; | 916 | pos = (loff_t) page->index << PAGE_SHIFT; |
918 | if (file->f_op->write) { | 917 | |
919 | pos = (loff_t) page->index << PAGE_SHIFT; | 918 | /* we mustn't write more data than we have, so we have |
920 | 919 | * to beware of a partial page at EOF */ | |
921 | /* we mustn't write more data than we have, so we have | 920 | eof = object->fscache.store_limit_l; |
922 | * to beware of a partial page at EOF */ | 921 | len = PAGE_SIZE; |
923 | eof = object->fscache.store_limit_l; | 922 | if (eof & ~PAGE_MASK) { |
924 | len = PAGE_SIZE; | 923 | ASSERTCMP(pos, <, eof); |
925 | if (eof & ~PAGE_MASK) { | 924 | if (eof - pos < PAGE_SIZE) { |
926 | ASSERTCMP(pos, <, eof); | 925 | _debug("cut short %llx to %llx", |
927 | if (eof - pos < PAGE_SIZE) { | 926 | pos, eof); |
928 | _debug("cut short %llx to %llx", | 927 | len = eof - pos; |
929 | pos, eof); | 928 | ASSERTCMP(pos + len, ==, eof); |
930 | len = eof - pos; | ||
931 | ASSERTCMP(pos + len, ==, eof); | ||
932 | } | ||
933 | } | 929 | } |
934 | |||
935 | data = kmap(page); | ||
936 | file_start_write(file); | ||
937 | old_fs = get_fs(); | ||
938 | set_fs(KERNEL_DS); | ||
939 | ret = file->f_op->write( | ||
940 | file, (const void __user *) data, len, &pos); | ||
941 | set_fs(old_fs); | ||
942 | kunmap(page); | ||
943 | file_end_write(file); | ||
944 | if (ret != len) | ||
945 | ret = -EIO; | ||
946 | } | 930 | } |
931 | |||
932 | data = kmap(page); | ||
933 | ret = __kernel_write(file, data, len, &pos); | ||
934 | kunmap(page); | ||
935 | if (ret != len) | ||
936 | ret = -EIO; | ||
947 | fput(file); | 937 | fput(file); |
948 | } | 938 | } |
949 | 939 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index c29d6ae68874..b6c59eaa4f64 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1069,7 +1069,6 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
1069 | ceph_dentry_lru_touch(dentry); | 1069 | ceph_dentry_lru_touch(dentry); |
1070 | } else { | 1070 | } else { |
1071 | ceph_dir_clear_complete(dir); | 1071 | ceph_dir_clear_complete(dir); |
1072 | d_drop(dentry); | ||
1073 | } | 1072 | } |
1074 | iput(dir); | 1073 | iput(dir); |
1075 | return valid; | 1074 | return valid; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6cbd9c688cfe..073640675a39 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -461,8 +461,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
461 | 461 | ||
462 | xid = get_xid(); | 462 | xid = get_xid(); |
463 | 463 | ||
464 | cifs_dbg(FYI, "parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 464 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
465 | inode, direntry->d_name.name, direntry); | 465 | inode, direntry, direntry); |
466 | 466 | ||
467 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | 467 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); |
468 | if (IS_ERR(tlink)) { | 468 | if (IS_ERR(tlink)) { |
@@ -540,8 +540,8 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
540 | struct cifs_fid fid; | 540 | struct cifs_fid fid; |
541 | __u32 oplock; | 541 | __u32 oplock; |
542 | 542 | ||
543 | cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 543 | cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
544 | inode, direntry->d_name.name, direntry); | 544 | inode, direntry, direntry); |
545 | 545 | ||
546 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | 546 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); |
547 | rc = PTR_ERR(tlink); | 547 | rc = PTR_ERR(tlink); |
@@ -713,8 +713,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
713 | 713 | ||
714 | xid = get_xid(); | 714 | xid = get_xid(); |
715 | 715 | ||
716 | cifs_dbg(FYI, "parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 716 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
717 | parent_dir_inode, direntry->d_name.name, direntry); | 717 | parent_dir_inode, direntry, direntry); |
718 | 718 | ||
719 | /* check whether path exists */ | 719 | /* check whether path exists */ |
720 | 720 | ||
@@ -833,7 +833,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) | |||
833 | { | 833 | { |
834 | int rc = 0; | 834 | int rc = 0; |
835 | 835 | ||
836 | cifs_dbg(FYI, "In cifs d_delete, name = %s\n", direntry->d_name.name); | 836 | cifs_dbg(FYI, "In cifs d_delete, name = %pd\n", direntry); |
837 | 837 | ||
838 | return rc; | 838 | return rc; |
839 | } */ | 839 | } */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f29354b072a..8f7b40fd8f3b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1650,8 +1650,8 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, | |||
1650 | 1650 | ||
1651 | cifs_sb = CIFS_SB(dentry->d_sb); | 1651 | cifs_sb = CIFS_SB(dentry->d_sb); |
1652 | 1652 | ||
1653 | cifs_dbg(FYI, "write %zd bytes to offset %lld of %s\n", | 1653 | cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n", |
1654 | write_size, *offset, dentry->d_name.name); | 1654 | write_size, *offset, dentry); |
1655 | 1655 | ||
1656 | tcon = tlink_tcon(open_file->tlink); | 1656 | tcon = tlink_tcon(open_file->tlink); |
1657 | server = tcon->ses->server; | 1657 | server = tcon->ses->server; |
@@ -2273,8 +2273,8 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, | |||
2273 | 2273 | ||
2274 | xid = get_xid(); | 2274 | xid = get_xid(); |
2275 | 2275 | ||
2276 | cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", | 2276 | cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n", |
2277 | file->f_path.dentry->d_name.name, datasync); | 2277 | file, datasync); |
2278 | 2278 | ||
2279 | if (!CIFS_CACHE_READ(CIFS_I(inode))) { | 2279 | if (!CIFS_CACHE_READ(CIFS_I(inode))) { |
2280 | rc = cifs_zap_mapping(inode); | 2280 | rc = cifs_zap_mapping(inode); |
@@ -2315,8 +2315,8 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
2315 | 2315 | ||
2316 | xid = get_xid(); | 2316 | xid = get_xid(); |
2317 | 2317 | ||
2318 | cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", | 2318 | cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n", |
2319 | file->f_path.dentry->d_name.name, datasync); | 2319 | file, datasync); |
2320 | 2320 | ||
2321 | tcon = tlink_tcon(smbfile->tlink); | 2321 | tcon = tlink_tcon(smbfile->tlink); |
2322 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { | 2322 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7899a40465b3..8fd4ee8e07ff 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1419,8 +1419,8 @@ cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1419 | d_instantiate(dentry, newinode); | 1419 | d_instantiate(dentry, newinode); |
1420 | 1420 | ||
1421 | #ifdef CONFIG_CIFS_DEBUG2 | 1421 | #ifdef CONFIG_CIFS_DEBUG2 |
1422 | cifs_dbg(FYI, "instantiated dentry %p %s to inode %p\n", | 1422 | cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p\n", |
1423 | dentry, dentry->d_name.name, newinode); | 1423 | dentry, dentry, newinode); |
1424 | 1424 | ||
1425 | if (newinode->i_nlink != 2) | 1425 | if (newinode->i_nlink != 2) |
1426 | cifs_dbg(FYI, "unexpected number of links %d\n", | 1426 | cifs_dbg(FYI, "unexpected number of links %d\n", |
@@ -2111,8 +2111,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
2111 | struct cifs_unix_set_info_args *args = NULL; | 2111 | struct cifs_unix_set_info_args *args = NULL; |
2112 | struct cifsFileInfo *open_file; | 2112 | struct cifsFileInfo *open_file; |
2113 | 2113 | ||
2114 | cifs_dbg(FYI, "setattr_unix on file %s attrs->ia_valid=0x%x\n", | 2114 | cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x\n", |
2115 | direntry->d_name.name, attrs->ia_valid); | 2115 | direntry, attrs->ia_valid); |
2116 | 2116 | ||
2117 | xid = get_xid(); | 2117 | xid = get_xid(); |
2118 | 2118 | ||
@@ -2254,8 +2254,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2254 | 2254 | ||
2255 | xid = get_xid(); | 2255 | xid = get_xid(); |
2256 | 2256 | ||
2257 | cifs_dbg(FYI, "setattr on file %s attrs->iavalid 0x%x\n", | 2257 | cifs_dbg(FYI, "setattr on file %pd attrs->iavalid 0x%x\n", |
2258 | direntry->d_name.name, attrs->ia_valid); | 2258 | direntry, attrs->ia_valid); |
2259 | 2259 | ||
2260 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 2260 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
2261 | attrs->ia_valid |= ATTR_FORCE; | 2261 | attrs->ia_valid |= ATTR_FORCE; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b334a89d6a66..d2141f101382 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -87,8 +87,6 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, | |||
87 | return; | 87 | return; |
88 | 88 | ||
89 | if (dentry) { | 89 | if (dentry) { |
90 | int err; | ||
91 | |||
92 | inode = dentry->d_inode; | 90 | inode = dentry->d_inode; |
93 | if (inode) { | 91 | if (inode) { |
94 | /* | 92 | /* |
@@ -105,10 +103,8 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, | |||
105 | goto out; | 103 | goto out; |
106 | } | 104 | } |
107 | } | 105 | } |
108 | err = d_invalidate(dentry); | 106 | d_invalidate(dentry); |
109 | dput(dentry); | 107 | dput(dentry); |
110 | if (err) | ||
111 | return; | ||
112 | } | 108 | } |
113 | 109 | ||
114 | /* | 110 | /* |
diff --git a/fs/compat.c b/fs/compat.c index 66d3d3c6b4b2..b13df99f3534 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -794,25 +794,21 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, | |||
794 | char *kernel_type; | 794 | char *kernel_type; |
795 | unsigned long data_page; | 795 | unsigned long data_page; |
796 | char *kernel_dev; | 796 | char *kernel_dev; |
797 | struct filename *dir; | ||
798 | int retval; | 797 | int retval; |
799 | 798 | ||
800 | retval = copy_mount_string(type, &kernel_type); | 799 | kernel_type = copy_mount_string(type); |
801 | if (retval < 0) | 800 | retval = PTR_ERR(kernel_type); |
801 | if (IS_ERR(kernel_type)) | ||
802 | goto out; | 802 | goto out; |
803 | 803 | ||
804 | dir = getname(dir_name); | 804 | kernel_dev = copy_mount_string(dev_name); |
805 | retval = PTR_ERR(dir); | 805 | retval = PTR_ERR(kernel_dev); |
806 | if (IS_ERR(dir)) | 806 | if (IS_ERR(kernel_dev)) |
807 | goto out1; | 807 | goto out1; |
808 | 808 | ||
809 | retval = copy_mount_string(dev_name, &kernel_dev); | ||
810 | if (retval < 0) | ||
811 | goto out2; | ||
812 | |||
813 | retval = copy_mount_options(data, &data_page); | 809 | retval = copy_mount_options(data, &data_page); |
814 | if (retval < 0) | 810 | if (retval < 0) |
815 | goto out3; | 811 | goto out2; |
816 | 812 | ||
817 | retval = -EINVAL; | 813 | retval = -EINVAL; |
818 | 814 | ||
@@ -821,19 +817,17 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, | |||
821 | do_ncp_super_data_conv((void *)data_page); | 817 | do_ncp_super_data_conv((void *)data_page); |
822 | } else if (!strcmp(kernel_type, NFS4_NAME)) { | 818 | } else if (!strcmp(kernel_type, NFS4_NAME)) { |
823 | if (do_nfs4_super_data_conv((void *) data_page)) | 819 | if (do_nfs4_super_data_conv((void *) data_page)) |
824 | goto out4; | 820 | goto out3; |
825 | } | 821 | } |
826 | } | 822 | } |
827 | 823 | ||
828 | retval = do_mount(kernel_dev, dir->name, kernel_type, | 824 | retval = do_mount(kernel_dev, dir_name, kernel_type, |
829 | flags, (void*)data_page); | 825 | flags, (void*)data_page); |
830 | 826 | ||
831 | out4: | ||
832 | free_page(data_page); | ||
833 | out3: | 827 | out3: |
834 | kfree(kernel_dev); | 828 | free_page(data_page); |
835 | out2: | 829 | out2: |
836 | putname(dir); | 830 | kfree(kernel_dev); |
837 | out1: | 831 | out1: |
838 | kfree(kernel_type); | 832 | kfree(kernel_type); |
839 | out: | 833 | out: |
diff --git a/fs/dcache.c b/fs/dcache.c index cb25a1a5e307..d5a23fd0da90 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -235,18 +235,49 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c | |||
235 | return dentry_string_cmp(cs, ct, tcount); | 235 | return dentry_string_cmp(cs, ct, tcount); |
236 | } | 236 | } |
237 | 237 | ||
238 | struct external_name { | ||
239 | union { | ||
240 | atomic_t count; | ||
241 | struct rcu_head head; | ||
242 | } u; | ||
243 | unsigned char name[]; | ||
244 | }; | ||
245 | |||
246 | static inline struct external_name *external_name(struct dentry *dentry) | ||
247 | { | ||
248 | return container_of(dentry->d_name.name, struct external_name, name[0]); | ||
249 | } | ||
250 | |||
238 | static void __d_free(struct rcu_head *head) | 251 | static void __d_free(struct rcu_head *head) |
239 | { | 252 | { |
240 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | 253 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); |
241 | 254 | ||
242 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); | 255 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); |
243 | if (dname_external(dentry)) | ||
244 | kfree(dentry->d_name.name); | ||
245 | kmem_cache_free(dentry_cache, dentry); | 256 | kmem_cache_free(dentry_cache, dentry); |
246 | } | 257 | } |
247 | 258 | ||
259 | static void __d_free_external(struct rcu_head *head) | ||
260 | { | ||
261 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
262 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); | ||
263 | kfree(external_name(dentry)); | ||
264 | kmem_cache_free(dentry_cache, dentry); | ||
265 | } | ||
266 | |||
267 | static inline int dname_external(const struct dentry *dentry) | ||
268 | { | ||
269 | return dentry->d_name.name != dentry->d_iname; | ||
270 | } | ||
271 | |||
248 | static void dentry_free(struct dentry *dentry) | 272 | static void dentry_free(struct dentry *dentry) |
249 | { | 273 | { |
274 | if (unlikely(dname_external(dentry))) { | ||
275 | struct external_name *p = external_name(dentry); | ||
276 | if (likely(atomic_dec_and_test(&p->u.count))) { | ||
277 | call_rcu(&dentry->d_u.d_rcu, __d_free_external); | ||
278 | return; | ||
279 | } | ||
280 | } | ||
250 | /* if dentry was never visible to RCU, immediate free is OK */ | 281 | /* if dentry was never visible to RCU, immediate free is OK */ |
251 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) | 282 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) |
252 | __d_free(&dentry->d_u.d_rcu); | 283 | __d_free(&dentry->d_u.d_rcu); |
@@ -456,7 +487,7 @@ static void __dentry_kill(struct dentry *dentry) | |||
456 | * inform the fs via d_prune that this dentry is about to be | 487 | * inform the fs via d_prune that this dentry is about to be |
457 | * unhashed and destroyed. | 488 | * unhashed and destroyed. |
458 | */ | 489 | */ |
459 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) | 490 | if (dentry->d_flags & DCACHE_OP_PRUNE) |
460 | dentry->d_op->d_prune(dentry); | 491 | dentry->d_op->d_prune(dentry); |
461 | 492 | ||
462 | if (dentry->d_flags & DCACHE_LRU_LIST) { | 493 | if (dentry->d_flags & DCACHE_LRU_LIST) { |
@@ -619,62 +650,6 @@ kill_it: | |||
619 | } | 650 | } |
620 | EXPORT_SYMBOL(dput); | 651 | EXPORT_SYMBOL(dput); |
621 | 652 | ||
622 | /** | ||
623 | * d_invalidate - invalidate a dentry | ||
624 | * @dentry: dentry to invalidate | ||
625 | * | ||
626 | * Try to invalidate the dentry if it turns out to be | ||
627 | * possible. If there are other dentries that can be | ||
628 | * reached through this one we can't delete it and we | ||
629 | * return -EBUSY. On success we return 0. | ||
630 | * | ||
631 | * no dcache lock. | ||
632 | */ | ||
633 | |||
634 | int d_invalidate(struct dentry * dentry) | ||
635 | { | ||
636 | /* | ||
637 | * If it's already been dropped, return OK. | ||
638 | */ | ||
639 | spin_lock(&dentry->d_lock); | ||
640 | if (d_unhashed(dentry)) { | ||
641 | spin_unlock(&dentry->d_lock); | ||
642 | return 0; | ||
643 | } | ||
644 | /* | ||
645 | * Check whether to do a partial shrink_dcache | ||
646 | * to get rid of unused child entries. | ||
647 | */ | ||
648 | if (!list_empty(&dentry->d_subdirs)) { | ||
649 | spin_unlock(&dentry->d_lock); | ||
650 | shrink_dcache_parent(dentry); | ||
651 | spin_lock(&dentry->d_lock); | ||
652 | } | ||
653 | |||
654 | /* | ||
655 | * Somebody else still using it? | ||
656 | * | ||
657 | * If it's a directory, we can't drop it | ||
658 | * for fear of somebody re-populating it | ||
659 | * with children (even though dropping it | ||
660 | * would make it unreachable from the root, | ||
661 | * we might still populate it if it was a | ||
662 | * working directory or similar). | ||
663 | * We also need to leave mountpoints alone, | ||
664 | * directory or not. | ||
665 | */ | ||
666 | if (dentry->d_lockref.count > 1 && dentry->d_inode) { | ||
667 | if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { | ||
668 | spin_unlock(&dentry->d_lock); | ||
669 | return -EBUSY; | ||
670 | } | ||
671 | } | ||
672 | |||
673 | __d_drop(dentry); | ||
674 | spin_unlock(&dentry->d_lock); | ||
675 | return 0; | ||
676 | } | ||
677 | EXPORT_SYMBOL(d_invalidate); | ||
678 | 653 | ||
679 | /* This must be called with d_lock held */ | 654 | /* This must be called with d_lock held */ |
680 | static inline void __dget_dlock(struct dentry *dentry) | 655 | static inline void __dget_dlock(struct dentry *dentry) |
@@ -735,7 +710,8 @@ EXPORT_SYMBOL(dget_parent); | |||
735 | * acquire the reference to alias and return it. Otherwise return NULL. | 710 | * acquire the reference to alias and return it. Otherwise return NULL. |
736 | * Notice that if inode is a directory there can be only one alias and | 711 | * Notice that if inode is a directory there can be only one alias and |
737 | * it can be unhashed only if it has no children, or if it is the root | 712 | * it can be unhashed only if it has no children, or if it is the root |
738 | * of a filesystem. | 713 | * of a filesystem, or if the directory was renamed and d_revalidate |
714 | * was the first vfs operation to notice. | ||
739 | * | 715 | * |
740 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer | 716 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer |
741 | * any other hashed alias over that one. | 717 | * any other hashed alias over that one. |
@@ -799,20 +775,13 @@ restart: | |||
799 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 775 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
800 | spin_lock(&dentry->d_lock); | 776 | spin_lock(&dentry->d_lock); |
801 | if (!dentry->d_lockref.count) { | 777 | if (!dentry->d_lockref.count) { |
802 | /* | 778 | struct dentry *parent = lock_parent(dentry); |
803 | * inform the fs via d_prune that this dentry | 779 | if (likely(!dentry->d_lockref.count)) { |
804 | * is about to be unhashed and destroyed. | 780 | __dentry_kill(dentry); |
805 | */ | 781 | goto restart; |
806 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && | 782 | } |
807 | !d_unhashed(dentry)) | 783 | if (parent) |
808 | dentry->d_op->d_prune(dentry); | 784 | spin_unlock(&parent->d_lock); |
809 | |||
810 | __dget_dlock(dentry); | ||
811 | __d_drop(dentry); | ||
812 | spin_unlock(&dentry->d_lock); | ||
813 | spin_unlock(&inode->i_lock); | ||
814 | dput(dentry); | ||
815 | goto restart; | ||
816 | } | 785 | } |
817 | spin_unlock(&dentry->d_lock); | 786 | spin_unlock(&dentry->d_lock); |
818 | } | 787 | } |
@@ -1193,7 +1162,7 @@ EXPORT_SYMBOL(have_submounts); | |||
1193 | * reachable (e.g. NFS can unhash a directory dentry and then the complete | 1162 | * reachable (e.g. NFS can unhash a directory dentry and then the complete |
1194 | * subtree can become unreachable). | 1163 | * subtree can become unreachable). |
1195 | * | 1164 | * |
1196 | * Only one of check_submounts_and_drop() and d_set_mounted() must succeed. For | 1165 | * Only one of d_invalidate() and d_set_mounted() must succeed. For |
1197 | * this reason take rename_lock and d_lock on dentry and ancestors. | 1166 | * this reason take rename_lock and d_lock on dentry and ancestors. |
1198 | */ | 1167 | */ |
1199 | int d_set_mounted(struct dentry *dentry) | 1168 | int d_set_mounted(struct dentry *dentry) |
@@ -1202,7 +1171,7 @@ int d_set_mounted(struct dentry *dentry) | |||
1202 | int ret = -ENOENT; | 1171 | int ret = -ENOENT; |
1203 | write_seqlock(&rename_lock); | 1172 | write_seqlock(&rename_lock); |
1204 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { | 1173 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { |
1205 | /* Need exclusion wrt. check_submounts_and_drop() */ | 1174 | /* Need exclusion wrt. d_invalidate() */ |
1206 | spin_lock(&p->d_lock); | 1175 | spin_lock(&p->d_lock); |
1207 | if (unlikely(d_unhashed(p))) { | 1176 | if (unlikely(d_unhashed(p))) { |
1208 | spin_unlock(&p->d_lock); | 1177 | spin_unlock(&p->d_lock); |
@@ -1346,70 +1315,84 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1346 | } | 1315 | } |
1347 | } | 1316 | } |
1348 | 1317 | ||
1349 | static enum d_walk_ret check_and_collect(void *_data, struct dentry *dentry) | 1318 | struct detach_data { |
1319 | struct select_data select; | ||
1320 | struct dentry *mountpoint; | ||
1321 | }; | ||
1322 | static enum d_walk_ret detach_and_collect(void *_data, struct dentry *dentry) | ||
1350 | { | 1323 | { |
1351 | struct select_data *data = _data; | 1324 | struct detach_data *data = _data; |
1352 | 1325 | ||
1353 | if (d_mountpoint(dentry)) { | 1326 | if (d_mountpoint(dentry)) { |
1354 | data->found = -EBUSY; | 1327 | __dget_dlock(dentry); |
1328 | data->mountpoint = dentry; | ||
1355 | return D_WALK_QUIT; | 1329 | return D_WALK_QUIT; |
1356 | } | 1330 | } |
1357 | 1331 | ||
1358 | return select_collect(_data, dentry); | 1332 | return select_collect(&data->select, dentry); |
1359 | } | 1333 | } |
1360 | 1334 | ||
1361 | static void check_and_drop(void *_data) | 1335 | static void check_and_drop(void *_data) |
1362 | { | 1336 | { |
1363 | struct select_data *data = _data; | 1337 | struct detach_data *data = _data; |
1364 | 1338 | ||
1365 | if (d_mountpoint(data->start)) | 1339 | if (!data->mountpoint && !data->select.found) |
1366 | data->found = -EBUSY; | 1340 | __d_drop(data->select.start); |
1367 | if (!data->found) | ||
1368 | __d_drop(data->start); | ||
1369 | } | 1341 | } |
1370 | 1342 | ||
1371 | /** | 1343 | /** |
1372 | * check_submounts_and_drop - prune dcache, check for submounts and drop | 1344 | * d_invalidate - detach submounts, prune dcache, and drop |
1345 | * @dentry: dentry to invalidate (aka detach, prune and drop) | ||
1373 | * | 1346 | * |
1374 | * All done as a single atomic operation relative to has_unlinked_ancestor(). | 1347 | * no dcache lock. |
1375 | * Returns 0 if successfully unhashed @parent. If there were submounts then | ||
1376 | * return -EBUSY. | ||
1377 | * | 1348 | * |
1378 | * @dentry: dentry to prune and drop | 1349 | * The final d_drop is done as an atomic operation relative to |
1350 | * rename_lock ensuring there are no races with d_set_mounted. This | ||
1351 | * ensures there are no unhashed dentries on the path to a mountpoint. | ||
1379 | */ | 1352 | */ |
1380 | int check_submounts_and_drop(struct dentry *dentry) | 1353 | void d_invalidate(struct dentry *dentry) |
1381 | { | 1354 | { |
1382 | int ret = 0; | 1355 | /* |
1356 | * If it's already been dropped, return OK. | ||
1357 | */ | ||
1358 | spin_lock(&dentry->d_lock); | ||
1359 | if (d_unhashed(dentry)) { | ||
1360 | spin_unlock(&dentry->d_lock); | ||
1361 | return; | ||
1362 | } | ||
1363 | spin_unlock(&dentry->d_lock); | ||
1383 | 1364 | ||
1384 | /* Negative dentries can be dropped without further checks */ | 1365 | /* Negative dentries can be dropped without further checks */ |
1385 | if (!dentry->d_inode) { | 1366 | if (!dentry->d_inode) { |
1386 | d_drop(dentry); | 1367 | d_drop(dentry); |
1387 | goto out; | 1368 | return; |
1388 | } | 1369 | } |
1389 | 1370 | ||
1390 | for (;;) { | 1371 | for (;;) { |
1391 | struct select_data data; | 1372 | struct detach_data data; |
1392 | 1373 | ||
1393 | INIT_LIST_HEAD(&data.dispose); | 1374 | data.mountpoint = NULL; |
1394 | data.start = dentry; | 1375 | INIT_LIST_HEAD(&data.select.dispose); |
1395 | data.found = 0; | 1376 | data.select.start = dentry; |
1377 | data.select.found = 0; | ||
1378 | |||
1379 | d_walk(dentry, &data, detach_and_collect, check_and_drop); | ||
1396 | 1380 | ||
1397 | d_walk(dentry, &data, check_and_collect, check_and_drop); | 1381 | if (data.select.found) |
1398 | ret = data.found; | 1382 | shrink_dentry_list(&data.select.dispose); |
1399 | 1383 | ||
1400 | if (!list_empty(&data.dispose)) | 1384 | if (data.mountpoint) { |
1401 | shrink_dentry_list(&data.dispose); | 1385 | detach_mounts(data.mountpoint); |
1386 | dput(data.mountpoint); | ||
1387 | } | ||
1402 | 1388 | ||
1403 | if (ret <= 0) | 1389 | if (!data.mountpoint && !data.select.found) |
1404 | break; | 1390 | break; |
1405 | 1391 | ||
1406 | cond_resched(); | 1392 | cond_resched(); |
1407 | } | 1393 | } |
1408 | |||
1409 | out: | ||
1410 | return ret; | ||
1411 | } | 1394 | } |
1412 | EXPORT_SYMBOL(check_submounts_and_drop); | 1395 | EXPORT_SYMBOL(d_invalidate); |
1413 | 1396 | ||
1414 | /** | 1397 | /** |
1415 | * __d_alloc - allocate a dcache entry | 1398 | * __d_alloc - allocate a dcache entry |
@@ -1438,11 +1421,14 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1438 | */ | 1421 | */ |
1439 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; | 1422 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; |
1440 | if (name->len > DNAME_INLINE_LEN-1) { | 1423 | if (name->len > DNAME_INLINE_LEN-1) { |
1441 | dname = kmalloc(name->len + 1, GFP_KERNEL); | 1424 | size_t size = offsetof(struct external_name, name[1]); |
1442 | if (!dname) { | 1425 | struct external_name *p = kmalloc(size + name->len, GFP_KERNEL); |
1426 | if (!p) { | ||
1443 | kmem_cache_free(dentry_cache, dentry); | 1427 | kmem_cache_free(dentry_cache, dentry); |
1444 | return NULL; | 1428 | return NULL; |
1445 | } | 1429 | } |
1430 | atomic_set(&p->u.count, 1); | ||
1431 | dname = p->name; | ||
1446 | } else { | 1432 | } else { |
1447 | dname = dentry->d_iname; | 1433 | dname = dentry->d_iname; |
1448 | } | 1434 | } |
@@ -2112,10 +2098,10 @@ struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name) | |||
2112 | struct dentry *dentry; | 2098 | struct dentry *dentry; |
2113 | unsigned seq; | 2099 | unsigned seq; |
2114 | 2100 | ||
2115 | do { | 2101 | do { |
2116 | seq = read_seqbegin(&rename_lock); | 2102 | seq = read_seqbegin(&rename_lock); |
2117 | dentry = __d_lookup(parent, name); | 2103 | dentry = __d_lookup(parent, name); |
2118 | if (dentry) | 2104 | if (dentry) |
2119 | break; | 2105 | break; |
2120 | } while (read_seqretry(&rename_lock, seq)); | 2106 | } while (read_seqretry(&rename_lock, seq)); |
2121 | return dentry; | 2107 | return dentry; |
@@ -2372,11 +2358,10 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | |||
2372 | } | 2358 | } |
2373 | EXPORT_SYMBOL(dentry_update_name_case); | 2359 | EXPORT_SYMBOL(dentry_update_name_case); |
2374 | 2360 | ||
2375 | static void switch_names(struct dentry *dentry, struct dentry *target, | 2361 | static void swap_names(struct dentry *dentry, struct dentry *target) |
2376 | bool exchange) | ||
2377 | { | 2362 | { |
2378 | if (dname_external(target)) { | 2363 | if (unlikely(dname_external(target))) { |
2379 | if (dname_external(dentry)) { | 2364 | if (unlikely(dname_external(dentry))) { |
2380 | /* | 2365 | /* |
2381 | * Both external: swap the pointers | 2366 | * Both external: swap the pointers |
2382 | */ | 2367 | */ |
@@ -2392,7 +2377,7 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2392 | target->d_name.name = target->d_iname; | 2377 | target->d_name.name = target->d_iname; |
2393 | } | 2378 | } |
2394 | } else { | 2379 | } else { |
2395 | if (dname_external(dentry)) { | 2380 | if (unlikely(dname_external(dentry))) { |
2396 | /* | 2381 | /* |
2397 | * dentry:external, target:internal. Give dentry's | 2382 | * dentry:external, target:internal. Give dentry's |
2398 | * storage to target and make dentry internal | 2383 | * storage to target and make dentry internal |
@@ -2407,12 +2392,6 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2407 | */ | 2392 | */ |
2408 | unsigned int i; | 2393 | unsigned int i; |
2409 | BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); | 2394 | BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); |
2410 | if (!exchange) { | ||
2411 | memcpy(dentry->d_iname, target->d_name.name, | ||
2412 | target->d_name.len + 1); | ||
2413 | dentry->d_name.hash_len = target->d_name.hash_len; | ||
2414 | return; | ||
2415 | } | ||
2416 | for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { | 2395 | for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { |
2417 | swap(((long *) &dentry->d_iname)[i], | 2396 | swap(((long *) &dentry->d_iname)[i], |
2418 | ((long *) &target->d_iname)[i]); | 2397 | ((long *) &target->d_iname)[i]); |
@@ -2422,6 +2401,24 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2422 | swap(dentry->d_name.hash_len, target->d_name.hash_len); | 2401 | swap(dentry->d_name.hash_len, target->d_name.hash_len); |
2423 | } | 2402 | } |
2424 | 2403 | ||
2404 | static void copy_name(struct dentry *dentry, struct dentry *target) | ||
2405 | { | ||
2406 | struct external_name *old_name = NULL; | ||
2407 | if (unlikely(dname_external(dentry))) | ||
2408 | old_name = external_name(dentry); | ||
2409 | if (unlikely(dname_external(target))) { | ||
2410 | atomic_inc(&external_name(target)->u.count); | ||
2411 | dentry->d_name = target->d_name; | ||
2412 | } else { | ||
2413 | memcpy(dentry->d_iname, target->d_name.name, | ||
2414 | target->d_name.len + 1); | ||
2415 | dentry->d_name.name = dentry->d_iname; | ||
2416 | dentry->d_name.hash_len = target->d_name.hash_len; | ||
2417 | } | ||
2418 | if (old_name && likely(atomic_dec_and_test(&old_name->u.count))) | ||
2419 | kfree_rcu(old_name, u.head); | ||
2420 | } | ||
2421 | |||
2425 | static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) | 2422 | static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) |
2426 | { | 2423 | { |
2427 | /* | 2424 | /* |
@@ -2518,7 +2515,10 @@ static void __d_move(struct dentry *dentry, struct dentry *target, | |||
2518 | } | 2515 | } |
2519 | 2516 | ||
2520 | /* Switch the names.. */ | 2517 | /* Switch the names.. */ |
2521 | switch_names(dentry, target, exchange); | 2518 | if (exchange) |
2519 | swap_names(dentry, target); | ||
2520 | else | ||
2521 | copy_name(dentry, target); | ||
2522 | 2522 | ||
2523 | /* ... and switch them in the tree */ | 2523 | /* ... and switch them in the tree */ |
2524 | if (IS_ROOT(dentry)) { | 2524 | if (IS_ROOT(dentry)) { |
@@ -2625,10 +2625,8 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2625 | goto out_err; | 2625 | goto out_err; |
2626 | m2 = &alias->d_parent->d_inode->i_mutex; | 2626 | m2 = &alias->d_parent->d_inode->i_mutex; |
2627 | out_unalias: | 2627 | out_unalias: |
2628 | if (likely(!d_mountpoint(alias))) { | 2628 | __d_move(alias, dentry, false); |
2629 | __d_move(alias, dentry, false); | 2629 | ret = alias; |
2630 | ret = alias; | ||
2631 | } | ||
2632 | out_err: | 2630 | out_err: |
2633 | spin_unlock(&inode->i_lock); | 2631 | spin_unlock(&inode->i_lock); |
2634 | if (m2) | 2632 | if (m2) |
@@ -2810,6 +2808,9 @@ static int prepend(char **buffer, int *buflen, const char *str, int namelen) | |||
2810 | * the beginning of the name. The sequence number check at the caller will | 2808 | * the beginning of the name. The sequence number check at the caller will |
2811 | * retry it again when a d_move() does happen. So any garbage in the buffer | 2809 | * retry it again when a d_move() does happen. So any garbage in the buffer |
2812 | * due to mismatched pointer and length will be discarded. | 2810 | * due to mismatched pointer and length will be discarded. |
2811 | * | ||
2812 | * Data dependency barrier is needed to make sure that we see that terminating | ||
2813 | * NUL. Alpha strikes again, film at 11... | ||
2813 | */ | 2814 | */ |
2814 | static int prepend_name(char **buffer, int *buflen, struct qstr *name) | 2815 | static int prepend_name(char **buffer, int *buflen, struct qstr *name) |
2815 | { | 2816 | { |
@@ -2817,6 +2818,8 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2817 | u32 dlen = ACCESS_ONCE(name->len); | 2818 | u32 dlen = ACCESS_ONCE(name->len); |
2818 | char *p; | 2819 | char *p; |
2819 | 2820 | ||
2821 | smp_read_barrier_depends(); | ||
2822 | |||
2820 | *buflen -= dlen + 1; | 2823 | *buflen -= dlen + 1; |
2821 | if (*buflen < 0) | 2824 | if (*buflen < 0) |
2822 | return -ENAMETOOLONG; | 2825 | return -ENAMETOOLONG; |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index b4b6ab9873ae..f5bce9096555 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -327,7 +327,7 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
327 | struct file *lower_file = ecryptfs_file_to_lower(file); | 327 | struct file *lower_file = ecryptfs_file_to_lower(file); |
328 | long rc = -ENOIOCTLCMD; | 328 | long rc = -ENOIOCTLCMD; |
329 | 329 | ||
330 | if (lower_file->f_op && lower_file->f_op->compat_ioctl) | 330 | if (lower_file->f_op->compat_ioctl) |
331 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); | 331 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); |
332 | return rc; | 332 | return rc; |
333 | } | 333 | } |
@@ -1372,18 +1372,23 @@ int search_binary_handler(struct linux_binprm *bprm) | |||
1372 | read_unlock(&binfmt_lock); | 1372 | read_unlock(&binfmt_lock); |
1373 | bprm->recursion_depth++; | 1373 | bprm->recursion_depth++; |
1374 | retval = fmt->load_binary(bprm); | 1374 | retval = fmt->load_binary(bprm); |
1375 | read_lock(&binfmt_lock); | ||
1376 | put_binfmt(fmt); | ||
1375 | bprm->recursion_depth--; | 1377 | bprm->recursion_depth--; |
1376 | if (retval >= 0 || retval != -ENOEXEC || | 1378 | if (retval < 0 && !bprm->mm) { |
1377 | bprm->mm == NULL || bprm->file == NULL) { | 1379 | /* we got to flush_old_exec() and failed after it */ |
1378 | put_binfmt(fmt); | 1380 | read_unlock(&binfmt_lock); |
1381 | force_sigsegv(SIGSEGV, current); | ||
1382 | return retval; | ||
1383 | } | ||
1384 | if (retval != -ENOEXEC || !bprm->file) { | ||
1385 | read_unlock(&binfmt_lock); | ||
1379 | return retval; | 1386 | return retval; |
1380 | } | 1387 | } |
1381 | read_lock(&binfmt_lock); | ||
1382 | put_binfmt(fmt); | ||
1383 | } | 1388 | } |
1384 | read_unlock(&binfmt_lock); | 1389 | read_unlock(&binfmt_lock); |
1385 | 1390 | ||
1386 | if (need_retry && retval == -ENOEXEC) { | 1391 | if (need_retry) { |
1387 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && | 1392 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && |
1388 | printable(bprm->buf[2]) && printable(bprm->buf[3])) | 1393 | printable(bprm->buf[2]) && printable(bprm->buf[3])) |
1389 | return retval; | 1394 | return retval; |
@@ -750,6 +750,7 @@ bool get_close_on_exec(unsigned int fd) | |||
750 | 750 | ||
751 | static int do_dup2(struct files_struct *files, | 751 | static int do_dup2(struct files_struct *files, |
752 | struct file *file, unsigned fd, unsigned flags) | 752 | struct file *file, unsigned fd, unsigned flags) |
753 | __releases(&files->file_lock) | ||
753 | { | 754 | { |
754 | struct file *tofree; | 755 | struct file *tofree; |
755 | struct fdtable *fdt; | 756 | struct fdtable *fdt; |
diff --git a/fs/file_table.c b/fs/file_table.c index 0bab12b20460..3f85411b03ce 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -150,18 +150,10 @@ over: | |||
150 | 150 | ||
151 | /** | 151 | /** |
152 | * alloc_file - allocate and initialize a 'struct file' | 152 | * alloc_file - allocate and initialize a 'struct file' |
153 | * @mnt: the vfsmount on which the file will reside | 153 | * |
154 | * @dentry: the dentry representing the new file | 154 | * @path: the (dentry, vfsmount) pair for the new file |
155 | * @mode: the mode with which the new file will be opened | 155 | * @mode: the mode with which the new file will be opened |
156 | * @fop: the 'struct file_operations' for the new file | 156 | * @fop: the 'struct file_operations' for the new file |
157 | * | ||
158 | * Use this instead of get_empty_filp() to get a new | ||
159 | * 'struct file'. Do so because of the same initialization | ||
160 | * pitfalls reasons listed for init_file(). This is a | ||
161 | * preferred interface to using init_file(). | ||
162 | * | ||
163 | * If all the callers of init_file() are eliminated, its | ||
164 | * code should be moved into this function. | ||
165 | */ | 157 | */ |
166 | struct file *alloc_file(struct path *path, fmode_t mode, | 158 | struct file *alloc_file(struct path *path, fmode_t mode, |
167 | const struct file_operations *fop) | 159 | const struct file_operations *fop) |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index de1d84af9f7c..dbab798f5caf 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -274,9 +274,6 @@ out: | |||
274 | 274 | ||
275 | invalid: | 275 | invalid: |
276 | ret = 0; | 276 | ret = 0; |
277 | |||
278 | if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0) | ||
279 | ret = 1; | ||
280 | goto out; | 277 | goto out; |
281 | } | 278 | } |
282 | 279 | ||
@@ -1289,9 +1286,7 @@ static int fuse_direntplus_link(struct file *file, | |||
1289 | d_drop(dentry); | 1286 | d_drop(dentry); |
1290 | } else if (get_node_id(inode) != o->nodeid || | 1287 | } else if (get_node_id(inode) != o->nodeid || |
1291 | ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { | 1288 | ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { |
1292 | err = d_invalidate(dentry); | 1289 | d_invalidate(dentry); |
1293 | if (err) | ||
1294 | goto out; | ||
1295 | } else if (is_bad_inode(inode)) { | 1290 | } else if (is_bad_inode(inode)) { |
1296 | err = -EIO; | 1291 | err = -EIO; |
1297 | goto out; | 1292 | goto out; |
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index d3a5d4e29ba5..589f4ea9381c 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -93,9 +93,6 @@ invalid_gunlock: | |||
93 | if (!had_lock) | 93 | if (!had_lock) |
94 | gfs2_glock_dq_uninit(&d_gh); | 94 | gfs2_glock_dq_uninit(&d_gh); |
95 | invalid: | 95 | invalid: |
96 | if (check_submounts_and_drop(dentry) != 0) | ||
97 | goto valid; | ||
98 | |||
99 | dput(parent); | 96 | dput(parent); |
100 | return 0; | 97 | return 0; |
101 | 98 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index fcf42eadb69c..c4ed823d150e 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1245,6 +1245,9 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1245 | struct dentry *d; | 1245 | struct dentry *d; |
1246 | bool excl = !!(flags & O_EXCL); | 1246 | bool excl = !!(flags & O_EXCL); |
1247 | 1247 | ||
1248 | if (!d_unhashed(dentry)) | ||
1249 | goto skip_lookup; | ||
1250 | |||
1248 | d = __gfs2_lookup(dir, dentry, file, opened); | 1251 | d = __gfs2_lookup(dir, dentry, file, opened); |
1249 | if (IS_ERR(d)) | 1252 | if (IS_ERR(d)) |
1250 | return PTR_ERR(d); | 1253 | return PTR_ERR(d); |
@@ -1261,6 +1264,8 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1261 | } | 1264 | } |
1262 | 1265 | ||
1263 | BUG_ON(d != NULL); | 1266 | BUG_ON(d != NULL); |
1267 | |||
1268 | skip_lookup: | ||
1264 | if (!(flags & O_CREAT)) | 1269 | if (!(flags & O_CREAT)) |
1265 | return -ENOENT; | 1270 | return -ENOENT; |
1266 | 1271 | ||
diff --git a/fs/internal.h b/fs/internal.h index b2623200107b..9477f8f6aefc 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -56,7 +56,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, | |||
56 | * namespace.c | 56 | * namespace.c |
57 | */ | 57 | */ |
58 | extern int copy_mount_options(const void __user *, unsigned long *); | 58 | extern int copy_mount_options(const void __user *, unsigned long *); |
59 | extern int copy_mount_string(const void __user *, char **); | 59 | extern char *copy_mount_string(const void __user *); |
60 | 60 | ||
61 | extern struct vfsmount *lookup_mnt(struct path *); | 61 | extern struct vfsmount *lookup_mnt(struct path *); |
62 | extern int finish_automount(struct vfsmount *, struct path *); | 62 | extern int finish_automount(struct vfsmount *, struct path *); |
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 413ef89c2d1b..046fee8b6e9b 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -134,8 +134,6 @@ struct jffs2_sb_info { | |||
134 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ | 134 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ |
135 | 135 | ||
136 | struct delayed_work wbuf_dwork; /* write-buffer write-out work */ | 136 | struct delayed_work wbuf_dwork; /* write-buffer write-out work */ |
137 | int wbuf_queued; /* non-zero delayed work is queued */ | ||
138 | spinlock_t wbuf_dwork_lock; /* protects wbuf_dwork and and wbuf_queued */ | ||
139 | 137 | ||
140 | unsigned char *oobbuf; | 138 | unsigned char *oobbuf; |
141 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ | 139 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index a6597d60d76d..09ed55190ee2 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -1162,10 +1162,6 @@ static void delayed_wbuf_sync(struct work_struct *work) | |||
1162 | struct jffs2_sb_info *c = work_to_sb(work); | 1162 | struct jffs2_sb_info *c = work_to_sb(work); |
1163 | struct super_block *sb = OFNI_BS_2SFFJ(c); | 1163 | struct super_block *sb = OFNI_BS_2SFFJ(c); |
1164 | 1164 | ||
1165 | spin_lock(&c->wbuf_dwork_lock); | ||
1166 | c->wbuf_queued = 0; | ||
1167 | spin_unlock(&c->wbuf_dwork_lock); | ||
1168 | |||
1169 | if (!(sb->s_flags & MS_RDONLY)) { | 1165 | if (!(sb->s_flags & MS_RDONLY)) { |
1170 | jffs2_dbg(1, "%s()\n", __func__); | 1166 | jffs2_dbg(1, "%s()\n", __func__); |
1171 | jffs2_flush_wbuf_gc(c, 0); | 1167 | jffs2_flush_wbuf_gc(c, 0); |
@@ -1180,14 +1176,9 @@ void jffs2_dirty_trigger(struct jffs2_sb_info *c) | |||
1180 | if (sb->s_flags & MS_RDONLY) | 1176 | if (sb->s_flags & MS_RDONLY) |
1181 | return; | 1177 | return; |
1182 | 1178 | ||
1183 | spin_lock(&c->wbuf_dwork_lock); | 1179 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); |
1184 | if (!c->wbuf_queued) { | 1180 | if (queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay)) |
1185 | jffs2_dbg(1, "%s()\n", __func__); | 1181 | jffs2_dbg(1, "%s()\n", __func__); |
1186 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
1187 | queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay); | ||
1188 | c->wbuf_queued = 1; | ||
1189 | } | ||
1190 | spin_unlock(&c->wbuf_dwork_lock); | ||
1191 | } | 1182 | } |
1192 | 1183 | ||
1193 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | 1184 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) |
@@ -1211,7 +1202,6 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | |||
1211 | 1202 | ||
1212 | /* Initialise write buffer */ | 1203 | /* Initialise write buffer */ |
1213 | init_rwsem(&c->wbuf_sem); | 1204 | init_rwsem(&c->wbuf_sem); |
1214 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1215 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1205 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1216 | c->wbuf_pagesize = c->mtd->writesize; | 1206 | c->wbuf_pagesize = c->mtd->writesize; |
1217 | c->wbuf_ofs = 0xFFFFFFFF; | 1207 | c->wbuf_ofs = 0xFFFFFFFF; |
@@ -1251,7 +1241,6 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { | |||
1251 | 1241 | ||
1252 | /* Initialize write buffer */ | 1242 | /* Initialize write buffer */ |
1253 | init_rwsem(&c->wbuf_sem); | 1243 | init_rwsem(&c->wbuf_sem); |
1254 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1255 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1244 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1256 | c->wbuf_pagesize = c->mtd->erasesize; | 1245 | c->wbuf_pagesize = c->mtd->erasesize; |
1257 | 1246 | ||
@@ -1311,7 +1300,6 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { | |||
1311 | 1300 | ||
1312 | /* Initialize write buffer */ | 1301 | /* Initialize write buffer */ |
1313 | init_rwsem(&c->wbuf_sem); | 1302 | init_rwsem(&c->wbuf_sem); |
1314 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1315 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1303 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1316 | 1304 | ||
1317 | c->wbuf_pagesize = c->mtd->writesize; | 1305 | c->wbuf_pagesize = c->mtd->writesize; |
@@ -1346,7 +1334,6 @@ int jffs2_ubivol_setup(struct jffs2_sb_info *c) { | |||
1346 | return 0; | 1334 | return 0; |
1347 | 1335 | ||
1348 | init_rwsem(&c->wbuf_sem); | 1336 | init_rwsem(&c->wbuf_sem); |
1349 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1350 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1337 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1351 | 1338 | ||
1352 | c->wbuf_pagesize = c->mtd->writesize; | 1339 | c->wbuf_pagesize = c->mtd->writesize; |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index adf8cb045b9e..93e897e588a8 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -550,7 +550,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
550 | inode->i_ino = 0; | 550 | inode->i_ino = 0; |
551 | inode->i_size = sb->s_bdev->bd_inode->i_size; | 551 | inode->i_size = sb->s_bdev->bd_inode->i_size; |
552 | inode->i_mapping->a_ops = &jfs_metapage_aops; | 552 | inode->i_mapping->a_ops = &jfs_metapage_aops; |
553 | insert_inode_hash(inode); | 553 | hlist_add_fake(&inode->i_hash); |
554 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | 554 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
555 | 555 | ||
556 | sbi->direct_inode = inode; | 556 | sbi->direct_inode = inode; |
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index a693f5b01ae6..1c771931bb60 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -463,21 +463,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) | |||
463 | goto out_bad; | 463 | goto out_bad; |
464 | 464 | ||
465 | mutex_unlock(&kernfs_mutex); | 465 | mutex_unlock(&kernfs_mutex); |
466 | out_valid: | ||
467 | return 1; | 466 | return 1; |
468 | out_bad: | 467 | out_bad: |
469 | mutex_unlock(&kernfs_mutex); | 468 | mutex_unlock(&kernfs_mutex); |
470 | out_bad_unlocked: | 469 | out_bad_unlocked: |
471 | /* | ||
472 | * @dentry doesn't match the underlying kernfs node, drop the | ||
473 | * dentry and force lookup. If we have submounts we must allow the | ||
474 | * vfs caches to lie about the state of the filesystem to prevent | ||
475 | * leaks and other nasty things, so use check_submounts_and_drop() | ||
476 | * instead of d_drop(). | ||
477 | */ | ||
478 | if (check_submounts_and_drop(dentry) != 0) | ||
479 | goto out_valid; | ||
480 | |||
481 | return 0; | 470 | return 0; |
482 | } | 471 | } |
483 | 472 | ||
diff --git a/fs/mount.h b/fs/mount.h index 6740a6215529..f82c62840905 100644 --- a/fs/mount.h +++ b/fs/mount.h | |||
@@ -21,6 +21,7 @@ struct mnt_pcp { | |||
21 | struct mountpoint { | 21 | struct mountpoint { |
22 | struct hlist_node m_hash; | 22 | struct hlist_node m_hash; |
23 | struct dentry *m_dentry; | 23 | struct dentry *m_dentry; |
24 | struct hlist_head m_list; | ||
24 | int m_count; | 25 | int m_count; |
25 | }; | 26 | }; |
26 | 27 | ||
@@ -29,7 +30,10 @@ struct mount { | |||
29 | struct mount *mnt_parent; | 30 | struct mount *mnt_parent; |
30 | struct dentry *mnt_mountpoint; | 31 | struct dentry *mnt_mountpoint; |
31 | struct vfsmount mnt; | 32 | struct vfsmount mnt; |
32 | struct rcu_head mnt_rcu; | 33 | union { |
34 | struct rcu_head mnt_rcu; | ||
35 | struct llist_node mnt_llist; | ||
36 | }; | ||
33 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
34 | struct mnt_pcp __percpu *mnt_pcp; | 38 | struct mnt_pcp __percpu *mnt_pcp; |
35 | #else | 39 | #else |
@@ -48,6 +52,7 @@ struct mount { | |||
48 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ | 52 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ |
49 | struct mnt_namespace *mnt_ns; /* containing namespace */ | 53 | struct mnt_namespace *mnt_ns; /* containing namespace */ |
50 | struct mountpoint *mnt_mp; /* where is it mounted */ | 54 | struct mountpoint *mnt_mp; /* where is it mounted */ |
55 | struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */ | ||
51 | #ifdef CONFIG_FSNOTIFY | 56 | #ifdef CONFIG_FSNOTIFY |
52 | struct hlist_head mnt_fsnotify_marks; | 57 | struct hlist_head mnt_fsnotify_marks; |
53 | __u32 mnt_fsnotify_mask; | 58 | __u32 mnt_fsnotify_mask; |
@@ -82,6 +87,15 @@ extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *); | |||
82 | 87 | ||
83 | extern bool legitimize_mnt(struct vfsmount *, unsigned); | 88 | extern bool legitimize_mnt(struct vfsmount *, unsigned); |
84 | 89 | ||
90 | extern void __detach_mounts(struct dentry *dentry); | ||
91 | |||
92 | static inline void detach_mounts(struct dentry *dentry) | ||
93 | { | ||
94 | if (!d_mountpoint(dentry)) | ||
95 | return; | ||
96 | __detach_mounts(dentry); | ||
97 | } | ||
98 | |||
85 | static inline void get_mnt_ns(struct mnt_namespace *ns) | 99 | static inline void get_mnt_ns(struct mnt_namespace *ns) |
86 | { | 100 | { |
87 | atomic_inc(&ns->count); | 101 | atomic_inc(&ns->count); |
@@ -112,3 +126,12 @@ struct proc_mounts { | |||
112 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) | 126 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) |
113 | 127 | ||
114 | extern const struct seq_operations mounts_op; | 128 | extern const struct seq_operations mounts_op; |
129 | |||
130 | extern bool __is_local_mountpoint(struct dentry *dentry); | ||
131 | static inline bool is_local_mountpoint(struct dentry *dentry) | ||
132 | { | ||
133 | if (!d_mountpoint(dentry)) | ||
134 | return false; | ||
135 | |||
136 | return __is_local_mountpoint(dentry); | ||
137 | } | ||
diff --git a/fs/namei.c b/fs/namei.c index 3ddb044f3702..43927d14db67 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1306,7 +1306,8 @@ static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | |||
1306 | if (error < 0) { | 1306 | if (error < 0) { |
1307 | dput(dentry); | 1307 | dput(dentry); |
1308 | return ERR_PTR(error); | 1308 | return ERR_PTR(error); |
1309 | } else if (!d_invalidate(dentry)) { | 1309 | } else { |
1310 | d_invalidate(dentry); | ||
1310 | dput(dentry); | 1311 | dput(dentry); |
1311 | dentry = NULL; | 1312 | dentry = NULL; |
1312 | } | 1313 | } |
@@ -1435,10 +1436,9 @@ unlazy: | |||
1435 | dput(dentry); | 1436 | dput(dentry); |
1436 | return status; | 1437 | return status; |
1437 | } | 1438 | } |
1438 | if (!d_invalidate(dentry)) { | 1439 | d_invalidate(dentry); |
1439 | dput(dentry); | 1440 | dput(dentry); |
1440 | goto need_lookup; | 1441 | goto need_lookup; |
1441 | } | ||
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | path->mnt = mnt; | 1444 | path->mnt = mnt; |
@@ -1950,7 +1950,7 @@ static int path_lookupat(int dfd, const char *name, | |||
1950 | err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base); | 1950 | err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base); |
1951 | 1951 | ||
1952 | if (unlikely(err)) | 1952 | if (unlikely(err)) |
1953 | return err; | 1953 | goto out; |
1954 | 1954 | ||
1955 | current->total_link_count = 0; | 1955 | current->total_link_count = 0; |
1956 | err = link_path_walk(name, nd); | 1956 | err = link_path_walk(name, nd); |
@@ -1982,6 +1982,7 @@ static int path_lookupat(int dfd, const char *name, | |||
1982 | } | 1982 | } |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | out: | ||
1985 | if (base) | 1986 | if (base) |
1986 | fput(base); | 1987 | fput(base); |
1987 | 1988 | ||
@@ -2301,7 +2302,7 @@ path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags | |||
2301 | 2302 | ||
2302 | err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base); | 2303 | err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base); |
2303 | if (unlikely(err)) | 2304 | if (unlikely(err)) |
2304 | return err; | 2305 | goto out; |
2305 | 2306 | ||
2306 | current->total_link_count = 0; | 2307 | current->total_link_count = 0; |
2307 | err = link_path_walk(name, &nd); | 2308 | err = link_path_walk(name, &nd); |
@@ -3565,7 +3566,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3565 | mutex_lock(&dentry->d_inode->i_mutex); | 3566 | mutex_lock(&dentry->d_inode->i_mutex); |
3566 | 3567 | ||
3567 | error = -EBUSY; | 3568 | error = -EBUSY; |
3568 | if (d_mountpoint(dentry)) | 3569 | if (is_local_mountpoint(dentry)) |
3569 | goto out; | 3570 | goto out; |
3570 | 3571 | ||
3571 | error = security_inode_rmdir(dir, dentry); | 3572 | error = security_inode_rmdir(dir, dentry); |
@@ -3579,6 +3580,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3579 | 3580 | ||
3580 | dentry->d_inode->i_flags |= S_DEAD; | 3581 | dentry->d_inode->i_flags |= S_DEAD; |
3581 | dont_mount(dentry); | 3582 | dont_mount(dentry); |
3583 | detach_mounts(dentry); | ||
3582 | 3584 | ||
3583 | out: | 3585 | out: |
3584 | mutex_unlock(&dentry->d_inode->i_mutex); | 3586 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -3681,7 +3683,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate | |||
3681 | return -EPERM; | 3683 | return -EPERM; |
3682 | 3684 | ||
3683 | mutex_lock(&target->i_mutex); | 3685 | mutex_lock(&target->i_mutex); |
3684 | if (d_mountpoint(dentry)) | 3686 | if (is_local_mountpoint(dentry)) |
3685 | error = -EBUSY; | 3687 | error = -EBUSY; |
3686 | else { | 3688 | else { |
3687 | error = security_inode_unlink(dir, dentry); | 3689 | error = security_inode_unlink(dir, dentry); |
@@ -3690,8 +3692,10 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate | |||
3690 | if (error) | 3692 | if (error) |
3691 | goto out; | 3693 | goto out; |
3692 | error = dir->i_op->unlink(dir, dentry); | 3694 | error = dir->i_op->unlink(dir, dentry); |
3693 | if (!error) | 3695 | if (!error) { |
3694 | dont_mount(dentry); | 3696 | dont_mount(dentry); |
3697 | detach_mounts(dentry); | ||
3698 | } | ||
3695 | } | 3699 | } |
3696 | } | 3700 | } |
3697 | out: | 3701 | out: |
@@ -4126,7 +4130,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4126 | mutex_lock(&target->i_mutex); | 4130 | mutex_lock(&target->i_mutex); |
4127 | 4131 | ||
4128 | error = -EBUSY; | 4132 | error = -EBUSY; |
4129 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | 4133 | if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry)) |
4130 | goto out; | 4134 | goto out; |
4131 | 4135 | ||
4132 | if (max_links && new_dir != old_dir) { | 4136 | if (max_links && new_dir != old_dir) { |
@@ -4164,6 +4168,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4164 | if (is_dir) | 4168 | if (is_dir) |
4165 | target->i_flags |= S_DEAD; | 4169 | target->i_flags |= S_DEAD; |
4166 | dont_mount(new_dentry); | 4170 | dont_mount(new_dentry); |
4171 | detach_mounts(new_dentry); | ||
4167 | } | 4172 | } |
4168 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) { | 4173 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) { |
4169 | if (!(flags & RENAME_EXCHANGE)) | 4174 | if (!(flags & RENAME_EXCHANGE)) |
diff --git a/fs/namespace.c b/fs/namespace.c index ef42d9bee212..348562f14e93 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/proc_ns.h> | 23 | #include <linux/proc_ns.h> |
24 | #include <linux/magic.h> | 24 | #include <linux/magic.h> |
25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
26 | #include <linux/task_work.h> | ||
26 | #include "pnode.h" | 27 | #include "pnode.h" |
27 | #include "internal.h" | 28 | #include "internal.h" |
28 | 29 | ||
@@ -224,6 +225,7 @@ static struct mount *alloc_vfsmnt(const char *name) | |||
224 | INIT_LIST_HEAD(&mnt->mnt_share); | 225 | INIT_LIST_HEAD(&mnt->mnt_share); |
225 | INIT_LIST_HEAD(&mnt->mnt_slave_list); | 226 | INIT_LIST_HEAD(&mnt->mnt_slave_list); |
226 | INIT_LIST_HEAD(&mnt->mnt_slave); | 227 | INIT_LIST_HEAD(&mnt->mnt_slave); |
228 | INIT_HLIST_NODE(&mnt->mnt_mp_list); | ||
227 | #ifdef CONFIG_FSNOTIFY | 229 | #ifdef CONFIG_FSNOTIFY |
228 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); | 230 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); |
229 | #endif | 231 | #endif |
@@ -666,11 +668,45 @@ struct vfsmount *lookup_mnt(struct path *path) | |||
666 | return m; | 668 | return m; |
667 | } | 669 | } |
668 | 670 | ||
669 | static struct mountpoint *new_mountpoint(struct dentry *dentry) | 671 | /* |
672 | * __is_local_mountpoint - Test to see if dentry is a mountpoint in the | ||
673 | * current mount namespace. | ||
674 | * | ||
675 | * The common case is dentries are not mountpoints at all and that | ||
676 | * test is handled inline. For the slow case when we are actually | ||
677 | * dealing with a mountpoint of some kind, walk through all of the | ||
678 | * mounts in the current mount namespace and test to see if the dentry | ||
679 | * is a mountpoint. | ||
680 | * | ||
681 | * The mount_hashtable is not usable in the context because we | ||
682 | * need to identify all mounts that may be in the current mount | ||
683 | * namespace not just a mount that happens to have some specified | ||
684 | * parent mount. | ||
685 | */ | ||
686 | bool __is_local_mountpoint(struct dentry *dentry) | ||
687 | { | ||
688 | struct mnt_namespace *ns = current->nsproxy->mnt_ns; | ||
689 | struct mount *mnt; | ||
690 | bool is_covered = false; | ||
691 | |||
692 | if (!d_mountpoint(dentry)) | ||
693 | goto out; | ||
694 | |||
695 | down_read(&namespace_sem); | ||
696 | list_for_each_entry(mnt, &ns->list, mnt_list) { | ||
697 | is_covered = (mnt->mnt_mountpoint == dentry); | ||
698 | if (is_covered) | ||
699 | break; | ||
700 | } | ||
701 | up_read(&namespace_sem); | ||
702 | out: | ||
703 | return is_covered; | ||
704 | } | ||
705 | |||
706 | static struct mountpoint *lookup_mountpoint(struct dentry *dentry) | ||
670 | { | 707 | { |
671 | struct hlist_head *chain = mp_hash(dentry); | 708 | struct hlist_head *chain = mp_hash(dentry); |
672 | struct mountpoint *mp; | 709 | struct mountpoint *mp; |
673 | int ret; | ||
674 | 710 | ||
675 | hlist_for_each_entry(mp, chain, m_hash) { | 711 | hlist_for_each_entry(mp, chain, m_hash) { |
676 | if (mp->m_dentry == dentry) { | 712 | if (mp->m_dentry == dentry) { |
@@ -681,6 +717,14 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry) | |||
681 | return mp; | 717 | return mp; |
682 | } | 718 | } |
683 | } | 719 | } |
720 | return NULL; | ||
721 | } | ||
722 | |||
723 | static struct mountpoint *new_mountpoint(struct dentry *dentry) | ||
724 | { | ||
725 | struct hlist_head *chain = mp_hash(dentry); | ||
726 | struct mountpoint *mp; | ||
727 | int ret; | ||
684 | 728 | ||
685 | mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); | 729 | mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); |
686 | if (!mp) | 730 | if (!mp) |
@@ -695,6 +739,7 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry) | |||
695 | mp->m_dentry = dentry; | 739 | mp->m_dentry = dentry; |
696 | mp->m_count = 1; | 740 | mp->m_count = 1; |
697 | hlist_add_head(&mp->m_hash, chain); | 741 | hlist_add_head(&mp->m_hash, chain); |
742 | INIT_HLIST_HEAD(&mp->m_list); | ||
698 | return mp; | 743 | return mp; |
699 | } | 744 | } |
700 | 745 | ||
@@ -702,6 +747,7 @@ static void put_mountpoint(struct mountpoint *mp) | |||
702 | { | 747 | { |
703 | if (!--mp->m_count) { | 748 | if (!--mp->m_count) { |
704 | struct dentry *dentry = mp->m_dentry; | 749 | struct dentry *dentry = mp->m_dentry; |
750 | BUG_ON(!hlist_empty(&mp->m_list)); | ||
705 | spin_lock(&dentry->d_lock); | 751 | spin_lock(&dentry->d_lock); |
706 | dentry->d_flags &= ~DCACHE_MOUNTED; | 752 | dentry->d_flags &= ~DCACHE_MOUNTED; |
707 | spin_unlock(&dentry->d_lock); | 753 | spin_unlock(&dentry->d_lock); |
@@ -748,6 +794,7 @@ static void detach_mnt(struct mount *mnt, struct path *old_path) | |||
748 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | 794 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; |
749 | list_del_init(&mnt->mnt_child); | 795 | list_del_init(&mnt->mnt_child); |
750 | hlist_del_init_rcu(&mnt->mnt_hash); | 796 | hlist_del_init_rcu(&mnt->mnt_hash); |
797 | hlist_del_init(&mnt->mnt_mp_list); | ||
751 | put_mountpoint(mnt->mnt_mp); | 798 | put_mountpoint(mnt->mnt_mp); |
752 | mnt->mnt_mp = NULL; | 799 | mnt->mnt_mp = NULL; |
753 | } | 800 | } |
@@ -764,6 +811,7 @@ void mnt_set_mountpoint(struct mount *mnt, | |||
764 | child_mnt->mnt_mountpoint = dget(mp->m_dentry); | 811 | child_mnt->mnt_mountpoint = dget(mp->m_dentry); |
765 | child_mnt->mnt_parent = mnt; | 812 | child_mnt->mnt_parent = mnt; |
766 | child_mnt->mnt_mp = mp; | 813 | child_mnt->mnt_mp = mp; |
814 | hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list); | ||
767 | } | 815 | } |
768 | 816 | ||
769 | /* | 817 | /* |
@@ -957,6 +1005,46 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
957 | return ERR_PTR(err); | 1005 | return ERR_PTR(err); |
958 | } | 1006 | } |
959 | 1007 | ||
1008 | static void cleanup_mnt(struct mount *mnt) | ||
1009 | { | ||
1010 | /* | ||
1011 | * This probably indicates that somebody messed | ||
1012 | * up a mnt_want/drop_write() pair. If this | ||
1013 | * happens, the filesystem was probably unable | ||
1014 | * to make r/w->r/o transitions. | ||
1015 | */ | ||
1016 | /* | ||
1017 | * The locking used to deal with mnt_count decrement provides barriers, | ||
1018 | * so mnt_get_writers() below is safe. | ||
1019 | */ | ||
1020 | WARN_ON(mnt_get_writers(mnt)); | ||
1021 | if (unlikely(mnt->mnt_pins.first)) | ||
1022 | mnt_pin_kill(mnt); | ||
1023 | fsnotify_vfsmount_delete(&mnt->mnt); | ||
1024 | dput(mnt->mnt.mnt_root); | ||
1025 | deactivate_super(mnt->mnt.mnt_sb); | ||
1026 | mnt_free_id(mnt); | ||
1027 | call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt); | ||
1028 | } | ||
1029 | |||
1030 | static void __cleanup_mnt(struct rcu_head *head) | ||
1031 | { | ||
1032 | cleanup_mnt(container_of(head, struct mount, mnt_rcu)); | ||
1033 | } | ||
1034 | |||
1035 | static LLIST_HEAD(delayed_mntput_list); | ||
1036 | static void delayed_mntput(struct work_struct *unused) | ||
1037 | { | ||
1038 | struct llist_node *node = llist_del_all(&delayed_mntput_list); | ||
1039 | struct llist_node *next; | ||
1040 | |||
1041 | for (; node; node = next) { | ||
1042 | next = llist_next(node); | ||
1043 | cleanup_mnt(llist_entry(node, struct mount, mnt_llist)); | ||
1044 | } | ||
1045 | } | ||
1046 | static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput); | ||
1047 | |||
960 | static void mntput_no_expire(struct mount *mnt) | 1048 | static void mntput_no_expire(struct mount *mnt) |
961 | { | 1049 | { |
962 | rcu_read_lock(); | 1050 | rcu_read_lock(); |
@@ -982,24 +1070,18 @@ static void mntput_no_expire(struct mount *mnt) | |||
982 | list_del(&mnt->mnt_instance); | 1070 | list_del(&mnt->mnt_instance); |
983 | unlock_mount_hash(); | 1071 | unlock_mount_hash(); |
984 | 1072 | ||
985 | /* | 1073 | if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))) { |
986 | * This probably indicates that somebody messed | 1074 | struct task_struct *task = current; |
987 | * up a mnt_want/drop_write() pair. If this | 1075 | if (likely(!(task->flags & PF_KTHREAD))) { |
988 | * happens, the filesystem was probably unable | 1076 | init_task_work(&mnt->mnt_rcu, __cleanup_mnt); |
989 | * to make r/w->r/o transitions. | 1077 | if (!task_work_add(task, &mnt->mnt_rcu, true)) |
990 | */ | 1078 | return; |
991 | /* | 1079 | } |
992 | * The locking used to deal with mnt_count decrement provides barriers, | 1080 | if (llist_add(&mnt->mnt_llist, &delayed_mntput_list)) |
993 | * so mnt_get_writers() below is safe. | 1081 | schedule_delayed_work(&delayed_mntput_work, 1); |
994 | */ | 1082 | return; |
995 | WARN_ON(mnt_get_writers(mnt)); | 1083 | } |
996 | if (unlikely(mnt->mnt_pins.first)) | 1084 | cleanup_mnt(mnt); |
997 | mnt_pin_kill(mnt); | ||
998 | fsnotify_vfsmount_delete(&mnt->mnt); | ||
999 | dput(mnt->mnt.mnt_root); | ||
1000 | deactivate_super(mnt->mnt.mnt_sb); | ||
1001 | mnt_free_id(mnt); | ||
1002 | call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt); | ||
1003 | } | 1085 | } |
1004 | 1086 | ||
1005 | void mntput(struct vfsmount *mnt) | 1087 | void mntput(struct vfsmount *mnt) |
@@ -1272,6 +1354,7 @@ void umount_tree(struct mount *mnt, int how) | |||
1272 | if (how < 2) | 1354 | if (how < 2) |
1273 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; | 1355 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; |
1274 | if (mnt_has_parent(p)) { | 1356 | if (mnt_has_parent(p)) { |
1357 | hlist_del_init(&p->mnt_mp_list); | ||
1275 | put_mountpoint(p->mnt_mp); | 1358 | put_mountpoint(p->mnt_mp); |
1276 | mnt_add_count(p->mnt_parent, -1); | 1359 | mnt_add_count(p->mnt_parent, -1); |
1277 | /* move the reference to mountpoint into ->mnt_ex_mountpoint */ | 1360 | /* move the reference to mountpoint into ->mnt_ex_mountpoint */ |
@@ -1385,6 +1468,37 @@ static int do_umount(struct mount *mnt, int flags) | |||
1385 | return retval; | 1468 | return retval; |
1386 | } | 1469 | } |
1387 | 1470 | ||
1471 | /* | ||
1472 | * __detach_mounts - lazily unmount all mounts on the specified dentry | ||
1473 | * | ||
1474 | * During unlink, rmdir, and d_drop it is possible to loose the path | ||
1475 | * to an existing mountpoint, and wind up leaking the mount. | ||
1476 | * detach_mounts allows lazily unmounting those mounts instead of | ||
1477 | * leaking them. | ||
1478 | * | ||
1479 | * The caller may hold dentry->d_inode->i_mutex. | ||
1480 | */ | ||
1481 | void __detach_mounts(struct dentry *dentry) | ||
1482 | { | ||
1483 | struct mountpoint *mp; | ||
1484 | struct mount *mnt; | ||
1485 | |||
1486 | namespace_lock(); | ||
1487 | mp = lookup_mountpoint(dentry); | ||
1488 | if (!mp) | ||
1489 | goto out_unlock; | ||
1490 | |||
1491 | lock_mount_hash(); | ||
1492 | while (!hlist_empty(&mp->m_list)) { | ||
1493 | mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); | ||
1494 | umount_tree(mnt, 2); | ||
1495 | } | ||
1496 | unlock_mount_hash(); | ||
1497 | put_mountpoint(mp); | ||
1498 | out_unlock: | ||
1499 | namespace_unlock(); | ||
1500 | } | ||
1501 | |||
1388 | /* | 1502 | /* |
1389 | * Is the caller allowed to modify his namespace? | 1503 | * Is the caller allowed to modify his namespace? |
1390 | */ | 1504 | */ |
@@ -1742,7 +1856,9 @@ retry: | |||
1742 | namespace_lock(); | 1856 | namespace_lock(); |
1743 | mnt = lookup_mnt(path); | 1857 | mnt = lookup_mnt(path); |
1744 | if (likely(!mnt)) { | 1858 | if (likely(!mnt)) { |
1745 | struct mountpoint *mp = new_mountpoint(dentry); | 1859 | struct mountpoint *mp = lookup_mountpoint(dentry); |
1860 | if (!mp) | ||
1861 | mp = new_mountpoint(dentry); | ||
1746 | if (IS_ERR(mp)) { | 1862 | if (IS_ERR(mp)) { |
1747 | namespace_unlock(); | 1863 | namespace_unlock(); |
1748 | mutex_unlock(&dentry->d_inode->i_mutex); | 1864 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -2398,21 +2514,9 @@ int copy_mount_options(const void __user * data, unsigned long *where) | |||
2398 | return 0; | 2514 | return 0; |
2399 | } | 2515 | } |
2400 | 2516 | ||
2401 | int copy_mount_string(const void __user *data, char **where) | 2517 | char *copy_mount_string(const void __user *data) |
2402 | { | 2518 | { |
2403 | char *tmp; | 2519 | return data ? strndup_user(data, PAGE_SIZE) : NULL; |
2404 | |||
2405 | if (!data) { | ||
2406 | *where = NULL; | ||
2407 | return 0; | ||
2408 | } | ||
2409 | |||
2410 | tmp = strndup_user(data, PAGE_SIZE); | ||
2411 | if (IS_ERR(tmp)) | ||
2412 | return PTR_ERR(tmp); | ||
2413 | |||
2414 | *where = tmp; | ||
2415 | return 0; | ||
2416 | } | 2520 | } |
2417 | 2521 | ||
2418 | /* | 2522 | /* |
@@ -2429,7 +2533,7 @@ int copy_mount_string(const void __user *data, char **where) | |||
2429 | * Therefore, if this magic number is present, it carries no information | 2533 | * Therefore, if this magic number is present, it carries no information |
2430 | * and must be discarded. | 2534 | * and must be discarded. |
2431 | */ | 2535 | */ |
2432 | long do_mount(const char *dev_name, const char *dir_name, | 2536 | long do_mount(const char *dev_name, const char __user *dir_name, |
2433 | const char *type_page, unsigned long flags, void *data_page) | 2537 | const char *type_page, unsigned long flags, void *data_page) |
2434 | { | 2538 | { |
2435 | struct path path; | 2539 | struct path path; |
@@ -2441,15 +2545,11 @@ long do_mount(const char *dev_name, const char *dir_name, | |||
2441 | flags &= ~MS_MGC_MSK; | 2545 | flags &= ~MS_MGC_MSK; |
2442 | 2546 | ||
2443 | /* Basic sanity checks */ | 2547 | /* Basic sanity checks */ |
2444 | |||
2445 | if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) | ||
2446 | return -EINVAL; | ||
2447 | |||
2448 | if (data_page) | 2548 | if (data_page) |
2449 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | 2549 | ((char *)data_page)[PAGE_SIZE - 1] = 0; |
2450 | 2550 | ||
2451 | /* ... and get the mountpoint */ | 2551 | /* ... and get the mountpoint */ |
2452 | retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); | 2552 | retval = user_path(dir_name, &path); |
2453 | if (retval) | 2553 | if (retval) |
2454 | return retval; | 2554 | return retval; |
2455 | 2555 | ||
@@ -2674,37 +2774,30 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2674 | { | 2774 | { |
2675 | int ret; | 2775 | int ret; |
2676 | char *kernel_type; | 2776 | char *kernel_type; |
2677 | struct filename *kernel_dir; | ||
2678 | char *kernel_dev; | 2777 | char *kernel_dev; |
2679 | unsigned long data_page; | 2778 | unsigned long data_page; |
2680 | 2779 | ||
2681 | ret = copy_mount_string(type, &kernel_type); | 2780 | kernel_type = copy_mount_string(type); |
2682 | if (ret < 0) | 2781 | ret = PTR_ERR(kernel_type); |
2782 | if (IS_ERR(kernel_type)) | ||
2683 | goto out_type; | 2783 | goto out_type; |
2684 | 2784 | ||
2685 | kernel_dir = getname(dir_name); | 2785 | kernel_dev = copy_mount_string(dev_name); |
2686 | if (IS_ERR(kernel_dir)) { | 2786 | ret = PTR_ERR(kernel_dev); |
2687 | ret = PTR_ERR(kernel_dir); | 2787 | if (IS_ERR(kernel_dev)) |
2688 | goto out_dir; | ||
2689 | } | ||
2690 | |||
2691 | ret = copy_mount_string(dev_name, &kernel_dev); | ||
2692 | if (ret < 0) | ||
2693 | goto out_dev; | 2788 | goto out_dev; |
2694 | 2789 | ||
2695 | ret = copy_mount_options(data, &data_page); | 2790 | ret = copy_mount_options(data, &data_page); |
2696 | if (ret < 0) | 2791 | if (ret < 0) |
2697 | goto out_data; | 2792 | goto out_data; |
2698 | 2793 | ||
2699 | ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags, | 2794 | ret = do_mount(kernel_dev, dir_name, kernel_type, flags, |
2700 | (void *) data_page); | 2795 | (void *) data_page); |
2701 | 2796 | ||
2702 | free_page(data_page); | 2797 | free_page(data_page); |
2703 | out_data: | 2798 | out_data: |
2704 | kfree(kernel_dev); | 2799 | kfree(kernel_dev); |
2705 | out_dev: | 2800 | out_dev: |
2706 | putname(kernel_dir); | ||
2707 | out_dir: | ||
2708 | kfree(kernel_type); | 2801 | kfree(kernel_type); |
2709 | out_type: | 2802 | out_type: |
2710 | return ret; | 2803 | return ret; |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 08b8ea8c353e..314e7add99b8 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -388,7 +388,6 @@ static struct dentry * | |||
388 | ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | 388 | ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) |
389 | { | 389 | { |
390 | struct dentry *dent = dentry; | 390 | struct dentry *dent = dentry; |
391 | struct list_head *next; | ||
392 | 391 | ||
393 | if (d_validate(dent, parent)) { | 392 | if (d_validate(dent, parent)) { |
394 | if (dent->d_name.len <= NCP_MAXPATHLEN && | 393 | if (dent->d_name.len <= NCP_MAXPATHLEN && |
@@ -404,9 +403,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
404 | 403 | ||
405 | /* If a pointer is invalid, we search the dentry. */ | 404 | /* If a pointer is invalid, we search the dentry. */ |
406 | spin_lock(&parent->d_lock); | 405 | spin_lock(&parent->d_lock); |
407 | next = parent->d_subdirs.next; | 406 | list_for_each_entry(dent, &parent->d_subdirs, d_u.d_child) { |
408 | while (next != &parent->d_subdirs) { | ||
409 | dent = list_entry(next, struct dentry, d_u.d_child); | ||
410 | if ((unsigned long)dent->d_fsdata == fpos) { | 407 | if ((unsigned long)dent->d_fsdata == fpos) { |
411 | if (dent->d_inode) | 408 | if (dent->d_inode) |
412 | dget(dent); | 409 | dget(dent); |
@@ -415,7 +412,6 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
415 | spin_unlock(&parent->d_lock); | 412 | spin_unlock(&parent->d_lock); |
416 | goto out; | 413 | goto out; |
417 | } | 414 | } |
418 | next = next->next; | ||
419 | } | 415 | } |
420 | spin_unlock(&parent->d_lock); | 416 | spin_unlock(&parent->d_lock); |
421 | return NULL; | 417 | return NULL; |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 32c06587351a..52cb19d66ecb 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -188,20 +188,14 @@ static inline void | |||
188 | ncp_renew_dentries(struct dentry *parent) | 188 | ncp_renew_dentries(struct dentry *parent) |
189 | { | 189 | { |
190 | struct ncp_server *server = NCP_SERVER(parent->d_inode); | 190 | struct ncp_server *server = NCP_SERVER(parent->d_inode); |
191 | struct list_head *next; | ||
192 | struct dentry *dentry; | 191 | struct dentry *dentry; |
193 | 192 | ||
194 | spin_lock(&parent->d_lock); | 193 | spin_lock(&parent->d_lock); |
195 | next = parent->d_subdirs.next; | 194 | list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { |
196 | while (next != &parent->d_subdirs) { | ||
197 | dentry = list_entry(next, struct dentry, d_u.d_child); | ||
198 | |||
199 | if (dentry->d_fsdata == NULL) | 195 | if (dentry->d_fsdata == NULL) |
200 | ncp_age_dentry(server, dentry); | 196 | ncp_age_dentry(server, dentry); |
201 | else | 197 | else |
202 | ncp_new_dentry(dentry); | 198 | ncp_new_dentry(dentry); |
203 | |||
204 | next = next->next; | ||
205 | } | 199 | } |
206 | spin_unlock(&parent->d_lock); | 200 | spin_unlock(&parent->d_lock); |
207 | } | 201 | } |
@@ -210,16 +204,12 @@ static inline void | |||
210 | ncp_invalidate_dircache_entries(struct dentry *parent) | 204 | ncp_invalidate_dircache_entries(struct dentry *parent) |
211 | { | 205 | { |
212 | struct ncp_server *server = NCP_SERVER(parent->d_inode); | 206 | struct ncp_server *server = NCP_SERVER(parent->d_inode); |
213 | struct list_head *next; | ||
214 | struct dentry *dentry; | 207 | struct dentry *dentry; |
215 | 208 | ||
216 | spin_lock(&parent->d_lock); | 209 | spin_lock(&parent->d_lock); |
217 | next = parent->d_subdirs.next; | 210 | list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { |
218 | while (next != &parent->d_subdirs) { | ||
219 | dentry = list_entry(next, struct dentry, d_u.d_child); | ||
220 | dentry->d_fsdata = NULL; | 211 | dentry->d_fsdata = NULL; |
221 | ncp_age_dentry(server, dentry); | 212 | ncp_age_dentry(server, dentry); |
222 | next = next->next; | ||
223 | } | 213 | } |
224 | spin_unlock(&parent->d_lock); | 214 | spin_unlock(&parent->d_lock); |
225 | } | 215 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 36d921f0c602..06e8cfcbb670 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -486,8 +486,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
486 | nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); | 486 | nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); |
487 | goto out; | 487 | goto out; |
488 | } else { | 488 | } else { |
489 | if (d_invalidate(dentry) != 0) | 489 | d_invalidate(dentry); |
490 | goto out; | ||
491 | dput(dentry); | 490 | dput(dentry); |
492 | } | 491 | } |
493 | } | 492 | } |
@@ -1211,10 +1210,6 @@ out_zap_parent: | |||
1211 | if (IS_ROOT(dentry)) | 1210 | if (IS_ROOT(dentry)) |
1212 | goto out_valid; | 1211 | goto out_valid; |
1213 | } | 1212 | } |
1214 | /* If we have submounts, don't unhash ! */ | ||
1215 | if (check_submounts_and_drop(dentry) != 0) | ||
1216 | goto out_valid; | ||
1217 | |||
1218 | dput(parent); | 1213 | dput(parent); |
1219 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", | 1214 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", |
1220 | __func__, dentry); | 1215 | __func__, dentry); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 950100e326a1..772efa45a452 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1565,7 +1565,6 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags) | |||
1565 | put_task_struct(task); | 1565 | put_task_struct(task); |
1566 | return 1; | 1566 | return 1; |
1567 | } | 1567 | } |
1568 | d_drop(dentry); | ||
1569 | return 0; | 1568 | return 0; |
1570 | } | 1569 | } |
1571 | 1570 | ||
@@ -1702,9 +1701,6 @@ out: | |||
1702 | put_task_struct(task); | 1701 | put_task_struct(task); |
1703 | 1702 | ||
1704 | out_notask: | 1703 | out_notask: |
1705 | if (status <= 0) | ||
1706 | d_drop(dentry); | ||
1707 | |||
1708 | return status; | 1704 | return status; |
1709 | } | 1705 | } |
1710 | 1706 | ||
@@ -2618,8 +2614,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) | |||
2618 | /* no ->d_hash() rejects on procfs */ | 2614 | /* no ->d_hash() rejects on procfs */ |
2619 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); | 2615 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); |
2620 | if (dentry) { | 2616 | if (dentry) { |
2621 | shrink_dcache_parent(dentry); | 2617 | d_invalidate(dentry); |
2622 | d_drop(dentry); | ||
2623 | dput(dentry); | 2618 | dput(dentry); |
2624 | } | 2619 | } |
2625 | 2620 | ||
@@ -2639,8 +2634,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) | |||
2639 | name.len = snprintf(buf, sizeof(buf), "%d", pid); | 2634 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2640 | dentry = d_hash_and_lookup(dir, &name); | 2635 | dentry = d_hash_and_lookup(dir, &name); |
2641 | if (dentry) { | 2636 | if (dentry) { |
2642 | shrink_dcache_parent(dentry); | 2637 | d_invalidate(dentry); |
2643 | d_drop(dentry); | ||
2644 | dput(dentry); | 2638 | dput(dentry); |
2645 | } | 2639 | } |
2646 | 2640 | ||
diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 955bb55fab8c..e11d7c590bb0 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c | |||
@@ -129,8 +129,6 @@ static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) | |||
129 | } | 129 | } |
130 | put_task_struct(task); | 130 | put_task_struct(task); |
131 | } | 131 | } |
132 | |||
133 | d_drop(dentry); | ||
134 | return 0; | 132 | return 0; |
135 | } | 133 | } |
136 | 134 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index 009d8542a889..7d9318c3d43c 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -513,6 +513,8 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t | |||
513 | return ret; | 513 | return ret; |
514 | } | 514 | } |
515 | 515 | ||
516 | EXPORT_SYMBOL(__kernel_write); | ||
517 | |||
516 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) | 518 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) |
517 | { | 519 | { |
518 | ssize_t ret; | 520 | ssize_t ret; |
diff --git a/fs/reiserfs/xattr.h b/fs/reiserfs/xattr.h index 857ec7e3016f..f620e9678dd5 100644 --- a/fs/reiserfs/xattr.h +++ b/fs/reiserfs/xattr.h | |||
@@ -7,7 +7,6 @@ struct inode; | |||
7 | struct dentry; | 7 | struct dentry; |
8 | struct iattr; | 8 | struct iattr; |
9 | struct super_block; | 9 | struct super_block; |
10 | struct nameidata; | ||
11 | 10 | ||
12 | int reiserfs_xattr_register_handlers(void) __init; | 11 | int reiserfs_xattr_register_handlers(void) __init; |
13 | void reiserfs_xattr_unregister_handlers(void); | 12 | void reiserfs_xattr_unregister_handlers(void); |
diff --git a/fs/super.c b/fs/super.c index 1b836107acee..eae088f6aaae 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -80,6 +80,8 @@ static unsigned long super_cache_scan(struct shrinker *shrink, | |||
80 | inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid); | 80 | inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid); |
81 | dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid); | 81 | dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid); |
82 | total_objects = dentries + inodes + fs_objects + 1; | 82 | total_objects = dentries + inodes + fs_objects + 1; |
83 | if (!total_objects) | ||
84 | total_objects = 1; | ||
83 | 85 | ||
84 | /* proportion the scan between the caches */ | 86 | /* proportion the scan between the caches */ |
85 | dentries = mult_frac(sc->nr_to_scan, dentries, total_objects); | 87 | dentries = mult_frac(sc->nr_to_scan, dentries, total_objects); |
diff --git a/fs/xattr.c b/fs/xattr.c index c69e6d43a0d2..64e83efb742d 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -364,13 +364,12 @@ out: | |||
364 | return error; | 364 | return error; |
365 | } | 365 | } |
366 | 366 | ||
367 | SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | 367 | static int path_setxattr(const char __user *pathname, |
368 | const char __user *, name, const void __user *, value, | 368 | const char __user *name, const void __user *value, |
369 | size_t, size, int, flags) | 369 | size_t size, int flags, unsigned int lookup_flags) |
370 | { | 370 | { |
371 | struct path path; | 371 | struct path path; |
372 | int error; | 372 | int error; |
373 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
374 | retry: | 373 | retry: |
375 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 374 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
376 | if (error) | 375 | if (error) |
@@ -388,28 +387,18 @@ retry: | |||
388 | return error; | 387 | return error; |
389 | } | 388 | } |
390 | 389 | ||
390 | SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | ||
391 | const char __user *, name, const void __user *, value, | ||
392 | size_t, size, int, flags) | ||
393 | { | ||
394 | return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW); | ||
395 | } | ||
396 | |||
391 | SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | 397 | SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, |
392 | const char __user *, name, const void __user *, value, | 398 | const char __user *, name, const void __user *, value, |
393 | size_t, size, int, flags) | 399 | size_t, size, int, flags) |
394 | { | 400 | { |
395 | struct path path; | 401 | return path_setxattr(pathname, name, value, size, flags, 0); |
396 | int error; | ||
397 | unsigned int lookup_flags = 0; | ||
398 | retry: | ||
399 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
400 | if (error) | ||
401 | return error; | ||
402 | error = mnt_want_write(path.mnt); | ||
403 | if (!error) { | ||
404 | error = setxattr(path.dentry, name, value, size, flags); | ||
405 | mnt_drop_write(path.mnt); | ||
406 | } | ||
407 | path_put(&path); | ||
408 | if (retry_estale(error, lookup_flags)) { | ||
409 | lookup_flags |= LOOKUP_REVAL; | ||
410 | goto retry; | ||
411 | } | ||
412 | return error; | ||
413 | } | 402 | } |
414 | 403 | ||
415 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | 404 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, |
@@ -481,12 +470,12 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, | |||
481 | return error; | 470 | return error; |
482 | } | 471 | } |
483 | 472 | ||
484 | SYSCALL_DEFINE4(getxattr, const char __user *, pathname, | 473 | static ssize_t path_getxattr(const char __user *pathname, |
485 | const char __user *, name, void __user *, value, size_t, size) | 474 | const char __user *name, void __user *value, |
475 | size_t size, unsigned int lookup_flags) | ||
486 | { | 476 | { |
487 | struct path path; | 477 | struct path path; |
488 | ssize_t error; | 478 | ssize_t error; |
489 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
490 | retry: | 479 | retry: |
491 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 480 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
492 | if (error) | 481 | if (error) |
@@ -500,23 +489,16 @@ retry: | |||
500 | return error; | 489 | return error; |
501 | } | 490 | } |
502 | 491 | ||
492 | SYSCALL_DEFINE4(getxattr, const char __user *, pathname, | ||
493 | const char __user *, name, void __user *, value, size_t, size) | ||
494 | { | ||
495 | return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW); | ||
496 | } | ||
497 | |||
503 | SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, | 498 | SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, |
504 | const char __user *, name, void __user *, value, size_t, size) | 499 | const char __user *, name, void __user *, value, size_t, size) |
505 | { | 500 | { |
506 | struct path path; | 501 | return path_getxattr(pathname, name, value, size, 0); |
507 | ssize_t error; | ||
508 | unsigned int lookup_flags = 0; | ||
509 | retry: | ||
510 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
511 | if (error) | ||
512 | return error; | ||
513 | error = getxattr(path.dentry, name, value, size); | ||
514 | path_put(&path); | ||
515 | if (retry_estale(error, lookup_flags)) { | ||
516 | lookup_flags |= LOOKUP_REVAL; | ||
517 | goto retry; | ||
518 | } | ||
519 | return error; | ||
520 | } | 502 | } |
521 | 503 | ||
522 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, | 504 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, |
@@ -571,12 +553,11 @@ listxattr(struct dentry *d, char __user *list, size_t size) | |||
571 | return error; | 553 | return error; |
572 | } | 554 | } |
573 | 555 | ||
574 | SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, | 556 | static ssize_t path_listxattr(const char __user *pathname, char __user *list, |
575 | size_t, size) | 557 | size_t size, unsigned int lookup_flags) |
576 | { | 558 | { |
577 | struct path path; | 559 | struct path path; |
578 | ssize_t error; | 560 | ssize_t error; |
579 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
580 | retry: | 561 | retry: |
581 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 562 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
582 | if (error) | 563 | if (error) |
@@ -590,23 +571,16 @@ retry: | |||
590 | return error; | 571 | return error; |
591 | } | 572 | } |
592 | 573 | ||
574 | SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, | ||
575 | size_t, size) | ||
576 | { | ||
577 | return path_listxattr(pathname, list, size, LOOKUP_FOLLOW); | ||
578 | } | ||
579 | |||
593 | SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, | 580 | SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, |
594 | size_t, size) | 581 | size_t, size) |
595 | { | 582 | { |
596 | struct path path; | 583 | return path_listxattr(pathname, list, size, 0); |
597 | ssize_t error; | ||
598 | unsigned int lookup_flags = 0; | ||
599 | retry: | ||
600 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
601 | if (error) | ||
602 | return error; | ||
603 | error = listxattr(path.dentry, list, size); | ||
604 | path_put(&path); | ||
605 | if (retry_estale(error, lookup_flags)) { | ||
606 | lookup_flags |= LOOKUP_REVAL; | ||
607 | goto retry; | ||
608 | } | ||
609 | return error; | ||
610 | } | 584 | } |
611 | 585 | ||
612 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) | 586 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) |
@@ -640,12 +614,11 @@ removexattr(struct dentry *d, const char __user *name) | |||
640 | return vfs_removexattr(d, kname); | 614 | return vfs_removexattr(d, kname); |
641 | } | 615 | } |
642 | 616 | ||
643 | SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | 617 | static int path_removexattr(const char __user *pathname, |
644 | const char __user *, name) | 618 | const char __user *name, unsigned int lookup_flags) |
645 | { | 619 | { |
646 | struct path path; | 620 | struct path path; |
647 | int error; | 621 | int error; |
648 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
649 | retry: | 622 | retry: |
650 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 623 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
651 | if (error) | 624 | if (error) |
@@ -663,27 +636,16 @@ retry: | |||
663 | return error; | 636 | return error; |
664 | } | 637 | } |
665 | 638 | ||
639 | SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | ||
640 | const char __user *, name) | ||
641 | { | ||
642 | return path_removexattr(pathname, name, LOOKUP_FOLLOW); | ||
643 | } | ||
644 | |||
666 | SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | 645 | SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, |
667 | const char __user *, name) | 646 | const char __user *, name) |
668 | { | 647 | { |
669 | struct path path; | 648 | return path_removexattr(pathname, name, 0); |
670 | int error; | ||
671 | unsigned int lookup_flags = 0; | ||
672 | retry: | ||
673 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
674 | if (error) | ||
675 | return error; | ||
676 | error = mnt_want_write(path.mnt); | ||
677 | if (!error) { | ||
678 | error = removexattr(path.dentry, name); | ||
679 | mnt_drop_write(path.mnt); | ||
680 | } | ||
681 | path_put(&path); | ||
682 | if (retry_estale(error, lookup_flags)) { | ||
683 | lookup_flags |= LOOKUP_REVAL; | ||
684 | goto retry; | ||
685 | } | ||
686 | return error; | ||
687 | } | 649 | } |
688 | 650 | ||
689 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | 651 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 75a227cc7ce2..b2a2a08523bf 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/rcupdate.h> | 11 | #include <linux/rcupdate.h> |
12 | #include <linux/lockref.h> | 12 | #include <linux/lockref.h> |
13 | 13 | ||
14 | struct nameidata; | ||
15 | struct path; | 14 | struct path; |
16 | struct vfsmount; | 15 | struct vfsmount; |
17 | 16 | ||
@@ -226,11 +225,6 @@ struct dentry_operations { | |||
226 | 225 | ||
227 | extern seqlock_t rename_lock; | 226 | extern seqlock_t rename_lock; |
228 | 227 | ||
229 | static inline int dname_external(const struct dentry *dentry) | ||
230 | { | ||
231 | return dentry->d_name.name != dentry->d_iname; | ||
232 | } | ||
233 | |||
234 | /* | 228 | /* |
235 | * These are the low-level FS interfaces to the dcache.. | 229 | * These are the low-level FS interfaces to the dcache.. |
236 | */ | 230 | */ |
@@ -254,7 +248,7 @@ extern struct dentry * d_obtain_root(struct inode *); | |||
254 | extern void shrink_dcache_sb(struct super_block *); | 248 | extern void shrink_dcache_sb(struct super_block *); |
255 | extern void shrink_dcache_parent(struct dentry *); | 249 | extern void shrink_dcache_parent(struct dentry *); |
256 | extern void shrink_dcache_for_umount(struct super_block *); | 250 | extern void shrink_dcache_for_umount(struct super_block *); |
257 | extern int d_invalidate(struct dentry *); | 251 | extern void d_invalidate(struct dentry *); |
258 | 252 | ||
259 | /* only used at mount-time */ | 253 | /* only used at mount-time */ |
260 | extern struct dentry * d_make_root(struct inode *); | 254 | extern struct dentry * d_make_root(struct inode *); |
@@ -269,7 +263,6 @@ extern void d_prune_aliases(struct inode *); | |||
269 | 263 | ||
270 | /* test whether we have any submounts in a subdir tree */ | 264 | /* test whether we have any submounts in a subdir tree */ |
271 | extern int have_submounts(struct dentry *); | 265 | extern int have_submounts(struct dentry *); |
272 | extern int check_submounts_and_drop(struct dentry *); | ||
273 | 266 | ||
274 | /* | 267 | /* |
275 | * This adds the entry to the hash queues. | 268 | * This adds the entry to the hash queues. |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 2023306c620e..ab4f1a10da20 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1839,7 +1839,8 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); | |||
1839 | extern void kern_unmount(struct vfsmount *mnt); | 1839 | extern void kern_unmount(struct vfsmount *mnt); |
1840 | extern int may_umount_tree(struct vfsmount *); | 1840 | extern int may_umount_tree(struct vfsmount *); |
1841 | extern int may_umount(struct vfsmount *); | 1841 | extern int may_umount(struct vfsmount *); |
1842 | extern long do_mount(const char *, const char *, const char *, unsigned long, void *); | 1842 | extern long do_mount(const char *, const char __user *, |
1843 | const char *, unsigned long, void *); | ||
1843 | extern struct vfsmount *collect_mounts(struct path *); | 1844 | extern struct vfsmount *collect_mounts(struct path *); |
1844 | extern void drop_collected_mounts(struct vfsmount *); | 1845 | extern void drop_collected_mounts(struct vfsmount *); |
1845 | extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, | 1846 | extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, |
@@ -1858,7 +1859,7 @@ extern int current_umask(void); | |||
1858 | extern void ihold(struct inode * inode); | 1859 | extern void ihold(struct inode * inode); |
1859 | extern void iput(struct inode *); | 1860 | extern void iput(struct inode *); |
1860 | 1861 | ||
1861 | static inline struct inode *file_inode(struct file *f) | 1862 | static inline struct inode *file_inode(const struct file *f) |
1862 | { | 1863 | { |
1863 | return f->f_inode; | 1864 | return f->f_inode; |
1864 | } | 1865 | } |
diff --git a/include/linux/uio.h b/include/linux/uio.h index 290fbf0b6b8a..9b1581414cd4 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
@@ -80,6 +80,9 @@ size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | |||
80 | struct iov_iter *i); | 80 | struct iov_iter *i); |
81 | size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes, | 81 | size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes, |
82 | struct iov_iter *i); | 82 | struct iov_iter *i); |
83 | size_t copy_to_iter(void *addr, size_t bytes, struct iov_iter *i); | ||
84 | size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i); | ||
85 | size_t iov_iter_zero(size_t bytes, struct iov_iter *); | ||
83 | unsigned long iov_iter_alignment(const struct iov_iter *i); | 86 | unsigned long iov_iter_alignment(const struct iov_iter *i); |
84 | void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, | 87 | void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, |
85 | unsigned long nr_segs, size_t count); | 88 | unsigned long nr_segs, size_t count); |
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 1ce770687ea8..7a6e69441f75 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -519,14 +519,13 @@ struct devkmsg_user { | |||
519 | char buf[8192]; | 519 | char buf[8192]; |
520 | }; | 520 | }; |
521 | 521 | ||
522 | static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, | 522 | static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) |
523 | unsigned long count, loff_t pos) | ||
524 | { | 523 | { |
525 | char *buf, *line; | 524 | char *buf, *line; |
526 | int i; | 525 | int i; |
527 | int level = default_message_loglevel; | 526 | int level = default_message_loglevel; |
528 | int facility = 1; /* LOG_USER */ | 527 | int facility = 1; /* LOG_USER */ |
529 | size_t len = iov_length(iv, count); | 528 | size_t len = iocb->ki_nbytes; |
530 | ssize_t ret = len; | 529 | ssize_t ret = len; |
531 | 530 | ||
532 | if (len > LOG_LINE_MAX) | 531 | if (len > LOG_LINE_MAX) |
@@ -535,13 +534,10 @@ static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, | |||
535 | if (buf == NULL) | 534 | if (buf == NULL) |
536 | return -ENOMEM; | 535 | return -ENOMEM; |
537 | 536 | ||
538 | line = buf; | 537 | buf[len] = '\0'; |
539 | for (i = 0; i < count; i++) { | 538 | if (copy_from_iter(buf, len, from) != len) { |
540 | if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) { | 539 | kfree(buf); |
541 | ret = -EFAULT; | 540 | return -EFAULT; |
542 | goto out; | ||
543 | } | ||
544 | line += iv[i].iov_len; | ||
545 | } | 541 | } |
546 | 542 | ||
547 | /* | 543 | /* |
@@ -567,10 +563,8 @@ static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, | |||
567 | line = endp; | 563 | line = endp; |
568 | } | 564 | } |
569 | } | 565 | } |
570 | line[len] = '\0'; | ||
571 | 566 | ||
572 | printk_emit(facility, level, NULL, 0, "%s", line); | 567 | printk_emit(facility, level, NULL, 0, "%s", line); |
573 | out: | ||
574 | kfree(buf); | 568 | kfree(buf); |
575 | return ret; | 569 | return ret; |
576 | } | 570 | } |
@@ -802,7 +796,7 @@ static int devkmsg_release(struct inode *inode, struct file *file) | |||
802 | const struct file_operations kmsg_fops = { | 796 | const struct file_operations kmsg_fops = { |
803 | .open = devkmsg_open, | 797 | .open = devkmsg_open, |
804 | .read = devkmsg_read, | 798 | .read = devkmsg_read, |
805 | .aio_write = devkmsg_writev, | 799 | .write_iter = devkmsg_write, |
806 | .llseek = devkmsg_llseek, | 800 | .llseek = devkmsg_llseek, |
807 | .poll = devkmsg_poll, | 801 | .poll = devkmsg_poll, |
808 | .release = devkmsg_release, | 802 | .release = devkmsg_release, |
diff --git a/mm/iov_iter.c b/mm/iov_iter.c index 9a09f2034fcc..eafcf60f6b83 100644 --- a/mm/iov_iter.c +++ b/mm/iov_iter.c | |||
@@ -4,6 +4,96 @@ | |||
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/vmalloc.h> | 5 | #include <linux/vmalloc.h> |
6 | 6 | ||
7 | static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i) | ||
8 | { | ||
9 | size_t skip, copy, left, wanted; | ||
10 | const struct iovec *iov; | ||
11 | char __user *buf; | ||
12 | |||
13 | if (unlikely(bytes > i->count)) | ||
14 | bytes = i->count; | ||
15 | |||
16 | if (unlikely(!bytes)) | ||
17 | return 0; | ||
18 | |||
19 | wanted = bytes; | ||
20 | iov = i->iov; | ||
21 | skip = i->iov_offset; | ||
22 | buf = iov->iov_base + skip; | ||
23 | copy = min(bytes, iov->iov_len - skip); | ||
24 | |||
25 | left = __copy_to_user(buf, from, copy); | ||
26 | copy -= left; | ||
27 | skip += copy; | ||
28 | from += copy; | ||
29 | bytes -= copy; | ||
30 | while (unlikely(!left && bytes)) { | ||
31 | iov++; | ||
32 | buf = iov->iov_base; | ||
33 | copy = min(bytes, iov->iov_len); | ||
34 | left = __copy_to_user(buf, from, copy); | ||
35 | copy -= left; | ||
36 | skip = copy; | ||
37 | from += copy; | ||
38 | bytes -= copy; | ||
39 | } | ||
40 | |||
41 | if (skip == iov->iov_len) { | ||
42 | iov++; | ||
43 | skip = 0; | ||
44 | } | ||
45 | i->count -= wanted - bytes; | ||
46 | i->nr_segs -= iov - i->iov; | ||
47 | i->iov = iov; | ||
48 | i->iov_offset = skip; | ||
49 | return wanted - bytes; | ||
50 | } | ||
51 | |||
52 | static size_t copy_from_iter_iovec(void *to, size_t bytes, struct iov_iter *i) | ||
53 | { | ||
54 | size_t skip, copy, left, wanted; | ||
55 | const struct iovec *iov; | ||
56 | char __user *buf; | ||
57 | |||
58 | if (unlikely(bytes > i->count)) | ||
59 | bytes = i->count; | ||
60 | |||
61 | if (unlikely(!bytes)) | ||
62 | return 0; | ||
63 | |||
64 | wanted = bytes; | ||
65 | iov = i->iov; | ||
66 | skip = i->iov_offset; | ||
67 | buf = iov->iov_base + skip; | ||
68 | copy = min(bytes, iov->iov_len - skip); | ||
69 | |||
70 | left = __copy_from_user(to, buf, copy); | ||
71 | copy -= left; | ||
72 | skip += copy; | ||
73 | to += copy; | ||
74 | bytes -= copy; | ||
75 | while (unlikely(!left && bytes)) { | ||
76 | iov++; | ||
77 | buf = iov->iov_base; | ||
78 | copy = min(bytes, iov->iov_len); | ||
79 | left = __copy_from_user(to, buf, copy); | ||
80 | copy -= left; | ||
81 | skip = copy; | ||
82 | to += copy; | ||
83 | bytes -= copy; | ||
84 | } | ||
85 | |||
86 | if (skip == iov->iov_len) { | ||
87 | iov++; | ||
88 | skip = 0; | ||
89 | } | ||
90 | i->count -= wanted - bytes; | ||
91 | i->nr_segs -= iov - i->iov; | ||
92 | i->iov = iov; | ||
93 | i->iov_offset = skip; | ||
94 | return wanted - bytes; | ||
95 | } | ||
96 | |||
7 | static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t bytes, | 97 | static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t bytes, |
8 | struct iov_iter *i) | 98 | struct iov_iter *i) |
9 | { | 99 | { |
@@ -166,6 +256,50 @@ done: | |||
166 | return wanted - bytes; | 256 | return wanted - bytes; |
167 | } | 257 | } |
168 | 258 | ||
259 | static size_t zero_iovec(size_t bytes, struct iov_iter *i) | ||
260 | { | ||
261 | size_t skip, copy, left, wanted; | ||
262 | const struct iovec *iov; | ||
263 | char __user *buf; | ||
264 | |||
265 | if (unlikely(bytes > i->count)) | ||
266 | bytes = i->count; | ||
267 | |||
268 | if (unlikely(!bytes)) | ||
269 | return 0; | ||
270 | |||
271 | wanted = bytes; | ||
272 | iov = i->iov; | ||
273 | skip = i->iov_offset; | ||
274 | buf = iov->iov_base + skip; | ||
275 | copy = min(bytes, iov->iov_len - skip); | ||
276 | |||
277 | left = __clear_user(buf, copy); | ||
278 | copy -= left; | ||
279 | skip += copy; | ||
280 | bytes -= copy; | ||
281 | |||
282 | while (unlikely(!left && bytes)) { | ||
283 | iov++; | ||
284 | buf = iov->iov_base; | ||
285 | copy = min(bytes, iov->iov_len); | ||
286 | left = __clear_user(buf, copy); | ||
287 | copy -= left; | ||
288 | skip = copy; | ||
289 | bytes -= copy; | ||
290 | } | ||
291 | |||
292 | if (skip == iov->iov_len) { | ||
293 | iov++; | ||
294 | skip = 0; | ||
295 | } | ||
296 | i->count -= wanted - bytes; | ||
297 | i->nr_segs -= iov - i->iov; | ||
298 | i->iov = iov; | ||
299 | i->iov_offset = skip; | ||
300 | return wanted - bytes; | ||
301 | } | ||
302 | |||
169 | static size_t __iovec_copy_from_user_inatomic(char *vaddr, | 303 | static size_t __iovec_copy_from_user_inatomic(char *vaddr, |
170 | const struct iovec *iov, size_t base, size_t bytes) | 304 | const struct iovec *iov, size_t base, size_t bytes) |
171 | { | 305 | { |
@@ -414,12 +548,17 @@ static void memcpy_to_page(struct page *page, size_t offset, char *from, size_t | |||
414 | kunmap_atomic(to); | 548 | kunmap_atomic(to); |
415 | } | 549 | } |
416 | 550 | ||
417 | static size_t copy_page_to_iter_bvec(struct page *page, size_t offset, size_t bytes, | 551 | static void memzero_page(struct page *page, size_t offset, size_t len) |
418 | struct iov_iter *i) | 552 | { |
553 | char *addr = kmap_atomic(page); | ||
554 | memset(addr + offset, 0, len); | ||
555 | kunmap_atomic(addr); | ||
556 | } | ||
557 | |||
558 | static size_t copy_to_iter_bvec(void *from, size_t bytes, struct iov_iter *i) | ||
419 | { | 559 | { |
420 | size_t skip, copy, wanted; | 560 | size_t skip, copy, wanted; |
421 | const struct bio_vec *bvec; | 561 | const struct bio_vec *bvec; |
422 | void *kaddr, *from; | ||
423 | 562 | ||
424 | if (unlikely(bytes > i->count)) | 563 | if (unlikely(bytes > i->count)) |
425 | bytes = i->count; | 564 | bytes = i->count; |
@@ -432,8 +571,6 @@ static size_t copy_page_to_iter_bvec(struct page *page, size_t offset, size_t by | |||
432 | skip = i->iov_offset; | 571 | skip = i->iov_offset; |
433 | copy = min_t(size_t, bytes, bvec->bv_len - skip); | 572 | copy = min_t(size_t, bytes, bvec->bv_len - skip); |
434 | 573 | ||
435 | kaddr = kmap_atomic(page); | ||
436 | from = kaddr + offset; | ||
437 | memcpy_to_page(bvec->bv_page, skip + bvec->bv_offset, from, copy); | 574 | memcpy_to_page(bvec->bv_page, skip + bvec->bv_offset, from, copy); |
438 | skip += copy; | 575 | skip += copy; |
439 | from += copy; | 576 | from += copy; |
@@ -446,7 +583,6 @@ static size_t copy_page_to_iter_bvec(struct page *page, size_t offset, size_t by | |||
446 | from += copy; | 583 | from += copy; |
447 | bytes -= copy; | 584 | bytes -= copy; |
448 | } | 585 | } |
449 | kunmap_atomic(kaddr); | ||
450 | if (skip == bvec->bv_len) { | 586 | if (skip == bvec->bv_len) { |
451 | bvec++; | 587 | bvec++; |
452 | skip = 0; | 588 | skip = 0; |
@@ -458,12 +594,10 @@ static size_t copy_page_to_iter_bvec(struct page *page, size_t offset, size_t by | |||
458 | return wanted - bytes; | 594 | return wanted - bytes; |
459 | } | 595 | } |
460 | 596 | ||
461 | static size_t copy_page_from_iter_bvec(struct page *page, size_t offset, size_t bytes, | 597 | static size_t copy_from_iter_bvec(void *to, size_t bytes, struct iov_iter *i) |
462 | struct iov_iter *i) | ||
463 | { | 598 | { |
464 | size_t skip, copy, wanted; | 599 | size_t skip, copy, wanted; |
465 | const struct bio_vec *bvec; | 600 | const struct bio_vec *bvec; |
466 | void *kaddr, *to; | ||
467 | 601 | ||
468 | if (unlikely(bytes > i->count)) | 602 | if (unlikely(bytes > i->count)) |
469 | bytes = i->count; | 603 | bytes = i->count; |
@@ -475,10 +609,6 @@ static size_t copy_page_from_iter_bvec(struct page *page, size_t offset, size_t | |||
475 | bvec = i->bvec; | 609 | bvec = i->bvec; |
476 | skip = i->iov_offset; | 610 | skip = i->iov_offset; |
477 | 611 | ||
478 | kaddr = kmap_atomic(page); | ||
479 | |||
480 | to = kaddr + offset; | ||
481 | |||
482 | copy = min(bytes, bvec->bv_len - skip); | 612 | copy = min(bytes, bvec->bv_len - skip); |
483 | 613 | ||
484 | memcpy_from_page(to, bvec->bv_page, bvec->bv_offset + skip, copy); | 614 | memcpy_from_page(to, bvec->bv_page, bvec->bv_offset + skip, copy); |
@@ -495,7 +625,6 @@ static size_t copy_page_from_iter_bvec(struct page *page, size_t offset, size_t | |||
495 | to += copy; | 625 | to += copy; |
496 | bytes -= copy; | 626 | bytes -= copy; |
497 | } | 627 | } |
498 | kunmap_atomic(kaddr); | ||
499 | if (skip == bvec->bv_len) { | 628 | if (skip == bvec->bv_len) { |
500 | bvec++; | 629 | bvec++; |
501 | skip = 0; | 630 | skip = 0; |
@@ -507,6 +636,61 @@ static size_t copy_page_from_iter_bvec(struct page *page, size_t offset, size_t | |||
507 | return wanted; | 636 | return wanted; |
508 | } | 637 | } |
509 | 638 | ||
639 | static size_t copy_page_to_iter_bvec(struct page *page, size_t offset, | ||
640 | size_t bytes, struct iov_iter *i) | ||
641 | { | ||
642 | void *kaddr = kmap_atomic(page); | ||
643 | size_t wanted = copy_to_iter_bvec(kaddr + offset, bytes, i); | ||
644 | kunmap_atomic(kaddr); | ||
645 | return wanted; | ||
646 | } | ||
647 | |||
648 | static size_t copy_page_from_iter_bvec(struct page *page, size_t offset, | ||
649 | size_t bytes, struct iov_iter *i) | ||
650 | { | ||
651 | void *kaddr = kmap_atomic(page); | ||
652 | size_t wanted = copy_from_iter_bvec(kaddr + offset, bytes, i); | ||
653 | kunmap_atomic(kaddr); | ||
654 | return wanted; | ||
655 | } | ||
656 | |||
657 | static size_t zero_bvec(size_t bytes, struct iov_iter *i) | ||
658 | { | ||
659 | size_t skip, copy, wanted; | ||
660 | const struct bio_vec *bvec; | ||
661 | |||
662 | if (unlikely(bytes > i->count)) | ||
663 | bytes = i->count; | ||
664 | |||
665 | if (unlikely(!bytes)) | ||
666 | return 0; | ||
667 | |||
668 | wanted = bytes; | ||
669 | bvec = i->bvec; | ||
670 | skip = i->iov_offset; | ||
671 | copy = min_t(size_t, bytes, bvec->bv_len - skip); | ||
672 | |||
673 | memzero_page(bvec->bv_page, skip + bvec->bv_offset, copy); | ||
674 | skip += copy; | ||
675 | bytes -= copy; | ||
676 | while (bytes) { | ||
677 | bvec++; | ||
678 | copy = min(bytes, (size_t)bvec->bv_len); | ||
679 | memzero_page(bvec->bv_page, bvec->bv_offset, copy); | ||
680 | skip = copy; | ||
681 | bytes -= copy; | ||
682 | } | ||
683 | if (skip == bvec->bv_len) { | ||
684 | bvec++; | ||
685 | skip = 0; | ||
686 | } | ||
687 | i->count -= wanted - bytes; | ||
688 | i->nr_segs -= bvec - i->bvec; | ||
689 | i->bvec = bvec; | ||
690 | i->iov_offset = skip; | ||
691 | return wanted - bytes; | ||
692 | } | ||
693 | |||
510 | static size_t copy_from_user_bvec(struct page *page, | 694 | static size_t copy_from_user_bvec(struct page *page, |
511 | struct iov_iter *i, unsigned long offset, size_t bytes) | 695 | struct iov_iter *i, unsigned long offset, size_t bytes) |
512 | { | 696 | { |
@@ -672,6 +856,34 @@ size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes, | |||
672 | } | 856 | } |
673 | EXPORT_SYMBOL(copy_page_from_iter); | 857 | EXPORT_SYMBOL(copy_page_from_iter); |
674 | 858 | ||
859 | size_t copy_to_iter(void *addr, size_t bytes, struct iov_iter *i) | ||
860 | { | ||
861 | if (i->type & ITER_BVEC) | ||
862 | return copy_to_iter_bvec(addr, bytes, i); | ||
863 | else | ||
864 | return copy_to_iter_iovec(addr, bytes, i); | ||
865 | } | ||
866 | EXPORT_SYMBOL(copy_to_iter); | ||
867 | |||
868 | size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i) | ||
869 | { | ||
870 | if (i->type & ITER_BVEC) | ||
871 | return copy_from_iter_bvec(addr, bytes, i); | ||
872 | else | ||
873 | return copy_from_iter_iovec(addr, bytes, i); | ||
874 | } | ||
875 | EXPORT_SYMBOL(copy_from_iter); | ||
876 | |||
877 | size_t iov_iter_zero(size_t bytes, struct iov_iter *i) | ||
878 | { | ||
879 | if (i->type & ITER_BVEC) { | ||
880 | return zero_bvec(bytes, i); | ||
881 | } else { | ||
882 | return zero_iovec(bytes, i); | ||
883 | } | ||
884 | } | ||
885 | EXPORT_SYMBOL(iov_iter_zero); | ||
886 | |||
675 | size_t iov_iter_copy_from_user_atomic(struct page *page, | 887 | size_t iov_iter_copy_from_user_atomic(struct page *page, |
676 | struct iov_iter *i, unsigned long offset, size_t bytes) | 888 | struct iov_iter *i, unsigned long offset, size_t bytes) |
677 | { | 889 | { |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index c416725d28c4..7a186e74b1b3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -715,7 +715,7 @@ static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, | |||
715 | * after validation, the socket and the ring may only be used by a | 715 | * after validation, the socket and the ring may only be used by a |
716 | * single process, otherwise we fall back to copying. | 716 | * single process, otherwise we fall back to copying. |
717 | */ | 717 | */ |
718 | if (atomic_long_read(&sk->sk_socket->file->f_count) > 2 || | 718 | if (atomic_long_read(&sk->sk_socket->file->f_count) > 1 || |
719 | atomic_read(&nlk->mapped) > 1) | 719 | atomic_read(&nlk->mapped) > 1) |
720 | excl = false; | 720 | excl = false; |
721 | 721 | ||
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 2553e5b55b89..d87767f76903 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -9,78 +9,48 @@ | |||
9 | */ | 9 | */ |
10 | s64 perf_atoll(const char *str) | 10 | s64 perf_atoll(const char *str) |
11 | { | 11 | { |
12 | unsigned int i; | 12 | s64 length; |
13 | s64 length = -1, unit = 1; | 13 | char *p; |
14 | char c; | ||
14 | 15 | ||
15 | if (!isdigit(str[0])) | 16 | if (!isdigit(str[0])) |
16 | goto out_err; | 17 | goto out_err; |
17 | 18 | ||
18 | for (i = 1; i < strlen(str); i++) { | 19 | length = strtoll(str, &p, 10); |
19 | switch (str[i]) { | 20 | switch (c = *p++) { |
20 | case 'B': | 21 | case 'b': case 'B': |
21 | case 'b': | 22 | if (*p) |
22 | break; | ||
23 | case 'K': | ||
24 | if (str[i + 1] != 'B') | ||
25 | goto out_err; | ||
26 | else | ||
27 | goto kilo; | ||
28 | case 'k': | ||
29 | if (str[i + 1] != 'b') | ||
30 | goto out_err; | ||
31 | kilo: | ||
32 | unit = K; | ||
33 | break; | ||
34 | case 'M': | ||
35 | if (str[i + 1] != 'B') | ||
36 | goto out_err; | ||
37 | else | ||
38 | goto mega; | ||
39 | case 'm': | ||
40 | if (str[i + 1] != 'b') | ||
41 | goto out_err; | 23 | goto out_err; |
42 | mega: | 24 | case '\0': |
43 | unit = K * K; | 25 | return length; |
26 | default: | ||
27 | goto out_err; | ||
28 | /* two-letter suffices */ | ||
29 | case 'k': case 'K': | ||
30 | length <<= 10; | ||
44 | break; | 31 | break; |
45 | case 'G': | 32 | case 'm': case 'M': |
46 | if (str[i + 1] != 'B') | 33 | length <<= 20; |
47 | goto out_err; | ||
48 | else | ||
49 | goto giga; | ||
50 | case 'g': | ||
51 | if (str[i + 1] != 'b') | ||
52 | goto out_err; | ||
53 | giga: | ||
54 | unit = K * K * K; | ||
55 | break; | 34 | break; |
56 | case 'T': | 35 | case 'g': case 'G': |
57 | if (str[i + 1] != 'B') | 36 | length <<= 30; |
58 | goto out_err; | ||
59 | else | ||
60 | goto tera; | ||
61 | case 't': | ||
62 | if (str[i + 1] != 'b') | ||
63 | goto out_err; | ||
64 | tera: | ||
65 | unit = K * K * K * K; | ||
66 | break; | 37 | break; |
67 | case '\0': /* only specified figures */ | 38 | case 't': case 'T': |
68 | unit = 1; | 39 | length <<= 40; |
69 | break; | 40 | break; |
70 | default: | ||
71 | if (!isdigit(str[i])) | ||
72 | goto out_err; | ||
73 | break; | ||
74 | } | ||
75 | } | 41 | } |
76 | 42 | /* we want the cases to match */ | |
77 | length = atoll(str) * unit; | 43 | if (islower(c)) { |
78 | goto out; | 44 | if (strcmp(p, "b") != 0) |
45 | goto out_err; | ||
46 | } else { | ||
47 | if (strcmp(p, "B") != 0) | ||
48 | goto out_err; | ||
49 | } | ||
50 | return length; | ||
79 | 51 | ||
80 | out_err: | 52 | out_err: |
81 | length = -1; | 53 | return -1; |
82 | out: | ||
83 | return length; | ||
84 | } | 54 | } |
85 | 55 | ||
86 | /* | 56 | /* |