Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 488492
Collapse All | Expand All

(-)file_not_specified_in_diff (-1 lines)
Line 232 Link Here
232
--
233
fs/dcache.c | 221 +++++++++++++++++++++---------------------------------------
3
fs/dcache.c | 221 +++++++++++++++++++++---------------------------------------
234
1 file changed, 76 insertions(+), 145 deletions(-)
4
1 file changed, 76 insertions(+), 145 deletions(-)
(-)a/fs/dcache.c (-146 / +76 lines)
Lines 88-122 EXPORT_SYMBOL(rename_lock); Link Here
88
88
89
static struct kmem_cache *dentry_cache __read_mostly;
89
static struct kmem_cache *dentry_cache __read_mostly;
90
90
91
/**
92
 * read_seqbegin_or_lock - begin a sequence number check or locking block
93
 * @lock: sequence lock
94
 * @seq : sequence number to be checked
95
 *
96
 * First try it once optimistically without taking the lock. If that fails,
97
 * take the lock. The sequence number is also used as a marker for deciding
98
 * whether to be a reader (even) or writer (odd).
99
 * N.B. seq must be initialized to an even number to begin with.
100
 */
101
static inline void read_seqbegin_or_lock(seqlock_t *lock, int *seq)
102
{
103
	if (!(*seq & 1))	/* Even */
104
		*seq = read_seqbegin(lock);
105
	else			/* Odd */
106
		read_seqlock_excl(lock);
107
}
108
109
static inline int need_seqretry(seqlock_t *lock, int seq)
110
{
111
	return !(seq & 1) && read_seqretry(lock, seq);
112
}
113
114
static inline void done_seqretry(seqlock_t *lock, int seq)
115
{
116
	if (seq & 1)
117
		read_sequnlock_excl(lock);
118
}
119
120
/*
91
/*
121
 * This is the single most critical data structure when it comes
92
 * This is the single most critical data structure when it comes
122
 * to the dcache: the hashtable for lookups. Somebody should try
93
 * to the dcache: the hashtable for lookups. Somebody should try
Lines 1191-1197 void shrink_dcache_for_umount(struct super_block *sb) Link Here
1191
 * the parenthood after dropping the lock and check
1162
 * the parenthood after dropping the lock and check
1192
 * that the sequence number still matches.
1163
 * that the sequence number still matches.
1193
 */
1164
 */
