source:
scripts/untested/blfs-patches/inotify-0.17-rml-2.6.10-2.patch@
8c8c5ab
Last change on this file since 8c8c5ab was 617118d, checked in by , 19 years ago | |
---|---|
|
|
File size: 45.2 KB |
-
drivers/char/inotify.c
inotify. Signed-off-by: Robert Love <rml@novell.com> drivers/char/Kconfig | 13 drivers/char/Makefile | 2 drivers/char/inotify.c | 1024 +++++++++++++++++++++++++++++++++++++++++++++ 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 | 155 ++++++ include/linux/miscdevice.h | 5 include/linux/sched.h | 2 kernel/user.c | 2 16 files changed, 1344 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 event_count; 63 unsigned int max_events; 64 struct user_struct *user; 65 }; 66 67 struct inotify_watch { 68 s32 wd; /* watch descriptor */ 69 u32 mask; 70 struct inode *inode; 71 struct inotify_device *dev; 72 struct list_head d_list; /* device list */ 73 struct list_head i_list; /* inode list */ 74 }; 75 76 static ssize_t show_max_queued_events(struct class_device *class, char *buf) 77 { 78 return sprintf(buf, "%d\n", sysfs_attrib_max_queued_events); 79 } 80 81 static ssize_t store_max_queued_events(struct class_device *class, 82 const char *buf, size_t count) 83 { 84 unsigned int max; 85 86 if (sscanf(buf, "%u", &max) > 0 && max > 0) { 87 sysfs_attrib_max_queued_events = max; 88 return strlen(buf); 89 } 90 return -EINVAL; 91 } 92 93 static ssize_t show_max_user_devices(struct class_device *class, char *buf) 94 { 95 return sprintf(buf, "%d\n", sysfs_attrib_max_user_devices); 96 } 97 98 static ssize_t store_max_user_devices(struct class_device *class, 99 const char *buf, size_t count) 100 { 101 int max; 102 103 if (sscanf(buf, "%d", &max) > 0 && max > 0) { 104 sysfs_attrib_max_user_devices = max; 105 return strlen(buf); 106 } 107 return -EINVAL; 108 } 109 110 static ssize_t show_max_user_watches(struct class_device *class, char *buf) 111 { 112 return sprintf(buf, "%d\n", sysfs_attrib_max_user_watches); 113 } 114 115 static ssize_t store_max_user_watches(struct class_device *class, 116 const char *buf, size_t count) 117 { 118 int max; 119 120 if (sscanf(buf, "%d", &max) > 0 && max > 0) { 121 sysfs_attrib_max_user_watches = max; 122 return strlen(buf); 123 } 124 return -EINVAL; 125 } 126 127 static CLASS_DEVICE_ATTR(max_queued_events, S_IRUGO | S_IWUSR, 128 show_max_queued_events, store_max_queued_events); 129 static CLASS_DEVICE_ATTR(max_user_devices, S_IRUGO | S_IWUSR, 130 show_max_user_devices, store_max_user_devices); 131 static CLASS_DEVICE_ATTR(max_user_watches, S_IRUGO | S_IWUSR, 132 show_max_user_watches, store_max_user_watches); 133 134 /* 135 * A list of these is attached to each instance of the driver 136 * when the drivers read() gets called, this list is walked and 137 * all events that can fit in the buffer get delivered 138 */ 139 struct inotify_kernel_event { 140 struct list_head list; 141 struct inotify_event event; 142 }; 143 144 static inline void __get_inode_data(struct inotify_inode_data *data) 145 { 146 atomic_inc(&data->count); 147 } 148 149 /* 150 * get_inode_data - pin an inotify_inode_data structure. Returns the structure 151 * if successful and NULL on failure, which can only occur if inotify_data is 152 * not yet allocated. The inode must be pinned prior to invocation. 153 */ 154 static inline struct inotify_inode_data * get_inode_data(struct inode *inode) 155 { 156 struct inotify_inode_data *data; 157 158 spin_lock(&inode->i_lock); 159 data = inode->inotify_data; 160 if (data) 161 __get_inode_data(data); 162 spin_unlock(&inode->i_lock); 163 164 return data; 165 } 166 167 /* 168 * put_inode_data - drop our reference on an inotify_inode_data and the 169 * inode structure in which it lives. If the reference count on inotify_data 170 * reaches zero, free it. 171 */ 172 static inline void put_inode_data(struct inode *inode) 173 { 174 //spin_lock(&inode->i_lock); 175 if (atomic_dec_and_test(&inode->inotify_data->count)) { 176 kmem_cache_free(inode_data_cachep, inode->inotify_data); 177 inode->inotify_data = NULL; 178 } 179 //spin_unlock(&inode->i_lock); 180 } 181 182 /* 183 * find_inode - resolve a user-given path to a specific inode and iget() it 184 */ 185 static struct inode * find_inode(const char __user *dirname) 186 { 187 struct inode *inode; 188 struct nameidata nd; 189 int error; 190 191 error = __user_walk(dirname, LOOKUP_FOLLOW, &nd); 192 if (error) 193 return ERR_PTR(error); 194 195 inode = nd.dentry->d_inode; 196 197 /* you can only watch an inode if you have read permissions on it */ 198 error = permission(inode, MAY_READ, NULL); 199 if (error) { 200 inode = ERR_PTR(error); 201 goto release_and_out; 202 } 203 204 spin_lock(&inode_lock); 205 __iget(inode); 206 spin_unlock(&inode_lock); 207 release_and_out: 208 path_release(&nd); 209 return inode; 210 } 211 212 struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie, 213 const char *filename) 214 { 215 struct inotify_kernel_event *kevent; 216 217 kevent = kmem_cache_alloc(event_cachep, GFP_ATOMIC); 218 if (!kevent) 219 return NULL; 220 221 /* we hand this out to user-space, so zero it out just in case */ 222 memset(kevent, 0, sizeof(struct inotify_kernel_event)); 223 224 kevent->event.wd = wd; 225 kevent->event.mask = mask; 226 kevent->event.cookie = cookie; 227 INIT_LIST_HEAD(&kevent->list); 228 229 if (filename) { 230 strncpy(kevent->event.filename, filename, INOTIFY_FILENAME_MAX); 231 kevent->event.filename[INOTIFY_FILENAME_MAX-1] = '\0'; 232 } else 233 kevent->event.filename[0] = '\0'; 234 235 return kevent; 236 } 237 238 void delete_kernel_event(struct inotify_kernel_event *kevent) 239 { 240 if (!kevent) 241 return; 242 kmem_cache_free(event_cachep, kevent); 243 } 244 245 #define list_to_inotify_kernel_event(pos) \ 246 list_entry((pos), struct inotify_kernel_event, list) 247 248 #define inotify_dev_get_event(dev) \ 249 (list_to_inotify_kernel_event(dev->events.next)) 250 251 /* Does this events mask get sent to the watch ? */ 252 #define event_and(event_mask,watches_mask) ((event_mask == IN_UNMOUNT) || \ 253 (event_mask == IN_IGNORED) || \ 254 (event_mask & watches_mask)) 255 256 /* 257 * inotify_dev_queue_event - add a new event to the given device 258 * 259 * Caller must hold dev->lock. 260 */ 261 static void inotify_dev_queue_event(struct inotify_device *dev, 262 struct inotify_watch *watch, u32 mask, 263 u32 cookie, const char *filename) 264 { 265 struct inotify_kernel_event *kevent, *last; 266 267 /* Check if the new event is a duplicate of the last event queued. */ 268 last = inotify_dev_get_event(dev); 269 if (dev->event_count && last->event.mask == mask && 270 last->event.wd == watch->wd) { 271 /* Check if the filenames match */ 272 if (!filename && last->event.filename[0] == '\0') 273 return; 274 if (filename && !strcmp(last->event.filename, filename)) 275 return; 276 } 277 278 /* 279 * the queue has already overflowed and we have already sent the 280 * Q_OVERFLOW event 281 */ 282 if (dev->event_count > dev->max_events) 283 return; 284 285 /* the queue has just overflowed and we need to notify user space */ 286 if (dev->event_count == dev->max_events) { 287 kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL); 288 goto add_event_to_queue; 289 } 290 291 if (!event_and(mask, watch->inode->inotify_data->watch_mask) || 292 !event_and(mask, watch->mask)) 293 return; 294 295 kevent = kernel_event(watch->wd, mask, cookie, filename); 296 297 add_event_to_queue: 298 if (!kevent) 299 return; 300 301 /* queue the event and wake up anyone waiting */ 302 dev->event_count++; 303 list_add_tail(&kevent->list, &dev->events); 304 wake_up_interruptible(&dev->wait); 305 } 306 307 static inline int inotify_dev_has_events(struct inotify_device *dev) 308 { 309 return !list_empty(&dev->events); 310 } 311 312 /* 313 * inotify_dev_event_dequeue - destroy an event on the given device 314 * 315 * Caller must hold dev->lock. 316 */ 317 static void inotify_dev_event_dequeue(struct inotify_device *dev) 318 { 319 struct inotify_kernel_event *kevent; 320 321 if (!inotify_dev_has_events(dev)) 322 return; 323 324 kevent = inotify_dev_get_event(dev); 325 list_del_init(&kevent->list); 326 dev->event_count--; 327 delete_kernel_event(kevent); 328 } 329 330 /* 331 * inotify_dev_get_wd - returns the next WD for use by the given dev 332 * 333 * This function can sleep. 334 */ 335 static int inotify_dev_get_wd(struct inotify_device *dev, 336 struct inotify_watch *watch) 337 { 338 int ret; 339 340 if (atomic_read(&dev->user->inotify_watches) >= 341 sysfs_attrib_max_user_watches) 342 return -ENOSPC; 343 344 repeat: 345 if (!idr_pre_get(&dev->idr, GFP_KERNEL)) 346 return -ENOSPC; 347 spin_lock(&dev->lock); 348 ret = idr_get_new(&dev->idr, watch, &watch->wd); 349 spin_unlock(&dev->lock); 350 if (ret == -EAGAIN) /* more memory is required, try again */ 351 goto repeat; 352 else if (ret) /* the idr is full! */ 353 return -ENOSPC; 354 355 atomic_inc(&dev->user->inotify_watches); 356 357 return 0; 358 } 359 360 /* 361 * inotify_dev_put_wd - release the given WD on the given device 362 * 363 * Caller must hold dev->lock. 364 */ 365 static int inotify_dev_put_wd(struct inotify_device *dev, s32 wd) 366 { 367 if (!dev || wd < 0) 368 return -1; 369 370 atomic_dec(&dev->user->inotify_watches); 371 idr_remove(&dev->idr, wd); 372 373 return 0; 374 } 375 376 /* 377 * create_watch - creates a watch on the given device. 378 * 379 * Grabs dev->lock, so the caller must not hold it. 380 */ 381 static struct inotify_watch *create_watch(struct inotify_device *dev, 382 u32 mask, struct inode *inode) 383 { 384 struct inotify_watch *watch; 385 386 watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL); 387 if (!watch) 388 return NULL; 389 390 watch->mask = mask; 391 watch->inode = inode; 392 watch->dev = dev; 393 INIT_LIST_HEAD(&watch->d_list); 394 INIT_LIST_HEAD(&watch->i_list); 395 396 if (inotify_dev_get_wd(dev, watch)) { 397 kmem_cache_free(watch_cachep, watch); 398 return NULL; 399 } 400 401 return watch; 402 } 403 404 /* 405 * delete_watch - removes the given 'watch' from the given 'dev' 406 * 407 * Caller must hold dev->lock. 408 */ 409 static void delete_watch(struct inotify_device *dev, 410 struct inotify_watch *watch) 411 { 412 inotify_dev_put_wd(dev, watch->wd); 413 kmem_cache_free(watch_cachep, watch); 414 } 415 416 /* 417 * inotify_find_dev - find the watch associated with the given inode and dev 418 * 419 * Caller must hold dev->lock. 420 * FIXME: Needs inotify_data->lock too. Don't need dev->lock, just pin it. 421 */ 422 static struct inotify_watch *inode_find_dev(struct inode *inode, 423 struct inotify_device *dev) 424 { 425 struct inotify_watch *watch; 426 427 if (!inode->inotify_data) 428 return NULL; 429 430 list_for_each_entry(watch, &inode->inotify_data->watches, i_list) { 431 if (watch->dev == dev) 432 return watch; 433 } 434 435 return NULL; 436 } 437 438 /* 439 * dev_find_wd - given a (dev,wd) pair, returns the matching inotify_watcher 440 * 441 * Returns the results of looking up (dev,wd) in the idr layer. NULL is 442 * returned on error. 443 * 444 * The caller must hold dev->lock. 445 */ 446 static inline struct inotify_watch *dev_find_wd(struct inotify_device *dev, 447 u32 wd) 448 { 449 return idr_find(&dev->idr, wd); 450 } 451 452 static int inotify_dev_is_watching_inode(struct inotify_device *dev, 453 struct inode *inode) 454 { 455 struct inotify_watch *watch; 456 457 list_for_each_entry(watch, &dev->watches, d_list) { 458 if (watch->inode == inode) 459 return 1; 460 } 461 462 return 0; 463 } 464 465 /* 466 * inotify_dev_add_watcher - add the given watcher to the given device instance 467 * 468 * Caller must hold dev->lock. 469 */ 470 static int inotify_dev_add_watch(struct inotify_device *dev, 471 struct inotify_watch *watch) 472 { 473 if (!dev || !watch) 474 return -EINVAL; 475 476 list_add(&watch->d_list, &dev->watches); 477 return 0; 478 } 479 480 /* 481 * inotify_dev_rm_watch - remove the given watch from the given device 482 * 483 * Caller must hold dev->lock because we call inotify_dev_queue_event(). 484 */ 485 static int inotify_dev_rm_watch(struct inotify_device *dev, 486 struct inotify_watch *watch) 487 { 488 if (!watch) 489 return -EINVAL; 490 491 inotify_dev_queue_event(dev, watch, IN_IGNORED, 0, NULL); 492 list_del_init(&watch->d_list); 493 494 return 0; 495 } 496 497 /* 498 * inode_update_watch_mask - update inode->inotify_data->watch_mask 499 * 500 * Grabs inode->inotify_data->lock. 501 */ 502 static void inode_update_watch_mask(struct inode *inode) 503 { 504 struct inotify_inode_data *data; 505 struct inotify_watch *watch; 506 u32 new_mask; 507 508 data = get_inode_data(inode); 509 if (!data) /* FIXME: this should never happen */ 510 return; 511 spin_lock(&data->lock); 512 513 new_mask = 0; 514 list_for_each_entry(watch, &data->watches, i_list) 515 new_mask |= watch->mask; 516 517 data->watch_mask = new_mask; 518 519 spin_unlock(&data->lock); 520 put_inode_data(inode); 521 } 522 523 /* 524 * inode_add_watch - add a watch to the given inode 525 * 526 * Callers must hold dev->lock, because we call inode_find_dev(). 527 */ 528 static int inode_add_watch(struct inode *inode, struct inotify_watch *watch) 529 { 530 int ret; 531 532 if (!inode || !watch) 533 return -EINVAL; 534 535 spin_lock(&inode->i_lock); 536 if (!inode->inotify_data) { 537 /* inotify_data is not attached to the inode, so add it */ 538 inode->inotify_data = kmem_cache_alloc(inode_data_cachep, 539 GFP_ATOMIC); 540 if (!inode->inotify_data) { 541 ret = -ENOMEM; 542 goto out_lock; 543 } 544 545 atomic_set(&inode->inotify_data->count, 0); 546 INIT_LIST_HEAD(&inode->inotify_data->watches); 547 inode->inotify_data->watch_mask = 0; 548 spin_lock_init(&inode->inotify_data->lock); 549 } else if (inode_find_dev(inode, watch->dev)) { 550 /* a watch is already associated with this (inode,dev) pair */ 551 ret = -EINVAL; 552 goto out_lock; 553 } 554 __get_inode_data(inode->inotify_data); 555 spin_unlock(&inode->i_lock); 556 557 list_add(&watch->i_list, &inode->inotify_data->watches); 558 inode_update_watch_mask(inode); 559 560 return 0; 561 out_lock: 562 spin_unlock(&inode->i_lock); 563 return ret; 564 } 565 566 static int inode_rm_watch(struct inode *inode, 567 struct inotify_watch *watch) 568 { 569 if (!inode || !watch || !inode->inotify_data) 570 return -EINVAL; 571 572 list_del_init(&watch->i_list); 573 inode_update_watch_mask(inode); 574 575 /* clean up inode->inotify_data */ 576 put_inode_data(inode); 577 578 return 0; 579 } 580 581 /* Kernel API */ 582 583 /* 584 * inotify_inode_queue_event - queue an event with the given mask, cookie, and 585 * filename to any watches associated with the given inode. 586 * 587 * inode must be pinned prior to calling. 588 */ 589 void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie, 590 const char *filename) 591 { 592 struct inotify_watch *watch; 593 594 if (!inode->inotify_data) 595 return; 596 597 list_for_each_entry(watch, &inode->inotify_data->watches, i_list) { 598 spin_lock(&watch->dev->lock); 599 inotify_dev_queue_event(watch->dev, watch, mask, cookie, 600 filename); 601 spin_unlock(&watch->dev->lock); 602 } 603 } 604 EXPORT_SYMBOL_GPL(inotify_inode_queue_event); 605 606 void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask, 607 u32 cookie, const char *filename) 608 { 609 struct dentry *parent; 610 611 parent = dget_parent(dentry); 612 inotify_inode_queue_event(parent->d_inode, mask, cookie, filename); 613 dput(parent); 614 } 615 EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event); 616 617 u32 inotify_get_cookie(void) 618 { 619 atomic_inc(&inotify_cookie); 620 return atomic_read(&inotify_cookie); 621 } 622 EXPORT_SYMBOL_GPL(inotify_get_cookie); 623 624 /* 625 * watch->inode must be pinned. We drop a reference before returning. 626 */ 627 static void ignore_helper(struct inotify_watch *watch, int event) 628 { 629 struct inotify_device *dev; 630 struct inode *inode; 631 632 inode = watch->inode; 633 dev = watch->dev; 634 635 spin_lock(&dev->lock); 636 637 if (event) 638 inotify_dev_queue_event(dev, watch, event, 0, NULL); 639 640 inode_rm_watch(inode, watch); 641 inotify_dev_rm_watch(watch->dev, watch); 642 643 delete_watch(dev, watch); 644 spin_unlock(&dev->lock); 645 646 iput(inode); 647 } 648 649 void inotify_super_block_umount(struct super_block *sb) 650 { 651 struct inode *inode; 652 653 spin_lock(&inode_lock); 654 655 /* 656 * We hold the inode_lock, so the inodes are not going anywhere, and 657 * we grab a reference on inotify_data before walking its list of 658 * watches. 659 */ 660 list_for_each_entry(inode, &inode_in_use, i_list) { 661 struct inotify_inode_data *inode_data; 662 struct inotify_watch *watch; 663 664 if (inode->i_sb != sb) 665 continue; 666 667 inode_data = get_inode_data(inode); 668 if (!inode_data) 669 continue; 670 671 list_for_each_entry(watch, &inode_data->watches, i_list) 672 ignore_helper(watch, IN_UNMOUNT); 673 put_inode_data(inode); 674 } 675 676 spin_unlock(&inode_lock); 677 } 678 EXPORT_SYMBOL_GPL(inotify_super_block_umount); 679 680 /* 681 * inotify_inode_is_dead - an inode has been deleted, cleanup any watches 682 */ 683 void inotify_inode_is_dead(struct inode *inode) 684 { 685 struct inotify_watch *watch, *next; 686 struct inotify_inode_data *data; 687 688 data = get_inode_data(inode); 689 if (!data) 690 return; 691 list_for_each_entry_safe(watch, next, &data->watches, i_list) 692 ignore_helper(watch, 0); 693 put_inode_data(inode); 694 } 695 EXPORT_SYMBOL_GPL(inotify_inode_is_dead); 696 697 /* The driver interface is implemented below */ 698 699 static unsigned int inotify_poll(struct file *file, poll_table *wait) 700 { 701 struct inotify_device *dev; 702 703 dev = file->private_data; 704 705 poll_wait(file, &dev->wait, wait); 706 707 if (inotify_dev_has_events(dev)) 708 return POLLIN | POLLRDNORM; 709 710 return 0; 711 } 712 713 static ssize_t inotify_read(struct file *file, char __user *buf, 714 size_t count, loff_t *pos) 715 { 716 size_t event_size; 717 struct inotify_device *dev; 718 char __user *start; 719 DECLARE_WAITQUEUE(wait, current); 720 721 start = buf; 722 dev = file->private_data; 723 724 /* We only hand out full inotify events */ 725 event_size = sizeof(struct inotify_event); 726 if (count < event_size) 727 return -EINVAL; 728 729 while (1) { 730 int has_events; 731 732 spin_lock(&dev->lock); 733 has_events = inotify_dev_has_events(dev); 734 spin_unlock(&dev->lock); 735 if (has_events) 736 break; 737 738 if (file->f_flags & O_NONBLOCK) 739 return -EAGAIN; 740 741 if (signal_pending(current)) 742 return -ERESTARTSYS; 743 744 add_wait_queue(&dev->wait, &wait); 745 set_current_state(TASK_INTERRUPTIBLE); 746 747 schedule(); 748 749 set_current_state(TASK_RUNNING); 750 remove_wait_queue(&dev->wait, &wait); 751 } 752 753 while (count >= event_size) { 754 struct inotify_kernel_event *kevent; 755 756 spin_lock(&dev->lock); 757 if (!inotify_dev_has_events(dev)) { 758 spin_unlock(&dev->lock); 759 break; 760 } 761 kevent = inotify_dev_get_event(dev); 762 spin_unlock(&dev->lock); 763 if (copy_to_user(buf, &kevent->event, event_size)) 764 return -EFAULT; 765 766 spin_lock(&dev->lock); 767 inotify_dev_event_dequeue(dev); 768 spin_unlock(&dev->lock); 769 count -= event_size; 770 buf += event_size; 771 } 772 773 return buf - start; 774 } 775 776 static int inotify_open(struct inode *inode, struct file *file) 777 { 778 struct inotify_device *dev; 779 struct user_struct *user; 780 int ret; 781 782 user = get_uid(current->user); 783 784 if (atomic_read(&user->inotify_devs) >= sysfs_attrib_max_user_devices) { 785 ret = -ENOSPC; 786 goto out_err; 787 } 788 789 atomic_inc(¤t->user->inotify_devs); 790 791 dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL); 792 if (!dev) { 793 ret = -ENOMEM; 794 goto out_err; 795 } 796 797 idr_init(&dev->idr); 798 799 INIT_LIST_HEAD(&dev->events); 800 INIT_LIST_HEAD(&dev->watches); 801 init_waitqueue_head(&dev->wait); 802 803 dev->event_count = 0; 804 dev->max_events = sysfs_attrib_max_queued_events; 805 dev->user = user; 806 spin_lock_init(&dev->lock); 807 808 file->private_data = dev; 809 810 return 0; 811 out_err: 812 free_uid(current->user); 813 return ret; 814 } 815 816 /* 817 * inotify_release_all_watches - destroy all watches on a given device 818 * 819 * FIXME: Do we want a lock here? 820 */ 821 static void inotify_release_all_watches(struct inotify_device *dev) 822 { 823 struct inotify_watch *watch, *next; 824 825 list_for_each_entry_safe(watch, next, &dev->watches, d_list) 826 ignore_helper(watch, 0); 827 } 828 829 /* 830 * inotify_release_all_events - destroy all of the events on a given device 831 */ 832 static void inotify_release_all_events(struct inotify_device *dev) 833 { 834 spin_lock(&dev->lock); 835 while (inotify_dev_has_events(dev)) 836 inotify_dev_event_dequeue(dev); 837 spin_unlock(&dev->lock); 838 } 839 840 static int inotify_release(struct inode *inode, struct file *file) 841 { 842 struct inotify_device *dev; 843 844 dev = file->private_data; 845 846 inotify_release_all_watches(dev); 847 inotify_release_all_events(dev); 848 849 atomic_dec(&dev->user->inotify_devs); 850 free_uid(dev->user); 851 852 kfree(dev); 853 854 return 0; 855 } 856 857 static int inotify_add_watch(struct inotify_device *dev, 858 struct inotify_watch_request *request) 859 { 860 struct inode *inode; 861 struct inotify_watch *watch; 862 int ret; 863 864 inode = find_inode((const char __user*) request->dirname); 865 if (IS_ERR(inode)) 866 return PTR_ERR(inode); 867 868 spin_lock(&dev->lock); 869 870 /* 871 * This handles the case of re-adding a directory we are already 872 * watching, we just update the mask and return 0 873 */ 874 if (inotify_dev_is_watching_inode(dev, inode)) { 875 struct inotify_watch *owatch; /* the old watch */ 876 877 owatch = inode_find_dev(inode, dev); 878 owatch->mask = request->mask; 879 inode_update_watch_mask(inode); 880 spin_unlock(&dev->lock); 881 iput(inode); 882 883 return owatch->wd; 884 } 885 886 spin_unlock(&dev->lock); 887 888 watch = create_watch(dev, request->mask, inode); 889 if (!watch) { 890 iput(inode); 891 return -ENOSPC; 892 } 893 894 spin_lock(&dev->lock); 895 896 /* We can't add anymore watches to this device */ 897 if (inotify_dev_add_watch(dev, watch)) { 898 delete_watch(dev, watch); 899 spin_unlock(&dev->lock); 900 iput(inode); 901 return -EINVAL; 902 } 903 904 ret = inode_add_watch(inode, watch); 905 if (ret < 0) { 906 list_del_init(&watch->d_list); 907 delete_watch(dev, watch); 908 spin_unlock(&dev->lock); 909 iput(inode); 910 return ret; 911 } 912 913 spin_unlock(&dev->lock); 914 915 return watch->wd; 916 } 917 918 static int inotify_ignore(struct inotify_device *dev, s32 wd) 919 { 920 struct inotify_watch *watch; 921 922 /* 923 * FIXME: Silly to grab dev->lock here and then drop it, when 924 * ignore_helper() grabs it anyway a few lines down. 925 */ 926 spin_lock(&dev->lock); 927 watch = dev_find_wd(dev, wd); 928 spin_unlock(&dev->lock); 929 if (!watch) 930 return -EINVAL; 931 ignore_helper(watch, 0); 932 933 return 0; 934 } 935 936 /* 937 * inotify_ioctl() - our device file's ioctl method 938 * 939 * The VFS serializes all of our calls via the BKL and we rely on that. We 940 * could, alternatively, grab dev->lock. Right now lower levels grab that 941 * where needed. 942 */ 943 static int inotify_ioctl(struct inode *ip, struct file *fp, 944 unsigned int cmd, unsigned long arg) 945 { 946 struct inotify_device *dev; 947 struct inotify_watch_request request; 948 void __user *p; 949 int bytes; 950 s32 wd; 951 952 dev = fp->private_data; 953 p = (void __user *) arg; 954 955 switch (cmd) { 956 case INOTIFY_WATCH: 957 if (copy_from_user(&request, p, sizeof (request))) 958 return -EFAULT; 959 return inotify_add_watch(dev, &request); 960 case INOTIFY_IGNORE: 961 if (copy_from_user(&wd, p, sizeof (wd))) 962 return -EFAULT; 963 return inotify_ignore(dev, wd); 964 case FIONREAD: 965 bytes = dev->event_count * sizeof(struct inotify_event); 966 return put_user(bytes, (int __user *) p); 967 default: 968 return -ENOTTY; 969 } 970 } 971 972 static struct file_operations inotify_fops = { 973 .owner = THIS_MODULE, 974 .poll = inotify_poll, 975 .read = inotify_read, 976 .open = inotify_open, 977 .release = inotify_release, 978 .ioctl = inotify_ioctl, 979 }; 980 981 struct miscdevice inotify_device = { 982 .minor = MISC_DYNAMIC_MINOR, 983 .name = "inotify", 984 .fops = &inotify_fops, 985 }; 986 987 static int __init inotify_init(void) 988 { 989 struct class_device *class; 990 int ret; 991 992 ret = misc_register(&inotify_device); 993 if (ret) 994 return ret; 995 996 sysfs_attrib_max_queued_events = 512; 997 sysfs_attrib_max_user_devices = 64; 998 sysfs_attrib_max_user_watches = 16384; 999 1000 class = inotify_device.class; 1001 class_device_create_file(class, &class_device_attr_max_queued_events); 1002 class_device_create_file(class, &class_device_attr_max_user_devices); 1003 class_device_create_file(class, &class_device_attr_max_user_watches); 1004 1005 atomic_set(&inotify_cookie, 0); 1006 1007 watch_cachep = kmem_cache_create("inotify_watch_cache", 1008 sizeof(struct inotify_watch), 0, SLAB_PANIC, 1009 NULL, NULL); 1010 1011 event_cachep = kmem_cache_create("inotify_event_cache", 1012 sizeof(struct inotify_kernel_event), 0, 1013 SLAB_PANIC, NULL, NULL); 1014 1015 inode_data_cachep = kmem_cache_create("inotify_inode_data_cache", 1016 sizeof(struct inotify_inode_data), 0, SLAB_PANIC, 1017 NULL, NULL); 1018 1019 printk(KERN_INFO "inotify device minor=%d\n", inotify_device.minor); 1020 1021 return 0; 1022 } 1023 1024 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 char filename[INOTIFY_FILENAME_MAX]; 30 }; 31 32 /* 33 * struct inotify_watch_request - represents a watch request 34 * 35 * Pass to the inotify device via the INOTIFY_WATCH ioctl 36 */ 37 struct inotify_watch_request { 38 char *dirname; /* directory name */ 39 __u32 mask; /* event mask */ 40 }; 41 42 /* the following are legal, implemented events */ 43 #define IN_ACCESS 0x00000001 /* File was accessed */ 44 #define IN_MODIFY 0x00000002 /* File was modified */ 45 #define IN_ATTRIB 0x00000004 /* File changed attributes */ 46 #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ 47 #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ 48 #define IN_OPEN 0x00000020 /* File was opened */ 49 #define IN_MOVED_FROM 0x00000040 /* File was moved from X */ 50 #define IN_MOVED_TO 0x00000080 /* File was moved to Y */ 51 #define IN_DELETE_SUBDIR 0x00000100 /* Subdir was deleted */ 52 #define IN_DELETE_FILE 0x00000200 /* Subfile was deleted */ 53 #define IN_CREATE_SUBDIR 0x00000400 /* Subdir was created */ 54 #define IN_CREATE_FILE 0x00000800 /* Subfile was created */ 55 #define IN_DELETE_SELF 0x00001000 /* Self was deleted */ 56 #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ 57 #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 58 #define IN_IGNORED 0x00008000 /* File was ignored */ 59 60 /* special flags */ 61 #define IN_ALL_EVENTS 0xffffffff /* All the events */ 62 #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) 63 64 #define INOTIFY_IOCTL_MAGIC 'Q' 65 #define INOTIFY_IOCTL_MAXNR 2 66 67 #define INOTIFY_WATCH _IOR(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch_request) 68 #define INOTIFY_IGNORE _IOR(INOTIFY_IOCTL_MAGIC, 2, int) 69 70 #ifdef __KERNEL__ 71 72 #include <linux/dcache.h> 73 #include <linux/fs.h> 74 #include <linux/config.h> 75 76 struct inotify_inode_data { 77 struct list_head watches; 78 __u32 watch_mask; 79 spinlock_t lock; 80 atomic_t count; 81 }; 82 83 #ifdef CONFIG_INOTIFY 84 85 extern void inotify_inode_queue_event(struct inode *, __u32, __u32, 86 const char *); 87 extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32, 88 const char *); 89 extern void inotify_super_block_umount(struct super_block *); 90 extern void inotify_inode_is_dead(struct inode *); 91 extern __u32 inotify_get_cookie(void); 92 extern __u32 setattr_mask_inotify(unsigned int); 93 94 /* this could be kstrdup if only we could add that to lib/string.c */ 95 static inline char * inotify_oldname_init(struct dentry *old_dentry) 96 { 97 char *old_name; 98 99 old_name = kmalloc(strlen(old_dentry->d_name.name) + 1, GFP_KERNEL); 100 if (old_name) 101 strcpy(old_name, old_dentry->d_name.name); 102 return old_name; 103 } 104 105 static inline void inotify_oldname_free(const char *old_name) 106 { 107 kfree(old_name); 108 } 109 110 #else 111 112 static inline void inotify_inode_queue_event(struct inode *inode, 113 __u32 mask, __u32 cookie, 114 const char *filename) 115 { 116 } 117 118 static inline void inotify_dentry_parent_queue_event(struct dentry *dentry, 119 __u32 mask, __u32 cookie, 120 const char *filename) 121 { 122 } 123 124 static inline void inotify_super_block_umount(struct super_block *sb) 125 { 126 } 127 128 static inline void inotify_inode_is_dead(struct inode *inode) 129 { 130 } 131 132 static inline char * inotify_oldname_init(struct dentry *old_dentry) 133 { 134 return NULL; 135 } 136 137 static inline __u32 inotify_get_cookie(void) 138 { 139 return 0; 140 } 141 142 static inline void inotify_oldname_free(const char *old_name) 143 { 144 } 145 146 static inline int setattr_mask_inotify(unsigned int ia_mask) 147 { 148 return 0; 149 } 150 151 #endif /* CONFIG_INOTIFY */ 152 153 #endif /* __KERNEL __ */ 154 155 #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.