aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/affs/affs.h2
-rw-r--r--fs/affs/amigaffs.c28
-rw-r--r--fs/affs/file.c76
-rw-r--r--fs/befs/linuxvfs.c4
-rw-r--r--fs/binfmt_em86.c4
-rw-r--r--fs/binfmt_misc.c4
-rw-r--r--fs/binfmt_script.c10
-rw-r--r--fs/drop_caches.c11
-rw-r--r--fs/exec.c113
-rw-r--r--fs/fat/fat.h1
-rw-r--r--fs/fat/file.c3
-rw-r--r--fs/fat/inode.c12
-rw-r--r--fs/hugetlbfs/inode.c14
-rw-r--r--fs/inode.c2
-rw-r--r--fs/namei.c2
-rw-r--r--fs/notify/dnotify/dnotify.c4
-rw-r--r--fs/notify/fdinfo.c6
-rw-r--r--fs/notify/fsnotify.c4
-rw-r--r--fs/notify/fsnotify.h12
-rw-r--r--fs/notify/inode_mark.c113
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c2
-rw-r--r--fs/notify/inotify/inotify_user.c10
-rw-r--r--fs/notify/mark.c97
-rw-r--r--fs/notify/vfsmount_mark.c109
-rw-r--r--fs/open.c11
-rw-r--r--fs/seq_file.c6
26 files changed, 376 insertions, 284 deletions
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index 9bca88159725..ff44ff3ff015 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -135,8 +135,10 @@ extern void affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
135extern void secs_to_datestamp(time_t secs, struct affs_date *ds); 135extern void secs_to_datestamp(time_t secs, struct affs_date *ds);
136extern umode_t prot_to_mode(u32 prot); 136extern umode_t prot_to_mode(u32 prot);
137extern void mode_to_prot(struct inode *inode); 137extern void mode_to_prot(struct inode *inode);
138__printf(3, 4)
138extern void affs_error(struct super_block *sb, const char *function, 139extern void affs_error(struct super_block *sb, const char *function,
139 const char *fmt, ...); 140 const char *fmt, ...);
141__printf(3, 4)
140extern void affs_warning(struct super_block *sb, const char *function, 142extern void affs_warning(struct super_block *sb, const char *function,
141 const char *fmt, ...); 143 const char *fmt, ...);
142extern bool affs_nofilenametruncate(const struct dentry *dentry); 144extern bool affs_nofilenametruncate(const struct dentry *dentry);
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index 937ce8754b24..c852f2fa1710 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -10,8 +10,6 @@
10 10
11#include "affs.h" 11#include "affs.h"
12 12
13static char ErrorBuffer[256];
14
15/* 13/*
16 * Functions for accessing Amiga-FFS structures. 14 * Functions for accessing Amiga-FFS structures.
17 */ 15 */
@@ -444,30 +442,30 @@ mode_to_prot(struct inode *inode)
444void 442void
445affs_error(struct super_block *sb, const char *function, const char *fmt, ...) 443affs_error(struct super_block *sb, const char *function, const char *fmt, ...)
446{ 444{
447 va_list args; 445 struct va_format vaf;
448 446 va_list args;
449 va_start(args,fmt);
450 vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args);
451 va_end(args);
452 447
453 pr_crit("error (device %s): %s(): %s\n", sb->s_id, 448 va_start(args, fmt);
454 function,ErrorBuffer); 449 vaf.fmt = fmt;
450 vaf.va = &args;
451 pr_crit("error (device %s): %s(): %pV\n", sb->s_id, function, &vaf);
455 if (!(sb->s_flags & MS_RDONLY)) 452 if (!(sb->s_flags & MS_RDONLY))
456 pr_warn("Remounting filesystem read-only\n"); 453 pr_warn("Remounting filesystem read-only\n");
457 sb->s_flags |= MS_RDONLY; 454 sb->s_flags |= MS_RDONLY;
455 va_end(args);
458} 456}
459 457
460void 458void
461affs_warning(struct super_block *sb, const char *function, const char *fmt, ...) 459affs_warning(struct super_block *sb, const char *function, const char *fmt, ...)
462{ 460{
463 va_list args; 461 struct va_format vaf;
462 va_list args;
464 463
465 va_start(args,fmt); 464 va_start(args, fmt);
466 vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); 465 vaf.fmt = fmt;
466 vaf.va = &args;
467 pr_warn("(device %s): %s(): %pV\n", sb->s_id, function, &vaf);
467 va_end(args); 468 va_end(args);
468
469 pr_warn("(device %s): %s(): %s\n", sb->s_id,
470 function,ErrorBuffer);
471} 469}
472 470
473bool 471bool
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 1ed590aafecf..8faa6593ca6d 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -12,35 +12,10 @@
12 * affs regular file handling primitives 12 * affs regular file handling primitives
13 */ 13 */
14 14
15#include <linux/aio.h>
15#include "affs.h" 16#include "affs.h"
16 17
17#if PAGE_SIZE < 4096
18#error PAGE_SIZE must be at least 4096
19#endif
20
21static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
22static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
23static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
24static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext); 18static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
25static int affs_file_open(struct inode *inode, struct file *filp);
26static int affs_file_release(struct inode *inode, struct file *filp);
27
28const struct file_operations affs_file_operations = {
29 .llseek = generic_file_llseek,
30 .read = new_sync_read,
31 .read_iter = generic_file_read_iter,
32 .write = new_sync_write,
33 .write_iter = generic_file_write_iter,
34 .mmap = generic_file_mmap,
35 .open = affs_file_open,
36 .release = affs_file_release,
37 .fsync = affs_file_fsync,
38 .splice_read = generic_file_splice_read,
39};
40
41const struct inode_operations affs_file_inode_operations = {
42 .setattr = affs_notify_change,
43};
44 19
45static int 20static int
46affs_file_open(struct inode *inode, struct file *filp) 21affs_file_open(struct inode *inode, struct file *filp)
@@ -355,7 +330,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
355 330
356 /* store new block */ 331 /* store new block */
357 if (bh_result->b_blocknr) 332 if (bh_result->b_blocknr)
358 affs_warning(sb, "get_block", "block already set (%x)", bh_result->b_blocknr); 333 affs_warning(sb, "get_block", "block already set (%lx)",
334 (unsigned long)bh_result->b_blocknr);
359 AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr); 335 AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr);
360 AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1); 336 AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1);
361 affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1); 337 affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1);
@@ -377,7 +353,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
377 return 0; 353 return 0;
378 354
379err_big: 355err_big:
380 affs_error(inode->i_sb,"get_block","strange block request %d", block); 356 affs_error(inode->i_sb, "get_block", "strange block request %d",
357 (int)block);
381 return -EIO; 358 return -EIO;
382err_ext: 359err_ext:
383 // unlock cache 360 // unlock cache
@@ -412,6 +389,22 @@ static void affs_write_failed(struct address_space *mapping, loff_t to)
412 } 389 }
413} 390}
414 391
392static ssize_t
393affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
394 loff_t offset)
395{
396 struct file *file = iocb->ki_filp;
397 struct address_space *mapping = file->f_mapping;
398 struct inode *inode = mapping->host;
399 size_t count = iov_iter_count(iter);
400 ssize_t ret;
401
402 ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, affs_get_block);
403 if (ret < 0 && (rw & WRITE))
404 affs_write_failed(mapping, offset + count);
405 return ret;
406}
407
415static int affs_write_begin(struct file *file, struct address_space *mapping, 408static int affs_write_begin(struct file *file, struct address_space *mapping,
416 loff_t pos, unsigned len, unsigned flags, 409 loff_t pos, unsigned len, unsigned flags,
417 struct page **pagep, void **fsdata) 410 struct page **pagep, void **fsdata)
@@ -438,6 +431,7 @@ const struct address_space_operations affs_aops = {
438 .writepage = affs_writepage, 431 .writepage = affs_writepage,
439 .write_begin = affs_write_begin, 432 .write_begin = affs_write_begin,
440 .write_end = generic_write_end, 433 .write_end = generic_write_end,
434 .direct_IO = affs_direct_IO,
441 .bmap = _affs_bmap 435 .bmap = _affs_bmap
442}; 436};
443 437
@@ -867,8 +861,9 @@ affs_truncate(struct inode *inode)
867 // lock cache 861 // lock cache
868 ext_bh = affs_get_extblock(inode, ext); 862 ext_bh = affs_get_extblock(inode, ext);
869 if (IS_ERR(ext_bh)) { 863 if (IS_ERR(ext_bh)) {
870 affs_warning(sb, "truncate", "unexpected read error for ext block %u (%d)", 864 affs_warning(sb, "truncate",
871 ext, PTR_ERR(ext_bh)); 865 "unexpected read error for ext block %u (%ld)",
866 (unsigned int)ext, PTR_ERR(ext_bh));
872 return; 867 return;
873 } 868 }
874 if (AFFS_I(inode)->i_lc) { 869 if (AFFS_I(inode)->i_lc) {
@@ -914,8 +909,9 @@ affs_truncate(struct inode *inode)
914 struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0); 909 struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0);
915 u32 tmp; 910 u32 tmp;
916 if (IS_ERR(bh)) { 911 if (IS_ERR(bh)) {
917 affs_warning(sb, "truncate", "unexpected read error for last block %u (%d)", 912 affs_warning(sb, "truncate",
918 ext, PTR_ERR(bh)); 913 "unexpected read error for last block %u (%ld)",
914 (unsigned int)ext, PTR_ERR(bh));
919 return; 915 return;
920 } 916 }
921 tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next); 917 tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next);
@@ -961,3 +957,19 @@ int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
961 mutex_unlock(&inode->i_mutex); 957 mutex_unlock(&inode->i_mutex);
962 return ret; 958 return ret;
963} 959}
960const struct file_operations affs_file_operations = {
961 .llseek = generic_file_llseek,
962 .read = new_sync_read,
963 .read_iter = generic_file_read_iter,
964 .write = new_sync_write,
965 .write_iter = generic_file_write_iter,
966 .mmap = generic_file_mmap,
967 .open = affs_file_open,
968 .release = affs_file_release,
969 .fsync = affs_file_fsync,
970 .splice_read = generic_file_splice_read,
971};
972
973const struct inode_operations affs_file_inode_operations = {
974 .setattr = affs_notify_change,
975};
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index b94d1cc9cd30..edf47774b03d 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -269,10 +269,6 @@ more:
269 } 269 }
270 ctx->pos++; 270 ctx->pos++;
271 goto more; 271 goto more;
272
273 befs_debug(sb, "<--- %s pos %lld", __func__, ctx->pos);
274
275 return 0;
276} 272}
277 273
278static struct inode * 274static struct inode *
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index f37b08cea1f7..490538536cb4 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -42,6 +42,10 @@ static int load_em86(struct linux_binprm *bprm)
42 return -ENOEXEC; 42 return -ENOEXEC;
43 } 43 }
44 44
45 /* Need to be able to load the file after exec */
46 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
47 return -ENOENT;
48
45 allow_write_access(bprm->file); 49 allow_write_access(bprm->file);
46 fput(bprm->file); 50 fput(bprm->file);
47 bprm->file = NULL; 51 bprm->file = NULL;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 70789e198dea..c04ef1d4f18a 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -144,6 +144,10 @@ static int load_misc_binary(struct linux_binprm *bprm)
144 if (!fmt) 144 if (!fmt)
145 goto ret; 145 goto ret;
146 146
147 /* Need to be able to load the file after exec */
148 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
149 return -ENOENT;
150
147 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { 151 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
148 retval = remove_arg_zero(bprm); 152 retval = remove_arg_zero(bprm);
149 if (retval) 153 if (retval)
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 5027a3e14922..afdf4e3cafc2 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -24,6 +24,16 @@ static int load_script(struct linux_binprm *bprm)
24 24
25 if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) 25 if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
26 return -ENOEXEC; 26 return -ENOEXEC;
27
28 /*
29 * If the script filename will be inaccessible after exec, typically
30 * because it is a "/dev/fd/<fd>/.." path against an O_CLOEXEC fd, give
31 * up now (on the assumption that the interpreter will want to load
32 * this file).
33 */
34 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
35 return -ENOENT;
36
27 /* 37 /*
28 * This section does the #! interpretation. 38 * This section does the #! interpretation.
29 * Sorta complicated, but hopefully it will work. -TYT 39 * Sorta complicated, but hopefully it will work. -TYT
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index 1de7294aad20..2bc2c87f35e7 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -40,13 +40,14 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
40static void drop_slab(void) 40static void drop_slab(void)
41{ 41{
42 int nr_objects; 42 int nr_objects;
43 struct shrink_control shrink = {
44 .gfp_mask = GFP_KERNEL,
45 };
46 43
47 nodes_setall(shrink.nodes_to_scan);
48 do { 44 do {
49 nr_objects = shrink_slab(&shrink, 1000, 1000); 45 int nid;
46
47 nr_objects = 0;
48 for_each_online_node(nid)
49 nr_objects += shrink_node_slabs(GFP_KERNEL, nid,
50 1000, 1000);
50 } while (nr_objects > 10); 51 } while (nr_objects > 10);
51} 52}
52 53
diff --git a/fs/exec.c b/fs/exec.c
index 01aebe300200..ad8798e26be9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -748,18 +748,25 @@ EXPORT_SYMBOL(setup_arg_pages);
748 748
749#endif /* CONFIG_MMU */ 749#endif /* CONFIG_MMU */
750 750
751static struct file *do_open_exec(struct filename *name) 751static struct file *do_open_execat(int fd, struct filename *name, int flags)
752{ 752{
753 struct file *file; 753 struct file *file;
754 int err; 754 int err;
755 static const struct open_flags open_exec_flags = { 755 struct open_flags open_exec_flags = {
756 .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 756 .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
757 .acc_mode = MAY_EXEC | MAY_OPEN, 757 .acc_mode = MAY_EXEC | MAY_OPEN,
758 .intent = LOOKUP_OPEN, 758 .intent = LOOKUP_OPEN,
759 .lookup_flags = LOOKUP_FOLLOW, 759 .lookup_flags = LOOKUP_FOLLOW,
760 }; 760 };
761 761
762 file = do_filp_open(AT_FDCWD, name, &open_exec_flags); 762 if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
763 return ERR_PTR(-EINVAL);
764 if (flags & AT_SYMLINK_NOFOLLOW)
765 open_exec_flags.lookup_flags &= ~LOOKUP_FOLLOW;
766 if (flags & AT_EMPTY_PATH)
767 open_exec_flags.lookup_flags |= LOOKUP_EMPTY;
768
769 file = do_filp_open(fd, name, &open_exec_flags);
763 if (IS_ERR(file)) 770 if (IS_ERR(file))
764 goto out; 771 goto out;
765 772
@@ -770,12 +777,13 @@ static struct file *do_open_exec(struct filename *name)
770 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) 777 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
771 goto exit; 778 goto exit;
772 779
773 fsnotify_open(file);
774
775 err = deny_write_access(file); 780 err = deny_write_access(file);
776 if (err) 781 if (err)
777 goto exit; 782 goto exit;
778 783
784 if (name->name[0] != '\0')
785 fsnotify_open(file);
786
779out: 787out:
780 return file; 788 return file;
781 789
@@ -787,7 +795,7 @@ exit:
787struct file *open_exec(const char *name) 795struct file *open_exec(const char *name)
788{ 796{
789 struct filename tmp = { .name = name }; 797 struct filename tmp = { .name = name };
790 return do_open_exec(&tmp); 798 return do_open_execat(AT_FDCWD, &tmp, 0);
791} 799}
792EXPORT_SYMBOL(open_exec); 800EXPORT_SYMBOL(open_exec);
793 801
@@ -1428,10 +1436,12 @@ static int exec_binprm(struct linux_binprm *bprm)
1428/* 1436/*
1429 * sys_execve() executes a new program. 1437 * sys_execve() executes a new program.
1430 */ 1438 */
1431static int do_execve_common(struct filename *filename, 1439static int do_execveat_common(int fd, struct filename *filename,
1432 struct user_arg_ptr argv, 1440 struct user_arg_ptr argv,
1433 struct user_arg_ptr envp) 1441 struct user_arg_ptr envp,
1442 int flags)
1434{ 1443{
1444 char *pathbuf = NULL;
1435 struct linux_binprm *bprm; 1445 struct linux_binprm *bprm;
1436 struct file *file; 1446 struct file *file;
1437 struct files_struct *displaced; 1447 struct files_struct *displaced;
@@ -1472,7 +1482,7 @@ static int do_execve_common(struct filename *filename,
1472 check_unsafe_exec(bprm); 1482 check_unsafe_exec(bprm);
1473 current->in_execve = 1; 1483 current->in_execve = 1;
1474 1484
1475 file = do_open_exec(filename); 1485 file = do_open_execat(fd, filename, flags);
1476 retval = PTR_ERR(file); 1486 retval = PTR_ERR(file);
1477 if (IS_ERR(file)) 1487 if (IS_ERR(file))
1478 goto out_unmark; 1488 goto out_unmark;
@@ -1480,7 +1490,28 @@ static int do_execve_common(struct filename *filename,
1480 sched_exec(); 1490 sched_exec();
1481 1491
1482 bprm->file = file; 1492 bprm->file = file;
1483 bprm->filename = bprm->interp = filename->name; 1493 if (fd == AT_FDCWD || filename->name[0] == '/') {
1494 bprm->filename = filename->name;
1495 } else {
1496 if (filename->name[0] == '\0')
1497 pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d", fd);
1498 else
1499 pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d/%s",
1500 fd, filename->name);
1501 if (!pathbuf) {
1502 retval = -ENOMEM;
1503 goto out_unmark;
1504 }
1505 /*
1506 * Record that a name derived from an O_CLOEXEC fd will be
1507 * inaccessible after exec. Relies on having exclusive access to
1508 * current->files (due to unshare_files above).
1509 */
1510 if (close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
1511 bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
1512 bprm->filename = pathbuf;
1513 }
1514 bprm->interp = bprm->filename;
1484 1515
1485 retval = bprm_mm_init(bprm); 1516 retval = bprm_mm_init(bprm);
1486 if (retval) 1517 if (retval)
@@ -1521,6 +1552,7 @@ static int do_execve_common(struct filename *filename,
1521 acct_update_integrals(current); 1552 acct_update_integrals(current);
1522 task_numa_free(current); 1553 task_numa_free(current);
1523 free_bprm(bprm); 1554 free_bprm(bprm);
1555 kfree(pathbuf);
1524 putname(filename); 1556 putname(filename);
1525 if (displaced) 1557 if (displaced)
1526 put_files_struct(displaced); 1558 put_files_struct(displaced);
@@ -1538,6 +1570,7 @@ out_unmark:
1538 1570
1539out_free: 1571out_free:
1540 free_bprm(bprm); 1572 free_bprm(bprm);
1573 kfree(pathbuf);
1541 1574
1542out_files: 1575out_files:
1543 if (displaced) 1576 if (displaced)
@@ -1553,7 +1586,18 @@ int do_execve(struct filename *filename,
1553{ 1586{
1554 struct user_arg_ptr argv = { .ptr.native = __argv }; 1587 struct user_arg_ptr argv = { .ptr.native = __argv };
1555 struct user_arg_ptr envp = { .ptr.native = __envp }; 1588 struct user_arg_ptr envp = { .ptr.native = __envp };
1556 return do_execve_common(filename, argv, envp); 1589 return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
1590}
1591
1592int do_execveat(int fd, struct filename *filename,
1593 const char __user *const __user *__argv,
1594 const char __user *const __user *__envp,
1595 int flags)
1596{
1597 struct user_arg_ptr argv = { .ptr.native = __argv };
1598 struct user_arg_ptr envp = { .ptr.native = __envp };
1599
1600 return do_execveat_common(fd, filename, argv, envp, flags);
1557} 1601}
1558 1602
1559#ifdef CONFIG_COMPAT 1603#ifdef CONFIG_COMPAT
@@ -1569,7 +1613,23 @@ static int compat_do_execve(struct filename *filename,
1569 .is_compat = true, 1613 .is_compat = true,
1570 .ptr.compat = __envp, 1614 .ptr.compat = __envp,
1571 }; 1615 };
1572 return do_execve_common(filename, argv, envp); 1616 return do_execveat_common(AT_FDCWD, filename, argv, envp, 0);
1617}
1618
1619static int compat_do_execveat(int fd, struct filename *filename,
1620 const compat_uptr_t __user *__argv,
1621 const compat_uptr_t __user *__envp,
1622 int flags)
1623{
1624 struct user_arg_ptr argv = {
1625 .is_compat = true,
1626 .ptr.compat = __argv,
1627 };
1628 struct user_arg_ptr envp = {
1629 .is_compat = true,
1630 .ptr.compat = __envp,
1631 };
1632 return do_execveat_common(fd, filename, argv, envp, flags);
1573} 1633}
1574#endif 1634#endif
1575 1635
@@ -1609,6 +1669,20 @@ SYSCALL_DEFINE3(execve,
1609{ 1669{
1610 return do_execve(getname(filename), argv, envp); 1670 return do_execve(getname(filename), argv, envp);
1611} 1671}
1672
1673SYSCALL_DEFINE5(execveat,
1674 int, fd, const char __user *, filename,
1675 const char __user *const __user *, argv,
1676 const char __user *const __user *, envp,
1677 int, flags)
1678{
1679 int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
1680
1681 return do_execveat(fd,
1682 getname_flags(filename, lookup_flags, NULL),
1683 argv, envp, flags);
1684}
1685
1612#ifdef CONFIG_COMPAT 1686#ifdef CONFIG_COMPAT
1613COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename, 1687COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,
1614 const compat_uptr_t __user *, argv, 1688 const compat_uptr_t __user *, argv,
@@ -1616,4 +1690,17 @@ COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,
1616{ 1690{
1617 return compat_do_execve(getname(filename), argv, envp); 1691 return compat_do_execve(getname(filename), argv, envp);
1618} 1692}
1693
1694COMPAT_SYSCALL_DEFINE5(execveat, int, fd,
1695 const char __user *, filename,
1696 const compat_uptr_t __user *, argv,
1697 const compat_uptr_t __user *, envp,
1698 int, flags)
1699{
1700 int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
1701
1702 return compat_do_execveat(fd,
1703 getname_flags(filename, lookup_flags, NULL),
1704 argv, envp, flags);
1705}
1619#endif 1706#endif
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index e0c4ba39a377..64e295e8ff38 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -370,6 +370,7 @@ extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
370 int datasync); 370 int datasync);
371 371
372/* fat/inode.c */ 372/* fat/inode.c */
373extern int fat_block_truncate_page(struct inode *inode, loff_t from);
373extern void fat_attach(struct inode *inode, loff_t i_pos); 374extern void fat_attach(struct inode *inode, loff_t i_pos);
374extern void fat_detach(struct inode *inode); 375extern void fat_detach(struct inode *inode);
375extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos); 376extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 85f79a89e747..8429c68e3057 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -443,6 +443,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
443 } 443 }
444 444
445 if (attr->ia_valid & ATTR_SIZE) { 445 if (attr->ia_valid & ATTR_SIZE) {
446 error = fat_block_truncate_page(inode, attr->ia_size);
447 if (error)
448 goto out;
446 down_write(&MSDOS_I(inode)->truncate_lock); 449 down_write(&MSDOS_I(inode)->truncate_lock);
447 truncate_setsize(inode, attr->ia_size); 450 truncate_setsize(inode, attr->ia_size);
448 fat_truncate_blocks(inode, attr->ia_size); 451 fat_truncate_blocks(inode, attr->ia_size);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 756aead10d96..7b41a2dcdd76 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -294,6 +294,18 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
294 return blocknr; 294 return blocknr;
295} 295}
296 296
297/*
298 * fat_block_truncate_page() zeroes out a mapping from file offset `from'
299 * up to the end of the block which corresponds to `from'.
300 * This is required during truncate to physically zeroout the tail end
301 * of that block so it doesn't yield old data if the file is later grown.
302 * Also, avoid causing failure from fsx for cases of "data past EOF"
303 */
304int fat_block_truncate_page(struct inode *inode, loff_t from)
305{
306 return block_truncate_page(inode->i_mapping, from, fat_get_block);
307}
308
297static const struct address_space_operations fat_aops = { 309static const struct address_space_operations fat_aops = {
298 .readpage = fat_readpage, 310 .readpage = fat_readpage,
299 .readpages = fat_readpages, 311 .readpages = fat_readpages,
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 1e2872b25343..5eba47f593f8 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -412,10 +412,10 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
412 pgoff = offset >> PAGE_SHIFT; 412 pgoff = offset >> PAGE_SHIFT;
413 413
414 i_size_write(inode, offset); 414 i_size_write(inode, offset);
415 mutex_lock(&mapping->i_mmap_mutex); 415 i_mmap_lock_write(mapping);
416 if (!RB_EMPTY_ROOT(&mapping->i_mmap)) 416 if (!RB_EMPTY_ROOT(&mapping->i_mmap))
417 hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); 417 hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
418 mutex_unlock(&mapping->i_mmap_mutex); 418 i_mmap_unlock_write(mapping);
419 truncate_hugepages(inode, offset); 419 truncate_hugepages(inode, offset);
420 return 0; 420 return 0;
421} 421}
@@ -472,12 +472,12 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb,
472} 472}
473 473
474/* 474/*
475 * Hugetlbfs is not reclaimable; therefore its i_mmap_mutex will never 475 * Hugetlbfs is not reclaimable; therefore its i_mmap_rwsem will never
476 * be taken from reclaim -- unlike regular filesystems. This needs an 476 * be taken from reclaim -- unlike regular filesystems. This needs an
477 * annotation because huge_pmd_share() does an allocation under 477 * annotation because huge_pmd_share() does an allocation under
478 * i_mmap_mutex. 478 * i_mmap_rwsem.
479 */ 479 */
480static struct lock_class_key hugetlbfs_i_mmap_mutex_key; 480static struct lock_class_key hugetlbfs_i_mmap_rwsem_key;
481 481
482static struct inode *hugetlbfs_get_inode(struct super_block *sb, 482static struct inode *hugetlbfs_get_inode(struct super_block *sb,
483 struct inode *dir, 483 struct inode *dir,
@@ -495,8 +495,8 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb,
495 struct hugetlbfs_inode_info *info; 495 struct hugetlbfs_inode_info *info;
496 inode->i_ino = get_next_ino(); 496 inode->i_ino = get_next_ino();
497 inode_init_owner(inode, dir, mode); 497 inode_init_owner(inode, dir, mode);
498 lockdep_set_class(&inode->i_mapping->i_mmap_mutex, 498 lockdep_set_class(&inode->i_mapping->i_mmap_rwsem,
499 &hugetlbfs_i_mmap_mutex_key); 499 &hugetlbfs_i_mmap_rwsem_key);
500 inode->i_mapping->a_ops = &hugetlbfs_aops; 500 inode->i_mapping->a_ops = &hugetlbfs_aops;
501 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info; 501 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
502 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 502 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
diff --git a/fs/inode.c b/fs/inode.c
index 2ed95f7caa4f..ad60555b4768 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -346,7 +346,7 @@ void address_space_init_once(struct address_space *mapping)
346 memset(mapping, 0, sizeof(*mapping)); 346 memset(mapping, 0, sizeof(*mapping));
347 INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC); 347 INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
348 spin_lock_init(&mapping->tree_lock); 348 spin_lock_init(&mapping->tree_lock);
349 mutex_init(&mapping->i_mmap_mutex); 349 init_rwsem(&mapping->i_mmap_rwsem);
350 INIT_LIST_HEAD(&mapping->private_list); 350 INIT_LIST_HEAD(&mapping->private_list);
351 spin_lock_init(&mapping->private_lock); 351 spin_lock_init(&mapping->private_lock);
352 mapping->i_mmap = RB_ROOT; 352 mapping->i_mmap = RB_ROOT;
diff --git a/fs/namei.c b/fs/namei.c
index db5fe86319e6..ca814165d84c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -130,7 +130,7 @@ void final_putname(struct filename *name)
130 130
131#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(struct filename)) 131#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(struct filename))
132 132
133static struct filename * 133struct filename *
134getname_flags(const char __user *filename, int flags, int *empty) 134getname_flags(const char __user *filename, int flags, int *empty)
135{ 135{
136 struct filename *result, *err; 136 struct filename *result, *err;
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index caaaf9dfe353..44523f4a6084 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -69,8 +69,8 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
69 if (old_mask == new_mask) 69 if (old_mask == new_mask)
70 return; 70 return;
71 71
72 if (fsn_mark->i.inode) 72 if (fsn_mark->inode)
73 fsnotify_recalc_inode_mask(fsn_mark->i.inode); 73 fsnotify_recalc_inode_mask(fsn_mark->inode);
74} 74}
75 75
76/* 76/*
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index 6ffd220eb14d..58b7cdb63da9 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -80,7 +80,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
80 return; 80 return;
81 81
82 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); 82 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
83 inode = igrab(mark->i.inode); 83 inode = igrab(mark->inode);
84 if (inode) { 84 if (inode) {
85 seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ", 85 seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ",
86 inode_mark->wd, inode->i_ino, inode->i_sb->s_dev, 86 inode_mark->wd, inode->i_ino, inode->i_sb->s_dev,
@@ -112,7 +112,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
112 mflags |= FAN_MARK_IGNORED_SURV_MODIFY; 112 mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
113 113
114 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { 114 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
115 inode = igrab(mark->i.inode); 115 inode = igrab(mark->inode);
116 if (!inode) 116 if (!inode)
117 return; 117 return;
118 seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ", 118 seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
@@ -122,7 +122,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
122 seq_putc(m, '\n'); 122 seq_putc(m, '\n');
123 iput(inode); 123 iput(inode);
124 } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) { 124 } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) {
125 struct mount *mnt = real_mount(mark->m.mnt); 125 struct mount *mnt = real_mount(mark->mnt);
126 126
127 seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n", 127 seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
128 mnt->mnt_id, mflags, mark->mask, mark->ignored_mask); 128 mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 41e39102743a..dd3fb0b17be7 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -242,13 +242,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
242 242
243 if (inode_node) { 243 if (inode_node) {
244 inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), 244 inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu),
245 struct fsnotify_mark, i.i_list); 245 struct fsnotify_mark, obj_list);
246 inode_group = inode_mark->group; 246 inode_group = inode_mark->group;
247 } 247 }
248 248
249 if (vfsmount_node) { 249 if (vfsmount_node) {
250 vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), 250 vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu),
251 struct fsnotify_mark, m.m_list); 251 struct fsnotify_mark, obj_list);
252 vfsmount_group = vfsmount_mark->group; 252 vfsmount_group = vfsmount_mark->group;
253 } 253 }
254 254
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 3b68b0ae0a97..13a00be516d2 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -12,12 +12,19 @@ extern void fsnotify_flush_notify(struct fsnotify_group *group);
12/* protects reads of inode and vfsmount marks list */ 12/* protects reads of inode and vfsmount marks list */
13extern struct srcu_struct fsnotify_mark_srcu; 13extern struct srcu_struct fsnotify_mark_srcu;
14 14
15/* Calculate mask of events for a list of marks */
16extern u32 fsnotify_recalc_mask(struct hlist_head *head);
17
15/* compare two groups for sorting of marks lists */ 18/* compare two groups for sorting of marks lists */
16extern int fsnotify_compare_groups(struct fsnotify_group *a, 19extern int fsnotify_compare_groups(struct fsnotify_group *a,
17 struct fsnotify_group *b); 20 struct fsnotify_group *b);
18 21
19extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark, 22extern void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *fsn_mark,
20 __u32 mask); 23 __u32 mask);
24/* Add mark to a proper place in mark list */
25extern int fsnotify_add_mark_list(struct hlist_head *head,
26 struct fsnotify_mark *mark,
27 int allow_dups);
21/* add a mark to an inode */ 28/* add a mark to an inode */
22extern int fsnotify_add_inode_mark(struct fsnotify_mark *mark, 29extern int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
23 struct fsnotify_group *group, struct inode *inode, 30 struct fsnotify_group *group, struct inode *inode,
@@ -31,6 +38,11 @@ extern int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
31extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark); 38extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark);
32/* inode specific destruction of a mark */ 39/* inode specific destruction of a mark */
33extern void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark); 40extern void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark);
41/* Destroy all marks in the given list */
42extern void fsnotify_destroy_marks(struct list_head *to_free);
43/* Find mark belonging to given group in the list of marks */
44extern struct fsnotify_mark *fsnotify_find_mark(struct hlist_head *head,
45 struct fsnotify_group *group);
34/* run the list of all marks associated with inode and flag them to be freed */ 46/* run the list of all marks associated with inode and flag them to be freed */
35extern void fsnotify_clear_marks_by_inode(struct inode *inode); 47extern void fsnotify_clear_marks_by_inode(struct inode *inode);
36/* run the list of all marks associated with vfsmount and flag them to be freed */ 48/* run the list of all marks associated with vfsmount and flag them to be freed */
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index dfbf5447eea4..3daf513ee99e 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -31,28 +31,13 @@
31#include "../internal.h" 31#include "../internal.h"
32 32
33/* 33/*
34 * Recalculate the mask of events relevant to a given inode locked.
35 */
36static void fsnotify_recalc_inode_mask_locked(struct inode *inode)
37{
38 struct fsnotify_mark *mark;
39 __u32 new_mask = 0;
40
41 assert_spin_locked(&inode->i_lock);
42
43 hlist_for_each_entry(mark, &inode->i_fsnotify_marks, i.i_list)
44 new_mask |= mark->mask;
45 inode->i_fsnotify_mask = new_mask;
46}
47
48/*
49 * Recalculate the inode->i_fsnotify_mask, or the mask of all FS_* event types 34 * Recalculate the inode->i_fsnotify_mask, or the mask of all FS_* event types
50 * any notifier is interested in hearing for this inode. 35 * any notifier is interested in hearing for this inode.
51 */ 36 */
52void fsnotify_recalc_inode_mask(struct inode *inode) 37void fsnotify_recalc_inode_mask(struct inode *inode)
53{ 38{
54 spin_lock(&inode->i_lock); 39 spin_lock(&inode->i_lock);
55 fsnotify_recalc_inode_mask_locked(inode); 40 inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks);
56 spin_unlock(&inode->i_lock); 41 spin_unlock(&inode->i_lock);
57 42
58 __fsnotify_update_child_dentry_flags(inode); 43 __fsnotify_update_child_dentry_flags(inode);
@@ -60,23 +45,22 @@ void fsnotify_recalc_inode_mask(struct inode *inode)
60 45
61void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) 46void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark)
62{ 47{
63 struct inode *inode = mark->i.inode; 48 struct inode *inode = mark->inode;
64 49
65 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); 50 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
66 assert_spin_locked(&mark->lock); 51 assert_spin_locked(&mark->lock);
67 52
68 spin_lock(&inode->i_lock); 53 spin_lock(&inode->i_lock);
69 54
70 hlist_del_init_rcu(&mark->i.i_list); 55 hlist_del_init_rcu(&mark->obj_list);
71 mark->i.inode = NULL; 56 mark->inode = NULL;
72 57
73 /* 58 /*
74 * this mark is now off the inode->i_fsnotify_marks list and we 59 * this mark is now off the inode->i_fsnotify_marks list and we
75 * hold the inode->i_lock, so this is the perfect time to update the 60 * hold the inode->i_lock, so this is the perfect time to update the
76 * inode->i_fsnotify_mask 61 * inode->i_fsnotify_mask
77 */ 62 */
78 fsnotify_recalc_inode_mask_locked(inode); 63 inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks);
79
80 spin_unlock(&inode->i_lock); 64 spin_unlock(&inode->i_lock);
81} 65}
82 66
@@ -85,30 +69,19 @@ void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark)
85 */ 69 */
86void fsnotify_clear_marks_by_inode(struct inode *inode) 70void fsnotify_clear_marks_by_inode(struct inode *inode)
87{ 71{
88 struct fsnotify_mark *mark, *lmark; 72 struct fsnotify_mark *mark;
89 struct hlist_node *n; 73 struct hlist_node *n;
90 LIST_HEAD(free_list); 74 LIST_HEAD(free_list);
91 75
92 spin_lock(&inode->i_lock); 76 spin_lock(&inode->i_lock);
93 hlist_for_each_entry_safe(mark, n, &inode->i_fsnotify_marks, i.i_list) { 77 hlist_for_each_entry_safe(mark, n, &inode->i_fsnotify_marks, obj_list) {
94 list_add(&mark->i.free_i_list, &free_list); 78 list_add(&mark->free_list, &free_list);
95 hlist_del_init_rcu(&mark->i.i_list); 79 hlist_del_init_rcu(&mark->obj_list);
96 fsnotify_get_mark(mark); 80 fsnotify_get_mark(mark);
97 } 81 }
98 spin_unlock(&inode->i_lock); 82 spin_unlock(&inode->i_lock);
99 83
100 list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) { 84 fsnotify_destroy_marks(&free_list);
101 struct fsnotify_group *group;
102
103 spin_lock(&mark->lock);
104 fsnotify_get_group(mark->group);
105 group = mark->group;
106 spin_unlock(&mark->lock);
107
108 fsnotify_destroy_mark(mark, group);
109 fsnotify_put_mark(mark);
110 fsnotify_put_group(group);
111 }
112} 85}
113 86
114/* 87/*
@@ -123,34 +96,13 @@ void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
123 * given a group and inode, find the mark associated with that combination. 96 * given a group and inode, find the mark associated with that combination.
124 * if found take a reference to that mark and return it, else return NULL 97 * if found take a reference to that mark and return it, else return NULL
125 */ 98 */
126static struct fsnotify_mark *fsnotify_find_inode_mark_locked(
127 struct fsnotify_group *group,
128 struct inode *inode)
129{
130 struct fsnotify_mark *mark;
131
132 assert_spin_locked(&inode->i_lock);
133
134 hlist_for_each_entry(mark, &inode->i_fsnotify_marks, i.i_list) {
135 if (mark->group == group) {
136 fsnotify_get_mark(mark);
137 return mark;
138 }
139 }
140 return NULL;
141}
142
143/*
144 * given a group and inode, find the mark associated with that combination.
145 * if found take a reference to that mark and return it, else return NULL
146 */
147struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, 99struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group,
148 struct inode *inode) 100 struct inode *inode)
149{ 101{
150 struct fsnotify_mark *mark; 102 struct fsnotify_mark *mark;
151 103
152 spin_lock(&inode->i_lock); 104 spin_lock(&inode->i_lock);
153 mark = fsnotify_find_inode_mark_locked(group, inode); 105 mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
154 spin_unlock(&inode->i_lock); 106 spin_unlock(&inode->i_lock);
155 107
156 return mark; 108 return mark;
@@ -168,10 +120,10 @@ void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *mark,
168 assert_spin_locked(&mark->lock); 120 assert_spin_locked(&mark->lock);
169 121
170 if (mask && 122 if (mask &&
171 mark->i.inode && 123 mark->inode &&
172 !(mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) { 124 !(mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) {
173 mark->flags |= FSNOTIFY_MARK_FLAG_OBJECT_PINNED; 125 mark->flags |= FSNOTIFY_MARK_FLAG_OBJECT_PINNED;
174 inode = igrab(mark->i.inode); 126 inode = igrab(mark->inode);
175 /* 127 /*
176 * we shouldn't be able to get here if the inode wasn't 128 * we shouldn't be able to get here if the inode wasn't
177 * already safely held in memory. But bug in case it 129 * already safely held in memory. But bug in case it
@@ -192,9 +144,7 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
192 struct fsnotify_group *group, struct inode *inode, 144 struct fsnotify_group *group, struct inode *inode,
193 int allow_dups) 145 int allow_dups)
194{ 146{
195 struct fsnotify_mark *lmark, *last = NULL; 147 int ret;
196 int ret = 0;
197 int cmp;
198 148
199 mark->flags |= FSNOTIFY_MARK_FLAG_INODE; 149 mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
200 150
@@ -202,37 +152,10 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
202 assert_spin_locked(&mark->lock); 152 assert_spin_locked(&mark->lock);
203 153
204 spin_lock(&inode->i_lock); 154 spin_lock(&inode->i_lock);
205 155 mark->inode = inode;
206 mark->i.inode = inode; 156 ret = fsnotify_add_mark_list(&inode->i_fsnotify_marks, mark,
207 157 allow_dups);
208 /* is mark the first mark? */ 158 inode->i_fsnotify_mask = fsnotify_recalc_mask(&inode->i_fsnotify_marks);
209 if (hlist_empty(&inode->i_fsnotify_marks)) {
210 hlist_add_head_rcu(&mark->i.i_list, &inode->i_fsnotify_marks);
211 goto out;
212 }
213
214 /* should mark be in the middle of the current list? */
215 hlist_for_each_entry(lmark, &inode->i_fsnotify_marks, i.i_list) {
216 last = lmark;
217
218 if ((lmark->group == group) && !allow_dups) {
219 ret = -EEXIST;
220 goto out;
221 }
222
223 cmp = fsnotify_compare_groups(lmark->group, mark->group);
224 if (cmp < 0)
225 continue;
226
227 hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
228 goto out;
229 }
230
231 BUG_ON(last == NULL);
232 /* mark should be the last entry. last is the current last entry */
233 hlist_add_behind_rcu(&mark->i.i_list, &last->i.i_list);
234out:
235 fsnotify_recalc_inode_mask_locked(inode);
236 spin_unlock(&inode->i_lock); 159 spin_unlock(&inode->i_lock);
237 160
238 return ret; 161 return ret;
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 7d888d77d59a..2cd900c2c737 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -156,7 +156,7 @@ static int idr_callback(int id, void *p, void *data)
156 */ 156 */
157 if (fsn_mark) 157 if (fsn_mark)
158 printk(KERN_WARNING "fsn_mark->group=%p inode=%p wd=%d\n", 158 printk(KERN_WARNING "fsn_mark->group=%p inode=%p wd=%d\n",
159 fsn_mark->group, fsn_mark->i.inode, i_mark->wd); 159 fsn_mark->group, fsn_mark->inode, i_mark->wd);
160 return 0; 160 return 0;
161} 161}
162 162
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 283aa312d745..450648697433 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -433,7 +433,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group,
433 if (wd == -1) { 433 if (wd == -1) {
434 WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" 434 WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p"
435 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, 435 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd,
436 i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); 436 i_mark->fsn_mark.group, i_mark->fsn_mark.inode);
437 goto out; 437 goto out;
438 } 438 }
439 439
@@ -442,7 +442,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group,
442 if (unlikely(!found_i_mark)) { 442 if (unlikely(!found_i_mark)) {
443 WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" 443 WARN_ONCE(1, "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p"
444 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, 444 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd,
445 i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); 445 i_mark->fsn_mark.group, i_mark->fsn_mark.inode);
446 goto out; 446 goto out;
447 } 447 }
448 448
@@ -456,9 +456,9 @@ static void inotify_remove_from_idr(struct fsnotify_group *group,
456 "mark->inode=%p found_i_mark=%p found_i_mark->wd=%d " 456 "mark->inode=%p found_i_mark=%p found_i_mark->wd=%d "
457 "found_i_mark->group=%p found_i_mark->inode=%p\n", 457 "found_i_mark->group=%p found_i_mark->inode=%p\n",
458 __func__, i_mark, i_mark->wd, i_mark->fsn_mark.group, 458 __func__, i_mark, i_mark->wd, i_mark->fsn_mark.group,
459 i_mark->fsn_mark.i.inode, found_i_mark, found_i_mark->wd, 459 i_mark->fsn_mark.inode, found_i_mark, found_i_mark->wd,
460 found_i_mark->fsn_mark.group, 460 found_i_mark->fsn_mark.group,
461 found_i_mark->fsn_mark.i.inode); 461 found_i_mark->fsn_mark.inode);
462 goto out; 462 goto out;
463 } 463 }
464 464
@@ -470,7 +470,7 @@ static void inotify_remove_from_idr(struct fsnotify_group *group,
470 if (unlikely(atomic_read(&i_mark->fsn_mark.refcnt) < 3)) { 470 if (unlikely(atomic_read(&i_mark->fsn_mark.refcnt) < 3)) {
471 printk(KERN_ERR "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p" 471 printk(KERN_ERR "%s: i_mark=%p i_mark->wd=%d i_mark->group=%p"
472 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd, 472 " i_mark->inode=%p\n", __func__, i_mark, i_mark->wd,
473 i_mark->fsn_mark.group, i_mark->fsn_mark.i.inode); 473 i_mark->fsn_mark.group, i_mark->fsn_mark.inode);
474 /* we can't really recover with bad ref cnting.. */ 474 /* we can't really recover with bad ref cnting.. */
475 BUG(); 475 BUG();
476 } 476 }
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 34c38fabf514..92e48c70f0f0 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -110,6 +110,17 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
110 } 110 }
111} 111}
112 112
113/* Calculate mask of events for a list of marks */
114u32 fsnotify_recalc_mask(struct hlist_head *head)
115{
116 u32 new_mask = 0;
117 struct fsnotify_mark *mark;
118
119 hlist_for_each_entry(mark, head, obj_list)
120 new_mask |= mark->mask;
121 return new_mask;
122}
123
113/* 124/*
114 * Any time a mark is getting freed we end up here. 125 * Any time a mark is getting freed we end up here.
115 * The caller had better be holding a reference to this mark so we don't actually 126 * The caller had better be holding a reference to this mark so we don't actually
@@ -133,7 +144,7 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
133 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; 144 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
134 145
135 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { 146 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
136 inode = mark->i.inode; 147 inode = mark->inode;
137 fsnotify_destroy_inode_mark(mark); 148 fsnotify_destroy_inode_mark(mark);
138 } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) 149 } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT)
139 fsnotify_destroy_vfsmount_mark(mark); 150 fsnotify_destroy_vfsmount_mark(mark);
@@ -150,7 +161,7 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
150 mutex_unlock(&group->mark_mutex); 161 mutex_unlock(&group->mark_mutex);
151 162
152 spin_lock(&destroy_lock); 163 spin_lock(&destroy_lock);
153 list_add(&mark->destroy_list, &destroy_list); 164 list_add(&mark->g_list, &destroy_list);
154 spin_unlock(&destroy_lock); 165 spin_unlock(&destroy_lock);
155 wake_up(&destroy_waitq); 166 wake_up(&destroy_waitq);
156 /* 167 /*
@@ -192,6 +203,27 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
192 mutex_unlock(&group->mark_mutex); 203 mutex_unlock(&group->mark_mutex);
193} 204}
194 205
206/*
207 * Destroy all marks in the given list. The marks must be already detached from
208 * the original inode / vfsmount.
209 */
210void fsnotify_destroy_marks(struct list_head *to_free)
211{
212 struct fsnotify_mark *mark, *lmark;
213 struct fsnotify_group *group;
214
215 list_for_each_entry_safe(mark, lmark, to_free, free_list) {
216 spin_lock(&mark->lock);
217 fsnotify_get_group(mark->group);
218 group = mark->group;
219 spin_unlock(&mark->lock);
220
221 fsnotify_destroy_mark(mark, group);
222 fsnotify_put_mark(mark);
223 fsnotify_put_group(group);
224 }
225}
226
195void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) 227void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
196{ 228{
197 assert_spin_locked(&mark->lock); 229 assert_spin_locked(&mark->lock);
@@ -245,6 +277,39 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
245 return -1; 277 return -1;
246} 278}
247 279
280/* Add mark into proper place in given list of marks */
281int fsnotify_add_mark_list(struct hlist_head *head, struct fsnotify_mark *mark,
282 int allow_dups)
283{
284 struct fsnotify_mark *lmark, *last = NULL;
285 int cmp;
286
287 /* is mark the first mark? */
288 if (hlist_empty(head)) {
289 hlist_add_head_rcu(&mark->obj_list, head);
290 return 0;
291 }
292
293 /* should mark be in the middle of the current list? */
294 hlist_for_each_entry(lmark, head, obj_list) {
295 last = lmark;
296
297 if ((lmark->group == mark->group) && !allow_dups)
298 return -EEXIST;
299
300 cmp = fsnotify_compare_groups(lmark->group, mark->group);
301 if (cmp >= 0) {
302 hlist_add_before_rcu(&mark->obj_list, &lmark->obj_list);
303 return 0;
304 }
305 }
306
307 BUG_ON(last == NULL);
308 /* mark should be the last entry. last is the current last entry */
309 hlist_add_behind_rcu(&mark->obj_list, &last->obj_list);
310 return 0;
311}
312
248/* 313/*
249 * Attach an initialized mark to a given group and fs object. 314 * Attach an initialized mark to a given group and fs object.
250 * These marks may be used for the fsnotify backend to determine which 315 * These marks may be used for the fsnotify backend to determine which
@@ -305,7 +370,7 @@ err:
305 spin_unlock(&mark->lock); 370 spin_unlock(&mark->lock);
306 371
307 spin_lock(&destroy_lock); 372 spin_lock(&destroy_lock);
308 list_add(&mark->destroy_list, &destroy_list); 373 list_add(&mark->g_list, &destroy_list);
309 spin_unlock(&destroy_lock); 374 spin_unlock(&destroy_lock);
310 wake_up(&destroy_waitq); 375 wake_up(&destroy_waitq);
311 376
@@ -323,6 +388,24 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
323} 388}
324 389
325/* 390/*
391 * Given a list of marks, find the mark associated with given group. If found
392 * take a reference to that mark and return it, else return NULL.
393 */
394struct fsnotify_mark *fsnotify_find_mark(struct hlist_head *head,
395 struct fsnotify_group *group)
396{
397 struct fsnotify_mark *mark;
398
399 hlist_for_each_entry(mark, head, obj_list) {
400 if (mark->group == group) {
401 fsnotify_get_mark(mark);
402 return mark;
403 }
404 }
405 return NULL;
406}
407
408/*
326 * clear any marks in a group in which mark->flags & flags is true 409 * clear any marks in a group in which mark->flags & flags is true
327 */ 410 */
328void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, 411void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group,
@@ -352,8 +435,8 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group)
352void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) 435void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old)
353{ 436{
354 assert_spin_locked(&old->lock); 437 assert_spin_locked(&old->lock);
355 new->i.inode = old->i.inode; 438 new->inode = old->inode;
356 new->m.mnt = old->m.mnt; 439 new->mnt = old->mnt;
357 if (old->group) 440 if (old->group)
358 fsnotify_get_group(old->group); 441 fsnotify_get_group(old->group);
359 new->group = old->group; 442 new->group = old->group;
@@ -386,8 +469,8 @@ static int fsnotify_mark_destroy(void *ignored)
386 469
387 synchronize_srcu(&fsnotify_mark_srcu); 470 synchronize_srcu(&fsnotify_mark_srcu);
388 471
389 list_for_each_entry_safe(mark, next, &private_destroy_list, destroy_list) { 472 list_for_each_entry_safe(mark, next, &private_destroy_list, g_list) {
390 list_del_init(&mark->destroy_list); 473 list_del_init(&mark->g_list);
391 fsnotify_put_mark(mark); 474 fsnotify_put_mark(mark);
392 } 475 }
393 476
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
index faefa72a11eb..326b148e623c 100644
--- a/fs/notify/vfsmount_mark.c
+++ b/fs/notify/vfsmount_mark.c
@@ -32,31 +32,20 @@
32 32
33void fsnotify_clear_marks_by_mount(struct vfsmount *mnt) 33void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
34{ 34{
35 struct fsnotify_mark *mark, *lmark; 35 struct fsnotify_mark *mark;
36 struct hlist_node *n; 36 struct hlist_node *n;
37 struct mount *m = real_mount(mnt); 37 struct mount *m = real_mount(mnt);
38 LIST_HEAD(free_list); 38 LIST_HEAD(free_list);
39 39
40 spin_lock(&mnt->mnt_root->d_lock); 40 spin_lock(&mnt->mnt_root->d_lock);
41 hlist_for_each_entry_safe(mark, n, &m->mnt_fsnotify_marks, m.m_list) { 41 hlist_for_each_entry_safe(mark, n, &m->mnt_fsnotify_marks, obj_list) {
42 list_add(&mark->m.free_m_list, &free_list); 42 list_add(&mark->free_list, &free_list);
43 hlist_del_init_rcu(&mark->m.m_list); 43 hlist_del_init_rcu(&mark->obj_list);
44 fsnotify_get_mark(mark); 44 fsnotify_get_mark(mark);
45 } 45 }
46 spin_unlock(&mnt->mnt_root->d_lock); 46 spin_unlock(&mnt->mnt_root->d_lock);
47 47
48 list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) { 48 fsnotify_destroy_marks(&free_list);
49 struct fsnotify_group *group;
50
51 spin_lock(&mark->lock);
52 fsnotify_get_group(mark->group);
53 group = mark->group;
54 spin_unlock(&mark->lock);
55
56 fsnotify_destroy_mark(mark, group);
57 fsnotify_put_mark(mark);
58 fsnotify_put_group(group);
59 }
60} 49}
61 50
62void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) 51void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
@@ -65,66 +54,35 @@ void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
65} 54}
66 55
67/* 56/*
68 * Recalculate the mask of events relevant to a given vfsmount locked.
69 */
70static void fsnotify_recalc_vfsmount_mask_locked(struct vfsmount *mnt)
71{
72 struct mount *m = real_mount(mnt);
73 struct fsnotify_mark *mark;
74 __u32 new_mask = 0;
75
76 assert_spin_locked(&mnt->mnt_root->d_lock);
77
78 hlist_for_each_entry(mark, &m->mnt_fsnotify_marks, m.m_list)
79 new_mask |= mark->mask;
80 m->mnt_fsnotify_mask = new_mask;
81}
82
83/*
84 * Recalculate the mnt->mnt_fsnotify_mask, or the mask of all FS_* event types 57 * Recalculate the mnt->mnt_fsnotify_mask, or the mask of all FS_* event types
85 * any notifier is interested in hearing for this mount point 58 * any notifier is interested in hearing for this mount point
86 */ 59 */
87void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt) 60void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt)
88{ 61{
62 struct mount *m = real_mount(mnt);
63
89 spin_lock(&mnt->mnt_root->d_lock); 64 spin_lock(&mnt->mnt_root->d_lock);
90 fsnotify_recalc_vfsmount_mask_locked(mnt); 65 m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks);
91 spin_unlock(&mnt->mnt_root->d_lock); 66 spin_unlock(&mnt->mnt_root->d_lock);
92} 67}
93 68
94void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) 69void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark)
95{ 70{
96 struct vfsmount *mnt = mark->m.mnt; 71 struct vfsmount *mnt = mark->mnt;
72 struct mount *m = real_mount(mnt);
97 73
98 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); 74 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
99 assert_spin_locked(&mark->lock); 75 assert_spin_locked(&mark->lock);
100 76
101 spin_lock(&mnt->mnt_root->d_lock); 77 spin_lock(&mnt->mnt_root->d_lock);
102 78
103 hlist_del_init_rcu(&mark->m.m_list); 79 hlist_del_init_rcu(&mark->obj_list);
104 mark->m.mnt = NULL; 80 mark->mnt = NULL;
105
106 fsnotify_recalc_vfsmount_mask_locked(mnt);
107 81
82 m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks);
108 spin_unlock(&mnt->mnt_root->d_lock); 83 spin_unlock(&mnt->mnt_root->d_lock);
109} 84}
110 85
111static struct fsnotify_mark *fsnotify_find_vfsmount_mark_locked(struct fsnotify_group *group,
112 struct vfsmount *mnt)
113{
114 struct mount *m = real_mount(mnt);
115 struct fsnotify_mark *mark;
116
117 assert_spin_locked(&mnt->mnt_root->d_lock);
118
119 hlist_for_each_entry(mark, &m->mnt_fsnotify_marks, m.m_list) {
120 if (mark->group == group) {
121 fsnotify_get_mark(mark);
122 return mark;
123 }
124 }
125 return NULL;
126}
127
128/* 86/*
129 * given a group and vfsmount, find the mark associated with that combination. 87 * given a group and vfsmount, find the mark associated with that combination.
130 * if found take a reference to that mark and return it, else return NULL 88 * if found take a reference to that mark and return it, else return NULL
@@ -132,10 +90,11 @@ static struct fsnotify_mark *fsnotify_find_vfsmount_mark_locked(struct fsnotify_
132struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, 90struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group,
133 struct vfsmount *mnt) 91 struct vfsmount *mnt)
134{ 92{
93 struct mount *m = real_mount(mnt);
135 struct fsnotify_mark *mark; 94 struct fsnotify_mark *mark;
136 95
137 spin_lock(&mnt->mnt_root->d_lock); 96 spin_lock(&mnt->mnt_root->d_lock);
138 mark = fsnotify_find_vfsmount_mark_locked(group, mnt); 97 mark = fsnotify_find_mark(&m->mnt_fsnotify_marks, group);
139 spin_unlock(&mnt->mnt_root->d_lock); 98 spin_unlock(&mnt->mnt_root->d_lock);
140 99
141 return mark; 100 return mark;
@@ -151,9 +110,7 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
151 int allow_dups) 110 int allow_dups)
152{ 111{
153 struct mount *m = real_mount(mnt); 112 struct mount *m = real_mount(mnt);
154 struct fsnotify_mark *lmark, *last = NULL; 113 int ret;
155 int ret = 0;
156 int cmp;
157 114
158 mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; 115 mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
159 116
@@ -161,37 +118,9 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
161 assert_spin_locked(&mark->lock); 118 assert_spin_locked(&mark->lock);
162 119
163 spin_lock(&mnt->mnt_root->d_lock); 120 spin_lock(&mnt->mnt_root->d_lock);
164 121 mark->mnt = mnt;
165 mark->m.mnt = mnt; 122 ret = fsnotify_add_mark_list(&m->mnt_fsnotify_marks, mark, allow_dups);
166 123 m->mnt_fsnotify_mask = fsnotify_recalc_mask(&m->mnt_fsnotify_marks);
167 /* is mark the first mark? */
168 if (hlist_empty(&m->mnt_fsnotify_marks)) {
169 hlist_add_head_rcu(&mark->m.m_list, &m->mnt_fsnotify_marks);
170 goto out;
171 }
172
173 /* should mark be in the middle of the current list? */
174 hlist_for_each_entry(lmark, &m->mnt_fsnotify_marks, m.m_list) {
175 last = lmark;
176
177 if ((lmark->group == group) && !allow_dups) {
178 ret = -EEXIST;
179 goto out;
180 }
181
182 cmp = fsnotify_compare_groups(lmark->group, mark->group);
183 if (cmp < 0)
184 continue;
185
186 hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
187 goto out;
188 }
189
190 BUG_ON(last == NULL);
191 /* mark should be the last entry. last is the current last entry */
192 hlist_add_behind_rcu(&mark->m.m_list, &last->m.m_list);
193out:
194 fsnotify_recalc_vfsmount_mask_locked(mnt);
195 spin_unlock(&mnt->mnt_root->d_lock); 124 spin_unlock(&mnt->mnt_root->d_lock);
196 125
197 return ret; 126 return ret;
diff --git a/fs/open.c b/fs/open.c
index b1bf3d542d5d..d45bd905d418 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -295,6 +295,17 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
295 295
296 sb_start_write(inode->i_sb); 296 sb_start_write(inode->i_sb);
297 ret = file->f_op->fallocate(file, mode, offset, len); 297 ret = file->f_op->fallocate(file, mode, offset, len);
298
299 /*
300 * Create inotify and fanotify events.
301 *
302 * To keep the logic simple always create events if fallocate succeeds.
303 * This implies that events are even created if the file size remains
304 * unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE.
305 */
306 if (ret == 0)
307 fsnotify_modify(file);
308
298 sb_end_write(inode->i_sb); 309 sb_end_write(inode->i_sb);
299 return ret; 310 return ret;
300} 311}
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 353948ba1c5b..dbf3a59c86bb 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -25,7 +25,11 @@ static void *seq_buf_alloc(unsigned long size)
25{ 25{
26 void *buf; 26 void *buf;
27 27
28 buf = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); 28 /*
29 * __GFP_NORETRY to avoid oom-killings with high-order allocations -
30 * it's better to fall back to vmalloc() than to kill things.
31 */
32 buf = kmalloc(size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
29 if (!buf && size > PAGE_SIZE) 33 if (!buf && size > PAGE_SIZE)
30 buf = vmalloc(size); 34 buf = vmalloc(size);
31 return buf; 35 return buf;