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}