aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig11
-rw-r--r--fs/bio.c8
-rw-r--r--fs/dcache.c7
-rw-r--r--fs/hfs/bnode.c2
-rw-r--r--fs/hfs/extent.c3
-rw-r--r--fs/hfsplus/bnode.c2
-rw-r--r--fs/hfsplus/extents.c4
-rw-r--r--fs/inotify.c5
-rw-r--r--fs/isofs/compress.c6
-rw-r--r--fs/namei.c4
-rw-r--r--fs/namespace.c2
11 files changed, 37 insertions, 17 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 5d0c4be43dba..e54be7058359 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -363,12 +363,15 @@ config INOTIFY
363 bool "Inotify file change notification support" 363 bool "Inotify file change notification support"
364 default y 364 default y
365 ---help--- 365 ---help---
366 Say Y here to enable inotify support and the /dev/inotify character 366 Say Y here to enable inotify support and the associated system
367 device. Inotify is a file change notification system and a 367 calls. Inotify is a file change notification system and a
368 replacement for dnotify. Inotify fixes numerous shortcomings in 368 replacement for dnotify. Inotify fixes numerous shortcomings in
369 dnotify and introduces several new features. It allows monitoring 369 dnotify and introduces several new features. It allows monitoring
370 of both files and directories via a single open fd. Multiple file 370 of both files and directories via a single open fd. Other features
371 events are supported. 371 include multiple file events, one-shot support, and unmount
372 notification.
373
374 For more information, see Documentation/filesystems/inotify.txt
372 375
373 If unsure, say Y. 376 If unsure, say Y.
374 377
diff --git a/fs/bio.c b/fs/bio.c
index 249dd6bb66c8..1f2d4649b188 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -248,17 +248,13 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src)
248{ 248{
249 request_queue_t *q = bdev_get_queue(bio_src->bi_bdev); 249 request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
250 250
251 memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * sizeof(struct bio_vec)); 251 memcpy(bio->bi_io_vec, bio_src->bi_io_vec,
252 bio_src->bi_max_vecs * sizeof(struct bio_vec));
252 253
253 bio->bi_sector = bio_src->bi_sector; 254 bio->bi_sector = bio_src->bi_sector;
254 bio->bi_bdev = bio_src->bi_bdev; 255 bio->bi_bdev = bio_src->bi_bdev;
255 bio->bi_flags |= 1 << BIO_CLONED; 256 bio->bi_flags |= 1 << BIO_CLONED;
256 bio->bi_rw = bio_src->bi_rw; 257 bio->bi_rw = bio_src->bi_rw;
257
258 /*
259 * notes -- maybe just leave bi_idx alone. assume identical mapping
260 * for the clone
261 */
262 bio->bi_vcnt = bio_src->bi_vcnt; 258 bio->bi_vcnt = bio_src->bi_vcnt;
263 bio->bi_size = bio_src->bi_size; 259 bio->bi_size = bio_src->bi_size;
264 bio->bi_idx = bio_src->bi_idx; 260 bio->bi_idx = bio_src->bi_idx;
diff --git a/fs/dcache.c b/fs/dcache.c
index 3aa8a7e980d8..a15a2e1f5520 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -19,6 +19,7 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/fsnotify.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
@@ -101,6 +102,7 @@ static inline void dentry_iput(struct dentry * dentry)
101 list_del_init(&dentry->d_alias); 102 list_del_init(&dentry->d_alias);
102 spin_unlock(&dentry->d_lock); 103 spin_unlock(&dentry->d_lock);
103 spin_unlock(&dcache_lock); 104 spin_unlock(&dcache_lock);
105 fsnotify_inoderemove(inode);
104 if (dentry->d_op && dentry->d_op->d_iput) 106 if (dentry->d_op && dentry->d_op->d_iput)
105 dentry->d_op->d_iput(dentry, inode); 107 dentry->d_op->d_iput(dentry, inode);
106 else 108 else
@@ -1165,13 +1167,16 @@ out:
1165 1167
1166void d_delete(struct dentry * dentry) 1168void d_delete(struct dentry * dentry)
1167{ 1169{
1170 int isdir = 0;
1168 /* 1171 /*
1169 * Are we the only user? 1172 * Are we the only user?
1170 */ 1173 */
1171 spin_lock(&dcache_lock); 1174 spin_lock(&dcache_lock);
1172 spin_lock(&dentry->d_lock); 1175 spin_lock(&dentry->d_lock);
1176 isdir = S_ISDIR(dentry->d_inode->i_mode);
1173 if (atomic_read(&dentry->d_count) == 1) { 1177 if (atomic_read(&dentry->d_count) == 1) {
1174 dentry_iput(dentry); 1178 dentry_iput(dentry);
1179 fsnotify_nameremove(dentry, isdir);
1175 return; 1180 return;
1176 } 1181 }
1177 1182
@@ -1180,6 +1185,8 @@ void d_delete(struct dentry * dentry)
1180 1185
1181 spin_unlock(&dentry->d_lock); 1186 spin_unlock(&dentry->d_lock);
1182 spin_unlock(&dcache_lock); 1187 spin_unlock(&dcache_lock);
1188
1189 fsnotify_nameremove(dentry, isdir);
1183} 1190}
1184 1191
1185static void __d_rehash(struct dentry * entry, struct hlist_head *list) 1192static void __d_rehash(struct dentry * entry, struct hlist_head *list)
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 6ad1211f84ed..a096c5a56664 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -480,6 +480,8 @@ void hfs_bnode_put(struct hfs_bnode *node)
480 return; 480 return;
481 } 481 }
482 for (i = 0; i < tree->pages_per_bnode; i++) { 482 for (i = 0; i < tree->pages_per_bnode; i++) {
483 if (!node->page[i])
484 continue;
483 mark_page_accessed(node->page[i]); 485 mark_page_accessed(node->page[i]);
484#if REF_PAGES 486#if REF_PAGES
485 put_page(node->page[i]); 487 put_page(node->page[i]);
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
index cbc8510ad222..5ea6b3d45eaa 100644
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -482,7 +482,8 @@ void hfs_file_truncate(struct inode *inode)
482 page_cache_release(page); 482 page_cache_release(page);
483 mark_inode_dirty(inode); 483 mark_inode_dirty(inode);
484 return; 484 return;
485 } 485 } else if (inode->i_size == HFS_I(inode)->phys_size)
486 return;
486 size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1; 487 size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1;
487 blk_cnt = size / HFS_SB(sb)->alloc_blksz; 488 blk_cnt = size / HFS_SB(sb)->alloc_blksz;
488 alloc_cnt = HFS_I(inode)->alloc_blocks; 489 alloc_cnt = HFS_I(inode)->alloc_blocks;
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 267872e84d71..8868d3b766fd 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -643,6 +643,8 @@ void hfs_bnode_put(struct hfs_bnode *node)
643 return; 643 return;
644 } 644 }
645 for (i = 0; i < tree->pages_per_bnode; i++) { 645 for (i = 0; i < tree->pages_per_bnode; i++) {
646 if (!node->page[i])
647 continue;
646 mark_page_accessed(node->page[i]); 648 mark_page_accessed(node->page[i]);
647#if REF_PAGES 649#if REF_PAGES
648 put_page(node->page[i]); 650 put_page(node->page[i]);
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index 376498cc64fd..e7235ca79a95 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -461,7 +461,9 @@ void hfsplus_file_truncate(struct inode *inode)
461 page_cache_release(page); 461 page_cache_release(page);
462 mark_inode_dirty(inode); 462 mark_inode_dirty(inode);
463 return; 463 return;
464 } 464 } else if (inode->i_size == HFSPLUS_I(inode).phys_size)
465 return;
466
465 blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; 467 blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift;
466 alloc_cnt = HFSPLUS_I(inode).alloc_blocks; 468 alloc_cnt = HFSPLUS_I(inode).alloc_blocks;
467 if (blk_cnt == alloc_cnt) 469 if (blk_cnt == alloc_cnt)
diff --git a/fs/inotify.c b/fs/inotify.c
index a8a714e48140..27ebcac5e07f 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -90,6 +90,7 @@ struct inotify_device {
90 unsigned int queue_size; /* size of the queue (bytes) */ 90 unsigned int queue_size; /* size of the queue (bytes) */
91 unsigned int event_count; /* number of pending events */ 91 unsigned int event_count; /* number of pending events */
92 unsigned int max_events; /* maximum number of events */ 92 unsigned int max_events; /* maximum number of events */
93 u32 last_wd; /* the last wd allocated */
93}; 94};
94 95
95/* 96/*
@@ -352,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev,
352 do { 353 do {
353 if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) 354 if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL)))
354 return -ENOSPC; 355 return -ENOSPC;
355 ret = idr_get_new(&dev->idr, watch, &watch->wd); 356 ret = idr_get_new_above(&dev->idr, watch, dev->last_wd, &watch->wd);
356 } while (ret == -EAGAIN); 357 } while (ret == -EAGAIN);
357 358
358 return ret; 359 return ret;
@@ -401,6 +402,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
401 return ERR_PTR(ret); 402 return ERR_PTR(ret);
402 } 403 }
403 404
405 dev->last_wd = ret;
404 watch->mask = mask; 406 watch->mask = mask;
405 atomic_set(&watch->count, 0); 407 atomic_set(&watch->count, 0);
406 INIT_LIST_HEAD(&watch->d_list); 408 INIT_LIST_HEAD(&watch->d_list);
@@ -899,6 +901,7 @@ asmlinkage long sys_inotify_init(void)
899 dev->queue_size = 0; 901 dev->queue_size = 0;
900 dev->max_events = inotify_max_queued_events; 902 dev->max_events = inotify_max_queued_events;
901 dev->user = user; 903 dev->user = user;
904 dev->last_wd = 0;
902 atomic_set(&dev->count, 0); 905 atomic_set(&dev->count, 0);
903 906
904 get_inotify_dev(dev); 907 get_inotify_dev(dev);
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index 34a44e451689..4917315db732 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file *file, struct page *page)
129 cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask))); 129 cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask)));
130 brelse(bh); 130 brelse(bh);
131 131
132 if (cstart > cend)
133 goto eio;
134
132 csize = cend-cstart; 135 csize = cend-cstart;
133 136
137 if (csize > deflateBound(1UL << zisofs_block_shift))
138 goto eio;
139
134 /* Now page[] contains an array of pages, any of which can be NULL, 140 /* Now page[] contains an array of pages, any of which can be NULL,
135 and the locks on which we hold. We should now read the data and 141 and the locks on which we hold. We should now read the data and
136 release the pages. If the pages are NULL the decompressed data 142 release the pages. If the pages are NULL the decompressed data
diff --git a/fs/namei.c b/fs/namei.c
index 02a824cd3c5c..57046d98a746 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1801,7 +1801,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
1801 } 1801 }
1802 up(&dentry->d_inode->i_sem); 1802 up(&dentry->d_inode->i_sem);
1803 if (!error) { 1803 if (!error) {
1804 fsnotify_rmdir(dentry, dentry->d_inode, dir);
1805 d_delete(dentry); 1804 d_delete(dentry);
1806 } 1805 }
1807 dput(dentry); 1806 dput(dentry);
@@ -1874,7 +1873,6 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
1874 1873
1875 /* We don't d_delete() NFS sillyrenamed files--they still exist. */ 1874 /* We don't d_delete() NFS sillyrenamed files--they still exist. */
1876 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { 1875 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
1877 fsnotify_unlink(dentry, dir);
1878 d_delete(dentry); 1876 d_delete(dentry);
1879 } 1877 }
1880 1878
@@ -2218,7 +2216,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2218 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); 2216 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
2219 if (!error) { 2217 if (!error) {
2220 const char *new_name = old_dentry->d_name.name; 2218 const char *new_name = old_dentry->d_name.name;
2221 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir); 2219 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, new_dentry->d_inode);
2222 } 2220 }
2223 fsnotify_oldname_free(old_name); 2221 fsnotify_oldname_free(old_name);
2224 2222
diff --git a/fs/namespace.c b/fs/namespace.c
index 587eb0d707ee..79bd8a46e1e7 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -160,7 +160,7 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
160 mnt->mnt_root = dget(root); 160 mnt->mnt_root = dget(root);
161 mnt->mnt_mountpoint = mnt->mnt_root; 161 mnt->mnt_mountpoint = mnt->mnt_root;
162 mnt->mnt_parent = mnt; 162 mnt->mnt_parent = mnt;
163 mnt->mnt_namespace = old->mnt_namespace; 163 mnt->mnt_namespace = current->namespace;
164 164
165 /* stick the duplicate mount on the same expiry list 165 /* stick the duplicate mount on the same expiry list
166 * as the original if that was on one */ 166 * as the original if that was on one */