source:
scripts_home/scripts/untested/blfs-patches/inotify-0.18-rml-2.6.10-4.patch@
1c9c5c3
Last change on this file since 1c9c5c3 was 1c9c5c3, checked in by , 19 years ago | |
---|---|
|
|
File size: 46.3 KB |
-
drivers/char/inotify.c
inotify, bitches. Signed-off-by: Robert Love <rml@novell.com> drivers/char/Kconfig | 13 drivers/char/Makefile | 2 drivers/char/inotify.c | 1067 +++++++++++++++++++++++++++++++++++++++++++++ drivers/char/misc.c | 14 fs/attr.c | 73 ++- fs/file_table.c | 7 fs/inode.c | 3 fs/namei.c | 36 + fs/open.c | 5 fs/read_write.c | 33 + fs/super.c | 2 include/linux/fs.h | 7 include/linux/inotify.h | 160 ++++++ include/linux/miscdevice.h | 5 include/linux/sched.h | 2 kernel/user.c | 2 16 files changed, 1392 insertions(+), 39 deletions(-) diff -urN linux-2.6.10/drivers/char/inotify.c linux/drivers/char/inotify.c
old new 1 /* 2 * Inode based directory notifications for Linux. 3 * 4 * Copyright (C) 2004 John McCutchan 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2, or (at your option) any 9 * later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 */ 16 17 #include <linux/module.h> 18 #include <linux/kernel.h> 19 #include <linux/sched.h> 20 #include <linux/spinlock.h> 21 #include <linux/idr.h> 22 #include <linux/slab.h> 23 #include <linux/fs.h> 24 #include <linux/namei.h> 25 #include <linux/poll.h> 26 #include <linux/device.h> 27 #include <linux/miscdevice.h> 28 #include <linux/init.h> 29 #include <linux/list.h> 30 #include <linux/writeback.h> 31 #include <linux/inotify.h> 32 33 #include <asm/ioctls.h> 34 35 static atomic_t inotify_cookie; 36 static kmem_cache_t *watch_cachep; 37 static kmem_cache_t *event_cachep; 38 static kmem_cache_t *inode_data_cachep; 39 40 static int sysfs_attrib_max_user_devices; 41 static int sysfs_attrib_max_user_watches; 42 static unsigned int sysfs_attrib_max_queued_events; 43 44 /* 45 * struct inotify_device - represents an open instance of an inotify device 46 * 47 * For each inotify device, we need to keep track of the events queued on it, 48 * a list of the inodes that we are watching, and so on. 49 * 50 * This structure is protected by 'lock'. Lock ordering: 51 * 52 * dev->lock (protects dev) 53 * inode_lock (used to safely walk inode_in_use list) 54 * inode->i_lock (only needed for getting ref on inode_data) 55 */ 56 struct inotify_device { 57 wait_queue_head_t wait; 58 struct idr idr; 59 struct list_head events; 60 struct list_head watches; 61 spinlock_t lock; 62 unsigned int queue_size; 63 unsigned int event_count; 64 unsigned int max_events; 65 struct user_struct *user; 66 }; 67 68 struct inotify_watch { 69 s32 wd; /* watch descriptor */ 70 u32 mask; 71 struct inode *inode; 72 struct inotify_device *dev; 73 struct list_head d_list; /* device list */ 74 struct list_head i_list; /* inode list */ 75 }; 76 77 static ssize_t show_max_queued_events(struct class_device *class, char *buf) 78 { 79 return sprintf(buf, "%d\n", sysfs_attrib_max_queued_events); 80 } 81 82 static ssize_t store_max_queued_events(struct class_device *class, 83 const char *buf, size_t count) 84 { 85 unsigned int max; 86 87 if (sscanf(buf, "%u", &max) > 0 && max > 0) { 88 sysfs_attrib_max_queued_events = max; 89 return strlen(buf); 90 } 91 return -EINVAL; 92 } 93 94 static ssize_t show_max_user_devices(struct class_device *class, char *buf) 95 { 96 return sprintf(buf, "%d\n", sysfs_attrib_max_user_devices); 97 } 98 99 static ssize_t store_max_user_devices(struct class_device *class, 100 const char *buf, size_t count) 101 { 102 int max; 103 104 if (sscanf(buf, "%d", &max) > 0 && max > 0) { 105 sysfs_attrib_max_user_devices = max; 106 return strlen(buf); 107 } 108 return -EINVAL; 109 } 110 111 static ssize_t show_max_user_watches(struct class_device *class, char *buf) 112 { 113 return sprintf(buf, "%d\n", sysfs_attrib_max_user_watches); 114 } 115 116 static ssize_t store_max_user_watches(struct class_device *class, 117 const char *buf, size_t count) 118 { 119 int max; 120 121 if (sscanf(buf, "%d", &max) > 0 && max > 0) { 122 sysfs_attrib_max_user_watches = max; 123 return strlen(buf); 124 } 125 return -EINVAL; 126 } 127 128 static CLASS_DEVICE_ATTR(max_queued_events, S_IRUGO | S_IWUSR, 129 show_max_queued_events, store_max_queued_events); 130 static CLASS_DEVICE_ATTR(max_user_devices, S_IRUGO | S_IWUSR, 131 show_max_user_devices, store_max_user_devices); 132 static CLASS_DEVICE_ATTR(max_user_watches, S_IRUGO | S_IWUSR, 133 show_max_user_watches, store_max_user_watches); 134 135 /* 136 * A list of these is attached to each instance of the driver 137 * when the drivers read() gets called, this list is walked and 138 * all events that can fit in the buffer get delivered 139 */ 140 struct inotify_kernel_event { 141 struct list_head list; 142 struct inotify_event event; 143 }; 144 145 static inline void __get_inode_data(struct inotify_inode_data *data) 146 { 147 atomic_inc(&data->count); 148 } 149 150 /* 151 * get_inode_data - pin an inotify_inode_data structure. Returns the structure 152 * if successful and NULL on failure, which can only occur if inotify_data is 153 * not yet allocated. The inode must be pinned prior to invocation. 154 */ 155 static inline struct inotify_inode_data * get_inode_data(struct inode *inode) 156 { 157 struct inotify_inode_data *data; 158 159 spin_lock(&inode->i_lock); 160 data = inode->inotify_data; 161 if (data) 162 __get_inode_data(data); 163 spin_unlock(&inode->i_lock); 164 165 return data; 166 } 167 168 /* 169 * put_inode_data - drop our reference on an inotify_inode_data and the 170 * inode structure in which it lives. If the reference count on inotify_data 171 * reaches zero, free it. 172 */ 173 static inline void put_inode_data(struct inode *inode) 174 { 175 //spin_lock(&inode->i_lock); 176 if (atomic_dec_and_test(&inode->inotify_data->count)) { 177 kmem_cache_free(inode_data_cachep, inode->inotify_data); 178 inode->inotify_data = NULL; 179 } 180 //spin_unlock(&inode->i_lock); 181 } 182 183 /* 184 * find_inode - resolve a user-given path to a specific inode and iget() it 185 */ 186 static struct inode * find_inode(const char __user *dirname) 187 { 188 struct inode *inode; 189 struct nameidata nd; 190 int error; 191 192 error = __user_walk(dirname, LOOKUP_FOLLOW, &nd); 193 if (error) 194 return ERR_PTR(error); 195 196 inode = nd.dentry->d_inode; 197 198 /* you can only watch an inode if you have read permissions on it */ 199 error = permission(inode, MAY_READ, NULL); 200 if (error) { 201 inode = ERR_PTR(error); 202 goto release_and_out; 203 } 204 205 spin_lock(&inode_lock); 206 __iget(inode); 207 spin_unlock(&inode_lock); 208 release_and_out: 209 path_release(&nd); 210 return inode; 211 } 212 213 struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie, 214 const char *filename) 215 { 216 struct inotify_kernel_event *kevent; 217 218 kevent = kmem_cache_alloc(event_cachep, GFP_ATOMIC); 219 if (!kevent) 220 return NULL; 221 222 /* we hand this out to user-space, so zero it out just in case */ 223 memset(kevent, 0, sizeof(struct inotify_kernel_event)); 224 225 kevent->event.wd = wd; 226 kevent->event.mask = mask; 227 kevent->event.cookie = cookie; 228 INIT_LIST_HEAD(&kevent->list); 229 230 if (filename) { 231 size_t len; 232 233 len = strlen(filename); 234 kevent->event.filename = kmalloc(len+1, GFP_ATOMIC); 235 if (!kevent->event.filename) { 236 kmem_cache_free (event_cachep, kevent); 237 return NULL; 238 } 239 memset(kevent->event.filename, 0, len+1); 240 strncpy(kevent->event.filename, filename, len); 241 kevent->event.len = len; 242 } else 243 kevent->event.filename = NULL; 244 245 return kevent; 246 } 247 248 void delete_kernel_event(struct inotify_kernel_event *kevent) 249 { 250 if (!kevent) 251 return; 252 253 if (kevent->event.filename) 254 kfree (kevent->event.filename); 255 kmem_cache_free(event_cachep, kevent); 256 } 257 258 #define list_to_inotify_kernel_event(pos) \ 259 list_entry((pos), struct inotify_kernel_event, list) 260 261 #define inotify_dev_get_event(dev) \ 262 (list_to_inotify_kernel_event(dev->events.next)) 263 264 /* Does this events mask get sent to the watch ? */ 265 #define event_and(event_mask,watches_mask) ((event_mask == IN_UNMOUNT) || \ 266 (event_mask == IN_IGNORED) || \ 267 (event_mask & watches_mask)) 268 269 /* 270 * inotify_dev_queue_event - add a new event to the given device 271 * 272 * Caller must hold dev->lock. 273 */ 274 static void inotify_dev_queue_event(struct inotify_device *dev, 275 struct inotify_watch *watch, u32 mask, 276 u32 cookie, const char *filename) 277 { 278 struct inotify_kernel_event *kevent, *last; 279 280 /* Check if the new event is a duplicate of the last event queued. */ 281 last = inotify_dev_get_event(dev); 282 if (dev->event_count && last->event.mask == mask && 283 last->event.wd == watch->wd) { 284 /* Check if the filenames match */ 285 if (!filename && last->event.filename[0] == '\0') 286 return; 287 if (filename && !strcmp(last->event.filename, filename)) 288 return; 289 } 290 291 /* 292 * the queue has already overflowed and we have already sent the 293 * Q_OVERFLOW event 294 */ 295 if (dev->event_count > dev->max_events) 296 return; 297 298 /* the queue has just overflowed and we need to notify user space */ 299 if (dev->event_count == dev->max_events) { 300 kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL); 301 goto add_event_to_queue; 302 } 303 304 if (!event_and(mask, watch->inode->inotify_data->watch_mask) || 305 !event_and(mask, watch->mask)) 306 return; 307 308 kevent = kernel_event(watch->wd, mask, cookie, filename); 309 310 add_event_to_queue: 311 if (!kevent) 312 return; 313 314 /* queue the event and wake up anyone waiting */ 315 dev->event_count++; 316 dev->queue_size += sizeof(struct inotify_event) + kevent->event.len - 317 sizeof(char *) + 1; 318 list_add_tail(&kevent->list, &dev->events); 319 wake_up_interruptible(&dev->wait); 320 } 321 322 static inline int inotify_dev_has_events(struct inotify_device *dev) 323 { 324 return !list_empty(&dev->events); 325 } 326 327 /* 328 * inotify_dev_event_dequeue - destroy an event on the given device 329 * 330 * Caller must hold dev->lock. 331 */ 332 static void inotify_dev_event_dequeue(struct inotify_device *dev) 333 { 334 struct inotify_kernel_event *kevent; 335 336 if (!inotify_dev_has_events(dev)) 337 return; 338 339 kevent = inotify_dev_get_event(dev); 340 list_del_init(&kevent->list); 341 dev->event_count--; 342 dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len - 343 sizeof(char *) + 1; 344 delete_kernel_event(kevent); 345 } 346 347 /* 348 * inotify_dev_get_wd - returns the next WD for use by the given dev 349 * 350 * This function can sleep. 351 */ 352 static int inotify_dev_get_wd(struct inotify_device *dev, 353 struct inotify_watch *watch) 354 { 355 int ret; 356 357 if (atomic_read(&dev->user->inotify_watches) >= 358 sysfs_attrib_max_user_watches) 359 return -ENOSPC; 360 361 repeat: 362 if (!idr_pre_get(&dev->idr, GFP_KERNEL)) 363 return -ENOSPC; 364 spin_lock(&dev->lock); 365 ret = idr_get_new(&dev->idr, watch, &watch->wd); 366 spin_unlock(&dev->lock); 367 if (ret == -EAGAIN) /* more memory is required, try again */ 368 goto repeat; 369 else if (ret) /* the idr is full! */ 370 return -ENOSPC; 371 372 atomic_inc(&dev->user->inotify_watches); 373 374 return 0; 375 } 376 377 /* 378 * inotify_dev_put_wd - release the given WD on the given device 379 * 380 * Caller must hold dev->lock. 381 */ 382 static int inotify_dev_put_wd(struct inotify_device *dev, s32 wd) 383 { 384 if (!dev || wd < 0) 385 return -1; 386 387 atomic_dec(&dev->user->inotify_watches); 388 idr_remove(&dev->idr, wd); 389 390 return 0; 391 } 392 393 /* 394 * create_watch - creates a watch on the given device. 395 * 396 * Grabs dev->lock, so the caller must not hold it. 397 */ 398 static struct inotify_watch *create_watch(struct inotify_device *dev, 399 u32 mask, struct inode *inode) 400 { 401 struct inotify_watch *watch; 402 403 watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL); 404 if (!watch) 405 return NULL; 406 407 watch->mask = mask; 408 watch->inode = inode; 409 watch->dev = dev; 410 INIT_LIST_HEAD(&watch->d_list); 411 INIT_LIST_HEAD(&watch->i_list); 412 413 if (inotify_dev_get_wd(dev, watch)) { 414 kmem_cache_free(watch_cachep, watch); 415 return NULL; 416 } 417 418 return watch; 419 } 420 421 /* 422 * delete_watch - removes the given 'watch' from the given 'dev' 423 * 424 * Caller must hold dev->lock. 425 */ 426 static void delete_watch(struct inotify_device *dev, 427 struct inotify_watch *watch) 428 { 429 inotify_dev_put_wd(dev, watch->wd); 430 kmem_cache_free(watch_cachep, watch); 431 } 432 433 /* 434 * inotify_find_dev - find the watch associated with the given inode and dev 435 * 436 * Caller must hold dev->lock. 437 * FIXME: Needs inotify_data->lock too. Don't need dev->lock, just pin it. 438 */ 439 static struct inotify_watch *inode_find_dev(struct inode *inode, 440 struct inotify_device *dev) 441 { 442 struct inotify_watch *watch; 443 444 if (!inode->inotify_data) 445 return NULL; 446 447 list_for_each_entry(watch, &inode->inotify_data->watches, i_list) { 448 if (watch->dev == dev) 449 return watch; 450 } 451 452 return NULL; 453 } 454 455 /* 456 * dev_find_wd - given a (dev,wd) pair, returns the matching inotify_watcher 457 * 458 * Returns the results of looking up (dev,wd) in the idr layer. NULL is 459 * returned on error. 460 * 461 * The caller must hold dev->lock. 462 */ 463 static inline struct inotify_watch *dev_find_wd(struct inotify_device *dev, 464 u32 wd) 465 { 466 return idr_find(&dev->idr, wd); 467 } 468 469 static int inotify_dev_is_watching_inode(struct inotify_device *dev, 470 struct inode *inode) 471 { 472 struct inotify_watch *watch; 473 474 list_for_each_entry(watch, &dev->watches, d_list) { 475 if (watch->inode == inode) 476 return 1; 477 } 478 479 return 0; 480 } 481 482 /* 483 * inotify_dev_add_watcher - add the given watcher to the given device instance 484 * 485 * Caller must hold dev->lock. 486 */ 487 static int inotify_dev_add_watch(struct inotify_device *dev, 488 struct inotify_watch *watch) 489 { 490 if (!dev || !watch) 491 return -EINVAL; 492 493 list_add(&watch->d_list, &dev->watches); 494 return 0; 495 } 496 497 /* 498 * inotify_dev_rm_watch - remove the given watch from the given device 499 * 500 * Caller must hold dev->lock because we call inotify_dev_queue_event(). 501 */ 502 static int inotify_dev_rm_watch(struct inotify_device *dev, 503 struct inotify_watch *watch) 504 { 505 if (!watch) 506 return -EINVAL; 507 508 inotify_dev_queue_event(dev, watch, IN_IGNORED, 0, NULL); 509 list_del_init(&watch->d_list); 510 511 return 0; 512 } 513 514 /* 515 * inode_update_watch_mask - update inode->inotify_data->watch_mask 516 * 517 * Grabs inode->inotify_data->lock. 518 */ 519 static void inode_update_watch_mask(struct inode *inode) 520 { 521 struct inotify_inode_data *data; 522 struct inotify_watch *watch; 523 u32 new_mask; 524 525 data = get_inode_data(inode); 526 if (!data) /* FIXME: this should never happen */ 527 return; 528 spin_lock(&data->lock); 529 530 new_mask = 0; 531 list_for_each_entry(watch, &data->watches, i_list) 532 new_mask |= watch->mask; 533 534 data->watch_mask = new_mask; 535 536 spin_unlock(&data->lock); 537 put_inode_data(inode); 538 } 539 540 /* 541 * inode_add_watch - add a watch to the given inode 542 * 543 * Callers must hold dev->lock, because we call inode_find_dev(). 544 */ 545 static int inode_add_watch(struct inode *inode, struct inotify_watch *watch) 546 { 547 int ret; 548 549 if (!inode || !watch) 550 return -EINVAL; 551 552 spin_lock(&inode->i_lock); 553 if (!inode->inotify_data) { 554 /* inotify_data is not attached to the inode, so add it */ 555 inode->inotify_data = kmem_cache_alloc(inode_data_cachep, 556 GFP_ATOMIC); 557 if (!inode->inotify_data) { 558 ret = -ENOMEM; 559 goto out_lock; 560 } 561 562 atomic_set(&inode->inotify_data->count, 0); 563 INIT_LIST_HEAD(&inode->inotify_data->watches); 564 inode->inotify_data->watch_mask = 0; 565 spin_lock_init(&inode->inotify_data->lock); 566 } else if (inode_find_dev(inode, watch->dev)) { 567 /* a watch is already associated with this (inode,dev) pair */ 568 ret = -EINVAL; 569 goto out_lock; 570 } 571 __get_inode_data(inode->inotify_data); 572 spin_unlock(&inode->i_lock); 573 574 list_add(&watch->i_list, &inode->inotify_data->watches); 575 inode_update_watch_mask(inode); 576 577 return 0; 578 out_lock: 579 spin_unlock(&inode->i_lock); 580 return ret; 581 } 582 583 static int inode_rm_watch(struct inode *inode, 584 struct inotify_watch *watch) 585 { 586 if (!inode || !watch || !inode->inotify_data) 587 return -EINVAL; 588 589 list_del_init(&watch->i_list); 590 inode_update_watch_mask(inode); 591 592 /* clean up inode->inotify_data */ 593 put_inode_data(inode); 594 595 return 0; 596 } 597 598 /* Kernel API */ 599 600 /* 601 * inotify_inode_queue_event - queue an event with the given mask, cookie, and 602 * filename to any watches associated with the given inode. 603 * 604 * inode must be pinned prior to calling. 605 */ 606 void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie, 607 const char *filename) 608 { 609 struct inotify_watch *watch; 610 611 if (!inode->inotify_data) 612 return; 613 614 list_for_each_entry(watch, &inode->inotify_data->watches, i_list) { 615 spin_lock(&watch->dev->lock); 616 inotify_dev_queue_event(watch->dev, watch, mask, cookie, 617 filename); 618 spin_unlock(&watch->dev->lock); 619 } 620 } 621 EXPORT_SYMBOL_GPL(inotify_inode_queue_event); 622 623 void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask, 624 u32 cookie, const char *filename) 625 { 626 struct dentry *parent; 627 628 parent = dget_parent(dentry); 629 inotify_inode_queue_event(parent->d_inode, mask, cookie, filename); 630 dput(parent); 631 } 632 EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event); 633 634 u32 inotify_get_cookie(void) 635 { 636 atomic_inc(&inotify_cookie); 637 return atomic_read(&inotify_cookie); 638 } 639 EXPORT_SYMBOL_GPL(inotify_get_cookie); 640 641 /* 642 * watch->inode must be pinned. We drop a reference before returning. 643 */ 644 static void ignore_helper(struct inotify_watch *watch, int event) 645 { 646 struct inotify_device *dev; 647 struct inode *inode; 648 649 inode = watch->inode; 650 dev = watch->dev; 651 652 spin_lock(&dev->lock); 653 654 if (event) 655 inotify_dev_queue_event(dev, watch, event, 0, NULL); 656 657 inode_rm_watch(inode, watch); 658 inotify_dev_rm_watch(watch->dev, watch); 659 660 delete_watch(dev, watch); 661 spin_unlock(&dev->lock); 662 663 iput(inode); 664 } 665 666 void inotify_super_block_umount(struct super_block *sb) 667 { 668 struct inode *inode; 669 670 spin_lock(&inode_lock); 671 672 /* 673 * We hold the inode_lock, so the inodes are not going anywhere, and 674 * we grab a reference on inotify_data before walking its list of 675 * watches. 676 */ 677 list_for_each_entry(inode, &inode_in_use, i_list) { 678 struct inotify_inode_data *inode_data; 679 struct inotify_watch *watch; 680 681 if (inode->i_sb != sb) 682 continue; 683 684 inode_data = get_inode_data(inode); 685 if (!inode_data) 686 continue; 687 688 list_for_each_entry(watch, &inode_data->watches, i_list) 689 ignore_helper(watch, IN_UNMOUNT); 690 put_inode_data(inode); 691 } 692 693 spin_unlock(&inode_lock); 694 } 695 EXPORT_SYMBOL_GPL(inotify_super_block_umount); 696 697 /* 698 * inotify_inode_is_dead - an inode has been deleted, cleanup any watches 699 */ 700 void inotify_inode_is_dead(struct inode *inode) 701 { 702 struct inotify_watch *watch, *next; 703 struct inotify_inode_data *data; 704 705 data = get_inode_data(inode); 706 if (!data) 707 return; 708 list_for_each_entry_safe(watch, next, &data->watches, i_list) 709 ignore_helper(watch, 0); 710 put_inode_data(inode); 711 } 712 EXPORT_SYMBOL_GPL(inotify_inode_is_dead); 713 714 /* The driver interface is implemented below */ 715 716 static unsigned int inotify_poll(struct file *file, poll_table *wait) 717 { 718 struct inotify_device *dev; 719 720 dev = file->private_data; 721 722 poll_wait(file, &dev->wait, wait); 723 724 if (inotify_dev_has_events(dev)) 725 return POLLIN | POLLRDNORM; 726 727 return 0; 728 } 729 730 static ssize_t inotify_read(struct file *file, char __user *buf, 731 size_t count, loff_t *pos) 732 { 733 size_t event_size; 734 struct inotify_device *dev; 735 char __user *start; 736 DECLARE_WAITQUEUE(wait, current); 737 738 start = buf; 739 dev = file->private_data; 740 741 /* We only hand out full inotify events */ 742 event_size = sizeof(struct inotify_event) - sizeof(char *); 743 744 if (count < event_size) 745 return -EINVAL; 746 747 while (1) { 748 int has_events; 749 750 spin_lock(&dev->lock); 751 has_events = inotify_dev_has_events(dev); 752 spin_unlock(&dev->lock); 753 if (has_events) 754 break; 755 756 if (file->f_flags & O_NONBLOCK) 757 return -EAGAIN; 758 759 if (signal_pending(current)) 760 return -ERESTARTSYS; 761 762 add_wait_queue(&dev->wait, &wait); 763 set_current_state(TASK_INTERRUPTIBLE); 764 765 schedule(); 766 767 set_current_state(TASK_RUNNING); 768 remove_wait_queue(&dev->wait, &wait); 769 } 770 771 while (count >= event_size) { 772 struct inotify_kernel_event *kevent; 773 774 spin_lock(&dev->lock); 775 if (!inotify_dev_has_events(dev)) { 776 spin_unlock(&dev->lock); 777 break; 778 } 779 kevent = inotify_dev_get_event(dev); 780 781 /* We can't send this event, not enough space in the buffer */ 782 if ((event_size + kevent->event.len + 1) > count) { 783 spin_unlock(&dev->lock); 784 break; 785 } 786 spin_unlock(&dev->lock); 787 788 /* Copy the entire event except the string to user space */ 789 if (copy_to_user(buf, &kevent->event, event_size)) 790 return -EFAULT; 791 792 buf += event_size; 793 count -= event_size; 794 795 /* Copy the filename to user space */ 796 if (kevent->event.filename) { 797 if (copy_to_user(buf, kevent->event.filename, 798 kevent->event.len+1)) 799 return -EFAULT; 800 buf += kevent->event.len + 1; 801 count -= kevent->event.len + 1; 802 } else { 803 int z = 0; 804 /* Copy the NULL */ 805 if (copy_to_user(buf, &z, 1)) 806 return -EFAULT; 807 808 buf += 1; 809 count -= 1; 810 } 811 812 spin_lock(&dev->lock); 813 inotify_dev_event_dequeue(dev); 814 spin_unlock(&dev->lock); 815 } 816 817 return buf - start; 818 } 819 820 static int inotify_open(struct inode *inode, struct file *file) 821 { 822 struct inotify_device *dev; 823 struct user_struct *user; 824 int ret; 825 826 user = get_uid(current->user); 827 828 if (atomic_read(&user->inotify_devs) >= sysfs_attrib_max_user_devices) { 829 ret = -ENOSPC; 830 goto out_err; 831 } 832 833 atomic_inc(¤t->user->inotify_devs); 834 835 dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL); 836 if (!dev) { 837 ret = -ENOMEM; 838 goto out_err; 839 } 840 841 idr_init(&dev->idr); 842 843 INIT_LIST_HEAD(&dev->events); 844 INIT_LIST_HEAD(&dev->watches); 845 init_waitqueue_head(&dev->wait); 846 847 dev->event_count = 0; 848 dev->queue_size = 0; 849 dev->max_events = sysfs_attrib_max_queued_events; 850 dev->user = user; 851 spin_lock_init(&dev->lock); 852 853 file->private_data = dev; 854 855 return 0; 856 out_err: 857 free_uid(current->user); 858 return ret; 859 } 860 861 /* 862 * inotify_release_all_watches - destroy all watches on a given device 863 * 864 * FIXME: Do we want a lock here? 865 */ 866 static void inotify_release_all_watches(struct inotify_device *dev) 867 { 868 struct inotify_watch *watch, *next; 869 870 list_for_each_entry_safe(watch, next, &dev->watches, d_list) 871 ignore_helper(watch, 0); 872 } 873 874 /* 875 * inotify_release_all_events - destroy all of the events on a given device 876 */ 877 static void inotify_release_all_events(struct inotify_device *dev) 878 { 879 spin_lock(&dev->lock); 880 while (inotify_dev_has_events(dev)) 881 inotify_dev_event_dequeue(dev); 882 spin_unlock(&dev->lock); 883 } 884 885 static int inotify_release(struct inode *inode, struct file *file) 886 { 887 struct inotify_device *dev; 888 889 dev = file->private_data; 890 891 inotify_release_all_watches(dev); 892 inotify_release_all_events(dev); 893 894 atomic_dec(&dev->user->inotify_devs); 895 free_uid(dev->user); 896 897 kfree(dev); 898 899 return 0; 900 } 901 902 static int inotify_add_watch(struct inotify_device *dev, 903 struct inotify_watch_request *request) 904 { 905 struct inode *inode; 906 struct inotify_watch *watch; 907 int ret; 908 909 inode = find_inode((const char __user*) request->dirname); 910 if (IS_ERR(inode)) 911 return PTR_ERR(inode); 912 913 spin_lock(&dev->lock); 914 915 /* 916 * This handles the case of re-adding a directory we are already 917 * watching, we just update the mask and return 0 918 */ 919 if (inotify_dev_is_watching_inode(dev, inode)) { 920 struct inotify_watch *owatch; /* the old watch */ 921 922 owatch = inode_find_dev(inode, dev); 923 owatch->mask = request->mask; 924 inode_update_watch_mask(inode); 925 spin_unlock(&dev->lock); 926 iput(inode); 927 928 return owatch->wd; 929 } 930 931 spin_unlock(&dev->lock); 932 933 watch = create_watch(dev, request->mask, inode); 934 if (!watch) { 935 iput(inode); 936 return -ENOSPC; 937 } 938 939 spin_lock(&dev->lock); 940 941 /* We can't add anymore watches to this device */ 942 if (inotify_dev_add_watch(dev, watch)) { 943 delete_watch(dev, watch); 944 spin_unlock(&dev->lock); 945 iput(inode); 946 return -EINVAL; 947 } 948 949 ret = inode_add_watch(inode, watch); 950 if (ret < 0) { 951 list_del_init(&watch->d_list); 952 delete_watch(dev, watch); 953 spin_unlock(&dev->lock); 954 iput(inode); 955 return ret; 956 } 957 958 spin_unlock(&dev->lock); 959 960 return watch->wd; 961 } 962 963 static int inotify_ignore(struct inotify_device *dev, s32 wd) 964 { 965 struct inotify_watch *watch; 966 967 /* 968 * FIXME: Silly to grab dev->lock here and then drop it, when 969 * ignore_helper() grabs it anyway a few lines down. 970 */ 971 spin_lock(&dev->lock); 972 watch = dev_find_wd(dev, wd); 973 spin_unlock(&dev->lock); 974 if (!watch) 975 return -EINVAL; 976 ignore_helper(watch, 0); 977 978 return 0; 979 } 980 981 /* 982 * inotify_ioctl() - our device file's ioctl method 983 * 984 * The VFS serializes all of our calls via the BKL and we rely on that. We 985 * could, alternatively, grab dev->lock. Right now lower levels grab that 986 * where needed. 987 */ 988 static int inotify_ioctl(struct inode *ip, struct file *fp, 989 unsigned int cmd, unsigned long arg) 990 { 991 struct inotify_device *dev; 992 struct inotify_watch_request request; 993 void __user *p; 994 s32 wd; 995 996 dev = fp->private_data; 997 p = (void __user *) arg; 998 999 switch (cmd) { 1000 case INOTIFY_WATCH: 1001 if (copy_from_user(&request, p, sizeof (request))) 1002 return -EFAULT; 1003 return inotify_add_watch(dev, &request); 1004 case INOTIFY_IGNORE: 1005 if (copy_from_user(&wd, p, sizeof (wd))) 1006 return -EFAULT; 1007 return inotify_ignore(dev, wd); 1008 case FIONREAD: 1009 return put_user(dev->queue_size, (int __user *) p); 1010 default: 1011 return -ENOTTY; 1012 } 1013 } 1014 1015 static struct file_operations inotify_fops = { 1016 .owner = THIS_MODULE, 1017 .poll = inotify_poll, 1018 .read = inotify_read, 1019 .open = inotify_open, 1020 .release = inotify_release, 1021 .ioctl = inotify_ioctl, 1022 }; 1023 1024 struct miscdevice inotify_device = { 1025 .minor = MISC_DYNAMIC_MINOR, 1026 .name = "inotify", 1027 .fops = &inotify_fops, 1028 }; 1029 1030 static int __init inotify_init(void) 1031 { 1032 struct class_device *class; 1033 int ret; 1034 1035 ret = misc_register(&inotify_device); 1036 if (ret) 1037 return ret; 1038 1039 sysfs_attrib_max_queued_events = 512; 1040 sysfs_attrib_max_user_devices = 64; 1041 sysfs_attrib_max_user_watches = 16384; 1042 1043 class = inotify_device.class; 1044 class_device_create_file(class, &class_device_attr_max_queued_events); 1045 class_device_create_file(class, &class_device_attr_max_user_devices); 1046 class_device_create_file(class, &class_device_attr_max_user_watches); 1047 1048 atomic_set(&inotify_cookie, 0); 1049 1050 watch_cachep = kmem_cache_create("inotify_watch_cache", 1051 sizeof(struct inotify_watch), 0, SLAB_PANIC, 1052 NULL, NULL); 1053 1054 event_cachep = kmem_cache_create("inotify_event_cache", 1055 sizeof(struct inotify_kernel_event), 0, 1056 SLAB_PANIC, NULL, NULL); 1057 1058 inode_data_cachep = kmem_cache_create("inotify_inode_data_cache", 1059 sizeof(struct inotify_inode_data), 0, SLAB_PANIC, 1060 NULL, NULL); 1061 1062 printk(KERN_INFO "inotify device minor=%d\n", inotify_device.minor); 1063 1064 return 0; 1065 } 1066 1067 module_init(inotify_init); -
drivers/char/Kconfig
diff -urN linux-2.6.10/drivers/char/Kconfig linux/drivers/char/Kconfig
old new 62 62 depends on VT && !S390 && !USERMODE 63 63 default y 64 64 65 config INOTIFY 66 bool "Inotify file change notification support" 67 default y 68 ---help--- 69 Say Y here to enable inotify support and the /dev/inotify character 70 device. Inotify is a file change notification system and a 71 replacement for dnotify. Inotify fixes numerous shortcomings in 72 dnotify and introduces several new features. It allows monitoring 73 of both files and directories via a single open fd. Multiple file 74 events are supported. 75 76 If unsure, say Y. 77 65 78 config SERIAL_NONSTANDARD 66 79 bool "Non-standard serial port support" 67 80 ---help--- -
drivers/char/Makefile
diff -urN linux-2.6.10/drivers/char/Makefile linux/drivers/char/Makefile
old new 9 9 10 10 obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o 11 11 12 13 obj-$(CONFIG_INOTIFY) += inotify.o 12 14 obj-$(CONFIG_LEGACY_PTYS) += pty.o 13 15 obj-$(CONFIG_UNIX98_PTYS) += pty.o 14 16 obj-y += misc.o -
drivers/char/misc.c
diff -urN linux-2.6.10/drivers/char/misc.c linux/drivers/char/misc.c
old new 207 207 int misc_register(struct miscdevice * misc) 208 208 { 209 209 struct miscdevice *c; 210 struct class_device *class;211 210 dev_t dev; 212 211 int err; 213 212 214 213 down(&misc_sem); 215 214 list_for_each_entry(c, &misc_list, list) { 216 215 if (c->minor == misc->minor) { … … 224 223 while (--i >= 0) 225 224 if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) 226 225 break; 227 if (i<0) 228 { 226 if (i<0) { 229 227 up(&misc_sem); 230 228 return -EBUSY; 231 229 } … … 240 238 } 241 239 dev = MKDEV(MISC_MAJOR, misc->minor); 242 240 243 class = class_simple_device_add(misc_class, dev,244 misc->dev, misc->name);245 if (IS_ERR( class)) {246 err = PTR_ERR( class);241 misc->class = class_simple_device_add(misc_class, dev, 242 misc->dev, misc->name); 243 if (IS_ERR(misc->class)) { 244 err = PTR_ERR(misc->class); 247 245 goto out; 248 246 } 249 247 -
fs/attr.c
diff -urN linux-2.6.10/fs/attr.c linux/fs/attr.c
old new 11 11 #include <linux/string.h> 12 12 #include <linux/smp_lock.h> 13 13 #include <linux/dnotify.h> 14 #include <linux/inotify.h> 14 15 #include <linux/fcntl.h> 15 16 #include <linux/quotaops.h> 16 17 #include <linux/security.h> … … 103 104 out: 104 105 return error; 105 106 } 106 107 107 EXPORT_SYMBOL(inode_setattr); 108 108 109 int setattr_mask(unsigned int ia_valid)109 void setattr_mask (unsigned int ia_valid, int *dn_mask, u32 *in_mask) 110 110 { 111 unsigned long dn_mask = 0; 111 int dnmask; 112 u32 inmask; 112 113 113 if (ia_valid & ATTR_UID) 114 dn_mask |= DN_ATTRIB; 115 if (ia_valid & ATTR_GID) 116 dn_mask |= DN_ATTRIB; 117 if (ia_valid & ATTR_SIZE) 118 dn_mask |= DN_MODIFY; 119 /* both times implies a utime(s) call */ 120 if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME)) 121 dn_mask |= DN_ATTRIB; 122 else if (ia_valid & ATTR_ATIME) 123 dn_mask |= DN_ACCESS; 124 else if (ia_valid & ATTR_MTIME) 125 dn_mask |= DN_MODIFY; 126 if (ia_valid & ATTR_MODE) 127 dn_mask |= DN_ATTRIB; 128 return dn_mask; 114 inmask = 0; 115 dnmask = 0; 116 117 if (!dn_mask || !in_mask) { 118 return; 119 } 120 if (ia_valid & ATTR_UID) { 121 inmask |= IN_ATTRIB; 122 dnmask |= DN_ATTRIB; 123 } 124 if (ia_valid & ATTR_GID) { 125 inmask |= IN_ATTRIB; 126 dnmask |= DN_ATTRIB; 127 } 128 if (ia_valid & ATTR_SIZE) { 129 inmask |= IN_MODIFY; 130 dnmask |= DN_MODIFY; 131 } 132 /* both times implies a utime(s) call */ 133 if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME)) { 134 inmask |= IN_ATTRIB; 135 dnmask |= DN_ATTRIB; 136 } 137 else if (ia_valid & ATTR_ATIME) { 138 inmask |= IN_ACCESS; 139 dnmask |= DN_ACCESS; 140 } 141 else if (ia_valid & ATTR_MTIME) { 142 inmask |= IN_MODIFY; 143 dnmask |= DN_MODIFY; 144 } 145 if (ia_valid & ATTR_MODE) { 146 inmask |= IN_ATTRIB; 147 dnmask |= DN_ATTRIB; 148 } 149 150 *in_mask = inmask; 151 *dn_mask = dnmask; 129 152 } 130 153 131 154 int notify_change(struct dentry * dentry, struct iattr * attr) … … 184 207 } 185 208 } 186 209 if (!error) { 187 unsigned long dn_mask = setattr_mask(ia_valid); 210 int dn_mask; 211 u32 in_mask; 212 213 setattr_mask (ia_valid, &dn_mask, &in_mask); 214 188 215 if (dn_mask) 189 216 dnotify_parent(dentry, dn_mask); 217 if (in_mask) { 218 inotify_inode_queue_event(dentry->d_inode, in_mask, 0, 219 NULL); 220 inotify_dentry_parent_queue_event(dentry, in_mask, 0, 221 dentry->d_name.name); 222 } 190 223 } 191 224 return error; 192 225 } -
fs/file_table.c
diff -urN linux-2.6.10/fs/file_table.c linux/fs/file_table.c
old new 16 16 #include <linux/eventpoll.h> 17 17 #include <linux/mount.h> 18 18 #include <linux/cdev.h> 19 #include <linux/inotify.h> 19 20 20 21 /* sysctl tunables... */ 21 22 struct files_stat_struct files_stat = { … … 120 121 struct dentry *dentry = file->f_dentry; 121 122 struct vfsmount *mnt = file->f_vfsmnt; 122 123 struct inode *inode = dentry->d_inode; 124 u32 mask; 125 126 127 mask = (file->f_mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE; 128 inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name); 129 inotify_inode_queue_event(inode, mask, 0, NULL); 123 130 124 131 might_sleep(); 125 132 /* -
fs/inode.c
diff -urN linux-2.6.10/fs/inode.c linux/fs/inode.c
old new 130 130 #ifdef CONFIG_QUOTA 131 131 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); 132 132 #endif 133 #ifdef CONFIG_INOTIFY 134 inode->inotify_data = NULL; 135 #endif 133 136 inode->i_pipe = NULL; 134 137 inode->i_bdev = NULL; 135 138 inode->i_cdev = NULL; -
fs/namei.c
diff -urN linux-2.6.10/fs/namei.c linux/fs/namei.c
old new 22 22 #include <linux/quotaops.h> 23 23 #include <linux/pagemap.h> 24 24 #include <linux/dnotify.h> 25 #include <linux/inotify.h> 25 26 #include <linux/smp_lock.h> 26 27 #include <linux/personality.h> 27 28 #include <linux/security.h> … … 1242 1243 error = dir->i_op->create(dir, dentry, mode, nd); 1243 1244 if (!error) { 1244 1245 inode_dir_notify(dir, DN_CREATE); 1246 inotify_inode_queue_event(dir, IN_CREATE_FILE, 1247 0, dentry->d_name.name); 1245 1248 security_inode_post_create(dir, dentry, mode); 1246 1249 } 1247 1250 return error; … … 1556 1559 error = dir->i_op->mknod(dir, dentry, mode, dev); 1557 1560 if (!error) { 1558 1561 inode_dir_notify(dir, DN_CREATE); 1562 inotify_inode_queue_event(dir, IN_CREATE_FILE, 0, 1563 dentry->d_name.name); 1559 1564 security_inode_post_mknod(dir, dentry, mode, dev); 1560 1565 } 1561 1566 return error; … … 1629 1634 error = dir->i_op->mkdir(dir, dentry, mode); 1630 1635 if (!error) { 1631 1636 inode_dir_notify(dir, DN_CREATE); 1637 inotify_inode_queue_event(dir, IN_CREATE_SUBDIR, 0, 1638 dentry->d_name.name); 1632 1639 security_inode_post_mkdir(dir,dentry, mode); 1633 1640 } 1634 1641 return error; … … 1724 1731 up(&dentry->d_inode->i_sem); 1725 1732 if (!error) { 1726 1733 inode_dir_notify(dir, DN_DELETE); 1734 inotify_inode_queue_event(dir, IN_DELETE_SUBDIR, 0, 1735 dentry->d_name.name); 1736 inotify_inode_queue_event(dentry->d_inode, IN_DELETE_SELF, 0, 1737 NULL); 1738 inotify_inode_is_dead (dentry->d_inode); 1727 1739 d_delete(dentry); 1728 1740 } 1729 1741 dput(dentry); … … 1796 1808 1797 1809 /* We don't d_delete() NFS sillyrenamed files--they still exist. */ 1798 1810 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { 1799 d_delete(dentry);1800 1811 inode_dir_notify(dir, DN_DELETE); 1812 inotify_inode_queue_event(dir, IN_DELETE_FILE, 0, 1813 dentry->d_name.name); 1814 inotify_inode_queue_event(dentry->d_inode, IN_DELETE_SELF, 0, 1815 NULL); 1816 inotify_inode_is_dead (dentry->d_inode); 1817 d_delete(dentry); 1801 1818 } 1802 1819 return error; 1803 1820 } … … 1873 1890 error = dir->i_op->symlink(dir, dentry, oldname); 1874 1891 if (!error) { 1875 1892 inode_dir_notify(dir, DN_CREATE); 1893 inotify_inode_queue_event(dir, IN_CREATE_FILE, 0, 1894 dentry->d_name.name); 1876 1895 security_inode_post_symlink(dir, dentry, oldname); 1877 1896 } 1878 1897 return error; … … 1946 1965 up(&old_dentry->d_inode->i_sem); 1947 1966 if (!error) { 1948 1967 inode_dir_notify(dir, DN_CREATE); 1968 inotify_inode_queue_event(dir, IN_CREATE_FILE, 0, 1969 new_dentry->d_name.name); 1949 1970 security_inode_post_link(old_dentry, dir, new_dentry); 1950 1971 } 1951 1972 return error; … … 2109 2130 { 2110 2131 int error; 2111 2132 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 2133 char *old_name; 2134 u32 cookie; 2112 2135 2113 2136 if (old_dentry->d_inode == new_dentry->d_inode) 2114 2137 return 0; … … 2130 2153 DQUOT_INIT(old_dir); 2131 2154 DQUOT_INIT(new_dir); 2132 2155 2156 old_name = inotify_oldname_init(old_dentry); 2157 2133 2158 if (is_dir) 2134 2159 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); 2135 2160 else … … 2141 2166 inode_dir_notify(old_dir, DN_DELETE); 2142 2167 inode_dir_notify(new_dir, DN_CREATE); 2143 2168 } 2169 2170 cookie = inotify_get_cookie(); 2171 2172 inotify_inode_queue_event(old_dir, IN_MOVED_FROM, cookie, 2173 old_name); 2174 inotify_inode_queue_event(new_dir, IN_MOVED_TO, cookie, 2175 old_dentry->d_name.name); 2144 2176 } 2177 inotify_oldname_free(old_name); 2178 2145 2179 return error; 2146 2180 } 2147 2181 -
fs/open.c
diff -urN linux-2.6.10/fs/open.c linux/fs/open.c
old new 11 11 #include <linux/smp_lock.h> 12 12 #include <linux/quotaops.h> 13 13 #include <linux/dnotify.h> 14 #include <linux/inotify.h> 14 15 #include <linux/module.h> 15 16 #include <linux/slab.h> 16 17 #include <linux/tty.h> … … 956 957 error = PTR_ERR(f); 957 958 if (IS_ERR(f)) 958 959 goto out_error; 960 inotify_inode_queue_event(f->f_dentry->d_inode, 961 IN_OPEN, 0, NULL); 962 inotify_dentry_parent_queue_event(f->f_dentry, IN_OPEN, 963 0, f->f_dentry->d_name.name); 959 964 fd_install(fd, f); 960 965 } 961 966 out: -
fs/read_write.c
diff -urN linux-2.6.10/fs/read_write.c linux/fs/read_write.c
old new 11 11 #include <linux/uio.h> 12 12 #include <linux/smp_lock.h> 13 13 #include <linux/dnotify.h> 14 #include <linux/inotify.h> 14 15 #include <linux/security.h> 15 16 #include <linux/module.h> 16 17 #include <linux/syscalls.h> … … 216 217 ret = file->f_op->read(file, buf, count, pos); 217 218 else 218 219 ret = do_sync_read(file, buf, count, pos); 219 if (ret > 0) 220 dnotify_parent(file->f_dentry, DN_ACCESS); 220 if (ret > 0) { 221 struct dentry *dentry = file->f_dentry; 222 dnotify_parent(dentry, DN_ACCESS); 223 inotify_dentry_parent_queue_event(dentry, 224 IN_ACCESS, 0, dentry->d_name.name); 225 inotify_inode_queue_event(inode, IN_ACCESS, 0, 226 NULL); 227 } 221 228 } 222 229 } 223 230 … … 260 267 ret = file->f_op->write(file, buf, count, pos); 261 268 else 262 269 ret = do_sync_write(file, buf, count, pos); 263 if (ret > 0) 264 dnotify_parent(file->f_dentry, DN_MODIFY); 270 if (ret > 0) { 271 struct dentry *dentry = file->f_dentry; 272 dnotify_parent(dentry, DN_MODIFY); 273 inotify_dentry_parent_queue_event(dentry, 274 IN_MODIFY, 0, dentry->d_name.name); 275 inotify_inode_queue_event(inode, IN_MODIFY, 0, 276 NULL); 277 } 265 278 } 266 279 } 267 280 … … 493 506 out: 494 507 if (iov != iovstack) 495 508 kfree(iov); 496 if ((ret + (type == READ)) > 0) 497 dnotify_parent(file->f_dentry, 498 (type == READ) ? DN_ACCESS : DN_MODIFY); 509 if ((ret + (type == READ)) > 0) { 510 struct dentry *dentry = file->f_dentry; 511 dnotify_parent(dentry, (type == READ) ? DN_ACCESS : DN_MODIFY); 512 inotify_dentry_parent_queue_event(dentry, 513 (type == READ) ? IN_ACCESS : IN_MODIFY, 0, 514 dentry->d_name.name); 515 inotify_inode_queue_event (dentry->d_inode, 516 (type == READ) ? IN_ACCESS : IN_MODIFY, 0, NULL); 517 } 499 518 return ret; 500 519 } 501 520 -
fs/super.c
diff -urN linux-2.6.10/fs/super.c linux/fs/super.c
old new 38 38 #include <linux/idr.h> 39 39 #include <linux/kobject.h> 40 40 #include <asm/uaccess.h> 41 #include <linux/inotify.h> 41 42 42 43 43 44 void get_filesystem(struct file_system_type *fs); … … 227 228 228 229 if (root) { 229 230 sb->s_root = NULL; 231 inotify_super_block_umount(sb); 230 232 shrink_dcache_parent(root); 231 233 shrink_dcache_anon(&sb->s_anon); 232 234 dput(root); -
include/linux/fs.h
diff -urN linux-2.6.10/include/linux/fs.h linux/include/linux/fs.h
old new 27 27 struct kstatfs; 28 28 struct vm_area_struct; 29 29 struct vfsmount; 30 struct inotify_inode_data; 30 31 31 32 /* 32 33 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change … … 473 474 struct dnotify_struct *i_dnotify; /* for directory notifications */ 474 475 #endif 475 476 477 #ifdef CONFIG_INOTIFY 478 struct inotify_inode_data *inotify_data; 479 #endif 480 476 481 unsigned long i_state; 477 482 unsigned long dirtied_when; /* jiffies of first dirtying */ 478 483 … … 1353 1358 extern int do_remount_sb(struct super_block *sb, int flags, 1354 1359 void *data, int force); 1355 1360 extern sector_t bmap(struct inode *, sector_t); 1356 extern int setattr_mask(unsigned int);1361 extern void setattr_mask(unsigned int, int *, u32 *); 1357 1362 extern int notify_change(struct dentry *, struct iattr *); 1358 1363 extern int permission(struct inode *, int, struct nameidata *); 1359 1364 extern int generic_permission(struct inode *, int, -
include/linux/inotify.h
diff -urN linux-2.6.10/include/linux/inotify.h linux/include/linux/inotify.h
old new 1 /* 2 * Inode based directory notification for Linux 3 * 4 * Copyright (C) 2004 John McCutchan 5 */ 6 7 #ifndef _LINUX_INOTIFY_H 8 #define _LINUX_INOTIFY_H 9 10 #include <linux/types.h> 11 #include <linux/limits.h> 12 13 /* this size could limit things, since technically we could need PATH_MAX */ 14 #define INOTIFY_FILENAME_MAX 256 15 16 /* 17 * struct inotify_event - structure read from the inotify device for each event 18 * 19 * When you are watching a directory, you will receive the filename for events 20 * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ... 21 * 22 * Note: When reading from the device you must provide a buffer that is a 23 * multiple of sizeof(struct inotify_event) 24 */ 25 struct inotify_event { 26 __s32 wd; 27 __u32 mask; 28 __u32 cookie; 29 size_t len; 30 #ifdef __KERNEL__ 31 char *filename; 32 #else 33 char filename[0]; 34 #endif 35 }; 36 37 /* 38 * struct inotify_watch_request - represents a watch request 39 * 40 * Pass to the inotify device via the INOTIFY_WATCH ioctl 41 */ 42 struct inotify_watch_request { 43 char *dirname; /* directory name */ 44 __u32 mask; /* event mask */ 45 }; 46 47 /* the following are legal, implemented events */ 48 #define IN_ACCESS 0x00000001 /* File was accessed */ 49 #define IN_MODIFY 0x00000002 /* File was modified */ 50 #define IN_ATTRIB 0x00000004 /* File changed attributes */ 51 #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ 52 #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ 53 #define IN_OPEN 0x00000020 /* File was opened */ 54 #define IN_MOVED_FROM 0x00000040 /* File was moved from X */ 55 #define IN_MOVED_TO 0x00000080 /* File was moved to Y */ 56 #define IN_DELETE_SUBDIR 0x00000100 /* Subdir was deleted */ 57 #define IN_DELETE_FILE 0x00000200 /* Subfile was deleted */ 58 #define IN_CREATE_SUBDIR 0x00000400 /* Subdir was created */ 59 #define IN_CREATE_FILE 0x00000800 /* Subfile was created */ 60 #define IN_DELETE_SELF 0x00001000 /* Self was deleted */ 61 #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ 62 #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 63 #define IN_IGNORED 0x00008000 /* File was ignored */ 64 65 /* special flags */ 66 #define IN_ALL_EVENTS 0xffffffff /* All the events */ 67 #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) 68 69 #define INOTIFY_IOCTL_MAGIC 'Q' 70 #define INOTIFY_IOCTL_MAXNR 2 71 72 #define INOTIFY_WATCH _IOR(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch_request) 73 #define INOTIFY_IGNORE _IOR(INOTIFY_IOCTL_MAGIC, 2, int) 74 75 #ifdef __KERNEL__ 76 77 #include <linux/dcache.h> 78 #include <linux/fs.h> 79 #include <linux/config.h> 80 81 struct inotify_inode_data { 82 struct list_head watches; 83 __u32 watch_mask; 84 spinlock_t lock; 85 atomic_t count; 86 }; 87 88 #ifdef CONFIG_INOTIFY 89 90 extern void inotify_inode_queue_event(struct inode *, __u32, __u32, 91 const char *); 92 extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32, 93 const char *); 94 extern void inotify_super_block_umount(struct super_block *); 95 extern void inotify_inode_is_dead(struct inode *); 96 extern __u32 inotify_get_cookie(void); 97 extern __u32 setattr_mask_inotify(unsigned int); 98 99 /* this could be kstrdup if only we could add that to lib/string.c */ 100 static inline char * inotify_oldname_init(struct dentry *old_dentry) 101 { 102 char *old_name; 103 104 old_name = kmalloc(strlen(old_dentry->d_name.name) + 1, GFP_KERNEL); 105 if (old_name) 106 strcpy(old_name, old_dentry->d_name.name); 107 return old_name; 108 } 109 110 static inline void inotify_oldname_free(const char *old_name) 111 { 112 kfree(old_name); 113 } 114 115 #else 116 117 static inline void inotify_inode_queue_event(struct inode *inode, 118 __u32 mask, __u32 cookie, 119 const char *filename) 120 { 121 } 122 123 static inline void inotify_dentry_parent_queue_event(struct dentry *dentry, 124 __u32 mask, __u32 cookie, 125 const char *filename) 126 { 127 } 128 129 static inline void inotify_super_block_umount(struct super_block *sb) 130 { 131 } 132 133 static inline void inotify_inode_is_dead(struct inode *inode) 134 { 135 } 136 137 static inline char * inotify_oldname_init(struct dentry *old_dentry) 138 { 139 return NULL; 140 } 141 142 static inline __u32 inotify_get_cookie(void) 143 { 144 return 0; 145 } 146 147 static inline void inotify_oldname_free(const char *old_name) 148 { 149 } 150 151 static inline int setattr_mask_inotify(unsigned int ia_mask) 152 { 153 return 0; 154 } 155 156 #endif /* CONFIG_INOTIFY */ 157 158 #endif /* __KERNEL __ */ 159 160 #endif /* _LINUX_INOTIFY_H */ -
include/linux/miscdevice.h
diff -urN linux-2.6.10/include/linux/miscdevice.h linux/include/linux/miscdevice.h
old new 2 2 #define _LINUX_MISCDEVICE_H 3 3 #include <linux/module.h> 4 4 #include <linux/major.h> 5 #include <linux/device.h> 5 6 6 7 #define PSMOUSE_MINOR 1 7 8 #define MS_BUSMOUSE_MINOR 2 … … 32 33 33 34 struct device; 34 35 35 struct miscdevice 36 { 36 struct miscdevice { 37 37 int minor; 38 38 const char *name; 39 39 struct file_operations *fops; 40 40 struct list_head list; 41 41 struct device *dev; 42 struct class_device *class; 42 43 char devfs_name[64]; 43 44 }; 44 45 -
include/linux/sched.h
diff -urN linux-2.6.10/include/linux/sched.h linux/include/linux/sched.h
old new 353 353 atomic_t processes; /* How many processes does this user have? */ 354 354 atomic_t files; /* How many open files does this user have? */ 355 355 atomic_t sigpending; /* How many pending signals does this user have? */ 356 atomic_t inotify_watches; /* How many inotify watches does this user have? */ 357 atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ 356 358 /* protected by mq_lock */ 357 359 unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ 358 360 unsigned long locked_shm; /* How many pages of mlocked shm ? */ -
kernel/user.c
diff -urN linux-2.6.10/kernel/user.c linux/kernel/user.c
old new 119 119 atomic_set(&new->processes, 0); 120 120 atomic_set(&new->files, 0); 121 121 atomic_set(&new->sigpending, 0); 122 atomic_set(&new->inotify_watches, 0); 123 atomic_set(&new->inotify_devs, 0); 122 124 123 125 new->mq_bytes = 0; 124 126 new->locked_shm = 0;
Note:
See TracBrowser
for help on using the repository browser.