1194
static struct dentry *try_to_ascend(struct dentry *old, unsigned seq)
1165
static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq)
1195
{
1166
{
1196
	struct dentry *new = old->d_parent;
1167
	struct dentry *new = old->d_parent;
1197
1168
Lines 1205-1211 static struct dentry *try_to_ascend(struct dentry *old, unsigned seq) Link Here
1205
	 */
1176
	 */
1206
	if (new != old->d_parent ||
1177
	if (new != old->d_parent ||
1207
		 (old->d_flags & DCACHE_DENTRY_KILLED) ||
1178
		 (old->d_flags & DCACHE_DENTRY_KILLED) ||
1208
		 need_seqretry(&rename_lock, seq)) {
1179
		 (!locked && read_seqretry(&rename_lock, seq))) {
1209
		spin_unlock(&new->d_lock);
1180
		spin_unlock(&new->d_lock);
1210
		new = NULL;
1181
		new = NULL;
1211
	}
1182
	}
Lines 1242-1253 static void d_walk(struct dentry *parent, void *data, Link Here
1242
{
1213
{
1243
	struct dentry *this_parent;
1214
	struct dentry *this_parent;
1244
	struct list_head *next;
1215
	struct list_head *next;
1245
	unsigned seq = 0;
1216
	unsigned seq;
1217
	int locked = 0;
1246
	enum d_walk_ret ret;
1218
	enum d_walk_ret ret;
1247
	bool retry = true;
1219
	bool retry = true;
1248
1220
1221
	seq = read_seqbegin(&rename_lock);
1249
again:
1222
again:
1250
	read_seqbegin_or_lock(&rename_lock, &seq);
1251
	this_parent = parent;
1223
	this_parent = parent;
1252
	spin_lock(&this_parent->d_lock);
1224
	spin_lock(&this_parent->d_lock);
1253
1225
Lines 1301-1313 resume: Link Here
1301
	 */
1273
	 */
1302
	if (this_parent != parent) {
1274
	if (this_parent != parent) {
1303
		struct dentry *child = this_parent;
1275
		struct dentry *child = this_parent;
1304
		this_parent = try_to_ascend(this_parent, seq);
1276
		this_parent = try_to_ascend(this_parent, locked, seq);
1305
		if (!this_parent)
1277
		if (!this_parent)
1306
			goto rename_retry;
1278
			goto rename_retry;
1307
		next = child->d_u.d_child.next;
1279
		next = child->d_u.d_child.next;
1308
		goto resume;
1280
		goto resume;
1309
	}
1281
	}
1310
	if (need_seqretry(&rename_lock, seq)) {
1282
	if (!locked && read_seqretry(&rename_lock, seq)) {
1311
		spin_unlock(&this_parent->d_lock);
1283
		spin_unlock(&this_parent->d_lock);
1312
		goto rename_retry;
1284
		goto rename_retry;
1313
	}
1285
	}
Lines 1316-1328 resume: Link Here
1316
1288
1317
out_unlock:
1289
out_unlock:
1318
	spin_unlock(&this_parent->d_lock);
1290
	spin_unlock(&this_parent->d_lock);
1319
	done_seqretry(&rename_lock, seq);
1291
	if (locked)
1292
		write_sequnlock(&rename_lock);
1320
	return;
1293
	return;
1321
1294
1322
rename_retry:
1295
rename_retry:
1323
	if (!retry)
1296
	if (!retry)
1324
		return;
1297
		return;
1325
	seq = 1;
1298
	if (locked)
1299
		goto again;
1300
	locked = 1;
1301
	write_seqlock(&rename_lock);
1326
	goto again;
1302
	goto again;
1327
}
1303
}
1328
1304
Lines 2825-2863 static int prepend(char **buffer, int *buflen, const char *str, int namelen) Link Here
2825
	return 0;
2801
	return 0;
2826
}
2802
}
2827
2803
2828
/**
2829
 * prepend_name - prepend a pathname in front of current buffer pointer
2830
 * @buffer: buffer pointer
2831
 * @buflen: allocated length of the buffer
2832
 * @name:   name string and length qstr structure
2833
 *
2834
 * With RCU path tracing, it may race with d_move(). Use ACCESS_ONCE() to
2835
 * make sure that either the old or the new name pointer and length are
2836
 * fetched. However, there may be mismatch between length and pointer.
2837
 * The length cannot be trusted, we need to copy it byte-by-byte until
2838
 * the length is reached or a null byte is found. It also prepends "/" at
2839
 * the beginning of the name. The sequence number check at the caller will
2840
 * retry it again when a d_move() does happen. So any garbage in the buffer
2841
 * due to mismatched pointer and length will be discarded.
2842
 */
2843
static int prepend_name(char **buffer, int *buflen, struct qstr *name)
2804
static int prepend_name(char **buffer, int *buflen, struct qstr *name)
2844
{
2805
{
2845
	const char *dname = ACCESS_ONCE(name->name);
2806
	return prepend(buffer, buflen, name->name, name->len);
2846
	u32 dlen = ACCESS_ONCE(name->len);
2847
	char *p;
2848
2849
	if (*buflen < dlen + 1)
2850
		return -ENAMETOOLONG;
2851
	*buflen -= dlen + 1;
2852
	p = *buffer -= dlen + 1;
2853
	*p++ = '/';
2854
	while (dlen--) {
2855
		char c = *dname++;
2856
		if (!c)
2857
			break;
2858
		*p++ = c;
2859
	}
2860
	return 0;
2861
}
2807
}
2862
2808
2863
/**
2809
/**
Lines 2867-2881 static int prepend_name(char **buffer, int *buflen, struct qstr *name) Link Here
2867
 * @buffer: pointer to the end of the buffer
2813
 * @buffer: pointer to the end of the buffer
2868
 * @buflen: pointer to buffer length
2814
 * @buflen: pointer to buffer length
2869
 *
2815
 *
2870
 * The function will first try to write out the pathname without taking any
2816
 * Caller holds the rename_lock.
2871
 * lock other than the RCU read lock to make sure that dentries won't go away.
2872
 * It only checks the sequence number of the global rename_lock as any change
2873
 * in the dentry's d_seq will be preceded by changes in the rename_lock
2874
 * sequence number. If the sequence number had been changed, it will restart
2875
 * the whole pathname back-tracing sequence again by taking the rename_lock.
2876
 * In this case, there is no need to take the RCU read lock as the recursive
2877
 * parent pointer references will keep the dentry chain alive as long as no
2878
 * rename operation is performed.
2879
 */
2817
 */
2880
static int prepend_path(const struct path *path,
2818
static int prepend_path(const struct path *path,
2881
			const struct path *root,
2819
			const struct path *root,
Lines 2884-2949 static int prepend_path(const struct path *path, Link Here
2884
	struct dentry *dentry = path->dentry;
2822
	struct dentry *dentry = path->dentry;
2885
	struct vfsmount *vfsmnt = path->mnt;
2823
	struct vfsmount *vfsmnt = path->mnt;
2886
	struct mount *mnt = real_mount(vfsmnt);
2824
	struct mount *mnt = real_mount(vfsmnt);
2825
	bool slash = false;
2887
	int error = 0;
2826
	int error = 0;
2888
	unsigned seq = 0;
2889
	char *bptr;
2890
	int blen;
2891
2827
2892
	rcu_read_lock();
2893
restart:
2894
	bptr = *buffer;
2895
	blen = *buflen;
2896
	read_seqbegin_or_lock(&rename_lock, &seq);
2897
	while (dentry != root->dentry || vfsmnt != root->mnt) {
2828
	while (dentry != root->dentry || vfsmnt != root->mnt) {
2898
		struct dentry * parent;
2829
		struct dentry * parent;
2899
2830
2900
		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
2831
		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
2901
			/* Global root? */
2832
			/* Global root? */
2902
			if (mnt_has_parent(mnt)) {
2833
			if (!mnt_has_parent(mnt))
2903
				dentry = mnt->mnt_mountpoint;
2834
				goto global_root;
2904
				mnt = mnt->mnt_parent;
2835
			dentry = mnt->mnt_mountpoint;
2905
				vfsmnt = &mnt->mnt;
2836
			mnt = mnt->mnt_parent;
2906
				continue;
2837
			vfsmnt = &mnt->mnt;
2907
			}
2838
			continue;
2908
			/*
2909
			 * Filesystems needing to implement special "root names"
2910
			 * should do so with ->d_dname()
2911
			 */
2912
			if (IS_ROOT(dentry) &&
2913
			   (dentry->d_name.len != 1 ||
2914
			    dentry->d_name.name[0] != '/')) {
2915
				WARN(1, "Root dentry has weird name <%.*s>\n",
2916
				     (int) dentry->d_name.len,
2917
				     dentry->d_name.name);
2918
			}
2919
			if (!error)
2920
				error = is_mounted(vfsmnt) ? 1 : 2;
2921
			break;
2922
		}
2839
		}
2923
		parent = dentry->d_parent;
2840
		parent = dentry->d_parent;
2924
		prefetch(parent);
2841
		prefetch(parent);
2925
		error = prepend_name(&bptr, &blen, &dentry->d_name);
2842
		spin_lock(&dentry->d_lock);
2843
		error = prepend_name(buffer, buflen, &dentry->d_name);
2844
		spin_unlock(&dentry->d_lock);
2845
		if (!error)
2846
			error = prepend(buffer, buflen, "/", 1);
2926
		if (error)
2847
		if (error)
2927
			break;
2848
			break;
2928
2849
2850
		slash = true;
2929
		dentry = parent;
2851
		dentry = parent;
2930
	}
2852
	}
2931
	if (!(seq & 1))
2932
		rcu_read_unlock();
2933
	if (need_seqretry(&rename_lock, seq)) {
2934
		seq = 1;
2935
		goto restart;
2936
	}
2937
	done_seqretry(&rename_lock, seq);
2938
2853
2939
	if (error >= 0 && bptr == *buffer) {
2854
	if (!error && !slash)
2940
		if (--blen < 0)
2855
		error = prepend(buffer, buflen, "/", 1);
2941
			error = -ENAMETOOLONG;
2856
2942
		else
2857
	return error;
2943
			*--bptr = '/';
2858
2944
	}
2859
global_root:
2945
	*buffer = bptr;
2860
	/*
2946
	*buflen = blen;
2861
	 * Filesystems needing to implement special "root names"
2862
	 * should do so with ->d_dname()
2863
	 */
2864
	if (IS_ROOT(dentry) &&
2865
	    (dentry->d_name.len != 1 || dentry->d_name.name[0] != '/')) {
2866
		WARN(1, "Root dentry has weird name <%.*s>\n",
2867
		     (int) dentry->d_name.len, dentry->d_name.name);
2868
	}
2869
	if (!slash)
2870
		error = prepend(buffer, buflen, "/", 1);
2871
	if (!error)
2872
		error = is_mounted(vfsmnt) ? 1 : 2;
2947
	return error;
2873
	return error;
2948
}
2874
}
2949
2875
Lines 2972-2978 char *__d_path(const struct path *path, Link Here
2972
2898
2973
	prepend(&res, &buflen, "\0", 1);
2899
	prepend(&res, &buflen, "\0", 1);
2974
	br_read_lock(&vfsmount_lock);
2900
	br_read_lock(&vfsmount_lock);
2901
	write_seqlock(&rename_lock);
2975
	error = prepend_path(path, root, &res, &buflen);
2902
	error = prepend_path(path, root, &res, &buflen);
2903
	write_sequnlock(&rename_lock);
2976
	br_read_unlock(&vfsmount_lock);
2904
	br_read_unlock(&vfsmount_lock);
2977
2905
2978
	if (error < 0)
2906
	if (error < 0)
Lines 2991-2997 char *d_absolute_path(const struct path *path, Link Here
2991
2919
2992
	prepend(&res, &buflen, "\0", 1);
2920
	prepend(&res, &buflen, "\0", 1);
2993
	br_read_lock(&vfsmount_lock);
2921
	br_read_lock(&vfsmount_lock);
2922
	write_seqlock(&rename_lock);
2994
	error = prepend_path(path, &root, &res, &buflen);
2923
	error = prepend_path(path, &root, &res, &buflen);
2924
	write_sequnlock(&rename_lock);
2995
	br_read_unlock(&vfsmount_lock);
2925
	br_read_unlock(&vfsmount_lock);
2996
2926
2997
	if (error > 1)
2927
	if (error > 1)
Lines 3068-3074 char *d_path(const struct path *path, char *buf, int buflen) Link Here
3068
	rcu_read_lock();
2998
	rcu_read_lock();
3069
	get_fs_root_rcu(current->fs, &root);
2999
	get_fs_root_rcu(current->fs, &root);
3070
	br_read_lock(&vfsmount_lock);
3000
	br_read_lock(&vfsmount_lock);
3001
	write_seqlock(&rename_lock);
3071
	error = path_with_deleted(path, &root, &res, &buflen);
3002
	error = path_with_deleted(path, &root, &res, &buflen);
3003
	write_sequnlock(&rename_lock);
3072
	br_read_unlock(&vfsmount_lock);
3004
	br_read_unlock(&vfsmount_lock);
3073
	rcu_read_unlock();
3005
	rcu_read_unlock();
3074
3006
Lines 3104-3113 char *simple_dname(struct dentry *dentry, char *buffer, int buflen) Link Here
3104
	char *end = buffer + buflen;
3036
	char *end = buffer + buflen;
3105
	/* these dentries are never renamed, so d_lock is not needed */
3037
	/* these dentries are never renamed, so d_lock is not needed */
3106
	if (prepend(&end, &buflen, " (deleted)", 11) ||
3038
	if (prepend(&end, &buflen, " (deleted)", 11) ||
3107
	    prepend(&end, &buflen, dentry->d_name.name, dentry->d_name.len) ||
3039
	    prepend_name(&end, &buflen, &dentry->d_name) ||
3108
	    prepend(&end, &buflen, "/", 1))  
3040
	    prepend(&end, &buflen, "/", 1))  
3109
		end = ERR_PTR(-ENAMETOOLONG);
3041
		end = ERR_PTR(-ENAMETOOLONG);
3110
	return end;
3042
	return end;  
3111
}
3043
}
3112
3044
3113
/*
3045
/*
Lines 3115-3156 char *simple_dname(struct dentry *dentry, char *buffer, int buflen) Link Here
3115
 */
