Commit 36947a76826111e661a26cb0f668a5be6cc3ddb4
Exists in
master
and in
39 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (36 commits) Cache xattr security drop check for write v2 fs: block_page_mkwrite should wait for writeback to finish mm: Wait for writeback when grabbing pages to begin a write configfs: remove unnecessary dentry_unhash on rmdir, dir rename fat: remove unnecessary dentry_unhash on rmdir, dir rename hpfs: remove unnecessary dentry_unhash on rmdir, dir rename minix: remove unnecessary dentry_unhash on rmdir, dir rename fuse: remove unnecessary dentry_unhash on rmdir, dir rename coda: remove unnecessary dentry_unhash on rmdir, dir rename afs: remove unnecessary dentry_unhash on rmdir, dir rename affs: remove unnecessary dentry_unhash on rmdir, dir rename 9p: remove unnecessary dentry_unhash on rmdir, dir rename ncpfs: fix rename over directory with dangling references ncpfs: document dentry_unhash usage ecryptfs: remove unnecessary dentry_unhash on rmdir, dir rename hostfs: remove unnecessary dentry_unhash on rmdir, dir rename hfsplus: remove unnecessary dentry_unhash on rmdir, dir rename hfs: remove unnecessary dentry_unhash on rmdir, dir rename omfs: remove unnecessary dentry_unhash on rmdir, dir rneame udf: remove unnecessary dentry_unhash from rmdir, dir rename ...
Showing 53 changed files Side-by-side Diff
- Documentation/filesystems/Locking
- Documentation/filesystems/vfs.txt
- fs/9p/vfs_inode.c
- fs/affs/namei.c
- fs/afs/dir.c
- fs/attr.c
- fs/bfs/dir.c
- fs/bio.c
- fs/btrfs/ctree.h
- fs/btrfs/inode.c
- fs/buffer.c
- fs/coda/dir.c
- fs/configfs/dir.c
- fs/ecryptfs/inode.c
- fs/ext3/inode.c
- fs/ext4/ext4.h
- fs/ext4/inode.c
- fs/fat/namei_msdos.c
- fs/fat/namei_vfat.c
- fs/fs-writeback.c
- fs/fuse/dir.c
- fs/hfs/dir.c
- fs/hfsplus/dir.c
- fs/hostfs/hostfs_kern.c
- fs/hpfs/namei.c
- fs/inode.c
- fs/jffs2/dir.c
- fs/jffs2/fs.c
- fs/jffs2/os-linux.h
- fs/jfs/inode.c
- fs/jfs/jfs_inode.h
- fs/jfs/namei.c
- fs/logfs/dir.c
- fs/minix/namei.c
- fs/namei.c
- fs/ncpfs/dir.c
- fs/nilfs2/inode.c
- fs/nilfs2/namei.c
- fs/nilfs2/nilfs.h
- fs/omfs/dir.c
- fs/reiserfs/namei.c
- fs/reiserfs/super.c
- fs/reiserfs/xattr.c
- fs/sysv/namei.c
- fs/ubifs/dir.c
- fs/ubifs/super.c
- fs/udf/namei.c
- fs/ufs/namei.c
- fs/xattr.c
- fs/xfs/linux-2.6/xfs_super.c
- include/linux/ext3_fs.h
- include/linux/fs.h
- mm/filemap.c
Documentation/filesystems/Locking
... | ... | @@ -104,7 +104,7 @@ |
104 | 104 | prototypes: |
105 | 105 | struct inode *(*alloc_inode)(struct super_block *sb); |
106 | 106 | void (*destroy_inode)(struct inode *); |
107 | - void (*dirty_inode) (struct inode *); | |
107 | + void (*dirty_inode) (struct inode *, int flags); | |
108 | 108 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
109 | 109 | int (*drop_inode) (struct inode *); |
110 | 110 | void (*evict_inode) (struct inode *); |
... | ... | @@ -126,7 +126,7 @@ |
126 | 126 | s_umount |
127 | 127 | alloc_inode: |
128 | 128 | destroy_inode: |
129 | -dirty_inode: (must not sleep) | |
129 | +dirty_inode: | |
130 | 130 | write_inode: |
131 | 131 | drop_inode: !!!inode->i_lock!!! |
132 | 132 | evict_inode: |
Documentation/filesystems/vfs.txt
... | ... | @@ -211,7 +211,7 @@ |
211 | 211 | struct inode *(*alloc_inode)(struct super_block *sb); |
212 | 212 | void (*destroy_inode)(struct inode *); |
213 | 213 | |
214 | - void (*dirty_inode) (struct inode *); | |
214 | + void (*dirty_inode) (struct inode *, int flags); | |
215 | 215 | int (*write_inode) (struct inode *, int); |
216 | 216 | void (*drop_inode) (struct inode *); |
217 | 217 | void (*delete_inode) (struct inode *); |
fs/9p/vfs_inode.c
... | ... | @@ -814,7 +814,6 @@ |
814 | 814 | |
815 | 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
816 | 816 | { |
817 | - dentry_unhash(d); | |
818 | 817 | return v9fs_remove(i, d, 1); |
819 | 818 | } |
820 | 819 | |
... | ... | @@ -839,9 +838,6 @@ |
839 | 838 | struct p9_fid *olddirfid; |
840 | 839 | struct p9_fid *newdirfid; |
841 | 840 | struct p9_wstat wstat; |
842 | - | |
843 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
844 | - dentry_unhash(new_dentry); | |
845 | 841 | |
846 | 842 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
847 | 843 | retval = 0; |
fs/affs/namei.c
... | ... | @@ -320,8 +320,6 @@ |
320 | 320 | dentry->d_inode->i_ino, |
321 | 321 | (int)dentry->d_name.len, dentry->d_name.name); |
322 | 322 | |
323 | - dentry_unhash(dentry); | |
324 | - | |
325 | 323 | return affs_remove_header(dentry); |
326 | 324 | } |
327 | 325 | |
... | ... | @@ -418,9 +416,6 @@ |
418 | 416 | struct super_block *sb = old_dir->i_sb; |
419 | 417 | struct buffer_head *bh = NULL; |
420 | 418 | int retval; |
421 | - | |
422 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
423 | - dentry_unhash(new_dentry); | |
424 | 419 | |
425 | 420 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
426 | 421 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
fs/afs/dir.c
... | ... | @@ -845,8 +845,6 @@ |
845 | 845 | _enter("{%x:%u},{%s}", |
846 | 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); |
847 | 847 | |
848 | - dentry_unhash(dentry); | |
849 | - | |
850 | 848 | ret = -ENAMETOOLONG; |
851 | 849 | if (dentry->d_name.len >= AFSNAMEMAX) |
852 | 850 | goto error; |
... | ... | @@ -1147,9 +1145,6 @@ |
1147 | 1145 | struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; |
1148 | 1146 | struct key *key; |
1149 | 1147 | int ret; |
1150 | - | |
1151 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1152 | - dentry_unhash(new_dentry); | |
1153 | 1148 | |
1154 | 1149 | vnode = AFS_FS_I(old_dentry->d_inode); |
1155 | 1150 | orig_dvnode = AFS_FS_I(old_dir); |
fs/attr.c
... | ... | @@ -175,6 +175,13 @@ |
175 | 175 | return -EPERM; |
176 | 176 | } |
177 | 177 | |
178 | + if ((ia_valid & ATTR_MODE)) { | |
179 | + mode_t amode = attr->ia_mode; | |
180 | + /* Flag setting protected by i_mutex */ | |
181 | + if (is_sxid(amode)) | |
182 | + inode->i_flags &= ~S_NOSEC; | |
183 | + } | |
184 | + | |
178 | 185 | now = current_fs_time(inode->i_sb); |
179 | 186 | |
180 | 187 | attr->ia_ctime = now; |
fs/bfs/dir.c
... | ... | @@ -224,9 +224,6 @@ |
224 | 224 | struct bfs_sb_info *info; |
225 | 225 | int error = -ENOENT; |
226 | 226 | |
227 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
228 | - dentry_unhash(new_dentry); | |
229 | - | |
230 | 227 | old_bh = new_bh = NULL; |
231 | 228 | old_inode = old_dentry->d_inode; |
232 | 229 | if (S_ISDIR(old_inode->i_mode)) |
fs/bio.c
... | ... | @@ -638,10 +638,11 @@ |
638 | 638 | * @offset: vec entry offset |
639 | 639 | * |
640 | 640 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
641 | - * number of reasons, such as the bio being full or target block | |
642 | - * device limitations. The target block device must allow bio's | |
643 | - * smaller than PAGE_SIZE, so it is always possible to add a single | |
644 | - * page to an empty bio. This should only be used by REQ_PC bios. | |
641 | + * number of reasons, such as the bio being full or target block device | |
642 | + * limitations. The target block device must allow bio's up to PAGE_SIZE, | |
643 | + * so it is always possible to add a single page to an empty bio. | |
644 | + * | |
645 | + * This should only be used by REQ_PC bios. | |
645 | 646 | */ |
646 | 647 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, |
647 | 648 | unsigned int len, unsigned int offset) |
... | ... | @@ -659,10 +660,9 @@ |
659 | 660 | * @offset: vec entry offset |
660 | 661 | * |
661 | 662 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
662 | - * number of reasons, such as the bio being full or target block | |
663 | - * device limitations. The target block device must allow bio's | |
664 | - * smaller than PAGE_SIZE, so it is always possible to add a single | |
665 | - * page to an empty bio. | |
663 | + * number of reasons, such as the bio being full or target block device | |
664 | + * limitations. The target block device must allow bio's up to PAGE_SIZE, | |
665 | + * so it is always possible to add a single page to an empty bio. | |
666 | 666 | */ |
667 | 667 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, |
668 | 668 | unsigned int offset) |
fs/btrfs/ctree.h
... | ... | @@ -2524,7 +2524,7 @@ |
2524 | 2524 | int btrfs_readpage(struct file *file, struct page *page); |
2525 | 2525 | void btrfs_evict_inode(struct inode *inode); |
2526 | 2526 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2527 | -void btrfs_dirty_inode(struct inode *inode); | |
2527 | +void btrfs_dirty_inode(struct inode *inode, int flags); | |
2528 | 2528 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2529 | 2529 | void btrfs_destroy_inode(struct inode *inode); |
2530 | 2530 | int btrfs_drop_inode(struct inode *inode); |
fs/btrfs/inode.c
... | ... | @@ -4294,7 +4294,7 @@ |
4294 | 4294 | * FIXME, needs more benchmarking...there are no reasons other than performance |
4295 | 4295 | * to keep or drop this code. |
4296 | 4296 | */ |
4297 | -void btrfs_dirty_inode(struct inode *inode) | |
4297 | +void btrfs_dirty_inode(struct inode *inode, int flags) | |
4298 | 4298 | { |
4299 | 4299 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4300 | 4300 | struct btrfs_trans_handle *trans; |
fs/buffer.c
fs/coda/dir.c
... | ... | @@ -336,8 +336,6 @@ |
336 | 336 | int len = de->d_name.len; |
337 | 337 | int error; |
338 | 338 | |
339 | - dentry_unhash(de); | |
340 | - | |
341 | 339 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
342 | 340 | if (!error) { |
343 | 341 | /* VFS may delete the child */ |
... | ... | @@ -360,9 +358,6 @@ |
360 | 358 | int old_length = old_dentry->d_name.len; |
361 | 359 | int new_length = new_dentry->d_name.len; |
362 | 360 | int error; |
363 | - | |
364 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
365 | - dentry_unhash(new_dentry); | |
366 | 361 | |
367 | 362 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
368 | 363 | coda_i2f(new_dir), old_length, new_length, |
fs/configfs/dir.c
fs/ecryptfs/inode.c
... | ... | @@ -521,8 +521,6 @@ |
521 | 521 | struct dentry *lower_dir_dentry; |
522 | 522 | int rc; |
523 | 523 | |
524 | - dentry_unhash(dentry); | |
525 | - | |
526 | 524 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
527 | 525 | dget(dentry); |
528 | 526 | lower_dir_dentry = lock_parent(lower_dentry); |
... | ... | @@ -574,9 +572,6 @@ |
574 | 572 | struct dentry *lower_old_dir_dentry; |
575 | 573 | struct dentry *lower_new_dir_dentry; |
576 | 574 | struct dentry *trap = NULL; |
577 | - | |
578 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
579 | - dentry_unhash(new_dentry); | |
580 | 575 | |
581 | 576 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
582 | 577 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
fs/ext3/inode.c
... | ... | @@ -3392,7 +3392,7 @@ |
3392 | 3392 | * so would cause a commit on atime updates, which we don't bother doing. |
3393 | 3393 | * We handle synchronous inodes at the highest possible level. |
3394 | 3394 | */ |
3395 | -void ext3_dirty_inode(struct inode *inode) | |
3395 | +void ext3_dirty_inode(struct inode *inode, int flags) | |
3396 | 3396 | { |
3397 | 3397 | handle_t *current_handle = ext3_journal_current_handle(); |
3398 | 3398 | handle_t *handle; |
fs/ext4/ext4.h
... | ... | @@ -1813,7 +1813,7 @@ |
1813 | 1813 | extern void ext4_evict_inode(struct inode *); |
1814 | 1814 | extern void ext4_clear_inode(struct inode *); |
1815 | 1815 | extern int ext4_sync_inode(handle_t *, struct inode *); |
1816 | -extern void ext4_dirty_inode(struct inode *); | |
1816 | +extern void ext4_dirty_inode(struct inode *, int); | |
1817 | 1817 | extern int ext4_change_inode_journal_flag(struct inode *, int); |
1818 | 1818 | extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); |
1819 | 1819 | extern int ext4_can_truncate(struct inode *inode); |
fs/ext4/inode.c
... | ... | @@ -5733,7 +5733,7 @@ |
5733 | 5733 | * so would cause a commit on atime updates, which we don't bother doing. |
5734 | 5734 | * We handle synchronous inodes at the highest possible level. |
5735 | 5735 | */ |
5736 | -void ext4_dirty_inode(struct inode *inode) | |
5736 | +void ext4_dirty_inode(struct inode *inode, int flags) | |
5737 | 5737 | { |
5738 | 5738 | handle_t *handle; |
5739 | 5739 |
fs/fat/namei_msdos.c
... | ... | @@ -326,8 +326,6 @@ |
326 | 326 | struct fat_slot_info sinfo; |
327 | 327 | int err; |
328 | 328 | |
329 | - dentry_unhash(dentry); | |
330 | - | |
331 | 329 | lock_super(sb); |
332 | 330 | /* |
333 | 331 | * Check whether the directory is not in use, then check |
... | ... | @@ -458,9 +456,6 @@ |
458 | 456 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
459 | 457 | old_inode = old_dentry->d_inode; |
460 | 458 | new_inode = new_dentry->d_inode; |
461 | - | |
462 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
463 | - dentry_unhash(new_dentry); | |
464 | 459 | |
465 | 460 | err = fat_scan(old_dir, old_name, &old_sinfo); |
466 | 461 | if (err) { |
fs/fat/namei_vfat.c
... | ... | @@ -824,8 +824,6 @@ |
824 | 824 | struct fat_slot_info sinfo; |
825 | 825 | int err; |
826 | 826 | |
827 | - dentry_unhash(dentry); | |
828 | - | |
829 | 827 | lock_super(sb); |
830 | 828 | |
831 | 829 | err = fat_dir_empty(inode); |
... | ... | @@ -932,9 +930,6 @@ |
932 | 930 | loff_t dotdot_i_pos, new_i_pos; |
933 | 931 | int err, is_dir, update_dotdot, corrupt = 0; |
934 | 932 | struct super_block *sb = old_dir->i_sb; |
935 | - | |
936 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
937 | - dentry_unhash(new_dentry); | |
938 | 933 | |
939 | 934 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
940 | 935 | old_inode = old_dentry->d_inode; |
fs/fs-writeback.c
... | ... | @@ -1007,9 +1007,6 @@ |
1007 | 1007 | * In short, make sure you hash any inodes _before_ you start marking |
1008 | 1008 | * them dirty. |
1009 | 1009 | * |
1010 | - * This function *must* be atomic for the I_DIRTY_PAGES case - | |
1011 | - * set_page_dirty() is called under spinlock in several places. | |
1012 | - * | |
1013 | 1010 | * Note that for blockdevs, inode->dirtied_when represents the dirtying time of |
1014 | 1011 | * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of |
1015 | 1012 | * the kernel-internal blockdev inode represents the dirtying time of the |
... | ... | @@ -1028,7 +1025,7 @@ |
1028 | 1025 | */ |
1029 | 1026 | if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { |
1030 | 1027 | if (sb->s_op->dirty_inode) |
1031 | - sb->s_op->dirty_inode(inode); | |
1028 | + sb->s_op->dirty_inode(inode, flags); | |
1032 | 1029 | } |
1033 | 1030 | |
1034 | 1031 | /* |
fs/fuse/dir.c
... | ... | @@ -667,8 +667,6 @@ |
667 | 667 | if (IS_ERR(req)) |
668 | 668 | return PTR_ERR(req); |
669 | 669 | |
670 | - dentry_unhash(entry); | |
671 | - | |
672 | 670 | req->in.h.opcode = FUSE_RMDIR; |
673 | 671 | req->in.h.nodeid = get_node_id(dir); |
674 | 672 | req->in.numargs = 1; |
... | ... | @@ -693,9 +691,6 @@ |
693 | 691 | struct fuse_rename_in inarg; |
694 | 692 | struct fuse_conn *fc = get_fuse_conn(olddir); |
695 | 693 | struct fuse_req *req = fuse_get_req(fc); |
696 | - | |
697 | - if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode)) | |
698 | - dentry_unhash(newent); | |
699 | 694 | |
700 | 695 | if (IS_ERR(req)) |
701 | 696 | return PTR_ERR(req); |
fs/hfs/dir.c
... | ... | @@ -253,9 +253,6 @@ |
253 | 253 | struct inode *inode = dentry->d_inode; |
254 | 254 | int res; |
255 | 255 | |
256 | - if (S_ISDIR(inode->i_mode)) | |
257 | - dentry_unhash(dentry); | |
258 | - | |
259 | 256 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) |
260 | 257 | return -ENOTEMPTY; |
261 | 258 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
... | ... | @@ -286,9 +283,6 @@ |
286 | 283 | |
287 | 284 | /* Unlink destination if it already exists */ |
288 | 285 | if (new_dentry->d_inode) { |
289 | - if (S_ISDIR(new_dentry->d_inode->i_mode)) | |
290 | - dentry_unhash(new_dentry); | |
291 | - | |
292 | 286 | res = hfs_remove(new_dir, new_dentry); |
293 | 287 | if (res) |
294 | 288 | return res; |
fs/hfsplus/dir.c
... | ... | @@ -370,8 +370,6 @@ |
370 | 370 | struct inode *inode = dentry->d_inode; |
371 | 371 | int res; |
372 | 372 | |
373 | - dentry_unhash(dentry); | |
374 | - | |
375 | 373 | if (inode->i_size != 2) |
376 | 374 | return -ENOTEMPTY; |
377 | 375 | |
378 | 376 | |
379 | 377 | |
... | ... | @@ -469,12 +467,10 @@ |
469 | 467 | |
470 | 468 | /* Unlink destination if it already exists */ |
471 | 469 | if (new_dentry->d_inode) { |
472 | - if (S_ISDIR(new_dentry->d_inode->i_mode)) { | |
473 | - dentry_unhash(new_dentry); | |
470 | + if (S_ISDIR(new_dentry->d_inode->i_mode)) | |
474 | 471 | res = hfsplus_rmdir(new_dir, new_dentry); |
475 | - } else { | |
472 | + else | |
476 | 473 | res = hfsplus_unlink(new_dir, new_dentry); |
477 | - } | |
478 | 474 | if (res) |
479 | 475 | return res; |
480 | 476 | } |
fs/hostfs/hostfs_kern.c
... | ... | @@ -683,8 +683,6 @@ |
683 | 683 | char *file; |
684 | 684 | int err; |
685 | 685 | |
686 | - dentry_unhash(dentry); | |
687 | - | |
688 | 686 | if ((file = dentry_name(dentry)) == NULL) |
689 | 687 | return -ENOMEM; |
690 | 688 | err = do_rmdir(file); |
... | ... | @@ -737,9 +735,6 @@ |
737 | 735 | { |
738 | 736 | char *from_name, *to_name; |
739 | 737 | int err; |
740 | - | |
741 | - if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | |
742 | - dentry_unhash(to); | |
743 | 738 | |
744 | 739 | if ((from_name = dentry_name(from)) == NULL) |
745 | 740 | return -ENOMEM; |
fs/hpfs/namei.c
... | ... | @@ -439,8 +439,6 @@ |
439 | 439 | int err; |
440 | 440 | int r; |
441 | 441 | |
442 | - dentry_unhash(dentry); | |
443 | - | |
444 | 442 | hpfs_adjust_length(name, &len); |
445 | 443 | hpfs_lock(dir->i_sb); |
446 | 444 | err = -ENOENT; |
... | ... | @@ -534,9 +532,6 @@ |
534 | 532 | struct buffer_head *bh; |
535 | 533 | struct fnode *fnode; |
536 | 534 | int err; |
537 | - | |
538 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
539 | - dentry_unhash(new_dentry); | |
540 | 535 | |
541 | 536 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
542 | 537 | err = 0; |
fs/inode.c
1 | 1 | /* |
2 | - * linux/fs/inode.c | |
3 | - * | |
4 | 2 | * (C) 1997 Linus Torvalds |
3 | + * (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation) | |
5 | 4 | */ |
6 | - | |
7 | 5 | #include <linux/fs.h> |
8 | 6 | #include <linux/mm.h> |
9 | 7 | #include <linux/dcache.h> |
10 | 8 | |
... | ... | @@ -27,10 +25,11 @@ |
27 | 25 | #include <linux/prefetch.h> |
28 | 26 | #include <linux/ima.h> |
29 | 27 | #include <linux/cred.h> |
28 | +#include <linux/buffer_head.h> /* for inode_has_buffers */ | |
30 | 29 | #include "internal.h" |
31 | 30 | |
32 | 31 | /* |
33 | - * inode locking rules. | |
32 | + * Inode locking rules: | |
34 | 33 | * |
35 | 34 | * inode->i_lock protects: |
36 | 35 | * inode->i_state, inode->i_hash, __iget() |
37 | 36 | |
... | ... | @@ -60,54 +59,11 @@ |
60 | 59 | * inode_hash_lock |
61 | 60 | */ |
62 | 61 | |
63 | -/* | |
64 | - * This is needed for the following functions: | |
65 | - * - inode_has_buffers | |
66 | - * - invalidate_bdev | |
67 | - * | |
68 | - * FIXME: remove all knowledge of the buffer layer from this file | |
69 | - */ | |
70 | -#include <linux/buffer_head.h> | |
71 | - | |
72 | -/* | |
73 | - * New inode.c implementation. | |
74 | - * | |
75 | - * This implementation has the basic premise of trying | |
76 | - * to be extremely low-overhead and SMP-safe, yet be | |
77 | - * simple enough to be "obviously correct". | |
78 | - * | |
79 | - * Famous last words. | |
80 | - */ | |
81 | - | |
82 | -/* inode dynamic allocation 1999, Andrea Arcangeli <andrea@suse.de> */ | |
83 | - | |
84 | -/* #define INODE_PARANOIA 1 */ | |
85 | -/* #define INODE_DEBUG 1 */ | |
86 | - | |
87 | -/* | |
88 | - * Inode lookup is no longer as critical as it used to be: | |
89 | - * most of the lookups are going to be through the dcache. | |
90 | - */ | |
91 | -#define I_HASHBITS i_hash_shift | |
92 | -#define I_HASHMASK i_hash_mask | |
93 | - | |
94 | 62 | static unsigned int i_hash_mask __read_mostly; |
95 | 63 | static unsigned int i_hash_shift __read_mostly; |
96 | 64 | static struct hlist_head *inode_hashtable __read_mostly; |
97 | 65 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); |
98 | 66 | |
99 | -/* | |
100 | - * Each inode can be on two separate lists. One is | |
101 | - * the hash list of the inode, used for lookups. The | |
102 | - * other linked list is the "type" list: | |
103 | - * "in_use" - valid inode, i_count > 0, i_nlink > 0 | |
104 | - * "dirty" - as "in_use" but also dirty | |
105 | - * "unused" - valid inode, i_count = 0 | |
106 | - * | |
107 | - * A "dirty" list is maintained for each super block, | |
108 | - * allowing for low-overhead inode sync() operations. | |
109 | - */ | |
110 | - | |
111 | 67 | static LIST_HEAD(inode_lru); |
112 | 68 | static DEFINE_SPINLOCK(inode_lru_lock); |
113 | 69 | |
... | ... | @@ -424,8 +380,8 @@ |
424 | 380 | |
425 | 381 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / |
426 | 382 | L1_CACHE_BYTES; |
427 | - tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | |
428 | - return tmp & I_HASHMASK; | |
383 | + tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> i_hash_shift); | |
384 | + return tmp & i_hash_mask; | |
429 | 385 | } |
430 | 386 | |
431 | 387 | /** |
fs/jffs2/dir.c
... | ... | @@ -605,8 +605,6 @@ |
605 | 605 | int ret; |
606 | 606 | uint32_t now = get_seconds(); |
607 | 607 | |
608 | - dentry_unhash(dentry); | |
609 | - | |
610 | 608 | for (fd = f->dents ; fd; fd = fd->next) { |
611 | 609 | if (fd->ino) |
612 | 610 | return -ENOTEMPTY; |
... | ... | @@ -781,9 +779,6 @@ |
781 | 779 | struct jffs2_inode_info *victim_f = NULL; |
782 | 780 | uint8_t type; |
783 | 781 | uint32_t now; |
784 | - | |
785 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
786 | - dentry_unhash(new_dentry); | |
787 | 782 | |
788 | 783 | /* The VFS will check for us and prevent trying to rename a |
789 | 784 | * file over a directory and vice versa, but if it's a directory, |
fs/jffs2/fs.c
fs/jffs2/os-linux.h
... | ... | @@ -172,7 +172,7 @@ |
172 | 172 | int jffs2_do_setattr (struct inode *, struct iattr *); |
173 | 173 | struct inode *jffs2_iget(struct super_block *, unsigned long); |
174 | 174 | void jffs2_evict_inode (struct inode *); |
175 | -void jffs2_dirty_inode(struct inode *inode); | |
175 | +void jffs2_dirty_inode(struct inode *inode, int flags); | |
176 | 176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, |
177 | 177 | struct jffs2_raw_inode *ri); |
178 | 178 | int jffs2_statfs (struct dentry *, struct kstatfs *); |
fs/jfs/inode.c
fs/jfs/jfs_inode.h
... | ... | @@ -28,7 +28,7 @@ |
28 | 28 | extern int jfs_commit_inode(struct inode *, int); |
29 | 29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); |
30 | 30 | extern void jfs_evict_inode(struct inode *); |
31 | -extern void jfs_dirty_inode(struct inode *); | |
31 | +extern void jfs_dirty_inode(struct inode *, int); | |
32 | 32 | extern void jfs_truncate(struct inode *); |
33 | 33 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
34 | 34 | extern void jfs_free_zero_link(struct inode *); |
fs/jfs/namei.c
... | ... | @@ -360,8 +360,6 @@ |
360 | 360 | |
361 | 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); |
362 | 362 | |
363 | - dentry_unhash(dentry); | |
364 | - | |
365 | 363 | /* Init inode for quota operations. */ |
366 | 364 | dquot_initialize(dip); |
367 | 365 | dquot_initialize(ip); |
... | ... | @@ -1096,9 +1094,6 @@ |
1096 | 1094 | |
1097 | 1095 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
1098 | 1096 | new_dentry->d_name.name); |
1099 | - | |
1100 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1101 | - dentry_unhash(new_dentry); | |
1102 | 1097 | |
1103 | 1098 | dquot_initialize(old_dir); |
1104 | 1099 | dquot_initialize(new_dir); |
fs/logfs/dir.c
... | ... | @@ -273,8 +273,6 @@ |
273 | 273 | { |
274 | 274 | struct inode *inode = dentry->d_inode; |
275 | 275 | |
276 | - dentry_unhash(dentry); | |
277 | - | |
278 | 276 | if (!logfs_empty_dir(inode)) |
279 | 277 | return -ENOTEMPTY; |
280 | 278 | |
... | ... | @@ -623,9 +621,6 @@ |
623 | 621 | struct logfs_transaction *ta; |
624 | 622 | loff_t pos; |
625 | 623 | int err; |
626 | - | |
627 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
628 | - dentry_unhash(new_dentry); | |
629 | 624 | |
630 | 625 | /* 1. locate source dd */ |
631 | 626 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); |
fs/minix/namei.c
... | ... | @@ -168,8 +168,6 @@ |
168 | 168 | struct inode * inode = dentry->d_inode; |
169 | 169 | int err = -ENOTEMPTY; |
170 | 170 | |
171 | - dentry_unhash(dentry); | |
172 | - | |
173 | 171 | if (minix_empty_dir(inode)) { |
174 | 172 | err = minix_unlink(dir, dentry); |
175 | 173 | if (!err) { |
... | ... | @@ -191,9 +189,6 @@ |
191 | 189 | struct page * old_page; |
192 | 190 | struct minix_dir_entry * old_de; |
193 | 191 | int err = -ENOENT; |
194 | - | |
195 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
196 | - dentry_unhash(new_dentry); | |
197 | 192 | |
198 | 193 | old_de = minix_find_entry(old_dentry, &old_page); |
199 | 194 | if (!old_de) |
fs/namei.c
... | ... | @@ -919,12 +919,11 @@ |
919 | 919 | } |
920 | 920 | |
921 | 921 | /* |
922 | - * Skip to top of mountpoint pile in rcuwalk mode. We abort the rcu-walk if we | |
923 | - * meet a managed dentry and we're not walking to "..". True is returned to | |
924 | - * continue, false to abort. | |
922 | + * Try to skip to top of mountpoint pile in rcuwalk mode. Fail if | |
923 | + * we meet a managed dentry that would need blocking. | |
925 | 924 | */ |
926 | 925 | static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, |
927 | - struct inode **inode, bool reverse_transit) | |
926 | + struct inode **inode) | |
928 | 927 | { |
929 | 928 | for (;;) { |
930 | 929 | struct vfsmount *mounted; |
... | ... | @@ -933,8 +932,7 @@ |
933 | 932 | * that wants to block transit. |
934 | 933 | */ |
935 | 934 | *inode = path->dentry->d_inode; |
936 | - if (!reverse_transit && | |
937 | - unlikely(managed_dentry_might_block(path->dentry))) | |
935 | + if (unlikely(managed_dentry_might_block(path->dentry))) | |
938 | 936 | return false; |
939 | 937 | |
940 | 938 | if (!d_mountpoint(path->dentry)) |
941 | 939 | |
942 | 940 | |
943 | 941 | |
... | ... | @@ -947,16 +945,24 @@ |
947 | 945 | path->dentry = mounted->mnt_root; |
948 | 946 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); |
949 | 947 | } |
950 | - | |
951 | - if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | |
952 | - return reverse_transit; | |
953 | 948 | return true; |
954 | 949 | } |
955 | 950 | |
956 | -static int follow_dotdot_rcu(struct nameidata *nd) | |
951 | +static void follow_mount_rcu(struct nameidata *nd) | |
957 | 952 | { |
958 | - struct inode *inode = nd->inode; | |
953 | + while (d_mountpoint(nd->path.dentry)) { | |
954 | + struct vfsmount *mounted; | |
955 | + mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); | |
956 | + if (!mounted) | |
957 | + break; | |
958 | + nd->path.mnt = mounted; | |
959 | + nd->path.dentry = mounted->mnt_root; | |
960 | + nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | |
961 | + } | |
962 | +} | |
959 | 963 | |
964 | +static int follow_dotdot_rcu(struct nameidata *nd) | |
965 | +{ | |
960 | 966 | set_root_rcu(nd); |
961 | 967 | |
962 | 968 | while (1) { |
... | ... | @@ -972,7 +978,6 @@ |
972 | 978 | seq = read_seqcount_begin(&parent->d_seq); |
973 | 979 | if (read_seqcount_retry(&old->d_seq, nd->seq)) |
974 | 980 | goto failed; |
975 | - inode = parent->d_inode; | |
976 | 981 | nd->path.dentry = parent; |
977 | 982 | nd->seq = seq; |
978 | 983 | break; |
979 | 984 | |
... | ... | @@ -980,10 +985,9 @@ |
980 | 985 | if (!follow_up_rcu(&nd->path)) |
981 | 986 | break; |
982 | 987 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); |
983 | - inode = nd->path.dentry->d_inode; | |
984 | 988 | } |
985 | - __follow_mount_rcu(nd, &nd->path, &inode, true); | |
986 | - nd->inode = inode; | |
989 | + follow_mount_rcu(nd); | |
990 | + nd->inode = nd->path.dentry->d_inode; | |
987 | 991 | return 0; |
988 | 992 | |
989 | 993 | failed: |
... | ... | @@ -1157,8 +1161,11 @@ |
1157 | 1161 | } |
1158 | 1162 | path->mnt = mnt; |
1159 | 1163 | path->dentry = dentry; |
1160 | - if (likely(__follow_mount_rcu(nd, path, inode, false))) | |
1161 | - return 0; | |
1164 | + if (unlikely(!__follow_mount_rcu(nd, path, inode))) | |
1165 | + goto unlazy; | |
1166 | + if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | |
1167 | + goto unlazy; | |
1168 | + return 0; | |
1162 | 1169 | unlazy: |
1163 | 1170 | if (unlazy_walk(nd, dentry)) |
1164 | 1171 | return -ECHILD; |
fs/ncpfs/dir.c
... | ... | @@ -1033,8 +1033,11 @@ |
1033 | 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
1034 | 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); |
1035 | 1035 | |
1036 | + /* | |
1037 | + * fail with EBUSY if there are still references to this | |
1038 | + * directory. | |
1039 | + */ | |
1036 | 1040 | dentry_unhash(dentry); |
1037 | - | |
1038 | 1041 | error = -EBUSY; |
1039 | 1042 | if (!d_unhashed(dentry)) |
1040 | 1043 | goto out; |
1041 | 1044 | |
... | ... | @@ -1141,8 +1144,16 @@ |
1141 | 1144 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1142 | 1145 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
1143 | 1146 | |
1144 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1147 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) { | |
1148 | + /* | |
1149 | + * fail with EBUSY if there are still references to this | |
1150 | + * directory. | |
1151 | + */ | |
1145 | 1152 | dentry_unhash(new_dentry); |
1153 | + error = -EBUSY; | |
1154 | + if (!d_unhashed(new_dentry)) | |
1155 | + goto out; | |
1156 | + } | |
1146 | 1157 | |
1147 | 1158 | ncp_age_dentry(server, old_dentry); |
1148 | 1159 | ncp_age_dentry(server, new_dentry); |
fs/nilfs2/inode.c
... | ... | @@ -917,7 +917,7 @@ |
917 | 917 | * construction. This function can be called both as a single operation |
918 | 918 | * and as a part of indivisible file operations. |
919 | 919 | */ |
920 | -void nilfs_dirty_inode(struct inode *inode) | |
920 | +void nilfs_dirty_inode(struct inode *inode, int flags) | |
921 | 921 | { |
922 | 922 | struct nilfs_transaction_info ti; |
923 | 923 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); |
fs/nilfs2/namei.c
... | ... | @@ -334,8 +334,6 @@ |
334 | 334 | struct nilfs_transaction_info ti; |
335 | 335 | int err; |
336 | 336 | |
337 | - dentry_unhash(dentry); | |
338 | - | |
339 | 337 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); |
340 | 338 | if (err) |
341 | 339 | return err; |
... | ... | @@ -370,9 +368,6 @@ |
370 | 368 | struct nilfs_dir_entry *old_de; |
371 | 369 | struct nilfs_transaction_info ti; |
372 | 370 | int err; |
373 | - | |
374 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
375 | - dentry_unhash(new_dentry); | |
376 | 371 | |
377 | 372 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); |
378 | 373 | if (unlikely(err)) |
fs/nilfs2/nilfs.h
... | ... | @@ -269,7 +269,7 @@ |
269 | 269 | extern int nilfs_inode_dirty(struct inode *); |
270 | 270 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); |
271 | 271 | extern int nilfs_mark_inode_dirty(struct inode *); |
272 | -extern void nilfs_dirty_inode(struct inode *); | |
272 | +extern void nilfs_dirty_inode(struct inode *, int flags); | |
273 | 273 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
274 | 274 | __u64 start, __u64 len); |
275 | 275 |
fs/omfs/dir.c
... | ... | @@ -241,11 +241,9 @@ |
241 | 241 | int ret; |
242 | 242 | |
243 | 243 | |
244 | - if (S_ISDIR(inode->i_mode)) { | |
245 | - dentry_unhash(dentry); | |
246 | - if (!omfs_dir_is_empty(inode)) | |
247 | - return -ENOTEMPTY; | |
248 | - } | |
244 | + if (S_ISDIR(inode->i_mode) && | |
245 | + !omfs_dir_is_empty(inode)) | |
246 | + return -ENOTEMPTY; | |
249 | 247 | |
250 | 248 | ret = omfs_delete_entry(dentry); |
251 | 249 | if (ret) |
... | ... | @@ -382,9 +380,6 @@ |
382 | 380 | int err; |
383 | 381 | |
384 | 382 | if (new_inode) { |
385 | - if (S_ISDIR(new_inode->i_mode)) | |
386 | - dentry_unhash(new_dentry); | |
387 | - | |
388 | 383 | /* overwriting existing file/dir */ |
389 | 384 | err = omfs_remove(new_dir, new_dentry); |
390 | 385 | if (err) |
fs/reiserfs/namei.c
... | ... | @@ -831,8 +831,6 @@ |
831 | 831 | INITIALIZE_PATH(path); |
832 | 832 | struct reiserfs_dir_entry de; |
833 | 833 | |
834 | - dentry_unhash(dentry); | |
835 | - | |
836 | 834 | /* we will be doing 2 balancings and update 2 stat data, we change quotas |
837 | 835 | * of the owner of the directory and of the owner of the parent directory. |
838 | 836 | * The quota structure is possibly deleted only on last iput => outside |
... | ... | @@ -1226,9 +1224,6 @@ |
1226 | 1224 | umode_t old_inode_mode; |
1227 | 1225 | unsigned long savelink = 1; |
1228 | 1226 | struct timespec ctime; |
1229 | - | |
1230 | - if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1231 | - dentry_unhash(new_dentry); | |
1232 | 1227 | |
1233 | 1228 | /* three balancings: (1) old name removal, (2) new name insertion |
1234 | 1229 | and (3) maybe "save" link insertion |
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/sysv/namei.c
... | ... | @@ -196,8 +196,6 @@ |
196 | 196 | struct inode *inode = dentry->d_inode; |
197 | 197 | int err = -ENOTEMPTY; |
198 | 198 | |
199 | - dentry_unhash(dentry); | |
200 | - | |
201 | 199 | if (sysv_empty_dir(inode)) { |
202 | 200 | err = sysv_unlink(dir, dentry); |
203 | 201 | if (!err) { |
... | ... | @@ -223,9 +221,6 @@ |
223 | 221 | struct page * old_page; |
224 | 222 | struct sysv_dir_entry * old_de; |
225 | 223 | int err = -ENOENT; |
226 | - | |
227 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
228 | - dentry_unhash(new_dentry); | |
229 | 224 | |
230 | 225 | old_de = sysv_find_entry(old_dentry, &old_page); |
231 | 226 | if (!old_de) |
fs/ubifs/dir.c
... | ... | @@ -656,8 +656,6 @@ |
656 | 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
657 | 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; |
658 | 658 | |
659 | - dentry_unhash(dentry); | |
660 | - | |
661 | 659 | /* |
662 | 660 | * Budget request settings: deletion direntry, deletion inode and |
663 | 661 | * changing the parent inode. If budgeting fails, go ahead anyway |
... | ... | @@ -977,9 +975,6 @@ |
977 | 975 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, |
978 | 976 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
979 | 977 | struct timespec time; |
980 | - | |
981 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
982 | - dentry_unhash(new_dentry); | |
983 | 978 | |
984 | 979 | /* |
985 | 980 | * Budget request settings: deletion direntry, new direntry, removing |
fs/ubifs/super.c
fs/udf/namei.c
... | ... | @@ -783,8 +783,6 @@ |
783 | 783 | struct fileIdentDesc *fi, cfi; |
784 | 784 | struct kernel_lb_addr tloc; |
785 | 785 | |
786 | - dentry_unhash(dentry); | |
787 | - | |
788 | 786 | retval = -ENOENT; |
789 | 787 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
790 | 788 | if (!fi) |
... | ... | @@ -1082,9 +1080,6 @@ |
1082 | 1080 | int retval = -ENOENT; |
1083 | 1081 | struct kernel_lb_addr tloc; |
1084 | 1082 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1085 | - | |
1086 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
1087 | - dentry_unhash(new_dentry); | |
1088 | 1083 | |
1089 | 1084 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1090 | 1085 | if (ofi) { |
fs/ufs/namei.c
... | ... | @@ -258,8 +258,6 @@ |
258 | 258 | struct inode * inode = dentry->d_inode; |
259 | 259 | int err= -ENOTEMPTY; |
260 | 260 | |
261 | - dentry_unhash(dentry); | |
262 | - | |
263 | 261 | lock_ufs(dir->i_sb); |
264 | 262 | if (ufs_empty_dir (inode)) { |
265 | 263 | err = ufs_unlink(dir, dentry); |
... | ... | @@ -283,9 +281,6 @@ |
283 | 281 | struct page *old_page; |
284 | 282 | struct ufs_dir_entry *old_de; |
285 | 283 | int err = -ENOENT; |
286 | - | |
287 | - if (new_inode && S_ISDIR(new_inode->i_mode)) | |
288 | - dentry_unhash(new_dentry); | |
289 | 284 | |
290 | 285 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
291 | 286 | if (!old_de) |
fs/xattr.c
... | ... | @@ -46,18 +46,22 @@ |
46 | 46 | return 0; |
47 | 47 | |
48 | 48 | /* |
49 | - * The trusted.* namespace can only be accessed by a privileged user. | |
49 | + * The trusted.* namespace can only be accessed by privileged users. | |
50 | 50 | */ |
51 | - if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | |
52 | - return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | |
51 | + if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { | |
52 | + if (!capable(CAP_SYS_ADMIN)) | |
53 | + return (mask & MAY_WRITE) ? -EPERM : -ENODATA; | |
54 | + return 0; | |
55 | + } | |
53 | 56 | |
54 | - /* In user.* namespace, only regular files and directories can have | |
57 | + /* | |
58 | + * In the user.* namespace, only regular files and directories can have | |
55 | 59 | * extended attributes. For sticky directories, only the owner and |
56 | - * privileged user can write attributes. | |
60 | + * privileged users can write attributes. | |
57 | 61 | */ |
58 | 62 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
59 | 63 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
60 | - return -EPERM; | |
64 | + return (mask & MAY_WRITE) ? -EPERM : -ENODATA; | |
61 | 65 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && |
62 | 66 | (mask & MAY_WRITE) && !inode_owner_or_capable(inode)) |
63 | 67 | return -EPERM; |
64 | 68 | |
... | ... | @@ -87,7 +91,11 @@ |
87 | 91 | { |
88 | 92 | struct inode *inode = dentry->d_inode; |
89 | 93 | int error = -EOPNOTSUPP; |
94 | + int issec = !strncmp(name, XATTR_SECURITY_PREFIX, | |
95 | + XATTR_SECURITY_PREFIX_LEN); | |
90 | 96 | |
97 | + if (issec) | |
98 | + inode->i_flags &= ~S_NOSEC; | |
91 | 99 | if (inode->i_op->setxattr) { |
92 | 100 | error = inode->i_op->setxattr(dentry, name, value, size, flags); |
93 | 101 | if (!error) { |
... | ... | @@ -95,8 +103,7 @@ |
95 | 103 | security_inode_post_setxattr(dentry, name, value, |
96 | 104 | size, flags); |
97 | 105 | } |
98 | - } else if (!strncmp(name, XATTR_SECURITY_PREFIX, | |
99 | - XATTR_SECURITY_PREFIX_LEN)) { | |
106 | + } else if (issec) { | |
100 | 107 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; |
101 | 108 | error = security_inode_setsecurity(inode, suffix, value, |
102 | 109 | size, flags); |
fs/xfs/linux-2.6/xfs_super.c
include/linux/ext3_fs.h
... | ... | @@ -909,7 +909,7 @@ |
909 | 909 | extern void ext3_evict_inode (struct inode *); |
910 | 910 | extern int ext3_sync_inode (handle_t *, struct inode *); |
911 | 911 | extern void ext3_discard_reservation (struct inode *); |
912 | -extern void ext3_dirty_inode(struct inode *); | |
912 | +extern void ext3_dirty_inode(struct inode *, int); | |
913 | 913 | extern int ext3_change_inode_journal_flag(struct inode *, int); |
914 | 914 | extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); |
915 | 915 | extern int ext3_can_truncate(struct inode *inode); |
include/linux/fs.h
... | ... | @@ -237,6 +237,7 @@ |
237 | 237 | #define S_PRIVATE 512 /* Inode is fs-internal */ |
238 | 238 | #define S_IMA 1024 /* Inode has an associated IMA struct */ |
239 | 239 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ |
240 | +#define S_NOSEC 4096 /* no suid or xattr security attributes */ | |
240 | 241 | |
241 | 242 | /* |
242 | 243 | * Note that nosuid etc flags are inode-specific: setting some file-system |
... | ... | @@ -273,6 +274,7 @@ |
273 | 274 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) |
274 | 275 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) |
275 | 276 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) |
277 | +#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) | |
276 | 278 | |
277 | 279 | /* the read-only stuff doesn't really belong here, but any other place is |
278 | 280 | probably as bad and I don't want to create yet another include file. */ |
... | ... | @@ -1618,7 +1620,7 @@ |
1618 | 1620 | struct inode *(*alloc_inode)(struct super_block *sb); |
1619 | 1621 | void (*destroy_inode)(struct inode *); |
1620 | 1622 | |
1621 | - void (*dirty_inode) (struct inode *); | |
1623 | + void (*dirty_inode) (struct inode *, int flags); | |
1622 | 1624 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
1623 | 1625 | int (*drop_inode) (struct inode *); |
1624 | 1626 | void (*evict_inode) (struct inode *); |
... | ... | @@ -2581,6 +2583,17 @@ |
2581 | 2583 | #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) |
2582 | 2584 | #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ |
2583 | 2585 | (flag & __FMODE_NONOTIFY))) |
2586 | + | |
2587 | +static inline int is_sxid(mode_t mode) | |
2588 | +{ | |
2589 | + return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); | |
2590 | +} | |
2591 | + | |
2592 | +static inline void inode_has_no_xattr(struct inode *inode) | |
2593 | +{ | |
2594 | + if (!is_sxid(inode->i_mode)) | |
2595 | + inode->i_flags |= S_NOSEC; | |
2596 | +} | |
2584 | 2597 | |
2585 | 2598 | #endif /* __KERNEL__ */ |
2586 | 2599 | #endif /* _LINUX_FS_H */ |
mm/filemap.c
... | ... | @@ -1982,16 +1982,26 @@ |
1982 | 1982 | int file_remove_suid(struct file *file) |
1983 | 1983 | { |
1984 | 1984 | struct dentry *dentry = file->f_path.dentry; |
1985 | - int killsuid = should_remove_suid(dentry); | |
1986 | - int killpriv = security_inode_need_killpriv(dentry); | |
1985 | + struct inode *inode = dentry->d_inode; | |
1986 | + int killsuid; | |
1987 | + int killpriv; | |
1987 | 1988 | int error = 0; |
1988 | 1989 | |
1990 | + /* Fast path for nothing security related */ | |
1991 | + if (IS_NOSEC(inode)) | |
1992 | + return 0; | |
1993 | + | |
1994 | + killsuid = should_remove_suid(dentry); | |
1995 | + killpriv = security_inode_need_killpriv(dentry); | |
1996 | + | |
1989 | 1997 | if (killpriv < 0) |
1990 | 1998 | return killpriv; |
1991 | 1999 | if (killpriv) |
1992 | 2000 | error = security_inode_killpriv(dentry); |
1993 | 2001 | if (!error && killsuid) |
1994 | 2002 | error = __remove_suid(dentry, killsuid); |
2003 | + if (!error) | |
2004 | + inode->i_flags |= S_NOSEC; | |
1995 | 2005 | |
1996 | 2006 | return error; |
1997 | 2007 | } |
... | ... | @@ -2327,7 +2337,7 @@ |
2327 | 2337 | repeat: |
2328 | 2338 | page = find_lock_page(mapping, index); |
2329 | 2339 | if (page) |
2330 | - return page; | |
2340 | + goto found; | |
2331 | 2341 | |
2332 | 2342 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); |
2333 | 2343 | if (!page) |
... | ... | @@ -2340,6 +2350,8 @@ |
2340 | 2350 | goto repeat; |
2341 | 2351 | return NULL; |
2342 | 2352 | } |
2353 | +found: | |
2354 | + wait_on_page_writeback(page); | |
2343 | 2355 | return page; |
2344 | 2356 | } |
2345 | 2357 | EXPORT_SYMBOL(grab_cache_page_write_begin); |