readdir.c (3a175cdf439275c3da347b6b42c4e9b652a12904) | readdir.c (1eff1a1deec727bacead79ec64554c1df190f43c) |
---|---|
1/* 2 * 3 * Copyright (C) 2011 Novell Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 */ --- 579 unchanged lines hidden (view full) --- 588 589 res = ovl_dir_read_impure(path, &cache->entries, &cache->root); 590 if (res) { 591 ovl_cache_free(&cache->entries); 592 kfree(cache); 593 return ERR_PTR(res); 594 } 595 if (list_empty(&cache->entries)) { | 1/* 2 * 3 * Copyright (C) 2011 Novell Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 */ --- 579 unchanged lines hidden (view full) --- 588 589 res = ovl_dir_read_impure(path, &cache->entries, &cache->root); 590 if (res) { 591 ovl_cache_free(&cache->entries); 592 kfree(cache); 593 return ERR_PTR(res); 594 } 595 if (list_empty(&cache->entries)) { |
596 /* Good oportunity to get rid of an unnecessary "impure" flag */ 597 ovl_do_removexattr(ovl_dentry_upper(dentry), OVL_XATTR_IMPURE); | 596 /* 597 * A good opportunity to get rid of an unneeded "impure" flag. 598 * Removing the "impure" xattr is best effort. 599 */ 600 if (!ovl_want_write(dentry)) { 601 ovl_do_removexattr(ovl_dentry_upper(dentry), 602 OVL_XATTR_IMPURE); 603 ovl_drop_write(dentry); 604 } |
598 ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); 599 kfree(cache); 600 return NULL; 601 } 602 603 cache->version = ovl_dentry_version_get(dentry); 604 ovl_set_dir_cache(d_inode(dentry), cache); 605 --- 158 unchanged lines hidden (view full) --- 764 765static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, 766 int datasync) 767{ 768 struct ovl_dir_file *od = file->private_data; 769 struct dentry *dentry = file->f_path.dentry; 770 struct file *realfile = od->realfile; 771 | 605 ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); 606 kfree(cache); 607 return NULL; 608 } 609 610 cache->version = ovl_dentry_version_get(dentry); 611 ovl_set_dir_cache(d_inode(dentry), cache); 612 --- 158 unchanged lines hidden (view full) --- 771 772static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end, 773 int datasync) 774{ 775 struct ovl_dir_file *od = file->private_data; 776 struct dentry *dentry = file->f_path.dentry; 777 struct file *realfile = od->realfile; 778 |
779 /* Nothing to sync for lower */ 780 if (!OVL_TYPE_UPPER(ovl_path_type(dentry))) 781 return 0; 782 |
|
772 /* 773 * Need to check if we started out being a lower dir, but got copied up 774 */ | 783 /* 784 * Need to check if we started out being a lower dir, but got copied up 785 */ |
775 if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) { | 786 if (!od->is_upper) { |
776 struct inode *inode = file_inode(file); 777 778 realfile = READ_ONCE(od->upperfile); 779 if (!realfile) { 780 struct path upperpath; 781 782 ovl_path_upper(dentry, &upperpath); 783 realfile = ovl_path_open(&upperpath, O_RDONLY); --- 69 unchanged lines hidden (view full) --- 853 .release = ovl_dir_release, 854}; 855 856int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) 857{ 858 int err; 859 struct ovl_cache_entry *p, *n; 860 struct rb_root root = RB_ROOT; | 787 struct inode *inode = file_inode(file); 788 789 realfile = READ_ONCE(od->upperfile); 790 if (!realfile) { 791 struct path upperpath; 792 793 ovl_path_upper(dentry, &upperpath); 794 realfile = ovl_path_open(&upperpath, O_RDONLY); --- 69 unchanged lines hidden (view full) --- 864 .release = ovl_dir_release, 865}; 866 867int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) 868{ 869 int err; 870 struct ovl_cache_entry *p, *n; 871 struct rb_root root = RB_ROOT; |
872 const struct cred *old_cred; |
|
861 | 873 |
874 old_cred = ovl_override_creds(dentry->d_sb); |
|
862 err = ovl_dir_read_merged(dentry, list, &root); | 875 err = ovl_dir_read_merged(dentry, list, &root); |
876 revert_creds(old_cred); |
|
863 if (err) 864 return err; 865 866 err = 0; 867 868 list_for_each_entry_safe(p, n, list, l_node) { 869 /* 870 * Select whiteouts in upperdir, they should --- 140 unchanged lines hidden (view full) --- 1011 1012 inode_unlock(dir); 1013 ovl_workdir_cleanup_recurse(&path, level + 1); 1014 inode_lock_nested(dir, I_MUTEX_PARENT); 1015 ovl_cleanup(dir, dentry); 1016 } 1017} 1018 | 877 if (err) 878 return err; 879 880 err = 0; 881 882 list_for_each_entry_safe(p, n, list, l_node) { 883 /* 884 * Select whiteouts in upperdir, they should --- 140 unchanged lines hidden (view full) --- 1025 1026 inode_unlock(dir); 1027 ovl_workdir_cleanup_recurse(&path, level + 1); 1028 inode_lock_nested(dir, I_MUTEX_PARENT); 1029 ovl_cleanup(dir, dentry); 1030 } 1031} 1032 |
1019int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, 1020 struct ovl_path *lower, unsigned int numlower) | 1033int ovl_indexdir_cleanup(struct ovl_fs *ofs) |
1021{ 1022 int err; | 1034{ 1035 int err; |
1036 struct dentry *indexdir = ofs->indexdir; |
|
1023 struct dentry *index = NULL; | 1037 struct dentry *index = NULL; |
1024 struct inode *dir = dentry->d_inode; 1025 struct path path = { .mnt = mnt, .dentry = dentry }; | 1038 struct inode *dir = indexdir->d_inode; 1039 struct path path = { .mnt = ofs->upper_mnt, .dentry = indexdir }; |
1026 LIST_HEAD(list); 1027 struct rb_root root = RB_ROOT; 1028 struct ovl_cache_entry *p; 1029 struct ovl_readdir_data rdd = { 1030 .ctx.actor = ovl_fill_merge, 1031 .dentry = NULL, 1032 .list = &list, 1033 .root = &root, --- 7 unchanged lines hidden (view full) --- 1041 inode_lock_nested(dir, I_MUTEX_PARENT); 1042 list_for_each_entry(p, &list, l_node) { 1043 if (p->name[0] == '.') { 1044 if (p->len == 1) 1045 continue; 1046 if (p->len == 2 && p->name[1] == '.') 1047 continue; 1048 } | 1040 LIST_HEAD(list); 1041 struct rb_root root = RB_ROOT; 1042 struct ovl_cache_entry *p; 1043 struct ovl_readdir_data rdd = { 1044 .ctx.actor = ovl_fill_merge, 1045 .dentry = NULL, 1046 .list = &list, 1047 .root = &root, --- 7 unchanged lines hidden (view full) --- 1055 inode_lock_nested(dir, I_MUTEX_PARENT); 1056 list_for_each_entry(p, &list, l_node) { 1057 if (p->name[0] == '.') { 1058 if (p->len == 1) 1059 continue; 1060 if (p->len == 2 && p->name[1] == '.') 1061 continue; 1062 } |
1049 index = lookup_one_len(p->name, dentry, p->len); | 1063 index = lookup_one_len(p->name, indexdir, p->len); |
1050 if (IS_ERR(index)) { 1051 err = PTR_ERR(index); 1052 index = NULL; 1053 break; 1054 } | 1064 if (IS_ERR(index)) { 1065 err = PTR_ERR(index); 1066 index = NULL; 1067 break; 1068 } |
1055 err = ovl_verify_index(index, lower, numlower); | 1069 err = ovl_verify_index(ofs, index); |
1056 /* Cleanup stale and orphan index entries */ 1057 if (err && (err == -ESTALE || err == -ENOENT)) 1058 err = ovl_cleanup(dir, index); 1059 if (err) 1060 break; 1061 1062 dput(index); 1063 index = NULL; 1064 } 1065 dput(index); 1066 inode_unlock(dir); 1067out: 1068 ovl_cache_free(&list); 1069 if (err) 1070 pr_err("overlayfs: failed index dir cleanup (%i)\n", err); 1071 return err; 1072} | 1070 /* Cleanup stale and orphan index entries */ 1071 if (err && (err == -ESTALE || err == -ENOENT)) 1072 err = ovl_cleanup(dir, index); 1073 if (err) 1074 break; 1075 1076 dput(index); 1077 index = NULL; 1078 } 1079 dput(index); 1080 inode_unlock(dir); 1081out: 1082 ovl_cache_free(&list); 1083 if (err) 1084 pr_err("overlayfs: failed index dir cleanup (%i)\n", err); 1085 return err; 1086} |