3047
 */
3116
static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
3048
static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
3117
{
3049
{
3118
	char *end, *retval;
3050
	char *end = buf + buflen;
3119
	int len, seq = 0;
3051
	char *retval;
3120
	int error = 0;
3121
3052
3122
	rcu_read_lock();
3053
	prepend(&end, &buflen, "\0", 1);
3123
restart:
3124
	end = buf + buflen;
3125
	len = buflen;
3126
	prepend(&end, &len, "\0", 1);
3127
	if (buflen < 1)
3054
	if (buflen < 1)
3128
		goto Elong;
3055
		goto Elong;
3129
	/* Get '/' right */
3056
	/* Get '/' right */
3130
	retval = end-1;
3057
	retval = end-1;
3131
	*retval = '/';
3058
	*retval = '/';
3132
	read_seqbegin_or_lock(&rename_lock, &seq);
3059
3133
	while (!IS_ROOT(dentry)) {
3060
	while (!IS_ROOT(dentry)) {
3134
		struct dentry *parent = dentry->d_parent;
3061
		struct dentry *parent = dentry->d_parent;
3135
		int error;
3062
		int error;
3136
3063
3137
		prefetch(parent);
3064
		prefetch(parent);
3138
		error = prepend_name(&end, &len, &dentry->d_name);
3065
		spin_lock(&dentry->d_lock);
3139
		if (error)
3066
		error = prepend_name(&end, &buflen, &dentry->d_name);
3140
			break;
3067
		spin_unlock(&dentry->d_lock);
3068
		if (error != 0 || prepend(&end, &buflen, "/", 1) != 0)
3069
			goto Elong;
3141
3070
3142
		retval = end;
3071
		retval = end;
3143
		dentry = parent;
3072
		dentry = parent;
3144
	}
3073
	}
3145
	if (!(seq & 1))
3146
		rcu_read_unlock();
3147
	if (need_seqretry(&rename_lock, seq)) {
3148
		seq = 1;
3149
		goto restart;
3150
	}
3151
	done_seqretry(&rename_lock, seq);
3152
	if (error)
3153
		goto Elong;
3154
	return retval;
3074
	return retval;
3155
Elong:
3075
Elong:
3156
	return ERR_PTR(-ENAMETOOLONG);
3076
	return ERR_PTR(-ENAMETOOLONG);
Lines 3158-3164 Elong: Link Here
3158
3078
3159
char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
3079
char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
3160
{
3080
{
3161
	return __dentry_path(dentry, buf, buflen);
3081
	char *retval;
3082
3083
	write_seqlock(&rename_lock);
3084
	retval = __dentry_path(dentry, buf, buflen);
3085
	write_sequnlock(&rename_lock);
3086
3087
	return retval;
3162
}
3088
}
3163
EXPORT_SYMBOL(dentry_path_raw);
3089
EXPORT_SYMBOL(dentry_path_raw);
3164
3090
Lines 3167-3172 char *dentry_path(struct dentry *dentry, char *buf, int buflen) Link Here
3167
	char *p = NULL;
3093
	char *p = NULL;
3168
	char *retval;
3094
	char *retval;
3169
3095
3096
	write_seqlock(&rename_lock);
3170
	if (d_unlinked(dentry)) {
3097
	if (d_unlinked(dentry)) {
3171
		p = buf + buflen;
3098
		p = buf + buflen;
3172
		if (prepend(&p, &buflen, "//deleted", 10) != 0)
3099
		if (prepend(&p, &buflen, "//deleted", 10) != 0)
Lines 3174-3179 char *dentry_path(struct dentry *dentry, char *buf, int buflen) Link Here
3174
		buflen++;
3101
		buflen++;
3175
	}
3102
	}
3176
	retval = __dentry_path(dentry, buf, buflen);
3103
	retval = __dentry_path(dentry, buf, buflen);
3104
	write_sequnlock(&rename_lock);
3177
	if (!IS_ERR(retval) && p)
3105
	if (!IS_ERR(retval) && p)
3178
		*p = '/';	/* restore '/' overriden with '\0' */
3106
		*p = '/';	/* restore '/' overriden with '\0' */
3179
	return retval;
3107
	return retval;
Lines 3225-3230 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) Link Here
3225
3153
3226
	error = -ENOENT;
3154
	error = -ENOENT;
3227
	br_read_lock(&vfsmount_lock);
3155
	br_read_lock(&vfsmount_lock);
3156
	write_seqlock(&rename_lock);
3228
	if (!d_unlinked(pwd.dentry)) {
3157
	if (!d_unlinked(pwd.dentry)) {
3229
		unsigned long len;
3158
		unsigned long len;
3230
		char *cwd = page + PATH_MAX;
3159
		char *cwd = page + PATH_MAX;
Lines 3232-3237 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) Link Here
3232
3161
3233
		prepend(&cwd, &buflen, "\0", 1);
3162
		prepend(&cwd, &buflen, "\0", 1);
3234
		error = prepend_path(&pwd, &root, &cwd, &buflen);
3163
		error = prepend_path(&pwd, &root, &cwd, &buflen);
3164
		write_sequnlock(&rename_lock);
3235
		br_read_unlock(&vfsmount_lock);
3165
		br_read_unlock(&vfsmount_lock);
3236
		rcu_read_unlock();
3166
		rcu_read_unlock();
3237
3167
Lines 3253-3258 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) Link Here
3253
				error = -EFAULT;
3183
				error = -EFAULT;
3254
		}
3184
		}
3255
	} else {
3185
	} else {
3186
		write_sequnlock(&rename_lock);
3256
		br_read_unlock(&vfsmount_lock);
3187
		br_read_unlock(&vfsmount_lock);
3257
		rcu_read_unlock();
3188
		rcu_read_unlock();
3258
	}
3189
	}
3259
- 

Return to bug 488492