Pull more vfs updates from Al Viro: "Assorted VFS fixes and related cleanups (IMO the most interesting in that part are f_path-related things and Eric's descriptor-related stuff). UFS regression fixes (it got broken last cycle). 9P fixes. fs-cache series, DAX patches, Jan's file_remove_suid() work" [ I'd say this is much more than "fixes and related cleanups". The file_table locking rule change by Eric Dumazet is a rather big and fundamental update even if the patch isn't huge. - Linus ] * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (49 commits) 9p: cope with bogus responses from server in p9_client_{read,write} p9_client_write(): avoid double p9_free_req() 9p: forgetting to cancel request on interrupted zero-copy RPC dax: bdev_direct_access() may sleep block: Add support for DAX reads/writes to block devices dax: Use copy_from_iter_nocache dax: Add block size note to documentation fs/file.c: __fget() and dup2() atomicity rules fs/file.c: don't acquire files->file_lock in fd_install() fs:super:get_anon_bdev: fix race condition could cause dev exceed its upper limitation vfs: avoid creation of inode number 0 in get_next_ino namei: make set_root_rcu() return void make simple_positive() public ufs: use dir_pages instead of ufs_dir_pages() pagemap.h: move dir_pages() over there remove the pointless include of lglock.h fs: cleanup slight list_entry abuse xfs: Correctly lock inode when removing suid and file capabilities fs: Call security_ops->inode_killpriv on truncate fs: Provide function telling whether file_remove_privs() will do anything ...
Unified · Split
| @@ -676,6 +676,29 @@ FS-Cache provides some utilities that a cache backend may make use of: · 675 unmodified lines | ||
| 676 | 676 | as possible. |
| 677 | 677 | |
| 678 | 678 | |
| 679 | + (*) Indicate that a stale object was found and discarded: | |
| 680 | + | |
| 681 | + void fscache_object_retrying_stale(struct fscache_object *object); | |
| 682 | + | |
| 683 | + This is called to indicate that the lookup procedure found an object in | |
| 684 | + the cache that the netfs decided was stale. The object has been | |
| 685 | + discarded from the cache and the lookup will be performed again. | |
| 686 | + | |
| 687 | + | |
| 688 | + (*) Indicate that the caching backend killed an object: | |
| 689 | + | |
| 690 | + void fscache_object_mark_killed(struct fscache_object *object, | |
| 691 | + enum fscache_why_object_killed why); | |
| 692 | + | |
| 693 | + This is called to indicate that the cache backend preemptively killed an | |
| 694 | + object. The why parameter should be set to indicate the reason: | |
| 695 | + | |
| 696 | + FSCACHE_OBJECT_IS_STALE - the object was stale and needs discarding. | |
| 697 | + FSCACHE_OBJECT_NO_SPACE - there was insufficient cache space | |
| 698 | + FSCACHE_OBJECT_WAS_RETIRED - the object was retired when relinquished. | |
| 699 | + FSCACHE_OBJECT_WAS_CULLED - the object was culled to make space. | |
| 700 | + | |
| 701 | + | |
| 679 | 702 | (*) Get and release references on a retrieval record: |
| 680 | 703 | |
| 681 | 704 | void fscache_get_retrieval(struct fscache_retrieval *op); |
| @@ -284,8 +284,9 @@ proc files. · 283 unmodified lines | ||
| 284 | 284 | enq=N Number of times async ops queued for processing |
| 285 | 285 | can=N Number of async ops cancelled |
| 286 | 286 | rej=N Number of async ops rejected due to object lookup/create failure |
| 287 | + ini=N Number of async ops initialised | |
| 287 | 288 | dfr=N Number of async ops queued for deferred release |
| 288 | − rel=N Number of async ops released | |
| 289 | + rel=N Number of async ops released (should equal ini=N when idle) | |
| 289 | 290 | gc=N Number of deferred-release async ops garbage collected |
| 290 | 291 | CacheOp alo=N Number of in-progress alloc_object() cache ops |
| 291 | 292 | luo=N Number of in-progress lookup_object() cache ops |
| @@ -303,6 +304,10 @@ proc files. · 11 unmodified lines | ||
| 303 | 304 | wrp=N Number of in-progress write_page() cache ops |
| 304 | 305 | ucp=N Number of in-progress uncache_page() cache ops |
| 305 | 306 | dsp=N Number of in-progress dissociate_pages() cache ops |
| 307 | + CacheEv nsp=N Number of object lookups/creations rejected due to lack of space | |
| 308 | + stl=N Number of stale objects deleted | |
| 309 | + rtr=N Number of objects retired when relinquished | |
| 310 | + cul=N Number of objects culled | |
| 306 | 311 | |
| 307 | 312 | |
| 308 | 313 | (*) /proc/fs/fscache/histogram |
| @@ -18,8 +18,10 @@ Usage · 17 unmodified lines | ||
| 18 | 18 | ----- |
| 19 | 19 | |
| 20 | 20 | If you have a block device which supports DAX, you can make a filesystem |
| 21 | −on it as usual. When mounting it, use the -o dax option manually | |
| 22 | −or add 'dax' to the options in /etc/fstab. | |
| 21 | +on it as usual. The DAX code currently only supports files with a block | |
| 22 | +size equal to your kernel's PAGE_SIZE, so you may need to specify a block | |
| 23 | +size when creating the filesystem. When mounting it, use the "-o dax" | |
| 24 | +option on the command line or add 'dax' to the options in /etc/fstab. | |
| 23 | 25 | |
| 24 | 26 | |
| 25 | 27 | Implementation Tips for Block Driver Writers |
| @@ -500,3 +500,7 @@ in your dentry operations instead. · 499 unmodified lines | ||
| 500 | 500 | dentry, it does not get nameidata at all and it gets called only when cookie |
| 501 | 501 | is non-NULL. Note that link body isn't available anymore, so if you need it, |
| 502 | 502 | store it as cookie. |
| 503 | +-- | |
| 504 | +[mandatory] | |
| 505 | + __fd_install() & fd_install() can now sleep. Callers should not | |
| 506 | + hold a spinlock or other resources that do not allow a schedule. | |
| @@ -71,15 +71,12 @@ static void print_task_path_n_nm(struct task_struct *tsk, char *buf) · 70 unmodified lines | ||
| 71 | 71 | mmput(mm); |
| 72 | 72 | |
| 73 | 73 | if (exe_file) { |
| 74 | − path = exe_file->f_path; | |
| 75 | − path_get(&exe_file->f_path); | |
| 74 | + path_nm = file_path(exe_file, buf, 255); | |
| 76 | 75 | fput(exe_file); |
| 77 | − path_nm = d_path(&path, buf, 255); | |
| 78 | − path_put(&path); | |
| 79 | 76 | } |
| 80 | 77 | |
| 81 | 78 | done: |
| 82 | − pr_info("Path: %s\n", path_nm); | |
| 79 | + pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?"); | |
| 83 | 80 | } |
| 84 | 81 | |
| 85 | 82 | static void show_faulting_vma(unsigned long address, char *buf) |
| @@ -103,8 +100,7 @@ static void show_faulting_vma(unsigned long address, char *buf) · 17 unmodified lines | ||
| 103 | 100 | if (vma && (vma->vm_start <= address)) { |
| 104 | 101 | struct file *file = vma->vm_file; |
| 105 | 102 | if (file) { |
| 106 | − struct path *path = &file->f_path; | |
| 107 | − nm = d_path(path, buf, PAGE_SIZE - 1); | |
| 103 | + nm = file_path(file, buf, PAGE_SIZE - 1); | |
| 108 | 104 | inode = file_inode(vma->vm_file); |
| 109 | 105 | dev = inode->i_sb->s_dev; |
| 110 | 106 | ino = inode->i_ino; |
| @@ -136,7 +136,7 @@ void decode_address(char *buf, unsigned long address) · 135 unmodified lines | ||
| 136 | 136 | struct file *file = vma->vm_file; |
| 137 | 137 | |
| 138 | 138 | if (file) { |
| 139 | − char *d_name = d_path(&file->f_path, _tmpbuf, | |
| 139 | + char *d_name = file_path(file, _tmpbuf, | |
| 140 | 140 | sizeof(_tmpbuf)); |
| 141 | 141 | if (!IS_ERR(d_name)) |
| 142 | 142 | name = d_name; |
| @@ -166,7 +166,7 @@ static void spufs_prune_dir(struct dentry *dir) · 165 unmodified lines | ||
| 166 | 166 | mutex_lock(&d_inode(dir)->i_mutex); |
| 167 | 167 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { |
| 168 | 168 | spin_lock(&dentry->d_lock); |
| 169 | − if (!(d_unhashed(dentry)) && d_really_is_positive(dentry)) { | |
| 169 | + if (simple_positive(dentry)) { | |
| 170 | 170 | dget_dlock(dentry); |
| 171 | 171 | __d_drop(dentry); |
| 172 | 172 | spin_unlock(&dentry->d_lock); |
| @@ -62,18 +62,13 @@ static void hypfs_add_dentry(struct dentry *dentry) · 61 unmodified lines | ||
| 62 | 62 | hypfs_last_dentry = dentry; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | −static inline int hypfs_positive(struct dentry *dentry) | |
| 66 | −{ | |
| 67 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 68 | −} | |
| 69 | − | |
| 70 | 65 | static void hypfs_remove(struct dentry *dentry) |
| 71 | 66 | { |
| 72 | 67 | struct dentry *parent; |
| 73 | 68 | |
| 74 | 69 | parent = dentry->d_parent; |
| 75 | 70 | mutex_lock(&d_inode(parent)->i_mutex); |
| 76 | − if (hypfs_positive(dentry)) { | |
| 71 | + if (simple_positive(dentry)) { | |
| 77 | 72 | if (d_is_dir(dentry)) |
| 78 | 73 | simple_rmdir(d_inode(parent), dentry); |
| 79 | 74 | else |
| @@ -332,7 +332,7 @@ static void describe_addr(struct KBacktraceIterator *kbt, · 331 unmodified lines | ||
| 332 | 332 | } |
| 333 | 333 | |
| 334 | 334 | if (vma->vm_file) { |
| 335 | − p = d_path(&vma->vm_file->f_path, buf, bufsize); | |
| 335 | + p = file_path(vma->vm_file, buf, bufsize); | |
| 336 | 336 | if (IS_ERR(p)) |
| 337 | 337 | p = "?"; |
| 338 | 338 | name = kbasename(p); |
| @@ -56,7 +56,7 @@ static int notify_exec(struct mm_struct *mm) · 55 unmodified lines | ||
| 56 | 56 | if (exe_file == NULL) |
| 57 | 57 | goto done_free; |
| 58 | 58 | |
| 59 | − path = d_path(&exe_file->f_path, buf, PAGE_SIZE); | |
| 59 | + path = file_path(exe_file, buf, PAGE_SIZE); | |
| 60 | 60 | if (IS_ERR(path)) |
| 61 | 61 | goto done_put; |
| 62 | 62 | |
| @@ -419,14 +419,6 @@ static int in_flight_summary_show(struct seq_file *m, void *pos) · 418 unmodified lines | ||
| 419 | 419 | return 0; |
| 420 | 420 | } |
| 421 | 421 | |
| 422 | −/* simple_positive(file->f_path.dentry) respectively debugfs_positive(), | |
| 423 | − * but neither is "reachable" from here. | |
| 424 | − * So we have our own inline version of it above. :-( */ | |
| 425 | −static inline int debugfs_positive(struct dentry *dentry) | |
| 426 | −{ | |
| 427 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 428 | −} | |
| 429 | − | |
| 430 | 422 | /* make sure at *open* time that the respective object won't go away. */ |
| 431 | 423 | static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, void *), |
| 432 | 424 | void *data, struct kref *kref, |
| @@ -444,7 +436,7 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo · 11 unmodified lines | ||
| 444 | 436 | /* serialize with d_delete() */ |
| 445 | 437 | mutex_lock(&d_inode(parent)->i_mutex); |
| 446 | 438 | /* Make sure the object is still alive */ |
| 447 | − if (debugfs_positive(file->f_path.dentry) | |
| 439 | + if (simple_positive(file->f_path.dentry) | |
| 448 | 440 | && kref_get_unless_zero(kref)) |
| 449 | 441 | ret = 0; |
| 450 | 442 | mutex_unlock(&d_inode(parent)->i_mutex); |
| @@ -588,7 +588,7 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) · 587 unmodified lines | ||
| 588 | 588 | |
| 589 | 589 | spin_lock_irq(&lo->lo_lock); |
| 590 | 590 | if (lo->lo_backing_file) |
| 591 | − p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1); | |
| 591 | + p = file_path(lo->lo_backing_file, buf, PAGE_SIZE - 1); | |
| 592 | 592 | spin_unlock_irq(&lo->lo_lock); |
| 593 | 593 | |
| 594 | 594 | if (IS_ERR_OR_NULL(p)) |
| @@ -277,7 +277,7 @@ static int remove_file(struct dentry *parent, char *name) · 276 unmodified lines | ||
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 | spin_lock(&tmp->d_lock); |
| 280 | − if (!d_unhashed(tmp) && d_really_is_positive(tmp)) { | |
| 280 | + if (simple_positive(tmp)) { | |
| 281 | 281 | dget_dlock(tmp); |
| 282 | 282 | __d_drop(tmp); |
| 283 | 283 | spin_unlock(&tmp->d_lock); |
| @@ -455,7 +455,7 @@ static int remove_file(struct dentry *parent, char *name) · 454 unmodified lines | ||
| 455 | 455 | } |
| 456 | 456 | |
| 457 | 457 | spin_lock(&tmp->d_lock); |
| 458 | − if (!d_unhashed(tmp) && d_really_is_positive(tmp)) { | |
| 458 | + if (simple_positive(tmp)) { | |
| 459 | 459 | __d_drop(tmp); |
| 460 | 460 | spin_unlock(&tmp->d_lock); |
| 461 | 461 | simple_unlink(d_inode(parent), tmp); |
| @@ -839,7 +839,7 @@ static void bitmap_file_kick(struct bitmap *bitmap) · 838 unmodified lines | ||
| 839 | 839 | if (bitmap->storage.file) { |
| 840 | 840 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 841 | 841 | if (path) |
| 842 | − ptr = d_path(&bitmap->storage.file->f_path, | |
| 842 | + ptr = file_path(bitmap->storage.file, | |
| 843 | 843 | path, PAGE_SIZE); |
| 844 | 844 | |
| 845 | 845 | printk(KERN_ALERT |
| @@ -1927,7 +1927,7 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap) · 1081 unmodified lines | ||
| 1927 | 1927 | chunk_kb ? "KB" : "B"); |
| 1928 | 1928 | if (bitmap->storage.file) { |
| 1929 | 1929 | seq_printf(seq, ", file: "); |
| 1930 | − seq_path(seq, &bitmap->storage.file->f_path, " \t\n"); | |
| 1930 | + seq_file_path(seq, bitmap->storage.file, " \t\n"); | |
| 1931 | 1931 | } |
| 1932 | 1932 | |
| 1933 | 1933 | seq_printf(seq, "\n"); |
| @@ -5766,7 +5766,7 @@ static int get_bitmap_file(struct mddev *mddev, void __user * arg) · 5765 unmodified lines | ||
| 5766 | 5766 | /* bitmap disabled, zero the first byte and copy out */ |
| 5767 | 5767 | if (!mddev->bitmap_info.file) |
| 5768 | 5768 | file->pathname[0] = '\0'; |
| 5769 | − else if ((ptr = d_path(&mddev->bitmap_info.file->f_path, | |
| 5769 | + else if ((ptr = file_path(mddev->bitmap_info.file, | |
| 5770 | 5770 | file->pathname, sizeof(file->pathname))), |
| 5771 | 5771 | IS_ERR(ptr)) |
| 5772 | 5772 | err = PTR_ERR(ptr); |
| @@ -2936,7 +2936,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, · 2935 unmodified lines | ||
| 2936 | 2936 | if (fsg_lun_is_open(lun)) { |
| 2937 | 2937 | p = "(error)"; |
| 2938 | 2938 | if (pathbuf) { |
| 2939 | − p = d_path(&lun->filp->f_path, pathbuf, PATH_MAX); | |
| 2939 | + p = file_path(lun->filp, pathbuf, PATH_MAX); | |
| 2940 | 2940 | if (IS_ERR(p)) |
| 2941 | 2941 | p = "(error)"; |
| 2942 | 2942 | } |
| @@ -341,7 +341,7 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, · 340 unmodified lines | ||
| 341 | 341 | |
| 342 | 342 | down_read(filesem); |
| 343 | 343 | if (fsg_lun_is_open(curlun)) { /* Get the complete pathname */ |
| 344 | − p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); | |
| 344 | + p = file_path(curlun->filp, buf, PAGE_SIZE - 1); | |
| 345 | 345 | if (IS_ERR(p)) |
| 346 | 346 | rc = PTR_ERR(p); |
| 347 | 347 | else { |
| @@ -64,7 +64,7 @@ struct affs_inode_info { · 63 unmodified lines | ||
| 64 | 64 | /* short cut to get to the affs specific inode data */ |
| 65 | 65 | static inline struct affs_inode_info *AFFS_I(struct inode *inode) |
| 66 | 66 | { |
| 67 | − return list_entry(inode, struct affs_inode_info, vfs_inode); | |
| 67 | + return container_of(inode, struct affs_inode_info, vfs_inode); | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | /* |
| @@ -238,11 +238,6 @@ static inline u64 autofs4_get_ino(struct autofs_sb_info *sbi) · 237 unmodified lines | ||
| 238 | 238 | return d_inode(sbi->sb->s_root)->i_ino; |
| 239 | 239 | } |
| 240 | 240 | |
| 241 | −static inline int simple_positive(struct dentry *dentry) | |
| 242 | −{ | |
| 243 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 244 | −} | |
| 245 | − | |
| 246 | 241 | static inline void __autofs4_add_expiring(struct dentry *dentry) |
| 247 | 242 | { |
| 248 | 243 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
| @@ -112,7 +112,7 @@ BEFS_SB(const struct super_block *super) · 111 unmodified lines | ||
| 112 | 112 | static inline struct befs_inode_info * |
| 113 | 113 | BEFS_I(const struct inode *inode) |
| 114 | 114 | { |
| 115 | − return list_entry(inode, struct befs_inode_info, vfs_inode); | |
| 115 | + return container_of(inode, struct befs_inode_info, vfs_inode); | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | static inline befs_blocknr_t |
| @@ -1530,7 +1530,7 @@ static int fill_files_note(struct memelfnote *note) · 1529 unmodified lines | ||
| 1530 | 1530 | file = vma->vm_file; |
| 1531 | 1531 | if (!file) |
| 1532 | 1532 | continue; |
| 1533 | − filename = d_path(&file->f_path, name_curpos, remaining); | |
| 1533 | + filename = file_path(file, name_curpos, remaining); | |
| 1534 | 1534 | if (IS_ERR(filename)) { |
| 1535 | 1535 | if (PTR_ERR(filename) == -ENAMETOOLONG) { |
| 1536 | 1536 | vfree(data); |
| @@ -1540,7 +1540,7 @@ static int fill_files_note(struct memelfnote *note) · 3 unmodified lines | ||
| 1540 | 1540 | continue; |
| 1541 | 1541 | } |
| 1542 | 1542 | |
| 1543 | − /* d_path() fills at the end, move name down */ | |
| 1543 | + /* file_path() fills at the end, move name down */ | |
| 1544 | 1544 | /* n = strlen(filename) + 1: */ |
| 1545 | 1545 | n = (name_curpos + remaining) - filename; |
| 1546 | 1546 | remaining = filename - name_curpos; |
| @@ -152,6 +152,9 @@ blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) · 151 unmodified lines | ||
| 152 | 152 | struct file *file = iocb->ki_filp; |
| 153 | 153 | struct inode *inode = file->f_mapping->host; |
| 154 | 154 | |
| 155 | + if (IS_DAX(inode)) | |
| 156 | + return dax_do_io(iocb, inode, iter, offset, blkdev_get_block, | |
| 157 | + NULL, DIO_SKIP_DIO_COUNT); | |
| 155 | 158 | return __blockdev_direct_IO(iocb, inode, I_BDEV(inode), iter, offset, |
| 156 | 159 | blkdev_get_block, NULL, NULL, |
| 157 | 160 | DIO_SKIP_DIO_COUNT); |
| @@ -443,6 +446,12 @@ long bdev_direct_access(struct block_device *bdev, sector_t sector, · 285 unmodified lines | ||
| 443 | 446 | long avail; |
| 444 | 447 | const struct block_device_operations *ops = bdev->bd_disk->fops; |
| 445 | 448 | |
| 449 | + /* | |
| 450 | + * The device driver is allowed to sleep, in order to make the | |
| 451 | + * memory directly accessible. | |
| 452 | + */ | |
| 453 | + might_sleep(); | |
| 454 | + | |
| 446 | 455 | if (size < 0) |
| 447 | 456 | return size; |
| 448 | 457 | if (!ops->direct_access) |
| @@ -1170,6 +1179,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) · 721 unmodified lines | ||
| 1170 | 1179 | bdev->bd_disk = disk; |
| 1171 | 1180 | bdev->bd_queue = disk->queue; |
| 1172 | 1181 | bdev->bd_contains = bdev; |
| 1182 | + bdev->bd_inode->i_flags = disk->fops->direct_access ? S_DAX : 0; | |
| 1173 | 1183 | if (!partno) { |
| 1174 | 1184 | ret = -ENXIO; |
| 1175 | 1185 | bdev->bd_part = disk_get_part(disk, partno); |
| @@ -1748,7 +1748,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, · 1747 unmodified lines | ||
| 1748 | 1748 | } |
| 1749 | 1749 | |
| 1750 | 1750 | current->backing_dev_info = inode_to_bdi(inode); |
| 1751 | − err = file_remove_suid(file); | |
| 1751 | + err = file_remove_privs(file); | |
| 1752 | 1752 | if (err) { |
| 1753 | 1753 | mutex_unlock(&inode->i_mutex); |
| 1754 | 1754 | goto out; |
| @@ -43,7 +43,6 @@ struct cachefiles_object { · 42 unmodified lines | ||
| 43 | 43 | loff_t i_size; /* object size */ |
| 44 | 44 | unsigned long flags; |
| 45 | 45 | #define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */ |
| 46 | −#define CACHEFILES_OBJECT_BURIED 1 /* T if preemptively buried */ | |
| 47 | 46 | atomic_t usage; /* object usage count */ |
| 48 | 47 | uint8_t type; /* object type */ |
| 49 | 48 | uint8_t new; /* T if object new */ |
| @@ -97,7 +97,8 @@ static noinline void cachefiles_printk_object(struct cachefiles_object *object, · 96 unmodified lines | ||
| 97 | 97 | * call vfs_unlink(), vfs_rmdir() or vfs_rename() |
| 98 | 98 | */ |
| 99 | 99 | static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, |
| 100 | − struct dentry *dentry) | |
| 100 | + struct dentry *dentry, | |
| 101 | + enum fscache_why_object_killed why) | |
| 101 | 102 | { |
| 102 | 103 | struct cachefiles_object *object; |
| 103 | 104 | struct rb_node *p; |
| @@ -132,8 +133,9 @@ found_dentry: · 28 unmodified lines | ||
| 132 | 133 | pr_err("\n"); |
| 133 | 134 | pr_err("Error: Can't preemptively bury live object\n"); |
| 134 | 135 | cachefiles_printk_object(object, NULL); |
| 135 | − } else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { | |
| 136 | − pr_err("Error: Object already preemptively buried\n"); | |
| 136 | + } else { | |
| 137 | + if (why != FSCACHE_OBJECT_IS_STALE) | |
| 138 | + fscache_object_mark_killed(&object->fscache, why); | |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | 141 | write_unlock(&cache->active_lock); |
| @@ -265,7 +267,8 @@ requeue: · 125 unmodified lines | ||
| 265 | 267 | static int cachefiles_bury_object(struct cachefiles_cache *cache, |
| 266 | 268 | struct dentry *dir, |
| 267 | 269 | struct dentry *rep, |
| 268 | − bool preemptive) | |
| 270 | + bool preemptive, | |
| 271 | + enum fscache_why_object_killed why) | |
| 269 | 272 | { |
| 270 | 273 | struct dentry *grave, *trap; |
| 271 | 274 | struct path path, path_to_graveyard; |
| @@ -289,7 +292,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, · 17 unmodified lines | ||
| 289 | 292 | ret = vfs_unlink(d_inode(dir), rep, NULL); |
| 290 | 293 | |
| 291 | 294 | if (preemptive) |
| 292 | − cachefiles_mark_object_buried(cache, rep); | |
| 295 | + cachefiles_mark_object_buried(cache, rep, why); | |
| 293 | 296 | } |
| 294 | 297 | |
| 295 | 298 | mutex_unlock(&d_inode(dir)->i_mutex); |
| @@ -394,7 +397,7 @@ try_again: · 98 unmodified lines | ||
| 394 | 397 | "Rename failed with error %d", ret); |
| 395 | 398 | |
| 396 | 399 | if (preemptive) |
| 397 | − cachefiles_mark_object_buried(cache, rep); | |
| 400 | + cachefiles_mark_object_buried(cache, rep, why); | |
| 398 | 401 | } |
| 399 | 402 | |
| 400 | 403 | unlock_rename(cache->graveyard, dir); |
| @@ -422,7 +425,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, · 21 unmodified lines | ||
| 422 | 425 | |
| 423 | 426 | mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT); |
| 424 | 427 | |
| 425 | − if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { | |
| 428 | + if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) { | |
| 426 | 429 | /* object allocation for the same key preemptively deleted this |
| 427 | 430 | * object's file so that it could create its own file */ |
| 428 | 431 | _debug("object preemptively buried"); |
| @@ -433,7 +436,8 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, · 4 unmodified lines | ||
| 433 | 436 | * may have been renamed */ |
| 434 | 437 | if (dir == object->dentry->d_parent) { |
| 435 | 438 | ret = cachefiles_bury_object(cache, dir, |
| 436 | − object->dentry, false); | |
| 439 | + object->dentry, false, | |
| 440 | + FSCACHE_OBJECT_WAS_RETIRED); | |
| 437 | 441 | } else { |
| 438 | 442 | /* it got moved, presumably by cachefilesd culling it, |
| 439 | 443 | * so it's no longer in the key path and we can ignore |
| @@ -522,7 +526,7 @@ lookup_again: · 82 unmodified lines | ||
| 522 | 526 | if (d_is_negative(next)) { |
| 523 | 527 | ret = cachefiles_has_space(cache, 1, 0); |
| 524 | 528 | if (ret < 0) |
| 525 | − goto create_error; | |
| 529 | + goto no_space_error; | |
| 526 | 530 | |
| 527 | 531 | path.dentry = dir; |
| 528 | 532 | ret = security_path_mkdir(&path, next, 0); |
| @@ -551,7 +555,7 @@ lookup_again: · 22 unmodified lines | ||
| 551 | 555 | if (d_is_negative(next)) { |
| 552 | 556 | ret = cachefiles_has_space(cache, 1, 0); |
| 553 | 557 | if (ret < 0) |
| 554 | − goto create_error; | |
| 558 | + goto no_space_error; | |
| 555 | 559 | |
| 556 | 560 | path.dentry = dir; |
| 557 | 561 | ret = security_path_mknod(&path, next, S_IFREG, 0); |
| @@ -602,7 +606,8 @@ lookup_again: · 44 unmodified lines | ||
| 602 | 606 | * mutex) */ |
| 603 | 607 | object->dentry = NULL; |
| 604 | 608 | |
| 605 | − ret = cachefiles_bury_object(cache, dir, next, true); | |
| 609 | + ret = cachefiles_bury_object(cache, dir, next, true, | |
| 610 | + FSCACHE_OBJECT_IS_STALE); | |
| 606 | 611 | dput(next); |
| 607 | 612 | next = NULL; |
| 608 | 613 | |
| @@ -610,6 +615,7 @@ lookup_again: · 1 unmodified line | ||
| 610 | 615 | goto delete_error; |
| 611 | 616 | |
| 612 | 617 | _debug("redo lookup"); |
| 618 | + fscache_object_retrying_stale(&object->fscache); | |
| 613 | 619 | goto lookup_again; |
| 614 | 620 | } |
| 615 | 621 | } |
| @@ -662,6 +668,8 @@ lookup_again: · 46 unmodified lines | ||
| 662 | 668 | _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); |
| 663 | 669 | return 0; |
| 664 | 670 | |
| 671 | +no_space_error: | |
| 672 | + fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); | |
| 665 | 673 | create_error: |
| 666 | 674 | _debug("create error %d", ret); |
| 667 | 675 | if (ret == -EIO) |
| @@ -927,7 +935,8 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, · 259 unmodified lines | ||
| 927 | 935 | /* actually remove the victim (drops the dir mutex) */ |
| 928 | 936 | _debug("bury"); |
| 929 | 937 | |
| 930 | − ret = cachefiles_bury_object(cache, dir, victim, false); | |
| 938 | + ret = cachefiles_bury_object(cache, dir, victim, false, | |
| 939 | + FSCACHE_OBJECT_WAS_CULLED); | |
| 931 | 940 | if (ret < 0) |
| 932 | 941 | goto error; |
| 933 | 942 | |
| @@ -962,7 +962,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) · 961 unmodified lines | ||
| 962 | 962 | |
| 963 | 963 | pos = iocb->ki_pos; |
| 964 | 964 | count = iov_iter_count(from); |
| 965 | − err = file_remove_suid(file); | |
| 965 | + err = file_remove_privs(file); | |
| 966 | 966 | if (err) |
| 967 | 967 | goto out; |
| 968 | 968 | |
| @@ -79,7 +79,7 @@ void coda_sysctl_clean(void); · 78 unmodified lines | ||
| 79 | 79 | |
| 80 | 80 | static inline struct coda_inode_info *ITOC(struct inode *inode) |
| 81 | 81 | { |
| 82 | − return list_entry(inode, struct coda_inode_info, vfs_inode); | |
| 82 | + return container_of(inode, struct coda_inode_info, vfs_inode); | |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | static __inline__ struct CodaFid *coda_i2f(struct inode *inode) |
| @@ -236,7 +236,7 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) · 235 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | if (dentry) { |
| 238 | 238 | spin_lock(&dentry->d_lock); |
| 239 | − if (!d_unhashed(dentry) && d_really_is_positive(dentry)) { | |
| 239 | + if (simple_positive(dentry)) { | |
| 240 | 240 | dget_dlock(dentry); |
| 241 | 241 | __d_drop(dentry); |
| 242 | 242 | spin_unlock(&dentry->d_lock); |
| @@ -140,7 +140,7 @@ static int cn_print_exe_file(struct core_name *cn) · 139 unmodified lines | ||
| 140 | 140 | goto put_exe_file; |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | − path = d_path(&exe_file->f_path, pathbuf, PATH_MAX); | |
| 143 | + path = file_path(exe_file, pathbuf, PATH_MAX); | |
| 144 | 144 | if (IS_ERR(path)) { |
| 145 | 145 | ret = PTR_ERR(path); |
| 146 | 146 | goto free_buf; |
| @@ -155,7 +155,7 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter, · 154 unmodified lines | ||
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | if (iov_iter_rw(iter) == WRITE) |
| 158 | − len = copy_from_iter(addr, max - pos, iter); | |
| 158 | + len = copy_from_iter_nocache(addr, max - pos, iter); | |
| 159 | 159 | else if (!hole) |
| 160 | 160 | len = copy_to_iter(addr, max - pos, iter); |
| 161 | 161 | else |
| @@ -209,7 +209,8 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode, · 47 unmodified lines | ||
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | /* Protects against truncate */ |
| 212 | − inode_dio_begin(inode); | |
| 212 | + if (!(flags & DIO_SKIP_DIO_COUNT)) | |
| 213 | + inode_dio_begin(inode); | |
| 213 | 214 | |
| 214 | 215 | retval = dax_io(inode, iter, pos, end, get_block, &bh); |
| 215 | 216 | |
| @@ -219,7 +220,8 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode, · 3 unmodified lines | ||
| 219 | 220 | if ((retval > 0) && end_io) |
| 220 | 221 | end_io(iocb, pos, retval, bh.b_private); |
| 221 | 222 | |
| 222 | − inode_dio_end(inode); | |
| 223 | + if (!(flags & DIO_SKIP_DIO_COUNT)) | |
| 224 | + inode_dio_end(inode); | |
| 223 | 225 | out: |
| 224 | 226 | return retval; |
| 225 | 227 | } |
| @@ -1673,7 +1673,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) · 1672 unmodified lines | ||
| 1673 | 1673 | DCACHE_OP_COMPARE | |
| 1674 | 1674 | DCACHE_OP_REVALIDATE | |
| 1675 | 1675 | DCACHE_OP_WEAK_REVALIDATE | |
| 1676 | − DCACHE_OP_DELETE )); | |
| 1676 | + DCACHE_OP_DELETE | | |
| 1677 | + DCACHE_OP_SELECT_INODE)); | |
| 1677 | 1678 | dentry->d_op = op; |
| 1678 | 1679 | if (!op) |
| 1679 | 1680 | return; |
| @@ -1689,6 +1690,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) · 9 unmodified lines | ||
| 1689 | 1690 | dentry->d_flags |= DCACHE_OP_DELETE; |
| 1690 | 1691 | if (op->d_prune) |
| 1691 | 1692 | dentry->d_flags |= DCACHE_OP_PRUNE; |
| 1693 | + if (op->d_select_inode) | |
| 1694 | + dentry->d_flags |= DCACHE_OP_SELECT_INODE; | |
| 1692 | 1695 | |
| 1693 | 1696 | } |
| 1694 | 1697 | EXPORT_SYMBOL(d_set_d_op); |
| @@ -44,11 +44,6 @@ static struct inode *debugfs_get_inode(struct super_block *sb) · 43 unmodified lines | ||
| 44 | 44 | return inode; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −static inline int debugfs_positive(struct dentry *dentry) | |
| 48 | −{ | |
| 49 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 50 | −} | |
| 51 | − | |
| 52 | 47 | struct debugfs_mount_opts { |
| 53 | 48 | kuid_t uid; |
| 54 | 49 | kgid_t gid; |
| @@ -522,7 +517,7 @@ static int __debugfs_remove(struct dentry *dentry, struct dentry *parent) · 467 unmodified lines | ||
| 522 | 517 | { |
| 523 | 518 | int ret = 0; |
| 524 | 519 | |
| 525 | − if (debugfs_positive(dentry)) { | |
| 520 | + if (simple_positive(dentry)) { | |
| 526 | 521 | dget(dentry); |
| 527 | 522 | if (d_is_dir(dentry)) |
| 528 | 523 | ret = simple_rmdir(d_inode(parent), dentry); |
| @@ -602,7 +597,7 @@ void debugfs_remove_recursive(struct dentry *dentry) · 73 unmodified lines | ||
| 602 | 597 | */ |
| 603 | 598 | spin_lock(&parent->d_lock); |
| 604 | 599 | list_for_each_entry(child, &parent->d_subdirs, d_child) { |
| 605 | − if (!debugfs_positive(child)) | |
| 600 | + if (!simple_positive(child)) | |
| 606 | 601 | continue; |
| 607 | 602 | |
| 608 | 603 | /* perhaps simple_empty(child) makes more sense */ |
| @@ -623,7 +618,7 @@ void debugfs_remove_recursive(struct dentry *dentry) · 14 unmodified lines | ||
| 623 | 618 | * from d_subdirs. When releasing the parent->d_lock we can |
| 624 | 619 | * no longer trust that the next pointer is valid. |
| 625 | 620 | * Restart the loop. We'll skip this one with the |
| 626 | − * debugfs_positive() check. | |
| 621 | + * simple_positive() check. | |
| 627 | 622 | */ |
| 628 | 623 | goto loop; |
| 629 | 624 | } |
| @@ -44,12 +44,6 @@ static inline void exofs_put_page(struct page *page) · 43 unmodified lines | ||
| 44 | 44 | page_cache_release(page); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −/* Accesses dir's inode->i_size must be called under inode lock */ | |
| 48 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 49 | −{ | |
| 50 | − return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | |
| 51 | −} | |
| 52 | − | |
| 53 | 47 | static unsigned exofs_last_byte(struct inode *inode, unsigned long page_nr) |
| 54 | 48 | { |
| 55 | 49 | loff_t last_byte = inode->i_size; |
| @@ -70,11 +70,6 @@ static inline void ext2_put_page(struct page *page) · 69 unmodified lines | ||
| 70 | 70 | page_cache_release(page); |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 74 | −{ | |
| 75 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 76 | −} | |
| 77 | − | |
| 78 | 73 | /* |
| 79 | 74 | * Return the offset into page `page_nr' of the last valid |
| 80 | 75 | * byte in that page, plus one. |
| @@ -452,7 +452,7 @@ void __ext4_error_file(struct file *file, const char *function, · 451 unmodified lines | ||
| 452 | 452 | es = EXT4_SB(inode->i_sb)->s_es; |
| 453 | 453 | es->s_last_error_ino = cpu_to_le32(inode->i_ino); |
| 454 | 454 | if (ext4_error_ratelimit(inode->i_sb)) { |
| 455 | − path = d_path(&(file->f_path), pathname, sizeof(pathname)); | |
| 455 | + path = file_path(file, pathname, sizeof(pathname)); | |
| 456 | 456 | if (IS_ERR(path)) |
| 457 | 457 | path = "(unknown)"; |
| 458 | 458 | va_start(args, fmt); |
| @@ -147,6 +147,13 @@ static int expand_fdtable(struct files_struct *files, int nr) · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | spin_unlock(&files->file_lock); |
| 149 | 149 | new_fdt = alloc_fdtable(nr); |
| 150 | + | |
| 151 | + /* make sure all __fd_install() have seen resize_in_progress | |
| 152 | + * or have finished their rcu_read_lock_sched() section. | |
| 153 | + */ | |
| 154 | + if (atomic_read(&files->count) > 1) | |
| 155 | + synchronize_sched(); | |
| 156 | + | |
| 150 | 157 | spin_lock(&files->file_lock); |
| 151 | 158 | if (!new_fdt) |
| 152 | 159 | return -ENOMEM; |
| @@ -158,21 +165,14 @@ static int expand_fdtable(struct files_struct *files, int nr) · 5 unmodified lines | ||
| 158 | 165 | __free_fdtable(new_fdt); |
| 159 | 166 | return -EMFILE; |
| 160 | 167 | } |
| 161 | − /* | |
| 162 | − * Check again since another task may have expanded the fd table while | |
| 163 | − * we dropped the lock | |
| 164 | − */ | |
| 165 | 168 | cur_fdt = files_fdtable(files); |
| 166 | − if (nr >= cur_fdt->max_fds) { | |
| 167 | − /* Continue as planned */ | |
| 168 | − copy_fdtable(new_fdt, cur_fdt); | |
| 169 | − rcu_assign_pointer(files->fdt, new_fdt); | |
| 170 | − if (cur_fdt != &files->fdtab) | |
| 171 | − call_rcu(&cur_fdt->rcu, free_fdtable_rcu); | |
| 172 | − } else { | |
| 173 | − /* Somebody else expanded, so undo our attempt */ | |
| 174 | − __free_fdtable(new_fdt); | |
| 175 | − } | |
| 169 | + BUG_ON(nr < cur_fdt->max_fds); | |
| 170 | + copy_fdtable(new_fdt, cur_fdt); | |
| 171 | + rcu_assign_pointer(files->fdt, new_fdt); | |
| 172 | + if (cur_fdt != &files->fdtab) | |
| 173 | + call_rcu(&cur_fdt->rcu, free_fdtable_rcu); | |
| 174 | + /* coupled with smp_rmb() in __fd_install() */ | |
| 175 | + smp_wmb(); | |
| 176 | 176 | return 1; |
| 177 | 177 | } |
| 178 | 178 | |
| @@ -185,21 +185,38 @@ static int expand_fdtable(struct files_struct *files, int nr) · 6 unmodified lines | ||
| 185 | 185 | * The files->file_lock should be held on entry, and will be held on exit. |
| 186 | 186 | */ |
| 187 | 187 | static int expand_files(struct files_struct *files, int nr) |
| 188 | + __releases(files->file_lock) | |
| 189 | + __acquires(files->file_lock) | |
| 188 | 190 | { |
| 189 | 191 | struct fdtable *fdt; |
| 192 | + int expanded = 0; | |
| 190 | 193 | |
| 194 | +repeat: | |
| 191 | 195 | fdt = files_fdtable(files); |
| 192 | 196 | |
| 193 | 197 | /* Do we need to expand? */ |
| 194 | 198 | if (nr < fdt->max_fds) |
| 195 | − return 0; | |
| 199 | + return expanded; | |
| 196 | 200 | |
| 197 | 201 | /* Can we expand? */ |
| 198 | 202 | if (nr >= sysctl_nr_open) |
| 199 | 203 | return -EMFILE; |
| 200 | 204 | |
| 205 | + if (unlikely(files->resize_in_progress)) { | |
| 206 | + spin_unlock(&files->file_lock); | |
| 207 | + expanded = 1; | |
| 208 | + wait_event(files->resize_wait, !files->resize_in_progress); | |
| 209 | + spin_lock(&files->file_lock); | |
| 210 | + goto repeat; | |
| 211 | + } | |
| 212 | + | |
| 201 | 213 | /* All good, so we try */ |
| 202 | − return expand_fdtable(files, nr); | |
| 214 | + files->resize_in_progress = true; | |
| 215 | + expanded = expand_fdtable(files, nr); | |
| 216 | + files->resize_in_progress = false; | |
| 217 | + | |
| 218 | + wake_up_all(&files->resize_wait); | |
| 219 | + return expanded; | |
| 203 | 220 | } |
| 204 | 221 | |
| 205 | 222 | static inline void __set_close_on_exec(int fd, struct fdtable *fdt) |
| @@ -256,6 +273,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) · 50 unmodified lines | ||
| 256 | 273 | atomic_set(&newf->count, 1); |
| 257 | 274 | |
| 258 | 275 | spin_lock_init(&newf->file_lock); |
| 276 | + newf->resize_in_progress = false; | |
| 277 | + init_waitqueue_head(&newf->resize_wait); | |
| 259 | 278 | newf->next_fd = 0; |
| 260 | 279 | new_fdt = &newf->fdtab; |
| 261 | 280 | new_fdt->max_fds = NR_OPEN_DEFAULT; |
| @@ -553,11 +572,21 @@ void __fd_install(struct files_struct *files, unsigned int fd, · 291 unmodified lines | ||
| 553 | 572 | struct file *file) |
| 554 | 573 | { |
| 555 | 574 | struct fdtable *fdt; |
| 556 | − spin_lock(&files->file_lock); | |
| 557 | − fdt = files_fdtable(files); | |
| 575 | + | |
| 576 | + might_sleep(); | |
| 577 | + rcu_read_lock_sched(); | |
| 578 | + | |
| 579 | + while (unlikely(files->resize_in_progress)) { | |
| 580 | + rcu_read_unlock_sched(); | |
| 581 | + wait_event(files->resize_wait, !files->resize_in_progress); | |
| 582 | + rcu_read_lock_sched(); | |
| 583 | + } | |
| 584 | + /* coupled with smp_wmb() in expand_fdtable() */ | |
| 585 | + smp_rmb(); | |
| 586 | + fdt = rcu_dereference_sched(files->fdt); | |
| 558 | 587 | BUG_ON(fdt->fd[fd] != NULL); |
| 559 | 588 | rcu_assign_pointer(fdt->fd[fd], file); |
| 560 | − spin_unlock(&files->file_lock); | |
| 589 | + rcu_read_unlock_sched(); | |
| 561 | 590 | } |
| 562 | 591 | |
| 563 | 592 | void fd_install(unsigned int fd, struct file *file) |
| @@ -635,11 +664,17 @@ static struct file *__fget(unsigned int fd, fmode_t mask) · 71 unmodified lines | ||
| 635 | 664 | struct file *file; |
| 636 | 665 | |
| 637 | 666 | rcu_read_lock(); |
| 667 | +loop: | |
| 638 | 668 | file = fcheck_files(files, fd); |
| 639 | 669 | if (file) { |
| 640 | − /* File object ref couldn't be taken */ | |
| 641 | − if ((file->f_mode & mask) || !get_file_rcu(file)) | |
| 670 | + /* File object ref couldn't be taken. | |
| 671 | + * dup2() atomicity guarantee is the reason | |
| 672 | + * we loop to catch the new file (or NULL pointer) | |
| 673 | + */ | |
| 674 | + if (file->f_mode & mask) | |
| 642 | 675 | file = NULL; |
| 676 | + else if (!get_file_rcu(file)) | |
| 677 | + goto loop; | |
| 643 | 678 | } |
| 644 | 679 | rcu_read_unlock(); |
| 645 | 680 | |
| @@ -20,7 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/cdev.h> |
| 21 | 21 | #include <linux/fsnotify.h> |
| 22 | 22 | #include <linux/sysctl.h> |
| 23 | −#include <linux/lglock.h> | |
| 24 | 23 | #include <linux/percpu_counter.h> |
| 25 | 24 | #include <linux/percpu.h> |
| 26 | 25 | #include <linux/hardirq.h> |
| @@ -61,13 +61,6 @@ const struct file_operations vxfs_dir_operations = { · 60 unmodified lines | ||
| 61 | 61 | .iterate = vxfs_readdir, |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | − | |
| 65 | −static inline u_long | |
| 66 | −dir_pages(struct inode *inode) | |
| 67 | −{ | |
| 68 | − return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | |
| 69 | −} | |
| 70 | − | |
| 71 | 64 | static inline u_long |
| 72 | 65 | dir_blocks(struct inode *ip) |
| 73 | 66 | { |
| @@ -327,7 +327,8 @@ static int fscache_alloc_object(struct fscache_cache *cache, · 326 unmodified lines | ||
| 327 | 327 | |
| 328 | 328 | object_already_extant: |
| 329 | 329 | ret = -ENOBUFS; |
| 330 | − if (fscache_object_is_dead(object)) { | |
| 330 | + if (fscache_object_is_dying(object) || | |
| 331 | + fscache_cache_is_broken(object)) { | |
| 331 | 332 | spin_unlock(&cookie->lock); |
| 332 | 333 | goto error; |
| 333 | 334 | } |
| @@ -671,7 +672,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) · 337 unmodified lines | ||
| 671 | 672 | if (!op) |
| 672 | 673 | return -ENOMEM; |
| 673 | 674 | |
| 674 | − fscache_operation_init(op, NULL, NULL); | |
| 675 | + fscache_operation_init(op, NULL, NULL, NULL); | |
| 675 | 676 | op->flags = FSCACHE_OP_MYTHREAD | |
| 676 | 677 | (1 << FSCACHE_OP_WAITING) | |
| 677 | 678 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
| @@ -695,8 +696,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) · 17 unmodified lines | ||
| 695 | 696 | /* the work queue now carries its own ref on the object */ |
| 696 | 697 | spin_unlock(&cookie->lock); |
| 697 | 698 | |
| 698 | − ret = fscache_wait_for_operation_activation(object, op, | |
| 699 | − NULL, NULL, NULL); | |
| 699 | + ret = fscache_wait_for_operation_activation(object, op, NULL, NULL); | |
| 700 | 700 | if (ret == 0) { |
| 701 | 701 | /* ask the cache to honour the operation */ |
| 702 | 702 | ret = object->cache->ops->check_consistency(op); |
| @@ -124,8 +124,7 @@ extern int fscache_submit_exclusive_op(struct fscache_object *, · 123 unmodified lines | ||
| 124 | 124 | struct fscache_operation *); |
| 125 | 125 | extern int fscache_submit_op(struct fscache_object *, |
| 126 | 126 | struct fscache_operation *); |
| 127 | −extern int fscache_cancel_op(struct fscache_operation *, | |
| 128 | − void (*)(struct fscache_operation *)); | |
| 127 | +extern int fscache_cancel_op(struct fscache_operation *, bool); | |
| 129 | 128 | extern void fscache_cancel_all_ops(struct fscache_object *); |
| 130 | 129 | extern void fscache_abort_object(struct fscache_object *); |
| 131 | 130 | extern void fscache_start_operations(struct fscache_object *); |
| @@ -138,8 +137,7 @@ extern int fscache_wait_for_deferred_lookup(struct fscache_cookie *); · 6 unmodified lines | ||
| 138 | 137 | extern int fscache_wait_for_operation_activation(struct fscache_object *, |
| 139 | 138 | struct fscache_operation *, |
| 140 | 139 | atomic_t *, |
| 141 | − atomic_t *, | |
| 142 | − void (*)(struct fscache_operation *)); | |
| 140 | + atomic_t *); | |
| 143 | 141 | extern void fscache_invalidate_writes(struct fscache_cookie *); |
| 144 | 142 | |
| 145 | 143 | /* |
| @@ -164,6 +162,7 @@ extern atomic_t fscache_n_op_pend; · 18 unmodified lines | ||
| 164 | 162 | extern atomic_t fscache_n_op_run; |
| 165 | 163 | extern atomic_t fscache_n_op_enqueue; |
| 166 | 164 | extern atomic_t fscache_n_op_deferred_release; |
| 165 | +extern atomic_t fscache_n_op_initialised; | |
| 167 | 166 | extern atomic_t fscache_n_op_release; |
| 168 | 167 | extern atomic_t fscache_n_op_gc; |
| 169 | 168 | extern atomic_t fscache_n_op_cancelled; |
| @@ -271,6 +270,11 @@ extern atomic_t fscache_n_cop_write_page; · 101 unmodified lines | ||
| 271 | 270 | extern atomic_t fscache_n_cop_uncache_page; |
| 272 | 271 | extern atomic_t fscache_n_cop_dissociate_pages; |
| 273 | 272 | |
| 273 | +extern atomic_t fscache_n_cache_no_space_reject; | |
| 274 | +extern atomic_t fscache_n_cache_stale_objects; | |
| 275 | +extern atomic_t fscache_n_cache_retired_objects; | |
| 276 | +extern atomic_t fscache_n_cache_culled_objects; | |
| 277 | + | |
| 274 | 278 | static inline void fscache_stat(atomic_t *stat) |
| 275 | 279 | { |
| 276 | 280 | atomic_inc(stat); |
| @@ -327,6 +327,17 @@ void fscache_object_init(struct fscache_object *object, · 326 unmodified lines | ||
| 327 | 327 | } |
| 328 | 328 | EXPORT_SYMBOL(fscache_object_init); |
| 329 | 329 | |
| 330 | +/* | |
| 331 | + * Mark the object as no longer being live, making sure that we synchronise | |
| 332 | + * against op submission. | |
| 333 | + */ | |
| 334 | +static inline void fscache_mark_object_dead(struct fscache_object *object) | |
| 335 | +{ | |
| 336 | + spin_lock(&object->lock); | |
| 337 | + clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); | |
| 338 | + spin_unlock(&object->lock); | |
| 339 | +} | |
| 340 | + | |
| 330 | 341 | /* |
| 331 | 342 | * Abort object initialisation before we start it. |
| 332 | 343 | */ |
| @@ -610,6 +621,8 @@ static const struct fscache_state *fscache_lookup_failure(struct fscache_object · 277 unmodified lines | ||
| 610 | 621 | object->cache->ops->lookup_complete(object); |
| 611 | 622 | fscache_stat_d(&fscache_n_cop_lookup_complete); |
| 612 | 623 | |
| 624 | + set_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->flags); | |
| 625 | + | |
| 613 | 626 | cookie = object->cookie; |
| 614 | 627 | set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); |
| 615 | 628 | if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags)) |
| @@ -629,7 +642,7 @@ static const struct fscache_state *fscache_kill_object(struct fscache_object *ob · 13 unmodified lines | ||
| 629 | 642 | _enter("{OBJ%x,%d,%d},%d", |
| 630 | 643 | object->debug_id, object->n_ops, object->n_children, event); |
| 631 | 644 | |
| 632 | − clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); | |
| 645 | + fscache_mark_object_dead(object); | |
| 633 | 646 | object->oob_event_mask = 0; |
| 634 | 647 | |
| 635 | 648 | if (list_empty(&object->dependents) && |
| @@ -948,7 +961,8 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj · 312 unmodified lines | ||
| 948 | 961 | if (!op) |
| 949 | 962 | goto nomem; |
| 950 | 963 | |
| 951 | − fscache_operation_init(op, object->cache->ops->invalidate_object, NULL); | |
| 964 | + fscache_operation_init(op, object->cache->ops->invalidate_object, | |
| 965 | + NULL, NULL); | |
| 952 | 966 | op->flags = FSCACHE_OP_ASYNC | |
| 953 | 967 | (1 << FSCACHE_OP_EXCLUSIVE) | |
| 954 | 968 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
| @@ -974,13 +988,13 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj · 19 unmodified lines | ||
| 974 | 988 | return transit_to(UPDATE_OBJECT); |
| 975 | 989 | |
| 976 | 990 | nomem: |
| 977 | − clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); | |
| 991 | + fscache_mark_object_dead(object); | |
| 978 | 992 | fscache_unuse_cookie(object); |
| 979 | 993 | _leave(" [ENOMEM]"); |
| 980 | 994 | return transit_to(KILL_OBJECT); |
| 981 | 995 | |
| 982 | 996 | submit_op_failed: |
| 983 | − clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); | |
| 997 | + fscache_mark_object_dead(object); | |
| 984 | 998 | spin_unlock(&cookie->lock); |
| 985 | 999 | fscache_unuse_cookie(object); |
| 986 | 1000 | kfree(op); |
| @@ -1016,3 +1030,50 @@ static const struct fscache_state *fscache_update_object(struct fscache_object * · 29 unmodified lines | ||
| 1016 | 1030 | _leave(""); |
| 1017 | 1031 | return transit_to(WAIT_FOR_CMD); |
| 1018 | 1032 | } |
| 1033 | + | |
| 1034 | +/** | |
| 1035 | + * fscache_object_retrying_stale - Note retrying stale object | |
| 1036 | + * @object: The object that will be retried | |
| 1037 | + * | |
| 1038 | + * Note that an object lookup found an on-disk object that was adjudged to be | |
| 1039 | + * stale and has been deleted. The lookup will be retried. | |
| 1040 | + */ | |
| 1041 | +void fscache_object_retrying_stale(struct fscache_object *object) | |
| 1042 | +{ | |
| 1043 | + fscache_stat(&fscache_n_cache_no_space_reject); | |
| 1044 | +} | |
| 1045 | +EXPORT_SYMBOL(fscache_object_retrying_stale); | |
| 1046 | + | |
| 1047 | +/** | |
| 1048 | + * fscache_object_mark_killed - Note that an object was killed | |
| 1049 | + * @object: The object that was culled | |
| 1050 | + * @why: The reason the object was killed. | |
| 1051 | + * | |
| 1052 | + * Note that an object was killed. Returns true if the object was | |
| 1053 | + * already marked killed, false if it wasn't. | |
| 1054 | + */ | |
| 1055 | +void fscache_object_mark_killed(struct fscache_object *object, | |
| 1056 | + enum fscache_why_object_killed why) | |
| 1057 | +{ | |
| 1058 | + if (test_and_set_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->flags)) { | |
| 1059 | + pr_err("Error: Object already killed by cache [%s]\n", | |
| 1060 | + object->cache->identifier); | |
| 1061 | + return; | |
| 1062 | + } | |
| 1063 | + | |
| 1064 | + switch (why) { | |
| 1065 | + case FSCACHE_OBJECT_NO_SPACE: | |
| 1066 | + fscache_stat(&fscache_n_cache_no_space_reject); | |
| 1067 | + break; | |
| 1068 | + case FSCACHE_OBJECT_IS_STALE: | |
| 1069 | + fscache_stat(&fscache_n_cache_stale_objects); | |
| 1070 | + break; | |
| 1071 | + case FSCACHE_OBJECT_WAS_RETIRED: | |
| 1072 | + fscache_stat(&fscache_n_cache_retired_objects); | |
| 1073 | + break; | |
| 1074 | + case FSCACHE_OBJECT_WAS_CULLED: | |
| 1075 | + fscache_stat(&fscache_n_cache_culled_objects); | |
| 1076 | + break; | |
| 1077 | + } | |
| 1078 | +} | |
| 1079 | +EXPORT_SYMBOL(fscache_object_mark_killed); | |
| @@ -20,6 +20,35 @@ · 19 unmodified lines | ||
| 20 | 20 | atomic_t fscache_op_debug_id; |
| 21 | 21 | EXPORT_SYMBOL(fscache_op_debug_id); |
| 22 | 22 | |
| 23 | +static void fscache_operation_dummy_cancel(struct fscache_operation *op) | |
| 24 | +{ | |
| 25 | +} | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * fscache_operation_init - Do basic initialisation of an operation | |
| 29 | + * @op: The operation to initialise | |
| 30 | + * @release: The release function to assign | |
| 31 | + * | |
| 32 | + * Do basic initialisation of an operation. The caller must still set flags, | |
| 33 | + * object and processor if needed. | |
| 34 | + */ | |
| 35 | +void fscache_operation_init(struct fscache_operation *op, | |
| 36 | + fscache_operation_processor_t processor, | |
| 37 | + fscache_operation_cancel_t cancel, | |
| 38 | + fscache_operation_release_t release) | |
| 39 | +{ | |
| 40 | + INIT_WORK(&op->work, fscache_op_work_func); | |
| 41 | + atomic_set(&op->usage, 1); | |
| 42 | + op->state = FSCACHE_OP_ST_INITIALISED; | |
| 43 | + op->debug_id = atomic_inc_return(&fscache_op_debug_id); | |
| 44 | + op->processor = processor; | |
| 45 | + op->cancel = cancel ?: fscache_operation_dummy_cancel; | |
| 46 | + op->release = release; | |
| 47 | + INIT_LIST_HEAD(&op->pend_link); | |
| 48 | + fscache_stat(&fscache_n_op_initialised); | |
| 49 | +} | |
| 50 | +EXPORT_SYMBOL(fscache_operation_init); | |
| 51 | + | |
| 23 | 52 | /** |
| 24 | 53 | * fscache_enqueue_operation - Enqueue an operation for processing |
| 25 | 54 | * @op: The operation to enqueue |
| @@ -75,6 +104,43 @@ static void fscache_run_op(struct fscache_object *object, · 49 unmodified lines | ||
| 75 | 104 | fscache_stat(&fscache_n_op_run); |
| 76 | 105 | } |
| 77 | 106 | |
| 107 | +/* | |
| 108 | + * report an unexpected submission | |
| 109 | + */ | |
| 110 | +static void fscache_report_unexpected_submission(struct fscache_object *object, | |
| 111 | + struct fscache_operation *op, | |
| 112 | + const struct fscache_state *ostate) | |
| 113 | +{ | |
| 114 | + static bool once_only; | |
| 115 | + struct fscache_operation *p; | |
| 116 | + unsigned n; | |
| 117 | + | |
| 118 | + if (once_only) | |
| 119 | + return; | |
| 120 | + once_only = true; | |
| 121 | + | |
| 122 | + kdebug("unexpected submission OP%x [OBJ%x %s]", | |
| 123 | + op->debug_id, object->debug_id, object->state->name); | |
| 124 | + kdebug("objstate=%s [%s]", object->state->name, ostate->name); | |
| 125 | + kdebug("objflags=%lx", object->flags); | |
| 126 | + kdebug("objevent=%lx [%lx]", object->events, object->event_mask); | |
| 127 | + kdebug("ops=%u inp=%u exc=%u", | |
| 128 | + object->n_ops, object->n_in_progress, object->n_exclusive); | |
| 129 | + | |
| 130 | + if (!list_empty(&object->pending_ops)) { | |
| 131 | + n = 0; | |
| 132 | + list_for_each_entry(p, &object->pending_ops, pend_link) { | |
| 133 | + ASSERTCMP(p->object, ==, object); | |
| 134 | + kdebug("%p %p", op->processor, op->release); | |
| 135 | + n++; | |
| 136 | + } | |
| 137 | + | |
| 138 | + kdebug("n=%u", n); | |
| 139 | + } | |
| 140 | + | |
| 141 | + dump_stack(); | |
| 142 | +} | |
| 143 | + | |
| 78 | 144 | /* |
| 79 | 145 | * submit an exclusive operation for an object |
| 80 | 146 | * - other ops are excluded from running simultaneously with this one |
| @@ -83,6 +149,8 @@ static void fscache_run_op(struct fscache_object *object, · 2 unmodified lines | ||
| 83 | 149 | int fscache_submit_exclusive_op(struct fscache_object *object, |
| 84 | 150 | struct fscache_operation *op) |
| 85 | 151 | { |
| 152 | + const struct fscache_state *ostate; | |
| 153 | + unsigned long flags; | |
| 86 | 154 | int ret; |
| 87 | 155 | |
| 88 | 156 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); |
| @@ -95,8 +163,21 @@ int fscache_submit_exclusive_op(struct fscache_object *object, · 6 unmodified lines | ||
| 95 | 163 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
| 96 | 164 | ASSERT(list_empty(&op->pend_link)); |
| 97 | 165 | |
| 166 | + ostate = object->state; | |
| 167 | + smp_rmb(); | |
| 168 | + | |
| 98 | 169 | op->state = FSCACHE_OP_ST_PENDING; |
| 99 | − if (fscache_object_is_active(object)) { | |
| 170 | + flags = READ_ONCE(object->flags); | |
| 171 | + if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) { | |
| 172 | + fscache_stat(&fscache_n_op_rejected); | |
| 173 | + op->cancel(op); | |
| 174 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 175 | + ret = -ENOBUFS; | |
| 176 | + } else if (unlikely(fscache_cache_is_broken(object))) { | |
| 177 | + op->cancel(op); | |
| 178 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 179 | + ret = -EIO; | |
| 180 | + } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) { | |
| 100 | 181 | op->object = object; |
| 101 | 182 | object->n_ops++; |
| 102 | 183 | object->n_exclusive++; /* reads and writes must wait */ |
| @@ -118,7 +199,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object, · 15 unmodified lines | ||
| 118 | 199 | /* need to issue a new write op after this */ |
| 119 | 200 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); |
| 120 | 201 | ret = 0; |
| 121 | − } else if (test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags)) { | |
| 202 | + } else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) { | |
| 122 | 203 | op->object = object; |
| 123 | 204 | object->n_ops++; |
| 124 | 205 | object->n_exclusive++; /* reads and writes must wait */ |
| @@ -126,55 +207,21 @@ int fscache_submit_exclusive_op(struct fscache_object *object, · 1 unmodified line | ||
| 126 | 207 | list_add_tail(&op->pend_link, &object->pending_ops); |
| 127 | 208 | fscache_stat(&fscache_n_op_pend); |
| 128 | 209 | ret = 0; |
| 210 | + } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) { | |
| 211 | + op->cancel(op); | |
| 212 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 213 | + ret = -ENOBUFS; | |
| 129 | 214 | } else { |
| 130 | − /* If we're in any other state, there must have been an I/O | |
| 131 | − * error of some nature. | |
| 132 | − */ | |
| 133 | − ASSERT(test_bit(FSCACHE_IOERROR, &object->cache->flags)); | |
| 134 | − ret = -EIO; | |
| 215 | + fscache_report_unexpected_submission(object, op, ostate); | |
| 216 | + op->cancel(op); | |
| 217 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 218 | + ret = -ENOBUFS; | |
| 135 | 219 | } |
| 136 | 220 | |
| 137 | 221 | spin_unlock(&object->lock); |
| 138 | 222 | return ret; |
| 139 | 223 | } |
| 140 | 224 | |
| 141 | −/* | |
| 142 | − * report an unexpected submission | |
| 143 | − */ | |
| 144 | −static void fscache_report_unexpected_submission(struct fscache_object *object, | |
| 145 | − struct fscache_operation *op, | |
| 146 | − const struct fscache_state *ostate) | |
| 147 | −{ | |
| 148 | − static bool once_only; | |
| 149 | − struct fscache_operation *p; | |
| 150 | − unsigned n; | |
| 151 | − | |
| 152 | − if (once_only) | |
| 153 | − return; | |
| 154 | − once_only = true; | |
| 155 | − | |
| 156 | − kdebug("unexpected submission OP%x [OBJ%x %s]", | |
| 157 | − op->debug_id, object->debug_id, object->state->name); | |
| 158 | − kdebug("objstate=%s [%s]", object->state->name, ostate->name); | |
| 159 | − kdebug("objflags=%lx", object->flags); | |
| 160 | − kdebug("objevent=%lx [%lx]", object->events, object->event_mask); | |
| 161 | − kdebug("ops=%u inp=%u exc=%u", | |
| 162 | − object->n_ops, object->n_in_progress, object->n_exclusive); | |
| 163 | − | |
| 164 | − if (!list_empty(&object->pending_ops)) { | |
| 165 | − n = 0; | |
| 166 | − list_for_each_entry(p, &object->pending_ops, pend_link) { | |
| 167 | − ASSERTCMP(p->object, ==, object); | |
| 168 | − kdebug("%p %p", op->processor, op->release); | |
| 169 | − n++; | |
| 170 | − } | |
| 171 | − | |
| 172 | − kdebug("n=%u", n); | |
| 173 | − } | |
| 174 | − | |
| 175 | − dump_stack(); | |
| 176 | −} | |
| 177 | − | |
| 178 | 225 | /* |
| 179 | 226 | * submit an operation for an object |
| 180 | 227 | * - objects may be submitted only in the following states: |
| @@ -187,6 +234,7 @@ int fscache_submit_op(struct fscache_object *object, · 6 unmodified lines | ||
| 187 | 234 | struct fscache_operation *op) |
| 188 | 235 | { |
| 189 | 236 | const struct fscache_state *ostate; |
| 237 | + unsigned long flags; | |
| 190 | 238 | int ret; |
| 191 | 239 | |
| 192 | 240 | _enter("{OBJ%x OP%x},{%u}", |
| @@ -204,7 +252,17 @@ int fscache_submit_op(struct fscache_object *object, · 11 unmodified lines | ||
| 204 | 252 | smp_rmb(); |
| 205 | 253 | |
| 206 | 254 | op->state = FSCACHE_OP_ST_PENDING; |
| 207 | − if (fscache_object_is_active(object)) { | |
| 255 | + flags = READ_ONCE(object->flags); | |
| 256 | + if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) { | |
| 257 | + fscache_stat(&fscache_n_op_rejected); | |
| 258 | + op->cancel(op); | |
| 259 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 260 | + ret = -ENOBUFS; | |
| 261 | + } else if (unlikely(fscache_cache_is_broken(object))) { | |
| 262 | + op->cancel(op); | |
| 263 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 264 | + ret = -EIO; | |
| 265 | + } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) { | |
| 208 | 266 | op->object = object; |
| 209 | 267 | object->n_ops++; |
| 210 | 268 | |
| @@ -222,23 +280,21 @@ int fscache_submit_op(struct fscache_object *object, · 11 unmodified lines | ||
| 222 | 280 | fscache_run_op(object, op); |
| 223 | 281 | } |
| 224 | 282 | ret = 0; |
| 225 | − } else if (test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags)) { | |
| 283 | + } else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) { | |
| 226 | 284 | op->object = object; |
| 227 | 285 | object->n_ops++; |
| 228 | 286 | atomic_inc(&op->usage); |
| 229 | 287 | list_add_tail(&op->pend_link, &object->pending_ops); |
| 230 | 288 | fscache_stat(&fscache_n_op_pend); |
| 231 | 289 | ret = 0; |
| 232 | − } else if (fscache_object_is_dying(object)) { | |
| 233 | − fscache_stat(&fscache_n_op_rejected); | |
| 290 | + } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) { | |
| 291 | + op->cancel(op); | |
| 234 | 292 | op->state = FSCACHE_OP_ST_CANCELLED; |
| 235 | 293 | ret = -ENOBUFS; |
| 236 | − } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { | |
| 294 | + } else { | |
| 237 | 295 | fscache_report_unexpected_submission(object, op, ostate); |
| 238 | 296 | ASSERT(!fscache_object_is_active(object)); |
| 239 | − op->state = FSCACHE_OP_ST_CANCELLED; | |
| 240 | − ret = -ENOBUFS; | |
| 241 | − } else { | |
| 297 | + op->cancel(op); | |
| 242 | 298 | op->state = FSCACHE_OP_ST_CANCELLED; |
| 243 | 299 | ret = -ENOBUFS; |
| 244 | 300 | } |
| @@ -293,9 +349,10 @@ void fscache_start_operations(struct fscache_object *object) · 48 unmodified lines | ||
| 293 | 349 | * cancel an operation that's pending on an object |
| 294 | 350 | */ |
| 295 | 351 | int fscache_cancel_op(struct fscache_operation *op, |
| 296 | − void (*do_cancel)(struct fscache_operation *)) | |
| 352 | + bool cancel_in_progress_op) | |
| 297 | 353 | { |
| 298 | 354 | struct fscache_object *object = op->object; |
| 355 | + bool put = false; | |
| 299 | 356 | int ret; |
| 300 | 357 | |
| 301 | 358 | _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); |
| @@ -309,19 +366,37 @@ int fscache_cancel_op(struct fscache_operation *op, · 7 unmodified lines | ||
| 309 | 366 | ret = -EBUSY; |
| 310 | 367 | if (op->state == FSCACHE_OP_ST_PENDING) { |
| 311 | 368 | ASSERT(!list_empty(&op->pend_link)); |
| 312 | − fscache_stat(&fscache_n_op_cancelled); | |
| 313 | 369 | list_del_init(&op->pend_link); |
| 314 | − if (do_cancel) | |
| 315 | − do_cancel(op); | |
| 370 | + put = true; | |
| 371 | + | |
| 372 | + fscache_stat(&fscache_n_op_cancelled); | |
| 373 | + op->cancel(op); | |
| 374 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 375 | + if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) | |
| 376 | + object->n_exclusive--; | |
| 377 | + if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | |
| 378 | + wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | |
| 379 | + ret = 0; | |
| 380 | + } else if (op->state == FSCACHE_OP_ST_IN_PROGRESS && cancel_in_progress_op) { | |
| 381 | + ASSERTCMP(object->n_in_progress, >, 0); | |
| 382 | + if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) | |
| 383 | + object->n_exclusive--; | |
| 384 | + object->n_in_progress--; | |
| 385 | + if (object->n_in_progress == 0) | |
| 386 | + fscache_start_operations(object); | |
| 387 | + | |
| 388 | + fscache_stat(&fscache_n_op_cancelled); | |
| 389 | + op->cancel(op); | |
| 316 | 390 | op->state = FSCACHE_OP_ST_CANCELLED; |
| 317 | 391 | if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) |
| 318 | 392 | object->n_exclusive--; |
| 319 | 393 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) |
| 320 | 394 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); |
| 321 | − fscache_put_operation(op); | |
| 322 | 395 | ret = 0; |
| 323 | 396 | } |
| 324 | 397 | |
| 398 | + if (put) | |
| 399 | + fscache_put_operation(op); | |
| 325 | 400 | spin_unlock(&object->lock); |
| 326 | 401 | _leave(" = %d", ret); |
| 327 | 402 | return ret; |
| @@ -345,6 +420,7 @@ void fscache_cancel_all_ops(struct fscache_object *object) · 17 unmodified lines | ||
| 345 | 420 | list_del_init(&op->pend_link); |
| 346 | 421 | |
| 347 | 422 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); |
| 423 | + op->cancel(op); | |
| 348 | 424 | op->state = FSCACHE_OP_ST_CANCELLED; |
| 349 | 425 | |
| 350 | 426 | if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) |
| @@ -377,8 +453,12 @@ void fscache_op_complete(struct fscache_operation *op, bool cancelled) · 26 unmodified lines | ||
| 377 | 453 | |
| 378 | 454 | spin_lock(&object->lock); |
| 379 | 455 | |
| 380 | − op->state = cancelled ? | |
| 381 | − FSCACHE_OP_ST_CANCELLED : FSCACHE_OP_ST_COMPLETE; | |
| 456 | + if (!cancelled) { | |
| 457 | + op->state = FSCACHE_OP_ST_COMPLETE; | |
| 458 | + } else { | |
| 459 | + op->cancel(op); | |
| 460 | + op->state = FSCACHE_OP_ST_CANCELLED; | |
| 461 | + } | |
| 382 | 462 | |
| 383 | 463 | if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) |
| 384 | 464 | object->n_exclusive--; |
| @@ -409,9 +489,9 @@ void fscache_put_operation(struct fscache_operation *op) · 24 unmodified lines | ||
| 409 | 489 | return; |
| 410 | 490 | |
| 411 | 491 | _debug("PUT OP"); |
| 412 | − ASSERTIFCMP(op->state != FSCACHE_OP_ST_COMPLETE, | |
| 492 | + ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED && | |
| 493 | + op->state != FSCACHE_OP_ST_COMPLETE, | |
| 413 | 494 | op->state, ==, FSCACHE_OP_ST_CANCELLED); |
| 414 | − op->state = FSCACHE_OP_ST_DEAD; | |
| 415 | 495 | |
| 416 | 496 | fscache_stat(&fscache_n_op_release); |
| 417 | 497 | |
| @@ -419,37 +499,39 @@ void fscache_put_operation(struct fscache_operation *op) · 1 unmodified line | ||
| 419 | 499 | op->release(op); |
| 420 | 500 | op->release = NULL; |
| 421 | 501 | } |
| 502 | + op->state = FSCACHE_OP_ST_DEAD; | |
| 422 | 503 | |
| 423 | 504 | object = op->object; |
| 505 | + if (likely(object)) { | |
| 506 | + if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) | |
| 507 | + atomic_dec(&object->n_reads); | |
| 508 | + if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags)) | |
| 509 | + fscache_unuse_cookie(object); | |
| 510 | + | |
| 511 | + /* now... we may get called with the object spinlock held, so we | |
| 512 | + * complete the cleanup here only if we can immediately acquire the | |
| 513 | + * lock, and defer it otherwise */ | |
| 514 | + if (!spin_trylock(&object->lock)) { | |
| 515 | + _debug("defer put"); | |
| 516 | + fscache_stat(&fscache_n_op_deferred_release); | |
| 517 | + | |
| 518 | + cache = object->cache; | |
| 519 | + spin_lock(&cache->op_gc_list_lock); | |
| 520 | + list_add_tail(&op->pend_link, &cache->op_gc_list); | |
| 521 | + spin_unlock(&cache->op_gc_list_lock); | |
| 522 | + schedule_work(&cache->op_gc); | |
| 523 | + _leave(" [defer]"); | |
| 524 | + return; | |
| 525 | + } | |
| 424 | 526 | |
| 425 | − if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) | |
| 426 | − atomic_dec(&object->n_reads); | |
| 427 | − if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags)) | |
| 428 | − fscache_unuse_cookie(object); | |
| 429 | − | |
| 430 | − /* now... we may get called with the object spinlock held, so we | |
| 431 | − * complete the cleanup here only if we can immediately acquire the | |
| 432 | − * lock, and defer it otherwise */ | |
| 433 | − if (!spin_trylock(&object->lock)) { | |
| 434 | − _debug("defer put"); | |
| 435 | − fscache_stat(&fscache_n_op_deferred_release); | |
| 527 | + ASSERTCMP(object->n_ops, >, 0); | |
| 528 | + object->n_ops--; | |
| 529 | + if (object->n_ops == 0) | |
| 530 | + fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED); | |
| 436 | 531 | |
| 437 | − cache = object->cache; | |
| 438 | − spin_lock(&cache->op_gc_list_lock); | |
| 439 | − list_add_tail(&op->pend_link, &cache->op_gc_list); | |
| 440 | − spin_unlock(&cache->op_gc_list_lock); | |
| 441 | − schedule_work(&cache->op_gc); | |
| 442 | − _leave(" [defer]"); | |
| 443 | − return; | |
| 532 | + spin_unlock(&object->lock); | |
| 444 | 533 | } |
| 445 | 534 | |
| 446 | − ASSERTCMP(object->n_ops, >, 0); | |
| 447 | − object->n_ops--; | |
| 448 | − if (object->n_ops == 0) | |
| 449 | − fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED); | |
| 450 | − | |
| 451 | − spin_unlock(&object->lock); | |
| 452 | − | |
| 453 | 535 | kfree(op); |
| 454 | 536 | _leave(" [done]"); |
| 455 | 537 | } |
| @@ -213,7 +213,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) · 212 unmodified lines | ||
| 213 | 213 | return -ENOMEM; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | − fscache_operation_init(op, fscache_attr_changed_op, NULL); | |
| 216 | + fscache_operation_init(op, fscache_attr_changed_op, NULL, NULL); | |
| 217 | 217 | op->flags = FSCACHE_OP_ASYNC | |
| 218 | 218 | (1 << FSCACHE_OP_EXCLUSIVE) | |
| 219 | 219 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
| @@ -239,7 +239,7 @@ nobufs_dec: · 19 unmodified lines | ||
| 239 | 239 | wake_cookie = __fscache_unuse_cookie(cookie); |
| 240 | 240 | nobufs: |
| 241 | 241 | spin_unlock(&cookie->lock); |
| 242 | − kfree(op); | |
| 242 | + fscache_put_operation(op); | |
| 243 | 243 | if (wake_cookie) |
| 244 | 244 | __fscache_wake_unused_cookie(cookie); |
| 245 | 245 | fscache_stat(&fscache_n_attr_changed_nobufs); |
| @@ -248,6 +248,17 @@ nobufs: · 2 unmodified lines | ||
| 248 | 248 | } |
| 249 | 249 | EXPORT_SYMBOL(__fscache_attr_changed); |
| 250 | 250 | |
| 251 | +/* | |
| 252 | + * Handle cancellation of a pending retrieval op | |
| 253 | + */ | |
| 254 | +static void fscache_do_cancel_retrieval(struct fscache_operation *_op) | |
| 255 | +{ | |
| 256 | + struct fscache_retrieval *op = | |
| 257 | + container_of(_op, struct fscache_retrieval, op); | |
| 258 | + | |
| 259 | + atomic_set(&op->n_pages, 0); | |
| 260 | +} | |
| 261 | + | |
| 251 | 262 | /* |
| 252 | 263 | * release a retrieval op reference |
| 253 | 264 | */ |
| @@ -258,11 +269,12 @@ static void fscache_release_retrieval_op(struct fscache_operation *_op) · 4 unmodified lines | ||
| 258 | 269 | |
| 259 | 270 | _enter("{OP%x}", op->op.debug_id); |
| 260 | 271 | |
| 261 | − ASSERTCMP(atomic_read(&op->n_pages), ==, 0); | |
| 272 | + ASSERTIFCMP(op->op.state != FSCACHE_OP_ST_INITIALISED, | |
| 273 | + atomic_read(&op->n_pages), ==, 0); | |
| 262 | 274 | |
| 263 | 275 | fscache_hist(fscache_retrieval_histogram, op->start_time); |
| 264 | 276 | if (op->context) |
| 265 | − fscache_put_context(op->op.object->cookie, op->context); | |
| 277 | + fscache_put_context(op->cookie, op->context); | |
| 266 | 278 | |
| 267 | 279 | _leave(""); |
| 268 | 280 | } |
| @@ -285,15 +297,24 @@ static struct fscache_retrieval *fscache_alloc_retrieval( · 16 unmodified lines | ||
| 285 | 297 | return NULL; |
| 286 | 298 | } |
| 287 | 299 | |
| 288 | − fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op); | |
| 300 | + fscache_operation_init(&op->op, NULL, | |
| 301 | + fscache_do_cancel_retrieval, | |
| 302 | + fscache_release_retrieval_op); | |
| 289 | 303 | op->op.flags = FSCACHE_OP_MYTHREAD | |
| 290 | 304 | (1UL << FSCACHE_OP_WAITING) | |
| 291 | 305 | (1UL << FSCACHE_OP_UNUSE_COOKIE); |
| 306 | + op->cookie = cookie; | |
| 292 | 307 | op->mapping = mapping; |
| 293 | 308 | op->end_io_func = end_io_func; |
| 294 | 309 | op->context = context; |
| 295 | 310 | op->start_time = jiffies; |
| 296 | 311 | INIT_LIST_HEAD(&op->to_do); |
| 312 | + | |
| 313 | + /* Pin the netfs read context in case we need to do the actual netfs | |
| 314 | + * read because we've encountered a cache read failure. | |
| 315 | + */ | |
| 316 | + if (context) | |
| 317 | + fscache_get_context(op->cookie, context); | |
| 297 | 318 | return op; |
| 298 | 319 | } |
| 299 | 320 | |
| @@ -329,25 +350,13 @@ int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie) · 29 unmodified lines | ||
| 329 | 350 | return 0; |
| 330 | 351 | } |
| 331 | 352 | |
| 332 | −/* | |
| 333 | − * Handle cancellation of a pending retrieval op | |
| 334 | − */ | |
| 335 | −static void fscache_do_cancel_retrieval(struct fscache_operation *_op) | |
| 336 | −{ | |
| 337 | − struct fscache_retrieval *op = | |
| 338 | − container_of(_op, struct fscache_retrieval, op); | |
| 339 | − | |
| 340 | − atomic_set(&op->n_pages, 0); | |
| 341 | −} | |
| 342 | − | |
| 343 | 353 | /* |
| 344 | 354 | * wait for an object to become active (or dead) |
| 345 | 355 | */ |
| 346 | 356 | int fscache_wait_for_operation_activation(struct fscache_object *object, |
| 347 | 357 | struct fscache_operation *op, |
| 348 | 358 | atomic_t *stat_op_waits, |
| 349 | − atomic_t *stat_object_dead, | |
| 350 | − void (*do_cancel)(struct fscache_operation *)) | |
| 359 | + atomic_t *stat_object_dead) | |
| 351 | 360 | { |
| 352 | 361 | int ret; |
| 353 | 362 | |
| @@ -359,7 +368,7 @@ int fscache_wait_for_operation_activation(struct fscache_object *object, · 5 unmodified lines | ||
| 359 | 368 | fscache_stat(stat_op_waits); |
| 360 | 369 | if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING, |
| 361 | 370 | TASK_INTERRUPTIBLE) != 0) { |
| 362 | − ret = fscache_cancel_op(op, do_cancel); | |
| 371 | + ret = fscache_cancel_op(op, false); | |
| 363 | 372 | if (ret == 0) |
| 364 | 373 | return -ERESTARTSYS; |
| 365 | 374 | |
| @@ -377,11 +386,13 @@ check_if_dead: · 11 unmodified lines | ||
| 377 | 386 | _leave(" = -ENOBUFS [cancelled]"); |
| 378 | 387 | return -ENOBUFS; |
| 379 | 388 | } |
| 380 | − if (unlikely(fscache_object_is_dead(object))) { | |
| 381 | − pr_err("%s() = -ENOBUFS [obj dead %d]\n", __func__, op->state); | |
| 382 | − fscache_cancel_op(op, do_cancel); | |
| 389 | + if (unlikely(fscache_object_is_dying(object) || | |
| 390 | + fscache_cache_is_broken(object))) { | |
| 391 | + enum fscache_operation_state state = op->state; | |
| 392 | + fscache_cancel_op(op, true); | |
| 383 | 393 | if (stat_object_dead) |
| 384 | 394 | fscache_stat(stat_object_dead); |
| 395 | + _leave(" = -ENOBUFS [obj dead %d]", state); | |
| 385 | 396 | return -ENOBUFS; |
| 386 | 397 | } |
| 387 | 398 | return 0; |
| @@ -453,17 +464,12 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, · 65 unmodified lines | ||
| 453 | 464 | |
| 454 | 465 | fscache_stat(&fscache_n_retrieval_ops); |
| 455 | 466 | |
| 456 | − /* pin the netfs read context in case we need to do the actual netfs | |
| 457 | − * read because we've encountered a cache read failure */ | |
| 458 | − fscache_get_context(object->cookie, op->context); | |
| 459 | − | |
| 460 | 467 | /* we wait for the operation to become active, and then process it |
| 461 | 468 | * *here*, in this thread, and not in the thread pool */ |
| 462 | 469 | ret = fscache_wait_for_operation_activation( |
| 463 | 470 | object, &op->op, |
| 464 | 471 | __fscache_stat(&fscache_n_retrieval_op_waits), |
| 465 | − __fscache_stat(&fscache_n_retrievals_object_dead), | |
| 466 | − fscache_do_cancel_retrieval); | |
| 472 | + __fscache_stat(&fscache_n_retrievals_object_dead)); | |
| 467 | 473 | if (ret < 0) |
| 468 | 474 | goto error; |
| 469 | 475 | |
| @@ -503,7 +509,7 @@ nobufs_unlock: · 33 unmodified lines | ||
| 503 | 509 | spin_unlock(&cookie->lock); |
| 504 | 510 | if (wake_cookie) |
| 505 | 511 | __fscache_wake_unused_cookie(cookie); |
| 506 | − kfree(op); | |
| 512 | + fscache_put_retrieval(op); | |
| 507 | 513 | nobufs: |
| 508 | 514 | fscache_stat(&fscache_n_retrievals_nobufs); |
| 509 | 515 | _leave(" = -ENOBUFS"); |
| @@ -584,17 +590,12 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, · 74 unmodified lines | ||
| 584 | 590 | |
| 585 | 591 | fscache_stat(&fscache_n_retrieval_ops); |
| 586 | 592 | |
| 587 | − /* pin the netfs read context in case we need to do the actual netfs | |
| 588 | − * read because we've encountered a cache read failure */ | |
| 589 | − fscache_get_context(object->cookie, op->context); | |
| 590 | − | |
| 591 | 593 | /* we wait for the operation to become active, and then process it |
| 592 | 594 | * *here*, in this thread, and not in the thread pool */ |
| 593 | 595 | ret = fscache_wait_for_operation_activation( |
| 594 | 596 | object, &op->op, |
| 595 | 597 | __fscache_stat(&fscache_n_retrieval_op_waits), |
| 596 | − __fscache_stat(&fscache_n_retrievals_object_dead), | |
| 597 | − fscache_do_cancel_retrieval); | |
| 598 | + __fscache_stat(&fscache_n_retrievals_object_dead)); | |
| 598 | 599 | if (ret < 0) |
| 599 | 600 | goto error; |
| 600 | 601 | |
| @@ -632,7 +633,7 @@ nobufs_unlock_dec: · 31 unmodified lines | ||
| 632 | 633 | wake_cookie = __fscache_unuse_cookie(cookie); |
| 633 | 634 | nobufs_unlock: |
| 634 | 635 | spin_unlock(&cookie->lock); |
| 635 | − kfree(op); | |
| 636 | + fscache_put_retrieval(op); | |
| 636 | 637 | if (wake_cookie) |
| 637 | 638 | __fscache_wake_unused_cookie(cookie); |
| 638 | 639 | nobufs: |
| @@ -700,8 +701,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, · 61 unmodified lines | ||
| 700 | 701 | ret = fscache_wait_for_operation_activation( |
| 701 | 702 | object, &op->op, |
| 702 | 703 | __fscache_stat(&fscache_n_alloc_op_waits), |
| 703 | − __fscache_stat(&fscache_n_allocs_object_dead), | |
| 704 | − fscache_do_cancel_retrieval); | |
| 704 | + __fscache_stat(&fscache_n_allocs_object_dead)); | |
| 705 | 705 | if (ret < 0) |
| 706 | 706 | goto error; |
| 707 | 707 | |
| @@ -726,7 +726,7 @@ nobufs_unlock_dec: · 18 unmodified lines | ||
| 726 | 726 | wake_cookie = __fscache_unuse_cookie(cookie); |
| 727 | 727 | nobufs_unlock: |
| 728 | 728 | spin_unlock(&cookie->lock); |
| 729 | − kfree(op); | |
| 729 | + fscache_put_retrieval(op); | |
| 730 | 730 | if (wake_cookie) |
| 731 | 731 | __fscache_wake_unused_cookie(cookie); |
| 732 | 732 | nobufs: |
| @@ -944,7 +944,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, · 211 unmodified lines | ||
| 944 | 944 | if (!op) |
| 945 | 945 | goto nomem; |
| 946 | 946 | |
| 947 | − fscache_operation_init(&op->op, fscache_write_op, | |
| 947 | + fscache_operation_init(&op->op, fscache_write_op, NULL, | |
| 948 | 948 | fscache_release_write_op); |
| 949 | 949 | op->op.flags = FSCACHE_OP_ASYNC | |
| 950 | 950 | (1 << FSCACHE_OP_WAITING) | |
| @@ -1016,7 +1016,7 @@ already_pending: · 65 unmodified lines | ||
| 1016 | 1016 | spin_unlock(&object->lock); |
| 1017 | 1017 | spin_unlock(&cookie->lock); |
| 1018 | 1018 | radix_tree_preload_end(); |
| 1019 | − kfree(op); | |
| 1019 | + fscache_put_operation(&op->op); | |
| 1020 | 1020 | fscache_stat(&fscache_n_stores_ok); |
| 1021 | 1021 | _leave(" = 0"); |
| 1022 | 1022 | return 0; |
| @@ -1036,7 +1036,7 @@ nobufs_unlock_obj: · 13 unmodified lines | ||
| 1036 | 1036 | nobufs: |
| 1037 | 1037 | spin_unlock(&cookie->lock); |
| 1038 | 1038 | radix_tree_preload_end(); |
| 1039 | − kfree(op); | |
| 1039 | + fscache_put_operation(&op->op); | |
| 1040 | 1040 | if (wake_cookie) |
| 1041 | 1041 | __fscache_wake_unused_cookie(cookie); |
| 1042 | 1042 | fscache_stat(&fscache_n_stores_nobufs); |
| @@ -1044,7 +1044,7 @@ nobufs: · 1 unmodified line | ||
| 1044 | 1044 | return -ENOBUFS; |
| 1045 | 1045 | |
| 1046 | 1046 | nomem_free: |
| 1047 | − kfree(op); | |
| 1047 | + fscache_put_operation(&op->op); | |
| 1048 | 1048 | nomem: |
| 1049 | 1049 | fscache_stat(&fscache_n_stores_oom); |
| 1050 | 1050 | _leave(" = -ENOMEM"); |
| @@ -23,6 +23,7 @@ atomic_t fscache_n_op_run; · 22 unmodified lines | ||
| 23 | 23 | atomic_t fscache_n_op_enqueue; |
| 24 | 24 | atomic_t fscache_n_op_requeue; |
| 25 | 25 | atomic_t fscache_n_op_deferred_release; |
| 26 | +atomic_t fscache_n_op_initialised; | |
| 26 | 27 | atomic_t fscache_n_op_release; |
| 27 | 28 | atomic_t fscache_n_op_gc; |
| 28 | 29 | atomic_t fscache_n_op_cancelled; |
| @@ -130,6 +131,11 @@ atomic_t fscache_n_cop_write_page; · 101 unmodified lines | ||
| 130 | 131 | atomic_t fscache_n_cop_uncache_page; |
| 131 | 132 | atomic_t fscache_n_cop_dissociate_pages; |
| 132 | 133 | |
| 134 | +atomic_t fscache_n_cache_no_space_reject; | |
| 135 | +atomic_t fscache_n_cache_stale_objects; | |
| 136 | +atomic_t fscache_n_cache_retired_objects; | |
| 137 | +atomic_t fscache_n_cache_culled_objects; | |
| 138 | + | |
| 133 | 139 | /* |
| 134 | 140 | * display the general statistics |
| 135 | 141 | */ |
| @@ -246,7 +252,8 @@ static int fscache_stats_show(struct seq_file *m, void *v) · 110 unmodified lines | ||
| 246 | 252 | atomic_read(&fscache_n_op_enqueue), |
| 247 | 253 | atomic_read(&fscache_n_op_cancelled), |
| 248 | 254 | atomic_read(&fscache_n_op_rejected)); |
| 249 | − seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", | |
| 255 | + seq_printf(m, "Ops : ini=%u dfr=%u rel=%u gc=%u\n", | |
| 256 | + atomic_read(&fscache_n_op_initialised), | |
| 250 | 257 | atomic_read(&fscache_n_op_deferred_release), |
| 251 | 258 | atomic_read(&fscache_n_op_release), |
| 252 | 259 | atomic_read(&fscache_n_op_gc)); |
| @@ -271,6 +278,11 @@ static int fscache_stats_show(struct seq_file *m, void *v) · 18 unmodified lines | ||
| 271 | 278 | atomic_read(&fscache_n_cop_write_page), |
| 272 | 279 | atomic_read(&fscache_n_cop_uncache_page), |
| 273 | 280 | atomic_read(&fscache_n_cop_dissociate_pages)); |
| 281 | + seq_printf(m, "CacheEv: nsp=%d stl=%d rtr=%d cul=%d\n", | |
| 282 | + atomic_read(&fscache_n_cache_no_space_reject), | |
| 283 | + atomic_read(&fscache_n_cache_stale_objects), | |
| 284 | + atomic_read(&fscache_n_cache_retired_objects), | |
| 285 | + atomic_read(&fscache_n_cache_culled_objects)); | |
| 274 | 286 | return 0; |
| 275 | 287 | } |
| 276 | 288 | |
| @@ -1169,7 +1169,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from) · 1168 unmodified lines | ||
| 1169 | 1169 | if (err <= 0) |
| 1170 | 1170 | goto out; |
| 1171 | 1171 | |
| 1172 | − err = file_remove_suid(file); | |
| 1172 | + err = file_remove_privs(file); | |
| 1173 | 1173 | if (err) |
| 1174 | 1174 | goto out; |
| 1175 | 1175 | |
| @@ -252,7 +252,7 @@ extern void hfs_mark_mdb_dirty(struct super_block *sb); · 251 unmodified lines | ||
| 252 | 252 | #define __hfs_u_to_mtime(sec) cpu_to_be32(sec + 2082844800U - sys_tz.tz_minuteswest * 60) |
| 253 | 253 | #define __hfs_m_to_utime(sec) (be32_to_cpu(sec) - 2082844800U + sys_tz.tz_minuteswest * 60) |
| 254 | 254 | |
| 255 | −#define HFS_I(inode) (list_entry(inode, struct hfs_inode_info, vfs_inode)) | |
| 255 | +#define HFS_I(inode) (container_of(inode, struct hfs_inode_info, vfs_inode)) | |
| 256 | 256 | #define HFS_SB(sb) ((struct hfs_sb_info *)(sb)->s_fs_info) |
| 257 | 257 | |
| 258 | 258 | #define hfs_m_to_utime(time) (struct timespec){ .tv_sec = __hfs_m_to_utime(time) } |
| @@ -263,7 +263,7 @@ struct hfsplus_inode_info { · 262 unmodified lines | ||
| 263 | 263 | |
| 264 | 264 | static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode) |
| 265 | 265 | { |
| 266 | − return list_entry(inode, struct hfsplus_inode_info, vfs_inode); | |
| 266 | + return container_of(inode, struct hfsplus_inode_info, vfs_inode); | |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | 269 | /* |
| @@ -304,7 +304,7 @@ extern const struct address_space_operations hpfs_symlink_aops; · 303 unmodified lines | ||
| 304 | 304 | |
| 305 | 305 | static inline struct hpfs_inode_info *hpfs_i(struct inode *inode) |
| 306 | 306 | { |
| 307 | − return list_entry(inode, struct hpfs_inode_info, vfs_inode); | |
| 307 | + return container_of(inode, struct hpfs_inode_info, vfs_inode); | |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | 310 | static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb) |
| @@ -841,7 +841,11 @@ unsigned int get_next_ino(void) · 840 unmodified lines | ||
| 841 | 841 | } |
| 842 | 842 | #endif |
| 843 | 843 | |
| 844 | − *p = ++res; | |
| 844 | + res++; | |
| 845 | + /* get_next_ino should not provide a 0 inode number */ | |
| 846 | + if (unlikely(!res)) | |
| 847 | + res++; | |
| 848 | + *p = res; | |
| 845 | 849 | put_cpu_var(last_ino); |
| 846 | 850 | return res; |
| 847 | 851 | } |
| @@ -1674,7 +1678,31 @@ int should_remove_suid(struct dentry *dentry) · 826 unmodified lines | ||
| 1674 | 1678 | } |
| 1675 | 1679 | EXPORT_SYMBOL(should_remove_suid); |
| 1676 | 1680 | |
| 1677 | −static int __remove_suid(struct dentry *dentry, int kill) | |
| 1681 | +/* | |
| 1682 | + * Return mask of changes for notify_change() that need to be done as a | |
| 1683 | + * response to write or truncate. Return 0 if nothing has to be changed. | |
| 1684 | + * Negative value on error (change should be denied). | |
| 1685 | + */ | |
| 1686 | +int dentry_needs_remove_privs(struct dentry *dentry) | |
| 1687 | +{ | |
| 1688 | + struct inode *inode = d_inode(dentry); | |
| 1689 | + int mask = 0; | |
| 1690 | + int ret; | |
| 1691 | + | |
| 1692 | + if (IS_NOSEC(inode)) | |
| 1693 | + return 0; | |
| 1694 | + | |
| 1695 | + mask = should_remove_suid(dentry); | |
| 1696 | + ret = security_inode_need_killpriv(dentry); | |
| 1697 | + if (ret < 0) | |
| 1698 | + return ret; | |
| 1699 | + if (ret) | |
| 1700 | + mask |= ATTR_KILL_PRIV; | |
| 1701 | + return mask; | |
| 1702 | +} | |
| 1703 | +EXPORT_SYMBOL(dentry_needs_remove_privs); | |
| 1704 | + | |
| 1705 | +static int __remove_privs(struct dentry *dentry, int kill) | |
| 1678 | 1706 | { |
| 1679 | 1707 | struct iattr newattrs; |
| 1680 | 1708 | |
| @@ -1686,33 +1714,32 @@ static int __remove_suid(struct dentry *dentry, int kill) · 5 unmodified lines | ||
| 1686 | 1714 | return notify_change(dentry, &newattrs, NULL); |
| 1687 | 1715 | } |
| 1688 | 1716 | |
| 1689 | −int file_remove_suid(struct file *file) | |
| 1717 | +/* | |
| 1718 | + * Remove special file priviledges (suid, capabilities) when file is written | |
| 1719 | + * to or truncated. | |
| 1720 | + */ | |
| 1721 | +int file_remove_privs(struct file *file) | |
| 1690 | 1722 | { |
| 1691 | 1723 | struct dentry *dentry = file->f_path.dentry; |
| 1692 | 1724 | struct inode *inode = d_inode(dentry); |
| 1693 | − int killsuid; | |
| 1694 | − int killpriv; | |
| 1725 | + int kill; | |
| 1695 | 1726 | int error = 0; |
| 1696 | 1727 | |
| 1697 | 1728 | /* Fast path for nothing security related */ |
| 1698 | 1729 | if (IS_NOSEC(inode)) |
| 1699 | 1730 | return 0; |
| 1700 | 1731 | |
| 1701 | − killsuid = should_remove_suid(dentry); | |
| 1702 | − killpriv = security_inode_need_killpriv(dentry); | |
| 1703 | − | |
| 1704 | − if (killpriv < 0) | |
| 1705 | − return killpriv; | |
| 1706 | − if (killpriv) | |
| 1707 | − error = security_inode_killpriv(dentry); | |
| 1708 | − if (!error && killsuid) | |
| 1709 | − error = __remove_suid(dentry, killsuid); | |
| 1710 | − if (!error && (inode->i_sb->s_flags & MS_NOSEC)) | |
| 1711 | − inode->i_flags |= S_NOSEC; | |
| 1732 | + kill = file_needs_remove_privs(file); | |
| 1733 | + if (kill < 0) | |
| 1734 | + return kill; | |
| 1735 | + if (kill) | |
| 1736 | + error = __remove_privs(dentry, kill); | |
| 1737 | + if (!error) | |
| 1738 | + inode_has_no_xattr(inode); | |
| 1712 | 1739 | |
| 1713 | 1740 | return error; |
| 1714 | 1741 | } |
| 1715 | −EXPORT_SYMBOL(file_remove_suid); | |
| 1742 | +EXPORT_SYMBOL(file_remove_privs); | |
| 1716 | 1743 | |
| 1717 | 1744 | /** |
| 1718 | 1745 | * file_update_time - update mtime and ctime time |
| @@ -1967,9 +1994,8 @@ EXPORT_SYMBOL(inode_dio_wait); · 248 unmodified lines | ||
| 1967 | 1994 | * inode is being instantiated). The reason for the cmpxchg() loop |
| 1968 | 1995 | * --- which wouldn't be necessary if all code paths which modify |
| 1969 | 1996 | * i_flags actually followed this rule, is that there is at least one |
| 1970 | − * code path which doesn't today --- for example, | |
| 1971 | − * __generic_file_aio_write() calls file_remove_suid() without holding | |
| 1972 | − * i_mutex --- so we use cmpxchg() out of an abundance of caution. | |
| 1997 | + * code path which doesn't today so we use cmpxchg() out of an abundance | |
| 1998 | + * of caution. | |
| 1973 | 1999 | * |
| 1974 | 2000 | * In the long run, i_mutex is overkill, and we should probably look |
| 1975 | 2001 | * at using the i_lock spinlock to protect i_flags, and then make sure |
| @@ -107,6 +107,7 @@ extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, · 106 unmodified lines | ||
| 107 | 107 | extern long do_handle_open(int mountdirfd, |
| 108 | 108 | struct file_handle __user *ufh, int open_flag); |
| 109 | 109 | extern int open_check_o_direct(struct file *f); |
| 110 | +extern int vfs_open(const struct path *, struct file *, const struct cred *); | |
| 110 | 111 | |
| 111 | 112 | /* |
| 112 | 113 | * inode.c |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | struct kstatfs; |
| 20 | 20 | struct kvec; |
| 21 | 21 | |
| 22 | −#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode)) | |
| 22 | +#define JFFS2_INODE_INFO(i) (container_of(i, struct jffs2_inode_info, vfs_inode)) | |
| 23 | 23 | #define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode) |
| 24 | 24 | #define JFFS2_SB_INFO(sb) (sb->s_fs_info) |
| 25 | 25 | #define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv) |
| @@ -206,7 +206,7 @@ struct jfs_sb_info { · 205 unmodified lines | ||
| 206 | 206 | |
| 207 | 207 | static inline struct jfs_inode_info *JFS_IP(struct inode *inode) |
| 208 | 208 | { |
| 209 | − return list_entry(inode, struct jfs_inode_info, vfs_inode); | |
| 209 | + return container_of(inode, struct jfs_inode_info, vfs_inode); | |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | 212 | static inline int jfs_dirtable_inline(struct inode *inode) |
| @@ -20,11 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include "internal.h" |
| 22 | 22 | |
| 23 | −static inline int simple_positive(struct dentry *dentry) | |
| 24 | −{ | |
| 25 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 26 | −} | |
| 27 | − | |
| 28 | 23 | int simple_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| 29 | 24 | struct kstat *stat) |
| 30 | 25 | { |
| @@ -45,11 +45,6 @@ minix_last_byte(struct inode *inode, unsigned long page_nr) · 44 unmodified lines | ||
| 45 | 45 | return last_byte; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 49 | −{ | |
| 50 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 51 | −} | |
| 52 | − | |
| 53 | 48 | static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) |
| 54 | 49 | { |
| 55 | 50 | struct address_space *mapping = page->mapping; |
| @@ -84,7 +84,7 @@ static inline struct minix_sb_info *minix_sb(struct super_block *sb) · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | static inline struct minix_inode_info *minix_i(struct inode *inode) |
| 86 | 86 | { |
| 87 | − return list_entry(inode, struct minix_inode_info, vfs_inode); | |
| 87 | + return container_of(inode, struct minix_inode_info, vfs_inode); | |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize) |
| @@ -792,7 +792,7 @@ static void set_root(struct nameidata *nd) · 791 unmodified lines | ||
| 792 | 792 | get_fs_root(current->fs, &nd->root); |
| 793 | 793 | } |
| 794 | 794 | |
| 795 | −static unsigned set_root_rcu(struct nameidata *nd) | |
| 795 | +static void set_root_rcu(struct nameidata *nd) | |
| 796 | 796 | { |
| 797 | 797 | struct fs_struct *fs = current->fs; |
| 798 | 798 | unsigned seq; |
| @@ -802,7 +802,6 @@ static unsigned set_root_rcu(struct nameidata *nd) · 3 unmodified lines | ||
| 802 | 802 | nd->root = fs->root; |
| 803 | 803 | nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq); |
| 804 | 804 | } while (read_seqcount_retry(&fs->seq, seq)); |
| 805 | − return nd->root_seq; | |
| 806 | 805 | } |
| 807 | 806 | |
| 808 | 807 | static void path_put_conditional(struct path *path, struct nameidata *nd) |
| @@ -1998,7 +1997,8 @@ static const char *path_init(struct nameidata *nd, unsigned flags) · 1189 unmodified lines | ||
| 1998 | 1997 | if (*s == '/') { |
| 1999 | 1998 | if (flags & LOOKUP_RCU) { |
| 2000 | 1999 | rcu_read_lock(); |
| 2001 | − nd->seq = set_root_rcu(nd); | |
| 2000 | + set_root_rcu(nd); | |
| 2001 | + nd->seq = nd->root_seq; | |
| 2002 | 2002 | } else { |
| 2003 | 2003 | set_root(nd); |
| 2004 | 2004 | path_get(&nd->root); |
| @@ -1145,6 +1145,8 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, · 1144 unmodified lines | ||
| 1145 | 1145 | case 0x00: |
| 1146 | 1146 | ncp_dbg(1, "renamed %pd -> %pd\n", |
| 1147 | 1147 | old_dentry, new_dentry); |
| 1148 | + ncp_d_prune(old_dentry); | |
| 1149 | + ncp_d_prune(new_dentry); | |
| 1148 | 1150 | break; |
| 1149 | 1151 | case 0x9E: |
| 1150 | 1152 | error = -ENAMETOOLONG; |
| @@ -1768,7 +1768,7 @@ EXPORT_SYMBOL_GPL(nfs_mkdir); · 1767 unmodified lines | ||
| 1768 | 1768 | |
| 1769 | 1769 | static void nfs_dentry_handle_enoent(struct dentry *dentry) |
| 1770 | 1770 | { |
| 1771 | − if (d_really_is_positive(dentry) && !d_unhashed(dentry)) | |
| 1771 | + if (simple_positive(dentry)) | |
| 1772 | 1772 | d_delete(dentry); |
| 1773 | 1773 | } |
| 1774 | 1774 | |
| @@ -61,11 +61,6 @@ static inline void nilfs_put_page(struct page *page) · 60 unmodified lines | ||
| 61 | 61 | page_cache_release(page); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 65 | −{ | |
| 66 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 67 | −} | |
| 68 | − | |
| 69 | 64 | /* |
| 70 | 65 | * Return the offset into page `page_nr' of the last valid |
| 71 | 66 | * byte in that page, plus one. |
| @@ -307,31 +307,13 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, · 306 unmodified lines | ||
| 307 | 307 | static ssize_t |
| 308 | 308 | nilfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) |
| 309 | 309 | { |
| 310 | − struct file *file = iocb->ki_filp; | |
| 311 | − struct address_space *mapping = file->f_mapping; | |
| 312 | − struct inode *inode = file->f_mapping->host; | |
| 313 | − size_t count = iov_iter_count(iter); | |
| 314 | − ssize_t size; | |
| 310 | + struct inode *inode = file_inode(iocb->ki_filp); | |
| 315 | 311 | |
| 316 | 312 | if (iov_iter_rw(iter) == WRITE) |
| 317 | 313 | return 0; |
| 318 | 314 | |
| 319 | 315 | /* Needs synchronization with the cleaner */ |
| 320 | − size = blockdev_direct_IO(iocb, inode, iter, offset, nilfs_get_block); | |
| 321 | − | |
| 322 | − /* | |
| 323 | − * In case of error extending write may have instantiated a few | |
| 324 | − * blocks outside i_size. Trim these off again. | |
| 325 | − */ | |
| 326 | − if (unlikely(iov_iter_rw(iter) == WRITE && size < 0)) { | |
| 327 | − loff_t isize = i_size_read(inode); | |
| 328 | − loff_t end = offset + count; | |
| 329 | − | |
| 330 | − if (end > isize) | |
| 331 | − nilfs_write_failed(mapping, end); | |
| 332 | − } | |
| 333 | − | |
| 334 | − return size; | |
| 316 | + return blockdev_direct_IO(iocb, inode, iter, offset, nilfs_get_block); | |
| 335 | 317 | } |
| 336 | 318 | |
| 337 | 319 | const struct address_space_operations nilfs_aops = { |
| @@ -382,7 +382,7 @@ static ssize_t ntfs_prepare_file_for_write(struct kiocb *iocb, · 381 unmodified lines | ||
| 382 | 382 | base_ni = ni; |
| 383 | 383 | if (NInoAttr(ni)) |
| 384 | 384 | base_ni = ni->ext.base_ntfs_ino; |
| 385 | − err = file_remove_suid(file); | |
| 385 | + err = file_remove_privs(file); | |
| 386 | 386 | if (unlikely(err)) |
| 387 | 387 | goto out; |
| 388 | 388 | /* |
| @@ -239,7 +239,7 @@ typedef struct { · 238 unmodified lines | ||
| 239 | 239 | */ |
| 240 | 240 | static inline ntfs_inode *NTFS_I(struct inode *inode) |
| 241 | 241 | { |
| 242 | − return (ntfs_inode *)list_entry(inode, big_ntfs_inode, vfs_inode); | |
| 242 | + return (ntfs_inode *)container_of(inode, big_ntfs_inode, vfs_inode); | |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | static inline struct inode *VFS_I(ntfs_inode *ni) |
| @@ -51,8 +51,10 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, · 50 unmodified lines | ||
| 51 | 51 | newattrs.ia_valid |= ATTR_FILE; |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | − /* Remove suid/sgid on truncate too */ | |
| 55 | − ret = should_remove_suid(dentry); | |
| 54 | + /* Remove suid, sgid, and file capabilities on truncate too */ | |
| 55 | + ret = dentry_needs_remove_privs(dentry); | |
| 56 | + if (ret < 0) | |
| 57 | + return ret; | |
| 56 | 58 | if (ret) |
| 57 | 59 | newattrs.ia_valid |= ret | ATTR_FORCE; |
| 58 | 60 | |
| @@ -678,18 +680,18 @@ int open_check_o_direct(struct file *f) · 619 unmodified lines | ||
| 678 | 680 | } |
| 679 | 681 | |
| 680 | 682 | static int do_dentry_open(struct file *f, |
| 683 | + struct inode *inode, | |
| 681 | 684 | int (*open)(struct inode *, struct file *), |
| 682 | 685 | const struct cred *cred) |
| 683 | 686 | { |
| 684 | 687 | static const struct file_operations empty_fops = {}; |
| 685 | − struct inode *inode; | |
| 686 | 688 | int error; |
| 687 | 689 | |
| 688 | 690 | f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK | |
| 689 | 691 | FMODE_PREAD | FMODE_PWRITE; |
| 690 | 692 | |
| 691 | 693 | path_get(&f->f_path); |
| 692 | − inode = f->f_inode = f->f_path.dentry->d_inode; | |
| 694 | + f->f_inode = inode; | |
| 693 | 695 | f->f_mapping = inode->i_mapping; |
| 694 | 696 | |
| 695 | 697 | if (unlikely(f->f_flags & O_PATH)) { |
| @@ -793,7 +795,8 @@ int finish_open(struct file *file, struct dentry *dentry, · 97 unmodified lines | ||
| 793 | 795 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ |
| 794 | 796 | |
| 795 | 797 | file->f_path.dentry = dentry; |
| 796 | − error = do_dentry_open(file, open, current_cred()); | |
| 798 | + error = do_dentry_open(file, d_backing_inode(dentry), open, | |
| 799 | + current_cred()); | |
| 797 | 800 | if (!error) |
| 798 | 801 | *opened |= FILE_OPENED; |
| 799 | 802 | |
| @@ -822,6 +825,34 @@ int finish_no_open(struct file *file, struct dentry *dentry) · 22 unmodified lines | ||
| 822 | 825 | } |
| 823 | 826 | EXPORT_SYMBOL(finish_no_open); |
| 824 | 827 | |
| 828 | +char *file_path(struct file *filp, char *buf, int buflen) | |
| 829 | +{ | |
| 830 | + return d_path(&filp->f_path, buf, buflen); | |
| 831 | +} | |
| 832 | +EXPORT_SYMBOL(file_path); | |
| 833 | + | |
| 834 | +/** | |
| 835 | + * vfs_open - open the file at the given path | |
| 836 | + * @path: path to open | |
| 837 | + * @file: newly allocated file with f_flag initialized | |
| 838 | + * @cred: credentials to use | |
| 839 | + */ | |
| 840 | +int vfs_open(const struct path *path, struct file *file, | |
| 841 | + const struct cred *cred) | |
| 842 | +{ | |
| 843 | + struct dentry *dentry = path->dentry; | |
| 844 | + struct inode *inode = dentry->d_inode; | |
| 845 | + | |
| 846 | + file->f_path = *path; | |
| 847 | + if (dentry->d_flags & DCACHE_OP_SELECT_INODE) { | |
| 848 | + inode = dentry->d_op->d_select_inode(dentry, file->f_flags); | |
| 849 | + if (IS_ERR(inode)) | |
| 850 | + return PTR_ERR(inode); | |
| 851 | + } | |
| 852 | + | |
| 853 | + return do_dentry_open(file, inode, NULL, cred); | |
| 854 | +} | |
| 855 | + | |
| 825 | 856 | struct file *dentry_open(const struct path *path, int flags, |
| 826 | 857 | const struct cred *cred) |
| 827 | 858 | { |
| @@ -853,26 +884,6 @@ struct file *dentry_open(const struct path *path, int flags, · 25 unmodified lines | ||
| 853 | 884 | } |
| 854 | 885 | EXPORT_SYMBOL(dentry_open); |
| 855 | 886 | |
| 856 | −/** | |
| 857 | − * vfs_open - open the file at the given path | |
| 858 | − * @path: path to open | |
| 859 | − * @filp: newly allocated file with f_flag initialized | |
| 860 | − * @cred: credentials to use | |
| 861 | − */ | |
| 862 | −int vfs_open(const struct path *path, struct file *filp, | |
| 863 | − const struct cred *cred) | |
| 864 | −{ | |
| 865 | − struct inode *inode = path->dentry->d_inode; | |
| 866 | − | |
| 867 | − if (inode->i_op->dentry_open) | |
| 868 | − return inode->i_op->dentry_open(path->dentry, filp, cred); | |
| 869 | − else { | |
| 870 | − filp->f_path = *path; | |
| 871 | − return do_dentry_open(filp, NULL, cred); | |
| 872 | − } | |
| 873 | −} | |
| 874 | −EXPORT_SYMBOL(vfs_open); | |
| 875 | − | |
| 876 | 887 | static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) |
| 877 | 888 | { |
| 878 | 889 | int lookup_flags = 0; |
| @@ -337,37 +337,30 @@ static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type, · 336 unmodified lines | ||
| 337 | 337 | return true; |
| 338 | 338 | } |
| 339 | 339 | |
| 340 | −static int ovl_dentry_open(struct dentry *dentry, struct file *file, | |
| 341 | − const struct cred *cred) | |
| 340 | +struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) | |
| 342 | 341 | { |
| 343 | 342 | int err; |
| 344 | 343 | struct path realpath; |
| 345 | 344 | enum ovl_path_type type; |
| 346 | − bool want_write = false; | |
| 347 | 345 | |
| 348 | 346 | type = ovl_path_real(dentry, &realpath); |
| 349 | − if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) { | |
| 350 | − want_write = true; | |
| 347 | + if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { | |
| 351 | 348 | err = ovl_want_write(dentry); |
| 352 | 349 | if (err) |
| 353 | − goto out; | |
| 350 | + return ERR_PTR(err); | |
| 354 | 351 | |
| 355 | − if (file->f_flags & O_TRUNC) | |
| 352 | + if (file_flags & O_TRUNC) | |
| 356 | 353 | err = ovl_copy_up_last(dentry, NULL, true); |
| 357 | 354 | else |
| 358 | 355 | err = ovl_copy_up(dentry); |
| 356 | + ovl_drop_write(dentry); | |
| 359 | 357 | if (err) |
| 360 | − goto out_drop_write; | |
| 358 | + return ERR_PTR(err); | |
| 361 | 359 | |
| 362 | 360 | ovl_path_upper(dentry, &realpath); |
| 363 | 361 | } |
| 364 | 362 | |
| 365 | − err = vfs_open(&realpath, file, cred); | |
| 366 | −out_drop_write: | |
| 367 | − if (want_write) | |
| 368 | − ovl_drop_write(dentry); | |
| 369 | −out: | |
| 370 | − return err; | |
| 363 | + return d_backing_inode(realpath.dentry); | |
| 371 | 364 | } |
| 372 | 365 | |
| 373 | 366 | static const struct inode_operations ovl_file_inode_operations = { |
| @@ -378,7 +371,6 @@ static const struct inode_operations ovl_file_inode_operations = { · 4 unmodified lines | ||
| 378 | 371 | .getxattr = ovl_getxattr, |
| 379 | 372 | .listxattr = ovl_listxattr, |
| 380 | 373 | .removexattr = ovl_removexattr, |
| 381 | − .dentry_open = ovl_dentry_open, | |
| 382 | 374 | }; |
| 383 | 375 | |
| 384 | 376 | static const struct inode_operations ovl_symlink_inode_operations = { |
| @@ -173,6 +173,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, const char *name, · 172 unmodified lines | ||
| 173 | 173 | void *value, size_t size); |
| 174 | 174 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); |
| 175 | 175 | int ovl_removexattr(struct dentry *dentry, const char *name); |
| 176 | +struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags); | |
| 176 | 177 | |
| 177 | 178 | struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, |
| 178 | 179 | struct ovl_entry *oe); |
| @@ -316,6 +316,7 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) · 315 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | static const struct dentry_operations ovl_dentry_operations = { |
| 318 | 318 | .d_release = ovl_dentry_release, |
| 319 | + .d_select_inode = ovl_d_select_inode, | |
| 319 | 320 | }; |
| 320 | 321 | |
| 321 | 322 | static const struct dentry_operations ovl_reval_dentry_operations = { |
| @@ -547,51 +547,45 @@ posix_acl_create(struct inode *dir, umode_t *mode, · 546 unmodified lines | ||
| 547 | 547 | struct posix_acl **default_acl, struct posix_acl **acl) |
| 548 | 548 | { |
| 549 | 549 | struct posix_acl *p; |
| 550 | + struct posix_acl *clone; | |
| 550 | 551 | int ret; |
| 551 | 552 | |
| 553 | + *acl = NULL; | |
| 554 | + *default_acl = NULL; | |
| 555 | + | |
| 552 | 556 | if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) |
| 553 | − goto no_acl; | |
| 557 | + return 0; | |
| 554 | 558 | |
| 555 | 559 | p = get_acl(dir, ACL_TYPE_DEFAULT); |
| 556 | − if (IS_ERR(p)) { | |
| 557 | − if (p == ERR_PTR(-EOPNOTSUPP)) | |
| 558 | − goto apply_umask; | |
| 559 | − return PTR_ERR(p); | |
| 560 | + if (!p || p == ERR_PTR(-EOPNOTSUPP)) { | |
| 561 | + *mode &= ~current_umask(); | |
| 562 | + return 0; | |
| 560 | 563 | } |
| 564 | + if (IS_ERR(p)) | |
| 565 | + return PTR_ERR(p); | |
| 561 | 566 | |
| 562 | − if (!p) | |
| 563 | − goto apply_umask; | |
| 564 | − | |
| 565 | − *acl = posix_acl_clone(p, GFP_NOFS); | |
| 566 | − if (!*acl) | |
| 567 | + clone = posix_acl_clone(p, GFP_NOFS); | |
| 568 | + if (!clone) | |
| 567 | 569 | goto no_mem; |
| 568 | 570 | |
| 569 | − ret = posix_acl_create_masq(*acl, mode); | |
| 571 | + ret = posix_acl_create_masq(clone, mode); | |
| 570 | 572 | if (ret < 0) |
| 571 | 573 | goto no_mem_clone; |
| 572 | 574 | |
| 573 | − if (ret == 0) { | |
| 574 | − posix_acl_release(*acl); | |
| 575 | − *acl = NULL; | |
| 576 | − } | |
| 575 | + if (ret == 0) | |
| 576 | + posix_acl_release(clone); | |
| 577 | + else | |
| 578 | + *acl = clone; | |
| 577 | 579 | |
| 578 | − if (!S_ISDIR(*mode)) { | |
| 580 | + if (!S_ISDIR(*mode)) | |
| 579 | 581 | posix_acl_release(p); |
| 580 | − *default_acl = NULL; | |
| 581 | − } else { | |
| 582 | + else | |
| 582 | 583 | *default_acl = p; |
| 583 | − } | |
| 584 | − return 0; | |
| 585 | 584 | |
| 586 | −apply_umask: | |
| 587 | − *mode &= ~current_umask(); | |
| 588 | −no_acl: | |
| 589 | − *default_acl = NULL; | |
| 590 | − *acl = NULL; | |
| 591 | 585 | return 0; |
| 592 | 586 | |
| 593 | 587 | no_mem_clone: |
| 594 | − posix_acl_release(*acl); | |
| 588 | + posix_acl_release(clone); | |
| 595 | 589 | no_mem: |
| 596 | 590 | posix_acl_release(p); |
| 597 | 591 | return -ENOMEM; |
| @@ -64,7 +64,7 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | if (file) { |
| 66 | 66 | seq_pad(m, ' '); |
| 67 | − seq_path(m, &file->f_path, ""); | |
| 67 | + seq_file_path(m, file, ""); | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | seq_putc(m, '\n'); |
| @@ -310,7 +310,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) · 309 unmodified lines | ||
| 310 | 310 | */ |
| 311 | 311 | if (file) { |
| 312 | 312 | seq_pad(m, ' '); |
| 313 | − seq_path(m, &file->f_path, "\n"); | |
| 313 | + seq_file_path(m, file, "\n"); | |
| 314 | 314 | goto done; |
| 315 | 315 | } |
| 316 | 316 | |
| @@ -1509,7 +1509,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) · 1192 unmodified lines | ||
| 1509 | 1509 | |
| 1510 | 1510 | if (file) { |
| 1511 | 1511 | seq_puts(m, " file="); |
| 1512 | − seq_path(m, &file->f_path, "\n\t= "); | |
| 1512 | + seq_file_path(m, file, "\n\t= "); | |
| 1513 | 1513 | } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { |
| 1514 | 1514 | seq_puts(m, " heap"); |
| 1515 | 1515 | } else { |
| @@ -180,7 +180,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, · 179 unmodified lines | ||
| 180 | 180 | |
| 181 | 181 | if (file) { |
| 182 | 182 | seq_pad(m, ' '); |
| 183 | − seq_path(m, &file->f_path, ""); | |
| 183 | + seq_file_path(m, file, ""); | |
| 184 | 184 | } else if (mm) { |
| 185 | 185 | pid_t tid = pid_of_stack(priv, vma, is_pid); |
| 186 | 186 | |
| @@ -32,11 +32,6 @@ static struct page *qnx6_get_page(struct inode *dir, unsigned long n) · 31 unmodified lines | ||
| 32 | 32 | return page; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 36 | −{ | |
| 37 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 38 | −} | |
| 39 | − | |
| 40 | 35 | static unsigned last_entry(struct inode *inode, unsigned long page_nr) |
| 41 | 36 | { |
| 42 | 37 | unsigned long last_byte = inode->i_size; |
| @@ -490,6 +490,20 @@ int seq_path(struct seq_file *m, const struct path *path, const char *esc) · 489 unmodified lines | ||
| 490 | 490 | } |
| 491 | 491 | EXPORT_SYMBOL(seq_path); |
| 492 | 492 | |
| 493 | +/** | |
| 494 | + * seq_file_path - seq_file interface to print a pathname of a file | |
| 495 | + * @m: the seq_file handle | |
| 496 | + * @file: the struct file to print | |
| 497 | + * @esc: set of characters to escape in the output | |
| 498 | + * | |
| 499 | + * return the absolute path to the file. | |
| 500 | + */ | |
| 501 | +int seq_file_path(struct seq_file *m, struct file *file, const char *esc) | |
| 502 | +{ | |
| 503 | + return seq_path(m, &file->f_path, esc); | |
| 504 | +} | |
| 505 | +EXPORT_SYMBOL(seq_file_path); | |
| 506 | + | |
| 493 | 507 | /* |
| 494 | 508 | * Same as seq_path, but relative to supplied root. |
| 495 | 509 | */ |
| @@ -49,6 +49,6 @@ struct squashfs_inode_info { · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | static inline struct squashfs_inode_info *squashfs_i(struct inode *inode) |
| 51 | 51 | { |
| 52 | − return list_entry(inode, struct squashfs_inode_info, vfs_inode); | |
| 52 | + return container_of(inode, struct squashfs_inode_info, vfs_inode); | |
| 53 | 53 | } |
| 54 | 54 | #endif |
| @@ -842,7 +842,7 @@ int get_anon_bdev(dev_t *p) · 841 unmodified lines | ||
| 842 | 842 | else if (error) |
| 843 | 843 | return -EAGAIN; |
| 844 | 844 | |
| 845 | − if (dev == (1 << MINORBITS)) { | |
| 845 | + if (dev >= (1 << MINORBITS)) { | |
| 846 | 846 | spin_lock(&unnamed_dev_lock); |
| 847 | 847 | ida_remove(&unnamed_dev_ida, dev); |
| 848 | 848 | if (unnamed_dev_start > dev) |
| @@ -33,11 +33,6 @@ static inline void dir_put_page(struct page *page) · 32 unmodified lines | ||
| 33 | 33 | page_cache_release(page); |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | −static inline unsigned long dir_pages(struct inode *inode) | |
| 37 | −{ | |
| 38 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 39 | −} | |
| 40 | − | |
| 41 | 36 | static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) |
| 42 | 37 | { |
| 43 | 38 | struct address_space *mapping = page->mapping; |
| @@ -73,7 +73,7 @@ struct sysv_inode_info { · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | static inline struct sysv_inode_info *SYSV_I(struct inode *inode) |
| 75 | 75 | { |
| 76 | − return list_entry(inode, struct sysv_inode_info, vfs_inode); | |
| 76 | + return container_of(inode, struct sysv_inode_info, vfs_inode); | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | static inline struct sysv_sb_info *SYSV_SB(struct super_block *sb) |
| @@ -496,16 +496,11 @@ struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *pare · 495 unmodified lines | ||
| 496 | 496 | return dentry; |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | −static inline int tracefs_positive(struct dentry *dentry) | |
| 500 | −{ | |
| 501 | − return dentry->d_inode && !d_unhashed(dentry); | |
| 502 | −} | |
| 503 | − | |
| 504 | 499 | static int __tracefs_remove(struct dentry *dentry, struct dentry *parent) |
| 505 | 500 | { |
| 506 | 501 | int ret = 0; |
| 507 | 502 | |
| 508 | − if (tracefs_positive(dentry)) { | |
| 503 | + if (simple_positive(dentry)) { | |
| 509 | 504 | if (dentry->d_inode) { |
| 510 | 505 | dget(dentry); |
| 511 | 506 | switch (dentry->d_inode->i_mode & S_IFMT) { |
| @@ -582,7 +577,7 @@ void tracefs_remove_recursive(struct dentry *dentry) · 70 unmodified lines | ||
| 582 | 577 | */ |
| 583 | 578 | spin_lock(&parent->d_lock); |
| 584 | 579 | list_for_each_entry(child, &parent->d_subdirs, d_child) { |
| 585 | − if (!tracefs_positive(child)) | |
| 580 | + if (!simple_positive(child)) | |
| 586 | 581 | continue; |
| 587 | 582 | |
| 588 | 583 | /* perhaps simple_empty(child) makes more sense */ |
| @@ -603,7 +598,7 @@ void tracefs_remove_recursive(struct dentry *dentry) · 14 unmodified lines | ||
| 603 | 598 | * from d_subdirs. When releasing the parent->d_lock we can |
| 604 | 599 | * no longer trust that the next pointer is valid. |
| 605 | 600 | * Restart the loop. We'll skip this one with the |
| 606 | − * tracefs_positive() check. | |
| 601 | + * simple_positive() check. | |
| 607 | 602 | */ |
| 608 | 603 | goto loop; |
| 609 | 604 | } |
| @@ -56,7 +56,7 @@ struct udf_inode_info { · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | static inline struct udf_inode_info *UDF_I(struct inode *inode) |
| 58 | 58 | { |
| 59 | − return list_entry(inode, struct udf_inode_info, vfs_inode); | |
| 59 | + return container_of(inode, struct udf_inode_info, vfs_inode); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | #endif /* _UDF_I_H) */ |
| @@ -51,8 +51,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) |
| 53 | 53 | ufs_error (sb, "ufs_free_fragments", "internal error"); |
| 54 | − | |
| 55 | − lock_ufs(sb); | |
| 54 | + | |
| 55 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 56 | 56 | |
| 57 | 57 | cgno = ufs_dtog(uspi, fragment); |
| 58 | 58 | bit = ufs_dtogd(uspi, fragment); |
| @@ -115,13 +115,13 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) · 56 unmodified lines | ||
| 115 | 115 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 116 | 116 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 117 | 117 | ufs_mark_sb_dirty(sb); |
| 118 | − | |
| 119 | − unlock_ufs(sb); | |
| 118 | + | |
| 119 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 120 | 120 | UFSD("EXIT\n"); |
| 121 | 121 | return; |
| 122 | 122 | |
| 123 | 123 | failed: |
| 124 | − unlock_ufs(sb); | |
| 124 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 125 | 125 | UFSD("EXIT (FAILED)\n"); |
| 126 | 126 | return; |
| 127 | 127 | } |
| @@ -151,7 +151,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) · 23 unmodified lines | ||
| 151 | 151 | goto failed; |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | − lock_ufs(sb); | |
| 154 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 155 | 155 | |
| 156 | 156 | do_more: |
| 157 | 157 | overflow = 0; |
| @@ -211,12 +211,12 @@ do_more: · 53 unmodified lines | ||
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | ufs_mark_sb_dirty(sb); |
| 214 | − unlock_ufs(sb); | |
| 214 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 215 | 215 | UFSD("EXIT\n"); |
| 216 | 216 | return; |
| 217 | 217 | |
| 218 | 218 | failed_unlock: |
| 219 | − unlock_ufs(sb); | |
| 219 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 220 | 220 | failed: |
| 221 | 221 | UFSD("EXIT (FAILED)\n"); |
| 222 | 222 | return; |
| @@ -357,7 +357,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 134 unmodified lines | ||
| 357 | 357 | usb1 = ubh_get_usb_first(uspi); |
| 358 | 358 | *err = -ENOSPC; |
| 359 | 359 | |
| 360 | − lock_ufs(sb); | |
| 360 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 361 | 361 | tmp = ufs_data_ptr_to_cpu(sb, p); |
| 362 | 362 | |
| 363 | 363 | if (count + ufs_fragnum(fragment) > uspi->s_fpb) { |
| @@ -378,19 +378,19 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 14 unmodified lines | ||
| 378 | 378 | "fragment %llu, tmp %llu\n", |
| 379 | 379 | (unsigned long long)fragment, |
| 380 | 380 | (unsigned long long)tmp); |
| 381 | − unlock_ufs(sb); | |
| 381 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 382 | 382 | return INVBLOCK; |
| 383 | 383 | } |
| 384 | 384 | if (fragment < UFS_I(inode)->i_lastfrag) { |
| 385 | 385 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
| 386 | − unlock_ufs(sb); | |
| 386 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 387 | 387 | return 0; |
| 388 | 388 | } |
| 389 | 389 | } |
| 390 | 390 | else { |
| 391 | 391 | if (tmp) { |
| 392 | 392 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
| 393 | − unlock_ufs(sb); | |
| 393 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 394 | 394 | return 0; |
| 395 | 395 | } |
| 396 | 396 | } |
| @@ -399,7 +399,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 2 unmodified lines | ||
| 399 | 399 | * There is not enough space for user on the device |
| 400 | 400 | */ |
| 401 | 401 | if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { |
| 402 | − unlock_ufs(sb); | |
| 402 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 403 | 403 | UFSD("EXIT (FAILED)\n"); |
| 404 | 404 | return 0; |
| 405 | 405 | } |
| @@ -424,7 +424,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 18 unmodified lines | ||
| 424 | 424 | ufs_clear_frags(inode, result + oldcount, |
| 425 | 425 | newcount - oldcount, locked_page != NULL); |
| 426 | 426 | } |
| 427 | − unlock_ufs(sb); | |
| 427 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 428 | 428 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
| 429 | 429 | return result; |
| 430 | 430 | } |
| @@ -439,7 +439,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 8 unmodified lines | ||
| 439 | 439 | fragment + count); |
| 440 | 440 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
| 441 | 441 | locked_page != NULL); |
| 442 | − unlock_ufs(sb); | |
| 442 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 443 | 443 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
| 444 | 444 | return result; |
| 445 | 445 | } |
| @@ -477,7 +477,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 31 unmodified lines | ||
| 477 | 477 | *err = 0; |
| 478 | 478 | UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, |
| 479 | 479 | fragment + count); |
| 480 | − unlock_ufs(sb); | |
| 480 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 481 | 481 | if (newcount < request) |
| 482 | 482 | ufs_free_fragments (inode, result + newcount, request - newcount); |
| 483 | 483 | ufs_free_fragments (inode, tmp, oldcount); |
| @@ -485,7 +485,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, · 1 unmodified line | ||
| 485 | 485 | return result; |
| 486 | 486 | } |
| 487 | 487 | |
| 488 | − unlock_ufs(sb); | |
| 488 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 489 | 489 | UFSD("EXIT (FAILED)\n"); |
| 490 | 490 | return 0; |
| 491 | 491 | } |
| @@ -65,11 +65,6 @@ static inline void ufs_put_page(struct page *page) · 64 unmodified lines | ||
| 65 | 65 | page_cache_release(page); |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | −static inline unsigned long ufs_dir_pages(struct inode *inode) | |
| 69 | −{ | |
| 70 | − return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; | |
| 71 | −} | |
| 72 | − | |
| 73 | 68 | ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr) |
| 74 | 69 | { |
| 75 | 70 | ino_t res = 0; |
| @@ -87,7 +82,8 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr) · 11 unmodified lines | ||
| 87 | 82 | |
| 88 | 83 | /* Releases the page */ |
| 89 | 84 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
| 90 | − struct page *page, struct inode *inode) | |
| 85 | + struct page *page, struct inode *inode, | |
| 86 | + bool update_times) | |
| 91 | 87 | { |
| 92 | 88 | loff_t pos = page_offset(page) + |
| 93 | 89 | (char *) de - (char *) page_address(page); |
| @@ -103,7 +99,8 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, · 9 unmodified lines | ||
| 103 | 99 | |
| 104 | 100 | err = ufs_commit_chunk(page, pos, len); |
| 105 | 101 | ufs_put_page(page); |
| 106 | − dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | |
| 102 | + if (update_times) | |
| 103 | + dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | |
| 107 | 104 | mark_inode_dirty(dir); |
| 108 | 105 | } |
| 109 | 106 | |
| @@ -256,7 +253,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr, · 146 unmodified lines | ||
| 256 | 253 | int namelen = qstr->len; |
| 257 | 254 | unsigned reclen = UFS_DIR_REC_LEN(namelen); |
| 258 | 255 | unsigned long start, n; |
| 259 | − unsigned long npages = ufs_dir_pages(dir); | |
| 256 | + unsigned long npages = dir_pages(dir); | |
| 260 | 257 | struct page *page = NULL; |
| 261 | 258 | struct ufs_inode_info *ui = UFS_I(dir); |
| 262 | 259 | struct ufs_dir_entry *de; |
| @@ -320,7 +317,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) · 57 unmodified lines | ||
| 320 | 317 | unsigned short rec_len, name_len; |
| 321 | 318 | struct page *page = NULL; |
| 322 | 319 | struct ufs_dir_entry *de; |
| 323 | − unsigned long npages = ufs_dir_pages(dir); | |
| 320 | + unsigned long npages = dir_pages(dir); | |
| 324 | 321 | unsigned long n; |
| 325 | 322 | char *kaddr; |
| 326 | 323 | loff_t pos; |
| @@ -437,7 +434,7 @@ ufs_readdir(struct file *file, struct dir_context *ctx) · 110 unmodified lines | ||
| 437 | 434 | struct super_block *sb = inode->i_sb; |
| 438 | 435 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
| 439 | 436 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
| 440 | − unsigned long npages = ufs_dir_pages(inode); | |
| 437 | + unsigned long npages = dir_pages(inode); | |
| 441 | 438 | unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); |
| 442 | 439 | int need_revalidate = file->f_version != inode->i_version; |
| 443 | 440 | unsigned flags = UFS_SB(sb)->s_flags; |
| @@ -608,7 +605,7 @@ int ufs_empty_dir(struct inode * inode) · 164 unmodified lines | ||
| 608 | 605 | { |
| 609 | 606 | struct super_block *sb = inode->i_sb; |
| 610 | 607 | struct page *page = NULL; |
| 611 | − unsigned long i, npages = ufs_dir_pages(inode); | |
| 608 | + unsigned long i, npages = dir_pages(inode); | |
| 612 | 609 | |
| 613 | 610 | for (i = 0; i < npages; i++) { |
| 614 | 611 | char *kaddr; |
| @@ -69,11 +69,11 @@ void ufs_free_inode (struct inode * inode) · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | ino = inode->i_ino; |
| 71 | 71 | |
| 72 | − lock_ufs(sb); | |
| 72 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 73 | 73 | |
| 74 | 74 | if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) { |
| 75 | 75 | ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino); |
| 76 | − unlock_ufs(sb); | |
| 76 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 77 | 77 | return; |
| 78 | 78 | } |
| 79 | 79 | |
| @@ -81,7 +81,7 @@ void ufs_free_inode (struct inode * inode) · 1 unmodified line | ||
| 81 | 81 | bit = ufs_inotocgoff (ino); |
| 82 | 82 | ucpi = ufs_load_cylinder (sb, cg); |
| 83 | 83 | if (!ucpi) { |
| 84 | − unlock_ufs(sb); | |
| 84 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 85 | 85 | return; |
| 86 | 86 | } |
| 87 | 87 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
| @@ -115,7 +115,7 @@ void ufs_free_inode (struct inode * inode) · 27 unmodified lines | ||
| 115 | 115 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 116 | 116 | |
| 117 | 117 | ufs_mark_sb_dirty(sb); |
| 118 | − unlock_ufs(sb); | |
| 118 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 119 | 119 | UFSD("EXIT\n"); |
| 120 | 120 | } |
| 121 | 121 | |
| @@ -193,7 +193,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode) · 71 unmodified lines | ||
| 193 | 193 | sbi = UFS_SB(sb); |
| 194 | 194 | uspi = sbi->s_uspi; |
| 195 | 195 | |
| 196 | − lock_ufs(sb); | |
| 196 | + mutex_lock(&sbi->s_lock); | |
| 197 | 197 | |
| 198 | 198 | /* |
| 199 | 199 | * Try to place the inode in its parent directory |
| @@ -331,21 +331,21 @@ cg_found: · 131 unmodified lines | ||
| 331 | 331 | sync_dirty_buffer(bh); |
| 332 | 332 | brelse(bh); |
| 333 | 333 | } |
| 334 | − unlock_ufs(sb); | |
| 334 | + mutex_unlock(&sbi->s_lock); | |
| 335 | 335 | |
| 336 | 336 | UFSD("allocating inode %lu\n", inode->i_ino); |
| 337 | 337 | UFSD("EXIT\n"); |
| 338 | 338 | return inode; |
| 339 | 339 | |
| 340 | 340 | fail_remove_inode: |
| 341 | − unlock_ufs(sb); | |
| 341 | + mutex_unlock(&sbi->s_lock); | |
| 342 | 342 | clear_nlink(inode); |
| 343 | 343 | unlock_new_inode(inode); |
| 344 | 344 | iput(inode); |
| 345 | 345 | UFSD("EXIT (FAILED): err %d\n", err); |
| 346 | 346 | return ERR_PTR(err); |
| 347 | 347 | failed: |
| 348 | − unlock_ufs(sb); | |
| 348 | + mutex_unlock(&sbi->s_lock); | |
| 349 | 349 | make_bad_inode(inode); |
| 350 | 350 | iput (inode); |
| 351 | 351 | UFSD("EXIT (FAILED): err %d\n", err); |
| @@ -903,6 +903,9 @@ void ufs_evict_inode(struct inode * inode) · 902 unmodified lines | ||
| 903 | 903 | invalidate_inode_buffers(inode); |
| 904 | 904 | clear_inode(inode); |
| 905 | 905 | |
| 906 | − if (want_delete) | |
| 906 | + if (want_delete) { | |
| 907 | + lock_ufs(inode->i_sb); | |
| 907 | 908 | ufs_free_inode(inode); |
| 909 | + unlock_ufs(inode->i_sb); | |
| 910 | + } | |
| 908 | 911 | } |
| @@ -56,11 +56,9 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsi · 55 unmodified lines | ||
| 56 | 56 | if (dentry->d_name.len > UFS_MAXNAMLEN) |
| 57 | 57 | return ERR_PTR(-ENAMETOOLONG); |
| 58 | 58 | |
| 59 | − lock_ufs(dir->i_sb); | |
| 60 | 59 | ino = ufs_inode_by_name(dir, &dentry->d_name); |
| 61 | 60 | if (ino) |
| 62 | 61 | inode = ufs_iget(dir->i_sb, ino); |
| 63 | − unlock_ufs(dir->i_sb); | |
| 64 | 62 | return d_splice_alias(inode, dentry); |
| 65 | 63 | } |
| 66 | 64 | |
| @@ -76,24 +74,16 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, · 9 unmodified lines | ||
| 76 | 74 | bool excl) |
| 77 | 75 | { |
| 78 | 76 | struct inode *inode; |
| 79 | − int err; | |
| 80 | − | |
| 81 | − UFSD("BEGIN\n"); | |
| 82 | 77 | |
| 83 | 78 | inode = ufs_new_inode(dir, mode); |
| 84 | − err = PTR_ERR(inode); | |
| 79 | + if (IS_ERR(inode)) | |
| 80 | + return PTR_ERR(inode); | |
| 85 | 81 | |
| 86 | − if (!IS_ERR(inode)) { | |
| 87 | − inode->i_op = &ufs_file_inode_operations; | |
| 88 | − inode->i_fop = &ufs_file_operations; | |
| 89 | − inode->i_mapping->a_ops = &ufs_aops; | |
| 90 | − mark_inode_dirty(inode); | |
| 91 | − lock_ufs(dir->i_sb); | |
| 92 | − err = ufs_add_nondir(dentry, inode); | |
| 93 | − unlock_ufs(dir->i_sb); | |
| 94 | − } | |
| 95 | − UFSD("END: err=%d\n", err); | |
| 96 | − return err; | |
| 82 | + inode->i_op = &ufs_file_inode_operations; | |
| 83 | + inode->i_fop = &ufs_file_operations; | |
| 84 | + inode->i_mapping->a_ops = &ufs_aops; | |
| 85 | + mark_inode_dirty(inode); | |
| 86 | + return ufs_add_nondir(dentry, inode); | |
| 97 | 87 | } |
| 98 | 88 | |
| 99 | 89 | static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
| @@ -110,9 +100,7 @@ static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev · 10 unmodified lines | ||
| 110 | 100 | init_special_inode(inode, mode, rdev); |
| 111 | 101 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); |
| 112 | 102 | mark_inode_dirty(inode); |
| 113 | − lock_ufs(dir->i_sb); | |
| 114 | 103 | err = ufs_add_nondir(dentry, inode); |
| 115 | − unlock_ufs(dir->i_sb); | |
| 116 | 104 | } |
| 117 | 105 | return err; |
| 118 | 106 | } |
| @@ -121,19 +109,18 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, · 2 unmodified lines | ||
| 121 | 109 | const char * symname) |
| 122 | 110 | { |
| 123 | 111 | struct super_block * sb = dir->i_sb; |
| 124 | − int err = -ENAMETOOLONG; | |
| 112 | + int err; | |
| 125 | 113 | unsigned l = strlen(symname)+1; |
| 126 | 114 | struct inode * inode; |
| 127 | 115 | |
| 128 | 116 | if (l > sb->s_blocksize) |
| 129 | − goto out_notlocked; | |
| 117 | + return -ENAMETOOLONG; | |
| 130 | 118 | |
| 131 | 119 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
| 132 | 120 | err = PTR_ERR(inode); |
| 133 | 121 | if (IS_ERR(inode)) |
| 134 | − goto out_notlocked; | |
| 122 | + return err; | |
| 135 | 123 | |
| 136 | − lock_ufs(dir->i_sb); | |
| 137 | 124 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { |
| 138 | 125 | /* slow symlink */ |
| 139 | 126 | inode->i_op = &ufs_symlink_inode_operations; |
| @@ -150,17 +137,13 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, · 10 unmodified lines | ||
| 150 | 137 | } |
| 151 | 138 | mark_inode_dirty(inode); |
| 152 | 139 | |
| 153 | − err = ufs_add_nondir(dentry, inode); | |
| 154 | −out: | |
| 155 | − unlock_ufs(dir->i_sb); | |
| 156 | −out_notlocked: | |
| 157 | − return err; | |
| 140 | + return ufs_add_nondir(dentry, inode); | |
| 158 | 141 | |
| 159 | 142 | out_fail: |
| 160 | 143 | inode_dec_link_count(inode); |
| 161 | 144 | unlock_new_inode(inode); |
| 162 | 145 | iput(inode); |
| 163 | − goto out; | |
| 146 | + return err; | |
| 164 | 147 | } |
| 165 | 148 | |
| 166 | 149 | static int ufs_link (struct dentry * old_dentry, struct inode * dir, |
| @@ -169,14 +152,16 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, · 2 unmodified lines | ||
| 169 | 152 | struct inode *inode = d_inode(old_dentry); |
| 170 | 153 | int error; |
| 171 | 154 | |
| 172 | − lock_ufs(dir->i_sb); | |
| 173 | − | |
| 174 | 155 | inode->i_ctime = CURRENT_TIME_SEC; |
| 175 | 156 | inode_inc_link_count(inode); |
| 176 | 157 | ihold(inode); |
| 177 | 158 | |
| 178 | − error = ufs_add_nondir(dentry, inode); | |
| 179 | − unlock_ufs(dir->i_sb); | |
| 159 | + error = ufs_add_link(dentry, inode); | |
| 160 | + if (error) { | |
| 161 | + inode_dec_link_count(inode); | |
| 162 | + iput(inode); | |
| 163 | + } else | |
| 164 | + d_instantiate(dentry, inode); | |
| 180 | 165 | return error; |
| 181 | 166 | } |
| 182 | 167 | |
| @@ -185,9 +170,12 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) · 2 unmodified lines | ||
| 185 | 170 | struct inode * inode; |
| 186 | 171 | int err; |
| 187 | 172 | |
| 173 | + inode_inc_link_count(dir); | |
| 174 | + | |
| 188 | 175 | inode = ufs_new_inode(dir, S_IFDIR|mode); |
| 176 | + err = PTR_ERR(inode); | |
| 189 | 177 | if (IS_ERR(inode)) |
| 190 | − return PTR_ERR(inode); | |
| 178 | + goto out_dir; | |
| 191 | 179 | |
| 192 | 180 | inode->i_op = &ufs_dir_inode_operations; |
| 193 | 181 | inode->i_fop = &ufs_dir_operations; |
| @@ -195,9 +183,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) · 1 unmodified line | ||
| 195 | 183 | |
| 196 | 184 | inode_inc_link_count(inode); |
| 197 | 185 | |
| 198 | − lock_ufs(dir->i_sb); | |
| 199 | − inode_inc_link_count(dir); | |
| 200 | − | |
| 201 | 186 | err = ufs_make_empty(inode, dir); |
| 202 | 187 | if (err) |
| 203 | 188 | goto out_fail; |
| @@ -205,20 +190,19 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) · 1 unmodified line | ||
| 205 | 190 | err = ufs_add_link(dentry, inode); |
| 206 | 191 | if (err) |
| 207 | 192 | goto out_fail; |
| 208 | − unlock_ufs(dir->i_sb); | |
| 209 | 193 | |
| 194 | + unlock_new_inode(inode); | |
| 210 | 195 | d_instantiate(dentry, inode); |
| 211 | −out: | |
| 212 | − return err; | |
| 196 | + return 0; | |
| 213 | 197 | |
| 214 | 198 | out_fail: |
| 215 | 199 | inode_dec_link_count(inode); |
| 216 | 200 | inode_dec_link_count(inode); |
| 217 | 201 | unlock_new_inode(inode); |
| 218 | 202 | iput (inode); |
| 203 | +out_dir: | |
| 219 | 204 | inode_dec_link_count(dir); |
| 220 | − unlock_ufs(dir->i_sb); | |
| 221 | − goto out; | |
| 205 | + return err; | |
| 222 | 206 | } |
| 223 | 207 | |
| 224 | 208 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) |
| @@ -248,7 +232,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) · 23 unmodified lines | ||
| 248 | 232 | struct inode * inode = d_inode(dentry); |
| 249 | 233 | int err= -ENOTEMPTY; |
| 250 | 234 | |
| 251 | − lock_ufs(dir->i_sb); | |
| 252 | 235 | if (ufs_empty_dir (inode)) { |
| 253 | 236 | err = ufs_unlink(dir, dentry); |
| 254 | 237 | if (!err) { |
| @@ -257,7 +240,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) · 2 unmodified lines | ||
| 257 | 240 | inode_dec_link_count(dir); |
| 258 | 241 | } |
| 259 | 242 | } |
| 260 | − unlock_ufs(dir->i_sb); | |
| 261 | 243 | return err; |
| 262 | 244 | } |
| 263 | 245 | |
| @@ -295,7 +277,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, · 31 unmodified lines | ||
| 295 | 277 | new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); |
| 296 | 278 | if (!new_de) |
| 297 | 279 | goto out_dir; |
| 298 | − ufs_set_link(new_dir, new_de, new_page, old_inode); | |
| 280 | + ufs_set_link(new_dir, new_de, new_page, old_inode, 1); | |
| 299 | 281 | new_inode->i_ctime = CURRENT_TIME_SEC; |
| 300 | 282 | if (dir_de) |
| 301 | 283 | drop_nlink(new_inode); |
| @@ -318,7 +300,12 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, · 16 unmodified lines | ||
| 318 | 300 | mark_inode_dirty(old_inode); |
| 319 | 301 | |
| 320 | 302 | if (dir_de) { |
| 321 | − ufs_set_link(old_inode, dir_de, dir_page, new_dir); | |
| 303 | + if (old_dir != new_dir) | |
| 304 | + ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0); | |
| 305 | + else { | |
| 306 | + kunmap(dir_page); | |
| 307 | + page_cache_release(dir_page); | |
| 308 | + } | |
| 322 | 309 | inode_dec_link_count(old_dir); |
| 323 | 310 | } |
| 324 | 311 | return 0; |
| @@ -695,6 +695,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) · 694 unmodified lines | ||
| 695 | 695 | unsigned flags; |
| 696 | 696 | |
| 697 | 697 | lock_ufs(sb); |
| 698 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 698 | 699 | |
| 699 | 700 | UFSD("ENTER\n"); |
| 700 | 701 | |
| @@ -712,6 +713,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) · 11 unmodified lines | ||
| 712 | 713 | ufs_put_cstotal(sb); |
| 713 | 714 | |
| 714 | 715 | UFSD("EXIT\n"); |
| 716 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 715 | 717 | unlock_ufs(sb); |
| 716 | 718 | |
| 717 | 719 | return 0; |
| @@ -800,6 +802,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) · 82 unmodified lines | ||
| 800 | 802 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); |
| 801 | 803 | |
| 802 | 804 | mutex_init(&sbi->mutex); |
| 805 | + mutex_init(&sbi->s_lock); | |
| 803 | 806 | spin_lock_init(&sbi->work_lock); |
| 804 | 807 | INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); |
| 805 | 808 | /* |
| @@ -1278,6 +1281,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 472 unmodified lines | ||
| 1278 | 1281 | |
| 1279 | 1282 | sync_filesystem(sb); |
| 1280 | 1283 | lock_ufs(sb); |
| 1284 | + mutex_lock(&UFS_SB(sb)->s_lock); | |
| 1281 | 1285 | uspi = UFS_SB(sb)->s_uspi; |
| 1282 | 1286 | flags = UFS_SB(sb)->s_flags; |
| 1283 | 1287 | usb1 = ubh_get_usb_first(uspi); |
| @@ -1291,6 +1295,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 7 unmodified lines | ||
| 1291 | 1295 | new_mount_opt = 0; |
| 1292 | 1296 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); |
| 1293 | 1297 | if (!ufs_parse_options (data, &new_mount_opt)) { |
| 1298 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1294 | 1299 | unlock_ufs(sb); |
| 1295 | 1300 | return -EINVAL; |
| 1296 | 1301 | } |
| @@ -1298,12 +1303,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 1 unmodified line | ||
| 1298 | 1303 | new_mount_opt |= ufstype; |
| 1299 | 1304 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
| 1300 | 1305 | pr_err("ufstype can't be changed during remount\n"); |
| 1306 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1301 | 1307 | unlock_ufs(sb); |
| 1302 | 1308 | return -EINVAL; |
| 1303 | 1309 | } |
| 1304 | 1310 | |
| 1305 | 1311 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
| 1306 | 1312 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
| 1313 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1307 | 1314 | unlock_ufs(sb); |
| 1308 | 1315 | return 0; |
| 1309 | 1316 | } |
| @@ -1327,6 +1334,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 17 unmodified lines | ||
| 1327 | 1334 | */ |
| 1328 | 1335 | #ifndef CONFIG_UFS_FS_WRITE |
| 1329 | 1336 | pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n"); |
| 1337 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1330 | 1338 | unlock_ufs(sb); |
| 1331 | 1339 | return -EINVAL; |
| 1332 | 1340 | #else |
| @@ -1336,11 +1344,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 3 unmodified lines | ||
| 1336 | 1344 | ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && |
| 1337 | 1345 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { |
| 1338 | 1346 | pr_err("this ufstype is read-only supported\n"); |
| 1347 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1339 | 1348 | unlock_ufs(sb); |
| 1340 | 1349 | return -EINVAL; |
| 1341 | 1350 | } |
| 1342 | 1351 | if (!ufs_read_cylinder_structures(sb)) { |
| 1343 | 1352 | pr_err("failed during remounting\n"); |
| 1353 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1344 | 1354 | unlock_ufs(sb); |
| 1345 | 1355 | return -EPERM; |
| 1346 | 1356 | } |
| @@ -1348,6 +1358,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) · 1 unmodified line | ||
| 1348 | 1358 | #endif |
| 1349 | 1359 | } |
| 1350 | 1360 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
| 1361 | + mutex_unlock(&UFS_SB(sb)->s_lock); | |
| 1351 | 1362 | unlock_ufs(sb); |
| 1352 | 1363 | return 0; |
| 1353 | 1364 | } |
| @@ -30,6 +30,7 @@ struct ufs_sb_info { · 29 unmodified lines | ||
| 30 | 30 | int work_queued; /* non-zero if the delayed work is queued */ |
| 31 | 31 | struct delayed_work sync_work; /* FS sync delayed work */ |
| 32 | 32 | spinlock_t work_lock; /* protects sync_work and work_queued */ |
| 33 | + struct mutex s_lock; | |
| 33 | 34 | }; |
| 34 | 35 | |
| 35 | 36 | struct ufs_inode_info { |
| @@ -105,7 +106,7 @@ extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page · 69 unmodified lines | ||
| 105 | 106 | extern int ufs_empty_dir (struct inode *); |
| 106 | 107 | extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **); |
| 107 | 108 | extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
| 108 | − struct page *page, struct inode *inode); | |
| 109 | + struct page *page, struct inode *inode, bool update_times); | |
| 109 | 110 | |
| 110 | 111 | /* file.c */ |
| 111 | 112 | extern const struct inode_operations ufs_file_inode_operations; |
| @@ -577,6 +577,13 @@ restart: · 576 unmodified lines | ||
| 577 | 577 | if (error) |
| 578 | 578 | return error; |
| 579 | 579 | |
| 580 | + /* For changing security info in file_remove_privs() we need i_mutex */ | |
| 581 | + if (*iolock == XFS_IOLOCK_SHARED && !IS_NOSEC(inode)) { | |
| 582 | + xfs_rw_iunlock(ip, *iolock); | |
| 583 | + *iolock = XFS_IOLOCK_EXCL; | |
| 584 | + xfs_rw_ilock(ip, *iolock); | |
| 585 | + goto restart; | |
| 586 | + } | |
| 580 | 587 | /* |
| 581 | 588 | * If the offset is beyond the size of the file, we need to zero any |
| 582 | 589 | * blocks that fall between the existing EOF and the start of this |
| @@ -637,7 +644,9 @@ restart: · 54 unmodified lines | ||
| 637 | 644 | * setgid bits if the process is not being run by root. This keeps |
| 638 | 645 | * people from modifying setuid and setgid binaries. |
| 639 | 646 | */ |
| 640 | − return file_remove_suid(file); | |
| 647 | + if (!IS_NOSEC(inode)) | |
| 648 | + return file_remove_privs(file); | |
| 649 | + return 0; | |
| 641 | 650 | } |
| 642 | 651 | |
| 643 | 652 | /* |
| @@ -160,6 +160,7 @@ struct dentry_operations { · 159 unmodified lines | ||
| 160 | 160 | char *(*d_dname)(struct dentry *, char *, int); |
| 161 | 161 | struct vfsmount *(*d_automount)(struct path *); |
| 162 | 162 | int (*d_manage)(struct dentry *, bool); |
| 163 | + struct inode *(*d_select_inode)(struct dentry *, unsigned); | |
| 163 | 164 | } ____cacheline_aligned; |
| 164 | 165 | |
| 165 | 166 | /* |
| @@ -225,6 +226,7 @@ struct dentry_operations { · 59 unmodified lines | ||
| 225 | 226 | |
| 226 | 227 | #define DCACHE_MAY_FREE 0x00800000 |
| 227 | 228 | #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ |
| 229 | +#define DCACHE_OP_SELECT_INODE 0x02000000 /* Unioned entry: dcache op selects inode */ | |
| 228 | 230 | |
| 229 | 231 | extern seqlock_t rename_lock; |
| 230 | 232 | |
| @@ -505,6 +507,11 @@ static inline bool d_really_is_positive(const struct dentry *dentry) · 274 unmodified lines | ||
| 505 | 507 | return dentry->d_inode != NULL; |
| 506 | 508 | } |
| 507 | 509 | |
| 510 | +static inline int simple_positive(struct dentry *dentry) | |
| 511 | +{ | |
| 512 | + return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 513 | +} | |
| 514 | + | |
| 508 | 515 | extern void d_set_fallthru(struct dentry *dentry); |
| 509 | 516 | |
| 510 | 517 | static inline bool d_is_fallthru(const struct dentry *dentry) |
| @@ -47,6 +47,9 @@ struct files_struct { · 46 unmodified lines | ||
| 47 | 47 | * read mostly part |
| 48 | 48 | */ |
| 49 | 49 | atomic_t count; |
| 50 | + bool resize_in_progress; | |
| 51 | + wait_queue_head_t resize_wait; | |
| 52 | + | |
| 50 | 53 | struct fdtable __rcu *fdt; |
| 51 | 54 | struct fdtable fdtab; |
| 52 | 55 | /* |
| @@ -1654,7 +1654,6 @@ struct inode_operations { · 1653 unmodified lines | ||
| 1654 | 1654 | int (*set_acl)(struct inode *, struct posix_acl *, int); |
| 1655 | 1655 | |
| 1656 | 1656 | /* WARNING: probably going away soon, do not use! */ |
| 1657 | − int (*dentry_open)(struct dentry *, struct file *, const struct cred *); | |
| 1658 | 1657 | } ____cacheline_aligned; |
| 1659 | 1658 | |
| 1660 | 1659 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, |
| @@ -2213,7 +2212,6 @@ extern struct file *file_open_name(struct filename *, int, umode_t); · 552 unmodified lines | ||
| 2213 | 2212 | extern struct file *filp_open(const char *, int, umode_t); |
| 2214 | 2213 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, |
| 2215 | 2214 | const char *, int); |
| 2216 | −extern int vfs_open(const struct path *, struct file *, const struct cred *); | |
| 2217 | 2215 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
| 2218 | 2216 | extern int filp_close(struct file *, fl_owner_t id); |
| 2219 | 2217 | |
| @@ -2530,6 +2528,8 @@ extern struct file * open_exec(const char *); · 310 unmodified lines | ||
| 2530 | 2528 | extern int is_subdir(struct dentry *, struct dentry *); |
| 2531 | 2529 | extern int path_is_under(struct path *, struct path *); |
| 2532 | 2530 | |
| 2531 | +extern char *file_path(struct file *, char *, int); | |
| 2532 | + | |
| 2533 | 2533 | #include <linux/err.h> |
| 2534 | 2534 | |
| 2535 | 2535 | /* needed for stackable file system support */ |
| @@ -2581,7 +2581,12 @@ extern struct inode *new_inode_pseudo(struct super_block *sb); · 45 unmodified lines | ||
| 2581 | 2581 | extern struct inode *new_inode(struct super_block *sb); |
| 2582 | 2582 | extern void free_inode_nonrcu(struct inode *inode); |
| 2583 | 2583 | extern int should_remove_suid(struct dentry *); |
| 2584 | −extern int file_remove_suid(struct file *); | |
| 2584 | +extern int file_remove_privs(struct file *); | |
| 2585 | +extern int dentry_needs_remove_privs(struct dentry *dentry); | |
| 2586 | +static inline int file_needs_remove_privs(struct file *file) | |
| 2587 | +{ | |
| 2588 | + return dentry_needs_remove_privs(file->f_path.dentry); | |
| 2589 | +} | |
| 2585 | 2590 | |
| 2586 | 2591 | extern void __insert_inode_hash(struct inode *, unsigned long hashval); |
| 2587 | 2592 | static inline void insert_inode_hash(struct inode *inode) |
| @@ -74,6 +74,7 @@ extern wait_queue_head_t fscache_cache_cleared_wq; · 73 unmodified lines | ||
| 74 | 74 | */ |
| 75 | 75 | typedef void (*fscache_operation_release_t)(struct fscache_operation *op); |
| 76 | 76 | typedef void (*fscache_operation_processor_t)(struct fscache_operation *op); |
| 77 | +typedef void (*fscache_operation_cancel_t)(struct fscache_operation *op); | |
| 77 | 78 | |
| 78 | 79 | enum fscache_operation_state { |
| 79 | 80 | FSCACHE_OP_ST_BLANK, /* Op is not yet submitted */ |
| @@ -109,6 +110,9 @@ struct fscache_operation { · 29 unmodified lines | ||
| 109 | 110 | * the op in a non-pool thread */ |
| 110 | 111 | fscache_operation_processor_t processor; |
| 111 | 112 | |
| 113 | + /* Operation cancellation cleanup (optional) */ | |
| 114 | + fscache_operation_cancel_t cancel; | |
| 115 | + | |
| 112 | 116 | /* operation releaser */ |
| 113 | 117 | fscache_operation_release_t release; |
| 114 | 118 | }; |
| @@ -119,33 +123,17 @@ extern void fscache_op_work_func(struct work_struct *work); · 4 unmodified lines | ||
| 119 | 123 | extern void fscache_enqueue_operation(struct fscache_operation *); |
| 120 | 124 | extern void fscache_op_complete(struct fscache_operation *, bool); |
| 121 | 125 | extern void fscache_put_operation(struct fscache_operation *); |
| 122 | − | |
| 123 | −/** | |
| 124 | − * fscache_operation_init - Do basic initialisation of an operation | |
| 125 | − * @op: The operation to initialise | |
| 126 | − * @release: The release function to assign | |
| 127 | − * | |
| 128 | − * Do basic initialisation of an operation. The caller must still set flags, | |
| 129 | − * object and processor if needed. | |
| 130 | − */ | |
| 131 | −static inline void fscache_operation_init(struct fscache_operation *op, | |
| 132 | − fscache_operation_processor_t processor, | |
| 133 | − fscache_operation_release_t release) | |
| 134 | −{ | |
| 135 | − INIT_WORK(&op->work, fscache_op_work_func); | |
| 136 | − atomic_set(&op->usage, 1); | |
| 137 | − op->state = FSCACHE_OP_ST_INITIALISED; | |
| 138 | − op->debug_id = atomic_inc_return(&fscache_op_debug_id); | |
| 139 | − op->processor = processor; | |
| 140 | − op->release = release; | |
| 141 | − INIT_LIST_HEAD(&op->pend_link); | |
| 142 | −} | |
| 126 | +extern void fscache_operation_init(struct fscache_operation *, | |
| 127 | + fscache_operation_processor_t, | |
| 128 | + fscache_operation_cancel_t, | |
| 129 | + fscache_operation_release_t); | |
| 143 | 130 | |
| 144 | 131 | /* |
| 145 | 132 | * data read operation |
| 146 | 133 | */ |
| 147 | 134 | struct fscache_retrieval { |
| 148 | 135 | struct fscache_operation op; |
| 136 | + struct fscache_cookie *cookie; /* The netfs cookie */ | |
| 149 | 137 | struct address_space *mapping; /* netfs pages */ |
| 150 | 138 | fscache_rw_complete_t end_io_func; /* function to call on I/O completion */ |
| 151 | 139 | void *context; /* netfs read context (pinned) */ |
| @@ -371,6 +359,7 @@ struct fscache_object { · 219 unmodified lines | ||
| 371 | 359 | #define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */ |
| 372 | 360 | #define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ |
| 373 | 361 | #define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */ |
| 362 | +#define FSCACHE_OBJECT_KILLED_BY_CACHE 7 /* T if object was killed by the cache */ | |
| 374 | 363 | |
| 375 | 364 | struct list_head cache_link; /* link in cache->object_list */ |
| 376 | 365 | struct hlist_node cookie_link; /* link in cookie->backing_objects */ |
| @@ -410,17 +399,16 @@ static inline bool fscache_object_is_available(struct fscache_object *object) · 33 unmodified lines | ||
| 410 | 399 | return test_bit(FSCACHE_OBJECT_IS_AVAILABLE, &object->flags); |
| 411 | 400 | } |
| 412 | 401 | |
| 413 | −static inline bool fscache_object_is_active(struct fscache_object *object) | |
| 402 | +static inline bool fscache_cache_is_broken(struct fscache_object *object) | |
| 414 | 403 | { |
| 415 | − return fscache_object_is_available(object) && | |
| 416 | − fscache_object_is_live(object) && | |
| 417 | − !test_bit(FSCACHE_IOERROR, &object->cache->flags); | |
| 404 | + return test_bit(FSCACHE_IOERROR, &object->cache->flags); | |
| 418 | 405 | } |
| 419 | 406 | |
| 420 | −static inline bool fscache_object_is_dead(struct fscache_object *object) | |
| 407 | +static inline bool fscache_object_is_active(struct fscache_object *object) | |
| 421 | 408 | { |
| 422 | − return fscache_object_is_dying(object) && | |
| 423 | − test_bit(FSCACHE_IOERROR, &object->cache->flags); | |
| 409 | + return fscache_object_is_available(object) && | |
| 410 | + fscache_object_is_live(object) && | |
| 411 | + !fscache_cache_is_broken(object); | |
| 424 | 412 | } |
| 425 | 413 | |
| 426 | 414 | /** |
| @@ -551,4 +539,15 @@ extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object, · 124 unmodified lines | ||
| 551 | 539 | const void *data, |
| 552 | 540 | uint16_t datalen); |
| 553 | 541 | |
| 542 | +extern void fscache_object_retrying_stale(struct fscache_object *object); | |
| 543 | + | |
| 544 | +enum fscache_why_object_killed { | |
| 545 | + FSCACHE_OBJECT_IS_STALE, | |
| 546 | + FSCACHE_OBJECT_NO_SPACE, | |
| 547 | + FSCACHE_OBJECT_WAS_RETIRED, | |
| 548 | + FSCACHE_OBJECT_WAS_CULLED, | |
| 549 | +}; | |
| 550 | +extern void fscache_object_mark_killed(struct fscache_object *object, | |
| 551 | + enum fscache_why_object_killed why); | |
| 552 | + | |
| 554 | 553 | #endif /* _LINUX_FSCACHE_CACHE_H */ |
| @@ -671,4 +671,10 @@ static inline int add_to_page_cache(struct page *page, · 670 unmodified lines | ||
| 671 | 671 | return error; |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | +static inline unsigned long dir_pages(struct inode *inode) | |
| 675 | +{ | |
| 676 | + return (unsigned long)(inode->i_size + PAGE_CACHE_SIZE - 1) >> | |
| 677 | + PAGE_CACHE_SHIFT; | |
| 678 | +} | |
| 679 | + | |
| 674 | 680 | #endif /* _LINUX_PAGEMAP_H */ |
| @@ -123,6 +123,7 @@ __printf(2, 3) int seq_printf(struct seq_file *, const char *, ...); · 122 unmodified lines | ||
| 123 | 123 | __printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args); |
| 124 | 124 | |
| 125 | 125 | int seq_path(struct seq_file *, const struct path *, const char *); |
| 126 | +int seq_file_path(struct seq_file *, struct file *, const char *); | |
| 126 | 127 | int seq_dentry(struct seq_file *, struct dentry *, const char *); |
| 127 | 128 | int seq_path_root(struct seq_file *m, const struct path *path, |
| 128 | 129 | const struct path *root, const char *esc); |
| @@ -5794,7 +5794,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) · 5793 unmodified lines | ||
| 5794 | 5794 | * need to add enough zero bytes after the string to handle |
| 5795 | 5795 | * the 64bit alignment we do later. |
| 5796 | 5796 | */ |
| 5797 | − name = d_path(&file->f_path, buf, PATH_MAX - sizeof(u64)); | |
| 5797 | + name = file_path(file, buf, PATH_MAX - sizeof(u64)); | |
| 5798 | 5798 | if (IS_ERR(name)) { |
| 5799 | 5799 | name = "//toolong"; |
| 5800 | 5800 | goto cpy_name; |
| @@ -2563,7 +2563,7 @@ ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) · 2562 unmodified lines | ||
| 2563 | 2563 | |
| 2564 | 2564 | /* We can write back this queue in page reclaim */ |
| 2565 | 2565 | current->backing_dev_info = inode_to_bdi(inode); |
| 2566 | − err = file_remove_suid(file); | |
| 2566 | + err = file_remove_privs(file); | |
| 2567 | 2567 | if (err) |
| 2568 | 2568 | goto out; |
| 2569 | 2569 | |
| @@ -3726,7 +3726,7 @@ void print_vma_addr(char *prefix, unsigned long ip) · 3725 unmodified lines | ||
| 3726 | 3726 | if (buf) { |
| 3727 | 3727 | char *p; |
| 3728 | 3728 | |
| 3729 | − p = d_path(&f->f_path, buf, PAGE_SIZE); | |
| 3729 | + p = file_path(f, buf, PAGE_SIZE); | |
| 3730 | 3730 | if (IS_ERR(p)) |
| 3731 | 3731 | p = "?"; |
| 3732 | 3732 | printk("%s%s[%lx+%lx]", prefix, kbasename(p), |
| @@ -2032,7 +2032,7 @@ static int swap_show(struct seq_file *swap, void *v) · 2031 unmodified lines | ||
| 2032 | 2032 | } |
| 2033 | 2033 | |
| 2034 | 2034 | file = si->swap_file; |
| 2035 | − len = seq_path(swap, &file->f_path, " \t\n\\"); | |
| 2035 | + len = seq_file_path(swap, file, " \t\n\\"); | |
| 2036 | 2036 | seq_printf(swap, "%*s%s\t%u\t%u\t%d\n", |
| 2037 | 2037 | len < 40 ? 40 - len : 1, " ", |
| 2038 | 2038 | S_ISBLK(file_inode(file)->i_mode) ? |
| @@ -843,7 +843,8 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, · 842 unmodified lines | ||
| 843 | 843 | if (err < 0) { |
| 844 | 844 | if (err == -EIO) |
| 845 | 845 | c->status = Disconnected; |
| 846 | − goto reterr; | |
| 846 | + if (err != -ERESTARTSYS) | |
| 847 | + goto reterr; | |
| 847 | 848 | } |
| 848 | 849 | if (req->status == REQ_STATUS_ERROR) { |
| 849 | 850 | p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); |
| @@ -1582,6 +1583,10 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) · 732 unmodified lines | ||
| 1582 | 1583 | p9_free_req(clnt, req); |
| 1583 | 1584 | break; |
| 1584 | 1585 | } |
| 1586 | + if (rsize < count) { | |
| 1587 | + pr_err("bogus RREAD count (%d > %d)\n", count, rsize); | |
| 1588 | + count = rsize; | |
| 1589 | + } | |
| 1585 | 1590 | |
| 1586 | 1591 | p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); |
| 1587 | 1592 | if (!count) { |
| @@ -1647,6 +1652,11 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) · 59 unmodified lines | ||
| 1647 | 1652 | if (*err) { |
| 1648 | 1653 | trace_9p_protocol_dump(clnt, req->rc); |
| 1649 | 1654 | p9_free_req(clnt, req); |
| 1655 | + break; | |
| 1656 | + } | |
| 1657 | + if (rsize < count) { | |
| 1658 | + pr_err("bogus RWRITE count (%d > %d)\n", count, rsize); | |
| 1659 | + count = rsize; | |
| 1650 | 1660 | } |
| 1651 | 1661 | |
| 1652 | 1662 | p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); |
| @@ -25,11 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | static struct vfsmount *mount; |
| 26 | 26 | static int mount_count; |
| 27 | 27 | |
| 28 | −static inline int positive(struct dentry *dentry) | |
| 29 | −{ | |
| 30 | − return d_really_is_positive(dentry) && !d_unhashed(dentry); | |
| 31 | −} | |
| 32 | − | |
| 33 | 28 | static int fill_super(struct super_block *sb, void *data, int silent) |
| 34 | 29 | { |
| 35 | 30 | static struct tree_descr files[] = {{""}}; |
| @@ -201,14 +196,12 @@ void securityfs_remove(struct dentry *dentry) · 165 unmodified lines | ||
| 201 | 196 | return; |
| 202 | 197 | |
| 203 | 198 | mutex_lock(&d_inode(parent)->i_mutex); |
| 204 | − if (positive(dentry)) { | |
| 205 | − if (d_really_is_positive(dentry)) { | |
| 206 | − if (d_is_dir(dentry)) | |
| 207 | − simple_rmdir(d_inode(parent), dentry); | |
| 208 | − else | |
| 209 | − simple_unlink(d_inode(parent), dentry); | |
| 210 | − dput(dentry); | |
| 211 | − } | |
| 199 | + if (simple_positive(dentry)) { | |
| 200 | + if (d_is_dir(dentry)) | |
| 201 | + simple_rmdir(d_inode(parent), dentry); | |
| 202 | + else | |
| 203 | + simple_unlink(d_inode(parent), dentry); | |
| 204 | + dput(dentry); | |
| 212 | 205 | } |
| 213 | 206 | mutex_unlock(&d_inode(parent)->i_mutex); |
| 214 | 207 | simple_release_fs(&mount, &mount_count); |