Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ceph-for-4.16-rc4' of git://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
"A cap handling fix from Zhi that ensures that metadata writeback isn't
delayed and three error path memory leak fixups from Chengguang"

* tag 'ceph-for-4.16-rc4' of git://github.com/ceph/ceph-client:
ceph: fix potential memory leak in init_caches()
ceph: fix dentry leak when failing to init debugfs
libceph, ceph: avoid memory leak when specifying same option several times
ceph: flush dirty caps of unlinked inode ASAP

+52 -38
+26
fs/ceph/caps.c
··· 3965 3965 } 3966 3966 3967 3967 /* 3968 + * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it 3969 + * looks like the link count will hit 0, drop any other caps (other 3970 + * than PIN) we don't specifically want (due to the file still being 3971 + * open). 3972 + */ 3973 + int ceph_drop_caps_for_unlink(struct inode *inode) 3974 + { 3975 + struct ceph_inode_info *ci = ceph_inode(inode); 3976 + int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; 3977 + 3978 + spin_lock(&ci->i_ceph_lock); 3979 + if (inode->i_nlink == 1) { 3980 + drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN); 3981 + 3982 + ci->i_ceph_flags |= CEPH_I_NODELAY; 3983 + if (__ceph_caps_dirty(ci)) { 3984 + struct ceph_mds_client *mdsc = 3985 + ceph_inode_to_client(inode)->mdsc; 3986 + __cap_delay_requeue_front(mdsc, ci); 3987 + } 3988 + } 3989 + spin_unlock(&ci->i_ceph_lock); 3990 + return drop; 3991 + } 3992 + 3993 + /* 3968 3994 * Helpers for embedding cap and dentry lease releases into mds 3969 3995 * requests. 3970 3996 *
+5 -23
fs/ceph/dir.c
··· 1003 1003 } 1004 1004 1005 1005 /* 1006 - * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it 1007 - * looks like the link count will hit 0, drop any other caps (other 1008 - * than PIN) we don't specifically want (due to the file still being 1009 - * open). 1010 - */ 1011 - static int drop_caps_for_unlink(struct inode *inode) 1012 - { 1013 - struct ceph_inode_info *ci = ceph_inode(inode); 1014 - int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; 1015 - 1016 - spin_lock(&ci->i_ceph_lock); 1017 - if (inode->i_nlink == 1) { 1018 - drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN); 1019 - ci->i_ceph_flags |= CEPH_I_NODELAY; 1020 - } 1021 - spin_unlock(&ci->i_ceph_lock); 1022 - return drop; 1023 - } 1024 - 1025 - /* 1026 1006 * rmdir and unlink are differ only by the metadata op code 1027 1007 */ 1028 1008 static int ceph_unlink(struct inode *dir, struct dentry *dentry) ··· 1036 1056 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags); 1037 1057 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 1038 1058 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 1039 - req->r_inode_drop = drop_caps_for_unlink(inode); 1059 + req->r_inode_drop = ceph_drop_caps_for_unlink(inode); 1040 1060 err = ceph_mdsc_do_request(mdsc, dir, req); 1041 1061 if (!err && !req->r_reply_info.head->is_dentry) 1042 1062 d_delete(dentry); ··· 1084 1104 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 1085 1105 /* release LINK_RDCACHE on source inode (mds will lock it) */ 1086 1106 req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; 1087 - if (d_really_is_positive(new_dentry)) 1088 - req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry)); 1107 + if (d_really_is_positive(new_dentry)) { 1108 + req->r_inode_drop = 1109 + ceph_drop_caps_for_unlink(d_inode(new_dentry)); 1110 + } 1089 1111 err = ceph_mdsc_do_request(mdsc, old_dir, req); 1090 1112 if (!err && !req->r_reply_info.head->is_dentry) { 1091 1113 /*
+13 -14
fs/ceph/super.c
··· 225 225 return -ENOMEM; 226 226 break; 227 227 case Opt_mds_namespace: 228 + kfree(fsopt->mds_namespace); 228 229 fsopt->mds_namespace = kstrndup(argstr[0].from, 229 230 argstr[0].to-argstr[0].from, 230 231 GFP_KERNEL); ··· 233 232 return -ENOMEM; 234 233 break; 235 234 case Opt_fscache_uniq: 235 + kfree(fsopt->fscache_uniq); 236 236 fsopt->fscache_uniq = kstrndup(argstr[0].from, 237 237 argstr[0].to-argstr[0].from, 238 238 GFP_KERNEL); ··· 713 711 goto bad_dentry; 714 712 715 713 ceph_file_cachep = KMEM_CACHE(ceph_file_info, SLAB_MEM_SPREAD); 716 - 717 714 if (!ceph_file_cachep) 718 715 goto bad_file; 719 716 720 - if ((error = ceph_fscache_register())) 721 - goto bad_file; 717 + error = ceph_fscache_register(); 718 + if (error) 719 + goto bad_fscache; 722 720 723 721 return 0; 722 + 723 + bad_fscache: 724 + kmem_cache_destroy(ceph_file_cachep); 724 725 bad_file: 725 726 kmem_cache_destroy(ceph_dentry_cachep); 726 727 bad_dentry: ··· 841 836 int err; 842 837 unsigned long started = jiffies; /* note the start time */ 843 838 struct dentry *root; 844 - int first = 0; /* first vfsmount for this super_block */ 845 839 846 840 dout("mount start %p\n", fsc); 847 841 mutex_lock(&fsc->client->mount_mutex); ··· 865 861 path = fsc->mount_options->server_path + 1; 866 862 dout("mount opening path %s\n", path); 867 863 } 864 + 865 + err = ceph_fs_debugfs_init(fsc); 866 + if (err < 0) 867 + goto out; 868 + 868 869 root = open_root_dentry(fsc, path, started); 869 870 if (IS_ERR(root)) { 870 871 err = PTR_ERR(root); 871 872 goto out; 872 873 } 873 874 fsc->sb->s_root = dget(root); 874 - first = 1; 875 - 876 - err = ceph_fs_debugfs_init(fsc); 877 - if (err < 0) 878 - goto fail; 879 875 } else { 880 876 root = dget(fsc->sb->s_root); 881 877 } ··· 885 881 mutex_unlock(&fsc->client->mount_mutex); 886 882 return root; 887 883 888 - fail: 889 - if (first) { 890 - dput(fsc->sb->s_root); 891 - fsc->sb->s_root = NULL; 892 - } 893 884 out: 894 885 mutex_unlock(&fsc->client->mount_mutex); 895 886 return ERR_PTR(err);
+1 -1
fs/ceph/super.h
··· 987 987 struct ceph_mds_session *session); 988 988 extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); 989 989 extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc); 990 - 990 + extern int ceph_drop_caps_for_unlink(struct inode *inode); 991 991 extern int ceph_encode_inode_release(void **p, struct inode *inode, 992 992 int mds, int drop, int unless, int force); 993 993 extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
+7
net/ceph/ceph_common.c
··· 418 418 opt->flags |= CEPH_OPT_FSID; 419 419 break; 420 420 case Opt_name: 421 + kfree(opt->name); 421 422 opt->name = kstrndup(argstr[0].from, 422 423 argstr[0].to-argstr[0].from, 423 424 GFP_KERNEL); ··· 428 427 } 429 428 break; 430 429 case Opt_secret: 430 + ceph_crypto_key_destroy(opt->key); 431 + kfree(opt->key); 432 + 431 433 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); 432 434 if (!opt->key) { 433 435 err = -ENOMEM; ··· 441 437 goto out; 442 438 break; 443 439 case Opt_key: 440 + ceph_crypto_key_destroy(opt->key); 441 + kfree(opt->key); 442 + 444 443 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); 445 444 if (!opt->key) { 446 445 err = -ENOMEM;